Merge commit 'u-boot/master' into for-1.3.1
authorStefan Roese <sr@denx.de>
Tue, 11 Dec 2007 10:34:54 +0000 (11:34 +0100)
committerStefan Roese <sr@denx.de>
Tue, 11 Dec 2007 10:34:54 +0000 (11:34 +0100)
Conflicts:

drivers/rtc/Makefile

640 files changed:
.gitignore [new file with mode: 0644]
CHANGELOG
MAKEALL
Makefile
README
blackfin_config.mk
board/ads5121/u-boot.lds
board/cds/common/ft_board.c
board/cds/mpc8541cds/u-boot.lds
board/cds/mpc8548cds/u-boot.lds
board/cds/mpc8555cds/u-boot.lds
board/cm5200/cm5200.c
board/cogent/u-boot.lds
board/dbau1x00/dbau1x00.c
board/dbau1x00/u-boot.lds
board/freescale/common/pixis.c
board/freescale/m54455evb/config.mk
board/freescale/m54455evb/u-boot.atm [new file with mode: 0644]
board/freescale/m54455evb/u-boot.int [new file with mode: 0644]
board/freescale/mpc832xemds/pci.c
board/freescale/mpc8349emds/pci.c
board/freescale/mpc8349itx/pci.c
board/freescale/mpc8360emds/pci.c
board/freescale/mpc8544ds/mpc8544ds.c
board/gth2/gth2.c
board/gth2/lowlevel_init.S
board/gth2/u-boot.lds
board/hymod/u-boot.lds
board/ids8247/ids8247.c
board/incaip/incaip.c
board/incaip/u-boot.lds
board/lwmon5/lwmon5.c
board/m5282evb/m5282evb.c
board/mousse/u-boot.lds
board/mpl/vcma9/cmd_vcma9.c
board/mpl/vcma9/flash.c
board/mpl/vcma9/vcma9.h
board/netstar/eeprom.c
board/pb1x00/Makefile
board/pb1x00/lowlevel_init.S [new file with mode: 0644]
board/pb1x00/memsetup.S [deleted file]
board/pb1x00/pb1x00.c
board/pb1x00/u-boot.lds
board/pleb2/flash.c
board/purple/flash.c
board/purple/purple.c
board/purple/u-boot.lds
board/rsdproto/rsdproto.c
board/rsdproto/u-boot.lds
board/sbc2410x/flash.c
board/smdk2410/flash.c
board/tb0229/tb0229.c
board/tb0229/u-boot.lds
board/tqm5200/tqm5200.c
board/voiceblue/eeprom.c
board/wepep250/flash.c
common/Makefile
common/cmd_bdinfo.c
common/cmd_bedbug.c
common/cmd_bmp.c
common/cmd_console.c
common/cmd_date.c
common/cmd_dcr.c
common/cmd_diag.c
common/cmd_display.c
common/cmd_doc.c
common/cmd_dtt.c
common/cmd_elf.c
common/cmd_ext2.c
common/cmd_fat.c
common/cmd_fdos.c
common/cmd_fdt.c
common/cmd_flash.c
common/cmd_fpga.c
common/cmd_i2c.c
common/cmd_ide.c
common/cmd_immap.c
common/cmd_itest.c
common/cmd_jffs2.c
common/cmd_log.c
common/cmd_mfsl.c
common/cmd_mii.c
common/cmd_misc.c
common/cmd_mmc.c
common/cmd_net.c
common/cmd_pci.c
common/cmd_portio.c
common/cmd_reginfo.c
common/cmd_reiser.c
common/cmd_scsi.c
common/cmd_spi.c
common/cmd_universe.c
common/cmd_usb.c
common/fdt_support.c
common/miiphyutil.c
common/spartan2.c
common/spartan3.c
common/usb_kbd.c
common/usb_storage.c
config.mk
cpu/arm920t/s3c24x0/Makefile
cpu/arm920t/s3c24x0/usb_ohci.c
cpu/mcf523x/config.mk
cpu/mcf52x2/config.mk
cpu/mcf52x2/start.S
cpu/mcf532x/config.mk
cpu/mcf532x/cpu.c
cpu/mcf532x/start.S
cpu/mcf5445x/config.mk
cpu/mcf5445x/start.S
cpu/mips/au1x00_eth.c
cpu/mips/cache.S
cpu/mips/config.mk
cpu/mips/cpu.c
cpu/mips/start.S
cpu/mpc512x/config.mk
cpu/mpc5xx/config.mk
cpu/mpc5xx/u-boot.lds
cpu/mpc5xxx/config.mk
cpu/mpc5xxx/cpu.c
cpu/mpc5xxx/u-boot-customlayout.lds
cpu/mpc5xxx/u-boot.lds
cpu/mpc8220/config.mk
cpu/mpc8220/u-boot.lds
cpu/mpc824x/config.mk
cpu/mpc824x/interrupts.c
cpu/mpc824x/u-boot.lds
cpu/mpc8260/config.mk
cpu/mpc8260/cpu.c
cpu/mpc8260/u-boot.lds
cpu/mpc83xx/config.mk
cpu/mpc83xx/cpu.c
cpu/mpc83xx/pci.c
cpu/mpc83xx/u-boot.lds
cpu/mpc85xx/cpu.c
cpu/mpc85xx/start.S
cpu/mpc86xx/cpu.c
cpu/mpc86xx/spd_sdram.c
cpu/mpc86xx/speed.c
cpu/pxa/i2c.c
disk/Makefile
drivers/3c589.c [deleted file]
drivers/3c589.h [deleted file]
drivers/5701rls.c [deleted file]
drivers/5701rls.h [deleted file]
drivers/8390.h [deleted file]
drivers/Makefile [deleted file]
drivers/ahci.c [deleted file]
drivers/ali512x.c [deleted file]
drivers/at45.c [deleted file]
drivers/ata_piix.c [deleted file]
drivers/ati_ids.h [deleted file]
drivers/ati_radeon_fb.c [deleted file]
drivers/ati_radeon_fb.h [deleted file]
drivers/atmel_usart.c [deleted file]
drivers/atmel_usart.h [deleted file]
drivers/bcm570x.c [deleted file]
drivers/bcm570x_autoneg.c [deleted file]
drivers/bcm570x_autoneg.h [deleted file]
drivers/bcm570x_bits.h [deleted file]
drivers/bcm570x_debug.h [deleted file]
drivers/bcm570x_lm.h [deleted file]
drivers/bcm570x_mm.h [deleted file]
drivers/bcm570x_queue.h [deleted file]
drivers/bios_emulator/besys.c
drivers/bios_emulator/biosemu.c
drivers/block/Makefile [new file with mode: 0644]
drivers/block/ahci.c [new file with mode: 0644]
drivers/block/ata_piix.c [new file with mode: 0644]
drivers/block/sil680.c [new file with mode: 0644]
drivers/block/sym53c8xx.c [new file with mode: 0644]
drivers/block/systemace.c [new file with mode: 0644]
drivers/cfb_console.c [deleted file]
drivers/cfi_flash.c [deleted file]
drivers/cs8900.c [deleted file]
drivers/cs8900.h [deleted file]
drivers/ct69000.c [deleted file]
drivers/dataflash.c [deleted file]
drivers/dc2114x.c [deleted file]
drivers/dm9000x.c [deleted file]
drivers/dm9000x.h [deleted file]
drivers/ds1722.c [deleted file]
drivers/e1000.c [deleted file]
drivers/e1000.h [deleted file]
drivers/eepro100.c [deleted file]
drivers/enc28j60.c [deleted file]
drivers/fsl_i2c.c [deleted file]
drivers/fsl_pci_init.c [deleted file]
drivers/hwmon/Makefile [new file with mode: 0644]
drivers/hwmon/adm1021.c [new file with mode: 0644]
drivers/hwmon/ds1621.c [new file with mode: 0644]
drivers/hwmon/ds1722.c [new file with mode: 0644]
drivers/hwmon/ds1775.c [new file with mode: 0644]
drivers/hwmon/lm75.c [new file with mode: 0644]
drivers/hwmon/lm81.c [new file with mode: 0644]
drivers/i2c/Makefile [new file with mode: 0644]
drivers/i2c/fsl_i2c.c [new file with mode: 0644]
drivers/i2c/omap1510_i2c.c [new file with mode: 0644]
drivers/i2c/omap24xx_i2c.c [new file with mode: 0644]
drivers/i2c/tsi108_i2c.c [new file with mode: 0644]
drivers/i8042.c [deleted file]
drivers/i82365.c [deleted file]
drivers/inca-ip_sw.c [deleted file]
drivers/input/Makefile [new file with mode: 0644]
drivers/input/i8042.c [new file with mode: 0644]
drivers/input/keyboard.c [new file with mode: 0644]
drivers/input/pc_keyb.c [new file with mode: 0644]
drivers/input/ps2mult.c [new file with mode: 0644]
drivers/input/ps2ser.c [new file with mode: 0644]
drivers/isp116x-hcd.c [deleted file]
drivers/isp116x.h [deleted file]
drivers/keyboard.c [deleted file]
drivers/ks8695eth.c [deleted file]
drivers/lan91c96.c [deleted file]
drivers/lan91c96.h [deleted file]
drivers/macb.c [deleted file]
drivers/macb.h [deleted file]
drivers/misc/Makefile [new file with mode: 0644]
drivers/misc/ali512x.c [new file with mode: 0644]
drivers/misc/ns87308.c [new file with mode: 0644]
drivers/misc/status_led.c [new file with mode: 0644]
drivers/mpc8xx_pcmcia.c [deleted file]
drivers/mtd/Makefile [new file with mode: 0644]
drivers/mtd/at45.c [new file with mode: 0644]
drivers/mtd/cfi_flash.c [new file with mode: 0644]
drivers/mtd/dataflash.c [new file with mode: 0644]
drivers/mtd/mw_eeprom.c [new file with mode: 0644]
drivers/mtd/nand/Makefile [new file with mode: 0644]
drivers/mtd/nand/diskonchip.c [new file with mode: 0644]
drivers/mtd/nand/nand.c [new file with mode: 0644]
drivers/mtd/nand/nand_base.c [new file with mode: 0644]
drivers/mtd/nand/nand_bbt.c [new file with mode: 0644]
drivers/mtd/nand/nand_ecc.c [new file with mode: 0644]
drivers/mtd/nand/nand_ids.c [new file with mode: 0644]
drivers/mtd/nand/nand_util.c [new file with mode: 0644]
drivers/mtd/nand_legacy/Makefile [new file with mode: 0644]
drivers/mtd/nand_legacy/nand_legacy.c [new file with mode: 0644]
drivers/mtd/onenand/Makefile [new file with mode: 0644]
drivers/mtd/onenand/onenand_base.c [new file with mode: 0644]
drivers/mtd/onenand/onenand_bbt.c [new file with mode: 0644]
drivers/mw_eeprom.c [deleted file]
drivers/nand/Makefile [deleted file]
drivers/nand/diskonchip.c [deleted file]
drivers/nand/nand.c [deleted file]
drivers/nand/nand_base.c [deleted file]
drivers/nand/nand_bbt.c [deleted file]
drivers/nand/nand_ecc.c [deleted file]
drivers/nand/nand_ids.c [deleted file]
drivers/nand/nand_util.c [deleted file]
drivers/nand_legacy/Makefile [deleted file]
drivers/nand_legacy/nand_legacy.c [deleted file]
drivers/natsemi.c [deleted file]
drivers/ne2000.c [deleted file]
drivers/ne2000.h [deleted file]
drivers/net/3c589.c [new file with mode: 0644]
drivers/net/3c589.h [new file with mode: 0644]
drivers/net/5701rls.c [new file with mode: 0644]
drivers/net/5701rls.h [new file with mode: 0644]
drivers/net/8390.h [new file with mode: 0644]
drivers/net/Makefile
drivers/net/bcm570x.c [new file with mode: 0644]
drivers/net/bcm570x_autoneg.c [new file with mode: 0644]
drivers/net/bcm570x_autoneg.h [new file with mode: 0644]
drivers/net/bcm570x_bits.h [new file with mode: 0644]
drivers/net/bcm570x_debug.h [new file with mode: 0644]
drivers/net/bcm570x_lm.h [new file with mode: 0644]
drivers/net/bcm570x_mm.h [new file with mode: 0644]
drivers/net/bcm570x_queue.h [new file with mode: 0644]
drivers/net/cs8900.c [new file with mode: 0644]
drivers/net/cs8900.h [new file with mode: 0644]
drivers/net/dc2114x.c [new file with mode: 0644]
drivers/net/dm9000x.c [new file with mode: 0644]
drivers/net/dm9000x.h [new file with mode: 0644]
drivers/net/e1000.c [new file with mode: 0644]
drivers/net/e1000.h [new file with mode: 0644]
drivers/net/eepro100.c [new file with mode: 0644]
drivers/net/enc28j60.c [new file with mode: 0644]
drivers/net/inca-ip_sw.c [new file with mode: 0644]
drivers/net/ks8695eth.c [new file with mode: 0644]
drivers/net/lan91c96.c [new file with mode: 0644]
drivers/net/lan91c96.h [new file with mode: 0644]
drivers/net/macb.c [new file with mode: 0644]
drivers/net/macb.h [new file with mode: 0644]
drivers/net/natsemi.c [new file with mode: 0644]
drivers/net/ne2000.c [new file with mode: 0644]
drivers/net/ne2000.h [new file with mode: 0644]
drivers/net/netarm_eth.c [new file with mode: 0644]
drivers/net/netarm_eth.h [new file with mode: 0644]
drivers/net/netconsole.c [new file with mode: 0644]
drivers/net/nicext.h [new file with mode: 0644]
drivers/net/ns7520_eth.c [new file with mode: 0644]
drivers/net/ns8382x.c [new file with mode: 0644]
drivers/net/ns9750_eth.c [new file with mode: 0644]
drivers/net/pcnet.c [new file with mode: 0644]
drivers/net/plb2800_eth.c [new file with mode: 0644]
drivers/net/rtl8019.c [new file with mode: 0644]
drivers/net/rtl8019.h [new file with mode: 0644]
drivers/net/rtl8139.c [new file with mode: 0644]
drivers/net/rtl8169.c [new file with mode: 0644]
drivers/net/s3c4510b_eth.c [new file with mode: 0644]
drivers/net/s3c4510b_eth.h [new file with mode: 0644]
drivers/net/sk98lin/Makefile [new file with mode: 0644]
drivers/net/sk98lin/h/lm80.h [new file with mode: 0644]
drivers/net/sk98lin/h/skaddr.h [new file with mode: 0644]
drivers/net/sk98lin/h/skcsum.h [new file with mode: 0644]
drivers/net/sk98lin/h/skdebug.h [new file with mode: 0644]
drivers/net/sk98lin/h/skdrv1st.h [new file with mode: 0644]
drivers/net/sk98lin/h/skdrv2nd.h [new file with mode: 0644]
drivers/net/sk98lin/h/skerror.h [new file with mode: 0644]
drivers/net/sk98lin/h/skgedrv.h [new file with mode: 0644]
drivers/net/sk98lin/h/skgehw.h [new file with mode: 0644]
drivers/net/sk98lin/h/skgehwt.h [new file with mode: 0644]
drivers/net/sk98lin/h/skgei2c.h [new file with mode: 0644]
drivers/net/sk98lin/h/skgeinit.h [new file with mode: 0644]
drivers/net/sk98lin/h/skgepnm2.h [new file with mode: 0644]
drivers/net/sk98lin/h/skgepnmi.h [new file with mode: 0644]
drivers/net/sk98lin/h/skgesirq.h [new file with mode: 0644]
drivers/net/sk98lin/h/ski2c.h [new file with mode: 0644]
drivers/net/sk98lin/h/skqueue.h [new file with mode: 0644]
drivers/net/sk98lin/h/skrlmt.h [new file with mode: 0644]
drivers/net/sk98lin/h/sktimer.h [new file with mode: 0644]
drivers/net/sk98lin/h/sktypes.h [new file with mode: 0644]
drivers/net/sk98lin/h/skversion.h [new file with mode: 0644]
drivers/net/sk98lin/h/skvpd.h [new file with mode: 0644]
drivers/net/sk98lin/h/xmac_ii.h [new file with mode: 0644]
drivers/net/sk98lin/skaddr.c [new file with mode: 0644]
drivers/net/sk98lin/skcsum.c [new file with mode: 0644]
drivers/net/sk98lin/skge.c [new file with mode: 0644]
drivers/net/sk98lin/skgehwt.c [new file with mode: 0644]
drivers/net/sk98lin/skgeinit.c [new file with mode: 0644]
drivers/net/sk98lin/skgemib.c [new file with mode: 0644]
drivers/net/sk98lin/skgepnmi.c [new file with mode: 0644]
drivers/net/sk98lin/skgesirq.c [new file with mode: 0644]
drivers/net/sk98lin/ski2c.c [new file with mode: 0644]
drivers/net/sk98lin/sklm80.c [new file with mode: 0644]
drivers/net/sk98lin/skproc.c [new file with mode: 0644]
drivers/net/sk98lin/skqueue.c [new file with mode: 0644]
drivers/net/sk98lin/skrlmt.c [new file with mode: 0644]
drivers/net/sk98lin/sktimer.c [new file with mode: 0644]
drivers/net/sk98lin/skvpd.c [new file with mode: 0644]
drivers/net/sk98lin/skxmac2.c [new file with mode: 0644]
drivers/net/sk98lin/u-boot_compat.h [new file with mode: 0644]
drivers/net/sk98lin/uboot_drv.c [new file with mode: 0644]
drivers/net/sk98lin/uboot_skb.c [new file with mode: 0644]
drivers/net/smc91111.c [new file with mode: 0644]
drivers/net/smc91111.h [new file with mode: 0644]
drivers/net/tigon3.c [new file with mode: 0644]
drivers/net/tigon3.h [new file with mode: 0644]
drivers/net/tsec.c [new file with mode: 0644]
drivers/net/tsec.h [new file with mode: 0644]
drivers/net/tsi108_eth.c [new file with mode: 0644]
drivers/net/uli526x.c [new file with mode: 0644]
drivers/netarm_eth.c [deleted file]
drivers/netarm_eth.h [deleted file]
drivers/netconsole.c [deleted file]
drivers/nicext.h [deleted file]
drivers/ns16550.c [deleted file]
drivers/ns7520_eth.c [deleted file]
drivers/ns8382x.c [deleted file]
drivers/ns87308.c [deleted file]
drivers/ns9750_eth.c [deleted file]
drivers/ns9750_serial.c [deleted file]
drivers/omap1510_i2c.c [deleted file]
drivers/omap24xx_i2c.c [deleted file]
drivers/onenand/Makefile [deleted file]
drivers/onenand/onenand_base.c [deleted file]
drivers/onenand/onenand_bbt.c [deleted file]
drivers/pc_keyb.c [deleted file]
drivers/pci.c [deleted file]
drivers/pci/Makefile [new file with mode: 0644]
drivers/pci/fsl_pci_init.c [new file with mode: 0644]
drivers/pci/pci.c [new file with mode: 0644]
drivers/pci/pci_auto.c [new file with mode: 0644]
drivers/pci/pci_indirect.c [new file with mode: 0644]
drivers/pci/tsi108_pci.c [new file with mode: 0644]
drivers/pci/w83c553f.c [new file with mode: 0644]
drivers/pci_auto.c [deleted file]
drivers/pci_indirect.c [deleted file]
drivers/pcmcia/Makefile [new file with mode: 0644]
drivers/pcmcia/i82365.c [new file with mode: 0644]
drivers/pcmcia/mpc8xx_pcmcia.c [new file with mode: 0644]
drivers/pcmcia/pxa_pcmcia.c [new file with mode: 0644]
drivers/pcmcia/rpx_pcmcia.c [new file with mode: 0644]
drivers/pcmcia/ti_pci1410a.c [new file with mode: 0644]
drivers/pcmcia/tqm8xx_pcmcia.c [new file with mode: 0644]
drivers/pcnet.c [deleted file]
drivers/plb2800_eth.c [deleted file]
drivers/ps2mult.c [deleted file]
drivers/ps2ser.c [deleted file]
drivers/pxa_pcmcia.c [deleted file]
drivers/rpx_pcmcia.c [deleted file]
drivers/rtc/Makefile [new file with mode: 0644]
drivers/rtc/bf5xx_rtc.c [new file with mode: 0644]
drivers/rtc/date.c [new file with mode: 0644]
drivers/rtc/ds12887.c [new file with mode: 0644]
drivers/rtc/ds1302.c [new file with mode: 0644]
drivers/rtc/ds1306.c [new file with mode: 0644]
drivers/rtc/ds1307.c [new file with mode: 0644]
drivers/rtc/ds1337.c [new file with mode: 0644]
drivers/rtc/ds1374.c [new file with mode: 0644]
drivers/rtc/ds1556.c [new file with mode: 0644]
drivers/rtc/ds164x.c [new file with mode: 0644]
drivers/rtc/ds174x.c [new file with mode: 0644]
drivers/rtc/ds3231.c [new file with mode: 0644]
drivers/rtc/m41t11.c [new file with mode: 0644]
drivers/rtc/m48t35ax.c [new file with mode: 0644]
drivers/rtc/max6900.c [new file with mode: 0644]
drivers/rtc/mc146818.c [new file with mode: 0644]
drivers/rtc/mcfrtc.c [new file with mode: 0644]
drivers/rtc/mk48t59.c [new file with mode: 0644]
drivers/rtc/mpc5xxx.c [new file with mode: 0644]
drivers/rtc/mpc8xx.c [new file with mode: 0644]
drivers/rtc/pcf8563.c [new file with mode: 0644]
drivers/rtc/rs5c372.c [new file with mode: 0644]
drivers/rtc/s3c24x0_rtc.c [new file with mode: 0644]
drivers/rtl8019.c [deleted file]
drivers/rtl8019.h [deleted file]
drivers/rtl8139.c [deleted file]
drivers/rtl8169.c [deleted file]
drivers/s3c4510b_eth.c [deleted file]
drivers/s3c4510b_eth.h [deleted file]
drivers/s3c4510b_uart.c [deleted file]
drivers/s3c4510b_uart.h [deleted file]
drivers/sed13806.c [deleted file]
drivers/sed156x.c [deleted file]
drivers/serial.c [deleted file]
drivers/serial/Makefile
drivers/serial/atmel_usart.c [new file with mode: 0644]
drivers/serial/atmel_usart.h [new file with mode: 0644]
drivers/serial/ns16550.c [new file with mode: 0644]
drivers/serial/ns9750_serial.c [new file with mode: 0644]
drivers/serial/s3c4510b_uart.c [new file with mode: 0644]
drivers/serial/s3c4510b_uart.h [new file with mode: 0644]
drivers/serial/serial.c [new file with mode: 0644]
drivers/serial/serial_max3100.c [new file with mode: 0644]
drivers/serial/serial_pl010.c [new file with mode: 0644]
drivers/serial/serial_pl011.c [new file with mode: 0644]
drivers/serial/serial_pl011.h [new file with mode: 0644]
drivers/serial/serial_xuartlite.c [new file with mode: 0644]
drivers/serial/usbtty.c [new file with mode: 0644]
drivers/serial/usbtty.h [new file with mode: 0644]
drivers/serial_max3100.c [deleted file]
drivers/serial_pl010.c [deleted file]
drivers/serial_pl011.c [deleted file]
drivers/serial_pl011.h [deleted file]
drivers/serial_xuartlite.c [deleted file]
drivers/sil680.c [deleted file]
drivers/sk98lin/Makefile [deleted file]
drivers/sk98lin/h/lm80.h [deleted file]
drivers/sk98lin/h/skaddr.h [deleted file]
drivers/sk98lin/h/skcsum.h [deleted file]
drivers/sk98lin/h/skdebug.h [deleted file]
drivers/sk98lin/h/skdrv1st.h [deleted file]
drivers/sk98lin/h/skdrv2nd.h [deleted file]
drivers/sk98lin/h/skerror.h [deleted file]
drivers/sk98lin/h/skgedrv.h [deleted file]
drivers/sk98lin/h/skgehw.h [deleted file]
drivers/sk98lin/h/skgehwt.h [deleted file]
drivers/sk98lin/h/skgei2c.h [deleted file]
drivers/sk98lin/h/skgeinit.h [deleted file]
drivers/sk98lin/h/skgepnm2.h [deleted file]
drivers/sk98lin/h/skgepnmi.h [deleted file]
drivers/sk98lin/h/skgesirq.h [deleted file]
drivers/sk98lin/h/ski2c.h [deleted file]
drivers/sk98lin/h/skqueue.h [deleted file]
drivers/sk98lin/h/skrlmt.h [deleted file]
drivers/sk98lin/h/sktimer.h [deleted file]
drivers/sk98lin/h/sktypes.h [deleted file]
drivers/sk98lin/h/skversion.h [deleted file]
drivers/sk98lin/h/skvpd.h [deleted file]
drivers/sk98lin/h/xmac_ii.h [deleted file]
drivers/sk98lin/skaddr.c [deleted file]
drivers/sk98lin/skcsum.c [deleted file]
drivers/sk98lin/skge.c [deleted file]
drivers/sk98lin/skgehwt.c [deleted file]
drivers/sk98lin/skgeinit.c [deleted file]
drivers/sk98lin/skgemib.c [deleted file]
drivers/sk98lin/skgepnmi.c [deleted file]
drivers/sk98lin/skgesirq.c [deleted file]
drivers/sk98lin/ski2c.c [deleted file]
drivers/sk98lin/sklm80.c [deleted file]
drivers/sk98lin/skproc.c [deleted file]
drivers/sk98lin/skqueue.c [deleted file]
drivers/sk98lin/skrlmt.c [deleted file]
drivers/sk98lin/sktimer.c [deleted file]
drivers/sk98lin/skvpd.c [deleted file]
drivers/sk98lin/skxmac2.c [deleted file]
drivers/sk98lin/u-boot_compat.h [deleted file]
drivers/sk98lin/uboot_drv.c [deleted file]
drivers/sk98lin/uboot_skb.c [deleted file]
drivers/sl811.h [deleted file]
drivers/sl811_usb.c [deleted file]
drivers/sm501.c [deleted file]
drivers/smc91111.c [deleted file]
drivers/smc91111.h [deleted file]
drivers/smiLynxEM.c [deleted file]
drivers/status_led.c [deleted file]
drivers/sym53c8xx.c [deleted file]
drivers/systemace.c [deleted file]
drivers/ti_pci1410a.c [deleted file]
drivers/tigon3.c [deleted file]
drivers/tigon3.h [deleted file]
drivers/tqm8xx_pcmcia.c [deleted file]
drivers/tsec.c [deleted file]
drivers/tsec.h [deleted file]
drivers/tsi108_eth.c [deleted file]
drivers/tsi108_i2c.c [deleted file]
drivers/tsi108_pci.c [deleted file]
drivers/usb/Makefile [new file with mode: 0644]
drivers/usb/isp116x-hcd.c [new file with mode: 0644]
drivers/usb/isp116x.h [new file with mode: 0644]
drivers/usb/sl811.h [new file with mode: 0644]
drivers/usb/sl811_usb.c [new file with mode: 0644]
drivers/usb/usb_ohci.c [new file with mode: 0644]
drivers/usb/usb_ohci.h [new file with mode: 0644]
drivers/usb/usbdcore.c [new file with mode: 0644]
drivers/usb/usbdcore_ep0.c [new file with mode: 0644]
drivers/usb/usbdcore_mpc8xx.c [new file with mode: 0644]
drivers/usb/usbdcore_omap1510.c [new file with mode: 0644]
drivers/usb_ohci.c [deleted file]
drivers/usb_ohci.h [deleted file]
drivers/usbdcore.c [deleted file]
drivers/usbdcore_ep0.c [deleted file]
drivers/usbdcore_mpc8xx.c [deleted file]
drivers/usbdcore_omap1510.c [deleted file]
drivers/usbtty.c [deleted file]
drivers/usbtty.h [deleted file]
drivers/video/Makefile [new file with mode: 0644]
drivers/video/ati_ids.h [new file with mode: 0644]
drivers/video/ati_radeon_fb.c [new file with mode: 0644]
drivers/video/ati_radeon_fb.h [new file with mode: 0644]
drivers/video/cfb_console.c [new file with mode: 0644]
drivers/video/ct69000.c [new file with mode: 0644]
drivers/video/sed13806.c [new file with mode: 0644]
drivers/video/sed156x.c [new file with mode: 0644]
drivers/video/sm501.c [new file with mode: 0644]
drivers/video/smiLynxEM.c [new file with mode: 0644]
drivers/video/videomodes.c [new file with mode: 0644]
drivers/video/videomodes.h [new file with mode: 0644]
drivers/videomodes.c [deleted file]
drivers/videomodes.h [deleted file]
drivers/w83c553f.c [deleted file]
dtt/Makefile [deleted file]
dtt/adm1021.c [deleted file]
dtt/ds1621.c [deleted file]
dtt/ds1775.c [deleted file]
dtt/lm75.c [deleted file]
dtt/lm81.c [deleted file]
examples/.gitignore [new file with mode: 0644]
examples/mips.lds
examples/smc91111_eeprom.c
fs/jffs2/Makefile
include/.gitignore [new file with mode: 0644]
include/asm-arm/arch-at91rm9200/hardware.h
include/asm-m68k/immap_5329.h
include/asm-m68k/m5329.h
include/asm-m68k/m5445x.h
include/asm-mips/addrspace.h
include/asm-mips/io.h
include/common.h
include/configs/ADNPESC1.h
include/configs/DK1C20.h
include/configs/DK1S10.h
include/configs/IDS8247.h
include/configs/LANTEC.h
include/configs/M5253EVBE.h
include/configs/M5282EVB.h
include/configs/M5329EVB.h
include/configs/M54455EVB.h
include/configs/MPC8260ADS.h
include/configs/MPC8541CDS.h
include/configs/MPC8544DS.h
include/configs/MPC8548CDS.h
include/configs/MPC8555CDS.h
include/configs/MPC8568MDS.h
include/configs/MPC8641HPCN.h
include/configs/RBC823.h
include/configs/ads5121.h
include/configs/atstk1002.h
include/configs/ep8260.h
include/configs/hymod.h
include/configs/rsdproto.h
include/configs/sbc2410x.h
include/configs/smdk2410.h
include/configs/uc101.h
include/fdt.h
include/fdt_support.h
include/libfdt.h
include/miiphy.h
lib_arm/board.c
lib_blackfin/board.c
lib_generic/Makefile
lib_m68k/m68k_linux.c
lib_mips/board.c
libfdt/Makefile
libfdt/fdt.c
libfdt/fdt_ro.c
libfdt/fdt_rw.c
libfdt/fdt_strerror.c
libfdt/fdt_sw.c
libfdt/fdt_wip.c
libfdt/libfdt_internal.h
mips_config.mk
nand_spl/board/amcc/acadia/Makefile
nand_spl/board/amcc/bamboo/Makefile
nand_spl/board/amcc/sequoia/Makefile
net/Makefile
net/bootp.c
net/bootp.h
net/eth.c
net/net.c
net/nfs.c
net/rarp.c
net/tftp.c
rtc/Makefile [deleted file]
rtc/bf5xx_rtc.c [deleted file]
rtc/date.c [deleted file]
rtc/ds12887.c [deleted file]
rtc/ds1302.c [deleted file]
rtc/ds1306.c [deleted file]
rtc/ds1307.c [deleted file]
rtc/ds1337.c [deleted file]
rtc/ds1374.c [deleted file]
rtc/ds1556.c [deleted file]
rtc/ds164x.c [deleted file]
rtc/ds174x.c [deleted file]
rtc/ds3231.c [deleted file]
rtc/m41t11.c [deleted file]
rtc/m48t35ax.c [deleted file]
rtc/max6900.c [deleted file]
rtc/mc146818.c [deleted file]
rtc/mcfrtc.c [deleted file]
rtc/mk48t59.c [deleted file]
rtc/mpc5xxx.c [deleted file]
rtc/mpc8xx.c [deleted file]
rtc/pcf8563.c [deleted file]
rtc/rs5c372.c [deleted file]
rtc/s3c24x0_rtc.c [deleted file]
tools/.gitignore [new file with mode: 0644]
tools/scripts/define2mk.sed [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..67fed08
--- /dev/null
@@ -0,0 +1,13 @@
+*.orig
+*.a
+*.o
+*.depend
+System.map
+/u-boot
+/u-boot.map
+/u-boot.bin
+/u-boot.srec
+/LOG
+/errlog
+/reloc_off
+
index 549c4f919cb9d0ffc36f223d6db88baf1876f6ef..015a4ac01b56d96c30a23d21c632063437aac53e 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
+commit a5f601fd1b1278deae5aa9fc27a232b0d1c1c788
+Author: Wolfgang Denk <wd@denx.de>
+Date:  Mon Nov 26 19:18:21 2007 +0100
+
+    Cleanup coding style; update CHANGELOG
+
+    Signed-off-by: Wolfgang Denk <wd@denx.de>
+
+commit 3deca9d44767efd1b83f4b701f0dbf21a7595f7b
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Sun Nov 25 22:39:25 2007 +0100
+
+    MAKEALL: add missing 512x boards in ppc
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit a340c325e668ca7386c2276387681720be9c3757
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Sun Nov 25 18:45:47 2007 +0100
+
+    Makefile : fix tags ctags etags with new drivers organization
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 87ddedd6ad804427ce125ceaa076d7a4f74e9d5d
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Sun Nov 25 18:45:47 2007 +0100
+
+    Makefile : fix tags ctags etags with new drivers organization
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 59829cc189378c142c13d2aa8d9a897d8bef3961
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Sat Nov 24 21:26:56 2007 +0100
+
+    drivers/mtd : move mtd drivers to drivers/mtd
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 318c0b90431f2648552e5ade78833f42652ce859
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Sat Nov 24 21:17:55 2007 +0100
+
+    drivers/misc : move misc drivers to drivers/misc
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 33daf5b7858807cb4ce4158c2c56524671c14c08
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Sat Nov 24 21:13:59 2007 +0100
+
+    drivers/block : move block drivers to drivers/block
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 0c698dcaa70275eb8814f665b545547cee013892
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Sat Nov 24 20:59:50 2007 +0100
+
+    drivers/rtc : move rtc drivers to drivers/rtc
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit f868cc5a50757d94f36c312395481cb0f187d9e6
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Sat Nov 24 20:14:44 2007 +0100
+
+    drivers/hwmon : move hardware monitor drviers to drivers/hwmon
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 16b195c82a18cbfd164800f17a1ef9db2e48331a
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Sat Nov 24 19:46:45 2007 +0100
+
+    drivers/input : move input drivers to drivers/input
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit e4558666293364fc3af1c1d9381ca933fa0f1275
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Sat Nov 24 19:40:11 2007 +0100
+
+    drivers/usb : move usb drivers to drivers/usb
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 1378df792a7ff3abd1bf54a63f5475784f5b083c
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Sat Nov 24 19:33:38 2007 +0100
+
+    drivers/serial : move serial drivers to drivers/serial
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 2439e4bfa111babf4bc07ba20efbf3e36036813e
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Wed Nov 21 21:19:24 2007 +0100
+
+    drivers/net : move net drivers to drivers/net
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 352d259130b349fe9593b8dada641bd78a9659e5
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Tue Nov 20 20:41:48 2007 +0100
+
+    drivers/video : move video drivers to drivers/video
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 73646217186aa17afc8e305c5f06f06dd335eaad
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Tue Nov 20 20:33:09 2007 +0100
+
+    drivers/pcmcia : move pcmcia drivers to drivers/pcmcia
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 93a686ee9c5ddc6fa368c32cfbfde6f6724599fc
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Tue Nov 20 20:28:09 2007 +0100
+
+    drivers/pci : move pci drivers to drivers/pci
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 9162352817579840d7802da6d85872b3ca003c97
+Author: Gerald Van Baren <vanbaren@cideas.com>
+Date:  Thu Nov 22 17:23:23 2007 -0500
+
+    Fix fdt printing for updated libfdt
+
+    Also improve printing (adopt dtc v1 "c style" hex format), whitespace cleanup.
+
+    Signed-off-by: Gerald Van Baren <vanbaren@cideas.com>
+
+commit 9eb77cea1fa12d5969eb26a1d1d81da381bd6b1c
+Author: Kumar Gala <galak@kernel.crashing.org>
+Date:  Wed Nov 21 13:30:15 2007 -0600
+
+    Add additional fdt fixup helper functions
+
+    Added the following fdt fixup helpers:
+     * do_fixup_by_prop{_u32} - Find matching nodes by property name/value
+     * do_fixup_by_compat{_u32} - Find matching nodes by compat
+
+    The _u32 variants work the same only the property they are setting
+    is know to be a 32-bit integer instead of a byte buffer.
+
+    Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
+
+commit ab544633abdd14f4dd5d92e500b73eb59ef57e67
+Author: Kumar Gala <galak@kernel.crashing.org>
+Date:  Wed Nov 21 11:11:03 2007 -0600
+
+    Add fdt_fixup_ethernet helper to set mac addresses
+
+    Added a fixup helper that uses aliases to set mac addresses
+    in the device tree based on the bd_t
+
+    Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
+
+commit dbaf07ce620aab249e3502b20a986234a6af1d3a
+Author: Kumar Gala <galak@kernel.crashing.org>
+Date:  Wed Nov 21 14:07:46 2007 -0600
+
+    Fix warnings from import of libfdt
+
+    cmd_fdt.c: In function fdt_print:
+    cmd_fdt.c:586: warning: assignment discards qualifiers from pointer target type
+    cmd_fdt.c:613: warning: assignment discards qualifiers from pointer target type
+    cmd_fdt.c:635: warning: assignment discards qualifiers from pointer target type
+    cmd_fdt.c:636: warning: assignment discards qualifiers from pointer target type
+
+    Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
+
+commit 8d04f02f6224e6983f4812ea4da704950ec8539c
+Author: Kumar Gala <galak@kernel.crashing.org>
+Date:  Wed Oct 24 11:04:22 2007 -0500
+
+    Update libfdt from device tree compiler (dtc)
+
+    Update libfdt to commit 8eaf5e358366017aa2e846c5038d1aa19958314e from
+    the device tree compiler (dtc) project.
+
+    Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
+
+commit e93becf80d732b64aef81b23e8b6ece02c40533d
+Author: Kumar Gala <galak@kernel.crashing.org>
+Date:  Sat Nov 3 19:46:28 2007 -0500
+
+    Move do_fixup* for libfdt into common code
+
+    Moved the generic fixup handling code out of cpu/mpc5xxx and cpu/mpc8260
+    into common/fdt_support.c and renamed:
+
+    do_fixup() -> do_fixup_by_path()
+    do_fixup_u32()     -> do_fixup_by_path_u32()
+
+    Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
+
+commit f738b4a75998f42a7408defadc9baac7a31c92db
+Author: Kumar Gala <galak@kernel.crashing.org>
+Date:  Thu Oct 25 16:15:07 2007 -0500
+
+    Make no options to fdt print default to '/'
+
+    Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
+
+commit a3c2933e02503fe36ade2c1b65af46f2b7a168e7
+Author: Kumar Gala <galak@kernel.crashing.org>
+Date:  Wed Oct 24 10:21:57 2007 -0500
+
+    Removed some nonused fdt functions and moved fdt_find_and_setprop out of libfdt
+
+    Removed:
+       fdt_node_is_compatible
+       fdt_find_node_by_type
+       fdt_find_compatible_node
+
+    To ease merge of newer libfdt as we aren't using them anywhere at this time.
+
+    Also moved fdt_find_and_setprop out of libfdt into fdt_support.c for the same
+    reason.
+
+    Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
+
+commit 98e2867cc85409b919f862e6c16026461ec955df
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Wed Nov 21 09:19:37 2007 -0700
+
+    [BUILD] Remove libraries when updating autoconf.mk
+
+    Fix library problems caused by conditional compilation.  Using
+    autoconf.mk to decide which files to compile has caused a problem when
+    changing configuration from one board to another without clearing out
+    the library (*.a) files.
+
+    It used to be that the linker was always passed the same list of .o
+    files when building the .a files.  However, that is not longer true
+    with conditional compilation.  Now, a different board config will have
+    a different file list passed to the linker.  The problem occurs when
+    a library has already been built and the board config is changed.
+
+    Since the linker will update instead of replace a preexisting library,
+    then if the file list changes to remove some object files the old
+    objects will still exist in the library.
+
+    The solution is to remove all old library files when autoconf.mk is
+    made.
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit ed1353d74b9ce8a7fcd660570b848a184d614b5f
+Author: Kumar Gala <galak@kernel.crashing.org>
+Date:  Wed Nov 21 08:49:50 2007 -0600
+
+    [BUILD] conditionally compile libfdt/*.c in libfdt/Makefile
+
+    Modify libfdt/Makefile to conditionally compile the *.c files based
+    on the board config.
+
+    Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
+
+commit 4a43719a7738712811d822ca8125427b27a55cdc
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Mon Sep 24 09:05:31 2007 -0600
+
+    [BUILD] conditionally compile common/cmd_*.c in common/Makefile
+
+    Modify common/Makefile to conditionally compile the cmd_*.c files based
+    on the board config.
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 2f155f6c0a1f5e9a306a3f1f4fbe067db7ced3b1
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Mon Sep 24 09:05:31 2007 -0600
+
+    [BUILD] Generate include/autoconf.mk from board config files
+
+    Use cpp and sed to postprocess config.h and import the defined values
+    into include/autoconf.mk.  autoconf.mk is then included by config.mk to
+    give 'make' access to the board configuration.
+
+    Doing this enables conditional compilation at the Makefile level instead
+    of by wrapping every .c file with #ifdef/#endif wrappers.
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 080c646dbf474a109c3f85718fb01ce042a38c45
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Tue Nov 20 20:14:18 2007 +0100
+
+    drivers/i2c : move i2c drivers to drivers/i2c
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 9a337ddc154a10a26f117fd147b009abcdeba75a
+Author: Wolfgang Denk <wd@denx.de>
+Date:  Mon Nov 19 22:20:24 2007 +0100
+
+    Prepare for 1.3.0 release.
+
+    Signed-off-by: Wolfgang Denk <wd@denx.de>
+
+commit f30ad49b16bf998b03c1a5228b6c86369d61c258
+Author: Haiying Wang <Haiying.Wang@freescale.com>
+Date:  Mon Nov 19 10:02:13 2007 -0500
+
+    Move CONFIG_QE out of CONFIG_PCI wrap for MPC8568MDS
+
+    CONFIG_QE shouldn't be in the wrap of CONFIG_PCI, fix it.
+
+    Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
+
+commit f8c320609366176b31104d9bf5e295232e1c7f1d
+Author: Shinya Kuribayashi <shinya.kuribayashi@necel.com>
+Date:  Mon Nov 19 11:14:16 2007 +0900
+
+    [MIPS] board/gth2/lowlevel_init.S: Fix a build warning
+
+    lowlevel_init.S: Assembler messages:
+    lowlevel_init.S:413: Warning: Pretending global symbol used as branch target is local.
+
+    Looking at codes, the `memtest' and `clearmem' are intentional mixed
+    use of `global symbols' and `label' for debugging purpose. To make it
+    build, just disable global-symbols-use for now. As a result `memtest'
+    still remains as unused, but leave it be...
+
+    Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi@necel.com>
+
+commit e8da58f2bc092891e8cc92b927ed5c4bd0cb0cab
+Author: Wolfgang Denk <wd@denx.de>
+Date:  Mon Nov 19 12:59:14 2007 +0100
+
+    Fix build problems with mp2usb board
+
+    Signed-off-by: Wolfgang Denk <wd@denx.de>
+
+commit 6bf4c686afca1e86e1c384d59218f914605713bf
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Sun Nov 18 18:36:11 2007 +0100
+
+    s3c24x0: Fix usb_ohci.c missing in Makefile
+    and usb_ohci.c warning differ in signedness
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 6073f61e078da5ddb521b56256bcc36508589883
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Sun Nov 18 12:55:02 2007 +0100
+
+    pb1x00 board: Fix u16 status declaration when PCMCIA is defined
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 8412d814ce8bf5570a2b747f1e7fd321097fe987
+Author: Wolfgang Denk <wd@denx.de>
+Date:  Sun Nov 18 17:11:09 2007 +0100
+
+    Fix compiler warnings for ARM systems.
+
+    Signed-off-by: Wolfgang Denk <wd@denx.de>
+
+commit 409ecdc0bb47dd28b0af6c25ffd658d22cc36b37
+Author: Wolfgang Denk <wd@denx.de>
+Date:  Sun Nov 18 16:36:27 2007 +0100
+
+    Fix compiler warnings for PPC systems. Update CHANGELOG.
+
+    Signed-off-by: Wolfgang Denk <wd@denx.de>
+
+commit 079c2c4fa71c0d1ebef394508df9088df8a308d3
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Sat Nov 17 11:31:10 2007 +0100
+
+    Fix warning differ in signedness in net/net.c and net/nfs.c
+
+commit 7e14fc65368cbd2861b1207453da55a4fc7b3f81
+Author: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+Date:  Sat Nov 17 20:42:45 2007 +0900
+
+    gth2.c: Fix a warning on gth2 build.
+
+    gth2.c: In function 'misc_init_r':
+    gth2.c:434: warning: pointer targets in passing argument 2 of 'setenv' differ in signedness
+
+    Signed-off-by: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+
+commit 2309c130aa4c84b91bd874a41269c923eb61b555
+Author: Stefan Roese <sr@denx.de>
+Date:  Sat Nov 17 07:58:25 2007 +0100
+
+    Fix warning differ in signedness in common/cmd_scsi.c
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 7e1d884b7cb602007329c517ec1c453e3a6a5d9c
+Author: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+Date:  Sat Nov 17 20:05:26 2007 +0900
+
+    [MIPS] cpu/mips/config.mk: Fix GNU assembler minor version picker
+
+    Current trick to pick up GNU assembler minor version does not work with the
+    latest binutils (2007-03-01 or later) due to ${PKGVERSION} now default to
+    "(GNU Binutils) ".
+
+      $ sde-as --version |grep "GNU assembler"
+      GNU assembler 2.15.94 mipssde-6.02.02-20050602
+      $ sde-as --version |grep "GNU assembler" |awk '{print $3}'
+      2.15.94
+      $ sde-as --version |grep "GNU assembler" |awk '{print $3}' |awk -F. '{print $2}'
+      15
+      $
+
+      $ mips-linux-as --version |grep "GNU assembler"
+      GNU assembler (GNU Binutils) 2.18
+      $ mips-linux-as --version |grep "GNU assembler" |awk '{print $3}'
+      (GNU
+      $ mips-linux-as --version |grep "GNU assembler" |awk '{print $3}' |awk -F. '{print $2}'
+      (no output)
+      $
+
+    As a result of above, you'll see many noises with such binutils:
+
+      make -C cpu/mips/
+      /bin/sh: line 0: [: : integer expression expected
+      /bin/sh: line 0: [: : integer expression expected
+      make[1]: Entering directory `/home/skuribay/devel/u-boot.git/cpu/mips'
+      mips-linux-gcc  -D__ASSEMBLY__ -g  -Os   -D__KERNEL__ -DTEXT_BASE=0xB0000000  -I/home/skuribay/devel/u-boot.git/include -fno-builtin -ffreestanding -nostdinc -isystem /home/skuribay/devel/buildroot/build_mips/staging_dir/usr/bin/../lib/gcc/mips-linux-uclibc/4.2.1/include -pipe  -DCONFIG_MIPS -D__MIPS__ -G 0 -mabicalls -fpic -pipe -msoft-float -march=4kc -mtune=4kc -EB -c -o incaip_wdt.o incaip_wdt.S
+      /bin/sh: line 0: [: : integer expression expected
+      mips-linux-gcc  -D__ASSEMBLY__ -g  -Os   -D__KERNEL__ -DTEXT_BASE=0xB0000000  -I/home/skuribay/devel/u-boot.git/include -fno-builtin -ffreestanding -nostdinc -isystem /home/skuribay/devel/buildroot/build_mips/staging_dir/usr/bin/../lib/gcc/mips-linux-uclibc/4.2.1/include -pipe  -DCONFIG_MIPS -D__MIPS__ -G 0 -mabicalls -fpic -pipe -msoft-float -march=4kc -mtune=4kc -EB -c -o cache.o cache.S
+      /bin/sh: line 0: [: : integer expression expected
+      mips-linux-gcc -g  -Os   -D__KERNEL__ -DTEXT_BASE=0xB0000000  -I/home/skuribay/devel/u-boot.git/include -fno-builtin -ffreestanding -nostdinc -isystem /home/skuribay/devel/buildroot/build_mips/staging_dir/usr/bin/../lib/gcc/mips-linux-uclibc/4.2.1/include -pipe  -DCONFIG_MIPS -D__MIPS__ -G 0 -mabicalls -fpic -pipe -msoft-float -march=4kc -mtune=4kc -EB -Wall -Wstrict-prototypes -c -o asc_serial.o asc_serial.c
+      /bin/sh: line 0: [: : integer expression expected
+
+    This patch simplifies the trick and makes it work with both versions of gas.
+    I also replace an expensive `awk (or gawk)' with `cut'.
+
+    Signed-off-by: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+
+commit 16664f72850846e645616da1c0fa5afcd6d15f15
+Author: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+Date:  Sat Nov 17 20:05:26 2007 +0900
+
+    [MIPS] Remove useless instructions for initializing $gp.
+
+    Signed-off-by: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+
+commit 03c031d5660ea946c39af6e2e16267da857c609f
+Author: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+Date:  Sat Oct 27 15:27:06 2007 +0900
+
+    [MIPS] MIPS 4K core: Coding style cleanups
+
+    No logical changes.
+
+    Signed-off-by: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+
+commit f5e429d3860bba4c6ae8bead8f78349fa24491b2
+Author: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+Date:  Sat Nov 17 20:05:20 2007 +0900
+
+    [MIPS] gth2.c: Fix a warning on gth2 build.
+
+    gth2.c: In function 'misc_init_r':
+    gth2.c:434: warning: pointer targets in passing argument 2 of 'setenv' differ in signedness
+
+    Signed-off-by: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+
+commit 4fbd0741b2b6441da10be93e10267122581b7079
+Author: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+Date:  Sat Oct 27 15:22:33 2007 +0900
+
+    [MIPS] au1x00_eth.c: Fixed a warning on pb1000 build.
+
+    au1x00_eth.c: In function 'au1x00_miiphy_write':
+    au1x00_eth.c:139: warning: 'return' with no value, in function returning non-void
+
+    Signed-off-by: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+
+commit f01320459736f156707425cf8112f98606301aa4
+Author: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+Date:  Sat Oct 27 15:00:25 2007 +0900
+
+    [MIPS] au1x00_eth.c: Fix au1x00_miiphy_{read,write} build error
+
+    au1x00_eth.c: In function 'au1x00_enet_initialize':
+    au1x00_eth.c:246: error: 'au1x00_miiphy_read' undeclared (first use in this function)
+    au1x00_eth.c:246: error: (Each undeclared identifier is reported only once
+    au1x00_eth.c:246: error: for each function it appears in.)
+    au1x00_eth.c:246: error: 'au1x00_miiphy_write' undeclared (first use in this function)
+    au1x00_eth.c: In function 'au1x00_miiphy_write':
+    au1x00_eth.c:298: warning: 'return' with no value, in function returning non-void
+    make[1]: *** [au1x00_eth.o] Error 1
+
+    Fixed by moving these two functions forward.
+
+    Signed-off-by: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+
+commit b09258c5393edd1087c5f39ae68338f16b49f8b3
+Author: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+Date:  Sat Oct 27 15:00:25 2007 +0900
+
+    MAKEALL: Added missing pb1000 board
+
+    Signed-off-by: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+
+commit 2e4a6e3667a1e39c0e6e99498686b15d2718b369
+Author: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+Date:  Sat Oct 27 15:00:24 2007 +0900
+
+    [MIPS] pb1000: Replace obsolete memsetup.S with lowlevel_init.S
+
+    Signed-off-by: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+
+commit 662e5cb397249c3ea88a4c3255e9ccfc40b98d82
+Author: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+Date:  Sat Oct 27 15:00:24 2007 +0900
+
+    [MIPS] u-boot.lds: Cleanup __u_boot_cmd_{start,end}
+
+    Signed-off-by: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+
+commit 5947f6999aafa7c54c1390983d264a8463dfea8e
+Author: Wolfgang Denk <wd@denx.de>
+Date:  Sat Nov 17 02:34:38 2007 +0100
+
+    Update CHANGELOIG, prepare for -rc4
+
+    Signed-off-by: Wolfgang Denk <wd@denx.de>
+
+commit fd329e6f05bbdfe6bd71b0e09f0c76d3b0a025a5
+Author: Luotao Fu <l.fu@pengutronix.de>
+Date:  Wed Nov 14 18:58:33 2007 +0100
+
+    Fix the i2c frequency and default address in rsdproto board
+
+    rsdproto board support has wrong I2C frequency and wrong return value
+    handling.
+
+    Signed-off-by: Luotao Fu <l.fu@pengutronix.de>
+
+commit 429c180edad038f91c989cb14b478228092e7054
+Author: Wolfgang Denk <wd@denx.de>
+Date:  Sat Nov 17 01:45:38 2007 +0100
+
+    powerpc: Backout relocation changes for MPC5121, too.
+
+    Apply Grant Likely's backout to MPC5121 code, too.
+
+    Pointed out by Rafal Jaworowski <raj@semihalf.com>
+
+    Signed-off-by: Wolfgang Denk <wd@denx.de>
+
+commit 1c3dd43338a077165e7e0309cb3994e65d2bdbf8
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Tue Nov 13 22:18:33 2007 -0700
+
+    powerpc: Backout relocation changes.
+
+    Ugh.  I *hate* to back this change out, but these compiler flags don't
+    work for relocation on all versions of GCC.  I've not been able to
+    reproduce the environment in my setup (and hence, not been able to
+    find a combination that *does* work), so I've got no choice but to go
+    back to the old gcc flags and linker script.
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 5c15010efad980ad5498cc565fc1ed70df2f52b4
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Tue Nov 13 09:11:05 2007 +0100
+
+    Fixed mips_io_port_base build errors.
+
+    This patch has been sent on:
+    - 29 Sep 2007
+
+    Although mips_io_port_base is currently a part of IDE command, it is quite
+    fundamental for MIPS I/O port access such as in[bwl] and out[bwl]. So move
+    it to MIPS general part, and introduce `set_io_port_base()' from Linux.
+
+    This patch is triggered by multiple definition of `mips_io_port_base' build
+    error on gth2 (and tb0229 also needs this fix.)
+
+    board/gth2/libgth2.a(gth2.o): In function `log_serial_char':
+    /home/skuribay/devel/u-boot.git/board/gth2/gth2.c:47: multiple definition of `mips_io_port_base'
+    common/libcommon.a(cmd_ide.o):/home/skuribay/devel/u-boot.git/common/cmd_ide.c:712: first defined here
+    make: *** [u-boot] Error 1
+
+    Signed-off-by: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 6ecbb7a3fa9b0940ed33e490d195d4b6830b2422
+Author: Wolfgang Denk <wd@denx.de>
+Date:  Sat Nov 17 01:30:40 2007 +0100
+
+    Fix a bug in the slave serial programming mode for the Xilinx
+    Spartan2/3 FPGAs. The old code used "< 0" on a "char" type to test if
+    the most significant bit was set, which did not work on any
+    architecture where "char" defaulted to be an unsigned type.
+
+    Based on a patch by Angelos Manousaridis <amanous@inaccessnetworks.com>
+
+    Signed-off-by: Wolfgang Denk <wd@denx.de>
+
+commit d08b7233bc252faad8339e7ca0ddfd62fa79903c
+Author: Jon Loeliger <jdl@freescale.com>
+Date:  Thu Nov 1 12:23:29 2007 -0500
+
+    86xx: Fix broken variable reference when #def DEBUGing.
+
+    Sometimes you can't reference the DDR2 controller variables.
+
+    Signed-off-by: Jon Loeliger <jdl@freescale.com>
+
+commit f9d9164d9c6b5a7f0393fd8d7e246b8a0326bc19
+Author: Jason Jin <Jason.jin@freescale.com>
+Date:  Fri Oct 26 18:32:00 2007 +0800
+
+    make 8610 board use pixis reset
+
+    Signed-off-by: Jason Jin <Jason.jin@freescale.com>
+
+commit db74b3c1c9481a6bffbf8cd445e5bcbf6908e836
+Author: Jason Jin <Jason.jin@freescale.com>
+Date:  Mon Oct 29 19:26:21 2007 +0800
+
+    Unify pixis_reset altbank across board families
+
+    Basically, refactor the CFG_PIXIS_VBOOT_MASK values
+    into the separate board config files.
+
+    Signed-off-by: Jason Jin <Jason.jin@freescale.com>
+    Signed-off-by: Jon Loeliger <jdl@freescale.com>
+
+commit 64bf555465c7926be13e1046ac0d0f05ac72829c
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Wed Nov 7 08:19:21 2007 +0100
+
+    Fix warning: pointer targets in assignment differ in signedness
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 7a60ee7c6248a958c5757d3660a1702723a2786d
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Wed Nov 7 08:19:19 2007 +0100
+
+    Fix warning differ in signedness in common/cmd_ide.c
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 4d4faae65e115e327425cd514c1a35146a85166b
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Mon Sep 24 09:05:31 2007 -0600
+
+    Group PCI and PCMCIA drivers in drivers/Makefile
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 5798f87dc10a496d79d3177b9f5a76488987fd35
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Mon Sep 24 09:05:31 2007 -0600
+
+    Group block/flash drivers in drivers/Makefile
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit df58c81551700f058b44cacf55a7997fa63bfe0a
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Mon Sep 24 09:05:31 2007 -0600
+
+    Group USB drivers in drivers/Makefile
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 5dbb6ed622e539b0c8493ef7e578d3a533181d29
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Mon Sep 24 09:05:30 2007 -0600
+
+    Group i2c drivers in drivers/Makefile
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit ec00c76de0e5971273905998d62d6bb119324218
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Mon Sep 24 09:05:30 2007 -0600
+
+    Group console drivers in drivers/Makefile
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 754f230aa01b8c789fc31f8013c2487954073300
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Mon Sep 24 09:05:30 2007 -0600
+
+    Group network drivers in drivers/Makefile
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit f0037c56b0d12cd46215124667b9f83d60ef9391
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Mon Sep 24 09:05:30 2007 -0600
+
+    Build: split COBJS value into multiple lines
+
+    This change is in preparation for condtitionial compile support in the
+    build system.  By spliting them all into seperate lines now, subsequent
+    patches that change 'COBJS-y += ' into 'COBJS-$(CONFIG_<blah>) += ' will
+    be less invasive and easier to review
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 1b4aaffe4fb2a5e95d9111a5d94fd1f89215dce4
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Mon Sep 24 09:05:30 2007 -0600
+
+    Add .gitignore files
+
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+    Acked-by: Kim Phillips <kim.phillips@freescale.com>
+
+commit 955413f35f054a82e40042f1dbcf501c6a05719b
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Thu Nov 15 08:27:52 2007 -0700
+
+    Revert "Correct relocation fixup for mpc5xx"
+
+    This reverts commit 3649cd99ba815b6601868735765602f00ef3692b.
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit e15633888a058aacb31a62d2cf1278e1e4c236ab
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Thu Nov 15 08:24:32 2007 -0700
+
+    Revert "Correct fixup relocation for MPC5xxx"
+
+    This reverts commit 6f7576b20ecf0d040c3ac3b032b5cbc860e38a90.
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 139365fbe566d0fc619a1ed04452ec5388f0cef8
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Thu Nov 15 08:21:04 2007 -0700
+
+    Revert "Correct fixup relocation for mpc8220"
+
+    This reverts commit a85dd254c0577fca13627c46e93fc2ad4c4f1f00.
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 70922342369e5e39b286fe21e768a239ca07a514
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Thu Nov 15 08:20:57 2007 -0700
+
+    Revert "Correct fixup relocation for mpc824x"
+
+    This reverts commit f3a52fe05923935db86985daf9438e2f70ac39aa.
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 96279ab4cad60cb5972aa934fbe4845ac02cc75a
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Thu Nov 15 08:20:50 2007 -0700
+
+    Revert "Correct fixup relocation for mpc8260"
+
+    This reverts commit 5af61b2f4b838a05f79be274f3e5a66edd2d9c96.
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 928fe33b24cdf382a8dc8687fed24b1961cdb5d6
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Thu Nov 15 08:20:43 2007 -0700
+
+    Revert "Correct fixup relocation for mpc83xx"
+
+    This reverts commit 057004f4a4863554d56cc56268bfa7c7d9738e27.
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit c93945e8f9e300860d2bf73a2549ce5794f8bd00
+Author: Grant Likely <grant.likely@secretlab.ca>
+Date:  Thu Nov 15 08:20:25 2007 -0700
+
+    Revert "[MPC512x] Correct fixup relocation"
+
+    This reverts commit 8d17979d0359492a822a0a409d26e3a3549b4cd4.
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit 54fd6c93c28a0a45352fff5dd92673401ff563f2
+Author: Stefan Roese <sr@denx.de>
+Date:  Tue Nov 13 08:18:20 2007 +0100
+
+    ppc4xx: lwmon5: Change PHY reset sequence for PHY MDIO address latching
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit 1ce55151c85d068f70317a8d65c61058b891afb4
+Author: Heiko Schocher <hs@denx.de>
+Date:  Tue Nov 13 07:50:29 2007 +0100
+
+    [UC101] SRAM now with 2 MB working.
+
+    Signed-off-by: Heiko Schocher <hs@denx.de>
+
+commit 8d737a28152ec12873f8544cca1fb39a49e5e693
+Author: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+Date:  Thu Nov 8 12:50:18 2007 -0600
+
+    ColdFire: MCF5329 - Remove reset registers from CCM
+
+    Signed-off-by: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+
+commit 7d7cdea769a60b0a6e4c18bef7f9d648fd14b8d7
+Author: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+Date:  Thu Nov 8 12:31:11 2007 -0600
+
+    ColdFire: MCF5329 - Add Reset structure to immap_5329.h
+
+    Signed-off-by: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+
+commit 09b26cf00d76d75fdf7fdc4b13e4dd929743bc21
+Author: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+Date:  Thu Nov 8 12:19:01 2007 -0600
+
+    ColdFire: MCF5329 - revert include/asm-m68k/m5329.h file mode
+
+    Signed-off-by: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+
+commit 225a24b5e062ad94627424508ae814f51dbe1a34
+Author: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+Date:  Wed Nov 7 18:00:54 2007 -0600
+
+    ColdFire: MCF5445x - Update correct RAMBAR and missing linker files
+
+    Signed-off-by: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+
+commit 248c7c14835f34d5d910b45e5600050e58ca6cab
+Author: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+Date:  Wed Nov 7 17:56:15 2007 -0600
+
+    ColdFire: MCF532x - Update do_reset() using core reset
+
+    Signed-off-by: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+
+commit d9240a5f827eb3b476a6ba2938d01f1a9e7688f4
+Author: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+Date:  Wed Nov 7 17:51:00 2007 -0600
+
+    ColdFire: Update cpu flag for 4.2-xx compiler
+
+    Signed-off-by: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+
+commit 1f103105a3746ab12279b63b8c1d372c0ce2cc58
+Author: Roy Zang <tie-fei.zang@freescale.com>
+Date:  Mon Nov 5 17:39:24 2007 +0800
+
+    Implement general ULi 526x Ethernet driver support in U-boot
+
+    This patch implements general ULi 526x Ethernet driver.
+    Until now, it is the only native Ethernet port on
+    MPC8610HPCD board, but it could be used on other boards
+    with ULi 526x Ethernet port as well.
+
+    Signed-off-by: Roy Zang <tie-fei.zang@freescale.com>
+    Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
+    Acked-by: Jon Loeliger <jdl@freescale.com>
+    Signed-off-by: Ben Warren <bwarren@qstreams.com>
+
+commit 71bc6e6474fea8ef481b9b45d1edd7ad1f6dfbbd
+Author: Larry Johnson <lrj@arlinx.com>
+Date:  Thu Nov 1 08:46:50 2007 -0500
+
+    NET: Add Ethernet 1000BASE-X support for PPC4xx
+
+    This patch adds support for 1000BASE-X to functions "miiphy_speed ()" and
+    "miiphy_duplex()". It also adds function "miiphy_is_1000base_x ()", which
+    returns non-zero iff the PHY registers are configured for 1000BASE-X.  The
+    "mii info" command is modified to distinguish between 1000BASE-T and -X.
+
+    Signed-off-by: Larry Johnson <lrj@acm.org>
+    Signed-off-by: Ben Warren <bwarren@qstreams.com>
+
+commit 298035df4948b113d29ac0e694717d34b95bc5dc
+Author: Larry Johnson <lrj@arlinx.com>
+Date:  Wed Oct 31 11:21:29 2007 -0500
+
+    NET: Cosmetic changes
+
+    Signed-off-by: Larry Johnson <lrj@acm.org>
+    Signed-off-by: Ben Warren <bwarren@qstreams.com>
+
+commit 992742a5b09d9040adbd156fb90756af66ade310
+Author: Wolfgang Denk <wd@denx.de>
+Date:  Sat Nov 3 23:09:27 2007 +0100
+
+    Cleanup coding style; update CHANGELOG
+
+    Signed-off-by: Wolfgang Denk <wd@denx.de>
+
+commit e881cb563e32f45832b7b6db77bdcd017adcbb41
+Author: Bruce Adler <bruce.adler@ccpu.com>
+Date:  Fri Nov 2 13:15:42 2007 -0700
+
+    fix wording in README
+
+    Changed the wording to properly describe the shadowing
+    of the environment from ROM to RAM
+
+    Signed-off-by: Bruce Adler <bruce.adler@acm.org>
+
+commit ad845beef06245426c57b53dcdc01b7dc70e0d45
+Author: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+Date:  Wed Oct 31 02:18:15 2007 +0900
+
+    blackfin: Move `-D__BLACKFIN__' to $(ARCH)_config.mk
+
+    Signed-off-by: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
+
+commit ec22755799466c8a103664bb3a5e647bf9c238f4
+Author: Vlad Lungu <vlad@comsys.ro>
+Date:  Thu Oct 25 16:08:14 2007 +0300
+
+    Trimmed some variables in ne2000.c
+
+    Signed-off-by: Vlad Lungu <vlad@comsys.ro>
+
+commit eb6f214d3644b2a77968c176ed36dcf858cfe7e0
+Author: Zhang Wei <wei.zhang@freescale.com>
+Date:  Thu Oct 25 17:51:27 2007 +0800
+
+    Fix the issue of usb_kbd driver missing the scan code of key 'z'.
+
+    The scan code of the key 'z' is 0x1d, which should be handled.
+
+    The change has be tested on NOVATEK USB keyboard and ULI PCI OHCI
+    controller.
+
+    Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
+
+commit bbf4796f6498fbade56d56eff3a0a49b299d93e5
+Author: Zhang Wei <wei.zhang@freescale.com>
+Date:  Thu Oct 25 17:30:04 2007 +0800
+
+    Fix USB support issue for MPC8641HPCN board.
+
+    The configuration file has already enabled USB, but it
+    missed definition of CFG_OHCI_SWAP_REG_ACCESS, the USB
+    on MPC8641HPCN can not work because of the wrong USB
+    register endian.
+
+    And add the USB command to U-Boot commands list.
+
+    Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
+
+commit 4e62041023dc3de9d98d977bb080235bc6d035e0
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Wed Oct 24 18:16:01 2007 +0200
+
+    Use config_cmd_default.h instead of config_cmd_all.h
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 56622f87857439b1c221e9deef11a9d5bb5d4308
+Author: Marian Balakowicz <m8@semihalf.com>
+Date:  Wed Oct 24 01:37:36 2007 +0200
+
+    TQM5200: Call usb_cpu_init() during board init
+
+    usb_cpu_init() configures GPS USB pins, clocks, etc. and
+    is required for proper operation of kernel USB subsystem.
+    This setup was previously done in the kernel by the fixup
+    code which is being removed, thus low level init must be
+    done by U-boot now.
+
+    Signed-off-by: Marian Balakowicz <m8@semihalf.com>
+
+commit 29c29c0267fe857e72014ce90c5d35b2ef6302bd
+Author: Guennadi Liakhovetski <lg@denx.de>
+Date:  Tue Oct 23 16:25:50 2007 +0200
+
+    Fix typo in nfs.c
+
+    An obvious typo. Originally fixed in linkstation u-boot port.
+
+    Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
+
+commit 59543fe00a4ce720ef9f5aa7fb387c6daf1c7d78
+Author: Guennadi Liakhovetski <lg@denx.de>
+Date:  Tue Oct 23 14:35:05 2007 +0200
+
+    Fix a typo in cpu/mpc824x/interrupts.c
+
+    Since December 2003 the timer_interrupt_cpu() function in
+    cpu/mpc824x/interrupts.c contains what seems to be a superfluous
+    parameter. Remove it.
+
+    Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
+
+commit c9e7b9b9a1700fe009678d1f9b41e6364ac5df2d
+Author: Sergej Stepanov <Sergej.Stepanov@ids.de>
+Date:  Wed Oct 17 11:13:51 2007 +0200
+
+    add ft_cpu_setup(..) on mpc8260
+
+    Add ft_cpu_setup(..)-function to adapt it for use with libfdt
+    based on code from mpc5xxx
+
+    Sigend-off-by: Sergej Stepanov <Sergej.Stepanov@ids.de>
+    --
+
+commit 6abd82e19ae93c0b4d104e50165e235915ec0875
+Author: Sergej Stepanov <Sergej.Stepanov@ids.de>
+Date:  Wed Oct 17 11:18:42 2007 +0200
+
+    changes for IDS8247 board support
+
+    To get the IDS8247 board working following are done:
+     - FCC2 is deactivated
+     - FCC1 is activated
+     - I2C is activated
+     - CFI driver is activated
+     - Adapted for use with LIBFDT
+
+    Signed-off-by: Sergej Stepanov <Sergej.Stepanov@ids.de>
+    --
+
+commit 8b6684a698500be9c142ec2c9f46cfc348e17f0c
+Author: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date:  Wed Oct 24 15:48:37 2007 +0200
+
+    ATSTK1002: Remove default ethernet addresses
+
+    Wolfgang is right: It's not a good idea to set up default initial
+    ethernet addresses for a board, even though they belong to the local
+    range.
+
+    This will change the failure mode from "IT manager screams at you for
+    using duplicate ethernet addresses" to a nice error message explaining
+    that the ethernet address hasn't been set properly.
+
+    Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
+
+commit e5c794e491a57d829b6d8733e2ed8368a2269abf
+Author: Justin Flammia <jflammia@savantav.com>
+Date:  Mon Oct 29 17:40:35 2007 -0400
+
+    DHCP Client Fix
+
+    This is a multi-part message in MIME format.
+
+    commit e6e505eae94ed721e123e177489291fc4544b7b8
+    Author: Justin Flammia <jflammia@savantav.com>
+    Date:   Mon Oct 29 17:19:03 2007 -0400
+
+       Found a bug in the way the DHCP Request packet is built, where the IP address
+       that is offered by the server is bound to prematurely. This patch is a fix of
+       that bug where the IP address offered by the DHCP server is not used until
+       after the DHCP ACK from the server is received.
+
+    Signed-off-by: Justin Flammia <jflammia@savantav.com>
+    Signed-off-by: Ben Warren <bwarren@qstreams.com>
+
+commit 31548249decf18a6b877a18436b6139dd483fe4a
+Author: Justin Flammia <jflammia@savantav.com>
+Date:  Mon Oct 29 17:40:35 2007 -0400
+
+    DHCP Client Fix
+
+    This is a multi-part message in MIME format.
+
+    commit e6e505eae94ed721e123e177489291fc4544b7b8
+    Author: Justin Flammia <jflammia@savantav.com>
+    Date:   Mon Oct 29 17:19:03 2007 -0400
+
+       Found a bug in the way the DHCP Request packet is built, where the IP address
+       that is offered by the server is bound to prematurely. This patch is a fix of
+       that bug where the IP address offered by the DHCP server is not used until
+       after the DHCP ACK from the server is received.
+
+    Signed-off-by: Justin Flammia <jflammia@savantav.com>
+    Signed-off-by: Ben Warren <bwarren@qstreams.com>
+
+commit e8ee8f3ade2a06c1893dd5e68f223070d650c7ed
+Author: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+Date:  Thu Oct 25 17:16:22 2007 -0500
+
+    ColdFire 54455: Fix correct boot location for atmel and intel
+
+    Signed-off-by: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+
+commit 688e8eb414ac111cca7ce60bdf30e805ab9a7bcb
+Author: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+Date:  Thu Oct 25 17:14:00 2007 -0500
+
+    ColdFire: Fix build error when CONFIG_WATCHDOG is defined
+
+    Signed-off-by: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+
+commit c67e12e705b204cfe914e3e3e693d69a445dcabf
+Author: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+Date:  Thu Oct 25 17:12:36 2007 -0500
+
+    ColdFire 5329: Assign correct SDRAM size and fix cache
+
+    Signed-off-by: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+
+commit 95e9f2c212a65610b2e59a5c00d0113383a4da0b
+Author: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+Date:  Thu Oct 25 17:10:23 2007 -0500
+
+    ColdFire 5253: Assign correct SDRAM size
+
+    Signed-off-by: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+
+commit 2acefa72ee0026f862ab65597ca687428f63a973
+Author: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+Date:  Thu Oct 25 17:09:17 2007 -0500
+
+    ColdFire 5282: Fix external flash boot and return dramsize
+
+    Signed-off-by: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
+
+commit d78791ae914d4e7c5edca1cdad73b3dc81a4eb82
+Author: Bartlomiej Sieka <tur@semihalf.com>
+Date:  Thu Oct 25 17:20:01 2007 +0200
+
+    TQM5200: increase kernel_addr_r and fdt_addr_r (hinted by Wolfgang Denk).
+
+    Signed-off-by: Bartlomiej Sieka <tur@semihalf.com>
+
+commit 1a0ce20aa4cb4e3068da04e7290ee9986fd0b834
+Author: Martin Krause <martin.krause@tqs.de>
+Date:  Wed Oct 24 08:42:25 2007 +0200
+
+    TQM5200: fix spurious characters on second serial interface
+
+    With this patch PSC3 is configured as UART. This is done, because if
+    the pins of PSC3 are not configured at all (-> all pins are GPI),
+    due to crosstalk, spurious characters may be send over the RX232_2_TXD
+    signal line.
+
+    Signed-off-by: Martin Krause <martin.krause@tqs.de>
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit be4a87f11e297a5cededbf7dd71c0248f3874acd
+Author: Martin Krause <martin.krause@tqs.de>
+Date:  Wed Oct 24 08:41:27 2007 +0200
+
+    TQM5200S: fix commands for STK52xx base board because of missing SM501 grafic controller
+
+    Some commands for the STK52xx base board try to access the SM501 grafic
+    controller. But the TQM5200S has no grafic controller (only the TQM5200
+    and the TQM5200B have). This patch deactivates the commands accessing
+    the SM501 for the TQM5200S.
+
+    Signed-off-by: Martin Krause <martin.krause@tqs.de>
+    Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+
+commit b31f64343ead9482cd439b1adbe4c34026a641b1
+Author: Martin Krause <martin.krause@tqs.de>
+Date:  Mon Oct 22 16:45:53 2007 +0200
+
+    TQM5200: fix spurious characters on second serial interface
+
+    With this patch PSC3 is configured as UART. This is done, because if
+    the pins of PSC3 are not configured at all (-> all pins are GPI),
+    due to crosstalk, spurious characters may be send over the RX232_2_TXD
+    signal line.
+
+    Signed-off-by: Martin Krause <martin.krause@tqs.de>
+
+commit 0fc0f91b20ffa802f5a66534ca5c2844910583f6
+Author: Martin Krause <martin.krause@tqs.de>
+Date:  Mon Oct 22 16:40:06 2007 +0200
+
+    TQM5200S: fix commands for STK52xx base board because of missing SM501 grafic controller
+
+    Some commands for the STK52xx base board try to access the SM501 grafic
+    controller. But the TQM5200S has no grafic controller (only the TQM5200
+    and the TQM5200B have). This patch deactivates the commands accessing
+    the SM501 for the TQM5200S.
+
+    Signed-off-by: Martin Krause <martin.krause@tqs.de>
+
+commit 7b0a42219f30277f71f4405cbaf8a269f6d2d227
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Sun Oct 21 09:14:28 2007 +0200
+
+    Mips: Fix string functions differ prototype declaration
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit cb8250fe4b3c4ed549b270e8a20bc22060e7e1d2
+Author: Ed Swarthout <Ed.Swarthout@freescale.com>
+Date:  Fri Oct 19 17:51:40 2007 -0500
+
+    fsl_pci_init enable COMMAND_MEMORY if inbound window
+
+    Patch 16e23c3f removed PCSRBAR allocation. But passing zero windows
+    to pciauto_setup_device has the side effect of not getting
+    COMMAND_MEMORY set.
+
+    Signed-off-by: Ed Swarthout <Ed.Swarthout@freescale.com>
+
+commit e9d0d527992566ebef9826962ff1745b2f082b92
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Fri Oct 19 10:55:24 2007 +0200
+
+    delta: Fix OHCI_REGS_BASE undeclared and wait_ms implicit declaration
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 9c4884f54da982ce990c7d1760ac81b0704d3c64
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Fri Oct 19 08:10:15 2007 +0200
+
+    fix warning: no return statement in function returning non-void
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit e78220f6e514206757acfe247297fc9a328a881f
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Fri Oct 19 06:33:45 2007 +0200
+
+    xsengine: Fix no partition type specified, use DOS as default
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 10cdb8dbd67a818823ab9ec88b68fc348903db59
+Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Date:  Fri Oct 19 00:24:59 2007 +0200
+
+    lubbock: Fix no partition type specified, use DOS as default
+
+    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+
+commit 41b4d282d38fa7231c315c5f6cfff5bdd24e0191
+Author: Wolfgang Denk <wd@denx.de>
+Date:  Tue Oct 23 16:50:03 2007 +0200
+
+    Coding style: keep lists sorted; update CHANGELOG
+
+    Signed-off-by: Wolfgang Denk <wd@denx.de>
+
 commit 58b74b05c621e2835ecf4e2d3243042cf4186777
 Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
 Date:  Fri Oct 19 00:09:05 2007 +0200
@@ -51,6 +1295,120 @@ Date:     Wed Oct 17 11:56:31 2007 -0500
     are added to u-boot.
     Signed-off-by Rune Torgersen <runet@innovsys.com>
 
+commit d3afa1ee19345a31fd1eaad3e98b97d13ca47315
+Author: Bartlomiej Sieka <tur@semihalf.com>
+Date:  Tue Oct 23 13:14:10 2007 +0200
+
+    Motion-PRO: Update configuration to accomodate next generation board.
+
+    New board has faster oscillator and a different Flash chip. This affects:
+    - CFG_MPC5XXX_CLKIN
+    - SDRAM timings
+    - Flash CS configuration (timings)
+    - Flash sector size, and thus MTD partition layout
+    - malloc() arena size (due to bigger Flash sectors)
+    - smaller memory test range (due to bigger malloc() arena)
+
+    This patch also enables more extensive memory testing via "mtest".
+
+    Signed-off-by: Bartlomiej Sieka <tur@semihalf.com>
+
+commit eff501904df2bf1724a750062628ba2c51dbb1f8
+Author: Bartlomiej Sieka <tur@semihalf.com>
+Date:  Tue Oct 23 11:36:07 2007 +0200
+
+    Motion-PRO: Add setting of SDelay reg. to SDRAM controller configuration.
+
+    Per AN3221 (MPC5200B SDRAM Initialization and Configuration), the SDelay
+    register must be written a value of 0x00000004 as the first step of the
+    SDRAM contorller configuration.
+
+    Signed-off-by: Bartlomiej Sieka <tur@semihalf.com>
+
+commit 7a9348728ebda63cdbaacffd83099aa71d9d4c54
+Author: Peter Pearse <peter.pearse@arm.com>
+Date:  Tue Oct 23 10:22:16 2007 +0100
+
+    Move PL01* serial drivers to drivers/serial and adjust Makefiles.
+
+commit 20d500d531a6b971ce6cc1bf191cb0092cdc0afc
+Author: Stefan Roese <sr@denx.de>
+Date:  Tue Oct 23 10:17:42 2007 +0200
+
+    ppc4xx: lwmon5: Some further GPIO config changes
+
+    Signed-off-by: Stefan Roese <sr@denx.de>
+
+commit de9a738faa7c2f47286119c3bfebc3dfbfe7d86d
+Author: Vlad Lungu <vlad@comsys.ro>
+Date:  Sun Oct 21 22:10:10 2007 +0900
+
+    [MIPS] Fix UNCACHED_SDRAM
+
+    PHYSADDR is for physical address, KSEG1ADDR is for uncached.
+
+    Signed-off-by: Vlad Lungu <vlad@comsys.ro>
+    Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi@necel.com>
+
+commit 00101dd7a32d12f698150123e47e4b3420279f86
+Author: Shinya Kuribayashi <shinya.kuribayashi@necel.com>
+Date:  Sun Oct 21 21:30:42 2007 +0900
+
+    [MIPS] Add PIC-related switches to PLATFORM_{CPP,LD}FLAGS and cleanup
+
+    Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi@necel.com>
+
+commit eb700636db017d310edaeb559b13d82588560674
+Author: Shinya Kuribayashi <shinya.kuribayashi@necel.com>
+Date:  Sun Oct 21 10:55:37 2007 +0900
+
+    [MIPS] u-boot.lds: Define _gp in a standard manner
+
+    Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi@necel.com>
+
+commit 22069215eb7adf5a3888bf7c7784ea9d70a72cd0
+Author: Shinya Kuribayashi <shinya.kuribayashi@necel.com>
+Date:  Sun Oct 21 10:55:36 2007 +0900
+
+    [MIPS] Fix $gp usage
+
+    Now we load $gp with _GLOBAL_OFFSET_TABLE_, but this is incorrect use.
+    As a general principle, we should use _gp for $gp.
+
+    Thanks to linker script's help we fortunately have _gp which equals to
+    _GLOBAL_OFFSET_TABLE_. But once _gp gets out of alignment, we will not
+    be able to access to GOT entires, global variables and procedure entry
+    points. The right thing to do is to use _gp.
+
+    This patch also introduce a new symbol `.gpword _GLOBAL_OFFSET_TABLE_'
+    which holds the offset from _gp. When updating GOT entries, we use this
+    offset and _gp to calculate the final _GLOBAL_OFFSET_TABLE_.
+
+    This patch is originally submitted by Vlad Lungu <vlad@comsys.ro>, then
+    I made some change to leave over num_got_entries.
+
+    Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi@necel.com>
+    Cc: Vlad Lungu <vlad@comsys.ro>
+
+commit cbf2323b5b8285ea01acba7bbb905a3162d9b021
+Author: Shinya Kuribayashi <shinya.kuribayashi@necel.com>
+Date:  Sun Oct 21 10:55:36 2007 +0900
+
+    [MIPS] u-boot.lds: Fix __got_start and __got_end
+
+    Ensure that __got_start points to top of the `.got', and __got_end points
+    to bottom as well, so that we never fail to count num_got_entries.
+
+    Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi@necel.com>
+
+commit e5f325fec5b48ae705c89522923ba5a2e37cd5c7
+Author: Shinya Kuribayashi <shinya.kuribayashi@necel.com>
+Date:  Sun Oct 21 10:55:36 2007 +0900
+
+    [MIPS] u-boot.lds: Remove duplicated .sdata section
+
+    Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi@necel.com>
+
 commit 05bf4919c1ce49cdedadacd564d0786a8ed796a1
 Author: Wolfgang Denk <wd@denx.de>
 Date:  Sun Oct 21 01:01:17 2007 +0200
@@ -73,6 +1431,84 @@ Date:      Thu Oct 4 20:47:10 2007 +0300
 
     Signed-off-by: Vlad Lungu <vlad@comsys.ro>
 
+commit df90968b48fb34fa9072fab150db2ac89678f537
+Author: urwithsughosh@gmail.com <urwithsughosh@gmail.com>
+Date:  Mon Sep 24 13:32:13 2007 -0400
+
+    Setting MSR[DE] in do_reset
+
+    Hello,
+       This patch ensures the soft reset of the board for the 85xx boards
+       by setting the MSR[DE] in the do_reset function.
+
+    Signed-off-by: Sughosh Ganu <urwithsughosh@gmail.com>
+
+commit 1e701e701304b3c3a3768ca83dd2ab7b9e88c77d
+Author: urwithsughosh@gmail.com <urwithsughosh@gmail.com>
+Date:  Mon Sep 24 13:36:01 2007 -0400
+
+    MSR overwrite fix
+
+    Hello,
+      This patch fixes the MSR overwrite in the start.S when moving out of
+      the last 4K page.
+
+    Signed-off-by: Sughosh Ganu <urwithsughosh@gmail.com>
+
+commit 5c7ea64bb74a850a2b2303f853a8270695ad8602
+Author: Dan Wilson <dwilson@fulcrummicro.com>
+Date:  Fri Oct 19 11:33:48 2007 -0500
+
+    tsec driver should clear RHALT on startup
+
+    This was causing problems for some people.
+
+    Signed-off-by: Alain Gravel <agravel@fulcrummicro.com>
+    Signed-off-by: Dan Wilson <dwilson@fulcrummicro.com>
+    Signed-off-by: Andy Fleming <afleming@freescale.com>
+
+commit 7600d47b8f6a10019e537dc9a62aa1498df58d25
+Author: Kumar Gala <galak@kernel.crashing.org>
+Date:  Thu Oct 11 00:29:18 2007 -0500
+
+    Improve handling of PCI interrupt device tree fixup on MPC85xx CDS
+
+    On the MPC85xx CDS we have two issues:
+
+    1. The device tree fixup code did not check to see if the property we are
+    trying to update is actually found.  Its possible that it would update
+    random memory starting at 0.
+
+    2. Newer Linux kernel's have moved the location of the PCI nodes to be
+    sibilings of the soc node and not children.  The explicit PATH to the PCI
+    node would not be found for these device trees.  Add the ability to handle
+    both paths.  In the future we shouldn't handle such fixups by explicit path.
+
+    Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
+
+commit a3063eec775719b7e91023bbec3f64b3118791df
+Author: Kumar Gala <galak@kernel.crashing.org>
+Date:  Thu Oct 11 00:18:48 2007 -0500
+
+    Set OF_STDOUT_PATH to match the default console on MPC8568 MDS
+
+    On the MPC8568 MDS we use ttyS0, UART0, etc. as the standard configured
+    console.  Make it so we match that config what we tell Linux as the early
+    STDOUT console.
+
+    Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
+
+commit e1ce3cb617bb06f91f82f98915391175addf3e82
+Author: Kumar Gala <galak@kernel.crashing.org>
+Date:  Tue Oct 2 11:12:27 2007 -0500
+
+    Remove magic numbers from cache related operations for mpc85xx
+
+    The mpc85xx start code uses some magic numbers that we actually
+    have #defines for in <config.h> so use those instead.
+
+    Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
+
 commit 5441f61a3d8b7034f19fc1361183e936198e6dbb
 Author: Detlev Zundel <dzu@denx.de>
 Date:  Fri Oct 19 16:47:26 2007 +0200
@@ -409,6 +1845,16 @@ Date:     Tue Sep 11 14:12:55 2007 +0200
 
     Signed-off-by: Stefan Roese <sr@denx.de>
 
+commit 1487adbdcf9594bb2eb686325a6f9540dad1b70a
+Author: Ed Swarthout <Ed.Swarthout@freescale.com>
+Date:  Wed Sep 26 16:35:54 2007 -0500
+
+    85xx io out functions need sync after write.
+
+    This fixes the mc146818 rtc_read/write functions for 85xx.
+
+    Signed-off-by: Ed Swarthout <Ed.Swarthout@freescale.com>
+
 commit 0d38effc6e359e6b1b0c78d66e8bc1a4dc15a2ae
 Author: Grant Likely <grant.likely@secretlab.ca>
 Date:  Tue Sep 25 15:48:05 2007 -0600
diff --git a/MAKEALL b/MAKEALL
index ef181bac73dbb7bf961219bba3a3f36a957b445b..fb53a9141cd54525e6f9b62800c37e1818dd5073 100755 (executable)
--- a/MAKEALL
+++ b/MAKEALL
@@ -383,6 +383,7 @@ LIST_7xx="          \
 
 LIST_ppc="             \
        ${LIST_5xx}     \
+       ${LIST_512x}    \
        ${LIST_5xxx}    \
        ${LIST_8xx}     \
        ${LIST_8220}    \
@@ -559,6 +560,7 @@ LIST_mips5kc_el=""
 
 LIST_au1xx0_el="       \
        dbau1550_el     \
+       pb1000          \
 "
 
 LIST_mips_el="                 \
index 35f8d31095d008e48778736f432ff5d6a24ae724..c73d4cfeff0220f57b1daaa835163e774ce0b31f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -23,8 +23,8 @@
 
 VERSION = 1
 PATCHLEVEL = 3
-SUBLEVEL = 0
-EXTRAVERSION = -rc3
+SUBLEVEL = 1
+EXTRAVERSION =
 U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 VERSION_FILE = $(obj)include/version_autogenerated.h
 
@@ -205,22 +205,30 @@ LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs
        fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a
 LIBS += net/libnet.a
 LIBS += disk/libdisk.a
-LIBS += rtc/librtc.a
-LIBS += dtt/libdtt.a
-LIBS += drivers/libdrivers.a
 LIBS += drivers/bios_emulator/libatibiosemu.a
-LIBS += drivers/nand/libnand.a
-LIBS += drivers/nand_legacy/libnand_legacy.a
-LIBS += drivers/onenand/libonenand.a
+LIBS += drivers/block/libblock.a
+LIBS += drivers/hwmon/libhwmon.a
+LIBS += drivers/i2c/libi2c.a
+LIBS += drivers/input/libinput.a
+LIBS += drivers/misc/libmisc.a
+LIBS += drivers/mtd/libmtd.a
+LIBS += drivers/mtd/nand/libnand.a
+LIBS += drivers/mtd/nand_legacy/libnand_legacy.a
+LIBS += drivers/mtd/onenand/libonenand.a
 LIBS += drivers/net/libnet.a
+LIBS += drivers/net/sk98lin/libsk98lin.a
+LIBS += drivers/pci/libpci.a
+LIBS += drivers/pcmcia/libpcmcia.a
 ifeq ($(CPU),mpc83xx)
 LIBS += drivers/qe/qe.a
 endif
 ifeq ($(CPU),mpc85xx)
 LIBS += drivers/qe/qe.a
 endif
+LIBS += drivers/rtc/librtc.a
 LIBS += drivers/serial/libserial.a
-LIBS += drivers/sk98lin/libsk98lin.a
+LIBS += drivers/usb/libusb.a
+LIBS += drivers/video/libvideo.a
 LIBS += post/libpost.a post/drivers/libpostdrivers.a
 LIBS += $(shell if [ -d post/lib_$(ARCH) ]; then echo \
        "post/lib_$(ARCH)/libpost$(ARCH).a"; fi)
@@ -323,25 +331,65 @@ env:
 depend dep:    version
                for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir _depend ; done
 
+TAG_SUBDIRS += include
+TAG_SUBDIRS += lib_generic board/$(BOARDDIR)
+TAG_SUBDIRS += cpu/$(CPU)
+TAG_SUBDIRS += lib_$(ARCH)
+TAG_SUBDIRS += fs/cramfs
+TAG_SUBDIRS += fs/fat
+TAG_SUBDIRS += fs/fdos
+TAG_SUBDIRS += fs/jffs2
+TAG_SUBDIRS += net
+TAG_SUBDIRS += disk
+TAG_SUBDIRS += common
+TAG_SUBDIRS += drivers/bios_emulator
+TAG_SUBDIRS += drivers/block
+TAG_SUBDIRS += drivers/hwmon
+TAG_SUBDIRS += drivers/i2c
+TAG_SUBDIRS += drivers/input
+TAG_SUBDIRS += drivers/misc
+TAG_SUBDIRS += drivers/mtd
+TAG_SUBDIRS += drivers/mtd/nand
+TAG_SUBDIRS += drivers/mtd/nand_legacy
+TAG_SUBDIRS += drivers/mtd/onenand
+TAG_SUBDIRS += drivers/net
+TAG_SUBDIRS += drivers/net/sk98lin
+TAG_SUBDIRS += drivers/pci
+TAG_SUBDIRS += drivers/pcmcia
+TAG_SUBDIRS += drivers/qe
+TAG_SUBDIRS += drivers/rtc
+TAG_SUBDIRS += drivers/serial
+TAG_SUBDIRS += drivers/usb
+TAG_SUBDIRS += drivers/video
+
 tags ctags:
-               ctags -w -o $(OBJTREE)/ctags `find $(SUBDIRS) include \
-                               lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH) \
-                               fs/cramfs fs/fat fs/fdos fs/jffs2 \
-                               net disk rtc dtt drivers drivers/sk98lin common \
-                       \( -name CVS -prune \) -o \( -name '*.[ch]' -print \)`
+               ctags -w -o $(OBJTREE)/ctags `find $(SUBDIRS) $(TAG_SUBDIRS) \
+                                               -name '*.[ch]' -print`
 
 etags:
-               etags -a -o $(OBJTREE)/etags `find $(SUBDIRS) include \
-                               lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH) \
-                               fs/cramfs fs/fat fs/fdos fs/jffs2 \
-                               net disk rtc dtt drivers drivers/sk98lin common \
-                       \( -name CVS -prune \) -o \( -name '*.[ch]' -print \)`
+               etags -a -o $(OBJTREE)/etags `find $(SUBDIRS) $(TAG_SUBDIRS) \
+                                               -name '*.[ch]' -print`
 
 $(obj)System.map:      $(obj)u-boot
                @$(NM) $< | \
                grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \
                sort > $(obj)System.map
 
+#
+# Auto-generate the autoconf.mk file (which is included by all makefiles)
+#
+# This target actually generates 2 files; autoconf.mk and autoconf.mk.dep.
+# the dep file is only include in this top level makefile to determine when
+# to regenerate the autoconf.mk file.
+$(OBJTREE)/include/autoconf.mk: $(obj)include/config.h
+       @echo Generating include/autoconf.mk
+       @# Generate the dependancies
+       @$(CC) -M $(HOST_CFLAGS) $(CPPFLAGS) -MQ $@ include/common.h > $@.dep
+       @# Extract the config macros
+       @$(CPP) $(CFLAGS) -dM include/common.h | sed -n -f tools/scripts/define2mk.sed >> $@
+
+sinclude $(OBJTREE)/include/autoconf.mk.dep
+
 #########################################################################
 else
 all $(obj)u-boot.hex $(obj)u-boot.srec $(obj)u-boot.bin \
@@ -361,7 +409,8 @@ CHANGELOG:
 
 unconfig:
        @rm -f $(obj)include/config.h $(obj)include/config.mk \
-               $(obj)board/*/config.tmp $(obj)board/*/*/config.tmp
+               $(obj)board/*/config.tmp $(obj)board/*/*/config.tmp \
+               $(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep
 
 #========================================================================
 # PowerPC
@@ -1750,9 +1799,13 @@ M54455EVB_i66_config :   unconfig
        >include/config.h ; \
        if [ "$${FLASH}" == "INTEL" ] ; then \
                echo "#undef CFG_ATMEL_BOOT" >> $(obj)include/config.h ; \
+               echo "TEXT_BASE = 0x00000000" > $(obj)board/freescale/m54455evb/config.tmp ; \
+               cp $(obj)board/freescale/m54455evb/u-boot.int $(obj)board/freescale/m54455evb/u-boot.lds ; \
                echo "... with INTEL boot..." ; \
        else \
                echo "#define CFG_ATMEL_BOOT"   >> $(obj)include/config.h ; \
+               echo "TEXT_BASE = 0x04000000" > $(obj)board/freescale/m54455evb/config.tmp ; \
+               cp $(obj)board/freescale/m54455evb/u-boot.atm $(obj)board/freescale/m54455evb/u-boot.lds ; \
                echo "... with ATMEL boot..." ; \
        fi; \
        echo "#define CFG_INPUT_CLKSRC $${FREQ}" >> $(obj)include/config.h ; \
diff --git a/README b/README
index 09eb76fe4528dfedca027b119ac760fce2570e35..3dad5fc726f76e72eaa797a31370cca8348e03b3 100644 (file)
--- a/README
+++ b/README
@@ -2123,7 +2123,7 @@ to save the current settings.
        to be a good choice since it makes it far enough from the
        start of the data area as well as from the stack pointer.
 
-Please note that the environment is read-only as long as the monitor
+Please note that the environment is read-only until the monitor
 has been relocated to RAM and a RAM copy of the environment has been
 created; also, when using EEPROM you will have to use getenv_r()
 until then to read environment variables.
index df324b7efa9a76d384dbaed26852d93b05dba7a1..f71a31370ec280ef6fee8be68a0a2fc1372d99fb 100644 (file)
@@ -21,4 +21,4 @@
 # MA 02111-1307 USA
 #
 
-PLATFORM_CPPFLAGS += -DCONFIG_BLACKFIN
+PLATFORM_CPPFLAGS += -DCONFIG_BLACKFIN -D__BLACKFIN__
index 34ceb0fdac45cd08c8529c312d08564e8fdec8fb..038d84955316ae362a6ce25e4a5e54ae82af73ee 100644 (file)
@@ -51,6 +51,7 @@ SECTIONS
   {
     cpu/mpc512x/start.o        (.text)
     *(.text)
+    *(.fixup)
     *(.got1)
     . = ALIGN(16);
     *(.rodata)
index 9d97905ca9b13b1a6bc2466ac4b075a55cf79e03..3eda1009efd140ec3b88a6d5acb2edb1d677a469 100644 (file)
@@ -37,17 +37,24 @@ static void cds_pci_fixup(void *blob)
 
        map = ft_get_prop(blob, "/" OF_SOC "/pci@8000/interrupt-map", &len);
 
-       len /= sizeof(u32);
+       if (!map)
+               map = ft_get_prop(blob, "/" OF_PCI "/interrupt-map", &len);
 
-       slot = get_pci_slot();
+       if (map) {
+               len /= sizeof(u32);
 
-       for (i=0;i<len;i+=7) {
-               /* We rotate the interrupt pins so that the mapping
-                * changes depending on the slot the carrier card is in.
-                */
-               map[3] = ((map[3] + slot - 2) % 4) + 1;
+               slot = get_pci_slot();
 
-               map+=7;
+               for (i=0;i<len;i+=7) {
+                       /* We rotate the interrupt pins so that the mapping
+                        * changes depending on the slot the carrier card is in.
+                        */
+                       map[3] = ((map[3] + slot - 2) % 4) + 1;
+
+                       map+=7;
+               }
+       } else {
+               printf("*** Warning - No PCI node found\n");
        }
 }
 #endif
index dc87a122a100621e88138fe34b5f1a709b96d524..7a5daefeb752f7b9318444d0125cde0650b41fad 100644 (file)
@@ -69,7 +69,7 @@ SECTIONS
     cpu/mpc85xx/interrupts.o (.text)
     cpu/mpc85xx/cpu_init.o (.text)
     cpu/mpc85xx/cpu.o (.text)
-    drivers/tsec.o (.text)
+    drivers/net/tsec.o (.text)
     cpu/mpc85xx/speed.o (.text)
     cpu/mpc85xx/pci.o (.text)
     common/dlmalloc.o (.text)
index 530ba5a721de26669b2de97e81697f03c5191c94..b19c481a96af3e1325b1f2a4d064859ad99d5cf6 100644 (file)
@@ -69,7 +69,7 @@ SECTIONS
     cpu/mpc85xx/interrupts.o (.text)
     cpu/mpc85xx/cpu_init.o (.text)
     cpu/mpc85xx/cpu.o (.text)
-    drivers/tsec.o (.text)
+    drivers/net/tsec.o (.text)
     cpu/mpc85xx/speed.o (.text)
     common/dlmalloc.o (.text)
     lib_generic/crc32.o (.text)
index 9285928dc428d89171745c1701628cb566dd0c7c..de0923a0d8b1e60c9104bf13292c9409a0fc036d 100644 (file)
@@ -69,7 +69,7 @@ SECTIONS
     cpu/mpc85xx/interrupts.o (.text)
     cpu/mpc85xx/cpu_init.o (.text)
     cpu/mpc85xx/cpu.o (.text)
-    drivers/tsec.o (.text)
+    drivers/net/tsec.o (.text)
     cpu/mpc85xx/speed.o (.text)
     cpu/mpc85xx/pci.o (.text)
     common/dlmalloc.o (.text)
index e2ab5b8e265faf1853ae1dfd84391679253b0c1b..4a86d3c5527b652ec2c339f32a7072010d67a745 100644 (file)
@@ -276,7 +276,7 @@ static void ft_blob_update(void *blob, bd_t *bd)
        memory_data[0] = cpu_to_be32(bd->bi_memstart);
        memory_data[1] = cpu_to_be32(bd->bi_memsize);
 
-       nodeoffset = fdt_find_node_by_path (blob, "/memory");
+       nodeoffset = fdt_path_offset (blob, "/memory");
        if (nodeoffset >= 0) {
                ret = fdt_setprop(blob, nodeoffset, "reg", memory_data,
                                        sizeof(memory_data));
index d87a39b249656b2cae495d8fece9184dff9a268b..5ce2694cbf7dd85155267f865adc8d13d7a5419e 100644 (file)
@@ -55,6 +55,7 @@ SECTIONS
   {
     *(.text)
     common/environment.o(.text)
+    *(.fixup)
     *(.got1)
   }
   _etext = .;
index d29e8d591e31146b0fb5ea6cf56b042d5d6cac0f..a13eeeb1232306ed84b219493d4367a50d071f4c 100644 (file)
@@ -25,6 +25,7 @@
 #include <command.h>
 #include <asm/au1x00.h>
 #include <asm/mipsregs.h>
+#include <asm/io.h>
 
 long int initdram(int board_type)
 {
@@ -77,6 +78,9 @@ int checkboard (void)
        default:
                printf ("Unsupported cpu %d, proc_id=0x%x\n", proc_id >> 24, proc_id);
        }
+
+       set_io_port_base(0);
+
 #ifdef CONFIG_IDE_PCMCIA
        /* Enable 3.3 V on slot 0 ( VCC )
           No 5V */
index 10c99179864c752ad1309610c23eaab28cc03620..861873272b6196a71a7ab4685cf2d0e83126ed61 100644 (file)
@@ -43,21 +43,22 @@ SECTIONS
        . = ALIGN(4);
        .data  : { *(.data) }
 
-       . = ALIGN(4);
-       .sdata  : { *(.sdata) }
-
-       _gp = ALIGN(16);
+       . = .;
+       _gp = ALIGN(16) + 0x7ff0;
 
-       __got_start = .;
-       .got  : { *(.got) }
-       __got_end = .;
+       .got : {
+         __got_start = .;
+         *(.got)
+         __got_end = .;
+       }
 
        .sdata  : { *(.sdata) }
 
-       . = .;
-       __u_boot_cmd_start = .;
-       .u_boot_cmd : { *(.u_boot_cmd) }
-       __u_boot_cmd_end = .;
+       .u_boot_cmd : {
+         __u_boot_cmd_start = .;
+         *(.u_boot_cmd)
+         __u_boot_cmd_end = .;
+       }
 
        uboot_end_data = .;
        num_got_entries = (__got_end - __got_start) >> 2;
index fd99a938c0f87830bb96004a0622e3e6868258e5..45dcf4dab03d425e9d867a6a1a7badef747d7237 100644 (file)
@@ -207,13 +207,16 @@ void read_from_px_regs_altbank(int set)
        out8(PIXIS_BASE + PIXIS_VCFGEN1, tmp);
 }
 
+#ifndef CFG_PIXIS_VBOOT_MASK
+#define CFG_PIXIS_VBOOT_MASK   0x40
+#endif
 
 void set_altbank(void)
 {
        u8 tmp;
 
        tmp = in8(PIXIS_BASE + PIXIS_VBOOT);
-       tmp ^= 0x40;
+       tmp ^= CFG_PIXIS_VBOOT_MASK;
 
        out8(PIXIS_BASE + PIXIS_VBOOT, tmp);
 }
index ce014edca8fdd71563af610c37708b5317ac24f2..b42fcc94ce7de4d7b8d5c2a02ed4692c504c4e5a 100644 (file)
@@ -22,4 +22,6 @@
 # MA 02111-1307 USA
 #
 
-TEXT_BASE = 0
+sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)
diff --git a/board/freescale/m54455evb/u-boot.atm b/board/freescale/m54455evb/u-boot.atm
new file mode 100644 (file)
index 0000000..bda68e4
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(m68k)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)          }
+  .dynsym        : { *(.dynsym)                }
+  .dynstr        : { *(.dynstr)                }
+  .rel.text      : { *(.rel.text)              }
+  .rela.text     : { *(.rela.text)     }
+  .rel.data      : { *(.rel.data)              }
+  .rela.data     : { *(.rela.data)     }
+  .rel.rodata    : { *(.rel.rodata)    }
+  .rela.rodata   : { *(.rela.rodata)   }
+  .rel.got       : { *(.rel.got)               }
+  .rela.got      : { *(.rela.got)              }
+  .rel.ctors     : { *(.rel.ctors)     }
+  .rela.ctors    : { *(.rela.ctors)    }
+  .rel.dtors     : { *(.rel.dtors)     }
+  .rela.dtors    : { *(.rela.dtors)    }
+  .rel.bss       : { *(.rel.bss)               }
+  .rela.bss      : { *(.rela.bss)              }
+  .rel.plt       : { *(.rel.plt)               }
+  .rela.plt      : { *(.rela.plt)              }
+  .init          : { *(.init)  }
+  .plt : { *(.plt) }
+  .text      :
+  {
+    /* WARNING - the following is hand-optimized to fit within */
+    /* the sector layout of our flash chips!   XXX FIXME XXX   */
+
+    cpu/mcf5445x/start.o               (.text)
+    lib_m68k/traps.o           (.text)
+    lib_m68k/interrupts.o      (.text)
+    common/dlmalloc.o          (.text)
+    lib_generic/zlib.o         (.text)
+
+    . = DEFINED(env_offset) ? env_offset : .;
+    common/environment.o       (.text)
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+
+  .reloc   :
+  {
+    __got_start = .;
+    *(.got)
+    __got_end = .;
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  . = .;
+  __u_boot_cmd_start = .;
+  .u_boot_cmd : { *(.u_boot_cmd) }
+  __u_boot_cmd_end = .;
+
+
+  . = .;
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   _sbss = .;
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+   . = ALIGN(4);
+   _ebss = .;
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/board/freescale/m54455evb/u-boot.int b/board/freescale/m54455evb/u-boot.int
new file mode 100644 (file)
index 0000000..e480c29
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(m68k)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)          }
+  .dynsym        : { *(.dynsym)                }
+  .dynstr        : { *(.dynstr)                }
+  .rel.text      : { *(.rel.text)              }
+  .rela.text     : { *(.rela.text)     }
+  .rel.data      : { *(.rel.data)              }
+  .rela.data     : { *(.rela.data)     }
+  .rel.rodata    : { *(.rel.rodata)    }
+  .rela.rodata   : { *(.rela.rodata)   }
+  .rel.got       : { *(.rel.got)               }
+  .rela.got      : { *(.rela.got)              }
+  .rel.ctors     : { *(.rel.ctors)     }
+  .rela.ctors    : { *(.rela.ctors)    }
+  .rel.dtors     : { *(.rel.dtors)     }
+  .rela.dtors    : { *(.rela.dtors)    }
+  .rel.bss       : { *(.rel.bss)               }
+  .rela.bss      : { *(.rela.bss)              }
+  .rel.plt       : { *(.rel.plt)               }
+  .rela.plt      : { *(.rela.plt)              }
+  .init          : { *(.init)  }
+  .plt : { *(.plt) }
+  .text      :
+  {
+    /* WARNING - the following is hand-optimized to fit within */
+    /* the sector layout of our flash chips!   XXX FIXME XXX   */
+
+    cpu/mcf5445x/start.o               (.text)
+    lib_m68k/traps.o           (.text)
+    lib_m68k/interrupts.o      (.text)
+    common/dlmalloc.o          (.text)
+    lib_generic/zlib.o         (.text)
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+
+  .reloc   :
+  {
+    __got_start = .;
+    *(.got)
+    __got_end = .;
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  . = .;
+  __u_boot_cmd_start = .;
+  .u_boot_cmd : { *(.u_boot_cmd) }
+  __u_boot_cmd_end = .;
+
+
+  . = .;
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   _sbss = .;
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+   . = ALIGN(4);
+   _ebss = .;
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
index 6bc35c70f2d4fff16c663021e53d1303a7310d81..7818a2e1ee9c709d7c486f76a93949766dc81755 100644 (file)
@@ -269,7 +269,7 @@ ft_pci_setup(void *blob, bd_t *bd)
        int err;
        int tmp[2];
 
-       nodeoffset = fdt_find_node_by_path(blob, "/" OF_SOC "/pci@8500");
+       nodeoffset = fdt_path_offset(blob, "/" OF_SOC "/pci@8500");
        if (nodeoffset >= 0) {
                tmp[0] = cpu_to_be32(hose[0].first_busno);
                tmp[1] = cpu_to_be32(hose[0].last_busno);
index ae94a2f384f77fecf1c86cda180ff889ddfb3bac..7bcdccbcc6780094cd3b219bbe00ca670a7d76c8 100644 (file)
@@ -396,7 +396,7 @@ ft_pci_setup(void *blob, bd_t *bd)
        int err;
        int tmp[2];
 
-       nodeoffset = fdt_find_node_by_path(blob, "/" OF_SOC "/pci@8500");
+       nodeoffset = fdt_path_offset(blob, "/" OF_SOC "/pci@8500");
        if (nodeoffset >= 0) {
                tmp[0] = cpu_to_be32(pci_hose[0].first_busno);
                tmp[1] = cpu_to_be32(pci_hose[0].last_busno);
@@ -408,7 +408,7 @@ ft_pci_setup(void *blob, bd_t *bd)
                                  tmp, sizeof(tmp[0]));
        }
 #ifdef CONFIG_MPC83XX_PCI2
-       nodeoffset = fdt_find_node_by_path(blob, "/" OF_SOC "/pci@8600");
+       nodeoffset = fdt_path_offset(blob, "/" OF_SOC "/pci@8600");
        if (nodeoffset >= 0) {
                tmp[0] = cpu_to_be32(pci_hose[1].first_busno);
                tmp[1] = cpu_to_be32(pci_hose[1].last_busno);
index 5ca094d4cbcc52d3b6217631f061b8ab11138de9..a764a61867a58f4ca6f8e9a13552dbc8db1884f1 100644 (file)
@@ -342,7 +342,7 @@ ft_pci_setup(void *blob, bd_t *bd)
        int err;
        int tmp[2];
 
-       nodeoffset = fdt_find_node_by_path(blob, "/" OF_SOC "/pci@8500");
+       nodeoffset = fdt_path_offset(blob, "/" OF_SOC "/pci@8500");
        if (nodeoffset >= 0) {
                tmp[0] = cpu_to_be32(pci_hose[0].first_busno);
                tmp[1] = cpu_to_be32(pci_hose[0].last_busno);
@@ -354,7 +354,7 @@ ft_pci_setup(void *blob, bd_t *bd)
                                  tmp, sizeof(tmp[0]));
        }
 #ifdef CONFIG_MPC83XX_PCI2
-       nodeoffset = fdt_find_node_by_path(blob, "/" OF_SOC "/pci@8500");
+       nodeoffset = fdt_path_offset(blob, "/" OF_SOC "/pci@8500");
        if (nodeoffset >= 0) {
                tmp[0] = cpu_to_be32(pci_hose[1].first_busno);
                tmp[1] = cpu_to_be32(pci_hose[1].last_busno);
index cf7ef90443f7e97c7de11a43a456bfeae78db913..f18e532ef5fcdd38968592083245bc72b9422085 100644 (file)
@@ -269,7 +269,7 @@ ft_pci_setup(void *blob, bd_t *bd)
        int err;
        int tmp[2];
 
-       nodeoffset = fdt_find_node_by_path(blob, "/" OF_SOC "/pci@8500");
+       nodeoffset = fdt_path_offset(blob, "/" OF_SOC "/pci@8500");
        if (nodeoffset >= 0) {
                tmp[0] = cpu_to_be32(hose[0].first_busno);
                tmp[1] = cpu_to_be32(hose[0].last_busno);
index 76d909191f9605a088beabbdae79a49862b79507..b6c9e93d5042d393c31e3a8893f196eaecfc8049 100644 (file)
@@ -227,7 +227,7 @@ pci_init_board(void)
                 * Activate ULI1575 legacy chip by performing a fake
                 * memory access.  Needed to make ULI RTC work.
                 */
-               in_be32(CFG_PCIE3_MEM_BASE);
+               in_be32((u32 *)CFG_PCIE3_MEM_BASE);
        } else {
                printf ("    PCIE3: disabled\n");
        }
index ffeaf587b56bf5093b13e212466fe425cca4aa6e..6da80dc758dc851e6cd13497a11b0ef266ae6688 100644 (file)
 #include <asm/au1x00.h>
 #include <asm/addrspace.h>
 #include <asm/mipsregs.h>
+#include <asm/io.h>
 #include <watchdog.h>
 
 #include "ee_access.h"
 
 static int wdi_status = 0;
 
-unsigned long mips_io_port_base = 0;
-
 #define SDRAM_SIZE ((64*1024*1024)-(12*4096))
 
 
@@ -147,6 +146,9 @@ int checkboard (void)
        default:
                printf ("Unsupported cpu %d, proc_id=0x%x\n", proc_id >> 24, proc_id);
        }
+
+       set_io_port_base(0);
+
 #ifdef CONFIG_IDE_PCMCIA
        /* PCMCIA is on a 36 bit physical address.
           We need to map it into a 32 bit addresses */
@@ -429,7 +431,7 @@ int misc_init_r(void){
            (Rx[8] != ':') | (Rx[11] != ':') | (Rx[14] != ':')) {
                printf ("*** ethernet addr invalid, using default ***\n");
        } else {
-               setenv ("ethaddr", Rx);
+               setenv ("ethaddr", (char *)Rx);
        }
        return (0);
 }
index 983ff704aca9184687a6a967db422705b81d74a3..eea378a3b653e344b4b0398e8777ac3c222c9050 100644 (file)
@@ -413,7 +413,9 @@ noCacheJump:
        j clearmem
        nop
 
+#if 0
        .globl  memtest
+#endif
 memtest:
        /* Fill memory with address */
        li      t0, 0x80000000
@@ -434,7 +436,9 @@ mt1:        lw      t2, 0(t0)
        bne     t1, zero, mt1
        nop
        nop
+#if 0
        .globl  clearmem
+#endif
 clearmem:
                /* Clear memory */
        li      t0, 0x80000000
index 8ba0b6d4c12906fe8865f50f6119fc7f6ffab054..ce53d9ddbb78755ca51719deb4491aa732fe45bc 100644 (file)
@@ -43,20 +43,22 @@ SECTIONS
        . = ALIGN(4);
        .data  : { *(.data) }
 
-       . = ALIGN(4);
-       .sdata  : { *(.sdata) }
-
-       _gp = ALIGN(16);
+       . = .;
+       _gp = ALIGN(16) + 0x7ff0;
 
-       __got_start = .;
-       .got  : { *(.got) }
-       __got_end = .;
+       .got : {
+         __got_start = .;
+         *(.got)
+         __got_end = .;
+       }
 
        .sdata  : { *(.sdata) }
 
-       __u_boot_cmd_start = .;
-       .u_boot_cmd : { *(.u_boot_cmd) }
-       __u_boot_cmd_end = .;
+       .u_boot_cmd : {
+         __u_boot_cmd_start = .;
+         *(.u_boot_cmd)
+         __u_boot_cmd_end = .;
+       }
 
        uboot_end_data = .;
        num_got_entries = (__got_end - __got_start) >> 2;
index 9bf0f0938a2fbf4e14329ce54bdf309ad87037c2..337a3954d2de2a0f10692f76f4e0524bf8028c68 100644 (file)
@@ -69,6 +69,7 @@ SECTIONS
     common/environment.o(.text)
 
     *(.text)
+    *(.fixup)
     *(.got1)
   }
   _etext = .;
index 19823a474ed09f1c831cefbd260fab9c6d1e70af..b05424d32b29a2cf3120445dc2d0da2f6bd398ad 100644 (file)
 #include <ioports.h>
 #include <mpc8260.h>
 
+#if defined(CONFIG_OF_LIBFDT)
+#include <libfdt.h>
+#include <libfdt_env.h>
+#include <fdt_support.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -38,12 +44,12 @@ const iop_conf_t iop_conf_tab[4][32] = {
 
     /* Port A configuration */
     {  /*            conf ppar psor pdir podr pdat */
-       /* PA31 */ {   0,   1,   1,   0,   0,   0   }, /* FCC1 COL */
-       /* PA30 */ {   0,   1,   1,   0,   0,   0   }, /* FCC1 CRS */
-       /* PA29 */ {   0,   1,   1,   1,   0,   0   }, /* FCC1 TXER */
-       /* PA28 */ {   0,   1,   1,   1,   0,   0   }, /* FCC1 TXEN */
-       /* PA27 */ {   0,   1,   1,   0,   0,   0   }, /* FCC1 RXDV */
-       /* PA26 */ {   0,   1,   1,   0,   0,   0   }, /* FCC1 RXER */
+       /* PA31 */ {   1,   1,   1,   0,   0,   0   }, /* FCC1 COL */
+       /* PA30 */ {   1,   1,   1,   0,   0,   0   }, /* FCC1 CRS */
+       /* PA29 */ {   1,   1,   1,   1,   0,   0   }, /* FCC1 TXER */
+       /* PA28 */ {   1,   1,   1,   1,   0,   0   }, /* FCC1 TXEN */
+       /* PA27 */ {   1,   1,   1,   0,   0,   0   }, /* FCC1 RXDV */
+       /* PA26 */ {   1,   1,   1,   0,   0,   0   }, /* FCC1 RXER */
        /* PA25 */ {   0,   0,   0,   0,   1,   0   }, /* 8247_P0 */
 #if defined(CONFIG_SOFT_I2C)
        /* PA24 */ {   1,   0,   0,   0,   1,   1   }, /* I2C_SDA2 */
@@ -53,14 +59,14 @@ const iop_conf_t iop_conf_tab[4][32] = {
        /* PA23 */ {   0,   0,   0,   1,   0,   0   }, /* PA23 */
 #endif
        /* PA22 */ {   0,   0,   0,   0,   1,   0   }, /* SMC2_DCD */
-       /* PA21 */ {   0,   1,   0,   1,   0,   0   }, /* FCC1 TXD3 */
-       /* PA20 */ {   0,   1,   0,   1,   0,   0   }, /* FCC1 TXD2 */
-       /* PA19 */ {   0,   1,   0,   1,   0,   0   }, /* FCC1 TXD1 */
-       /* PA18 */ {   0,   1,   0,   1,   0,   0   }, /* FCC1 TXD0 */
-       /* PA17 */ {   0,   1,   0,   0,   0,   0   }, /* FCC1 RXD0 */
-       /* PA16 */ {   0,   1,   0,   0,   0,   0   }, /* FCC1 RXD1 */
-       /* PA15 */ {   0,   1,   0,   0,   0,   0   }, /* FCC1 RXD2 */
-       /* PA14 */ {   0,   1,   0,   0,   0,   0   }, /* FCC1 RXD3 */
+       /* PA21 */ {   1,   1,   0,   1,   0,   0   }, /* FCC1 TXD3 */
+       /* PA20 */ {   1,   1,   0,   1,   0,   0   }, /* FCC1 TXD2 */
+       /* PA19 */ {   1,   1,   0,   1,   0,   0   }, /* FCC1 TXD1 */
+       /* PA18 */ {   1,   1,   0,   1,   0,   0   }, /* FCC1 TXD0 */
+       /* PA17 */ {   1,   1,   0,   0,   0,   0   }, /* FCC1 RXD0 */
+       /* PA16 */ {   1,   1,   0,   0,   0,   0   }, /* FCC1 RXD1 */
+       /* PA15 */ {   1,   1,   0,   0,   0,   0   }, /* FCC1 RXD2 */
+       /* PA14 */ {   1,   1,   0,   0,   0,   0   }, /* FCC1 RXD3 */
        /* PA13 */ {   0,   0,   0,   1,   1,   0   }, /* SMC2_RTS */
        /* PA12 */ {   0,   0,   0,   0,   1,   0   }, /* SMC2_CTS */
        /* PA11 */ {   0,   0,   0,   1,   1,   0   }, /* SMC2_DTR */
@@ -79,20 +85,20 @@ const iop_conf_t iop_conf_tab[4][32] = {
 
     /* Port B configuration */
     {  /*            conf ppar psor pdir podr pdat */
-       /* PB31 */ {   1,   1,   0,   1,   0,   0   }, /* FCC2 MII TX_ER */
-       /* PB30 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RX_DV */
-       /* PB29 */ {   1,   1,   1,   1,   0,   0   }, /* FCC2 MII TX_EN */
-       /* PB28 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RX_ER */
-       /* PB27 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII COL */
-       /* PB26 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII CRS */
-       /* PB25 */ {   1,   1,   0,   1,   0,   0   }, /* FCC2 MII TxD[3] */
-       /* PB24 */ {   1,   1,   0,   1,   0,   0   }, /* FCC2 MII TxD[2] */
-       /* PB23 */ {   1,   1,   0,   1,   0,   0   }, /* FCC2 MII TxD[1] */
-       /* PB22 */ {   1,   1,   0,   1,   0,   0   }, /* FCC2 MII TxD[0] */
-       /* PB21 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RxD[0] */
-       /* PB20 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RxD[1] */
-       /* PB19 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RxD[2] */
-       /* PB18 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RxD[3] */
+       /* PB31 */ {   0,   1,   0,   1,   0,   0   }, /* FCC2 MII TX_ER */
+       /* PB30 */ {   0,   1,   0,   0,   0,   0   }, /* FCC2 MII RX_DV */
+       /* PB29 */ {   0,   1,   1,   1,   0,   0   }, /* FCC2 MII TX_EN */
+       /* PB28 */ {   0,   1,   0,   0,   0,   0   }, /* FCC2 MII RX_ER */
+       /* PB27 */ {   0,   1,   0,   0,   0,   0   }, /* FCC2 MII COL */
+       /* PB26 */ {   0,   1,   0,   0,   0,   0   }, /* FCC2 MII CRS */
+       /* PB25 */ {   0,   1,   0,   1,   0,   0   }, /* FCC2 MII TxD[3] */
+       /* PB24 */ {   0,   1,   0,   1,   0,   0   }, /* FCC2 MII TxD[2] */
+       /* PB23 */ {   0,   1,   0,   1,   0,   0   }, /* FCC2 MII TxD[1] */
+       /* PB22 */ {   0,   1,   0,   1,   0,   0   }, /* FCC2 MII TxD[0] */
+       /* PB21 */ {   0,   1,   0,   0,   0,   0   }, /* FCC2 MII RxD[0] */
+       /* PB20 */ {   0,   1,   0,   0,   0,   0   }, /* FCC2 MII RxD[1] */
+       /* PB19 */ {   0,   1,   0,   0,   0,   0   }, /* FCC2 MII RxD[2] */
+       /* PB18 */ {   0,   1,   0,   0,   0,   0   }, /* FCC2 MII RxD[3] */
        /* PB17 */ {   0,   0,   0,   0,   0,   0   }, /* PB17 */
        /* PB16 */ {   0,   0,   0,   0,   0,   0   }, /* PB16 */
        /* PB15 */ {   0,   0,   0,   0,   0,   0   }, /* PB15 */
@@ -123,8 +129,8 @@ const iop_conf_t iop_conf_tab[4][32] = {
        /* PC26 */ {   0,   0,   0,   1,   0,   0   }, /* PC26 */
        /* PC25 */ {   0,   1,   1,   0,   0,   0   }, /* SYNC_IN */
        /* PC24 */ {   0,   0,   0,   1,   0,   0   }, /* PC24 */
-       /* PC23 */ {   0,   1,   0,   1,   0,   0   }, /* ATMTFCLK */
-       /* PC22 */ {   0,   1,   0,   0,   0,   0   }, /* ATMRFCLK */
+       /* PC23 */ {   1,   1,   0,   0,   0,   0   }, /* FCC1 MII TX_CLK */
+       /* PC22 */ {   1,   1,   0,   0,   0,   0   }, /* FCC1 MII RX_CLK */
        /* PC21 */ {   0,   1,   0,   0,   0,   0   }, /* SCC1 EN RXCLK */
        /* PC20 */ {   0,   1,   0,   0,   0,   0   }, /* SCC1 EN TXCLK */
        /* PC19 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RX_CLK */
@@ -180,7 +186,7 @@ const iop_conf_t iop_conf_tab[4][32] = {
        /* PD10 */ {   0,   0,   0,   0,   0,   0   }, /* PD10 */
        /* PD9  */ {   0,   0,   0,   0,   0,   0   }, /* PD9 */
        /* PD8  */ {   0,   0,   0,   0,   0,   0   }, /* PD8 */
-       /* PD7  */ {   0,   0,   0,   1,   0,   1   }, /* MII_MDIO */
+       /* PD7  */ {   1,   0,   0,   1,   0,   1   }, /* MII_MDIO */
        /* PD6  */ {   0,   0,   0,   1,   0,   1   }, /* PD6 */
        /* PD5  */ {   0,   0,   0,   1,   0,   1   }, /* PD5 */
        /* PD4  */ {   0,   0,   0,   1,   0,   1   }, /* PD4 */
@@ -224,7 +230,7 @@ static long int try_init (volatile memctl8260_t * memctl, ulong sdmr,
         * mapped by the controller. That means, that the initial mapping has
         * to be (at least) twice as large as the maximum expected size.
         */
-       maxsize = (1 + (~orx | 0x7fff)) / 2;
+       maxsize = (1 + (~orx | 0x7fff))/* / 2*/;
 
        sdmr_ptr = &memctl->memc_psdmr;
        orx_ptr = &memctl->memc_or2;
@@ -315,4 +321,38 @@ nand_init (void)
        printf ("%4lu MB\n", totlen >>20);
 }
 
-#endif
+#endif /* CFG_CMD_NAND */
+
+#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
+/*
+ * update "memory" property in the blob
+ */
+void ft_blob_update(void *blob, bd_t *bd)
+{
+       int ret, nodeoffset = 0;
+       ulong memory_data[2] = {0};
+
+       memory_data[0] = cpu_to_be32(bd->bi_memstart);
+       memory_data[1] = cpu_to_be32(bd->bi_memsize);
+
+       nodeoffset = fdt_find_node_by_path (blob, "/memory");
+       if (nodeoffset >= 0) {
+               ret = fdt_setprop(blob, nodeoffset, "reg", memory_data,
+                                       sizeof(memory_data));
+       if (ret < 0)
+               printf("ft_blob_update): cannot set /memory/reg "
+                       "property err:%s\n", fdt_strerror(ret));
+       }
+       else {
+               /* memory node is required in dts */
+               printf("ft_blob_update(): cannot find /memory node "
+               "err:%s\n", fdt_strerror(nodeoffset));
+       }
+}
+
+void ft_board_setup(void *blob, bd_t *bd)
+{
+       ft_cpu_setup( blob, bd);
+       ft_blob_update(blob, bd);
+}
+#endif /* defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) */
index b5d9e0049270711adbd134a59f3841f2f9e326c7..dbf0ecc5af3d1d56bfbd9b16c18a2ea27c16ce94 100644 (file)
@@ -25,7 +25,7 @@
 #include <command.h>
 #include <asm/addrspace.h>
 #include <asm/inca-ip.h>
-
+#include <asm/io.h>
 
 extern uint incaip_get_cpuclk(void);
 
@@ -85,7 +85,6 @@ long int initdram(int board_type)
 
 int checkboard (void)
 {
-
        unsigned long chipid = *INCA_IP_WDT_CHIPID;
        int part_num;
 
@@ -107,5 +106,7 @@ int checkboard (void)
 
        printf("CPU Speed %d MHz\n", incaip_get_cpuclk()/1000000);
 
+       set_io_port_base(0);
+
        return 0;
 }
index 10c99179864c752ad1309610c23eaab28cc03620..861873272b6196a71a7ab4685cf2d0e83126ed61 100644 (file)
@@ -43,21 +43,22 @@ SECTIONS
        . = ALIGN(4);
        .data  : { *(.data) }
 
-       . = ALIGN(4);
-       .sdata  : { *(.sdata) }
-
-       _gp = ALIGN(16);
+       . = .;
+       _gp = ALIGN(16) + 0x7ff0;
 
-       __got_start = .;
-       .got  : { *(.got) }
-       __got_end = .;
+       .got : {
+         __got_start = .;
+         *(.got)
+         __got_end = .;
+       }
 
        .sdata  : { *(.sdata) }
 
-       . = .;
-       __u_boot_cmd_start = .;
-       .u_boot_cmd : { *(.u_boot_cmd) }
-       __u_boot_cmd_end = .;
+       .u_boot_cmd : {
+         __u_boot_cmd_start = .;
+         *(.u_boot_cmd)
+         __u_boot_cmd_end = .;
+       }
 
        uboot_end_data = .;
        num_got_entries = (__got_end - __got_start) >> 2;
index 77f998971a051f437c5a9712a94f0b369ff0e4f8..9b24a7e55e52f9fb3e19866cabb1169bc62a4357 100644 (file)
@@ -96,6 +96,23 @@ int board_early_init_f(void)
 
        gpio_write_bit(CFG_GPIO_FLASH_WP, 1);
 
+       /*
+        * Reset PHY's:
+        * The PHY's need a 2nd reset pulse, since the MDIO address is latched
+        * upon reset, and with the first reset upon powerup, the addresses are
+        * not latched reliable, since the IRQ line is multiplexed with an
+        * MDIO address. A 2nd reset at this time will make sure, that the
+        * correct address is latched.
+        */
+       gpio_write_bit(CFG_GPIO_PHY0_RST, 1);
+       gpio_write_bit(CFG_GPIO_PHY1_RST, 1);
+       udelay(1000);
+       gpio_write_bit(CFG_GPIO_PHY0_RST, 0);
+       gpio_write_bit(CFG_GPIO_PHY1_RST, 0);
+       udelay(1000);
+       gpio_write_bit(CFG_GPIO_PHY0_RST, 1);
+       gpio_write_bit(CFG_GPIO_PHY1_RST, 1);
+
        return 0;
 }
 
@@ -230,15 +247,6 @@ int misc_init_r(void)
        /* Write lime controller memory parameters */
        out_be32((void *)CFG_LIME_MMR, CFG_LIME_MMR_VALUE);
 
-       /*
-        * Reset PHY's
-        */
-       gpio_write_bit(CFG_GPIO_PHY0_RST, 0);
-       gpio_write_bit(CFG_GPIO_PHY1_RST, 0);
-       udelay(100);
-       gpio_write_bit(CFG_GPIO_PHY0_RST, 1);
-       gpio_write_bit(CFG_GPIO_PHY1_RST, 1);
-
        /*
         * Init display controller
         */
index 243d6a4d83e9219a44646c65158fc0b83c833276..7d6d1d6231a1b1daa6be1ed33bf93c5587d4168a 100644 (file)
@@ -89,4 +89,5 @@ long int initdram (int board_type)
                /* Write to the SDRAM Mode Register */
                *(u32 *)(CFG_SDRAM_BASE + 0x400) = 0xA5A59696;
        }
+       return dramsize;
 }
index eb4d8e4e2b61f97586643e2a7c15f4585cf32dc6..57358b8a49dcb69640e30cf2a47be7ccc7e40078 100644 (file)
@@ -60,6 +60,7 @@ SECTIONS
     lib_generic/crc32.o                (.text)
     lib_generic/zlib.o         (.text)
 
+    *(.fixup)
     *(.got1)
     . = ALIGN(16);
     *(.rodata)
index 227c49272cef347b406202c658b1a3f53734a66a..90a1b08e24996955ecf0e5ec23e27fbfb37de022 100644 (file)
@@ -31,7 +31,7 @@
 #include "../common/common_util.h"
 
 #if defined(CONFIG_DRIVER_CS8900)
-#include <../drivers/cs8900.h>
+#include <../drivers/net/cs8900.h>
 
 static uchar cs8900_chksum(ushort data)
 {
index ccfe1768f63617d3a814c90339a720b8f782dcab..d15a19115e511e47860d3f5656a097af453cf36d 100644 (file)
@@ -290,7 +290,7 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
  * Copy memory to flash
  */
 
-volatile static int write_hword (flash_info_t * info, ulong dest, ushort data)
+static int write_hword (flash_info_t * info, ulong dest, ushort data)
 {
        vu_short *addr = (vu_short *) dest;
        ushort result;
index 7a32343748dd467b956d3df19e096eeefb37cf11..220b7053babe39b207e3ba5c3789f0f8fdf41e90 100644 (file)
@@ -128,7 +128,7 @@ typedef struct {
 } /*__attribute__((__packed__))*/ VCMA9_PLD;
 
 #define VCMA9_PLD_BASE 0x2C000100
-static inline VCMA9_PLD * const VCMA9_GetBase_PLD(void)
+static inline VCMA9_PLD * VCMA9_GetBase_PLD(void)
 {
        return (VCMA9_PLD * const)VCMA9_PLD_BASE;
 }
index fef3822aae2c2a9206e7b4a72b3799651f185a7c..0de594b65f27161b33039e22aa311bd6446d5dc4 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <common.h>
 #include <exports.h>
-#include "../drivers/smc91111.h"
+#include "../drivers/net/smc91111.h"
 
 #define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE
 
index f7d58416c9a38e85a5f4168fe8ccabbccd54a1c9..afe02c27c6ff9baecff2c09aed27241fb42cbb97 100644 (file)
@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
 LIB    = $(obj)lib$(BOARD).a
 
 COBJS  = $(BOARD).o flash.o
-SOBJS  = memsetup.o
+SOBJS  = lowlevel_init.o
 
 SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS))
diff --git a/board/pb1x00/lowlevel_init.S b/board/pb1x00/lowlevel_init.S
new file mode 100644 (file)
index 0000000..e851e2f
--- /dev/null
@@ -0,0 +1,392 @@
+/* Memory sub-system initialization code */
+
+#include <config.h>
+#include <version.h>
+#include <asm/regdef.h>
+#include <asm/au1x00.h>
+#include <asm/mipsregs.h>
+
+#define AU1500_SYS_ADDR                0xB1900000
+#define sys_endian             0x0038
+#define CP0_Config0            $16
+#define MEM_1MS                        ((396000000/1000000) * 1000)
+
+       .text
+       .set noreorder
+       .set mips32
+
+       .globl  lowlevel_init
+lowlevel_init:
+       /*
+        * Step 1) Establish CPU endian mode.
+        * NOTE: A fair amount of code is necessary on the Pb1000 to
+        * obtain the value of Switch S8.1 which is used to determine
+        * endian at run-time.
+        */
+
+       /* RCE1 */
+       li              t0, MEM_STCFG1
+       li              t1, 0x00000083
+       sw              t1, 0(t0)
+
+       li              t0, MEM_STTIME1
+       li              t1, 0x33030A10
+       sw              t1, 0(t0)
+
+       li              t0, MEM_STADDR1
+       li              t1, 0x11803E40
+       sw              t1, 0(t0)
+
+       /* Set DSTRB bits so switch will read correctly */
+       li              t1, 0xBE00000C
+       lw              t2, 0(t1)
+       or              t2, t2, 0x00000300
+       sw              t2, 0(t1)
+
+       /* Check switch setting */
+       li              t1, 0xBE000014
+       lw              t2, 0(t1)
+       and             t2, t2, 0x00000100
+       bne             t2, zero, big_endian
+       nop
+
+little_endian:
+
+       /* Change Au1 core to little endian */
+       li      t0, AU1500_SYS_ADDR
+       li      t1, 1
+       sw      t1, sys_endian(t0)
+       mfc0    t2, CP0_CONFIG
+       mtc0    t2, CP0_CONFIG
+       nop
+       nop
+
+       /* Big Endian is default so nothing to do but fall through */
+
+big_endian:
+
+       /*
+        * Step 2) Establish Status Register
+        * (set BEV, clear ERL, clear EXL, clear IE)
+        */
+       li      t1, 0x00400000
+       mtc0    t1, CP0_STATUS
+
+       /*
+        * Step 3) Establish CP0 Config0
+        * (set OD, set K0=3)
+        */
+       li      t1, 0x00080003
+       mtc0    t1, CP0_CONFIG
+
+       /*
+        * Step 4) Disable Watchpoint facilities
+        */
+       li t1, 0x00000000
+       mtc0    t1, CP0_WATCHLO
+       mtc0    t1, CP0_IWATCHLO
+       /*
+        * Step 5) Disable the performance counters
+        */
+       mtc0    zero, CP0_PERFORMANCE
+       nop
+
+       /*
+        * Step 6) Establish EJTAG Debug register
+        */
+       mtc0    zero, CP0_DEBUG
+       nop
+
+       /*
+        * Step 7) Establish Cause
+        * (set IV bit)
+        */
+       li      t1, 0x00800000
+       mtc0    t1, CP0_CAUSE
+
+       /* Establish Wired (and Random) */
+       mtc0    zero, CP0_WIRED
+       nop
+
+       /* First setup pll:s to make serial work ok */
+       /* We have a 12 MHz crystal */
+       li      t0, SYS_CPUPLL
+       li      t1, 0x21  /* 396 MHz */
+       sw      t1, 0(t0)
+       sync
+       nop
+       nop
+
+       /* wait 1mS for clocks to settle */
+       li      t1, MEM_1MS
+1:     add     t1, -1
+       bne     t1, zero, 1b
+       nop
+       /* Setup AUX PLL */
+       li      t0, SYS_AUXPLL
+       li      t1, 8 /* 96 MHz */
+       sw      t1, 0(t0) /* aux pll */
+       sync
+
+       /*  Static memory controller */
+
+       /* RCE0 8MB AMD29D323 Flash */
+       li      t0, MEM_STCFG0
+       li      t1, 0x00001403
+       sw      t1, 0(t0)
+
+       li      t0, MEM_STTIME0
+       li      t1, 0xFFFFFFDD
+       sw      t1, 0(t0)
+
+       li      t0, MEM_STADDR0
+       li      t1, 0x11F83FE0
+       sw      t1, 0(t0)
+
+       /* RCE1 CPLD Board Logic */
+       li      t0, MEM_STCFG1
+       li      t1, 0x00000083
+       sw      t1, 0(t0)
+
+       li      t0, MEM_STTIME1
+       li      t1, 0x33030A10
+       sw      t1, 0(t0)
+
+       li      t0, MEM_STADDR1
+       li      t1, 0x11803E40
+       sw      t1, 0(t0)
+
+       /* RCE2 CPLD Board Logic */
+       li      t0, MEM_STCFG2
+       li      t1, 0x00000004
+       sw      t1, 0(t0)
+
+       li      t0, MEM_STTIME2
+       li      t1, 0x08061908
+       sw      t1, 0(t0)
+
+       li      t0, MEM_STADDR2
+       li      t1, 0x12A03FC0
+       sw      t1, 0(t0)
+
+       /* RCE3 PCMCIA 250ns */
+       li      t0, MEM_STCFG3
+       li      t1, 0x00000002
+       sw      t1, 0(t0)
+
+       li      t0, MEM_STTIME3
+       li      t1, 0x280E3E07
+       sw      t1, 0(t0)
+
+       li      t0, MEM_STADDR3
+       li      t1, 0x10000000
+       sw      t1, 0(t0)
+
+       sync
+
+       /* Set peripherals to a known state */
+       li      t0, IC0_CFG0CLR
+       li      t1, 0xFFFFFFFF
+       sw      t1, 0(t0)
+
+       li      t0, IC0_CFG0CLR
+       sw      t1, 0(t0)
+
+       li      t0, IC0_CFG1CLR
+       sw      t1, 0(t0)
+
+       li      t0, IC0_CFG2CLR
+       sw      t1, 0(t0)
+
+       li      t0, IC0_SRCSET
+       sw      t1, 0(t0)
+
+       li      t0, IC0_ASSIGNSET
+       sw      t1, 0(t0)
+
+       li      t0, IC0_WAKECLR
+       sw      t1, 0(t0)
+
+       li      t0, IC0_RISINGCLR
+       sw      t1, 0(t0)
+
+       li      t0, IC0_FALLINGCLR
+       sw      t1, 0(t0)
+
+       li      t0, IC0_TESTBIT
+       li      t1, 0x00000000
+       sw      t1, 0(t0)
+       sync
+
+       li      t0, IC1_CFG0CLR
+       li      t1, 0xFFFFFFFF
+       sw      t1, 0(t0)
+
+       li      t0, IC1_CFG0CLR
+       sw      t1, 0(t0)
+
+       li      t0, IC1_CFG1CLR
+       sw      t1, 0(t0)
+
+       li      t0, IC1_CFG2CLR
+       sw      t1, 0(t0)
+
+       li      t0, IC1_SRCSET
+       sw      t1, 0(t0)
+
+       li      t0, IC1_ASSIGNSET
+       sw      t1, 0(t0)
+
+       li      t0, IC1_WAKECLR
+       sw      t1, 0(t0)
+
+       li      t0, IC1_RISINGCLR
+       sw      t1, 0(t0)
+
+       li      t0, IC1_FALLINGCLR
+       sw      t1, 0(t0)
+
+       li      t0, IC1_TESTBIT
+       li      t1, 0x00000000
+       sw      t1, 0(t0)
+       sync
+
+       li      t0, SYS_FREQCTRL0
+       li      t1, 0x00000000
+       sw      t1, 0(t0)
+
+       li      t0, SYS_FREQCTRL1
+       li      t1, 0x00000000
+       sw      t1, 0(t0)
+
+       li      t0, SYS_CLKSRC
+       li      t1, 0x00000000
+       sw      t1, 0(t0)
+
+       li      t0, SYS_PININPUTEN
+       li      t1, 0x00000000
+       sw      t1, 0(t0)
+       sync
+
+       li      t0, 0xB1100100
+       li      t1, 0x00000000
+       sw      t1, 0(t0)
+
+       li      t0, 0xB1400100
+       li      t1, 0x00000000
+       sw      t1, 0(t0)
+
+
+       li      t0, SYS_WAKEMSK
+       li      t1, 0x00000000
+       sw      t1, 0(t0)
+
+       li      t0, SYS_WAKESRC
+       li      t1, 0x00000000
+       sw      t1, 0(t0)
+
+       /* wait 1mS before setup */
+       li      t1, MEM_1MS
+1:     add     t1, -1
+       bne     t1, zero, 1b
+       nop
+
+       /*
+        * Skip memory setup if we are running from memory
+        */
+       li              t0, 0x90000000
+       sub             t0, ra, t0
+       bltz            t0, skip_memsetup
+       nop
+
+       /*
+        * SDCS0 - Not used, for SMROM
+        * SDCS1 - 32MB Micron 48LCBM16A2
+        * SDCS2 - 32MB Micron 48LCBM16A2
+        */
+       li      t0, MEM_SDMODE0
+       li      t1, 0x00000000
+       sw      t1, 0(t0)
+
+       li      t0, MEM_SDMODE1
+       li      t1, 0x00552229
+       sw      t1, 0(t0)
+
+       li      t0, MEM_SDMODE2
+       li      t1, 0x00552229
+       sw      t1, 0(t0)
+
+       li      t0, MEM_SDADDR0
+       li      t1, 0x00000000
+       sw      t1, 0(t0)
+
+       li      t0, MEM_SDADDR1
+       li      t1, 0x001003F8
+       sw      t1, 0(t0)
+
+       li      t0, MEM_SDADDR2
+       li      t1, 0x001023F8
+       sw      t1, 0(t0)
+
+       sync
+
+       li      t0, MEM_SDREFCFG
+       li      t1, 0x74000c30 /* Disable */
+       sw      t1, 0(t0)
+       sync
+
+       li      t0, MEM_SDPRECMD
+       sw      zero, 0(t0)
+       sync
+
+       li      t0, MEM_SDAUTOREF
+       sw      zero, 0(t0)
+       sync
+       sw      zero, 0(t0)
+       sync
+
+       li      t0, MEM_SDREFCFG
+       li      t1, 0x76000c30 /* Enable */
+       sw      t1, 0(t0)
+       sync
+
+       li      t0, MEM_SDWRMD0
+       li      t1, 0x00000023
+       sw      t1, 0(t0)
+       sync
+
+       li      t0, MEM_SDWRMD1
+       li      t1, 0x00000023
+       sw      t1, 0(t0)
+       sync
+
+       li      t0, MEM_SDWRMD2
+       li      t1, 0x00000023
+       sw      t1, 0(t0)
+       sync
+
+       /* wait 1mS after setup */
+       li      t1, MEM_1MS
+1:     add     t1, -1
+       bne     t1, zero, 1b
+       nop
+
+skip_memsetup:
+
+       li      t0, SYS_PINFUNC
+       li      t1, 0/*0x00008080*/
+       sw      t1, 0(t0)
+
+       /*
+       li      t0, SYS_TRIOUTCLR
+       li      t1, 0x00001FFF
+       sw      t1, 0(t0)
+
+       li      t0, SYS_OUTPUTCLR
+       li      t1, 0x00008000
+       sw      t1, 0(t0)
+       */
+       sync
+
+       j       ra
+       nop
diff --git a/board/pb1x00/memsetup.S b/board/pb1x00/memsetup.S
deleted file mode 100644 (file)
index 44f02b9..0000000
+++ /dev/null
@@ -1,392 +0,0 @@
-/* Memory sub-system initialization code */
-
-#include <config.h>
-#include <version.h>
-#include <asm/regdef.h>
-#include <asm/au1x00.h>
-#include <asm/mipsregs.h>
-
-#define AU1500_SYS_ADDR                0xB1900000
-#define sys_endian             0x0038
-#define CP0_Config0            $16
-#define MEM_1MS                        ((396000000/1000000) * 1000)
-
-       .text
-       .set noreorder
-       .set mips32
-
-       .globl  memsetup
-memsetup:
-       /*
-        * Step 1) Establish CPU endian mode.
-        * NOTE: A fair amount of code is necessary on the Pb1000 to
-        * obtain the value of Switch S8.1 which is used to determine
-        * endian at run-time.
-        */
-
-       /* RCE1 */
-       li              t0, MEM_STCFG1
-       li              t1, 0x00000083
-       sw              t1, 0(t0)
-
-       li              t0, MEM_STTIME1
-       li              t1, 0x33030A10
-       sw              t1, 0(t0)
-
-       li              t0, MEM_STADDR1
-       li              t1, 0x11803E40
-       sw              t1, 0(t0)
-
-       /* Set DSTRB bits so switch will read correctly */
-       li              t1, 0xBE00000C
-       lw              t2, 0(t1)
-       or              t2, t2, 0x00000300
-       sw              t2, 0(t1)
-
-       /* Check switch setting */
-       li              t1, 0xBE000014
-       lw              t2, 0(t1)
-       and             t2, t2, 0x00000100
-       bne             t2, zero, big_endian
-       nop
-
-little_endian:
-
-       /* Change Au1 core to little endian */
-       li      t0, AU1500_SYS_ADDR
-       li      t1, 1
-       sw      t1, sys_endian(t0)
-       mfc0    t2, CP0_CONFIG
-       mtc0    t2, CP0_CONFIG
-       nop
-       nop
-
-       /* Big Endian is default so nothing to do but fall through */
-
-big_endian:
-
-       /*
-        * Step 2) Establish Status Register
-        * (set BEV, clear ERL, clear EXL, clear IE)
-        */
-       li      t1, 0x00400000
-       mtc0    t1, CP0_STATUS
-
-       /*
-        * Step 3) Establish CP0 Config0
-        * (set OD, set K0=3)
-        */
-       li      t1, 0x00080003
-       mtc0    t1, CP0_CONFIG
-
-       /*
-        * Step 4) Disable Watchpoint facilities
-        */
-       li t1, 0x00000000
-       mtc0    t1, CP0_WATCHLO
-       mtc0    t1, CP0_IWATCHLO
-       /*
-        * Step 5) Disable the performance counters
-        */
-       mtc0    zero, CP0_PERFORMANCE
-       nop
-
-       /*
-        * Step 6) Establish EJTAG Debug register
-        */
-       mtc0    zero, CP0_DEBUG
-       nop
-
-       /*
-        * Step 7) Establish Cause
-        * (set IV bit)
-        */
-       li      t1, 0x00800000
-       mtc0    t1, CP0_CAUSE
-
-       /* Establish Wired (and Random) */
-       mtc0    zero, CP0_WIRED
-       nop
-
-       /* First setup pll:s to make serial work ok */
-       /* We have a 12 MHz crystal */
-       li      t0, SYS_CPUPLL
-       li      t1, 0x21  /* 396 MHz */
-       sw      t1, 0(t0)
-       sync
-       nop
-       nop
-
-       /* wait 1mS for clocks to settle */
-       li      t1, MEM_1MS
-1:     add     t1, -1
-       bne     t1, zero, 1b
-       nop
-       /* Setup AUX PLL */
-       li      t0, SYS_AUXPLL
-       li      t1, 8 /* 96 MHz */
-       sw      t1, 0(t0) /* aux pll */
-       sync
-
-       /*  Static memory controller */
-
-       /* RCE0 8MB AMD29D323 Flash */
-       li      t0, MEM_STCFG0
-       li      t1, 0x00001403
-       sw      t1, 0(t0)
-
-       li      t0, MEM_STTIME0
-       li      t1, 0xFFFFFFDD
-       sw      t1, 0(t0)
-
-       li      t0, MEM_STADDR0
-       li      t1, 0x11F83FE0
-       sw      t1, 0(t0)
-
-       /* RCE1 CPLD Board Logic */
-       li      t0, MEM_STCFG1
-       li      t1, 0x00000083
-       sw      t1, 0(t0)
-
-       li      t0, MEM_STTIME1
-       li      t1, 0x33030A10
-       sw      t1, 0(t0)
-
-       li      t0, MEM_STADDR1
-       li      t1, 0x11803E40
-       sw      t1, 0(t0)
-
-       /* RCE2 CPLD Board Logic */
-       li      t0, MEM_STCFG2
-       li      t1, 0x00000004
-       sw      t1, 0(t0)
-
-       li      t0, MEM_STTIME2
-       li      t1, 0x08061908
-       sw      t1, 0(t0)
-
-       li      t0, MEM_STADDR2
-       li      t1, 0x12A03FC0
-       sw      t1, 0(t0)
-
-       /* RCE3 PCMCIA 250ns */
-       li      t0, MEM_STCFG3
-       li      t1, 0x00000002
-       sw      t1, 0(t0)
-
-       li      t0, MEM_STTIME3
-       li      t1, 0x280E3E07
-       sw      t1, 0(t0)
-
-       li      t0, MEM_STADDR3
-       li      t1, 0x10000000
-       sw      t1, 0(t0)
-
-       sync
-
-       /* Set peripherals to a known state */
-       li      t0, IC0_CFG0CLR
-       li      t1, 0xFFFFFFFF
-       sw      t1, 0(t0)
-
-       li      t0, IC0_CFG0CLR
-       sw      t1, 0(t0)
-
-       li      t0, IC0_CFG1CLR
-       sw      t1, 0(t0)
-
-       li      t0, IC0_CFG2CLR
-       sw      t1, 0(t0)
-
-       li      t0, IC0_SRCSET
-       sw      t1, 0(t0)
-
-       li      t0, IC0_ASSIGNSET
-       sw      t1, 0(t0)
-
-       li      t0, IC0_WAKECLR
-       sw      t1, 0(t0)
-
-       li      t0, IC0_RISINGCLR
-       sw      t1, 0(t0)
-
-       li      t0, IC0_FALLINGCLR
-       sw      t1, 0(t0)
-
-       li      t0, IC0_TESTBIT
-       li      t1, 0x00000000
-       sw      t1, 0(t0)
-       sync
-
-       li      t0, IC1_CFG0CLR
-       li      t1, 0xFFFFFFFF
-       sw      t1, 0(t0)
-
-       li      t0, IC1_CFG0CLR
-       sw      t1, 0(t0)
-
-       li      t0, IC1_CFG1CLR
-       sw      t1, 0(t0)
-
-       li      t0, IC1_CFG2CLR
-       sw      t1, 0(t0)
-
-       li      t0, IC1_SRCSET
-       sw      t1, 0(t0)
-
-       li      t0, IC1_ASSIGNSET
-       sw      t1, 0(t0)
-
-       li      t0, IC1_WAKECLR
-       sw      t1, 0(t0)
-
-       li      t0, IC1_RISINGCLR
-       sw      t1, 0(t0)
-
-       li      t0, IC1_FALLINGCLR
-       sw      t1, 0(t0)
-
-       li      t0, IC1_TESTBIT
-       li      t1, 0x00000000
-       sw      t1, 0(t0)
-       sync
-
-       li      t0, SYS_FREQCTRL0
-       li      t1, 0x00000000
-       sw      t1, 0(t0)
-
-       li      t0, SYS_FREQCTRL1
-       li      t1, 0x00000000
-       sw      t1, 0(t0)
-
-       li      t0, SYS_CLKSRC
-       li      t1, 0x00000000
-       sw      t1, 0(t0)
-
-       li      t0, SYS_PININPUTEN
-       li      t1, 0x00000000
-       sw      t1, 0(t0)
-       sync
-
-       li      t0, 0xB1100100
-       li      t1, 0x00000000
-       sw      t1, 0(t0)
-
-       li      t0, 0xB1400100
-       li      t1, 0x00000000
-       sw      t1, 0(t0)
-
-
-       li      t0, SYS_WAKEMSK
-       li      t1, 0x00000000
-       sw      t1, 0(t0)
-
-       li      t0, SYS_WAKESRC
-       li      t1, 0x00000000
-       sw      t1, 0(t0)
-
-       /* wait 1mS before setup */
-       li      t1, MEM_1MS
-1:     add     t1, -1
-       bne     t1, zero, 1b
-       nop
-
-       /*
-        * Skip memory setup if we are running from memory
-        */
-       li              t0, 0x90000000
-       sub             t0, ra, t0
-       bltz            t0, skip_memsetup
-       nop
-
-       /*
-        * SDCS0 - Not used, for SMROM
-        * SDCS1 - 32MB Micron 48LCBM16A2
-        * SDCS2 - 32MB Micron 48LCBM16A2
-        */
-       li      t0, MEM_SDMODE0
-       li      t1, 0x00000000
-       sw      t1, 0(t0)
-
-       li      t0, MEM_SDMODE1
-       li      t1, 0x00552229
-       sw      t1, 0(t0)
-
-       li      t0, MEM_SDMODE2
-       li      t1, 0x00552229
-       sw      t1, 0(t0)
-
-       li      t0, MEM_SDADDR0
-       li      t1, 0x00000000
-       sw      t1, 0(t0)
-
-       li      t0, MEM_SDADDR1
-       li      t1, 0x001003F8
-       sw      t1, 0(t0)
-
-       li      t0, MEM_SDADDR2
-       li      t1, 0x001023F8
-       sw      t1, 0(t0)
-
-       sync
-
-       li      t0, MEM_SDREFCFG
-       li      t1, 0x74000c30 /* Disable */
-       sw      t1, 0(t0)
-       sync
-
-       li      t0, MEM_SDPRECMD
-       sw      zero, 0(t0)
-       sync
-
-       li      t0, MEM_SDAUTOREF
-       sw      zero, 0(t0)
-       sync
-       sw      zero, 0(t0)
-       sync
-
-       li      t0, MEM_SDREFCFG
-       li      t1, 0x76000c30 /* Enable */
-       sw      t1, 0(t0)
-       sync
-
-       li      t0, MEM_SDWRMD0
-       li      t1, 0x00000023
-       sw      t1, 0(t0)
-       sync
-
-       li      t0, MEM_SDWRMD1
-       li      t1, 0x00000023
-       sw      t1, 0(t0)
-       sync
-
-       li      t0, MEM_SDWRMD2
-       li      t1, 0x00000023
-       sw      t1, 0(t0)
-       sync
-
-       /* wait 1mS after setup */
-       li      t1, MEM_1MS
-1:     add     t1, -1
-       bne     t1, zero, 1b
-       nop
-
-skip_memsetup:
-
-       li      t0, SYS_PINFUNC
-       li      t1, 0/*0x00008080*/
-       sw      t1, 0(t0)
-
-       /*
-       li      t0, SYS_TRIOUTCLR
-       li      t1, 0x00001FFF
-       sw      t1, 0(t0)
-
-       li      t0, SYS_OUTPUTCLR
-       li      t1, 0x00008000
-       sw      t1, 0(t0)
-       */
-       sync
-
-       j       ra
-       nop
index 40ac2a4d7cd719812c90c13c3a23ab15787e4470..536c9544f53e407e9682c6a19ceb824d30ac8e0c 100644 (file)
@@ -25,6 +25,7 @@
 #include <command.h>
 #include <asm/au1x00.h>
 #include <asm/mipsregs.h>
+#include <asm/io.h>
 
 long int initdram(int board_type)
 {
@@ -41,7 +42,9 @@ void write_one_tlb( int index, u32 pagemask, u32 hi, u32 low0, u32 low1 );
 
 int checkboard (void)
 {
+#if defined(CONFIG_IDE_PCMCIA) && 0
        u16 status;
+#endif
        /* volatile u32 *pcmcia_bcsr = (u32*)(DB1000_BCSR_ADDR+0x10); */
        volatile u32 *sys_counter = (volatile u32*)SYS_COUNTER_CNTRL;
        u32 proc_id;
@@ -69,6 +72,9 @@ int checkboard (void)
        default:
                printf ("Unsupported cpu %d, proc_id=0x%x\n", proc_id >> 24, proc_id);
        }
+
+       set_io_port_base(0);
+
 #if defined(CONFIG_IDE_PCMCIA) && 0
        /* Enable 3.3 V on slot 0 ( VCC )
           No 5V */
index a2d19a84c9eae9195799605bbd7b2f0338555b2f..861873272b6196a71a7ab4685cf2d0e83126ed61 100644 (file)
@@ -43,20 +43,22 @@ SECTIONS
        . = ALIGN(4);
        .data  : { *(.data) }
 
-       . = ALIGN(4);
-       .sdata  : { *(.sdata) }
-
-       _gp = ALIGN(16);
+       . = .;
+       _gp = ALIGN(16) + 0x7ff0;
 
-       __got_start = .;
-       .got  : { *(.got) }
-       __got_end = .;
+       .got : {
+         __got_start = .;
+         *(.got)
+         __got_end = .;
+       }
 
        .sdata  : { *(.sdata) }
 
-       __u_boot_cmd_start = .;
-       .u_boot_cmd : { *(.u_boot_cmd) }
-       __u_boot_cmd_end = .;
+       .u_boot_cmd : {
+         __u_boot_cmd_start = .;
+         *(.u_boot_cmd)
+         __u_boot_cmd_end = .;
+       }
 
        uboot_end_data = .;
        num_got_entries = (__got_end - __got_start) >> 2;
index 97271d921e49e71f567615e46967cb68c7622e25..5a1eba6b3f7eb050095705c8c1de1094672b216d 100644 (file)
@@ -196,7 +196,7 @@ void flash_print_info (flash_info_t * info)
        int i;
        uchar *boottype;
        uchar *bootletter;
-       uchar *fmt;
+       char *fmt;
        uchar botbootletter[] = "B";
        uchar topbootletter[] = "T";
        uchar botboottype[] = "bottom boot sector";
index 7522580808d9e929b0a24d2a71120dba65b05524..1baae35eb886a291a40b7c6e0db1f23cdfe60b8a 100644 (file)
@@ -299,7 +299,7 @@ void flash_print_info (flash_info_t *info)
        int i;
        uchar *boottype;
        uchar *bootletter;
-       uchar *fmt;
+       char *fmt;
        uchar botbootletter[] = "B";
        uchar topbootletter[] = "T";
        uchar botboottype[] = "bottom boot sector";
index 4c3e5b44b5303ed161d30fe90a885658e5755f2d..74718afb4897d4e690a23ffda5243ed3189d0389 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/inca-ip.h>
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
+#include <asm/io.h>
 #include <asm/addrspace.h>
 #include <asm/cacheops.h>
 
@@ -145,6 +146,8 @@ int checkboard (void)
 
        printf("CPU Speed %d MHz\n", CPU_CLOCK_RATE/1000000);
 
+       set_io_port_base(0);
+
        return 0;
 }
 
index 1bdac1f4a6faa64c02bdf17d00f973a24675ea8a..50e7f848e913913fe1759cf86a59d6f0880d1786 100644 (file)
@@ -53,21 +53,22 @@ SECTIONS
        . = ALIGN(4);
        .data  : { *(.data) }
 
-       . = ALIGN(4);
-       .sdata  : { *(.sdata) }
-
-       _gp = ALIGN(16);
+       . = .;
+       _gp = ALIGN(16) + 0x7ff0;
 
-       __got_start = .;
-       .got  : { *(.got) }
-       __got_end = .;
+       .got : {
+         __got_start = .;
+         *(.got)
+         __got_end = .;
+       }
 
        .sdata  : { *(.sdata) }
 
-       . = .;
-       __u_boot_cmd_start = .;
-       .u_boot_cmd : { *(.u_boot_cmd) }
-       __u_boot_cmd_end = .;
+       .u_boot_cmd : {
+         __u_boot_cmd_start = .;
+         *(.u_boot_cmd)
+         __u_boot_cmd_end = .;
+       }
 
        uboot_end_data = .;
        num_got_entries = (__got_end - __got_start) >> 2;
index bf4fd5305f90af973b6daccb6be62ffa3e250288..312d4b8605dd7fb4f28a7cbab5b682d6287a4cbc 100644 (file)
@@ -210,7 +210,7 @@ void read_RS5C372_time (struct tm *timedate)
 
 #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
 
-       if (i2c_read (RS5C372_PPC_I2C_ADR, 0, 1, buffer, sizeof (buffer))) {
+       if (i2c_read (RS5C372_PPC_I2C_ADR, 0, 1, buffer, sizeof (buffer))) {
                timedate->tm_sec = BCD_TO_BIN (buffer[0]);
                timedate->tm_min = BCD_TO_BIN (buffer[1]);
                timedate->tm_hour = BCD_TO_BIN (buffer[2]);
@@ -231,7 +231,7 @@ int read_LM84_temp (int address)
        unsigned char buffer[8];
        /*int rc;*/
 
-       if (i2c_read (address, 0, 1, buffer, 1)) {
+       if (i2c_read (address, 0, 1, buffer, 1)) {
                return (int) buffer[0];
        } else {
                /*printf("i2c error %02x\n", rc); */
index 9bd6248095267e3af50ebc40e9acaff8a1d27343..70fc3a5d2799034dbc00711a89a4fb91fe9c70bc 100644 (file)
@@ -55,6 +55,7 @@ SECTIONS
   {
     cpu/mpc8260/start.o        (.text)
     *(.text)
+    *(.fixup)
     *(.got1)
     /*. = env_offset; */
   }
index f2718f256ff6ca91165231e8318373f72e29f6b0..0c669e4d76c23f02a4db9044a4958f94ff85c5c3 100644 (file)
@@ -288,7 +288,7 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
  * Copy memory to flash
  */
 
-volatile static int write_hword (flash_info_t * info, ulong dest, ushort data)
+static int write_hword (flash_info_t * info, ulong dest, ushort data)
 {
        vu_short *addr = (vu_short *) dest;
        ushort result;
index 993946be93b8510a280bb0d380161d2835909562..376930bd3cbf4b448fe5dd6b261c06b6fa7b4c34 100644 (file)
@@ -290,7 +290,7 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
  * Copy memory to flash
  */
 
-volatile static int write_hword (flash_info_t * info, ulong dest, ushort data)
+static int write_hword (flash_info_t * info, ulong dest, ushort data)
 {
        vu_short *addr = (vu_short *) dest;
        ushort result;
index e7914bd15bd7c9a94894013bb5911f67f55bacb8..61c2e9bd36606f00872c90bd082f12b1f223513e 100644 (file)
 #include <command.h>
 #include <asm/addrspace.h>
 #include <asm/inca-ip.h>
+#include <asm/io.h>
 #include <pci.h>
 
-unsigned long mips_io_port_base = 0;
-
 #if defined(CONFIG_PCI)
 static struct pci_controller hose;
 
@@ -26,17 +25,17 @@ void pci_init_board (void)
 }
 #endif
 
-
 long int initdram(int board_type)
 {
        return get_ram_size (CFG_SDRAM_BASE, 0x8000000);
 }
 
-
 int checkboard (void)
 {
        printf("Board: TANBAC TB0229 ");
        printf("(CPU Speed %d MHz)\n", (int)CPU_CLOCK_RATE/1000000);
 
+       set_io_port_base(0);
+
        return 0;
 }
index 30a2bc57eac50d9b3504b211ba2c96f362902e97..c629040a080575ff52d85ff2dd0c132d69cd4052 100644 (file)
@@ -43,21 +43,22 @@ SECTIONS
        . = ALIGN(4);
        .data  : { *(.data) }
 
-       . = ALIGN(4);
-       .sdata  : { *(.sdata) }
-
-       _gp = ALIGN(16);
+       . = .;
+       _gp = ALIGN(16) + 0x7ff0;
 
-       __got_start = .;
-       .got  : { *(.got) }
-       __got_end = .;
+       .got : {
+         __got_start = .;
+         *(.got)
+         __got_end = .;
+       }
 
        .sdata  : { *(.sdata) }
 
-       . = .;
-       __u_boot_cmd_start = .;
-       .u_boot_cmd : { *(.u_boot_cmd) }
-       __u_boot_cmd_end = .;
+       .u_boot_cmd : {
+         __u_boot_cmd_start = .;
+         *(.u_boot_cmd)
+         __u_boot_cmd_end = .;
+       }
 
        uboot_end_data = .;
        num_got_entries = (__got_end - __got_start) >> 2;
index d10cb5937d66ca21bc526c98253dc4bfe99b3b18..f33d17258ded641ee8c889be33acee964b603338 100644 (file)
@@ -441,15 +441,23 @@ ulong post_word_load (void)
 }
 #endif /* CONFIG_POST || CONFIG_LOGBUFFER*/
 
-#ifdef CONFIG_PS2MULT
 #ifdef CONFIG_BOARD_EARLY_INIT_R
 int board_early_init_r (void)
 {
+       extern int usb_cpu_init(void);
+
+#ifdef CONFIG_PS2MULT
        ps2mult_early_init();
+#endif /* CONFIG_PS2MULT */
+
+#if defined(CONFIG_USB_OHCI_NEW) && defined(CFG_USB_OHCI_CPU_INIT)
+       /* Low level USB init, required for proper kernel operation */
+       usb_cpu_init();
+#endif
+
        return (0);
 }
 #endif
-#endif /* CONFIG_PS2MULT */
 
 #ifdef CONFIG_FO300
 int silent_boot (void)
@@ -585,9 +593,9 @@ int last_stage_init (void)
                disable_ctrlc(1);
        }
 #endif
+#endif /* !CONFIG_TQM5200S */
 
        return 0;
-#endif /* !CONFIG_TQM5200S */
 }
 
 #ifdef CONFIG_VIDEO_SM501
index 0ad1b666b917baf9dca15c1a51eb51a998cec447..d8ea6e5731c32d172f043fd3622349473c1cd639 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <common.h>
 #include <exports.h>
-#include "../drivers/smc91111.h"
+#include "../drivers/net/smc91111.h"
 
 #define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE
 
index 2a322903d5f9427d4797b7de8a64b277f522f95c..e2e08f742d07c19265a2ff2ff8679afba4cad741 100644 (file)
@@ -44,6 +44,7 @@
 
 #if ( WEP_FLASH_BUS_WIDTH == 1 )
 #  define FLASH_BUS vu_char
+#  define FLASH_BUS_RET u_char
 #  if ( WEP_FLASH_INTERLEAVE == 1 )
 #    define FLASH_CMD( x ) x
 #  else
@@ -53,6 +54,7 @@
 
 #elif ( WEP_FLASH_BUS_WIDTH == 2 )
 #  define FLASH_BUS vu_short
+#  define FLASH_BUS_RET u_short
 #  if ( WEP_FLASH_INTERLEAVE == 1 )
 #    define FLASH_CMD( x ) x
 #  elif ( WEP_FLASH_INTERLEAVE == 2 )
@@ -64,6 +66,7 @@
 
 #elif ( WEP_FLASH_BUS_WIDTH == 4 )
 #  define FLASH_BUS vu_long
+#  define FLASH_BUS_RET u_long
 #  if ( WEP_FLASH_INTERLEAVE == 1 )
 #    define FLASH_CMD( x ) x
 #  elif ( WEP_FLASH_INTERLEAVE == 2 )
@@ -81,7 +84,7 @@
 
 flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
 
-static FLASH_BUS flash_status_reg (void)
+static FLASH_BUS_RET flash_status_reg (void)
 {
 
        FLASH_BUS *addr = (FLASH_BUS *) 0;
index fde5ad903d63dddd7d2950168f483ecd7c228180..ace8cc7edc0663cd250c5ffebaab57aa344676e5 100644 (file)
@@ -27,32 +27,113 @@ LIB        = $(obj)libcommon.a
 
 AOBJS  =
 
-COBJS  = main.o ACEX1K.o altera.o bedbug.o circbuf.o cmd_autoscript.o \
-         cmd_bdinfo.o cmd_bedbug.o cmd_bmp.o cmd_boot.o cmd_bootm.o \
-         cmd_cache.o cmd_console.o \
-         cmd_date.o cmd_dcr.o cmd_diag.o cmd_display.o cmd_doc.o cmd_dtt.o \
-         cmd_eeprom.o cmd_elf.o cmd_ext2.o \
-         cmd_fat.o cmd_fdc.o cmd_fdt.o cmd_fdos.o cmd_flash.o cmd_fpga.o \
-         cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o \
-         cmd_load.o cmd_log.o \
-         cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \
-         cmd_nand.o cmd_net.o cmd_nvedit.o \
-         cmd_onenand.o \
-         cmd_pci.o cmd_pcmcia.o cmd_portio.o \
-         cmd_reginfo.o cmd_reiser.o cmd_sata.o cmd_scsi.o cmd_spi.o \
-         cmd_universe.o cmd_usb.o cmd_vfd.o \
-         command.o console.o cyclon2.o devices.o dlmalloc.o docecc.o \
-         environment.o env_common.o \
-         env_nand.o env_dataflash.o env_flash.o env_eeprom.o \
-         env_onenand.o env_nvram.o env_nowhere.o \
-         exports.o \
-         fdt_support.o flash.o fpga.o ft_build.o \
-         hush.o kgdb.o lcd.o lists.o lynxkdi.o \
-         memsize.o miiphybb.o miiphyutil.o \
-         s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o \
-         usb.o usb_kbd.o usb_storage.o \
-         virtex2.o xilinx.o crc16.o xyzModem.o cmd_mac.o cmd_mfsl.o
+COBJS-y += main.o
+COBJS-y += ACEX1K.o
+COBJS-y += altera.o
+COBJS-y += bedbug.o
+COBJS-y += circbuf.o
+COBJS-y += cmd_autoscript.o
+COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
+COBJS-$(CONFIG_CMD_BEDBUG) += cmd_bedbug.o
+COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o
+COBJS-y += cmd_boot.o
+COBJS-y += cmd_bootm.o
+COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o
+COBJS-$(CONFIG_CMD_CONSOLE) += cmd_console.o
+COBJS-$(CONFIG_CMD_DATE) += cmd_date.o
+ifdef CONFIG_4xx
+COBJS-$(CONFIG_CMD_SETGETDCR) += cmd_dcr.o
+endif
+ifdef CONFIG_POST
+COBJS-$(CONFIG_CMD_DIAG) += cmd_diag.o
+endif
+COBJS-$(CONFIG_CMD_DISPLAY) += cmd_display.o
+COBJS-$(CONFIG_CMD_DOC) += cmd_doc.o
+COBJS-$(CONFIG_CMD_DTT) += cmd_dtt.o
+COBJS-y += cmd_eeprom.o
+COBJS-$(CONFIG_CMD_ELF) += cmd_elf.o
+COBJS-$(CONFIG_CMD_EXT2) += cmd_ext2.o
+COBJS-$(CONFIG_CMD_FAT) += cmd_fat.o
+COBJS-y += cmd_fdc.o
+COBJS-$(CONFIG_OF_LIBFDT) += cmd_fdt.o
+COBJS-$(CONFIG_CMD_FDOS) += cmd_fdos.o
+COBJS-$(CONFIG_CMD_FLASH) += cmd_flash.o
+ifdef CONFIG_FPGA
+COBJS-$(CONFIG_CMD_FPGA) += cmd_fpga.o
+endif
+COBJS-$(CONFIG_CMD_I2C) += cmd_i2c.o
+COBJS-$(CONFIG_CMD_IDE) += cmd_ide.o
+COBJS-$(CONFIG_CMD_IMMAP) += cmd_immap.o
+COBJS-$(CONFIG_CMD_ITEST) += cmd_itest.o
+COBJS-$(CONFIG_CMD_JFFS2) += cmd_jffs2.o
+COBJS-y += cmd_load.o
+COBJS-$(CONFIG_LOGBUFFER) += cmd_log.o
+COBJS-y += cmd_mem.o
+COBJS-$(CONFIG_CMD_MII) += cmd_mii.o
+COBJS-$(CONFIG_CMD_MISC) += cmd_misc.o
+COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o
+COBJS-y += cmd_nand.o
+COBJS-$(CONFIG_CMD_NET) += cmd_net.o
+COBJS-y += cmd_nvedit.o
+COBJS-y += cmd_onenand.o
+ifdef CONFIG_PCI
+COBJS-$(CONFIG_CMD_PCI) += cmd_pci.o
+endif
+COBJS-y += cmd_pcmcia.o
+COBJS-$(CONFIG_CMD_PORTIO) += cmd_portio.o
+COBJS-$(CONFIG_CMD_REGINFO) += cmd_reginfo.o
+COBJS-$(CONFIG_CMD_REISER) += cmd_reiser.o
+COBJS-y += cmd_sata.o
+COBJS-$(CONFIG_CMD_SCSI) += cmd_scsi.o
+COBJS-$(CONFIG_CMD_SPI) += cmd_spi.o
+COBJS-$(CONFIG_CMD_UNIVERSE) += cmd_universe.o
+COBJS-$(CONFIG_CMD_USB) += cmd_usb.o
+COBJS-y += cmd_vfd.o
+COBJS-y += command.o
+COBJS-y += console.o
+COBJS-y += cyclon2.o
+COBJS-y += devices.o
+COBJS-y += dlmalloc.o
+COBJS-y += docecc.o
+COBJS-y += environment.o
+COBJS-y += env_common.o
+COBJS-y += env_nand.o
+COBJS-y += env_dataflash.o
+COBJS-y += env_flash.o
+COBJS-y += env_eeprom.o
+COBJS-y += env_onenand.o
+COBJS-y += env_nvram.o
+COBJS-y += env_nowhere.o
+COBJS-y += exports.o
+COBJS-y += fdt_support.o
+COBJS-y += flash.o
+COBJS-y += fpga.o
+COBJS-y += ft_build.o
+COBJS-y += hush.o
+COBJS-y += kgdb.o
+COBJS-y += lcd.o
+COBJS-y += lists.o
+COBJS-y += lynxkdi.o
+COBJS-y += memsize.o
+COBJS-y += miiphybb.o
+COBJS-y += miiphyutil.o
+COBJS-y += s_record.o
+COBJS-y += serial.o
+COBJS-y += soft_i2c.o
+COBJS-y += soft_spi.o
+COBJS-y += spartan2.o
+COBJS-y += spartan3.o
+COBJS-y += usb.o
+COBJS-y += usb_kbd.o
+COBJS-y += usb_storage.o
+COBJS-y += virtex2.o
+COBJS-y += xilinx.o
+COBJS-y += crc16.o
+COBJS-y += xyzModem.o
+COBJS-y += cmd_mac.o
+COBJS-$(CONFIG_CMD_MFSL) += cmd_mfsl.o
 
+COBJS  := $(COBJS-y)
 SRCS   := $(AOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(AOBJS) $(COBJS))
 
index ef15a006cd19af522fd51b311c3dfeeecddf9550..d05998366b150e82f6200f249c017c2c989c052d 100644 (file)
@@ -30,7 +30,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#if defined(CONFIG_CMD_BDI)
 static void print_num(const char *, ulong);
 
 #ifndef CONFIG_ARM     /* PowerPC and other */
@@ -350,4 +349,3 @@ U_BOOT_CMD(
        "bdinfo  - print Board Info structure\n",
        NULL
 );
-#endif
index 1c3547a1fcc680247d4401c244d7ef55b4f22916..94f7e0847b4b63b07bc5b224d2355dd3d228bee3 100644 (file)
@@ -13,8 +13,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#if defined(CONFIG_CMD_BEDBUG)
-
 #ifndef MAX
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 #endif
@@ -413,7 +411,6 @@ int do_bedbug_rdump (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 U_BOOT_CMD (rdump, 1, 1, do_bedbug_rdump,
            "rdump   - Show registers.\n", " - Show registers.\n");
 /* ====================================================================== */
-#endif
 
 
 /*
index 241aa8357a3ce3ccea7e3fee4f137c53b1dcd128..907f9a2db7e15da815fa5273e4cdb26f9428cd2b 100644 (file)
@@ -31,8 +31,6 @@
 #include <asm/byteorder.h>
 #include <malloc.h>
 
-#if defined(CONFIG_CMD_BMP)
-
 static int bmp_info (ulong addr);
 static int bmp_display (ulong addr, int x, int y);
 
@@ -187,5 +185,3 @@ static int bmp_display(ulong addr, int x, int y)
 # error bmp_display() requires CONFIG_LCD or CONFIG_VIDEO
 #endif
 }
-
-#endif /* defined(CONFIG_CMD_BMP) */
index 5e0f990723b371c013fe315af27811db812fc2e4..50ddb011cd402d81dd9a6a19efed26f3baf6cb00 100644 (file)
@@ -28,8 +28,6 @@
 #include <command.h>
 #include <devices.h>
 
-#if defined(CONFIG_CMD_CONSOLE)
-
 extern void _do_coninfo (void);
 int do_coninfo (cmd_tbl_t * cmd, int flag, int argc, char *argv[])
 {
@@ -67,5 +65,3 @@ U_BOOT_CMD(
        "coninfo - print console devices and information\n",
        ""
 );
-
-#endif
index 4a42534900a78c90ee6945874e437afa24ba5258..751159847a487da0fd3c034d355417eed03ca646 100644 (file)
@@ -31,8 +31,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#if defined(CONFIG_CMD_DATE)
-
 const char *weekdays[] = {
        "Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur",
 };
@@ -210,5 +208,3 @@ U_BOOT_CMD(
        "  - with numeric argument: set the system date & time\n"
        "  - with 'reset' argument: reset the RTC\n"
 );
-
-#endif
index 12fa9db08d07bcd5037467c65f1f3d329beb503d..a053343abe872c5098c19b5a43320413bf69f65f 100644 (file)
@@ -29,8 +29,6 @@
 #include <config.h>
 #include <command.h>
 
-#if defined(CONFIG_4xx) && defined(CONFIG_CMD_SETGETDCR)
-
 unsigned long get_dcr (unsigned short);
 unsigned long set_dcr (unsigned short, unsigned long);
 
@@ -245,5 +243,3 @@ U_BOOT_CMD(
        "setidcr - Set a register value via indirect DCR addressing\n",
        "adr_dcrn[.dat_dcrn] offset value - write offset to adr_dcrn, write value to dat_dcrn.\n"
 );
-
-#endif
index cb99b7700f7770dd8b014202544bb3e447231119..82d5ad313478f5b1985ec143d484553b74a35386 100644 (file)
@@ -28,8 +28,6 @@
 #include <command.h>
 #include <post.h>
 
-#if defined(CONFIG_CMD_DIAG) && defined(CONFIG_POST)
-
 int do_diag (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 {
        unsigned int i;
@@ -76,5 +74,3 @@ U_BOOT_CMD(
        "diag run [test1 [test2]]\n"
        "         - run specified tests\n"
 );
-
-#endif
index d19f412819d2aba58a364122b8c714b6940bcba5..a29345c6ba11c7d3527b4e2c42747b420e081d4d 100644 (file)
@@ -24,8 +24,6 @@
 #include <common.h>
 #include <command.h>
 
-#if defined(CONFIG_CMD_DISPLAY)
-
 #undef DEBUG_DISP
 
 #define DISP_SIZE      8
@@ -78,5 +76,3 @@ U_BOOT_CMD(
        "    - with <string> argument: display <string> on dot matrix display\n"
        "    - without arguments: clear dot matrix display\n"
 );
-
-#endif
index d6d3aff8c875757e62067455643a94ad01a40194..3d717c039d444a54c3cd756d8a8c44e0474abbc0 100644 (file)
@@ -11,9 +11,6 @@
 #include <command.h>
 #include <malloc.h>
 #include <asm/io.h>
-
-#if defined(CONFIG_CMD_DOC)
-
 #include <linux/mtd/nftl.h>
 #include <linux/mtd/doc2000.h>
 
@@ -1607,5 +1604,3 @@ void doc_probe(unsigned long physadr)
                puts ("No DiskOnChip found\n");
        }
 }
-
-#endif
index 804d467f251f3aaa13fd4c00e642454d23c67f3b..956dc69daecbd3736f86b94096c41669c06fd4ed 100644 (file)
@@ -25,8 +25,6 @@
 #include <config.h>
 #include <command.h>
 
-#if defined(CONFIG_CMD_DTT)
-
 #include <dtt.h>
 #include <i2c.h>
 
@@ -60,5 +58,3 @@ U_BOOT_CMD(
          "dtt     - Digital Thermometer and Thermostat\n",
          "        - Read temperature from digital thermometer and thermostat.\n"
 );
-
-#endif
index 63a5593e4343ae16964f4cb369b00cedbeaff6c4..2eb745315602afa86b351255844d5d636b4a2a0e 100644 (file)
@@ -23,8 +23,6 @@
 DECLARE_GLOBAL_DATA_PTR;
 #endif
 
-#if defined(CONFIG_CMD_ELF)
-
 #ifndef MAX
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 #endif
@@ -323,5 +321,3 @@ U_BOOT_CMD(
        "bootvx  - Boot vxWorks from an ELF image\n",
        " [address] - load address of vxWorks ELF image.\n"
 );
-
-#endif
index 8bd2b476e5448f2067f19b839194380cda93337c..f569406432264f0a61eba2182d1ecd89ebb9d126 100644 (file)
@@ -34,8 +34,6 @@
  */
 #include <common.h>
 #include <part.h>
-
-#if defined(CONFIG_CMD_EXT2)
 #include <config.h>
 #include <command.h>
 #include <image.h>
@@ -259,5 +257,3 @@ U_BOOT_CMD(
        "    - load binary file 'filename' from 'dev' on 'interface'\n"
        "      to address 'addr' from ext2 filesystem\n"
 );
-
-#endif
index 54f0f9f9cec7f82a938888679212b9134d0c892a..9576cdf389df838323d32d3c005cc0fdb0d96e3f 100644 (file)
 #include <net.h>
 #include <ata.h>
 #include <part.h>
-
-#if defined(CONFIG_CMD_FAT)
-
-#undef DEBUG
-
 #include <fat.h>
 
 
@@ -323,5 +318,3 @@ void hexdump (int cnt, unsigned char *data)
        }
 }
 #endif /* NOT_IMPLEMENTED_YET */
-
-#endif
index f9da98ddcc7e9491345435aedfa752fad4d861a6..b3dbd19faea952f448f8c03e1f56f39e7bf96997 100644 (file)
@@ -31,8 +31,6 @@
 #include <command.h>
 #include <fdc.h>
 
-#if defined(CONFIG_CMD_FDOS)
-
 /*-----------------------------------------------------------------------------
  * do_fdosboot --
  *-----------------------------------------------------------------------------
@@ -153,5 +151,3 @@ U_BOOT_CMD(
        "fdosls  - list files in a directory\n",
        "[directory]\n"
 );
-
-#endif
index 571b8f14d56f3bc97dcd49eb8465cfdc9988d786..629c9b413ea6524cfebd565240ef098ace230ca8 100644 (file)
@@ -28,9 +28,6 @@
 #include <command.h>
 #include <linux/ctype.h>
 #include <linux/types.h>
-
-#ifdef CONFIG_OF_LIBFDT
-
 #include <asm/global_data.h>
 #include <fdt.h>
 #include <libfdt.h>
@@ -47,7 +44,7 @@ DECLARE_GLOBAL_DATA_PTR;
 static int fdt_valid(void);
 static int fdt_parse_prop(char *pathp, char *prop, char *newval,
        char *data, int *len);
-static int fdt_print(char *pathp, char *prop, int depth);
+static int fdt_print(const char *pathp, char *prop, int depth);
 
 /*
  * Flattened Device Tree command, see the help for parameter definitions.
@@ -78,7 +75,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
                        /*
                         * Optional new length
                         */
-                       len =  simple_strtoul(argv[3], NULL, 16);
+                       len = simple_strtoul(argv[3], NULL, 16);
                        if (len < fdt_totalsize(fdt)) {
                                printf ("New length %d < existing length %d, "
                                        "ignoring.\n",
@@ -165,12 +162,12 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
                pathp = argv[2];
                nodep = argv[3];
 
-               nodeoffset = fdt_find_node_by_path (fdt, pathp);
+               nodeoffset = fdt_path_offset (fdt, pathp);
                if (nodeoffset < 0) {
                        /*
                         * Not found or something else bad happened.
                         */
-                       printf ("libfdt fdt_find_node_by_path() returned %s\n",
+                       printf ("libfdt fdt_path_offset() returned %s\n",
                                fdt_strerror(nodeoffset));
                        return 1;
                }
@@ -205,12 +202,12 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
                prop   = argv[3];
                newval = argv[4];
 
-               nodeoffset = fdt_find_node_by_path (fdt, pathp);
+               nodeoffset = fdt_path_offset (fdt, pathp);
                if (nodeoffset < 0) {
                        /*
                         * Not found or something else bad happened.
                         */
-                       printf ("libfdt fdt_find_node_by_path() returned %s\n",
+                       printf ("libfdt fdt_path_offset() returned %s\n",
                                fdt_strerror(nodeoffset));
                        return 1;
                }
@@ -232,6 +229,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
                char *pathp;            /* path */
                char *prop;             /* property */
                int  ret;               /* return value */
+               static char root[2] = "/";
 
                /*
                 * list is an alias for print, but limited to 1 level
@@ -244,7 +242,10 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
                 * Get the starting path.  The root node is an oddball,
                 * the offset is zero and has no name.
                 */
-               pathp = argv[2];
+               if (argc == 2)
+                       pathp = root;
+               else
+                       pathp = argv[2];
                if (argc > 3)
                        prop = argv[3];
                else
@@ -265,12 +266,12 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
                 * Get the path.  The root node is an oddball, the offset
                 * is zero and has no name.
                 */
-               nodeoffset = fdt_find_node_by_path (fdt, argv[2]);
+               nodeoffset = fdt_path_offset (fdt, argv[2]);
                if (nodeoffset < 0) {
                        /*
                         * Not found or something else bad happened.
                         */
-                       printf ("libfdt fdt_find_node_by_path() returned %s\n",
+                       printf ("libfdt fdt_path_offset() returned %s\n",
                                fdt_strerror(nodeoffset));
                        return 1;
                }
@@ -521,21 +522,21 @@ static void print_data(const void *data, int len)
 
        switch (len) {
        case 1:  /* byte */
-               printf("<%02x>", (*(u8 *) data) & 0xff);
+               printf("<0x%02x>", (*(u8 *) data) & 0xff);
                break;
        case 2:  /* half-word */
-               printf("<%04x>", be16_to_cpu(*(u16 *) data) & 0xffff);
+               printf("<0x%04x>", be16_to_cpu(*(u16 *) data) & 0xffff);
                break;
        case 4:  /* word */
-               printf("<%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
+               printf("<0x%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
                break;
        case 8:  /* double-word */
 #if __WORDSIZE == 64
-               printf("<%016llx>", be64_to_cpu(*(uint64_t *) data));
+               printf("<0x%016llx>", be64_to_cpu(*(uint64_t *) data));
 #else
-               printf("<%08x ", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
+               printf("<0x%08x ", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
                data += 4;
-               printf("%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
+               printf("0x%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
 #endif
                break;
        default:                /* anything else... hexdump */
@@ -554,25 +555,25 @@ static void print_data(const void *data, int len)
  * Recursively print (a portion of) the fdt.  The depth parameter
  * determines how deeply nested the fdt is printed.
  */
-static int fdt_print(char *pathp, char *prop, int depth)
+static int fdt_print(const char *pathp, char *prop, int depth)
 {
-       static int offstack[MAX_LEVEL];
        static char tabs[MAX_LEVEL+1] =
                "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"
                "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
-       void *nodep;            /* property node pointer */
+       const void *nodep;      /* property node pointer */
        int  nodeoffset;        /* node offset from libfdt */
        int  nextoffset;        /* next node offset from libfdt */
        uint32_t tag;           /* tag */
        int  len;               /* length of the property */
        int  level = 0;         /* keep track of nesting level */
+       const struct fdt_property *fdt_prop;
 
-       nodeoffset = fdt_find_node_by_path (fdt, pathp);
+       nodeoffset = fdt_path_offset (fdt, pathp);
        if (nodeoffset < 0) {
                /*
                 * Not found or something else bad happened.
                 */
-               printf ("libfdt fdt_find_node_by_path() returned %s\n",
+               printf ("libfdt fdt_path_offset() returned %s\n",
                        fdt_strerror(nodeoffset));
                return 1;
        }
@@ -602,45 +603,52 @@ static int fdt_print(char *pathp, char *prop, int depth)
         * The user passed in a node path and no property,
         * print the node and all subnodes.
         */
-       offstack[0] = nodeoffset;
-
        while(level >= 0) {
-               tag = fdt_next_tag(fdt, nodeoffset, &nextoffset, &pathp);
+               tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
                switch(tag) {
                case FDT_BEGIN_NODE:
-                       if(level <= depth)
+                       pathp = fdt_get_name(fdt, nodeoffset, NULL);
+                       if (level <= depth) {
+                               if (pathp == NULL)
+                                       pathp = "/* NULL pointer error */";
+                               if (*pathp == '\0')
+                                       pathp = "/";    /* root is nameless */
                                printf("%s%s {\n",
                                        &tabs[MAX_LEVEL - level], pathp);
+                       }
                        level++;
-                       offstack[level] = nodeoffset;
                        if (level >= MAX_LEVEL) {
-                               printf("Aaaiii <splat> nested too deep. "
-                                       "Aborting.\n");
+                               printf("Nested too deep, aborting.\n");
                                return 1;
                        }
                        break;
                case FDT_END_NODE:
                        level--;
-                       if(level <= depth)
+                       if (level <= depth)
                                printf("%s};\n", &tabs[MAX_LEVEL - level]);
                        if (level == 0) {
                                level = -1;             /* exit the loop */
                        }
                        break;
                case FDT_PROP:
-                       nodep = fdt_getprop (fdt, offstack[level], pathp, &len);
+                       fdt_prop = fdt_offset_ptr(fdt, nodeoffset,
+                                       sizeof(*fdt_prop));
+                       pathp    = fdt_string(fdt,
+                                       fdt32_to_cpu(fdt_prop->nameoff));
+                       len      = fdt32_to_cpu(fdt_prop->len);
+                       nodep    = fdt_prop->data;
                        if (len < 0) {
                                printf ("libfdt fdt_getprop(): %s\n",
                                        fdt_strerror(len));
                                return 1;
                        } else if (len == 0) {
                                /* the property has no value */
-                               if(level <= depth)
+                               if (level <= depth)
                                        printf("%s%s;\n",
                                                &tabs[MAX_LEVEL - level],
                                                pathp);
                        } else {
-                               if(level <= depth) {
+                               if (level <= depth) {
                                        printf("%s%s=",
                                                &tabs[MAX_LEVEL - level],
                                                pathp);
@@ -650,11 +658,12 @@ static int fdt_print(char *pathp, char *prop, int depth)
                        }
                        break;
                case FDT_NOP:
+                       printf("/* NOP */\n", &tabs[MAX_LEVEL - level]);
                        break;
                case FDT_END:
                        return 1;
                default:
-                       if(level <= depth)
+                       if (level <= depth)
                                printf("Unknown tag 0x%08X\n", tag);
                        return 1;
                }
@@ -692,5 +701,3 @@ U_BOOT_CMD(
        "          fdt print /cpus \"#address-cells\"\n"
        "          fdt set   /cpus \"#address-cells\" \"[00 00 00 01]\"\n"
 );
-
-#endif /* CONFIG_OF_LIBFDT */
index 11c8857313b42d2e0c95fb8b2b7d82ab4be6511a..f56443e25e3a80ef03b0a46a17369d55a1c0665f 100644 (file)
@@ -31,8 +31,6 @@
 #include <dataflash.h>
 #endif
 
-#if defined(CONFIG_CMD_FLASH)
-
 #if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
 #include <jffs2/jffs2.h>
 
@@ -731,5 +729,3 @@ U_BOOT_CMD(
 #undef TMP_ERASE
 #undef TMP_PROT_ON
 #undef TMP_PROT_OFF
-
-#endif
index cce23ad70d78ce4e316583d71f40d23c41bbc8dd..377a692f7dc3b2810500e020df420f91aaee30ee 100644 (file)
@@ -43,8 +43,6 @@
 #define PRINTF(fmt,args...)
 #endif
 
-#if defined (CONFIG_FPGA) && defined(CONFIG_CMD_FPGA)
-
 /* Local functions */
 static void fpga_usage (cmd_tbl_t * cmdtp);
 static int fpga_get_op (char *opstr);
@@ -321,4 +319,3 @@ U_BOOT_CMD (fpga, 6, 1, do_fpga,
            "\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\n"
            "\tloadmk\tLoad device generated with mkimage\n"
            "\tdump\tLoad device to memory buffer\n");
-#endif
index a684a580e6edc24f54f057ad0a93de8d40659d95..10cab4609a5da87c2d7a1fc67db302d40f4991b9 100644 (file)
@@ -86,9 +86,6 @@
 #include <i2c.h>
 #include <asm/byteorder.h>
 
-#if defined(CONFIG_CMD_I2C)
-
-
 /* Display values from last command.
  * Memory modify remembered values are different from display memory.
  */
@@ -1024,5 +1021,3 @@ U_BOOT_CMD(
        "      (valid chip values 50..57)\n"
 );
 #endif
-
-#endif
index bb064eaa04a3ad7869db70aeca2f99f23a3be8b9..821dcff9bf4b3026a86b463011aae73f2c74631b 100644 (file)
 
 #ifndef __PPC__
 #include <asm/io.h>
-#ifdef __MIPS__
-/* Macros depend on this variable */
-unsigned long mips_io_port_base = 0;
-#endif
 #endif
 
 #ifdef CONFIG_IDE_8xx_DIRECT
@@ -72,8 +68,6 @@ DECLARE_GLOBAL_DATA_PTR;
 # define SYNC          /* nothing */
 #endif
 
-#if defined(CONFIG_CMD_IDE)
-
 #ifdef CONFIG_IDE_8xx_DIRECT
 /* Timings for IDE Interface
  *
@@ -1136,9 +1130,9 @@ static void ide_ident (block_dev_desc_t *dev_desc)
 
        input_swap_data (device, iobuf, ATA_SECTORWORDS);
 
-       ident_cpy (dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision));
-       ident_cpy (dev_desc->vendor, iop->model, sizeof(dev_desc->vendor));
-       ident_cpy (dev_desc->product, iop->serial_no, sizeof(dev_desc->product));
+       ident_cpy ((unsigned char*)dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision));
+       ident_cpy ((unsigned char*)dev_desc->vendor, iop->model, sizeof(dev_desc->vendor));
+       ident_cpy ((unsigned char*)dev_desc->product, iop->serial_no, sizeof(dev_desc->product));
 #ifdef __LITTLE_ENDIAN
        /*
         * firmware revision and model number have Big Endian Byte
@@ -1953,9 +1947,9 @@ static void       atapi_inquiry(block_dev_desc_t * dev_desc)
                return;
 
        /* copy device ident strings */
-       ident_cpy(dev_desc->vendor,&iobuf[8],8);
-       ident_cpy(dev_desc->product,&iobuf[16],16);
-       ident_cpy(dev_desc->revision,&iobuf[32],5);
+       ident_cpy((unsigned char*)dev_desc->vendor,&iobuf[8],8);
+       ident_cpy((unsigned char*)dev_desc->product,&iobuf[16],16);
+       ident_cpy((unsigned char*)dev_desc->revision,&iobuf[32],5);
 
        dev_desc->lun=0;
        dev_desc->lba=0;
@@ -2085,5 +2079,3 @@ U_BOOT_CMD(
        "diskboot- boot from IDE device\n",
        "loadAddr dev:part\n"
 );
-
-#endif
index ae95758247d5e15cd26da5aca3b36ea45cdba7f8..d758269777324da5bceb0da1d54bd751898beb17 100644 (file)
@@ -28,8 +28,7 @@
 #include <common.h>
 #include <command.h>
 
-#if defined(CONFIG_CMD_IMMAP) && \
-    (defined(CONFIG_8xx) || defined(CONFIG_8260))
+#if defined(CONFIG_8xx) || defined(CONFIG_8260)
 
 #if defined(CONFIG_8xx)
 #include <asm/8xx_immap.h>
@@ -41,9 +40,7 @@
 #include <asm/iopin_8260.h>
 #endif
 
-#if defined(CONFIG_8xx) || defined(CONFIG_8260)
 DECLARE_GLOBAL_DATA_PTR;
-#endif
 
 static void
 unimplemented ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
index 8e2051714ce6e441c808bd1e1136e328c41497f9..ce988723c02d18733d79410dddb385746c9a06e7 100644 (file)
@@ -32,8 +32,6 @@
 #include <config.h>
 #include <command.h>
 
-#if defined(CONFIG_CMD_ITEST)
-
 #define EQ     0
 #define NE     1
 #define LT     2
@@ -197,4 +195,3 @@ U_BOOT_CMD(
        "itest\t- return true/false on integer compare\n",
        "[.b, .w, .l, .s] [*]value1 <op> [*]value2\n"
 );
-#endif
index 513a226c43113db0aea70df980b7464859883237..efe9eb7be4ca1b1b46e8122b306ec3124478295f 100644 (file)
@@ -93,9 +93,6 @@
 #include <jffs2/jffs2.h>
 #include <linux/list.h>
 #include <linux/ctype.h>
-
-#if defined(CONFIG_CMD_JFFS2)
-
 #include <cramfs/cramfs_fs.h>
 
 #if defined(CONFIG_CMD_NAND)
@@ -2191,5 +2188,3 @@ U_BOOT_CMD(
 #endif /* #ifdef CONFIG_JFFS2_CMDLINE */
 
 /***************************************************/
-
-#endif
index fba8bd8bf5c51a3e39ecbaa0fd8ccb3d8f639eec..e593dbedd374c74fe2d5b61f3dbeaba189b56151 100644 (file)
@@ -48,8 +48,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#if defined(CONFIG_LOGBUFFER)
-
 /* Local prototypes */
 static void logbuff_putc (const char c);
 static void logbuff_puts (const char *s);
@@ -287,5 +285,3 @@ static int logbuff_printk(const char *line)
        }
        return i;
 }
-
-#endif /* (CONFIG_LOGBUFFER) */
index 9d1d87551a5b130a5b74e3fd142e2a7ce4bf66ca..5982b76e6e9ca0bc6c220485878cb8a51fbde87d 100644 (file)
@@ -29,8 +29,6 @@
 #include <common.h>
 #include <config.h>
 #include <command.h>
-
-#if defined(CONFIG_CMD_MFSL)
 #include <asm/asm.h>
 
 int do_frd (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
@@ -413,5 +411,3 @@ U_BOOT_CMD (rspr, 3, 1, do_rspr,
                " 1 - MSR - Machine status register\n"
                " 3 - EAR - Exception address register\n"
                " 5 - ESR - Exception status register\n");
-
-#endif
index 72e11d54425097d4eec8e790597803a3aa42be8c..f530a38421e04b61169ee60e6804a027fa2a213b 100644 (file)
@@ -27,8 +27,6 @@
 
 #include <common.h>
 #include <command.h>
-
-#if defined(CONFIG_CMD_MII)
 #include <miiphy.h>
 
 #ifdef CONFIG_TERSE_MII
@@ -112,9 +110,11 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
                                        "OUI = 0x%04X, "
                                        "Model = 0x%02X, "
                                        "Rev = 0x%02X, "
-                                       "%3dbaseT, %s\n",
+                                       "%3dbase%s, %s\n",
                                        j, oui, model, rev,
                                        miiphy_speed (devname, j),
+                                       miiphy_is_1000base_x (devname, j)
+                                               ? "X" : "T",
                                        (miiphy_duplex (devname, j) == FULL)
                                                ? "FDX" : "HDX");
                        }
@@ -496,9 +496,11 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
                                        "OUI = 0x%04X, "
                                        "Model = 0x%02X, "
                                        "Rev = 0x%02X, "
-                                       "%3dbaseT, %s\n",
+                                       "%3dbase%s, %s\n",
                                        j, oui, model, rev,
                                        miiphy_speed (devname, j),
+                                       miiphy_is_1000base_x (devname, j)
+                                               ? "X" : "T",
                                        (miiphy_duplex (devname, j) == FULL)
                                                ? "FDX" : "HDX");
                        }
@@ -594,5 +596,3 @@ U_BOOT_CMD(
 );
 
 #endif /* CONFIG_TERSE_MII */
-
-#endif
index c0c6b8f05af54ae683dcfd102514657e6863dda8..126b538ce8d551ecf5e0e1df85e9d0e5924bc932 100644 (file)
@@ -27,8 +27,6 @@
 #include <common.h>
 #include <command.h>
 
-#if defined(CONFIG_CMD_MISC)
-
 int do_sleep (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
        ulong start = get_timer(0);
@@ -68,5 +66,3 @@ U_BOOT_CMD(
        "N\n"
        "    - delay execution for N seconds (N is _decimal_ !!!)\n"
 );
-
-#endif
index 069c6d02a066ab5a6a010cd0c3df883cd8b1bfe4..25c970257d0b34844bcfc6734a65aaaaca0afe98 100644 (file)
@@ -23,9 +23,6 @@
 
 #include <common.h>
 #include <command.h>
-
-#if defined(CONFIG_CMD_MMC)
-
 #include <mmc.h>
 
 int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
@@ -42,5 +39,3 @@ U_BOOT_CMD(
        "mmcinit - init mmc card\n",
        NULL
 );
-
-#endif
index 0715fbc203ce06fc8fa2c61af5db240ec9de50b3..21682c09e93393aa3ac5a89f8f6e9a54279c685f 100644 (file)
@@ -28,8 +28,6 @@
 #include <command.h>
 #include <net.h>
 
-#if defined(CONFIG_CMD_NET)
-
 extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
 
 static int netboot_common (proto_t, cmd_tbl_t *, int , char *[]);
@@ -343,5 +341,3 @@ U_BOOT_CMD(
        "[NTP server IP]\n"
 );
 #endif
-
-#endif
index 8be6da93f936a4ca6d3353b9f9b3ac6c0041d4de..82d97178f5dd24ad1482e6c8450b62ce110a8b84 100644 (file)
  */
 
 #include <common.h>
-
-#ifdef CONFIG_PCI
-
 #include <command.h>
 #include <asm/processor.h>
 #include <asm/io.h>
 #include <pci.h>
 
-#if defined(CONFIG_CMD_PCI)
-
 extern int cmd_get_data_size(char* arg, int default_size);
 
 unsigned char  ShortPCIListing = 1;
@@ -564,7 +559,3 @@ U_BOOT_CMD(
        "pci write[.b, .w, .l] b.d.f address value\n"
        "    - write to CFG address\n"
 );
-
-#endif
-
-#endif /* CONFIG_PCI */
index bfe33e3a8cbd5f0166dcf4bf29fc4fcd568695b9..a06cac01663b914038a4ef90ac83159f84f0d798 100644 (file)
@@ -30,8 +30,6 @@
 #include <common.h>
 #include <command.h>
 
-#if defined(CONFIG_CMD_PORTIO)
-
 extern int cmd_get_data_size (char *arg, int default_size);
 
 /* Display values from last command.
@@ -165,5 +163,3 @@ U_BOOT_CMD(
        "[.b, .w, .l] port\n"
        "    - read datum from IO port\n"
 );
-
-#endif
index 17e9cd9072aa8cfbab4e11c75377db850af3403c..bb6aa30d18a3ba7ae8aa0247296a38012a8af3eb 100644 (file)
@@ -33,8 +33,6 @@
 #include <mpc5xxx.h>
 #endif
 
-#if defined(CONFIG_CMD_REGINFO)
-
 int do_reginfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 #if defined(CONFIG_8xx)
@@ -335,9 +333,6 @@ int do_reginfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        return 0;
 }
 
-#endif
-
-
  /**************************************************/
 
 #if ( defined(CONFIG_8xx)   || defined(CONFIG_405GP) || \
index 1ba392990067ec384ab08d619f87b5b14fcd191a..b7395d7959f366ac9d756b815e48e216abf40b0d 100644 (file)
@@ -27,8 +27,6 @@
  * Reiserfs support
  */
 #include <common.h>
-
-#if defined(CONFIG_CMD_REISER)
 #include <config.h>
 #include <command.h>
 #include <image.h>
@@ -239,5 +237,3 @@ U_BOOT_CMD(
        "    - load binary file 'filename' from 'dev' on 'interface'\n"
        "      to address 'addr' from dos filesystem\n"
 );
-
-#endif
index f56393107faa807623623c6694685b3fdac3716b..1cdec159f5a8d71aef09a73292a4bc21dcb48355 100644 (file)
@@ -34,8 +34,6 @@
 #include <image.h>
 #include <pci.h>
 
-#if defined(CONFIG_CMD_SCSI)
-
 #ifdef CONFIG_SCSI_SYM53C8XX
 #define SCSI_VEND_ID   0x1000
 #ifndef CONFIG_SCSI_DEV_ID
@@ -129,9 +127,12 @@ void scsi_scan(int mode)
                        if((modi&0x80)==0x80) /* drive is removable */
                                scsi_dev_desc[scsi_max_devs].removable=TRUE;
                        /* get info for this device */
-                       scsi_ident_cpy(&scsi_dev_desc[scsi_max_devs].vendor[0],&tempbuff[8],8);
-                       scsi_ident_cpy(&scsi_dev_desc[scsi_max_devs].product[0],&tempbuff[16],16);
-                       scsi_ident_cpy(&scsi_dev_desc[scsi_max_devs].revision[0],&tempbuff[32],4);
+                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc[scsi_max_devs].vendor[0],
+                                      &tempbuff[8], 8);
+                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc[scsi_max_devs].product[0],
+                                      &tempbuff[16], 16);
+                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc[scsi_max_devs].revision[0],
+                                      &tempbuff[32], 4);
                        scsi_dev_desc[scsi_max_devs].target=pccb->target;
                        scsi_dev_desc[scsi_max_devs].lun=pccb->lun;
 
@@ -608,5 +609,3 @@ U_BOOT_CMD(
        "scsiboot- boot from SCSI device\n",
        "loadAddr dev:part\n"
 );
-
-#endif
index 3118d279b97dcea25658f561b06d6b1bfde7ff29..76044221416c9fbd194828b6f4c6bd35fdd461fd 100644 (file)
@@ -29,8 +29,6 @@
 #include <command.h>
 #include <spi.h>
 
-#if defined(CONFIG_CMD_SPI)
-
 /*-----------------------------------------------------------------------
  * Definitions
  */
@@ -139,5 +137,3 @@ U_BOOT_CMD(
        "<bit_len> - Number of bits to send (base 10)\n"
        "<dout>    - Hexadecimal string that gets sent\n"
 );
-
-#endif
index 8bf0b1f1e28da4d93233a9665fbc63e811ef4cf2..ea977828a05e35c359c4b3765e86f03601d3a3ee 100644 (file)
@@ -28,8 +28,6 @@
 
 #include <universe.h>
 
-#if defined(CONFIG_CMD_UNIVERSE)
-
 #define PCI_VENDOR PCI_VENDOR_ID_TUNDRA
 #define PCI_DEVICE PCI_DEVICE_ID_TUNDRA_CA91C042
 
@@ -386,5 +384,3 @@ U_BOOT_CMD(
        "                                      02 -> D16 Data Width\n"
        "                                      03 -> D32 Data Width\n"
 );
-
-#endif
index 45e07f175c8792b6c5814c776e51207aa1b482f2..c6b17c2ab7ad2af8d74ac4ce4c55c63e07f60dac 100644 (file)
@@ -29,9 +29,6 @@
 #include <command.h>
 #include <asm/byteorder.h>
 #include <part.h>
-
-#if defined(CONFIG_CMD_USB)
-
 #include <usb.h>
 
 #ifdef CONFIG_USB_STORAGE
@@ -608,12 +605,6 @@ int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        return 1;
 }
 
-
-#endif
-
-
-#if defined(CONFIG_CMD_USB)
-
 #ifdef CONFIG_USB_STORAGE
 U_BOOT_CMD(
        usb,    5,      1,      do_usb,
@@ -645,4 +636,3 @@ U_BOOT_CMD(
        "usb  info [dev] - show available USB devices\n"
 );
 #endif
-#endif
index 175d59eb99432ccb36078a766043c0722eb9c2ec..c67bb3d390f4f4524679bbec4c450b605c347a2a 100644 (file)
@@ -44,6 +44,32 @@ struct fdt_header *fdt;
 
 /********************************************************************/
 
+/**
+ * fdt_find_and_setprop: Find a node and set it's property
+ *
+ * @fdt: ptr to device tree
+ * @node: path of node
+ * @prop: property name
+ * @val: ptr to new value
+ * @len: length of new property value
+ * @create: flag to create the property if it doesn't exist
+ *
+ * Convenience function to directly set a property given the path to the node.
+ */
+int fdt_find_and_setprop(void *fdt, const char *node, const char *prop,
+                        const void *val, int len, int create)
+{
+       int nodeoff = fdt_path_offset(fdt, node);
+
+       if (nodeoff < 0)
+               return nodeoff;
+
+       if ((!create) && (fdt_get_property(fdt, nodeoff, prop, 0) == NULL))
+               return 0; /* create flag not set; so exit quietly */
+
+       return fdt_setprop(fdt, nodeoff, prop, val, len);
+}
+
 int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force)
 {
        int   nodeoffset;
@@ -58,34 +84,23 @@ int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force)
        }
 
        if (initrd_start && initrd_end) {
-               struct fdt_reserve_entry re;
-               int  used;
-               int  total;
+               uint64_t addr, size;
+               int  total = fdt_num_mem_rsv(fdt);
                int  j;
 
-               err = fdt_num_reservemap(fdt, &used, &total);
-               if (err < 0) {
-                       printf("fdt_chosen: %s\n", fdt_strerror(err));
-                       return err;
-               }
-               if (used >= total) {
-                       printf("WARNING: "
-                               "no room in the reserved map (%d of %d)\n",
-                               used, total);
-                       return -1;
-               }
                /*
                 * Look for an existing entry and update it.  If we don't find
                 * the entry, we will j be the next available slot.
                 */
-               for (j = 0; j < used; j++) {
-                       err = fdt_get_reservemap(fdt, j, &re);
-                       if (re.address == initrd_start) {
+               for (j = 0; j < total; j++) {
+                       err = fdt_get_mem_rsv(fdt, j, &addr, &size);
+                       if (addr == initrd_start) {
+                               fdt_del_mem_rsv(fdt, j);
                                break;
                        }
                }
-               err = fdt_replace_reservemap_entry(fdt, j,
-                       initrd_start, initrd_end - initrd_start + 1);
+
+               err = fdt_add_mem_rsv(fdt, initrd_start, initrd_end - initrd_start + 1);
                if (err < 0) {
                        printf("fdt_chosen: %s\n", fdt_strerror(err));
                        return err;
@@ -95,7 +110,7 @@ int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force)
        /*
         * Find the "chosen" node.
         */
-       nodeoffset = fdt_find_node_by_path (fdt, "/chosen");
+       nodeoffset = fdt_path_offset (fdt, "/chosen");
 
        /*
         * If we have a "chosen" node already the "force the writing"
@@ -182,7 +197,7 @@ int fdt_env(void *fdt)
         * See if we already have a "u-boot-env" node, delete it if so.
         * Then create a new empty node.
         */
-       nodeoffset = fdt_find_node_by_path (fdt, "/u-boot-env");
+       nodeoffset = fdt_path_offset (fdt, "/u-boot-env");
        if (nodeoffset >= 0) {
                err = fdt_del_node(fdt, nodeoffset);
                if (err < 0) {
@@ -304,7 +319,7 @@ int fdt_bd_t(void *fdt)
         * See if we already have a "bd_t" node, delete it if so.
         * Then create a new empty node.
         */
-       nodeoffset = fdt_find_node_by_path (fdt, "/bd_t");
+       nodeoffset = fdt_path_offset (fdt, "/bd_t");
        if (nodeoffset >= 0) {
                err = fdt_del_node(fdt, nodeoffset);
                if (err < 0) {
@@ -348,4 +363,128 @@ int fdt_bd_t(void *fdt)
 }
 #endif /* ifdef CONFIG_OF_HAS_BD_T */
 
+void do_fixup_by_path(void *fdt, const char *path, const char *prop,
+                     const void *val, int len, int create)
+{
+#if defined(DEBUG)
+       int i;
+       debug("Updating property '%s/%s' = ", node, prop);
+       for (i = 0; i < len; i++)
+               debug(" %.2x", *(u8*)(val+i));
+       debug("\n");
+#endif
+       int rc = fdt_find_and_setprop(fdt, path, prop, val, len, create);
+       if (rc)
+               printf("Unable to update property %s:%s, err=%s\n",
+                       path, prop, fdt_strerror(rc));
+}
+
+void do_fixup_by_path_u32(void *fdt, const char *path, const char *prop,
+                         u32 val, int create)
+{
+       val = cpu_to_fdt32(val);
+       do_fixup_by_path(fdt, path, prop, &val, sizeof(val), create);
+}
+
+void do_fixup_by_prop(void *fdt,
+                     const char *pname, const void *pval, int plen,
+                     const char *prop, const void *val, int len,
+                     int create)
+{
+       int off;
+#if defined(DEBUG)
+       int i;
+       debug("Updating property '%s/%s' = ", node, prop);
+       for (i = 0; i < len; i++)
+               debug(" %.2x", *(u8*)(val+i));
+       debug("\n");
+#endif
+       off = fdt_node_offset_by_prop_value(fdt, -1, pname, pval, plen);
+       while (off != -FDT_ERR_NOTFOUND) {
+               if (create || (fdt_get_property(fdt, off, prop, 0) != NULL))
+                       fdt_setprop(fdt, off, prop, val, len);
+               off = fdt_node_offset_by_prop_value(fdt, off, pname, pval, plen);
+       }
+}
+
+void do_fixup_by_prop_u32(void *fdt,
+                         const char *pname, const void *pval, int plen,
+                         const char *prop, u32 val, int create)
+{
+       val = cpu_to_fdt32(val);
+       do_fixup_by_prop(fdt, pname, pval, plen, prop, &val, 4, create);
+}
+
+void do_fixup_by_compat(void *fdt, const char *compat,
+                       const char *prop, const void *val, int len, int create)
+{
+       int off = -1;
+#if defined(DEBUG)
+       int i;
+       debug("Updating property '%s/%s' = ", node, prop);
+       for (i = 0; i < len; i++)
+               debug(" %.2x", *(u8*)(val+i));
+       debug("\n");
+#endif
+       off = fdt_node_offset_by_compatible(fdt, -1, compat);
+       while (off != -FDT_ERR_NOTFOUND) {
+               if (create || (fdt_get_property(fdt, off, prop, 0) != NULL))
+                       fdt_setprop(fdt, off, prop, val, len);
+               off = fdt_node_offset_by_compatible(fdt, off, compat);
+       }
+}
+
+void do_fixup_by_compat_u32(void *fdt, const char *compat,
+                           const char *prop, u32 val, int create)
+{
+       val = cpu_to_fdt32(val);
+       do_fixup_by_compat(fdt, compat, prop, &val, 4, create);
+}
+
+void fdt_fixup_ethernet(void *fdt, bd_t *bd)
+{
+       int node;
+       const char *path;
+
+       node = fdt_path_offset(fdt, "/aliases");
+       if (node >= 0) {
+#if defined(CONFIG_HAS_ETH0)
+               path = fdt_getprop(fdt, node, "ethernet0", NULL);
+               if (path) {
+                       do_fixup_by_path(fdt, path, "mac-address",
+                               bd->bi_enetaddr, 6, 0);
+                       do_fixup_by_path(fdt, path, "local-mac-address",
+                               bd->bi_enetaddr, 6, 1);
+               }
+#endif
+#if defined(CONFIG_HAS_ETH1)
+               path = fdt_getprop(fdt, node, "ethernet1", NULL);
+               if (path) {
+                       do_fixup_by_path(fdt, path, "mac-address",
+                               bd->bi_enet1addr, 6, 0);
+                       do_fixup_by_path(fdt, path, "local-mac-address",
+                               bd->bi_enet1addr, 6, 1);
+               }
+#endif
+#if defined(CONFIG_HAS_ETH2)
+               path = fdt_getprop(fdt, node, "ethernet2", NULL);
+               if (path) {
+                       do_fixup_by_path(fdt, path, "mac-address",
+                               bd->bi_enet2addr, 6, 0);
+                       do_fixup_by_path(fdt, path, "local-mac-address",
+                               bd->bi_enet2addr, 6, 1);
+               }
+#endif
+#if defined(CONFIG_HAS_ETH3)
+               path = fdt_getprop(fdt, node, "ethernet3", NULL);
+               if (path) {
+                       do_fixup_by_path(fdt, path, "mac-address",
+                               bd->bi_enet3addr, 6, 0);
+                       do_fixup_by_path(fdt, path, "local-mac-address",
+                               bd->bi_enet3addr, 6, 1);
+               }
+#endif
+       }
+}
+
 #endif /* CONFIG_OF_LIBFDT */
index c69501fedfb9a77150a4a9b7265d85d8465f24a5..281f0b29e3bc1c006e312ee6188e9892b7ef5ab5 100644 (file)
 struct mii_dev {
        struct list_head link;
        char *name;
-       int (* read)(char *devname, unsigned char addr,
-                       unsigned char reg, unsigned short *value);
-       int (* write)(char *devname, unsigned char addr,
-                       unsigned char reg, unsigned short value);
+       int (*read) (char *devname, unsigned char addr,
+                    unsigned char reg, unsigned short *value);
+       int (*write) (char *devname, unsigned char addr,
+                     unsigned char reg, unsigned short value);
 };
 
 static struct list_head mii_devs;
@@ -62,21 +62,21 @@ static struct mii_dev *current_mii;
  *
  * Initialize global data. Need to be called before any other miiphy routine.
  */
-void miiphy_init()
+void miiphy_init ()
 {
-               INIT_LIST_HEAD(&mii_devs);
-               current_mii = NULL;
+       INIT_LIST_HEAD (&mii_devs);
+       current_mii = NULL;
 }
 
 /*****************************************************************************
  *
  * Register read and write MII access routines for the device <name>.
  */
-void miiphy_register(char *name,
-               int (* read)(char *devname, unsigned char addr,
-                       unsigned char reg, unsigned short *value),
-               int (* write)(char *devname, unsigned char addr,
-                       unsigned char reg, unsigned short value))
+void miiphy_register (char *name,
+                     int (*read) (char *devname, unsigned char addr,
+                                  unsigned char reg, unsigned short *value),
+                     int (*write) (char *devname, unsigned char addr,
+                                   unsigned char reg, unsigned short value))
 {
        struct list_head *entry;
        struct mii_dev *new_dev;
@@ -84,63 +84,64 @@ void miiphy_register(char *name,
        unsigned int name_len;
 
        /* check if we have unique name */
-       list_for_each(entry, &mii_devs) {
-               miidev = list_entry(entry, struct mii_dev, link);
-               if (strcmp(miidev->name, name) == 0) {
-                       printf("miiphy_register: non unique device name '%s'\n",
-                                       name);
+       list_for_each (entry, &mii_devs) {
+               miidev = list_entry (entry, struct mii_dev, link);
+               if (strcmp (miidev->name, name) == 0) {
+                       printf ("miiphy_register: non unique device name "
+                               "'%s'\n", name);
                        return;
                }
        }
 
        /* allocate memory */
-       name_len = strlen(name);
-       new_dev = (struct mii_dev *)malloc(sizeof(struct mii_dev) + name_len + 1);
+       name_len = strlen (name);
+       new_dev =
+           (struct mii_dev *)malloc (sizeof (struct mii_dev) + name_len + 1);
 
-       if(new_dev == NULL) {
-               printf("miiphy_register: cannot allocate memory for '%s'\n",
-                               name);
+       if (new_dev == NULL) {
+               printf ("miiphy_register: cannot allocate memory for '%s'\n",
+                       name);
                return;
        }
-       memset(new_dev, 0, sizeof(struct mii_dev) + name_len);
+       memset (new_dev, 0, sizeof (struct mii_dev) + name_len);
 
        /* initalize mii_dev struct fields */
-       INIT_LIST_HEAD(&new_dev->link);
+       INIT_LIST_HEAD (&new_dev->link);
        new_dev->read = read;
        new_dev->write = write;
        new_dev->name = (char *)(new_dev + 1);
-       strncpy(new_dev->name, name, name_len);
+       strncpy (new_dev->name, name, name_len);
        new_dev->name[name_len] = '\0';
 
-       debug("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n",
-                       new_dev->name, new_dev->read, new_dev->write);
+       debug ("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n",
+              new_dev->name, new_dev->read, new_dev->write);
 
        /* add it to the list */
-       list_add_tail(&new_dev->link, &mii_devs);
+       list_add_tail (&new_dev->link, &mii_devs);
 
        if (!current_mii)
                current_mii = new_dev;
 }
 
-int miiphy_set_current_dev(char *devname)
+int miiphy_set_current_dev (char *devname)
 {
        struct list_head *entry;
        struct mii_dev *dev;
 
-       list_for_each(entry, &mii_devs) {
-               dev = list_entry(entry, struct mii_dev, link);
+       list_for_each (entry, &mii_devs) {
+               dev = list_entry (entry, struct mii_dev, link);
 
-               if (strcmp(devname, dev->name) == 0) {
+               if (strcmp (devname, dev->name) == 0) {
                        current_mii = dev;
                        return 0;
                }
        }
 
-       printf("No such device: %s\n", devname);
+       printf ("No such device: %s\n", devname);
        return 1;
 }
 
-char *miiphy_get_current_dev()
+char *miiphy_get_current_dev ()
 {
        if (current_mii)
                return current_mii->name;
@@ -156,8 +157,8 @@ char *miiphy_get_current_dev()
  * Returns:
  *   0 on success
  */
-int miiphy_read(char *devname, unsigned char addr, unsigned char reg,
-               unsigned short *value)
+int miiphy_read (char *devname, unsigned char addr, unsigned char reg,
+                unsigned short *value)
 {
        struct list_head *entry;
        struct mii_dev *dev;
@@ -165,22 +166,22 @@ int miiphy_read(char *devname, unsigned char addr, unsigned char reg,
        int read_ret = 0;
 
        if (!devname) {
-               printf("NULL device name!\n");
+               printf ("NULL device name!\n");
                return 1;
        }
 
-       list_for_each(entry, &mii_devs) {
-               dev = list_entry(entry, struct mii_dev, link);
+       list_for_each (entry, &mii_devs) {
+               dev = list_entry (entry, struct mii_dev, link);
 
-               if (strcmp(devname, dev->name) == 0) {
+               if (strcmp (devname, dev->name) == 0) {
                        found_dev = 1;
-                       read_ret = dev->read(devname, addr, reg, value);
+                       read_ret = dev->read (devname, addr, reg, value);
                        break;
                }
        }
 
        if (found_dev == 0)
-               printf("No such device: %s\n", devname);
+               printf ("No such device: %s\n", devname);
 
        return ((found_dev) ? read_ret : 1);
 }
@@ -193,8 +194,8 @@ int miiphy_read(char *devname, unsigned char addr, unsigned char reg,
  * Returns:
  *   0 on success
  */
-int miiphy_write(char *devname, unsigned char addr, unsigned char reg,
-               unsigned short value)
+int miiphy_write (char *devname, unsigned char addr, unsigned char reg,
+                 unsigned short value)
 {
        struct list_head *entry;
        struct mii_dev *dev;
@@ -202,22 +203,22 @@ int miiphy_write(char *devname, unsigned char addr, unsigned char reg,
        int write_ret = 0;
 
        if (!devname) {
-               printf("NULL device name!\n");
+               printf ("NULL device name!\n");
                return 1;
        }
 
-       list_for_each(entry, &mii_devs) {
-               dev = list_entry(entry, struct mii_dev, link);
+       list_for_each (entry, &mii_devs) {
+               dev = list_entry (entry, struct mii_dev, link);
 
-               if (strcmp(devname, dev->name) == 0) {
+               if (strcmp (devname, dev->name) == 0) {
                        found_dev = 1;
-                       write_ret = dev->write(devname, addr, reg, value);
+                       write_ret = dev->write (devname, addr, reg, value);
                        break;
                }
        }
 
        if (found_dev == 0)
-               printf("No such device: %s\n", devname);
+               printf ("No such device: %s\n", devname);
 
        return ((found_dev) ? write_ret : 1);
 }
@@ -226,23 +227,22 @@ int miiphy_write(char *devname, unsigned char addr, unsigned char reg,
  *
  * Print out list of registered MII capable devices.
  */
-void miiphy_listdev(void)
+void miiphy_listdev (void)
 {
        struct list_head *entry;
        struct mii_dev *dev;
 
-       puts("MII devices: ");
-       list_for_each(entry, &mii_devs) {
-               dev = list_entry(entry, struct mii_dev, link);
-               printf("'%s' ", dev->name);
+       puts ("MII devices: ");
+       list_for_each (entry, &mii_devs) {
+               dev = list_entry (entry, struct mii_dev, link);
+               printf ("'%s' ", dev->name);
        }
-       puts("\n");
+       puts ("\n");
 
        if (current_mii)
-               printf("Current device: '%s'\n", current_mii->name);
+               printf ("Current device: '%s'\n", current_mii->name);
 }
 
-
 /*****************************************************************************
  *
  * Read the OUI, manufacture's model number, and revision number.
@@ -254,9 +254,7 @@ void miiphy_listdev(void)
  * Returns:
  *   0 on success
  */
-int miiphy_info (char *devname,
-                unsigned char addr,
-                unsigned int *oui,
+int miiphy_info (char *devname, unsigned char addr, unsigned int *oui,
                 unsigned char *model, unsigned char *rev)
 {
        unsigned int reg = 0;
@@ -288,13 +286,12 @@ int miiphy_info (char *devname,
 #ifdef DEBUG
        printf ("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg);
 #endif
-       *oui   =                 ( reg >> 10);
-       *model = (unsigned char) ((reg >>  4) & 0x0000003F);
-       *rev   = (unsigned char) ( reg        & 0x0000000F);
+       *oui = (reg >> 10);
+       *model = (unsigned char)((reg >> 4) & 0x0000003F);
+       *rev = (unsigned char)(reg & 0x0000000F);
        return (0);
 }
 
-
 /*****************************************************************************
  *
  * Reset the PHY.
@@ -345,104 +342,138 @@ int miiphy_reset (char *devname, unsigned char addr)
        return (0);
 }
 
-
 /*****************************************************************************
  *
- * Determine the ethernet speed (10/100).
+ * Determine the ethernet speed (10/100/1000).  Return 10 on error.
  */
 int miiphy_speed (char *devname, unsigned char addr)
 {
-       unsigned short reg;
+       u16 bmcr, anlpar;
 
 #if defined(CONFIG_PHY_GIGE)
-       if (miiphy_read (devname, addr, PHY_1000BTSR, &reg)) {
-               printf ("PHY 1000BT Status read failed\n");
-       } else {
-               if (reg != 0xFFFF) {
-                       if ((reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) !=0) {
-                               return (_1000BASET);
-                       }
-               }
+       u16 btsr;
+
+       /*
+        * Check for 1000BASE-X.  If it is supported, then assume that the speed
+        * is 1000.
+        */
+       if (miiphy_is_1000base_x (devname, addr)) {
+               return _1000BASET;
+       }
+       /*
+        * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
+        */
+       /* Check for 1000BASE-T. */
+       if (miiphy_read (devname, addr, PHY_1000BTSR, &btsr)) {
+               printf ("PHY 1000BT status");
+               goto miiphy_read_failed;
+       }
+       if (btsr != 0xFFFF &&
+           (btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD))) {
+               return _1000BASET;
        }
 #endif /* CONFIG_PHY_GIGE */
 
        /* Check Basic Management Control Register first. */
-       if (miiphy_read (devname, addr, PHY_BMCR, &reg)) {
-               puts ("PHY speed read failed, assuming 10bT\n");
-               return (_10BASET);
+       if (miiphy_read (devname, addr, PHY_BMCR, &bmcr)) {
+               printf ("PHY speed");
+               goto miiphy_read_failed;
        }
        /* Check if auto-negotiation is on. */
-       if ((reg & PHY_BMCR_AUTON) != 0) {
+       if (bmcr & PHY_BMCR_AUTON) {
                /* Get auto-negotiation results. */
-               if (miiphy_read (devname, addr, PHY_ANLPAR, &reg)) {
-                       puts ("PHY AN speed read failed, assuming 10bT\n");
-                       return (_10BASET);
-               }
-               if ((reg & PHY_ANLPAR_100) != 0) {
-                       return (_100BASET);
-               } else {
-                       return (_10BASET);
+               if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
+                       printf ("PHY AN speed");
+                       goto miiphy_read_failed;
                }
+               return (anlpar & PHY_ANLPAR_100) ? _100BASET : _10BASET;
        }
        /* Get speed from basic control settings. */
-       else if (reg & PHY_BMCR_100MB) {
-               return (_100BASET);
-       } else {
-               return (_10BASET);
-       }
+       return (bmcr & PHY_BMCR_100MB) ? _100BASET : _10BASET;
 
+      miiphy_read_failed:
+       printf (" read failed, assuming 10BASE-T\n");
+       return _10BASET;
 }
 
-
 /*****************************************************************************
  *
- * Determine full/half duplex.
+ * Determine full/half duplex.  Return half on error.
  */
 int miiphy_duplex (char *devname, unsigned char addr)
 {
-       unsigned short reg;
+       u16 bmcr, anlpar;
 
 #if defined(CONFIG_PHY_GIGE)
-       if (miiphy_read (devname, addr, PHY_1000BTSR, &reg)) {
-               printf ("PHY 1000BT Status read failed\n");
-       } else {
-               if ( (reg != 0xFFFF) &&
-                    (reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) ) {
-                       if ((reg & PHY_1000BTSR_1000FD) !=0) {
-                               return (FULL);
-                       } else {
-                               return (HALF);
-                       }
+       u16 btsr;
+
+       /* Check for 1000BASE-X. */
+       if (miiphy_is_1000base_x (devname, addr)) {
+               /* 1000BASE-X */
+               if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
+                       printf ("1000BASE-X PHY AN duplex");
+                       goto miiphy_read_failed;
+               }
+       }
+       /*
+        * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
+        */
+       /* Check for 1000BASE-T. */
+       if (miiphy_read (devname, addr, PHY_1000BTSR, &btsr)) {
+               printf ("PHY 1000BT status");
+               goto miiphy_read_failed;
+       }
+       if (btsr != 0xFFFF) {
+               if (btsr & PHY_1000BTSR_1000FD) {
+                       return FULL;
+               } else if (btsr & PHY_1000BTSR_1000HD) {
+                       return HALF;
                }
        }
 #endif /* CONFIG_PHY_GIGE */
 
        /* Check Basic Management Control Register first. */
-       if (miiphy_read (devname, addr, PHY_BMCR, &reg)) {
-               puts ("PHY duplex read failed, assuming half duplex\n");
-               return (HALF);
+       if (miiphy_read (devname, addr, PHY_BMCR, &bmcr)) {
+               puts ("PHY duplex");
+               goto miiphy_read_failed;
        }
        /* Check if auto-negotiation is on. */
-       if ((reg & PHY_BMCR_AUTON) != 0) {
+       if (bmcr & PHY_BMCR_AUTON) {
                /* Get auto-negotiation results. */
-               if (miiphy_read (devname, addr, PHY_ANLPAR, &reg)) {
-                       puts ("PHY AN duplex read failed, assuming half duplex\n");
-                       return (HALF);
-               }
-
-               if ((reg & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) != 0) {
-                       return (FULL);
-               } else {
-                       return (HALF);
+               if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
+                       puts ("PHY AN duplex");
+                       goto miiphy_read_failed;
                }
+               return (anlpar & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) ?
+                   FULL : HALF;
        }
        /* Get speed from basic control settings. */
-       else if (reg & PHY_BMCR_DPLX) {
-               return (FULL);
-       } else {
-               return (HALF);
-       }
+       return (bmcr & PHY_BMCR_DPLX) ? FULL : HALF;
+
+      miiphy_read_failed:
+       printf (" read failed, assuming half duplex\n");
+       return HALF;
+}
 
+/*****************************************************************************
+ *
+ * Return 1 if PHY supports 1000BASE-X, 0 if PHY supports 10BASE-T/100BASE-TX/
+ * 1000BASE-T, or on error.
+ */
+int miiphy_is_1000base_x (char *devname, unsigned char addr)
+{
+#if defined(CONFIG_PHY_GIGE)
+       u16 exsr;
+
+       if (miiphy_read (devname, addr, PHY_EXSR, &exsr)) {
+               printf ("PHY extended status read failed, assuming no "
+                       "1000BASE-X\n");
+               return 0;
+       }
+       return 0 != (exsr & (PHY_EXSR_1000XF | PHY_EXSR_1000XH));
+#else
+       return 0;
+#endif
 }
 
 #ifdef CFG_FAULT_ECHO_LINK_DOWN
@@ -455,7 +486,7 @@ int miiphy_link (char *devname, unsigned char addr)
        unsigned short reg;
 
        /* dummy read; needed to latch some phys */
-       (void)miiphy_read(devname, addr, PHY_BMSR, &reg);
+       (void)miiphy_read (devname, addr, PHY_BMSR, &reg);
        if (miiphy_read (devname, addr, PHY_BMSR, &reg)) {
                puts ("PHY_BMSR read failed, assuming no link\n");
                return (0);
@@ -469,5 +500,4 @@ int miiphy_link (char *devname, unsigned char addr)
        }
 }
 #endif
-
 #endif /* CONFIG_MII */
index 0fb23b6592069140cdb56a0f09496211cd97a66c..06550b9858cde121928d6b9beab8bffebb176f1c 100644 (file)
@@ -516,7 +516,7 @@ static int Spartan2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
                                (*fn->clk) (FALSE, TRUE, cookie);
                                CONFIG_FPGA_DELAY ();
                                /* Write data */
-                               (*fn->wr) ((val 0), TRUE, cookie);
+                               (*fn->wr) ((val & 0x80), TRUE, cookie);
                                CONFIG_FPGA_DELAY ();
                                /* Assert the clock */
                                (*fn->clk) (TRUE, TRUE, cookie);
index c0f2b05e480db356d097f1689e59be4df6bd0281..f7c4f8cf2b24aa9e70110d68440198449d8c01b8 100644 (file)
@@ -521,7 +521,7 @@ static int Spartan3_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
                                (*fn->clk) (FALSE, TRUE, cookie);
                                CONFIG_FPGA_DELAY ();
                                /* Write data */
-                               (*fn->wr) ((val 0), TRUE, cookie);
+                               (*fn->wr) ((val & 0x80), TRUE, cookie);
                                CONFIG_FPGA_DELAY ();
                                /* Assert the clock */
                                (*fn->clk) (TRUE, TRUE, cookie);
index aec558ad203b34a9a2a04a6091ab7b717aa4703f..7bdfcc0b903418018fefae26c40249f755fa9edb 100644 (file)
@@ -257,7 +257,7 @@ static int usb_kbd_translate(unsigned char scancode,unsigned char modifier,int p
                repeat_delay=REPEAT_DELAY;
        }
        keycode=0;
-       if((scancode>3) && (scancode<0x1d)) { /* alpha numeric values */
+       if((scancode>3) && (scancode<=0x1d)) { /* alpha numeric values */
                keycode=scancode-4 + 0x61;
                if(caps_lock)
                        keycode&=~CAPITAL_MASK; /* switch to capital Letters */
index 0f79f367c90b213bf1187cc1c43b278e6197353c..443d78574abcef38671e7453f001b490ac62c56b 100644 (file)
@@ -1195,7 +1195,7 @@ int usb_stor_get_info(struct usb_device *dev,struct us_data *ss,block_dev_desc_t
        dev_desc->product[16] = 0;
        dev_desc->revision[4] = 0;
 #ifdef CONFIG_USB_BIN_FIXUP
-       usb_bin_fixup(dev->descriptor, dev_desc->vendor, dev_desc->product);
+       usb_bin_fixup(dev->descriptor, (uchar *)dev_desc->vendor, (uchar *)dev_desc->product);
 #endif /* CONFIG_USB_BIN_FIXUP */
        USB_STOR_PRINTF("ISO Vers %X, Response Data %X\n",usb_stor_buf[2],usb_stor_buf[3]);
        if(usb_test_unit_ready(pccb,ss)) {
index 582df329a47b4e85bbbd2ae909c01d11cf71223d..79e5a31b72a6599f027eb0b45df9f95e526b563b 100644 (file)
--- a/config.mk
+++ b/config.mk
@@ -69,10 +69,6 @@ PLATFORM_CPPFLAGS+= -D__ARM__
 endif
 endif
 
-ifeq ($(ARCH),blackfin)
-PLATFORM_CPPFLAGS+= -D__BLACKFIN__
-endif
-
 ifdef  ARCH
 sinclude $(TOPDIR)/$(ARCH)_config.mk   # include architecture dependend rules
 endif
@@ -91,6 +87,9 @@ ifdef BOARD
 sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk # include board specific rules
 endif
 
+# Load generated board configuration
+sinclude $(OBJTREE)/include/autoconf.mk
+
 #########################################################################
 
 CONFIG_SHELL   := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
index 0ff36c596a36d0baf603d0b7172177631ac7a6df..1ed9bf307cb66a27e914e7eb02cc183e49a1039b 100644 (file)
@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
 LIB    = $(obj)lib$(SOC).a
 
 COBJS  = i2c.o interrupts.o serial.o speed.o \
-         usb.o
+         usb.o usb_ohci.o
 
 SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
index 869ca79d032dcbf97e6561836306d483662d0f2e..4075f2e1834967d0bb2033fa7446a64ffbeceaeb 100644 (file)
@@ -498,7 +498,7 @@ static int ep_link (ohci_t *ohci, ed_t *edi)
                if (ohci->ed_controltail == NULL) {
                        writel (ed, &ohci->regs->ed_controlhead);
                } else {
-                       ohci->ed_controltail->hwNextED = m32_swap (ed);
+                       ohci->ed_controltail->hwNextED = (__u32)m32_swap (ed);
                }
                ed->ed_prev = ohci->ed_controltail;
                if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&
@@ -514,7 +514,7 @@ static int ep_link (ohci_t *ohci, ed_t *edi)
                if (ohci->ed_bulktail == NULL) {
                        writel (ed, &ohci->regs->ed_bulkhead);
                } else {
-                       ohci->ed_bulktail->hwNextED = m32_swap (ed);
+                       ohci->ed_bulktail->hwNextED = (__u32)m32_swap (ed);
                }
                ed->ed_prev = ohci->ed_bulktail;
                if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&
@@ -606,7 +606,7 @@ static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe)
                ed->hwINFO = m32_swap (OHCI_ED_SKIP); /* skip ed */
                /* dummy td; end of td list for ed */
                td = td_alloc (usb_dev);
-               ed->hwTailP = m32_swap (td);
+               ed->hwTailP = (__u32)m32_swap (td);
                ed->hwHeadP = ed->hwTailP;
                ed->state = ED_UNLINK;
                ed->type = usb_pipetype (pipe);
@@ -663,13 +663,13 @@ static void td_fill (ohci_t *ohci, unsigned int info,
        if (!len)
                data = 0;
 
-       td->hwINFO = m32_swap (info);
-       td->hwCBP = m32_swap (data);
+       td->hwINFO = (__u32)m32_swap (info);
+       td->hwCBP = (__u32)m32_swap (data);
        if (data)
-               td->hwBE = m32_swap (data + len - 1);
+               td->hwBE = (__u32)m32_swap (data + len - 1);
        else
                td->hwBE = 0;
-       td->hwNextTD = m32_swap (td_pt);
+       td->hwNextTD = (__u32)m32_swap (td_pt);
 
        /* append to queue */
        td->ed->hwTailP = td->hwNextTD;
index ba324a894a5e7a4df4d1fc521038818c253c7e7a..93645a31e0a086c4c12d6d2d9ec8cd4b93f12f50 100644 (file)
@@ -24,4 +24,8 @@
 #
 
 PLATFORM_RELFLAGS += -ffixed-d7 -msep-data
+ifeq ($(findstring 4.2,$(shell $(CC) --version)),4.2)
+PLATFORM_CPPFLAGS += -mcpu=5235 -fPIC
+else
 PLATFORM_CPPFLAGS += -m5307 -fPIC
+endif
index 650db8583150ac108f6411496ae175050d0558fa..f97157d041eee31fab996511348e3272f2c138bc 100644 (file)
 #
 
 PLATFORM_RELFLAGS += -ffixed-d7 -msep-data
+
+cfg=$(shell grep configs $(OBJTREE)/include/config.h | sed 's/.*<\(configs.*\)>/\1/')
+is5249=$(shell grep CONFIG_M5249 $(TOPDIR)/include/$(cfg))
+is5253=$(shell grep CONFIG_M5253 $(TOPDIR)/include/$(cfg))
+is5271=$(shell grep CONFIG_M5271 $(TOPDIR)/include/$(cfg))
+is5272=$(shell grep CONFIG_M5272 $(TOPDIR)/include/$(cfg))
+is5282=$(shell grep CONFIG_M5282 $(TOPDIR)/include/$(cfg))
+
+
+ifeq ($(findstring 4.2,$(shell $(CC) --version)),4.2)
+
+ifneq (,$(findstring CONFIG_M5249,$(is5249)))
+PLATFORM_CPPFLAGS += -mcpu=5249
+endif
+ifneq (,$(findstring CONFIG_M5253,$(is5253)))
+PLATFORM_CPPFLAGS += -mcpu=5253
+endif
+ifneq (,$(findstring CONFIG_M5271,$(is5271)))
+PLATFORM_CPPFLAGS += -mcpu=5271
+endif
+ifneq (,$(findstring CONFIG_M5272,$(is5272)))
+PLATFORM_CPPFLAGS += -mcpu=5272
+endif
+ifneq (,$(findstring CONFIG_M5282,$(is5282)))
+PLATFORM_CPPFLAGS += -mcpu=5282
+endif
+
+else
 PLATFORM_CPPFLAGS += -m5307
+endif
index 686e2a533302af0e69feae9603c7d835625f4932..260a09abf76ffdcdd1c1a8ff4451993f9b9556bc 100644 (file)
@@ -58,7 +58,7 @@ _vectors:
 .long  0x00000000              /* Flash offset is 0 until we setup CS0 */
 #if defined(CONFIG_R5200)
 .long  0x400
-#elif defined(CONFIG_M5282)
+#elif defined(CONFIG_M5282) && (TEXT_BASE == CFG_INT_FLASH_BASE)
 .long  _start - TEXT_BASE
 #else
 .long  _START
@@ -177,7 +177,11 @@ _after_flashbar_copy:
         * therefore no VBR to set
         */
 #if !defined(CONFIG_MONITOR_IS_IN_RAM)
+#if defined(CONFIG_M5282) && (TEXT_BASE == CFG_INT_FLASH_BASE)
+       move.l  #CFG_INT_FLASH_BASE, %d0
+#else
        move.l  #CFG_FLASH_BASE, %d0
+#endif
        movec   %d0, %VBR
 #endif
 
index ba324a894a5e7a4df4d1fc521038818c253c7e7a..16a0bc3264b1031b394d0180fd5dac5c6a08b269 100644 (file)
@@ -24,4 +24,8 @@
 #
 
 PLATFORM_RELFLAGS += -ffixed-d7 -msep-data
+ifeq ($(findstring 4.2,$(shell $(CC) --version)),4.2)
+PLATFORM_CPPFLAGS += -mcpu=5329 -fPIC
+else
 PLATFORM_CPPFLAGS += -m5307 -fPIC
+endif
index 2f62e956ccafe0295aecc30ad476b7c4fe6ec59b..89cc8ad93070f56349484eddb9ee91efcf0a734d 100644 (file)
@@ -35,14 +35,10 @@ DECLARE_GLOBAL_DATA_PTR;
 
 int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
 {
-       volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG);
+       volatile rcm_t *rcm = (rcm_t *) (MMAP_RCM);
 
-       wdp->cr = 0;
        udelay(1000);
-
-       /* enable watchdog, set timeout to 0 and wait */
-       wdp->cr = WTM_WCR_EN;
-       while (1) ;
+       rcm->rcr |= RCM_RCR_SOFTRST;
 
        /* we don't return! */
        return 0;
index 5cc1c87cdd0bd5e6e9dbef41c3e31b9cffc3356c..61be2eac695b122d81782849e198bc8fc8cd1d37 100644 (file)
@@ -131,7 +131,7 @@ _start:
        movec   %d0, %VBR
 
        move.l  #(CFG_INIT_RAM_ADDR + CFG_INIT_RAM_CTRL), %d0
-       movec   %d0, %RAMBAR0
+       movec   %d0, %RAMBAR1
 
        /* invalidate and disable cache */
        move.l  #0x01000000, %d0                /* Invalidate cache cmd */
@@ -268,7 +268,7 @@ _int_handler:
 icache_enable:
        move.l  #0x01000000, %d0                /* Invalidate cache cmd */
        movec   %d0, %CACR                      /* Invalidate cache */
-       move.l  #(CFG_SDRAM_BASE + 0xc000 + ((CFG_SDRAM_SIZE & 0x1fe0) << 11)), %d0
+       move.l  #(CFG_SDRAM_BASE + 0x1c000), %d0
        movec   %d0, %ACR0                      /* Enable cache */
 
        move.l  #0x80000200, %d0                /* Setup cache mask */
index d0c72fb6b0e88a0bd2f45f3b92f5f254e0a9d684..88433f2f6d6e04494d46b662e528ea5a1547a049 100644 (file)
@@ -24,4 +24,8 @@
 #
 
 PLATFORM_RELFLAGS += -ffixed-d7 -msep-data
+ifeq ($(findstring 4.2,$(shell $(CC) --version)),4.2)
+PLATFORM_CPPFLAGS += -mcpu=54455 -fPIC
+else
 PLATFORM_CPPFLAGS += -m5407 -fPIC
+endif
index cd989ab6261460b4df95a3da7b2e7ef535baba46..423583d04adbf30c54d2b306265abc4cd0be8928 100644 (file)
@@ -136,7 +136,7 @@ _start:
        movec   %d0, %VBR
 
        move.l  #(CFG_INIT_RAM_ADDR + CFG_INIT_RAM_CTRL), %d0
-       movec   %d0, %RAMBAR0
+       movec   %d0, %RAMBAR1
 
        /* initialize general use internal ram */
        move.l #0, %d0
index b69741ae6833f9b40fabf06e26d56b54ee272497..d70c5fe9875cf4984e76876790a40aa26c541798 100644 (file)
@@ -90,6 +90,65 @@ mac_fifo_t mac_fifo[NO_OF_FIFOS];
 
 #define MAX_WAIT 1000
 
+#if defined(CONFIG_CMD_MII)
+int  au1x00_miiphy_read(char *devname, unsigned char addr,
+               unsigned char reg, unsigned short * value)
+{
+       volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL);
+       volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA);
+       u32 mii_control;
+       unsigned int timedout = 20;
+
+       while (*mii_control_reg & MAC_MII_BUSY) {
+               udelay(1000);
+               if (--timedout == 0) {
+                       printf("au1x00_eth: miiphy_read busy timeout!!\n");
+                       return -1;
+               }
+       }
+
+       mii_control = MAC_SET_MII_SELECT_REG(reg) |
+               MAC_SET_MII_SELECT_PHY(addr) | MAC_MII_READ;
+
+       *mii_control_reg = mii_control;
+
+       timedout = 20;
+       while (*mii_control_reg & MAC_MII_BUSY) {
+               udelay(1000);
+               if (--timedout == 0) {
+                       printf("au1x00_eth: miiphy_read busy timeout!!\n");
+                       return -1;
+               }
+       }
+       *value = *mii_data_reg;
+       return 0;
+}
+
+int  au1x00_miiphy_write(char *devname, unsigned char addr,
+               unsigned char reg, unsigned short value)
+{
+       volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL);
+       volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA);
+       u32 mii_control;
+       unsigned int timedout = 20;
+
+       while (*mii_control_reg & MAC_MII_BUSY) {
+               udelay(1000);
+               if (--timedout == 0) {
+                       printf("au1x00_eth: miiphy_write busy timeout!!\n");
+                       return -1;
+               }
+       }
+
+       mii_control = MAC_SET_MII_SELECT_REG(reg) |
+               MAC_SET_MII_SELECT_PHY(addr) | MAC_MII_WRITE;
+
+       *mii_data_reg = value;
+       *mii_control_reg = mii_control;
+       return 0;
+}
+#endif
+
 static int au1x00_send(struct eth_device* dev, volatile void *packet, int length){
        volatile mac_fifo_t *fifo_tx =
                (volatile mac_fifo_t*)(MAC0_TX_DMA_ADDR+MAC_TX_BUFF0_STATUS);
@@ -249,63 +308,4 @@ int au1x00_enet_initialize(bd_t *bis){
        return 1;
 }
 
-#if defined(CONFIG_CMD_MII)
-int  au1x00_miiphy_read(char *devname, unsigned char addr,
-               unsigned char reg, unsigned short * value)
-{
-       volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL);
-       volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA);
-       u32 mii_control;
-       unsigned int timedout = 20;
-
-       while (*mii_control_reg & MAC_MII_BUSY) {
-               udelay(1000);
-               if (--timedout == 0) {
-                       printf("au1x00_eth: miiphy_read busy timeout!!\n");
-                       return -1;
-               }
-       }
-
-       mii_control = MAC_SET_MII_SELECT_REG(reg) |
-               MAC_SET_MII_SELECT_PHY(addr) | MAC_MII_READ;
-
-       *mii_control_reg = mii_control;
-
-       timedout = 20;
-       while (*mii_control_reg & MAC_MII_BUSY) {
-               udelay(1000);
-               if (--timedout == 0) {
-                       printf("au1x00_eth: miiphy_read busy timeout!!\n");
-                       return -1;
-               }
-       }
-       *value = *mii_data_reg;
-       return 0;
-}
-
-int  au1x00_miiphy_write(char *devname, unsigned char addr,
-               unsigned char reg, unsigned short value)
-{
-       volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL);
-       volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA);
-       u32 mii_control;
-       unsigned int timedout = 20;
-
-       while (*mii_control_reg & MAC_MII_BUSY) {
-               udelay(1000);
-               if (--timedout == 0) {
-                       printf("au1x00_eth: miiphy_write busy timeout!!\n");
-                       return;
-               }
-       }
-
-       mii_control = MAC_SET_MII_SELECT_REG(reg) |
-               MAC_SET_MII_SELECT_PHY(addr) | MAC_MII_WRITE;
-
-       *mii_data_reg = value;
-       *mii_control_reg = mii_control;
-       return 0;
-}
-#endif
-
 #endif /* CONFIG_AU1X00 */
index aad76e0afb8316bd262189616a5215b470c6bc47..443240e540b897937eb165c83fa945bee593f971 100644 (file)
@@ -22,7 +22,6 @@
  * MA 02111-1307 USA
  */
 
-
 #include <config.h>
 #include <version.h>
 #include <asm/regdef.h>
 #include <asm/addrspace.h>
 #include <asm/cacheops.h>
 
-
        /* 16KB is the maximum size of instruction and data caches on
         * MIPS 4K.
         */
 #define MIPS_MAX_CACHE_SIZE    0x4000
 
-
 /*
  * cacheop macro to automate cache operations
  * first some helpers...
@@ -131,7 +128,6 @@ mips_cache_reset:
        li      t4, CFG_CACHELINE_SIZE
        move    t5, t4
 
-
        li      v0, MIPS_MAX_CACHE_SIZE
 
        /* Now clear that much memory starting from zero.
@@ -139,8 +135,8 @@ mips_cache_reset:
 
        li      a0, KSEG1
        addu    a1, a0, v0
-
-2:     sw      zero, 0(a0)
+2:
+       sw      zero, 0(a0)
        sw      zero, 4(a0)
        sw      zero, 8(a0)
        sw      zero, 12(a0)
@@ -156,11 +152,11 @@ mips_cache_reset:
 
        mtc0    zero, CP0_TAGLO
 
-   /*
-    * The caches are probably in an indeterminate state,
-    * so we force good parity into them by doing an
-    * invalidate, load/fill, invalidate for each line.
-    */
+       /*
+        * The caches are probably in an indeterminate state,
+        * so we force good parity into them by doing an
+        * invalidate, load/fill, invalidate for each line.
+        */
 
        /* Assume bottom of RAM will generate good parity for the cache.
         */
@@ -201,9 +197,9 @@ mips_cache_reset:
        move    a1, a2
        icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
 
-       j  ra
-       .end  mips_cache_reset
+       j       ra
 
+       .end    mips_cache_reset
 
 /*******************************************************************************
 *
@@ -220,7 +216,7 @@ dcache_status:
        andi    v0, v0, 1
        j       ra
 
-       .end  dcache_status
+       .end    dcache_status
 
 /*******************************************************************************
 *
@@ -237,11 +233,10 @@ dcache_disable:
        li      t1, -8
        and     t0, t0, t1
        ori     t0, t0, CONF_CM_UNCACHED
-       mtc0    t0, CP0_CONFIG
+       mtc0    t0, CP0_CONFIG
        j       ra
 
-       .end  dcache_disable
-
+       .end    dcache_disable
 
 /*******************************************************************************
 *
@@ -266,4 +261,5 @@ mips_cache_lock:
        icacheop(a0,a1,a2,a3,0x1d)
 
        j       ra
+
        .end    mips_cache_lock
index b29986e26b7bac08bb20653a0ac7fc8a2a58577f..ad03bd61ba5dbcbad2b154f39fb8efe4a7a4b9cb 100644 (file)
@@ -20,8 +20,7 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 # MA 02111-1307 USA
 #
-v=$(shell \
-$(CROSS_COMPILE)as --version|grep "GNU assembler"|awk '{print $$3}'|awk -F . '{print $$2}')
+v=$(shell $(AS) --version |grep "GNU assembler" |cut -d. -f2)
 MIPSFLAGS=$(shell \
 if [ "$v" -lt "14" ]; then \
        echo "-mcpu=4kc"; \
@@ -35,6 +34,6 @@ else
 ENDIANNESS = -EB
 endif
 
-MIPSFLAGS += $(ENDIANNESS) -mabicalls
+MIPSFLAGS += $(ENDIANNESS)
 
 PLATFORM_CPPFLAGS += $(MIPSFLAGS)
index f48675e9967da799ce3303a983bbf142592ecaa2..7559ac657f40384dded344006b8a7076e5b68c0e 100644 (file)
@@ -39,12 +39,12 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        return 0;
 }
 
-void flush_cache (ulong start_addr, ulong size)
+void flush_cache(ulong start_addr, ulong size)
 {
-
 }
 
-void write_one_tlb( int index, u32 pagemask, u32 hi, u32 low0, u32 low1 ){
+void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1)
+{
        write_32bit_cp0_register(CP0_ENTRYLO0, low0);
        write_32bit_cp0_register(CP0_PAGEMASK, pagemask);
        write_32bit_cp0_register(CP0_ENTRYLO1, low1);
index e91e2137d704f7eb8c0fe7ab6b1907673c1f2716..c92b16278267200d208cc649fa1d7722628d92da 100644 (file)
  * MA 02111-1307 USA
  */
 
-
 #include <config.h>
 #include <version.h>
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
 
-
 #define RVECENT(f,n) \
    b f; nop
 #define XVECENT(f,bev) \
@@ -192,7 +190,7 @@ _start:
        .word   0x00000000
        .word   0x03e00008
        .word   0x00000000
-       .word   0x00000000
+       .word   0x00000000
 /* 0xbfc00428 */
        .word   0xdc870000
        .word   0xfca70000
@@ -203,7 +201,7 @@ _start:
        .word   0x00000000
        .word   0x03e00008
        .word   0x00000000
-       .word   0x00000000
+       .word   0x00000000
 #endif /* CONFIG_PURPLE */
        .align 4
 reset:
@@ -234,34 +232,32 @@ reset:
        li      t0, CONF_CM_UNCACHED
        mtc0    t0, CP0_CONFIG
 
-       /* Initialize GOT pointer.
-       */
-       bal     1f
+       /* Initialize $gp.
+        */
+       bal     1f
        nop
-       .word   _GLOBAL_OFFSET_TABLE_
-       1:
-       move    gp, ra
-       lw      t1, 0(ra)
-       move    gp, t1
+       .word   _gp
+1:
+       lw      gp, 0(ra)
 
 #ifdef CONFIG_INCA_IP
        /* Disable INCA-IP Watchdog.
         */
-       la      t9, disable_incaip_wdt
-       jalr    t9
+       la      t9, disable_incaip_wdt
+       jalr    t9
        nop
 #endif
 
        /* Initialize any external memory.
         */
-       la      t9, lowlevel_init
-       jalr    t9
+       la      t9, lowlevel_init
+       jalr    t9
        nop
 
        /* Initialize caches...
         */
-       la      t9, mips_cache_reset
-       jalr    t9
+       la      t9, mips_cache_reset
+       jalr    t9
        nop
 
        /* ... and enable them.
@@ -269,12 +265,11 @@ reset:
        li      t0, CONF_CM_CACHABLE_NONCOHERENT
        mtc0    t0, CP0_CONFIG
 
-
        /* Set up temporary stack.
         */
        li      a0, CFG_INIT_SP_OFFSET
-       la      t9, mips_cache_lock
-       jalr    t9
+       la      t9, mips_cache_lock
+       jalr    t9
        nop
 
        li      t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET
@@ -284,7 +279,6 @@ reset:
        j       t9
        nop
 
-
 /*
  * void relocate_code (addr_sp, gd, addr_moni)
  *
@@ -298,7 +292,7 @@ reset:
        .globl  relocate_code
        .ent    relocate_code
 relocate_code:
-       move    sp, a0          /* Set new stack pointer                */
+       move    sp, a0          /* Set new stack pointer        */
 
        li      t0, CFG_MONITOR_BASE
        la      t3, in_ram
@@ -306,14 +300,14 @@ relocate_code:
        move    t1, a2
 
        /*
-        * Fix GOT pointer:
+        * Fix $gp:
         *
-        * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
+        * New $gp = (Old $gp - CFG_MONITOR_BASE) + Destination Address
         */
        move    t6, gp
        sub     gp, CFG_MONITOR_BASE
-       add     gp, a2                  /* gp now adjusted              */
-       sub     t6, gp, t6              /* t6 <-- relocation offset     */
+       add     gp, a2          /* gp now adjusted              */
+       sub     t6, gp, t6      /* t6 <-- relocation offset     */
 
        /*
         * t0 = source address
@@ -329,7 +323,7 @@ relocate_code:
        sw      t3, 0(t1)
        addu    t0, 4
        ble     t0, t2, 1b
-       addu    t1, 4                   /* delay slot                   */
+       addu    t1, 4           /* delay slot                   */
 #endif
 
        /* If caches were enabled, we would have to flush them here.
@@ -341,15 +335,22 @@ relocate_code:
        j       t0
        nop
 
+       .gpword _GLOBAL_OFFSET_TABLE_   /* _GLOBAL_OFFSET_TABLE_ - _gp  */
        .word   uboot_end_data
        .word   uboot_end
        .word   num_got_entries
 
 in_ram:
-       /* Now we want to update GOT.
+       /*
+        * Now we want to update GOT.
+        *
+        * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
+        * generated by GNU ld. Skip these reserved entries from relocation.
         */
        lw      t3, -4(t0)      /* t3 <-- num_got_entries       */
-       addi    t4, gp, 8       /* Skipping first two entries.  */
+       lw      t4, -16(t0)     /* t4 <-- (_GLOBAL_OFFSET_TABLE_ - _gp) */
+       add     t4, t4, gp      /* t4 now holds _GLOBAL_OFFSET_TABLE_   */
+       addi    t4, t4, 8       /* Skipping first two entries.  */
        li      t2, 2
 1:
        lw      t1, 0(t4)
@@ -369,7 +370,8 @@ in_ram:
        add     t2, t6
 
        sub     t1, 4
-1:     addi    t1, 4
+1:
+       addi    t1, 4
        bltl    t1, t2, 1b
        sw      zero, 0(t1)     /* delay slot                   */
 
@@ -380,11 +382,10 @@ in_ram:
 
        .end    relocate_code
 
-
        /* Exception handlers.
         */
 romReserved:
-       b romReserved
+       b       romReserved
 
 romExcHandle:
-       b romExcHandle
+       b       romExcHandle
index 3259d53a13f83c3666ba6cd1b26cfa289df2040b..8a07c5a3b679cc4c0308c32de290ab70eb4d661a 100644 (file)
@@ -19,7 +19,7 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 # MA 02111-1307 USA
 #
-PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi -mrelocatable
+PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
 
 PLATFORM_CPPFLAGS += -DCONFIG_MPC512X -DCONFIG_E300 \
                        -ffixed-r2 -ffixed-r29 -msoft-float -mcpu=603e
index e95b8a1a85514a062eb127b43aed697d56334ecc..64cd60071ad4085ab2ae1b583545ce51bccb68f1 100644 (file)
@@ -28,7 +28,7 @@
 #
 
 
-PLATFORM_RELFLAGS +=   -fPIC -ffixed-r14 -meabi -mrelocatable
+PLATFORM_RELFLAGS +=   -fPIC -ffixed-r14 -meabi
 
 PLATFORM_CPPFLAGS +=   -DCONFIG_5xx -ffixed-r2 -ffixed-r29 -mpowerpc -msoft-float
 
index 10001b1c1decabc2b05db808fdfef65cf6ee6e68..5b03fef66c77ddac1bbbe0c032a0525b5752953b 100644 (file)
@@ -59,6 +59,7 @@ SECTIONS
     cpu/mpc5xx/start.o (.text)
 
     *(.text)
+    *(.fixup)
     *(.got1)
   }
   _etext = .;
index 0e861c4a0f8280679d9b96070279304378a11183..0df51babd70b558cb1649bd8031a202e003e3b49 100644 (file)
@@ -21,7 +21,7 @@
 # MA 02111-1307 USA
 #
 
-PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi -mrelocatable
+PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
 
 PLATFORM_CPPFLAGS += -DCONFIG_MPC5xxx -ffixed-r2 -ffixed-r29 \
                     -mstring -mcpu=603e -mmultiple
index 7f16b92a6cac06af26f00a9a267f7bd6c371323a..e4d6168224825ae9ba9c09d864e1348ad05397bc 100644 (file)
@@ -35,6 +35,7 @@
 #if defined(CONFIG_OF_LIBFDT)
 #include <libfdt.h>
 #include <libfdt_env.h>
+#include <fdt_support.h>
 #endif
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -114,42 +115,19 @@ unsigned long get_tbclk (void)
 /* ------------------------------------------------------------------------- */
 
 #ifdef CONFIG_OF_LIBFDT
-static void do_fixup(void *fdt, const char *node, const char *prop,
-                    const void *val, int len, int create)
-{
-#if defined(DEBUG)
-       int i;
-       debug("Updating property '%s/%s' = ", node, prop);
-       for (i = 0; i < len; i++)
-               debug(" %.2x", *(u8*)(val+i));
-       debug("\n");
-#endif
-       int rc = fdt_find_and_setprop(fdt, node, prop, val, len, create);
-       if (rc)
-               printf("Unable to update property %s:%s, err=%s\n",
-                      node, prop, fdt_strerror(rc));
-}
-
-static void do_fixup_u32(void *fdt, const char *node, const char *prop,
-                        u32 val, int create)
-{
-       val = cpu_to_fdt32(val);
-       do_fixup(fdt, node, prop, &val, sizeof(val), create);
-}
-
 void ft_cpu_setup(void *blob, bd_t *bd)
 {
        int div = in_8((void*)CFG_MBAR + 0x204) & 0x0020 ? 8 : 4;
        char * cpu_path = "/cpus/" OF_CPU;
        char * eth_path = "/" OF_SOC "/ethernet@3000";
 
-       do_fixup_u32(blob, cpu_path, "timebase-frequency", OF_TBCLK, 1);
-       do_fixup_u32(blob, cpu_path, "bus-frequency", bd->bi_busfreq, 1);
-       do_fixup_u32(blob, cpu_path, "clock-frequency", bd->bi_intfreq, 1);
-       do_fixup_u32(blob, "/" OF_SOC, "bus-frequency", bd->bi_ipbfreq, 1);
-       do_fixup_u32(blob, "/" OF_SOC, "system-frequency",
-                       bd->bi_busfreq*div, 1);
-       do_fixup(blob, eth_path, "mac-address", bd->bi_enetaddr, 6, 0);
-       do_fixup(blob, eth_path, "local-mac-address", bd->bi_enetaddr, 6, 0);
+       do_fixup_by_path_u32(blob, cpu_path, "timebase-frequency", OF_TBCLK, 1);
+       do_fixup_by_path_u32(blob, cpu_path, "bus-frequency", bd->bi_busfreq, 1);
+       do_fixup_by_path_u32(blob, cpu_path, "clock-frequency", bd->bi_intfreq, 1);
+       do_fixup_by_path_u32(blob, "/" OF_SOC, "bus-frequency", bd->bi_ipbfreq, 1);
+       do_fixup_by_path_u32(blob, "/" OF_SOC, "system-frequency",
+                               bd->bi_busfreq*div, 1);
+       do_fixup_by_path(blob, eth_path, "mac-address", bd->bi_enetaddr, 6, 0);
+       do_fixup_by_path(blob, eth_path, "local-mac-address", bd->bi_enetaddr, 6, 0);
 }
 #endif
index 11079430d57b9bb74edeb3538876b914035f003a..123a14c5aa01dc9c01b5312f3531270b669e44ef 100644 (file)
@@ -66,6 +66,7 @@ SECTIONS
     common/environment.o        (.ppcenv)
 
     *(.text)
+    *(.fixup)
     *(.got1)
     . = ALIGN(16);
     *(.rodata)
index a28a3afc71c000019bff183187ff0fe80c1db135..78818a49ebd753254f09a3b6bc800294267bb44f 100644 (file)
@@ -55,6 +55,7 @@ SECTIONS
   {
     cpu/mpc5xxx/start.o        (.text)
     *(.text)
+    *(.fixup)
     *(.got1)
     . = ALIGN(16);
     *(.rodata)
index c41cafe97fef6c17dda4a48f10500ead4253ec9b..8e3ba54287cbab5b70975f8bba9f847277e91013 100644 (file)
@@ -21,7 +21,7 @@
 # MA 02111-1307 USA
 #
 
-PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi -mrelocatable
+PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
 
 PLATFORM_CPPFLAGS += -DCONFIG_MPC8220 -ffixed-r2 -ffixed-r29 \
                     -mstring -mcpu=603e -mmultiple
index a199a64f13183f7db36c41c8baed028debec45b6..889bc77d2f820d3af5cb055013a307d0416a850e 100644 (file)
@@ -55,6 +55,7 @@ SECTIONS
   {
     cpu/mpc8220/start.o        (.text)
     *(.text)
+    *(.fixup)
     *(.got1)
     . = ALIGN(16);
     *(.rodata)
index 17fdb21d35a170b2c98472a507a2a7b6380e0472..66207f4354dfac4b59089ff895f5b2bfc1248d4e 100644 (file)
@@ -21,7 +21,7 @@
 # MA 02111-1307 USA
 #
 
-PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi -fno-strict-aliasing -mrelocatable
+PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi -fno-strict-aliasing
 
 PLATFORM_CPPFLAGS += -DCONFIG_MPC824X -ffixed-r2 -ffixed-r29 -mstring -mcpu=603e -msoft-float
 
index acb8947e0d8a9c6acbd69c62113c8834181f9537..4359ecc05e97e6c90c8463b74de316956338c4a3 100644 (file)
@@ -86,7 +86,7 @@ void irq_free_handler (int vec)
  vga?
  */
 
-void timer_interrupt_cpu (struct pt_regs *regs, ulong timestamp)
+void timer_interrupt_cpu (struct pt_regs *regs)
 {
        /* nothing to do here */
        return;
index 8cbef4aed43805f406743d79d7d7f7f5bb50f2db..c90d1e9457e80a065bb77208cf022a7b456ca958 100644 (file)
@@ -55,6 +55,7 @@ SECTIONS
   {
     cpu/mpc824x/start.o                (.text)
     *(.text)
+    *(.fixup)
     *(.got1)
     . = ALIGN(16);
     *(.rodata)
index d401e4ca04f9e43e3f6e915bd8fc13d7ef75c713..683b6fbf2b2f16f194d8073a2d2248b63829d361 100644 (file)
@@ -21,7 +21,7 @@
 # MA 02111-1307 USA
 #
 
-PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi -mrelocatable
+PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
 
 PLATFORM_CPPFLAGS += -DCONFIG_8260 -DCONFIG_CPM2 -ffixed-r2 -ffixed-r29 \
                     -mstring -mcpu=603e -mmultiple
index 94651dc4a69846731d2e8bae49645e5b2eb63c95..55e61a1887586ab0e76048e3d749d32a5078c85d 100644 (file)
 #include <asm/processor.h>
 #include <asm/cpm_8260.h>
 
+#if defined(CONFIG_OF_LIBFDT)
+#include <libfdt.h>
+#include <libfdt_env.h>
+#include <fdt_support.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #if defined(CONFIG_GET_CPU_STR_F)
@@ -294,3 +300,13 @@ void watchdog_reset (void)
 #endif /* CONFIG_WATCHDOG */
 
 /* ------------------------------------------------------------------------- */
+#if defined(CONFIG_OF_LIBFDT)
+void ft_cpu_setup (void *blob, bd_t *bd)
+{
+       char * cpu_path = "/cpus/" OF_CPU;
+
+       do_fixup_by_path_u32(blob, cpu_path, "bus-frequency", bd->bi_busfreq, 1);
+       do_fixup_by_path_u32(blob, cpu_path, "timebase-frequency", OF_TBCLK, 1);
+       do_fixup_by_path_u32(blob, cpu_path, "clock-frequency", bd->bi_intfreq, 1);
+}
+#endif /* CONFIG_OF_LIBFDT */
index b8abc17d413bca83f5123077a9c236f17cfbb6dd..3e84f234d7226a90886777696f215874bc853092 100644 (file)
@@ -55,6 +55,7 @@ SECTIONS
   {
     cpu/mpc8260/start.o                (.text)
     *(.text)
+    *(.fixup)
     *(.got1)
     . = ALIGN(16);
     *(.rodata)
index 2ec395d4ca9d57a7cd59aba67e685e0eea7dde40..ecf8a60bbefa19441fce6396aa65947e5c52fdc1 100644 (file)
@@ -20,7 +20,7 @@
 # MA 02111-1307 USA
 #
 
-PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi -mrelocatable
+PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
 
 PLATFORM_CPPFLAGS += -DCONFIG_MPC83XX -DCONFIG_E300 \
                        -ffixed-r2 -ffixed-r29 -msoft-float
index e634f0a25b25597f89b47cfe96a4f99d83d564c5..b2c35d3007c6dfe360f950c48893a69afe6a9204 100644 (file)
@@ -529,7 +529,7 @@ ft_cpu_setup(void *blob, bd_t *bd)
        int tmp[2];
 
        for (j = 0; j < (sizeof(fixup_props) / sizeof(fixup_props[0])); j++) {
-               nodeoffset = fdt_find_node_by_path(blob, fixup_props[j].node);
+               nodeoffset = fdt_path_offset(blob, fixup_props[j].node);
                if (nodeoffset >= 0) {
                        err = fixup_props[j].set_fn(blob, nodeoffset,
                                                    fixup_props[j].prop, bd);
@@ -544,7 +544,7 @@ ft_cpu_setup(void *blob, bd_t *bd)
        }
 
        /* update, or add and update /memory node */
-       nodeoffset = fdt_find_node_by_path(blob, "/memory");
+       nodeoffset = fdt_path_offset(blob, "/memory");
        if (nodeoffset < 0) {
                nodeoffset = fdt_add_subnode(blob, 0, "memory");
                if (nodeoffset < 0)
index 5675afe9710009ebc571c96a6215afc97b91f80e..0defb0ec89094612d6b66fb9d2843e9ea6749b0e 100644 (file)
@@ -179,7 +179,7 @@ void ft_pci_setup(void *blob, bd_t *bd)
        if (pci_num_buses < 1)
                return;
 
-       nodeoffset = fdt_find_node_by_path(blob, "/" OF_SOC "/pci@8500");
+       nodeoffset = fdt_path_offset(blob, "/" OF_SOC "/pci@8500");
        if (nodeoffset >= 0) {
                tmp[0] = cpu_to_be32(pci_hose[0].first_busno);
                tmp[1] = cpu_to_be32(pci_hose[0].last_busno);
@@ -194,7 +194,7 @@ void ft_pci_setup(void *blob, bd_t *bd)
        if (pci_num_buses < 2)
                return;
 
-       nodeoffset = fdt_find_node_by_path(blob, "/" OF_SOC "/pci@8600");
+       nodeoffset = fdt_path_offset(blob, "/" OF_SOC "/pci@8600");
        if (nodeoffset >= 0) {
                tmp[0] = cpu_to_be32(pci_hose[0].first_busno);
                tmp[1] = cpu_to_be32(pci_hose[0].last_busno);
index ca663bc87bf865f895918b0dcb1d17da0f357222..937c87a27cd3ce375c0ec7696c52b1101a5ea573 100644 (file)
@@ -52,6 +52,7 @@ SECTIONS
   {
     cpu/mpc83xx/start.o        (.text)
     *(.text)
+    *(.fixup)
     *(.got1)
     . = ALIGN(16);
     *(.rodata)
index 08e04685f593efbc4a9ee9abc247356ff3449271..bbc54448daa6951728b02938a22d8195721f1e4d 100644 (file)
@@ -163,7 +163,12 @@ int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
         * Initiate hard reset in debug control register DBCR0
         * Make sure MSR[DE] = 1
         */
-               unsigned long val;
+               unsigned long val, msr;
+
+               msr = mfmsr ();
+               msr |= MSR_DE;
+               mtmsr (msr);
+
                val = mfspr(DBCR0);
                val |= 0x70000000;
                mtspr(DBCR0,val);
index 2c98c2ad8a0cbfa0d9e473fec8daa73d2b950c67..b769ef8a76a4ffa3ee281a6f264c9c7fc449144e 100644 (file)
@@ -218,6 +218,8 @@ _start_e500:
        bdnz    0b
 
        /* Clear and set up some registers. */
+       li      r0,0
+       mtmsr   r0
        li      r0,0x0000
        lis     r1,0xffff
        mtspr   DEC,r0                  /* prevent dec exceptions */
@@ -266,18 +268,17 @@ _start_e500:
         */
        lis     r3,CFG_INIT_RAM_ADDR@h
        ori     r3,r3,CFG_INIT_RAM_ADDR@l
-       li      r2,512 /* 512*32=16K */
+       li      r2,(CFG_DCACHE_SIZE / (2 * CFG_CACHELINE_SIZE))
        mtctr   r2
        li      r0,0
 1:
        dcbz    r0,r3
        dcbtls  0,r0,r3
-       addi    r3,r3,32
+       addi    r3,r3,CFG_CACHELINE_SIZE
        bdnz    1b
 
        /* Jump out the last 4K page and continue to 'normal' start */
 #ifdef CFG_RAMBOOT
-       bl      3f
        b       _start_cont
 #else
        /* Calculate absolute address in FLASH and jump there           */
@@ -286,15 +287,9 @@ _start_e500:
        ori     r3,r3,CFG_MONITOR_BASE@l
        addi    r3,r3,_start_cont - _start + _START_OFFSET
        mtlr    r3
+       blr
 #endif
 
-3:     li      r0,0
-       mtspr   SRR1,r0         /* Keep things disabled for now */
-       mflr    r1
-       mtspr   SRR0,r1
-       rfi
-       isync
-
        .text
        .globl  _start
 _start:
@@ -701,6 +696,7 @@ in8:
        .globl  out8
 out8:
        stb     r4,0x0000(r3)
+       sync
        blr
 
 /*------------------------------------------------------------------------------- */
@@ -710,6 +706,7 @@ out8:
        .globl  out16
 out16:
        sth     r4,0x0000(r3)
+       sync
        blr
 
 /*------------------------------------------------------------------------------- */
@@ -719,6 +716,7 @@ out16:
        .globl  out16r
 out16r:
        sthbrx  r4,r0,r3
+       sync
        blr
 
 /*------------------------------------------------------------------------------- */
@@ -728,6 +726,7 @@ out16r:
        .globl  out32
 out32:
        stw     r4,0x0000(r3)
+       sync
        blr
 
 /*------------------------------------------------------------------------------- */
@@ -737,6 +736,7 @@ out32:
        .globl  out32r
 out32r:
        stwbrx  r4,r0,r3
+       sync
        blr
 
 /*------------------------------------------------------------------------------- */
@@ -1061,11 +1061,11 @@ unlock_ram_in_cache:
        /* invalidate the INIT_RAM section */
        lis     r3,(CFG_INIT_RAM_ADDR & ~31)@h
        ori     r3,r3,(CFG_INIT_RAM_ADDR & ~31)@l
-       li      r4,512
+       li      r4,(CFG_DCACHE_SIZE / (2 * CFG_CACHELINE_SIZE))
        mtctr   r4
 1:     icbi    r0,r3
        dcbi    r0,r3
-       addi    r3,r3,32
+       addi    r3,r3,CFG_CACHELINE_SIZE
        bdnz    1b
        sync                    /* Wait for all icbi to complete on bus */
        isync
index 9456471e84e7468ef7c685f0db017ecd7ec72e54..d83bedd6e0c2aa082016ac7623c6a379f633dde2 100644 (file)
@@ -120,7 +120,7 @@ checkcpu(void)
 static inline void
 soft_restart(unsigned long addr)
 {
-#ifndef CONFIG_MPC8641HPCN
+#if !defined(CONFIG_MPC8641HPCN) && !defined(CONFIG_MPC8610HPCD)
 
        /*
         * SRR0 has system reset vector, SRR1 has default MSR value
@@ -148,7 +148,7 @@ soft_restart(unsigned long addr)
 void
 do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
-#ifndef CONFIG_MPC8641HPCN
+#if !defined(CONFIG_MPC8641HPCN) && !defined(CONFIG_MPC8610HPCD)
 
 #ifdef CFG_RESET_ADDRESS
        ulong addr = CFG_RESET_ADDRESS;
index 059097f5142ae595d51b6cd105b1180c43195c85..265e033fb3dca0c3d30ecfac1bbd6b55c566c20e 100644 (file)
@@ -1114,8 +1114,10 @@ spd_sdram(void)
        int memsize_ddr1 = 0;
        unsigned int law_size_ddr1;
        volatile immap_t *immap = (immap_t *)CFG_IMMR;
-       volatile ccsr_ddr_t *ddr1 = &immap->im_ddr1;
        volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm;
+#ifdef CONFIG_DDR_INTERLEAVE
+       volatile ccsr_ddr_t *ddr1 = &immap->im_ddr1;
+#endif
 
 #if (CONFIG_NUM_DDR_CONTROLLERS > 1)
        int memsize_ddr2_dimm1 = 0;
@@ -1270,10 +1272,12 @@ spd_sdram(void)
                debug("\nDDR: LAWBAR8=0x%08x\n", mcm->lawbar8);
                debug("DDR: LAWAR8=0x%08x\n", mcm->lawar8);
        }
+
+       debug("\nMemory size of DDR2 = 0x%08lx\n", memsize_ddr2);
+
 #endif /* CONFIG_NUM_DDR_CONTROLLERS > 1 */
 
-       debug("\nMemory sizes are DDR1 = 0x%08lx, DDR2 = 0x%08lx\n",
-             memsize_ddr1, memsize_ddr2);
+       debug("\nMemory size of DDR1 = 0x%08lx\n", memsize_ddr1);
 
        /*
         * If neither DDR controller is enabled return 0.
index 23161ca8cbed2b084eb75b64dd12fe238a07c7e4..4f7e8f17dc11984bae3ef17b7102df57c6fba488 100644 (file)
@@ -31,6 +31,9 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/* used in some defintiions of CONFIG_SYS_CLK_FREQ */
+extern unsigned long get_board_sys_clk(unsigned long dummy);
+
 void get_sys_info(sys_info_t *sysInfo)
 {
        volatile immap_t *immap = (immap_t *) CFG_IMMR;
index 722d949473f5a81bc3796bf682306665d48303f9..92dd19f95f22f0b703c343761a1d5ae94600cb8b 100644 (file)
@@ -457,7 +457,7 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
 
 uchar i2c_reg_read (uchar chip, uchar reg)
 {
-       char buf;
+       uchar buf;
 
        PRINTD(("i2c_reg_read(chip=0x%02x, reg=0x%02x)\n",chip,reg));
        i2c_read(chip, reg, 1, &buf, 1);
index 1a929ce6deb3960f4650e81986423f671e869f23..f19d18d89f691c1f297d0871a9b9fb71a222373e 100644 (file)
@@ -27,8 +27,13 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)libdisk.a
 
-COBJS  = part.o part_mac.o part_dos.o part_iso.o part_amiga.o
+COBJS-y += part.o
+COBJS-y += part_mac.o
+COBJS-y += part_dos.o
+COBJS-y += part_iso.o
+COBJS-y += part_amiga.o
 
+COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS))
 
diff --git a/drivers/3c589.c b/drivers/3c589.c
deleted file mode 100644 (file)
index 080b686..0000000
+++ /dev/null
@@ -1,519 +0,0 @@
-/*------------------------------------------------------------------------
- . 3c589.c
- . This is a driver for 3Com's 3C589 (Etherlink III) PCMCIA Ethernet device.
- .
- . (C) Copyright 2002
- . Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- . Rolf Offermanns <rof@sysgo.de>
- .
- . This program is free software; you can redistribute it and/or modify
- . it under the terms of the GNU General Public License as published by
- . the Free Software Foundation; either version 2 of the License, or
- . (at your option) any later version.
- .
- . This program is distributed in the hope that it will be useful,
- . but WITHOUT ANY WARRANTY; without even the implied warranty of
- . MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- . GNU General Public License for more details.
- .
- . You should have received a copy of the GNU General Public License
- . along with this program; if not, write to the Free Software
- . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- .
- ----------------------------------------------------------------------------*/
-
-#include <common.h>
-#include <command.h>
-#include <net.h>
-
-#ifdef CONFIG_DRIVER_3C589
-
-#include "3c589.h"
-
-
-/* Use power-down feature of the chip */
-#define POWER_DOWN     0
-
-#define NO_AUTOPROBE
-
-static const char version[] =
-       "Your ad here! :P\n";
-
-
-#undef EL_DEBUG
-
-typedef unsigned char byte;
-typedef unsigned short word;
-typedef unsigned long int dword;
-/*------------------------------------------------------------------------
- .
- . Configuration options, for the experienced user to change.
- .
- -------------------------------------------------------------------------*/
-
-/*
- . Wait time for memory to be free.  This probably shouldn't be
- . tuned that much, as waiting for this means nothing else happens
- . in the system
-*/
-#define MEMORY_WAIT_TIME 16
-
-
-#if (EL_DEBUG > 2 )
-#define PRINTK3(args...) printf(args)
-#else
-#define PRINTK3(args...)
-#endif
-
-#if EL_DEBUG > 1
-#define PRINTK2(args...) printf(args)
-#else
-#define PRINTK2(args...)
-#endif
-
-#ifdef EL_DEBUG
-#define PRINTK(args...) printf(args)
-#else
-#define PRINTK(args...)
-#endif
-
-#define outb(args...)  mmio_outb(args)
-#define mmio_outb(value, addr) (*((volatile byte *)(addr)) = value)
-
-#define inb(args...)   mmio_inb(args)
-#define mmio_inb(addr) (*((volatile byte *)(addr)))
-
-#define outw(args...)  mmio_outw(args)
-#define mmio_outw(value, addr) (*((volatile word *)(addr)) = value)
-
-#define inw(args...)   mmio_inw(args)
-#define mmio_inw(addr) (*((volatile word *)(addr)))
-
-#define outsw(args...) mmio_outsw(args)
-#define mmio_outsw(r,b,l)      ({      int __i; \
-                                       word *__b2; \
-                                       __b2 = (word *) b; \
-                                       for (__i = 0; __i < l; __i++) { \
-                                           mmio_outw( *(__b2 + __i), r); \
-                                       } \
-                               })
-
-#define insw(args...)  mmio_insw(args)
-#define mmio_insw(r,b,l)       ({      int __i ;  \
-                                       word *__b2;  \
-                                       __b2 = (word *) b;  \
-                                       for (__i = 0; __i < l; __i++) {  \
-                                         *(__b2 + __i) = mmio_inw(r);  \
-                                         mmio_inw(0);  \
-                                       };  \
-                               })
-
-/*------------------------------------------------------------------------
- .
- . The internal workings of the driver.  If you are changing anything
- . here with the 3Com stuff, you should have the datasheet and know
- . what you are doing.
- .
- -------------------------------------------------------------------------*/
-#define EL_BASE_ADDR   0x20000000
-
-
-/* Offsets from base I/O address. */
-#define EL3_DATA       0x00
-#define EL3_TIMER      0x0a
-#define EL3_CMD                0x0e
-#define EL3_STATUS     0x0e
-
-#define EEPROM_READ    0x0080
-
-#define EL3WINDOW(win_num) mmio_outw(SelectWindow + (win_num), EL_BASE_ADDR + EL3_CMD)
-
-/* The top five bits written to EL3_CMD are a command, the lower
-   11 bits are the parameter, if applicable. */
-enum c509cmd {
-    TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11,
-    RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11,
-    TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11,
-    FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11,
-    SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
-    SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11,
-    StatsDisable = 22<<11, StopCoax = 23<<11,
-};
-
-enum c509status {
-    IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
-    TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
-    IntReq = 0x0040, StatsFull = 0x0080, CmdBusy = 0x1000
-};
-
-/* The SetRxFilter command accepts the following classes: */
-enum RxFilter {
-    RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8
-};
-
-/* Register window 1 offsets, the window used in normal operation. */
-#define TX_FIFO                0x00
-#define RX_FIFO                0x00
-#define RX_STATUS      0x08
-#define TX_STATUS      0x0B
-#define TX_FREE                0x0C    /* Remaining free bytes in Tx buffer. */
-
-
-/*
-  Read a word from the EEPROM using the regular EEPROM access register.
-  Assume that we are in register window zero.
-*/
-static word read_eeprom(dword ioaddr, int index)
-{
-    int i;
-    outw(EEPROM_READ + index, ioaddr + 0xa);
-    /* Reading the eeprom takes 162 us */
-    for (i = 1620; i >= 0; i--)
-       if ((inw(ioaddr + 10) & EEPROM_BUSY) == 0)
-           break;
-    return inw(ioaddr + 0xc);
-}
-
-static void el_get_mac_addr( unsigned char *mac_addr )
-{
-       int i;
-       union
-       {
-               word w;
-               unsigned char b[2];
-       } wrd;
-       unsigned char old_window = inw( EL_BASE_ADDR + EL3_STATUS ) >> 13;
-       GO_WINDOW(0);
-       VX_BUSY_WAIT;
-       for (i = 0; i < 3; i++)
-       {
-               wrd.w = read_eeprom(EL_BASE_ADDR, 0xa+i);
-#ifdef __BIG_ENDIAN
-               mac_addr[2*i]   = wrd.b[0];
-               mac_addr[2*i+1] = wrd.b[1];
-#else
-               mac_addr[2*i]   = wrd.b[1];
-               mac_addr[2*i+1] = wrd.b[0];
-#endif
-       }
-       GO_WINDOW(old_window);
-       VX_BUSY_WAIT;
-}
-
-
-#if EL_DEBUG > 1
-static void print_packet( byte * buf, int length )
-{
-       int i;
-       int remainder;
-       int lines;
-
-       PRINTK2("Packet of length %d \n", length );
-
-       lines = length / 16;
-       remainder = length % 16;
-
-       for ( i = 0; i < lines ; i ++ ) {
-               int cur;
-
-               for ( cur = 0; cur < 8; cur ++ ) {
-                       byte a, b;
-
-                       a = *(buf ++ );
-                       b = *(buf ++ );
-                       PRINTK2("%02x%02x ", a, b );
-               }
-               PRINTK2("\n");
-       }
-       for ( i = 0; i < remainder/2 ; i++ ) {
-               byte a, b;
-
-               a = *(buf ++ );
-               b = *(buf ++ );
-               PRINTK2("%02x%02x ", a, b );
-       }
-       PRINTK2("\n");
-}
-#endif /* EL_DEBUG > 1 */
-
-
-/**************************************************************************
-ETH_RESET - Reset adapter
-***************************************************************************/
-static void el_reset(bd_t *bd)
-{
-       /***********************************************************
-                       Reset 3Com 595 card
-       *************************************************************/
-       /* QUICK HACK
-        * - adjust timing for 3c589
-        * - enable io for PCMCIA */
-       outw(0x0004, 0xa0000018);
-       udelay(100);
-       outw(0x0041, 0x28010000);
-       udelay(100);
-
-       /* issue global reset */
-       outw(GLOBAL_RESET, BASE + VX_COMMAND);
-
-       /* must wait for at least 1ms */
-       udelay(100000000);
-
-       /* set mac addr */
-       {
-               unsigned char *mac_addr = bd->bi_enetaddr;
-               int i;
-
-               el_get_mac_addr( mac_addr );
-
-               GO_WINDOW(2);
-               VX_BUSY_WAIT;
-
-               printf("3C589 MAC Addr.: ");
-               for (i = 0; i < 6; i++)
-               {
-                       printf("%02x", mac_addr[i]);
-                       outb(mac_addr[i], BASE + VX_W2_ADDR_0 + i);
-                       VX_BUSY_WAIT;
-               }
-               printf("\n\n");
-       }
-
-       /* set RX filter */
-       outw(SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST, BASE + VX_COMMAND);
-       VX_BUSY_WAIT;
-
-
-       /* set irq mask and read_zero */
-       outw(SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
-               S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
-       VX_BUSY_WAIT;
-
-       outw(SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
-               S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
-       VX_BUSY_WAIT;
-
-       /* enable TP Linkbeat */
-       GO_WINDOW(4);
-       VX_BUSY_WAIT;
-
-       outw( ENABLE_UTP, BASE + VX_W4_MEDIA_TYPE);
-       VX_BUSY_WAIT;
-
-
-/*
- * Attempt to get rid of any stray interrupts that occured during
- * configuration.  On the i386 this isn't possible because one may
- * already be queued.  However, a single stray interrupt is
- * unimportant.
- */
-
-       outw(ACK_INTR | 0xff, BASE + VX_COMMAND);
-       VX_BUSY_WAIT;
-
-       /* enable TX and RX */
-       outw( RX_ENABLE, BASE + VX_COMMAND );
-       VX_BUSY_WAIT;
-
-       outw( TX_ENABLE, BASE + VX_COMMAND );
-       VX_BUSY_WAIT;
-
-
-       /* print the diag. regs. */
-       PRINTK2("Diag. Regs\n");
-       PRINTK2("--> MEDIA_TYPE:   %04x\n", inw(BASE + VX_W4_MEDIA_TYPE));
-       PRINTK2("--> NET_DIAG:     %04x\n", inw(BASE + VX_W4_NET_DIAG));
-       PRINTK2("--> FIFO_DIAG:    %04x\n", inw(BASE + VX_W4_FIFO_DIAG));
-       PRINTK2("--> CTRLR_STATUS: %04x\n", inw(BASE + VX_W4_CTRLR_STATUS));
-       PRINTK2("\n\n");
-
-       /* enter working mode */
-       GO_WINDOW(1);
-       VX_BUSY_WAIT;
-
-       /* wait for another 1ms */
-       udelay(100000000);
-}
-
-
-/*-----------------------------------------------------------------
- .
- .  The driver can be entered at any of the following entry points.
- .
- .------------------------------------------------------------------  */
-
-extern int eth_init(bd_t *bd);
-extern void eth_halt(void);
-extern int eth_rx(void);
-extern int eth_send(volatile void *packet, int length);
-
-
-/*
- ------------------------------------------------------------
- .
- . Internal routines
- .
- ------------------------------------------------------------
-*/
-
-int eth_init(bd_t *bd)
-{
-       el_reset(bd);
-       return 0;
-}
-
-void eth_halt() {
-       return;
-}
-
-#define EDEBUG 1
-
-
-/**************************************************************************
-ETH_POLL - Wait for a frame
-***************************************************************************/
-
-int eth_rx()
-{
-       word status, rx_status, packet_size;
-
-       VX_BUSY_WAIT;
-
-       status = inw( BASE + VX_STATUS );
-
-       if ( (status & S_RX_COMPLETE) == 0 ) return 0; /* nothing to do */
-
-       /* Packet waiting -> check RX_STATUS */
-       rx_status = inw( BASE + VX_W1_RX_STATUS );
-
-       if ( rx_status & ERR_RX )
-       {
-               /* error in packet -> discard */
-               PRINTK("[ERROR] Invalid packet -> discarding\n");
-               PRINTK("-- error code 0x%02x\n", rx_status & ERR_MASK);
-               PRINTK("-- rx bytes 0x%04d\n", rx_status & ((1<<11) - 1));
-               PRINTK("[ERROR] Invalid packet -> discarding\n");
-               outw( RX_DISCARD_TOP_PACK, BASE + VX_COMMAND );
-               return 0;
-       }
-
-       /* correct pack. waiting in fifo */
-       packet_size = rx_status & RX_BYTES_MASK;
-
-       PRINTK("Correct packet waiting in fifo, size: %d\n", packet_size);
-
-       {
-               volatile word *packet_start = (word *)(BASE + VX_W1_RX_PIO_RD_1);
-               word *RcvBuffer = (word *)(NetRxPackets[0]);
-               int wcount = 0;
-
-               for (wcount = 0; wcount < (packet_size >> 1); wcount++)
-               {
-                       *RcvBuffer++ = *(packet_start);
-               }
-
-               /* handle odd packets */
-               if ( packet_size & 1 )
-               {
-                       *RcvBuffer++ = *(packet_start);
-               }
-       }
-
-       /* fifo should now be empty (besides the padding bytes) */
-       if ( ((*((word *)(BASE + VX_W1_RX_STATUS))) & RX_BYTES_MASK) > 3 )
-       {
-               PRINTK("[ERROR] Fifo not empty after packet read (remaining pkts: %d)\n",
-                       (((*(word *)(BASE + VX_W1_RX_STATUS))) & RX_BYTES_MASK));
-       }
-
-       /* discard packet */
-       *((word *)(BASE + VX_COMMAND)) = RX_DISCARD_TOP_PACK;
-
-       /* Pass Packets to upper Layer */
-       NetReceive(NetRxPackets[0], packet_size);
-       return packet_size;
-}
-
-
-/**************************************************************************
-ETH_TRANSMIT - Transmit a frame
-***************************************************************************/
-static char padmap[] = {
-       0, 3, 2, 1};
-
-
-int eth_send(volatile void *packet, int length) {
-       int pad;
-       int status;
-       volatile word *buf = (word *)packet;
-       int dummy = 0;
-
-       /* padding stuff */
-       pad = padmap[length & 3];
-
-       PRINTK("eth_send(), length: %d\n", length);
-       /* drop acknowledgements */
-       while(( status=inb(EL_BASE_ADDR + VX_W1_TX_STATUS) )& TXS_COMPLETE ) {
-               if(status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
-                       outw(TX_RESET, EL_BASE_ADDR + VX_COMMAND);
-                       outw(TX_ENABLE, EL_BASE_ADDR + VX_COMMAND);
-                       PRINTK("Bad status, resetting and reenabling transmitter\n");
-               }
-
-               outb(0x0, EL_BASE_ADDR + VX_W1_TX_STATUS);
-       }
-
-
-       while (inw(EL_BASE_ADDR + VX_W1_FREE_TX) < length + pad + 4) {
-               /* no room in FIFO */
-               if (dummy == 0)
-               {
-                       PRINTK("No room in FIFO, waiting...\n");
-                       dummy++;
-               }
-
-       }
-
-       PRINTK("    ---> FIFO ready\n");
-
-
-       outw(length, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
-
-       /* Second dword meaningless */
-       outw(0x0, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
-
-#if EL_DEBUG > 1
-       print_packet((byte *)buf, length);
-#endif
-
-       /* write packet */
-       {
-               unsigned int i, totw;
-
-               totw = ((length + 1) >> 1);
-               PRINTK("Buffer: (totw = %d)\n", totw);
-               for (i = 0; i < totw; i++) {
-                       outw( *(buf+i), EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
-                       udelay(10);
-               }
-               if(totw & 1)
-               {       /* pad to double word length */
-                       outw( 0, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
-                       udelay(10);
-               }
-               PRINTK("\n\n");
-       }
-
-       /* wait for Tx complete */
-       PRINTK("Waiting for Tx to complete...\n");
-       while(((status = inw(EL_BASE_ADDR + VX_STATUS)) & S_COMMAND_IN_PROGRESS) != 0)
-       {
-               udelay(10);
-       }
-       PRINTK("   ---> Tx completed, status = 0x%04x\n", status);
-
-       return length;
-}
-
-
-#endif /* CONFIG_DRIVER_3C589 */
diff --git a/drivers/3c589.h b/drivers/3c589.h
deleted file mode 100644 (file)
index 6735bf9..0000000
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * Copyright (c) 1993 Herb Peyerl (hpeyerl@novatel.ca) All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer. 2. The name
- * of the author may not be used to endorse or promote products derived from
- * this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- October 2, 1994
-
- Modified by: Andres Vega Garcia
-
- INRIA - Sophia Antipolis, France
- e-mail: avega@sophia.inria.fr
- finger: avega@pax.inria.fr
-
- */
-
-/*
- * Created from if_epreg.h by Fred Gray (fgray@rice.edu) to support the
- * 3c590 family.
- */
-
-/*
- * Modified by Shusuke Nisiyama <shu@athena.qe.eng.hokudai.ac.jp>
- * for etherboot
- * Mar. 14, 2000
-*/
-
-/*
- * Ethernet software status per interface.
- */
-
-/*
- * Some global constants
- */
-
-#define TX_INIT_RATE         16
-#define TX_INIT_MAX_RATE     64
-#define RX_INIT_LATENCY      64
-#define RX_INIT_EARLY_THRESH 64
-#define MIN_RX_EARLY_THRESHF   16 /* not less than ether_header */
-#define MIN_RX_EARLY_THRESHL   4
-
-#define EEPROMSIZE      0x40
-#define MAX_EEPROMBUSY  1000
-#define VX_LAST_TAG     0xd7
-#define VX_MAX_BOARDS   16
-#define VX_ID_PORT      0x100
-
-/*
- * some macros to acces long named fields
- */
-#define BASE   (EL_BASE_ADDR)
-
-/*
- * Commands to read/write EEPROM trough EEPROM command register (Window 0,
- * Offset 0xa)
- */
-#define EEPROM_CMD_RD    0x0080        /* Read:  Address required (5 bits) */
-#define EEPROM_CMD_WR    0x0040        /* Write: Address required (5 bits) */
-#define EEPROM_CMD_ERASE 0x00c0        /* Erase: Address required (5 bits) */
-#define EEPROM_CMD_EWEN  0x0030        /* Erase/Write Enable: No data required */
-
-#define EEPROM_BUSY            (1<<15)
-
-/*
- * Some short functions, worth to let them be a macro
- */
-
-/**************************************************************************
- *                                                                       *
- * These define the EEPROM data structure.  They are used in the probe
- * function to verify the existence of the adapter after having sent
- * the ID_Sequence.
- *
- * There are others but only the ones we use are defined here.
- *
- **************************************************************************/
-
-#define EEPROM_NODE_ADDR_0     0x0     /* Word */
-#define EEPROM_NODE_ADDR_1     0x1     /* Word */
-#define EEPROM_NODE_ADDR_2     0x2     /* Word */
-#define EEPROM_PROD_ID         0x3     /* 0x9[0-f]50 */
-#define EEPROM_MFG_ID          0x7     /* 0x6d50 */
-#define EEPROM_ADDR_CFG                0x8     /* Base addr */
-#define EEPROM_RESOURCE_CFG    0x9     /* IRQ. Bits 12-15 */
-#define EEPROM_OEM_ADDR_0      0xa     /* Word */
-#define EEPROM_OEM_ADDR_1      0xb     /* Word */
-#define EEPROM_OEM_ADDR_2      0xc     /* Word */
-#define EEPROM_SOFT_INFO_2     0xf     /* Software information 2 */
-
-#define NO_RX_OVN_ANOMALY       (1<<5)
-
-/**************************************************************************
- *                                                                               *
- * These are the registers for the 3Com 3c509 and their bit patterns when *
- * applicable.  They have been taken out the the "EtherLink III Parallel  *
- * Tasking EISA and ISA Technical Reference" "Beta Draft 10/30/92" manual *
- * from 3com.                                                            *
- *                                                                               *
- **************************************************************************/
-
-#define VX_COMMAND             0x0e    /* Write. BASE+0x0e is always a
-                                        * command reg. */
-#define VX_STATUS              0x0e    /* Read. BASE+0x0e is always status
-                                        * reg. */
-#define VX_WINDOW              0x0f    /* Read. BASE+0x0f is always window
-                                        * reg. */
-/*
- * Window 0 registers. Setup.
- */
-/* Write */
-#define VX_W0_EEPROM_DATA      0x0c
-#define VX_W0_EEPROM_COMMAND   0x0a
-#define VX_W0_RESOURCE_CFG     0x08
-#define VX_W0_ADDRESS_CFG      0x06
-#define VX_W0_CONFIG_CTRL      0x04
-       /* Read */
-#define VX_W0_PRODUCT_ID       0x02
-#define VX_W0_MFG_ID           0x00
-
-
-/*
- * Window 1 registers. Operating Set.
- */
-/* Write */
-#define VX_W1_TX_PIO_WR_2      0x02
-#define VX_W1_TX_PIO_WR_1      0x00
-/* Read */
-#define VX_W1_FREE_TX          0x0c
-#define VX_W1_TX_STATUS                0x0b    /* byte */
-#define VX_W1_TIMER            0x0a    /* byte */
-#define VX_W1_RX_STATUS                0x08
-#define VX_W1_RX_PIO_RD_2      0x02
-#define VX_W1_RX_PIO_RD_1      0x00
-
-/*
- * Window 2 registers. Station Address Setup/Read
- */
-/* Read/Write */
-#define VX_W2_ADDR_5           0x05
-#define VX_W2_ADDR_4           0x04
-#define VX_W2_ADDR_3           0x03
-#define VX_W2_ADDR_2           0x02
-#define VX_W2_ADDR_1           0x01
-#define VX_W2_ADDR_0           0x00
-
-/*
- * Window 3 registers. FIFO Management.
- */
-/* Read */
-#define VX_W3_INTERNAL_CFG     0x00
-#define VX_W3_RESET_OPT                0x08
-#define VX_W3_FREE_TX          0x0c
-#define VX_W3_FREE_RX          0x0a
-
-/*
- * Window 4 registers. Diagnostics.
- */
-/* Read/Write */
-#define VX_W4_MEDIA_TYPE       0x0a
-#define VX_W4_CTRLR_STATUS     0x08
-#define VX_W4_NET_DIAG         0x06
-#define VX_W4_FIFO_DIAG                0x04
-#define VX_W4_HOST_DIAG                0x02
-#define VX_W4_TX_DIAG          0x00
-
-/*
- * Window 5 Registers.  Results and Internal status.
- */
-/* Read */
-#define VX_W5_READ_0_MASK      0x0c
-#define VX_W5_INTR_MASK                0x0a
-#define VX_W5_RX_FILTER                0x08
-#define VX_W5_RX_EARLY_THRESH  0x06
-#define VX_W5_TX_AVAIL_THRESH  0x02
-#define VX_W5_TX_START_THRESH  0x00
-
-/*
- * Window 6 registers. Statistics.
- */
-/* Read/Write */
-#define TX_TOTAL_OK            0x0c
-#define RX_TOTAL_OK            0x0a
-#define TX_DEFERRALS           0x08
-#define RX_FRAMES_OK           0x07
-#define TX_FRAMES_OK           0x06
-#define RX_OVERRUNS            0x05
-#define TX_COLLISIONS          0x04
-#define TX_AFTER_1_COLLISION   0x03
-#define TX_AFTER_X_COLLISIONS  0x02
-#define TX_NO_SQE              0x01
-#define TX_CD_LOST             0x00
-
-/****************************************
- *
- * Register definitions.
- *
- ****************************************/
-
-/*
- * Command register. All windows.
- *
- * 16 bit register.
- *     15-11:  5-bit code for command to be executed.
- *     10-0:   11-bit arg if any. For commands with no args;
- *           this can be set to anything.
- */
-#define GLOBAL_RESET           (unsigned short) 0x0000 /* Wait at least 1ms
-                                                        * after issuing */
-#define WINDOW_SELECT          (unsigned short) (0x1<<11)
-#define START_TRANSCEIVER      (unsigned short) (0x2<<11)      /* Read ADDR_CFG reg to
-                                                        * determine whether
-                                                        * this is needed. If
-                                                        * so; wait 800 uSec
-                                                        * before using trans-
-                                                        * ceiver. */
-#define RX_DISABLE             (unsigned short) (0x3<<11)      /* state disabled on
-                                                        * power-up */
-#define RX_ENABLE              (unsigned short) (0x4<<11)
-#define RX_RESET               (unsigned short) (0x5<<11)
-#define RX_DISCARD_TOP_PACK    (unsigned short) (0x8<<11)
-#define TX_ENABLE              (unsigned short) (0x9<<11)
-#define TX_DISABLE             (unsigned short) (0xa<<11)
-#define TX_RESET               (unsigned short) (0xb<<11)
-#define REQ_INTR               (unsigned short) (0xc<<11)
-/*
- * The following C_* acknowledge the various interrupts. Some of them don't
- * do anything.  See the manual.
- */
-#define ACK_INTR               (unsigned short) (0x6800)
-#      define C_INTR_LATCH     (unsigned short) (ACK_INTR|0x1)
-#      define C_CARD_FAILURE   (unsigned short) (ACK_INTR|0x2)
-#      define C_TX_COMPLETE    (unsigned short) (ACK_INTR|0x4)
-#      define C_TX_AVAIL       (unsigned short) (ACK_INTR|0x8)
-#      define C_RX_COMPLETE    (unsigned short) (ACK_INTR|0x10)
-#      define C_RX_EARLY       (unsigned short) (ACK_INTR|0x20)
-#      define C_INT_RQD                (unsigned short) (ACK_INTR|0x40)
-#      define C_UPD_STATS      (unsigned short) (ACK_INTR|0x80)
-#define SET_INTR_MASK          (unsigned short) (0xe<<11)
-#define SET_RD_0_MASK          (unsigned short) (0xf<<11)
-#define SET_RX_FILTER          (unsigned short) (0x10<<11)
-#      define FIL_INDIVIDUAL   (unsigned short) (0x1)
-#      define FIL_MULTICAST     (unsigned short) (0x02)
-#      define FIL_BRDCST        (unsigned short) (0x04)
-#      define FIL_PROMISC       (unsigned short) (0x08)
-#define SET_RX_EARLY_THRESH    (unsigned short) (0x11<<11)
-#define SET_TX_AVAIL_THRESH    (unsigned short) (0x12<<11)
-#define SET_TX_START_THRESH    (unsigned short) (0x13<<11)
-#define STATS_ENABLE           (unsigned short) (0x15<<11)
-#define STATS_DISABLE          (unsigned short) (0x16<<11)
-#define STOP_TRANSCEIVER       (unsigned short) (0x17<<11)
-
-/*
- * Status register. All windows.
- *
- *     15-13:  Window number(0-7).
- *     12:     Command_in_progress.
- *     11:     reserved.
- *     10:     reserved.
- *     9:      reserved.
- *     8:      reserved.
- *     7:      Update Statistics.
- *     6:      Interrupt Requested.
- *     5:      RX Early.
- *     4:      RX Complete.
- *     3:      TX Available.
- *     2:      TX Complete.
- *     1:      Adapter Failure.
- *     0:      Interrupt Latch.
- */
-#define S_INTR_LATCH           (unsigned short) (0x1)
-#define S_CARD_FAILURE         (unsigned short) (0x2)
-#define S_TX_COMPLETE          (unsigned short) (0x4)
-#define S_TX_AVAIL             (unsigned short) (0x8)
-#define S_RX_COMPLETE          (unsigned short) (0x10)
-#define S_RX_EARLY             (unsigned short) (0x20)
-#define S_INT_RQD              (unsigned short) (0x40)
-#define S_UPD_STATS            (unsigned short) (0x80)
-#define S_COMMAND_IN_PROGRESS  (unsigned short) (0x1000)
-
-#define VX_BUSY_WAIT while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS)
-
-/* Address Config. Register.
- * Window 0/Port 06
- */
-
-#define ACF_CONNECTOR_BITS     14
-#define ACF_CONNECTOR_UTP      0
-#define ACF_CONNECTOR_AUI      1
-#define ACF_CONNECTOR_BNC      3
-
-#define INTERNAL_CONNECTOR_BITS 20
-#define INTERNAL_CONNECTOR_MASK 0x01700000
-
-/*
- * FIFO Registers. RX Status.
- *
- *     15:     Incomplete or FIFO empty.
- *     14:     1: Error in RX Packet   0: Incomplete or no error.
- *     13-11:  Type of error.
- *           1000 = Overrun.
- *           1011 = Run Packet Error.
- *           1100 = Alignment Error.
- *           1101 = CRC Error.
- *           1001 = Oversize Packet Error (>1514 bytes)
- *           0010 = Dribble Bits.
- *           (all other error codes, no errors.)
- *
- *     10-0:   RX Bytes (0-1514)
- */
-#define ERR_INCOMPLETE  (unsigned short) (0x8000)
-#define ERR_RX          (unsigned short) (0x4000)
-#define ERR_MASK        (unsigned short) (0x7800)
-#define ERR_OVERRUN     (unsigned short) (0x4000)
-#define ERR_RUNT        (unsigned short) (0x5800)
-#define ERR_ALIGNMENT   (unsigned short) (0x6000)
-#define ERR_CRC         (unsigned short) (0x6800)
-#define ERR_OVERSIZE    (unsigned short) (0x4800)
-#define ERR_DRIBBLE     (unsigned short) (0x1000)
-
-/*
- * TX Status.
- *
- *   Reports the transmit status of a completed transmission. Writing this
- *   register pops the transmit completion stack.
- *
- *   Window 1/Port 0x0b.
- *
- *     7:      Complete
- *     6:      Interrupt on successful transmission requested.
- *     5:      Jabber Error (TP Only, TX Reset required. )
- *     4:      Underrun (TX Reset required. )
- *     3:      Maximum Collisions.
- *     2:      TX Status Overflow.
- *     1-0:    Undefined.
- *
- */
-#define TXS_COMPLETE           0x80
-#define TXS_INTR_REQ           0x40
-#define TXS_JABBER             0x20
-#define TXS_UNDERRUN           0x10
-#define TXS_MAX_COLLISION      0x8
-#define TXS_STATUS_OVERFLOW    0x4
-
-#define RS_AUI                 (1<<5)
-#define RS_BNC                 (1<<4)
-#define RS_UTP                 (1<<3)
-#define        RS_T4                   (1<<0)
-#define        RS_TX                   (1<<1)
-#define        RS_FX                   (1<<2)
-#define        RS_MII                  (1<<6)
-
-
-/*
- * FIFO Status (Window 4)
- *
- *   Supports FIFO diagnostics
- *
- *   Window 4/Port 0x04.1
- *
- *     15:     1=RX receiving (RO). Set when a packet is being received
- *             into the RX FIFO.
- *     14:     Reserved
- *     13:     1=RX underrun (RO). Generates Adapter Failure interrupt.
- *             Requires RX Reset or Global Reset command to recover.
- *             It is generated when you read past the end of a packet -
- *             reading past what has been received so far will give bad
- *             data.
- *     12:     1=RX status overrun (RO). Set when there are already 8
- *             packets in the RX FIFO. While this bit is set, no additional
- *             packets are received. Requires no action on the part of
- *             the host. The condition is cleared once a packet has been
- *             read out of the RX FIFO.
- *     11:     1=RX overrun (RO). Set when the RX FIFO is full (there
- *             may not be an overrun packet yet). While this bit is set,
- *             no additional packets will be received (some additional
- *             bytes can still be pending between the wire and the RX
- *             FIFO). Requires no action on the part of the host. The
- *             condition is cleared once a few bytes have been read out
- *             from the RX FIFO.
- *     10:     1=TX overrun (RO). Generates adapter failure interrupt.
- *             Requires TX Reset or Global Reset command to recover.
- *             Disables Transmitter.
- *     9-8:    Unassigned.
- *     7-0:    Built in self test bits for the RX and TX FIFO's.
- */
-#define FIFOS_RX_RECEIVING     (unsigned short) 0x8000
-#define FIFOS_RX_UNDERRUN      (unsigned short) 0x2000
-#define FIFOS_RX_STATUS_OVERRUN        (unsigned short) 0x1000
-#define FIFOS_RX_OVERRUN       (unsigned short) 0x0800
-#define FIFOS_TX_OVERRUN       (unsigned short) 0x0400
-
-/*
- * Misc defines for various things.
- */
-#define TAG_ADAPTER                     0xd0
-#define ACTIVATE_ADAPTER_TO_CONFIG      0xff
-#define ENABLE_DRQ_IRQ                  0x0001
-#define MFG_ID                          0x506d  /* `TCM' */
-#define PROD_ID                         0x5090
-#define GO_WINDOW(x)           outw(WINDOW_SELECT|(x),BASE+VX_COMMAND)
-#define JABBER_GUARD_ENABLE    0x40
-#define LINKBEAT_ENABLE                0x80
-#define        ENABLE_UTP              (JABBER_GUARD_ENABLE | LINKBEAT_ENABLE)
-#define DISABLE_UTP            0x0
-#define RX_BYTES_MASK          (unsigned short) (0x07ff)
-#define RX_ERROR        0x4000
-#define RX_INCOMPLETE   0x8000
-#define TX_INDICATE            1<<15
-#define is_eeprom_busy(b)      (inw((b)+VX_W0_EEPROM_COMMAND)&EEPROM_BUSY)
-
-#define        VX_IOSIZE       0x20
-
-#define VX_CONNECTORS 8
-
-/*
- * Local variables:
- *  c-basic-offset: 8
- * End:
- */
diff --git a/drivers/5701rls.c b/drivers/5701rls.c
deleted file mode 100644 (file)
index 86950d0..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/******************************************************************************/
-/*                                                                            */
-/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
-/* Corporation.                                                               */
-/* All rights reserved.                                                       */
-/*                                                                            */
-/* This program is free software; you can redistribute it and/or modify       */
-/* it under the terms of the GNU General Public License as published by       */
-/* the Free Software Foundation, located in the file LICENSE.                 */
-/*                                                                            */
-/* History:                                                                   */
-/*                                                                            */
-/******************************************************************************/
-
-#if INCLUDE_5701_AX_FIX
-
-#include "bcm570x_mm.h"
-#include "5701rls.h"
-
-LM_STATUS LM_LoadRlsFirmware(PLM_DEVICE_BLOCK pDevice)
-{
-  T3_FWIMG_INFO FwImgInfo;
-
-  FwImgInfo.StartAddress = t3FwStartAddr;
-  FwImgInfo.Text.Buffer = (PLM_UINT8)t3FwText;
-  FwImgInfo.Text.Offset  = t3FwTextAddr;
-  FwImgInfo.Text.Length  = t3FwTextLen;
-  FwImgInfo.ROnlyData.Buffer = (PLM_UINT8)t3FwRodata;
-  FwImgInfo.ROnlyData.Offset  = t3FwRodataAddr;
-  FwImgInfo.ROnlyData.Length  = t3FwRodataLen;
-  FwImgInfo.Data.Buffer = (PLM_UINT8)t3FwData;
-  FwImgInfo.Data.Offset  = t3FwDataAddr;
-  FwImgInfo.Data.Length  = t3FwDataLen;
-
-  if (LM_LoadFirmware(pDevice,
-                     &FwImgInfo,
-                     T3_RX_CPU_ID | T3_TX_CPU_ID,
-                     T3_RX_CPU_ID) != LM_STATUS_SUCCESS)
-    {
-      return LM_STATUS_FAILURE;
-    }
-
-  return LM_STATUS_SUCCESS;
-}
-
-#endif /* INCLUDE_5701_AX_FIX */
diff --git a/drivers/5701rls.h b/drivers/5701rls.h
deleted file mode 100644 (file)
index 30b127a..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-/******************************************************************************/
-/*                                                                            */
-/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
-/* Corporation.                                                               */
-/* All rights reserved.                                                       */
-/*                                                                            */
-/* This program is free software; you can redistribute it and/or modify       */
-/* it under the terms of the GNU General Public License as published by       */
-/* the Free Software Foundation, located in the file LICENSE.                 */
-/*                                                                            */
-/* History:                                                                   */
-/******************************************************************************/
-
-typedef unsigned long U32;
-int t3FwReleaseMajor = 0x0;
-int t3FwReleaseMinor = 0x0;
-int t3FwReleaseFix = 0x0;
-U32 t3FwStartAddr = 0x08000000;
-U32 t3FwTextAddr = 0x08000000;
-int t3FwTextLen = 0x9c0;
-U32 t3FwRodataAddr = 0x080009c0;
-int t3FwRodataLen = 0x60;
-U32 t3FwDataAddr = 0x08000a40;
-int t3FwDataLen = 0x20;
-U32 t3FwSbssAddr = 0x08000a60;
-int t3FwSbssLen = 0xc;
-U32 t3FwBssAddr = 0x08000a70;
-int t3FwBssLen = 0x10;
-U32 t3FwText[(0x9c0/4) + 1] = {
-0x0,
-0x10000003, 0x0, 0xd, 0xd,
-0x3c1d0800, 0x37bd3ffc, 0x3a0f021, 0x3c100800,
-0x26100000, 0xe000018, 0x0, 0xd,
-0x3c1d0800, 0x37bd3ffc, 0x3a0f021, 0x3c100800,
-0x26100034, 0xe00021c, 0x0, 0xd,
-0x0, 0x0, 0x0, 0x27bdffe0,
-0x3c1cc000, 0xafbf0018, 0xaf80680c, 0xe00004c,
-0x241b2105, 0x97850000, 0x97870002, 0x9782002c,
-0x9783002e, 0x3c040800, 0x248409c0, 0xafa00014,
-0x21400, 0x621825, 0x52c00, 0xafa30010,
-0x8f860010, 0xe52825, 0xe000060, 0x24070102,
-0x3c02ac00, 0x34420100, 0x3c03ac01, 0x34630100,
-0xaf820490, 0x3c02ffff, 0xaf820494, 0xaf830498,
-0xaf82049c, 0x24020001, 0xaf825ce0, 0xe00003f,
-0xaf825d00, 0xe000140, 0x0, 0x8fbf0018,
-0x3e00008, 0x27bd0020, 0x2402ffff, 0xaf825404,
-0x8f835400, 0x34630400, 0xaf835400, 0xaf825404,
-0x3c020800, 0x24420034, 0xaf82541c, 0x3e00008,
-0xaf805400, 0x0, 0x0, 0x3c020800,
-0x34423000, 0x3c030800, 0x34633000, 0x3c040800,
-0x348437ff, 0x3c010800, 0xac220a64, 0x24020040,
-0x3c010800, 0xac220a68, 0x3c010800, 0xac200a60,
-0xac600000, 0x24630004, 0x83102b, 0x5040fffd,
-0xac600000, 0x3e00008, 0x0, 0x804821,
-0x8faa0010, 0x3c020800, 0x8c420a60, 0x3c040800,
-0x8c840a68, 0x8fab0014, 0x24430001, 0x44102b,
-0x3c010800, 0xac230a60, 0x14400003, 0x4021,
-0x3c010800, 0xac200a60, 0x3c020800, 0x8c420a60,
-0x3c030800, 0x8c630a64, 0x91240000, 0x21140,
-0x431021, 0x481021, 0x25080001, 0xa0440000,
-0x29020008, 0x1440fff4, 0x25290001, 0x3c020800,
-0x8c420a60, 0x3c030800, 0x8c630a64, 0x8f84680c,
-0x21140, 0x431021, 0xac440008, 0xac45000c,
-0xac460010, 0xac470014, 0xac4a0018, 0x3e00008,
-0xac4b001c, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x2000008,
-0x0, 0xa0001e3, 0x3c0a0001, 0xa0001e3,
-0x3c0a0002, 0xa0001e3, 0x0, 0xa0001e3,
-0x0, 0xa0001e3, 0x0, 0xa0001e3,
-0x0, 0xa0001e3, 0x0, 0xa0001e3,
-0x0, 0xa0001e3, 0x0, 0xa0001e3,
-0x0, 0xa0001e3, 0x0, 0xa0001e3,
-0x3c0a0007, 0xa0001e3, 0x3c0a0008, 0xa0001e3,
-0x3c0a0009, 0xa0001e3, 0x0, 0xa0001e3,
-0x0, 0xa0001e3, 0x3c0a000b, 0xa0001e3,
-0x3c0a000c, 0xa0001e3, 0x3c0a000d, 0xa0001e3,
-0x0, 0xa0001e3, 0x0, 0xa0001e3,
-0x3c0a000e, 0xa0001e3, 0x0, 0xa0001e3,
-0x0, 0xa0001e3, 0x0, 0xa0001e3,
-0x0, 0xa0001e3, 0x0, 0xa0001e3,
-0x0, 0xa0001e3, 0x0, 0xa0001e3,
-0x0, 0xa0001e3, 0x3c0a0013, 0xa0001e3,
-0x3c0a0014, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x27bdffe0,
-0x1821, 0x1021, 0xafbf0018, 0xafb10014,
-0xafb00010, 0x3c010800, 0x220821, 0xac200a70,
-0x3c010800, 0x220821, 0xac200a74, 0x3c010800,
-0x220821, 0xac200a78, 0x24630001, 0x1860fff5,
-0x2442000c, 0x24110001, 0x8f906810, 0x32020004,
-0x14400005, 0x24040001, 0x3c020800, 0x8c420a78,
-0x18400003, 0x2021, 0xe000182, 0x0,
-0x32020001, 0x10400003, 0x0, 0xe000169,
-0x0, 0xa000153, 0xaf915028, 0x8fbf0018,
-0x8fb10014, 0x8fb00010, 0x3e00008, 0x27bd0020,
-0x3c050800, 0x8ca50a70, 0x3c060800, 0x8cc60a80,
-0x3c070800, 0x8ce70a78, 0x27bdffe0, 0x3c040800,
-0x248409d0, 0xafbf0018, 0xafa00010, 0xe000060,
-0xafa00014, 0xe00017b, 0x2021, 0x8fbf0018,
-0x3e00008, 0x27bd0020, 0x24020001, 0x8f836810,
-0x821004, 0x21027, 0x621824, 0x3e00008,
-0xaf836810, 0x27bdffd8, 0xafbf0024, 0x1080002e,
-0xafb00020, 0x8f825cec, 0xafa20018, 0x8f825cec,
-0x3c100800, 0x26100a78, 0xafa2001c, 0x34028000,
-0xaf825cec, 0x8e020000, 0x18400016, 0x0,
-0x3c020800, 0x94420a74, 0x8fa3001c, 0x221c0,
-0xac830004, 0x8fa2001c, 0x3c010800, 0xe000201,
-0xac220a74, 0x10400005, 0x0, 0x8e020000,
-0x24420001, 0xa0001df, 0xae020000, 0x3c020800,
-0x8c420a70, 0x21c02, 0x321c0, 0xa0001c5,
-0xafa2001c, 0xe000201, 0x0, 0x1040001f,
-0x0, 0x8e020000, 0x8fa3001c, 0x24420001,
-0x3c010800, 0xac230a70, 0x3c010800, 0xac230a74,
-0xa0001df, 0xae020000, 0x3c100800, 0x26100a78,
-0x8e020000, 0x18400028, 0x0, 0xe000201,
-0x0, 0x14400024, 0x0, 0x8e020000,
-0x3c030800, 0x8c630a70, 0x2442ffff, 0xafa3001c,
-0x18400006, 0xae020000, 0x31402, 0x221c0,
-0x8c820004, 0x3c010800, 0xac220a70, 0x97a2001e,
-0x2442ff00, 0x2c420300, 0x1440000b, 0x24024000,
-0x3c040800, 0x248409dc, 0xafa00010, 0xafa00014,
-0x8fa6001c, 0x24050008, 0xe000060, 0x3821,
-0xa0001df, 0x0, 0xaf825cf8, 0x3c020800,
-0x8c420a40, 0x8fa3001c, 0x24420001, 0xaf835cf8,
-0x3c010800, 0xac220a40, 0x8fbf0024, 0x8fb00020,
-0x3e00008, 0x27bd0028, 0x27bdffe0, 0x3c040800,
-0x248409e8, 0x2821, 0x3021, 0x3821,
-0xafbf0018, 0xafa00010, 0xe000060, 0xafa00014,
-0x8fbf0018, 0x3e00008, 0x27bd0020, 0x8f82680c,
-0x8f85680c, 0x21827, 0x3182b, 0x31823,
-0x431024, 0x441021, 0xa2282b, 0x10a00006,
-0x0, 0x401821, 0x8f82680c, 0x43102b,
-0x1440fffd, 0x0, 0x3e00008, 0x0,
-0x3c040800, 0x8c840000, 0x3c030800, 0x8c630a40,
-0x64102b, 0x54400002, 0x831023, 0x641023,
-0x2c420008, 0x3e00008, 0x38420001, 0x27bdffe0,
-0x802821, 0x3c040800, 0x24840a00, 0x3021,
-0x3821, 0xafbf0018, 0xafa00010, 0xe000060,
-0xafa00014, 0xa000216, 0x0, 0x8fbf0018,
-0x3e00008, 0x27bd0020, 0x0, 0x27bdffe0,
-0x3c1cc000, 0xafbf0018, 0xe00004c, 0xaf80680c,
-0x3c040800, 0x24840a10, 0x3802821, 0x3021,
-0x3821, 0xafa00010, 0xe000060, 0xafa00014,
-0x2402ffff, 0xaf825404, 0x3c0200aa, 0xe000234,
-0xaf825434, 0x8fbf0018, 0x3e00008, 0x27bd0020,
-0x0, 0x0, 0x0, 0x27bdffe8,
-0xafb00010, 0x24100001, 0xafbf0014, 0x3c01c003,
-0xac200000, 0x8f826810, 0x30422000, 0x10400003,
-0x0, 0xe000246, 0x0, 0xa00023a,
-0xaf905428, 0x8fbf0014, 0x8fb00010, 0x3e00008,
-0x27bd0018, 0x27bdfff8, 0x8f845d0c, 0x3c0200ff,
-0x3c030800, 0x8c630a50, 0x3442fff8, 0x821024,
-0x1043001e, 0x3c0500ff, 0x34a5fff8, 0x3c06c003,
-0x3c074000, 0x851824, 0x8c620010, 0x3c010800,
-0xac230a50, 0x30420008, 0x10400005, 0x871025,
-0x8cc20000, 0x24420001, 0xacc20000, 0x871025,
-0xaf825d0c, 0x8fa20000, 0x24420001, 0xafa20000,
-0x8fa20000, 0x8fa20000, 0x24420001, 0xafa20000,
-0x8fa20000, 0x8f845d0c, 0x3c030800, 0x8c630a50,
-0x851024, 0x1443ffe8, 0x851824, 0x27bd0008,
-0x3e00008, 0x0, 0x0, 0x0 };
-U32 t3FwRodata[(0x60/4) + 1] = {
-0x35373031, 0x726c7341, 0x0,
-0x0, 0x53774576, 0x656e7430, 0x0,
-0x726c7045, 0x76656e74, 0x31000000, 0x556e6b6e,
-0x45766e74, 0x0, 0x0, 0x0,
-0x0, 0x66617461, 0x6c457272, 0x0,
-0x0, 0x4d61696e, 0x43707542, 0x0,
-0x0, 0x0 };
-U32 t3FwData[(0x20/4) + 1] = {
-0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0 };
diff --git a/drivers/8390.h b/drivers/8390.h
deleted file mode 100644 (file)
index f087217..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-
-Ported to U-Boot  by Christian Pellegrin <chri@ascensit.com>
-
-Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
-eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
-are GPL, so this is, of course, GPL.
-
-*/
-
-/* Generic NS8390 register definitions. */
-/* This file is part of Donald Becker's 8390 drivers, and is distributed
-   under the same license. Auto-loading of 8390.o only in v2.2 - Paul G.
-   Some of these names and comments originated from the Crynwr
-   packet drivers, which are distributed under the GPL. */
-
-#ifndef _8390_h
-#define _8390_h
-
-/* Some generic ethernet register configurations. */
-#define E8390_TX_IRQ_MASK      0xa     /* For register EN0_ISR */
-#define E8390_RX_IRQ_MASK      0x5
-#define E8390_RXCONFIG         0x4     /* EN0_RXCR: broadcasts, no multicast,errors */
-#define E8390_RXOFF            0x20    /* EN0_RXCR: Accept no packets */
-#define E8390_TXCONFIG         0x00    /* EN0_TXCR: Normal transmit mode */
-#define E8390_TXOFF            0x02    /* EN0_TXCR: Transmitter off */
-
-/*  Register accessed at EN_CMD, the 8390 base addr.  */
-#define E8390_STOP     0x01    /* Stop and reset the chip */
-#define E8390_START    0x02    /* Start the chip, clear reset */
-#define E8390_TRANS    0x04    /* Transmit a frame */
-#define E8390_RREAD    0x08    /* Remote read */
-#define E8390_RWRITE   0x10    /* Remote write  */
-#define E8390_NODMA    0x20    /* Remote DMA */
-#define E8390_PAGE0    0x00    /* Select page chip registers */
-#define E8390_PAGE1    0x40    /* using the two high-order bits */
-#define E8390_PAGE2    0x80    /* Page 3 is invalid. */
-
-/*
- *     Only generate indirect loads given a machine that needs them.
- *      - removed AMIGA_PCMCIA from this list, handled as ISA io now
- */
-
-#define n2k_inb(port)   (*((volatile unsigned char *)(port+CONFIG_DRIVER_NE2000_BASE)))
-#define n2k_outb(val,port)  (*((volatile unsigned char *)(port+CONFIG_DRIVER_NE2000_BASE)) = val)
-
-#define EI_SHIFT(x)    (x)
-
-#define E8390_CMD      EI_SHIFT(0x00)  /* The command register (for all pages) */
-/* Page 0 register offsets. */
-#define EN0_CLDALO     EI_SHIFT(0x01)  /* Low byte of current local dma addr  RD */
-#define EN0_STARTPG    EI_SHIFT(0x01)  /* Starting page of ring bfr WR */
-#define EN0_CLDAHI     EI_SHIFT(0x02)  /* High byte of current local dma addr  RD */
-#define EN0_STOPPG     EI_SHIFT(0x02)  /* Ending page +1 of ring bfr WR */
-#define EN0_BOUNDARY   EI_SHIFT(0x03)  /* Boundary page of ring bfr RD WR */
-#define EN0_TSR                EI_SHIFT(0x04)  /* Transmit status reg RD */
-#define EN0_TPSR       EI_SHIFT(0x04)  /* Transmit starting page WR */
-#define EN0_NCR                EI_SHIFT(0x05)  /* Number of collision reg RD */
-#define EN0_TCNTLO     EI_SHIFT(0x05)  /* Low  byte of tx byte count WR */
-#define EN0_FIFO       EI_SHIFT(0x06)  /* FIFO RD */
-#define EN0_TCNTHI     EI_SHIFT(0x06)  /* High byte of tx byte count WR */
-#define EN0_ISR                EI_SHIFT(0x07)  /* Interrupt status reg RD WR */
-#define EN0_CRDALO     EI_SHIFT(0x08)  /* low byte of current remote dma address RD */
-#define EN0_RSARLO     EI_SHIFT(0x08)  /* Remote start address reg 0 */
-#define EN0_CRDAHI     EI_SHIFT(0x09)  /* high byte, current remote dma address RD */
-#define EN0_RSARHI     EI_SHIFT(0x09)  /* Remote start address reg 1 */
-#define EN0_RCNTLO     EI_SHIFT(0x0a)  /* Remote byte count reg WR */
-#define EN0_RCNTHI     EI_SHIFT(0x0b)  /* Remote byte count reg WR */
-#define EN0_RSR                EI_SHIFT(0x0c)  /* rx status reg RD */
-#define EN0_RXCR       EI_SHIFT(0x0c)  /* RX configuration reg WR */
-#define EN0_TXCR       EI_SHIFT(0x0d)  /* TX configuration reg WR */
-#define EN0_COUNTER0   EI_SHIFT(0x0d)  /* Rcv alignment error counter RD */
-#define EN0_DCFG       EI_SHIFT(0x0e)  /* Data configuration reg WR */
-#define EN0_COUNTER1   EI_SHIFT(0x0e)  /* Rcv CRC error counter RD */
-#define EN0_IMR                EI_SHIFT(0x0f)  /* Interrupt mask reg WR */
-#define EN0_COUNTER2   EI_SHIFT(0x0f)  /* Rcv missed frame error counter RD */
-
-/* Bits in EN0_ISR - Interrupt status register */
-#define ENISR_RX       0x01    /* Receiver, no error */
-#define ENISR_TX       0x02    /* Transmitter, no error */
-#define ENISR_RX_ERR   0x04    /* Receiver, with error */
-#define ENISR_TX_ERR   0x08    /* Transmitter, with error */
-#define ENISR_OVER     0x10    /* Receiver overwrote the ring */
-#define ENISR_COUNTERS 0x20    /* Counters need emptying */
-#define ENISR_RDC      0x40    /* remote dma complete */
-#define ENISR_RESET    0x80    /* Reset completed */
-#define ENISR_ALL      0x3f    /* Interrupts we will enable */
-
-/* Bits in EN0_DCFG - Data config register */
-#define ENDCFG_WTS     0x01    /* word transfer mode selection */
-#define ENDCFG_BOS     0x02    /* byte order selection */
-#define ENDCFG_AUTO_INIT   0x10        /* Auto-init to remove packets from ring */
-#define ENDCFG_FIFO            0x40    /* 8 bytes */
-
-/* Page 1 register offsets. */
-#define EN1_PHYS   EI_SHIFT(0x01)      /* This board's physical enet addr RD WR */
-#define EN1_PHYS_SHIFT(i)  EI_SHIFT(i+1) /* Get and set mac address */
-#define EN1_CURPAG EI_SHIFT(0x07)      /* Current memory page RD WR */
-#define EN1_MULT   EI_SHIFT(0x08)      /* Multicast filter mask array (8 bytes) RD WR */
-#define EN1_MULT_SHIFT(i)  EI_SHIFT(8+i) /* Get and set multicast filter */
-
-/* Bits in received packet status byte and EN0_RSR*/
-#define ENRSR_RXOK     0x01    /* Received a good packet */
-#define ENRSR_CRC      0x02    /* CRC error */
-#define ENRSR_FAE      0x04    /* frame alignment error */
-#define ENRSR_FO       0x08    /* FIFO overrun */
-#define ENRSR_MPA      0x10    /* missed pkt */
-#define ENRSR_PHY      0x20    /* physical/multicast address */
-#define ENRSR_DIS      0x40    /* receiver disable. set in monitor mode */
-#define ENRSR_DEF      0x80    /* deferring */
-
-/* Transmitted packet status, EN0_TSR. */
-#define ENTSR_PTX 0x01 /* Packet transmitted without error */
-#define ENTSR_ND  0x02 /* The transmit wasn't deferred. */
-#define ENTSR_COL 0x04 /* The transmit collided at least once. */
-#define ENTSR_ABT 0x08  /* The transmit collided 16 times, and was deferred. */
-#define ENTSR_CRS 0x10 /* The carrier sense was lost. */
-#define ENTSR_FU  0x20  /* A "FIFO underrun" occurred during transmit. */
-#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */
-#define ENTSR_OWC 0x80  /* There was an out-of-window collision. */
-
-#define NIC_RECEIVE_MONITOR_MODE 0x20
-
-#endif /* _8390_h */
diff --git a/drivers/Makefile b/drivers/Makefile
deleted file mode 100755 (executable)
index 00978d8..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# (C) Copyright 2000-2007
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-#
-# See file CREDITS for list of people who contributed to this
-# project.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-# MA 02111-1307 USA
-#
-
-include $(TOPDIR)/config.mk
-
-# CFLAGS += -DET_DEBUG -DDEBUG
-
-LIB    = $(obj)libdrivers.a
-
-COBJS  = 3c589.o 5701rls.o ali512x.o at45.o ata_piix.o \
-         ati_radeon_fb.o atmel_usart.o \
-         bcm570x.o bcm570x_autoneg.o cfb_console.o cfi_flash.o \
-         cs8900.o ct69000.o dataflash.o dc2114x.o dm9000x.o \
-         ds1722.o e1000.o eepro100.o enc28j60.o \
-         fsl_i2c.o fsl_pci_init.o \
-         i8042.o inca-ip_sw.o isp116x-hcd.o \
-         keyboard.o ks8695eth.o \
-         lan91c96.o macb.o mpc8xx_pcmcia.o mw_eeprom.o \
-         natsemi.o ne2000.o netarm_eth.o netconsole.o \
-         ns16550.o ns8382x.o ns87308.o ns7520_eth.o omap1510_i2c.o \
-         omap24xx_i2c.o pc_keyb.o \
-         pci.o pci_auto.o pci_indirect.o \
-         pcnet.o plb2800_eth.o ps2ser.o ps2mult.o pxa_pcmcia.o \
-         rpx_pcmcia.o rtl8019.o rtl8139.o rtl8169.o \
-         s3c4510b_eth.o s3c4510b_uart.o \
-         sed13806.o sed156x.o \
-         serial.o serial_max3100.o \
-         serial_pl010.o serial_pl011.o serial_xuartlite.o \
-         sil680.o sl811_usb.o sm501.o smc91111.o smiLynxEM.o \
-         status_led.o sym53c8xx.o systemace.o ahci.o \
-         ti_pci1410a.o tigon3.o tqm8xx_pcmcia.o tsec.o \
-         tsi108_eth.o tsi108_i2c.o tsi108_pci.o \
-         usb_ohci.o \
-         usbdcore.o usbdcore_ep0.o usbdcore_mpc8xx.o usbdcore_omap1510.o \
-         usbtty.o \
-         videomodes.o w83c553f.o
-
-SRCS   := $(COBJS:.o=.c)
-OBJS   := $(addprefix $(obj),$(COBJS))
-
-all:   $(LIB)
-
-$(LIB): $(obj).depend $(OBJS)
-       $(AR) $(ARFLAGS) $@ $(OBJS)
-
-#########################################################################
-
-# defines $(obj).depend target
-include $(SRCTREE)/rules.mk
-
-sinclude $(obj).depend
-
-#########################################################################
diff --git a/drivers/ahci.c b/drivers/ahci.c
deleted file mode 100644 (file)
index 3d82c62..0000000
+++ /dev/null
@@ -1,703 +0,0 @@
-/*
- * Copyright (C) Freescale Semiconductor, Inc. 2006. All rights reserved.
- * Author: Jason Jin<Jason.jin@freescale.com>
- *         Zhang Wei<wei.zhang@freescale.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * with the reference on libata and ahci drvier in kernel
- *
- */
-#include <common.h>
-
-#ifdef CONFIG_SCSI_AHCI
-
-#include <command.h>
-#include <pci.h>
-#include <asm/processor.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <malloc.h>
-#include <scsi.h>
-#include <ata.h>
-#include <linux/ctype.h>
-#include <ahci.h>
-
-struct ahci_probe_ent *probe_ent = NULL;
-hd_driveid_t *ataid[AHCI_MAX_PORTS];
-
-#define writel_with_flush(a,b) do { writel(a,b); readl(b); } while (0)
-
-
-static inline u32 ahci_port_base(u32 base, u32 port)
-{
-       return base + 0x100 + (port * 0x80);
-}
-
-
-static void ahci_setup_port(struct ahci_ioports *port, unsigned long base,
-                           unsigned int port_idx)
-{
-       base = ahci_port_base(base, port_idx);
-
-       port->cmd_addr = base;
-       port->scr_addr = base + PORT_SCR;
-}
-
-
-#define msleep(a) udelay(a * 1000)
-#define ssleep(a) msleep(a * 1000)
-
-static int waiting_for_cmd_completed(volatile u8 *offset,
-                                    int timeout_msec,
-                                    u32 sign)
-{
-       int i;
-       u32 status;
-
-       for (i = 0; ((status = readl(offset)) & sign) && i < timeout_msec; i++)
-               msleep(1);
-
-       return (i < timeout_msec) ? 0 : -1;
-}
-
-
-static int ahci_host_init(struct ahci_probe_ent *probe_ent)
-{
-       pci_dev_t pdev = probe_ent->dev;
-       volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base;
-       u32 tmp, cap_save;
-       u16 tmp16;
-       int i, j;
-       volatile u8 *port_mmio;
-       unsigned short vendor;
-
-       cap_save = readl(mmio + HOST_CAP);
-       cap_save &= ((1 << 28) | (1 << 17));
-       cap_save |= (1 << 27);
-
-       /* global controller reset */
-       tmp = readl(mmio + HOST_CTL);
-       if ((tmp & HOST_RESET) == 0)
-               writel_with_flush(tmp | HOST_RESET, mmio + HOST_CTL);
-
-       /* reset must complete within 1 second, or
-        * the hardware should be considered fried.
-        */
-       ssleep(1);
-
-       tmp = readl(mmio + HOST_CTL);
-       if (tmp & HOST_RESET) {
-               debug("controller reset failed (0x%x)\n", tmp);
-               return -1;
-       }
-
-       writel_with_flush(HOST_AHCI_EN, mmio + HOST_CTL);
-       writel(cap_save, mmio + HOST_CAP);
-       writel_with_flush(0xf, mmio + HOST_PORTS_IMPL);
-
-       pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);
-
-       if (vendor == PCI_VENDOR_ID_INTEL) {
-               u16 tmp16;
-               pci_read_config_word(pdev, 0x92, &tmp16);
-               tmp16 |= 0xf;
-               pci_write_config_word(pdev, 0x92, tmp16);
-       }
-
-       probe_ent->cap = readl(mmio + HOST_CAP);
-       probe_ent->port_map = readl(mmio + HOST_PORTS_IMPL);
-       probe_ent->n_ports = (probe_ent->cap & 0x1f) + 1;
-
-       debug("cap 0x%x  port_map 0x%x  n_ports %d\n",
-             probe_ent->cap, probe_ent->port_map, probe_ent->n_ports);
-
-       for (i = 0; i < probe_ent->n_ports; i++) {
-               probe_ent->port[i].port_mmio = ahci_port_base((u32) mmio, i);
-               port_mmio = (u8 *) probe_ent->port[i].port_mmio;
-               ahci_setup_port(&probe_ent->port[i], (unsigned long)mmio, i);
-
-               /* make sure port is not active */
-               tmp = readl(port_mmio + PORT_CMD);
-               if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
-                          PORT_CMD_FIS_RX | PORT_CMD_START)) {
-                       tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
-                                PORT_CMD_FIS_RX | PORT_CMD_START);
-                       writel_with_flush(tmp, port_mmio + PORT_CMD);
-
-                       /* spec says 500 msecs for each bit, so
-                        * this is slightly incorrect.
-                        */
-                       msleep(500);
-               }
-
-               writel(PORT_CMD_SPIN_UP, port_mmio + PORT_CMD);
-
-               j = 0;
-               while (j < 100) {
-                       msleep(10);
-                       tmp = readl(port_mmio + PORT_SCR_STAT);
-                       if ((tmp & 0xf) == 0x3)
-                               break;
-                       j++;
-               }
-
-               tmp = readl(port_mmio + PORT_SCR_ERR);
-               debug("PORT_SCR_ERR 0x%x\n", tmp);
-               writel(tmp, port_mmio + PORT_SCR_ERR);
-
-               /* ack any pending irq events for this port */
-               tmp = readl(port_mmio + PORT_IRQ_STAT);
-               debug("PORT_IRQ_STAT 0x%x\n", tmp);
-               if (tmp)
-                       writel(tmp, port_mmio + PORT_IRQ_STAT);
-
-               writel(1 << i, mmio + HOST_IRQ_STAT);
-
-               /* set irq mask (enables interrupts) */
-               writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK);
-
-               /*register linkup ports */
-               tmp = readl(port_mmio + PORT_SCR_STAT);
-               debug("Port %d status: 0x%x\n", i, tmp);
-               if ((tmp & 0xf) == 0x03)
-                       probe_ent->link_port_map |= (0x01 << i);
-       }
-
-       tmp = readl(mmio + HOST_CTL);
-       debug("HOST_CTL 0x%x\n", tmp);
-       writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
-       tmp = readl(mmio + HOST_CTL);
-       debug("HOST_CTL 0x%x\n", tmp);
-
-       pci_read_config_word(pdev, PCI_COMMAND, &tmp16);
-       tmp |= PCI_COMMAND_MASTER;
-       pci_write_config_word(pdev, PCI_COMMAND, tmp16);
-
-       return 0;
-}
-
-
-static void ahci_print_info(struct ahci_probe_ent *probe_ent)
-{
-       pci_dev_t pdev = probe_ent->dev;
-       volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base;
-       u32 vers, cap, impl, speed;
-       const char *speed_s;
-       u16 cc;
-       const char *scc_s;
-
-       vers = readl(mmio + HOST_VERSION);
-       cap = probe_ent->cap;
-       impl = probe_ent->port_map;
-
-       speed = (cap >> 20) & 0xf;
-       if (speed == 1)
-               speed_s = "1.5";
-       else if (speed == 2)
-               speed_s = "3";
-       else
-               speed_s = "?";
-
-       pci_read_config_word(pdev, 0x0a, &cc);
-       if (cc == 0x0101)
-               scc_s = "IDE";
-       else if (cc == 0x0106)
-               scc_s = "SATA";
-       else if (cc == 0x0104)
-               scc_s = "RAID";
-       else
-               scc_s = "unknown";
-
-       printf("AHCI %02x%02x.%02x%02x "
-              "%u slots %u ports %s Gbps 0x%x impl %s mode\n",
-              (vers >> 24) & 0xff,
-              (vers >> 16) & 0xff,
-              (vers >> 8) & 0xff,
-              vers & 0xff,
-              ((cap >> 8) & 0x1f) + 1, (cap & 0x1f) + 1, speed_s, impl, scc_s);
-
-       printf("flags: "
-              "%s%s%s%s%s%s"
-              "%s%s%s%s%s%s%s\n",
-              cap & (1 << 31) ? "64bit " : "",
-              cap & (1 << 30) ? "ncq " : "",
-              cap & (1 << 28) ? "ilck " : "",
-              cap & (1 << 27) ? "stag " : "",
-              cap & (1 << 26) ? "pm " : "",
-              cap & (1 << 25) ? "led " : "",
-              cap & (1 << 24) ? "clo " : "",
-              cap & (1 << 19) ? "nz " : "",
-              cap & (1 << 18) ? "only " : "",
-              cap & (1 << 17) ? "pmp " : "",
-              cap & (1 << 15) ? "pio " : "",
-              cap & (1 << 14) ? "slum " : "",
-              cap & (1 << 13) ? "part " : "");
-}
-
-static int ahci_init_one(pci_dev_t pdev)
-{
-       u32 iobase;
-       u16 vendor;
-       int rc;
-
-       memset((void *)ataid, 0, sizeof(hd_driveid_t *) * AHCI_MAX_PORTS);
-
-       probe_ent = malloc(sizeof(struct ahci_probe_ent));
-       memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
-       probe_ent->dev = pdev;
-
-       pci_read_config_dword(pdev, AHCI_PCI_BAR, &iobase);
-       iobase &= ~0xf;
-
-       probe_ent->host_flags = ATA_FLAG_SATA
-                               | ATA_FLAG_NO_LEGACY
-                               | ATA_FLAG_MMIO
-                               | ATA_FLAG_PIO_DMA
-                               | ATA_FLAG_NO_ATAPI;
-       probe_ent->pio_mask = 0x1f;
-       probe_ent->udma_mask = 0x7f;    /*Fixme,assume to support UDMA6 */
-
-       probe_ent->mmio_base = iobase;
-
-       /* Take from kernel:
-        * JMicron-specific fixup:
-        * make sure we're in AHCI mode
-        */
-       pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);
-       if (vendor == 0x197b)
-               pci_write_config_byte(pdev, 0x41, 0xa1);
-
-       /* initialize adapter */
-       rc = ahci_host_init(probe_ent);
-       if (rc)
-               goto err_out;
-
-       ahci_print_info(probe_ent);
-
-       return 0;
-
-      err_out:
-       return rc;
-}
-
-
-#define MAX_DATA_BYTE_COUNT  (4*1024*1024)
-
-static int ahci_fill_sg(u8 port, unsigned char *buf, int buf_len)
-{
-       struct ahci_ioports *pp = &(probe_ent->port[port]);
-       struct ahci_sg *ahci_sg = pp->cmd_tbl_sg;
-       u32 sg_count;
-       int i;
-
-       sg_count = ((buf_len - 1) / MAX_DATA_BYTE_COUNT) + 1;
-       if (sg_count > AHCI_MAX_SG) {
-               printf("Error:Too much sg!\n");
-               return -1;
-       }
-
-       for (i = 0; i < sg_count; i++) {
-               ahci_sg->addr =
-                   cpu_to_le32((u32) buf + i * MAX_DATA_BYTE_COUNT);
-               ahci_sg->addr_hi = 0;
-               ahci_sg->flags_size = cpu_to_le32(0x3fffff &
-                                         (buf_len < MAX_DATA_BYTE_COUNT
-                                          ? (buf_len - 1)
-                                          : (MAX_DATA_BYTE_COUNT - 1)));
-               ahci_sg++;
-               buf_len -= MAX_DATA_BYTE_COUNT;
-       }
-
-       return sg_count;
-}
-
-
-static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 opts)
-{
-       pp->cmd_slot->opts = cpu_to_le32(opts);
-       pp->cmd_slot->status = 0;
-       pp->cmd_slot->tbl_addr = cpu_to_le32(pp->cmd_tbl & 0xffffffff);
-       pp->cmd_slot->tbl_addr_hi = 0;
-}
-
-
-static void ahci_set_feature(u8 port)
-{
-       struct ahci_ioports *pp = &(probe_ent->port[port]);
-       volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
-       u32 cmd_fis_len = 5;    /* five dwords */
-       u8 fis[20];
-
-       /*set feature */
-       memset(fis, 0, 20);
-       fis[0] = 0x27;
-       fis[1] = 1 << 7;
-       fis[2] = ATA_CMD_SETF;
-       fis[3] = SETFEATURES_XFER;
-       fis[12] = __ilog2(probe_ent->udma_mask + 1) + 0x40 - 0x01;
-
-       memcpy((unsigned char *)pp->cmd_tbl, fis, 20);
-       ahci_fill_cmd_slot(pp, cmd_fis_len);
-       writel(1, port_mmio + PORT_CMD_ISSUE);
-       readl(port_mmio + PORT_CMD_ISSUE);
-
-       if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, 150, 0x1)) {
-               printf("set feature error!\n");
-       }
-}
-
-
-static int ahci_port_start(u8 port)
-{
-       struct ahci_ioports *pp = &(probe_ent->port[port]);
-       volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
-       u32 port_status;
-       u32 mem;
-
-       debug("Enter start port: %d\n", port);
-       port_status = readl(port_mmio + PORT_SCR_STAT);
-       debug("Port %d status: %x\n", port, port_status);
-       if ((port_status & 0xf) != 0x03) {
-               printf("No Link on this port!\n");
-               return -1;
-       }
-
-       mem = (u32) malloc(AHCI_PORT_PRIV_DMA_SZ + 2048);
-       if (!mem) {
-               free(pp);
-               printf("No mem for table!\n");
-               return -ENOMEM;
-       }
-
-       mem = (mem + 0x800) & (~0x7ff); /* Aligned to 2048-bytes */
-       memset((u8 *) mem, 0, AHCI_PORT_PRIV_DMA_SZ);
-
-       /*
-        * First item in chunk of DMA memory: 32-slot command table,
-        * 32 bytes each in size
-        */
-       pp->cmd_slot = (struct ahci_cmd_hdr *)mem;
-       debug("cmd_slot = 0x%x\n", pp->cmd_slot);
-       mem += (AHCI_CMD_SLOT_SZ + 224);
-
-       /*
-        * Second item: Received-FIS area
-        */
-       pp->rx_fis = mem;
-       mem += AHCI_RX_FIS_SZ;
-
-       /*
-        * Third item: data area for storing a single command
-        * and its scatter-gather table
-        */
-       pp->cmd_tbl = mem;
-       debug("cmd_tbl_dma = 0x%x\n", pp->cmd_tbl);
-
-       mem += AHCI_CMD_TBL_HDR;
-       pp->cmd_tbl_sg = (struct ahci_sg *)mem;
-
-       writel_with_flush((u32) pp->cmd_slot, port_mmio + PORT_LST_ADDR);
-
-       writel_with_flush(pp->rx_fis, port_mmio + PORT_FIS_ADDR);
-
-       writel_with_flush(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
-                         PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
-                         PORT_CMD_START, port_mmio + PORT_CMD);
-
-       debug("Exit start port %d\n", port);
-
-       return 0;
-}
-
-
-static int get_ahci_device_data(u8 port, u8 *fis, int fis_len, u8 *buf,
-                               int buf_len)
-{
-
-       struct ahci_ioports *pp = &(probe_ent->port[port]);
-       volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
-       u32 opts;
-       u32 port_status;
-       int sg_count;
-
-       debug("Enter get_ahci_device_data: for port %d\n", port);
-
-       if (port > probe_ent->n_ports) {
-               printf("Invaild port number %d\n", port);
-               return -1;
-       }
-
-       port_status = readl(port_mmio + PORT_SCR_STAT);
-       if ((port_status & 0xf) != 0x03) {
-               debug("No Link on port %d!\n", port);
-               return -1;
-       }
-
-       memcpy((unsigned char *)pp->cmd_tbl, fis, fis_len);
-
-       sg_count = ahci_fill_sg(port, buf, buf_len);
-       opts = (fis_len >> 2) | (sg_count << 16);
-       ahci_fill_cmd_slot(pp, opts);
-
-       writel_with_flush(1, port_mmio + PORT_CMD_ISSUE);
-
-       if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, 150, 0x1)) {
-               printf("timeout exit!\n");
-               return -1;
-       }
-       debug("get_ahci_device_data: %d byte transferred.\n",
-             pp->cmd_slot->status);
-
-       return 0;
-}
-
-
-static char *ata_id_strcpy(u16 *target, u16 *src, int len)
-{
-       int i;
-       for (i = 0; i < len / 2; i++)
-               target[i] = le16_to_cpu(src[i]);
-       return (char *)target;
-}
-
-
-static void dump_ataid(hd_driveid_t *ataid)
-{
-       debug("(49)ataid->capability = 0x%x\n", ataid->capability);
-       debug("(53)ataid->field_valid =0x%x\n", ataid->field_valid);
-       debug("(63)ataid->dma_mword = 0x%x\n", ataid->dma_mword);
-       debug("(64)ataid->eide_pio_modes = 0x%x\n", ataid->eide_pio_modes);
-       debug("(75)ataid->queue_depth = 0x%x\n", ataid->queue_depth);
-       debug("(80)ataid->major_rev_num = 0x%x\n", ataid->major_rev_num);
-       debug("(81)ataid->minor_rev_num = 0x%x\n", ataid->minor_rev_num);
-       debug("(82)ataid->command_set_1 = 0x%x\n", ataid->command_set_1);
-       debug("(83)ataid->command_set_2 = 0x%x\n", ataid->command_set_2);
-       debug("(84)ataid->cfsse = 0x%x\n", ataid->cfsse);
-       debug("(85)ataid->cfs_enable_1 = 0x%x\n", ataid->cfs_enable_1);
-       debug("(86)ataid->cfs_enable_2 = 0x%x\n", ataid->cfs_enable_2);
-       debug("(87)ataid->csf_default = 0x%x\n", ataid->csf_default);
-       debug("(88)ataid->dma_ultra = 0x%x\n", ataid->dma_ultra);
-       debug("(93)ataid->hw_config = 0x%x\n", ataid->hw_config);
-}
-
-
-/*
- * SCSI INQUIRY command operation.
- */
-static int ata_scsiop_inquiry(ccb *pccb)
-{
-       u8 hdr[] = {
-               0,
-               0,
-               0x5,            /* claim SPC-3 version compatibility */
-               2,
-               95 - 4,
-       };
-       u8 fis[20];
-       u8 *tmpid;
-       u8 port;
-
-       /* Clean ccb data buffer */
-       memset(pccb->pdata, 0, pccb->datalen);
-
-       memcpy(pccb->pdata, hdr, sizeof(hdr));
-
-       if (pccb->datalen <= 35)
-               return 0;
-
-       memset(fis, 0, 20);
-       /* Construct the FIS */
-       fis[0] = 0x27;          /* Host to device FIS. */
-       fis[1] = 1 << 7;        /* Command FIS. */
-       fis[2] = ATA_CMD_IDENT; /* Command byte. */
-
-       /* Read id from sata */
-       port = pccb->target;
-       if (!(tmpid = malloc(sizeof(hd_driveid_t))))
-               return -ENOMEM;
-
-       if (get_ahci_device_data(port, (u8 *) & fis, 20,
-                                tmpid, sizeof(hd_driveid_t))) {
-               debug("scsi_ahci: SCSI inquiry command failure.\n");
-               return -EIO;
-       }
-
-       if (ataid[port])
-               free(ataid[port]);
-       ataid[port] = (hd_driveid_t *) tmpid;
-
-       memcpy(&pccb->pdata[8], "ATA     ", 8);
-       ata_id_strcpy((u16 *) &pccb->pdata[16], (u16 *)ataid[port]->model, 16);
-       ata_id_strcpy((u16 *) &pccb->pdata[32], (u16 *)ataid[port]->fw_rev, 4);
-
-       dump_ataid(ataid[port]);
-       return 0;
-}
-
-
-/*
- * SCSI READ10 command operation.
- */
-static int ata_scsiop_read10(ccb * pccb)
-{
-       u64 lba = 0;
-       u32 len = 0;
-       u8 fis[20];
-
-       lba = (((u64) pccb->cmd[2]) << 24) | (((u64) pccb->cmd[3]) << 16)
-           | (((u64) pccb->cmd[4]) << 8) | ((u64) pccb->cmd[5]);
-       len = (((u32) pccb->cmd[7]) << 8) | ((u32) pccb->cmd[8]);
-
-       /* For 10-byte and 16-byte SCSI R/W commands, transfer
-        * length 0 means transfer 0 block of data.
-        * However, for ATA R/W commands, sector count 0 means
-        * 256 or 65536 sectors, not 0 sectors as in SCSI.
-        *
-        * WARNING: one or two older ATA drives treat 0 as 0...
-        */
-       if (!len)
-               return 0;
-       memset(fis, 0, 20);
-
-       /* Construct the FIS */
-       fis[0] = 0x27;          /* Host to device FIS. */
-       fis[1] = 1 << 7;        /* Command FIS. */
-       fis[2] = ATA_CMD_RD_DMA;        /* Command byte. */
-
-       /* LBA address, only support LBA28 in this driver */
-       fis[4] = pccb->cmd[5];
-       fis[5] = pccb->cmd[4];
-       fis[6] = pccb->cmd[3];
-       fis[7] = (pccb->cmd[2] & 0x0f) | 0xe0;
-
-       /* Sector Count */
-       fis[12] = pccb->cmd[8];
-       fis[13] = pccb->cmd[7];
-
-       /* Read from ahci */
-       if (get_ahci_device_data(pccb->target, (u8 *) & fis, 20,
-                                pccb->pdata, pccb->datalen)) {
-               debug("scsi_ahci: SCSI READ10 command failure.\n");
-               return -EIO;
-       }
-
-       return 0;
-}
-
-
-/*
- * SCSI READ CAPACITY10 command operation.
- */
-static int ata_scsiop_read_capacity10(ccb *pccb)
-{
-       u8 buf[8];
-
-       if (!ataid[pccb->target]) {
-               printf("scsi_ahci: SCSI READ CAPACITY10 command failure. "
-                      "\tNo ATA info!\n"
-                      "\tPlease run SCSI commmand INQUIRY firstly!\n");
-               return -EPERM;
-       }
-
-       memset(buf, 0, 8);
-
-       *(u32 *) buf = le32_to_cpu(ataid[pccb->target]->lba_capacity);
-
-       buf[6] = 512 >> 8;
-       buf[7] = 512 & 0xff;
-
-       memcpy(pccb->pdata, buf, 8);
-
-       return 0;
-}
-
-
-/*
- * SCSI TEST UNIT READY command operation.
- */
-static int ata_scsiop_test_unit_ready(ccb *pccb)
-{
-       return (ataid[pccb->target]) ? 0 : -EPERM;
-}
-
-
-int scsi_exec(ccb *pccb)
-{
-       int ret;
-
-       switch (pccb->cmd[0]) {
-       case SCSI_READ10:
-               ret = ata_scsiop_read10(pccb);
-               break;
-       case SCSI_RD_CAPAC:
-               ret = ata_scsiop_read_capacity10(pccb);
-               break;
-       case SCSI_TST_U_RDY:
-               ret = ata_scsiop_test_unit_ready(pccb);
-               break;
-       case SCSI_INQUIRY:
-               ret = ata_scsiop_inquiry(pccb);
-               break;
-       default:
-               printf("Unsupport SCSI command 0x%02x\n", pccb->cmd[0]);
-               return FALSE;
-       }
-
-       if (ret) {
-               debug("SCSI command 0x%02x ret errno %d\n", pccb->cmd[0], ret);
-               return FALSE;
-       }
-       return TRUE;
-
-}
-
-
-void scsi_low_level_init(int busdevfunc)
-{
-       int i;
-       u32 linkmap;
-
-       ahci_init_one(busdevfunc);
-
-       linkmap = probe_ent->link_port_map;
-
-       for (i = 0; i < CFG_SCSI_MAX_SCSI_ID; i++) {
-               if (((linkmap >> i) & 0x01)) {
-                       if (ahci_port_start((u8) i)) {
-                               printf("Can not start port %d\n", i);
-                               continue;
-                       }
-                       ahci_set_feature((u8) i);
-               }
-       }
-}
-
-
-void scsi_bus_reset(void)
-{
-       /*Not implement*/
-}
-
-
-void scsi_print_error(ccb * pccb)
-{
-       /*The ahci error info can be read in the ahci driver*/
-}
-#endif
diff --git a/drivers/ali512x.c b/drivers/ali512x.c
deleted file mode 100644 (file)
index 7b7edc0..0000000
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * (C) Copyright 2002
- * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Based on sc520cdp.c from rolo 1.6:
- *----------------------------------------------------------------------
- * (C) Copyright 2000
- * Sysgo Real-Time Solutions GmbH
- * Klein-Winternheim, Germany
- *----------------------------------------------------------------------
- */
-
-#include <config.h>
-
-#ifdef CONFIG_ALI152X
-
-#include <common.h>
-#include <asm/io.h>
-#include <asm/ic/ali512x.h>
-
-
-/* ALI M5123 Logical device numbers:
- * 0 FDC
- * 1 unused?
- * 2 unused?
- * 3 lpt
- * 4 UART1
- * 5 UART2
- * 6 RTC
- * 7 mouse/kbd
- * 8 CIO
- */
-
-/*
- ************************************************************
- *  Some access primitives for the ALi chip:                *
- ************************************************************
- */
-
-static void ali_write(u8 index, u8 value)
-{
-       /* write an arbirary register */
-       outb(index, ALI_INDEX);
-       outb(value, ALI_DATA);
-}
-
-#if 0
-static int ali_read(u8 index)
-{
-       outb(index, ALI_INDEX);
-       return inb(ALI_DATA);
-}
-#endif
-
-#define ALI_OPEN() \
-       outb(0x51, ALI_INDEX); \
-       outb(0x23, ALI_INDEX)
-
-
-#define ALI_CLOSE() \
-       outb(0xbb, ALI_INDEX)
-
-/* Select a logical device */
-#define ALI_SELDEV(dev)        \
-       ali_write(0x07, dev)
-
-
-void ali512x_init(void)
-{
-       ALI_OPEN();
-
-       ali_write(0x02, 0x01);  /* soft reset */
-       ali_write(0x03, 0x03);  /* disable access to CIOs */
-       ali_write(0x22, 0x00);  /* disable direct powerdown */
-       ali_write(0x23, 0x00);  /* disable auto powerdown */
-       ali_write(0x24, 0x00);  /* IR 8 is active hi, pin26 is PDIR */
-
-       ALI_CLOSE();
-}
-
-void ali512x_set_fdc(int enabled, u16 io, u8 irq, u8 dma_channel)
-{
-       ALI_OPEN();
-       ALI_SELDEV(0);
-
-       ali_write(0x30, enabled?1:0);
-       if (enabled) {
-               ali_write(0x60, io >> 8);
-               ali_write(0x61, io & 0xff);
-               ali_write(0x70, irq);
-               ali_write(0x74, dma_channel);
-
-               /* AT mode, no drive swap */
-               ali_write(0xf0, 0x08);
-               ali_write(0xf1, 0x00);
-               ali_write(0xf2, 0xff);
-               ali_write(0xf4, 0x00);
-       }
-       ALI_CLOSE();
-}
-
-
-void ali512x_set_pp(int enabled, u16 io, u8 irq, u8 dma_channel)
-{
-       ALI_OPEN();
-       ALI_SELDEV(3);
-
-       ali_write(0x30, enabled?1:0);
-       if (enabled) {
-               ali_write(0x60, io >> 8);
-               ali_write(0x61, io & 0xff);
-               ali_write(0x70, irq);
-               ali_write(0x74, dma_channel);
-
-               /* mode: EPP 1.9, ECP FIFO threshold = 7, IRQ active low */
-               ali_write(0xf0, 0xbc);
-               /* 12 MHz, Burst DMA in ECP */
-               ali_write(0xf1, 0x05);
-       }
-       ALI_CLOSE();
-
-}
-
-void ali512x_set_uart(int enabled, int index, u16 io, u8 irq)
-{
-       ALI_OPEN();
-       ALI_SELDEV(index?5:4);
-
-       ali_write(0x30, enabled?1:0);
-       if (enabled) {
-               ali_write(0x60, io >> 8);
-               ali_write(0x61, io & 0xff);
-               ali_write(0x70, irq);
-
-               ali_write(0xf0, 0x00);
-               ali_write(0xf1, 0x00);
-
-               /* huh? write 0xf2 twice - a typo in rolo
-                * or some secret ali errata? Who knows?
-                */
-               if (index) {
-                       ali_write(0xf2, 0x00);
-               }
-               ali_write(0xf2, 0x0c);
-       }
-       ALI_CLOSE();
-
-}
-
-void ali512x_set_uart2_irda(int enabled)
-{
-       ALI_OPEN();
-       ALI_SELDEV(5);
-
-       ali_write(0xf1, enabled?0x48:0x00); /* fullduplex IrDa */
-       ALI_CLOSE();
-
-}
-
-void ali512x_set_rtc(int enabled, u16 io, u8 irq)
-{
-       ALI_OPEN();
-       ALI_SELDEV(6);
-
-       ali_write(0x30, enabled?1:0);
-       if (enabled) {
-               ali_write(0x60, io >> 8);
-               ali_write(0x61, io & 0xff);
-               ali_write(0x70, irq);
-
-               ali_write(0xf0, 0x00);
-       }
-       ALI_CLOSE();
-}
-
-void ali512x_set_kbc(int enabled, u8 kbc_irq, u8 mouse_irq)
-{
-       ALI_OPEN();
-       ALI_SELDEV(7);
-
-       ali_write(0x30, enabled?1:0);
-       if (enabled) {
-               ali_write(0x70, kbc_irq);
-               ali_write(0x72, mouse_irq);
-
-               ali_write(0xf0, 0x00);
-       }
-       ALI_CLOSE();
-}
-
-
-/* Common I/O
- *
- * (This descripotsion is base on several incompete sources
- *  since I have not been able to obtain any datasheet for the device
- *  there may be some mis-understandings burried in here.
- *  -- Daniel daniel@omicron.se)
- *
- * There are 22 CIO pins numbered
- * 10-17
- * 20-25
- * 30-37
- *
- * 20-24 are dedicated CIO pins, the other 17 are muliplexed with
- * other functions.
- *
- *           Secondary
- * CIO Pin   Function    Decription
- * =======================================================
- * CIO10     IRQIN1      Interrupt input 1?
- * CIO11     IRQIN2      Interrupt input 2?
- * CIO12     IRRX        IrDa Receive
- * CIO13     IRTX        IrDa Transmit
- * CIO14     P21         KBC P21 fucntion
- * CIO15     P20         KBC P21 fucntion
- * CIO16     I2C_CLK     I2C Clock
- * CIO17     I2C_DAT     I2C Data
- *
- * CIO20     -
- * CIO21     -
- * CIO22     -
- * CIO23     -
- * CIO24     -
- * CIO25     LOCK        Keylock
- *
- * CIO30     KBC_CLK     Keybaord Clock
- * CIO31     CS0J        General Chip Select decoder CS0J
- * CIO32     CS1J        General Chip Select decoder CS1J
- * CIO33     ALT_KCLK    Alternative Keyboard Clock
- * CIO34     ALT_KDAT    Alternative Keyboard Data
- * CIO35     ALT_MCLK    Alternative Mouse Clock
- * CIO36     ALT_MDAT    Alternative Mouse Data
- * CIO37     ALT_KBC     Alternative KBC select
- *
- * The CIO use an indirect address scheme.
- *
- * Reigster 3 in the SIO is used to select the index and data
- * port addresses where the CIO I/O registers show up.
- * The function selection registers are accessible under
- * function SIO 8.
- *
- * SIO reigster 3 (CIO Address Selection) bit definitions:
- * bit 7   CIO index and data registers enabled
- * bit 1-0 CIO indirect registers port address select
- *              0  index = 0xE0 data = 0xE1
- *       1  index = 0xE2 data = 0xE3
- *       2  index = 0xE4 data = 0xE5
- *       3  index = 0xEA data = 0xEB
- *
- * There are three CIO I/O register accessed via CIO index port and CIO data port
- * 0x01     CIO 10-17 data
- * 0x02     CIO 20-25 data (bits 7-6 unused)
- * 0x03     CIO 30-37 data
- *
- *
- * The pin function is accessed through normal
- * SIO registers, each register have the same format:
- *
- * Bit   Function                     Value
- * 0     Input/output                 1=input
- * 1     Polarity of signal           1=inverted
- * 2     Unused                       ??
- * 3     Function (normal or special) 1=special
- * 7-4   Unused
- *
- * SIO REG
- * 0xe0     CIO 10 Config
- * 0xe1     CIO 11 Config
- * 0xe2     CIO 12 Config
- * 0xe3     CIO 13 Config
- * 0xe4     CIO 14 Config
- * 0xe5     CIO 15 Config
- * 0xe6     CIO 16 Config
- * 0xe7     CIO 16 Config
- *
- * 0xe8     CIO 20 Config
- * 0xe9     CIO 21 Config
- * 0xea     CIO 22 Config
- * 0xeb     CIO 23 Config
- * 0xec     CIO 24 Config
- * 0xed     CIO 25 Config
- *
- * 0xf5     CIO 30 Config
- * 0xf6     CIO 31 Config
- * 0xf7     CIO 32 Config
- * 0xf8     CIO 33 Config
- * 0xf9     CIO 34 Config
- * 0xfa     CIO 35 Config
- * 0xfb     CIO 36 Config
- * 0xfc     CIO 37 Config
- *
- */
-
-#define ALI_CIO_PORT_SEL 0x83
-#define ALI_CIO_INDEX    0xea
-#define ALI_CIO_DATA     0xeb
-
-void ali512x_set_cio(int enabled)
-{
-       int i;
-
-       ALI_OPEN();
-
-       if (enabled) {
-               ali_write(0x3, ALI_CIO_PORT_SEL);    /* Enable CIO data register */
-       } else {
-               ali_write(0x3, ALI_CIO_PORT_SEL & ~0x80);
-       }
-
-       ALI_SELDEV(8);
-
-       ali_write(0x30, enabled?1:0);
-
-       /* set all pins to input to start with */
-       for (i=0xe0;i<0xee;i++) {
-               ali_write(i, 1);
-       }
-
-       for (i=0xf5;i<0xfe;i++) {
-               ali_write(i, 1);
-       }
-
-       ALI_CLOSE();
-}
-
-
-void ali512x_cio_function(int pin, int special, int inv, int input)
-{
-       u8 data;
-       u8 addr;
-
-       /* valid pins are 10-17, 20-25 and 30-37 */
-       if (pin >= 10 && pin <= 17) {
-               addr = 0xe0+(pin&7);
-       } else if (pin >= 20 && pin <= 25) {
-               addr = 0xe8+(pin&7);
-       } else if (pin >= 30 && pin <= 37) {
-               addr = 0xf5+(pin&7);
-       } else {
-               return;
-       }
-
-       ALI_OPEN();
-
-       ALI_SELDEV(8);
-
-
-       data=0xf4;
-       if (special) {
-               data |= 0x08;
-       } else {
-               if (inv) {
-                       data |= 0x02;
-               }
-               if (input) {
-                       data |= 0x01;
-               }
-       }
-
-       ali_write(addr, data);
-
-       ALI_CLOSE();
-}
-
-void ali512x_cio_out(int pin, int value)
-{
-       u8 reg;
-       u8 data;
-       u8 bit;
-
-       reg = pin/10;
-       bit = 1 << (pin%10);
-
-
-       outb(reg, ALI_CIO_INDEX);     /* select I/O register */
-       data = inb(ALI_CIO_DATA);
-       if (value) {
-               data |= bit;
-       } else {
-               data &= ~bit;
-       }
-       outb(data, ALI_CIO_DATA);
-}
-
-int ali512x_cio_in(int pin)
-{
-       u8 reg;
-       u8 data;
-       u8 bit;
-
-       /* valid pins are 10-17, 20-25 and 30-37 */
-       reg = pin/10;
-       bit = 1 << (pin%10);
-
-
-       outb(reg, ALI_CIO_INDEX);     /* select I/O register */
-       data = inb(ALI_CIO_DATA);
-
-       return data & bit;
-}
-
-
-#endif
diff --git a/drivers/at45.c b/drivers/at45.c
deleted file mode 100644 (file)
index dac987a..0000000
+++ /dev/null
@@ -1,562 +0,0 @@
-/* Driver for ATMEL DataFlash support
- * Author : Hamid Ikdoumi (Atmel)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- */
-
-#include <config.h>
-#include <common.h>
-
-#ifdef CONFIG_HAS_DATAFLASH
-#include <dataflash.h>
-
-/*
- * spi.c API
- */
-extern unsigned int AT91F_SpiWrite(AT91PS_DataflashDesc pDesc);
-extern void AT91F_SpiEnable(int cs);
-
-#define AT91C_TIMEOUT_WRDY                     200000
-
-/*----------------------------------------------------------------------*/
-/* \fn    AT91F_DataFlashSendCommand                                   */
-/* \brief Generic function to send a command to the dataflash          */
-/*----------------------------------------------------------------------*/
-AT91S_DataFlashStatus AT91F_DataFlashSendCommand(AT91PS_DataFlash pDataFlash,
-                                                unsigned char OpCode,
-                                                unsigned int CmdSize,
-                                                unsigned int DataflashAddress)
-{
-       unsigned int adr;
-
-       if ((pDataFlash->pDataFlashDesc->state) != IDLE)
-               return DATAFLASH_BUSY;
-
-       /* process the address to obtain page address and byte address */
-       adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) <<
-               pDataFlash->pDevice->page_offset) +
-                       (DataflashAddress % (pDataFlash->pDevice->pages_size));
-
-       /* fill the command buffer */
-       pDataFlash->pDataFlashDesc->command[0] = OpCode;
-       if (pDataFlash->pDevice->pages_number >= 16384) {
-               pDataFlash->pDataFlashDesc->command[1] =
-                       (unsigned char)((adr & 0x0F000000) >> 24);
-               pDataFlash->pDataFlashDesc->command[2] =
-                       (unsigned char)((adr & 0x00FF0000) >> 16);
-               pDataFlash->pDataFlashDesc->command[3] =
-                       (unsigned char)((adr & 0x0000FF00) >> 8);
-               pDataFlash->pDataFlashDesc->command[4] =
-                       (unsigned char)(adr & 0x000000FF);
-       } else {
-               pDataFlash->pDataFlashDesc->command[1] =
-                       (unsigned char)((adr & 0x00FF0000) >> 16);
-               pDataFlash->pDataFlashDesc->command[2] =
-                       (unsigned char)((adr & 0x0000FF00) >> 8);
-               pDataFlash->pDataFlashDesc->command[3] =
-                       (unsigned char)(adr & 0x000000FF);
-               pDataFlash->pDataFlashDesc->command[4] = 0;
-       }
-       pDataFlash->pDataFlashDesc->command[5] = 0;
-       pDataFlash->pDataFlashDesc->command[6] = 0;
-       pDataFlash->pDataFlashDesc->command[7] = 0;
-
-       /* Initialize the SpiData structure for the spi write fuction */
-       pDataFlash->pDataFlashDesc->tx_cmd_pt =
-               pDataFlash->pDataFlashDesc->command;
-       pDataFlash->pDataFlashDesc->tx_cmd_size = CmdSize;
-       pDataFlash->pDataFlashDesc->rx_cmd_pt =
-               pDataFlash->pDataFlashDesc->command;
-       pDataFlash->pDataFlashDesc->rx_cmd_size = CmdSize;
-
-       /* send the command and read the data */
-       return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
-}
-
-/*----------------------------------------------------------------------*/
-/* \fn    AT91F_DataFlashGetStatus                                     */
-/* \brief Read the status register of the dataflash                    */
-/*----------------------------------------------------------------------*/
-AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
-{
-       AT91S_DataFlashStatus status;
-
-       /* if a transfert is in progress ==> return 0 */
-       if ((pDesc->state) != IDLE)
-               return DATAFLASH_BUSY;
-
-       /* first send the read status command (D7H) */
-       pDesc->command[0] = DB_STATUS;
-       pDesc->command[1] = 0;
-
-       pDesc->DataFlash_state = GET_STATUS;
-       pDesc->tx_data_size = 0;        /* Transmit the command */
-       /* and receive response */
-       pDesc->tx_cmd_pt = pDesc->command;
-       pDesc->rx_cmd_pt = pDesc->command;
-       pDesc->rx_cmd_size = 2;
-       pDesc->tx_cmd_size = 2;
-       status = AT91F_SpiWrite(pDesc);
-
-       pDesc->DataFlash_state = *((unsigned char *)(pDesc->rx_cmd_pt) + 1);
-
-       return status;
-}
-
-/*----------------------------------------------------------------------*/
-/* \fn    AT91F_DataFlashWaitReady                                     */
-/* \brief wait for dataflash ready (bit7 of the status register == 1)  */
-/*----------------------------------------------------------------------*/
-AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc
-                                               pDataFlashDesc,
-                                               unsigned int timeout)
-{
-       pDataFlashDesc->DataFlash_state = IDLE;
-
-       do {
-               AT91F_DataFlashGetStatus(pDataFlashDesc);
-               timeout--;
-       } while (((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) &&
-                (timeout > 0));
-
-       if ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
-               return DATAFLASH_ERROR;
-
-       return DATAFLASH_OK;
-}
-
-/*--------------------------------------------------------------------------*/
-/* Function Name       : AT91F_DataFlashContinuousRead                             */
-/* Object              : Continuous stream Read                            */
-/* Input Parameters    : DataFlash Service                                 */
-/*                                             : <src> = dataflash address */
-/*                     : <*dataBuffer> = data buffer pointer               */
-/*                     : <sizeToRead> = data buffer size                   */
-/* Return value                : State of the dataflash                            */
-/*--------------------------------------------------------------------------*/
-AT91S_DataFlashStatus AT91F_DataFlashContinuousRead(
-                               AT91PS_DataFlash pDataFlash,
-                               int src,
-                               unsigned char *dataBuffer,
-                               int sizeToRead)
-{
-       AT91S_DataFlashStatus status;
-       /* Test the size to read in the device */
-       if ((src + sizeToRead) >
-                       (pDataFlash->pDevice->pages_size *
-                               (pDataFlash->pDevice->pages_number)))
-               return DATAFLASH_MEMORY_OVERFLOW;
-
-       pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
-       pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead;
-       pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
-       pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;
-
-       status = AT91F_DataFlashSendCommand(
-                       pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src);
-       /* Send the command to the dataflash */
-       return (status);
-}
-
-/*---------------------------------------------------------------------------*/
-/* Function Name       : AT91F_DataFlashPagePgmBuf                          */
-/* Object              : Main memory page program thru buffer 1 or buffer 2  */
-/* Input Parameters    : DataFlash Service                                  */
-/*                                             : <*src> = Source buffer     */
-/*                     : <dest> = dataflash destination address                     */
-/*                     : <SizeToWrite> = data buffer size                   */
-/* Return value                : State of the dataflash                             */
-/*---------------------------------------------------------------------------*/
-AT91S_DataFlashStatus AT91F_DataFlashPagePgmBuf(AT91PS_DataFlash pDataFlash,
-                                               unsigned char *src,
-                                               unsigned int dest,
-                                               unsigned int SizeToWrite)
-{
-       int cmdsize;
-       pDataFlash->pDataFlashDesc->tx_data_pt = src;
-       pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite;
-       pDataFlash->pDataFlashDesc->rx_data_pt = src;
-       pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
-
-       cmdsize = 4;
-       /* Send the command to the dataflash */
-       if (pDataFlash->pDevice->pages_number >= 16384)
-               cmdsize = 5;
-       return (AT91F_DataFlashSendCommand(
-                       pDataFlash, DB_PAGE_PGM_BUF1, cmdsize, dest));
-}
-
-/*---------------------------------------------------------------------------*/
-/* Function Name       : AT91F_MainMemoryToBufferTransfert                  */
-/* Object              : Read a page in the SRAM Buffer 1 or 2              */
-/* Input Parameters    : DataFlash Service                                  */
-/*                     : Page concerned                                             */
-/*                     :                                                    */
-/* Return value                : State of the dataflash                             */
-/*---------------------------------------------------------------------------*/
-AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfert(
-                                       AT91PS_DataFlash
-                                       pDataFlash,
-                                       unsigned char
-                                       BufferCommand,
-                                       unsigned int page)
-{
-       int cmdsize;
-       /* Test if the buffer command is legal */
-       if ((BufferCommand != DB_PAGE_2_BUF1_TRF) &&
-                       (BufferCommand != DB_PAGE_2_BUF2_TRF)) {
-               return DATAFLASH_BAD_COMMAND;
-       }
-
-       /* no data to transmit or receive */
-       pDataFlash->pDataFlashDesc->tx_data_size = 0;
-       cmdsize = 4;
-       if (pDataFlash->pDevice->pages_number >= 16384)
-               cmdsize = 5;
-       return (AT91F_DataFlashSendCommand(
-                       pDataFlash, BufferCommand, cmdsize,
-                       page * pDataFlash->pDevice->pages_size));
-}
-
-/*-------------------------------------------------------------------------- */
-/* Function Name       : AT91F_DataFlashWriteBuffer                         */
-/* Object              : Write data to the internal sram buffer 1 or 2      */
-/* Input Parameters    : DataFlash Service                                  */
-/*                     : <BufferCommand> = command to write buffer1 or 2    */
-/*                     : <*dataBuffer> = data buffer to write               */
-/*                     : <bufferAddress> = address in the internal buffer    */
-/*                     : <SizeToWrite> = data buffer size                   */
-/* Return value                : State of the dataflash                             */
-/*---------------------------------------------------------------------------*/
-AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer(
-                                       AT91PS_DataFlash pDataFlash,
-                                       unsigned char BufferCommand,
-                                       unsigned char *dataBuffer,
-                                       unsigned int bufferAddress,
-                                       int SizeToWrite)
-{
-       int cmdsize;
-       /* Test if the buffer command is legal */
-       if ((BufferCommand != DB_BUF1_WRITE) &&
-                       (BufferCommand != DB_BUF2_WRITE)) {
-               return DATAFLASH_BAD_COMMAND;
-       }
-
-       /* buffer address must be lower than page size */
-       if (bufferAddress > pDataFlash->pDevice->pages_size)
-               return DATAFLASH_BAD_ADDRESS;
-
-       if ((pDataFlash->pDataFlashDesc->state) != IDLE)
-               return DATAFLASH_BUSY;
-
-       /* Send first Write Command */
-       pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
-       pDataFlash->pDataFlashDesc->command[1] = 0;
-       if (pDataFlash->pDevice->pages_number >= 16384) {
-               pDataFlash->pDataFlashDesc->command[2] = 0;
-               pDataFlash->pDataFlashDesc->command[3] =
-                       (unsigned char)(((unsigned int)(bufferAddress &
-                                                       pDataFlash->pDevice->
-                                                       byte_mask)) >> 8);
-               pDataFlash->pDataFlashDesc->command[4] =
-                       (unsigned char)((unsigned int)bufferAddress & 0x00FF);
-               cmdsize = 5;
-       } else {
-               pDataFlash->pDataFlashDesc->command[2] =
-                       (unsigned char)(((unsigned int)(bufferAddress &
-                                                       pDataFlash->pDevice->
-                                                       byte_mask)) >> 8);
-               pDataFlash->pDataFlashDesc->command[3] =
-                       (unsigned char)((unsigned int)bufferAddress & 0x00FF);
-               pDataFlash->pDataFlashDesc->command[4] = 0;
-               cmdsize = 4;
-       }
-
-       pDataFlash->pDataFlashDesc->tx_cmd_pt =
-               pDataFlash->pDataFlashDesc->command;
-       pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize;
-       pDataFlash->pDataFlashDesc->rx_cmd_pt =
-               pDataFlash->pDataFlashDesc->command;
-       pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize;
-
-       pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
-       pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
-       pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
-       pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite;
-
-       return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
-}
-
-/*---------------------------------------------------------------------------*/
-/* Function Name       : AT91F_PageErase                                     */
-/* Object              : Erase a page                                       */
-/* Input Parameters    : DataFlash Service                                  */
-/*                     : Page concerned                                             */
-/*                     :                                                    */
-/* Return value                : State of the dataflash                             */
-/*---------------------------------------------------------------------------*/
-AT91S_DataFlashStatus AT91F_PageErase(
-                                       AT91PS_DataFlash pDataFlash,
-                                       unsigned int page)
-{
-       int cmdsize;
-       /* Test if the buffer command is legal */
-       /* no data to transmit or receive */
-       pDataFlash->pDataFlashDesc->tx_data_size = 0;
-
-       cmdsize = 4;
-       if (pDataFlash->pDevice->pages_number >= 16384)
-               cmdsize = 5;
-       return (AT91F_DataFlashSendCommand(pDataFlash,
-                               DB_PAGE_ERASE, cmdsize,
-                               page * pDataFlash->pDevice->pages_size));
-}
-
-/*---------------------------------------------------------------------------*/
-/* Function Name       : AT91F_BlockErase                                    */
-/* Object              : Erase a Block                                              */
-/* Input Parameters    : DataFlash Service                                  */
-/*                     : Page concerned                                             */
-/*                     :                                                    */
-/* Return value                : State of the dataflash                             */
-/*---------------------------------------------------------------------------*/
-AT91S_DataFlashStatus AT91F_BlockErase(
-                               AT91PS_DataFlash pDataFlash,
-                               unsigned int block)
-{
-       int cmdsize;
-       /* Test if the buffer command is legal */
-       /* no data to transmit or receive */
-       pDataFlash->pDataFlashDesc->tx_data_size = 0;
-       cmdsize = 4;
-       if (pDataFlash->pDevice->pages_number >= 16384)
-               cmdsize = 5;
-       return (AT91F_DataFlashSendCommand(pDataFlash, DB_BLOCK_ERASE, cmdsize,
-                                       block * 8 *
-                                       pDataFlash->pDevice->pages_size));
-}
-
-/*---------------------------------------------------------------------------*/
-/* Function Name       : AT91F_WriteBufferToMain                            */
-/* Object              : Write buffer to the main memory                    */
-/* Input Parameters    : DataFlash Service                                  */
-/*             : <BufferCommand> = command to send to buffer1 or buffer2    */
-/*                     : <dest> = main memory address                       */
-/* Return value                : State of the dataflash                             */
-/*---------------------------------------------------------------------------*/
-AT91S_DataFlashStatus AT91F_WriteBufferToMain(AT91PS_DataFlash pDataFlash,
-                                       unsigned char BufferCommand,
-                                       unsigned int dest)
-{
-       int cmdsize;
-       /* Test if the buffer command is correct */
-       if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
-                       (BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
-                       (BufferCommand != DB_BUF2_PAGE_PGM) &&
-                       (BufferCommand != DB_BUF2_PAGE_ERASE_PGM))
-               return DATAFLASH_BAD_COMMAND;
-
-       /* no data to transmit or receive */
-       pDataFlash->pDataFlashDesc->tx_data_size = 0;
-
-       cmdsize = 4;
-       if (pDataFlash->pDevice->pages_number >= 16384)
-               cmdsize = 5;
-       /* Send the command to the dataflash */
-       return (AT91F_DataFlashSendCommand(pDataFlash, BufferCommand,
-                                               cmdsize, dest));
-}
-
-/*---------------------------------------------------------------------------*/
-/* Function Name       : AT91F_PartialPageWrite                                     */
-/* Object              : Erase partielly a page                                     */
-/* Input Parameters    : <page> = page number                               */
-/*                     : <AdrInpage> = adr to begin the fading              */
-/*                     : <length> = Number of bytes to erase                */
-/*---------------------------------------------------------------------------*/
-AT91S_DataFlashStatus AT91F_PartialPageWrite(AT91PS_DataFlash pDataFlash,
-                                       unsigned char *src,
-                                       unsigned int dest,
-                                       unsigned int size)
-{
-       unsigned int page;
-       unsigned int AdrInPage;
-
-       page = dest / (pDataFlash->pDevice->pages_size);
-       AdrInPage = dest % (pDataFlash->pDevice->pages_size);
-
-       /* Read the contents of the page in the Sram Buffer */
-       AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
-       AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
-                                AT91C_TIMEOUT_WRDY);
-       /*Update the SRAM buffer */
-       AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src,
-                                       AdrInPage, size);
-
-       AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
-                                       AT91C_TIMEOUT_WRDY);
-
-       /* Erase page if a 128 Mbits device */
-       if (pDataFlash->pDevice->pages_number >= 16384) {
-               AT91F_PageErase(pDataFlash, page);
-               /* Rewrite the modified Sram Buffer in the main memory */
-               AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
-                                        AT91C_TIMEOUT_WRDY);
-       }
-
-       /* Rewrite the modified Sram Buffer in the main memory */
-       return (AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM,
-                                       (page *
-                                        pDataFlash->pDevice->pages_size)));
-}
-
-/*---------------------------------------------------------------------------*/
-/* Function Name       : AT91F_DataFlashWrite                               */
-/* Object              :                                                    */
-/* Input Parameters    : <*src> = Source buffer                                     */
-/*                     : <dest> = dataflash adress                          */
-/*                     : <size> = data buffer size                          */
-/*---------------------------------------------------------------------------*/
-AT91S_DataFlashStatus AT91F_DataFlashWrite(AT91PS_DataFlash pDataFlash,
-                                               unsigned char *src,
-                                               int dest, int size)
-{
-       unsigned int length;
-       unsigned int page;
-       unsigned int status;
-
-       AT91F_SpiEnable(pDataFlash->pDevice->cs);
-
-       if ((dest + size) > (pDataFlash->pDevice->pages_size *
-                       (pDataFlash->pDevice->pages_number)))
-               return DATAFLASH_MEMORY_OVERFLOW;
-
-       /* If destination does not fit a page start address */
-       if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size))) != 0) {
-               length =
-                       pDataFlash->pDevice->pages_size -
-                       (dest % ((unsigned int)(pDataFlash->pDevice->pages_size)));
-
-               if (size < length)
-                       length = size;
-
-               if (!AT91F_PartialPageWrite(pDataFlash, src, dest, length))
-                       return DATAFLASH_ERROR;
-
-               AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
-                                        AT91C_TIMEOUT_WRDY);
-
-               /* Update size, source and destination pointers */
-               size -= length;
-               dest += length;
-               src += length;
-       }
-
-       while ((size - pDataFlash->pDevice->pages_size) >= 0) {
-               /* program dataflash page */
-               page = (unsigned int)dest / (pDataFlash->pDevice->pages_size);
-
-               status = AT91F_DataFlashWriteBuffer(pDataFlash,
-                                       DB_BUF1_WRITE, src, 0,
-                                       pDataFlash->pDevice->
-                                       pages_size);
-               AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
-                                        AT91C_TIMEOUT_WRDY);
-
-               status = AT91F_PageErase(pDataFlash, page);
-               AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
-                                        AT91C_TIMEOUT_WRDY);
-               if (!status)
-                       return DATAFLASH_ERROR;
-
-               status = AT91F_WriteBufferToMain(pDataFlash,
-                                        DB_BUF1_PAGE_PGM, dest);
-               if (!status)
-                       return DATAFLASH_ERROR;
-
-               AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
-                                        AT91C_TIMEOUT_WRDY);
-
-               /* Update size, source and destination pointers */
-               size -= pDataFlash->pDevice->pages_size;
-               dest += pDataFlash->pDevice->pages_size;
-               src += pDataFlash->pDevice->pages_size;
-       }
-
-       /* If still some bytes to read */
-       if (size > 0) {
-               /* program dataflash page */
-               if (!AT91F_PartialPageWrite(pDataFlash, src, dest, size))
-                       return DATAFLASH_ERROR;
-
-               AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
-                                        AT91C_TIMEOUT_WRDY);
-       }
-       return DATAFLASH_OK;
-}
-
-/*---------------------------------------------------------------------------*/
-/* Function Name       : AT91F_DataFlashRead                                */
-/* Object              : Read a block in dataflash                          */
-/* Input Parameters    :                                                    */
-/* Return value                :                                                    */
-/*---------------------------------------------------------------------------*/
-int AT91F_DataFlashRead(AT91PS_DataFlash pDataFlash,
-                       unsigned long addr, unsigned long size, char *buffer)
-{
-       unsigned long SizeToRead;
-
-       AT91F_SpiEnable(pDataFlash->pDevice->cs);
-
-       if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
-                                       AT91C_TIMEOUT_WRDY) != DATAFLASH_OK)
-               return -1;
-
-       while (size) {
-               SizeToRead = (size < 0x8000) ? size : 0x8000;
-
-               if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
-                                       AT91C_TIMEOUT_WRDY) !=
-                                               DATAFLASH_OK)
-                       return -1;
-
-               if (AT91F_DataFlashContinuousRead(pDataFlash, addr,
-                                               (uchar *) buffer,
-                                               SizeToRead) != DATAFLASH_OK)
-                       return -1;
-
-               size -= SizeToRead;
-               addr += SizeToRead;
-               buffer += SizeToRead;
-       }
-
-       return DATAFLASH_OK;
-}
-
-/*---------------------------------------------------------------------------*/
-/* Function Name       : AT91F_DataflashProbe                               */
-/* Object              :                                                    */
-/* Input Parameters    :                                                    */
-/* Return value               : Dataflash status register                           */
-/*---------------------------------------------------------------------------*/
-int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc)
-{
-       AT91F_SpiEnable(cs);
-       AT91F_DataFlashGetStatus(pDesc);
-       return ((pDesc->command[1] == 0xFF) ? 0 : pDesc->command[1] & 0x3C);
-}
-#endif
diff --git a/drivers/ata_piix.c b/drivers/ata_piix.c
deleted file mode 100644 (file)
index 42456d7..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (C) Procsys. All rights reserved.
- * Author: Mushtaq Khan <mushtaq_k@procsys.com>
- *                     <mushtaqk_921@yahoo.co.in>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * with the reference to ata_piix driver in kernel 2.4.32
- */
-
-/*
- * This file contains SATA controller and SATA drive initialization functions
- */
-
-#include <common.h>
-#include <pci.h>
-#include <command.h>
-#include <config.h>
-#include <asm/byteorder.h>
-#include <ide.h>
-#include <ata.h>
-
-#ifdef CFG_ATA_PIIX            /*ata_piix driver */
-
-#define DEBUG_SATA 0           /*For debug prints set DEBUG_SATA to 1 */
-
-#define DRV_DECL               /*For file specific declarations */
-#include <sata.h>
-#undef DRV_DECL
-
-/*Macros realted to PCI*/
-#define PCI_SATA_BUS   0x00
-#define PCI_SATA_DEV   0x1f
-#define PCI_SATA_FUNC  0x02
-
-#define PCI_SATA_BASE1 0x10
-#define PCI_SATA_BASE2 0x14
-#define PCI_SATA_BASE3 0x18
-#define PCI_SATA_BASE4 0x1c
-#define PCI_SATA_BASE5 0x20
-#define PCI_PMR         0x90
-#define PCI_PI          0x09
-#define PCI_PCS         0x92
-#define PCI_DMA_CTL     0x48
-
-#define PORT_PRESENT (1<<0)
-#define PORT_ENABLED (1<<4)
-
-u32 bdf;
-u32 iobase1 = 0;               /*Primary cmd block */
-u32 iobase2 = 0;               /*Primary ctl block */
-u32 iobase3 = 0;               /*Sec cmd block */
-u32 iobase4 = 0;               /*sec ctl block */
-u32 iobase5 = 0;               /*BMDMA*/
-int
-pci_sata_init (void)
-{
-       u32 bus = PCI_SATA_BUS;
-       u32 dev = PCI_SATA_DEV;
-       u32 fun = PCI_SATA_FUNC;
-       u16 cmd = 0;
-       u8 lat = 0, pcibios_max_latency = 0xff;
-       u8 pmr;                 /*Port mapping reg */
-       u8 pi;                  /*Prgming Interface reg */
-
-       bdf = PCI_BDF (bus, dev, fun);
-       pci_read_config_dword (bdf, PCI_SATA_BASE1, &iobase1);
-       pci_read_config_dword (bdf, PCI_SATA_BASE2, &iobase2);
-       pci_read_config_dword (bdf, PCI_SATA_BASE3, &iobase3);
-       pci_read_config_dword (bdf, PCI_SATA_BASE4, &iobase4);
-       pci_read_config_dword (bdf, PCI_SATA_BASE5, &iobase5);
-
-       if ((iobase1 == 0xFFFFFFFF) || (iobase2 == 0xFFFFFFFF) ||
-           (iobase3 == 0xFFFFFFFF) || (iobase4 == 0xFFFFFFFF) ||
-           (iobase5 == 0xFFFFFFFF)) {
-               printf ("error no base addr for SATA controller\n");
-               return 1;
-        /*ERROR*/}
-
-       iobase1 &= 0xFFFFFFFE;
-       iobase2 &= 0xFFFFFFFE;
-       iobase3 &= 0xFFFFFFFE;
-       iobase4 &= 0xFFFFFFFE;
-       iobase5 &= 0xFFFFFFFE;
-
-       /*check for mode */
-       pci_read_config_byte (bdf, PCI_PMR, &pmr);
-       if (pmr > 1) {
-               printf ("combined mode not supported\n");
-               return 1;
-       }
-
-       pci_read_config_byte (bdf, PCI_PI, &pi);
-       if ((pi & 0x05) != 0x05) {
-               printf ("Sata is in Legacy mode\n");
-               return 1;
-       } else {
-               printf ("sata is in Native mode\n");
-       }
-
-       /*MASTER CFG AND IO CFG */
-       pci_read_config_word (bdf, PCI_COMMAND, &cmd);
-       cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
-       pci_write_config_word (bdf, PCI_COMMAND, cmd);
-       pci_read_config_byte (dev, PCI_LATENCY_TIMER, &lat);
-
-       if (lat < 16)
-               lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
-       else if (lat > pcibios_max_latency)
-               lat = pcibios_max_latency;
-       pci_write_config_byte (dev, PCI_LATENCY_TIMER, lat);
-
-       return 0;
-}
-
-int
-sata_bus_probe (int port_no)
-{
-       int orig_mask, mask;
-       u16 pcs;
-
-       mask = (PORT_PRESENT << port_no);
-       pci_read_config_word (bdf, PCI_PCS, &pcs);
-       orig_mask = (int) pcs & 0xff;
-       if ((orig_mask & mask) != mask)
-               return 0;
-       else
-               return 1;
-}
-
-int
-init_sata (void)
-{
-       u8 i, rv = 0;
-
-       for (i = 0; i < CFG_SATA_MAXDEVICES; i++) {
-               sata_dev_desc[i].type = DEV_TYPE_UNKNOWN;
-               sata_dev_desc[i].if_type = IF_TYPE_IDE;
-               sata_dev_desc[i].dev = i;
-               sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
-               sata_dev_desc[i].blksz = 0;
-               sata_dev_desc[i].lba = 0;
-               sata_dev_desc[i].block_read = sata_read;
-       }
-
-       rv = pci_sata_init ();
-       if (rv == 1) {
-               printf ("pci initialization failed\n");
-               return 1;
-       }
-
-       port[0].port_no = 0;
-       port[0].ioaddr.cmd_addr = iobase1;
-       port[0].ioaddr.altstatus_addr = port[0].ioaddr.ctl_addr =
-           iobase2 | ATA_PCI_CTL_OFS;
-       port[0].ioaddr.bmdma_addr = iobase5;
-
-       port[1].port_no = 1;
-       port[1].ioaddr.cmd_addr = iobase3;
-       port[1].ioaddr.altstatus_addr = port[1].ioaddr.ctl_addr =
-           iobase4 | ATA_PCI_CTL_OFS;
-       port[1].ioaddr.bmdma_addr = iobase5 + 0x8;
-
-       for (i = 0; i < CFG_SATA_MAXBUS; i++)
-               sata_port (&port[i].ioaddr);
-
-       for (i = 0; i < CFG_SATA_MAXBUS; i++) {
-               if (!(sata_bus_probe (i))) {
-                       port[i].port_state = 0;
-                       printf ("SATA#%d port is not present \n", i);
-               } else {
-                       printf ("SATA#%d port is present\n", i);
-                       if (sata_bus_softreset (i)) {
-                               port[i].port_state = 0;
-                       } else {
-                               port[i].port_state = 1;
-                       }
-               }
-       }
-
-       for (i = 0; i < CFG_SATA_MAXBUS; i++) {
-               u8 j, devno;
-
-               if (port[i].port_state == 0)
-                       continue;
-               for (j = 0; j < CFG_SATA_DEVS_PER_BUS; j++) {
-                       sata_identify (i, j);
-                       set_Feature_cmd (i, j);
-                       devno = i * CFG_SATA_DEVS_PER_BUS + j;
-                       if ((sata_dev_desc[devno].lba > 0) &&
-                           (sata_dev_desc[devno].blksz > 0)) {
-                               dev_print (&sata_dev_desc[devno]);
-                               /* initialize partition type */
-                               init_part (&sata_dev_desc[devno]);
-                               if (curr_dev < 0)
-                                       curr_dev =
-                                           i * CFG_SATA_DEVS_PER_BUS + j;
-                       }
-               }
-       }
-       return 0;
-}
-#endif
diff --git a/drivers/ati_ids.h b/drivers/ati_ids.h
deleted file mode 100644 (file)
index 3e72a7d..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * ATI PCI IDs from XFree86, kept here to make sync'ing with
- * XFree much simpler. Currently, this list is only used by
- * radeonfb
- */
-
-#define PCI_CHIP_RV380_3150             0x3150
-#define PCI_CHIP_RV380_3151             0x3151
-#define PCI_CHIP_RV380_3152             0x3152
-#define PCI_CHIP_RV380_3153             0x3153
-#define PCI_CHIP_RV380_3154             0x3154
-#define PCI_CHIP_RV380_3156             0x3156
-#define PCI_CHIP_RV380_3E50             0x3E50
-#define PCI_CHIP_RV380_3E51             0x3E51
-#define PCI_CHIP_RV380_3E52             0x3E52
-#define PCI_CHIP_RV380_3E53             0x3E53
-#define PCI_CHIP_RV380_3E54             0x3E54
-#define PCI_CHIP_RV380_3E56             0x3E56
-#define PCI_CHIP_RS100_4136            0x4136
-#define PCI_CHIP_RS200_4137            0x4137
-#define PCI_CHIP_R300_AD               0x4144
-#define PCI_CHIP_R300_AE               0x4145
-#define PCI_CHIP_R300_AF               0x4146
-#define PCI_CHIP_R300_AG               0x4147
-#define PCI_CHIP_R350_AH                0x4148
-#define PCI_CHIP_R350_AI                0x4149
-#define PCI_CHIP_R350_AJ                0x414A
-#define PCI_CHIP_R350_AK                0x414B
-#define PCI_CHIP_RV350_AP               0x4150
-#define PCI_CHIP_RV350_AQ               0x4151
-#define PCI_CHIP_RV360_AR               0x4152
-#define PCI_CHIP_RV350_AS               0x4153
-#define PCI_CHIP_RV350_AT               0x4154
-#define PCI_CHIP_RV350_AV               0x4156
-#define PCI_CHIP_MACH32                0x4158
-#define PCI_CHIP_RS250_4237            0x4237
-#define PCI_CHIP_R200_BB               0x4242
-#define PCI_CHIP_R200_BC               0x4243
-#define PCI_CHIP_RS100_4336            0x4336
-#define PCI_CHIP_RS200_4337            0x4337
-#define PCI_CHIP_MACH64CT              0x4354
-#define PCI_CHIP_MACH64CX              0x4358
-#define PCI_CHIP_RS250_4437            0x4437
-#define PCI_CHIP_MACH64ET              0x4554
-#define PCI_CHIP_MACH64GB              0x4742
-#define PCI_CHIP_MACH64GD              0x4744
-#define PCI_CHIP_MACH64GI              0x4749
-#define PCI_CHIP_MACH64GL              0x474C
-#define PCI_CHIP_MACH64GM              0x474D
-#define PCI_CHIP_MACH64GN              0x474E
-#define PCI_CHIP_MACH64GO              0x474F
-#define PCI_CHIP_MACH64GP              0x4750
-#define PCI_CHIP_MACH64GQ              0x4751
-#define PCI_CHIP_MACH64GR              0x4752
-#define PCI_CHIP_MACH64GS              0x4753
-#define PCI_CHIP_MACH64GT              0x4754
-#define PCI_CHIP_MACH64GU              0x4755
-#define PCI_CHIP_MACH64GV              0x4756
-#define PCI_CHIP_MACH64GW              0x4757
-#define PCI_CHIP_MACH64GX              0x4758
-#define PCI_CHIP_MACH64GY              0x4759
-#define PCI_CHIP_MACH64GZ              0x475A
-#define PCI_CHIP_RV250_Id              0x4964
-#define PCI_CHIP_RV250_Ie              0x4965
-#define PCI_CHIP_RV250_If              0x4966
-#define PCI_CHIP_RV250_Ig              0x4967
-#define PCI_CHIP_R420_JH                0x4A48
-#define PCI_CHIP_R420_JI                0x4A49
-#define PCI_CHIP_R420_JJ                0x4A4A
-#define PCI_CHIP_R420_JK                0x4A4B
-#define PCI_CHIP_R420_JL                0x4A4C
-#define PCI_CHIP_R420_JM                0x4A4D
-#define PCI_CHIP_R420_JN                0x4A4E
-#define PCI_CHIP_R420_JP                0x4A50
-#define PCI_CHIP_MACH64LB              0x4C42
-#define PCI_CHIP_MACH64LD              0x4C44
-#define PCI_CHIP_RAGE128LE             0x4C45
-#define PCI_CHIP_RAGE128LF             0x4C46
-#define PCI_CHIP_MACH64LG              0x4C47
-#define PCI_CHIP_MACH64LI              0x4C49
-#define PCI_CHIP_MACH64LM              0x4C4D
-#define PCI_CHIP_MACH64LN              0x4C4E
-#define PCI_CHIP_MACH64LP              0x4C50
-#define PCI_CHIP_MACH64LQ              0x4C51
-#define PCI_CHIP_MACH64LR              0x4C52
-#define PCI_CHIP_MACH64LS              0x4C53
-#define PCI_CHIP_MACH64LT              0x4C54
-#define PCI_CHIP_RADEON_LW             0x4C57
-#define PCI_CHIP_RADEON_LX             0x4C58
-#define PCI_CHIP_RADEON_LY             0x4C59
-#define PCI_CHIP_RADEON_LZ             0x4C5A
-#define PCI_CHIP_RV250_Ld              0x4C64
-#define PCI_CHIP_RV250_Le              0x4C65
-#define PCI_CHIP_RV250_Lf              0x4C66
-#define PCI_CHIP_RV250_Lg              0x4C67
-#define PCI_CHIP_RV250_Ln              0x4C6E
-#define PCI_CHIP_RAGE128MF             0x4D46
-#define PCI_CHIP_RAGE128ML             0x4D4C
-#define PCI_CHIP_R300_ND               0x4E44
-#define PCI_CHIP_R300_NE               0x4E45
-#define PCI_CHIP_R300_NF               0x4E46
-#define PCI_CHIP_R300_NG               0x4E47
-#define PCI_CHIP_R350_NH                0x4E48
-#define PCI_CHIP_R350_NI                0x4E49
-#define PCI_CHIP_R360_NJ                0x4E4A
-#define PCI_CHIP_R350_NK                0x4E4B
-#define PCI_CHIP_RV350_NP               0x4E50
-#define PCI_CHIP_RV350_NQ               0x4E51
-#define PCI_CHIP_RV350_NR               0x4E52
-#define PCI_CHIP_RV350_NS               0x4E53
-#define PCI_CHIP_RV350_NT               0x4E54
-#define PCI_CHIP_RV350_NV               0x4E56
-#define PCI_CHIP_RAGE128PA             0x5041
-#define PCI_CHIP_RAGE128PB             0x5042
-#define PCI_CHIP_RAGE128PC             0x5043
-#define PCI_CHIP_RAGE128PD             0x5044
-#define PCI_CHIP_RAGE128PE             0x5045
-#define PCI_CHIP_RAGE128PF             0x5046
-#define PCI_CHIP_RAGE128PG             0x5047
-#define PCI_CHIP_RAGE128PH             0x5048
-#define PCI_CHIP_RAGE128PI             0x5049
-#define PCI_CHIP_RAGE128PJ             0x504A
-#define PCI_CHIP_RAGE128PK             0x504B
-#define PCI_CHIP_RAGE128PL             0x504C
-#define PCI_CHIP_RAGE128PM             0x504D
-#define PCI_CHIP_RAGE128PN             0x504E
-#define PCI_CHIP_RAGE128PO             0x504F
-#define PCI_CHIP_RAGE128PP             0x5050
-#define PCI_CHIP_RAGE128PQ             0x5051
-#define PCI_CHIP_RAGE128PR             0x5052
-#define PCI_CHIP_RAGE128PS             0x5053
-#define PCI_CHIP_RAGE128PT             0x5054
-#define PCI_CHIP_RAGE128PU             0x5055
-#define PCI_CHIP_RAGE128PV             0x5056
-#define PCI_CHIP_RAGE128PW             0x5057
-#define PCI_CHIP_RAGE128PX             0x5058
-#define PCI_CHIP_RADEON_QD             0x5144
-#define PCI_CHIP_RADEON_QE             0x5145
-#define PCI_CHIP_RADEON_QF             0x5146
-#define PCI_CHIP_RADEON_QG             0x5147
-#define PCI_CHIP_R200_QH               0x5148
-#define PCI_CHIP_R200_QI               0x5149
-#define PCI_CHIP_R200_QJ               0x514A
-#define PCI_CHIP_R200_QK               0x514B
-#define PCI_CHIP_R200_QL               0x514C
-#define PCI_CHIP_R200_QM               0x514D
-#define PCI_CHIP_R200_QN               0x514E
-#define PCI_CHIP_R200_QO               0x514F
-#define PCI_CHIP_RV200_QW              0x5157
-#define PCI_CHIP_RV200_QX              0x5158
-#define PCI_CHIP_RV100_QY              0x5159
-#define PCI_CHIP_RV100_QZ              0x515A
-#define PCI_CHIP_RN50                  0x515E
-#define PCI_CHIP_RAGE128RE             0x5245
-#define PCI_CHIP_RAGE128RF             0x5246
-#define PCI_CHIP_RAGE128RG             0x5247
-#define PCI_CHIP_RAGE128RK             0x524B
-#define PCI_CHIP_RAGE128RL             0x524C
-#define PCI_CHIP_RAGE128SE             0x5345
-#define PCI_CHIP_RAGE128SF             0x5346
-#define PCI_CHIP_RAGE128SG             0x5347
-#define PCI_CHIP_RAGE128SH             0x5348
-#define PCI_CHIP_RAGE128SK             0x534B
-#define PCI_CHIP_RAGE128SL             0x534C
-#define PCI_CHIP_RAGE128SM             0x534D
-#define PCI_CHIP_RAGE128SN             0x534E
-#define PCI_CHIP_RAGE128TF             0x5446
-#define PCI_CHIP_RAGE128TL             0x544C
-#define PCI_CHIP_RAGE128TR             0x5452
-#define PCI_CHIP_RAGE128TS             0x5453
-#define PCI_CHIP_RAGE128TT             0x5454
-#define PCI_CHIP_RAGE128TU             0x5455
-#define PCI_CHIP_RV370_5460             0x5460
-#define PCI_CHIP_RV370_5461             0x5461
-#define PCI_CHIP_RV370_5462             0x5462
-#define PCI_CHIP_RV370_5463             0x5463
-#define PCI_CHIP_RV370_5464             0x5464
-#define PCI_CHIP_RV370_5465             0x5465
-#define PCI_CHIP_RV370_5466             0x5466
-#define PCI_CHIP_RV370_5467             0x5467
-#define PCI_CHIP_R423_UH                0x5548
-#define PCI_CHIP_R423_UI                0x5549
-#define PCI_CHIP_R423_UJ                0x554A
-#define PCI_CHIP_R423_UK                0x554B
-#define PCI_CHIP_R423_UQ                0x5551
-#define PCI_CHIP_R423_UR                0x5552
-#define PCI_CHIP_R423_UT                0x5554
-#define PCI_CHIP_MACH64VT              0x5654
-#define PCI_CHIP_MACH64VU              0x5655
-#define PCI_CHIP_MACH64VV              0x5656
-#define PCI_CHIP_RS300_5834            0x5834
-#define PCI_CHIP_RS300_5835            0x5835
-#define PCI_CHIP_RS300_5836            0x5836
-#define PCI_CHIP_RS300_5837            0x5837
-#define PCI_CHIP_RV370_5B60             0x5B60
-#define PCI_CHIP_RV370_5B61             0x5B61
-#define PCI_CHIP_RV370_5B62             0x5B62
-#define PCI_CHIP_RV370_5B63             0x5B63
-#define PCI_CHIP_RV370_5B64             0x5B64
-#define PCI_CHIP_RV370_5B65             0x5B65
-#define PCI_CHIP_RV370_5B66             0x5B66
-#define PCI_CHIP_RV370_5B67             0x5B67
-#define PCI_CHIP_RV280_5960            0x5960
-#define PCI_CHIP_RV280_5961            0x5961
-#define PCI_CHIP_RV280_5962            0x5962
-#define PCI_CHIP_RV280_5964            0x5964
-#define PCI_CHIP_RV280_5C61            0x5C61
-#define PCI_CHIP_RV280_5C63            0x5C63
-#define PCI_CHIP_R423_5D57              0x5D57
-#define PCI_CHIP_RS350_7834             0x7834
-#define PCI_CHIP_RS350_7835             0x7835
diff --git a/drivers/ati_radeon_fb.c b/drivers/ati_radeon_fb.c
deleted file mode 100644 (file)
index c174f37..0000000
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * ATI Radeon Video card Framebuffer driver.
- *
- * Copyright 2007 Freescale Semiconductor, Inc.
- * Zhang Wei <wei.zhang@freescale.com>
- * Jason Jin <jason.jin@freescale.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * Some codes of this file is partly ported from Linux kernel
- * ATI video framebuffer driver.
- *
- * Now the driver is tested on below ATI chips:
- *   9200
- *   X300
- *   X700
- *
- */
-
-#include <common.h>
-
-#ifdef CONFIG_ATI_RADEON_FB
-
-#include <command.h>
-#include <pci.h>
-#include <asm/processor.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <malloc.h>
-#include <video_fb.h>
-
-#include <radeon.h>
-#include "ati_ids.h"
-#include "ati_radeon_fb.h"
-
-#undef DEBUG
-
-#ifdef DEBUG
-#define DPRINT(x...) printf(x)
-#else
-#define DPRINT(x...) do{}while(0)
-#endif
-
-#ifndef min_t
-#define min_t(type,x,y) \
-       ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
-#endif
-
-#define MAX_MAPPED_VRAM        (2048*2048*4)
-#define MIN_MAPPED_VRAM        (1024*768*1)
-
-/*#define PCI_VENDOR_ID_ATI*/
-#define PCI_CHIP_RV280_5960            0x5960
-#define PCI_CHIP_RV280_5961            0x5961
-#define PCI_CHIP_RV280_5962            0x5962
-#define PCI_CHIP_RV280_5964            0x5964
-#define PCI_CHIP_RV370_5B60            0x5B60
-#define PCI_CHIP_RV380_5657            0x5657
-#define PCI_CHIP_R420_554d             0x554d
-
-static struct pci_device_id ati_radeon_pci_ids[] = {
-       {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5960},
-       {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5961},
-       {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5962},
-       {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5964},
-       {PCI_VENDOR_ID_ATI, PCI_CHIP_RV370_5B60},
-       {PCI_VENDOR_ID_ATI, PCI_CHIP_RV380_5657},
-       {PCI_VENDOR_ID_ATI, PCI_CHIP_R420_554d},
-       {0, 0}
-};
-
-static u16 ati_radeon_id_family_table[][2] = {
-       {PCI_CHIP_RV280_5960, CHIP_FAMILY_RV280},
-       {PCI_CHIP_RV280_5961, CHIP_FAMILY_RV280},
-       {PCI_CHIP_RV280_5962, CHIP_FAMILY_RV280},
-       {PCI_CHIP_RV280_5964, CHIP_FAMILY_RV280},
-       {PCI_CHIP_RV370_5B60, CHIP_FAMILY_RV380},
-       {PCI_CHIP_RV380_5657, CHIP_FAMILY_RV380},
-       {PCI_CHIP_R420_554d,  CHIP_FAMILY_R420},
-       {0, 0}
-};
-
-u16 get_radeon_id_family(u16 device)
-{
-       int i;
-       for (i=0; ati_radeon_id_family_table[0][i]; i+=2)
-               if (ati_radeon_id_family_table[0][i] == device)
-                       return ati_radeon_id_family_table[0][i + 1];
-       return 0;
-}
-
-struct radeonfb_info *rinfo;
-
-static void radeon_identify_vram(struct radeonfb_info *rinfo)
-{
-       u32 tmp;
-
-       /* framebuffer size */
-       if ((rinfo->family == CHIP_FAMILY_RS100) ||
-               (rinfo->family == CHIP_FAMILY_RS200) ||
-               (rinfo->family == CHIP_FAMILY_RS300)) {
-               u32 tom = INREG(NB_TOM);
-               tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
-
-               radeon_fifo_wait(6);
-               OUTREG(MC_FB_LOCATION, tom);
-               OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
-               OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
-               OUTREG(OV0_BASE_ADDR, (tom & 0xffff) << 16);
-
-               /* This is supposed to fix the crtc2 noise problem. */
-               OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000);
-
-               if ((rinfo->family == CHIP_FAMILY_RS100) ||
-                       (rinfo->family == CHIP_FAMILY_RS200)) {
-               /* This is to workaround the asic bug for RMX, some versions
-                  of BIOS dosen't have this register initialized correctly.
-               */
-                       OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN,
-                               ~CRTC_H_CUTOFF_ACTIVE_EN);
-               }
-       } else {
-               tmp = INREG(CONFIG_MEMSIZE);
-       }
-
-       /* mem size is bits [28:0], mask off the rest */
-       rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
-
-       /*
-        * Hack to get around some busted production M6's
-        * reporting no ram
-        */
-       if (rinfo->video_ram == 0) {
-               switch (rinfo->pdev.device) {
-               case PCI_CHIP_RADEON_LY:
-               case PCI_CHIP_RADEON_LZ:
-                       rinfo->video_ram = 8192 * 1024;
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       /*
-        * Now try to identify VRAM type
-        */
-       if ((rinfo->family >= CHIP_FAMILY_R300) ||
-           (INREG(MEM_SDRAM_MODE_REG) & (1<<30)))
-               rinfo->vram_ddr = 1;
-       else
-               rinfo->vram_ddr = 0;
-
-       tmp = INREG(MEM_CNTL);
-       if (IS_R300_VARIANT(rinfo)) {
-               tmp &=  R300_MEM_NUM_CHANNELS_MASK;
-               switch (tmp) {
-               case 0:  rinfo->vram_width = 64; break;
-               case 1:  rinfo->vram_width = 128; break;
-               case 2:  rinfo->vram_width = 256; break;
-               default: rinfo->vram_width = 128; break;
-               }
-       } else if ((rinfo->family == CHIP_FAMILY_RV100) ||
-                  (rinfo->family == CHIP_FAMILY_RS100) ||
-                  (rinfo->family == CHIP_FAMILY_RS200)){
-               if (tmp & RV100_MEM_HALF_MODE)
-                       rinfo->vram_width = 32;
-               else
-                       rinfo->vram_width = 64;
-       } else {
-               if (tmp & MEM_NUM_CHANNELS_MASK)
-                       rinfo->vram_width = 128;
-               else
-                       rinfo->vram_width = 64;
-       }
-
-       /* This may not be correct, as some cards can have half of channel disabled
-        * ToDo: identify these cases
-        */
-
-       DPRINT("radeonfb: Found %ldk of %s %d bits wide videoram\n",
-              rinfo->video_ram / 1024,
-              rinfo->vram_ddr ? "DDR" : "SDRAM",
-              rinfo->vram_width);
-
-}
-
-static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode)
-{
-       int i;
-
-       radeon_fifo_wait(20);
-
-#if 0
-       /* Workaround from XFree */
-       if (rinfo->is_mobility) {
-               /* A temporal workaround for the occational blanking on certain laptop
-                * panels. This appears to related to the PLL divider registers
-                * (fail to lock?). It occurs even when all dividers are the same
-                * with their old settings. In this case we really don't need to
-                * fiddle with PLL registers. By doing this we can avoid the blanking
-                * problem with some panels.
-                */
-               if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) &&
-                   (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) &
-                                         (PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK)))) {
-                       /* We still have to force a switch to selected PPLL div thanks to
-                        * an XFree86 driver bug which will switch it away in some cases
-                        * even when using UseFDev */
-                       OUTREGP(CLOCK_CNTL_INDEX,
-                               mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
-                               ~PPLL_DIV_SEL_MASK);
-                       radeon_pll_errata_after_index(rinfo);
-                       radeon_pll_errata_after_data(rinfo);
-                       return;
-               }
-       }
-#endif
-       if(rinfo->pdev.device == PCI_CHIP_RV370_5B60) return;
-
-       /* Swich VCKL clock input to CPUCLK so it stays fed while PPLL updates*/
-       OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_CPUCLK, ~VCLK_SRC_SEL_MASK);
-
-       /* Reset PPLL & enable atomic update */
-       OUTPLLP(PPLL_CNTL,
-               PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN,
-               ~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
-
-       /* Switch to selected PPLL divider */
-       OUTREGP(CLOCK_CNTL_INDEX,
-               mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
-               ~PPLL_DIV_SEL_MASK);
-
-       /* Set PPLL ref. div */
-       if (rinfo->family == CHIP_FAMILY_R300 ||
-           rinfo->family == CHIP_FAMILY_RS300 ||
-           rinfo->family == CHIP_FAMILY_R350 ||
-           rinfo->family == CHIP_FAMILY_RV350) {
-               if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
-                       /* When restoring console mode, use saved PPLL_REF_DIV
-                        * setting.
-                        */
-                       OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, 0);
-               } else {
-                       /* R300 uses ref_div_acc field as real ref divider */
-                       OUTPLLP(PPLL_REF_DIV,
-                               (mode->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT),
-                               ~R300_PPLL_REF_DIV_ACC_MASK);
-               }
-       } else
-               OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
-
-       /* Set PPLL divider 3 & post divider*/
-       OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
-       OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
-
-       /* Write update */
-       while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R)
-               ;
-       OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W);
-
-       /* Wait read update complete */
-       /* FIXME: Certain revisions of R300 can't recover here.  Not sure of
-          the cause yet, but this workaround will mask the problem for now.
-          Other chips usually will pass at the very first test, so the
-          workaround shouldn't have any effect on them. */
-       for (i = 0; (i < 10000 && INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); i++)
-               ;
-
-       OUTPLL(HTOTAL_CNTL, 0);
-
-       /* Clear reset & atomic update */
-       OUTPLLP(PPLL_CNTL, 0,
-               ~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
-
-       /* We may want some locking ... oh well */
-       udelay(5000);
-
-       /* Switch back VCLK source to PPLL */
-       OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK);
-}
-
-typedef struct {
-       u16 reg;
-       u32 val;
-} reg_val;
-
-
-/* these common regs are cleared before mode setting so they do not
- * interfere with anything
- */
-static reg_val common_regs[] = {
-       { OVR_CLR, 0 },
-       { OVR_WID_LEFT_RIGHT, 0 },
-       { OVR_WID_TOP_BOTTOM, 0 },
-       { OV0_SCALE_CNTL, 0 },
-       { SUBPIC_CNTL, 0 },
-       { VIPH_CONTROL, 0 },
-       { I2C_CNTL_1, 0 },
-       { GEN_INT_CNTL, 0 },
-       { CAP0_TRIG_CNTL, 0 },
-       { CAP1_TRIG_CNTL, 0 },
-};
-
-
-void radeon_setmode(void)
-{
-       int i;
-       struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));
-
-       mode->crtc_gen_cntl = 0x03000200;
-       mode->crtc_ext_cntl = 0x00008048;
-       mode->dac_cntl = 0xff002100;
-       mode->crtc_h_total_disp = 0x4f0063;
-       mode->crtc_h_sync_strt_wid = 0x8c02a2;
-       mode->crtc_v_total_disp = 0x01df020c;
-       mode->crtc_v_sync_strt_wid = 0x8201ea;
-       mode->crtc_pitch = 0x00500050;
-
-       OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
-       OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
-               ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
-       OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
-       OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
-       OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
-       OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
-       OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
-       OUTREG(CRTC_OFFSET, 0);
-       OUTREG(CRTC_OFFSET_CNTL, 0);
-       OUTREG(CRTC_PITCH, mode->crtc_pitch);
-
-       mode->clk_cntl_index = 0x300;
-       mode->ppll_ref_div = 0xc;
-       mode->ppll_div_3 = 0x00030059;
-
-       radeon_write_pll_regs(rinfo, mode);
-}
-
-int radeon_probe(struct radeonfb_info *rinfo)
-{
-       pci_dev_t pdev;
-       u16 did;
-
-       pdev = pci_find_devices(ati_radeon_pci_ids, 0);
-
-       if (pdev != -1) {
-               pci_read_config_word(pdev, PCI_DEVICE_ID, &did);
-               printf("ATI Radeon video card (%04x, %04x) found @(%d:%d:%d)\n",
-                               PCI_VENDOR_ID_ATI, did, (pdev >> 16) & 0xff,
-                               (pdev >> 11) & 0x1f, (pdev >> 8) & 0x7);
-
-               strcpy(rinfo->name, "ATI Radeon");
-               rinfo->pdev.vendor = PCI_VENDOR_ID_ATI;
-               rinfo->pdev.device = did;
-               rinfo->family = get_radeon_id_family(rinfo->pdev.device);
-               pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0,
-                               &rinfo->fb_base_phys);
-               pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2,
-                               &rinfo->mmio_base_phys);
-               rinfo->fb_base_phys &= 0xfffff000;
-               rinfo->mmio_base_phys &= ~0x04;
-
-               rinfo->mmio_base = (void *)rinfo->mmio_base_phys;
-               DPRINT("rinfo->mmio_base = 0x%x\n",rinfo->mmio_base);
-               rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
-               DPRINT("rinfo->fb_local_base = 0x%x\n",rinfo->fb_local_base);
-               /* PostBIOS with x86 emulater */
-               BootVideoCardBIOS(pdev, NULL, 0);
-
-               /*
-                * Check for errata
-                * (These will be added in the future for the chipfamily
-                * R300, RV200, RS200, RV100, RS100.)
-                */
-
-               /* Get VRAM size and type */
-               radeon_identify_vram(rinfo);
-
-               rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM,
-                               rinfo->video_ram);
-               rinfo->fb_base = (void *)rinfo->fb_base_phys;
-
-               DPRINT("Radeon: framebuffer base phy address 0x%08x," \
-                     "MMIO base phy address 0x%08x," \
-                     "framebuffer local base 0x%08x.\n ",
-                     rinfo->fb_base_phys, rinfo->mmio_base_phys,
-                     rinfo->fb_local_base);
-
-               return 0;
-       }
-       return -1;
-}
-
-/*
- * The Graphic Device
- */
-GraphicDevice ctfb;
-
-#define CURSOR_SIZE    0x1000  /* in KByte for HW Cursor */
-#define PATTERN_ADR    (pGD->dprBase + CURSOR_SIZE)    /* pattern Memory after Cursor Memory */
-#define PATTERN_SIZE   8*8*4   /* 4 Bytes per Pixel 8 x 8 Pixel */
-#define ACCELMEMORY    (CURSOR_SIZE + PATTERN_SIZE)    /* reserved Memory for BITBlt and hw cursor */
-
-void *video_hw_init(void)
-{
-       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
-       int i;
-       u32 *vm;
-
-       rinfo = malloc(sizeof(struct radeonfb_info));
-
-       if(radeon_probe(rinfo)) {
-               printf("No radeon video card found!\n");
-               return NULL;
-       }
-
-       /* fill in Graphic device struct */
-       sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", 640,
-                480, 16, (1000 / 1000),
-                (2000 / 1000));
-       printf ("%s\n", pGD->modeIdent);
-
-       pGD->winSizeX = 640;
-       pGD->winSizeY = 480;
-       pGD->plnSizeX = 640;
-       pGD->plnSizeY = 480;
-
-       pGD->gdfBytesPP = 1;
-       pGD->gdfIndex = GDF__8BIT_INDEX;
-
-       pGD->isaBase = CFG_ISA_IO_BASE_ADDRESS;
-       pGD->pciBase = rinfo->fb_base_phys;
-       pGD->frameAdrs = rinfo->fb_base_phys;
-       pGD->memSize = 64 * 1024 * 1024;
-
-       /* Cursor Start Address */
-       pGD->dprBase =
-           (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + rinfo->fb_base_phys;
-       if ((pGD->dprBase & 0x0fff) != 0) {
-               /* allign it */
-               pGD->dprBase &= 0xfffff000;
-               pGD->dprBase += 0x00001000;
-       }
-       DPRINT ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
-               PATTERN_ADR);
-       pGD->vprBase = rinfo->fb_base_phys;     /* Dummy */
-       pGD->cprBase = rinfo->fb_base_phys;     /* Dummy */
-       /* set up Hardware */
-
-       /* Clear video memory */
-       i = pGD->memSize / 4;
-       vm = (unsigned int *) pGD->pciBase;
-       while (i--)
-               *vm++ = 0;
-       /*SetDrawingEngine (bits_per_pixel);*/
-
-       radeon_setmode();
-
-       return ((void *) pGD);
-}
-
-void video_set_lut (unsigned int index,        /* color number */
-              unsigned char r, /* red */
-              unsigned char g, /* green */
-              unsigned char b  /* blue */
-              )
-{
-       OUTREG(PALETTE_INDEX, index);
-       OUTREG(PALETTE_DATA, (r << 16) | (g << 8) | b);
-}
-#endif
diff --git a/drivers/ati_radeon_fb.h b/drivers/ati_radeon_fb.h
deleted file mode 100644 (file)
index b5c4b8b..0000000
+++ /dev/null
@@ -1,282 +0,0 @@
-#ifndef __ATI_RADEON_FB_H
-#define __ATI_RADEON_FB_H
-
-/***************************************************************
- * Most of the definitions here are adapted right from XFree86 *
- ***************************************************************/
-
-/*
- * Chip families. Must fit in the low 16 bits of a long word
- */
-enum radeon_family {
-       CHIP_FAMILY_UNKNOW,
-       CHIP_FAMILY_LEGACY,
-       CHIP_FAMILY_RADEON,
-       CHIP_FAMILY_RV100,
-       CHIP_FAMILY_RS100,    /* U1 (IGP320M) or A3 (IGP320)*/
-       CHIP_FAMILY_RV200,
-       CHIP_FAMILY_RS200,    /* U2 (IGP330M/340M/350M) or A4 (IGP330/340/345/350),
-                                RS250 (IGP 7000) */
-       CHIP_FAMILY_R200,
-       CHIP_FAMILY_RV250,
-       CHIP_FAMILY_RS300,    /* Radeon 9000 IGP */
-       CHIP_FAMILY_RV280,
-       CHIP_FAMILY_R300,
-       CHIP_FAMILY_R350,
-       CHIP_FAMILY_RV350,
-       CHIP_FAMILY_RV380,    /* RV370/RV380/M22/M24 */
-       CHIP_FAMILY_R420,     /* R420/R423/M18 */
-       CHIP_FAMILY_LAST,
-};
-
-#define IS_RV100_VARIANT(rinfo) (((rinfo)->family == CHIP_FAMILY_RV100)  || \
-                                ((rinfo)->family == CHIP_FAMILY_RV200)  || \
-                                ((rinfo)->family == CHIP_FAMILY_RS100)  || \
-                                ((rinfo)->family == CHIP_FAMILY_RS200)  || \
-                                ((rinfo)->family == CHIP_FAMILY_RV250)  || \
-                                ((rinfo)->family == CHIP_FAMILY_RV280)  || \
-                                ((rinfo)->family == CHIP_FAMILY_RS300))
-
-#define IS_R300_VARIANT(rinfo) (((rinfo)->family == CHIP_FAMILY_R300)  || \
-                               ((rinfo)->family == CHIP_FAMILY_RV350) || \
-                               ((rinfo)->family == CHIP_FAMILY_R350)  || \
-                               ((rinfo)->family == CHIP_FAMILY_RV380) || \
-                               ((rinfo)->family == CHIP_FAMILY_R420))
-
-struct radeonfb_info {
-       char name[20];
-
-       struct pci_device_id    pdev;
-       u16                     family;
-
-       u32                     fb_base_phys;
-       u32                     mmio_base_phys;
-
-       void                    *mmio_base;
-       void                    *fb_base;
-
-       u32                     video_ram;
-       u32                     mapped_vram;
-       int                     vram_width;
-       int                     vram_ddr;
-
-       u32                     fb_local_base;
-};
-
-#define INREG8(addr)           readb((rinfo->mmio_base)+addr)
-#define OUTREG8(addr,val)      writeb(val, (rinfo->mmio_base)+addr)
-#define INREG16(addr)          readw((rinfo->mmio_base)+addr)
-#define OUTREG16(addr,val)     writew(val, (rinfo->mmio_base)+addr)
-#define INREG(addr)            readl((rinfo->mmio_base)+addr)
-#define OUTREG(addr,val)       writel(val, (rinfo->mmio_base)+addr)
-
-static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr,
-                      u32 val, u32 mask)
-{
-       unsigned int tmp;
-
-       tmp = INREG(addr);
-       tmp &= (mask);
-       tmp |= (val);
-       OUTREG(addr, tmp);
-}
-
-#define OUTREGP(addr,val,mask) _OUTREGP(rinfo, addr, val,mask)
-
-/*
- * 2D Engine helper routines
- */
-static inline void radeon_engine_flush (struct radeonfb_info *rinfo)
-{
-       int i;
-
-       /* initiate flush */
-       OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
-               ~RB2D_DC_FLUSH_ALL);
-
-       for (i=0; i < 2000000; i++) {
-               if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
-                       return;
-               udelay(1);
-       }
-       printf("radeonfb: Flush Timeout !\n");
-}
-
-static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries)
-{
-       int i;
-
-       for (i=0; i<2000000; i++) {
-               if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
-                       return;
-               udelay(1);
-       }
-       printf("radeonfb: FIFO Timeout !\n");
-}
-
-static inline void _radeon_engine_idle(struct radeonfb_info *rinfo)
-{
-       int i;
-
-       /* ensure FIFO is empty before waiting for idle */
-       _radeon_fifo_wait (rinfo, 64);
-
-       for (i=0; i<2000000; i++) {
-               if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
-                       radeon_engine_flush (rinfo);
-                       return;
-               }
-               udelay(1);
-       }
-       printf("radeonfb: Idle Timeout !\n");
-}
-
-#define radeon_engine_idle()           _radeon_engine_idle(rinfo)
-#define radeon_fifo_wait(entries)      _radeon_fifo_wait(rinfo,entries)
-#define radeon_msleep(ms)              _radeon_msleep(rinfo,ms)
-
-/*
- * This structure contains the various registers manipulated by this
- * driver for setting or restoring a mode. It's mostly copied from
- * XFree's RADEONSaveRec structure. A few chip settings might still be
- * tweaked without beeing reflected or saved in these registers though
- */
-struct radeon_regs {
-       /* Common registers */
-       u32             ovr_clr;
-       u32             ovr_wid_left_right;
-       u32             ovr_wid_top_bottom;
-       u32             ov0_scale_cntl;
-       u32             mpp_tb_config;
-       u32             mpp_gp_config;
-       u32             subpic_cntl;
-       u32             viph_control;
-       u32             i2c_cntl_1;
-       u32             gen_int_cntl;
-       u32             cap0_trig_cntl;
-       u32             cap1_trig_cntl;
-       u32             bus_cntl;
-       u32             surface_cntl;
-       u32             bios_5_scratch;
-
-       /* Other registers to save for VT switches or driver load/unload */
-       u32             dp_datatype;
-       u32             rbbm_soft_reset;
-       u32             clock_cntl_index;
-       u32             amcgpio_en_reg;
-       u32             amcgpio_mask;
-
-       /* Surface/tiling registers */
-       u32             surf_lower_bound[8];
-       u32             surf_upper_bound[8];
-       u32             surf_info[8];
-
-       /* CRTC registers */
-       u32             crtc_gen_cntl;
-       u32             crtc_ext_cntl;
-       u32             dac_cntl;
-       u32             crtc_h_total_disp;
-       u32             crtc_h_sync_strt_wid;
-       u32             crtc_v_total_disp;
-       u32             crtc_v_sync_strt_wid;
-       u32             crtc_offset;
-       u32             crtc_offset_cntl;
-       u32             crtc_pitch;
-       u32             disp_merge_cntl;
-       u32             grph_buffer_cntl;
-       u32             crtc_more_cntl;
-
-       /* CRTC2 registers */
-       u32             crtc2_gen_cntl;
-       u32             dac2_cntl;
-       u32             disp_output_cntl;
-       u32             disp_hw_debug;
-       u32             disp2_merge_cntl;
-       u32             grph2_buffer_cntl;
-       u32             crtc2_h_total_disp;
-       u32             crtc2_h_sync_strt_wid;
-       u32             crtc2_v_total_disp;
-       u32             crtc2_v_sync_strt_wid;
-       u32             crtc2_offset;
-       u32             crtc2_offset_cntl;
-       u32             crtc2_pitch;
-
-       /* Flat panel regs */
-       u32             fp_crtc_h_total_disp;
-       u32             fp_crtc_v_total_disp;
-       u32             fp_gen_cntl;
-       u32             fp2_gen_cntl;
-       u32             fp_h_sync_strt_wid;
-       u32             fp2_h_sync_strt_wid;
-       u32             fp_horz_stretch;
-       u32             fp_panel_cntl;
-       u32             fp_v_sync_strt_wid;
-       u32             fp2_v_sync_strt_wid;
-       u32             fp_vert_stretch;
-       u32             lvds_gen_cntl;
-       u32             lvds_pll_cntl;
-       u32             tmds_crc;
-       u32             tmds_transmitter_cntl;
-
-       /* Computed values for PLL */
-       u32             dot_clock_freq;
-       int             feedback_div;
-       int             post_div;
-
-       /* PLL registers */
-       u32             ppll_div_3;
-       u32             ppll_ref_div;
-       u32             vclk_ecp_cntl;
-       u32             clk_cntl_index;
-
-       /* Computed values for PLL2 */
-       u32             dot_clock_freq_2;
-       int             feedback_div_2;
-       int             post_div_2;
-
-       /* PLL2 registers */
-       u32             p2pll_ref_div;
-       u32             p2pll_div_0;
-       u32             htotal_cntl2;
-
-       /* Palette */
-       int             palette_valid;
-};
-
-static inline u32 __INPLL(struct radeonfb_info *rinfo, u32 addr)
-{
-       u32 data;
-
-       OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f);
-       /* radeon_pll_errata_after_index(rinfo); */
-       data = INREG(CLOCK_CNTL_DATA);
-       /* radeon_pll_errata_after_data(rinfo); */
-       return data;
-}
-
-static inline void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index,
-                           u32 val)
-{
-
-       OUTREG8(CLOCK_CNTL_INDEX, (index & 0x0000003f) | 0x00000080);
-       /* radeon_pll_errata_after_index(rinfo); */
-       OUTREG(CLOCK_CNTL_DATA, val);
-       /* radeon_pll_errata_after_data(rinfo); */
-}
-
-static inline void __OUTPLLP(struct radeonfb_info *rinfo, unsigned int index,
-                            u32 val, u32 mask)
-{
-       unsigned int tmp;
-
-       tmp  = __INPLL(rinfo, index);
-       tmp &= (mask);
-       tmp |= (val);
-       __OUTPLL(rinfo, index, tmp);
-}
-
-#define INPLL(addr)                    __INPLL(rinfo, addr)
-#define OUTPLL(index, val)             __OUTPLL(rinfo, index, val)
-#define OUTPLLP(index, val, mask)      __OUTPLLP(rinfo, index, val, mask)
-
-#endif
diff --git a/drivers/atmel_usart.c b/drivers/atmel_usart.c
deleted file mode 100644 (file)
index f35b997..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2004-2006 Atmel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <common.h>
-
-#ifdef CONFIG_ATMEL_USART
-#include <asm/io.h>
-#include <asm/arch/clk.h>
-#include <asm/arch/memory-map.h>
-
-#if defined(CONFIG_USART0)
-# define USART_ID      0
-# define USART_BASE    USART0_BASE
-#elif defined(CONFIG_USART1)
-# define USART_ID      1
-# define USART_BASE    USART1_BASE
-#elif defined(CONFIG_USART2)
-# define USART_ID      2
-# define USART_BASE    USART2_BASE
-#elif defined(CONFIG_USART3)
-# define USART_ID      3
-# define USART_BASE    USART3_BASE
-#endif
-
-#include "atmel_usart.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-void serial_setbrg(void)
-{
-       unsigned long divisor;
-       unsigned long usart_hz;
-
-       /*
-        *              Master Clock
-        * Baud Rate = --------------
-        *                16 * CD
-        */
-       usart_hz = get_usart_clk_rate(USART_ID);
-       divisor = (usart_hz / 16 + gd->baudrate / 2) / gd->baudrate;
-       usart3_writel(BRGR, USART3_BF(CD, divisor));
-}
-
-int serial_init(void)
-{
-       usart3_writel(CR, USART3_BIT(RSTRX) | USART3_BIT(RSTTX));
-
-       serial_setbrg();
-
-       usart3_writel(CR, USART3_BIT(RXEN) | USART3_BIT(TXEN));
-       usart3_writel(MR, (USART3_BF(USART_MODE, USART3_USART_MODE_NORMAL)
-                          | USART3_BF(USCLKS, USART3_USCLKS_MCK)
-                          | USART3_BF(CHRL, USART3_CHRL_8)
-                          | USART3_BF(PAR, USART3_PAR_NONE)
-                          | USART3_BF(NBSTOP, USART3_NBSTOP_1)));
-
-       return 0;
-}
-
-void serial_putc(char c)
-{
-       if (c == '\n')
-               serial_putc('\r');
-
-       while (!(usart3_readl(CSR) & USART3_BIT(TXRDY))) ;
-       usart3_writel(THR, c);
-}
-
-void serial_puts(const char *s)
-{
-       while (*s)
-               serial_putc(*s++);
-}
-
-int serial_getc(void)
-{
-       while (!(usart3_readl(CSR) & USART3_BIT(RXRDY))) ;
-       return usart3_readl(RHR);
-}
-
-int serial_tstc(void)
-{
-       return (usart3_readl(CSR) & USART3_BIT(RXRDY)) != 0;
-}
-
-#endif /* CONFIG_ATMEL_USART */
diff --git a/drivers/atmel_usart.h b/drivers/atmel_usart.h
deleted file mode 100644 (file)
index af3773a..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Register definitions for the Atmel USART3 module.
- *
- * Copyright (C) 2005-2006 Atmel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __DRIVERS_ATMEL_USART_H__
-#define __DRIVERS_ATMEL_USART_H__
-
-/* USART3 register offsets */
-#define USART3_CR                              0x0000
-#define USART3_MR                              0x0004
-#define USART3_IER                             0x0008
-#define USART3_IDR                             0x000c
-#define USART3_IMR                             0x0010
-#define USART3_CSR                             0x0014
-#define USART3_RHR                             0x0018
-#define USART3_THR                             0x001c
-#define USART3_BRGR                            0x0020
-#define USART3_RTOR                            0x0024
-#define USART3_TTGR                            0x0028
-#define USART3_FIDI                            0x0040
-#define USART3_NER                             0x0044
-#define USART3_XXR                             0x0048
-#define USART3_IFR                             0x004c
-#define USART3_RPR                             0x0100
-#define USART3_RCR                             0x0104
-#define USART3_TPR                             0x0108
-#define USART3_TCR                             0x010c
-#define USART3_RNPR                            0x0110
-#define USART3_RNCR                            0x0114
-#define USART3_TNPR                            0x0118
-#define USART3_TNCR                            0x011c
-#define USART3_PTCR                            0x0120
-#define USART3_PTSR                            0x0124
-
-/* Bitfields in CR */
-#define USART3_RSTRX_OFFSET                    2
-#define USART3_RSTRX_SIZE                      1
-#define USART3_RSTTX_OFFSET                    3
-#define USART3_RSTTX_SIZE                      1
-#define USART3_RXEN_OFFSET                     4
-#define USART3_RXEN_SIZE                       1
-#define USART3_RXDIS_OFFSET                    5
-#define USART3_RXDIS_SIZE                      1
-#define USART3_TXEN_OFFSET                     6
-#define USART3_TXEN_SIZE                       1
-#define USART3_TXDIS_OFFSET                    7
-#define USART3_TXDIS_SIZE                      1
-#define USART3_RSTSTA_OFFSET                   8
-#define USART3_RSTSTA_SIZE                     1
-#define USART3_STTBRK_OFFSET                   9
-#define USART3_STTBRK_SIZE                     1
-#define USART3_STPBRK_OFFSET                   10
-#define USART3_STPBRK_SIZE                     1
-#define USART3_STTTO_OFFSET                    11
-#define USART3_STTTO_SIZE                      1
-#define USART3_SENDA_OFFSET                    12
-#define USART3_SENDA_SIZE                      1
-#define USART3_RSTIT_OFFSET                    13
-#define USART3_RSTIT_SIZE                      1
-#define USART3_RSTNACK_OFFSET                  14
-#define USART3_RSTNACK_SIZE                    1
-#define USART3_RETTO_OFFSET                    15
-#define USART3_RETTO_SIZE                      1
-#define USART3_DTREN_OFFSET                    16
-#define USART3_DTREN_SIZE                      1
-#define USART3_DTRDIS_OFFSET                   17
-#define USART3_DTRDIS_SIZE                     1
-#define USART3_RTSEN_OFFSET                    18
-#define USART3_RTSEN_SIZE                      1
-#define USART3_RTSDIS_OFFSET                   19
-#define USART3_RTSDIS_SIZE                     1
-#define USART3_COMM_TX_OFFSET                  30
-#define USART3_COMM_TX_SIZE                    1
-#define USART3_COMM_RX_OFFSET                  31
-#define USART3_COMM_RX_SIZE                    1
-
-/* Bitfields in MR */
-#define USART3_USART_MODE_OFFSET               0
-#define USART3_USART_MODE_SIZE                 4
-#define USART3_USCLKS_OFFSET                   4
-#define USART3_USCLKS_SIZE                     2
-#define USART3_CHRL_OFFSET                     6
-#define USART3_CHRL_SIZE                       2
-#define USART3_SYNC_OFFSET                     8
-#define USART3_SYNC_SIZE                       1
-#define USART3_PAR_OFFSET                      9
-#define USART3_PAR_SIZE                                3
-#define USART3_NBSTOP_OFFSET                   12
-#define USART3_NBSTOP_SIZE                     2
-#define USART3_CHMODE_OFFSET                   14
-#define USART3_CHMODE_SIZE                     2
-#define USART3_MSBF_OFFSET                     16
-#define USART3_MSBF_SIZE                       1
-#define USART3_MODE9_OFFSET                    17
-#define USART3_MODE9_SIZE                      1
-#define USART3_CLKO_OFFSET                     18
-#define USART3_CLKO_SIZE                       1
-#define USART3_OVER_OFFSET                     19
-#define USART3_OVER_SIZE                       1
-#define USART3_INACK_OFFSET                    20
-#define USART3_INACK_SIZE                      1
-#define USART3_DSNACK_OFFSET                   21
-#define USART3_DSNACK_SIZE                     1
-#define USART3_MAX_ITERATION_OFFSET            24
-#define USART3_MAX_ITERATION_SIZE              3
-#define USART3_FILTER_OFFSET                   28
-#define USART3_FILTER_SIZE                     1
-
-/* Bitfields in CSR */
-#define USART3_RXRDY_OFFSET                    0
-#define USART3_RXRDY_SIZE                      1
-#define USART3_TXRDY_OFFSET                    1
-#define USART3_TXRDY_SIZE                      1
-#define USART3_RXBRK_OFFSET                    2
-#define USART3_RXBRK_SIZE                      1
-#define USART3_ENDRX_OFFSET                    3
-#define USART3_ENDRX_SIZE                      1
-#define USART3_ENDTX_OFFSET                    4
-#define USART3_ENDTX_SIZE                      1
-#define USART3_OVRE_OFFSET                     5
-#define USART3_OVRE_SIZE                       1
-#define USART3_FRAME_OFFSET                    6
-#define USART3_FRAME_SIZE                      1
-#define USART3_PARE_OFFSET                     7
-#define USART3_PARE_SIZE                       1
-#define USART3_TIMEOUT_OFFSET                  8
-#define USART3_TIMEOUT_SIZE                    1
-#define USART3_TXEMPTY_OFFSET                  9
-#define USART3_TXEMPTY_SIZE                    1
-#define USART3_ITERATION_OFFSET                        10
-#define USART3_ITERATION_SIZE                  1
-#define USART3_TXBUFE_OFFSET                   11
-#define USART3_TXBUFE_SIZE                     1
-#define USART3_RXBUFF_OFFSET                   12
-#define USART3_RXBUFF_SIZE                     1
-#define USART3_NACK_OFFSET                     13
-#define USART3_NACK_SIZE                       1
-#define USART3_RIIC_OFFSET                     16
-#define USART3_RIIC_SIZE                       1
-#define USART3_DSRIC_OFFSET                    17
-#define USART3_DSRIC_SIZE                      1
-#define USART3_DCDIC_OFFSET                    18
-#define USART3_DCDIC_SIZE                      1
-#define USART3_CTSIC_OFFSET                    19
-#define USART3_CTSIC_SIZE                      1
-#define USART3_RI_OFFSET                       20
-#define USART3_RI_SIZE                         1
-#define USART3_DSR_OFFSET                      21
-#define USART3_DSR_SIZE                                1
-#define USART3_DCD_OFFSET                      22
-#define USART3_DCD_SIZE                                1
-#define USART3_CTS_OFFSET                      23
-#define USART3_CTS_SIZE                                1
-
-/* Bitfields in RHR */
-#define USART3_RXCHR_OFFSET                    0
-#define USART3_RXCHR_SIZE                      9
-
-/* Bitfields in THR */
-#define USART3_TXCHR_OFFSET                    0
-#define USART3_TXCHR_SIZE                      9
-
-/* Bitfields in BRGR */
-#define USART3_CD_OFFSET                       0
-#define USART3_CD_SIZE                         16
-
-/* Bitfields in RTOR */
-#define USART3_TO_OFFSET                       0
-#define USART3_TO_SIZE                         16
-
-/* Bitfields in TTGR */
-#define USART3_TG_OFFSET                       0
-#define USART3_TG_SIZE                         8
-
-/* Bitfields in FIDI */
-#define USART3_FI_DI_RATIO_OFFSET              0
-#define USART3_FI_DI_RATIO_SIZE                        11
-
-/* Bitfields in NER */
-#define USART3_NB_ERRORS_OFFSET                        0
-#define USART3_NB_ERRORS_SIZE                  8
-
-/* Bitfields in XXR */
-#define USART3_XOFF_OFFSET                     0
-#define USART3_XOFF_SIZE                       8
-#define USART3_XON_OFFSET                      8
-#define USART3_XON_SIZE                                8
-
-/* Bitfields in IFR */
-#define USART3_IRDA_FILTER_OFFSET              0
-#define USART3_IRDA_FILTER_SIZE                        8
-
-/* Bitfields in RCR */
-#define USART3_RXCTR_OFFSET                    0
-#define USART3_RXCTR_SIZE                      16
-
-/* Bitfields in TCR */
-#define USART3_TXCTR_OFFSET                    0
-#define USART3_TXCTR_SIZE                      16
-
-/* Bitfields in RNCR */
-#define USART3_RXNCR_OFFSET                    0
-#define USART3_RXNCR_SIZE                      16
-
-/* Bitfields in TNCR */
-#define USART3_TXNCR_OFFSET                    0
-#define USART3_TXNCR_SIZE                      16
-
-/* Bitfields in PTCR */
-#define USART3_RXTEN_OFFSET                    0
-#define USART3_RXTEN_SIZE                      1
-#define USART3_RXTDIS_OFFSET                   1
-#define USART3_RXTDIS_SIZE                     1
-#define USART3_TXTEN_OFFSET                    8
-#define USART3_TXTEN_SIZE                      1
-#define USART3_TXTDIS_OFFSET                   9
-#define USART3_TXTDIS_SIZE                     1
-
-/* Constants for USART_MODE */
-#define USART3_USART_MODE_NORMAL               0
-#define USART3_USART_MODE_RS485                        1
-#define USART3_USART_MODE_HARDWARE             2
-#define USART3_USART_MODE_MODEM                        3
-#define USART3_USART_MODE_ISO7816_T0           4
-#define USART3_USART_MODE_ISO7816_T1           6
-#define USART3_USART_MODE_IRDA                 8
-
-/* Constants for USCLKS */
-#define USART3_USCLKS_MCK                      0
-#define USART3_USCLKS_MCK_DIV                  1
-#define USART3_USCLKS_SCK                      3
-
-/* Constants for CHRL */
-#define USART3_CHRL_5                          0
-#define USART3_CHRL_6                          1
-#define USART3_CHRL_7                          2
-#define USART3_CHRL_8                          3
-
-/* Constants for PAR */
-#define USART3_PAR_EVEN                                0
-#define USART3_PAR_ODD                         1
-#define USART3_PAR_SPACE                       2
-#define USART3_PAR_MARK                                3
-#define USART3_PAR_NONE                                4
-#define USART3_PAR_MULTI                       6
-
-/* Constants for NBSTOP */
-#define USART3_NBSTOP_1                                0
-#define USART3_NBSTOP_1_5                      1
-#define USART3_NBSTOP_2                                2
-
-/* Constants for CHMODE */
-#define USART3_CHMODE_NORMAL                   0
-#define USART3_CHMODE_ECHO                     1
-#define USART3_CHMODE_LOCAL_LOOP               2
-#define USART3_CHMODE_REMOTE_LOOP              3
-
-/* Constants for MSBF */
-#define USART3_MSBF_LSBF                       0
-#define USART3_MSBF_MSBF                       1
-
-/* Constants for OVER */
-#define USART3_OVER_X16                                0
-#define USART3_OVER_X8                         1
-
-/* Constants for CD */
-#define USART3_CD_DISABLE                      0
-#define USART3_CD_BYPASS                       1
-
-/* Constants for TO */
-#define USART3_TO_DISABLE                      0
-
-/* Constants for TG */
-#define USART3_TG_DISABLE                      0
-
-/* Constants for FI_DI_RATIO */
-#define USART3_FI_DI_RATIO_DISABLE             0
-
-/* Bit manipulation macros */
-#define USART3_BIT(name)                               \
-       (1 << USART3_##name##_OFFSET)
-#define USART3_BF(name,value)                          \
-       (((value) & ((1 << USART3_##name##_SIZE) - 1))  \
-        << USART3_##name##_OFFSET)
-#define USART3_BFEXT(name,value)                       \
-       (((value) >> USART3_##name##_OFFSET)            \
-        & ((1 << USART3_##name##_SIZE) - 1))
-#define USART3_BFINS(name,value,old)                   \
-       (((old) & ~(((1 << USART3_##name##_SIZE) - 1)   \
-                   << USART3_##name##_OFFSET))         \
-        | USART3_BF(name,value))
-
-/* Register access macros */
-#define usart3_readl(reg)                              \
-       readl((void *)USART_BASE + USART3_##reg)
-#define usart3_writel(reg,value)                       \
-       writel((value), (void *)USART_BASE + USART3_##reg)
-
-#endif /* __DRIVERS_ATMEL_USART_H__ */
diff --git a/drivers/bcm570x.c b/drivers/bcm570x.c
deleted file mode 100644 (file)
index c8f4064..0000000
+++ /dev/null
@@ -1,1603 +0,0 @@
-/*
- * Broadcom BCM570x Ethernet Driver for U-Boot.
- * Support 5701, 5702, 5703, and 5704. Single instance driver.
- * Copyright (C) 2002 James F. Dougherty (jfd@broadcom.com)
- */
-
-#include <common.h>
-
-#if defined(CONFIG_CMD_NET) \
-       && (!defined(CONFIG_NET_MULTI)) && defined(CONFIG_BCM570x)
-
-#ifdef CONFIG_BMW
-#include <mpc824x.h>
-#endif
-#include <net.h>
-#include "bcm570x_mm.h"
-#include "bcm570x_autoneg.h"
-#include <pci.h>
-#include <malloc.h>
-
-/*
- * PCI Registers and definitions.
- */
-#define PCI_CMD_MASK   0xffff0000      /* mask to save status bits */
-#define PCI_ANY_ID (~0)
-
-/*
- * PCI memory base for Ethernet device as well as device Interrupt.
- */
-#define BCM570X_MBAR   0x80100000
-#define BCM570X_ILINE   1
-
-#define SECOND_USEC    1000000
-#define MAX_PACKET_SIZE 1600
-#define MAX_UNITS       4
-
-/* Globals to this module */
-int initialized = 0;
-unsigned int ioBase = 0;
-volatile PLM_DEVICE_BLOCK pDevice = NULL;      /* 570x softc */
-volatile PUM_DEVICE_BLOCK pUmDevice = NULL;
-
-/* Used to pass the full-duplex flag, etc. */
-int line_speed[MAX_UNITS] = { 0, 0, 0, 0 };
-static int full_duplex[MAX_UNITS] = { 1, 1, 1, 1 };
-static int rx_flow_control[MAX_UNITS] = { 0, 0, 0, 0 };
-static int tx_flow_control[MAX_UNITS] = { 0, 0, 0, 0 };
-static int auto_flow_control[MAX_UNITS] = { 0, 0, 0, 0 };
-static int tx_checksum[MAX_UNITS] = { 1, 1, 1, 1 };
-static int rx_checksum[MAX_UNITS] = { 1, 1, 1, 1 };
-static int auto_speed[MAX_UNITS] = { 1, 1, 1, 1 };
-
-#if JUMBO_FRAMES
-/* Jumbo MTU for interfaces. */
-static int mtu[MAX_UNITS] = { 0, 0, 0, 0 };
-#endif
-
-/* Turn on Wake-on lan for a device unit */
-static int enable_wol[MAX_UNITS] = { 0, 0, 0, 0 };
-
-#define TX_DESC_CNT DEFAULT_TX_PACKET_DESC_COUNT
-static unsigned int tx_pkt_desc_cnt[MAX_UNITS] =
-    { TX_DESC_CNT, TX_DESC_CNT, TX_DESC_CNT, TX_DESC_CNT };
-
-#define RX_DESC_CNT DEFAULT_STD_RCV_DESC_COUNT
-static unsigned int rx_std_desc_cnt[MAX_UNITS] =
-    { RX_DESC_CNT, RX_DESC_CNT, RX_DESC_CNT, RX_DESC_CNT };
-
-static unsigned int rx_adaptive_coalesce[MAX_UNITS] = { 1, 1, 1, 1 };
-
-#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
-#define JBO_DESC_CNT DEFAULT_JUMBO_RCV_DESC_COUNT
-static unsigned int rx_jumbo_desc_cnt[MAX_UNITS] =
-    { JBO_DESC_CNT, JBO_DESC_CNT, JBO_DESC_CNT, JBO_DESC_CNT };
-#endif
-#define RX_COAL_TK DEFAULT_RX_COALESCING_TICKS
-static unsigned int rx_coalesce_ticks[MAX_UNITS] =
-    { RX_COAL_TK, RX_COAL_TK, RX_COAL_TK, RX_COAL_TK };
-
-#define RX_COAL_FM DEFAULT_RX_MAX_COALESCED_FRAMES
-static unsigned int rx_max_coalesce_frames[MAX_UNITS] =
-    { RX_COAL_FM, RX_COAL_FM, RX_COAL_FM, RX_COAL_FM };
-
-#define TX_COAL_TK DEFAULT_TX_COALESCING_TICKS
-static unsigned int tx_coalesce_ticks[MAX_UNITS] =
-    { TX_COAL_TK, TX_COAL_TK, TX_COAL_TK, TX_COAL_TK };
-
-#define TX_COAL_FM DEFAULT_TX_MAX_COALESCED_FRAMES
-static unsigned int tx_max_coalesce_frames[MAX_UNITS] =
-    { TX_COAL_FM, TX_COAL_FM, TX_COAL_FM, TX_COAL_FM };
-
-#define ST_COAL_TK DEFAULT_STATS_COALESCING_TICKS
-static unsigned int stats_coalesce_ticks[MAX_UNITS] =
-    { ST_COAL_TK, ST_COAL_TK, ST_COAL_TK, ST_COAL_TK };
-
-/*
- * Legitimate values for BCM570x device types
- */
-typedef enum {
-       BCM5700VIGIL = 0,
-       BCM5700A6,
-       BCM5700T6,
-       BCM5700A9,
-       BCM5700T9,
-       BCM5700,
-       BCM5701A5,
-       BCM5701T1,
-       BCM5701T8,
-       BCM5701A7,
-       BCM5701A10,
-       BCM5701A12,
-       BCM5701,
-       BCM5702,
-       BCM5703,
-       BCM5703A31,
-       TC996T,
-       TC996ST,
-       TC996SSX,
-       TC996SX,
-       TC996BT,
-       TC997T,
-       TC997SX,
-       TC1000T,
-       TC940BR01,
-       TC942BR01,
-       NC6770,
-       NC7760,
-       NC7770,
-       NC7780
-} board_t;
-
-/* Chip-Rev names for each device-type */
-static struct {
-       char *name;
-} chip_rev[] = {
-       {
-       "BCM5700VIGIL"}, {
-       "BCM5700A6"}, {
-       "BCM5700T6"}, {
-       "BCM5700A9"}, {
-       "BCM5700T9"}, {
-       "BCM5700"}, {
-       "BCM5701A5"}, {
-       "BCM5701T1"}, {
-       "BCM5701T8"}, {
-       "BCM5701A7"}, {
-       "BCM5701A10"}, {
-       "BCM5701A12"}, {
-       "BCM5701"}, {
-       "BCM5702"}, {
-       "BCM5703"}, {
-       "BCM5703A31"}, {
-       "TC996T"}, {
-       "TC996ST"}, {
-       "TC996SSX"}, {
-       "TC996SX"}, {
-       "TC996BT"}, {
-       "TC997T"}, {
-       "TC997SX"}, {
-       "TC1000T"}, {
-       "TC940BR01"}, {
-       "TC942BR01"}, {
-       "NC6770"}, {
-       "NC7760"}, {
-       "NC7770"}, {
-       "NC7780"}, {
-       0}
-};
-
-/* indexed by board_t, above */
-static struct {
-       char *name;
-} board_info[] = {
-       {
-       "Broadcom Vigil B5700 1000Base-T"}, {
-       "Broadcom BCM5700 1000Base-T"}, {
-       "Broadcom BCM5700 1000Base-SX"}, {
-       "Broadcom BCM5700 1000Base-SX"}, {
-       "Broadcom BCM5700 1000Base-T"}, {
-       "Broadcom BCM5700"}, {
-       "Broadcom BCM5701 1000Base-T"}, {
-       "Broadcom BCM5701 1000Base-T"}, {
-       "Broadcom BCM5701 1000Base-T"}, {
-       "Broadcom BCM5701 1000Base-SX"}, {
-       "Broadcom BCM5701 1000Base-T"}, {
-       "Broadcom BCM5701 1000Base-T"}, {
-       "Broadcom BCM5701"}, {
-       "Broadcom BCM5702 1000Base-T"}, {
-       "Broadcom BCM5703 1000Base-T"}, {
-       "Broadcom BCM5703 1000Base-SX"}, {
-       "3Com 3C996 10/100/1000 Server NIC"}, {
-       "3Com 3C996 10/100/1000 Server NIC"}, {
-       "3Com 3C996 Gigabit Fiber-SX Server NIC"}, {
-       "3Com 3C996 Gigabit Fiber-SX Server NIC"}, {
-       "3Com 3C996B Gigabit Server NIC"}, {
-       "3Com 3C997 Gigabit Server NIC"}, {
-       "3Com 3C997 Gigabit Fiber-SX Server NIC"}, {
-       "3Com 3C1000 Gigabit NIC"}, {
-       "3Com 3C940 Gigabit LOM (21X21)"}, {
-       "3Com 3C942 Gigabit LOM (31X31)"}, {
-       "Compaq NC6770 Gigabit Server Adapter"}, {
-       "Compaq NC7760 Gigabit Server Adapter"}, {
-       "Compaq NC7770 Gigabit Server Adapter"}, {
-       "Compaq NC7780 Gigabit Server Adapter"}, {
-0},};
-
-/* PCI Devices which use the 570x chipset */
-struct pci_device_table {
-       unsigned short vendor_id, device_id;    /* Vendor/DeviceID */
-       unsigned short subvendor, subdevice;    /* Subsystem ID's or PCI_ANY_ID */
-       unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */
-       unsigned long board_id; /* Data private to the driver */
-       int io_size, min_latency;
-} bcm570xDevices[] = {
-       {
-       0x14e4, 0x1644, 0x1014, 0x0277, 0, 0, BCM5700VIGIL, 128, 32}, {
-       0x14e4, 0x1644, 0x14e4, 0x1644, 0, 0, BCM5700A6, 128, 32}, {
-       0x14e4, 0x1644, 0x14e4, 0x2, 0, 0, BCM5700T6, 128, 32}, {
-       0x14e4, 0x1644, 0x14e4, 0x3, 0, 0, BCM5700A9, 128, 32}, {
-       0x14e4, 0x1644, 0x14e4, 0x4, 0, 0, BCM5700T9, 128, 32}, {
-       0x14e4, 0x1644, 0x1028, 0xd1, 0, 0, BCM5700, 128, 32}, {
-       0x14e4, 0x1644, 0x1028, 0x0106, 0, 0, BCM5700, 128, 32}, {
-       0x14e4, 0x1644, 0x1028, 0x0109, 0, 0, BCM5700, 128, 32}, {
-       0x14e4, 0x1644, 0x1028, 0x010a, 0, 0, BCM5700, 128, 32}, {
-       0x14e4, 0x1644, 0x10b7, 0x1000, 0, 0, TC996T, 128, 32}, {
-       0x14e4, 0x1644, 0x10b7, 0x1001, 0, 0, TC996ST, 128, 32}, {
-       0x14e4, 0x1644, 0x10b7, 0x1002, 0, 0, TC996SSX, 128, 32}, {
-       0x14e4, 0x1644, 0x10b7, 0x1003, 0, 0, TC997T, 128, 32}, {
-       0x14e4, 0x1644, 0x10b7, 0x1005, 0, 0, TC997SX, 128, 32}, {
-       0x14e4, 0x1644, 0x10b7, 0x1008, 0, 0, TC942BR01, 128, 32}, {
-       0x14e4, 0x1644, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5700, 128, 32}, {
-       0x14e4, 0x1645, 0x14e4, 1, 0, 0, BCM5701A5, 128, 32}, {
-       0x14e4, 0x1645, 0x14e4, 5, 0, 0, BCM5701T1, 128, 32}, {
-       0x14e4, 0x1645, 0x14e4, 6, 0, 0, BCM5701T8, 128, 32}, {
-       0x14e4, 0x1645, 0x14e4, 7, 0, 0, BCM5701A7, 128, 32}, {
-       0x14e4, 0x1645, 0x14e4, 8, 0, 0, BCM5701A10, 128, 32}, {
-       0x14e4, 0x1645, 0x14e4, 0x8008, 0, 0, BCM5701A12, 128, 32}, {
-       0x14e4, 0x1645, 0x0e11, 0xc1, 0, 0, NC6770, 128, 32}, {
-       0x14e4, 0x1645, 0x0e11, 0x7c, 0, 0, NC7770, 128, 32}, {
-       0x14e4, 0x1645, 0x0e11, 0x85, 0, 0, NC7780, 128, 32}, {
-       0x14e4, 0x1645, 0x1028, 0x0121, 0, 0, BCM5701, 128, 32}, {
-       0x14e4, 0x1645, 0x10b7, 0x1004, 0, 0, TC996SX, 128, 32}, {
-       0x14e4, 0x1645, 0x10b7, 0x1006, 0, 0, TC996BT, 128, 32}, {
-       0x14e4, 0x1645, 0x10b7, 0x1007, 0, 0, TC1000T, 128, 32}, {
-       0x14e4, 0x1645, 0x10b7, 0x1008, 0, 0, TC940BR01, 128, 32}, {
-       0x14e4, 0x1645, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5701, 128, 32}, {
-       0x14e4, 0x1646, 0x14e4, 0x8009, 0, 0, BCM5702, 128, 32}, {
-       0x14e4, 0x1646, 0x0e11, 0xbb, 0, 0, NC7760, 128, 32}, {
-       0x14e4, 0x1646, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5702, 128, 32}, {
-       0x14e4, 0x16a6, 0x14e4, 0x8009, 0, 0, BCM5702, 128, 32}, {
-       0x14e4, 0x16a6, 0x0e11, 0xbb, 0, 0, NC7760, 128, 32}, {
-       0x14e4, 0x16a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5702, 128, 32}, {
-       0x14e4, 0x1647, 0x14e4, 0x0009, 0, 0, BCM5703, 128, 32}, {
-       0x14e4, 0x1647, 0x14e4, 0x000a, 0, 0, BCM5703A31, 128, 32}, {
-       0x14e4, 0x1647, 0x14e4, 0x000b, 0, 0, BCM5703, 128, 32}, {
-       0x14e4, 0x1647, 0x14e4, 0x800a, 0, 0, BCM5703, 128, 32}, {
-       0x14e4, 0x1647, 0x0e11, 0x9a, 0, 0, NC7770, 128, 32}, {
-       0x14e4, 0x1647, 0x0e11, 0x99, 0, 0, NC7780, 128, 32}, {
-       0x14e4, 0x1647, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5703, 128, 32}, {
-       0x14e4, 0x16a7, 0x14e4, 0x0009, 0, 0, BCM5703, 128, 32}, {
-       0x14e4, 0x16a7, 0x14e4, 0x000a, 0, 0, BCM5703A31, 128, 32}, {
-       0x14e4, 0x16a7, 0x14e4, 0x000b, 0, 0, BCM5703, 128, 32}, {
-       0x14e4, 0x16a7, 0x14e4, 0x800a, 0, 0, BCM5703, 128, 32}, {
-       0x14e4, 0x16a7, 0x0e11, 0x9a, 0, 0, NC7770, 128, 32}, {
-       0x14e4, 0x16a7, 0x0e11, 0x99, 0, 0, NC7780, 128, 32}, {
-       0x14e4, 0x16a7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5703, 128, 32}
-};
-
-#define n570xDevices   (sizeof(bcm570xDevices)/sizeof(bcm570xDevices[0]))
-
-/*
- * Allocate a packet buffer from the bcm570x packet pool.
- */
-void *bcm570xPktAlloc (int u, int pksize)
-{
-       return malloc (pksize);
-}
-
-/*
- * Free a packet previously allocated from the bcm570x packet
- * buffer pool.
- */
-void bcm570xPktFree (int u, void *p)
-{
-       free (p);
-}
-
-int bcm570xReplenishRxBuffers (PUM_DEVICE_BLOCK pUmDevice)
-{
-       PLM_PACKET pPacket;
-       PUM_PACKET pUmPacket;
-       void *skb;
-       int queue_rx = 0;
-       int ret = 0;
-
-       while ((pUmPacket = (PUM_PACKET)
-               QQ_PopHead (&pUmDevice->rx_out_of_buf_q.Container)) != 0) {
-
-               pPacket = (PLM_PACKET) pUmPacket;
-
-               /* reuse an old skb */
-               if (pUmPacket->skbuff) {
-                       QQ_PushTail (&pDevice->RxPacketFreeQ.Container,
-                                    pPacket);
-                       queue_rx = 1;
-                       continue;
-               }
-               if ((skb = bcm570xPktAlloc (pUmDevice->index,
-                                           pPacket->u.Rx.RxBufferSize + 2)) ==
-                   0) {
-                       QQ_PushHead (&pUmDevice->rx_out_of_buf_q.Container,
-                                    pPacket);
-                       printf ("NOTICE: Out of RX memory.\n");
-                       ret = 1;
-                       break;
-               }
-
-               pUmPacket->skbuff = skb;
-               QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
-               queue_rx = 1;
-       }
-
-       if (queue_rx) {
-               LM_QueueRxPackets (pDevice);
-       }
-
-       return ret;
-}
-
-/*
- * Probe, Map, and Init 570x device.
- */
-int eth_init (bd_t * bis)
-{
-       int i, rv, devFound = FALSE;
-       pci_dev_t devbusfn;
-       unsigned short status;
-
-       /* Find PCI device, if it exists, configure ...  */
-       for (i = 0; i < n570xDevices; i++) {
-               devbusfn = pci_find_device (bcm570xDevices[i].vendor_id,
-                                           bcm570xDevices[i].device_id, 0);
-               if (devbusfn == -1) {
-                       continue;       /* No device of that vendor/device ID */
-               } else {
-
-                       /* Set ILINE */
-                       pci_write_config_byte (devbusfn,
-                                              PCI_INTERRUPT_LINE,
-                                              BCM570X_ILINE);
-
-                       /*
-                        * 0x10 - 0x14 define one 64-bit MBAR.
-                        * 0x14 is the higher-order address bits of the BAR.
-                        */
-                       pci_write_config_dword (devbusfn,
-                                               PCI_BASE_ADDRESS_1, 0);
-
-                       ioBase = BCM570X_MBAR;
-
-                       pci_write_config_dword (devbusfn,
-                                               PCI_BASE_ADDRESS_0, ioBase);
-
-                       /*
-                        * Enable PCI memory, IO, and Master -- don't
-                        * reset any status bits in doing so.
-                        */
-                       pci_read_config_word (devbusfn, PCI_COMMAND, &status);
-
-                       status |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
-
-                       pci_write_config_word (devbusfn, PCI_COMMAND, status);
-
-                       printf
-                           ("\n%s: bus %d, device %d, function %d: MBAR=0x%x\n",
-                            board_info[bcm570xDevices[i].board_id].name,
-                            PCI_BUS (devbusfn), PCI_DEV (devbusfn),
-                            PCI_FUNC (devbusfn), ioBase);
-
-                       /* Allocate once, but always clear on init */
-                       if (!pDevice) {
-                               pDevice = malloc (sizeof (UM_DEVICE_BLOCK));
-                               pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
-                               memset (pDevice, 0x0, sizeof (UM_DEVICE_BLOCK));
-                       }
-
-                       /* Configure pci dev structure */
-                       pUmDevice->pdev = devbusfn;
-                       pUmDevice->index = 0;
-                       pUmDevice->tx_pkt = 0;
-                       pUmDevice->rx_pkt = 0;
-                       devFound = TRUE;
-                       break;
-               }
-       }
-
-       if (!devFound) {
-               printf
-                   ("eth_init: FAILURE: no BCM570x Ethernet devices found.\n");
-               return -1;
-       }
-
-       /* Setup defaults for chip */
-       pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;
-
-       if (pDevice->ChipRevId == T3_CHIP_ID_5700_B0) {
-               pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;
-       } else {
-
-               if (rx_checksum[i]) {
-                       pDevice->TaskToOffload |=
-                           LM_TASK_OFFLOAD_RX_TCP_CHECKSUM |
-                           LM_TASK_OFFLOAD_RX_UDP_CHECKSUM;
-               }
-
-               if (tx_checksum[i]) {
-                       pDevice->TaskToOffload |=
-                           LM_TASK_OFFLOAD_TX_TCP_CHECKSUM |
-                           LM_TASK_OFFLOAD_TX_UDP_CHECKSUM;
-                       pDevice->NoTxPseudoHdrChksum = TRUE;
-               }
-       }
-
-       /* Set Device PCI Memory base address */
-       pDevice->pMappedMemBase = (PLM_UINT8) ioBase;
-
-       /* Pull down adapter info */
-       if ((rv = LM_GetAdapterInfo (pDevice)) != LM_STATUS_SUCCESS) {
-               printf ("bcm570xEnd: LM_GetAdapterInfo failed: rv=%d!\n", rv);
-               return -2;
-       }
-
-       /* Lock not needed */
-       pUmDevice->do_global_lock = 0;
-
-       if (T3_ASIC_REV (pUmDevice->lm_dev.ChipRevId) == T3_ASIC_REV_5700) {
-               /* The 5700 chip works best without interleaved register */
-               /* accesses on certain machines. */
-               pUmDevice->do_global_lock = 1;
-       }
-
-       /* Setup timer delays */
-       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
-               pDevice->UseTaggedStatus = TRUE;
-               pUmDevice->timer_interval = CFG_HZ;
-       } else {
-               pUmDevice->timer_interval = CFG_HZ / 50;
-       }
-
-       /* Grab name .... */
-       pUmDevice->name =
-           (char *)malloc (strlen (board_info[bcm570xDevices[i].board_id].name)
-                           + 1);
-       strcpy (pUmDevice->name, board_info[bcm570xDevices[i].board_id].name);
-
-       memcpy (pDevice->NodeAddress, bis->bi_enetaddr, 6);
-       LM_SetMacAddress (pDevice, bis->bi_enetaddr);
-       /* Init queues  .. */
-       QQ_InitQueue (&pUmDevice->rx_out_of_buf_q.Container,
-                     MAX_RX_PACKET_DESC_COUNT);
-       pUmDevice->rx_last_cnt = pUmDevice->tx_last_cnt = 0;
-
-       /* delay for 4 seconds */
-       pUmDevice->delayed_link_ind = (4 * CFG_HZ) / pUmDevice->timer_interval;
-
-       pUmDevice->adaptive_expiry = CFG_HZ / pUmDevice->timer_interval;
-
-       /* Sometimes we get spurious ints. after reset when link is down. */
-       /* This field tells the isr to service the int. even if there is */
-       /* no status block update. */
-       pUmDevice->adapter_just_inited =
-           (3 * CFG_HZ) / pUmDevice->timer_interval;
-
-       /* Initialize 570x */
-       if (LM_InitializeAdapter (pDevice) != LM_STATUS_SUCCESS) {
-               printf ("ERROR: Adapter initialization failed.\n");
-               return ERROR;
-       }
-
-       /* Enable chip ISR */
-       LM_EnableInterrupt (pDevice);
-
-       /* Clear MC table */
-       LM_MulticastClear (pDevice);
-
-       /* Enable Multicast */
-       LM_SetReceiveMask (pDevice,
-                          pDevice->ReceiveMask | LM_ACCEPT_ALL_MULTICAST);
-
-       pUmDevice->opened = 1;
-       pUmDevice->tx_full = 0;
-       pUmDevice->tx_pkt = 0;
-       pUmDevice->rx_pkt = 0;
-       printf ("eth%d: %s @0x%lx,",
-               pDevice->index, pUmDevice->name, (unsigned long)ioBase);
-       printf ("node addr ");
-       for (i = 0; i < 6; i++) {
-               printf ("%2.2x", pDevice->NodeAddress[i]);
-       }
-       printf ("\n");
-
-       printf ("eth%d: ", pDevice->index);
-       printf ("%s with ", chip_rev[bcm570xDevices[i].board_id].name);
-
-       if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5400_PHY_ID)
-               printf ("Broadcom BCM5400 Copper ");
-       else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
-               printf ("Broadcom BCM5401 Copper ");
-       else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5411_PHY_ID)
-               printf ("Broadcom BCM5411 Copper ");
-       else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5701_PHY_ID)
-               printf ("Broadcom BCM5701 Integrated Copper ");
-       else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5703_PHY_ID)
-               printf ("Broadcom BCM5703 Integrated Copper ");
-       else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM8002_PHY_ID)
-               printf ("Broadcom BCM8002 SerDes ");
-       else if (pDevice->EnableTbi)
-               printf ("Agilent HDMP-1636 SerDes ");
-       else
-               printf ("Unknown ");
-       printf ("transceiver found\n");
-
-       printf ("eth%d: %s, MTU: %d,",
-               pDevice->index, pDevice->BusSpeedStr, 1500);
-
-       if ((pDevice->ChipRevId != T3_CHIP_ID_5700_B0) && rx_checksum[i])
-               printf ("Rx Checksum ON\n");
-       else
-               printf ("Rx Checksum OFF\n");
-       initialized++;
-
-       return 0;
-}
-
-/* Ethernet Interrupt service routine */
-void eth_isr (void)
-{
-       LM_UINT32 oldtag, newtag;
-       int i;
-
-       pUmDevice->interrupt = 1;
-
-       if (pDevice->UseTaggedStatus) {
-               if ((pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_UPDATED) ||
-                   pUmDevice->adapter_just_inited) {
-                       MB_REG_WR (pDevice, Mailbox.Interrupt[0].Low, 1);
-                       oldtag = pDevice->pStatusBlkVirt->StatusTag;
-
-                       for (i = 0;; i++) {
-                               pDevice->pStatusBlkVirt->Status &=
-                                   ~STATUS_BLOCK_UPDATED;
-                               LM_ServiceInterrupts (pDevice);
-                               newtag = pDevice->pStatusBlkVirt->StatusTag;
-                               if ((newtag == oldtag) || (i > 50)) {
-                                       MB_REG_WR (pDevice,
-                                                  Mailbox.Interrupt[0].Low,
-                                                  newtag << 24);
-                                       if (pDevice->UndiFix) {
-                                               REG_WR (pDevice, Grc.LocalCtrl,
-                                                       pDevice->
-                                                       GrcLocalCtrl | 0x2);
-                                       }
-                                       break;
-                               }
-                               oldtag = newtag;
-                       }
-               }
-       } else {
-               while (pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_UPDATED) {
-                       unsigned int dummy;
-
-                       pDevice->pMemView->Mailbox.Interrupt[0].Low = 1;
-                       pDevice->pStatusBlkVirt->Status &=
-                           ~STATUS_BLOCK_UPDATED;
-                       LM_ServiceInterrupts (pDevice);
-                       pDevice->pMemView->Mailbox.Interrupt[0].Low = 0;
-                       dummy = pDevice->pMemView->Mailbox.Interrupt[0].Low;
-               }
-       }
-
-       /* Allocate new RX buffers */
-       if (QQ_GetEntryCnt (&pUmDevice->rx_out_of_buf_q.Container)) {
-               bcm570xReplenishRxBuffers (pUmDevice);
-       }
-
-       /* Queue packets */
-       if (QQ_GetEntryCnt (&pDevice->RxPacketFreeQ.Container)) {
-               LM_QueueRxPackets (pDevice);
-       }
-
-       if (pUmDevice->tx_queued) {
-               pUmDevice->tx_queued = 0;
-       }
-
-       if (pUmDevice->tx_full) {
-               if (pDevice->LinkStatus != LM_STATUS_LINK_DOWN) {
-                       printf
-                           ("NOTICE: tx was previously blocked, restarting MUX\n");
-                       pUmDevice->tx_full = 0;
-               }
-       }
-
-       pUmDevice->interrupt = 0;
-
-}
-
-int eth_send (volatile void *packet, int length)
-{
-       int status = 0;
-#if ET_DEBUG
-       unsigned char *ptr = (unsigned char *)packet;
-#endif
-       PLM_PACKET pPacket;
-       PUM_PACKET pUmPacket;
-
-       /* Link down, return */
-       while (pDevice->LinkStatus == LM_STATUS_LINK_DOWN) {
-#if 0
-               printf ("eth%d: link down - check cable or link partner.\n",
-                       pUmDevice->index);
-#endif
-               eth_isr ();
-
-               /* Wait to see link for one-half a second before sending ... */
-               udelay (1500000);
-
-       }
-
-       /* Clear sent flag */
-       pUmDevice->tx_pkt = 0;
-
-       /* Previously blocked */
-       if (pUmDevice->tx_full) {
-               printf ("eth%d: tx blocked.\n", pUmDevice->index);
-               return 0;
-       }
-
-       pPacket = (PLM_PACKET)
-           QQ_PopHead (&pDevice->TxPacketFreeQ.Container);
-
-       if (pPacket == 0) {
-               pUmDevice->tx_full = 1;
-               printf ("bcm570xEndSend: TX full!\n");
-               return 0;
-       }
-
-       if (pDevice->SendBdLeft.counter == 0) {
-               pUmDevice->tx_full = 1;
-               printf ("bcm570xEndSend: no more TX descriptors!\n");
-               QQ_PushHead (&pDevice->TxPacketFreeQ.Container, pPacket);
-               return 0;
-       }
-
-       if (length <= 0) {
-               printf ("eth: bad packet size: %d\n", length);
-               goto out;
-       }
-
-       /* Get packet buffers and fragment list */
-       pUmPacket = (PUM_PACKET) pPacket;
-       /* Single DMA Descriptor transmit.
-        * Fragments may be provided, but one DMA descriptor max is
-        * used to send the packet.
-        */
-       if (MM_CoalesceTxBuffer (pDevice, pPacket) != LM_STATUS_SUCCESS) {
-               if (pUmPacket->skbuff == NULL) {
-                       /* Packet was discarded */
-                       printf ("TX: failed (1)\n");
-                       status = 1;
-               } else {
-                       printf ("TX: failed (2)\n");
-                       status = 2;
-               }
-               QQ_PushHead (&pDevice->TxPacketFreeQ.Container, pPacket);
-               return status;
-       }
-
-       /* Copy packet to DMA buffer */
-       memset (pUmPacket->skbuff, 0x0, MAX_PACKET_SIZE);
-       memcpy ((void *)pUmPacket->skbuff, (void *)packet, length);
-       pPacket->PacketSize = length;
-       pPacket->Flags |= SND_BD_FLAG_END | SND_BD_FLAG_COAL_NOW;
-       pPacket->u.Tx.FragCount = 1;
-       /* We've already provided a frame ready for transmission */
-       pPacket->Flags &= ~SND_BD_FLAG_TCP_UDP_CKSUM;
-
-       if (LM_SendPacket (pDevice, pPacket) == LM_STATUS_FAILURE) {
-               /*
-                *  A lower level send failure will push the packet descriptor back
-                *  in the free queue, so just deal with the VxWorks clusters.
-                */
-               if (pUmPacket->skbuff == NULL) {
-                       printf ("TX failed (1)!\n");
-                       /* Packet was discarded */
-                       status = 3;
-               } else {
-                       /* A resource problem ... */
-                       printf ("TX failed (2)!\n");
-                       status = 4;
-               }
-
-               if (QQ_GetEntryCnt (&pDevice->TxPacketFreeQ.Container) == 0) {
-                       printf ("TX: emptyQ!\n");
-                       pUmDevice->tx_full = 1;
-               }
-       }
-
-       while (pUmDevice->tx_pkt == 0) {
-               /* Service TX */
-               eth_isr ();
-       }
-#if ET_DEBUG
-       printf ("eth_send: 0x%x, %d bytes\n"
-               "[%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x] ...\n",
-               (int)pPacket, length,
-               ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5],
-               ptr[6], ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12],
-               ptr[13], ptr[14], ptr[15]);
-#endif
-       pUmDevice->tx_pkt = 0;
-       QQ_PushHead (&pDevice->TxPacketFreeQ.Container, pPacket);
-
-       /* Done with send */
-      out:
-       return status;
-}
-
-/* Ethernet receive */
-int eth_rx (void)
-{
-       PLM_PACKET pPacket = NULL;
-       PUM_PACKET pUmPacket = NULL;
-       void *skb;
-       int size = 0;
-
-       while (TRUE) {
-
-             bcm570x_service_isr:
-               /* Pull down packet if it is there */
-               eth_isr ();
-
-               /* Indicate RX packets called */
-               if (pUmDevice->rx_pkt) {
-                       /* printf("eth_rx: got a packet...\n"); */
-                       pUmDevice->rx_pkt = 0;
-               } else {
-                       /* printf("eth_rx: waiting for packet...\n"); */
-                       goto bcm570x_service_isr;
-               }
-
-               pPacket = (PLM_PACKET)
-                   QQ_PopHead (&pDevice->RxPacketReceivedQ.Container);
-
-               if (pPacket == 0) {
-                       printf ("eth_rx: empty packet!\n");
-                       goto bcm570x_service_isr;
-               }
-
-               pUmPacket = (PUM_PACKET) pPacket;
-#if ET_DEBUG
-               printf ("eth_rx: packet @0x%x\n", (int)pPacket);
-#endif
-               /* If the packet generated an error, reuse buffer */
-               if ((pPacket->PacketStatus != LM_STATUS_SUCCESS) ||
-                   ((size = pPacket->PacketSize) > pDevice->RxMtu)) {
-
-                       /* reuse skb */
-                       QQ_PushTail (&pDevice->RxPacketFreeQ.Container,
-                                    pPacket);
-                       printf ("eth_rx: error in packet dma!\n");
-                       goto bcm570x_service_isr;
-               }
-
-               /* Set size and address */
-               skb = pUmPacket->skbuff;
-               size = pPacket->PacketSize;
-
-               /* Pass the packet up to the protocol
-                * layers.
-                */
-               NetReceive (skb, size);
-
-               /* Free packet buffer */
-               bcm570xPktFree (pUmDevice->index, skb);
-               pUmPacket->skbuff = NULL;
-
-               /* Reuse SKB */
-               QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
-
-               return 0;       /* Got a packet, bail ... */
-       }
-       return size;
-}
-
-/* Shut down device */
-void eth_halt (void)
-{
-       int i;
-       if (initialized)
-               if (pDevice && pUmDevice && pUmDevice->opened) {
-                       printf ("\neth%d:%s,", pUmDevice->index,
-                               pUmDevice->name);
-                       printf ("HALT,");
-                       /* stop device */
-                       LM_Halt (pDevice);
-                       printf ("POWER DOWN,");
-                       LM_SetPowerState (pDevice, LM_POWER_STATE_D3);
-
-                       /* Free the memory allocated by the device in tigon3 */
-                       for (i = 0; i < pUmDevice->mem_list_num; i++) {
-                               if (pUmDevice->mem_list[i]) {
-                                       /* sanity check */
-                                       if (pUmDevice->dma_list[i]) {   /* cache-safe memory */
-                                               free (pUmDevice->mem_list[i]);
-                                       } else {
-                                               free (pUmDevice->mem_list[i]);  /* normal memory   */
-                                       }
-                               }
-                       }
-                       pUmDevice->opened = 0;
-                       free (pDevice);
-                       pDevice = NULL;
-                       pUmDevice = NULL;
-                       initialized = 0;
-                       printf ("done - offline.\n");
-               }
-}
-
-/*
- *
- * Middle Module: Interface between the HW driver (tigon3 modules) and
- * the native (SENS) driver.  These routines implement the system
- * interface for tigon3 on VxWorks.
- */
-
-/* Middle module dependency - size of a packet descriptor */
-int MM_Packet_Desc_Size = sizeof (UM_PACKET);
-
-LM_STATUS
-MM_ReadConfig32 (PLM_DEVICE_BLOCK pDevice,
-                LM_UINT32 Offset, LM_UINT32 * pValue32)
-{
-       UM_DEVICE_BLOCK *pUmDevice;
-       pUmDevice = (UM_DEVICE_BLOCK *) pDevice;
-       pci_read_config_dword (pUmDevice->pdev, Offset, (u32 *) pValue32);
-       return LM_STATUS_SUCCESS;
-}
-
-LM_STATUS
-MM_WriteConfig32 (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, LM_UINT32 Value32)
-{
-       UM_DEVICE_BLOCK *pUmDevice;
-       pUmDevice = (UM_DEVICE_BLOCK *) pDevice;
-       pci_write_config_dword (pUmDevice->pdev, Offset, Value32);
-       return LM_STATUS_SUCCESS;
-}
-
-LM_STATUS
-MM_ReadConfig16 (PLM_DEVICE_BLOCK pDevice,
-                LM_UINT32 Offset, LM_UINT16 * pValue16)
-{
-       UM_DEVICE_BLOCK *pUmDevice;
-       pUmDevice = (UM_DEVICE_BLOCK *) pDevice;
-       pci_read_config_word (pUmDevice->pdev, Offset, (u16 *) pValue16);
-       return LM_STATUS_SUCCESS;
-}
-
-LM_STATUS
-MM_WriteConfig16 (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, LM_UINT16 Value16)
-{
-       UM_DEVICE_BLOCK *pUmDevice;
-       pUmDevice = (UM_DEVICE_BLOCK *) pDevice;
-       pci_write_config_word (pUmDevice->pdev, Offset, Value16);
-       return LM_STATUS_SUCCESS;
-}
-
-LM_STATUS
-MM_AllocateSharedMemory (PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
-                        PLM_VOID * pMemoryBlockVirt,
-                        PLM_PHYSICAL_ADDRESS pMemoryBlockPhy, LM_BOOL Cached)
-{
-       PLM_VOID pvirt;
-       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
-       dma_addr_t mapping;
-
-       pvirt = malloc (BlockSize);
-       mapping = (dma_addr_t) (pvirt);
-       if (!pvirt)
-               return LM_STATUS_FAILURE;
-
-       pUmDevice->mem_list[pUmDevice->mem_list_num] = pvirt;
-       pUmDevice->dma_list[pUmDevice->mem_list_num] = mapping;
-       pUmDevice->mem_size_list[pUmDevice->mem_list_num++] = BlockSize;
-       memset (pvirt, 0, BlockSize);
-
-       *pMemoryBlockVirt = (PLM_VOID) pvirt;
-       MM_SetAddr (pMemoryBlockPhy, (dma_addr_t) mapping);
-
-       return LM_STATUS_SUCCESS;
-}
-
-LM_STATUS
-MM_AllocateMemory (PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
-                  PLM_VOID * pMemoryBlockVirt)
-{
-       PLM_VOID pvirt;
-       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
-
-       pvirt = malloc (BlockSize);
-
-       if (!pvirt)
-               return LM_STATUS_FAILURE;
-
-       pUmDevice->mem_list[pUmDevice->mem_list_num] = pvirt;
-       pUmDevice->dma_list[pUmDevice->mem_list_num] = 0;
-       pUmDevice->mem_size_list[pUmDevice->mem_list_num++] = BlockSize;
-       memset (pvirt, 0, BlockSize);
-       *pMemoryBlockVirt = pvirt;
-
-       return LM_STATUS_SUCCESS;
-}
-
-LM_STATUS MM_MapMemBase (PLM_DEVICE_BLOCK pDevice)
-{
-       printf ("BCM570x PCI Memory base address @0x%x\n",
-               (unsigned int)pDevice->pMappedMemBase);
-       return LM_STATUS_SUCCESS;
-}
-
-LM_STATUS MM_InitializeUmPackets (PLM_DEVICE_BLOCK pDevice)
-{
-       int i;
-       void *skb;
-       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
-       PUM_PACKET pUmPacket = NULL;
-       PLM_PACKET pPacket = NULL;
-
-       for (i = 0; i < pDevice->RxPacketDescCnt; i++) {
-               pPacket = QQ_PopHead (&pDevice->RxPacketFreeQ.Container);
-               pUmPacket = (PUM_PACKET) pPacket;
-
-               if (pPacket == 0) {
-                       printf ("MM_InitializeUmPackets: Bad RxPacketFreeQ\n");
-               }
-
-               skb = bcm570xPktAlloc (pUmDevice->index,
-                                      pPacket->u.Rx.RxBufferSize + 2);
-
-               if (skb == 0) {
-                       pUmPacket->skbuff = 0;
-                       QQ_PushTail (&pUmDevice->rx_out_of_buf_q.Container,
-                                    pPacket);
-                       printf ("MM_InitializeUmPackets: out of buffer.\n");
-                       continue;
-               }
-
-               pUmPacket->skbuff = skb;
-               QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
-       }
-
-       pUmDevice->rx_low_buf_thresh = pDevice->RxPacketDescCnt / 8;
-
-       return LM_STATUS_SUCCESS;
-}
-
-LM_STATUS MM_GetConfig (PLM_DEVICE_BLOCK pDevice)
-{
-       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
-       int index = pDevice->index;
-
-       if (auto_speed[index] == 0)
-               pDevice->DisableAutoNeg = TRUE;
-       else
-               pDevice->DisableAutoNeg = FALSE;
-
-       if (line_speed[index] == 0) {
-               pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_AUTO;
-               pDevice->DisableAutoNeg = FALSE;
-       } else {
-               if (line_speed[index] == 1000) {
-                       if (pDevice->EnableTbi) {
-                               pDevice->RequestedMediaType =
-                                   LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS_FULL_DUPLEX;
-                       } else if (full_duplex[index]) {
-                               pDevice->RequestedMediaType =
-                                   LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS_FULL_DUPLEX;
-                       } else {
-                               pDevice->RequestedMediaType =
-                                   LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS;
-                       }
-                       if (!pDevice->EnableTbi)
-                               pDevice->DisableAutoNeg = FALSE;
-               } else if (line_speed[index] == 100) {
-                       if (full_duplex[index]) {
-                               pDevice->RequestedMediaType =
-                                   LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS_FULL_DUPLEX;
-                       } else {
-                               pDevice->RequestedMediaType =
-                                   LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS;
-                       }
-               } else if (line_speed[index] == 10) {
-                       if (full_duplex[index]) {
-                               pDevice->RequestedMediaType =
-                                   LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS_FULL_DUPLEX;
-                       } else {
-                               pDevice->RequestedMediaType =
-                                   LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS;
-                       }
-               } else {
-                       pDevice->RequestedMediaType =
-                           LM_REQUESTED_MEDIA_TYPE_AUTO;
-                       pDevice->DisableAutoNeg = FALSE;
-               }
-
-       }
-       pDevice->FlowControlCap = 0;
-       if (rx_flow_control[index] != 0) {
-               pDevice->FlowControlCap |= LM_FLOW_CONTROL_RECEIVE_PAUSE;
-       }
-       if (tx_flow_control[index] != 0) {
-               pDevice->FlowControlCap |= LM_FLOW_CONTROL_TRANSMIT_PAUSE;
-       }
-       if ((auto_flow_control[index] != 0) &&
-           (pDevice->DisableAutoNeg == FALSE)) {
-
-               pDevice->FlowControlCap |= LM_FLOW_CONTROL_AUTO_PAUSE;
-               if ((tx_flow_control[index] == 0) &&
-                   (rx_flow_control[index] == 0)) {
-                       pDevice->FlowControlCap |=
-                           LM_FLOW_CONTROL_TRANSMIT_PAUSE |
-                           LM_FLOW_CONTROL_RECEIVE_PAUSE;
-               }
-       }
-
-       /* Default MTU for now */
-       pUmDevice->mtu = 1500;
-
-#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
-       if (pUmDevice->mtu > 1500) {
-               pDevice->RxMtu = pUmDevice->mtu;
-               pDevice->RxJumboDescCnt = DEFAULT_JUMBO_RCV_DESC_COUNT;
-       } else {
-               pDevice->RxJumboDescCnt = 0;
-       }
-       pDevice->RxJumboDescCnt = rx_jumbo_desc_cnt[index];
-#else
-       pDevice->RxMtu = pUmDevice->mtu;
-#endif
-
-       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
-               pDevice->UseTaggedStatus = TRUE;
-               pUmDevice->timer_interval = CFG_HZ;
-       } else {
-               pUmDevice->timer_interval = CFG_HZ / 50;
-       }
-
-       pDevice->TxPacketDescCnt = tx_pkt_desc_cnt[index];
-       pDevice->RxStdDescCnt = rx_std_desc_cnt[index];
-       /* Note:  adaptive coalescence really isn't adaptive in this driver */
-       pUmDevice->rx_adaptive_coalesce = rx_adaptive_coalesce[index];
-       if (!pUmDevice->rx_adaptive_coalesce) {
-               pDevice->RxCoalescingTicks = rx_coalesce_ticks[index];
-               if (pDevice->RxCoalescingTicks > MAX_RX_COALESCING_TICKS)
-                       pDevice->RxCoalescingTicks = MAX_RX_COALESCING_TICKS;
-               pUmDevice->rx_curr_coalesce_ticks = pDevice->RxCoalescingTicks;
-
-               pDevice->RxMaxCoalescedFrames = rx_max_coalesce_frames[index];
-               if (pDevice->RxMaxCoalescedFrames > MAX_RX_MAX_COALESCED_FRAMES)
-                       pDevice->RxMaxCoalescedFrames =
-                           MAX_RX_MAX_COALESCED_FRAMES;
-               pUmDevice->rx_curr_coalesce_frames =
-                   pDevice->RxMaxCoalescedFrames;
-               pDevice->StatsCoalescingTicks = stats_coalesce_ticks[index];
-               if (pDevice->StatsCoalescingTicks > MAX_STATS_COALESCING_TICKS)
-                       pDevice->StatsCoalescingTicks =
-                           MAX_STATS_COALESCING_TICKS;
-       } else {
-               pUmDevice->rx_curr_coalesce_frames =
-                   DEFAULT_RX_MAX_COALESCED_FRAMES;
-               pUmDevice->rx_curr_coalesce_ticks = DEFAULT_RX_COALESCING_TICKS;
-       }
-       pDevice->TxCoalescingTicks = tx_coalesce_ticks[index];
-       if (pDevice->TxCoalescingTicks > MAX_TX_COALESCING_TICKS)
-               pDevice->TxCoalescingTicks = MAX_TX_COALESCING_TICKS;
-       pDevice->TxMaxCoalescedFrames = tx_max_coalesce_frames[index];
-       if (pDevice->TxMaxCoalescedFrames > MAX_TX_MAX_COALESCED_FRAMES)
-               pDevice->TxMaxCoalescedFrames = MAX_TX_MAX_COALESCED_FRAMES;
-
-       if (enable_wol[index]) {
-               pDevice->WakeUpModeCap = LM_WAKE_UP_MODE_MAGIC_PACKET;
-               pDevice->WakeUpMode = LM_WAKE_UP_MODE_MAGIC_PACKET;
-       }
-       pDevice->NicSendBd = TRUE;
-
-       /* Don't update status blocks during interrupt */
-       pDevice->RxCoalescingTicksDuringInt = 0;
-       pDevice->TxCoalescingTicksDuringInt = 0;
-
-       return LM_STATUS_SUCCESS;
-
-}
-
-LM_STATUS MM_StartTxDma (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
-{
-       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
-       printf ("Start TX DMA: dev=%d packet @0x%x\n",
-               (int)pUmDevice->index, (unsigned int)pPacket);
-
-       return LM_STATUS_SUCCESS;
-}
-
-LM_STATUS MM_CompleteTxDma (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
-{
-       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
-       printf ("Complete TX DMA: dev=%d packet @0x%x\n",
-               (int)pUmDevice->index, (unsigned int)pPacket);
-       return LM_STATUS_SUCCESS;
-}
-
-LM_STATUS MM_IndicateStatus (PLM_DEVICE_BLOCK pDevice, LM_STATUS Status)
-{
-       char buf[128];
-       char lcd[4];
-       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
-       LM_FLOW_CONTROL flow_control;
-
-       pUmDevice->delayed_link_ind = 0;
-       memset (lcd, 0x0, 4);
-
-       if (Status == LM_STATUS_LINK_DOWN) {
-               sprintf (buf, "eth%d: %s: NIC Link is down\n",
-                        pUmDevice->index, pUmDevice->name);
-               lcd[0] = 'L';
-               lcd[1] = 'N';
-               lcd[2] = 'K';
-               lcd[3] = '?';
-       } else if (Status == LM_STATUS_LINK_ACTIVE) {
-               sprintf (buf, "eth%d:%s: ", pUmDevice->index, pUmDevice->name);
-
-               if (pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) {
-                       strcat (buf, "1000 Mbps ");
-                       lcd[0] = '1';
-                       lcd[1] = 'G';
-                       lcd[2] = 'B';
-               } else if (pDevice->LineSpeed == LM_LINE_SPEED_100MBPS) {
-                       strcat (buf, "100 Mbps ");
-                       lcd[0] = '1';
-                       lcd[1] = '0';
-                       lcd[2] = '0';
-               } else if (pDevice->LineSpeed == LM_LINE_SPEED_10MBPS) {
-                       strcat (buf, "10 Mbps ");
-                       lcd[0] = '1';
-                       lcd[1] = '0';
-                       lcd[2] = ' ';
-               }
-               if (pDevice->DuplexMode == LM_DUPLEX_MODE_FULL) {
-                       strcat (buf, "full duplex");
-                       lcd[3] = 'F';
-               } else {
-                       strcat (buf, "half duplex");
-                       lcd[3] = 'H';
-               }
-               strcat (buf, " link up");
-
-               flow_control = pDevice->FlowControl &
-                   (LM_FLOW_CONTROL_RECEIVE_PAUSE |
-                    LM_FLOW_CONTROL_TRANSMIT_PAUSE);
-
-               if (flow_control) {
-                       if (flow_control & LM_FLOW_CONTROL_RECEIVE_PAUSE) {
-                               strcat (buf, ", receive ");
-                               if (flow_control &
-                                   LM_FLOW_CONTROL_TRANSMIT_PAUSE)
-                                       strcat (buf, " & transmit ");
-                       } else {
-                               strcat (buf, ", transmit ");
-                       }
-                       strcat (buf, "flow control ON");
-               } else {
-                       strcat (buf, ", flow control OFF");
-               }
-               strcat (buf, "\n");
-               printf ("%s", buf);
-       }
-#if 0
-       sysLedDsply (lcd[0], lcd[1], lcd[2], lcd[3]);
-#endif
-       return LM_STATUS_SUCCESS;
-}
-
-LM_STATUS MM_FreeRxBuffer (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
-{
-
-       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
-       PUM_PACKET pUmPacket;
-       void *skb;
-
-       pUmPacket = (PUM_PACKET) pPacket;
-
-       if ((skb = pUmPacket->skbuff))
-               bcm570xPktFree (pUmDevice->index, skb);
-
-       pUmPacket->skbuff = 0;
-
-       return LM_STATUS_SUCCESS;
-}
-
-unsigned long MM_AnGetCurrentTime_us (PAN_STATE_INFO pAnInfo)
-{
-       return get_timer (0);
-}
-
-/*
- *   Transform an MBUF chain into a single MBUF.
- *   This routine will fail if the amount of data in the
- *   chain overflows a transmit buffer.  In that case,
- *   the incoming MBUF chain will be freed.  This routine can
- *   also fail by not being able to allocate a new MBUF (including
- *   cluster and mbuf headers).  In that case the failure is
- *   non-fatal.  The incoming cluster chain is not freed, giving
- *   the caller the choice of whether to try a retransmit later.
- */
-LM_STATUS MM_CoalesceTxBuffer (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
-{
-       PUM_PACKET pUmPacket = (PUM_PACKET) pPacket;
-       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
-       void *skbnew;
-       int len = 0;
-
-       if (len == 0)
-               return (LM_STATUS_SUCCESS);
-
-       if (len > MAX_PACKET_SIZE) {
-               printf ("eth%d: xmit frame discarded, too big!, size = %d\n",
-                       pUmDevice->index, len);
-               return (LM_STATUS_FAILURE);
-       }
-
-       skbnew = bcm570xPktAlloc (pUmDevice->index, MAX_PACKET_SIZE);
-
-       if (skbnew == NULL) {
-               pUmDevice->tx_full = 1;
-               printf ("eth%d: out of transmit buffers", pUmDevice->index);
-               return (LM_STATUS_FAILURE);
-       }
-
-       /* New packet values */
-       pUmPacket->skbuff = skbnew;
-       pUmPacket->lm_packet.u.Tx.FragCount = 1;
-
-       return (LM_STATUS_SUCCESS);
-}
-
-LM_STATUS MM_IndicateRxPackets (PLM_DEVICE_BLOCK pDevice)
-{
-       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
-       pUmDevice->rx_pkt = 1;
-       return LM_STATUS_SUCCESS;
-}
-
-LM_STATUS MM_IndicateTxPackets (PLM_DEVICE_BLOCK pDevice)
-{
-       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
-       PLM_PACKET pPacket;
-       PUM_PACKET pUmPacket;
-       void *skb;
-       while (TRUE) {
-
-               pPacket = (PLM_PACKET)
-                   QQ_PopHead (&pDevice->TxPacketXmittedQ.Container);
-
-               if (pPacket == 0)
-                       break;
-
-               pUmPacket = (PUM_PACKET) pPacket;
-               skb = (void *)pUmPacket->skbuff;
-
-               /*
-                * Free MBLK if we transmitted a fragmented packet or a
-                * non-fragmented packet straight from the VxWorks
-                * buffer pool. If packet was copied to a local transmit
-                * buffer, then there's no MBUF to free, just free
-                * the transmit buffer back to the cluster pool.
-                */
-
-               if (skb)
-                       bcm570xPktFree (pUmDevice->index, skb);
-
-               pUmPacket->skbuff = 0;
-               QQ_PushTail (&pDevice->TxPacketFreeQ.Container, pPacket);
-               pUmDevice->tx_pkt = 1;
-       }
-       if (pUmDevice->tx_full) {
-               if (QQ_GetEntryCnt (&pDevice->TxPacketFreeQ.Container) >=
-                   (QQ_GetSize (&pDevice->TxPacketFreeQ.Container) >> 1))
-                       pUmDevice->tx_full = 0;
-       }
-       return LM_STATUS_SUCCESS;
-}
-
-/*
- *  Scan an MBUF chain until we reach fragment number "frag"
- *  Return its length and physical address.
- */
-void MM_MapTxDma
-    (PLM_DEVICE_BLOCK pDevice,
-     struct _LM_PACKET *pPacket,
-     T3_64BIT_HOST_ADDR * paddr, LM_UINT32 * len, int frag) {
-       PUM_PACKET pUmPacket = (PUM_PACKET) pPacket;
-       *len = pPacket->PacketSize;
-       MM_SetT3Addr (paddr, (dma_addr_t) pUmPacket->skbuff);
-}
-
-/*
- *  Convert an mbuf address, a CPU local virtual address,
- *  to a physical address as seen from a PCI device.  Store the
- *  result at paddr.
- */
-void MM_MapRxDma (PLM_DEVICE_BLOCK pDevice,
-                 struct _LM_PACKET *pPacket, T3_64BIT_HOST_ADDR * paddr)
-{
-       PUM_PACKET pUmPacket = (PUM_PACKET) pPacket;
-       MM_SetT3Addr (paddr, (dma_addr_t) pUmPacket->skbuff);
-}
-
-void MM_SetAddr (LM_PHYSICAL_ADDRESS * paddr, dma_addr_t addr)
-{
-#if (BITS_PER_LONG == 64)
-       paddr->High = ((unsigned long)addr) >> 32;
-       paddr->Low = ((unsigned long)addr) & 0xffffffff;
-#else
-       paddr->High = 0;
-       paddr->Low = (unsigned long)addr;
-#endif
-}
-
-void MM_SetT3Addr (T3_64BIT_HOST_ADDR * paddr, dma_addr_t addr)
-{
-       unsigned long baddr = (unsigned long)addr;
-#if (BITS_PER_LONG == 64)
-       set_64bit_addr (paddr, baddr & 0xffffffff, baddr >> 32);
-#else
-       set_64bit_addr (paddr, baddr, 0);
-#endif
-}
-
-/*
- * This combination of `inline' and `extern' has almost the effect of a
- * macro.  The way to use it is to put a function definition in a header
- * file with these keywords, and put another copy of the definition
- * (lacking `inline' and `extern') in a library file.  The definition in
- * the header file will cause most calls to the function to be inlined.
- * If any uses of the function remain, they will refer to the single copy
- * in the library.
- */
-void atomic_set (atomic_t * entry, int val)
-{
-       entry->counter = val;
-}
-
-int atomic_read (atomic_t * entry)
-{
-       return entry->counter;
-}
-
-void atomic_inc (atomic_t * entry)
-{
-       if (entry)
-               entry->counter++;
-}
-
-void atomic_dec (atomic_t * entry)
-{
-       if (entry)
-               entry->counter--;
-}
-
-void atomic_sub (int a, atomic_t * entry)
-{
-       if (entry)
-               entry->counter -= a;
-}
-
-void atomic_add (int a, atomic_t * entry)
-{
-       if (entry)
-               entry->counter += a;
-}
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-void QQ_InitQueue (PQQ_CONTAINER pQueue, unsigned int QueueSize)
-{
-       pQueue->Head = 0;
-       pQueue->Tail = 0;
-       pQueue->Size = QueueSize + 1;
-       atomic_set (&pQueue->EntryCnt, 0);
-}                              /* QQ_InitQueue */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-char QQ_Full (PQQ_CONTAINER pQueue)
-{
-       unsigned int NewHead;
-
-       NewHead = (pQueue->Head + 1) % pQueue->Size;
-
-       return (NewHead == pQueue->Tail);
-}                              /* QQ_Full */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-char QQ_Empty (PQQ_CONTAINER pQueue)
-{
-       return (pQueue->Head == pQueue->Tail);
-}                              /* QQ_Empty */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-unsigned int QQ_GetSize (PQQ_CONTAINER pQueue)
-{
-       return pQueue->Size;
-}                              /* QQ_GetSize */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-unsigned int QQ_GetEntryCnt (PQQ_CONTAINER pQueue)
-{
-       return atomic_read (&pQueue->EntryCnt);
-}                              /* QQ_GetEntryCnt */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/*    TRUE entry was added successfully.                                      */
-/*    FALSE queue is full.                                                    */
-/******************************************************************************/
-char QQ_PushHead (PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry)
-{
-       unsigned int Head;
-
-       Head = (pQueue->Head + 1) % pQueue->Size;
-
-#if !defined(QQ_NO_OVERFLOW_CHECK)
-       if (Head == pQueue->Tail) {
-               return 0;
-       }                       /* if */
-#endif                         /* QQ_NO_OVERFLOW_CHECK */
-
-       pQueue->Array[pQueue->Head] = pEntry;
-       wmb ();
-       pQueue->Head = Head;
-       atomic_inc (&pQueue->EntryCnt);
-
-       return -1;
-}                              /* QQ_PushHead */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/*    TRUE entry was added successfully.                                      */
-/*    FALSE queue is full.                                                    */
-/******************************************************************************/
-char QQ_PushTail (PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry)
-{
-       unsigned int Tail;
-
-       Tail = pQueue->Tail;
-       if (Tail == 0) {
-               Tail = pQueue->Size;
-       }                       /* if */
-       Tail--;
-
-#if !defined(QQ_NO_OVERFLOW_CHECK)
-       if (Tail == pQueue->Head) {
-               return 0;
-       }                       /* if */
-#endif                         /* QQ_NO_OVERFLOW_CHECK */
-
-       pQueue->Array[Tail] = pEntry;
-       wmb ();
-       pQueue->Tail = Tail;
-       atomic_inc (&pQueue->EntryCnt);
-
-       return -1;
-}                              /* QQ_PushTail */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-PQQ_ENTRY QQ_PopHead (PQQ_CONTAINER pQueue)
-{
-       unsigned int Head;
-       PQQ_ENTRY Entry;
-
-       Head = pQueue->Head;
-
-#if !defined(QQ_NO_UNDERFLOW_CHECK)
-       if (Head == pQueue->Tail) {
-               return (PQQ_ENTRY) 0;
-       }                       /* if */
-#endif                         /* QQ_NO_UNDERFLOW_CHECK */
-
-       if (Head == 0) {
-               Head = pQueue->Size;
-       }                       /* if */
-       Head--;
-
-       Entry = pQueue->Array[Head];
-       membar ();
-
-       pQueue->Head = Head;
-       atomic_dec (&pQueue->EntryCnt);
-
-       return Entry;
-}                              /* QQ_PopHead */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-PQQ_ENTRY QQ_PopTail (PQQ_CONTAINER pQueue)
-{
-       unsigned int Tail;
-       PQQ_ENTRY Entry;
-
-       Tail = pQueue->Tail;
-
-#if !defined(QQ_NO_UNDERFLOW_CHECK)
-       if (Tail == pQueue->Head) {
-               return (PQQ_ENTRY) 0;
-       }                       /* if */
-#endif                         /* QQ_NO_UNDERFLOW_CHECK */
-
-       Entry = pQueue->Array[Tail];
-       membar ();
-       pQueue->Tail = (Tail + 1) % pQueue->Size;
-       atomic_dec (&pQueue->EntryCnt);
-
-       return Entry;
-}                              /* QQ_PopTail */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-PQQ_ENTRY QQ_GetHead (PQQ_CONTAINER pQueue, unsigned int Idx)
-{
-       if (Idx >= atomic_read (&pQueue->EntryCnt)) {
-               return (PQQ_ENTRY) 0;
-       }
-
-       if (pQueue->Head > Idx) {
-               Idx = pQueue->Head - Idx;
-       } else {
-               Idx = pQueue->Size - (Idx - pQueue->Head);
-       }
-       Idx--;
-
-       return pQueue->Array[Idx];
-}
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-PQQ_ENTRY QQ_GetTail (PQQ_CONTAINER pQueue, unsigned int Idx)
-{
-       if (Idx >= atomic_read (&pQueue->EntryCnt)) {
-               return (PQQ_ENTRY) 0;
-       }
-
-       Idx += pQueue->Tail;
-       if (Idx >= pQueue->Size) {
-               Idx = Idx - pQueue->Size;
-       }
-
-       return pQueue->Array[Idx];
-}
-
-#endif
diff --git a/drivers/bcm570x_autoneg.c b/drivers/bcm570x_autoneg.c
deleted file mode 100644 (file)
index 9023796..0000000
+++ /dev/null
@@ -1,439 +0,0 @@
-/******************************************************************************/
-/*                                                                            */
-/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2001 Broadcom         */
-/* Corporation.                                                               */
-/* All rights reserved.                                                       */
-/*                                                                            */
-/* This program is free software; you can redistribute it and/or modify       */
-/* it under the terms of the GNU General Public License as published by       */
-/* the Free Software Foundation, located in the file LICENSE.                 */
-/*                                                                            */
-/* History:                                                                   */
-/******************************************************************************/
-#if !defined(CONFIG_NET_MULTI)
-#if INCLUDE_TBI_SUPPORT
-#include "bcm570x_autoneg.h"
-#include "bcm570x_mm.h"
-
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-void
-MM_AnTxConfig(
-    PAN_STATE_INFO pAnInfo)
-{
-    PLM_DEVICE_BLOCK pDevice;
-
-    pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext;
-
-    REG_WR(pDevice, MacCtrl.TxAutoNeg, (LM_UINT32) pAnInfo->TxConfig.AsUSHORT);
-
-    pDevice->MacMode |= MAC_MODE_SEND_CONFIGS;
-    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
-}
-
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-void
-MM_AnTxIdle(
-    PAN_STATE_INFO pAnInfo)
-{
-    PLM_DEVICE_BLOCK pDevice;
-
-    pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext;
-
-    pDevice->MacMode &= ~MAC_MODE_SEND_CONFIGS;
-    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
-}
-
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-char
-MM_AnRxConfig(
-    PAN_STATE_INFO pAnInfo,
-    unsigned short *pRxConfig)
-{
-    PLM_DEVICE_BLOCK pDevice;
-    LM_UINT32 Value32;
-    char Retcode;
-
-    Retcode = AN_FALSE;
-
-    pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext;
-
-    Value32 = REG_RD(pDevice, MacCtrl.Status);
-    if(Value32 & MAC_STATUS_RECEIVING_CFG)
-    {
-       Value32 = REG_RD(pDevice, MacCtrl.RxAutoNeg);
-       *pRxConfig = (unsigned short) Value32;
-
-       Retcode = AN_TRUE;
-    }
-
-    return Retcode;
-}
-
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-void
-AutonegInit(
-    PAN_STATE_INFO pAnInfo)
-{
-    unsigned long j;
-
-    for(j = 0; j < sizeof(AN_STATE_INFO); j++)
-    {
-       ((unsigned char *) pAnInfo)[j] = 0;
-    }
-
-    /* Initialize the default advertisement register. */
-    pAnInfo->mr_adv_full_duplex = 1;
-    pAnInfo->mr_adv_sym_pause = 1;
-    pAnInfo->mr_adv_asym_pause = 1;
-    pAnInfo->mr_an_enable = 1;
-}
-
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-AUTONEG_STATUS
-Autoneg8023z(
-    PAN_STATE_INFO pAnInfo)
-{
-    unsigned short RxConfig;
-    unsigned long Delta_us;
-    AUTONEG_STATUS AnRet;
-
-    /* Get the current time. */
-    if(pAnInfo->State == AN_STATE_UNKNOWN)
-    {
-       pAnInfo->RxConfig.AsUSHORT = 0;
-       pAnInfo->CurrentTime_us = 0;
-       pAnInfo->LinkTime_us = 0;
-       pAnInfo->AbilityMatchCfg = 0;
-       pAnInfo->AbilityMatchCnt = 0;
-       pAnInfo->AbilityMatch = AN_FALSE;
-       pAnInfo->IdleMatch = AN_FALSE;
-       pAnInfo->AckMatch = AN_FALSE;
-    }
-
-    /* Increment the timer tick.  This function is called every microsecon. */
-/*    pAnInfo->CurrentTime_us++; */
-
-    /* Set the AbilityMatch, IdleMatch, and AckMatch flags if their */
-    /* corresponding conditions are satisfied. */
-    if(MM_AnRxConfig(pAnInfo, &RxConfig))
-    {
-       if(RxConfig != pAnInfo->AbilityMatchCfg)
-       {
-           pAnInfo->AbilityMatchCfg = RxConfig;
-           pAnInfo->AbilityMatch = AN_FALSE;
-           pAnInfo->AbilityMatchCnt = 0;
-       }
-       else
-       {
-           pAnInfo->AbilityMatchCnt++;
-           if(pAnInfo->AbilityMatchCnt > 1)
-           {
-               pAnInfo->AbilityMatch = AN_TRUE;
-               pAnInfo->AbilityMatchCfg = RxConfig;
-           }
-       }
-
-       if(RxConfig & AN_CONFIG_ACK)
-       {
-           pAnInfo->AckMatch = AN_TRUE;
-       }
-       else
-       {
-           pAnInfo->AckMatch = AN_FALSE;
-       }
-
-       pAnInfo->IdleMatch = AN_FALSE;
-    }
-    else
-    {
-       pAnInfo->IdleMatch = AN_TRUE;
-
-       pAnInfo->AbilityMatchCfg = 0;
-       pAnInfo->AbilityMatchCnt = 0;
-       pAnInfo->AbilityMatch = AN_FALSE;
-       pAnInfo->AckMatch = AN_FALSE;
-
-       RxConfig = 0;
-    }
-
-    /* Save the last Config. */
-    pAnInfo->RxConfig.AsUSHORT = RxConfig;
-
-    /* Default return code. */
-    AnRet = AUTONEG_STATUS_OK;
-
-    /* Autoneg state machine as defined in 802.3z section 37.3.1.5. */
-    switch(pAnInfo->State)
-    {
-       case AN_STATE_UNKNOWN:
-           if(pAnInfo->mr_an_enable || pAnInfo->mr_restart_an)
-           {
-               pAnInfo->CurrentTime_us = 0;
-               pAnInfo->State = AN_STATE_AN_ENABLE;
-           }
-
-           /* Fall through.*/
-
-       case AN_STATE_AN_ENABLE:
-           pAnInfo->mr_an_complete = AN_FALSE;
-           pAnInfo->mr_page_rx = AN_FALSE;
-
-           if(pAnInfo->mr_an_enable)
-           {
-               pAnInfo->LinkTime_us = 0;
-               pAnInfo->AbilityMatchCfg = 0;
-               pAnInfo->AbilityMatchCnt = 0;
-               pAnInfo->AbilityMatch = AN_FALSE;
-               pAnInfo->IdleMatch = AN_FALSE;
-               pAnInfo->AckMatch = AN_FALSE;
-
-               pAnInfo->State = AN_STATE_AN_RESTART_INIT;
-           }
-           else
-           {
-               pAnInfo->State = AN_STATE_DISABLE_LINK_OK;
-           }
-           break;
-
-       case AN_STATE_AN_RESTART_INIT:
-           pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us;
-           pAnInfo->mr_np_loaded = AN_FALSE;
-
-           pAnInfo->TxConfig.AsUSHORT = 0;
-           MM_AnTxConfig(pAnInfo);
-
-           AnRet = AUTONEG_STATUS_TIMER_ENABLED;
-
-           pAnInfo->State = AN_STATE_AN_RESTART;
-
-           /* Fall through.*/
-
-       case AN_STATE_AN_RESTART:
-           /* Get the current time and compute the delta with the saved */
-           /* link timer. */
-           Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us;
-           if(Delta_us > AN_LINK_TIMER_INTERVAL_US)
-           {
-               pAnInfo->State = AN_STATE_ABILITY_DETECT_INIT;
-           }
-           else
-           {
-               AnRet = AUTONEG_STATUS_TIMER_ENABLED;
-           }
-           break;
-
-       case AN_STATE_DISABLE_LINK_OK:
-           AnRet = AUTONEG_STATUS_DONE;
-           break;
-
-       case AN_STATE_ABILITY_DETECT_INIT:
-           /* Note: in the state diagram, this variable is set to */
-           /* mr_adv_ability<12>.  Is this right?. */
-           pAnInfo->mr_toggle_tx = AN_FALSE;
-
-           /* Send the config as advertised in the advertisement register. */
-           pAnInfo->TxConfig.AsUSHORT = 0;
-           pAnInfo->TxConfig.D5_FD = pAnInfo->mr_adv_full_duplex;
-           pAnInfo->TxConfig.D6_HD = pAnInfo->mr_adv_half_duplex;
-           pAnInfo->TxConfig.D7_PS1 = pAnInfo->mr_adv_sym_pause;
-           pAnInfo->TxConfig.D8_PS2 = pAnInfo->mr_adv_asym_pause;
-           pAnInfo->TxConfig.D12_RF1 = pAnInfo->mr_adv_remote_fault1;
-           pAnInfo->TxConfig.D13_RF2 = pAnInfo->mr_adv_remote_fault2;
-           pAnInfo->TxConfig.D15_NP = pAnInfo->mr_adv_next_page;
-
-           MM_AnTxConfig(pAnInfo);
-
-           pAnInfo->State = AN_STATE_ABILITY_DETECT;
-
-           break;
-
-       case AN_STATE_ABILITY_DETECT:
-           if(pAnInfo->AbilityMatch == AN_TRUE &&
-               pAnInfo->RxConfig.AsUSHORT != 0)
-           {
-               pAnInfo->State = AN_STATE_ACK_DETECT_INIT;
-           }
-
-           break;
-
-       case AN_STATE_ACK_DETECT_INIT:
-           pAnInfo->TxConfig.D14_ACK = 1;
-           MM_AnTxConfig(pAnInfo);
-
-           pAnInfo->State = AN_STATE_ACK_DETECT;
-
-           /* Fall through. */
-
-       case AN_STATE_ACK_DETECT:
-           if(pAnInfo->AckMatch == AN_TRUE)
-           {
-               if((pAnInfo->RxConfig.AsUSHORT & ~AN_CONFIG_ACK) ==
-                   (pAnInfo->AbilityMatchCfg & ~AN_CONFIG_ACK))
-               {
-                   pAnInfo->State = AN_STATE_COMPLETE_ACK_INIT;
-               }
-               else
-               {
-                   pAnInfo->State = AN_STATE_AN_ENABLE;
-               }
-           }
-           else if(pAnInfo->AbilityMatch == AN_TRUE &&
-               pAnInfo->RxConfig.AsUSHORT == 0)
-           {
-               pAnInfo->State = AN_STATE_AN_ENABLE;
-           }
-
-           break;
-
-       case AN_STATE_COMPLETE_ACK_INIT:
-           /* Make sure invalid bits are not set. */
-           if(pAnInfo->RxConfig.bits.D0 || pAnInfo->RxConfig.bits.D1 ||
-               pAnInfo->RxConfig.bits.D2 || pAnInfo->RxConfig.bits.D3 ||
-               pAnInfo->RxConfig.bits.D4 || pAnInfo->RxConfig.bits.D9 ||
-               pAnInfo->RxConfig.bits.D10 || pAnInfo->RxConfig.bits.D11)
-           {
-               AnRet = AUTONEG_STATUS_FAILED;
-               break;
-           }
-
-           /* Set up the link partner advertisement register. */
-           pAnInfo->mr_lp_adv_full_duplex = pAnInfo->RxConfig.D5_FD;
-           pAnInfo->mr_lp_adv_half_duplex = pAnInfo->RxConfig.D6_HD;
-           pAnInfo->mr_lp_adv_sym_pause = pAnInfo->RxConfig.D7_PS1;
-           pAnInfo->mr_lp_adv_asym_pause = pAnInfo->RxConfig.D8_PS2;
-           pAnInfo->mr_lp_adv_remote_fault1 = pAnInfo->RxConfig.D12_RF1;
-           pAnInfo->mr_lp_adv_remote_fault2 = pAnInfo->RxConfig.D13_RF2;
-           pAnInfo->mr_lp_adv_next_page = pAnInfo->RxConfig.D15_NP;
-
-           pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us;
-
-           pAnInfo->mr_toggle_tx = !pAnInfo->mr_toggle_tx;
-           pAnInfo->mr_toggle_rx = pAnInfo->RxConfig.bits.D11;
-           pAnInfo->mr_np_rx = pAnInfo->RxConfig.D15_NP;
-           pAnInfo->mr_page_rx = AN_TRUE;
-
-           pAnInfo->State = AN_STATE_COMPLETE_ACK;
-           AnRet = AUTONEG_STATUS_TIMER_ENABLED;
-
-           break;
-
-       case AN_STATE_COMPLETE_ACK:
-           if(pAnInfo->AbilityMatch == AN_TRUE &&
-               pAnInfo->RxConfig.AsUSHORT == 0)
-           {
-               pAnInfo->State = AN_STATE_AN_ENABLE;
-               break;
-           }
-
-           Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us;
-
-           if(Delta_us > AN_LINK_TIMER_INTERVAL_US)
-           {
-               if(pAnInfo->mr_adv_next_page == 0 ||
-                   pAnInfo->mr_lp_adv_next_page == 0)
-               {
-                   pAnInfo->State = AN_STATE_IDLE_DETECT_INIT;
-               }
-               else
-               {
-                   if(pAnInfo->TxConfig.bits.D15 == 0 &&
-                       pAnInfo->mr_np_rx == 0)
-                   {
-                       pAnInfo->State = AN_STATE_IDLE_DETECT_INIT;
-                   }
-                   else
-                   {
-                       AnRet = AUTONEG_STATUS_FAILED;
-                   }
-               }
-           }
-
-           break;
-
-       case AN_STATE_IDLE_DETECT_INIT:
-           pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us;
-
-           MM_AnTxIdle(pAnInfo);
-
-           pAnInfo->State = AN_STATE_IDLE_DETECT;
-
-           AnRet = AUTONEG_STATUS_TIMER_ENABLED;
-
-           break;
-
-       case AN_STATE_IDLE_DETECT:
-           if(pAnInfo->AbilityMatch == AN_TRUE &&
-               pAnInfo->RxConfig.AsUSHORT == 0)
-           {
-               pAnInfo->State = AN_STATE_AN_ENABLE;
-               break;
-           }
-
-           Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us;
-           if(Delta_us > AN_LINK_TIMER_INTERVAL_US)
-           {
-#if 0
-/*                if(pAnInfo->IdleMatch == AN_TRUE) */
-/*                { */
-#endif
-                   pAnInfo->State = AN_STATE_LINK_OK;
-#if 0
-/*                } */
-/*                else */
-/*                { */
-/*                    AnRet = AUTONEG_STATUS_FAILED; */
-/*                    break; */
-/*                } */
-#endif
-           }
-
-           break;
-
-       case AN_STATE_LINK_OK:
-           pAnInfo->mr_an_complete = AN_TRUE;
-           pAnInfo->mr_link_ok = AN_TRUE;
-           AnRet = AUTONEG_STATUS_DONE;
-
-           break;
-
-       case AN_STATE_NEXT_PAGE_WAIT_INIT:
-           break;
-
-       case AN_STATE_NEXT_PAGE_WAIT:
-           break;
-
-       default:
-           AnRet = AUTONEG_STATUS_FAILED;
-           break;
-    }
-
-    return AnRet;
-}
-#endif /* INCLUDE_TBI_SUPPORT */
-
-#endif /* !defined(CONFIG_NET_MULTI) */
diff --git a/drivers/bcm570x_autoneg.h b/drivers/bcm570x_autoneg.h
deleted file mode 100644 (file)
index 7830944..0000000
+++ /dev/null
@@ -1,408 +0,0 @@
-/******************************************************************************/
-/*                                                                            */
-/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2001 Broadcom         */
-/* Corporation.                                                               */
-/* All rights reserved.                                                       */
-/*                                                                            */
-/* This program is free software; you can redistribute it and/or modify       */
-/* it under the terms of the GNU General Public License as published by       */
-/* the Free Software Foundation, located in the file LICENSE.                 */
-/*                                                                            */
-/* History:                                                                   */
-/******************************************************************************/
-
-
-#ifndef AUTONEG_H
-#define AUTONEG_H
-
-
-/******************************************************************************/
-/* Constants. */
-/******************************************************************************/
-
-#define AN_LINK_TIMER_INTERVAL_US           9000       /* 10ms */
-
-/* TRUE, FALSE */
-#define AN_TRUE                             1
-#define AN_FALSE                            0
-
-
-/******************************************************************************/
-/* Main data structure for keeping track of 802.3z auto-negotation state */
-/* variables as shown in Figure 37-6 of the IEEE 802.3z specification. */
-/******************************************************************************/
-
-typedef struct
-{
-    /* Current auto-negotiation state. */
-    unsigned long State;
-    #define AN_STATE_UNKNOWN                        0
-    #define AN_STATE_AN_ENABLE                      1
-    #define AN_STATE_AN_RESTART_INIT                2
-    #define AN_STATE_AN_RESTART                     3
-    #define AN_STATE_DISABLE_LINK_OK                4
-    #define AN_STATE_ABILITY_DETECT_INIT            5
-    #define AN_STATE_ABILITY_DETECT                 6
-    #define AN_STATE_ACK_DETECT_INIT                7
-    #define AN_STATE_ACK_DETECT                     8
-    #define AN_STATE_COMPLETE_ACK_INIT              9
-    #define AN_STATE_COMPLETE_ACK                   10
-    #define AN_STATE_IDLE_DETECT_INIT               11
-    #define AN_STATE_IDLE_DETECT                    12
-    #define AN_STATE_LINK_OK                        13
-    #define AN_STATE_NEXT_PAGE_WAIT_INIT            14
-    #define AN_STATE_NEXT_PAGE_WAIT                 16
-
-    /* Link timer. */
-    unsigned long LinkTime_us;
-
-    /* Current time. */
-    unsigned long CurrentTime_us;
-
-    /* Need these values for consistency check. */
-    unsigned short AbilityMatchCfg;
-
-    /* Ability, idle, and ack match functions. */
-    unsigned long AbilityMatchCnt;
-    char AbilityMatch;
-    char IdleMatch;
-    char AckMatch;
-
-    /* Tx config data */
-    union
-    {
-       /* The TxConfig register is arranged as follows:                      */
-       /*                                                                    */
-       /* MSB                                                           LSB  */
-       /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
-       /* | D7| D6| D5| D4| D3| D2| D1| D0|D15|D14|D13|D12|D11|D10| D9| D8|  */
-       /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
-       struct
-       {
-#ifdef BIG_ENDIAN_HOST
-           unsigned int D7:1;        /* PS1 */
-           unsigned int D6:1;        /* HD */
-           unsigned int D5:1;        /* FD */
-           unsigned int D4:1;
-           unsigned int D3:1;
-           unsigned int D2:1;
-           unsigned int D1:1;
-           unsigned int D0:1;
-           unsigned int D15:1;       /* NP */
-           unsigned int D14:1;       /* ACK */
-           unsigned int D13:1;       /* RF2 */
-           unsigned int D12:1;       /* RF1 */
-           unsigned int D11:1;
-           unsigned int D10:1;
-           unsigned int D9:1;
-           unsigned int D8:1;        /* PS2 */
-#else /* BIG_ENDIAN_HOST */
-           unsigned int D8:1;        /* PS2 */
-           unsigned int D9:1;
-           unsigned int D10:1;
-           unsigned int D11:1;
-           unsigned int D12:1;       /* RF1 */
-           unsigned int D13:1;       /* RF2 */
-           unsigned int D14:1;       /* ACK */
-           unsigned int D15:1;       /* NP */
-           unsigned int D0:1;
-           unsigned int D1:1;
-           unsigned int D2:1;
-           unsigned int D3:1;
-           unsigned int D4:1;
-           unsigned int D5:1;        /* FD */
-           unsigned int D6:1;        /* HD */
-           unsigned int D7:1;        /* PS1 */
-#endif
-       } bits;
-
-       unsigned short AsUSHORT;
-
-       #define D8_PS2                      bits.D8
-       #define D12_RF1                     bits.D12
-       #define D13_RF2                     bits.D13
-       #define D14_ACK                     bits.D14
-       #define D15_NP                      bits.D15
-       #define D5_FD                       bits.D5
-       #define D6_HD                       bits.D6
-       #define D7_PS1                      bits.D7
-    } TxConfig;
-
-    /* Rx config data */
-    union
-    {
-       /* The RxConfig register is arranged as follows:                      */
-       /*                                                                    */
-       /* MSB                                                           LSB  */
-       /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
-       /* | D7| D6| D5| D4| D3| D2| D1| D0|D15|D14|D13|D12|D11|D10| D9| D8|  */
-       /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
-       struct
-       {
-#ifdef BIG_ENDIAN_HOST
-           unsigned int D7:1;        /* PS1 */
-           unsigned int D6:1;        /* HD */
-           unsigned int D5:1;        /* FD */
-           unsigned int D4:1;
-           unsigned int D3:1;
-           unsigned int D2:1;
-           unsigned int D1:1;
-           unsigned int D0:1;
-           unsigned int D15:1;       /* NP */
-           unsigned int D14:1;       /* ACK */
-           unsigned int D13:1;       /* RF2 */
-           unsigned int D12:1;       /* RF1 */
-           unsigned int D11:1;
-           unsigned int D10:1;
-           unsigned int D9:1;
-           unsigned int D8:1;        /* PS2 */
-#else /* BIG_ENDIAN_HOST */
-           unsigned int D8:1;        /* PS2 */
-           unsigned int D9:1;
-           unsigned int D10:1;
-           unsigned int D11:1;
-           unsigned int D12:1;       /* RF1 */
-           unsigned int D13:1;       /* RF2 */
-           unsigned int D14:1;       /* ACK */
-           unsigned int D15:1;       /* NP */
-           unsigned int D0:1;
-           unsigned int D1:1;
-           unsigned int D2:1;
-           unsigned int D3:1;
-           unsigned int D4:1;
-           unsigned int D5:1;        /* FD */
-           unsigned int D6:1;        /* HD */
-           unsigned int D7:1;        /* PS1 */
-#endif
-       } bits;
-
-       unsigned short AsUSHORT;
-    } RxConfig;
-
-    #define AN_CONFIG_NP                            0x0080
-    #define AN_CONFIG_ACK                           0x0040
-    #define AN_CONFIG_RF2                           0x0020
-    #define AN_CONFIG_RF1                           0x0010
-    #define AN_CONFIG_PS2                           0x0001
-    #define AN_CONFIG_PS1                           0x8000
-    #define AN_CONFIG_HD                            0x4000
-    #define AN_CONFIG_FD                            0x2000
-
-
-    /* Management registers. */
-
-    /* Control register. */
-    union
-    {
-       struct
-       {
-           unsigned int an_enable:1;
-           unsigned int loopback:1;
-           unsigned int reset:1;
-           unsigned int restart_an:1;
-       } bits;
-
-       unsigned short AsUSHORT;
-
-       #define mr_an_enable                Mr0.bits.an_enable
-       #define mr_loopback                 Mr0.bits.loopback
-       #define mr_main_reset               Mr0.bits.reset
-       #define mr_restart_an               Mr0.bits.restart_an
-    } Mr0;
-
-    /* Status register. */
-    union
-    {
-       struct
-       {
-           unsigned int an_complete:1;
-           unsigned int link_ok:1;
-       } bits;
-
-       unsigned short AsUSHORT;
-
-       #define mr_an_complete              Mr1.bits.an_complete
-       #define mr_link_ok                  Mr1.bits.link_ok
-    } Mr1;
-
-    /* Advertisement register. */
-    union
-    {
-       struct
-       {
-           unsigned int reserved_4:5;
-           unsigned int full_duplex:1;
-           unsigned int half_duplex:1;
-           unsigned int sym_pause:1;
-           unsigned int asym_pause:1;
-           unsigned int reserved_11:3;
-           unsigned int remote_fault1:1;
-           unsigned int remote_fault2:1;
-           unsigned int reserved_14:1;
-           unsigned int next_page:1;
-       } bits;
-
-       unsigned short AsUSHORT;
-
-       #define mr_adv_full_duplex          Mr4.bits.full_duplex
-       #define mr_adv_half_duplex          Mr4.bits.half_duplex
-       #define mr_adv_sym_pause            Mr4.bits.sym_pause
-       #define mr_adv_asym_pause           Mr4.bits.asym_pause
-       #define mr_adv_remote_fault1        Mr4.bits.remote_fault1
-       #define mr_adv_remote_fault2        Mr4.bits.remote_fault2
-       #define mr_adv_next_page            Mr4.bits.next_page
-    } Mr4;
-
-    /* Link partner advertisement register. */
-    union
-    {
-       struct
-       {
-           unsigned int reserved_4:5;
-           unsigned int lp_full_duplex:1;
-           unsigned int lp_half_duplex:1;
-           unsigned int lp_sym_pause:1;
-           unsigned int lp_asym_pause:1;
-           unsigned int reserved_11:3;
-           unsigned int lp_remote_fault1:1;
-           unsigned int lp_remote_fault2:1;
-           unsigned int lp_ack:1;
-           unsigned int lp_next_page:1;
-       } bits;
-
-       unsigned short AsUSHORT;
-
-       #define mr_lp_adv_full_duplex       Mr5.bits.lp_full_duplex
-       #define mr_lp_adv_half_duplex       Mr5.bits.lp_half_duplex
-       #define mr_lp_adv_sym_pause         Mr5.bits.lp_sym_pause
-       #define mr_lp_adv_asym_pause        Mr5.bits.lp_asym_pause
-       #define mr_lp_adv_remote_fault1     Mr5.bits.lp_remote_fault1
-       #define mr_lp_adv_remote_fault2     Mr5.bits.lp_remote_fault2
-       #define mr_lp_adv_next_page         Mr5.bits.lp_next_page
-    } Mr5;
-
-    /* Auto-negotiation expansion register. */
-    union
-    {
-       struct
-       {
-           unsigned int reserved_0:1;
-           unsigned int page_received:1;
-           unsigned int next_pageable:1;
-           unsigned int reserved_15:13;
-       } bits;
-
-       unsigned short AsUSHORT;
-    } Mr6;
-
-    /* Auto-negotiation next page transmit register. */
-    union
-    {
-       struct
-       {
-           unsigned int code_field:11;
-           unsigned int toggle:1;
-           unsigned int ack2:1;
-           unsigned int message_page:1;
-           unsigned int reserved_14:1;
-           unsigned int next_page:1;
-       } bits;
-
-       unsigned short AsUSHORT;
-
-       #define mr_np_tx                    Mr7.AsUSHORT
-    } Mr7;
-
-    /* Auto-negotiation link partner ability register. */
-    union
-    {
-       struct
-       {
-           unsigned int code_field:11;
-           unsigned int toggle:1;
-           unsigned int ack2:1;
-           unsigned int message_page:1;
-           unsigned int ack:1;
-           unsigned int next_page:1;
-       } bits;
-
-       unsigned short AsUSHORT;
-
-       #define mr_lp_np_rx                 Mr8.AsUSHORT
-    } Mr8;
-
-    /* Extended status register. */
-    union
-    {
-       struct
-       {
-           unsigned int reserved_11:12;
-           unsigned int base1000_t_hd:1;
-           unsigned int base1000_t_fd:1;
-           unsigned int base1000_x_hd:1;
-           unsigned int base1000_x_fd:1;
-       } bits;
-
-       unsigned short AsUSHORT;
-    } Mr15;
-
-    /* Miscellaneous state variables. */
-    union
-    {
-       struct
-       {
-           unsigned int toggle_tx:1;
-           unsigned int toggle_rx:1;
-           unsigned int np_rx:1;
-           unsigned int page_rx:1;
-           unsigned int np_loaded:1;
-       } bits;
-
-       unsigned short AsUSHORT;
-
-       #define mr_toggle_tx                MrMisc.bits.toggle_tx
-       #define mr_toggle_rx                MrMisc.bits.toggle_rx
-       #define mr_np_rx                    MrMisc.bits.np_rx
-       #define mr_page_rx                  MrMisc.bits.page_rx
-       #define mr_np_loaded                MrMisc.bits.np_loaded
-    } MrMisc;
-
-
-    /* Implement specifics */
-
-    /* Pointer to the operating system specific data structure. */
-    void *pContext;
-} AN_STATE_INFO, *PAN_STATE_INFO;
-
-
-/******************************************************************************/
-/* Return code of Autoneg8023z. */
-/******************************************************************************/
-
-typedef enum
-{
-    AUTONEG_STATUS_OK               = 0,
-    AUTONEG_STATUS_DONE             = 1,
-    AUTONEG_STATUS_TIMER_ENABLED    = 2,
-    AUTONEG_STATUS_FAILED           = 0xfffffff
-} AUTONEG_STATUS, *PAUTONEG_STATUS;
-
-
-/******************************************************************************/
-/* Function prototypes. */
-/******************************************************************************/
-
-AUTONEG_STATUS Autoneg8023z(PAN_STATE_INFO pAnInfo);
-void AutonegInit(PAN_STATE_INFO pAnInfo);
-
-
-/******************************************************************************/
-/* The following functions are defined in the os-dependent module. */
-/******************************************************************************/
-
-void MM_AnTxConfig(PAN_STATE_INFO pAnInfo);
-void MM_AnTxIdle(PAN_STATE_INFO pAnInfo);
-char MM_AnRxConfig(PAN_STATE_INFO pAnInfo, unsigned short *pRxConfig);
-
-
-#endif /* AUTONEG_H */
diff --git a/drivers/bcm570x_bits.h b/drivers/bcm570x_bits.h
deleted file mode 100644 (file)
index 615d61e..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-
-/******************************************************************************/
-/*                                                                            */
-/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
-/* Corporation.                                                               */
-/* All rights reserved.                                                       */
-/*                                                                            */
-/* This program is free software; you can redistribute it and/or modify       */
-/* it under the terms of the GNU General Public License as published by       */
-/* the Free Software Foundation, located in the file LICENSE.                 */
-/*                                                                            */
-/* History:                                                                   */
-/*    02/25/00 Hav Khauv        Initial version.                              */
-/******************************************************************************/
-
-#ifndef BITS_H
-#define BITS_H
-
-
-/******************************************************************************/
-/* Bit Mask definitions */
-/******************************************************************************/
-#define BIT_NONE            0x00
-#define BIT_0               0x01
-#define BIT_1               0x02
-#define BIT_2               0x04
-#define BIT_3               0x08
-#define BIT_4               0x10
-#define BIT_5               0x20
-#define BIT_6               0x40
-#define BIT_7               0x80
-#define BIT_8               0x0100
-#define BIT_9               0x0200
-#define BIT_10              0x0400
-#define BIT_11              0x0800
-#define BIT_12              0x1000
-#define BIT_13              0x2000
-#define BIT_14              0x4000
-#define BIT_15              0x8000
-#define BIT_16              0x010000
-#define BIT_17              0x020000
-#define BIT_18              0x040000
-#define BIT_19              0x080000
-#define BIT_20              0x100000
-#define BIT_21              0x200000
-#define BIT_22              0x400000
-#define BIT_23              0x800000
-#define BIT_24              0x01000000
-#define BIT_25              0x02000000
-#define BIT_26              0x04000000
-#define BIT_27              0x08000000
-#define BIT_28              0x10000000
-#define BIT_29              0x20000000
-#define BIT_30              0x40000000
-#define BIT_31              0x80000000
-
-#endif /* BITS_H */
diff --git a/drivers/bcm570x_debug.h b/drivers/bcm570x_debug.h
deleted file mode 100644 (file)
index 88e209b..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-
-/******************************************************************************/
-/*                                                                            */
-/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
-/* Corporation.                                                               */
-/* All rights reserved.                                                       */
-/*                                                                            */
-/* This program is free software; you can redistribute it and/or modify       */
-/* it under the terms of the GNU General Public License as published by       */
-/* the Free Software Foundation, located in the file LICENSE.                 */
-/*                                                                            */
-/* History:                                                                   */
-/*    02/25/00 Hav Khauv        Initial version.                              */
-/******************************************************************************/
-
-#ifndef DEBUG_H
-#define DEBUG_H
-
-#ifdef VXWORKS
-#include <vxWorks.h>
-#endif
-
-/******************************************************************************/
-/* Debug macros                                                               */
-/******************************************************************************/
-
-/* Code path for controlling output debug messages. */
-/* Define your code path here. */
-#define CP_INIT                     0x010000
-#define CP_SEND                     0x020000
-#define CP_RCV                      0x040000
-#define CP_INT                      0x080000
-#define CP_UINIT                    0x100000
-#define CP_RESET                    0x200000
-
-#define CP_ALL                      (CP_INIT | CP_SEND | CP_RCV | CP_INT | \
-                                   CP_RESET | CP_UINIT)
-
-#define CP_MASK                     0xffff0000
-
-
-/* Debug message levels. */
-#define LV_VERBOSE                  0x03
-#define LV_INFORM                   0x02
-#define LV_WARN                     0x01
-#define LV_FATAL                    0x00
-
-#define LV_MASK                     0xffff
-
-
-/* Code path and messsage level combined.  These are the first argument of */
-/* the DbgMessage macro. */
-#define INIT_V                      (CP_INIT | LV_VERBOSE)
-#define INIT_I                      (CP_INIT | LV_INFORM)
-#define INIT_W                      (CP_INIT | LV_WARN)
-#define SEND_V                      (CP_SEND | LV_VERBOSE)
-#define SEND_I                      (CP_SEND | LV_INFORM)
-#define SEND_W                      (CP_SEND | LV_WARN)
-#define RCV_V                       (CP_RCV | LV_VERBOSE)
-#define RCV_I                       (CP_RCV | LV_INFORM)
-#define RCV_W                       (CP_RCV | LV_WARN)
-#define INT_V                       (CP_INT | LV_VERBOSE)
-#define INT_I                       (CP_INT | LV_INFORM)
-#define INT_W                       (CP_INT | LV_WARN)
-#define UINIT_V                     (CP_UINIT | LV_VERBOSE)
-#define UINIT_I                     (CP_UINIT | LV_INFORM)
-#define UINIT_W                     (CP_UINIT | LV_WARN)
-#define RESET_V                     (CP_RESET | LV_VERBOSE)
-#define RESET_I                     (CP_RESET | LV_INFORM)
-#define RESET_W                     (CP_RESET | LV_WARN)
-#define CPALL_V                     (CP_ALL | LV_VERBOSE)
-#define CPALL_I                     (CP_ALL | LV_INFORM)
-#define CPALL_W                     (CP_ALL | LV_WARN)
-
-
-/* All code path message levels. */
-#define FATAL                       (CP_ALL | LV_FATAL)
-#define WARN                        (CP_ALL | LV_WARN)
-#define INFORM                      (CP_ALL | LV_INFORM)
-#define VERBOSE                     (CP_ALL | LV_VERBOSE)
-
-
-/* These constants control the message output. */
-/* Set your debug message output level and code path here. */
-#ifndef DBG_MSG_CP
-#define DBG_MSG_CP                  CP_ALL      /* Where to output messages. */
-#endif
-
-#ifndef DBG_MSG_LV
-#define DBG_MSG_LV                  LV_VERBOSE  /* Level of message output. */
-#endif
-
-/* DbgMessage macro. */
-#if DBG
-#define DbgMessage(CNTRL, MESSAGE)  \
-    if((CNTRL & DBG_MSG_CP) && ((CNTRL & LV_MASK) <= DBG_MSG_LV)) \
-       printf MESSAGE
-#define DbgBreak()                 DbgBreakPoint()
-#undef STATIC
-#define STATIC
-#else
-#define DbgMessage(CNTRL, MESSAGE)
-#define DbgBreak()
-#undef STATIC
-#define STATIC static
-#endif /* DBG */
-
-
-#endif /* DEBUG_H */
diff --git a/drivers/bcm570x_lm.h b/drivers/bcm570x_lm.h
deleted file mode 100644 (file)
index 2ea6ca8..0000000
+++ /dev/null
@@ -1,434 +0,0 @@
-
-/******************************************************************************/
-/*                                                                            */
-/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
-/* Corporation.                                                               */
-/* All rights reserved.                                                       */
-/*                                                                            */
-/* This program is free software; you can redistribute it and/or modify       */
-/* it under the terms of the GNU General Public License as published by       */
-/* the Free Software Foundation, located in the file LICENSE.                 */
-/*                                                                            */
-/* History:                                                                   */
-/*    02/25/00 Hav Khauv        Initial version.                              */
-/******************************************************************************/
-
-#ifndef LM_H
-#define LM_H
-
-#include "bcm570x_queue.h"
-#include "bcm570x_bits.h"
-
-/******************************************************************************/
-/* Basic types. */
-/******************************************************************************/
-
-typedef char LM_CHAR, *PLM_CHAR;
-typedef unsigned int LM_UINT, *PLM_UINT;
-typedef unsigned char LM_UINT8, *PLM_UINT8;
-typedef unsigned short LM_UINT16, *PLM_UINT16;
-typedef unsigned int LM_UINT32, *PLM_UINT32;
-typedef unsigned int LM_COUNTER, *PLM_COUNTER;
-typedef void LM_VOID, *PLM_VOID;
-typedef char LM_BOOL, *PLM_BOOL;
-
-/* 64bit value. */
-typedef struct {
-#ifdef BIG_ENDIAN_HOST
-       LM_UINT32 High;
-       LM_UINT32 Low;
-#else                          /* BIG_ENDIAN_HOST */
-       LM_UINT32 Low;
-       LM_UINT32 High;
-#endif                         /* !BIG_ENDIAN_HOST */
-} LM_UINT64, *PLM_UINT64;
-
-typedef LM_UINT64 LM_PHYSICAL_ADDRESS, *PLM_PHYSICAL_ADDRESS;
-
-/* void LM_INC_PHYSICAL_ADDRESS(PLM_PHYSICAL_ADDRESS pAddr,LM_UINT32 IncSize) */
-#define LM_INC_PHYSICAL_ADDRESS(pAddr, IncSize)             \
-    {                                                       \
-       LM_UINT32 OrgLow;                                   \
-                                                           \
-       OrgLow = (pAddr)->Low;                              \
-       (pAddr)->Low += IncSize;                            \
-       if((pAddr)->Low < OrgLow) {                         \
-           (pAddr)->High++; /* Wrap around. */             \
-       }                                                   \
-    }
-
-#ifndef NULL
-#define NULL                ((void *) 0)
-#endif                         /* NULL */
-
-#ifndef OFFSETOF
-#define OFFSETOF(_s, _m)    (MM_UINT_PTR(&(((_s *) 0)->_m)))
-#endif                         /* OFFSETOF */
-
-/******************************************************************************/
-/* Simple macros. */
-/******************************************************************************/
-
-#define IS_ETH_BROADCAST(_pEthAddr)                                         \
-    (((unsigned char *) (_pEthAddr))[0] == ((unsigned char) 0xff))
-
-#define IS_ETH_MULTICAST(_pEthAddr)                                         \
-    (((unsigned char *) (_pEthAddr))[0] & ((unsigned char) 0x01))
-
-#define IS_ETH_ADDRESS_EQUAL(_pEtherAddr1, _pEtherAddr2)                    \
-    ((((unsigned char *) (_pEtherAddr1))[0] ==                              \
-    ((unsigned char *) (_pEtherAddr2))[0]) &&                               \
-    (((unsigned char *) (_pEtherAddr1))[1] ==                               \
-    ((unsigned char *) (_pEtherAddr2))[1]) &&                               \
-    (((unsigned char *) (_pEtherAddr1))[2] ==                               \
-    ((unsigned char *) (_pEtherAddr2))[2]) &&                               \
-    (((unsigned char *) (_pEtherAddr1))[3] ==                               \
-    ((unsigned char *) (_pEtherAddr2))[3]) &&                               \
-    (((unsigned char *) (_pEtherAddr1))[4] ==                               \
-    ((unsigned char *) (_pEtherAddr2))[4]) &&                               \
-    (((unsigned char *) (_pEtherAddr1))[5] ==                               \
-    ((unsigned char *) (_pEtherAddr2))[5]))
-
-#define COPY_ETH_ADDRESS(_Src, _Dst)                                        \
-    ((unsigned char *) (_Dst))[0] = ((unsigned char *) (_Src))[0];          \
-    ((unsigned char *) (_Dst))[1] = ((unsigned char *) (_Src))[1];          \
-    ((unsigned char *) (_Dst))[2] = ((unsigned char *) (_Src))[2];          \
-    ((unsigned char *) (_Dst))[3] = ((unsigned char *) (_Src))[3];          \
-    ((unsigned char *) (_Dst))[4] = ((unsigned char *) (_Src))[4];          \
-    ((unsigned char *) (_Dst))[5] = ((unsigned char *) (_Src))[5];
-
-/******************************************************************************/
-/* Constants. */
-/******************************************************************************/
-
-#define ETHERNET_ADDRESS_SIZE           6
-#define ETHERNET_PACKET_HEADER_SIZE     14
-#define MIN_ETHERNET_PACKET_SIZE        64     /* with 4 byte crc. */
-#define MAX_ETHERNET_PACKET_SIZE        1518   /* with 4 byte crc. */
-#define MIN_ETHERNET_PACKET_SIZE_NO_CRC 60
-#define MAX_ETHERNET_PACKET_SIZE_NO_CRC 1514
-#define MAX_ETHERNET_PACKET_BUFFER_SIZE 1536   /* A nice even number. */
-
-#ifndef LM_MAX_MC_TABLE_SIZE
-#define LM_MAX_MC_TABLE_SIZE            32
-#endif                         /* LM_MAX_MC_TABLE_SIZE */
-#define LM_MC_ENTRY_SIZE                (ETHERNET_ADDRESS_SIZE+1)
-#define LM_MC_INSTANCE_COUNT_INDEX      (LM_MC_ENTRY_SIZE-1)
-
-/* Receive filter masks. */
-#define LM_ACCEPT_UNICAST               0x0001
-#define LM_ACCEPT_MULTICAST             0x0002
-#define LM_ACCEPT_ALL_MULTICAST         0x0004
-#define LM_ACCEPT_BROADCAST             0x0008
-#define LM_ACCEPT_ERROR_PACKET          0x0010
-
-#define LM_PROMISCUOUS_MODE             0x10000
-
-/******************************************************************************/
-/* PCI registers. */
-/******************************************************************************/
-
-#define PCI_VENDOR_ID_REG               0x00
-#define PCI_DEVICE_ID_REG               0x02
-
-#define PCI_COMMAND_REG                 0x04
-#define PCI_IO_SPACE_ENABLE             0x0001
-#define PCI_MEM_SPACE_ENABLE            0x0002
-#define PCI_BUSMASTER_ENABLE            0x0004
-#define PCI_MEMORY_WRITE_INVALIDATE     0x0010
-#define PCI_PARITY_ERROR_ENABLE         0x0040
-#define PCI_SYSTEM_ERROR_ENABLE         0x0100
-#define PCI_FAST_BACK_TO_BACK_ENABLE    0x0200
-
-#define PCI_STATUS_REG                  0x06
-#define PCI_REV_ID_REG                  0x08
-
-#define PCI_CACHE_LINE_SIZE_REG         0x0c
-
-#define PCI_IO_BASE_ADDR_REG            0x10
-#define PCI_IO_BASE_ADDR_MASK           0xfffffff0
-
-#define PCI_MEM_BASE_ADDR_LOW           0x10
-#define PCI_MEM_BASE_ADDR_HIGH          0x14
-
-#define PCI_SUBSYSTEM_VENDOR_ID_REG     0x2c
-#define PCI_SUBSYSTEM_ID_REG            0x2e
-#define PCI_INT_LINE_REG                0x3c
-
-#define PCIX_CAP_REG                    0x40
-#define PCIX_ENABLE_RELAXED_ORDERING    BIT_17
-
-/******************************************************************************/
-/* Fragment structure. */
-/******************************************************************************/
-
-typedef struct {
-       LM_UINT32 FragSize;
-       LM_PHYSICAL_ADDRESS FragBuf;
-} LM_FRAG, *PLM_FRAG;
-
-typedef struct {
-       /* FragCount is initialized for the caller to the maximum array size, on */
-       /* return FragCount is the number of the actual fragments in the array. */
-       LM_UINT32 FragCount;
-
-       /* Total buffer size. */
-       LM_UINT32 TotalSize;
-
-       /* Fragment array buffer. */
-       LM_FRAG Fragments[1];
-} LM_FRAG_LIST, *PLM_FRAG_LIST;
-
-#define DECLARE_FRAG_LIST_BUFFER_TYPE(_FRAG_LIST_TYPE_NAME, _MAX_FRAG_COUNT) \
-    typedef struct {                                                         \
-       LM_FRAG_LIST FragList;                                               \
-       LM_FRAG FragListBuffer[_MAX_FRAG_COUNT-1];                           \
-    } _FRAG_LIST_TYPE_NAME, *P##_FRAG_LIST_TYPE_NAME
-
-/******************************************************************************/
-/* Status codes. */
-/******************************************************************************/
-
-#define LM_STATUS_SUCCESS                                       0
-#define LM_STATUS_FAILURE                                       1
-
-#define LM_STATUS_INTERRUPT_ACTIVE                              2
-#define LM_STATUS_INTERRUPT_NOT_ACTIVE                          3
-
-#define LM_STATUS_LINK_ACTIVE                                   4
-#define LM_STATUS_LINK_DOWN                                     5
-#define LM_STATUS_LINK_SETTING_MISMATCH                         6
-
-#define LM_STATUS_TOO_MANY_FRAGMENTS                            7
-#define LM_STATUS_TRANSMIT_ABORTED                              8
-#define LM_STATUS_TRANSMIT_ERROR                                9
-#define LM_STATUS_RECEIVE_ABORTED                               10
-#define LM_STATUS_RECEIVE_ERROR                                 11
-#define LM_STATUS_INVALID_PACKET_SIZE                           12
-#define LM_STATUS_OUT_OF_MAP_REGISTERS                          13
-#define LM_STATUS_UNKNOWN_ADAPTER                               14
-
-typedef LM_UINT LM_STATUS, *PLM_STATUS;
-
-/******************************************************************************/
-/* Requested media type. */
-/******************************************************************************/
-
-#define LM_REQUESTED_MEDIA_TYPE_AUTO                            0
-#define LM_REQUESTED_MEDIA_TYPE_BNC                             1
-#define LM_REQUESTED_MEDIA_TYPE_UTP_AUTO                        2
-#define LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS                      3
-#define LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS_FULL_DUPLEX          4
-#define LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS                     5
-#define LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS_FULL_DUPLEX         6
-#define LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS                    7
-#define LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS_FULL_DUPLEX        8
-#define LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS                   9
-#define LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS_FULL_DUPLEX       10
-#define LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS                  11
-#define LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS_FULL_DUPLEX      12
-#define LM_REQUESTED_MEDIA_TYPE_MAC_LOOPBACK                    0xfffe
-#define LM_REQUESTED_MEDIA_TYPE_PHY_LOOPBACK                    0xffff
-
-typedef LM_UINT32 LM_REQUESTED_MEDIA_TYPE, *PLM_REQUESTED_MEDIA_TYPE;
-
-/******************************************************************************/
-/* Media type. */
-/******************************************************************************/
-
-#define LM_MEDIA_TYPE_UNKNOWN                                   -1
-#define LM_MEDIA_TYPE_AUTO                                      0
-#define LM_MEDIA_TYPE_UTP                                       1
-#define LM_MEDIA_TYPE_BNC                                       2
-#define LM_MEDIA_TYPE_AUI                                       3
-#define LM_MEDIA_TYPE_FIBER                                     4
-
-typedef LM_UINT32 LM_MEDIA_TYPE, *PLM_MEDIA_TYPE;
-
-/******************************************************************************/
-/* Line speed. */
-/******************************************************************************/
-
-#define LM_LINE_SPEED_UNKNOWN                                   0
-#define LM_LINE_SPEED_10MBPS                                    1
-#define LM_LINE_SPEED_100MBPS                                   2
-#define LM_LINE_SPEED_1000MBPS                                  3
-
-typedef LM_UINT32 LM_LINE_SPEED, *PLM_LINE_SPEED;
-
-/******************************************************************************/
-/* Duplex mode. */
-/******************************************************************************/
-
-#define LM_DUPLEX_MODE_UNKNOWN                                  0
-#define LM_DUPLEX_MODE_HALF                                     1
-#define LM_DUPLEX_MODE_FULL                                     2
-
-typedef LM_UINT32 LM_DUPLEX_MODE, *PLM_DUPLEX_MODE;
-
-/******************************************************************************/
-/* Power state. */
-/******************************************************************************/
-
-#define LM_POWER_STATE_D0       0
-#define LM_POWER_STATE_D1       1
-#define LM_POWER_STATE_D2       2
-#define LM_POWER_STATE_D3       3
-
-typedef LM_UINT32 LM_POWER_STATE, *PLM_POWER_STATE;
-
-/******************************************************************************/
-/* Task offloading. */
-/******************************************************************************/
-
-#define LM_TASK_OFFLOAD_NONE                    0x0000
-#define LM_TASK_OFFLOAD_TX_IP_CHECKSUM          0x0001
-#define LM_TASK_OFFLOAD_RX_IP_CHECKSUM          0x0002
-#define LM_TASK_OFFLOAD_TX_TCP_CHECKSUM         0x0004
-#define LM_TASK_OFFLOAD_RX_TCP_CHECKSUM         0x0008
-#define LM_TASK_OFFLOAD_TX_UDP_CHECKSUM         0x0010
-#define LM_TASK_OFFLOAD_RX_UDP_CHECKSUM         0x0020
-#define LM_TASK_OFFLOAD_TCP_SEGMENTATION        0x0040
-
-typedef LM_UINT32 LM_TASK_OFFLOAD, *PLM_TASK_OFFLOAD;
-
-/******************************************************************************/
-/* Flow control. */
-/******************************************************************************/
-
-#define LM_FLOW_CONTROL_NONE                    0x00
-#define LM_FLOW_CONTROL_RECEIVE_PAUSE           0x01
-#define LM_FLOW_CONTROL_TRANSMIT_PAUSE          0x02
-#define LM_FLOW_CONTROL_RX_TX_PAUSE (LM_FLOW_CONTROL_RECEIVE_PAUSE | \
-    LM_FLOW_CONTROL_TRANSMIT_PAUSE)
-
-/* This value can be or-ed with RECEIVE_PAUSE and TRANSMIT_PAUSE.  If the */
-/* auto-negotiation is disabled and the RECEIVE_PAUSE and TRANSMIT_PAUSE */
-/* bits are set, then flow control is enabled regardless of link partner's */
-/* flow control capability. */
-#define LM_FLOW_CONTROL_AUTO_PAUSE              0x80000000
-
-typedef LM_UINT32 LM_FLOW_CONTROL, *PLM_FLOW_CONTROL;
-
-/******************************************************************************/
-/* Wake up mode. */
-/******************************************************************************/
-
-#define LM_WAKE_UP_MODE_NONE                    0
-#define LM_WAKE_UP_MODE_MAGIC_PACKET            1
-#define LM_WAKE_UP_MODE_NWUF                    2
-#define LM_WAKE_UP_MODE_LINK_CHANGE             4
-
-typedef LM_UINT32 LM_WAKE_UP_MODE, *PLM_WAKE_UP_MODE;
-
-/******************************************************************************/
-/* Counters. */
-/******************************************************************************/
-
-#define LM_COUNTER_FRAMES_XMITTED_OK                            0
-#define LM_COUNTER_FRAMES_RECEIVED_OK                           1
-#define LM_COUNTER_ERRORED_TRANSMIT_COUNT                       2
-#define LM_COUNTER_ERRORED_RECEIVE_COUNT                        3
-#define LM_COUNTER_RCV_CRC_ERROR                                4
-#define LM_COUNTER_ALIGNMENT_ERROR                              5
-#define LM_COUNTER_SINGLE_COLLISION_FRAMES                      6
-#define LM_COUNTER_MULTIPLE_COLLISION_FRAMES                    7
-#define LM_COUNTER_FRAMES_DEFERRED                              8
-#define LM_COUNTER_MAX_COLLISIONS                               9
-#define LM_COUNTER_RCV_OVERRUN                                  10
-#define LM_COUNTER_XMIT_UNDERRUN                                11
-#define LM_COUNTER_UNICAST_FRAMES_XMIT                          12
-#define LM_COUNTER_MULTICAST_FRAMES_XMIT                        13
-#define LM_COUNTER_BROADCAST_FRAMES_XMIT                        14
-#define LM_COUNTER_UNICAST_FRAMES_RCV                           15
-#define LM_COUNTER_MULTICAST_FRAMES_RCV                         16
-#define LM_COUNTER_BROADCAST_FRAMES_RCV                         17
-
-typedef LM_UINT32 LM_COUNTER_TYPE, *PLM_COUNTER_TYPE;
-
-/******************************************************************************/
-/* Forward definition. */
-/******************************************************************************/
-
-typedef struct _LM_DEVICE_BLOCK *PLM_DEVICE_BLOCK;
-typedef struct _LM_PACKET *PLM_PACKET;
-
-/******************************************************************************/
-/* Function prototypes. */
-/******************************************************************************/
-
-LM_STATUS LM_GetAdapterInfo (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS LM_InitializeAdapter (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS LM_ResetAdapter (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS LM_DisableInterrupt (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS LM_EnableInterrupt (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS LM_SendPacket (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
-LM_STATUS LM_ServiceInterrupts (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS LM_QueueRxPackets (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS LM_SetReceiveMask (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Mask);
-LM_STATUS LM_Halt (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS LM_Abort (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS LM_MulticastAdd (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress);
-LM_STATUS LM_MulticastDel (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress);
-LM_STATUS LM_MulticastClear (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS LM_SetMacAddress (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMacAddress);
-LM_STATUS LM_LoopbackAddress (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pAddress);
-
-LM_UINT32 LM_GetCrcCounter (PLM_DEVICE_BLOCK pDevice);
-
-LM_WAKE_UP_MODE LM_PMCapabilities (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS LM_NwufAdd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 ByteMaskSize,
-                     LM_UINT8 * pByteMask, LM_UINT8 * pPattern);
-LM_STATUS LM_NwufRemove (PLM_DEVICE_BLOCK pDevice, LM_UINT32 ByteMaskSize,
-                        LM_UINT8 * pByteMask, LM_UINT8 * pPattern);
-LM_STATUS LM_SetPowerState (PLM_DEVICE_BLOCK pDevice,
-                           LM_POWER_STATE PowerLevel);
-
-LM_VOID LM_ReadPhy (PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg,
-                   PLM_UINT32 pData32);
-LM_VOID LM_WritePhy (PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg,
-                    LM_UINT32 Data32);
-
-LM_STATUS LM_ControlLoopBack (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Control);
-LM_STATUS LM_SetupPhy (PLM_DEVICE_BLOCK pDevice);
-int LM_BlinkLED (PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlinkDuration);
-
-/******************************************************************************/
-/* These are the OS specific functions called by LMAC. */
-/******************************************************************************/
-
-LM_STATUS MM_ReadConfig16 (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
-                          LM_UINT16 * pValue16);
-LM_STATUS MM_WriteConfig16 (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
-                           LM_UINT16 Value16);
-LM_STATUS MM_ReadConfig32 (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
-                          LM_UINT32 * pValue32);
-LM_STATUS MM_WriteConfig32 (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
-                           LM_UINT32 Value32);
-LM_STATUS MM_MapMemBase (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS MM_MapIoBase (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS MM_IndicateRxPackets (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS MM_IndicateTxPackets (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS MM_StartTxDma (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
-LM_STATUS MM_CompleteTxDma (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
-LM_STATUS MM_AllocateMemory (PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
-                            PLM_VOID * pMemoryBlockVirt);
-LM_STATUS MM_AllocateSharedMemory (PLM_DEVICE_BLOCK pDevice,
-                                  LM_UINT32 BlockSize,
-                                  PLM_VOID * pMemoryBlockVirt,
-                                  PLM_PHYSICAL_ADDRESS pMemoryBlockPhy,
-                                  LM_BOOL Cached);
-LM_STATUS MM_GetConfig (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS MM_IndicateStatus (PLM_DEVICE_BLOCK pDevice, LM_STATUS Status);
-LM_STATUS MM_InitializeUmPackets (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS MM_FreeRxBuffer (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
-LM_STATUS MM_CoalesceTxBuffer (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
-LM_STATUS LM_MbufWorkAround (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS LM_SetLinkSpeed (PLM_DEVICE_BLOCK pDevice,
-                          LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
-
-#if INCLUDE_5703_A0_FIX
-LM_STATUS LM_Load5703DmaWFirmware (PLM_DEVICE_BLOCK pDevice);
-#endif
-
-#endif                         /* LM_H */
diff --git a/drivers/bcm570x_mm.h b/drivers/bcm570x_mm.h
deleted file mode 100644 (file)
index ff5302f..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-
-/******************************************************************************/
-/*                                                                            */
-/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
-/* Corporation.                                                               */
-/* All rights reserved.                                                       */
-/*                                                                            */
-/* This program is free software; you can redistribute it and/or modify       */
-/* it under the terms of the GNU General Public License as published by       */
-/* the Free Software Foundation, located in the file LICENSE.                 */
-/*                                                                            */
-/******************************************************************************/
-
-#ifndef MM_H
-#define MM_H
-
-#define __raw_readl readl
-#define __raw_writel writel
-
-#define BIG_ENDIAN_HOST 1
-#define readl(addr) (*(volatile unsigned int*)(addr))
-#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
-
-/* Define memory barrier function here if needed */
-#define wmb()
-#define membar()
-#include <common.h>
-#include <asm/types.h>
-#include "bcm570x_lm.h"
-#include "bcm570x_queue.h"
-#include "tigon3.h"
-#include <pci.h>
-
-#define FALSE 0
-#define TRUE  1
-#define ERROR -1
-
-#if DBG
-#define STATIC
-#else
-#define STATIC static
-#endif
-
-extern int MM_Packet_Desc_Size;
-
-#define MM_PACKET_DESC_SIZE MM_Packet_Desc_Size
-
-DECLARE_QUEUE_TYPE (UM_RX_PACKET_Q, MAX_RX_PACKET_DESC_COUNT + 1);
-
-#define MAX_MEM 16
-
-/* Synch */
-typedef int mutex_t;
-typedef int spinlock_t;
-
-/* Embedded device control */
-typedef struct _UM_DEVICE_BLOCK {
-       LM_DEVICE_BLOCK lm_dev;
-       pci_dev_t pdev;
-       char *name;
-       void *mem_list[MAX_MEM];
-       dma_addr_t dma_list[MAX_MEM];
-       int mem_size_list[MAX_MEM];
-       int mem_list_num;
-       int mtu;
-       int index;
-       int opened;
-       int delayed_link_ind;   /* Delay link status during initial load */
-       int adapter_just_inited;        /* the first few seconds after init. */
-       int spurious_int;       /* new -- unsupported */
-       int timer_interval;
-       int adaptive_expiry;
-       int crc_counter_expiry; /* new -- unsupported */
-       int poll_tib_expiry;    /* new -- unsupported */
-       int tx_full;
-       int tx_queued;
-       int line_speed;         /* in Mbps, 0 if link is down */
-       UM_RX_PACKET_Q rx_out_of_buf_q;
-       int rx_out_of_buf;
-       int rx_low_buf_thresh;  /* changed to rx_buf_repl_thresh */
-       int rx_buf_repl_panic_thresh;
-       int rx_buf_align;       /* new -- unsupported */
-       int do_global_lock;
-       mutex_t global_lock;
-       mutex_t undi_lock;
-       long undi_flags;
-       volatile int interrupt;
-       int tasklet_pending;
-       int tasklet_busy;       /* new -- unsupported */
-       int rx_pkt;
-       int tx_pkt;
-#ifdef NICE_SUPPORT            /* unsupported, this is a linux ioctl */
-       void (*nice_rx) (void *, void *);
-       void *nice_ctx;
-#endif                         /* NICE_SUPPORT */
-       int rx_adaptive_coalesce;
-       unsigned int rx_last_cnt;
-       unsigned int tx_last_cnt;
-       unsigned int rx_curr_coalesce_frames;
-       unsigned int rx_curr_coalesce_ticks;
-       unsigned int tx_curr_coalesce_frames;   /* new -- unsupported */
-#if TIGON3_DEBUG               /* new -- unsupported */
-       uint tx_zc_count;
-       uint tx_chksum_count;
-       uint tx_himem_count;
-       uint rx_good_chksum_count;
-#endif
-       unsigned int rx_bad_chksum_count;       /* new -- unsupported */
-       unsigned int rx_misc_errors;    /* new -- unsupported */
-} UM_DEVICE_BLOCK, *PUM_DEVICE_BLOCK;
-
-/* Physical/PCI DMA address */
-typedef union {
-       dma_addr_t dma_map;
-} dma_map_t;
-
-/* Packet */
-typedef struct
-    _UM_PACKET {
-       LM_PACKET lm_packet;
-       void *skbuff;           /* Address of packet buffer */
-} UM_PACKET, *PUM_PACKET;
-
-#define MM_ACQUIRE_UNDI_LOCK(_pDevice)
-#define MM_RELEASE_UNDI_LOCK(_pDevice)
-#define MM_ACQUIRE_INT_LOCK(_pDevice)
-#define MM_RELEASE_INT_LOCK(_pDevice)
-#define MM_UINT_PTR(_ptr)   ((unsigned long) (_ptr))
-
-/* Macro for setting 64bit address struct */
-#define set_64bit_addr(paddr, low, high) \
-       (paddr)->Low = low;             \
-       (paddr)->High = high;
-
-/* Assume that PCI controller's view of host memory is same as host */
-
-#define MEM_TO_PCI_PHYS(addr) (addr)
-
-extern void MM_SetAddr (LM_PHYSICAL_ADDRESS * paddr, dma_addr_t addr);
-extern void MM_SetT3Addr (T3_64BIT_HOST_ADDR * paddr, dma_addr_t addr);
-extern void MM_MapTxDma (PLM_DEVICE_BLOCK pDevice,
-                        struct _LM_PACKET *pPacket, T3_64BIT_HOST_ADDR * paddr,
-                        LM_UINT32 * len, int frag);
-extern void MM_MapRxDma (PLM_DEVICE_BLOCK pDevice,
-                        struct _LM_PACKET *pPacket,
-                        T3_64BIT_HOST_ADDR * paddr);
-
-/* BSP needs to provide sysUsecDelay and sysSerialPrintString */
-extern void sysSerialPrintString (char *s);
-#define MM_Wait(usec) udelay(usec)
-
-/* Define memory barrier function here if needed */
-#define wmb()
-
-#if 0
-#define cpu_to_le32(val) LONGSWAP(val)
-#endif
-#endif                         /* MM_H */
diff --git a/drivers/bcm570x_queue.h b/drivers/bcm570x_queue.h
deleted file mode 100644 (file)
index 336b3ca..0000000
+++ /dev/null
@@ -1,387 +0,0 @@
-
-/******************************************************************************/
-/*                                                                            */
-/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
-/* Corporation.                                                               */
-/* All rights reserved.                                                       */
-/*                                                                            */
-/* This program is free software; you can redistribute it and/or modify       */
-/* it under the terms of the GNU General Public License as published by       */
-/* the Free Software Foundation, located in the file LICENSE.                 */
-/*                                                                            */
-/* Queue functions.                                                           */
-/*    void          QQ_InitQueue(PQQ_CONTAINER pQueue)                        */
-/*    char          QQ_Full(PQQ_CONTAINER pQueue)                             */
-/*    char          QQ_Empty(PQQ_CONTAINER pQueue)                            */
-/*    unsigned int QQ_GetSize(PQQ_CONTAINER pQueue)                          */
-/*    unsigned int QQ_GetEntryCnt(PQQ_CONTAINER pQueue)                      */
-/*    char          QQ_PushHead(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry)       */
-/*    char          QQ_PushTail(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry)       */
-/*    PQQ_ENTRY     QQ_PopHead(PQQ_CONTAINER pQueue)                          */
-/*    PQQ_ENTRY     QQ_PopTail(PQQ_CONTAINER pQueue)                          */
-/*    PQQ_ENTRY     QQ_GetHead(PQQ_CONTAINER pQueue, unsigned int Idx)       */
-/*    PQQ_ENTRY     QQ_GetTail(PQQ_CONTAINER pQueue, unsigned int Idx)       */
-/*                                                                            */
-/*                                                                            */
-/* History:                                                                   */
-/*    02/25/00 Hav Khauv        Initial version.                              */
-/******************************************************************************/
-
-#ifndef BCM_QUEUE_H
-#define BCM_QUEUE_H
-#ifndef EMBEDDED
-#define EMBEDDED 1
-#endif
-
-/******************************************************************************/
-/* Queue definitions. */
-/******************************************************************************/
-
-/* Entry for queueing. */
-typedef void *PQQ_ENTRY;
-
-/* Linux Atomic Ops support */
-typedef struct { int counter; } atomic_t;
-
-
-/*
- * This combination of `inline' and `extern' has almost the effect of a
- * macro.  The way to use it is to put a function definition in a header
- * file with these keywords, and put another copy of the definition
- * (lacking `inline' and `extern') in a library file.  The definition in
- * the header file will cause most calls to the function to be inlined.
- * If any uses of the function remain, they will refer to the single copy
- * in the library.
- */
-extern __inline void
-atomic_set(atomic_t* entry, int val)
-{
-    entry->counter = val;
-}
-extern __inline int
-atomic_read(atomic_t* entry)
-{
-    return entry->counter;
-}
-extern __inline void
-atomic_inc(atomic_t* entry)
-{
-    if(entry)
-       entry->counter++;
-}
-
-extern __inline void
-atomic_dec(atomic_t* entry)
-{
-    if(entry)
-       entry->counter--;
-}
-
-extern __inline void
-atomic_sub(int a, atomic_t* entry)
-{
-    if(entry)
-       entry->counter -= a;
-}
-extern __inline void
-atomic_add(int a, atomic_t* entry)
-{
-    if(entry)
-       entry->counter += a;
-}
-
-
-/* Queue header -- base type. */
-typedef struct {
-    unsigned int Head;
-    unsigned int Tail;
-    unsigned int Size;
-    atomic_t EntryCnt;
-    PQQ_ENTRY Array[1];
-} QQ_CONTAINER, *PQQ_CONTAINER;
-
-
-/* Declare queue type macro. */
-#define DECLARE_QUEUE_TYPE(_QUEUE_TYPE, _QUEUE_SIZE)            \
-                                                               \
-    typedef struct {                                            \
-       QQ_CONTAINER Container;                                 \
-       PQQ_ENTRY EntryBuffer[_QUEUE_SIZE];                     \
-    } _QUEUE_TYPE, *P##_QUEUE_TYPE
-
-
-/******************************************************************************/
-/* Compilation switches. */
-/******************************************************************************/
-
-#if DBG
-#undef QQ_NO_OVERFLOW_CHECK
-#undef QQ_NO_UNDERFLOW_CHECK
-#endif /* DBG */
-
-#ifdef QQ_USE_MACROS
-/* notdone */
-#else
-
-#ifdef QQ_NO_INLINE
-#define __inline
-#endif /* QQ_NO_INLINE */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-extern __inline void
-QQ_InitQueue(
-PQQ_CONTAINER pQueue,
-unsigned int QueueSize) {
-    pQueue->Head = 0;
-    pQueue->Tail = 0;
-    pQueue->Size = QueueSize+1;
-    atomic_set(&pQueue->EntryCnt, 0);
-} /* QQ_InitQueue */
-
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-extern __inline char
-QQ_Full(
-PQQ_CONTAINER pQueue) {
-    unsigned int NewHead;
-
-    NewHead = (pQueue->Head + 1) % pQueue->Size;
-
-    return(NewHead == pQueue->Tail);
-} /* QQ_Full */
-
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-extern __inline char
-QQ_Empty(
-PQQ_CONTAINER pQueue) {
-    return(pQueue->Head == pQueue->Tail);
-} /* QQ_Empty */
-
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-extern __inline unsigned int
-QQ_GetSize(
-PQQ_CONTAINER pQueue) {
-    return pQueue->Size;
-} /* QQ_GetSize */
-
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-extern __inline unsigned int
-QQ_GetEntryCnt(
-PQQ_CONTAINER pQueue) {
-    return atomic_read(&pQueue->EntryCnt);
-} /* QQ_GetEntryCnt */
-
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/*    TRUE entry was added successfully.                                      */
-/*    FALSE queue is full.                                                    */
-/******************************************************************************/
-extern __inline char
-QQ_PushHead(
-PQQ_CONTAINER pQueue,
-PQQ_ENTRY pEntry) {
-    unsigned int Head;
-
-    Head = (pQueue->Head + 1) % pQueue->Size;
-
-#if !defined(QQ_NO_OVERFLOW_CHECK)
-    if(Head == pQueue->Tail) {
-       return 0;
-    } /* if */
-#endif /* QQ_NO_OVERFLOW_CHECK */
-
-    pQueue->Array[pQueue->Head] = pEntry;
-    wmb();
-    pQueue->Head = Head;
-    atomic_inc(&pQueue->EntryCnt);
-
-    return -1;
-} /* QQ_PushHead */
-
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/*    TRUE entry was added successfully.                                      */
-/*    FALSE queue is full.                                                    */
-/******************************************************************************/
-extern __inline char
-QQ_PushTail(
-PQQ_CONTAINER pQueue,
-PQQ_ENTRY pEntry) {
-    unsigned int Tail;
-
-    Tail = pQueue->Tail;
-    if(Tail == 0) {
-       Tail = pQueue->Size;
-    } /* if */
-    Tail--;
-
-#if !defined(QQ_NO_OVERFLOW_CHECK)
-    if(Tail == pQueue->Head) {
-       return 0;
-    } /* if */
-#endif /* QQ_NO_OVERFLOW_CHECK */
-
-    pQueue->Array[Tail] = pEntry;
-    wmb();
-    pQueue->Tail = Tail;
-    atomic_inc(&pQueue->EntryCnt);
-
-    return -1;
-} /* QQ_PushTail */
-
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-extern __inline PQQ_ENTRY
-QQ_PopHead(
-PQQ_CONTAINER pQueue) {
-    unsigned int Head;
-    PQQ_ENTRY Entry;
-
-    Head = pQueue->Head;
-
-#if !defined(QQ_NO_UNDERFLOW_CHECK)
-    if(Head == pQueue->Tail) {
-       return (PQQ_ENTRY) 0;
-    } /* if */
-#endif /* QQ_NO_UNDERFLOW_CHECK */
-
-    if(Head == 0) {
-       Head = pQueue->Size;
-    } /* if */
-    Head--;
-
-    Entry = pQueue->Array[Head];
-#ifdef EMBEDDED
-    membar();
-#else
-    mb();
-#endif
-    pQueue->Head = Head;
-    atomic_dec(&pQueue->EntryCnt);
-
-    return Entry;
-} /* QQ_PopHead */
-
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-extern __inline PQQ_ENTRY
-QQ_PopTail(
-PQQ_CONTAINER pQueue) {
-    unsigned int Tail;
-    PQQ_ENTRY Entry;
-
-    Tail = pQueue->Tail;
-
-#if !defined(QQ_NO_UNDERFLOW_CHECK)
-    if(Tail == pQueue->Head) {
-       return (PQQ_ENTRY) 0;
-    } /* if */
-#endif /* QQ_NO_UNDERFLOW_CHECK */
-
-    Entry = pQueue->Array[Tail];
-#ifdef EMBEDDED
-    membar();
-#else
-    mb();
-#endif
-    pQueue->Tail = (Tail + 1) % pQueue->Size;
-    atomic_dec(&pQueue->EntryCnt);
-
-    return Entry;
-} /* QQ_PopTail */
-
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-extern __inline PQQ_ENTRY
-QQ_GetHead(
-    PQQ_CONTAINER pQueue,
-    unsigned int Idx)
-{
-    if(Idx >= atomic_read(&pQueue->EntryCnt))
-    {
-       return (PQQ_ENTRY) 0;
-    }
-
-    if(pQueue->Head > Idx)
-    {
-       Idx = pQueue->Head - Idx;
-    }
-    else
-    {
-       Idx = pQueue->Size - (Idx - pQueue->Head);
-    }
-    Idx--;
-
-    return pQueue->Array[Idx];
-}
-
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-extern __inline PQQ_ENTRY
-QQ_GetTail(
-    PQQ_CONTAINER pQueue,
-    unsigned int Idx)
-{
-    if(Idx >= atomic_read(&pQueue->EntryCnt))
-    {
-       return (PQQ_ENTRY) 0;
-    }
-
-    Idx += pQueue->Tail;
-    if(Idx >= pQueue->Size)
-    {
-       Idx = Idx - pQueue->Size;
-    }
-
-    return pQueue->Array[Idx];
-}
-
-#endif /* QQ_USE_MACROS */
-
-
-#endif /* QUEUE_H */
index 8f1d8b29d59d3bd35f076ef5f194f0f88d27f6e2..cb1b0c1b958a473072e483c23b62187d01bfe258 100644 (file)
@@ -96,7 +96,7 @@ static u8 *BE_memaddr(u32 addr)
        else if (addr >= 0xFFFF5 && addr < 0xFFFFE) {
                /* Return a faked BIOS date string for non-x86 machines */
                DB(printf("BE_memaddr - Returning BIOS date\n");)
-               return BE_biosDate + addr - 0xFFFF5;
+               return (u8 *)(BE_biosDate + addr - 0xFFFF5);
        } else if (addr == 0xFFFFE) {
                /* Return system model identifier for non-x86 machines */
                DB(printf("BE_memaddr - Returning model\n");)
index ccfc872f788bf84fbd2fa3d043befd8e5bf1b675..75ceb458cfeb9feac04b24af85c566a859cf6f1b 100644 (file)
@@ -96,7 +96,7 @@ int X86API BE_init(u32 debugFlags, int memSize, BE_VGAInfo * info, int shared)
                return 0;
        }
 
-       M.mem_base = (unsigned long)malloc(memSize);
+       M.mem_base = malloc(memSize);
 
        if (M.mem_base == NULL){
                printf("Biosemu:Out of memory!");
@@ -106,7 +106,7 @@ int X86API BE_init(u32 debugFlags, int memSize, BE_VGAInfo * info, int shared)
 
        _BE_env.emulateVGA = 0;
        _BE_env.busmem_base = (unsigned long)malloc(128 * 1024);
-       if (_BE_env.busmem_base == NULL){
+       if ((void *)_BE_env.busmem_base == NULL){
                printf("Biosemu:Out of memory!");
                return 0;
        }
@@ -230,7 +230,7 @@ Cleans up and exits the emulator.
 void X86API BE_exit(void)
 {
        free(M.mem_base);
-       free(_BE_env.busmem_base);
+       free((void *)_BE_env.busmem_base);
 }
 
 /****************************************************************************
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
new file mode 100644 (file)
index 0000000..e069969
--- /dev/null
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libblock.a
+
+COBJS-y += ahci.o
+COBJS-y += ata_piix.o
+COBJS-y += sil680.o
+COBJS-y += sym53c8xx.o
+COBJS-y += systemace.o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c
new file mode 100644 (file)
index 0000000..3d82c62
--- /dev/null
@@ -0,0 +1,703 @@
+/*
+ * Copyright (C) Freescale Semiconductor, Inc. 2006. All rights reserved.
+ * Author: Jason Jin<Jason.jin@freescale.com>
+ *         Zhang Wei<wei.zhang@freescale.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * with the reference on libata and ahci drvier in kernel
+ *
+ */
+#include <common.h>
+
+#ifdef CONFIG_SCSI_AHCI
+
+#include <command.h>
+#include <pci.h>
+#include <asm/processor.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <scsi.h>
+#include <ata.h>
+#include <linux/ctype.h>
+#include <ahci.h>
+
+struct ahci_probe_ent *probe_ent = NULL;
+hd_driveid_t *ataid[AHCI_MAX_PORTS];
+
+#define writel_with_flush(a,b) do { writel(a,b); readl(b); } while (0)
+
+
+static inline u32 ahci_port_base(u32 base, u32 port)
+{
+       return base + 0x100 + (port * 0x80);
+}
+
+
+static void ahci_setup_port(struct ahci_ioports *port, unsigned long base,
+                           unsigned int port_idx)
+{
+       base = ahci_port_base(base, port_idx);
+
+       port->cmd_addr = base;
+       port->scr_addr = base + PORT_SCR;
+}
+
+
+#define msleep(a) udelay(a * 1000)
+#define ssleep(a) msleep(a * 1000)
+
+static int waiting_for_cmd_completed(volatile u8 *offset,
+                                    int timeout_msec,
+                                    u32 sign)
+{
+       int i;
+       u32 status;
+
+       for (i = 0; ((status = readl(offset)) & sign) && i < timeout_msec; i++)
+               msleep(1);
+
+       return (i < timeout_msec) ? 0 : -1;
+}
+
+
+static int ahci_host_init(struct ahci_probe_ent *probe_ent)
+{
+       pci_dev_t pdev = probe_ent->dev;
+       volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base;
+       u32 tmp, cap_save;
+       u16 tmp16;
+       int i, j;
+       volatile u8 *port_mmio;
+       unsigned short vendor;
+
+       cap_save = readl(mmio + HOST_CAP);
+       cap_save &= ((1 << 28) | (1 << 17));
+       cap_save |= (1 << 27);
+
+       /* global controller reset */
+       tmp = readl(mmio + HOST_CTL);
+       if ((tmp & HOST_RESET) == 0)
+               writel_with_flush(tmp | HOST_RESET, mmio + HOST_CTL);
+
+       /* reset must complete within 1 second, or
+        * the hardware should be considered fried.
+        */
+       ssleep(1);
+
+       tmp = readl(mmio + HOST_CTL);
+       if (tmp & HOST_RESET) {
+               debug("controller reset failed (0x%x)\n", tmp);
+               return -1;
+       }
+
+       writel_with_flush(HOST_AHCI_EN, mmio + HOST_CTL);
+       writel(cap_save, mmio + HOST_CAP);
+       writel_with_flush(0xf, mmio + HOST_PORTS_IMPL);
+
+       pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);
+
+       if (vendor == PCI_VENDOR_ID_INTEL) {
+               u16 tmp16;
+               pci_read_config_word(pdev, 0x92, &tmp16);
+               tmp16 |= 0xf;
+               pci_write_config_word(pdev, 0x92, tmp16);
+       }
+
+       probe_ent->cap = readl(mmio + HOST_CAP);
+       probe_ent->port_map = readl(mmio + HOST_PORTS_IMPL);
+       probe_ent->n_ports = (probe_ent->cap & 0x1f) + 1;
+
+       debug("cap 0x%x  port_map 0x%x  n_ports %d\n",
+             probe_ent->cap, probe_ent->port_map, probe_ent->n_ports);
+
+       for (i = 0; i < probe_ent->n_ports; i++) {
+               probe_ent->port[i].port_mmio = ahci_port_base((u32) mmio, i);
+               port_mmio = (u8 *) probe_ent->port[i].port_mmio;
+               ahci_setup_port(&probe_ent->port[i], (unsigned long)mmio, i);
+
+               /* make sure port is not active */
+               tmp = readl(port_mmio + PORT_CMD);
+               if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
+                          PORT_CMD_FIS_RX | PORT_CMD_START)) {
+                       tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
+                                PORT_CMD_FIS_RX | PORT_CMD_START);
+                       writel_with_flush(tmp, port_mmio + PORT_CMD);
+
+                       /* spec says 500 msecs for each bit, so
+                        * this is slightly incorrect.
+                        */
+                       msleep(500);
+               }
+
+               writel(PORT_CMD_SPIN_UP, port_mmio + PORT_CMD);
+
+               j = 0;
+               while (j < 100) {
+                       msleep(10);
+                       tmp = readl(port_mmio + PORT_SCR_STAT);
+                       if ((tmp & 0xf) == 0x3)
+                               break;
+                       j++;
+               }
+
+               tmp = readl(port_mmio + PORT_SCR_ERR);
+               debug("PORT_SCR_ERR 0x%x\n", tmp);
+               writel(tmp, port_mmio + PORT_SCR_ERR);
+
+               /* ack any pending irq events for this port */
+               tmp = readl(port_mmio + PORT_IRQ_STAT);
+               debug("PORT_IRQ_STAT 0x%x\n", tmp);
+               if (tmp)
+                       writel(tmp, port_mmio + PORT_IRQ_STAT);
+
+               writel(1 << i, mmio + HOST_IRQ_STAT);
+
+               /* set irq mask (enables interrupts) */
+               writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK);
+
+               /*register linkup ports */
+               tmp = readl(port_mmio + PORT_SCR_STAT);
+               debug("Port %d status: 0x%x\n", i, tmp);
+               if ((tmp & 0xf) == 0x03)
+                       probe_ent->link_port_map |= (0x01 << i);
+       }
+
+       tmp = readl(mmio + HOST_CTL);
+       debug("HOST_CTL 0x%x\n", tmp);
+       writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
+       tmp = readl(mmio + HOST_CTL);
+       debug("HOST_CTL 0x%x\n", tmp);
+
+       pci_read_config_word(pdev, PCI_COMMAND, &tmp16);
+       tmp |= PCI_COMMAND_MASTER;
+       pci_write_config_word(pdev, PCI_COMMAND, tmp16);
+
+       return 0;
+}
+
+
+static void ahci_print_info(struct ahci_probe_ent *probe_ent)
+{
+       pci_dev_t pdev = probe_ent->dev;
+       volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base;
+       u32 vers, cap, impl, speed;
+       const char *speed_s;
+       u16 cc;
+       const char *scc_s;
+
+       vers = readl(mmio + HOST_VERSION);
+       cap = probe_ent->cap;
+       impl = probe_ent->port_map;
+
+       speed = (cap >> 20) & 0xf;
+       if (speed == 1)
+               speed_s = "1.5";
+       else if (speed == 2)
+               speed_s = "3";
+       else
+               speed_s = "?";
+
+       pci_read_config_word(pdev, 0x0a, &cc);
+       if (cc == 0x0101)
+               scc_s = "IDE";
+       else if (cc == 0x0106)
+               scc_s = "SATA";
+       else if (cc == 0x0104)
+               scc_s = "RAID";
+       else
+               scc_s = "unknown";
+
+       printf("AHCI %02x%02x.%02x%02x "
+              "%u slots %u ports %s Gbps 0x%x impl %s mode\n",
+              (vers >> 24) & 0xff,
+              (vers >> 16) & 0xff,
+              (vers >> 8) & 0xff,
+              vers & 0xff,
+              ((cap >> 8) & 0x1f) + 1, (cap & 0x1f) + 1, speed_s, impl, scc_s);
+
+       printf("flags: "
+              "%s%s%s%s%s%s"
+              "%s%s%s%s%s%s%s\n",
+              cap & (1 << 31) ? "64bit " : "",
+              cap & (1 << 30) ? "ncq " : "",
+              cap & (1 << 28) ? "ilck " : "",
+              cap & (1 << 27) ? "stag " : "",
+              cap & (1 << 26) ? "pm " : "",
+              cap & (1 << 25) ? "led " : "",
+              cap & (1 << 24) ? "clo " : "",
+              cap & (1 << 19) ? "nz " : "",
+              cap & (1 << 18) ? "only " : "",
+              cap & (1 << 17) ? "pmp " : "",
+              cap & (1 << 15) ? "pio " : "",
+              cap & (1 << 14) ? "slum " : "",
+              cap & (1 << 13) ? "part " : "");
+}
+
+static int ahci_init_one(pci_dev_t pdev)
+{
+       u32 iobase;
+       u16 vendor;
+       int rc;
+
+       memset((void *)ataid, 0, sizeof(hd_driveid_t *) * AHCI_MAX_PORTS);
+
+       probe_ent = malloc(sizeof(struct ahci_probe_ent));
+       memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
+       probe_ent->dev = pdev;
+
+       pci_read_config_dword(pdev, AHCI_PCI_BAR, &iobase);
+       iobase &= ~0xf;
+
+       probe_ent->host_flags = ATA_FLAG_SATA
+                               | ATA_FLAG_NO_LEGACY
+                               | ATA_FLAG_MMIO
+                               | ATA_FLAG_PIO_DMA
+                               | ATA_FLAG_NO_ATAPI;
+       probe_ent->pio_mask = 0x1f;
+       probe_ent->udma_mask = 0x7f;    /*Fixme,assume to support UDMA6 */
+
+       probe_ent->mmio_base = iobase;
+
+       /* Take from kernel:
+        * JMicron-specific fixup:
+        * make sure we're in AHCI mode
+        */
+       pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);
+       if (vendor == 0x197b)
+               pci_write_config_byte(pdev, 0x41, 0xa1);
+
+       /* initialize adapter */
+       rc = ahci_host_init(probe_ent);
+       if (rc)
+               goto err_out;
+
+       ahci_print_info(probe_ent);
+
+       return 0;
+
+      err_out:
+       return rc;
+}
+
+
+#define MAX_DATA_BYTE_COUNT  (4*1024*1024)
+
+static int ahci_fill_sg(u8 port, unsigned char *buf, int buf_len)
+{
+       struct ahci_ioports *pp = &(probe_ent->port[port]);
+       struct ahci_sg *ahci_sg = pp->cmd_tbl_sg;
+       u32 sg_count;
+       int i;
+
+       sg_count = ((buf_len - 1) / MAX_DATA_BYTE_COUNT) + 1;
+       if (sg_count > AHCI_MAX_SG) {
+               printf("Error:Too much sg!\n");
+               return -1;
+       }
+
+       for (i = 0; i < sg_count; i++) {
+               ahci_sg->addr =
+                   cpu_to_le32((u32) buf + i * MAX_DATA_BYTE_COUNT);
+               ahci_sg->addr_hi = 0;
+               ahci_sg->flags_size = cpu_to_le32(0x3fffff &
+                                         (buf_len < MAX_DATA_BYTE_COUNT
+                                          ? (buf_len - 1)
+                                          : (MAX_DATA_BYTE_COUNT - 1)));
+               ahci_sg++;
+               buf_len -= MAX_DATA_BYTE_COUNT;
+       }
+
+       return sg_count;
+}
+
+
+static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 opts)
+{
+       pp->cmd_slot->opts = cpu_to_le32(opts);
+       pp->cmd_slot->status = 0;
+       pp->cmd_slot->tbl_addr = cpu_to_le32(pp->cmd_tbl & 0xffffffff);
+       pp->cmd_slot->tbl_addr_hi = 0;
+}
+
+
+static void ahci_set_feature(u8 port)
+{
+       struct ahci_ioports *pp = &(probe_ent->port[port]);
+       volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
+       u32 cmd_fis_len = 5;    /* five dwords */
+       u8 fis[20];
+
+       /*set feature */
+       memset(fis, 0, 20);
+       fis[0] = 0x27;
+       fis[1] = 1 << 7;
+       fis[2] = ATA_CMD_SETF;
+       fis[3] = SETFEATURES_XFER;
+       fis[12] = __ilog2(probe_ent->udma_mask + 1) + 0x40 - 0x01;
+
+       memcpy((unsigned char *)pp->cmd_tbl, fis, 20);
+       ahci_fill_cmd_slot(pp, cmd_fis_len);
+       writel(1, port_mmio + PORT_CMD_ISSUE);
+       readl(port_mmio + PORT_CMD_ISSUE);
+
+       if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, 150, 0x1)) {
+               printf("set feature error!\n");
+       }
+}
+
+
+static int ahci_port_start(u8 port)
+{
+       struct ahci_ioports *pp = &(probe_ent->port[port]);
+       volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
+       u32 port_status;
+       u32 mem;
+
+       debug("Enter start port: %d\n", port);
+       port_status = readl(port_mmio + PORT_SCR_STAT);
+       debug("Port %d status: %x\n", port, port_status);
+       if ((port_status & 0xf) != 0x03) {
+               printf("No Link on this port!\n");
+               return -1;
+       }
+
+       mem = (u32) malloc(AHCI_PORT_PRIV_DMA_SZ + 2048);
+       if (!mem) {
+               free(pp);
+               printf("No mem for table!\n");
+               return -ENOMEM;
+       }
+
+       mem = (mem + 0x800) & (~0x7ff); /* Aligned to 2048-bytes */
+       memset((u8 *) mem, 0, AHCI_PORT_PRIV_DMA_SZ);
+
+       /*
+        * First item in chunk of DMA memory: 32-slot command table,
+        * 32 bytes each in size
+        */
+       pp->cmd_slot = (struct ahci_cmd_hdr *)mem;
+       debug("cmd_slot = 0x%x\n", pp->cmd_slot);
+       mem += (AHCI_CMD_SLOT_SZ + 224);
+
+       /*
+        * Second item: Received-FIS area
+        */
+       pp->rx_fis = mem;
+       mem += AHCI_RX_FIS_SZ;
+
+       /*
+        * Third item: data area for storing a single command
+        * and its scatter-gather table
+        */
+       pp->cmd_tbl = mem;
+       debug("cmd_tbl_dma = 0x%x\n", pp->cmd_tbl);
+
+       mem += AHCI_CMD_TBL_HDR;
+       pp->cmd_tbl_sg = (struct ahci_sg *)mem;
+
+       writel_with_flush((u32) pp->cmd_slot, port_mmio + PORT_LST_ADDR);
+
+       writel_with_flush(pp->rx_fis, port_mmio + PORT_FIS_ADDR);
+
+       writel_with_flush(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
+                         PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
+                         PORT_CMD_START, port_mmio + PORT_CMD);
+
+       debug("Exit start port %d\n", port);
+
+       return 0;
+}
+
+
+static int get_ahci_device_data(u8 port, u8 *fis, int fis_len, u8 *buf,
+                               int buf_len)
+{
+
+       struct ahci_ioports *pp = &(probe_ent->port[port]);
+       volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
+       u32 opts;
+       u32 port_status;
+       int sg_count;
+
+       debug("Enter get_ahci_device_data: for port %d\n", port);
+
+       if (port > probe_ent->n_ports) {
+               printf("Invaild port number %d\n", port);
+               return -1;
+       }
+
+       port_status = readl(port_mmio + PORT_SCR_STAT);
+       if ((port_status & 0xf) != 0x03) {
+               debug("No Link on port %d!\n", port);
+               return -1;
+       }
+
+       memcpy((unsigned char *)pp->cmd_tbl, fis, fis_len);
+
+       sg_count = ahci_fill_sg(port, buf, buf_len);
+       opts = (fis_len >> 2) | (sg_count << 16);
+       ahci_fill_cmd_slot(pp, opts);
+
+       writel_with_flush(1, port_mmio + PORT_CMD_ISSUE);
+
+       if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, 150, 0x1)) {
+               printf("timeout exit!\n");
+               return -1;
+       }
+       debug("get_ahci_device_data: %d byte transferred.\n",
+             pp->cmd_slot->status);
+
+       return 0;
+}
+
+
+static char *ata_id_strcpy(u16 *target, u16 *src, int len)
+{
+       int i;
+       for (i = 0; i < len / 2; i++)
+               target[i] = le16_to_cpu(src[i]);
+       return (char *)target;
+}
+
+
+static void dump_ataid(hd_driveid_t *ataid)
+{
+       debug("(49)ataid->capability = 0x%x\n", ataid->capability);
+       debug("(53)ataid->field_valid =0x%x\n", ataid->field_valid);
+       debug("(63)ataid->dma_mword = 0x%x\n", ataid->dma_mword);
+       debug("(64)ataid->eide_pio_modes = 0x%x\n", ataid->eide_pio_modes);
+       debug("(75)ataid->queue_depth = 0x%x\n", ataid->queue_depth);
+       debug("(80)ataid->major_rev_num = 0x%x\n", ataid->major_rev_num);
+       debug("(81)ataid->minor_rev_num = 0x%x\n", ataid->minor_rev_num);
+       debug("(82)ataid->command_set_1 = 0x%x\n", ataid->command_set_1);
+       debug("(83)ataid->command_set_2 = 0x%x\n", ataid->command_set_2);
+       debug("(84)ataid->cfsse = 0x%x\n", ataid->cfsse);
+       debug("(85)ataid->cfs_enable_1 = 0x%x\n", ataid->cfs_enable_1);
+       debug("(86)ataid->cfs_enable_2 = 0x%x\n", ataid->cfs_enable_2);
+       debug("(87)ataid->csf_default = 0x%x\n", ataid->csf_default);
+       debug("(88)ataid->dma_ultra = 0x%x\n", ataid->dma_ultra);
+       debug("(93)ataid->hw_config = 0x%x\n", ataid->hw_config);
+}
+
+
+/*
+ * SCSI INQUIRY command operation.
+ */
+static int ata_scsiop_inquiry(ccb *pccb)
+{
+       u8 hdr[] = {
+               0,
+               0,
+               0x5,            /* claim SPC-3 version compatibility */
+               2,
+               95 - 4,
+       };
+       u8 fis[20];
+       u8 *tmpid;
+       u8 port;
+
+       /* Clean ccb data buffer */
+       memset(pccb->pdata, 0, pccb->datalen);
+
+       memcpy(pccb->pdata, hdr, sizeof(hdr));
+
+       if (pccb->datalen <= 35)
+               return 0;
+
+       memset(fis, 0, 20);
+       /* Construct the FIS */
+       fis[0] = 0x27;          /* Host to device FIS. */
+       fis[1] = 1 << 7;        /* Command FIS. */
+       fis[2] = ATA_CMD_IDENT; /* Command byte. */
+
+       /* Read id from sata */
+       port = pccb->target;
+       if (!(tmpid = malloc(sizeof(hd_driveid_t))))
+               return -ENOMEM;
+
+       if (get_ahci_device_data(port, (u8 *) & fis, 20,
+                                tmpid, sizeof(hd_driveid_t))) {
+               debug("scsi_ahci: SCSI inquiry command failure.\n");
+               return -EIO;
+       }
+
+       if (ataid[port])
+               free(ataid[port]);
+       ataid[port] = (hd_driveid_t *) tmpid;
+
+       memcpy(&pccb->pdata[8], "ATA     ", 8);
+       ata_id_strcpy((u16 *) &pccb->pdata[16], (u16 *)ataid[port]->model, 16);
+       ata_id_strcpy((u16 *) &pccb->pdata[32], (u16 *)ataid[port]->fw_rev, 4);
+
+       dump_ataid(ataid[port]);
+       return 0;
+}
+
+
+/*
+ * SCSI READ10 command operation.
+ */
+static int ata_scsiop_read10(ccb * pccb)
+{
+       u64 lba = 0;
+       u32 len = 0;
+       u8 fis[20];
+
+       lba = (((u64) pccb->cmd[2]) << 24) | (((u64) pccb->cmd[3]) << 16)
+           | (((u64) pccb->cmd[4]) << 8) | ((u64) pccb->cmd[5]);
+       len = (((u32) pccb->cmd[7]) << 8) | ((u32) pccb->cmd[8]);
+
+       /* For 10-byte and 16-byte SCSI R/W commands, transfer
+        * length 0 means transfer 0 block of data.
+        * However, for ATA R/W commands, sector count 0 means
+        * 256 or 65536 sectors, not 0 sectors as in SCSI.
+        *
+        * WARNING: one or two older ATA drives treat 0 as 0...
+        */
+       if (!len)
+               return 0;
+       memset(fis, 0, 20);
+
+       /* Construct the FIS */
+       fis[0] = 0x27;          /* Host to device FIS. */
+       fis[1] = 1 << 7;        /* Command FIS. */
+       fis[2] = ATA_CMD_RD_DMA;        /* Command byte. */
+
+       /* LBA address, only support LBA28 in this driver */
+       fis[4] = pccb->cmd[5];
+       fis[5] = pccb->cmd[4];
+       fis[6] = pccb->cmd[3];
+       fis[7] = (pccb->cmd[2] & 0x0f) | 0xe0;
+
+       /* Sector Count */
+       fis[12] = pccb->cmd[8];
+       fis[13] = pccb->cmd[7];
+
+       /* Read from ahci */
+       if (get_ahci_device_data(pccb->target, (u8 *) & fis, 20,
+                                pccb->pdata, pccb->datalen)) {
+               debug("scsi_ahci: SCSI READ10 command failure.\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+
+/*
+ * SCSI READ CAPACITY10 command operation.
+ */
+static int ata_scsiop_read_capacity10(ccb *pccb)
+{
+       u8 buf[8];
+
+       if (!ataid[pccb->target]) {
+               printf("scsi_ahci: SCSI READ CAPACITY10 command failure. "
+                      "\tNo ATA info!\n"
+                      "\tPlease run SCSI commmand INQUIRY firstly!\n");
+               return -EPERM;
+       }
+
+       memset(buf, 0, 8);
+
+       *(u32 *) buf = le32_to_cpu(ataid[pccb->target]->lba_capacity);
+
+       buf[6] = 512 >> 8;
+       buf[7] = 512 & 0xff;
+
+       memcpy(pccb->pdata, buf, 8);
+
+       return 0;
+}
+
+
+/*
+ * SCSI TEST UNIT READY command operation.
+ */
+static int ata_scsiop_test_unit_ready(ccb *pccb)
+{
+       return (ataid[pccb->target]) ? 0 : -EPERM;
+}
+
+
+int scsi_exec(ccb *pccb)
+{
+       int ret;
+
+       switch (pccb->cmd[0]) {
+       case SCSI_READ10:
+               ret = ata_scsiop_read10(pccb);
+               break;
+       case SCSI_RD_CAPAC:
+               ret = ata_scsiop_read_capacity10(pccb);
+               break;
+       case SCSI_TST_U_RDY:
+               ret = ata_scsiop_test_unit_ready(pccb);
+               break;
+       case SCSI_INQUIRY:
+               ret = ata_scsiop_inquiry(pccb);
+               break;
+       default:
+               printf("Unsupport SCSI command 0x%02x\n", pccb->cmd[0]);
+               return FALSE;
+       }
+
+       if (ret) {
+               debug("SCSI command 0x%02x ret errno %d\n", pccb->cmd[0], ret);
+               return FALSE;
+       }
+       return TRUE;
+
+}
+
+
+void scsi_low_level_init(int busdevfunc)
+{
+       int i;
+       u32 linkmap;
+
+       ahci_init_one(busdevfunc);
+
+       linkmap = probe_ent->link_port_map;
+
+       for (i = 0; i < CFG_SCSI_MAX_SCSI_ID; i++) {
+               if (((linkmap >> i) & 0x01)) {
+                       if (ahci_port_start((u8) i)) {
+                               printf("Can not start port %d\n", i);
+                               continue;
+                       }
+                       ahci_set_feature((u8) i);
+               }
+       }
+}
+
+
+void scsi_bus_reset(void)
+{
+       /*Not implement*/
+}
+
+
+void scsi_print_error(ccb * pccb)
+{
+       /*The ahci error info can be read in the ahci driver*/
+}
+#endif
diff --git a/drivers/block/ata_piix.c b/drivers/block/ata_piix.c
new file mode 100644 (file)
index 0000000..42456d7
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) Procsys. All rights reserved.
+ * Author: Mushtaq Khan <mushtaq_k@procsys.com>
+ *                     <mushtaqk_921@yahoo.co.in>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * with the reference to ata_piix driver in kernel 2.4.32
+ */
+
+/*
+ * This file contains SATA controller and SATA drive initialization functions
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <command.h>
+#include <config.h>
+#include <asm/byteorder.h>
+#include <ide.h>
+#include <ata.h>
+
+#ifdef CFG_ATA_PIIX            /*ata_piix driver */
+
+#define DEBUG_SATA 0           /*For debug prints set DEBUG_SATA to 1 */
+
+#define DRV_DECL               /*For file specific declarations */
+#include <sata.h>
+#undef DRV_DECL
+
+/*Macros realted to PCI*/
+#define PCI_SATA_BUS   0x00
+#define PCI_SATA_DEV   0x1f
+#define PCI_SATA_FUNC  0x02
+
+#define PCI_SATA_BASE1 0x10
+#define PCI_SATA_BASE2 0x14
+#define PCI_SATA_BASE3 0x18
+#define PCI_SATA_BASE4 0x1c
+#define PCI_SATA_BASE5 0x20
+#define PCI_PMR         0x90
+#define PCI_PI          0x09
+#define PCI_PCS         0x92
+#define PCI_DMA_CTL     0x48
+
+#define PORT_PRESENT (1<<0)
+#define PORT_ENABLED (1<<4)
+
+u32 bdf;
+u32 iobase1 = 0;               /*Primary cmd block */
+u32 iobase2 = 0;               /*Primary ctl block */
+u32 iobase3 = 0;               /*Sec cmd block */
+u32 iobase4 = 0;               /*sec ctl block */
+u32 iobase5 = 0;               /*BMDMA*/
+int
+pci_sata_init (void)
+{
+       u32 bus = PCI_SATA_BUS;
+       u32 dev = PCI_SATA_DEV;
+       u32 fun = PCI_SATA_FUNC;
+       u16 cmd = 0;
+       u8 lat = 0, pcibios_max_latency = 0xff;
+       u8 pmr;                 /*Port mapping reg */
+       u8 pi;                  /*Prgming Interface reg */
+
+       bdf = PCI_BDF (bus, dev, fun);
+       pci_read_config_dword (bdf, PCI_SATA_BASE1, &iobase1);
+       pci_read_config_dword (bdf, PCI_SATA_BASE2, &iobase2);
+       pci_read_config_dword (bdf, PCI_SATA_BASE3, &iobase3);
+       pci_read_config_dword (bdf, PCI_SATA_BASE4, &iobase4);
+       pci_read_config_dword (bdf, PCI_SATA_BASE5, &iobase5);
+
+       if ((iobase1 == 0xFFFFFFFF) || (iobase2 == 0xFFFFFFFF) ||
+           (iobase3 == 0xFFFFFFFF) || (iobase4 == 0xFFFFFFFF) ||
+           (iobase5 == 0xFFFFFFFF)) {
+               printf ("error no base addr for SATA controller\n");
+               return 1;
+        /*ERROR*/}
+
+       iobase1 &= 0xFFFFFFFE;
+       iobase2 &= 0xFFFFFFFE;
+       iobase3 &= 0xFFFFFFFE;
+       iobase4 &= 0xFFFFFFFE;
+       iobase5 &= 0xFFFFFFFE;
+
+       /*check for mode */
+       pci_read_config_byte (bdf, PCI_PMR, &pmr);
+       if (pmr > 1) {
+               printf ("combined mode not supported\n");
+               return 1;
+       }
+
+       pci_read_config_byte (bdf, PCI_PI, &pi);
+       if ((pi & 0x05) != 0x05) {
+               printf ("Sata is in Legacy mode\n");
+               return 1;
+       } else {
+               printf ("sata is in Native mode\n");
+       }
+
+       /*MASTER CFG AND IO CFG */
+       pci_read_config_word (bdf, PCI_COMMAND, &cmd);
+       cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+       pci_write_config_word (bdf, PCI_COMMAND, cmd);
+       pci_read_config_byte (dev, PCI_LATENCY_TIMER, &lat);
+
+       if (lat < 16)
+               lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+       else if (lat > pcibios_max_latency)
+               lat = pcibios_max_latency;
+       pci_write_config_byte (dev, PCI_LATENCY_TIMER, lat);
+
+       return 0;
+}
+
+int
+sata_bus_probe (int port_no)
+{
+       int orig_mask, mask;
+       u16 pcs;
+
+       mask = (PORT_PRESENT << port_no);
+       pci_read_config_word (bdf, PCI_PCS, &pcs);
+       orig_mask = (int) pcs & 0xff;
+       if ((orig_mask & mask) != mask)
+               return 0;
+       else
+               return 1;
+}
+
+int
+init_sata (void)
+{
+       u8 i, rv = 0;
+
+       for (i = 0; i < CFG_SATA_MAXDEVICES; i++) {
+               sata_dev_desc[i].type = DEV_TYPE_UNKNOWN;
+               sata_dev_desc[i].if_type = IF_TYPE_IDE;
+               sata_dev_desc[i].dev = i;
+               sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
+               sata_dev_desc[i].blksz = 0;
+               sata_dev_desc[i].lba = 0;
+               sata_dev_desc[i].block_read = sata_read;
+       }
+
+       rv = pci_sata_init ();
+       if (rv == 1) {
+               printf ("pci initialization failed\n");
+               return 1;
+       }
+
+       port[0].port_no = 0;
+       port[0].ioaddr.cmd_addr = iobase1;
+       port[0].ioaddr.altstatus_addr = port[0].ioaddr.ctl_addr =
+           iobase2 | ATA_PCI_CTL_OFS;
+       port[0].ioaddr.bmdma_addr = iobase5;
+
+       port[1].port_no = 1;
+       port[1].ioaddr.cmd_addr = iobase3;
+       port[1].ioaddr.altstatus_addr = port[1].ioaddr.ctl_addr =
+           iobase4 | ATA_PCI_CTL_OFS;
+       port[1].ioaddr.bmdma_addr = iobase5 + 0x8;
+
+       for (i = 0; i < CFG_SATA_MAXBUS; i++)
+               sata_port (&port[i].ioaddr);
+
+       for (i = 0; i < CFG_SATA_MAXBUS; i++) {
+               if (!(sata_bus_probe (i))) {
+                       port[i].port_state = 0;
+                       printf ("SATA#%d port is not present \n", i);
+               } else {
+                       printf ("SATA#%d port is present\n", i);
+                       if (sata_bus_softreset (i)) {
+                               port[i].port_state = 0;
+                       } else {
+                               port[i].port_state = 1;
+                       }
+               }
+       }
+
+       for (i = 0; i < CFG_SATA_MAXBUS; i++) {
+               u8 j, devno;
+
+               if (port[i].port_state == 0)
+                       continue;
+               for (j = 0; j < CFG_SATA_DEVS_PER_BUS; j++) {
+                       sata_identify (i, j);
+                       set_Feature_cmd (i, j);
+                       devno = i * CFG_SATA_DEVS_PER_BUS + j;
+                       if ((sata_dev_desc[devno].lba > 0) &&
+                           (sata_dev_desc[devno].blksz > 0)) {
+                               dev_print (&sata_dev_desc[devno]);
+                               /* initialize partition type */
+                               init_part (&sata_dev_desc[devno]);
+                               if (curr_dev < 0)
+                                       curr_dev =
+                                           i * CFG_SATA_DEVS_PER_BUS + j;
+                       }
+               }
+       }
+       return 0;
+}
+#endif
diff --git a/drivers/block/sil680.c b/drivers/block/sil680.c
new file mode 100644 (file)
index 0000000..a6143df
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * (C) Copyright 2007
+ * Gary Jennejohn, DENX Software Engineering, garyj@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+/* sil680.c - ide support functions for the Sil0680A controller */
+
+/*
+ * The following parameters must be defined in the configuration file
+ * of the target board:
+ *
+ * #define CFG_IDE_SIL680
+ *
+ * #define CONFIG_PCI_PNP
+ * NOTE it may also be necessary to define this if the default of 8 is
+ * incorrect for the target board (e.g. the sequoia board requires 0).
+ * #define CFG_PCI_CACHE_LINE_SIZE     0
+ *
+ * #define CONFIG_CMD_IDE
+ * #undef  CONFIG_IDE_8xx_DIRECT
+ * #undef  CONFIG_IDE_LED
+ * #undef  CONFIG_IDE_RESET
+ * #define CONFIG_IDE_PREINIT
+ * #define CFG_IDE_MAXBUS              2 - modify to suit
+ * #define CFG_IDE_MAXDEVICE   (CFG_IDE_MAXBUS*2) - modify to suit
+ * #define CFG_ATA_BASE_ADDR   0
+ * #define CFG_ATA_IDE0_OFFSET 0
+ * #define CFG_ATA_IDE1_OFFSET 0
+ * #define CFG_ATA_DATA_OFFSET 0
+ * #define CFG_ATA_REG_OFFSET  0
+ * #define CFG_ATA_ALT_OFFSET  0x0004
+ *
+ * The mapping for PCI IO-space.
+ * NOTE this is the value for the sequoia board. Modify to suit.
+ * #define CFG_PCI0_IO_SPACE   0xE8000000
+ */
+
+#include <common.h>
+#if defined(CFG_IDE_SIL680)
+#include <ata.h>
+#include <ide.h>
+#include <pci.h>
+
+extern ulong ide_bus_offset[CFG_IDE_MAXBUS];
+
+int ide_preinit (void)
+{
+       int status;
+       pci_dev_t devbusfn;
+       int l;
+
+       status = 1;
+       for (l = 0; l < CFG_IDE_MAXBUS; l++) {
+               ide_bus_offset[l] = -ATA_STATUS;
+       }
+       devbusfn = pci_find_device (0x1095, 0x0680, 0);
+       if (devbusfn != -1) {
+               status = 0;
+
+               pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0,
+                                      (u32 *) &ide_bus_offset[0]);
+               ide_bus_offset[0] &= 0xfffffff8;
+               ide_bus_offset[0] += CFG_PCI0_IO_SPACE;
+               pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_2,
+                                      (u32 *) &ide_bus_offset[1]);
+               ide_bus_offset[1] &= 0xfffffff8;
+               ide_bus_offset[1] += CFG_PCI0_IO_SPACE;
+               /* init various things - taken from the Linux driver */
+               /* set PIO mode */
+               pci_write_config_byte(devbusfn, 0x80, 0x00);
+               pci_write_config_byte(devbusfn, 0x84, 0x00);
+               /* IDE0 */
+               pci_write_config_byte(devbusfn,  0xA1, 0x02);
+               pci_write_config_word(devbusfn,  0xA2, 0x328A);
+               pci_write_config_dword(devbusfn, 0xA4, 0x62DD62DD);
+               pci_write_config_dword(devbusfn, 0xA8, 0x43924392);
+               pci_write_config_dword(devbusfn, 0xAC, 0x40094009);
+               /* IDE1 */
+               pci_write_config_byte(devbusfn,  0xB1, 0x02);
+               pci_write_config_word(devbusfn,  0xB2, 0x328A);
+               pci_write_config_dword(devbusfn, 0xB4, 0x62DD62DD);
+               pci_write_config_dword(devbusfn, 0xB8, 0x43924392);
+               pci_write_config_dword(devbusfn, 0xBC, 0x40094009);
+       }
+       return (status);
+}
+
+void ide_set_reset (int flag) {
+       return;
+}
+
+#endif /* CFG_IDE_SIL680 */
diff --git a/drivers/block/sym53c8xx.c b/drivers/block/sym53c8xx.c
new file mode 100644 (file)
index 0000000..29eeccd
--- /dev/null
@@ -0,0 +1,793 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ * partly derived from
+ * linux/drivers/scsi/sym53c8xx.c
+ *
+ */
+
+/*
+ * SCSI support based on the chip sym53C810.
+ *
+ * 09-19-2001 Andreas Heppel, Sysgo RTS GmbH <aheppel@sysgo.de>
+ *             The local version of this driver for the BAB750 board does not
+ *             use interrupts but polls the chip instead (see the call of
+ *             'handle_scsi_int()' in 'scsi_issue()'.
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_SCSI_SYM53C8XX
+
+#include <command.h>
+#include <pci.h>
+#include <asm/processor.h>
+#include <sym53c8xx.h>
+#include <scsi.h>
+
+#undef SYM53C8XX_DEBUG
+
+#ifdef SYM53C8XX_DEBUG
+#define        PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#if defined(CONFIG_CMD_SCSI) && defined(CONFIG_SCSI_SYM53C8XX)
+
+#undef SCSI_SINGLE_STEP
+/*
+ * Single Step is only used for debug purposes
+ */
+#ifdef SCSI_SINGLE_STEP
+static unsigned long start_script_select;
+static unsigned long start_script_msgout;
+static unsigned long start_script_msgin;
+static unsigned long start_script_msg_ext;
+static unsigned long start_script_cmd;
+static unsigned long start_script_data_in;
+static unsigned long start_script_data_out;
+static unsigned long start_script_status;
+static unsigned long start_script_complete;
+static unsigned long start_script_error;
+static unsigned long start_script_reselection;
+static unsigned int len_script_select;
+static unsigned int len_script_msgout;
+static unsigned int len_script_msgin;
+static unsigned int len_script_msg_ext;
+static unsigned int len_script_cmd;
+static unsigned int len_script_data_in;
+static unsigned int len_script_data_out;
+static unsigned int len_script_status;
+static unsigned int len_script_complete;
+static unsigned int len_script_error;
+static unsigned int len_script_reselection;
+#endif
+
+
+static unsigned short scsi_int_mask;           /* shadow register for SCSI related interrupts */
+static unsigned char  script_int_mask; /* shadow register for SCRIPT related interrupts */
+static unsigned long script_select[8]; /* script for selection */
+static unsigned long script_msgout[8]; /* script for message out phase (NOT USED) */
+static unsigned long script_msgin[14]; /* script for message in phase */
+static unsigned long script_msg_ext[32]; /* script for message in phase when more than 1 byte message */
+static unsigned long script_cmd[18];    /* script for command phase */
+static unsigned long script_data_in[8]; /* script for data in phase */
+static unsigned long script_data_out[8]; /* script for data out phase */
+static unsigned long script_status[6]; /* script for status phase */
+static unsigned long script_complete[10]; /* script for complete */
+static unsigned long script_reselection[4]; /* script for reselection (NOT USED) */
+static unsigned long script_error[2]; /* script for error handling */
+
+static unsigned long int_stat[3]; /* interrupt status */
+static unsigned long scsi_mem_addr; /* base memory address =SCSI_MEM_ADDRESS; */
+
+#define bus_to_phys(a) pci_mem_to_phys(busdevfunc, (unsigned long) (a))
+#define phys_to_bus(a) pci_phys_to_mem(busdevfunc, (unsigned long) (a))
+
+#define SCSI_MAX_RETRY 3 /* number of retries in scsi_issue() */
+
+#define SCSI_MAX_RETRY_NOT_READY 10 /* number of retries when device is not ready */
+#define SCSI_NOT_READY_TIME_OUT 500 /* timeout per retry when not ready */
+
+/*********************************************************************************
+ * forward declerations
+ */
+
+void scsi_chip_init(void);
+void handle_scsi_int(void);
+
+
+/********************************************************************************
+ * reports SCSI errors to the user
+ */
+void scsi_print_error(ccb *pccb)
+{
+       int i;
+       printf("SCSI Error: Target %d LUN %d Command %02X\n",pccb->target, pccb->lun, pccb->cmd[0]);
+       printf("       CCB: ");
+       for(i=0;i<pccb->cmdlen;i++)
+               printf("%02X ",pccb->cmd[i]);
+       printf("(len=%d)\n",pccb->cmdlen);
+       printf("     Cntrl: ");
+       switch(pccb->contr_stat) {
+               case SIR_COMPLETE:                                              printf("Complete (no Error)\n"); break;
+               case SIR_SEL_ATN_NO_MSG_OUT:    printf("Selected with ATN no MSG out phase\n"); break;
+               case SIR_CMD_OUT_ILL_PH:                        printf("Command out illegal phase\n"); break;
+               case SIR_MSG_RECEIVED:                          printf("MSG received Error\n"); break;
+               case SIR_DATA_IN_ERR:                           printf("Data in Error\n"); break;
+               case SIR_DATA_OUT_ERR:                          printf("Data out Error\n"); break;
+               case SIR_SCRIPT_ERROR:                          printf("Script Error\n"); break;
+               case SIR_MSG_OUT_NO_CMD:                        printf("MSG out no Command phase\n"); break;
+               case SIR_MSG_OVER7:                                     printf("MSG in over 7 bytes\n"); break;
+               case INT_ON_FY:                                                         printf("Interrupt on fly\n"); break;
+               case SCSI_SEL_TIME_OUT:                         printf("SCSI Selection Timeout\n"); break;
+               case SCSI_HNS_TIME_OUT:                         printf("SCSI Handshake Timeout\n"); break;
+               case SCSI_MA_TIME_OUT:                          printf("SCSI Phase Error\n"); break;
+               case SCSI_UNEXP_DIS:                                    printf("SCSI unexpected disconnect\n"); break;
+               default:                                                                                        printf("unknown status %lx\n",pccb->contr_stat); break;
+       }
+       printf("     Sense: SK %x (",pccb->sense_buf[2]&0x0f);
+       switch(pccb->sense_buf[2]&0xf) {
+               case SENSE_NO_SENSE: printf("No Sense)"); break;
+               case SENSE_RECOVERED_ERROR: printf("Recovered Error)"); break;
+               case SENSE_NOT_READY:   printf("Not Ready)"); break;
+               case SENSE_MEDIUM_ERROR: printf("Medium Error)"); break;
+               case SENSE_HARDWARE_ERROR: printf("Hardware Error)"); break;
+               case SENSE_ILLEGAL_REQUEST: printf("Illegal request)"); break;
+               case SENSE_UNIT_ATTENTION: printf("Unit Attention)"); break;
+               case SENSE_DATA_PROTECT: printf("Data Protect)"); break;
+               case SENSE_BLANK_CHECK: printf("Blank check)"); break;
+               case SENSE_VENDOR_SPECIFIC: printf("Vendor specific)"); break;
+               case SENSE_COPY_ABORTED: printf("Copy aborted)"); break;
+               case SENSE_ABORTED_COMMAND:     printf("Aborted Command)"); break;
+               case SENSE_VOLUME_OVERFLOW:     printf("Volume overflow)"); break;
+               case SENSE_MISCOMPARE: printf("Misscompare\n"); break;
+               default: printf("Illegal Sensecode\n"); break;
+       }
+       printf(" ASC %x ASCQ %x\n",pccb->sense_buf[12],pccb->sense_buf[13]);
+       printf("    Status: ");
+       switch(pccb->status) {
+               case S_GOOD :   printf("Good\n"); break;
+               case S_CHECK_COND: printf("Check condition\n"); break;
+               case S_COND_MET: printf("Condition Met\n"); break;
+               case S_BUSY: printf("Busy\n"); break;
+               case S_INT: printf("Intermediate\n"); break;
+               case S_INT_COND_MET: printf("Intermediate condition met\n"); break;
+               case S_CONFLICT: printf("Reservation conflict\n"); break;
+               case S_TERMINATED: printf("Command terminated\n"); break;
+               case S_QUEUE_FULL: printf("Task set full\n"); break;
+               default: printf("unknown: %02X\n",pccb->status); break;
+       }
+
+}
+
+
+/******************************************************************************
+ * sets-up the SCSI controller
+ * the base memory address is retrived via the pci_read_config_dword
+ */
+void scsi_low_level_init(int busdevfunc)
+{
+       unsigned int cmd;
+       unsigned int addr;
+       unsigned char vec;
+
+       pci_read_config_byte(busdevfunc, PCI_INTERRUPT_LINE, &vec);
+       pci_read_config_dword(busdevfunc, PCI_BASE_ADDRESS_1, &addr);
+
+       addr = bus_to_phys(addr & ~0xf);
+
+       /*
+        * Enable bus mastering in case this has not been done, yet.
+        */
+       pci_read_config_dword(busdevfunc, PCI_COMMAND, &cmd);
+       cmd |= PCI_COMMAND_MASTER;
+       pci_write_config_dword(busdevfunc, PCI_COMMAND, cmd);
+
+       scsi_mem_addr = addr;
+
+       scsi_chip_init();
+       scsi_bus_reset();
+}
+
+
+/************************************************************************************
+ * Low level Part of SCSI Driver
+ */
+
+/*
+ * big-endian -> little endian conversion for the script
+ */
+unsigned long swap_script(unsigned long val)
+{
+       unsigned long tmp;
+       tmp = ((val>>24)&0xff) | ((val>>8)&0xff00) | ((val<<8)&0xff0000) | ((val<<24)&0xff000000);
+       return tmp;
+}
+
+
+void scsi_write_byte(ulong offset,unsigned char val)
+{
+       out8(scsi_mem_addr+offset,val);
+}
+
+
+unsigned char scsi_read_byte(ulong offset)
+{
+       return(in8(scsi_mem_addr+offset));
+}
+
+
+/********************************************************************************
+ * interrupt handler
+ */
+void handle_scsi_int(void)
+{
+       unsigned char stat,stat1,stat2;
+       unsigned short sstat;
+       int i;
+#ifdef SCSI_SINGLE_STEP
+       unsigned long tt;
+#endif
+       stat=scsi_read_byte(ISTAT);
+       if((stat & DIP)==DIP) { /* DMA Interrupt pending */
+               stat1=scsi_read_byte(DSTAT);
+#ifdef SCSI_SINGLE_STEP
+               if((stat1 & SSI)==SSI)
+               {
+                       tt=in32r(scsi_mem_addr+DSP);
+                       if(((tt)>=start_script_select) && ((tt)<start_script_select+len_script_select)) {
+                               printf("select %d\n",(tt-start_script_select)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_msgout) && ((tt)<start_script_msgout+len_script_msgout)) {
+                               printf("msgout %d\n",(tt-start_script_msgout)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_msgin) && ((tt)<start_script_msgin+len_script_msgin)) {
+                               printf("msgin %d\n",(tt-start_script_msgin)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_msg_ext) && ((tt)<start_script_msg_ext+len_script_msg_ext)) {
+                               printf("msgin_ext %d\n",(tt-start_script_msg_ext)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_cmd) && ((tt)<start_script_cmd+len_script_cmd)) {
+                               printf("cmd %d\n",(tt-start_script_cmd)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_data_in) && ((tt)<start_script_data_in+len_script_data_in)) {
+                               printf("data_in %d\n",(tt-start_script_data_in)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_data_out) && ((tt)<start_script_data_out+len_script_data_out)) {
+                               printf("data_out %d\n",(tt-start_script_data_out)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_status) && ((tt)<start_script_status+len_script_status)) {
+                               printf("status %d\n",(tt-start_script_status)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_complete) && ((tt)<start_script_complete+len_script_complete)) {
+                               printf("complete %d\n",(tt-start_script_complete)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_error) && ((tt)<start_script_error+len_script_error)) {
+                               printf("error %d\n",(tt-start_script_error)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_reselection) && ((tt)<start_script_reselection+len_script_reselection)) {
+                               printf("reselection %d\n",(tt-start_script_reselection)>>2);
+                               goto end_single;
+                       }
+                       printf("sc: %lx\n",tt);
+end_single:
+                       stat2=scsi_read_byte(DCNTL);
+                       stat2|=STD;
+                       scsi_write_byte(DCNTL,stat2);
+               }
+#endif
+               if((stat1 & SIR)==SIR) /* script interrupt */
+               {
+                       int_stat[0]=in32(scsi_mem_addr+DSPS);
+               }
+               if((stat1 & DFE)==0) { /* fifo not epmty */
+                       scsi_write_byte(CTEST3,CLF); /* Clear DMA FIFO */
+                       stat2=scsi_read_byte(STEST3);
+                       scsi_write_byte(STEST3,(stat2 | CSF)); /* Clear SCSI FIFO */
+               }
+       }
+       if((stat & SIP)==SIP) {  /* scsi interrupt */
+               sstat = (unsigned short)scsi_read_byte(SIST+1);
+               sstat <<=8;
+               sstat |= (unsigned short)scsi_read_byte(SIST);
+               for(i=0;i<3;i++) {
+                       if(int_stat[i]==0)
+                               break; /* found an empty int status */
+               }
+               int_stat[i]=SCSI_INT_STATE | sstat;
+               stat1=scsi_read_byte(DSTAT);
+               if((stat1 & DFE)==0) { /* fifo not epmty */
+                       scsi_write_byte(CTEST3,CLF); /* Clear DMA FIFO */
+                       stat2=scsi_read_byte(STEST3);
+                       scsi_write_byte(STEST3,(stat2 | CSF)); /* Clear SCSI FIFO */
+               }
+       }
+       if((stat & INTF)==INTF) { /* interrupt on Fly */
+               scsi_write_byte(ISTAT,stat); /* clear it */
+               for(i=0;i<3;i++) {
+                       if(int_stat[i]==0)
+                               break; /* found an empty int status */
+               }
+               int_stat[i]=INT_ON_FY;
+       }
+}
+
+void scsi_bus_reset(void)
+{
+       unsigned char t;
+       int i;
+       int end = CFG_SCSI_SPIN_UP_TIME*1000;
+
+       t=scsi_read_byte(SCNTL1);
+       scsi_write_byte(SCNTL1,(t | CRST));
+       udelay(50);
+       scsi_write_byte(SCNTL1,t);
+
+       puts("waiting for devices to spin up");
+       for(i=0;i<end;i++) {
+               udelay(1000); /* give the devices time to spin up */
+               if (i % 1000 == 0)
+                       putc('.');
+       }
+       putc('\n');
+       scsi_chip_init(); /* reinit the chip ...*/
+
+}
+
+void scsi_int_enable(void)
+{
+       scsi_write_byte(SIEN,(unsigned char)scsi_int_mask);
+       scsi_write_byte(SIEN+1,(unsigned char)(scsi_int_mask>>8));
+       scsi_write_byte(DIEN,script_int_mask);
+}
+
+void scsi_write_dsp(unsigned long start)
+{
+       unsigned long val;
+#ifdef SCSI_SINGLE_STEP
+       unsigned char t;
+#endif
+       val = start;
+       out32r(scsi_mem_addr + DSP,start);
+#ifdef SCSI_SINGLE_STEP
+       t=scsi_read_byte(DCNTL);
+  t|=STD;
+       scsi_write_byte(DCNTL,t);
+#endif
+}
+
+/* only used for debug purposes */
+void scsi_print_script(void)
+{
+       printf("script_select @         0x%08lX\n",(unsigned long)&script_select[0]);
+       printf("script_msgout @         0x%08lX\n",(unsigned long)&script_msgout[0]);
+       printf("script_msgin @          0x%08lX\n",(unsigned long)&script_msgin[0]);
+       printf("script_msgext @         0x%08lX\n",(unsigned long)&script_msg_ext[0]);
+       printf("script_cmd @            0x%08lX\n",(unsigned long)&script_cmd[0]);
+       printf("script_data_in @        0x%08lX\n",(unsigned long)&script_data_in[0]);
+       printf("script_data_out @       0x%08lX\n",(unsigned long)&script_data_out[0]);
+       printf("script_status @         0x%08lX\n",(unsigned long)&script_status[0]);
+       printf("script_complete @       0x%08lX\n",(unsigned long)&script_complete[0]);
+       printf("script_error @          0x%08lX\n",(unsigned long)&script_error[0]);
+}
+
+
+void scsi_set_script(ccb *pccb)
+{
+       int busdevfunc = pccb->priv;
+       int i;
+       i=0;
+       script_select[i++]=swap_script(SCR_REG_REG(GPREG, SCR_AND, 0xfe));
+       script_select[i++]=0; /* LED ON */
+       script_select[i++]=swap_script(SCR_CLR(SCR_TRG)); /* select initiator mode */
+       script_select[i++]=0;
+       /* script_select[i++]=swap_script(SCR_SEL_ABS_ATN | pccb->target << 16); */
+       script_select[i++]=swap_script(SCR_SEL_ABS | pccb->target << 16);
+       script_select[i++]=swap_script(phys_to_bus(&script_cmd[4])); /* error handling */
+       script_select[i++]=swap_script(SCR_JUMP); /* next section */
+       /*      script_select[i++]=swap_script((unsigned long)&script_msgout[0]); */ /* message out */
+       script_select[i++]=swap_script(phys_to_bus(&script_cmd[0])); /* command out */
+
+#ifdef SCSI_SINGLE_STEP
+       start_script_select=(unsigned long)&script_select[0];
+       len_script_select=i*4;
+#endif
+
+       i=0;
+       script_msgout[i++]=swap_script(SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)));
+       script_msgout[i++]=SIR_SEL_ATN_NO_MSG_OUT;
+       script_msgout[i++]=swap_script( SCR_MOVE_ABS(1) ^ SCR_MSG_OUT);
+       script_msgout[i++]=swap_script(phys_to_bus(&pccb->msgout[0]));
+       script_msgout[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_COMMAND))); /* if Command phase */
+       script_msgout[i++]=swap_script(phys_to_bus(&script_cmd[0])); /* switch to command */
+       script_msgout[i++]=swap_script(SCR_INT); /* interrupt if not */
+       script_msgout[i++]=SIR_MSG_OUT_NO_CMD;
+
+#ifdef SCSI_SINGLE_STEP
+       start_script_msgout=(unsigned long)&script_msgout[0];
+       len_script_msgout=i*4;
+#endif
+       i=0;
+       script_cmd[i++]=swap_script(SCR_MOVE_ABS(pccb->cmdlen) ^ SCR_COMMAND);
+       script_cmd[i++]=swap_script(phys_to_bus(&pccb->cmd[0]));
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN))); /* message in ? */
+       script_cmd[i++]=swap_script(phys_to_bus(&script_msgin[0]));
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_DATA_OUT))); /* data out ? */
+       script_cmd[i++]=swap_script(phys_to_bus(&script_data_out[0]));
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_DATA_IN))); /* data in ? */
+       script_cmd[i++]=swap_script(phys_to_bus(&script_data_in[0]));
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_STATUS)));  /* status ? */
+       script_cmd[i++]=swap_script(phys_to_bus(&script_status[0]));
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND)));  /* command ? */
+       script_cmd[i++]=swap_script(phys_to_bus(&script_cmd[0]));
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)));  /* message out ? */
+       script_cmd[i++]=swap_script(phys_to_bus(&script_msgout[0]));
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_MSG_IN))); /* just for error handling message in ? */
+       script_cmd[i++]=swap_script(phys_to_bus(&script_msgin[0]));
+       script_cmd[i++]=swap_script(SCR_INT); /* interrupt if not */
+       script_cmd[i++]=SIR_CMD_OUT_ILL_PH;
+#ifdef SCSI_SINGLE_STEP
+       start_script_cmd=(unsigned long)&script_cmd[0];
+       len_script_cmd=i*4;
+#endif
+       i=0;
+       script_data_out[i++]=swap_script(SCR_MOVE_ABS(pccb->datalen)^ SCR_DATA_OUT); /* move */
+       script_data_out[i++]=swap_script(phys_to_bus(pccb->pdata)); /* pointer to buffer */
+       script_data_out[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)));
+       script_data_out[i++]=swap_script(phys_to_bus(&script_status[0]));
+       script_data_out[i++]=swap_script(SCR_INT);
+       script_data_out[i++]=SIR_DATA_OUT_ERR;
+
+#ifdef SCSI_SINGLE_STEP
+       start_script_data_out=(unsigned long)&script_data_out[0];
+       len_script_data_out=i*4;
+#endif
+       i=0;
+       script_data_in[i++]=swap_script(SCR_MOVE_ABS(pccb->datalen)^ SCR_DATA_IN); /* move  */
+       script_data_in[i++]=swap_script(phys_to_bus(pccb->pdata)); /* pointer to buffer */
+       script_data_in[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)));
+       script_data_in[i++]=swap_script(phys_to_bus(&script_status[0]));
+       script_data_in[i++]=swap_script(SCR_INT);
+       script_data_in[i++]=SIR_DATA_IN_ERR;
+#ifdef SCSI_SINGLE_STEP
+       start_script_data_in=(unsigned long)&script_data_in[0];
+       len_script_data_in=i*4;
+#endif
+       i=0;
+       script_msgin[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN);
+       script_msgin[i++]=swap_script(phys_to_bus(&pccb->msgin[0]));
+       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)));
+       script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0]));
+       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)));
+       script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0]));
+       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)));
+       script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0]));
+       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)));
+       script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0]));
+       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)));
+       script_msgin[i++]=swap_script(phys_to_bus(&script_msg_ext[0]));
+       script_msgin[i++]=swap_script(SCR_INT);
+       script_msgin[i++]=SIR_MSG_RECEIVED;
+#ifdef SCSI_SINGLE_STEP
+       start_script_msgin=(unsigned long)&script_msgin[0];
+       len_script_msgin=i*4;
+#endif
+       i=0;
+       script_msg_ext[i++]=swap_script(SCR_CLR (SCR_ACK)); /* clear ACK */
+       script_msg_ext[i++]=0;
+       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* assuming this is the msg length */
+       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[1]));
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
+       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
+       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
+       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[2]));
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
+       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
+       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
+       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[3]));
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
+       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
+       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
+       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[4]));
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
+       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
+       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
+       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[5]));
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
+       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
+       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
+       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[6]));
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
+       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
+       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
+       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[7]));
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
+       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
+       script_msg_ext[i++]=swap_script(SCR_INT);
+       script_msg_ext[i++]=SIR_MSG_OVER7;
+#ifdef SCSI_SINGLE_STEP
+       start_script_msg_ext=(unsigned long)&script_msg_ext[0];
+       len_script_msg_ext=i*4;
+#endif
+       i=0;
+       script_status[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_STATUS);
+       script_status[i++]=swap_script(phys_to_bus(&pccb->status));
+       script_status[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)));
+       script_status[i++]=swap_script(phys_to_bus(&script_msgin[0]));
+       script_status[i++]=swap_script(SCR_INT);
+       script_status[i++]=SIR_STATUS_ILL_PH;
+#ifdef SCSI_SINGLE_STEP
+       start_script_status=(unsigned long)&script_status[0];
+       len_script_status=i*4;
+#endif
+       i=0;
+       script_complete[i++]=swap_script(SCR_REG_REG (SCNTL2, SCR_AND, 0x7f));
+       script_complete[i++]=0;
+       script_complete[i++]=swap_script(SCR_CLR (SCR_ACK|SCR_ATN));
+       script_complete[i++]=0;
+       script_complete[i++]=swap_script(SCR_WAIT_DISC);
+       script_complete[i++]=0;
+       script_complete[i++]=swap_script(SCR_REG_REG(GPREG, SCR_OR, 0x01));
+       script_complete[i++]=0; /* LED OFF */
+       script_complete[i++]=swap_script(SCR_INT);
+       script_complete[i++]=SIR_COMPLETE;
+#ifdef SCSI_SINGLE_STEP
+       start_script_complete=(unsigned long)&script_complete[0];
+       len_script_complete=i*4;
+#endif
+       i=0;
+       script_error[i++]=swap_script(SCR_INT); /* interrupt if error */
+       script_error[i++]=SIR_SCRIPT_ERROR;
+#ifdef SCSI_SINGLE_STEP
+       start_script_error=(unsigned long)&script_error[0];
+       len_script_error=i*4;
+#endif
+       i=0;
+       script_reselection[i++]=swap_script(SCR_CLR (SCR_TRG)); /* target status */
+       script_reselection[i++]=0;
+       script_reselection[i++]=swap_script(SCR_WAIT_RESEL);
+       script_reselection[i++]=swap_script(phys_to_bus(&script_select[0])); /* len = 4 */
+#ifdef SCSI_SINGLE_STEP
+       start_script_reselection=(unsigned long)&script_reselection[0];
+       len_script_reselection=i*4;
+#endif
+}
+
+
+void scsi_issue(ccb *pccb)
+{
+       int busdevfunc = pccb->priv;
+       int i;
+       unsigned short sstat;
+       int retrycnt;  /* retry counter */
+       for(i=0;i<3;i++)
+               int_stat[i]=0; /* delete all int status */
+       /* struct pccb must be set-up correctly */
+       retrycnt=0;
+       PRINTF("ID %d issue cmd %02X\n",pccb->target,pccb->cmd[0]);
+       pccb->trans_bytes=0; /* no bytes transfered yet */
+       scsi_set_script(pccb); /* fill in SCRIPT                */
+       scsi_int_mask=STO | UDC | MA; /* | CMP; / * Interrupts which are enabled */
+       script_int_mask=0xff; /* enable all Ints */
+       scsi_int_enable();
+       scsi_write_dsp(phys_to_bus(&script_select[0])); /* start script */
+       /* now we have to wait for IRQs */
+retry:
+       /*
+        * This version of the driver is _not_ interrupt driven,
+        * but polls the chip's interrupt registers (ISTAT, DSTAT).
+        */
+       while(int_stat[0]==0)
+               handle_scsi_int();
+
+       if(int_stat[0]==SIR_COMPLETE) {
+               if(pccb->msgin[0]==M_DISCONNECT) {
+                       PRINTF("Wait for reselection\n");
+                       for(i=0;i<3;i++)
+                               int_stat[i]=0; /* delete all int status */
+                       scsi_write_dsp(phys_to_bus(&script_reselection[0])); /* start reselection script */
+                       goto retry;
+               }
+               pccb->contr_stat=SIR_COMPLETE;
+               return;
+       }
+       if((int_stat[0] & SCSI_INT_STATE)==SCSI_INT_STATE) { /* scsi interrupt */
+               sstat=(unsigned short)int_stat[0];
+               if((sstat & STO)==STO) { /* selection timeout */
+                       pccb->contr_stat=SCSI_SEL_TIME_OUT;
+                       scsi_write_byte(GPREG,0x01);
+                       PRINTF("ID: %X Selection Timeout\n",pccb->target);
+                       return;
+               }
+               if((sstat & UDC)==UDC) { /* unexpected disconnect */
+                       pccb->contr_stat=SCSI_UNEXP_DIS;
+                       scsi_write_byte(GPREG,0x01);
+                       PRINTF("ID: %X Unexpected Disconnect\n",pccb->target);
+                       return;
+               }
+               if((sstat & RSL)==RSL) { /* reselection */
+                       pccb->contr_stat=SCSI_UNEXP_DIS;
+                       scsi_write_byte(GPREG,0x01);
+                       PRINTF("ID: %X Unexpected Disconnect\n",pccb->target);
+                       return;
+               }
+               if(((sstat & MA)==MA)||((sstat & HTH)==HTH)) { /* phase missmatch */
+                       if(retrycnt<SCSI_MAX_RETRY) {
+                               pccb->trans_bytes=pccb->datalen -
+                                       ((unsigned long)scsi_read_byte(DBC) |
+                                       ((unsigned long)scsi_read_byte(DBC+1)<<8) |
+                                       ((unsigned long)scsi_read_byte(DBC+2)<<16));
+                               for(i=0;i<3;i++)
+                                       int_stat[i]=0; /* delete all int status */
+                               retrycnt++;
+                               PRINTF("ID: %X Phase Missmatch Retry %d Phase %02X transfered %lx\n",
+                                               pccb->target,retrycnt,scsi_read_byte(SBCL),pccb->trans_bytes);
+                               scsi_write_dsp(phys_to_bus(&script_cmd[4])); /* start retry script */
+                               goto retry;
+                       }
+                       if((sstat & MA)==MA)
+                               pccb->contr_stat=SCSI_MA_TIME_OUT;
+                       else
+                               pccb->contr_stat=SCSI_HNS_TIME_OUT;
+                       PRINTF("Phase Missmatch stat %lx\n",pccb->contr_stat);
+                       return;
+               } /* no phase int */
+/*             if((sstat & CMP)==CMP) {
+                       pccb->contr_stat=SIR_COMPLETE;
+                       return;
+               }
+*/
+               PRINTF("SCSI INT %lX\n",int_stat[0]);
+               pccb->contr_stat=int_stat[0];
+               return;
+       } /* end scsi int */
+       PRINTF("SCRIPT INT %lX phase %02X\n",int_stat[0],scsi_read_byte(SBCL));
+       pccb->contr_stat=int_stat[0];
+       return;
+}
+
+int scsi_exec(ccb *pccb)
+{
+       unsigned char tmpcmd[16],tmpstat;
+       int i,retrycnt,t;
+       unsigned long transbytes,datalen;
+       unsigned char *tmpptr;
+       retrycnt=0;
+retry:
+       scsi_issue(pccb);
+       if(pccb->contr_stat!=SIR_COMPLETE)
+               return FALSE;
+       if(pccb->status==S_GOOD)
+               return TRUE;
+       if(pccb->status==S_CHECK_COND) { /* check condition */
+               for(i=0;i<16;i++)
+                       tmpcmd[i]=pccb->cmd[i];
+               pccb->cmd[0]=SCSI_REQ_SENSE;
+               pccb->cmd[1]=pccb->lun<<5;
+               pccb->cmd[2]=0;
+               pccb->cmd[3]=0;
+               pccb->cmd[4]=14;
+               pccb->cmd[5]=0;
+               pccb->cmdlen=6;
+               pccb->msgout[0]=SCSI_IDENTIFY;
+               transbytes=pccb->trans_bytes;
+               tmpptr=pccb->pdata;
+               pccb->pdata=&pccb->sense_buf[0];
+               datalen=pccb->datalen;
+               pccb->datalen=14;
+               tmpstat=pccb->status;
+               scsi_issue(pccb);
+               for(i=0;i<16;i++)
+                       pccb->cmd[i]=tmpcmd[i];
+               pccb->trans_bytes=transbytes;
+               pccb->pdata=tmpptr;
+               pccb->datalen=datalen;
+               pccb->status=tmpstat;
+               PRINTF("Request_sense sense key %x ASC %x ASCQ %x\n",pccb->sense_buf[2]&0x0f,
+                       pccb->sense_buf[12],pccb->sense_buf[13]);
+               switch(pccb->sense_buf[2]&0xf) {
+                       case SENSE_NO_SENSE:
+                       case SENSE_RECOVERED_ERROR:
+                               /* seems to be ok */
+                               return TRUE;
+                               break;
+                       case SENSE_NOT_READY:
+                               if((pccb->sense_buf[12]!=0x04)||(pccb->sense_buf[13]!=0x01)) {
+                                       /* if device is not in process of becoming ready */
+                                       return FALSE;
+                                       break;
+                               } /* else fall through */
+                       case SENSE_UNIT_ATTENTION:
+                               if(retrycnt<SCSI_MAX_RETRY_NOT_READY) {
+                                       PRINTF("Target %d not ready, retry %d\n",pccb->target,retrycnt);
+                                       for(t=0;t<SCSI_NOT_READY_TIME_OUT;t++)
+                                               udelay(1000); /* 1sec wait */
+                                       retrycnt++;
+                                       goto retry;
+                               }
+                               PRINTF("Target %d not ready, %d retried\n",pccb->target,retrycnt);
+                               return FALSE;
+                       default:
+                               return FALSE;
+               }
+       }
+       PRINTF("Status = %X\n",pccb->status);
+       return FALSE;
+}
+
+
+void scsi_chip_init(void)
+{
+       /* first we issue a soft reset */
+       scsi_write_byte(ISTAT,SRST);
+       udelay(1000);
+       scsi_write_byte(ISTAT,0);
+       /* setup chip */
+       scsi_write_byte(SCNTL0,0xC0); /* full arbitration no start, no message, parity disabled, master */
+       scsi_write_byte(SCNTL1,0x00);
+       scsi_write_byte(SCNTL2,0x00);
+#ifndef CFG_SCSI_SYM53C8XX_CCF    /* config value for none 40 mhz clocks */
+       scsi_write_byte(SCNTL3,0x13); /* synchronous clock 40/4=10MHz, asynchronous 40MHz */
+#else
+       scsi_write_byte(SCNTL3,CFG_SCSI_SYM53C8XX_CCF); /* config value for none 40 mhz clocks */
+#endif
+       scsi_write_byte(SCID,0x47); /* ID=7, enable reselection */
+       scsi_write_byte(SXFER,0x00); /* synchronous transfer period 10MHz, asynchronous */
+       scsi_write_byte(SDID,0x00);  /* targed SCSI ID = 0 */
+       scsi_int_mask=0x0000; /* no Interrupt is enabled */
+       script_int_mask=0x00;
+       scsi_int_enable();
+       scsi_write_byte(GPREG,0x01); /* GPIO0 is LED (off) */
+       scsi_write_byte(GPCNTL,0x0E); /* GPIO0 is Output */
+       scsi_write_byte(STIME0,0x08); /* handshake timer disabled, selection timeout 512msec */
+       scsi_write_byte(RESPID,0x80); /* repond only to the own ID (reselection) */
+       scsi_write_byte(STEST1,0x00); /* not isolated, SCLK is used */
+       scsi_write_byte(STEST2,0x00); /* no Lowlevel Mode? */
+       scsi_write_byte(STEST3,0x80); /* enable tolerANT */
+       scsi_write_byte(CTEST3,0x04); /* clear FIFO */
+       scsi_write_byte(CTEST4,0x00);
+       scsi_write_byte(CTEST5,0x00);
+#ifdef SCSI_SINGLE_STEP
+/*     scsi_write_byte(DCNTL,IRQM | SSM);      */
+       scsi_write_byte(DCNTL,IRQD | SSM);
+       scsi_write_byte(DMODE,MAN);
+#else
+/*     scsi_write_byte(DCNTL,IRQM);    */
+       scsi_write_byte(DCNTL,IRQD);
+       scsi_write_byte(DMODE,0x00);
+#endif
+}
+#endif
+
+
+#endif /* CONFIG_SCSI_SYM53C8XX */
diff --git a/drivers/block/systemace.c b/drivers/block/systemace.c
new file mode 100644 (file)
index 0000000..7d82c27
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2004 Picture Elements, Inc.
+ *    Stephen Williams (XXXXXXXXXXXXXXXX)
+ *
+ *    This source code is free software; you can redistribute it
+ *    and/or modify it in source code form under the terms of the GNU
+ *    General Public License as published by the Free Software
+ *    Foundation; either version 2 of the License, or (at your option)
+ *    any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/*
+ * The Xilinx SystemACE chip support is activated by defining
+ * CONFIG_SYSTEMACE to turn on support, and CFG_SYSTEMACE_BASE
+ * to set the base address of the device. This code currently
+ * assumes that the chip is connected via a byte-wide bus.
+ *
+ * The CONFIG_SYSTEMACE also adds to fat support the device class
+ * "ace" that allows the user to execute "fatls ace 0" and the
+ * like. This works by making the systemace_get_dev function
+ * available to cmd_fat.c:get_dev and filling in a block device
+ * description that has all the bits needed for FAT support to
+ * read sectors.
+ *
+ * According to Xilinx technical support, before accessing the
+ * SystemACE CF you need to set the following control bits:
+ *      FORCECFGMODE : 1
+ *      CFGMODE : 0
+ *      CFGSTART : 0
+ */
+
+#include <common.h>
+#include <command.h>
+#include <systemace.h>
+#include <part.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_SYSTEMACE
+
+/*
+ * The ace_readw and writew functions read/write 16bit words, but the
+ * offset value is the BYTE offset as most used in the Xilinx
+ * datasheet for the SystemACE chip. The CFG_SYSTEMACE_BASE is defined
+ * to be the base address for the chip, usually in the local
+ * peripheral bus.
+ */
+#if (CFG_SYSTEMACE_WIDTH == 8)
+#if !defined(__BIG_ENDIAN)
+#define ace_readw(off) ((readb(CFG_SYSTEMACE_BASE+off)<<8) | \
+                       (readb(CFG_SYSTEMACE_BASE+off+1)))
+#define ace_writew(val, off) {writeb(val>>8, CFG_SYSTEMACE_BASE+off); \
+                             writeb(val, CFG_SYSTEMACE_BASE+off+1);}
+#else
+#define ace_readw(off) ((readb(CFG_SYSTEMACE_BASE+off)) | \
+                       (readb(CFG_SYSTEMACE_BASE+off+1)<<8))
+#define ace_writew(val, off) {writeb(val, CFG_SYSTEMACE_BASE+off); \
+                             writeb(val>>8, CFG_SYSTEMACE_BASE+off+1);}
+#endif
+#else
+#define ace_readw(off) (in16(CFG_SYSTEMACE_BASE+off))
+#define ace_writew(val, off) (out16(CFG_SYSTEMACE_BASE+off,val))
+#endif
+
+/* */
+
+static unsigned long systemace_read(int dev, unsigned long start,
+                                   unsigned long blkcnt, void *buffer);
+
+static block_dev_desc_t systemace_dev = { 0 };
+
+static int get_cf_lock(void)
+{
+       int retry = 10;
+
+       /* CONTROLREG = LOCKREG */
+       unsigned val = ace_readw(0x18);
+       val |= 0x0002;
+       ace_writew((val & 0xffff), 0x18);
+
+       /* Wait for MPULOCK in STATUSREG[15:0] */
+       while (!(ace_readw(0x04) & 0x0002)) {
+
+               if (retry < 0)
+                       return -1;
+
+               udelay(100000);
+               retry -= 1;
+       }
+
+       return 0;
+}
+
+static void release_cf_lock(void)
+{
+       unsigned val = ace_readw(0x18);
+       val &= ~(0x0002);
+       ace_writew((val & 0xffff), 0x18);
+}
+
+block_dev_desc_t *systemace_get_dev(int dev)
+{
+       /* The first time through this, the systemace_dev object is
+          not yet initialized. In that case, fill it in. */
+       if (systemace_dev.blksz == 0) {
+               systemace_dev.if_type = IF_TYPE_UNKNOWN;
+               systemace_dev.dev = 0;
+               systemace_dev.part_type = PART_TYPE_UNKNOWN;
+               systemace_dev.type = DEV_TYPE_HARDDISK;
+               systemace_dev.blksz = 512;
+               systemace_dev.removable = 1;
+               systemace_dev.block_read = systemace_read;
+
+               /*
+                * Ensure the correct bus mode (8/16 bits) gets enabled
+                */
+               ace_writew(CFG_SYSTEMACE_WIDTH == 8 ? 0 : 0x0001, 0);
+
+               init_part(&systemace_dev);
+
+       }
+
+       return &systemace_dev;
+}
+
+/*
+ * This function is called (by dereferencing the block_read pointer in
+ * the dev_desc) to read blocks of data. The return value is the
+ * number of blocks read. A zero return indicates an error.
+ */
+static unsigned long systemace_read(int dev, unsigned long start,
+                                   unsigned long blkcnt, void *buffer)
+{
+       int retry;
+       unsigned blk_countdown;
+       unsigned char *dp = buffer;
+       unsigned val;
+
+       if (get_cf_lock() < 0) {
+               unsigned status = ace_readw(0x04);
+
+               /* If CFDETECT is false, card is missing. */
+               if (!(status & 0x0010)) {
+                       printf("** CompactFlash card not present. **\n");
+                       return 0;
+               }
+
+               printf("**** ACE locked away from me (STATUSREG=%04x)\n",
+                      status);
+               return 0;
+       }
+#ifdef DEBUG_SYSTEMACE
+       printf("... systemace read %lu sectors at %lu\n", blkcnt, start);
+#endif
+
+       retry = 2000;
+       for (;;) {
+               val = ace_readw(0x04);
+
+               /* If CFDETECT is false, card is missing. */
+               if (!(val & 0x0010)) {
+                       printf("**** ACE CompactFlash not found.\n");
+                       release_cf_lock();
+                       return 0;
+               }
+
+               /* If RDYFORCMD, then we are ready to go. */
+               if (val & 0x0100)
+                       break;
+
+               if (retry < 0) {
+                       printf("**** SystemACE not ready.\n");
+                       release_cf_lock();
+                       return 0;
+               }
+
+               udelay(1000);
+               retry -= 1;
+       }
+
+       /* The SystemACE can only transfer 256 sectors at a time, so
+          limit the current chunk of sectors. The blk_countdown
+          variable is the number of sectors left to transfer. */
+
+       blk_countdown = blkcnt;
+       while (blk_countdown > 0) {
+               unsigned trans = blk_countdown;
+
+               if (trans > 256)
+                       trans = 256;
+
+#ifdef DEBUG_SYSTEMACE
+               printf("... transfer %lu sector in a chunk\n", trans);
+#endif
+               /* Write LBA block address */
+               ace_writew((start >> 0) & 0xffff, 0x10);
+               ace_writew((start >> 16) & 0x0fff, 0x12);
+
+               /* NOTE: in the Write Sector count below, a count of 0
+                  causes a transfer of 256, so &0xff gives the right
+                  value for whatever transfer count we want. */
+
+               /* Write sector count | ReadMemCardData. */
+               ace_writew((trans & 0xff) | 0x0300, 0x14);
+
+/*
+ * For FPGA configuration via SystemACE is reset unacceptable
+ * CFGDONE bit in STATUSREG is not set to 1.
+ */
+#ifndef SYSTEMACE_CONFIG_FPGA
+               /* Reset the configruation controller */
+               val = ace_readw(0x18);
+               val |= 0x0080;
+               ace_writew(val, 0x18);
+#endif
+
+               retry = trans * 16;
+               while (retry > 0) {
+                       int idx;
+
+                       /* Wait for buffer to become ready. */
+                       while (!(ace_readw(0x04) & 0x0020)) {
+                               udelay(100);
+                       }
+
+                       /* Read 16 words of 2bytes from the sector buffer. */
+                       for (idx = 0; idx < 16; idx += 1) {
+                               unsigned short val = ace_readw(0x40);
+                               *dp++ = val & 0xff;
+                               *dp++ = (val >> 8) & 0xff;
+                       }
+
+                       retry -= 1;
+               }
+
+               /* Clear the configruation controller reset */
+               val = ace_readw(0x18);
+               val &= ~0x0080;
+               ace_writew(val, 0x18);
+
+               /* Count the blocks we transfer this time. */
+               start += trans;
+               blk_countdown -= trans;
+       }
+
+       release_cf_lock();
+
+       return blkcnt;
+}
+#endif /* CONFIG_SYSTEMACE */
diff --git a/drivers/cfb_console.c b/drivers/cfb_console.c
deleted file mode 100644 (file)
index bcf8771..0000000
+++ /dev/null
@@ -1,1274 +0,0 @@
-/*
- * (C) Copyright 2002 ELTEC Elektronik AG
- * Frank Gottschling <fgottschling@eltec.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * cfb_console.c
- *
- * Color Framebuffer Console driver for 8/15/16/24/32 bits per pixel.
- *
- * At the moment only the 8x16 font is tested and the font fore- and
- * background color is limited to black/white/gray colors. The Linux
- * logo can be placed in the upper left corner and additional board
- * information strings (that normaly goes to serial port) can be drawed.
- *
- * The console driver can use the standard PC keyboard interface (i8042)
- * for character input. Character output goes to a memory mapped video
- * framebuffer with little or big-endian organisation.
- * With environment setting 'console=serial' the console i/o can be
- * forced to serial port.
-
- The driver uses graphic specific defines/parameters/functions:
-
- (for SMI LynxE graphic chip)
-
- CONFIG_VIDEO_SMI_LYNXEM - use graphic driver for SMI 710,712,810
- VIDEO_FB_LITTLE_ENDIAN         - framebuffer organisation default: big endian
- VIDEO_HW_RECTFILL      - graphic driver supports hardware rectangle fill
- VIDEO_HW_BITBLT        - graphic driver supports hardware bit blt
-
- Console Parameters are set by graphic drivers global struct:
-
- VIDEO_VISIBLE_COLS         - x resolution
- VIDEO_VISIBLE_ROWS         - y resolution
- VIDEO_PIXEL_SIZE           - storage size in byte per pixel
- VIDEO_DATA_FORMAT          - graphical data format GDF
- VIDEO_FB_ADRS              - start of video memory
-
- CONFIG_I8042_KBD           - AT Keyboard driver for i8042
- VIDEO_KBD_INIT_FCT         - init function for keyboard
- VIDEO_TSTC_FCT                     - keyboard_tstc function
- VIDEO_GETC_FCT                     - keyboard_getc function
-
- CONFIG_CONSOLE_CURSOR      - on/off drawing cursor is done with delay
-                              loop in VIDEO_TSTC_FCT (i8042)
- CFG_CONSOLE_BLINK_COUNT     - value for delay loop - blink rate
- CONFIG_CONSOLE_TIME        - display time/date in upper right corner,
-                              needs CONFIG_CMD_DATE and CONFIG_CONSOLE_CURSOR
- CONFIG_VIDEO_LOGO          - display Linux Logo in upper left corner
- CONFIG_VIDEO_BMP_LOGO      - use bmp_logo instead of linux_logo
- CONFIG_CONSOLE_EXTRA_INFO   - display additional board information strings
-                              that normaly goes to serial port. This define
-                              requires a board specific function:
-                              video_drawstring (VIDEO_INFO_X,
-                                                VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT,
-                                                info);
-                              that fills a info buffer at i=row.
-                              s.a: board/eltec/bab7xx.
-CONFIG_VGA_AS_SINGLE_DEVICE  - If set the framebuffer device will be initialised
-                              as an output only device. The Keyboard driver
-                              will not be set-up. This may be used, if you
-                              have none or more than one Keyboard devices
-                              (USB Keyboard, AT Keyboard).
-
-CONFIG_VIDEO_SW_CURSOR:             - Draws a cursor after the last character. No
-                              blinking is provided. Uses the macros CURSOR_SET
-                              and CURSOR_OFF.
-CONFIG_VIDEO_HW_CURSOR:             - Uses the hardware cursor capability of the
-                              graphic chip. Uses the macro CURSOR_SET.
-                              ATTENTION: If booting an OS, the display driver
-                              must disable the hardware register of the graphic
-                              chip. Otherwise a blinking field is displayed
-*/
-
-#include <common.h>
-
-#ifdef CONFIG_CFB_CONSOLE
-
-#include <malloc.h>
-
-/*****************************************************************************/
-/* Console device defines with SMI graphic                                  */
-/* Any other graphic must change this section                               */
-/*****************************************************************************/
-
-#ifdef CONFIG_VIDEO_SMI_LYNXEM
-
-#define VIDEO_FB_LITTLE_ENDIAN
-#define VIDEO_HW_RECTFILL
-#define VIDEO_HW_BITBLT
-#endif
-
-/*****************************************************************************/
-/* Defines for the CT69000 driver                                           */
-/*****************************************************************************/
-#ifdef CONFIG_VIDEO_CT69000
-
-#define VIDEO_FB_LITTLE_ENDIAN
-#define VIDEO_HW_RECTFILL
-#define VIDEO_HW_BITBLT
-#endif
-
-/*****************************************************************************/
-/* Defines for the SED13806 driver                                          */
-/*****************************************************************************/
-#ifdef CONFIG_VIDEO_SED13806
-
-#ifndef CONFIG_TOTAL5200
-#define VIDEO_FB_LITTLE_ENDIAN
-#endif
-#define VIDEO_HW_RECTFILL
-#define VIDEO_HW_BITBLT
-#endif
-
-/*****************************************************************************/
-/* Defines for the SED13806 driver                                          */
-/*****************************************************************************/
-#ifdef CONFIG_VIDEO_SM501
-
-#ifdef CONFIG_HH405
-#define VIDEO_FB_LITTLE_ENDIAN
-#endif
-#endif
-
-/*****************************************************************************/
-/* Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc            */
-/*****************************************************************************/
-#include <video_fb.h>
-
-/*****************************************************************************/
-/* some Macros                                                              */
-/*****************************************************************************/
-#define VIDEO_VISIBLE_COLS     (pGD->winSizeX)
-#define VIDEO_VISIBLE_ROWS     (pGD->winSizeY)
-#define VIDEO_PIXEL_SIZE       (pGD->gdfBytesPP)
-#define VIDEO_DATA_FORMAT      (pGD->gdfIndex)
-#define VIDEO_FB_ADRS          (pGD->frameAdrs)
-
-/*****************************************************************************/
-/* Console device defines with i8042 keyboard controller                    */
-/* Any other keyboard controller must change this section                   */
-/*****************************************************************************/
-
-#ifdef CONFIG_I8042_KBD
-#include <i8042.h>
-
-#define VIDEO_KBD_INIT_FCT     i8042_kbd_init()
-#define VIDEO_TSTC_FCT         i8042_tstc
-#define VIDEO_GETC_FCT         i8042_getc
-#endif
-
-/*****************************************************************************/
-/* Console device                                                           */
-/*****************************************************************************/
-
-#include <version.h>
-#include <linux/types.h>
-#include <devices.h>
-#include <video_font.h>
-
-#if defined(CONFIG_CMD_DATE)
-#include <rtc.h>
-#endif
-
-#if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
-#include <watchdog.h>
-#include <bmp_layout.h>
-#endif
-
-/*****************************************************************************/
-/* Cursor definition:                                                       */
-/* CONFIG_CONSOLE_CURSOR:  Uses a timer function (see drivers/i8042.c) to    */
-/*                        let the cursor blink. Uses the macros CURSOR_OFF  */
-/*                        and CURSOR_ON.                                    */
-/* CONFIG_VIDEO_SW_CURSOR: Draws a cursor after the last character. No      */
-/*                        blinking is provided. Uses the macros CURSOR_SET  */
-/*                        and CURSOR_OFF.                                   */
-/* CONFIG_VIDEO_HW_CURSOR: Uses the hardware cursor capability of the       */
-/*                        graphic chip. Uses the macro CURSOR_SET.          */
-/*                        ATTENTION: If booting an OS, the display driver   */
-/*                        must disable the hardware register of the graphic */
-/*                        chip. Otherwise a blinking field is displayed     */
-/*****************************************************************************/
-#if !defined(CONFIG_CONSOLE_CURSOR) && \
-    !defined(CONFIG_VIDEO_SW_CURSOR) && \
-    !defined(CONFIG_VIDEO_HW_CURSOR)
-/* no Cursor defined */
-#define CURSOR_ON
-#define CURSOR_OFF
-#define CURSOR_SET
-#endif
-
-#ifdef CONFIG_CONSOLE_CURSOR
-#ifdef CURSOR_ON
-#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
-#endif
-void   console_cursor (int state);
-#define CURSOR_ON  console_cursor(1);
-#define CURSOR_OFF console_cursor(0);
-#define CURSOR_SET
-#ifndef CONFIG_I8042_KBD
-#warning Cursor drawing on/off needs timer function s.a. drivers/i8042.c
-#endif
-#else
-#ifdef CONFIG_CONSOLE_TIME
-#error CONFIG_CONSOLE_CURSOR must be defined for CONFIG_CONSOLE_TIME
-#endif
-#endif /* CONFIG_CONSOLE_CURSOR */
-
-#ifdef CONFIG_VIDEO_SW_CURSOR
-#ifdef CURSOR_ON
-#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
-#endif
-#define CURSOR_ON
-#define CURSOR_OFF video_putchar(console_col * VIDEO_FONT_WIDTH,\
-                                console_row * VIDEO_FONT_HEIGHT, ' ');
-#define CURSOR_SET video_set_cursor();
-#endif /* CONFIG_VIDEO_SW_CURSOR */
-
-
-#ifdef CONFIG_VIDEO_HW_CURSOR
-#ifdef CURSOR_ON
-#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
-#endif
-#define CURSOR_ON
-#define CURSOR_OFF
-#define CURSOR_SET video_set_hw_cursor(console_col * VIDEO_FONT_WIDTH, \
-                 (console_row * VIDEO_FONT_HEIGHT) + VIDEO_LOGO_HEIGHT);
-#endif /* CONFIG_VIDEO_HW_CURSOR */
-
-#ifdef CONFIG_VIDEO_LOGO
-#ifdef CONFIG_VIDEO_BMP_LOGO
-#include <bmp_logo.h>
-#define VIDEO_LOGO_WIDTH       BMP_LOGO_WIDTH
-#define VIDEO_LOGO_HEIGHT      BMP_LOGO_HEIGHT
-#define VIDEO_LOGO_LUT_OFFSET  BMP_LOGO_OFFSET
-#define VIDEO_LOGO_COLORS      BMP_LOGO_COLORS
-
-#else  /* CONFIG_VIDEO_BMP_LOGO */
-#define LINUX_LOGO_WIDTH       80
-#define LINUX_LOGO_HEIGHT      80
-#define LINUX_LOGO_COLORS      214
-#define LINUX_LOGO_LUT_OFFSET  0x20
-#define __initdata
-#include <linux_logo.h>
-#define VIDEO_LOGO_WIDTH       LINUX_LOGO_WIDTH
-#define VIDEO_LOGO_HEIGHT      LINUX_LOGO_HEIGHT
-#define VIDEO_LOGO_LUT_OFFSET  LINUX_LOGO_LUT_OFFSET
-#define VIDEO_LOGO_COLORS      LINUX_LOGO_COLORS
-#endif /* CONFIG_VIDEO_BMP_LOGO */
-#define VIDEO_INFO_X           (VIDEO_LOGO_WIDTH)
-#define VIDEO_INFO_Y           (VIDEO_FONT_HEIGHT/2)
-#else  /* CONFIG_VIDEO_LOGO */
-#define VIDEO_LOGO_WIDTH       0
-#define VIDEO_LOGO_HEIGHT      0
-#endif /* CONFIG_VIDEO_LOGO */
-
-#define VIDEO_COLS             VIDEO_VISIBLE_COLS
-#define VIDEO_ROWS             VIDEO_VISIBLE_ROWS
-#define VIDEO_SIZE             (VIDEO_ROWS*VIDEO_COLS*VIDEO_PIXEL_SIZE)
-#define VIDEO_PIX_BLOCKS       (VIDEO_SIZE >> 2)
-#define VIDEO_LINE_LEN         (VIDEO_COLS*VIDEO_PIXEL_SIZE)
-#define VIDEO_BURST_LEN                (VIDEO_COLS/8)
-
-#ifdef CONFIG_VIDEO_LOGO
-#define CONSOLE_ROWS           ((VIDEO_ROWS - VIDEO_LOGO_HEIGHT) / VIDEO_FONT_HEIGHT)
-#else
-#define CONSOLE_ROWS           (VIDEO_ROWS / VIDEO_FONT_HEIGHT)
-#endif
-
-#define CONSOLE_COLS           (VIDEO_COLS / VIDEO_FONT_WIDTH)
-#define CONSOLE_ROW_SIZE       (VIDEO_FONT_HEIGHT * VIDEO_LINE_LEN)
-#define CONSOLE_ROW_FIRST      (video_console_address)
-#define CONSOLE_ROW_SECOND     (video_console_address + CONSOLE_ROW_SIZE)
-#define CONSOLE_ROW_LAST       (video_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE)
-#define CONSOLE_SIZE           (CONSOLE_ROW_SIZE * CONSOLE_ROWS)
-#define CONSOLE_SCROLL_SIZE    (CONSOLE_SIZE - CONSOLE_ROW_SIZE)
-
-/* Macros */
-#ifdef VIDEO_FB_LITTLE_ENDIAN
-#define SWAP16(x)       ((((x) & 0x00ff) << 8) | ( (x) >> 8))
-#define SWAP32(x)       ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\
-                         (((x) & 0x00ff0000) >>  8) | (((x) & 0xff000000) >> 24) )
-#define SHORTSWAP32(x)  ((((x) & 0x000000ff) <<  8) | (((x) & 0x0000ff00) >> 8)|\
-                         (((x) & 0x00ff0000) <<  8) | (((x) & 0xff000000) >> 8) )
-#else
-#define SWAP16(x)       (x)
-#define SWAP32(x)       (x)
-#define SHORTSWAP32(x)  (x)
-#endif
-
-#if defined(DEBUG) || defined(DEBUG_CFB_CONSOLE)
-#define PRINTD(x)        printf(x)
-#else
-#define PRINTD(x)
-#endif
-
-
-#ifdef CONFIG_CONSOLE_EXTRA_INFO
-extern void video_get_info_str (    /* setup a board string: type, speed, etc. */
-    int line_number,       /* location to place info string beside logo */
-    char *info             /* buffer for info string */
-    );
-
-#endif
-
-/* Locals */
-static GraphicDevice *pGD;     /* Pointer to Graphic array */
-
-static void *video_fb_address;         /* frame buffer address */
-static void *video_console_address;    /* console buffer start address */
-
-static int console_col = 0; /* cursor col */
-static int console_row = 0; /* cursor row */
-
-static u32 eorx, fgx, bgx;  /* color pats */
-
-static const int video_font_draw_table8[] = {
-           0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
-           0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
-           0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
-           0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff };
-
-static const int video_font_draw_table15[] = {
-           0x00000000, 0x00007fff, 0x7fff0000, 0x7fff7fff };
-
-static const int video_font_draw_table16[] = {
-           0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff };
-
-static const int video_font_draw_table24[16][3] = {
-           { 0x00000000, 0x00000000, 0x00000000 },
-           { 0x00000000, 0x00000000, 0x00ffffff },
-           { 0x00000000, 0x0000ffff, 0xff000000 },
-           { 0x00000000, 0x0000ffff, 0xffffffff },
-           { 0x000000ff, 0xffff0000, 0x00000000 },
-           { 0x000000ff, 0xffff0000, 0x00ffffff },
-           { 0x000000ff, 0xffffffff, 0xff000000 },
-           { 0x000000ff, 0xffffffff, 0xffffffff },
-           { 0xffffff00, 0x00000000, 0x00000000 },
-           { 0xffffff00, 0x00000000, 0x00ffffff },
-           { 0xffffff00, 0x0000ffff, 0xff000000 },
-           { 0xffffff00, 0x0000ffff, 0xffffffff },
-           { 0xffffffff, 0xffff0000, 0x00000000 },
-           { 0xffffffff, 0xffff0000, 0x00ffffff },
-           { 0xffffffff, 0xffffffff, 0xff000000 },
-           { 0xffffffff, 0xffffffff, 0xffffffff } };
-
-static const int video_font_draw_table32[16][4] = {
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-           { 0x00000000, 0x00000000, 0x00000000, 0x00ffffff },
-           { 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 },
-           { 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff },
-           { 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 },
-           { 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff },
-           { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 },
-           { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff },
-           { 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 },
-           { 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff },
-           { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 },
-           { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff },
-           { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 },
-           { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff },
-           { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 },
-           { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff } };
-
-
-int gunzip(void *, int, unsigned char *, unsigned long *);
-
-/******************************************************************************/
-
-static void video_drawchars (int xx, int yy, unsigned char *s, int count)
-{
-       u8 *cdat, *dest, *dest0;
-       int rows, offset, c;
-
-       offset = yy * VIDEO_LINE_LEN + xx * VIDEO_PIXEL_SIZE;
-       dest0 = video_fb_address + offset;
-
-       switch (VIDEO_DATA_FORMAT) {
-       case GDF__8BIT_INDEX:
-       case GDF__8BIT_332RGB:
-               while (count--) {
-                       c = *s;
-                       cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
-                       for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
-                            rows--;
-                            dest += VIDEO_LINE_LEN) {
-                               u8 bits = *cdat++;
-
-                               ((u32 *) dest)[0] = (video_font_draw_table8[bits >> 4] & eorx) ^ bgx;
-                               ((u32 *) dest)[1] = (video_font_draw_table8[bits & 15] & eorx) ^ bgx;
-                       }
-                       dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
-                       s++;
-               }
-               break;
-
-       case GDF_15BIT_555RGB:
-               while (count--) {
-                       c = *s;
-                       cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
-                       for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
-                            rows--;
-                            dest += VIDEO_LINE_LEN) {
-                               u8 bits = *cdat++;
-
-                               ((u32 *) dest)[0] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 6] & eorx) ^ bgx);
-                               ((u32 *) dest)[1] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 4 & 3] & eorx) ^ bgx);
-                               ((u32 *) dest)[2] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 2 & 3] & eorx) ^ bgx);
-                               ((u32 *) dest)[3] = SHORTSWAP32 ((video_font_draw_table15 [bits & 3] & eorx) ^ bgx);
-                       }
-                       dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
-                       s++;
-               }
-               break;
-
-       case GDF_16BIT_565RGB:
-               while (count--) {
-                       c = *s;
-                       cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
-                       for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
-                            rows--;
-                            dest += VIDEO_LINE_LEN) {
-                               u8 bits = *cdat++;
-
-                               ((u32 *) dest)[0] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 6] & eorx) ^ bgx);
-                               ((u32 *) dest)[1] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 4 & 3] & eorx) ^ bgx);
-                               ((u32 *) dest)[2] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 2 & 3] & eorx) ^ bgx);
-                               ((u32 *) dest)[3] = SHORTSWAP32 ((video_font_draw_table16 [bits & 3] & eorx) ^ bgx);
-                       }
-                       dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
-                       s++;
-               }
-               break;
-
-       case GDF_32BIT_X888RGB:
-               while (count--) {
-                       c = *s;
-                       cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
-                       for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
-                            rows--;
-                            dest += VIDEO_LINE_LEN) {
-                               u8 bits = *cdat++;
-
-                               ((u32 *) dest)[0] = SWAP32 ((video_font_draw_table32 [bits >> 4][0] & eorx) ^ bgx);
-                               ((u32 *) dest)[1] = SWAP32 ((video_font_draw_table32 [bits >> 4][1] & eorx) ^ bgx);
-                               ((u32 *) dest)[2] = SWAP32 ((video_font_draw_table32 [bits >> 4][2] & eorx) ^ bgx);
-                               ((u32 *) dest)[3] = SWAP32 ((video_font_draw_table32 [bits >> 4][3] & eorx) ^ bgx);
-                               ((u32 *) dest)[4] = SWAP32 ((video_font_draw_table32 [bits & 15][0] & eorx) ^ bgx);
-                               ((u32 *) dest)[5] = SWAP32 ((video_font_draw_table32 [bits & 15][1] & eorx) ^ bgx);
-                               ((u32 *) dest)[6] = SWAP32 ((video_font_draw_table32 [bits & 15][2] & eorx) ^ bgx);
-                               ((u32 *) dest)[7] = SWAP32 ((video_font_draw_table32 [bits & 15][3] & eorx) ^ bgx);
-                       }
-                       dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
-                       s++;
-               }
-               break;
-
-       case GDF_24BIT_888RGB:
-               while (count--) {
-                       c = *s;
-                       cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
-                       for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
-                            rows--;
-                            dest += VIDEO_LINE_LEN) {
-                               u8 bits = *cdat++;
-
-                               ((u32 *) dest)[0] = (video_font_draw_table24[bits >> 4][0] & eorx) ^ bgx;
-                               ((u32 *) dest)[1] = (video_font_draw_table24[bits >> 4][1] & eorx) ^ bgx;
-                               ((u32 *) dest)[2] = (video_font_draw_table24[bits >> 4][2] & eorx) ^ bgx;
-                               ((u32 *) dest)[3] = (video_font_draw_table24[bits & 15][0] & eorx) ^ bgx;
-                               ((u32 *) dest)[4] = (video_font_draw_table24[bits & 15][1] & eorx) ^ bgx;
-                               ((u32 *) dest)[5] = (video_font_draw_table24[bits & 15][2] & eorx) ^ bgx;
-                       }
-                       dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
-                       s++;
-               }
-               break;
-       }
-}
-
-/*****************************************************************************/
-
-static inline void video_drawstring (int xx, int yy, unsigned char *s)
-{
-       video_drawchars (xx, yy, s, strlen ((char *)s));
-}
-
-/*****************************************************************************/
-
-static void video_putchar (int xx, int yy, unsigned char c)
-{
-       video_drawchars (xx, yy + VIDEO_LOGO_HEIGHT, &c, 1);
-}
-
-/*****************************************************************************/
-#if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
-static void video_set_cursor (void)
-{
-       /* swap drawing colors */
-       eorx = fgx;
-       fgx = bgx;
-       bgx = eorx;
-       eorx = fgx ^ bgx;
-       /* draw cursor */
-       video_putchar (console_col * VIDEO_FONT_WIDTH,
-                      console_row * VIDEO_FONT_HEIGHT,
-                      ' ');
-       /* restore drawing colors */
-       eorx = fgx;
-       fgx = bgx;
-       bgx = eorx;
-       eorx = fgx ^ bgx;
-}
-#endif
-/*****************************************************************************/
-#ifdef CONFIG_CONSOLE_CURSOR
-void console_cursor (int state)
-{
-       static int last_state = 0;
-
-#ifdef CONFIG_CONSOLE_TIME
-       struct rtc_time tm;
-       char info[16];
-
-       /* time update only if cursor is on (faster scroll) */
-       if (state) {
-               rtc_get (&tm);
-
-               sprintf (info, " %02d:%02d:%02d ", tm.tm_hour, tm.tm_min,
-                        tm.tm_sec);
-               video_drawstring (VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH,
-                                 VIDEO_INFO_Y, (uchar *)info);
-
-               sprintf (info, "%02d.%02d.%04d", tm.tm_mday, tm.tm_mon,
-                        tm.tm_year);
-               video_drawstring (VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH,
-                                 VIDEO_INFO_Y + 1 * VIDEO_FONT_HEIGHT, (uchar *)info);
-       }
-#endif
-
-       if (state && (last_state != state)) {
-               video_set_cursor ();
-       }
-
-       if (!state && (last_state != state)) {
-               /* clear cursor */
-               video_putchar (console_col * VIDEO_FONT_WIDTH,
-                              console_row * VIDEO_FONT_HEIGHT,
-                              ' ');
-       }
-
-       last_state = state;
-}
-#endif
-
-/*****************************************************************************/
-
-#ifndef VIDEO_HW_RECTFILL
-static void memsetl (int *p, int c, int v)
-{
-       while (c--)
-               *(p++) = v;
-}
-#endif
-
-/*****************************************************************************/
-
-#ifndef VIDEO_HW_BITBLT
-static void memcpyl (int *d, int *s, int c)
-{
-       while (c--)
-               *(d++) = *(s++);
-}
-#endif
-
-/*****************************************************************************/
-
-static void console_scrollup (void)
-{
-       /* copy up rows ignoring the first one */
-
-#ifdef VIDEO_HW_BITBLT
-       video_hw_bitblt (VIDEO_PIXEL_SIZE,      /* bytes per pixel */
-                        0,     /* source pos x */
-                        VIDEO_LOGO_HEIGHT + VIDEO_FONT_HEIGHT, /* source pos y */
-                        0,     /* dest pos x */
-                        VIDEO_LOGO_HEIGHT,     /* dest pos y */
-                        VIDEO_VISIBLE_COLS,    /* frame width */
-                        VIDEO_VISIBLE_ROWS - VIDEO_LOGO_HEIGHT - VIDEO_FONT_HEIGHT     /* frame height */
-               );
-#else
-       memcpyl (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND,
-                CONSOLE_SCROLL_SIZE >> 2);
-#endif
-
-       /* clear the last one */
-#ifdef VIDEO_HW_RECTFILL
-       video_hw_rectfill (VIDEO_PIXEL_SIZE,    /* bytes per pixel */
-                          0,   /* dest pos x */
-                          VIDEO_VISIBLE_ROWS - VIDEO_FONT_HEIGHT,      /* dest pos y */
-                          VIDEO_VISIBLE_COLS,  /* frame width */
-                          VIDEO_FONT_HEIGHT,   /* frame height */
-                          CONSOLE_BG_COL       /* fill color */
-               );
-#else
-       memsetl (CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL);
-#endif
-}
-
-/*****************************************************************************/
-
-static void console_back (void)
-{
-       CURSOR_OFF console_col--;
-
-       if (console_col < 0) {
-               console_col = CONSOLE_COLS - 1;
-               console_row--;
-               if (console_row < 0)
-                       console_row = 0;
-       }
-       video_putchar (console_col * VIDEO_FONT_WIDTH,
-                      console_row * VIDEO_FONT_HEIGHT,
-                      ' ');
-}
-
-/*****************************************************************************/
-
-static void console_newline (void)
-{
-       CURSOR_OFF console_row++;
-       console_col = 0;
-
-       /* Check if we need to scroll the terminal */
-       if (console_row >= CONSOLE_ROWS) {
-               /* Scroll everything up */
-               console_scrollup ();
-
-               /* Decrement row number */
-               console_row--;
-       }
-}
-
-/*****************************************************************************/
-
-void video_putc (const char c)
-{
-       switch (c) {
-       case 13:                /* ignore */
-               break;
-
-       case '\n':              /* next line */
-               console_newline ();
-               break;
-
-       case 9:         /* tab 8 */
-               CURSOR_OFF console_col |= 0x0008;
-               console_col &= ~0x0007;
-
-               if (console_col >= CONSOLE_COLS)
-                       console_newline ();
-               break;
-
-       case 8:         /* backspace */
-               console_back ();
-               break;
-
-       default:                /* draw the char */
-               video_putchar (console_col * VIDEO_FONT_WIDTH,
-                              console_row * VIDEO_FONT_HEIGHT,
-                              c);
-               console_col++;
-
-               /* check for newline */
-               if (console_col >= CONSOLE_COLS)
-                       console_newline ();
-       }
-CURSOR_SET}
-
-
-/*****************************************************************************/
-
-void video_puts (const char *s)
-{
-       int count = strlen (s);
-
-       while (count--)
-               video_putc (*s++);
-}
-
-/*****************************************************************************/
-
-#if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
-
-#define FILL_8BIT_332RGB(r,g,b)        {                       \
-       *fb = ((r>>5)<<5) | ((g>>5)<<2) | (b>>6);       \
-       fb ++;                                          \
-}
-
-#define FILL_15BIT_555RGB(r,g,b) {                     \
-       *(unsigned short *)fb = SWAP16((unsigned short)(((r>>3)<<10) | ((g>>3)<<5) | (b>>3))); \
-       fb += 2;                                        \
-}
-
-#define FILL_16BIT_565RGB(r,g,b) {                     \
-       *(unsigned short *)fb = SWAP16((unsigned short)((((r)>>3)<<11) | (((g)>>2)<<5) | ((b)>>3))); \
-       fb += 2;                                        \
-}
-
-#define FILL_32BIT_X888RGB(r,g,b) {                    \
-       *(unsigned long *)fb = SWAP32((unsigned long)(((r<<16) | (g<<8) | b))); \
-       fb += 4;                                        \
-}
-
-#ifdef VIDEO_FB_LITTLE_ENDIAN
-#define FILL_24BIT_888RGB(r,g,b) {                     \
-       fb[0] = b;                                      \
-       fb[1] = g;                                      \
-       fb[2] = r;                                      \
-       fb += 3;                                        \
-}
-#else
-#define FILL_24BIT_888RGB(r,g,b) {                     \
-       fb[0] = r;                                      \
-       fb[1] = g;                                      \
-       fb[2] = b;                                      \
-       fb += 3;                                        \
-}
-#endif
-
-
-/*
- * Display the BMP file located at address bmp_image.
- * Only uncompressed
- */
-int video_display_bitmap (ulong bmp_image, int x, int y)
-{
-       ushort xcount, ycount;
-       uchar *fb;
-       bmp_image_t *bmp = (bmp_image_t *) bmp_image;
-       uchar *bmap;
-       ushort padded_line;
-       unsigned long width, height, bpp;
-       unsigned colors;
-       unsigned long compression;
-       bmp_color_table_entry_t cte;
-#ifdef CONFIG_VIDEO_BMP_GZIP
-       unsigned char *dst = NULL;
-       ulong len;
-#endif
-
-       WATCHDOG_RESET ();
-
-       if (!((bmp->header.signature[0] == 'B') &&
-             (bmp->header.signature[1] == 'M'))) {
-
-#ifdef CONFIG_VIDEO_BMP_GZIP
-               /*
-                * Could be a gzipped bmp image, try to decrompress...
-                */
-               len = CFG_VIDEO_LOGO_MAX_SIZE;
-               dst = malloc(CFG_VIDEO_LOGO_MAX_SIZE);
-               if (dst == NULL) {
-                       printf("Error: malloc in gunzip failed!\n");
-                       return(1);
-               }
-               if (gunzip(dst, CFG_VIDEO_LOGO_MAX_SIZE, (uchar *)bmp_image, &len) != 0) {
-                       printf ("Error: no valid bmp or bmp.gz image at %lx\n", bmp_image);
-                       free(dst);
-                       return 1;
-               }
-               if (len == CFG_VIDEO_LOGO_MAX_SIZE) {
-                       printf("Image could be truncated (increase CFG_VIDEO_LOGO_MAX_SIZE)!\n");
-               }
-
-               /*
-                * Set addr to decompressed image
-                */
-               bmp = (bmp_image_t *)dst;
-
-               if (!((bmp->header.signature[0] == 'B') &&
-                     (bmp->header.signature[1] == 'M'))) {
-                       printf ("Error: no valid bmp.gz image at %lx\n", bmp_image);
-                       return 1;
-               }
-#else
-               printf ("Error: no valid bmp image at %lx\n", bmp_image);
-               return 1;
-#endif /* CONFIG_VIDEO_BMP_GZIP */
-       }
-
-       width = le32_to_cpu (bmp->header.width);
-       height = le32_to_cpu (bmp->header.height);
-       bpp = le16_to_cpu (bmp->header.bit_count);
-       colors = le32_to_cpu (bmp->header.colors_used);
-       compression = le32_to_cpu (bmp->header.compression);
-
-       debug ("Display-bmp: %d x %d  with %d colors\n",
-              width, height, colors);
-
-       if (compression != BMP_BI_RGB) {
-               printf ("Error: compression type %ld not supported\n",
-                       compression);
-               return 1;
-       }
-
-       padded_line = (((width * bpp + 7) / 8) + 3) & ~0x3;
-
-       if ((x + width) > VIDEO_VISIBLE_COLS)
-               width = VIDEO_VISIBLE_COLS - x;
-       if ((y + height) > VIDEO_VISIBLE_ROWS)
-               height = VIDEO_VISIBLE_ROWS - y;
-
-       bmap = (uchar *) bmp + le32_to_cpu (bmp->header.data_offset);
-       fb = (uchar *) (video_fb_address +
-                       ((y + height - 1) * VIDEO_COLS * VIDEO_PIXEL_SIZE) +
-                       x * VIDEO_PIXEL_SIZE);
-
-       /* We handle only 8bpp or 24 bpp bitmap */
-       switch (le16_to_cpu (bmp->header.bit_count)) {
-       case 8:
-               padded_line -= width;
-               if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) {
-                       /* Copy colormap                                             */
-                       for (xcount = 0; xcount < colors; ++xcount) {
-                               cte = bmp->color_table[xcount];
-                               video_set_lut (xcount, cte.red, cte.green, cte.blue);
-                       }
-               }
-               ycount = height;
-               switch (VIDEO_DATA_FORMAT) {
-               case GDF__8BIT_INDEX:
-                       while (ycount--) {
-                               WATCHDOG_RESET ();
-                               xcount = width;
-                               while (xcount--) {
-                                       *fb++ = *bmap++;
-                               }
-                               bmap += padded_line;
-                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
-                       }
-                       break;
-               case GDF__8BIT_332RGB:
-                       while (ycount--) {
-                               WATCHDOG_RESET ();
-                               xcount = width;
-                               while (xcount--) {
-                                       cte = bmp->color_table[*bmap++];
-                                       FILL_8BIT_332RGB (cte.red, cte.green, cte.blue);
-                               }
-                               bmap += padded_line;
-                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
-                       }
-                       break;
-               case GDF_15BIT_555RGB:
-                       while (ycount--) {
-                               WATCHDOG_RESET ();
-                               xcount = width;
-                               while (xcount--) {
-                                       cte = bmp->color_table[*bmap++];
-                                       FILL_15BIT_555RGB (cte.red, cte.green, cte.blue);
-                               }
-                               bmap += padded_line;
-                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
-                       }
-                       break;
-               case GDF_16BIT_565RGB:
-                       while (ycount--) {
-                               WATCHDOG_RESET ();
-                               xcount = width;
-                               while (xcount--) {
-                                       cte = bmp->color_table[*bmap++];
-                                       FILL_16BIT_565RGB (cte.red, cte.green, cte.blue);
-                               }
-                               bmap += padded_line;
-                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
-                       }
-                       break;
-               case GDF_32BIT_X888RGB:
-                       while (ycount--) {
-                               WATCHDOG_RESET ();
-                               xcount = width;
-                               while (xcount--) {
-                                       cte = bmp->color_table[*bmap++];
-                                       FILL_32BIT_X888RGB (cte.red, cte.green, cte.blue);
-                               }
-                               bmap += padded_line;
-                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
-                       }
-                       break;
-               case GDF_24BIT_888RGB:
-                       while (ycount--) {
-                               WATCHDOG_RESET ();
-                               xcount = width;
-                               while (xcount--) {
-                                       cte = bmp->color_table[*bmap++];
-                                       FILL_24BIT_888RGB (cte.red, cte.green, cte.blue);
-                               }
-                               bmap += padded_line;
-                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
-                       }
-                       break;
-               }
-               break;
-       case 24:
-               padded_line -= 3 * width;
-               ycount = height;
-               switch (VIDEO_DATA_FORMAT) {
-               case GDF__8BIT_332RGB:
-                       while (ycount--) {
-                               WATCHDOG_RESET ();
-                               xcount = width;
-                               while (xcount--) {
-                                       FILL_8BIT_332RGB (bmap[2], bmap[1], bmap[0]);
-                                       bmap += 3;
-                               }
-                               bmap += padded_line;
-                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
-                       }
-                       break;
-               case GDF_15BIT_555RGB:
-                       while (ycount--) {
-                               WATCHDOG_RESET ();
-                               xcount = width;
-                               while (xcount--) {
-                                       FILL_15BIT_555RGB (bmap[2], bmap[1], bmap[0]);
-                                       bmap += 3;
-                               }
-                               bmap += padded_line;
-                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
-                       }
-                       break;
-               case GDF_16BIT_565RGB:
-                       while (ycount--) {
-                               WATCHDOG_RESET ();
-                               xcount = width;
-                               while (xcount--) {
-                                       FILL_16BIT_565RGB (bmap[2], bmap[1], bmap[0]);
-                                       bmap += 3;
-                               }
-                               bmap += padded_line;
-                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
-                       }
-                       break;
-               case GDF_32BIT_X888RGB:
-                       while (ycount--) {
-                               WATCHDOG_RESET ();
-                               xcount = width;
-                               while (xcount--) {
-                                       FILL_32BIT_X888RGB (bmap[2], bmap[1], bmap[0]);
-                                       bmap += 3;
-                               }
-                               bmap += padded_line;
-                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
-                       }
-                       break;
-               case GDF_24BIT_888RGB:
-                       while (ycount--) {
-                               WATCHDOG_RESET ();
-                               xcount = width;
-                               while (xcount--) {
-                                       FILL_24BIT_888RGB (bmap[2], bmap[1], bmap[0]);
-                                       bmap += 3;
-                               }
-                               bmap += padded_line;
-                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
-                       }
-                       break;
-               default:
-                       printf ("Error: 24 bits/pixel bitmap incompatible with current video mode\n");
-                       break;
-               }
-               break;
-       default:
-               printf ("Error: %d bit/pixel bitmaps not supported by U-Boot\n",
-                       le16_to_cpu (bmp->header.bit_count));
-               break;
-       }
-
-#ifdef CONFIG_VIDEO_BMP_GZIP
-       if (dst) {
-               free(dst);
-       }
-#endif
-
-       return (0);
-}
-#endif
-
-/*****************************************************************************/
-
-#ifdef CONFIG_VIDEO_LOGO
-void logo_plot (void *screen, int width, int x, int y)
-{
-
-       int xcount, i;
-       int skip   = (width - VIDEO_LOGO_WIDTH) * VIDEO_PIXEL_SIZE;
-       int ycount = VIDEO_LOGO_HEIGHT;
-       unsigned char r, g, b, *logo_red, *logo_blue, *logo_green;
-       unsigned char *source;
-       unsigned char *dest = (unsigned char *)screen + ((y * width * VIDEO_PIXEL_SIZE) + x);
-
-#ifdef CONFIG_VIDEO_BMP_LOGO
-       source = bmp_logo_bitmap;
-
-       /* Allocate temporary space for computing colormap                       */
-       logo_red = malloc (BMP_LOGO_COLORS);
-       logo_green = malloc (BMP_LOGO_COLORS);
-       logo_blue = malloc (BMP_LOGO_COLORS);
-       /* Compute color map                                                     */
-       for (i = 0; i < VIDEO_LOGO_COLORS; i++) {
-               logo_red[i] = (bmp_logo_palette[i] & 0x0f00) >> 4;
-               logo_green[i] = (bmp_logo_palette[i] & 0x00f0);
-               logo_blue[i] = (bmp_logo_palette[i] & 0x000f) << 4;
-       }
-#else
-       source = linux_logo;
-       logo_red = linux_logo_red;
-       logo_green = linux_logo_green;
-       logo_blue = linux_logo_blue;
-#endif
-
-       if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) {
-               for (i = 0; i < VIDEO_LOGO_COLORS; i++) {
-                       video_set_lut (i + VIDEO_LOGO_LUT_OFFSET,
-                                      logo_red[i], logo_green[i], logo_blue[i]);
-               }
-       }
-
-       while (ycount--) {
-               xcount = VIDEO_LOGO_WIDTH;
-               while (xcount--) {
-                       r = logo_red[*source - VIDEO_LOGO_LUT_OFFSET];
-                       g = logo_green[*source - VIDEO_LOGO_LUT_OFFSET];
-                       b = logo_blue[*source - VIDEO_LOGO_LUT_OFFSET];
-
-                       switch (VIDEO_DATA_FORMAT) {
-                       case GDF__8BIT_INDEX:
-                               *dest = *source;
-                               break;
-                       case GDF__8BIT_332RGB:
-                               *dest = ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
-                               break;
-                       case GDF_15BIT_555RGB:
-                               *(unsigned short *) dest =
-                                       SWAP16 ((unsigned short) (((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3)));
-                               break;
-                       case GDF_16BIT_565RGB:
-                               *(unsigned short *) dest =
-                                       SWAP16 ((unsigned short) (((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)));
-                               break;
-                       case GDF_32BIT_X888RGB:
-                               *(unsigned long *) dest =
-                                       SWAP32 ((unsigned long) ((r << 16) | (g << 8) | b));
-                               break;
-                       case GDF_24BIT_888RGB:
-#ifdef VIDEO_FB_LITTLE_ENDIAN
-                               dest[0] = b;
-                               dest[1] = g;
-                               dest[2] = r;
-#else
-                               dest[0] = r;
-                               dest[1] = g;
-                               dest[2] = b;
-#endif
-                               break;
-                       }
-                       source++;
-                       dest += VIDEO_PIXEL_SIZE;
-               }
-               dest += skip;
-       }
-#ifdef CONFIG_VIDEO_BMP_LOGO
-       free (logo_red);
-       free (logo_green);
-       free (logo_blue);
-#endif
-}
-
-/*****************************************************************************/
-
-static void *video_logo (void)
-{
-       char info[128];
-       extern char version_string;
-
-#ifdef CONFIG_SPLASH_SCREEN
-       char *s;
-       ulong addr;
-
-       if ((s = getenv ("splashimage")) != NULL) {
-               addr = simple_strtoul (s, NULL, 16);
-
-               if (video_display_bitmap (addr, 0, 0) == 0) {
-                       return ((void *) (video_fb_address));
-               }
-       }
-#endif /* CONFIG_SPLASH_SCREEN */
-
-       logo_plot (video_fb_address, VIDEO_COLS, 0, 0);
-
-       sprintf (info, " %s", &version_string);
-       video_drawstring (VIDEO_INFO_X, VIDEO_INFO_Y, (uchar *)info);
-
-#ifdef CONFIG_CONSOLE_EXTRA_INFO
-       {
-               int i, n = ((VIDEO_LOGO_HEIGHT - VIDEO_FONT_HEIGHT) / VIDEO_FONT_HEIGHT);
-
-               for (i = 1; i < n; i++) {
-                       video_get_info_str (i, info);
-                       if (*info)
-                               video_drawstring (VIDEO_INFO_X,
-                                                 VIDEO_INFO_Y + i * VIDEO_FONT_HEIGHT,
-                                                 (uchar *)info);
-               }
-       }
-#endif
-
-       return (video_fb_address + VIDEO_LOGO_HEIGHT * VIDEO_LINE_LEN);
-}
-#endif
-
-
-/*****************************************************************************/
-
-static int video_init (void)
-{
-       unsigned char color8;
-
-       if ((pGD = video_hw_init ()) == NULL)
-               return -1;
-
-       video_fb_address = (void *) VIDEO_FB_ADRS;
-#ifdef CONFIG_VIDEO_HW_CURSOR
-       video_init_hw_cursor (VIDEO_FONT_WIDTH, VIDEO_FONT_HEIGHT);
-#endif
-
-       /* Init drawing pats */
-       switch (VIDEO_DATA_FORMAT) {
-       case GDF__8BIT_INDEX:
-               video_set_lut (0x01, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL);
-               video_set_lut (0x00, CONSOLE_BG_COL, CONSOLE_BG_COL, CONSOLE_BG_COL);
-               fgx = 0x01010101;
-               bgx = 0x00000000;
-               break;
-       case GDF__8BIT_332RGB:
-               color8 = ((CONSOLE_FG_COL & 0xe0) |
-                         ((CONSOLE_FG_COL >> 3) & 0x1c) | CONSOLE_FG_COL >> 6);
-               fgx = (color8 << 24) | (color8 << 16) | (color8 << 8) | color8;
-               color8 = ((CONSOLE_BG_COL & 0xe0) |
-                         ((CONSOLE_BG_COL >> 3) & 0x1c) | CONSOLE_BG_COL >> 6);
-               bgx = (color8 << 24) | (color8 << 16) | (color8 << 8) | color8;
-               break;
-       case GDF_15BIT_555RGB:
-               fgx = (((CONSOLE_FG_COL >> 3) << 26) |
-                      ((CONSOLE_FG_COL >> 3) << 21) | ((CONSOLE_FG_COL >> 3) << 16) |
-                      ((CONSOLE_FG_COL >> 3) << 10) | ((CONSOLE_FG_COL >> 3) << 5) |
-                      (CONSOLE_FG_COL >> 3));
-               bgx = (((CONSOLE_BG_COL >> 3) << 26) |
-                      ((CONSOLE_BG_COL >> 3) << 21) | ((CONSOLE_BG_COL >> 3) << 16) |
-                      ((CONSOLE_BG_COL >> 3) << 10) | ((CONSOLE_BG_COL >> 3) << 5) |
-                      (CONSOLE_BG_COL >> 3));
-               break;
-       case GDF_16BIT_565RGB:
-               fgx = (((CONSOLE_FG_COL >> 3) << 27) |
-                      ((CONSOLE_FG_COL >> 2) << 21) | ((CONSOLE_FG_COL >> 3) << 16) |
-                      ((CONSOLE_FG_COL >> 3) << 11) | ((CONSOLE_FG_COL >> 2) << 5) |
-                      (CONSOLE_FG_COL >> 3));
-               bgx = (((CONSOLE_BG_COL >> 3) << 27) |
-                      ((CONSOLE_BG_COL >> 2) << 21) | ((CONSOLE_BG_COL >> 3) << 16) |
-                      ((CONSOLE_BG_COL >> 3) << 11) | ((CONSOLE_BG_COL >> 2) << 5) |
-                      (CONSOLE_BG_COL >> 3));
-               break;
-       case GDF_32BIT_X888RGB:
-               fgx = (CONSOLE_FG_COL << 16) | (CONSOLE_FG_COL << 8) | CONSOLE_FG_COL;
-               bgx = (CONSOLE_BG_COL << 16) | (CONSOLE_BG_COL << 8) | CONSOLE_BG_COL;
-               break;
-       case GDF_24BIT_888RGB:
-               fgx = (CONSOLE_FG_COL << 24) | (CONSOLE_FG_COL << 16) |
-                       (CONSOLE_FG_COL << 8) | CONSOLE_FG_COL;
-               bgx = (CONSOLE_BG_COL << 24) | (CONSOLE_BG_COL << 16) |
-                       (CONSOLE_BG_COL << 8) | CONSOLE_BG_COL;
-               break;
-       }
-       eorx = fgx ^ bgx;
-
-#ifdef CONFIG_VIDEO_LOGO
-       /* Plot the logo and get start point of console */
-       PRINTD ("Video: Drawing the logo ...\n");
-       video_console_address = video_logo ();
-#else
-       video_console_address = video_fb_address;
-#endif
-
-       /* Initialize the console */
-       console_col = 0;
-       console_row = 0;
-
-       return 0;
-}
-
-
-/*****************************************************************************/
-
-int drv_video_init (void)
-{
-       int skip_dev_init;
-       device_t console_dev;
-
-       skip_dev_init = 0;
-
-       /* Init video chip - returns with framebuffer cleared */
-       if (video_init () == -1)
-               skip_dev_init = 1;
-
-#ifdef CONFIG_VGA_AS_SINGLE_DEVICE
-       /* Devices VGA and Keyboard will be assigned seperately */
-       /* Init vga device */
-       if (!skip_dev_init) {
-               memset (&console_dev, 0, sizeof (console_dev));
-               strcpy (console_dev.name, "vga");
-               console_dev.ext = DEV_EXT_VIDEO;        /* Video extensions */
-               console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM;
-               console_dev.putc = video_putc;  /* 'putc' function */
-               console_dev.puts = video_puts;  /* 'puts' function */
-               console_dev.tstc = NULL;        /* 'tstc' function */
-               console_dev.getc = NULL;        /* 'getc' function */
-
-               if (device_register (&console_dev) == 0)
-                       return 1;
-       }
-#else
-       PRINTD ("KBD: Keyboard init ...\n");
-       if (VIDEO_KBD_INIT_FCT == -1)
-               skip_dev_init = 1;
-
-       /* Init console device */
-       if (!skip_dev_init) {
-               memset (&console_dev, 0, sizeof (console_dev));
-               strcpy (console_dev.name, "vga");
-               console_dev.ext = DEV_EXT_VIDEO;        /* Video extensions */
-               console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
-               console_dev.putc = video_putc;  /* 'putc' function */
-               console_dev.puts = video_puts;  /* 'puts' function */
-               console_dev.tstc = VIDEO_TSTC_FCT;      /* 'tstc' function */
-               console_dev.getc = VIDEO_GETC_FCT;      /* 'getc' function */
-
-               if (device_register (&console_dev) == 0)
-                       return 1;
-       }
-#endif /* CONFIG_VGA_AS_SINGLE_DEVICE */
-       /* No console dev available */
-       return 0;
-}
-#endif /* CONFIG_CFB_CONSOLE */
diff --git a/drivers/cfi_flash.c b/drivers/cfi_flash.c
deleted file mode 100644 (file)
index 5579a1e..0000000
+++ /dev/null
@@ -1,1528 +0,0 @@
-/*
- * (C) Copyright 2002-2004
- * Brad Kemp, Seranoa Networks, Brad.Kemp@seranoa.com
- *
- * Copyright (C) 2003 Arabella Software Ltd.
- * Yuli Barcohen <yuli@arabellasw.com>
- *
- * Copyright (C) 2004
- * Ed Okerson
- *
- * Copyright (C) 2006
- * Tolunay Orkun <listmember@orkun.us>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- */
-
-/* The DEBUG define must be before common to enable debugging */
-/* #define DEBUG       */
-
-#include <common.h>
-#include <asm/processor.h>
-#include <asm/io.h>
-#include <asm/byteorder.h>
-#include <environment.h>
-#ifdef CFG_FLASH_CFI_DRIVER
-
-/*
- * This file implements a Common Flash Interface (CFI) driver for U-Boot.
- * The width of the port and the width of the chips are determined at initialization.
- * These widths are used to calculate the address for access CFI data structures.
- *
- * References
- * JEDEC Standard JESD68 - Common Flash Interface (CFI)
- * JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes
- * Intel Application Note 646 Common Flash Interface (CFI) and Command Sets
- * Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet
- * AMD CFI Specification, Release 2.0 December 1, 2001
- * AMD/Spansion Application Note: Migration from Single-byte to Three-byte
- *   Device IDs, Publication Number 25538 Revision A, November 8, 2001
- *
- * define CFG_WRITE_SWAPPED_DATA, if you have to swap the Bytes between
- * reading and writing ... (yes there is such a Hardware).
- */
-
-#ifndef CFG_FLASH_BANKS_LIST
-#define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE }
-#endif
-
-#define FLASH_CMD_CFI                  0x98
-#define FLASH_CMD_READ_ID              0x90
-#define FLASH_CMD_RESET                        0xff
-#define FLASH_CMD_BLOCK_ERASE          0x20
-#define FLASH_CMD_ERASE_CONFIRM                0xD0
-#define FLASH_CMD_WRITE                        0x40
-#define FLASH_CMD_PROTECT              0x60
-#define FLASH_CMD_PROTECT_SET          0x01
-#define FLASH_CMD_PROTECT_CLEAR                0xD0
-#define FLASH_CMD_CLEAR_STATUS         0x50
-#define FLASH_CMD_WRITE_TO_BUFFER      0xE8
-#define FLASH_CMD_WRITE_BUFFER_CONFIRM 0xD0
-
-#define FLASH_STATUS_DONE              0x80
-#define FLASH_STATUS_ESS               0x40
-#define FLASH_STATUS_ECLBS             0x20
-#define FLASH_STATUS_PSLBS             0x10
-#define FLASH_STATUS_VPENS             0x08
-#define FLASH_STATUS_PSS               0x04
-#define FLASH_STATUS_DPS               0x02
-#define FLASH_STATUS_R                 0x01
-#define FLASH_STATUS_PROTECT           0x01
-
-#define AMD_CMD_RESET                  0xF0
-#define AMD_CMD_WRITE                  0xA0
-#define AMD_CMD_ERASE_START            0x80
-#define AMD_CMD_ERASE_SECTOR           0x30
-#define AMD_CMD_UNLOCK_START           0xAA
-#define AMD_CMD_UNLOCK_ACK             0x55
-#define AMD_CMD_WRITE_TO_BUFFER                0x25
-#define AMD_CMD_WRITE_BUFFER_CONFIRM   0x29
-
-#define AMD_STATUS_TOGGLE              0x40
-#define AMD_STATUS_ERROR               0x20
-
-#define AMD_ADDR_ERASE_START   ((info->portwidth == FLASH_CFI_8BIT) ? 0xAAA : 0x555)
-#define AMD_ADDR_START         ((info->portwidth == FLASH_CFI_8BIT) ? 0xAAA : 0x555)
-#define AMD_ADDR_ACK           ((info->portwidth == FLASH_CFI_8BIT) ? 0x555 : 0x2AA)
-
-#define FLASH_OFFSET_MANUFACTURER_ID   0x00
-#define FLASH_OFFSET_DEVICE_ID         0x01
-#define FLASH_OFFSET_DEVICE_ID2                0x0E
-#define FLASH_OFFSET_DEVICE_ID3                0x0F
-#define FLASH_OFFSET_CFI               0x55
-#define FLASH_OFFSET_CFI_ALT           0x555
-#define FLASH_OFFSET_CFI_RESP          0x10
-#define FLASH_OFFSET_PRIMARY_VENDOR    0x13
-#define FLASH_OFFSET_EXT_QUERY_T_P_ADDR        0x15    /* extended query table primary addr */
-#define FLASH_OFFSET_WTOUT             0x1F
-#define FLASH_OFFSET_WBTOUT            0x20
-#define FLASH_OFFSET_ETOUT             0x21
-#define FLASH_OFFSET_CETOUT            0x22
-#define FLASH_OFFSET_WMAX_TOUT         0x23
-#define FLASH_OFFSET_WBMAX_TOUT                0x24
-#define FLASH_OFFSET_EMAX_TOUT         0x25
-#define FLASH_OFFSET_CEMAX_TOUT                0x26
-#define FLASH_OFFSET_SIZE              0x27
-#define FLASH_OFFSET_INTERFACE         0x28
-#define FLASH_OFFSET_BUFFER_SIZE       0x2A
-#define FLASH_OFFSET_NUM_ERASE_REGIONS 0x2C
-#define FLASH_OFFSET_ERASE_REGIONS     0x2D
-#define FLASH_OFFSET_PROTECT           0x02
-#define FLASH_OFFSET_USER_PROTECTION   0x85
-#define FLASH_OFFSET_INTEL_PROTECTION  0x81
-
-#define CFI_CMDSET_NONE                        0
-#define CFI_CMDSET_INTEL_EXTENDED      1
-#define CFI_CMDSET_AMD_STANDARD                2
-#define CFI_CMDSET_INTEL_STANDARD      3
-#define CFI_CMDSET_AMD_EXTENDED                4
-#define CFI_CMDSET_MITSU_STANDARD      256
-#define CFI_CMDSET_MITSU_EXTENDED      257
-#define CFI_CMDSET_SST                 258
-
-#ifdef CFG_FLASH_CFI_AMD_RESET /* needed for STM_ID_29W320DB on UC100 */
-# undef  FLASH_CMD_RESET
-# define FLASH_CMD_RESET       AMD_CMD_RESET /* use AMD-Reset instead */
-#endif
-
-typedef union {
-       unsigned char c;
-       unsigned short w;
-       unsigned long l;
-       unsigned long long ll;
-} cfiword_t;
-
-typedef union {
-       volatile unsigned char *cp;
-       volatile unsigned short *wp;
-       volatile unsigned long *lp;
-       volatile unsigned long long *llp;
-} cfiptr_t;
-
-#define NUM_ERASE_REGIONS      4 /* max. number of erase regions */
-
-static uint flash_offset_cfi[2]={FLASH_OFFSET_CFI,FLASH_OFFSET_CFI_ALT};
-
-/* use CFG_MAX_FLASH_BANKS_DETECT if defined */
-#ifdef CFG_MAX_FLASH_BANKS_DETECT
-static ulong bank_base[CFG_MAX_FLASH_BANKS_DETECT] = CFG_FLASH_BANKS_LIST;
-flash_info_t flash_info[CFG_MAX_FLASH_BANKS_DETECT];   /* FLASH chips info */
-#else
-static ulong bank_base[CFG_MAX_FLASH_BANKS] = CFG_FLASH_BANKS_LIST;
-flash_info_t flash_info[CFG_MAX_FLASH_BANKS];          /* FLASH chips info */
-#endif
-
-/*
- * Check if chip width is defined. If not, start detecting with 8bit.
- */
-#ifndef CFG_FLASH_CFI_WIDTH
-#define CFG_FLASH_CFI_WIDTH    FLASH_CFI_8BIT
-#endif
-
-
-/*-----------------------------------------------------------------------
- * Functions
- */
-
-typedef unsigned long flash_sect_t;
-
-static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c);
-static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf);
-static void flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
-static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect);
-static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
-static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
-static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
-static void flash_read_jedec_ids (flash_info_t * info);
-static int flash_detect_cfi (flash_info_t * info);
-static int flash_write_cfiword (flash_info_t * info, ulong dest, cfiword_t cword);
-static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
-                                   ulong tout, char *prompt);
-ulong flash_get_size (ulong base, int banknum);
-#if defined(CFG_ENV_IS_IN_FLASH) || defined(CFG_ENV_ADDR_REDUND) || (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
-static flash_info_t *flash_get_info(ulong base);
-#endif
-#ifdef CFG_FLASH_USE_BUFFER_WRITE
-static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp, int len);
-#endif
-
-/*-----------------------------------------------------------------------
- * create an address based on the offset and the port width
- */
-inline uchar *flash_make_addr (flash_info_t * info, flash_sect_t sect, uint offset)
-{
-       return ((uchar *) (info->start[sect] + (offset * info->portwidth)));
-}
-
-#ifdef DEBUG
-/*-----------------------------------------------------------------------
- * Debug support
- */
-void print_longlong (char *str, unsigned long long data)
-{
-       int i;
-       char *cp;
-
-       cp = (unsigned char *) &data;
-       for (i = 0; i < 8; i++)
-               sprintf (&str[i * 2], "%2.2x", *cp++);
-}
-static void flash_printqry (flash_info_t * info, flash_sect_t sect)
-{
-       cfiptr_t cptr;
-       int x, y;
-
-       for (x = 0; x < 0x40; x += 16U / info->portwidth) {
-               cptr.cp =
-                       flash_make_addr (info, sect,
-                                        x + FLASH_OFFSET_CFI_RESP);
-               debug ("%p : ", cptr.cp);
-               for (y = 0; y < 16; y++) {
-                       debug ("%2.2x ", cptr.cp[y]);
-               }
-               debug (" ");
-               for (y = 0; y < 16; y++) {
-                       if (cptr.cp[y] >= 0x20 && cptr.cp[y] <= 0x7e) {
-                               debug ("%c", cptr.cp[y]);
-                       } else {
-                               debug (".");
-                       }
-               }
-               debug ("\n");
-       }
-}
-#endif
-
-
-/*-----------------------------------------------------------------------
- * read a character at a port width address
- */
-inline uchar flash_read_uchar (flash_info_t * info, uint offset)
-{
-       uchar *cp;
-
-       cp = flash_make_addr (info, 0, offset);
-#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
-       return (cp[0]);
-#else
-       return (cp[info->portwidth - 1]);
-#endif
-}
-
-/*-----------------------------------------------------------------------
- * read a short word by swapping for ppc format.
- */
-ushort flash_read_ushort (flash_info_t * info, flash_sect_t sect, uint offset)
-{
-       uchar *addr;
-       ushort retval;
-
-#ifdef DEBUG
-       int x;
-#endif
-       addr = flash_make_addr (info, sect, offset);
-
-#ifdef DEBUG
-       debug ("ushort addr is at %p info->portwidth = %d\n", addr,
-              info->portwidth);
-       for (x = 0; x < 2 * info->portwidth; x++) {
-               debug ("addr[%x] = 0x%x\n", x, addr[x]);
-       }
-#endif
-#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
-       retval = ((addr[(info->portwidth)] << 8) | addr[0]);
-#else
-       retval = ((addr[(2 * info->portwidth) - 1] << 8) |
-                 addr[info->portwidth - 1]);
-#endif
-
-       debug ("retval = 0x%x\n", retval);
-       return retval;
-}
-
-/*-----------------------------------------------------------------------
- * read a long word by picking the least significant byte of each maximum
- * port size word. Swap for ppc format.
- */
-ulong flash_read_long (flash_info_t * info, flash_sect_t sect, uint offset)
-{
-       uchar *addr;
-       ulong retval;
-
-#ifdef DEBUG
-       int x;
-#endif
-       addr = flash_make_addr (info, sect, offset);
-
-#ifdef DEBUG
-       debug ("long addr is at %p info->portwidth = %d\n", addr,
-              info->portwidth);
-       for (x = 0; x < 4 * info->portwidth; x++) {
-               debug ("addr[%x] = 0x%x\n", x, addr[x]);
-       }
-#endif
-#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
-       retval = (addr[0] << 16) | (addr[(info->portwidth)] << 24) |
-               (addr[(2 * info->portwidth)]) | (addr[(3 * info->portwidth)] << 8);
-#else
-       retval = (addr[(2 * info->portwidth) - 1] << 24) |
-               (addr[(info->portwidth) - 1] << 16) |
-               (addr[(4 * info->portwidth) - 1] << 8) |
-               addr[(3 * info->portwidth) - 1];
-#endif
-       return retval;
-}
-
-
-/*-----------------------------------------------------------------------
- */
-unsigned long flash_init (void)
-{
-       unsigned long size = 0;
-       int i;
-
-#ifdef CFG_FLASH_PROTECTION
-       char *s = getenv("unlock");
-#endif
-
-       /* Init: no FLASHes known */
-       for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
-               flash_info[i].flash_id = FLASH_UNKNOWN;
-               size += flash_info[i].size = flash_get_size (bank_base[i], i);
-               if (flash_info[i].flash_id == FLASH_UNKNOWN) {
-#ifndef CFG_FLASH_QUIET_TEST
-                       printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
-                               i+1, flash_info[i].size, flash_info[i].size << 20);
-#endif /* CFG_FLASH_QUIET_TEST */
-               }
-#ifdef CFG_FLASH_PROTECTION
-               else if ((s != NULL) && (strcmp(s, "yes") == 0)) {
-                       /*
-                        * Only the U-Boot image and it's environment is protected,
-                        * all other sectors are unprotected (unlocked) if flash
-                        * hardware protection is used (CFG_FLASH_PROTECTION) and
-                        * the environment variable "unlock" is set to "yes".
-                        */
-                       if (flash_info[i].legacy_unlock) {
-                               int k;
-
-                               /*
-                                * Disable legacy_unlock temporarily, since
-                                * flash_real_protect would relock all other sectors
-                                * again otherwise.
-                                */
-                               flash_info[i].legacy_unlock = 0;
-
-                               /*
-                                * Legacy unlocking (e.g. Intel J3) -> unlock only one
-                                * sector. This will unlock all sectors.
-                                */
-                               flash_real_protect (&flash_info[i], 0, 0);
-
-                               flash_info[i].legacy_unlock = 1;
-
-                               /*
-                                * Manually mark other sectors as unlocked (unprotected)
-                                */
-                               for (k = 1; k < flash_info[i].sector_count; k++)
-                                       flash_info[i].protect[k] = 0;
-                       } else {
-                               /*
-                                * No legancy unlocking -> unlock all sectors
-                                */
-                               flash_protect (FLAG_PROTECT_CLEAR,
-                                              flash_info[i].start[0],
-                                              flash_info[i].start[0] + flash_info[i].size - 1,
-                                              &flash_info[i]);
-                       }
-               }
-#endif /* CFG_FLASH_PROTECTION */
-       }
-
-       /* Monitor protection ON by default */
-#if (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
-       flash_protect (FLAG_PROTECT_SET,
-                      CFG_MONITOR_BASE,
-                      CFG_MONITOR_BASE + monitor_flash_len  - 1,
-                      flash_get_info(CFG_MONITOR_BASE));
-#endif
-
-       /* Environment protection ON by default */
-#ifdef CFG_ENV_IS_IN_FLASH
-       flash_protect (FLAG_PROTECT_SET,
-                      CFG_ENV_ADDR,
-                      CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
-                      flash_get_info(CFG_ENV_ADDR));
-#endif
-
-       /* Redundant environment protection ON by default */
-#ifdef CFG_ENV_ADDR_REDUND
-       flash_protect (FLAG_PROTECT_SET,
-                      CFG_ENV_ADDR_REDUND,
-                      CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1,
-                      flash_get_info(CFG_ENV_ADDR_REDUND));
-#endif
-       return (size);
-}
-
-/*-----------------------------------------------------------------------
- */
-#if defined(CFG_ENV_IS_IN_FLASH) || defined(CFG_ENV_ADDR_REDUND) || (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
-static flash_info_t *flash_get_info(ulong base)
-{
-       int i;
-       flash_info_t * info = 0;
-
-       for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
-               info = & flash_info[i];
-               if (info->size && info->start[0] <= base &&
-                   base <= info->start[0] + info->size - 1)
-                       break;
-       }
-
-       return i == CFG_MAX_FLASH_BANKS ? 0 : info;
-}
-#endif
-
-/*-----------------------------------------------------------------------
- */
-int flash_erase (flash_info_t * info, int s_first, int s_last)
-{
-       int rcode = 0;
-       int prot;
-       flash_sect_t sect;
-
-       if (info->flash_id != FLASH_MAN_CFI) {
-               puts ("Can't erase unknown flash type - aborted\n");
-               return 1;
-       }
-       if ((s_first < 0) || (s_first > s_last)) {
-               puts ("- no sectors to erase\n");
-               return 1;
-       }
-
-       prot = 0;
-       for (sect = s_first; sect <= s_last; ++sect) {
-               if (info->protect[sect]) {
-                       prot++;
-               }
-       }
-       if (prot) {
-               printf ("- Warning: %d protected sectors will not be erased!\n", prot);
-       } else {
-               putc ('\n');
-       }
-
-
-       for (sect = s_first; sect <= s_last; sect++) {
-               if (info->protect[sect] == 0) { /* not protected */
-                       switch (info->vendor) {
-                       case CFI_CMDSET_INTEL_STANDARD:
-                       case CFI_CMDSET_INTEL_EXTENDED:
-                               flash_write_cmd (info, sect, 0, FLASH_CMD_CLEAR_STATUS);
-                               flash_write_cmd (info, sect, 0, FLASH_CMD_BLOCK_ERASE);
-                               flash_write_cmd (info, sect, 0, FLASH_CMD_ERASE_CONFIRM);
-                               break;
-                       case CFI_CMDSET_AMD_STANDARD:
-                       case CFI_CMDSET_AMD_EXTENDED:
-                               flash_unlock_seq (info, sect);
-                               flash_write_cmd (info, sect, AMD_ADDR_ERASE_START,
-                                                       AMD_CMD_ERASE_START);
-                               flash_unlock_seq (info, sect);
-                               flash_write_cmd (info, sect, 0, AMD_CMD_ERASE_SECTOR);
-                               break;
-                       default:
-                               debug ("Unkown flash vendor %d\n",
-                                      info->vendor);
-                               break;
-                       }
-
-                       if (flash_full_status_check
-                           (info, sect, info->erase_blk_tout, "erase")) {
-                               rcode = 1;
-                       } else
-                               putc ('.');
-               }
-       }
-       puts (" done\n");
-       return rcode;
-}
-
-/*-----------------------------------------------------------------------
- */
-void flash_print_info (flash_info_t * info)
-{
-       int i;
-
-       if (info->flash_id != FLASH_MAN_CFI) {
-               puts ("missing or unknown FLASH type\n");
-               return;
-       }
-
-       printf ("CFI conformant FLASH (%d x %d)",
-               (info->portwidth << 3), (info->chipwidth << 3));
-       printf ("  Size: %ld MB in %d Sectors\n",
-               info->size >> 20, info->sector_count);
-       printf ("  ");
-       switch (info->vendor) {
-               case CFI_CMDSET_INTEL_STANDARD:
-                       printf ("Intel Standard");
-                       break;
-               case CFI_CMDSET_INTEL_EXTENDED:
-                       printf ("Intel Extended");
-                       break;
-               case CFI_CMDSET_AMD_STANDARD:
-                       printf ("AMD Standard");
-                       break;
-               case CFI_CMDSET_AMD_EXTENDED:
-                       printf ("AMD Extended");
-                       break;
-               default:
-                       printf ("Unknown (%d)", info->vendor);
-                       break;
-       }
-       printf (" command set, Manufacturer ID: 0x%02X, Device ID: 0x%02X",
-               info->manufacturer_id, info->device_id);
-       if (info->device_id == 0x7E) {
-               printf("%04X", info->device_id2);
-       }
-       printf ("\n  Erase timeout: %ld ms, write timeout: %ld ms\n",
-               info->erase_blk_tout,
-               info->write_tout);
-       if (info->buffer_size > 1) {
-               printf ("  Buffer write timeout: %ld ms, buffer size: %d bytes\n",
-               info->buffer_write_tout,
-               info->buffer_size);
-       }
-
-       puts ("\n  Sector Start Addresses:");
-       for (i = 0; i < info->sector_count; ++i) {
-               if ((i % 5) == 0)
-                       printf ("\n");
-#ifdef CFG_FLASH_EMPTY_INFO
-               int k;
-               int size;
-               int erased;
-               volatile unsigned long *flash;
-
-               /*
-                * Check if whole sector is erased
-                */
-               if (i != (info->sector_count - 1))
-                       size = info->start[i + 1] - info->start[i];
-               else
-                       size = info->start[0] + info->size - info->start[i];
-               erased = 1;
-               flash = (volatile unsigned long *) info->start[i];
-               size = size >> 2;       /* divide by 4 for longword access */
-               for (k = 0; k < size; k++) {
-                       if (*flash++ != 0xffffffff) {
-                               erased = 0;
-                               break;
-                       }
-               }
-
-               /* print empty and read-only info */
-               printf ("  %08lX %c %s ",
-                       info->start[i],
-                       erased ? 'E' : ' ',
-                       info->protect[i] ? "RO" : "  ");
-#else  /* ! CFG_FLASH_EMPTY_INFO */
-               printf ("  %08lX   %s ",
-                       info->start[i],
-                       info->protect[i] ? "RO" : "  ");
-#endif
-       }
-       putc ('\n');
-       return;
-}
-
-/*-----------------------------------------------------------------------
- * Copy memory to flash, returns:
- * 0 - OK
- * 1 - write timeout
- * 2 - Flash not erased
- */
-int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
-{
-       ulong wp;
-       ulong cp;
-       int aln;
-       cfiword_t cword;
-       int i, rc;
-
-#ifdef CFG_FLASH_USE_BUFFER_WRITE
-       int buffered_size;
-#endif
-       /* get lower aligned address */
-       /* get lower aligned address */
-       wp = (addr & ~(info->portwidth - 1));
-
-       /* handle unaligned start */
-       if ((aln = addr - wp) != 0) {
-               cword.l = 0;
-               cp = wp;
-               for (i = 0; i < aln; ++i, ++cp)
-                       flash_add_byte (info, &cword, (*(uchar *) cp));
-
-               for (; (i < info->portwidth) && (cnt > 0); i++) {
-                       flash_add_byte (info, &cword, *src++);
-                       cnt--;
-                       cp++;
-               }
-               for (; (cnt == 0) && (i < info->portwidth); ++i, ++cp)
-                       flash_add_byte (info, &cword, (*(uchar *) cp));
-               if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
-                       return rc;
-               wp = cp;
-       }
-
-       /* handle the aligned part */
-#ifdef CFG_FLASH_USE_BUFFER_WRITE
-       buffered_size = (info->portwidth / info->chipwidth);
-       buffered_size *= info->buffer_size;
-       while (cnt >= info->portwidth) {
-               /* prohibit buffer write when buffer_size is 1 */
-               if (info->buffer_size == 1) {
-                       cword.l = 0;
-                       for (i = 0; i < info->portwidth; i++)
-                               flash_add_byte (info, &cword, *src++);
-                       if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
-                               return rc;
-                       wp += info->portwidth;
-                       cnt -= info->portwidth;
-                       continue;
-               }
-
-               /* write buffer until next buffered_size aligned boundary */
-               i = buffered_size - (wp % buffered_size);
-               if (i > cnt)
-                       i = cnt;
-               if ((rc = flash_write_cfibuffer (info, wp, src, i)) != ERR_OK)
-                       return rc;
-               i -= i & (info->portwidth - 1);
-               wp += i;
-               src += i;
-               cnt -= i;
-       }
-#else
-       while (cnt >= info->portwidth) {
-               cword.l = 0;
-               for (i = 0; i < info->portwidth; i++) {
-                       flash_add_byte (info, &cword, *src++);
-               }
-               if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
-                       return rc;
-               wp += info->portwidth;
-               cnt -= info->portwidth;
-       }
-#endif /* CFG_FLASH_USE_BUFFER_WRITE */
-       if (cnt == 0) {
-               return (0);
-       }
-
-       /*
-        * handle unaligned tail bytes
-        */
-       cword.l = 0;
-       for (i = 0, cp = wp; (i < info->portwidth) && (cnt > 0); ++i, ++cp) {
-               flash_add_byte (info, &cword, *src++);
-               --cnt;
-       }
-       for (; i < info->portwidth; ++i, ++cp) {
-               flash_add_byte (info, &cword, (*(uchar *) cp));
-       }
-
-       return flash_write_cfiword (info, wp, cword);
-}
-
-/*-----------------------------------------------------------------------
- */
-#ifdef CFG_FLASH_PROTECTION
-
-int flash_real_protect (flash_info_t * info, long sector, int prot)
-{
-       int retcode = 0;
-
-       flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
-       flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT);
-       if (prot)
-               flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_SET);
-       else
-               flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_CLEAR);
-
-       if ((retcode =
-            flash_full_status_check (info, sector, info->erase_blk_tout,
-                                     prot ? "protect" : "unprotect")) == 0) {
-
-               info->protect[sector] = prot;
-
-               /*
-                * On some of Intel's flash chips (marked via legacy_unlock)
-                * unprotect unprotects all locking.
-                */
-               if ((prot == 0) && (info->legacy_unlock)) {
-                       flash_sect_t i;
-
-                       for (i = 0; i < info->sector_count; i++) {
-                               if (info->protect[i])
-                                       flash_real_protect (info, i, 1);
-                       }
-               }
-       }
-       return retcode;
-}
-
-/*-----------------------------------------------------------------------
- * flash_read_user_serial - read the OneTimeProgramming cells
- */
-void flash_read_user_serial (flash_info_t * info, void *buffer, int offset,
-                            int len)
-{
-       uchar *src;
-       uchar *dst;
-
-       dst = buffer;
-       src = flash_make_addr (info, 0, FLASH_OFFSET_USER_PROTECTION);
-       flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
-       memcpy (dst, src + offset, len);
-       flash_write_cmd (info, 0, 0, info->cmd_reset);
-}
-
-/*
- * flash_read_factory_serial - read the device Id from the protection area
- */
-void flash_read_factory_serial (flash_info_t * info, void *buffer, int offset,
-                               int len)
-{
-       uchar *src;
-
-       src = flash_make_addr (info, 0, FLASH_OFFSET_INTEL_PROTECTION);
-       flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
-       memcpy (buffer, src + offset, len);
-       flash_write_cmd (info, 0, 0, info->cmd_reset);
-}
-
-#endif /* CFG_FLASH_PROTECTION */
-
-/*
- * flash_is_busy - check to see if the flash is busy
- * This routine checks the status of the chip and returns true if the chip is busy
- */
-static int flash_is_busy (flash_info_t * info, flash_sect_t sect)
-{
-       int retval;
-
-       switch (info->vendor) {
-       case CFI_CMDSET_INTEL_STANDARD:
-       case CFI_CMDSET_INTEL_EXTENDED:
-               retval = !flash_isset (info, sect, 0, FLASH_STATUS_DONE);
-               break;
-       case CFI_CMDSET_AMD_STANDARD:
-       case CFI_CMDSET_AMD_EXTENDED:
-               retval = flash_toggle (info, sect, 0, AMD_STATUS_TOGGLE);
-               break;
-       default:
-               retval = 0;
-       }
-       debug ("flash_is_busy: %d\n", retval);
-       return retval;
-}
-
-/*-----------------------------------------------------------------------
- *  wait for XSR.7 to be set. Time out with an error if it does not.
- *  This routine does not set the flash to read-array mode.
- */
-static int flash_status_check (flash_info_t * info, flash_sect_t sector,
-                              ulong tout, char *prompt)
-{
-       ulong start;
-
-#if CFG_HZ != 1000
-       tout *= CFG_HZ/1000;
-#endif
-
-       /* Wait for command completion */
-       start = get_timer (0);
-       while (flash_is_busy (info, sector)) {
-               if (get_timer (start) > tout) {
-                       printf ("Flash %s timeout at address %lx data %lx\n",
-                               prompt, info->start[sector],
-                               flash_read_long (info, sector, 0));
-                       flash_write_cmd (info, sector, 0, info->cmd_reset);
-                       return ERR_TIMOUT;
-               }
-               udelay (1);             /* also triggers watchdog */
-       }
-       return ERR_OK;
-}
-
-/*-----------------------------------------------------------------------
- * Wait for XSR.7 to be set, if it times out print an error, otherwise do a full status check.
- * This routine sets the flash to read-array mode.
- */
-static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
-                                   ulong tout, char *prompt)
-{
-       int retcode;
-
-       retcode = flash_status_check (info, sector, tout, prompt);
-       switch (info->vendor) {
-       case CFI_CMDSET_INTEL_EXTENDED:
-       case CFI_CMDSET_INTEL_STANDARD:
-               if ((retcode == ERR_OK)
-                   && !flash_isequal (info, sector, 0, FLASH_STATUS_DONE)) {
-                       retcode = ERR_INVAL;
-                       printf ("Flash %s error at address %lx\n", prompt,
-                               info->start[sector]);
-                       if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)) {
-                               puts ("Command Sequence Error.\n");
-                       } else if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS)) {
-                               puts ("Block Erase Error.\n");
-                               retcode = ERR_NOT_ERASED;
-                       } else if (flash_isset (info, sector, 0, FLASH_STATUS_PSLBS)) {
-                               puts ("Locking Error\n");
-                       }
-                       if (flash_isset (info, sector, 0, FLASH_STATUS_DPS)) {
-                               puts ("Block locked.\n");
-                               retcode = ERR_PROTECTED;
-                       }
-                       if (flash_isset (info, sector, 0, FLASH_STATUS_VPENS))
-                               puts ("Vpp Low Error.\n");
-               }
-               flash_write_cmd (info, sector, 0, info->cmd_reset);
-               break;
-       default:
-               break;
-       }
-       return retcode;
-}
-
-/*-----------------------------------------------------------------------
- */
-static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)
-{
-#if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA)
-       unsigned short  w;
-       unsigned int    l;
-       unsigned long long ll;
-#endif
-
-       switch (info->portwidth) {
-       case FLASH_CFI_8BIT:
-               cword->c = c;
-               break;
-       case FLASH_CFI_16BIT:
-#if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA)
-               w = c;
-               w <<= 8;
-               cword->w = (cword->w >> 8) | w;
-#else
-               cword->w = (cword->w << 8) | c;
-#endif
-               break;
-       case FLASH_CFI_32BIT:
-#if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA)
-               l = c;
-               l <<= 24;
-               cword->l = (cword->l >> 8) | l;
-#else
-               cword->l = (cword->l << 8) | c;
-#endif
-               break;
-       case FLASH_CFI_64BIT:
-#if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA)
-               ll = c;
-               ll <<= 56;
-               cword->ll = (cword->ll >> 8) | ll;
-#else
-               cword->ll = (cword->ll << 8) | c;
-#endif
-               break;
-       }
-}
-
-
-/*-----------------------------------------------------------------------
- * make a proper sized command based on the port and chip widths
- */
-static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf)
-{
-       int i;
-       uchar *cp = (uchar *) cmdbuf;
-
-#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
-       for (i = info->portwidth; i > 0; i--)
-#else
-       for (i = 1; i <= info->portwidth; i++)
-#endif
-               *cp++ = (i & (info->chipwidth - 1)) ? '\0' : cmd;
-}
-
-/*
- * Write a proper sized command to the correct address
- */
-static void flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
-{
-
-       volatile cfiptr_t addr;
-       cfiword_t cword;
-
-       addr.cp = flash_make_addr (info, sect, offset);
-       flash_make_cmd (info, cmd, &cword);
-       switch (info->portwidth) {
-       case FLASH_CFI_8BIT:
-               debug ("fwc addr %p cmd %x %x 8bit x %d bit\n", addr.cp, cmd,
-                      cword.c, info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
-               *addr.cp = cword.c;
-               break;
-       case FLASH_CFI_16BIT:
-               debug ("fwc addr %p cmd %x %4.4x 16bit x %d bit\n", addr.wp,
-                      cmd, cword.w,
-                      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
-               *addr.wp = cword.w;
-               break;
-       case FLASH_CFI_32BIT:
-               debug ("fwc addr %p cmd %x %8.8lx 32bit x %d bit\n", addr.lp,
-                      cmd, cword.l,
-                      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
-               *addr.lp = cword.l;
-               break;
-       case FLASH_CFI_64BIT:
-#ifdef DEBUG
-               {
-                       char str[20];
-
-                       print_longlong (str, cword.ll);
-
-                       debug ("fwrite addr %p cmd %x %s 64 bit x %d bit\n",
-                              addr.llp, cmd, str,
-                              info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
-               }
-#endif
-               *addr.llp = cword.ll;
-               break;
-       }
-
-       /* Ensure all the instructions are fully finished */
-       sync();
-}
-
-static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect)
-{
-       flash_write_cmd (info, sect, AMD_ADDR_START, AMD_CMD_UNLOCK_START);
-       flash_write_cmd (info, sect, AMD_ADDR_ACK, AMD_CMD_UNLOCK_ACK);
-}
-
-/*-----------------------------------------------------------------------
- */
-static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
-{
-       cfiptr_t cptr;
-       cfiword_t cword;
-       int retval;
-
-       cptr.cp = flash_make_addr (info, sect, offset);
-       flash_make_cmd (info, cmd, &cword);
-
-       debug ("is= cmd %x(%c) addr %p ", cmd, cmd, cptr.cp);
-       switch (info->portwidth) {
-       case FLASH_CFI_8BIT:
-               debug ("is= %x %x\n", cptr.cp[0], cword.c);
-               retval = (cptr.cp[0] == cword.c);
-               break;
-       case FLASH_CFI_16BIT:
-               debug ("is= %4.4x %4.4x\n", cptr.wp[0], cword.w);
-               retval = (cptr.wp[0] == cword.w);
-               break;
-       case FLASH_CFI_32BIT:
-               debug ("is= %8.8lx %8.8lx\n", cptr.lp[0], cword.l);
-               retval = (cptr.lp[0] == cword.l);
-               break;
-       case FLASH_CFI_64BIT:
-#ifdef DEBUG
-               {
-                       char str1[20];
-                       char str2[20];
-
-                       print_longlong (str1, cptr.llp[0]);
-                       print_longlong (str2, cword.ll);
-                       debug ("is= %s %s\n", str1, str2);
-               }
-#endif
-               retval = (cptr.llp[0] == cword.ll);
-               break;
-       default:
-               retval = 0;
-               break;
-       }
-       return retval;
-}
-
-/*-----------------------------------------------------------------------
- */
-static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
-{
-       cfiptr_t cptr;
-       cfiword_t cword;
-       int retval;
-
-       cptr.cp = flash_make_addr (info, sect, offset);
-       flash_make_cmd (info, cmd, &cword);
-       switch (info->portwidth) {
-       case FLASH_CFI_8BIT:
-               retval = ((cptr.cp[0] & cword.c) == cword.c);
-               break;
-       case FLASH_CFI_16BIT:
-               retval = ((cptr.wp[0] & cword.w) == cword.w);
-               break;
-       case FLASH_CFI_32BIT:
-               retval = ((cptr.lp[0] & cword.l) == cword.l);
-               break;
-       case FLASH_CFI_64BIT:
-               retval = ((cptr.llp[0] & cword.ll) == cword.ll);
-               break;
-       default:
-               retval = 0;
-               break;
-       }
-       return retval;
-}
-
-/*-----------------------------------------------------------------------
- */
-static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
-{
-       cfiptr_t cptr;
-       cfiword_t cword;
-       int retval;
-
-       cptr.cp = flash_make_addr (info, sect, offset);
-       flash_make_cmd (info, cmd, &cword);
-       switch (info->portwidth) {
-       case FLASH_CFI_8BIT:
-               retval = ((cptr.cp[0] & cword.c) != (cptr.cp[0] & cword.c));
-               break;
-       case FLASH_CFI_16BIT:
-               retval = ((cptr.wp[0] & cword.w) != (cptr.wp[0] & cword.w));
-               break;
-       case FLASH_CFI_32BIT:
-               retval = ((cptr.lp[0] & cword.l) != (cptr.lp[0] & cword.l));
-               break;
-       case FLASH_CFI_64BIT:
-               retval = ((cptr.llp[0] & cword.ll) !=
-                         (cptr.llp[0] & cword.ll));
-               break;
-       default:
-               retval = 0;
-               break;
-       }
-       return retval;
-}
-
-/*-----------------------------------------------------------------------
- * read jedec ids from device and set corresponding fields in info struct
- *
- * Note: assume cfi->vendor, cfi->portwidth and cfi->chipwidth are correct
- *
-*/
-static void flash_read_jedec_ids (flash_info_t * info)
-{
-       info->manufacturer_id = 0;
-       info->device_id       = 0;
-       info->device_id2      = 0;
-
-       switch (info->vendor) {
-       case CFI_CMDSET_INTEL_STANDARD:
-       case CFI_CMDSET_INTEL_EXTENDED:
-               flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
-               flash_write_cmd(info, 0, 0, FLASH_CMD_READ_ID);
-               udelay(1000); /* some flash are slow to respond */
-               info->manufacturer_id = flash_read_uchar (info,
-                                               FLASH_OFFSET_MANUFACTURER_ID);
-               info->device_id = flash_read_uchar (info,
-                                               FLASH_OFFSET_DEVICE_ID);
-               flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
-               break;
-       case CFI_CMDSET_AMD_STANDARD:
-       case CFI_CMDSET_AMD_EXTENDED:
-               flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
-               flash_unlock_seq(info, 0);
-               flash_write_cmd(info, 0, AMD_ADDR_START, FLASH_CMD_READ_ID);
-               udelay(1000); /* some flash are slow to respond */
-               info->manufacturer_id = flash_read_uchar (info,
-                                               FLASH_OFFSET_MANUFACTURER_ID);
-               info->device_id = flash_read_uchar (info,
-                                               FLASH_OFFSET_DEVICE_ID);
-               if (info->device_id == 0x7E) {
-                       /* AMD 3-byte (expanded) device ids */
-                       info->device_id2 = flash_read_uchar (info,
-                                               FLASH_OFFSET_DEVICE_ID2);
-                       info->device_id2 <<= 8;
-                       info->device_id2 |= flash_read_uchar (info,
-                                               FLASH_OFFSET_DEVICE_ID3);
-               }
-               flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
-               break;
-       default:
-               break;
-       }
-}
-
-/*-----------------------------------------------------------------------
- * detect if flash is compatible with the Common Flash Interface (CFI)
- * http://www.jedec.org/download/search/jesd68.pdf
- *
-*/
-static int flash_detect_cfi (flash_info_t * info)
-{
-       int cfi_offset;
-       debug ("flash detect cfi\n");
-
-       for (info->portwidth = CFG_FLASH_CFI_WIDTH;
-            info->portwidth <= FLASH_CFI_64BIT; info->portwidth <<= 1) {
-               for (info->chipwidth = FLASH_CFI_BY8;
-                    info->chipwidth <= info->portwidth;
-                    info->chipwidth <<= 1) {
-                       flash_write_cmd (info, 0, 0, info->cmd_reset);
-                       for (cfi_offset=0; cfi_offset < sizeof(flash_offset_cfi)/sizeof(uint); cfi_offset++) {
-                               flash_write_cmd (info, 0, flash_offset_cfi[cfi_offset], FLASH_CMD_CFI);
-                               if (flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
-                                && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R')
-                                && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {
-                                       info->interface = flash_read_ushort (info, 0, FLASH_OFFSET_INTERFACE);
-                                       info->cfi_offset=flash_offset_cfi[cfi_offset];
-                                       debug ("device interface is %d\n",
-                                               info->interface);
-                                       debug ("found port %d chip %d ",
-                                               info->portwidth, info->chipwidth);
-                                       debug ("port %d bits chip %d bits\n",
-                                               info->portwidth << CFI_FLASH_SHIFT_WIDTH,
-                                               info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
-                                       return 1;
-                               }
-                       }
-               }
-       }
-       debug ("not found\n");
-       return 0;
-}
-
-/*
- * The following code cannot be run from FLASH!
- *
- */
-ulong flash_get_size (ulong base, int banknum)
-{
-       flash_info_t *info = &flash_info[banknum];
-       int i, j;
-       flash_sect_t sect_cnt;
-       unsigned long sector;
-       unsigned long tmp;
-       int size_ratio;
-       uchar num_erase_regions;
-       int erase_region_size;
-       int erase_region_count;
-       int geometry_reversed = 0;
-
-       info->ext_addr = 0;
-       info->cfi_version = 0;
-#ifdef CFG_FLASH_PROTECTION
-       info->legacy_unlock = 0;
-#endif
-
-       info->start[0] = base;
-
-       if (flash_detect_cfi (info)) {
-               info->vendor = flash_read_ushort (info, 0,
-                                       FLASH_OFFSET_PRIMARY_VENDOR);
-               flash_read_jedec_ids (info);
-               flash_write_cmd (info, 0, info->cfi_offset, FLASH_CMD_CFI);
-               num_erase_regions = flash_read_uchar (info,
-                                       FLASH_OFFSET_NUM_ERASE_REGIONS);
-               info->ext_addr = flash_read_ushort (info, 0,
-                                       FLASH_OFFSET_EXT_QUERY_T_P_ADDR);
-               if (info->ext_addr) {
-                       info->cfi_version = (ushort) flash_read_uchar (info,
-                                               info->ext_addr + 3) << 8;
-                       info->cfi_version |= (ushort) flash_read_uchar (info,
-                                               info->ext_addr + 4);
-               }
-#ifdef DEBUG
-               flash_printqry (info, 0);
-#endif
-               switch (info->vendor) {
-               case CFI_CMDSET_INTEL_STANDARD:
-               case CFI_CMDSET_INTEL_EXTENDED:
-               default:
-                       info->cmd_reset = FLASH_CMD_RESET;
-#ifdef CFG_FLASH_PROTECTION
-                       /* read legacy lock/unlock bit from intel flash */
-                       if (info->ext_addr) {
-                               info->legacy_unlock = flash_read_uchar (info,
-                                               info->ext_addr + 5) & 0x08;
-                       }
-#endif
-                       break;
-               case CFI_CMDSET_AMD_STANDARD:
-               case CFI_CMDSET_AMD_EXTENDED:
-                       info->cmd_reset = AMD_CMD_RESET;
-                       /* check if flash geometry needs reversal */
-                       if (num_erase_regions <= 1)
-                               break;
-                       /* reverse geometry if top boot part */
-                       if (info->cfi_version < 0x3131) {
-                               /* CFI < 1.1, try to guess from device id */
-                               if ((info->device_id & 0x80) != 0) {
-                                       geometry_reversed = 1;
-                               }
-                               break;
-                       }
-                       /* CFI >= 1.1, deduct from top/bottom flag */
-                       /* note: ext_addr is valid since cfi_version > 0 */
-                       if (flash_read_uchar(info, info->ext_addr + 0xf) == 3) {
-                               geometry_reversed = 1;
-                       }
-                       break;
-               }
-
-               debug ("manufacturer is %d\n", info->vendor);
-               debug ("manufacturer id is 0x%x\n", info->manufacturer_id);
-               debug ("device id is 0x%x\n", info->device_id);
-               debug ("device id2 is 0x%x\n", info->device_id2);
-               debug ("cfi version is 0x%04x\n", info->cfi_version);
-
-               size_ratio = info->portwidth / info->chipwidth;
-               /* if the chip is x8/x16 reduce the ratio by half */
-               if ((info->interface == FLASH_CFI_X8X16)
-                   && (info->chipwidth == FLASH_CFI_BY8)) {
-                       size_ratio >>= 1;
-               }
-               debug ("size_ratio %d port %d bits chip %d bits\n",
-                      size_ratio, info->portwidth << CFI_FLASH_SHIFT_WIDTH,
-                      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
-               debug ("found %d erase regions\n", num_erase_regions);
-               sect_cnt = 0;
-               sector = base;
-               for (i = 0; i < num_erase_regions; i++) {
-                       if (i > NUM_ERASE_REGIONS) {
-                               printf ("%d erase regions found, only %d used\n",
-                                       num_erase_regions, NUM_ERASE_REGIONS);
-                               break;
-                       }
-                       if (geometry_reversed)
-                               tmp = flash_read_long (info, 0,
-                                              FLASH_OFFSET_ERASE_REGIONS +
-                                              (num_erase_regions - 1 - i) * 4);
-                       else
-                               tmp = flash_read_long (info, 0,
-                                              FLASH_OFFSET_ERASE_REGIONS +
-                                              i * 4);
-                       erase_region_size =
-                               (tmp & 0xffff) ? ((tmp & 0xffff) * 256) : 128;
-                       tmp >>= 16;
-                       erase_region_count = (tmp & 0xffff) + 1;
-                       debug ("erase_region_count = %d erase_region_size = %d\n",
-                               erase_region_count, erase_region_size);
-                       for (j = 0; j < erase_region_count; j++) {
-                               info->start[sect_cnt] = sector;
-                               sector += (erase_region_size * size_ratio);
-
-                               /*
-                                * Only read protection status from supported devices (intel...)
-                                */
-                               switch (info->vendor) {
-                               case CFI_CMDSET_INTEL_EXTENDED:
-                               case CFI_CMDSET_INTEL_STANDARD:
-                                       info->protect[sect_cnt] =
-                                               flash_isset (info, sect_cnt,
-                                                            FLASH_OFFSET_PROTECT,
-                                                            FLASH_STATUS_PROTECT);
-                                       break;
-                               default:
-                                       info->protect[sect_cnt] = 0; /* default: not protected */
-                               }
-
-                               sect_cnt++;
-                       }
-               }
-
-               info->sector_count = sect_cnt;
-               /* multiply the size by the number of chips */
-               info->size = (1 << flash_read_uchar (info, FLASH_OFFSET_SIZE)) * size_ratio;
-               info->buffer_size = (1 << flash_read_ushort (info, 0, FLASH_OFFSET_BUFFER_SIZE));
-               tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_ETOUT);
-               info->erase_blk_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_EMAX_TOUT)));
-               tmp = (1 << flash_read_uchar (info, FLASH_OFFSET_WBTOUT)) *
-                       (1 << flash_read_uchar (info, FLASH_OFFSET_WBMAX_TOUT));
-               info->buffer_write_tout = tmp / 1000 + (tmp % 1000 ? 1 : 0); /* round up when converting to ms */
-               tmp = (1 << flash_read_uchar (info, FLASH_OFFSET_WTOUT)) *
-                     (1 << flash_read_uchar (info, FLASH_OFFSET_WMAX_TOUT));
-               info->write_tout = tmp / 1000 + (tmp % 1000 ? 1 : 0); /* round up when converting to ms */
-               info->flash_id = FLASH_MAN_CFI;
-               if ((info->interface == FLASH_CFI_X8X16) && (info->chipwidth == FLASH_CFI_BY8)) {
-                       info->portwidth >>= 1;  /* XXX - Need to test on x8/x16 in parallel. */
-               }
-       }
-
-       flash_write_cmd (info, 0, 0, info->cmd_reset);
-       return (info->size);
-}
-
-/* loop through the sectors from the highest address
- * when the passed address is greater or equal to the sector address
- * we have a match
- */
-static flash_sect_t find_sector (flash_info_t * info, ulong addr)
-{
-       flash_sect_t sector;
-
-       for (sector = info->sector_count - 1; sector >= 0; sector--) {
-               if (addr >= info->start[sector])
-                       break;
-       }
-       return sector;
-}
-
-/*-----------------------------------------------------------------------
- */
-static int flash_write_cfiword (flash_info_t * info, ulong dest,
-                               cfiword_t cword)
-{
-       cfiptr_t ctladdr;
-       cfiptr_t cptr;
-       int flag;
-
-       ctladdr.cp = flash_make_addr (info, 0, 0);
-       cptr.cp = (uchar *) dest;
-
-       /* Check if Flash is (sufficiently) erased */
-       switch (info->portwidth) {
-       case FLASH_CFI_8BIT:
-               flag = ((cptr.cp[0] & cword.c) == cword.c);
-               break;
-       case FLASH_CFI_16BIT:
-               flag = ((cptr.wp[0] & cword.w) == cword.w);
-               break;
-       case FLASH_CFI_32BIT:
-               flag = ((cptr.lp[0] & cword.l) == cword.l);
-               break;
-       case FLASH_CFI_64BIT:
-               flag = ((cptr.llp[0] & cword.ll) == cword.ll);
-               break;
-       default:
-               return 2;
-       }
-       if (!flag)
-               return 2;
-
-       /* Disable interrupts which might cause a timeout here */
-       flag = disable_interrupts ();
-
-       switch (info->vendor) {
-       case CFI_CMDSET_INTEL_EXTENDED:
-       case CFI_CMDSET_INTEL_STANDARD:
-               flash_write_cmd (info, 0, 0, FLASH_CMD_CLEAR_STATUS);
-               flash_write_cmd (info, 0, 0, FLASH_CMD_WRITE);
-               break;
-       case CFI_CMDSET_AMD_EXTENDED:
-       case CFI_CMDSET_AMD_STANDARD:
-               flash_unlock_seq (info, 0);
-               flash_write_cmd (info, 0, AMD_ADDR_START, AMD_CMD_WRITE);
-               break;
-       }
-
-       switch (info->portwidth) {
-       case FLASH_CFI_8BIT:
-               cptr.cp[0] = cword.c;
-               break;
-       case FLASH_CFI_16BIT:
-               cptr.wp[0] = cword.w;
-               break;
-       case FLASH_CFI_32BIT:
-               cptr.lp[0] = cword.l;
-               break;
-       case FLASH_CFI_64BIT:
-               cptr.llp[0] = cword.ll;
-               break;
-       }
-
-       /* re-enable interrupts if necessary */
-       if (flag)
-               enable_interrupts ();
-
-       return flash_full_status_check (info, find_sector (info, dest),
-                                       info->write_tout, "write");
-}
-
-#ifdef CFG_FLASH_USE_BUFFER_WRITE
-
-static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
-                                 int len)
-{
-       flash_sect_t sector;
-       int cnt;
-       int retcode;
-       volatile cfiptr_t src;
-       volatile cfiptr_t dst;
-
-       switch (info->vendor) {
-       case CFI_CMDSET_INTEL_STANDARD:
-       case CFI_CMDSET_INTEL_EXTENDED:
-               src.cp = cp;
-               dst.cp = (uchar *) dest;
-               sector = find_sector (info, dest);
-               flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
-               flash_write_cmd (info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER);
-               if ((retcode = flash_status_check (info, sector, info->buffer_write_tout,
-                                                  "write to buffer")) == ERR_OK) {
-                       /* reduce the number of loops by the width of the port  */
-                       switch (info->portwidth) {
-                       case FLASH_CFI_8BIT:
-                               cnt = len;
-                               break;
-                       case FLASH_CFI_16BIT:
-                               cnt = len >> 1;
-                               break;
-                       case FLASH_CFI_32BIT:
-                               cnt = len >> 2;
-                               break;
-                       case FLASH_CFI_64BIT:
-                               cnt = len >> 3;
-                               break;
-                       default:
-                               return ERR_INVAL;
-                               break;
-                       }
-                       flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
-                       while (cnt-- > 0) {
-                               switch (info->portwidth) {
-                               case FLASH_CFI_8BIT:
-                                       *dst.cp++ = *src.cp++;
-                                       break;
-                               case FLASH_CFI_16BIT:
-                                       *dst.wp++ = *src.wp++;
-                                       break;
-                               case FLASH_CFI_32BIT:
-                                       *dst.lp++ = *src.lp++;
-                                       break;
-                               case FLASH_CFI_64BIT:
-                                       *dst.llp++ = *src.llp++;
-                                       break;
-                               default:
-                                       return ERR_INVAL;
-                                       break;
-                               }
-                       }
-                       flash_write_cmd (info, sector, 0,
-                                        FLASH_CMD_WRITE_BUFFER_CONFIRM);
-                       retcode = flash_full_status_check (info, sector,
-                                                          info->buffer_write_tout,
-                                                          "buffer write");
-               }
-               return retcode;
-
-       case CFI_CMDSET_AMD_STANDARD:
-       case CFI_CMDSET_AMD_EXTENDED:
-               src.cp = cp;
-               dst.cp = (uchar *) dest;
-               sector = find_sector (info, dest);
-
-               flash_unlock_seq(info,0);
-               flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_TO_BUFFER);
-
-               switch (info->portwidth) {
-               case FLASH_CFI_8BIT:
-                       cnt = len;
-                       flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
-                       while (cnt-- > 0) *dst.cp++ = *src.cp++;
-                       break;
-               case FLASH_CFI_16BIT:
-                       cnt = len >> 1;
-                       flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
-                       while (cnt-- > 0) *dst.wp++ = *src.wp++;
-                       break;
-               case FLASH_CFI_32BIT:
-                       cnt = len >> 2;
-                       flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
-                       while (cnt-- > 0) *dst.lp++ = *src.lp++;
-                       break;
-               case FLASH_CFI_64BIT:
-                       cnt = len >> 3;
-                       flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
-                       while (cnt-- > 0) *dst.llp++ = *src.llp++;
-                       break;
-               default:
-                       return ERR_INVAL;
-               }
-
-               flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_BUFFER_CONFIRM);
-               retcode = flash_full_status_check (info, sector, info->buffer_write_tout,
-                                                  "buffer write");
-               return retcode;
-
-       default:
-               debug ("Unknown Command Set\n");
-               return ERR_INVAL;
-       }
-}
-#endif /* CFG_FLASH_USE_BUFFER_WRITE */
-
-#endif /* CFG_FLASH_CFI */
diff --git a/drivers/cs8900.c b/drivers/cs8900.c
deleted file mode 100644 (file)
index 80c4ba2..0000000
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Cirrus Logic CS8900A Ethernet
- *
- * (C) 2003 Wolfgang Denk, wd@denx.de
- *     Extension to synchronize ethaddr environment variable
- *     against value in EEPROM
- *
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
- *
- * Copyright (C) 1999 Ben Williamson <benw@pobox.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is loaded into SRAM in bootstrap mode, where it waits
- * for commands on UART1 to read and write memory, jump to code etc.
- * A design goal for this program is to be entirely independent of the
- * target board.  Anything with a CL-PS7111 or EP7211 should be able to run
- * this code in bootstrap mode.  All the board specifics can be handled on
- * the host.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <common.h>
-#include <command.h>
-#include "cs8900.h"
-#include <net.h>
-
-#ifdef CONFIG_DRIVER_CS8900
-
-#if defined(CONFIG_CMD_NET)
-
-#undef DEBUG
-
-/* packet page register access functions */
-
-#ifdef CS8900_BUS32
-/* we don't need 16 bit initialisation on 32 bit bus */
-#define get_reg_init_bus(x) get_reg((x))
-#else
-static unsigned short get_reg_init_bus (int regno)
-{
-       /* force 16 bit busmode */
-       volatile unsigned char c;
-
-       c = CS8900_BUS16_0;
-       c = CS8900_BUS16_1;
-       c = CS8900_BUS16_0;
-       c = CS8900_BUS16_1;
-       c = CS8900_BUS16_0;
-
-       CS8900_PPTR = regno;
-       return (unsigned short) CS8900_PDATA;
-}
-#endif
-
-static unsigned short get_reg (int regno)
-{
-       CS8900_PPTR = regno;
-       return (unsigned short) CS8900_PDATA;
-}
-
-
-static void put_reg (int regno, unsigned short val)
-{
-       CS8900_PPTR = regno;
-       CS8900_PDATA = val;
-}
-
-static void eth_reset (void)
-{
-       int tmo;
-       unsigned short us;
-
-       /* reset NIC */
-       put_reg (PP_SelfCTL, get_reg (PP_SelfCTL) | PP_SelfCTL_Reset);
-
-       /* wait for 200ms */
-       udelay (200000);
-       /* Wait until the chip is reset */
-
-       tmo = get_timer (0) + 1 * CFG_HZ;
-       while ((((us = get_reg_init_bus (PP_SelfSTAT)) & PP_SelfSTAT_InitD) == 0)
-                  && tmo < get_timer (0))
-               /*NOP*/;
-}
-
-static void eth_reginit (void)
-{
-       /* receive only error free packets addressed to this card */
-       put_reg (PP_RxCTL, PP_RxCTL_IA | PP_RxCTL_Broadcast | PP_RxCTL_RxOK);
-       /* do not generate any interrupts on receive operations */
-       put_reg (PP_RxCFG, 0);
-       /* do not generate any interrupts on transmit operations */
-       put_reg (PP_TxCFG, 0);
-       /* do not generate any interrupts on buffer operations */
-       put_reg (PP_BufCFG, 0);
-       /* enable transmitter/receiver mode */
-       put_reg (PP_LineCTL, PP_LineCTL_Rx | PP_LineCTL_Tx);
-}
-
-void cs8900_get_enetaddr (uchar * addr)
-{
-       int i;
-       unsigned char env_enetaddr[6];
-       char *tmp = getenv ("ethaddr");
-       char *end;
-
-       for (i=0; i<6; i++) {
-               env_enetaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
-               if (tmp)
-                       tmp = (*end) ? end+1 : end;
-       }
-
-       /* verify chip id */
-       if (get_reg_init_bus (PP_ChipID) != 0x630e)
-               return;
-       eth_reset ();
-       if ((get_reg (PP_SelfST) & (PP_SelfSTAT_EEPROM | PP_SelfSTAT_EEPROM_OK)) ==
-                       (PP_SelfSTAT_EEPROM | PP_SelfSTAT_EEPROM_OK)) {
-
-               /* Load the MAC from EEPROM */
-               for (i = 0; i < 6 / 2; i++) {
-                       unsigned int Addr;
-
-                       Addr = get_reg (PP_IA + i * 2);
-                       addr[i * 2] = Addr & 0xFF;
-                       addr[i * 2 + 1] = Addr >> 8;
-               }
-
-               if (memcmp(env_enetaddr, "\0\0\0\0\0\0", 6) != 0 &&
-                   memcmp(env_enetaddr, addr, 6) != 0) {
-                       printf ("\nWarning: MAC addresses don't match:\n");
-                       printf ("\tHW MAC address:  "
-                               "%02X:%02X:%02X:%02X:%02X:%02X\n",
-                               addr[0], addr[1],
-                               addr[2], addr[3],
-                               addr[4], addr[5] );
-                       printf ("\t\"ethaddr\" value: "
-                               "%02X:%02X:%02X:%02X:%02X:%02X\n",
-                               env_enetaddr[0], env_enetaddr[1],
-                               env_enetaddr[2], env_enetaddr[3],
-                               env_enetaddr[4], env_enetaddr[5]) ;
-                       debug ("### Set MAC addr from environment\n");
-                       memcpy (addr, env_enetaddr, 6);
-               }
-               if (!tmp) {
-                       char ethaddr[20];
-                       sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
-                                addr[0], addr[1],
-                                addr[2], addr[3],
-                                addr[4], addr[5]) ;
-                       debug ("### Set environment from HW MAC addr = \"%s\"\n",                               ethaddr);
-                       setenv ("ethaddr", ethaddr);
-               }
-
-       }
-}
-
-void eth_halt (void)
-{
-       /* disable transmitter/receiver mode */
-       put_reg (PP_LineCTL, 0);
-
-       /* "shutdown" to show ChipID or kernel wouldn't find he cs8900 ... */
-       get_reg_init_bus (PP_ChipID);
-}
-
-int eth_init (bd_t * bd)
-{
-
-       /* verify chip id */
-       if (get_reg_init_bus (PP_ChipID) != 0x630e) {
-               printf ("CS8900 Ethernet chip not found?!\n");
-               return 0;
-       }
-
-       eth_reset ();
-       /* set the ethernet address */
-       put_reg (PP_IA + 0, bd->bi_enetaddr[0] | (bd->bi_enetaddr[1] << 8));
-       put_reg (PP_IA + 2, bd->bi_enetaddr[2] | (bd->bi_enetaddr[3] << 8));
-       put_reg (PP_IA + 4, bd->bi_enetaddr[4] | (bd->bi_enetaddr[5] << 8));
-
-       eth_reginit ();
-       return 0;
-}
-
-/* Get a data block via Ethernet */
-extern int eth_rx (void)
-{
-       int i;
-       unsigned short rxlen;
-       unsigned short *addr;
-       unsigned short status;
-
-       status = get_reg (PP_RER);
-
-       if ((status & PP_RER_RxOK) == 0)
-               return 0;
-
-       status = CS8900_RTDATA;         /* stat */
-       rxlen = CS8900_RTDATA;          /* len */
-
-#ifdef DEBUG
-       if (rxlen > PKTSIZE_ALIGN + PKTALIGN)
-               printf ("packet too big!\n");
-#endif
-       for (addr = (unsigned short *) NetRxPackets[0], i = rxlen >> 1; i > 0;
-                i--)
-               *addr++ = CS8900_RTDATA;
-       if (rxlen & 1)
-               *addr++ = CS8900_RTDATA;
-
-       /* Pass the packet up to the protocol layers. */
-       NetReceive (NetRxPackets[0], rxlen);
-
-       return rxlen;
-}
-
-/* Send a data block via Ethernet. */
-extern int eth_send (volatile void *packet, int length)
-{
-       volatile unsigned short *addr;
-       int tmo;
-       unsigned short s;
-
-retry:
-       /* initiate a transmit sequence */
-       CS8900_TxCMD = PP_TxCmd_TxStart_Full;
-       CS8900_TxLEN = length;
-
-       /* Test to see if the chip has allocated memory for the packet */
-       if ((get_reg (PP_BusSTAT) & PP_BusSTAT_TxRDY) == 0) {
-               /* Oops... this should not happen! */
-#ifdef DEBUG
-               printf ("cs: unable to send packet; retrying...\n");
-#endif
-               for (tmo = get_timer (0) + 5 * CFG_HZ; get_timer (0) < tmo;)
-                       /*NOP*/;
-               eth_reset ();
-               eth_reginit ();
-               goto retry;
-       }
-
-       /* Write the contents of the packet */
-       /* assume even number of bytes */
-       for (addr = packet; length > 0; length -= 2)
-               CS8900_RTDATA = *addr++;
-
-       /* wait for transfer to succeed */
-       tmo = get_timer (0) + 5 * CFG_HZ;
-       while ((s = get_reg (PP_TER) & ~0x1F) == 0) {
-               if (get_timer (0) >= tmo)
-                       break;
-       }
-
-       /* nothing */ ;
-       if ((s & (PP_TER_CRS | PP_TER_TxOK)) != PP_TER_TxOK) {
-#ifdef DEBUG
-               printf ("\ntransmission error %#x\n", s);
-#endif
-       }
-
-       return 0;
-}
-
-static void cs8900_e2prom_ready(void)
-{
-       while(get_reg(PP_SelfST) & SI_BUSY);
-}
-
-/***********************************************************/
-/* read a 16-bit word out of the EEPROM                    */
-/***********************************************************/
-
-int cs8900_e2prom_read(unsigned char addr, unsigned short *value)
-{
-       cs8900_e2prom_ready();
-       put_reg(PP_EECMD, EEPROM_READ_CMD | addr);
-       cs8900_e2prom_ready();
-       *value = get_reg(PP_EEData);
-
-       return 0;
-}
-
-
-/***********************************************************/
-/* write a 16-bit word into the EEPROM                     */
-/***********************************************************/
-
-int cs8900_e2prom_write(unsigned char addr, unsigned short value)
-{
-       cs8900_e2prom_ready();
-       put_reg(PP_EECMD, EEPROM_WRITE_EN);
-       cs8900_e2prom_ready();
-       put_reg(PP_EEData, value);
-       put_reg(PP_EECMD, EEPROM_WRITE_CMD | addr);
-       cs8900_e2prom_ready();
-       put_reg(PP_EECMD, EEPROM_WRITE_DIS);
-       cs8900_e2prom_ready();
-
-       return 0;
-}
-
-#endif /* COMMANDS & CFG_NET */
-
-#endif /* CONFIG_DRIVER_CS8900 */
diff --git a/drivers/cs8900.h b/drivers/cs8900.h
deleted file mode 100644 (file)
index f886d10..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Cirrus Logic CS8900A Ethernet
- *
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
- *
- * Copyright (C) 1999 Ben Williamson <benw@pobox.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is loaded into SRAM in bootstrap mode, where it waits
- * for commands on UART1 to read and write memory, jump to code etc.
- * A design goal for this program is to be entirely independent of the
- * target board.  Anything with a CL-PS7111 or EP7211 should be able to run
- * this code in bootstrap mode.  All the board specifics can be handled on
- * the host.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <asm/types.h>
-#include <config.h>
-
-#ifdef CONFIG_DRIVER_CS8900
-
-/* although the registers are 16 bit, they are 32-bit aligned on the
-   EDB7111. so we have to read them as 32-bit registers and ignore the
-   upper 16-bits. i'm not sure if this holds for the EDB7211. */
-
-#ifdef CS8900_BUS16
-  /* 16 bit aligned registers, 16 bit wide */
-  #define CS8900_REG u16
-  #define CS8900_OFF 0x02
-  #define CS8900_BUS16_0  *(volatile u8 *)(CS8900_BASE+0x00)
-  #define CS8900_BUS16_1  *(volatile u8 *)(CS8900_BASE+0x01)
-#elif  defined(CS8900_BUS32)
-  /* 32 bit aligned registers, 16 bit wide (we ignore upper 16 bits) */
-  #define CS8900_REG u32
-  #define CS8900_OFF 0x04
-#else
-  #error unknown bussize ...
-#endif
-
-#define CS8900_RTDATA *(volatile CS8900_REG *)(CS8900_BASE+0x00*CS8900_OFF)
-#define CS8900_TxCMD  *(volatile CS8900_REG *)(CS8900_BASE+0x02*CS8900_OFF)
-#define CS8900_TxLEN  *(volatile CS8900_REG *)(CS8900_BASE+0x03*CS8900_OFF)
-#define CS8900_ISQ    *(volatile CS8900_REG *)(CS8900_BASE+0x04*CS8900_OFF)
-#define CS8900_PPTR   *(volatile CS8900_REG *)(CS8900_BASE+0x05*CS8900_OFF)
-#define CS8900_PDATA  *(volatile CS8900_REG *)(CS8900_BASE+0x06*CS8900_OFF)
-
-
-#define ISQ_RxEvent     0x04
-#define ISQ_TxEvent     0x08
-#define ISQ_BufEvent    0x0C
-#define ISQ_RxMissEvent 0x10
-#define ISQ_TxColEvent  0x12
-#define ISQ_EventMask   0x3F
-
-/* packet page register offsets */
-
-/* bus interface registers */
-#define PP_ChipID    0x0000  /* Chip identifier - must be 0x630E */
-#define PP_ChipRev   0x0002  /* Chip revision, model codes */
-
-#define PP_IntReg    0x0022  /* Interrupt configuration */
-#define PP_IntReg_IRQ0         0x0000  /* Use INTR0 pin */
-#define PP_IntReg_IRQ1         0x0001  /* Use INTR1 pin */
-#define PP_IntReg_IRQ2         0x0002  /* Use INTR2 pin */
-#define PP_IntReg_IRQ3         0x0003  /* Use INTR3 pin */
-
-/* status and control registers */
-
-#define PP_RxCFG     0x0102  /* Receiver configuration */
-#define PP_RxCFG_Skip1         0x0040  /* Skip (i.e. discard) current frame */
-#define PP_RxCFG_Stream        0x0080  /* Enable streaming mode */
-#define PP_RxCFG_RxOK          0x0100  /* RxOK interrupt enable */
-#define PP_RxCFG_RxDMAonly     0x0200  /* Use RxDMA for all frames */
-#define PP_RxCFG_AutoRxDMA     0x0400  /* Select RxDMA automatically */
-#define PP_RxCFG_BufferCRC     0x0800  /* Include CRC characters in frame */
-#define PP_RxCFG_CRC           0x1000  /* Enable interrupt on CRC error */
-#define PP_RxCFG_RUNT          0x2000  /* Enable interrupt on RUNT frames */
-#define PP_RxCFG_EXTRA         0x4000  /* Enable interrupt on frames with extra data */
-
-#define PP_RxCTL     0x0104  /* Receiver control */
-#define PP_RxCTL_IAHash        0x0040  /* Accept frames that match hash */
-#define PP_RxCTL_Promiscuous   0x0080  /* Accept any frame */
-#define PP_RxCTL_RxOK          0x0100  /* Accept well formed frames */
-#define PP_RxCTL_Multicast     0x0200  /* Accept multicast frames */
-#define PP_RxCTL_IA            0x0400  /* Accept frame that matches IA */
-#define PP_RxCTL_Broadcast     0x0800  /* Accept broadcast frames */
-#define PP_RxCTL_CRC           0x1000  /* Accept frames with bad CRC */
-#define PP_RxCTL_RUNT          0x2000  /* Accept runt frames */
-#define PP_RxCTL_EXTRA         0x4000  /* Accept frames that are too long */
-
-#define PP_TxCFG     0x0106  /* Transmit configuration */
-#define PP_TxCFG_CRS           0x0040  /* Enable interrupt on loss of carrier */
-#define PP_TxCFG_SQE           0x0080  /* Enable interrupt on Signal Quality Error */
-#define PP_TxCFG_TxOK          0x0100  /* Enable interrupt on successful xmits */
-#define PP_TxCFG_Late          0x0200  /* Enable interrupt on "out of window" */
-#define PP_TxCFG_Jabber        0x0400  /* Enable interrupt on jabber detect */
-#define PP_TxCFG_Collision     0x0800  /* Enable interrupt if collision */
-#define PP_TxCFG_16Collisions  0x8000  /* Enable interrupt if > 16 collisions */
-
-#define PP_TxCmd     0x0108  /* Transmit command status */
-#define PP_TxCmd_TxStart_5     0x0000  /* Start after 5 bytes in buffer */
-#define PP_TxCmd_TxStart_381   0x0040  /* Start after 381 bytes in buffer */
-#define PP_TxCmd_TxStart_1021  0x0080  /* Start after 1021 bytes in buffer */
-#define PP_TxCmd_TxStart_Full  0x00C0  /* Start after all bytes loaded */
-#define PP_TxCmd_Force         0x0100  /* Discard any pending packets */
-#define PP_TxCmd_OneCollision  0x0200  /* Abort after a single collision */
-#define PP_TxCmd_NoCRC         0x1000  /* Do not add CRC */
-#define PP_TxCmd_NoPad         0x2000  /* Do not pad short packets */
-
-#define PP_BufCFG    0x010A  /* Buffer configuration */
-#define PP_BufCFG_SWI          0x0040  /* Force interrupt via software */
-#define PP_BufCFG_RxDMA        0x0080  /* Enable interrupt on Rx DMA */
-#define PP_BufCFG_TxRDY        0x0100  /* Enable interrupt when ready for Tx */
-#define PP_BufCFG_TxUE         0x0200  /* Enable interrupt in Tx underrun */
-#define PP_BufCFG_RxMiss       0x0400  /* Enable interrupt on missed Rx packets */
-#define PP_BufCFG_Rx128        0x0800  /* Enable Rx interrupt after 128 bytes */
-#define PP_BufCFG_TxCol        0x1000  /* Enable int on Tx collision ctr overflow */
-#define PP_BufCFG_Miss         0x2000  /* Enable int on Rx miss ctr overflow */
-#define PP_BufCFG_RxDest       0x8000  /* Enable int on Rx dest addr match */
-
-#define PP_LineCTL   0x0112  /* Line control */
-#define PP_LineCTL_Rx          0x0040  /* Enable receiver */
-#define PP_LineCTL_Tx          0x0080  /* Enable transmitter */
-#define PP_LineCTL_AUIonly     0x0100  /* AUI interface only */
-#define PP_LineCTL_AutoAUI10BT 0x0200  /* Autodetect AUI or 10BaseT interface */
-#define PP_LineCTL_ModBackoffE 0x0800  /* Enable modified backoff algorithm */
-#define PP_LineCTL_PolarityDis 0x1000  /* Disable Rx polarity autodetect */
-#define PP_LineCTL_2partDefDis 0x2000  /* Disable two-part defferal */
-#define PP_LineCTL_LoRxSquelch 0x4000  /* Reduce receiver squelch threshold */
-
-#define PP_SelfCTL   0x0114  /* Chip self control */
-#define PP_SelfCTL_Reset       0x0040  /* Self-clearing reset */
-#define PP_SelfCTL_SWSuspend   0x0100  /* Initiate suspend mode */
-#define PP_SelfCTL_HWSleepE    0x0200  /* Enable SLEEP input */
-#define PP_SelfCTL_HWStandbyE  0x0400  /* Enable standby mode */
-#define PP_SelfCTL_HC0E        0x1000  /* use HCB0 for LINK LED */
-#define PP_SelfCTL_HC1E        0x2000  /* use HCB1 for BSTATUS LED */
-#define PP_SelfCTL_HCB0        0x4000  /* control LINK LED if HC0E set */
-#define PP_SelfCTL_HCB1        0x8000  /* control BSTATUS LED if HC1E set */
-
-#define PP_BusCTL    0x0116  /* Bus control */
-#define PP_BusCTL_ResetRxDMA   0x0040  /* Reset RxDMA pointer */
-#define PP_BusCTL_DMAextend    0x0100  /* Extend DMA cycle */
-#define PP_BusCTL_UseSA        0x0200  /* Assert MEMCS16 on address decode */
-#define PP_BusCTL_MemoryE      0x0400  /* Enable memory mode */
-#define PP_BusCTL_DMAburst     0x0800  /* Limit DMA access burst */
-#define PP_BusCTL_IOCHRDYE     0x1000  /* Set IOCHRDY high impedence */
-#define PP_BusCTL_RxDMAsize    0x2000  /* Set DMA buffer size 64KB */
-#define PP_BusCTL_EnableIRQ    0x8000  /* Generate interrupt on interrupt event */
-
-#define PP_TestCTL   0x0118  /* Test control */
-#define PP_TestCTL_DisableLT   0x0080  /* Disable link status */
-#define PP_TestCTL_ENDECloop   0x0200  /* Internal loopback */
-#define PP_TestCTL_AUIloop     0x0400  /* AUI loopback */
-#define PP_TestCTL_DisBackoff  0x0800  /* Disable backoff algorithm */
-#define PP_TestCTL_FDX         0x4000  /* Enable full duplex mode */
-
-#define PP_ISQ       0x0120  /* Interrupt Status Queue */
-
-#define PP_RER       0x0124  /* Receive event */
-#define PP_RER_IAHash          0x0040  /* Frame hash match */
-#define PP_RER_Dribble         0x0080  /* Frame had 1-7 extra bits after last byte */
-#define PP_RER_RxOK            0x0100  /* Frame received with no errors */
-#define PP_RER_Hashed          0x0200  /* Frame address hashed OK */
-#define PP_RER_IA              0x0400  /* Frame address matched IA */
-#define PP_RER_Broadcast       0x0800  /* Broadcast frame */
-#define PP_RER_CRC             0x1000  /* Frame had CRC error */
-#define PP_RER_RUNT            0x2000  /* Runt frame */
-#define PP_RER_EXTRA           0x4000  /* Frame was too long */
-
-#define PP_TER       0x0128 /* Transmit event */
-#define PP_TER_CRS             0x0040  /* Carrier lost */
-#define PP_TER_SQE             0x0080  /* Signal Quality Error */
-#define PP_TER_TxOK            0x0100  /* Packet sent without error */
-#define PP_TER_Late            0x0200  /* Out of window */
-#define PP_TER_Jabber          0x0400  /* Stuck transmit? */
-#define PP_TER_NumCollisions   0x7800  /* Number of collisions */
-#define PP_TER_16Collisions    0x8000  /* > 16 collisions */
-
-#define PP_BER       0x012C /* Buffer event */
-#define PP_BER_SWint           0x0040 /* Software interrupt */
-#define PP_BER_RxDMAFrame      0x0080 /* Received framed DMAed */
-#define PP_BER_Rdy4Tx          0x0100 /* Ready for transmission */
-#define PP_BER_TxUnderrun      0x0200 /* Transmit underrun */
-#define PP_BER_RxMiss          0x0400 /* Received frame missed */
-#define PP_BER_Rx128           0x0800 /* 128 bytes received */
-#define PP_BER_RxDest          0x8000 /* Received framed passed address filter */
-
-#define PP_RxMiss    0x0130  /*  Receiver miss counter */
-
-#define PP_TxCol     0x0132  /*  Transmit collision counter */
-
-#define PP_LineSTAT  0x0134  /* Line status */
-#define PP_LineSTAT_LinkOK     0x0080  /* Line is connected and working */
-#define PP_LineSTAT_AUI        0x0100  /* Connected via AUI */
-#define PP_LineSTAT_10BT       0x0200  /* Connected via twisted pair */
-#define PP_LineSTAT_Polarity   0x1000  /* Line polarity OK (10BT only) */
-#define PP_LineSTAT_CRS        0x4000  /* Frame being received */
-
-#define PP_SelfSTAT  0x0136  /* Chip self status */
-#define PP_SelfSTAT_33VActive  0x0040  /* supply voltage is 3.3V */
-#define PP_SelfSTAT_InitD      0x0080  /* Chip initialization complete */
-#define PP_SelfSTAT_SIBSY      0x0100  /* EEPROM is busy */
-#define PP_SelfSTAT_EEPROM     0x0200  /* EEPROM present */
-#define PP_SelfSTAT_EEPROM_OK  0x0400  /* EEPROM checks out */
-#define PP_SelfSTAT_ELPresent  0x0800  /* External address latch logic available */
-#define PP_SelfSTAT_EEsize     0x1000  /* Size of EEPROM */
-
-#define PP_BusSTAT   0x0138  /* Bus status */
-#define PP_BusSTAT_TxBid       0x0080  /* Tx error */
-#define PP_BusSTAT_TxRDY       0x0100  /* Ready for Tx data */
-
-#define PP_TDR       0x013C  /* AUI Time Domain Reflectometer */
-
-/* initiate transmit registers */
-
-#define PP_TxCommand 0x0144  /* Tx Command */
-#define PP_TxLength  0x0146  /* Tx Length */
-
-
-/* address filter registers */
-
-#define PP_LAF       0x0150  /* Logical address filter (6 bytes) */
-#define PP_IA        0x0158  /* Individual address (MAC) */
-
-/* EEPROM Kram */
-#define SI_BUSY 0x0100
-#define PP_SelfST 0x0136       /*  Self State register */
-#define PP_EECMD 0x0040                /*  NVR Interface Command register */
-#define PP_EEData 0x0042       /*  NVR Interface Data Register */
-#define EEPROM_WRITE_EN                0x00F0
-#define EEPROM_WRITE_DIS       0x0000
-#define EEPROM_WRITE_CMD       0x0100
-#define EEPROM_READ_CMD                0x0200
-#define EEPROM_ERASE_CMD       0x0300
-
-extern int cs8900_e2prom_read(uchar, ushort *);
-extern int cs8900_e2prom_write(uchar, ushort);
-
-#endif /* CONFIG_DRIVER_CS8900 */
diff --git a/drivers/ct69000.c b/drivers/ct69000.c
deleted file mode 100644 (file)
index 29d82e4..0000000
+++ /dev/null
@@ -1,1286 +0,0 @@
-/* ported from ctfb.c (linux kernel):
- * Created in Jan - July 2000 by Thomas Höhenleitner <th@visuelle-maschinen.de>
- *
- * Ported to U-Boot:
- * (C) Copyright 2002 Denis Peter, MPL AG Switzerland
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-
-#ifdef CONFIG_VIDEO
-
-#include <pci.h>
-#include <video_fb.h>
-#include "videomodes.h"
-
-#ifdef CONFIG_VIDEO_CT69000
-
-/* debug */
-#undef VGA_DEBUG
-#undef VGA_DUMP_REG
-#ifdef VGA_DEBUG
-#define        PRINTF(fmt,args...)     printf (fmt ,##args)
-#else
-#define PRINTF(fmt,args...)
-#endif
-
-/* Macros */
-#ifndef min
-#define min( a, b ) ( ( a ) < ( b ) ) ? ( a ) : ( b )
-#endif
-#ifndef max
-#define max( a, b ) ( ( a ) > ( b ) ) ? ( a ) : ( b )
-#endif
-#ifdef minmax
-#error "term minmax already used."
-#endif
-#define minmax( a, x, b ) max( ( a ), min( ( x ), ( b ) ) )
-#define N_ELTS( x ) ( sizeof( x ) / sizeof( x[ 0 ] ) )
-
-/* CT Register Offsets */
-#define CT_AR_O                        0x3c0   /* Index and Data write port of the attribute Registers */
-#define CT_GR_O                        0x3ce   /* Index port of the Graphic Controller Registers */
-#define CT_SR_O                        0x3c4   /* Index port of the Sequencer Controller */
-#define CT_CR_O                        0x3d4   /* Index port of the CRT Controller */
-#define CT_XR_O                        0x3d6   /* Extended Register index */
-#define CT_MSR_W_O             0x3c2   /* Misc. Output Register (write only) */
-#define CT_LUT_MASK_O          0x3c6   /* Color Palette Mask */
-#define CT_LUT_START_O         0x3c8   /* Color Palette Write Mode Index */
-#define CT_LUT_RGB_O           0x3c9   /* Color Palette Data Port */
-#define CT_STATUS_REG0_O       0x3c2   /* Status Register 0 (read only) */
-#define CT_STATUS_REG1_O       0x3da   /* Input Status Register 1 (read only) */
-
-#define CT_FP_O                        0x3d0   /* Index port of the Flat panel Registers */
-#define CT_MR_O                        0x3d2   /* Index Port of the Multimedia Extension */
-
-/* defines for the memory mapped registers */
-#define BR00_o         0x400000        /* Source and Destination Span Register */
-#define BR01_o         0x400004        /* Pattern/Source Expansion Background Color & Transparency Key Register */
-#define BR02_o         0x400008        /* Pattern/Source Expansion Foreground Color Register */
-#define BR03_o         0x40000C        /* Monochrome Source Control Register */
-#define BR04_o         0x400010        /* BitBLT Control Register */
-#define BR05_o         0x400014        /* Pattern Address Registe */
-#define BR06_o         0x400018        /* Source Address Register */
-#define BR07_o         0x40001C        /* Destination Address Register */
-#define BR08_o         0x400020        /* Destination Width & Height Register */
-#define BR09_o         0x400024        /* Source Expansion Background Color & Transparency Key Register */
-#define BR0A_o         0x400028        /* Source Expansion Foreground Color Register */
-
-#define CURSOR_SIZE    0x1000  /* in KByte for HW Cursor */
-#define PATTERN_ADR    (pGD->dprBase + CURSOR_SIZE)    /* pattern Memory after Cursor Memory */
-#define PATTERN_SIZE   8*8*4   /* 4 Bytes per Pixel 8 x 8 Pixel */
-#define ACCELMEMORY    (CURSOR_SIZE + PATTERN_SIZE)    /* reserved Memory for BITBlt and hw cursor */
-
-/* Some Mode definitions */
-#define FB_SYNC_HOR_HIGH_ACT   1       /* horizontal sync high active  */
-#define FB_SYNC_VERT_HIGH_ACT  2       /* vertical sync high active    */
-#define FB_SYNC_EXT            4       /* external sync                */
-#define FB_SYNC_COMP_HIGH_ACT  8       /* composite sync high active   */
-#define FB_SYNC_BROADCAST      16      /* broadcast video timings      */
-                                       /* vtotal = 144d/288n/576i => PAL  */
-                                       /* vtotal = 121d/242n/484i => NTSC */
-#define FB_SYNC_ON_GREEN       32      /* sync on green */
-
-#define FB_VMODE_NONINTERLACED  0      /* non interlaced */
-#define FB_VMODE_INTERLACED    1       /* interlaced   */
-#define FB_VMODE_DOUBLE                2       /* double scan */
-#define FB_VMODE_MASK          255
-
-#define FB_VMODE_YWRAP         256     /* ywrap instead of panning     */
-#define FB_VMODE_SMOOTH_XPAN   512     /* smooth xpan possible (internally used) */
-#define FB_VMODE_CONUPDATE     512     /* don't update x/yoffset       */
-
-#define text                   0
-#define fntwidth               8
-
-/* table for VGA Initialization  */
-typedef struct {
-       const unsigned char reg;
-       const unsigned char val;
-} CT_CFG_TABLE;
-
-/* this table provides some basic initialisations such as Memory Clock etc */
-static CT_CFG_TABLE xreg[] = {
-       {0x09, 0x01},           /* CRT Controller Extensions Enable */
-       {0x0A, 0x02},           /* Frame Buffer Mapping */
-       {0x0B, 0x01},           /* PCI Write Burst support */
-       {0x20, 0x00},           /* BitBLT Configuration */
-       {0x40, 0x03},           /* Memory Access Control */
-       {0x60, 0x00},           /* Video Pin Control */
-       {0x61, 0x00},           /* DPMS Synch control */
-       {0x62, 0x00},           /* GPIO Pin Control */
-       {0x63, 0xBD},           /* GPIO Pin Data */
-       {0x67, 0x00},           /* Pin Tri-State */
-       {0x80, 0x80},           /* Pixel Pipeline Config 0 register */
-       {0xA0, 0x00},           /* Cursor 1 Control Reg */
-       {0xA1, 0x00},           /* Cursor 1 Vertical Extension Reg */
-       {0xA2, 0x00},           /* Cursor 1 Base Address Low */
-       {0xA3, 0x00},           /* Cursor 1 Base Address High */
-       {0xA4, 0x00},           /* Cursor 1 X-Position Low */
-       {0xA5, 0x00},           /* Cursor 1 X-Position High */
-       {0xA6, 0x00},           /* Cursor 1 Y-Position Low */
-       {0xA7, 0x00},           /* Cursor 1 Y-Position High */
-       {0xA8, 0x00},           /* Cursor 2 Control Reg */
-       {0xA9, 0x00},           /* Cursor 2 Vertical Extension Reg */
-       {0xAA, 0x00},           /* Cursor 2 Base Address Low */
-       {0xAB, 0x00},           /* Cursor 2 Base Address High */
-       {0xAC, 0x00},           /* Cursor 2 X-Position Low */
-       {0xAD, 0x00},           /* Cursor 2 X-Position High */
-       {0xAE, 0x00},           /* Cursor 2 Y-Position Low */
-       {0xAF, 0x00},           /* Cursor 2 Y-Position High */
-       {0xC0, 0x7D},           /* Dot Clock 0 VCO M-Divisor */
-       {0xC1, 0x07},           /* Dot Clock 0 VCO N-Divisor */
-       {0xC3, 0x34},           /* Dot Clock 0 Divisor select */
-       {0xC4, 0x55},           /* Dot Clock 1 VCO M-Divisor */
-       {0xC5, 0x09},           /* Dot Clock 1 VCO N-Divisor */
-       {0xC7, 0x24},           /* Dot Clock 1 Divisor select */
-       {0xC8, 0x7D},           /* Dot Clock 2 VCO M-Divisor */
-       {0xC9, 0x07},           /* Dot Clock 2 VCO N-Divisor */
-       {0xCB, 0x34},           /* Dot Clock 2 Divisor select */
-       {0xCC, 0x38},           /* Memory Clock 0 VCO M-Divisor */
-       {0xCD, 0x03},           /* Memory Clock 0 VCO N-Divisor */
-       {0xCE, 0x90},           /* Memory Clock 0 Divisor select */
-       {0xCF, 0x06},           /* Clock Config */
-       {0xD0, 0x0F},           /* Power Down */
-       {0xD1, 0x01},           /* Power Down BitBLT */
-       {0xFF, 0xFF}            /* end of table */
-};
-/* Clock Config:
- * =============
- *
- * PD Registers:
- * -------------
- * Bit2 and Bit4..6 are used for the Loop Divisor and Post Divisor.
- * They are encoded as follows:
- *
- * +---+--------------+
- * | 2 | Loop Divisor |
- * +---+--------------+
- * | 1 | 1            |
- * +---+--------------+
- * | 0 | 4            |
- * +---+--------------+
- * Note: The Memory Clock does not have a Loop Divisor.
- * +---+---+---+--------------+
- * | 6 | 5 | 4 | Post Divisor |
- * +---+---+---+--------------+
- * | 0 | 0 | 0 | 1            |
- * +---+---+---+--------------+
- * | 0 | 0 | 1 | 2            |
- * +---+---+---+--------------+
- * | 0 | 1 | 0 | 4            |
- * +---+---+---+--------------+
- * | 0 | 1 | 1 | 8            |
- * +---+---+---+--------------+
- * | 1 | 0 | 0 | 16           |
- * +---+---+---+--------------+
- * | 1 | 0 | 1 | 32           |
- * +---+---+---+--------------+
- * | 1 | 1 | X | reserved     |
- * +---+---+---+--------------+
- *
- * All other bits are reserved in these registers.
- *
- * Clock VCO M Registers:
- * ----------------------
- * These Registers contain the M Value -2.
- *
- * Clock VCO N Registers:
- * ----------------------
- * These Registers contain the N Value -2.
- *
- * Formulas:
- * ---------
- * Fvco = (Fref * Loop Divisor * M/N), whereas 100MHz < Fvco < 220MHz
- * Fout = Fvco / Post Divisor
- *
- * Dot Clk0 (default 25MHz):
- * -------------------------
- * Fvco = 14.318 * 127 / 9 = 202.045MHz
- * Fout = 202.045MHz / 8 = 25.25MHz
- * Post Divisor = 8
- * Loop Divisor = 1
- * XRC0 = (M - 2) = 125 = 0x7D
- * XRC1 = (N - 2) = 7   = 0x07
- * XRC3 =                 0x34
- *
- * Dot Clk1 (default 28MHz):
- * -------------------------
- * Fvco = 14.318 * 87 / 11 = 113.24MHz
- * Fout = 113.24MHz / 4 = 28.31MHz
- * Post Divisor = 4
- * Loop Divisor = 1
- * XRC4 = (M - 2) = 85 = 0x55
- * XRC5 = (N - 2) = 9  = 0x09
- * XRC7 =                0x24
- *
- * Dot Clk2 (variable for extended modes set to 25MHz):
- * ----------------------------------------------------
- * Fvco = 14.318 * 127 / 9 = 202.045MHz
- * Fout = 202.045MHz / 8 = 25.25MHz
- * Post Divisor = 8
- * Loop Divisor = 1
- * XRC8 = (M - 2) = 125 = 0x7D
- * XRC9 = (N - 2) = 7   = 0x07
- * XRCB =                 0x34
- *
- * Memory Clk for most modes >50MHz:
- * ----------------------------------
- * Fvco = 14.318 * 58 / 5 = 166MHz
- * Fout = 166MHz / 2      = 83MHz
- * Post Divisor = 2
- * XRCC = (M - 2) = 57  = 0x38
- * XRCD = (N - 2) = 3   = 0x03
- * XRCE =                 0x90
- *
- * Note Bit7 enables the clock source from the VCO
- *
- */
-
-/*******************************************************************
- * Chips struct
- *******************************************************************/
-struct ctfb_chips_properties {
-       int device_id;          /* PCI Device ID */
-       unsigned long max_mem;  /* memory for frame buffer */
-       int vld_set;            /* value of VLD if bit2 in clock control is set */
-       int vld_not_set;        /* value of VLD if bit2 in clock control is set */
-       int mn_diff;            /* difference between M/N Value + mn_diff = M/N Register */
-       int mn_min;             /* min value of M/N Value */
-       int mn_max;             /* max value of M/N Value */
-       int vco_min;            /* VCO Min in MHz */
-       int vco_max;            /* VCO Max in MHz */
-};
-
-static const struct ctfb_chips_properties chips[] = {
-       {PCI_DEVICE_ID_CT_69000, 0x200000, 1, 4, -2, 3, 257, 100, 220},
-#ifdef CONFIG_USE_CPCIDVI
-       {PCI_DEVICE_ID_CT_69030, 0x400000, 1, 4, -2, 3, 257, 100, 220},
-#endif
-       {PCI_DEVICE_ID_CT_65555, 0x100000, 16, 4, 0, 1, 255, 48, 220},  /* NOT TESTED */
-       {0, 0, 0, 0, 0, 0, 0, 0, 0}     /* Terminator */
-};
-
-/*
- * The Graphic Device
- */
-GraphicDevice ctfb;
-
-/*******************************************************************************
-*
-* Low Level Routines
-*/
-
-/*******************************************************************************
-*
-* Read CT ISA register
-*/
-#ifdef VGA_DEBUG
-static unsigned char
-ctRead (unsigned short index)
-{
-       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
-       if (index == CT_AR_O)
-               /* synch the Flip Flop */
-               in8 (pGD->isaBase + CT_STATUS_REG1_O);
-
-       return (in8 (pGD->isaBase + index));
-}
-#endif
-/*******************************************************************************
-*
-* Write CT ISA register
-*/
-static void
-ctWrite (unsigned short index, unsigned char val)
-{
-       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
-
-       out8 ((pGD->isaBase + index), val);
-}
-
-/*******************************************************************************
-*
-* Read CT ISA register indexed
-*/
-static unsigned char
-ctRead_i (unsigned short index, char reg)
-{
-       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
-       if (index == CT_AR_O)
-               /* synch the Flip Flop */
-               in8 (pGD->isaBase + CT_STATUS_REG1_O);
-       out8 ((pGD->isaBase + index), reg);
-       return (in8 (pGD->isaBase + index + 1));
-}
-
-/*******************************************************************************
-*
-* Write CT ISA register indexed
-*/
-static void
-ctWrite_i (unsigned short index, char reg, char val)
-{
-       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
-       if (index == CT_AR_O) {
-               /* synch the Flip Flop */
-               in8 (pGD->isaBase + CT_STATUS_REG1_O);
-               out8 ((pGD->isaBase + index), reg);
-               out8 ((pGD->isaBase + index), val);
-       } else {
-               out8 ((pGD->isaBase + index), reg);
-               out8 ((pGD->isaBase + index + 1), val);
-       }
-}
-
-/*******************************************************************************
-*
-* Write a table of CT ISA register
-*/
-static void
-ctLoadRegs (unsigned short index, CT_CFG_TABLE * regTab)
-{
-       while (regTab->reg != 0xFF) {
-               ctWrite_i (index, regTab->reg, regTab->val);
-               regTab++;
-       }
-}
-
-/*****************************************************************************/
-static void
-SetArRegs (void)
-{
-       int i, tmp;
-
-       for (i = 0; i < 0x10; i++)
-               ctWrite_i (CT_AR_O, i, i);
-       if (text)
-               tmp = 0x04;
-       else
-               tmp = 0x41;
-
-       ctWrite_i (CT_AR_O, 0x10, tmp); /* Mode Control Register */
-       ctWrite_i (CT_AR_O, 0x11, 0x00);        /* Overscan Color Register */
-       ctWrite_i (CT_AR_O, 0x12, 0x0f);        /* Memory Plane Enable Register */
-       if (fntwidth == 9)
-               tmp = 0x08;
-       else
-               tmp = 0x00;
-       ctWrite_i (CT_AR_O, 0x13, tmp); /* Horizontal Pixel Panning */
-       ctWrite_i (CT_AR_O, 0x14, 0x00);        /* Color Select Register    */
-       ctWrite (CT_AR_O, 0x20);        /* enable video             */
-}
-
-/*****************************************************************************/
-static void
-SetGrRegs (void)
-{                              /* Set Graphics Mode */
-       int i;
-
-       for (i = 0; i < 0x05; i++)
-               ctWrite_i (CT_GR_O, i, 0);
-       if (text) {
-               ctWrite_i (CT_GR_O, 0x05, 0x10);
-               ctWrite_i (CT_GR_O, 0x06, 0x02);
-       } else {
-               ctWrite_i (CT_GR_O, 0x05, 0x40);
-               ctWrite_i (CT_GR_O, 0x06, 0x05);
-       }
-       ctWrite_i (CT_GR_O, 0x07, 0x0f);
-       ctWrite_i (CT_GR_O, 0x08, 0xff);
-}
-
-/*****************************************************************************/
-static void
-SetSrRegs (void)
-{
-       int tmp = 0;
-
-       ctWrite_i (CT_SR_O, 0x00, 0x00);        /* reset */
-       /*rr( sr, 0x01, tmp );
-          if( fntwidth == 8 ) tmp |= 0x01; else tmp &= ~0x01;
-          wr( sr, 0x01, tmp );  */
-       if (fntwidth == 8)
-               ctWrite_i (CT_SR_O, 0x01, 0x01);        /* Clocking Mode Register */
-       else
-               ctWrite_i (CT_SR_O, 0x01, 0x00);        /* Clocking Mode Register */
-       ctWrite_i (CT_SR_O, 0x02, 0x0f);        /* Enable CPU wr access to given memory plane */
-       ctWrite_i (CT_SR_O, 0x03, 0x00);        /* Character Map Select Register */
-       if (text)
-               tmp = 0x02;
-       else
-               tmp = 0x0e;
-       ctWrite_i (CT_SR_O, 0x04, tmp); /* Enable CPU accesses to the rest of the 256KB
-                                          total VGA memory beyond the first 64KB and set
-                                          fb mapping mode. */
-       ctWrite_i (CT_SR_O, 0x00, 0x03);        /* enable */
-}
-
-/*****************************************************************************/
-static void
-SetBitsPerPixelIntoXrRegs (int bpp)
-{
-       unsigned int n = (bpp >> 3), tmp;       /* only for 15, 8, 16, 24 bpp */
-       static char md[4] = { 0x04, 0x02, 0x05, 0x06 }; /* DisplayColorMode */
-       static char off[4] = { ~0x20, ~0x30, ~0x20, ~0x10 };    /* mask */
-       static char on[4] = { 0x10, 0x00, 0x10, 0x20 }; /* mask */
-       if (bpp == 15)
-               n = 0;
-       tmp = ctRead_i (CT_XR_O, 0x20);
-       tmp &= off[n];
-       tmp |= on[n];
-       ctWrite_i (CT_XR_O, 0x20, tmp); /* BitBLT Configuration */
-       ctWrite_i (CT_XR_O, 0x81, md[n]);
-}
-
-/*****************************************************************************/
-static void
-SetCrRegs (struct ctfb_res_modes *var, int bits_per_pixel)
-{                              /* he -le-   ht|0    hd -ri- hs     -h-      he */
-       unsigned char cr[0x7a];
-       int i, tmp;
-       unsigned int hd, hs, he, ht, hbe;       /* Horizontal.  */
-       unsigned int vd, vs, ve, vt;    /* vertical */
-       unsigned int bpp, wd, dblscan, interlaced, bcast, CrtHalfLine;
-       unsigned int CompSyncCharClkDelay, CompSyncPixelClkDelay;
-       unsigned int NTSC_PAL_HorizontalPulseWidth, BlDelayCtrl;
-       unsigned int HorizontalEqualizationPulses;
-       unsigned int HorizontalSerration1Start, HorizontalSerration2Start;
-
-       const int LineCompare = 0x3ff;
-       unsigned int TextScanLines = 1; /* this is in fact a vertical zoom factor   */
-       unsigned int RAMDAC_BlankPedestalEnable = 0;    /* 1=en-, 0=disable, see XR82 */
-
-       hd = (var->xres) / 8;   /* HDisp.  */
-       hs = (var->xres + var->right_margin) / 8;       /* HsStrt  */
-       he = (var->xres + var->right_margin + var->hsync_len) / 8;      /* HsEnd   */
-       ht = (var->left_margin + var->xres + var->right_margin + var->hsync_len) / 8;   /* HTotal  */
-       hbe = ht - 1;           /* HBlankEnable todo docu wants ht here, but it does not work */
-       /* ve -up-  vt|0    vd -lo- vs     -v-      ve */
-       vd = var->yres;         /* VDisplay   */
-       vs = var->yres + var->lower_margin;     /* VSyncStart */
-       ve = var->yres + var->lower_margin + var->vsync_len;    /* VSyncEnd */
-       vt = var->upper_margin + var->yres + var->lower_margin + var->vsync_len;        /* VTotal  */
-       bpp = bits_per_pixel;
-       dblscan = (var->vmode & FB_VMODE_DOUBLE) ? 1 : 0;
-       interlaced = var->vmode & FB_VMODE_INTERLACED;
-       bcast = var->sync & FB_SYNC_BROADCAST;
-       CrtHalfLine = bcast ? (hd >> 1) : 0;
-       BlDelayCtrl = bcast ? 1 : 0;
-       CompSyncCharClkDelay = 0;       /* 2 bit */
-       CompSyncPixelClkDelay = 0;      /* 3 bit */
-       if (bcast) {
-               NTSC_PAL_HorizontalPulseWidth = 7;      /*( var->hsync_len >> 1 ) + 1 */
-               HorizontalEqualizationPulses = 0;       /* inverse value */
-               HorizontalSerration1Start = 31; /* ( ht >> 1 ) */
-               HorizontalSerration2Start = 89; /* ( ht >> 1 ) */
-       } else {
-               NTSC_PAL_HorizontalPulseWidth = 0;
-               /* 4 bit: hsync pulse width = ( ( CR74[4:0] - CR74[5] )
-                * / 2 ) + 1 --> CR74[4:0] = 2*(hs-1) + CR74[5] */
-               HorizontalEqualizationPulses = 1;       /* inverse value */
-               HorizontalSerration1Start = 0;  /* ( ht >> 1 ) */
-               HorizontalSerration2Start = 0;  /* ( ht >> 1 ) */
-       }
-
-       if (bpp == 15)
-               bpp = 16;
-       wd = var->xres * bpp / 64;      /* double words per line */
-       if (interlaced) {       /* we divide all vertical timings, exept vd */
-               vs >>= 1;
-               ve >>= 1;
-               vt >>= 1;
-       }
-       memset (cr, 0, sizeof (cr));
-       cr[0x00] = 0xff & (ht - 5);
-       cr[0x01] = hd - 1;      /* soll:4f ist 59 */
-       cr[0x02] = hd;
-       cr[0x03] = (hbe & 0x1F) | 0x80; /* hd + ht - hd  */
-       cr[0x04] = hs;
-       cr[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
-       cr[0x06] = (vt - 2) & 0xFF;
-       cr[0x30] = (vt - 2) >> 8;
-       cr[0x07] = ((vt & 0x100) >> 8)
-           | ((vd & 0x100) >> 7)
-           | ((vs & 0x100) >> 6)
-           | ((vs & 0x100) >> 5)
-           | ((LineCompare & 0x100) >> 4)
-           | ((vt & 0x200) >> 4)
-           | ((vd & 0x200) >> 3)
-           | ((vs & 0x200) >> 2);
-       cr[0x08] = 0x00;
-       cr[0x09] = (dblscan << 7)
-           | ((LineCompare & 0x200) >> 3)
-           | ((vs & 0x200) >> 4)
-           | (TextScanLines - 1);
-       cr[0x10] = vs & 0xff;   /* VSyncPulseStart */
-       cr[0x32] = (vs & 0xf00) >> 8;   /* VSyncPulseStart */
-       cr[0x11] = (ve & 0x0f); /* | 0x20;      */
-       cr[0x12] = (vd - 1) & 0xff;     /* LineCount  */
-       cr[0x31] = ((vd - 1) & 0xf00) >> 8;     /* LineCount */
-       cr[0x13] = wd & 0xff;
-       cr[0x41] = (wd & 0xf00) >> 8;
-       cr[0x15] = vs & 0xff;
-       cr[0x33] = (vs & 0xf00) >> 8;
-       cr[0x38] = (0x100 & (ht - 5)) >> 8;
-       cr[0x3C] = 0xc0 & hbe;
-       cr[0x16] = (vt - 1) & 0xff;     /* vbe - docu wants vt here, */
-       cr[0x17] = 0xe3;        /* but it does not work */
-       cr[0x18] = 0xff & LineCompare;
-       cr[0x22] = 0xff;        /* todo? */
-       cr[0x70] = interlaced ? (0x80 | CrtHalfLine) : 0x00;    /* check:0xa6  */
-       cr[0x71] = 0x80 | (RAMDAC_BlankPedestalEnable << 6)
-           | (BlDelayCtrl << 5)
-           | ((0x03 & CompSyncCharClkDelay) << 3)
-           | (0x07 & CompSyncPixelClkDelay);   /* todo: see XR82 */
-       cr[0x72] = HorizontalSerration1Start;
-       cr[0x73] = HorizontalSerration2Start;
-       cr[0x74] = (HorizontalEqualizationPulses << 5)
-           | NTSC_PAL_HorizontalPulseWidth;
-       /* todo: ct69000 has also 0x75-79 */
-       /* now set the registers */
-       for (i = 0; i <= 0x0d; i++) {   /*CR00 .. CR0D */
-               ctWrite_i (CT_CR_O, i, cr[i]);
-       }
-       for (i = 0x10; i <= 0x18; i++) {        /*CR10 .. CR18 */
-               ctWrite_i (CT_CR_O, i, cr[i]);
-       }
-       i = 0x22;               /*CR22 */
-       ctWrite_i (CT_CR_O, i, cr[i]);
-       for (i = 0x30; i <= 0x33; i++) {        /*CR30 .. CR33 */
-               ctWrite_i (CT_CR_O, i, cr[i]);
-       }
-       i = 0x38;               /*CR38 */
-       ctWrite_i (CT_CR_O, i, cr[i]);
-       i = 0x3C;               /*CR3C */
-       ctWrite_i (CT_CR_O, i, cr[i]);
-       for (i = 0x40; i <= 0x41; i++) {        /*CR40 .. CR41 */
-               ctWrite_i (CT_CR_O, i, cr[i]);
-       }
-       for (i = 0x70; i <= 0x74; i++) {        /*CR70 .. CR74 */
-               ctWrite_i (CT_CR_O, i, cr[i]);
-       }
-       tmp = ctRead_i (CT_CR_O, 0x40);
-       tmp &= 0x0f;
-       tmp |= 0x80;
-       ctWrite_i (CT_CR_O, 0x40, tmp); /* StartAddressEnable */
-}
-
-/* pixelclock control */
-
-/*****************************************************************************
- We have a rational number p/q and need an m/n which is very close to p/q
- but has m and n within mnmin and mnmax. We have no floating point in the
- kernel. We can use long long without divide. And we have time to compute...
-******************************************************************************/
-static unsigned int
-FindBestPQFittingMN (unsigned int p, unsigned int q, unsigned int mnmin,
-                    unsigned int mnmax, unsigned int *pm, unsigned int *pn)
-{
-       /* this code is not for general purpose usable but good for our number ranges */
-       unsigned int n = mnmin, m = 0;
-       long long int L = 0, P = p, Q = q, H = P >> 1;
-       long long int D = 0x7ffffffffffffffLL;
-       for (n = mnmin; n <= mnmax; n++) {
-               m = mnmin;      /* p/q ~ m/n -> p*n ~ m*q -> p*n-x*q ~ 0 */
-               L = P * n - m * Q;      /* n * vco - m * fref should be near 0 */
-               while (L > 0 && m < mnmax) {
-                       L -= q; /* difference is greater as 0 subtract fref */
-                       m++;    /* and increment m */
-               }
-               /* difference is less or equal than 0 or m > maximum */
-               if (m > mnmax)
-                       break;  /* no solution: if we increase n we get the same situation */
-               /* L is <= 0 now */
-               if (-L > H && m > mnmin) {      /* if difference > the half fref */
-                       L += q; /* we take the situation before */
-                       m--;    /* because its closer to 0 */
-               }
-               L = (L < 0) ? -L : +L;  /* absolute value */
-               if (D < L)      /* if last difference was better take next n */
-                       continue;
-               D = L;
-               *pm = m;
-               *pn = n;        /*  keep improved data */
-               if (D == 0)
-                       break;  /* best result we can get */
-       }
-       return (unsigned int) (0xffffffff & D);
-}
-
-/* that is the hardware < 69000 we have to manage
- +---------+  +-------------------+  +----------------------+  +--+
- | REFCLK  |__|NTSC Divisor Select|__|FVCO Reference Divisor|__|÷N|__
- | 14.3MHz |  |(NTSCDS) (÷1, Ã·5)  |  |Select (RDS) (÷1, Ã·4) |  |  |  |
- +---------+  +-------------------+  +----------------------+  +--+  |
-  ___________________________________________________________________|
- |
- |                                    fvco                      fout
- | +--------+  +------------+  +-----+     +-------------------+   +----+
- +-| Phase  |__|Charge Pump |__| VCO |_____|Post Divisor (PD)  |___|CLK |--->
- +-| Detect |  |& Filter VCO|  |     |  |  |÷1, 2, 4, 8, 16, 32|   |    |
- | +--------+  +------------+  +-----+  |  +-------------------+   +----+
- |                                      |
- |    +--+   +---------------+          |
- |____|÷M|___|VCO Loop Divide|__________|
-      |  |   |(VLD)(÷4, Ã·16) |
-      +--+   +---------------+
-****************************************************************************
-  that is the hardware >= 69000 we have to manage
- +---------+  +--+
- | REFCLK  |__|÷N|__
- | 14.3MHz |  |  |  |
- +---------+  +--+  |
-  __________________|
- |
- |                                    fvco                      fout
- | +--------+  +------------+  +-----+     +-------------------+   +----+
- +-| Phase  |__|Charge Pump |__| VCO |_____|Post Divisor (PD)  |___|CLK |--->
- +-| Detect |  |& Filter VCO|  |     |  |  |÷1, 2, 4, 8, 16, 32|   |    |
- | +--------+  +------------+  +-----+  |  +-------------------+   +----+
- |                                      |
- |    +--+   +---------------+          |
- |____|÷M|___|VCO Loop Divide|__________|
-      |  |   |(VLD)(÷1, Ã·4)  |
-      +--+   +---------------+
-
-
-*/
-
-#define VIDEO_FREF 14318180;   /* Hz  */
-/*****************************************************************************/
-static int
-ReadPixClckFromXrRegsBack (struct ctfb_chips_properties *param)
-{
-       unsigned int m, n, vld, pd, PD, fref, xr_cb, i, pixclock;
-       i = 0;
-       pixclock = -1;
-       fref = VIDEO_FREF;
-       m = ctRead_i (CT_XR_O, 0xc8);
-       n = ctRead_i (CT_XR_O, 0xc9);
-       m -= param->mn_diff;
-       n -= param->mn_diff;
-       xr_cb = ctRead_i (CT_XR_O, 0xcb);
-       PD = (0x70 & xr_cb) >> 4;
-       pd = 1;
-       for (i = 0; i < PD; i++) {
-               pd *= 2;
-       }
-       vld = (0x04 & xr_cb) ? param->vld_set : param->vld_not_set;
-       if (n * vld * m) {
-               unsigned long long p = 1000000000000LL * pd * n;
-               unsigned long long q = (long long) fref * vld * m;
-               while ((p > 0xffffffffLL) || (q > 0xffffffffLL)) {
-                       p >>= 1;        /* can't divide with long long so we scale down */
-                       q >>= 1;
-               }
-               pixclock = (unsigned) p / (unsigned) q;
-       } else
-               printf ("Invalid data in xr regs.\n");
-       return pixclock;
-}
-
-/*****************************************************************************/
-static void
-FindAndSetPllParamIntoXrRegs (unsigned int pixelclock,
-                             struct ctfb_chips_properties *param)
-{
-       unsigned int m, n, vld, pd, PD, fref, xr_cb;
-       unsigned int fvcomin, fvcomax, pclckmin, pclckmax, pclk;
-       unsigned int pfreq, fvco, new_pixclock;
-       unsigned int D,nback,mback;
-
-       fref = VIDEO_FREF;
-       pd = 1;
-       PD = 0;
-       fvcomin = param->vco_min;
-       fvcomax = param->vco_max;       /* MHz */
-       pclckmin = 1000000 / fvcomax + 1;       /*   4546 */
-       pclckmax = 32000000 / fvcomin - 1;      /* 666665 */
-       pclk = minmax (pclckmin, pixelclock, pclckmax); /* ps pp */
-       pfreq = 250 * (4000000000U / pclk);
-       fvco = pfreq;           /* Hz */
-       new_pixclock = 0;
-       while (fvco < fvcomin * 1000000) {
-               /* double VCO starting with the pixelclock frequency
-                * as long as it is lower than the minimal VCO frequency */
-               fvco *= 2;
-               pd *= 2;
-               PD++;
-       }
-       /* fvco is exactly pd * pixelclock and higher than the ninmal VCO frequency */
-       /* first try */
-       vld = param->vld_set;
-       D=FindBestPQFittingMN (fvco / vld, fref, param->mn_min, param->mn_max, &m, &n); /* rds = 1 */
-       mback=m;
-       nback=n;
-       /* second try */
-       vld = param->vld_not_set;
-       if(D<FindBestPQFittingMN (fvco / vld, fref, param->mn_min, param->mn_max, &m, &n)) {    /* rds = 1 */
-               /* first try was better */
-               m=mback;
-               n=nback;
-               vld = param->vld_set;
-       }
-       m += param->mn_diff;
-       n += param->mn_diff;
-       PRINTF ("VCO %d, pd %d, m %d n %d vld %d \n", fvco, pd, m, n, vld);
-       xr_cb = ((0x7 & PD) << 4) | (vld == param->vld_set ? 0x04 : 0);
-       /* All four of the registers used for dot clock 2 (XRC8 - XRCB) must be
-        * written, and in order from XRC8 to XRCB, before the hardware will
-        * update the synthesizer s settings.
-        */
-       ctWrite_i (CT_XR_O, 0xc8, m);
-       ctWrite_i (CT_XR_O, 0xc9, n);   /* xrca does not exist in CT69000 and CT69030 */
-       ctWrite_i (CT_XR_O, 0xca, 0);   /* because of a hw bug I guess, but we write */
-       ctWrite_i (CT_XR_O, 0xcb, xr_cb);       /* 0 to it for savety */
-       new_pixclock = ReadPixClckFromXrRegsBack (param);
-       PRINTF ("pixelclock.set = %d, pixelclock.real = %d \n",
-               pixelclock, new_pixclock);
-}
-
-/*****************************************************************************/
-static void
-SetMsrRegs (struct ctfb_res_modes *mode)
-{
-       unsigned char h_synch_high, v_synch_high;
-
-       h_synch_high = (mode->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 0x40;  /* horizontal Synch High active */
-       v_synch_high = (mode->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 0x80; /* vertical Synch High active */
-       ctWrite (CT_MSR_W_O, (h_synch_high | v_synch_high | 0x29));
-       /* upper64K==0x20, CLC2select==0x08, RAMenable==0x02!(todo), CGA==0x01
-        * Selects the upper 64KB page.Bit5=1
-        * CLK2 (left reserved in standard VGA) Bit3|2=1|0
-        * Disables CPU access to frame buffer. Bit1=0
-        * Sets the I/O address decode for ST01, FCR, and all CR registers
-        * to the 3Dx I/O address range (CGA emulation). Bit0=1
-        */
-}
-
-/************************************************************************************/
-#ifdef VGA_DUMP_REG
-
-static void
-ctDispRegs (unsigned short index, int from, int to)
-{
-       unsigned char status;
-       int i;
-
-       for (i = from; i < to; i++) {
-               status = ctRead_i (index, i);
-               printf ("%02X: is %02X\n", i, status);
-       }
-}
-
-void
-video_dump_reg (void)
-{
-       int i;
-
-       printf ("Extended Regs:\n");
-       ctDispRegs (CT_XR_O, 0, 0xC);
-       ctDispRegs (CT_XR_O, 0xe, 0xf);
-       ctDispRegs (CT_XR_O, 0x20, 0x21);
-       ctDispRegs (CT_XR_O, 0x40, 0x50);
-       ctDispRegs (CT_XR_O, 0x60, 0x64);
-       ctDispRegs (CT_XR_O, 0x67, 0x68);
-       ctDispRegs (CT_XR_O, 0x70, 0x72);
-       ctDispRegs (CT_XR_O, 0x80, 0x83);
-       ctDispRegs (CT_XR_O, 0xA0, 0xB0);
-       ctDispRegs (CT_XR_O, 0xC0, 0xD3);
-       printf ("Sequencer Regs:\n");
-       ctDispRegs (CT_SR_O, 0, 0x8);
-       printf ("Graphic Regs:\n");
-       ctDispRegs (CT_GR_O, 0, 0x9);
-       printf ("CRT Regs:\n");
-       ctDispRegs (CT_CR_O, 0, 0x19);
-       ctDispRegs (CT_CR_O, 0x22, 0x23);
-       ctDispRegs (CT_CR_O, 0x30, 0x34);
-       ctDispRegs (CT_CR_O, 0x38, 0x39);
-       ctDispRegs (CT_CR_O, 0x3C, 0x3D);
-       ctDispRegs (CT_CR_O, 0x40, 0x42);
-       ctDispRegs (CT_CR_O, 0x70, 0x80);
-       /* don't display the attributes */
-}
-
-#endif
-
-#ifdef CONFIG_VIDEO_HW_CURSOR
-/***************************************************************
- * Set Hardware Cursor in Pixel
- */
-void
-video_set_hw_cursor (int x, int y)
-{
-       int sig_x = 0, sig_y = 0;
-       if (x < 0) {
-               x *= -1;
-               sig_x = 1;
-       }
-       if (y < 0) {
-               y *= -1;
-               sig_y = 1;
-       }
-       ctWrite_i (CT_XR_O, 0xa4, x & 0xff);
-       ctWrite_i (CT_XR_O, 0xa5, (x >> 8) & 0x7);
-       ctWrite_i (CT_XR_O, 0xa6, y & 0xff);
-       ctWrite_i (CT_XR_O, 0xa7, (y >> 8) & 0x7);
-}
-
-/***************************************************************
- * Init Hardware Cursor. To know the size of the Cursor,
- * we have to know the Font size.
- */
-void
-video_init_hw_cursor (int font_width, int font_height)
-{
-       unsigned char xr_80;
-       unsigned long *curs, pattern;
-       int i;
-       int cursor_start;
-       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
-
-       cursor_start = pGD->dprBase;
-       xr_80 = ctRead_i (CT_XR_O, 0x80);
-       /* set start address */
-       ctWrite_i (CT_XR_O, 0xa2, (cursor_start >> 8) & 0xf0);
-       ctWrite_i (CT_XR_O, 0xa3, (cursor_start >> 16) & 0x3f);
-       /* set cursor shape */
-       curs = (unsigned long *) cursor_start;
-       i = 0;
-       while (i < 0x400) {
-               curs[i++] = 0xffffffff; /* AND mask */
-               curs[i++] = 0xffffffff; /* AND mask */
-               curs[i++] = 0;  /* XOR mask */
-               curs[i++] = 0;  /* XOR mask */
-               /* Transparent */
-       }
-       pattern = 0xffffffff >> font_width;
-       i = 0;
-       while (i < (font_height * 2)) {
-               curs[i++] = pattern;    /* AND mask */
-               curs[i++] = pattern;    /* AND mask */
-               curs[i++] = 0;  /* XOR mask */
-               curs[i++] = 0;  /* XOR mask */
-               /* Cursor Color 0 */
-       }
-       /* set blink rate */
-       ctWrite_i (CT_FP_O, 0x19, 0xf);
-
-       /* set cursors colors */
-       xr_80 = ctRead_i (CT_XR_O, 0x80);
-       xr_80 |= 0x1;           /* alternate palette select */
-       ctWrite_i (CT_XR_O, 0x80, xr_80);
-       video_set_lut (4, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL);
-       /* position 4 is color 0 cursor 0 */
-       xr_80 &= 0xfe;          /* normal palette select */
-       ctWrite_i (CT_XR_O, 0x80, xr_80);
-       /* cursor enable */
-       ctWrite_i (CT_XR_O, 0xa0, 0x91);
-       xr_80 |= 0x10;          /* enable hwcursor */
-       ctWrite_i (CT_XR_O, 0x80, xr_80);
-       video_set_hw_cursor (0, 0);
-}
-#endif                         /* CONFIG_VIDEO_HW_CURSOR */
-
-/***************************************************************
- * Wait for BitBlt ready
- */
-static int
-video_wait_bitblt (unsigned long addr)
-{
-       unsigned long br04;
-       int i = 0;
-       br04 = in32r (addr);
-       while (br04 & 0x80000000) {
-               udelay (1);
-               br04 = in32r (addr);
-               if (i++ > 1000000) {
-                       printf ("ERROR Timeout %lx\n", br04);
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-/***************************************************************
- * Set up BitBlt Registrs
- */
-static void
-SetDrawingEngine (int bits_per_pixel)
-{
-       unsigned long br04, br00;
-       unsigned char tmp;
-
-       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
-
-       tmp = ctRead_i (CT_XR_O, 0x20); /* BitBLT Configuration */
-       tmp |= 0x02;            /* reset BitBLT */
-       ctWrite_i (CT_XR_O, 0x20, tmp); /* BitBLT Configuration */
-       udelay (10);
-       tmp &= 0xfd;            /* release reset BitBLT */
-       ctWrite_i (CT_XR_O, 0x20, tmp); /* BitBLT Configuration */
-       video_wait_bitblt (pGD->pciBase + BR04_o);
-
-       /* set pattern Address */
-       out32r (pGD->pciBase + BR05_o, PATTERN_ADR & 0x003ffff8);
-       br04 = 0;
-       if (bits_per_pixel == 1) {
-               br04 |= 0x00040000;     /* monochome Pattern */
-               br04 |= 0x00001000;     /* monochome source */
-       }
-       br00 = ((pGD->winSizeX * pGD->gdfBytesPP) << 16) + (pGD->winSizeX * pGD->gdfBytesPP);   /* bytes per scanline */
-       out32r (pGD->pciBase + BR00_o, br00);   /* */
-       out32r (pGD->pciBase + BR08_o, (10 << 16) + 10);        /* dummy */
-       out32r (pGD->pciBase + BR04_o, br04);   /* write all 0 */
-       out32r (pGD->pciBase + BR07_o, 0);      /* destination */
-       video_wait_bitblt (pGD->pciBase + BR04_o);
-}
-
-/****************************************************************************
-* supported Video Chips
-*/
-static struct pci_device_id supported[] = {
-       {PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69000},
-#ifdef CONFIG_USE_CPCIDVI
-       {PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69030},
-#endif
-       {}
-};
-
-/*******************************************************************************
-*
-* Init video chip
-*/
-void *
-video_hw_init (void)
-{
-       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
-       unsigned short device_id;
-       pci_dev_t devbusfn;
-       int videomode;
-       unsigned long t1, hsynch, vsynch;
-       unsigned int pci_mem_base, *vm;
-       int tmp, i, bits_per_pixel;
-       char *penv;
-       struct ctfb_res_modes *res_mode;
-       struct ctfb_res_modes var_mode;
-       struct ctfb_chips_properties *chips_param;
-       /* Search for video chip */
-
-       if ((devbusfn = pci_find_devices (supported, 0)) < 0) {
-#ifdef CONFIG_VIDEO_ONBOARD
-               printf ("Video: Controller not found !\n");
-#endif
-               return (NULL);
-       }
-
-       /* PCI setup */
-       pci_write_config_dword (devbusfn, PCI_COMMAND,
-                               (PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
-       pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
-       pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
-       pci_mem_base = pci_mem_to_phys (devbusfn, pci_mem_base);
-
-       /* get chips params */
-       for (chips_param = (struct ctfb_chips_properties *) &chips[0];
-            chips_param->device_id != 0; chips_param++) {
-               if (chips_param->device_id == device_id)
-                       break;
-       }
-       if (chips_param->device_id == 0) {
-#ifdef CONFIG_VIDEO_ONBOARD
-               printf ("Video: controller 0x%X not supported\n", device_id);
-#endif
-               return NULL;
-       }
-       /* supported Video controller found */
-       printf ("Video: ");
-
-       tmp = 0;
-       videomode = 0x301;
-       /* get video mode via environment */
-       if ((penv = getenv ("videomode")) != NULL) {
-               /* deceide if it is a string */
-               if (penv[0] <= '9') {
-                       videomode = (int) simple_strtoul (penv, NULL, 16);
-                       tmp = 1;
-               }
-       } else {
-               tmp = 1;
-       }
-       if (tmp) {
-               /* parameter are vesa modes */
-               /* search params */
-               for (i = 0; i < VESA_MODES_COUNT; i++) {
-                       if (vesa_modes[i].vesanr == videomode)
-                               break;
-               }
-               if (i == VESA_MODES_COUNT) {
-                       printf ("no VESA Mode found, switching to mode 0x301 ");
-                       i = 0;
-               }
-               res_mode =
-                   (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].
-                                                            resindex];
-               bits_per_pixel = vesa_modes[i].bits_per_pixel;
-       } else {
-
-               res_mode = (struct ctfb_res_modes *) &var_mode;
-               bits_per_pixel = video_get_params (res_mode, penv);
-       }
-
-       /* calculate available color depth for controller memory */
-       if (bits_per_pixel == 15)
-               tmp = 2;
-       else
-               tmp = bits_per_pixel >> 3;      /* /8 */
-       if (((chips_param->max_mem -
-             ACCELMEMORY) / (res_mode->xres * res_mode->yres)) < tmp) {
-               tmp =
-                   ((chips_param->max_mem -
-                     ACCELMEMORY) / (res_mode->xres * res_mode->yres));
-               if (tmp == 0) {
-                       printf
-                           ("No matching videomode found .-> reduce resolution\n");
-                       return NULL;
-               } else {
-                       printf ("Switching back to %d Bits per Pixel ",
-                               tmp << 3);
-                       bits_per_pixel = tmp << 3;
-               }
-       }
-
-       /* calculate hsynch and vsynch freq (info only) */
-       t1 = (res_mode->left_margin + res_mode->xres +
-             res_mode->right_margin + res_mode->hsync_len) / 8;
-       t1 *= 8;
-       t1 *= res_mode->pixclock;
-       t1 /= 1000;
-       hsynch = 1000000000L / t1;
-       t1 *=
-           (res_mode->upper_margin + res_mode->yres +
-            res_mode->lower_margin + res_mode->vsync_len);
-       t1 /= 1000;
-       vsynch = 1000000000L / t1;
-
-       /* fill in Graphic device struct */
-       sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
-                res_mode->yres, bits_per_pixel, (hsynch / 1000),
-                (vsynch / 1000));
-       printf ("%s\n", pGD->modeIdent);
-       pGD->winSizeX = res_mode->xres;
-       pGD->winSizeY = res_mode->yres;
-       pGD->plnSizeX = res_mode->xres;
-       pGD->plnSizeY = res_mode->yres;
-       switch (bits_per_pixel) {
-       case 8:
-               pGD->gdfBytesPP = 1;
-               pGD->gdfIndex = GDF__8BIT_INDEX;
-               break;
-       case 15:
-               pGD->gdfBytesPP = 2;
-               pGD->gdfIndex = GDF_15BIT_555RGB;
-               break;
-       case 16:
-               pGD->gdfBytesPP = 2;
-               pGD->gdfIndex = GDF_16BIT_565RGB;
-               break;
-       case 24:
-               pGD->gdfBytesPP = 3;
-               pGD->gdfIndex = GDF_24BIT_888RGB;
-               break;
-       }
-       pGD->isaBase = CFG_ISA_IO_BASE_ADDRESS;
-       pGD->pciBase = pci_mem_base;
-       pGD->frameAdrs = pci_mem_base;
-       pGD->memSize = chips_param->max_mem;
-       /* Cursor Start Address */
-       pGD->dprBase =
-           (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + pci_mem_base;
-       if ((pGD->dprBase & 0x0fff) != 0) {
-               /* allign it */
-               pGD->dprBase &= 0xfffff000;
-               pGD->dprBase += 0x00001000;
-       }
-       PRINTF ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
-               PATTERN_ADR);
-       pGD->vprBase = pci_mem_base;    /* Dummy */
-       pGD->cprBase = pci_mem_base;    /* Dummy */
-       /* set up Hardware */
-
-#ifdef CONFIG_USE_CPCIDVI
-       if (device_id == PCI_DEVICE_ID_CT_69030) {
-               ctWrite (CT_MSR_W_O, 0x0b);
-               ctWrite (0x3cd, 0x13);
-               ctWrite_i (CT_FP_O, 0x02, 0x00);
-               ctWrite_i (CT_FP_O, 0x05, 0x00);
-               ctWrite_i (CT_FP_O, 0x06, 0x00);
-               ctWrite (0x3c2, 0x0b);
-               ctWrite_i (CT_FP_O, 0x02, 0x10);
-               ctWrite_i (CT_FP_O, 0x01, 0x09);
-       } else {
-               ctWrite (CT_MSR_W_O, 0x01);
-       }
-#else
-       ctWrite (CT_MSR_W_O, 0x01);
-#endif
-
-       /* set the extended Registers */
-       ctLoadRegs (CT_XR_O, xreg);
-       /* set atribute registers */
-       SetArRegs ();
-       /* set Graphics register */
-       SetGrRegs ();
-       /* set sequencer */
-       SetSrRegs ();
-
-       /* set msr */
-       SetMsrRegs (res_mode);
-
-       /* set CRT Registers */
-       SetCrRegs (res_mode, bits_per_pixel);
-       /* set color mode */
-       SetBitsPerPixelIntoXrRegs (bits_per_pixel);
-
-       /* set PLL */
-       FindAndSetPllParamIntoXrRegs (res_mode->pixclock, chips_param);
-
-       ctWrite_i (CT_SR_O, 0, 0x03);   /* clear synchronous reset */
-       /* Clear video memory */
-       i = pGD->memSize / 4;
-       vm = (unsigned int *) pGD->pciBase;
-       while (i--)
-               *vm++ = 0;
-       SetDrawingEngine (bits_per_pixel);
-#ifdef VGA_DUMP_REG
-       video_dump_reg ();
-#endif
-
-       return ((void *) &ctfb);
-}
-
- /*******************************************************************************
-*
-* Set a RGB color in the LUT (8 bit index)
-*/
-void
-video_set_lut (unsigned int index,     /* color number */
-              unsigned char r, /* red */
-              unsigned char g, /* green */
-              unsigned char b  /* blue */
-    )
-{
-
-       ctWrite (CT_LUT_MASK_O, 0xff);
-
-       ctWrite (CT_LUT_START_O, (char) index);
-
-       ctWrite (CT_LUT_RGB_O, r);      /* red */
-       ctWrite (CT_LUT_RGB_O, g);      /* green */
-       ctWrite (CT_LUT_RGB_O, b);      /* blue */
-       udelay (1);
-       ctWrite (CT_LUT_MASK_O, 0xff);
-}
-
-/*******************************************************************************
-*
-* Drawing engine fill on screen region
-*/
-void
-video_hw_rectfill (unsigned int bpp,   /* bytes per pixel */
-                  unsigned int dst_x,  /* dest pos x */
-                  unsigned int dst_y,  /* dest pos y */
-                  unsigned int dim_x,  /* frame width */
-                  unsigned int dim_y,  /* frame height */
-                  unsigned int color   /* fill color */
-    )
-{
-       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
-       unsigned long *p, br04;
-
-       video_wait_bitblt (pGD->pciBase + BR04_o);
-
-       p = (unsigned long *) PATTERN_ADR;
-       dim_x *= bpp;
-       if (bpp == 3)
-               bpp++;          /* 24Bit needs a 32bit pattern */
-       memset (p, color, (bpp * sizeof (unsigned char) * 8 * 8));      /* 8 x 8 pattern data */
-       out32r (pGD->pciBase + BR07_o, ((pGD->winSizeX * dst_y) + dst_x) * pGD->gdfBytesPP);    /* destination */
-       br04 = in32r (pGD->pciBase + BR04_o) & 0xffffff00;
-       br04 |= 0xF0;           /* write Pattern P -> D */
-       out32r (pGD->pciBase + BR04_o, br04);   /* */
-       out32r (pGD->pciBase + BR08_o, (dim_y << 16) + dim_x);  /* starts the BITBlt */
-       video_wait_bitblt (pGD->pciBase + BR04_o);
-}
-
-/*******************************************************************************
-*
-* Drawing engine bitblt with screen region
-*/
-void
-video_hw_bitblt (unsigned int bpp,     /* bytes per pixel */
-                unsigned int src_x,    /* source pos x */
-                unsigned int src_y,    /* source pos y */
-                unsigned int dst_x,    /* dest pos x */
-                unsigned int dst_y,    /* dest pos y */
-                unsigned int dim_x,    /* frame width */
-                unsigned int dim_y     /* frame height */
-    )
-{
-       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
-       unsigned long br04;
-
-       br04 = in32r (pGD->pciBase + BR04_o);
-
-       /* to prevent data corruption due to overlap, we have to
-        * find out if, and how the frames overlaps */
-       if (src_x < dst_x) {
-               /* src is more left than dest
-                * the frame may overlap -> start from right to left */
-               br04 |= 0x00000100;     /* set bit 8 */
-               src_x += dim_x;
-               dst_x += dim_x;
-       } else {
-               br04 &= 0xfffffeff;     /* clear bit 8 left to right */
-       }
-       if (src_y < dst_y) {
-               /* src is higher than dst
-                * the frame may overlap => start from bottom */
-               br04 |= 0x00000200;     /* set bit 9 */
-               src_y += dim_y;
-               dst_y += dim_y;
-       } else {
-               br04 &= 0xfffffdff;     /* clear bit 9 top to bottom */
-       }
-       dim_x *= bpp;
-       out32r (pGD->pciBase + BR06_o, ((pGD->winSizeX * src_y) + src_x) * pGD->gdfBytesPP);    /* source */
-       out32r (pGD->pciBase + BR07_o, ((pGD->winSizeX * dst_y) + dst_x) * pGD->gdfBytesPP);    /* destination */
-       br04 &= 0xffffff00;
-       br04 |= 0x000000CC;     /* S -> D */
-       out32r (pGD->pciBase + BR04_o, br04);   /* */
-       out32r (pGD->pciBase + BR08_o, (dim_y << 16) + dim_x);  /* start the BITBlt */
-       video_wait_bitblt (pGD->pciBase + BR04_o);
-}
-
-#endif                         /* CONFIG_CT69000 */
-
-#endif                         /* CONFIG_VIDEO */
diff --git a/drivers/dataflash.c b/drivers/dataflash.c
deleted file mode 100644 (file)
index 91903c8..0000000
+++ /dev/null
@@ -1,507 +0,0 @@
-/* LowLevel function for ATMEL DataFlash support
- * Author : Hamid Ikdoumi (Atmel)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- */
-#include <common.h>
-#include <config.h>
-#ifdef CONFIG_HAS_DATAFLASH
-#include <asm/hardware.h>
-#include <dataflash.h>
-
-AT91S_DATAFLASH_INFO dataflash_info[CFG_MAX_DATAFLASH_BANKS];
-static AT91S_DataFlash DataFlashInst;
-
-#ifdef CONFIG_AT91SAM9260EK
-int cs[][CFG_MAX_DATAFLASH_BANKS] = {
-       {CFG_DATAFLASH_LOGIC_ADDR_CS0, 0},      /* Logical adress, CS */
-       {CFG_DATAFLASH_LOGIC_ADDR_CS1, 1}
-};
-#elif defined(CONFIG_AT91SAM9263EK)
-int cs[][CFG_MAX_DATAFLASH_BANKS] = {
-       {CFG_DATAFLASH_LOGIC_ADDR_CS0, 0}       /* Logical adress, CS */
-};
-#else
-int cs[][CFG_MAX_DATAFLASH_BANKS] = {
-       {CFG_DATAFLASH_LOGIC_ADDR_CS0, 0},      /* Logical adress, CS */
-       {CFG_DATAFLASH_LOGIC_ADDR_CS3, 3}
-};
-#endif
-
-/*define the area offsets*/
-#if defined(CONFIG_AT91SAM9261EK) || defined(CONFIG_AT91SAM9260EK) || defined(CONFIG_AT91SAM9263EK)
-#if    defined(CONFIG_NEW_PARTITION)
-dataflash_protect_t area_list[NB_DATAFLASH_AREA] = {
-       {0x00000000,    0x00003FFF,     FLAG_PROTECT_SET,       0,              "Bootstrap"},   /* ROM code */
-       {0x00004200,    0x000083FF,     FLAG_PROTECT_CLEAR,     0,              "Environment"}, /* u-boot environment */
-       {0x00008400,    0x0003DDFF,     FLAG_PROTECT_SET,       0,              "U-Boot"},      /* u-boot code */
-       {0x0003DE00,    0x00041FFF,     FLAG_PROTECT_CLEAR,     FLAG_SETENV,    "MON"},         /* Room for alternative boot monitor */
-       {0x00042000,    0x0018BFFF,     FLAG_PROTECT_CLEAR,     FLAG_SETENV,    "OS"},          /* data area size to tune */
-       {0x0018C000,    0xFFFFFFFF,     FLAG_PROTECT_CLEAR,     FLAG_SETENV,    "FS"},          /* data area size to tune */
-};
-#else
-dataflash_protect_t area_list[NB_DATAFLASH_AREA] = {
-       {0, 0x3fff, FLAG_PROTECT_SET},                  /* ROM code */
-       {0x4000, 0x7fff, FLAG_PROTECT_CLEAR},           /* u-boot environment */
-       {0x8000, 0x37fff, FLAG_PROTECT_SET},            /* u-boot code */
-       {0x38000, 0x1fffff, FLAG_PROTECT_CLEAR},        /* data area size to tune */
-};
-#endif
-#elif defined(CONFIG_NEW_PARTITION)
-/*define the area offsets*/
-/* Invalid partitions should be defined with start > end */
-dataflash_protect_t area_list[NB_DATAFLASH_AREA*CFG_MAX_DATAFLASH_BANKS] = {
-       {0x00000000, 0x000083ff, FLAG_PROTECT_SET,      0,              "Bootstrap"},   /* ROM code */
-       {0x00008400, 0x00020fff, FLAG_PROTECT_SET,      0,              "U-Boot"},      /* u-boot code */
-       {0x00021000, 0x000293ff, FLAG_PROTECT_CLEAR,    0,              "Environment"}, /* u-boot environment 8Kb */
-       {0x00029400, 0x00041fff, FLAG_PROTECT_INVALID,  0,              "<Unused>"},    /* Rest of Sector 1 */
-       {0x00042000, 0x0018Bfff, FLAG_PROTECT_CLEAR,    FLAG_SETENV,    "OS"},  /* data area size to tune */
-       {0x0018C000, 0xffffffff, FLAG_PROTECT_CLEAR,    FLAG_SETENV,    "FS"},  /* data area size to tune */
-
-       {0x00000000, 0xffffffff, FLAG_PROTECT_CLEAR,    FLAG_SETENV,    "Data"},        /* data area */
-       {0xffffffff, 0x00000000, FLAG_PROTECT_INVALID,  0,              "<Invalid>"},   /* Invalid */
-       {0xffffffff, 0x00000000, FLAG_PROTECT_INVALID,  0,              "<Invalid>"},   /* Invalid */
-       {0xffffffff, 0x00000000, FLAG_PROTECT_INVALID,  0,              "<Invalid>"},   /* Invalid */
-       {0xffffffff, 0x00000000, FLAG_PROTECT_INVALID,  0,              "<Invalid>"},   /* Invalid */
-       {0xffffffff, 0x00000000, FLAG_PROTECT_INVALID,  0,              "<Invalid>"},   /* Invalid */
-};
-#else
-dataflash_protect_t area_list[NB_DATAFLASH_AREA] = {
-       {0, 0x7fff, FLAG_PROTECT_SET},                  /* ROM code */
-       {0x8000, 0x1ffff, FLAG_PROTECT_SET},            /* u-boot code */
-       {0x20000, 0x27fff, FLAG_PROTECT_CLEAR},         /* u-boot environment */
-       {0x28000, 0x1fffff, FLAG_PROTECT_CLEAR},        /* data area size to tune */
-};
-#endif
-
-extern void AT91F_SpiInit (void);
-extern int AT91F_DataflashProbe (int i, AT91PS_DataflashDesc pDesc);
-extern int AT91F_DataFlashRead (AT91PS_DataFlash pDataFlash,
-                               unsigned long addr,
-                               unsigned long size, char *buffer);
-extern int AT91F_DataFlashWrite( AT91PS_DataFlash pDataFlash,
-                               unsigned char *src,
-                               int dest,
-                               int size );
-
-int AT91F_DataflashInit (void)
-{
-       int i, j;
-       int dfcode;
-       int part = 0;
-       int last_part;
-       int found[CFG_MAX_DATAFLASH_BANKS];
-       unsigned char protected;
-
-       AT91F_SpiInit ();
-
-       for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
-               found[i] = 0;
-               dataflash_info[i].Desc.state = IDLE;
-               dataflash_info[i].id = 0;
-               dataflash_info[i].Device.pages_number = 0;
-               dfcode = AT91F_DataflashProbe (cs[i][1],
-                               &dataflash_info[i].Desc);
-
-               switch (dfcode) {
-               case AT45DB161:
-                       dataflash_info[i].Device.pages_number = 4096;
-                       dataflash_info[i].Device.pages_size = 528;
-                       dataflash_info[i].Device.page_offset = 10;
-                       dataflash_info[i].Device.byte_mask = 0x300;
-                       dataflash_info[i].Device.cs = cs[i][1];
-                       dataflash_info[i].Desc.DataFlash_state = IDLE;
-                       dataflash_info[i].logical_address = cs[i][0];
-                       dataflash_info[i].id = dfcode;
-                       found[i] += dfcode;;
-                       break;
-
-               case AT45DB321:
-                       dataflash_info[i].Device.pages_number = 8192;
-                       dataflash_info[i].Device.pages_size = 528;
-                       dataflash_info[i].Device.page_offset = 10;
-                       dataflash_info[i].Device.byte_mask = 0x300;
-                       dataflash_info[i].Device.cs = cs[i][1];
-                       dataflash_info[i].Desc.DataFlash_state = IDLE;
-                       dataflash_info[i].logical_address = cs[i][0];
-                       dataflash_info[i].id = dfcode;
-                       found[i] += dfcode;;
-                       break;
-
-               case AT45DB642:
-                       dataflash_info[i].Device.pages_number = 8192;
-                       dataflash_info[i].Device.pages_size = 1056;
-                       dataflash_info[i].Device.page_offset = 11;
-                       dataflash_info[i].Device.byte_mask = 0x700;
-                       dataflash_info[i].Device.cs = cs[i][1];
-                       dataflash_info[i].Desc.DataFlash_state = IDLE;
-                       dataflash_info[i].logical_address = cs[i][0];
-                       dataflash_info[i].id = dfcode;
-                       found[i] += dfcode;;
-                       break;
-
-               case AT45DB128:
-                       dataflash_info[i].Device.pages_number = 16384;
-                       dataflash_info[i].Device.pages_size = 1056;
-                       dataflash_info[i].Device.page_offset = 11;
-                       dataflash_info[i].Device.byte_mask = 0x700;
-                       dataflash_info[i].Device.cs = cs[i][1];
-                       dataflash_info[i].Desc.DataFlash_state = IDLE;
-                       dataflash_info[i].logical_address = cs[i][0];
-                       dataflash_info[i].id = dfcode;
-                       found[i] += dfcode;;
-                       break;
-
-               default:
-                       dfcode = 0;
-                       break;
-               }
-               /* set the last area end to the dataflash size*/
-               area_list[NB_DATAFLASH_AREA -1].end =
-                               (dataflash_info[i].Device.pages_number *
-                               dataflash_info[i].Device.pages_size)-1;
-
-               last_part=0;
-               /* set the area addresses */
-               for(j = 0; j<NB_DATAFLASH_AREA; j++) {
-                       if(found[i]!=0) {
-                               dataflash_info[i].Device.area_list[j].start =
-                                       area_list[part].start +
-                                       dataflash_info[i].logical_address;
-                               if(area_list[part].end == 0xffffffff) {
-                                       dataflash_info[i].Device.area_list[j].end =
-                                               dataflash_info[i].end_address +
-                                               dataflash_info  [i].logical_address;
-                                       last_part = 1;
-                               } else {
-                                       dataflash_info[i].Device.area_list[j].end =
-                                               area_list[part].end +
-                                               dataflash_info[i].logical_address;
-                               }
-                               protected = area_list[part].protected;
-                               /* Set the environment according to the label...*/
-                               if(protected == FLAG_PROTECT_INVALID) {
-                                       dataflash_info[i].Device.area_list[j].protected =
-                                               FLAG_PROTECT_INVALID;
-                               } else {
-                                       dataflash_info[i].Device.area_list[j].protected =
-                                               protected;
-                               }
-                               strcpy((char*)(dataflash_info[i].Device.area_list[j].label),
-                                               (const char *)area_list[part].label);
-                       }
-                       part++;
-               }
-       }
-       return found[0];
-}
-
-#ifdef CONFIG_NEW_DF_PARTITION
-int AT91F_DataflashSetEnv (void)
-{
-       int i, j;
-       int part;
-       unsigned char env;
-       unsigned char s[32];    /* Will fit a long int in hex */
-       unsigned long start;
-       for (i = 0, part= 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
-               for(j = 0; j<NB_DATAFLASH_AREA; j++) {
-                       env = area_list[part].setenv;
-                       /* Set the environment according to the label...*/
-                       if((env & FLAG_SETENV) == FLAG_SETENV) {
-                               start =
-                               dataflash_info[i].Device.area_list[j].start;
-                               sprintf(s,"%X",start);
-                               setenv(area_list[part].label,s);
-                       }
-                       part++;
-               }
-       }
-}
-#endif
-
-void dataflash_print_info (void)
-{
-       int i, j;
-
-       for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
-               if (dataflash_info[i].id != 0) {
-                       printf("DataFlash:");
-                       switch (dataflash_info[i].id) {
-                       case AT45DB161:
-                               printf("AT45DB161\n");
-                               break;
-
-                       case AT45DB321:
-                               printf("AT45DB321\n");
-                               break;
-
-                       case AT45DB642:
-                               printf("AT45DB642\n");
-                               break;
-                       case AT45DB128:
-                               printf("AT45DB128\n");
-                               break;
-                       }
-
-                       printf("Nb pages: %6d\n"
-                               "Page Size: %6d\n"
-                               "Size=%8d bytes\n"
-                               "Logical address: 0x%08X\n",
-                               (unsigned int) dataflash_info[i].Device.pages_number,
-                               (unsigned int) dataflash_info[i].Device.pages_size,
-                               (unsigned int) dataflash_info[i].Device.pages_number *
-                               dataflash_info[i].Device.pages_size,
-                               (unsigned int) dataflash_info[i].logical_address);
-                       for (j=0; j< NB_DATAFLASH_AREA; j++) {
-                               switch(dataflash_info[i].Device.area_list[j].protected) {
-                               case    FLAG_PROTECT_SET:
-                               case    FLAG_PROTECT_CLEAR:
-                                       printf("Area %i:\t%08lX to %08lX %s", j,
-                                               dataflash_info[i].Device.area_list[j].start,
-                                               dataflash_info[i].Device.area_list[j].end,
-                                               (dataflash_info[i].Device.area_list[j].protected==FLAG_PROTECT_SET) ? "(RO)" : "    ");
-#ifdef CONFIG_NEW_DF_PARTITION
-                                               printf(" %s\n", dataflash_info[i].Device.area_list[j].label);
-#else
-                                               printf("\n");
-#endif
-                                       break;
-#ifdef CONFIG_NEW_DF_PARTITION
-                               case    FLAG_PROTECT_INVALID:
-                                       break;
-#endif
-                               }
-                       }
-               }
-       }
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* Function Name       : AT91F_DataflashSelect                                      */
-/* Object              : Select the correct device                          */
-/*---------------------------------------------------------------------------*/
-AT91PS_DataFlash AT91F_DataflashSelect (AT91PS_DataFlash pFlash,
-                               unsigned long *addr)
-{
-       char addr_valid = 0;
-       int i;
-
-       for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++)
-               if ( dataflash_info[i].id
-                       && ((((int) addr) & 0xFF000000) ==
-                       dataflash_info[i].logical_address)) {
-                       addr_valid = 1;
-                       break;
-               }
-       if (!addr_valid) {
-               pFlash = (AT91PS_DataFlash) 0;
-               return pFlash;
-       }
-       pFlash->pDataFlashDesc = &(dataflash_info[i].Desc);
-       pFlash->pDevice = &(dataflash_info[i].Device);
-       *addr -= dataflash_info[i].logical_address;
-       return (pFlash);
-}
-
-/*---------------------------------------------------------------------------*/
-/* Function Name       : addr_dataflash                                     */
-/* Object              : Test if address is valid                           */
-/*---------------------------------------------------------------------------*/
-int addr_dataflash (unsigned long addr)
-{
-       int addr_valid = 0;
-       int i;
-
-       for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
-               if ((((int) addr) & 0xFF000000) ==
-                       dataflash_info[i].logical_address) {
-                       addr_valid = 1;
-                       break;
-               }
-       }
-
-       return addr_valid;
-}
-/*---------------------------------------------------------------------------*/
-/* Function Name       : size_dataflash                                     */
-/* Object              : Test if address is valid regarding the size        */
-/*---------------------------------------------------------------------------*/
-int size_dataflash (AT91PS_DataFlash pdataFlash, unsigned long addr,
-                       unsigned long size)
-{
-       /* is outside the dataflash */
-       if (((int)addr & 0x0FFFFFFF) > (pdataFlash->pDevice->pages_size *
-               pdataFlash->pDevice->pages_number)) return 0;
-       /* is too large for the dataflash */
-       if (size > ((pdataFlash->pDevice->pages_size *
-               pdataFlash->pDevice->pages_number) -
-               ((int)addr & 0x0FFFFFFF))) return 0;
-
-       return 1;
-}
-/*---------------------------------------------------------------------------*/
-/* Function Name       : prot_dataflash                                     */
-/* Object              : Test if destination area is protected              */
-/*---------------------------------------------------------------------------*/
-int prot_dataflash (AT91PS_DataFlash pdataFlash, unsigned long addr)
-{
-int area;
-       /* find area */
-       for (area=0; area < NB_DATAFLASH_AREA; area++) {
-               if ((addr >= pdataFlash->pDevice->area_list[area].start) &&
-                       (addr < pdataFlash->pDevice->area_list[area].end))
-                       break;
-       }
-       if (area == NB_DATAFLASH_AREA)
-               return -1;
-
-       /*test protection value*/
-       if (pdataFlash->pDevice->area_list[area].protected == FLAG_PROTECT_SET)
-               return 0;
-       if (pdataFlash->pDevice->area_list[area].protected == FLAG_PROTECT_INVALID)
-               return 0;
-
-       return 1;
-}
-/*--------------------------------------------------------------------------*/
-/* Function Name       : dataflash_real_protect                                    */
-/* Object              : protect/unprotect area                                    */
-/*--------------------------------------------------------------------------*/
-int dataflash_real_protect (int flag, unsigned long start_addr,
-                               unsigned long end_addr)
-{
-int i,j, area1, area2, addr_valid = 0;
-       /* find dataflash */
-       for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
-               if ((((int) start_addr) & 0xF0000000) ==
-                       dataflash_info[i].logical_address) {
-                               addr_valid = 1;
-                               break;
-               }
-       }
-       if (!addr_valid) {
-               return -1;
-       }
-       /* find start area */
-       for (area1=0; area1 < NB_DATAFLASH_AREA; area1++) {
-               if (start_addr == dataflash_info[i].Device.area_list[area1].start)
-                       break;
-       }
-       if (area1 == NB_DATAFLASH_AREA) return -1;
-       /* find end area */
-       for (area2=0; area2 < NB_DATAFLASH_AREA; area2++) {
-               if (end_addr == dataflash_info[i].Device.area_list[area2].end)
-                       break;
-       }
-       if (area2 == NB_DATAFLASH_AREA)
-               return -1;
-
-       /*set protection value*/
-       for(j = area1; j < area2+1 ; j++)
-               if(dataflash_info[i].Device.area_list[j].protected
-                               != FLAG_PROTECT_INVALID) {
-                       if (flag == 0) {
-                               dataflash_info[i].Device.area_list[j].protected
-                                       = FLAG_PROTECT_CLEAR;
-                       } else {
-                               dataflash_info[i].Device.area_list[j].protected
-                                       = FLAG_PROTECT_SET;
-                       }
-               }
-
-       return (area2-area1+1);
-}
-
-/*---------------------------------------------------------------------------*/
-/* Function Name       : read_dataflash                                     */
-/* Object              : dataflash memory read                              */
-/*---------------------------------------------------------------------------*/
-int read_dataflash (unsigned long addr, unsigned long size, char *result)
-{
-       unsigned long AddrToRead = addr;
-       AT91PS_DataFlash pFlash = &DataFlashInst;
-
-       pFlash = AT91F_DataflashSelect (pFlash, &AddrToRead);
-
-       if (pFlash == 0)
-               return ERR_UNKNOWN_FLASH_TYPE;
-
-       if (size_dataflash(pFlash,addr,size) == 0)
-               return ERR_INVAL;
-
-       return (AT91F_DataFlashRead (pFlash, AddrToRead, size, result));
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* Function Name       : write_dataflash                                    */
-/* Object              : write a block in dataflash                         */
-/*---------------------------------------------------------------------------*/
-int write_dataflash (unsigned long addr_dest, unsigned long addr_src,
-                       unsigned long size)
-{
-       unsigned long AddrToWrite = addr_dest;
-       AT91PS_DataFlash pFlash = &DataFlashInst;
-
-       pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite);
-
-       if (pFlash == 0)
-               return ERR_UNKNOWN_FLASH_TYPE;
-
-       if (size_dataflash(pFlash,addr_dest,size) == 0)
-               return ERR_INVAL;
-
-       if (prot_dataflash(pFlash,addr_dest) == 0)
-               return ERR_PROTECTED;
-
-       if (AddrToWrite == -1)
-               return -1;
-
-       return AT91F_DataFlashWrite (pFlash, (uchar *)addr_src,
-                                               AddrToWrite, size);
-}
-
-
-void dataflash_perror (int err)
-{
-       switch (err) {
-       case ERR_OK:
-               break;
-       case ERR_TIMOUT:
-               printf("Timeout writing to DataFlash\n");
-               break;
-       case ERR_PROTECTED:
-               printf("Can't write to protected/invalid DataFlash sectors\n");
-               break;
-       case ERR_INVAL:
-               printf("Outside available DataFlash\n");
-               break;
-       case ERR_UNKNOWN_FLASH_TYPE:
-               printf("Unknown Type of DataFlash\n");
-               break;
-       case ERR_PROG_ERROR:
-               printf("General DataFlash Programming Error\n");
-               break;
-       default:
-               printf("%s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err);
-               break;
-       }
-}
-
-#endif
diff --git a/drivers/dc2114x.c b/drivers/dc2114x.c
deleted file mode 100644 (file)
index d5275dc..0000000
+++ /dev/null
@@ -1,771 +0,0 @@
-/*
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-
-#if defined(CONFIG_CMD_NET) \
-       && defined(CONFIG_NET_MULTI) && defined(CONFIG_TULIP)
-
-#include <malloc.h>
-#include <net.h>
-#include <pci.h>
-
-#undef DEBUG_SROM
-#undef DEBUG_SROM2
-
-#undef UPDATE_SROM
-
-/* PCI Registers.
- */
-#define PCI_CFDA_PSM           0x43
-
-#define CFRV_RN                0x000000f0      /* Revision Number */
-
-#define WAKEUP         0x00            /* Power Saving Wakeup */
-#define SLEEP          0x80            /* Power Saving Sleep Mode */
-
-#define DC2114x_BRK    0x0020          /* CFRV break between DC21142 & DC21143 */
-
-/* Ethernet chip registers.
- */
-#define DE4X5_BMR      0x000           /* Bus Mode Register */
-#define DE4X5_TPD      0x008           /* Transmit Poll Demand Reg */
-#define DE4X5_RRBA     0x018           /* RX Ring Base Address Reg */
-#define DE4X5_TRBA     0x020           /* TX Ring Base Address Reg */
-#define DE4X5_STS      0x028           /* Status Register */
-#define DE4X5_OMR      0x030           /* Operation Mode Register */
-#define DE4X5_SICR     0x068           /* SIA Connectivity Register */
-#define DE4X5_APROM    0x048           /* Ethernet Address PROM */
-
-/* Register bits.
- */
-#define BMR_SWR                0x00000001      /* Software Reset */
-#define STS_TS         0x00700000      /* Transmit Process State */
-#define STS_RS         0x000e0000      /* Receive Process State */
-#define OMR_ST         0x00002000      /* Start/Stop Transmission Command */
-#define OMR_SR         0x00000002      /* Start/Stop Receive */
-#define OMR_PS         0x00040000      /* Port Select */
-#define OMR_SDP                0x02000000      /* SD Polarity - MUST BE ASSERTED */
-#define OMR_PM         0x00000080      /* Pass All Multicast */
-
-/* Descriptor bits.
- */
-#define R_OWN          0x80000000      /* Own Bit */
-#define RD_RER         0x02000000      /* Receive End Of Ring */
-#define RD_LS          0x00000100      /* Last Descriptor */
-#define RD_ES          0x00008000      /* Error Summary */
-#define TD_TER         0x02000000      /* Transmit End Of Ring */
-#define T_OWN          0x80000000      /* Own Bit */
-#define TD_LS          0x40000000      /* Last Segment */
-#define TD_FS          0x20000000      /* First Segment */
-#define TD_ES          0x00008000      /* Error Summary */
-#define TD_SET         0x08000000      /* Setup Packet */
-
-/* The EEPROM commands include the alway-set leading bit. */
-#define SROM_WRITE_CMD 5
-#define SROM_READ_CMD  6
-#define SROM_ERASE_CMD 7
-
-#define SROM_HWADD         0x0014      /* Hardware Address offset in SROM */
-#define SROM_RD                0x00004000      /* Read from Boot ROM */
-#define EE_DATA_WRITE        0x04      /* EEPROM chip data in. */
-#define EE_WRITE_0         0x4801
-#define EE_WRITE_1         0x4805
-#define EE_DATA_READ         0x08      /* EEPROM chip data out. */
-#define SROM_SR                0x00000800      /* Select Serial ROM when set */
-
-#define DT_IN          0x00000004      /* Serial Data In */
-#define DT_CLK         0x00000002      /* Serial ROM Clock */
-#define DT_CS          0x00000001      /* Serial ROM Chip Select */
-
-#define POLL_DEMAND    1
-
-#ifdef CONFIG_TULIP_FIX_DAVICOM
-#define RESET_DM9102(dev) {\
-    unsigned long i;\
-    i=INL(dev, 0x0);\
-    udelay(1000);\
-    OUTL(dev, i | BMR_SWR, DE4X5_BMR);\
-    udelay(1000);\
-}
-#else
-#define RESET_DE4X5(dev) {\
-    int i;\
-    i=INL(dev, DE4X5_BMR);\
-    udelay(1000);\
-    OUTL(dev, i | BMR_SWR, DE4X5_BMR);\
-    udelay(1000);\
-    OUTL(dev, i, DE4X5_BMR);\
-    udelay(1000);\
-    for (i=0;i<5;i++) {INL(dev, DE4X5_BMR); udelay(10000);}\
-    udelay(1000);\
-}
-#endif
-
-#define START_DE4X5(dev) {\
-    s32 omr; \
-    omr = INL(dev, DE4X5_OMR);\
-    omr |= OMR_ST | OMR_SR;\
-    OUTL(dev, omr, DE4X5_OMR);         /* Enable the TX and/or RX */\
-}
-
-#define STOP_DE4X5(dev) {\
-    s32 omr; \
-    omr = INL(dev, DE4X5_OMR);\
-    omr &= ~(OMR_ST|OMR_SR);\
-    OUTL(dev, omr, DE4X5_OMR);         /* Disable the TX and/or RX */ \
-}
-
-#define NUM_RX_DESC PKTBUFSRX
-#ifndef CONFIG_TULIP_FIX_DAVICOM
-       #define NUM_TX_DESC 1                   /* Number of TX descriptors   */
-#else
-       #define NUM_TX_DESC 4
-#endif
-#define RX_BUFF_SZ  PKTSIZE_ALIGN
-
-#define TOUT_LOOP   1000000
-
-#define SETUP_FRAME_LEN 192
-#define ETH_ALEN       6
-
-struct de4x5_desc {
-       volatile s32 status;
-       u32 des1;
-       u32 buf;
-       u32 next;
-};
-
-static struct de4x5_desc rx_ring[NUM_RX_DESC] __attribute__ ((aligned(32))); /* RX descriptor ring         */
-static struct de4x5_desc tx_ring[NUM_TX_DESC] __attribute__ ((aligned(32))); /* TX descriptor ring         */
-static int rx_new;                             /* RX descriptor ring pointer */
-static int tx_new;                             /* TX descriptor ring pointer */
-
-static char rxRingSize;
-static char txRingSize;
-
-#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM)
-static void  sendto_srom(struct eth_device* dev, u_int command, u_long addr);
-static int   getfrom_srom(struct eth_device* dev, u_long addr);
-static int   do_eeprom_cmd(struct eth_device *dev, u_long ioaddr,int cmd,int cmd_len);
-static int   do_read_eeprom(struct eth_device *dev,u_long ioaddr,int location,int addr_len);
-#endif /* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */
-#ifdef UPDATE_SROM
-static int   write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value);
-static void  update_srom(struct eth_device *dev, bd_t *bis);
-#endif
-#ifndef CONFIG_TULIP_FIX_DAVICOM
-static int   read_srom(struct eth_device *dev, u_long ioaddr, int index);
-static void  read_hw_addr(struct eth_device* dev, bd_t * bis);
-#endif /* CONFIG_TULIP_FIX_DAVICOM */
-static void  send_setup_frame(struct eth_device* dev, bd_t * bis);
-
-static int   dc21x4x_init(struct eth_device* dev, bd_t* bis);
-static int   dc21x4x_send(struct eth_device* dev, volatile void *packet, int length);
-static int   dc21x4x_recv(struct eth_device* dev);
-static void  dc21x4x_halt(struct eth_device* dev);
-#ifdef CONFIG_TULIP_SELECT_MEDIA
-extern void  dc21x4x_select_media(struct eth_device* dev);
-#endif
-
-#if defined(CONFIG_E500)
-#define phys_to_bus(a) (a)
-#else
-#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
-#endif
-
-static int INL(struct eth_device* dev, u_long addr)
-{
-       return le32_to_cpu(*(volatile u_long *)(addr + dev->iobase));
-}
-
-static void OUTL(struct eth_device* dev, int command, u_long addr)
-{
-       *(volatile u_long *)(addr + dev->iobase) = cpu_to_le32(command);
-}
-
-static struct pci_device_id supported[] = {
-       { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST },
-       { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142 },
-#ifdef CONFIG_TULIP_FIX_DAVICOM
-       { PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DAVICOM_DM9102A },
-#endif
-       { }
-};
-
-int dc21x4x_initialize(bd_t *bis)
-{
-       int                     idx=0;
-       int                     card_number = 0;
-       unsigned int            cfrv;
-       unsigned char           timer;
-       pci_dev_t               devbusfn;
-       unsigned int            iobase;
-       unsigned short          status;
-       struct eth_device*      dev;
-
-       while(1) {
-               devbusfn =  pci_find_devices(supported, idx++);
-               if (devbusfn == -1) {
-                       break;
-               }
-
-               /* Get the chip configuration revision register. */
-               pci_read_config_dword(devbusfn, PCI_REVISION_ID, &cfrv);
-
-#ifndef CONFIG_TULIP_FIX_DAVICOM
-               if ((cfrv & CFRV_RN) < DC2114x_BRK ) {
-                       printf("Error: The chip is not DC21143.\n");
-                       continue;
-               }
-#endif
-
-               pci_read_config_word(devbusfn, PCI_COMMAND, &status);
-               status |=
-#ifdef CONFIG_TULIP_USE_IO
-                 PCI_COMMAND_IO |
-#else
-                 PCI_COMMAND_MEMORY |
-#endif
-                 PCI_COMMAND_MASTER;
-               pci_write_config_word(devbusfn, PCI_COMMAND, status);
-
-               pci_read_config_word(devbusfn, PCI_COMMAND, &status);
-               if (!(status & PCI_COMMAND_IO)) {
-                       printf("Error: Can not enable I/O access.\n");
-                       continue;
-               }
-
-               if (!(status & PCI_COMMAND_IO)) {
-                       printf("Error: Can not enable I/O access.\n");
-                       continue;
-               }
-
-               if (!(status & PCI_COMMAND_MASTER)) {
-                       printf("Error: Can not enable Bus Mastering.\n");
-                       continue;
-               }
-
-               /* Check the latency timer for values >= 0x60. */
-               pci_read_config_byte(devbusfn, PCI_LATENCY_TIMER, &timer);
-
-               if (timer < 0x60) {
-                       pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x60);
-               }
-
-#ifdef CONFIG_TULIP_USE_IO
-               /* read BAR for memory space access */
-               pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase);
-               iobase &= PCI_BASE_ADDRESS_IO_MASK;
-#else
-               /* read BAR for memory space access */
-               pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &iobase);
-               iobase &= PCI_BASE_ADDRESS_MEM_MASK;
-#endif
-               debug ("dc21x4x: DEC 21142 PCI Device @0x%x\n", iobase);
-
-               dev = (struct eth_device*) malloc(sizeof *dev);
-
-#ifdef CONFIG_TULIP_FIX_DAVICOM
-               sprintf(dev->name, "Davicom#%d", card_number);
-#else
-               sprintf(dev->name, "dc21x4x#%d", card_number);
-#endif
-
-#ifdef CONFIG_TULIP_USE_IO
-               dev->iobase = pci_io_to_phys(devbusfn, iobase);
-#else
-               dev->iobase = pci_mem_to_phys(devbusfn, iobase);
-#endif
-               dev->priv   = (void*) devbusfn;
-               dev->init   = dc21x4x_init;
-               dev->halt   = dc21x4x_halt;
-               dev->send   = dc21x4x_send;
-               dev->recv   = dc21x4x_recv;
-
-               /* Ensure we're not sleeping. */
-               pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP);
-
-               udelay(10 * 1000);
-
-#ifndef CONFIG_TULIP_FIX_DAVICOM
-               read_hw_addr(dev, bis);
-#endif
-               eth_register(dev);
-
-               card_number++;
-       }
-
-       return card_number;
-}
-
-static int dc21x4x_init(struct eth_device* dev, bd_t* bis)
-{
-       int             i;
-       int             devbusfn = (int) dev->priv;
-
-       /* Ensure we're not sleeping. */
-       pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP);
-
-#ifdef CONFIG_TULIP_FIX_DAVICOM
-       RESET_DM9102(dev);
-#else
-       RESET_DE4X5(dev);
-#endif
-
-       if ((INL(dev, DE4X5_STS) & (STS_TS | STS_RS)) != 0) {
-               printf("Error: Cannot reset ethernet controller.\n");
-               return 0;
-       }
-
-#ifdef CONFIG_TULIP_SELECT_MEDIA
-       dc21x4x_select_media(dev);
-#else
-       OUTL(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR);
-#endif
-
-       for (i = 0; i < NUM_RX_DESC; i++) {
-               rx_ring[i].status = cpu_to_le32(R_OWN);
-               rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ);
-               rx_ring[i].buf = cpu_to_le32(phys_to_bus((u32) NetRxPackets[i]));
-#ifdef CONFIG_TULIP_FIX_DAVICOM
-               rx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &rx_ring[(i+1) % NUM_RX_DESC]));
-#else
-               rx_ring[i].next = 0;
-#endif
-       }
-
-       for (i=0; i < NUM_TX_DESC; i++) {
-               tx_ring[i].status = 0;
-               tx_ring[i].des1 = 0;
-               tx_ring[i].buf = 0;
-
-#ifdef CONFIG_TULIP_FIX_DAVICOM
-       tx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &tx_ring[(i+1) % NUM_TX_DESC]));
-#else
-               tx_ring[i].next = 0;
-#endif
-       }
-
-       rxRingSize = NUM_RX_DESC;
-       txRingSize = NUM_TX_DESC;
-
-       /* Write the end of list marker to the descriptor lists. */
-       rx_ring[rxRingSize - 1].des1 |= cpu_to_le32(RD_RER);
-       tx_ring[txRingSize - 1].des1 |= cpu_to_le32(TD_TER);
-
-       /* Tell the adapter where the TX/RX rings are located. */
-       OUTL(dev, phys_to_bus((u32) &rx_ring), DE4X5_RRBA);
-       OUTL(dev, phys_to_bus((u32) &tx_ring), DE4X5_TRBA);
-
-       START_DE4X5(dev);
-
-       tx_new = 0;
-       rx_new = 0;
-
-       send_setup_frame(dev, bis);
-
-       return 1;
-}
-
-static int dc21x4x_send(struct eth_device* dev, volatile void *packet, int length)
-{
-       int             status = -1;
-       int             i;
-
-       if (length <= 0) {
-               printf("%s: bad packet size: %d\n", dev->name, length);
-               goto Done;
-       }
-
-       for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
-               if (i >= TOUT_LOOP) {
-                       printf("%s: tx error buffer not ready\n", dev->name);
-                       goto Done;
-               }
-       }
-
-       tx_ring[tx_new].buf    = cpu_to_le32(phys_to_bus((u32) packet));
-       tx_ring[tx_new].des1   = cpu_to_le32(TD_TER | TD_LS | TD_FS | length);
-       tx_ring[tx_new].status = cpu_to_le32(T_OWN);
-
-       OUTL(dev, POLL_DEMAND, DE4X5_TPD);
-
-       for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
-               if (i >= TOUT_LOOP) {
-                       printf(".%s: tx buffer not ready\n", dev->name);
-                       goto Done;
-               }
-       }
-
-       if (le32_to_cpu(tx_ring[tx_new].status) & TD_ES) {
-#if 0 /* test-only */
-               printf("TX error status = 0x%08X\n",
-                       le32_to_cpu(tx_ring[tx_new].status));
-#endif
-               tx_ring[tx_new].status = 0x0;
-               goto Done;
-       }
-
-       status = length;
-
- Done:
-    tx_new = (tx_new+1) % NUM_TX_DESC;
-       return status;
-}
-
-static int dc21x4x_recv(struct eth_device* dev)
-{
-       s32             status;
-       int             length    = 0;
-
-       for ( ; ; ) {
-               status = (s32)le32_to_cpu(rx_ring[rx_new].status);
-
-               if (status & R_OWN) {
-                       break;
-               }
-
-               if (status & RD_LS) {
-                       /* Valid frame status.
-                        */
-                       if (status & RD_ES) {
-
-                               /* There was an error.
-                                */
-                               printf("RX error status = 0x%08X\n", status);
-                       } else {
-                               /* A valid frame received.
-                                */
-                               length = (le32_to_cpu(rx_ring[rx_new].status) >> 16);
-
-                               /* Pass the packet up to the protocol
-                                * layers.
-                                */
-                               NetReceive(NetRxPackets[rx_new], length - 4);
-                       }
-
-                       /* Change buffer ownership for this frame, back
-                        * to the adapter.
-                        */
-                       rx_ring[rx_new].status = cpu_to_le32(R_OWN);
-               }
-
-               /* Update entry information.
-                */
-               rx_new = (rx_new + 1) % rxRingSize;
-       }
-
-       return length;
-}
-
-static void dc21x4x_halt(struct eth_device* dev)
-{
-       int             devbusfn = (int) dev->priv;
-
-       STOP_DE4X5(dev);
-       OUTL(dev, 0, DE4X5_SICR);
-
-       pci_write_config_byte(devbusfn, PCI_CFDA_PSM, SLEEP);
-}
-
-static void send_setup_frame(struct eth_device* dev, bd_t *bis)
-{
-       int             i;
-       char    setup_frame[SETUP_FRAME_LEN];
-       char    *pa = &setup_frame[0];
-
-       memset(pa, 0xff, SETUP_FRAME_LEN);
-
-       for (i = 0; i < ETH_ALEN; i++) {
-               *(pa + (i & 1)) = dev->enetaddr[i];
-               if (i & 0x01) {
-                       pa += 4;
-               }
-       }
-
-       for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
-               if (i >= TOUT_LOOP) {
-                       printf("%s: tx error buffer not ready\n", dev->name);
-                       goto Done;
-               }
-       }
-
-       tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((u32) &setup_frame[0]));
-       tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_SET| SETUP_FRAME_LEN);
-       tx_ring[tx_new].status = cpu_to_le32(T_OWN);
-
-       OUTL(dev, POLL_DEMAND, DE4X5_TPD);
-
-       for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
-               if (i >= TOUT_LOOP) {
-                       printf("%s: tx buffer not ready\n", dev->name);
-                       goto Done;
-               }
-       }
-
-       if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) {
-               printf("TX error status2 = 0x%08X\n", le32_to_cpu(tx_ring[tx_new].status));
-       }
-       tx_new = (tx_new+1) % NUM_TX_DESC;
-
-Done:
-       return;
-}
-
-#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM)
-/* SROM Read and write routines.
- */
-static void
-sendto_srom(struct eth_device* dev, u_int command, u_long addr)
-{
-       OUTL(dev, command, addr);
-       udelay(1);
-}
-
-static int
-getfrom_srom(struct eth_device* dev, u_long addr)
-{
-       s32 tmp;
-
-       tmp = INL(dev, addr);
-       udelay(1);
-
-       return tmp;
-}
-
-/* Note: this routine returns extra data bits for size detection. */
-static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, int addr_len)
-{
-       int i;
-       unsigned retval = 0;
-       int read_cmd = location | (SROM_READ_CMD << addr_len);
-
-       sendto_srom(dev, SROM_RD | SROM_SR, ioaddr);
-       sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
-
-#ifdef DEBUG_SROM
-       printf(" EEPROM read at %d ", location);
-#endif
-
-       /* Shift the read command bits out. */
-       for (i = 4 + addr_len; i >= 0; i--) {
-               short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
-               sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval, ioaddr);
-               udelay(10);
-               sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval | DT_CLK, ioaddr);
-               udelay(10);
-#ifdef DEBUG_SROM2
-               printf("%X", getfrom_srom(dev, ioaddr) & 15);
-#endif
-               retval = (retval << 1) | ((getfrom_srom(dev, ioaddr) & EE_DATA_READ) ? 1 : 0);
-       }
-
-       sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
-
-#ifdef DEBUG_SROM2
-       printf(" :%X:", getfrom_srom(dev, ioaddr) & 15);
-#endif
-
-       for (i = 16; i > 0; i--) {
-               sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr);
-               udelay(10);
-#ifdef DEBUG_SROM2
-               printf("%X", getfrom_srom(dev, ioaddr) & 15);
-#endif
-               retval = (retval << 1) | ((getfrom_srom(dev, ioaddr) & EE_DATA_READ) ? 1 : 0);
-               sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
-               udelay(10);
-       }
-
-       /* Terminate the EEPROM access. */
-       sendto_srom(dev, SROM_RD | SROM_SR, ioaddr);
-
-#ifdef DEBUG_SROM2
-       printf(" EEPROM value at %d is %5.5x.\n", location, retval);
-#endif
-
-       return retval;
-}
-#endif /* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */
-
-/* This executes a generic EEPROM command, typically a write or write
- * enable. It returns the data output from the EEPROM, and thus may
- * also be used for reads.
- */
-#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM)
-static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, int cmd_len)
-{
-       unsigned retval = 0;
-
-#ifdef DEBUG_SROM
-       printf(" EEPROM op 0x%x: ", cmd);
-#endif
-
-       sendto_srom(dev,SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr);
-
-       /* Shift the command bits out. */
-       do {
-               short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;
-               sendto_srom(dev,dataval, ioaddr);
-               udelay(10);
-
-#ifdef DEBUG_SROM2
-               printf("%X", getfrom_srom(dev,ioaddr) & 15);
-#endif
-
-               sendto_srom(dev,dataval | DT_CLK, ioaddr);
-               udelay(10);
-               retval = (retval << 1) | ((getfrom_srom(dev,ioaddr) & EE_DATA_READ) ? 1 : 0);
-       } while (--cmd_len >= 0);
-       sendto_srom(dev,SROM_RD | SROM_SR | DT_CS, ioaddr);
-
-       /* Terminate the EEPROM access. */
-       sendto_srom(dev,SROM_RD | SROM_SR, ioaddr);
-
-#ifdef DEBUG_SROM
-       printf(" EEPROM result is 0x%5.5x.\n", retval);
-#endif
-
-       return retval;
-}
-#endif /* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */
-
-#ifndef CONFIG_TULIP_FIX_DAVICOM
-static int read_srom(struct eth_device *dev, u_long ioaddr, int index)
-{
-       int ee_addr_size = do_read_eeprom(dev, ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
-
-       return do_eeprom_cmd(dev, ioaddr,
-                            (((SROM_READ_CMD << ee_addr_size) | index) << 16)
-                            | 0xffff, 3 + ee_addr_size + 16);
-}
-#endif /* CONFIG_TULIP_FIX_DAVICOM */
-
-#ifdef UPDATE_SROM
-static int write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value)
-{
-       int ee_addr_size = do_read_eeprom(dev, ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
-       int i;
-       unsigned short newval;
-
-       udelay(10*1000); /* test-only */
-
-#ifdef DEBUG_SROM
-       printf("ee_addr_size=%d.\n", ee_addr_size);
-       printf("Writing new entry 0x%4.4x to offset %d.\n", new_value, index);
-#endif
-
-       /* Enable programming modes. */
-       do_eeprom_cmd(dev, ioaddr, (0x4f << (ee_addr_size-4)), 3+ee_addr_size);
-
-       /* Do the actual write. */
-       do_eeprom_cmd(dev, ioaddr,
-                     (((SROM_WRITE_CMD<<ee_addr_size)|index) << 16) | new_value,
-                     3 + ee_addr_size + 16);
-
-       /* Poll for write finished. */
-       sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
-       for (i = 0; i < 10000; i++)                     /* Typical 2000 ticks */
-               if (getfrom_srom(dev, ioaddr) & EE_DATA_READ)
-                       break;
-
-#ifdef DEBUG_SROM
-       printf(" Write finished after %d ticks.\n", i);
-#endif
-
-       /* Disable programming. */
-       do_eeprom_cmd(dev, ioaddr, (0x40 << (ee_addr_size-4)), 3 + ee_addr_size);
-
-       /* And read the result. */
-       newval = do_eeprom_cmd(dev, ioaddr,
-                              (((SROM_READ_CMD<<ee_addr_size)|index) << 16)
-                              | 0xffff, 3 + ee_addr_size + 16);
-#ifdef DEBUG_SROM
-       printf("  New value at offset %d is %4.4x.\n", index, newval);
-#endif
-       return 1;
-}
-#endif
-
-#ifndef CONFIG_TULIP_FIX_DAVICOM
-static void read_hw_addr(struct eth_device *dev, bd_t *bis)
-{
-       u_short tmp, *p = (u_short *)(&dev->enetaddr[0]);
-       int i, j = 0;
-
-       for (i = 0; i < (ETH_ALEN >> 1); i++) {
-               tmp = read_srom(dev, DE4X5_APROM, ((SROM_HWADD >> 1) + i));
-               *p = le16_to_cpu(tmp);
-               j += *p++;
-       }
-
-       if ((j == 0) || (j == 0x2fffd)) {
-               memset (dev->enetaddr, 0, ETH_ALEN);
-               debug ("Warning: can't read HW address from SROM.\n");
-               goto Done;
-       }
-
-       return;
-
-Done:
-#ifdef UPDATE_SROM
-       update_srom(dev, bis);
-#endif
-       return;
-}
-#endif /* CONFIG_TULIP_FIX_DAVICOM */
-
-#ifdef UPDATE_SROM
-static void update_srom(struct eth_device *dev, bd_t *bis)
-{
-       int i;
-       static unsigned short eeprom[0x40] = {
-               0x140b, 0x6610, 0x0000, 0x0000,         /* 00 */
-               0x0000, 0x0000, 0x0000, 0x0000,         /* 04 */
-               0x00a3, 0x0103, 0x0000, 0x0000,         /* 08 */
-               0x0000, 0x1f00, 0x0000, 0x0000,         /* 0c */
-               0x0108, 0x038d, 0x0000, 0x0000,         /* 10 */
-               0xe078, 0x0001, 0x0040, 0x0018,         /* 14 */
-               0x0000, 0x0000, 0x0000, 0x0000,         /* 18 */
-               0x0000, 0x0000, 0x0000, 0x0000,         /* 1c */
-               0x0000, 0x0000, 0x0000, 0x0000,         /* 20 */
-               0x0000, 0x0000, 0x0000, 0x0000,         /* 24 */
-               0x0000, 0x0000, 0x0000, 0x0000,         /* 28 */
-               0x0000, 0x0000, 0x0000, 0x0000,         /* 2c */
-               0x0000, 0x0000, 0x0000, 0x0000,         /* 30 */
-               0x0000, 0x0000, 0x0000, 0x0000,         /* 34 */
-               0x0000, 0x0000, 0x0000, 0x0000,         /* 38 */
-               0x0000, 0x0000, 0x0000, 0x4e07,         /* 3c */
-       };
-
-       /* Ethernet Addr... */
-       eeprom[0x0a] = ((bis->bi_enetaddr[1] & 0xff) << 8) | (bis->bi_enetaddr[0] & 0xff);
-       eeprom[0x0b] = ((bis->bi_enetaddr[3] & 0xff) << 8) | (bis->bi_enetaddr[2] & 0xff);
-       eeprom[0x0c] = ((bis->bi_enetaddr[5] & 0xff) << 8) | (bis->bi_enetaddr[4] & 0xff);
-
-       for (i=0; i<0x40; i++)
-       {
-               write_srom(dev, DE4X5_APROM, i, eeprom[i]);
-       }
-}
-#endif /* UPDATE_SROM */
-
-#endif
diff --git a/drivers/dm9000x.c b/drivers/dm9000x.c
deleted file mode 100644 (file)
index 6131b5c..0000000
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
-  dm9000.c: Version 1.2 12/15/2003
-
-       A Davicom DM9000 ISA NIC fast Ethernet driver for Linux.
-       Copyright (C) 1997  Sten Wang
-
-       This program is free software; you can redistribute it and/or
-       modify it under the terms of the GNU General Public License
-       as published by the Free Software Foundation; either version 2
-       of the License, or (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-  (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved.
-
-V0.11  06/20/2001      REG_0A bit3=1, default enable BP with DA match
-       06/22/2001      Support DM9801 progrmming
-                       E3: R25 = ((R24 + NF) & 0x00ff) | 0xf000
-                       E4: R25 = ((R24 + NF) & 0x00ff) | 0xc200
-               R17 = (R17 & 0xfff0) | NF + 3
-                       E5: R25 = ((R24 + NF - 3) & 0x00ff) | 0xc200
-               R17 = (R17 & 0xfff0) | NF
-
-v1.00                  modify by simon 2001.9.5
-                       change for kernel 2.4.x
-
-v1.1   11/09/2001              fix force mode bug
-
-v1.2   03/18/2003       Weilun Huang <weilun_huang@davicom.com.tw>:
-                       Fixed phy reset.
-                       Added tx/rx 32 bit mode.
-                       Cleaned up for kernel merge.
-
---------------------------------------
-
-       12/15/2003       Initial port to u-boot by Sascha Hauer <saschahauer@web.de>
-
-TODO: Homerun NIC and longrun NIC are not functional, only internal at the
-      moment.
-*/
-
-#include <common.h>
-#include <command.h>
-#include <net.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_DRIVER_DM9000
-
-#include "dm9000x.h"
-
-/* Board/System/Debug information/definition ---------------- */
-
-#define DM9801_NOISE_FLOOR     0x08
-#define DM9802_NOISE_FLOOR     0x05
-
-/* #define CONFIG_DM9000_DEBUG */
-
-#ifdef CONFIG_DM9000_DEBUG
-#define DM9000_DBG(fmt,args...) printf(fmt ,##args)
-#else                          /*  */
-#define DM9000_DBG(fmt,args...)
-#endif                         /*  */
-enum DM9000_PHY_mode { DM9000_10MHD = 0, DM9000_100MHD =
-           1, DM9000_10MFD = 4, DM9000_100MFD = 5, DM9000_AUTO =
-           8, DM9000_1M_HPNA = 0x10
-};
-enum DM9000_NIC_TYPE { FASTETHER_NIC = 0, HOMERUN_NIC = 1, LONGRUN_NIC = 2
-};
-
-/* Structure/enum declaration ------------------------------- */
-typedef struct board_info {
-       u32 runt_length_counter;        /* counter: RX length < 64byte */
-       u32 long_length_counter;        /* counter: RX length > 1514byte */
-       u32 reset_counter;      /* counter: RESET */
-       u32 reset_tx_timeout;   /* RESET caused by TX Timeout */
-       u32 reset_rx_status;    /* RESET caused by RX Statsus wrong */
-       u16 tx_pkt_cnt;
-       u16 queue_start_addr;
-       u16 dbug_cnt;
-       u8 phy_addr;
-       u8 device_wait_reset;   /* device state */
-       u8 nic_type;            /* NIC type */
-       unsigned char srom[128];
-} board_info_t;
-board_info_t dmfe_info;
-
-/* For module input parameter */
-static int media_mode = DM9000_AUTO;
-static u8 nfloor = 0;
-
-/* function declaration ------------------------------------- */
-int eth_init(bd_t * bd);
-int eth_send(volatile void *, int);
-int eth_rx(void);
-void eth_halt(void);
-static int dm9000_probe(void);
-static u16 phy_read(int);
-static void phy_write(int, u16);
-u16 read_srom_word(int);
-static u8 DM9000_ior(int);
-static void DM9000_iow(int reg, u8 value);
-
-/* DM9000 network board routine ---------------------------- */
-
-#define DM9000_outb(d,r) ( *(volatile u8 *)r = d )
-#define DM9000_outw(d,r) ( *(volatile u16 *)r = d )
-#define DM9000_outl(d,r) ( *(volatile u32 *)r = d )
-#define DM9000_inb(r) (*(volatile u8 *)r)
-#define DM9000_inw(r) (*(volatile u16 *)r)
-#define DM9000_inl(r) (*(volatile u32 *)r)
-
-#ifdef CONFIG_DM9000_DEBUG
-static void
-dump_regs(void)
-{
-       DM9000_DBG("\n");
-       DM9000_DBG("NCR   (0x00): %02x\n", DM9000_ior(0));
-       DM9000_DBG("NSR   (0x01): %02x\n", DM9000_ior(1));
-       DM9000_DBG("TCR   (0x02): %02x\n", DM9000_ior(2));
-       DM9000_DBG("TSRI  (0x03): %02x\n", DM9000_ior(3));
-       DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(4));
-       DM9000_DBG("RCR   (0x05): %02x\n", DM9000_ior(5));
-       DM9000_DBG("RSR   (0x06): %02x\n", DM9000_ior(6));
-       DM9000_DBG("ISR   (0xFE): %02x\n", DM9000_ior(ISR));
-       DM9000_DBG("\n");
-}
-#endif                         /*  */
-
-/*
-  Search DM9000 board, allocate space and register it
-*/
-int
-dm9000_probe(void)
-{
-       u32 id_val;
-       id_val = DM9000_ior(DM9000_VIDL);
-       id_val |= DM9000_ior(DM9000_VIDH) << 8;
-       id_val |= DM9000_ior(DM9000_PIDL) << 16;
-       id_val |= DM9000_ior(DM9000_PIDH) << 24;
-       if (id_val == DM9000_ID) {
-               printf("dm9000 i/o: 0x%x, id: 0x%x \n", CONFIG_DM9000_BASE,
-                      id_val);
-               return 0;
-       } else {
-               printf("dm9000 not found at 0x%08x id: 0x%08x\n",
-                      CONFIG_DM9000_BASE, id_val);
-               return -1;
-       }
-}
-
-/* Set PHY operationg mode
-*/
-static void
-set_PHY_mode(void)
-{
-       u16 phy_reg4 = 0x01e1, phy_reg0 = 0x1000;
-       if (!(media_mode & DM9000_AUTO)) {
-               switch (media_mode) {
-               case DM9000_10MHD:
-                       phy_reg4 = 0x21;
-                       phy_reg0 = 0x0000;
-                       break;
-               case DM9000_10MFD:
-                       phy_reg4 = 0x41;
-                       phy_reg0 = 0x1100;
-                       break;
-               case DM9000_100MHD:
-                       phy_reg4 = 0x81;
-                       phy_reg0 = 0x2000;
-                       break;
-               case DM9000_100MFD:
-                       phy_reg4 = 0x101;
-                       phy_reg0 = 0x3100;
-                       break;
-               }
-               phy_write(4, phy_reg4); /* Set PHY media mode */
-               phy_write(0, phy_reg0); /*  Tmp */
-       }
-       DM9000_iow(DM9000_GPCR, 0x01);  /* Let GPIO0 output */
-       DM9000_iow(DM9000_GPR, 0x00);   /* Enable PHY */
-}
-
-/*
-       Init HomeRun DM9801
-*/
-static void
-program_dm9801(u16 HPNA_rev)
-{
-       __u16 reg16, reg17, reg24, reg25;
-       if (!nfloor)
-               nfloor = DM9801_NOISE_FLOOR;
-       reg16 = phy_read(16);
-       reg17 = phy_read(17);
-       reg24 = phy_read(24);
-       reg25 = phy_read(25);
-       switch (HPNA_rev) {
-       case 0xb900:            /* DM9801 E3 */
-               reg16 |= 0x1000;
-               reg25 = ((reg24 + nfloor) & 0x00ff) | 0xf000;
-               break;
-       case 0xb901:            /* DM9801 E4 */
-               reg25 = ((reg24 + nfloor) & 0x00ff) | 0xc200;
-               reg17 = (reg17 & 0xfff0) + nfloor + 3;
-               break;
-       case 0xb902:            /* DM9801 E5 */
-       case 0xb903:            /* DM9801 E6 */
-       default:
-               reg16 |= 0x1000;
-               reg25 = ((reg24 + nfloor - 3) & 0x00ff) | 0xc200;
-               reg17 = (reg17 & 0xfff0) + nfloor;
-       }
-       phy_write(16, reg16);
-       phy_write(17, reg17);
-       phy_write(25, reg25);
-}
-
-/*
-       Init LongRun DM9802
-*/
-static void
-program_dm9802(void)
-{
-       __u16 reg25;
-       if (!nfloor)
-               nfloor = DM9802_NOISE_FLOOR;
-       reg25 = phy_read(25);
-       reg25 = (reg25 & 0xff00) + nfloor;
-       phy_write(25, reg25);
-}
-
-/* Identify NIC type
-*/
-static void
-identify_nic(void)
-{
-       struct board_info *db = &dmfe_info;     /* Point a board information structure */
-       u16 phy_reg3;
-       DM9000_iow(DM9000_NCR, NCR_EXT_PHY);
-       phy_reg3 = phy_read(3);
-       switch (phy_reg3 & 0xfff0) {
-       case 0xb900:
-               if (phy_read(31) == 0x4404) {
-                       db->nic_type = HOMERUN_NIC;
-                       program_dm9801(phy_reg3);
-                       DM9000_DBG("found homerun NIC\n");
-               } else {
-                       db->nic_type = LONGRUN_NIC;
-                       DM9000_DBG("found longrun NIC\n");
-                       program_dm9802();
-               }
-               break;
-       default:
-               db->nic_type = FASTETHER_NIC;
-               break;
-       }
-       DM9000_iow(DM9000_NCR, 0);
-}
-
-/* General Purpose dm9000 reset routine */
-static void
-dm9000_reset(void)
-{
-       DM9000_DBG("resetting\n");
-       DM9000_iow(DM9000_NCR, NCR_RST);
-       udelay(1000);           /* delay 1ms */
-}
-
-/* Initilize dm9000 board
-*/
-int
-eth_init(bd_t * bd)
-{
-       int i, oft, lnk;
-       DM9000_DBG("eth_init()\n");
-
-       /* RESET device */
-       dm9000_reset();
-       dm9000_probe();
-
-       /* NIC Type: FASTETHER, HOMERUN, LONGRUN */
-       identify_nic();
-
-       /* GPIO0 on pre-activate PHY */
-       DM9000_iow(DM9000_GPR, 0x00);   /*REG_1F bit0 activate phyxcer */
-
-       /* Set PHY */
-       set_PHY_mode();
-
-       /* Program operating register */
-       DM9000_iow(DM9000_NCR, 0x0);    /* only intern phy supported by now */
-       DM9000_iow(DM9000_TCR, 0);      /* TX Polling clear */
-       DM9000_iow(DM9000_BPTR, 0x3f);  /* Less 3Kb, 200us */
-       DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8));   /* Flow Control : High/Low Water */
-       DM9000_iow(DM9000_FCR, 0x0);    /* SH FIXME: This looks strange! Flow Control */
-       DM9000_iow(DM9000_SMCR, 0);     /* Special Mode */
-       DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);   /* clear TX status */
-       DM9000_iow(DM9000_ISR, 0x0f);   /* Clear interrupt status */
-
-       /* Set Node address */
-       for (i = 0; i < 6; i++)
-               ((u16 *) bd->bi_enetaddr)[i] = read_srom_word(i);
-
-       if (is_zero_ether_addr(bd->bi_enetaddr) ||
-           is_multicast_ether_addr(bd->bi_enetaddr)) {
-               /* try reading from environment */
-               u8 i;
-               char *s, *e;
-               s = getenv ("ethaddr");
-               for (i = 0; i < 6; ++i) {
-                       bd->bi_enetaddr[i] = s ?
-                               simple_strtoul (s, &e, 16) : 0;
-                       if (s)
-                               s = (*e) ? e + 1 : e;
-               }
-       }
-
-       printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", bd->bi_enetaddr[0],
-              bd->bi_enetaddr[1], bd->bi_enetaddr[2], bd->bi_enetaddr[3],
-              bd->bi_enetaddr[4], bd->bi_enetaddr[5]);
-       for (i = 0, oft = 0x10; i < 6; i++, oft++)
-               DM9000_iow(oft, bd->bi_enetaddr[i]);
-       for (i = 0, oft = 0x16; i < 8; i++, oft++)
-               DM9000_iow(oft, 0xff);
-
-       /* read back mac, just to be sure */
-       for (i = 0, oft = 0x10; i < 6; i++, oft++)
-               DM9000_DBG("%02x:", DM9000_ior(oft));
-       DM9000_DBG("\n");
-
-       /* Activate DM9000 */
-       DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);  /* RX enable */
-       DM9000_iow(DM9000_IMR, IMR_PAR);        /* Enable TX/RX interrupt mask */
-       i = 0;
-       while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */
-               udelay(1000);
-               i++;
-               if (i == 10000) {
-                       printf("could not establish link\n");
-                       return 0;
-               }
-       }
-
-       /* see what we've got */
-       lnk = phy_read(17) >> 12;
-       printf("operating at ");
-       switch (lnk) {
-       case 1:
-               printf("10M half duplex ");
-               break;
-       case 2:
-               printf("10M full duplex ");
-               break;
-       case 4:
-               printf("100M half duplex ");
-               break;
-       case 8:
-               printf("100M full duplex ");
-               break;
-       default:
-               printf("unknown: %d ", lnk);
-               break;
-       }
-       printf("mode\n");
-       return 0;
-}
-
-/*
-  Hardware start transmission.
-  Send a packet to media from the upper layer.
-*/
-int
-eth_send(volatile void *packet, int length)
-{
-       char *data_ptr;
-       u32 tmplen, i;
-       int tmo;
-       DM9000_DBG("eth_send: length: %d\n", length);
-       for (i = 0; i < length; i++) {
-               if (i % 8 == 0)
-                       DM9000_DBG("\nSend: 02x: ", i);
-               DM9000_DBG("%02x ", ((unsigned char *) packet)[i]);
-       } DM9000_DBG("\n");
-
-       /* Move data to DM9000 TX RAM */
-       data_ptr = (char *) packet;
-       DM9000_outb(DM9000_MWCMD, DM9000_IO);
-
-#ifdef CONFIG_DM9000_USE_8BIT
-       /* Byte mode */
-       for (i = 0; i < length; i++)
-               DM9000_outb((data_ptr[i] & 0xff), DM9000_DATA);
-
-#endif                         /*  */
-#ifdef CONFIG_DM9000_USE_16BIT
-       tmplen = (length + 1) / 2;
-       for (i = 0; i < tmplen; i++)
-               DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA);
-
-#endif                         /*  */
-#ifdef CONFIG_DM9000_USE_32BIT
-       tmplen = (length + 3) / 4;
-       for (i = 0; i < tmplen; i++)
-               DM9000_outl(((u32 *) data_ptr)[i], DM9000_DATA);
-
-#endif                         /*  */
-
-       /* Set TX length to DM9000 */
-       DM9000_iow(DM9000_TXPLL, length & 0xff);
-       DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff);
-
-       /* Issue TX polling command */
-       DM9000_iow(DM9000_TCR, TCR_TXREQ);      /* Cleared after TX complete */
-
-       /* wait for end of transmission */
-       tmo = get_timer(0) + 5 * CFG_HZ;
-       while (DM9000_ior(DM9000_TCR) & TCR_TXREQ) {
-               if (get_timer(0) >= tmo) {
-                       printf("transmission timeout\n");
-                       break;
-               }
-       }
-       DM9000_DBG("transmit done\n\n");
-       return 0;
-}
-
-/*
-  Stop the interface.
-  The interface is stopped when it is brought.
-*/
-void
-eth_halt(void)
-{
-       DM9000_DBG("eth_halt\n");
-
-       /* RESET devie */
-       phy_write(0, 0x8000);   /* PHY RESET */
-       DM9000_iow(DM9000_GPR, 0x01);   /* Power-Down PHY */
-       DM9000_iow(DM9000_IMR, 0x80);   /* Disable all interrupt */
-       DM9000_iow(DM9000_RCR, 0x00);   /* Disable RX */
-}
-
-/*
-  Received a packet and pass to upper layer
-*/
-int
-eth_rx(void)
-{
-       u8 rxbyte, *rdptr = (u8 *) NetRxPackets[0];
-       u16 RxStatus, RxLen = 0;
-       u32 tmplen, i;
-#ifdef CONFIG_DM9000_USE_32BIT
-       u32 tmpdata;
-#endif
-
-       /* Check packet ready or not */
-       DM9000_ior(DM9000_MRCMDX);      /* Dummy read */
-       rxbyte = DM9000_inb(DM9000_DATA);       /* Got most updated data */
-       if (rxbyte == 0)
-               return 0;
-
-       /* Status check: this byte must be 0 or 1 */
-       if (rxbyte > 1) {
-               DM9000_iow(DM9000_RCR, 0x00);   /* Stop Device */
-               DM9000_iow(DM9000_ISR, 0x80);   /* Stop INT request */
-               DM9000_DBG("rx status check: %d\n", rxbyte);
-       }
-       DM9000_DBG("receiving packet\n");
-
-       /* A packet ready now  & Get status/length */
-       DM9000_outb(DM9000_MRCMD, DM9000_IO);
-
-#ifdef CONFIG_DM9000_USE_8BIT
-       RxStatus = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8);
-       RxLen = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8);
-
-#endif                         /*  */
-#ifdef CONFIG_DM9000_USE_16BIT
-       RxStatus = DM9000_inw(DM9000_DATA);
-       RxLen = DM9000_inw(DM9000_DATA);
-
-#endif                         /*  */
-#ifdef CONFIG_DM9000_USE_32BIT
-       tmpdata = DM9000_inl(DM9000_DATA);
-       RxStatus = tmpdata;
-       RxLen = tmpdata >> 16;
-
-#endif                         /*  */
-       DM9000_DBG("rx status: 0x%04x rx len: %d\n", RxStatus, RxLen);
-
-       /* Move data from DM9000 */
-       /* Read received packet from RX SRAM */
-#ifdef CONFIG_DM9000_USE_8BIT
-       for (i = 0; i < RxLen; i++)
-               rdptr[i] = DM9000_inb(DM9000_DATA);
-
-#endif                         /*  */
-#ifdef CONFIG_DM9000_USE_16BIT
-       tmplen = (RxLen + 1) / 2;
-       for (i = 0; i < tmplen; i++)
-               ((u16 *) rdptr)[i] = DM9000_inw(DM9000_DATA);
-
-#endif                         /*  */
-#ifdef CONFIG_DM9000_USE_32BIT
-       tmplen = (RxLen + 3) / 4;
-       for (i = 0; i < tmplen; i++)
-               ((u32 *) rdptr)[i] = DM9000_inl(DM9000_DATA);
-
-#endif                         /*  */
-       if ((RxStatus & 0xbf00) || (RxLen < 0x40)
-           || (RxLen > DM9000_PKT_MAX)) {
-               if (RxStatus & 0x100) {
-                       printf("rx fifo error\n");
-               }
-               if (RxStatus & 0x200) {
-                       printf("rx crc error\n");
-               }
-               if (RxStatus & 0x8000) {
-                       printf("rx length error\n");
-               }
-               if (RxLen > DM9000_PKT_MAX) {
-                       printf("rx length too big\n");
-                       dm9000_reset();
-               }
-       } else {
-
-               /* Pass to upper layer */
-               DM9000_DBG("passing packet to upper layer\n");
-               NetReceive(NetRxPackets[0], RxLen);
-               return RxLen;
-       }
-       return 0;
-}
-
-/*
-  Read a word data from SROM
-*/
-u16
-read_srom_word(int offset)
-{
-       DM9000_iow(DM9000_EPAR, offset);
-       DM9000_iow(DM9000_EPCR, 0x4);
-       udelay(8000);
-       DM9000_iow(DM9000_EPCR, 0x0);
-       return (DM9000_ior(DM9000_EPDRL) + (DM9000_ior(DM9000_EPDRH) << 8));
-}
-
-void
-write_srom_word(int offset, u16 val)
-{
-       DM9000_iow(DM9000_EPAR, offset);
-       DM9000_iow(DM9000_EPDRH, ((val >> 8) & 0xff));
-       DM9000_iow(DM9000_EPDRL, (val & 0xff));
-       DM9000_iow(DM9000_EPCR, 0x12);
-       udelay(8000);
-       DM9000_iow(DM9000_EPCR, 0);
-}
-
-
-/*
-   Read a byte from I/O port
-*/
-static u8
-DM9000_ior(int reg)
-{
-       DM9000_outb(reg, DM9000_IO);
-       return DM9000_inb(DM9000_DATA);
-}
-
-/*
-   Write a byte to I/O port
-*/
-static void
-DM9000_iow(int reg, u8 value)
-{
-       DM9000_outb(reg, DM9000_IO);
-       DM9000_outb(value, DM9000_DATA);
-}
-
-/*
-   Read a word from phyxcer
-*/
-static u16
-phy_read(int reg)
-{
-       u16 val;
-
-       /* Fill the phyxcer register into REG_0C */
-       DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
-       DM9000_iow(DM9000_EPCR, 0xc);   /* Issue phyxcer read command */
-       udelay(100);            /* Wait read complete */
-       DM9000_iow(DM9000_EPCR, 0x0);   /* Clear phyxcer read command */
-       val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);
-
-       /* The read data keeps on REG_0D & REG_0E */
-       DM9000_DBG("phy_read(%d): %d\n", reg, val);
-       return val;
-}
-
-/*
-   Write a word to phyxcer
-*/
-static void
-phy_write(int reg, u16 value)
-{
-
-       /* Fill the phyxcer register into REG_0C */
-       DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
-
-       /* Fill the written data into REG_0D & REG_0E */
-       DM9000_iow(DM9000_EPDRL, (value & 0xff));
-       DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff));
-       DM9000_iow(DM9000_EPCR, 0xa);   /* Issue phyxcer write command */
-       udelay(500);            /* Wait write complete */
-       DM9000_iow(DM9000_EPCR, 0x0);   /* Clear phyxcer write command */
-       DM9000_DBG("phy_write(reg:%d, value:%d)\n", reg, value);
-}
-#endif                         /* CONFIG_DRIVER_DM9000 */
diff --git a/drivers/dm9000x.h b/drivers/dm9000x.h
deleted file mode 100644 (file)
index f47ff8c..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * dm9000 Ethernet
- */
-
-#ifdef CONFIG_DRIVER_DM9000
-
-#define DM9000_ID              0x90000A46
-#define DM9000_PKT_MAX         1536    /* Received packet max size */
-#define DM9000_PKT_RDY         0x01    /* Packet ready to receive */
-
-/* although the registers are 16 bit, they are 32-bit aligned.
- */
-
-#define DM9000_NCR             0x00
-#define DM9000_NSR             0x01
-#define DM9000_TCR             0x02
-#define DM9000_TSR1            0x03
-#define DM9000_TSR2            0x04
-#define DM9000_RCR             0x05
-#define DM9000_RSR             0x06
-#define DM9000_ROCR            0x07
-#define DM9000_BPTR            0x08
-#define DM9000_FCTR            0x09
-#define DM9000_FCR             0x0A
-#define DM9000_EPCR            0x0B
-#define DM9000_EPAR            0x0C
-#define DM9000_EPDRL           0x0D
-#define DM9000_EPDRH           0x0E
-#define DM9000_WCR             0x0F
-
-#define DM9000_PAR             0x10
-#define DM9000_MAR             0x16
-
-#define DM9000_GPCR                    0x1e
-#define DM9000_GPR             0x1f
-#define DM9000_TRPAL           0x22
-#define DM9000_TRPAH           0x23
-#define DM9000_RWPAL           0x24
-#define DM9000_RWPAH           0x25
-
-#define DM9000_VIDL            0x28
-#define DM9000_VIDH            0x29
-#define DM9000_PIDL            0x2A
-#define DM9000_PIDH            0x2B
-
-#define DM9000_CHIPR           0x2C
-#define DM9000_SMCR            0x2F
-
-#define DM9000_PHY             0x40    /* PHY address 0x01 */
-
-#define DM9000_MRCMDX          0xF0
-#define DM9000_MRCMD           0xF2
-#define DM9000_MRRL            0xF4
-#define DM9000_MRRH            0xF5
-#define DM9000_MWCMDX                  0xF6
-#define DM9000_MWCMD           0xF8
-#define DM9000_MWRL            0xFA
-#define DM9000_MWRH            0xFB
-#define DM9000_TXPLL           0xFC
-#define DM9000_TXPLH           0xFD
-#define DM9000_ISR             0xFE
-#define DM9000_IMR             0xFF
-
-#define NCR_EXT_PHY            (1<<7)
-#define NCR_WAKEEN             (1<<6)
-#define NCR_FCOL               (1<<4)
-#define NCR_FDX                        (1<<3)
-#define NCR_LBK                        (3<<1)
-#define NCR_RST                        (1<<0)
-
-#define NSR_SPEED              (1<<7)
-#define NSR_LINKST             (1<<6)
-#define NSR_WAKEST             (1<<5)
-#define NSR_TX2END             (1<<3)
-#define NSR_TX1END             (1<<2)
-#define NSR_RXOV               (1<<1)
-
-#define TCR_TJDIS              (1<<6)
-#define TCR_EXCECM             (1<<5)
-#define TCR_PAD_DIS2   (1<<4)
-#define TCR_CRC_DIS2   (1<<3)
-#define TCR_PAD_DIS1   (1<<2)
-#define TCR_CRC_DIS1   (1<<1)
-#define TCR_TXREQ              (1<<0)
-
-#define TSR_TJTO               (1<<7)
-#define TSR_LC                 (1<<6)
-#define TSR_NC                 (1<<5)
-#define TSR_LCOL               (1<<4)
-#define TSR_COL                        (1<<3)
-#define TSR_EC                 (1<<2)
-
-#define RCR_WTDIS              (1<<6)
-#define RCR_DIS_LONG   (1<<5)
-#define RCR_DIS_CRC            (1<<4)
-#define RCR_ALL                        (1<<3)
-#define RCR_RUNT               (1<<2)
-#define RCR_PRMSC              (1<<1)
-#define RCR_RXEN               (1<<0)
-
-#define RSR_RF                 (1<<7)
-#define RSR_MF                 (1<<6)
-#define RSR_LCS                        (1<<5)
-#define RSR_RWTO               (1<<4)
-#define RSR_PLE                        (1<<3)
-#define RSR_AE                 (1<<2)
-#define RSR_CE                 (1<<1)
-#define RSR_FOE                        (1<<0)
-
-#define FCTR_HWOT(ot)  (( ot & 0xf ) << 4 )
-#define FCTR_LWOT(ot)  ( ot & 0xf )
-
-#define IMR_PAR                        (1<<7)
-#define IMR_ROOM               (1<<3)
-#define IMR_ROM                        (1<<2)
-#define IMR_PTM                        (1<<1)
-#define IMR_PRM                        (1<<0)
-
-#endif
diff --git a/drivers/ds1722.c b/drivers/ds1722.c
deleted file mode 100644 (file)
index c19ee01..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-
-#include <common.h>
-
-#ifdef CONFIG_DS1722
-
-#include <ssi.h>
-
-static void ds1722_select(int dev)
-{
-       ssi_set_interface(4096, 0, 0, 0);
-       ssi_chip_select(0);
-       udelay(1);
-       ssi_chip_select(dev);
-       udelay(1);
-}
-
-
-u8 ds1722_read(int dev, int addr)
-{
-       u8 res;
-
-       ds1722_select(dev);
-
-       ssi_tx_byte(addr);
-       res = ssi_rx_byte();
-
-       ssi_chip_select(0);
-
-       return res;
-}
-
-void ds1722_write(int dev, int addr, u8 data)
-{
-       ds1722_select(dev);
-
-       ssi_tx_byte(0x80|addr);
-       ssi_tx_byte(data);
-
-       ssi_chip_select(0);
-}
-
-
-u16 ds1722_temp(int dev, int resolution)
-{
-       static int useconds[] = {
-               75000, 150000, 300000, 600000, 1200000
-       };
-       char temp;
-       u16 res;
-
-
-       /* set up the desired resulotion ... */
-       ds1722_write(dev, 0, 0xe0 | (resolution << 1));
-
-       /* wait while the chip measures the tremperature */
-       udelay(useconds[resolution]);
-
-       res = (temp = ds1722_read(dev, 2)) << 8;
-
-       if (temp < 0) {
-               temp = (16 - (ds1722_read(dev, 1) >> 4)) & 0x0f;
-       } else {
-               temp = (ds1722_read(dev, 1) >> 4);
-       }
-
-       switch (temp) {
-       case 0:
-               /* .0000 */
-               break;
-       case 1:
-               /* .0625 */
-               res |=1;
-               break;
-       case 2:
-               /* .1250 */
-               res |=1;
-               break;
-       case 3:
-               /* .1875 */
-               res |=2;
-               break;
-       case 4:
-               /* .2500 */
-               res |=3;
-               break;
-       case 5:
-               /* .3125 */
-               res |=3;
-               break;
-       case 6:
-               /* .3750 */
-               res |=4;
-               break;
-       case 7:
-               /* .4375 */
-               res |=4;
-               break;
-       case 8:
-               /* .5000 */
-               res |=5;
-               break;
-       case 9:
-               /* .5625 */
-               res |=6;
-               break;
-       case 10:
-               /* .6250 */
-               res |=6;
-               break;
-       case 11:
-               /* .6875 */
-               res |=7;
-               break;
-       case 12:
-               /* .7500 */
-               res |=8;
-               break;
-       case 13:
-               /* .8125 */
-               res |=8;
-               break;
-       case 14:
-               /* .8750 */
-               res |=9;
-               break;
-       case 15:
-               /* .9375 */
-               res |=9;
-               break;
-       }
-       return res;
-
-}
-
-int ds1722_probe(int dev)
-{
-       u16 temp = ds1722_temp(dev, DS1722_RESOLUTION_12BIT);
-       printf("%d.%d deg C\n\n", (char)(temp >> 8), temp & 0xff);
-       return 0;
-}
-
-#endif
diff --git a/drivers/e1000.c b/drivers/e1000.c
deleted file mode 100644 (file)
index f0741da..0000000
+++ /dev/null
@@ -1,3016 +0,0 @@
-/**************************************************************************
-Inter Pro 1000 for ppcboot/das-u-boot
-Drivers are port from Intel's Linux driver e1000-4.3.15
-and from Etherboot pro 1000 driver by mrakes at vivato dot net
-tested on both gig copper and gig fiber boards
-***************************************************************************/
-/*******************************************************************************
-
-
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
-
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-
-  Contact Information:
-  Linux NICS <linux.nics@intel.com>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-/*
- *  Copyright (C) Archway Digital Solutions.
- *
- *  written by Chrsitopher Li <cli at arcyway dot com> or <chrisl at gnuchina dot org>
- *  2/9/2002
- *
- *  Copyright (C) Linux Networx.
- *  Massive upgrade to work with the new intel gigabit NICs.
- *  <ebiederman at lnxi dot com>
- */
-
-#include "e1000.h"
-
-#if defined(CONFIG_CMD_NET) \
-       && defined(CONFIG_NET_MULTI) && defined(CONFIG_E1000)
-
-#define TOUT_LOOP   100000
-
-#undef virt_to_bus
-#define        virt_to_bus(x)  ((unsigned long)x)
-#define bus_to_phys(devno, a)  pci_mem_to_phys(devno, a)
-#define mdelay(n)       udelay((n)*1000)
-
-#define E1000_DEFAULT_PBA    0x00000030
-
-/* NIC specific static variables go here */
-
-static char tx_pool[128 + 16];
-static char rx_pool[128 + 16];
-static char packet[2096];
-
-static struct e1000_tx_desc *tx_base;
-static struct e1000_rx_desc *rx_base;
-
-static int tx_tail;
-static int rx_tail, rx_last;
-
-static struct pci_device_id supported[] = {
-       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82542},
-       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_FIBER},
-       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_COPPER},
-       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_COPPER},
-       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_FIBER},
-       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_COPPER},
-       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_LOM},
-       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM},
-       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_COPPER},
-       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_COPPER},
-       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_FIBER},
-       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER},
-       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM_LOM},
-};
-
-/* Function forward declarations */
-static int e1000_setup_link(struct eth_device *nic);
-static int e1000_setup_fiber_link(struct eth_device *nic);
-static int e1000_setup_copper_link(struct eth_device *nic);
-static int e1000_phy_setup_autoneg(struct e1000_hw *hw);
-static void e1000_config_collision_dist(struct e1000_hw *hw);
-static int e1000_config_mac_to_phy(struct e1000_hw *hw);
-static int e1000_config_fc_after_link_up(struct e1000_hw *hw);
-static int e1000_check_for_link(struct eth_device *nic);
-static int e1000_wait_autoneg(struct e1000_hw *hw);
-static void e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed,
-                                      uint16_t * duplex);
-static int e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr,
-                             uint16_t * phy_data);
-static int e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr,
-                              uint16_t phy_data);
-static void e1000_phy_hw_reset(struct e1000_hw *hw);
-static int e1000_phy_reset(struct e1000_hw *hw);
-static int e1000_detect_gig_phy(struct e1000_hw *hw);
-
-#define E1000_WRITE_REG(a, reg, value) (writel((value), ((a)->hw_addr + E1000_##reg)))
-#define E1000_READ_REG(a, reg) (readl((a)->hw_addr + E1000_##reg))
-#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) (\
-                       writel((value), ((a)->hw_addr + E1000_##reg + ((offset) << 2))))
-#define E1000_READ_REG_ARRAY(a, reg, offset) ( \
-       readl((a)->hw_addr + E1000_##reg + ((offset) << 2)))
-#define E1000_WRITE_FLUSH(a) {uint32_t x; x = E1000_READ_REG(a, STATUS);}
-
-#ifndef CONFIG_AP1000 /* remove for warnings */
-/******************************************************************************
- * Raises the EEPROM's clock input.
- *
- * hw - Struct containing variables accessed by shared code
- * eecd - EECD's current value
- *****************************************************************************/
-static void
-e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t * eecd)
-{
-       /* Raise the clock input to the EEPROM (by setting the SK bit), and then
-        * wait 50 microseconds.
-        */
-       *eecd = *eecd | E1000_EECD_SK;
-       E1000_WRITE_REG(hw, EECD, *eecd);
-       E1000_WRITE_FLUSH(hw);
-       udelay(50);
-}
-
-/******************************************************************************
- * Lowers the EEPROM's clock input.
- *
- * hw - Struct containing variables accessed by shared code
- * eecd - EECD's current value
- *****************************************************************************/
-static void
-e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t * eecd)
-{
-       /* Lower the clock input to the EEPROM (by clearing the SK bit), and then
-        * wait 50 microseconds.
-        */
-       *eecd = *eecd & ~E1000_EECD_SK;
-       E1000_WRITE_REG(hw, EECD, *eecd);
-       E1000_WRITE_FLUSH(hw);
-       udelay(50);
-}
-
-/******************************************************************************
- * Shift data bits out to the EEPROM.
- *
- * hw - Struct containing variables accessed by shared code
- * data - data to send to the EEPROM
- * count - number of bits to shift out
- *****************************************************************************/
-static void
-e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t count)
-{
-       uint32_t eecd;
-       uint32_t mask;
-
-       /* We need to shift "count" bits out to the EEPROM. So, value in the
-        * "data" parameter will be shifted out to the EEPROM one bit at a time.
-        * In order to do this, "data" must be broken down into bits.
-        */
-       mask = 0x01 << (count - 1);
-       eecd = E1000_READ_REG(hw, EECD);
-       eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
-       do {
-               /* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
-                * and then raising and then lowering the clock (the SK bit controls
-                * the clock input to the EEPROM).  A "0" is shifted out to the EEPROM
-                * by setting "DI" to "0" and then raising and then lowering the clock.
-                */
-               eecd &= ~E1000_EECD_DI;
-
-               if (data & mask)
-                       eecd |= E1000_EECD_DI;
-
-               E1000_WRITE_REG(hw, EECD, eecd);
-               E1000_WRITE_FLUSH(hw);
-
-               udelay(50);
-
-               e1000_raise_ee_clk(hw, &eecd);
-               e1000_lower_ee_clk(hw, &eecd);
-
-               mask = mask >> 1;
-
-       } while (mask);
-
-       /* We leave the "DI" bit set to "0" when we leave this routine. */
-       eecd &= ~E1000_EECD_DI;
-       E1000_WRITE_REG(hw, EECD, eecd);
-}
-
-/******************************************************************************
- * Shift data bits in from the EEPROM
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static uint16_t
-e1000_shift_in_ee_bits(struct e1000_hw *hw)
-{
-       uint32_t eecd;
-       uint32_t i;
-       uint16_t data;
-
-       /* In order to read a register from the EEPROM, we need to shift 16 bits
-        * in from the EEPROM. Bits are "shifted in" by raising the clock input to
-        * the EEPROM (setting the SK bit), and then reading the value of the "DO"
-        * bit.  During this "shifting in" process the "DI" bit should always be
-        * clear..
-        */
-
-       eecd = E1000_READ_REG(hw, EECD);
-
-       eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
-       data = 0;
-
-       for (i = 0; i < 16; i++) {
-               data = data << 1;
-               e1000_raise_ee_clk(hw, &eecd);
-
-               eecd = E1000_READ_REG(hw, EECD);
-
-               eecd &= ~(E1000_EECD_DI);
-               if (eecd & E1000_EECD_DO)
-                       data |= 1;
-
-               e1000_lower_ee_clk(hw, &eecd);
-       }
-
-       return data;
-}
-
-/******************************************************************************
- * Prepares EEPROM for access
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
- * function should be called before issuing a command to the EEPROM.
- *****************************************************************************/
-static void
-e1000_setup_eeprom(struct e1000_hw *hw)
-{
-       uint32_t eecd;
-
-       eecd = E1000_READ_REG(hw, EECD);
-
-       /* Clear SK and DI */
-       eecd &= ~(E1000_EECD_SK | E1000_EECD_DI);
-       E1000_WRITE_REG(hw, EECD, eecd);
-
-       /* Set CS */
-       eecd |= E1000_EECD_CS;
-       E1000_WRITE_REG(hw, EECD, eecd);
-}
-
-/******************************************************************************
- * Returns EEPROM to a "standby" state
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static void
-e1000_standby_eeprom(struct e1000_hw *hw)
-{
-       uint32_t eecd;
-
-       eecd = E1000_READ_REG(hw, EECD);
-
-       /* Deselct EEPROM */
-       eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
-       E1000_WRITE_REG(hw, EECD, eecd);
-       E1000_WRITE_FLUSH(hw);
-       udelay(50);
-
-       /* Clock high */
-       eecd |= E1000_EECD_SK;
-       E1000_WRITE_REG(hw, EECD, eecd);
-       E1000_WRITE_FLUSH(hw);
-       udelay(50);
-
-       /* Select EEPROM */
-       eecd |= E1000_EECD_CS;
-       E1000_WRITE_REG(hw, EECD, eecd);
-       E1000_WRITE_FLUSH(hw);
-       udelay(50);
-
-       /* Clock low */
-       eecd &= ~E1000_EECD_SK;
-       E1000_WRITE_REG(hw, EECD, eecd);
-       E1000_WRITE_FLUSH(hw);
-       udelay(50);
-}
-
-/******************************************************************************
- * Reads a 16 bit word from the EEPROM.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset of  word in the EEPROM to read
- * data - word read from the EEPROM
- *****************************************************************************/
-static int
-e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, uint16_t * data)
-{
-       uint32_t eecd;
-       uint32_t i = 0;
-       int large_eeprom = FALSE;
-
-       /* Request EEPROM Access */
-       if (hw->mac_type > e1000_82544) {
-               eecd = E1000_READ_REG(hw, EECD);
-               if (eecd & E1000_EECD_SIZE)
-                       large_eeprom = TRUE;
-               eecd |= E1000_EECD_REQ;
-               E1000_WRITE_REG(hw, EECD, eecd);
-               eecd = E1000_READ_REG(hw, EECD);
-               while ((!(eecd & E1000_EECD_GNT)) && (i < 100)) {
-                       i++;
-                       udelay(10);
-                       eecd = E1000_READ_REG(hw, EECD);
-               }
-               if (!(eecd & E1000_EECD_GNT)) {
-                       eecd &= ~E1000_EECD_REQ;
-                       E1000_WRITE_REG(hw, EECD, eecd);
-                       DEBUGOUT("Could not acquire EEPROM grant\n");
-                       return -E1000_ERR_EEPROM;
-               }
-       }
-
-       /*  Prepare the EEPROM for reading  */
-       e1000_setup_eeprom(hw);
-
-       /*  Send the READ command (opcode + addr)  */
-       e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE, 3);
-       e1000_shift_out_ee_bits(hw, offset, (large_eeprom) ? 8 : 6);
-
-       /* Read the data */
-       *data = e1000_shift_in_ee_bits(hw);
-
-       /* End this read operation */
-       e1000_standby_eeprom(hw);
-
-       /* Stop requesting EEPROM access */
-       if (hw->mac_type > e1000_82544) {
-               eecd = E1000_READ_REG(hw, EECD);
-               eecd &= ~E1000_EECD_REQ;
-               E1000_WRITE_REG(hw, EECD, eecd);
-       }
-
-       return 0;
-}
-
-#if 0
-static void
-e1000_eeprom_cleanup(struct e1000_hw *hw)
-{
-       uint32_t eecd;
-
-       eecd = E1000_READ_REG(hw, EECD);
-       eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
-       E1000_WRITE_REG(hw, EECD, eecd);
-       e1000_raise_ee_clk(hw, &eecd);
-       e1000_lower_ee_clk(hw, &eecd);
-}
-
-static uint16_t
-e1000_wait_eeprom_done(struct e1000_hw *hw)
-{
-       uint32_t eecd;
-       uint32_t i;
-
-       e1000_standby_eeprom(hw);
-       for (i = 0; i < 200; i++) {
-               eecd = E1000_READ_REG(hw, EECD);
-               if (eecd & E1000_EECD_DO)
-                       return (TRUE);
-               udelay(5);
-       }
-       return (FALSE);
-}
-
-static int
-e1000_write_eeprom(struct e1000_hw *hw, uint16_t Reg, uint16_t Data)
-{
-       uint32_t eecd;
-       int large_eeprom = FALSE;
-       int i = 0;
-
-       /* Request EEPROM Access */
-       if (hw->mac_type > e1000_82544) {
-               eecd = E1000_READ_REG(hw, EECD);
-               if (eecd & E1000_EECD_SIZE)
-                       large_eeprom = TRUE;
-               eecd |= E1000_EECD_REQ;
-               E1000_WRITE_REG(hw, EECD, eecd);
-               eecd = E1000_READ_REG(hw, EECD);
-               while ((!(eecd & E1000_EECD_GNT)) && (i < 100)) {
-                       i++;
-                       udelay(5);
-                       eecd = E1000_READ_REG(hw, EECD);
-               }
-               if (!(eecd & E1000_EECD_GNT)) {
-                       eecd &= ~E1000_EECD_REQ;
-                       E1000_WRITE_REG(hw, EECD, eecd);
-                       DEBUGOUT("Could not acquire EEPROM grant\n");
-                       return FALSE;
-               }
-       }
-       e1000_setup_eeprom(hw);
-       e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE, 5);
-       e1000_shift_out_ee_bits(hw, Reg, (large_eeprom) ? 6 : 4);
-       e1000_standby_eeprom(hw);
-       e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE, 3);
-       e1000_shift_out_ee_bits(hw, Reg, (large_eeprom) ? 8 : 6);
-       e1000_shift_out_ee_bits(hw, Data, 16);
-       if (!e1000_wait_eeprom_done(hw)) {
-               return FALSE;
-       }
-       e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE, 5);
-       e1000_shift_out_ee_bits(hw, Reg, (large_eeprom) ? 6 : 4);
-       e1000_eeprom_cleanup(hw);
-
-       /* Stop requesting EEPROM access */
-       if (hw->mac_type > e1000_82544) {
-               eecd = E1000_READ_REG(hw, EECD);
-               eecd &= ~E1000_EECD_REQ;
-               E1000_WRITE_REG(hw, EECD, eecd);
-       }
-       i = 0;
-       eecd = E1000_READ_REG(hw, EECD);
-       while (((eecd & E1000_EECD_GNT)) && (i < 500)) {
-               i++;
-               udelay(10);
-               eecd = E1000_READ_REG(hw, EECD);
-       }
-       if ((eecd & E1000_EECD_GNT)) {
-               DEBUGOUT("Could not release EEPROM grant\n");
-       }
-       return TRUE;
-}
-#endif
-
-/******************************************************************************
- * Verifies that the EEPROM has a valid checksum
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Reads the first 64 16 bit words of the EEPROM and sums the values read.
- * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
- * valid.
- *****************************************************************************/
-static int
-e1000_validate_eeprom_checksum(struct eth_device *nic)
-{
-       struct e1000_hw *hw = nic->priv;
-       uint16_t checksum = 0;
-       uint16_t i, eeprom_data;
-
-       DEBUGFUNC();
-
-       for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
-               if (e1000_read_eeprom(hw, i, &eeprom_data) < 0) {
-                       DEBUGOUT("EEPROM Read Error\n");
-                       return -E1000_ERR_EEPROM;
-               }
-               checksum += eeprom_data;
-       }
-
-       if (checksum == (uint16_t) EEPROM_SUM) {
-               return 0;
-       } else {
-               DEBUGOUT("EEPROM Checksum Invalid\n");
-               return -E1000_ERR_EEPROM;
-       }
-}
-#endif /* #ifndef CONFIG_AP1000 */
-
-/******************************************************************************
- * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
- * second function of dual function devices
- *
- * nic - Struct containing variables accessed by shared code
- *****************************************************************************/
-static int
-e1000_read_mac_addr(struct eth_device *nic)
-{
-#ifndef CONFIG_AP1000
-       struct e1000_hw *hw = nic->priv;
-       uint16_t offset;
-       uint16_t eeprom_data;
-       int i;
-
-       DEBUGFUNC();
-
-       for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
-               offset = i >> 1;
-               if (e1000_read_eeprom(hw, offset, &eeprom_data) < 0) {
-                       DEBUGOUT("EEPROM Read Error\n");
-                       return -E1000_ERR_EEPROM;
-               }
-               nic->enetaddr[i] = eeprom_data & 0xff;
-               nic->enetaddr[i + 1] = (eeprom_data >> 8) & 0xff;
-       }
-       if ((hw->mac_type == e1000_82546) &&
-           (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
-               /* Invert the last bit if this is the second device */
-               nic->enetaddr[5] += 1;
-       }
-#else
-       /*
-        * The AP1000's e1000 has no eeprom; the MAC address is stored in the
-        * environment variables.  Currently this does not support the addition
-        * of a PMC e1000 card, which is certainly a possibility, so this should
-        * be updated to properly use the env variable only for the onboard e1000
-        */
-
-       int ii;
-       char *s, *e;
-
-       DEBUGFUNC();
-
-       s = getenv ("ethaddr");
-       if (s == NULL){
-               return -E1000_ERR_EEPROM;
-       }
-       else{
-               for(ii = 0; ii < 6; ii++) {
-                       nic->enetaddr[ii] = s ? simple_strtoul (s, &e, 16) : 0;
-                       if (s){
-                               s = (*e) ? e + 1 : e;
-                       }
-               }
-       }
-#endif
-       return 0;
-}
-
-/******************************************************************************
- * Initializes receive address filters.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Places the MAC address in receive address register 0 and clears the rest
- * of the receive addresss registers. Clears the multicast table. Assumes
- * the receiver is in reset when the routine is called.
- *****************************************************************************/
-static void
-e1000_init_rx_addrs(struct eth_device *nic)
-{
-       struct e1000_hw *hw = nic->priv;
-       uint32_t i;
-       uint32_t addr_low;
-       uint32_t addr_high;
-
-       DEBUGFUNC();
-
-       /* Setup the receive address. */
-       DEBUGOUT("Programming MAC Address into RAR[0]\n");
-       addr_low = (nic->enetaddr[0] |
-                   (nic->enetaddr[1] << 8) |
-                   (nic->enetaddr[2] << 16) | (nic->enetaddr[3] << 24));
-
-       addr_high = (nic->enetaddr[4] | (nic->enetaddr[5] << 8) | E1000_RAH_AV);
-
-       E1000_WRITE_REG_ARRAY(hw, RA, 0, addr_low);
-       E1000_WRITE_REG_ARRAY(hw, RA, 1, addr_high);
-
-       /* Zero out the other 15 receive addresses. */
-       DEBUGOUT("Clearing RAR[1-15]\n");
-       for (i = 1; i < E1000_RAR_ENTRIES; i++) {
-               E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
-               E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
-       }
-}
-
-/******************************************************************************
- * Clears the VLAN filer table
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static void
-e1000_clear_vfta(struct e1000_hw *hw)
-{
-       uint32_t offset;
-
-       for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++)
-               E1000_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
-}
-
-/******************************************************************************
- * Set the mac type member in the hw struct.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static int
-e1000_set_mac_type(struct e1000_hw *hw)
-{
-       DEBUGFUNC();
-
-       switch (hw->device_id) {
-       case E1000_DEV_ID_82542:
-               switch (hw->revision_id) {
-               case E1000_82542_2_0_REV_ID:
-                       hw->mac_type = e1000_82542_rev2_0;
-                       break;
-               case E1000_82542_2_1_REV_ID:
-                       hw->mac_type = e1000_82542_rev2_1;
-                       break;
-               default:
-                       /* Invalid 82542 revision ID */
-                       return -E1000_ERR_MAC_TYPE;
-               }
-               break;
-       case E1000_DEV_ID_82543GC_FIBER:
-       case E1000_DEV_ID_82543GC_COPPER:
-               hw->mac_type = e1000_82543;
-               break;
-       case E1000_DEV_ID_82544EI_COPPER:
-       case E1000_DEV_ID_82544EI_FIBER:
-       case E1000_DEV_ID_82544GC_COPPER:
-       case E1000_DEV_ID_82544GC_LOM:
-               hw->mac_type = e1000_82544;
-               break;
-       case E1000_DEV_ID_82540EM:
-       case E1000_DEV_ID_82540EM_LOM:
-               hw->mac_type = e1000_82540;
-               break;
-       case E1000_DEV_ID_82545EM_COPPER:
-       case E1000_DEV_ID_82545EM_FIBER:
-               hw->mac_type = e1000_82545;
-               break;
-       case E1000_DEV_ID_82546EB_COPPER:
-       case E1000_DEV_ID_82546EB_FIBER:
-               hw->mac_type = e1000_82546;
-               break;
-       default:
-               /* Should never have loaded on this device */
-               return -E1000_ERR_MAC_TYPE;
-       }
-       return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Reset the transmit and receive units; mask and clear all interrupts.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-void
-e1000_reset_hw(struct e1000_hw *hw)
-{
-       uint32_t ctrl;
-       uint32_t ctrl_ext;
-       uint32_t icr;
-       uint32_t manc;
-
-       DEBUGFUNC();
-
-       /* For 82542 (rev 2.0), disable MWI before issuing a device reset */
-       if (hw->mac_type == e1000_82542_rev2_0) {
-               DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
-               pci_write_config_word(hw->pdev, PCI_COMMAND,
-                                     hw->
-                                     pci_cmd_word & ~PCI_COMMAND_INVALIDATE);
-       }
-
-       /* Clear interrupt mask to stop board from generating interrupts */
-       DEBUGOUT("Masking off all interrupts\n");
-       E1000_WRITE_REG(hw, IMC, 0xffffffff);
-
-       /* Disable the Transmit and Receive units.  Then delay to allow
-        * any pending transactions to complete before we hit the MAC with
-        * the global reset.
-        */
-       E1000_WRITE_REG(hw, RCTL, 0);
-       E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP);
-       E1000_WRITE_FLUSH(hw);
-
-       /* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
-       hw->tbi_compatibility_on = FALSE;
-
-       /* Delay to allow any outstanding PCI transactions to complete before
-        * resetting the device
-        */
-       mdelay(10);
-
-       /* Issue a global reset to the MAC.  This will reset the chip's
-        * transmit, receive, DMA, and link units.  It will not effect
-        * the current PCI configuration.  The global reset bit is self-
-        * clearing, and should clear within a microsecond.
-        */
-       DEBUGOUT("Issuing a global reset to MAC\n");
-       ctrl = E1000_READ_REG(hw, CTRL);
-
-#if 0
-       if (hw->mac_type > e1000_82543)
-               E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
-       else
-#endif
-               E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
-
-       /* Force a reload from the EEPROM if necessary */
-       if (hw->mac_type < e1000_82540) {
-               /* Wait for reset to complete */
-               udelay(10);
-               ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
-               ctrl_ext |= E1000_CTRL_EXT_EE_RST;
-               E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-               E1000_WRITE_FLUSH(hw);
-               /* Wait for EEPROM reload */
-               mdelay(2);
-       } else {
-               /* Wait for EEPROM reload (it happens automatically) */
-               mdelay(4);
-               /* Dissable HW ARPs on ASF enabled adapters */
-               manc = E1000_READ_REG(hw, MANC);
-               manc &= ~(E1000_MANC_ARP_EN);
-               E1000_WRITE_REG(hw, MANC, manc);
-       }
-
-       /* Clear interrupt mask to stop board from generating interrupts */
-       DEBUGOUT("Masking off all interrupts\n");
-       E1000_WRITE_REG(hw, IMC, 0xffffffff);
-
-       /* Clear any pending interrupt events. */
-       icr = E1000_READ_REG(hw, ICR);
-
-       /* If MWI was previously enabled, reenable it. */
-       if (hw->mac_type == e1000_82542_rev2_0) {
-               pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word);
-       }
-}
-
-/******************************************************************************
- * Performs basic configuration of the adapter.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Assumes that the controller has previously been reset and is in a
- * post-reset uninitialized state. Initializes the receive address registers,
- * multicast table, and VLAN filter table. Calls routines to setup link
- * configuration and flow control settings. Clears all on-chip counters. Leaves
- * the transmit and receive units disabled and uninitialized.
- *****************************************************************************/
-static int
-e1000_init_hw(struct eth_device *nic)
-{
-       struct e1000_hw *hw = nic->priv;
-       uint32_t ctrl, status;
-       uint32_t i;
-       int32_t ret_val;
-       uint16_t pcix_cmd_word;
-       uint16_t pcix_stat_hi_word;
-       uint16_t cmd_mmrbc;
-       uint16_t stat_mmrbc;
-       e1000_bus_type bus_type = e1000_bus_type_unknown;
-
-       DEBUGFUNC();
-#if 0
-       /* Initialize Identification LED */
-       ret_val = e1000_id_led_init(hw);
-       if (ret_val < 0) {
-               DEBUGOUT("Error Initializing Identification LED\n");
-               return ret_val;
-       }
-#endif
-       /* Set the Media Type and exit with error if it is not valid. */
-       if (hw->mac_type != e1000_82543) {
-               /* tbi_compatibility is only valid on 82543 */
-               hw->tbi_compatibility_en = FALSE;
-       }
-
-       if (hw->mac_type >= e1000_82543) {
-               status = E1000_READ_REG(hw, STATUS);
-               if (status & E1000_STATUS_TBIMODE) {
-                       hw->media_type = e1000_media_type_fiber;
-                       /* tbi_compatibility not valid on fiber */
-                       hw->tbi_compatibility_en = FALSE;
-               } else {
-                       hw->media_type = e1000_media_type_copper;
-               }
-       } else {
-               /* This is an 82542 (fiber only) */
-               hw->media_type = e1000_media_type_fiber;
-       }
-
-       /* Disabling VLAN filtering. */
-       DEBUGOUT("Initializing the IEEE VLAN\n");
-       E1000_WRITE_REG(hw, VET, 0);
-
-       e1000_clear_vfta(hw);
-
-       /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
-       if (hw->mac_type == e1000_82542_rev2_0) {
-               DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
-               pci_write_config_word(hw->pdev, PCI_COMMAND,
-                                     hw->
-                                     pci_cmd_word & ~PCI_COMMAND_INVALIDATE);
-               E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST);
-               E1000_WRITE_FLUSH(hw);
-               mdelay(5);
-       }
-
-       /* Setup the receive address. This involves initializing all of the Receive
-        * Address Registers (RARs 0 - 15).
-        */
-       e1000_init_rx_addrs(nic);
-
-       /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
-       if (hw->mac_type == e1000_82542_rev2_0) {
-               E1000_WRITE_REG(hw, RCTL, 0);
-               E1000_WRITE_FLUSH(hw);
-               mdelay(1);
-               pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word);
-       }
-
-       /* Zero out the Multicast HASH table */
-       DEBUGOUT("Zeroing the MTA\n");
-       for (i = 0; i < E1000_MC_TBL_SIZE; i++)
-               E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
-
-#if 0
-       /* Set the PCI priority bit correctly in the CTRL register.  This
-        * determines if the adapter gives priority to receives, or if it
-        * gives equal priority to transmits and receives.
-        */
-       if (hw->dma_fairness) {
-               ctrl = E1000_READ_REG(hw, CTRL);
-               E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);
-       }
-#endif
-       if (hw->mac_type >= e1000_82543) {
-               status = E1000_READ_REG(hw, STATUS);
-               bus_type = (status & E1000_STATUS_PCIX_MODE) ?
-                   e1000_bus_type_pcix : e1000_bus_type_pci;
-       }
-       /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
-       if (bus_type == e1000_bus_type_pcix) {
-               pci_read_config_word(hw->pdev, PCIX_COMMAND_REGISTER,
-                                    &pcix_cmd_word);
-               pci_read_config_word(hw->pdev, PCIX_STATUS_REGISTER_HI,
-                                    &pcix_stat_hi_word);
-               cmd_mmrbc =
-                   (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >>
-                   PCIX_COMMAND_MMRBC_SHIFT;
-               stat_mmrbc =
-                   (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
-                   PCIX_STATUS_HI_MMRBC_SHIFT;
-               if (stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
-                       stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
-               if (cmd_mmrbc > stat_mmrbc) {
-                       pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;
-                       pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
-                       pci_write_config_word(hw->pdev, PCIX_COMMAND_REGISTER,
-                                             pcix_cmd_word);
-               }
-       }
-
-       /* Call a subroutine to configure the link and setup flow control. */
-       ret_val = e1000_setup_link(nic);
-
-       /* Set the transmit descriptor write-back policy */
-       if (hw->mac_type > e1000_82544) {
-               ctrl = E1000_READ_REG(hw, TXDCTL);
-               ctrl =
-                   (ctrl & ~E1000_TXDCTL_WTHRESH) |
-                   E1000_TXDCTL_FULL_TX_DESC_WB;
-               E1000_WRITE_REG(hw, TXDCTL, ctrl);
-       }
-#if 0
-       /* Clear all of the statistics registers (clear on read).  It is
-        * important that we do this after we have tried to establish link
-        * because the symbol error count will increment wildly if there
-        * is no link.
-        */
-       e1000_clear_hw_cntrs(hw);
-#endif
-
-       return ret_val;
-}
-
-/******************************************************************************
- * Configures flow control and link settings.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Determines which flow control settings to use. Calls the apropriate media-
- * specific link configuration function. Configures the flow control settings.
- * Assuming the adapter has a valid link partner, a valid link should be
- * established. Assumes the hardware has previously been reset and the
- * transmitter and receiver are not enabled.
- *****************************************************************************/
-static int
-e1000_setup_link(struct eth_device *nic)
-{
-       struct e1000_hw *hw = nic->priv;
-       uint32_t ctrl_ext;
-       int32_t ret_val;
-       uint16_t eeprom_data;
-
-       DEBUGFUNC();
-
-#ifndef CONFIG_AP1000
-       /* Read and store word 0x0F of the EEPROM. This word contains bits
-        * that determine the hardware's default PAUSE (flow control) mode,
-        * a bit that determines whether the HW defaults to enabling or
-        * disabling auto-negotiation, and the direction of the
-        * SW defined pins. If there is no SW over-ride of the flow
-        * control setting, then the variable hw->fc will
-        * be initialized based on a value in the EEPROM.
-        */
-       if (e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, &eeprom_data) < 0) {
-               DEBUGOUT("EEPROM Read Error\n");
-               return -E1000_ERR_EEPROM;
-       }
-#else
-       /* we have to hardcode the proper value for our hardware. */
-       /* this value is for the 82540EM pci card used for prototyping, and it works. */
-       eeprom_data = 0xb220;
-#endif
-
-       if (hw->fc == e1000_fc_default) {
-               if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
-                       hw->fc = e1000_fc_none;
-               else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
-                        EEPROM_WORD0F_ASM_DIR)
-                       hw->fc = e1000_fc_tx_pause;
-               else
-                       hw->fc = e1000_fc_full;
-       }
-
-       /* We want to save off the original Flow Control configuration just
-        * in case we get disconnected and then reconnected into a different
-        * hub or switch with different Flow Control capabilities.
-        */
-       if (hw->mac_type == e1000_82542_rev2_0)
-               hw->fc &= (~e1000_fc_tx_pause);
-
-       if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
-               hw->fc &= (~e1000_fc_rx_pause);
-
-       hw->original_fc = hw->fc;
-
-       DEBUGOUT("After fix-ups FlowControl is now = %x\n", hw->fc);
-
-       /* Take the 4 bits from EEPROM word 0x0F that determine the initial
-        * polarity value for the SW controlled pins, and setup the
-        * Extended Device Control reg with that info.
-        * This is needed because one of the SW controlled pins is used for
-        * signal detection.  So this should be done before e1000_setup_pcs_link()
-        * or e1000_phy_setup() is called.
-        */
-       if (hw->mac_type == e1000_82543) {
-               ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) <<
-                           SWDPIO__EXT_SHIFT);
-               E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-       }
-
-       /* Call the necessary subroutine to configure the link. */
-       ret_val = (hw->media_type == e1000_media_type_fiber) ?
-           e1000_setup_fiber_link(nic) : e1000_setup_copper_link(nic);
-       if (ret_val < 0) {
-               return ret_val;
-       }
-
-       /* Initialize the flow control address, type, and PAUSE timer
-        * registers to their default values.  This is done even if flow
-        * control is disabled, because it does not hurt anything to
-        * initialize these registers.
-        */
-       DEBUGOUT
-           ("Initializing the Flow Control address, type and timer regs\n");
-
-       E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW);
-       E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH);
-       E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE);
-       E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time);
-
-       /* Set the flow control receive threshold registers.  Normally,
-        * these registers will be set to a default threshold that may be
-        * adjusted later by the driver's runtime code.  However, if the
-        * ability to transmit pause frames in not enabled, then these
-        * registers will be set to 0.
-        */
-       if (!(hw->fc & e1000_fc_tx_pause)) {
-               E1000_WRITE_REG(hw, FCRTL, 0);
-               E1000_WRITE_REG(hw, FCRTH, 0);
-       } else {
-               /* We need to set up the Receive Threshold high and low water marks
-                * as well as (optionally) enabling the transmission of XON frames.
-                */
-               if (hw->fc_send_xon) {
-                       E1000_WRITE_REG(hw, FCRTL,
-                                       (hw->fc_low_water | E1000_FCRTL_XONE));
-                       E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
-               } else {
-                       E1000_WRITE_REG(hw, FCRTL, hw->fc_low_water);
-                       E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
-               }
-       }
-       return ret_val;
-}
-
-/******************************************************************************
- * Sets up link for a fiber based adapter
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Manipulates Physical Coding Sublayer functions in order to configure
- * link. Assumes the hardware has been previously reset and the transmitter
- * and receiver are not enabled.
- *****************************************************************************/
-static int
-e1000_setup_fiber_link(struct eth_device *nic)
-{
-       struct e1000_hw *hw = nic->priv;
-       uint32_t ctrl;
-       uint32_t status;
-       uint32_t txcw = 0;
-       uint32_t i;
-       uint32_t signal;
-       int32_t ret_val;
-
-       DEBUGFUNC();
-       /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be
-        * set when the optics detect a signal. On older adapters, it will be
-        * cleared when there is a signal
-        */
-       ctrl = E1000_READ_REG(hw, CTRL);
-       if ((hw->mac_type > e1000_82544) && !(ctrl & E1000_CTRL_ILOS))
-               signal = E1000_CTRL_SWDPIN1;
-       else
-               signal = 0;
-
-       printf("signal for %s is %x (ctrl %08x)!!!!\n", nic->name, signal,
-              ctrl);
-       /* Take the link out of reset */
-       ctrl &= ~(E1000_CTRL_LRST);
-
-       e1000_config_collision_dist(hw);
-
-       /* Check for a software override of the flow control settings, and setup
-        * the device accordingly.  If auto-negotiation is enabled, then software
-        * will have to set the "PAUSE" bits to the correct value in the Tranmsit
-        * Config Word Register (TXCW) and re-start auto-negotiation.  However, if
-        * auto-negotiation is disabled, then software will have to manually
-        * configure the two flow control enable bits in the CTRL register.
-        *
-        * The possible values of the "fc" parameter are:
-        *      0:  Flow control is completely disabled
-        *      1:  Rx flow control is enabled (we can receive pause frames, but
-        *          not send pause frames).
-        *      2:  Tx flow control is enabled (we can send pause frames but we do
-        *          not support receiving pause frames).
-        *      3:  Both Rx and TX flow control (symmetric) are enabled.
-        */
-       switch (hw->fc) {
-       case e1000_fc_none:
-               /* Flow control is completely disabled by a software over-ride. */
-               txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
-               break;
-       case e1000_fc_rx_pause:
-               /* RX Flow control is enabled and TX Flow control is disabled by a
-                * software over-ride. Since there really isn't a way to advertise
-                * that we are capable of RX Pause ONLY, we will advertise that we
-                * support both symmetric and asymmetric RX PAUSE. Later, we will
-                *  disable the adapter's ability to send PAUSE frames.
-                */
-               txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
-               break;
-       case e1000_fc_tx_pause:
-               /* TX Flow control is enabled, and RX Flow control is disabled, by a
-                * software over-ride.
-                */
-               txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
-               break;
-       case e1000_fc_full:
-               /* Flow control (both RX and TX) is enabled by a software over-ride. */
-               txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
-               break;
-       default:
-               DEBUGOUT("Flow control param set incorrectly\n");
-               return -E1000_ERR_CONFIG;
-               break;
-       }
-
-       /* Since auto-negotiation is enabled, take the link out of reset (the link
-        * will be in reset, because we previously reset the chip). This will
-        * restart auto-negotiation.  If auto-neogtiation is successful then the
-        * link-up status bit will be set and the flow control enable bits (RFCE
-        * and TFCE) will be set according to their negotiated value.
-        */
-       DEBUGOUT("Auto-negotiation enabled (%#x)\n", txcw);
-
-       E1000_WRITE_REG(hw, TXCW, txcw);
-       E1000_WRITE_REG(hw, CTRL, ctrl);
-       E1000_WRITE_FLUSH(hw);
-
-       hw->txcw = txcw;
-       mdelay(1);
-
-       /* If we have a signal (the cable is plugged in) then poll for a "Link-Up"
-        * indication in the Device Status Register.  Time-out if a link isn't
-        * seen in 500 milliseconds seconds (Auto-negotiation should complete in
-        * less than 500 milliseconds even if the other end is doing it in SW).
-        */
-       if ((E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) {
-               DEBUGOUT("Looking for Link\n");
-               for (i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
-                       mdelay(10);
-                       status = E1000_READ_REG(hw, STATUS);
-                       if (status & E1000_STATUS_LU)
-                               break;
-               }
-               if (i == (LINK_UP_TIMEOUT / 10)) {
-                       /* AutoNeg failed to achieve a link, so we'll call
-                        * e1000_check_for_link. This routine will force the link up if we
-                        * detect a signal. This will allow us to communicate with
-                        * non-autonegotiating link partners.
-                        */
-                       DEBUGOUT("Never got a valid link from auto-neg!!!\n");
-                       hw->autoneg_failed = 1;
-                       ret_val = e1000_check_for_link(nic);
-                       if (ret_val < 0) {
-                               DEBUGOUT("Error while checking for link\n");
-                               return ret_val;
-                       }
-                       hw->autoneg_failed = 0;
-               } else {
-                       hw->autoneg_failed = 0;
-                       DEBUGOUT("Valid Link Found\n");
-               }
-       } else {
-               DEBUGOUT("No Signal Detected\n");
-               return -E1000_ERR_NOLINK;
-       }
-       return 0;
-}
-
-/******************************************************************************
-* Detects which PHY is present and the speed and duplex
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static int
-e1000_setup_copper_link(struct eth_device *nic)
-{
-       struct e1000_hw *hw = nic->priv;
-       uint32_t ctrl;
-       int32_t ret_val;
-       uint16_t i;
-       uint16_t phy_data;
-
-       DEBUGFUNC();
-
-       ctrl = E1000_READ_REG(hw, CTRL);
-       /* With 82543, we need to force speed and duplex on the MAC equal to what
-        * the PHY speed and duplex configuration is. In addition, we need to
-        * perform a hardware reset on the PHY to take it out of reset.
-        */
-       if (hw->mac_type > e1000_82543) {
-               ctrl |= E1000_CTRL_SLU;
-               ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
-               E1000_WRITE_REG(hw, CTRL, ctrl);
-       } else {
-               ctrl |=
-                   (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU);
-               E1000_WRITE_REG(hw, CTRL, ctrl);
-               e1000_phy_hw_reset(hw);
-       }
-
-       /* Make sure we have a valid PHY */
-       ret_val = e1000_detect_gig_phy(hw);
-       if (ret_val < 0) {
-               DEBUGOUT("Error, did not detect valid phy.\n");
-               return ret_val;
-       }
-       DEBUGOUT("Phy ID = %x \n", hw->phy_id);
-
-       /* Enable CRS on TX. This must be set for half-duplex operation. */
-       if (e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
-               DEBUGOUT("PHY Read Error\n");
-               return -E1000_ERR_PHY;
-       }
-       phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
-
-#if 0
-       /* Options:
-        *   MDI/MDI-X = 0 (default)
-        *   0 - Auto for all speeds
-        *   1 - MDI mode
-        *   2 - MDI-X mode
-        *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
-        */
-       phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
-       switch (hw->mdix) {
-       case 1:
-               phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
-               break;
-       case 2:
-               phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
-               break;
-       case 3:
-               phy_data |= M88E1000_PSCR_AUTO_X_1000T;
-               break;
-       case 0:
-       default:
-               phy_data |= M88E1000_PSCR_AUTO_X_MODE;
-               break;
-       }
-#else
-       phy_data |= M88E1000_PSCR_AUTO_X_MODE;
-#endif
-
-#if 0
-       /* Options:
-        *   disable_polarity_correction = 0 (default)
-        *       Automatic Correction for Reversed Cable Polarity
-        *   0 - Disabled
-        *   1 - Enabled
-        */
-       phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
-       if (hw->disable_polarity_correction == 1)
-               phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
-#else
-       phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
-#endif
-       if (e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) {
-               DEBUGOUT("PHY Write Error\n");
-               return -E1000_ERR_PHY;
-       }
-
-       /* Force TX_CLK in the Extended PHY Specific Control Register
-        * to 25MHz clock.
-        */
-       if (e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data) < 0) {
-               DEBUGOUT("PHY Read Error\n");
-               return -E1000_ERR_PHY;
-       }
-       phy_data |= M88E1000_EPSCR_TX_CLK_25;
-       /* Configure Master and Slave downshift values */
-       phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
-                     M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
-       phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
-                    M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
-       if (e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data) < 0) {
-               DEBUGOUT("PHY Write Error\n");
-               return -E1000_ERR_PHY;
-       }
-
-       /* SW Reset the PHY so all changes take effect */
-       ret_val = e1000_phy_reset(hw);
-       if (ret_val < 0) {
-               DEBUGOUT("Error Resetting the PHY\n");
-               return ret_val;
-       }
-
-       /* Options:
-        *   autoneg = 1 (default)
-        *      PHY will advertise value(s) parsed from
-        *      autoneg_advertised and fc
-        *   autoneg = 0
-        *      PHY will be set to 10H, 10F, 100H, or 100F
-        *      depending on value parsed from forced_speed_duplex.
-        */
-
-       /* Is autoneg enabled?  This is enabled by default or by software override.
-        * If so, call e1000_phy_setup_autoneg routine to parse the
-        * autoneg_advertised and fc options. If autoneg is NOT enabled, then the
-        * user should have provided a speed/duplex override.  If so, then call
-        * e1000_phy_force_speed_duplex to parse and set this up.
-        */
-       /* Perform some bounds checking on the hw->autoneg_advertised
-        * parameter.  If this variable is zero, then set it to the default.
-        */
-       hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
-
-       /* If autoneg_advertised is zero, we assume it was not defaulted
-        * by the calling code so we set to advertise full capability.
-        */
-       if (hw->autoneg_advertised == 0)
-               hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
-
-       DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
-       ret_val = e1000_phy_setup_autoneg(hw);
-       if (ret_val < 0) {
-               DEBUGOUT("Error Setting up Auto-Negotiation\n");
-               return ret_val;
-       }
-       DEBUGOUT("Restarting Auto-Neg\n");
-
-       /* Restart auto-negotiation by setting the Auto Neg Enable bit and
-        * the Auto Neg Restart bit in the PHY control register.
-        */
-       if (e1000_read_phy_reg(hw, PHY_CTRL, &phy_data) < 0) {
-               DEBUGOUT("PHY Read Error\n");
-               return -E1000_ERR_PHY;
-       }
-       phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
-       if (e1000_write_phy_reg(hw, PHY_CTRL, phy_data) < 0) {
-               DEBUGOUT("PHY Write Error\n");
-               return -E1000_ERR_PHY;
-       }
-#if 0
-       /* Does the user want to wait for Auto-Neg to complete here, or
-        * check at a later time (for example, callback routine).
-        */
-       if (hw->wait_autoneg_complete) {
-               ret_val = e1000_wait_autoneg(hw);
-               if (ret_val < 0) {
-                       DEBUGOUT
-                           ("Error while waiting for autoneg to complete\n");
-                       return ret_val;
-               }
-       }
-#else
-       /* If we do not wait for autonegtation to complete I
-        * do not see a valid link status.
-        */
-       ret_val = e1000_wait_autoneg(hw);
-       if (ret_val < 0) {
-               DEBUGOUT("Error while waiting for autoneg to complete\n");
-               return ret_val;
-       }
-#endif
-
-       /* Check link status. Wait up to 100 microseconds for link to become
-        * valid.
-        */
-       for (i = 0; i < 10; i++) {
-               if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
-                       DEBUGOUT("PHY Read Error\n");
-                       return -E1000_ERR_PHY;
-               }
-               if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
-                       DEBUGOUT("PHY Read Error\n");
-                       return -E1000_ERR_PHY;
-               }
-               if (phy_data & MII_SR_LINK_STATUS) {
-                       /* We have link, so we need to finish the config process:
-                        *   1) Set up the MAC to the current PHY speed/duplex
-                        *      if we are on 82543.  If we
-                        *      are on newer silicon, we only need to configure
-                        *      collision distance in the Transmit Control Register.
-                        *   2) Set up flow control on the MAC to that established with
-                        *      the link partner.
-                        */
-                       if (hw->mac_type >= e1000_82544) {
-                               e1000_config_collision_dist(hw);
-                       } else {
-                               ret_val = e1000_config_mac_to_phy(hw);
-                               if (ret_val < 0) {
-                                       DEBUGOUT
-                                           ("Error configuring MAC to PHY settings\n");
-                                       return ret_val;
-                               }
-                       }
-                       ret_val = e1000_config_fc_after_link_up(hw);
-                       if (ret_val < 0) {
-                               DEBUGOUT("Error Configuring Flow Control\n");
-                               return ret_val;
-                       }
-                       DEBUGOUT("Valid link established!!!\n");
-                       return 0;
-               }
-               udelay(10);
-       }
-
-       DEBUGOUT("Unable to establish link!!!\n");
-       return -E1000_ERR_NOLINK;
-}
-
-/******************************************************************************
-* Configures PHY autoneg and flow control advertisement settings
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static int
-e1000_phy_setup_autoneg(struct e1000_hw *hw)
-{
-       uint16_t mii_autoneg_adv_reg;
-       uint16_t mii_1000t_ctrl_reg;
-
-       DEBUGFUNC();
-
-       /* Read the MII Auto-Neg Advertisement Register (Address 4). */
-       if (e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg) < 0) {
-               DEBUGOUT("PHY Read Error\n");
-               return -E1000_ERR_PHY;
-       }
-
-       /* Read the MII 1000Base-T Control Register (Address 9). */
-       if (e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg) < 0) {
-               DEBUGOUT("PHY Read Error\n");
-               return -E1000_ERR_PHY;
-       }
-
-       /* Need to parse both autoneg_advertised and fc and set up
-        * the appropriate PHY registers.  First we will parse for
-        * autoneg_advertised software override.  Since we can advertise
-        * a plethora of combinations, we need to check each bit
-        * individually.
-        */
-
-       /* First we clear all the 10/100 mb speed bits in the Auto-Neg
-        * Advertisement Register (Address 4) and the 1000 mb speed bits in
-        * the  1000Base-T Control Register (Address 9).
-        */
-       mii_autoneg_adv_reg &= ~REG4_SPEED_MASK;
-       mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
-
-       DEBUGOUT("autoneg_advertised %x\n", hw->autoneg_advertised);
-
-       /* Do we want to advertise 10 Mb Half Duplex? */
-       if (hw->autoneg_advertised & ADVERTISE_10_HALF) {
-               DEBUGOUT("Advertise 10mb Half duplex\n");
-               mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
-       }
-
-       /* Do we want to advertise 10 Mb Full Duplex? */
-       if (hw->autoneg_advertised & ADVERTISE_10_FULL) {
-               DEBUGOUT("Advertise 10mb Full duplex\n");
-               mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
-       }
-
-       /* Do we want to advertise 100 Mb Half Duplex? */
-       if (hw->autoneg_advertised & ADVERTISE_100_HALF) {
-               DEBUGOUT("Advertise 100mb Half duplex\n");
-               mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
-       }
-
-       /* Do we want to advertise 100 Mb Full Duplex? */
-       if (hw->autoneg_advertised & ADVERTISE_100_FULL) {
-               DEBUGOUT("Advertise 100mb Full duplex\n");
-               mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
-       }
-
-       /* We do not allow the Phy to advertise 1000 Mb Half Duplex */
-       if (hw->autoneg_advertised & ADVERTISE_1000_HALF) {
-               DEBUGOUT
-                   ("Advertise 1000mb Half duplex requested, request denied!\n");
-       }
-
-       /* Do we want to advertise 1000 Mb Full Duplex? */
-       if (hw->autoneg_advertised & ADVERTISE_1000_FULL) {
-               DEBUGOUT("Advertise 1000mb Full duplex\n");
-               mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
-       }
-
-       /* Check for a software override of the flow control settings, and
-        * setup the PHY advertisement registers accordingly.  If
-        * auto-negotiation is enabled, then software will have to set the
-        * "PAUSE" bits to the correct value in the Auto-Negotiation
-        * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-negotiation.
-        *
-        * The possible values of the "fc" parameter are:
-        *      0:  Flow control is completely disabled
-        *      1:  Rx flow control is enabled (we can receive pause frames
-        *          but not send pause frames).
-        *      2:  Tx flow control is enabled (we can send pause frames
-        *          but we do not support receiving pause frames).
-        *      3:  Both Rx and TX flow control (symmetric) are enabled.
-        *  other:  No software override.  The flow control configuration
-        *          in the EEPROM is used.
-        */
-       switch (hw->fc) {
-       case e1000_fc_none:     /* 0 */
-               /* Flow control (RX & TX) is completely disabled by a
-                * software over-ride.
-                */
-               mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
-               break;
-       case e1000_fc_rx_pause: /* 1 */
-               /* RX Flow control is enabled, and TX Flow control is
-                * disabled, by a software over-ride.
-                */
-               /* Since there really isn't a way to advertise that we are
-                * capable of RX Pause ONLY, we will advertise that we
-                * support both symmetric and asymmetric RX PAUSE.  Later
-                * (in e1000_config_fc_after_link_up) we will disable the
-                *hw's ability to send PAUSE frames.
-                */
-               mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
-               break;
-       case e1000_fc_tx_pause: /* 2 */
-               /* TX Flow control is enabled, and RX Flow control is
-                * disabled, by a software over-ride.
-                */
-               mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
-               mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
-               break;
-       case e1000_fc_full:     /* 3 */
-               /* Flow control (both RX and TX) is enabled by a software
-                * over-ride.
-                */
-               mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
-               break;
-       default:
-               DEBUGOUT("Flow control param set incorrectly\n");
-               return -E1000_ERR_CONFIG;
-       }
-
-       if (e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg) < 0) {
-               DEBUGOUT("PHY Write Error\n");
-               return -E1000_ERR_PHY;
-       }
-
-       DEBUGOUT("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
-
-       if (e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg) < 0) {
-               DEBUGOUT("PHY Write Error\n");
-               return -E1000_ERR_PHY;
-       }
-       return 0;
-}
-
-/******************************************************************************
-* Sets the collision distance in the Transmit Control register
-*
-* hw - Struct containing variables accessed by shared code
-*
-* Link should have been established previously. Reads the speed and duplex
-* information from the Device Status register.
-******************************************************************************/
-static void
-e1000_config_collision_dist(struct e1000_hw *hw)
-{
-       uint32_t tctl;
-
-       tctl = E1000_READ_REG(hw, TCTL);
-
-       tctl &= ~E1000_TCTL_COLD;
-       tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
-
-       E1000_WRITE_REG(hw, TCTL, tctl);
-       E1000_WRITE_FLUSH(hw);
-}
-
-/******************************************************************************
-* Sets MAC speed and duplex settings to reflect the those in the PHY
-*
-* hw - Struct containing variables accessed by shared code
-* mii_reg - data to write to the MII control register
-*
-* The contents of the PHY register containing the needed information need to
-* be passed in.
-******************************************************************************/
-static int
-e1000_config_mac_to_phy(struct e1000_hw *hw)
-{
-       uint32_t ctrl;
-       uint16_t phy_data;
-
-       DEBUGFUNC();
-
-       /* Read the Device Control Register and set the bits to Force Speed
-        * and Duplex.
-        */
-       ctrl = E1000_READ_REG(hw, CTRL);
-       ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
-       ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);
-
-       /* Set up duplex in the Device Control and Transmit Control
-        * registers depending on negotiated values.
-        */
-       if (e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) {
-               DEBUGOUT("PHY Read Error\n");
-               return -E1000_ERR_PHY;
-       }
-       if (phy_data & M88E1000_PSSR_DPLX)
-               ctrl |= E1000_CTRL_FD;
-       else
-               ctrl &= ~E1000_CTRL_FD;
-
-       e1000_config_collision_dist(hw);
-
-       /* Set up speed in the Device Control register depending on
-        * negotiated values.
-        */
-       if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
-               ctrl |= E1000_CTRL_SPD_1000;
-       else if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
-               ctrl |= E1000_CTRL_SPD_100;
-       /* Write the configured values back to the Device Control Reg. */
-       E1000_WRITE_REG(hw, CTRL, ctrl);
-       return 0;
-}
-
-/******************************************************************************
- * Forces the MAC's flow control settings.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Sets the TFCE and RFCE bits in the device control register to reflect
- * the adapter settings. TFCE and RFCE need to be explicitly set by
- * software when a Copper PHY is used because autonegotiation is managed
- * by the PHY rather than the MAC. Software must also configure these
- * bits when link is forced on a fiber connection.
- *****************************************************************************/
-static int
-e1000_force_mac_fc(struct e1000_hw *hw)
-{
-       uint32_t ctrl;
-
-       DEBUGFUNC();
-
-       /* Get the current configuration of the Device Control Register */
-       ctrl = E1000_READ_REG(hw, CTRL);
-
-       /* Because we didn't get link via the internal auto-negotiation
-        * mechanism (we either forced link or we got link via PHY
-        * auto-neg), we have to manually enable/disable transmit an
-        * receive flow control.
-        *
-        * The "Case" statement below enables/disable flow control
-        * according to the "hw->fc" parameter.
-        *
-        * The possible values of the "fc" parameter are:
-        *      0:  Flow control is completely disabled
-        *      1:  Rx flow control is enabled (we can receive pause
-        *          frames but not send pause frames).
-        *      2:  Tx flow control is enabled (we can send pause frames
-        *          frames but we do not receive pause frames).
-        *      3:  Both Rx and TX flow control (symmetric) is enabled.
-        *  other:  No other values should be possible at this point.
-        */
-
-       switch (hw->fc) {
-       case e1000_fc_none:
-               ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
-               break;
-       case e1000_fc_rx_pause:
-               ctrl &= (~E1000_CTRL_TFCE);
-               ctrl |= E1000_CTRL_RFCE;
-               break;
-       case e1000_fc_tx_pause:
-               ctrl &= (~E1000_CTRL_RFCE);
-               ctrl |= E1000_CTRL_TFCE;
-               break;
-       case e1000_fc_full:
-               ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
-               break;
-       default:
-               DEBUGOUT("Flow control param set incorrectly\n");
-               return -E1000_ERR_CONFIG;
-       }
-
-       /* Disable TX Flow Control for 82542 (rev 2.0) */
-       if (hw->mac_type == e1000_82542_rev2_0)
-               ctrl &= (~E1000_CTRL_TFCE);
-
-       E1000_WRITE_REG(hw, CTRL, ctrl);
-       return 0;
-}
-
-/******************************************************************************
- * Configures flow control settings after link is established
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Should be called immediately after a valid link has been established.
- * Forces MAC flow control settings if link was forced. When in MII/GMII mode
- * and autonegotiation is enabled, the MAC flow control settings will be set
- * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
- * and RFCE bits will be automaticaly set to the negotiated flow control mode.
- *****************************************************************************/
-static int
-e1000_config_fc_after_link_up(struct e1000_hw *hw)
-{
-       int32_t ret_val;
-       uint16_t mii_status_reg;
-       uint16_t mii_nway_adv_reg;
-       uint16_t mii_nway_lp_ability_reg;
-       uint16_t speed;
-       uint16_t duplex;
-
-       DEBUGFUNC();
-
-       /* Check for the case where we have fiber media and auto-neg failed
-        * so we had to force link.  In this case, we need to force the
-        * configuration of the MAC to match the "fc" parameter.
-        */
-       if ((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) {
-               ret_val = e1000_force_mac_fc(hw);
-               if (ret_val < 0) {
-                       DEBUGOUT("Error forcing flow control settings\n");
-                       return ret_val;
-               }
-       }
-
-       /* Check for the case where we have copper media and auto-neg is
-        * enabled.  In this case, we need to check and see if Auto-Neg
-        * has completed, and if so, how the PHY and link partner has
-        * flow control configured.
-        */
-       if (hw->media_type == e1000_media_type_copper) {
-               /* Read the MII Status Register and check to see if AutoNeg
-                * has completed.  We read this twice because this reg has
-                * some "sticky" (latched) bits.
-                */
-               if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
-                       DEBUGOUT("PHY Read Error \n");
-                       return -E1000_ERR_PHY;
-               }
-               if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
-                       DEBUGOUT("PHY Read Error \n");
-                       return -E1000_ERR_PHY;
-               }
-
-               if (mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
-                       /* The AutoNeg process has completed, so we now need to
-                        * read both the Auto Negotiation Advertisement Register
-                        * (Address 4) and the Auto_Negotiation Base Page Ability
-                        * Register (Address 5) to determine how flow control was
-                        * negotiated.
-                        */
-                       if (e1000_read_phy_reg
-                           (hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg) < 0) {
-                               DEBUGOUT("PHY Read Error\n");
-                               return -E1000_ERR_PHY;
-                       }
-                       if (e1000_read_phy_reg
-                           (hw, PHY_LP_ABILITY,
-                            &mii_nway_lp_ability_reg) < 0) {
-                               DEBUGOUT("PHY Read Error\n");
-                               return -E1000_ERR_PHY;
-                       }
-
-                       /* Two bits in the Auto Negotiation Advertisement Register
-                        * (Address 4) and two bits in the Auto Negotiation Base
-                        * Page Ability Register (Address 5) determine flow control
-                        * for both the PHY and the link partner.  The following
-                        * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
-                        * 1999, describes these PAUSE resolution bits and how flow
-                        * control is determined based upon these settings.
-                        * NOTE:  DC = Don't Care
-                        *
-                        *   LOCAL DEVICE  |   LINK PARTNER
-                        * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
-                        *-------|---------|-------|---------|--------------------
-                        *   0   |    0    |  DC   |   DC    | e1000_fc_none
-                        *   0   |    1    |   0   |   DC    | e1000_fc_none
-                        *   0   |    1    |   1   |    0    | e1000_fc_none
-                        *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
-                        *   1   |    0    |   0   |   DC    | e1000_fc_none
-                        *   1   |   DC    |   1   |   DC    | e1000_fc_full
-                        *   1   |    1    |   0   |    0    | e1000_fc_none
-                        *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
-                        *
-                        */
-                       /* Are both PAUSE bits set to 1?  If so, this implies
-                        * Symmetric Flow Control is enabled at both ends.  The
-                        * ASM_DIR bits are irrelevant per the spec.
-                        *
-                        * For Symmetric Flow Control:
-                        *
-                        *   LOCAL DEVICE  |   LINK PARTNER
-                        * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
-                        *-------|---------|-------|---------|--------------------
-                        *   1   |   DC    |   1   |   DC    | e1000_fc_full
-                        *
-                        */
-                       if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
-                           (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
-                               /* Now we need to check if the user selected RX ONLY
-                                * of pause frames.  In this case, we had to advertise
-                                * FULL flow control because we could not advertise RX
-                                * ONLY. Hence, we must now check to see if we need to
-                                * turn OFF  the TRANSMISSION of PAUSE frames.
-                                */
-                               if (hw->original_fc == e1000_fc_full) {
-                                       hw->fc = e1000_fc_full;
-                                       DEBUGOUT("Flow Control = FULL.\r\n");
-                               } else {
-                                       hw->fc = e1000_fc_rx_pause;
-                                       DEBUGOUT
-                                           ("Flow Control = RX PAUSE frames only.\r\n");
-                               }
-                       }
-                       /* For receiving PAUSE frames ONLY.
-                        *
-                        *   LOCAL DEVICE  |   LINK PARTNER
-                        * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
-                        *-------|---------|-------|---------|--------------------
-                        *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
-                        *
-                        */
-                       else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
-                                (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
-                                (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
-                                (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
-                       {
-                               hw->fc = e1000_fc_tx_pause;
-                               DEBUGOUT
-                                   ("Flow Control = TX PAUSE frames only.\r\n");
-                       }
-                       /* For transmitting PAUSE frames ONLY.
-                        *
-                        *   LOCAL DEVICE  |   LINK PARTNER
-                        * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
-                        *-------|---------|-------|---------|--------------------
-                        *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
-                        *
-                        */
-                       else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
-                                (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
-                                !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
-                                (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
-                       {
-                               hw->fc = e1000_fc_rx_pause;
-                               DEBUGOUT
-                                   ("Flow Control = RX PAUSE frames only.\r\n");
-                       }
-                       /* Per the IEEE spec, at this point flow control should be
-                        * disabled.  However, we want to consider that we could
-                        * be connected to a legacy switch that doesn't advertise
-                        * desired flow control, but can be forced on the link
-                        * partner.  So if we advertised no flow control, that is
-                        * what we will resolve to.  If we advertised some kind of
-                        * receive capability (Rx Pause Only or Full Flow Control)
-                        * and the link partner advertised none, we will configure
-                        * ourselves to enable Rx Flow Control only.  We can do
-                        * this safely for two reasons:  If the link partner really
-                        * didn't want flow control enabled, and we enable Rx, no
-                        * harm done since we won't be receiving any PAUSE frames
-                        * anyway.  If the intent on the link partner was to have
-                        * flow control enabled, then by us enabling RX only, we
-                        * can at least receive pause frames and process them.
-                        * This is a good idea because in most cases, since we are
-                        * predominantly a server NIC, more times than not we will
-                        * be asked to delay transmission of packets than asking
-                        * our link partner to pause transmission of frames.
-                        */
-                       else if (hw->original_fc == e1000_fc_none ||
-                                hw->original_fc == e1000_fc_tx_pause) {
-                               hw->fc = e1000_fc_none;
-                               DEBUGOUT("Flow Control = NONE.\r\n");
-                       } else {
-                               hw->fc = e1000_fc_rx_pause;
-                               DEBUGOUT
-                                   ("Flow Control = RX PAUSE frames only.\r\n");
-                       }
-
-                       /* Now we need to do one last check...  If we auto-
-                        * negotiated to HALF DUPLEX, flow control should not be
-                        * enabled per IEEE 802.3 spec.
-                        */
-                       e1000_get_speed_and_duplex(hw, &speed, &duplex);
-
-                       if (duplex == HALF_DUPLEX)
-                               hw->fc = e1000_fc_none;
-
-                       /* Now we call a subroutine to actually force the MAC
-                        * controller to use the correct flow control settings.
-                        */
-                       ret_val = e1000_force_mac_fc(hw);
-                       if (ret_val < 0) {
-                               DEBUGOUT
-                                   ("Error forcing flow control settings\n");
-                               return ret_val;
-                       }
-               } else {
-                       DEBUGOUT
-                           ("Copper PHY and Auto Neg has not completed.\r\n");
-               }
-       }
-       return 0;
-}
-
-/******************************************************************************
- * Checks to see if the link status of the hardware has changed.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Called by any function that needs to check the link status of the adapter.
- *****************************************************************************/
-static int
-e1000_check_for_link(struct eth_device *nic)
-{
-       struct e1000_hw *hw = nic->priv;
-       uint32_t rxcw;
-       uint32_t ctrl;
-       uint32_t status;
-       uint32_t rctl;
-       uint32_t signal;
-       int32_t ret_val;
-       uint16_t phy_data;
-       uint16_t lp_capability;
-
-       DEBUGFUNC();
-
-       /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be
-        * set when the optics detect a signal. On older adapters, it will be
-        * cleared when there is a signal
-        */
-       ctrl = E1000_READ_REG(hw, CTRL);
-       if ((hw->mac_type > e1000_82544) && !(ctrl & E1000_CTRL_ILOS))
-               signal = E1000_CTRL_SWDPIN1;
-       else
-               signal = 0;
-
-       status = E1000_READ_REG(hw, STATUS);
-       rxcw = E1000_READ_REG(hw, RXCW);
-       DEBUGOUT("ctrl: %#08x status %#08x rxcw %#08x\n", ctrl, status, rxcw);
-
-       /* If we have a copper PHY then we only want to go out to the PHY
-        * registers to see if Auto-Neg has completed and/or if our link
-        * status has changed.  The get_link_status flag will be set if we
-        * receive a Link Status Change interrupt or we have Rx Sequence
-        * Errors.
-        */
-       if ((hw->media_type == e1000_media_type_copper) && hw->get_link_status) {
-               /* First we want to see if the MII Status Register reports
-                * link.  If so, then we want to get the current speed/duplex
-                * of the PHY.
-                * Read the register twice since the link bit is sticky.
-                */
-               if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
-                       DEBUGOUT("PHY Read Error\n");
-                       return -E1000_ERR_PHY;
-               }
-               if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
-                       DEBUGOUT("PHY Read Error\n");
-                       return -E1000_ERR_PHY;
-               }
-
-               if (phy_data & MII_SR_LINK_STATUS) {
-                       hw->get_link_status = FALSE;
-               } else {
-                       /* No link detected */
-                       return -E1000_ERR_NOLINK;
-               }
-
-               /* We have a M88E1000 PHY and Auto-Neg is enabled.  If we
-                * have Si on board that is 82544 or newer, Auto
-                * Speed Detection takes care of MAC speed/duplex
-                * configuration.  So we only need to configure Collision
-                * Distance in the MAC.  Otherwise, we need to force
-                * speed/duplex on the MAC to the current PHY speed/duplex
-                * settings.
-                */
-               if (hw->mac_type >= e1000_82544)
-                       e1000_config_collision_dist(hw);
-               else {
-                       ret_val = e1000_config_mac_to_phy(hw);
-                       if (ret_val < 0) {
-                               DEBUGOUT
-                                   ("Error configuring MAC to PHY settings\n");
-                               return ret_val;
-                       }
-               }
-
-               /* Configure Flow Control now that Auto-Neg has completed. First, we
-                * need to restore the desired flow control settings because we may
-                * have had to re-autoneg with a different link partner.
-                */
-               ret_val = e1000_config_fc_after_link_up(hw);
-               if (ret_val < 0) {
-                       DEBUGOUT("Error configuring flow control\n");
-                       return ret_val;
-               }
-
-               /* At this point we know that we are on copper and we have
-                * auto-negotiated link.  These are conditions for checking the link
-                * parter capability register.  We use the link partner capability to
-                * determine if TBI Compatibility needs to be turned on or off.  If
-                * the link partner advertises any speed in addition to Gigabit, then
-                * we assume that they are GMII-based, and TBI compatibility is not
-                * needed. If no other speeds are advertised, we assume the link
-                * partner is TBI-based, and we turn on TBI Compatibility.
-                */
-               if (hw->tbi_compatibility_en) {
-                       if (e1000_read_phy_reg
-                           (hw, PHY_LP_ABILITY, &lp_capability) < 0) {
-                               DEBUGOUT("PHY Read Error\n");
-                               return -E1000_ERR_PHY;
-                       }
-                       if (lp_capability & (NWAY_LPAR_10T_HD_CAPS |
-                                            NWAY_LPAR_10T_FD_CAPS |
-                                            NWAY_LPAR_100TX_HD_CAPS |
-                                            NWAY_LPAR_100TX_FD_CAPS |
-                                            NWAY_LPAR_100T4_CAPS)) {
-                               /* If our link partner advertises anything in addition to
-                                * gigabit, we do not need to enable TBI compatibility.
-                                */
-                               if (hw->tbi_compatibility_on) {
-                                       /* If we previously were in the mode, turn it off. */
-                                       rctl = E1000_READ_REG(hw, RCTL);
-                                       rctl &= ~E1000_RCTL_SBP;
-                                       E1000_WRITE_REG(hw, RCTL, rctl);
-                                       hw->tbi_compatibility_on = FALSE;
-                               }
-                       } else {
-                               /* If TBI compatibility is was previously off, turn it on. For
-                                * compatibility with a TBI link partner, we will store bad
-                                * packets. Some frames have an additional byte on the end and
-                                * will look like CRC errors to to the hardware.
-                                */
-                               if (!hw->tbi_compatibility_on) {
-                                       hw->tbi_compatibility_on = TRUE;
-                                       rctl = E1000_READ_REG(hw, RCTL);
-                                       rctl |= E1000_RCTL_SBP;
-                                       E1000_WRITE_REG(hw, RCTL, rctl);
-                               }
-                       }
-               }
-       }
-       /* If we don't have link (auto-negotiation failed or link partner cannot
-        * auto-negotiate), the cable is plugged in (we have signal), and our
-        * link partner is not trying to auto-negotiate with us (we are receiving
-        * idles or data), we need to force link up. We also need to give
-        * auto-negotiation time to complete, in case the cable was just plugged
-        * in. The autoneg_failed flag does this.
-        */
-       else if ((hw->media_type == e1000_media_type_fiber) &&
-                (!(status & E1000_STATUS_LU)) &&
-                ((ctrl & E1000_CTRL_SWDPIN1) == signal) &&
-                (!(rxcw & E1000_RXCW_C))) {
-               if (hw->autoneg_failed == 0) {
-                       hw->autoneg_failed = 1;
-                       return 0;
-               }
-               DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\r\n");
-
-               /* Disable auto-negotiation in the TXCW register */
-               E1000_WRITE_REG(hw, TXCW, (hw->txcw & ~E1000_TXCW_ANE));
-
-               /* Force link-up and also force full-duplex. */
-               ctrl = E1000_READ_REG(hw, CTRL);
-               ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
-               E1000_WRITE_REG(hw, CTRL, ctrl);
-
-               /* Configure Flow Control after forcing link up. */
-               ret_val = e1000_config_fc_after_link_up(hw);
-               if (ret_val < 0) {
-                       DEBUGOUT("Error configuring flow control\n");
-                       return ret_val;
-               }
-       }
-       /* If we are forcing link and we are receiving /C/ ordered sets, re-enable
-        * auto-negotiation in the TXCW register and disable forced link in the
-        * Device Control register in an attempt to auto-negotiate with our link
-        * partner.
-        */
-       else if ((hw->media_type == e1000_media_type_fiber) &&
-                (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
-               DEBUGOUT
-                   ("RXing /C/, enable AutoNeg and stop forcing link.\r\n");
-               E1000_WRITE_REG(hw, TXCW, hw->txcw);
-               E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU));
-       }
-       return 0;
-}
-
-/******************************************************************************
- * Detects the current speed and duplex settings of the hardware.
- *
- * hw - Struct containing variables accessed by shared code
- * speed - Speed of the connection
- * duplex - Duplex setting of the connection
- *****************************************************************************/
-static void
-e1000_get_speed_and_duplex(struct e1000_hw *hw,
-                          uint16_t * speed, uint16_t * duplex)
-{
-       uint32_t status;
-
-       DEBUGFUNC();
-
-       if (hw->mac_type >= e1000_82543) {
-               status = E1000_READ_REG(hw, STATUS);
-               if (status & E1000_STATUS_SPEED_1000) {
-                       *speed = SPEED_1000;
-                       DEBUGOUT("1000 Mbs, ");
-               } else if (status & E1000_STATUS_SPEED_100) {
-                       *speed = SPEED_100;
-                       DEBUGOUT("100 Mbs, ");
-               } else {
-                       *speed = SPEED_10;
-                       DEBUGOUT("10 Mbs, ");
-               }
-
-               if (status & E1000_STATUS_FD) {
-                       *duplex = FULL_DUPLEX;
-                       DEBUGOUT("Full Duplex\r\n");
-               } else {
-                       *duplex = HALF_DUPLEX;
-                       DEBUGOUT(" Half Duplex\r\n");
-               }
-       } else {
-               DEBUGOUT("1000 Mbs, Full Duplex\r\n");
-               *speed = SPEED_1000;
-               *duplex = FULL_DUPLEX;
-       }
-}
-
-/******************************************************************************
-* Blocks until autoneg completes or times out (~4.5 seconds)
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static int
-e1000_wait_autoneg(struct e1000_hw *hw)
-{
-       uint16_t i;
-       uint16_t phy_data;
-
-       DEBUGFUNC();
-       DEBUGOUT("Waiting for Auto-Neg to complete.\n");
-
-       /* We will wait for autoneg to complete or 4.5 seconds to expire. */
-       for (i = PHY_AUTO_NEG_TIME; i > 0; i--) {
-               /* Read the MII Status Register and wait for Auto-Neg
-                * Complete bit to be set.
-                */
-               if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
-                       DEBUGOUT("PHY Read Error\n");
-                       return -E1000_ERR_PHY;
-               }
-               if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
-                       DEBUGOUT("PHY Read Error\n");
-                       return -E1000_ERR_PHY;
-               }
-               if (phy_data & MII_SR_AUTONEG_COMPLETE) {
-                       DEBUGOUT("Auto-Neg complete.\n");
-                       return 0;
-               }
-               mdelay(100);
-       }
-       DEBUGOUT("Auto-Neg timedout.\n");
-       return -E1000_ERR_TIMEOUT;
-}
-
-/******************************************************************************
-* Raises the Management Data Clock
-*
-* hw - Struct containing variables accessed by shared code
-* ctrl - Device control register's current value
-******************************************************************************/
-static void
-e1000_raise_mdi_clk(struct e1000_hw *hw, uint32_t * ctrl)
-{
-       /* Raise the clock input to the Management Data Clock (by setting the MDC
-        * bit), and then delay 2 microseconds.
-        */
-       E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
-       E1000_WRITE_FLUSH(hw);
-       udelay(2);
-}
-
-/******************************************************************************
-* Lowers the Management Data Clock
-*
-* hw - Struct containing variables accessed by shared code
-* ctrl - Device control register's current value
-******************************************************************************/
-static void
-e1000_lower_mdi_clk(struct e1000_hw *hw, uint32_t * ctrl)
-{
-       /* Lower the clock input to the Management Data Clock (by clearing the MDC
-        * bit), and then delay 2 microseconds.
-        */
-       E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
-       E1000_WRITE_FLUSH(hw);
-       udelay(2);
-}
-
-/******************************************************************************
-* Shifts data bits out to the PHY
-*
-* hw - Struct containing variables accessed by shared code
-* data - Data to send out to the PHY
-* count - Number of bits to shift out
-*
-* Bits are shifted out in MSB to LSB order.
-******************************************************************************/
-static void
-e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data, uint16_t count)
-{
-       uint32_t ctrl;
-       uint32_t mask;
-
-       /* We need to shift "count" number of bits out to the PHY. So, the value
-        * in the "data" parameter will be shifted out to the PHY one bit at a
-        * time. In order to do this, "data" must be broken down into bits.
-        */
-       mask = 0x01;
-       mask <<= (count - 1);
-
-       ctrl = E1000_READ_REG(hw, CTRL);
-
-       /* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
-       ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
-
-       while (mask) {
-               /* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and
-                * then raising and lowering the Management Data Clock. A "0" is
-                * shifted out to the PHY by setting the MDIO bit to "0" and then
-                * raising and lowering the clock.
-                */
-               if (data & mask)
-                       ctrl |= E1000_CTRL_MDIO;
-               else
-                       ctrl &= ~E1000_CTRL_MDIO;
-
-               E1000_WRITE_REG(hw, CTRL, ctrl);
-               E1000_WRITE_FLUSH(hw);
-
-               udelay(2);
-
-               e1000_raise_mdi_clk(hw, &ctrl);
-               e1000_lower_mdi_clk(hw, &ctrl);
-
-               mask = mask >> 1;
-       }
-}
-
-/******************************************************************************
-* Shifts data bits in from the PHY
-*
-* hw - Struct containing variables accessed by shared code
-*
-* Bits are shifted in in MSB to LSB order.
-******************************************************************************/
-static uint16_t
-e1000_shift_in_mdi_bits(struct e1000_hw *hw)
-{
-       uint32_t ctrl;
-       uint16_t data = 0;
-       uint8_t i;
-
-       /* In order to read a register from the PHY, we need to shift in a total
-        * of 18 bits from the PHY. The first two bit (turnaround) times are used
-        * to avoid contention on the MDIO pin when a read operation is performed.
-        * These two bits are ignored by us and thrown away. Bits are "shifted in"
-        * by raising the input to the Management Data Clock (setting the MDC bit),
-        * and then reading the value of the MDIO bit.
-        */
-       ctrl = E1000_READ_REG(hw, CTRL);
-
-       /* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */
-       ctrl &= ~E1000_CTRL_MDIO_DIR;
-       ctrl &= ~E1000_CTRL_MDIO;
-
-       E1000_WRITE_REG(hw, CTRL, ctrl);
-       E1000_WRITE_FLUSH(hw);
-
-       /* Raise and Lower the clock before reading in the data. This accounts for
-        * the turnaround bits. The first clock occurred when we clocked out the
-        * last bit of the Register Address.
-        */
-       e1000_raise_mdi_clk(hw, &ctrl);
-       e1000_lower_mdi_clk(hw, &ctrl);
-
-       for (data = 0, i = 0; i < 16; i++) {
-               data = data << 1;
-               e1000_raise_mdi_clk(hw, &ctrl);
-               ctrl = E1000_READ_REG(hw, CTRL);
-               /* Check to see if we shifted in a "1". */
-               if (ctrl & E1000_CTRL_MDIO)
-                       data |= 1;
-               e1000_lower_mdi_clk(hw, &ctrl);
-       }
-
-       e1000_raise_mdi_clk(hw, &ctrl);
-       e1000_lower_mdi_clk(hw, &ctrl);
-
-       return data;
-}
-
-/*****************************************************************************
-* Reads the value from a PHY register
-*
-* hw - Struct containing variables accessed by shared code
-* reg_addr - address of the PHY register to read
-******************************************************************************/
-static int
-e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t * phy_data)
-{
-       uint32_t i;
-       uint32_t mdic = 0;
-       const uint32_t phy_addr = 1;
-
-       if (reg_addr > MAX_PHY_REG_ADDRESS) {
-               DEBUGOUT("PHY Address %d is out of range\n", reg_addr);
-               return -E1000_ERR_PARAM;
-       }
-
-       if (hw->mac_type > e1000_82543) {
-               /* Set up Op-code, Phy Address, and register address in the MDI
-                * Control register.  The MAC will take care of interfacing with the
-                * PHY to retrieve the desired data.
-                */
-               mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
-                       (phy_addr << E1000_MDIC_PHY_SHIFT) |
-                       (E1000_MDIC_OP_READ));
-
-               E1000_WRITE_REG(hw, MDIC, mdic);
-
-               /* Poll the ready bit to see if the MDI read completed */
-               for (i = 0; i < 64; i++) {
-                       udelay(10);
-                       mdic = E1000_READ_REG(hw, MDIC);
-                       if (mdic & E1000_MDIC_READY)
-                               break;
-               }
-               if (!(mdic & E1000_MDIC_READY)) {
-                       DEBUGOUT("MDI Read did not complete\n");
-                       return -E1000_ERR_PHY;
-               }
-               if (mdic & E1000_MDIC_ERROR) {
-                       DEBUGOUT("MDI Error\n");
-                       return -E1000_ERR_PHY;
-               }
-               *phy_data = (uint16_t) mdic;
-       } else {
-               /* We must first send a preamble through the MDIO pin to signal the
-                * beginning of an MII instruction.  This is done by sending 32
-                * consecutive "1" bits.
-                */
-               e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
-
-               /* Now combine the next few fields that are required for a read
-                * operation.  We use this method instead of calling the
-                * e1000_shift_out_mdi_bits routine five different times. The format of
-                * a MII read instruction consists of a shift out of 14 bits and is
-                * defined as follows:
-                *    <Preamble><SOF><Op Code><Phy Addr><Reg Addr>
-                * followed by a shift in of 18 bits.  This first two bits shifted in
-                * are TurnAround bits used to avoid contention on the MDIO pin when a
-                * READ operation is performed.  These two bits are thrown away
-                * followed by a shift in of 16 bits which contains the desired data.
-                */
-               mdic = ((reg_addr) | (phy_addr << 5) |
-                       (PHY_OP_READ << 10) | (PHY_SOF << 12));
-
-               e1000_shift_out_mdi_bits(hw, mdic, 14);
-
-               /* Now that we've shifted out the read command to the MII, we need to
-                * "shift in" the 16-bit value (18 total bits) of the requested PHY
-                * register address.
-                */
-               *phy_data = e1000_shift_in_mdi_bits(hw);
-       }
-       return 0;
-}
-
-/******************************************************************************
-* Writes a value to a PHY register
-*
-* hw - Struct containing variables accessed by shared code
-* reg_addr - address of the PHY register to write
-* data - data to write to the PHY
-******************************************************************************/
-static int
-e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t phy_data)
-{
-       uint32_t i;
-       uint32_t mdic = 0;
-       const uint32_t phy_addr = 1;
-
-       if (reg_addr > MAX_PHY_REG_ADDRESS) {
-               DEBUGOUT("PHY Address %d is out of range\n", reg_addr);
-               return -E1000_ERR_PARAM;
-       }
-
-       if (hw->mac_type > e1000_82543) {
-               /* Set up Op-code, Phy Address, register address, and data intended
-                * for the PHY register in the MDI Control register.  The MAC will take
-                * care of interfacing with the PHY to send the desired data.
-                */
-               mdic = (((uint32_t) phy_data) |
-                       (reg_addr << E1000_MDIC_REG_SHIFT) |
-                       (phy_addr << E1000_MDIC_PHY_SHIFT) |
-                       (E1000_MDIC_OP_WRITE));
-
-               E1000_WRITE_REG(hw, MDIC, mdic);
-
-               /* Poll the ready bit to see if the MDI read completed */
-               for (i = 0; i < 64; i++) {
-                       udelay(10);
-                       mdic = E1000_READ_REG(hw, MDIC);
-                       if (mdic & E1000_MDIC_READY)
-                               break;
-               }
-               if (!(mdic & E1000_MDIC_READY)) {
-                       DEBUGOUT("MDI Write did not complete\n");
-                       return -E1000_ERR_PHY;
-               }
-       } else {
-               /* We'll need to use the SW defined pins to shift the write command
-                * out to the PHY. We first send a preamble to the PHY to signal the
-                * beginning of the MII instruction.  This is done by sending 32
-                * consecutive "1" bits.
-                */
-               e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
-
-               /* Now combine the remaining required fields that will indicate a
-                * write operation. We use this method instead of calling the
-                * e1000_shift_out_mdi_bits routine for each field in the command. The
-                * format of a MII write instruction is as follows:
-                * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.
-                */
-               mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) |
-                       (PHY_OP_WRITE << 12) | (PHY_SOF << 14));
-               mdic <<= 16;
-               mdic |= (uint32_t) phy_data;
-
-               e1000_shift_out_mdi_bits(hw, mdic, 32);
-       }
-       return 0;
-}
-
-/******************************************************************************
-* Returns the PHY to the power-on reset state
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static void
-e1000_phy_hw_reset(struct e1000_hw *hw)
-{
-       uint32_t ctrl;
-       uint32_t ctrl_ext;
-
-       DEBUGFUNC();
-
-       DEBUGOUT("Resetting Phy...\n");
-
-       if (hw->mac_type > e1000_82543) {
-               /* Read the device control register and assert the E1000_CTRL_PHY_RST
-                * bit. Then, take it out of reset.
-                */
-               ctrl = E1000_READ_REG(hw, CTRL);
-               E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
-               E1000_WRITE_FLUSH(hw);
-               mdelay(10);
-               E1000_WRITE_REG(hw, CTRL, ctrl);
-               E1000_WRITE_FLUSH(hw);
-       } else {
-               /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
-                * bit to put the PHY into reset. Then, take it out of reset.
-                */
-               ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
-               ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
-               ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
-               E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-               E1000_WRITE_FLUSH(hw);
-               mdelay(10);
-               ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
-               E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-               E1000_WRITE_FLUSH(hw);
-       }
-       udelay(150);
-}
-
-/******************************************************************************
-* Resets the PHY
-*
-* hw - Struct containing variables accessed by shared code
-*
-* Sets bit 15 of the MII Control regiser
-******************************************************************************/
-static int
-e1000_phy_reset(struct e1000_hw *hw)
-{
-       uint16_t phy_data;
-
-       DEBUGFUNC();
-
-       if (e1000_read_phy_reg(hw, PHY_CTRL, &phy_data) < 0) {
-               DEBUGOUT("PHY Read Error\n");
-               return -E1000_ERR_PHY;
-       }
-       phy_data |= MII_CR_RESET;
-       if (e1000_write_phy_reg(hw, PHY_CTRL, phy_data) < 0) {
-               DEBUGOUT("PHY Write Error\n");
-               return -E1000_ERR_PHY;
-       }
-       udelay(1);
-       return 0;
-}
-
-/******************************************************************************
-* Probes the expected PHY address for known PHY IDs
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static int
-e1000_detect_gig_phy(struct e1000_hw *hw)
-{
-       uint16_t phy_id_high, phy_id_low;
-       int match = FALSE;
-
-       DEBUGFUNC();
-
-       /* Read the PHY ID Registers to identify which PHY is onboard. */
-       if (e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high) < 0) {
-               DEBUGOUT("PHY Read Error\n");
-               return -E1000_ERR_PHY;
-       }
-       hw->phy_id = (uint32_t) (phy_id_high << 16);
-       udelay(2);
-       if (e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low) < 0) {
-               DEBUGOUT("PHY Read Error\n");
-               return -E1000_ERR_PHY;
-       }
-       hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK);
-
-       switch (hw->mac_type) {
-       case e1000_82543:
-               if (hw->phy_id == M88E1000_E_PHY_ID)
-                       match = TRUE;
-               break;
-       case e1000_82544:
-               if (hw->phy_id == M88E1000_I_PHY_ID)
-                       match = TRUE;
-               break;
-       case e1000_82540:
-       case e1000_82545:
-       case e1000_82546:
-               if (hw->phy_id == M88E1011_I_PHY_ID)
-                       match = TRUE;
-               break;
-       default:
-               DEBUGOUT("Invalid MAC type %d\n", hw->mac_type);
-               return -E1000_ERR_CONFIG;
-       }
-       if (match) {
-               DEBUGOUT("PHY ID 0x%X detected\n", hw->phy_id);
-               return 0;
-       }
-       DEBUGOUT("Invalid PHY ID 0x%X\n", hw->phy_id);
-       return -E1000_ERR_PHY;
-}
-
-/**
- * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
- *
- * e1000_sw_init initializes the Adapter private data structure.
- * Fields are initialized based on PCI device information and
- * OS network device settings (MTU size).
- **/
-
-static int
-e1000_sw_init(struct eth_device *nic, int cardnum)
-{
-       struct e1000_hw *hw = (typeof(hw)) nic->priv;
-       int result;
-
-       /* PCI config space info */
-       pci_read_config_word(hw->pdev, PCI_VENDOR_ID, &hw->vendor_id);
-       pci_read_config_word(hw->pdev, PCI_DEVICE_ID, &hw->device_id);
-       pci_read_config_word(hw->pdev, PCI_SUBSYSTEM_VENDOR_ID,
-                            &hw->subsystem_vendor_id);
-       pci_read_config_word(hw->pdev, PCI_SUBSYSTEM_ID, &hw->subsystem_id);
-
-       pci_read_config_byte(hw->pdev, PCI_REVISION_ID, &hw->revision_id);
-       pci_read_config_word(hw->pdev, PCI_COMMAND, &hw->pci_cmd_word);
-
-       /* identify the MAC */
-       result = e1000_set_mac_type(hw);
-       if (result) {
-               E1000_ERR("Unknown MAC Type\n");
-               return result;
-       }
-
-       /* lan a vs. lan b settings */
-       if (hw->mac_type == e1000_82546)
-               /*this also works w/ multiple 82546 cards */
-               /*but not if they're intermingled /w other e1000s */
-               hw->lan_loc = (cardnum % 2) ? e1000_lan_b : e1000_lan_a;
-       else
-               hw->lan_loc = e1000_lan_a;
-
-       /* flow control settings */
-       hw->fc_high_water = E1000_FC_HIGH_THRESH;
-       hw->fc_low_water = E1000_FC_LOW_THRESH;
-       hw->fc_pause_time = E1000_FC_PAUSE_TIME;
-       hw->fc_send_xon = 1;
-
-       /* Media type - copper or fiber */
-
-       if (hw->mac_type >= e1000_82543) {
-               uint32_t status = E1000_READ_REG(hw, STATUS);
-
-               if (status & E1000_STATUS_TBIMODE) {
-                       DEBUGOUT("fiber interface\n");
-                       hw->media_type = e1000_media_type_fiber;
-               } else {
-                       DEBUGOUT("copper interface\n");
-                       hw->media_type = e1000_media_type_copper;
-               }
-       } else {
-               hw->media_type = e1000_media_type_fiber;
-       }
-
-       if (hw->mac_type < e1000_82543)
-               hw->report_tx_early = 0;
-       else
-               hw->report_tx_early = 1;
-
-       hw->tbi_compatibility_en = TRUE;
-#if 0
-       hw->wait_autoneg_complete = FALSE;
-       hw->adaptive_ifs = TRUE;
-
-       /* Copper options */
-       if (hw->media_type == e1000_media_type_copper) {
-               hw->mdix = AUTO_ALL_MODES;
-               hw->disable_polarity_correction = FALSE;
-       }
-#endif
-       return E1000_SUCCESS;
-}
-
-void
-fill_rx(struct e1000_hw *hw)
-{
-       struct e1000_rx_desc *rd;
-
-       rx_last = rx_tail;
-       rd = rx_base + rx_tail;
-       rx_tail = (rx_tail + 1) % 8;
-       memset(rd, 0, 16);
-       rd->buffer_addr = cpu_to_le64((u32) & packet);
-       E1000_WRITE_REG(hw, RDT, rx_tail);
-}
-
-/**
- * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
- * @adapter: board private structure
- *
- * Configure the Tx unit of the MAC after a reset.
- **/
-
-static void
-e1000_configure_tx(struct e1000_hw *hw)
-{
-       unsigned long ptr;
-       unsigned long tctl;
-       unsigned long tipg;
-
-       ptr = (u32) tx_pool;
-       if (ptr & 0xf)
-               ptr = (ptr + 0x10) & (~0xf);
-
-       tx_base = (typeof(tx_base)) ptr;
-
-       E1000_WRITE_REG(hw, TDBAL, (u32) tx_base);
-       E1000_WRITE_REG(hw, TDBAH, 0);
-
-       E1000_WRITE_REG(hw, TDLEN, 128);
-
-       /* Setup the HW Tx Head and Tail descriptor pointers */
-       E1000_WRITE_REG(hw, TDH, 0);
-       E1000_WRITE_REG(hw, TDT, 0);
-       tx_tail = 0;
-
-       /* Set the default values for the Tx Inter Packet Gap timer */
-       switch (hw->mac_type) {
-       case e1000_82542_rev2_0:
-       case e1000_82542_rev2_1:
-               tipg = DEFAULT_82542_TIPG_IPGT;
-               tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
-               tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
-               break;
-       default:
-               if (hw->media_type == e1000_media_type_fiber)
-                       tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
-               else
-                       tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
-               tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
-               tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
-       }
-       E1000_WRITE_REG(hw, TIPG, tipg);
-#if 0
-       /* Set the Tx Interrupt Delay register */
-       E1000_WRITE_REG(hw, TIDV, adapter->tx_int_delay);
-       if (hw->mac_type >= e1000_82540)
-               E1000_WRITE_REG(hw, TADV, adapter->tx_abs_int_delay);
-#endif
-       /* Program the Transmit Control Register */
-       tctl = E1000_READ_REG(hw, TCTL);
-       tctl &= ~E1000_TCTL_CT;
-       tctl |= E1000_TCTL_EN | E1000_TCTL_PSP |
-           (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
-       E1000_WRITE_REG(hw, TCTL, tctl);
-
-       e1000_config_collision_dist(hw);
-#if 0
-       /* Setup Transmit Descriptor Settings for this adapter */
-       adapter->txd_cmd = E1000_TXD_CMD_IFCS | E1000_TXD_CMD_IDE;
-
-       if (adapter->hw.report_tx_early == 1)
-               adapter->txd_cmd |= E1000_TXD_CMD_RS;
-       else
-               adapter->txd_cmd |= E1000_TXD_CMD_RPS;
-#endif
-}
-
-/**
- * e1000_setup_rctl - configure the receive control register
- * @adapter: Board private structure
- **/
-static void
-e1000_setup_rctl(struct e1000_hw *hw)
-{
-       uint32_t rctl;
-
-       rctl = E1000_READ_REG(hw, RCTL);
-
-       rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
-
-       rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF;     /* |
-                                                                                                  (hw.mc_filter_type << E1000_RCTL_MO_SHIFT); */
-
-       if (hw->tbi_compatibility_on == 1)
-               rctl |= E1000_RCTL_SBP;
-       else
-               rctl &= ~E1000_RCTL_SBP;
-
-       rctl &= ~(E1000_RCTL_SZ_4096);
-#if 0
-       switch (adapter->rx_buffer_len) {
-       case E1000_RXBUFFER_2048:
-       default:
-#endif
-               rctl |= E1000_RCTL_SZ_2048;
-               rctl &= ~(E1000_RCTL_BSEX | E1000_RCTL_LPE);
-#if 0
-               break;
-       case E1000_RXBUFFER_4096:
-               rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
-               break;
-       case E1000_RXBUFFER_8192:
-               rctl |= E1000_RCTL_SZ_8192 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
-               break;
-       case E1000_RXBUFFER_16384:
-               rctl |= E1000_RCTL_SZ_16384 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
-               break;
-       }
-#endif
-       E1000_WRITE_REG(hw, RCTL, rctl);
-}
-
-/**
- * e1000_configure_rx - Configure 8254x Receive Unit after Reset
- * @adapter: board private structure
- *
- * Configure the Rx unit of the MAC after a reset.
- **/
-static void
-e1000_configure_rx(struct e1000_hw *hw)
-{
-       unsigned long ptr;
-       unsigned long rctl;
-#if 0
-       unsigned long rxcsum;
-#endif
-       rx_tail = 0;
-       /* make sure receives are disabled while setting up the descriptors */
-       rctl = E1000_READ_REG(hw, RCTL);
-       E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
-#if 0
-       /* set the Receive Delay Timer Register */
-
-       E1000_WRITE_REG(hw, RDTR, adapter->rx_int_delay);
-#endif
-       if (hw->mac_type >= e1000_82540) {
-#if 0
-               E1000_WRITE_REG(hw, RADV, adapter->rx_abs_int_delay);
-#endif
-               /* Set the interrupt throttling rate.  Value is calculated
-                * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns) */
-#define MAX_INTS_PER_SEC        8000
-#define DEFAULT_ITR             1000000000/(MAX_INTS_PER_SEC * 256)
-               E1000_WRITE_REG(hw, ITR, DEFAULT_ITR);
-       }
-
-       /* Setup the Base and Length of the Rx Descriptor Ring */
-       ptr = (u32) rx_pool;
-       if (ptr & 0xf)
-               ptr = (ptr + 0x10) & (~0xf);
-       rx_base = (typeof(rx_base)) ptr;
-       E1000_WRITE_REG(hw, RDBAL, (u32) rx_base);
-       E1000_WRITE_REG(hw, RDBAH, 0);
-
-       E1000_WRITE_REG(hw, RDLEN, 128);
-
-       /* Setup the HW Rx Head and Tail Descriptor Pointers */
-       E1000_WRITE_REG(hw, RDH, 0);
-       E1000_WRITE_REG(hw, RDT, 0);
-#if 0
-       /* Enable 82543 Receive Checksum Offload for TCP and UDP */
-       if ((adapter->hw.mac_type >= e1000_82543) && (adapter->rx_csum == TRUE)) {
-               rxcsum = E1000_READ_REG(hw, RXCSUM);
-               rxcsum |= E1000_RXCSUM_TUOFL;
-               E1000_WRITE_REG(hw, RXCSUM, rxcsum);
-       }
-#endif
-       /* Enable Receives */
-
-       E1000_WRITE_REG(hw, RCTL, rctl);
-       fill_rx(hw);
-}
-
-/**************************************************************************
-POLL - Wait for a frame
-***************************************************************************/
-static int
-e1000_poll(struct eth_device *nic)
-{
-       struct e1000_hw *hw = nic->priv;
-       struct e1000_rx_desc *rd;
-       /* return true if there's an ethernet packet ready to read */
-       rd = rx_base + rx_last;
-       if (!(le32_to_cpu(rd->status)) & E1000_RXD_STAT_DD)
-               return 0;
-       /*DEBUGOUT("recv: packet len=%d \n", rd->length); */
-       NetReceive((uchar *)packet, le32_to_cpu(rd->length));
-       fill_rx(hw);
-       return 1;
-}
-
-/**************************************************************************
-TRANSMIT - Transmit a frame
-***************************************************************************/
-static int
-e1000_transmit(struct eth_device *nic, volatile void *packet, int length)
-{
-       struct e1000_hw *hw = nic->priv;
-       struct e1000_tx_desc *txp;
-       int i = 0;
-
-       txp = tx_base + tx_tail;
-       tx_tail = (tx_tail + 1) % 8;
-
-       txp->buffer_addr = cpu_to_le64(virt_to_bus(packet));
-       txp->lower.data = cpu_to_le32(E1000_TXD_CMD_RPS | E1000_TXD_CMD_EOP |
-                                     E1000_TXD_CMD_IFCS | length);
-       txp->upper.data = 0;
-       E1000_WRITE_REG(hw, TDT, tx_tail);
-
-       while (!(le32_to_cpu(txp->upper.data) & E1000_TXD_STAT_DD)) {
-               if (i++ > TOUT_LOOP) {
-                       DEBUGOUT("e1000: tx timeout\n");
-                       return 0;
-               }
-               udelay(10);     /* give the nic a chance to write to the register */
-       }
-       return 1;
-}
-
-/*reset function*/
-static inline int
-e1000_reset(struct eth_device *nic)
-{
-       struct e1000_hw *hw = nic->priv;
-
-       e1000_reset_hw(hw);
-       if (hw->mac_type >= e1000_82544) {
-               E1000_WRITE_REG(hw, WUC, 0);
-       }
-       return e1000_init_hw(nic);
-}
-
-/**************************************************************************
-DISABLE - Turn off ethernet interface
-***************************************************************************/
-static void
-e1000_disable(struct eth_device *nic)
-{
-       struct e1000_hw *hw = nic->priv;
-
-       /* Turn off the ethernet interface */
-       E1000_WRITE_REG(hw, RCTL, 0);
-       E1000_WRITE_REG(hw, TCTL, 0);
-
-       /* Clear the transmit ring */
-       E1000_WRITE_REG(hw, TDH, 0);
-       E1000_WRITE_REG(hw, TDT, 0);
-
-       /* Clear the receive ring */
-       E1000_WRITE_REG(hw, RDH, 0);
-       E1000_WRITE_REG(hw, RDT, 0);
-
-       /* put the card in its initial state */
-#if 0
-       E1000_WRITE_REG(hw, CTRL, E1000_CTRL_RST);
-#endif
-       mdelay(10);
-
-}
-
-/**************************************************************************
-INIT - set up ethernet interface(s)
-***************************************************************************/
-static int
-e1000_init(struct eth_device *nic, bd_t * bis)
-{
-       struct e1000_hw *hw = nic->priv;
-       int ret_val = 0;
-
-       ret_val = e1000_reset(nic);
-       if (ret_val < 0) {
-               if ((ret_val == -E1000_ERR_NOLINK) ||
-                   (ret_val == -E1000_ERR_TIMEOUT)) {
-                       E1000_ERR("Valid Link not detected\n");
-               } else {
-                       E1000_ERR("Hardware Initialization Failed\n");
-               }
-               return 0;
-       }
-       e1000_configure_tx(hw);
-       e1000_setup_rctl(hw);
-       e1000_configure_rx(hw);
-       return 1;
-}
-
-/**************************************************************************
-PROBE - Look for an adapter, this routine's visible to the outside
-You should omit the last argument struct pci_device * for a non-PCI NIC
-***************************************************************************/
-int
-e1000_initialize(bd_t * bis)
-{
-       pci_dev_t devno;
-       int card_number = 0;
-       struct eth_device *nic = NULL;
-       struct e1000_hw *hw = NULL;
-       u32 iobase;
-       int idx = 0;
-       u32 PciCommandWord;
-
-       while (1) {             /* Find PCI device(s) */
-               if ((devno = pci_find_devices(supported, idx++)) < 0) {
-                       break;
-               }
-
-               pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase);
-               iobase &= ~0xf; /* Mask the bits that say "this is an io addr" */
-               DEBUGOUT("e1000#%d: iobase 0x%08x\n", card_number, iobase);
-
-               pci_write_config_dword(devno, PCI_COMMAND,
-                                      PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
-               /* Check if I/O accesses and Bus Mastering are enabled. */
-               pci_read_config_dword(devno, PCI_COMMAND, &PciCommandWord);
-               if (!(PciCommandWord & PCI_COMMAND_MEMORY)) {
-                       printf("Error: Can not enable MEM access.\n");
-                       continue;
-               } else if (!(PciCommandWord & PCI_COMMAND_MASTER)) {
-                       printf("Error: Can not enable Bus Mastering.\n");
-                       continue;
-               }
-
-               nic = (struct eth_device *) malloc(sizeof (*nic));
-               hw = (struct e1000_hw *) malloc(sizeof (*hw));
-               hw->pdev = devno;
-               nic->priv = hw;
-               nic->iobase = bus_to_phys(devno, iobase);
-
-               sprintf(nic->name, "e1000#%d", card_number);
-
-               /* Are these variables needed? */
-#if 0
-               hw->fc = e1000_fc_none;
-               hw->original_fc = e1000_fc_none;
-#else
-               hw->fc = e1000_fc_default;
-               hw->original_fc = e1000_fc_default;
-#endif
-               hw->autoneg_failed = 0;
-               hw->get_link_status = TRUE;
-               hw->hw_addr = (typeof(hw->hw_addr)) iobase;
-               hw->mac_type = e1000_undefined;
-
-               /* MAC and Phy settings */
-               if (e1000_sw_init(nic, card_number) < 0) {
-                       free(hw);
-                       free(nic);
-                       return 0;
-               }
-#ifndef CONFIG_AP1000
-               if (e1000_validate_eeprom_checksum(nic) < 0) {
-                       printf("The EEPROM Checksum Is Not Valid\n");
-                       free(hw);
-                       free(nic);
-                       return 0;
-               }
-#endif
-               e1000_read_mac_addr(nic);
-
-               E1000_WRITE_REG(hw, PBA, E1000_DEFAULT_PBA);
-
-               printf("e1000: %02x:%02x:%02x:%02x:%02x:%02x\n",
-                      nic->enetaddr[0], nic->enetaddr[1], nic->enetaddr[2],
-                      nic->enetaddr[3], nic->enetaddr[4], nic->enetaddr[5]);
-
-               nic->init = e1000_init;
-               nic->recv = e1000_poll;
-               nic->send = e1000_transmit;
-               nic->halt = e1000_disable;
-
-               eth_register(nic);
-
-               card_number++;
-       }
-       return 1;
-}
-
-#endif
diff --git a/drivers/e1000.h b/drivers/e1000.h
deleted file mode 100644 (file)
index 0fbdc90..0000000
+++ /dev/null
@@ -1,1758 +0,0 @@
-/*******************************************************************************
-
-
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
-
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-
-  Contact Information:
-  Linux NICS <linux.nics@intel.com>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-/* e1000_hw.h
- * Structures, enums, and macros for the MAC
- */
-
-#ifndef _E1000_HW_H_
-#define _E1000_HW_H_
-
-#include <common.h>
-#include <malloc.h>
-#include <net.h>
-#include <asm/io.h>
-#include <pci.h>
-
-#define E1000_ERR(args...) printf("e1000: " args)
-
-#ifdef E1000_DEBUG
-#define E1000_DBG(args...)     printf("e1000: " args)
-#define DEBUGOUT(fmt,args...) printf(fmt ,##args)
-#define DEBUGFUNC()        printf("%s\n", __FUNCTION__);
-#else
-#define E1000_DBG(args...)
-#define DEBUGFUNC()
-#define DEBUGOUT(fmt,args...)
-#endif
-
-/* Forward declarations of structures used by the shared code */
-struct e1000_hw;
-struct e1000_hw_stats;
-
-typedef enum {
-       FALSE = 0,
-       TRUE = 1
-} boolean_t;
-
-/* Enumerated types specific to the e1000 hardware */
-/* Media Access Controlers */
-typedef enum {
-       e1000_undefined = 0,
-       e1000_82542_rev2_0,
-       e1000_82542_rev2_1,
-       e1000_82543,
-       e1000_82544,
-       e1000_82540,
-       e1000_82545,
-       e1000_82546,
-       e1000_num_macs
-} e1000_mac_type;
-
-/* Media Types */
-typedef enum {
-       e1000_media_type_copper = 0,
-       e1000_media_type_fiber = 1,
-       e1000_num_media_types
-} e1000_media_type;
-
-typedef enum {
-       e1000_10_half = 0,
-       e1000_10_full = 1,
-       e1000_100_half = 2,
-       e1000_100_full = 3
-} e1000_speed_duplex_type;
-
-typedef enum {
-       e1000_lan_a = 0,
-       e1000_lan_b = 1
-} e1000_lan_loc;
-
-/* Flow Control Settings */
-typedef enum {
-       e1000_fc_none = 0,
-       e1000_fc_rx_pause = 1,
-       e1000_fc_tx_pause = 2,
-       e1000_fc_full = 3,
-       e1000_fc_default = 0xFF
-} e1000_fc_type;
-
-/* PCI bus types */
-typedef enum {
-       e1000_bus_type_unknown = 0,
-       e1000_bus_type_pci,
-       e1000_bus_type_pcix
-} e1000_bus_type;
-
-/* PCI bus speeds */
-typedef enum {
-       e1000_bus_speed_unknown = 0,
-       e1000_bus_speed_33,
-       e1000_bus_speed_66,
-       e1000_bus_speed_100,
-       e1000_bus_speed_133,
-       e1000_bus_speed_reserved
-} e1000_bus_speed;
-
-/* PCI bus widths */
-typedef enum {
-       e1000_bus_width_unknown = 0,
-       e1000_bus_width_32,
-       e1000_bus_width_64
-} e1000_bus_width;
-
-/* PHY status info structure and supporting enums */
-typedef enum {
-       e1000_cable_length_50 = 0,
-       e1000_cable_length_50_80,
-       e1000_cable_length_80_110,
-       e1000_cable_length_110_140,
-       e1000_cable_length_140,
-       e1000_cable_length_undefined = 0xFF
-} e1000_cable_length;
-
-typedef enum {
-       e1000_10bt_ext_dist_enable_normal = 0,
-       e1000_10bt_ext_dist_enable_lower,
-       e1000_10bt_ext_dist_enable_undefined = 0xFF
-} e1000_10bt_ext_dist_enable;
-
-typedef enum {
-       e1000_rev_polarity_normal = 0,
-       e1000_rev_polarity_reversed,
-       e1000_rev_polarity_undefined = 0xFF
-} e1000_rev_polarity;
-
-typedef enum {
-       e1000_polarity_reversal_enabled = 0,
-       e1000_polarity_reversal_disabled,
-       e1000_polarity_reversal_undefined = 0xFF
-} e1000_polarity_reversal;
-
-typedef enum {
-       e1000_auto_x_mode_manual_mdi = 0,
-       e1000_auto_x_mode_manual_mdix,
-       e1000_auto_x_mode_auto1,
-       e1000_auto_x_mode_auto2,
-       e1000_auto_x_mode_undefined = 0xFF
-} e1000_auto_x_mode;
-
-typedef enum {
-       e1000_1000t_rx_status_not_ok = 0,
-       e1000_1000t_rx_status_ok,
-       e1000_1000t_rx_status_undefined = 0xFF
-} e1000_1000t_rx_status;
-
-struct e1000_phy_info {
-       e1000_cable_length cable_length;
-       e1000_10bt_ext_dist_enable extended_10bt_distance;
-       e1000_rev_polarity cable_polarity;
-       e1000_polarity_reversal polarity_correction;
-       e1000_auto_x_mode mdix_mode;
-       e1000_1000t_rx_status local_rx;
-       e1000_1000t_rx_status remote_rx;
-};
-
-struct e1000_phy_stats {
-       uint32_t idle_errors;
-       uint32_t receive_errors;
-};
-
-/* Error Codes */
-#define E1000_SUCCESS      0
-#define E1000_ERR_EEPROM   1
-#define E1000_ERR_PHY      2
-#define E1000_ERR_CONFIG   3
-#define E1000_ERR_PARAM    4
-#define E1000_ERR_MAC_TYPE 5
-#define E1000_ERR_NOLINK   6
-#define E1000_ERR_TIMEOUT  7
-
-/* PCI Device IDs */
-#define E1000_DEV_ID_82542          0x1000
-#define E1000_DEV_ID_82543GC_FIBER  0x1001
-#define E1000_DEV_ID_82543GC_COPPER 0x1004
-#define E1000_DEV_ID_82544EI_COPPER 0x1008
-#define E1000_DEV_ID_82544EI_FIBER  0x1009
-#define E1000_DEV_ID_82544GC_COPPER 0x100C
-#define E1000_DEV_ID_82544GC_LOM    0x100D
-#define E1000_DEV_ID_82540EM        0x100E
-#define E1000_DEV_ID_82540EM_LOM    0x1015
-#define E1000_DEV_ID_82545EM_COPPER 0x100F
-#define E1000_DEV_ID_82545EM_FIBER  0x1011
-#define E1000_DEV_ID_82546EB_COPPER 0x1010
-#define E1000_DEV_ID_82546EB_FIBER  0x1012
-#define NUM_DEV_IDS 13
-
-#define NODE_ADDRESS_SIZE 6
-#define ETH_LENGTH_OF_ADDRESS 6
-
-/* MAC decode size is 128K - This is the size of BAR0 */
-#define MAC_DECODE_SIZE (128 * 1024)
-
-#define E1000_82542_2_0_REV_ID 2
-#define E1000_82542_2_1_REV_ID 3
-
-#define SPEED_10    10
-#define SPEED_100   100
-#define SPEED_1000  1000
-#define HALF_DUPLEX 1
-#define FULL_DUPLEX 2
-
-/* The sizes (in bytes) of a ethernet packet */
-#define ENET_HEADER_SIZE             14
-#define MAXIMUM_ETHERNET_FRAME_SIZE  1518      /* With FCS */
-#define MINIMUM_ETHERNET_FRAME_SIZE  64        /* With FCS */
-#define ETHERNET_FCS_SIZE            4
-#define MAXIMUM_ETHERNET_PACKET_SIZE \
-    (MAXIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE)
-#define MINIMUM_ETHERNET_PACKET_SIZE \
-    (MINIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE)
-#define CRC_LENGTH                   ETHERNET_FCS_SIZE
-#define MAX_JUMBO_FRAME_SIZE         0x3F00
-
-/* 802.1q VLAN Packet Sizes */
-#define VLAN_TAG_SIZE                     4    /* 802.3ac tag (not DMAed) */
-
-/* Ethertype field values */
-#define ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.3ac packet */
-#define ETHERNET_IP_TYPE        0x0800 /* IP packets */
-#define ETHERNET_ARP_TYPE       0x0806 /* Address Resolution Protocol (ARP) */
-
-/* Packet Header defines */
-#define IP_PROTOCOL_TCP    6
-#define IP_PROTOCOL_UDP    0x11
-
-/* This defines the bits that are set in the Interrupt Mask
- * Set/Read Register.  Each bit is documented below:
- *   o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
- *   o RXSEQ  = Receive Sequence Error
- */
-#define POLL_IMS_ENABLE_MASK ( \
-    E1000_IMS_RXDMT0 |         \
-    E1000_IMS_RXSEQ)
-
-/* This defines the bits that are set in the Interrupt Mask
- * Set/Read Register.  Each bit is documented below:
- *   o RXT0   = Receiver Timer Interrupt (ring 0)
- *   o TXDW   = Transmit Descriptor Written Back
- *   o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
- *   o RXSEQ  = Receive Sequence Error
- *   o LSC    = Link Status Change
- */
-#define IMS_ENABLE_MASK ( \
-    E1000_IMS_RXT0   |    \
-    E1000_IMS_TXDW   |    \
-    E1000_IMS_RXDMT0 |    \
-    E1000_IMS_RXSEQ  |    \
-    E1000_IMS_LSC)
-
-/* The number of high/low register pairs in the RAR. The RAR (Receive Address
- * Registers) holds the directed and multicast addresses that we monitor. We
- * reserve one of these spots for our directed address, allowing us room for
- * E1000_RAR_ENTRIES - 1 multicast addresses.
- */
-#define E1000_RAR_ENTRIES 16
-
-#define MIN_NUMBER_OF_DESCRIPTORS 8
-#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
-
-/* Receive Descriptor */
-struct e1000_rx_desc {
-       uint64_t buffer_addr;   /* Address of the descriptor's data buffer */
-       uint16_t length;        /* Length of data DMAed into data buffer */
-       uint16_t csum;          /* Packet checksum */
-       uint8_t status;         /* Descriptor status */
-       uint8_t errors;         /* Descriptor Errors */
-       uint16_t special;
-};
-
-/* Receive Decriptor bit definitions */
-#define E1000_RXD_STAT_DD       0x01   /* Descriptor Done */
-#define E1000_RXD_STAT_EOP      0x02   /* End of Packet */
-#define E1000_RXD_STAT_IXSM     0x04   /* Ignore checksum */
-#define E1000_RXD_STAT_VP       0x08   /* IEEE VLAN Packet */
-#define E1000_RXD_STAT_TCPCS    0x20   /* TCP xsum calculated */
-#define E1000_RXD_STAT_IPCS     0x40   /* IP xsum calculated */
-#define E1000_RXD_STAT_PIF      0x80   /* passed in-exact filter */
-#define E1000_RXD_ERR_CE        0x01   /* CRC Error */
-#define E1000_RXD_ERR_SE        0x02   /* Symbol Error */
-#define E1000_RXD_ERR_SEQ       0x04   /* Sequence Error */
-#define E1000_RXD_ERR_CXE       0x10   /* Carrier Extension Error */
-#define E1000_RXD_ERR_TCPE      0x20   /* TCP/UDP Checksum Error */
-#define E1000_RXD_ERR_IPE       0x40   /* IP Checksum Error */
-#define E1000_RXD_ERR_RXE       0x80   /* Rx Data Error */
-#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
-#define E1000_RXD_SPC_PRI_MASK  0xE000 /* Priority is in upper 3 bits */
-#define E1000_RXD_SPC_PRI_SHIFT 0x000D /* Priority is in upper 3 of 16 */
-#define E1000_RXD_SPC_CFI_MASK  0x1000 /* CFI is bit 12 */
-#define E1000_RXD_SPC_CFI_SHIFT 0x000C /* CFI is bit 12 */
-
-/* mask to determine if packets should be dropped due to frame errors */
-#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
-    E1000_RXD_ERR_CE  |                \
-    E1000_RXD_ERR_SE  |                \
-    E1000_RXD_ERR_SEQ |                \
-    E1000_RXD_ERR_CXE |                \
-    E1000_RXD_ERR_RXE)
-
-/* Transmit Descriptor */
-struct e1000_tx_desc {
-       uint64_t buffer_addr;   /* Address of the descriptor's data buffer */
-       union {
-               uint32_t data;
-               struct {
-                       uint16_t length;        /* Data buffer length */
-                       uint8_t cso;    /* Checksum offset */
-                       uint8_t cmd;    /* Descriptor control */
-               } flags;
-       } lower;
-       union {
-               uint32_t data;
-               struct {
-                       uint8_t status; /* Descriptor status */
-                       uint8_t css;    /* Checksum start */
-                       uint16_t special;
-               } fields;
-       } upper;
-};
-
-/* Transmit Descriptor bit definitions */
-#define E1000_TXD_DTYP_D     0x00100000        /* Data Descriptor */
-#define E1000_TXD_DTYP_C     0x00000000        /* Context Descriptor */
-#define E1000_TXD_POPTS_IXSM 0x01      /* Insert IP checksum */
-#define E1000_TXD_POPTS_TXSM 0x02      /* Insert TCP/UDP checksum */
-#define E1000_TXD_CMD_EOP    0x01000000        /* End of Packet */
-#define E1000_TXD_CMD_IFCS   0x02000000        /* Insert FCS (Ethernet CRC) */
-#define E1000_TXD_CMD_IC     0x04000000        /* Insert Checksum */
-#define E1000_TXD_CMD_RS     0x08000000        /* Report Status */
-#define E1000_TXD_CMD_RPS    0x10000000        /* Report Packet Sent */
-#define E1000_TXD_CMD_DEXT   0x20000000        /* Descriptor extension (0 = legacy) */
-#define E1000_TXD_CMD_VLE    0x40000000        /* Add VLAN tag */
-#define E1000_TXD_CMD_IDE    0x80000000        /* Enable Tidv register */
-#define E1000_TXD_STAT_DD    0x00000001        /* Descriptor Done */
-#define E1000_TXD_STAT_EC    0x00000002        /* Excess Collisions */
-#define E1000_TXD_STAT_LC    0x00000004        /* Late Collisions */
-#define E1000_TXD_STAT_TU    0x00000008        /* Transmit underrun */
-#define E1000_TXD_CMD_TCP    0x01000000        /* TCP packet */
-#define E1000_TXD_CMD_IP     0x02000000        /* IP packet */
-#define E1000_TXD_CMD_TSE    0x04000000        /* TCP Seg enable */
-#define E1000_TXD_STAT_TC    0x00000004        /* Tx Underrun */
-
-/* Offload Context Descriptor */
-struct e1000_context_desc {
-       union {
-               uint32_t ip_config;
-               struct {
-                       uint8_t ipcss;  /* IP checksum start */
-                       uint8_t ipcso;  /* IP checksum offset */
-                       uint16_t ipcse; /* IP checksum end */
-               } ip_fields;
-       } lower_setup;
-       union {
-               uint32_t tcp_config;
-               struct {
-                       uint8_t tucss;  /* TCP checksum start */
-                       uint8_t tucso;  /* TCP checksum offset */
-                       uint16_t tucse; /* TCP checksum end */
-               } tcp_fields;
-       } upper_setup;
-       uint32_t cmd_and_length;        /* */
-       union {
-               uint32_t data;
-               struct {
-                       uint8_t status; /* Descriptor status */
-                       uint8_t hdr_len;        /* Header length */
-                       uint16_t mss;   /* Maximum segment size */
-               } fields;
-       } tcp_seg_setup;
-};
-
-/* Offload data descriptor */
-struct e1000_data_desc {
-       uint64_t buffer_addr;   /* Address of the descriptor's buffer address */
-       union {
-               uint32_t data;
-               struct {
-                       uint16_t length;        /* Data buffer length */
-                       uint8_t typ_len_ext;    /* */
-                       uint8_t cmd;    /* */
-               } flags;
-       } lower;
-       union {
-               uint32_t data;
-               struct {
-                       uint8_t status; /* Descriptor status */
-                       uint8_t popts;  /* Packet Options */
-                       uint16_t special;       /* */
-               } fields;
-       } upper;
-};
-
-/* Filters */
-#define E1000_NUM_UNICAST          16  /* Unicast filter entries */
-#define E1000_MC_TBL_SIZE          128 /* Multicast Filter Table (4096 bits) */
-#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
-
-/* Receive Address Register */
-struct e1000_rar {
-       volatile uint32_t low;  /* receive address low */
-       volatile uint32_t high; /* receive address high */
-};
-
-/* The number of entries in the Multicast Table Array (MTA). */
-#define E1000_NUM_MTA_REGISTERS 128
-
-/* IPv4 Address Table Entry */
-struct e1000_ipv4_at_entry {
-       volatile uint32_t ipv4_addr;    /* IP Address (RW) */
-       volatile uint32_t reserved;
-};
-
-/* Four wakeup IP addresses are supported */
-#define E1000_WAKEUP_IP_ADDRESS_COUNT_MAX 4
-#define E1000_IP4AT_SIZE                  E1000_WAKEUP_IP_ADDRESS_COUNT_MAX
-#define E1000_IP6AT_SIZE                  1
-
-/* IPv6 Address Table Entry */
-struct e1000_ipv6_at_entry {
-       volatile uint8_t ipv6_addr[16];
-};
-
-/* Flexible Filter Length Table Entry */
-struct e1000_fflt_entry {
-       volatile uint32_t length;       /* Flexible Filter Length (RW) */
-       volatile uint32_t reserved;
-};
-
-/* Flexible Filter Mask Table Entry */
-struct e1000_ffmt_entry {
-       volatile uint32_t mask; /* Flexible Filter Mask (RW) */
-       volatile uint32_t reserved;
-};
-
-/* Flexible Filter Value Table Entry */
-struct e1000_ffvt_entry {
-       volatile uint32_t value;        /* Flexible Filter Value (RW) */
-       volatile uint32_t reserved;
-};
-
-/* Four Flexible Filters are supported */
-#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4
-
-/* Each Flexible Filter is at most 128 (0x80) bytes in length */
-#define E1000_FLEXIBLE_FILTER_SIZE_MAX  128
-
-#define E1000_FFLT_SIZE E1000_FLEXIBLE_FILTER_COUNT_MAX
-#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
-#define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
-
-/* Register Set. (82543, 82544)
- *
- * Registers are defined to be 32 bits and  should be accessed as 32 bit values.
- * These registers are physically located on the NIC, but are mapped into the
- * host memory address space.
- *
- * RW - register is both readable and writable
- * RO - register is read only
- * WO - register is write only
- * R/clr - register is read only and is cleared when read
- * A - register array
- */
-#define E1000_CTRL     0x00000 /* Device Control - RW */
-#define E1000_STATUS   0x00008 /* Device Status - RO */
-#define E1000_EECD     0x00010 /* EEPROM/Flash Control - RW */
-#define E1000_EERD     0x00014 /* EEPROM Read - RW */
-#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
-#define E1000_MDIC     0x00020 /* MDI Control - RW */
-#define E1000_FCAL     0x00028 /* Flow Control Address Low - RW */
-#define E1000_FCAH     0x0002C /* Flow Control Address High -RW */
-#define E1000_FCT      0x00030 /* Flow Control Type - RW */
-#define E1000_VET      0x00038 /* VLAN Ether Type - RW */
-#define E1000_ICR      0x000C0 /* Interrupt Cause Read - R/clr */
-#define E1000_ITR      0x000C4 /* Interrupt Throttling Rate - RW */
-#define E1000_ICS      0x000C8 /* Interrupt Cause Set - WO */
-#define E1000_IMS      0x000D0 /* Interrupt Mask Set - RW */
-#define E1000_IMC      0x000D8 /* Interrupt Mask Clear - WO */
-#define E1000_RCTL     0x00100 /* RX Control - RW */
-#define E1000_FCTTV    0x00170 /* Flow Control Transmit Timer Value - RW */
-#define E1000_TXCW     0x00178 /* TX Configuration Word - RW */
-#define E1000_RXCW     0x00180 /* RX Configuration Word - RO */
-#define E1000_TCTL     0x00400 /* TX Control - RW */
-#define E1000_TIPG     0x00410 /* TX Inter-packet gap -RW */
-#define E1000_TBT      0x00448 /* TX Burst Timer - RW */
-#define E1000_AIT      0x00458 /* Adaptive Interframe Spacing Throttle - RW */
-#define E1000_LEDCTL   0x00E00 /* LED Control - RW */
-#define E1000_PBA      0x01000 /* Packet Buffer Allocation - RW */
-#define E1000_FCRTL    0x02160 /* Flow Control Receive Threshold Low - RW */
-#define E1000_FCRTH    0x02168 /* Flow Control Receive Threshold High - RW */
-#define E1000_RDBAL    0x02800 /* RX Descriptor Base Address Low - RW */
-#define E1000_RDBAH    0x02804 /* RX Descriptor Base Address High - RW */
-#define E1000_RDLEN    0x02808 /* RX Descriptor Length - RW */
-#define E1000_RDH      0x02810 /* RX Descriptor Head - RW */
-#define E1000_RDT      0x02818 /* RX Descriptor Tail - RW */
-#define E1000_RDTR     0x02820 /* RX Delay Timer - RW */
-#define E1000_RXDCTL   0x02828 /* RX Descriptor Control - RW */
-#define E1000_RADV     0x0282C /* RX Interrupt Absolute Delay Timer - RW */
-#define E1000_RSRPD    0x02C00 /* RX Small Packet Detect - RW */
-#define E1000_TXDMAC   0x03000 /* TX DMA Control - RW */
-#define E1000_TDBAL    0x03800 /* TX Descriptor Base Address Low - RW */
-#define E1000_TDBAH    0x03804 /* TX Descriptor Base Address High - RW */
-#define E1000_TDLEN    0x03808 /* TX Descriptor Length - RW */
-#define E1000_TDH      0x03810 /* TX Descriptor Head - RW */
-#define E1000_TDT      0x03818 /* TX Descripotr Tail - RW */
-#define E1000_TIDV     0x03820 /* TX Interrupt Delay Value - RW */
-#define E1000_TXDCTL   0x03828 /* TX Descriptor Control - RW */
-#define E1000_TADV     0x0382C /* TX Interrupt Absolute Delay Val - RW */
-#define E1000_TSPMT    0x03830 /* TCP Segmentation PAD & Min Threshold - RW */
-#define E1000_CRCERRS  0x04000 /* CRC Error Count - R/clr */
-#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
-#define E1000_SYMERRS  0x04008 /* Symbol Error Count - R/clr */
-#define E1000_RXERRC   0x0400C /* Receive Error Count - R/clr */
-#define E1000_MPC      0x04010 /* Missed Packet Count - R/clr */
-#define E1000_SCC      0x04014 /* Single Collision Count - R/clr */
-#define E1000_ECOL     0x04018 /* Excessive Collision Count - R/clr */
-#define E1000_MCC      0x0401C /* Multiple Collision Count - R/clr */
-#define E1000_LATECOL  0x04020 /* Late Collision Count - R/clr */
-#define E1000_COLC     0x04028 /* Collision Count - R/clr */
-#define E1000_DC       0x04030 /* Defer Count - R/clr */
-#define E1000_TNCRS    0x04034 /* TX-No CRS - R/clr */
-#define E1000_SEC      0x04038 /* Sequence Error Count - R/clr */
-#define E1000_CEXTERR  0x0403C /* Carrier Extension Error Count - R/clr */
-#define E1000_RLEC     0x04040 /* Receive Length Error Count - R/clr */
-#define E1000_XONRXC   0x04048 /* XON RX Count - R/clr */
-#define E1000_XONTXC   0x0404C /* XON TX Count - R/clr */
-#define E1000_XOFFRXC  0x04050 /* XOFF RX Count - R/clr */
-#define E1000_XOFFTXC  0x04054 /* XOFF TX Count - R/clr */
-#define E1000_FCRUC    0x04058 /* Flow Control RX Unsupported Count- R/clr */
-#define E1000_PRC64    0x0405C /* Packets RX (64 bytes) - R/clr */
-#define E1000_PRC127   0x04060 /* Packets RX (65-127 bytes) - R/clr */
-#define E1000_PRC255   0x04064 /* Packets RX (128-255 bytes) - R/clr */
-#define E1000_PRC511   0x04068 /* Packets RX (255-511 bytes) - R/clr */
-#define E1000_PRC1023  0x0406C /* Packets RX (512-1023 bytes) - R/clr */
-#define E1000_PRC1522  0x04070 /* Packets RX (1024-1522 bytes) - R/clr */
-#define E1000_GPRC     0x04074 /* Good Packets RX Count - R/clr */
-#define E1000_BPRC     0x04078 /* Broadcast Packets RX Count - R/clr */
-#define E1000_MPRC     0x0407C /* Multicast Packets RX Count - R/clr */
-#define E1000_GPTC     0x04080 /* Good Packets TX Count - R/clr */
-#define E1000_GORCL    0x04088 /* Good Octets RX Count Low - R/clr */
-#define E1000_GORCH    0x0408C /* Good Octets RX Count High - R/clr */
-#define E1000_GOTCL    0x04090 /* Good Octets TX Count Low - R/clr */
-#define E1000_GOTCH    0x04094 /* Good Octets TX Count High - R/clr */
-#define E1000_RNBC     0x040A0 /* RX No Buffers Count - R/clr */
-#define E1000_RUC      0x040A4 /* RX Undersize Count - R/clr */
-#define E1000_RFC      0x040A8 /* RX Fragment Count - R/clr */
-#define E1000_ROC      0x040AC /* RX Oversize Count - R/clr */
-#define E1000_RJC      0x040B0 /* RX Jabber Count - R/clr */
-#define E1000_MGTPRC   0x040B4 /* Management Packets RX Count - R/clr */
-#define E1000_MGTPDC   0x040B8 /* Management Packets Dropped Count - R/clr */
-#define E1000_MGTPTC   0x040BC /* Management Packets TX Count - R/clr */
-#define E1000_TORL     0x040C0 /* Total Octets RX Low - R/clr */
-#define E1000_TORH     0x040C4 /* Total Octets RX High - R/clr */
-#define E1000_TOTL     0x040C8 /* Total Octets TX Low - R/clr */
-#define E1000_TOTH     0x040CC /* Total Octets TX High - R/clr */
-#define E1000_TPR      0x040D0 /* Total Packets RX - R/clr */
-#define E1000_TPT      0x040D4 /* Total Packets TX - R/clr */
-#define E1000_PTC64    0x040D8 /* Packets TX (64 bytes) - R/clr */
-#define E1000_PTC127   0x040DC /* Packets TX (65-127 bytes) - R/clr */
-#define E1000_PTC255   0x040E0 /* Packets TX (128-255 bytes) - R/clr */
-#define E1000_PTC511   0x040E4 /* Packets TX (256-511 bytes) - R/clr */
-#define E1000_PTC1023  0x040E8 /* Packets TX (512-1023 bytes) - R/clr */
-#define E1000_PTC1522  0x040EC /* Packets TX (1024-1522 Bytes) - R/clr */
-#define E1000_MPTC     0x040F0 /* Multicast Packets TX Count - R/clr */
-#define E1000_BPTC     0x040F4 /* Broadcast Packets TX Count - R/clr */
-#define E1000_TSCTC    0x040F8 /* TCP Segmentation Context TX - R/clr */
-#define E1000_TSCTFC   0x040FC /* TCP Segmentation Context TX Fail - R/clr */
-#define E1000_RXCSUM   0x05000 /* RX Checksum Control - RW */
-#define E1000_MTA      0x05200 /* Multicast Table Array - RW Array */
-#define E1000_RA       0x05400 /* Receive Address - RW Array */
-#define E1000_VFTA     0x05600 /* VLAN Filter Table Array - RW Array */
-#define E1000_WUC      0x05800 /* Wakeup Control - RW */
-#define E1000_WUFC     0x05808 /* Wakeup Filter Control - RW */
-#define E1000_WUS      0x05810 /* Wakeup Status - RO */
-#define E1000_MANC     0x05820 /* Management Control - RW */
-#define E1000_IPAV     0x05838 /* IP Address Valid - RW */
-#define E1000_IP4AT    0x05840 /* IPv4 Address Table - RW Array */
-#define E1000_IP6AT    0x05880 /* IPv6 Address Table - RW Array */
-#define E1000_WUPL     0x05900 /* Wakeup Packet Length - RW */
-#define E1000_WUPM     0x05A00 /* Wakeup Packet Memory - RO A */
-#define E1000_FFLT     0x05F00 /* Flexible Filter Length Table - RW Array */
-#define E1000_FFMT     0x09000 /* Flexible Filter Mask Table - RW Array */
-#define E1000_FFVT     0x09800 /* Flexible Filter Value Table - RW Array */
-
-/* Register Set (82542)
- *
- * Some of the 82542 registers are located at different offsets than they are
- * in more current versions of the 8254x. Despite the difference in location,
- * the registers function in the same manner.
- */
-#define E1000_82542_CTRL     E1000_CTRL
-#define E1000_82542_STATUS   E1000_STATUS
-#define E1000_82542_EECD     E1000_EECD
-#define E1000_82542_EERD     E1000_EERD
-#define E1000_82542_CTRL_EXT E1000_CTRL_EXT
-#define E1000_82542_MDIC     E1000_MDIC
-#define E1000_82542_FCAL     E1000_FCAL
-#define E1000_82542_FCAH     E1000_FCAH
-#define E1000_82542_FCT      E1000_FCT
-#define E1000_82542_VET      E1000_VET
-#define E1000_82542_RA       0x00040
-#define E1000_82542_ICR      E1000_ICR
-#define E1000_82542_ITR      E1000_ITR
-#define E1000_82542_ICS      E1000_ICS
-#define E1000_82542_IMS      E1000_IMS
-#define E1000_82542_IMC      E1000_IMC
-#define E1000_82542_RCTL     E1000_RCTL
-#define E1000_82542_RDTR     0x00108
-#define E1000_82542_RDBAL    0x00110
-#define E1000_82542_RDBAH    0x00114
-#define E1000_82542_RDLEN    0x00118
-#define E1000_82542_RDH      0x00120
-#define E1000_82542_RDT      0x00128
-#define E1000_82542_FCRTH    0x00160
-#define E1000_82542_FCRTL    0x00168
-#define E1000_82542_FCTTV    E1000_FCTTV
-#define E1000_82542_TXCW     E1000_TXCW
-#define E1000_82542_RXCW     E1000_RXCW
-#define E1000_82542_MTA      0x00200
-#define E1000_82542_TCTL     E1000_TCTL
-#define E1000_82542_TIPG     E1000_TIPG
-#define E1000_82542_TDBAL    0x00420
-#define E1000_82542_TDBAH    0x00424
-#define E1000_82542_TDLEN    0x00428
-#define E1000_82542_TDH      0x00430
-#define E1000_82542_TDT      0x00438
-#define E1000_82542_TIDV     0x00440
-#define E1000_82542_TBT      E1000_TBT
-#define E1000_82542_AIT      E1000_AIT
-#define E1000_82542_VFTA     0x00600
-#define E1000_82542_LEDCTL   E1000_LEDCTL
-#define E1000_82542_PBA      E1000_PBA
-#define E1000_82542_RXDCTL   E1000_RXDCTL
-#define E1000_82542_RADV     E1000_RADV
-#define E1000_82542_RSRPD    E1000_RSRPD
-#define E1000_82542_TXDMAC   E1000_TXDMAC
-#define E1000_82542_TXDCTL   E1000_TXDCTL
-#define E1000_82542_TADV     E1000_TADV
-#define E1000_82542_TSPMT    E1000_TSPMT
-#define E1000_82542_CRCERRS  E1000_CRCERRS
-#define E1000_82542_ALGNERRC E1000_ALGNERRC
-#define E1000_82542_SYMERRS  E1000_SYMERRS
-#define E1000_82542_RXERRC   E1000_RXERRC
-#define E1000_82542_MPC      E1000_MPC
-#define E1000_82542_SCC      E1000_SCC
-#define E1000_82542_ECOL     E1000_ECOL
-#define E1000_82542_MCC      E1000_MCC
-#define E1000_82542_LATECOL  E1000_LATECOL
-#define E1000_82542_COLC     E1000_COLC
-#define E1000_82542_DC       E1000_DC
-#define E1000_82542_TNCRS    E1000_TNCRS
-#define E1000_82542_SEC      E1000_SEC
-#define E1000_82542_CEXTERR  E1000_CEXTERR
-#define E1000_82542_RLEC     E1000_RLEC
-#define E1000_82542_XONRXC   E1000_XONRXC
-#define E1000_82542_XONTXC   E1000_XONTXC
-#define E1000_82542_XOFFRXC  E1000_XOFFRXC
-#define E1000_82542_XOFFTXC  E1000_XOFFTXC
-#define E1000_82542_FCRUC    E1000_FCRUC
-#define E1000_82542_PRC64    E1000_PRC64
-#define E1000_82542_PRC127   E1000_PRC127
-#define E1000_82542_PRC255   E1000_PRC255
-#define E1000_82542_PRC511   E1000_PRC511
-#define E1000_82542_PRC1023  E1000_PRC1023
-#define E1000_82542_PRC1522  E1000_PRC1522
-#define E1000_82542_GPRC     E1000_GPRC
-#define E1000_82542_BPRC     E1000_BPRC
-#define E1000_82542_MPRC     E1000_MPRC
-#define E1000_82542_GPTC     E1000_GPTC
-#define E1000_82542_GORCL    E1000_GORCL
-#define E1000_82542_GORCH    E1000_GORCH
-#define E1000_82542_GOTCL    E1000_GOTCL
-#define E1000_82542_GOTCH    E1000_GOTCH
-#define E1000_82542_RNBC     E1000_RNBC
-#define E1000_82542_RUC      E1000_RUC
-#define E1000_82542_RFC      E1000_RFC
-#define E1000_82542_ROC      E1000_ROC
-#define E1000_82542_RJC      E1000_RJC
-#define E1000_82542_MGTPRC   E1000_MGTPRC
-#define E1000_82542_MGTPDC   E1000_MGTPDC
-#define E1000_82542_MGTPTC   E1000_MGTPTC
-#define E1000_82542_TORL     E1000_TORL
-#define E1000_82542_TORH     E1000_TORH
-#define E1000_82542_TOTL     E1000_TOTL
-#define E1000_82542_TOTH     E1000_TOTH
-#define E1000_82542_TPR      E1000_TPR
-#define E1000_82542_TPT      E1000_TPT
-#define E1000_82542_PTC64    E1000_PTC64
-#define E1000_82542_PTC127   E1000_PTC127
-#define E1000_82542_PTC255   E1000_PTC255
-#define E1000_82542_PTC511   E1000_PTC511
-#define E1000_82542_PTC1023  E1000_PTC1023
-#define E1000_82542_PTC1522  E1000_PTC1522
-#define E1000_82542_MPTC     E1000_MPTC
-#define E1000_82542_BPTC     E1000_BPTC
-#define E1000_82542_TSCTC    E1000_TSCTC
-#define E1000_82542_TSCTFC   E1000_TSCTFC
-#define E1000_82542_RXCSUM   E1000_RXCSUM
-#define E1000_82542_WUC      E1000_WUC
-#define E1000_82542_WUFC     E1000_WUFC
-#define E1000_82542_WUS      E1000_WUS
-#define E1000_82542_MANC     E1000_MANC
-#define E1000_82542_IPAV     E1000_IPAV
-#define E1000_82542_IP4AT    E1000_IP4AT
-#define E1000_82542_IP6AT    E1000_IP6AT
-#define E1000_82542_WUPL     E1000_WUPL
-#define E1000_82542_WUPM     E1000_WUPM
-#define E1000_82542_FFLT     E1000_FFLT
-#define E1000_82542_FFMT     E1000_FFMT
-#define E1000_82542_FFVT     E1000_FFVT
-
-/* Statistics counters collected by the MAC */
-struct e1000_hw_stats {
-       uint64_t crcerrs;
-       uint64_t algnerrc;
-       uint64_t symerrs;
-       uint64_t rxerrc;
-       uint64_t mpc;
-       uint64_t scc;
-       uint64_t ecol;
-       uint64_t mcc;
-       uint64_t latecol;
-       uint64_t colc;
-       uint64_t dc;
-       uint64_t tncrs;
-       uint64_t sec;
-       uint64_t cexterr;
-       uint64_t rlec;
-       uint64_t xonrxc;
-       uint64_t xontxc;
-       uint64_t xoffrxc;
-       uint64_t xofftxc;
-       uint64_t fcruc;
-       uint64_t prc64;
-       uint64_t prc127;
-       uint64_t prc255;
-       uint64_t prc511;
-       uint64_t prc1023;
-       uint64_t prc1522;
-       uint64_t gprc;
-       uint64_t bprc;
-       uint64_t mprc;
-       uint64_t gptc;
-       uint64_t gorcl;
-       uint64_t gorch;
-       uint64_t gotcl;
-       uint64_t gotch;
-       uint64_t rnbc;
-       uint64_t ruc;
-       uint64_t rfc;
-       uint64_t roc;
-       uint64_t rjc;
-       uint64_t mgprc;
-       uint64_t mgpdc;
-       uint64_t mgptc;
-       uint64_t torl;
-       uint64_t torh;
-       uint64_t totl;
-       uint64_t toth;
-       uint64_t tpr;
-       uint64_t tpt;
-       uint64_t ptc64;
-       uint64_t ptc127;
-       uint64_t ptc255;
-       uint64_t ptc511;
-       uint64_t ptc1023;
-       uint64_t ptc1522;
-       uint64_t mptc;
-       uint64_t bptc;
-       uint64_t tsctc;
-       uint64_t tsctfc;
-};
-
-/* Structure containing variables used by the shared code (e1000_hw.c) */
-struct e1000_hw {
-       pci_dev_t pdev;
-       uint8_t *hw_addr;
-       e1000_mac_type mac_type;
-       e1000_media_type media_type;
-       e1000_lan_loc lan_loc;
-       e1000_fc_type fc;
-#if 0
-       e1000_bus_speed bus_speed;
-       e1000_bus_width bus_width;
-       e1000_bus_type bus_type;
-       uint32_t io_base;
-#endif
-       uint32_t phy_id;
-       uint32_t phy_addr;
-       uint32_t original_fc;
-       uint32_t txcw;
-       uint32_t autoneg_failed;
-#if 0
-       uint32_t max_frame_size;
-       uint32_t min_frame_size;
-       uint32_t mc_filter_type;
-       uint32_t num_mc_addrs;
-       uint32_t collision_delta;
-       uint32_t tx_packet_delta;
-       uint32_t ledctl_default;
-       uint32_t ledctl_mode1;
-       uint32_t ledctl_mode2;
-#endif
-       uint16_t autoneg_advertised;
-       uint16_t pci_cmd_word;
-       uint16_t fc_high_water;
-       uint16_t fc_low_water;
-       uint16_t fc_pause_time;
-#if 0
-       uint16_t current_ifs_val;
-       uint16_t ifs_min_val;
-       uint16_t ifs_max_val;
-       uint16_t ifs_step_size;
-       uint16_t ifs_ratio;
-#endif
-       uint16_t device_id;
-       uint16_t vendor_id;
-       uint16_t subsystem_id;
-       uint16_t subsystem_vendor_id;
-       uint8_t revision_id;
-#if 0
-       uint8_t autoneg;
-       uint8_t mdix;
-       uint8_t forced_speed_duplex;
-       uint8_t wait_autoneg_complete;
-       uint8_t dma_fairness;
-#endif
-#if 0
-       uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
-       boolean_t disable_polarity_correction;
-#endif
-       boolean_t get_link_status;
-       boolean_t tbi_compatibility_en;
-       boolean_t tbi_compatibility_on;
-       boolean_t fc_send_xon;
-       boolean_t report_tx_early;
-#if 0
-       boolean_t adaptive_ifs;
-       boolean_t ifs_params_forced;
-       boolean_t in_ifs_mode;
-#endif
-};
-
-#define E1000_EEPROM_SWDPIN0   0x0001  /* SWDPIN 0 EEPROM Value */
-#define E1000_EEPROM_LED_LOGIC 0x0020  /* Led Logic Word */
-
-/* Register Bit Masks */
-/* Device Control */
-#define E1000_CTRL_FD       0x00000001 /* Full duplex.0=half; 1=full */
-#define E1000_CTRL_BEM      0x00000002 /* Endian Mode.0=little,1=big */
-#define E1000_CTRL_PRIOR    0x00000004 /* Priority on PCI. 0=rx,1=fair */
-#define E1000_CTRL_LRST     0x00000008 /* Link reset. 0=normal,1=reset */
-#define E1000_CTRL_TME      0x00000010 /* Test mode. 0=normal,1=test */
-#define E1000_CTRL_SLE      0x00000020 /* Serial Link on 0=dis,1=en */
-#define E1000_CTRL_ASDE     0x00000020 /* Auto-speed detect enable */
-#define E1000_CTRL_SLU      0x00000040 /* Set link up (Force Link) */
-#define E1000_CTRL_ILOS     0x00000080 /* Invert Loss-Of Signal */
-#define E1000_CTRL_SPD_SEL  0x00000300 /* Speed Select Mask */
-#define E1000_CTRL_SPD_10   0x00000000 /* Force 10Mb */
-#define E1000_CTRL_SPD_100  0x00000100 /* Force 100Mb */
-#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */
-#define E1000_CTRL_BEM32    0x00000400 /* Big Endian 32 mode */
-#define E1000_CTRL_FRCSPD   0x00000800 /* Force Speed */
-#define E1000_CTRL_FRCDPX   0x00001000 /* Force Duplex */
-#define E1000_CTRL_SWDPIN0  0x00040000 /* SWDPIN 0 value */
-#define E1000_CTRL_SWDPIN1  0x00080000 /* SWDPIN 1 value */
-#define E1000_CTRL_SWDPIN2  0x00100000 /* SWDPIN 2 value */
-#define E1000_CTRL_SWDPIN3  0x00200000 /* SWDPIN 3 value */
-#define E1000_CTRL_SWDPIO0  0x00400000 /* SWDPIN 0 Input or output */
-#define E1000_CTRL_SWDPIO1  0x00800000 /* SWDPIN 1 input or output */
-#define E1000_CTRL_SWDPIO2  0x01000000 /* SWDPIN 2 input or output */
-#define E1000_CTRL_SWDPIO3  0x02000000 /* SWDPIN 3 input or output */
-#define E1000_CTRL_RST      0x04000000 /* Global reset */
-#define E1000_CTRL_RFCE     0x08000000 /* Receive Flow Control enable */
-#define E1000_CTRL_TFCE     0x10000000 /* Transmit flow control enable */
-#define E1000_CTRL_RTE      0x20000000 /* Routing tag enable */
-#define E1000_CTRL_VME      0x40000000 /* IEEE VLAN mode enable */
-#define E1000_CTRL_PHY_RST  0x80000000 /* PHY Reset */
-
-/* Device Status */
-#define E1000_STATUS_FD         0x00000001     /* Full duplex.0=half,1=full */
-#define E1000_STATUS_LU         0x00000002     /* Link up.0=no,1=link */
-#define E1000_STATUS_FUNC_MASK  0x0000000C     /* PCI Function Mask */
-#define E1000_STATUS_FUNC_0     0x00000000     /* Function 0 */
-#define E1000_STATUS_FUNC_1     0x00000004     /* Function 1 */
-#define E1000_STATUS_TXOFF      0x00000010     /* transmission paused */
-#define E1000_STATUS_TBIMODE    0x00000020     /* TBI mode */
-#define E1000_STATUS_SPEED_MASK 0x000000C0
-#define E1000_STATUS_SPEED_10   0x00000000     /* Speed 10Mb/s */
-#define E1000_STATUS_SPEED_100  0x00000040     /* Speed 100Mb/s */
-#define E1000_STATUS_SPEED_1000 0x00000080     /* Speed 1000Mb/s */
-#define E1000_STATUS_ASDV       0x00000300     /* Auto speed detect value */
-#define E1000_STATUS_MTXCKOK    0x00000400     /* MTX clock running OK */
-#define E1000_STATUS_PCI66      0x00000800     /* In 66Mhz slot */
-#define E1000_STATUS_BUS64      0x00001000     /* In 64 bit slot */
-#define E1000_STATUS_PCIX_MODE  0x00002000     /* PCI-X mode */
-#define E1000_STATUS_PCIX_SPEED 0x0000C000     /* PCI-X bus speed */
-
-/* Constants used to intrepret the masked PCI-X bus speed. */
-#define E1000_STATUS_PCIX_SPEED_66  0x00000000 /* PCI-X bus speed  50-66 MHz */
-#define E1000_STATUS_PCIX_SPEED_100 0x00004000 /* PCI-X bus speed  66-100 MHz */
-#define E1000_STATUS_PCIX_SPEED_133 0x00008000 /* PCI-X bus speed 100-133 MHz */
-
-/* EEPROM/Flash Control */
-#define E1000_EECD_SK        0x00000001        /* EEPROM Clock */
-#define E1000_EECD_CS        0x00000002        /* EEPROM Chip Select */
-#define E1000_EECD_DI        0x00000004        /* EEPROM Data In */
-#define E1000_EECD_DO        0x00000008        /* EEPROM Data Out */
-#define E1000_EECD_FWE_MASK  0x00000030
-#define E1000_EECD_FWE_DIS   0x00000010        /* Disable FLASH writes */
-#define E1000_EECD_FWE_EN    0x00000020        /* Enable FLASH writes */
-#define E1000_EECD_FWE_SHIFT 4
-#define E1000_EECD_SIZE      0x00000200        /* EEPROM Size (0=64 word 1=256 word) */
-#define E1000_EECD_REQ       0x00000040        /* EEPROM Access Request */
-#define E1000_EECD_GNT       0x00000080        /* EEPROM Access Grant */
-#define E1000_EECD_PRES      0x00000100        /* EEPROM Present */
-
-/* EEPROM Read */
-#define E1000_EERD_START      0x00000001       /* Start Read */
-#define E1000_EERD_DONE       0x00000010       /* Read Done */
-#define E1000_EERD_ADDR_SHIFT 8
-#define E1000_EERD_ADDR_MASK  0x0000FF00       /* Read Address */
-#define E1000_EERD_DATA_SHIFT 16
-#define E1000_EERD_DATA_MASK  0xFFFF0000       /* Read Data */
-
-/* Extended Device Control */
-#define E1000_CTRL_EXT_GPI0_EN   0x00000001    /* Maps SDP4 to GPI0 */
-#define E1000_CTRL_EXT_GPI1_EN   0x00000002    /* Maps SDP5 to GPI1 */
-#define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN
-#define E1000_CTRL_EXT_GPI2_EN   0x00000004    /* Maps SDP6 to GPI2 */
-#define E1000_CTRL_EXT_GPI3_EN   0x00000008    /* Maps SDP7 to GPI3 */
-#define E1000_CTRL_EXT_SDP4_DATA 0x00000010    /* Value of SW Defineable Pin 4 */
-#define E1000_CTRL_EXT_SDP5_DATA 0x00000020    /* Value of SW Defineable Pin 5 */
-#define E1000_CTRL_EXT_PHY_INT   E1000_CTRL_EXT_SDP5_DATA
-#define E1000_CTRL_EXT_SDP6_DATA 0x00000040    /* Value of SW Defineable Pin 6 */
-#define E1000_CTRL_EXT_SWDPIN6          0x00000040     /* SWDPIN 6 value */
-#define E1000_CTRL_EXT_SDP7_DATA 0x00000080    /* Value of SW Defineable Pin 7 */
-#define E1000_CTRL_EXT_SWDPIN7          0x00000080     /* SWDPIN 7 value */
-#define E1000_CTRL_EXT_SDP4_DIR  0x00000100    /* Direction of SDP4 0=in 1=out */
-#define E1000_CTRL_EXT_SDP5_DIR  0x00000200    /* Direction of SDP5 0=in 1=out */
-#define E1000_CTRL_EXT_SDP6_DIR  0x00000400    /* Direction of SDP6 0=in 1=out */
-#define E1000_CTRL_EXT_SWDPIO6   0x00000400    /* SWDPIN 6 Input or output */
-#define E1000_CTRL_EXT_SDP7_DIR  0x00000800    /* Direction of SDP7 0=in 1=out */
-#define E1000_CTRL_EXT_SWDPIO7   0x00000800    /* SWDPIN 7 Input or output */
-#define E1000_CTRL_EXT_ASDCHK    0x00001000    /* Initiate an ASD sequence */
-#define E1000_CTRL_EXT_EE_RST    0x00002000    /* Reinitialize from EEPROM */
-#define E1000_CTRL_EXT_IPS       0x00004000    /* Invert Power State */
-#define E1000_CTRL_EXT_SPD_BYPS  0x00008000    /* Speed Select Bypass */
-#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
-#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
-#define E1000_CTRL_EXT_LINK_MODE_TBI  0x00C00000
-#define E1000_CTRL_EXT_WR_WMARK_MASK  0x03000000
-#define E1000_CTRL_EXT_WR_WMARK_256   0x00000000
-#define E1000_CTRL_EXT_WR_WMARK_320   0x01000000
-#define E1000_CTRL_EXT_WR_WMARK_384   0x02000000
-#define E1000_CTRL_EXT_WR_WMARK_448   0x03000000
-
-/* MDI Control */
-#define E1000_MDIC_DATA_MASK 0x0000FFFF
-#define E1000_MDIC_REG_MASK  0x001F0000
-#define E1000_MDIC_REG_SHIFT 16
-#define E1000_MDIC_PHY_MASK  0x03E00000
-#define E1000_MDIC_PHY_SHIFT 21
-#define E1000_MDIC_OP_WRITE  0x04000000
-#define E1000_MDIC_OP_READ   0x08000000
-#define E1000_MDIC_READY     0x10000000
-#define E1000_MDIC_INT_EN    0x20000000
-#define E1000_MDIC_ERROR     0x40000000
-
-/* LED Control */
-#define E1000_LEDCTL_LED0_MODE_MASK  0x0000000F
-#define E1000_LEDCTL_LED0_MODE_SHIFT 0
-#define E1000_LEDCTL_LED0_IVRT       0x00000040
-#define E1000_LEDCTL_LED0_BLINK      0x00000080
-#define E1000_LEDCTL_LED1_MODE_MASK  0x00000F00
-#define E1000_LEDCTL_LED1_MODE_SHIFT 8
-#define E1000_LEDCTL_LED1_IVRT       0x00004000
-#define E1000_LEDCTL_LED1_BLINK      0x00008000
-#define E1000_LEDCTL_LED2_MODE_MASK  0x000F0000
-#define E1000_LEDCTL_LED2_MODE_SHIFT 16
-#define E1000_LEDCTL_LED2_IVRT       0x00400000
-#define E1000_LEDCTL_LED2_BLINK      0x00800000
-#define E1000_LEDCTL_LED3_MODE_MASK  0x0F000000
-#define E1000_LEDCTL_LED3_MODE_SHIFT 24
-#define E1000_LEDCTL_LED3_IVRT       0x40000000
-#define E1000_LEDCTL_LED3_BLINK      0x80000000
-
-#define E1000_LEDCTL_MODE_LINK_10_1000  0x0
-#define E1000_LEDCTL_MODE_LINK_100_1000 0x1
-#define E1000_LEDCTL_MODE_LINK_UP       0x2
-#define E1000_LEDCTL_MODE_ACTIVITY      0x3
-#define E1000_LEDCTL_MODE_LINK_ACTIVITY 0x4
-#define E1000_LEDCTL_MODE_LINK_10       0x5
-#define E1000_LEDCTL_MODE_LINK_100      0x6
-#define E1000_LEDCTL_MODE_LINK_1000     0x7
-#define E1000_LEDCTL_MODE_PCIX_MODE     0x8
-#define E1000_LEDCTL_MODE_FULL_DUPLEX   0x9
-#define E1000_LEDCTL_MODE_COLLISION     0xA
-#define E1000_LEDCTL_MODE_BUS_SPEED     0xB
-#define E1000_LEDCTL_MODE_BUS_SIZE      0xC
-#define E1000_LEDCTL_MODE_PAUSED        0xD
-#define E1000_LEDCTL_MODE_LED_ON        0xE
-#define E1000_LEDCTL_MODE_LED_OFF       0xF
-
-/* Receive Address */
-#define E1000_RAH_AV  0x80000000       /* Receive descriptor valid */
-
-/* Interrupt Cause Read */
-#define E1000_ICR_TXDW    0x00000001   /* Transmit desc written back */
-#define E1000_ICR_TXQE    0x00000002   /* Transmit Queue empty */
-#define E1000_ICR_LSC     0x00000004   /* Link Status Change */
-#define E1000_ICR_RXSEQ   0x00000008   /* rx sequence error */
-#define E1000_ICR_RXDMT0  0x00000010   /* rx desc min. threshold (0) */
-#define E1000_ICR_RXO     0x00000040   /* rx overrun */
-#define E1000_ICR_RXT0    0x00000080   /* rx timer intr (ring 0) */
-#define E1000_ICR_MDAC    0x00000200   /* MDIO access complete */
-#define E1000_ICR_RXCFG   0x00000400   /* RX /c/ ordered set */
-#define E1000_ICR_GPI_EN0 0x00000800   /* GP Int 0 */
-#define E1000_ICR_GPI_EN1 0x00001000   /* GP Int 1 */
-#define E1000_ICR_GPI_EN2 0x00002000   /* GP Int 2 */
-#define E1000_ICR_GPI_EN3 0x00004000   /* GP Int 3 */
-#define E1000_ICR_TXD_LOW 0x00008000
-#define E1000_ICR_SRPD    0x00010000
-
-/* Interrupt Cause Set */
-#define E1000_ICS_TXDW    E1000_ICR_TXDW       /* Transmit desc written back */
-#define E1000_ICS_TXQE    E1000_ICR_TXQE       /* Transmit Queue empty */
-#define E1000_ICS_LSC     E1000_ICR_LSC        /* Link Status Change */
-#define E1000_ICS_RXSEQ   E1000_ICR_RXSEQ      /* rx sequence error */
-#define E1000_ICS_RXDMT0  E1000_ICR_RXDMT0     /* rx desc min. threshold */
-#define E1000_ICS_RXO     E1000_ICR_RXO        /* rx overrun */
-#define E1000_ICS_RXT0    E1000_ICR_RXT0       /* rx timer intr */
-#define E1000_ICS_MDAC    E1000_ICR_MDAC       /* MDIO access complete */
-#define E1000_ICS_RXCFG   E1000_ICR_RXCFG      /* RX /c/ ordered set */
-#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0    /* GP Int 0 */
-#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1    /* GP Int 1 */
-#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2    /* GP Int 2 */
-#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3    /* GP Int 3 */
-#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW
-#define E1000_ICS_SRPD    E1000_ICR_SRPD
-
-/* Interrupt Mask Set */
-#define E1000_IMS_TXDW    E1000_ICR_TXDW       /* Transmit desc written back */
-#define E1000_IMS_TXQE    E1000_ICR_TXQE       /* Transmit Queue empty */
-#define E1000_IMS_LSC     E1000_ICR_LSC        /* Link Status Change */
-#define E1000_IMS_RXSEQ   E1000_ICR_RXSEQ      /* rx sequence error */
-#define E1000_IMS_RXDMT0  E1000_ICR_RXDMT0     /* rx desc min. threshold */
-#define E1000_IMS_RXO     E1000_ICR_RXO        /* rx overrun */
-#define E1000_IMS_RXT0    E1000_ICR_RXT0       /* rx timer intr */
-#define E1000_IMS_MDAC    E1000_ICR_MDAC       /* MDIO access complete */
-#define E1000_IMS_RXCFG   E1000_ICR_RXCFG      /* RX /c/ ordered set */
-#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0    /* GP Int 0 */
-#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1    /* GP Int 1 */
-#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2    /* GP Int 2 */
-#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3    /* GP Int 3 */
-#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
-#define E1000_IMS_SRPD    E1000_ICR_SRPD
-
-/* Interrupt Mask Clear */
-#define E1000_IMC_TXDW    E1000_ICR_TXDW       /* Transmit desc written back */
-#define E1000_IMC_TXQE    E1000_ICR_TXQE       /* Transmit Queue empty */
-#define E1000_IMC_LSC     E1000_ICR_LSC        /* Link Status Change */
-#define E1000_IMC_RXSEQ   E1000_ICR_RXSEQ      /* rx sequence error */
-#define E1000_IMC_RXDMT0  E1000_ICR_RXDMT0     /* rx desc min. threshold */
-#define E1000_IMC_RXO     E1000_ICR_RXO        /* rx overrun */
-#define E1000_IMC_RXT0    E1000_ICR_RXT0       /* rx timer intr */
-#define E1000_IMC_MDAC    E1000_ICR_MDAC       /* MDIO access complete */
-#define E1000_IMC_RXCFG   E1000_ICR_RXCFG      /* RX /c/ ordered set */
-#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0    /* GP Int 0 */
-#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1    /* GP Int 1 */
-#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2    /* GP Int 2 */
-#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3    /* GP Int 3 */
-#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW
-#define E1000_IMC_SRPD    E1000_ICR_SRPD
-
-/* Receive Control */
-#define E1000_RCTL_RST          0x00000001     /* Software reset */
-#define E1000_RCTL_EN           0x00000002     /* enable */
-#define E1000_RCTL_SBP          0x00000004     /* store bad packet */
-#define E1000_RCTL_UPE          0x00000008     /* unicast promiscuous enable */
-#define E1000_RCTL_MPE          0x00000010     /* multicast promiscuous enab */
-#define E1000_RCTL_LPE          0x00000020     /* long packet enable */
-#define E1000_RCTL_LBM_NO       0x00000000     /* no loopback mode */
-#define E1000_RCTL_LBM_MAC      0x00000040     /* MAC loopback mode */
-#define E1000_RCTL_LBM_SLP      0x00000080     /* serial link loopback mode */
-#define E1000_RCTL_LBM_TCVR     0x000000C0     /* tcvr loopback mode */
-#define E1000_RCTL_RDMTS_HALF   0x00000000     /* rx desc min threshold size */
-#define E1000_RCTL_RDMTS_QUAT   0x00000100     /* rx desc min threshold size */
-#define E1000_RCTL_RDMTS_EIGTH  0x00000200     /* rx desc min threshold size */
-#define E1000_RCTL_MO_SHIFT     12     /* multicast offset shift */
-#define E1000_RCTL_MO_0         0x00000000     /* multicast offset 11:0 */
-#define E1000_RCTL_MO_1         0x00001000     /* multicast offset 12:1 */
-#define E1000_RCTL_MO_2         0x00002000     /* multicast offset 13:2 */
-#define E1000_RCTL_MO_3         0x00003000     /* multicast offset 15:4 */
-#define E1000_RCTL_MDR          0x00004000     /* multicast desc ring 0 */
-#define E1000_RCTL_BAM          0x00008000     /* broadcast enable */
-/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
-#define E1000_RCTL_SZ_2048      0x00000000     /* rx buffer size 2048 */
-#define E1000_RCTL_SZ_1024      0x00010000     /* rx buffer size 1024 */
-#define E1000_RCTL_SZ_512       0x00020000     /* rx buffer size 512 */
-#define E1000_RCTL_SZ_256       0x00030000     /* rx buffer size 256 */
-/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
-#define E1000_RCTL_SZ_16384     0x00010000     /* rx buffer size 16384 */
-#define E1000_RCTL_SZ_8192      0x00020000     /* rx buffer size 8192 */
-#define E1000_RCTL_SZ_4096      0x00030000     /* rx buffer size 4096 */
-#define E1000_RCTL_VFE          0x00040000     /* vlan filter enable */
-#define E1000_RCTL_CFIEN        0x00080000     /* canonical form enable */
-#define E1000_RCTL_CFI          0x00100000     /* canonical form indicator */
-#define E1000_RCTL_DPF          0x00400000     /* discard pause frames */
-#define E1000_RCTL_PMCF         0x00800000     /* pass MAC control frames */
-#define E1000_RCTL_BSEX         0x02000000     /* Buffer size extension */
-
-/* Receive Descriptor */
-#define E1000_RDT_DELAY 0x0000ffff     /* Delay timer (1=1024us) */
-#define E1000_RDT_FPDB  0x80000000     /* Flush descriptor block */
-#define E1000_RDLEN_LEN 0x0007ff80     /* descriptor length */
-#define E1000_RDH_RDH   0x0000ffff     /* receive descriptor head */
-#define E1000_RDT_RDT   0x0000ffff     /* receive descriptor tail */
-
-/* Flow Control */
-#define E1000_FCRTH_RTH  0x0000FFF8    /* Mask Bits[15:3] for RTH */
-#define E1000_FCRTH_XFCE 0x80000000    /* External Flow Control Enable */
-#define E1000_FCRTL_RTL  0x0000FFF8    /* Mask Bits[15:3] for RTL */
-#define E1000_FCRTL_XONE 0x80000000    /* Enable XON frame transmission */
-
-/* Receive Descriptor Control */
-#define E1000_RXDCTL_PTHRESH 0x0000003F        /* RXDCTL Prefetch Threshold */
-#define E1000_RXDCTL_HTHRESH 0x00003F00        /* RXDCTL Host Threshold */
-#define E1000_RXDCTL_WTHRESH 0x003F0000        /* RXDCTL Writeback Threshold */
-#define E1000_RXDCTL_GRAN    0x01000000        /* RXDCTL Granularity */
-
-/* Transmit Descriptor Control */
-#define E1000_TXDCTL_PTHRESH 0x000000FF        /* TXDCTL Prefetch Threshold */
-#define E1000_TXDCTL_HTHRESH 0x0000FF00        /* TXDCTL Host Threshold */
-#define E1000_TXDCTL_WTHRESH 0x00FF0000        /* TXDCTL Writeback Threshold */
-#define E1000_TXDCTL_GRAN    0x01000000        /* TXDCTL Granularity */
-#define E1000_TXDCTL_LWTHRESH 0xFE000000       /* TXDCTL Low Threshold */
-#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000        /* GRAN=1, WTHRESH=1 */
-
-/* Transmit Configuration Word */
-#define E1000_TXCW_FD         0x00000020       /* TXCW full duplex */
-#define E1000_TXCW_HD         0x00000040       /* TXCW half duplex */
-#define E1000_TXCW_PAUSE      0x00000080       /* TXCW sym pause request */
-#define E1000_TXCW_ASM_DIR    0x00000100       /* TXCW astm pause direction */
-#define E1000_TXCW_PAUSE_MASK 0x00000180       /* TXCW pause request mask */
-#define E1000_TXCW_RF         0x00003000       /* TXCW remote fault */
-#define E1000_TXCW_NP         0x00008000       /* TXCW next page */
-#define E1000_TXCW_CW         0x0000ffff       /* TxConfigWord mask */
-#define E1000_TXCW_TXC        0x40000000       /* Transmit Config control */
-#define E1000_TXCW_ANE        0x80000000       /* Auto-neg enable */
-
-/* Receive Configuration Word */
-#define E1000_RXCW_CW    0x0000ffff    /* RxConfigWord mask */
-#define E1000_RXCW_NC    0x04000000    /* Receive config no carrier */
-#define E1000_RXCW_IV    0x08000000    /* Receive config invalid */
-#define E1000_RXCW_CC    0x10000000    /* Receive config change */
-#define E1000_RXCW_C     0x20000000    /* Receive config */
-#define E1000_RXCW_SYNCH 0x40000000    /* Receive config synch */
-#define E1000_RXCW_ANC   0x80000000    /* Auto-neg complete */
-
-/* Transmit Control */
-#define E1000_TCTL_RST    0x00000001   /* software reset */
-#define E1000_TCTL_EN     0x00000002   /* enable tx */
-#define E1000_TCTL_BCE    0x00000004   /* busy check enable */
-#define E1000_TCTL_PSP    0x00000008   /* pad short packets */
-#define E1000_TCTL_CT     0x00000ff0   /* collision threshold */
-#define E1000_TCTL_COLD   0x003ff000   /* collision distance */
-#define E1000_TCTL_SWXOFF 0x00400000   /* SW Xoff transmission */
-#define E1000_TCTL_PBE    0x00800000   /* Packet Burst Enable */
-#define E1000_TCTL_RTLC   0x01000000   /* Re-transmit on late collision */
-#define E1000_TCTL_NRTU   0x02000000   /* No Re-transmit on underrun */
-
-/* Receive Checksum Control */
-#define E1000_RXCSUM_PCSS_MASK 0x000000FF      /* Packet Checksum Start */
-#define E1000_RXCSUM_IPOFL     0x00000100      /* IPv4 checksum offload */
-#define E1000_RXCSUM_TUOFL     0x00000200      /* TCP / UDP checksum offload */
-#define E1000_RXCSUM_IPV6OFL   0x00000400      /* IPv6 checksum offload */
-
-/* Definitions for power management and wakeup registers */
-/* Wake Up Control */
-#define E1000_WUC_APME       0x00000001        /* APM Enable */
-#define E1000_WUC_PME_EN     0x00000002        /* PME Enable */
-#define E1000_WUC_PME_STATUS 0x00000004        /* PME Status */
-#define E1000_WUC_APMPME     0x00000008        /* Assert PME on APM Wakeup */
-
-/* Wake Up Filter Control */
-#define E1000_WUFC_LNKC 0x00000001     /* Link Status Change Wakeup Enable */
-#define E1000_WUFC_MAG  0x00000002     /* Magic Packet Wakeup Enable */
-#define E1000_WUFC_EX   0x00000004     /* Directed Exact Wakeup Enable */
-#define E1000_WUFC_MC   0x00000008     /* Directed Multicast Wakeup Enable */
-#define E1000_WUFC_BC   0x00000010     /* Broadcast Wakeup Enable */
-#define E1000_WUFC_ARP  0x00000020     /* ARP Request Packet Wakeup Enable */
-#define E1000_WUFC_IPV4 0x00000040     /* Directed IPv4 Packet Wakeup Enable */
-#define E1000_WUFC_IPV6 0x00000080     /* Directed IPv6 Packet Wakeup Enable */
-#define E1000_WUFC_FLX0 0x00010000     /* Flexible Filter 0 Enable */
-#define E1000_WUFC_FLX1 0x00020000     /* Flexible Filter 1 Enable */
-#define E1000_WUFC_FLX2 0x00040000     /* Flexible Filter 2 Enable */
-#define E1000_WUFC_FLX3 0x00080000     /* Flexible Filter 3 Enable */
-#define E1000_WUFC_ALL_FILTERS 0x000F00FF      /* Mask for all wakeup filters */
-#define E1000_WUFC_FLX_OFFSET 16       /* Offset to the Flexible Filters bits */
-#define E1000_WUFC_FLX_FILTERS 0x000F0000      /* Mask for the 4 flexible filters */
-
-/* Wake Up Status */
-#define E1000_WUS_LNKC 0x00000001      /* Link Status Changed */
-#define E1000_WUS_MAG  0x00000002      /* Magic Packet Received */
-#define E1000_WUS_EX   0x00000004      /* Directed Exact Received */
-#define E1000_WUS_MC   0x00000008      /* Directed Multicast Received */
-#define E1000_WUS_BC   0x00000010      /* Broadcast Received */
-#define E1000_WUS_ARP  0x00000020      /* ARP Request Packet Received */
-#define E1000_WUS_IPV4 0x00000040      /* Directed IPv4 Packet Wakeup Received */
-#define E1000_WUS_IPV6 0x00000080      /* Directed IPv6 Packet Wakeup Received */
-#define E1000_WUS_FLX0 0x00010000      /* Flexible Filter 0 Match */
-#define E1000_WUS_FLX1 0x00020000      /* Flexible Filter 1 Match */
-#define E1000_WUS_FLX2 0x00040000      /* Flexible Filter 2 Match */
-#define E1000_WUS_FLX3 0x00080000      /* Flexible Filter 3 Match */
-#define E1000_WUS_FLX_FILTERS 0x000F0000       /* Mask for the 4 flexible filters */
-
-/* Management Control */
-#define E1000_MANC_SMBUS_EN      0x00000001    /* SMBus Enabled - RO */
-#define E1000_MANC_ASF_EN        0x00000002    /* ASF Enabled - RO */
-#define E1000_MANC_R_ON_FORCE    0x00000004    /* Reset on Force TCO - RO */
-#define E1000_MANC_RMCP_EN       0x00000100    /* Enable RCMP 026Fh Filtering */
-#define E1000_MANC_0298_EN       0x00000200    /* Enable RCMP 0298h Filtering */
-#define E1000_MANC_IPV4_EN       0x00000400    /* Enable IPv4 */
-#define E1000_MANC_IPV6_EN       0x00000800    /* Enable IPv6 */
-#define E1000_MANC_SNAP_EN       0x00001000    /* Accept LLC/SNAP */
-#define E1000_MANC_ARP_EN        0x00002000    /* Enable ARP Request Filtering */
-#define E1000_MANC_NEIGHBOR_EN   0x00004000    /* Enable Neighbor Discovery
-                                                * Filtering */
-#define E1000_MANC_TCO_RESET     0x00010000    /* TCO Reset Occurred */
-#define E1000_MANC_RCV_TCO_EN    0x00020000    /* Receive TCO Packets Enabled */
-#define E1000_MANC_REPORT_STATUS 0x00040000    /* Status Reporting Enabled */
-#define E1000_MANC_SMB_REQ       0x01000000    /* SMBus Request */
-#define E1000_MANC_SMB_GNT       0x02000000    /* SMBus Grant */
-#define E1000_MANC_SMB_CLK_IN    0x04000000    /* SMBus Clock In */
-#define E1000_MANC_SMB_DATA_IN   0x08000000    /* SMBus Data In */
-#define E1000_MANC_SMB_DATA_OUT  0x10000000    /* SMBus Data Out */
-#define E1000_MANC_SMB_CLK_OUT   0x20000000    /* SMBus Clock Out */
-
-#define E1000_MANC_SMB_DATA_OUT_SHIFT  28      /* SMBus Data Out Shift */
-#define E1000_MANC_SMB_CLK_OUT_SHIFT   29      /* SMBus Clock Out Shift */
-
-/* Wake Up Packet Length */
-#define E1000_WUPL_LENGTH_MASK 0x0FFF  /* Only the lower 12 bits are valid */
-
-#define E1000_MDALIGN          4096
-
-/* EEPROM Commands */
-#define EEPROM_READ_OPCODE  0x6        /* EERPOM read opcode */
-#define EEPROM_WRITE_OPCODE 0x5        /* EERPOM write opcode */
-#define EEPROM_ERASE_OPCODE 0x7        /* EERPOM erase opcode */
-#define EEPROM_EWEN_OPCODE  0x13       /* EERPOM erase/write enable */
-#define EEPROM_EWDS_OPCODE  0x10       /* EERPOM erast/write disable */
-
-/* EEPROM Word Offsets */
-#define EEPROM_COMPAT              0x0003
-#define EEPROM_ID_LED_SETTINGS     0x0004
-#define EEPROM_INIT_CONTROL1_REG   0x000A
-#define EEPROM_INIT_CONTROL2_REG   0x000F
-#define EEPROM_FLASH_VERSION       0x0032
-#define EEPROM_CHECKSUM_REG        0x003F
-
-/* Word definitions for ID LED Settings */
-#define ID_LED_RESERVED_0000 0x0000
-#define ID_LED_RESERVED_FFFF 0xFFFF
-#define ID_LED_DEFAULT       ((ID_LED_OFF1_ON2 << 12) | \
-                             (ID_LED_OFF1_OFF2 << 8) | \
-                             (ID_LED_DEF1_DEF2 << 4) | \
-                             (ID_LED_DEF1_DEF2))
-#define ID_LED_DEF1_DEF2     0x1
-#define ID_LED_DEF1_ON2      0x2
-#define ID_LED_DEF1_OFF2     0x3
-#define ID_LED_ON1_DEF2      0x4
-#define ID_LED_ON1_ON2       0x5
-#define ID_LED_ON1_OFF2      0x6
-#define ID_LED_OFF1_DEF2     0x7
-#define ID_LED_OFF1_ON2      0x8
-#define ID_LED_OFF1_OFF2     0x9
-
-/* Mask bits for fields in Word 0x03 of the EEPROM */
-#define EEPROM_COMPAT_SERVER 0x0400
-#define EEPROM_COMPAT_CLIENT 0x0200
-
-/* Mask bits for fields in Word 0x0a of the EEPROM */
-#define EEPROM_WORD0A_ILOS   0x0010
-#define EEPROM_WORD0A_SWDPIO 0x01E0
-#define EEPROM_WORD0A_LRST   0x0200
-#define EEPROM_WORD0A_FD     0x0400
-#define EEPROM_WORD0A_66MHZ  0x0800
-
-/* Mask bits for fields in Word 0x0f of the EEPROM */
-#define EEPROM_WORD0F_PAUSE_MASK 0x3000
-#define EEPROM_WORD0F_PAUSE      0x1000
-#define EEPROM_WORD0F_ASM_DIR    0x2000
-#define EEPROM_WORD0F_ANE        0x0800
-#define EEPROM_WORD0F_SWPDIO_EXT 0x00F0
-
-/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */
-#define EEPROM_SUM 0xBABA
-
-/* EEPROM Map defines (WORD OFFSETS)*/
-#define EEPROM_NODE_ADDRESS_BYTE_0 0
-#define EEPROM_PBA_BYTE_1          8
-
-/* EEPROM Map Sizes (Byte Counts) */
-#define PBA_SIZE 4
-
-/* Collision related configuration parameters */
-#define E1000_COLLISION_THRESHOLD       16
-#define E1000_CT_SHIFT                  4
-#define E1000_COLLISION_DISTANCE        64
-#define E1000_FDX_COLLISION_DISTANCE    E1000_COLLISION_DISTANCE
-#define E1000_HDX_COLLISION_DISTANCE    E1000_COLLISION_DISTANCE
-#define E1000_GB_HDX_COLLISION_DISTANCE 512
-#define E1000_COLD_SHIFT                12
-
-/* The number of Transmit and Receive Descriptors must be a multiple of 8 */
-#define REQ_TX_DESCRIPTOR_MULTIPLE  8
-#define REQ_RX_DESCRIPTOR_MULTIPLE  8
-
-/* Default values for the transmit IPG register */
-#define DEFAULT_82542_TIPG_IPGT        10
-#define DEFAULT_82543_TIPG_IPGT_FIBER  9
-#define DEFAULT_82543_TIPG_IPGT_COPPER 8
-
-#define E1000_TIPG_IPGT_MASK  0x000003FF
-#define E1000_TIPG_IPGR1_MASK 0x000FFC00
-#define E1000_TIPG_IPGR2_MASK 0x3FF00000
-
-#define DEFAULT_82542_TIPG_IPGR1 2
-#define DEFAULT_82543_TIPG_IPGR1 8
-#define E1000_TIPG_IPGR1_SHIFT  10
-
-#define DEFAULT_82542_TIPG_IPGR2 10
-#define DEFAULT_82543_TIPG_IPGR2 6
-#define E1000_TIPG_IPGR2_SHIFT  20
-
-#define E1000_TXDMAC_DPP 0x00000001
-
-/* Adaptive IFS defines */
-#define TX_THRESHOLD_START     8
-#define TX_THRESHOLD_INCREMENT 10
-#define TX_THRESHOLD_DECREMENT 1
-#define TX_THRESHOLD_STOP      190
-#define TX_THRESHOLD_DISABLE   0
-#define TX_THRESHOLD_TIMER_MS  10000
-#define MIN_NUM_XMITS          1000
-#define IFS_MAX                80
-#define IFS_STEP               10
-#define IFS_MIN                40
-#define IFS_RATIO              4
-
-/* PBA constants */
-#define E1000_PBA_16K 0x0010   /* 16KB, default TX allocation */
-#define E1000_PBA_24K 0x0018
-#define E1000_PBA_40K 0x0028
-#define E1000_PBA_48K 0x0030   /* 48KB, default RX allocation */
-
-/* Flow Control Constants */
-#define FLOW_CONTROL_ADDRESS_LOW  0x00C28001
-#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100
-#define FLOW_CONTROL_TYPE         0x8808
-
-/* The historical defaults for the flow control values are given below. */
-#define FC_DEFAULT_HI_THRESH        (0x8000)   /* 32KB */
-#define FC_DEFAULT_LO_THRESH        (0x4000)   /* 16KB */
-#define FC_DEFAULT_TX_TIMER         (0x100)    /* ~130 us */
-
-/* Flow Control High-Watermark: 43464 bytes */
-#define E1000_FC_HIGH_THRESH 0xA9C8
-/* Flow Control Low-Watermark: 43456 bytes */
-#define E1000_FC_LOW_THRESH 0xA9C0
-/* Flow Control Pause Time: 858 usec */
-#define E1000_FC_PAUSE_TIME 0x0680
-
-/* PCIX Config space */
-#define PCIX_COMMAND_REGISTER    0xE6
-#define PCIX_STATUS_REGISTER_LO  0xE8
-#define PCIX_STATUS_REGISTER_HI  0xEA
-
-#define PCIX_COMMAND_MMRBC_MASK      0x000C
-#define PCIX_COMMAND_MMRBC_SHIFT     0x2
-#define PCIX_STATUS_HI_MMRBC_MASK    0x0060
-#define PCIX_STATUS_HI_MMRBC_SHIFT   0x5
-#define PCIX_STATUS_HI_MMRBC_4K      0x3
-#define PCIX_STATUS_HI_MMRBC_2K      0x2
-
-/* The number of bits that we need to shift right to move the "pause"
- * bits from the EEPROM (bits 13:12) to the "pause" (bits 8:7) field
- * in the TXCW register
- */
-#define PAUSE_SHIFT 5
-
-/* The number of bits that we need to shift left to move the "SWDPIO"
- * bits from the EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field
- * in the CTRL register
- */
-#define SWDPIO_SHIFT 17
-
-/* The number of bits that we need to shift left to move the "SWDPIO_EXT"
- * bits from the EEPROM word F (bits 7:4) to the bits 11:8 of The
- * Extended CTRL register.
- * in the CTRL register
- */
-#define SWDPIO__EXT_SHIFT 4
-
-/* The number of bits that we need to shift left to move the "ILOS"
- * bit from the EEPROM (bit 4) to the "ILOS" (bit 7) field
- * in the CTRL register
- */
-#define ILOS_SHIFT  3
-
-#define RECEIVE_BUFFER_ALIGN_SIZE  (256)
-
-/* The number of milliseconds we wait for auto-negotiation to complete */
-#define LINK_UP_TIMEOUT             500
-
-#define E1000_TX_BUFFER_SIZE ((uint32_t)1514)
-
-/* The carrier extension symbol, as received by the NIC. */
-#define CARRIER_EXTENSION   0x0F
-
-/* TBI_ACCEPT macro definition:
- *
- * This macro requires:
- *      adapter = a pointer to struct e1000_hw
- *      status = the 8 bit status field of the RX descriptor with EOP set
- *      error = the 8 bit error field of the RX descriptor with EOP set
- *      length = the sum of all the length fields of the RX descriptors that
- *               make up the current frame
- *      last_byte = the last byte of the frame DMAed by the hardware
- *      max_frame_length = the maximum frame length we want to accept.
- *      min_frame_length = the minimum frame length we want to accept.
- *
- * This macro is a conditional that should be used in the interrupt
- * handler's Rx processing routine when RxErrors have been detected.
- *
- * Typical use:
- *  ...
- *  if (TBI_ACCEPT) {
- *      accept_frame = TRUE;
- *      e1000_tbi_adjust_stats(adapter, MacAddress);
- *      frame_length--;
- *  } else {
- *      accept_frame = FALSE;
- *  }
- *  ...
- */
-
-#define TBI_ACCEPT(adapter, status, errors, length, last_byte) \
-    ((adapter)->tbi_compatibility_on && \
-     (((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \
-     ((last_byte) == CARRIER_EXTENSION) && \
-     (((status) & E1000_RXD_STAT_VP) ? \
-         (((length) > ((adapter)->min_frame_size - VLAN_TAG_SIZE)) && \
-          ((length) <= ((adapter)->max_frame_size + 1))) : \
-         (((length) > (adapter)->min_frame_size) && \
-          ((length) <= ((adapter)->max_frame_size + VLAN_TAG_SIZE + 1)))))
-
-/* Structures, enums, and macros for the PHY */
-
-/* Bit definitions for the Management Data IO (MDIO) and Management Data
- * Clock (MDC) pins in the Device Control Register.
- */
-#define E1000_CTRL_PHY_RESET_DIR  E1000_CTRL_SWDPIO0
-#define E1000_CTRL_PHY_RESET      E1000_CTRL_SWDPIN0
-#define E1000_CTRL_MDIO_DIR       E1000_CTRL_SWDPIO2
-#define E1000_CTRL_MDIO           E1000_CTRL_SWDPIN2
-#define E1000_CTRL_MDC_DIR        E1000_CTRL_SWDPIO3
-#define E1000_CTRL_MDC            E1000_CTRL_SWDPIN3
-#define E1000_CTRL_PHY_RESET_DIR4 E1000_CTRL_EXT_SDP4_DIR
-#define E1000_CTRL_PHY_RESET4     E1000_CTRL_EXT_SDP4_DATA
-
-/* PHY 1000 MII Register/Bit Definitions */
-/* PHY Registers defined by IEEE */
-#define PHY_CTRL         0x00  /* Control Register */
-#define PHY_STATUS       0x01  /* Status Regiser */
-#define PHY_ID1          0x02  /* Phy Id Reg (word 1) */
-#define PHY_ID2          0x03  /* Phy Id Reg (word 2) */
-#define PHY_AUTONEG_ADV  0x04  /* Autoneg Advertisement */
-#define PHY_LP_ABILITY   0x05  /* Link Partner Ability (Base Page) */
-#define PHY_AUTONEG_EXP  0x06  /* Autoneg Expansion Reg */
-#define PHY_NEXT_PAGE_TX 0x07  /* Next Page TX */
-#define PHY_LP_NEXT_PAGE 0x08  /* Link Partner Next Page */
-#define PHY_1000T_CTRL   0x09  /* 1000Base-T Control Reg */
-#define PHY_1000T_STATUS 0x0A  /* 1000Base-T Status Reg */
-#define PHY_EXT_STATUS   0x0F  /* Extended Status Reg */
-
-/* M88E1000 Specific Registers */
-#define M88E1000_PHY_SPEC_CTRL     0x10        /* PHY Specific Control Register */
-#define M88E1000_PHY_SPEC_STATUS   0x11        /* PHY Specific Status Register */
-#define M88E1000_INT_ENABLE        0x12        /* Interrupt Enable Register */
-#define M88E1000_INT_STATUS        0x13        /* Interrupt Status Register */
-#define M88E1000_EXT_PHY_SPEC_CTRL 0x14        /* Extended PHY Specific Control */
-#define M88E1000_RX_ERR_CNTR       0x15        /* Receive Error Counter */
-
-#define MAX_PHY_REG_ADDRESS 0x1F       /* 5 bit address bus (0-0x1F) */
-
-/* PHY Control Register */
-#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */
-#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
-#define MII_CR_FULL_DUPLEX      0x0100 /* FDX =1, half duplex =0 */
-#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
-#define MII_CR_ISOLATE          0x0400 /* Isolate PHY from MII */
-#define MII_CR_POWER_DOWN       0x0800 /* Power down */
-#define MII_CR_AUTO_NEG_EN      0x1000 /* Auto Neg Enable */
-#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */
-#define MII_CR_LOOPBACK         0x4000 /* 0 = normal, 1 = loopback */
-#define MII_CR_RESET            0x8000 /* 0 = normal, 1 = PHY reset */
-
-/* PHY Status Register */
-#define MII_SR_EXTENDED_CAPS     0x0001        /* Extended register capabilities */
-#define MII_SR_JABBER_DETECT     0x0002        /* Jabber Detected */
-#define MII_SR_LINK_STATUS       0x0004        /* Link Status 1 = link */
-#define MII_SR_AUTONEG_CAPS      0x0008        /* Auto Neg Capable */
-#define MII_SR_REMOTE_FAULT      0x0010        /* Remote Fault Detect */
-#define MII_SR_AUTONEG_COMPLETE  0x0020        /* Auto Neg Complete */
-#define MII_SR_PREAMBLE_SUPPRESS 0x0040        /* Preamble may be suppressed */
-#define MII_SR_EXTENDED_STATUS   0x0100        /* Ext. status info in Reg 0x0F */
-#define MII_SR_100T2_HD_CAPS     0x0200        /* 100T2 Half Duplex Capable */
-#define MII_SR_100T2_FD_CAPS     0x0400        /* 100T2 Full Duplex Capable */
-#define MII_SR_10T_HD_CAPS       0x0800        /* 10T   Half Duplex Capable */
-#define MII_SR_10T_FD_CAPS       0x1000        /* 10T   Full Duplex Capable */
-#define MII_SR_100X_HD_CAPS      0x2000        /* 100X  Half Duplex Capable */
-#define MII_SR_100X_FD_CAPS      0x4000        /* 100X  Full Duplex Capable */
-#define MII_SR_100T4_CAPS        0x8000        /* 100T4 Capable */
-
-/* Autoneg Advertisement Register */
-#define NWAY_AR_SELECTOR_FIELD 0x0001  /* indicates IEEE 802.3 CSMA/CD */
-#define NWAY_AR_10T_HD_CAPS    0x0020  /* 10T   Half Duplex Capable */
-#define NWAY_AR_10T_FD_CAPS    0x0040  /* 10T   Full Duplex Capable */
-#define NWAY_AR_100TX_HD_CAPS  0x0080  /* 100TX Half Duplex Capable */
-#define NWAY_AR_100TX_FD_CAPS  0x0100  /* 100TX Full Duplex Capable */
-#define NWAY_AR_100T4_CAPS     0x0200  /* 100T4 Capable */
-#define NWAY_AR_PAUSE          0x0400  /* Pause operation desired */
-#define NWAY_AR_ASM_DIR        0x0800  /* Asymmetric Pause Direction bit */
-#define NWAY_AR_REMOTE_FAULT   0x2000  /* Remote Fault detected */
-#define NWAY_AR_NEXT_PAGE      0x8000  /* Next Page ability supported */
-
-/* Link Partner Ability Register (Base Page) */
-#define NWAY_LPAR_SELECTOR_FIELD 0x0000        /* LP protocol selector field */
-#define NWAY_LPAR_10T_HD_CAPS    0x0020        /* LP is 10T   Half Duplex Capable */
-#define NWAY_LPAR_10T_FD_CAPS    0x0040        /* LP is 10T   Full Duplex Capable */
-#define NWAY_LPAR_100TX_HD_CAPS  0x0080        /* LP is 100TX Half Duplex Capable */
-#define NWAY_LPAR_100TX_FD_CAPS  0x0100        /* LP is 100TX Full Duplex Capable */
-#define NWAY_LPAR_100T4_CAPS     0x0200        /* LP is 100T4 Capable */
-#define NWAY_LPAR_PAUSE          0x0400        /* LP Pause operation desired */
-#define NWAY_LPAR_ASM_DIR        0x0800        /* LP Asymmetric Pause Direction bit */
-#define NWAY_LPAR_REMOTE_FAULT   0x2000        /* LP has detected Remote Fault */
-#define NWAY_LPAR_ACKNOWLEDGE    0x4000        /* LP has rx'd link code word */
-#define NWAY_LPAR_NEXT_PAGE      0x8000        /* Next Page ability supported */
-
-/* Autoneg Expansion Register */
-#define NWAY_ER_LP_NWAY_CAPS      0x0001       /* LP has Auto Neg Capability */
-#define NWAY_ER_PAGE_RXD          0x0002       /* LP is 10T   Half Duplex Capable */
-#define NWAY_ER_NEXT_PAGE_CAPS    0x0004       /* LP is 10T   Full Duplex Capable */
-#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008       /* LP is 100TX Half Duplex Capable */
-#define NWAY_ER_PAR_DETECT_FAULT  0x0100       /* LP is 100TX Full Duplex Capable */
-
-/* Next Page TX Register */
-#define NPTX_MSG_CODE_FIELD 0x0001     /* NP msg code or unformatted data */
-#define NPTX_TOGGLE         0x0800     /* Toggles between exchanges
-                                        * of different NP
-                                        */
-#define NPTX_ACKNOWLDGE2    0x1000     /* 1 = will comply with msg
-                                        * 0 = cannot comply with msg
-                                        */
-#define NPTX_MSG_PAGE       0x2000     /* formatted(1)/unformatted(0) pg */
-#define NPTX_NEXT_PAGE      0x8000     /* 1 = addition NP will follow
-                                        * 0 = sending last NP
-                                        */
-
-/* Link Partner Next Page Register */
-#define LP_RNPR_MSG_CODE_FIELD 0x0001  /* NP msg code or unformatted data */
-#define LP_RNPR_TOGGLE         0x0800  /* Toggles between exchanges
-                                        * of different NP
-                                        */
-#define LP_RNPR_ACKNOWLDGE2    0x1000  /* 1 = will comply with msg
-                                        * 0 = cannot comply with msg
-                                        */
-#define LP_RNPR_MSG_PAGE       0x2000  /* formatted(1)/unformatted(0) pg */
-#define LP_RNPR_ACKNOWLDGE     0x4000  /* 1 = ACK / 0 = NO ACK */
-#define LP_RNPR_NEXT_PAGE      0x8000  /* 1 = addition NP will follow
-                                        * 0 = sending last NP
-                                        */
-
-/* 1000BASE-T Control Register */
-#define CR_1000T_ASYM_PAUSE      0x0080        /* Advertise asymmetric pause bit */
-#define CR_1000T_HD_CAPS         0x0100        /* Advertise 1000T HD capability */
-#define CR_1000T_FD_CAPS         0x0200        /* Advertise 1000T FD capability  */
-#define CR_1000T_REPEATER_DTE    0x0400        /* 1=Repeater/switch device port */
-                                       /* 0=DTE device */
-#define CR_1000T_MS_VALUE        0x0800        /* 1=Configure PHY as Master */
-                                       /* 0=Configure PHY as Slave */
-#define CR_1000T_MS_ENABLE       0x1000        /* 1=Master/Slave manual config value */
-                                       /* 0=Automatic Master/Slave config */
-#define CR_1000T_TEST_MODE_NORMAL 0x0000       /* Normal Operation */
-#define CR_1000T_TEST_MODE_1     0x2000        /* Transmit Waveform test */
-#define CR_1000T_TEST_MODE_2     0x4000        /* Master Transmit Jitter test */
-#define CR_1000T_TEST_MODE_3     0x6000        /* Slave Transmit Jitter test */
-#define CR_1000T_TEST_MODE_4     0x8000        /* Transmitter Distortion test */
-
-/* 1000BASE-T Status Register */
-#define SR_1000T_IDLE_ERROR_CNT   0x00FF       /* Num idle errors since last read */
-#define SR_1000T_ASYM_PAUSE_DIR   0x0100       /* LP asymmetric pause direction bit */
-#define SR_1000T_LP_HD_CAPS       0x0400       /* LP is 1000T HD capable */
-#define SR_1000T_LP_FD_CAPS       0x0800       /* LP is 1000T FD capable */
-#define SR_1000T_REMOTE_RX_STATUS 0x1000       /* Remote receiver OK */
-#define SR_1000T_LOCAL_RX_STATUS  0x2000       /* Local receiver OK */
-#define SR_1000T_MS_CONFIG_RES    0x4000       /* 1=Local TX is Master, 0=Slave */
-#define SR_1000T_MS_CONFIG_FAULT  0x8000       /* Master/Slave config fault */
-#define SR_1000T_REMOTE_RX_STATUS_SHIFT 12
-#define SR_1000T_LOCAL_RX_STATUS_SHIFT  13
-
-/* Extended Status Register */
-#define IEEE_ESR_1000T_HD_CAPS 0x1000  /* 1000T HD capable */
-#define IEEE_ESR_1000T_FD_CAPS 0x2000  /* 1000T FD capable */
-#define IEEE_ESR_1000X_HD_CAPS 0x4000  /* 1000X HD capable */
-#define IEEE_ESR_1000X_FD_CAPS 0x8000  /* 1000X FD capable */
-
-#define PHY_TX_POLARITY_MASK   0x0100  /* register 10h bit 8 (polarity bit) */
-#define PHY_TX_NORMAL_POLARITY 0       /* register 10h bit 8 (normal polarity) */
-
-#define AUTO_POLARITY_DISABLE  0x0010  /* register 11h bit 4 */
-                                     /* (0=enable, 1=disable) */
-
-/* M88E1000 PHY Specific Control Register */
-#define M88E1000_PSCR_JABBER_DISABLE    0x0001 /* 1=Jabber Function disabled */
-#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */
-#define M88E1000_PSCR_SQE_TEST          0x0004 /* 1=SQE Test enabled */
-#define M88E1000_PSCR_CLK125_DISABLE    0x0010 /* 1=CLK125 low,
-                                                * 0=CLK125 toggling
-                                                */
-#define M88E1000_PSCR_MDI_MANUAL_MODE  0x0000  /* MDI Crossover Mode bits 6:5 */
-                                              /* Manual MDI configuration */
-#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020  /* Manual MDIX configuration */
-#define M88E1000_PSCR_AUTO_X_1000T     0x0040  /* 1000BASE-T: Auto crossover,
-                                                *  100BASE-TX/10BASE-T:
-                                                *  MDI Mode
-                                                */
-#define M88E1000_PSCR_AUTO_X_MODE      0x0060  /* Auto crossover enabled
-                                                * all speeds.
-                                                */
-#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE 0x0080
-                                       /* 1=Enable Extended 10BASE-T distance
-                                        * (Lower 10BASE-T RX Threshold)
-                                        * 0=Normal 10BASE-T RX Threshold */
-#define M88E1000_PSCR_MII_5BIT_ENABLE      0x0100
-                                       /* 1=5-Bit interface in 100BASE-TX
-                                        * 0=MII interface in 100BASE-TX */
-#define M88E1000_PSCR_SCRAMBLER_DISABLE    0x0200      /* 1=Scrambler disable */
-#define M88E1000_PSCR_FORCE_LINK_GOOD      0x0400      /* 1=Force link good */
-#define M88E1000_PSCR_ASSERT_CRS_ON_TX     0x0800      /* 1=Assert CRS on Transmit */
-
-#define M88E1000_PSCR_POLARITY_REVERSAL_SHIFT    1
-#define M88E1000_PSCR_AUTO_X_MODE_SHIFT          5
-#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7
-
-/* M88E1000 PHY Specific Status Register */
-#define M88E1000_PSSR_JABBER             0x0001        /* 1=Jabber */
-#define M88E1000_PSSR_REV_POLARITY       0x0002        /* 1=Polarity reversed */
-#define M88E1000_PSSR_MDIX               0x0040        /* 1=MDIX; 0=MDI */
-#define M88E1000_PSSR_CABLE_LENGTH       0x0380        /* 0=<50M;1=50-80M;2=80-110M;
-                                                  * 3=110-140M;4=>140M */
-#define M88E1000_PSSR_LINK               0x0400        /* 1=Link up, 0=Link down */
-#define M88E1000_PSSR_SPD_DPLX_RESOLVED  0x0800        /* 1=Speed & Duplex resolved */
-#define M88E1000_PSSR_PAGE_RCVD          0x1000        /* 1=Page received */
-#define M88E1000_PSSR_DPLX               0x2000        /* 1=Duplex 0=Half Duplex */
-#define M88E1000_PSSR_SPEED              0xC000        /* Speed, bits 14:15 */
-#define M88E1000_PSSR_10MBS              0x0000        /* 00=10Mbs */
-#define M88E1000_PSSR_100MBS             0x4000        /* 01=100Mbs */
-#define M88E1000_PSSR_1000MBS            0x8000        /* 10=1000Mbs */
-
-#define M88E1000_PSSR_REV_POLARITY_SHIFT 1
-#define M88E1000_PSSR_MDIX_SHIFT         6
-#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
-
-/* M88E1000 Extended PHY Specific Control Register */
-#define M88E1000_EPSCR_FIBER_LOOPBACK 0x4000   /* 1=Fiber loopback */
-#define M88E1000_EPSCR_DOWN_NO_IDLE   0x8000   /* 1=Lost lock detect enabled.
-                                                * Will assert lost lock and bring
-                                                * link down if idle not seen
-                                                * within 1ms in 1000BASE-T
-                                                */
-/* Number of times we will attempt to autonegotiate before downshifting if we
- * are the master */
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X   0x0000
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_2X   0x0400
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_3X   0x0800
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_4X   0x0C00
-/* Number of times we will attempt to autonegotiate before downshifting if we
- * are the slave */
-#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK  0x0300
-#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_DIS   0x0000
-#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X    0x0100
-#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_2X    0x0200
-#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_3X    0x0300
-#define M88E1000_EPSCR_TX_CLK_2_5     0x0060   /* 2.5 MHz TX_CLK */
-#define M88E1000_EPSCR_TX_CLK_25      0x0070   /* 25  MHz TX_CLK */
-#define M88E1000_EPSCR_TX_CLK_0       0x0000   /* NO  TX_CLK */
-
-/* Bit definitions for valid PHY IDs. */
-#define M88E1000_E_PHY_ID  0x01410C50
-#define M88E1000_I_PHY_ID  0x01410C30
-#define M88E1011_I_PHY_ID  0x01410C20
-#define M88E1000_12_PHY_ID M88E1000_E_PHY_ID
-#define M88E1000_14_PHY_ID M88E1000_E_PHY_ID
-
-/* Miscellaneous PHY bit definitions. */
-#define PHY_PREAMBLE        0xFFFFFFFF
-#define PHY_SOF             0x01
-#define PHY_OP_READ         0x02
-#define PHY_OP_WRITE        0x01
-#define PHY_TURNAROUND      0x02
-#define PHY_PREAMBLE_SIZE   32
-#define MII_CR_SPEED_1000   0x0040
-#define MII_CR_SPEED_100    0x2000
-#define MII_CR_SPEED_10     0x0000
-#define E1000_PHY_ADDRESS   0x01
-#define PHY_AUTO_NEG_TIME   45 /* 4.5 Seconds */
-#define PHY_FORCE_TIME      20 /* 2.0 Seconds */
-#define PHY_REVISION_MASK   0xFFFFFFF0
-#define DEVICE_SPEED_MASK   0x00000300 /* Device Ctrl Reg Speed Mask */
-#define REG4_SPEED_MASK     0x01E0
-#define REG9_SPEED_MASK     0x0300
-#define ADVERTISE_10_HALF   0x0001
-#define ADVERTISE_10_FULL   0x0002
-#define ADVERTISE_100_HALF  0x0004
-#define ADVERTISE_100_FULL  0x0008
-#define ADVERTISE_1000_HALF 0x0010
-#define ADVERTISE_1000_FULL 0x0020
-#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F /* Everything but 1000-Half */
-
-#endif                         /* _E1000_HW_H_ */
diff --git a/drivers/eepro100.c b/drivers/eepro100.c
deleted file mode 100644 (file)
index 738146e..0000000
+++ /dev/null
@@ -1,948 +0,0 @@
-/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <malloc.h>
-#include <net.h>
-#include <asm/io.h>
-#include <pci.h>
-#include <miiphy.h>
-
-#undef DEBUG
-
-#if defined(CONFIG_CMD_NET) \
-       && defined(CONFIG_NET_MULTI) && defined(CONFIG_EEPRO100)
-
-       /* Ethernet chip registers.
-        */
-#define SCBStatus              0       /* Rx/Command Unit Status *Word* */
-#define SCBIntAckByte          1       /* Rx/Command Unit STAT/ACK byte */
-#define SCBCmd                 2       /* Rx/Command Unit Command *Word* */
-#define SCBIntrCtlByte         3       /* Rx/Command Unit Intr.Control Byte */
-#define SCBPointer             4       /* General purpose pointer. */
-#define SCBPort                        8       /* Misc. commands and operands. */
-#define SCBflash               12      /* Flash memory control. */
-#define SCBeeprom              14      /* EEPROM memory control. */
-#define SCBCtrlMDI             16      /* MDI interface control. */
-#define SCBEarlyRx             20      /* Early receive byte count. */
-#define SCBGenControl          28      /* 82559 General Control Register */
-#define SCBGenStatus           29      /* 82559 General Status register */
-
-       /* 82559 SCB status word defnitions
-        */
-#define SCB_STATUS_CX          0x8000  /* CU finished command (transmit) */
-#define SCB_STATUS_FR          0x4000  /* frame received */
-#define SCB_STATUS_CNA         0x2000  /* CU left active state */
-#define SCB_STATUS_RNR         0x1000  /* receiver left ready state */
-#define SCB_STATUS_MDI         0x0800  /* MDI read/write cycle done */
-#define SCB_STATUS_SWI         0x0400  /* software generated interrupt */
-#define SCB_STATUS_FCP         0x0100  /* flow control pause interrupt */
-
-#define SCB_INTACK_MASK                0xFD00  /* all the above */
-
-#define SCB_INTACK_TX          (SCB_STATUS_CX | SCB_STATUS_CNA)
-#define SCB_INTACK_RX          (SCB_STATUS_FR | SCB_STATUS_RNR)
-
-       /* System control block commands
-        */
-/* CU Commands */
-#define CU_NOP                 0x0000
-#define CU_START               0x0010
-#define CU_RESUME              0x0020
-#define CU_STATSADDR           0x0040  /* Load Dump Statistics ctrs addr */
-#define CU_SHOWSTATS           0x0050  /* Dump statistics counters. */
-#define CU_ADDR_LOAD           0x0060  /* Base address to add to CU commands */
-#define CU_DUMPSTATS           0x0070  /* Dump then reset stats counters. */
-
-/* RUC Commands */
-#define RUC_NOP                        0x0000
-#define RUC_START              0x0001
-#define RUC_RESUME             0x0002
-#define RUC_ABORT              0x0004
-#define RUC_ADDR_LOAD          0x0006  /* (seems not to clear on acceptance) */
-#define RUC_RESUMENR           0x0007
-
-#define CU_CMD_MASK            0x00f0
-#define RU_CMD_MASK            0x0007
-
-#define SCB_M                  0x0100  /* 0 = enable interrupt, 1 = disable */
-#define SCB_SWI                        0x0200  /* 1 - cause device to interrupt */
-
-#define CU_STATUS_MASK         0x00C0
-#define RU_STATUS_MASK         0x003C
-
-#define RU_STATUS_IDLE         (0<<2)
-#define RU_STATUS_SUS          (1<<2)
-#define RU_STATUS_NORES                (2<<2)
-#define RU_STATUS_READY                (4<<2)
-#define RU_STATUS_NO_RBDS_SUS  ((1<<2)|(8<<2))
-#define RU_STATUS_NO_RBDS_NORES ((2<<2)|(8<<2))
-#define RU_STATUS_NO_RBDS_READY ((4<<2)|(8<<2))
-
-       /* 82559 Port interface commands.
-        */
-#define I82559_RESET           0x00000000      /* Software reset */
-#define I82559_SELFTEST                0x00000001      /* 82559 Selftest command */
-#define I82559_SELECTIVE_RESET 0x00000002
-#define I82559_DUMP            0x00000003
-#define I82559_DUMP_WAKEUP     0x00000007
-
-       /* 82559 Eeprom interface.
-        */
-#define EE_SHIFT_CLK           0x01    /* EEPROM shift clock. */
-#define EE_CS                  0x02    /* EEPROM chip select. */
-#define EE_DATA_WRITE          0x04    /* EEPROM chip data in. */
-#define EE_WRITE_0             0x01
-#define EE_WRITE_1             0x05
-#define EE_DATA_READ           0x08    /* EEPROM chip data out. */
-#define EE_ENB                 (0x4800 | EE_CS)
-#define EE_CMD_BITS            3
-#define EE_DATA_BITS           16
-
-       /* The EEPROM commands include the alway-set leading bit.
-        */
-#define EE_EWENB_CMD           (4 << addr_len)
-#define EE_WRITE_CMD           (5 << addr_len)
-#define EE_READ_CMD            (6 << addr_len)
-#define EE_ERASE_CMD           (7 << addr_len)
-
-       /* Receive frame descriptors.
-        */
-struct RxFD {
-       volatile u16 status;
-       volatile u16 control;
-       volatile u32 link;              /* struct RxFD * */
-       volatile u32 rx_buf_addr;       /* void * */
-       volatile u32 count;
-
-       volatile u8 data[PKTSIZE_ALIGN];
-};
-
-#define RFD_STATUS_C           0x8000  /* completion of received frame */
-#define RFD_STATUS_OK          0x2000  /* frame received with no errors */
-
-#define RFD_CONTROL_EL         0x8000  /* 1=last RFD in RFA */
-#define RFD_CONTROL_S          0x4000  /* 1=suspend RU after receiving frame */
-#define RFD_CONTROL_H          0x0010  /* 1=RFD is a header RFD */
-#define RFD_CONTROL_SF         0x0008  /* 0=simplified, 1=flexible mode */
-
-#define RFD_COUNT_MASK         0x3fff
-#define RFD_COUNT_F            0x4000
-#define RFD_COUNT_EOF          0x8000
-
-#define RFD_RX_CRC             0x0800  /* crc error */
-#define RFD_RX_ALIGNMENT       0x0400  /* alignment error */
-#define RFD_RX_RESOURCE                0x0200  /* out of space, no resources */
-#define RFD_RX_DMA_OVER                0x0100  /* DMA overrun */
-#define RFD_RX_SHORT           0x0080  /* short frame error */
-#define RFD_RX_LENGTH          0x0020
-#define RFD_RX_ERROR           0x0010  /* receive error */
-#define RFD_RX_NO_ADR_MATCH    0x0004  /* no address match */
-#define RFD_RX_IA_MATCH                0x0002  /* individual address does not match */
-#define RFD_RX_TCO             0x0001  /* TCO indication */
-
-       /* Transmit frame descriptors
-        */
-struct TxFD {                          /* Transmit frame descriptor set. */
-       volatile u16 status;
-       volatile u16 command;
-       volatile u32 link;              /* void * */
-       volatile u32 tx_desc_addr;      /* Always points to the tx_buf_addr element. */
-       volatile s32 count;
-
-       volatile u32 tx_buf_addr0;      /* void *, frame to be transmitted.  */
-       volatile s32 tx_buf_size0;      /* Length of Tx frame. */
-       volatile u32 tx_buf_addr1;      /* void *, frame to be transmitted.  */
-       volatile s32 tx_buf_size1;      /* Length of Tx frame. */
-};
-
-#define TxCB_CMD_TRANSMIT      0x0004  /* transmit command */
-#define TxCB_CMD_SF            0x0008  /* 0=simplified, 1=flexible mode */
-#define TxCB_CMD_NC            0x0010  /* 0=CRC insert by controller */
-#define TxCB_CMD_I             0x2000  /* generate interrupt on completion */
-#define TxCB_CMD_S             0x4000  /* suspend on completion */
-#define TxCB_CMD_EL            0x8000  /* last command block in CBL */
-
-#define TxCB_COUNT_MASK                0x3fff
-#define TxCB_COUNT_EOF         0x8000
-
-       /* The Speedo3 Rx and Tx frame/buffer descriptors.
-        */
-struct descriptor {                    /* A generic descriptor. */
-       volatile u16 status;
-       volatile u16 command;
-       volatile u32 link;              /* struct descriptor *  */
-
-       unsigned char params[0];
-};
-
-#define CFG_CMD_EL             0x8000
-#define CFG_CMD_SUSPEND                0x4000
-#define CFG_CMD_INT            0x2000
-#define CFG_CMD_IAS            0x0001  /* individual address setup */
-#define CFG_CMD_CONFIGURE      0x0002  /* configure */
-
-#define CFG_STATUS_C           0x8000
-#define CFG_STATUS_OK          0x2000
-
-       /* Misc.
-        */
-#define NUM_RX_DESC            PKTBUFSRX
-#define NUM_TX_DESC            1       /* Number of TX descriptors   */
-
-#define TOUT_LOOP              1000000
-
-#define ETH_ALEN               6
-
-static struct RxFD rx_ring[NUM_RX_DESC];       /* RX descriptor ring         */
-static struct TxFD tx_ring[NUM_TX_DESC];       /* TX descriptor ring         */
-static int rx_next;                    /* RX descriptor ring pointer */
-static int tx_next;                    /* TX descriptor ring pointer */
-static int tx_threshold;
-
-/*
- * The parameters for a CmdConfigure operation.
- * There are so many options that it would be difficult to document
- * each bit. We mostly use the default or recommended settings.
- */
-static const char i82557_config_cmd[] = {
-       22, 0x08, 0, 0, 0, 0, 0x32, 0x03, 1,    /* 1=Use MII  0=Use AUI */
-       0, 0x2E, 0, 0x60, 0,
-       0xf2, 0x48, 0, 0x40, 0xf2, 0x80,        /* 0x40=Force full-duplex */
-       0x3f, 0x05,
-};
-static const char i82558_config_cmd[] = {
-       22, 0x08, 0, 1, 0, 0, 0x22, 0x03, 1,    /* 1=Use MII  0=Use AUI */
-       0, 0x2E, 0, 0x60, 0x08, 0x88,
-       0x68, 0, 0x40, 0xf2, 0x84,              /* Disable FC */
-       0x31, 0x05,
-};
-
-static void init_rx_ring (struct eth_device *dev);
-static void purge_tx_ring (struct eth_device *dev);
-
-static void read_hw_addr (struct eth_device *dev, bd_t * bis);
-
-static int eepro100_init (struct eth_device *dev, bd_t * bis);
-static int eepro100_send (struct eth_device *dev, volatile void *packet,
-                                                 int length);
-static int eepro100_recv (struct eth_device *dev);
-static void eepro100_halt (struct eth_device *dev);
-
-#if defined(CONFIG_E500) || defined(CONFIG_DB64360) || defined(CONFIG_DB64460)
-#define bus_to_phys(a) (a)
-#define phys_to_bus(a) (a)
-#else
-#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a)
-#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
-#endif
-
-static inline int INW (struct eth_device *dev, u_long addr)
-{
-       return le16_to_cpu (*(volatile u16 *) (addr + dev->iobase));
-}
-
-static inline void OUTW (struct eth_device *dev, int command, u_long addr)
-{
-       *(volatile u16 *) ((addr + dev->iobase)) = cpu_to_le16 (command);
-}
-
-static inline void OUTL (struct eth_device *dev, int command, u_long addr)
-{
-       *(volatile u32 *) ((addr + dev->iobase)) = cpu_to_le32 (command);
-}
-
-#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-static inline int INL (struct eth_device *dev, u_long addr)
-{
-       return le32_to_cpu (*(volatile u32 *) (addr + dev->iobase));
-}
-
-static int get_phyreg (struct eth_device *dev, unsigned char addr,
-               unsigned char reg, unsigned short *value)
-{
-       int cmd;
-       int timeout = 50;
-
-       /* read requested data */
-       cmd = (2 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16);
-       OUTL (dev, cmd, SCBCtrlMDI);
-
-       do {
-               udelay(1000);
-               cmd = INL (dev, SCBCtrlMDI);
-       } while (!(cmd & (1 << 28)) && (--timeout));
-
-       if (timeout == 0)
-               return -1;
-
-       *value = (unsigned short) (cmd & 0xffff);
-
-       return 0;
-}
-
-static int set_phyreg (struct eth_device *dev, unsigned char addr,
-               unsigned char reg, unsigned short value)
-{
-       int cmd;
-       int timeout = 50;
-
-       /* write requested data */
-       cmd = (1 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16);
-       OUTL (dev, cmd | value, SCBCtrlMDI);
-
-       while (!(INL (dev, SCBCtrlMDI) & (1 << 28)) && (--timeout))
-               udelay(1000);
-
-       if (timeout == 0)
-               return -1;
-
-       return 0;
-}
-
-/* Check if given phyaddr is valid, i.e. there is a PHY connected.
- * Do this by checking model value field from ID2 register.
- */
-static struct eth_device* verify_phyaddr (char *devname, unsigned char addr)
-{
-       struct eth_device *dev;
-       unsigned short value;
-       unsigned char model;
-
-       dev = eth_get_dev_by_name(devname);
-       if (dev == NULL) {
-               printf("%s: no such device\n", devname);
-               return NULL;
-       }
-
-       /* read id2 register */
-       if (get_phyreg(dev, addr, PHY_PHYIDR2, &value) != 0) {
-               printf("%s: mii read timeout!\n", devname);
-               return NULL;
-       }
-
-       /* get model */
-       model = (unsigned char)((value >> 4) & 0x003f);
-
-       if (model == 0) {
-               printf("%s: no PHY at address %d\n", devname, addr);
-               return NULL;
-       }
-
-       return dev;
-}
-
-static int eepro100_miiphy_read (char *devname, unsigned char addr,
-               unsigned char reg, unsigned short *value)
-{
-       struct eth_device *dev;
-
-       dev = verify_phyaddr(devname, addr);
-       if (dev == NULL)
-               return -1;
-
-       if (get_phyreg(dev, addr, reg, value) != 0) {
-               printf("%s: mii read timeout!\n", devname);
-               return -1;
-       }
-
-       return 0;
-}
-
-static int eepro100_miiphy_write (char *devname, unsigned char addr,
-               unsigned char reg, unsigned short value)
-{
-       struct eth_device *dev;
-
-       dev = verify_phyaddr(devname, addr);
-       if (dev == NULL)
-               return -1;
-
-       if (set_phyreg(dev, addr, reg, value) != 0) {
-               printf("%s: mii write timeout!\n", devname);
-               return -1;
-       }
-
-       return 0;
-}
-
-#endif
-
-/* Wait for the chip get the command.
-*/
-static int wait_for_eepro100 (struct eth_device *dev)
-{
-       int i;
-
-       for (i = 0; INW (dev, SCBCmd) & (CU_CMD_MASK | RU_CMD_MASK); i++) {
-               if (i >= TOUT_LOOP) {
-                       return 0;
-               }
-       }
-
-       return 1;
-}
-
-static struct pci_device_id supported[] = {
-       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557},
-       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559},
-       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER},
-       {}
-};
-
-int eepro100_initialize (bd_t * bis)
-{
-       pci_dev_t devno;
-       int card_number = 0;
-       struct eth_device *dev;
-       u32 iobase, status;
-       int idx = 0;
-
-       while (1) {
-               /* Find PCI device
-                */
-               if ((devno = pci_find_devices (supported, idx++)) < 0) {
-                       break;
-               }
-
-               pci_read_config_dword (devno, PCI_BASE_ADDRESS_0, &iobase);
-               iobase &= ~0xf;
-
-#ifdef DEBUG
-               printf ("eepro100: Intel i82559 PCI EtherExpressPro @0x%x\n",
-                               iobase);
-#endif
-
-               pci_write_config_dword (devno,
-                                       PCI_COMMAND,
-                                       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
-
-               /* Check if I/O accesses and Bus Mastering are enabled.
-                */
-               pci_read_config_dword (devno, PCI_COMMAND, &status);
-               if (!(status & PCI_COMMAND_MEMORY)) {
-                       printf ("Error: Can not enable MEM access.\n");
-                       continue;
-               }
-
-               if (!(status & PCI_COMMAND_MASTER)) {
-                       printf ("Error: Can not enable Bus Mastering.\n");
-                       continue;
-               }
-
-               dev = (struct eth_device *) malloc (sizeof *dev);
-
-               sprintf (dev->name, "i82559#%d", card_number);
-               dev->priv = (void *) devno; /* this have to come before bus_to_phys() */
-               dev->iobase = bus_to_phys (iobase);
-               dev->init = eepro100_init;
-               dev->halt = eepro100_halt;
-               dev->send = eepro100_send;
-               dev->recv = eepro100_recv;
-
-               eth_register (dev);
-
-#if defined (CONFIG_MII) || defined(CONFIG_CMD_MII)
-               /* register mii command access routines */
-               miiphy_register(dev->name,
-                               eepro100_miiphy_read, eepro100_miiphy_write);
-#endif
-
-               card_number++;
-
-               /* Set the latency timer for value.
-                */
-               pci_write_config_byte (devno, PCI_LATENCY_TIMER, 0x20);
-
-               udelay (10 * 1000);
-
-               read_hw_addr (dev, bis);
-       }
-
-       return card_number;
-}
-
-
-static int eepro100_init (struct eth_device *dev, bd_t * bis)
-{
-       int i, status = 0;
-       int tx_cur;
-       struct descriptor *ias_cmd, *cfg_cmd;
-
-       /* Reset the ethernet controller
-        */
-       OUTL (dev, I82559_SELECTIVE_RESET, SCBPort);
-       udelay (20);
-
-       OUTL (dev, I82559_RESET, SCBPort);
-       udelay (20);
-
-       if (!wait_for_eepro100 (dev)) {
-               printf ("Error: Can not reset ethernet controller.\n");
-               goto Done;
-       }
-       OUTL (dev, 0, SCBPointer);
-       OUTW (dev, SCB_M | RUC_ADDR_LOAD, SCBCmd);
-
-       if (!wait_for_eepro100 (dev)) {
-               printf ("Error: Can not reset ethernet controller.\n");
-               goto Done;
-       }
-       OUTL (dev, 0, SCBPointer);
-       OUTW (dev, SCB_M | CU_ADDR_LOAD, SCBCmd);
-
-       /* Initialize Rx and Tx rings.
-        */
-       init_rx_ring (dev);
-       purge_tx_ring (dev);
-
-       /* Tell the adapter where the RX ring is located.
-        */
-       if (!wait_for_eepro100 (dev)) {
-               printf ("Error: Can not reset ethernet controller.\n");
-               goto Done;
-       }
-
-       OUTL (dev, phys_to_bus ((u32) & rx_ring[rx_next]), SCBPointer);
-       OUTW (dev, SCB_M | RUC_START, SCBCmd);
-
-       /* Send the Configure frame */
-       tx_cur = tx_next;
-       tx_next = ((tx_next + 1) % NUM_TX_DESC);
-
-       cfg_cmd = (struct descriptor *) &tx_ring[tx_cur];
-       cfg_cmd->command = cpu_to_le16 ((CFG_CMD_SUSPEND | CFG_CMD_CONFIGURE));
-       cfg_cmd->status = 0;
-       cfg_cmd->link = cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next]));
-
-       memcpy (cfg_cmd->params, i82558_config_cmd,
-                       sizeof (i82558_config_cmd));
-
-       if (!wait_for_eepro100 (dev)) {
-               printf ("Error---CFG_CMD_CONFIGURE: Can not reset ethernet controller.\n");
-               goto Done;
-       }
-
-       OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer);
-       OUTW (dev, SCB_M | CU_START, SCBCmd);
-
-       for (i = 0;
-            !(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_C);
-            i++) {
-               if (i >= TOUT_LOOP) {
-                       printf ("%s: Tx error buffer not ready\n", dev->name);
-                       goto Done;
-               }
-       }
-
-       if (!(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_OK)) {
-               printf ("TX error status = 0x%08X\n",
-                       le16_to_cpu (tx_ring[tx_cur].status));
-               goto Done;
-       }
-
-       /* Send the Individual Address Setup frame
-        */
-       tx_cur = tx_next;
-       tx_next = ((tx_next + 1) % NUM_TX_DESC);
-
-       ias_cmd = (struct descriptor *) &tx_ring[tx_cur];
-       ias_cmd->command = cpu_to_le16 ((CFG_CMD_SUSPEND | CFG_CMD_IAS));
-       ias_cmd->status = 0;
-       ias_cmd->link = cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next]));
-
-       memcpy (ias_cmd->params, dev->enetaddr, 6);
-
-       /* Tell the adapter where the TX ring is located.
-        */
-       if (!wait_for_eepro100 (dev)) {
-               printf ("Error: Can not reset ethernet controller.\n");
-               goto Done;
-       }
-
-       OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer);
-       OUTW (dev, SCB_M | CU_START, SCBCmd);
-
-       for (i = 0; !(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_C);
-                i++) {
-               if (i >= TOUT_LOOP) {
-                       printf ("%s: Tx error buffer not ready\n",
-                               dev->name);
-                       goto Done;
-               }
-       }
-
-       if (!(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_OK)) {
-               printf ("TX error status = 0x%08X\n",
-                       le16_to_cpu (tx_ring[tx_cur].status));
-               goto Done;
-       }
-
-       status = 1;
-
-  Done:
-       return status;
-}
-
-static int eepro100_send (struct eth_device *dev, volatile void *packet, int length)
-{
-       int i, status = -1;
-       int tx_cur;
-
-       if (length <= 0) {
-               printf ("%s: bad packet size: %d\n", dev->name, length);
-               goto Done;
-       }
-
-       tx_cur = tx_next;
-       tx_next = (tx_next + 1) % NUM_TX_DESC;
-
-       tx_ring[tx_cur].command = cpu_to_le16 ( TxCB_CMD_TRANSMIT |
-                                               TxCB_CMD_SF     |
-                                               TxCB_CMD_S      |
-                                               TxCB_CMD_EL );
-       tx_ring[tx_cur].status = 0;
-       tx_ring[tx_cur].count = cpu_to_le32 (tx_threshold);
-       tx_ring[tx_cur].link =
-               cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next]));
-       tx_ring[tx_cur].tx_desc_addr =
-               cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_cur].tx_buf_addr0));
-       tx_ring[tx_cur].tx_buf_addr0 =
-               cpu_to_le32 (phys_to_bus ((u_long) packet));
-       tx_ring[tx_cur].tx_buf_size0 = cpu_to_le32 (length);
-
-       if (!wait_for_eepro100 (dev)) {
-               printf ("%s: Tx error ethernet controller not ready.\n",
-                               dev->name);
-               goto Done;
-       }
-
-       /* Send the packet.
-        */
-       OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer);
-       OUTW (dev, SCB_M | CU_START, SCBCmd);
-
-       for (i = 0; !(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_C);
-                i++) {
-               if (i >= TOUT_LOOP) {
-                       printf ("%s: Tx error buffer not ready\n", dev->name);
-                       goto Done;
-               }
-       }
-
-       if (!(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_OK)) {
-               printf ("TX error status = 0x%08X\n",
-                       le16_to_cpu (tx_ring[tx_cur].status));
-               goto Done;
-       }
-
-       status = length;
-
-  Done:
-       return status;
-}
-
-static int eepro100_recv (struct eth_device *dev)
-{
-       u16 status, stat;
-       int rx_prev, length = 0;
-
-       stat = INW (dev, SCBStatus);
-       OUTW (dev, stat & SCB_STATUS_RNR, SCBStatus);
-
-       for (;;) {
-               status = le16_to_cpu (rx_ring[rx_next].status);
-
-               if (!(status & RFD_STATUS_C)) {
-                       break;
-               }
-
-               /* Valid frame status.
-                */
-               if ((status & RFD_STATUS_OK)) {
-                       /* A valid frame received.
-                        */
-                       length = le32_to_cpu (rx_ring[rx_next].count) & 0x3fff;
-
-                       /* Pass the packet up to the protocol
-                        * layers.
-                        */
-                       NetReceive (rx_ring[rx_next].data, length);
-               } else {
-                       /* There was an error.
-                        */
-                       printf ("RX error status = 0x%08X\n", status);
-               }
-
-               rx_ring[rx_next].control = cpu_to_le16 (RFD_CONTROL_S);
-               rx_ring[rx_next].status = 0;
-               rx_ring[rx_next].count = cpu_to_le32 (PKTSIZE_ALIGN << 16);
-
-               rx_prev = (rx_next + NUM_RX_DESC - 1) % NUM_RX_DESC;
-               rx_ring[rx_prev].control = 0;
-
-               /* Update entry information.
-                */
-               rx_next = (rx_next + 1) % NUM_RX_DESC;
-       }
-
-       if (stat & SCB_STATUS_RNR) {
-
-               printf ("%s: Receiver is not ready, restart it !\n", dev->name);
-
-               /* Reinitialize Rx ring.
-                */
-               init_rx_ring (dev);
-
-               if (!wait_for_eepro100 (dev)) {
-                       printf ("Error: Can not restart ethernet controller.\n");
-                       goto Done;
-               }
-
-               OUTL (dev, phys_to_bus ((u32) & rx_ring[rx_next]), SCBPointer);
-               OUTW (dev, SCB_M | RUC_START, SCBCmd);
-       }
-
-  Done:
-       return length;
-}
-
-static void eepro100_halt (struct eth_device *dev)
-{
-       /* Reset the ethernet controller
-        */
-       OUTL (dev, I82559_SELECTIVE_RESET, SCBPort);
-       udelay (20);
-
-       OUTL (dev, I82559_RESET, SCBPort);
-       udelay (20);
-
-       if (!wait_for_eepro100 (dev)) {
-               printf ("Error: Can not reset ethernet controller.\n");
-               goto Done;
-       }
-       OUTL (dev, 0, SCBPointer);
-       OUTW (dev, SCB_M | RUC_ADDR_LOAD, SCBCmd);
-
-       if (!wait_for_eepro100 (dev)) {
-               printf ("Error: Can not reset ethernet controller.\n");
-               goto Done;
-       }
-       OUTL (dev, 0, SCBPointer);
-       OUTW (dev, SCB_M | CU_ADDR_LOAD, SCBCmd);
-
-  Done:
-       return;
-}
-
-       /* SROM Read.
-        */
-static int read_eeprom (struct eth_device *dev, int location, int addr_len)
-{
-       unsigned short retval = 0;
-       int read_cmd = location | EE_READ_CMD;
-       int i;
-
-       OUTW (dev, EE_ENB & ~EE_CS, SCBeeprom);
-       OUTW (dev, EE_ENB, SCBeeprom);
-
-       /* Shift the read command bits out. */
-       for (i = 12; i >= 0; i--) {
-               short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
-
-               OUTW (dev, EE_ENB | dataval, SCBeeprom);
-               udelay (1);
-               OUTW (dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);
-               udelay (1);
-       }
-       OUTW (dev, EE_ENB, SCBeeprom);
-
-       for (i = 15; i >= 0; i--) {
-               OUTW (dev, EE_ENB | EE_SHIFT_CLK, SCBeeprom);
-               udelay (1);
-               retval = (retval << 1) |
-                               ((INW (dev, SCBeeprom) & EE_DATA_READ) ? 1 : 0);
-               OUTW (dev, EE_ENB, SCBeeprom);
-               udelay (1);
-       }
-
-       /* Terminate the EEPROM access. */
-       OUTW (dev, EE_ENB & ~EE_CS, SCBeeprom);
-       return retval;
-}
-
-#ifdef CONFIG_EEPRO100_SROM_WRITE
-int eepro100_write_eeprom (struct eth_device* dev, int location, int addr_len, unsigned short data)
-{
-    unsigned short dataval;
-    int enable_cmd = 0x3f | EE_EWENB_CMD;
-    int write_cmd  = location | EE_WRITE_CMD;
-    int i;
-    unsigned long datalong, tmplong;
-
-    OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom);
-    udelay(1);
-    OUTW(dev, EE_ENB, SCBeeprom);
-
-    /* Shift the enable command bits out. */
-    for (i = (addr_len+EE_CMD_BITS-1); i >= 0; i--)
-    {
-       dataval = (enable_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
-       OUTW(dev, EE_ENB | dataval, SCBeeprom);
-       udelay(1);
-       OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);
-       udelay(1);
-    }
-
-    OUTW(dev, EE_ENB, SCBeeprom);
-    udelay(1);
-    OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom);
-    udelay(1);
-    OUTW(dev, EE_ENB, SCBeeprom);
-
-
-    /* Shift the write command bits out. */
-    for (i = (addr_len+EE_CMD_BITS-1); i >= 0; i--)
-    {
-       dataval = (write_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
-       OUTW(dev, EE_ENB | dataval, SCBeeprom);
-       udelay(1);
-       OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);
-       udelay(1);
-    }
-
-    /* Write the data */
-    datalong= (unsigned long) ((((data) & 0x00ff) << 8) | ( (data) >> 8));
-
-    for (i = 0; i< EE_DATA_BITS; i++)
-    {
-    /* Extract and move data bit to bit DI */
-    dataval = ((datalong & 0x8000)>>13) ? EE_DATA_WRITE : 0;
-
-    OUTW(dev, EE_ENB | dataval, SCBeeprom);
-    udelay(1);
-    OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);
-    udelay(1);
-    OUTW(dev, EE_ENB | dataval, SCBeeprom);
-    udelay(1);
-
-    datalong = datalong << 1;  /* Adjust significant data bit*/
-    }
-
-    /* Finish up command  (toggle CS) */
-    OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom);
-    udelay(1);                 /* delay for more than 250 ns */
-    OUTW(dev, EE_ENB, SCBeeprom);
-
-    /* Wait for programming ready (D0 = 1) */
-    tmplong = 10;
-    do
-    {
-       dataval = INW(dev, SCBeeprom);
-       if (dataval & EE_DATA_READ)
-           break;
-       udelay(10000);
-    }
-    while (-- tmplong);
-
-    if (tmplong == 0)
-    {
-       printf ("Write i82559 eeprom timed out (100 ms waiting for data ready.\n");
-       return -1;
-    }
-
-    /* Terminate the EEPROM access. */
-    OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom);
-
-    return 0;
-}
-#endif
-
-static void init_rx_ring (struct eth_device *dev)
-{
-       int i;
-
-       for (i = 0; i < NUM_RX_DESC; i++) {
-               rx_ring[i].status = 0;
-               rx_ring[i].control =
-                               (i == NUM_RX_DESC - 1) ? cpu_to_le16 (RFD_CONTROL_S) : 0;
-               rx_ring[i].link =
-                               cpu_to_le32 (phys_to_bus
-                                                        ((u32) & rx_ring[(i + 1) % NUM_RX_DESC]));
-               rx_ring[i].rx_buf_addr = 0xffffffff;
-               rx_ring[i].count = cpu_to_le32 (PKTSIZE_ALIGN << 16);
-       }
-
-       rx_next = 0;
-}
-
-static void purge_tx_ring (struct eth_device *dev)
-{
-       int i;
-
-       tx_next = 0;
-       tx_threshold = 0x01208000;
-
-       for (i = 0; i < NUM_TX_DESC; i++) {
-               tx_ring[i].status = 0;
-               tx_ring[i].command = 0;
-               tx_ring[i].link = 0;
-               tx_ring[i].tx_desc_addr = 0;
-               tx_ring[i].count = 0;
-
-               tx_ring[i].tx_buf_addr0 = 0;
-               tx_ring[i].tx_buf_size0 = 0;
-               tx_ring[i].tx_buf_addr1 = 0;
-               tx_ring[i].tx_buf_size1 = 0;
-       }
-}
-
-static void read_hw_addr (struct eth_device *dev, bd_t * bis)
-{
-       u16 eeprom[0x40];
-       u16 sum = 0;
-       int i, j;
-       int addr_len = read_eeprom (dev, 0, 6) == 0xffff ? 8 : 6;
-
-       for (j = 0, i = 0; i < 0x40; i++) {
-               u16 value = read_eeprom (dev, i, addr_len);
-
-               eeprom[i] = value;
-               sum += value;
-               if (i < 3) {
-                       dev->enetaddr[j++] = value;
-                       dev->enetaddr[j++] = value >> 8;
-               }
-       }
-
-       if (sum != 0xBABA) {
-               memset (dev->enetaddr, 0, ETH_ALEN);
-#ifdef DEBUG
-               printf ("%s: Invalid EEPROM checksum %#4.4x, "
-                       "check settings before activating this device!\n",
-                       dev->name, sum);
-#endif
-       }
-}
-
-#endif
diff --git a/drivers/enc28j60.c b/drivers/enc28j60.c
deleted file mode 100644 (file)
index 98303ac..0000000
+++ /dev/null
@@ -1,983 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <config.h>
-#include <common.h>
-#ifdef CONFIG_ENC28J60
-#include <net.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/spi.h>
-
-/*
- * Control Registers in Bank 0
- */
-
-#define CTL_REG_ERDPTL  0x00
-#define CTL_REG_ERDPTH  0x01
-#define CTL_REG_EWRPTL  0x02
-#define CTL_REG_EWRPTH  0x03
-#define CTL_REG_ETXSTL  0x04
-#define CTL_REG_ETXSTH  0x05
-#define CTL_REG_ETXNDL  0x06
-#define CTL_REG_ETXNDH  0x07
-#define CTL_REG_ERXSTL  0x08
-#define CTL_REG_ERXSTH  0x09
-#define CTL_REG_ERXNDL  0x0A
-#define CTL_REG_ERXNDH  0x0B
-#define CTL_REG_ERXRDPTL 0x0C
-#define CTL_REG_ERXRDPTH 0x0D
-#define CTL_REG_ERXWRPTL 0x0E
-#define CTL_REG_ERXWRPTH 0x0F
-#define CTL_REG_EDMASTL  0x10
-#define CTL_REG_EDMASTH  0x11
-#define CTL_REG_EDMANDL  0x12
-#define CTL_REG_EDMANDH  0x13
-#define CTL_REG_EDMADSTL 0x14
-#define CTL_REG_EDMADSTH 0x15
-#define CTL_REG_EDMACSL  0x16
-#define CTL_REG_EDMACSH  0x17
-/* these are common in all banks */
-#define CTL_REG_EIE     0x1B
-#define CTL_REG_EIR     0x1C
-#define CTL_REG_ESTAT   0x1D
-#define CTL_REG_ECON2   0x1E
-#define CTL_REG_ECON1   0x1F
-
-/*
- * Control Registers in Bank 1
- */
-
-#define CTL_REG_EHT0   0x00
-#define CTL_REG_EHT1   0x01
-#define CTL_REG_EHT2   0x02
-#define CTL_REG_EHT3   0x03
-#define CTL_REG_EHT4   0x04
-#define CTL_REG_EHT5   0x05
-#define CTL_REG_EHT6   0x06
-#define CTL_REG_EHT7   0x07
-#define CTL_REG_EPMM0  0x08
-#define CTL_REG_EPMM1  0x09
-#define CTL_REG_EPMM2  0x0A
-#define CTL_REG_EPMM3  0x0B
-#define CTL_REG_EPMM4  0x0C
-#define CTL_REG_EPMM5  0x0D
-#define CTL_REG_EPMM6  0x0E
-#define CTL_REG_EPMM7  0x0F
-#define CTL_REG_EPMCSL 0x10
-#define CTL_REG_EPMCSH 0x11
-#define CTL_REG_EPMOL  0x14
-#define CTL_REG_EPMOH  0x15
-#define CTL_REG_EWOLIE 0x16
-#define CTL_REG_EWOLIR 0x17
-#define CTL_REG_ERXFCON 0x18
-#define CTL_REG_EPKTCNT 0x19
-
-/*
- * Control Registers in Bank 2
- */
-
-#define CTL_REG_MACON1  0x00
-#define CTL_REG_MACON2  0x01
-#define CTL_REG_MACON3  0x02
-#define CTL_REG_MACON4  0x03
-#define CTL_REG_MABBIPG  0x04
-#define CTL_REG_MAIPGL  0x06
-#define CTL_REG_MAIPGH  0x07
-#define CTL_REG_MACLCON1 0x08
-#define CTL_REG_MACLCON2 0x09
-#define CTL_REG_MAMXFLL  0x0A
-#define CTL_REG_MAMXFLH  0x0B
-#define CTL_REG_MAPHSUP  0x0D
-#define CTL_REG_MICON   0x11
-#define CTL_REG_MICMD   0x12
-#define CTL_REG_MIREGADR 0x14
-#define CTL_REG_MIWRL   0x16
-#define CTL_REG_MIWRH   0x17
-#define CTL_REG_MIRDL   0x18
-#define CTL_REG_MIRDH   0x19
-
-/*
- * Control Registers in Bank 3
- */
-
-#define CTL_REG_MAADR1 0x00
-#define CTL_REG_MAADR0 0x01
-#define CTL_REG_MAADR3 0x02
-#define CTL_REG_MAADR2 0x03
-#define CTL_REG_MAADR5 0x04
-#define CTL_REG_MAADR4 0x05
-#define CTL_REG_EBSTSD 0x06
-#define CTL_REG_EBSTCON 0x07
-#define CTL_REG_EBSTCSL 0x08
-#define CTL_REG_EBSTCSH 0x09
-#define CTL_REG_MISTAT 0x0A
-#define CTL_REG_EREVID 0x12
-#define CTL_REG_ECOCON 0x15
-#define CTL_REG_EFLOCON 0x17
-#define CTL_REG_EPAUSL 0x18
-#define CTL_REG_EPAUSH 0x19
-
-
-/*
- * PHY Register
- */
-
-#define PHY_REG_PHID1 0x02
-#define PHY_REG_PHID2 0x03
-/* taken from the Linux driver */
-#define PHY_REG_PHCON1 0x00
-#define PHY_REG_PHCON2 0x10
-#define PHY_REG_PHLCON 0x14
-
-/*
- * Receive Filter Register (ERXFCON) bits
- */
-
-#define ENC_RFR_UCEN  0x80
-#define ENC_RFR_ANDOR 0x40
-#define ENC_RFR_CRCEN 0x20
-#define ENC_RFR_PMEN  0x10
-#define ENC_RFR_MPEN  0x08
-#define ENC_RFR_HTEN  0x04
-#define ENC_RFR_MCEN  0x02
-#define ENC_RFR_BCEN  0x01
-
-/*
- * ECON1 Register Bits
- */
-
-#define ENC_ECON1_TXRST  0x80
-#define ENC_ECON1_RXRST  0x40
-#define ENC_ECON1_DMAST  0x20
-#define ENC_ECON1_CSUMEN 0x10
-#define ENC_ECON1_TXRTS  0x08
-#define ENC_ECON1_RXEN  0x04
-#define ENC_ECON1_BSEL1  0x02
-#define ENC_ECON1_BSEL0  0x01
-
-/*
- * ECON2 Register Bits
- */
-#define ENC_ECON2_AUTOINC 0x80
-#define ENC_ECON2_PKTDEC  0x40
-#define ENC_ECON2_PWRSV   0x20
-#define ENC_ECON2_VRPS   0x08
-
-/*
- * EIR Register Bits
- */
-#define ENC_EIR_PKTIF  0x40
-#define ENC_EIR_DMAIF  0x20
-#define ENC_EIR_LINKIF 0x10
-#define ENC_EIR_TXIF   0x08
-#define ENC_EIR_WOLIF  0x04
-#define ENC_EIR_TXERIF 0x02
-#define ENC_EIR_RXERIF 0x01
-
-/*
- * ESTAT Register Bits
- */
-
-#define ENC_ESTAT_INT    0x80
-#define ENC_ESTAT_LATECOL 0x10
-#define ENC_ESTAT_RXBUSY  0x04
-#define ENC_ESTAT_TXABRT  0x02
-#define ENC_ESTAT_CLKRDY  0x01
-
-/*
- * EIE Register Bits
- */
-
-#define ENC_EIE_INTIE  0x80
-#define ENC_EIE_PKTIE  0x40
-#define ENC_EIE_DMAIE  0x20
-#define ENC_EIE_LINKIE 0x10
-#define ENC_EIE_TXIE   0x08
-#define ENC_EIE_WOLIE  0x04
-#define ENC_EIE_TXERIE 0x02
-#define ENC_EIE_RXERIE 0x01
-
-/*
- * MACON1 Register Bits
- */
-#define ENC_MACON1_LOOPBK  0x10
-#define ENC_MACON1_TXPAUS  0x08
-#define ENC_MACON1_RXPAUS  0x04
-#define ENC_MACON1_PASSALL 0x02
-#define ENC_MACON1_MARXEN  0x01
-
-
-/*
- * MACON2 Register Bits
- */
-#define ENC_MACON2_MARST   0x80
-#define ENC_MACON2_RNDRST  0x40
-#define ENC_MACON2_MARXRST 0x08
-#define ENC_MACON2_RFUNRST 0x04
-#define ENC_MACON2_MATXRST 0x02
-#define ENC_MACON2_TFUNRST 0x01
-
-/*
- * MACON3 Register Bits
- */
-#define ENC_MACON3_PADCFG2 0x80
-#define ENC_MACON3_PADCFG1 0x40
-#define ENC_MACON3_PADCFG0 0x20
-#define ENC_MACON3_TXCRCEN 0x10
-#define ENC_MACON3_PHDRLEN 0x08
-#define ENC_MACON3_HFRMEN  0x04
-#define ENC_MACON3_FRMLNEN 0x02
-#define ENC_MACON3_FULDPX  0x01
-
-/*
- * MICMD Register Bits
- */
-#define ENC_MICMD_MIISCAN 0x02
-#define ENC_MICMD_MIIRD   0x01
-
-/*
- * MISTAT Register Bits
- */
-#define ENC_MISTAT_NVALID 0x04
-#define ENC_MISTAT_SCAN   0x02
-#define ENC_MISTAT_BUSY   0x01
-
-/*
- * PHID1 and PHID2 values
- */
-#define ENC_PHID1_VALUE 0x0083
-#define ENC_PHID2_VALUE 0x1400
-#define ENC_PHID2_MASK 0xFC00
-
-
-#define ENC_SPI_SLAVE_CS 0x00010000    /* pin P1.16 */
-#define ENC_RESET       0x00020000     /* pin P1.17 */
-
-#define FAILSAFE_VALUE 5000
-
-/*
- * Controller memory layout:
- *
- * 0x0000 - 0x17ff  6k bytes receive buffer
- * 0x1800 - 0x1fff  2k bytes transmit buffer
- */
-/* Use the lower memory for receiver buffer. See errata pt. 5 */
-#define ENC_RX_BUF_START 0x0000
-#define ENC_TX_BUF_START 0x1800
-/* taken from the Linux driver */
-#define ENC_RX_BUF_END   0x17ff
-#define ENC_TX_BUF_END   0x1fff
-
-/* maximum frame length */
-#define ENC_MAX_FRM_LEN 1518
-
-#define enc_enable() PUT32(IO1CLR, ENC_SPI_SLAVE_CS)
-#define enc_disable() PUT32(IO1SET, ENC_SPI_SLAVE_CS)
-#define enc_cfg_spi() spi_set_cfg(0, 0, 0); spi_set_clock(8);
-
-
-static unsigned char encReadReg (unsigned char regNo);
-static void encWriteReg (unsigned char regNo, unsigned char data);
-static void encWriteRegRetry (unsigned char regNo, unsigned char data, int c);
-static void encReadBuff (unsigned short length, unsigned char *pBuff);
-static void encWriteBuff (unsigned short length, unsigned char *pBuff);
-static void encBitSet (unsigned char regNo, unsigned char data);
-static void encBitClr (unsigned char regNo, unsigned char data);
-static void encReset (void);
-static void encInit (unsigned char *pEthAddr);
-static unsigned short phyRead (unsigned char addr);
-static void phyWrite(unsigned char, unsigned short);
-static void encPoll (void);
-static void encRx (void);
-
-#define m_nic_read(reg) encReadReg(reg)
-#define m_nic_write(reg, data) encWriteReg(reg, data)
-#define m_nic_write_retry(reg, data, count) encWriteRegRetry(reg, data, count)
-#define m_nic_read_data(len, buf) encReadBuff((len), (buf))
-#define m_nic_write_data(len, buf) encWriteBuff((len), (buf))
-
-/* bit field set */
-#define m_nic_bfs(reg, data) encBitSet(reg, data)
-
-/* bit field clear */
-#define m_nic_bfc(reg, data) encBitClr(reg, data)
-
-static unsigned char bank = 0; /* current bank in enc28j60 */
-static unsigned char next_pointer_lsb;
-static unsigned char next_pointer_msb;
-
-static unsigned char buffer[ENC_MAX_FRM_LEN];
-static int rxResetCounter = 0;
-
-#define RX_RESET_COUNTER 1000;
-
-/*-----------------------------------------------------------------------------
- * Always returns 0
- */
-int eth_init (bd_t * bis)
-{
-       unsigned char estatVal;
-
-       /* configure GPIO */
-       (*((volatile unsigned long *) IO1DIR)) |= ENC_SPI_SLAVE_CS;
-       (*((volatile unsigned long *) IO1DIR)) |= ENC_RESET;
-
-       /* CS and RESET active low */
-       PUT32 (IO1SET, ENC_SPI_SLAVE_CS);
-       PUT32 (IO1SET, ENC_RESET);
-
-       spi_init ();
-
-       /* taken from the Linux driver - dangerous stuff here! */
-       /* Wait for CLKRDY to become set (i.e., check that we can communicate with
-          the ENC) */
-       do
-       {
-               estatVal = m_nic_read(CTL_REG_ESTAT);
-       } while ((estatVal & 0x08) || (~estatVal & ENC_ESTAT_CLKRDY));
-
-       /* initialize controller */
-       encReset ();
-       encInit (bis->bi_enetaddr);
-
-       m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_RXEN);      /* enable receive */
-
-       return 0;
-}
-
-int eth_send (volatile void *packet, int length)
-{
-       /* check frame length, etc. */
-       /* TODO: */
-
-       /* switch to bank 0 */
-       m_nic_bfc (CTL_REG_ECON1, (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0));
-
-       /* set EWRPT */
-       m_nic_write (CTL_REG_EWRPTL, (ENC_TX_BUF_START & 0xff));
-       m_nic_write (CTL_REG_EWRPTH, (ENC_TX_BUF_START >> 8));
-
-       /* set ETXND */
-       m_nic_write (CTL_REG_ETXNDL, (length + ENC_TX_BUF_START) & 0xFF);
-       m_nic_write (CTL_REG_ETXNDH, (length + ENC_TX_BUF_START) >> 8);
-
-       /* set ETXST */
-       m_nic_write (CTL_REG_ETXSTL, ENC_TX_BUF_START & 0xFF);
-       m_nic_write (CTL_REG_ETXSTH, ENC_TX_BUF_START >> 8);
-
-       /* write packet */
-       m_nic_write_data (length, (unsigned char *) packet);
-
-       /* taken from the Linux driver */
-       /* Verify that the internal transmit logic has not been altered by excessive
-          collisions.  See Errata B4 12 and 14.
-        */
-       if (m_nic_read(CTL_REG_EIR) & ENC_EIR_TXERIF) {
-               m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_TXRST);
-               m_nic_bfc(CTL_REG_ECON1, ENC_ECON1_TXRST);
-       }
-       m_nic_bfc(CTL_REG_EIR, (ENC_EIR_TXERIF | ENC_EIR_TXIF));
-
-       /* set ECON1.TXRTS */
-       m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_TXRTS);
-
-       return 0;
-}
-
-
-/*****************************************************************************
- * This function resets the receiver only. This function may be called from
- * interrupt-context.
- */
-static void encReceiverReset (void)
-{
-       unsigned char econ1;
-
-       econ1 = m_nic_read (CTL_REG_ECON1);
-       if ((econ1 & ENC_ECON1_RXRST) == 0) {
-               m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_RXRST);
-               rxResetCounter = RX_RESET_COUNTER;
-       }
-}
-
-/*****************************************************************************
- * receiver reset timer
- */
-static void encReceiverResetCallback (void)
-{
-       m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_RXRST);
-       m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_RXEN);      /* enable receive */
-}
-
-/*-----------------------------------------------------------------------------
- * Check for received packets. Call NetReceive for each packet. The return
- * value is ignored by the caller.
- */
-int eth_rx (void)
-{
-       if (rxResetCounter > 0 && --rxResetCounter == 0) {
-               encReceiverResetCallback ();
-       }
-
-       encPoll ();
-
-       return 0;
-}
-
-void eth_halt (void)
-{
-       m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_RXEN);      /* disable receive */
-}
-
-/*****************************************************************************/
-
-static void encPoll (void)
-{
-       unsigned char eir_reg;
-       volatile unsigned char estat_reg;
-       unsigned char pkt_cnt;
-
-#ifdef CONFIG_USE_IRQ
-       /* clear global interrupt enable bit in enc28j60 */
-       m_nic_bfc (CTL_REG_EIE, ENC_EIE_INTIE);
-#endif
-       estat_reg = m_nic_read (CTL_REG_ESTAT);
-
-       eir_reg = m_nic_read (CTL_REG_EIR);
-
-       if (eir_reg & ENC_EIR_TXIF) {
-               /* clear TXIF bit in EIR */
-               m_nic_bfc (CTL_REG_EIR, ENC_EIR_TXIF);
-       }
-
-       /* We have to use pktcnt and not pktif bit, see errata pt. 6 */
-
-       /* move to bank 1 */
-       m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_BSEL1);
-       m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_BSEL0);
-
-       /* read pktcnt */
-       pkt_cnt = m_nic_read (CTL_REG_EPKTCNT);
-
-       if (pkt_cnt > 0) {
-               if ((eir_reg & ENC_EIR_PKTIF) == 0) {
-                       /*printf("encPoll: pkt cnt > 0, but pktif not set\n"); */
-               }
-               encRx ();
-               /* clear PKTIF bit in EIR, this should not need to be done but it
-                  seems like we get problems if we do not */
-               m_nic_bfc (CTL_REG_EIR, ENC_EIR_PKTIF);
-       }
-
-       if (eir_reg & ENC_EIR_RXERIF) {
-               printf ("encPoll: rx error\n");
-               m_nic_bfc (CTL_REG_EIR, ENC_EIR_RXERIF);
-       }
-       if (eir_reg & ENC_EIR_TXERIF) {
-               printf ("encPoll: tx error\n");
-               m_nic_bfc (CTL_REG_EIR, ENC_EIR_TXERIF);
-       }
-
-#ifdef CONFIG_USE_IRQ
-       /* set global interrupt enable bit in enc28j60 */
-       m_nic_bfs (CTL_REG_EIE, ENC_EIE_INTIE);
-#endif
-}
-
-static void encRx (void)
-{
-       unsigned short pkt_len;
-       unsigned short copy_len;
-       unsigned short status;
-       unsigned char eir_reg;
-       unsigned char pkt_cnt = 0;
-       unsigned short rxbuf_rdpt;
-
-       /* switch to bank 0 */
-       m_nic_bfc (CTL_REG_ECON1, (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0));
-
-       m_nic_write (CTL_REG_ERDPTL, next_pointer_lsb);
-       m_nic_write (CTL_REG_ERDPTH, next_pointer_msb);
-
-       do {
-               m_nic_read_data (6, buffer);
-               next_pointer_lsb = buffer[0];
-               next_pointer_msb = buffer[1];
-               pkt_len = buffer[2];
-               pkt_len |= (unsigned short) buffer[3] << 8;
-               status = buffer[4];
-               status |= (unsigned short) buffer[5] << 8;
-
-               if (pkt_len <= ENC_MAX_FRM_LEN)
-                       copy_len = pkt_len;
-               else
-                       copy_len = 0;
-
-               if ((status & (1L << 7)) == 0) /* check Received Ok bit */
-                       copy_len = 0;
-
-               /* taken from the Linux driver */
-               /* check if next pointer is resonable */
-               if ((((unsigned int)next_pointer_msb << 8) |
-                       (unsigned int)next_pointer_lsb) >= ENC_TX_BUF_START)
-                       copy_len = 0;
-
-               if (copy_len > 0) {
-                       m_nic_read_data (copy_len, buffer);
-               }
-
-               /* advance read pointer to next pointer */
-               m_nic_write (CTL_REG_ERDPTL, next_pointer_lsb);
-               m_nic_write (CTL_REG_ERDPTH, next_pointer_msb);
-
-               /* decrease packet counter */
-               m_nic_bfs (CTL_REG_ECON2, ENC_ECON2_PKTDEC);
-
-               /* taken from the Linux driver */
-               /* Only odd values should be written to ERXRDPTL,
-                * see errata B4 pt.13
-                */
-               rxbuf_rdpt = (next_pointer_msb << 8 | next_pointer_lsb) - 1;
-               if ((rxbuf_rdpt < (m_nic_read(CTL_REG_ERXSTH) << 8 |
-                               m_nic_read(CTL_REG_ERXSTL))) || (rxbuf_rdpt >
-                               (m_nic_read(CTL_REG_ERXNDH) << 8 |
-                               m_nic_read(CTL_REG_ERXNDL)))) {
-                       m_nic_write(CTL_REG_ERXRDPTL, m_nic_read(CTL_REG_ERXNDL));
-                       m_nic_write(CTL_REG_ERXRDPTH, m_nic_read(CTL_REG_ERXNDH));
-               } else {
-                       m_nic_write(CTL_REG_ERXRDPTL, rxbuf_rdpt & 0xFF);
-                       m_nic_write(CTL_REG_ERXRDPTH, rxbuf_rdpt >> 8);
-               }
-
-               /* move to bank 1 */
-               m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_BSEL1);
-               m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_BSEL0);
-
-               /* read pktcnt */
-               pkt_cnt = m_nic_read (CTL_REG_EPKTCNT);
-
-               /* switch to bank 0 */
-               m_nic_bfc (CTL_REG_ECON1,
-                          (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0));
-
-               if (copy_len == 0) {
-                       eir_reg = m_nic_read (CTL_REG_EIR);
-                       encReceiverReset ();
-                       printf ("eth_rx: copy_len=0\n");
-                       continue;
-               }
-
-               NetReceive ((unsigned char *) buffer, pkt_len);
-
-               eir_reg = m_nic_read (CTL_REG_EIR);
-       } while (pkt_cnt);      /* Use EPKTCNT not EIR.PKTIF flag, see errata pt. 6 */
-}
-
-static void encWriteReg (unsigned char regNo, unsigned char data)
-{
-       spi_lock ();
-       enc_cfg_spi ();
-       enc_enable ();
-
-       spi_write (0x40 | regNo);       /* write in regNo */
-       spi_write (data);
-
-       enc_disable ();
-       enc_enable ();
-
-       spi_write (0x1f);       /* write reg 0x1f */
-
-       enc_disable ();
-       spi_unlock ();
-}
-
-static void encWriteRegRetry (unsigned char regNo, unsigned char data, int c)
-{
-       unsigned char readback;
-       int i;
-
-       spi_lock ();
-
-       for (i = 0; i < c; i++) {
-               enc_cfg_spi ();
-               enc_enable ();
-
-               spi_write (0x40 | regNo);       /* write in regNo */
-               spi_write (data);
-
-               enc_disable ();
-               enc_enable ();
-
-               spi_write (0x1f);       /* write reg 0x1f */
-
-               enc_disable ();
-
-               spi_unlock ();  /* we must unlock spi first */
-
-               readback = encReadReg (regNo);
-
-               spi_lock ();
-
-               if (readback == data)
-                       break;
-       }
-       spi_unlock ();
-
-       if (i == c) {
-               printf ("enc28j60: write reg %d failed\n", regNo);
-       }
-}
-
-static unsigned char encReadReg (unsigned char regNo)
-{
-       unsigned char rxByte;
-
-       spi_lock ();
-       enc_cfg_spi ();
-       enc_enable ();
-
-       spi_write (0x1f);       /* read reg 0x1f */
-
-       bank = spi_read () & 0x3;
-
-       enc_disable ();
-       enc_enable ();
-
-       spi_write (regNo);
-       rxByte = spi_read ();
-
-       /* check if MAC or MII register */
-       if (((bank == 2) && (regNo <= 0x1a)) ||
-           ((bank == 3) && (regNo <= 0x05 || regNo == 0x0a))) {
-               /* ignore first byte and read another byte */
-               rxByte = spi_read ();
-       }
-
-       enc_disable ();
-       spi_unlock ();
-
-       return rxByte;
-}
-
-static void encReadBuff (unsigned short length, unsigned char *pBuff)
-{
-       spi_lock ();
-       enc_cfg_spi ();
-       enc_enable ();
-
-       spi_write (0x20 | 0x1a);        /* read buffer memory */
-
-       while (length--) {
-               if (pBuff != NULL)
-                       *pBuff++ = spi_read ();
-               else
-                       spi_write (0);
-       }
-
-       enc_disable ();
-       spi_unlock ();
-}
-
-static void encWriteBuff (unsigned short length, unsigned char *pBuff)
-{
-       spi_lock ();
-       enc_cfg_spi ();
-       enc_enable ();
-
-       spi_write (0x60 | 0x1a);        /* write buffer memory */
-
-       spi_write (0x00);       /* control byte */
-
-       while (length--)
-               spi_write (*pBuff++);
-
-       enc_disable ();
-       spi_unlock ();
-}
-
-static void encBitSet (unsigned char regNo, unsigned char data)
-{
-       spi_lock ();
-       enc_cfg_spi ();
-       enc_enable ();
-
-       spi_write (0x80 | regNo);       /* bit field set */
-       spi_write (data);
-
-       enc_disable ();
-       spi_unlock ();
-}
-
-static void encBitClr (unsigned char regNo, unsigned char data)
-{
-       spi_lock ();
-       enc_cfg_spi ();
-       enc_enable ();
-
-       spi_write (0xA0 | regNo);       /* bit field clear */
-       spi_write (data);
-
-       enc_disable ();
-       spi_unlock ();
-}
-
-static void encReset (void)
-{
-       spi_lock ();
-       enc_cfg_spi ();
-       enc_enable ();
-
-       spi_write (0xff);       /* soft reset */
-
-       enc_disable ();
-       spi_unlock ();
-
-       /* sleep 1 ms. See errata pt. 2 */
-       udelay (1000);
-}
-
-static void encInit (unsigned char *pEthAddr)
-{
-       unsigned short phid1 = 0;
-       unsigned short phid2 = 0;
-
-       /* switch to bank 0 */
-       m_nic_bfc (CTL_REG_ECON1, (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0));
-
-       /*
-        * Setup the buffer space. The reset values are valid for the
-        * other pointers.
-        */
-       /* We shall not write to ERXST, see errata pt. 5. Instead we
-          have to make sure that ENC_RX_BUS_START is 0. */
-       m_nic_write_retry (CTL_REG_ERXSTL, (ENC_RX_BUF_START & 0xFF), 1);
-       m_nic_write_retry (CTL_REG_ERXSTH, (ENC_RX_BUF_START >> 8), 1);
-
-       /* taken from the Linux driver */
-       m_nic_write_retry (CTL_REG_ERXNDL, (ENC_RX_BUF_END & 0xFF), 1);
-       m_nic_write_retry (CTL_REG_ERXNDH, (ENC_RX_BUF_END >> 8), 1);
-
-       m_nic_write_retry (CTL_REG_ERDPTL, (ENC_RX_BUF_START & 0xFF), 1);
-       m_nic_write_retry (CTL_REG_ERDPTH, (ENC_RX_BUF_START >> 8), 1);
-
-       next_pointer_lsb = (ENC_RX_BUF_START & 0xFF);
-       next_pointer_msb = (ENC_RX_BUF_START >> 8);
-
-       /* verify identification */
-       phid1 = phyRead (PHY_REG_PHID1);
-       phid2 = phyRead (PHY_REG_PHID2);
-
-       if (phid1 != ENC_PHID1_VALUE
-           || (phid2 & ENC_PHID2_MASK) != ENC_PHID2_VALUE) {
-               printf ("ERROR: failed to identify controller\n");
-               printf ("phid1 = %x, phid2 = %x\n",
-                       phid1, (phid2 & ENC_PHID2_MASK));
-               printf ("should be phid1 = %x, phid2 = %x\n",
-                       ENC_PHID1_VALUE, ENC_PHID2_VALUE);
-       }
-
-       /*
-        * --- MAC Initialization ---
-        */
-
-       /* Pull MAC out of Reset */
-
-       /* switch to bank 2 */
-       m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_BSEL0);
-       m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_BSEL1);
-
-       /* enable MAC to receive frames */
-       /* added some bits from the Linux driver */
-       m_nic_write_retry (CTL_REG_MACON1
-               ,(ENC_MACON1_MARXEN | ENC_MACON1_TXPAUS | ENC_MACON1_RXPAUS)
-               ,10);
-
-       /* configure pad, tx-crc and duplex */
-       /* added a bit from the Linux driver */
-       m_nic_write_retry (CTL_REG_MACON3
-               ,(ENC_MACON3_PADCFG0 | ENC_MACON3_TXCRCEN | ENC_MACON3_FRMLNEN)
-               ,10);
-
-       /* added 4 new lines from the Linux driver */
-       /* Allow infinite deferals if the medium is continously busy */
-       m_nic_write_retry(CTL_REG_MACON4, (1<<6) /*ENC_MACON4_DEFER*/, 10);
-
-       /* Late collisions occur beyond 63 bytes */
-       m_nic_write_retry(CTL_REG_MACLCON2, 63, 10);
-
-       /* Set (low byte) Non-Back-to_Back Inter-Packet Gap. Recommended 0x12 */
-       m_nic_write_retry(CTL_REG_MAIPGL, 0x12, 10);
-
-       /*
-       * Set (high byte) Non-Back-to_Back Inter-Packet Gap. Recommended
-       * 0x0c for half-duplex. Nothing for full-duplex
-       */
-       m_nic_write_retry(CTL_REG_MAIPGH, 0x0C, 10);
-
-       /* set maximum frame length */
-       m_nic_write_retry (CTL_REG_MAMXFLL, (ENC_MAX_FRM_LEN & 0xff), 10);
-       m_nic_write_retry (CTL_REG_MAMXFLH, (ENC_MAX_FRM_LEN >> 8), 10);
-
-       /*
-        * Set MAC back-to-back inter-packet gap. Recommended 0x12 for half duplex
-        * and 0x15 for full duplex.
-        */
-       m_nic_write_retry (CTL_REG_MABBIPG, 0x12, 10);
-
-       /* set MAC address */
-
-       /* switch to bank 3 */
-       m_nic_bfs (CTL_REG_ECON1, (ENC_ECON1_BSEL0 | ENC_ECON1_BSEL1));
-
-       m_nic_write_retry (CTL_REG_MAADR0, pEthAddr[5], 1);
-       m_nic_write_retry (CTL_REG_MAADR1, pEthAddr[4], 1);
-       m_nic_write_retry (CTL_REG_MAADR2, pEthAddr[3], 1);
-       m_nic_write_retry (CTL_REG_MAADR3, pEthAddr[2], 1);
-       m_nic_write_retry (CTL_REG_MAADR4, pEthAddr[1], 1);
-       m_nic_write_retry (CTL_REG_MAADR5, pEthAddr[0], 1);
-
-       /*
-       * PHY Initialization taken from the Linux driver
-        */
-
-       /* Prevent automatic loopback of data beeing transmitted by setting
-          ENC_PHCON2_HDLDIS */
-       phyWrite(PHY_REG_PHCON2, (1<<8));
-
-       /* LEDs configuration
-        * LEDA: LACFG = 0100 -> display link status
-        * LEDB: LBCFG = 0111 -> display TX & RX activity
-        * STRCH = 1 -> LED pulses
-        */
-       phyWrite(PHY_REG_PHLCON, 0x0472);
-
-       /* Reset PDPXMD-bit => half duplex */
-       phyWrite(PHY_REG_PHCON1, 0);
-
-       /*
-        * Receive settings
-        */
-
-#ifdef CONFIG_USE_IRQ
-       /* enable interrupts */
-       m_nic_bfs (CTL_REG_EIE, ENC_EIE_PKTIE);
-       m_nic_bfs (CTL_REG_EIE, ENC_EIE_TXIE);
-       m_nic_bfs (CTL_REG_EIE, ENC_EIE_RXERIE);
-       m_nic_bfs (CTL_REG_EIE, ENC_EIE_TXERIE);
-       m_nic_bfs (CTL_REG_EIE, ENC_EIE_INTIE);
-#endif
-}
-
-/*****************************************************************************
- *
- * Description:
- *    Read PHY registers.
- *
- *    NOTE! This function will change to Bank 2.
- *
- * Params:
- *    [in] addr address of the register to read
- *
- * Returns:
- *    The value in the register
- */
-static unsigned short phyRead (unsigned char addr)
-{
-       unsigned short ret = 0;
-
-       /* move to bank 2 */
-       m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_BSEL0);
-       m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_BSEL1);
-
-       /* write address to MIREGADR */
-       m_nic_write (CTL_REG_MIREGADR, addr);
-
-       /* set MICMD.MIIRD */
-       m_nic_write (CTL_REG_MICMD, ENC_MICMD_MIIRD);
-
-       /* taken from the Linux driver */
-       /* move to bank 3 */
-       m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL0);
-       m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL1);
-
-       /* poll MISTAT.BUSY bit until operation is complete */
-       while ((m_nic_read (CTL_REG_MISTAT) & ENC_MISTAT_BUSY) != 0) {
-               static int cnt = 0;
-
-               if (cnt++ >= 1000) {
-                       /* GJ - this seems extremely dangerous! */
-                       /* printf("#"); */
-                       cnt = 0;
-               }
-       }
-
-       /* taken from the Linux driver */
-       /* move to bank 2 */
-       m_nic_bfc(CTL_REG_ECON1, ENC_ECON1_BSEL0);
-       m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL1);
-
-       /* clear MICMD.MIIRD */
-       m_nic_write (CTL_REG_MICMD, 0);
-
-       ret = (m_nic_read (CTL_REG_MIRDH) << 8);
-       ret |= (m_nic_read (CTL_REG_MIRDL) & 0xFF);
-
-       return ret;
-}
-
-/*****************************************************************************
- *
- * Taken from the Linux driver.
- * Description:
- * Write PHY registers.
- *
- * NOTE! This function will change to Bank 3.
- *
- * Params:
- * [in] addr address of the register to write to
- * [in] data to be written
- *
- * Returns:
- *    None
- */
-static void phyWrite(unsigned char addr, unsigned short data)
-{
-       /* move to bank 2 */
-       m_nic_bfc(CTL_REG_ECON1, ENC_ECON1_BSEL0);
-       m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL1);
-
-       /* write address to MIREGADR */
-       m_nic_write(CTL_REG_MIREGADR, addr);
-
-       m_nic_write(CTL_REG_MIWRL, data & 0xff);
-       m_nic_write(CTL_REG_MIWRH, data >> 8);
-
-       /* move to bank 3 */
-       m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL0);
-       m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL1);
-
-       /* poll MISTAT.BUSY bit until operation is complete */
-       while((m_nic_read(CTL_REG_MISTAT) & ENC_MISTAT_BUSY) != 0) {
-               static int cnt = 0;
-
-               if(cnt++ >= 1000) {
-                       cnt = 0;
-               }
-       }
-}
-
-#endif /* CONFIG_ENC28J60 */
diff --git a/drivers/fsl_i2c.c b/drivers/fsl_i2c.c
deleted file mode 100644 (file)
index 22485ea..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright 2006 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * Version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-
-#ifdef CONFIG_FSL_I2C
-#ifdef CONFIG_HARD_I2C
-
-#include <command.h>
-#include <i2c.h>               /* Functional interface */
-
-#include <asm/io.h>
-#include <asm/fsl_i2c.h>       /* HW definitions */
-
-#define I2C_TIMEOUT    (CFG_HZ / 4)
-
-#define I2C_READ_BIT  1
-#define I2C_WRITE_BIT 0
-
-/* Initialize the bus pointer to whatever one the SPD EEPROM is on.
- * Default is bus 0.  This is necessary because the DDR initialization
- * runs from ROM, and we can't switch buses because we can't modify
- * the global variables.
- */
-#ifdef CFG_SPD_BUS_NUM
-static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = CFG_SPD_BUS_NUM;
-#else
-static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = 0;
-#endif
-
-static volatile struct fsl_i2c *i2c_dev[2] = {
-       (struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET),
-#ifdef CFG_I2C2_OFFSET
-       (struct fsl_i2c *) (CFG_IMMR + CFG_I2C2_OFFSET)
-#endif
-};
-
-void
-i2c_init(int speed, int slaveadd)
-{
-       volatile struct fsl_i2c *dev;
-
-       dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET);
-
-       writeb(0, &dev->cr);                    /* stop I2C controller */
-       udelay(5);                              /* let it shutdown in peace */
-       writeb(0x3F, &dev->fdr);                /* set bus speed */
-       writeb(0x3F, &dev->dfsrr);              /* set default filter */
-       writeb(slaveadd << 1, &dev->adr);       /* write slave address */
-       writeb(0x0, &dev->sr);                  /* clear status register */
-       writeb(I2C_CR_MEN, &dev->cr);           /* start I2C controller */
-
-#ifdef CFG_I2C2_OFFSET
-       dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C2_OFFSET);
-
-       writeb(0, &dev->cr);                    /* stop I2C controller */
-       udelay(5);                              /* let it shutdown in peace */
-       writeb(0x3F, &dev->fdr);                /* set bus speed */
-       writeb(0x3F, &dev->dfsrr);              /* set default filter */
-       writeb(slaveadd << 1, &dev->adr);       /* write slave address */
-       writeb(0x0, &dev->sr);                  /* clear status register */
-       writeb(I2C_CR_MEN, &dev->cr);           /* start I2C controller */
-#endif /* CFG_I2C2_OFFSET */
-}
-
-static __inline__ int
-i2c_wait4bus(void)
-{
-       ulong timeval = get_timer(0);
-
-       while (readb(&i2c_dev[i2c_bus_num]->sr) & I2C_SR_MBB) {
-               if (get_timer(timeval) > I2C_TIMEOUT) {
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-static __inline__ int
-i2c_wait(int write)
-{
-       u32 csr;
-       ulong timeval = get_timer(0);
-
-       do {
-               csr = readb(&i2c_dev[i2c_bus_num]->sr);
-               if (!(csr & I2C_SR_MIF))
-                       continue;
-
-               writeb(0x0, &i2c_dev[i2c_bus_num]->sr);
-
-               if (csr & I2C_SR_MAL) {
-                       debug("i2c_wait: MAL\n");
-                       return -1;
-               }
-
-               if (!(csr & I2C_SR_MCF))        {
-                       debug("i2c_wait: unfinished\n");
-                       return -1;
-               }
-
-               if (write == I2C_WRITE_BIT && (csr & I2C_SR_RXAK)) {
-                       debug("i2c_wait: No RXACK\n");
-                       return -1;
-               }
-
-               return 0;
-       } while (get_timer (timeval) < I2C_TIMEOUT);
-
-       debug("i2c_wait: timed out\n");
-       return -1;
-}
-
-static __inline__ int
-i2c_write_addr (u8 dev, u8 dir, int rsta)
-{
-       writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX
-              | (rsta ? I2C_CR_RSTA : 0),
-              &i2c_dev[i2c_bus_num]->cr);
-
-       writeb((dev << 1) | dir, &i2c_dev[i2c_bus_num]->dr);
-
-       if (i2c_wait(I2C_WRITE_BIT) < 0)
-               return 0;
-
-       return 1;
-}
-
-static __inline__ int
-__i2c_write(u8 *data, int length)
-{
-       int i;
-
-       writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX,
-              &i2c_dev[i2c_bus_num]->cr);
-
-       for (i = 0; i < length; i++) {
-               writeb(data[i], &i2c_dev[i2c_bus_num]->dr);
-
-               if (i2c_wait(I2C_WRITE_BIT) < 0)
-                       break;
-       }
-
-       return i;
-}
-
-static __inline__ int
-__i2c_read(u8 *data, int length)
-{
-       int i;
-
-       writeb(I2C_CR_MEN | I2C_CR_MSTA | ((length == 1) ? I2C_CR_TXAK : 0),
-              &i2c_dev[i2c_bus_num]->cr);
-
-       /* dummy read */
-       readb(&i2c_dev[i2c_bus_num]->dr);
-
-       for (i = 0; i < length; i++) {
-               if (i2c_wait(I2C_READ_BIT) < 0)
-                       break;
-
-               /* Generate ack on last next to last byte */
-               if (i == length - 2)
-                       writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_TXAK,
-                              &i2c_dev[i2c_bus_num]->cr);
-
-               /* Generate stop on last byte */
-               if (i == length - 1)
-                       writeb(I2C_CR_MEN | I2C_CR_TXAK, &i2c_dev[i2c_bus_num]->cr);
-
-               data[i] = readb(&i2c_dev[i2c_bus_num]->dr);
-       }
-
-       return i;
-}
-
-int
-i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
-{
-       int i = -1; /* signal error */
-       u8 *a = (u8*)&addr;
-
-       if (i2c_wait4bus() >= 0
-           && i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0
-           && __i2c_write(&a[4 - alen], alen) == alen)
-               i = 0; /* No error so far */
-
-       if (length
-           && i2c_write_addr(dev, I2C_READ_BIT, 1) != 0)
-               i = __i2c_read(data, length);
-
-       writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
-
-       if (i == length)
-           return 0;
-
-       return -1;
-}
-
-int
-i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
-{
-       int i = -1; /* signal error */
-       u8 *a = (u8*)&addr;
-
-       if (i2c_wait4bus() >= 0
-           && i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0
-           && __i2c_write(&a[4 - alen], alen) == alen) {
-               i = __i2c_write(data, length);
-       }
-
-       writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
-
-       if (i == length)
-           return 0;
-
-       return -1;
-}
-
-int
-i2c_probe(uchar chip)
-{
-       /* For unknow reason the controller will ACK when
-        * probing for a slave with the same address, so skip
-        * it.
-        */
-       if (chip == (readb(&i2c_dev[i2c_bus_num]->adr) >> 1))
-               return -1;
-
-       return i2c_read(chip, 0, 0, NULL, 0);
-}
-
-uchar
-i2c_reg_read(uchar i2c_addr, uchar reg)
-{
-       uchar buf[1];
-
-       i2c_read(i2c_addr, reg, 1, buf, 1);
-
-       return buf[0];
-}
-
-void
-i2c_reg_write(uchar i2c_addr, uchar reg, uchar val)
-{
-       i2c_write(i2c_addr, reg, 1, &val, 1);
-}
-
-int i2c_set_bus_num(unsigned int bus)
-{
-#ifdef CFG_I2C2_OFFSET
-       if (bus > 1) {
-#else
-       if (bus > 0) {
-#endif
-               return -1;
-       }
-
-       i2c_bus_num = bus;
-
-       return 0;
-}
-
-int i2c_set_bus_speed(unsigned int speed)
-{
-       return -1;
-}
-
-unsigned int i2c_get_bus_num(void)
-{
-       return i2c_bus_num;
-}
-
-unsigned int i2c_get_bus_speed(void)
-{
-       return 0;
-}
-#endif /* CONFIG_HARD_I2C */
-#endif /* CONFIG_FSL_I2C */
diff --git a/drivers/fsl_pci_init.c b/drivers/fsl_pci_init.c
deleted file mode 100644 (file)
index 1e77884..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright 2007 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * Version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-
-#ifdef CONFIG_FSL_PCI_INIT
-
-/*
- * PCI/PCIE Controller initialization for mpc85xx/mpc86xx soc's
- *
- * Initialize controller and call the common driver/pci pci_hose_scan to
- * scan for bridges and devices.
- *
- * Hose fields which need to be pre-initialized by board specific code:
- *   regions[]
- *   first_busno
- *
- * Fields updated:
- *   last_busno
- */
-
-#include <pci.h>
-#include <asm/immap_fsl_pci.h>
-
-void pciauto_prescan_setup_bridge(struct pci_controller *hose,
-                               pci_dev_t dev, int sub_bus);
-void pciauto_postscan_setup_bridge(struct pci_controller *hose,
-                               pci_dev_t dev, int sub_bus);
-
-void pciauto_config_init(struct pci_controller *hose);
-void
-fsl_pci_init(struct pci_controller *hose)
-{
-       u16 temp16;
-       u32 temp32;
-       int busno = hose->first_busno;
-       int enabled;
-       u16 ltssm;
-       u8 temp8;
-       int r;
-       int bridge;
-       int inbound = 0;
-       volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) hose->cfg_addr;
-       pci_dev_t dev = PCI_BDF(busno,0,0);
-
-       /* Initialize ATMU registers based on hose regions and flags */
-       volatile pot_t *po=&pci->pot[1];        /* skip 0 */
-       volatile pit_t *pi=&pci->pit[0];        /* ranges from: 3 to 1 */
-
-#ifdef DEBUG
-       int neg_link_w;
-#endif
-
-       for (r=0; r<hose->region_count; r++) {
-               if (hose->regions[r].flags & PCI_REGION_MEMORY) { /* inbound */
-                       pi->pitar = (hose->regions[r].bus_start >> 12) & 0x000fffff;
-                       pi->piwbar = (hose->regions[r].phys_start >> 12) & 0x000fffff;
-                       pi->piwbear = 0;
-                       pi->piwar = PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
-                               PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP |
-                               (__ilog2(hose->regions[r].size) - 1);
-                       pi++;
-                       inbound = hose->regions[r].size > 0;
-               } else { /* Outbound */
-                       po->powbar = (hose->regions[r].phys_start >> 12) & 0x000fffff;
-                       po->potar = (hose->regions[r].bus_start >> 12) & 0x000fffff;
-                       po->potear = 0;
-                       if (hose->regions[r].flags & PCI_REGION_IO)
-                               po->powar = POWAR_EN | POWAR_IO_READ | POWAR_IO_WRITE |
-                                       (__ilog2(hose->regions[r].size) - 1);
-                       else
-                               po->powar = POWAR_EN | POWAR_MEM_READ | POWAR_MEM_WRITE |
-                                       (__ilog2(hose->regions[r].size) - 1);
-                       po++;
-               }
-       }
-
-       pci_register_hose(hose);
-       pciauto_config_init(hose);      /* grab pci_{mem,prefetch,io} */
-       hose->current_busno = hose->first_busno;
-
-       pci->pedr = 0xffffffff;         /* Clear any errors */
-       pci->peer = ~0x20140;           /* Enable All Error Interupts except
-                                        * - Master abort (pci)
-                                        * - Master PERR (pci)
-                                        * - ICCA (PCIe)
-                                        */
-       pci_hose_read_config_dword (hose, dev, PCI_DCR, &temp32);
-       temp32 |= 0xf000e;              /* set URR, FER, NFER (but not CER) */
-       pci_hose_write_config_dword(hose, dev, PCI_DCR, temp32);
-
-       pci_hose_read_config_byte (hose, dev, PCI_HEADER_TYPE, &temp8);
-       bridge = temp8 & PCI_HEADER_TYPE_BRIDGE; /* Bridge, such as pcie */
-
-       if ( bridge ) {
-
-               pci_hose_read_config_word(hose, dev, PCI_LTSSM, &ltssm);
-               enabled = ltssm >= PCI_LTSSM_L0;
-
-               if (!enabled) {
-                       debug("....PCIE link error.  Skipping scan."
-                             "LTSSM=0x%02x\n", ltssm);
-                       hose->last_busno = hose->first_busno;
-                       return;
-               }
-
-               pci->pme_msg_det = 0xffffffff;
-               pci->pme_msg_int_en = 0xffffffff;
-#ifdef DEBUG
-               pci_hose_read_config_word(hose, dev, PCI_LSR, &temp16);
-               neg_link_w = (temp16 & 0x3f0 ) >> 4;
-               printf("...PCIE LTSSM=0x%x, Negotiated link width=%d\n",
-                     ltssm, neg_link_w);
-#endif
-               hose->current_busno++; /* Start scan with secondary */
-               pciauto_prescan_setup_bridge(hose, dev, hose->current_busno);
-
-       }
-
-       /* Use generic setup_device to initialize standard pci regs,
-        * but do not allocate any windows since any BAR found (such
-        * as PCSRBAR) is not in this cpu's memory space.
-        */
-
-       pciauto_setup_device(hose, dev, 0, hose->pci_mem,
-                            hose->pci_prefetch, hose->pci_io);
-
-       if (inbound) {
-               pci_hose_read_config_word(hose, dev, PCI_COMMAND, &temp16);
-               pci_hose_write_config_word(hose, dev, PCI_COMMAND,
-                                          temp16 | PCI_COMMAND_MEMORY);
-       }
-
-#ifndef CONFIG_PCI_NOSCAN
-       printf ("               Scanning PCI bus %02x\n", hose->current_busno);
-       hose->last_busno = pci_hose_scan_bus(hose,hose->current_busno);
-
-       if ( bridge ) { /* update limit regs and subordinate busno */
-               pciauto_postscan_setup_bridge(hose, dev, hose->last_busno);
-       }
-#else
-       hose->last_busno = hose->current_busno;
-#endif
-
-       /* Clear all error indications */
-
-       pci->pme_msg_det = 0xffffffff;
-       pci->pedr = 0xffffffff;
-
-       pci_hose_read_config_word (hose, dev, PCI_DSR, &temp16);
-       if (temp16) {
-               pci_hose_write_config_word(hose, dev,
-                                       PCI_DSR, 0xffff);
-       }
-
-       pci_hose_read_config_word (hose, dev, PCI_SEC_STATUS, &temp16);
-       if (temp16) {
-               pci_hose_write_config_word(hose, dev, PCI_SEC_STATUS, 0xffff);
-       }
-}
-
-#endif /* CONFIG_FSL_PCI */
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
new file mode 100644 (file)
index 0000000..cebb2ba
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# (C) Copyright 2001
+# Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+#CFLAGS += -DDEBUG
+
+LIB    = $(obj)libhwmon.a
+
+COBJS-y += adm1021.o
+COBJS-y += ds1621.o
+COBJS-y += ds1722.o
+COBJS-y += ds1775.o
+COBJS-y += lm75.o
+COBJS-y += lm81.o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c
new file mode 100644 (file)
index 0000000..9f65cfb
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * (C) Copyright 2003
+ * Murray Jensen, CSIRO-MIT, Murray.Jensen@csiro.au
+ *
+ * based on dtt/lm75.c which is ...
+ *
+ * (C) Copyright 2001
+ * Bill Hunter,  Wave 7 Optics, williamhunter@mediaone.net
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Analog Devices's ADM1021
+ * "Low Cost Microprocessor System Temperature Monitor"
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_ADM1021
+
+#include <i2c.h>
+#include <dtt.h>
+
+typedef
+       struct {
+               uint i2c_addr:7;        /* 7bit i2c chip address */
+               uint conv_rate:3;       /* conversion rate */
+               uint enable_alert:1;    /* enable alert output pin */
+               uint enable_local:1;    /* enable internal temp sensor */
+               uint max_local:8;       /* internal temp maximum */
+               uint min_local:8;       /* internal temp minimum */
+               uint enable_remote:1;   /* enable remote temp sensor */
+               uint max_remote:8;      /* remote temp maximum */
+               uint min_remote:8;      /* remote temp minimum */
+       }
+dtt_cfg_t;
+
+dtt_cfg_t dttcfg[] = CFG_DTT_ADM1021;
+
+int
+dtt_read (int sensor, int reg)
+{
+       dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
+       uchar data;
+
+       if (i2c_read(dcp->i2c_addr, reg, 1, &data, 1) != 0)
+               return -1;
+
+       return (int)data;
+} /* dtt_read() */
+
+int
+dtt_write (int sensor, int reg, int val)
+{
+       dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
+       uchar data;
+
+       data = (uchar)(val & 0xff);
+
+       if (i2c_write(dcp->i2c_addr, reg, 1, &data, 1) != 0)
+               return 1;
+
+       return 0;
+} /* dtt_write() */
+
+static int
+_dtt_init (int sensor)
+{
+       dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
+       int reg, val;
+
+       if (((sensor & 1) == 0 ? dcp->enable_local : dcp->enable_remote) == 0)
+               return 1;       /* sensor is disabled (or rather ignored) */
+
+       /*
+        * Setup High Limit register
+        */
+       if ((sensor & 1) == 0) {
+               reg = DTT_WRITE_LOC_HIGHLIM;
+               val = dcp->max_local;
+       }
+       else {
+               reg = DTT_WRITE_REM_HIGHLIM;
+               val = dcp->max_remote;
+       }
+       if (dtt_write (sensor, reg, val) != 0)
+               return 1;
+
+       /*
+        * Setup Low Limit register
+        */
+       if ((sensor & 1) == 0) {
+               reg = DTT_WRITE_LOC_LOWLIM;
+               val = dcp->min_local;
+       }
+       else {
+               reg = DTT_WRITE_REM_LOWLIM;
+               val = dcp->min_remote;
+       }
+       if (dtt_write (sensor, reg, val) != 0)
+               return 1;
+
+       /* shouldn't hurt if the rest gets done twice */
+
+       /*
+        * Setup Conversion Rate register
+        */
+       if (dtt_write (sensor, DTT_WRITE_CONVRATE, dcp->conv_rate) != 0)
+               return 1;
+
+       /*
+        * Setup configuraton register
+        */
+       val = 0;                                /* running */
+       if (dcp->enable_alert == 0)
+               val |= DTT_CONFIG_ALERT_MASKED; /* mask ALERT pin */
+       if (dtt_write (sensor, DTT_WRITE_CONFIG, val) != 0)
+               return 1;
+
+       return 0;
+} /* _dtt_init() */
+
+int
+dtt_init (void)
+{
+       int i;
+       unsigned char sensors[] = CONFIG_DTT_SENSORS;
+       const char *const header = "DTT:   ";
+
+       /* switch to correct I2C bus */
+       I2C_SET_BUS(CFG_DTT_BUS_NUM);
+
+       for (i = 0; i < sizeof(sensors); i++) {
+               if (_dtt_init(sensors[i]) != 0)
+                       printf ("%s%d FAILED INIT\n", header, i+1);
+               else
+                       printf ("%s%d is %i C\n", header, i+1,
+                               dtt_get_temp(sensors[i]));
+       }
+
+       return (0);
+} /* dtt_init() */
+
+int
+dtt_get_temp (int sensor)
+{
+       signed char val;
+
+       if ((sensor & 1) == 0)
+               val = dtt_read(sensor, DTT_READ_LOC_VALUE);
+       else
+               val = dtt_read(sensor, DTT_READ_REM_VALUE);
+
+       return (int) val;
+} /* dtt_get_temp() */
+
+#endif /* CONFIG_DTT_ADM1021 */
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
new file mode 100644 (file)
index 0000000..4948181
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen,  Wave 7 Optics, etheisen@mindspring.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Dallas Semiconductor's DS1621 Digital Thermometer and Thermostat.
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_DS1621
+#if !defined(CFG_EEPROM_PAGE_WRITE_ENABLE) || \
+       (CFG_EEPROM_PAGE_WRITE_BITS < 1)
+# error "CFG_EEPROM_PAGE_WRITE_ENABLE must be defined and CFG_EEPROM_PAGE_WRITE_BITS must be greater than 1 to use CONFIG_DTT_DS1621"
+#endif
+#include <i2c.h>
+#include <dtt.h>
+
+/*
+ * Device code
+ */
+#define DTT_I2C_DEV_CODE 0x48                  /* Dallas Semi's DS1621 */
+
+int dtt_read(int sensor, int reg)
+{
+    int dlen;
+    uchar data[2];
+
+    /*
+     * Calculate sensor address and command.
+     *
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* Calculate addr of ds1621*/
+
+    /*
+     * Prepare to handle 2 byte result.
+     */
+    if ((reg == DTT_READ_TEMP) ||
+       (reg == DTT_TEMP_HIGH) || (reg == DTT_TEMP_LOW))
+       dlen = 2;
+    else
+       dlen = 1;
+
+    /*
+     * Now try to read the register.
+     */
+    if (i2c_read(sensor, reg, 1, data, dlen) != 0)
+       return 1;
+
+    /*
+     * Handle 2 byte result.
+     */
+    if (dlen == 2)
+       return ((int)((short)data[1] + (((short)data[0]) << 8)));
+
+    return (int)data[0];
+} /* dtt_read() */
+
+
+int dtt_write(int sensor, int reg, int val)
+{
+    int dlen;
+    uchar data[2];
+
+    /*
+     * Calculate sensor address and register.
+     *
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07);
+
+    /*
+     * Handle various data sizes.
+     */
+    if ((reg == DTT_READ_TEMP) ||
+       (reg == DTT_TEMP_HIGH) || (reg == DTT_TEMP_LOW)) {
+       dlen = 2;
+       data[0] = (char)((val >> 8) & 0xff);    /* MSB first */
+       data[1] = (char)(val & 0xff);
+    }
+    else if ((reg == DTT_WRITE_START_CONV) || (reg == DTT_WRITE_STOP_CONV)) {
+       dlen = 0;
+       data[0] = (char)0;
+       data[1] = (char)0;
+    }
+    else {
+       dlen = 1;
+       data[0] = (char)(val & 0xff);
+    }
+
+    /*
+     * Write value to device.
+     */
+    if (i2c_write(sensor, reg, 1, data, dlen) != 0)
+       return 1;
+
+    return 0;
+} /* dtt_write() */
+
+
+static int _dtt_init(int sensor)
+{
+    int val;
+
+    /*
+     * Setup High Temp.
+     */
+    val = ((CFG_DTT_MAX_TEMP * 2) << 7) & 0xff80;
+    if (dtt_write(sensor, DTT_TEMP_HIGH, val) != 0)
+       return 1;
+    udelay(50000);                             /* Max 50ms */
+
+    /*
+     * Setup Low Temp - hysteresis.
+     */
+    val = (((CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
+    if (dtt_write(sensor, DTT_TEMP_LOW, val) != 0)
+       return 1;
+    udelay(50000);                             /* Max 50ms */
+
+    /*
+     * Setup configuraton register
+     *
+     * Clear THF & TLF, Reserved = 1, Polarity = Active Low, One Shot = YES
+     *
+     * We run in polled mode, since there isn't any way to know if this
+     * lousy device is ready to provide temperature readings on power up.
+     */
+    val = 0x9;
+    if (dtt_write(sensor, DTT_CONFIG, val) != 0)
+       return 1;
+    udelay(50000);                             /* Max 50ms */
+
+    return 0;
+} /* _dtt_init() */
+
+
+int dtt_init (void)
+{
+    int i;
+    unsigned char sensors[] = CONFIG_DTT_SENSORS;
+
+    for (i = 0; i < sizeof(sensors); i++) {
+       if (_dtt_init(sensors[i]) != 0)
+           printf("DTT%d:  FAILED\n", i+1);
+       else
+           printf("DTT%d:  %i C\n", i+1, dtt_get_temp(sensors[i]));
+    }
+
+    return (0);
+} /* dtt_init() */
+
+
+int dtt_get_temp(int sensor)
+{
+    int i;
+
+    /*
+     * Start a conversion, may take up to 1 second.
+     */
+    dtt_write(sensor, DTT_WRITE_START_CONV, 0);
+    for (i = 0; i <= 10; i++) {
+       udelay(100000);
+       if (dtt_read(sensor, DTT_CONFIG) & 0x80)
+           break;
+    }
+
+    return (dtt_read(sensor, DTT_READ_TEMP) / 256);
+} /* dtt_get_temp() */
+
+
+#endif /* CONFIG_DTT_DS1621 */
diff --git a/drivers/hwmon/ds1722.c b/drivers/hwmon/ds1722.c
new file mode 100644 (file)
index 0000000..c19ee01
--- /dev/null
@@ -0,0 +1,142 @@
+
+#include <common.h>
+
+#ifdef CONFIG_DS1722
+
+#include <ssi.h>
+
+static void ds1722_select(int dev)
+{
+       ssi_set_interface(4096, 0, 0, 0);
+       ssi_chip_select(0);
+       udelay(1);
+       ssi_chip_select(dev);
+       udelay(1);
+}
+
+
+u8 ds1722_read(int dev, int addr)
+{
+       u8 res;
+
+       ds1722_select(dev);
+
+       ssi_tx_byte(addr);
+       res = ssi_rx_byte();
+
+       ssi_chip_select(0);
+
+       return res;
+}
+
+void ds1722_write(int dev, int addr, u8 data)
+{
+       ds1722_select(dev);
+
+       ssi_tx_byte(0x80|addr);
+       ssi_tx_byte(data);
+
+       ssi_chip_select(0);
+}
+
+
+u16 ds1722_temp(int dev, int resolution)
+{
+       static int useconds[] = {
+               75000, 150000, 300000, 600000, 1200000
+       };
+       char temp;
+       u16 res;
+
+
+       /* set up the desired resulotion ... */
+       ds1722_write(dev, 0, 0xe0 | (resolution << 1));
+
+       /* wait while the chip measures the tremperature */
+       udelay(useconds[resolution]);
+
+       res = (temp = ds1722_read(dev, 2)) << 8;
+
+       if (temp < 0) {
+               temp = (16 - (ds1722_read(dev, 1) >> 4)) & 0x0f;
+       } else {
+               temp = (ds1722_read(dev, 1) >> 4);
+       }
+
+       switch (temp) {
+       case 0:
+               /* .0000 */
+               break;
+       case 1:
+               /* .0625 */
+               res |=1;
+               break;
+       case 2:
+               /* .1250 */
+               res |=1;
+               break;
+       case 3:
+               /* .1875 */
+               res |=2;
+               break;
+       case 4:
+               /* .2500 */
+               res |=3;
+               break;
+       case 5:
+               /* .3125 */
+               res |=3;
+               break;
+       case 6:
+               /* .3750 */
+               res |=4;
+               break;
+       case 7:
+               /* .4375 */
+               res |=4;
+               break;
+       case 8:
+               /* .5000 */
+               res |=5;
+               break;
+       case 9:
+               /* .5625 */
+               res |=6;
+               break;
+       case 10:
+               /* .6250 */
+               res |=6;
+               break;
+       case 11:
+               /* .6875 */
+               res |=7;
+               break;
+       case 12:
+               /* .7500 */
+               res |=8;
+               break;
+       case 13:
+               /* .8125 */
+               res |=8;
+               break;
+       case 14:
+               /* .8750 */
+               res |=9;
+               break;
+       case 15:
+               /* .9375 */
+               res |=9;
+               break;
+       }
+       return res;
+
+}
+
+int ds1722_probe(int dev)
+{
+       u16 temp = ds1722_temp(dev, DS1722_RESOLUTION_12BIT);
+       printf("%d.%d deg C\n\n", (char)(temp >> 8), temp & 0xff);
+       return 0;
+}
+
+#endif
diff --git a/drivers/hwmon/ds1775.c b/drivers/hwmon/ds1775.c
new file mode 100644 (file)
index 0000000..0fbb0b4
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Dallas Semiconductor's DS1775 Digital Thermometer and Thermostat
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_DS1775
+#include <i2c.h>
+#include <dtt.h>
+
+#define DTT_I2C_DEV_CODE       CFG_I2C_DTT_ADDR /* Dallas Semi's DS1775 device code */
+
+int dtt_read(int sensor, int reg)
+{
+       int dlen;
+       uchar data[2];
+
+       /*
+        * Calculate sensor address and command
+        */
+       sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* Calculate addr of ds1775 */
+
+       /*
+        * Prepare to handle 2 byte result
+        */
+       if ((reg == DTT_READ_TEMP) ||
+           (reg == DTT_TEMP_OS) || (reg == DTT_TEMP_HYST))
+               dlen = 2;
+       else
+               dlen = 1;
+
+       /*
+        * Now try to read the register
+        */
+       if (i2c_read(sensor, reg, 1, data, dlen) != 0)
+               return 1;
+
+       /*
+        * Handle 2 byte result
+        */
+       if (dlen == 2)
+               return ((int)((short)data[1] + (((short)data[0]) << 8)));
+
+       return (int) data[0];
+}
+
+
+int dtt_write(int sensor, int reg, int val)
+{
+       int dlen;
+       uchar data[2];
+
+       /*
+        * Calculate sensor address and register
+        */
+       sensor = DTT_I2C_DEV_CODE + (sensor & 0x07);
+
+       /*
+        * Handle various data sizes
+        */
+       if ((reg == DTT_READ_TEMP) ||
+           (reg == DTT_TEMP_OS) || (reg == DTT_TEMP_HYST)) {
+               dlen = 2;
+               data[0] = (char)((val >> 8) & 0xff); /* MSB first */
+               data[1] = (char)(val & 0xff);
+       } else {
+               dlen = 1;
+               data[0] = (char)(val & 0xff);
+       }
+
+       /*
+        * Write value to device
+        */
+       if (i2c_write(sensor, reg, 1, data, dlen) != 0)
+               return 1;
+
+       return 0;
+}
+
+
+static int _dtt_init(int sensor)
+{
+       int val;
+
+       /*
+        * Setup High Temp
+        */
+       val = ((CFG_DTT_MAX_TEMP * 2) << 7) & 0xff80;
+       if (dtt_write(sensor, DTT_TEMP_OS, val) != 0)
+               return 1;
+       udelay(50000);                  /* Max 50ms */
+
+       /*
+        * Setup Low Temp - hysteresis
+        */
+       val = (((CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
+       if (dtt_write(sensor, DTT_TEMP_HYST, val) != 0)
+               return 1;
+       udelay(50000);                  /* Max 50ms */
+
+       /*
+        * Setup configuraton register
+        *
+        * Fault Tolerance limits 4, Thermometer resolution bits is 9,
+        * Polarity = Active Low,continuous conversion mode, Thermostat
+        * mode is interrupt mode
+        */
+       val = 0xa;
+       if (dtt_write(sensor, DTT_CONFIG, val) != 0)
+               return 1;
+       udelay(50000);                  /* Max 50ms */
+
+       return 0;
+}
+
+
+int dtt_init (void)
+{
+       int i;
+       unsigned char sensors[] = CONFIG_DTT_SENSORS;
+
+       for (i = 0; i < sizeof(sensors); i++) {
+               if (_dtt_init(sensors[i]) != 0)
+                       printf("DTT%d:  FAILED\n", i+1);
+               else
+                       printf("DTT%d:  %i C\n", i+1, dtt_get_temp(sensors[i]));
+       }
+
+       return (0);
+}
+
+
+int dtt_get_temp(int sensor)
+{
+       return (dtt_read(sensor, DTT_READ_TEMP) / 256);
+}
+
+
+#endif /* CONFIG_DTT_DS1775 */
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
new file mode 100644 (file)
index 0000000..63f3b75
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * (C) Copyright 2001
+ * Bill Hunter,  Wave 7 Optics, williamhunter@mediaone.net
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * On Semiconductor's LM75 Temperature Sensor
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_LM75
+#if !defined(CFG_EEPROM_PAGE_WRITE_ENABLE) || \
+       (CFG_EEPROM_PAGE_WRITE_BITS < 1)
+# error "CFG_EEPROM_PAGE_WRITE_ENABLE must be defined and CFG_EEPROM_PAGE_WRITE_BITS must be greater than  1 to use CONFIG_DTT_LM75"
+#endif
+
+#include <i2c.h>
+#include <dtt.h>
+
+
+/*
+ * Device code
+ */
+#define DTT_I2C_DEV_CODE 0x48                  /* ON Semi's LM75 device */
+
+int dtt_read(int sensor, int reg)
+{
+    int dlen;
+    uchar data[2];
+
+    /*
+     * Validate 'reg' param
+     */
+    if((reg < 0) || (reg > 3))
+       return -1;
+
+    /*
+     * Calculate sensor address and register.
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* calculate address of lm75 */
+
+    /*
+     * Prepare to handle 2 byte result.
+     */
+    if ((reg == DTT_READ_TEMP) ||
+       (reg == DTT_TEMP_HYST) ||
+       (reg == DTT_TEMP_SET))
+       dlen = 2;
+    else
+       dlen = 1;
+
+    /*
+     * Now try to read the register.
+     */
+    if (i2c_read(sensor, reg, 1, data, dlen) != 0)
+       return -1;
+
+    /*
+     * Handle 2 byte result.
+     */
+    if (dlen == 2)
+       return ((int)((short)data[1] + (((short)data[0]) << 8)));
+
+
+    return (int)data[0];
+} /* dtt_read() */
+
+
+int dtt_write(int sensor, int reg, int val)
+{
+    int dlen;
+    uchar data[2];
+
+    /*
+     * Validate 'reg' param
+     */
+    if ((reg < 0) || (reg > 3))
+       return 1;
+
+    /*
+     * Calculate sensor address and register.
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* calculate address of lm75 */
+
+    /*
+     * Handle 2 byte values.
+     */
+    if ((reg == DTT_READ_TEMP) ||
+       (reg == DTT_TEMP_HYST) ||
+       (reg == DTT_TEMP_SET)) {
+       dlen = 2;
+       data[0] = (char)((val >> 8) & 0xff);    /* MSB first */
+       data[1] = (char)(val & 0xff);
+    } else {
+       dlen = 1;
+       data[0] = (char)(val & 0xff);
+    }
+
+    /*
+     * Write value to register.
+     */
+    if (i2c_write(sensor, reg, 1, data, dlen) != 0)
+       return 1;
+
+    return 0;
+} /* dtt_write() */
+
+
+static int _dtt_init(int sensor)
+{
+    int val;
+
+    /*
+     * Setup TSET ( trip point ) register
+     */
+    val = ((CFG_DTT_MAX_TEMP * 2) << 7) & 0xff80; /* trip */
+    if (dtt_write(sensor, DTT_TEMP_SET, val) != 0)
+       return 1;
+
+    /*
+     * Setup THYST ( untrip point ) register - Hysteresis
+     */
+    val = (((CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
+    if (dtt_write(sensor, DTT_TEMP_HYST, val) != 0)
+       return 1;
+
+    /*
+     * Setup configuraton register
+     */
+#ifdef CONFIG_DTT_AD7414
+    /* config = alert active low and disabled */
+    val = 0x60;
+#else
+    /* config = 6 sample integration, int mode, active low, and enable */
+    val = 0x18;
+#endif
+    if (dtt_write(sensor, DTT_CONFIG, val) != 0)
+       return 1;
+
+    return 0;
+} /* _dtt_init() */
+
+
+int dtt_init (void)
+{
+    int i;
+    unsigned char sensors[] = CONFIG_DTT_SENSORS;
+    const char *const header = "DTT:   ";
+
+    for (i = 0; i < sizeof(sensors); i++) {
+       if (_dtt_init(sensors[i]) != 0)
+           printf("%s%d FAILED INIT\n", header, i+1);
+       else
+           printf("%s%d is %i C\n", header, i+1,
+                  dtt_get_temp(sensors[i]));
+    }
+
+    return (0);
+} /* dtt_init() */
+
+int dtt_get_temp(int sensor)
+{
+    return (dtt_read(sensor, DTT_READ_TEMP) / 256);
+} /* dtt_get_temp() */
+
+#endif /* CONFIG_DTT_LM75 */
diff --git a/drivers/hwmon/lm81.c b/drivers/hwmon/lm81.c
new file mode 100644 (file)
index 0000000..03bc53d
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * (C) Copyright 2006
+ * Heiko Schocher, DENX Software Enginnering <hs@denx.de>
+ *
+ * based on dtt/lm75.c which is ...
+ *
+ * (C) Copyright 2001
+ * Bill Hunter,  Wave 7 Optics, williamhunter@mediaone.net
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * On Semiconductor's LM81 Temperature Sensor
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_LM81
+#if !defined(CFG_EEPROM_PAGE_WRITE_ENABLE) || \
+       (CFG_EEPROM_PAGE_WRITE_BITS < 1)
+# error "CFG_EEPROM_PAGE_WRITE_ENABLE must be defined and CFG_EEPROM_PAGE_WRITE_BITS must be greater than  1 to use CONFIG_DTT_LM81"
+#endif
+
+#include <i2c.h>
+#include <dtt.h>
+
+/*
+ * Device code
+ */
+#define DTT_I2C_DEV_CODE 0x2c                  /* ON Semi's LM81 device */
+
+int dtt_read(int sensor, int reg)
+{
+    int dlen = 1;
+    uchar data[2];
+
+    /*
+     * Calculate sensor address and register.
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x03); /* calculate address of lm81 */
+
+    /*
+     * Now try to read the register.
+     */
+    if (i2c_read(sensor, reg, 1, data, dlen) != 0)
+       return -1;
+
+    return (int)data[0];
+} /* dtt_read() */
+
+
+int dtt_write(int sensor, int reg, int val)
+{
+    uchar data;
+
+    /*
+     * Calculate sensor address and register.
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x03); /* calculate address of lm81 */
+
+    data = (char)(val & 0xff);
+
+    /*
+     * Write value to register.
+     */
+    if (i2c_write(sensor, reg, 1, &data, 1) != 0)
+       return 1;
+
+    return 0;
+} /* dtt_write() */
+
+#define DTT_MANU       0x3e
+#define DTT_REV                0x3f
+#define DTT_CONFIG     0x40
+#define DTT_ADR                0x48
+
+static int _dtt_init(int sensor)
+{
+       int     man;
+       int     adr;
+       int     rev;
+
+       if (dtt_write (sensor, DTT_CONFIG, 0x01) < 0)
+               return 1;
+       /* The LM81 needs 400ms to get the correct values ... */
+       udelay (400000);
+       man = dtt_read (sensor, DTT_MANU);
+       if (man != 0x01)
+               return 1;
+       adr = dtt_read (sensor, DTT_ADR);
+       if (adr < 0)
+               return 1;
+       rev = dtt_read (sensor, DTT_REV);
+       if (adr < 0)
+               return 1;
+
+       printf ("DTT:   Found LM81@%x Rev: %d\n", adr, rev);
+       return 0;
+} /* _dtt_init() */
+
+
+int dtt_init (void)
+{
+    int i;
+    unsigned char sensors[] = CONFIG_DTT_SENSORS;
+    const char *const header = "DTT:   ";
+
+    for (i = 0; i < sizeof(sensors); i++) {
+       if (_dtt_init(sensors[i]) != 0)
+           printf("%s%d FAILED INIT\n", header, i+1);
+       else
+           printf("%s%d is %i C\n", header, i+1,
+                  dtt_get_temp(sensors[i]));
+    }
+
+    return (0);
+} /* dtt_init() */
+
+#define TEMP_FROM_REG(temp) \
+   ((temp)<256?((((temp)&0x1fe) >> 1) * 10)     + ((temp) & 1) * 5:  \
+              ((((temp)&0x1fe) >> 1) -255) * 10 - ((temp) & 1) * 5)  \
+
+int dtt_get_temp(int sensor)
+{
+       int val = dtt_read (sensor, DTT_READ_TEMP);
+       int tmpcnf = dtt_read (sensor, DTT_CONFIG_TEMP);
+
+       return (TEMP_FROM_REG((val << 1) + ((tmpcnf & 0x80) >> 7))) / 10;
+} /* dtt_get_temp() */
+
+#endif /* CONFIG_DTT_LM81 */
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
new file mode 100644 (file)
index 0000000..29d6c03
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libi2c.a
+
+COBJS-y += fsl_i2c.o
+COBJS-y += omap1510_i2c.o
+COBJS-y += omap24xx_i2c.o
+COBJS-y += tsi108_i2c.o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c
new file mode 100644 (file)
index 0000000..22485ea
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+ * Copyright 2006 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * Version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_FSL_I2C
+#ifdef CONFIG_HARD_I2C
+
+#include <command.h>
+#include <i2c.h>               /* Functional interface */
+
+#include <asm/io.h>
+#include <asm/fsl_i2c.h>       /* HW definitions */
+
+#define I2C_TIMEOUT    (CFG_HZ / 4)
+
+#define I2C_READ_BIT  1
+#define I2C_WRITE_BIT 0
+
+/* Initialize the bus pointer to whatever one the SPD EEPROM is on.
+ * Default is bus 0.  This is necessary because the DDR initialization
+ * runs from ROM, and we can't switch buses because we can't modify
+ * the global variables.
+ */
+#ifdef CFG_SPD_BUS_NUM
+static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = CFG_SPD_BUS_NUM;
+#else
+static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = 0;
+#endif
+
+static volatile struct fsl_i2c *i2c_dev[2] = {
+       (struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET),
+#ifdef CFG_I2C2_OFFSET
+       (struct fsl_i2c *) (CFG_IMMR + CFG_I2C2_OFFSET)
+#endif
+};
+
+void
+i2c_init(int speed, int slaveadd)
+{
+       volatile struct fsl_i2c *dev;
+
+       dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET);
+
+       writeb(0, &dev->cr);                    /* stop I2C controller */
+       udelay(5);                              /* let it shutdown in peace */
+       writeb(0x3F, &dev->fdr);                /* set bus speed */
+       writeb(0x3F, &dev->dfsrr);              /* set default filter */
+       writeb(slaveadd << 1, &dev->adr);       /* write slave address */
+       writeb(0x0, &dev->sr);                  /* clear status register */
+       writeb(I2C_CR_MEN, &dev->cr);           /* start I2C controller */
+
+#ifdef CFG_I2C2_OFFSET
+       dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C2_OFFSET);
+
+       writeb(0, &dev->cr);                    /* stop I2C controller */
+       udelay(5);                              /* let it shutdown in peace */
+       writeb(0x3F, &dev->fdr);                /* set bus speed */
+       writeb(0x3F, &dev->dfsrr);              /* set default filter */
+       writeb(slaveadd << 1, &dev->adr);       /* write slave address */
+       writeb(0x0, &dev->sr);                  /* clear status register */
+       writeb(I2C_CR_MEN, &dev->cr);           /* start I2C controller */
+#endif /* CFG_I2C2_OFFSET */
+}
+
+static __inline__ int
+i2c_wait4bus(void)
+{
+       ulong timeval = get_timer(0);
+
+       while (readb(&i2c_dev[i2c_bus_num]->sr) & I2C_SR_MBB) {
+               if (get_timer(timeval) > I2C_TIMEOUT) {
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+static __inline__ int
+i2c_wait(int write)
+{
+       u32 csr;
+       ulong timeval = get_timer(0);
+
+       do {
+               csr = readb(&i2c_dev[i2c_bus_num]->sr);
+               if (!(csr & I2C_SR_MIF))
+                       continue;
+
+               writeb(0x0, &i2c_dev[i2c_bus_num]->sr);
+
+               if (csr & I2C_SR_MAL) {
+                       debug("i2c_wait: MAL\n");
+                       return -1;
+               }
+
+               if (!(csr & I2C_SR_MCF))        {
+                       debug("i2c_wait: unfinished\n");
+                       return -1;
+               }
+
+               if (write == I2C_WRITE_BIT && (csr & I2C_SR_RXAK)) {
+                       debug("i2c_wait: No RXACK\n");
+                       return -1;
+               }
+
+               return 0;
+       } while (get_timer (timeval) < I2C_TIMEOUT);
+
+       debug("i2c_wait: timed out\n");
+       return -1;
+}
+
+static __inline__ int
+i2c_write_addr (u8 dev, u8 dir, int rsta)
+{
+       writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX
+              | (rsta ? I2C_CR_RSTA : 0),
+              &i2c_dev[i2c_bus_num]->cr);
+
+       writeb((dev << 1) | dir, &i2c_dev[i2c_bus_num]->dr);
+
+       if (i2c_wait(I2C_WRITE_BIT) < 0)
+               return 0;
+
+       return 1;
+}
+
+static __inline__ int
+__i2c_write(u8 *data, int length)
+{
+       int i;
+
+       writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX,
+              &i2c_dev[i2c_bus_num]->cr);
+
+       for (i = 0; i < length; i++) {
+               writeb(data[i], &i2c_dev[i2c_bus_num]->dr);
+
+               if (i2c_wait(I2C_WRITE_BIT) < 0)
+                       break;
+       }
+
+       return i;
+}
+
+static __inline__ int
+__i2c_read(u8 *data, int length)
+{
+       int i;
+
+       writeb(I2C_CR_MEN | I2C_CR_MSTA | ((length == 1) ? I2C_CR_TXAK : 0),
+              &i2c_dev[i2c_bus_num]->cr);
+
+       /* dummy read */
+       readb(&i2c_dev[i2c_bus_num]->dr);
+
+       for (i = 0; i < length; i++) {
+               if (i2c_wait(I2C_READ_BIT) < 0)
+                       break;
+
+               /* Generate ack on last next to last byte */
+               if (i == length - 2)
+                       writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_TXAK,
+                              &i2c_dev[i2c_bus_num]->cr);
+
+               /* Generate stop on last byte */
+               if (i == length - 1)
+                       writeb(I2C_CR_MEN | I2C_CR_TXAK, &i2c_dev[i2c_bus_num]->cr);
+
+               data[i] = readb(&i2c_dev[i2c_bus_num]->dr);
+       }
+
+       return i;
+}
+
+int
+i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
+{
+       int i = -1; /* signal error */
+       u8 *a = (u8*)&addr;
+
+       if (i2c_wait4bus() >= 0
+           && i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0
+           && __i2c_write(&a[4 - alen], alen) == alen)
+               i = 0; /* No error so far */
+
+       if (length
+           && i2c_write_addr(dev, I2C_READ_BIT, 1) != 0)
+               i = __i2c_read(data, length);
+
+       writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
+
+       if (i == length)
+           return 0;
+
+       return -1;
+}
+
+int
+i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
+{
+       int i = -1; /* signal error */
+       u8 *a = (u8*)&addr;
+
+       if (i2c_wait4bus() >= 0
+           && i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0
+           && __i2c_write(&a[4 - alen], alen) == alen) {
+               i = __i2c_write(data, length);
+       }
+
+       writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
+
+       if (i == length)
+           return 0;
+
+       return -1;
+}
+
+int
+i2c_probe(uchar chip)
+{
+       /* For unknow reason the controller will ACK when
+        * probing for a slave with the same address, so skip
+        * it.
+        */
+       if (chip == (readb(&i2c_dev[i2c_bus_num]->adr) >> 1))
+               return -1;
+
+       return i2c_read(chip, 0, 0, NULL, 0);
+}
+
+uchar
+i2c_reg_read(uchar i2c_addr, uchar reg)
+{
+       uchar buf[1];
+
+       i2c_read(i2c_addr, reg, 1, buf, 1);
+
+       return buf[0];
+}
+
+void
+i2c_reg_write(uchar i2c_addr, uchar reg, uchar val)
+{
+       i2c_write(i2c_addr, reg, 1, &val, 1);
+}
+
+int i2c_set_bus_num(unsigned int bus)
+{
+#ifdef CFG_I2C2_OFFSET
+       if (bus > 1) {
+#else
+       if (bus > 0) {
+#endif
+               return -1;
+       }
+
+       i2c_bus_num = bus;
+
+       return 0;
+}
+
+int i2c_set_bus_speed(unsigned int speed)
+{
+       return -1;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+       return i2c_bus_num;
+}
+
+unsigned int i2c_get_bus_speed(void)
+{
+       return 0;
+}
+#endif /* CONFIG_HARD_I2C */
+#endif /* CONFIG_FSL_I2C */
diff --git a/drivers/i2c/omap1510_i2c.c b/drivers/i2c/omap1510_i2c.c
new file mode 100644 (file)
index 0000000..04400fb
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ * Basic I2C functions
+ *
+ * Copyright (c) 2003 Texas Instruments
+ *
+ * This package is free software;  you can redistribute it and/or
+ * modify it under the terms of the license found in the file
+ * named COPYING that should have accompanied this file.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author: Jian Zhang jzhang@ti.com, Texas Instruments
+ *
+ * Copyright (c) 2003 Wolfgang Denk, wd@denx.de
+ * Rewritten to fit into the current U-Boot framework
+ *
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DRIVER_OMAP1510_I2C
+
+static void wait_for_bb (void);
+static u16 wait_for_pin (void);
+
+void i2c_init (int speed, int slaveadd)
+{
+       u16 scl;
+
+       if (inw (I2C_CON) & I2C_CON_EN) {
+               outw (0, I2C_CON);
+               udelay (5000);
+       }
+
+       /* 12Mhz I2C module clock */
+       outw (0, I2C_PSC);
+       outw (I2C_CON_EN, I2C_CON);
+       outw (0, I2C_SYSTEST);
+       /* have to enable intrrupts or OMAP i2c module doesn't work */
+       outw (I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
+             I2C_IE_NACK_IE | I2C_IE_AL_IE, I2C_IE);
+       scl = (12000000 / 2) / speed - 6;
+       outw (scl, I2C_SCLL);
+       outw (scl, I2C_SCLH);
+       /* own address */
+       outw (slaveadd, I2C_OA);
+       outw (0, I2C_CNT);
+       udelay (1000);
+}
+
+static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
+{
+       int i2c_error = 0;
+       u16 status;
+
+       /* wait until bus not busy */
+       wait_for_bb ();
+
+       /* one byte only */
+       outw (1, I2C_CNT);
+       /* set slave address */
+       outw (devaddr, I2C_SA);
+       /* no stop bit needed here */
+       outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON);
+
+       status = wait_for_pin ();
+
+       if (status & I2C_STAT_XRDY) {
+               /* Important: have to use byte access */
+               *(volatile u8 *) (I2C_DATA) = regoffset;
+               udelay (20000);
+               if (inw (I2C_STAT) & I2C_STAT_NACK) {
+                       i2c_error = 1;
+               }
+       } else {
+               i2c_error = 1;
+       }
+
+       if (!i2c_error) {
+               /* free bus, otherwise we can't use a combined transction */
+               outw (0, I2C_CON);
+               while (inw (I2C_STAT) || (inw (I2C_CON) & I2C_CON_MST)) {
+                       udelay (10000);
+                       /* Have to clear pending interrupt to clear I2C_STAT */
+                       inw (I2C_IV);
+               }
+
+               wait_for_bb ();
+               /* set slave address */
+               outw (devaddr, I2C_SA);
+               /* read one byte from slave */
+               outw (1, I2C_CNT);
+               /* need stop bit here */
+               outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP,
+                     I2C_CON);
+
+               status = wait_for_pin ();
+               if (status & I2C_STAT_RRDY) {
+                       *value = inw (I2C_DATA);
+                       udelay (20000);
+               } else {
+                       i2c_error = 1;
+               }
+
+               if (!i2c_error) {
+                       outw (I2C_CON_EN, I2C_CON);
+                       while (inw (I2C_STAT)
+                              || (inw (I2C_CON) & I2C_CON_MST)) {
+                               udelay (10000);
+                               inw (I2C_IV);
+                       }
+               }
+       }
+
+       return i2c_error;
+}
+
+static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value)
+{
+       int i2c_error = 0;
+       u16 status;
+
+       /* wait until bus not busy */
+       wait_for_bb ();
+
+       /* two bytes */
+       outw (2, I2C_CNT);
+       /* set slave address */
+       outw (devaddr, I2C_SA);
+       /* stop bit needed here */
+       outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
+             I2C_CON_STP, I2C_CON);
+
+       /* wait until state change */
+       status = wait_for_pin ();
+
+       if (status & I2C_STAT_XRDY) {
+               /* send out two bytes */
+               outw ((value << 8) + regoffset, I2C_DATA);
+               /* must have enough delay to allow BB bit to go low */
+               udelay (30000);
+               if (inw (I2C_STAT) & I2C_STAT_NACK) {
+                       i2c_error = 1;
+               }
+       } else {
+               i2c_error = 1;
+       }
+
+       if (!i2c_error) {
+               outw (I2C_CON_EN, I2C_CON);
+               while (inw (I2C_STAT) || (inw (I2C_CON) & I2C_CON_MST)) {
+                       udelay (1000);
+                       /* have to read to clear intrrupt */
+                       inw (I2C_IV);
+               }
+       }
+
+       return i2c_error;
+}
+
+int i2c_probe (uchar chip)
+{
+       int res = 1;
+
+       if (chip == inw (I2C_OA)) {
+               return res;
+       }
+
+       /* wait until bus not busy */
+       wait_for_bb ();
+
+       /* try to read one byte */
+       outw (1, I2C_CNT);
+       /* set slave address */
+       outw (chip, I2C_SA);
+       /* stop bit needed here */
+       outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON);
+       /* enough delay for the NACK bit set */
+       udelay (2000);
+       if (!(inw (I2C_STAT) & I2C_STAT_NACK)) {
+               res = 0;
+       } else {
+               outw (inw (I2C_CON) | I2C_CON_STP, I2C_CON);
+               udelay (20);
+               wait_for_bb ();
+       }
+
+       return res;
+}
+
+int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+       int i;
+
+       if (alen > 1) {
+               printf ("I2C read: addr len %d not supported\n", alen);
+               return 1;
+       }
+
+       if (addr + len > 256) {
+               printf ("I2C read: address out of range\n");
+               return 1;
+       }
+
+       for (i = 0; i < len; i++) {
+               if (i2c_read_byte (chip, addr + i, &buffer[i])) {
+                       printf ("I2C read: I/O error\n");
+                       i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+       int i;
+
+       if (alen > 1) {
+               printf ("I2C read: addr len %d not supported\n", alen);
+               return 1;
+       }
+
+       if (addr + len > 256) {
+               printf ("I2C read: address out of range\n");
+               return 1;
+       }
+
+       for (i = 0; i < len; i++) {
+               if (i2c_write_byte (chip, addr + i, buffer[i])) {
+                       printf ("I2C read: I/O error\n");
+                       i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static void wait_for_bb (void)
+{
+       int timeout = 10;
+
+       while ((inw (I2C_STAT) & I2C_STAT_BB) && timeout--) {
+               inw (I2C_IV);
+               udelay (1000);
+       }
+
+       if (timeout <= 0) {
+               printf ("timed out in wait_for_bb: I2C_STAT=%x\n",
+                       inw (I2C_STAT));
+       }
+}
+
+static u16 wait_for_pin (void)
+{
+       u16 status, iv;
+       int timeout = 10;
+
+       do {
+               udelay (1000);
+               status = inw (I2C_STAT);
+               iv = inw (I2C_IV);
+       } while (!iv &&
+                !(status &
+                  (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
+                   I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
+                   I2C_STAT_AL)) && timeout--);
+
+       if (timeout <= 0) {
+               printf ("timed out in wait_for_pin: I2C_STAT=%x\n",
+                       inw (I2C_STAT));
+       }
+
+       return status;
+}
+
+#endif /* CONFIG_DRIVER_OMAP1510_I2C */
diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
new file mode 100644 (file)
index 0000000..7dab786
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ * Basic I2C functions
+ *
+ * Copyright (c) 2004 Texas Instruments
+ *
+ * This package is free software;  you can redistribute it and/or
+ * modify it under the terms of the license found in the file
+ * named COPYING that should have accompanied this file.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author: Jian Zhang jzhang@ti.com, Texas Instruments
+ *
+ * Copyright (c) 2003 Wolfgang Denk, wd@denx.de
+ * Rewritten to fit into the current U-Boot framework
+ *
+ * Adapted for OMAP2420 I2C, r-woodruff2@ti.com
+ *
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DRIVER_OMAP24XX_I2C
+
+#include <asm/arch/i2c.h>
+#include <asm/io.h>
+
+#define inw(a) __raw_readw(a)
+#define outw(a,v) __raw_writew(a,v)
+
+static void wait_for_bb (void);
+static u16 wait_for_pin (void);
+static void flush_fifo(void);
+
+void i2c_init (int speed, int slaveadd)
+{
+       u16 scl;
+
+       outw(0x2, I2C_SYSC); /* for ES2 after soft reset */
+       udelay(1000);
+       outw(0x0, I2C_SYSC); /* will probably self clear but */
+
+       if (inw (I2C_CON) & I2C_CON_EN) {
+               outw (0, I2C_CON);
+               udelay (50000);
+       }
+
+       /* 12Mhz I2C module clock */
+       outw (0, I2C_PSC);
+       speed = speed/1000;                 /* 100 or 400 */
+       scl = ((12000/(speed*2)) - 7);  /* use 7 when PSC = 0 */
+       outw (scl, I2C_SCLL);
+       outw (scl, I2C_SCLH);
+       /* own address */
+       outw (slaveadd, I2C_OA);
+       outw (I2C_CON_EN, I2C_CON);
+
+       /* have to enable intrrupts or OMAP i2c module doesn't work */
+       outw (I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
+             I2C_IE_NACK_IE | I2C_IE_AL_IE, I2C_IE);
+       udelay (1000);
+       flush_fifo();
+       outw (0xFFFF, I2C_STAT);
+       outw (0, I2C_CNT);
+}
+
+static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
+{
+       int i2c_error = 0;
+       u16 status;
+
+       /* wait until bus not busy */
+       wait_for_bb ();
+
+       /* one byte only */
+       outw (1, I2C_CNT);
+       /* set slave address */
+       outw (devaddr, I2C_SA);
+       /* no stop bit needed here */
+       outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON);
+
+       status = wait_for_pin ();
+
+       if (status & I2C_STAT_XRDY) {
+               /* Important: have to use byte access */
+               *(volatile u8 *) (I2C_DATA) = regoffset;
+               udelay (20000);
+               if (inw (I2C_STAT) & I2C_STAT_NACK) {
+                       i2c_error = 1;
+               }
+       } else {
+               i2c_error = 1;
+       }
+
+       if (!i2c_error) {
+               /* free bus, otherwise we can't use a combined transction */
+               outw (0, I2C_CON);
+               while (inw (I2C_STAT) || (inw (I2C_CON) & I2C_CON_MST)) {
+                       udelay (10000);
+                       /* Have to clear pending interrupt to clear I2C_STAT */
+                       outw (0xFFFF, I2C_STAT);
+               }
+
+               wait_for_bb ();
+               /* set slave address */
+               outw (devaddr, I2C_SA);
+               /* read one byte from slave */
+               outw (1, I2C_CNT);
+               /* need stop bit here */
+               outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP,
+                     I2C_CON);
+
+               status = wait_for_pin ();
+               if (status & I2C_STAT_RRDY) {
+                       *value = inw (I2C_DATA);
+                       udelay (20000);
+               } else {
+                       i2c_error = 1;
+               }
+
+               if (!i2c_error) {
+                       outw (I2C_CON_EN, I2C_CON);
+                       while (inw (I2C_STAT)
+                              || (inw (I2C_CON) & I2C_CON_MST)) {
+                               udelay (10000);
+                               outw (0xFFFF, I2C_STAT);
+                       }
+               }
+       }
+       flush_fifo();
+       outw (0xFFFF, I2C_STAT);
+       outw (0, I2C_CNT);
+       return i2c_error;
+}
+
+static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value)
+{
+       int i2c_error = 0;
+       u16 status, stat;
+
+       /* wait until bus not busy */
+       wait_for_bb ();
+
+       /* two bytes */
+       outw (2, I2C_CNT);
+       /* set slave address */
+       outw (devaddr, I2C_SA);
+       /* stop bit needed here */
+       outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
+             I2C_CON_STP, I2C_CON);
+
+       /* wait until state change */
+       status = wait_for_pin ();
+
+       if (status & I2C_STAT_XRDY) {
+               /* send out two bytes */
+               outw ((value << 8) + regoffset, I2C_DATA);
+               /* must have enough delay to allow BB bit to go low */
+               udelay (50000);
+               if (inw (I2C_STAT) & I2C_STAT_NACK) {
+                       i2c_error = 1;
+               }
+       } else {
+               i2c_error = 1;
+       }
+
+       if (!i2c_error) {
+               int eout = 200;
+
+               outw (I2C_CON_EN, I2C_CON);
+               while ((stat = inw (I2C_STAT)) || (inw (I2C_CON) & I2C_CON_MST)) {
+                       udelay (1000);
+                       /* have to read to clear intrrupt */
+                       outw (0xFFFF, I2C_STAT);
+                       if(--eout == 0) /* better leave with error than hang */
+                               break;
+               }
+       }
+       flush_fifo();
+       outw (0xFFFF, I2C_STAT);
+       outw (0, I2C_CNT);
+       return i2c_error;
+}
+
+static void flush_fifo(void)
+{      u16 stat;
+
+       /* note: if you try and read data when its not there or ready
+        * you get a bus error
+        */
+       while(1){
+               stat = inw(I2C_STAT);
+               if(stat == I2C_STAT_RRDY){
+                       inw(I2C_DATA);
+                       outw(I2C_STAT_RRDY,I2C_STAT);
+                       udelay(1000);
+               }else
+                       break;
+       }
+}
+
+int i2c_probe (uchar chip)
+{
+       int res = 1; /* default = fail */
+
+       if (chip == inw (I2C_OA)) {
+               return res;
+       }
+
+       /* wait until bus not busy */
+       wait_for_bb ();
+
+       /* try to read one byte */
+       outw (1, I2C_CNT);
+       /* set slave address */
+       outw (chip, I2C_SA);
+       /* stop bit needed here */
+       outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON);
+       /* enough delay for the NACK bit set */
+       udelay (50000);
+
+       if (!(inw (I2C_STAT) & I2C_STAT_NACK)) {
+               res = 0;      /* success case */
+               flush_fifo();
+               outw(0xFFFF, I2C_STAT);
+       } else {
+               outw(0xFFFF, I2C_STAT);  /* failue, clear sources*/
+               outw (inw (I2C_CON) | I2C_CON_STP, I2C_CON); /* finish up xfer */
+               udelay(20000);
+               wait_for_bb ();
+       }
+       flush_fifo();
+       outw (0, I2C_CNT); /* don't allow any more data in...we don't want it.*/
+       outw(0xFFFF, I2C_STAT);
+       return res;
+}
+
+int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+       int i;
+
+       if (alen > 1) {
+               printf ("I2C read: addr len %d not supported\n", alen);
+               return 1;
+       }
+
+       if (addr + len > 256) {
+               printf ("I2C read: address out of range\n");
+               return 1;
+       }
+
+       for (i = 0; i < len; i++) {
+               if (i2c_read_byte (chip, addr + i, &buffer[i])) {
+                       printf ("I2C read: I/O error\n");
+                       i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+       int i;
+
+       if (alen > 1) {
+               printf ("I2C read: addr len %d not supported\n", alen);
+               return 1;
+       }
+
+       if (addr + len > 256) {
+               printf ("I2C read: address out of range\n");
+               return 1;
+       }
+
+       for (i = 0; i < len; i++) {
+               if (i2c_write_byte (chip, addr + i, buffer[i])) {
+                       printf ("I2C read: I/O error\n");
+                       i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static void wait_for_bb (void)
+{
+       int timeout = 10;
+       u16 stat;
+
+       outw(0xFFFF, I2C_STAT);  /* clear current interruts...*/
+       while ((stat = inw (I2C_STAT) & I2C_STAT_BB) && timeout--) {
+               outw (stat, I2C_STAT);
+               udelay (50000);
+       }
+
+       if (timeout <= 0) {
+               printf ("timed out in wait_for_bb: I2C_STAT=%x\n",
+                       inw (I2C_STAT));
+       }
+       outw(0xFFFF, I2C_STAT);  /* clear delayed stuff*/
+}
+
+static u16 wait_for_pin (void)
+{
+       u16 status;
+       int timeout = 10;
+
+       do {
+               udelay (1000);
+               status = inw (I2C_STAT);
+       } while (  !(status &
+                  (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
+                   I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
+                   I2C_STAT_AL)) && timeout--);
+
+       if (timeout <= 0) {
+               printf ("timed out in wait_for_pin: I2C_STAT=%x\n",
+                       inw (I2C_STAT));
+                       outw(0xFFFF, I2C_STAT);
+}
+       return status;
+}
+
+#endif /* CONFIG_DRIVER_OMAP24XX_I2C */
diff --git a/drivers/i2c/tsi108_i2c.c b/drivers/i2c/tsi108_i2c.c
new file mode 100644 (file)
index 0000000..d6736b0
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * (C) Copyright 2004 Tundra Semiconductor Corp.
+ * Author: Alex Bounine
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+#include <common.h>
+
+#ifdef CONFIG_TSI108_I2C
+#include <tsi108.h>
+
+#if defined(CONFIG_CMD_I2C)
+
+#define I2C_DELAY      100000
+#undef  DEBUG_I2C
+
+#ifdef DEBUG_I2C
+#define DPRINT(x) printf (x)
+#else
+#define DPRINT(x)
+#endif
+
+/* All functions assume that Tsi108 I2C block is the only master on the bus */
+/* I2C read helper function */
+
+static int i2c_read_byte (
+               uint i2c_chan,  /* I2C channel number: 0 - main, 1 - SDC SPD */
+               uchar chip_addr,/* I2C device address on the bus */
+               uint byte_addr, /* Byte address within I2C device */
+               uchar * buffer  /* pointer to data buffer */
+               )
+{
+       u32 temp;
+       u32 to_count = I2C_DELAY;
+       u32 op_status = TSI108_I2C_TIMEOUT_ERR;
+       u32 chan_offset = TSI108_I2C_OFFSET;
+
+       DPRINT (("I2C read_byte() %d 0x%02x 0x%02x\n",
+               i2c_chan, chip_addr, byte_addr));
+
+       if (0 != i2c_chan)
+               chan_offset = TSI108_I2C_SDRAM_OFFSET;
+
+       /* Check if I2C operation is in progress */
+       temp = *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + I2C_CNTRL2);
+
+       if (0 == (temp & (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_WR_STATUS |
+                         I2C_CNTRL2_START))) {
+               /* Set device address and operation (read = 0) */
+               temp = (byte_addr << 16) | ((chip_addr & 0x07) << 8) |
+                   ((chip_addr >> 3) & 0x0F);
+               *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + I2C_CNTRL1) =
+                   temp;
+
+               /* Issue the read command
+                * (at this moment all other parameters are 0
+                * (size = 1 byte, lane = 0)
+                */
+
+               *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + I2C_CNTRL2) =
+                   (I2C_CNTRL2_START);
+
+               /* Wait until operation completed */
+               do {
+                       /* Read I2C operation status */
+                       temp = *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + I2C_CNTRL2);
+
+                       if (0 == (temp & (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_START))) {
+                               if (0 == (temp &
+                                    (I2C_CNTRL2_I2C_CFGERR |
+                                     I2C_CNTRL2_I2C_TO_ERR))
+                                   ) {
+                                       op_status = TSI108_I2C_SUCCESS;
+
+                                       temp = *(u32 *) (CFG_TSI108_CSR_BASE +
+                                                        chan_offset +
+                                                        I2C_RD_DATA);
+
+                                       *buffer = (u8) (temp & 0xFF);
+                               } else {
+                                       /* report HW error */
+                                       op_status = TSI108_I2C_IF_ERROR;
+
+                                       DPRINT (("I2C HW error reported: 0x%02x\n", temp));
+                               }
+
+                               break;
+                       }
+               } while (to_count--);
+       } else {
+               op_status = TSI108_I2C_IF_BUSY;
+
+               DPRINT (("I2C Transaction start failed: 0x%02x\n", temp));
+       }
+
+       DPRINT (("I2C read_byte() status: 0x%02x\n", op_status));
+       return op_status;
+}
+
+/*
+ * I2C Read interface as defined in "include/i2c.h" :
+ *   chip_addr: I2C chip address, range 0..127
+ *                  (to read from SPD channel EEPROM use (0xD0 ... 0xD7)
+ *              NOTE: The bit 7 in the chip_addr serves as a channel select.
+ *              This hack is for enabling "isdram" command on Tsi108 boards
+ *              without changes to common code. Used for I2C reads only.
+ *   byte_addr: Memory or register address within the chip
+ *   alen:      Number of bytes to use for addr (typically 1, 2 for larger
+ *              memories, 0 for register type devices with only one
+ *              register)
+ *   buffer:    Pointer to destination buffer for data to be read
+ *   len:       How many bytes to read
+ *
+ *   Returns: 0 on success, not 0 on failure
+ */
+
+int i2c_read (uchar chip_addr, uint byte_addr, int alen,
+               uchar * buffer, int len)
+{
+       u32 op_status = TSI108_I2C_PARAM_ERR;
+       u32 i2c_if = 0;
+
+       /* Hack to support second (SPD) I2C controller (SPD EEPROM read only).*/
+       if (0xD0 == (chip_addr & ~0x07)) {
+               i2c_if = 1;
+               chip_addr &= 0x7F;
+       }
+       /* Check for valid I2C address */
+       if (chip_addr <= 0x7F && (byte_addr + len) <= (0x01 << (alen * 8))) {
+               while (len--) {
+                       op_status = i2c_read_byte(i2c_if, chip_addr, byte_addr++, buffer++);
+
+                       if (TSI108_I2C_SUCCESS != op_status) {
+                               DPRINT (("I2C read_byte() failed: 0x%02x (%d left)\n", op_status, len));
+
+                               break;
+                       }
+               }
+       }
+
+       DPRINT (("I2C read() status: 0x%02x\n", op_status));
+       return op_status;
+}
+
+/* I2C write helper function */
+
+static int i2c_write_byte (uchar chip_addr,/* I2C device address on the bus */
+                         uint byte_addr, /* Byte address within I2C device */
+                         uchar * buffer  /*  pointer to data buffer */
+                         )
+{
+       u32 temp;
+       u32 to_count = I2C_DELAY;
+       u32 op_status = TSI108_I2C_TIMEOUT_ERR;
+
+       /* Check if I2C operation is in progress */
+       temp = *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET + I2C_CNTRL2);
+
+       if (0 == (temp & (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_WR_STATUS | I2C_CNTRL2_START))) {
+               /* Place data into the I2C Tx Register */
+               *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET +
+                         I2C_TX_DATA) = (u32) * buffer;
+
+               /* Set device address and operation  */
+               temp =
+                   I2C_CNTRL1_I2CWRITE | (byte_addr << 16) |
+                   ((chip_addr & 0x07) << 8) | ((chip_addr >> 3) & 0x0F);
+               *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET +
+                         I2C_CNTRL1) = temp;
+
+               /* Issue the write command (at this moment all other parameters
+                * are 0 (size = 1 byte, lane = 0)
+                */
+
+               *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET +
+                         I2C_CNTRL2) = (I2C_CNTRL2_START);
+
+               op_status = TSI108_I2C_TIMEOUT_ERR;
+
+               /* Wait until operation completed */
+               do {
+                       /* Read I2C operation status */
+                       temp = *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET + I2C_CNTRL2);
+
+                       if (0 == (temp & (I2C_CNTRL2_WR_STATUS | I2C_CNTRL2_START))) {
+                               if (0 == (temp &
+                                    (I2C_CNTRL2_I2C_CFGERR |
+                                     I2C_CNTRL2_I2C_TO_ERR))) {
+                                       op_status = TSI108_I2C_SUCCESS;
+                               } else {
+                                       /* report detected HW error */
+                                       op_status = TSI108_I2C_IF_ERROR;
+
+                                       DPRINT (("I2C HW error reported: 0x%02x\n", temp));
+                               }
+
+                               break;
+                       }
+
+               } while (to_count--);
+       } else {
+               op_status = TSI108_I2C_IF_BUSY;
+
+               DPRINT (("I2C Transaction start failed: 0x%02x\n", temp));
+       }
+
+       return op_status;
+}
+
+/*
+ * I2C Write interface as defined in "include/i2c.h" :
+ *   chip_addr: I2C chip address, range 0..127
+ *   byte_addr: Memory or register address within the chip
+ *   alen:      Number of bytes to use for addr (typically 1, 2 for larger
+ *              memories, 0 for register type devices with only one
+ *              register)
+ *   buffer:    Pointer to data to be written
+ *   len:       How many bytes to write
+ *
+ *   Returns: 0 on success, not 0 on failure
+ */
+
+int i2c_write (uchar chip_addr, uint byte_addr, int alen, uchar * buffer,
+             int len)
+{
+       u32 op_status = TSI108_I2C_PARAM_ERR;
+
+       /* Check for valid I2C address */
+       if (chip_addr <= 0x7F && (byte_addr + len) <= (0x01 << (alen * 8))) {
+               while (len--) {
+                       op_status =
+                           i2c_write_byte (chip_addr, byte_addr++, buffer++);
+
+                       if (TSI108_I2C_SUCCESS != op_status) {
+                               DPRINT (("I2C write_byte() failed: 0x%02x (%d left)\n", op_status, len));
+
+                               break;
+                       }
+               }
+       }
+
+       return op_status;
+}
+
+/*
+ * I2C interface function as defined in "include/i2c.h".
+ * Probe the given I2C chip address by reading single byte from offset 0.
+ * Returns 0 if a chip responded, not 0 on failure.
+ */
+
+int i2c_probe (uchar chip)
+{
+       u32 tmp;
+
+       /*
+        * Try to read the first location of the chip.
+        * The Tsi108 HW doesn't support sending just the chip address
+        * and checkong for an <ACK> back.
+        */
+       return i2c_read (chip, 0, 1, (uchar *)&tmp, 1);
+}
+
+#endif
+#endif /* CONFIG_TSI108_I2C */
diff --git a/drivers/i8042.c b/drivers/i8042.c
deleted file mode 100644 (file)
index 22c2a4e..0000000
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- * (C) Copyright 2002 ELTEC Elektronik AG
- * Frank Gottschling <fgottschling@eltec.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/* i8042.c - Intel 8042 keyboard driver routines */
-
-/* includes */
-
-#include <common.h>
-
-#ifdef CONFIG_I8042_KBD
-
-#ifdef CONFIG_USE_CPCIDVI
-extern u8  gt_cpcidvi_in8(u32 offset);
-extern void gt_cpcidvi_out8(u32 offset, u8 data);
-
-#define in8(a)    gt_cpcidvi_in8(a)
-#define out8(a, b) gt_cpcidvi_out8(a,b)
-#endif
-
-#include <i8042.h>
-
-/* defines */
-
-#ifdef CONFIG_CONSOLE_CURSOR
-extern void console_cursor (int state);
-static int blinkCount = CFG_CONSOLE_BLINK_COUNT;
-static int cursor_state = 0;
-#endif
-
-/* locals */
-
-static int  kbd_input   = -1;          /* no input yet */
-static int  kbd_mapping         = KBD_US;      /* default US keyboard */
-static int  kbd_flags   = NORMAL;      /* after reset */
-static int  kbd_state   = 0;           /* unshift code */
-
-static void kbd_conv_char (unsigned char scan_code);
-static void kbd_led_set (void);
-static void kbd_normal (unsigned char scan_code);
-static void kbd_shift (unsigned char scan_code);
-static void kbd_ctrl (unsigned char scan_code);
-static void kbd_num (unsigned char scan_code);
-static void kbd_caps (unsigned char scan_code);
-static void kbd_scroll (unsigned char scan_code);
-static void kbd_alt (unsigned char scan_code);
-static int  kbd_input_empty (void);
-static int  kbd_reset (void);
-
-static unsigned char kbd_fct_map [144] =
-    { /* kbd_fct_map table for scan code */
-    0,  AS,   AS,   AS,   AS,   AS,   AS,   AS, /* scan  0- 7 */
-   AS,  AS,   AS,   AS,   AS,   AS,   AS,   AS, /* scan  8- F */
-   AS,  AS,   AS,   AS,   AS,   AS,   AS,   AS, /* scan 10-17 */
-   AS,  AS,   AS,   AS,   AS,   CN,   AS,   AS, /* scan 18-1F */
-   AS,  AS,   AS,   AS,   AS,   AS,   AS,   AS, /* scan 20-27 */
-   AS,  AS,   SH,   AS,   AS,   AS,   AS,   AS, /* scan 28-2F */
-   AS,  AS,   AS,   AS,   AS,   AS,   SH,   AS, /* scan 30-37 */
-   AS,  AS,   CP,   0,    0,    0,    0,     0, /* scan 38-3F */
-    0,  0,    0,    0,    0,    NM,   ST,   ES, /* scan 40-47 */
-   ES,  ES,   ES,   ES,   ES,   ES,   ES,   ES, /* scan 48-4F */
-   ES,  ES,   ES,   ES,   0,    0,    AS,    0, /* scan 50-57 */
-    0,  0,    0,    0,    0,    0,    0,     0, /* scan 58-5F */
-    0,  0,    0,    0,    0,    0,    0,     0, /* scan 60-67 */
-    0,  0,    0,    0,    0,    0,    0,     0, /* scan 68-6F */
-   AS,  0,    0,    AS,   0,    0,    AS,    0, /* scan 70-77 */
-    0,  AS,   0,    0,    0,    AS,   0,     0, /* scan 78-7F */
-   AS,  CN,   AS,   AS,   AK,   ST,   EX,   EX, /* enhanced   */
-   AS,  EX,   EX,   AS,   EX,   AS,   EX,   EX  /* enhanced   */
-    };
-
-static unsigned char kbd_key_map [2][5][144] =
-    {
-    { /* US keyboard */
-    { /* unshift code */
-    0, 0x1b,   '1',   '2',   '3',   '4',   '5',   '6',    /* scan  0- 7 */
-  '7',  '8',   '9',   '0',   '-',   '=',  0x08,  '\t',    /* scan  8- F */
-  'q',  'w',   'e',   'r',   't',   'y',   'u',   'i',    /* scan 10-17 */
-  'o',  'p',   '[',   ']',  '\r',   CN,    'a',   's',    /* scan 18-1F */
-  'd',  'f',   'g',   'h',   'j',   'k',   'l',   ';',    /* scan 20-27 */
- '\'',  '`',   SH,   '\\',   'z',   'x',   'c',   'v',    /* scan 28-2F */
-  'b',  'n',   'm',   ',',   '.',   '/',   SH,    '*',    /* scan 30-37 */
-  ' ',  ' ',   CP,      0,     0,     0,     0,     0,    /* scan 38-3F */
-    0,    0,     0,     0,     0,   NM,    ST,    '7',    /* scan 40-47 */
-  '8',  '9',   '-',   '4',   '5',   '6',   '+',   '1',    /* scan 48-4F */
-  '2',  '3',   '0',   '.',     0,     0,     0,     0,    /* scan 50-57 */
-    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 58-5F */
-    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 60-67 */
-    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 68-6F */
-    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 70-77 */
-    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 78-7F */
-  '\r',          CN,   '/',   '*',   ' ',    ST,   'F',   'A',    /* extended */
-    0,  'D',   'C',     0,   'B',     0,    '@',  'P'     /* extended */
-    },
-    { /* shift code */
-    0, 0x1b,   '!',   '@',   '#',   '$',   '%',   '^',    /* scan  0- 7 */
-  '&',  '*',   '(',   ')',   '_',   '+',  0x08,  '\t',    /* scan  8- F */
-  'Q',  'W',   'E',   'R',   'T',   'Y',   'U',   'I',    /* scan 10-17 */
-  'O',  'P',   '{',   '}',  '\r',   CN,    'A',   'S',    /* scan 18-1F */
-  'D',  'F',   'G',   'H',   'J',   'K',   'L',   ':',    /* scan 20-27 */
-  '"',  '~',   SH,    '|',   'Z',   'X',   'C',   'V',    /* scan 28-2F */
-  'B',  'N',   'M',   '<',   '>',   '?',   SH,    '*',    /* scan 30-37 */
-  ' ',  ' ',   CP,      0,     0,     0,     0,     0,    /* scan 38-3F */
-    0,    0,     0,     0,     0,   NM,    ST,    '7',    /* scan 40-47 */
-  '8',  '9',   '-',   '4',   '5',   '6',   '+',   '1',    /* scan 48-4F */
-  '2',  '3',   '0',   '.',     0,     0,     0,     0,    /* scan 50-57 */
-    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 58-5F */
-    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 60-67 */
-    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 68-6F */
-    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 70-77 */
-    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 78-7F */
-  '\r',          CN,   '/',   '*',   ' ',    ST,   'F',   'A',    /* extended */
-    0,  'D',   'C',     0,   'B',     0,   '@',   'P'     /* extended */
-    },
-    { /* control code */
- 0xff, 0x1b,  0xff,  0x00,  0xff,  0xff,  0xff,  0xff,    /* scan  0- 7 */
- 0x1e, 0xff,  0xff,  0xff,  0x1f,  0xff,  0xff,  '\t',    /* scan  8- F */
- 0x11, 0x17,  0x05,  0x12,  0x14,  0x19,  0x15,  0x09,    /* scan 10-17 */
- 0x0f, 0x10,  0x1b,  0x1d,  '\r',   CN,   0x01,  0x13,    /* scan 18-1F */
- 0x04, 0x06,  0x07,  0x08,  0x0a,  0x0b,  0x0c,  0xff,    /* scan 20-27 */
- 0xff, 0x1c,   SH,   0xff,  0x1a,  0x18,  0x03,  0x16,    /* scan 28-2F */
- 0x02, 0x0e,  0x0d,  0xff,  0xff,  0xff,   SH,   0xff,    /* scan 30-37 */
- 0xff, 0xff,   CP,   0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 38-3F */
- 0xff, 0xff,  0xff,  0xff,  0xff,   NM,    ST,   0xff,    /* scan 40-47 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 48-4F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 50-57 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 58-5F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 60-67 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 68-6F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 70-77 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 78-7F */
-  '\r',          CN,   '/',   '*',   ' ',    ST,  0xff,  0xff,    /* extended */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff     /* extended */
-    },
-    { /* non numeric code */
-    0, 0x1b,   '1',   '2',   '3',   '4',   '5',   '6',    /* scan  0- 7 */
-  '7',  '8',   '9',   '0',   '-',   '=',  0x08,  '\t',    /* scan  8- F */
-  'q',  'w',   'e',   'r',   't',   'y',   'u',   'i',    /* scan 10-17 */
-  'o',  'p',   '[',   ']',  '\r',   CN,    'a',   's',    /* scan 18-1F */
-  'd',  'f',   'g',   'h',   'j',   'k',   'l',   ';',    /* scan 20-27 */
- '\'',  '`',   SH,   '\\',   'z',   'x',   'c',   'v',    /* scan 28-2F */
-  'b',  'n',   'm',   ',',   '.',   '/',   SH,    '*',    /* scan 30-37 */
-  ' ',  ' ',   CP,      0,     0,     0,     0,     0,    /* scan 38-3F */
-    0,    0,     0,     0,     0,   NM,    ST,    'w',    /* scan 40-47 */
-  'x',  'y',   'l',   't',   'u',   'v',   'm',   'q',    /* scan 48-4F */
-  'r',  's',   'p',   'n',     0,     0,     0,     0,    /* scan 50-57 */
-    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 58-5F */
-    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 60-67 */
-    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 68-6F */
-    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 70-77 */
-    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 78-7F */
-  '\r',          CN,   '/',   '*',   ' ',    ST,   'F',   'A',    /* extended */
-    0,  'D',   'C',     0,   'B',     0,    '@',  'P'     /* extended */
-    },
-    { /* right alt mode - not used in US keyboard */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan  0 - 7 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan  8 - F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 10 -17 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 18 -1F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 20 -27 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 28 -2F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 30 -37 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 38 -3F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 40 -47 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 48 -4F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 50 -57 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 58 -5F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 60 -67 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 68 -6F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 70 -77 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 78 -7F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* extended    */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff  /* extended    */
-    }
-    },
-    { /* german keyboard */
-    { /* unshift code */
-    0, 0x1b,   '1',   '2',   '3',   '4',   '5',   '6', /* scan  0- 7 */
-  '7',  '8',   '9',   '0',  0xe1,  '\'',  0x08,  '\t', /* scan  8- F */
-  'q',  'w',   'e',   'r',   't',   'z',   'u',   'i', /* scan 10-17 */
-  'o',  'p',  0x81,   '+',  '\r',   CN,    'a',   's', /* scan 18-1F */
-  'd',  'f',   'g',   'h',   'j',   'k',   'l',  0x94, /* scan 20-27 */
- 0x84,  '^',   SH,    '#',   'y',   'x',   'c',   'v', /* scan 28-2F */
-  'b',  'n',   'm',   ',',   '.',   '-',   SH,    '*', /* scan 30-37 */
-  ' ',  ' ',   CP,      0,     0,     0,     0,     0, /* scan 38-3F */
-    0,    0,     0,     0,     0,   NM,    ST,    '7', /* scan 40-47 */
-  '8',  '9',   '-',   '4',   '5',   '6',   '+',   '1', /* scan 48-4F */
-  '2',  '3',   '0',   ',',     0,     0,   '<',     0, /* scan 50-57 */
-    0,    0,     0,     0,     0,     0,     0,     0, /* scan 58-5F */
-    0,    0,     0,     0,     0,     0,     0,     0, /* scan 60-67 */
-    0,    0,     0,     0,     0,     0,     0,     0, /* scan 68-6F */
-    0,    0,     0,     0,     0,     0,     0,     0, /* scan 70-77 */
-    0,    0,     0,     0,     0,     0,     0,     0, /* scan 78-7F */
-  '\r',          CN,   '/',   '*',   ' ',    ST,   'F',   'A', /* extended */
-    0,  'D',   'C',     0,   'B',     0,    '@',  'P'  /* extended */
-    },
-    { /* shift code */
-    0, 0x1b,   '!',   '"',  0x15,   '$',   '%',   '&', /* scan  0- 7 */
-  '/',  '(',   ')',   '=',   '?',   '`',  0x08,  '\t', /* scan  8- F */
-  'Q',  'W',   'E',   'R',   'T',   'Z',   'U',   'I', /* scan 10-17 */
-  'O',  'P',  0x9a,   '*',  '\r',   CN,    'A',   'S', /* scan 18-1F */
-  'D',  'F',   'G',   'H',   'J',   'K',   'L',  0x99, /* scan 20-27 */
- 0x8e, 0xf8,   SH,   '\'',   'Y',   'X',   'C',   'V', /* scan 28-2F */
-  'B',  'N',   'M',   ';',   ':',   '_',   SH,    '*', /* scan 30-37 */
-  ' ',  ' ',   CP,      0,     0,     0,     0,     0, /* scan 38-3F */
-    0,    0,     0,     0,     0,   NM,    ST,    '7', /* scan 40-47 */
-  '8',  '9',   '-',   '4',   '5',   '6',   '+',   '1', /* scan 48-4F */
-  '2',  '3',   '0',   ',',     0,     0,   '>',     0, /* scan 50-57 */
-    0,    0,     0,     0,     0,     0,     0,     0, /* scan 58-5F */
-    0,    0,     0,     0,     0,     0,     0,     0, /* scan 60-67 */
-    0,    0,     0,     0,     0,     0,     0,     0, /* scan 68-6F */
-    0,    0,     0,     0,     0,     0,     0,     0, /* scan 70-77 */
-    0,    0,     0,     0,     0,     0,     0,     0, /* scan 78-7F */
-  '\r',          CN,   '/',   '*',   ' ',    ST,   'F',   'A', /* extended */
-    0,  'D',   'C',     0,   'B',     0,   '@',   'P'  /* extended */
-    },
-    { /* control code */
- 0xff, 0x1b,  0xff,  0x00,  0xff,  0xff,  0xff,  0xff, /* scan  0- 7 */
- 0x1e, 0xff,  0xff,  0xff,  0x1f,  0xff,  0xff,  '\t', /* scan  8- F */
- 0x11, 0x17,  0x05,  0x12,  0x14,  0x19,  0x15,  0x09, /* scan 10-17 */
- 0x0f, 0x10,  0x1b,  0x1d,  '\r',   CN,   0x01,  0x13, /* scan 18-1F */
- 0x04, 0x06,  0x07,  0x08,  0x0a,  0x0b,  0x0c,  0xff, /* scan 20-27 */
- 0xff, 0x1c,   SH,   0xff,  0x1a,  0x18,  0x03,  0x16, /* scan 28-2F */
- 0x02, 0x0e,  0x0d,  0xff,  0xff,  0xff,   SH,   0xff, /* scan 30-37 */
- 0xff, 0xff,   CP,   0xff,  0xff,  0xff,  0xff,  0xff, /* scan 38-3F */
- 0xff, 0xff,  0xff,  0xff,  0xff,   NM,    ST,   0xff, /* scan 40-47 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 48-4F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 50-57 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 58-5F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 60-67 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 68-6F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 70-77 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 78-7F */
-  '\r',          CN,   '/',   '*',   ' ',    ST,  0xff,  0xff, /* extended */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff  /* extended */
-    },
-    { /* non numeric code */
-    0, 0x1b,   '1',   '2',   '3',   '4',   '5',   '6', /* scan  0- 7 */
-  '7',  '8',   '9',   '0',  0xe1,  '\'',  0x08,  '\t', /* scan  8- F */
-  'q',  'w',   'e',   'r',   't',   'z',   'u',   'i', /* scan 10-17 */
-  'o',  'p',  0x81,   '+',  '\r',   CN,    'a',   's', /* scan 18-1F */
-  'd',  'f',   'g',   'h',   'j',   'k',   'l',  0x94, /* scan 20-27 */
- 0x84,  '^',   SH,      0,   'y',   'x',   'c',   'v', /* scan 28-2F */
-  'b',  'n',   'm',   ',',   '.',   '-',   SH,    '*', /* scan 30-37 */
-  ' ',  ' ',   CP,      0,     0,     0,     0,     0, /* scan 38-3F */
-    0,    0,     0,     0,     0,   NM,    ST,    'w', /* scan 40-47 */
-  'x',  'y',   'l',   't',   'u',   'v',   'm',   'q', /* scan 48-4F */
-  'r',  's',   'p',   'n',     0,     0,   '<',     0, /* scan 50-57 */
-    0,    0,     0,     0,     0,     0,     0,     0, /* scan 58-5F */
-    0,    0,     0,     0,     0,     0,     0,     0, /* scan 60-67 */
-    0,    0,     0,     0,     0,     0,     0,     0, /* scan 68-6F */
-    0,    0,     0,     0,     0,     0,     0,     0, /* scan 70-77 */
-    0,    0,     0,     0,     0,     0,     0,     0, /* scan 78-7F */
-  '\r',          CN,   '/',   '*',   ' ',    ST,   'F',   'A', /* extended */
-    0,  'D',   'C',     0,   'B',     0,    '@',  'P'  /* extended */
-    },
-    { /* Right alt mode - is used in German keyboard */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan  0 - 7 */
-  '{',  '[',   ']',   '}',  '\\',  0xff,  0xff,  0xff, /* scan  8 - F */
-  '@', 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 10 -17 */
- 0xff, 0xff,  0xff,   '~',  0xff,  0xff,  0xff,  0xff, /* scan 18 -1F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 20 -27 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 28 -2F */
- 0xff, 0xff,  0xe6,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 30 -37 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 38 -3F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 40 -47 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 48 -4F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,   '|',  0xff, /* scan 50 -57 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 58 -5F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 60 -67 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 68 -6F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 70 -77 */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 78 -7F */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* extended    */
- 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff  /* extended    */
-    }
-    }
-    };
-
-static unsigned char ext_key_map [] =
-    {
-    0x1c,   /* keypad enter */
-    0x1d,   /* right control */
-    0x35,   /* keypad slash */
-    0x37,   /* print screen */
-    0x38,   /* right alt */
-    0x46,   /* break */
-    0x47,   /* editpad home */
-    0x48,   /* editpad up */
-    0x49,   /* editpad pgup */
-    0x4b,   /* editpad left */
-    0x4d,   /* editpad right */
-    0x4f,   /* editpad end */
-    0x50,   /* editpad dn */
-    0x51,   /* editpad pgdn */
-    0x52,   /* editpad ins */
-    0x53,   /* editpad del */
-    0x00    /* map end */
-    };
-
-/*******************************************************************************
- *
- * i8042_kbd_init - reset keyboard and init state flags
- */
-int i8042_kbd_init (void)
-{
-    int keymap, try;
-    char *penv;
-
-#ifdef CONFIG_USE_CPCIDVI
-    if ((penv = getenv ("console")) != NULL) {
-           if (strncmp (penv, "serial", 7) == 0) {
-                   return -1;
-           }
-    }
-#endif
-    /* Init keyboard device (default US layout) */
-    keymap = KBD_US;
-    if ((penv = getenv ("keymap")) != NULL)
-    {
-       if (strncmp (penv, "de", 3) == 0)
-       keymap = KBD_GER;
-    }
-
-    for (try = 0; try < KBD_RESET_TRIES; try++)
-    {
-       if (kbd_reset() == 0)
-       {
-           kbd_mapping   = keymap;
-           kbd_flags     = NORMAL;
-           kbd_state     = 0;
-           kbd_led_set();
-           return 0;
-           }
-    }
-    return -1;
-}
-
-
-/*******************************************************************************
- *
- * i8042_tstc - test if keyboard input is available
- *             option: cursor blinking if called in a loop
- */
-int i8042_tstc (void)
-{
-    unsigned char scan_code = 0;
-
-#ifdef CONFIG_CONSOLE_CURSOR
-    if (--blinkCount == 0)
-    {
-       cursor_state ^= 1;
-       console_cursor (cursor_state);
-       blinkCount = CFG_CONSOLE_BLINK_COUNT;
-       udelay (10);
-    }
-#endif
-
-    if ((in8 (I8042_STATUS_REG) & 0x01) == 0)
-       return 0;
-    else
-    {
-       scan_code = in8 (I8042_DATA_REG);
-       if (scan_code == 0xfa)
-           return 0;
-
-       kbd_conv_char(scan_code);
-
-       if (kbd_input != -1)
-           return 1;
-    }
-    return 0;
-}
-
-
-/*******************************************************************************
- *
- * i8042_getc - wait till keyboard input is available
- *             option: turn on/off cursor while waiting
- */
-int i8042_getc (void)
-{
-    int ret_chr;
-    unsigned char scan_code;
-
-    while (kbd_input == -1)
-    {
-       while ((in8 (I8042_STATUS_REG) & 0x01) == 0)
-       {
-#ifdef CONFIG_CONSOLE_CURSOR
-           if (--blinkCount==0)
-           {
-               cursor_state ^= 1;
-               console_cursor (cursor_state);
-               blinkCount = CFG_CONSOLE_BLINK_COUNT;
-           }
-           udelay (10);
-#endif
-       }
-
-       scan_code = in8 (I8042_DATA_REG);
-
-       if (scan_code != 0xfa)
-       kbd_conv_char (scan_code);
-    }
-    ret_chr = kbd_input;
-    kbd_input = -1;
-    return ret_chr;
-}
-
-
-/******************************************************************************/
-
-static void kbd_conv_char (unsigned char scan_code)
-{
-    if (scan_code == 0xe0)
-    {
-       kbd_flags |= EXT;
-       return;
-    }
-
-    /* if high bit of scan_code, set break flag */
-    if (scan_code & 0x80)
-       kbd_flags |=  BRK;
-    else
-       kbd_flags &= ~BRK;
-
-    if ((scan_code == 0xe1) || (kbd_flags & E1))
-    {
-       if (scan_code == 0xe1)
-       {
-           kbd_flags ^= BRK;     /* reset the break flag */
-           kbd_flags ^= E1;      /* bitwise EXOR with E1 flag */
-       }
-       return;
-    }
-
-    scan_code &= 0x7f;
-
-    if (kbd_flags & EXT)
-    {
-       int i;
-
-       kbd_flags ^= EXT;
-       for (i=0; ext_key_map[i]; i++)
-       {
-           if (ext_key_map[i] == scan_code)
-           {
-               scan_code = 0x80 + i;
-               break;
-           }
-       }
-       /* not found ? */
-       if (!ext_key_map[i])
-           return;
-    }
-
-    switch (kbd_fct_map [scan_code])
-    {
-    case AS:  kbd_normal (scan_code);
-       break;
-    case SH:  kbd_shift (scan_code);
-       break;
-    case CN:  kbd_ctrl (scan_code);
-       break;
-    case NM:  kbd_num (scan_code);
-       break;
-    case CP:  kbd_caps (scan_code);
-       break;
-    case ST:  kbd_scroll (scan_code);
-       break;
-    case AK:  kbd_alt (scan_code);
-       break;
-    }
-    return;
-}
-
-
-/******************************************************************************/
-
-static void kbd_normal (unsigned char scan_code)
-{
-    unsigned char chr;
-
-    if ((kbd_flags & BRK) == NORMAL)
-    {
-       chr = kbd_key_map [kbd_mapping][kbd_state][scan_code];
-       if ((chr == 0xff) || (chr == 0x00))
-       {
-           return;
-       }
-
-       /* if caps lock convert upper to lower */
-       if (((kbd_flags & CAPS) == CAPS) && (chr >= 'a' && chr <= 'z'))
-       {
-          chr -= 'a' - 'A';
-       }
-       kbd_input = chr;
-    }
-}
-
-
-/******************************************************************************/
-
-static void kbd_shift (unsigned char scan_code)
-{
-    if ((kbd_flags & BRK) == BRK)
-    {
-       kbd_state = AS;
-       kbd_flags &= (~SHIFT);
-    }
-    else
-    {
-       kbd_state = SH;
-       kbd_flags |= SHIFT;
-    }
-}
-
-
-/******************************************************************************/
-
-static void kbd_ctrl (unsigned char scan_code)
-{
-    if ((kbd_flags & BRK) == BRK)
-    {
-       kbd_state = AS;
-       kbd_flags &= (~CTRL);
-    }
-    else
-    {
-       kbd_state = CN;
-       kbd_flags |= CTRL;
-    }
-}
-
-
-/******************************************************************************/
-
-static void kbd_caps (unsigned char scan_code)
-{
-    if ((kbd_flags & BRK) == NORMAL)
-    {
-       kbd_flags ^= CAPS;
-       kbd_led_set ();           /* update keyboard LED */
-    }
-}
-
-
-/******************************************************************************/
-
-static void kbd_num (unsigned char scan_code)
-{
-    if ((kbd_flags & BRK) == NORMAL)
-    {
-       kbd_flags ^= NUM;
-       kbd_state = (kbd_flags & NUM) ? AS : NM;
-       kbd_led_set ();           /* update keyboard LED */
-    }
-}
-
-
-/******************************************************************************/
-
-static void kbd_scroll (unsigned char scan_code)
-{
-    if ((kbd_flags & BRK) == NORMAL)
-    {
-       kbd_flags ^= STP;
-       kbd_led_set ();            /* update keyboard LED */
-       if (kbd_flags & STP)
-           kbd_input = 0x13;
-       else
-           kbd_input = 0x11;
-    }
-}
-
-/******************************************************************************/
-
-static void kbd_alt (unsigned char scan_code)
-{
-    if ((kbd_flags & BRK) == BRK)
-    {
-       kbd_state = AS;
-       kbd_flags &= (~ALT);
-    }
-    else
-    {
-       kbd_state = AK;
-       kbd_flags &= ALT;
-    }
-}
-
-
-/******************************************************************************/
-
-static void kbd_led_set (void)
-{
-    kbd_input_empty();
-    out8 (I8042_DATA_REG, 0xed);       /* SET LED command */
-    kbd_input_empty();
-    out8 (I8042_DATA_REG, (kbd_flags & 0x7));   /* LED bits only */
-}
-
-
-/******************************************************************************/
-
-static int kbd_input_empty (void)
-{
-    int kbdTimeout = KBD_TIMEOUT;
-
-    /* wait for input buf empty */
-    while ((in8 (I8042_STATUS_REG) & 0x02) && kbdTimeout--)
-       udelay(1000);
-
-    return kbdTimeout;
-}
-
-/******************************************************************************/
-
-static int kbd_reset (void)
-{
-    if (kbd_input_empty() == 0)
-       return -1;
-
-    out8 (I8042_DATA_REG, 0xff);
-
-    udelay(250000);
-
-    if (kbd_input_empty() == 0)
-       return -1;
-
-#ifdef CONFIG_USE_CPCIDVI
-    out8 (I8042_COMMAND_REG, 0x60);
-#else
-    out8 (I8042_DATA_REG, 0x60);
-#endif
-
-    if (kbd_input_empty() == 0)
-       return -1;
-
-    out8 (I8042_DATA_REG, 0x45);
-
-
-    if (kbd_input_empty() == 0)
-       return -1;
-
-    out8 (I8042_COMMAND_REG, 0xae);
-
-    if (kbd_input_empty() == 0)
-       return -1;
-
-    return 0;
-}
-
-#endif /* CONFIG_I8042_KBD */
diff --git a/drivers/i82365.c b/drivers/i82365.c
deleted file mode 100644 (file)
index a40fcf4..0000000
+++ /dev/null
@@ -1,1014 +0,0 @@
-/*
- * (C) Copyright 2003-2005
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- ********************************************************************
- *
- * Lots of code copied from:
- *
- * i82365.c 1.352 - Linux driver for Intel 82365 and compatible
- * PC Card controllers, and Yenta-compatible PCI-to-CardBus controllers.
- * (C) 1999 David A. Hinds <dahinds@users.sourceforge.net>
- */
-
-#include <common.h>
-
-#ifdef CONFIG_I82365
-
-#include <command.h>
-#include <pci.h>
-#include <pcmcia.h>
-#include <asm/io.h>
-
-#include <pcmcia/ss.h>
-#include <pcmcia/i82365.h>
-#include <pcmcia/yenta.h>
-#ifdef CONFIG_CPC45
-#include <pcmcia/cirrus.h>
-#else
-#include <pcmcia/ti113x.h>
-#endif
-
-static struct pci_device_id supported[] = {
-#ifdef CONFIG_CPC45
-       {PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6729},
-#else
-       {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1510},
-#endif
-       {0, 0}
-};
-
-#define CYCLE_TIME     120
-
-#ifdef CONFIG_CPC45
-extern int SPD67290Init (void);
-#endif
-
-#ifdef DEBUG
-static void i82365_dump_regions (pci_dev_t dev);
-#endif
-
-typedef struct socket_info_t {
-       pci_dev_t       dev;
-       u_short         bcr;
-       u_char          pci_lat, cb_lat, sub_bus, cache;
-       u_int           cb_phys;
-
-       socket_cap_t    cap;
-       u_short         type;
-       u_int           flags;
-#ifdef CONFIG_CPC45
-       cirrus_state_t  c_state;
-#else
-       ti113x_state_t  state;
-#endif
-} socket_info_t;
-
-#ifdef CONFIG_CPC45
-/* These definitions must match the pcic table! */
-typedef enum pcic_id {
-       IS_PD6710, IS_PD672X, IS_VT83C469
-} pcic_id;
-
-typedef struct pcic_t {
-       char *name;
-} pcic_t;
-
-static pcic_t pcic[] = {
-       {" Cirrus PD6710: "},
-       {" Cirrus PD672x: "},
-       {" VIA VT83C469: "},
-};
-#endif
-
-static socket_info_t socket;
-static socket_state_t state;
-static struct pccard_mem_map mem;
-static struct pccard_io_map io;
-
-/*====================================================================*/
-
-/* Some PCI shortcuts */
-
-static int pci_readb (socket_info_t * s, int r, u_char * v)
-{
-       return pci_read_config_byte (s->dev, r, v);
-}
-static int pci_writeb (socket_info_t * s, int r, u_char v)
-{
-       return pci_write_config_byte (s->dev, r, v);
-}
-static int pci_readw (socket_info_t * s, int r, u_short * v)
-{
-       return pci_read_config_word (s->dev, r, v);
-}
-static int pci_writew (socket_info_t * s, int r, u_short v)
-{
-       return pci_write_config_word (s->dev, r, v);
-}
-#ifndef CONFIG_CPC45
-static int pci_readl (socket_info_t * s, int r, u_int * v)
-{
-       return pci_read_config_dword (s->dev, r, v);
-}
-static int pci_writel (socket_info_t * s, int r, u_int v)
-{
-       return pci_write_config_dword (s->dev, r, v);
-}
-#endif /* !CONFIG_CPC45 */
-
-/*====================================================================*/
-
-#ifdef CONFIG_CPC45
-
-#define cb_readb(s)            readb((s)->cb_phys + 1)
-#define cb_writeb(s, v)                writeb(v, (s)->cb_phys)
-#define cb_writeb2(s, v)       writeb(v, (s)->cb_phys + 1)
-#define cb_readl(s, r)         readl((s)->cb_phys + (r))
-#define cb_writel(s, r, v)     writel(v, (s)->cb_phys + (r))
-
-
-static u_char i365_get (socket_info_t * s, u_short reg)
-{
-       u_char val;
-#ifdef CONFIG_PCMCIA_SLOT_A
-       int slot = 0;
-#else
-       int slot = 1;
-#endif
-
-       val = I365_REG (slot, reg);
-
-       cb_writeb (s, val);
-       val = cb_readb (s);
-
-       debug ("i365_get slot:%x reg: %x val: %x\n", slot, reg, val);
-       return val;
-}
-
-static void i365_set (socket_info_t * s, u_short reg, u_char data)
-{
-#ifdef CONFIG_PCMCIA_SLOT_A
-       int slot = 0;
-#else
-       int slot = 1;
-#endif
-       u_char val;
-
-       val = I365_REG (slot, reg);
-
-       cb_writeb (s, val);
-       cb_writeb2 (s, data);
-
-       debug ("i365_set slot:%x reg: %x data:%x\n", slot, reg, data);
-}
-
-#else  /* ! CONFIG_CPC45 */
-
-#define cb_readb(s, r)         readb((s)->cb_phys + (r))
-#define cb_readl(s, r)         readl((s)->cb_phys + (r))
-#define cb_writeb(s, r, v)     writeb(v, (s)->cb_phys + (r))
-#define cb_writel(s, r, v)     writel(v, (s)->cb_phys + (r))
-
-static u_char i365_get (socket_info_t * s, u_short reg)
-{
-       return cb_readb (s, 0x0800 + reg);
-}
-
-static void i365_set (socket_info_t * s, u_short reg, u_char data)
-{
-       cb_writeb (s, 0x0800 + reg, data);
-}
-#endif /* CONFIG_CPC45 */
-
-static void i365_bset (socket_info_t * s, u_short reg, u_char mask)
-{
-       i365_set (s, reg, i365_get (s, reg) | mask);
-}
-
-static void i365_bclr (socket_info_t * s, u_short reg, u_char mask)
-{
-       i365_set (s, reg, i365_get (s, reg) & ~mask);
-}
-
-#if 0  /* not used */
-static void i365_bflip (socket_info_t * s, u_short reg, u_char mask, int b)
-{
-       u_char d = i365_get (s, reg);
-
-       i365_set (s, reg, (b) ? (d | mask) : (d & ~mask));
-}
-
-static u_short i365_get_pair (socket_info_t * s, u_short reg)
-{
-       return (i365_get (s, reg) + (i365_get (s, reg + 1) << 8));
-}
-#endif /* not used */
-
-static void i365_set_pair (socket_info_t * s, u_short reg, u_short data)
-{
-       i365_set (s, reg, data & 0xff);
-       i365_set (s, reg + 1, data >> 8);
-}
-
-#ifdef CONFIG_CPC45
-/*======================================================================
-
-    Code to save and restore global state information for Cirrus
-    PD67xx controllers, and to set and report global configuration
-    options.
-
-======================================================================*/
-
-#define flip(v,b,f) (v = ((f)<0) ? v : ((f) ? ((v)|(b)) : ((v)&(~b))))
-
-static void cirrus_get_state (socket_info_t * s)
-{
-       int i;
-       cirrus_state_t *p = &s->c_state;
-
-       p->misc1 = i365_get (s, PD67_MISC_CTL_1);
-       p->misc1 &= (PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
-       p->misc2 = i365_get (s, PD67_MISC_CTL_2);
-       for (i = 0; i < 6; i++)
-               p->timer[i] = i365_get (s, PD67_TIME_SETUP (0) + i);
-
-}
-
-static void cirrus_set_state (socket_info_t * s)
-{
-       int i;
-       u_char misc;
-       cirrus_state_t *p = &s->c_state;
-
-       misc = i365_get (s, PD67_MISC_CTL_2);
-       i365_set (s, PD67_MISC_CTL_2, p->misc2);
-       if (misc & PD67_MC2_SUSPEND)
-               udelay (50000);
-       misc = i365_get (s, PD67_MISC_CTL_1);
-       misc &= ~(PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
-       i365_set (s, PD67_MISC_CTL_1, misc | p->misc1);
-       for (i = 0; i < 6; i++)
-               i365_set (s, PD67_TIME_SETUP (0) + i, p->timer[i]);
-}
-
-static u_int cirrus_set_opts (socket_info_t * s)
-{
-       cirrus_state_t *p = &s->c_state;
-       u_int mask = 0xffff;
-#if DEBUG
-       char buf[200];
-
-       memset (buf, 0, 200);
-#endif
-
-       if (has_ring == -1)
-               has_ring = 1;
-       flip (p->misc2, PD67_MC2_IRQ15_RI, has_ring);
-       flip (p->misc2, PD67_MC2_DYNAMIC_MODE, dynamic_mode);
-#if DEBUG
-       if (p->misc2 & PD67_MC2_IRQ15_RI)
-               strcat (buf, " [ring]");
-       if (p->misc2 & PD67_MC2_DYNAMIC_MODE)
-               strcat (buf, " [dyn mode]");
-       if (p->misc1 & PD67_MC1_INPACK_ENA)
-               strcat (buf, " [inpack]");
-#endif
-
-       if (p->misc2 & PD67_MC2_IRQ15_RI)
-               mask &= ~0x8000;
-       if (has_led > 0) {
-#if DEBUG
-               strcat (buf, " [led]");
-#endif
-               mask &= ~0x1000;
-       }
-       if (has_dma > 0) {
-#if DEBUG
-               strcat (buf, " [dma]");
-#endif
-               mask &= ~0x0600;
-               flip (p->misc2, PD67_MC2_FREQ_BYPASS, freq_bypass);
-#if DEBUG
-               if (p->misc2 & PD67_MC2_FREQ_BYPASS)
-                       strcat (buf, " [freq bypass]");
-#endif
-       }
-
-       if (setup_time >= 0)
-               p->timer[0] = p->timer[3] = setup_time;
-       if (cmd_time > 0) {
-               p->timer[1] = cmd_time;
-               p->timer[4] = cmd_time * 2 + 4;
-       }
-       if (p->timer[1] == 0) {
-               p->timer[1] = 6;
-               p->timer[4] = 16;
-               if (p->timer[0] == 0)
-                       p->timer[0] = p->timer[3] = 1;
-       }
-       if (recov_time >= 0)
-               p->timer[2] = p->timer[5] = recov_time;
-
-       debug ("i82365 Opt: %s [%d/%d/%d] [%d/%d/%d]\n",
-               buf,
-               p->timer[0], p->timer[1], p->timer[2],
-               p->timer[3], p->timer[4], p->timer[5]);
-
-       return mask;
-}
-
-#else  /* !CONFIG_CPC45 */
-
-/*======================================================================
-
-    Code to save and restore global state information for TI 1130 and
-    TI 1131 controllers, and to set and report global configuration
-    options.
-
-======================================================================*/
-
-static void ti113x_get_state (socket_info_t * s)
-{
-       ti113x_state_t *p = &s->state;
-
-       pci_readl (s, TI113X_SYSTEM_CONTROL, &p->sysctl);
-       pci_readb (s, TI113X_CARD_CONTROL, &p->cardctl);
-       pci_readb (s, TI113X_DEVICE_CONTROL, &p->devctl);
-       pci_readb (s, TI1250_DIAGNOSTIC, &p->diag);
-       pci_readl (s, TI12XX_IRQMUX, &p->irqmux);
-}
-
-static void ti113x_set_state (socket_info_t * s)
-{
-       ti113x_state_t *p = &s->state;
-
-       pci_writel (s, TI113X_SYSTEM_CONTROL, p->sysctl);
-       pci_writeb (s, TI113X_CARD_CONTROL, p->cardctl);
-       pci_writeb (s, TI113X_DEVICE_CONTROL, p->devctl);
-       pci_writeb (s, TI1250_MULTIMEDIA_CTL, 0);
-       pci_writeb (s, TI1250_DIAGNOSTIC, p->diag);
-       pci_writel (s, TI12XX_IRQMUX, p->irqmux);
-       i365_set_pair (s, TI113X_IO_OFFSET (0), 0);
-       i365_set_pair (s, TI113X_IO_OFFSET (1), 0);
-}
-
-static u_int ti113x_set_opts (socket_info_t * s)
-{
-       ti113x_state_t *p = &s->state;
-       u_int mask = 0xffff;
-
-       p->cardctl &= ~TI113X_CCR_ZVENABLE;
-       p->cardctl |= TI113X_CCR_SPKROUTEN;
-
-       return mask;
-}
-#endif /* CONFIG_CPC45 */
-
-/*======================================================================
-
-    Routines to handle common CardBus options
-
-======================================================================*/
-
-/* Default settings for PCI command configuration register */
-#define CMD_DFLT (PCI_COMMAND_IO|PCI_COMMAND_MEMORY| \
-                 PCI_COMMAND_MASTER|PCI_COMMAND_WAIT)
-
-static void cb_get_state (socket_info_t * s)
-{
-       pci_readb (s, PCI_CACHE_LINE_SIZE, &s->cache);
-       pci_readb (s, PCI_LATENCY_TIMER, &s->pci_lat);
-       pci_readb (s, CB_LATENCY_TIMER, &s->cb_lat);
-       pci_readb (s, CB_CARDBUS_BUS, &s->cap.cardbus);
-       pci_readb (s, CB_SUBORD_BUS, &s->sub_bus);
-       pci_readw (s, CB_BRIDGE_CONTROL, &s->bcr);
-}
-
-static void cb_set_state (socket_info_t * s)
-{
-#ifndef CONFIG_CPC45
-       pci_writel (s, CB_LEGACY_MODE_BASE, 0);
-       pci_writel (s, PCI_BASE_ADDRESS_0, s->cb_phys);
-#endif
-       pci_writew (s, PCI_COMMAND, CMD_DFLT);
-       pci_writeb (s, PCI_CACHE_LINE_SIZE, s->cache);
-       pci_writeb (s, PCI_LATENCY_TIMER, s->pci_lat);
-       pci_writeb (s, CB_LATENCY_TIMER, s->cb_lat);
-       pci_writeb (s, CB_CARDBUS_BUS, s->cap.cardbus);
-       pci_writeb (s, CB_SUBORD_BUS, s->sub_bus);
-       pci_writew (s, CB_BRIDGE_CONTROL, s->bcr);
-}
-
-static void cb_set_opts (socket_info_t * s)
-{
-#ifndef CONFIG_CPC45
-       if (s->cache == 0)
-               s->cache = 8;
-       if (s->pci_lat == 0)
-               s->pci_lat = 0xa8;
-       if (s->cb_lat == 0)
-               s->cb_lat = 0xb0;
-#endif
-}
-
-/*======================================================================
-
-    Power control for Cardbus controllers: used both for 16-bit and
-    Cardbus cards.
-
-======================================================================*/
-
-static int cb_set_power (socket_info_t * s, socket_state_t * state)
-{
-       u_int reg = 0;
-
-#ifdef CONFIG_CPC45
-
-       reg = I365_PWR_NORESET;
-       if (state->flags & SS_PWR_AUTO)
-               reg |= I365_PWR_AUTO;
-       if (state->flags & SS_OUTPUT_ENA)
-               reg |= I365_PWR_OUT;
-       if (state->Vpp != 0) {
-               if (state->Vpp == 120) {
-                       reg |= I365_VPP1_12V;
-                       puts (" 12V card found: ");
-               } else if (state->Vpp == state->Vcc) {
-                       reg |= I365_VPP1_5V;
-               } else {
-                       puts (" power not found: ");
-                       return -1;
-               }
-       }
-       if (state->Vcc != 0) {
-               reg |= I365_VCC_5V;
-               if (state->Vcc == 33) {
-                       puts (" 3.3V card found: ");
-                       i365_bset (s, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
-               } else if (state->Vcc == 50) {
-                       puts (" 5V card found: ");
-                       i365_bclr (s, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
-               } else {
-                       puts (" power not found: ");
-                       return -1;
-               }
-       }
-
-       if (reg != i365_get (s, I365_POWER)) {
-               reg = (I365_PWR_OUT | I365_PWR_NORESET | I365_VCC_5V | I365_VPP1_5V);
-               i365_set (s, I365_POWER, reg);
-       }
-
-#else  /* ! CONFIG_CPC45 */
-
-       /* restart card voltage detection if it seems appropriate */
-       if ((state->Vcc == 0) && (state->Vpp == 0) &&
-          !(cb_readl (s, CB_SOCKET_STATE) & CB_SS_VSENSE))
-               cb_writel (s, CB_SOCKET_FORCE, CB_SF_CVSTEST);
-       switch (state->Vcc) {
-       case 0:
-               reg = 0;
-               break;
-       case 33:
-               reg = CB_SC_VCC_3V;
-               break;
-       case 50:
-               reg = CB_SC_VCC_5V;
-               break;
-       default:
-               return -1;
-       }
-       switch (state->Vpp) {
-       case 0:
-               break;
-       case 33:
-               reg |= CB_SC_VPP_3V;
-               break;
-       case 50:
-               reg |= CB_SC_VPP_5V;
-               break;
-       case 120:
-               reg |= CB_SC_VPP_12V;
-               break;
-       default:
-               return -1;
-       }
-       if (reg != cb_readl (s, CB_SOCKET_CONTROL))
-               cb_writel (s, CB_SOCKET_CONTROL, reg);
-#endif /* CONFIG_CPC45 */
-       return 0;
-}
-
-/*======================================================================
-
-    Generic routines to get and set controller options
-
-======================================================================*/
-
-static void get_bridge_state (socket_info_t * s)
-{
-#ifdef CONFIG_CPC45
-       cirrus_get_state (s);
-#else
-       ti113x_get_state (s);
-#endif
-       cb_get_state (s);
-}
-
-static void set_bridge_state (socket_info_t * s)
-{
-       cb_set_state (s);
-       i365_set (s, I365_GBLCTL, 0x00);
-       i365_set (s, I365_GENCTL, 0x00);
-#ifdef CONFIG_CPC45
-       cirrus_set_state (s);
-#else
-       ti113x_set_state (s);
-#endif
-}
-
-static void set_bridge_opts (socket_info_t * s)
-{
-#ifdef CONFIG_CPC45
-       cirrus_set_opts (s);
-#else
-       ti113x_set_opts (s);
-#endif
-       cb_set_opts (s);
-}
-
-/*====================================================================*/
-#define PD67_EXT_INDEX         0x2e    /* Extension index */
-#define PD67_EXT_DATA          0x2f    /* Extension data */
-#define PD67_EXD_VS1(s)                (0x01 << ((s)<<1))
-
-#define pd67_ext_get(s, r) \
-    (i365_set(s, PD67_EXT_INDEX, r), i365_get(s, PD67_EXT_DATA))
-
-static int i365_get_status (socket_info_t * s, u_int * value)
-{
-       u_int status;
-#ifdef CONFIG_CPC45
-       u_char val;
-       u_char power, vcc, vpp;
-       u_int powerstate;
-#endif
-
-       status = i365_get (s, I365_IDENT);
-       status = i365_get (s, I365_STATUS);
-       *value = ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0;
-       if (i365_get (s, I365_INTCTL) & I365_PC_IOCARD) {
-               *value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
-       } else {
-               *value |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;
-               *value |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;
-       }
-       *value |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;
-       *value |= (status & I365_CS_READY) ? SS_READY : 0;
-       *value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
-
-#ifdef CONFIG_CPC45
-       /* Check for Cirrus CL-PD67xx chips */
-       i365_set (s, PD67_CHIP_INFO, 0);
-       val = i365_get (s, PD67_CHIP_INFO);
-       s->type = -1;
-       if ((val & PD67_INFO_CHIP_ID) == PD67_INFO_CHIP_ID) {
-               val = i365_get (s, PD67_CHIP_INFO);
-               if ((val & PD67_INFO_CHIP_ID) == 0) {
-                       s->type = (val & PD67_INFO_SLOTS) ? IS_PD672X : IS_PD6710;
-                       i365_set (s, PD67_EXT_INDEX, 0xe5);
-                       if (i365_get (s, PD67_EXT_INDEX) != 0xe5)
-                               s->type = IS_VT83C469;
-               }
-       } else {
-               printf ("no Cirrus Chip found\n");
-               *value = 0;
-               return -1;
-       }
-
-       power = i365_get (s, I365_POWER);
-       state.flags |= (power & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
-       state.flags |= (power & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
-       vcc = power & I365_VCC_MASK;
-       vpp = power & I365_VPP1_MASK;
-       state.Vcc = state.Vpp = 0;
-       if((vcc== 0) || (vpp == 0)) {
-               /*
-                * On the Cirrus we get the info which card voltage
-                * we have in EXTERN DATA and write it to MISC_CTL1
-                */
-               powerstate = pd67_ext_get(s, PD67_EXTERN_DATA);
-               if (powerstate & PD67_EXD_VS1(0)) {
-                       /* 5V Card */
-                       i365_bclr (s, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
-               } else {
-                       /* 3.3V Card */
-                       i365_bset (s, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
-               }
-               i365_set (s, I365_POWER, (I365_PWR_OUT | I365_PWR_NORESET | I365_VCC_5V | I365_VPP1_5V));
-               power = i365_get (s, I365_POWER);
-       }
-       if (power & I365_VCC_5V) {
-               state.Vcc = (i365_get(s, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) ? 33 : 50;
-       }
-
-       if (power == I365_VPP1_12V)
-               state.Vpp = 120;
-
-       /* IO card, RESET flags, IO interrupt */
-       power = i365_get (s, I365_INTCTL);
-       state.flags |= (power & I365_PC_RESET) ? 0 : SS_RESET;
-       if (power & I365_PC_IOCARD)
-               state.flags |= SS_IOCARD;
-       state.io_irq = power & I365_IRQ_MASK;
-
-       /* Card status change mask */
-       power = i365_get (s, I365_CSCINT);
-       state.csc_mask = (power & I365_CSC_DETECT) ? SS_DETECT : 0;
-       if (state.flags & SS_IOCARD)
-               state.csc_mask |= (power & I365_CSC_STSCHG) ? SS_STSCHG : 0;
-       else {
-               state.csc_mask |= (power & I365_CSC_BVD1) ? SS_BATDEAD : 0;
-               state.csc_mask |= (power & I365_CSC_BVD2) ? SS_BATWARN : 0;
-               state.csc_mask |= (power & I365_CSC_READY) ? SS_READY : 0;
-       }
-       debug ("i82365: GetStatus(0) = flags %#3.3x, Vcc %d, Vpp %d, "
-               "io_irq %d, csc_mask %#2.2x\n", state.flags,
-               state.Vcc, state.Vpp, state.io_irq, state.csc_mask);
-
-#else  /* !CONFIG_CPC45 */
-
-       status = cb_readl (s, CB_SOCKET_STATE);
-       *value |= (status & CB_SS_32BIT) ? SS_CARDBUS : 0;
-       *value |= (status & CB_SS_3VCARD) ? SS_3VCARD : 0;
-       *value |= (status & CB_SS_XVCARD) ? SS_XVCARD : 0;
-       *value |= (status & CB_SS_VSENSE) ? 0 : SS_PENDING;
-       /* For now, ignore cards with unsupported voltage keys */
-       if (*value & SS_XVCARD)
-               *value &= ~(SS_DETECT | SS_3VCARD | SS_XVCARD);
-#endif /* CONFIG_CPC45 */
-       return 0;
-}      /* i365_get_status */
-
-static int i365_set_socket (socket_info_t * s, socket_state_t * state)
-{
-       u_char reg;
-
-       set_bridge_state (s);
-
-       /* IO card, RESET flag */
-       reg = 0;
-       reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
-       reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
-       i365_set (s, I365_INTCTL, reg);
-
-#ifdef CONFIG_CPC45
-       cb_set_power (s, state);
-
-#if 0
-       /* Card status change interrupt mask */
-       reg = s->cs_irq << 4;
-       if (state->csc_mask & SS_DETECT)
-               reg |= I365_CSC_DETECT;
-       if (state->flags & SS_IOCARD) {
-               if (state->csc_mask & SS_STSCHG)
-                       reg |= I365_CSC_STSCHG;
-       } else {
-               if (state->csc_mask & SS_BATDEAD)
-                       reg |= I365_CSC_BVD1;
-               if (state->csc_mask & SS_BATWARN)
-                       reg |= I365_CSC_BVD2;
-               if (state->csc_mask & SS_READY)
-                       reg |= I365_CSC_READY;
-       }
-       i365_set (s, I365_CSCINT, reg);
-       i365_get (s, I365_CSC);
-#endif /* 0 */
-
-#else  /* !CONFIG_CPC45 */
-
-       reg = I365_PWR_NORESET;
-       if (state->flags & SS_PWR_AUTO)
-               reg |= I365_PWR_AUTO;
-       if (state->flags & SS_OUTPUT_ENA)
-               reg |= I365_PWR_OUT;
-
-       cb_set_power (s, state);
-       reg |= i365_get (s, I365_POWER) & (I365_VCC_MASK | I365_VPP1_MASK);
-
-       if (reg != i365_get (s, I365_POWER))
-               i365_set (s, I365_POWER, reg);
-#endif /* CONFIG_CPC45 */
-
-       return 0;
-}      /* i365_set_socket */
-
-/*====================================================================*/
-
-static int i365_set_mem_map (socket_info_t * s, struct pccard_mem_map *mem)
-{
-       u_short base, i;
-       u_char map;
-
-       debug ("i82365: SetMemMap(%d, %#2.2x, %d ns, %#5.5lx-%#5.5lx, %#5.5x)\n",
-               mem->map, mem->flags, mem->speed,
-               mem->sys_start, mem->sys_stop, mem->card_start);
-
-       map = mem->map;
-       if ((map > 4) ||
-           (mem->card_start > 0x3ffffff) ||
-           (mem->sys_start > mem->sys_stop) ||
-           (mem->speed > 1000)) {
-               return -1;
-       }
-
-       /* Turn off the window before changing anything */
-       if (i365_get (s, I365_ADDRWIN) & I365_ENA_MEM (map))
-               i365_bclr (s, I365_ADDRWIN, I365_ENA_MEM (map));
-
-       /* Take care of high byte, for PCI controllers */
-       i365_set (s, CB_MEM_PAGE (map), mem->sys_start >> 24);
-
-       base = I365_MEM (map);
-       i = (mem->sys_start >> 12) & 0x0fff;
-       if (mem->flags & MAP_16BIT)
-               i |= I365_MEM_16BIT;
-       if (mem->flags & MAP_0WS)
-               i |= I365_MEM_0WS;
-       i365_set_pair (s, base + I365_W_START, i);
-
-       i = (mem->sys_stop >> 12) & 0x0fff;
-       switch (mem->speed / CYCLE_TIME) {
-       case 0:
-               break;
-       case 1:
-               i |= I365_MEM_WS0;
-               break;
-       case 2:
-               i |= I365_MEM_WS1;
-               break;
-       default:
-               i |= I365_MEM_WS1 | I365_MEM_WS0;
-               break;
-       }
-       i365_set_pair (s, base + I365_W_STOP, i);
-
-#ifdef CONFIG_CPC45
-       i = 0;
-#else
-       i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff;
-#endif
-       if (mem->flags & MAP_WRPROT)
-               i |= I365_MEM_WRPROT;
-       if (mem->flags & MAP_ATTRIB)
-               i |= I365_MEM_REG;
-       i365_set_pair (s, base + I365_W_OFF, i);
-
-#ifdef CONFIG_CPC45
-       /* set System Memory map Upper Adress */
-       i365_set(s, PD67_EXT_INDEX, PD67_MEM_PAGE(map));
-       i365_set(s, PD67_EXT_DATA, ((mem->sys_start >> 24) & 0xff));
-#endif
-
-       /* Turn on the window if necessary */
-       if (mem->flags & MAP_ACTIVE)
-               i365_bset (s, I365_ADDRWIN, I365_ENA_MEM (map));
-       return 0;
-}      /* i365_set_mem_map */
-
-static int i365_set_io_map (socket_info_t * s, struct pccard_io_map *io)
-{
-       u_char map, ioctl;
-
-       map = io->map;
-       /* comment out: comparison is always false due to limited range of data type */
-       if ((map > 1) || /* (io->start > 0xffff) || (io->stop > 0xffff) || */
-           (io->stop < io->start))
-               return -1;
-       /* Turn off the window before changing anything */
-       if (i365_get (s, I365_ADDRWIN) & I365_ENA_IO (map))
-               i365_bclr (s, I365_ADDRWIN, I365_ENA_IO (map));
-       i365_set_pair (s, I365_IO (map) + I365_W_START, io->start);
-       i365_set_pair (s, I365_IO (map) + I365_W_STOP, io->stop);
-       ioctl = i365_get (s, I365_IOCTL) & ~I365_IOCTL_MASK (map);
-       if (io->speed)
-               ioctl |= I365_IOCTL_WAIT (map);
-       if (io->flags & MAP_0WS)
-               ioctl |= I365_IOCTL_0WS (map);
-       if (io->flags & MAP_16BIT)
-               ioctl |= I365_IOCTL_16BIT (map);
-       if (io->flags & MAP_AUTOSZ)
-               ioctl |= I365_IOCTL_IOCS16 (map);
-       i365_set (s, I365_IOCTL, ioctl);
-       /* Turn on the window if necessary */
-       if (io->flags & MAP_ACTIVE)
-               i365_bset (s, I365_ADDRWIN, I365_ENA_IO (map));
-       return 0;
-}      /* i365_set_io_map */
-
-/*====================================================================*/
-
-int i82365_init (void)
-{
-       u_int val;
-       int i;
-
-#ifdef CONFIG_CPC45
-       if (SPD67290Init () != 0)
-               return 1;
-#endif
-       if ((socket.dev = pci_find_devices (supported, 0)) < 0) {
-               /* Controller not found */
-               return 1;
-       }
-       debug ("i82365 Device Found!\n");
-
-       pci_read_config_dword (socket.dev, PCI_BASE_ADDRESS_0, &socket.cb_phys);
-       socket.cb_phys &= ~0xf;
-
-#ifdef CONFIG_CPC45
-       /* + 0xfe000000 see MPC 8245 Users Manual Adress Map B */
-       socket.cb_phys += 0xfe000000;
-#endif
-
-       get_bridge_state (&socket);
-       set_bridge_opts (&socket);
-
-       i = i365_get_status (&socket, &val);
-
-#ifdef CONFIG_CPC45
-       if (i > -1) {
-               puts (pcic[socket.type].name);
-       } else {
-               printf ("i82365: Controller not found.\n");
-               return 1;
-       }
-       if((val & SS_DETECT) != SS_DETECT){
-               puts ("No card\n");
-               return 1;
-       }
-#else  /* !CONFIG_CPC45 */
-       if (val & SS_DETECT) {
-               if (val & SS_3VCARD) {
-                       state.Vcc = state.Vpp = 33;
-                       puts (" 3.3V card found: ");
-               } else if (!(val & SS_XVCARD)) {
-                       state.Vcc = state.Vpp = 50;
-                       puts (" 5.0V card found: ");
-               } else {
-                       puts ("i82365: unsupported voltage key\n");
-                       state.Vcc = state.Vpp = 0;
-               }
-       } else {
-               /* No card inserted */
-               puts ("No card\n");
-               return 1;
-       }
-#endif /* CONFIG_CPC45 */
-
-#ifdef CONFIG_CPC45
-       state.flags |= SS_OUTPUT_ENA;
-#else
-       state.flags = SS_IOCARD | SS_OUTPUT_ENA;
-       state.csc_mask = 0;
-       state.io_irq = 0;
-#endif
-
-       i365_set_socket (&socket, &state);
-
-       for (i = 500; i; i--) {
-               if ((i365_get (&socket, I365_STATUS) & I365_CS_READY))
-                       break;
-               udelay (1000);
-       }
-
-       if (i == 0) {
-               /* PC Card not ready for data transfer */
-               puts ("i82365 PC Card not ready for data transfer\n");
-               return 1;
-       }
-       debug (" PC Card ready for data transfer: ");
-
-       mem.map = 0;
-       mem.flags = MAP_ATTRIB | MAP_ACTIVE;
-       mem.speed = 300;
-       mem.sys_start = CFG_PCMCIA_MEM_ADDR;
-       mem.sys_stop = CFG_PCMCIA_MEM_ADDR + CFG_PCMCIA_MEM_SIZE - 1;
-       mem.card_start = 0;
-       i365_set_mem_map (&socket, &mem);
-
-#ifdef CONFIG_CPC45
-       mem.map = 1;
-       mem.flags = MAP_ACTIVE;
-       mem.speed = 300;
-       mem.sys_start = CFG_PCMCIA_MEM_ADDR + CFG_PCMCIA_MEM_SIZE;
-       mem.sys_stop = CFG_PCMCIA_MEM_ADDR + (2 * CFG_PCMCIA_MEM_SIZE) - 1;
-       mem.card_start = 0;
-       i365_set_mem_map (&socket, &mem);
-
-#else  /* !CONFIG_CPC45 */
-
-       io.map = 0;
-       io.flags = MAP_AUTOSZ | MAP_ACTIVE;
-       io.speed = 0;
-       io.start = 0x0100;
-       io.stop = 0x010F;
-       i365_set_io_map (&socket, &io);
-
-#endif /* CONFIG_CPC45 */
-
-#ifdef DEBUG
-       i82365_dump_regions (socket.dev);
-#endif
-
-       return 0;
-}
-
-void i82365_exit (void)
-{
-       io.map = 0;
-       io.flags = 0;
-       io.speed = 0;
-       io.start = 0;
-       io.stop = 0x1;
-
-       i365_set_io_map (&socket, &io);
-
-       mem.map = 0;
-       mem.flags = 0;
-       mem.speed = 0;
-       mem.sys_start = 0;
-       mem.sys_stop = 0x1000;
-       mem.card_start = 0;
-
-       i365_set_mem_map (&socket, &mem);
-
-#ifdef CONFIG_CPC45
-       mem.map = 1;
-       mem.flags = 0;
-       mem.speed = 0;
-       mem.sys_start = 0;
-       mem.sys_stop = 0x1000;
-       mem.card_start = 0;
-
-       i365_set_mem_map (&socket, &mem);
-#else  /* !CONFIG_CPC45 */
-       socket.state.sysctl &= 0xFFFF00FF;
-#endif
-       state.Vcc = state.Vpp = 0;
-
-       i365_set_socket (&socket, &state);
-}
-
-/*======================================================================
-
-    Debug stuff
-
-======================================================================*/
-
-#ifdef DEBUG
-static void i82365_dump_regions (pci_dev_t dev)
-{
-       u_int tmp[2];
-       u_int *mem = (void *) socket.cb_phys;
-       u_char *cis = (void *) CFG_PCMCIA_MEM_ADDR;
-       u_char *ide = (void *) (CFG_ATA_BASE_ADDR + CFG_ATA_REG_OFFSET);
-
-       pci_read_config_dword (dev, 0x00, tmp + 0);
-       pci_read_config_dword (dev, 0x80, tmp + 1);
-
-       printf ("PCI CONF: %08X ... %08X\n",
-               tmp[0], tmp[1]);
-       printf ("PCI MEM:  ... %08X ... %08X\n",
-               mem[0x8 / 4], mem[0x800 / 4]);
-       printf ("CIS:      ...%c%c%c%c%c%c%c%c...\n",
-               cis[0x38], cis[0x3a], cis[0x3c], cis[0x3e],
-               cis[0x40], cis[0x42], cis[0x44], cis[0x48]);
-       printf ("CIS CONF: %02X %02X %02X ...\n",
-               cis[0x200], cis[0x202], cis[0x204]);
-       printf ("IDE:      %02X %02X %02X %02X %02X %02X %02X %02X\n",
-               ide[0], ide[1], ide[2], ide[3],
-               ide[4], ide[5], ide[6], ide[7]);
-}
-#endif /* DEBUG */
-
-#endif /* CONFIG_I82365 */
diff --git a/drivers/inca-ip_sw.c b/drivers/inca-ip_sw.c
deleted file mode 100644 (file)
index e4aaed6..0000000
+++ /dev/null
@@ -1,817 +0,0 @@
-/*
- * INCA-IP internal switch ethernet driver.
- *
- * (C) Copyright 2003-2004
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-
-#include <common.h>
-
-#if defined(CONFIG_CMD_NET) \
-       && defined(CONFIG_NET_MULTI) && defined(CONFIG_INCA_IP_SWITCH)
-
-#include <malloc.h>
-#include <net.h>
-#include <asm/inca-ip.h>
-#include <asm/addrspace.h>
-
-
-#define NUM_RX_DESC    PKTBUFSRX
-#define NUM_TX_DESC    3
-#define TOUT_LOOP      1000000
-
-
-#define DELAY  udelay(10000)
-  /* Sometimes the store word instruction hangs while writing to one
-   * of the Switch registers. Moving the instruction into a separate
-   * function somehow makes the problem go away.
-   */
-static void SWORD(volatile u32 * reg, u32 value)
-{
-       *reg = value;
-}
-
-#define DMA_WRITE_REG(reg, value) *((volatile u32 *)reg) = (u32)value;
-#define DMA_READ_REG(reg, value)    value = (u32)*((volatile u32*)reg)
-#define SW_WRITE_REG(reg, value)   \
-       SWORD(reg, value);\
-       DELAY;\
-       SWORD(reg, value);
-
-#define SW_READ_REG(reg, value)           \
-       value = (u32)*((volatile u32*)reg);\
-       DELAY;\
-       value = (u32)*((volatile u32*)reg);
-
-#define INCA_DMA_TX_POLLING_TIME       0x07
-#define INCA_DMA_RX_POLLING_TIME       0x07
-
-#define INCA_DMA_TX_HOLD               0x80000000
-#define INCA_DMA_TX_EOP                        0x40000000
-#define INCA_DMA_TX_SOP                        0x20000000
-#define INCA_DMA_TX_ICPT               0x10000000
-#define INCA_DMA_TX_IEOP               0x08000000
-
-#define INCA_DMA_RX_C                  0x80000000
-#define INCA_DMA_RX_SOP                        0x40000000
-#define INCA_DMA_RX_EOP                        0x20000000
-
-#define INCA_SWITCH_PHY_SPEED_10H      0x1
-#define INCA_SWITCH_PHY_SPEED_10F      0x5
-#define INCA_SWITCH_PHY_SPEED_100H     0x2
-#define INCA_SWITCH_PHY_SPEED_100F     0x6
-
-/************************ Auto MDIX settings ************************/
-#define INCA_IP_AUTO_MDIX_LAN_PORTS_DIR                INCA_IP_Ports_P1_DIR
-#define INCA_IP_AUTO_MDIX_LAN_PORTS_ALTSEL     INCA_IP_Ports_P1_ALTSEL
-#define INCA_IP_AUTO_MDIX_LAN_PORTS_OUT                INCA_IP_Ports_P1_OUT
-#define INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX    16
-
-#define WAIT_SIGNAL_RETRIES                    100
-#define WAIT_LINK_RETRIES                      100
-#define LINK_RETRY_DELAY                       2000  /* ms */
-/********************************************************************/
-
-typedef struct
-{
-       union {
-               struct {
-                       volatile u32 HOLD               :1;
-                       volatile u32 ICpt               :1;
-                       volatile u32 IEop               :1;
-                       volatile u32 offset             :3;
-                       volatile u32 reserved0          :4;
-                       volatile u32 NFB                :22;
-               }field;
-
-               volatile u32 word;
-       }params;
-
-       volatile u32 nextRxDescPtr;
-
-       volatile u32 RxDataPtr;
-
-       union {
-               struct {
-                       volatile u32 C                  :1;
-                       volatile u32 Sop                :1;
-                       volatile u32 Eop                :1;
-                       volatile u32 reserved3          :12;
-                       volatile u32 NBT                :17;
-               }field;
-
-               volatile u32 word;
-       }status;
-
-} inca_rx_descriptor_t;
-
-
-typedef struct
-{
-       union {
-               struct {
-                       volatile u32 HOLD               :1;
-                       volatile u32 Eop                :1;
-                       volatile u32 Sop                :1;
-                       volatile u32 ICpt               :1;
-                       volatile u32 IEop               :1;
-                       volatile u32 reserved0          :5;
-                       volatile u32 NBA                :22;
-               }field;
-
-               volatile u32 word;
-       }params;
-
-       volatile u32 nextTxDescPtr;
-
-       volatile u32 TxDataPtr;
-
-       volatile u32 C                  :1;
-       volatile u32 reserved3          :31;
-
-} inca_tx_descriptor_t;
-
-
-static inca_rx_descriptor_t rx_ring[NUM_RX_DESC] __attribute__ ((aligned(16)));
-static inca_tx_descriptor_t tx_ring[NUM_TX_DESC] __attribute__ ((aligned(16)));
-
-static int tx_new, rx_new, tx_hold, rx_hold;
-static int tx_old_hold = -1;
-static int initialized = 0;
-
-
-static int inca_switch_init(struct eth_device *dev, bd_t * bis);
-static int inca_switch_send(struct eth_device *dev, volatile void *packet, int length);
-static int inca_switch_recv(struct eth_device *dev);
-static void inca_switch_halt(struct eth_device *dev);
-static void inca_init_switch_chip(void);
-static void inca_dma_init(void);
-static int inca_amdix(void);
-
-
-int inca_switch_initialize(bd_t * bis)
-{
-       struct eth_device *dev;
-
-#if 0
-       printf("Entered inca_switch_initialize()\n");
-#endif
-
-       if (!(dev = (struct eth_device *) malloc (sizeof *dev))) {
-               printf("Failed to allocate memory\n");
-               return 0;
-       }
-       memset(dev, 0, sizeof(*dev));
-
-       inca_dma_init();
-
-       inca_init_switch_chip();
-
-#if defined(CONFIG_INCA_IP_SWITCH_AMDIX)
-       inca_amdix();
-#endif
-
-       sprintf(dev->name, "INCA-IP Switch");
-       dev->init = inca_switch_init;
-       dev->halt = inca_switch_halt;
-       dev->send = inca_switch_send;
-       dev->recv = inca_switch_recv;
-
-       eth_register(dev);
-
-#if 0
-       printf("Leaving inca_switch_initialize()\n");
-#endif
-
-       return 1;
-}
-
-
-static int inca_switch_init(struct eth_device *dev, bd_t * bis)
-{
-       int i;
-       u32 v, regValue;
-       u16 wTmp;
-
-#if 0
-       printf("Entering inca_switch_init()\n");
-#endif
-
-       /* Set MAC address.
-        */
-       wTmp = (u16)dev->enetaddr[0];
-       regValue = (wTmp << 8) | dev->enetaddr[1];
-
-       SW_WRITE_REG(INCA_IP_Switch_PMAC_SA1, regValue);
-
-       wTmp = (u16)dev->enetaddr[2];
-       regValue = (wTmp << 8) | dev->enetaddr[3];
-       regValue = regValue << 16;
-       wTmp = (u16)dev->enetaddr[4];
-       regValue |= (wTmp<<8) | dev->enetaddr[5];
-
-       SW_WRITE_REG(INCA_IP_Switch_PMAC_SA2, regValue);
-
-       /* Initialize the descriptor rings.
-        */
-       for (i = 0; i < NUM_RX_DESC; i++) {
-               inca_rx_descriptor_t * rx_desc = KSEG1ADDR(&rx_ring[i]);
-               memset(rx_desc, 0, sizeof(rx_ring[i]));
-
-               /* Set maximum size of receive buffer.
-                */
-               rx_desc->params.field.NFB = PKTSIZE_ALIGN;
-
-               /* Set the offset of the receive buffer. Zero means
-                * that the offset mechanism is not used.
-                */
-               rx_desc->params.field.offset = 0;
-
-               /* Check if it is the last descriptor.
-                */
-               if (i == (NUM_RX_DESC - 1)) {
-                       /* Let the last descriptor point to the first
-                        * one.
-                        */
-                       rx_desc->nextRxDescPtr = KSEG1ADDR((u32)rx_ring);
-               } else {
-                       /* Set the address of the next descriptor.
-                        */
-                       rx_desc->nextRxDescPtr = (u32)KSEG1ADDR(&rx_ring[i+1]);
-               }
-
-               rx_desc->RxDataPtr = (u32)KSEG1ADDR(NetRxPackets[i]);
-       }
-
-#if 0
-       printf("rx_ring = 0x%08X 0x%08X\n", (u32)rx_ring, (u32)&rx_ring[0]);
-       printf("tx_ring = 0x%08X 0x%08X\n", (u32)tx_ring, (u32)&tx_ring[0]);
-#endif
-
-       for (i = 0; i < NUM_TX_DESC; i++) {
-               inca_tx_descriptor_t * tx_desc = KSEG1ADDR(&tx_ring[i]);
-
-               memset(tx_desc, 0, sizeof(tx_ring[i]));
-
-               tx_desc->params.word       = 0;
-               tx_desc->params.field.HOLD = 1;
-               tx_desc->C                 = 1;
-
-                       /* Check if it is the last descriptor.
-                        */
-               if (i == (NUM_TX_DESC - 1)) {
-                               /* Let the last descriptor point to the
-                                * first one.
-                                */
-                       tx_desc->nextTxDescPtr = KSEG1ADDR((u32)tx_ring);
-               } else {
-                               /* Set the address of the next descriptor.
-                                */
-                       tx_desc->nextTxDescPtr = (u32)KSEG1ADDR(&tx_ring[i+1]);
-               }
-       }
-
-       /* Initialize RxDMA.
-        */
-       DMA_READ_REG(INCA_IP_DMA_DMA_RXISR, v);
-#if 0
-       printf("RX status = 0x%08X\n", v);
-#endif
-
-       /* Writing to the FRDA of CHANNEL.
-        */
-       DMA_WRITE_REG(INCA_IP_DMA_DMA_RXFRDA0, (u32)rx_ring);
-
-       /* Writing to the COMMAND REG.
-        */
-       DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_INIT);
-
-       /* Initialize TxDMA.
-        */
-       DMA_READ_REG(INCA_IP_DMA_DMA_TXISR, v);
-#if 0
-       printf("TX status = 0x%08X\n", v);
-#endif
-
-       /* Writing to the FRDA of CHANNEL.
-        */
-       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXFRDA0, (u32)tx_ring);
-
-       tx_new = rx_new = 0;
-
-       tx_hold = NUM_TX_DESC - 1;
-       rx_hold = NUM_RX_DESC - 1;
-
-#if 0
-       rx_ring[rx_hold].params.field.HOLD = 1;
-#endif
-       /* enable spanning tree forwarding, enable the CPU port */
-       /* ST_PT:
-        *      CPS (CPU port status)   0x3 (forwarding)
-        *      LPS (LAN port status)   0x3 (forwarding)
-        *      PPS (PC port status)    0x3 (forwarding)
-        */
-       SW_WRITE_REG(INCA_IP_Switch_ST_PT,0x3f);
-
-#if 0
-       printf("Leaving inca_switch_init()\n");
-#endif
-
-       return 0;
-}
-
-
-static int inca_switch_send(struct eth_device *dev, volatile void *packet, int length)
-{
-       int                    i;
-       int                    res      = -1;
-       u32                    command;
-       u32                    regValue;
-       inca_tx_descriptor_t * tx_desc  = KSEG1ADDR(&tx_ring[tx_new]);
-
-#if 0
-       printf("Entered inca_switch_send()\n");
-#endif
-
-       if (length <= 0) {
-               printf ("%s: bad packet size: %d\n", dev->name, length);
-               goto Done;
-       }
-
-       for(i = 0; tx_desc->C == 0; i++) {
-               if (i >= TOUT_LOOP) {
-                       printf("%s: tx error buffer not ready\n", dev->name);
-                       goto Done;
-               }
-       }
-
-       if (tx_old_hold >= 0) {
-               KSEG1ADDR(&tx_ring[tx_old_hold])->params.field.HOLD = 1;
-       }
-       tx_old_hold = tx_hold;
-
-       tx_desc->params.word =
-                       (INCA_DMA_TX_SOP | INCA_DMA_TX_EOP | INCA_DMA_TX_HOLD);
-
-       tx_desc->C = 0;
-       tx_desc->TxDataPtr = (u32)packet;
-       tx_desc->params.field.NBA = length;
-
-       KSEG1ADDR(&tx_ring[tx_hold])->params.field.HOLD = 0;
-
-       tx_hold = tx_new;
-       tx_new  = (tx_new + 1) % NUM_TX_DESC;
-
-
-       if (! initialized) {
-               command = INCA_IP_DMA_DMA_TXCCR0_INIT;
-               initialized = 1;
-       } else {
-               command = INCA_IP_DMA_DMA_TXCCR0_HR;
-       }
-
-       DMA_READ_REG(INCA_IP_DMA_DMA_TXCCR0, regValue);
-       regValue |= command;
-#if 0
-       printf("regValue = 0x%x\n", regValue);
-#endif
-       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, regValue);
-
-#if 1
-       for(i = 0; KSEG1ADDR(&tx_ring[tx_hold])->C == 0; i++) {
-               if (i >= TOUT_LOOP) {
-                       printf("%s: tx buffer not ready\n", dev->name);
-                       goto Done;
-               }
-       }
-#endif
-       res = length;
-Done:
-#if 0
-       printf("Leaving inca_switch_send()\n");
-#endif
-       return res;
-}
-
-
-static int inca_switch_recv(struct eth_device *dev)
-{
-       int                    length  = 0;
-       inca_rx_descriptor_t * rx_desc;
-
-#if 0
-       printf("Entered inca_switch_recv()\n");
-#endif
-
-       for (;;) {
-               rx_desc = KSEG1ADDR(&rx_ring[rx_new]);
-
-               if (rx_desc->status.field.C == 0) {
-                       break;
-               }
-
-#if 0
-               rx_ring[rx_new].params.field.HOLD = 1;
-#endif
-
-               if (! rx_desc->status.field.Eop) {
-                       printf("Partly received packet!!!\n");
-                       break;
-               }
-
-               length = rx_desc->status.field.NBT;
-               rx_desc->status.word &=
-                        ~(INCA_DMA_RX_EOP | INCA_DMA_RX_SOP | INCA_DMA_RX_C);
-#if 0
-{
-  int i;
-  for (i=0;i<length - 4;i++) {
-    if (i % 16 == 0) printf("\n%04x: ", i);
-    printf("%02X ", NetRxPackets[rx_new][i]);
-  }
-  printf("\n");
-}
-#endif
-
-               if (length) {
-#if 0
-                       printf("Received %d bytes\n", length);
-#endif
-                       NetReceive((void*)KSEG1ADDR(NetRxPackets[rx_new]), length - 4);
-               } else {
-#if 1
-                       printf("Zero length!!!\n");
-#endif
-               }
-
-
-               KSEG1ADDR(&rx_ring[rx_hold])->params.field.HOLD = 0;
-
-               rx_hold = rx_new;
-
-               rx_new = (rx_new + 1) % NUM_RX_DESC;
-       }
-
-#if 0
-       printf("Leaving inca_switch_recv()\n");
-#endif
-
-       return length;
-}
-
-
-static void inca_switch_halt(struct eth_device *dev)
-{
-#if 0
-       printf("Entered inca_switch_halt()\n");
-#endif
-
-#if 1
-       initialized = 0;
-#endif
-#if 1
-       /* Disable forwarding to the CPU port.
-        */
-       SW_WRITE_REG(INCA_IP_Switch_ST_PT,0xf);
-
-       /* Close RxDMA channel.
-        */
-       DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF);
-
-       /* Close TxDMA channel.
-        */
-       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, INCA_IP_DMA_DMA_TXCCR0_OFF);
-
-
-#endif
-#if 0
-       printf("Leaving inca_switch_halt()\n");
-#endif
-}
-
-
-static void inca_init_switch_chip(void)
-{
-       u32 regValue;
-
-       /* To workaround a problem with collision counter
-        * (see Errata sheet).
-        */
-       SW_WRITE_REG(INCA_IP_Switch_PC_TX_CTL, 0x00000001);
-       SW_WRITE_REG(INCA_IP_Switch_LAN_TX_CTL, 0x00000001);
-
-#if 1
-       /* init MDIO configuration:
-        *      MDS (Poll speed):       0x01 (4ms)
-        *      PHY_LAN_ADDR:           0x06
-        *      PHY_PC_ADDR:            0x05
-        *      UEP (Use External PHY): 0x00 (Internal PHY is used)
-        *      PS (Port Select):       0x00 (PT/UMM for LAN)
-        *      PT (PHY Test):          0x00 (no test mode)
-        *      UMM (Use MDIO Mode):    0x00 (state machine is disabled)
-        */
-       SW_WRITE_REG(INCA_IP_Switch_MDIO_CFG, 0x4c50);
-
-       /* init PHY:
-        *      SL (Auto Neg. Speed for LAN)
-        *      SP (Auto Neg. Speed for PC)
-        *      LL (Link Status for LAN)
-        *      LP (Link Status for PC)
-        *      DL (Duplex Status for LAN)
-        *      DP (Duplex Status for PC)
-        *      PL (Auto Neg. Pause Status for LAN)
-        *      PP (Auto Neg. Pause Status for PC)
-        */
-       SW_WRITE_REG (INCA_IP_Switch_EPHY, 0xff);
-
-       /* MDIO_ACC:
-        *      RA (Request/Ack)  0x01 (Request)
-        *      RW (Read/Write)   0x01 (Write)
-        *      PHY_ADDR          0x05 (PC)
-        *      REG_ADDR          0x00 (PHY_BCR: basic control register)
-        *      PHY_DATA          0x8000
-        *                    Reset                   - software reset
-        *                    LB (loop back)          - normal
-        *                    SS (speed select)       - 10 Mbit/s
-        *                    ANE (auto neg. enable)  - enable
-        *                    PD (power down)         - normal
-        *                    ISO (isolate)           - normal
-        *                    RAN (restart auto neg.) - normal
-        *                    DM (duplex mode)        - half duplex
-        *                    CT (collision test)     - enable
-        */
-       SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, 0xc0a09000);
-
-       /* MDIO_ACC:
-        *      RA (Request/Ack)  0x01 (Request)
-        *      RW (Read/Write)   0x01 (Write)
-        *      PHY_ADDR          0x06 (LAN)
-        *      REG_ADDR          0x00 (PHY_BCR: basic control register)
-        *      PHY_DATA          0x8000
-        *                    Reset                   - software reset
-        *                    LB (loop back)          - normal
-        *                    SS (speed select)       - 10 Mbit/s
-        *                    ANE (auto neg. enable)  - enable
-        *                    PD (power down)         - normal
-        *                    ISO (isolate)           - normal
-        *                    RAN (restart auto neg.) - normal
-        *                    DM (duplex mode)        - half duplex
-        *                    CT (collision test)     - enable
-        */
-       SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, 0xc0c09000);
-
-#endif
-
-       /* Make sure the CPU port is disabled for now. We
-        * don't want packets to get stacked for us until
-        * we enable DMA and are prepared to receive them.
-        */
-       SW_WRITE_REG(INCA_IP_Switch_ST_PT,0xf);
-
-       SW_READ_REG(INCA_IP_Switch_ARL_CTL, regValue);
-
-       /* CRC GEN is enabled.
-        */
-       regValue |= 0x00000200;
-       SW_WRITE_REG(INCA_IP_Switch_ARL_CTL, regValue);
-
-       /* ADD TAG is disabled.
-        */
-       SW_READ_REG(INCA_IP_Switch_PMAC_HD_CTL, regValue);
-       regValue &= ~0x00000002;
-       SW_WRITE_REG(INCA_IP_Switch_PMAC_HD_CTL, regValue);
-}
-
-
-static void inca_dma_init(void)
-{
-       /* Switch off all DMA channels.
-        */
-       DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF);
-       DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR1, INCA_IP_DMA_DMA_RXCCR1_OFF);
-
-       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF);
-       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR1, INCA_IP_DMA_DMA_TXCCR1_OFF);
-       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR2, INCA_IP_DMA_DMA_TXCCR2_OFF);
-
-       /* Setup TX channel polling time.
-        */
-       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXPOLL, INCA_DMA_TX_POLLING_TIME);
-
-       /* Setup RX channel polling time.
-        */
-       DMA_WRITE_REG(INCA_IP_DMA_DMA_RXPOLL, INCA_DMA_RX_POLLING_TIME);
-
-       /* ERRATA: write reset value into the DMA RX IMR register.
-        */
-       DMA_WRITE_REG(INCA_IP_DMA_DMA_RXIMR, 0xFFFFFFFF);
-
-       /* Just in case: disable all transmit interrupts also.
-        */
-       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXIMR, 0xFFFFFFFF);
-
-       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXISR, 0xFFFFFFFF);
-       DMA_WRITE_REG(INCA_IP_DMA_DMA_RXISR, 0xFFFFFFFF);
-}
-
-#if defined(CONFIG_INCA_IP_SWITCH_AMDIX)
-static int inca_amdix(void)
-{
-       u32 phyReg1 = 0;
-       u32 phyReg4 = 0;
-       u32 phyReg5 = 0;
-       u32 phyReg6 = 0;
-       u32 phyReg31 = 0;
-       u32 regEphy = 0;
-       int mdi_flag;
-       int retries;
-
-       /* Setup GPIO pins.
-        */
-       *INCA_IP_AUTO_MDIX_LAN_PORTS_DIR    |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
-       *INCA_IP_AUTO_MDIX_LAN_PORTS_ALTSEL |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
-
-#if 0
-       /* Wait for signal.
-        */
-       retries = WAIT_SIGNAL_RETRIES;
-       while (--retries) {
-               SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
-                               (0x1 << 31) |   /* RA           */
-                               (0x0 << 30) |   /* Read         */
-                               (0x6 << 21) |   /* LAN          */
-                               (17  << 16));   /* PHY_MCSR     */
-               do {
-                       SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1);
-               } while (phyReg1 & (1 << 31));
-
-               if (phyReg1 & (1 << 1)) {
-                       /* Signal detected */
-                       break;
-               }
-       }
-
-       if (!retries)
-               goto Fail;
-#endif
-
-       /* Set MDI mode.
-        */
-       *INCA_IP_AUTO_MDIX_LAN_PORTS_OUT &= ~(1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
-       mdi_flag = 1;
-
-       /* Wait for link.
-        */
-       retries = WAIT_LINK_RETRIES;
-       while (--retries) {
-               udelay(LINK_RETRY_DELAY * 1000);
-               SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
-                               (0x1 << 31) |   /* RA           */
-                               (0x0 << 30) |   /* Read         */
-                               (0x6 << 21) |   /* LAN          */
-                               (1   << 16));   /* PHY_BSR      */
-               do {
-                       SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1);
-               } while (phyReg1 & (1 << 31));
-
-               if (phyReg1 & (1 << 2)) {
-                       /* Link is up */
-                       break;
-               } else if (mdi_flag) {
-                       /* Set MDIX mode */
-                       *INCA_IP_AUTO_MDIX_LAN_PORTS_OUT |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
-                       mdi_flag = 0;
-               } else {
-                       /* Set MDI mode */
-                       *INCA_IP_AUTO_MDIX_LAN_PORTS_OUT &= ~(1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
-                       mdi_flag = 1;
-               }
-       }
-
-       if (!retries) {
-               goto Fail;
-       } else {
-               SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
-                               (0x1 << 31) |   /* RA           */
-                               (0x0 << 30) |   /* Read         */
-                               (0x6 << 21) |   /* LAN          */
-                               (1   << 16));   /* PHY_BSR      */
-               do {
-                       SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1);
-               } while (phyReg1 & (1 << 31));
-
-               /* Auto-negotiation / Parallel detection complete
-                */
-               if (phyReg1 & (1 << 5)) {
-                       SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
-                               (0x1 << 31) |   /* RA           */
-                               (0x0 << 30) |   /* Read         */
-                               (0x6 << 21) |   /* LAN          */
-                               (31  << 16));   /* PHY_SCSR     */
-                       do {
-                               SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg31);
-                       } while (phyReg31 & (1 << 31));
-
-                       switch ((phyReg31 >> 2) & 0x7) {
-                       case INCA_SWITCH_PHY_SPEED_10H:
-                               /* 10Base-T Half-duplex */
-                               regEphy = 0;
-                               break;
-                       case INCA_SWITCH_PHY_SPEED_10F:
-                               /* 10Base-T Full-duplex */
-                               regEphy = INCA_IP_Switch_EPHY_DL;
-                               break;
-                       case INCA_SWITCH_PHY_SPEED_100H:
-                               /* 100Base-TX Half-duplex */
-                               regEphy = INCA_IP_Switch_EPHY_SL;
-                               break;
-                       case INCA_SWITCH_PHY_SPEED_100F:
-                               /* 100Base-TX Full-duplex */
-                               regEphy = INCA_IP_Switch_EPHY_SL | INCA_IP_Switch_EPHY_DL;
-                               break;
-                       }
-
-                       /* In case of Auto-negotiation,
-                        * update the negotiated PAUSE support status
-                        */
-                       if (phyReg1 & (1 << 3)) {
-                               SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
-                                       (0x1 << 31) |   /* RA           */
-                                       (0x0 << 30) |   /* Read         */
-                                       (0x6 << 21) |   /* LAN          */
-                                       (6   << 16));   /* PHY_ANER     */
-                               do {
-                                       SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg6);
-                               } while (phyReg6 & (1 << 31));
-
-                               /* We are Autoneg-able.
-                                * Is Link partner also able to autoneg?
-                                */
-                               if (phyReg6 & (1 << 0)) {
-                                       SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
-                                               (0x1 << 31) |   /* RA           */
-                                               (0x0 << 30) |   /* Read         */
-                                               (0x6 << 21) |   /* LAN          */
-                                               (4   << 16));   /* PHY_ANAR     */
-                                       do {
-                                               SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg4);
-                                       } while (phyReg4 & (1 << 31));
-
-                                       /* We advertise PAUSE capab.
-                                        * Does link partner also advertise it?
-                                        */
-                                       if (phyReg4 & (1 << 10)) {
-                                               SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
-                                                       (0x1 << 31) |   /* RA           */
-                                                       (0x0 << 30) |   /* Read         */
-                                                       (0x6 << 21) |   /* LAN          */
-                                                       (5   << 16));   /* PHY_ANLPAR   */
-                                               do {
-                                                       SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg5);
-                                               } while (phyReg5 & (1 << 31));
-
-                                               /* Link partner is PAUSE capab.
-                                                */
-                                               if (phyReg5 & (1 << 10)) {
-                                                       regEphy |= INCA_IP_Switch_EPHY_PL;
-                                               }
-                                       }
-                               }
-
-                       }
-
-                       /* Link is up */
-                       regEphy |= INCA_IP_Switch_EPHY_LL;
-
-                       SW_WRITE_REG(INCA_IP_Switch_EPHY, regEphy);
-               }
-       }
-
-       return 0;
-
-Fail:
-       printf("No Link on LAN port\n");
-       return -1;
-}
-#endif /* CONFIG_INCA_IP_SWITCH_AMDIX */
-
-#endif
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
new file mode 100644 (file)
index 0000000..df22cf9
--- /dev/null
@@ -0,0 +1,48 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libinput.a
+
+COBJS-y += i8042.o
+COBJS-y += keyboard.o
+COBJS-y += pc_keyb.o ps2ser.o ps2mult.o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/input/i8042.c b/drivers/input/i8042.c
new file mode 100644 (file)
index 0000000..22c2a4e
--- /dev/null
@@ -0,0 +1,674 @@
+/*
+ * (C) Copyright 2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* i8042.c - Intel 8042 keyboard driver routines */
+
+/* includes */
+
+#include <common.h>
+
+#ifdef CONFIG_I8042_KBD
+
+#ifdef CONFIG_USE_CPCIDVI
+extern u8  gt_cpcidvi_in8(u32 offset);
+extern void gt_cpcidvi_out8(u32 offset, u8 data);
+
+#define in8(a)    gt_cpcidvi_in8(a)
+#define out8(a, b) gt_cpcidvi_out8(a,b)
+#endif
+
+#include <i8042.h>
+
+/* defines */
+
+#ifdef CONFIG_CONSOLE_CURSOR
+extern void console_cursor (int state);
+static int blinkCount = CFG_CONSOLE_BLINK_COUNT;
+static int cursor_state = 0;
+#endif
+
+/* locals */
+
+static int  kbd_input   = -1;          /* no input yet */
+static int  kbd_mapping         = KBD_US;      /* default US keyboard */
+static int  kbd_flags   = NORMAL;      /* after reset */
+static int  kbd_state   = 0;           /* unshift code */
+
+static void kbd_conv_char (unsigned char scan_code);
+static void kbd_led_set (void);
+static void kbd_normal (unsigned char scan_code);
+static void kbd_shift (unsigned char scan_code);
+static void kbd_ctrl (unsigned char scan_code);
+static void kbd_num (unsigned char scan_code);
+static void kbd_caps (unsigned char scan_code);
+static void kbd_scroll (unsigned char scan_code);
+static void kbd_alt (unsigned char scan_code);
+static int  kbd_input_empty (void);
+static int  kbd_reset (void);
+
+static unsigned char kbd_fct_map [144] =
+    { /* kbd_fct_map table for scan code */
+    0,  AS,   AS,   AS,   AS,   AS,   AS,   AS, /* scan  0- 7 */
+   AS,  AS,   AS,   AS,   AS,   AS,   AS,   AS, /* scan  8- F */
+   AS,  AS,   AS,   AS,   AS,   AS,   AS,   AS, /* scan 10-17 */
+   AS,  AS,   AS,   AS,   AS,   CN,   AS,   AS, /* scan 18-1F */
+   AS,  AS,   AS,   AS,   AS,   AS,   AS,   AS, /* scan 20-27 */
+   AS,  AS,   SH,   AS,   AS,   AS,   AS,   AS, /* scan 28-2F */
+   AS,  AS,   AS,   AS,   AS,   AS,   SH,   AS, /* scan 30-37 */
+   AS,  AS,   CP,   0,    0,    0,    0,     0, /* scan 38-3F */
+    0,  0,    0,    0,    0,    NM,   ST,   ES, /* scan 40-47 */
+   ES,  ES,   ES,   ES,   ES,   ES,   ES,   ES, /* scan 48-4F */
+   ES,  ES,   ES,   ES,   0,    0,    AS,    0, /* scan 50-57 */
+    0,  0,    0,    0,    0,    0,    0,     0, /* scan 58-5F */
+    0,  0,    0,    0,    0,    0,    0,     0, /* scan 60-67 */
+    0,  0,    0,    0,    0,    0,    0,     0, /* scan 68-6F */
+   AS,  0,    0,    AS,   0,    0,    AS,    0, /* scan 70-77 */
+    0,  AS,   0,    0,    0,    AS,   0,     0, /* scan 78-7F */
+   AS,  CN,   AS,   AS,   AK,   ST,   EX,   EX, /* enhanced   */
+   AS,  EX,   EX,   AS,   EX,   AS,   EX,   EX  /* enhanced   */
+    };
+
+static unsigned char kbd_key_map [2][5][144] =
+    {
+    { /* US keyboard */
+    { /* unshift code */
+    0, 0x1b,   '1',   '2',   '3',   '4',   '5',   '6',    /* scan  0- 7 */
+  '7',  '8',   '9',   '0',   '-',   '=',  0x08,  '\t',    /* scan  8- F */
+  'q',  'w',   'e',   'r',   't',   'y',   'u',   'i',    /* scan 10-17 */
+  'o',  'p',   '[',   ']',  '\r',   CN,    'a',   's',    /* scan 18-1F */
+  'd',  'f',   'g',   'h',   'j',   'k',   'l',   ';',    /* scan 20-27 */
+ '\'',  '`',   SH,   '\\',   'z',   'x',   'c',   'v',    /* scan 28-2F */
+  'b',  'n',   'm',   ',',   '.',   '/',   SH,    '*',    /* scan 30-37 */
+  ' ',  ' ',   CP,      0,     0,     0,     0,     0,    /* scan 38-3F */
+    0,    0,     0,     0,     0,   NM,    ST,    '7',    /* scan 40-47 */
+  '8',  '9',   '-',   '4',   '5',   '6',   '+',   '1',    /* scan 48-4F */
+  '2',  '3',   '0',   '.',     0,     0,     0,     0,    /* scan 50-57 */
+    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 58-5F */
+    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 60-67 */
+    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 68-6F */
+    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 70-77 */
+    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 78-7F */
+  '\r',          CN,   '/',   '*',   ' ',    ST,   'F',   'A',    /* extended */
+    0,  'D',   'C',     0,   'B',     0,    '@',  'P'     /* extended */
+    },
+    { /* shift code */
+    0, 0x1b,   '!',   '@',   '#',   '$',   '%',   '^',    /* scan  0- 7 */
+  '&',  '*',   '(',   ')',   '_',   '+',  0x08,  '\t',    /* scan  8- F */
+  'Q',  'W',   'E',   'R',   'T',   'Y',   'U',   'I',    /* scan 10-17 */
+  'O',  'P',   '{',   '}',  '\r',   CN,    'A',   'S',    /* scan 18-1F */
+  'D',  'F',   'G',   'H',   'J',   'K',   'L',   ':',    /* scan 20-27 */
+  '"',  '~',   SH,    '|',   'Z',   'X',   'C',   'V',    /* scan 28-2F */
+  'B',  'N',   'M',   '<',   '>',   '?',   SH,    '*',    /* scan 30-37 */
+  ' ',  ' ',   CP,      0,     0,     0,     0,     0,    /* scan 38-3F */
+    0,    0,     0,     0,     0,   NM,    ST,    '7',    /* scan 40-47 */
+  '8',  '9',   '-',   '4',   '5',   '6',   '+',   '1',    /* scan 48-4F */
+  '2',  '3',   '0',   '.',     0,     0,     0,     0,    /* scan 50-57 */
+    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 58-5F */
+    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 60-67 */
+    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 68-6F */
+    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 70-77 */
+    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 78-7F */
+  '\r',          CN,   '/',   '*',   ' ',    ST,   'F',   'A',    /* extended */
+    0,  'D',   'C',     0,   'B',     0,   '@',   'P'     /* extended */
+    },
+    { /* control code */
+ 0xff, 0x1b,  0xff,  0x00,  0xff,  0xff,  0xff,  0xff,    /* scan  0- 7 */
+ 0x1e, 0xff,  0xff,  0xff,  0x1f,  0xff,  0xff,  '\t',    /* scan  8- F */
+ 0x11, 0x17,  0x05,  0x12,  0x14,  0x19,  0x15,  0x09,    /* scan 10-17 */
+ 0x0f, 0x10,  0x1b,  0x1d,  '\r',   CN,   0x01,  0x13,    /* scan 18-1F */
+ 0x04, 0x06,  0x07,  0x08,  0x0a,  0x0b,  0x0c,  0xff,    /* scan 20-27 */
+ 0xff, 0x1c,   SH,   0xff,  0x1a,  0x18,  0x03,  0x16,    /* scan 28-2F */
+ 0x02, 0x0e,  0x0d,  0xff,  0xff,  0xff,   SH,   0xff,    /* scan 30-37 */
+ 0xff, 0xff,   CP,   0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 38-3F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,   NM,    ST,   0xff,    /* scan 40-47 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 48-4F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 50-57 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 58-5F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 60-67 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 68-6F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 70-77 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,    /* scan 78-7F */
+  '\r',          CN,   '/',   '*',   ' ',    ST,  0xff,  0xff,    /* extended */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff     /* extended */
+    },
+    { /* non numeric code */
+    0, 0x1b,   '1',   '2',   '3',   '4',   '5',   '6',    /* scan  0- 7 */
+  '7',  '8',   '9',   '0',   '-',   '=',  0x08,  '\t',    /* scan  8- F */
+  'q',  'w',   'e',   'r',   't',   'y',   'u',   'i',    /* scan 10-17 */
+  'o',  'p',   '[',   ']',  '\r',   CN,    'a',   's',    /* scan 18-1F */
+  'd',  'f',   'g',   'h',   'j',   'k',   'l',   ';',    /* scan 20-27 */
+ '\'',  '`',   SH,   '\\',   'z',   'x',   'c',   'v',    /* scan 28-2F */
+  'b',  'n',   'm',   ',',   '.',   '/',   SH,    '*',    /* scan 30-37 */
+  ' ',  ' ',   CP,      0,     0,     0,     0,     0,    /* scan 38-3F */
+    0,    0,     0,     0,     0,   NM,    ST,    'w',    /* scan 40-47 */
+  'x',  'y',   'l',   't',   'u',   'v',   'm',   'q',    /* scan 48-4F */
+  'r',  's',   'p',   'n',     0,     0,     0,     0,    /* scan 50-57 */
+    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 58-5F */
+    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 60-67 */
+    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 68-6F */
+    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 70-77 */
+    0,    0,     0,     0,     0,     0,     0,     0,    /* scan 78-7F */
+  '\r',          CN,   '/',   '*',   ' ',    ST,   'F',   'A',    /* extended */
+    0,  'D',   'C',     0,   'B',     0,    '@',  'P'     /* extended */
+    },
+    { /* right alt mode - not used in US keyboard */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan  0 - 7 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan  8 - F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 10 -17 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 18 -1F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 20 -27 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 28 -2F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 30 -37 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 38 -3F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 40 -47 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 48 -4F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 50 -57 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 58 -5F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 60 -67 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 68 -6F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 70 -77 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 78 -7F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* extended    */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff  /* extended    */
+    }
+    },
+    { /* german keyboard */
+    { /* unshift code */
+    0, 0x1b,   '1',   '2',   '3',   '4',   '5',   '6', /* scan  0- 7 */
+  '7',  '8',   '9',   '0',  0xe1,  '\'',  0x08,  '\t', /* scan  8- F */
+  'q',  'w',   'e',   'r',   't',   'z',   'u',   'i', /* scan 10-17 */
+  'o',  'p',  0x81,   '+',  '\r',   CN,    'a',   's', /* scan 18-1F */
+  'd',  'f',   'g',   'h',   'j',   'k',   'l',  0x94, /* scan 20-27 */
+ 0x84,  '^',   SH,    '#',   'y',   'x',   'c',   'v', /* scan 28-2F */
+  'b',  'n',   'm',   ',',   '.',   '-',   SH,    '*', /* scan 30-37 */
+  ' ',  ' ',   CP,      0,     0,     0,     0,     0, /* scan 38-3F */
+    0,    0,     0,     0,     0,   NM,    ST,    '7', /* scan 40-47 */
+  '8',  '9',   '-',   '4',   '5',   '6',   '+',   '1', /* scan 48-4F */
+  '2',  '3',   '0',   ',',     0,     0,   '<',     0, /* scan 50-57 */
+    0,    0,     0,     0,     0,     0,     0,     0, /* scan 58-5F */
+    0,    0,     0,     0,     0,     0,     0,     0, /* scan 60-67 */
+    0,    0,     0,     0,     0,     0,     0,     0, /* scan 68-6F */
+    0,    0,     0,     0,     0,     0,     0,     0, /* scan 70-77 */
+    0,    0,     0,     0,     0,     0,     0,     0, /* scan 78-7F */
+  '\r',          CN,   '/',   '*',   ' ',    ST,   'F',   'A', /* extended */
+    0,  'D',   'C',     0,   'B',     0,    '@',  'P'  /* extended */
+    },
+    { /* shift code */
+    0, 0x1b,   '!',   '"',  0x15,   '$',   '%',   '&', /* scan  0- 7 */
+  '/',  '(',   ')',   '=',   '?',   '`',  0x08,  '\t', /* scan  8- F */
+  'Q',  'W',   'E',   'R',   'T',   'Z',   'U',   'I', /* scan 10-17 */
+  'O',  'P',  0x9a,   '*',  '\r',   CN,    'A',   'S', /* scan 18-1F */
+  'D',  'F',   'G',   'H',   'J',   'K',   'L',  0x99, /* scan 20-27 */
+ 0x8e, 0xf8,   SH,   '\'',   'Y',   'X',   'C',   'V', /* scan 28-2F */
+  'B',  'N',   'M',   ';',   ':',   '_',   SH,    '*', /* scan 30-37 */
+  ' ',  ' ',   CP,      0,     0,     0,     0,     0, /* scan 38-3F */
+    0,    0,     0,     0,     0,   NM,    ST,    '7', /* scan 40-47 */
+  '8',  '9',   '-',   '4',   '5',   '6',   '+',   '1', /* scan 48-4F */
+  '2',  '3',   '0',   ',',     0,     0,   '>',     0, /* scan 50-57 */
+    0,    0,     0,     0,     0,     0,     0,     0, /* scan 58-5F */
+    0,    0,     0,     0,     0,     0,     0,     0, /* scan 60-67 */
+    0,    0,     0,     0,     0,     0,     0,     0, /* scan 68-6F */
+    0,    0,     0,     0,     0,     0,     0,     0, /* scan 70-77 */
+    0,    0,     0,     0,     0,     0,     0,     0, /* scan 78-7F */
+  '\r',          CN,   '/',   '*',   ' ',    ST,   'F',   'A', /* extended */
+    0,  'D',   'C',     0,   'B',     0,   '@',   'P'  /* extended */
+    },
+    { /* control code */
+ 0xff, 0x1b,  0xff,  0x00,  0xff,  0xff,  0xff,  0xff, /* scan  0- 7 */
+ 0x1e, 0xff,  0xff,  0xff,  0x1f,  0xff,  0xff,  '\t', /* scan  8- F */
+ 0x11, 0x17,  0x05,  0x12,  0x14,  0x19,  0x15,  0x09, /* scan 10-17 */
+ 0x0f, 0x10,  0x1b,  0x1d,  '\r',   CN,   0x01,  0x13, /* scan 18-1F */
+ 0x04, 0x06,  0x07,  0x08,  0x0a,  0x0b,  0x0c,  0xff, /* scan 20-27 */
+ 0xff, 0x1c,   SH,   0xff,  0x1a,  0x18,  0x03,  0x16, /* scan 28-2F */
+ 0x02, 0x0e,  0x0d,  0xff,  0xff,  0xff,   SH,   0xff, /* scan 30-37 */
+ 0xff, 0xff,   CP,   0xff,  0xff,  0xff,  0xff,  0xff, /* scan 38-3F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,   NM,    ST,   0xff, /* scan 40-47 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 48-4F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 50-57 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 58-5F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 60-67 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 68-6F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 70-77 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 78-7F */
+  '\r',          CN,   '/',   '*',   ' ',    ST,  0xff,  0xff, /* extended */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff  /* extended */
+    },
+    { /* non numeric code */
+    0, 0x1b,   '1',   '2',   '3',   '4',   '5',   '6', /* scan  0- 7 */
+  '7',  '8',   '9',   '0',  0xe1,  '\'',  0x08,  '\t', /* scan  8- F */
+  'q',  'w',   'e',   'r',   't',   'z',   'u',   'i', /* scan 10-17 */
+  'o',  'p',  0x81,   '+',  '\r',   CN,    'a',   's', /* scan 18-1F */
+  'd',  'f',   'g',   'h',   'j',   'k',   'l',  0x94, /* scan 20-27 */
+ 0x84,  '^',   SH,      0,   'y',   'x',   'c',   'v', /* scan 28-2F */
+  'b',  'n',   'm',   ',',   '.',   '-',   SH,    '*', /* scan 30-37 */
+  ' ',  ' ',   CP,      0,     0,     0,     0,     0, /* scan 38-3F */
+    0,    0,     0,     0,     0,   NM,    ST,    'w', /* scan 40-47 */
+  'x',  'y',   'l',   't',   'u',   'v',   'm',   'q', /* scan 48-4F */
+  'r',  's',   'p',   'n',     0,     0,   '<',     0, /* scan 50-57 */
+    0,    0,     0,     0,     0,     0,     0,     0, /* scan 58-5F */
+    0,    0,     0,     0,     0,     0,     0,     0, /* scan 60-67 */
+    0,    0,     0,     0,     0,     0,     0,     0, /* scan 68-6F */
+    0,    0,     0,     0,     0,     0,     0,     0, /* scan 70-77 */
+    0,    0,     0,     0,     0,     0,     0,     0, /* scan 78-7F */
+  '\r',          CN,   '/',   '*',   ' ',    ST,   'F',   'A', /* extended */
+    0,  'D',   'C',     0,   'B',     0,    '@',  'P'  /* extended */
+    },
+    { /* Right alt mode - is used in German keyboard */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan  0 - 7 */
+  '{',  '[',   ']',   '}',  '\\',  0xff,  0xff,  0xff, /* scan  8 - F */
+  '@', 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 10 -17 */
+ 0xff, 0xff,  0xff,   '~',  0xff,  0xff,  0xff,  0xff, /* scan 18 -1F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 20 -27 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 28 -2F */
+ 0xff, 0xff,  0xe6,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 30 -37 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 38 -3F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 40 -47 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 48 -4F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,   '|',  0xff, /* scan 50 -57 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 58 -5F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 60 -67 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 68 -6F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 70 -77 */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 78 -7F */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* extended    */
+ 0xff, 0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff  /* extended    */
+    }
+    }
+    };
+
+static unsigned char ext_key_map [] =
+    {
+    0x1c,   /* keypad enter */
+    0x1d,   /* right control */
+    0x35,   /* keypad slash */
+    0x37,   /* print screen */
+    0x38,   /* right alt */
+    0x46,   /* break */
+    0x47,   /* editpad home */
+    0x48,   /* editpad up */
+    0x49,   /* editpad pgup */
+    0x4b,   /* editpad left */
+    0x4d,   /* editpad right */
+    0x4f,   /* editpad end */
+    0x50,   /* editpad dn */
+    0x51,   /* editpad pgdn */
+    0x52,   /* editpad ins */
+    0x53,   /* editpad del */
+    0x00    /* map end */
+    };
+
+/*******************************************************************************
+ *
+ * i8042_kbd_init - reset keyboard and init state flags
+ */
+int i8042_kbd_init (void)
+{
+    int keymap, try;
+    char *penv;
+
+#ifdef CONFIG_USE_CPCIDVI
+    if ((penv = getenv ("console")) != NULL) {
+           if (strncmp (penv, "serial", 7) == 0) {
+                   return -1;
+           }
+    }
+#endif
+    /* Init keyboard device (default US layout) */
+    keymap = KBD_US;
+    if ((penv = getenv ("keymap")) != NULL)
+    {
+       if (strncmp (penv, "de", 3) == 0)
+       keymap = KBD_GER;
+    }
+
+    for (try = 0; try < KBD_RESET_TRIES; try++)
+    {
+       if (kbd_reset() == 0)
+       {
+           kbd_mapping   = keymap;
+           kbd_flags     = NORMAL;
+           kbd_state     = 0;
+           kbd_led_set();
+           return 0;
+           }
+    }
+    return -1;
+}
+
+
+/*******************************************************************************
+ *
+ * i8042_tstc - test if keyboard input is available
+ *             option: cursor blinking if called in a loop
+ */
+int i8042_tstc (void)
+{
+    unsigned char scan_code = 0;
+
+#ifdef CONFIG_CONSOLE_CURSOR
+    if (--blinkCount == 0)
+    {
+       cursor_state ^= 1;
+       console_cursor (cursor_state);
+       blinkCount = CFG_CONSOLE_BLINK_COUNT;
+       udelay (10);
+    }
+#endif
+
+    if ((in8 (I8042_STATUS_REG) & 0x01) == 0)
+       return 0;
+    else
+    {
+       scan_code = in8 (I8042_DATA_REG);
+       if (scan_code == 0xfa)
+           return 0;
+
+       kbd_conv_char(scan_code);
+
+       if (kbd_input != -1)
+           return 1;
+    }
+    return 0;
+}
+
+
+/*******************************************************************************
+ *
+ * i8042_getc - wait till keyboard input is available
+ *             option: turn on/off cursor while waiting
+ */
+int i8042_getc (void)
+{
+    int ret_chr;
+    unsigned char scan_code;
+
+    while (kbd_input == -1)
+    {
+       while ((in8 (I8042_STATUS_REG) & 0x01) == 0)
+       {
+#ifdef CONFIG_CONSOLE_CURSOR
+           if (--blinkCount==0)
+           {
+               cursor_state ^= 1;
+               console_cursor (cursor_state);
+               blinkCount = CFG_CONSOLE_BLINK_COUNT;
+           }
+           udelay (10);
+#endif
+       }
+
+       scan_code = in8 (I8042_DATA_REG);
+
+       if (scan_code != 0xfa)
+       kbd_conv_char (scan_code);
+    }
+    ret_chr = kbd_input;
+    kbd_input = -1;
+    return ret_chr;
+}
+
+
+/******************************************************************************/
+
+static void kbd_conv_char (unsigned char scan_code)
+{
+    if (scan_code == 0xe0)
+    {
+       kbd_flags |= EXT;
+       return;
+    }
+
+    /* if high bit of scan_code, set break flag */
+    if (scan_code & 0x80)
+       kbd_flags |=  BRK;
+    else
+       kbd_flags &= ~BRK;
+
+    if ((scan_code == 0xe1) || (kbd_flags & E1))
+    {
+       if (scan_code == 0xe1)
+       {
+           kbd_flags ^= BRK;     /* reset the break flag */
+           kbd_flags ^= E1;      /* bitwise EXOR with E1 flag */
+       }
+       return;
+    }
+
+    scan_code &= 0x7f;
+
+    if (kbd_flags & EXT)
+    {
+       int i;
+
+       kbd_flags ^= EXT;
+       for (i=0; ext_key_map[i]; i++)
+       {
+           if (ext_key_map[i] == scan_code)
+           {
+               scan_code = 0x80 + i;
+               break;
+           }
+       }
+       /* not found ? */
+       if (!ext_key_map[i])
+           return;
+    }
+
+    switch (kbd_fct_map [scan_code])
+    {
+    case AS:  kbd_normal (scan_code);
+       break;
+    case SH:  kbd_shift (scan_code);
+       break;
+    case CN:  kbd_ctrl (scan_code);
+       break;
+    case NM:  kbd_num (scan_code);
+       break;
+    case CP:  kbd_caps (scan_code);
+       break;
+    case ST:  kbd_scroll (scan_code);
+       break;
+    case AK:  kbd_alt (scan_code);
+       break;
+    }
+    return;
+}
+
+
+/******************************************************************************/
+
+static void kbd_normal (unsigned char scan_code)
+{
+    unsigned char chr;
+
+    if ((kbd_flags & BRK) == NORMAL)
+    {
+       chr = kbd_key_map [kbd_mapping][kbd_state][scan_code];
+       if ((chr == 0xff) || (chr == 0x00))
+       {
+           return;
+       }
+
+       /* if caps lock convert upper to lower */
+       if (((kbd_flags & CAPS) == CAPS) && (chr >= 'a' && chr <= 'z'))
+       {
+          chr -= 'a' - 'A';
+       }
+       kbd_input = chr;
+    }
+}
+
+
+/******************************************************************************/
+
+static void kbd_shift (unsigned char scan_code)
+{
+    if ((kbd_flags & BRK) == BRK)
+    {
+       kbd_state = AS;
+       kbd_flags &= (~SHIFT);
+    }
+    else
+    {
+       kbd_state = SH;
+       kbd_flags |= SHIFT;
+    }
+}
+
+
+/******************************************************************************/
+
+static void kbd_ctrl (unsigned char scan_code)
+{
+    if ((kbd_flags & BRK) == BRK)
+    {
+       kbd_state = AS;
+       kbd_flags &= (~CTRL);
+    }
+    else
+    {
+       kbd_state = CN;
+       kbd_flags |= CTRL;
+    }
+}
+
+
+/******************************************************************************/
+
+static void kbd_caps (unsigned char scan_code)
+{
+    if ((kbd_flags & BRK) == NORMAL)
+    {
+       kbd_flags ^= CAPS;
+       kbd_led_set ();           /* update keyboard LED */
+    }
+}
+
+
+/******************************************************************************/
+
+static void kbd_num (unsigned char scan_code)
+{
+    if ((kbd_flags & BRK) == NORMAL)
+    {
+       kbd_flags ^= NUM;
+       kbd_state = (kbd_flags & NUM) ? AS : NM;
+       kbd_led_set ();           /* update keyboard LED */
+    }
+}
+
+
+/******************************************************************************/
+
+static void kbd_scroll (unsigned char scan_code)
+{
+    if ((kbd_flags & BRK) == NORMAL)
+    {
+       kbd_flags ^= STP;
+       kbd_led_set ();            /* update keyboard LED */
+       if (kbd_flags & STP)
+           kbd_input = 0x13;
+       else
+           kbd_input = 0x11;
+    }
+}
+
+/******************************************************************************/
+
+static void kbd_alt (unsigned char scan_code)
+{
+    if ((kbd_flags & BRK) == BRK)
+    {
+       kbd_state = AS;
+       kbd_flags &= (~ALT);
+    }
+    else
+    {
+       kbd_state = AK;
+       kbd_flags &= ALT;
+    }
+}
+
+
+/******************************************************************************/
+
+static void kbd_led_set (void)
+{
+    kbd_input_empty();
+    out8 (I8042_DATA_REG, 0xed);       /* SET LED command */
+    kbd_input_empty();
+    out8 (I8042_DATA_REG, (kbd_flags & 0x7));   /* LED bits only */
+}
+
+
+/******************************************************************************/
+
+static int kbd_input_empty (void)
+{
+    int kbdTimeout = KBD_TIMEOUT;
+
+    /* wait for input buf empty */
+    while ((in8 (I8042_STATUS_REG) & 0x02) && kbdTimeout--)
+       udelay(1000);
+
+    return kbdTimeout;
+}
+
+/******************************************************************************/
+
+static int kbd_reset (void)
+{
+    if (kbd_input_empty() == 0)
+       return -1;
+
+    out8 (I8042_DATA_REG, 0xff);
+
+    udelay(250000);
+
+    if (kbd_input_empty() == 0)
+       return -1;
+
+#ifdef CONFIG_USE_CPCIDVI
+    out8 (I8042_COMMAND_REG, 0x60);
+#else
+    out8 (I8042_DATA_REG, 0x60);
+#endif
+
+    if (kbd_input_empty() == 0)
+       return -1;
+
+    out8 (I8042_DATA_REG, 0x45);
+
+
+    if (kbd_input_empty() == 0)
+       return -1;
+
+    out8 (I8042_COMMAND_REG, 0xae);
+
+    if (kbd_input_empty() == 0)
+       return -1;
+
+    return 0;
+}
+
+#endif /* CONFIG_I8042_KBD */
diff --git a/drivers/input/keyboard.c b/drivers/input/keyboard.c
new file mode 100644 (file)
index 0000000..9975202
--- /dev/null
@@ -0,0 +1,305 @@
+/***********************************************************************
+ *
+ * (C) Copyright 2004
+ * DENX Software Engineering
+ * Wolfgang Denk, wd@denx.de
+ * All rights reserved.
+ *
+ * Keyboard driver
+ *
+ ***********************************************************************/
+
+#include <common.h>
+
+#ifdef CONFIG_PS2KBD
+
+#include <devices.h>
+#include <keyboard.h>
+
+#undef KBG_DEBUG
+
+#ifdef KBG_DEBUG
+#define        PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+
+#define        DEVNAME                 "kbd"
+
+#define        LED_SCR                 0x01    /* scroll lock led */
+#define        LED_CAP                 0x04    /* caps lock led */
+#define        LED_NUM                 0x02    /* num lock led */
+
+#define        KBD_BUFFER_LEN          0x20  /* size of the keyboardbuffer */
+
+#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+int ps2ser_check(void);
+#endif
+
+static volatile char kbd_buffer[KBD_BUFFER_LEN];
+static volatile int in_pointer = 0;
+static volatile int out_pointer = 0;
+
+static unsigned char leds = 0;
+static unsigned char num_lock = 0;
+static unsigned char caps_lock = 0;
+static unsigned char scroll_lock = 0;
+static unsigned char shift = 0;
+static unsigned char ctrl = 0;
+static unsigned char alt = 0;
+static unsigned char e0 = 0;
+
+/******************************************************************
+ * Queue handling
+ ******************************************************************/
+
+/* puts character in the queue and sets up the in and out pointer */
+static void kbd_put_queue(char data)
+{
+       if((in_pointer+1)==KBD_BUFFER_LEN) {
+               if(out_pointer==0) {
+                       return; /* buffer full */
+               } else{
+                       in_pointer=0;
+               }
+       } else {
+               if((in_pointer+1)==out_pointer)
+                       return; /* buffer full */
+               in_pointer++;
+       }
+       kbd_buffer[in_pointer]=data;
+       return;
+}
+
+/* test if a character is in the queue */
+static int kbd_testc(void)
+{
+#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+       /* no ISR is used, so received chars must be polled */
+       ps2ser_check();
+#endif
+       if(in_pointer==out_pointer)
+               return(0); /* no data */
+       else
+               return(1);
+}
+
+/* gets the character from the queue */
+static int kbd_getc(void)
+{
+       char c;
+       while(in_pointer==out_pointer) {
+#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+       /* no ISR is used, so received chars must be polled */
+       ps2ser_check();
+#endif
+       ;}
+       if((out_pointer+1)==KBD_BUFFER_LEN)
+               out_pointer=0;
+       else
+               out_pointer++;
+       c=kbd_buffer[out_pointer];
+       return (int)c;
+
+}
+
+/* Simple translation table for the keys */
+
+static unsigned char kbd_plain_xlate[] = {
+       0xff,0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=','\b','\t',        /* 0x00 - 0x0f */
+        'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']','\r',0xff, 'a', 's',        /* 0x10 - 0x1f */
+        'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', '`',0xff,'\\', 'z', 'x', 'c', 'v',        /* 0x20 - 0x2f */
+        'b', 'n', 'm', ',', '.', '/',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff,        /* 0x30 - 0x3f */
+       0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1',        /* 0x40 - 0x4f */
+        '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,  /* 0x50 - 0x5F */
+       '\r',0xff,0xff
+       };
+
+static unsigned char kbd_shift_xlate[] = {
+       0xff,0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+','\b','\t',        /* 0x00 - 0x0f */
+        'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}','\r',0xff, 'A', 'S',        /* 0x10 - 0x1f */
+        'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',0xff, '|', 'Z', 'X', 'C', 'V',        /* 0x20 - 0x2f */
+        'B', 'N', 'M', '<', '>', '?',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff,        /* 0x30 - 0x3f */
+       0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1',        /* 0x40 - 0x4f */
+        '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,  /* 0x50 - 0x5F */
+       '\r',0xff,0xff
+       };
+
+static unsigned char kbd_ctrl_xlate[] = {
+       0xff,0x1b, '1',0x00, '3', '4', '5',0x1E, '7', '8', '9', '0',0x1F, '=','\b','\t',        /* 0x00 - 0x0f */
+       0x11,0x17,0x05,0x12,0x14,0x18,0x15,0x09,0x0f,0x10,0x1b,0x1d,'\n',0xff,0x01,0x13,        /* 0x10 - 0x1f */
+       0x04,0x06,0x08,0x09,0x0a,0x0b,0x0c, ';','\'', '~',0x00,0x1c,0x1a,0x18,0x03,0x16,        /* 0x20 - 0x2f */
+       0x02,0x0e,0x0d, '<', '>', '?',0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,        /* 0x30 - 0x3f */
+       0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1',        /* 0x40 - 0x4f */
+        '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,  /* 0x50 - 0x5F */
+       '\r',0xff,0xff
+       };
+
+
+void handle_scancode(unsigned char scancode)
+{
+       unsigned char keycode;
+
+       /*  Convert scancode to keycode */
+       PRINTF("scancode %x\n",scancode);
+       if(scancode==0xe0) {
+               e0=1; /* special charakters */
+               return;
+       }
+       if(e0==1) {
+               e0=0; /* delete flag */
+               if(!(   ((scancode&0x7F)==0x38)|| /* the right ctrl key */
+                                       ((scancode&0x7F)==0x1D)|| /* the right alt key */
+                                       ((scancode&0x7F)==0x35)||       /* the right '/' key */
+                                       ((scancode&0x7F)==0x1C) ))  /* the right enter key */
+                       /* we swallow unknown e0 codes */
+                       return;
+       }
+       /* special cntrl keys */
+       switch(scancode) {
+       case 0x2A:
+       case 0x36: /* shift pressed */
+               shift=1;
+               return; /* do nothing else */
+       case 0xAA:
+       case 0xB6: /* shift released */
+               shift=0;
+               return; /* do nothing else */
+       case 0x38: /* alt pressed */
+               alt=1;
+               return; /* do nothing else */
+       case 0xB8: /* alt released */
+               alt=0;
+               return; /* do nothing else */
+       case 0x1d: /* ctrl pressed */
+               ctrl=1;
+               return; /* do nothing else */
+       case 0x9d: /* ctrl released */
+               ctrl=0;
+               return; /* do nothing else */
+       case 0x46: /* scrollock pressed */
+               scroll_lock=~scroll_lock;
+               if(scroll_lock==0)
+                       leds&=~LED_SCR; /* switch LED off */
+               else
+                       leds|=LED_SCR; /* switch on LED */
+               pckbd_leds(leds);
+               return; /* do nothing else */
+       case 0x3A: /* capslock pressed */
+               caps_lock=~caps_lock;
+               if(caps_lock==0)
+                       leds&=~LED_CAP; /* switch caps_lock off */
+               else
+                       leds|=LED_CAP; /* switch on LED */
+               pckbd_leds(leds);
+               return;
+       case 0x45: /* numlock pressed */
+               num_lock=~num_lock;
+               if(num_lock==0)
+                       leds&=~LED_NUM; /* switch LED off */
+               else
+                       leds|=LED_NUM;  /* switch on LED */
+               pckbd_leds(leds);
+               return;
+       case 0xC6: /* scroll lock released */
+       case 0xC5: /* num lock released */
+       case 0xBA: /* caps lock released */
+               return; /* just swallow */
+       }
+#if 1
+       if((scancode&0x80)==0x80) /* key released */
+               return;
+#else
+       if((scancode&0x80)==0x00) /* key pressed */
+               return;
+       scancode &= ~0x80;
+#endif
+       /* now, decide which table we need */
+       if(scancode > (sizeof(kbd_plain_xlate)/sizeof(kbd_plain_xlate[0]))) { /* scancode not in list */
+               PRINTF("unkown scancode %X\n",scancode);
+               return; /* swallow it */
+       }
+       /* setup plain code first */
+       keycode=kbd_plain_xlate[scancode];
+       if(caps_lock==1) { /* caps_lock is pressed, overwrite plain code */
+               if(scancode > (sizeof(kbd_shift_xlate)/sizeof(kbd_shift_xlate[0]))) { /* scancode not in list */
+                       PRINTF("unkown caps-locked scancode %X\n",scancode);
+                       return; /* swallow it */
+               }
+               keycode=kbd_shift_xlate[scancode];
+               if(keycode<'A') { /* we only want the alphas capital */
+                       keycode=kbd_plain_xlate[scancode];
+               }
+       }
+       if(shift==1) { /* shift overwrites caps_lock */
+               if(scancode > (sizeof(kbd_shift_xlate)/sizeof(kbd_shift_xlate[0]))) { /* scancode not in list */
+                       PRINTF("unkown shifted scancode %X\n",scancode);
+                       return; /* swallow it */
+               }
+               keycode=kbd_shift_xlate[scancode];
+       }
+       if(ctrl==1) { /* ctrl overwrites caps_lock and shift */
+               if(scancode > (sizeof(kbd_ctrl_xlate)/sizeof(kbd_ctrl_xlate[0]))) { /* scancode not in list */
+                       PRINTF("unkown ctrl scancode %X\n",scancode);
+                       return; /* swallow it */
+               }
+               keycode=kbd_ctrl_xlate[scancode];
+       }
+       /* check if valid keycode */
+       if(keycode==0xff) {
+               PRINTF("unkown scancode %X\n",scancode);
+               return; /* swallow unknown codes */
+       }
+
+       kbd_put_queue(keycode);
+       PRINTF("%x\n",keycode);
+}
+
+/******************************************************************
+ * Init
+ ******************************************************************/
+
+#ifdef CFG_CONSOLE_OVERWRITE_ROUTINE
+extern int overwrite_console (void);
+#define OVERWRITE_CONSOLE overwrite_console ()
+#else
+#define OVERWRITE_CONSOLE 0
+#endif /* CFG_CONSOLE_OVERWRITE_ROUTINE */
+
+int kbd_init (void)
+{
+       int error;
+       device_t kbddev ;
+       char *stdinname  = getenv ("stdin");
+
+       if(kbd_init_hw()==-1)
+               return -1;
+       memset (&kbddev, 0, sizeof(kbddev));
+       strcpy(kbddev.name, DEVNAME);
+       kbddev.flags =  DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+       kbddev.putc = NULL ;
+       kbddev.puts = NULL ;
+       kbddev.getc = kbd_getc ;
+       kbddev.tstc = kbd_testc ;
+
+       error = device_register (&kbddev);
+       if(error==0) {
+               /* check if this is the standard input device */
+               if(strcmp(stdinname,DEVNAME)==0) {
+                       /* reassign the console */
+                       if(OVERWRITE_CONSOLE) {
+                               return 1;
+                       }
+                       error=console_assign(stdin,DEVNAME);
+                       if(error==0)
+                               return 1;
+                       else
+                               return error;
+               }
+               return 1;
+       }
+       return error;
+}
+
+#endif /* CONFIG_PS2KBD */
diff --git a/drivers/input/pc_keyb.c b/drivers/input/pc_keyb.c
new file mode 100644 (file)
index 0000000..81d3e98
--- /dev/null
@@ -0,0 +1,256 @@
+/***********************************************************************
+ *
+ * (C) Copyright 2004
+ * DENX Software Engineering
+ * Wolfgang Denk, wd@denx.de
+ * All rights reserved.
+ *
+ * PS/2 keyboard driver
+ *
+ * Originally from linux source (drivers/char/pc_keyb.c)
+ *
+ ***********************************************************************/
+
+#include <common.h>
+
+#ifdef CONFIG_PS2KBD
+
+#include <keyboard.h>
+#include <pc_keyb.h>
+
+#undef KBG_DEBUG
+
+#ifdef KBG_DEBUG
+#define        PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+
+/*
+ * This reads the keyboard status port, and does the
+ * appropriate action.
+ *
+ */
+static unsigned char handle_kbd_event(void)
+{
+       unsigned char status = kbd_read_status();
+       unsigned int work = 10000;
+
+       while ((--work > 0) && (status & KBD_STAT_OBF)) {
+               unsigned char scancode;
+
+               scancode = kbd_read_input();
+
+               /* Error bytes must be ignored to make the
+                  Synaptics touchpads compaq use work */
+               /* Ignore error bytes */
+               if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR))) {
+                       if (status & KBD_STAT_MOUSE_OBF)
+                               ; /* not supported: handle_mouse_event(scancode); */
+                       else
+                               handle_scancode(scancode);
+               }
+               status = kbd_read_status();
+       }
+       if (!work)
+               PRINTF("pc_keyb: controller jammed (0x%02X).\n", status);
+       return status;
+}
+
+
+static int kbd_read_data(void)
+{
+       int val;
+       unsigned char status;
+
+       val=-1;
+       status = kbd_read_status();
+       if (status & KBD_STAT_OBF) {
+               val = kbd_read_input();
+               if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
+                       val = -2;
+       }
+       return val;
+}
+
+static int kbd_wait_for_input(void)
+{
+       unsigned long timeout;
+       int val;
+
+       timeout = KBD_TIMEOUT;
+       val=kbd_read_data();
+       while(val < 0) {
+               if(timeout--==0)
+                       return -1;
+               udelay(1000);
+               val=kbd_read_data();
+       }
+       return val;
+}
+
+
+static int kb_wait(void)
+{
+       unsigned long timeout = KBC_TIMEOUT * 10;
+
+       do {
+               unsigned char status = handle_kbd_event();
+               if (!(status & KBD_STAT_IBF))
+                       return 0; /* ok */
+               udelay(1000);
+               timeout--;
+       } while (timeout);
+       return 1;
+}
+
+static void kbd_write_command_w(int data)
+{
+       if(kb_wait())
+               PRINTF("timeout in kbd_write_command_w\n");
+       kbd_write_command(data);
+}
+
+static void kbd_write_output_w(int data)
+{
+       if(kb_wait())
+               PRINTF("timeout in kbd_write_output_w\n");
+       kbd_write_output(data);
+}
+
+static void kbd_send_data(unsigned char data)
+{
+       kbd_write_output_w(data);
+       kbd_wait_for_input();
+}
+
+
+static char * kbd_initialize(void)
+{
+       int status;
+
+       /*
+        * Test the keyboard interface.
+        * This seems to be the only way to get it going.
+        * If the test is successful a x55 is placed in the input buffer.
+        */
+       kbd_write_command_w(KBD_CCMD_SELF_TEST);
+       if (kbd_wait_for_input() != 0x55)
+               return "Kbd:   failed self test";
+       /*
+        * Perform a keyboard interface test.  This causes the controller
+        * to test the keyboard clock and data lines.  The results of the
+        * test are placed in the input buffer.
+        */
+       kbd_write_command_w(KBD_CCMD_KBD_TEST);
+       if (kbd_wait_for_input() != 0x00)
+               return "Kbd:   interface failed self test";
+       /*
+        * Enable the keyboard by allowing the keyboard clock to run.
+        */
+       kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
+
+       /*
+        * Reset keyboard. If the read times out
+        * then the assumption is that no keyboard is
+        * plugged into the machine.
+        * This defaults the keyboard to scan-code set 2.
+        *
+        * Set up to try again if the keyboard asks for RESEND.
+        */
+       do {
+               kbd_write_output_w(KBD_CMD_RESET);
+               status = kbd_wait_for_input();
+               if (status == KBD_REPLY_ACK)
+                       break;
+               if (status != KBD_REPLY_RESEND) {
+                       PRINTF("status: %X\n",status);
+                       return "Kbd:   reset failed, no ACK";
+               }
+       } while (1);
+       if (kbd_wait_for_input() != KBD_REPLY_POR)
+               return "Kbd:   reset failed, no POR";
+
+       /*
+        * Set keyboard controller mode. During this, the keyboard should be
+        * in the disabled state.
+        *
+        * Set up to try again if the keyboard asks for RESEND.
+        */
+       do {
+               kbd_write_output_w(KBD_CMD_DISABLE);
+               status = kbd_wait_for_input();
+               if (status == KBD_REPLY_ACK)
+                       break;
+               if (status != KBD_REPLY_RESEND)
+                       return "Kbd:   disable keyboard: no ACK";
+       } while (1);
+
+       kbd_write_command_w(KBD_CCMD_WRITE_MODE);
+       kbd_write_output_w(KBD_MODE_KBD_INT
+                             | KBD_MODE_SYS
+                             | KBD_MODE_DISABLE_MOUSE
+                             | KBD_MODE_KCC);
+
+       /* AMCC powerpc portables need this to use scan-code set 1 -- Cort */
+       kbd_write_command_w(KBD_CCMD_READ_MODE);
+       if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
+               /*
+                * If the controller does not support conversion,
+                * Set the keyboard to scan-code set 1.
+                */
+               kbd_write_output_w(0xF0);
+               kbd_wait_for_input();
+               kbd_write_output_w(0x01);
+               kbd_wait_for_input();
+       }
+       kbd_write_output_w(KBD_CMD_ENABLE);
+       if (kbd_wait_for_input() != KBD_REPLY_ACK)
+               return "Kbd:   enable keyboard: no ACK";
+
+       /*
+        * Finally, set the typematic rate to maximum.
+        */
+       kbd_write_output_w(KBD_CMD_SET_RATE);
+       if (kbd_wait_for_input() != KBD_REPLY_ACK)
+               return "Kbd:   Set rate: no ACK";
+       kbd_write_output_w(0x00);
+       if (kbd_wait_for_input() != KBD_REPLY_ACK)
+               return "Kbd:   Set rate: no ACK";
+       return NULL;
+}
+
+static void kbd_interrupt(void *dev_id)
+{
+       handle_kbd_event();
+}
+
+/******************************************************************
+ * Init
+ ******************************************************************/
+
+int kbd_init_hw(void)
+{
+       char* result;
+
+       kbd_request_region();
+
+       result=kbd_initialize();
+       if (result==NULL) {
+               PRINTF("AT Keyboard initialized\n");
+               kbd_request_irq(kbd_interrupt);
+               return (1);
+       } else {
+               printf("%s\n",result);
+               return (-1);
+       }
+}
+
+void pckbd_leds(unsigned char leds)
+{
+       kbd_send_data(KBD_CMD_SET_LEDS);
+       kbd_send_data(leds);
+}
+
+#endif /* CONFIG_PS2KBD */
diff --git a/drivers/input/ps2mult.c b/drivers/input/ps2mult.c
new file mode 100644 (file)
index 0000000..9515a0f
--- /dev/null
@@ -0,0 +1,466 @@
+/***********************************************************************
+ *
+ * (C) Copyright 2004
+ * DENX Software Engineering
+ * Wolfgang Denk, wd@denx.de
+ * All rights reserved.
+ *
+ * PS/2 multiplexer driver
+ *
+ * Originally from linux source (drivers/char/ps2mult.c)
+ *
+ * Uses simple serial driver (ps2ser.c) to access the multiplexer
+ * Used by PS/2 keyboard driver (pc_keyb.c)
+ *
+ ***********************************************************************/
+
+#include <common.h>
+
+#ifdef CONFIG_PS2MULT
+
+#include <pc_keyb.h>
+#include <asm/atomic.h>
+#include <ps2mult.h>
+
+/* #define DEBUG_MULT */
+/* #define DEBUG_KEYB */
+
+#define KBD_STAT_DEFAULT               (KBD_STAT_SELFTEST | KBD_STAT_UNLOCKED)
+
+#define PRINTF(format, args...)                printf("ps2mult.c: " format, ## args)
+
+#ifdef DEBUG_MULT
+#define PRINTF_MULT(format, args...)   printf("PS2MULT: " format, ## args)
+#else
+#define PRINTF_MULT(format, args...)
+#endif
+
+#ifdef DEBUG_KEYB
+#define PRINTF_KEYB(format, args...)   printf("KEYB: " format, ## args)
+#else
+#define PRINTF_KEYB(format, args...)
+#endif
+
+
+static ulong start_time;
+static int init_done = 0;
+
+static int received_escape = 0;
+static int received_bsync = 0;
+static int received_selector = 0;
+
+static int kbd_command_active = 0;
+static int mouse_command_active = 0;
+static int ctl_command_active = 0;
+
+static u_char command_byte = 0;
+
+static void (*keyb_handler)(void *dev_id);
+
+static u_char ps2mult_buf [PS2BUF_SIZE];
+static atomic_t ps2mult_buf_cnt;
+static int ps2mult_buf_in_idx;
+static int ps2mult_buf_out_idx;
+
+static u_char ps2mult_buf_status [PS2BUF_SIZE];
+
+#ifndef CONFIG_BOARD_EARLY_INIT_R
+#error #define CONFIG_BOARD_EARLY_INIT_R and call ps2mult_early_init() in board_early_init_r()
+#endif
+void ps2mult_early_init (void)
+{
+       start_time = get_timer(0);
+}
+
+static void ps2mult_send_byte(u_char byte, u_char sel)
+{
+       ps2ser_putc(sel);
+
+       if (sel == PS2MULT_KB_SELECTOR) {
+               PRINTF_MULT("0x%02x send KEYBOARD\n", byte);
+               kbd_command_active = 1;
+       } else {
+               PRINTF_MULT("0x%02x send MOUSE\n", byte);
+               mouse_command_active = 1;
+       }
+
+       switch (byte) {
+       case PS2MULT_ESCAPE:
+       case PS2MULT_BSYNC:
+       case PS2MULT_KB_SELECTOR:
+       case PS2MULT_MS_SELECTOR:
+       case PS2MULT_SESSION_START:
+       case PS2MULT_SESSION_END:
+               ps2ser_putc(PS2MULT_ESCAPE);
+               break;
+       default:
+               break;
+       }
+
+       ps2ser_putc(byte);
+}
+
+static void ps2mult_receive_byte(u_char byte, u_char sel)
+{
+       u_char status = KBD_STAT_DEFAULT;
+
+#if 1 /* Ignore mouse in U-Boot */
+       if (sel == PS2MULT_MS_SELECTOR) return;
+#endif
+
+       if (sel == PS2MULT_KB_SELECTOR) {
+               if (kbd_command_active) {
+                       if (!received_bsync) {
+                               PRINTF_MULT("0x%02x lost KEYBOARD !!!\n", byte);
+                               return;
+                       } else {
+                               kbd_command_active = 0;
+                               received_bsync = 0;
+                       }
+               }
+               PRINTF_MULT("0x%02x receive KEYBOARD\n", byte);
+               status |= KBD_STAT_IBF | KBD_STAT_OBF;
+       } else {
+               if (mouse_command_active) {
+                       if (!received_bsync) {
+                               PRINTF_MULT("0x%02x lost MOUSE !!!\n", byte);
+                               return;
+                       } else {
+                               mouse_command_active = 0;
+                               received_bsync = 0;
+                       }
+               }
+               PRINTF_MULT("0x%02x receive MOUSE\n", byte);
+               status |= KBD_STAT_IBF | KBD_STAT_OBF | KBD_STAT_MOUSE_OBF;
+       }
+
+       if (atomic_read(&ps2mult_buf_cnt) < PS2BUF_SIZE) {
+               ps2mult_buf_status[ps2mult_buf_in_idx] = status;
+               ps2mult_buf[ps2mult_buf_in_idx++] = byte;
+               ps2mult_buf_in_idx &= (PS2BUF_SIZE - 1);
+               atomic_inc(&ps2mult_buf_cnt);
+       } else {
+               PRINTF("buffer overflow\n");
+       }
+
+       if (received_bsync) {
+               PRINTF("unexpected BSYNC\n");
+               received_bsync = 0;
+       }
+}
+
+void ps2mult_callback (int in_cnt)
+{
+       int i;
+       u_char byte;
+       static int keyb_handler_active = 0;
+
+       if (!init_done) {
+               return;
+       }
+
+       for (i = 0; i < in_cnt; i ++) {
+               byte = ps2ser_getc();
+
+               if (received_escape) {
+                       ps2mult_receive_byte(byte, received_selector);
+                       received_escape = 0;
+               } else switch (byte) {
+               case PS2MULT_ESCAPE:
+                       PRINTF_MULT("ESCAPE receive\n");
+                       received_escape = 1;
+                       break;
+
+               case PS2MULT_BSYNC:
+                       PRINTF_MULT("BSYNC receive\n");
+                       received_bsync = 1;
+                       break;
+
+               case PS2MULT_KB_SELECTOR:
+               case PS2MULT_MS_SELECTOR:
+                       PRINTF_MULT("%s receive\n",
+                           byte == PS2MULT_KB_SELECTOR ? "KB_SEL" : "MS_SEL");
+                       received_selector = byte;
+                       break;
+
+               case PS2MULT_SESSION_START:
+               case PS2MULT_SESSION_END:
+                       PRINTF_MULT("%s receive\n",
+                           byte == PS2MULT_SESSION_START ?
+                           "SESSION_START" : "SESSION_END");
+                       break;
+
+               default:
+                       ps2mult_receive_byte(byte, received_selector);
+               }
+       }
+
+       if (keyb_handler && !keyb_handler_active &&
+           atomic_read(&ps2mult_buf_cnt)) {
+               keyb_handler_active = 1;
+               keyb_handler(NULL);
+               keyb_handler_active = 0;
+       }
+}
+
+u_char ps2mult_read_status(void)
+{
+       u_char byte;
+
+       if (atomic_read(&ps2mult_buf_cnt) == 0) {
+               ps2ser_check();
+       }
+
+       if (atomic_read(&ps2mult_buf_cnt)) {
+               byte = ps2mult_buf_status[ps2mult_buf_out_idx];
+       } else {
+               byte = KBD_STAT_DEFAULT;
+       }
+       PRINTF_KEYB("read_status()=0x%02x\n", byte);
+       return byte;
+}
+
+u_char ps2mult_read_input(void)
+{
+       u_char byte = 0;
+
+       if (atomic_read(&ps2mult_buf_cnt) == 0) {
+               ps2ser_check();
+       }
+
+       if (atomic_read(&ps2mult_buf_cnt)) {
+               byte = ps2mult_buf[ps2mult_buf_out_idx++];
+               ps2mult_buf_out_idx &= (PS2BUF_SIZE - 1);
+               atomic_dec(&ps2mult_buf_cnt);
+       }
+       PRINTF_KEYB("read_input()=0x%02x\n", byte);
+       return byte;
+}
+
+void ps2mult_write_output(u_char val)
+{
+       int i;
+
+       PRINTF_KEYB("write_output(0x%02x)\n", val);
+
+       for (i = 0; i < KBD_TIMEOUT; i++) {
+               if (!kbd_command_active && !mouse_command_active) {
+                       break;
+               }
+               udelay(1000);
+               ps2ser_check();
+       }
+
+       if (kbd_command_active) {
+               PRINTF("keyboard command not acknoledged\n");
+               kbd_command_active = 0;
+       }
+
+       if (mouse_command_active) {
+               PRINTF("mouse command not acknoledged\n");
+               mouse_command_active = 0;
+       }
+
+       if (ctl_command_active) {
+               switch (ctl_command_active) {
+               case KBD_CCMD_WRITE_MODE:
+                         /* Scan code conversion not supported */
+                       command_byte = val & ~KBD_MODE_KCC;
+                       break;
+
+               case KBD_CCMD_WRITE_AUX_OBUF:
+                       ps2mult_receive_byte(val, PS2MULT_MS_SELECTOR);
+                       break;
+
+               case KBD_CCMD_WRITE_MOUSE:
+                       ps2mult_send_byte(val, PS2MULT_MS_SELECTOR);
+                       break;
+
+               default:
+                       PRINTF("invalid controller command\n");
+                       break;
+               }
+
+               ctl_command_active = 0;
+               return;
+       }
+
+       ps2mult_send_byte(val, PS2MULT_KB_SELECTOR);
+}
+
+void ps2mult_write_command(u_char val)
+{
+       ctl_command_active = 0;
+
+       PRINTF_KEYB("write_command(0x%02x)\n", val);
+
+       switch (val) {
+       case KBD_CCMD_READ_MODE:
+               ps2mult_receive_byte(command_byte, PS2MULT_KB_SELECTOR);
+               break;
+
+       case KBD_CCMD_WRITE_MODE:
+               ctl_command_active = val;
+               break;
+
+       case KBD_CCMD_MOUSE_DISABLE:
+               break;
+
+       case KBD_CCMD_MOUSE_ENABLE:
+               break;
+
+       case KBD_CCMD_SELF_TEST:
+               ps2mult_receive_byte(0x55, PS2MULT_KB_SELECTOR);
+               break;
+
+       case KBD_CCMD_KBD_TEST:
+               ps2mult_receive_byte(0x00, PS2MULT_KB_SELECTOR);
+               break;
+
+       case KBD_CCMD_KBD_DISABLE:
+               break;
+
+       case KBD_CCMD_KBD_ENABLE:
+               break;
+
+       case KBD_CCMD_WRITE_AUX_OBUF:
+               ctl_command_active = val;
+               break;
+
+       case KBD_CCMD_WRITE_MOUSE:
+               ctl_command_active = val;
+               break;
+
+       default:
+               PRINTF("invalid controller command\n");
+               break;
+       }
+}
+
+static int ps2mult_getc_w (void)
+{
+       int res = -1;
+       int i;
+
+       for (i = 0; i < KBD_TIMEOUT; i++) {
+               if (ps2ser_check()) {
+                       res = ps2ser_getc();
+                       break;
+               }
+               udelay(1000);
+       }
+
+       switch (res) {
+       case PS2MULT_KB_SELECTOR:
+       case PS2MULT_MS_SELECTOR:
+               received_selector = res;
+               break;
+       default:
+               break;
+       }
+
+       return res;
+}
+
+int ps2mult_init (void)
+{
+       int byte;
+       int kbd_found = 0;
+       int mouse_found = 0;
+
+       while (get_timer(start_time) < CONFIG_PS2MULT_DELAY);
+
+       ps2ser_init();
+
+       ps2ser_putc(PS2MULT_SESSION_START);
+
+       ps2ser_putc(PS2MULT_KB_SELECTOR);
+       ps2ser_putc(KBD_CMD_RESET);
+
+       do {
+               byte = ps2mult_getc_w();
+       } while (byte >= 0 && byte != KBD_REPLY_ACK);
+
+       if (byte == KBD_REPLY_ACK) {
+               byte = ps2mult_getc_w();
+               if (byte == 0xaa) {
+                       kbd_found = 1;
+                       puts("keyboard");
+               }
+       }
+
+       if (!kbd_found) {
+               while (byte >= 0) {
+                       byte = ps2mult_getc_w();
+               }
+       }
+
+#if 1 /* detect mouse */
+       ps2ser_putc(PS2MULT_MS_SELECTOR);
+       ps2ser_putc(AUX_RESET);
+
+       do {
+               byte = ps2mult_getc_w();
+       } while (byte >= 0 && byte != AUX_ACK);
+
+       if (byte == AUX_ACK) {
+               byte = ps2mult_getc_w();
+               if (byte == 0xaa) {
+                       byte = ps2mult_getc_w();
+                       if (byte == 0x00) {
+                               mouse_found = 1;
+                               puts(", mouse");
+                       }
+               }
+       }
+
+       if (!mouse_found) {
+               while (byte >= 0) {
+                       byte = ps2mult_getc_w();
+               }
+       }
+#endif
+
+       if (mouse_found || kbd_found) {
+               if (!received_selector) {
+                       if (mouse_found) {
+                               received_selector = PS2MULT_MS_SELECTOR;
+                       } else {
+                               received_selector = PS2MULT_KB_SELECTOR;
+                       }
+               }
+
+               init_done = 1;
+       } else {
+               puts("No device found");
+       }
+
+       puts("\n");
+
+#if 0 /* for testing */
+       {
+               int i;
+               u_char key[] = {
+                       0x1f, 0x12, 0x14, 0x12, 0x31, 0x2f, 0x39,       /* setenv */
+                       0x1f, 0x14, 0x20, 0x17, 0x31, 0x39,             /* stdin */
+                       0x1f, 0x12, 0x13, 0x17, 0x1e, 0x26, 0x1c,       /* serial */
+               };
+
+               for (i = 0; i < sizeof (key); i++) {
+                       ps2mult_receive_byte (key[i],        PS2MULT_KB_SELECTOR);
+                       ps2mult_receive_byte (key[i] | 0x80, PS2MULT_KB_SELECTOR);
+               }
+       }
+#endif
+
+       return init_done ? 0 : -1;
+}
+
+int ps2mult_request_irq(void (*handler)(void *))
+{
+       keyb_handler = handler;
+
+       return 0;
+}
+
+#endif /* CONFIG_PS2MULT */
diff --git a/drivers/input/ps2ser.c b/drivers/input/ps2ser.c
new file mode 100644 (file)
index 0000000..4e304f7
--- /dev/null
@@ -0,0 +1,319 @@
+/***********************************************************************
+ *
+ * (C) Copyright 2004
+ * DENX Software Engineering
+ * Wolfgang Denk, wd@denx.de
+ * All rights reserved.
+ *
+ * Simple 16550A serial driver
+ *
+ * Originally from linux source (drivers/char/ps2ser.c)
+ *
+ * Used by the PS/2 multiplexer driver (ps2mult.c)
+ *
+ ***********************************************************************/
+
+#include <common.h>
+
+#ifdef CONFIG_PS2SERIAL
+
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include <ps2mult.h>
+#if defined(CFG_NS16550) || defined(CONFIG_MPC85xx)
+#include <ns16550.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* #define     DEBUG */
+
+#define PS2SER_BAUD    57600
+
+#ifdef CONFIG_MPC5xxx
+#if CONFIG_PS2SERIAL == 1
+#define PSC_BASE MPC5XXX_PSC1
+#elif CONFIG_PS2SERIAL == 2
+#define PSC_BASE MPC5XXX_PSC2
+#elif CONFIG_PS2SERIAL == 3
+#define PSC_BASE MPC5XXX_PSC3
+#elif defined(CONFIG_MGT5100)
+#error CONFIG_PS2SERIAL must be in 1, 2 or 3
+#elif CONFIG_PS2SERIAL == 4
+#define PSC_BASE MPC5XXX_PSC4
+#elif CONFIG_PS2SERIAL == 5
+#define PSC_BASE MPC5XXX_PSC5
+#elif CONFIG_PS2SERIAL == 6
+#define PSC_BASE MPC5XXX_PSC6
+#else
+#error CONFIG_PS2SERIAL must be in 1 ... 6
+#endif
+
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+
+#if CONFIG_PS2SERIAL == 1
+#define COM_BASE (CFG_CCSRBAR+0x4500)
+#elif CONFIG_PS2SERIAL == 2
+#define COM_BASE (CFG_CCSRBAR+0x4600)
+#else
+#error CONFIG_PS2SERIAL must be in 1 ... 2
+#endif
+
+#endif /* CONFIG_MPC5xxx / CONFIG_MPC8540 / other */
+
+static int     ps2ser_getc_hw(void);
+static void    ps2ser_interrupt(void *dev_id);
+
+extern struct  serial_state rs_table[]; /* in serial.c */
+#if !defined(CONFIG_MPC5xxx) && !defined(CONFIG_MPC8540) && !defined(CONFIG_MPC8541) && !defined(CONFIG_MPC8555)
+static struct  serial_state *state;
+#endif
+
+static u_char  ps2buf[PS2BUF_SIZE];
+static atomic_t        ps2buf_cnt;
+static int     ps2buf_in_idx;
+static int     ps2buf_out_idx;
+
+#ifdef CONFIG_MPC5xxx
+int ps2ser_init(void)
+{
+       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+       unsigned long baseclk;
+       int div;
+
+       /* reset PSC */
+       psc->command = PSC_SEL_MODE_REG_1;
+
+       /* select clock sources */
+#if defined(CONFIG_MGT5100)
+       psc->psc_clock_select = 0xdd00;
+       baseclk = (CFG_MPC5XXX_CLKIN + 16) / 32;
+#elif defined(CONFIG_MPC5200)
+       psc->psc_clock_select = 0;
+       baseclk = (gd->ipb_clk + 16) / 32;
+#endif
+
+       /* switch to UART mode */
+       psc->sicr = 0;
+
+       /* configure parity, bit length and so on */
+#if defined(CONFIG_MGT5100)
+       psc->mode = PSC_MODE_ERR | PSC_MODE_8_BITS | PSC_MODE_PARNONE;
+#elif defined(CONFIG_MPC5200)
+       psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE;
+#endif
+       psc->mode = PSC_MODE_ONE_STOP;
+
+       /* set up UART divisor */
+       div = (baseclk + (PS2SER_BAUD/2)) / PS2SER_BAUD;
+       psc->ctur = (div >> 8) & 0xff;
+       psc->ctlr = div & 0xff;
+
+       /* disable all interrupts */
+       psc->psc_imr = 0;
+
+       /* reset and enable Rx/Tx */
+       psc->command = PSC_RST_RX;
+       psc->command = PSC_RST_TX;
+       psc->command = PSC_RX_ENABLE | PSC_TX_ENABLE;
+
+       return (0);
+}
+
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+int ps2ser_init(void)
+{
+       NS16550_t com_port = (NS16550_t)COM_BASE;
+
+       com_port->ier = 0x00;
+       com_port->lcr = LCR_BKSE | LCR_8N1;
+       com_port->dll = (CFG_NS16550_CLK / 16 / PS2SER_BAUD) & 0xff;
+       com_port->dlm = ((CFG_NS16550_CLK / 16 / PS2SER_BAUD) >> 8) & 0xff;
+       com_port->lcr = LCR_8N1;
+       com_port->mcr = (MCR_DTR | MCR_RTS);
+       com_port->fcr = (FCR_FIFO_EN | FCR_RXSR | FCR_TXSR);
+
+       return (0);
+}
+
+#else /* !CONFIG_MPC5xxx && !CONFIG_MPC8540 / other */
+
+static inline unsigned int ps2ser_in(int offset)
+{
+       return readb((unsigned long) state->iomem_base + offset);
+}
+
+static inline void ps2ser_out(int offset, int value)
+{
+       writeb(value, (unsigned long) state->iomem_base + offset);
+}
+
+int ps2ser_init(void)
+{
+       int quot;
+       unsigned cval;
+
+       state = rs_table + CONFIG_PS2SERIAL;
+
+       quot = state->baud_base / PS2SER_BAUD;
+       cval = 0x3; /* 8N1 - 8 data bits, no parity bits, 1 stop bit */
+
+         /* Set speed, enable interrupts, enable FIFO
+          */
+       ps2ser_out(UART_LCR, cval | UART_LCR_DLAB);
+       ps2ser_out(UART_DLL, quot & 0xff);
+       ps2ser_out(UART_DLM, quot >> 8);
+       ps2ser_out(UART_LCR, cval);
+       ps2ser_out(UART_IER, UART_IER_RDI);
+       ps2ser_out(UART_MCR, UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS);
+       ps2ser_out(UART_FCR,
+           UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+
+       /* If we read 0xff from the LSR, there is no UART here
+        */
+       if (ps2ser_in(UART_LSR) == 0xff) {
+               printf ("ps2ser.c: no UART found\n");
+               return -1;
+       }
+
+       irq_install_handler(state->irq, ps2ser_interrupt, NULL);
+
+       return 0;
+}
+#endif /* CONFIG_MPC5xxx / CONFIG_MPC8540 / other */
+
+void ps2ser_putc(int chr)
+{
+#ifdef CONFIG_MPC5xxx
+       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+       NS16550_t com_port = (NS16550_t)COM_BASE;
+#endif
+#ifdef DEBUG
+       printf(">>>> 0x%02x\n", chr);
+#endif
+
+#ifdef CONFIG_MPC5xxx
+       while (!(psc->psc_status & PSC_SR_TXRDY));
+
+       psc->psc_buffer_8 = chr;
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+       while ((com_port->lsr & LSR_THRE) == 0);
+       com_port->thr = chr;
+#else
+       while (!(ps2ser_in(UART_LSR) & UART_LSR_THRE));
+
+       ps2ser_out(UART_TX, chr);
+#endif
+}
+
+static int ps2ser_getc_hw(void)
+{
+#ifdef CONFIG_MPC5xxx
+       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+       NS16550_t com_port = (NS16550_t)COM_BASE;
+#endif
+       int res = -1;
+
+#ifdef CONFIG_MPC5xxx
+       if (psc->psc_status & PSC_SR_RXRDY) {
+               res = (psc->psc_buffer_8);
+       }
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+       if (com_port->lsr & LSR_DR) {
+               res = com_port->rbr;
+       }
+#else
+       if (ps2ser_in(UART_LSR) & UART_LSR_DR) {
+               res = (ps2ser_in(UART_RX));
+       }
+#endif
+
+       return res;
+}
+
+int ps2ser_getc(void)
+{
+       volatile int chr;
+       int flags;
+
+#ifdef DEBUG
+       printf("<< ");
+#endif
+
+       flags = disable_interrupts();
+
+       do {
+               if (atomic_read(&ps2buf_cnt) != 0) {
+                       chr = ps2buf[ps2buf_out_idx++];
+                       ps2buf_out_idx &= (PS2BUF_SIZE - 1);
+                       atomic_dec(&ps2buf_cnt);
+               } else {
+                       chr = ps2ser_getc_hw();
+               }
+       }
+       while (chr < 0);
+
+       if (flags) enable_interrupts();
+
+#ifdef DEBUG
+       printf("0x%02x\n", chr);
+#endif
+
+       return chr;
+}
+
+int ps2ser_check(void)
+{
+       int flags;
+
+       flags = disable_interrupts();
+       ps2ser_interrupt(NULL);
+       if (flags) enable_interrupts();
+
+       return atomic_read(&ps2buf_cnt);
+}
+
+static void ps2ser_interrupt(void *dev_id)
+{
+#ifdef CONFIG_MPC5xxx
+       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+       NS16550_t com_port = (NS16550_t)COM_BASE;
+#endif
+       int chr;
+       int status;
+
+       do {
+               chr = ps2ser_getc_hw();
+#ifdef CONFIG_MPC5xxx
+               status = psc->psc_status;
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+               status = com_port->lsr;
+#else
+               status = ps2ser_in(UART_IIR);
+#endif
+               if (chr < 0) continue;
+
+               if (atomic_read(&ps2buf_cnt) < PS2BUF_SIZE) {
+                       ps2buf[ps2buf_in_idx++] = chr;
+                       ps2buf_in_idx &= (PS2BUF_SIZE - 1);
+                       atomic_inc(&ps2buf_cnt);
+               } else {
+                       printf ("ps2ser.c: buffer overflow\n");
+               }
+#ifdef CONFIG_MPC5xxx
+       } while (status & PSC_SR_RXRDY);
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+       } while (status & LSR_DR);
+#else
+       } while (status & UART_IIR_RDI);
+#endif
+
+       if (atomic_read(&ps2buf_cnt)) {
+               ps2mult_callback(atomic_read(&ps2buf_cnt));
+       }
+}
+
+#endif /* CONFIG_PS2SERIAL */
diff --git a/drivers/isp116x-hcd.c b/drivers/isp116x-hcd.c
deleted file mode 100644 (file)
index b21af10..0000000
+++ /dev/null
@@ -1,1445 +0,0 @@
-/*
- * ISP116x HCD (Host Controller Driver) for u-boot.
- *
- * Copyright (C) 2006-2007 Rodolfo Giometti <giometti@linux.it>
- * Copyright (C) 2006-2007 Eurotech S.p.A. <info@eurotech.it>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- *
- * Derived in part from the SL811 HCD driver "u-boot/drivers/sl811_usb.c"
- * (original copyright message follows):
- *
- *    (C) Copyright 2004
- *    Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- *    This code is based on linux driver for sl811hs chip, source at
- *    drivers/usb/host/sl811.c:
- *
- *    SL811 Host Controller Interface driver for USB.
- *
- *    Copyright (c) 2003/06, Courage Co., Ltd.
- *
- *    Based on:
- *         1.uhci.c by Linus Torvalds, Johannes Erdfelt, Randy Dunlap,
- *           Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber,
- *           Adam Richter, Gregory P. Smith;
- *         2.Original SL811 driver (hc_sl811.o) by Pei Liu <pbl@cypress.com>
- *         3.Rewrited as sl811.o by Yin Aihua <yinah:couragetech.com.cn>
- *
- *    [[GNU/GPL disclaimer]]
- *
- * and in part from AU1x00 OHCI HCD driver "u-boot/cpu/mips/au1x00_usb_ohci.c"
- * (original copyright message follows):
- *
- *    URB OHCI HCD (Host Controller Driver) for USB on the AU1x00.
- *
- *    (C) Copyright 2003
- *    Gary Jennejohn, DENX Software Engineering <gj@denx.de>
- *
- *    [[GNU/GPL disclaimer]]
- *
- *    Note: Part of this code has been derived from linux
- */
-
-#include <common.h>
-
-#ifdef CONFIG_USB_ISP116X_HCD
-#include <asm/io.h>
-#include <usb.h>
-#include <malloc.h>
-#include <linux/list.h>
-
-/*
- * ISP116x chips require certain delays between accesses to its
- * registers. The following timing options exist.
- *
- * 1. Configure your memory controller (the best)
- * 2. Use ndelay (easiest, poorest). For that, enable the following macro.
- *
- * Value is in microseconds.
- */
-#ifdef ISP116X_HCD_USE_UDELAY
-#define UDELAY         1
-#endif
-
-/*
- * On some (slowly?) machines an extra delay after data packing into
- * controller's FIFOs is required, * otherwise you may get the following
- * error:
- *
- *   uboot> usb start
- *   (Re)start USB...
- *   USB:   scanning bus for devices... isp116x: isp116x_submit_job: CTL:TIMEOUT
- *   isp116x: isp116x_submit_job: ****** FIFO not ready! ******
- *
- *         USB device not responding, giving up (status=4)
- *         isp116x: isp116x_submit_job: ****** FIFO not empty! ******
- *         isp116x: isp116x_submit_job: ****** FIFO not empty! ******
- *         isp116x: isp116x_submit_job: ****** FIFO not empty! ******
- *         3 USB Device(s) found
- *                scanning bus for storage devices... 0 Storage Device(s) found
- *
- * Value is in milliseconds.
- */
-#ifdef ISP116X_HCD_USE_EXTRA_DELAY
-#define EXTRA_DELAY    2
-#endif
-
-/*
- * Enable the following defines if you wish enable debugging messages.
- */
-#undef DEBUG                   /* enable debugging messages */
-#undef TRACE                   /* enable tracing code */
-#undef VERBOSE                 /* verbose debugging messages */
-
-#include "isp116x.h"
-
-#define DRIVER_VERSION "08 Jan 2007"
-static const char hcd_name[] = "isp116x-hcd";
-
-struct isp116x isp116x_dev;
-struct isp116x_platform_data isp116x_board;
-static int got_rhsc;           /* root hub status change */
-struct usb_device *devgone;    /* device which was disconnected */
-static int rh_devnum;          /* address of Root Hub endpoint */
-
-/* ------------------------------------------------------------------------- */
-
-#define ALIGN(x,a)     (((x)+(a)-1UL)&~((a)-1UL))
-#define min_t(type,x,y)        \
-       ({ type __x = (x); type __y = (y); __x < __y ? __x : __y; })
-
-/* ------------------------------------------------------------------------- */
-
-static int isp116x_reset(struct isp116x *isp116x);
-
-/* --- Debugging functions ------------------------------------------------- */
-
-#define isp116x_show_reg(d, r) {                               \
-       if ((r) < 0x20) {                                       \
-               DBG("%-12s[%02x]: %08x", #r,                    \
-                       r, isp116x_read_reg32(d, r));           \
-       } else {                                                \
-               DBG("%-12s[%02x]:     %04x", #r,                \
-                       r, isp116x_read_reg16(d, r));           \
-       }                                                       \
-}
-
-#define isp116x_show_regs(d) {                                 \
-       isp116x_show_reg(d, HCREVISION);                        \
-       isp116x_show_reg(d, HCCONTROL);                         \
-       isp116x_show_reg(d, HCCMDSTAT);                         \
-       isp116x_show_reg(d, HCINTSTAT);                         \
-       isp116x_show_reg(d, HCINTENB);                          \
-       isp116x_show_reg(d, HCFMINTVL);                         \
-       isp116x_show_reg(d, HCFMREM);                           \
-       isp116x_show_reg(d, HCFMNUM);                           \
-       isp116x_show_reg(d, HCLSTHRESH);                        \
-       isp116x_show_reg(d, HCRHDESCA);                         \
-       isp116x_show_reg(d, HCRHDESCB);                         \
-       isp116x_show_reg(d, HCRHSTATUS);                        \
-       isp116x_show_reg(d, HCRHPORT1);                         \
-       isp116x_show_reg(d, HCRHPORT2);                         \
-       isp116x_show_reg(d, HCHWCFG);                           \
-       isp116x_show_reg(d, HCDMACFG);                          \
-       isp116x_show_reg(d, HCXFERCTR);                         \
-       isp116x_show_reg(d, HCuPINT);                           \
-       isp116x_show_reg(d, HCuPINTENB);                        \
-       isp116x_show_reg(d, HCCHIPID);                          \
-       isp116x_show_reg(d, HCSCRATCH);                         \
-       isp116x_show_reg(d, HCITLBUFLEN);                       \
-       isp116x_show_reg(d, HCATLBUFLEN);                       \
-       isp116x_show_reg(d, HCBUFSTAT);                         \
-       isp116x_show_reg(d, HCRDITL0LEN);                       \
-       isp116x_show_reg(d, HCRDITL1LEN);                       \
-}
-
-#if defined(TRACE)
-
-static int isp116x_get_current_frame_number(struct usb_device *usb_dev)
-{
-       struct isp116x *isp116x = &isp116x_dev;
-
-       return isp116x_read_reg32(isp116x, HCFMNUM);
-}
-
-static void dump_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-                    int len, char *str)
-{
-#if defined(VERBOSE)
-       int i;
-#endif
-
-       DBG("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d stat:%#lx",
-           str,
-           isp116x_get_current_frame_number(dev),
-           usb_pipedevice(pipe),
-           usb_pipeendpoint(pipe),
-           usb_pipeout(pipe) ? 'O' : 'I',
-           usb_pipetype(pipe) < 2 ?
-           (usb_pipeint(pipe) ?
-            "INTR" : "ISOC") :
-           (usb_pipecontrol(pipe) ? "CTRL" : "BULK"), len, dev->status);
-#if defined(VERBOSE)
-       if (len > 0 && buffer) {
-               printf(__FILE__ ": data(%d):", len);
-               for (i = 0; i < 16 && i < len; i++)
-                       printf(" %02x", ((__u8 *) buffer)[i]);
-               printf("%s\n", i < len ? "..." : "");
-       }
-#endif
-}
-
-#define PTD_DIR_STR(ptd)  ({char __c;          \
-       switch(PTD_GET_DIR(ptd)){               \
-       case 0:  __c = 's'; break;              \
-       case 1:  __c = 'o'; break;              \
-       default: __c = 'i'; break;              \
-       }; __c;})
-
-/*
-  Dump PTD info. The code documents the format
-  perfectly, right :)
-*/
-static inline void dump_ptd(struct ptd *ptd)
-{
-#if defined(VERBOSE)
-       int k;
-#endif
-
-       DBG("PTD(ext) : cc:%x %d%c%d %d,%d,%d t:%x %x%x%x",
-           PTD_GET_CC(ptd),
-           PTD_GET_FA(ptd), PTD_DIR_STR(ptd), PTD_GET_EP(ptd),
-           PTD_GET_COUNT(ptd), PTD_GET_LEN(ptd), PTD_GET_MPS(ptd),
-           PTD_GET_TOGGLE(ptd),
-           PTD_GET_ACTIVE(ptd), PTD_GET_SPD(ptd), PTD_GET_LAST(ptd));
-#if defined(VERBOSE)
-       printf("isp116x: %s: PTD(byte): ", __FUNCTION__);
-       for (k = 0; k < sizeof(struct ptd); ++k)
-               printf("%02x ", ((u8 *) ptd)[k]);
-       printf("\n");
-#endif
-}
-
-static inline void dump_ptd_data(struct ptd *ptd, u8 * buf, int type)
-{
-#if defined(VERBOSE)
-       int k;
-
-       if (type == 0 /* 0ut data */ ) {
-               printf("isp116x: %s: out data: ", __FUNCTION__);
-               for (k = 0; k < PTD_GET_LEN(ptd); ++k)
-                       printf("%02x ", ((u8 *) buf)[k]);
-               printf("\n");
-       }
-       if (type == 1 /* 1n data */ ) {
-               printf("isp116x: %s: in data: ", __FUNCTION__);
-               for (k = 0; k < PTD_GET_COUNT(ptd); ++k)
-                       printf("%02x ", ((u8 *) buf)[k]);
-               printf("\n");
-       }
-
-       if (PTD_GET_LAST(ptd))
-               DBG("--- last PTD ---");
-#endif
-}
-
-#else
-
-#define dump_msg(dev, pipe, buffer, len, str)                  do { } while (0)
-#define dump_pkt(dev, pipe, buffer, len, setup, str, small)    do {} while (0)
-
-#define dump_ptd(ptd)                  do {} while (0)
-#define dump_ptd_data(ptd, buf, type)  do {} while (0)
-
-#endif
-
-/* --- Virtual Root Hub ---------------------------------------------------- */
-
-/* Device descriptor */
-static __u8 root_hub_dev_des[] = {
-       0x12,                   /*  __u8  bLength; */
-       0x01,                   /*  __u8  bDescriptorType; Device */
-       0x10,                   /*  __u16 bcdUSB; v1.1 */
-       0x01,
-       0x09,                   /*  __u8  bDeviceClass; HUB_CLASSCODE */
-       0x00,                   /*  __u8  bDeviceSubClass; */
-       0x00,                   /*  __u8  bDeviceProtocol; */
-       0x08,                   /*  __u8  bMaxPacketSize0; 8 Bytes */
-       0x00,                   /*  __u16 idVendor; */
-       0x00,
-       0x00,                   /*  __u16 idProduct; */
-       0x00,
-       0x00,                   /*  __u16 bcdDevice; */
-       0x00,
-       0x00,                   /*  __u8  iManufacturer; */
-       0x01,                   /*  __u8  iProduct; */
-       0x00,                   /*  __u8  iSerialNumber; */
-       0x01                    /*  __u8  bNumConfigurations; */
-};
-
-/* Configuration descriptor */
-static __u8 root_hub_config_des[] = {
-       0x09,                   /*  __u8  bLength; */
-       0x02,                   /*  __u8  bDescriptorType; Configuration */
-       0x19,                   /*  __u16 wTotalLength; */
-       0x00,
-       0x01,                   /*  __u8  bNumInterfaces; */
-       0x01,                   /*  __u8  bConfigurationValue; */
-       0x00,                   /*  __u8  iConfiguration; */
-       0x40,                   /*  __u8  bmAttributes;
-                                  Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
-       0x00,                   /*  __u8  MaxPower; */
-
-       /* interface */
-       0x09,                   /*  __u8  if_bLength; */
-       0x04,                   /*  __u8  if_bDescriptorType; Interface */
-       0x00,                   /*  __u8  if_bInterfaceNumber; */
-       0x00,                   /*  __u8  if_bAlternateSetting; */
-       0x01,                   /*  __u8  if_bNumEndpoints; */
-       0x09,                   /*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
-       0x00,                   /*  __u8  if_bInterfaceSubClass; */
-       0x00,                   /*  __u8  if_bInterfaceProtocol; */
-       0x00,                   /*  __u8  if_iInterface; */
-
-       /* endpoint */
-       0x07,                   /*  __u8  ep_bLength; */
-       0x05,                   /*  __u8  ep_bDescriptorType; Endpoint */
-       0x81,                   /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
-       0x03,                   /*  __u8  ep_bmAttributes; Interrupt */
-       0x00,                   /*  __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
-       0x02,
-       0xff                    /*  __u8  ep_bInterval; 255 ms */
-};
-
-static unsigned char root_hub_str_index0[] = {
-       0x04,                   /*  __u8  bLength; */
-       0x03,                   /*  __u8  bDescriptorType; String-descriptor */
-       0x09,                   /*  __u8  lang ID */
-       0x04,                   /*  __u8  lang ID */
-};
-
-static unsigned char root_hub_str_index1[] = {
-       0x22,                   /*  __u8  bLength; */
-       0x03,                   /*  __u8  bDescriptorType; String-descriptor */
-       'I',                    /*  __u8  Unicode */
-       0,                      /*  __u8  Unicode */
-       'S',                    /*  __u8  Unicode */
-       0,                      /*  __u8  Unicode */
-       'P',                    /*  __u8  Unicode */
-       0,                      /*  __u8  Unicode */
-       '1',                    /*  __u8  Unicode */
-       0,                      /*  __u8  Unicode */
-       '1',                    /*  __u8  Unicode */
-       0,                      /*  __u8  Unicode */
-       '6',                    /*  __u8  Unicode */
-       0,                      /*  __u8  Unicode */
-       'x',                    /*  __u8  Unicode */
-       0,                      /*  __u8  Unicode */
-       ' ',                    /*  __u8  Unicode */
-       0,                      /*  __u8  Unicode */
-       'R',                    /*  __u8  Unicode */
-       0,                      /*  __u8  Unicode */
-       'o',                    /*  __u8  Unicode */
-       0,                      /*  __u8  Unicode */
-       'o',                    /*  __u8  Unicode */
-       0,                      /*  __u8  Unicode */
-       't',                    /*  __u8  Unicode */
-       0,                      /*  __u8  Unicode */
-       ' ',                    /*  __u8  Unicode */
-       0,                      /*  __u8  Unicode */
-       'H',                    /*  __u8  Unicode */
-       0,                      /*  __u8  Unicode */
-       'u',                    /*  __u8  Unicode */
-       0,                      /*  __u8  Unicode */
-       'b',                    /*  __u8  Unicode */
-       0,                      /*  __u8  Unicode */
-};
-
-/*
- * Hub class-specific descriptor is constructed dynamically
- */
-
-/* --- Virtual root hub management functions ------------------------------- */
-
-static int rh_check_port_status(struct isp116x *isp116x)
-{
-       u32 temp, ndp, i;
-       int res;
-
-       res = -1;
-       temp = isp116x_read_reg32(isp116x, HCRHSTATUS);
-       ndp = (temp & RH_A_NDP);
-       for (i = 0; i < ndp; i++) {
-               temp = isp116x_read_reg32(isp116x, HCRHPORT1 + i);
-               /* check for a device disconnect */
-               if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
-                    (RH_PS_PESC | RH_PS_CSC)) && ((temp & RH_PS_CCS) == 0)) {
-                       res = i;
-                       break;
-               }
-       }
-       return res;
-}
-
-/* --- HC management functions --------------------------------------------- */
-
-/* Write len bytes to fifo, pad till 32-bit boundary
- */
-static void write_ptddata_to_fifo(struct isp116x *isp116x, void *buf, int len)
-{
-       u8 *dp = (u8 *) buf;
-       u16 *dp2 = (u16 *) buf;
-       u16 w;
-       int quot = len % 4;
-
-       if ((unsigned long)dp2 & 1) {
-               /* not aligned */
-               for (; len > 1; len -= 2) {
-                       w = *dp++;
-                       w |= *dp++ << 8;
-                       isp116x_raw_write_data16(isp116x, w);
-               }
-               if (len)
-                       isp116x_write_data16(isp116x, (u16) * dp);
-       } else {
-               /* aligned */
-               for (; len > 1; len -= 2)
-                       isp116x_raw_write_data16(isp116x, *dp2++);
-               if (len)
-                       isp116x_write_data16(isp116x, 0xff & *((u8 *) dp2));
-       }
-       if (quot == 1 || quot == 2)
-               isp116x_raw_write_data16(isp116x, 0);
-}
-
-/* Read len bytes from fifo and then read till 32-bit boundary
- */
-static void read_ptddata_from_fifo(struct isp116x *isp116x, void *buf, int len)
-{
-       u8 *dp = (u8 *) buf;
-       u16 *dp2 = (u16 *) buf;
-       u16 w;
-       int quot = len % 4;
-
-       if ((unsigned long)dp2 & 1) {
-               /* not aligned */
-               for (; len > 1; len -= 2) {
-                       w = isp116x_raw_read_data16(isp116x);
-                       *dp++ = w & 0xff;
-                       *dp++ = (w >> 8) & 0xff;
-               }
-               if (len)
-                       *dp = 0xff & isp116x_read_data16(isp116x);
-       } else {
-               /* aligned */
-               for (; len > 1; len -= 2)
-                       *dp2++ = isp116x_raw_read_data16(isp116x);
-               if (len)
-                       *(u8 *) dp2 = 0xff & isp116x_read_data16(isp116x);
-       }
-       if (quot == 1 || quot == 2)
-               isp116x_raw_read_data16(isp116x);
-}
-
-/* Write PTD's and data for scheduled transfers into the fifo ram.
- * Fifo must be empty and ready */
-static void pack_fifo(struct isp116x *isp116x, struct usb_device *dev,
-                     unsigned long pipe, struct ptd *ptd, int n, void *data,
-                     int len)
-{
-       int buflen = n * sizeof(struct ptd) + len;
-       int i, done;
-
-       DBG("--- pack buffer %p - %d bytes (fifo %d) ---", data, len, buflen);
-
-       isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
-       isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
-       isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET);
-
-       done = 0;
-       for (i = 0; i < n; i++) {
-               DBG("i=%d - done=%d - len=%d", i, done, PTD_GET_LEN(&ptd[i]));
-
-               dump_ptd(&ptd[i]);
-               isp116x_write_data16(isp116x, ptd[i].count);
-               isp116x_write_data16(isp116x, ptd[i].mps);
-               isp116x_write_data16(isp116x, ptd[i].len);
-               isp116x_write_data16(isp116x, ptd[i].faddr);
-
-               dump_ptd_data(&ptd[i], (__u8 *) data + done, 0);
-               write_ptddata_to_fifo(isp116x,
-                                     (__u8 *) data + done,
-                                     PTD_GET_LEN(&ptd[i]));
-
-               done += PTD_GET_LEN(&ptd[i]);
-       }
-}
-
-/* Read the processed PTD's and data from fifo ram back to URBs' buffers.
- * Fifo must be full and done */
-static int unpack_fifo(struct isp116x *isp116x, struct usb_device *dev,
-                      unsigned long pipe, struct ptd *ptd, int n, void *data,
-                      int len)
-{
-       int buflen = n * sizeof(struct ptd) + len;
-       int i, done, cc, ret;
-
-       isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
-       isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
-       isp116x_write_addr(isp116x, HCATLPORT);
-
-       ret = TD_CC_NOERROR;
-       done = 0;
-       for (i = 0; i < n; i++) {
-               DBG("i=%d - done=%d - len=%d", i, done, PTD_GET_LEN(&ptd[i]));
-
-               ptd[i].count = isp116x_read_data16(isp116x);
-               ptd[i].mps = isp116x_read_data16(isp116x);
-               ptd[i].len = isp116x_read_data16(isp116x);
-               ptd[i].faddr = isp116x_read_data16(isp116x);
-               dump_ptd(&ptd[i]);
-
-               read_ptddata_from_fifo(isp116x,
-                                      (__u8 *) data + done,
-                                      PTD_GET_LEN(&ptd[i]));
-               dump_ptd_data(&ptd[i], (__u8 *) data + done, 1);
-
-               done += PTD_GET_LEN(&ptd[i]);
-
-               cc = PTD_GET_CC(&ptd[i]);
-
-               /* Data underrun means basically that we had more buffer space than
-                * the function had data. It is perfectly normal but upper levels have
-                * to know how much we actually transferred.
-                */
-               if (cc == TD_NOTACCESSED ||
-                               (cc != TD_CC_NOERROR && (ret == TD_CC_NOERROR || ret == TD_DATAUNDERRUN)))
-                       ret = cc;
-       }
-
-       DBG("--- unpack buffer %p - %d bytes (fifo %d) ---", data, len, buflen);
-
-       return ret;
-}
-
-/* Interrupt handling
- */
-static int isp116x_interrupt(struct isp116x *isp116x)
-{
-       u16 irqstat;
-       u32 intstat;
-       int ret = 0;
-
-       isp116x_write_reg16(isp116x, HCuPINTENB, 0);
-       irqstat = isp116x_read_reg16(isp116x, HCuPINT);
-       isp116x_write_reg16(isp116x, HCuPINT, irqstat);
-       DBG(">>>>>> irqstat %x <<<<<<", irqstat);
-
-       if (irqstat & HCuPINT_ATL) {
-               DBG(">>>>>> HCuPINT_ATL <<<<<<");
-               udelay(500);
-               ret = 1;
-       }
-
-       if (irqstat & HCuPINT_OPR) {
-               intstat = isp116x_read_reg32(isp116x, HCINTSTAT);
-               isp116x_write_reg32(isp116x, HCINTSTAT, intstat);
-               DBG(">>>>>> HCuPINT_OPR %x <<<<<<", intstat);
-
-               if (intstat & HCINT_UE) {
-                       ERR("unrecoverable error, controller disabled");
-
-                       /* FIXME: be optimistic, hope that bug won't repeat
-                        * often. Make some non-interrupt context restart the
-                        * controller. Count and limit the retries though;
-                        * either hardware or software errors can go forever...
-                        */
-                       isp116x_reset(isp116x);
-                       ret = -1;
-                       return -1;
-               }
-
-               if (intstat & HCINT_RHSC) {
-                       got_rhsc = 1;
-                       ret = 1;
-                       /* When root hub or any of its ports is going
-                          to come out of suspend, it may take more
-                          than 10ms for status bits to stabilize. */
-                       wait_ms(20);
-               }
-
-               if (intstat & HCINT_SO) {
-                       ERR("schedule overrun");
-                       ret = -1;
-               }
-
-               irqstat &= ~HCuPINT_OPR;
-       }
-
-       return ret;
-}
-
-/* With one PTD we can transfer almost 1K in one go;
- * HC does the splitting into endpoint digestible transactions
- */
-struct ptd ptd[1];
-
-static inline int max_transfer_len(struct usb_device *dev, unsigned long pipe)
-{
-       unsigned mpck = usb_maxpacket(dev, pipe);
-
-       /* One PTD can transfer 1023 bytes but try to always
-        * transfer multiples of endpoint buffer size
-        */
-       return 1023 / mpck * mpck;
-}
-
-/* Do an USB transfer
- */
-static int isp116x_submit_job(struct usb_device *dev, unsigned long pipe,
-                             int dir, void *buffer, int len)
-{
-       struct isp116x *isp116x = &isp116x_dev;
-       int type = usb_pipetype(pipe);
-       int epnum = usb_pipeendpoint(pipe);
-       int max = usb_maxpacket(dev, pipe);
-       int dir_out = usb_pipeout(pipe);
-       int speed_low = usb_pipeslow(pipe);
-       int i, done = 0, stat, timeout, cc;
-
-       /* 500 frames or 0.5s timeout when function is busy and NAKs transactions for a while */
-       int retries = 500;
-
-       DBG("------------------------------------------------");
-       dump_msg(dev, pipe, buffer, len, "SUBMIT");
-       DBG("------------------------------------------------");
-
-       if (len >= 1024) {
-               ERR("Too big job");
-               dev->status = USB_ST_CRC_ERR;
-               return -1;
-       }
-
-       if (isp116x->disabled) {
-               ERR("EPIPE");
-               dev->status = USB_ST_CRC_ERR;
-               return -1;
-       }
-
-       /* device pulled? Shortcut the action. */
-       if (devgone == dev) {
-               ERR("ENODEV");
-               dev->status = USB_ST_CRC_ERR;
-               return USB_ST_CRC_ERR;
-       }
-
-       if (!max) {
-               ERR("pipesize for pipe %lx is zero", pipe);
-               dev->status = USB_ST_CRC_ERR;
-               return -1;
-       }
-
-       if (type == PIPE_ISOCHRONOUS) {
-               ERR("isochronous transfers not supported");
-               dev->status = USB_ST_CRC_ERR;
-               return -1;
-       }
-
-       /* FIFO not empty? */
-       if (isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_FULL) {
-               ERR("****** FIFO not empty! ******");
-               dev->status = USB_ST_BUF_ERR;
-               return -1;
-       }
-
-      retry:
-       isp116x_write_reg32(isp116x, HCINTSTAT, 0xff);
-
-       /* Prepare the PTD data */
-       ptd->count = PTD_CC_MSK | PTD_ACTIVE_MSK |
-               PTD_TOGGLE(usb_gettoggle(dev, epnum, dir_out));
-       ptd->mps = PTD_MPS(max) | PTD_SPD(speed_low) | PTD_EP(epnum) | PTD_LAST_MSK;
-       ptd->len = PTD_LEN(len) | PTD_DIR(dir);
-       ptd->faddr = PTD_FA(usb_pipedevice(pipe));
-
-retry_same:
-       /* Pack data into FIFO ram */
-       pack_fifo(isp116x, dev, pipe, ptd, 1, buffer, len);
-#ifdef EXTRA_DELAY
-       wait_ms(EXTRA_DELAY);
-#endif
-
-       /* Start the data transfer */
-
-       /* Allow more time for a BULK device to react - some are slow */
-       if (usb_pipetype(pipe) == PIPE_BULK)
-               timeout = 5000;
-       else
-               timeout = 100;
-
-       /* Wait for it to complete */
-       for (;;) {
-               /* Check whether the controller is done */
-               stat = isp116x_interrupt(isp116x);
-
-               if (stat < 0) {
-                       dev->status = USB_ST_CRC_ERR;
-                       break;
-               }
-               if (stat > 0)
-                       break;
-
-               /* Check the timeout */
-               if (--timeout)
-                       udelay(1);
-               else {
-                       ERR("CTL:TIMEOUT ");
-                       stat = USB_ST_CRC_ERR;
-                       break;
-               }
-       }
-
-       /* We got an Root Hub Status Change interrupt */
-       if (got_rhsc) {
-               isp116x_show_regs(isp116x);
-
-               got_rhsc = 0;
-
-               /* Abuse timeout */
-               timeout = rh_check_port_status(isp116x);
-               if (timeout >= 0) {
-                       /*
-                        * FIXME! NOTE! AAAARGH!
-                        * This is potentially dangerous because it assumes
-                        * that only one device is ever plugged in!
-                        */
-                       devgone = dev;
-               }
-       }
-
-       /* Ok, now we can read transfer status */
-
-       /* FIFO not ready? */
-       if (!(isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_DONE)) {
-               ERR("****** FIFO not ready! ******");
-               dev->status = USB_ST_BUF_ERR;
-               return -1;
-       }
-
-       /* Unpack data from FIFO ram */
-       cc = unpack_fifo(isp116x, dev, pipe, ptd, 1, buffer, len);
-
-       i = PTD_GET_COUNT(ptd);
-       done += i;
-       buffer += i;
-       len -= i;
-
-       /* There was some kind of real problem; Prepare the PTD again
-        * and retry from the failed transaction on
-        */
-       if (cc && cc != TD_NOTACCESSED && cc != TD_DATAUNDERRUN) {
-               if (retries >= 100) {
-                       retries -= 100;
-                       /* The chip will have toggled the toggle bit for the failed
-                        * transaction too. We have to toggle it back.
-                        */
-                       usb_settoggle(dev, epnum, dir_out, !PTD_GET_TOGGLE(ptd));
-                       goto retry;
-               }
-       }
-       /* "Normal" errors; TD_NOTACCESSED would mean in effect that the function have NAKed
-        * the transactions from the first on for the whole frame. It may be busy and we retry
-        * with the same PTD. PTD_ACTIVE (and not TD_NOTACCESSED) would mean that some of the
-        * PTD didn't make it because the function was busy or the frame ended before the PTD
-        * finished. We prepare the rest of the data and try again.
-        */
-       else if (cc == TD_NOTACCESSED || PTD_GET_ACTIVE(ptd) || (cc != TD_DATAUNDERRUN && PTD_GET_COUNT(ptd) < PTD_GET_LEN(ptd))) {
-               if (retries) {
-                       --retries;
-                       if (cc == TD_NOTACCESSED && PTD_GET_ACTIVE(ptd) && !PTD_GET_COUNT(ptd)) goto retry_same;
-                       usb_settoggle(dev, epnum, dir_out, PTD_GET_TOGGLE(ptd));
-                       goto retry;
-               }
-       }
-
-       if (cc != TD_CC_NOERROR && cc != TD_DATAUNDERRUN) {
-               DBG("****** completition code error %x ******", cc);
-               switch (cc) {
-               case TD_CC_BITSTUFFING:
-                       dev->status = USB_ST_BIT_ERR;
-                       break;
-               case TD_CC_STALL:
-                       dev->status = USB_ST_STALLED;
-                       break;
-               case TD_BUFFEROVERRUN:
-               case TD_BUFFERUNDERRUN:
-                       dev->status = USB_ST_BUF_ERR;
-                       break;
-               default:
-                       dev->status = USB_ST_CRC_ERR;
-               }
-               return -cc;
-       }
-       else usb_settoggle(dev, epnum, dir_out, PTD_GET_TOGGLE(ptd));
-
-       dump_msg(dev, pipe, buffer, len, "SUBMIT(ret)");
-
-       dev->status = 0;
-       return done;
-}
-
-/* Adapted from au1x00_usb_ohci.c
- */
-static int isp116x_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
-                                void *buffer, int transfer_len,
-                                struct devrequest *cmd)
-{
-       struct isp116x *isp116x = &isp116x_dev;
-       u32 tmp = 0;
-
-       int leni = transfer_len;
-       int len = 0;
-       int stat = 0;
-       u32 datab[4];
-       u8 *data_buf = (u8 *) datab;
-       u16 bmRType_bReq;
-       u16 wValue;
-       u16 wIndex;
-       u16 wLength;
-
-       if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
-               INFO("Root-Hub submit IRQ: NOT implemented");
-               return 0;
-       }
-
-       bmRType_bReq = cmd->requesttype | (cmd->request << 8);
-       wValue = swap_16(cmd->value);
-       wIndex = swap_16(cmd->index);
-       wLength = swap_16(cmd->length);
-
-       DBG("--- HUB ----------------------------------------");
-       DBG("submit rh urb, req=%x val=%#x index=%#x len=%d",
-           bmRType_bReq, wValue, wIndex, wLength);
-       dump_msg(dev, pipe, buffer, transfer_len, "RH");
-       DBG("------------------------------------------------");
-
-       switch (bmRType_bReq) {
-       case RH_GET_STATUS:
-               DBG("RH_GET_STATUS");
-
-               *(__u16 *) data_buf = swap_16(1);
-               len = 2;
-               break;
-
-       case RH_GET_STATUS | RH_INTERFACE:
-               DBG("RH_GET_STATUS | RH_INTERFACE");
-
-               *(__u16 *) data_buf = swap_16(0);
-               len = 2;
-               break;
-
-       case RH_GET_STATUS | RH_ENDPOINT:
-               DBG("RH_GET_STATUS | RH_ENDPOINT");
-
-               *(__u16 *) data_buf = swap_16(0);
-               len = 2;
-               break;
-
-       case RH_GET_STATUS | RH_CLASS:
-               DBG("RH_GET_STATUS | RH_CLASS");
-
-               tmp = isp116x_read_reg32(isp116x, HCRHSTATUS);
-
-               *(__u32 *) data_buf = swap_32(tmp & ~(RH_HS_CRWE | RH_HS_DRWE));
-               len = 4;
-               break;
-
-       case RH_GET_STATUS | RH_OTHER | RH_CLASS:
-               DBG("RH_GET_STATUS | RH_OTHER | RH_CLASS");
-
-               tmp = isp116x_read_reg32(isp116x, HCRHPORT1 + wIndex - 1);
-               *(__u32 *) data_buf = swap_32(tmp);
-               isp116x_show_regs(isp116x);
-               len = 4;
-               break;
-
-       case RH_CLEAR_FEATURE | RH_ENDPOINT:
-               DBG("RH_CLEAR_FEATURE | RH_ENDPOINT");
-
-               switch (wValue) {
-               case RH_ENDPOINT_STALL:
-                       DBG("C_HUB_ENDPOINT_STALL");
-                       len = 0;
-                       break;
-               }
-               break;
-
-       case RH_CLEAR_FEATURE | RH_CLASS:
-               DBG("RH_CLEAR_FEATURE | RH_CLASS");
-
-               switch (wValue) {
-               case RH_C_HUB_LOCAL_POWER:
-                       DBG("C_HUB_LOCAL_POWER");
-                       len = 0;
-                       break;
-
-               case RH_C_HUB_OVER_CURRENT:
-                       DBG("C_HUB_OVER_CURRENT");
-                       isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_OCIC);
-                       len = 0;
-                       break;
-               }
-               break;
-
-       case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
-               DBG("RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS");
-
-               switch (wValue) {
-               case RH_PORT_ENABLE:
-                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
-                                           RH_PS_CCS);
-                       len = 0;
-                       break;
-
-               case RH_PORT_SUSPEND:
-                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
-                                           RH_PS_POCI);
-                       len = 0;
-                       break;
-
-               case RH_PORT_POWER:
-                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
-                                           RH_PS_LSDA);
-                       len = 0;
-                       break;
-
-               case RH_C_PORT_CONNECTION:
-                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
-                                           RH_PS_CSC);
-                       len = 0;
-                       break;
-
-               case RH_C_PORT_ENABLE:
-                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
-                                           RH_PS_PESC);
-                       len = 0;
-                       break;
-
-               case RH_C_PORT_SUSPEND:
-                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
-                                           RH_PS_PSSC);
-                       len = 0;
-                       break;
-
-               case RH_C_PORT_OVER_CURRENT:
-                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
-                                           RH_PS_POCI);
-                       len = 0;
-                       break;
-
-               case RH_C_PORT_RESET:
-                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
-                                           RH_PS_PRSC);
-                       len = 0;
-                       break;
-
-               default:
-                       ERR("invalid wValue");
-                       stat = USB_ST_STALLED;
-               }
-
-               isp116x_show_regs(isp116x);
-
-               break;
-
-       case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
-               DBG("RH_SET_FEATURE | RH_OTHER | RH_CLASS");
-
-               switch (wValue) {
-               case RH_PORT_SUSPEND:
-                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
-                                           RH_PS_PSS);
-                       len = 0;
-                       break;
-
-               case RH_PORT_RESET:
-                       /* Spin until any current reset finishes */
-                       while (1) {
-                               tmp =
-                                   isp116x_read_reg32(isp116x,
-                                                      HCRHPORT1 + wIndex - 1);
-                               if (!(tmp & RH_PS_PRS))
-                                       break;
-                               wait_ms(1);
-                       }
-                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
-                                           RH_PS_PRS);
-                       wait_ms(10);
-
-                       len = 0;
-                       break;
-
-               case RH_PORT_POWER:
-                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
-                                           RH_PS_PPS);
-                       len = 0;
-                       break;
-
-               case RH_PORT_ENABLE:
-                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
-                                           RH_PS_PES);
-                       len = 0;
-                       break;
-
-               default:
-                       ERR("invalid wValue");
-                       stat = USB_ST_STALLED;
-               }
-
-               isp116x_show_regs(isp116x);
-
-               break;
-
-       case RH_SET_ADDRESS:
-               DBG("RH_SET_ADDRESS");
-
-               rh_devnum = wValue;
-               len = 0;
-               break;
-
-       case RH_GET_DESCRIPTOR:
-               DBG("RH_GET_DESCRIPTOR: %x, %d", wValue, wLength);
-
-               switch (wValue) {
-               case (USB_DT_DEVICE << 8):      /* device descriptor */
-                       len = min_t(unsigned int,
-                                   leni, min_t(unsigned int,
-                                               sizeof(root_hub_dev_des),
-                                               wLength));
-                       data_buf = root_hub_dev_des;
-                       break;
-
-               case (USB_DT_CONFIG << 8):      /* configuration descriptor */
-                       len = min_t(unsigned int,
-                                   leni, min_t(unsigned int,
-                                               sizeof(root_hub_config_des),
-                                               wLength));
-                       data_buf = root_hub_config_des;
-                       break;
-
-               case ((USB_DT_STRING << 8) | 0x00):     /* string 0 descriptors */
-                       len = min_t(unsigned int,
-                                   leni, min_t(unsigned int,
-                                               sizeof(root_hub_str_index0),
-                                               wLength));
-                       data_buf = root_hub_str_index0;
-                       break;
-
-               case ((USB_DT_STRING << 8) | 0x01):     /* string 1 descriptors */
-                       len = min_t(unsigned int,
-                                   leni, min_t(unsigned int,
-                                               sizeof(root_hub_str_index1),
-                                               wLength));
-                       data_buf = root_hub_str_index1;
-                       break;
-
-               default:
-                       ERR("invalid wValue");
-                       stat = USB_ST_STALLED;
-               }
-
-               break;
-
-       case RH_GET_DESCRIPTOR | RH_CLASS:
-               DBG("RH_GET_DESCRIPTOR | RH_CLASS");
-
-               tmp = isp116x_read_reg32(isp116x, HCRHDESCA);
-
-               data_buf[0] = 0x09;     /* min length; */
-               data_buf[1] = 0x29;
-               data_buf[2] = tmp & RH_A_NDP;
-               data_buf[3] = 0;
-               if (tmp & RH_A_PSM)     /* per-port power switching? */
-                       data_buf[3] |= 0x01;
-               if (tmp & RH_A_NOCP)    /* no overcurrent reporting? */
-                       data_buf[3] |= 0x10;
-               else if (tmp & RH_A_OCPM)       /* per-port overcurrent rep? */
-                       data_buf[3] |= 0x08;
-
-               /* Corresponds to data_buf[4-7] */
-               datab[1] = 0;
-               data_buf[5] = (tmp & RH_A_POTPGT) >> 24;
-
-               tmp = isp116x_read_reg32(isp116x, HCRHDESCB);
-
-               data_buf[7] = tmp & RH_B_DR;
-               if (data_buf[2] < 7)
-                       data_buf[8] = 0xff;
-               else {
-                       data_buf[0] += 2;
-                       data_buf[8] = (tmp & RH_B_DR) >> 8;
-                       data_buf[10] = data_buf[9] = 0xff;
-               }
-
-               len = min_t(unsigned int, leni,
-                           min_t(unsigned int, data_buf[0], wLength));
-               break;
-
-       case RH_GET_CONFIGURATION:
-               DBG("RH_GET_CONFIGURATION");
-
-               *(__u8 *) data_buf = 0x01;
-               len = 1;
-               break;
-
-       case RH_SET_CONFIGURATION:
-               DBG("RH_SET_CONFIGURATION");
-
-               isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPSC);
-               len = 0;
-               break;
-
-       default:
-               ERR("*** *** *** unsupported root hub command *** *** ***");
-               stat = USB_ST_STALLED;
-       }
-
-       len = min_t(int, len, leni);
-       if (buffer != data_buf)
-               memcpy(buffer, data_buf, len);
-
-       dev->act_len = len;
-       dev->status = stat;
-       DBG("dev act_len %d, status %d", dev->act_len, dev->status);
-
-       dump_msg(dev, pipe, buffer, transfer_len, "RH(ret)");
-
-       return stat;
-}
-
-/* --- Transfer functions -------------------------------------------------- */
-
-int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-                  int len, int interval)
-{
-       DBG("dev=%p pipe=%#lx buf=%p size=%d int=%d",
-           dev, pipe, buffer, len, interval);
-
-       return -1;
-}
-
-int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-                      int len, struct devrequest *setup)
-{
-       int devnum = usb_pipedevice(pipe);
-       int epnum = usb_pipeendpoint(pipe);
-       int max = max_transfer_len(dev, pipe);
-       int dir_in = usb_pipein(pipe);
-       int done, ret;
-
-       /* Control message is for the HUB? */
-       if (devnum == rh_devnum)
-               return isp116x_submit_rh_msg(dev, pipe, buffer, len, setup);
-
-       /* Ok, no HUB message so send the message to the device */
-
-       /* Setup phase */
-       DBG("--- SETUP PHASE --------------------------------");
-       usb_settoggle(dev, epnum, 1, 0);
-       ret = isp116x_submit_job(dev, pipe,
-                                PTD_DIR_SETUP,
-                                setup, sizeof(struct devrequest));
-       if (ret < 0) {
-               DBG("control setup phase error (ret = %d", ret);
-               return -1;
-       }
-
-       /* Data phase */
-       DBG("--- DATA PHASE ---------------------------------");
-       done = 0;
-       usb_settoggle(dev, epnum, !dir_in, 1);
-       while (done < len) {
-               ret = isp116x_submit_job(dev, pipe,
-                                        dir_in ? PTD_DIR_IN : PTD_DIR_OUT,
-                                        (__u8 *) buffer + done,
-                                        max > len - done ? len - done : max);
-               if (ret < 0) {
-                       DBG("control data phase error (ret = %d)", ret);
-                       return -1;
-               }
-               done += ret;
-
-               if (dir_in && ret < max)        /* short packet */
-                       break;
-       }
-
-       /* Status phase */
-       DBG("--- STATUS PHASE -------------------------------");
-       usb_settoggle(dev, epnum, !dir_in, 1);
-       ret = isp116x_submit_job(dev, pipe,
-                                !dir_in ? PTD_DIR_IN : PTD_DIR_OUT, NULL, 0);
-       if (ret < 0) {
-               DBG("control status phase error (ret = %d", ret);
-               return -1;
-       }
-
-       dev->act_len = done;
-
-       dump_msg(dev, pipe, buffer, len, "DEV(ret)");
-
-       return done;
-}
-
-int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-                   int len)
-{
-       int dir_out = usb_pipeout(pipe);
-       int max = max_transfer_len(dev, pipe);
-       int done, ret;
-
-       DBG("--- BULK ---------------------------------------");
-       DBG("dev=%ld pipe=%ld buf=%p size=%d dir_out=%d",
-           usb_pipedevice(pipe), usb_pipeendpoint(pipe), buffer, len, dir_out);
-
-       done = 0;
-       while (done < len) {
-               ret = isp116x_submit_job(dev, pipe,
-                                        !dir_out ? PTD_DIR_IN : PTD_DIR_OUT,
-                                        (__u8 *) buffer + done,
-                                        max > len - done ? len - done : max);
-               if (ret < 0) {
-                       DBG("error on bulk message (ret = %d)", ret);
-                       return -1;
-               }
-
-               done += ret;
-
-               if (!dir_out && ret < max)      /* short packet */
-                       break;
-       }
-
-       dev->act_len = done;
-
-       return 0;
-}
-
-/* --- Basic functions ----------------------------------------------------- */
-
-static int isp116x_sw_reset(struct isp116x *isp116x)
-{
-       int retries = 15;
-       int ret = 0;
-
-       DBG("");
-
-       isp116x->disabled = 1;
-
-       isp116x_write_reg16(isp116x, HCSWRES, HCSWRES_MAGIC);
-       isp116x_write_reg32(isp116x, HCCMDSTAT, HCCMDSTAT_HCR);
-       while (--retries) {
-               /* It usually resets within 1 ms */
-               wait_ms(1);
-               if (!(isp116x_read_reg32(isp116x, HCCMDSTAT) & HCCMDSTAT_HCR))
-                       break;
-       }
-       if (!retries) {
-               ERR("software reset timeout");
-               ret = -1;
-       }
-       return ret;
-}
-
-static int isp116x_reset(struct isp116x *isp116x)
-{
-       unsigned long t;
-       u16 clkrdy = 0;
-       int ret, timeout = 15 /* ms */ ;
-
-       DBG("");
-
-       ret = isp116x_sw_reset(isp116x);
-       if (ret)
-               return ret;
-
-       for (t = 0; t < timeout; t++) {
-               clkrdy = isp116x_read_reg16(isp116x, HCuPINT) & HCuPINT_CLKRDY;
-               if (clkrdy)
-                       break;
-               wait_ms(1);
-       }
-       if (!clkrdy) {
-               ERR("clock not ready after %dms", timeout);
-               /* After sw_reset the clock won't report to be ready, if
-                  H_WAKEUP pin is high. */
-               ERR("please make sure that the H_WAKEUP pin is pulled low!");
-               ret = -1;
-       }
-       return ret;
-}
-
-static void isp116x_stop(struct isp116x *isp116x)
-{
-       u32 val;
-
-       DBG("");
-
-       isp116x_write_reg16(isp116x, HCuPINTENB, 0);
-
-       /* Switch off ports' power, some devices don't come up
-          after next 'start' without this */
-       val = isp116x_read_reg32(isp116x, HCRHDESCA);
-       val &= ~(RH_A_NPS | RH_A_PSM);
-       isp116x_write_reg32(isp116x, HCRHDESCA, val);
-       isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPS);
-
-       isp116x_sw_reset(isp116x);
-}
-
-/*
- *  Configure the chip. The chip must be successfully reset by now.
- */
-static int isp116x_start(struct isp116x *isp116x)
-{
-       struct isp116x_platform_data *board = isp116x->board;
-       u32 val;
-
-       DBG("");
-
-       /* Clear interrupt status and disable all interrupt sources */
-       isp116x_write_reg16(isp116x, HCuPINT, 0xff);
-       isp116x_write_reg16(isp116x, HCuPINTENB, 0);
-
-       isp116x_write_reg16(isp116x, HCITLBUFLEN, ISP116x_ITL_BUFSIZE);
-       isp116x_write_reg16(isp116x, HCATLBUFLEN, ISP116x_ATL_BUFSIZE);
-
-       /* Hardware configuration */
-       val = HCHWCFG_DBWIDTH(1);
-       if (board->sel15Kres)
-               val |= HCHWCFG_15KRSEL;
-       /* Remote wakeup won't work without working clock */
-       if (board->remote_wakeup_enable)
-               val |= HCHWCFG_CLKNOTSTOP;
-       if (board->oc_enable)
-               val |= HCHWCFG_ANALOG_OC;
-       isp116x_write_reg16(isp116x, HCHWCFG, val);
-
-       /* --- Root hub configuration */
-       val = (25 << 24) & RH_A_POTPGT;
-       /* AN10003_1.pdf recommends RH_A_NPS (no power switching) to
-          be always set. Yet, instead, we request individual port
-          power switching. */
-       val |= RH_A_PSM;
-       /* Report overcurrent per port */
-       val |= RH_A_OCPM;
-       isp116x_write_reg32(isp116x, HCRHDESCA, val);
-       isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA);
-
-       val = RH_B_PPCM;
-       isp116x_write_reg32(isp116x, HCRHDESCB, val);
-       isp116x->rhdescb = isp116x_read_reg32(isp116x, HCRHDESCB);
-
-       val = 0;
-       if (board->remote_wakeup_enable)
-               val |= RH_HS_DRWE;
-       isp116x_write_reg32(isp116x, HCRHSTATUS, val);
-       isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS);
-
-       isp116x_write_reg32(isp116x, HCFMINTVL, 0x27782edf);
-
-       /* Go operational */
-       val = HCCONTROL_USB_OPER;
-       if (board->remote_wakeup_enable)
-               val |= HCCONTROL_RWE;
-       isp116x_write_reg32(isp116x, HCCONTROL, val);
-
-       /* Disable ports to avoid race in device enumeration */
-       isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS);
-       isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS);
-
-       isp116x_show_regs(isp116x);
-
-       isp116x->disabled = 0;
-
-       return 0;
-}
-
-/* --- Init functions ------------------------------------------------------ */
-
-int isp116x_check_id(struct isp116x *isp116x)
-{
-       int val;
-
-       val = isp116x_read_reg16(isp116x, HCCHIPID);
-       if ((val & HCCHIPID_MASK) != HCCHIPID_MAGIC) {
-               ERR("invalid chip ID %04x", val);
-               return -1;
-       }
-
-       return 0;
-}
-
-int usb_lowlevel_init(void)
-{
-       struct isp116x *isp116x = &isp116x_dev;
-
-       DBG("");
-
-       got_rhsc = rh_devnum = 0;
-
-       /* Init device registers addr */
-       isp116x->addr_reg = (u16 *) ISP116X_HCD_ADDR;
-       isp116x->data_reg = (u16 *) ISP116X_HCD_DATA;
-
-       /* Setup specific board settings */
-#ifdef ISP116X_HCD_SEL15kRES
-       isp116x_board.sel15Kres = 1;
-#endif
-#ifdef ISP116X_HCD_OC_ENABLE
-       isp116x_board.oc_enable = 1;
-#endif
-#ifdef ISP116X_HCD_REMOTE_WAKEUP_ENABLE
-       isp116x_board.remote_wakeup_enable = 1;
-#endif
-       isp116x->board = &isp116x_board;
-
-       /* Try to get ISP116x silicon chip ID */
-       if (isp116x_check_id(isp116x) < 0)
-               return -1;
-
-       isp116x->disabled = 1;
-       isp116x->sleeping = 0;
-
-       isp116x_reset(isp116x);
-       isp116x_start(isp116x);
-
-       return 0;
-}
-
-int usb_lowlevel_stop(void)
-{
-       struct isp116x *isp116x = &isp116x_dev;
-
-       DBG("");
-
-       if (!isp116x->disabled)
-               isp116x_stop(isp116x);
-
-       return 0;
-}
-
-#endif                         /* CONFIG_USB_ISP116X_HCD */
diff --git a/drivers/isp116x.h b/drivers/isp116x.h
deleted file mode 100644 (file)
index a3ce3b5..0000000
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * ISP116x register declarations and HCD data structures
- *
- * Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
- * Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.it>
- * Copyright (C) 2005 Olav Kongas <ok@artecdesign.ee>
- * Portions:
- * Copyright (C) 2004 Lothar Wassmann
- * Copyright (C) 2004 Psion Teklogix
- * Copyright (C) 2004 David Brownell
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#ifdef DEBUG
-#define DBG(fmt, args...)      \
-               printf("isp116x: %s: " fmt "\n" , __FUNCTION__ , ## args)
-#else
-#define DBG(fmt, args...)      do {} while (0)
-#endif
-
-#ifdef VERBOSE
-#    define VDBG               DBG
-#else
-#    define VDBG(fmt, args...) do {} while (0)
-#endif
-
-#define ERR(fmt, args...)      \
-               printf("isp116x: %s: " fmt "\n" , __FUNCTION__ , ## args)
-#define WARN(fmt, args...)     \
-               printf("isp116x: %s: " fmt "\n" , __FUNCTION__ , ## args)
-#define INFO(fmt, args...)     \
-               printf("isp116x: " fmt "\n" , ## args)
-
-/* ------------------------------------------------------------------------- */
-
-/* us of 1ms frame */
-#define  MAX_LOAD_LIMIT                850
-
-/* Full speed: max # of bytes to transfer for a single urb
-   at a time must be < 1024 && must be multiple of 64.
-   832 allows transfering 4kiB within 5 frames. */
-#define MAX_TRANSFER_SIZE_FULLSPEED    832
-
-/* Low speed: there is no reason to schedule in very big
-   chunks; often the requested long transfers are for
-   string descriptors containing short strings. */
-#define MAX_TRANSFER_SIZE_LOWSPEED     64
-
-/* Bytetime (us), a rough indication of how much time it
-   would take to transfer a byte of useful data over USB */
-#define BYTE_TIME_FULLSPEED    1
-#define BYTE_TIME_LOWSPEED     20
-
-/* Buffer sizes */
-#define ISP116x_BUF_SIZE       4096
-#define ISP116x_ITL_BUFSIZE    0
-#define ISP116x_ATL_BUFSIZE    ((ISP116x_BUF_SIZE) - 2*(ISP116x_ITL_BUFSIZE))
-
-#define ISP116x_WRITE_OFFSET   0x80
-
-/* --- ISP116x registers/bits ---------------------------------------------- */
-
-#define        HCREVISION      0x00
-#define        HCCONTROL       0x01
-#define                HCCONTROL_HCFS  (3 << 6)        /* host controller
-                                                  functional state */
-#define                HCCONTROL_USB_RESET     (0 << 6)
-#define                HCCONTROL_USB_RESUME    (1 << 6)
-#define                HCCONTROL_USB_OPER      (2 << 6)
-#define                HCCONTROL_USB_SUSPEND   (3 << 6)
-#define                HCCONTROL_RWC   (1 << 9)        /* remote wakeup connected */
-#define                HCCONTROL_RWE   (1 << 10)       /* remote wakeup enable */
-#define        HCCMDSTAT       0x02
-#define                HCCMDSTAT_HCR   (1 << 0)        /* host controller reset */
-#define                HCCMDSTAT_SOC   (3 << 16)       /* scheduling overrun count */
-#define        HCINTSTAT       0x03
-#define                HCINT_SO        (1 << 0)        /* scheduling overrun */
-#define                HCINT_WDH       (1 << 1)        /* writeback of done_head */
-#define                HCINT_SF        (1 << 2)        /* start frame */
-#define                HCINT_RD        (1 << 3)        /* resume detect */
-#define                HCINT_UE        (1 << 4)        /* unrecoverable error */
-#define                HCINT_FNO       (1 << 5)        /* frame number overflow */
-#define                HCINT_RHSC      (1 << 6)        /* root hub status change */
-#define                HCINT_OC        (1 << 30)       /* ownership change */
-#define                HCINT_MIE       (1 << 31)       /* master interrupt enable */
-#define        HCINTENB        0x04
-#define        HCINTDIS        0x05
-#define        HCFMINTVL       0x0d
-#define        HCFMREM         0x0e
-#define        HCFMNUM         0x0f
-#define        HCLSTHRESH      0x11
-#define        HCRHDESCA       0x12
-#define                RH_A_NDP        (0x3 << 0)      /* # downstream ports */
-#define                RH_A_PSM        (1 << 8)        /* power switching mode */
-#define                RH_A_NPS        (1 << 9)        /* no power switching */
-#define                RH_A_DT         (1 << 10)       /* device type (mbz) */
-#define                RH_A_OCPM       (1 << 11)       /* overcurrent protection
-                                                  mode */
-#define                RH_A_NOCP       (1 << 12)       /* no overcurrent protection */
-#define                RH_A_POTPGT     (0xff << 24)    /* power on -> power good
-                                                  time */
-#define        HCRHDESCB       0x13
-#define                RH_B_DR         (0xffff << 0)   /* device removable flags */
-#define                RH_B_PPCM       (0xffff << 16)  /* port power control mask */
-#define        HCRHSTATUS      0x14
-#define                RH_HS_LPS       (1 << 0)        /* local power status */
-#define                RH_HS_OCI       (1 << 1)        /* over current indicator */
-#define                RH_HS_DRWE      (1 << 15)       /* device remote wakeup
-                                                  enable */
-#define                RH_HS_LPSC      (1 << 16)       /* local power status change */
-#define                RH_HS_OCIC      (1 << 17)       /* over current indicator
-                                                  change */
-#define                RH_HS_CRWE      (1 << 31)       /* clear remote wakeup
-                                                  enable */
-#define        HCRHPORT1       0x15
-#define                RH_PS_CCS       (1 << 0)        /* current connect status */
-#define                RH_PS_PES       (1 << 1)        /* port enable status */
-#define                RH_PS_PSS       (1 << 2)        /* port suspend status */
-#define                RH_PS_POCI      (1 << 3)        /* port over current
-                                                  indicator */
-#define                RH_PS_PRS       (1 << 4)        /* port reset status */
-#define                RH_PS_PPS       (1 << 8)        /* port power status */
-#define                RH_PS_LSDA      (1 << 9)        /* low speed device attached */
-#define                RH_PS_CSC       (1 << 16)       /* connect status change */
-#define                RH_PS_PESC      (1 << 17)       /* port enable status change */
-#define                RH_PS_PSSC      (1 << 18)       /* port suspend status
-                                                  change */
-#define                RH_PS_OCIC      (1 << 19)       /* over current indicator
-                                                  change */
-#define                RH_PS_PRSC      (1 << 20)       /* port reset status change */
-#define                HCRHPORT_CLRMASK        (0x1f << 16)
-#define        HCRHPORT2       0x16
-#define        HCHWCFG         0x20
-#define                HCHWCFG_15KRSEL         (1 << 12)
-#define                HCHWCFG_CLKNOTSTOP      (1 << 11)
-#define                HCHWCFG_ANALOG_OC       (1 << 10)
-#define                HCHWCFG_DACK_MODE       (1 << 8)
-#define                HCHWCFG_EOT_POL         (1 << 7)
-#define                HCHWCFG_DACK_POL        (1 << 6)
-#define                HCHWCFG_DREQ_POL        (1 << 5)
-#define                HCHWCFG_DBWIDTH_MASK    (0x03 << 3)
-#define                HCHWCFG_DBWIDTH(n)      (((n) << 3) & HCHWCFG_DBWIDTH_MASK)
-#define                HCHWCFG_INT_POL         (1 << 2)
-#define                HCHWCFG_INT_TRIGGER     (1 << 1)
-#define                HCHWCFG_INT_ENABLE      (1 << 0)
-#define        HCDMACFG        0x21
-#define                HCDMACFG_BURST_LEN_MASK (0x03 << 5)
-#define                HCDMACFG_BURST_LEN(n)   (((n) << 5) & HCDMACFG_BURST_LEN_MASK)
-#define                HCDMACFG_BURST_LEN_1    HCDMACFG_BURST_LEN(0)
-#define                HCDMACFG_BURST_LEN_4    HCDMACFG_BURST_LEN(1)
-#define                HCDMACFG_BURST_LEN_8    HCDMACFG_BURST_LEN(2)
-#define                HCDMACFG_DMA_ENABLE     (1 << 4)
-#define                HCDMACFG_BUF_TYPE_MASK  (0x07 << 1)
-#define                HCDMACFG_CTR_SEL        (1 << 2)
-#define                HCDMACFG_ITLATL_SEL     (1 << 1)
-#define                HCDMACFG_DMA_RW_SELECT  (1 << 0)
-#define        HCXFERCTR       0x22
-#define        HCuPINT         0x24
-#define                HCuPINT_SOF             (1 << 0)
-#define                HCuPINT_ATL             (1 << 1)
-#define                HCuPINT_AIIEOT          (1 << 2)
-#define                HCuPINT_OPR             (1 << 4)
-#define                HCuPINT_SUSP            (1 << 5)
-#define                HCuPINT_CLKRDY          (1 << 6)
-#define        HCuPINTENB      0x25
-#define        HCCHIPID        0x27
-#define                HCCHIPID_MASK           0xff00
-#define                HCCHIPID_MAGIC          0x6100
-#define        HCSCRATCH       0x28
-#define        HCSWRES         0x29
-#define                HCSWRES_MAGIC           0x00f6
-#define        HCITLBUFLEN     0x2a
-#define        HCATLBUFLEN     0x2b
-#define        HCBUFSTAT       0x2c
-#define                HCBUFSTAT_ITL0_FULL     (1 << 0)
-#define                HCBUFSTAT_ITL1_FULL     (1 << 1)
-#define                HCBUFSTAT_ATL_FULL      (1 << 2)
-#define                HCBUFSTAT_ITL0_DONE     (1 << 3)
-#define                HCBUFSTAT_ITL1_DONE     (1 << 4)
-#define                HCBUFSTAT_ATL_DONE      (1 << 5)
-#define        HCRDITL0LEN     0x2d
-#define        HCRDITL1LEN     0x2e
-#define        HCITLPORT       0x40
-#define        HCATLPORT       0x41
-
-/* PTD accessor macros. */
-#define PTD_GET_COUNT(p)       (((p)->count & PTD_COUNT_MSK) >> 0)
-#define PTD_COUNT(v)           (((v) << 0) & PTD_COUNT_MSK)
-#define PTD_GET_TOGGLE(p)      (((p)->count & PTD_TOGGLE_MSK) >> 10)
-#define PTD_TOGGLE(v)          (((v) << 10) & PTD_TOGGLE_MSK)
-#define PTD_GET_ACTIVE(p)      (((p)->count & PTD_ACTIVE_MSK) >> 11)
-#define PTD_ACTIVE(v)          (((v) << 11) & PTD_ACTIVE_MSK)
-#define PTD_GET_CC(p)          (((p)->count & PTD_CC_MSK) >> 12)
-#define PTD_CC(v)              (((v) << 12) & PTD_CC_MSK)
-#define PTD_GET_MPS(p)         (((p)->mps & PTD_MPS_MSK) >> 0)
-#define PTD_MPS(v)             (((v) << 0) & PTD_MPS_MSK)
-#define PTD_GET_SPD(p)         (((p)->mps & PTD_SPD_MSK) >> 10)
-#define PTD_SPD(v)             (((v) << 10) & PTD_SPD_MSK)
-#define PTD_GET_LAST(p)                (((p)->mps & PTD_LAST_MSK) >> 11)
-#define PTD_LAST(v)            (((v) << 11) & PTD_LAST_MSK)
-#define PTD_GET_EP(p)          (((p)->mps & PTD_EP_MSK) >> 12)
-#define PTD_EP(v)              (((v) << 12) & PTD_EP_MSK)
-#define PTD_GET_LEN(p)         (((p)->len & PTD_LEN_MSK) >> 0)
-#define PTD_LEN(v)             (((v) << 0) & PTD_LEN_MSK)
-#define PTD_GET_DIR(p)         (((p)->len & PTD_DIR_MSK) >> 10)
-#define PTD_DIR(v)             (((v) << 10) & PTD_DIR_MSK)
-#define PTD_GET_B5_5(p)                (((p)->len & PTD_B5_5_MSK) >> 13)
-#define PTD_B5_5(v)            (((v) << 13) & PTD_B5_5_MSK)
-#define PTD_GET_FA(p)          (((p)->faddr & PTD_FA_MSK) >> 0)
-#define PTD_FA(v)              (((v) << 0) & PTD_FA_MSK)
-#define PTD_GET_FMT(p)         (((p)->faddr & PTD_FMT_MSK) >> 7)
-#define PTD_FMT(v)             (((v) << 7) & PTD_FMT_MSK)
-
-/*  Hardware transfer status codes -- CC from ptd->count */
-#define TD_CC_NOERROR      0x00
-#define TD_CC_CRC          0x01
-#define TD_CC_BITSTUFFING  0x02
-#define TD_CC_DATATOGGLEM  0x03
-#define TD_CC_STALL        0x04
-#define TD_DEVNOTRESP      0x05
-#define TD_PIDCHECKFAIL    0x06
-#define TD_UNEXPECTEDPID   0x07
-#define TD_DATAOVERRUN     0x08
-#define TD_DATAUNDERRUN    0x09
-    /* 0x0A, 0x0B reserved for hardware */
-#define TD_BUFFEROVERRUN   0x0C
-#define TD_BUFFERUNDERRUN  0x0D
-    /* 0x0E, 0x0F reserved for HCD */
-#define TD_NOTACCESSED     0x0F
-
-/* ------------------------------------------------------------------------- */
-
-#define        LOG2_PERIODIC_SIZE      5       /* arbitrary; this matches OHCI */
-#define        PERIODIC_SIZE           (1 << LOG2_PERIODIC_SIZE)
-
-/* Philips transfer descriptor */
-struct ptd {
-       u16 count;
-#define        PTD_COUNT_MSK   (0x3ff << 0)
-#define        PTD_TOGGLE_MSK  (1 << 10)
-#define        PTD_ACTIVE_MSK  (1 << 11)
-#define        PTD_CC_MSK      (0xf << 12)
-       u16 mps;
-#define        PTD_MPS_MSK     (0x3ff << 0)
-#define        PTD_SPD_MSK     (1 << 10)
-#define        PTD_LAST_MSK    (1 << 11)
-#define        PTD_EP_MSK      (0xf << 12)
-       u16 len;
-#define        PTD_LEN_MSK     (0x3ff << 0)
-#define        PTD_DIR_MSK     (3 << 10)
-#define        PTD_DIR_SETUP   (0)
-#define        PTD_DIR_OUT     (1)
-#define        PTD_DIR_IN      (2)
-#define        PTD_B5_5_MSK    (1 << 13)
-       u16 faddr;
-#define        PTD_FA_MSK      (0x7f << 0)
-#define        PTD_FMT_MSK     (1 << 7)
-} __attribute__ ((packed, aligned(2)));
-
-struct isp116x_ep {
-       struct usb_device *udev;
-       struct ptd ptd;
-
-       u8 maxpacket;
-       u8 epnum;
-       u8 nextpid;
-
-       u16 length;             /* of current packet */
-       unsigned char *data;    /* to databuf */
-
-       u16 error_count;
-};
-
-/* URB struct */
-#define N_URB_TD               48
-#define URB_DEL                        1
-typedef struct {
-       struct isp116x_ep *ed;
-       void *transfer_buffer;  /* (in) associated data buffer */
-       int actual_length;      /* (return) actual transfer length */
-       unsigned long pipe;     /* (in) pipe information */
-#if 0
-       int state;
-#endif
-} urb_priv_t;
-
-struct isp116x_platform_data {
-       /* Enable internal resistors on downstream ports */
-       unsigned sel15Kres:1;
-       /* On-chip overcurrent detection */
-       unsigned oc_enable:1;
-       /* Enable wakeup by devices on usb bus (e.g. wakeup
-          by attachment/detachment or by device activity
-          such as moving a mouse). When chosen, this option
-          prevents stopping internal clock, increasing
-          thereby power consumption in suspended state. */
-       unsigned remote_wakeup_enable:1;
-};
-
-struct isp116x {
-       u16 *addr_reg;
-       u16 *data_reg;
-
-       struct isp116x_platform_data *board;
-
-       struct dentry *dentry;
-       unsigned long stat1, stat2, stat4, stat8, stat16;
-
-       /* Status flags */
-       unsigned disabled:1;
-       unsigned sleeping:1;
-
-       /* Root hub registers */
-       u32 rhdesca;
-       u32 rhdescb;
-       u32 rhstatus;
-       u32 rhport[2];
-
-       /* Schedule for the current frame */
-       struct isp116x_ep *atl_active;
-       int atl_buflen;
-       int atl_bufshrt;
-       int atl_last_dir;
-       int atl_finishing;
-};
-
-/* ------------------------------------------------- */
-
-/* Inter-io delay (ns). The chip is picky about access timings; it
- * expects at least:
- * 150ns delay between consecutive accesses to DATA_REG,
- * 300ns delay between access to ADDR_REG and DATA_REG
- * OE, WE MUST NOT be changed during these intervals
- */
-#if defined(UDELAY)
-#define        isp116x_delay(h,d)      udelay(d)
-#else
-#define        isp116x_delay(h,d)      do {} while (0)
-#endif
-
-static inline void isp116x_write_addr(struct isp116x *isp116x, unsigned reg)
-{
-       writew(reg & 0xff, isp116x->addr_reg);
-       isp116x_delay(isp116x, UDELAY);
-}
-
-static inline void isp116x_write_data16(struct isp116x *isp116x, u16 val)
-{
-       writew(val, isp116x->data_reg);
-       isp116x_delay(isp116x, UDELAY);
-}
-
-static inline void isp116x_raw_write_data16(struct isp116x *isp116x, u16 val)
-{
-       __raw_writew(val, isp116x->data_reg);
-       isp116x_delay(isp116x, UDELAY);
-}
-
-static inline u16 isp116x_read_data16(struct isp116x *isp116x)
-{
-       u16 val;
-
-       val = readw(isp116x->data_reg);
-       isp116x_delay(isp116x, UDELAY);
-       return val;
-}
-
-static inline u16 isp116x_raw_read_data16(struct isp116x *isp116x)
-{
-       u16 val;
-
-       val = __raw_readw(isp116x->data_reg);
-       isp116x_delay(isp116x, UDELAY);
-       return val;
-}
-
-static inline void isp116x_write_data32(struct isp116x *isp116x, u32 val)
-{
-       writew(val & 0xffff, isp116x->data_reg);
-       isp116x_delay(isp116x, UDELAY);
-       writew(val >> 16, isp116x->data_reg);
-       isp116x_delay(isp116x, UDELAY);
-}
-
-static inline u32 isp116x_read_data32(struct isp116x *isp116x)
-{
-       u32 val;
-
-       val = (u32) readw(isp116x->data_reg);
-       isp116x_delay(isp116x, UDELAY);
-       val |= ((u32) readw(isp116x->data_reg)) << 16;
-       isp116x_delay(isp116x, UDELAY);
-       return val;
-}
-
-/* Let's keep register access functions out of line. Hint:
-   we wait at least 150 ns at every access.
-*/
-static u16 isp116x_read_reg16(struct isp116x *isp116x, unsigned reg)
-{
-       isp116x_write_addr(isp116x, reg);
-       return isp116x_read_data16(isp116x);
-}
-
-static u32 isp116x_read_reg32(struct isp116x *isp116x, unsigned reg)
-{
-       isp116x_write_addr(isp116x, reg);
-       return isp116x_read_data32(isp116x);
-}
-
-static void isp116x_write_reg16(struct isp116x *isp116x, unsigned reg,
-                               unsigned val)
-{
-       isp116x_write_addr(isp116x, reg | ISP116x_WRITE_OFFSET);
-       isp116x_write_data16(isp116x, (u16) (val & 0xffff));
-}
-
-static void isp116x_write_reg32(struct isp116x *isp116x, unsigned reg,
-                               unsigned val)
-{
-       isp116x_write_addr(isp116x, reg | ISP116x_WRITE_OFFSET);
-       isp116x_write_data32(isp116x, (u32) val);
-}
-
-/* --- USB HUB constants (not OHCI-specific; see hub.h) -------------------- */
-
-/* destination of request */
-#define RH_INTERFACE               0x01
-#define RH_ENDPOINT                0x02
-#define RH_OTHER                   0x03
-
-#define RH_CLASS                   0x20
-#define RH_VENDOR                  0x40
-
-/* Requests: bRequest << 8 | bmRequestType */
-#define RH_GET_STATUS           0x0080
-#define RH_CLEAR_FEATURE        0x0100
-#define RH_SET_FEATURE          0x0300
-#define RH_SET_ADDRESS          0x0500
-#define RH_GET_DESCRIPTOR       0x0680
-#define RH_SET_DESCRIPTOR       0x0700
-#define RH_GET_CONFIGURATION    0x0880
-#define RH_SET_CONFIGURATION    0x0900
-#define RH_GET_STATE            0x0280
-#define RH_GET_INTERFACE        0x0A80
-#define RH_SET_INTERFACE        0x0B00
-#define RH_SYNC_FRAME           0x0C80
-/* Our Vendor Specific Request */
-#define RH_SET_EP               0x2000
-
-/* Hub port features */
-#define RH_PORT_CONNECTION         0x00
-#define RH_PORT_ENABLE             0x01
-#define RH_PORT_SUSPEND            0x02
-#define RH_PORT_OVER_CURRENT       0x03
-#define RH_PORT_RESET              0x04
-#define RH_PORT_POWER              0x08
-#define RH_PORT_LOW_SPEED          0x09
-
-#define RH_C_PORT_CONNECTION       0x10
-#define RH_C_PORT_ENABLE           0x11
-#define RH_C_PORT_SUSPEND          0x12
-#define RH_C_PORT_OVER_CURRENT     0x13
-#define RH_C_PORT_RESET            0x14
-
-/* Hub features */
-#define RH_C_HUB_LOCAL_POWER       0x00
-#define RH_C_HUB_OVER_CURRENT      0x01
-
-#define RH_DEVICE_REMOTE_WAKEUP    0x00
-#define RH_ENDPOINT_STALL          0x01
-
-#define RH_ACK                     0x01
-#define RH_REQ_ERR                 -1
-#define RH_NACK                    0x00
diff --git a/drivers/keyboard.c b/drivers/keyboard.c
deleted file mode 100644 (file)
index 9975202..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-/***********************************************************************
- *
- * (C) Copyright 2004
- * DENX Software Engineering
- * Wolfgang Denk, wd@denx.de
- * All rights reserved.
- *
- * Keyboard driver
- *
- ***********************************************************************/
-
-#include <common.h>
-
-#ifdef CONFIG_PS2KBD
-
-#include <devices.h>
-#include <keyboard.h>
-
-#undef KBG_DEBUG
-
-#ifdef KBG_DEBUG
-#define        PRINTF(fmt,args...)     printf (fmt ,##args)
-#else
-#define PRINTF(fmt,args...)
-#endif
-
-
-#define        DEVNAME                 "kbd"
-
-#define        LED_SCR                 0x01    /* scroll lock led */
-#define        LED_CAP                 0x04    /* caps lock led */
-#define        LED_NUM                 0x02    /* num lock led */
-
-#define        KBD_BUFFER_LEN          0x20  /* size of the keyboardbuffer */
-
-#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
-int ps2ser_check(void);
-#endif
-
-static volatile char kbd_buffer[KBD_BUFFER_LEN];
-static volatile int in_pointer = 0;
-static volatile int out_pointer = 0;
-
-static unsigned char leds = 0;
-static unsigned char num_lock = 0;
-static unsigned char caps_lock = 0;
-static unsigned char scroll_lock = 0;
-static unsigned char shift = 0;
-static unsigned char ctrl = 0;
-static unsigned char alt = 0;
-static unsigned char e0 = 0;
-
-/******************************************************************
- * Queue handling
- ******************************************************************/
-
-/* puts character in the queue and sets up the in and out pointer */
-static void kbd_put_queue(char data)
-{
-       if((in_pointer+1)==KBD_BUFFER_LEN) {
-               if(out_pointer==0) {
-                       return; /* buffer full */
-               } else{
-                       in_pointer=0;
-               }
-       } else {
-               if((in_pointer+1)==out_pointer)
-                       return; /* buffer full */
-               in_pointer++;
-       }
-       kbd_buffer[in_pointer]=data;
-       return;
-}
-
-/* test if a character is in the queue */
-static int kbd_testc(void)
-{
-#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
-       /* no ISR is used, so received chars must be polled */
-       ps2ser_check();
-#endif
-       if(in_pointer==out_pointer)
-               return(0); /* no data */
-       else
-               return(1);
-}
-
-/* gets the character from the queue */
-static int kbd_getc(void)
-{
-       char c;
-       while(in_pointer==out_pointer) {
-#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
-       /* no ISR is used, so received chars must be polled */
-       ps2ser_check();
-#endif
-       ;}
-       if((out_pointer+1)==KBD_BUFFER_LEN)
-               out_pointer=0;
-       else
-               out_pointer++;
-       c=kbd_buffer[out_pointer];
-       return (int)c;
-
-}
-
-/* Simple translation table for the keys */
-
-static unsigned char kbd_plain_xlate[] = {
-       0xff,0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=','\b','\t',        /* 0x00 - 0x0f */
-        'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']','\r',0xff, 'a', 's',        /* 0x10 - 0x1f */
-        'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', '`',0xff,'\\', 'z', 'x', 'c', 'v',        /* 0x20 - 0x2f */
-        'b', 'n', 'm', ',', '.', '/',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff,        /* 0x30 - 0x3f */
-       0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1',        /* 0x40 - 0x4f */
-        '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,  /* 0x50 - 0x5F */
-       '\r',0xff,0xff
-       };
-
-static unsigned char kbd_shift_xlate[] = {
-       0xff,0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+','\b','\t',        /* 0x00 - 0x0f */
-        'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}','\r',0xff, 'A', 'S',        /* 0x10 - 0x1f */
-        'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',0xff, '|', 'Z', 'X', 'C', 'V',        /* 0x20 - 0x2f */
-        'B', 'N', 'M', '<', '>', '?',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff,        /* 0x30 - 0x3f */
-       0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1',        /* 0x40 - 0x4f */
-        '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,  /* 0x50 - 0x5F */
-       '\r',0xff,0xff
-       };
-
-static unsigned char kbd_ctrl_xlate[] = {
-       0xff,0x1b, '1',0x00, '3', '4', '5',0x1E, '7', '8', '9', '0',0x1F, '=','\b','\t',        /* 0x00 - 0x0f */
-       0x11,0x17,0x05,0x12,0x14,0x18,0x15,0x09,0x0f,0x10,0x1b,0x1d,'\n',0xff,0x01,0x13,        /* 0x10 - 0x1f */
-       0x04,0x06,0x08,0x09,0x0a,0x0b,0x0c, ';','\'', '~',0x00,0x1c,0x1a,0x18,0x03,0x16,        /* 0x20 - 0x2f */
-       0x02,0x0e,0x0d, '<', '>', '?',0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,        /* 0x30 - 0x3f */
-       0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1',        /* 0x40 - 0x4f */
-        '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,  /* 0x50 - 0x5F */
-       '\r',0xff,0xff
-       };
-
-
-void handle_scancode(unsigned char scancode)
-{
-       unsigned char keycode;
-
-       /*  Convert scancode to keycode */
-       PRINTF("scancode %x\n",scancode);
-       if(scancode==0xe0) {
-               e0=1; /* special charakters */
-               return;
-       }
-       if(e0==1) {
-               e0=0; /* delete flag */
-               if(!(   ((scancode&0x7F)==0x38)|| /* the right ctrl key */
-                                       ((scancode&0x7F)==0x1D)|| /* the right alt key */
-                                       ((scancode&0x7F)==0x35)||       /* the right '/' key */
-                                       ((scancode&0x7F)==0x1C) ))  /* the right enter key */
-                       /* we swallow unknown e0 codes */
-                       return;
-       }
-       /* special cntrl keys */
-       switch(scancode) {
-       case 0x2A:
-       case 0x36: /* shift pressed */
-               shift=1;
-               return; /* do nothing else */
-       case 0xAA:
-       case 0xB6: /* shift released */
-               shift=0;
-               return; /* do nothing else */
-       case 0x38: /* alt pressed */
-               alt=1;
-               return; /* do nothing else */
-       case 0xB8: /* alt released */
-               alt=0;
-               return; /* do nothing else */
-       case 0x1d: /* ctrl pressed */
-               ctrl=1;
-               return; /* do nothing else */
-       case 0x9d: /* ctrl released */
-               ctrl=0;
-               return; /* do nothing else */
-       case 0x46: /* scrollock pressed */
-               scroll_lock=~scroll_lock;
-               if(scroll_lock==0)
-                       leds&=~LED_SCR; /* switch LED off */
-               else
-                       leds|=LED_SCR; /* switch on LED */
-               pckbd_leds(leds);
-               return; /* do nothing else */
-       case 0x3A: /* capslock pressed */
-               caps_lock=~caps_lock;
-               if(caps_lock==0)
-                       leds&=~LED_CAP; /* switch caps_lock off */
-               else
-                       leds|=LED_CAP; /* switch on LED */
-               pckbd_leds(leds);
-               return;
-       case 0x45: /* numlock pressed */
-               num_lock=~num_lock;
-               if(num_lock==0)
-                       leds&=~LED_NUM; /* switch LED off */
-               else
-                       leds|=LED_NUM;  /* switch on LED */
-               pckbd_leds(leds);
-               return;
-       case 0xC6: /* scroll lock released */
-       case 0xC5: /* num lock released */
-       case 0xBA: /* caps lock released */
-               return; /* just swallow */
-       }
-#if 1
-       if((scancode&0x80)==0x80) /* key released */
-               return;
-#else
-       if((scancode&0x80)==0x00) /* key pressed */
-               return;
-       scancode &= ~0x80;
-#endif
-       /* now, decide which table we need */
-       if(scancode > (sizeof(kbd_plain_xlate)/sizeof(kbd_plain_xlate[0]))) { /* scancode not in list */
-               PRINTF("unkown scancode %X\n",scancode);
-               return; /* swallow it */
-       }
-       /* setup plain code first */
-       keycode=kbd_plain_xlate[scancode];
-       if(caps_lock==1) { /* caps_lock is pressed, overwrite plain code */
-               if(scancode > (sizeof(kbd_shift_xlate)/sizeof(kbd_shift_xlate[0]))) { /* scancode not in list */
-                       PRINTF("unkown caps-locked scancode %X\n",scancode);
-                       return; /* swallow it */
-               }
-               keycode=kbd_shift_xlate[scancode];
-               if(keycode<'A') { /* we only want the alphas capital */
-                       keycode=kbd_plain_xlate[scancode];
-               }
-       }
-       if(shift==1) { /* shift overwrites caps_lock */
-               if(scancode > (sizeof(kbd_shift_xlate)/sizeof(kbd_shift_xlate[0]))) { /* scancode not in list */
-                       PRINTF("unkown shifted scancode %X\n",scancode);
-                       return; /* swallow it */
-               }
-               keycode=kbd_shift_xlate[scancode];
-       }
-       if(ctrl==1) { /* ctrl overwrites caps_lock and shift */
-               if(scancode > (sizeof(kbd_ctrl_xlate)/sizeof(kbd_ctrl_xlate[0]))) { /* scancode not in list */
-                       PRINTF("unkown ctrl scancode %X\n",scancode);
-                       return; /* swallow it */
-               }
-               keycode=kbd_ctrl_xlate[scancode];
-       }
-       /* check if valid keycode */
-       if(keycode==0xff) {
-               PRINTF("unkown scancode %X\n",scancode);
-               return; /* swallow unknown codes */
-       }
-
-       kbd_put_queue(keycode);
-       PRINTF("%x\n",keycode);
-}
-
-/******************************************************************
- * Init
- ******************************************************************/
-
-#ifdef CFG_CONSOLE_OVERWRITE_ROUTINE
-extern int overwrite_console (void);
-#define OVERWRITE_CONSOLE overwrite_console ()
-#else
-#define OVERWRITE_CONSOLE 0
-#endif /* CFG_CONSOLE_OVERWRITE_ROUTINE */
-
-int kbd_init (void)
-{
-       int error;
-       device_t kbddev ;
-       char *stdinname  = getenv ("stdin");
-
-       if(kbd_init_hw()==-1)
-               return -1;
-       memset (&kbddev, 0, sizeof(kbddev));
-       strcpy(kbddev.name, DEVNAME);
-       kbddev.flags =  DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
-       kbddev.putc = NULL ;
-       kbddev.puts = NULL ;
-       kbddev.getc = kbd_getc ;
-       kbddev.tstc = kbd_testc ;
-
-       error = device_register (&kbddev);
-       if(error==0) {
-               /* check if this is the standard input device */
-               if(strcmp(stdinname,DEVNAME)==0) {
-                       /* reassign the console */
-                       if(OVERWRITE_CONSOLE) {
-                               return 1;
-                       }
-                       error=console_assign(stdin,DEVNAME);
-                       if(error==0)
-                               return 1;
-                       else
-                               return error;
-               }
-               return 1;
-       }
-       return error;
-}
-
-#endif /* CONFIG_PS2KBD */
diff --git a/drivers/ks8695eth.c b/drivers/ks8695eth.c
deleted file mode 100644 (file)
index b598dd7..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * ks8695eth.c -- KS8695 ethernet driver
- *
- * (C) Copyright 2004-2005, Greg Ungerer <greg.ungerer@opengear.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/****************************************************************************/
-
-#include <common.h>
-
-#ifdef CONFIG_DRIVER_KS8695ETH
-#include <malloc.h>
-#include <net.h>
-#include <asm/io.h>
-#include <asm/arch/platform.h>
-
-/****************************************************************************/
-
-/*
- * Hardware register access to the KS8695 LAN ethernet port
- * (well, it is the 4 port switch really).
- */
-#define        ks8695_read(a)    *((volatile unsigned long *) (KS8695_IO_BASE + (a)))
-#define        ks8695_write(a,v) *((volatile unsigned long *) (KS8695_IO_BASE + (a))) = (v)
-
-/****************************************************************************/
-
-/*
- * Define the descriptor in-memory data structures.
- */
-struct ks8695_txdesc {
-       uint32_t        owner;
-       uint32_t        ctrl;
-       uint32_t        addr;
-       uint32_t        next;
-};
-
-struct ks8695_rxdesc {
-       uint32_t        status;
-       uint32_t        ctrl;
-       uint32_t        addr;
-       uint32_t        next;
-};
-
-/****************************************************************************/
-
-/*
- * Allocate local data structures to use for receiving and sending
- * packets. Just to keep it all nice and simple.
- */
-
-#define        TXDESCS         4
-#define        RXDESCS         4
-#define        BUFSIZE         2048
-
-volatile struct ks8695_txdesc ks8695_tx[TXDESCS] __attribute__((aligned(256)));
-volatile struct ks8695_rxdesc ks8695_rx[RXDESCS] __attribute__((aligned(256)));
-volatile uint8_t ks8695_bufs[BUFSIZE*(TXDESCS+RXDESCS)] __attribute__((aligned(2048)));;
-
-/****************************************************************************/
-
-/*
- *     Ideally we want to use the MAC address stored in flash.
- *     But we do some sanity checks in case they are not present
- *     first.
- */
-unsigned char eth_mac[] = {
-       0x00, 0x13, 0xc6, 0x00, 0x00, 0x00
-};
-
-void ks8695_getmac(void)
-{
-       unsigned char *fp;
-       int i;
-
-       /* Check if flash MAC is valid */
-       fp = (unsigned char *) 0x0201c000;
-       for (i = 0; (i < 6); i++) {
-               if ((fp[i] != 0) && (fp[i] != 0xff))
-                       break;
-       }
-
-       /* If we found a valid looking MAC address then use it */
-       if (i < 6)
-               memcpy(&eth_mac[0], fp, 6);
-}
-
-/****************************************************************************/
-
-void eth_reset(bd_t *bd)
-{
-       int i;
-
-       debug ("%s(%d): eth_reset()\n", __FILE__, __LINE__);
-
-       /* Reset the ethernet engines first */
-       ks8695_write(KS8695_LAN_DMA_TX, 0x80000000);
-       ks8695_write(KS8695_LAN_DMA_RX, 0x80000000);
-
-       ks8695_getmac();
-
-       /* Set MAC address */
-       ks8695_write(KS8695_LAN_MAC_LOW, (eth_mac[5] | (eth_mac[4] << 8) |
-               (eth_mac[3] << 16) | (eth_mac[2] << 24)));
-       ks8695_write(KS8695_LAN_MAC_HIGH, (eth_mac[1] | (eth_mac[0] << 8)));
-
-       /* Turn the 4 port switch on */
-       i = ks8695_read(KS8695_SWITCH_CTRL0);
-       ks8695_write(KS8695_SWITCH_CTRL0, (i | 0x1));
-       /* ks8695_write(KS8695_WAN_CONTROL, 0x3f000066); */
-
-       /* Initialize descriptor rings */
-       for (i = 0; (i < TXDESCS); i++) {
-               ks8695_tx[i].owner = 0;
-               ks8695_tx[i].ctrl = 0;
-               ks8695_tx[i].addr = (uint32_t) &ks8695_bufs[i*BUFSIZE];
-               ks8695_tx[i].next = (uint32_t) &ks8695_tx[i+1];
-       }
-       ks8695_tx[TXDESCS-1].ctrl = 0x02000000;
-       ks8695_tx[TXDESCS-1].next = (uint32_t) &ks8695_tx[0];
-
-       for (i = 0; (i < RXDESCS); i++) {
-               ks8695_rx[i].status = 0x80000000;
-               ks8695_rx[i].ctrl = BUFSIZE - 4;
-               ks8695_rx[i].addr = (uint32_t) &ks8695_bufs[(i+TXDESCS)*BUFSIZE];
-               ks8695_rx[i].next = (uint32_t) &ks8695_rx[i+1];
-       }
-       ks8695_rx[RXDESCS-1].ctrl |= 0x00080000;
-       ks8695_rx[RXDESCS-1].next = (uint32_t) &ks8695_rx[0];
-
-       /* The KS8695 is pretty slow reseting the ethernets... */
-       udelay(2000000);
-
-       /* Enable the ethernet engine */
-       ks8695_write(KS8695_LAN_TX_LIST, (uint32_t) &ks8695_tx[0]);
-       ks8695_write(KS8695_LAN_RX_LIST, (uint32_t) &ks8695_rx[0]);
-       ks8695_write(KS8695_LAN_DMA_TX, 0x3);
-       ks8695_write(KS8695_LAN_DMA_RX, 0x71);
-       ks8695_write(KS8695_LAN_DMA_RX_START, 0x1);
-
-       printf("KS8695 ETHERNET: ");
-       for (i = 0; (i < 5); i++) {
-               bd->bi_enetaddr[i] = eth_mac[i];
-               printf("%02x:", eth_mac[i]);
-       }
-       bd->bi_enetaddr[i] = eth_mac[i];
-       printf("%02x\n", eth_mac[i]);
-}
-
-/****************************************************************************/
-
-int eth_init(bd_t *bd)
-{
-       debug ("%s(%d): eth_init()\n", __FILE__, __LINE__);
-
-       eth_reset(bd);
-       return 0;
-}
-
-/****************************************************************************/
-
-void eth_halt(void)
-{
-       debug ("%s(%d): eth_halt()\n", __FILE__, __LINE__);
-
-       /* Reset the ethernet engines */
-       ks8695_write(KS8695_LAN_DMA_TX, 0x80000000);
-       ks8695_write(KS8695_LAN_DMA_RX, 0x80000000);
-}
-
-/****************************************************************************/
-
-int eth_rx(void)
-{
-       volatile struct ks8695_rxdesc *dp;
-       int i, len = 0;
-
-       debug ("%s(%d): eth_rx()\n", __FILE__, __LINE__);
-
-       for (i = 0; (i < RXDESCS); i++) {
-               dp= &ks8695_rx[i];
-               if ((dp->status & 0x80000000) == 0) {
-                       len = (dp->status & 0x7ff) - 4;
-                       NetReceive((void *) dp->addr, len);
-                       dp->status = 0x80000000;
-                       ks8695_write(KS8695_LAN_DMA_RX_START, 0x1);
-                       break;
-               }
-       }
-
-       return len;
-}
-
-/****************************************************************************/
-
-int eth_send(volatile void *packet, int len)
-{
-       volatile struct ks8695_txdesc *dp;
-       static int next = 0;
-
-       debug ("%s(%d): eth_send(packet=%x,len=%d)\n", __FILE__, __LINE__,
-               packet, len);
-
-       dp = &ks8695_tx[next];
-       memcpy((void *) dp->addr, (void *) packet, len);
-
-       if (len < 64) {
-               memset((void *) (dp->addr + len), 0, 64-len);
-               len = 64;
-       }
-
-       dp->ctrl = len | 0xe0000000;
-       dp->owner = 0x80000000;
-
-       ks8695_write(KS8695_LAN_DMA_TX, 0x3);
-       ks8695_write(KS8695_LAN_DMA_TX_START, 0x1);
-
-       if (++next >= TXDESCS)
-               next = 0;
-
-       return len;
-}
-
-#endif /* CONFIG_DRIVER_KS8695ETH */
diff --git a/drivers/lan91c96.c b/drivers/lan91c96.c
deleted file mode 100644 (file)
index ecdcbd9..0000000
+++ /dev/null
@@ -1,967 +0,0 @@
-/*------------------------------------------------------------------------
- * lan91c96.c
- * This is a driver for SMSC's LAN91C96 single-chip Ethernet device, based
- * on the SMC91111 driver from U-boot.
- *
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Rolf Offermanns <rof@sysgo.de>
- *
- * Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
- *       Developed by Simple Network Magic Corporation (SNMC)
- * Copyright (C) 1996 by Erik Stahlman (ES)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Information contained in this file was obtained from the LAN91C96
- * manual from SMC.  To get a copy, if you really want one, you can find
- * information under www.smsc.com.
- *
- *
- * "Features" of the SMC chip:
- *   6144 byte packet memory. ( for the 91C96 )
- *   EEPROM for configuration
- *   AUI/TP selection  ( mine has 10Base2/10BaseT select )
- *
- * Arguments:
- *     io      = for the base address
- *     irq     = for the IRQ
- *
- * author:
- *     Erik Stahlman                           ( erik@vt.edu )
- *     Daris A Nevil                           ( dnevil@snmc.com )
- *
- *
- * Hardware multicast code from Peter Cammaert ( pc@denkart.be )
- *
- * Sources:
- *    o   SMSC LAN91C96 databook (www.smsc.com)
- *    o   smc91111.c (u-boot driver)
- *    o   smc9194.c (linux kernel driver)
- *    o   lan91c96.c (Intel Diagnostic Manager driver)
- *
- * History:
- *     04/30/03  Mathijs Haarman       Modified smc91111.c (u-boot version)
- *                                     for lan91c96
- *---------------------------------------------------------------------------
- */
-
-#include <common.h>
-#include <command.h>
-#include "lan91c96.h"
-#include <net.h>
-
-#ifdef CONFIG_DRIVER_LAN91C96
-
-#if defined(CONFIG_CMD_NET)
-
-/*------------------------------------------------------------------------
- *
- * Configuration options, for the experienced user to change.
- *
- -------------------------------------------------------------------------*/
-
-/* Use power-down feature of the chip */
-#define POWER_DOWN     0
-
-/*
- * Wait time for memory to be free.  This probably shouldn't be
- * tuned that much, as waiting for this means nothing else happens
- * in the system
-*/
-#define MEMORY_WAIT_TIME 16
-
-#define SMC_DEBUG 0
-
-#if (SMC_DEBUG > 2 )
-#define PRINTK3(args...) printf(args)
-#else
-#define PRINTK3(args...)
-#endif
-
-#if SMC_DEBUG > 1
-#define PRINTK2(args...) printf(args)
-#else
-#define PRINTK2(args...)
-#endif
-
-#ifdef SMC_DEBUG
-#define PRINTK(args...) printf(args)
-#else
-#define PRINTK(args...)
-#endif
-
-
-/*------------------------------------------------------------------------
- *
- * The internal workings of the driver.  If you are changing anything
- * here with the SMC stuff, you should have the datasheet and know
- * what you are doing.
- *
- *------------------------------------------------------------------------
- */
-#define CARDNAME "LAN91C96"
-
-#define SMC_BASE_ADDRESS CONFIG_LAN91C96_BASE
-
-#define SMC_DEV_NAME "LAN91C96"
-#define SMC_ALLOC_MAX_TRY 5
-#define SMC_TX_TIMEOUT 30
-
-#define ETH_ZLEN 60
-
-#ifdef  CONFIG_LAN91C96_USE_32_BIT
-#define USE_32_BIT  1
-#else
-#undef USE_32_BIT
-#endif
-
-/*-----------------------------------------------------------------
- *
- *  The driver can be entered at any of the following entry points.
- *
- *-----------------------------------------------------------------
- */
-
-extern int eth_init (bd_t * bd);
-extern void eth_halt (void);
-extern int eth_rx (void);
-extern int eth_send (volatile void *packet, int length);
-#if 0
-static int smc_hw_init (void);
-#endif
-
-/*
- * This is called by  register_netdev().  It is responsible for
- * checking the portlist for the SMC9000 series chipset.  If it finds
- * one, then it will initialize the device, find the hardware information,
- * and sets up the appropriate device parameters.
- * NOTE: Interrupts are *OFF* when this procedure is called.
- *
- * NB:This shouldn't be static since it is referred to externally.
- */
-int smc_init (void);
-
-/*
- * This is called by  unregister_netdev().  It is responsible for
- * cleaning up before the driver is finally unregistered and discarded.
- */
-void smc_destructor (void);
-
-/*
- * The kernel calls this function when someone wants to use the device,
- * typically 'ifconfig ethX up'.
- */
-static int smc_open (bd_t *bd);
-
-
-/*
- * This is called by the kernel in response to 'ifconfig ethX down'.  It
- * is responsible for cleaning up everything that the open routine
- * does, and maybe putting the card into a powerdown state.
- */
-static int smc_close (void);
-
-/*
- * This is a separate procedure to handle the receipt of a packet, to
- * leave the interrupt code looking slightly cleaner
- */
-static int smc_rcv (void);
-
-/* See if a MAC address is defined in the current environment. If so use it. If not
- . print a warning and set the environment and other globals with the default.
- . If an EEPROM is present it really should be consulted.
-*/
-int smc_get_ethaddr(bd_t *bd);
-int get_rom_mac(unsigned char *v_rom_mac);
-
-/* ------------------------------------------------------------
- * Internal routines
- * ------------------------------------------------------------
- */
-
-static unsigned char smc_mac_addr[] = { 0xc0, 0x00, 0x00, 0x1b, 0x62, 0x9c };
-
-/*
- * This function must be called before smc_open() if you want to override
- * the default mac address.
- */
-
-void smc_set_mac_addr (const unsigned char *addr)
-{
-       int i;
-
-       for (i = 0; i < sizeof (smc_mac_addr); i++) {
-               smc_mac_addr[i] = addr[i];
-       }
-}
-
-/*
- * smc_get_macaddr is no longer used. If you want to override the default
- * mac address, call smc_get_mac_addr as a part of the board initialisation.
- */
-
-#if 0
-void smc_get_macaddr (byte * addr)
-{
-       /* MAC ADDRESS AT FLASHBLOCK 1 / OFFSET 0x10 */
-       unsigned char *dnp1110_mac = (unsigned char *) (0xE8000000 + 0x20010);
-       int i;
-
-
-       for (i = 0; i < 6; i++) {
-               addr[0] = *(dnp1110_mac + 0);
-               addr[1] = *(dnp1110_mac + 1);
-               addr[2] = *(dnp1110_mac + 2);
-               addr[3] = *(dnp1110_mac + 3);
-               addr[4] = *(dnp1110_mac + 4);
-               addr[5] = *(dnp1110_mac + 5);
-       }
-}
-#endif /* 0 */
-
-/***********************************************
- * Show available memory                       *
- ***********************************************/
-void dump_memory_info (void)
-{
-       word mem_info;
-       word old_bank;
-
-       old_bank = SMC_inw (LAN91C96_BANK_SELECT) & 0xF;
-
-       SMC_SELECT_BANK (0);
-       mem_info = SMC_inw (LAN91C96_MIR);
-       PRINTK2 ("Memory: %4d available\n", (mem_info >> 8) * 2048);
-
-       SMC_SELECT_BANK (old_bank);
-}
-
-/*
- * A rather simple routine to print out a packet for debugging purposes.
- */
-#if SMC_DEBUG > 2
-static void print_packet (byte *, int);
-#endif
-
-/* #define tx_done(dev) 1 */
-
-
-/* this does a soft reset on the device */
-static void smc_reset (void);
-
-/* Enable Interrupts, Receive, and Transmit */
-static void smc_enable (void);
-
-/* this puts the device in an inactive state */
-static void smc_shutdown (void);
-
-
-static int poll4int (byte mask, int timeout)
-{
-       int tmo = get_timer (0) + timeout * CFG_HZ;
-       int is_timeout = 0;
-       word old_bank = SMC_inw (LAN91C96_BANK_SELECT);
-
-       PRINTK2 ("Polling...\n");
-       SMC_SELECT_BANK (2);
-       while ((SMC_inw (LAN91C96_INT_STATS) & mask) == 0) {
-               if (get_timer (0) >= tmo) {
-                       is_timeout = 1;
-                       break;
-               }
-       }
-
-       /* restore old bank selection */
-       SMC_SELECT_BANK (old_bank);
-
-       if (is_timeout)
-               return 1;
-       else
-               return 0;
-}
-
-/*
- * Function: smc_reset( void )
- * Purpose:
- *     This sets the SMC91111 chip to its normal state, hopefully from whatever
- *     mess that any other DOS driver has put it in.
- *
- * Maybe I should reset more registers to defaults in here?  SOFTRST  should
- * do that for me.
- *
- * Method:
- *     1.  send a SOFT RESET
- *     2.  wait for it to finish
- *     3.  enable autorelease mode
- *     4.  reset the memory management unit
- *     5.  clear all interrupts
- *
-*/
-static void smc_reset (void)
-{
-       PRINTK2 ("%s:smc_reset\n", SMC_DEV_NAME);
-
-       /* This resets the registers mostly to defaults, but doesn't
-          affect EEPROM.  That seems unnecessary */
-       SMC_SELECT_BANK (0);
-       SMC_outw (LAN91C96_RCR_SOFT_RST, LAN91C96_RCR);
-
-       udelay (10);
-
-       /* Disable transmit and receive functionality */
-       SMC_outw (0, LAN91C96_RCR);
-       SMC_outw (0, LAN91C96_TCR);
-
-       /* set the control register */
-       SMC_SELECT_BANK (1);
-       SMC_outw (SMC_inw (LAN91C96_CONTROL) | LAN91C96_CTR_BIT_8,
-                         LAN91C96_CONTROL);
-
-       /* Disable all interrupts */
-       SMC_outb (0, LAN91C96_INT_MASK);
-}
-
-/*
- * Function: smc_enable
- * Purpose: let the chip talk to the outside work
- * Method:
- *     1.  Initialize the Memory Configuration Register
- *     2.  Enable the transmitter
- *     3.  Enable the receiver
-*/
-static void smc_enable ()
-{
-       PRINTK2 ("%s:smc_enable\n", SMC_DEV_NAME);
-       SMC_SELECT_BANK (0);
-
-       /* Initialize the Memory Configuration Register. See page
-          49 of the LAN91C96 data sheet for details. */
-       SMC_outw (LAN91C96_MCR_TRANSMIT_PAGES, LAN91C96_MCR);
-
-       /* Initialize the Transmit Control Register */
-       SMC_outw (LAN91C96_TCR_TXENA, LAN91C96_TCR);
-       /* Initialize the Receive Control Register
-        * FIXME:
-        * The promiscuous bit set because I could not receive ARP reply
-        * packets from the server when I send a ARP request. It only works
-        * when I set the promiscuous bit
-        */
-       SMC_outw (LAN91C96_RCR_RXEN | LAN91C96_RCR_PRMS, LAN91C96_RCR);
-}
-
-/*
- * Function: smc_shutdown
- * Purpose:  closes down the SMC91xxx chip.
- * Method:
- *     1. zero the interrupt mask
- *     2. clear the enable receive flag
- *     3. clear the enable xmit flags
- *
- * TODO:
- *   (1) maybe utilize power down mode.
- *     Why not yet?  Because while the chip will go into power down mode,
- *     the manual says that it will wake up in response to any I/O requests
- *     in the register space.   Empirical results do not show this working.
- */
-static void smc_shutdown ()
-{
-       PRINTK2 (CARDNAME ":smc_shutdown\n");
-
-       /* no more interrupts for me */
-       SMC_SELECT_BANK (2);
-       SMC_outb (0, LAN91C96_INT_MASK);
-
-       /* and tell the card to stay away from that nasty outside world */
-       SMC_SELECT_BANK (0);
-       SMC_outb (0, LAN91C96_RCR);
-       SMC_outb (0, LAN91C96_TCR);
-}
-
-
-/*
- * Function:  smc_hardware_send_packet(struct net_device * )
- * Purpose:
- *     This sends the actual packet to the SMC9xxx chip.
- *
- * Algorithm:
- *     First, see if a saved_skb is available.
- *             ( this should NOT be called if there is no 'saved_skb'
- *     Now, find the packet number that the chip allocated
- *     Point the data pointers at it in memory
- *     Set the length word in the chip's memory
- *     Dump the packet to chip memory
- *     Check if a last byte is needed ( odd length packet )
- *             if so, set the control flag right
- *     Tell the card to send it
- *     Enable the transmit interrupt, so I know if it failed
- *     Free the kernel data if I actually sent it.
- */
-static int smc_send_packet (volatile void *packet, int packet_length)
-{
-       byte packet_no;
-       unsigned long ioaddr;
-       byte *buf;
-       int length;
-       int numPages;
-       int try = 0;
-       int time_out;
-       byte status;
-
-
-       PRINTK3 ("%s:smc_hardware_send_packet\n", SMC_DEV_NAME);
-
-       length = ETH_ZLEN < packet_length ? packet_length : ETH_ZLEN;
-
-       /* allocate memory
-        ** The MMU wants the number of pages to be the number of 256 bytes
-        ** 'pages', minus 1 ( since a packet can't ever have 0 pages :) )
-        **
-        ** The 91C111 ignores the size bits, but the code is left intact
-        ** for backwards and future compatibility.
-        **
-        ** Pkt size for allocating is data length +6 (for additional status
-        ** words, length and ctl!)
-        **
-        ** If odd size then last byte is included in this header.
-        */
-       numPages = ((length & 0xfffe) + 6);
-       numPages >>= 8;                         /* Divide by 256 */
-
-       if (numPages > 7) {
-               printf ("%s: Far too big packet error. \n", SMC_DEV_NAME);
-               return 0;
-       }
-
-       /* now, try to allocate the memory */
-
-       SMC_SELECT_BANK (2);
-       SMC_outw (LAN91C96_MMUCR_ALLOC_TX | numPages, LAN91C96_MMU);
-
-  again:
-       try++;
-       time_out = MEMORY_WAIT_TIME;
-       do {
-               status = SMC_inb (LAN91C96_INT_STATS);
-               if (status & LAN91C96_IST_ALLOC_INT) {
-
-                       SMC_outb (LAN91C96_IST_ALLOC_INT, LAN91C96_INT_STATS);
-                       break;
-               }
-       } while (--time_out);
-
-       if (!time_out) {
-               PRINTK2 ("%s: memory allocation, try %d failed ...\n",
-                                SMC_DEV_NAME, try);
-               if (try < SMC_ALLOC_MAX_TRY)
-                       goto again;
-               else
-                       return 0;
-       }
-
-       PRINTK2 ("%s: memory allocation, try %d succeeded ...\n",
-                        SMC_DEV_NAME, try);
-
-       /* I can send the packet now.. */
-
-       ioaddr = SMC_BASE_ADDRESS;
-
-       buf = (byte *) packet;
-
-       /* If I get here, I _know_ there is a packet slot waiting for me */
-       packet_no = SMC_inb (LAN91C96_ARR);
-       if (packet_no & LAN91C96_ARR_FAILED) {
-               /* or isn't there?  BAD CHIP! */
-               printf ("%s: Memory allocation failed. \n", SMC_DEV_NAME);
-               return 0;
-       }
-
-       /* we have a packet address, so tell the card to use it */
-       SMC_outb (packet_no, LAN91C96_PNR);
-
-       /* point to the beginning of the packet */
-       SMC_outw (LAN91C96_PTR_AUTO_INCR, LAN91C96_POINTER);
-
-       PRINTK3 ("%s: Trying to xmit packet of length %x\n",
-                        SMC_DEV_NAME, length);
-
-#if SMC_DEBUG > 2
-       printf ("Transmitting Packet\n");
-       print_packet (buf, length);
-#endif
-
-       /* send the packet length ( +6 for status, length and ctl byte )
-          and the status word ( set to zeros ) */
-#ifdef USE_32_BIT
-       SMC_outl ((length + 6) << 16, LAN91C96_DATA_HIGH);
-#else
-       SMC_outw (0, LAN91C96_DATA_HIGH);
-       /* send the packet length ( +6 for status words, length, and ctl */
-       SMC_outw ((length + 6), LAN91C96_DATA_HIGH);
-#endif /* USE_32_BIT */
-
-       /* send the actual data
-        * I _think_ it's faster to send the longs first, and then
-        * mop up by sending the last word.  It depends heavily
-        * on alignment, at least on the 486.  Maybe it would be
-        * a good idea to check which is optimal?  But that could take
-        * almost as much time as is saved?
-        */
-#ifdef USE_32_BIT
-       SMC_outsl (LAN91C96_DATA_HIGH, buf, length >> 2);
-       if (length & 0x2)
-               SMC_outw (*((word *) (buf + (length & 0xFFFFFFFC))),
-                                 LAN91C96_DATA_HIGH);
-#else
-       SMC_outsw (LAN91C96_DATA_HIGH, buf, (length) >> 1);
-#endif /* USE_32_BIT */
-
-       /* Send the last byte, if there is one.   */
-       if ((length & 1) == 0) {
-               SMC_outw (0, LAN91C96_DATA_HIGH);
-       } else {
-               SMC_outw (buf[length - 1] | 0x2000, LAN91C96_DATA_HIGH);
-       }
-
-       /* and let the chipset deal with it */
-       SMC_outw (LAN91C96_MMUCR_ENQUEUE, LAN91C96_MMU);
-
-       /* poll for TX INT */
-       if (poll4int (LAN91C96_MSK_TX_INT, SMC_TX_TIMEOUT)) {
-               /* sending failed */
-               PRINTK2 ("%s: TX timeout, sending failed...\n", SMC_DEV_NAME);
-
-               /* release packet */
-               SMC_outw (LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU);
-
-               /* wait for MMU getting ready (low) */
-               while (SMC_inw (LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY) {
-                       udelay (10);
-               }
-
-               PRINTK2 ("MMU ready\n");
-
-
-               return 0;
-       } else {
-               /* ack. int */
-               SMC_outw (LAN91C96_IST_TX_INT, LAN91C96_INT_STATS);
-
-               PRINTK2 ("%s: Sent packet of length %d \n", SMC_DEV_NAME, length);
-
-               /* release packet */
-               SMC_outw (LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU);
-
-               /* wait for MMU getting ready (low) */
-               while (SMC_inw (LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY) {
-                       udelay (10);
-               }
-
-               PRINTK2 ("MMU ready\n");
-       }
-
-       return length;
-}
-
-/*-------------------------------------------------------------------------
- * smc_destructor( struct net_device * dev )
- *   Input parameters:
- *     dev, pointer to the device structure
- *
- *   Output:
- *     None.
- *--------------------------------------------------------------------------
- */
-void smc_destructor ()
-{
-       PRINTK2 (CARDNAME ":smc_destructor\n");
-}
-
-
-/*
- * Open and Initialize the board
- *
- * Set up everything, reset the card, etc ..
- *
- */
-static int smc_open (bd_t *bd)
-{
-       int i, err;                     /* used to set hw ethernet address */
-
-       PRINTK2 ("%s:smc_open\n", SMC_DEV_NAME);
-
-       /* reset the hardware */
-
-       smc_reset ();
-       smc_enable ();
-
-       SMC_SELECT_BANK (1);
-
-       err = smc_get_ethaddr (bd);     /* set smc_mac_addr, and sync it with u-boot globals */
-       if (err < 0) {
-               memset (bd->bi_enetaddr, 0, 6); /* hack to make error stick! upper code will abort if not set */
-               return (-1);    /* upper code ignores this, but NOT bi_enetaddr */
-       }
-#ifdef USE_32_BIT
-       for (i = 0; i < 6; i += 2) {
-               word address;
-
-               address = smc_mac_addr[i + 1] << 8;
-               address |= smc_mac_addr[i];
-               SMC_outw (address, LAN91C96_IA0 + i);
-       }
-#else
-       for (i = 0; i < 6; i++)
-               SMC_outb (smc_mac_addr[i], LAN91C96_IA0 + i);
-#endif
-       return 0;
-}
-
-/*-------------------------------------------------------------
- *
- * smc_rcv -  receive a packet from the card
- *
- * There is ( at least ) a packet waiting to be read from
- * chip-memory.
- *
- * o Read the status
- * o If an error, record it
- * o otherwise, read in the packet
- *-------------------------------------------------------------
- */
-static int smc_rcv ()
-{
-       int packet_number;
-       word status;
-       word packet_length;
-       int is_error = 0;
-
-#ifdef USE_32_BIT
-       dword stat_len;
-#endif
-
-
-       SMC_SELECT_BANK (2);
-       packet_number = SMC_inw (LAN91C96_FIFO);
-
-       if (packet_number & LAN91C96_FIFO_RXEMPTY) {
-               return 0;
-       }
-
-       PRINTK3 ("%s:smc_rcv\n", SMC_DEV_NAME);
-       /*  start reading from the start of the packet */
-       SMC_outw (LAN91C96_PTR_READ | LAN91C96_PTR_RCV |
-                         LAN91C96_PTR_AUTO_INCR, LAN91C96_POINTER);
-
-       /* First two words are status and packet_length */
-#ifdef USE_32_BIT
-       stat_len = SMC_inl (LAN91C96_DATA_HIGH);
-       status = stat_len & 0xffff;
-       packet_length = stat_len >> 16;
-#else
-       status = SMC_inw (LAN91C96_DATA_HIGH);
-       packet_length = SMC_inw (LAN91C96_DATA_HIGH);
-#endif
-
-       packet_length &= 0x07ff;        /* mask off top bits */
-
-       PRINTK2 ("RCV: STATUS %4x LENGTH %4x\n", status, packet_length);
-
-       if (!(status & FRAME_FILTER)) {
-               /* Adjust for having already read the first two words */
-               packet_length -= 4;             /*4; */
-
-
-               /* set odd length for bug in LAN91C111, */
-               /* which never sets RS_ODDFRAME */
-               /* TODO ? */
-
-
-#ifdef USE_32_BIT
-               PRINTK3 (" Reading %d dwords (and %d bytes) \n",
-                        packet_length >> 2, packet_length & 3);
-               /* QUESTION:  Like in the TX routine, do I want
-                  to send the DWORDs or the bytes first, or some
-                  mixture.  A mixture might improve already slow PIO
-                  performance  */
-               SMC_insl (LAN91C96_DATA_HIGH, NetRxPackets[0], packet_length >> 2);
-               /* read the left over bytes */
-               if (packet_length & 3) {
-                       int i;
-
-                       byte *tail = (byte *) (NetRxPackets[0] + (packet_length & ~3));
-                       dword leftover = SMC_inl (LAN91C96_DATA_HIGH);
-
-                       for (i = 0; i < (packet_length & 3); i++)
-                               *tail++ = (byte) (leftover >> (8 * i)) & 0xff;
-               }
-#else
-               PRINTK3 (" Reading %d words and %d byte(s) \n",
-                                (packet_length >> 1), packet_length & 1);
-               SMC_insw (LAN91C96_DATA_HIGH, NetRxPackets[0], packet_length >> 1);
-
-#endif /* USE_32_BIT */
-
-#if    SMC_DEBUG > 2
-               printf ("Receiving Packet\n");
-               print_packet (NetRxPackets[0], packet_length);
-#endif
-       } else {
-               /* error ... */
-               /* TODO ? */
-               is_error = 1;
-       }
-
-       while (SMC_inw (LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
-               udelay (1);             /* Wait until not busy */
-
-       /*  error or good, tell the card to get rid of this packet */
-       SMC_outw (LAN91C96_MMUCR_RELEASE_RX, LAN91C96_MMU);
-
-       while (SMC_inw (LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
-               udelay (1);             /* Wait until not busy */
-
-       if (!is_error) {
-               /* Pass the packet up to the protocol layers. */
-               NetReceive (NetRxPackets[0], packet_length);
-               return packet_length;
-       } else {
-               return 0;
-       }
-
-}
-
-/*----------------------------------------------------
- * smc_close
- *
- * this makes the board clean up everything that it can
- * and not talk to the outside world.   Caused by
- * an 'ifconfig ethX down'
- *
- -----------------------------------------------------*/
-static int smc_close ()
-{
-       PRINTK2 ("%s:smc_close\n", SMC_DEV_NAME);
-
-       /* clear everything */
-       smc_shutdown ();
-
-       return 0;
-}
-
-#if SMC_DEBUG > 2
-static void print_packet (byte * buf, int length)
-{
-#if 0
-       int i;
-       int remainder;
-       int lines;
-
-       printf ("Packet of length %d \n", length);
-
-       lines = length / 16;
-       remainder = length % 16;
-
-       for (i = 0; i < lines; i++) {
-               int cur;
-
-               for (cur = 0; cur < 8; cur++) {
-                       byte a, b;
-
-                       a = *(buf++);
-                       b = *(buf++);
-                       printf ("%02x%02x ", a, b);
-               }
-               printf ("\n");
-       }
-       for (i = 0; i < remainder / 2; i++) {
-               byte a, b;
-
-               a = *(buf++);
-               b = *(buf++);
-               printf ("%02x%02x ", a, b);
-       }
-       printf ("\n");
-#endif /* 0 */
-}
-#endif /* SMC_DEBUG > 2 */
-
-int eth_init (bd_t * bd)
-{
-       return (smc_open(bd));
-}
-
-void eth_halt ()
-{
-       smc_close ();
-}
-
-int eth_rx ()
-{
-       return smc_rcv ();
-}
-
-int eth_send (volatile void *packet, int length)
-{
-       return smc_send_packet (packet, length);
-}
-
-
-#if 0
-/*-------------------------------------------------------------------------
- * smc_hw_init()
- *
- *   Function:
- *      Reset and enable the device, check if the I/O space location
- *      is correct
- *
- *   Input parameters:
- *      None
- *
- *   Output:
- *     0 --> success
- *     1 --> error
- *--------------------------------------------------------------------------
- */
-static int smc_hw_init ()
-{
-       unsigned short status_test;
-
-       /* The attribute register of the LAN91C96 is located at address
-          0x0e000000 on the lubbock platform */
-       volatile unsigned *attaddr = (unsigned *) (0x0e000000);
-
-       /* first reset, then enable the device. Sequence is critical */
-       attaddr[LAN91C96_ECOR] |= LAN91C96_ECOR_SRESET;
-       udelay (100);
-       attaddr[LAN91C96_ECOR] &= ~LAN91C96_ECOR_SRESET;
-       attaddr[LAN91C96_ECOR] |= LAN91C96_ECOR_ENABLE;
-
-       /* force 16-bit mode */
-       attaddr[LAN91C96_ECSR] &= ~LAN91C96_ECSR_IOIS8;
-       udelay (100);
-
-       /* check if the I/O address is correct, the upper byte of the
-          bank select register should read 0x33 */
-
-       status_test = SMC_inw (LAN91C96_BANK_SELECT);
-       if ((status_test & 0xFF00) != 0x3300) {
-               printf ("Failed to initialize ethernetchip\n");
-               return 1;
-       }
-       return 0;
-}
-#endif /* 0 */
-
-#endif /* COMMANDS & CFG_NET */
-
-
-/* smc_get_ethaddr (bd_t * bd)
- *
- * This checks both the environment and the ROM for an ethernet address. If
- * found, the environment takes precedence.
- */
-
-int smc_get_ethaddr (bd_t * bd)
-{
-       int env_size = 0;
-       int rom_valid = 0;
-       int env_present = 0;
-       int reg = 0;
-       char *s = NULL;
-       char *e = NULL;
-       char *v_mac, es[] = "11:22:33:44:55:66";
-       char s_env_mac[64];
-       uchar v_env_mac[6];
-       uchar v_rom_mac[6];
-
-       env_size = getenv_r ("ethaddr", s_env_mac, sizeof (s_env_mac));
-       if (env_size != sizeof(es)) {   /* Ignore if env is bad or not set */
-               printf ("\n*** Warning: ethaddr is not set properly, ignoring!!\n");
-       } else {
-               env_present = 1;
-               s = s_env_mac;
-
-               for (reg = 0; reg < 6; ++reg) { /* turn string into mac value */
-                       v_env_mac[reg] = s ? simple_strtoul (s, &e, 16) : 0;
-                       if (s)
-                               s = (*e) ? e + 1 : e;
-               }
-       }
-
-       rom_valid = get_rom_mac (v_rom_mac);    /* get ROM mac value if any */
-
-       if (!env_present) {     /* if NO env */
-               if (rom_valid) {        /* but ROM is valid */
-                       v_mac = (char *)v_rom_mac;
-                       sprintf (s_env_mac, "%02X:%02X:%02X:%02X:%02X:%02X",
-                                v_mac[0], v_mac[1], v_mac[2], v_mac[3],
-                                v_mac[4], v_mac[5]);
-                       setenv ("ethaddr", s_env_mac);
-               } else {        /* no env, bad ROM */
-                       printf ("\n*** ERROR: ethaddr is NOT set !!\n");
-                       return (-1);
-               }
-       } else {                /* good env, don't care ROM */
-               v_mac = (char *)v_env_mac;      /* always use a good env over a ROM */
-       }
-
-       if (env_present && rom_valid) { /* if both env and ROM are good */
-               if (memcmp (v_env_mac, v_rom_mac, 6) != 0) {
-                       printf ("\nWarning: MAC addresses don't match:\n");
-                       printf ("\tHW MAC address:  "
-                               "%02X:%02X:%02X:%02X:%02X:%02X\n",
-                               v_rom_mac[0], v_rom_mac[1],
-                               v_rom_mac[2], v_rom_mac[3],
-                               v_rom_mac[4], v_rom_mac[5] );
-                       printf ("\t\"ethaddr\" value: "
-                               "%02X:%02X:%02X:%02X:%02X:%02X\n",
-                               v_env_mac[0], v_env_mac[1],
-                               v_env_mac[2], v_env_mac[3],
-                               v_env_mac[4], v_env_mac[5]) ;
-                       debug ("### Set MAC addr from environment\n");
-               }
-       }
-       memcpy (bd->bi_enetaddr, v_mac, 6);     /* update global address to match env (allows env changing) */
-       smc_set_mac_addr ((unsigned char *)v_mac); /* use old function to update smc default */
-       PRINTK("Using MAC Address %02X:%02X:%02X:%02X:%02X:%02X\n", v_mac[0], v_mac[1],
-               v_mac[2], v_mac[3], v_mac[4], v_mac[5]);
-       return (0);
-}
-
-/*
- * get_rom_mac()
- * Note, this has omly been tested for the OMAP730 P2.
- */
-
-int get_rom_mac (unsigned char *v_rom_mac)
-{
-#ifdef HARDCODE_MAC    /* used for testing or to supress run time warnings */
-       char hw_mac_addr[] = { 0x02, 0x80, 0xad, 0x20, 0x31, 0xb8 };
-
-       memcpy (v_rom_mac, hw_mac_addr, 6);
-       return (1);
-#else
-       int i;
-       SMC_SELECT_BANK (1);
-       for (i=0; i<6; i++)
-       {
-               v_rom_mac[i] = SMC_inb (LAN91C96_IA0 + i);
-       }
-       return (1);
-#endif
-}
-
-#endif /* CONFIG_DRIVER_LAN91C96 */
diff --git a/drivers/lan91c96.h b/drivers/lan91c96.h
deleted file mode 100644 (file)
index 7d33a82..0000000
+++ /dev/null
@@ -1,643 +0,0 @@
-/*------------------------------------------------------------------------
- * lan91c96.h
- *
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Rolf Offermanns <rof@sysgo.de>
- * Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
- *       Developed by Simple Network Magic Corporation (SNMC)
- * Copyright (C) 1996 by Erik Stahlman (ES)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * This file contains register information and access macros for
- * the LAN91C96 single chip ethernet controller.  It is a modified
- * version of the smc9111.h file.
- *
- * Information contained in this file was obtained from the LAN91C96
- * manual from SMC. To get a copy, if you really want one, you can find
- * information under www.smsc.com.
- *
- * Authors
- *     Erik Stahlman                           ( erik@vt.edu )
- *     Daris A Nevil                           ( dnevil@snmc.com )
- *
- * History
- * 04/30/03    Mathijs Haarman         Modified smc91111.h (u-boot version)
- *                                     for lan91c96
- *-------------------------------------------------------------------------
- */
-#ifndef _LAN91C96_H_
-#define _LAN91C96_H_
-
-#include <asm/types.h>
-#include <asm/io.h>
-#include <config.h>
-
-/*
- * This function may be called by the board specific initialisation code
- * in order to override the default mac address.
- */
-
-void smc_set_mac_addr(const unsigned char *addr);
-
-
-/* I want some simple types */
-
-typedef unsigned char                  byte;
-typedef unsigned short                 word;
-typedef unsigned long int              dword;
-
-/*
- * DEBUGGING LEVELS
- *
- * 0 for normal operation
- * 1 for slightly more details
- * >2 for various levels of increasingly useless information
- *    2 for interrupt tracking, status flags
- *    3 for packet info
- *    4 for complete packet dumps
- */
-/*#define SMC_DEBUG 0 */
-
-/* Because of bank switching, the LAN91xxx uses only 16 I/O ports */
-
-#define        SMC_IO_EXTENT   16
-
-#ifdef CONFIG_PXA250
-
-#ifdef CONFIG_LUBBOCK
-#define        SMC_IO_SHIFT    2
-#undef USE_32_BIT
-
-#else
-#define        SMC_IO_SHIFT    0
-#endif
-
-#define        SMCREG(r)       (SMC_BASE_ADDRESS+((r)<<SMC_IO_SHIFT))
-
-#define        SMC_inl(r)      (*((volatile dword *)SMCREG(r)))
-#define        SMC_inw(r)      (*((volatile word *)SMCREG(r)))
-#define SMC_inb(p) ({ \
-       unsigned int __p = p; \
-       unsigned int __v = SMC_inw(__p & ~1); \
-       if (__p & 1) __v >>= 8; \
-       else __v &= 0xff; \
-       __v; })
-
-#define        SMC_outl(d,r)   (*((volatile dword *)SMCREG(r)) = d)
-#define        SMC_outw(d,r)   (*((volatile word *)SMCREG(r)) = d)
-#define        SMC_outb(d,r)   ({      word __d = (byte)(d);  \
-                               word __w = SMC_inw((r)&~1);  \
-                               __w &= ((r)&1) ? 0x00FF : 0xFF00;  \
-                               __w |= ((r)&1) ? __d<<8 : __d;  \
-                               SMC_outw(__w,(r)&~1);  \
-                       })
-
-#define SMC_outsl(r,b,l)       ({      int __i; \
-                                       dword *__b2; \
-                                       __b2 = (dword *) b; \
-                                       for (__i = 0; __i < l; __i++) { \
-                                           SMC_outl( *(__b2 + __i), r ); \
-                                       } \
-                               })
-
-#define SMC_outsw(r,b,l)       ({      int __i; \
-                                       word *__b2; \
-                                       __b2 = (word *) b; \
-                                       for (__i = 0; __i < l; __i++) { \
-                                           SMC_outw( *(__b2 + __i), r ); \
-                                       } \
-                               })
-
-#define SMC_insl(r,b,l)        ({      int __i ;  \
-                                       dword *__b2;  \
-                                       __b2 = (dword *) b;  \
-                                       for (__i = 0; __i < l; __i++) {  \
-                                         *(__b2 + __i) = SMC_inl(r);  \
-                                         SMC_inl(0);  \
-                                       };  \
-                               })
-
-#define SMC_insw(r,b,l)        ({      int __i ;  \
-                                       word *__b2;  \
-                                       __b2 = (word *) b;  \
-                                       for (__i = 0; __i < l; __i++) {  \
-                                         *(__b2 + __i) = SMC_inw(r);  \
-                                         SMC_inw(0);  \
-                                       };  \
-                               })
-
-#define SMC_insb(r,b,l)        ({      int __i ;  \
-                                       byte *__b2;  \
-                                       __b2 = (byte *) b;  \
-                                       for (__i = 0; __i < l; __i++) {  \
-                                         *(__b2 + __i) = SMC_inb(r);  \
-                                         SMC_inb(0);  \
-                                       };  \
-                               })
-
-#else /* if not CONFIG_PXA250 */
-
-/*
- * We have only 16 Bit PCMCIA access on Socket 0
- */
-
-#define        SMC_inw(r)      (*((volatile word *)(SMC_BASE_ADDRESS+(r))))
-#define  SMC_inb(r)    (((r)&1) ? SMC_inw((r)&~1)>>8 : SMC_inw(r)&0xFF)
-
-#define        SMC_outw(d,r)   (*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d)
-#define        SMC_outb(d,r)   ({      word __d = (byte)(d);  \
-                               word __w = SMC_inw((r)&~1);  \
-                               __w &= ((r)&1) ? 0x00FF : 0xFF00;  \
-                               __w |= ((r)&1) ? __d<<8 : __d;  \
-                               SMC_outw(__w,(r)&~1);  \
-                       })
-#if 0
-#define        SMC_outsw(r,b,l)        outsw(SMC_BASE_ADDRESS+(r), (b), (l))
-#else
-#define SMC_outsw(r,b,l)       ({      int __i; \
-                                       word *__b2; \
-                                       __b2 = (word *) b; \
-                                       for (__i = 0; __i < l; __i++) { \
-                                           SMC_outw( *(__b2 + __i), r); \
-                                       } \
-                               })
-#endif
-
-#if 0
-#define        SMC_insw(r,b,l)         insw(SMC_BASE_ADDRESS+(r), (b), (l))
-#else
-#define SMC_insw(r,b,l)        ({      int __i ;  \
-                                       word *__b2;  \
-                                       __b2 = (word *) b;  \
-                                       for (__i = 0; __i < l; __i++) {  \
-                                         *(__b2 + __i) = SMC_inw(r);  \
-                                         SMC_inw(0);  \
-                                       };  \
-                               })
-#endif
-
-#endif
-
-/*
- ****************************************************************************
- *     Bank Select Field
- ****************************************************************************
- */
-#define LAN91C96_BANK_SELECT  14       /* Bank Select Register */
-#define LAN91C96_BANKSELECT (0x3UC << 0)
-#define BANK0               0x00
-#define BANK1               0x01
-#define BANK2               0x02
-#define BANK3               0x03
-#define BANK4               0x04
-
-/*
- ****************************************************************************
- *     EEPROM Addresses.
- ****************************************************************************
- */
-#define EEPROM_MAC_OFFSET_1    0x6020
-#define EEPROM_MAC_OFFSET_2    0x6021
-#define EEPROM_MAC_OFFSET_3    0x6022
-
-/*
- ****************************************************************************
- *     Bank 0 Register Map in I/O Space
- ****************************************************************************
- */
-#define LAN91C96_TCR          0        /* Transmit Control Register */
-#define LAN91C96_EPH_STATUS   2        /* EPH Status Register */
-#define LAN91C96_RCR          4        /* Receive Control Register */
-#define LAN91C96_COUNTER      6        /* Counter Register */
-#define LAN91C96_MIR          8        /* Memory Information Register */
-#define LAN91C96_MCR          10       /* Memory Configuration Register */
-
-/*
- ****************************************************************************
- *     Transmit Control Register - Bank 0 - Offset 0
- ****************************************************************************
- */
-#define LAN91C96_TCR_TXENA        (0x1U << 0)
-#define LAN91C96_TCR_LOOP         (0x1U << 1)
-#define LAN91C96_TCR_FORCOL       (0x1U << 2)
-#define LAN91C96_TCR_TXP_EN       (0x1U << 3)
-#define LAN91C96_TCR_PAD_EN       (0x1U << 7)
-#define LAN91C96_TCR_NOCRC        (0x1U << 8)
-#define LAN91C96_TCR_MON_CSN      (0x1U << 10)
-#define LAN91C96_TCR_FDUPLX       (0x1U << 11)
-#define LAN91C96_TCR_STP_SQET     (0x1U << 12)
-#define LAN91C96_TCR_EPH_LOOP     (0x1U << 13)
-#define LAN91C96_TCR_ETEN_TYPE    (0x1U << 14)
-#define LAN91C96_TCR_FDSE         (0x1U << 15)
-
-/*
- ****************************************************************************
- *     EPH Status Register - Bank 0 - Offset 2
- ****************************************************************************
- */
-#define LAN91C96_EPHSR_TX_SUC     (0x1U << 0)
-#define LAN91C96_EPHSR_SNGL_COL   (0x1U << 1)
-#define LAN91C96_EPHSR_MUL_COL    (0x1U << 2)
-#define LAN91C96_EPHSR_LTX_MULT   (0x1U << 3)
-#define LAN91C96_EPHSR_16COL      (0x1U << 4)
-#define LAN91C96_EPHSR_SQET       (0x1U << 5)
-#define LAN91C96_EPHSR_LTX_BRD    (0x1U << 6)
-#define LAN91C96_EPHSR_TX_DEFR    (0x1U << 7)
-#define LAN91C96_EPHSR_WAKEUP     (0x1U << 8)
-#define LAN91C96_EPHSR_LATCOL     (0x1U << 9)
-#define LAN91C96_EPHSR_LOST_CARR  (0x1U << 10)
-#define LAN91C96_EPHSR_EXC_DEF    (0x1U << 11)
-#define LAN91C96_EPHSR_CTR_ROL    (0x1U << 12)
-
-#define LAN91C96_EPHSR_LINK_OK    (0x1U << 14)
-#define LAN91C96_EPHSR_TX_UNRN    (0x1U << 15)
-
-#define LAN91C96_EPHSR_ERRORS     (LAN91C96_EPHSR_SNGL_COL  |    \
-                                  LAN91C96_EPHSR_MUL_COL   |    \
-                                  LAN91C96_EPHSR_16COL     |    \
-                                  LAN91C96_EPHSR_SQET      |    \
-                                  LAN91C96_EPHSR_TX_DEFR   |    \
-                                  LAN91C96_EPHSR_LATCOL    |    \
-                                  LAN91C96_EPHSR_LOST_CARR |    \
-                                  LAN91C96_EPHSR_EXC_DEF   |    \
-                                  LAN91C96_EPHSR_LINK_OK   |    \
-                                  LAN91C96_EPHSR_TX_UNRN)
-
-/*
- ****************************************************************************
- *     Receive Control Register - Bank 0 - Offset 4
- ****************************************************************************
- */
-#define LAN91C96_RCR_RX_ABORT     (0x1U << 0)
-#define LAN91C96_RCR_PRMS         (0x1U << 1)
-#define LAN91C96_RCR_ALMUL        (0x1U << 2)
-#define LAN91C96_RCR_RXEN         (0x1U << 8)
-#define LAN91C96_RCR_STRIP_CRC    (0x1U << 9)
-#define LAN91C96_RCR_FILT_CAR     (0x1U << 14)
-#define LAN91C96_RCR_SOFT_RST     (0x1U << 15)
-
-/*
- ****************************************************************************
- *     Counter Register - Bank 0 - Offset 6
- ****************************************************************************
- */
-#define LAN91C96_ECR_SNGL_COL     (0xFU << 0)
-#define LAN91C96_ECR_MULT_COL     (0xFU << 5)
-#define LAN91C96_ECR_DEF_TX       (0xFU << 8)
-#define LAN91C96_ECR_EXC_DEF_TX   (0xFU << 12)
-
-/*
- ****************************************************************************
- *     Memory Information Register - Bank 0 - OFfset 8
- ****************************************************************************
- */
-#define LAN91C96_MIR_SIZE        (0x18 << 0)    /* 6144 bytes */
-
-/*
- ****************************************************************************
- *     Memory Configuration Register - Bank 0 - Offset 10
- ****************************************************************************
- */
-#define LAN91C96_MCR_MEM_RES      (0xFFU << 0)
-#define LAN91C96_MCR_MEM_MULT     (0x3U << 9)
-#define LAN91C96_MCR_HIGH_ID      (0x3U << 12)
-
-#define LAN91C96_MCR_TRANSMIT_PAGES 0x6
-
-/*
- ****************************************************************************
- *     Bank 1 Register Map in I/O Space
- ****************************************************************************
- */
-#define LAN91C96_CONFIG       0        /* Configuration Register */
-#define LAN91C96_BASE         2        /* Base Address Register */
-#define LAN91C96_IA0          4        /* Individual Address Register - 0 */
-#define LAN91C96_IA1          5        /* Individual Address Register - 1 */
-#define LAN91C96_IA2          6        /* Individual Address Register - 2 */
-#define LAN91C96_IA3          7        /* Individual Address Register - 3 */
-#define LAN91C96_IA4          8        /* Individual Address Register - 4 */
-#define LAN91C96_IA5          9        /* Individual Address Register - 5 */
-#define LAN91C96_GEN_PURPOSE  10       /* General Address Registers */
-#define LAN91C96_CONTROL      12       /* Control Register */
-
-/*
- ****************************************************************************
- *     Configuration Register - Bank 1 - Offset 0
- ****************************************************************************
- */
-#define LAN91C96_CR_INT_SEL0      (0x1U << 1)
-#define LAN91C96_CR_INT_SEL1      (0x1U << 2)
-#define LAN91C96_CR_RES           (0x3U << 3)
-#define LAN91C96_CR_DIS_LINK      (0x1U << 6)
-#define LAN91C96_CR_16BIT         (0x1U << 7)
-#define LAN91C96_CR_AUI_SELECT    (0x1U << 8)
-#define LAN91C96_CR_SET_SQLCH     (0x1U << 9)
-#define LAN91C96_CR_FULL_STEP     (0x1U << 10)
-#define LAN91C96_CR_NO_WAIT       (0x1U << 12)
-
-/*
- ****************************************************************************
- *     Base Address Register - Bank 1 - Offset 2
- ****************************************************************************
- */
-#define LAN91C96_BAR_RA_BITS      (0x27U << 0)
-#define LAN91C96_BAR_ROM_SIZE     (0x1U << 6)
-#define LAN91C96_BAR_A_BITS       (0xFFU << 8)
-
-/*
- ****************************************************************************
- *     Control Register - Bank 1 - Offset 12
- ****************************************************************************
- */
-#define LAN91C96_CTR_STORE        (0x1U << 0)
-#define LAN91C96_CTR_RELOAD       (0x1U << 1)
-#define LAN91C96_CTR_EEPROM       (0x1U << 2)
-#define LAN91C96_CTR_TE_ENABLE    (0x1U << 5)
-#define LAN91C96_CTR_CR_ENABLE    (0x1U << 6)
-#define LAN91C96_CTR_LE_ENABLE    (0x1U << 7)
-#define LAN91C96_CTR_BIT_8        (0x1U << 8)
-#define LAN91C96_CTR_AUTO_RELEASE (0x1U << 11)
-#define LAN91C96_CTR_WAKEUP_EN    (0x1U << 12)
-#define LAN91C96_CTR_PWRDN        (0x1U << 13)
-#define LAN91C96_CTR_RCV_BAD      (0x1U << 14)
-
-/*
- ****************************************************************************
- *     Bank 2 Register Map in I/O Space
- ****************************************************************************
- */
-#define LAN91C96_MMU            0      /* MMU Command Register */
-#define LAN91C96_AUTO_TX_START  1      /* Auto Tx Start Register */
-#define LAN91C96_PNR            2      /* Packet Number Register */
-#define LAN91C96_ARR            3      /* Allocation Result Register */
-#define LAN91C96_FIFO           4      /* FIFO Ports Register */
-#define LAN91C96_POINTER        6      /* Pointer Register */
-#define LAN91C96_DATA_HIGH      8      /* Data High Register */
-#define LAN91C96_DATA_LOW       10     /* Data Low Register */
-#define LAN91C96_INT_STATS      12     /* Interrupt Status Register - RO */
-#define LAN91C96_INT_ACK        12     /* Interrupt Acknowledge Register -WO */
-#define LAN91C96_INT_MASK       13     /* Interrupt Mask Register */
-
-/*
- ****************************************************************************
- *     MMU Command Register - Bank 2 - Offset 0
- ****************************************************************************
- */
-#define LAN91C96_MMUCR_NO_BUSY    (0x1U << 0)
-#define LAN91C96_MMUCR_N1         (0x1U << 1)
-#define LAN91C96_MMUCR_N2         (0x1U << 2)
-#define LAN91C96_MMUCR_COMMAND    (0xFU << 4)
-#define LAN91C96_MMUCR_ALLOC_TX   (0x2U << 4)    /* WXYZ = 0010 */
-#define LAN91C96_MMUCR_RESET_MMU  (0x4U << 4)    /* WXYZ = 0100 */
-#define LAN91C96_MMUCR_REMOVE_RX  (0x6U << 4)    /* WXYZ = 0110 */
-#define LAN91C96_MMUCR_REMOVE_TX  (0x7U << 4)    /* WXYZ = 0111 */
-#define LAN91C96_MMUCR_RELEASE_RX (0x8U << 4)    /* WXYZ = 1000 */
-#define LAN91C96_MMUCR_RELEASE_TX (0xAU << 4)    /* WXYZ = 1010 */
-#define LAN91C96_MMUCR_ENQUEUE    (0xCU << 4)    /* WXYZ = 1100 */
-#define LAN91C96_MMUCR_RESET_TX   (0xEU << 4)    /* WXYZ = 1110 */
-
-/*
- ****************************************************************************
- *     Auto Tx Start Register - Bank 2 - Offset 1
- ****************************************************************************
- */
-#define LAN91C96_AUTOTX           (0xFFU << 0)
-
-/*
- ****************************************************************************
- *     Packet Number Register - Bank 2 - Offset 2
- ****************************************************************************
- */
-#define LAN91C96_PNR_TX           (0x1FU << 0)
-
-/*
- ****************************************************************************
- *     Allocation Result Register - Bank 2 - Offset 3
- ****************************************************************************
- */
-#define LAN91C96_ARR_ALLOC_PN     (0x7FU << 0)
-#define LAN91C96_ARR_FAILED       (0x1U << 7)
-
-/*
- ****************************************************************************
- *     FIFO Ports Register - Bank 2 - Offset 4
- ****************************************************************************
- */
-#define LAN91C96_FIFO_TX_DONE_PN  (0x1FU << 0)
-#define LAN91C96_FIFO_TEMPTY      (0x1U << 7)
-#define LAN91C96_FIFO_RX_DONE_PN  (0x1FU << 8)
-#define LAN91C96_FIFO_RXEMPTY     (0x1U << 15)
-
-/*
- ****************************************************************************
- *     Pointer Register - Bank 2 - Offset 6
- ****************************************************************************
- */
-#define LAN91C96_PTR_LOW          (0xFFU << 0)
-#define LAN91C96_PTR_HIGH         (0x7U << 8)
-#define LAN91C96_PTR_AUTO_TX      (0x1U << 11)
-#define LAN91C96_PTR_ETEN         (0x1U << 12)
-#define LAN91C96_PTR_READ         (0x1U << 13)
-#define LAN91C96_PTR_AUTO_INCR    (0x1U << 14)
-#define LAN91C96_PTR_RCV          (0x1U << 15)
-
-#define LAN91C96_PTR_RX_FRAME     (LAN91C96_PTR_RCV       |    \
-                                  LAN91C96_PTR_AUTO_INCR |    \
-                                  LAN91C96_PTR_READ)
-
-/*
- ****************************************************************************
- *     Data Register - Bank 2 - Offset 8
- ****************************************************************************
- */
-#define LAN91C96_CONTROL_CRC      (0x1U << 4)    /* CRC bit */
-#define LAN91C96_CONTROL_ODD      (0x1U << 5)    /* ODD bit */
-
-/*
- ****************************************************************************
- *     Interrupt Status Register - Bank 2 - Offset 12
- ****************************************************************************
- */
-#define LAN91C96_IST_RCV_INT      (0x1U << 0)
-#define LAN91C96_IST_TX_INT       (0x1U << 1)
-#define LAN91C96_IST_TX_EMPTY_INT (0x1U << 2)
-#define LAN91C96_IST_ALLOC_INT    (0x1U << 3)
-#define LAN91C96_IST_RX_OVRN_INT  (0x1U << 4)
-#define LAN91C96_IST_EPH_INT      (0x1U << 5)
-#define LAN91C96_IST_ERCV_INT     (0x1U << 6)
-#define LAN91C96_IST_RX_IDLE_INT  (0x1U << 7)
-
-/*
- ****************************************************************************
- *     Interrupt Acknowledge Register - Bank 2 - Offset 12
- ****************************************************************************
- */
-#define LAN91C96_ACK_TX_INT       (0x1U << 1)
-#define LAN91C96_ACK_TX_EMPTY_INT (0x1U << 2)
-#define LAN91C96_ACK_RX_OVRN_INT  (0x1U << 4)
-#define LAN91C96_ACK_ERCV_INT     (0x1U << 6)
-
-/*
- ****************************************************************************
- *     Interrupt Mask Register - Bank 2 - Offset 13
- ****************************************************************************
- */
-#define LAN91C96_MSK_RCV_INT      (0x1U << 0)
-#define LAN91C96_MSK_TX_INT       (0x1U << 1)
-#define LAN91C96_MSK_TX_EMPTY_INT (0x1U << 2)
-#define LAN91C96_MSK_ALLOC_INT    (0x1U << 3)
-#define LAN91C96_MSK_RX_OVRN_INT  (0x1U << 4)
-#define LAN91C96_MSK_EPH_INT      (0x1U << 5)
-#define LAN91C96_MSK_ERCV_INT     (0x1U << 6)
-#define LAN91C96_MSK_TX_IDLE_INT  (0x1U << 7)
-
-/*
- ****************************************************************************
- *     Bank 3 Register Map in I/O Space
- **************************************************************************
- */
-#define LAN91C96_MGMT_MDO         (0x1U << 0)
-#define LAN91C96_MGMT_MDI         (0x1U << 1)
-#define LAN91C96_MGMT_MCLK        (0x1U << 2)
-#define LAN91C96_MGMT_MDOE        (0x1U << 3)
-#define LAN91C96_MGMT_LOW_ID      (0x3U << 4)
-#define LAN91C96_MGMT_IOS0        (0x1U << 8)
-#define LAN91C96_MGMT_IOS1        (0x1U << 9)
-#define LAN91C96_MGMT_IOS2        (0x1U << 10)
-#define LAN91C96_MGMT_nXNDEC      (0x1U << 11)
-#define LAN91C96_MGMT_HIGH_ID     (0x3U << 12)
-
-/*
- ****************************************************************************
- *     Revision Register - Bank 3 - Offset 10
- ****************************************************************************
- */
-#define LAN91C96_REV_REVID        (0xFU << 0)
-#define LAN91C96_REV_CHIPID       (0xFU << 4)
-
-/*
- ****************************************************************************
- *     Early RCV Register - Bank 3 - Offset 12
- ****************************************************************************
- */
-#define LAN91C96_ERCV_THRESHOLD   (0x1FU << 0)
-#define LAN91C96_ERCV_RCV_DISCRD  (0x1U << 7)
-
-/*
- ****************************************************************************
- *     PCMCIA Configuration Registers
- ****************************************************************************
- */
-#define LAN91C96_ECOR    0x8000        /* Ethernet Configuration Register */
-#define LAN91C96_ECSR    0x8002        /* Ethernet Configuration and Status */
-
-/*
- ****************************************************************************
- *     PCMCIA Ethernet Configuration Option Register (ECOR)
- ****************************************************************************
- */
-#define LAN91C96_ECOR_ENABLE       (0x1U << 0)
-#define LAN91C96_ECOR_WR_ATTRIB    (0x1U << 2)
-#define LAN91C96_ECOR_LEVEL_REQ    (0x1U << 6)
-#define LAN91C96_ECOR_SRESET       (0x1U << 7)
-
-/*
- ****************************************************************************
- *     PCMCIA Ethernet Configuration and Status Register (ECSR)
- ****************************************************************************
- */
-#define LAN91C96_ECSR_INTR        (0x1U << 1)
-#define LAN91C96_ECSR_PWRDWN      (0x1U << 2)
-#define LAN91C96_ECSR_IOIS8       (0x1U << 5)
-
-/*
- ****************************************************************************
- *     Receive Frame Status Word - See page 38 of the LAN91C96 specification.
- ****************************************************************************
- */
-#define LAN91C96_TOO_SHORT        (0x1U << 10)
-#define LAN91C96_TOO_LONG         (0x1U << 11)
-#define LAN91C96_ODD_FRM          (0x1U << 12)
-#define LAN91C96_BAD_CRC          (0x1U << 13)
-#define LAN91C96_BROD_CAST        (0x1U << 14)
-#define LAN91C96_ALGN_ERR         (0x1U << 15)
-
-#define FRAME_FILTER              (LAN91C96_TOO_SHORT | LAN91C96_TOO_LONG  | LAN91C96_BAD_CRC   | LAN91C96_ALGN_ERR)
-
-/*
- ****************************************************************************
- *     Default MAC Address
- ****************************************************************************
- */
-#define MAC_DEF_HI  0x0800
-#define MAC_DEF_MED 0x3333
-#define MAC_DEF_LO  0x0100
-
-/*
- ****************************************************************************
- *     Default I/O Signature - 0x33
- ****************************************************************************
- */
-#define LAN91C96_LOW_SIGNATURE        (0x33U << 0)
-#define LAN91C96_HIGH_SIGNATURE       (0x33U << 8)
-#define LAN91C96_SIGNATURE (LAN91C96_HIGH_SIGNATURE | LAN91C96_LOW_SIGNATURE)
-
-#define LAN91C96_MAX_PAGES     6        /* Maximum number of 256 pages. */
-#define ETHERNET_MAX_LENGTH 1514
-
-
-/*-------------------------------------------------------------------------
- *  I define some macros to make it easier to do somewhat common
- * or slightly complicated, repeated tasks.
- *-------------------------------------------------------------------------
- */
-
-/* select a register bank, 0 to 3  */
-
-#define SMC_SELECT_BANK(x)  { SMC_outw( x, LAN91C96_BANK_SELECT ); }
-
-/* this enables an interrupt in the interrupt mask register */
-#define SMC_ENABLE_INT(x) {\
-               unsigned char mask;\
-               SMC_SELECT_BANK(2);\
-               mask = SMC_inb( LAN91C96_INT_MASK );\
-               mask |= (x);\
-               SMC_outb( mask, LAN91C96_INT_MASK ); \
-}
-
-/* this disables an interrupt from the interrupt mask register */
-
-#define SMC_DISABLE_INT(x) {\
-               unsigned char mask;\
-               SMC_SELECT_BANK(2);\
-               mask = SMC_inb( LAN91C96_INT_MASK );\
-               mask &= ~(x);\
-               SMC_outb( mask, LAN91C96_INT_MASK ); \
-}
-
-/*----------------------------------------------------------------------
- * Define the interrupts that I want to receive from the card
- *
- * I want:
- *  LAN91C96_IST_EPH_INT, for nasty errors
- *  LAN91C96_IST_RCV_INT, for happy received packets
- *  LAN91C96_IST_RX_OVRN_INT, because I have to kick the receiver
- *-------------------------------------------------------------------------
- */
-#define SMC_INTERRUPT_MASK   (LAN91C96_IST_EPH_INT | LAN91C96_IST_RX_OVRN_INT | LAN91C96_IST_RCV_INT)
-
-#endif  /* _LAN91C96_H_ */
diff --git a/drivers/macb.c b/drivers/macb.c
deleted file mode 100644 (file)
index 95cdc49..0000000
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Atmel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <common.h>
-
-#if defined(CONFIG_MACB) \
-       && (defined(CONFIG_CMD_NET) || defined(CONFIG_CMD_MII))
-
-/*
- * The u-boot networking stack is a little weird.  It seems like the
- * networking core allocates receive buffers up front without any
- * regard to the hardware that's supposed to actually receive those
- * packets.
- *
- * The MACB receives packets into 128-byte receive buffers, so the
- * buffers allocated by the core isn't very practical to use.  We'll
- * allocate our own, but we need one such buffer in case a packet
- * wraps around the DMA ring so that we have to copy it.
- *
- * Therefore, define CFG_RX_ETH_BUFFER to 1 in the board-specific
- * configuration header.  This way, the core allocates one RX buffer
- * and one TX buffer, each of which can hold a ethernet packet of
- * maximum size.
- *
- * For some reason, the networking core unconditionally specifies a
- * 32-byte packet "alignment" (which really should be called
- * "padding").  MACB shouldn't need that, but we'll refrain from any
- * core modifications here...
- */
-
-#include <net.h>
-#include <malloc.h>
-
-#include <linux/mii.h>
-#include <asm/io.h>
-#include <asm/dma-mapping.h>
-#include <asm/arch/clk.h>
-
-#include "macb.h"
-
-#define barrier() asm volatile("" ::: "memory")
-
-#define CFG_MACB_RX_BUFFER_SIZE                4096
-#define CFG_MACB_RX_RING_SIZE          (CFG_MACB_RX_BUFFER_SIZE / 128)
-#define CFG_MACB_TX_RING_SIZE          16
-#define CFG_MACB_TX_TIMEOUT            1000
-#define CFG_MACB_AUTONEG_TIMEOUT       5000000
-
-struct macb_dma_desc {
-       u32     addr;
-       u32     ctrl;
-};
-
-#define RXADDR_USED            0x00000001
-#define RXADDR_WRAP            0x00000002
-
-#define RXBUF_FRMLEN_MASK      0x00000fff
-#define RXBUF_FRAME_START      0x00004000
-#define RXBUF_FRAME_END                0x00008000
-#define RXBUF_TYPEID_MATCH     0x00400000
-#define RXBUF_ADDR4_MATCH      0x00800000
-#define RXBUF_ADDR3_MATCH      0x01000000
-#define RXBUF_ADDR2_MATCH      0x02000000
-#define RXBUF_ADDR1_MATCH      0x04000000
-#define RXBUF_BROADCAST                0x80000000
-
-#define TXBUF_FRMLEN_MASK      0x000007ff
-#define TXBUF_FRAME_END                0x00008000
-#define TXBUF_NOCRC            0x00010000
-#define TXBUF_EXHAUSTED                0x08000000
-#define TXBUF_UNDERRUN         0x10000000
-#define TXBUF_MAXRETRY         0x20000000
-#define TXBUF_WRAP             0x40000000
-#define TXBUF_USED             0x80000000
-
-struct macb_device {
-       void                    *regs;
-
-       unsigned int            rx_tail;
-       unsigned int            tx_head;
-       unsigned int            tx_tail;
-
-       void                    *rx_buffer;
-       void                    *tx_buffer;
-       struct macb_dma_desc    *rx_ring;
-       struct macb_dma_desc    *tx_ring;
-
-       unsigned long           rx_buffer_dma;
-       unsigned long           rx_ring_dma;
-       unsigned long           tx_ring_dma;
-
-       const struct device     *dev;
-       struct eth_device       netdev;
-       unsigned short          phy_addr;
-};
-#define to_macb(_nd) container_of(_nd, struct macb_device, netdev)
-
-static void macb_mdio_write(struct macb_device *macb, u8 reg, u16 value)
-{
-       unsigned long netctl;
-       unsigned long netstat;
-       unsigned long frame;
-
-       netctl = macb_readl(macb, NCR);
-       netctl |= MACB_BIT(MPE);
-       macb_writel(macb, NCR, netctl);
-
-       frame = (MACB_BF(SOF, 1)
-                | MACB_BF(RW, 1)
-                | MACB_BF(PHYA, macb->phy_addr)
-                | MACB_BF(REGA, reg)
-                | MACB_BF(CODE, 2)
-                | MACB_BF(DATA, value));
-       macb_writel(macb, MAN, frame);
-
-       do {
-               netstat = macb_readl(macb, NSR);
-       } while (!(netstat & MACB_BIT(IDLE)));
-
-       netctl = macb_readl(macb, NCR);
-       netctl &= ~MACB_BIT(MPE);
-       macb_writel(macb, NCR, netctl);
-}
-
-static u16 macb_mdio_read(struct macb_device *macb, u8 reg)
-{
-       unsigned long netctl;
-       unsigned long netstat;
-       unsigned long frame;
-
-       netctl = macb_readl(macb, NCR);
-       netctl |= MACB_BIT(MPE);
-       macb_writel(macb, NCR, netctl);
-
-       frame = (MACB_BF(SOF, 1)
-                | MACB_BF(RW, 2)
-                | MACB_BF(PHYA, macb->phy_addr)
-                | MACB_BF(REGA, reg)
-                | MACB_BF(CODE, 2));
-       macb_writel(macb, MAN, frame);
-
-       do {
-               netstat = macb_readl(macb, NSR);
-       } while (!(netstat & MACB_BIT(IDLE)));
-
-       frame = macb_readl(macb, MAN);
-
-       netctl = macb_readl(macb, NCR);
-       netctl &= ~MACB_BIT(MPE);
-       macb_writel(macb, NCR, netctl);
-
-       return MACB_BFEXT(DATA, frame);
-}
-
-#if defined(CONFIG_CMD_NET)
-
-static int macb_send(struct eth_device *netdev, volatile void *packet,
-                    int length)
-{
-       struct macb_device *macb = to_macb(netdev);
-       unsigned long paddr, ctrl;
-       unsigned int tx_head = macb->tx_head;
-       int i;
-
-       paddr = dma_map_single(packet, length, DMA_TO_DEVICE);
-
-       ctrl = length & TXBUF_FRMLEN_MASK;
-       ctrl |= TXBUF_FRAME_END;
-       if (tx_head == (CFG_MACB_TX_RING_SIZE - 1)) {
-               ctrl |= TXBUF_WRAP;
-               macb->tx_head = 0;
-       } else
-               macb->tx_head++;
-
-       macb->tx_ring[tx_head].ctrl = ctrl;
-       macb->tx_ring[tx_head].addr = paddr;
-       barrier();
-       macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));
-
-       /*
-        * I guess this is necessary because the networking core may
-        * re-use the transmit buffer as soon as we return...
-        */
-       for (i = 0; i <= CFG_MACB_TX_TIMEOUT; i++) {
-               barrier();
-               ctrl = macb->tx_ring[tx_head].ctrl;
-               if (ctrl & TXBUF_USED)
-                       break;
-               udelay(1);
-       }
-
-       dma_unmap_single(packet, length, paddr);
-
-       if (i <= CFG_MACB_TX_TIMEOUT) {
-               if (ctrl & TXBUF_UNDERRUN)
-                       printf("%s: TX underrun\n", netdev->name);
-               if (ctrl & TXBUF_EXHAUSTED)
-                       printf("%s: TX buffers exhausted in mid frame\n",
-                              netdev->name);
-       } else {
-               printf("%s: TX timeout\n", netdev->name);
-       }
-
-       /* No one cares anyway */
-       return 0;
-}
-
-static void reclaim_rx_buffers(struct macb_device *macb,
-                              unsigned int new_tail)
-{
-       unsigned int i;
-
-       i = macb->rx_tail;
-       while (i > new_tail) {
-               macb->rx_ring[i].addr &= ~RXADDR_USED;
-               i++;
-               if (i > CFG_MACB_RX_RING_SIZE)
-                       i = 0;
-       }
-
-       while (i < new_tail) {
-               macb->rx_ring[i].addr &= ~RXADDR_USED;
-               i++;
-       }
-
-       barrier();
-       macb->rx_tail = new_tail;
-}
-
-static int macb_recv(struct eth_device *netdev)
-{
-       struct macb_device *macb = to_macb(netdev);
-       unsigned int rx_tail = macb->rx_tail;
-       void *buffer;
-       int length;
-       int wrapped = 0;
-       u32 status;
-
-       for (;;) {
-               if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED))
-                       return -1;
-
-               status = macb->rx_ring[rx_tail].ctrl;
-               if (status & RXBUF_FRAME_START) {
-                       if (rx_tail != macb->rx_tail)
-                               reclaim_rx_buffers(macb, rx_tail);
-                       wrapped = 0;
-               }
-
-               if (status & RXBUF_FRAME_END) {
-                       buffer = macb->rx_buffer + 128 * macb->rx_tail;
-                       length = status & RXBUF_FRMLEN_MASK;
-                       if (wrapped) {
-                               unsigned int headlen, taillen;
-
-                               headlen = 128 * (CFG_MACB_RX_RING_SIZE
-                                                - macb->rx_tail);
-                               taillen = length - headlen;
-                               memcpy((void *)NetRxPackets[0],
-                                      buffer, headlen);
-                               memcpy((void *)NetRxPackets[0] + headlen,
-                                      macb->rx_buffer, taillen);
-                               buffer = (void *)NetRxPackets[0];
-                       }
-
-                       NetReceive(buffer, length);
-                       if (++rx_tail >= CFG_MACB_RX_RING_SIZE)
-                               rx_tail = 0;
-                       reclaim_rx_buffers(macb, rx_tail);
-               } else {
-                       if (++rx_tail >= CFG_MACB_RX_RING_SIZE) {
-                               wrapped = 1;
-                               rx_tail = 0;
-                       }
-               }
-               barrier();
-       }
-
-       return 0;
-}
-
-static void macb_phy_reset(struct macb_device *macb)
-{
-       struct eth_device *netdev = &macb->netdev;
-       int i;
-       u16 status, adv;
-
-       adv = ADVERTISE_CSMA | ADVERTISE_ALL;
-       macb_mdio_write(macb, MII_ADVERTISE, adv);
-       printf("%s: Starting autonegotiation...\n", netdev->name);
-       macb_mdio_write(macb, MII_BMCR, (BMCR_ANENABLE
-                                        | BMCR_ANRESTART));
-
-       for (i = 0; i < CFG_MACB_AUTONEG_TIMEOUT / 100; i++) {
-               status = macb_mdio_read(macb, MII_BMSR);
-               if (status & BMSR_ANEGCOMPLETE)
-                       break;
-               udelay(100);
-       }
-
-       if (status & BMSR_ANEGCOMPLETE)
-               printf("%s: Autonegotiation complete\n", netdev->name);
-       else
-               printf("%s: Autonegotiation timed out (status=0x%04x)\n",
-                      netdev->name, status);
-}
-
-static int macb_phy_init(struct macb_device *macb)
-{
-       struct eth_device *netdev = &macb->netdev;
-       u32 ncfgr;
-       u16 phy_id, status, adv, lpa;
-       int media, speed, duplex;
-       int i;
-
-       /* Check if the PHY is up to snuff... */
-       phy_id = macb_mdio_read(macb, MII_PHYSID1);
-       if (phy_id == 0xffff) {
-               printf("%s: No PHY present\n", netdev->name);
-               return 0;
-       }
-
-       status = macb_mdio_read(macb, MII_BMSR);
-       if (!(status & BMSR_LSTATUS)) {
-               /* Try to re-negotiate if we don't have link already. */
-               macb_phy_reset(macb);
-
-               for (i = 0; i < CFG_MACB_AUTONEG_TIMEOUT / 100; i++) {
-                       status = macb_mdio_read(macb, MII_BMSR);
-                       if (status & BMSR_LSTATUS)
-                               break;
-                       udelay(100);
-               }
-       }
-
-       if (!(status & BMSR_LSTATUS)) {
-               printf("%s: link down (status: 0x%04x)\n",
-                      netdev->name, status);
-               return 0;
-       } else {
-               adv = macb_mdio_read(macb, MII_ADVERTISE);
-               lpa = macb_mdio_read(macb, MII_LPA);
-               media = mii_nway_result(lpa & adv);
-               speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
-                        ? 1 : 0);
-               duplex = (media & ADVERTISE_FULL) ? 1 : 0;
-               printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n",
-                      netdev->name,
-                      speed ? "100" : "10",
-                      duplex ? "full" : "half",
-                      lpa);
-
-               ncfgr = macb_readl(macb, NCFGR);
-               ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
-               if (speed)
-                       ncfgr |= MACB_BIT(SPD);
-               if (duplex)
-                       ncfgr |= MACB_BIT(FD);
-               macb_writel(macb, NCFGR, ncfgr);
-               return 1;
-       }
-}
-
-static int macb_init(struct eth_device *netdev, bd_t *bd)
-{
-       struct macb_device *macb = to_macb(netdev);
-       unsigned long paddr;
-       u32 hwaddr_bottom;
-       u16 hwaddr_top;
-       int i;
-
-       /*
-        * macb_halt should have been called at some point before now,
-        * so we'll assume the controller is idle.
-        */
-
-       /* initialize DMA descriptors */
-       paddr = macb->rx_buffer_dma;
-       for (i = 0; i < CFG_MACB_RX_RING_SIZE; i++) {
-               if (i == (CFG_MACB_RX_RING_SIZE - 1))
-                       paddr |= RXADDR_WRAP;
-               macb->rx_ring[i].addr = paddr;
-               macb->rx_ring[i].ctrl = 0;
-               paddr += 128;
-       }
-       for (i = 0; i < CFG_MACB_TX_RING_SIZE; i++) {
-               macb->tx_ring[i].addr = 0;
-               if (i == (CFG_MACB_TX_RING_SIZE - 1))
-                       macb->tx_ring[i].ctrl = TXBUF_USED | TXBUF_WRAP;
-               else
-                       macb->tx_ring[i].ctrl = TXBUF_USED;
-       }
-       macb->rx_tail = macb->tx_head = macb->tx_tail = 0;
-
-       macb_writel(macb, RBQP, macb->rx_ring_dma);
-       macb_writel(macb, TBQP, macb->tx_ring_dma);
-
-       /* set hardware address */
-       hwaddr_bottom = cpu_to_le32(*((u32 *)netdev->enetaddr));
-       macb_writel(macb, SA1B, hwaddr_bottom);
-       hwaddr_top = cpu_to_le16(*((u16 *)(netdev->enetaddr + 4)));
-       macb_writel(macb, SA1T, hwaddr_top);
-
-       /* choose RMII or MII mode. This depends on the board */
-#ifdef CONFIG_RMII
-       macb_writel(macb, USRIO, 0);
-#else
-       macb_writel(macb, USRIO, MACB_BIT(MII));
-#endif
-
-       if (!macb_phy_init(macb))
-               return 0;
-
-       /* Enable TX and RX */
-       macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE));
-
-       return 1;
-}
-
-static void macb_halt(struct eth_device *netdev)
-{
-       struct macb_device *macb = to_macb(netdev);
-       u32 ncr, tsr;
-
-       /* Halt the controller and wait for any ongoing transmission to end. */
-       ncr = macb_readl(macb, NCR);
-       ncr |= MACB_BIT(THALT);
-       macb_writel(macb, NCR, ncr);
-
-       do {
-               tsr = macb_readl(macb, TSR);
-       } while (tsr & MACB_BIT(TGO));
-
-       /* Disable TX and RX, and clear statistics */
-       macb_writel(macb, NCR, MACB_BIT(CLRSTAT));
-}
-
-int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)
-{
-       struct macb_device *macb;
-       struct eth_device *netdev;
-       unsigned long macb_hz;
-       u32 ncfgr;
-
-       macb = malloc(sizeof(struct macb_device));
-       if (!macb) {
-               printf("Error: Failed to allocate memory for MACB%d\n", id);
-               return -1;
-       }
-       memset(macb, 0, sizeof(struct macb_device));
-
-       netdev = &macb->netdev;
-
-       macb->rx_buffer = dma_alloc_coherent(CFG_MACB_RX_BUFFER_SIZE,
-                                            &macb->rx_buffer_dma);
-       macb->rx_ring = dma_alloc_coherent(CFG_MACB_RX_RING_SIZE
-                                          * sizeof(struct macb_dma_desc),
-                                          &macb->rx_ring_dma);
-       macb->tx_ring = dma_alloc_coherent(CFG_MACB_TX_RING_SIZE
-                                          * sizeof(struct macb_dma_desc),
-                                          &macb->tx_ring_dma);
-
-       macb->regs = regs;
-       macb->phy_addr = phy_addr;
-
-       sprintf(netdev->name, "macb%d", id);
-       netdev->init = macb_init;
-       netdev->halt = macb_halt;
-       netdev->send = macb_send;
-       netdev->recv = macb_recv;
-
-       /*
-        * Do some basic initialization so that we at least can talk
-        * to the PHY
-        */
-       macb_hz = get_macb_pclk_rate(id);
-       if (macb_hz < 20000000)
-               ncfgr = MACB_BF(CLK, MACB_CLK_DIV8);
-       else if (macb_hz < 40000000)
-               ncfgr = MACB_BF(CLK, MACB_CLK_DIV16);
-       else if (macb_hz < 80000000)
-               ncfgr = MACB_BF(CLK, MACB_CLK_DIV32);
-       else
-               ncfgr = MACB_BF(CLK, MACB_CLK_DIV64);
-
-       macb_writel(macb, NCFGR, ncfgr);
-
-       eth_register(netdev);
-
-       return 0;
-}
-
-#endif
-
-#if defined(CONFIG_CMD_MII)
-
-int miiphy_read(unsigned char addr, unsigned char reg, unsigned short *value)
-{
-       unsigned long netctl;
-       unsigned long netstat;
-       unsigned long frame;
-       int iflag;
-
-       iflag = disable_interrupts();
-       netctl = macb_readl(&macb, EMACB_NCR);
-       netctl |= MACB_BIT(MPE);
-       macb_writel(&macb, EMACB_NCR, netctl);
-       if (iflag)
-               enable_interrupts();
-
-       frame = (MACB_BF(SOF, 1)
-                | MACB_BF(RW, 2)
-                | MACB_BF(PHYA, addr)
-                | MACB_BF(REGA, reg)
-                | MACB_BF(CODE, 2));
-       macb_writel(&macb, EMACB_MAN, frame);
-
-       do {
-               netstat = macb_readl(&macb, EMACB_NSR);
-       } while (!(netstat & MACB_BIT(IDLE)));
-
-       frame = macb_readl(&macb, EMACB_MAN);
-       *value = MACB_BFEXT(DATA, frame);
-
-       iflag = disable_interrupts();
-       netctl = macb_readl(&macb, EMACB_NCR);
-       netctl &= ~MACB_BIT(MPE);
-       macb_writel(&macb, EMACB_NCR, netctl);
-       if (iflag)
-               enable_interrupts();
-
-       return 0;
-}
-
-int miiphy_write(unsigned char addr, unsigned char reg, unsigned short value)
-{
-       unsigned long netctl;
-       unsigned long netstat;
-       unsigned long frame;
-       int iflag;
-
-       iflag = disable_interrupts();
-       netctl = macb_readl(&macb, EMACB_NCR);
-       netctl |= MACB_BIT(MPE);
-       macb_writel(&macb, EMACB_NCR, netctl);
-       if (iflag)
-               enable_interrupts();
-
-       frame = (MACB_BF(SOF, 1)
-                | MACB_BF(RW, 1)
-                | MACB_BF(PHYA, addr)
-                | MACB_BF(REGA, reg)
-                | MACB_BF(CODE, 2)
-                | MACB_BF(DATA, value));
-       macb_writel(&macb, EMACB_MAN, frame);
-
-       do {
-               netstat = macb_readl(&macb, EMACB_NSR);
-       } while (!(netstat & MACB_BIT(IDLE)));
-
-       iflag = disable_interrupts();
-       netctl = macb_readl(&macb, EMACB_NCR);
-       netctl &= ~MACB_BIT(MPE);
-       macb_writel(&macb, EMACB_NCR, netctl);
-       if (iflag)
-               enable_interrupts();
-
-       return 0;
-}
-
-#endif
-
-#endif /* CONFIG_MACB */
diff --git a/drivers/macb.h b/drivers/macb.h
deleted file mode 100644 (file)
index c778e4e..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Atmel Corporation
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-#ifndef __DRIVERS_MACB_H__
-#define __DRIVERS_MACB_H__
-
-/* MACB register offsets */
-#define MACB_NCR                               0x0000
-#define MACB_NCFGR                             0x0004
-#define MACB_NSR                               0x0008
-#define MACB_TSR                               0x0014
-#define MACB_RBQP                              0x0018
-#define MACB_TBQP                              0x001c
-#define MACB_RSR                               0x0020
-#define MACB_ISR                               0x0024
-#define MACB_IER                               0x0028
-#define MACB_IDR                               0x002c
-#define MACB_IMR                               0x0030
-#define MACB_MAN                               0x0034
-#define MACB_PTR                               0x0038
-#define MACB_PFR                               0x003c
-#define MACB_FTO                               0x0040
-#define MACB_SCF                               0x0044
-#define MACB_MCF                               0x0048
-#define MACB_FRO                               0x004c
-#define MACB_FCSE                              0x0050
-#define MACB_ALE                               0x0054
-#define MACB_DTF                               0x0058
-#define MACB_LCOL                              0x005c
-#define MACB_EXCOL                             0x0060
-#define MACB_TUND                              0x0064
-#define MACB_CSE                               0x0068
-#define MACB_RRE                               0x006c
-#define MACB_ROVR                              0x0070
-#define MACB_RSE                               0x0074
-#define MACB_ELE                               0x0078
-#define MACB_RJA                               0x007c
-#define MACB_USF                               0x0080
-#define MACB_STE                               0x0084
-#define MACB_RLE                               0x0088
-#define MACB_TPF                               0x008c
-#define MACB_HRB                               0x0090
-#define MACB_HRT                               0x0094
-#define MACB_SA1B                              0x0098
-#define MACB_SA1T                              0x009c
-#define MACB_SA2B                              0x00a0
-#define MACB_SA2T                              0x00a4
-#define MACB_SA3B                              0x00a8
-#define MACB_SA3T                              0x00ac
-#define MACB_SA4B                              0x00b0
-#define MACB_SA4T                              0x00b4
-#define MACB_TID                               0x00b8
-#define MACB_TPQ                               0x00bc
-#define MACB_USRIO                             0x00c0
-#define MACB_WOL                               0x00c4
-
-/* Bitfields in NCR */
-#define MACB_LB_OFFSET                         0
-#define MACB_LB_SIZE                           1
-#define MACB_LLB_OFFSET                                1
-#define MACB_LLB_SIZE                          1
-#define MACB_RE_OFFSET                         2
-#define MACB_RE_SIZE                           1
-#define MACB_TE_OFFSET                         3
-#define MACB_TE_SIZE                           1
-#define MACB_MPE_OFFSET                                4
-#define MACB_MPE_SIZE                          1
-#define MACB_CLRSTAT_OFFSET                    5
-#define MACB_CLRSTAT_SIZE                      1
-#define MACB_INCSTAT_OFFSET                    6
-#define MACB_INCSTAT_SIZE                      1
-#define MACB_WESTAT_OFFSET                     7
-#define MACB_WESTAT_SIZE                       1
-#define MACB_BP_OFFSET                         8
-#define MACB_BP_SIZE                           1
-#define MACB_TSTART_OFFSET                     9
-#define MACB_TSTART_SIZE                       1
-#define MACB_THALT_OFFSET                      10
-#define MACB_THALT_SIZE                                1
-#define MACB_NCR_TPF_OFFSET                    11
-#define MACB_NCR_TPF_SIZE                      1
-#define MACB_TZQ_OFFSET                                12
-#define MACB_TZQ_SIZE                          1
-
-/* Bitfields in NCFGR */
-#define MACB_SPD_OFFSET                                0
-#define MACB_SPD_SIZE                          1
-#define MACB_FD_OFFSET                         1
-#define MACB_FD_SIZE                           1
-#define MACB_BIT_RATE_OFFSET                   2
-#define MACB_BIT_RATE_SIZE                     1
-#define MACB_JFRAME_OFFSET                     3
-#define MACB_JFRAME_SIZE                       1
-#define MACB_CAF_OFFSET                                4
-#define MACB_CAF_SIZE                          1
-#define MACB_NBC_OFFSET                                5
-#define MACB_NBC_SIZE                          1
-#define MACB_NCFGR_MTI_OFFSET                  6
-#define MACB_NCFGR_MTI_SIZE                    1
-#define MACB_UNI_OFFSET                                7
-#define MACB_UNI_SIZE                          1
-#define MACB_BIG_OFFSET                                8
-#define MACB_BIG_SIZE                          1
-#define MACB_EAE_OFFSET                                9
-#define MACB_EAE_SIZE                          1
-#define MACB_CLK_OFFSET                                10
-#define MACB_CLK_SIZE                          2
-#define MACB_RTY_OFFSET                                12
-#define MACB_RTY_SIZE                          1
-#define MACB_PAE_OFFSET                                13
-#define MACB_PAE_SIZE                          1
-#define MACB_RBOF_OFFSET                       14
-#define MACB_RBOF_SIZE                         2
-#define MACB_RLCE_OFFSET                       16
-#define MACB_RLCE_SIZE                         1
-#define MACB_DRFCS_OFFSET                      17
-#define MACB_DRFCS_SIZE                                1
-#define MACB_EFRHD_OFFSET                      18
-#define MACB_EFRHD_SIZE                                1
-#define MACB_IRXFCS_OFFSET                     19
-#define MACB_IRXFCS_SIZE                       1
-
-/* Bitfields in NSR */
-#define MACB_NSR_LINK_OFFSET                   0
-#define MACB_NSR_LINK_SIZE                     1
-#define MACB_MDIO_OFFSET                       1
-#define MACB_MDIO_SIZE                         1
-#define MACB_IDLE_OFFSET                       2
-#define MACB_IDLE_SIZE                         1
-
-/* Bitfields in TSR */
-#define MACB_UBR_OFFSET                                0
-#define MACB_UBR_SIZE                          1
-#define MACB_COL_OFFSET                                1
-#define MACB_COL_SIZE                          1
-#define MACB_TSR_RLE_OFFSET                    2
-#define MACB_TSR_RLE_SIZE                      1
-#define MACB_TGO_OFFSET                                3
-#define MACB_TGO_SIZE                          1
-#define MACB_BEX_OFFSET                                4
-#define MACB_BEX_SIZE                          1
-#define MACB_COMP_OFFSET                       5
-#define MACB_COMP_SIZE                         1
-#define MACB_UND_OFFSET                                6
-#define MACB_UND_SIZE                          1
-
-/* Bitfields in RSR */
-#define MACB_BNA_OFFSET                                0
-#define MACB_BNA_SIZE                          1
-#define MACB_REC_OFFSET                                1
-#define MACB_REC_SIZE                          1
-#define MACB_OVR_OFFSET                                2
-#define MACB_OVR_SIZE                          1
-
-/* Bitfields in ISR/IER/IDR/IMR */
-#define MACB_MFD_OFFSET                                0
-#define MACB_MFD_SIZE                          1
-#define MACB_RCOMP_OFFSET                      1
-#define MACB_RCOMP_SIZE                                1
-#define MACB_RXUBR_OFFSET                      2
-#define MACB_RXUBR_SIZE                                1
-#define MACB_TXUBR_OFFSET                      3
-#define MACB_TXUBR_SIZE                                1
-#define MACB_ISR_TUND_OFFSET                   4
-#define MACB_ISR_TUND_SIZE                     1
-#define MACB_ISR_RLE_OFFSET                    5
-#define MACB_ISR_RLE_SIZE                      1
-#define MACB_TXERR_OFFSET                      6
-#define MACB_TXERR_SIZE                                1
-#define MACB_TCOMP_OFFSET                      7
-#define MACB_TCOMP_SIZE                                1
-#define MACB_ISR_LINK_OFFSET                   9
-#define MACB_ISR_LINK_SIZE                     1
-#define MACB_ISR_ROVR_OFFSET                   10
-#define MACB_ISR_ROVR_SIZE                     1
-#define MACB_HRESP_OFFSET                      11
-#define MACB_HRESP_SIZE                                1
-#define MACB_PFR_OFFSET                                12
-#define MACB_PFR_SIZE                          1
-#define MACB_PTZ_OFFSET                                13
-#define MACB_PTZ_SIZE                          1
-
-/* Bitfields in MAN */
-#define MACB_DATA_OFFSET                       0
-#define MACB_DATA_SIZE                         16
-#define MACB_CODE_OFFSET                       16
-#define MACB_CODE_SIZE                         2
-#define MACB_REGA_OFFSET                       18
-#define MACB_REGA_SIZE                         5
-#define MACB_PHYA_OFFSET                       23
-#define MACB_PHYA_SIZE                         5
-#define MACB_RW_OFFSET                         28
-#define MACB_RW_SIZE                           2
-#define MACB_SOF_OFFSET                                30
-#define MACB_SOF_SIZE                          2
-
-/* Bitfields in USRIO */
-#define MACB_MII_OFFSET                                0
-#define MACB_MII_SIZE                          1
-#define MACB_EAM_OFFSET                                1
-#define MACB_EAM_SIZE                          1
-#define MACB_TX_PAUSE_OFFSET                   2
-#define MACB_TX_PAUSE_SIZE                     1
-#define MACB_TX_PAUSE_ZERO_OFFSET              3
-#define MACB_TX_PAUSE_ZERO_SIZE                        1
-
-/* Bitfields in WOL */
-#define MACB_IP_OFFSET                         0
-#define MACB_IP_SIZE                           16
-#define MACB_MAG_OFFSET                                16
-#define MACB_MAG_SIZE                          1
-#define MACB_ARP_OFFSET                                17
-#define MACB_ARP_SIZE                          1
-#define MACB_SA1_OFFSET                                18
-#define MACB_SA1_SIZE                          1
-#define MACB_WOL_MTI_OFFSET                    19
-#define MACB_WOL_MTI_SIZE                      1
-
-/* Constants for CLK */
-#define MACB_CLK_DIV8                          0
-#define MACB_CLK_DIV16                         1
-#define MACB_CLK_DIV32                         2
-#define MACB_CLK_DIV64                         3
-
-/* Constants for MAN register */
-#define MACB_MAN_SOF                           1
-#define MACB_MAN_WRITE                         1
-#define MACB_MAN_READ                          2
-#define MACB_MAN_CODE                          2
-
-/* Bit manipulation macros */
-#define MACB_BIT(name)                                 \
-       (1 << MACB_##name##_OFFSET)
-#define MACB_BF(name,value)                            \
-       (((value) & ((1 << MACB_##name##_SIZE) - 1))    \
-        << MACB_##name##_OFFSET)
-#define MACB_BFEXT(name,value)\
-       (((value) >> MACB_##name##_OFFSET)              \
-        & ((1 << MACB_##name##_SIZE) - 1))
-#define MACB_BFINS(name,value,old)                     \
-       (((old) & ~(((1 << MACB_##name##_SIZE) - 1)     \
-                   << MACB_##name##_OFFSET))           \
-        | MACB_BF(name,value))
-
-/* Register access macros */
-#define macb_readl(port,reg)                           \
-       readl((port)->regs + MACB_##reg)
-#define macb_writel(port,reg,value)                    \
-       writel((value), (port)->regs + MACB_##reg)
-
-#endif /* __DRIVERS_MACB_H__ */
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
new file mode 100644 (file)
index 0000000..78cec21
--- /dev/null
@@ -0,0 +1,48 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libmisc.a
+
+COBJS-y += ali512x.o
+COBJS-y += ns87308.o
+COBJS-y += status_led.o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/misc/ali512x.c b/drivers/misc/ali512x.c
new file mode 100644 (file)
index 0000000..7b7edc0
--- /dev/null
@@ -0,0 +1,423 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Based on sc520cdp.c from rolo 1.6:
+ *----------------------------------------------------------------------
+ * (C) Copyright 2000
+ * Sysgo Real-Time Solutions GmbH
+ * Klein-Winternheim, Germany
+ *----------------------------------------------------------------------
+ */
+
+#include <config.h>
+
+#ifdef CONFIG_ALI152X
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/ic/ali512x.h>
+
+
+/* ALI M5123 Logical device numbers:
+ * 0 FDC
+ * 1 unused?
+ * 2 unused?
+ * 3 lpt
+ * 4 UART1
+ * 5 UART2
+ * 6 RTC
+ * 7 mouse/kbd
+ * 8 CIO
+ */
+
+/*
+ ************************************************************
+ *  Some access primitives for the ALi chip:                *
+ ************************************************************
+ */
+
+static void ali_write(u8 index, u8 value)
+{
+       /* write an arbirary register */
+       outb(index, ALI_INDEX);
+       outb(value, ALI_DATA);
+}
+
+#if 0
+static int ali_read(u8 index)
+{
+       outb(index, ALI_INDEX);
+       return inb(ALI_DATA);
+}
+#endif
+
+#define ALI_OPEN() \
+       outb(0x51, ALI_INDEX); \
+       outb(0x23, ALI_INDEX)
+
+
+#define ALI_CLOSE() \
+       outb(0xbb, ALI_INDEX)
+
+/* Select a logical device */
+#define ALI_SELDEV(dev)        \
+       ali_write(0x07, dev)
+
+
+void ali512x_init(void)
+{
+       ALI_OPEN();
+
+       ali_write(0x02, 0x01);  /* soft reset */
+       ali_write(0x03, 0x03);  /* disable access to CIOs */
+       ali_write(0x22, 0x00);  /* disable direct powerdown */
+       ali_write(0x23, 0x00);  /* disable auto powerdown */
+       ali_write(0x24, 0x00);  /* IR 8 is active hi, pin26 is PDIR */
+
+       ALI_CLOSE();
+}
+
+void ali512x_set_fdc(int enabled, u16 io, u8 irq, u8 dma_channel)
+{
+       ALI_OPEN();
+       ALI_SELDEV(0);
+
+       ali_write(0x30, enabled?1:0);
+       if (enabled) {
+               ali_write(0x60, io >> 8);
+               ali_write(0x61, io & 0xff);
+               ali_write(0x70, irq);
+               ali_write(0x74, dma_channel);
+
+               /* AT mode, no drive swap */
+               ali_write(0xf0, 0x08);
+               ali_write(0xf1, 0x00);
+               ali_write(0xf2, 0xff);
+               ali_write(0xf4, 0x00);
+       }
+       ALI_CLOSE();
+}
+
+
+void ali512x_set_pp(int enabled, u16 io, u8 irq, u8 dma_channel)
+{
+       ALI_OPEN();
+       ALI_SELDEV(3);
+
+       ali_write(0x30, enabled?1:0);
+       if (enabled) {
+               ali_write(0x60, io >> 8);
+               ali_write(0x61, io & 0xff);
+               ali_write(0x70, irq);
+               ali_write(0x74, dma_channel);
+
+               /* mode: EPP 1.9, ECP FIFO threshold = 7, IRQ active low */
+               ali_write(0xf0, 0xbc);
+               /* 12 MHz, Burst DMA in ECP */
+               ali_write(0xf1, 0x05);
+       }
+       ALI_CLOSE();
+
+}
+
+void ali512x_set_uart(int enabled, int index, u16 io, u8 irq)
+{
+       ALI_OPEN();
+       ALI_SELDEV(index?5:4);
+
+       ali_write(0x30, enabled?1:0);
+       if (enabled) {
+               ali_write(0x60, io >> 8);
+               ali_write(0x61, io & 0xff);
+               ali_write(0x70, irq);
+
+               ali_write(0xf0, 0x00);
+               ali_write(0xf1, 0x00);
+
+               /* huh? write 0xf2 twice - a typo in rolo
+                * or some secret ali errata? Who knows?
+                */
+               if (index) {
+                       ali_write(0xf2, 0x00);
+               }
+               ali_write(0xf2, 0x0c);
+       }
+       ALI_CLOSE();
+
+}
+
+void ali512x_set_uart2_irda(int enabled)
+{
+       ALI_OPEN();
+       ALI_SELDEV(5);
+
+       ali_write(0xf1, enabled?0x48:0x00); /* fullduplex IrDa */
+       ALI_CLOSE();
+
+}
+
+void ali512x_set_rtc(int enabled, u16 io, u8 irq)
+{
+       ALI_OPEN();
+       ALI_SELDEV(6);
+
+       ali_write(0x30, enabled?1:0);
+       if (enabled) {
+               ali_write(0x60, io >> 8);
+               ali_write(0x61, io & 0xff);
+               ali_write(0x70, irq);
+
+               ali_write(0xf0, 0x00);
+       }
+       ALI_CLOSE();
+}
+
+void ali512x_set_kbc(int enabled, u8 kbc_irq, u8 mouse_irq)
+{
+       ALI_OPEN();
+       ALI_SELDEV(7);
+
+       ali_write(0x30, enabled?1:0);
+       if (enabled) {
+               ali_write(0x70, kbc_irq);
+               ali_write(0x72, mouse_irq);
+
+               ali_write(0xf0, 0x00);
+       }
+       ALI_CLOSE();
+}
+
+
+/* Common I/O
+ *
+ * (This descripotsion is base on several incompete sources
+ *  since I have not been able to obtain any datasheet for the device
+ *  there may be some mis-understandings burried in here.
+ *  -- Daniel daniel@omicron.se)
+ *
+ * There are 22 CIO pins numbered
+ * 10-17
+ * 20-25
+ * 30-37
+ *
+ * 20-24 are dedicated CIO pins, the other 17 are muliplexed with
+ * other functions.
+ *
+ *           Secondary
+ * CIO Pin   Function    Decription
+ * =======================================================
+ * CIO10     IRQIN1      Interrupt input 1?
+ * CIO11     IRQIN2      Interrupt input 2?
+ * CIO12     IRRX        IrDa Receive
+ * CIO13     IRTX        IrDa Transmit
+ * CIO14     P21         KBC P21 fucntion
+ * CIO15     P20         KBC P21 fucntion
+ * CIO16     I2C_CLK     I2C Clock
+ * CIO17     I2C_DAT     I2C Data
+ *
+ * CIO20     -
+ * CIO21     -
+ * CIO22     -
+ * CIO23     -
+ * CIO24     -
+ * CIO25     LOCK        Keylock
+ *
+ * CIO30     KBC_CLK     Keybaord Clock
+ * CIO31     CS0J        General Chip Select decoder CS0J
+ * CIO32     CS1J        General Chip Select decoder CS1J
+ * CIO33     ALT_KCLK    Alternative Keyboard Clock
+ * CIO34     ALT_KDAT    Alternative Keyboard Data
+ * CIO35     ALT_MCLK    Alternative Mouse Clock
+ * CIO36     ALT_MDAT    Alternative Mouse Data
+ * CIO37     ALT_KBC     Alternative KBC select
+ *
+ * The CIO use an indirect address scheme.
+ *
+ * Reigster 3 in the SIO is used to select the index and data
+ * port addresses where the CIO I/O registers show up.
+ * The function selection registers are accessible under
+ * function SIO 8.
+ *
+ * SIO reigster 3 (CIO Address Selection) bit definitions:
+ * bit 7   CIO index and data registers enabled
+ * bit 1-0 CIO indirect registers port address select
+ *              0  index = 0xE0 data = 0xE1
+ *       1  index = 0xE2 data = 0xE3
+ *       2  index = 0xE4 data = 0xE5
+ *       3  index = 0xEA data = 0xEB
+ *
+ * There are three CIO I/O register accessed via CIO index port and CIO data port
+ * 0x01     CIO 10-17 data
+ * 0x02     CIO 20-25 data (bits 7-6 unused)
+ * 0x03     CIO 30-37 data
+ *
+ *
+ * The pin function is accessed through normal
+ * SIO registers, each register have the same format:
+ *
+ * Bit   Function                     Value
+ * 0     Input/output                 1=input
+ * 1     Polarity of signal           1=inverted
+ * 2     Unused                       ??
+ * 3     Function (normal or special) 1=special
+ * 7-4   Unused
+ *
+ * SIO REG
+ * 0xe0     CIO 10 Config
+ * 0xe1     CIO 11 Config
+ * 0xe2     CIO 12 Config
+ * 0xe3     CIO 13 Config
+ * 0xe4     CIO 14 Config
+ * 0xe5     CIO 15 Config
+ * 0xe6     CIO 16 Config
+ * 0xe7     CIO 16 Config
+ *
+ * 0xe8     CIO 20 Config
+ * 0xe9     CIO 21 Config
+ * 0xea     CIO 22 Config
+ * 0xeb     CIO 23 Config
+ * 0xec     CIO 24 Config
+ * 0xed     CIO 25 Config
+ *
+ * 0xf5     CIO 30 Config
+ * 0xf6     CIO 31 Config
+ * 0xf7     CIO 32 Config
+ * 0xf8     CIO 33 Config
+ * 0xf9     CIO 34 Config
+ * 0xfa     CIO 35 Config
+ * 0xfb     CIO 36 Config
+ * 0xfc     CIO 37 Config
+ *
+ */
+
+#define ALI_CIO_PORT_SEL 0x83
+#define ALI_CIO_INDEX    0xea
+#define ALI_CIO_DATA     0xeb
+
+void ali512x_set_cio(int enabled)
+{
+       int i;
+
+       ALI_OPEN();
+
+       if (enabled) {
+               ali_write(0x3, ALI_CIO_PORT_SEL);    /* Enable CIO data register */
+       } else {
+               ali_write(0x3, ALI_CIO_PORT_SEL & ~0x80);
+       }
+
+       ALI_SELDEV(8);
+
+       ali_write(0x30, enabled?1:0);
+
+       /* set all pins to input to start with */
+       for (i=0xe0;i<0xee;i++) {
+               ali_write(i, 1);
+       }
+
+       for (i=0xf5;i<0xfe;i++) {
+               ali_write(i, 1);
+       }
+
+       ALI_CLOSE();
+}
+
+
+void ali512x_cio_function(int pin, int special, int inv, int input)
+{
+       u8 data;
+       u8 addr;
+
+       /* valid pins are 10-17, 20-25 and 30-37 */
+       if (pin >= 10 && pin <= 17) {
+               addr = 0xe0+(pin&7);
+       } else if (pin >= 20 && pin <= 25) {
+               addr = 0xe8+(pin&7);
+       } else if (pin >= 30 && pin <= 37) {
+               addr = 0xf5+(pin&7);
+       } else {
+               return;
+       }
+
+       ALI_OPEN();
+
+       ALI_SELDEV(8);
+
+
+       data=0xf4;
+       if (special) {
+               data |= 0x08;
+       } else {
+               if (inv) {
+                       data |= 0x02;
+               }
+               if (input) {
+                       data |= 0x01;
+               }
+       }
+
+       ali_write(addr, data);
+
+       ALI_CLOSE();
+}
+
+void ali512x_cio_out(int pin, int value)
+{
+       u8 reg;
+       u8 data;
+       u8 bit;
+
+       reg = pin/10;
+       bit = 1 << (pin%10);
+
+
+       outb(reg, ALI_CIO_INDEX);     /* select I/O register */
+       data = inb(ALI_CIO_DATA);
+       if (value) {
+               data |= bit;
+       } else {
+               data &= ~bit;
+       }
+       outb(data, ALI_CIO_DATA);
+}
+
+int ali512x_cio_in(int pin)
+{
+       u8 reg;
+       u8 data;
+       u8 bit;
+
+       /* valid pins are 10-17, 20-25 and 30-37 */
+       reg = pin/10;
+       bit = 1 << (pin%10);
+
+
+       outb(reg, ALI_CIO_INDEX);     /* select I/O register */
+       data = inb(ALI_CIO_DATA);
+
+       return data & bit;
+}
+
+
+#endif
diff --git a/drivers/misc/ns87308.c b/drivers/misc/ns87308.c
new file mode 100644 (file)
index 0000000..cf4d359
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+
+#ifdef CFG_NS87308
+
+#include <ns87308.h>
+
+void initialise_ns87308 (void)
+{
+#ifdef CFG_NS87308_PS2MOD
+       unsigned char data;
+
+       /*
+        * Switch floppy drive to PS/2 mode.
+        */
+       read_pnp_config(SUPOERIO_CONF1, &data);
+       data &= 0xFB;
+       write_pnp_config(SUPOERIO_CONF1, data);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_KBC1)
+       PNP_SET_DEVICE_BASE(LDEV_KBC1, CFG_NS87308_KBC1_BASE);
+       write_pnp_config(LUN_CONFIG_REG, 0);
+       write_pnp_config(CBASE_HIGH, 0x00);
+       write_pnp_config(CBASE_LOW, 0x64);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_MOUSE)
+       PNP_ACTIVATE_DEVICE(LDEV_MOUSE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_RTC_APC)
+       PNP_SET_DEVICE_BASE(LDEV_RTC_APC, CFG_NS87308_RTC_BASE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_FDC)
+       PNP_SET_DEVICE_BASE(LDEV_FDC, CFG_NS87308_FDC_BASE);
+       write_pnp_config(LUN_CONFIG_REG, 0x40);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_RARP)
+       PNP_SET_DEVICE_BASE(LDEV_PARP, CFG_NS87308_LPT_BASE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_UART1)
+       PNP_SET_DEVICE_BASE(LDEV_UART1, CFG_NS87308_UART1_BASE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_UART2)
+       PNP_SET_DEVICE_BASE(LDEV_UART2, CFG_NS87308_UART2_BASE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_GPIO)
+       PNP_SET_DEVICE_BASE(LDEV_GPIO, CFG_NS87308_GPIO_BASE);
+#endif
+
+#if (CFG_NS87308_DEVS & CFG_NS87308_POWRMAN)
+#ifndef CFG_NS87308_PWMAN_BASE
+       PNP_ACTIVATE_DEVICE(LDEV_POWRMAN);
+#else
+       PNP_SET_DEVICE_BASE(LDEV_POWRMAN, CFG_NS87308_PWMAN_BASE);
+
+       /*
+        * Enable all units
+        */
+       write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_FER1, 0x7d);
+       write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_FER2, 0x87);
+
+#ifdef CFG_NS87308_PMC1
+       write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_PMC1, CFG_NS87308_PMC1);
+#endif
+
+#ifdef CFG_NS87308_PMC2
+       write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_PMC2, CFG_NS87308_PMC2);
+#endif
+
+#ifdef CFG_NS87308_PMC3
+       write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_PMC3, CFG_NS87308_PMC3);
+#endif
+#endif
+#endif
+
+#ifdef CFG_NS87308_CS0_BASE
+       PNP_PGCS_CSLINE_BASE(0, CFG_NS87308_CS0_BASE);
+       PNP_PGCS_CSLINE_CONF(0, CFG_NS87308_CS0_CONF);
+#endif
+
+#ifdef CFG_NS87308_CS1_BASE
+       PNP_PGCS_CSLINE_BASE(1, CFG_NS87308_CS1_BASE);
+       PNP_PGCS_CSLINE_CONF(1, CFG_NS87308_CS1_CONF);
+#endif
+
+#ifdef CFG_NS87308_CS2_BASE
+       PNP_PGCS_CSLINE_BASE(2, CFG_NS87308_CS2_BASE);
+       PNP_PGCS_CSLINE_CONF(2, CFG_NS87308_CS2_CONF);
+#endif
+}
+
+#endif
diff --git a/drivers/misc/status_led.c b/drivers/misc/status_led.c
new file mode 100644 (file)
index 0000000..ddb6c22
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * (C) Copyright 2000-2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <status_led.h>
+
+/*
+ * The purpose of this code is to signal the operational status of a
+ * target which usually boots over the network; while running in
+ * U-Boot, a status LED is blinking. As soon as a valid BOOTP reply
+ * message has been received, the LED is turned off. The Linux
+ * kernel, once it is running, will start blinking the LED again,
+ * with another frequency.
+ */
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_STATUS_LED
+
+typedef struct {
+       led_id_t mask;
+       int state;
+       int period;
+       int cnt;
+} led_dev_t;
+
+led_dev_t led_dev[] = {
+    {  STATUS_LED_BIT,
+       STATUS_LED_STATE,
+       STATUS_LED_PERIOD,
+       0,
+    },
+#if defined(STATUS_LED_BIT1)
+    {  STATUS_LED_BIT1,
+       STATUS_LED_STATE1,
+       STATUS_LED_PERIOD1,
+       0,
+    },
+#endif
+#if defined(STATUS_LED_BIT2)
+    {  STATUS_LED_BIT2,
+       STATUS_LED_STATE2,
+       STATUS_LED_PERIOD2,
+       0,
+    },
+#endif
+#if defined(STATUS_LED_BIT3)
+    {  STATUS_LED_BIT3,
+       STATUS_LED_STATE3,
+       STATUS_LED_PERIOD3,
+       0,
+    },
+#endif
+};
+
+#define MAX_LED_DEV    (sizeof(led_dev)/sizeof(led_dev_t))
+
+static int status_led_init_done = 0;
+
+static void status_led_init (void)
+{
+       led_dev_t *ld;
+       int i;
+
+       for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++)
+               __led_init (ld->mask, ld->state);
+       status_led_init_done = 1;
+}
+
+void status_led_tick (ulong timestamp)
+{
+       led_dev_t *ld;
+       int i;
+
+       if (!status_led_init_done)
+               status_led_init ();
+
+       for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++) {
+
+               if (ld->state != STATUS_LED_BLINKING)
+                       continue;
+
+               if (++ld->cnt >= ld->period) {
+                       __led_toggle (ld->mask);
+                       ld->cnt -= ld->period;
+               }
+
+       }
+}
+
+void status_led_set (int led, int state)
+{
+       led_dev_t *ld;
+
+       if (led < 0 || led >= MAX_LED_DEV)
+               return;
+
+       if (!status_led_init_done)
+               status_led_init ();
+
+       ld = &led_dev[led];
+
+       ld->state = state;
+       if (state == STATUS_LED_BLINKING) {
+               ld->cnt = 0;            /* always start with full period    */
+               state = STATUS_LED_ON;  /* always start with LED _ON_       */
+       }
+       __led_set (ld->mask, state);
+}
+
+#endif /* CONFIG_STATUS_LED */
diff --git a/drivers/mpc8xx_pcmcia.c b/drivers/mpc8xx_pcmcia.c
deleted file mode 100644 (file)
index 8a34cd3..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-#include <common.h>
-#if defined(CONFIG_8xx)
-#include <mpc8xx.h>
-#endif
-#include <pcmcia.h>
-
-#undef CONFIG_PCMCIA
-
-#if defined(CONFIG_CMD_PCMCIA)
-#define        CONFIG_PCMCIA
-#endif
-
-#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
-#define        CONFIG_PCMCIA
-#endif
-
-#if defined(CONFIG_8xx)        && defined(CONFIG_PCMCIA)
-
-#if    defined(CONFIG_IDE_8xx_PCCARD)
-extern int check_ide_device (int slot);
-#endif
-
-extern int pcmcia_hardware_enable (int slot);
-extern int pcmcia_voltage_set(int slot, int vcc, int vpp);
-
-#if defined(CONFIG_CMD_PCMCIA)
-extern int pcmcia_hardware_disable(int slot);
-#endif
-
-static u_int m8xx_get_graycode(u_int size);
-#if 0 /* Disabled */
-static u_int m8xx_get_speed(u_int ns, u_int is_io);
-#endif
-
-/* look up table for pgcrx registers */
-u_int *pcmcia_pgcrx[2] = {
-       &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
-       &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
-};
-
-/*
- * Search this table to see if the windowsize is
- * supported...
- */
-
-#define M8XX_SIZES_NO 32
-
-static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
-{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
-  0x00000080, 0x00000040, 0x00000010, 0x00000020,
-  0x00008000, 0x00004000, 0x00001000, 0x00002000,
-  0x00000100, 0x00000200, 0x00000800, 0x00000400,
-
-  0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-  0x01000000, 0x02000000, 0xffffffff, 0x04000000,
-  0x00010000, 0x00020000, 0x00080000, 0x00040000,
-  0x00800000, 0x00400000, 0x00100000, 0x00200000 };
-
-
-/* -------------------------------------------------------------------- */
-
-#ifdef CONFIG_HMI10
-#define        HMI10_FRAM_TIMING       (       PCMCIA_SHT(2)   \
-                               |       PCMCIA_SST(2)   \
-                               |       PCMCIA_SL(4))
-#endif
-
-#if    defined(CONFIG_LWMON) || defined(CONFIG_NSCU)
-#define        CFG_PCMCIA_TIMING       (       PCMCIA_SHT(9)   \
-                               |       PCMCIA_SST(3)   \
-                               |       PCMCIA_SL(12))
-#else
-#define        CFG_PCMCIA_TIMING       (       PCMCIA_SHT(2)   \
-                               |       PCMCIA_SST(4)   \
-                               |       PCMCIA_SL(9))
-#endif
-
-/* -------------------------------------------------------------------- */
-
-int pcmcia_on (void)
-{
-       u_long reg, base;
-       pcmcia_win_t *win;
-       u_int slotbit;
-       u_int rc, slot;
-       int i;
-
-       debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
-
-       /* intialize the fixed memory windows */
-       win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
-       base = CFG_PCMCIA_MEM_ADDR;
-
-       if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
-               printf ("Cannot set window size to 0x%08x\n",
-                       CFG_PCMCIA_MEM_SIZE);
-               return (1);
-       }
-
-       slotbit = PCMCIA_SLOT_x;
-       for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
-               win->br = base;
-
-#if    (PCMCIA_SOCKETS_NO == 2)
-               if (i == 4) /* Another slot starting from win 4 */
-                       slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
-#endif
-               switch (i) {
-#ifdef CONFIG_IDE_8xx_PCCARD
-               case 4:
-#ifdef CONFIG_HMI10
-               {       /* map FRAM area */
-                       win->or = (     PCMCIA_BSIZE_256K
-                               |       PCMCIA_PPS_8
-                               |       PCMCIA_PRS_ATTR
-                               |       slotbit
-                               |       PCMCIA_PV
-                               |       HMI10_FRAM_TIMING );
-                       break;
-               }
-#endif
-               case 0: {       /* map attribute memory */
-                       win->or = (     PCMCIA_BSIZE_64M
-                               |       PCMCIA_PPS_8
-                               |       PCMCIA_PRS_ATTR
-                               |       slotbit
-                               |       PCMCIA_PV
-                               |       CFG_PCMCIA_TIMING );
-                       break;
-               }
-               case 5:
-               case 1: {       /* map I/O window for data reg */
-                       win->or = (     PCMCIA_BSIZE_1K
-                               |       PCMCIA_PPS_16
-                               |       PCMCIA_PRS_IO
-                               |       slotbit
-                               |       PCMCIA_PV
-                               |       CFG_PCMCIA_TIMING );
-                       break;
-               }
-               case 6:
-               case 2: {       /* map I/O window for cmd/ctrl reg block */
-                       win->or = (     PCMCIA_BSIZE_1K
-                               |       PCMCIA_PPS_8
-                               |       PCMCIA_PRS_IO
-                               |       slotbit
-                               |       PCMCIA_PV
-                               |       CFG_PCMCIA_TIMING );
-                       break;
-               }
-#endif /* CONFIG_IDE_8xx_PCCARD */
-#ifdef CONFIG_HMI10
-               case 3: {       /* map I/O window for 4xUART data/ctrl */
-                       win->br += 0x40000;
-                       win->or = (     PCMCIA_BSIZE_256K
-                               |       PCMCIA_PPS_8
-                               |       PCMCIA_PRS_IO
-                               |       slotbit
-                               |       PCMCIA_PV
-                               |       CFG_PCMCIA_TIMING );
-                       break;
-               }
-#endif /* CONFIG_HMI10 */
-               default:        /* set to not valid */
-                       win->or = 0;
-                       break;
-               }
-
-               debug ("MemWin %d: PBR 0x%08lX  POR %08lX\n",
-                      i, win->br, win->or);
-               base += CFG_PCMCIA_MEM_SIZE;
-               ++win;
-       }
-
-       for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
-               /* turn off voltage */
-               if ((rc = pcmcia_voltage_set(slot, 0, 0)))
-                       continue;
-
-               /* Enable external hardware */
-               if ((rc = pcmcia_hardware_enable(slot)))
-                       continue;
-
-#ifdef CONFIG_IDE_8xx_PCCARD
-               if ((rc = check_ide_device(i)))
-                       continue;
-#endif
-       }
-       return rc;
-}
-
-#if defined(CONFIG_CMD_PCMCIA)
-int pcmcia_off (void)
-{
-       int i;
-       pcmcia_win_t *win;
-
-       printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
-
-       /* clear interrupt state, and disable interrupts */
-       ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr =  PCMCIA_MASK(_slot_);
-       ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
-
-       /* turn off interrupt and disable CxOE */
-       PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
-
-       /* turn off memory windows */
-       win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
-
-       for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
-               /* disable memory window */
-               win->or = 0;
-               ++win;
-       }
-
-       /* turn off voltage */
-       pcmcia_voltage_set(_slot_, 0, 0);
-
-       /* disable external hardware */
-       printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
-       pcmcia_hardware_disable(_slot_);
-       return 0;
-}
-#endif
-
-
-static u_int m8xx_get_graycode(u_int size)
-{
-       u_int k;
-
-       for (k = 0; k < M8XX_SIZES_NO; k++) {
-               if(m8xx_size_to_gray[k] == size)
-                       break;
-       }
-
-       if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
-               k = -1;
-
-       return k;
-}
-
-#if    0
-
-#if    defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
-
-/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
- * SYPCR is write once only, therefore must the slowest memory be faster
- * than the bus monitor or we will get a machine check due to the bus timeout.
- */
-#undef PCMCIA_BMT_LIMIT
-#define        PCMCIA_BMT_LIMIT (6*8)
-#endif
-
-static u_int m8xx_get_speed(u_int ns, u_int is_io)
-{
-       u_int reg, clocks, psst, psl, psht;
-
-       if(!ns) {
-
-               /*
-               * We get called with IO maps setup to 0ns
-               * if not specified by the user.
-               * They should be 255ns.
-               */
-
-               if(is_io)
-                       ns = 255;
-               else
-                       ns = 100;  /* fast memory if 0 */
-       }
-
-       /*
-       * In PSST, PSL, PSHT fields we tell the controller
-       * timing parameters in CLKOUT clock cycles.
-       * CLKOUT is the same as GCLK2_50.
-       */
-
-       /* how we want to adjust the timing - in percent */
-
-#define ADJ 180 /* 80 % longer accesstime - to be sure */
-
-       clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
-       clocks = (clocks * ADJ) / (100*1000);
-
-       if(clocks >= PCMCIA_BMT_LIMIT) {
-               DEBUG(0, "Max access time limit reached\n");
-               clocks = PCMCIA_BMT_LIMIT-1;
-       }
-
-       psst = clocks / 7;          /* setup time */
-       psht = clocks / 7;          /* hold time */
-       psl  = (clocks * 5) / 7;    /* strobe length */
-
-       psst += clocks - (psst + psht + psl);
-
-       reg =  psst << 12;
-       reg |= psl  << 7;
-       reg |= psht << 16;
-
-       return reg;
-}
-#endif /* 0 */
-
-#endif /* CONFIG_8xx && CONFIG_PCMCIA */
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
new file mode 100644 (file)
index 0000000..95c5e02
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libmtd.a
+
+COBJS-y += at45.o
+COBJS-y += cfi_flash.o
+COBJS-y += dataflash.o
+COBJS-y += mw_eeprom.o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/mtd/at45.c b/drivers/mtd/at45.c
new file mode 100644 (file)
index 0000000..dac987a
--- /dev/null
@@ -0,0 +1,562 @@
+/* Driver for ATMEL DataFlash support
+ * Author : Hamid Ikdoumi (Atmel)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+#include <common.h>
+
+#ifdef CONFIG_HAS_DATAFLASH
+#include <dataflash.h>
+
+/*
+ * spi.c API
+ */
+extern unsigned int AT91F_SpiWrite(AT91PS_DataflashDesc pDesc);
+extern void AT91F_SpiEnable(int cs);
+
+#define AT91C_TIMEOUT_WRDY                     200000
+
+/*----------------------------------------------------------------------*/
+/* \fn    AT91F_DataFlashSendCommand                                   */
+/* \brief Generic function to send a command to the dataflash          */
+/*----------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashSendCommand(AT91PS_DataFlash pDataFlash,
+                                                unsigned char OpCode,
+                                                unsigned int CmdSize,
+                                                unsigned int DataflashAddress)
+{
+       unsigned int adr;
+
+       if ((pDataFlash->pDataFlashDesc->state) != IDLE)
+               return DATAFLASH_BUSY;
+
+       /* process the address to obtain page address and byte address */
+       adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) <<
+               pDataFlash->pDevice->page_offset) +
+                       (DataflashAddress % (pDataFlash->pDevice->pages_size));
+
+       /* fill the command buffer */
+       pDataFlash->pDataFlashDesc->command[0] = OpCode;
+       if (pDataFlash->pDevice->pages_number >= 16384) {
+               pDataFlash->pDataFlashDesc->command[1] =
+                       (unsigned char)((adr & 0x0F000000) >> 24);
+               pDataFlash->pDataFlashDesc->command[2] =
+                       (unsigned char)((adr & 0x00FF0000) >> 16);
+               pDataFlash->pDataFlashDesc->command[3] =
+                       (unsigned char)((adr & 0x0000FF00) >> 8);
+               pDataFlash->pDataFlashDesc->command[4] =
+                       (unsigned char)(adr & 0x000000FF);
+       } else {
+               pDataFlash->pDataFlashDesc->command[1] =
+                       (unsigned char)((adr & 0x00FF0000) >> 16);
+               pDataFlash->pDataFlashDesc->command[2] =
+                       (unsigned char)((adr & 0x0000FF00) >> 8);
+               pDataFlash->pDataFlashDesc->command[3] =
+                       (unsigned char)(adr & 0x000000FF);
+               pDataFlash->pDataFlashDesc->command[4] = 0;
+       }
+       pDataFlash->pDataFlashDesc->command[5] = 0;
+       pDataFlash->pDataFlashDesc->command[6] = 0;
+       pDataFlash->pDataFlashDesc->command[7] = 0;
+
+       /* Initialize the SpiData structure for the spi write fuction */
+       pDataFlash->pDataFlashDesc->tx_cmd_pt =
+               pDataFlash->pDataFlashDesc->command;
+       pDataFlash->pDataFlashDesc->tx_cmd_size = CmdSize;
+       pDataFlash->pDataFlashDesc->rx_cmd_pt =
+               pDataFlash->pDataFlashDesc->command;
+       pDataFlash->pDataFlashDesc->rx_cmd_size = CmdSize;
+
+       /* send the command and read the data */
+       return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
+}
+
+/*----------------------------------------------------------------------*/
+/* \fn    AT91F_DataFlashGetStatus                                     */
+/* \brief Read the status register of the dataflash                    */
+/*----------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
+{
+       AT91S_DataFlashStatus status;
+
+       /* if a transfert is in progress ==> return 0 */
+       if ((pDesc->state) != IDLE)
+               return DATAFLASH_BUSY;
+
+       /* first send the read status command (D7H) */
+       pDesc->command[0] = DB_STATUS;
+       pDesc->command[1] = 0;
+
+       pDesc->DataFlash_state = GET_STATUS;
+       pDesc->tx_data_size = 0;        /* Transmit the command */
+       /* and receive response */
+       pDesc->tx_cmd_pt = pDesc->command;
+       pDesc->rx_cmd_pt = pDesc->command;
+       pDesc->rx_cmd_size = 2;
+       pDesc->tx_cmd_size = 2;
+       status = AT91F_SpiWrite(pDesc);
+
+       pDesc->DataFlash_state = *((unsigned char *)(pDesc->rx_cmd_pt) + 1);
+
+       return status;
+}
+
+/*----------------------------------------------------------------------*/
+/* \fn    AT91F_DataFlashWaitReady                                     */
+/* \brief wait for dataflash ready (bit7 of the status register == 1)  */
+/*----------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc
+                                               pDataFlashDesc,
+                                               unsigned int timeout)
+{
+       pDataFlashDesc->DataFlash_state = IDLE;
+
+       do {
+               AT91F_DataFlashGetStatus(pDataFlashDesc);
+               timeout--;
+       } while (((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) &&
+                (timeout > 0));
+
+       if ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
+               return DATAFLASH_ERROR;
+
+       return DATAFLASH_OK;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Function Name       : AT91F_DataFlashContinuousRead                             */
+/* Object              : Continuous stream Read                            */
+/* Input Parameters    : DataFlash Service                                 */
+/*                                             : <src> = dataflash address */
+/*                     : <*dataBuffer> = data buffer pointer               */
+/*                     : <sizeToRead> = data buffer size                   */
+/* Return value                : State of the dataflash                            */
+/*--------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashContinuousRead(
+                               AT91PS_DataFlash pDataFlash,
+                               int src,
+                               unsigned char *dataBuffer,
+                               int sizeToRead)
+{
+       AT91S_DataFlashStatus status;
+       /* Test the size to read in the device */
+       if ((src + sizeToRead) >
+                       (pDataFlash->pDevice->pages_size *
+                               (pDataFlash->pDevice->pages_number)))
+               return DATAFLASH_MEMORY_OVERFLOW;
+
+       pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
+       pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead;
+       pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
+       pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;
+
+       status = AT91F_DataFlashSendCommand(
+                       pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src);
+       /* Send the command to the dataflash */
+       return (status);
+}
+
+/*---------------------------------------------------------------------------*/
+/* Function Name       : AT91F_DataFlashPagePgmBuf                          */
+/* Object              : Main memory page program thru buffer 1 or buffer 2  */
+/* Input Parameters    : DataFlash Service                                  */
+/*                                             : <*src> = Source buffer     */
+/*                     : <dest> = dataflash destination address                     */
+/*                     : <SizeToWrite> = data buffer size                   */
+/* Return value                : State of the dataflash                             */
+/*---------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashPagePgmBuf(AT91PS_DataFlash pDataFlash,
+                                               unsigned char *src,
+                                               unsigned int dest,
+                                               unsigned int SizeToWrite)
+{
+       int cmdsize;
+       pDataFlash->pDataFlashDesc->tx_data_pt = src;
+       pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite;
+       pDataFlash->pDataFlashDesc->rx_data_pt = src;
+       pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
+
+       cmdsize = 4;
+       /* Send the command to the dataflash */
+       if (pDataFlash->pDevice->pages_number >= 16384)
+               cmdsize = 5;
+       return (AT91F_DataFlashSendCommand(
+                       pDataFlash, DB_PAGE_PGM_BUF1, cmdsize, dest));
+}
+
+/*---------------------------------------------------------------------------*/
+/* Function Name       : AT91F_MainMemoryToBufferTransfert                  */
+/* Object              : Read a page in the SRAM Buffer 1 or 2              */
+/* Input Parameters    : DataFlash Service                                  */
+/*                     : Page concerned                                             */
+/*                     :                                                    */
+/* Return value                : State of the dataflash                             */
+/*---------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfert(
+                                       AT91PS_DataFlash
+                                       pDataFlash,
+                                       unsigned char
+                                       BufferCommand,
+                                       unsigned int page)
+{
+       int cmdsize;
+       /* Test if the buffer command is legal */
+       if ((BufferCommand != DB_PAGE_2_BUF1_TRF) &&
+                       (BufferCommand != DB_PAGE_2_BUF2_TRF)) {
+               return DATAFLASH_BAD_COMMAND;
+       }
+
+       /* no data to transmit or receive */
+       pDataFlash->pDataFlashDesc->tx_data_size = 0;
+       cmdsize = 4;
+       if (pDataFlash->pDevice->pages_number >= 16384)
+               cmdsize = 5;
+       return (AT91F_DataFlashSendCommand(
+                       pDataFlash, BufferCommand, cmdsize,
+                       page * pDataFlash->pDevice->pages_size));
+}
+
+/*-------------------------------------------------------------------------- */
+/* Function Name       : AT91F_DataFlashWriteBuffer                         */
+/* Object              : Write data to the internal sram buffer 1 or 2      */
+/* Input Parameters    : DataFlash Service                                  */
+/*                     : <BufferCommand> = command to write buffer1 or 2    */
+/*                     : <*dataBuffer> = data buffer to write               */
+/*                     : <bufferAddress> = address in the internal buffer    */
+/*                     : <SizeToWrite> = data buffer size                   */
+/* Return value                : State of the dataflash                             */
+/*---------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer(
+                                       AT91PS_DataFlash pDataFlash,
+                                       unsigned char BufferCommand,
+                                       unsigned char *dataBuffer,
+                                       unsigned int bufferAddress,
+                                       int SizeToWrite)
+{
+       int cmdsize;
+       /* Test if the buffer command is legal */
+       if ((BufferCommand != DB_BUF1_WRITE) &&
+                       (BufferCommand != DB_BUF2_WRITE)) {
+               return DATAFLASH_BAD_COMMAND;
+       }
+
+       /* buffer address must be lower than page size */
+       if (bufferAddress > pDataFlash->pDevice->pages_size)
+               return DATAFLASH_BAD_ADDRESS;
+
+       if ((pDataFlash->pDataFlashDesc->state) != IDLE)
+               return DATAFLASH_BUSY;
+
+       /* Send first Write Command */
+       pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
+       pDataFlash->pDataFlashDesc->command[1] = 0;
+       if (pDataFlash->pDevice->pages_number >= 16384) {
+               pDataFlash->pDataFlashDesc->command[2] = 0;
+               pDataFlash->pDataFlashDesc->command[3] =
+                       (unsigned char)(((unsigned int)(bufferAddress &
+                                                       pDataFlash->pDevice->
+                                                       byte_mask)) >> 8);
+               pDataFlash->pDataFlashDesc->command[4] =
+                       (unsigned char)((unsigned int)bufferAddress & 0x00FF);
+               cmdsize = 5;
+       } else {
+               pDataFlash->pDataFlashDesc->command[2] =
+                       (unsigned char)(((unsigned int)(bufferAddress &
+                                                       pDataFlash->pDevice->
+                                                       byte_mask)) >> 8);
+               pDataFlash->pDataFlashDesc->command[3] =
+                       (unsigned char)((unsigned int)bufferAddress & 0x00FF);
+               pDataFlash->pDataFlashDesc->command[4] = 0;
+               cmdsize = 4;
+       }
+
+       pDataFlash->pDataFlashDesc->tx_cmd_pt =
+               pDataFlash->pDataFlashDesc->command;
+       pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize;
+       pDataFlash->pDataFlashDesc->rx_cmd_pt =
+               pDataFlash->pDataFlashDesc->command;
+       pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize;
+
+       pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
+       pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
+       pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
+       pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite;
+
+       return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
+}
+
+/*---------------------------------------------------------------------------*/
+/* Function Name       : AT91F_PageErase                                     */
+/* Object              : Erase a page                                       */
+/* Input Parameters    : DataFlash Service                                  */
+/*                     : Page concerned                                             */
+/*                     :                                                    */
+/* Return value                : State of the dataflash                             */
+/*---------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_PageErase(
+                                       AT91PS_DataFlash pDataFlash,
+                                       unsigned int page)
+{
+       int cmdsize;
+       /* Test if the buffer command is legal */
+       /* no data to transmit or receive */
+       pDataFlash->pDataFlashDesc->tx_data_size = 0;
+
+       cmdsize = 4;
+       if (pDataFlash->pDevice->pages_number >= 16384)
+               cmdsize = 5;
+       return (AT91F_DataFlashSendCommand(pDataFlash,
+                               DB_PAGE_ERASE, cmdsize,
+                               page * pDataFlash->pDevice->pages_size));
+}
+
+/*---------------------------------------------------------------------------*/
+/* Function Name       : AT91F_BlockErase                                    */
+/* Object              : Erase a Block                                              */
+/* Input Parameters    : DataFlash Service                                  */
+/*                     : Page concerned                                             */
+/*                     :                                                    */
+/* Return value                : State of the dataflash                             */
+/*---------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_BlockErase(
+                               AT91PS_DataFlash pDataFlash,
+                               unsigned int block)
+{
+       int cmdsize;
+       /* Test if the buffer command is legal */
+       /* no data to transmit or receive */
+       pDataFlash->pDataFlashDesc->tx_data_size = 0;
+       cmdsize = 4;
+       if (pDataFlash->pDevice->pages_number >= 16384)
+               cmdsize = 5;
+       return (AT91F_DataFlashSendCommand(pDataFlash, DB_BLOCK_ERASE, cmdsize,
+                                       block * 8 *
+                                       pDataFlash->pDevice->pages_size));
+}
+
+/*---------------------------------------------------------------------------*/
+/* Function Name       : AT91F_WriteBufferToMain                            */
+/* Object              : Write buffer to the main memory                    */
+/* Input Parameters    : DataFlash Service                                  */
+/*             : <BufferCommand> = command to send to buffer1 or buffer2    */
+/*                     : <dest> = main memory address                       */
+/* Return value                : State of the dataflash                             */
+/*---------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_WriteBufferToMain(AT91PS_DataFlash pDataFlash,
+                                       unsigned char BufferCommand,
+                                       unsigned int dest)
+{
+       int cmdsize;
+       /* Test if the buffer command is correct */
+       if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
+                       (BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
+                       (BufferCommand != DB_BUF2_PAGE_PGM) &&
+                       (BufferCommand != DB_BUF2_PAGE_ERASE_PGM))
+               return DATAFLASH_BAD_COMMAND;
+
+       /* no data to transmit or receive */
+       pDataFlash->pDataFlashDesc->tx_data_size = 0;
+
+       cmdsize = 4;
+       if (pDataFlash->pDevice->pages_number >= 16384)
+               cmdsize = 5;
+       /* Send the command to the dataflash */
+       return (AT91F_DataFlashSendCommand(pDataFlash, BufferCommand,
+                                               cmdsize, dest));
+}
+
+/*---------------------------------------------------------------------------*/
+/* Function Name       : AT91F_PartialPageWrite                                     */
+/* Object              : Erase partielly a page                                     */
+/* Input Parameters    : <page> = page number                               */
+/*                     : <AdrInpage> = adr to begin the fading              */
+/*                     : <length> = Number of bytes to erase                */
+/*---------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_PartialPageWrite(AT91PS_DataFlash pDataFlash,
+                                       unsigned char *src,
+                                       unsigned int dest,
+                                       unsigned int size)
+{
+       unsigned int page;
+       unsigned int AdrInPage;
+
+       page = dest / (pDataFlash->pDevice->pages_size);
+       AdrInPage = dest % (pDataFlash->pDevice->pages_size);
+
+       /* Read the contents of the page in the Sram Buffer */
+       AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
+       AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
+                                AT91C_TIMEOUT_WRDY);
+       /*Update the SRAM buffer */
+       AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src,
+                                       AdrInPage, size);
+
+       AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
+                                       AT91C_TIMEOUT_WRDY);
+
+       /* Erase page if a 128 Mbits device */
+       if (pDataFlash->pDevice->pages_number >= 16384) {
+               AT91F_PageErase(pDataFlash, page);
+               /* Rewrite the modified Sram Buffer in the main memory */
+               AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
+                                        AT91C_TIMEOUT_WRDY);
+       }
+
+       /* Rewrite the modified Sram Buffer in the main memory */
+       return (AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM,
+                                       (page *
+                                        pDataFlash->pDevice->pages_size)));
+}
+
+/*---------------------------------------------------------------------------*/
+/* Function Name       : AT91F_DataFlashWrite                               */
+/* Object              :                                                    */
+/* Input Parameters    : <*src> = Source buffer                                     */
+/*                     : <dest> = dataflash adress                          */
+/*                     : <size> = data buffer size                          */
+/*---------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashWrite(AT91PS_DataFlash pDataFlash,
+                                               unsigned char *src,
+                                               int dest, int size)
+{
+       unsigned int length;
+       unsigned int page;
+       unsigned int status;
+
+       AT91F_SpiEnable(pDataFlash->pDevice->cs);
+
+       if ((dest + size) > (pDataFlash->pDevice->pages_size *
+                       (pDataFlash->pDevice->pages_number)))
+               return DATAFLASH_MEMORY_OVERFLOW;
+
+       /* If destination does not fit a page start address */
+       if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size))) != 0) {
+               length =
+                       pDataFlash->pDevice->pages_size -
+                       (dest % ((unsigned int)(pDataFlash->pDevice->pages_size)));
+
+               if (size < length)
+                       length = size;
+
+               if (!AT91F_PartialPageWrite(pDataFlash, src, dest, length))
+                       return DATAFLASH_ERROR;
+
+               AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
+                                        AT91C_TIMEOUT_WRDY);
+
+               /* Update size, source and destination pointers */
+               size -= length;
+               dest += length;
+               src += length;
+       }
+
+       while ((size - pDataFlash->pDevice->pages_size) >= 0) {
+               /* program dataflash page */
+               page = (unsigned int)dest / (pDataFlash->pDevice->pages_size);
+
+               status = AT91F_DataFlashWriteBuffer(pDataFlash,
+                                       DB_BUF1_WRITE, src, 0,
+                                       pDataFlash->pDevice->
+                                       pages_size);
+               AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
+                                        AT91C_TIMEOUT_WRDY);
+
+               status = AT91F_PageErase(pDataFlash, page);
+               AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
+                                        AT91C_TIMEOUT_WRDY);
+               if (!status)
+                       return DATAFLASH_ERROR;
+
+               status = AT91F_WriteBufferToMain(pDataFlash,
+                                        DB_BUF1_PAGE_PGM, dest);
+               if (!status)
+                       return DATAFLASH_ERROR;
+
+               AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
+                                        AT91C_TIMEOUT_WRDY);
+
+               /* Update size, source and destination pointers */
+               size -= pDataFlash->pDevice->pages_size;
+               dest += pDataFlash->pDevice->pages_size;
+               src += pDataFlash->pDevice->pages_size;
+       }
+
+       /* If still some bytes to read */
+       if (size > 0) {
+               /* program dataflash page */
+               if (!AT91F_PartialPageWrite(pDataFlash, src, dest, size))
+                       return DATAFLASH_ERROR;
+
+               AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
+                                        AT91C_TIMEOUT_WRDY);
+       }
+       return DATAFLASH_OK;
+}
+
+/*---------------------------------------------------------------------------*/
+/* Function Name       : AT91F_DataFlashRead                                */
+/* Object              : Read a block in dataflash                          */
+/* Input Parameters    :                                                    */
+/* Return value                :                                                    */
+/*---------------------------------------------------------------------------*/
+int AT91F_DataFlashRead(AT91PS_DataFlash pDataFlash,
+                       unsigned long addr, unsigned long size, char *buffer)
+{
+       unsigned long SizeToRead;
+
+       AT91F_SpiEnable(pDataFlash->pDevice->cs);
+
+       if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
+                                       AT91C_TIMEOUT_WRDY) != DATAFLASH_OK)
+               return -1;
+
+       while (size) {
+               SizeToRead = (size < 0x8000) ? size : 0x8000;
+
+               if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
+                                       AT91C_TIMEOUT_WRDY) !=
+                                               DATAFLASH_OK)
+                       return -1;
+
+               if (AT91F_DataFlashContinuousRead(pDataFlash, addr,
+                                               (uchar *) buffer,
+                                               SizeToRead) != DATAFLASH_OK)
+                       return -1;
+
+               size -= SizeToRead;
+               addr += SizeToRead;
+               buffer += SizeToRead;
+       }
+
+       return DATAFLASH_OK;
+}
+
+/*---------------------------------------------------------------------------*/
+/* Function Name       : AT91F_DataflashProbe                               */
+/* Object              :                                                    */
+/* Input Parameters    :                                                    */
+/* Return value               : Dataflash status register                           */
+/*---------------------------------------------------------------------------*/
+int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc)
+{
+       AT91F_SpiEnable(cs);
+       AT91F_DataFlashGetStatus(pDesc);
+       return ((pDesc->command[1] == 0xFF) ? 0 : pDesc->command[1] & 0x3C);
+}
+#endif
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
new file mode 100644 (file)
index 0000000..5579a1e
--- /dev/null
@@ -0,0 +1,1528 @@
+/*
+ * (C) Copyright 2002-2004
+ * Brad Kemp, Seranoa Networks, Brad.Kemp@seranoa.com
+ *
+ * Copyright (C) 2003 Arabella Software Ltd.
+ * Yuli Barcohen <yuli@arabellasw.com>
+ *
+ * Copyright (C) 2004
+ * Ed Okerson
+ *
+ * Copyright (C) 2006
+ * Tolunay Orkun <listmember@orkun.us>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+/* The DEBUG define must be before common to enable debugging */
+/* #define DEBUG       */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <environment.h>
+#ifdef CFG_FLASH_CFI_DRIVER
+
+/*
+ * This file implements a Common Flash Interface (CFI) driver for U-Boot.
+ * The width of the port and the width of the chips are determined at initialization.
+ * These widths are used to calculate the address for access CFI data structures.
+ *
+ * References
+ * JEDEC Standard JESD68 - Common Flash Interface (CFI)
+ * JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes
+ * Intel Application Note 646 Common Flash Interface (CFI) and Command Sets
+ * Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet
+ * AMD CFI Specification, Release 2.0 December 1, 2001
+ * AMD/Spansion Application Note: Migration from Single-byte to Three-byte
+ *   Device IDs, Publication Number 25538 Revision A, November 8, 2001
+ *
+ * define CFG_WRITE_SWAPPED_DATA, if you have to swap the Bytes between
+ * reading and writing ... (yes there is such a Hardware).
+ */
+
+#ifndef CFG_FLASH_BANKS_LIST
+#define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE }
+#endif
+
+#define FLASH_CMD_CFI                  0x98
+#define FLASH_CMD_READ_ID              0x90
+#define FLASH_CMD_RESET                        0xff
+#define FLASH_CMD_BLOCK_ERASE          0x20
+#define FLASH_CMD_ERASE_CONFIRM                0xD0
+#define FLASH_CMD_WRITE                        0x40
+#define FLASH_CMD_PROTECT              0x60
+#define FLASH_CMD_PROTECT_SET          0x01
+#define FLASH_CMD_PROTECT_CLEAR                0xD0
+#define FLASH_CMD_CLEAR_STATUS         0x50
+#define FLASH_CMD_WRITE_TO_BUFFER      0xE8
+#define FLASH_CMD_WRITE_BUFFER_CONFIRM 0xD0
+
+#define FLASH_STATUS_DONE              0x80
+#define FLASH_STATUS_ESS               0x40
+#define FLASH_STATUS_ECLBS             0x20
+#define FLASH_STATUS_PSLBS             0x10
+#define FLASH_STATUS_VPENS             0x08
+#define FLASH_STATUS_PSS               0x04
+#define FLASH_STATUS_DPS               0x02
+#define FLASH_STATUS_R                 0x01
+#define FLASH_STATUS_PROTECT           0x01
+
+#define AMD_CMD_RESET                  0xF0
+#define AMD_CMD_WRITE                  0xA0
+#define AMD_CMD_ERASE_START            0x80
+#define AMD_CMD_ERASE_SECTOR           0x30
+#define AMD_CMD_UNLOCK_START           0xAA
+#define AMD_CMD_UNLOCK_ACK             0x55
+#define AMD_CMD_WRITE_TO_BUFFER                0x25
+#define AMD_CMD_WRITE_BUFFER_CONFIRM   0x29
+
+#define AMD_STATUS_TOGGLE              0x40
+#define AMD_STATUS_ERROR               0x20
+
+#define AMD_ADDR_ERASE_START   ((info->portwidth == FLASH_CFI_8BIT) ? 0xAAA : 0x555)
+#define AMD_ADDR_START         ((info->portwidth == FLASH_CFI_8BIT) ? 0xAAA : 0x555)
+#define AMD_ADDR_ACK           ((info->portwidth == FLASH_CFI_8BIT) ? 0x555 : 0x2AA)
+
+#define FLASH_OFFSET_MANUFACTURER_ID   0x00
+#define FLASH_OFFSET_DEVICE_ID         0x01
+#define FLASH_OFFSET_DEVICE_ID2                0x0E
+#define FLASH_OFFSET_DEVICE_ID3                0x0F
+#define FLASH_OFFSET_CFI               0x55
+#define FLASH_OFFSET_CFI_ALT           0x555
+#define FLASH_OFFSET_CFI_RESP          0x10
+#define FLASH_OFFSET_PRIMARY_VENDOR    0x13
+#define FLASH_OFFSET_EXT_QUERY_T_P_ADDR        0x15    /* extended query table primary addr */
+#define FLASH_OFFSET_WTOUT             0x1F
+#define FLASH_OFFSET_WBTOUT            0x20
+#define FLASH_OFFSET_ETOUT             0x21
+#define FLASH_OFFSET_CETOUT            0x22
+#define FLASH_OFFSET_WMAX_TOUT         0x23
+#define FLASH_OFFSET_WBMAX_TOUT                0x24
+#define FLASH_OFFSET_EMAX_TOUT         0x25
+#define FLASH_OFFSET_CEMAX_TOUT                0x26
+#define FLASH_OFFSET_SIZE              0x27
+#define FLASH_OFFSET_INTERFACE         0x28
+#define FLASH_OFFSET_BUFFER_SIZE       0x2A
+#define FLASH_OFFSET_NUM_ERASE_REGIONS 0x2C
+#define FLASH_OFFSET_ERASE_REGIONS     0x2D
+#define FLASH_OFFSET_PROTECT           0x02
+#define FLASH_OFFSET_USER_PROTECTION   0x85
+#define FLASH_OFFSET_INTEL_PROTECTION  0x81
+
+#define CFI_CMDSET_NONE                        0
+#define CFI_CMDSET_INTEL_EXTENDED      1
+#define CFI_CMDSET_AMD_STANDARD                2
+#define CFI_CMDSET_INTEL_STANDARD      3
+#define CFI_CMDSET_AMD_EXTENDED                4
+#define CFI_CMDSET_MITSU_STANDARD      256
+#define CFI_CMDSET_MITSU_EXTENDED      257
+#define CFI_CMDSET_SST                 258
+
+#ifdef CFG_FLASH_CFI_AMD_RESET /* needed for STM_ID_29W320DB on UC100 */
+# undef  FLASH_CMD_RESET
+# define FLASH_CMD_RESET       AMD_CMD_RESET /* use AMD-Reset instead */
+#endif
+
+typedef union {
+       unsigned char c;
+       unsigned short w;
+       unsigned long l;
+       unsigned long long ll;
+} cfiword_t;
+
+typedef union {
+       volatile unsigned char *cp;
+       volatile unsigned short *wp;
+       volatile unsigned long *lp;
+       volatile unsigned long long *llp;
+} cfiptr_t;
+
+#define NUM_ERASE_REGIONS      4 /* max. number of erase regions */
+
+static uint flash_offset_cfi[2]={FLASH_OFFSET_CFI,FLASH_OFFSET_CFI_ALT};
+
+/* use CFG_MAX_FLASH_BANKS_DETECT if defined */
+#ifdef CFG_MAX_FLASH_BANKS_DETECT
+static ulong bank_base[CFG_MAX_FLASH_BANKS_DETECT] = CFG_FLASH_BANKS_LIST;
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS_DETECT];   /* FLASH chips info */
+#else
+static ulong bank_base[CFG_MAX_FLASH_BANKS] = CFG_FLASH_BANKS_LIST;
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];          /* FLASH chips info */
+#endif
+
+/*
+ * Check if chip width is defined. If not, start detecting with 8bit.
+ */
+#ifndef CFG_FLASH_CFI_WIDTH
+#define CFG_FLASH_CFI_WIDTH    FLASH_CFI_8BIT
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+
+typedef unsigned long flash_sect_t;
+
+static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c);
+static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf);
+static void flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
+static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect);
+static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
+static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
+static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
+static void flash_read_jedec_ids (flash_info_t * info);
+static int flash_detect_cfi (flash_info_t * info);
+static int flash_write_cfiword (flash_info_t * info, ulong dest, cfiword_t cword);
+static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
+                                   ulong tout, char *prompt);
+ulong flash_get_size (ulong base, int banknum);
+#if defined(CFG_ENV_IS_IN_FLASH) || defined(CFG_ENV_ADDR_REDUND) || (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
+static flash_info_t *flash_get_info(ulong base);
+#endif
+#ifdef CFG_FLASH_USE_BUFFER_WRITE
+static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp, int len);
+#endif
+
+/*-----------------------------------------------------------------------
+ * create an address based on the offset and the port width
+ */
+inline uchar *flash_make_addr (flash_info_t * info, flash_sect_t sect, uint offset)
+{
+       return ((uchar *) (info->start[sect] + (offset * info->portwidth)));
+}
+
+#ifdef DEBUG
+/*-----------------------------------------------------------------------
+ * Debug support
+ */
+void print_longlong (char *str, unsigned long long data)
+{
+       int i;
+       char *cp;
+
+       cp = (unsigned char *) &data;
+       for (i = 0; i < 8; i++)
+               sprintf (&str[i * 2], "%2.2x", *cp++);
+}
+static void flash_printqry (flash_info_t * info, flash_sect_t sect)
+{
+       cfiptr_t cptr;
+       int x, y;
+
+       for (x = 0; x < 0x40; x += 16U / info->portwidth) {
+               cptr.cp =
+                       flash_make_addr (info, sect,
+                                        x + FLASH_OFFSET_CFI_RESP);
+               debug ("%p : ", cptr.cp);
+               for (y = 0; y < 16; y++) {
+                       debug ("%2.2x ", cptr.cp[y]);
+               }
+               debug (" ");
+               for (y = 0; y < 16; y++) {
+                       if (cptr.cp[y] >= 0x20 && cptr.cp[y] <= 0x7e) {
+                               debug ("%c", cptr.cp[y]);
+                       } else {
+                               debug (".");
+                       }
+               }
+               debug ("\n");
+       }
+}
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * read a character at a port width address
+ */
+inline uchar flash_read_uchar (flash_info_t * info, uint offset)
+{
+       uchar *cp;
+
+       cp = flash_make_addr (info, 0, offset);
+#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
+       return (cp[0]);
+#else
+       return (cp[info->portwidth - 1]);
+#endif
+}
+
+/*-----------------------------------------------------------------------
+ * read a short word by swapping for ppc format.
+ */
+ushort flash_read_ushort (flash_info_t * info, flash_sect_t sect, uint offset)
+{
+       uchar *addr;
+       ushort retval;
+
+#ifdef DEBUG
+       int x;
+#endif
+       addr = flash_make_addr (info, sect, offset);
+
+#ifdef DEBUG
+       debug ("ushort addr is at %p info->portwidth = %d\n", addr,
+              info->portwidth);
+       for (x = 0; x < 2 * info->portwidth; x++) {
+               debug ("addr[%x] = 0x%x\n", x, addr[x]);
+       }
+#endif
+#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
+       retval = ((addr[(info->portwidth)] << 8) | addr[0]);
+#else
+       retval = ((addr[(2 * info->portwidth) - 1] << 8) |
+                 addr[info->portwidth - 1]);
+#endif
+
+       debug ("retval = 0x%x\n", retval);
+       return retval;
+}
+
+/*-----------------------------------------------------------------------
+ * read a long word by picking the least significant byte of each maximum
+ * port size word. Swap for ppc format.
+ */
+ulong flash_read_long (flash_info_t * info, flash_sect_t sect, uint offset)
+{
+       uchar *addr;
+       ulong retval;
+
+#ifdef DEBUG
+       int x;
+#endif
+       addr = flash_make_addr (info, sect, offset);
+
+#ifdef DEBUG
+       debug ("long addr is at %p info->portwidth = %d\n", addr,
+              info->portwidth);
+       for (x = 0; x < 4 * info->portwidth; x++) {
+               debug ("addr[%x] = 0x%x\n", x, addr[x]);
+       }
+#endif
+#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
+       retval = (addr[0] << 16) | (addr[(info->portwidth)] << 24) |
+               (addr[(2 * info->portwidth)]) | (addr[(3 * info->portwidth)] << 8);
+#else
+       retval = (addr[(2 * info->portwidth) - 1] << 24) |
+               (addr[(info->portwidth) - 1] << 16) |
+               (addr[(4 * info->portwidth) - 1] << 8) |
+               addr[(3 * info->portwidth) - 1];
+#endif
+       return retval;
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+unsigned long flash_init (void)
+{
+       unsigned long size = 0;
+       int i;
+
+#ifdef CFG_FLASH_PROTECTION
+       char *s = getenv("unlock");
+#endif
+
+       /* Init: no FLASHes known */
+       for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
+               flash_info[i].flash_id = FLASH_UNKNOWN;
+               size += flash_info[i].size = flash_get_size (bank_base[i], i);
+               if (flash_info[i].flash_id == FLASH_UNKNOWN) {
+#ifndef CFG_FLASH_QUIET_TEST
+                       printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
+                               i+1, flash_info[i].size, flash_info[i].size << 20);
+#endif /* CFG_FLASH_QUIET_TEST */
+               }
+#ifdef CFG_FLASH_PROTECTION
+               else if ((s != NULL) && (strcmp(s, "yes") == 0)) {
+                       /*
+                        * Only the U-Boot image and it's environment is protected,
+                        * all other sectors are unprotected (unlocked) if flash
+                        * hardware protection is used (CFG_FLASH_PROTECTION) and
+                        * the environment variable "unlock" is set to "yes".
+                        */
+                       if (flash_info[i].legacy_unlock) {
+                               int k;
+
+                               /*
+                                * Disable legacy_unlock temporarily, since
+                                * flash_real_protect would relock all other sectors
+                                * again otherwise.
+                                */
+                               flash_info[i].legacy_unlock = 0;
+
+                               /*
+                                * Legacy unlocking (e.g. Intel J3) -> unlock only one
+                                * sector. This will unlock all sectors.
+                                */
+                               flash_real_protect (&flash_info[i], 0, 0);
+
+                               flash_info[i].legacy_unlock = 1;
+
+                               /*
+                                * Manually mark other sectors as unlocked (unprotected)
+                                */
+                               for (k = 1; k < flash_info[i].sector_count; k++)
+                                       flash_info[i].protect[k] = 0;
+                       } else {
+                               /*
+                                * No legancy unlocking -> unlock all sectors
+                                */
+                               flash_protect (FLAG_PROTECT_CLEAR,
+                                              flash_info[i].start[0],
+                                              flash_info[i].start[0] + flash_info[i].size - 1,
+                                              &flash_info[i]);
+                       }
+               }
+#endif /* CFG_FLASH_PROTECTION */
+       }
+
+       /* Monitor protection ON by default */
+#if (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
+       flash_protect (FLAG_PROTECT_SET,
+                      CFG_MONITOR_BASE,
+                      CFG_MONITOR_BASE + monitor_flash_len  - 1,
+                      flash_get_info(CFG_MONITOR_BASE));
+#endif
+
+       /* Environment protection ON by default */
+#ifdef CFG_ENV_IS_IN_FLASH
+       flash_protect (FLAG_PROTECT_SET,
+                      CFG_ENV_ADDR,
+                      CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
+                      flash_get_info(CFG_ENV_ADDR));
+#endif
+
+       /* Redundant environment protection ON by default */
+#ifdef CFG_ENV_ADDR_REDUND
+       flash_protect (FLAG_PROTECT_SET,
+                      CFG_ENV_ADDR_REDUND,
+                      CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1,
+                      flash_get_info(CFG_ENV_ADDR_REDUND));
+#endif
+       return (size);
+}
+
+/*-----------------------------------------------------------------------
+ */
+#if defined(CFG_ENV_IS_IN_FLASH) || defined(CFG_ENV_ADDR_REDUND) || (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
+static flash_info_t *flash_get_info(ulong base)
+{
+       int i;
+       flash_info_t * info = 0;
+
+       for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
+               info = & flash_info[i];
+               if (info->size && info->start[0] <= base &&
+                   base <= info->start[0] + info->size - 1)
+                       break;
+       }
+
+       return i == CFG_MAX_FLASH_BANKS ? 0 : info;
+}
+#endif
+
+/*-----------------------------------------------------------------------
+ */
+int flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+       int rcode = 0;
+       int prot;
+       flash_sect_t sect;
+
+       if (info->flash_id != FLASH_MAN_CFI) {
+               puts ("Can't erase unknown flash type - aborted\n");
+               return 1;
+       }
+       if ((s_first < 0) || (s_first > s_last)) {
+               puts ("- no sectors to erase\n");
+               return 1;
+       }
+
+       prot = 0;
+       for (sect = s_first; sect <= s_last; ++sect) {
+               if (info->protect[sect]) {
+                       prot++;
+               }
+       }
+       if (prot) {
+               printf ("- Warning: %d protected sectors will not be erased!\n", prot);
+       } else {
+               putc ('\n');
+       }
+
+
+       for (sect = s_first; sect <= s_last; sect++) {
+               if (info->protect[sect] == 0) { /* not protected */
+                       switch (info->vendor) {
+                       case CFI_CMDSET_INTEL_STANDARD:
+                       case CFI_CMDSET_INTEL_EXTENDED:
+                               flash_write_cmd (info, sect, 0, FLASH_CMD_CLEAR_STATUS);
+                               flash_write_cmd (info, sect, 0, FLASH_CMD_BLOCK_ERASE);
+                               flash_write_cmd (info, sect, 0, FLASH_CMD_ERASE_CONFIRM);
+                               break;
+                       case CFI_CMDSET_AMD_STANDARD:
+                       case CFI_CMDSET_AMD_EXTENDED:
+                               flash_unlock_seq (info, sect);
+                               flash_write_cmd (info, sect, AMD_ADDR_ERASE_START,
+                                                       AMD_CMD_ERASE_START);
+                               flash_unlock_seq (info, sect);
+                               flash_write_cmd (info, sect, 0, AMD_CMD_ERASE_SECTOR);
+                               break;
+                       default:
+                               debug ("Unkown flash vendor %d\n",
+                                      info->vendor);
+                               break;
+                       }
+
+                       if (flash_full_status_check
+                           (info, sect, info->erase_blk_tout, "erase")) {
+                               rcode = 1;
+                       } else
+                               putc ('.');
+               }
+       }
+       puts (" done\n");
+       return rcode;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t * info)
+{
+       int i;
+
+       if (info->flash_id != FLASH_MAN_CFI) {
+               puts ("missing or unknown FLASH type\n");
+               return;
+       }
+
+       printf ("CFI conformant FLASH (%d x %d)",
+               (info->portwidth << 3), (info->chipwidth << 3));
+       printf ("  Size: %ld MB in %d Sectors\n",
+               info->size >> 20, info->sector_count);
+       printf ("  ");
+       switch (info->vendor) {
+               case CFI_CMDSET_INTEL_STANDARD:
+                       printf ("Intel Standard");
+                       break;
+               case CFI_CMDSET_INTEL_EXTENDED:
+                       printf ("Intel Extended");
+                       break;
+               case CFI_CMDSET_AMD_STANDARD:
+                       printf ("AMD Standard");
+                       break;
+               case CFI_CMDSET_AMD_EXTENDED:
+                       printf ("AMD Extended");
+                       break;
+               default:
+                       printf ("Unknown (%d)", info->vendor);
+                       break;
+       }
+       printf (" command set, Manufacturer ID: 0x%02X, Device ID: 0x%02X",
+               info->manufacturer_id, info->device_id);
+       if (info->device_id == 0x7E) {
+               printf("%04X", info->device_id2);
+       }
+       printf ("\n  Erase timeout: %ld ms, write timeout: %ld ms\n",
+               info->erase_blk_tout,
+               info->write_tout);
+       if (info->buffer_size > 1) {
+               printf ("  Buffer write timeout: %ld ms, buffer size: %d bytes\n",
+               info->buffer_write_tout,
+               info->buffer_size);
+       }
+
+       puts ("\n  Sector Start Addresses:");
+       for (i = 0; i < info->sector_count; ++i) {
+               if ((i % 5) == 0)
+                       printf ("\n");
+#ifdef CFG_FLASH_EMPTY_INFO
+               int k;
+               int size;
+               int erased;
+               volatile unsigned long *flash;
+
+               /*
+                * Check if whole sector is erased
+                */
+               if (i != (info->sector_count - 1))
+                       size = info->start[i + 1] - info->start[i];
+               else
+                       size = info->start[0] + info->size - info->start[i];
+               erased = 1;
+               flash = (volatile unsigned long *) info->start[i];
+               size = size >> 2;       /* divide by 4 for longword access */
+               for (k = 0; k < size; k++) {
+                       if (*flash++ != 0xffffffff) {
+                               erased = 0;
+                               break;
+                       }
+               }
+
+               /* print empty and read-only info */
+               printf ("  %08lX %c %s ",
+                       info->start[i],
+                       erased ? 'E' : ' ',
+                       info->protect[i] ? "RO" : "  ");
+#else  /* ! CFG_FLASH_EMPTY_INFO */
+               printf ("  %08lX   %s ",
+                       info->start[i],
+                       info->protect[i] ? "RO" : "  ");
+#endif
+       }
+       putc ('\n');
+       return;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+       ulong wp;
+       ulong cp;
+       int aln;
+       cfiword_t cword;
+       int i, rc;
+
+#ifdef CFG_FLASH_USE_BUFFER_WRITE
+       int buffered_size;
+#endif
+       /* get lower aligned address */
+       /* get lower aligned address */
+       wp = (addr & ~(info->portwidth - 1));
+
+       /* handle unaligned start */
+       if ((aln = addr - wp) != 0) {
+               cword.l = 0;
+               cp = wp;
+               for (i = 0; i < aln; ++i, ++cp)
+                       flash_add_byte (info, &cword, (*(uchar *) cp));
+
+               for (; (i < info->portwidth) && (cnt > 0); i++) {
+                       flash_add_byte (info, &cword, *src++);
+                       cnt--;
+                       cp++;
+               }
+               for (; (cnt == 0) && (i < info->portwidth); ++i, ++cp)
+                       flash_add_byte (info, &cword, (*(uchar *) cp));
+               if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
+                       return rc;
+               wp = cp;
+       }
+
+       /* handle the aligned part */
+#ifdef CFG_FLASH_USE_BUFFER_WRITE
+       buffered_size = (info->portwidth / info->chipwidth);
+       buffered_size *= info->buffer_size;
+       while (cnt >= info->portwidth) {
+               /* prohibit buffer write when buffer_size is 1 */
+               if (info->buffer_size == 1) {
+                       cword.l = 0;
+                       for (i = 0; i < info->portwidth; i++)
+                               flash_add_byte (info, &cword, *src++);
+                       if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
+                               return rc;
+                       wp += info->portwidth;
+                       cnt -= info->portwidth;
+                       continue;
+               }
+
+               /* write buffer until next buffered_size aligned boundary */
+               i = buffered_size - (wp % buffered_size);
+               if (i > cnt)
+                       i = cnt;
+               if ((rc = flash_write_cfibuffer (info, wp, src, i)) != ERR_OK)
+                       return rc;
+               i -= i & (info->portwidth - 1);
+               wp += i;
+               src += i;
+               cnt -= i;
+       }
+#else
+       while (cnt >= info->portwidth) {
+               cword.l = 0;
+               for (i = 0; i < info->portwidth; i++) {
+                       flash_add_byte (info, &cword, *src++);
+               }
+               if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
+                       return rc;
+               wp += info->portwidth;
+               cnt -= info->portwidth;
+       }
+#endif /* CFG_FLASH_USE_BUFFER_WRITE */
+       if (cnt == 0) {
+               return (0);
+       }
+
+       /*
+        * handle unaligned tail bytes
+        */
+       cword.l = 0;
+       for (i = 0, cp = wp; (i < info->portwidth) && (cnt > 0); ++i, ++cp) {
+               flash_add_byte (info, &cword, *src++);
+               --cnt;
+       }
+       for (; i < info->portwidth; ++i, ++cp) {
+               flash_add_byte (info, &cword, (*(uchar *) cp));
+       }
+
+       return flash_write_cfiword (info, wp, cword);
+}
+
+/*-----------------------------------------------------------------------
+ */
+#ifdef CFG_FLASH_PROTECTION
+
+int flash_real_protect (flash_info_t * info, long sector, int prot)
+{
+       int retcode = 0;
+
+       flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
+       flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT);
+       if (prot)
+               flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_SET);
+       else
+               flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_CLEAR);
+
+       if ((retcode =
+            flash_full_status_check (info, sector, info->erase_blk_tout,
+                                     prot ? "protect" : "unprotect")) == 0) {
+
+               info->protect[sector] = prot;
+
+               /*
+                * On some of Intel's flash chips (marked via legacy_unlock)
+                * unprotect unprotects all locking.
+                */
+               if ((prot == 0) && (info->legacy_unlock)) {
+                       flash_sect_t i;
+
+                       for (i = 0; i < info->sector_count; i++) {
+                               if (info->protect[i])
+                                       flash_real_protect (info, i, 1);
+                       }
+               }
+       }
+       return retcode;
+}
+
+/*-----------------------------------------------------------------------
+ * flash_read_user_serial - read the OneTimeProgramming cells
+ */
+void flash_read_user_serial (flash_info_t * info, void *buffer, int offset,
+                            int len)
+{
+       uchar *src;
+       uchar *dst;
+
+       dst = buffer;
+       src = flash_make_addr (info, 0, FLASH_OFFSET_USER_PROTECTION);
+       flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
+       memcpy (dst, src + offset, len);
+       flash_write_cmd (info, 0, 0, info->cmd_reset);
+}
+
+/*
+ * flash_read_factory_serial - read the device Id from the protection area
+ */
+void flash_read_factory_serial (flash_info_t * info, void *buffer, int offset,
+                               int len)
+{
+       uchar *src;
+
+       src = flash_make_addr (info, 0, FLASH_OFFSET_INTEL_PROTECTION);
+       flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
+       memcpy (buffer, src + offset, len);
+       flash_write_cmd (info, 0, 0, info->cmd_reset);
+}
+
+#endif /* CFG_FLASH_PROTECTION */
+
+/*
+ * flash_is_busy - check to see if the flash is busy
+ * This routine checks the status of the chip and returns true if the chip is busy
+ */
+static int flash_is_busy (flash_info_t * info, flash_sect_t sect)
+{
+       int retval;
+
+       switch (info->vendor) {
+       case CFI_CMDSET_INTEL_STANDARD:
+       case CFI_CMDSET_INTEL_EXTENDED:
+               retval = !flash_isset (info, sect, 0, FLASH_STATUS_DONE);
+               break;
+       case CFI_CMDSET_AMD_STANDARD:
+       case CFI_CMDSET_AMD_EXTENDED:
+               retval = flash_toggle (info, sect, 0, AMD_STATUS_TOGGLE);
+               break;
+       default:
+               retval = 0;
+       }
+       debug ("flash_is_busy: %d\n", retval);
+       return retval;
+}
+
+/*-----------------------------------------------------------------------
+ *  wait for XSR.7 to be set. Time out with an error if it does not.
+ *  This routine does not set the flash to read-array mode.
+ */
+static int flash_status_check (flash_info_t * info, flash_sect_t sector,
+                              ulong tout, char *prompt)
+{
+       ulong start;
+
+#if CFG_HZ != 1000
+       tout *= CFG_HZ/1000;
+#endif
+
+       /* Wait for command completion */
+       start = get_timer (0);
+       while (flash_is_busy (info, sector)) {
+               if (get_timer (start) > tout) {
+                       printf ("Flash %s timeout at address %lx data %lx\n",
+                               prompt, info->start[sector],
+                               flash_read_long (info, sector, 0));
+                       flash_write_cmd (info, sector, 0, info->cmd_reset);
+                       return ERR_TIMOUT;
+               }
+               udelay (1);             /* also triggers watchdog */
+       }
+       return ERR_OK;
+}
+
+/*-----------------------------------------------------------------------
+ * Wait for XSR.7 to be set, if it times out print an error, otherwise do a full status check.
+ * This routine sets the flash to read-array mode.
+ */
+static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
+                                   ulong tout, char *prompt)
+{
+       int retcode;
+
+       retcode = flash_status_check (info, sector, tout, prompt);
+       switch (info->vendor) {
+       case CFI_CMDSET_INTEL_EXTENDED:
+       case CFI_CMDSET_INTEL_STANDARD:
+               if ((retcode == ERR_OK)
+                   && !flash_isequal (info, sector, 0, FLASH_STATUS_DONE)) {
+                       retcode = ERR_INVAL;
+                       printf ("Flash %s error at address %lx\n", prompt,
+                               info->start[sector]);
+                       if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)) {
+                               puts ("Command Sequence Error.\n");
+                       } else if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS)) {
+                               puts ("Block Erase Error.\n");
+                               retcode = ERR_NOT_ERASED;
+                       } else if (flash_isset (info, sector, 0, FLASH_STATUS_PSLBS)) {
+                               puts ("Locking Error\n");
+                       }
+                       if (flash_isset (info, sector, 0, FLASH_STATUS_DPS)) {
+                               puts ("Block locked.\n");
+                               retcode = ERR_PROTECTED;
+                       }
+                       if (flash_isset (info, sector, 0, FLASH_STATUS_VPENS))
+                               puts ("Vpp Low Error.\n");
+               }
+               flash_write_cmd (info, sector, 0, info->cmd_reset);
+               break;
+       default:
+               break;
+       }
+       return retcode;
+}
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)
+{
+#if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA)
+       unsigned short  w;
+       unsigned int    l;
+       unsigned long long ll;
+#endif
+
+       switch (info->portwidth) {
+       case FLASH_CFI_8BIT:
+               cword->c = c;
+               break;
+       case FLASH_CFI_16BIT:
+#if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA)
+               w = c;
+               w <<= 8;
+               cword->w = (cword->w >> 8) | w;
+#else
+               cword->w = (cword->w << 8) | c;
+#endif
+               break;
+       case FLASH_CFI_32BIT:
+#if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA)
+               l = c;
+               l <<= 24;
+               cword->l = (cword->l >> 8) | l;
+#else
+               cword->l = (cword->l << 8) | c;
+#endif
+               break;
+       case FLASH_CFI_64BIT:
+#if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA)
+               ll = c;
+               ll <<= 56;
+               cword->ll = (cword->ll >> 8) | ll;
+#else
+               cword->ll = (cword->ll << 8) | c;
+#endif
+               break;
+       }
+}
+
+
+/*-----------------------------------------------------------------------
+ * make a proper sized command based on the port and chip widths
+ */
+static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf)
+{
+       int i;
+       uchar *cp = (uchar *) cmdbuf;
+
+#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
+       for (i = info->portwidth; i > 0; i--)
+#else
+       for (i = 1; i <= info->portwidth; i++)
+#endif
+               *cp++ = (i & (info->chipwidth - 1)) ? '\0' : cmd;
+}
+
+/*
+ * Write a proper sized command to the correct address
+ */
+static void flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
+{
+
+       volatile cfiptr_t addr;
+       cfiword_t cword;
+
+       addr.cp = flash_make_addr (info, sect, offset);
+       flash_make_cmd (info, cmd, &cword);
+       switch (info->portwidth) {
+       case FLASH_CFI_8BIT:
+               debug ("fwc addr %p cmd %x %x 8bit x %d bit\n", addr.cp, cmd,
+                      cword.c, info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+               *addr.cp = cword.c;
+               break;
+       case FLASH_CFI_16BIT:
+               debug ("fwc addr %p cmd %x %4.4x 16bit x %d bit\n", addr.wp,
+                      cmd, cword.w,
+                      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+               *addr.wp = cword.w;
+               break;
+       case FLASH_CFI_32BIT:
+               debug ("fwc addr %p cmd %x %8.8lx 32bit x %d bit\n", addr.lp,
+                      cmd, cword.l,
+                      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+               *addr.lp = cword.l;
+               break;
+       case FLASH_CFI_64BIT:
+#ifdef DEBUG
+               {
+                       char str[20];
+
+                       print_longlong (str, cword.ll);
+
+                       debug ("fwrite addr %p cmd %x %s 64 bit x %d bit\n",
+                              addr.llp, cmd, str,
+                              info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+               }
+#endif
+               *addr.llp = cword.ll;
+               break;
+       }
+
+       /* Ensure all the instructions are fully finished */
+       sync();
+}
+
+static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect)
+{
+       flash_write_cmd (info, sect, AMD_ADDR_START, AMD_CMD_UNLOCK_START);
+       flash_write_cmd (info, sect, AMD_ADDR_ACK, AMD_CMD_UNLOCK_ACK);
+}
+
+/*-----------------------------------------------------------------------
+ */
+static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
+{
+       cfiptr_t cptr;
+       cfiword_t cword;
+       int retval;
+
+       cptr.cp = flash_make_addr (info, sect, offset);
+       flash_make_cmd (info, cmd, &cword);
+
+       debug ("is= cmd %x(%c) addr %p ", cmd, cmd, cptr.cp);
+       switch (info->portwidth) {
+       case FLASH_CFI_8BIT:
+               debug ("is= %x %x\n", cptr.cp[0], cword.c);
+               retval = (cptr.cp[0] == cword.c);
+               break;
+       case FLASH_CFI_16BIT:
+               debug ("is= %4.4x %4.4x\n", cptr.wp[0], cword.w);
+               retval = (cptr.wp[0] == cword.w);
+               break;
+       case FLASH_CFI_32BIT:
+               debug ("is= %8.8lx %8.8lx\n", cptr.lp[0], cword.l);
+               retval = (cptr.lp[0] == cword.l);
+               break;
+       case FLASH_CFI_64BIT:
+#ifdef DEBUG
+               {
+                       char str1[20];
+                       char str2[20];
+
+                       print_longlong (str1, cptr.llp[0]);
+                       print_longlong (str2, cword.ll);
+                       debug ("is= %s %s\n", str1, str2);
+               }
+#endif
+               retval = (cptr.llp[0] == cword.ll);
+               break;
+       default:
+               retval = 0;
+               break;
+       }
+       return retval;
+}
+
+/*-----------------------------------------------------------------------
+ */
+static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
+{
+       cfiptr_t cptr;
+       cfiword_t cword;
+       int retval;
+
+       cptr.cp = flash_make_addr (info, sect, offset);
+       flash_make_cmd (info, cmd, &cword);
+       switch (info->portwidth) {
+       case FLASH_CFI_8BIT:
+               retval = ((cptr.cp[0] & cword.c) == cword.c);
+               break;
+       case FLASH_CFI_16BIT:
+               retval = ((cptr.wp[0] & cword.w) == cword.w);
+               break;
+       case FLASH_CFI_32BIT:
+               retval = ((cptr.lp[0] & cword.l) == cword.l);
+               break;
+       case FLASH_CFI_64BIT:
+               retval = ((cptr.llp[0] & cword.ll) == cword.ll);
+               break;
+       default:
+               retval = 0;
+               break;
+       }
+       return retval;
+}
+
+/*-----------------------------------------------------------------------
+ */
+static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
+{
+       cfiptr_t cptr;
+       cfiword_t cword;
+       int retval;
+
+       cptr.cp = flash_make_addr (info, sect, offset);
+       flash_make_cmd (info, cmd, &cword);
+       switch (info->portwidth) {
+       case FLASH_CFI_8BIT:
+               retval = ((cptr.cp[0] & cword.c) != (cptr.cp[0] & cword.c));
+               break;
+       case FLASH_CFI_16BIT:
+               retval = ((cptr.wp[0] & cword.w) != (cptr.wp[0] & cword.w));
+               break;
+       case FLASH_CFI_32BIT:
+               retval = ((cptr.lp[0] & cword.l) != (cptr.lp[0] & cword.l));
+               break;
+       case FLASH_CFI_64BIT:
+               retval = ((cptr.llp[0] & cword.ll) !=
+                         (cptr.llp[0] & cword.ll));
+               break;
+       default:
+               retval = 0;
+               break;
+       }
+       return retval;
+}
+
+/*-----------------------------------------------------------------------
+ * read jedec ids from device and set corresponding fields in info struct
+ *
+ * Note: assume cfi->vendor, cfi->portwidth and cfi->chipwidth are correct
+ *
+*/
+static void flash_read_jedec_ids (flash_info_t * info)
+{
+       info->manufacturer_id = 0;
+       info->device_id       = 0;
+       info->device_id2      = 0;
+
+       switch (info->vendor) {
+       case CFI_CMDSET_INTEL_STANDARD:
+       case CFI_CMDSET_INTEL_EXTENDED:
+               flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
+               flash_write_cmd(info, 0, 0, FLASH_CMD_READ_ID);
+               udelay(1000); /* some flash are slow to respond */
+               info->manufacturer_id = flash_read_uchar (info,
+                                               FLASH_OFFSET_MANUFACTURER_ID);
+               info->device_id = flash_read_uchar (info,
+                                               FLASH_OFFSET_DEVICE_ID);
+               flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
+               break;
+       case CFI_CMDSET_AMD_STANDARD:
+       case CFI_CMDSET_AMD_EXTENDED:
+               flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
+               flash_unlock_seq(info, 0);
+               flash_write_cmd(info, 0, AMD_ADDR_START, FLASH_CMD_READ_ID);
+               udelay(1000); /* some flash are slow to respond */
+               info->manufacturer_id = flash_read_uchar (info,
+                                               FLASH_OFFSET_MANUFACTURER_ID);
+               info->device_id = flash_read_uchar (info,
+                                               FLASH_OFFSET_DEVICE_ID);
+               if (info->device_id == 0x7E) {
+                       /* AMD 3-byte (expanded) device ids */
+                       info->device_id2 = flash_read_uchar (info,
+                                               FLASH_OFFSET_DEVICE_ID2);
+                       info->device_id2 <<= 8;
+                       info->device_id2 |= flash_read_uchar (info,
+                                               FLASH_OFFSET_DEVICE_ID3);
+               }
+               flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
+               break;
+       default:
+               break;
+       }
+}
+
+/*-----------------------------------------------------------------------
+ * detect if flash is compatible with the Common Flash Interface (CFI)
+ * http://www.jedec.org/download/search/jesd68.pdf
+ *
+*/
+static int flash_detect_cfi (flash_info_t * info)
+{
+       int cfi_offset;
+       debug ("flash detect cfi\n");
+
+       for (info->portwidth = CFG_FLASH_CFI_WIDTH;
+            info->portwidth <= FLASH_CFI_64BIT; info->portwidth <<= 1) {
+               for (info->chipwidth = FLASH_CFI_BY8;
+                    info->chipwidth <= info->portwidth;
+                    info->chipwidth <<= 1) {
+                       flash_write_cmd (info, 0, 0, info->cmd_reset);
+                       for (cfi_offset=0; cfi_offset < sizeof(flash_offset_cfi)/sizeof(uint); cfi_offset++) {
+                               flash_write_cmd (info, 0, flash_offset_cfi[cfi_offset], FLASH_CMD_CFI);
+                               if (flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
+                                && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R')
+                                && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {
+                                       info->interface = flash_read_ushort (info, 0, FLASH_OFFSET_INTERFACE);
+                                       info->cfi_offset=flash_offset_cfi[cfi_offset];
+                                       debug ("device interface is %d\n",
+                                               info->interface);
+                                       debug ("found port %d chip %d ",
+                                               info->portwidth, info->chipwidth);
+                                       debug ("port %d bits chip %d bits\n",
+                                               info->portwidth << CFI_FLASH_SHIFT_WIDTH,
+                                               info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+                                       return 1;
+                               }
+                       }
+               }
+       }
+       debug ("not found\n");
+       return 0;
+}
+
+/*
+ * The following code cannot be run from FLASH!
+ *
+ */
+ulong flash_get_size (ulong base, int banknum)
+{
+       flash_info_t *info = &flash_info[banknum];
+       int i, j;
+       flash_sect_t sect_cnt;
+       unsigned long sector;
+       unsigned long tmp;
+       int size_ratio;
+       uchar num_erase_regions;
+       int erase_region_size;
+       int erase_region_count;
+       int geometry_reversed = 0;
+
+       info->ext_addr = 0;
+       info->cfi_version = 0;
+#ifdef CFG_FLASH_PROTECTION
+       info->legacy_unlock = 0;
+#endif
+
+       info->start[0] = base;
+
+       if (flash_detect_cfi (info)) {
+               info->vendor = flash_read_ushort (info, 0,
+                                       FLASH_OFFSET_PRIMARY_VENDOR);
+               flash_read_jedec_ids (info);
+               flash_write_cmd (info, 0, info->cfi_offset, FLASH_CMD_CFI);
+               num_erase_regions = flash_read_uchar (info,
+                                       FLASH_OFFSET_NUM_ERASE_REGIONS);
+               info->ext_addr = flash_read_ushort (info, 0,
+                                       FLASH_OFFSET_EXT_QUERY_T_P_ADDR);
+               if (info->ext_addr) {
+                       info->cfi_version = (ushort) flash_read_uchar (info,
+                                               info->ext_addr + 3) << 8;
+                       info->cfi_version |= (ushort) flash_read_uchar (info,
+                                               info->ext_addr + 4);
+               }
+#ifdef DEBUG
+               flash_printqry (info, 0);
+#endif
+               switch (info->vendor) {
+               case CFI_CMDSET_INTEL_STANDARD:
+               case CFI_CMDSET_INTEL_EXTENDED:
+               default:
+                       info->cmd_reset = FLASH_CMD_RESET;
+#ifdef CFG_FLASH_PROTECTION
+                       /* read legacy lock/unlock bit from intel flash */
+                       if (info->ext_addr) {
+                               info->legacy_unlock = flash_read_uchar (info,
+                                               info->ext_addr + 5) & 0x08;
+                       }
+#endif
+                       break;
+               case CFI_CMDSET_AMD_STANDARD:
+               case CFI_CMDSET_AMD_EXTENDED:
+                       info->cmd_reset = AMD_CMD_RESET;
+                       /* check if flash geometry needs reversal */
+                       if (num_erase_regions <= 1)
+                               break;
+                       /* reverse geometry if top boot part */
+                       if (info->cfi_version < 0x3131) {
+                               /* CFI < 1.1, try to guess from device id */
+                               if ((info->device_id & 0x80) != 0) {
+                                       geometry_reversed = 1;
+                               }
+                               break;
+                       }
+                       /* CFI >= 1.1, deduct from top/bottom flag */
+                       /* note: ext_addr is valid since cfi_version > 0 */
+                       if (flash_read_uchar(info, info->ext_addr + 0xf) == 3) {
+                               geometry_reversed = 1;
+                       }
+                       break;
+               }
+
+               debug ("manufacturer is %d\n", info->vendor);
+               debug ("manufacturer id is 0x%x\n", info->manufacturer_id);
+               debug ("device id is 0x%x\n", info->device_id);
+               debug ("device id2 is 0x%x\n", info->device_id2);
+               debug ("cfi version is 0x%04x\n", info->cfi_version);
+
+               size_ratio = info->portwidth / info->chipwidth;
+               /* if the chip is x8/x16 reduce the ratio by half */
+               if ((info->interface == FLASH_CFI_X8X16)
+                   && (info->chipwidth == FLASH_CFI_BY8)) {
+                       size_ratio >>= 1;
+               }
+               debug ("size_ratio %d port %d bits chip %d bits\n",
+                      size_ratio, info->portwidth << CFI_FLASH_SHIFT_WIDTH,
+                      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+               debug ("found %d erase regions\n", num_erase_regions);
+               sect_cnt = 0;
+               sector = base;
+               for (i = 0; i < num_erase_regions; i++) {
+                       if (i > NUM_ERASE_REGIONS) {
+                               printf ("%d erase regions found, only %d used\n",
+                                       num_erase_regions, NUM_ERASE_REGIONS);
+                               break;
+                       }
+                       if (geometry_reversed)
+                               tmp = flash_read_long (info, 0,
+                                              FLASH_OFFSET_ERASE_REGIONS +
+                                              (num_erase_regions - 1 - i) * 4);
+                       else
+                               tmp = flash_read_long (info, 0,
+                                              FLASH_OFFSET_ERASE_REGIONS +
+                                              i * 4);
+                       erase_region_size =
+                               (tmp & 0xffff) ? ((tmp & 0xffff) * 256) : 128;
+                       tmp >>= 16;
+                       erase_region_count = (tmp & 0xffff) + 1;
+                       debug ("erase_region_count = %d erase_region_size = %d\n",
+                               erase_region_count, erase_region_size);
+                       for (j = 0; j < erase_region_count; j++) {
+                               info->start[sect_cnt] = sector;
+                               sector += (erase_region_size * size_ratio);
+
+                               /*
+                                * Only read protection status from supported devices (intel...)
+                                */
+                               switch (info->vendor) {
+                               case CFI_CMDSET_INTEL_EXTENDED:
+                               case CFI_CMDSET_INTEL_STANDARD:
+                                       info->protect[sect_cnt] =
+                                               flash_isset (info, sect_cnt,
+                                                            FLASH_OFFSET_PROTECT,
+                                                            FLASH_STATUS_PROTECT);
+                                       break;
+                               default:
+                                       info->protect[sect_cnt] = 0; /* default: not protected */
+                               }
+
+                               sect_cnt++;
+                       }
+               }
+
+               info->sector_count = sect_cnt;
+               /* multiply the size by the number of chips */
+               info->size = (1 << flash_read_uchar (info, FLASH_OFFSET_SIZE)) * size_ratio;
+               info->buffer_size = (1 << flash_read_ushort (info, 0, FLASH_OFFSET_BUFFER_SIZE));
+               tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_ETOUT);
+               info->erase_blk_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_EMAX_TOUT)));
+               tmp = (1 << flash_read_uchar (info, FLASH_OFFSET_WBTOUT)) *
+                       (1 << flash_read_uchar (info, FLASH_OFFSET_WBMAX_TOUT));
+               info->buffer_write_tout = tmp / 1000 + (tmp % 1000 ? 1 : 0); /* round up when converting to ms */
+               tmp = (1 << flash_read_uchar (info, FLASH_OFFSET_WTOUT)) *
+                     (1 << flash_read_uchar (info, FLASH_OFFSET_WMAX_TOUT));
+               info->write_tout = tmp / 1000 + (tmp % 1000 ? 1 : 0); /* round up when converting to ms */
+               info->flash_id = FLASH_MAN_CFI;
+               if ((info->interface == FLASH_CFI_X8X16) && (info->chipwidth == FLASH_CFI_BY8)) {
+                       info->portwidth >>= 1;  /* XXX - Need to test on x8/x16 in parallel. */
+               }
+       }
+
+       flash_write_cmd (info, 0, 0, info->cmd_reset);
+       return (info->size);
+}
+
+/* loop through the sectors from the highest address
+ * when the passed address is greater or equal to the sector address
+ * we have a match
+ */
+static flash_sect_t find_sector (flash_info_t * info, ulong addr)
+{
+       flash_sect_t sector;
+
+       for (sector = info->sector_count - 1; sector >= 0; sector--) {
+               if (addr >= info->start[sector])
+                       break;
+       }
+       return sector;
+}
+
+/*-----------------------------------------------------------------------
+ */
+static int flash_write_cfiword (flash_info_t * info, ulong dest,
+                               cfiword_t cword)
+{
+       cfiptr_t ctladdr;
+       cfiptr_t cptr;
+       int flag;
+
+       ctladdr.cp = flash_make_addr (info, 0, 0);
+       cptr.cp = (uchar *) dest;
+
+       /* Check if Flash is (sufficiently) erased */
+       switch (info->portwidth) {
+       case FLASH_CFI_8BIT:
+               flag = ((cptr.cp[0] & cword.c) == cword.c);
+               break;
+       case FLASH_CFI_16BIT:
+               flag = ((cptr.wp[0] & cword.w) == cword.w);
+               break;
+       case FLASH_CFI_32BIT:
+               flag = ((cptr.lp[0] & cword.l) == cword.l);
+               break;
+       case FLASH_CFI_64BIT:
+               flag = ((cptr.llp[0] & cword.ll) == cword.ll);
+               break;
+       default:
+               return 2;
+       }
+       if (!flag)
+               return 2;
+
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts ();
+
+       switch (info->vendor) {
+       case CFI_CMDSET_INTEL_EXTENDED:
+       case CFI_CMDSET_INTEL_STANDARD:
+               flash_write_cmd (info, 0, 0, FLASH_CMD_CLEAR_STATUS);
+               flash_write_cmd (info, 0, 0, FLASH_CMD_WRITE);
+               break;
+       case CFI_CMDSET_AMD_EXTENDED:
+       case CFI_CMDSET_AMD_STANDARD:
+               flash_unlock_seq (info, 0);
+               flash_write_cmd (info, 0, AMD_ADDR_START, AMD_CMD_WRITE);
+               break;
+       }
+
+       switch (info->portwidth) {
+       case FLASH_CFI_8BIT:
+               cptr.cp[0] = cword.c;
+               break;
+       case FLASH_CFI_16BIT:
+               cptr.wp[0] = cword.w;
+               break;
+       case FLASH_CFI_32BIT:
+               cptr.lp[0] = cword.l;
+               break;
+       case FLASH_CFI_64BIT:
+               cptr.llp[0] = cword.ll;
+               break;
+       }
+
+       /* re-enable interrupts if necessary */
+       if (flag)
+               enable_interrupts ();
+
+       return flash_full_status_check (info, find_sector (info, dest),
+                                       info->write_tout, "write");
+}
+
+#ifdef CFG_FLASH_USE_BUFFER_WRITE
+
+static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
+                                 int len)
+{
+       flash_sect_t sector;
+       int cnt;
+       int retcode;
+       volatile cfiptr_t src;
+       volatile cfiptr_t dst;
+
+       switch (info->vendor) {
+       case CFI_CMDSET_INTEL_STANDARD:
+       case CFI_CMDSET_INTEL_EXTENDED:
+               src.cp = cp;
+               dst.cp = (uchar *) dest;
+               sector = find_sector (info, dest);
+               flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
+               flash_write_cmd (info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER);
+               if ((retcode = flash_status_check (info, sector, info->buffer_write_tout,
+                                                  "write to buffer")) == ERR_OK) {
+                       /* reduce the number of loops by the width of the port  */
+                       switch (info->portwidth) {
+                       case FLASH_CFI_8BIT:
+                               cnt = len;
+                               break;
+                       case FLASH_CFI_16BIT:
+                               cnt = len >> 1;
+                               break;
+                       case FLASH_CFI_32BIT:
+                               cnt = len >> 2;
+                               break;
+                       case FLASH_CFI_64BIT:
+                               cnt = len >> 3;
+                               break;
+                       default:
+                               return ERR_INVAL;
+                               break;
+                       }
+                       flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
+                       while (cnt-- > 0) {
+                               switch (info->portwidth) {
+                               case FLASH_CFI_8BIT:
+                                       *dst.cp++ = *src.cp++;
+                                       break;
+                               case FLASH_CFI_16BIT:
+                                       *dst.wp++ = *src.wp++;
+                                       break;
+                               case FLASH_CFI_32BIT:
+                                       *dst.lp++ = *src.lp++;
+                                       break;
+                               case FLASH_CFI_64BIT:
+                                       *dst.llp++ = *src.llp++;
+                                       break;
+                               default:
+                                       return ERR_INVAL;
+                                       break;
+                               }
+                       }
+                       flash_write_cmd (info, sector, 0,
+                                        FLASH_CMD_WRITE_BUFFER_CONFIRM);
+                       retcode = flash_full_status_check (info, sector,
+                                                          info->buffer_write_tout,
+                                                          "buffer write");
+               }
+               return retcode;
+
+       case CFI_CMDSET_AMD_STANDARD:
+       case CFI_CMDSET_AMD_EXTENDED:
+               src.cp = cp;
+               dst.cp = (uchar *) dest;
+               sector = find_sector (info, dest);
+
+               flash_unlock_seq(info,0);
+               flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_TO_BUFFER);
+
+               switch (info->portwidth) {
+               case FLASH_CFI_8BIT:
+                       cnt = len;
+                       flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
+                       while (cnt-- > 0) *dst.cp++ = *src.cp++;
+                       break;
+               case FLASH_CFI_16BIT:
+                       cnt = len >> 1;
+                       flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
+                       while (cnt-- > 0) *dst.wp++ = *src.wp++;
+                       break;
+               case FLASH_CFI_32BIT:
+                       cnt = len >> 2;
+                       flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
+                       while (cnt-- > 0) *dst.lp++ = *src.lp++;
+                       break;
+               case FLASH_CFI_64BIT:
+                       cnt = len >> 3;
+                       flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
+                       while (cnt-- > 0) *dst.llp++ = *src.llp++;
+                       break;
+               default:
+                       return ERR_INVAL;
+               }
+
+               flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_BUFFER_CONFIRM);
+               retcode = flash_full_status_check (info, sector, info->buffer_write_tout,
+                                                  "buffer write");
+               return retcode;
+
+       default:
+               debug ("Unknown Command Set\n");
+               return ERR_INVAL;
+       }
+}
+#endif /* CFG_FLASH_USE_BUFFER_WRITE */
+
+#endif /* CFG_FLASH_CFI */
diff --git a/drivers/mtd/dataflash.c b/drivers/mtd/dataflash.c
new file mode 100644 (file)
index 0000000..91903c8
--- /dev/null
@@ -0,0 +1,507 @@
+/* LowLevel function for ATMEL DataFlash support
+ * Author : Hamid Ikdoumi (Atmel)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+#include <common.h>
+#include <config.h>
+#ifdef CONFIG_HAS_DATAFLASH
+#include <asm/hardware.h>
+#include <dataflash.h>
+
+AT91S_DATAFLASH_INFO dataflash_info[CFG_MAX_DATAFLASH_BANKS];
+static AT91S_DataFlash DataFlashInst;
+
+#ifdef CONFIG_AT91SAM9260EK
+int cs[][CFG_MAX_DATAFLASH_BANKS] = {
+       {CFG_DATAFLASH_LOGIC_ADDR_CS0, 0},      /* Logical adress, CS */
+       {CFG_DATAFLASH_LOGIC_ADDR_CS1, 1}
+};
+#elif defined(CONFIG_AT91SAM9263EK)
+int cs[][CFG_MAX_DATAFLASH_BANKS] = {
+       {CFG_DATAFLASH_LOGIC_ADDR_CS0, 0}       /* Logical adress, CS */
+};
+#else
+int cs[][CFG_MAX_DATAFLASH_BANKS] = {
+       {CFG_DATAFLASH_LOGIC_ADDR_CS0, 0},      /* Logical adress, CS */
+       {CFG_DATAFLASH_LOGIC_ADDR_CS3, 3}
+};
+#endif
+
+/*define the area offsets*/
+#if defined(CONFIG_AT91SAM9261EK) || defined(CONFIG_AT91SAM9260EK) || defined(CONFIG_AT91SAM9263EK)
+#if    defined(CONFIG_NEW_PARTITION)
+dataflash_protect_t area_list[NB_DATAFLASH_AREA] = {
+       {0x00000000,    0x00003FFF,     FLAG_PROTECT_SET,       0,              "Bootstrap"},   /* ROM code */
+       {0x00004200,    0x000083FF,     FLAG_PROTECT_CLEAR,     0,              "Environment"}, /* u-boot environment */
+       {0x00008400,    0x0003DDFF,     FLAG_PROTECT_SET,       0,              "U-Boot"},      /* u-boot code */
+       {0x0003DE00,    0x00041FFF,     FLAG_PROTECT_CLEAR,     FLAG_SETENV,    "MON"},         /* Room for alternative boot monitor */
+       {0x00042000,    0x0018BFFF,     FLAG_PROTECT_CLEAR,     FLAG_SETENV,    "OS"},          /* data area size to tune */
+       {0x0018C000,    0xFFFFFFFF,     FLAG_PROTECT_CLEAR,     FLAG_SETENV,    "FS"},          /* data area size to tune */
+};
+#else
+dataflash_protect_t area_list[NB_DATAFLASH_AREA] = {
+       {0, 0x3fff, FLAG_PROTECT_SET},                  /* ROM code */
+       {0x4000, 0x7fff, FLAG_PROTECT_CLEAR},           /* u-boot environment */
+       {0x8000, 0x37fff, FLAG_PROTECT_SET},            /* u-boot code */
+       {0x38000, 0x1fffff, FLAG_PROTECT_CLEAR},        /* data area size to tune */
+};
+#endif
+#elif defined(CONFIG_NEW_PARTITION)
+/*define the area offsets*/
+/* Invalid partitions should be defined with start > end */
+dataflash_protect_t area_list[NB_DATAFLASH_AREA*CFG_MAX_DATAFLASH_BANKS] = {
+       {0x00000000, 0x000083ff, FLAG_PROTECT_SET,      0,              "Bootstrap"},   /* ROM code */
+       {0x00008400, 0x00020fff, FLAG_PROTECT_SET,      0,              "U-Boot"},      /* u-boot code */
+       {0x00021000, 0x000293ff, FLAG_PROTECT_CLEAR,    0,              "Environment"}, /* u-boot environment 8Kb */
+       {0x00029400, 0x00041fff, FLAG_PROTECT_INVALID,  0,              "<Unused>"},    /* Rest of Sector 1 */
+       {0x00042000, 0x0018Bfff, FLAG_PROTECT_CLEAR,    FLAG_SETENV,    "OS"},  /* data area size to tune */
+       {0x0018C000, 0xffffffff, FLAG_PROTECT_CLEAR,    FLAG_SETENV,    "FS"},  /* data area size to tune */
+
+       {0x00000000, 0xffffffff, FLAG_PROTECT_CLEAR,    FLAG_SETENV,    "Data"},        /* data area */
+       {0xffffffff, 0x00000000, FLAG_PROTECT_INVALID,  0,              "<Invalid>"},   /* Invalid */
+       {0xffffffff, 0x00000000, FLAG_PROTECT_INVALID,  0,              "<Invalid>"},   /* Invalid */
+       {0xffffffff, 0x00000000, FLAG_PROTECT_INVALID,  0,              "<Invalid>"},   /* Invalid */
+       {0xffffffff, 0x00000000, FLAG_PROTECT_INVALID,  0,              "<Invalid>"},   /* Invalid */
+       {0xffffffff, 0x00000000, FLAG_PROTECT_INVALID,  0,              "<Invalid>"},   /* Invalid */
+};
+#else
+dataflash_protect_t area_list[NB_DATAFLASH_AREA] = {
+       {0, 0x7fff, FLAG_PROTECT_SET},                  /* ROM code */
+       {0x8000, 0x1ffff, FLAG_PROTECT_SET},            /* u-boot code */
+       {0x20000, 0x27fff, FLAG_PROTECT_CLEAR},         /* u-boot environment */
+       {0x28000, 0x1fffff, FLAG_PROTECT_CLEAR},        /* data area size to tune */
+};
+#endif
+
+extern void AT91F_SpiInit (void);
+extern int AT91F_DataflashProbe (int i, AT91PS_DataflashDesc pDesc);
+extern int AT91F_DataFlashRead (AT91PS_DataFlash pDataFlash,
+                               unsigned long addr,
+                               unsigned long size, char *buffer);
+extern int AT91F_DataFlashWrite( AT91PS_DataFlash pDataFlash,
+                               unsigned char *src,
+                               int dest,
+                               int size );
+
+int AT91F_DataflashInit (void)
+{
+       int i, j;
+       int dfcode;
+       int part = 0;
+       int last_part;
+       int found[CFG_MAX_DATAFLASH_BANKS];
+       unsigned char protected;
+
+       AT91F_SpiInit ();
+
+       for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
+               found[i] = 0;
+               dataflash_info[i].Desc.state = IDLE;
+               dataflash_info[i].id = 0;
+               dataflash_info[i].Device.pages_number = 0;
+               dfcode = AT91F_DataflashProbe (cs[i][1],
+                               &dataflash_info[i].Desc);
+
+               switch (dfcode) {
+               case AT45DB161:
+                       dataflash_info[i].Device.pages_number = 4096;
+                       dataflash_info[i].Device.pages_size = 528;
+                       dataflash_info[i].Device.page_offset = 10;
+                       dataflash_info[i].Device.byte_mask = 0x300;
+                       dataflash_info[i].Device.cs = cs[i][1];
+                       dataflash_info[i].Desc.DataFlash_state = IDLE;
+                       dataflash_info[i].logical_address = cs[i][0];
+                       dataflash_info[i].id = dfcode;
+                       found[i] += dfcode;;
+                       break;
+
+               case AT45DB321:
+                       dataflash_info[i].Device.pages_number = 8192;
+                       dataflash_info[i].Device.pages_size = 528;
+                       dataflash_info[i].Device.page_offset = 10;
+                       dataflash_info[i].Device.byte_mask = 0x300;
+                       dataflash_info[i].Device.cs = cs[i][1];
+                       dataflash_info[i].Desc.DataFlash_state = IDLE;
+                       dataflash_info[i].logical_address = cs[i][0];
+                       dataflash_info[i].id = dfcode;
+                       found[i] += dfcode;;
+                       break;
+
+               case AT45DB642:
+                       dataflash_info[i].Device.pages_number = 8192;
+                       dataflash_info[i].Device.pages_size = 1056;
+                       dataflash_info[i].Device.page_offset = 11;
+                       dataflash_info[i].Device.byte_mask = 0x700;
+                       dataflash_info[i].Device.cs = cs[i][1];
+                       dataflash_info[i].Desc.DataFlash_state = IDLE;
+                       dataflash_info[i].logical_address = cs[i][0];
+                       dataflash_info[i].id = dfcode;
+                       found[i] += dfcode;;
+                       break;
+
+               case AT45DB128:
+                       dataflash_info[i].Device.pages_number = 16384;
+                       dataflash_info[i].Device.pages_size = 1056;
+                       dataflash_info[i].Device.page_offset = 11;
+                       dataflash_info[i].Device.byte_mask = 0x700;
+                       dataflash_info[i].Device.cs = cs[i][1];
+                       dataflash_info[i].Desc.DataFlash_state = IDLE;
+                       dataflash_info[i].logical_address = cs[i][0];
+                       dataflash_info[i].id = dfcode;
+                       found[i] += dfcode;;
+                       break;
+
+               default:
+                       dfcode = 0;
+                       break;
+               }
+               /* set the last area end to the dataflash size*/
+               area_list[NB_DATAFLASH_AREA -1].end =
+                               (dataflash_info[i].Device.pages_number *
+                               dataflash_info[i].Device.pages_size)-1;
+
+               last_part=0;
+               /* set the area addresses */
+               for(j = 0; j<NB_DATAFLASH_AREA; j++) {
+                       if(found[i]!=0) {
+                               dataflash_info[i].Device.area_list[j].start =
+                                       area_list[part].start +
+                                       dataflash_info[i].logical_address;
+                               if(area_list[part].end == 0xffffffff) {
+                                       dataflash_info[i].Device.area_list[j].end =
+                                               dataflash_info[i].end_address +
+                                               dataflash_info  [i].logical_address;
+                                       last_part = 1;
+                               } else {
+                                       dataflash_info[i].Device.area_list[j].end =
+                                               area_list[part].end +
+                                               dataflash_info[i].logical_address;
+                               }
+                               protected = area_list[part].protected;
+                               /* Set the environment according to the label...*/
+                               if(protected == FLAG_PROTECT_INVALID) {
+                                       dataflash_info[i].Device.area_list[j].protected =
+                                               FLAG_PROTECT_INVALID;
+                               } else {
+                                       dataflash_info[i].Device.area_list[j].protected =
+                                               protected;
+                               }
+                               strcpy((char*)(dataflash_info[i].Device.area_list[j].label),
+                                               (const char *)area_list[part].label);
+                       }
+                       part++;
+               }
+       }
+       return found[0];
+}
+
+#ifdef CONFIG_NEW_DF_PARTITION
+int AT91F_DataflashSetEnv (void)
+{
+       int i, j;
+       int part;
+       unsigned char env;
+       unsigned char s[32];    /* Will fit a long int in hex */
+       unsigned long start;
+       for (i = 0, part= 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
+               for(j = 0; j<NB_DATAFLASH_AREA; j++) {
+                       env = area_list[part].setenv;
+                       /* Set the environment according to the label...*/
+                       if((env & FLAG_SETENV) == FLAG_SETENV) {
+                               start =
+                               dataflash_info[i].Device.area_list[j].start;
+                               sprintf(s,"%X",start);
+                               setenv(area_list[part].label,s);
+                       }
+                       part++;
+               }
+       }
+}
+#endif
+
+void dataflash_print_info (void)
+{
+       int i, j;
+
+       for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
+               if (dataflash_info[i].id != 0) {
+                       printf("DataFlash:");
+                       switch (dataflash_info[i].id) {
+                       case AT45DB161:
+                               printf("AT45DB161\n");
+                               break;
+
+                       case AT45DB321:
+                               printf("AT45DB321\n");
+                               break;
+
+                       case AT45DB642:
+                               printf("AT45DB642\n");
+                               break;
+                       case AT45DB128:
+                               printf("AT45DB128\n");
+                               break;
+                       }
+
+                       printf("Nb pages: %6d\n"
+                               "Page Size: %6d\n"
+                               "Size=%8d bytes\n"
+                               "Logical address: 0x%08X\n",
+                               (unsigned int) dataflash_info[i].Device.pages_number,
+                               (unsigned int) dataflash_info[i].Device.pages_size,
+                               (unsigned int) dataflash_info[i].Device.pages_number *
+                               dataflash_info[i].Device.pages_size,
+                               (unsigned int) dataflash_info[i].logical_address);
+                       for (j=0; j< NB_DATAFLASH_AREA; j++) {
+                               switch(dataflash_info[i].Device.area_list[j].protected) {
+                               case    FLAG_PROTECT_SET:
+                               case    FLAG_PROTECT_CLEAR:
+                                       printf("Area %i:\t%08lX to %08lX %s", j,
+                                               dataflash_info[i].Device.area_list[j].start,
+                                               dataflash_info[i].Device.area_list[j].end,
+                                               (dataflash_info[i].Device.area_list[j].protected==FLAG_PROTECT_SET) ? "(RO)" : "    ");
+#ifdef CONFIG_NEW_DF_PARTITION
+                                               printf(" %s\n", dataflash_info[i].Device.area_list[j].label);
+#else
+                                               printf("\n");
+#endif
+                                       break;
+#ifdef CONFIG_NEW_DF_PARTITION
+                               case    FLAG_PROTECT_INVALID:
+                                       break;
+#endif
+                               }
+                       }
+               }
+       }
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* Function Name       : AT91F_DataflashSelect                                      */
+/* Object              : Select the correct device                          */
+/*---------------------------------------------------------------------------*/
+AT91PS_DataFlash AT91F_DataflashSelect (AT91PS_DataFlash pFlash,
+                               unsigned long *addr)
+{
+       char addr_valid = 0;
+       int i;
+
+       for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++)
+               if ( dataflash_info[i].id
+                       && ((((int) addr) & 0xFF000000) ==
+                       dataflash_info[i].logical_address)) {
+                       addr_valid = 1;
+                       break;
+               }
+       if (!addr_valid) {
+               pFlash = (AT91PS_DataFlash) 0;
+               return pFlash;
+       }
+       pFlash->pDataFlashDesc = &(dataflash_info[i].Desc);
+       pFlash->pDevice = &(dataflash_info[i].Device);
+       *addr -= dataflash_info[i].logical_address;
+       return (pFlash);
+}
+
+/*---------------------------------------------------------------------------*/
+/* Function Name       : addr_dataflash                                     */
+/* Object              : Test if address is valid                           */
+/*---------------------------------------------------------------------------*/
+int addr_dataflash (unsigned long addr)
+{
+       int addr_valid = 0;
+       int i;
+
+       for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
+               if ((((int) addr) & 0xFF000000) ==
+                       dataflash_info[i].logical_address) {
+                       addr_valid = 1;
+                       break;
+               }
+       }
+
+       return addr_valid;
+}
+/*---------------------------------------------------------------------------*/
+/* Function Name       : size_dataflash                                     */
+/* Object              : Test if address is valid regarding the size        */
+/*---------------------------------------------------------------------------*/
+int size_dataflash (AT91PS_DataFlash pdataFlash, unsigned long addr,
+                       unsigned long size)
+{
+       /* is outside the dataflash */
+       if (((int)addr & 0x0FFFFFFF) > (pdataFlash->pDevice->pages_size *
+               pdataFlash->pDevice->pages_number)) return 0;
+       /* is too large for the dataflash */
+       if (size > ((pdataFlash->pDevice->pages_size *
+               pdataFlash->pDevice->pages_number) -
+               ((int)addr & 0x0FFFFFFF))) return 0;
+
+       return 1;
+}
+/*---------------------------------------------------------------------------*/
+/* Function Name       : prot_dataflash                                     */
+/* Object              : Test if destination area is protected              */
+/*---------------------------------------------------------------------------*/
+int prot_dataflash (AT91PS_DataFlash pdataFlash, unsigned long addr)
+{
+int area;
+       /* find area */
+       for (area=0; area < NB_DATAFLASH_AREA; area++) {
+               if ((addr >= pdataFlash->pDevice->area_list[area].start) &&
+                       (addr < pdataFlash->pDevice->area_list[area].end))
+                       break;
+       }
+       if (area == NB_DATAFLASH_AREA)
+               return -1;
+
+       /*test protection value*/
+       if (pdataFlash->pDevice->area_list[area].protected == FLAG_PROTECT_SET)
+               return 0;
+       if (pdataFlash->pDevice->area_list[area].protected == FLAG_PROTECT_INVALID)
+               return 0;
+
+       return 1;
+}
+/*--------------------------------------------------------------------------*/
+/* Function Name       : dataflash_real_protect                                    */
+/* Object              : protect/unprotect area                                    */
+/*--------------------------------------------------------------------------*/
+int dataflash_real_protect (int flag, unsigned long start_addr,
+                               unsigned long end_addr)
+{
+int i,j, area1, area2, addr_valid = 0;
+       /* find dataflash */
+       for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
+               if ((((int) start_addr) & 0xF0000000) ==
+                       dataflash_info[i].logical_address) {
+                               addr_valid = 1;
+                               break;
+               }
+       }
+       if (!addr_valid) {
+               return -1;
+       }
+       /* find start area */
+       for (area1=0; area1 < NB_DATAFLASH_AREA; area1++) {
+               if (start_addr == dataflash_info[i].Device.area_list[area1].start)
+                       break;
+       }
+       if (area1 == NB_DATAFLASH_AREA) return -1;
+       /* find end area */
+       for (area2=0; area2 < NB_DATAFLASH_AREA; area2++) {
+               if (end_addr == dataflash_info[i].Device.area_list[area2].end)
+                       break;
+       }
+       if (area2 == NB_DATAFLASH_AREA)
+               return -1;
+
+       /*set protection value*/
+       for(j = area1; j < area2+1 ; j++)
+               if(dataflash_info[i].Device.area_list[j].protected
+                               != FLAG_PROTECT_INVALID) {
+                       if (flag == 0) {
+                               dataflash_info[i].Device.area_list[j].protected
+                                       = FLAG_PROTECT_CLEAR;
+                       } else {
+                               dataflash_info[i].Device.area_list[j].protected
+                                       = FLAG_PROTECT_SET;
+                       }
+               }
+
+       return (area2-area1+1);
+}
+
+/*---------------------------------------------------------------------------*/
+/* Function Name       : read_dataflash                                     */
+/* Object              : dataflash memory read                              */
+/*---------------------------------------------------------------------------*/
+int read_dataflash (unsigned long addr, unsigned long size, char *result)
+{
+       unsigned long AddrToRead = addr;
+       AT91PS_DataFlash pFlash = &DataFlashInst;
+
+       pFlash = AT91F_DataflashSelect (pFlash, &AddrToRead);
+
+       if (pFlash == 0)
+               return ERR_UNKNOWN_FLASH_TYPE;
+
+       if (size_dataflash(pFlash,addr,size) == 0)
+               return ERR_INVAL;
+
+       return (AT91F_DataFlashRead (pFlash, AddrToRead, size, result));
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* Function Name       : write_dataflash                                    */
+/* Object              : write a block in dataflash                         */
+/*---------------------------------------------------------------------------*/
+int write_dataflash (unsigned long addr_dest, unsigned long addr_src,
+                       unsigned long size)
+{
+       unsigned long AddrToWrite = addr_dest;
+       AT91PS_DataFlash pFlash = &DataFlashInst;
+
+       pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite);
+
+       if (pFlash == 0)
+               return ERR_UNKNOWN_FLASH_TYPE;
+
+       if (size_dataflash(pFlash,addr_dest,size) == 0)
+               return ERR_INVAL;
+
+       if (prot_dataflash(pFlash,addr_dest) == 0)
+               return ERR_PROTECTED;
+
+       if (AddrToWrite == -1)
+               return -1;
+
+       return AT91F_DataFlashWrite (pFlash, (uchar *)addr_src,
+                                               AddrToWrite, size);
+}
+
+
+void dataflash_perror (int err)
+{
+       switch (err) {
+       case ERR_OK:
+               break;
+       case ERR_TIMOUT:
+               printf("Timeout writing to DataFlash\n");
+               break;
+       case ERR_PROTECTED:
+               printf("Can't write to protected/invalid DataFlash sectors\n");
+               break;
+       case ERR_INVAL:
+               printf("Outside available DataFlash\n");
+               break;
+       case ERR_UNKNOWN_FLASH_TYPE:
+               printf("Unknown Type of DataFlash\n");
+               break;
+       case ERR_PROG_ERROR:
+               printf("General DataFlash Programming Error\n");
+               break;
+       default:
+               printf("%s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err);
+               break;
+       }
+}
+
+#endif
diff --git a/drivers/mtd/mw_eeprom.c b/drivers/mtd/mw_eeprom.c
new file mode 100644 (file)
index 0000000..2b33488
--- /dev/null
@@ -0,0 +1,241 @@
+/* Three-wire (MicroWire) serial eeprom driver (for 93C46 and compatibles) */
+
+#include <common.h>
+
+#ifdef CONFIG_MW_EEPROM
+
+#include <ssi.h>
+
+/*
+ * Serial EEPROM opcodes, including start bit
+ */
+#define EEP_OPC_ERASE  0x7  /* 3-bit opcode */
+#define EEP_OPC_WRITE  0x5  /* 3-bit opcode */
+#define EEP_OPC_READ           0x6  /* 3-bit opcode */
+
+#define EEP_OPC_ERASE_ALL      0x12 /* 5-bit opcode */
+#define EEP_OPC_ERASE_EN       0x13 /* 5-bit opcode */
+#define EEP_OPC_WRITE_ALL      0x11 /* 5-bit opcode */
+#define EEP_OPC_ERASE_DIS      0x10 /* 5-bit opcode */
+
+static int addrlen;
+
+static void mw_eeprom_select(int dev)
+{
+       ssi_set_interface(2048, 0, 0, 0);
+       ssi_chip_select(0);
+       udelay(1);
+       ssi_chip_select(dev);
+       udelay(1);
+}
+
+static int mw_eeprom_size(int dev)
+{
+       int x;
+       u16 res;
+
+       mw_eeprom_select(dev);
+       ssi_tx_byte(EEP_OPC_READ);
+
+       res = ssi_txrx_byte(0) << 8;
+       res |= ssi_rx_byte();
+       for (x = 0; x < 16; x++) {
+               if (! (res & 0x8000)) {
+                       break;
+               }
+               res <<= 1;
+       }
+       ssi_chip_select(0);
+
+       return x;
+}
+
+int mw_eeprom_erase_enable(int dev)
+{
+       mw_eeprom_select(dev);
+       ssi_tx_byte(EEP_OPC_ERASE_EN);
+       ssi_tx_byte(0);
+       udelay(1);
+       ssi_chip_select(0);
+
+       return 0;
+}
+
+int mw_eeprom_erase_disable(int dev)
+{
+       mw_eeprom_select(dev);
+       ssi_tx_byte(EEP_OPC_ERASE_DIS);
+       ssi_tx_byte(0);
+       udelay(1);
+       ssi_chip_select(0);
+
+       return 0;
+}
+
+
+u32 mw_eeprom_read_word(int dev, int addr)
+{
+       u16 rcv;
+       u16 res;
+       int bits;
+
+       mw_eeprom_select(dev);
+       ssi_tx_byte((EEP_OPC_READ << 5) | ((addr >> (addrlen - 5)) & 0x1f));
+       rcv = ssi_txrx_byte(addr << (13 - addrlen));
+       res = rcv << (16 - addrlen);
+       bits = 4 + addrlen;
+
+       while (bits>0) {
+               rcv = ssi_rx_byte();
+               if (bits > 7) {
+                       res |= rcv << (bits - 8);
+               } else {
+                       res |= rcv >> (8 - bits);
+               }
+               bits -= 8;
+       }
+
+       ssi_chip_select(0);
+
+       return res;
+}
+
+int mw_eeprom_write_word(int dev, int addr, u16 data)
+{
+       u8 byte1=0;
+       u8 byte2=0;
+
+       mw_eeprom_erase_enable(dev);
+       mw_eeprom_select(dev);
+
+       switch (addrlen) {
+        case 6:
+               byte1 = EEP_OPC_WRITE >> 2;
+               byte2 = (EEP_OPC_WRITE << 6)&0xc0;
+               byte2 |= addr;
+               break;
+        case 7:
+               byte1 = EEP_OPC_WRITE >> 1;
+               byte2 = (EEP_OPC_WRITE << 7)&0x80;
+               byte2 |= addr;
+               break;
+        case 8:
+               byte1 = EEP_OPC_WRITE;
+               byte2 = addr;
+               break;
+        case 9:
+               byte1 = EEP_OPC_WRITE << 1;
+               byte1 |= addr >> 8;
+               byte2 = addr & 0xff;
+               break;
+        case 10:
+               byte1 = EEP_OPC_WRITE << 2;
+               byte1 |= addr >> 8;
+               byte2 = addr & 0xff;
+               break;
+        default:
+               printf("Unsupported number of address bits: %d\n", addrlen);
+               return -1;
+
+       }
+
+       ssi_tx_byte(byte1);
+       ssi_tx_byte(byte2);
+       ssi_tx_byte(data >> 8);
+       ssi_tx_byte(data & 0xff);
+       ssi_chip_select(0);
+       udelay(10000); /* Worst case */
+       mw_eeprom_erase_disable(dev);
+
+       return 0;
+}
+
+
+int mw_eeprom_write(int dev, int addr, u8 *buffer, int len)
+{
+       int done;
+
+       done = 0;
+       if (addr & 1) {
+               u16 temp = mw_eeprom_read_word(dev, addr >> 1);
+               temp &= 0xff00;
+               temp |= buffer[0];
+
+               mw_eeprom_write_word(dev, addr >> 1, temp);
+               len--;
+               addr++;
+               buffer++;
+               done++;
+       }
+
+       while (len <= 2) {
+               mw_eeprom_write_word(dev, addr >> 1, *(u16*)buffer);
+               len-=2;
+               addr+=2;
+               buffer+=2;
+               done+=2;
+       }
+
+       if (len) {
+               u16 temp = mw_eeprom_read_word(dev, addr >> 1);
+               temp &= 0x00ff;
+               temp |= buffer[0] << 8;
+
+               mw_eeprom_write_word(dev, addr >> 1, temp);
+               len--;
+               addr++;
+               buffer++;
+               done++;
+       }
+
+       return done;
+}
+
+
+int mw_eeprom_read(int dev, int addr, u8 *buffer, int len)
+{
+       int done;
+
+       done = 0;
+       if (addr & 1) {
+               u16 temp = mw_eeprom_read_word(dev, addr >> 1);
+               buffer[0]= temp & 0xff;
+
+               len--;
+               addr++;
+               buffer++;
+               done++;
+       }
+
+       while (len <= 2) {
+               *(u16*)buffer = mw_eeprom_read_word(dev, addr >> 1);
+               len-=2;
+               addr+=2;
+               buffer+=2;
+               done+=2;
+       }
+
+       if (len) {
+               u16 temp = mw_eeprom_read_word(dev, addr >> 1);
+               buffer[0] = temp >> 8;
+
+               len--;
+               addr++;
+               buffer++;
+               done++;
+       }
+
+       return done;
+}
+
+int mw_eeprom_probe(int dev)
+{
+       addrlen = mw_eeprom_size(dev);
+
+       if (addrlen < 6 || addrlen > 10) {
+               return -1;
+       }
+       return 0;
+}
+
+#endif
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
new file mode 100644 (file)
index 0000000..42864f9
--- /dev/null
@@ -0,0 +1,51 @@
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libnand.a
+
+COBJS-y += nand.o
+COBJS-y += nand_base.o
+COBJS-y += nand_ids.o
+COBJS-y += nand_ecc.o
+COBJS-y += nand_bbt.o
+COBJS-y += nand_util.o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
new file mode 100644 (file)
index 0000000..e17af70
--- /dev/null
@@ -0,0 +1,1787 @@
+/*
+ * drivers/mtd/nand/diskonchip.c
+ *
+ * (C) 2003 Red Hat, Inc.
+ * (C) 2004 Dan Brown <dan_brown@ieee.org>
+ * (C) 2004 Kalev Lember <kalev@smartlink.ee>
+ *
+ * Author: David Woodhouse <dwmw2@infradead.org>
+ * Additional Diskonchip 2000 and Millennium support by Dan Brown <dan_brown@ieee.org>
+ * Diskonchip Millennium Plus support by Kalev Lember <kalev@smartlink.ee>
+ *
+ * Error correction code lifted from the old docecc code
+ * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
+ * Copyright (C) 2000 Netgem S.A.
+ * converted to the generic Reed-Solomon library by Thomas Gleixner <tglx@linutronix.de>
+ *
+ * Interface to generic NAND code for M-Systems DiskOnChip devices
+ *
+ * $Id: diskonchip.c,v 1.45 2005/01/05 18:05:14 dwmw2 Exp $
+ */
+
+#include <common.h>
+
+#if !defined(CFG_NAND_LEGACY)
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/rslib.h>
+#include <linux/moduleparam.h>
+#include <asm/io.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/doc2000.h>
+#include <linux/mtd/compatmac.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/inftl.h>
+
+/* Where to look for the devices? */
+#ifndef CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS
+#define CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS 0
+#endif
+
+static unsigned long __initdata doc_locations[] = {
+#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
+#ifdef CONFIG_MTD_DISKONCHIP_PROBE_HIGH
+       0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
+       0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
+       0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
+       0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
+       0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000,
+#else /*  CONFIG_MTD_DOCPROBE_HIGH */
+       0xc8000, 0xca000, 0xcc000, 0xce000,
+       0xd0000, 0xd2000, 0xd4000, 0xd6000,
+       0xd8000, 0xda000, 0xdc000, 0xde000,
+       0xe0000, 0xe2000, 0xe4000, 0xe6000,
+       0xe8000, 0xea000, 0xec000, 0xee000,
+#endif /*  CONFIG_MTD_DOCPROBE_HIGH */
+#elif defined(__PPC__)
+       0xe4000000,
+#elif defined(CONFIG_MOMENCO_OCELOT)
+       0x2f000000,
+       0xff000000,
+#elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C)
+       0xff000000,
+##else
+#warning Unknown architecture for DiskOnChip. No default probe locations defined
+#endif
+       0xffffffff };
+
+static struct mtd_info *doclist = NULL;
+
+struct doc_priv {
+       void __iomem *virtadr;
+       unsigned long physadr;
+       u_char ChipID;
+       u_char CDSNControl;
+       int chips_per_floor; /* The number of chips detected on each floor */
+       int curfloor;
+       int curchip;
+       int mh0_page;
+       int mh1_page;
+       struct mtd_info *nextdoc;
+};
+
+/* Max number of eraseblocks to scan (from start of device) for the (I)NFTL
+   MediaHeader.  The spec says to just keep going, I think, but that's just
+   silly. */
+#define MAX_MEDIAHEADER_SCAN 8
+
+/* This is the syndrome computed by the HW ecc generator upon reading an empty
+   page, one with all 0xff for data and stored ecc code. */
+static u_char empty_read_syndrome[6] = { 0x26, 0xff, 0x6d, 0x47, 0x73, 0x7a };
+/* This is the ecc value computed by the HW ecc generator upon writing an empty
+   page, one with all 0xff for data. */
+static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 };
+
+#define INFTL_BBT_RESERVED_BLOCKS 4
+
+#define DoC_is_MillenniumPlus(doc) ((doc)->ChipID == DOC_ChipID_DocMilPlus16 || (doc)->ChipID == DOC_ChipID_DocMilPlus32)
+#define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil)
+#define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k)
+
+static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd);
+static void doc200x_select_chip(struct mtd_info *mtd, int chip);
+
+static int debug=0;
+module_param(debug, int, 0);
+
+static int try_dword=1;
+module_param(try_dword, int, 0);
+
+static int no_ecc_failures=0;
+module_param(no_ecc_failures, int, 0);
+
+#ifdef CONFIG_MTD_PARTITIONS
+static int no_autopart=0;
+module_param(no_autopart, int, 0);
+#endif
+
+#ifdef MTD_NAND_DISKONCHIP_BBTWRITE
+static int inftl_bbt_write=1;
+#else
+static int inftl_bbt_write=0;
+#endif
+module_param(inftl_bbt_write, int, 0);
+
+static unsigned long doc_config_location = CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS;
+module_param(doc_config_location, ulong, 0);
+MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe for DiskOnChip");
+
+
+/* Sector size for HW ECC */
+#define SECTOR_SIZE 512
+/* The sector bytes are packed into NB_DATA 10 bit words */
+#define NB_DATA (((SECTOR_SIZE + 1) * 8 + 6) / 10)
+/* Number of roots */
+#define NROOTS 4
+/* First consective root */
+#define FCR 510
+/* Number of symbols */
+#define NN 1023
+
+/* the Reed Solomon control structure */
+static struct rs_control *rs_decoder;
+
+/*
+ * The HW decoder in the DoC ASIC's provides us a error syndrome,
+ * which we must convert to a standard syndrom usable by the generic
+ * Reed-Solomon library code.
+ *
+ * Fabrice Bellard figured this out in the old docecc code. I added
+ * some comments, improved a minor bit and converted it to make use
+ * of the generic Reed-Solomon libary. tglx
+ */
+static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
+{
+       int i, j, nerr, errpos[8];
+       uint8_t parity;
+       uint16_t ds[4], s[5], tmp, errval[8], syn[4];
+
+       /* Convert the ecc bytes into words */
+       ds[0] = ((ecc[4] & 0xff) >> 0) | ((ecc[5] & 0x03) << 8);
+       ds[1] = ((ecc[5] & 0xfc) >> 2) | ((ecc[2] & 0x0f) << 6);
+       ds[2] = ((ecc[2] & 0xf0) >> 4) | ((ecc[3] & 0x3f) << 4);
+       ds[3] = ((ecc[3] & 0xc0) >> 6) | ((ecc[0] & 0xff) << 2);
+       parity = ecc[1];
+
+       /* Initialize the syndrom buffer */
+       for (i = 0; i < NROOTS; i++)
+               s[i] = ds[0];
+       /*
+        *  Evaluate
+        *  s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0]
+        *  where x = alpha^(FCR + i)
+        */
+       for(j = 1; j < NROOTS; j++) {
+               if(ds[j] == 0)
+                       continue;
+               tmp = rs->index_of[ds[j]];
+               for(i = 0; i < NROOTS; i++)
+                       s[i] ^= rs->alpha_to[rs_modnn(rs, tmp + (FCR + i) * j)];
+       }
+
+       /* Calc s[i] = s[i] / alpha^(v + i) */
+       for (i = 0; i < NROOTS; i++) {
+               if (syn[i])
+                       syn[i] = rs_modnn(rs, rs->index_of[s[i]] + (NN - FCR - i));
+       }
+       /* Call the decoder library */
+       nerr = decode_rs16(rs, NULL, NULL, 1019, syn, 0, errpos, 0, errval);
+
+       /* Incorrectable errors ? */
+       if (nerr < 0)
+               return nerr;
+
+       /*
+        * Correct the errors. The bitpositions are a bit of magic,
+        * but they are given by the design of the de/encoder circuit
+        * in the DoC ASIC's.
+        */
+       for(i = 0;i < nerr; i++) {
+               int index, bitpos, pos = 1015 - errpos[i];
+               uint8_t val;
+               if (pos >= NB_DATA && pos < 1019)
+                       continue;
+               if (pos < NB_DATA) {
+                       /* extract bit position (MSB first) */
+                       pos = 10 * (NB_DATA - 1 - pos) - 6;
+                       /* now correct the following 10 bits. At most two bytes
+                          can be modified since pos is even */
+                       index = (pos >> 3) ^ 1;
+                       bitpos = pos & 7;
+                       if ((index >= 0 && index < SECTOR_SIZE) ||
+                           index == (SECTOR_SIZE + 1)) {
+                               val = (uint8_t) (errval[i] >> (2 + bitpos));
+                               parity ^= val;
+                               if (index < SECTOR_SIZE)
+                                       data[index] ^= val;
+                       }
+                       index = ((pos >> 3) + 1) ^ 1;
+                       bitpos = (bitpos + 10) & 7;
+                       if (bitpos == 0)
+                               bitpos = 8;
+                       if ((index >= 0 && index < SECTOR_SIZE) ||
+                           index == (SECTOR_SIZE + 1)) {
+                               val = (uint8_t)(errval[i] << (8 - bitpos));
+                               parity ^= val;
+                               if (index < SECTOR_SIZE)
+                                       data[index] ^= val;
+                       }
+               }
+       }
+       /* If the parity is wrong, no rescue possible */
+       return parity ? -1 : nerr;
+}
+
+static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
+{
+       volatile char dummy;
+       int i;
+
+       for (i = 0; i < cycles; i++) {
+               if (DoC_is_Millennium(doc))
+                       dummy = ReadDOC(doc->virtadr, NOP);
+               else if (DoC_is_MillenniumPlus(doc))
+                       dummy = ReadDOC(doc->virtadr, Mplus_NOP);
+               else
+                       dummy = ReadDOC(doc->virtadr, DOCStatus);
+       }
+
+}
+
+#define CDSN_CTRL_FR_B_MASK    (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1)
+
+/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
+static int _DoC_WaitReady(struct doc_priv *doc)
+{
+       void __iomem *docptr = doc->virtadr;
+       unsigned long timeo = jiffies + (HZ * 10);
+
+       if(debug) printk("_DoC_WaitReady...\n");
+       /* Out-of-line routine to wait for chip response */
+       if (DoC_is_MillenniumPlus(doc)) {
+               while ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) {
+                       if (time_after(jiffies, timeo)) {
+                               printk("_DoC_WaitReady timed out.\n");
+                               return -EIO;
+                       }
+                       udelay(1);
+                       cond_resched();
+               }
+       } else {
+               while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
+                       if (time_after(jiffies, timeo)) {
+                               printk("_DoC_WaitReady timed out.\n");
+                               return -EIO;
+                       }
+                       udelay(1);
+                       cond_resched();
+               }
+       }
+
+       return 0;
+}
+
+static inline int DoC_WaitReady(struct doc_priv *doc)
+{
+       void __iomem *docptr = doc->virtadr;
+       int ret = 0;
+
+       if (DoC_is_MillenniumPlus(doc)) {
+               DoC_Delay(doc, 4);
+
+               if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK)
+                       /* Call the out-of-line routine to wait */
+                       ret = _DoC_WaitReady(doc);
+       } else {
+               DoC_Delay(doc, 4);
+
+               if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
+                       /* Call the out-of-line routine to wait */
+                       ret = _DoC_WaitReady(doc);
+               DoC_Delay(doc, 2);
+       }
+
+       if(debug) printk("DoC_WaitReady OK\n");
+       return ret;
+}
+
+static void doc2000_write_byte(struct mtd_info *mtd, u_char datum)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+
+       if(debug)printk("write_byte %02x\n", datum);
+       WriteDOC(datum, docptr, CDSNSlowIO);
+       WriteDOC(datum, docptr, 2k_CDSN_IO);
+}
+
+static u_char doc2000_read_byte(struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+       u_char ret;
+
+       ReadDOC(docptr, CDSNSlowIO);
+       DoC_Delay(doc, 2);
+       ret = ReadDOC(docptr, 2k_CDSN_IO);
+       if (debug) printk("read_byte returns %02x\n", ret);
+       return ret;
+}
+
+static void doc2000_writebuf(struct mtd_info *mtd,
+                            const u_char *buf, int len)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+       int i;
+       if (debug)printk("writebuf of %d bytes: ", len);
+       for (i=0; i < len; i++) {
+               WriteDOC_(buf[i], docptr, DoC_2k_CDSN_IO + i);
+               if (debug && i < 16)
+                       printk("%02x ", buf[i]);
+       }
+       if (debug) printk("\n");
+}
+
+static void doc2000_readbuf(struct mtd_info *mtd,
+                           u_char *buf, int len)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+       int i;
+
+       if (debug)printk("readbuf of %d bytes: ", len);
+
+       for (i=0; i < len; i++) {
+               buf[i] = ReadDOC(docptr, 2k_CDSN_IO + i);
+       }
+}
+
+static void doc2000_readbuf_dword(struct mtd_info *mtd,
+                           u_char *buf, int len)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+       int i;
+
+       if (debug) printk("readbuf_dword of %d bytes: ", len);
+
+       if (unlikely((((unsigned long)buf)|len) & 3)) {
+               for (i=0; i < len; i++) {
+                       *(uint8_t *)(&buf[i]) = ReadDOC(docptr, 2k_CDSN_IO + i);
+               }
+       } else {
+               for (i=0; i < len; i+=4) {
+                       *(uint32_t*)(&buf[i]) = readl(docptr + DoC_2k_CDSN_IO + i);
+               }
+       }
+}
+
+static int doc2000_verifybuf(struct mtd_info *mtd,
+                             const u_char *buf, int len)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+       int i;
+
+       for (i=0; i < len; i++)
+               if (buf[i] != ReadDOC(docptr, 2k_CDSN_IO))
+                       return -EFAULT;
+       return 0;
+}
+
+static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       uint16_t ret;
+
+       doc200x_select_chip(mtd, nr);
+       doc200x_hwcontrol(mtd, NAND_CTL_SETCLE);
+       this->write_byte(mtd, NAND_CMD_READID);
+       doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE);
+       doc200x_hwcontrol(mtd, NAND_CTL_SETALE);
+       this->write_byte(mtd, 0);
+       doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
+
+       ret = this->read_byte(mtd) << 8;
+       ret |= this->read_byte(mtd);
+
+       if (doc->ChipID == DOC_ChipID_Doc2k && try_dword && !nr) {
+               /* First chip probe. See if we get same results by 32-bit access */
+               union {
+                       uint32_t dword;
+                       uint8_t byte[4];
+               } ident;
+               void __iomem *docptr = doc->virtadr;
+
+               doc200x_hwcontrol(mtd, NAND_CTL_SETCLE);
+               doc2000_write_byte(mtd, NAND_CMD_READID);
+               doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE);
+               doc200x_hwcontrol(mtd, NAND_CTL_SETALE);
+               doc2000_write_byte(mtd, 0);
+               doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
+
+               ident.dword = readl(docptr + DoC_2k_CDSN_IO);
+               if (((ident.byte[0] << 8) | ident.byte[1]) == ret) {
+                       printk(KERN_INFO "DiskOnChip 2000 responds to DWORD access\n");
+                       this->read_buf = &doc2000_readbuf_dword;
+               }
+       }
+
+       return ret;
+}
+
+static void __init doc2000_count_chips(struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       uint16_t mfrid;
+       int i;
+
+       /* Max 4 chips per floor on DiskOnChip 2000 */
+       doc->chips_per_floor = 4;
+
+       /* Find out what the first chip is */
+       mfrid = doc200x_ident_chip(mtd, 0);
+
+       /* Find how many chips in each floor. */
+       for (i = 1; i < 4; i++) {
+               if (doc200x_ident_chip(mtd, i) != mfrid)
+                       break;
+       }
+       doc->chips_per_floor = i;
+       printk(KERN_DEBUG "Detected %d chips per floor.\n", i);
+}
+
+static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
+{
+       struct doc_priv *doc = this->priv;
+
+       int status;
+
+       DoC_WaitReady(doc);
+       this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
+       DoC_WaitReady(doc);
+       status = (int)this->read_byte(mtd);
+
+       return status;
+}
+
+static void doc2001_write_byte(struct mtd_info *mtd, u_char datum)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+
+       WriteDOC(datum, docptr, CDSNSlowIO);
+       WriteDOC(datum, docptr, Mil_CDSN_IO);
+       WriteDOC(datum, docptr, WritePipeTerm);
+}
+
+static u_char doc2001_read_byte(struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+
+       /*ReadDOC(docptr, CDSNSlowIO); */
+       /* 11.4.5 -- delay twice to allow extended length cycle */
+       DoC_Delay(doc, 2);
+       ReadDOC(docptr, ReadPipeInit);
+       /*return ReadDOC(docptr, Mil_CDSN_IO); */
+       return ReadDOC(docptr, LastDataRead);
+}
+
+static void doc2001_writebuf(struct mtd_info *mtd,
+                            const u_char *buf, int len)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+       int i;
+
+       for (i=0; i < len; i++)
+               WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i);
+       /* Terminate write pipeline */
+       WriteDOC(0x00, docptr, WritePipeTerm);
+}
+
+static void doc2001_readbuf(struct mtd_info *mtd,
+                           u_char *buf, int len)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+       int i;
+
+       /* Start read pipeline */
+       ReadDOC(docptr, ReadPipeInit);
+
+       for (i=0; i < len-1; i++)
+               buf[i] = ReadDOC(docptr, Mil_CDSN_IO + (i & 0xff));
+
+       /* Terminate read pipeline */
+       buf[i] = ReadDOC(docptr, LastDataRead);
+}
+
+static int doc2001_verifybuf(struct mtd_info *mtd,
+                            const u_char *buf, int len)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+       int i;
+
+       /* Start read pipeline */
+       ReadDOC(docptr, ReadPipeInit);
+
+       for (i=0; i < len-1; i++)
+               if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {
+                       ReadDOC(docptr, LastDataRead);
+                       return i;
+               }
+       if (buf[i] != ReadDOC(docptr, LastDataRead))
+               return i;
+       return 0;
+}
+
+static u_char doc2001plus_read_byte(struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+       u_char ret;
+
+       ReadDOC(docptr, Mplus_ReadPipeInit);
+       ReadDOC(docptr, Mplus_ReadPipeInit);
+       ret = ReadDOC(docptr, Mplus_LastDataRead);
+       if (debug) printk("read_byte returns %02x\n", ret);
+       return ret;
+}
+
+static void doc2001plus_writebuf(struct mtd_info *mtd,
+                            const u_char *buf, int len)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+       int i;
+
+       if (debug)printk("writebuf of %d bytes: ", len);
+       for (i=0; i < len; i++) {
+               WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i);
+               if (debug && i < 16)
+                       printk("%02x ", buf[i]);
+       }
+       if (debug) printk("\n");
+}
+
+static void doc2001plus_readbuf(struct mtd_info *mtd,
+                           u_char *buf, int len)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+       int i;
+
+       if (debug)printk("readbuf of %d bytes: ", len);
+
+       /* Start read pipeline */
+       ReadDOC(docptr, Mplus_ReadPipeInit);
+       ReadDOC(docptr, Mplus_ReadPipeInit);
+
+       for (i=0; i < len-2; i++) {
+               buf[i] = ReadDOC(docptr, Mil_CDSN_IO);
+               if (debug && i < 16)
+                       printk("%02x ", buf[i]);
+       }
+
+       /* Terminate read pipeline */
+       buf[len-2] = ReadDOC(docptr, Mplus_LastDataRead);
+       if (debug && i < 16)
+               printk("%02x ", buf[len-2]);
+       buf[len-1] = ReadDOC(docptr, Mplus_LastDataRead);
+       if (debug && i < 16)
+               printk("%02x ", buf[len-1]);
+       if (debug) printk("\n");
+}
+
+static int doc2001plus_verifybuf(struct mtd_info *mtd,
+                            const u_char *buf, int len)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+       int i;
+
+       if (debug)printk("verifybuf of %d bytes: ", len);
+
+       /* Start read pipeline */
+       ReadDOC(docptr, Mplus_ReadPipeInit);
+       ReadDOC(docptr, Mplus_ReadPipeInit);
+
+       for (i=0; i < len-2; i++)
+               if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {
+                       ReadDOC(docptr, Mplus_LastDataRead);
+                       ReadDOC(docptr, Mplus_LastDataRead);
+                       return i;
+               }
+       if (buf[len-2] != ReadDOC(docptr, Mplus_LastDataRead))
+               return len-2;
+       if (buf[len-1] != ReadDOC(docptr, Mplus_LastDataRead))
+               return len-1;
+       return 0;
+}
+
+static void doc2001plus_select_chip(struct mtd_info *mtd, int chip)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+       int floor = 0;
+
+       if(debug)printk("select chip (%d)\n", chip);
+
+       if (chip == -1) {
+               /* Disable flash internally */
+               WriteDOC(0, docptr, Mplus_FlashSelect);
+               return;
+       }
+
+       floor = chip / doc->chips_per_floor;
+       chip -= (floor *  doc->chips_per_floor);
+
+       /* Assert ChipEnable and deassert WriteProtect */
+       WriteDOC((DOC_FLASH_CE), docptr, Mplus_FlashSelect);
+       this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+
+       doc->curchip = chip;
+       doc->curfloor = floor;
+}
+
+static void doc200x_select_chip(struct mtd_info *mtd, int chip)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+       int floor = 0;
+
+       if(debug)printk("select chip (%d)\n", chip);
+
+       if (chip == -1)
+               return;
+
+       floor = chip / doc->chips_per_floor;
+       chip -= (floor *  doc->chips_per_floor);
+
+       /* 11.4.4 -- deassert CE before changing chip */
+       doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE);
+
+       WriteDOC(floor, docptr, FloorSelect);
+       WriteDOC(chip, docptr, CDSNDeviceSelect);
+
+       doc200x_hwcontrol(mtd, NAND_CTL_SETNCE);
+
+       doc->curchip = chip;
+       doc->curfloor = floor;
+}
+
+static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+
+       switch(cmd) {
+       case NAND_CTL_SETNCE:
+               doc->CDSNControl |= CDSN_CTRL_CE;
+               break;
+       case NAND_CTL_CLRNCE:
+               doc->CDSNControl &= ~CDSN_CTRL_CE;
+               break;
+       case NAND_CTL_SETCLE:
+               doc->CDSNControl |= CDSN_CTRL_CLE;
+               break;
+       case NAND_CTL_CLRCLE:
+               doc->CDSNControl &= ~CDSN_CTRL_CLE;
+               break;
+       case NAND_CTL_SETALE:
+               doc->CDSNControl |= CDSN_CTRL_ALE;
+               break;
+       case NAND_CTL_CLRALE:
+               doc->CDSNControl &= ~CDSN_CTRL_ALE;
+               break;
+       case NAND_CTL_SETWP:
+               doc->CDSNControl |= CDSN_CTRL_WP;
+               break;
+       case NAND_CTL_CLRWP:
+               doc->CDSNControl &= ~CDSN_CTRL_WP;
+               break;
+       }
+       if (debug)printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl);
+       WriteDOC(doc->CDSNControl, docptr, CDSNControl);
+       /* 11.4.3 -- 4 NOPs after CSDNControl write */
+       DoC_Delay(doc, 4);
+}
+
+static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+
+       /*
+        * Must terminate write pipeline before sending any commands
+        * to the device.
+        */
+       if (command == NAND_CMD_PAGEPROG) {
+               WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
+               WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
+       }
+
+       /*
+        * Write out the command to the device.
+        */
+       if (command == NAND_CMD_SEQIN) {
+               int readcmd;
+
+               if (column >= mtd->oobblock) {
+                       /* OOB area */
+                       column -= mtd->oobblock;
+                       readcmd = NAND_CMD_READOOB;
+               } else if (column < 256) {
+                       /* First 256 bytes --> READ0 */
+                       readcmd = NAND_CMD_READ0;
+               } else {
+                       column -= 256;
+                       readcmd = NAND_CMD_READ1;
+               }
+               WriteDOC(readcmd, docptr, Mplus_FlashCmd);
+       }
+       WriteDOC(command, docptr, Mplus_FlashCmd);
+       WriteDOC(0, docptr, Mplus_WritePipeTerm);
+       WriteDOC(0, docptr, Mplus_WritePipeTerm);
+
+       if (column != -1 || page_addr != -1) {
+               /* Serially input address */
+               if (column != -1) {
+                       /* Adjust columns for 16 bit buswidth */
+                       if (this->options & NAND_BUSWIDTH_16)
+                               column >>= 1;
+                       WriteDOC(column, docptr, Mplus_FlashAddress);
+               }
+               if (page_addr != -1) {
+                       WriteDOC((unsigned char) (page_addr & 0xff), docptr, Mplus_FlashAddress);
+                       WriteDOC((unsigned char) ((page_addr >> 8) & 0xff), docptr, Mplus_FlashAddress);
+                       /* One more address cycle for higher density devices */
+                       if (this->chipsize & 0x0c000000) {
+                               WriteDOC((unsigned char) ((page_addr >> 16) & 0x0f), docptr, Mplus_FlashAddress);
+                               printk("high density\n");
+                       }
+               }
+               WriteDOC(0, docptr, Mplus_WritePipeTerm);
+               WriteDOC(0, docptr, Mplus_WritePipeTerm);
+               /* deassert ALE */
+               if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 || command == NAND_CMD_READOOB || command == NAND_CMD_READID)
+                       WriteDOC(0, docptr, Mplus_FlashControl);
+       }
+
+       /*
+        * program and erase have their own busy handlers
+        * status and sequential in needs no delay
+       */
+       switch (command) {
+
+       case NAND_CMD_PAGEPROG:
+       case NAND_CMD_ERASE1:
+       case NAND_CMD_ERASE2:
+       case NAND_CMD_SEQIN:
+       case NAND_CMD_STATUS:
+               return;
+
+       case NAND_CMD_RESET:
+               if (this->dev_ready)
+                       break;
+               udelay(this->chip_delay);
+               WriteDOC(NAND_CMD_STATUS, docptr, Mplus_FlashCmd);
+               WriteDOC(0, docptr, Mplus_WritePipeTerm);
+               WriteDOC(0, docptr, Mplus_WritePipeTerm);
+               while ( !(this->read_byte(mtd) & 0x40));
+               return;
+
+       /* This applies to read commands */
+       default:
+               /*
+                * If we don't have access to the busy pin, we apply the given
+                * command delay
+               */
+               if (!this->dev_ready) {
+                       udelay (this->chip_delay);
+                       return;
+               }
+       }
+
+       /* Apply this short delay always to ensure that we do wait tWB in
+        * any case on any machine. */
+       ndelay (100);
+       /* wait until command is processed */
+       while (!this->dev_ready(mtd));
+}
+
+static int doc200x_dev_ready(struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+
+       if (DoC_is_MillenniumPlus(doc)) {
+               /* 11.4.2 -- must NOP four times before checking FR/B# */
+               DoC_Delay(doc, 4);
+               if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) {
+                       if(debug)
+                               printk("not ready\n");
+                       return 0;
+               }
+               if (debug)printk("was ready\n");
+               return 1;
+       } else {
+               /* 11.4.2 -- must NOP four times before checking FR/B# */
+               DoC_Delay(doc, 4);
+               if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
+                       if(debug)
+                               printk("not ready\n");
+                       return 0;
+               }
+               /* 11.4.2 -- Must NOP twice if it's ready */
+               DoC_Delay(doc, 2);
+               if (debug)printk("was ready\n");
+               return 1;
+       }
+}
+
+static int doc200x_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
+{
+       /* This is our last resort if we couldn't find or create a BBT.  Just
+          pretend all blocks are good. */
+       return 0;
+}
+
+static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+
+       /* Prime the ECC engine */
+       switch(mode) {
+       case NAND_ECC_READ:
+               WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
+               WriteDOC(DOC_ECC_EN, docptr, ECCConf);
+               break;
+       case NAND_ECC_WRITE:
+               WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
+               WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
+               break;
+       }
+}
+
+static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+
+       /* Prime the ECC engine */
+       switch(mode) {
+       case NAND_ECC_READ:
+               WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
+               WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);
+               break;
+       case NAND_ECC_WRITE:
+               WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
+               WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf);
+               break;
+       }
+}
+
+/* This code is only called on write */
+static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
+                                unsigned char *ecc_code)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+       int i;
+       int emptymatch = 1;
+
+       /* flush the pipeline */
+       if (DoC_is_2000(doc)) {
+               WriteDOC(doc->CDSNControl & ~CDSN_CTRL_FLASH_IO, docptr, CDSNControl);
+               WriteDOC(0, docptr, 2k_CDSN_IO);
+               WriteDOC(0, docptr, 2k_CDSN_IO);
+               WriteDOC(0, docptr, 2k_CDSN_IO);
+               WriteDOC(doc->CDSNControl, docptr, CDSNControl);
+       } else if (DoC_is_MillenniumPlus(doc)) {
+               WriteDOC(0, docptr, Mplus_NOP);
+               WriteDOC(0, docptr, Mplus_NOP);
+               WriteDOC(0, docptr, Mplus_NOP);
+       } else {
+               WriteDOC(0, docptr, NOP);
+               WriteDOC(0, docptr, NOP);
+               WriteDOC(0, docptr, NOP);
+       }
+
+       for (i = 0; i < 6; i++) {
+               if (DoC_is_MillenniumPlus(doc))
+                       ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i);
+               else
+                       ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
+               if (ecc_code[i] != empty_write_ecc[i])
+                       emptymatch = 0;
+       }
+       if (DoC_is_MillenniumPlus(doc))
+               WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
+       else
+               WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
+#if 0
+       /* If emptymatch=1, we might have an all-0xff data buffer.  Check. */
+       if (emptymatch) {
+               /* Note: this somewhat expensive test should not be triggered
+                  often.  It could be optimized away by examining the data in
+                  the writebuf routine, and remembering the result. */
+               for (i = 0; i < 512; i++) {
+                       if (dat[i] == 0xff) continue;
+                       emptymatch = 0;
+                       break;
+               }
+       }
+       /* If emptymatch still =1, we do have an all-0xff data buffer.
+          Return all-0xff ecc value instead of the computed one, so
+          it'll look just like a freshly-erased page. */
+       if (emptymatch) memset(ecc_code, 0xff, 6);
+#endif
+       return 0;
+}
+
+static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
+{
+       int i, ret = 0;
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       void __iomem *docptr = doc->virtadr;
+       volatile u_char dummy;
+       int emptymatch = 1;
+
+       /* flush the pipeline */
+       if (DoC_is_2000(doc)) {
+               dummy = ReadDOC(docptr, 2k_ECCStatus);
+               dummy = ReadDOC(docptr, 2k_ECCStatus);
+               dummy = ReadDOC(docptr, 2k_ECCStatus);
+       } else if (DoC_is_MillenniumPlus(doc)) {
+               dummy = ReadDOC(docptr, Mplus_ECCConf);
+               dummy = ReadDOC(docptr, Mplus_ECCConf);
+               dummy = ReadDOC(docptr, Mplus_ECCConf);
+       } else {
+               dummy = ReadDOC(docptr, ECCConf);
+               dummy = ReadDOC(docptr, ECCConf);
+               dummy = ReadDOC(docptr, ECCConf);
+       }
+
+       /* Error occured ? */
+       if (dummy & 0x80) {
+               for (i = 0; i < 6; i++) {
+                       if (DoC_is_MillenniumPlus(doc))
+                               calc_ecc[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i);
+                       else
+                               calc_ecc[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
+                       if (calc_ecc[i] != empty_read_syndrome[i])
+                               emptymatch = 0;
+               }
+               /* If emptymatch=1, the read syndrome is consistent with an
+                  all-0xff data and stored ecc block.  Check the stored ecc. */
+               if (emptymatch) {
+                       for (i = 0; i < 6; i++) {
+                               if (read_ecc[i] == 0xff) continue;
+                               emptymatch = 0;
+                               break;
+                       }
+               }
+               /* If emptymatch still =1, check the data block. */
+               if (emptymatch) {
+               /* Note: this somewhat expensive test should not be triggered
+                  often.  It could be optimized away by examining the data in
+                  the readbuf routine, and remembering the result. */
+                       for (i = 0; i < 512; i++) {
+                               if (dat[i] == 0xff) continue;
+                               emptymatch = 0;
+                               break;
+                       }
+               }
+               /* If emptymatch still =1, this is almost certainly a freshly-
+                  erased block, in which case the ECC will not come out right.
+                  We'll suppress the error and tell the caller everything's
+                  OK.  Because it is. */
+               if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc);
+               if (ret > 0)
+                       printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret);
+       }
+       if (DoC_is_MillenniumPlus(doc))
+               WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
+       else
+               WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
+       if (no_ecc_failures && (ret == -1)) {
+               printk(KERN_ERR "suppressing ECC failure\n");
+               ret = 0;
+       }
+       return ret;
+}
+
+/*u_char mydatabuf[528]; */
+
+static struct nand_oobinfo doc200x_oobinfo = {
+       .useecc = MTD_NANDECC_AUTOPLACE,
+       .eccbytes = 6,
+       .eccpos = {0, 1, 2, 3, 4, 5},
+       .oobfree = { {8, 8} }
+};
+
+/* Find the (I)NFTL Media Header, and optionally also the mirror media header.
+   On sucessful return, buf will contain a copy of the media header for
+   further processing.  id is the string to scan for, and will presumably be
+   either "ANAND" or "BNAND".  If findmirror=1, also look for the mirror media
+   header.  The page #s of the found media headers are placed in mh0_page and
+   mh1_page in the DOC private structure. */
+static int __init find_media_headers(struct mtd_info *mtd, u_char *buf,
+                                    const char *id, int findmirror)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       unsigned offs, end = (MAX_MEDIAHEADER_SCAN << this->phys_erase_shift);
+       int ret;
+       size_t retlen;
+
+       end = min(end, mtd->size); /* paranoia */
+       for (offs = 0; offs < end; offs += mtd->erasesize) {
+               ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf);
+               if (retlen != mtd->oobblock) continue;
+               if (ret) {
+                       printk(KERN_WARNING "ECC error scanning DOC at 0x%x\n",
+                               offs);
+               }
+               if (memcmp(buf, id, 6)) continue;
+               printk(KERN_INFO "Found DiskOnChip %s Media Header at 0x%x\n", id, offs);
+               if (doc->mh0_page == -1) {
+                       doc->mh0_page = offs >> this->page_shift;
+                       if (!findmirror) return 1;
+                       continue;
+               }
+               doc->mh1_page = offs >> this->page_shift;
+               return 2;
+       }
+       if (doc->mh0_page == -1) {
+               printk(KERN_WARNING "DiskOnChip %s Media Header not found.\n", id);
+               return 0;
+       }
+       /* Only one mediaheader was found.  We want buf to contain a
+          mediaheader on return, so we'll have to re-read the one we found. */
+       offs = doc->mh0_page << this->page_shift;
+       ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf);
+       if (retlen != mtd->oobblock) {
+               /* Insanity.  Give up. */
+               printk(KERN_ERR "Read DiskOnChip Media Header once, but can't reread it???\n");
+               return 0;
+       }
+       return 1;
+}
+
+static inline int __init nftl_partscan(struct mtd_info *mtd,
+                               struct mtd_partition *parts)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       int ret = 0;
+       u_char *buf;
+       struct NFTLMediaHeader *mh;
+       const unsigned psize = 1 << this->page_shift;
+       unsigned blocks, maxblocks;
+       int offs, numheaders;
+
+       buf = kmalloc(mtd->oobblock, GFP_KERNEL);
+       if (!buf) {
+               printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n");
+               return 0;
+       }
+       if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) goto out;
+       mh = (struct NFTLMediaHeader *) buf;
+
+/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */
+/*     if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */
+       printk(KERN_INFO "    DataOrgID        = %s\n"
+                        "    NumEraseUnits    = %d\n"
+                        "    FirstPhysicalEUN = %d\n"
+                        "    FormattedSize    = %d\n"
+                        "    UnitSizeFactor   = %d\n",
+               mh->DataOrgID, mh->NumEraseUnits,
+               mh->FirstPhysicalEUN, mh->FormattedSize,
+               mh->UnitSizeFactor);
+/*#endif */
+
+       blocks = mtd->size >> this->phys_erase_shift;
+       maxblocks = min(32768U, mtd->erasesize - psize);
+
+       if (mh->UnitSizeFactor == 0x00) {
+               /* Auto-determine UnitSizeFactor.  The constraints are:
+                  - There can be at most 32768 virtual blocks.
+                  - There can be at most (virtual block size - page size)
+                    virtual blocks (because MediaHeader+BBT must fit in 1).
+               */
+               mh->UnitSizeFactor = 0xff;
+               while (blocks > maxblocks) {
+                       blocks >>= 1;
+                       maxblocks = min(32768U, (maxblocks << 1) + psize);
+                       mh->UnitSizeFactor--;
+               }
+               printk(KERN_WARNING "UnitSizeFactor=0x00 detected.  Correct value is assumed to be 0x%02x.\n", mh->UnitSizeFactor);
+       }
+
+       /* NOTE: The lines below modify internal variables of the NAND and MTD
+          layers; variables with have already been configured by nand_scan.
+          Unfortunately, we didn't know before this point what these values
+          should be.  Thus, this code is somewhat dependant on the exact
+          implementation of the NAND layer.  */
+       if (mh->UnitSizeFactor != 0xff) {
+               this->bbt_erase_shift += (0xff - mh->UnitSizeFactor);
+               mtd->erasesize <<= (0xff - mh->UnitSizeFactor);
+               printk(KERN_INFO "Setting virtual erase size to %d\n", mtd->erasesize);
+               blocks = mtd->size >> this->bbt_erase_shift;
+               maxblocks = min(32768U, mtd->erasesize - psize);
+       }
+
+       if (blocks > maxblocks) {
+               printk(KERN_ERR "UnitSizeFactor of 0x%02x is inconsistent with device size.  Aborting.\n", mh->UnitSizeFactor);
+               goto out;
+       }
+
+       /* Skip past the media headers. */
+       offs = max(doc->mh0_page, doc->mh1_page);
+       offs <<= this->page_shift;
+       offs += mtd->erasesize;
+
+       /*parts[0].name = " DiskOnChip Boot / Media Header partition"; */
+       /*parts[0].offset = 0; */
+       /*parts[0].size = offs; */
+
+       parts[0].name = " DiskOnChip BDTL partition";
+       parts[0].offset = offs;
+       parts[0].size = (mh->NumEraseUnits - numheaders) << this->bbt_erase_shift;
+
+       offs += parts[0].size;
+       if (offs < mtd->size) {
+               parts[1].name = " DiskOnChip Remainder partition";
+               parts[1].offset = offs;
+               parts[1].size = mtd->size - offs;
+               ret = 2;
+               goto out;
+       }
+       ret = 1;
+out:
+       kfree(buf);
+       return ret;
+}
+
+/* This is a stripped-down copy of the code in inftlmount.c */
+static inline int __init inftl_partscan(struct mtd_info *mtd,
+                                struct mtd_partition *parts)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       int ret = 0;
+       u_char *buf;
+       struct INFTLMediaHeader *mh;
+       struct INFTLPartition *ip;
+       int numparts = 0;
+       int blocks;
+       int vshift, lastvunit = 0;
+       int i;
+       int end = mtd->size;
+
+       if (inftl_bbt_write)
+               end -= (INFTL_BBT_RESERVED_BLOCKS << this->phys_erase_shift);
+
+       buf = kmalloc(mtd->oobblock, GFP_KERNEL);
+       if (!buf) {
+               printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n");
+               return 0;
+       }
+
+       if (!find_media_headers(mtd, buf, "BNAND", 0)) goto out;
+       doc->mh1_page = doc->mh0_page + (4096 >> this->page_shift);
+       mh = (struct INFTLMediaHeader *) buf;
+
+       mh->NoOfBootImageBlocks = le32_to_cpu(mh->NoOfBootImageBlocks);
+       mh->NoOfBinaryPartitions = le32_to_cpu(mh->NoOfBinaryPartitions);
+       mh->NoOfBDTLPartitions = le32_to_cpu(mh->NoOfBDTLPartitions);
+       mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits);
+       mh->FormatFlags = le32_to_cpu(mh->FormatFlags);
+       mh->PercentUsed = le32_to_cpu(mh->PercentUsed);
+
+/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */
+/*     if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */
+       printk(KERN_INFO "    bootRecordID          = %s\n"
+                        "    NoOfBootImageBlocks   = %d\n"
+                        "    NoOfBinaryPartitions  = %d\n"
+                        "    NoOfBDTLPartitions    = %d\n"
+                        "    BlockMultiplerBits    = %d\n"
+                        "    FormatFlgs            = %d\n"
+                        "    OsakVersion           = %d.%d.%d.%d\n"
+                        "    PercentUsed           = %d\n",
+               mh->bootRecordID, mh->NoOfBootImageBlocks,
+               mh->NoOfBinaryPartitions,
+               mh->NoOfBDTLPartitions,
+               mh->BlockMultiplierBits, mh->FormatFlags,
+               ((unsigned char *) &mh->OsakVersion)[0] & 0xf,
+               ((unsigned char *) &mh->OsakVersion)[1] & 0xf,
+               ((unsigned char *) &mh->OsakVersion)[2] & 0xf,
+               ((unsigned char *) &mh->OsakVersion)[3] & 0xf,
+               mh->PercentUsed);
+/*#endif */
+
+       vshift = this->phys_erase_shift + mh->BlockMultiplierBits;
+
+       blocks = mtd->size >> vshift;
+       if (blocks > 32768) {
+               printk(KERN_ERR "BlockMultiplierBits=%d is inconsistent with device size.  Aborting.\n", mh->BlockMultiplierBits);
+               goto out;
+       }
+
+       blocks = doc->chips_per_floor << (this->chip_shift - this->phys_erase_shift);
+       if (inftl_bbt_write && (blocks > mtd->erasesize)) {
+               printk(KERN_ERR "Writeable BBTs spanning more than one erase block are not yet supported.  FIX ME!\n");
+               goto out;
+       }
+
+       /* Scan the partitions */
+       for (i = 0; (i < 4); i++) {
+               ip = &(mh->Partitions[i]);
+               ip->virtualUnits = le32_to_cpu(ip->virtualUnits);
+               ip->firstUnit = le32_to_cpu(ip->firstUnit);
+               ip->lastUnit = le32_to_cpu(ip->lastUnit);
+               ip->flags = le32_to_cpu(ip->flags);
+               ip->spareUnits = le32_to_cpu(ip->spareUnits);
+               ip->Reserved0 = le32_to_cpu(ip->Reserved0);
+
+/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */
+/*             if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */
+               printk(KERN_INFO        "    PARTITION[%d] ->\n"
+                       "        virtualUnits    = %d\n"
+                       "        firstUnit       = %d\n"
+                       "        lastUnit        = %d\n"
+                       "        flags           = 0x%x\n"
+                       "        spareUnits      = %d\n",
+                       i, ip->virtualUnits, ip->firstUnit,
+                       ip->lastUnit, ip->flags,
+                       ip->spareUnits);
+/*#endif */
+
+/*
+               if ((i == 0) && (ip->firstUnit > 0)) {
+                       parts[0].name = " DiskOnChip IPL / Media Header partition";
+                       parts[0].offset = 0;
+                       parts[0].size = mtd->erasesize * ip->firstUnit;
+                       numparts = 1;
+               }
+*/
+
+               if (ip->flags & INFTL_BINARY)
+                       parts[numparts].name = " DiskOnChip BDK partition";
+               else
+                       parts[numparts].name = " DiskOnChip BDTL partition";
+               parts[numparts].offset = ip->firstUnit << vshift;
+               parts[numparts].size = (1 + ip->lastUnit - ip->firstUnit) << vshift;
+               numparts++;
+               if (ip->lastUnit > lastvunit) lastvunit = ip->lastUnit;
+               if (ip->flags & INFTL_LAST) break;
+       }
+       lastvunit++;
+       if ((lastvunit << vshift) < end) {
+               parts[numparts].name = " DiskOnChip Remainder partition";
+               parts[numparts].offset = lastvunit << vshift;
+               parts[numparts].size = end - parts[numparts].offset;
+               numparts++;
+       }
+       ret = numparts;
+out:
+       kfree(buf);
+       return ret;
+}
+
+static int __init nftl_scan_bbt(struct mtd_info *mtd)
+{
+       int ret, numparts;
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       struct mtd_partition parts[2];
+
+       memset((char *) parts, 0, sizeof(parts));
+       /* On NFTL, we have to find the media headers before we can read the
+          BBTs, since they're stored in the media header eraseblocks. */
+       numparts = nftl_partscan(mtd, parts);
+       if (!numparts) return -EIO;
+       this->bbt_td->options = NAND_BBT_ABSPAGE | NAND_BBT_8BIT |
+                               NAND_BBT_SAVECONTENT | NAND_BBT_WRITE |
+                               NAND_BBT_VERSION;
+       this->bbt_td->veroffs = 7;
+       this->bbt_td->pages[0] = doc->mh0_page + 1;
+       if (doc->mh1_page != -1) {
+               this->bbt_md->options = NAND_BBT_ABSPAGE | NAND_BBT_8BIT |
+                                       NAND_BBT_SAVECONTENT | NAND_BBT_WRITE |
+                                       NAND_BBT_VERSION;
+               this->bbt_md->veroffs = 7;
+               this->bbt_md->pages[0] = doc->mh1_page + 1;
+       } else {
+               this->bbt_md = NULL;
+       }
+
+       /* It's safe to set bd=NULL below because NAND_BBT_CREATE is not set.
+          At least as nand_bbt.c is currently written. */
+       if ((ret = nand_scan_bbt(mtd, NULL)))
+               return ret;
+       add_mtd_device(mtd);
+#ifdef CONFIG_MTD_PARTITIONS
+       if (!no_autopart)
+               add_mtd_partitions(mtd, parts, numparts);
+#endif
+       return 0;
+}
+
+static int __init inftl_scan_bbt(struct mtd_info *mtd)
+{
+       int ret, numparts;
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+       struct mtd_partition parts[5];
+
+       if (this->numchips > doc->chips_per_floor) {
+               printk(KERN_ERR "Multi-floor INFTL devices not yet supported.\n");
+               return -EIO;
+       }
+
+       if (DoC_is_MillenniumPlus(doc)) {
+               this->bbt_td->options = NAND_BBT_2BIT | NAND_BBT_ABSPAGE;
+               if (inftl_bbt_write)
+                       this->bbt_td->options |= NAND_BBT_WRITE;
+               this->bbt_td->pages[0] = 2;
+               this->bbt_md = NULL;
+       } else {
+               this->bbt_td->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT |
+                                       NAND_BBT_VERSION;
+               if (inftl_bbt_write)
+                       this->bbt_td->options |= NAND_BBT_WRITE;
+               this->bbt_td->offs = 8;
+               this->bbt_td->len = 8;
+               this->bbt_td->veroffs = 7;
+               this->bbt_td->maxblocks = INFTL_BBT_RESERVED_BLOCKS;
+               this->bbt_td->reserved_block_code = 0x01;
+               this->bbt_td->pattern = "MSYS_BBT";
+
+               this->bbt_md->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT |
+                                       NAND_BBT_VERSION;
+               if (inftl_bbt_write)
+                       this->bbt_md->options |= NAND_BBT_WRITE;
+               this->bbt_md->offs = 8;
+               this->bbt_md->len = 8;
+               this->bbt_md->veroffs = 7;
+               this->bbt_md->maxblocks = INFTL_BBT_RESERVED_BLOCKS;
+               this->bbt_md->reserved_block_code = 0x01;
+               this->bbt_md->pattern = "TBB_SYSM";
+       }
+
+       /* It's safe to set bd=NULL below because NAND_BBT_CREATE is not set.
+          At least as nand_bbt.c is currently written. */
+       if ((ret = nand_scan_bbt(mtd, NULL)))
+               return ret;
+       memset((char *) parts, 0, sizeof(parts));
+       numparts = inftl_partscan(mtd, parts);
+       /* At least for now, require the INFTL Media Header.  We could probably
+          do without it for non-INFTL use, since all it gives us is
+          autopartitioning, but I want to give it more thought. */
+       if (!numparts) return -EIO;
+       add_mtd_device(mtd);
+#ifdef CONFIG_MTD_PARTITIONS
+       if (!no_autopart)
+               add_mtd_partitions(mtd, parts, numparts);
+#endif
+       return 0;
+}
+
+static inline int __init doc2000_init(struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+
+       this->write_byte = doc2000_write_byte;
+       this->read_byte = doc2000_read_byte;
+       this->write_buf = doc2000_writebuf;
+       this->read_buf = doc2000_readbuf;
+       this->verify_buf = doc2000_verifybuf;
+       this->scan_bbt = nftl_scan_bbt;
+
+       doc->CDSNControl = CDSN_CTRL_FLASH_IO | CDSN_CTRL_ECC_IO;
+       doc2000_count_chips(mtd);
+       mtd->name = "DiskOnChip 2000 (NFTL Model)";
+       return (4 * doc->chips_per_floor);
+}
+
+static inline int __init doc2001_init(struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+
+       this->write_byte = doc2001_write_byte;
+       this->read_byte = doc2001_read_byte;
+       this->write_buf = doc2001_writebuf;
+       this->read_buf = doc2001_readbuf;
+       this->verify_buf = doc2001_verifybuf;
+
+       ReadDOC(doc->virtadr, ChipID);
+       ReadDOC(doc->virtadr, ChipID);
+       ReadDOC(doc->virtadr, ChipID);
+       if (ReadDOC(doc->virtadr, ChipID) != DOC_ChipID_DocMil) {
+               /* It's not a Millennium; it's one of the newer
+                  DiskOnChip 2000 units with a similar ASIC.
+                  Treat it like a Millennium, except that it
+                  can have multiple chips. */
+               doc2000_count_chips(mtd);
+               mtd->name = "DiskOnChip 2000 (INFTL Model)";
+               this->scan_bbt = inftl_scan_bbt;
+               return (4 * doc->chips_per_floor);
+       } else {
+               /* Bog-standard Millennium */
+               doc->chips_per_floor = 1;
+               mtd->name = "DiskOnChip Millennium";
+               this->scan_bbt = nftl_scan_bbt;
+               return 1;
+       }
+}
+
+static inline int __init doc2001plus_init(struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+       struct doc_priv *doc = this->priv;
+
+       this->write_byte = NULL;
+       this->read_byte = doc2001plus_read_byte;
+       this->write_buf = doc2001plus_writebuf;
+       this->read_buf = doc2001plus_readbuf;
+       this->verify_buf = doc2001plus_verifybuf;
+       this->scan_bbt = inftl_scan_bbt;
+       this->hwcontrol = NULL;
+       this->select_chip = doc2001plus_select_chip;
+       this->cmdfunc = doc2001plus_command;
+       this->enable_hwecc = doc2001plus_enable_hwecc;
+
+       doc->chips_per_floor = 1;
+       mtd->name = "DiskOnChip Millennium Plus";
+
+       return 1;
+}
+
+static inline int __init doc_probe(unsigned long physadr)
+{
+       unsigned char ChipID;
+       struct mtd_info *mtd;
+       struct nand_chip *nand;
+       struct doc_priv *doc;
+       void __iomem *virtadr;
+       unsigned char save_control;
+       unsigned char tmp, tmpb, tmpc;
+       int reg, len, numchips;
+       int ret = 0;
+
+       virtadr = ioremap(physadr, DOC_IOREMAP_LEN);
+       if (!virtadr) {
+               printk(KERN_ERR "Diskonchip ioremap failed: 0x%x bytes at 0x%lx\n", DOC_IOREMAP_LEN, physadr);
+               return -EIO;
+       }
+
+       /* It's not possible to cleanly detect the DiskOnChip - the
+        * bootup procedure will put the device into reset mode, and
+        * it's not possible to talk to it without actually writing
+        * to the DOCControl register. So we store the current contents
+        * of the DOCControl register's location, in case we later decide
+        * that it's not a DiskOnChip, and want to put it back how we
+        * found it.
+        */
+       save_control = ReadDOC(virtadr, DOCControl);
+
+       /* Reset the DiskOnChip ASIC */
+       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
+                virtadr, DOCControl);
+       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
+                virtadr, DOCControl);
+
+       /* Enable the DiskOnChip ASIC */
+       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
+                virtadr, DOCControl);
+       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
+                virtadr, DOCControl);
+
+       ChipID = ReadDOC(virtadr, ChipID);
+
+       switch(ChipID) {
+       case DOC_ChipID_Doc2k:
+               reg = DoC_2k_ECCStatus;
+               break;
+       case DOC_ChipID_DocMil:
+               reg = DoC_ECCConf;
+               break;
+       case DOC_ChipID_DocMilPlus16:
+       case DOC_ChipID_DocMilPlus32:
+       case 0:
+               /* Possible Millennium Plus, need to do more checks */
+               /* Possibly release from power down mode */
+               for (tmp = 0; (tmp < 4); tmp++)
+                       ReadDOC(virtadr, Mplus_Power);
+
+               /* Reset the Millennium Plus ASIC */
+               tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
+                       DOC_MODE_BDECT;
+               WriteDOC(tmp, virtadr, Mplus_DOCControl);
+               WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm);
+
+               mdelay(1);
+               /* Enable the Millennium Plus ASIC */
+               tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
+                       DOC_MODE_BDECT;
+               WriteDOC(tmp, virtadr, Mplus_DOCControl);
+               WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm);
+               mdelay(1);
+
+               ChipID = ReadDOC(virtadr, ChipID);
+
+               switch (ChipID) {
+               case DOC_ChipID_DocMilPlus16:
+                       reg = DoC_Mplus_Toggle;
+                       break;
+               case DOC_ChipID_DocMilPlus32:
+                       printk(KERN_ERR "DiskOnChip Millennium Plus 32MB is not supported, ignoring.\n");
+               default:
+                       ret = -ENODEV;
+                       goto notfound;
+               }
+               break;
+
+       default:
+               ret = -ENODEV;
+               goto notfound;
+       }
+       /* Check the TOGGLE bit in the ECC register */
+       tmp  = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;
+       tmpb = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;
+       tmpc = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;
+       if ((tmp == tmpb) || (tmp != tmpc)) {
+               printk(KERN_WARNING "Possible DiskOnChip at 0x%lx failed TOGGLE test, dropping.\n", physadr);
+               ret = -ENODEV;
+               goto notfound;
+       }
+
+       for (mtd = doclist; mtd; mtd = doc->nextdoc) {
+               unsigned char oldval;
+               unsigned char newval;
+               nand = mtd->priv;
+               doc = nand->priv;
+               /* Use the alias resolution register to determine if this is
+                  in fact the same DOC aliased to a new address.  If writes
+                  to one chip's alias resolution register change the value on
+                  the other chip, they're the same chip. */
+               if (ChipID == DOC_ChipID_DocMilPlus16) {
+                       oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution);
+                       newval = ReadDOC(virtadr, Mplus_AliasResolution);
+               } else {
+                       oldval = ReadDOC(doc->virtadr, AliasResolution);
+                       newval = ReadDOC(virtadr, AliasResolution);
+               }
+               if (oldval != newval)
+                       continue;
+               if (ChipID == DOC_ChipID_DocMilPlus16) {
+                       WriteDOC(~newval, virtadr, Mplus_AliasResolution);
+                       oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution);
+                       WriteDOC(newval, virtadr, Mplus_AliasResolution); /* restore it */
+               } else {
+                       WriteDOC(~newval, virtadr, AliasResolution);
+                       oldval = ReadDOC(doc->virtadr, AliasResolution);
+                       WriteDOC(newval, virtadr, AliasResolution); /* restore it */
+               }
+               newval = ~newval;
+               if (oldval == newval) {
+                       printk(KERN_DEBUG "Found alias of DOC at 0x%lx to 0x%lx\n", doc->physadr, physadr);
+                       goto notfound;
+               }
+       }
+
+       printk(KERN_NOTICE "DiskOnChip found at 0x%lx\n", physadr);
+
+       len = sizeof(struct mtd_info) +
+             sizeof(struct nand_chip) +
+             sizeof(struct doc_priv) +
+             (2 * sizeof(struct nand_bbt_descr));
+       mtd =  kmalloc(len, GFP_KERNEL);
+       if (!mtd) {
+               printk(KERN_ERR "DiskOnChip kmalloc (%d bytes) failed!\n", len);
+               ret = -ENOMEM;
+               goto fail;
+       }
+       memset(mtd, 0, len);
+
+       nand                    = (struct nand_chip *) (mtd + 1);
+       doc                     = (struct doc_priv *) (nand + 1);
+       nand->bbt_td            = (struct nand_bbt_descr *) (doc + 1);
+       nand->bbt_md            = nand->bbt_td + 1;
+
+       mtd->priv               = nand;
+       mtd->owner              = THIS_MODULE;
+
+       nand->priv              = doc;
+       nand->select_chip       = doc200x_select_chip;
+       nand->hwcontrol         = doc200x_hwcontrol;
+       nand->dev_ready         = doc200x_dev_ready;
+       nand->waitfunc          = doc200x_wait;
+       nand->block_bad         = doc200x_block_bad;
+       nand->enable_hwecc      = doc200x_enable_hwecc;
+       nand->calculate_ecc     = doc200x_calculate_ecc;
+       nand->correct_data      = doc200x_correct_data;
+
+       nand->autooob           = &doc200x_oobinfo;
+       nand->eccmode           = NAND_ECC_HW6_512;
+       nand->options           = NAND_USE_FLASH_BBT | NAND_HWECC_SYNDROME;
+
+       doc->physadr            = physadr;
+       doc->virtadr            = virtadr;
+       doc->ChipID             = ChipID;
+       doc->curfloor           = -1;
+       doc->curchip            = -1;
+       doc->mh0_page           = -1;
+       doc->mh1_page           = -1;
+       doc->nextdoc            = doclist;
+
+       if (ChipID == DOC_ChipID_Doc2k)
+               numchips = doc2000_init(mtd);
+       else if (ChipID == DOC_ChipID_DocMilPlus16)
+               numchips = doc2001plus_init(mtd);
+       else
+               numchips = doc2001_init(mtd);
+
+       if ((ret = nand_scan(mtd, numchips))) {
+               /* DBB note: i believe nand_release is necessary here, as
+                  buffers may have been allocated in nand_base.  Check with
+                  Thomas. FIX ME! */
+               /* nand_release will call del_mtd_device, but we haven't yet
+                  added it.  This is handled without incident by
+                  del_mtd_device, as far as I can tell. */
+               nand_release(mtd);
+               kfree(mtd);
+               goto fail;
+       }
+
+       /* Success! */
+       doclist = mtd;
+       return 0;
+
+notfound:
+       /* Put back the contents of the DOCControl register, in case it's not
+          actually a DiskOnChip.  */
+       WriteDOC(save_control, virtadr, DOCControl);
+fail:
+       iounmap(virtadr);
+       return ret;
+}
+
+static void release_nanddoc(void)
+{
+       struct mtd_info *mtd, *nextmtd;
+       struct nand_chip *nand;
+       struct doc_priv *doc;
+
+       for (mtd = doclist; mtd; mtd = nextmtd) {
+               nand = mtd->priv;
+               doc = nand->priv;
+
+               nextmtd = doc->nextdoc;
+               nand_release(mtd);
+               iounmap(doc->virtadr);
+               kfree(mtd);
+       }
+}
+
+static int __init init_nanddoc(void)
+{
+       int i, ret = 0;
+
+       /* We could create the decoder on demand, if memory is a concern.
+        * This way we have it handy, if an error happens
+        *
+        * Symbolsize is 10 (bits)
+        * Primitve polynomial is x^10+x^3+1
+        * first consecutive root is 510
+        * primitve element to generate roots = 1
+        * generator polinomial degree = 4
+        */
+       rs_decoder = init_rs(10, 0x409, FCR, 1, NROOTS);
+       if (!rs_decoder) {
+               printk (KERN_ERR "DiskOnChip: Could not create a RS decoder\n");
+               return -ENOMEM;
+       }
+
+       if (doc_config_location) {
+               printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location);
+               ret = doc_probe(doc_config_location);
+               if (ret < 0)
+                       goto outerr;
+       } else {
+               for (i=0; (doc_locations[i] != 0xffffffff); i++) {
+                       doc_probe(doc_locations[i]);
+               }
+       }
+       /* No banner message any more. Print a message if no DiskOnChip
+          found, so the user knows we at least tried. */
+       if (!doclist) {
+               printk(KERN_INFO "No valid DiskOnChip devices found\n");
+               ret = -ENODEV;
+               goto outerr;
+       }
+       return 0;
+outerr:
+       free_rs(rs_decoder);
+       return ret;
+}
+
+static void __exit cleanup_nanddoc(void)
+{
+       /* Cleanup the nand/DoC resources */
+       release_nanddoc();
+
+       /* Free the reed solomon resources */
+       if (rs_decoder) {
+               free_rs(rs_decoder);
+       }
+}
+
+module_init(init_nanddoc);
+module_exit(cleanup_nanddoc);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver\n");
+#endif
diff --git a/drivers/mtd/nand/nand.c b/drivers/mtd/nand/nand.c
new file mode 100644 (file)
index 0000000..27b5792
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * (C) Copyright 2005
+ * 2N Telekomunikace, a.s. <www.2n.cz>
+ * Ladislav Michl <michl@2n.cz>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
+
+#include <nand.h>
+
+#ifndef CFG_NAND_BASE_LIST
+#define CFG_NAND_BASE_LIST { CFG_NAND_BASE }
+#endif
+
+int nand_curr_device = -1;
+nand_info_t nand_info[CFG_MAX_NAND_DEVICE];
+
+static struct nand_chip nand_chip[CFG_MAX_NAND_DEVICE];
+static ulong base_address[CFG_MAX_NAND_DEVICE] = CFG_NAND_BASE_LIST;
+
+static const char default_nand_name[] = "nand";
+
+extern int board_nand_init(struct nand_chip *nand);
+
+static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand,
+                          ulong base_addr)
+{
+       mtd->priv = nand;
+
+       nand->IO_ADDR_R = nand->IO_ADDR_W = (void  __iomem *)base_addr;
+       if (board_nand_init(nand) == 0) {
+               if (nand_scan(mtd, 1) == 0) {
+                       if (!mtd->name)
+                               mtd->name = (char *)default_nand_name;
+               } else
+                       mtd->name = NULL;
+       } else {
+               mtd->name = NULL;
+               mtd->size = 0;
+       }
+
+}
+
+void nand_init(void)
+{
+       int i;
+       unsigned int size = 0;
+       for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {
+               nand_init_chip(&nand_info[i], &nand_chip[i], base_address[i]);
+               size += nand_info[i].size;
+               if (nand_curr_device == -1)
+                       nand_curr_device = i;
+       }
+       printf("%lu MiB\n", size / (1024 * 1024));
+
+#ifdef CFG_NAND_SELECT_DEVICE
+       /*
+        * Select the chip in the board/cpu specific driver
+        */
+       board_nand_select_device(nand_info[nand_curr_device].priv, nand_curr_device);
+#endif
+}
+
+#endif
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
new file mode 100644 (file)
index 0000000..151f535
--- /dev/null
@@ -0,0 +1,2668 @@
+/*
+ *  drivers/mtd/nand.c
+ *
+ *  Overview:
+ *   This is the generic MTD driver for NAND flash devices. It should be
+ *   capable of working with almost all NAND chips currently available.
+ *   Basic support for AG-AND chips is provided.
+ *
+ *     Additional technical information is available on
+ *     http://www.linux-mtd.infradead.org/tech/nand.html
+ *
+ *  Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
+ *               2002 Thomas Gleixner (tglx@linutronix.de)
+ *
+ *  02-08-2004  tglx: support for strange chips, which cannot auto increment
+ *             pages on read / read_oob
+ *
+ *  03-17-2004  tglx: Check ready before auto increment check. Simon Bayes
+ *             pointed this out, as he marked an auto increment capable chip
+ *             as NOAUTOINCR in the board driver.
+ *             Make reads over block boundaries work too
+ *
+ *  04-14-2004 tglx: first working version for 2k page size chips
+ *
+ *  05-19-2004  tglx: Basic support for Renesas AG-AND chips
+ *
+ *  09-24-2004  tglx: add support for hardware controllers (e.g. ECC) shared
+ *             among multiple independend devices. Suggestions and initial patch
+ *             from Ben Dooks <ben-mtd@fluff.org>
+ *
+ * Credits:
+ *     David Woodhouse for adding multichip support
+ *
+ *     Aleph One Ltd. and Toby Churchill Ltd. for supporting the
+ *     rework for 2K page size chips
+ *
+ * TODO:
+ *     Enable cached programming for 2k page size chips
+ *     Check, if mtd->ecctype should be set to MTD_ECC_HW
+ *     if we have HW ecc support.
+ *     The AG-AND chips have nice features for speed improvement,
+ *     which are not supported yet. Read / program 4 pages in one go.
+ *
+ * $Id: nand_base.c,v 1.126 2004/12/13 11:22:25 lavinen Exp $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/* XXX U-BOOT XXX */
+#if 0
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/compatmac.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_MTD_PARTITIONS
+#include <linux/mtd/partitions.h>
+#endif
+
+#endif
+
+#include <common.h>
+
+#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
+
+#include <malloc.h>
+#include <watchdog.h>
+#include <linux/mtd/compat.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+
+#include <asm/io.h>
+#include <asm/errno.h>
+
+#ifdef CONFIG_JFFS2_NAND
+#include <jffs2/jffs2.h>
+#endif
+
+/* Define default oob placement schemes for large and small page devices */
+static struct nand_oobinfo nand_oob_8 = {
+       .useecc = MTD_NANDECC_AUTOPLACE,
+       .eccbytes = 3,
+       .eccpos = {0, 1, 2},
+       .oobfree = { {3, 2}, {6, 2} }
+};
+
+static struct nand_oobinfo nand_oob_16 = {
+       .useecc = MTD_NANDECC_AUTOPLACE,
+       .eccbytes = 6,
+       .eccpos = {0, 1, 2, 3, 6, 7},
+       .oobfree = { {8, 8} }
+};
+
+static struct nand_oobinfo nand_oob_64 = {
+       .useecc = MTD_NANDECC_AUTOPLACE,
+       .eccbytes = 24,
+       .eccpos = {
+               40, 41, 42, 43, 44, 45, 46, 47,
+               48, 49, 50, 51, 52, 53, 54, 55,
+               56, 57, 58, 59, 60, 61, 62, 63},
+       .oobfree = { {2, 38} }
+};
+
+/* This is used for padding purposes in nand_write_oob */
+static u_char ffchars[] = {
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+
+/*
+ * NAND low-level MTD interface functions
+ */
+static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len);
+static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len);
+static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len);
+
+static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
+static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
+                         size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
+static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
+static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf);
+static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
+                          size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
+static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char *buf);
+/* XXX U-BOOT XXX */
+#if 0
+static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs,
+                       unsigned long count, loff_t to, size_t * retlen);
+static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs,
+                       unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
+#endif
+static int nand_erase (struct mtd_info *mtd, struct erase_info *instr);
+static void nand_sync (struct mtd_info *mtd);
+
+/* Some internal functions */
+static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf,
+               struct nand_oobinfo *oobsel, int mode);
+#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
+static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
+       u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode);
+#else
+#define nand_verify_pages(...) (0)
+#endif
+
+static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state);
+
+/**
+ * nand_release_device - [GENERIC] release chip
+ * @mtd:       MTD device structure
+ *
+ * Deselect, release chip lock and wake up anyone waiting on the device
+ */
+/* XXX U-BOOT XXX */
+#if 0
+static void nand_release_device (struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+
+       /* De-select the NAND device */
+       this->select_chip(mtd, -1);
+       /* Do we have a hardware controller ? */
+       if (this->controller) {
+               spin_lock(&this->controller->lock);
+               this->controller->active = NULL;
+               spin_unlock(&this->controller->lock);
+       }
+       /* Release the chip */
+       spin_lock (&this->chip_lock);
+       this->state = FL_READY;
+       wake_up (&this->wq);
+       spin_unlock (&this->chip_lock);
+}
+#else
+static void nand_release_device (struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+       this->select_chip(mtd, -1);     /* De-select the NAND device */
+}
+#endif
+
+/**
+ * nand_read_byte - [DEFAULT] read one byte from the chip
+ * @mtd:       MTD device structure
+ *
+ * Default read function for 8bit buswith
+ */
+static u_char nand_read_byte(struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+       return readb(this->IO_ADDR_R);
+}
+
+/**
+ * nand_write_byte - [DEFAULT] write one byte to the chip
+ * @mtd:       MTD device structure
+ * @byte:      pointer to data byte to write
+ *
+ * Default write function for 8it buswith
+ */
+static void nand_write_byte(struct mtd_info *mtd, u_char byte)
+{
+       struct nand_chip *this = mtd->priv;
+       writeb(byte, this->IO_ADDR_W);
+}
+
+/**
+ * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
+ * @mtd:       MTD device structure
+ *
+ * Default read function for 16bit buswith with
+ * endianess conversion
+ */
+static u_char nand_read_byte16(struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+       return (u_char) cpu_to_le16(readw(this->IO_ADDR_R));
+}
+
+/**
+ * nand_write_byte16 - [DEFAULT] write one byte endianess aware to the chip
+ * @mtd:       MTD device structure
+ * @byte:      pointer to data byte to write
+ *
+ * Default write function for 16bit buswith with
+ * endianess conversion
+ */
+static void nand_write_byte16(struct mtd_info *mtd, u_char byte)
+{
+       struct nand_chip *this = mtd->priv;
+       writew(le16_to_cpu((u16) byte), this->IO_ADDR_W);
+}
+
+/**
+ * nand_read_word - [DEFAULT] read one word from the chip
+ * @mtd:       MTD device structure
+ *
+ * Default read function for 16bit buswith without
+ * endianess conversion
+ */
+static u16 nand_read_word(struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+       return readw(this->IO_ADDR_R);
+}
+
+/**
+ * nand_write_word - [DEFAULT] write one word to the chip
+ * @mtd:       MTD device structure
+ * @word:      data word to write
+ *
+ * Default write function for 16bit buswith without
+ * endianess conversion
+ */
+static void nand_write_word(struct mtd_info *mtd, u16 word)
+{
+       struct nand_chip *this = mtd->priv;
+       writew(word, this->IO_ADDR_W);
+}
+
+/**
+ * nand_select_chip - [DEFAULT] control CE line
+ * @mtd:       MTD device structure
+ * @chip:      chipnumber to select, -1 for deselect
+ *
+ * Default select function for 1 chip devices.
+ */
+static void nand_select_chip(struct mtd_info *mtd, int chip)
+{
+       struct nand_chip *this = mtd->priv;
+       switch(chip) {
+       case -1:
+               this->hwcontrol(mtd, NAND_CTL_CLRNCE);
+               break;
+       case 0:
+               this->hwcontrol(mtd, NAND_CTL_SETNCE);
+               break;
+
+       default:
+               BUG();
+       }
+}
+
+/**
+ * nand_write_buf - [DEFAULT] write buffer to chip
+ * @mtd:       MTD device structure
+ * @buf:       data buffer
+ * @len:       number of bytes to write
+ *
+ * Default write function for 8bit buswith
+ */
+static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+       int i;
+       struct nand_chip *this = mtd->priv;
+
+       for (i=0; i<len; i++)
+               writeb(buf[i], this->IO_ADDR_W);
+}
+
+/**
+ * nand_read_buf - [DEFAULT] read chip data into buffer
+ * @mtd:       MTD device structure
+ * @buf:       buffer to store date
+ * @len:       number of bytes to read
+ *
+ * Default read function for 8bit buswith
+ */
+static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+       int i;
+       struct nand_chip *this = mtd->priv;
+
+       for (i=0; i<len; i++)
+               buf[i] = readb(this->IO_ADDR_R);
+}
+
+/**
+ * nand_verify_buf - [DEFAULT] Verify chip data against buffer
+ * @mtd:       MTD device structure
+ * @buf:       buffer containing the data to compare
+ * @len:       number of bytes to compare
+ *
+ * Default verify function for 8bit buswith
+ */
+static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+       int i;
+       struct nand_chip *this = mtd->priv;
+
+       for (i=0; i<len; i++)
+               if (buf[i] != readb(this->IO_ADDR_R))
+                       return -EFAULT;
+
+       return 0;
+}
+
+/**
+ * nand_write_buf16 - [DEFAULT] write buffer to chip
+ * @mtd:       MTD device structure
+ * @buf:       data buffer
+ * @len:       number of bytes to write
+ *
+ * Default write function for 16bit buswith
+ */
+static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
+{
+       int i;
+       struct nand_chip *this = mtd->priv;
+       u16 *p = (u16 *) buf;
+       len >>= 1;
+
+       for (i=0; i<len; i++)
+               writew(p[i], this->IO_ADDR_W);
+
+}
+
+/**
+ * nand_read_buf16 - [DEFAULT] read chip data into buffer
+ * @mtd:       MTD device structure
+ * @buf:       buffer to store date
+ * @len:       number of bytes to read
+ *
+ * Default read function for 16bit buswith
+ */
+static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
+{
+       int i;
+       struct nand_chip *this = mtd->priv;
+       u16 *p = (u16 *) buf;
+       len >>= 1;
+
+       for (i=0; i<len; i++)
+               p[i] = readw(this->IO_ADDR_R);
+}
+
+/**
+ * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
+ * @mtd:       MTD device structure
+ * @buf:       buffer containing the data to compare
+ * @len:       number of bytes to compare
+ *
+ * Default verify function for 16bit buswith
+ */
+static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
+{
+       int i;
+       struct nand_chip *this = mtd->priv;
+       u16 *p = (u16 *) buf;
+       len >>= 1;
+
+       for (i=0; i<len; i++)
+               if (p[i] != readw(this->IO_ADDR_R))
+                       return -EFAULT;
+
+       return 0;
+}
+
+/**
+ * nand_block_bad - [DEFAULT] Read bad block marker from the chip
+ * @mtd:       MTD device structure
+ * @ofs:       offset from device start
+ * @getchip:   0, if the chip is already selected
+ *
+ * Check, if the block is bad.
+ */
+static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
+{
+       int page, chipnr, res = 0;
+       struct nand_chip *this = mtd->priv;
+       u16 bad;
+
+       page = (int)(ofs >> this->page_shift) & this->pagemask;
+
+       if (getchip) {
+               chipnr = (int)(ofs >> this->chip_shift);
+
+               /* Grab the lock and see if the device is available */
+               nand_get_device (this, mtd, FL_READING);
+
+               /* Select the NAND device */
+               this->select_chip(mtd, chipnr);
+       }
+
+       if (this->options & NAND_BUSWIDTH_16) {
+               this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page);
+               bad = cpu_to_le16(this->read_word(mtd));
+               if (this->badblockpos & 0x1)
+                       bad >>= 1;
+               if ((bad & 0xFF) != 0xff)
+                       res = 1;
+       } else {
+               this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos, page);
+               if (this->read_byte(mtd) != 0xff)
+                       res = 1;
+       }
+
+       if (getchip) {
+               /* Deselect and wake up anyone waiting on the device */
+               nand_release_device(mtd);
+       }
+
+       return res;
+}
+
+/**
+ * nand_default_block_markbad - [DEFAULT] mark a block bad
+ * @mtd:       MTD device structure
+ * @ofs:       offset from device start
+ *
+ * This is the default implementation, which can be overridden by
+ * a hardware specific driver.
+*/
+static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
+{
+       struct nand_chip *this = mtd->priv;
+       u_char buf[2] = {0, 0};
+       size_t  retlen;
+       int block;
+
+       /* Get block number */
+       block = ((int) ofs) >> this->bbt_erase_shift;
+       this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
+
+       /* Do we have a flash based bad block table ? */
+       if (this->options & NAND_USE_FLASH_BBT)
+               return nand_update_bbt (mtd, ofs);
+
+       /* We write two bytes, so we dont have to mess with 16 bit access */
+       ofs += mtd->oobsize + (this->badblockpos & ~0x01);
+       return nand_write_oob (mtd, ofs , 2, &retlen, buf);
+}
+
+/**
+ * nand_check_wp - [GENERIC] check if the chip is write protected
+ * @mtd:       MTD device structure
+ * Check, if the device is write protected
+ *
+ * The function expects, that the device is already selected
+ */
+static int nand_check_wp (struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+       /* Check the WP bit */
+       this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
+       return (this->read_byte(mtd) & 0x80) ? 0 : 1;
+}
+
+/**
+ * nand_block_checkbad - [GENERIC] Check if a block is marked bad
+ * @mtd:       MTD device structure
+ * @ofs:       offset from device start
+ * @getchip:   0, if the chip is already selected
+ * @allowbbt:  1, if its allowed to access the bbt area
+ *
+ * Check, if the block is bad. Either by reading the bad block table or
+ * calling of the scan function.
+ */
+static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
+{
+       struct nand_chip *this = mtd->priv;
+
+       if (!this->bbt)
+               return this->block_bad(mtd, ofs, getchip);
+
+       /* Return info from the table */
+       return nand_isbad_bbt (mtd, ofs, allowbbt);
+}
+
+/**
+ * nand_command - [DEFAULT] Send command to NAND device
+ * @mtd:       MTD device structure
+ * @command:   the command to be sent
+ * @column:    the column address for this command, -1 if none
+ * @page_addr: the page address for this command, -1 if none
+ *
+ * Send command to NAND device. This function is used for small page
+ * devices (256/512 Bytes per page)
+ */
+static void nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
+{
+       register struct nand_chip *this = mtd->priv;
+
+       /* Begin command latch cycle */
+       this->hwcontrol(mtd, NAND_CTL_SETCLE);
+       /*
+        * Write out the command to the device.
+        */
+       if (command == NAND_CMD_SEQIN) {
+               int readcmd;
+
+               if (column >= mtd->oobblock) {
+                       /* OOB area */
+                       column -= mtd->oobblock;
+                       readcmd = NAND_CMD_READOOB;
+               } else if (column < 256) {
+                       /* First 256 bytes --> READ0 */
+                       readcmd = NAND_CMD_READ0;
+               } else {
+                       column -= 256;
+                       readcmd = NAND_CMD_READ1;
+               }
+               this->write_byte(mtd, readcmd);
+       }
+       this->write_byte(mtd, command);
+
+       /* Set ALE and clear CLE to start address cycle */
+       this->hwcontrol(mtd, NAND_CTL_CLRCLE);
+
+       if (column != -1 || page_addr != -1) {
+               this->hwcontrol(mtd, NAND_CTL_SETALE);
+
+               /* Serially input address */
+               if (column != -1) {
+                       /* Adjust columns for 16 bit buswidth */
+                       if (this->options & NAND_BUSWIDTH_16)
+                               column >>= 1;
+                       this->write_byte(mtd, column);
+               }
+               if (page_addr != -1) {
+                       this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
+                       this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
+                       /* One more address cycle for devices > 32MiB */
+                       if (this->chipsize > (32 << 20))
+                               this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
+               }
+               /* Latch in address */
+               this->hwcontrol(mtd, NAND_CTL_CLRALE);
+       }
+
+       /*
+        * program and erase have their own busy handlers
+        * status and sequential in needs no delay
+       */
+       switch (command) {
+
+       case NAND_CMD_PAGEPROG:
+       case NAND_CMD_ERASE1:
+       case NAND_CMD_ERASE2:
+       case NAND_CMD_SEQIN:
+       case NAND_CMD_STATUS:
+               return;
+
+       case NAND_CMD_RESET:
+               if (this->dev_ready)
+                       break;
+               udelay(this->chip_delay);
+               this->hwcontrol(mtd, NAND_CTL_SETCLE);
+               this->write_byte(mtd, NAND_CMD_STATUS);
+               this->hwcontrol(mtd, NAND_CTL_CLRCLE);
+               while ( !(this->read_byte(mtd) & 0x40));
+               return;
+
+       /* This applies to read commands */
+       default:
+               /*
+                * If we don't have access to the busy pin, we apply the given
+                * command delay
+               */
+               if (!this->dev_ready) {
+                       udelay (this->chip_delay);
+                       return;
+               }
+       }
+
+       /* Apply this short delay always to ensure that we do wait tWB in
+        * any case on any machine. */
+       ndelay (100);
+       /* wait until command is processed */
+       while (!this->dev_ready(mtd));
+}
+
+/**
+ * nand_command_lp - [DEFAULT] Send command to NAND large page device
+ * @mtd:       MTD device structure
+ * @command:   the command to be sent
+ * @column:    the column address for this command, -1 if none
+ * @page_addr: the page address for this command, -1 if none
+ *
+ * Send command to NAND device. This is the version for the new large page devices
+ * We dont have the seperate regions as we have in the small page devices.
+ * We must emulate NAND_CMD_READOOB to keep the code compatible.
+ *
+ */
+static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, int page_addr)
+{
+       register struct nand_chip *this = mtd->priv;
+
+       /* Emulate NAND_CMD_READOOB */
+       if (command == NAND_CMD_READOOB) {
+               column += mtd->oobblock;
+               command = NAND_CMD_READ0;
+       }
+
+
+       /* Begin command latch cycle */
+       this->hwcontrol(mtd, NAND_CTL_SETCLE);
+       /* Write out the command to the device. */
+       this->write_byte(mtd, command);
+       /* End command latch cycle */
+       this->hwcontrol(mtd, NAND_CTL_CLRCLE);
+
+       if (column != -1 || page_addr != -1) {
+               this->hwcontrol(mtd, NAND_CTL_SETALE);
+
+               /* Serially input address */
+               if (column != -1) {
+                       /* Adjust columns for 16 bit buswidth */
+                       if (this->options & NAND_BUSWIDTH_16)
+                               column >>= 1;
+                       this->write_byte(mtd, column & 0xff);
+                       this->write_byte(mtd, column >> 8);
+               }
+               if (page_addr != -1) {
+                       this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
+                       this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
+                       /* One more address cycle for devices > 128MiB */
+                       if (this->chipsize > (128 << 20))
+                               this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0xff));
+               }
+               /* Latch in address */
+               this->hwcontrol(mtd, NAND_CTL_CLRALE);
+       }
+
+       /*
+        * program and erase have their own busy handlers
+        * status and sequential in needs no delay
+       */
+       switch (command) {
+
+       case NAND_CMD_CACHEDPROG:
+       case NAND_CMD_PAGEPROG:
+       case NAND_CMD_ERASE1:
+       case NAND_CMD_ERASE2:
+       case NAND_CMD_SEQIN:
+       case NAND_CMD_STATUS:
+               return;
+
+
+       case NAND_CMD_RESET:
+               if (this->dev_ready)
+                       break;
+               udelay(this->chip_delay);
+               this->hwcontrol(mtd, NAND_CTL_SETCLE);
+               this->write_byte(mtd, NAND_CMD_STATUS);
+               this->hwcontrol(mtd, NAND_CTL_CLRCLE);
+               while ( !(this->read_byte(mtd) & 0x40));
+               return;
+
+       case NAND_CMD_READ0:
+               /* Begin command latch cycle */
+               this->hwcontrol(mtd, NAND_CTL_SETCLE);
+               /* Write out the start read command */
+               this->write_byte(mtd, NAND_CMD_READSTART);
+               /* End command latch cycle */
+               this->hwcontrol(mtd, NAND_CTL_CLRCLE);
+               /* Fall through into ready check */
+
+       /* This applies to read commands */
+       default:
+               /*
+                * If we don't have access to the busy pin, we apply the given
+                * command delay
+               */
+               if (!this->dev_ready) {
+                       udelay (this->chip_delay);
+                       return;
+               }
+       }
+
+       /* Apply this short delay always to ensure that we do wait tWB in
+        * any case on any machine. */
+       ndelay (100);
+       /* wait until command is processed */
+       while (!this->dev_ready(mtd));
+}
+
+/**
+ * nand_get_device - [GENERIC] Get chip for selected access
+ * @this:      the nand chip descriptor
+ * @mtd:       MTD device structure
+ * @new_state: the state which is requested
+ *
+ * Get the device and lock it for exclusive access
+ */
+/* XXX U-BOOT XXX */
+#if 0
+static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
+{
+       struct nand_chip *active = this;
+
+       DECLARE_WAITQUEUE (wait, current);
+
+       /*
+        * Grab the lock and see if the device is available
+       */
+retry:
+       /* Hardware controller shared among independend devices */
+       if (this->controller) {
+               spin_lock (&this->controller->lock);
+               if (this->controller->active)
+                       active = this->controller->active;
+               else
+                       this->controller->active = this;
+               spin_unlock (&this->controller->lock);
+       }
+
+       if (active == this) {
+               spin_lock (&this->chip_lock);
+               if (this->state == FL_READY) {
+                       this->state = new_state;
+                       spin_unlock (&this->chip_lock);
+                       return;
+               }
+       }
+       set_current_state (TASK_UNINTERRUPTIBLE);
+       add_wait_queue (&active->wq, &wait);
+       spin_unlock (&active->chip_lock);
+       schedule ();
+       remove_wait_queue (&active->wq, &wait);
+       goto retry;
+}
+#else
+static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state) {}
+#endif
+
+/**
+ * nand_wait - [DEFAULT]  wait until the command is done
+ * @mtd:       MTD device structure
+ * @this:      NAND chip structure
+ * @state:     state to select the max. timeout value
+ *
+ * Wait for command done. This applies to erase and program only
+ * Erase can take up to 400ms and program up to 20ms according to
+ * general NAND and SmartMedia specs
+ *
+*/
+/* XXX U-BOOT XXX */
+#if 0
+static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
+{
+       unsigned long   timeo = jiffies;
+       int     status;
+
+       if (state == FL_ERASING)
+                timeo += (HZ * 400) / 1000;
+       else
+                timeo += (HZ * 20) / 1000;
+
+       /* Apply this short delay always to ensure that we do wait tWB in
+        * any case on any machine. */
+       ndelay (100);
+
+       if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
+               this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1);
+       else
+               this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
+
+       while (time_before(jiffies, timeo)) {
+               /* Check, if we were interrupted */
+               if (this->state != state)
+                       return 0;
+
+               if (this->dev_ready) {
+                       if (this->dev_ready(mtd))
+                               break;
+               } else {
+                       if (this->read_byte(mtd) & NAND_STATUS_READY)
+                               break;
+               }
+               yield ();
+       }
+       status = (int) this->read_byte(mtd);
+       return status;
+
+       return 0;
+}
+#else
+static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
+{
+       unsigned long   timeo;
+
+       if (state == FL_ERASING)
+               timeo = (CFG_HZ * 400) / 1000;
+       else
+               timeo = (CFG_HZ * 20) / 1000;
+
+       if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
+               this->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1);
+       else
+               this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
+
+       reset_timer();
+
+       while (1) {
+               if (get_timer(0) > timeo) {
+                       printf("Timeout!");
+                       return 0x01;
+               }
+
+               if (this->dev_ready) {
+                       if (this->dev_ready(mtd))
+                               break;
+               } else {
+                       if (this->read_byte(mtd) & NAND_STATUS_READY)
+                               break;
+               }
+       }
+#ifdef PPCHAMELON_NAND_TIMER_HACK
+       reset_timer();
+       while (get_timer(0) < 10);
+#endif /*  PPCHAMELON_NAND_TIMER_HACK */
+
+       return this->read_byte(mtd);
+}
+#endif
+
+/**
+ * nand_write_page - [GENERIC] write one page
+ * @mtd:       MTD device structure
+ * @this:      NAND chip structure
+ * @page:      startpage inside the chip, must be called with (page & this->pagemask)
+ * @oob_buf:   out of band data buffer
+ * @oobsel:    out of band selecttion structre
+ * @cached:    1 = enable cached programming if supported by chip
+ *
+ * Nand_page_program function is used for write and writev !
+ * This function will always program a full page of data
+ * If you call it with a non page aligned buffer, you're lost :)
+ *
+ * Cached programming is not supported yet.
+ */
+static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page,
+       u_char *oob_buf,  struct nand_oobinfo *oobsel, int cached)
+{
+       int     i, status;
+       u_char  ecc_code[32];
+       int     eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
+       uint    *oob_config = oobsel->eccpos;
+       int     datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
+       int     eccbytes = 0;
+
+       /* FIXME: Enable cached programming */
+       cached = 0;
+
+       /* Send command to begin auto page programming */
+       this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page);
+
+       /* Write out complete page of data, take care of eccmode */
+       switch (eccmode) {
+       /* No ecc, write all */
+       case NAND_ECC_NONE:
+               printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n");
+               this->write_buf(mtd, this->data_poi, mtd->oobblock);
+               break;
+
+       /* Software ecc 3/256, write all */
+       case NAND_ECC_SOFT:
+               for (; eccsteps; eccsteps--) {
+                       this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
+                       for (i = 0; i < 3; i++, eccidx++)
+                               oob_buf[oob_config[eccidx]] = ecc_code[i];
+                       datidx += this->eccsize;
+               }
+               this->write_buf(mtd, this->data_poi, mtd->oobblock);
+               break;
+       default:
+               eccbytes = this->eccbytes;
+               for (; eccsteps; eccsteps--) {
+                       /* enable hardware ecc logic for write */
+                       this->enable_hwecc(mtd, NAND_ECC_WRITE);
+                       this->write_buf(mtd, &this->data_poi[datidx], this->eccsize);
+                       this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
+                       for (i = 0; i < eccbytes; i++, eccidx++)
+                               oob_buf[oob_config[eccidx]] = ecc_code[i];
+                       /* If the hardware ecc provides syndromes then
+                        * the ecc code must be written immidiately after
+                        * the data bytes (words) */
+                       if (this->options & NAND_HWECC_SYNDROME)
+                               this->write_buf(mtd, ecc_code, eccbytes);
+                       datidx += this->eccsize;
+               }
+               break;
+       }
+
+       /* Write out OOB data */
+       if (this->options & NAND_HWECC_SYNDROME)
+               this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes);
+       else
+               this->write_buf(mtd, oob_buf, mtd->oobsize);
+
+       /* Send command to actually program the data */
+       this->cmdfunc (mtd, cached ? NAND_CMD_CACHEDPROG : NAND_CMD_PAGEPROG, -1, -1);
+
+       if (!cached) {
+               /* call wait ready function */
+               status = this->waitfunc (mtd, this, FL_WRITING);
+               /* See if device thinks it succeeded */
+               if (status & 0x01) {
+                       DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write, page 0x%08x, ", __FUNCTION__, page);
+                       return -EIO;
+               }
+       } else {
+               /* FIXME: Implement cached programming ! */
+               /* wait until cache is ready*/
+               /* status = this->waitfunc (mtd, this, FL_CACHEDRPG); */
+       }
+       return 0;
+}
+
+#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
+/**
+ * nand_verify_pages - [GENERIC] verify the chip contents after a write
+ * @mtd:       MTD device structure
+ * @this:      NAND chip structure
+ * @page:      startpage inside the chip, must be called with (page & this->pagemask)
+ * @numpages:  number of pages to verify
+ * @oob_buf:   out of band data buffer
+ * @oobsel:    out of band selecttion structre
+ * @chipnr:    number of the current chip
+ * @oobmode:   1 = full buffer verify, 0 = ecc only
+ *
+ * The NAND device assumes that it is always writing to a cleanly erased page.
+ * Hence, it performs its internal write verification only on bits that
+ * transitioned from 1 to 0. The device does NOT verify the whole page on a
+ * byte by byte basis. It is possible that the page was not completely erased
+ * or the page is becoming unusable due to wear. The read with ECC would catch
+ * the error later when the ECC page check fails, but we would rather catch
+ * it early in the page write stage. Better to write no data than invalid data.
+ */
+static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
+       u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode)
+{
+       int     i, j, datidx = 0, oobofs = 0, res = -EIO;
+       int     eccsteps = this->eccsteps;
+       int     hweccbytes;
+       u_char  oobdata[64];
+
+       hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0;
+
+       /* Send command to read back the first page */
+       this->cmdfunc (mtd, NAND_CMD_READ0, 0, page);
+
+       for(;;) {
+               for (j = 0; j < eccsteps; j++) {
+                       /* Loop through and verify the data */
+                       if (this->verify_buf(mtd, &this->data_poi[datidx], mtd->eccsize)) {
+                               DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
+                               goto out;
+                       }
+                       datidx += mtd->eccsize;
+                       /* Have we a hw generator layout ? */
+                       if (!hweccbytes)
+                               continue;
+                       if (this->verify_buf(mtd, &this->oob_buf[oobofs], hweccbytes)) {
+                               DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
+                               goto out;
+                       }
+                       oobofs += hweccbytes;
+               }
+
+               /* check, if we must compare all data or if we just have to
+                * compare the ecc bytes
+                */
+               if (oobmode) {
+                       if (this->verify_buf(mtd, &oob_buf[oobofs], mtd->oobsize - hweccbytes * eccsteps)) {
+                               DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
+                               goto out;
+                       }
+               } else {
+                       /* Read always, else autoincrement fails */
+                       this->read_buf(mtd, oobdata, mtd->oobsize - hweccbytes * eccsteps);
+
+                       if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) {
+                               int ecccnt = oobsel->eccbytes;
+
+                               for (i = 0; i < ecccnt; i++) {
+                                       int idx = oobsel->eccpos[i];
+                                       if (oobdata[idx] != oob_buf[oobofs + idx] ) {
+                                               DEBUG (MTD_DEBUG_LEVEL0,
+                                               "%s: Failed ECC write "
+                                               "verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i);
+                                               goto out;
+                                       }
+                               }
+                       }
+               }
+               oobofs += mtd->oobsize - hweccbytes * eccsteps;
+               page++;
+               numpages--;
+
+               /* Apply delay or wait for ready/busy pin
+                * Do this before the AUTOINCR check, so no problems
+                * arise if a chip which does auto increment
+                * is marked as NOAUTOINCR by the board driver.
+                * Do this also before returning, so the chip is
+                * ready for the next command.
+               */
+               if (!this->dev_ready)
+                       udelay (this->chip_delay);
+               else
+                       while (!this->dev_ready(mtd));
+
+               /* All done, return happy */
+               if (!numpages)
+                       return 0;
+
+
+               /* Check, if the chip supports auto page increment */
+               if (!NAND_CANAUTOINCR(this))
+                       this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
+       }
+       /*
+        * Terminate the read command. We come here in case of an error
+        * So we must issue a reset command.
+        */
+out:
+       this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1);
+       return res;
+}
+#endif
+
+/**
+ * nand_read - [MTD Interface] MTD compability function for nand_read_ecc
+ * @mtd:       MTD device structure
+ * @from:      offset to read from
+ * @len:       number of bytes to read
+ * @retlen:    pointer to variable to store the number of read bytes
+ * @buf:       the databuffer to put data
+ *
+ * This function simply calls nand_read_ecc with oob buffer and oobsel = NULL
+*/
+static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
+{
+       return nand_read_ecc (mtd, from, len, retlen, buf, NULL, NULL);
+}
+
+
+/**
+ * nand_read_ecc - [MTD Interface] Read data with ECC
+ * @mtd:       MTD device structure
+ * @from:      offset to read from
+ * @len:       number of bytes to read
+ * @retlen:    pointer to variable to store the number of read bytes
+ * @buf:       the databuffer to put data
+ * @oob_buf:   filesystem supplied oob data buffer
+ * @oobsel:    oob selection structure
+ *
+ * NAND read with ECC
+ */
+static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
+                         size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel)
+{
+       int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1;
+       int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0;
+       struct nand_chip *this = mtd->priv;
+       u_char *data_poi, *oob_data = oob_buf;
+       u_char ecc_calc[32];
+       u_char ecc_code[32];
+       int eccmode, eccsteps;
+       unsigned *oob_config;
+       int     datidx;
+       int     blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
+       int     eccbytes;
+       int     compareecc = 1;
+       int     oobreadlen;
+
+
+       DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
+
+       /* Do not allow reads past end of device */
+       if ((from + len) > mtd->size) {
+               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: Attempt read beyond end of device\n");
+               *retlen = 0;
+               return -EINVAL;
+       }
+
+       /* Grab the lock and see if the device is available */
+       nand_get_device (this, mtd ,FL_READING);
+
+       /* use userspace supplied oobinfo, if zero */
+       if (oobsel == NULL)
+               oobsel = &mtd->oobinfo;
+
+       /* Autoplace of oob data ? Use the default placement scheme */
+       if (oobsel->useecc == MTD_NANDECC_AUTOPLACE)
+               oobsel = this->autooob;
+
+       eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
+       oob_config = oobsel->eccpos;
+
+       /* Select the NAND device */
+       chipnr = (int)(from >> this->chip_shift);
+       this->select_chip(mtd, chipnr);
+
+       /* First we calculate the starting page */
+       realpage = (int) (from >> this->page_shift);
+       page = realpage & this->pagemask;
+
+       /* Get raw starting column */
+       col = from & (mtd->oobblock - 1);
+
+       end = mtd->oobblock;
+       ecc = this->eccsize;
+       eccbytes = this->eccbytes;
+
+       if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
+               compareecc = 0;
+
+       oobreadlen = mtd->oobsize;
+       if (this->options & NAND_HWECC_SYNDROME)
+               oobreadlen -= oobsel->eccbytes;
+
+       /* Loop until all data read */
+       while (read < len) {
+
+               int aligned = (!col && (len - read) >= end);
+               /*
+                * If the read is not page aligned, we have to read into data buffer
+                * due to ecc, else we read into return buffer direct
+                */
+               if (aligned)
+                       data_poi = &buf[read];
+               else
+                       data_poi = this->data_buf;
+
+               /* Check, if we have this page in the buffer
+                *
+                * FIXME: Make it work when we must provide oob data too,
+                * check the usage of data_buf oob field
+                */
+               if (realpage == this->pagebuf && !oob_buf) {
+                       /* aligned read ? */
+                       if (aligned)
+                               memcpy (data_poi, this->data_buf, end);
+                       goto readdata;
+               }
+
+               /* Check, if we must send the read command */
+               if (sndcmd) {
+                       this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
+                       sndcmd = 0;
+               }
+
+               /* get oob area, if we have no oob buffer from fs-driver */
+               if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE ||
+                       oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
+                       oob_data = &this->data_buf[end];
+
+               eccsteps = this->eccsteps;
+
+               switch (eccmode) {
+               case NAND_ECC_NONE: {   /* No ECC, Read in a page */
+/* XXX U-BOOT XXX */
+#if 0
+                       static unsigned long lastwhinge = 0;
+                       if ((lastwhinge / HZ) != (jiffies / HZ)) {
+                               printk (KERN_WARNING "Reading data from NAND FLASH without ECC is not recommended\n");
+                               lastwhinge = jiffies;
+                       }
+#else
+                       puts("Reading data from NAND FLASH without ECC is not recommended\n");
+#endif
+                       this->read_buf(mtd, data_poi, end);
+                       break;
+               }
+
+               case NAND_ECC_SOFT:     /* Software ECC 3/256: Read in a page + oob data */
+                       this->read_buf(mtd, data_poi, end);
+                       for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc)
+                               this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
+                       break;
+
+               default:
+                       for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) {
+                               this->enable_hwecc(mtd, NAND_ECC_READ);
+                               this->read_buf(mtd, &data_poi[datidx], ecc);
+
+                               /* HW ecc with syndrome calculation must read the
+                                * syndrome from flash immidiately after the data */
+                               if (!compareecc) {
+                                       /* Some hw ecc generators need to know when the
+                                        * syndrome is read from flash */
+                                       this->enable_hwecc(mtd, NAND_ECC_READSYN);
+                                       this->read_buf(mtd, &oob_data[i], eccbytes);
+                                       /* We calc error correction directly, it checks the hw
+                                        * generator for an error, reads back the syndrome and
+                                        * does the error correction on the fly */
+                                       if (this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]) == -1) {
+                                               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
+                                                       "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
+                                               ecc_failed++;
+                                       }
+                               } else {
+                                       this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
+                               }
+                       }
+                       break;
+               }
+
+               /* read oobdata */
+               this->read_buf(mtd, &oob_data[mtd->oobsize - oobreadlen], oobreadlen);
+
+               /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */
+               if (!compareecc)
+                       goto readoob;
+
+               /* Pick the ECC bytes out of the oob data */
+               for (j = 0; j < oobsel->eccbytes; j++)
+                       ecc_code[j] = oob_data[oob_config[j]];
+
+               /* correct data, if neccecary */
+               for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) {
+                       ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]);
+
+                       /* Get next chunk of ecc bytes */
+                       j += eccbytes;
+
+                       /* Check, if we have a fs supplied oob-buffer,
+                        * This is the legacy mode. Used by YAFFS1
+                        * Should go away some day
+                        */
+                       if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) {
+                               int *p = (int *)(&oob_data[mtd->oobsize]);
+                               p[i] = ecc_status;
+                       }
+
+                       if (ecc_status == -1) {
+                               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
+                               ecc_failed++;
+                       }
+               }
+
+       readoob:
+               /* check, if we have a fs supplied oob-buffer */
+               if (oob_buf) {
+                       /* without autoplace. Legacy mode used by YAFFS1 */
+                       switch(oobsel->useecc) {
+                       case MTD_NANDECC_AUTOPLACE:
+                       case MTD_NANDECC_AUTOPL_USR:
+                               /* Walk through the autoplace chunks */
+                               for (i = 0, j = 0; j < mtd->oobavail; i++) {
+                                       int from = oobsel->oobfree[i][0];
+                                       int num = oobsel->oobfree[i][1];
+                                       memcpy(&oob_buf[oob], &oob_data[from], num);
+                                       j+= num;
+                               }
+                               oob += mtd->oobavail;
+                               break;
+                       case MTD_NANDECC_PLACE:
+                               /* YAFFS1 legacy mode */
+                               oob_data += this->eccsteps * sizeof (int);
+                       default:
+                               oob_data += mtd->oobsize;
+                       }
+               }
+       readdata:
+               /* Partial page read, transfer data into fs buffer */
+               if (!aligned) {
+                       for (j = col; j < end && read < len; j++)
+                               buf[read++] = data_poi[j];
+                       this->pagebuf = realpage;
+               } else
+                       read += mtd->oobblock;
+
+               /* Apply delay or wait for ready/busy pin
+                * Do this before the AUTOINCR check, so no problems
+                * arise if a chip which does auto increment
+                * is marked as NOAUTOINCR by the board driver.
+               */
+               if (!this->dev_ready)
+                       udelay (this->chip_delay);
+               else
+                       while (!this->dev_ready(mtd));
+
+               if (read == len)
+                       break;
+
+               /* For subsequent reads align to page boundary. */
+               col = 0;
+               /* Increment page address */
+               realpage++;
+
+               page = realpage & this->pagemask;
+               /* Check, if we cross a chip boundary */
+               if (!page) {
+                       chipnr++;
+                       this->select_chip(mtd, -1);
+                       this->select_chip(mtd, chipnr);
+               }
+               /* Check, if the chip supports auto page increment
+                * or if we have hit a block boundary.
+               */
+               if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
+                       sndcmd = 1;
+       }
+
+       /* Deselect and wake up anyone waiting on the device */
+       nand_release_device(mtd);
+
+       /*
+        * Return success, if no ECC failures, else -EBADMSG
+        * fs driver will take care of that, because
+        * retlen == desired len and result == -EBADMSG
+        */
+       *retlen = read;
+       return ecc_failed ? -EBADMSG : 0;
+}
+
+/**
+ * nand_read_oob - [MTD Interface] NAND read out-of-band
+ * @mtd:       MTD device structure
+ * @from:      offset to read from
+ * @len:       number of bytes to read
+ * @retlen:    pointer to variable to store the number of read bytes
+ * @buf:       the databuffer to put data
+ *
+ * NAND read out-of-band data from the spare area
+ */
+static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
+{
+       int i, col, page, chipnr;
+       struct nand_chip *this = mtd->priv;
+       int     blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
+
+       DEBUG (MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
+
+       /* Shift to get page */
+       page = (int)(from >> this->page_shift);
+       chipnr = (int)(from >> this->chip_shift);
+
+       /* Mask to get column */
+       col = from & (mtd->oobsize - 1);
+
+       /* Initialize return length value */
+       *retlen = 0;
+
+       /* Do not allow reads past end of device */
+       if ((from + len) > mtd->size) {
+               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: Attempt read beyond end of device\n");
+               *retlen = 0;
+               return -EINVAL;
+       }
+
+       /* Grab the lock and see if the device is available */
+       nand_get_device (this, mtd , FL_READING);
+
+       /* Select the NAND device */
+       this->select_chip(mtd, chipnr);
+
+       /* Send the read command */
+       this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask);
+       /*
+        * Read the data, if we read more than one page
+        * oob data, let the device transfer the data !
+        */
+       i = 0;
+       while (i < len) {
+               int thislen = mtd->oobsize - col;
+               thislen = min_t(int, thislen, len);
+               this->read_buf(mtd, &buf[i], thislen);
+               i += thislen;
+
+               /* Apply delay or wait for ready/busy pin
+                * Do this before the AUTOINCR check, so no problems
+                * arise if a chip which does auto increment
+                * is marked as NOAUTOINCR by the board driver.
+               */
+               if (!this->dev_ready)
+                       udelay (this->chip_delay);
+               else
+                       while (!this->dev_ready(mtd));
+
+               /* Read more ? */
+               if (i < len) {
+                       page++;
+                       col = 0;
+
+                       /* Check, if we cross a chip boundary */
+                       if (!(page & this->pagemask)) {
+                               chipnr++;
+                               this->select_chip(mtd, -1);
+                               this->select_chip(mtd, chipnr);
+                       }
+
+                       /* Check, if the chip supports auto page increment
+                        * or if we have hit a block boundary.
+                       */
+                       if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) {
+                               /* For subsequent page reads set offset to 0 */
+                               this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
+                       }
+               }
+       }
+
+       /* Deselect and wake up anyone waiting on the device */
+       nand_release_device(mtd);
+
+       /* Return happy */
+       *retlen = len;
+       return 0;
+}
+
+/**
+ * nand_read_raw - [GENERIC] Read raw data including oob into buffer
+ * @mtd:       MTD device structure
+ * @buf:       temporary buffer
+ * @from:      offset to read from
+ * @len:       number of bytes to read
+ * @ooblen:    number of oob data bytes to read
+ *
+ * Read raw data including oob into buffer
+ */
+int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen)
+{
+       struct nand_chip *this = mtd->priv;
+       int page = (int) (from >> this->page_shift);
+       int chip = (int) (from >> this->chip_shift);
+       int sndcmd = 1;
+       int cnt = 0;
+       int pagesize = mtd->oobblock + mtd->oobsize;
+       int     blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
+
+       /* Do not allow reads past end of device */
+       if ((from + len) > mtd->size) {
+               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_raw: Attempt read beyond end of device\n");
+               return -EINVAL;
+       }
+
+       /* Grab the lock and see if the device is available */
+       nand_get_device (this, mtd , FL_READING);
+
+       this->select_chip (mtd, chip);
+
+       /* Add requested oob length */
+       len += ooblen;
+
+       while (len) {
+               if (sndcmd)
+                       this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask);
+               sndcmd = 0;
+
+               this->read_buf (mtd, &buf[cnt], pagesize);
+
+               len -= pagesize;
+               cnt += pagesize;
+               page++;
+
+               if (!this->dev_ready)
+                       udelay (this->chip_delay);
+               else
+                       while (!this->dev_ready(mtd));
+
+               /* Check, if the chip supports auto page increment */
+               if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
+                       sndcmd = 1;
+       }
+
+       /* Deselect and wake up anyone waiting on the device */
+       nand_release_device(mtd);
+       return 0;
+}
+
+
+/**
+ * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer
+ * @mtd:       MTD device structure
+ * @fsbuf:     buffer given by fs driver
+ * @oobsel:    out of band selection structre
+ * @autoplace: 1 = place given buffer into the oob bytes
+ * @numpages:  number of pages to prepare
+ *
+ * Return:
+ * 1. Filesystem buffer available and autoplacement is off,
+ *    return filesystem buffer
+ * 2. No filesystem buffer or autoplace is off, return internal
+ *    buffer
+ * 3. Filesystem buffer is given and autoplace selected
+ *    put data from fs buffer into internal buffer and
+ *    retrun internal buffer
+ *
+ * Note: The internal buffer is filled with 0xff. This must
+ * be done only once, when no autoplacement happens
+ * Autoplacement sets the buffer dirty flag, which
+ * forces the 0xff fill before using the buffer again.
+ *
+*/
+static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct nand_oobinfo *oobsel,
+               int autoplace, int numpages)
+{
+       struct nand_chip *this = mtd->priv;
+       int i, len, ofs;
+
+       /* Zero copy fs supplied buffer */
+       if (fsbuf && !autoplace)
+               return fsbuf;
+
+       /* Check, if the buffer must be filled with ff again */
+       if (this->oobdirty) {
+               memset (this->oob_buf, 0xff,
+                       mtd->oobsize << (this->phys_erase_shift - this->page_shift));
+               this->oobdirty = 0;
+       }
+
+       /* If we have no autoplacement or no fs buffer use the internal one */
+       if (!autoplace || !fsbuf)
+               return this->oob_buf;
+
+       /* Walk through the pages and place the data */
+       this->oobdirty = 1;
+       ofs = 0;
+       while (numpages--) {
+               for (i = 0, len = 0; len < mtd->oobavail; i++) {
+                       int to = ofs + oobsel->oobfree[i][0];
+                       int num = oobsel->oobfree[i][1];
+                       memcpy (&this->oob_buf[to], fsbuf, num);
+                       len += num;
+                       fsbuf += num;
+               }
+               ofs += mtd->oobavail;
+       }
+       return this->oob_buf;
+}
+
+#define NOTALIGNED(x) (x & (mtd->oobblock-1)) != 0
+
+/**
+ * nand_write - [MTD Interface] compability function for nand_write_ecc
+ * @mtd:       MTD device structure
+ * @to:                offset to write to
+ * @len:       number of bytes to write
+ * @retlen:    pointer to variable to store the number of written bytes
+ * @buf:       the data to write
+ *
+ * This function simply calls nand_write_ecc with oob buffer and oobsel = NULL
+ *
+*/
+static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
+{
+       return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL));
+}
+
+/**
+ * nand_write_ecc - [MTD Interface] NAND write with ECC
+ * @mtd:       MTD device structure
+ * @to:                offset to write to
+ * @len:       number of bytes to write
+ * @retlen:    pointer to variable to store the number of written bytes
+ * @buf:       the data to write
+ * @eccbuf:    filesystem supplied oob data buffer
+ * @oobsel:    oob selection structure
+ *
+ * NAND write with ECC
+ */
+static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
+                          size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel)
+{
+       int startpage, page, ret = -EIO, oob = 0, written = 0, chipnr;
+       int autoplace = 0, numpages, totalpages;
+       struct nand_chip *this = mtd->priv;
+       u_char *oobbuf, *bufstart;
+       int     ppblock = (1 << (this->phys_erase_shift - this->page_shift));
+
+       DEBUG (MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
+
+       /* Initialize retlen, in case of early exit */
+       *retlen = 0;
+
+       /* Do not allow write past end of device */
+       if ((to + len) > mtd->size) {
+               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Attempt to write past end of page\n");
+               return -EINVAL;
+       }
+
+       /* reject writes, which are not page aligned */
+       if (NOTALIGNED (to) || NOTALIGNED(len)) {
+               printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
+               return -EINVAL;
+       }
+
+       /* Grab the lock and see if the device is available */
+       nand_get_device (this, mtd, FL_WRITING);
+
+       /* Calculate chipnr */
+       chipnr = (int)(to >> this->chip_shift);
+       /* Select the NAND device */
+       this->select_chip(mtd, chipnr);
+
+       /* Check, if it is write protected */
+       if (nand_check_wp(mtd))
+               goto out;
+
+       /* if oobsel is NULL, use chip defaults */
+       if (oobsel == NULL)
+               oobsel = &mtd->oobinfo;
+
+       /* Autoplace of oob data ? Use the default placement scheme */
+       if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
+               oobsel = this->autooob;
+               autoplace = 1;
+       }
+       if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
+               autoplace = 1;
+
+       /* Setup variables and oob buffer */
+       totalpages = len >> this->page_shift;
+       page = (int) (to >> this->page_shift);
+       /* Invalidate the page cache, if we write to the cached page */
+       if (page <= this->pagebuf && this->pagebuf < (page + totalpages))
+               this->pagebuf = -1;
+
+       /* Set it relative to chip */
+       page &= this->pagemask;
+       startpage = page;
+       /* Calc number of pages we can write in one go */
+       numpages = min (ppblock - (startpage  & (ppblock - 1)), totalpages);
+       oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, autoplace, numpages);
+       bufstart = (u_char *)buf;
+
+       /* Loop until all data is written */
+       while (written < len) {
+
+               this->data_poi = (u_char*) &buf[written];
+               /* Write one page. If this is the last page to write
+                * or the last page in this block, then use the
+                * real pageprogram command, else select cached programming
+                * if supported by the chip.
+                */
+               ret = nand_write_page (mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0));
+               if (ret) {
+                       DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret);
+                       goto out;
+               }
+               /* Next oob page */
+               oob += mtd->oobsize;
+               /* Update written bytes count */
+               written += mtd->oobblock;
+               if (written == len)
+                       goto cmp;
+
+               /* Increment page address */
+               page++;
+
+               /* Have we hit a block boundary ? Then we have to verify and
+                * if verify is ok, we have to setup the oob buffer for
+                * the next pages.
+               */
+               if (!(page & (ppblock - 1))){
+                       int ofs;
+                       this->data_poi = bufstart;
+                       ret = nand_verify_pages (mtd, this, startpage,
+                               page - startpage,
+                               oobbuf, oobsel, chipnr, (eccbuf != NULL));
+                       if (ret) {
+                               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
+                               goto out;
+                       }
+                       *retlen = written;
+                       bufstart = (u_char*) &buf[written];
+
+                       ofs = autoplace ? mtd->oobavail : mtd->oobsize;
+                       if (eccbuf)
+                               eccbuf += (page - startpage) * ofs;
+                       totalpages -= page - startpage;
+                       numpages = min (totalpages, ppblock);
+                       page &= this->pagemask;
+                       startpage = page;
+                       oob = 0;
+                       this->oobdirty = 1;
+                       oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel,
+                                       autoplace, numpages);
+                       /* Check, if we cross a chip boundary */
+                       if (!page) {
+                               chipnr++;
+                               this->select_chip(mtd, -1);
+                               this->select_chip(mtd, chipnr);
+                       }
+               }
+       }
+       /* Verify the remaining pages */
+cmp:
+       this->data_poi = bufstart;
+       ret = nand_verify_pages (mtd, this, startpage, totalpages,
+               oobbuf, oobsel, chipnr, (eccbuf != NULL));
+       if (!ret)
+               *retlen = written;
+       else
+               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
+
+out:
+       /* Deselect and wake up anyone waiting on the device */
+       nand_release_device(mtd);
+
+       return ret;
+}
+
+
+/**
+ * nand_write_oob - [MTD Interface] NAND write out-of-band
+ * @mtd:       MTD device structure
+ * @to:                offset to write to
+ * @len:       number of bytes to write
+ * @retlen:    pointer to variable to store the number of written bytes
+ * @buf:       the data to write
+ *
+ * NAND write out-of-band
+ */
+static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
+{
+       int column, page, status, ret = -EIO, chipnr;
+       struct nand_chip *this = mtd->priv;
+
+       DEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
+
+       /* Shift to get page */
+       page = (int) (to >> this->page_shift);
+       chipnr = (int) (to >> this->chip_shift);
+
+       /* Mask to get column */
+       column = to & (mtd->oobsize - 1);
+
+       /* Initialize return length value */
+       *retlen = 0;
+
+       /* Do not allow write past end of page */
+       if ((column + len) > mtd->oobsize) {
+               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Attempt to write past end of page\n");
+               return -EINVAL;
+       }
+
+       /* Grab the lock and see if the device is available */
+       nand_get_device (this, mtd, FL_WRITING);
+
+       /* Select the NAND device */
+       this->select_chip(mtd, chipnr);
+
+       /* Reset the chip. Some chips (like the Toshiba TC5832DC found
+          in one of my DiskOnChip 2000 test units) will clear the whole
+          data page too if we don't do this. I have no clue why, but
+          I seem to have 'fixed' it in the doc2000 driver in
+          August 1999.  dwmw2. */
+       this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+
+       /* Check, if it is write protected */
+       if (nand_check_wp(mtd))
+               goto out;
+
+       /* Invalidate the page cache, if we write to the cached page */
+       if (page == this->pagebuf)
+               this->pagebuf = -1;
+
+       if (NAND_MUST_PAD(this)) {
+               /* Write out desired data */
+               this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page & this->pagemask);
+               /* prepad 0xff for partial programming */
+               this->write_buf(mtd, ffchars, column);
+               /* write data */
+               this->write_buf(mtd, buf, len);
+               /* postpad 0xff for partial programming */
+               this->write_buf(mtd, ffchars, mtd->oobsize - (len+column));
+       } else {
+               /* Write out desired data */
+               this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock + column, page & this->pagemask);
+               /* write data */
+               this->write_buf(mtd, buf, len);
+       }
+       /* Send command to program the OOB data */
+       this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1);
+
+       status = this->waitfunc (mtd, this, FL_WRITING);
+
+       /* See if device thinks it succeeded */
+       if (status & 0x01) {
+               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08x\n", page);
+               ret = -EIO;
+               goto out;
+       }
+       /* Return happy */
+       *retlen = len;
+
+#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
+       /* Send command to read back the data */
+       this->cmdfunc (mtd, NAND_CMD_READOOB, column, page & this->pagemask);
+
+       if (this->verify_buf(mtd, buf, len)) {
+               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
+               ret = -EIO;
+               goto out;
+       }
+#endif
+       ret = 0;
+out:
+       /* Deselect and wake up anyone waiting on the device */
+       nand_release_device(mtd);
+
+       return ret;
+}
+
+/* XXX U-BOOT XXX */
+#if 0
+/**
+ * nand_writev - [MTD Interface] compabilty function for nand_writev_ecc
+ * @mtd:       MTD device structure
+ * @vecs:      the iovectors to write
+ * @count:     number of vectors
+ * @to:                offset to write to
+ * @retlen:    pointer to variable to store the number of written bytes
+ *
+ * NAND write with kvec. This just calls the ecc function
+ */
+static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
+               loff_t to, size_t * retlen)
+{
+       return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL));
+}
+
+/**
+ * nand_writev_ecc - [MTD Interface] write with iovec with ecc
+ * @mtd:       MTD device structure
+ * @vecs:      the iovectors to write
+ * @count:     number of vectors
+ * @to:                offset to write to
+ * @retlen:    pointer to variable to store the number of written bytes
+ * @eccbuf:    filesystem supplied oob data buffer
+ * @oobsel:    oob selection structure
+ *
+ * NAND write with iovec with ecc
+ */
+static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
+               loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel)
+{
+       int i, page, len, total_len, ret = -EIO, written = 0, chipnr;
+       int oob, numpages, autoplace = 0, startpage;
+       struct nand_chip *this = mtd->priv;
+       int     ppblock = (1 << (this->phys_erase_shift - this->page_shift));
+       u_char *oobbuf, *bufstart;
+
+       /* Preset written len for early exit */
+       *retlen = 0;
+
+       /* Calculate total length of data */
+       total_len = 0;
+       for (i = 0; i < count; i++)
+               total_len += (int) vecs[i].iov_len;
+
+       DEBUG (MTD_DEBUG_LEVEL3,
+              "nand_writev: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
+
+       /* Do not allow write past end of page */
+       if ((to + total_len) > mtd->size) {
+               DEBUG (MTD_DEBUG_LEVEL0, "nand_writev: Attempted write past end of device\n");
+               return -EINVAL;
+       }
+
+       /* reject writes, which are not page aligned */
+       if (NOTALIGNED (to) || NOTALIGNED(total_len)) {
+               printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
+               return -EINVAL;
+       }
+
+       /* Grab the lock and see if the device is available */
+       nand_get_device (this, mtd, FL_WRITING);
+
+       /* Get the current chip-nr */
+       chipnr = (int) (to >> this->chip_shift);
+       /* Select the NAND device */
+       this->select_chip(mtd, chipnr);
+
+       /* Check, if it is write protected */
+       if (nand_check_wp(mtd))
+               goto out;
+
+       /* if oobsel is NULL, use chip defaults */
+       if (oobsel == NULL)
+               oobsel = &mtd->oobinfo;
+
+       /* Autoplace of oob data ? Use the default placement scheme */
+       if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
+               oobsel = this->autooob;
+               autoplace = 1;
+       }
+       if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
+               autoplace = 1;
+
+       /* Setup start page */
+       page = (int) (to >> this->page_shift);
+       /* Invalidate the page cache, if we write to the cached page */
+       if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift))
+               this->pagebuf = -1;
+
+       startpage = page & this->pagemask;
+
+       /* Loop until all kvec' data has been written */
+       len = 0;
+       while (count) {
+               /* If the given tuple is >= pagesize then
+                * write it out from the iov
+                */
+               if ((vecs->iov_len - len) >= mtd->oobblock) {
+                       /* Calc number of pages we can write
+                        * out of this iov in one go */
+                       numpages = (vecs->iov_len - len) >> this->page_shift;
+                       /* Do not cross block boundaries */
+                       numpages = min (ppblock - (startpage & (ppblock - 1)), numpages);
+                       oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
+                       bufstart = (u_char *)vecs->iov_base;
+                       bufstart += len;
+                       this->data_poi = bufstart;
+                       oob = 0;
+                       for (i = 1; i <= numpages; i++) {
+                               /* Write one page. If this is the last page to write
+                                * then use the real pageprogram command, else select
+                                * cached programming if supported by the chip.
+                                */
+                               ret = nand_write_page (mtd, this, page & this->pagemask,
+                                       &oobbuf[oob], oobsel, i != numpages);
+                               if (ret)
+                                       goto out;
+                               this->data_poi += mtd->oobblock;
+                               len += mtd->oobblock;
+                               oob += mtd->oobsize;
+                               page++;
+                       }
+                       /* Check, if we have to switch to the next tuple */
+                       if (len >= (int) vecs->iov_len) {
+                               vecs++;
+                               len = 0;
+                               count--;
+                       }
+               } else {
+                       /* We must use the internal buffer, read data out of each
+                        * tuple until we have a full page to write
+                        */
+                       int cnt = 0;
+                       while (cnt < mtd->oobblock) {
+                               if (vecs->iov_base != NULL && vecs->iov_len)
+                                       this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++];
+                               /* Check, if we have to switch to the next tuple */
+                               if (len >= (int) vecs->iov_len) {
+                                       vecs++;
+                                       len = 0;
+                                       count--;
+                               }
+                       }
+                       this->pagebuf = page;
+                       this->data_poi = this->data_buf;
+                       bufstart = this->data_poi;
+                       numpages = 1;
+                       oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
+                       ret = nand_write_page (mtd, this, page & this->pagemask,
+                               oobbuf, oobsel, 0);
+                       if (ret)
+                               goto out;
+                       page++;
+               }
+
+               this->data_poi = bufstart;
+               ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0);
+               if (ret)
+                       goto out;
+
+               written += mtd->oobblock * numpages;
+               /* All done ? */
+               if (!count)
+                       break;
+
+               startpage = page & this->pagemask;
+               /* Check, if we cross a chip boundary */
+               if (!startpage) {
+                       chipnr++;
+                       this->select_chip(mtd, -1);
+                       this->select_chip(mtd, chipnr);
+               }
+       }
+       ret = 0;
+out:
+       /* Deselect and wake up anyone waiting on the device */
+       nand_release_device(mtd);
+
+       *retlen = written;
+       return ret;
+}
+#endif
+
+/**
+ * single_erease_cmd - [GENERIC] NAND standard block erase command function
+ * @mtd:       MTD device structure
+ * @page:      the page address of the block which will be erased
+ *
+ * Standard erase command for NAND chips
+ */
+static void single_erase_cmd (struct mtd_info *mtd, int page)
+{
+       struct nand_chip *this = mtd->priv;
+       /* Send commands to erase a block */
+       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page);
+       this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1);
+}
+
+/**
+ * multi_erease_cmd - [GENERIC] AND specific block erase command function
+ * @mtd:       MTD device structure
+ * @page:      the page address of the block which will be erased
+ *
+ * AND multi block erase command function
+ * Erase 4 consecutive blocks
+ */
+static void multi_erase_cmd (struct mtd_info *mtd, int page)
+{
+       struct nand_chip *this = mtd->priv;
+       /* Send commands to erase a block */
+       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
+       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
+       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
+       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page);
+       this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1);
+}
+
+/**
+ * nand_erase - [MTD Interface] erase block(s)
+ * @mtd:       MTD device structure
+ * @instr:     erase instruction
+ *
+ * Erase one ore more blocks
+ */
+static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
+{
+       return nand_erase_nand (mtd, instr, 0);
+}
+
+/**
+ * nand_erase_intern - [NAND Interface] erase block(s)
+ * @mtd:       MTD device structure
+ * @instr:     erase instruction
+ * @allowbbt:  allow erasing the bbt area
+ *
+ * Erase one ore more blocks
+ */
+int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt)
+{
+       int page, len, status, pages_per_block, ret, chipnr;
+       struct nand_chip *this = mtd->priv;
+
+       DEBUG (MTD_DEBUG_LEVEL3,
+              "nand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len);
+
+       /* Start address must align on block boundary */
+       if (instr->addr & ((1 << this->phys_erase_shift) - 1)) {
+               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Unaligned address\n");
+               return -EINVAL;
+       }
+
+       /* Length must align on block boundary */
+       if (instr->len & ((1 << this->phys_erase_shift) - 1)) {
+               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Length not block aligned\n");
+               return -EINVAL;
+       }
+
+       /* Do not allow erase past end of device */
+       if ((instr->len + instr->addr) > mtd->size) {
+               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Erase past end of device\n");
+               return -EINVAL;
+       }
+
+       instr->fail_addr = 0xffffffff;
+
+       /* Grab the lock and see if the device is available */
+       nand_get_device (this, mtd, FL_ERASING);
+
+       /* Shift to get first page */
+       page = (int) (instr->addr >> this->page_shift);
+       chipnr = (int) (instr->addr >> this->chip_shift);
+
+       /* Calculate pages in each block */
+       pages_per_block = 1 << (this->phys_erase_shift - this->page_shift);
+
+       /* Select the NAND device */
+       this->select_chip(mtd, chipnr);
+
+       /* Check the WP bit */
+       /* Check, if it is write protected */
+       if (nand_check_wp(mtd)) {
+               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Device is write protected!!!\n");
+               instr->state = MTD_ERASE_FAILED;
+               goto erase_exit;
+       }
+
+       /* Loop through the pages */
+       len = instr->len;
+
+       instr->state = MTD_ERASING;
+
+       while (len) {
+#ifndef NAND_ALLOW_ERASE_ALL
+               /* Check if we have a bad block, we do not erase bad blocks ! */
+               if (nand_block_checkbad(mtd, ((loff_t) page) << this->page_shift, 0, allowbbt)) {
+                       printk (KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page);
+                       instr->state = MTD_ERASE_FAILED;
+                       goto erase_exit;
+               }
+#endif
+               /* Invalidate the page cache, if we erase the block which contains
+                  the current cached page */
+               if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block))
+                       this->pagebuf = -1;
+
+               this->erase_cmd (mtd, page & this->pagemask);
+
+               status = this->waitfunc (mtd, this, FL_ERASING);
+
+               /* See if block erase succeeded */
+               if (status & 0x01) {
+                       DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page);
+                       instr->state = MTD_ERASE_FAILED;
+                       instr->fail_addr = (page << this->page_shift);
+                       goto erase_exit;
+               }
+
+               /* Increment page address and decrement length */
+               len -= (1 << this->phys_erase_shift);
+               page += pages_per_block;
+
+               /* Check, if we cross a chip boundary */
+               if (len && !(page & this->pagemask)) {
+                       chipnr++;
+                       this->select_chip(mtd, -1);
+                       this->select_chip(mtd, chipnr);
+               }
+       }
+       instr->state = MTD_ERASE_DONE;
+
+erase_exit:
+
+       ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
+       /* Do call back function */
+       if (!ret)
+               mtd_erase_callback(instr);
+
+       /* Deselect and wake up anyone waiting on the device */
+       nand_release_device(mtd);
+
+       /* Return more or less happy */
+       return ret;
+}
+
+/**
+ * nand_sync - [MTD Interface] sync
+ * @mtd:       MTD device structure
+ *
+ * Sync is actually a wait for chip ready function
+ */
+static void nand_sync (struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+
+       DEBUG (MTD_DEBUG_LEVEL3, "nand_sync: called\n");
+
+       /* Grab the lock and see if the device is available */
+       nand_get_device (this, mtd, FL_SYNCING);
+       /* Release it and go back */
+       nand_release_device (mtd);
+}
+
+
+/**
+ * nand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
+ * @mtd:       MTD device structure
+ * @ofs:       offset relative to mtd start
+ */
+static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs)
+{
+       /* Check for invalid offset */
+       if (ofs > mtd->size)
+               return -EINVAL;
+
+       return nand_block_checkbad (mtd, ofs, 1, 0);
+}
+
+/**
+ * nand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
+ * @mtd:       MTD device structure
+ * @ofs:       offset relative to mtd start
+ */
+static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs)
+{
+       struct nand_chip *this = mtd->priv;
+       int ret;
+
+       if ((ret = nand_block_isbad(mtd, ofs))) {
+               /* If it was bad already, return success and do nothing. */
+               if (ret > 0)
+                       return 0;
+               return ret;
+       }
+
+       return this->block_markbad(mtd, ofs);
+}
+
+/**
+ * nand_scan - [NAND Interface] Scan for the NAND device
+ * @mtd:       MTD device structure
+ * @maxchips:  Number of chips to scan for
+ *
+ * This fills out all the not initialized function pointers
+ * with the defaults.
+ * The flash ID is read and the mtd/chip structures are
+ * filled with the appropriate values. Buffers are allocated if
+ * they are not provided by the board driver
+ *
+ */
+int nand_scan (struct mtd_info *mtd, int maxchips)
+{
+       int i, j, nand_maf_id, nand_dev_id, busw;
+       struct nand_chip *this = mtd->priv;
+
+       /* Get buswidth to select the correct functions*/
+       busw = this->options & NAND_BUSWIDTH_16;
+
+       /* check for proper chip_delay setup, set 20us if not */
+       if (!this->chip_delay)
+               this->chip_delay = 20;
+
+       /* check, if a user supplied command function given */
+       if (this->cmdfunc == NULL)
+               this->cmdfunc = nand_command;
+
+       /* check, if a user supplied wait function given */
+       if (this->waitfunc == NULL)
+               this->waitfunc = nand_wait;
+
+       if (!this->select_chip)
+               this->select_chip = nand_select_chip;
+       if (!this->write_byte)
+               this->write_byte = busw ? nand_write_byte16 : nand_write_byte;
+       if (!this->read_byte)
+               this->read_byte = busw ? nand_read_byte16 : nand_read_byte;
+       if (!this->write_word)
+               this->write_word = nand_write_word;
+       if (!this->read_word)
+               this->read_word = nand_read_word;
+       if (!this->block_bad)
+               this->block_bad = nand_block_bad;
+       if (!this->block_markbad)
+               this->block_markbad = nand_default_block_markbad;
+       if (!this->write_buf)
+               this->write_buf = busw ? nand_write_buf16 : nand_write_buf;
+       if (!this->read_buf)
+               this->read_buf = busw ? nand_read_buf16 : nand_read_buf;
+       if (!this->verify_buf)
+               this->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf;
+       if (!this->scan_bbt)
+               this->scan_bbt = nand_default_bbt;
+
+       /* Select the device */
+       this->select_chip(mtd, 0);
+
+       /* Send the command for reading device ID */
+       this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
+
+       /* Read manufacturer and device IDs */
+       nand_maf_id = this->read_byte(mtd);
+       nand_dev_id = this->read_byte(mtd);
+
+       /* Print and store flash device information */
+       for (i = 0; nand_flash_ids[i].name != NULL; i++) {
+
+               if (nand_dev_id != nand_flash_ids[i].id)
+                       continue;
+
+               if (!mtd->name) mtd->name = nand_flash_ids[i].name;
+               this->chipsize = nand_flash_ids[i].chipsize << 20;
+
+               /* New devices have all the information in additional id bytes */
+               if (!nand_flash_ids[i].pagesize) {
+                       int extid;
+                       /* The 3rd id byte contains non relevant data ATM */
+                       extid = this->read_byte(mtd);
+                       /* The 4th id byte is the important one */
+                       extid = this->read_byte(mtd);
+                       /* Calc pagesize */
+                       mtd->oobblock = 1024 << (extid & 0x3);
+                       extid >>= 2;
+                       /* Calc oobsize */
+                       mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock / 512);
+                       extid >>= 2;
+                       /* Calc blocksize. Blocksize is multiples of 64KiB */
+                       mtd->erasesize = (64 * 1024)  << (extid & 0x03);
+                       extid >>= 2;
+                       /* Get buswidth information */
+                       busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+
+               } else {
+                       /* Old devices have this data hardcoded in the
+                        * device id table */
+                       mtd->erasesize = nand_flash_ids[i].erasesize;
+                       mtd->oobblock = nand_flash_ids[i].pagesize;
+                       mtd->oobsize = mtd->oobblock / 32;
+                       busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16;
+               }
+
+               /* Check, if buswidth is correct. Hardware drivers should set
+                * this correct ! */
+               if (busw != (this->options & NAND_BUSWIDTH_16)) {
+                       printk (KERN_INFO "NAND device: Manufacturer ID:"
+                               " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
+                               nand_manuf_ids[i].name , mtd->name);
+                       printk (KERN_WARNING
+                               "NAND bus width %d instead %d bit\n",
+                                       (this->options & NAND_BUSWIDTH_16) ? 16 : 8,
+                                       busw ? 16 : 8);
+                       this->select_chip(mtd, -1);
+                       return 1;
+               }
+
+               /* Calculate the address shift from the page size */
+               this->page_shift = ffs(mtd->oobblock) - 1;
+               this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1;
+               this->chip_shift = ffs(this->chipsize) - 1;
+
+               /* Set the bad block position */
+               this->badblockpos = mtd->oobblock > 512 ?
+                       NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
+
+               /* Get chip options, preserve non chip based options */
+               this->options &= ~NAND_CHIPOPTIONS_MSK;
+               this->options |= nand_flash_ids[i].options & NAND_CHIPOPTIONS_MSK;
+               /* Set this as a default. Board drivers can override it, if neccecary */
+               this->options |= NAND_NO_AUTOINCR;
+               /* Check if this is a not a samsung device. Do not clear the options
+                * for chips which are not having an extended id.
+                */
+               if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize)
+                       this->options &= ~NAND_SAMSUNG_LP_OPTIONS;
+
+               /* Check for AND chips with 4 page planes */
+               if (this->options & NAND_4PAGE_ARRAY)
+                       this->erase_cmd = multi_erase_cmd;
+               else
+                       this->erase_cmd = single_erase_cmd;
+
+               /* Do not replace user supplied command function ! */
+               if (mtd->oobblock > 512 && this->cmdfunc == nand_command)
+                       this->cmdfunc = nand_command_lp;
+
+               /* Try to identify manufacturer */
+               for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
+                       if (nand_manuf_ids[j].id == nand_maf_id)
+                               break;
+               }
+               break;
+       }
+
+       if (!nand_flash_ids[i].name) {
+#ifndef CFG_NAND_QUIET_TEST
+               printk (KERN_WARNING "No NAND device found!!!\n");
+#endif
+               this->select_chip(mtd, -1);
+               return 1;
+       }
+
+       for (i=1; i < maxchips; i++) {
+               this->select_chip(mtd, i);
+
+               /* Send the command for reading device ID */
+               this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
+
+               /* Read manufacturer and device IDs */
+               if (nand_maf_id != this->read_byte(mtd) ||
+                   nand_dev_id != this->read_byte(mtd))
+                       break;
+       }
+       if (i > 1)
+               printk(KERN_INFO "%d NAND chips detected\n", i);
+
+       /* Allocate buffers, if neccecary */
+       if (!this->oob_buf) {
+               size_t len;
+               len = mtd->oobsize << (this->phys_erase_shift - this->page_shift);
+               this->oob_buf = kmalloc (len, GFP_KERNEL);
+               if (!this->oob_buf) {
+                       printk (KERN_ERR "nand_scan(): Cannot allocate oob_buf\n");
+                       return -ENOMEM;
+               }
+               this->options |= NAND_OOBBUF_ALLOC;
+       }
+
+       if (!this->data_buf) {
+               size_t len;
+               len = mtd->oobblock + mtd->oobsize;
+               this->data_buf = kmalloc (len, GFP_KERNEL);
+               if (!this->data_buf) {
+                       if (this->options & NAND_OOBBUF_ALLOC)
+                               kfree (this->oob_buf);
+                       printk (KERN_ERR "nand_scan(): Cannot allocate data_buf\n");
+                       return -ENOMEM;
+               }
+               this->options |= NAND_DATABUF_ALLOC;
+       }
+
+       /* Store the number of chips and calc total size for mtd */
+       this->numchips = i;
+       mtd->size = i * this->chipsize;
+       /* Convert chipsize to number of pages per chip -1. */
+       this->pagemask = (this->chipsize >> this->page_shift) - 1;
+       /* Preset the internal oob buffer */
+       memset(this->oob_buf, 0xff, mtd->oobsize << (this->phys_erase_shift - this->page_shift));
+
+       /* If no default placement scheme is given, select an
+        * appropriate one */
+       if (!this->autooob) {
+               /* Select the appropriate default oob placement scheme for
+                * placement agnostic filesystems */
+               switch (mtd->oobsize) {
+               case 8:
+                       this->autooob = &nand_oob_8;
+                       break;
+               case 16:
+                       this->autooob = &nand_oob_16;
+                       break;
+               case 64:
+                       this->autooob = &nand_oob_64;
+                       break;
+               default:
+                       printk (KERN_WARNING "No oob scheme defined for oobsize %d\n",
+                               mtd->oobsize);
+/*                     BUG(); */
+               }
+       }
+
+       /* The number of bytes available for the filesystem to place fs dependend
+        * oob data */
+       if (this->options & NAND_BUSWIDTH_16) {
+               mtd->oobavail = mtd->oobsize - (this->autooob->eccbytes + 2);
+               if (this->autooob->eccbytes & 0x01)
+                       mtd->oobavail--;
+       } else
+               mtd->oobavail = mtd->oobsize - (this->autooob->eccbytes + 1);
+
+       /*
+        * check ECC mode, default to software
+        * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize
+        * fallback to software ECC
+       */
+       this->eccsize = 256;    /* set default eccsize */
+       this->eccbytes = 3;
+
+       switch (this->eccmode) {
+       case NAND_ECC_HW12_2048:
+               if (mtd->oobblock < 2048) {
+                       printk(KERN_WARNING "2048 byte HW ECC not possible on %d byte page size, fallback to SW ECC\n",
+                              mtd->oobblock);
+                       this->eccmode = NAND_ECC_SOFT;
+                       this->calculate_ecc = nand_calculate_ecc;
+                       this->correct_data = nand_correct_data;
+               } else
+                       this->eccsize = 2048;
+               break;
+
+       case NAND_ECC_HW3_512:
+       case NAND_ECC_HW6_512:
+       case NAND_ECC_HW8_512:
+               if (mtd->oobblock == 256) {
+                       printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n");
+                       this->eccmode = NAND_ECC_SOFT;
+                       this->calculate_ecc = nand_calculate_ecc;
+                       this->correct_data = nand_correct_data;
+               } else
+                       this->eccsize = 512; /* set eccsize to 512 */
+               break;
+
+       case NAND_ECC_HW3_256:
+               break;
+
+       case NAND_ECC_NONE:
+               printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n");
+               this->eccmode = NAND_ECC_NONE;
+               break;
+
+       case NAND_ECC_SOFT:
+               this->calculate_ecc = nand_calculate_ecc;
+               this->correct_data = nand_correct_data;
+               break;
+
+       default:
+               printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
+/*             BUG(); */
+       }
+
+       /* Check hardware ecc function availability and adjust number of ecc bytes per
+        * calculation step
+       */
+       switch (this->eccmode) {
+       case NAND_ECC_HW12_2048:
+               this->eccbytes += 4;
+       case NAND_ECC_HW8_512:
+               this->eccbytes += 2;
+       case NAND_ECC_HW6_512:
+               this->eccbytes += 3;
+       case NAND_ECC_HW3_512:
+       case NAND_ECC_HW3_256:
+               if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
+                       break;
+               printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
+/*             BUG();  */
+       }
+
+       mtd->eccsize = this->eccsize;
+
+       /* Set the number of read / write steps for one page to ensure ECC generation */
+       switch (this->eccmode) {
+       case NAND_ECC_HW12_2048:
+               this->eccsteps = mtd->oobblock / 2048;
+               break;
+       case NAND_ECC_HW3_512:
+       case NAND_ECC_HW6_512:
+       case NAND_ECC_HW8_512:
+               this->eccsteps = mtd->oobblock / 512;
+               break;
+       case NAND_ECC_HW3_256:
+       case NAND_ECC_SOFT:
+               this->eccsteps = mtd->oobblock / 256;
+               break;
+
+       case NAND_ECC_NONE:
+               this->eccsteps = 1;
+               break;
+       }
+
+/* XXX U-BOOT XXX */
+#if 0
+       /* Initialize state, waitqueue and spinlock */
+       this->state = FL_READY;
+       init_waitqueue_head (&this->wq);
+       spin_lock_init (&this->chip_lock);
+#endif
+
+       /* De-select the device */
+       this->select_chip(mtd, -1);
+
+       /* Invalidate the pagebuffer reference */
+       this->pagebuf = -1;
+
+       /* Fill in remaining MTD driver data */
+       mtd->type = MTD_NANDFLASH;
+       mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC;
+       mtd->ecctype = MTD_ECC_SW;
+       mtd->erase = nand_erase;
+       mtd->point = NULL;
+       mtd->unpoint = NULL;
+       mtd->read = nand_read;
+       mtd->write = nand_write;
+       mtd->read_ecc = nand_read_ecc;
+       mtd->write_ecc = nand_write_ecc;
+       mtd->read_oob = nand_read_oob;
+       mtd->write_oob = nand_write_oob;
+/* XXX U-BOOT XXX */
+#if 0
+       mtd->readv = NULL;
+       mtd->writev = nand_writev;
+       mtd->writev_ecc = nand_writev_ecc;
+#endif
+       mtd->sync = nand_sync;
+/* XXX U-BOOT XXX */
+#if 0
+       mtd->lock = NULL;
+       mtd->unlock = NULL;
+       mtd->suspend = NULL;
+       mtd->resume = NULL;
+#endif
+       mtd->block_isbad = nand_block_isbad;
+       mtd->block_markbad = nand_block_markbad;
+
+       /* and make the autooob the default one */
+       memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
+/* XXX U-BOOT XXX */
+#if 0
+       mtd->owner = THIS_MODULE;
+#endif
+       /* Build bad block table */
+       return this->scan_bbt (mtd);
+}
+
+/**
+ * nand_release - [NAND Interface] Free resources held by the NAND device
+ * @mtd:       MTD device structure
+ */
+void nand_release (struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+
+#ifdef CONFIG_MTD_PARTITIONS
+       /* Deregister partitions */
+       del_mtd_partitions (mtd);
+#endif
+       /* Deregister the device */
+/* XXX U-BOOT XXX */
+#if 0
+       del_mtd_device (mtd);
+#endif
+       /* Free bad block table memory, if allocated */
+       if (this->bbt)
+               kfree (this->bbt);
+       /* Buffer allocated by nand_scan ? */
+       if (this->options & NAND_OOBBUF_ALLOC)
+               kfree (this->oob_buf);
+       /* Buffer allocated by nand_scan ? */
+       if (this->options & NAND_DATABUF_ALLOC)
+               kfree (this->data_buf);
+}
+
+#endif
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
new file mode 100644 (file)
index 0000000..19a9bc2
--- /dev/null
@@ -0,0 +1,1052 @@
+/*
+ *  drivers/mtd/nand_bbt.c
+ *
+ *  Overview:
+ *   Bad block table support for the NAND driver
+ *
+ *  Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
+ *
+ * $Id: nand_bbt.c,v 1.28 2004/11/13 10:19:09 gleixner Exp $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Description:
+ *
+ * When nand_scan_bbt is called, then it tries to find the bad block table
+ * depending on the options in the bbt descriptor(s). If a bbt is found
+ * then the contents are read and the memory based bbt is created. If a
+ * mirrored bbt is selected then the mirror is searched too and the
+ * versions are compared. If the mirror has a greater version number
+ * than the mirror bbt is used to build the memory based bbt.
+ * If the tables are not versioned, then we "or" the bad block information.
+ * If one of the bbt's is out of date or does not exist it is (re)created.
+ * If no bbt exists at all then the device is scanned for factory marked
+ * good / bad blocks and the bad block tables are created.
+ *
+ * For manufacturer created bbts like the one found on M-SYS DOC devices
+ * the bbt is searched and read but never created
+ *
+ * The autogenerated bad block table is located in the last good blocks
+ * of the device. The table is mirrored, so it can be updated eventually.
+ * The table is marked in the oob area with an ident pattern and a version
+ * number which indicates which of both tables is more up to date.
+ *
+ * The table uses 2 bits per block
+ * 11b:        block is good
+ * 00b:        block is factory marked bad
+ * 01b, 10b:   block is marked bad due to wear
+ *
+ * The memory bad block table uses the following scheme:
+ * 00b:                block is good
+ * 01b:                block is marked bad due to wear
+ * 10b:                block is reserved (to protect the bbt area)
+ * 11b:                block is factory marked bad
+ *
+ * Multichip devices like DOC store the bad block info per floor.
+ *
+ * Following assumptions are made:
+ * - bbts start at a page boundary, if autolocated on a block boundary
+ * - the space neccecary for a bbt in FLASH does not exceed a block boundary
+ *
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
+
+#include <malloc.h>
+#include <linux/mtd/compat.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+
+#include <asm/errno.h>
+
+/**
+ * check_pattern - [GENERIC] check if a pattern is in the buffer
+ * @buf:       the buffer to search
+ * @len:       the length of buffer to search
+ * @paglen:    the pagelength
+ * @td:                search pattern descriptor
+ *
+ * Check for a pattern at the given place. Used to search bad block
+ * tables and good / bad block identifiers.
+ * If the SCAN_EMPTY option is set then check, if all bytes except the
+ * pattern area contain 0xff
+ *
+*/
+static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
+{
+       int i, end;
+       uint8_t *p = buf;
+
+       end = paglen + td->offs;
+       if (td->options & NAND_BBT_SCANEMPTY) {
+               for (i = 0; i < end; i++) {
+                       if (p[i] != 0xff)
+                               return -1;
+               }
+       }
+       p += end;
+
+       /* Compare the pattern */
+       for (i = 0; i < td->len; i++) {
+               if (p[i] != td->pattern[i])
+                       return -1;
+       }
+
+       p += td->len;
+       end += td->len;
+       if (td->options & NAND_BBT_SCANEMPTY) {
+               for (i = end; i < len; i++) {
+                       if (*p++ != 0xff)
+                               return -1;
+               }
+       }
+       return 0;
+}
+
+/**
+ * read_bbt - [GENERIC] Read the bad block table starting from page
+ * @mtd:       MTD device structure
+ * @buf:       temporary buffer
+ * @page:      the starting page
+ * @num:       the number of bbt descriptors to read
+ * @bits:      number of bits per block
+ * @offs:      offset in the memory table
+ * @reserved_block_code:       Pattern to identify reserved blocks
+ *
+ * Read the bad block table starting from page.
+ *
+ */
+static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
+       int bits, int offs, int reserved_block_code)
+{
+       int res, i, j, act = 0;
+       struct nand_chip *this = mtd->priv;
+       size_t retlen, len, totlen;
+       loff_t from;
+       uint8_t msk = (uint8_t) ((1 << bits) - 1);
+
+       totlen = (num * bits) >> 3;
+       from = ((loff_t)page) << this->page_shift;
+
+       while (totlen) {
+               len = min (totlen, (size_t) (1 << this->bbt_erase_shift));
+               res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob);
+               if (res < 0) {
+                       if (retlen != len) {
+                               printk (KERN_INFO "nand_bbt: Error reading bad block table\n");
+                               return res;
+                       }
+                       printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
+               }
+
+               /* Analyse data */
+               for (i = 0; i < len; i++) {
+                       uint8_t dat = buf[i];
+                       for (j = 0; j < 8; j += bits, act += 2) {
+                               uint8_t tmp = (dat >> j) & msk;
+                               if (tmp == msk)
+                                       continue;
+                               if (reserved_block_code &&
+                                   (tmp == reserved_block_code)) {
+                                       printk (KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n",
+                                               ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
+                                       this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
+                                       continue;
+                               }
+                               /* Leave it for now, if its matured we can move this
+                                * message to MTD_DEBUG_LEVEL0 */
+                               printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
+                                       ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
+                               /* Factory marked bad or worn out ? */
+                               if (tmp == 0)
+                                       this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
+                               else
+                                       this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06);
+                       }
+               }
+               totlen -= len;
+               from += len;
+       }
+       return 0;
+}
+
+/**
+ * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page
+ * @mtd:       MTD device structure
+ * @buf:       temporary buffer
+ * @td:                descriptor for the bad block table
+ * @chip:      read the table for a specific chip, -1 read all chips.
+ *             Applies only if NAND_BBT_PERCHIP option is set
+ *
+ * Read the bad block table for all chips starting at a given page
+ * We assume that the bbt bits are in consecutive order.
+*/
+static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
+{
+       struct nand_chip *this = mtd->priv;
+       int res = 0, i;
+       int bits;
+
+       bits = td->options & NAND_BBT_NRBITS_MSK;
+       if (td->options & NAND_BBT_PERCHIP) {
+               int offs = 0;
+               for (i = 0; i < this->numchips; i++) {
+                       if (chip == -1 || chip == i)
+                               res = read_bbt (mtd, buf, td->pages[i], this->chipsize >> this->bbt_erase_shift, bits, offs, td->reserved_block_code);
+                       if (res)
+                               return res;
+                       offs += this->chipsize >> (this->bbt_erase_shift + 2);
+               }
+       } else {
+               res = read_bbt (mtd, buf, td->pages[0], mtd->size >> this->bbt_erase_shift, bits, 0, td->reserved_block_code);
+               if (res)
+                       return res;
+       }
+       return 0;
+}
+
+/**
+ * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
+ * @mtd:       MTD device structure
+ * @buf:       temporary buffer
+ * @td:                descriptor for the bad block table
+ * @md:                descriptor for the bad block table mirror
+ *
+ * Read the bad block table(s) for all chips starting at a given page
+ * We assume that the bbt bits are in consecutive order.
+ *
+*/
+static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td,
+       struct nand_bbt_descr *md)
+{
+       struct nand_chip *this = mtd->priv;
+
+       /* Read the primary version, if available */
+       if (td->options & NAND_BBT_VERSION) {
+               nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
+               td->version[0] = buf[mtd->oobblock + td->veroffs];
+               printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]);
+       }
+
+       /* Read the mirror version, if available */
+       if (md && (md->options & NAND_BBT_VERSION)) {
+               nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
+               md->version[0] = buf[mtd->oobblock + md->veroffs];
+               printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]);
+       }
+
+       return 1;
+}
+
+/**
+ * create_bbt - [GENERIC] Create a bad block table by scanning the device
+ * @mtd:       MTD device structure
+ * @buf:       temporary buffer
+ * @bd:                descriptor for the good/bad block search pattern
+ * @chip:      create the table for a specific chip, -1 read all chips.
+ *             Applies only if NAND_BBT_PERCHIP option is set
+ *
+ * Create a bad block table by scanning the device
+ * for the given good/bad block identify pattern
+ */
+static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
+{
+       struct nand_chip *this = mtd->priv;
+       int i, j, numblocks, len, scanlen;
+       int startblock;
+       loff_t from;
+       size_t readlen, ooblen;
+
+       if (bd->options & NAND_BBT_SCANALLPAGES)
+               len = 1 << (this->bbt_erase_shift - this->page_shift);
+       else {
+               if (bd->options & NAND_BBT_SCAN2NDPAGE)
+                       len = 2;
+               else
+                       len = 1;
+       }
+       scanlen = mtd->oobblock + mtd->oobsize;
+       readlen = len * mtd->oobblock;
+       ooblen = len * mtd->oobsize;
+
+       if (chip == -1) {
+               /* Note that numblocks is 2 * (real numblocks) here, see i+=2 below as it
+                * makes shifting and masking less painful */
+               numblocks = mtd->size >> (this->bbt_erase_shift - 1);
+               startblock = 0;
+               from = 0;
+       } else {
+               if (chip >= this->numchips) {
+                       printk (KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n",
+                               chip + 1, this->numchips);
+                       return;
+               }
+               numblocks = this->chipsize >> (this->bbt_erase_shift - 1);
+               startblock = chip * numblocks;
+               numblocks += startblock;
+               from = startblock << (this->bbt_erase_shift - 1);
+       }
+
+       for (i = startblock; i < numblocks;) {
+               nand_read_raw (mtd, buf, from, readlen, ooblen);
+               for (j = 0; j < len; j++) {
+                       if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
+                               this->bbt[i >> 3] |= 0x03 << (i & 0x6);
+                               break;
+                       }
+               }
+               i += 2;
+               from += (1 << this->bbt_erase_shift);
+       }
+}
+
+/**
+ * search_bbt - [GENERIC] scan the device for a specific bad block table
+ * @mtd:       MTD device structure
+ * @buf:       temporary buffer
+ * @td:                descriptor for the bad block table
+ *
+ * Read the bad block table by searching for a given ident pattern.
+ * Search is preformed either from the beginning up or from the end of
+ * the device downwards. The search starts always at the start of a
+ * block.
+ * If the option NAND_BBT_PERCHIP is given, each chip is searched
+ * for a bbt, which contains the bad block information of this chip.
+ * This is neccecary to provide support for certain DOC devices.
+ *
+ * The bbt ident pattern resides in the oob area of the first page
+ * in a block.
+ */
+static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
+{
+       struct nand_chip *this = mtd->priv;
+       int i, chips;
+       int bits, startblock, block, dir;
+       int scanlen = mtd->oobblock + mtd->oobsize;
+       int bbtblocks;
+
+       /* Search direction top -> down ? */
+       if (td->options & NAND_BBT_LASTBLOCK) {
+               startblock = (mtd->size >> this->bbt_erase_shift) -1;
+               dir = -1;
+       } else {
+               startblock = 0;
+               dir = 1;
+       }
+
+       /* Do we have a bbt per chip ? */
+       if (td->options & NAND_BBT_PERCHIP) {
+               chips = this->numchips;
+               bbtblocks = this->chipsize >> this->bbt_erase_shift;
+               startblock &= bbtblocks - 1;
+       } else {
+               chips = 1;
+               bbtblocks = mtd->size >> this->bbt_erase_shift;
+       }
+
+       /* Number of bits for each erase block in the bbt */
+       bits = td->options & NAND_BBT_NRBITS_MSK;
+
+       for (i = 0; i < chips; i++) {
+               /* Reset version information */
+               td->version[i] = 0;
+               td->pages[i] = -1;
+               /* Scan the maximum number of blocks */
+               for (block = 0; block < td->maxblocks; block++) {
+                       int actblock = startblock + dir * block;
+                       /* Read first page */
+                       nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize);
+                       if (!check_pattern(buf, scanlen, mtd->oobblock, td)) {
+                               td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift);
+                               if (td->options & NAND_BBT_VERSION) {
+                                       td->version[i] = buf[mtd->oobblock + td->veroffs];
+                               }
+                               break;
+                       }
+               }
+               startblock += this->chipsize >> this->bbt_erase_shift;
+       }
+       /* Check, if we found a bbt for each requested chip */
+       for (i = 0; i < chips; i++) {
+               if (td->pages[i] == -1)
+                       printk (KERN_WARNING "Bad block table not found for chip %d\n", i);
+               else
+                       printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]);
+       }
+       return 0;
+}
+
+/**
+ * search_read_bbts - [GENERIC] scan the device for bad block table(s)
+ * @mtd:       MTD device structure
+ * @buf:       temporary buffer
+ * @td:                descriptor for the bad block table
+ * @md:                descriptor for the bad block table mirror
+ *
+ * Search and read the bad block table(s)
+*/
+static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
+       struct nand_bbt_descr *td, struct nand_bbt_descr *md)
+{
+       /* Search the primary table */
+       search_bbt (mtd, buf, td);
+
+       /* Search the mirror table */
+       if (md)
+               search_bbt (mtd, buf, md);
+
+       /* Force result check */
+       return 1;
+}
+
+
+/**
+ * write_bbt - [GENERIC] (Re)write the bad block table
+ *
+ * @mtd:       MTD device structure
+ * @buf:       temporary buffer
+ * @td:                descriptor for the bad block table
+ * @md:                descriptor for the bad block table mirror
+ * @chipsel:   selector for a specific chip, -1 for all
+ *
+ * (Re)write the bad block table
+ *
+*/
+static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
+       struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel)
+{
+       struct nand_chip *this = mtd->priv;
+       struct nand_oobinfo oobinfo;
+       struct erase_info einfo;
+       int i, j, res, chip = 0;
+       int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
+       int nrchips, bbtoffs, pageoffs;
+       uint8_t msk[4];
+       uint8_t rcode = td->reserved_block_code;
+       size_t retlen, len = 0;
+       loff_t to;
+
+       if (!rcode)
+               rcode = 0xff;
+       /* Write bad block table per chip rather than per device ? */
+       if (td->options & NAND_BBT_PERCHIP) {
+               numblocks = (int) (this->chipsize >> this->bbt_erase_shift);
+               /* Full device write or specific chip ? */
+               if (chipsel == -1) {
+                       nrchips = this->numchips;
+               } else {
+                       nrchips = chipsel + 1;
+                       chip = chipsel;
+               }
+       } else {
+               numblocks = (int) (mtd->size >> this->bbt_erase_shift);
+               nrchips = 1;
+       }
+
+       /* Loop through the chips */
+       for (; chip < nrchips; chip++) {
+
+               /* There was already a version of the table, reuse the page
+                * This applies for absolute placement too, as we have the
+                * page nr. in td->pages.
+                */
+               if (td->pages[chip] != -1) {
+                       page = td->pages[chip];
+                       goto write;
+               }
+
+               /* Automatic placement of the bad block table */
+               /* Search direction top -> down ? */
+               if (td->options & NAND_BBT_LASTBLOCK) {
+                       startblock = numblocks * (chip + 1) - 1;
+                       dir = -1;
+               } else {
+                       startblock = chip * numblocks;
+                       dir = 1;
+               }
+
+               for (i = 0; i < td->maxblocks; i++) {
+                       int block = startblock + dir * i;
+                       /* Check, if the block is bad */
+                       switch ((this->bbt[block >> 2] >> (2 * (block & 0x03))) & 0x03) {
+                       case 0x01:
+                       case 0x03:
+                               continue;
+                       }
+                       page = block << (this->bbt_erase_shift - this->page_shift);
+                       /* Check, if the block is used by the mirror table */
+                       if (!md || md->pages[chip] != page)
+                               goto write;
+               }
+               printk (KERN_ERR "No space left to write bad block table\n");
+               return -ENOSPC;
+write:
+
+               /* Set up shift count and masks for the flash table */
+               bits = td->options & NAND_BBT_NRBITS_MSK;
+               switch (bits) {
+               case 1: sft = 3; sftmsk = 0x07; msk[0] = 0x00; msk[1] = 0x01; msk[2] = ~rcode; msk[3] = 0x01; break;
+               case 2: sft = 2; sftmsk = 0x06; msk[0] = 0x00; msk[1] = 0x01; msk[2] = ~rcode; msk[3] = 0x03; break;
+               case 4: sft = 1; sftmsk = 0x04; msk[0] = 0x00; msk[1] = 0x0C; msk[2] = ~rcode; msk[3] = 0x0f; break;
+               case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break;
+               default: return -EINVAL;
+               }
+
+               bbtoffs = chip * (numblocks >> 2);
+
+               to = ((loff_t) page) << this->page_shift;
+
+               memcpy (&oobinfo, this->autooob, sizeof(oobinfo));
+               oobinfo.useecc = MTD_NANDECC_PLACEONLY;
+
+               /* Must we save the block contents ? */
+               if (td->options & NAND_BBT_SAVECONTENT) {
+                       /* Make it block aligned */
+                       to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1));
+                       len = 1 << this->bbt_erase_shift;
+                       res = mtd->read_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
+                       if (res < 0) {
+                               if (retlen != len) {
+                                       printk (KERN_INFO "nand_bbt: Error reading block for writing the bad block table\n");
+                                       return res;
+                               }
+                               printk (KERN_WARNING "nand_bbt: ECC error while reading block for writing bad block table\n");
+                       }
+                       /* Calc the byte offset in the buffer */
+                       pageoffs = page - (int)(to >> this->page_shift);
+                       offs = pageoffs << this->page_shift;
+                       /* Preset the bbt area with 0xff */
+                       memset (&buf[offs], 0xff, (size_t)(numblocks >> sft));
+                       /* Preset the bbt's oob area with 0xff */
+                       memset (&buf[len + pageoffs * mtd->oobsize], 0xff,
+                               ((len >> this->page_shift) - pageoffs) * mtd->oobsize);
+                       if (td->options & NAND_BBT_VERSION) {
+                               buf[len + (pageoffs * mtd->oobsize) + td->veroffs] = td->version[chip];
+                       }
+               } else {
+                       /* Calc length */
+                       len = (size_t) (numblocks >> sft);
+                       /* Make it page aligned ! */
+                       len = (len + (mtd->oobblock-1)) & ~(mtd->oobblock-1);
+                       /* Preset the buffer with 0xff */
+                       memset (buf, 0xff, len + (len >> this->page_shift) * mtd->oobsize);
+                       offs = 0;
+                       /* Pattern is located in oob area of first page */
+                       memcpy (&buf[len + td->offs], td->pattern, td->len);
+                       if (td->options & NAND_BBT_VERSION) {
+                               buf[len + td->veroffs] = td->version[chip];
+                       }
+               }
+
+               /* walk through the memory table */
+               for (i = 0; i < numblocks; ) {
+                       uint8_t dat;
+                       dat = this->bbt[bbtoffs + (i >> 2)];
+                       for (j = 0; j < 4; j++ , i++) {
+                               int sftcnt = (i << (3 - sft)) & sftmsk;
+                               /* Do not store the reserved bbt blocks ! */
+                               buf[offs + (i >> sft)] &= ~(msk[dat & 0x03] << sftcnt);
+                               dat >>= 2;
+                       }
+               }
+
+               memset (&einfo, 0, sizeof (einfo));
+               einfo.mtd = mtd;
+               einfo.addr = (unsigned long) to;
+               einfo.len = 1 << this->bbt_erase_shift;
+               res = nand_erase_nand (mtd, &einfo, 1);
+               if (res < 0) {
+                       printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res);
+                       return res;
+               }
+
+               res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
+               if (res < 0) {
+                       printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res);
+                       return res;
+               }
+               printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n",
+                       (unsigned int) to, td->version[chip]);
+
+               /* Mark it as used */
+               td->pages[chip] = page;
+       }
+       return 0;
+}
+
+/**
+ * nand_memory_bbt - [GENERIC] create a memory based bad block table
+ * @mtd:       MTD device structure
+ * @bd:                descriptor for the good/bad block search pattern
+ *
+ * The function creates a memory based bbt by scanning the device
+ * for manufacturer / software marked good / bad blocks
+*/
+static int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
+{
+       struct nand_chip *this = mtd->priv;
+
+       /* Ensure that we only scan for the pattern and nothing else */
+       bd->options = 0;
+       create_bbt (mtd, this->data_buf, bd, -1);
+       return 0;
+}
+
+/**
+ * check_create - [GENERIC] create and write bbt(s) if neccecary
+ * @mtd:       MTD device structure
+ * @buf:       temporary buffer
+ * @bd:                descriptor for the good/bad block search pattern
+ *
+ * The function checks the results of the previous call to read_bbt
+ * and creates / updates the bbt(s) if neccecary
+ * Creation is neccecary if no bbt was found for the chip/device
+ * Update is neccecary if one of the tables is missing or the
+ * version nr. of one table is less than the other
+*/
+static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
+{
+       int i, chips, writeops, chipsel, res;
+       struct nand_chip *this = mtd->priv;
+       struct nand_bbt_descr *td = this->bbt_td;
+       struct nand_bbt_descr *md = this->bbt_md;
+       struct nand_bbt_descr *rd, *rd2;
+
+       /* Do we have a bbt per chip ? */
+       if (td->options & NAND_BBT_PERCHIP)
+               chips = this->numchips;
+       else
+               chips = 1;
+
+       for (i = 0; i < chips; i++) {
+               writeops = 0;
+               rd = NULL;
+               rd2 = NULL;
+               /* Per chip or per device ? */
+               chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1;
+               /* Mirrored table avilable ? */
+               if (md) {
+                       if (td->pages[i] == -1 && md->pages[i] == -1) {
+                               writeops = 0x03;
+                               goto create;
+                       }
+
+                       if (td->pages[i] == -1) {
+                               rd = md;
+                               td->version[i] = md->version[i];
+                               writeops = 1;
+                               goto writecheck;
+                       }
+
+                       if (md->pages[i] == -1) {
+                               rd = td;
+                               md->version[i] = td->version[i];
+                               writeops = 2;
+                               goto writecheck;
+                       }
+
+                       if (td->version[i] == md->version[i]) {
+                               rd = td;
+                               if (!(td->options & NAND_BBT_VERSION))
+                                       rd2 = md;
+                               goto writecheck;
+                       }
+
+                       if (((int8_t) (td->version[i] - md->version[i])) > 0) {
+                               rd = td;
+                               md->version[i] = td->version[i];
+                               writeops = 2;
+                       } else {
+                               rd = md;
+                               td->version[i] = md->version[i];
+                               writeops = 1;
+                       }
+
+                       goto writecheck;
+
+               } else {
+                       if (td->pages[i] == -1) {
+                               writeops = 0x01;
+                               goto create;
+                       }
+                       rd = td;
+                       goto writecheck;
+               }
+create:
+               /* Create the bad block table by scanning the device ? */
+               if (!(td->options & NAND_BBT_CREATE))
+                       continue;
+
+               /* Create the table in memory by scanning the chip(s) */
+               create_bbt (mtd, buf, bd, chipsel);
+
+               td->version[i] = 1;
+               if (md)
+                       md->version[i] = 1;
+writecheck:
+               /* read back first ? */
+               if (rd)
+                       read_abs_bbt (mtd, buf, rd, chipsel);
+               /* If they weren't versioned, read both. */
+               if (rd2)
+                       read_abs_bbt (mtd, buf, rd2, chipsel);
+
+               /* Write the bad block table to the device ? */
+               if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
+                       res = write_bbt (mtd, buf, td, md, chipsel);
+                       if (res < 0)
+                               return res;
+               }
+
+               /* Write the mirror bad block table to the device ? */
+               if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
+                       res = write_bbt (mtd, buf, md, td, chipsel);
+                       if (res < 0)
+                               return res;
+               }
+       }
+       return 0;
+}
+
+/**
+ * mark_bbt_regions - [GENERIC] mark the bad block table regions
+ * @mtd:       MTD device structure
+ * @td:                bad block table descriptor
+ *
+ * The bad block table regions are marked as "bad" to prevent
+ * accidental erasures / writes. The regions are identified by
+ * the mark 0x02.
+*/
+static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
+{
+       struct nand_chip *this = mtd->priv;
+       int i, j, chips, block, nrblocks, update;
+       uint8_t oldval, newval;
+
+       /* Do we have a bbt per chip ? */
+       if (td->options & NAND_BBT_PERCHIP) {
+               chips = this->numchips;
+               nrblocks = (int)(this->chipsize >> this->bbt_erase_shift);
+       } else {
+               chips = 1;
+               nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
+       }
+
+       for (i = 0; i < chips; i++) {
+               if ((td->options & NAND_BBT_ABSPAGE) ||
+                   !(td->options & NAND_BBT_WRITE)) {
+                       if (td->pages[i] == -1) continue;
+                       block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
+                       block <<= 1;
+                       oldval = this->bbt[(block >> 3)];
+                       newval = oldval | (0x2 << (block & 0x06));
+                       this->bbt[(block >> 3)] = newval;
+                       if ((oldval != newval) && td->reserved_block_code)
+                               nand_update_bbt(mtd, block << (this->bbt_erase_shift - 1));
+                       continue;
+               }
+               update = 0;
+               if (td->options & NAND_BBT_LASTBLOCK)
+                       block = ((i + 1) * nrblocks) - td->maxblocks;
+               else
+                       block = i * nrblocks;
+               block <<= 1;
+               for (j = 0; j < td->maxblocks; j++) {
+                       oldval = this->bbt[(block >> 3)];
+                       newval = oldval | (0x2 << (block & 0x06));
+                       this->bbt[(block >> 3)] = newval;
+                       if (oldval != newval) update = 1;
+                       block += 2;
+               }
+               /* If we want reserved blocks to be recorded to flash, and some
+                  new ones have been marked, then we need to update the stored
+                  bbts.  This should only happen once. */
+               if (update && td->reserved_block_code)
+                       nand_update_bbt(mtd, (block - 2) << (this->bbt_erase_shift - 1));
+       }
+}
+
+/**
+ * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s)
+ * @mtd:       MTD device structure
+ * @bd:                descriptor for the good/bad block search pattern
+ *
+ * The function checks, if a bad block table(s) is/are already
+ * available. If not it scans the device for manufacturer
+ * marked good / bad blocks and writes the bad block table(s) to
+ * the selected place.
+ *
+ * The bad block table memory is allocated here. It must be freed
+ * by calling the nand_free_bbt function.
+ *
+*/
+int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
+{
+       struct nand_chip *this = mtd->priv;
+       int len, res = 0;
+       uint8_t *buf;
+       struct nand_bbt_descr *td = this->bbt_td;
+       struct nand_bbt_descr *md = this->bbt_md;
+
+       len = mtd->size >> (this->bbt_erase_shift + 2);
+       /* Allocate memory (2bit per block) */
+       this->bbt = kmalloc (len, GFP_KERNEL);
+       if (!this->bbt) {
+               printk (KERN_ERR "nand_scan_bbt: Out of memory\n");
+               return -ENOMEM;
+       }
+       /* Clear the memory bad block table */
+       memset (this->bbt, 0x00, len);
+
+       /* If no primary table decriptor is given, scan the device
+        * to build a memory based bad block table
+        */
+       if (!td)
+               return nand_memory_bbt(mtd, bd);
+
+       /* Allocate a temporary buffer for one eraseblock incl. oob */
+       len = (1 << this->bbt_erase_shift);
+       len += (len >> this->page_shift) * mtd->oobsize;
+       buf = kmalloc (len, GFP_KERNEL);
+       if (!buf) {
+               printk (KERN_ERR "nand_bbt: Out of memory\n");
+               kfree (this->bbt);
+               this->bbt = NULL;
+               return -ENOMEM;
+       }
+
+       /* Is the bbt at a given page ? */
+       if (td->options & NAND_BBT_ABSPAGE) {
+               res = read_abs_bbts (mtd, buf, td, md);
+       } else {
+               /* Search the bad block table using a pattern in oob */
+               res = search_read_bbts (mtd, buf, td, md);
+       }
+
+       if (res)
+               res = check_create (mtd, buf, bd);
+
+       /* Prevent the bbt regions from erasing / writing */
+       mark_bbt_region (mtd, td);
+       if (md)
+               mark_bbt_region (mtd, md);
+
+       kfree (buf);
+       return res;
+}
+
+
+/**
+ * nand_update_bbt - [NAND Interface] update bad block table(s)
+ * @mtd:       MTD device structure
+ * @offs:      the offset of the newly marked block
+ *
+ * The function updates the bad block table(s)
+*/
+int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
+{
+       struct nand_chip *this = mtd->priv;
+       int len, res = 0, writeops = 0;
+       int chip, chipsel;
+       uint8_t *buf;
+       struct nand_bbt_descr *td = this->bbt_td;
+       struct nand_bbt_descr *md = this->bbt_md;
+
+       if (!this->bbt || !td)
+               return -EINVAL;
+
+       len = mtd->size >> (this->bbt_erase_shift + 2);
+       /* Allocate a temporary buffer for one eraseblock incl. oob */
+       len = (1 << this->bbt_erase_shift);
+       len += (len >> this->page_shift) * mtd->oobsize;
+       buf = kmalloc (len, GFP_KERNEL);
+       if (!buf) {
+               printk (KERN_ERR "nand_update_bbt: Out of memory\n");
+               return -ENOMEM;
+       }
+
+       writeops = md != NULL ? 0x03 : 0x01;
+
+       /* Do we have a bbt per chip ? */
+       if (td->options & NAND_BBT_PERCHIP) {
+               chip = (int) (offs >> this->chip_shift);
+               chipsel = chip;
+       } else {
+               chip = 0;
+               chipsel = -1;
+       }
+
+       td->version[chip]++;
+       if (md)
+               md->version[chip]++;
+
+       /* Write the bad block table to the device ? */
+       if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
+               res = write_bbt (mtd, buf, td, md, chipsel);
+               if (res < 0)
+                       goto out;
+       }
+       /* Write the mirror bad block table to the device ? */
+       if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
+               res = write_bbt (mtd, buf, md, td, chipsel);
+       }
+
+out:
+       kfree (buf);
+       return res;
+}
+
+/* Define some generic bad / good block scan pattern which are used
+ * while scanning a device for factory marked good / bad blocks
+ *
+ * The memory based patterns just
+ */
+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+
+static struct nand_bbt_descr smallpage_memorybased = {
+       .options = 0,
+       .offs = 5,
+       .len = 1,
+       .pattern = scan_ff_pattern
+};
+
+static struct nand_bbt_descr largepage_memorybased = {
+       .options = 0,
+       .offs = 0,
+       .len = 2,
+       .pattern = scan_ff_pattern
+};
+
+static struct nand_bbt_descr smallpage_flashbased = {
+       .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
+       .offs = 5,
+       .len = 1,
+       .pattern = scan_ff_pattern
+};
+
+static struct nand_bbt_descr largepage_flashbased = {
+       .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
+       .offs = 0,
+       .len = 2,
+       .pattern = scan_ff_pattern
+};
+
+static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 };
+
+static struct nand_bbt_descr agand_flashbased = {
+       .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
+       .offs = 0x20,
+       .len = 6,
+       .pattern = scan_agand_pattern
+};
+
+/* Generic flash bbt decriptors
+*/
+static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
+static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
+
+static struct nand_bbt_descr bbt_main_descr = {
+       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+               | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+       .offs = 8,
+       .len = 4,
+       .veroffs = 12,
+       .maxblocks = 4,
+       .pattern = bbt_pattern
+};
+
+static struct nand_bbt_descr bbt_mirror_descr = {
+       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+               | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+       .offs = 8,
+       .len = 4,
+       .veroffs = 12,
+       .maxblocks = 4,
+       .pattern = mirror_pattern
+};
+
+/**
+ * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
+ * @mtd:       MTD device structure
+ *
+ * This function selects the default bad block table
+ * support for the device and calls the nand_scan_bbt function
+ *
+*/
+int nand_default_bbt (struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+
+       /* Default for AG-AND. We must use a flash based
+        * bad block table as the devices have factory marked
+        * _good_ blocks. Erasing those blocks leads to loss
+        * of the good / bad information, so we _must_ store
+        * this information in a good / bad table during
+        * startup
+       */
+       if (this->options & NAND_IS_AND) {
+               /* Use the default pattern descriptors */
+               if (!this->bbt_td) {
+                       this->bbt_td = &bbt_main_descr;
+                       this->bbt_md = &bbt_mirror_descr;
+               }
+               this->options |= NAND_USE_FLASH_BBT;
+               return nand_scan_bbt (mtd, &agand_flashbased);
+       }
+
+
+       /* Is a flash based bad block table requested ? */
+       if (this->options & NAND_USE_FLASH_BBT) {
+               /* Use the default pattern descriptors */
+               if (!this->bbt_td) {
+                       this->bbt_td = &bbt_main_descr;
+                       this->bbt_md = &bbt_mirror_descr;
+               }
+               if (!this->badblock_pattern) {
+                       this->badblock_pattern = (mtd->oobblock > 512) ?
+                               &largepage_flashbased : &smallpage_flashbased;
+               }
+       } else {
+               this->bbt_td = NULL;
+               this->bbt_md = NULL;
+               if (!this->badblock_pattern) {
+                       this->badblock_pattern = (mtd->oobblock > 512) ?
+                               &largepage_memorybased : &smallpage_memorybased;
+               }
+       }
+       return nand_scan_bbt (mtd, this->badblock_pattern);
+}
+
+/**
+ * nand_isbad_bbt - [NAND Interface] Check if a block is bad
+ * @mtd:       MTD device structure
+ * @offs:      offset in the device
+ * @allowbbt:  allow access to bad block table region
+ *
+ */
+int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt)
+{
+       struct nand_chip *this = mtd->priv;
+       int block;
+       uint8_t res;
+
+       /* Get block number * 2 */
+       block = (int) (offs >> (this->bbt_erase_shift - 1));
+       res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
+
+       DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
+               (unsigned int)offs, res, block >> 1);
+
+       switch ((int)res) {
+       case 0x00:      return 0;
+       case 0x01:      return 1;
+       case 0x02:      return allowbbt ? 0 : 1;
+       }
+       return 1;
+}
+
+#endif
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
new file mode 100644 (file)
index 0000000..4c532b0
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * This file contains an ECC algorithm from Toshiba that detects and
+ * corrects 1 bit errors in a 256 byte block of data.
+ *
+ * drivers/mtd/nand/nand_ecc.c
+ *
+ * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com)
+ *                         Toshiba America Electronics Components, Inc.
+ *
+ * $Id: nand_ecc.c,v 1.14 2004/06/16 15:34:37 gleixner Exp $
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 or (at your option) any
+ * later version.
+ *
+ * This file is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this file; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * As a special exception, if other files instantiate templates or use
+ * macros or inline functions from these files, or you compile these
+ * files and link them with other works to produce a work based on these
+ * files, these files do not by themselves cause the resulting work to be
+ * covered by the GNU General Public License. However the source code for
+ * these files must still be made available in accordance with section (3)
+ * of the GNU General Public License.
+ *
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
+
+#include<linux/mtd/mtd.h>
+
+/*
+ * NAND-SPL has no sofware ECC for now, so don't include nand_calculate_ecc(),
+ * only nand_correct_data() is needed
+ */
+
+#ifndef CONFIG_NAND_SPL
+/*
+ * Pre-calculated 256-way 1 byte column parity
+ */
+static const u_char nand_ecc_precalc_table[] = {
+       0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
+       0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
+       0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
+       0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
+       0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
+       0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
+       0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
+       0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
+       0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
+       0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
+       0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
+       0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
+       0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
+       0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
+       0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
+       0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
+};
+
+/**
+ * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256-byte block
+ * @mtd:       MTD block structure
+ * @dat:       raw data
+ * @ecc_code:  buffer for ECC
+ */
+int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
+                      u_char *ecc_code)
+{
+       uint8_t idx, reg1, reg2, reg3, tmp1, tmp2;
+       int i;
+
+       /* Initialize variables */
+       reg1 = reg2 = reg3 = 0;
+
+       /* Build up column parity */
+       for(i = 0; i < 256; i++) {
+               /* Get CP0 - CP5 from table */
+               idx = nand_ecc_precalc_table[*dat++];
+               reg1 ^= (idx & 0x3f);
+
+               /* All bit XOR = 1 ? */
+               if (idx & 0x40) {
+                       reg3 ^= (uint8_t) i;
+                       reg2 ^= ~((uint8_t) i);
+               }
+       }
+
+       /* Create non-inverted ECC code from line parity */
+       tmp1  = (reg3 & 0x80) >> 0; /* B7 -> B7 */
+       tmp1 |= (reg2 & 0x80) >> 1; /* B7 -> B6 */
+       tmp1 |= (reg3 & 0x40) >> 1; /* B6 -> B5 */
+       tmp1 |= (reg2 & 0x40) >> 2; /* B6 -> B4 */
+       tmp1 |= (reg3 & 0x20) >> 2; /* B5 -> B3 */
+       tmp1 |= (reg2 & 0x20) >> 3; /* B5 -> B2 */
+       tmp1 |= (reg3 & 0x10) >> 3; /* B4 -> B1 */
+       tmp1 |= (reg2 & 0x10) >> 4; /* B4 -> B0 */
+
+       tmp2  = (reg3 & 0x08) << 4; /* B3 -> B7 */
+       tmp2 |= (reg2 & 0x08) << 3; /* B3 -> B6 */
+       tmp2 |= (reg3 & 0x04) << 3; /* B2 -> B5 */
+       tmp2 |= (reg2 & 0x04) << 2; /* B2 -> B4 */
+       tmp2 |= (reg3 & 0x02) << 2; /* B1 -> B3 */
+       tmp2 |= (reg2 & 0x02) << 1; /* B1 -> B2 */
+       tmp2 |= (reg3 & 0x01) << 1; /* B0 -> B1 */
+       tmp2 |= (reg2 & 0x01) << 0; /* B7 -> B0 */
+
+       /* Calculate final ECC code */
+#ifdef CONFIG_MTD_NAND_ECC_SMC
+       ecc_code[0] = ~tmp2;
+       ecc_code[1] = ~tmp1;
+#else
+       ecc_code[0] = ~tmp1;
+       ecc_code[1] = ~tmp2;
+#endif
+       ecc_code[2] = ((~reg1) << 2) | 0x03;
+
+       return 0;
+}
+#endif /* CONFIG_NAND_SPL */
+
+static inline int countbits(uint32_t byte)
+{
+       int res = 0;
+
+       for (;byte; byte >>= 1)
+               res += byte & 0x01;
+       return res;
+}
+
+/**
+ * nand_correct_data - [NAND Interface] Detect and correct bit error(s)
+ * @mtd:       MTD block structure
+ * @dat:       raw data read from the chip
+ * @read_ecc:  ECC from the chip
+ * @calc_ecc:  the ECC calculated from raw data
+ *
+ * Detect and correct a 1 bit error for 256 byte block
+ */
+int nand_correct_data(struct mtd_info *mtd, u_char *dat,
+                     u_char *read_ecc, u_char *calc_ecc)
+{
+       uint8_t s0, s1, s2;
+
+#ifdef CONFIG_MTD_NAND_ECC_SMC
+       s0 = calc_ecc[0] ^ read_ecc[0];
+       s1 = calc_ecc[1] ^ read_ecc[1];
+       s2 = calc_ecc[2] ^ read_ecc[2];
+#else
+       s1 = calc_ecc[0] ^ read_ecc[0];
+       s0 = calc_ecc[1] ^ read_ecc[1];
+       s2 = calc_ecc[2] ^ read_ecc[2];
+#endif
+       if ((s0 | s1 | s2) == 0)
+               return 0;
+
+       /* Check for a single bit error */
+       if( ((s0 ^ (s0 >> 1)) & 0x55) == 0x55 &&
+           ((s1 ^ (s1 >> 1)) & 0x55) == 0x55 &&
+           ((s2 ^ (s2 >> 1)) & 0x54) == 0x54) {
+
+               uint32_t byteoffs, bitnum;
+
+               byteoffs = (s1 << 0) & 0x80;
+               byteoffs |= (s1 << 1) & 0x40;
+               byteoffs |= (s1 << 2) & 0x20;
+               byteoffs |= (s1 << 3) & 0x10;
+
+               byteoffs |= (s0 >> 4) & 0x08;
+               byteoffs |= (s0 >> 3) & 0x04;
+               byteoffs |= (s0 >> 2) & 0x02;
+               byteoffs |= (s0 >> 1) & 0x01;
+
+               bitnum = (s2 >> 5) & 0x04;
+               bitnum |= (s2 >> 4) & 0x02;
+               bitnum |= (s2 >> 3) & 0x01;
+
+               dat[byteoffs] ^= (1 << bitnum);
+
+               return 1;
+       }
+
+       if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1)
+               return 1;
+
+       return -1;
+}
+
+#endif
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
new file mode 100644 (file)
index 0000000..6d7e347
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ *  drivers/mtd/nandids.c
+ *
+ *  Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de)
+  *
+ * $Id: nand_ids.c,v 1.10 2004/05/26 13:40:12 gleixner Exp $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
+
+#include <linux/mtd/nand.h>
+
+/*
+*      Chip ID list
+*
+*      Name. ID code, pagesize, chipsize in MegaByte, eraseblock size,
+*      options
+*
+*      Pagesize; 0, 256, 512
+*      0       get this information from the extended chip ID
++      256     256 Byte page size
+*      512     512 Byte page size
+*/
+struct nand_flash_dev nand_flash_ids[] = {
+       {"NAND 1MiB 5V 8-bit",          0x6e, 256, 1, 0x1000, 0},
+       {"NAND 2MiB 5V 8-bit",          0x64, 256, 2, 0x1000, 0},
+       {"NAND 4MiB 5V 8-bit",          0x6b, 512, 4, 0x2000, 0},
+       {"NAND 1MiB 3,3V 8-bit",        0xe8, 256, 1, 0x1000, 0},
+       {"NAND 1MiB 3,3V 8-bit",        0xec, 256, 1, 0x1000, 0},
+       {"NAND 2MiB 3,3V 8-bit",        0xea, 256, 2, 0x1000, 0},
+       {"NAND 4MiB 3,3V 8-bit",        0xd5, 512, 4, 0x2000, 0},
+       {"NAND 4MiB 3,3V 8-bit",        0xe3, 512, 4, 0x2000, 0},
+       {"NAND 4MiB 3,3V 8-bit",        0xe5, 512, 4, 0x2000, 0},
+       {"NAND 8MiB 3,3V 8-bit",        0xd6, 512, 8, 0x2000, 0},
+
+       {"NAND 8MiB 1,8V 8-bit",        0x39, 512, 8, 0x2000, 0},
+       {"NAND 8MiB 3,3V 8-bit",        0xe6, 512, 8, 0x2000, 0},
+       {"NAND 8MiB 1,8V 16-bit",       0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},
+       {"NAND 8MiB 3,3V 16-bit",       0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},
+
+       {"NAND 16MiB 1,8V 8-bit",       0x33, 512, 16, 0x4000, 0},
+       {"NAND 16MiB 3,3V 8-bit",       0x73, 512, 16, 0x4000, 0},
+       {"NAND 16MiB 1,8V 16-bit",      0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16},
+       {"NAND 16MiB 3,3V 16-bit",      0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16},
+
+       {"NAND 32MiB 1,8V 8-bit",       0x35, 512, 32, 0x4000, 0},
+       {"NAND 32MiB 3,3V 8-bit",       0x75, 512, 32, 0x4000, 0},
+       {"NAND 32MiB 1,8V 16-bit",      0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16},
+       {"NAND 32MiB 3,3V 16-bit",      0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16},
+
+       {"NAND 64MiB 1,8V 8-bit",       0x36, 512, 64, 0x4000, 0},
+       {"NAND 64MiB 3,3V 8-bit",       0x76, 512, 64, 0x4000, 0},
+       {"NAND 64MiB 1,8V 16-bit",      0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16},
+       {"NAND 64MiB 3,3V 16-bit",      0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
+
+       {"NAND 128MiB 1,8V 8-bit",      0x78, 512, 128, 0x4000, 0},
+       {"NAND 128MiB 3,3V 8-bit",      0x79, 512, 128, 0x4000, 0},
+       {"NAND 128MiB 1,8V 16-bit",     0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16},
+       {"NAND 128MiB 3,3V 16-bit",     0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
+
+       {"NAND 256MiB 3,3V 8-bit",      0x71, 512, 256, 0x4000, 0},
+
+       {"NAND 512MiB 3,3V 8-bit",      0xDC, 512, 512, 0x4000, 0},
+
+       /* These are the new chips with large page size. The pagesize
+       * and the erasesize is determined from the extended id bytes
+       */
+       /* 1 Gigabit */
+       {"NAND 128MiB 1,8V 8-bit",      0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
+       {"NAND 128MiB 3,3V 8-bit",      0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
+       {"NAND 128MiB 1,8V 16-bit",     0xB1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
+       {"NAND 128MiB 3,3V 16-bit",     0xC1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
+
+       /* 2 Gigabit */
+       {"NAND 256MiB 1,8V 8-bit",      0xAA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
+       {"NAND 256MiB 3,3V 8-bit",      0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
+       {"NAND 256MiB 1,8V 16-bit",     0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
+       {"NAND 256MiB 3,3V 16-bit",     0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
+
+       /* 4 Gigabit */
+       {"NAND 512MiB 1,8V 8-bit",      0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
+       {"NAND 512MiB 3,3V 8-bit",      0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
+       {"NAND 512MiB 1,8V 16-bit",     0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
+       {"NAND 512MiB 3,3V 16-bit",     0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
+
+       /* 8 Gigabit */
+       {"NAND 1GiB 1,8V 8-bit",        0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
+       {"NAND 1GiB 3,3V 8-bit",        0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
+       {"NAND 1GiB 1,8V 16-bit",       0xB3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
+       {"NAND 1GiB 3,3V 16-bit",       0xC3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
+
+       /* 16 Gigabit */
+       {"NAND 2GiB 1,8V 8-bit",        0xA5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
+       {"NAND 2GiB 3,3V 8-bit",        0xD5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
+       {"NAND 2GiB 1,8V 16-bit",       0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
+       {"NAND 2GiB 3,3V 16-bit",       0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
+
+       /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout !
+        * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes
+        * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7
+        * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go
+        * There are more speed improvements for reads and writes possible, but not implemented now
+        */
+       {"AND 128MiB 3,3V 8-bit",       0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY},
+
+       {NULL,}
+};
+
+/*
+*      Manufacturer ID list
+*/
+struct nand_manufacturers nand_manuf_ids[] = {
+       {NAND_MFR_TOSHIBA, "Toshiba"},
+       {NAND_MFR_SAMSUNG, "Samsung"},
+       {NAND_MFR_FUJITSU, "Fujitsu"},
+       {NAND_MFR_NATIONAL, "National"},
+       {NAND_MFR_RENESAS, "Renesas"},
+       {NAND_MFR_STMICRO, "ST Micro"},
+       {NAND_MFR_MICRON, "Micron"},
+       {0x0, "Unknown"}
+};
+#endif
diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c
new file mode 100644 (file)
index 0000000..4fd4e16
--- /dev/null
@@ -0,0 +1,872 @@
+/*
+ * drivers/nand/nand_util.c
+ *
+ * Copyright (C) 2006 by Weiss-Electronic GmbH.
+ * All rights reserved.
+ *
+ * @author:    Guido Classen <clagix@gmail.com>
+ * @descr:     NAND Flash support
+ * @references: borrowed heavily from Linux mtd-utils code:
+ *             flash_eraseall.c by Arcom Control System Ltd
+ *             nandwrite.c by Steven J. Hill (sjhill@realitydiluted.com)
+ *                            and Thomas Gleixner (tglx@linutronix.de)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
+
+#include <command.h>
+#include <watchdog.h>
+#include <malloc.h>
+#include <div64.h>
+
+#include <nand.h>
+#include <jffs2/jffs2.h>
+
+typedef struct erase_info erase_info_t;
+typedef struct mtd_info          mtd_info_t;
+
+/* support only for native endian JFFS2 */
+#define cpu_to_je16(x) (x)
+#define cpu_to_je32(x) (x)
+
+/*****************************************************************************/
+static int nand_block_bad_scrub(struct mtd_info *mtd, loff_t ofs, int getchip)
+{
+       return 0;
+}
+
+/**
+ * nand_erase_opts: - erase NAND flash with support for various options
+ *                   (jffs2 formating)
+ *
+ * @param meminfo      NAND device to erase
+ * @param opts         options,  @see struct nand_erase_options
+ * @return             0 in case of success
+ *
+ * This code is ported from flash_eraseall.c from Linux mtd utils by
+ * Arcom Control System Ltd.
+ */
+int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)
+{
+       struct jffs2_unknown_node cleanmarker;
+       int clmpos = 0;
+       int clmlen = 8;
+       erase_info_t erase;
+       ulong erase_length;
+       int isNAND;
+       int bbtest = 1;
+       int result;
+       int percent_complete = -1;
+       int (*nand_block_bad_old)(struct mtd_info *, loff_t, int) = NULL;
+       const char *mtd_device = meminfo->name;
+
+       memset(&erase, 0, sizeof(erase));
+
+       erase.mtd = meminfo;
+       erase.len  = meminfo->erasesize;
+       erase.addr = opts->offset;
+       erase_length = opts->length;
+
+       isNAND = meminfo->type == MTD_NANDFLASH ? 1 : 0;
+
+       if (opts->jffs2) {
+               cleanmarker.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK);
+               cleanmarker.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER);
+               if (isNAND) {
+                       struct nand_oobinfo *oobinfo = &meminfo->oobinfo;
+
+                       /* check for autoplacement */
+                       if (oobinfo->useecc == MTD_NANDECC_AUTOPLACE) {
+                               /* get the position of the free bytes */
+                               if (!oobinfo->oobfree[0][1]) {
+                                       printf(" Eeep. Autoplacement selected "
+                                              "and no empty space in oob\n");
+                                       return -1;
+                               }
+                               clmpos = oobinfo->oobfree[0][0];
+                               clmlen = oobinfo->oobfree[0][1];
+                               if (clmlen > 8)
+                                       clmlen = 8;
+                       } else {
+                               /* legacy mode */
+                               switch (meminfo->oobsize) {
+                               case 8:
+                                       clmpos = 6;
+                                       clmlen = 2;
+                                       break;
+                               case 16:
+                                       clmpos = 8;
+                                       clmlen = 8;
+                                       break;
+                               case 64:
+                                       clmpos = 16;
+                                       clmlen = 8;
+                                       break;
+                               }
+                       }
+
+                       cleanmarker.totlen = cpu_to_je32(8);
+               } else {
+                       cleanmarker.totlen =
+                               cpu_to_je32(sizeof(struct jffs2_unknown_node));
+               }
+               cleanmarker.hdr_crc =  cpu_to_je32(
+                       crc32_no_comp(0, (unsigned char *) &cleanmarker,
+                                     sizeof(struct jffs2_unknown_node) - 4));
+       }
+
+       /* scrub option allows to erase badblock. To prevent internal
+        * check from erase() method, set block check method to dummy
+        * and disable bad block table while erasing.
+        */
+       if (opts->scrub) {
+               struct nand_chip *priv_nand = meminfo->priv;
+
+               nand_block_bad_old = priv_nand->block_bad;
+               priv_nand->block_bad = nand_block_bad_scrub;
+               /* we don't need the bad block table anymore...
+                * after scrub, there are no bad blocks left!
+                */
+               if (priv_nand->bbt) {
+                       kfree(priv_nand->bbt);
+               }
+               priv_nand->bbt = NULL;
+       }
+
+       for (;
+            erase.addr < opts->offset + erase_length;
+            erase.addr += meminfo->erasesize) {
+
+               WATCHDOG_RESET ();
+
+               if (!opts->scrub && bbtest) {
+                       int ret = meminfo->block_isbad(meminfo, erase.addr);
+                       if (ret > 0) {
+                               if (!opts->quiet)
+                                       printf("\rSkipping bad block at  "
+                                              "0x%08x                   "
+                                              "                         \n",
+                                              erase.addr);
+                               continue;
+
+                       } else if (ret < 0) {
+                               printf("\n%s: MTD get bad block failed: %d\n",
+                                      mtd_device,
+                                      ret);
+                               return -1;
+                       }
+               }
+
+               result = meminfo->erase(meminfo, &erase);
+               if (result != 0) {
+                       printf("\n%s: MTD Erase failure: %d\n",
+                              mtd_device, result);
+                       continue;
+               }
+
+               /* format for JFFS2 ? */
+               if (opts->jffs2) {
+
+                       /* write cleanmarker */
+                       if (isNAND) {
+                               size_t written;
+                               result = meminfo->write_oob(meminfo,
+                                                           erase.addr + clmpos,
+                                                           clmlen,
+                                                           &written,
+                                                           (unsigned char *)
+                                                           &cleanmarker);
+                               if (result != 0) {
+                                       printf("\n%s: MTD writeoob failure: %d\n",
+                                              mtd_device, result);
+                                       continue;
+                               }
+                       } else {
+                               printf("\n%s: this erase routine only supports"
+                                      " NAND devices!\n",
+                                      mtd_device);
+                       }
+               }
+
+               if (!opts->quiet) {
+                       unsigned long long n =(unsigned long long)
+                               (erase.addr + meminfo->erasesize - opts->offset)
+                               * 100;
+                       int percent;
+
+                       do_div(n, erase_length);
+                       percent = (int)n;
+
+                       /* output progress message only at whole percent
+                        * steps to reduce the number of messages printed
+                        * on (slow) serial consoles
+                        */
+                       if (percent != percent_complete) {
+                               percent_complete = percent;
+
+                               printf("\rErasing at 0x%x -- %3d%% complete.",
+                                      erase.addr, percent);
+
+                               if (opts->jffs2 && result == 0)
+                                       printf(" Cleanmarker written at 0x%x.",
+                                              erase.addr);
+                       }
+               }
+       }
+       if (!opts->quiet)
+               printf("\n");
+
+       if (nand_block_bad_old) {
+               struct nand_chip *priv_nand = meminfo->priv;
+
+               priv_nand->block_bad = nand_block_bad_old;
+               priv_nand->scan_bbt(meminfo);
+       }
+
+       return 0;
+}
+
+#define MAX_PAGE_SIZE  2048
+#define MAX_OOB_SIZE   64
+
+/*
+ * buffer array used for writing data
+ */
+static unsigned char data_buf[MAX_PAGE_SIZE];
+static unsigned char oob_buf[MAX_OOB_SIZE];
+
+/* OOB layouts to pass into the kernel as default */
+static struct nand_oobinfo none_oobinfo = {
+       .useecc = MTD_NANDECC_OFF,
+};
+
+static struct nand_oobinfo jffs2_oobinfo = {
+       .useecc = MTD_NANDECC_PLACE,
+       .eccbytes = 6,
+       .eccpos = { 0, 1, 2, 3, 6, 7 }
+};
+
+static struct nand_oobinfo yaffs_oobinfo = {
+       .useecc = MTD_NANDECC_PLACE,
+       .eccbytes = 6,
+       .eccpos = { 8, 9, 10, 13, 14, 15}
+};
+
+static struct nand_oobinfo autoplace_oobinfo = {
+       .useecc = MTD_NANDECC_AUTOPLACE
+};
+
+/**
+ * nand_write_opts: - write image to NAND flash with support for various options
+ *
+ * @param meminfo      NAND device to erase
+ * @param opts         write options (@see nand_write_options)
+ * @return             0 in case of success
+ *
+ * This code is ported from nandwrite.c from Linux mtd utils by
+ * Steven J. Hill and Thomas Gleixner.
+ */
+int nand_write_opts(nand_info_t *meminfo, const nand_write_options_t *opts)
+{
+       int imglen = 0;
+       int pagelen;
+       int baderaseblock;
+       int blockstart = -1;
+       loff_t offs;
+       int readlen;
+       int oobinfochanged = 0;
+       int percent_complete = -1;
+       struct nand_oobinfo old_oobinfo;
+       ulong mtdoffset = opts->offset;
+       ulong erasesize_blockalign;
+       u_char *buffer = opts->buffer;
+       size_t written;
+       int result;
+
+       if (opts->pad && opts->writeoob) {
+               printf("Can't pad when oob data is present.\n");
+               return -1;
+       }
+
+       /* set erasesize to specified number of blocks - to match
+        * jffs2 (virtual) block size */
+       if (opts->blockalign == 0) {
+               erasesize_blockalign = meminfo->erasesize;
+       } else {
+               erasesize_blockalign = meminfo->erasesize * opts->blockalign;
+       }
+
+       /* make sure device page sizes are valid */
+       if (!(meminfo->oobsize == 16 && meminfo->oobblock == 512)
+           && !(meminfo->oobsize == 8 && meminfo->oobblock == 256)
+           && !(meminfo->oobsize == 64 && meminfo->oobblock == 2048)) {
+               printf("Unknown flash (not normal NAND)\n");
+               return -1;
+       }
+
+       /* read the current oob info */
+       memcpy(&old_oobinfo, &meminfo->oobinfo, sizeof(old_oobinfo));
+
+       /* write without ecc? */
+       if (opts->noecc) {
+               memcpy(&meminfo->oobinfo, &none_oobinfo,
+                      sizeof(meminfo->oobinfo));
+               oobinfochanged = 1;
+       }
+
+       /* autoplace ECC? */
+       if (opts->autoplace && (old_oobinfo.useecc != MTD_NANDECC_AUTOPLACE)) {
+
+               memcpy(&meminfo->oobinfo, &autoplace_oobinfo,
+                      sizeof(meminfo->oobinfo));
+               oobinfochanged = 1;
+       }
+
+       /* force OOB layout for jffs2 or yaffs? */
+       if (opts->forcejffs2 || opts->forceyaffs) {
+               struct nand_oobinfo *oobsel =
+                       opts->forcejffs2 ? &jffs2_oobinfo : &yaffs_oobinfo;
+
+               if (meminfo->oobsize == 8) {
+                       if (opts->forceyaffs) {
+                               printf("YAFSS cannot operate on "
+                                      "256 Byte page size\n");
+                               goto restoreoob;
+                       }
+                       /* Adjust number of ecc bytes */
+                       jffs2_oobinfo.eccbytes = 3;
+               }
+
+               memcpy(&meminfo->oobinfo, oobsel, sizeof(meminfo->oobinfo));
+       }
+
+       /* get image length */
+       imglen = opts->length;
+       pagelen = meminfo->oobblock
+               + ((opts->writeoob != 0) ? meminfo->oobsize : 0);
+
+       /* check, if file is pagealigned */
+       if ((!opts->pad) && ((imglen % pagelen) != 0)) {
+               printf("Input block length is not page aligned\n");
+               goto restoreoob;
+       }
+
+       /* check, if length fits into device */
+       if (((imglen / pagelen) * meminfo->oobblock)
+            > (meminfo->size - opts->offset)) {
+               printf("Image %d bytes, NAND page %d bytes, "
+                      "OOB area %u bytes, device size %u bytes\n",
+                      imglen, pagelen, meminfo->oobblock, meminfo->size);
+               printf("Input block does not fit into device\n");
+               goto restoreoob;
+       }
+
+       if (!opts->quiet)
+               printf("\n");
+
+       /* get data from input and write to the device */
+       while (imglen && (mtdoffset < meminfo->size)) {
+
+               WATCHDOG_RESET ();
+
+               /*
+                * new eraseblock, check for bad block(s). Stay in the
+                * loop to be sure if the offset changes because of
+                * a bad block, that the next block that will be
+                * written to is also checked. Thus avoiding errors if
+                * the block(s) after the skipped block(s) is also bad
+                * (number of blocks depending on the blockalign
+                */
+               while (blockstart != (mtdoffset & (~erasesize_blockalign+1))) {
+                       blockstart = mtdoffset & (~erasesize_blockalign+1);
+                       offs = blockstart;
+                       baderaseblock = 0;
+
+                       /* check all the blocks in an erase block for
+                        * bad blocks */
+                       do {
+                               int ret = meminfo->block_isbad(meminfo, offs);
+
+                               if (ret < 0) {
+                                       printf("Bad block check failed\n");
+                                       goto restoreoob;
+                               }
+                               if (ret == 1) {
+                                       baderaseblock = 1;
+                                       if (!opts->quiet)
+                                               printf("\rBad block at 0x%lx "
+                                                      "in erase block from "
+                                                      "0x%x will be skipped\n",
+                                                      (long) offs,
+                                                      blockstart);
+                               }
+
+                               if (baderaseblock) {
+                                       mtdoffset = blockstart
+                                               + erasesize_blockalign;
+                               }
+                               offs +=  erasesize_blockalign
+                                       / opts->blockalign;
+                       } while (offs < blockstart + erasesize_blockalign);
+               }
+
+               readlen = meminfo->oobblock;
+               if (opts->pad && (imglen < readlen)) {
+                       readlen = imglen;
+                       memset(data_buf + readlen, 0xff,
+                              meminfo->oobblock - readlen);
+               }
+
+               /* read page data from input memory buffer */
+               memcpy(data_buf, buffer, readlen);
+               buffer += readlen;
+
+               if (opts->writeoob) {
+                       /* read OOB data from input memory block, exit
+                        * on failure */
+                       memcpy(oob_buf, buffer, meminfo->oobsize);
+                       buffer += meminfo->oobsize;
+
+                       /* write OOB data first, as ecc will be placed
+                        * in there*/
+                       result = meminfo->write_oob(meminfo,
+                                                   mtdoffset,
+                                                   meminfo->oobsize,
+                                                   &written,
+                                                   (unsigned char *)
+                                                   &oob_buf);
+
+                       if (result != 0) {
+                               printf("\nMTD writeoob failure: %d\n",
+                                      result);
+                               goto restoreoob;
+                       }
+                       imglen -= meminfo->oobsize;
+               }
+
+               /* write out the page data */
+               result = meminfo->write(meminfo,
+                                       mtdoffset,
+                                       meminfo->oobblock,
+                                       &written,
+                                       (unsigned char *) &data_buf);
+
+               if (result != 0) {
+                       printf("writing NAND page at offset 0x%lx failed\n",
+                              mtdoffset);
+                       goto restoreoob;
+               }
+               imglen -= readlen;
+
+               if (!opts->quiet) {
+                       unsigned long long n = (unsigned long long)
+                                (opts->length-imglen) * 100;
+                       int percent;
+
+                       do_div(n, opts->length);
+                       percent = (int)n;
+
+                       /* output progress message only at whole percent
+                        * steps to reduce the number of messages printed
+                        * on (slow) serial consoles
+                        */
+                       if (percent != percent_complete) {
+                               printf("\rWriting data at 0x%x "
+                                      "-- %3d%% complete.",
+                                      mtdoffset, percent);
+                               percent_complete = percent;
+                       }
+               }
+
+               mtdoffset += meminfo->oobblock;
+       }
+
+       if (!opts->quiet)
+               printf("\n");
+
+restoreoob:
+       if (oobinfochanged) {
+               memcpy(&meminfo->oobinfo, &old_oobinfo,
+                      sizeof(meminfo->oobinfo));
+       }
+
+       if (imglen > 0) {
+               printf("Data did not fit into device, due to bad blocks\n");
+               return -1;
+       }
+
+       /* return happy */
+       return 0;
+}
+
+/**
+ * nand_read_opts: - read image from NAND flash with support for various options
+ *
+ * @param meminfo      NAND device to erase
+ * @param opts         read options (@see struct nand_read_options)
+ * @return             0 in case of success
+ *
+ */
+int nand_read_opts(nand_info_t *meminfo, const nand_read_options_t *opts)
+{
+       int imglen = opts->length;
+       int pagelen;
+       int baderaseblock;
+       int blockstart = -1;
+       int percent_complete = -1;
+       loff_t offs;
+       size_t readlen;
+       ulong mtdoffset = opts->offset;
+       u_char *buffer = opts->buffer;
+       int result;
+
+       /* make sure device page sizes are valid */
+       if (!(meminfo->oobsize == 16 && meminfo->oobblock == 512)
+           && !(meminfo->oobsize == 8 && meminfo->oobblock == 256)
+           && !(meminfo->oobsize == 64 && meminfo->oobblock == 2048)) {
+               printf("Unknown flash (not normal NAND)\n");
+               return -1;
+       }
+
+       pagelen = meminfo->oobblock
+               + ((opts->readoob != 0) ? meminfo->oobsize : 0);
+
+       /* check, if length is not larger than device */
+       if (((imglen / pagelen) * meminfo->oobblock)
+            > (meminfo->size - opts->offset)) {
+               printf("Image %d bytes, NAND page %d bytes, "
+                      "OOB area %u bytes, device size %u bytes\n",
+                      imglen, pagelen, meminfo->oobblock, meminfo->size);
+               printf("Input block is larger than device\n");
+               return -1;
+       }
+
+       if (!opts->quiet)
+               printf("\n");
+
+       /* get data from input and write to the device */
+       while (imglen && (mtdoffset < meminfo->size)) {
+
+               WATCHDOG_RESET ();
+
+               /*
+                * new eraseblock, check for bad block(s). Stay in the
+                * loop to be sure if the offset changes because of
+                * a bad block, that the next block that will be
+                * written to is also checked. Thus avoiding errors if
+                * the block(s) after the skipped block(s) is also bad
+                * (number of blocks depending on the blockalign
+                */
+               while (blockstart != (mtdoffset & (~meminfo->erasesize+1))) {
+                       blockstart = mtdoffset & (~meminfo->erasesize+1);
+                       offs = blockstart;
+                       baderaseblock = 0;
+
+                       /* check all the blocks in an erase block for
+                        * bad blocks */
+                       do {
+                               int ret = meminfo->block_isbad(meminfo, offs);
+
+                               if (ret < 0) {
+                                       printf("Bad block check failed\n");
+                                       return -1;
+                               }
+                               if (ret == 1) {
+                                       baderaseblock = 1;
+                                       if (!opts->quiet)
+                                               printf("\rBad block at 0x%lx "
+                                                      "in erase block from "
+                                                      "0x%x will be skipped\n",
+                                                      (long) offs,
+                                                      blockstart);
+                               }
+
+                               if (baderaseblock) {
+                                       mtdoffset = blockstart
+                                               + meminfo->erasesize;
+                               }
+                               offs +=  meminfo->erasesize;
+
+                       } while (offs < blockstart + meminfo->erasesize);
+               }
+
+
+               /* read page data to memory buffer */
+               result = meminfo->read(meminfo,
+                                      mtdoffset,
+                                      meminfo->oobblock,
+                                      &readlen,
+                                      (unsigned char *) &data_buf);
+
+               if (result != 0) {
+                       printf("reading NAND page at offset 0x%lx failed\n",
+                              mtdoffset);
+                       return -1;
+               }
+
+               if (imglen < readlen) {
+                       readlen = imglen;
+               }
+
+               memcpy(buffer, data_buf, readlen);
+               buffer += readlen;
+               imglen -= readlen;
+
+               if (opts->readoob) {
+                       result = meminfo->read_oob(meminfo,
+                                                  mtdoffset,
+                                                  meminfo->oobsize,
+                                                  &readlen,
+                                                  (unsigned char *)
+                                                  &oob_buf);
+
+                       if (result != 0) {
+                               printf("\nMTD readoob failure: %d\n",
+                                      result);
+                               return -1;
+                       }
+
+
+                       if (imglen < readlen) {
+                               readlen = imglen;
+                       }
+
+                       memcpy(buffer, oob_buf, readlen);
+
+                       buffer += readlen;
+                       imglen -= readlen;
+               }
+
+               if (!opts->quiet) {
+                       unsigned long long n = (unsigned long long)
+                                (opts->length-imglen) * 100;
+                       int percent;
+
+                       do_div(n, opts->length);
+                       percent = (int)n;
+
+                       /* output progress message only at whole percent
+                        * steps to reduce the number of messages printed
+                        * on (slow) serial consoles
+                        */
+                       if (percent != percent_complete) {
+                       if (!opts->quiet)
+                               printf("\rReading data from 0x%x "
+                                      "-- %3d%% complete.",
+                                      mtdoffset, percent);
+                               percent_complete = percent;
+                       }
+               }
+
+               mtdoffset += meminfo->oobblock;
+       }
+
+       if (!opts->quiet)
+               printf("\n");
+
+       if (imglen > 0) {
+               printf("Could not read entire image due to bad blocks\n");
+               return -1;
+       }
+
+       /* return happy */
+       return 0;
+}
+
+/******************************************************************************
+ * Support for locking / unlocking operations of some NAND devices
+ *****************************************************************************/
+
+#define NAND_CMD_LOCK          0x2a
+#define NAND_CMD_LOCK_TIGHT    0x2c
+#define NAND_CMD_UNLOCK1       0x23
+#define NAND_CMD_UNLOCK2       0x24
+#define NAND_CMD_LOCK_STATUS   0x7a
+
+/**
+ * nand_lock: Set all pages of NAND flash chip to the LOCK or LOCK-TIGHT
+ *           state
+ *
+ * @param meminfo      nand mtd instance
+ * @param tight                bring device in lock tight mode
+ *
+ * @return             0 on success, -1 in case of error
+ *
+ * The lock / lock-tight command only applies to the whole chip. To get some
+ * parts of the chip lock and others unlocked use the following sequence:
+ *
+ * - Lock all pages of the chip using nand_lock(mtd, 0) (or the lockpre pin)
+ * - Call nand_unlock() once for each consecutive area to be unlocked
+ * - If desired: Bring the chip to the lock-tight state using nand_lock(mtd, 1)
+ *
+ *   If the device is in lock-tight state software can't change the
+ *   current active lock/unlock state of all pages. nand_lock() / nand_unlock()
+ *   calls will fail. It is only posible to leave lock-tight state by
+ *   an hardware signal (low pulse on _WP pin) or by power down.
+ */
+int nand_lock(nand_info_t *meminfo, int tight)
+{
+       int ret = 0;
+       int status;
+       struct nand_chip *this = meminfo->priv;
+
+       /* select the NAND device */
+       this->select_chip(meminfo, 0);
+
+       this->cmdfunc(meminfo,
+                     (tight ? NAND_CMD_LOCK_TIGHT : NAND_CMD_LOCK),
+                     -1, -1);
+
+       /* call wait ready function */
+       status = this->waitfunc(meminfo, this, FL_WRITING);
+
+       /* see if device thinks it succeeded */
+       if (status & 0x01) {
+               ret = -1;
+       }
+
+       /* de-select the NAND device */
+       this->select_chip(meminfo, -1);
+       return ret;
+}
+
+/**
+ * nand_get_lock_status: - query current lock state from one page of NAND
+ *                        flash
+ *
+ * @param meminfo      nand mtd instance
+ * @param offset       page address to query (muss be page aligned!)
+ *
+ * @return             -1 in case of error
+ *                     >0 lock status:
+ *                       bitfield with the following combinations:
+ *                       NAND_LOCK_STATUS_TIGHT: page in tight state
+ *                       NAND_LOCK_STATUS_LOCK:  page locked
+ *                       NAND_LOCK_STATUS_UNLOCK: page unlocked
+ *
+ */
+int nand_get_lock_status(nand_info_t *meminfo, ulong offset)
+{
+       int ret = 0;
+       int chipnr;
+       int page;
+       struct nand_chip *this = meminfo->priv;
+
+       /* select the NAND device */
+       chipnr = (int)(offset >> this->chip_shift);
+       this->select_chip(meminfo, chipnr);
+
+
+       if ((offset & (meminfo->oobblock - 1)) != 0) {
+               printf ("nand_get_lock_status: "
+                       "Start address must be beginning of "
+                       "nand page!\n");
+               ret = -1;
+               goto out;
+       }
+
+       /* check the Lock Status */
+       page = (int)(offset >> this->page_shift);
+       this->cmdfunc(meminfo, NAND_CMD_LOCK_STATUS, -1, page & this->pagemask);
+
+       ret = this->read_byte(meminfo) & (NAND_LOCK_STATUS_TIGHT
+                                         | NAND_LOCK_STATUS_LOCK
+                                         | NAND_LOCK_STATUS_UNLOCK);
+
+ out:
+       /* de-select the NAND device */
+       this->select_chip(meminfo, -1);
+       return ret;
+}
+
+/**
+ * nand_unlock: - Unlock area of NAND pages
+ *               only one consecutive area can be unlocked at one time!
+ *
+ * @param meminfo      nand mtd instance
+ * @param start                start byte address
+ * @param length       number of bytes to unlock (must be a multiple of
+ *                     page size nand->oobblock)
+ *
+ * @return             0 on success, -1 in case of error
+ */
+int nand_unlock(nand_info_t *meminfo, ulong start, ulong length)
+{
+       int ret = 0;
+       int chipnr;
+       int status;
+       int page;
+       struct nand_chip *this = meminfo->priv;
+       printf ("nand_unlock: start: %08x, length: %d!\n",
+               (int)start, (int)length);
+
+       /* select the NAND device */
+       chipnr = (int)(start >> this->chip_shift);
+       this->select_chip(meminfo, chipnr);
+
+       /* check the WP bit */
+       this->cmdfunc(meminfo, NAND_CMD_STATUS, -1, -1);
+       if ((this->read_byte(meminfo) & 0x80) == 0) {
+               printf ("nand_unlock: Device is write protected!\n");
+               ret = -1;
+               goto out;
+       }
+
+       if ((start & (meminfo->oobblock - 1)) != 0) {
+               printf ("nand_unlock: Start address must be beginning of "
+                       "nand page!\n");
+               ret = -1;
+               goto out;
+       }
+
+       if (length == 0 || (length & (meminfo->oobblock - 1)) != 0) {
+               printf ("nand_unlock: Length must be a multiple of nand page "
+                       "size!\n");
+               ret = -1;
+               goto out;
+       }
+
+       /* submit address of first page to unlock */
+       page = (int)(start >> this->page_shift);
+       this->cmdfunc(meminfo, NAND_CMD_UNLOCK1, -1, page & this->pagemask);
+
+       /* submit ADDRESS of LAST page to unlock */
+       page += (int)(length >> this->page_shift) - 1;
+       this->cmdfunc(meminfo, NAND_CMD_UNLOCK2, -1, page & this->pagemask);
+
+       /* call wait ready function */
+       status = this->waitfunc(meminfo, this, FL_WRITING);
+       /* see if device thinks it succeeded */
+       if (status & 0x01) {
+               /* there was an error */
+               ret = -1;
+               goto out;
+       }
+
+ out:
+       /* de-select the NAND device */
+       this->select_chip(meminfo, -1);
+       return ret;
+}
+
+#endif
diff --git a/drivers/mtd/nand_legacy/Makefile b/drivers/mtd/nand_legacy/Makefile
new file mode 100644 (file)
index 0000000..95314d8
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libnand_legacy.a
+
+COBJS  := nand_legacy.o
+
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/mtd/nand_legacy/nand_legacy.c b/drivers/mtd/nand_legacy/nand_legacy.c
new file mode 100644 (file)
index 0000000..49d2ebb
--- /dev/null
@@ -0,0 +1,1612 @@
+/*
+ * (C) 2006 Denx
+ * Driver for NAND support, Rick Bronson
+ * borrowed heavily from:
+ * (c) 1999 Machine Vision Holdings, Inc.
+ * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
+ *
+ * Added 16-bit nand support
+ * (C) 2004 Texas Instruments
+ */
+
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <watchdog.h>
+
+#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
+
+#include <linux/mtd/nand_legacy.h>
+#include <linux/mtd/nand_ids.h>
+#include <jffs2/jffs2.h>
+
+#ifdef CONFIG_OMAP1510
+void archflashwp(void *archdata, int wp);
+#endif
+
+#define ROUND_DOWN(value,boundary)      ((value) & (~((boundary)-1)))
+
+#undef PSYCHO_DEBUG
+#undef NAND_DEBUG
+
+/* ****************** WARNING *********************
+ * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will
+ * erase (or at least attempt to erase) blocks that are marked
+ * bad. This can be very handy if you are _sure_ that the block
+ * is OK, say because you marked a good block bad to test bad
+ * block handling and you are done testing, or if you have
+ * accidentally marked blocks bad.
+ *
+ * Erasing factory marked bad blocks is a _bad_ idea. If the
+ * erase succeeds there is no reliable way to find them again,
+ * and attempting to program or erase bad blocks can affect
+ * the data in _other_ (good) blocks.
+ */
+#define         ALLOW_ERASE_BAD_DEBUG 0
+
+#define CONFIG_MTD_NAND_ECC  /* enable ECC */
+#define CONFIG_MTD_NAND_ECC_JFFS2
+
+/* bits for nand_legacy_rw() `cmd'; or together as needed */
+#define NANDRW_READ    0x01
+#define NANDRW_WRITE   0x00
+#define NANDRW_JFFS2   0x02
+#define NANDRW_JFFS2_SKIP      0x04
+
+
+/*
+ * Exported variables etc.
+ */
+
+/* Definition of the out of band configuration structure */
+struct nand_oob_config {
+       /* position of ECC bytes inside oob */
+       int ecc_pos[6];
+       /* position of  bad blk flag inside oob -1 = inactive */
+       int badblock_pos;
+       /* position of ECC valid flag inside oob -1 = inactive */
+       int eccvalid_pos;
+} oob_config = { {0}, 0, 0};
+
+struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE] = {{0}};
+
+int curr_device = -1; /* Current NAND Device */
+
+
+/*
+ * Exported functionss
+ */
+int nand_legacy_erase(struct nand_chip* nand, size_t ofs,
+                    size_t len, int clean);
+int nand_legacy_rw(struct nand_chip* nand, int cmd,
+                 size_t start, size_t len,
+                 size_t * retlen, u_char * buf);
+void nand_print(struct nand_chip *nand);
+void nand_print_bad(struct nand_chip *nand);
+int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
+                size_t * retlen, u_char * buf);
+int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
+                size_t * retlen, const u_char * buf);
+
+/*
+ * Internals
+ */
+static int NanD_WaitReady(struct nand_chip *nand, int ale_wait);
+static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
+                size_t * retlen, u_char *buf, u_char *ecc_code);
+static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
+                          size_t * retlen, const u_char * buf,
+                          u_char * ecc_code);
+#ifdef CONFIG_MTD_NAND_ECC
+static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc);
+static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code);
+#endif
+
+
+/*
+ *
+ * Function definitions
+ *
+ */
+
+/* returns 0 if block containing pos is OK:
+ *             valid erase block and
+ *             not marked bad, or no bad mark position is specified
+ * returns 1 if marked bad or otherwise invalid
+ */
+static int check_block (struct nand_chip *nand, unsigned long pos)
+{
+       size_t retlen;
+       uint8_t oob_data;
+       uint16_t oob_data16[6];
+       int page0 = pos & (-nand->erasesize);
+       int page1 = page0 + nand->oobblock;
+       int badpos = oob_config.badblock_pos;
+
+       if (pos >= nand->totlen)
+               return 1;
+
+       if (badpos < 0)
+               return 0;       /* no way to check, assume OK */
+
+       if (nand->bus16) {
+               if (nand_read_oob(nand, (page0 + 0), 12, &retlen, (uint8_t *)oob_data16)
+                   || (oob_data16[2] & 0xff00) != 0xff00)
+                       return 1;
+               if (nand_read_oob(nand, (page1 + 0), 12, &retlen, (uint8_t *)oob_data16)
+                   || (oob_data16[2] & 0xff00) != 0xff00)
+                       return 1;
+       } else {
+               /* Note - bad block marker can be on first or second page */
+               if (nand_read_oob(nand, page0 + badpos, 1, &retlen, (unsigned char *)&oob_data)
+                   || oob_data != 0xff
+                   || nand_read_oob (nand, page1 + badpos, 1, &retlen, (unsigned char *)&oob_data)
+                   || oob_data != 0xff)
+                       return 1;
+       }
+
+       return 0;
+}
+
+/* print bad blocks in NAND flash */
+void nand_print_bad(struct nand_chip* nand)
+{
+       unsigned long pos;
+
+       for (pos = 0; pos < nand->totlen; pos += nand->erasesize) {
+               if (check_block(nand, pos))
+                       printf(" 0x%8.8lx\n", pos);
+       }
+       puts("\n");
+}
+
+/* cmd: 0: NANDRW_WRITE                        write, fail on bad block
+ *     1: NANDRW_READ                  read, fail on bad block
+ *     2: NANDRW_WRITE | NANDRW_JFFS2  write, skip bad blocks
+ *     3: NANDRW_READ | NANDRW_JFFS2   read, data all 0xff for bad blocks
+ *      7: NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP read, skip bad blocks
+ */
+int nand_legacy_rw (struct nand_chip* nand, int cmd,
+                  size_t start, size_t len,
+                  size_t * retlen, u_char * buf)
+{
+       int ret = 0, n, total = 0;
+       char eccbuf[6];
+       /* eblk (once set) is the start of the erase block containing the
+        * data being processed.
+        */
+       unsigned long eblk = ~0;        /* force mismatch on first pass */
+       unsigned long erasesize = nand->erasesize;
+
+       while (len) {
+               if ((start & (-erasesize)) != eblk) {
+                       /* have crossed into new erase block, deal with
+                        * it if it is sure marked bad.
+                        */
+                       eblk = start & (-erasesize); /* start of block */
+                       if (check_block(nand, eblk)) {
+                               if (cmd == (NANDRW_READ | NANDRW_JFFS2)) {
+                                       while (len > 0 &&
+                                              start - eblk < erasesize) {
+                                               *(buf++) = 0xff;
+                                               ++start;
+                                               ++total;
+                                               --len;
+                                       }
+                                       continue;
+                               } else if (cmd == (NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP)) {
+                                       start += erasesize;
+                                       continue;
+                               } else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) {
+                                       /* skip bad block */
+                                       start += erasesize;
+                                       continue;
+                               } else {
+                                       ret = 1;
+                                       break;
+                               }
+                       }
+               }
+               /* The ECC will not be calculated correctly if
+                  less than 512 is written or read */
+               /* Is request at least 512 bytes AND it starts on a proper boundry */
+               if((start != ROUND_DOWN(start, 0x200)) || (len < 0x200))
+                       printf("Warning block writes should be at least 512 bytes and start on a 512 byte boundry\n");
+
+               if (cmd & NANDRW_READ) {
+                       ret = nand_read_ecc(nand, start,
+                                          min(len, eblk + erasesize - start),
+                                          (size_t *)&n, (u_char*)buf, (u_char *)eccbuf);
+               } else {
+                       ret = nand_write_ecc(nand, start,
+                                           min(len, eblk + erasesize - start),
+                                           (size_t *)&n, (u_char*)buf, (u_char *)eccbuf);
+               }
+
+               if (ret)
+                       break;
+
+               start  += n;
+               buf   += n;
+               total += n;
+               len   -= n;
+       }
+       if (retlen)
+               *retlen = total;
+
+       return ret;
+}
+
+void nand_print(struct nand_chip *nand)
+{
+       if (nand->numchips > 1) {
+               printf("%s at 0x%lx,\n"
+                      "\t  %d chips %s, size %d MB, \n"
+                      "\t  total size %ld MB, sector size %ld kB\n",
+                      nand->name, nand->IO_ADDR, nand->numchips,
+                      nand->chips_name, 1 << (nand->chipshift - 20),
+                      nand->totlen >> 20, nand->erasesize >> 10);
+       }
+       else {
+               printf("%s at 0x%lx (", nand->chips_name, nand->IO_ADDR);
+               print_size(nand->totlen, ", ");
+               print_size(nand->erasesize, " sector)\n");
+       }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int NanD_WaitReady(struct nand_chip *nand, int ale_wait)
+{
+       /* This is inline, to optimise the common case, where it's ready instantly */
+       int ret = 0;
+
+#ifdef NAND_NO_RB      /* in config file, shorter delays currently wrap accesses */
+       if(ale_wait)
+               NAND_WAIT_READY(nand);  /* do the worst case 25us wait */
+       else
+               udelay(10);
+#else  /* has functional r/b signal */
+       NAND_WAIT_READY(nand);
+#endif
+       return ret;
+}
+
+/* NanD_Command: Send a flash command to the flash chip */
+
+static inline int NanD_Command(struct nand_chip *nand, unsigned char command)
+{
+       unsigned long nandptr = nand->IO_ADDR;
+
+       /* Assert the CLE (Command Latch Enable) line to the flash chip */
+       NAND_CTL_SETCLE(nandptr);
+
+       /* Send the command */
+       WRITE_NAND_COMMAND(command, nandptr);
+
+       /* Lower the CLE line */
+       NAND_CTL_CLRCLE(nandptr);
+
+#ifdef NAND_NO_RB
+       if(command == NAND_CMD_RESET){
+               u_char ret_val;
+               NanD_Command(nand, NAND_CMD_STATUS);
+               do {
+                       ret_val = READ_NAND(nandptr);/* wait till ready */
+               } while((ret_val & 0x40) != 0x40);
+       }
+#endif
+       return NanD_WaitReady(nand, 0);
+}
+
+/* NanD_Address: Set the current address for the flash chip */
+
+static int NanD_Address(struct nand_chip *nand, int numbytes, unsigned long ofs)
+{
+       unsigned long nandptr;
+       int i;
+
+       nandptr = nand->IO_ADDR;
+
+       /* Assert the ALE (Address Latch Enable) line to the flash chip */
+       NAND_CTL_SETALE(nandptr);
+
+       /* Send the address */
+       /* Devices with 256-byte page are addressed as:
+        * Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
+        * there is no device on the market with page256
+        * and more than 24 bits.
+        * Devices with 512-byte page are addressed as:
+        * Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
+        * 25-31 is sent only if the chip support it.
+        * bit 8 changes the read command to be sent
+        * (NAND_CMD_READ0 or NAND_CMD_READ1).
+        */
+
+       if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE)
+               WRITE_NAND_ADDRESS(ofs, nandptr);
+
+       ofs = ofs >> nand->page_shift;
+
+       if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) {
+               for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8) {
+                       WRITE_NAND_ADDRESS(ofs, nandptr);
+               }
+       }
+
+       /* Lower the ALE line */
+       NAND_CTL_CLRALE(nandptr);
+
+       /* Wait for the chip to respond */
+       return NanD_WaitReady(nand, 1);
+}
+
+/* NanD_SelectChip: Select a given flash chip within the current floor */
+
+static inline int NanD_SelectChip(struct nand_chip *nand, int chip)
+{
+       /* Wait for it to be ready */
+       return NanD_WaitReady(nand, 0);
+}
+
+/* NanD_IdentChip: Identify a given NAND chip given {floor,chip} */
+
+static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)
+{
+       int mfr, id, i;
+
+       NAND_ENABLE_CE(nand);  /* set pin low */
+       /* Reset the chip */
+       if (NanD_Command(nand, NAND_CMD_RESET)) {
+#ifdef NAND_DEBUG
+               printf("NanD_Command (reset) for %d,%d returned true\n",
+                      floor, chip);
+#endif
+               NAND_DISABLE_CE(nand);  /* set pin high */
+               return 0;
+       }
+
+       /* Read the NAND chip ID: 1. Send ReadID command */
+       if (NanD_Command(nand, NAND_CMD_READID)) {
+#ifdef NAND_DEBUG
+               printf("NanD_Command (ReadID) for %d,%d returned true\n",
+                      floor, chip);
+#endif
+               NAND_DISABLE_CE(nand);  /* set pin high */
+               return 0;
+       }
+
+       /* Read the NAND chip ID: 2. Send address byte zero */
+       NanD_Address(nand, ADDR_COLUMN, 0);
+
+       /* Read the manufacturer and device id codes from the device */
+
+       mfr = READ_NAND(nand->IO_ADDR);
+
+       id = READ_NAND(nand->IO_ADDR);
+
+       NAND_DISABLE_CE(nand);  /* set pin high */
+
+#ifdef NAND_DEBUG
+       printf("NanD_Command (ReadID) got %x %x\n", mfr, id);
+#endif
+       if (mfr == 0xff || mfr == 0) {
+               /* No response - return failure */
+               return 0;
+       }
+
+       /* Check it's the same as the first chip we identified.
+        * M-Systems say that any given nand_chip device should only
+        * contain _one_ type of flash part, although that's not a
+        * hardware restriction. */
+       if (nand->mfr) {
+               if (nand->mfr == mfr && nand->id == id) {
+                       return 1;       /* This is another the same the first */
+               } else {
+                       printf("Flash chip at floor %d, chip %d is different:\n",
+                              floor, chip);
+               }
+       }
+
+       /* Print and store the manufacturer and ID codes. */
+       for (i = 0; nand_flash_ids[i].name != NULL; i++) {
+               if (mfr == nand_flash_ids[i].manufacture_id &&
+                   id == nand_flash_ids[i].model_id) {
+#ifdef NAND_DEBUG
+                       printf("Flash chip found:\n\t Manufacturer ID: 0x%2.2X, "
+                              "Chip ID: 0x%2.2X (%s)\n", mfr, id,
+                              nand_flash_ids[i].name);
+#endif
+                       if (!nand->mfr) {
+                               nand->mfr = mfr;
+                               nand->id = id;
+                               nand->chipshift =
+                                   nand_flash_ids[i].chipshift;
+                               nand->page256 = nand_flash_ids[i].page256;
+                               nand->eccsize = 256;
+                               if (nand->page256) {
+                                       nand->oobblock = 256;
+                                       nand->oobsize = 8;
+                                       nand->page_shift = 8;
+                               } else {
+                                       nand->oobblock = 512;
+                                       nand->oobsize = 16;
+                                       nand->page_shift = 9;
+                               }
+                               nand->pageadrlen = nand_flash_ids[i].pageadrlen;
+                               nand->erasesize  = nand_flash_ids[i].erasesize;
+                               nand->chips_name = nand_flash_ids[i].name;
+                               nand->bus16      = nand_flash_ids[i].bus16;
+                               return 1;
+                       }
+                       return 0;
+               }
+       }
+
+
+#ifdef NAND_DEBUG
+       /* We haven't fully identified the chip. Print as much as we know. */
+       printf("Unknown flash chip found: %2.2X %2.2X\n",
+              id, mfr);
+#endif
+
+       return 0;
+}
+
+/* NanD_ScanChips: Find all NAND chips present in a nand_chip, and identify them */
+
+static void NanD_ScanChips(struct nand_chip *nand)
+{
+       int floor, chip;
+       int numchips[NAND_MAX_FLOORS];
+       int maxchips = NAND_MAX_CHIPS;
+       int ret = 1;
+
+       nand->numchips = 0;
+       nand->mfr = 0;
+       nand->id = 0;
+
+
+       /* For each floor, find the number of valid chips it contains */
+       for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
+               ret = 1;
+               numchips[floor] = 0;
+               for (chip = 0; chip < maxchips && ret != 0; chip++) {
+
+                       ret = NanD_IdentChip(nand, floor, chip);
+                       if (ret) {
+                               numchips[floor]++;
+                               nand->numchips++;
+                       }
+               }
+       }
+
+       /* If there are none at all that we recognise, bail */
+       if (!nand->numchips) {
+#ifdef NAND_DEBUG
+               puts ("No NAND flash chips recognised.\n");
+#endif
+               return;
+       }
+
+       /* Allocate an array to hold the information for each chip */
+       nand->chips = malloc(sizeof(struct Nand) * nand->numchips);
+       if (!nand->chips) {
+               puts ("No memory for allocating chip info structures\n");
+               return;
+       }
+
+       ret = 0;
+
+       /* Fill out the chip array with {floor, chipno} for each
+        * detected chip in the device. */
+       for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
+               for (chip = 0; chip < numchips[floor]; chip++) {
+                       nand->chips[ret].floor = floor;
+                       nand->chips[ret].chip = chip;
+                       nand->chips[ret].curadr = 0;
+                       nand->chips[ret].curmode = 0x50;
+                       ret++;
+               }
+       }
+
+       /* Calculate and print the total size of the device */
+       nand->totlen = nand->numchips * (1 << nand->chipshift);
+
+#ifdef NAND_DEBUG
+       printf("%d flash chips found. Total nand_chip size: %ld MB\n",
+              nand->numchips, nand->totlen >> 20);
+#endif
+}
+
+/* we need to be fast here, 1 us per read translates to 1 second per meg */
+static void NanD_ReadBuf (struct nand_chip *nand, u_char * data_buf, int cntr)
+{
+       unsigned long nandptr = nand->IO_ADDR;
+
+       NanD_Command (nand, NAND_CMD_READ0);
+
+       if (nand->bus16) {
+               u16 val;
+
+               while (cntr >= 16) {
+                       val = READ_NAND (nandptr);
+                       *data_buf++ = val & 0xff;
+                       *data_buf++ = val >> 8;
+                       val = READ_NAND (nandptr);
+                       *data_buf++ = val & 0xff;
+                       *data_buf++ = val >> 8;
+                       val = READ_NAND (nandptr);
+                       *data_buf++ = val & 0xff;
+                       *data_buf++ = val >> 8;
+                       val = READ_NAND (nandptr);
+                       *data_buf++ = val & 0xff;
+                       *data_buf++ = val >> 8;
+                       val = READ_NAND (nandptr);
+                       *data_buf++ = val & 0xff;
+                       *data_buf++ = val >> 8;
+                       val = READ_NAND (nandptr);
+                       *data_buf++ = val & 0xff;
+                       *data_buf++ = val >> 8;
+                       val = READ_NAND (nandptr);
+                       *data_buf++ = val & 0xff;
+                       *data_buf++ = val >> 8;
+                       val = READ_NAND (nandptr);
+                       *data_buf++ = val & 0xff;
+                       *data_buf++ = val >> 8;
+                       cntr -= 16;
+               }
+
+               while (cntr > 0) {
+                       val = READ_NAND (nandptr);
+                       *data_buf++ = val & 0xff;
+                       *data_buf++ = val >> 8;
+                       cntr -= 2;
+               }
+       } else {
+               while (cntr >= 16) {
+                       *data_buf++ = READ_NAND (nandptr);
+                       *data_buf++ = READ_NAND (nandptr);
+                       *data_buf++ = READ_NAND (nandptr);
+                       *data_buf++ = READ_NAND (nandptr);
+                       *data_buf++ = READ_NAND (nandptr);
+                       *data_buf++ = READ_NAND (nandptr);
+                       *data_buf++ = READ_NAND (nandptr);
+                       *data_buf++ = READ_NAND (nandptr);
+                       *data_buf++ = READ_NAND (nandptr);
+                       *data_buf++ = READ_NAND (nandptr);
+                       *data_buf++ = READ_NAND (nandptr);
+                       *data_buf++ = READ_NAND (nandptr);
+                       *data_buf++ = READ_NAND (nandptr);
+                       *data_buf++ = READ_NAND (nandptr);
+                       *data_buf++ = READ_NAND (nandptr);
+                       *data_buf++ = READ_NAND (nandptr);
+                       cntr -= 16;
+               }
+
+               while (cntr > 0) {
+                       *data_buf++ = READ_NAND (nandptr);
+                       cntr--;
+               }
+       }
+}
+
+/*
+ * NAND read with ECC
+ */
+static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
+                size_t * retlen, u_char *buf, u_char *ecc_code)
+{
+       int col, page;
+       int ecc_status = 0;
+#ifdef CONFIG_MTD_NAND_ECC
+       int j;
+       int ecc_failed = 0;
+       u_char *data_poi;
+       u_char ecc_calc[6];
+#endif
+
+       /* Do not allow reads past end of device */
+       if ((start + len) > nand->totlen) {
+               printf ("%s: Attempt read beyond end of device %x %x %x\n",
+                       __FUNCTION__, (uint) start, (uint) len, (uint) nand->totlen);
+               *retlen = 0;
+               return -1;
+       }
+
+       /* First we calculate the starting page */
+       /*page = shr(start, nand->page_shift);*/
+       page = start >> nand->page_shift;
+
+       /* Get raw starting column */
+       col = start & (nand->oobblock - 1);
+
+       /* Initialize return value */
+       *retlen = 0;
+
+       /* Select the NAND device */
+       NAND_ENABLE_CE(nand);  /* set pin low */
+
+       /* Loop until all data read */
+       while (*retlen < len) {
+
+#ifdef CONFIG_MTD_NAND_ECC
+               /* Do we have this page in cache ? */
+               if (nand->cache_page == page)
+                       goto readdata;
+               /* Send the read command */
+               NanD_Command(nand, NAND_CMD_READ0);
+               if (nand->bus16) {
+                       NanD_Address(nand, ADDR_COLUMN_PAGE,
+                                    (page << nand->page_shift) + (col >> 1));
+               } else {
+                       NanD_Address(nand, ADDR_COLUMN_PAGE,
+                                    (page << nand->page_shift) + col);
+               }
+
+               /* Read in a page + oob data */
+               NanD_ReadBuf(nand, nand->data_buf, nand->oobblock + nand->oobsize);
+
+               /* copy data into cache, for read out of cache and if ecc fails */
+               if (nand->data_cache) {
+                       memcpy (nand->data_cache, nand->data_buf,
+                               nand->oobblock + nand->oobsize);
+               }
+
+               /* Pick the ECC bytes out of the oob data */
+               for (j = 0; j < 6; j++) {
+                       ecc_code[j] = nand->data_buf[(nand->oobblock + oob_config.ecc_pos[j])];
+               }
+
+               /* Calculate the ECC and verify it */
+               /* If block was not written with ECC, skip ECC */
+               if (oob_config.eccvalid_pos != -1 &&
+                   (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0x0f) != 0x0f) {
+
+                       nand_calculate_ecc (&nand->data_buf[0], &ecc_calc[0]);
+                       switch (nand_correct_data (&nand->data_buf[0], &ecc_code[0], &ecc_calc[0])) {
+                       case -1:
+                               printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
+                               ecc_failed++;
+                               break;
+                       case 1:
+                       case 2: /* transfer ECC corrected data to cache */
+                               if (nand->data_cache)
+                                       memcpy (nand->data_cache, nand->data_buf, 256);
+                               break;
+                       }
+               }
+
+               if (oob_config.eccvalid_pos != -1 &&
+                   nand->oobblock == 512 && (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0xf0) != 0xf0) {
+
+                       nand_calculate_ecc (&nand->data_buf[256], &ecc_calc[3]);
+                       switch (nand_correct_data (&nand->data_buf[256], &ecc_code[3], &ecc_calc[3])) {
+                       case -1:
+                               printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
+                               ecc_failed++;
+                               break;
+                       case 1:
+                       case 2: /* transfer ECC corrected data to cache */
+                               if (nand->data_cache)
+                                       memcpy (&nand->data_cache[256], &nand->data_buf[256], 256);
+                               break;
+                       }
+               }
+readdata:
+               /* Read the data from ECC data buffer into return buffer */
+               data_poi = (nand->data_cache) ? nand->data_cache : nand->data_buf;
+               data_poi += col;
+               if ((*retlen + (nand->oobblock - col)) >= len) {
+                       memcpy (buf + *retlen, data_poi, len - *retlen);
+                       *retlen = len;
+               } else {
+                       memcpy (buf + *retlen, data_poi,  nand->oobblock - col);
+                       *retlen += nand->oobblock - col;
+               }
+               /* Set cache page address, invalidate, if ecc_failed */
+               nand->cache_page = (nand->data_cache && !ecc_failed) ? page : -1;
+
+               ecc_status += ecc_failed;
+               ecc_failed = 0;
+
+#else
+               /* Send the read command */
+               NanD_Command(nand, NAND_CMD_READ0);
+               if (nand->bus16) {
+                       NanD_Address(nand, ADDR_COLUMN_PAGE,
+                                    (page << nand->page_shift) + (col >> 1));
+               } else {
+                       NanD_Address(nand, ADDR_COLUMN_PAGE,
+                                    (page << nand->page_shift) + col);
+               }
+
+               /* Read the data directly into the return buffer */
+               if ((*retlen + (nand->oobblock - col)) >= len) {
+                       NanD_ReadBuf(nand, buf + *retlen, len - *retlen);
+                       *retlen = len;
+                       /* We're done */
+                       continue;
+               } else {
+                       NanD_ReadBuf(nand, buf + *retlen, nand->oobblock - col);
+                       *retlen += nand->oobblock - col;
+                       }
+#endif
+               /* For subsequent reads align to page boundary. */
+               col = 0;
+               /* Increment page address */
+               page++;
+       }
+
+       /* De-select the NAND device */
+       NAND_DISABLE_CE(nand);  /* set pin high */
+
+       /*
+        * Return success, if no ECC failures, else -EIO
+        * fs driver will take care of that, because
+        * retlen == desired len and result == -EIO
+        */
+       return ecc_status ? -1 : 0;
+}
+
+/*
+ *     Nand_page_program function is used for write and writev !
+ */
+static int nand_write_page (struct nand_chip *nand,
+                           int page, int col, int last, u_char * ecc_code)
+{
+
+       int i;
+       unsigned long nandptr = nand->IO_ADDR;
+
+#ifdef CONFIG_MTD_NAND_ECC
+#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
+       int ecc_bytes = (nand->oobblock == 512) ? 6 : 3;
+#endif
+#endif
+       /* pad oob area */
+       for (i = nand->oobblock; i < nand->oobblock + nand->oobsize; i++)
+               nand->data_buf[i] = 0xff;
+
+#ifdef CONFIG_MTD_NAND_ECC
+       /* Zero out the ECC array */
+       for (i = 0; i < 6; i++)
+               ecc_code[i] = 0x00;
+
+       /* Read back previous written data, if col > 0 */
+       if (col) {
+               NanD_Command (nand, NAND_CMD_READ0);
+               if (nand->bus16) {
+                       NanD_Address (nand, ADDR_COLUMN_PAGE,
+                                     (page << nand->page_shift) + (col >> 1));
+               } else {
+                       NanD_Address (nand, ADDR_COLUMN_PAGE,
+                                     (page << nand->page_shift) + col);
+               }
+
+               if (nand->bus16) {
+                       u16 val;
+
+                       for (i = 0; i < col; i += 2) {
+                               val = READ_NAND (nandptr);
+                               nand->data_buf[i] = val & 0xff;
+                               nand->data_buf[i + 1] = val >> 8;
+                       }
+               } else {
+                       for (i = 0; i < col; i++)
+                               nand->data_buf[i] = READ_NAND (nandptr);
+               }
+       }
+
+       /* Calculate and write the ECC if we have enough data */
+       if ((col < nand->eccsize) && (last >= nand->eccsize)) {
+               nand_calculate_ecc (&nand->data_buf[0], &(ecc_code[0]));
+               for (i = 0; i < 3; i++) {
+                       nand->data_buf[(nand->oobblock +
+                                       oob_config.ecc_pos[i])] = ecc_code[i];
+               }
+               if (oob_config.eccvalid_pos != -1) {
+                       nand->data_buf[nand->oobblock +
+                                      oob_config.eccvalid_pos] = 0xf0;
+               }
+       }
+
+       /* Calculate and write the second ECC if we have enough data */
+       if ((nand->oobblock == 512) && (last == nand->oobblock)) {
+               nand_calculate_ecc (&nand->data_buf[256], &(ecc_code[3]));
+               for (i = 3; i < 6; i++) {
+                       nand->data_buf[(nand->oobblock +
+                                       oob_config.ecc_pos[i])] = ecc_code[i];
+               }
+               if (oob_config.eccvalid_pos != -1) {
+                       nand->data_buf[nand->oobblock +
+                                      oob_config.eccvalid_pos] &= 0x0f;
+               }
+       }
+#endif
+       /* Prepad for partial page programming !!! */
+       for (i = 0; i < col; i++)
+               nand->data_buf[i] = 0xff;
+
+       /* Postpad for partial page programming !!! oob is already padded */
+       for (i = last; i < nand->oobblock; i++)
+               nand->data_buf[i] = 0xff;
+
+       /* Send command to begin auto page programming */
+       NanD_Command (nand, NAND_CMD_READ0);
+       NanD_Command (nand, NAND_CMD_SEQIN);
+       if (nand->bus16) {
+               NanD_Address (nand, ADDR_COLUMN_PAGE,
+                             (page << nand->page_shift) + (col >> 1));
+       } else {
+               NanD_Address (nand, ADDR_COLUMN_PAGE,
+                             (page << nand->page_shift) + col);
+       }
+
+       /* Write out complete page of data */
+       if (nand->bus16) {
+               for (i = 0; i < (nand->oobblock + nand->oobsize); i += 2) {
+                       WRITE_NAND (nand->data_buf[i] +
+                                   (nand->data_buf[i + 1] << 8),
+                                   nand->IO_ADDR);
+               }
+       } else {
+               for (i = 0; i < (nand->oobblock + nand->oobsize); i++)
+                       WRITE_NAND (nand->data_buf[i], nand->IO_ADDR);
+       }
+
+       /* Send command to actually program the data */
+       NanD_Command (nand, NAND_CMD_PAGEPROG);
+       NanD_Command (nand, NAND_CMD_STATUS);
+#ifdef NAND_NO_RB
+       {
+               u_char ret_val;
+
+               do {
+                       ret_val = READ_NAND (nandptr);  /* wait till ready */
+               } while ((ret_val & 0x40) != 0x40);
+       }
+#endif
+       /* See if device thinks it succeeded */
+       if (READ_NAND (nand->IO_ADDR) & 0x01) {
+               printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__,
+                       page);
+               return -1;
+       }
+#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
+       /*
+        * The NAND device assumes that it is always writing to
+        * a cleanly erased page. Hence, it performs its internal
+        * write verification only on bits that transitioned from
+        * 1 to 0. The device does NOT verify the whole page on a
+        * byte by byte basis. It is possible that the page was
+        * not completely erased or the page is becoming unusable
+        * due to wear. The read with ECC would catch the error
+        * later when the ECC page check fails, but we would rather
+        * catch it early in the page write stage. Better to write
+        * no data than invalid data.
+        */
+
+       /* Send command to read back the page */
+       if (col < nand->eccsize)
+               NanD_Command (nand, NAND_CMD_READ0);
+       else
+               NanD_Command (nand, NAND_CMD_READ1);
+       if (nand->bus16) {
+               NanD_Address (nand, ADDR_COLUMN_PAGE,
+                             (page << nand->page_shift) + (col >> 1));
+       } else {
+               NanD_Address (nand, ADDR_COLUMN_PAGE,
+                             (page << nand->page_shift) + col);
+       }
+
+       /* Loop through and verify the data */
+       if (nand->bus16) {
+               for (i = col; i < last; i = +2) {
+                       if ((nand->data_buf[i] +
+                            (nand->data_buf[i + 1] << 8)) != READ_NAND (nand->IO_ADDR)) {
+                               printf ("%s: Failed write verify, page 0x%08x ",
+                                       __FUNCTION__, page);
+                               return -1;
+                       }
+               }
+       } else {
+               for (i = col; i < last; i++) {
+                       if (nand->data_buf[i] != READ_NAND (nand->IO_ADDR)) {
+                               printf ("%s: Failed write verify, page 0x%08x ",
+                                       __FUNCTION__, page);
+                               return -1;
+                       }
+               }
+       }
+
+#ifdef CONFIG_MTD_NAND_ECC
+       /*
+        * We also want to check that the ECC bytes wrote
+        * correctly for the same reasons stated above.
+        */
+       NanD_Command (nand, NAND_CMD_READOOB);
+       if (nand->bus16) {
+               NanD_Address (nand, ADDR_COLUMN_PAGE,
+                             (page << nand->page_shift) + (col >> 1));
+       } else {
+               NanD_Address (nand, ADDR_COLUMN_PAGE,
+                             (page << nand->page_shift) + col);
+       }
+       if (nand->bus16) {
+               for (i = 0; i < nand->oobsize; i += 2) {
+                       u16 val;
+
+                       val = READ_NAND (nand->IO_ADDR);
+                       nand->data_buf[i] = val & 0xff;
+                       nand->data_buf[i + 1] = val >> 8;
+               }
+       } else {
+               for (i = 0; i < nand->oobsize; i++) {
+                       nand->data_buf[i] = READ_NAND (nand->IO_ADDR);
+               }
+       }
+       for (i = 0; i < ecc_bytes; i++) {
+               if ((nand->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) {
+                       printf ("%s: Failed ECC write "
+                               "verify, page 0x%08x, "
+                               "%6i bytes were succesful\n",
+                               __FUNCTION__, page, i);
+                       return -1;
+               }
+       }
+#endif /* CONFIG_MTD_NAND_ECC */
+#endif /* CONFIG_MTD_NAND_VERIFY_WRITE */
+       return 0;
+}
+
+static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
+                          size_t * retlen, const u_char * buf, u_char * ecc_code)
+{
+       int i, page, col, cnt, ret = 0;
+
+       /* Do not allow write past end of device */
+       if ((to + len) > nand->totlen) {
+               printf ("%s: Attempt to write past end of page\n", __FUNCTION__);
+               return -1;
+       }
+
+       /* Shift to get page */
+       page = ((int) to) >> nand->page_shift;
+
+       /* Get the starting column */
+       col = to & (nand->oobblock - 1);
+
+       /* Initialize return length value */
+       *retlen = 0;
+
+       /* Select the NAND device */
+#ifdef CONFIG_OMAP1510
+       archflashwp(0,0);
+#endif
+#ifdef CFG_NAND_WP
+       NAND_WP_OFF();
+#endif
+
+       NAND_ENABLE_CE(nand);  /* set pin low */
+
+       /* Check the WP bit */
+       NanD_Command(nand, NAND_CMD_STATUS);
+       if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
+               printf ("%s: Device is write protected!!!\n", __FUNCTION__);
+               ret = -1;
+               goto out;
+       }
+
+       /* Loop until all data is written */
+       while (*retlen < len) {
+               /* Invalidate cache, if we write to this page */
+               if (nand->cache_page == page)
+                       nand->cache_page = -1;
+
+               /* Write data into buffer */
+               if ((col + len) >= nand->oobblock) {
+                       for (i = col, cnt = 0; i < nand->oobblock; i++, cnt++) {
+                               nand->data_buf[i] = buf[(*retlen + cnt)];
+                       }
+               } else {
+                       for (i = col, cnt = 0; cnt < (len - *retlen); i++, cnt++) {
+                               nand->data_buf[i] = buf[(*retlen + cnt)];
+                       }
+               }
+               /* We use the same function for write and writev !) */
+               ret = nand_write_page (nand, page, col, i, ecc_code);
+               if (ret)
+                       goto out;
+
+               /* Next data start at page boundary */
+               col = 0;
+
+               /* Update written bytes count */
+               *retlen += cnt;
+
+               /* Increment page address */
+               page++;
+       }
+
+       /* Return happy */
+       *retlen = len;
+
+out:
+       /* De-select the NAND device */
+       NAND_DISABLE_CE(nand);  /* set pin high */
+#ifdef CONFIG_OMAP1510
+       archflashwp(0,1);
+#endif
+#ifdef CFG_NAND_WP
+       NAND_WP_ON();
+#endif
+
+       return ret;
+}
+
+/* read from the 16 bytes of oob data that correspond to a 512 byte
+ * page or 2 256-byte pages.
+ */
+int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
+                        size_t * retlen, u_char * buf)
+{
+       int len256 = 0;
+       struct Nand *mychip;
+       int ret = 0;
+
+       mychip = &nand->chips[ofs >> nand->chipshift];
+
+       /* update address for 2M x 8bit devices. OOB starts on the second */
+       /* page to maintain compatibility with nand_read_ecc. */
+       if (nand->page256) {
+               if (!(ofs & 0x8))
+                       ofs += 0x100;
+               else
+                       ofs -= 0x8;
+       }
+
+       NAND_ENABLE_CE(nand);  /* set pin low */
+       NanD_Command(nand, NAND_CMD_READOOB);
+       if (nand->bus16) {
+               NanD_Address(nand, ADDR_COLUMN_PAGE,
+                            ((ofs >> nand->page_shift) << nand->page_shift) +
+                               ((ofs & (nand->oobblock - 1)) >> 1));
+       } else {
+               NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
+       }
+
+       /* treat crossing 8-byte OOB data for 2M x 8bit devices */
+       /* Note: datasheet says it should automaticaly wrap to the */
+       /*       next OOB block, but it didn't work here. mf.      */
+       if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
+               len256 = (ofs | 0x7) + 1 - ofs;
+               NanD_ReadBuf(nand, buf, len256);
+
+               NanD_Command(nand, NAND_CMD_READOOB);
+               NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
+       }
+
+       NanD_ReadBuf(nand, &buf[len256], len - len256);
+
+       *retlen = len;
+       /* Reading the full OOB data drops us off of the end of the page,
+        * causing the flash device to go into busy mode, so we need
+        * to wait until ready 11.4.1 and Toshiba TC58256FT nands */
+
+       ret = NanD_WaitReady(nand, 1);
+       NAND_DISABLE_CE(nand);  /* set pin high */
+
+       return ret;
+
+}
+
+/* write to the 16 bytes of oob data that correspond to a 512 byte
+ * page or 2 256-byte pages.
+ */
+int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
+                 size_t * retlen, const u_char * buf)
+{
+       int len256 = 0;
+       int i;
+       unsigned long nandptr = nand->IO_ADDR;
+
+#ifdef PSYCHO_DEBUG
+       printf("nand_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",
+              (long)ofs, len, buf[0], buf[1], buf[2], buf[3],
+              buf[8], buf[9], buf[14],buf[15]);
+#endif
+
+       NAND_ENABLE_CE(nand);  /* set pin low to enable chip */
+
+       /* Reset the chip */
+       NanD_Command(nand, NAND_CMD_RESET);
+
+       /* issue the Read2 command to set the pointer to the Spare Data Area. */
+       NanD_Command(nand, NAND_CMD_READOOB);
+       if (nand->bus16) {
+               NanD_Address(nand, ADDR_COLUMN_PAGE,
+                            ((ofs >> nand->page_shift) << nand->page_shift) +
+                               ((ofs & (nand->oobblock - 1)) >> 1));
+       } else {
+               NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
+       }
+
+       /* update address for 2M x 8bit devices. OOB starts on the second */
+       /* page to maintain compatibility with nand_read_ecc. */
+       if (nand->page256) {
+               if (!(ofs & 0x8))
+                       ofs += 0x100;
+               else
+                       ofs -= 0x8;
+       }
+
+       /* issue the Serial Data In command to initial the Page Program process */
+       NanD_Command(nand, NAND_CMD_SEQIN);
+       if (nand->bus16) {
+               NanD_Address(nand, ADDR_COLUMN_PAGE,
+                            ((ofs >> nand->page_shift) << nand->page_shift) +
+                               ((ofs & (nand->oobblock - 1)) >> 1));
+       } else {
+               NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
+       }
+
+       /* treat crossing 8-byte OOB data for 2M x 8bit devices */
+       /* Note: datasheet says it should automaticaly wrap to the */
+       /*       next OOB block, but it didn't work here. mf.      */
+       if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
+               len256 = (ofs | 0x7) + 1 - ofs;
+               for (i = 0; i < len256; i++)
+                       WRITE_NAND(buf[i], nandptr);
+
+               NanD_Command(nand, NAND_CMD_PAGEPROG);
+               NanD_Command(nand, NAND_CMD_STATUS);
+#ifdef NAND_NO_RB
+               { u_char ret_val;
+                       do {
+                               ret_val = READ_NAND(nandptr); /* wait till ready */
+                       } while ((ret_val & 0x40) != 0x40);
+               }
+#endif
+               if (READ_NAND(nandptr) & 1) {
+                       puts ("Error programming oob data\n");
+                       /* There was an error */
+                       NAND_DISABLE_CE(nand);  /* set pin high */
+                       *retlen = 0;
+                       return -1;
+               }
+               NanD_Command(nand, NAND_CMD_SEQIN);
+               NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
+       }
+
+       if (nand->bus16) {
+               for (i = len256; i < len; i += 2) {
+                       WRITE_NAND(buf[i] + (buf[i+1] << 8), nandptr);
+               }
+       } else {
+               for (i = len256; i < len; i++)
+                       WRITE_NAND(buf[i], nandptr);
+       }
+
+       NanD_Command(nand, NAND_CMD_PAGEPROG);
+       NanD_Command(nand, NAND_CMD_STATUS);
+#ifdef NAND_NO_RB
+       {       u_char ret_val;
+               do {
+                       ret_val = READ_NAND(nandptr); /* wait till ready */
+               } while ((ret_val & 0x40) != 0x40);
+       }
+#endif
+       if (READ_NAND(nandptr) & 1) {
+               puts ("Error programming oob data\n");
+               /* There was an error */
+               NAND_DISABLE_CE(nand);  /* set pin high */
+               *retlen = 0;
+               return -1;
+       }
+
+       NAND_DISABLE_CE(nand);  /* set pin high */
+       *retlen = len;
+       return 0;
+
+}
+
+int nand_legacy_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean)
+{
+       /* This is defined as a structure so it will work on any system
+        * using native endian jffs2 (the default).
+        */
+       static struct jffs2_unknown_node clean_marker = {
+               JFFS2_MAGIC_BITMASK,
+               JFFS2_NODETYPE_CLEANMARKER,
+               8               /* 8 bytes in this node */
+       };
+       unsigned long nandptr;
+       struct Nand *mychip;
+       int ret = 0;
+
+       if (ofs & (nand->erasesize-1) || len & (nand->erasesize-1)) {
+               printf ("Offset and size must be sector aligned, erasesize = %d\n",
+                       (int) nand->erasesize);
+               return -1;
+       }
+
+       nandptr = nand->IO_ADDR;
+
+       /* Select the NAND device */
+#ifdef CONFIG_OMAP1510
+       archflashwp(0,0);
+#endif
+#ifdef CFG_NAND_WP
+       NAND_WP_OFF();
+#endif
+    NAND_ENABLE_CE(nand);  /* set pin low */
+
+       /* Check the WP bit */
+       NanD_Command(nand, NAND_CMD_STATUS);
+       if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
+               printf ("nand_write_ecc: Device is write protected!!!\n");
+               ret = -1;
+               goto out;
+       }
+
+       /* Check the WP bit */
+       NanD_Command(nand, NAND_CMD_STATUS);
+       if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
+               printf ("%s: Device is write protected!!!\n", __FUNCTION__);
+               ret = -1;
+               goto out;
+       }
+
+       /* FIXME: Do nand in the background. Use timers or schedule_task() */
+       while(len) {
+               /*mychip = &nand->chips[shr(ofs, nand->chipshift)];*/
+               mychip = &nand->chips[ofs >> nand->chipshift];
+
+               /* always check for bad block first, genuine bad blocks
+                * should _never_  be erased.
+                */
+               if (ALLOW_ERASE_BAD_DEBUG || !check_block(nand, ofs)) {
+                       /* Select the NAND device */
+                       NAND_ENABLE_CE(nand);  /* set pin low */
+
+                       NanD_Command(nand, NAND_CMD_ERASE1);
+                       NanD_Address(nand, ADDR_PAGE, ofs);
+                       NanD_Command(nand, NAND_CMD_ERASE2);
+
+                       NanD_Command(nand, NAND_CMD_STATUS);
+
+#ifdef NAND_NO_RB
+                       {       u_char ret_val;
+                               do {
+                                       ret_val = READ_NAND(nandptr); /* wait till ready */
+                               } while ((ret_val & 0x40) != 0x40);
+                       }
+#endif
+                       if (READ_NAND(nandptr) & 1) {
+                               printf ("%s: Error erasing at 0x%lx\n",
+                                       __FUNCTION__, (long)ofs);
+                               /* There was an error */
+                               ret = -1;
+                               goto out;
+                       }
+                       if (clean) {
+                               int n;  /* return value not used */
+                               int p, l;
+
+                               /* clean marker position and size depend
+                                * on the page size, since 256 byte pages
+                                * only have 8 bytes of oob data
+                                */
+                               if (nand->page256) {
+                                       p = NAND_JFFS2_OOB8_FSDAPOS;
+                                       l = NAND_JFFS2_OOB8_FSDALEN;
+                               } else {
+                                       p = NAND_JFFS2_OOB16_FSDAPOS;
+                                       l = NAND_JFFS2_OOB16_FSDALEN;
+                               }
+
+                               ret = nand_write_oob(nand, ofs + p, l, (size_t *)&n,
+                                                    (u_char *)&clean_marker);
+                               /* quit here if write failed */
+                               if (ret)
+                                       goto out;
+                       }
+               }
+               ofs += nand->erasesize;
+               len -= nand->erasesize;
+       }
+
+out:
+       /* De-select the NAND device */
+       NAND_DISABLE_CE(nand);  /* set pin high */
+#ifdef CONFIG_OMAP1510
+       archflashwp(0,1);
+#endif
+#ifdef CFG_NAND_WP
+       NAND_WP_ON();
+#endif
+
+       return ret;
+}
+
+
+static inline int nandcheck(unsigned long potential, unsigned long physadr)
+{
+       return 0;
+}
+
+unsigned long nand_probe(unsigned long physadr)
+{
+       struct nand_chip *nand = NULL;
+       int i = 0, ChipID = 1;
+
+#ifdef CONFIG_MTD_NAND_ECC_JFFS2
+       oob_config.ecc_pos[0] = NAND_JFFS2_OOB_ECCPOS0;
+       oob_config.ecc_pos[1] = NAND_JFFS2_OOB_ECCPOS1;
+       oob_config.ecc_pos[2] = NAND_JFFS2_OOB_ECCPOS2;
+       oob_config.ecc_pos[3] = NAND_JFFS2_OOB_ECCPOS3;
+       oob_config.ecc_pos[4] = NAND_JFFS2_OOB_ECCPOS4;
+       oob_config.ecc_pos[5] = NAND_JFFS2_OOB_ECCPOS5;
+       oob_config.eccvalid_pos = 4;
+#else
+       oob_config.ecc_pos[0] = NAND_NOOB_ECCPOS0;
+       oob_config.ecc_pos[1] = NAND_NOOB_ECCPOS1;
+       oob_config.ecc_pos[2] = NAND_NOOB_ECCPOS2;
+       oob_config.ecc_pos[3] = NAND_NOOB_ECCPOS3;
+       oob_config.ecc_pos[4] = NAND_NOOB_ECCPOS4;
+       oob_config.ecc_pos[5] = NAND_NOOB_ECCPOS5;
+       oob_config.eccvalid_pos = NAND_NOOB_ECCVPOS;
+#endif
+       oob_config.badblock_pos = 5;
+
+       for (i=0; i<CFG_MAX_NAND_DEVICE; i++) {
+               if (nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN) {
+                       nand = &nand_dev_desc[i];
+                       break;
+               }
+       }
+       if (!nand)
+               return (0);
+
+       memset((char *)nand, 0, sizeof(struct nand_chip));
+
+       nand->IO_ADDR = physadr;
+       nand->cache_page = -1;  /* init the cache page */
+       NanD_ScanChips(nand);
+
+       if (nand->totlen == 0) {
+               /* no chips found, clean up and quit */
+               memset((char *)nand, 0, sizeof(struct nand_chip));
+               nand->ChipID = NAND_ChipID_UNKNOWN;
+               return (0);
+       }
+
+       nand->ChipID = ChipID;
+       if (curr_device == -1)
+               curr_device = i;
+
+       nand->data_buf = malloc (nand->oobblock + nand->oobsize);
+       if (!nand->data_buf) {
+               puts ("Cannot allocate memory for data structures.\n");
+               return (0);
+       }
+
+       return (nand->totlen);
+}
+
+#ifdef CONFIG_MTD_NAND_ECC
+/*
+ * Pre-calculated 256-way 1 byte column parity
+ */
+static const u_char nand_ecc_precalc_table[] = {
+       0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
+       0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
+       0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
+       0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
+       0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
+       0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
+       0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
+       0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
+       0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
+       0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
+       0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
+       0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
+       0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
+       0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
+       0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
+       0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
+       0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
+       0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
+       0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
+       0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
+       0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
+       0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
+       0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
+       0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
+       0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
+       0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
+       0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
+       0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
+       0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
+       0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
+       0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
+       0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
+};
+
+
+/*
+ * Creates non-inverted ECC code from line parity
+ */
+static void nand_trans_result(u_char reg2, u_char reg3,
+       u_char *ecc_code)
+{
+       u_char a, b, i, tmp1, tmp2;
+
+       /* Initialize variables */
+       a = b = 0x80;
+       tmp1 = tmp2 = 0;
+
+       /* Calculate first ECC byte */
+       for (i = 0; i < 4; i++) {
+               if (reg3 & a)           /* LP15,13,11,9 --> ecc_code[0] */
+                       tmp1 |= b;
+               b >>= 1;
+               if (reg2 & a)           /* LP14,12,10,8 --> ecc_code[0] */
+                       tmp1 |= b;
+               b >>= 1;
+               a >>= 1;
+       }
+
+       /* Calculate second ECC byte */
+       b = 0x80;
+       for (i = 0; i < 4; i++) {
+               if (reg3 & a)           /* LP7,5,3,1 --> ecc_code[1] */
+                       tmp2 |= b;
+               b >>= 1;
+               if (reg2 & a)           /* LP6,4,2,0 --> ecc_code[1] */
+                       tmp2 |= b;
+               b >>= 1;
+               a >>= 1;
+       }
+
+       /* Store two of the ECC bytes */
+       ecc_code[0] = tmp1;
+       ecc_code[1] = tmp2;
+}
+
+/*
+ * Calculate 3 byte ECC code for 256 byte block
+ */
+static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code)
+{
+       u_char idx, reg1, reg3;
+       int j;
+
+       /* Initialize variables */
+       reg1 = reg3 = 0;
+       ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
+
+       /* Build up column parity */
+       for(j = 0; j < 256; j++) {
+
+               /* Get CP0 - CP5 from table */
+               idx = nand_ecc_precalc_table[dat[j]];
+               reg1 ^= idx;
+
+               /* All bit XOR = 1 ? */
+               if (idx & 0x40) {
+                       reg3 ^= (u_char) j;
+               }
+       }
+
+       /* Create non-inverted ECC code from line parity */
+       nand_trans_result((reg1 & 0x40) ? ~reg3 : reg3, reg3, ecc_code);
+
+       /* Calculate final ECC code */
+       ecc_code[0] = ~ecc_code[0];
+       ecc_code[1] = ~ecc_code[1];
+       ecc_code[2] = ((~reg1) << 2) | 0x03;
+}
+
+/*
+ * Detect and correct a 1 bit error for 256 byte block
+ */
+static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc)
+{
+       u_char a, b, c, d1, d2, d3, add, bit, i;
+
+       /* Do error detection */
+       d1 = calc_ecc[0] ^ read_ecc[0];
+       d2 = calc_ecc[1] ^ read_ecc[1];
+       d3 = calc_ecc[2] ^ read_ecc[2];
+
+       if ((d1 | d2 | d3) == 0) {
+               /* No errors */
+               return 0;
+       } else {
+               a = (d1 ^ (d1 >> 1)) & 0x55;
+               b = (d2 ^ (d2 >> 1)) & 0x55;
+               c = (d3 ^ (d3 >> 1)) & 0x54;
+
+               /* Found and will correct single bit error in the data */
+               if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
+                       c = 0x80;
+                       add = 0;
+                       a = 0x80;
+                       for (i=0; i<4; i++) {
+                               if (d1 & c)
+                                       add |= a;
+                               c >>= 2;
+                               a >>= 1;
+                       }
+                       c = 0x80;
+                       for (i=0; i<4; i++) {
+                               if (d2 & c)
+                                       add |= a;
+                               c >>= 2;
+                               a >>= 1;
+                       }
+                       bit = 0;
+                       b = 0x04;
+                       c = 0x80;
+                       for (i=0; i<3; i++) {
+                               if (d3 & c)
+                                       bit |= b;
+                               c >>= 2;
+                               b >>= 1;
+                       }
+                       b = 0x01;
+                       a = dat[add];
+                       a ^= (b << bit);
+                       dat[add] = a;
+                       return 1;
+               }
+               else {
+                       i = 0;
+                       while (d1) {
+                               if (d1 & 0x01)
+                                       ++i;
+                               d1 >>= 1;
+                       }
+                       while (d2) {
+                               if (d2 & 0x01)
+                                       ++i;
+                               d2 >>= 1;
+                       }
+                       while (d3) {
+                               if (d3 & 0x01)
+                                       ++i;
+                               d3 >>= 1;
+                       }
+                       if (i == 1) {
+                               /* ECC Code Error Correction */
+                               read_ecc[0] = calc_ecc[0];
+                               read_ecc[1] = calc_ecc[1];
+                               read_ecc[2] = calc_ecc[2];
+                               return 2;
+                       }
+                       else {
+                               /* Uncorrectable Error */
+                               return -1;
+                       }
+               }
+       }
+
+       /* Should never happen */
+       return -1;
+}
+
+#endif
+
+#ifdef CONFIG_JFFS2_NAND
+int read_jffs2_nand(size_t start, size_t len,
+               size_t * retlen, u_char * buf, int nanddev)
+{
+       return nand_legacy_rw(nand_dev_desc + nanddev, NANDRW_READ | NANDRW_JFFS2,
+                       start, len, retlen, buf);
+}
+#endif /* CONFIG_JFFS2_NAND */
+
+#endif
diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile
new file mode 100644 (file)
index 0000000..2049413
--- /dev/null
@@ -0,0 +1,44 @@
+#
+# Copyright (C) 2005-2007 Samsung Electronics.
+# Kyungmin Park <kyungmin.park@samsung.com>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libonenand.a
+
+COBJS  := onenand_base.o onenand_bbt.o
+
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB): $(obj).depend $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
new file mode 100644 (file)
index 0000000..7983a4a
--- /dev/null
@@ -0,0 +1,1294 @@
+/*
+ *  linux/drivers/mtd/onenand/onenand_base.c
+ *
+ *  Copyright (C) 2005-2007 Samsung Electronics
+ *  Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_CMD_ONENAND
+
+#include <linux/mtd/compat.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+
+#include <asm/io.h>
+#include <asm/errno.h>
+
+static const unsigned char ffchars[] = {
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 32 */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */
+};
+
+/**
+ * onenand_readw - [OneNAND Interface] Read OneNAND register
+ * @param addr         address to read
+ *
+ * Read OneNAND register
+ */
+static unsigned short onenand_readw(void __iomem * addr)
+{
+       return readw(addr);
+}
+
+/**
+ * onenand_writew - [OneNAND Interface] Write OneNAND register with value
+ * @param value                value to write
+ * @param addr         address to write
+ *
+ * Write OneNAND register with value
+ */
+static void onenand_writew(unsigned short value, void __iomem * addr)
+{
+       writew(value, addr);
+}
+
+/**
+ * onenand_block_address - [DEFAULT] Get block address
+ * @param device       the device id
+ * @param block                the block
+ * @return             translated block address if DDP, otherwise same
+ *
+ * Setup Start Address 1 Register (F100h)
+ */
+static int onenand_block_address(int device, int block)
+{
+       if (device & ONENAND_DEVICE_IS_DDP) {
+               /* Device Flash Core select, NAND Flash Block Address */
+               int dfs = 0, density, mask;
+
+               density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
+               mask = (1 << (density + 6));
+
+               if (block & mask)
+                       dfs = 1;
+
+               return (dfs << ONENAND_DDP_SHIFT) | (block & (mask - 1));
+       }
+
+       return block;
+}
+
+/**
+ * onenand_bufferram_address - [DEFAULT] Get bufferram address
+ * @param device       the device id
+ * @param block                the block
+ * @return             set DBS value if DDP, otherwise 0
+ *
+ * Setup Start Address 2 Register (F101h) for DDP
+ */
+static int onenand_bufferram_address(int device, int block)
+{
+       if (device & ONENAND_DEVICE_IS_DDP) {
+               /* Device BufferRAM Select */
+               int dbs = 0, density, mask;
+
+               density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
+               mask = (1 << (density + 6));
+
+               if (block & mask)
+                       dbs = 1;
+
+               return (dbs << ONENAND_DDP_SHIFT);
+       }
+
+       return 0;
+}
+
+/**
+ * onenand_page_address - [DEFAULT] Get page address
+ * @param page         the page address
+ * @param sector       the sector address
+ * @return             combined page and sector address
+ *
+ * Setup Start Address 8 Register (F107h)
+ */
+static int onenand_page_address(int page, int sector)
+{
+       /* Flash Page Address, Flash Sector Address */
+       int fpa, fsa;
+
+       fpa = page & ONENAND_FPA_MASK;
+       fsa = sector & ONENAND_FSA_MASK;
+
+       return ((fpa << ONENAND_FPA_SHIFT) | fsa);
+}
+
+/**
+ * onenand_buffer_address - [DEFAULT] Get buffer address
+ * @param dataram1     DataRAM index
+ * @param sectors      the sector address
+ * @param count                the number of sectors
+ * @return             the start buffer value
+ *
+ * Setup Start Buffer Register (F200h)
+ */
+static int onenand_buffer_address(int dataram1, int sectors, int count)
+{
+       int bsa, bsc;
+
+       /* BufferRAM Sector Address */
+       bsa = sectors & ONENAND_BSA_MASK;
+
+       if (dataram1)
+               bsa |= ONENAND_BSA_DATARAM1;    /* DataRAM1 */
+       else
+               bsa |= ONENAND_BSA_DATARAM0;    /* DataRAM0 */
+
+       /* BufferRAM Sector Count */
+       bsc = count & ONENAND_BSC_MASK;
+
+       return ((bsa << ONENAND_BSA_SHIFT) | bsc);
+}
+
+/**
+ * onenand_command - [DEFAULT] Send command to OneNAND device
+ * @param mtd          MTD device structure
+ * @param cmd          the command to be sent
+ * @param addr         offset to read from or write to
+ * @param len          number of bytes to read or write
+ *
+ * Send command to OneNAND device. This function is used for middle/large page
+ * devices (1KB/2KB Bytes per page)
+ */
+static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr,
+                          size_t len)
+{
+       struct onenand_chip *this = mtd->priv;
+       int value, readcmd = 0;
+       int block, page;
+       /* Now we use page size operation */
+       int sectors = 4, count = 4;
+
+       /* Address translation */
+       switch (cmd) {
+       case ONENAND_CMD_UNLOCK:
+       case ONENAND_CMD_LOCK:
+       case ONENAND_CMD_LOCK_TIGHT:
+               block = -1;
+               page = -1;
+               break;
+
+       case ONENAND_CMD_ERASE:
+       case ONENAND_CMD_BUFFERRAM:
+               block = (int)(addr >> this->erase_shift);
+               page = -1;
+               break;
+
+       default:
+               block = (int)(addr >> this->erase_shift);
+               page = (int)(addr >> this->page_shift);
+               page &= this->page_mask;
+               break;
+       }
+
+       /* NOTE: The setting order of the registers is very important! */
+       if (cmd == ONENAND_CMD_BUFFERRAM) {
+               /* Select DataRAM for DDP */
+               value = onenand_bufferram_address(this->device_id, block);
+               this->write_word(value,
+                                this->base + ONENAND_REG_START_ADDRESS2);
+
+               /* Switch to the next data buffer */
+               ONENAND_SET_NEXT_BUFFERRAM(this);
+
+               return 0;
+       }
+
+       if (block != -1) {
+               /* Write 'DFS, FBA' of Flash */
+               value = onenand_block_address(this->device_id, block);
+               this->write_word(value,
+                                this->base + ONENAND_REG_START_ADDRESS1);
+       }
+
+       if (page != -1) {
+               int dataram;
+
+               switch (cmd) {
+               case ONENAND_CMD_READ:
+               case ONENAND_CMD_READOOB:
+                       dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
+                       readcmd = 1;
+                       break;
+
+               default:
+                       dataram = ONENAND_CURRENT_BUFFERRAM(this);
+                       break;
+               }
+
+               /* Write 'FPA, FSA' of Flash */
+               value = onenand_page_address(page, sectors);
+               this->write_word(value,
+                                this->base + ONENAND_REG_START_ADDRESS8);
+
+               /* Write 'BSA, BSC' of DataRAM */
+               value = onenand_buffer_address(dataram, sectors, count);
+               this->write_word(value, this->base + ONENAND_REG_START_BUFFER);
+
+               if (readcmd) {
+                       /* Select DataRAM for DDP */
+                       value =
+                           onenand_bufferram_address(this->device_id, block);
+                       this->write_word(value,
+                                        this->base +
+                                        ONENAND_REG_START_ADDRESS2);
+               }
+       }
+
+       /* Interrupt clear */
+       this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT);
+       /* Write command */
+       this->write_word(cmd, this->base + ONENAND_REG_COMMAND);
+
+       return 0;
+}
+
+/**
+ * onenand_wait - [DEFAULT] wait until the command is done
+ * @param mtd          MTD device structure
+ * @param state                state to select the max. timeout value
+ *
+ * Wait for command done. This applies to all OneNAND command
+ * Read can take up to 30us, erase up to 2ms and program up to 350us
+ * according to general OneNAND specs
+ */
+static int onenand_wait(struct mtd_info *mtd, int state)
+{
+       struct onenand_chip *this = mtd->priv;
+       unsigned int flags = ONENAND_INT_MASTER;
+       unsigned int interrupt = 0;
+       unsigned int ctrl, ecc;
+
+       while (1) {
+               interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
+               if (interrupt & flags)
+                       break;
+       }
+
+       ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
+
+       if (ctrl & ONENAND_CTRL_ERROR) {
+               DEBUG(MTD_DEBUG_LEVEL0,
+                     "onenand_wait: controller error = 0x%04x\n", ctrl);
+               return -EAGAIN;
+       }
+
+       if (ctrl & ONENAND_CTRL_LOCK) {
+               DEBUG(MTD_DEBUG_LEVEL0,
+                     "onenand_wait: it's locked error = 0x%04x\n", ctrl);
+               return -EIO;
+       }
+
+       if (interrupt & ONENAND_INT_READ) {
+               ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
+               if (ecc & ONENAND_ECC_2BIT_ALL) {
+                       DEBUG(MTD_DEBUG_LEVEL0,
+                             "onenand_wait: ECC error = 0x%04x\n", ecc);
+                       return -EBADMSG;
+               }
+       }
+
+       return 0;
+}
+
+/**
+ * onenand_bufferram_offset - [DEFAULT] BufferRAM offset
+ * @param mtd          MTD data structure
+ * @param area         BufferRAM area
+ * @return             offset given area
+ *
+ * Return BufferRAM offset given area
+ */
+static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
+{
+       struct onenand_chip *this = mtd->priv;
+
+       if (ONENAND_CURRENT_BUFFERRAM(this)) {
+               if (area == ONENAND_DATARAM)
+                       return mtd->oobblock;
+               if (area == ONENAND_SPARERAM)
+                       return mtd->oobsize;
+       }
+
+       return 0;
+}
+
+/**
+ * onenand_read_bufferram - [OneNAND Interface] Read the bufferram area
+ * @param mtd          MTD data structure
+ * @param area         BufferRAM area
+ * @param buffer       the databuffer to put/get data
+ * @param offset       offset to read from or write to
+ * @param count                number of bytes to read/write
+ *
+ * Read the BufferRAM area
+ */
+static int onenand_read_bufferram(struct mtd_info *mtd, int area,
+                                 unsigned char *buffer, int offset,
+                                 size_t count)
+{
+       struct onenand_chip *this = mtd->priv;
+       void __iomem *bufferram;
+
+       bufferram = this->base + area;
+       bufferram += onenand_bufferram_offset(mtd, area);
+
+       memcpy(buffer, bufferram + offset, count);
+
+       return 0;
+}
+
+/**
+ * onenand_sync_read_bufferram - [OneNAND Interface] Read the bufferram area with Sync. Burst mode
+ * @param mtd          MTD data structure
+ * @param area         BufferRAM area
+ * @param buffer       the databuffer to put/get data
+ * @param offset       offset to read from or write to
+ * @param count                number of bytes to read/write
+ *
+ * Read the BufferRAM area with Sync. Burst Mode
+ */
+static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area,
+                                      unsigned char *buffer, int offset,
+                                      size_t count)
+{
+       struct onenand_chip *this = mtd->priv;
+       void __iomem *bufferram;
+
+       bufferram = this->base + area;
+       bufferram += onenand_bufferram_offset(mtd, area);
+
+       this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
+
+       memcpy(buffer, bufferram + offset, count);
+
+       this->mmcontrol(mtd, 0);
+
+       return 0;
+}
+
+/**
+ * onenand_write_bufferram - [OneNAND Interface] Write the bufferram area
+ * @param mtd          MTD data structure
+ * @param area         BufferRAM area
+ * @param buffer       the databuffer to put/get data
+ * @param offset       offset to read from or write to
+ * @param count                number of bytes to read/write
+ *
+ * Write the BufferRAM area
+ */
+static int onenand_write_bufferram(struct mtd_info *mtd, int area,
+                                  const unsigned char *buffer, int offset,
+                                  size_t count)
+{
+       struct onenand_chip *this = mtd->priv;
+       void __iomem *bufferram;
+
+       bufferram = this->base + area;
+       bufferram += onenand_bufferram_offset(mtd, area);
+
+       memcpy(bufferram + offset, buffer, count);
+
+       return 0;
+}
+
+/**
+ * onenand_check_bufferram - [GENERIC] Check BufferRAM information
+ * @param mtd          MTD data structure
+ * @param addr         address to check
+ * @return             1 if there are valid data, otherwise 0
+ *
+ * Check bufferram if there is data we required
+ */
+static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
+{
+       struct onenand_chip *this = mtd->priv;
+       int block, page;
+       int i;
+
+       block = (int)(addr >> this->erase_shift);
+       page = (int)(addr >> this->page_shift);
+       page &= this->page_mask;
+
+       i = ONENAND_CURRENT_BUFFERRAM(this);
+
+       /* Is there valid data? */
+       if (this->bufferram[i].block == block &&
+           this->bufferram[i].page == page && this->bufferram[i].valid)
+               return 1;
+
+       return 0;
+}
+
+/**
+ * onenand_update_bufferram - [GENERIC] Update BufferRAM information
+ * @param mtd          MTD data structure
+ * @param addr         address to update
+ * @param valid                valid flag
+ *
+ * Update BufferRAM information
+ */
+static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
+                                   int valid)
+{
+       struct onenand_chip *this = mtd->priv;
+       int block, page;
+       int i;
+
+       block = (int)(addr >> this->erase_shift);
+       page = (int)(addr >> this->page_shift);
+       page &= this->page_mask;
+
+       /* Invalidate BufferRAM */
+       for (i = 0; i < MAX_BUFFERRAM; i++) {
+               if (this->bufferram[i].block == block &&
+                   this->bufferram[i].page == page)
+                       this->bufferram[i].valid = 0;
+       }
+
+       /* Update BufferRAM */
+       i = ONENAND_CURRENT_BUFFERRAM(this);
+       this->bufferram[i].block = block;
+       this->bufferram[i].page = page;
+       this->bufferram[i].valid = valid;
+
+       return 0;
+}
+
+/**
+ * onenand_get_device - [GENERIC] Get chip for selected access
+ * @param mtd          MTD device structure
+ * @param new_state    the state which is requested
+ *
+ * Get the device and lock it for exclusive access
+ */
+static void onenand_get_device(struct mtd_info *mtd, int new_state)
+{
+       /* Do nothing */
+}
+
+/**
+ * onenand_release_device - [GENERIC] release chip
+ * @param mtd          MTD device structure
+ *
+ * Deselect, release chip lock and wake up anyone waiting on the device
+ */
+static void onenand_release_device(struct mtd_info *mtd)
+{
+       /* Do nothing */
+}
+
+/**
+ * onenand_read_ecc - [MTD Interface] Read data with ECC
+ * @param mtd          MTD device structure
+ * @param from         offset to read from
+ * @param len          number of bytes to read
+ * @param retlen       pointer to variable to store the number of read bytes
+ * @param buf          the databuffer to put data
+ * @param oob_buf      filesystem supplied oob data buffer
+ * @param oobsel       oob selection structure
+ *
+ * OneNAND read with ECC
+ */
+static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
+                           size_t * retlen, u_char * buf,
+                           u_char * oob_buf, struct nand_oobinfo *oobsel)
+{
+       struct onenand_chip *this = mtd->priv;
+       int read = 0, column;
+       int thislen;
+       int ret = 0;
+
+       DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ecc: from = 0x%08x, len = %i\n",
+             (unsigned int)from, (int)len);
+
+       /* Do not allow reads past end of device */
+       if ((from + len) > mtd->size) {
+               DEBUG(MTD_DEBUG_LEVEL0,
+                     "onenand_read_ecc: Attempt read beyond end of device\n");
+               *retlen = 0;
+               return -EINVAL;
+       }
+
+       /* Grab the lock and see if the device is available */
+       onenand_get_device(mtd, FL_READING);
+
+       while (read < len) {
+               thislen = min_t(int, mtd->oobblock, len - read);
+
+               column = from & (mtd->oobblock - 1);
+               if (column + thislen > mtd->oobblock)
+                       thislen = mtd->oobblock - column;
+
+               if (!onenand_check_bufferram(mtd, from)) {
+                       this->command(mtd, ONENAND_CMD_READ, from,
+                                     mtd->oobblock);
+                       ret = this->wait(mtd, FL_READING);
+                       /* First copy data and check return value for ECC handling */
+                       onenand_update_bufferram(mtd, from, 1);
+               }
+
+               this->read_bufferram(mtd, ONENAND_DATARAM, buf, column,
+                                    thislen);
+
+               read += thislen;
+               if (read == len)
+                       break;
+
+               if (ret) {
+                       DEBUG(MTD_DEBUG_LEVEL0,
+                             "onenand_read_ecc: read failed = %d\n", ret);
+                       break;
+               }
+
+               from += thislen;
+               buf += thislen;
+       }
+
+       /* Deselect and wake up anyone waiting on the device */
+       onenand_release_device(mtd);
+
+       /*
+        * Return success, if no ECC failures, else -EBADMSG
+        * fs driver will take care of that, because
+        * retlen == desired len and result == -EBADMSG
+        */
+       *retlen = read;
+       return ret;
+}
+
+/**
+ * onenand_read - [MTD Interface] MTD compability function for onenand_read_ecc
+ * @param mtd          MTD device structure
+ * @param from         offset to read from
+ * @param len          number of bytes to read
+ * @param retlen       pointer to variable to store the number of read bytes
+ * @param buf          the databuffer to put data
+ *
+ * This function simply calls onenand_read_ecc with oob buffer and oobsel = NULL
+*/
+int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
+                size_t * retlen, u_char * buf)
+{
+       return onenand_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
+}
+
+/**
+ * onenand_read_oob - [MTD Interface] OneNAND read out-of-band
+ * @param mtd          MTD device structure
+ * @param from         offset to read from
+ * @param len          number of bytes to read
+ * @param retlen       pointer to variable to store the number of read bytes
+ * @param buf          the databuffer to put data
+ *
+ * OneNAND read out-of-band data from the spare area
+ */
+int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
+                    size_t * retlen, u_char * buf)
+{
+       struct onenand_chip *this = mtd->priv;
+       int read = 0, thislen, column;
+       int ret = 0;
+
+       DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n",
+             (unsigned int)from, (int)len);
+
+       /* Initialize return length value */
+       *retlen = 0;
+
+       /* Do not allow reads past end of device */
+       if (unlikely((from + len) > mtd->size)) {
+               DEBUG(MTD_DEBUG_LEVEL0,
+                     "onenand_read_oob: Attempt read beyond end of device\n");
+               return -EINVAL;
+       }
+
+       /* Grab the lock and see if the device is available */
+       onenand_get_device(mtd, FL_READING);
+
+       column = from & (mtd->oobsize - 1);
+
+       while (read < len) {
+               thislen = mtd->oobsize - column;
+               thislen = min_t(int, thislen, len);
+
+               this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
+
+               onenand_update_bufferram(mtd, from, 0);
+
+               ret = this->wait(mtd, FL_READING);
+               /* First copy data and check return value for ECC handling */
+
+               this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column,
+                                    thislen);
+
+               read += thislen;
+               if (read == len)
+                       break;
+
+               if (ret) {
+                       DEBUG(MTD_DEBUG_LEVEL0,
+                             "onenand_read_oob: read failed = %d\n", ret);
+                       break;
+               }
+
+               buf += thislen;
+               /* Read more? */
+               if (read < len) {
+                       /* Page size */
+                       from += mtd->oobblock;
+                       column = 0;
+               }
+       }
+
+       /* Deselect and wake up anyone waiting on the device */
+       onenand_release_device(mtd);
+
+       *retlen = read;
+       return ret;
+}
+
+#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
+/**
+ * onenand_verify_page - [GENERIC] verify the chip contents after a write
+ * @param mtd          MTD device structure
+ * @param buf          the databuffer to verify
+ * @param block                block address
+ * @param page         page address
+ *
+ * Check DataRAM area directly
+ */
+static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
+                              loff_t addr, int block, int page)
+{
+       struct onenand_chip *this = mtd->priv;
+       void __iomem *dataram0, *dataram1;
+       int ret = 0;
+
+       this->command(mtd, ONENAND_CMD_READ, addr, mtd->oobblock);
+
+       ret = this->wait(mtd, FL_READING);
+       if (ret)
+               return ret;
+
+       onenand_update_bufferram(mtd, addr, 1);
+
+       /* Check, if the two dataram areas are same */
+       dataram0 = this->base + ONENAND_DATARAM;
+       dataram1 = dataram0 + mtd->oobblock;
+
+       if (memcmp(dataram0, dataram1, mtd->oobblock))
+               return -EBADMSG;
+
+       return 0;
+}
+#else
+#define onenand_verify_page(...)       (0)
+#endif
+
+#define NOTALIGNED(x)  ((x & (mtd->oobblock - 1)) != 0)
+
+/**
+ * onenand_write_ecc - [MTD Interface] OneNAND write with ECC
+ * @param mtd          MTD device structure
+ * @param to           offset to write to
+ * @param len          number of bytes to write
+ * @param retlen       pointer to variable to store the number of written bytes
+ * @param buf          the data to write
+ * @param eccbuf       filesystem supplied oob data buffer
+ * @param oobsel       oob selection structure
+ *
+ * OneNAND write with ECC
+ */
+static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
+                            size_t * retlen, const u_char * buf,
+                            u_char * eccbuf, struct nand_oobinfo *oobsel)
+{
+       struct onenand_chip *this = mtd->priv;
+       int written = 0;
+       int ret = 0;
+
+       DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ecc: to = 0x%08x, len = %i\n",
+             (unsigned int)to, (int)len);
+
+       /* Initialize retlen, in case of early exit */
+       *retlen = 0;
+
+       /* Do not allow writes past end of device */
+       if (unlikely((to + len) > mtd->size)) {
+               DEBUG(MTD_DEBUG_LEVEL0,
+                     "onenand_write_ecc: Attempt write to past end of device\n");
+               return -EINVAL;
+       }
+
+       /* Reject writes, which are not page aligned */
+       if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
+               DEBUG(MTD_DEBUG_LEVEL0,
+                     "onenand_write_ecc: Attempt to write not page aligned data\n");
+               return -EINVAL;
+       }
+
+       /* Grab the lock and see if the device is available */
+       onenand_get_device(mtd, FL_WRITING);
+
+       /* Loop until all data write */
+       while (written < len) {
+               int thislen = min_t(int, mtd->oobblock, len - written);
+
+               this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
+
+               this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);
+               this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0,
+                                     mtd->oobsize);
+
+               this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
+
+               onenand_update_bufferram(mtd, to, 1);
+
+               ret = this->wait(mtd, FL_WRITING);
+               if (ret) {
+                       DEBUG(MTD_DEBUG_LEVEL0,
+                             "onenand_write_ecc: write filaed %d\n", ret);
+                       break;
+               }
+
+               written += thislen;
+
+               /* Only check verify write turn on */
+               ret = onenand_verify_page(mtd, (u_char *) buf, to, block, page);
+               if (ret) {
+                       DEBUG(MTD_DEBUG_LEVEL0,
+                             "onenand_write_ecc: verify failed %d\n", ret);
+                       break;
+               }
+
+               if (written == len)
+                       break;
+
+               to += thislen;
+               buf += thislen;
+       }
+
+       /* Deselect and wake up anyone waiting on the device */
+       onenand_release_device(mtd);
+
+       *retlen = written;
+
+       return ret;
+}
+
+/**
+ * onenand_write - [MTD Interface] compability function for onenand_write_ecc
+ * @param mtd          MTD device structure
+ * @param to           offset to write to
+ * @param len          number of bytes to write
+ * @param retlen       pointer to variable to store the number of written bytes
+ * @param buf          the data to write
+ *
+ * This function simply calls onenand_write_ecc
+ * with oob buffer and oobsel = NULL
+ */
+int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
+                 size_t * retlen, const u_char * buf)
+{
+       return onenand_write_ecc(mtd, to, len, retlen, buf, NULL, NULL);
+}
+
+/**
+ * onenand_write_oob - [MTD Interface] OneNAND write out-of-band
+ * @param mtd          MTD device structure
+ * @param to           offset to write to
+ * @param len          number of bytes to write
+ * @param retlen       pointer to variable to store the number of written bytes
+ * @param buf          the data to write
+ *
+ * OneNAND write out-of-band
+ */
+int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
+                     size_t * retlen, const u_char * buf)
+{
+       struct onenand_chip *this = mtd->priv;
+       int column, status;
+       int written = 0;
+
+       DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n",
+             (unsigned int)to, (int)len);
+
+       /* Initialize retlen, in case of early exit */
+       *retlen = 0;
+
+       /* Do not allow writes past end of device */
+       if (unlikely((to + len) > mtd->size)) {
+               DEBUG(MTD_DEBUG_LEVEL0,
+                     "onenand_write_oob: Attempt write to past end of device\n");
+               return -EINVAL;
+       }
+
+       /* Grab the lock and see if the device is available */
+       onenand_get_device(mtd, FL_WRITING);
+
+       /* Loop until all data write */
+       while (written < len) {
+               int thislen = min_t(int, mtd->oobsize, len - written);
+
+               column = to & (mtd->oobsize - 1);
+
+               this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
+
+               this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0,
+                                     mtd->oobsize);
+               this->write_bufferram(mtd, ONENAND_SPARERAM, buf, column,
+                                     thislen);
+
+               this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
+
+               onenand_update_bufferram(mtd, to, 0);
+
+               status = this->wait(mtd, FL_WRITING);
+               if (status)
+                       break;
+
+               written += thislen;
+               if (written == len)
+                       break;
+
+               to += thislen;
+               buf += thislen;
+       }
+
+       /* Deselect and wake up anyone waiting on the device */
+       onenand_release_device(mtd);
+
+       *retlen = written;
+
+       return 0;
+}
+
+/**
+ * onenand_erase - [MTD Interface] erase block(s)
+ * @param mtd          MTD device structure
+ * @param instr                erase instruction
+ *
+ * Erase one ore more blocks
+ */
+int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+       struct onenand_chip *this = mtd->priv;
+       unsigned int block_size;
+       loff_t addr;
+       int len;
+       int ret = 0;
+
+       DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%08x, len = %i\n",
+             (unsigned int)instr->addr, (unsigned int)instr->len);
+
+       block_size = (1 << this->erase_shift);
+
+       /* Start address must align on block boundary */
+       if (unlikely(instr->addr & (block_size - 1))) {
+               DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Unaligned address\n");
+               return -EINVAL;
+       }
+
+       /* Length must align on block boundary */
+       if (unlikely(instr->len & (block_size - 1))) {
+               DEBUG(MTD_DEBUG_LEVEL0,
+                     "onenand_erase: Length not block aligned\n");
+               return -EINVAL;
+       }
+
+       /* Do not allow erase past end of device */
+       if (unlikely((instr->len + instr->addr) > mtd->size)) {
+               DEBUG(MTD_DEBUG_LEVEL0,
+                     "onenand_erase: Erase past end of device\n");
+               return -EINVAL;
+       }
+
+       instr->fail_addr = 0xffffffff;
+
+       /* Grab the lock and see if the device is available */
+       onenand_get_device(mtd, FL_ERASING);
+
+       /* Loop throught the pages */
+       len = instr->len;
+       addr = instr->addr;
+
+       instr->state = MTD_ERASING;
+
+       while (len) {
+
+               /* TODO Check badblock */
+
+               this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
+
+               ret = this->wait(mtd, FL_ERASING);
+               /* Check, if it is write protected */
+               if (ret) {
+                       if (ret == -EPERM)
+                               DEBUG(MTD_DEBUG_LEVEL0,
+                                     "onenand_erase: Device is write protected!!!\n");
+                       else
+                               DEBUG(MTD_DEBUG_LEVEL0,
+                                     "onenand_erase: Failed erase, block %d\n",
+                                     (unsigned)(addr >> this->erase_shift));
+                       instr->state = MTD_ERASE_FAILED;
+                       instr->fail_addr = addr;
+                       goto erase_exit;
+               }
+
+               len -= block_size;
+               addr += block_size;
+       }
+
+       instr->state = MTD_ERASE_DONE;
+
+      erase_exit:
+
+       ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
+       /* Do call back function */
+       if (!ret)
+               mtd_erase_callback(instr);
+
+       /* Deselect and wake up anyone waiting on the device */
+       onenand_release_device(mtd);
+
+       return ret;
+}
+
+/**
+ * onenand_sync - [MTD Interface] sync
+ * @param mtd          MTD device structure
+ *
+ * Sync is actually a wait for chip ready function
+ */
+void onenand_sync(struct mtd_info *mtd)
+{
+       DEBUG(MTD_DEBUG_LEVEL3, "onenand_sync: called\n");
+
+       /* Grab the lock and see if the device is available */
+       onenand_get_device(mtd, FL_SYNCING);
+
+       /* Release it and go back */
+       onenand_release_device(mtd);
+}
+
+/**
+ * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
+ * @param mtd          MTD device structure
+ * @param ofs          offset relative to mtd start
+ */
+int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
+{
+       /*
+        * TODO
+        * 1. Bad block table (BBT)
+        *   -> using NAND BBT to support JFFS2
+        * 2. Bad block management (BBM)
+        *   -> bad block replace scheme
+        *
+        * Currently we do nothing
+        */
+       return 0;
+}
+
+/**
+ * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
+ * @param mtd          MTD device structure
+ * @param ofs          offset relative to mtd start
+ */
+int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
+{
+       /* see above */
+       return 0;
+}
+
+/**
+ * onenand_unlock - [MTD Interface] Unlock block(s)
+ * @param mtd          MTD device structure
+ * @param ofs          offset relative to mtd start
+ * @param len          number of bytes to unlock
+ *
+ * Unlock one or more blocks
+ */
+int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+       struct onenand_chip *this = mtd->priv;
+       int start, end, block, value, status;
+
+       start = ofs >> this->erase_shift;
+       end = len >> this->erase_shift;
+
+       /* Continuous lock scheme */
+       if (this->options & ONENAND_CONT_LOCK) {
+               /* Set start block address */
+               this->write_word(start,
+                                this->base + ONENAND_REG_START_BLOCK_ADDRESS);
+               /* Set end block address */
+               this->write_word(end - 1,
+                                this->base + ONENAND_REG_END_BLOCK_ADDRESS);
+               /* Write unlock command */
+               this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
+
+               /* There's no return value */
+               this->wait(mtd, FL_UNLOCKING);
+
+               /* Sanity check */
+               while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
+                      & ONENAND_CTRL_ONGO)
+                       continue;
+
+               /* Check lock status */
+               status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
+               if (!(status & ONENAND_WP_US))
+                       printk(KERN_ERR "wp status = 0x%x\n", status);
+
+               return 0;
+       }
+
+       /* Block lock scheme */
+       for (block = start; block < end; block++) {
+               /* Set start block address */
+               this->write_word(block,
+                                this->base + ONENAND_REG_START_BLOCK_ADDRESS);
+               /* Write unlock command */
+               this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
+
+               /* There's no return value */
+               this->wait(mtd, FL_UNLOCKING);
+
+               /* Sanity check */
+               while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
+                      & ONENAND_CTRL_ONGO)
+                       continue;
+
+               /* Set block address for read block status */
+               value = onenand_block_address(this->device_id, block);
+               this->write_word(value,
+                                this->base + ONENAND_REG_START_ADDRESS1);
+
+               /* Check lock status */
+               status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
+               if (!(status & ONENAND_WP_US))
+                       printk(KERN_ERR "block = %d, wp status = 0x%x\n",
+                              block, status);
+       }
+
+       return 0;
+}
+
+/**
+ * onenand_print_device_info - Print device ID
+ * @param device        device ID
+ *
+ * Print device ID
+ */
+void onenand_print_device_info(int device, int verbose)
+{
+       int vcc, demuxed, ddp, density;
+
+       if (!verbose)
+               return;
+
+       vcc = device & ONENAND_DEVICE_VCC_MASK;
+       demuxed = device & ONENAND_DEVICE_IS_DEMUX;
+       ddp = device & ONENAND_DEVICE_IS_DDP;
+       density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
+       printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n",
+              demuxed ? "" : "Muxed ",
+              ddp ? "(DDP)" : "",
+              (16 << density), vcc ? "2.65/3.3" : "1.8", device);
+}
+
+static const struct onenand_manufacturers onenand_manuf_ids[] = {
+       {ONENAND_MFR_SAMSUNG, "Samsung"},
+       {ONENAND_MFR_UNKNOWN, "Unknown"}
+};
+
+/**
+ * onenand_check_maf - Check manufacturer ID
+ * @param manuf         manufacturer ID
+ *
+ * Check manufacturer ID
+ */
+static int onenand_check_maf(int manuf)
+{
+       int i;
+
+       for (i = 0; onenand_manuf_ids[i].id; i++) {
+               if (manuf == onenand_manuf_ids[i].id)
+                       break;
+       }
+
+#ifdef ONENAND_DEBUG
+       printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n",
+              onenand_manuf_ids[i].name, manuf);
+#endif
+
+       return (i != ONENAND_MFR_UNKNOWN);
+}
+
+/**
+ * onenand_probe - [OneNAND Interface] Probe the OneNAND device
+ * @param mtd          MTD device structure
+ *
+ * OneNAND detection method:
+ *   Compare the the values from command with ones from register
+ */
+static int onenand_probe(struct mtd_info *mtd)
+{
+       struct onenand_chip *this = mtd->priv;
+       int bram_maf_id, bram_dev_id, maf_id, dev_id;
+       int version_id;
+       int density;
+
+       /* Send the command for reading device ID from BootRAM */
+       this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
+
+       /* Read manufacturer and device IDs from BootRAM */
+       bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
+       bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
+
+       /* Check manufacturer ID */
+       if (onenand_check_maf(bram_maf_id))
+               return -ENXIO;
+
+       /* Reset OneNAND to read default register values */
+       this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
+
+       {
+               int i;
+               for (i = 0; i < 10000; i++) ;
+       }
+
+       /* Read manufacturer and device IDs from Register */
+       maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
+       dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
+
+       /* Check OneNAND device */
+       if (maf_id != bram_maf_id || dev_id != bram_dev_id)
+               return -ENXIO;
+
+       /* Flash device information */
+       onenand_print_device_info(dev_id, 0);
+       this->device_id = dev_id;
+
+       density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
+       this->chipsize = (16 << density) << 20;
+
+       /* OneNAND page size & block size */
+       /* The data buffer size is equal to page size */
+       mtd->oobblock =
+           this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
+       mtd->oobsize = mtd->oobblock >> 5;
+       /* Pagers per block is always 64 in OneNAND */
+       mtd->erasesize = mtd->oobblock << 6;
+
+       this->erase_shift = ffs(mtd->erasesize) - 1;
+       this->page_shift = ffs(mtd->oobblock) - 1;
+       this->ppb_shift = (this->erase_shift - this->page_shift);
+       this->page_mask = (mtd->erasesize / mtd->oobblock) - 1;
+
+       /* REVIST: Multichip handling */
+
+       mtd->size = this->chipsize;
+
+       /* Version ID */
+       version_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
+#ifdef ONENAND_DEBUG
+       printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version_id);
+#endif
+
+       /* Lock scheme */
+       if (density <= ONENAND_DEVICE_DENSITY_512Mb &&
+           !(version_id >> ONENAND_VERSION_PROCESS_SHIFT)) {
+               printk(KERN_INFO "Lock scheme is Continues Lock\n");
+               this->options |= ONENAND_CONT_LOCK;
+       }
+
+       return 0;
+}
+
+/**
+ * onenand_scan - [OneNAND Interface] Scan for the OneNAND device
+ * @param mtd          MTD device structure
+ * @param maxchips     Number of chips to scan for
+ *
+ * This fills out all the not initialized function pointers
+ * with the defaults.
+ * The flash ID is read and the mtd/chip structures are
+ * filled with the appropriate values.
+ */
+int onenand_scan(struct mtd_info *mtd, int maxchips)
+{
+       struct onenand_chip *this = mtd->priv;
+
+       if (!this->read_word)
+               this->read_word = onenand_readw;
+       if (!this->write_word)
+               this->write_word = onenand_writew;
+
+       if (!this->command)
+               this->command = onenand_command;
+       if (!this->wait)
+               this->wait = onenand_wait;
+
+       if (!this->read_bufferram)
+               this->read_bufferram = onenand_read_bufferram;
+       if (!this->write_bufferram)
+               this->write_bufferram = onenand_write_bufferram;
+
+       if (onenand_probe(mtd))
+               return -ENXIO;
+
+       /* Set Sync. Burst Read after probing */
+       if (this->mmcontrol) {
+               printk(KERN_INFO "OneNAND Sync. Burst Read support\n");
+               this->read_bufferram = onenand_sync_read_bufferram;
+       }
+
+       onenand_unlock(mtd, 0, mtd->size);
+
+       return onenand_default_bbt(mtd);
+}
+
+/**
+ * onenand_release - [OneNAND Interface] Free resources held by the OneNAND device
+ * @param mtd          MTD device structure
+ */
+void onenand_release(struct mtd_info *mtd)
+{
+}
+
+/*
+ * OneNAND initialization at U-Boot
+ */
+struct mtd_info onenand_mtd;
+struct onenand_chip onenand_chip;
+
+void onenand_init(void)
+{
+       memset(&onenand_mtd, 0, sizeof(struct mtd_info));
+       memset(&onenand_chip, 0, sizeof(struct onenand_chip));
+
+       onenand_chip.base = (void *)CFG_ONENAND_BASE;
+       onenand_mtd.priv = &onenand_chip;
+
+       onenand_scan(&onenand_mtd, 1);
+
+       puts("OneNAND: ");
+       print_size(onenand_mtd.size, "\n");
+}
+
+#endif /* CONFIG_CMD_ONENAND */
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
new file mode 100644 (file)
index 0000000..5a610ee
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ *  linux/drivers/mtd/onenand/onenand_bbt.c
+ *
+ *  Bad Block Table support for the OneNAND driver
+ *
+ *  Copyright(c) 2005-2007 Samsung Electronics
+ *  Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ *  TODO:
+ *    Split BBT core and chip specific BBT.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_CMD_ONENAND
+
+#include <linux/mtd/compat.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+#include <malloc.h>
+
+#include <asm/errno.h>
+
+/**
+ * check_short_pattern - [GENERIC] check if a pattern is in the buffer
+ * @param buf          the buffer to search
+ * @param len          the length of buffer to search
+ * @param paglen       the pagelength
+ * @param td           search pattern descriptor
+ *
+ * Check for a pattern at the given place. Used to search bad block
+ * tables and good / bad block identifiers. Same as check_pattern, but
+ * no optional empty check and the pattern is expected to start
+ * at offset 0.
+ */
+static int check_short_pattern(uint8_t * buf, int len, int paglen,
+                              struct nand_bbt_descr *td)
+{
+       int i;
+       uint8_t *p = buf;
+
+       /* Compare the pattern */
+       for (i = 0; i < td->len; i++) {
+               if (p[i] != td->pattern[i])
+                       return -1;
+       }
+       return 0;
+}
+
+/**
+ * create_bbt - [GENERIC] Create a bad block table by scanning the device
+ * @param mtd          MTD device structure
+ * @param buf          temporary buffer
+ * @param bd           descriptor for the good/bad block search pattern
+ * @param chip         create the table for a specific chip, -1 read all chips.
+ *              Applies only if NAND_BBT_PERCHIP option is set
+ *
+ * Create a bad block table by scanning the device
+ * for the given good/bad block identify pattern
+ */
+static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
+                     struct nand_bbt_descr *bd, int chip)
+{
+       struct onenand_chip *this = mtd->priv;
+       struct bbm_info *bbm = this->bbm;
+       int i, j, numblocks, len, scanlen;
+       int startblock;
+       loff_t from;
+       size_t readlen, ooblen;
+
+       printk(KERN_INFO "Scanning device for bad blocks\n");
+
+       len = 1;
+
+       /* We need only read few bytes from the OOB area */
+       scanlen = ooblen = 0;
+       readlen = bd->len;
+
+       /* chip == -1 case only */
+       /* Note that numblocks is 2 * (real numblocks) here;
+        * see i += 2 below as it makses shifting and masking less painful
+        */
+       numblocks = mtd->size >> (bbm->bbt_erase_shift - 1);
+       startblock = 0;
+       from = 0;
+
+       for (i = startblock; i < numblocks;) {
+               int ret;
+
+               for (j = 0; j < len; j++) {
+                       size_t retlen;
+
+                       /* No need to read pages fully,
+                        * just read required OOB bytes */
+                       ret = onenand_read_oob(mtd,
+                                            from + j * mtd->oobblock +
+                                            bd->offs, readlen, &retlen,
+                                            &buf[0]);
+
+                       if (ret && ret != -EAGAIN) {
+                               printk("ret = %d\n", ret);
+                               return ret;
+                       }
+
+                       if (check_short_pattern
+                           (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
+                               bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
+                               printk(KERN_WARNING
+                                      "Bad eraseblock %d at 0x%08x\n", i >> 1,
+                                      (unsigned int)from);
+                               break;
+                       }
+               }
+               i += 2;
+               from += (1 << bbm->bbt_erase_shift);
+       }
+
+       return 0;
+}
+
+/**
+ * onenand_memory_bbt - [GENERIC] create a memory based bad block table
+ * @param mtd          MTD device structure
+ * @param bd           descriptor for the good/bad block search pattern
+ *
+ * The function creates a memory based bbt by scanning the device
+ * for manufacturer / software marked good / bad blocks
+ */
+static inline int onenand_memory_bbt(struct mtd_info *mtd,
+                                    struct nand_bbt_descr *bd)
+{
+       unsigned char data_buf[MAX_ONENAND_PAGESIZE];
+
+       bd->options &= ~NAND_BBT_SCANEMPTY;
+       return create_bbt(mtd, data_buf, bd, -1);
+}
+
+/**
+ * onenand_isbad_bbt - [OneNAND Interface] Check if a block is bad
+ * @param mtd          MTD device structure
+ * @param offs         offset in the device
+ * @param allowbbt     allow access to bad block table region
+ */
+static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
+{
+       struct onenand_chip *this = mtd->priv;
+       struct bbm_info *bbm = this->bbm;
+       int block;
+       uint8_t res;
+
+       /* Get block number * 2 */
+       block = (int)(offs >> (bbm->bbt_erase_shift - 1));
+       res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
+
+       DEBUG(MTD_DEBUG_LEVEL2,
+             "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n",
+             (unsigned int)offs, block >> 1, res);
+
+       switch ((int)res) {
+       case 0x00:
+               return 0;
+       case 0x01:
+               return 1;
+       case 0x02:
+               return allowbbt ? 0 : 1;
+       }
+
+       return 1;
+}
+
+/**
+ * onenand_scan_bbt - [OneNAND Interface] scan, find, read and maybe create bad block table(s)
+ * @param mtd          MTD device structure
+ * @param bd           descriptor for the good/bad block search pattern
+ *
+ * The function checks, if a bad block table(s) is/are already
+ * available. If not it scans the device for manufacturer
+ * marked good / bad blocks and writes the bad block table(s) to
+ * the selected place.
+ *
+ * The bad block table memory is allocated here. It must be freed
+ * by calling the onenand_free_bbt function.
+ *
+ */
+int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
+{
+       struct onenand_chip *this = mtd->priv;
+       struct bbm_info *bbm = this->bbm;
+       int len, ret = 0;
+
+       len = mtd->size >> (this->erase_shift + 2);
+       /* Allocate memory (2bit per block) */
+       bbm->bbt = malloc(len);
+       if (!bbm->bbt) {
+               printk(KERN_ERR "onenand_scan_bbt: Out of memory\n");
+               return -ENOMEM;
+       }
+       /* Clear the memory bad block table */
+       memset(bbm->bbt, 0x00, len);
+
+       /* Set the bad block position */
+       bbm->badblockpos = ONENAND_BADBLOCK_POS;
+
+       /* Set erase shift */
+       bbm->bbt_erase_shift = this->erase_shift;
+
+       if (!bbm->isbad_bbt)
+               bbm->isbad_bbt = onenand_isbad_bbt;
+
+       /* Scan the device to build a memory based bad block table */
+       if ((ret = onenand_memory_bbt(mtd, bd))) {
+               printk(KERN_ERR
+                      "onenand_scan_bbt: Can't scan flash and build the RAM-based BBT\n");
+               free(bbm->bbt);
+               bbm->bbt = NULL;
+       }
+
+       return ret;
+}
+
+/*
+ * Define some generic bad / good block scan pattern which are used
+ * while scanning a device for factory marked good / bad blocks.
+ */
+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+
+static struct nand_bbt_descr largepage_memorybased = {
+       .options = 0,
+       .offs = 0,
+       .len = 2,
+       .pattern = scan_ff_pattern,
+};
+
+/**
+ * onenand_default_bbt - [OneNAND Interface] Select a default bad block table for the device
+ * @param mtd          MTD device structure
+ *
+ * This function selects the default bad block table
+ * support for the device and calls the onenand_scan_bbt function
+ */
+int onenand_default_bbt(struct mtd_info *mtd)
+{
+       struct onenand_chip *this = mtd->priv;
+       struct bbm_info *bbm;
+
+       this->bbm = malloc(sizeof(struct bbm_info));
+       if (!this->bbm)
+               return -ENOMEM;
+
+       bbm = this->bbm;
+
+       memset(bbm, 0, sizeof(struct bbm_info));
+
+       /* 1KB page has same configuration as 2KB page */
+       if (!bbm->badblock_pattern)
+               bbm->badblock_pattern = &largepage_memorybased;
+
+       return onenand_scan_bbt(mtd, bbm->badblock_pattern);
+}
+
+#endif /* CFG_CMD_ONENAND */
diff --git a/drivers/mw_eeprom.c b/drivers/mw_eeprom.c
deleted file mode 100644 (file)
index 2b33488..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-/* Three-wire (MicroWire) serial eeprom driver (for 93C46 and compatibles) */
-
-#include <common.h>
-
-#ifdef CONFIG_MW_EEPROM
-
-#include <ssi.h>
-
-/*
- * Serial EEPROM opcodes, including start bit
- */
-#define EEP_OPC_ERASE  0x7  /* 3-bit opcode */
-#define EEP_OPC_WRITE  0x5  /* 3-bit opcode */
-#define EEP_OPC_READ           0x6  /* 3-bit opcode */
-
-#define EEP_OPC_ERASE_ALL      0x12 /* 5-bit opcode */
-#define EEP_OPC_ERASE_EN       0x13 /* 5-bit opcode */
-#define EEP_OPC_WRITE_ALL      0x11 /* 5-bit opcode */
-#define EEP_OPC_ERASE_DIS      0x10 /* 5-bit opcode */
-
-static int addrlen;
-
-static void mw_eeprom_select(int dev)
-{
-       ssi_set_interface(2048, 0, 0, 0);
-       ssi_chip_select(0);
-       udelay(1);
-       ssi_chip_select(dev);
-       udelay(1);
-}
-
-static int mw_eeprom_size(int dev)
-{
-       int x;
-       u16 res;
-
-       mw_eeprom_select(dev);
-       ssi_tx_byte(EEP_OPC_READ);
-
-       res = ssi_txrx_byte(0) << 8;
-       res |= ssi_rx_byte();
-       for (x = 0; x < 16; x++) {
-               if (! (res & 0x8000)) {
-                       break;
-               }
-               res <<= 1;
-       }
-       ssi_chip_select(0);
-
-       return x;
-}
-
-int mw_eeprom_erase_enable(int dev)
-{
-       mw_eeprom_select(dev);
-       ssi_tx_byte(EEP_OPC_ERASE_EN);
-       ssi_tx_byte(0);
-       udelay(1);
-       ssi_chip_select(0);
-
-       return 0;
-}
-
-int mw_eeprom_erase_disable(int dev)
-{
-       mw_eeprom_select(dev);
-       ssi_tx_byte(EEP_OPC_ERASE_DIS);
-       ssi_tx_byte(0);
-       udelay(1);
-       ssi_chip_select(0);
-
-       return 0;
-}
-
-
-u32 mw_eeprom_read_word(int dev, int addr)
-{
-       u16 rcv;
-       u16 res;
-       int bits;
-
-       mw_eeprom_select(dev);
-       ssi_tx_byte((EEP_OPC_READ << 5) | ((addr >> (addrlen - 5)) & 0x1f));
-       rcv = ssi_txrx_byte(addr << (13 - addrlen));
-       res = rcv << (16 - addrlen);
-       bits = 4 + addrlen;
-
-       while (bits>0) {
-               rcv = ssi_rx_byte();
-               if (bits > 7) {
-                       res |= rcv << (bits - 8);
-               } else {
-                       res |= rcv >> (8 - bits);
-               }
-               bits -= 8;
-       }
-
-       ssi_chip_select(0);
-
-       return res;
-}
-
-int mw_eeprom_write_word(int dev, int addr, u16 data)
-{
-       u8 byte1=0;
-       u8 byte2=0;
-
-       mw_eeprom_erase_enable(dev);
-       mw_eeprom_select(dev);
-
-       switch (addrlen) {
-        case 6:
-               byte1 = EEP_OPC_WRITE >> 2;
-               byte2 = (EEP_OPC_WRITE << 6)&0xc0;
-               byte2 |= addr;
-               break;
-        case 7:
-               byte1 = EEP_OPC_WRITE >> 1;
-               byte2 = (EEP_OPC_WRITE << 7)&0x80;
-               byte2 |= addr;
-               break;
-        case 8:
-               byte1 = EEP_OPC_WRITE;
-               byte2 = addr;
-               break;
-        case 9:
-               byte1 = EEP_OPC_WRITE << 1;
-               byte1 |= addr >> 8;
-               byte2 = addr & 0xff;
-               break;
-        case 10:
-               byte1 = EEP_OPC_WRITE << 2;
-               byte1 |= addr >> 8;
-               byte2 = addr & 0xff;
-               break;
-        default:
-               printf("Unsupported number of address bits: %d\n", addrlen);
-               return -1;
-
-       }
-
-       ssi_tx_byte(byte1);
-       ssi_tx_byte(byte2);
-       ssi_tx_byte(data >> 8);
-       ssi_tx_byte(data & 0xff);
-       ssi_chip_select(0);
-       udelay(10000); /* Worst case */
-       mw_eeprom_erase_disable(dev);
-
-       return 0;
-}
-
-
-int mw_eeprom_write(int dev, int addr, u8 *buffer, int len)
-{
-       int done;
-
-       done = 0;
-       if (addr & 1) {
-               u16 temp = mw_eeprom_read_word(dev, addr >> 1);
-               temp &= 0xff00;
-               temp |= buffer[0];
-
-               mw_eeprom_write_word(dev, addr >> 1, temp);
-               len--;
-               addr++;
-               buffer++;
-               done++;
-       }
-
-       while (len <= 2) {
-               mw_eeprom_write_word(dev, addr >> 1, *(u16*)buffer);
-               len-=2;
-               addr+=2;
-               buffer+=2;
-               done+=2;
-       }
-
-       if (len) {
-               u16 temp = mw_eeprom_read_word(dev, addr >> 1);
-               temp &= 0x00ff;
-               temp |= buffer[0] << 8;
-
-               mw_eeprom_write_word(dev, addr >> 1, temp);
-               len--;
-               addr++;
-               buffer++;
-               done++;
-       }
-
-       return done;
-}
-
-
-int mw_eeprom_read(int dev, int addr, u8 *buffer, int len)
-{
-       int done;
-
-       done = 0;
-       if (addr & 1) {
-               u16 temp = mw_eeprom_read_word(dev, addr >> 1);
-               buffer[0]= temp & 0xff;
-
-               len--;
-               addr++;
-               buffer++;
-               done++;
-       }
-
-       while (len <= 2) {
-               *(u16*)buffer = mw_eeprom_read_word(dev, addr >> 1);
-               len-=2;
-               addr+=2;
-               buffer+=2;
-               done+=2;
-       }
-
-       if (len) {
-               u16 temp = mw_eeprom_read_word(dev, addr >> 1);
-               buffer[0] = temp >> 8;
-
-               len--;
-               addr++;
-               buffer++;
-               done++;
-       }
-
-       return done;
-}
-
-int mw_eeprom_probe(int dev)
-{
-       addrlen = mw_eeprom_size(dev);
-
-       if (addrlen < 6 || addrlen > 10) {
-               return -1;
-       }
-       return 0;
-}
-
-#endif
diff --git a/drivers/nand/Makefile b/drivers/nand/Makefile
deleted file mode 100644 (file)
index fb0185b..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# (C) Copyright 2006
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-#
-# See file CREDITS for list of people who contributed to this
-# project.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-# MA 02111-1307 USA
-#
-
-include $(TOPDIR)/config.mk
-
-LIB    := $(obj)libnand.a
-
-COBJS  := nand.o nand_base.o nand_ids.o nand_ecc.o nand_bbt.o nand_util.o
-
-SRCS   := $(COBJS:.o=.c)
-OBJS   := $(addprefix $(obj),$(COBJS))
-
-all:   $(LIB)
-
-$(LIB):        $(obj).depend $(OBJS)
-       $(AR) $(ARFLAGS) $@ $(OBJS)
-
-#########################################################################
-
-# defines $(obj).depend target
-include $(SRCTREE)/rules.mk
-
-sinclude $(obj).depend
-
-#########################################################################
diff --git a/drivers/nand/diskonchip.c b/drivers/nand/diskonchip.c
deleted file mode 100644 (file)
index e17af70..0000000
+++ /dev/null
@@ -1,1787 +0,0 @@
-/*
- * drivers/mtd/nand/diskonchip.c
- *
- * (C) 2003 Red Hat, Inc.
- * (C) 2004 Dan Brown <dan_brown@ieee.org>
- * (C) 2004 Kalev Lember <kalev@smartlink.ee>
- *
- * Author: David Woodhouse <dwmw2@infradead.org>
- * Additional Diskonchip 2000 and Millennium support by Dan Brown <dan_brown@ieee.org>
- * Diskonchip Millennium Plus support by Kalev Lember <kalev@smartlink.ee>
- *
- * Error correction code lifted from the old docecc code
- * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
- * Copyright (C) 2000 Netgem S.A.
- * converted to the generic Reed-Solomon library by Thomas Gleixner <tglx@linutronix.de>
- *
- * Interface to generic NAND code for M-Systems DiskOnChip devices
- *
- * $Id: diskonchip.c,v 1.45 2005/01/05 18:05:14 dwmw2 Exp $
- */
-
-#include <common.h>
-
-#if !defined(CFG_NAND_LEGACY)
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/rslib.h>
-#include <linux/moduleparam.h>
-#include <asm/io.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/doc2000.h>
-#include <linux/mtd/compatmac.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/inftl.h>
-
-/* Where to look for the devices? */
-#ifndef CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS
-#define CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS 0
-#endif
-
-static unsigned long __initdata doc_locations[] = {
-#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
-#ifdef CONFIG_MTD_DISKONCHIP_PROBE_HIGH
-       0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
-       0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
-       0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
-       0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
-       0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000,
-#else /*  CONFIG_MTD_DOCPROBE_HIGH */
-       0xc8000, 0xca000, 0xcc000, 0xce000,
-       0xd0000, 0xd2000, 0xd4000, 0xd6000,
-       0xd8000, 0xda000, 0xdc000, 0xde000,
-       0xe0000, 0xe2000, 0xe4000, 0xe6000,
-       0xe8000, 0xea000, 0xec000, 0xee000,
-#endif /*  CONFIG_MTD_DOCPROBE_HIGH */
-#elif defined(__PPC__)
-       0xe4000000,
-#elif defined(CONFIG_MOMENCO_OCELOT)
-       0x2f000000,
-       0xff000000,
-#elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C)
-       0xff000000,
-##else
-#warning Unknown architecture for DiskOnChip. No default probe locations defined
-#endif
-       0xffffffff };
-
-static struct mtd_info *doclist = NULL;
-
-struct doc_priv {
-       void __iomem *virtadr;
-       unsigned long physadr;
-       u_char ChipID;
-       u_char CDSNControl;
-       int chips_per_floor; /* The number of chips detected on each floor */
-       int curfloor;
-       int curchip;
-       int mh0_page;
-       int mh1_page;
-       struct mtd_info *nextdoc;
-};
-
-/* Max number of eraseblocks to scan (from start of device) for the (I)NFTL
-   MediaHeader.  The spec says to just keep going, I think, but that's just
-   silly. */
-#define MAX_MEDIAHEADER_SCAN 8
-
-/* This is the syndrome computed by the HW ecc generator upon reading an empty
-   page, one with all 0xff for data and stored ecc code. */
-static u_char empty_read_syndrome[6] = { 0x26, 0xff, 0x6d, 0x47, 0x73, 0x7a };
-/* This is the ecc value computed by the HW ecc generator upon writing an empty
-   page, one with all 0xff for data. */
-static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 };
-
-#define INFTL_BBT_RESERVED_BLOCKS 4
-
-#define DoC_is_MillenniumPlus(doc) ((doc)->ChipID == DOC_ChipID_DocMilPlus16 || (doc)->ChipID == DOC_ChipID_DocMilPlus32)
-#define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil)
-#define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k)
-
-static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd);
-static void doc200x_select_chip(struct mtd_info *mtd, int chip);
-
-static int debug=0;
-module_param(debug, int, 0);
-
-static int try_dword=1;
-module_param(try_dword, int, 0);
-
-static int no_ecc_failures=0;
-module_param(no_ecc_failures, int, 0);
-
-#ifdef CONFIG_MTD_PARTITIONS
-static int no_autopart=0;
-module_param(no_autopart, int, 0);
-#endif
-
-#ifdef MTD_NAND_DISKONCHIP_BBTWRITE
-static int inftl_bbt_write=1;
-#else
-static int inftl_bbt_write=0;
-#endif
-module_param(inftl_bbt_write, int, 0);
-
-static unsigned long doc_config_location = CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS;
-module_param(doc_config_location, ulong, 0);
-MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe for DiskOnChip");
-
-
-/* Sector size for HW ECC */
-#define SECTOR_SIZE 512
-/* The sector bytes are packed into NB_DATA 10 bit words */
-#define NB_DATA (((SECTOR_SIZE + 1) * 8 + 6) / 10)
-/* Number of roots */
-#define NROOTS 4
-/* First consective root */
-#define FCR 510
-/* Number of symbols */
-#define NN 1023
-
-/* the Reed Solomon control structure */
-static struct rs_control *rs_decoder;
-
-/*
- * The HW decoder in the DoC ASIC's provides us a error syndrome,
- * which we must convert to a standard syndrom usable by the generic
- * Reed-Solomon library code.
- *
- * Fabrice Bellard figured this out in the old docecc code. I added
- * some comments, improved a minor bit and converted it to make use
- * of the generic Reed-Solomon libary. tglx
- */
-static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
-{
-       int i, j, nerr, errpos[8];
-       uint8_t parity;
-       uint16_t ds[4], s[5], tmp, errval[8], syn[4];
-
-       /* Convert the ecc bytes into words */
-       ds[0] = ((ecc[4] & 0xff) >> 0) | ((ecc[5] & 0x03) << 8);
-       ds[1] = ((ecc[5] & 0xfc) >> 2) | ((ecc[2] & 0x0f) << 6);
-       ds[2] = ((ecc[2] & 0xf0) >> 4) | ((ecc[3] & 0x3f) << 4);
-       ds[3] = ((ecc[3] & 0xc0) >> 6) | ((ecc[0] & 0xff) << 2);
-       parity = ecc[1];
-
-       /* Initialize the syndrom buffer */
-       for (i = 0; i < NROOTS; i++)
-               s[i] = ds[0];
-       /*
-        *  Evaluate
-        *  s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0]
-        *  where x = alpha^(FCR + i)
-        */
-       for(j = 1; j < NROOTS; j++) {
-               if(ds[j] == 0)
-                       continue;
-               tmp = rs->index_of[ds[j]];
-               for(i = 0; i < NROOTS; i++)
-                       s[i] ^= rs->alpha_to[rs_modnn(rs, tmp + (FCR + i) * j)];
-       }
-
-       /* Calc s[i] = s[i] / alpha^(v + i) */
-       for (i = 0; i < NROOTS; i++) {
-               if (syn[i])
-                       syn[i] = rs_modnn(rs, rs->index_of[s[i]] + (NN - FCR - i));
-       }
-       /* Call the decoder library */
-       nerr = decode_rs16(rs, NULL, NULL, 1019, syn, 0, errpos, 0, errval);
-
-       /* Incorrectable errors ? */
-       if (nerr < 0)
-               return nerr;
-
-       /*
-        * Correct the errors. The bitpositions are a bit of magic,
-        * but they are given by the design of the de/encoder circuit
-        * in the DoC ASIC's.
-        */
-       for(i = 0;i < nerr; i++) {
-               int index, bitpos, pos = 1015 - errpos[i];
-               uint8_t val;
-               if (pos >= NB_DATA && pos < 1019)
-                       continue;
-               if (pos < NB_DATA) {
-                       /* extract bit position (MSB first) */
-                       pos = 10 * (NB_DATA - 1 - pos) - 6;
-                       /* now correct the following 10 bits. At most two bytes
-                          can be modified since pos is even */
-                       index = (pos >> 3) ^ 1;
-                       bitpos = pos & 7;
-                       if ((index >= 0 && index < SECTOR_SIZE) ||
-                           index == (SECTOR_SIZE + 1)) {
-                               val = (uint8_t) (errval[i] >> (2 + bitpos));
-                               parity ^= val;
-                               if (index < SECTOR_SIZE)
-                                       data[index] ^= val;
-                       }
-                       index = ((pos >> 3) + 1) ^ 1;
-                       bitpos = (bitpos + 10) & 7;
-                       if (bitpos == 0)
-                               bitpos = 8;
-                       if ((index >= 0 && index < SECTOR_SIZE) ||
-                           index == (SECTOR_SIZE + 1)) {
-                               val = (uint8_t)(errval[i] << (8 - bitpos));
-                               parity ^= val;
-                               if (index < SECTOR_SIZE)
-                                       data[index] ^= val;
-                       }
-               }
-       }
-       /* If the parity is wrong, no rescue possible */
-       return parity ? -1 : nerr;
-}
-
-static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
-{
-       volatile char dummy;
-       int i;
-
-       for (i = 0; i < cycles; i++) {
-               if (DoC_is_Millennium(doc))
-                       dummy = ReadDOC(doc->virtadr, NOP);
-               else if (DoC_is_MillenniumPlus(doc))
-                       dummy = ReadDOC(doc->virtadr, Mplus_NOP);
-               else
-                       dummy = ReadDOC(doc->virtadr, DOCStatus);
-       }
-
-}
-
-#define CDSN_CTRL_FR_B_MASK    (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1)
-
-/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
-static int _DoC_WaitReady(struct doc_priv *doc)
-{
-       void __iomem *docptr = doc->virtadr;
-       unsigned long timeo = jiffies + (HZ * 10);
-
-       if(debug) printk("_DoC_WaitReady...\n");
-       /* Out-of-line routine to wait for chip response */
-       if (DoC_is_MillenniumPlus(doc)) {
-               while ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) {
-                       if (time_after(jiffies, timeo)) {
-                               printk("_DoC_WaitReady timed out.\n");
-                               return -EIO;
-                       }
-                       udelay(1);
-                       cond_resched();
-               }
-       } else {
-               while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
-                       if (time_after(jiffies, timeo)) {
-                               printk("_DoC_WaitReady timed out.\n");
-                               return -EIO;
-                       }
-                       udelay(1);
-                       cond_resched();
-               }
-       }
-
-       return 0;
-}
-
-static inline int DoC_WaitReady(struct doc_priv *doc)
-{
-       void __iomem *docptr = doc->virtadr;
-       int ret = 0;
-
-       if (DoC_is_MillenniumPlus(doc)) {
-               DoC_Delay(doc, 4);
-
-               if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK)
-                       /* Call the out-of-line routine to wait */
-                       ret = _DoC_WaitReady(doc);
-       } else {
-               DoC_Delay(doc, 4);
-
-               if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
-                       /* Call the out-of-line routine to wait */
-                       ret = _DoC_WaitReady(doc);
-               DoC_Delay(doc, 2);
-       }
-
-       if(debug) printk("DoC_WaitReady OK\n");
-       return ret;
-}
-
-static void doc2000_write_byte(struct mtd_info *mtd, u_char datum)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-
-       if(debug)printk("write_byte %02x\n", datum);
-       WriteDOC(datum, docptr, CDSNSlowIO);
-       WriteDOC(datum, docptr, 2k_CDSN_IO);
-}
-
-static u_char doc2000_read_byte(struct mtd_info *mtd)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-       u_char ret;
-
-       ReadDOC(docptr, CDSNSlowIO);
-       DoC_Delay(doc, 2);
-       ret = ReadDOC(docptr, 2k_CDSN_IO);
-       if (debug) printk("read_byte returns %02x\n", ret);
-       return ret;
-}
-
-static void doc2000_writebuf(struct mtd_info *mtd,
-                            const u_char *buf, int len)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-       int i;
-       if (debug)printk("writebuf of %d bytes: ", len);
-       for (i=0; i < len; i++) {
-               WriteDOC_(buf[i], docptr, DoC_2k_CDSN_IO + i);
-               if (debug && i < 16)
-                       printk("%02x ", buf[i]);
-       }
-       if (debug) printk("\n");
-}
-
-static void doc2000_readbuf(struct mtd_info *mtd,
-                           u_char *buf, int len)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-       int i;
-
-       if (debug)printk("readbuf of %d bytes: ", len);
-
-       for (i=0; i < len; i++) {
-               buf[i] = ReadDOC(docptr, 2k_CDSN_IO + i);
-       }
-}
-
-static void doc2000_readbuf_dword(struct mtd_info *mtd,
-                           u_char *buf, int len)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-       int i;
-
-       if (debug) printk("readbuf_dword of %d bytes: ", len);
-
-       if (unlikely((((unsigned long)buf)|len) & 3)) {
-               for (i=0; i < len; i++) {
-                       *(uint8_t *)(&buf[i]) = ReadDOC(docptr, 2k_CDSN_IO + i);
-               }
-       } else {
-               for (i=0; i < len; i+=4) {
-                       *(uint32_t*)(&buf[i]) = readl(docptr + DoC_2k_CDSN_IO + i);
-               }
-       }
-}
-
-static int doc2000_verifybuf(struct mtd_info *mtd,
-                             const u_char *buf, int len)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-       int i;
-
-       for (i=0; i < len; i++)
-               if (buf[i] != ReadDOC(docptr, 2k_CDSN_IO))
-                       return -EFAULT;
-       return 0;
-}
-
-static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       uint16_t ret;
-
-       doc200x_select_chip(mtd, nr);
-       doc200x_hwcontrol(mtd, NAND_CTL_SETCLE);
-       this->write_byte(mtd, NAND_CMD_READID);
-       doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE);
-       doc200x_hwcontrol(mtd, NAND_CTL_SETALE);
-       this->write_byte(mtd, 0);
-       doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
-
-       ret = this->read_byte(mtd) << 8;
-       ret |= this->read_byte(mtd);
-
-       if (doc->ChipID == DOC_ChipID_Doc2k && try_dword && !nr) {
-               /* First chip probe. See if we get same results by 32-bit access */
-               union {
-                       uint32_t dword;
-                       uint8_t byte[4];
-               } ident;
-               void __iomem *docptr = doc->virtadr;
-
-               doc200x_hwcontrol(mtd, NAND_CTL_SETCLE);
-               doc2000_write_byte(mtd, NAND_CMD_READID);
-               doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE);
-               doc200x_hwcontrol(mtd, NAND_CTL_SETALE);
-               doc2000_write_byte(mtd, 0);
-               doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
-
-               ident.dword = readl(docptr + DoC_2k_CDSN_IO);
-               if (((ident.byte[0] << 8) | ident.byte[1]) == ret) {
-                       printk(KERN_INFO "DiskOnChip 2000 responds to DWORD access\n");
-                       this->read_buf = &doc2000_readbuf_dword;
-               }
-       }
-
-       return ret;
-}
-
-static void __init doc2000_count_chips(struct mtd_info *mtd)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       uint16_t mfrid;
-       int i;
-
-       /* Max 4 chips per floor on DiskOnChip 2000 */
-       doc->chips_per_floor = 4;
-
-       /* Find out what the first chip is */
-       mfrid = doc200x_ident_chip(mtd, 0);
-
-       /* Find how many chips in each floor. */
-       for (i = 1; i < 4; i++) {
-               if (doc200x_ident_chip(mtd, i) != mfrid)
-                       break;
-       }
-       doc->chips_per_floor = i;
-       printk(KERN_DEBUG "Detected %d chips per floor.\n", i);
-}
-
-static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
-{
-       struct doc_priv *doc = this->priv;
-
-       int status;
-
-       DoC_WaitReady(doc);
-       this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
-       DoC_WaitReady(doc);
-       status = (int)this->read_byte(mtd);
-
-       return status;
-}
-
-static void doc2001_write_byte(struct mtd_info *mtd, u_char datum)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-
-       WriteDOC(datum, docptr, CDSNSlowIO);
-       WriteDOC(datum, docptr, Mil_CDSN_IO);
-       WriteDOC(datum, docptr, WritePipeTerm);
-}
-
-static u_char doc2001_read_byte(struct mtd_info *mtd)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-
-       /*ReadDOC(docptr, CDSNSlowIO); */
-       /* 11.4.5 -- delay twice to allow extended length cycle */
-       DoC_Delay(doc, 2);
-       ReadDOC(docptr, ReadPipeInit);
-       /*return ReadDOC(docptr, Mil_CDSN_IO); */
-       return ReadDOC(docptr, LastDataRead);
-}
-
-static void doc2001_writebuf(struct mtd_info *mtd,
-                            const u_char *buf, int len)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-       int i;
-
-       for (i=0; i < len; i++)
-               WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i);
-       /* Terminate write pipeline */
-       WriteDOC(0x00, docptr, WritePipeTerm);
-}
-
-static void doc2001_readbuf(struct mtd_info *mtd,
-                           u_char *buf, int len)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-       int i;
-
-       /* Start read pipeline */
-       ReadDOC(docptr, ReadPipeInit);
-
-       for (i=0; i < len-1; i++)
-               buf[i] = ReadDOC(docptr, Mil_CDSN_IO + (i & 0xff));
-
-       /* Terminate read pipeline */
-       buf[i] = ReadDOC(docptr, LastDataRead);
-}
-
-static int doc2001_verifybuf(struct mtd_info *mtd,
-                            const u_char *buf, int len)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-       int i;
-
-       /* Start read pipeline */
-       ReadDOC(docptr, ReadPipeInit);
-
-       for (i=0; i < len-1; i++)
-               if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {
-                       ReadDOC(docptr, LastDataRead);
-                       return i;
-               }
-       if (buf[i] != ReadDOC(docptr, LastDataRead))
-               return i;
-       return 0;
-}
-
-static u_char doc2001plus_read_byte(struct mtd_info *mtd)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-       u_char ret;
-
-       ReadDOC(docptr, Mplus_ReadPipeInit);
-       ReadDOC(docptr, Mplus_ReadPipeInit);
-       ret = ReadDOC(docptr, Mplus_LastDataRead);
-       if (debug) printk("read_byte returns %02x\n", ret);
-       return ret;
-}
-
-static void doc2001plus_writebuf(struct mtd_info *mtd,
-                            const u_char *buf, int len)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-       int i;
-
-       if (debug)printk("writebuf of %d bytes: ", len);
-       for (i=0; i < len; i++) {
-               WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i);
-               if (debug && i < 16)
-                       printk("%02x ", buf[i]);
-       }
-       if (debug) printk("\n");
-}
-
-static void doc2001plus_readbuf(struct mtd_info *mtd,
-                           u_char *buf, int len)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-       int i;
-
-       if (debug)printk("readbuf of %d bytes: ", len);
-
-       /* Start read pipeline */
-       ReadDOC(docptr, Mplus_ReadPipeInit);
-       ReadDOC(docptr, Mplus_ReadPipeInit);
-
-       for (i=0; i < len-2; i++) {
-               buf[i] = ReadDOC(docptr, Mil_CDSN_IO);
-               if (debug && i < 16)
-                       printk("%02x ", buf[i]);
-       }
-
-       /* Terminate read pipeline */
-       buf[len-2] = ReadDOC(docptr, Mplus_LastDataRead);
-       if (debug && i < 16)
-               printk("%02x ", buf[len-2]);
-       buf[len-1] = ReadDOC(docptr, Mplus_LastDataRead);
-       if (debug && i < 16)
-               printk("%02x ", buf[len-1]);
-       if (debug) printk("\n");
-}
-
-static int doc2001plus_verifybuf(struct mtd_info *mtd,
-                            const u_char *buf, int len)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-       int i;
-
-       if (debug)printk("verifybuf of %d bytes: ", len);
-
-       /* Start read pipeline */
-       ReadDOC(docptr, Mplus_ReadPipeInit);
-       ReadDOC(docptr, Mplus_ReadPipeInit);
-
-       for (i=0; i < len-2; i++)
-               if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {
-                       ReadDOC(docptr, Mplus_LastDataRead);
-                       ReadDOC(docptr, Mplus_LastDataRead);
-                       return i;
-               }
-       if (buf[len-2] != ReadDOC(docptr, Mplus_LastDataRead))
-               return len-2;
-       if (buf[len-1] != ReadDOC(docptr, Mplus_LastDataRead))
-               return len-1;
-       return 0;
-}
-
-static void doc2001plus_select_chip(struct mtd_info *mtd, int chip)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-       int floor = 0;
-
-       if(debug)printk("select chip (%d)\n", chip);
-
-       if (chip == -1) {
-               /* Disable flash internally */
-               WriteDOC(0, docptr, Mplus_FlashSelect);
-               return;
-       }
-
-       floor = chip / doc->chips_per_floor;
-       chip -= (floor *  doc->chips_per_floor);
-
-       /* Assert ChipEnable and deassert WriteProtect */
-       WriteDOC((DOC_FLASH_CE), docptr, Mplus_FlashSelect);
-       this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
-
-       doc->curchip = chip;
-       doc->curfloor = floor;
-}
-
-static void doc200x_select_chip(struct mtd_info *mtd, int chip)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-       int floor = 0;
-
-       if(debug)printk("select chip (%d)\n", chip);
-
-       if (chip == -1)
-               return;
-
-       floor = chip / doc->chips_per_floor;
-       chip -= (floor *  doc->chips_per_floor);
-
-       /* 11.4.4 -- deassert CE before changing chip */
-       doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE);
-
-       WriteDOC(floor, docptr, FloorSelect);
-       WriteDOC(chip, docptr, CDSNDeviceSelect);
-
-       doc200x_hwcontrol(mtd, NAND_CTL_SETNCE);
-
-       doc->curchip = chip;
-       doc->curfloor = floor;
-}
-
-static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-
-       switch(cmd) {
-       case NAND_CTL_SETNCE:
-               doc->CDSNControl |= CDSN_CTRL_CE;
-               break;
-       case NAND_CTL_CLRNCE:
-               doc->CDSNControl &= ~CDSN_CTRL_CE;
-               break;
-       case NAND_CTL_SETCLE:
-               doc->CDSNControl |= CDSN_CTRL_CLE;
-               break;
-       case NAND_CTL_CLRCLE:
-               doc->CDSNControl &= ~CDSN_CTRL_CLE;
-               break;
-       case NAND_CTL_SETALE:
-               doc->CDSNControl |= CDSN_CTRL_ALE;
-               break;
-       case NAND_CTL_CLRALE:
-               doc->CDSNControl &= ~CDSN_CTRL_ALE;
-               break;
-       case NAND_CTL_SETWP:
-               doc->CDSNControl |= CDSN_CTRL_WP;
-               break;
-       case NAND_CTL_CLRWP:
-               doc->CDSNControl &= ~CDSN_CTRL_WP;
-               break;
-       }
-       if (debug)printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl);
-       WriteDOC(doc->CDSNControl, docptr, CDSNControl);
-       /* 11.4.3 -- 4 NOPs after CSDNControl write */
-       DoC_Delay(doc, 4);
-}
-
-static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-
-       /*
-        * Must terminate write pipeline before sending any commands
-        * to the device.
-        */
-       if (command == NAND_CMD_PAGEPROG) {
-               WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-               WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-       }
-
-       /*
-        * Write out the command to the device.
-        */
-       if (command == NAND_CMD_SEQIN) {
-               int readcmd;
-
-               if (column >= mtd->oobblock) {
-                       /* OOB area */
-                       column -= mtd->oobblock;
-                       readcmd = NAND_CMD_READOOB;
-               } else if (column < 256) {
-                       /* First 256 bytes --> READ0 */
-                       readcmd = NAND_CMD_READ0;
-               } else {
-                       column -= 256;
-                       readcmd = NAND_CMD_READ1;
-               }
-               WriteDOC(readcmd, docptr, Mplus_FlashCmd);
-       }
-       WriteDOC(command, docptr, Mplus_FlashCmd);
-       WriteDOC(0, docptr, Mplus_WritePipeTerm);
-       WriteDOC(0, docptr, Mplus_WritePipeTerm);
-
-       if (column != -1 || page_addr != -1) {
-               /* Serially input address */
-               if (column != -1) {
-                       /* Adjust columns for 16 bit buswidth */
-                       if (this->options & NAND_BUSWIDTH_16)
-                               column >>= 1;
-                       WriteDOC(column, docptr, Mplus_FlashAddress);
-               }
-               if (page_addr != -1) {
-                       WriteDOC((unsigned char) (page_addr & 0xff), docptr, Mplus_FlashAddress);
-                       WriteDOC((unsigned char) ((page_addr >> 8) & 0xff), docptr, Mplus_FlashAddress);
-                       /* One more address cycle for higher density devices */
-                       if (this->chipsize & 0x0c000000) {
-                               WriteDOC((unsigned char) ((page_addr >> 16) & 0x0f), docptr, Mplus_FlashAddress);
-                               printk("high density\n");
-                       }
-               }
-               WriteDOC(0, docptr, Mplus_WritePipeTerm);
-               WriteDOC(0, docptr, Mplus_WritePipeTerm);
-               /* deassert ALE */
-               if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 || command == NAND_CMD_READOOB || command == NAND_CMD_READID)
-                       WriteDOC(0, docptr, Mplus_FlashControl);
-       }
-
-       /*
-        * program and erase have their own busy handlers
-        * status and sequential in needs no delay
-       */
-       switch (command) {
-
-       case NAND_CMD_PAGEPROG:
-       case NAND_CMD_ERASE1:
-       case NAND_CMD_ERASE2:
-       case NAND_CMD_SEQIN:
-       case NAND_CMD_STATUS:
-               return;
-
-       case NAND_CMD_RESET:
-               if (this->dev_ready)
-                       break;
-               udelay(this->chip_delay);
-               WriteDOC(NAND_CMD_STATUS, docptr, Mplus_FlashCmd);
-               WriteDOC(0, docptr, Mplus_WritePipeTerm);
-               WriteDOC(0, docptr, Mplus_WritePipeTerm);
-               while ( !(this->read_byte(mtd) & 0x40));
-               return;
-
-       /* This applies to read commands */
-       default:
-               /*
-                * If we don't have access to the busy pin, we apply the given
-                * command delay
-               */
-               if (!this->dev_ready) {
-                       udelay (this->chip_delay);
-                       return;
-               }
-       }
-
-       /* Apply this short delay always to ensure that we do wait tWB in
-        * any case on any machine. */
-       ndelay (100);
-       /* wait until command is processed */
-       while (!this->dev_ready(mtd));
-}
-
-static int doc200x_dev_ready(struct mtd_info *mtd)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-
-       if (DoC_is_MillenniumPlus(doc)) {
-               /* 11.4.2 -- must NOP four times before checking FR/B# */
-               DoC_Delay(doc, 4);
-               if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) {
-                       if(debug)
-                               printk("not ready\n");
-                       return 0;
-               }
-               if (debug)printk("was ready\n");
-               return 1;
-       } else {
-               /* 11.4.2 -- must NOP four times before checking FR/B# */
-               DoC_Delay(doc, 4);
-               if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
-                       if(debug)
-                               printk("not ready\n");
-                       return 0;
-               }
-               /* 11.4.2 -- Must NOP twice if it's ready */
-               DoC_Delay(doc, 2);
-               if (debug)printk("was ready\n");
-               return 1;
-       }
-}
-
-static int doc200x_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
-{
-       /* This is our last resort if we couldn't find or create a BBT.  Just
-          pretend all blocks are good. */
-       return 0;
-}
-
-static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-
-       /* Prime the ECC engine */
-       switch(mode) {
-       case NAND_ECC_READ:
-               WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
-               WriteDOC(DOC_ECC_EN, docptr, ECCConf);
-               break;
-       case NAND_ECC_WRITE:
-               WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
-               WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
-               break;
-       }
-}
-
-static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-
-       /* Prime the ECC engine */
-       switch(mode) {
-       case NAND_ECC_READ:
-               WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-               WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);
-               break;
-       case NAND_ECC_WRITE:
-               WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-               WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf);
-               break;
-       }
-}
-
-/* This code is only called on write */
-static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
-                                unsigned char *ecc_code)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-       int i;
-       int emptymatch = 1;
-
-       /* flush the pipeline */
-       if (DoC_is_2000(doc)) {
-               WriteDOC(doc->CDSNControl & ~CDSN_CTRL_FLASH_IO, docptr, CDSNControl);
-               WriteDOC(0, docptr, 2k_CDSN_IO);
-               WriteDOC(0, docptr, 2k_CDSN_IO);
-               WriteDOC(0, docptr, 2k_CDSN_IO);
-               WriteDOC(doc->CDSNControl, docptr, CDSNControl);
-       } else if (DoC_is_MillenniumPlus(doc)) {
-               WriteDOC(0, docptr, Mplus_NOP);
-               WriteDOC(0, docptr, Mplus_NOP);
-               WriteDOC(0, docptr, Mplus_NOP);
-       } else {
-               WriteDOC(0, docptr, NOP);
-               WriteDOC(0, docptr, NOP);
-               WriteDOC(0, docptr, NOP);
-       }
-
-       for (i = 0; i < 6; i++) {
-               if (DoC_is_MillenniumPlus(doc))
-                       ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i);
-               else
-                       ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
-               if (ecc_code[i] != empty_write_ecc[i])
-                       emptymatch = 0;
-       }
-       if (DoC_is_MillenniumPlus(doc))
-               WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
-       else
-               WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
-#if 0
-       /* If emptymatch=1, we might have an all-0xff data buffer.  Check. */
-       if (emptymatch) {
-               /* Note: this somewhat expensive test should not be triggered
-                  often.  It could be optimized away by examining the data in
-                  the writebuf routine, and remembering the result. */
-               for (i = 0; i < 512; i++) {
-                       if (dat[i] == 0xff) continue;
-                       emptymatch = 0;
-                       break;
-               }
-       }
-       /* If emptymatch still =1, we do have an all-0xff data buffer.
-          Return all-0xff ecc value instead of the computed one, so
-          it'll look just like a freshly-erased page. */
-       if (emptymatch) memset(ecc_code, 0xff, 6);
-#endif
-       return 0;
-}
-
-static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
-{
-       int i, ret = 0;
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       void __iomem *docptr = doc->virtadr;
-       volatile u_char dummy;
-       int emptymatch = 1;
-
-       /* flush the pipeline */
-       if (DoC_is_2000(doc)) {
-               dummy = ReadDOC(docptr, 2k_ECCStatus);
-               dummy = ReadDOC(docptr, 2k_ECCStatus);
-               dummy = ReadDOC(docptr, 2k_ECCStatus);
-       } else if (DoC_is_MillenniumPlus(doc)) {
-               dummy = ReadDOC(docptr, Mplus_ECCConf);
-               dummy = ReadDOC(docptr, Mplus_ECCConf);
-               dummy = ReadDOC(docptr, Mplus_ECCConf);
-       } else {
-               dummy = ReadDOC(docptr, ECCConf);
-               dummy = ReadDOC(docptr, ECCConf);
-               dummy = ReadDOC(docptr, ECCConf);
-       }
-
-       /* Error occured ? */
-       if (dummy & 0x80) {
-               for (i = 0; i < 6; i++) {
-                       if (DoC_is_MillenniumPlus(doc))
-                               calc_ecc[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i);
-                       else
-                               calc_ecc[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
-                       if (calc_ecc[i] != empty_read_syndrome[i])
-                               emptymatch = 0;
-               }
-               /* If emptymatch=1, the read syndrome is consistent with an
-                  all-0xff data and stored ecc block.  Check the stored ecc. */
-               if (emptymatch) {
-                       for (i = 0; i < 6; i++) {
-                               if (read_ecc[i] == 0xff) continue;
-                               emptymatch = 0;
-                               break;
-                       }
-               }
-               /* If emptymatch still =1, check the data block. */
-               if (emptymatch) {
-               /* Note: this somewhat expensive test should not be triggered
-                  often.  It could be optimized away by examining the data in
-                  the readbuf routine, and remembering the result. */
-                       for (i = 0; i < 512; i++) {
-                               if (dat[i] == 0xff) continue;
-                               emptymatch = 0;
-                               break;
-                       }
-               }
-               /* If emptymatch still =1, this is almost certainly a freshly-
-                  erased block, in which case the ECC will not come out right.
-                  We'll suppress the error and tell the caller everything's
-                  OK.  Because it is. */
-               if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc);
-               if (ret > 0)
-                       printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret);
-       }
-       if (DoC_is_MillenniumPlus(doc))
-               WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
-       else
-               WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
-       if (no_ecc_failures && (ret == -1)) {
-               printk(KERN_ERR "suppressing ECC failure\n");
-               ret = 0;
-       }
-       return ret;
-}
-
-/*u_char mydatabuf[528]; */
-
-static struct nand_oobinfo doc200x_oobinfo = {
-       .useecc = MTD_NANDECC_AUTOPLACE,
-       .eccbytes = 6,
-       .eccpos = {0, 1, 2, 3, 4, 5},
-       .oobfree = { {8, 8} }
-};
-
-/* Find the (I)NFTL Media Header, and optionally also the mirror media header.
-   On sucessful return, buf will contain a copy of the media header for
-   further processing.  id is the string to scan for, and will presumably be
-   either "ANAND" or "BNAND".  If findmirror=1, also look for the mirror media
-   header.  The page #s of the found media headers are placed in mh0_page and
-   mh1_page in the DOC private structure. */
-static int __init find_media_headers(struct mtd_info *mtd, u_char *buf,
-                                    const char *id, int findmirror)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       unsigned offs, end = (MAX_MEDIAHEADER_SCAN << this->phys_erase_shift);
-       int ret;
-       size_t retlen;
-
-       end = min(end, mtd->size); /* paranoia */
-       for (offs = 0; offs < end; offs += mtd->erasesize) {
-               ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf);
-               if (retlen != mtd->oobblock) continue;
-               if (ret) {
-                       printk(KERN_WARNING "ECC error scanning DOC at 0x%x\n",
-                               offs);
-               }
-               if (memcmp(buf, id, 6)) continue;
-               printk(KERN_INFO "Found DiskOnChip %s Media Header at 0x%x\n", id, offs);
-               if (doc->mh0_page == -1) {
-                       doc->mh0_page = offs >> this->page_shift;
-                       if (!findmirror) return 1;
-                       continue;
-               }
-               doc->mh1_page = offs >> this->page_shift;
-               return 2;
-       }
-       if (doc->mh0_page == -1) {
-               printk(KERN_WARNING "DiskOnChip %s Media Header not found.\n", id);
-               return 0;
-       }
-       /* Only one mediaheader was found.  We want buf to contain a
-          mediaheader on return, so we'll have to re-read the one we found. */
-       offs = doc->mh0_page << this->page_shift;
-       ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf);
-       if (retlen != mtd->oobblock) {
-               /* Insanity.  Give up. */
-               printk(KERN_ERR "Read DiskOnChip Media Header once, but can't reread it???\n");
-               return 0;
-       }
-       return 1;
-}
-
-static inline int __init nftl_partscan(struct mtd_info *mtd,
-                               struct mtd_partition *parts)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       int ret = 0;
-       u_char *buf;
-       struct NFTLMediaHeader *mh;
-       const unsigned psize = 1 << this->page_shift;
-       unsigned blocks, maxblocks;
-       int offs, numheaders;
-
-       buf = kmalloc(mtd->oobblock, GFP_KERNEL);
-       if (!buf) {
-               printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n");
-               return 0;
-       }
-       if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) goto out;
-       mh = (struct NFTLMediaHeader *) buf;
-
-/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */
-/*     if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */
-       printk(KERN_INFO "    DataOrgID        = %s\n"
-                        "    NumEraseUnits    = %d\n"
-                        "    FirstPhysicalEUN = %d\n"
-                        "    FormattedSize    = %d\n"
-                        "    UnitSizeFactor   = %d\n",
-               mh->DataOrgID, mh->NumEraseUnits,
-               mh->FirstPhysicalEUN, mh->FormattedSize,
-               mh->UnitSizeFactor);
-/*#endif */
-
-       blocks = mtd->size >> this->phys_erase_shift;
-       maxblocks = min(32768U, mtd->erasesize - psize);
-
-       if (mh->UnitSizeFactor == 0x00) {
-               /* Auto-determine UnitSizeFactor.  The constraints are:
-                  - There can be at most 32768 virtual blocks.
-                  - There can be at most (virtual block size - page size)
-                    virtual blocks (because MediaHeader+BBT must fit in 1).
-               */
-               mh->UnitSizeFactor = 0xff;
-               while (blocks > maxblocks) {
-                       blocks >>= 1;
-                       maxblocks = min(32768U, (maxblocks << 1) + psize);
-                       mh->UnitSizeFactor--;
-               }
-               printk(KERN_WARNING "UnitSizeFactor=0x00 detected.  Correct value is assumed to be 0x%02x.\n", mh->UnitSizeFactor);
-       }
-
-       /* NOTE: The lines below modify internal variables of the NAND and MTD
-          layers; variables with have already been configured by nand_scan.
-          Unfortunately, we didn't know before this point what these values
-          should be.  Thus, this code is somewhat dependant on the exact
-          implementation of the NAND layer.  */
-       if (mh->UnitSizeFactor != 0xff) {
-               this->bbt_erase_shift += (0xff - mh->UnitSizeFactor);
-               mtd->erasesize <<= (0xff - mh->UnitSizeFactor);
-               printk(KERN_INFO "Setting virtual erase size to %d\n", mtd->erasesize);
-               blocks = mtd->size >> this->bbt_erase_shift;
-               maxblocks = min(32768U, mtd->erasesize - psize);
-       }
-
-       if (blocks > maxblocks) {
-               printk(KERN_ERR "UnitSizeFactor of 0x%02x is inconsistent with device size.  Aborting.\n", mh->UnitSizeFactor);
-               goto out;
-       }
-
-       /* Skip past the media headers. */
-       offs = max(doc->mh0_page, doc->mh1_page);
-       offs <<= this->page_shift;
-       offs += mtd->erasesize;
-
-       /*parts[0].name = " DiskOnChip Boot / Media Header partition"; */
-       /*parts[0].offset = 0; */
-       /*parts[0].size = offs; */
-
-       parts[0].name = " DiskOnChip BDTL partition";
-       parts[0].offset = offs;
-       parts[0].size = (mh->NumEraseUnits - numheaders) << this->bbt_erase_shift;
-
-       offs += parts[0].size;
-       if (offs < mtd->size) {
-               parts[1].name = " DiskOnChip Remainder partition";
-               parts[1].offset = offs;
-               parts[1].size = mtd->size - offs;
-               ret = 2;
-               goto out;
-       }
-       ret = 1;
-out:
-       kfree(buf);
-       return ret;
-}
-
-/* This is a stripped-down copy of the code in inftlmount.c */
-static inline int __init inftl_partscan(struct mtd_info *mtd,
-                                struct mtd_partition *parts)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       int ret = 0;
-       u_char *buf;
-       struct INFTLMediaHeader *mh;
-       struct INFTLPartition *ip;
-       int numparts = 0;
-       int blocks;
-       int vshift, lastvunit = 0;
-       int i;
-       int end = mtd->size;
-
-       if (inftl_bbt_write)
-               end -= (INFTL_BBT_RESERVED_BLOCKS << this->phys_erase_shift);
-
-       buf = kmalloc(mtd->oobblock, GFP_KERNEL);
-       if (!buf) {
-               printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n");
-               return 0;
-       }
-
-       if (!find_media_headers(mtd, buf, "BNAND", 0)) goto out;
-       doc->mh1_page = doc->mh0_page + (4096 >> this->page_shift);
-       mh = (struct INFTLMediaHeader *) buf;
-
-       mh->NoOfBootImageBlocks = le32_to_cpu(mh->NoOfBootImageBlocks);
-       mh->NoOfBinaryPartitions = le32_to_cpu(mh->NoOfBinaryPartitions);
-       mh->NoOfBDTLPartitions = le32_to_cpu(mh->NoOfBDTLPartitions);
-       mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits);
-       mh->FormatFlags = le32_to_cpu(mh->FormatFlags);
-       mh->PercentUsed = le32_to_cpu(mh->PercentUsed);
-
-/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */
-/*     if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */
-       printk(KERN_INFO "    bootRecordID          = %s\n"
-                        "    NoOfBootImageBlocks   = %d\n"
-                        "    NoOfBinaryPartitions  = %d\n"
-                        "    NoOfBDTLPartitions    = %d\n"
-                        "    BlockMultiplerBits    = %d\n"
-                        "    FormatFlgs            = %d\n"
-                        "    OsakVersion           = %d.%d.%d.%d\n"
-                        "    PercentUsed           = %d\n",
-               mh->bootRecordID, mh->NoOfBootImageBlocks,
-               mh->NoOfBinaryPartitions,
-               mh->NoOfBDTLPartitions,
-               mh->BlockMultiplierBits, mh->FormatFlags,
-               ((unsigned char *) &mh->OsakVersion)[0] & 0xf,
-               ((unsigned char *) &mh->OsakVersion)[1] & 0xf,
-               ((unsigned char *) &mh->OsakVersion)[2] & 0xf,
-               ((unsigned char *) &mh->OsakVersion)[3] & 0xf,
-               mh->PercentUsed);
-/*#endif */
-
-       vshift = this->phys_erase_shift + mh->BlockMultiplierBits;
-
-       blocks = mtd->size >> vshift;
-       if (blocks > 32768) {
-               printk(KERN_ERR "BlockMultiplierBits=%d is inconsistent with device size.  Aborting.\n", mh->BlockMultiplierBits);
-               goto out;
-       }
-
-       blocks = doc->chips_per_floor << (this->chip_shift - this->phys_erase_shift);
-       if (inftl_bbt_write && (blocks > mtd->erasesize)) {
-               printk(KERN_ERR "Writeable BBTs spanning more than one erase block are not yet supported.  FIX ME!\n");
-               goto out;
-       }
-
-       /* Scan the partitions */
-       for (i = 0; (i < 4); i++) {
-               ip = &(mh->Partitions[i]);
-               ip->virtualUnits = le32_to_cpu(ip->virtualUnits);
-               ip->firstUnit = le32_to_cpu(ip->firstUnit);
-               ip->lastUnit = le32_to_cpu(ip->lastUnit);
-               ip->flags = le32_to_cpu(ip->flags);
-               ip->spareUnits = le32_to_cpu(ip->spareUnits);
-               ip->Reserved0 = le32_to_cpu(ip->Reserved0);
-
-/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */
-/*             if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */
-               printk(KERN_INFO        "    PARTITION[%d] ->\n"
-                       "        virtualUnits    = %d\n"
-                       "        firstUnit       = %d\n"
-                       "        lastUnit        = %d\n"
-                       "        flags           = 0x%x\n"
-                       "        spareUnits      = %d\n",
-                       i, ip->virtualUnits, ip->firstUnit,
-                       ip->lastUnit, ip->flags,
-                       ip->spareUnits);
-/*#endif */
-
-/*
-               if ((i == 0) && (ip->firstUnit > 0)) {
-                       parts[0].name = " DiskOnChip IPL / Media Header partition";
-                       parts[0].offset = 0;
-                       parts[0].size = mtd->erasesize * ip->firstUnit;
-                       numparts = 1;
-               }
-*/
-
-               if (ip->flags & INFTL_BINARY)
-                       parts[numparts].name = " DiskOnChip BDK partition";
-               else
-                       parts[numparts].name = " DiskOnChip BDTL partition";
-               parts[numparts].offset = ip->firstUnit << vshift;
-               parts[numparts].size = (1 + ip->lastUnit - ip->firstUnit) << vshift;
-               numparts++;
-               if (ip->lastUnit > lastvunit) lastvunit = ip->lastUnit;
-               if (ip->flags & INFTL_LAST) break;
-       }
-       lastvunit++;
-       if ((lastvunit << vshift) < end) {
-               parts[numparts].name = " DiskOnChip Remainder partition";
-               parts[numparts].offset = lastvunit << vshift;
-               parts[numparts].size = end - parts[numparts].offset;
-               numparts++;
-       }
-       ret = numparts;
-out:
-       kfree(buf);
-       return ret;
-}
-
-static int __init nftl_scan_bbt(struct mtd_info *mtd)
-{
-       int ret, numparts;
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       struct mtd_partition parts[2];
-
-       memset((char *) parts, 0, sizeof(parts));
-       /* On NFTL, we have to find the media headers before we can read the
-          BBTs, since they're stored in the media header eraseblocks. */
-       numparts = nftl_partscan(mtd, parts);
-       if (!numparts) return -EIO;
-       this->bbt_td->options = NAND_BBT_ABSPAGE | NAND_BBT_8BIT |
-                               NAND_BBT_SAVECONTENT | NAND_BBT_WRITE |
-                               NAND_BBT_VERSION;
-       this->bbt_td->veroffs = 7;
-       this->bbt_td->pages[0] = doc->mh0_page + 1;
-       if (doc->mh1_page != -1) {
-               this->bbt_md->options = NAND_BBT_ABSPAGE | NAND_BBT_8BIT |
-                                       NAND_BBT_SAVECONTENT | NAND_BBT_WRITE |
-                                       NAND_BBT_VERSION;
-               this->bbt_md->veroffs = 7;
-               this->bbt_md->pages[0] = doc->mh1_page + 1;
-       } else {
-               this->bbt_md = NULL;
-       }
-
-       /* It's safe to set bd=NULL below because NAND_BBT_CREATE is not set.
-          At least as nand_bbt.c is currently written. */
-       if ((ret = nand_scan_bbt(mtd, NULL)))
-               return ret;
-       add_mtd_device(mtd);
-#ifdef CONFIG_MTD_PARTITIONS
-       if (!no_autopart)
-               add_mtd_partitions(mtd, parts, numparts);
-#endif
-       return 0;
-}
-
-static int __init inftl_scan_bbt(struct mtd_info *mtd)
-{
-       int ret, numparts;
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-       struct mtd_partition parts[5];
-
-       if (this->numchips > doc->chips_per_floor) {
-               printk(KERN_ERR "Multi-floor INFTL devices not yet supported.\n");
-               return -EIO;
-       }
-
-       if (DoC_is_MillenniumPlus(doc)) {
-               this->bbt_td->options = NAND_BBT_2BIT | NAND_BBT_ABSPAGE;
-               if (inftl_bbt_write)
-                       this->bbt_td->options |= NAND_BBT_WRITE;
-               this->bbt_td->pages[0] = 2;
-               this->bbt_md = NULL;
-       } else {
-               this->bbt_td->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT |
-                                       NAND_BBT_VERSION;
-               if (inftl_bbt_write)
-                       this->bbt_td->options |= NAND_BBT_WRITE;
-               this->bbt_td->offs = 8;
-               this->bbt_td->len = 8;
-               this->bbt_td->veroffs = 7;
-               this->bbt_td->maxblocks = INFTL_BBT_RESERVED_BLOCKS;
-               this->bbt_td->reserved_block_code = 0x01;
-               this->bbt_td->pattern = "MSYS_BBT";
-
-               this->bbt_md->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT |
-                                       NAND_BBT_VERSION;
-               if (inftl_bbt_write)
-                       this->bbt_md->options |= NAND_BBT_WRITE;
-               this->bbt_md->offs = 8;
-               this->bbt_md->len = 8;
-               this->bbt_md->veroffs = 7;
-               this->bbt_md->maxblocks = INFTL_BBT_RESERVED_BLOCKS;
-               this->bbt_md->reserved_block_code = 0x01;
-               this->bbt_md->pattern = "TBB_SYSM";
-       }
-
-       /* It's safe to set bd=NULL below because NAND_BBT_CREATE is not set.
-          At least as nand_bbt.c is currently written. */
-       if ((ret = nand_scan_bbt(mtd, NULL)))
-               return ret;
-       memset((char *) parts, 0, sizeof(parts));
-       numparts = inftl_partscan(mtd, parts);
-       /* At least for now, require the INFTL Media Header.  We could probably
-          do without it for non-INFTL use, since all it gives us is
-          autopartitioning, but I want to give it more thought. */
-       if (!numparts) return -EIO;
-       add_mtd_device(mtd);
-#ifdef CONFIG_MTD_PARTITIONS
-       if (!no_autopart)
-               add_mtd_partitions(mtd, parts, numparts);
-#endif
-       return 0;
-}
-
-static inline int __init doc2000_init(struct mtd_info *mtd)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-
-       this->write_byte = doc2000_write_byte;
-       this->read_byte = doc2000_read_byte;
-       this->write_buf = doc2000_writebuf;
-       this->read_buf = doc2000_readbuf;
-       this->verify_buf = doc2000_verifybuf;
-       this->scan_bbt = nftl_scan_bbt;
-
-       doc->CDSNControl = CDSN_CTRL_FLASH_IO | CDSN_CTRL_ECC_IO;
-       doc2000_count_chips(mtd);
-       mtd->name = "DiskOnChip 2000 (NFTL Model)";
-       return (4 * doc->chips_per_floor);
-}
-
-static inline int __init doc2001_init(struct mtd_info *mtd)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-
-       this->write_byte = doc2001_write_byte;
-       this->read_byte = doc2001_read_byte;
-       this->write_buf = doc2001_writebuf;
-       this->read_buf = doc2001_readbuf;
-       this->verify_buf = doc2001_verifybuf;
-
-       ReadDOC(doc->virtadr, ChipID);
-       ReadDOC(doc->virtadr, ChipID);
-       ReadDOC(doc->virtadr, ChipID);
-       if (ReadDOC(doc->virtadr, ChipID) != DOC_ChipID_DocMil) {
-               /* It's not a Millennium; it's one of the newer
-                  DiskOnChip 2000 units with a similar ASIC.
-                  Treat it like a Millennium, except that it
-                  can have multiple chips. */
-               doc2000_count_chips(mtd);
-               mtd->name = "DiskOnChip 2000 (INFTL Model)";
-               this->scan_bbt = inftl_scan_bbt;
-               return (4 * doc->chips_per_floor);
-       } else {
-               /* Bog-standard Millennium */
-               doc->chips_per_floor = 1;
-               mtd->name = "DiskOnChip Millennium";
-               this->scan_bbt = nftl_scan_bbt;
-               return 1;
-       }
-}
-
-static inline int __init doc2001plus_init(struct mtd_info *mtd)
-{
-       struct nand_chip *this = mtd->priv;
-       struct doc_priv *doc = this->priv;
-
-       this->write_byte = NULL;
-       this->read_byte = doc2001plus_read_byte;
-       this->write_buf = doc2001plus_writebuf;
-       this->read_buf = doc2001plus_readbuf;
-       this->verify_buf = doc2001plus_verifybuf;
-       this->scan_bbt = inftl_scan_bbt;
-       this->hwcontrol = NULL;
-       this->select_chip = doc2001plus_select_chip;
-       this->cmdfunc = doc2001plus_command;
-       this->enable_hwecc = doc2001plus_enable_hwecc;
-
-       doc->chips_per_floor = 1;
-       mtd->name = "DiskOnChip Millennium Plus";
-
-       return 1;
-}
-
-static inline int __init doc_probe(unsigned long physadr)
-{
-       unsigned char ChipID;
-       struct mtd_info *mtd;
-       struct nand_chip *nand;
-       struct doc_priv *doc;
-       void __iomem *virtadr;
-       unsigned char save_control;
-       unsigned char tmp, tmpb, tmpc;
-       int reg, len, numchips;
-       int ret = 0;
-
-       virtadr = ioremap(physadr, DOC_IOREMAP_LEN);
-       if (!virtadr) {
-               printk(KERN_ERR "Diskonchip ioremap failed: 0x%x bytes at 0x%lx\n", DOC_IOREMAP_LEN, physadr);
-               return -EIO;
-       }
-
-       /* It's not possible to cleanly detect the DiskOnChip - the
-        * bootup procedure will put the device into reset mode, and
-        * it's not possible to talk to it without actually writing
-        * to the DOCControl register. So we store the current contents
-        * of the DOCControl register's location, in case we later decide
-        * that it's not a DiskOnChip, and want to put it back how we
-        * found it.
-        */
-       save_control = ReadDOC(virtadr, DOCControl);
-
-       /* Reset the DiskOnChip ASIC */
-       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
-                virtadr, DOCControl);
-       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
-                virtadr, DOCControl);
-
-       /* Enable the DiskOnChip ASIC */
-       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
-                virtadr, DOCControl);
-       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
-                virtadr, DOCControl);
-
-       ChipID = ReadDOC(virtadr, ChipID);
-
-       switch(ChipID) {
-       case DOC_ChipID_Doc2k:
-               reg = DoC_2k_ECCStatus;
-               break;
-       case DOC_ChipID_DocMil:
-               reg = DoC_ECCConf;
-               break;
-       case DOC_ChipID_DocMilPlus16:
-       case DOC_ChipID_DocMilPlus32:
-       case 0:
-               /* Possible Millennium Plus, need to do more checks */
-               /* Possibly release from power down mode */
-               for (tmp = 0; (tmp < 4); tmp++)
-                       ReadDOC(virtadr, Mplus_Power);
-
-               /* Reset the Millennium Plus ASIC */
-               tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
-                       DOC_MODE_BDECT;
-               WriteDOC(tmp, virtadr, Mplus_DOCControl);
-               WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm);
-
-               mdelay(1);
-               /* Enable the Millennium Plus ASIC */
-               tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
-                       DOC_MODE_BDECT;
-               WriteDOC(tmp, virtadr, Mplus_DOCControl);
-               WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm);
-               mdelay(1);
-
-               ChipID = ReadDOC(virtadr, ChipID);
-
-               switch (ChipID) {
-               case DOC_ChipID_DocMilPlus16:
-                       reg = DoC_Mplus_Toggle;
-                       break;
-               case DOC_ChipID_DocMilPlus32:
-                       printk(KERN_ERR "DiskOnChip Millennium Plus 32MB is not supported, ignoring.\n");
-               default:
-                       ret = -ENODEV;
-                       goto notfound;
-               }
-               break;
-
-       default:
-               ret = -ENODEV;
-               goto notfound;
-       }
-       /* Check the TOGGLE bit in the ECC register */
-       tmp  = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;
-       tmpb = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;
-       tmpc = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;
-       if ((tmp == tmpb) || (tmp != tmpc)) {
-               printk(KERN_WARNING "Possible DiskOnChip at 0x%lx failed TOGGLE test, dropping.\n", physadr);
-               ret = -ENODEV;
-               goto notfound;
-       }
-
-       for (mtd = doclist; mtd; mtd = doc->nextdoc) {
-               unsigned char oldval;
-               unsigned char newval;
-               nand = mtd->priv;
-               doc = nand->priv;
-               /* Use the alias resolution register to determine if this is
-                  in fact the same DOC aliased to a new address.  If writes
-                  to one chip's alias resolution register change the value on
-                  the other chip, they're the same chip. */
-               if (ChipID == DOC_ChipID_DocMilPlus16) {
-                       oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution);
-                       newval = ReadDOC(virtadr, Mplus_AliasResolution);
-               } else {
-                       oldval = ReadDOC(doc->virtadr, AliasResolution);
-                       newval = ReadDOC(virtadr, AliasResolution);
-               }
-               if (oldval != newval)
-                       continue;
-               if (ChipID == DOC_ChipID_DocMilPlus16) {
-                       WriteDOC(~newval, virtadr, Mplus_AliasResolution);
-                       oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution);
-                       WriteDOC(newval, virtadr, Mplus_AliasResolution); /* restore it */
-               } else {
-                       WriteDOC(~newval, virtadr, AliasResolution);
-                       oldval = ReadDOC(doc->virtadr, AliasResolution);
-                       WriteDOC(newval, virtadr, AliasResolution); /* restore it */
-               }
-               newval = ~newval;
-               if (oldval == newval) {
-                       printk(KERN_DEBUG "Found alias of DOC at 0x%lx to 0x%lx\n", doc->physadr, physadr);
-                       goto notfound;
-               }
-       }
-
-       printk(KERN_NOTICE "DiskOnChip found at 0x%lx\n", physadr);
-
-       len = sizeof(struct mtd_info) +
-             sizeof(struct nand_chip) +
-             sizeof(struct doc_priv) +
-             (2 * sizeof(struct nand_bbt_descr));
-       mtd =  kmalloc(len, GFP_KERNEL);
-       if (!mtd) {
-               printk(KERN_ERR "DiskOnChip kmalloc (%d bytes) failed!\n", len);
-               ret = -ENOMEM;
-               goto fail;
-       }
-       memset(mtd, 0, len);
-
-       nand                    = (struct nand_chip *) (mtd + 1);
-       doc                     = (struct doc_priv *) (nand + 1);
-       nand->bbt_td            = (struct nand_bbt_descr *) (doc + 1);
-       nand->bbt_md            = nand->bbt_td + 1;
-
-       mtd->priv               = nand;
-       mtd->owner              = THIS_MODULE;
-
-       nand->priv              = doc;
-       nand->select_chip       = doc200x_select_chip;
-       nand->hwcontrol         = doc200x_hwcontrol;
-       nand->dev_ready         = doc200x_dev_ready;
-       nand->waitfunc          = doc200x_wait;
-       nand->block_bad         = doc200x_block_bad;
-       nand->enable_hwecc      = doc200x_enable_hwecc;
-       nand->calculate_ecc     = doc200x_calculate_ecc;
-       nand->correct_data      = doc200x_correct_data;
-
-       nand->autooob           = &doc200x_oobinfo;
-       nand->eccmode           = NAND_ECC_HW6_512;
-       nand->options           = NAND_USE_FLASH_BBT | NAND_HWECC_SYNDROME;
-
-       doc->physadr            = physadr;
-       doc->virtadr            = virtadr;
-       doc->ChipID             = ChipID;
-       doc->curfloor           = -1;
-       doc->curchip            = -1;
-       doc->mh0_page           = -1;
-       doc->mh1_page           = -1;
-       doc->nextdoc            = doclist;
-
-       if (ChipID == DOC_ChipID_Doc2k)
-               numchips = doc2000_init(mtd);
-       else if (ChipID == DOC_ChipID_DocMilPlus16)
-               numchips = doc2001plus_init(mtd);
-       else
-               numchips = doc2001_init(mtd);
-
-       if ((ret = nand_scan(mtd, numchips))) {
-               /* DBB note: i believe nand_release is necessary here, as
-                  buffers may have been allocated in nand_base.  Check with
-                  Thomas. FIX ME! */
-               /* nand_release will call del_mtd_device, but we haven't yet
-                  added it.  This is handled without incident by
-                  del_mtd_device, as far as I can tell. */
-               nand_release(mtd);
-               kfree(mtd);
-               goto fail;
-       }
-
-       /* Success! */
-       doclist = mtd;
-       return 0;
-
-notfound:
-       /* Put back the contents of the DOCControl register, in case it's not
-          actually a DiskOnChip.  */
-       WriteDOC(save_control, virtadr, DOCControl);
-fail:
-       iounmap(virtadr);
-       return ret;
-}
-
-static void release_nanddoc(void)
-{
-       struct mtd_info *mtd, *nextmtd;
-       struct nand_chip *nand;
-       struct doc_priv *doc;
-
-       for (mtd = doclist; mtd; mtd = nextmtd) {
-               nand = mtd->priv;
-               doc = nand->priv;
-
-               nextmtd = doc->nextdoc;
-               nand_release(mtd);
-               iounmap(doc->virtadr);
-               kfree(mtd);
-       }
-}
-
-static int __init init_nanddoc(void)
-{
-       int i, ret = 0;
-
-       /* We could create the decoder on demand, if memory is a concern.
-        * This way we have it handy, if an error happens
-        *
-        * Symbolsize is 10 (bits)
-        * Primitve polynomial is x^10+x^3+1
-        * first consecutive root is 510
-        * primitve element to generate roots = 1
-        * generator polinomial degree = 4
-        */
-       rs_decoder = init_rs(10, 0x409, FCR, 1, NROOTS);
-       if (!rs_decoder) {
-               printk (KERN_ERR "DiskOnChip: Could not create a RS decoder\n");
-               return -ENOMEM;
-       }
-
-       if (doc_config_location) {
-               printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location);
-               ret = doc_probe(doc_config_location);
-               if (ret < 0)
-                       goto outerr;
-       } else {
-               for (i=0; (doc_locations[i] != 0xffffffff); i++) {
-                       doc_probe(doc_locations[i]);
-               }
-       }
-       /* No banner message any more. Print a message if no DiskOnChip
-          found, so the user knows we at least tried. */
-       if (!doclist) {
-               printk(KERN_INFO "No valid DiskOnChip devices found\n");
-               ret = -ENODEV;
-               goto outerr;
-       }
-       return 0;
-outerr:
-       free_rs(rs_decoder);
-       return ret;
-}
-
-static void __exit cleanup_nanddoc(void)
-{
-       /* Cleanup the nand/DoC resources */
-       release_nanddoc();
-
-       /* Free the reed solomon resources */
-       if (rs_decoder) {
-               free_rs(rs_decoder);
-       }
-}
-
-module_init(init_nanddoc);
-module_exit(cleanup_nanddoc);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver\n");
-#endif
diff --git a/drivers/nand/nand.c b/drivers/nand/nand.c
deleted file mode 100644 (file)
index 27b5792..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * (C) Copyright 2005
- * 2N Telekomunikace, a.s. <www.2n.cz>
- * Ladislav Michl <michl@2n.cz>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-
-#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
-
-#include <nand.h>
-
-#ifndef CFG_NAND_BASE_LIST
-#define CFG_NAND_BASE_LIST { CFG_NAND_BASE }
-#endif
-
-int nand_curr_device = -1;
-nand_info_t nand_info[CFG_MAX_NAND_DEVICE];
-
-static struct nand_chip nand_chip[CFG_MAX_NAND_DEVICE];
-static ulong base_address[CFG_MAX_NAND_DEVICE] = CFG_NAND_BASE_LIST;
-
-static const char default_nand_name[] = "nand";
-
-extern int board_nand_init(struct nand_chip *nand);
-
-static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand,
-                          ulong base_addr)
-{
-       mtd->priv = nand;
-
-       nand->IO_ADDR_R = nand->IO_ADDR_W = (void  __iomem *)base_addr;
-       if (board_nand_init(nand) == 0) {
-               if (nand_scan(mtd, 1) == 0) {
-                       if (!mtd->name)
-                               mtd->name = (char *)default_nand_name;
-               } else
-                       mtd->name = NULL;
-       } else {
-               mtd->name = NULL;
-               mtd->size = 0;
-       }
-
-}
-
-void nand_init(void)
-{
-       int i;
-       unsigned int size = 0;
-       for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {
-               nand_init_chip(&nand_info[i], &nand_chip[i], base_address[i]);
-               size += nand_info[i].size;
-               if (nand_curr_device == -1)
-                       nand_curr_device = i;
-       }
-       printf("%lu MiB\n", size / (1024 * 1024));
-
-#ifdef CFG_NAND_SELECT_DEVICE
-       /*
-        * Select the chip in the board/cpu specific driver
-        */
-       board_nand_select_device(nand_info[nand_curr_device].priv, nand_curr_device);
-#endif
-}
-
-#endif
diff --git a/drivers/nand/nand_base.c b/drivers/nand/nand_base.c
deleted file mode 100644 (file)
index 151f535..0000000
+++ /dev/null
@@ -1,2668 +0,0 @@
-/*
- *  drivers/mtd/nand.c
- *
- *  Overview:
- *   This is the generic MTD driver for NAND flash devices. It should be
- *   capable of working with almost all NAND chips currently available.
- *   Basic support for AG-AND chips is provided.
- *
- *     Additional technical information is available on
- *     http://www.linux-mtd.infradead.org/tech/nand.html
- *
- *  Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
- *               2002 Thomas Gleixner (tglx@linutronix.de)
- *
- *  02-08-2004  tglx: support for strange chips, which cannot auto increment
- *             pages on read / read_oob
- *
- *  03-17-2004  tglx: Check ready before auto increment check. Simon Bayes
- *             pointed this out, as he marked an auto increment capable chip
- *             as NOAUTOINCR in the board driver.
- *             Make reads over block boundaries work too
- *
- *  04-14-2004 tglx: first working version for 2k page size chips
- *
- *  05-19-2004  tglx: Basic support for Renesas AG-AND chips
- *
- *  09-24-2004  tglx: add support for hardware controllers (e.g. ECC) shared
- *             among multiple independend devices. Suggestions and initial patch
- *             from Ben Dooks <ben-mtd@fluff.org>
- *
- * Credits:
- *     David Woodhouse for adding multichip support
- *
- *     Aleph One Ltd. and Toby Churchill Ltd. for supporting the
- *     rework for 2K page size chips
- *
- * TODO:
- *     Enable cached programming for 2k page size chips
- *     Check, if mtd->ecctype should be set to MTD_ECC_HW
- *     if we have HW ecc support.
- *     The AG-AND chips have nice features for speed improvement,
- *     which are not supported yet. Read / program 4 pages in one go.
- *
- * $Id: nand_base.c,v 1.126 2004/12/13 11:22:25 lavinen Exp $
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-/* XXX U-BOOT XXX */
-#if 0
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/compatmac.h>
-#include <linux/interrupt.h>
-#include <linux/bitops.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_MTD_PARTITIONS
-#include <linux/mtd/partitions.h>
-#endif
-
-#endif
-
-#include <common.h>
-
-#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
-
-#include <malloc.h>
-#include <watchdog.h>
-#include <linux/mtd/compat.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-
-#include <asm/io.h>
-#include <asm/errno.h>
-
-#ifdef CONFIG_JFFS2_NAND
-#include <jffs2/jffs2.h>
-#endif
-
-/* Define default oob placement schemes for large and small page devices */
-static struct nand_oobinfo nand_oob_8 = {
-       .useecc = MTD_NANDECC_AUTOPLACE,
-       .eccbytes = 3,
-       .eccpos = {0, 1, 2},
-       .oobfree = { {3, 2}, {6, 2} }
-};
-
-static struct nand_oobinfo nand_oob_16 = {
-       .useecc = MTD_NANDECC_AUTOPLACE,
-       .eccbytes = 6,
-       .eccpos = {0, 1, 2, 3, 6, 7},
-       .oobfree = { {8, 8} }
-};
-
-static struct nand_oobinfo nand_oob_64 = {
-       .useecc = MTD_NANDECC_AUTOPLACE,
-       .eccbytes = 24,
-       .eccpos = {
-               40, 41, 42, 43, 44, 45, 46, 47,
-               48, 49, 50, 51, 52, 53, 54, 55,
-               56, 57, 58, 59, 60, 61, 62, 63},
-       .oobfree = { {2, 38} }
-};
-
-/* This is used for padding purposes in nand_write_oob */
-static u_char ffchars[] = {
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-};
-
-/*
- * NAND low-level MTD interface functions
- */
-static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len);
-static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len);
-static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len);
-
-static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
-static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
-                         size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
-static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
-static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf);
-static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
-                          size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
-static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char *buf);
-/* XXX U-BOOT XXX */
-#if 0
-static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs,
-                       unsigned long count, loff_t to, size_t * retlen);
-static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs,
-                       unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
-#endif
-static int nand_erase (struct mtd_info *mtd, struct erase_info *instr);
-static void nand_sync (struct mtd_info *mtd);
-
-/* Some internal functions */
-static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf,
-               struct nand_oobinfo *oobsel, int mode);
-#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
-static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
-       u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode);
-#else
-#define nand_verify_pages(...) (0)
-#endif
-
-static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state);
-
-/**
- * nand_release_device - [GENERIC] release chip
- * @mtd:       MTD device structure
- *
- * Deselect, release chip lock and wake up anyone waiting on the device
- */
-/* XXX U-BOOT XXX */
-#if 0
-static void nand_release_device (struct mtd_info *mtd)
-{
-       struct nand_chip *this = mtd->priv;
-
-       /* De-select the NAND device */
-       this->select_chip(mtd, -1);
-       /* Do we have a hardware controller ? */
-       if (this->controller) {
-               spin_lock(&this->controller->lock);
-               this->controller->active = NULL;
-               spin_unlock(&this->controller->lock);
-       }
-       /* Release the chip */
-       spin_lock (&this->chip_lock);
-       this->state = FL_READY;
-       wake_up (&this->wq);
-       spin_unlock (&this->chip_lock);
-}
-#else
-static void nand_release_device (struct mtd_info *mtd)
-{
-       struct nand_chip *this = mtd->priv;
-       this->select_chip(mtd, -1);     /* De-select the NAND device */
-}
-#endif
-
-/**
- * nand_read_byte - [DEFAULT] read one byte from the chip
- * @mtd:       MTD device structure
- *
- * Default read function for 8bit buswith
- */
-static u_char nand_read_byte(struct mtd_info *mtd)
-{
-       struct nand_chip *this = mtd->priv;
-       return readb(this->IO_ADDR_R);
-}
-
-/**
- * nand_write_byte - [DEFAULT] write one byte to the chip
- * @mtd:       MTD device structure
- * @byte:      pointer to data byte to write
- *
- * Default write function for 8it buswith
- */
-static void nand_write_byte(struct mtd_info *mtd, u_char byte)
-{
-       struct nand_chip *this = mtd->priv;
-       writeb(byte, this->IO_ADDR_W);
-}
-
-/**
- * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
- * @mtd:       MTD device structure
- *
- * Default read function for 16bit buswith with
- * endianess conversion
- */
-static u_char nand_read_byte16(struct mtd_info *mtd)
-{
-       struct nand_chip *this = mtd->priv;
-       return (u_char) cpu_to_le16(readw(this->IO_ADDR_R));
-}
-
-/**
- * nand_write_byte16 - [DEFAULT] write one byte endianess aware to the chip
- * @mtd:       MTD device structure
- * @byte:      pointer to data byte to write
- *
- * Default write function for 16bit buswith with
- * endianess conversion
- */
-static void nand_write_byte16(struct mtd_info *mtd, u_char byte)
-{
-       struct nand_chip *this = mtd->priv;
-       writew(le16_to_cpu((u16) byte), this->IO_ADDR_W);
-}
-
-/**
- * nand_read_word - [DEFAULT] read one word from the chip
- * @mtd:       MTD device structure
- *
- * Default read function for 16bit buswith without
- * endianess conversion
- */
-static u16 nand_read_word(struct mtd_info *mtd)
-{
-       struct nand_chip *this = mtd->priv;
-       return readw(this->IO_ADDR_R);
-}
-
-/**
- * nand_write_word - [DEFAULT] write one word to the chip
- * @mtd:       MTD device structure
- * @word:      data word to write
- *
- * Default write function for 16bit buswith without
- * endianess conversion
- */
-static void nand_write_word(struct mtd_info *mtd, u16 word)
-{
-       struct nand_chip *this = mtd->priv;
-       writew(word, this->IO_ADDR_W);
-}
-
-/**
- * nand_select_chip - [DEFAULT] control CE line
- * @mtd:       MTD device structure
- * @chip:      chipnumber to select, -1 for deselect
- *
- * Default select function for 1 chip devices.
- */
-static void nand_select_chip(struct mtd_info *mtd, int chip)
-{
-       struct nand_chip *this = mtd->priv;
-       switch(chip) {
-       case -1:
-               this->hwcontrol(mtd, NAND_CTL_CLRNCE);
-               break;
-       case 0:
-               this->hwcontrol(mtd, NAND_CTL_SETNCE);
-               break;
-
-       default:
-               BUG();
-       }
-}
-
-/**
- * nand_write_buf - [DEFAULT] write buffer to chip
- * @mtd:       MTD device structure
- * @buf:       data buffer
- * @len:       number of bytes to write
- *
- * Default write function for 8bit buswith
- */
-static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
-       int i;
-       struct nand_chip *this = mtd->priv;
-
-       for (i=0; i<len; i++)
-               writeb(buf[i], this->IO_ADDR_W);
-}
-
-/**
- * nand_read_buf - [DEFAULT] read chip data into buffer
- * @mtd:       MTD device structure
- * @buf:       buffer to store date
- * @len:       number of bytes to read
- *
- * Default read function for 8bit buswith
- */
-static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
-{
-       int i;
-       struct nand_chip *this = mtd->priv;
-
-       for (i=0; i<len; i++)
-               buf[i] = readb(this->IO_ADDR_R);
-}
-
-/**
- * nand_verify_buf - [DEFAULT] Verify chip data against buffer
- * @mtd:       MTD device structure
- * @buf:       buffer containing the data to compare
- * @len:       number of bytes to compare
- *
- * Default verify function for 8bit buswith
- */
-static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
-       int i;
-       struct nand_chip *this = mtd->priv;
-
-       for (i=0; i<len; i++)
-               if (buf[i] != readb(this->IO_ADDR_R))
-                       return -EFAULT;
-
-       return 0;
-}
-
-/**
- * nand_write_buf16 - [DEFAULT] write buffer to chip
- * @mtd:       MTD device structure
- * @buf:       data buffer
- * @len:       number of bytes to write
- *
- * Default write function for 16bit buswith
- */
-static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
-{
-       int i;
-       struct nand_chip *this = mtd->priv;
-       u16 *p = (u16 *) buf;
-       len >>= 1;
-
-       for (i=0; i<len; i++)
-               writew(p[i], this->IO_ADDR_W);
-
-}
-
-/**
- * nand_read_buf16 - [DEFAULT] read chip data into buffer
- * @mtd:       MTD device structure
- * @buf:       buffer to store date
- * @len:       number of bytes to read
- *
- * Default read function for 16bit buswith
- */
-static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
-{
-       int i;
-       struct nand_chip *this = mtd->priv;
-       u16 *p = (u16 *) buf;
-       len >>= 1;
-
-       for (i=0; i<len; i++)
-               p[i] = readw(this->IO_ADDR_R);
-}
-
-/**
- * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
- * @mtd:       MTD device structure
- * @buf:       buffer containing the data to compare
- * @len:       number of bytes to compare
- *
- * Default verify function for 16bit buswith
- */
-static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
-{
-       int i;
-       struct nand_chip *this = mtd->priv;
-       u16 *p = (u16 *) buf;
-       len >>= 1;
-
-       for (i=0; i<len; i++)
-               if (p[i] != readw(this->IO_ADDR_R))
-                       return -EFAULT;
-
-       return 0;
-}
-
-/**
- * nand_block_bad - [DEFAULT] Read bad block marker from the chip
- * @mtd:       MTD device structure
- * @ofs:       offset from device start
- * @getchip:   0, if the chip is already selected
- *
- * Check, if the block is bad.
- */
-static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
-{
-       int page, chipnr, res = 0;
-       struct nand_chip *this = mtd->priv;
-       u16 bad;
-
-       page = (int)(ofs >> this->page_shift) & this->pagemask;
-
-       if (getchip) {
-               chipnr = (int)(ofs >> this->chip_shift);
-
-               /* Grab the lock and see if the device is available */
-               nand_get_device (this, mtd, FL_READING);
-
-               /* Select the NAND device */
-               this->select_chip(mtd, chipnr);
-       }
-
-       if (this->options & NAND_BUSWIDTH_16) {
-               this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page);
-               bad = cpu_to_le16(this->read_word(mtd));
-               if (this->badblockpos & 0x1)
-                       bad >>= 1;
-               if ((bad & 0xFF) != 0xff)
-                       res = 1;
-       } else {
-               this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos, page);
-               if (this->read_byte(mtd) != 0xff)
-                       res = 1;
-       }
-
-       if (getchip) {
-               /* Deselect and wake up anyone waiting on the device */
-               nand_release_device(mtd);
-       }
-
-       return res;
-}
-
-/**
- * nand_default_block_markbad - [DEFAULT] mark a block bad
- * @mtd:       MTD device structure
- * @ofs:       offset from device start
- *
- * This is the default implementation, which can be overridden by
- * a hardware specific driver.
-*/
-static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
-{
-       struct nand_chip *this = mtd->priv;
-       u_char buf[2] = {0, 0};
-       size_t  retlen;
-       int block;
-
-       /* Get block number */
-       block = ((int) ofs) >> this->bbt_erase_shift;
-       this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
-
-       /* Do we have a flash based bad block table ? */
-       if (this->options & NAND_USE_FLASH_BBT)
-               return nand_update_bbt (mtd, ofs);
-
-       /* We write two bytes, so we dont have to mess with 16 bit access */
-       ofs += mtd->oobsize + (this->badblockpos & ~0x01);
-       return nand_write_oob (mtd, ofs , 2, &retlen, buf);
-}
-
-/**
- * nand_check_wp - [GENERIC] check if the chip is write protected
- * @mtd:       MTD device structure
- * Check, if the device is write protected
- *
- * The function expects, that the device is already selected
- */
-static int nand_check_wp (struct mtd_info *mtd)
-{
-       struct nand_chip *this = mtd->priv;
-       /* Check the WP bit */
-       this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
-       return (this->read_byte(mtd) & 0x80) ? 0 : 1;
-}
-
-/**
- * nand_block_checkbad - [GENERIC] Check if a block is marked bad
- * @mtd:       MTD device structure
- * @ofs:       offset from device start
- * @getchip:   0, if the chip is already selected
- * @allowbbt:  1, if its allowed to access the bbt area
- *
- * Check, if the block is bad. Either by reading the bad block table or
- * calling of the scan function.
- */
-static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
-{
-       struct nand_chip *this = mtd->priv;
-
-       if (!this->bbt)
-               return this->block_bad(mtd, ofs, getchip);
-
-       /* Return info from the table */
-       return nand_isbad_bbt (mtd, ofs, allowbbt);
-}
-
-/**
- * nand_command - [DEFAULT] Send command to NAND device
- * @mtd:       MTD device structure
- * @command:   the command to be sent
- * @column:    the column address for this command, -1 if none
- * @page_addr: the page address for this command, -1 if none
- *
- * Send command to NAND device. This function is used for small page
- * devices (256/512 Bytes per page)
- */
-static void nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
-{
-       register struct nand_chip *this = mtd->priv;
-
-       /* Begin command latch cycle */
-       this->hwcontrol(mtd, NAND_CTL_SETCLE);
-       /*
-        * Write out the command to the device.
-        */
-       if (command == NAND_CMD_SEQIN) {
-               int readcmd;
-
-               if (column >= mtd->oobblock) {
-                       /* OOB area */
-                       column -= mtd->oobblock;
-                       readcmd = NAND_CMD_READOOB;
-               } else if (column < 256) {
-                       /* First 256 bytes --> READ0 */
-                       readcmd = NAND_CMD_READ0;
-               } else {
-                       column -= 256;
-                       readcmd = NAND_CMD_READ1;
-               }
-               this->write_byte(mtd, readcmd);
-       }
-       this->write_byte(mtd, command);
-
-       /* Set ALE and clear CLE to start address cycle */
-       this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-
-       if (column != -1 || page_addr != -1) {
-               this->hwcontrol(mtd, NAND_CTL_SETALE);
-
-               /* Serially input address */
-               if (column != -1) {
-                       /* Adjust columns for 16 bit buswidth */
-                       if (this->options & NAND_BUSWIDTH_16)
-                               column >>= 1;
-                       this->write_byte(mtd, column);
-               }
-               if (page_addr != -1) {
-                       this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
-                       this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
-                       /* One more address cycle for devices > 32MiB */
-                       if (this->chipsize > (32 << 20))
-                               this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
-               }
-               /* Latch in address */
-               this->hwcontrol(mtd, NAND_CTL_CLRALE);
-       }
-
-       /*
-        * program and erase have their own busy handlers
-        * status and sequential in needs no delay
-       */
-       switch (command) {
-
-       case NAND_CMD_PAGEPROG:
-       case NAND_CMD_ERASE1:
-       case NAND_CMD_ERASE2:
-       case NAND_CMD_SEQIN:
-       case NAND_CMD_STATUS:
-               return;
-
-       case NAND_CMD_RESET:
-               if (this->dev_ready)
-                       break;
-               udelay(this->chip_delay);
-               this->hwcontrol(mtd, NAND_CTL_SETCLE);
-               this->write_byte(mtd, NAND_CMD_STATUS);
-               this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-               while ( !(this->read_byte(mtd) & 0x40));
-               return;
-
-       /* This applies to read commands */
-       default:
-               /*
-                * If we don't have access to the busy pin, we apply the given
-                * command delay
-               */
-               if (!this->dev_ready) {
-                       udelay (this->chip_delay);
-                       return;
-               }
-       }
-
-       /* Apply this short delay always to ensure that we do wait tWB in
-        * any case on any machine. */
-       ndelay (100);
-       /* wait until command is processed */
-       while (!this->dev_ready(mtd));
-}
-
-/**
- * nand_command_lp - [DEFAULT] Send command to NAND large page device
- * @mtd:       MTD device structure
- * @command:   the command to be sent
- * @column:    the column address for this command, -1 if none
- * @page_addr: the page address for this command, -1 if none
- *
- * Send command to NAND device. This is the version for the new large page devices
- * We dont have the seperate regions as we have in the small page devices.
- * We must emulate NAND_CMD_READOOB to keep the code compatible.
- *
- */
-static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, int page_addr)
-{
-       register struct nand_chip *this = mtd->priv;
-
-       /* Emulate NAND_CMD_READOOB */
-       if (command == NAND_CMD_READOOB) {
-               column += mtd->oobblock;
-               command = NAND_CMD_READ0;
-       }
-
-
-       /* Begin command latch cycle */
-       this->hwcontrol(mtd, NAND_CTL_SETCLE);
-       /* Write out the command to the device. */
-       this->write_byte(mtd, command);
-       /* End command latch cycle */
-       this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-
-       if (column != -1 || page_addr != -1) {
-               this->hwcontrol(mtd, NAND_CTL_SETALE);
-
-               /* Serially input address */
-               if (column != -1) {
-                       /* Adjust columns for 16 bit buswidth */
-                       if (this->options & NAND_BUSWIDTH_16)
-                               column >>= 1;
-                       this->write_byte(mtd, column & 0xff);
-                       this->write_byte(mtd, column >> 8);
-               }
-               if (page_addr != -1) {
-                       this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
-                       this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
-                       /* One more address cycle for devices > 128MiB */
-                       if (this->chipsize > (128 << 20))
-                               this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0xff));
-               }
-               /* Latch in address */
-               this->hwcontrol(mtd, NAND_CTL_CLRALE);
-       }
-
-       /*
-        * program and erase have their own busy handlers
-        * status and sequential in needs no delay
-       */
-       switch (command) {
-
-       case NAND_CMD_CACHEDPROG:
-       case NAND_CMD_PAGEPROG:
-       case NAND_CMD_ERASE1:
-       case NAND_CMD_ERASE2:
-       case NAND_CMD_SEQIN:
-       case NAND_CMD_STATUS:
-               return;
-
-
-       case NAND_CMD_RESET:
-               if (this->dev_ready)
-                       break;
-               udelay(this->chip_delay);
-               this->hwcontrol(mtd, NAND_CTL_SETCLE);
-               this->write_byte(mtd, NAND_CMD_STATUS);
-               this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-               while ( !(this->read_byte(mtd) & 0x40));
-               return;
-
-       case NAND_CMD_READ0:
-               /* Begin command latch cycle */
-               this->hwcontrol(mtd, NAND_CTL_SETCLE);
-               /* Write out the start read command */
-               this->write_byte(mtd, NAND_CMD_READSTART);
-               /* End command latch cycle */
-               this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-               /* Fall through into ready check */
-
-       /* This applies to read commands */
-       default:
-               /*
-                * If we don't have access to the busy pin, we apply the given
-                * command delay
-               */
-               if (!this->dev_ready) {
-                       udelay (this->chip_delay);
-                       return;
-               }
-       }
-
-       /* Apply this short delay always to ensure that we do wait tWB in
-        * any case on any machine. */
-       ndelay (100);
-       /* wait until command is processed */
-       while (!this->dev_ready(mtd));
-}
-
-/**
- * nand_get_device - [GENERIC] Get chip for selected access
- * @this:      the nand chip descriptor
- * @mtd:       MTD device structure
- * @new_state: the state which is requested
- *
- * Get the device and lock it for exclusive access
- */
-/* XXX U-BOOT XXX */
-#if 0
-static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
-{
-       struct nand_chip *active = this;
-
-       DECLARE_WAITQUEUE (wait, current);
-
-       /*
-        * Grab the lock and see if the device is available
-       */
-retry:
-       /* Hardware controller shared among independend devices */
-       if (this->controller) {
-               spin_lock (&this->controller->lock);
-               if (this->controller->active)
-                       active = this->controller->active;
-               else
-                       this->controller->active = this;
-               spin_unlock (&this->controller->lock);
-       }
-
-       if (active == this) {
-               spin_lock (&this->chip_lock);
-               if (this->state == FL_READY) {
-                       this->state = new_state;
-                       spin_unlock (&this->chip_lock);
-                       return;
-               }
-       }
-       set_current_state (TASK_UNINTERRUPTIBLE);
-       add_wait_queue (&active->wq, &wait);
-       spin_unlock (&active->chip_lock);
-       schedule ();
-       remove_wait_queue (&active->wq, &wait);
-       goto retry;
-}
-#else
-static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state) {}
-#endif
-
-/**
- * nand_wait - [DEFAULT]  wait until the command is done
- * @mtd:       MTD device structure
- * @this:      NAND chip structure
- * @state:     state to select the max. timeout value
- *
- * Wait for command done. This applies to erase and program only
- * Erase can take up to 400ms and program up to 20ms according to
- * general NAND and SmartMedia specs
- *
-*/
-/* XXX U-BOOT XXX */
-#if 0
-static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
-{
-       unsigned long   timeo = jiffies;
-       int     status;
-
-       if (state == FL_ERASING)
-                timeo += (HZ * 400) / 1000;
-       else
-                timeo += (HZ * 20) / 1000;
-
-       /* Apply this short delay always to ensure that we do wait tWB in
-        * any case on any machine. */
-       ndelay (100);
-
-       if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
-               this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1);
-       else
-               this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
-
-       while (time_before(jiffies, timeo)) {
-               /* Check, if we were interrupted */
-               if (this->state != state)
-                       return 0;
-
-               if (this->dev_ready) {
-                       if (this->dev_ready(mtd))
-                               break;
-               } else {
-                       if (this->read_byte(mtd) & NAND_STATUS_READY)
-                               break;
-               }
-               yield ();
-       }
-       status = (int) this->read_byte(mtd);
-       return status;
-
-       return 0;
-}
-#else
-static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
-{
-       unsigned long   timeo;
-
-       if (state == FL_ERASING)
-               timeo = (CFG_HZ * 400) / 1000;
-       else
-               timeo = (CFG_HZ * 20) / 1000;
-
-       if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
-               this->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1);
-       else
-               this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
-
-       reset_timer();
-
-       while (1) {
-               if (get_timer(0) > timeo) {
-                       printf("Timeout!");
-                       return 0x01;
-               }
-
-               if (this->dev_ready) {
-                       if (this->dev_ready(mtd))
-                               break;
-               } else {
-                       if (this->read_byte(mtd) & NAND_STATUS_READY)
-                               break;
-               }
-       }
-#ifdef PPCHAMELON_NAND_TIMER_HACK
-       reset_timer();
-       while (get_timer(0) < 10);
-#endif /*  PPCHAMELON_NAND_TIMER_HACK */
-
-       return this->read_byte(mtd);
-}
-#endif
-
-/**
- * nand_write_page - [GENERIC] write one page
- * @mtd:       MTD device structure
- * @this:      NAND chip structure
- * @page:      startpage inside the chip, must be called with (page & this->pagemask)
- * @oob_buf:   out of band data buffer
- * @oobsel:    out of band selecttion structre
- * @cached:    1 = enable cached programming if supported by chip
- *
- * Nand_page_program function is used for write and writev !
- * This function will always program a full page of data
- * If you call it with a non page aligned buffer, you're lost :)
- *
- * Cached programming is not supported yet.
- */
-static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page,
-       u_char *oob_buf,  struct nand_oobinfo *oobsel, int cached)
-{
-       int     i, status;
-       u_char  ecc_code[32];
-       int     eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
-       uint    *oob_config = oobsel->eccpos;
-       int     datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
-       int     eccbytes = 0;
-
-       /* FIXME: Enable cached programming */
-       cached = 0;
-
-       /* Send command to begin auto page programming */
-       this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page);
-
-       /* Write out complete page of data, take care of eccmode */
-       switch (eccmode) {
-       /* No ecc, write all */
-       case NAND_ECC_NONE:
-               printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n");
-               this->write_buf(mtd, this->data_poi, mtd->oobblock);
-               break;
-
-       /* Software ecc 3/256, write all */
-       case NAND_ECC_SOFT:
-               for (; eccsteps; eccsteps--) {
-                       this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
-                       for (i = 0; i < 3; i++, eccidx++)
-                               oob_buf[oob_config[eccidx]] = ecc_code[i];
-                       datidx += this->eccsize;
-               }
-               this->write_buf(mtd, this->data_poi, mtd->oobblock);
-               break;
-       default:
-               eccbytes = this->eccbytes;
-               for (; eccsteps; eccsteps--) {
-                       /* enable hardware ecc logic for write */
-                       this->enable_hwecc(mtd, NAND_ECC_WRITE);
-                       this->write_buf(mtd, &this->data_poi[datidx], this->eccsize);
-                       this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
-                       for (i = 0; i < eccbytes; i++, eccidx++)
-                               oob_buf[oob_config[eccidx]] = ecc_code[i];
-                       /* If the hardware ecc provides syndromes then
-                        * the ecc code must be written immidiately after
-                        * the data bytes (words) */
-                       if (this->options & NAND_HWECC_SYNDROME)
-                               this->write_buf(mtd, ecc_code, eccbytes);
-                       datidx += this->eccsize;
-               }
-               break;
-       }
-
-       /* Write out OOB data */
-       if (this->options & NAND_HWECC_SYNDROME)
-               this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes);
-       else
-               this->write_buf(mtd, oob_buf, mtd->oobsize);
-
-       /* Send command to actually program the data */
-       this->cmdfunc (mtd, cached ? NAND_CMD_CACHEDPROG : NAND_CMD_PAGEPROG, -1, -1);
-
-       if (!cached) {
-               /* call wait ready function */
-               status = this->waitfunc (mtd, this, FL_WRITING);
-               /* See if device thinks it succeeded */
-               if (status & 0x01) {
-                       DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write, page 0x%08x, ", __FUNCTION__, page);
-                       return -EIO;
-               }
-       } else {
-               /* FIXME: Implement cached programming ! */
-               /* wait until cache is ready*/
-               /* status = this->waitfunc (mtd, this, FL_CACHEDRPG); */
-       }
-       return 0;
-}
-
-#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
-/**
- * nand_verify_pages - [GENERIC] verify the chip contents after a write
- * @mtd:       MTD device structure
- * @this:      NAND chip structure
- * @page:      startpage inside the chip, must be called with (page & this->pagemask)
- * @numpages:  number of pages to verify
- * @oob_buf:   out of band data buffer
- * @oobsel:    out of band selecttion structre
- * @chipnr:    number of the current chip
- * @oobmode:   1 = full buffer verify, 0 = ecc only
- *
- * The NAND device assumes that it is always writing to a cleanly erased page.
- * Hence, it performs its internal write verification only on bits that
- * transitioned from 1 to 0. The device does NOT verify the whole page on a
- * byte by byte basis. It is possible that the page was not completely erased
- * or the page is becoming unusable due to wear. The read with ECC would catch
- * the error later when the ECC page check fails, but we would rather catch
- * it early in the page write stage. Better to write no data than invalid data.
- */
-static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
-       u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode)
-{
-       int     i, j, datidx = 0, oobofs = 0, res = -EIO;
-       int     eccsteps = this->eccsteps;
-       int     hweccbytes;
-       u_char  oobdata[64];
-
-       hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0;
-
-       /* Send command to read back the first page */
-       this->cmdfunc (mtd, NAND_CMD_READ0, 0, page);
-
-       for(;;) {
-               for (j = 0; j < eccsteps; j++) {
-                       /* Loop through and verify the data */
-                       if (this->verify_buf(mtd, &this->data_poi[datidx], mtd->eccsize)) {
-                               DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
-                               goto out;
-                       }
-                       datidx += mtd->eccsize;
-                       /* Have we a hw generator layout ? */
-                       if (!hweccbytes)
-                               continue;
-                       if (this->verify_buf(mtd, &this->oob_buf[oobofs], hweccbytes)) {
-                               DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
-                               goto out;
-                       }
-                       oobofs += hweccbytes;
-               }
-
-               /* check, if we must compare all data or if we just have to
-                * compare the ecc bytes
-                */
-               if (oobmode) {
-                       if (this->verify_buf(mtd, &oob_buf[oobofs], mtd->oobsize - hweccbytes * eccsteps)) {
-                               DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
-                               goto out;
-                       }
-               } else {
-                       /* Read always, else autoincrement fails */
-                       this->read_buf(mtd, oobdata, mtd->oobsize - hweccbytes * eccsteps);
-
-                       if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) {
-                               int ecccnt = oobsel->eccbytes;
-
-                               for (i = 0; i < ecccnt; i++) {
-                                       int idx = oobsel->eccpos[i];
-                                       if (oobdata[idx] != oob_buf[oobofs + idx] ) {
-                                               DEBUG (MTD_DEBUG_LEVEL0,
-                                               "%s: Failed ECC write "
-                                               "verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i);
-                                               goto out;
-                                       }
-                               }
-                       }
-               }
-               oobofs += mtd->oobsize - hweccbytes * eccsteps;
-               page++;
-               numpages--;
-
-               /* Apply delay or wait for ready/busy pin
-                * Do this before the AUTOINCR check, so no problems
-                * arise if a chip which does auto increment
-                * is marked as NOAUTOINCR by the board driver.
-                * Do this also before returning, so the chip is
-                * ready for the next command.
-               */
-               if (!this->dev_ready)
-                       udelay (this->chip_delay);
-               else
-                       while (!this->dev_ready(mtd));
-
-               /* All done, return happy */
-               if (!numpages)
-                       return 0;
-
-
-               /* Check, if the chip supports auto page increment */
-               if (!NAND_CANAUTOINCR(this))
-                       this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
-       }
-       /*
-        * Terminate the read command. We come here in case of an error
-        * So we must issue a reset command.
-        */
-out:
-       this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1);
-       return res;
-}
-#endif
-
-/**
- * nand_read - [MTD Interface] MTD compability function for nand_read_ecc
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @len:       number of bytes to read
- * @retlen:    pointer to variable to store the number of read bytes
- * @buf:       the databuffer to put data
- *
- * This function simply calls nand_read_ecc with oob buffer and oobsel = NULL
-*/
-static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
-{
-       return nand_read_ecc (mtd, from, len, retlen, buf, NULL, NULL);
-}
-
-
-/**
- * nand_read_ecc - [MTD Interface] Read data with ECC
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @len:       number of bytes to read
- * @retlen:    pointer to variable to store the number of read bytes
- * @buf:       the databuffer to put data
- * @oob_buf:   filesystem supplied oob data buffer
- * @oobsel:    oob selection structure
- *
- * NAND read with ECC
- */
-static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
-                         size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel)
-{
-       int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1;
-       int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0;
-       struct nand_chip *this = mtd->priv;
-       u_char *data_poi, *oob_data = oob_buf;
-       u_char ecc_calc[32];
-       u_char ecc_code[32];
-       int eccmode, eccsteps;
-       unsigned *oob_config;
-       int     datidx;
-       int     blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
-       int     eccbytes;
-       int     compareecc = 1;
-       int     oobreadlen;
-
-
-       DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
-
-       /* Do not allow reads past end of device */
-       if ((from + len) > mtd->size) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: Attempt read beyond end of device\n");
-               *retlen = 0;
-               return -EINVAL;
-       }
-
-       /* Grab the lock and see if the device is available */
-       nand_get_device (this, mtd ,FL_READING);
-
-       /* use userspace supplied oobinfo, if zero */
-       if (oobsel == NULL)
-               oobsel = &mtd->oobinfo;
-
-       /* Autoplace of oob data ? Use the default placement scheme */
-       if (oobsel->useecc == MTD_NANDECC_AUTOPLACE)
-               oobsel = this->autooob;
-
-       eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
-       oob_config = oobsel->eccpos;
-
-       /* Select the NAND device */
-       chipnr = (int)(from >> this->chip_shift);
-       this->select_chip(mtd, chipnr);
-
-       /* First we calculate the starting page */
-       realpage = (int) (from >> this->page_shift);
-       page = realpage & this->pagemask;
-
-       /* Get raw starting column */
-       col = from & (mtd->oobblock - 1);
-
-       end = mtd->oobblock;
-       ecc = this->eccsize;
-       eccbytes = this->eccbytes;
-
-       if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
-               compareecc = 0;
-
-       oobreadlen = mtd->oobsize;
-       if (this->options & NAND_HWECC_SYNDROME)
-               oobreadlen -= oobsel->eccbytes;
-
-       /* Loop until all data read */
-       while (read < len) {
-
-               int aligned = (!col && (len - read) >= end);
-               /*
-                * If the read is not page aligned, we have to read into data buffer
-                * due to ecc, else we read into return buffer direct
-                */
-               if (aligned)
-                       data_poi = &buf[read];
-               else
-                       data_poi = this->data_buf;
-
-               /* Check, if we have this page in the buffer
-                *
-                * FIXME: Make it work when we must provide oob data too,
-                * check the usage of data_buf oob field
-                */
-               if (realpage == this->pagebuf && !oob_buf) {
-                       /* aligned read ? */
-                       if (aligned)
-                               memcpy (data_poi, this->data_buf, end);
-                       goto readdata;
-               }
-
-               /* Check, if we must send the read command */
-               if (sndcmd) {
-                       this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
-                       sndcmd = 0;
-               }
-
-               /* get oob area, if we have no oob buffer from fs-driver */
-               if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE ||
-                       oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
-                       oob_data = &this->data_buf[end];
-
-               eccsteps = this->eccsteps;
-
-               switch (eccmode) {
-               case NAND_ECC_NONE: {   /* No ECC, Read in a page */
-/* XXX U-BOOT XXX */
-#if 0
-                       static unsigned long lastwhinge = 0;
-                       if ((lastwhinge / HZ) != (jiffies / HZ)) {
-                               printk (KERN_WARNING "Reading data from NAND FLASH without ECC is not recommended\n");
-                               lastwhinge = jiffies;
-                       }
-#else
-                       puts("Reading data from NAND FLASH without ECC is not recommended\n");
-#endif
-                       this->read_buf(mtd, data_poi, end);
-                       break;
-               }
-
-               case NAND_ECC_SOFT:     /* Software ECC 3/256: Read in a page + oob data */
-                       this->read_buf(mtd, data_poi, end);
-                       for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc)
-                               this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
-                       break;
-
-               default:
-                       for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) {
-                               this->enable_hwecc(mtd, NAND_ECC_READ);
-                               this->read_buf(mtd, &data_poi[datidx], ecc);
-
-                               /* HW ecc with syndrome calculation must read the
-                                * syndrome from flash immidiately after the data */
-                               if (!compareecc) {
-                                       /* Some hw ecc generators need to know when the
-                                        * syndrome is read from flash */
-                                       this->enable_hwecc(mtd, NAND_ECC_READSYN);
-                                       this->read_buf(mtd, &oob_data[i], eccbytes);
-                                       /* We calc error correction directly, it checks the hw
-                                        * generator for an error, reads back the syndrome and
-                                        * does the error correction on the fly */
-                                       if (this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]) == -1) {
-                                               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
-                                                       "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
-                                               ecc_failed++;
-                                       }
-                               } else {
-                                       this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
-                               }
-                       }
-                       break;
-               }
-
-               /* read oobdata */
-               this->read_buf(mtd, &oob_data[mtd->oobsize - oobreadlen], oobreadlen);
-
-               /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */
-               if (!compareecc)
-                       goto readoob;
-
-               /* Pick the ECC bytes out of the oob data */
-               for (j = 0; j < oobsel->eccbytes; j++)
-                       ecc_code[j] = oob_data[oob_config[j]];
-
-               /* correct data, if neccecary */
-               for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) {
-                       ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]);
-
-                       /* Get next chunk of ecc bytes */
-                       j += eccbytes;
-
-                       /* Check, if we have a fs supplied oob-buffer,
-                        * This is the legacy mode. Used by YAFFS1
-                        * Should go away some day
-                        */
-                       if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) {
-                               int *p = (int *)(&oob_data[mtd->oobsize]);
-                               p[i] = ecc_status;
-                       }
-
-                       if (ecc_status == -1) {
-                               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
-                               ecc_failed++;
-                       }
-               }
-
-       readoob:
-               /* check, if we have a fs supplied oob-buffer */
-               if (oob_buf) {
-                       /* without autoplace. Legacy mode used by YAFFS1 */
-                       switch(oobsel->useecc) {
-                       case MTD_NANDECC_AUTOPLACE:
-                       case MTD_NANDECC_AUTOPL_USR:
-                               /* Walk through the autoplace chunks */
-                               for (i = 0, j = 0; j < mtd->oobavail; i++) {
-                                       int from = oobsel->oobfree[i][0];
-                                       int num = oobsel->oobfree[i][1];
-                                       memcpy(&oob_buf[oob], &oob_data[from], num);
-                                       j+= num;
-                               }
-                               oob += mtd->oobavail;
-                               break;
-                       case MTD_NANDECC_PLACE:
-                               /* YAFFS1 legacy mode */
-                               oob_data += this->eccsteps * sizeof (int);
-                       default:
-                               oob_data += mtd->oobsize;
-                       }
-               }
-       readdata:
-               /* Partial page read, transfer data into fs buffer */
-               if (!aligned) {
-                       for (j = col; j < end && read < len; j++)
-                               buf[read++] = data_poi[j];
-                       this->pagebuf = realpage;
-               } else
-                       read += mtd->oobblock;
-
-               /* Apply delay or wait for ready/busy pin
-                * Do this before the AUTOINCR check, so no problems
-                * arise if a chip which does auto increment
-                * is marked as NOAUTOINCR by the board driver.
-               */
-               if (!this->dev_ready)
-                       udelay (this->chip_delay);
-               else
-                       while (!this->dev_ready(mtd));
-
-               if (read == len)
-                       break;
-
-               /* For subsequent reads align to page boundary. */
-               col = 0;
-               /* Increment page address */
-               realpage++;
-
-               page = realpage & this->pagemask;
-               /* Check, if we cross a chip boundary */
-               if (!page) {
-                       chipnr++;
-                       this->select_chip(mtd, -1);
-                       this->select_chip(mtd, chipnr);
-               }
-               /* Check, if the chip supports auto page increment
-                * or if we have hit a block boundary.
-               */
-               if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
-                       sndcmd = 1;
-       }
-
-       /* Deselect and wake up anyone waiting on the device */
-       nand_release_device(mtd);
-
-       /*
-        * Return success, if no ECC failures, else -EBADMSG
-        * fs driver will take care of that, because
-        * retlen == desired len and result == -EBADMSG
-        */
-       *retlen = read;
-       return ecc_failed ? -EBADMSG : 0;
-}
-
-/**
- * nand_read_oob - [MTD Interface] NAND read out-of-band
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @len:       number of bytes to read
- * @retlen:    pointer to variable to store the number of read bytes
- * @buf:       the databuffer to put data
- *
- * NAND read out-of-band data from the spare area
- */
-static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
-{
-       int i, col, page, chipnr;
-       struct nand_chip *this = mtd->priv;
-       int     blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
-
-       DEBUG (MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
-
-       /* Shift to get page */
-       page = (int)(from >> this->page_shift);
-       chipnr = (int)(from >> this->chip_shift);
-
-       /* Mask to get column */
-       col = from & (mtd->oobsize - 1);
-
-       /* Initialize return length value */
-       *retlen = 0;
-
-       /* Do not allow reads past end of device */
-       if ((from + len) > mtd->size) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: Attempt read beyond end of device\n");
-               *retlen = 0;
-               return -EINVAL;
-       }
-
-       /* Grab the lock and see if the device is available */
-       nand_get_device (this, mtd , FL_READING);
-
-       /* Select the NAND device */
-       this->select_chip(mtd, chipnr);
-
-       /* Send the read command */
-       this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask);
-       /*
-        * Read the data, if we read more than one page
-        * oob data, let the device transfer the data !
-        */
-       i = 0;
-       while (i < len) {
-               int thislen = mtd->oobsize - col;
-               thislen = min_t(int, thislen, len);
-               this->read_buf(mtd, &buf[i], thislen);
-               i += thislen;
-
-               /* Apply delay or wait for ready/busy pin
-                * Do this before the AUTOINCR check, so no problems
-                * arise if a chip which does auto increment
-                * is marked as NOAUTOINCR by the board driver.
-               */
-               if (!this->dev_ready)
-                       udelay (this->chip_delay);
-               else
-                       while (!this->dev_ready(mtd));
-
-               /* Read more ? */
-               if (i < len) {
-                       page++;
-                       col = 0;
-
-                       /* Check, if we cross a chip boundary */
-                       if (!(page & this->pagemask)) {
-                               chipnr++;
-                               this->select_chip(mtd, -1);
-                               this->select_chip(mtd, chipnr);
-                       }
-
-                       /* Check, if the chip supports auto page increment
-                        * or if we have hit a block boundary.
-                       */
-                       if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) {
-                               /* For subsequent page reads set offset to 0 */
-                               this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
-                       }
-               }
-       }
-
-       /* Deselect and wake up anyone waiting on the device */
-       nand_release_device(mtd);
-
-       /* Return happy */
-       *retlen = len;
-       return 0;
-}
-
-/**
- * nand_read_raw - [GENERIC] Read raw data including oob into buffer
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @from:      offset to read from
- * @len:       number of bytes to read
- * @ooblen:    number of oob data bytes to read
- *
- * Read raw data including oob into buffer
- */
-int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen)
-{
-       struct nand_chip *this = mtd->priv;
-       int page = (int) (from >> this->page_shift);
-       int chip = (int) (from >> this->chip_shift);
-       int sndcmd = 1;
-       int cnt = 0;
-       int pagesize = mtd->oobblock + mtd->oobsize;
-       int     blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
-
-       /* Do not allow reads past end of device */
-       if ((from + len) > mtd->size) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_read_raw: Attempt read beyond end of device\n");
-               return -EINVAL;
-       }
-
-       /* Grab the lock and see if the device is available */
-       nand_get_device (this, mtd , FL_READING);
-
-       this->select_chip (mtd, chip);
-
-       /* Add requested oob length */
-       len += ooblen;
-
-       while (len) {
-               if (sndcmd)
-                       this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask);
-               sndcmd = 0;
-
-               this->read_buf (mtd, &buf[cnt], pagesize);
-
-               len -= pagesize;
-               cnt += pagesize;
-               page++;
-
-               if (!this->dev_ready)
-                       udelay (this->chip_delay);
-               else
-                       while (!this->dev_ready(mtd));
-
-               /* Check, if the chip supports auto page increment */
-               if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
-                       sndcmd = 1;
-       }
-
-       /* Deselect and wake up anyone waiting on the device */
-       nand_release_device(mtd);
-       return 0;
-}
-
-
-/**
- * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer
- * @mtd:       MTD device structure
- * @fsbuf:     buffer given by fs driver
- * @oobsel:    out of band selection structre
- * @autoplace: 1 = place given buffer into the oob bytes
- * @numpages:  number of pages to prepare
- *
- * Return:
- * 1. Filesystem buffer available and autoplacement is off,
- *    return filesystem buffer
- * 2. No filesystem buffer or autoplace is off, return internal
- *    buffer
- * 3. Filesystem buffer is given and autoplace selected
- *    put data from fs buffer into internal buffer and
- *    retrun internal buffer
- *
- * Note: The internal buffer is filled with 0xff. This must
- * be done only once, when no autoplacement happens
- * Autoplacement sets the buffer dirty flag, which
- * forces the 0xff fill before using the buffer again.
- *
-*/
-static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct nand_oobinfo *oobsel,
-               int autoplace, int numpages)
-{
-       struct nand_chip *this = mtd->priv;
-       int i, len, ofs;
-
-       /* Zero copy fs supplied buffer */
-       if (fsbuf && !autoplace)
-               return fsbuf;
-
-       /* Check, if the buffer must be filled with ff again */
-       if (this->oobdirty) {
-               memset (this->oob_buf, 0xff,
-                       mtd->oobsize << (this->phys_erase_shift - this->page_shift));
-               this->oobdirty = 0;
-       }
-
-       /* If we have no autoplacement or no fs buffer use the internal one */
-       if (!autoplace || !fsbuf)
-               return this->oob_buf;
-
-       /* Walk through the pages and place the data */
-       this->oobdirty = 1;
-       ofs = 0;
-       while (numpages--) {
-               for (i = 0, len = 0; len < mtd->oobavail; i++) {
-                       int to = ofs + oobsel->oobfree[i][0];
-                       int num = oobsel->oobfree[i][1];
-                       memcpy (&this->oob_buf[to], fsbuf, num);
-                       len += num;
-                       fsbuf += num;
-               }
-               ofs += mtd->oobavail;
-       }
-       return this->oob_buf;
-}
-
-#define NOTALIGNED(x) (x & (mtd->oobblock-1)) != 0
-
-/**
- * nand_write - [MTD Interface] compability function for nand_write_ecc
- * @mtd:       MTD device structure
- * @to:                offset to write to
- * @len:       number of bytes to write
- * @retlen:    pointer to variable to store the number of written bytes
- * @buf:       the data to write
- *
- * This function simply calls nand_write_ecc with oob buffer and oobsel = NULL
- *
-*/
-static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
-{
-       return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL));
-}
-
-/**
- * nand_write_ecc - [MTD Interface] NAND write with ECC
- * @mtd:       MTD device structure
- * @to:                offset to write to
- * @len:       number of bytes to write
- * @retlen:    pointer to variable to store the number of written bytes
- * @buf:       the data to write
- * @eccbuf:    filesystem supplied oob data buffer
- * @oobsel:    oob selection structure
- *
- * NAND write with ECC
- */
-static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
-                          size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel)
-{
-       int startpage, page, ret = -EIO, oob = 0, written = 0, chipnr;
-       int autoplace = 0, numpages, totalpages;
-       struct nand_chip *this = mtd->priv;
-       u_char *oobbuf, *bufstart;
-       int     ppblock = (1 << (this->phys_erase_shift - this->page_shift));
-
-       DEBUG (MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
-
-       /* Initialize retlen, in case of early exit */
-       *retlen = 0;
-
-       /* Do not allow write past end of device */
-       if ((to + len) > mtd->size) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Attempt to write past end of page\n");
-               return -EINVAL;
-       }
-
-       /* reject writes, which are not page aligned */
-       if (NOTALIGNED (to) || NOTALIGNED(len)) {
-               printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
-               return -EINVAL;
-       }
-
-       /* Grab the lock and see if the device is available */
-       nand_get_device (this, mtd, FL_WRITING);
-
-       /* Calculate chipnr */
-       chipnr = (int)(to >> this->chip_shift);
-       /* Select the NAND device */
-       this->select_chip(mtd, chipnr);
-
-       /* Check, if it is write protected */
-       if (nand_check_wp(mtd))
-               goto out;
-
-       /* if oobsel is NULL, use chip defaults */
-       if (oobsel == NULL)
-               oobsel = &mtd->oobinfo;
-
-       /* Autoplace of oob data ? Use the default placement scheme */
-       if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
-               oobsel = this->autooob;
-               autoplace = 1;
-       }
-       if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
-               autoplace = 1;
-
-       /* Setup variables and oob buffer */
-       totalpages = len >> this->page_shift;
-       page = (int) (to >> this->page_shift);
-       /* Invalidate the page cache, if we write to the cached page */
-       if (page <= this->pagebuf && this->pagebuf < (page + totalpages))
-               this->pagebuf = -1;
-
-       /* Set it relative to chip */
-       page &= this->pagemask;
-       startpage = page;
-       /* Calc number of pages we can write in one go */
-       numpages = min (ppblock - (startpage  & (ppblock - 1)), totalpages);
-       oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, autoplace, numpages);
-       bufstart = (u_char *)buf;
-
-       /* Loop until all data is written */
-       while (written < len) {
-
-               this->data_poi = (u_char*) &buf[written];
-               /* Write one page. If this is the last page to write
-                * or the last page in this block, then use the
-                * real pageprogram command, else select cached programming
-                * if supported by the chip.
-                */
-               ret = nand_write_page (mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0));
-               if (ret) {
-                       DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret);
-                       goto out;
-               }
-               /* Next oob page */
-               oob += mtd->oobsize;
-               /* Update written bytes count */
-               written += mtd->oobblock;
-               if (written == len)
-                       goto cmp;
-
-               /* Increment page address */
-               page++;
-
-               /* Have we hit a block boundary ? Then we have to verify and
-                * if verify is ok, we have to setup the oob buffer for
-                * the next pages.
-               */
-               if (!(page & (ppblock - 1))){
-                       int ofs;
-                       this->data_poi = bufstart;
-                       ret = nand_verify_pages (mtd, this, startpage,
-                               page - startpage,
-                               oobbuf, oobsel, chipnr, (eccbuf != NULL));
-                       if (ret) {
-                               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
-                               goto out;
-                       }
-                       *retlen = written;
-                       bufstart = (u_char*) &buf[written];
-
-                       ofs = autoplace ? mtd->oobavail : mtd->oobsize;
-                       if (eccbuf)
-                               eccbuf += (page - startpage) * ofs;
-                       totalpages -= page - startpage;
-                       numpages = min (totalpages, ppblock);
-                       page &= this->pagemask;
-                       startpage = page;
-                       oob = 0;
-                       this->oobdirty = 1;
-                       oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel,
-                                       autoplace, numpages);
-                       /* Check, if we cross a chip boundary */
-                       if (!page) {
-                               chipnr++;
-                               this->select_chip(mtd, -1);
-                               this->select_chip(mtd, chipnr);
-                       }
-               }
-       }
-       /* Verify the remaining pages */
-cmp:
-       this->data_poi = bufstart;
-       ret = nand_verify_pages (mtd, this, startpage, totalpages,
-               oobbuf, oobsel, chipnr, (eccbuf != NULL));
-       if (!ret)
-               *retlen = written;
-       else
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
-
-out:
-       /* Deselect and wake up anyone waiting on the device */
-       nand_release_device(mtd);
-
-       return ret;
-}
-
-
-/**
- * nand_write_oob - [MTD Interface] NAND write out-of-band
- * @mtd:       MTD device structure
- * @to:                offset to write to
- * @len:       number of bytes to write
- * @retlen:    pointer to variable to store the number of written bytes
- * @buf:       the data to write
- *
- * NAND write out-of-band
- */
-static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
-{
-       int column, page, status, ret = -EIO, chipnr;
-       struct nand_chip *this = mtd->priv;
-
-       DEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
-
-       /* Shift to get page */
-       page = (int) (to >> this->page_shift);
-       chipnr = (int) (to >> this->chip_shift);
-
-       /* Mask to get column */
-       column = to & (mtd->oobsize - 1);
-
-       /* Initialize return length value */
-       *retlen = 0;
-
-       /* Do not allow write past end of page */
-       if ((column + len) > mtd->oobsize) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Attempt to write past end of page\n");
-               return -EINVAL;
-       }
-
-       /* Grab the lock and see if the device is available */
-       nand_get_device (this, mtd, FL_WRITING);
-
-       /* Select the NAND device */
-       this->select_chip(mtd, chipnr);
-
-       /* Reset the chip. Some chips (like the Toshiba TC5832DC found
-          in one of my DiskOnChip 2000 test units) will clear the whole
-          data page too if we don't do this. I have no clue why, but
-          I seem to have 'fixed' it in the doc2000 driver in
-          August 1999.  dwmw2. */
-       this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
-
-       /* Check, if it is write protected */
-       if (nand_check_wp(mtd))
-               goto out;
-
-       /* Invalidate the page cache, if we write to the cached page */
-       if (page == this->pagebuf)
-               this->pagebuf = -1;
-
-       if (NAND_MUST_PAD(this)) {
-               /* Write out desired data */
-               this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page & this->pagemask);
-               /* prepad 0xff for partial programming */
-               this->write_buf(mtd, ffchars, column);
-               /* write data */
-               this->write_buf(mtd, buf, len);
-               /* postpad 0xff for partial programming */
-               this->write_buf(mtd, ffchars, mtd->oobsize - (len+column));
-       } else {
-               /* Write out desired data */
-               this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock + column, page & this->pagemask);
-               /* write data */
-               this->write_buf(mtd, buf, len);
-       }
-       /* Send command to program the OOB data */
-       this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1);
-
-       status = this->waitfunc (mtd, this, FL_WRITING);
-
-       /* See if device thinks it succeeded */
-       if (status & 0x01) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08x\n", page);
-               ret = -EIO;
-               goto out;
-       }
-       /* Return happy */
-       *retlen = len;
-
-#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
-       /* Send command to read back the data */
-       this->cmdfunc (mtd, NAND_CMD_READOOB, column, page & this->pagemask);
-
-       if (this->verify_buf(mtd, buf, len)) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
-               ret = -EIO;
-               goto out;
-       }
-#endif
-       ret = 0;
-out:
-       /* Deselect and wake up anyone waiting on the device */
-       nand_release_device(mtd);
-
-       return ret;
-}
-
-/* XXX U-BOOT XXX */
-#if 0
-/**
- * nand_writev - [MTD Interface] compabilty function for nand_writev_ecc
- * @mtd:       MTD device structure
- * @vecs:      the iovectors to write
- * @count:     number of vectors
- * @to:                offset to write to
- * @retlen:    pointer to variable to store the number of written bytes
- *
- * NAND write with kvec. This just calls the ecc function
- */
-static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
-               loff_t to, size_t * retlen)
-{
-       return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL));
-}
-
-/**
- * nand_writev_ecc - [MTD Interface] write with iovec with ecc
- * @mtd:       MTD device structure
- * @vecs:      the iovectors to write
- * @count:     number of vectors
- * @to:                offset to write to
- * @retlen:    pointer to variable to store the number of written bytes
- * @eccbuf:    filesystem supplied oob data buffer
- * @oobsel:    oob selection structure
- *
- * NAND write with iovec with ecc
- */
-static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
-               loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel)
-{
-       int i, page, len, total_len, ret = -EIO, written = 0, chipnr;
-       int oob, numpages, autoplace = 0, startpage;
-       struct nand_chip *this = mtd->priv;
-       int     ppblock = (1 << (this->phys_erase_shift - this->page_shift));
-       u_char *oobbuf, *bufstart;
-
-       /* Preset written len for early exit */
-       *retlen = 0;
-
-       /* Calculate total length of data */
-       total_len = 0;
-       for (i = 0; i < count; i++)
-               total_len += (int) vecs[i].iov_len;
-
-       DEBUG (MTD_DEBUG_LEVEL3,
-              "nand_writev: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
-
-       /* Do not allow write past end of page */
-       if ((to + total_len) > mtd->size) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_writev: Attempted write past end of device\n");
-               return -EINVAL;
-       }
-
-       /* reject writes, which are not page aligned */
-       if (NOTALIGNED (to) || NOTALIGNED(total_len)) {
-               printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
-               return -EINVAL;
-       }
-
-       /* Grab the lock and see if the device is available */
-       nand_get_device (this, mtd, FL_WRITING);
-
-       /* Get the current chip-nr */
-       chipnr = (int) (to >> this->chip_shift);
-       /* Select the NAND device */
-       this->select_chip(mtd, chipnr);
-
-       /* Check, if it is write protected */
-       if (nand_check_wp(mtd))
-               goto out;
-
-       /* if oobsel is NULL, use chip defaults */
-       if (oobsel == NULL)
-               oobsel = &mtd->oobinfo;
-
-       /* Autoplace of oob data ? Use the default placement scheme */
-       if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
-               oobsel = this->autooob;
-               autoplace = 1;
-       }
-       if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
-               autoplace = 1;
-
-       /* Setup start page */
-       page = (int) (to >> this->page_shift);
-       /* Invalidate the page cache, if we write to the cached page */
-       if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift))
-               this->pagebuf = -1;
-
-       startpage = page & this->pagemask;
-
-       /* Loop until all kvec' data has been written */
-       len = 0;
-       while (count) {
-               /* If the given tuple is >= pagesize then
-                * write it out from the iov
-                */
-               if ((vecs->iov_len - len) >= mtd->oobblock) {
-                       /* Calc number of pages we can write
-                        * out of this iov in one go */
-                       numpages = (vecs->iov_len - len) >> this->page_shift;
-                       /* Do not cross block boundaries */
-                       numpages = min (ppblock - (startpage & (ppblock - 1)), numpages);
-                       oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
-                       bufstart = (u_char *)vecs->iov_base;
-                       bufstart += len;
-                       this->data_poi = bufstart;
-                       oob = 0;
-                       for (i = 1; i <= numpages; i++) {
-                               /* Write one page. If this is the last page to write
-                                * then use the real pageprogram command, else select
-                                * cached programming if supported by the chip.
-                                */
-                               ret = nand_write_page (mtd, this, page & this->pagemask,
-                                       &oobbuf[oob], oobsel, i != numpages);
-                               if (ret)
-                                       goto out;
-                               this->data_poi += mtd->oobblock;
-                               len += mtd->oobblock;
-                               oob += mtd->oobsize;
-                               page++;
-                       }
-                       /* Check, if we have to switch to the next tuple */
-                       if (len >= (int) vecs->iov_len) {
-                               vecs++;
-                               len = 0;
-                               count--;
-                       }
-               } else {
-                       /* We must use the internal buffer, read data out of each
-                        * tuple until we have a full page to write
-                        */
-                       int cnt = 0;
-                       while (cnt < mtd->oobblock) {
-                               if (vecs->iov_base != NULL && vecs->iov_len)
-                                       this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++];
-                               /* Check, if we have to switch to the next tuple */
-                               if (len >= (int) vecs->iov_len) {
-                                       vecs++;
-                                       len = 0;
-                                       count--;
-                               }
-                       }
-                       this->pagebuf = page;
-                       this->data_poi = this->data_buf;
-                       bufstart = this->data_poi;
-                       numpages = 1;
-                       oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
-                       ret = nand_write_page (mtd, this, page & this->pagemask,
-                               oobbuf, oobsel, 0);
-                       if (ret)
-                               goto out;
-                       page++;
-               }
-
-               this->data_poi = bufstart;
-               ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0);
-               if (ret)
-                       goto out;
-
-               written += mtd->oobblock * numpages;
-               /* All done ? */
-               if (!count)
-                       break;
-
-               startpage = page & this->pagemask;
-               /* Check, if we cross a chip boundary */
-               if (!startpage) {
-                       chipnr++;
-                       this->select_chip(mtd, -1);
-                       this->select_chip(mtd, chipnr);
-               }
-       }
-       ret = 0;
-out:
-       /* Deselect and wake up anyone waiting on the device */
-       nand_release_device(mtd);
-
-       *retlen = written;
-       return ret;
-}
-#endif
-
-/**
- * single_erease_cmd - [GENERIC] NAND standard block erase command function
- * @mtd:       MTD device structure
- * @page:      the page address of the block which will be erased
- *
- * Standard erase command for NAND chips
- */
-static void single_erase_cmd (struct mtd_info *mtd, int page)
-{
-       struct nand_chip *this = mtd->priv;
-       /* Send commands to erase a block */
-       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page);
-       this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1);
-}
-
-/**
- * multi_erease_cmd - [GENERIC] AND specific block erase command function
- * @mtd:       MTD device structure
- * @page:      the page address of the block which will be erased
- *
- * AND multi block erase command function
- * Erase 4 consecutive blocks
- */
-static void multi_erase_cmd (struct mtd_info *mtd, int page)
-{
-       struct nand_chip *this = mtd->priv;
-       /* Send commands to erase a block */
-       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
-       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
-       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
-       this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page);
-       this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1);
-}
-
-/**
- * nand_erase - [MTD Interface] erase block(s)
- * @mtd:       MTD device structure
- * @instr:     erase instruction
- *
- * Erase one ore more blocks
- */
-static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
-{
-       return nand_erase_nand (mtd, instr, 0);
-}
-
-/**
- * nand_erase_intern - [NAND Interface] erase block(s)
- * @mtd:       MTD device structure
- * @instr:     erase instruction
- * @allowbbt:  allow erasing the bbt area
- *
- * Erase one ore more blocks
- */
-int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt)
-{
-       int page, len, status, pages_per_block, ret, chipnr;
-       struct nand_chip *this = mtd->priv;
-
-       DEBUG (MTD_DEBUG_LEVEL3,
-              "nand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len);
-
-       /* Start address must align on block boundary */
-       if (instr->addr & ((1 << this->phys_erase_shift) - 1)) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Unaligned address\n");
-               return -EINVAL;
-       }
-
-       /* Length must align on block boundary */
-       if (instr->len & ((1 << this->phys_erase_shift) - 1)) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Length not block aligned\n");
-               return -EINVAL;
-       }
-
-       /* Do not allow erase past end of device */
-       if ((instr->len + instr->addr) > mtd->size) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Erase past end of device\n");
-               return -EINVAL;
-       }
-
-       instr->fail_addr = 0xffffffff;
-
-       /* Grab the lock and see if the device is available */
-       nand_get_device (this, mtd, FL_ERASING);
-
-       /* Shift to get first page */
-       page = (int) (instr->addr >> this->page_shift);
-       chipnr = (int) (instr->addr >> this->chip_shift);
-
-       /* Calculate pages in each block */
-       pages_per_block = 1 << (this->phys_erase_shift - this->page_shift);
-
-       /* Select the NAND device */
-       this->select_chip(mtd, chipnr);
-
-       /* Check the WP bit */
-       /* Check, if it is write protected */
-       if (nand_check_wp(mtd)) {
-               DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Device is write protected!!!\n");
-               instr->state = MTD_ERASE_FAILED;
-               goto erase_exit;
-       }
-
-       /* Loop through the pages */
-       len = instr->len;
-
-       instr->state = MTD_ERASING;
-
-       while (len) {
-#ifndef NAND_ALLOW_ERASE_ALL
-               /* Check if we have a bad block, we do not erase bad blocks ! */
-               if (nand_block_checkbad(mtd, ((loff_t) page) << this->page_shift, 0, allowbbt)) {
-                       printk (KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page);
-                       instr->state = MTD_ERASE_FAILED;
-                       goto erase_exit;
-               }
-#endif
-               /* Invalidate the page cache, if we erase the block which contains
-                  the current cached page */
-               if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block))
-                       this->pagebuf = -1;
-
-               this->erase_cmd (mtd, page & this->pagemask);
-
-               status = this->waitfunc (mtd, this, FL_ERASING);
-
-               /* See if block erase succeeded */
-               if (status & 0x01) {
-                       DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page);
-                       instr->state = MTD_ERASE_FAILED;
-                       instr->fail_addr = (page << this->page_shift);
-                       goto erase_exit;
-               }
-
-               /* Increment page address and decrement length */
-               len -= (1 << this->phys_erase_shift);
-               page += pages_per_block;
-
-               /* Check, if we cross a chip boundary */
-               if (len && !(page & this->pagemask)) {
-                       chipnr++;
-                       this->select_chip(mtd, -1);
-                       this->select_chip(mtd, chipnr);
-               }
-       }
-       instr->state = MTD_ERASE_DONE;
-
-erase_exit:
-
-       ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
-       /* Do call back function */
-       if (!ret)
-               mtd_erase_callback(instr);
-
-       /* Deselect and wake up anyone waiting on the device */
-       nand_release_device(mtd);
-
-       /* Return more or less happy */
-       return ret;
-}
-
-/**
- * nand_sync - [MTD Interface] sync
- * @mtd:       MTD device structure
- *
- * Sync is actually a wait for chip ready function
- */
-static void nand_sync (struct mtd_info *mtd)
-{
-       struct nand_chip *this = mtd->priv;
-
-       DEBUG (MTD_DEBUG_LEVEL3, "nand_sync: called\n");
-
-       /* Grab the lock and see if the device is available */
-       nand_get_device (this, mtd, FL_SYNCING);
-       /* Release it and go back */
-       nand_release_device (mtd);
-}
-
-
-/**
- * nand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
- * @mtd:       MTD device structure
- * @ofs:       offset relative to mtd start
- */
-static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs)
-{
-       /* Check for invalid offset */
-       if (ofs > mtd->size)
-               return -EINVAL;
-
-       return nand_block_checkbad (mtd, ofs, 1, 0);
-}
-
-/**
- * nand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
- * @mtd:       MTD device structure
- * @ofs:       offset relative to mtd start
- */
-static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs)
-{
-       struct nand_chip *this = mtd->priv;
-       int ret;
-
-       if ((ret = nand_block_isbad(mtd, ofs))) {
-               /* If it was bad already, return success and do nothing. */
-               if (ret > 0)
-                       return 0;
-               return ret;
-       }
-
-       return this->block_markbad(mtd, ofs);
-}
-
-/**
- * nand_scan - [NAND Interface] Scan for the NAND device
- * @mtd:       MTD device structure
- * @maxchips:  Number of chips to scan for
- *
- * This fills out all the not initialized function pointers
- * with the defaults.
- * The flash ID is read and the mtd/chip structures are
- * filled with the appropriate values. Buffers are allocated if
- * they are not provided by the board driver
- *
- */
-int nand_scan (struct mtd_info *mtd, int maxchips)
-{
-       int i, j, nand_maf_id, nand_dev_id, busw;
-       struct nand_chip *this = mtd->priv;
-
-       /* Get buswidth to select the correct functions*/
-       busw = this->options & NAND_BUSWIDTH_16;
-
-       /* check for proper chip_delay setup, set 20us if not */
-       if (!this->chip_delay)
-               this->chip_delay = 20;
-
-       /* check, if a user supplied command function given */
-       if (this->cmdfunc == NULL)
-               this->cmdfunc = nand_command;
-
-       /* check, if a user supplied wait function given */
-       if (this->waitfunc == NULL)
-               this->waitfunc = nand_wait;
-
-       if (!this->select_chip)
-               this->select_chip = nand_select_chip;
-       if (!this->write_byte)
-               this->write_byte = busw ? nand_write_byte16 : nand_write_byte;
-       if (!this->read_byte)
-               this->read_byte = busw ? nand_read_byte16 : nand_read_byte;
-       if (!this->write_word)
-               this->write_word = nand_write_word;
-       if (!this->read_word)
-               this->read_word = nand_read_word;
-       if (!this->block_bad)
-               this->block_bad = nand_block_bad;
-       if (!this->block_markbad)
-               this->block_markbad = nand_default_block_markbad;
-       if (!this->write_buf)
-               this->write_buf = busw ? nand_write_buf16 : nand_write_buf;
-       if (!this->read_buf)
-               this->read_buf = busw ? nand_read_buf16 : nand_read_buf;
-       if (!this->verify_buf)
-               this->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf;
-       if (!this->scan_bbt)
-               this->scan_bbt = nand_default_bbt;
-
-       /* Select the device */
-       this->select_chip(mtd, 0);
-
-       /* Send the command for reading device ID */
-       this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
-
-       /* Read manufacturer and device IDs */
-       nand_maf_id = this->read_byte(mtd);
-       nand_dev_id = this->read_byte(mtd);
-
-       /* Print and store flash device information */
-       for (i = 0; nand_flash_ids[i].name != NULL; i++) {
-
-               if (nand_dev_id != nand_flash_ids[i].id)
-                       continue;
-
-               if (!mtd->name) mtd->name = nand_flash_ids[i].name;
-               this->chipsize = nand_flash_ids[i].chipsize << 20;
-
-               /* New devices have all the information in additional id bytes */
-               if (!nand_flash_ids[i].pagesize) {
-                       int extid;
-                       /* The 3rd id byte contains non relevant data ATM */
-                       extid = this->read_byte(mtd);
-                       /* The 4th id byte is the important one */
-                       extid = this->read_byte(mtd);
-                       /* Calc pagesize */
-                       mtd->oobblock = 1024 << (extid & 0x3);
-                       extid >>= 2;
-                       /* Calc oobsize */
-                       mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock / 512);
-                       extid >>= 2;
-                       /* Calc blocksize. Blocksize is multiples of 64KiB */
-                       mtd->erasesize = (64 * 1024)  << (extid & 0x03);
-                       extid >>= 2;
-                       /* Get buswidth information */
-                       busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
-
-               } else {
-                       /* Old devices have this data hardcoded in the
-                        * device id table */
-                       mtd->erasesize = nand_flash_ids[i].erasesize;
-                       mtd->oobblock = nand_flash_ids[i].pagesize;
-                       mtd->oobsize = mtd->oobblock / 32;
-                       busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16;
-               }
-
-               /* Check, if buswidth is correct. Hardware drivers should set
-                * this correct ! */
-               if (busw != (this->options & NAND_BUSWIDTH_16)) {
-                       printk (KERN_INFO "NAND device: Manufacturer ID:"
-                               " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
-                               nand_manuf_ids[i].name , mtd->name);
-                       printk (KERN_WARNING
-                               "NAND bus width %d instead %d bit\n",
-                                       (this->options & NAND_BUSWIDTH_16) ? 16 : 8,
-                                       busw ? 16 : 8);
-                       this->select_chip(mtd, -1);
-                       return 1;
-               }
-
-               /* Calculate the address shift from the page size */
-               this->page_shift = ffs(mtd->oobblock) - 1;
-               this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1;
-               this->chip_shift = ffs(this->chipsize) - 1;
-
-               /* Set the bad block position */
-               this->badblockpos = mtd->oobblock > 512 ?
-                       NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
-
-               /* Get chip options, preserve non chip based options */
-               this->options &= ~NAND_CHIPOPTIONS_MSK;
-               this->options |= nand_flash_ids[i].options & NAND_CHIPOPTIONS_MSK;
-               /* Set this as a default. Board drivers can override it, if neccecary */
-               this->options |= NAND_NO_AUTOINCR;
-               /* Check if this is a not a samsung device. Do not clear the options
-                * for chips which are not having an extended id.
-                */
-               if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize)
-                       this->options &= ~NAND_SAMSUNG_LP_OPTIONS;
-
-               /* Check for AND chips with 4 page planes */
-               if (this->options & NAND_4PAGE_ARRAY)
-                       this->erase_cmd = multi_erase_cmd;
-               else
-                       this->erase_cmd = single_erase_cmd;
-
-               /* Do not replace user supplied command function ! */
-               if (mtd->oobblock > 512 && this->cmdfunc == nand_command)
-                       this->cmdfunc = nand_command_lp;
-
-               /* Try to identify manufacturer */
-               for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
-                       if (nand_manuf_ids[j].id == nand_maf_id)
-                               break;
-               }
-               break;
-       }
-
-       if (!nand_flash_ids[i].name) {
-#ifndef CFG_NAND_QUIET_TEST
-               printk (KERN_WARNING "No NAND device found!!!\n");
-#endif
-               this->select_chip(mtd, -1);
-               return 1;
-       }
-
-       for (i=1; i < maxchips; i++) {
-               this->select_chip(mtd, i);
-
-               /* Send the command for reading device ID */
-               this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
-
-               /* Read manufacturer and device IDs */
-               if (nand_maf_id != this->read_byte(mtd) ||
-                   nand_dev_id != this->read_byte(mtd))
-                       break;
-       }
-       if (i > 1)
-               printk(KERN_INFO "%d NAND chips detected\n", i);
-
-       /* Allocate buffers, if neccecary */
-       if (!this->oob_buf) {
-               size_t len;
-               len = mtd->oobsize << (this->phys_erase_shift - this->page_shift);
-               this->oob_buf = kmalloc (len, GFP_KERNEL);
-               if (!this->oob_buf) {
-                       printk (KERN_ERR "nand_scan(): Cannot allocate oob_buf\n");
-                       return -ENOMEM;
-               }
-               this->options |= NAND_OOBBUF_ALLOC;
-       }
-
-       if (!this->data_buf) {
-               size_t len;
-               len = mtd->oobblock + mtd->oobsize;
-               this->data_buf = kmalloc (len, GFP_KERNEL);
-               if (!this->data_buf) {
-                       if (this->options & NAND_OOBBUF_ALLOC)
-                               kfree (this->oob_buf);
-                       printk (KERN_ERR "nand_scan(): Cannot allocate data_buf\n");
-                       return -ENOMEM;
-               }
-               this->options |= NAND_DATABUF_ALLOC;
-       }
-
-       /* Store the number of chips and calc total size for mtd */
-       this->numchips = i;
-       mtd->size = i * this->chipsize;
-       /* Convert chipsize to number of pages per chip -1. */
-       this->pagemask = (this->chipsize >> this->page_shift) - 1;
-       /* Preset the internal oob buffer */
-       memset(this->oob_buf, 0xff, mtd->oobsize << (this->phys_erase_shift - this->page_shift));
-
-       /* If no default placement scheme is given, select an
-        * appropriate one */
-       if (!this->autooob) {
-               /* Select the appropriate default oob placement scheme for
-                * placement agnostic filesystems */
-               switch (mtd->oobsize) {
-               case 8:
-                       this->autooob = &nand_oob_8;
-                       break;
-               case 16:
-                       this->autooob = &nand_oob_16;
-                       break;
-               case 64:
-                       this->autooob = &nand_oob_64;
-                       break;
-               default:
-                       printk (KERN_WARNING "No oob scheme defined for oobsize %d\n",
-                               mtd->oobsize);
-/*                     BUG(); */
-               }
-       }
-
-       /* The number of bytes available for the filesystem to place fs dependend
-        * oob data */
-       if (this->options & NAND_BUSWIDTH_16) {
-               mtd->oobavail = mtd->oobsize - (this->autooob->eccbytes + 2);
-               if (this->autooob->eccbytes & 0x01)
-                       mtd->oobavail--;
-       } else
-               mtd->oobavail = mtd->oobsize - (this->autooob->eccbytes + 1);
-
-       /*
-        * check ECC mode, default to software
-        * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize
-        * fallback to software ECC
-       */
-       this->eccsize = 256;    /* set default eccsize */
-       this->eccbytes = 3;
-
-       switch (this->eccmode) {
-       case NAND_ECC_HW12_2048:
-               if (mtd->oobblock < 2048) {
-                       printk(KERN_WARNING "2048 byte HW ECC not possible on %d byte page size, fallback to SW ECC\n",
-                              mtd->oobblock);
-                       this->eccmode = NAND_ECC_SOFT;
-                       this->calculate_ecc = nand_calculate_ecc;
-                       this->correct_data = nand_correct_data;
-               } else
-                       this->eccsize = 2048;
-               break;
-
-       case NAND_ECC_HW3_512:
-       case NAND_ECC_HW6_512:
-       case NAND_ECC_HW8_512:
-               if (mtd->oobblock == 256) {
-                       printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n");
-                       this->eccmode = NAND_ECC_SOFT;
-                       this->calculate_ecc = nand_calculate_ecc;
-                       this->correct_data = nand_correct_data;
-               } else
-                       this->eccsize = 512; /* set eccsize to 512 */
-               break;
-
-       case NAND_ECC_HW3_256:
-               break;
-
-       case NAND_ECC_NONE:
-               printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n");
-               this->eccmode = NAND_ECC_NONE;
-               break;
-
-       case NAND_ECC_SOFT:
-               this->calculate_ecc = nand_calculate_ecc;
-               this->correct_data = nand_correct_data;
-               break;
-
-       default:
-               printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
-/*             BUG(); */
-       }
-
-       /* Check hardware ecc function availability and adjust number of ecc bytes per
-        * calculation step
-       */
-       switch (this->eccmode) {
-       case NAND_ECC_HW12_2048:
-               this->eccbytes += 4;
-       case NAND_ECC_HW8_512:
-               this->eccbytes += 2;
-       case NAND_ECC_HW6_512:
-               this->eccbytes += 3;
-       case NAND_ECC_HW3_512:
-       case NAND_ECC_HW3_256:
-               if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
-                       break;
-               printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
-/*             BUG();  */
-       }
-
-       mtd->eccsize = this->eccsize;
-
-       /* Set the number of read / write steps for one page to ensure ECC generation */
-       switch (this->eccmode) {
-       case NAND_ECC_HW12_2048:
-               this->eccsteps = mtd->oobblock / 2048;
-               break;
-       case NAND_ECC_HW3_512:
-       case NAND_ECC_HW6_512:
-       case NAND_ECC_HW8_512:
-               this->eccsteps = mtd->oobblock / 512;
-               break;
-       case NAND_ECC_HW3_256:
-       case NAND_ECC_SOFT:
-               this->eccsteps = mtd->oobblock / 256;
-               break;
-
-       case NAND_ECC_NONE:
-               this->eccsteps = 1;
-               break;
-       }
-
-/* XXX U-BOOT XXX */
-#if 0
-       /* Initialize state, waitqueue and spinlock */
-       this->state = FL_READY;
-       init_waitqueue_head (&this->wq);
-       spin_lock_init (&this->chip_lock);
-#endif
-
-       /* De-select the device */
-       this->select_chip(mtd, -1);
-
-       /* Invalidate the pagebuffer reference */
-       this->pagebuf = -1;
-
-       /* Fill in remaining MTD driver data */
-       mtd->type = MTD_NANDFLASH;
-       mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC;
-       mtd->ecctype = MTD_ECC_SW;
-       mtd->erase = nand_erase;
-       mtd->point = NULL;
-       mtd->unpoint = NULL;
-       mtd->read = nand_read;
-       mtd->write = nand_write;
-       mtd->read_ecc = nand_read_ecc;
-       mtd->write_ecc = nand_write_ecc;
-       mtd->read_oob = nand_read_oob;
-       mtd->write_oob = nand_write_oob;
-/* XXX U-BOOT XXX */
-#if 0
-       mtd->readv = NULL;
-       mtd->writev = nand_writev;
-       mtd->writev_ecc = nand_writev_ecc;
-#endif
-       mtd->sync = nand_sync;
-/* XXX U-BOOT XXX */
-#if 0
-       mtd->lock = NULL;
-       mtd->unlock = NULL;
-       mtd->suspend = NULL;
-       mtd->resume = NULL;
-#endif
-       mtd->block_isbad = nand_block_isbad;
-       mtd->block_markbad = nand_block_markbad;
-
-       /* and make the autooob the default one */
-       memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
-/* XXX U-BOOT XXX */
-#if 0
-       mtd->owner = THIS_MODULE;
-#endif
-       /* Build bad block table */
-       return this->scan_bbt (mtd);
-}
-
-/**
- * nand_release - [NAND Interface] Free resources held by the NAND device
- * @mtd:       MTD device structure
- */
-void nand_release (struct mtd_info *mtd)
-{
-       struct nand_chip *this = mtd->priv;
-
-#ifdef CONFIG_MTD_PARTITIONS
-       /* Deregister partitions */
-       del_mtd_partitions (mtd);
-#endif
-       /* Deregister the device */
-/* XXX U-BOOT XXX */
-#if 0
-       del_mtd_device (mtd);
-#endif
-       /* Free bad block table memory, if allocated */
-       if (this->bbt)
-               kfree (this->bbt);
-       /* Buffer allocated by nand_scan ? */
-       if (this->options & NAND_OOBBUF_ALLOC)
-               kfree (this->oob_buf);
-       /* Buffer allocated by nand_scan ? */
-       if (this->options & NAND_DATABUF_ALLOC)
-               kfree (this->data_buf);
-}
-
-#endif
diff --git a/drivers/nand/nand_bbt.c b/drivers/nand/nand_bbt.c
deleted file mode 100644 (file)
index 19a9bc2..0000000
+++ /dev/null
@@ -1,1052 +0,0 @@
-/*
- *  drivers/mtd/nand_bbt.c
- *
- *  Overview:
- *   Bad block table support for the NAND driver
- *
- *  Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
- *
- * $Id: nand_bbt.c,v 1.28 2004/11/13 10:19:09 gleixner Exp $
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Description:
- *
- * When nand_scan_bbt is called, then it tries to find the bad block table
- * depending on the options in the bbt descriptor(s). If a bbt is found
- * then the contents are read and the memory based bbt is created. If a
- * mirrored bbt is selected then the mirror is searched too and the
- * versions are compared. If the mirror has a greater version number
- * than the mirror bbt is used to build the memory based bbt.
- * If the tables are not versioned, then we "or" the bad block information.
- * If one of the bbt's is out of date or does not exist it is (re)created.
- * If no bbt exists at all then the device is scanned for factory marked
- * good / bad blocks and the bad block tables are created.
- *
- * For manufacturer created bbts like the one found on M-SYS DOC devices
- * the bbt is searched and read but never created
- *
- * The autogenerated bad block table is located in the last good blocks
- * of the device. The table is mirrored, so it can be updated eventually.
- * The table is marked in the oob area with an ident pattern and a version
- * number which indicates which of both tables is more up to date.
- *
- * The table uses 2 bits per block
- * 11b:        block is good
- * 00b:        block is factory marked bad
- * 01b, 10b:   block is marked bad due to wear
- *
- * The memory bad block table uses the following scheme:
- * 00b:                block is good
- * 01b:                block is marked bad due to wear
- * 10b:                block is reserved (to protect the bbt area)
- * 11b:                block is factory marked bad
- *
- * Multichip devices like DOC store the bad block info per floor.
- *
- * Following assumptions are made:
- * - bbts start at a page boundary, if autolocated on a block boundary
- * - the space neccecary for a bbt in FLASH does not exceed a block boundary
- *
- */
-
-#include <common.h>
-
-#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
-
-#include <malloc.h>
-#include <linux/mtd/compat.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-
-#include <asm/errno.h>
-
-/**
- * check_pattern - [GENERIC] check if a pattern is in the buffer
- * @buf:       the buffer to search
- * @len:       the length of buffer to search
- * @paglen:    the pagelength
- * @td:                search pattern descriptor
- *
- * Check for a pattern at the given place. Used to search bad block
- * tables and good / bad block identifiers.
- * If the SCAN_EMPTY option is set then check, if all bytes except the
- * pattern area contain 0xff
- *
-*/
-static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
-{
-       int i, end;
-       uint8_t *p = buf;
-
-       end = paglen + td->offs;
-       if (td->options & NAND_BBT_SCANEMPTY) {
-               for (i = 0; i < end; i++) {
-                       if (p[i] != 0xff)
-                               return -1;
-               }
-       }
-       p += end;
-
-       /* Compare the pattern */
-       for (i = 0; i < td->len; i++) {
-               if (p[i] != td->pattern[i])
-                       return -1;
-       }
-
-       p += td->len;
-       end += td->len;
-       if (td->options & NAND_BBT_SCANEMPTY) {
-               for (i = end; i < len; i++) {
-                       if (*p++ != 0xff)
-                               return -1;
-               }
-       }
-       return 0;
-}
-
-/**
- * read_bbt - [GENERIC] Read the bad block table starting from page
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @page:      the starting page
- * @num:       the number of bbt descriptors to read
- * @bits:      number of bits per block
- * @offs:      offset in the memory table
- * @reserved_block_code:       Pattern to identify reserved blocks
- *
- * Read the bad block table starting from page.
- *
- */
-static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
-       int bits, int offs, int reserved_block_code)
-{
-       int res, i, j, act = 0;
-       struct nand_chip *this = mtd->priv;
-       size_t retlen, len, totlen;
-       loff_t from;
-       uint8_t msk = (uint8_t) ((1 << bits) - 1);
-
-       totlen = (num * bits) >> 3;
-       from = ((loff_t)page) << this->page_shift;
-
-       while (totlen) {
-               len = min (totlen, (size_t) (1 << this->bbt_erase_shift));
-               res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob);
-               if (res < 0) {
-                       if (retlen != len) {
-                               printk (KERN_INFO "nand_bbt: Error reading bad block table\n");
-                               return res;
-                       }
-                       printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
-               }
-
-               /* Analyse data */
-               for (i = 0; i < len; i++) {
-                       uint8_t dat = buf[i];
-                       for (j = 0; j < 8; j += bits, act += 2) {
-                               uint8_t tmp = (dat >> j) & msk;
-                               if (tmp == msk)
-                                       continue;
-                               if (reserved_block_code &&
-                                   (tmp == reserved_block_code)) {
-                                       printk (KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n",
-                                               ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
-                                       this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
-                                       continue;
-                               }
-                               /* Leave it for now, if its matured we can move this
-                                * message to MTD_DEBUG_LEVEL0 */
-                               printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
-                                       ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
-                               /* Factory marked bad or worn out ? */
-                               if (tmp == 0)
-                                       this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
-                               else
-                                       this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06);
-                       }
-               }
-               totlen -= len;
-               from += len;
-       }
-       return 0;
-}
-
-/**
- * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
- * @chip:      read the table for a specific chip, -1 read all chips.
- *             Applies only if NAND_BBT_PERCHIP option is set
- *
- * Read the bad block table for all chips starting at a given page
- * We assume that the bbt bits are in consecutive order.
-*/
-static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
-{
-       struct nand_chip *this = mtd->priv;
-       int res = 0, i;
-       int bits;
-
-       bits = td->options & NAND_BBT_NRBITS_MSK;
-       if (td->options & NAND_BBT_PERCHIP) {
-               int offs = 0;
-               for (i = 0; i < this->numchips; i++) {
-                       if (chip == -1 || chip == i)
-                               res = read_bbt (mtd, buf, td->pages[i], this->chipsize >> this->bbt_erase_shift, bits, offs, td->reserved_block_code);
-                       if (res)
-                               return res;
-                       offs += this->chipsize >> (this->bbt_erase_shift + 2);
-               }
-       } else {
-               res = read_bbt (mtd, buf, td->pages[0], mtd->size >> this->bbt_erase_shift, bits, 0, td->reserved_block_code);
-               if (res)
-                       return res;
-       }
-       return 0;
-}
-
-/**
- * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
- * @md:                descriptor for the bad block table mirror
- *
- * Read the bad block table(s) for all chips starting at a given page
- * We assume that the bbt bits are in consecutive order.
- *
-*/
-static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td,
-       struct nand_bbt_descr *md)
-{
-       struct nand_chip *this = mtd->priv;
-
-       /* Read the primary version, if available */
-       if (td->options & NAND_BBT_VERSION) {
-               nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
-               td->version[0] = buf[mtd->oobblock + td->veroffs];
-               printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]);
-       }
-
-       /* Read the mirror version, if available */
-       if (md && (md->options & NAND_BBT_VERSION)) {
-               nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
-               md->version[0] = buf[mtd->oobblock + md->veroffs];
-               printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]);
-       }
-
-       return 1;
-}
-
-/**
- * create_bbt - [GENERIC] Create a bad block table by scanning the device
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @bd:                descriptor for the good/bad block search pattern
- * @chip:      create the table for a specific chip, -1 read all chips.
- *             Applies only if NAND_BBT_PERCHIP option is set
- *
- * Create a bad block table by scanning the device
- * for the given good/bad block identify pattern
- */
-static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
-{
-       struct nand_chip *this = mtd->priv;
-       int i, j, numblocks, len, scanlen;
-       int startblock;
-       loff_t from;
-       size_t readlen, ooblen;
-
-       if (bd->options & NAND_BBT_SCANALLPAGES)
-               len = 1 << (this->bbt_erase_shift - this->page_shift);
-       else {
-               if (bd->options & NAND_BBT_SCAN2NDPAGE)
-                       len = 2;
-               else
-                       len = 1;
-       }
-       scanlen = mtd->oobblock + mtd->oobsize;
-       readlen = len * mtd->oobblock;
-       ooblen = len * mtd->oobsize;
-
-       if (chip == -1) {
-               /* Note that numblocks is 2 * (real numblocks) here, see i+=2 below as it
-                * makes shifting and masking less painful */
-               numblocks = mtd->size >> (this->bbt_erase_shift - 1);
-               startblock = 0;
-               from = 0;
-       } else {
-               if (chip >= this->numchips) {
-                       printk (KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n",
-                               chip + 1, this->numchips);
-                       return;
-               }
-               numblocks = this->chipsize >> (this->bbt_erase_shift - 1);
-               startblock = chip * numblocks;
-               numblocks += startblock;
-               from = startblock << (this->bbt_erase_shift - 1);
-       }
-
-       for (i = startblock; i < numblocks;) {
-               nand_read_raw (mtd, buf, from, readlen, ooblen);
-               for (j = 0; j < len; j++) {
-                       if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
-                               this->bbt[i >> 3] |= 0x03 << (i & 0x6);
-                               break;
-                       }
-               }
-               i += 2;
-               from += (1 << this->bbt_erase_shift);
-       }
-}
-
-/**
- * search_bbt - [GENERIC] scan the device for a specific bad block table
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
- *
- * Read the bad block table by searching for a given ident pattern.
- * Search is preformed either from the beginning up or from the end of
- * the device downwards. The search starts always at the start of a
- * block.
- * If the option NAND_BBT_PERCHIP is given, each chip is searched
- * for a bbt, which contains the bad block information of this chip.
- * This is neccecary to provide support for certain DOC devices.
- *
- * The bbt ident pattern resides in the oob area of the first page
- * in a block.
- */
-static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
-{
-       struct nand_chip *this = mtd->priv;
-       int i, chips;
-       int bits, startblock, block, dir;
-       int scanlen = mtd->oobblock + mtd->oobsize;
-       int bbtblocks;
-
-       /* Search direction top -> down ? */
-       if (td->options & NAND_BBT_LASTBLOCK) {
-               startblock = (mtd->size >> this->bbt_erase_shift) -1;
-               dir = -1;
-       } else {
-               startblock = 0;
-               dir = 1;
-       }
-
-       /* Do we have a bbt per chip ? */
-       if (td->options & NAND_BBT_PERCHIP) {
-               chips = this->numchips;
-               bbtblocks = this->chipsize >> this->bbt_erase_shift;
-               startblock &= bbtblocks - 1;
-       } else {
-               chips = 1;
-               bbtblocks = mtd->size >> this->bbt_erase_shift;
-       }
-
-       /* Number of bits for each erase block in the bbt */
-       bits = td->options & NAND_BBT_NRBITS_MSK;
-
-       for (i = 0; i < chips; i++) {
-               /* Reset version information */
-               td->version[i] = 0;
-               td->pages[i] = -1;
-               /* Scan the maximum number of blocks */
-               for (block = 0; block < td->maxblocks; block++) {
-                       int actblock = startblock + dir * block;
-                       /* Read first page */
-                       nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize);
-                       if (!check_pattern(buf, scanlen, mtd->oobblock, td)) {
-                               td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift);
-                               if (td->options & NAND_BBT_VERSION) {
-                                       td->version[i] = buf[mtd->oobblock + td->veroffs];
-                               }
-                               break;
-                       }
-               }
-               startblock += this->chipsize >> this->bbt_erase_shift;
-       }
-       /* Check, if we found a bbt for each requested chip */
-       for (i = 0; i < chips; i++) {
-               if (td->pages[i] == -1)
-                       printk (KERN_WARNING "Bad block table not found for chip %d\n", i);
-               else
-                       printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]);
-       }
-       return 0;
-}
-
-/**
- * search_read_bbts - [GENERIC] scan the device for bad block table(s)
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
- * @md:                descriptor for the bad block table mirror
- *
- * Search and read the bad block table(s)
-*/
-static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
-       struct nand_bbt_descr *td, struct nand_bbt_descr *md)
-{
-       /* Search the primary table */
-       search_bbt (mtd, buf, td);
-
-       /* Search the mirror table */
-       if (md)
-               search_bbt (mtd, buf, md);
-
-       /* Force result check */
-       return 1;
-}
-
-
-/**
- * write_bbt - [GENERIC] (Re)write the bad block table
- *
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
- * @md:                descriptor for the bad block table mirror
- * @chipsel:   selector for a specific chip, -1 for all
- *
- * (Re)write the bad block table
- *
-*/
-static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
-       struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel)
-{
-       struct nand_chip *this = mtd->priv;
-       struct nand_oobinfo oobinfo;
-       struct erase_info einfo;
-       int i, j, res, chip = 0;
-       int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
-       int nrchips, bbtoffs, pageoffs;
-       uint8_t msk[4];
-       uint8_t rcode = td->reserved_block_code;
-       size_t retlen, len = 0;
-       loff_t to;
-
-       if (!rcode)
-               rcode = 0xff;
-       /* Write bad block table per chip rather than per device ? */
-       if (td->options & NAND_BBT_PERCHIP) {
-               numblocks = (int) (this->chipsize >> this->bbt_erase_shift);
-               /* Full device write or specific chip ? */
-               if (chipsel == -1) {
-                       nrchips = this->numchips;
-               } else {
-                       nrchips = chipsel + 1;
-                       chip = chipsel;
-               }
-       } else {
-               numblocks = (int) (mtd->size >> this->bbt_erase_shift);
-               nrchips = 1;
-       }
-
-       /* Loop through the chips */
-       for (; chip < nrchips; chip++) {
-
-               /* There was already a version of the table, reuse the page
-                * This applies for absolute placement too, as we have the
-                * page nr. in td->pages.
-                */
-               if (td->pages[chip] != -1) {
-                       page = td->pages[chip];
-                       goto write;
-               }
-
-               /* Automatic placement of the bad block table */
-               /* Search direction top -> down ? */
-               if (td->options & NAND_BBT_LASTBLOCK) {
-                       startblock = numblocks * (chip + 1) - 1;
-                       dir = -1;
-               } else {
-                       startblock = chip * numblocks;
-                       dir = 1;
-               }
-
-               for (i = 0; i < td->maxblocks; i++) {
-                       int block = startblock + dir * i;
-                       /* Check, if the block is bad */
-                       switch ((this->bbt[block >> 2] >> (2 * (block & 0x03))) & 0x03) {
-                       case 0x01:
-                       case 0x03:
-                               continue;
-                       }
-                       page = block << (this->bbt_erase_shift - this->page_shift);
-                       /* Check, if the block is used by the mirror table */
-                       if (!md || md->pages[chip] != page)
-                               goto write;
-               }
-               printk (KERN_ERR "No space left to write bad block table\n");
-               return -ENOSPC;
-write:
-
-               /* Set up shift count and masks for the flash table */
-               bits = td->options & NAND_BBT_NRBITS_MSK;
-               switch (bits) {
-               case 1: sft = 3; sftmsk = 0x07; msk[0] = 0x00; msk[1] = 0x01; msk[2] = ~rcode; msk[3] = 0x01; break;
-               case 2: sft = 2; sftmsk = 0x06; msk[0] = 0x00; msk[1] = 0x01; msk[2] = ~rcode; msk[3] = 0x03; break;
-               case 4: sft = 1; sftmsk = 0x04; msk[0] = 0x00; msk[1] = 0x0C; msk[2] = ~rcode; msk[3] = 0x0f; break;
-               case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break;
-               default: return -EINVAL;
-               }
-
-               bbtoffs = chip * (numblocks >> 2);
-
-               to = ((loff_t) page) << this->page_shift;
-
-               memcpy (&oobinfo, this->autooob, sizeof(oobinfo));
-               oobinfo.useecc = MTD_NANDECC_PLACEONLY;
-
-               /* Must we save the block contents ? */
-               if (td->options & NAND_BBT_SAVECONTENT) {
-                       /* Make it block aligned */
-                       to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1));
-                       len = 1 << this->bbt_erase_shift;
-                       res = mtd->read_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
-                       if (res < 0) {
-                               if (retlen != len) {
-                                       printk (KERN_INFO "nand_bbt: Error reading block for writing the bad block table\n");
-                                       return res;
-                               }
-                               printk (KERN_WARNING "nand_bbt: ECC error while reading block for writing bad block table\n");
-                       }
-                       /* Calc the byte offset in the buffer */
-                       pageoffs = page - (int)(to >> this->page_shift);
-                       offs = pageoffs << this->page_shift;
-                       /* Preset the bbt area with 0xff */
-                       memset (&buf[offs], 0xff, (size_t)(numblocks >> sft));
-                       /* Preset the bbt's oob area with 0xff */
-                       memset (&buf[len + pageoffs * mtd->oobsize], 0xff,
-                               ((len >> this->page_shift) - pageoffs) * mtd->oobsize);
-                       if (td->options & NAND_BBT_VERSION) {
-                               buf[len + (pageoffs * mtd->oobsize) + td->veroffs] = td->version[chip];
-                       }
-               } else {
-                       /* Calc length */
-                       len = (size_t) (numblocks >> sft);
-                       /* Make it page aligned ! */
-                       len = (len + (mtd->oobblock-1)) & ~(mtd->oobblock-1);
-                       /* Preset the buffer with 0xff */
-                       memset (buf, 0xff, len + (len >> this->page_shift) * mtd->oobsize);
-                       offs = 0;
-                       /* Pattern is located in oob area of first page */
-                       memcpy (&buf[len + td->offs], td->pattern, td->len);
-                       if (td->options & NAND_BBT_VERSION) {
-                               buf[len + td->veroffs] = td->version[chip];
-                       }
-               }
-
-               /* walk through the memory table */
-               for (i = 0; i < numblocks; ) {
-                       uint8_t dat;
-                       dat = this->bbt[bbtoffs + (i >> 2)];
-                       for (j = 0; j < 4; j++ , i++) {
-                               int sftcnt = (i << (3 - sft)) & sftmsk;
-                               /* Do not store the reserved bbt blocks ! */
-                               buf[offs + (i >> sft)] &= ~(msk[dat & 0x03] << sftcnt);
-                               dat >>= 2;
-                       }
-               }
-
-               memset (&einfo, 0, sizeof (einfo));
-               einfo.mtd = mtd;
-               einfo.addr = (unsigned long) to;
-               einfo.len = 1 << this->bbt_erase_shift;
-               res = nand_erase_nand (mtd, &einfo, 1);
-               if (res < 0) {
-                       printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res);
-                       return res;
-               }
-
-               res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
-               if (res < 0) {
-                       printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res);
-                       return res;
-               }
-               printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n",
-                       (unsigned int) to, td->version[chip]);
-
-               /* Mark it as used */
-               td->pages[chip] = page;
-       }
-       return 0;
-}
-
-/**
- * nand_memory_bbt - [GENERIC] create a memory based bad block table
- * @mtd:       MTD device structure
- * @bd:                descriptor for the good/bad block search pattern
- *
- * The function creates a memory based bbt by scanning the device
- * for manufacturer / software marked good / bad blocks
-*/
-static int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
-{
-       struct nand_chip *this = mtd->priv;
-
-       /* Ensure that we only scan for the pattern and nothing else */
-       bd->options = 0;
-       create_bbt (mtd, this->data_buf, bd, -1);
-       return 0;
-}
-
-/**
- * check_create - [GENERIC] create and write bbt(s) if neccecary
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @bd:                descriptor for the good/bad block search pattern
- *
- * The function checks the results of the previous call to read_bbt
- * and creates / updates the bbt(s) if neccecary
- * Creation is neccecary if no bbt was found for the chip/device
- * Update is neccecary if one of the tables is missing or the
- * version nr. of one table is less than the other
-*/
-static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
-{
-       int i, chips, writeops, chipsel, res;
-       struct nand_chip *this = mtd->priv;
-       struct nand_bbt_descr *td = this->bbt_td;
-       struct nand_bbt_descr *md = this->bbt_md;
-       struct nand_bbt_descr *rd, *rd2;
-
-       /* Do we have a bbt per chip ? */
-       if (td->options & NAND_BBT_PERCHIP)
-               chips = this->numchips;
-       else
-               chips = 1;
-
-       for (i = 0; i < chips; i++) {
-               writeops = 0;
-               rd = NULL;
-               rd2 = NULL;
-               /* Per chip or per device ? */
-               chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1;
-               /* Mirrored table avilable ? */
-               if (md) {
-                       if (td->pages[i] == -1 && md->pages[i] == -1) {
-                               writeops = 0x03;
-                               goto create;
-                       }
-
-                       if (td->pages[i] == -1) {
-                               rd = md;
-                               td->version[i] = md->version[i];
-                               writeops = 1;
-                               goto writecheck;
-                       }
-
-                       if (md->pages[i] == -1) {
-                               rd = td;
-                               md->version[i] = td->version[i];
-                               writeops = 2;
-                               goto writecheck;
-                       }
-
-                       if (td->version[i] == md->version[i]) {
-                               rd = td;
-                               if (!(td->options & NAND_BBT_VERSION))
-                                       rd2 = md;
-                               goto writecheck;
-                       }
-
-                       if (((int8_t) (td->version[i] - md->version[i])) > 0) {
-                               rd = td;
-                               md->version[i] = td->version[i];
-                               writeops = 2;
-                       } else {
-                               rd = md;
-                               td->version[i] = md->version[i];
-                               writeops = 1;
-                       }
-
-                       goto writecheck;
-
-               } else {
-                       if (td->pages[i] == -1) {
-                               writeops = 0x01;
-                               goto create;
-                       }
-                       rd = td;
-                       goto writecheck;
-               }
-create:
-               /* Create the bad block table by scanning the device ? */
-               if (!(td->options & NAND_BBT_CREATE))
-                       continue;
-
-               /* Create the table in memory by scanning the chip(s) */
-               create_bbt (mtd, buf, bd, chipsel);
-
-               td->version[i] = 1;
-               if (md)
-                       md->version[i] = 1;
-writecheck:
-               /* read back first ? */
-               if (rd)
-                       read_abs_bbt (mtd, buf, rd, chipsel);
-               /* If they weren't versioned, read both. */
-               if (rd2)
-                       read_abs_bbt (mtd, buf, rd2, chipsel);
-
-               /* Write the bad block table to the device ? */
-               if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
-                       res = write_bbt (mtd, buf, td, md, chipsel);
-                       if (res < 0)
-                               return res;
-               }
-
-               /* Write the mirror bad block table to the device ? */
-               if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
-                       res = write_bbt (mtd, buf, md, td, chipsel);
-                       if (res < 0)
-                               return res;
-               }
-       }
-       return 0;
-}
-
-/**
- * mark_bbt_regions - [GENERIC] mark the bad block table regions
- * @mtd:       MTD device structure
- * @td:                bad block table descriptor
- *
- * The bad block table regions are marked as "bad" to prevent
- * accidental erasures / writes. The regions are identified by
- * the mark 0x02.
-*/
-static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
-{
-       struct nand_chip *this = mtd->priv;
-       int i, j, chips, block, nrblocks, update;
-       uint8_t oldval, newval;
-
-       /* Do we have a bbt per chip ? */
-       if (td->options & NAND_BBT_PERCHIP) {
-               chips = this->numchips;
-               nrblocks = (int)(this->chipsize >> this->bbt_erase_shift);
-       } else {
-               chips = 1;
-               nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
-       }
-
-       for (i = 0; i < chips; i++) {
-               if ((td->options & NAND_BBT_ABSPAGE) ||
-                   !(td->options & NAND_BBT_WRITE)) {
-                       if (td->pages[i] == -1) continue;
-                       block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
-                       block <<= 1;
-                       oldval = this->bbt[(block >> 3)];
-                       newval = oldval | (0x2 << (block & 0x06));
-                       this->bbt[(block >> 3)] = newval;
-                       if ((oldval != newval) && td->reserved_block_code)
-                               nand_update_bbt(mtd, block << (this->bbt_erase_shift - 1));
-                       continue;
-               }
-               update = 0;
-               if (td->options & NAND_BBT_LASTBLOCK)
-                       block = ((i + 1) * nrblocks) - td->maxblocks;
-               else
-                       block = i * nrblocks;
-               block <<= 1;
-               for (j = 0; j < td->maxblocks; j++) {
-                       oldval = this->bbt[(block >> 3)];
-                       newval = oldval | (0x2 << (block & 0x06));
-                       this->bbt[(block >> 3)] = newval;
-                       if (oldval != newval) update = 1;
-                       block += 2;
-               }
-               /* If we want reserved blocks to be recorded to flash, and some
-                  new ones have been marked, then we need to update the stored
-                  bbts.  This should only happen once. */
-               if (update && td->reserved_block_code)
-                       nand_update_bbt(mtd, (block - 2) << (this->bbt_erase_shift - 1));
-       }
-}
-
-/**
- * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s)
- * @mtd:       MTD device structure
- * @bd:                descriptor for the good/bad block search pattern
- *
- * The function checks, if a bad block table(s) is/are already
- * available. If not it scans the device for manufacturer
- * marked good / bad blocks and writes the bad block table(s) to
- * the selected place.
- *
- * The bad block table memory is allocated here. It must be freed
- * by calling the nand_free_bbt function.
- *
-*/
-int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
-{
-       struct nand_chip *this = mtd->priv;
-       int len, res = 0;
-       uint8_t *buf;
-       struct nand_bbt_descr *td = this->bbt_td;
-       struct nand_bbt_descr *md = this->bbt_md;
-
-       len = mtd->size >> (this->bbt_erase_shift + 2);
-       /* Allocate memory (2bit per block) */
-       this->bbt = kmalloc (len, GFP_KERNEL);
-       if (!this->bbt) {
-               printk (KERN_ERR "nand_scan_bbt: Out of memory\n");
-               return -ENOMEM;
-       }
-       /* Clear the memory bad block table */
-       memset (this->bbt, 0x00, len);
-
-       /* If no primary table decriptor is given, scan the device
-        * to build a memory based bad block table
-        */
-       if (!td)
-               return nand_memory_bbt(mtd, bd);
-
-       /* Allocate a temporary buffer for one eraseblock incl. oob */
-       len = (1 << this->bbt_erase_shift);
-       len += (len >> this->page_shift) * mtd->oobsize;
-       buf = kmalloc (len, GFP_KERNEL);
-       if (!buf) {
-               printk (KERN_ERR "nand_bbt: Out of memory\n");
-               kfree (this->bbt);
-               this->bbt = NULL;
-               return -ENOMEM;
-       }
-
-       /* Is the bbt at a given page ? */
-       if (td->options & NAND_BBT_ABSPAGE) {
-               res = read_abs_bbts (mtd, buf, td, md);
-       } else {
-               /* Search the bad block table using a pattern in oob */
-               res = search_read_bbts (mtd, buf, td, md);
-       }
-
-       if (res)
-               res = check_create (mtd, buf, bd);
-
-       /* Prevent the bbt regions from erasing / writing */
-       mark_bbt_region (mtd, td);
-       if (md)
-               mark_bbt_region (mtd, md);
-
-       kfree (buf);
-       return res;
-}
-
-
-/**
- * nand_update_bbt - [NAND Interface] update bad block table(s)
- * @mtd:       MTD device structure
- * @offs:      the offset of the newly marked block
- *
- * The function updates the bad block table(s)
-*/
-int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
-{
-       struct nand_chip *this = mtd->priv;
-       int len, res = 0, writeops = 0;
-       int chip, chipsel;
-       uint8_t *buf;
-       struct nand_bbt_descr *td = this->bbt_td;
-       struct nand_bbt_descr *md = this->bbt_md;
-
-       if (!this->bbt || !td)
-               return -EINVAL;
-
-       len = mtd->size >> (this->bbt_erase_shift + 2);
-       /* Allocate a temporary buffer for one eraseblock incl. oob */
-       len = (1 << this->bbt_erase_shift);
-       len += (len >> this->page_shift) * mtd->oobsize;
-       buf = kmalloc (len, GFP_KERNEL);
-       if (!buf) {
-               printk (KERN_ERR "nand_update_bbt: Out of memory\n");
-               return -ENOMEM;
-       }
-
-       writeops = md != NULL ? 0x03 : 0x01;
-
-       /* Do we have a bbt per chip ? */
-       if (td->options & NAND_BBT_PERCHIP) {
-               chip = (int) (offs >> this->chip_shift);
-               chipsel = chip;
-       } else {
-               chip = 0;
-               chipsel = -1;
-       }
-
-       td->version[chip]++;
-       if (md)
-               md->version[chip]++;
-
-       /* Write the bad block table to the device ? */
-       if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
-               res = write_bbt (mtd, buf, td, md, chipsel);
-               if (res < 0)
-                       goto out;
-       }
-       /* Write the mirror bad block table to the device ? */
-       if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
-               res = write_bbt (mtd, buf, md, td, chipsel);
-       }
-
-out:
-       kfree (buf);
-       return res;
-}
-
-/* Define some generic bad / good block scan pattern which are used
- * while scanning a device for factory marked good / bad blocks
- *
- * The memory based patterns just
- */
-static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
-
-static struct nand_bbt_descr smallpage_memorybased = {
-       .options = 0,
-       .offs = 5,
-       .len = 1,
-       .pattern = scan_ff_pattern
-};
-
-static struct nand_bbt_descr largepage_memorybased = {
-       .options = 0,
-       .offs = 0,
-       .len = 2,
-       .pattern = scan_ff_pattern
-};
-
-static struct nand_bbt_descr smallpage_flashbased = {
-       .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
-       .offs = 5,
-       .len = 1,
-       .pattern = scan_ff_pattern
-};
-
-static struct nand_bbt_descr largepage_flashbased = {
-       .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
-       .offs = 0,
-       .len = 2,
-       .pattern = scan_ff_pattern
-};
-
-static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 };
-
-static struct nand_bbt_descr agand_flashbased = {
-       .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
-       .offs = 0x20,
-       .len = 6,
-       .pattern = scan_agand_pattern
-};
-
-/* Generic flash bbt decriptors
-*/
-static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
-static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
-
-static struct nand_bbt_descr bbt_main_descr = {
-       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
-               | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
-       .offs = 8,
-       .len = 4,
-       .veroffs = 12,
-       .maxblocks = 4,
-       .pattern = bbt_pattern
-};
-
-static struct nand_bbt_descr bbt_mirror_descr = {
-       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
-               | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
-       .offs = 8,
-       .len = 4,
-       .veroffs = 12,
-       .maxblocks = 4,
-       .pattern = mirror_pattern
-};
-
-/**
- * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
- * @mtd:       MTD device structure
- *
- * This function selects the default bad block table
- * support for the device and calls the nand_scan_bbt function
- *
-*/
-int nand_default_bbt (struct mtd_info *mtd)
-{
-       struct nand_chip *this = mtd->priv;
-
-       /* Default for AG-AND. We must use a flash based
-        * bad block table as the devices have factory marked
-        * _good_ blocks. Erasing those blocks leads to loss
-        * of the good / bad information, so we _must_ store
-        * this information in a good / bad table during
-        * startup
-       */
-       if (this->options & NAND_IS_AND) {
-               /* Use the default pattern descriptors */
-               if (!this->bbt_td) {
-                       this->bbt_td = &bbt_main_descr;
-                       this->bbt_md = &bbt_mirror_descr;
-               }
-               this->options |= NAND_USE_FLASH_BBT;
-               return nand_scan_bbt (mtd, &agand_flashbased);
-       }
-
-
-       /* Is a flash based bad block table requested ? */
-       if (this->options & NAND_USE_FLASH_BBT) {
-               /* Use the default pattern descriptors */
-               if (!this->bbt_td) {
-                       this->bbt_td = &bbt_main_descr;
-                       this->bbt_md = &bbt_mirror_descr;
-               }
-               if (!this->badblock_pattern) {
-                       this->badblock_pattern = (mtd->oobblock > 512) ?
-                               &largepage_flashbased : &smallpage_flashbased;
-               }
-       } else {
-               this->bbt_td = NULL;
-               this->bbt_md = NULL;
-               if (!this->badblock_pattern) {
-                       this->badblock_pattern = (mtd->oobblock > 512) ?
-                               &largepage_memorybased : &smallpage_memorybased;
-               }
-       }
-       return nand_scan_bbt (mtd, this->badblock_pattern);
-}
-
-/**
- * nand_isbad_bbt - [NAND Interface] Check if a block is bad
- * @mtd:       MTD device structure
- * @offs:      offset in the device
- * @allowbbt:  allow access to bad block table region
- *
- */
-int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt)
-{
-       struct nand_chip *this = mtd->priv;
-       int block;
-       uint8_t res;
-
-       /* Get block number * 2 */
-       block = (int) (offs >> (this->bbt_erase_shift - 1));
-       res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
-
-       DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
-               (unsigned int)offs, res, block >> 1);
-
-       switch ((int)res) {
-       case 0x00:      return 0;
-       case 0x01:      return 1;
-       case 0x02:      return allowbbt ? 0 : 1;
-       }
-       return 1;
-}
-
-#endif
diff --git a/drivers/nand/nand_ecc.c b/drivers/nand/nand_ecc.c
deleted file mode 100644 (file)
index 4c532b0..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * This file contains an ECC algorithm from Toshiba that detects and
- * corrects 1 bit errors in a 256 byte block of data.
- *
- * drivers/mtd/nand/nand_ecc.c
- *
- * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com)
- *                         Toshiba America Electronics Components, Inc.
- *
- * $Id: nand_ecc.c,v 1.14 2004/06/16 15:34:37 gleixner Exp $
- *
- * This file is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 or (at your option) any
- * later version.
- *
- * This file is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this file; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * As a special exception, if other files instantiate templates or use
- * macros or inline functions from these files, or you compile these
- * files and link them with other works to produce a work based on these
- * files, these files do not by themselves cause the resulting work to be
- * covered by the GNU General Public License. However the source code for
- * these files must still be made available in accordance with section (3)
- * of the GNU General Public License.
- *
- * This exception does not invalidate any other reasons why a work based on
- * this file might be covered by the GNU General Public License.
- */
-
-#include <common.h>
-
-#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
-
-#include<linux/mtd/mtd.h>
-
-/*
- * NAND-SPL has no sofware ECC for now, so don't include nand_calculate_ecc(),
- * only nand_correct_data() is needed
- */
-
-#ifndef CONFIG_NAND_SPL
-/*
- * Pre-calculated 256-way 1 byte column parity
- */
-static const u_char nand_ecc_precalc_table[] = {
-       0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
-       0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
-       0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
-       0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
-       0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
-       0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
-       0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
-       0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
-       0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
-       0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
-       0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
-       0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
-       0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
-       0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
-       0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
-       0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
-};
-
-/**
- * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256-byte block
- * @mtd:       MTD block structure
- * @dat:       raw data
- * @ecc_code:  buffer for ECC
- */
-int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
-                      u_char *ecc_code)
-{
-       uint8_t idx, reg1, reg2, reg3, tmp1, tmp2;
-       int i;
-
-       /* Initialize variables */
-       reg1 = reg2 = reg3 = 0;
-
-       /* Build up column parity */
-       for(i = 0; i < 256; i++) {
-               /* Get CP0 - CP5 from table */
-               idx = nand_ecc_precalc_table[*dat++];
-               reg1 ^= (idx & 0x3f);
-
-               /* All bit XOR = 1 ? */
-               if (idx & 0x40) {
-                       reg3 ^= (uint8_t) i;
-                       reg2 ^= ~((uint8_t) i);
-               }
-       }
-
-       /* Create non-inverted ECC code from line parity */
-       tmp1  = (reg3 & 0x80) >> 0; /* B7 -> B7 */
-       tmp1 |= (reg2 & 0x80) >> 1; /* B7 -> B6 */
-       tmp1 |= (reg3 & 0x40) >> 1; /* B6 -> B5 */
-       tmp1 |= (reg2 & 0x40) >> 2; /* B6 -> B4 */
-       tmp1 |= (reg3 & 0x20) >> 2; /* B5 -> B3 */
-       tmp1 |= (reg2 & 0x20) >> 3; /* B5 -> B2 */
-       tmp1 |= (reg3 & 0x10) >> 3; /* B4 -> B1 */
-       tmp1 |= (reg2 & 0x10) >> 4; /* B4 -> B0 */
-
-       tmp2  = (reg3 & 0x08) << 4; /* B3 -> B7 */
-       tmp2 |= (reg2 & 0x08) << 3; /* B3 -> B6 */
-       tmp2 |= (reg3 & 0x04) << 3; /* B2 -> B5 */
-       tmp2 |= (reg2 & 0x04) << 2; /* B2 -> B4 */
-       tmp2 |= (reg3 & 0x02) << 2; /* B1 -> B3 */
-       tmp2 |= (reg2 & 0x02) << 1; /* B1 -> B2 */
-       tmp2 |= (reg3 & 0x01) << 1; /* B0 -> B1 */
-       tmp2 |= (reg2 & 0x01) << 0; /* B7 -> B0 */
-
-       /* Calculate final ECC code */
-#ifdef CONFIG_MTD_NAND_ECC_SMC
-       ecc_code[0] = ~tmp2;
-       ecc_code[1] = ~tmp1;
-#else
-       ecc_code[0] = ~tmp1;
-       ecc_code[1] = ~tmp2;
-#endif
-       ecc_code[2] = ((~reg1) << 2) | 0x03;
-
-       return 0;
-}
-#endif /* CONFIG_NAND_SPL */
-
-static inline int countbits(uint32_t byte)
-{
-       int res = 0;
-
-       for (;byte; byte >>= 1)
-               res += byte & 0x01;
-       return res;
-}
-
-/**
- * nand_correct_data - [NAND Interface] Detect and correct bit error(s)
- * @mtd:       MTD block structure
- * @dat:       raw data read from the chip
- * @read_ecc:  ECC from the chip
- * @calc_ecc:  the ECC calculated from raw data
- *
- * Detect and correct a 1 bit error for 256 byte block
- */
-int nand_correct_data(struct mtd_info *mtd, u_char *dat,
-                     u_char *read_ecc, u_char *calc_ecc)
-{
-       uint8_t s0, s1, s2;
-
-#ifdef CONFIG_MTD_NAND_ECC_SMC
-       s0 = calc_ecc[0] ^ read_ecc[0];
-       s1 = calc_ecc[1] ^ read_ecc[1];
-       s2 = calc_ecc[2] ^ read_ecc[2];
-#else
-       s1 = calc_ecc[0] ^ read_ecc[0];
-       s0 = calc_ecc[1] ^ read_ecc[1];
-       s2 = calc_ecc[2] ^ read_ecc[2];
-#endif
-       if ((s0 | s1 | s2) == 0)
-               return 0;
-
-       /* Check for a single bit error */
-       if( ((s0 ^ (s0 >> 1)) & 0x55) == 0x55 &&
-           ((s1 ^ (s1 >> 1)) & 0x55) == 0x55 &&
-           ((s2 ^ (s2 >> 1)) & 0x54) == 0x54) {
-
-               uint32_t byteoffs, bitnum;
-
-               byteoffs = (s1 << 0) & 0x80;
-               byteoffs |= (s1 << 1) & 0x40;
-               byteoffs |= (s1 << 2) & 0x20;
-               byteoffs |= (s1 << 3) & 0x10;
-
-               byteoffs |= (s0 >> 4) & 0x08;
-               byteoffs |= (s0 >> 3) & 0x04;
-               byteoffs |= (s0 >> 2) & 0x02;
-               byteoffs |= (s0 >> 1) & 0x01;
-
-               bitnum = (s2 >> 5) & 0x04;
-               bitnum |= (s2 >> 4) & 0x02;
-               bitnum |= (s2 >> 3) & 0x01;
-
-               dat[byteoffs] ^= (1 << bitnum);
-
-               return 1;
-       }
-
-       if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1)
-               return 1;
-
-       return -1;
-}
-
-#endif
diff --git a/drivers/nand/nand_ids.c b/drivers/nand/nand_ids.c
deleted file mode 100644 (file)
index 6d7e347..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- *  drivers/mtd/nandids.c
- *
- *  Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de)
-  *
- * $Id: nand_ids.c,v 1.10 2004/05/26 13:40:12 gleixner Exp $
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <common.h>
-
-#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
-
-#include <linux/mtd/nand.h>
-
-/*
-*      Chip ID list
-*
-*      Name. ID code, pagesize, chipsize in MegaByte, eraseblock size,
-*      options
-*
-*      Pagesize; 0, 256, 512
-*      0       get this information from the extended chip ID
-+      256     256 Byte page size
-*      512     512 Byte page size
-*/
-struct nand_flash_dev nand_flash_ids[] = {
-       {"NAND 1MiB 5V 8-bit",          0x6e, 256, 1, 0x1000, 0},
-       {"NAND 2MiB 5V 8-bit",          0x64, 256, 2, 0x1000, 0},
-       {"NAND 4MiB 5V 8-bit",          0x6b, 512, 4, 0x2000, 0},
-       {"NAND 1MiB 3,3V 8-bit",        0xe8, 256, 1, 0x1000, 0},
-       {"NAND 1MiB 3,3V 8-bit",        0xec, 256, 1, 0x1000, 0},
-       {"NAND 2MiB 3,3V 8-bit",        0xea, 256, 2, 0x1000, 0},
-       {"NAND 4MiB 3,3V 8-bit",        0xd5, 512, 4, 0x2000, 0},
-       {"NAND 4MiB 3,3V 8-bit",        0xe3, 512, 4, 0x2000, 0},
-       {"NAND 4MiB 3,3V 8-bit",        0xe5, 512, 4, 0x2000, 0},
-       {"NAND 8MiB 3,3V 8-bit",        0xd6, 512, 8, 0x2000, 0},
-
-       {"NAND 8MiB 1,8V 8-bit",        0x39, 512, 8, 0x2000, 0},
-       {"NAND 8MiB 3,3V 8-bit",        0xe6, 512, 8, 0x2000, 0},
-       {"NAND 8MiB 1,8V 16-bit",       0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},
-       {"NAND 8MiB 3,3V 16-bit",       0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},
-
-       {"NAND 16MiB 1,8V 8-bit",       0x33, 512, 16, 0x4000, 0},
-       {"NAND 16MiB 3,3V 8-bit",       0x73, 512, 16, 0x4000, 0},
-       {"NAND 16MiB 1,8V 16-bit",      0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16},
-       {"NAND 16MiB 3,3V 16-bit",      0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16},
-
-       {"NAND 32MiB 1,8V 8-bit",       0x35, 512, 32, 0x4000, 0},
-       {"NAND 32MiB 3,3V 8-bit",       0x75, 512, 32, 0x4000, 0},
-       {"NAND 32MiB 1,8V 16-bit",      0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16},
-       {"NAND 32MiB 3,3V 16-bit",      0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16},
-
-       {"NAND 64MiB 1,8V 8-bit",       0x36, 512, 64, 0x4000, 0},
-       {"NAND 64MiB 3,3V 8-bit",       0x76, 512, 64, 0x4000, 0},
-       {"NAND 64MiB 1,8V 16-bit",      0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16},
-       {"NAND 64MiB 3,3V 16-bit",      0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
-
-       {"NAND 128MiB 1,8V 8-bit",      0x78, 512, 128, 0x4000, 0},
-       {"NAND 128MiB 3,3V 8-bit",      0x79, 512, 128, 0x4000, 0},
-       {"NAND 128MiB 1,8V 16-bit",     0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16},
-       {"NAND 128MiB 3,3V 16-bit",     0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
-
-       {"NAND 256MiB 3,3V 8-bit",      0x71, 512, 256, 0x4000, 0},
-
-       {"NAND 512MiB 3,3V 8-bit",      0xDC, 512, 512, 0x4000, 0},
-
-       /* These are the new chips with large page size. The pagesize
-       * and the erasesize is determined from the extended id bytes
-       */
-       /* 1 Gigabit */
-       {"NAND 128MiB 1,8V 8-bit",      0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
-       {"NAND 128MiB 3,3V 8-bit",      0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
-       {"NAND 128MiB 1,8V 16-bit",     0xB1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
-       {"NAND 128MiB 3,3V 16-bit",     0xC1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
-
-       /* 2 Gigabit */
-       {"NAND 256MiB 1,8V 8-bit",      0xAA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
-       {"NAND 256MiB 3,3V 8-bit",      0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
-       {"NAND 256MiB 1,8V 16-bit",     0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
-       {"NAND 256MiB 3,3V 16-bit",     0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
-
-       /* 4 Gigabit */
-       {"NAND 512MiB 1,8V 8-bit",      0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
-       {"NAND 512MiB 3,3V 8-bit",      0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
-       {"NAND 512MiB 1,8V 16-bit",     0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
-       {"NAND 512MiB 3,3V 16-bit",     0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
-
-       /* 8 Gigabit */
-       {"NAND 1GiB 1,8V 8-bit",        0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
-       {"NAND 1GiB 3,3V 8-bit",        0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
-       {"NAND 1GiB 1,8V 16-bit",       0xB3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
-       {"NAND 1GiB 3,3V 16-bit",       0xC3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
-
-       /* 16 Gigabit */
-       {"NAND 2GiB 1,8V 8-bit",        0xA5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
-       {"NAND 2GiB 3,3V 8-bit",        0xD5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
-       {"NAND 2GiB 1,8V 16-bit",       0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
-       {"NAND 2GiB 3,3V 16-bit",       0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
-
-       /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout !
-        * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes
-        * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7
-        * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go
-        * There are more speed improvements for reads and writes possible, but not implemented now
-        */
-       {"AND 128MiB 3,3V 8-bit",       0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY},
-
-       {NULL,}
-};
-
-/*
-*      Manufacturer ID list
-*/
-struct nand_manufacturers nand_manuf_ids[] = {
-       {NAND_MFR_TOSHIBA, "Toshiba"},
-       {NAND_MFR_SAMSUNG, "Samsung"},
-       {NAND_MFR_FUJITSU, "Fujitsu"},
-       {NAND_MFR_NATIONAL, "National"},
-       {NAND_MFR_RENESAS, "Renesas"},
-       {NAND_MFR_STMICRO, "ST Micro"},
-       {NAND_MFR_MICRON, "Micron"},
-       {0x0, "Unknown"}
-};
-#endif
diff --git a/drivers/nand/nand_util.c b/drivers/nand/nand_util.c
deleted file mode 100644 (file)
index 4fd4e16..0000000
+++ /dev/null
@@ -1,872 +0,0 @@
-/*
- * drivers/nand/nand_util.c
- *
- * Copyright (C) 2006 by Weiss-Electronic GmbH.
- * All rights reserved.
- *
- * @author:    Guido Classen <clagix@gmail.com>
- * @descr:     NAND Flash support
- * @references: borrowed heavily from Linux mtd-utils code:
- *             flash_eraseall.c by Arcom Control System Ltd
- *             nandwrite.c by Steven J. Hill (sjhill@realitydiluted.com)
- *                            and Thomas Gleixner (tglx@linutronix.de)
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- */
-
-#include <common.h>
-
-#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
-
-#include <command.h>
-#include <watchdog.h>
-#include <malloc.h>
-#include <div64.h>
-
-#include <nand.h>
-#include <jffs2/jffs2.h>
-
-typedef struct erase_info erase_info_t;
-typedef struct mtd_info          mtd_info_t;
-
-/* support only for native endian JFFS2 */
-#define cpu_to_je16(x) (x)
-#define cpu_to_je32(x) (x)
-
-/*****************************************************************************/
-static int nand_block_bad_scrub(struct mtd_info *mtd, loff_t ofs, int getchip)
-{
-       return 0;
-}
-
-/**
- * nand_erase_opts: - erase NAND flash with support for various options
- *                   (jffs2 formating)
- *
- * @param meminfo      NAND device to erase
- * @param opts         options,  @see struct nand_erase_options
- * @return             0 in case of success
- *
- * This code is ported from flash_eraseall.c from Linux mtd utils by
- * Arcom Control System Ltd.
- */
-int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)
-{
-       struct jffs2_unknown_node cleanmarker;
-       int clmpos = 0;
-       int clmlen = 8;
-       erase_info_t erase;
-       ulong erase_length;
-       int isNAND;
-       int bbtest = 1;
-       int result;
-       int percent_complete = -1;
-       int (*nand_block_bad_old)(struct mtd_info *, loff_t, int) = NULL;
-       const char *mtd_device = meminfo->name;
-
-       memset(&erase, 0, sizeof(erase));
-
-       erase.mtd = meminfo;
-       erase.len  = meminfo->erasesize;
-       erase.addr = opts->offset;
-       erase_length = opts->length;
-
-       isNAND = meminfo->type == MTD_NANDFLASH ? 1 : 0;
-
-       if (opts->jffs2) {
-               cleanmarker.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK);
-               cleanmarker.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER);
-               if (isNAND) {
-                       struct nand_oobinfo *oobinfo = &meminfo->oobinfo;
-
-                       /* check for autoplacement */
-                       if (oobinfo->useecc == MTD_NANDECC_AUTOPLACE) {
-                               /* get the position of the free bytes */
-                               if (!oobinfo->oobfree[0][1]) {
-                                       printf(" Eeep. Autoplacement selected "
-                                              "and no empty space in oob\n");
-                                       return -1;
-                               }
-                               clmpos = oobinfo->oobfree[0][0];
-                               clmlen = oobinfo->oobfree[0][1];
-                               if (clmlen > 8)
-                                       clmlen = 8;
-                       } else {
-                               /* legacy mode */
-                               switch (meminfo->oobsize) {
-                               case 8:
-                                       clmpos = 6;
-                                       clmlen = 2;
-                                       break;
-                               case 16:
-                                       clmpos = 8;
-                                       clmlen = 8;
-                                       break;
-                               case 64:
-                                       clmpos = 16;
-                                       clmlen = 8;
-                                       break;
-                               }
-                       }
-
-                       cleanmarker.totlen = cpu_to_je32(8);
-               } else {
-                       cleanmarker.totlen =
-                               cpu_to_je32(sizeof(struct jffs2_unknown_node));
-               }
-               cleanmarker.hdr_crc =  cpu_to_je32(
-                       crc32_no_comp(0, (unsigned char *) &cleanmarker,
-                                     sizeof(struct jffs2_unknown_node) - 4));
-       }
-
-       /* scrub option allows to erase badblock. To prevent internal
-        * check from erase() method, set block check method to dummy
-        * and disable bad block table while erasing.
-        */
-       if (opts->scrub) {
-               struct nand_chip *priv_nand = meminfo->priv;
-
-               nand_block_bad_old = priv_nand->block_bad;
-               priv_nand->block_bad = nand_block_bad_scrub;
-               /* we don't need the bad block table anymore...
-                * after scrub, there are no bad blocks left!
-                */
-               if (priv_nand->bbt) {
-                       kfree(priv_nand->bbt);
-               }
-               priv_nand->bbt = NULL;
-       }
-
-       for (;
-            erase.addr < opts->offset + erase_length;
-            erase.addr += meminfo->erasesize) {
-
-               WATCHDOG_RESET ();
-
-               if (!opts->scrub && bbtest) {
-                       int ret = meminfo->block_isbad(meminfo, erase.addr);
-                       if (ret > 0) {
-                               if (!opts->quiet)
-                                       printf("\rSkipping bad block at  "
-                                              "0x%08x                   "
-                                              "                         \n",
-                                              erase.addr);
-                               continue;
-
-                       } else if (ret < 0) {
-                               printf("\n%s: MTD get bad block failed: %d\n",
-                                      mtd_device,
-                                      ret);
-                               return -1;
-                       }
-               }
-
-               result = meminfo->erase(meminfo, &erase);
-               if (result != 0) {
-                       printf("\n%s: MTD Erase failure: %d\n",
-                              mtd_device, result);
-                       continue;
-               }
-
-               /* format for JFFS2 ? */
-               if (opts->jffs2) {
-
-                       /* write cleanmarker */
-                       if (isNAND) {
-                               size_t written;
-                               result = meminfo->write_oob(meminfo,
-                                                           erase.addr + clmpos,
-                                                           clmlen,
-                                                           &written,
-                                                           (unsigned char *)
-                                                           &cleanmarker);
-                               if (result != 0) {
-                                       printf("\n%s: MTD writeoob failure: %d\n",
-                                              mtd_device, result);
-                                       continue;
-                               }
-                       } else {
-                               printf("\n%s: this erase routine only supports"
-                                      " NAND devices!\n",
-                                      mtd_device);
-                       }
-               }
-
-               if (!opts->quiet) {
-                       unsigned long long n =(unsigned long long)
-                               (erase.addr + meminfo->erasesize - opts->offset)
-                               * 100;
-                       int percent;
-
-                       do_div(n, erase_length);
-                       percent = (int)n;
-
-                       /* output progress message only at whole percent
-                        * steps to reduce the number of messages printed
-                        * on (slow) serial consoles
-                        */
-                       if (percent != percent_complete) {
-                               percent_complete = percent;
-
-                               printf("\rErasing at 0x%x -- %3d%% complete.",
-                                      erase.addr, percent);
-
-                               if (opts->jffs2 && result == 0)
-                                       printf(" Cleanmarker written at 0x%x.",
-                                              erase.addr);
-                       }
-               }
-       }
-       if (!opts->quiet)
-               printf("\n");
-
-       if (nand_block_bad_old) {
-               struct nand_chip *priv_nand = meminfo->priv;
-
-               priv_nand->block_bad = nand_block_bad_old;
-               priv_nand->scan_bbt(meminfo);
-       }
-
-       return 0;
-}
-
-#define MAX_PAGE_SIZE  2048
-#define MAX_OOB_SIZE   64
-
-/*
- * buffer array used for writing data
- */
-static unsigned char data_buf[MAX_PAGE_SIZE];
-static unsigned char oob_buf[MAX_OOB_SIZE];
-
-/* OOB layouts to pass into the kernel as default */
-static struct nand_oobinfo none_oobinfo = {
-       .useecc = MTD_NANDECC_OFF,
-};
-
-static struct nand_oobinfo jffs2_oobinfo = {
-       .useecc = MTD_NANDECC_PLACE,
-       .eccbytes = 6,
-       .eccpos = { 0, 1, 2, 3, 6, 7 }
-};
-
-static struct nand_oobinfo yaffs_oobinfo = {
-       .useecc = MTD_NANDECC_PLACE,
-       .eccbytes = 6,
-       .eccpos = { 8, 9, 10, 13, 14, 15}
-};
-
-static struct nand_oobinfo autoplace_oobinfo = {
-       .useecc = MTD_NANDECC_AUTOPLACE
-};
-
-/**
- * nand_write_opts: - write image to NAND flash with support for various options
- *
- * @param meminfo      NAND device to erase
- * @param opts         write options (@see nand_write_options)
- * @return             0 in case of success
- *
- * This code is ported from nandwrite.c from Linux mtd utils by
- * Steven J. Hill and Thomas Gleixner.
- */
-int nand_write_opts(nand_info_t *meminfo, const nand_write_options_t *opts)
-{
-       int imglen = 0;
-       int pagelen;
-       int baderaseblock;
-       int blockstart = -1;
-       loff_t offs;
-       int readlen;
-       int oobinfochanged = 0;
-       int percent_complete = -1;
-       struct nand_oobinfo old_oobinfo;
-       ulong mtdoffset = opts->offset;
-       ulong erasesize_blockalign;
-       u_char *buffer = opts->buffer;
-       size_t written;
-       int result;
-
-       if (opts->pad && opts->writeoob) {
-               printf("Can't pad when oob data is present.\n");
-               return -1;
-       }
-
-       /* set erasesize to specified number of blocks - to match
-        * jffs2 (virtual) block size */
-       if (opts->blockalign == 0) {
-               erasesize_blockalign = meminfo->erasesize;
-       } else {
-               erasesize_blockalign = meminfo->erasesize * opts->blockalign;
-       }
-
-       /* make sure device page sizes are valid */
-       if (!(meminfo->oobsize == 16 && meminfo->oobblock == 512)
-           && !(meminfo->oobsize == 8 && meminfo->oobblock == 256)
-           && !(meminfo->oobsize == 64 && meminfo->oobblock == 2048)) {
-               printf("Unknown flash (not normal NAND)\n");
-               return -1;
-       }
-
-       /* read the current oob info */
-       memcpy(&old_oobinfo, &meminfo->oobinfo, sizeof(old_oobinfo));
-
-       /* write without ecc? */
-       if (opts->noecc) {
-               memcpy(&meminfo->oobinfo, &none_oobinfo,
-                      sizeof(meminfo->oobinfo));
-               oobinfochanged = 1;
-       }
-
-       /* autoplace ECC? */
-       if (opts->autoplace && (old_oobinfo.useecc != MTD_NANDECC_AUTOPLACE)) {
-
-               memcpy(&meminfo->oobinfo, &autoplace_oobinfo,
-                      sizeof(meminfo->oobinfo));
-               oobinfochanged = 1;
-       }
-
-       /* force OOB layout for jffs2 or yaffs? */
-       if (opts->forcejffs2 || opts->forceyaffs) {
-               struct nand_oobinfo *oobsel =
-                       opts->forcejffs2 ? &jffs2_oobinfo : &yaffs_oobinfo;
-
-               if (meminfo->oobsize == 8) {
-                       if (opts->forceyaffs) {
-                               printf("YAFSS cannot operate on "
-                                      "256 Byte page size\n");
-                               goto restoreoob;
-                       }
-                       /* Adjust number of ecc bytes */
-                       jffs2_oobinfo.eccbytes = 3;
-               }
-
-               memcpy(&meminfo->oobinfo, oobsel, sizeof(meminfo->oobinfo));
-       }
-
-       /* get image length */
-       imglen = opts->length;
-       pagelen = meminfo->oobblock
-               + ((opts->writeoob != 0) ? meminfo->oobsize : 0);
-
-       /* check, if file is pagealigned */
-       if ((!opts->pad) && ((imglen % pagelen) != 0)) {
-               printf("Input block length is not page aligned\n");
-               goto restoreoob;
-       }
-
-       /* check, if length fits into device */
-       if (((imglen / pagelen) * meminfo->oobblock)
-            > (meminfo->size - opts->offset)) {
-               printf("Image %d bytes, NAND page %d bytes, "
-                      "OOB area %u bytes, device size %u bytes\n",
-                      imglen, pagelen, meminfo->oobblock, meminfo->size);
-               printf("Input block does not fit into device\n");
-               goto restoreoob;
-       }
-
-       if (!opts->quiet)
-               printf("\n");
-
-       /* get data from input and write to the device */
-       while (imglen && (mtdoffset < meminfo->size)) {
-
-               WATCHDOG_RESET ();
-
-               /*
-                * new eraseblock, check for bad block(s). Stay in the
-                * loop to be sure if the offset changes because of
-                * a bad block, that the next block that will be
-                * written to is also checked. Thus avoiding errors if
-                * the block(s) after the skipped block(s) is also bad
-                * (number of blocks depending on the blockalign
-                */
-               while (blockstart != (mtdoffset & (~erasesize_blockalign+1))) {
-                       blockstart = mtdoffset & (~erasesize_blockalign+1);
-                       offs = blockstart;
-                       baderaseblock = 0;
-
-                       /* check all the blocks in an erase block for
-                        * bad blocks */
-                       do {
-                               int ret = meminfo->block_isbad(meminfo, offs);
-
-                               if (ret < 0) {
-                                       printf("Bad block check failed\n");
-                                       goto restoreoob;
-                               }
-                               if (ret == 1) {
-                                       baderaseblock = 1;
-                                       if (!opts->quiet)
-                                               printf("\rBad block at 0x%lx "
-                                                      "in erase block from "
-                                                      "0x%x will be skipped\n",
-                                                      (long) offs,
-                                                      blockstart);
-                               }
-
-                               if (baderaseblock) {
-                                       mtdoffset = blockstart
-                                               + erasesize_blockalign;
-                               }
-                               offs +=  erasesize_blockalign
-                                       / opts->blockalign;
-                       } while (offs < blockstart + erasesize_blockalign);
-               }
-
-               readlen = meminfo->oobblock;
-               if (opts->pad && (imglen < readlen)) {
-                       readlen = imglen;
-                       memset(data_buf + readlen, 0xff,
-                              meminfo->oobblock - readlen);
-               }
-
-               /* read page data from input memory buffer */
-               memcpy(data_buf, buffer, readlen);
-               buffer += readlen;
-
-               if (opts->writeoob) {
-                       /* read OOB data from input memory block, exit
-                        * on failure */
-                       memcpy(oob_buf, buffer, meminfo->oobsize);
-                       buffer += meminfo->oobsize;
-
-                       /* write OOB data first, as ecc will be placed
-                        * in there*/
-                       result = meminfo->write_oob(meminfo,
-                                                   mtdoffset,
-                                                   meminfo->oobsize,
-                                                   &written,
-                                                   (unsigned char *)
-                                                   &oob_buf);
-
-                       if (result != 0) {
-                               printf("\nMTD writeoob failure: %d\n",
-                                      result);
-                               goto restoreoob;
-                       }
-                       imglen -= meminfo->oobsize;
-               }
-
-               /* write out the page data */
-               result = meminfo->write(meminfo,
-                                       mtdoffset,
-                                       meminfo->oobblock,
-                                       &written,
-                                       (unsigned char *) &data_buf);
-
-               if (result != 0) {
-                       printf("writing NAND page at offset 0x%lx failed\n",
-                              mtdoffset);
-                       goto restoreoob;
-               }
-               imglen -= readlen;
-
-               if (!opts->quiet) {
-                       unsigned long long n = (unsigned long long)
-                                (opts->length-imglen) * 100;
-                       int percent;
-
-                       do_div(n, opts->length);
-                       percent = (int)n;
-
-                       /* output progress message only at whole percent
-                        * steps to reduce the number of messages printed
-                        * on (slow) serial consoles
-                        */
-                       if (percent != percent_complete) {
-                               printf("\rWriting data at 0x%x "
-                                      "-- %3d%% complete.",
-                                      mtdoffset, percent);
-                               percent_complete = percent;
-                       }
-               }
-
-               mtdoffset += meminfo->oobblock;
-       }
-
-       if (!opts->quiet)
-               printf("\n");
-
-restoreoob:
-       if (oobinfochanged) {
-               memcpy(&meminfo->oobinfo, &old_oobinfo,
-                      sizeof(meminfo->oobinfo));
-       }
-
-       if (imglen > 0) {
-               printf("Data did not fit into device, due to bad blocks\n");
-               return -1;
-       }
-
-       /* return happy */
-       return 0;
-}
-
-/**
- * nand_read_opts: - read image from NAND flash with support for various options
- *
- * @param meminfo      NAND device to erase
- * @param opts         read options (@see struct nand_read_options)
- * @return             0 in case of success
- *
- */
-int nand_read_opts(nand_info_t *meminfo, const nand_read_options_t *opts)
-{
-       int imglen = opts->length;
-       int pagelen;
-       int baderaseblock;
-       int blockstart = -1;
-       int percent_complete = -1;
-       loff_t offs;
-       size_t readlen;
-       ulong mtdoffset = opts->offset;
-       u_char *buffer = opts->buffer;
-       int result;
-
-       /* make sure device page sizes are valid */
-       if (!(meminfo->oobsize == 16 && meminfo->oobblock == 512)
-           && !(meminfo->oobsize == 8 && meminfo->oobblock == 256)
-           && !(meminfo->oobsize == 64 && meminfo->oobblock == 2048)) {
-               printf("Unknown flash (not normal NAND)\n");
-               return -1;
-       }
-
-       pagelen = meminfo->oobblock
-               + ((opts->readoob != 0) ? meminfo->oobsize : 0);
-
-       /* check, if length is not larger than device */
-       if (((imglen / pagelen) * meminfo->oobblock)
-            > (meminfo->size - opts->offset)) {
-               printf("Image %d bytes, NAND page %d bytes, "
-                      "OOB area %u bytes, device size %u bytes\n",
-                      imglen, pagelen, meminfo->oobblock, meminfo->size);
-               printf("Input block is larger than device\n");
-               return -1;
-       }
-
-       if (!opts->quiet)
-               printf("\n");
-
-       /* get data from input and write to the device */
-       while (imglen && (mtdoffset < meminfo->size)) {
-
-               WATCHDOG_RESET ();
-
-               /*
-                * new eraseblock, check for bad block(s). Stay in the
-                * loop to be sure if the offset changes because of
-                * a bad block, that the next block that will be
-                * written to is also checked. Thus avoiding errors if
-                * the block(s) after the skipped block(s) is also bad
-                * (number of blocks depending on the blockalign
-                */
-               while (blockstart != (mtdoffset & (~meminfo->erasesize+1))) {
-                       blockstart = mtdoffset & (~meminfo->erasesize+1);
-                       offs = blockstart;
-                       baderaseblock = 0;
-
-                       /* check all the blocks in an erase block for
-                        * bad blocks */
-                       do {
-                               int ret = meminfo->block_isbad(meminfo, offs);
-
-                               if (ret < 0) {
-                                       printf("Bad block check failed\n");
-                                       return -1;
-                               }
-                               if (ret == 1) {
-                                       baderaseblock = 1;
-                                       if (!opts->quiet)
-                                               printf("\rBad block at 0x%lx "
-                                                      "in erase block from "
-                                                      "0x%x will be skipped\n",
-                                                      (long) offs,
-                                                      blockstart);
-                               }
-
-                               if (baderaseblock) {
-                                       mtdoffset = blockstart
-                                               + meminfo->erasesize;
-                               }
-                               offs +=  meminfo->erasesize;
-
-                       } while (offs < blockstart + meminfo->erasesize);
-               }
-
-
-               /* read page data to memory buffer */
-               result = meminfo->read(meminfo,
-                                      mtdoffset,
-                                      meminfo->oobblock,
-                                      &readlen,
-                                      (unsigned char *) &data_buf);
-
-               if (result != 0) {
-                       printf("reading NAND page at offset 0x%lx failed\n",
-                              mtdoffset);
-                       return -1;
-               }
-
-               if (imglen < readlen) {
-                       readlen = imglen;
-               }
-
-               memcpy(buffer, data_buf, readlen);
-               buffer += readlen;
-               imglen -= readlen;
-
-               if (opts->readoob) {
-                       result = meminfo->read_oob(meminfo,
-                                                  mtdoffset,
-                                                  meminfo->oobsize,
-                                                  &readlen,
-                                                  (unsigned char *)
-                                                  &oob_buf);
-
-                       if (result != 0) {
-                               printf("\nMTD readoob failure: %d\n",
-                                      result);
-                               return -1;
-                       }
-
-
-                       if (imglen < readlen) {
-                               readlen = imglen;
-                       }
-
-                       memcpy(buffer, oob_buf, readlen);
-
-                       buffer += readlen;
-                       imglen -= readlen;
-               }
-
-               if (!opts->quiet) {
-                       unsigned long long n = (unsigned long long)
-                                (opts->length-imglen) * 100;
-                       int percent;
-
-                       do_div(n, opts->length);
-                       percent = (int)n;
-
-                       /* output progress message only at whole percent
-                        * steps to reduce the number of messages printed
-                        * on (slow) serial consoles
-                        */
-                       if (percent != percent_complete) {
-                       if (!opts->quiet)
-                               printf("\rReading data from 0x%x "
-                                      "-- %3d%% complete.",
-                                      mtdoffset, percent);
-                               percent_complete = percent;
-                       }
-               }
-
-               mtdoffset += meminfo->oobblock;
-       }
-
-       if (!opts->quiet)
-               printf("\n");
-
-       if (imglen > 0) {
-               printf("Could not read entire image due to bad blocks\n");
-               return -1;
-       }
-
-       /* return happy */
-       return 0;
-}
-
-/******************************************************************************
- * Support for locking / unlocking operations of some NAND devices
- *****************************************************************************/
-
-#define NAND_CMD_LOCK          0x2a
-#define NAND_CMD_LOCK_TIGHT    0x2c
-#define NAND_CMD_UNLOCK1       0x23
-#define NAND_CMD_UNLOCK2       0x24
-#define NAND_CMD_LOCK_STATUS   0x7a
-
-/**
- * nand_lock: Set all pages of NAND flash chip to the LOCK or LOCK-TIGHT
- *           state
- *
- * @param meminfo      nand mtd instance
- * @param tight                bring device in lock tight mode
- *
- * @return             0 on success, -1 in case of error
- *
- * The lock / lock-tight command only applies to the whole chip. To get some
- * parts of the chip lock and others unlocked use the following sequence:
- *
- * - Lock all pages of the chip using nand_lock(mtd, 0) (or the lockpre pin)
- * - Call nand_unlock() once for each consecutive area to be unlocked
- * - If desired: Bring the chip to the lock-tight state using nand_lock(mtd, 1)
- *
- *   If the device is in lock-tight state software can't change the
- *   current active lock/unlock state of all pages. nand_lock() / nand_unlock()
- *   calls will fail. It is only posible to leave lock-tight state by
- *   an hardware signal (low pulse on _WP pin) or by power down.
- */
-int nand_lock(nand_info_t *meminfo, int tight)
-{
-       int ret = 0;
-       int status;
-       struct nand_chip *this = meminfo->priv;
-
-       /* select the NAND device */
-       this->select_chip(meminfo, 0);
-
-       this->cmdfunc(meminfo,
-                     (tight ? NAND_CMD_LOCK_TIGHT : NAND_CMD_LOCK),
-                     -1, -1);
-
-       /* call wait ready function */
-       status = this->waitfunc(meminfo, this, FL_WRITING);
-
-       /* see if device thinks it succeeded */
-       if (status & 0x01) {
-               ret = -1;
-       }
-
-       /* de-select the NAND device */
-       this->select_chip(meminfo, -1);
-       return ret;
-}
-
-/**
- * nand_get_lock_status: - query current lock state from one page of NAND
- *                        flash
- *
- * @param meminfo      nand mtd instance
- * @param offset       page address to query (muss be page aligned!)
- *
- * @return             -1 in case of error
- *                     >0 lock status:
- *                       bitfield with the following combinations:
- *                       NAND_LOCK_STATUS_TIGHT: page in tight state
- *                       NAND_LOCK_STATUS_LOCK:  page locked
- *                       NAND_LOCK_STATUS_UNLOCK: page unlocked
- *
- */
-int nand_get_lock_status(nand_info_t *meminfo, ulong offset)
-{
-       int ret = 0;
-       int chipnr;
-       int page;
-       struct nand_chip *this = meminfo->priv;
-
-       /* select the NAND device */
-       chipnr = (int)(offset >> this->chip_shift);
-       this->select_chip(meminfo, chipnr);
-
-
-       if ((offset & (meminfo->oobblock - 1)) != 0) {
-               printf ("nand_get_lock_status: "
-                       "Start address must be beginning of "
-                       "nand page!\n");
-               ret = -1;
-               goto out;
-       }
-
-       /* check the Lock Status */
-       page = (int)(offset >> this->page_shift);
-       this->cmdfunc(meminfo, NAND_CMD_LOCK_STATUS, -1, page & this->pagemask);
-
-       ret = this->read_byte(meminfo) & (NAND_LOCK_STATUS_TIGHT
-                                         | NAND_LOCK_STATUS_LOCK
-                                         | NAND_LOCK_STATUS_UNLOCK);
-
- out:
-       /* de-select the NAND device */
-       this->select_chip(meminfo, -1);
-       return ret;
-}
-
-/**
- * nand_unlock: - Unlock area of NAND pages
- *               only one consecutive area can be unlocked at one time!
- *
- * @param meminfo      nand mtd instance
- * @param start                start byte address
- * @param length       number of bytes to unlock (must be a multiple of
- *                     page size nand->oobblock)
- *
- * @return             0 on success, -1 in case of error
- */
-int nand_unlock(nand_info_t *meminfo, ulong start, ulong length)
-{
-       int ret = 0;
-       int chipnr;
-       int status;
-       int page;
-       struct nand_chip *this = meminfo->priv;
-       printf ("nand_unlock: start: %08x, length: %d!\n",
-               (int)start, (int)length);
-
-       /* select the NAND device */
-       chipnr = (int)(start >> this->chip_shift);
-       this->select_chip(meminfo, chipnr);
-
-       /* check the WP bit */
-       this->cmdfunc(meminfo, NAND_CMD_STATUS, -1, -1);
-       if ((this->read_byte(meminfo) & 0x80) == 0) {
-               printf ("nand_unlock: Device is write protected!\n");
-               ret = -1;
-               goto out;
-       }
-
-       if ((start & (meminfo->oobblock - 1)) != 0) {
-               printf ("nand_unlock: Start address must be beginning of "
-                       "nand page!\n");
-               ret = -1;
-               goto out;
-       }
-
-       if (length == 0 || (length & (meminfo->oobblock - 1)) != 0) {
-               printf ("nand_unlock: Length must be a multiple of nand page "
-                       "size!\n");
-               ret = -1;
-               goto out;
-       }
-
-       /* submit address of first page to unlock */
-       page = (int)(start >> this->page_shift);
-       this->cmdfunc(meminfo, NAND_CMD_UNLOCK1, -1, page & this->pagemask);
-
-       /* submit ADDRESS of LAST page to unlock */
-       page += (int)(length >> this->page_shift) - 1;
-       this->cmdfunc(meminfo, NAND_CMD_UNLOCK2, -1, page & this->pagemask);
-
-       /* call wait ready function */
-       status = this->waitfunc(meminfo, this, FL_WRITING);
-       /* see if device thinks it succeeded */
-       if (status & 0x01) {
-               /* there was an error */
-               ret = -1;
-               goto out;
-       }
-
- out:
-       /* de-select the NAND device */
-       this->select_chip(meminfo, -1);
-       return ret;
-}
-
-#endif
diff --git a/drivers/nand_legacy/Makefile b/drivers/nand_legacy/Makefile
deleted file mode 100644 (file)
index 95314d8..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# (C) Copyright 2006
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-#
-# See file CREDITS for list of people who contributed to this
-# project.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-# MA 02111-1307 USA
-#
-
-include $(TOPDIR)/config.mk
-
-LIB    := $(obj)libnand_legacy.a
-
-COBJS  := nand_legacy.o
-
-SRCS   := $(COBJS:.o=.c)
-OBJS   := $(addprefix $(obj),$(COBJS))
-
-all:   $(LIB)
-
-$(LIB):        $(obj).depend $(OBJS)
-       $(AR) $(ARFLAGS) $@ $(OBJS)
-
-#########################################################################
-
-# defines $(obj).depend target
-include $(SRCTREE)/rules.mk
-
-sinclude $(obj).depend
-
-#########################################################################
diff --git a/drivers/nand_legacy/nand_legacy.c b/drivers/nand_legacy/nand_legacy.c
deleted file mode 100644 (file)
index 49d2ebb..0000000
+++ /dev/null
@@ -1,1612 +0,0 @@
-/*
- * (C) 2006 Denx
- * Driver for NAND support, Rick Bronson
- * borrowed heavily from:
- * (c) 1999 Machine Vision Holdings, Inc.
- * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
- *
- * Added 16-bit nand support
- * (C) 2004 Texas Instruments
- */
-
-#include <common.h>
-#include <command.h>
-#include <malloc.h>
-#include <asm/io.h>
-#include <watchdog.h>
-
-#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
-
-#include <linux/mtd/nand_legacy.h>
-#include <linux/mtd/nand_ids.h>
-#include <jffs2/jffs2.h>
-
-#ifdef CONFIG_OMAP1510
-void archflashwp(void *archdata, int wp);
-#endif
-
-#define ROUND_DOWN(value,boundary)      ((value) & (~((boundary)-1)))
-
-#undef PSYCHO_DEBUG
-#undef NAND_DEBUG
-
-/* ****************** WARNING *********************
- * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will
- * erase (or at least attempt to erase) blocks that are marked
- * bad. This can be very handy if you are _sure_ that the block
- * is OK, say because you marked a good block bad to test bad
- * block handling and you are done testing, or if you have
- * accidentally marked blocks bad.
- *
- * Erasing factory marked bad blocks is a _bad_ idea. If the
- * erase succeeds there is no reliable way to find them again,
- * and attempting to program or erase bad blocks can affect
- * the data in _other_ (good) blocks.
- */
-#define         ALLOW_ERASE_BAD_DEBUG 0
-
-#define CONFIG_MTD_NAND_ECC  /* enable ECC */
-#define CONFIG_MTD_NAND_ECC_JFFS2
-
-/* bits for nand_legacy_rw() `cmd'; or together as needed */
-#define NANDRW_READ    0x01
-#define NANDRW_WRITE   0x00
-#define NANDRW_JFFS2   0x02
-#define NANDRW_JFFS2_SKIP      0x04
-
-
-/*
- * Exported variables etc.
- */
-
-/* Definition of the out of band configuration structure */
-struct nand_oob_config {
-       /* position of ECC bytes inside oob */
-       int ecc_pos[6];
-       /* position of  bad blk flag inside oob -1 = inactive */
-       int badblock_pos;
-       /* position of ECC valid flag inside oob -1 = inactive */
-       int eccvalid_pos;
-} oob_config = { {0}, 0, 0};
-
-struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE] = {{0}};
-
-int curr_device = -1; /* Current NAND Device */
-
-
-/*
- * Exported functionss
- */
-int nand_legacy_erase(struct nand_chip* nand, size_t ofs,
-                    size_t len, int clean);
-int nand_legacy_rw(struct nand_chip* nand, int cmd,
-                 size_t start, size_t len,
-                 size_t * retlen, u_char * buf);
-void nand_print(struct nand_chip *nand);
-void nand_print_bad(struct nand_chip *nand);
-int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
-                size_t * retlen, u_char * buf);
-int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
-                size_t * retlen, const u_char * buf);
-
-/*
- * Internals
- */
-static int NanD_WaitReady(struct nand_chip *nand, int ale_wait);
-static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
-                size_t * retlen, u_char *buf, u_char *ecc_code);
-static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
-                          size_t * retlen, const u_char * buf,
-                          u_char * ecc_code);
-#ifdef CONFIG_MTD_NAND_ECC
-static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc);
-static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code);
-#endif
-
-
-/*
- *
- * Function definitions
- *
- */
-
-/* returns 0 if block containing pos is OK:
- *             valid erase block and
- *             not marked bad, or no bad mark position is specified
- * returns 1 if marked bad or otherwise invalid
- */
-static int check_block (struct nand_chip *nand, unsigned long pos)
-{
-       size_t retlen;
-       uint8_t oob_data;
-       uint16_t oob_data16[6];
-       int page0 = pos & (-nand->erasesize);
-       int page1 = page0 + nand->oobblock;
-       int badpos = oob_config.badblock_pos;
-
-       if (pos >= nand->totlen)
-               return 1;
-
-       if (badpos < 0)
-               return 0;       /* no way to check, assume OK */
-
-       if (nand->bus16) {
-               if (nand_read_oob(nand, (page0 + 0), 12, &retlen, (uint8_t *)oob_data16)
-                   || (oob_data16[2] & 0xff00) != 0xff00)
-                       return 1;
-               if (nand_read_oob(nand, (page1 + 0), 12, &retlen, (uint8_t *)oob_data16)
-                   || (oob_data16[2] & 0xff00) != 0xff00)
-                       return 1;
-       } else {
-               /* Note - bad block marker can be on first or second page */
-               if (nand_read_oob(nand, page0 + badpos, 1, &retlen, (unsigned char *)&oob_data)
-                   || oob_data != 0xff
-                   || nand_read_oob (nand, page1 + badpos, 1, &retlen, (unsigned char *)&oob_data)
-                   || oob_data != 0xff)
-                       return 1;
-       }
-
-       return 0;
-}
-
-/* print bad blocks in NAND flash */
-void nand_print_bad(struct nand_chip* nand)
-{
-       unsigned long pos;
-
-       for (pos = 0; pos < nand->totlen; pos += nand->erasesize) {
-               if (check_block(nand, pos))
-                       printf(" 0x%8.8lx\n", pos);
-       }
-       puts("\n");
-}
-
-/* cmd: 0: NANDRW_WRITE                        write, fail on bad block
- *     1: NANDRW_READ                  read, fail on bad block
- *     2: NANDRW_WRITE | NANDRW_JFFS2  write, skip bad blocks
- *     3: NANDRW_READ | NANDRW_JFFS2   read, data all 0xff for bad blocks
- *      7: NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP read, skip bad blocks
- */
-int nand_legacy_rw (struct nand_chip* nand, int cmd,
-                  size_t start, size_t len,
-                  size_t * retlen, u_char * buf)
-{
-       int ret = 0, n, total = 0;
-       char eccbuf[6];
-       /* eblk (once set) is the start of the erase block containing the
-        * data being processed.
-        */
-       unsigned long eblk = ~0;        /* force mismatch on first pass */
-       unsigned long erasesize = nand->erasesize;
-
-       while (len) {
-               if ((start & (-erasesize)) != eblk) {
-                       /* have crossed into new erase block, deal with
-                        * it if it is sure marked bad.
-                        */
-                       eblk = start & (-erasesize); /* start of block */
-                       if (check_block(nand, eblk)) {
-                               if (cmd == (NANDRW_READ | NANDRW_JFFS2)) {
-                                       while (len > 0 &&
-                                              start - eblk < erasesize) {
-                                               *(buf++) = 0xff;
-                                               ++start;
-                                               ++total;
-                                               --len;
-                                       }
-                                       continue;
-                               } else if (cmd == (NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP)) {
-                                       start += erasesize;
-                                       continue;
-                               } else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) {
-                                       /* skip bad block */
-                                       start += erasesize;
-                                       continue;
-                               } else {
-                                       ret = 1;
-                                       break;
-                               }
-                       }
-               }
-               /* The ECC will not be calculated correctly if
-                  less than 512 is written or read */
-               /* Is request at least 512 bytes AND it starts on a proper boundry */
-               if((start != ROUND_DOWN(start, 0x200)) || (len < 0x200))
-                       printf("Warning block writes should be at least 512 bytes and start on a 512 byte boundry\n");
-
-               if (cmd & NANDRW_READ) {
-                       ret = nand_read_ecc(nand, start,
-                                          min(len, eblk + erasesize - start),
-                                          (size_t *)&n, (u_char*)buf, (u_char *)eccbuf);
-               } else {
-                       ret = nand_write_ecc(nand, start,
-                                           min(len, eblk + erasesize - start),
-                                           (size_t *)&n, (u_char*)buf, (u_char *)eccbuf);
-               }
-
-               if (ret)
-                       break;
-
-               start  += n;
-               buf   += n;
-               total += n;
-               len   -= n;
-       }
-       if (retlen)
-               *retlen = total;
-
-       return ret;
-}
-
-void nand_print(struct nand_chip *nand)
-{
-       if (nand->numchips > 1) {
-               printf("%s at 0x%lx,\n"
-                      "\t  %d chips %s, size %d MB, \n"
-                      "\t  total size %ld MB, sector size %ld kB\n",
-                      nand->name, nand->IO_ADDR, nand->numchips,
-                      nand->chips_name, 1 << (nand->chipshift - 20),
-                      nand->totlen >> 20, nand->erasesize >> 10);
-       }
-       else {
-               printf("%s at 0x%lx (", nand->chips_name, nand->IO_ADDR);
-               print_size(nand->totlen, ", ");
-               print_size(nand->erasesize, " sector)\n");
-       }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int NanD_WaitReady(struct nand_chip *nand, int ale_wait)
-{
-       /* This is inline, to optimise the common case, where it's ready instantly */
-       int ret = 0;
-
-#ifdef NAND_NO_RB      /* in config file, shorter delays currently wrap accesses */
-       if(ale_wait)
-               NAND_WAIT_READY(nand);  /* do the worst case 25us wait */
-       else
-               udelay(10);
-#else  /* has functional r/b signal */
-       NAND_WAIT_READY(nand);
-#endif
-       return ret;
-}
-
-/* NanD_Command: Send a flash command to the flash chip */
-
-static inline int NanD_Command(struct nand_chip *nand, unsigned char command)
-{
-       unsigned long nandptr = nand->IO_ADDR;
-
-       /* Assert the CLE (Command Latch Enable) line to the flash chip */
-       NAND_CTL_SETCLE(nandptr);
-
-       /* Send the command */
-       WRITE_NAND_COMMAND(command, nandptr);
-
-       /* Lower the CLE line */
-       NAND_CTL_CLRCLE(nandptr);
-
-#ifdef NAND_NO_RB
-       if(command == NAND_CMD_RESET){
-               u_char ret_val;
-               NanD_Command(nand, NAND_CMD_STATUS);
-               do {
-                       ret_val = READ_NAND(nandptr);/* wait till ready */
-               } while((ret_val & 0x40) != 0x40);
-       }
-#endif
-       return NanD_WaitReady(nand, 0);
-}
-
-/* NanD_Address: Set the current address for the flash chip */
-
-static int NanD_Address(struct nand_chip *nand, int numbytes, unsigned long ofs)
-{
-       unsigned long nandptr;
-       int i;
-
-       nandptr = nand->IO_ADDR;
-
-       /* Assert the ALE (Address Latch Enable) line to the flash chip */
-       NAND_CTL_SETALE(nandptr);
-
-       /* Send the address */
-       /* Devices with 256-byte page are addressed as:
-        * Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
-        * there is no device on the market with page256
-        * and more than 24 bits.
-        * Devices with 512-byte page are addressed as:
-        * Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
-        * 25-31 is sent only if the chip support it.
-        * bit 8 changes the read command to be sent
-        * (NAND_CMD_READ0 or NAND_CMD_READ1).
-        */
-
-       if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE)
-               WRITE_NAND_ADDRESS(ofs, nandptr);
-
-       ofs = ofs >> nand->page_shift;
-
-       if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) {
-               for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8) {
-                       WRITE_NAND_ADDRESS(ofs, nandptr);
-               }
-       }
-
-       /* Lower the ALE line */
-       NAND_CTL_CLRALE(nandptr);
-
-       /* Wait for the chip to respond */
-       return NanD_WaitReady(nand, 1);
-}
-
-/* NanD_SelectChip: Select a given flash chip within the current floor */
-
-static inline int NanD_SelectChip(struct nand_chip *nand, int chip)
-{
-       /* Wait for it to be ready */
-       return NanD_WaitReady(nand, 0);
-}
-
-/* NanD_IdentChip: Identify a given NAND chip given {floor,chip} */
-
-static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)
-{
-       int mfr, id, i;
-
-       NAND_ENABLE_CE(nand);  /* set pin low */
-       /* Reset the chip */
-       if (NanD_Command(nand, NAND_CMD_RESET)) {
-#ifdef NAND_DEBUG
-               printf("NanD_Command (reset) for %d,%d returned true\n",
-                      floor, chip);
-#endif
-               NAND_DISABLE_CE(nand);  /* set pin high */
-               return 0;
-       }
-
-       /* Read the NAND chip ID: 1. Send ReadID command */
-       if (NanD_Command(nand, NAND_CMD_READID)) {
-#ifdef NAND_DEBUG
-               printf("NanD_Command (ReadID) for %d,%d returned true\n",
-                      floor, chip);
-#endif
-               NAND_DISABLE_CE(nand);  /* set pin high */
-               return 0;
-       }
-
-       /* Read the NAND chip ID: 2. Send address byte zero */
-       NanD_Address(nand, ADDR_COLUMN, 0);
-
-       /* Read the manufacturer and device id codes from the device */
-
-       mfr = READ_NAND(nand->IO_ADDR);
-
-       id = READ_NAND(nand->IO_ADDR);
-
-       NAND_DISABLE_CE(nand);  /* set pin high */
-
-#ifdef NAND_DEBUG
-       printf("NanD_Command (ReadID) got %x %x\n", mfr, id);
-#endif
-       if (mfr == 0xff || mfr == 0) {
-               /* No response - return failure */
-               return 0;
-       }
-
-       /* Check it's the same as the first chip we identified.
-        * M-Systems say that any given nand_chip device should only
-        * contain _one_ type of flash part, although that's not a
-        * hardware restriction. */
-       if (nand->mfr) {
-               if (nand->mfr == mfr && nand->id == id) {
-                       return 1;       /* This is another the same the first */
-               } else {
-                       printf("Flash chip at floor %d, chip %d is different:\n",
-                              floor, chip);
-               }
-       }
-
-       /* Print and store the manufacturer and ID codes. */
-       for (i = 0; nand_flash_ids[i].name != NULL; i++) {
-               if (mfr == nand_flash_ids[i].manufacture_id &&
-                   id == nand_flash_ids[i].model_id) {
-#ifdef NAND_DEBUG
-                       printf("Flash chip found:\n\t Manufacturer ID: 0x%2.2X, "
-                              "Chip ID: 0x%2.2X (%s)\n", mfr, id,
-                              nand_flash_ids[i].name);
-#endif
-                       if (!nand->mfr) {
-                               nand->mfr = mfr;
-                               nand->id = id;
-                               nand->chipshift =
-                                   nand_flash_ids[i].chipshift;
-                               nand->page256 = nand_flash_ids[i].page256;
-                               nand->eccsize = 256;
-                               if (nand->page256) {
-                                       nand->oobblock = 256;
-                                       nand->oobsize = 8;
-                                       nand->page_shift = 8;
-                               } else {
-                                       nand->oobblock = 512;
-                                       nand->oobsize = 16;
-                                       nand->page_shift = 9;
-                               }
-                               nand->pageadrlen = nand_flash_ids[i].pageadrlen;
-                               nand->erasesize  = nand_flash_ids[i].erasesize;
-                               nand->chips_name = nand_flash_ids[i].name;
-                               nand->bus16      = nand_flash_ids[i].bus16;
-                               return 1;
-                       }
-                       return 0;
-               }
-       }
-
-
-#ifdef NAND_DEBUG
-       /* We haven't fully identified the chip. Print as much as we know. */
-       printf("Unknown flash chip found: %2.2X %2.2X\n",
-              id, mfr);
-#endif
-
-       return 0;
-}
-
-/* NanD_ScanChips: Find all NAND chips present in a nand_chip, and identify them */
-
-static void NanD_ScanChips(struct nand_chip *nand)
-{
-       int floor, chip;
-       int numchips[NAND_MAX_FLOORS];
-       int maxchips = NAND_MAX_CHIPS;
-       int ret = 1;
-
-       nand->numchips = 0;
-       nand->mfr = 0;
-       nand->id = 0;
-
-
-       /* For each floor, find the number of valid chips it contains */
-       for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
-               ret = 1;
-               numchips[floor] = 0;
-               for (chip = 0; chip < maxchips && ret != 0; chip++) {
-
-                       ret = NanD_IdentChip(nand, floor, chip);
-                       if (ret) {
-                               numchips[floor]++;
-                               nand->numchips++;
-                       }
-               }
-       }
-
-       /* If there are none at all that we recognise, bail */
-       if (!nand->numchips) {
-#ifdef NAND_DEBUG
-               puts ("No NAND flash chips recognised.\n");
-#endif
-               return;
-       }
-
-       /* Allocate an array to hold the information for each chip */
-       nand->chips = malloc(sizeof(struct Nand) * nand->numchips);
-       if (!nand->chips) {
-               puts ("No memory for allocating chip info structures\n");
-               return;
-       }
-
-       ret = 0;
-
-       /* Fill out the chip array with {floor, chipno} for each
-        * detected chip in the device. */
-       for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
-               for (chip = 0; chip < numchips[floor]; chip++) {
-                       nand->chips[ret].floor = floor;
-                       nand->chips[ret].chip = chip;
-                       nand->chips[ret].curadr = 0;
-                       nand->chips[ret].curmode = 0x50;
-                       ret++;
-               }
-       }
-
-       /* Calculate and print the total size of the device */
-       nand->totlen = nand->numchips * (1 << nand->chipshift);
-
-#ifdef NAND_DEBUG
-       printf("%d flash chips found. Total nand_chip size: %ld MB\n",
-              nand->numchips, nand->totlen >> 20);
-#endif
-}
-
-/* we need to be fast here, 1 us per read translates to 1 second per meg */
-static void NanD_ReadBuf (struct nand_chip *nand, u_char * data_buf, int cntr)
-{
-       unsigned long nandptr = nand->IO_ADDR;
-
-       NanD_Command (nand, NAND_CMD_READ0);
-
-       if (nand->bus16) {
-               u16 val;
-
-               while (cntr >= 16) {
-                       val = READ_NAND (nandptr);
-                       *data_buf++ = val & 0xff;
-                       *data_buf++ = val >> 8;
-                       val = READ_NAND (nandptr);
-                       *data_buf++ = val & 0xff;
-                       *data_buf++ = val >> 8;
-                       val = READ_NAND (nandptr);
-                       *data_buf++ = val & 0xff;
-                       *data_buf++ = val >> 8;
-                       val = READ_NAND (nandptr);
-                       *data_buf++ = val & 0xff;
-                       *data_buf++ = val >> 8;
-                       val = READ_NAND (nandptr);
-                       *data_buf++ = val & 0xff;
-                       *data_buf++ = val >> 8;
-                       val = READ_NAND (nandptr);
-                       *data_buf++ = val & 0xff;
-                       *data_buf++ = val >> 8;
-                       val = READ_NAND (nandptr);
-                       *data_buf++ = val & 0xff;
-                       *data_buf++ = val >> 8;
-                       val = READ_NAND (nandptr);
-                       *data_buf++ = val & 0xff;
-                       *data_buf++ = val >> 8;
-                       cntr -= 16;
-               }
-
-               while (cntr > 0) {
-                       val = READ_NAND (nandptr);
-                       *data_buf++ = val & 0xff;
-                       *data_buf++ = val >> 8;
-                       cntr -= 2;
-               }
-       } else {
-               while (cntr >= 16) {
-                       *data_buf++ = READ_NAND (nandptr);
-                       *data_buf++ = READ_NAND (nandptr);
-                       *data_buf++ = READ_NAND (nandptr);
-                       *data_buf++ = READ_NAND (nandptr);
-                       *data_buf++ = READ_NAND (nandptr);
-                       *data_buf++ = READ_NAND (nandptr);
-                       *data_buf++ = READ_NAND (nandptr);
-                       *data_buf++ = READ_NAND (nandptr);
-                       *data_buf++ = READ_NAND (nandptr);
-                       *data_buf++ = READ_NAND (nandptr);
-                       *data_buf++ = READ_NAND (nandptr);
-                       *data_buf++ = READ_NAND (nandptr);
-                       *data_buf++ = READ_NAND (nandptr);
-                       *data_buf++ = READ_NAND (nandptr);
-                       *data_buf++ = READ_NAND (nandptr);
-                       *data_buf++ = READ_NAND (nandptr);
-                       cntr -= 16;
-               }
-
-               while (cntr > 0) {
-                       *data_buf++ = READ_NAND (nandptr);
-                       cntr--;
-               }
-       }
-}
-
-/*
- * NAND read with ECC
- */
-static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
-                size_t * retlen, u_char *buf, u_char *ecc_code)
-{
-       int col, page;
-       int ecc_status = 0;
-#ifdef CONFIG_MTD_NAND_ECC
-       int j;
-       int ecc_failed = 0;
-       u_char *data_poi;
-       u_char ecc_calc[6];
-#endif
-
-       /* Do not allow reads past end of device */
-       if ((start + len) > nand->totlen) {
-               printf ("%s: Attempt read beyond end of device %x %x %x\n",
-                       __FUNCTION__, (uint) start, (uint) len, (uint) nand->totlen);
-               *retlen = 0;
-               return -1;
-       }
-
-       /* First we calculate the starting page */
-       /*page = shr(start, nand->page_shift);*/
-       page = start >> nand->page_shift;
-
-       /* Get raw starting column */
-       col = start & (nand->oobblock - 1);
-
-       /* Initialize return value */
-       *retlen = 0;
-
-       /* Select the NAND device */
-       NAND_ENABLE_CE(nand);  /* set pin low */
-
-       /* Loop until all data read */
-       while (*retlen < len) {
-
-#ifdef CONFIG_MTD_NAND_ECC
-               /* Do we have this page in cache ? */
-               if (nand->cache_page == page)
-                       goto readdata;
-               /* Send the read command */
-               NanD_Command(nand, NAND_CMD_READ0);
-               if (nand->bus16) {
-                       NanD_Address(nand, ADDR_COLUMN_PAGE,
-                                    (page << nand->page_shift) + (col >> 1));
-               } else {
-                       NanD_Address(nand, ADDR_COLUMN_PAGE,
-                                    (page << nand->page_shift) + col);
-               }
-
-               /* Read in a page + oob data */
-               NanD_ReadBuf(nand, nand->data_buf, nand->oobblock + nand->oobsize);
-
-               /* copy data into cache, for read out of cache and if ecc fails */
-               if (nand->data_cache) {
-                       memcpy (nand->data_cache, nand->data_buf,
-                               nand->oobblock + nand->oobsize);
-               }
-
-               /* Pick the ECC bytes out of the oob data */
-               for (j = 0; j < 6; j++) {
-                       ecc_code[j] = nand->data_buf[(nand->oobblock + oob_config.ecc_pos[j])];
-               }
-
-               /* Calculate the ECC and verify it */
-               /* If block was not written with ECC, skip ECC */
-               if (oob_config.eccvalid_pos != -1 &&
-                   (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0x0f) != 0x0f) {
-
-                       nand_calculate_ecc (&nand->data_buf[0], &ecc_calc[0]);
-                       switch (nand_correct_data (&nand->data_buf[0], &ecc_code[0], &ecc_calc[0])) {
-                       case -1:
-                               printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
-                               ecc_failed++;
-                               break;
-                       case 1:
-                       case 2: /* transfer ECC corrected data to cache */
-                               if (nand->data_cache)
-                                       memcpy (nand->data_cache, nand->data_buf, 256);
-                               break;
-                       }
-               }
-
-               if (oob_config.eccvalid_pos != -1 &&
-                   nand->oobblock == 512 && (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0xf0) != 0xf0) {
-
-                       nand_calculate_ecc (&nand->data_buf[256], &ecc_calc[3]);
-                       switch (nand_correct_data (&nand->data_buf[256], &ecc_code[3], &ecc_calc[3])) {
-                       case -1:
-                               printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
-                               ecc_failed++;
-                               break;
-                       case 1:
-                       case 2: /* transfer ECC corrected data to cache */
-                               if (nand->data_cache)
-                                       memcpy (&nand->data_cache[256], &nand->data_buf[256], 256);
-                               break;
-                       }
-               }
-readdata:
-               /* Read the data from ECC data buffer into return buffer */
-               data_poi = (nand->data_cache) ? nand->data_cache : nand->data_buf;
-               data_poi += col;
-               if ((*retlen + (nand->oobblock - col)) >= len) {
-                       memcpy (buf + *retlen, data_poi, len - *retlen);
-                       *retlen = len;
-               } else {
-                       memcpy (buf + *retlen, data_poi,  nand->oobblock - col);
-                       *retlen += nand->oobblock - col;
-               }
-               /* Set cache page address, invalidate, if ecc_failed */
-               nand->cache_page = (nand->data_cache && !ecc_failed) ? page : -1;
-
-               ecc_status += ecc_failed;
-               ecc_failed = 0;
-
-#else
-               /* Send the read command */
-               NanD_Command(nand, NAND_CMD_READ0);
-               if (nand->bus16) {
-                       NanD_Address(nand, ADDR_COLUMN_PAGE,
-                                    (page << nand->page_shift) + (col >> 1));
-               } else {
-                       NanD_Address(nand, ADDR_COLUMN_PAGE,
-                                    (page << nand->page_shift) + col);
-               }
-
-               /* Read the data directly into the return buffer */
-               if ((*retlen + (nand->oobblock - col)) >= len) {
-                       NanD_ReadBuf(nand, buf + *retlen, len - *retlen);
-                       *retlen = len;
-                       /* We're done */
-                       continue;
-               } else {
-                       NanD_ReadBuf(nand, buf + *retlen, nand->oobblock - col);
-                       *retlen += nand->oobblock - col;
-                       }
-#endif
-               /* For subsequent reads align to page boundary. */
-               col = 0;
-               /* Increment page address */
-               page++;
-       }
-
-       /* De-select the NAND device */
-       NAND_DISABLE_CE(nand);  /* set pin high */
-
-       /*
-        * Return success, if no ECC failures, else -EIO
-        * fs driver will take care of that, because
-        * retlen == desired len and result == -EIO
-        */
-       return ecc_status ? -1 : 0;
-}
-
-/*
- *     Nand_page_program function is used for write and writev !
- */
-static int nand_write_page (struct nand_chip *nand,
-                           int page, int col, int last, u_char * ecc_code)
-{
-
-       int i;
-       unsigned long nandptr = nand->IO_ADDR;
-
-#ifdef CONFIG_MTD_NAND_ECC
-#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
-       int ecc_bytes = (nand->oobblock == 512) ? 6 : 3;
-#endif
-#endif
-       /* pad oob area */
-       for (i = nand->oobblock; i < nand->oobblock + nand->oobsize; i++)
-               nand->data_buf[i] = 0xff;
-
-#ifdef CONFIG_MTD_NAND_ECC
-       /* Zero out the ECC array */
-       for (i = 0; i < 6; i++)
-               ecc_code[i] = 0x00;
-
-       /* Read back previous written data, if col > 0 */
-       if (col) {
-               NanD_Command (nand, NAND_CMD_READ0);
-               if (nand->bus16) {
-                       NanD_Address (nand, ADDR_COLUMN_PAGE,
-                                     (page << nand->page_shift) + (col >> 1));
-               } else {
-                       NanD_Address (nand, ADDR_COLUMN_PAGE,
-                                     (page << nand->page_shift) + col);
-               }
-
-               if (nand->bus16) {
-                       u16 val;
-
-                       for (i = 0; i < col; i += 2) {
-                               val = READ_NAND (nandptr);
-                               nand->data_buf[i] = val & 0xff;
-                               nand->data_buf[i + 1] = val >> 8;
-                       }
-               } else {
-                       for (i = 0; i < col; i++)
-                               nand->data_buf[i] = READ_NAND (nandptr);
-               }
-       }
-
-       /* Calculate and write the ECC if we have enough data */
-       if ((col < nand->eccsize) && (last >= nand->eccsize)) {
-               nand_calculate_ecc (&nand->data_buf[0], &(ecc_code[0]));
-               for (i = 0; i < 3; i++) {
-                       nand->data_buf[(nand->oobblock +
-                                       oob_config.ecc_pos[i])] = ecc_code[i];
-               }
-               if (oob_config.eccvalid_pos != -1) {
-                       nand->data_buf[nand->oobblock +
-                                      oob_config.eccvalid_pos] = 0xf0;
-               }
-       }
-
-       /* Calculate and write the second ECC if we have enough data */
-       if ((nand->oobblock == 512) && (last == nand->oobblock)) {
-               nand_calculate_ecc (&nand->data_buf[256], &(ecc_code[3]));
-               for (i = 3; i < 6; i++) {
-                       nand->data_buf[(nand->oobblock +
-                                       oob_config.ecc_pos[i])] = ecc_code[i];
-               }
-               if (oob_config.eccvalid_pos != -1) {
-                       nand->data_buf[nand->oobblock +
-                                      oob_config.eccvalid_pos] &= 0x0f;
-               }
-       }
-#endif
-       /* Prepad for partial page programming !!! */
-       for (i = 0; i < col; i++)
-               nand->data_buf[i] = 0xff;
-
-       /* Postpad for partial page programming !!! oob is already padded */
-       for (i = last; i < nand->oobblock; i++)
-               nand->data_buf[i] = 0xff;
-
-       /* Send command to begin auto page programming */
-       NanD_Command (nand, NAND_CMD_READ0);
-       NanD_Command (nand, NAND_CMD_SEQIN);
-       if (nand->bus16) {
-               NanD_Address (nand, ADDR_COLUMN_PAGE,
-                             (page << nand->page_shift) + (col >> 1));
-       } else {
-               NanD_Address (nand, ADDR_COLUMN_PAGE,
-                             (page << nand->page_shift) + col);
-       }
-
-       /* Write out complete page of data */
-       if (nand->bus16) {
-               for (i = 0; i < (nand->oobblock + nand->oobsize); i += 2) {
-                       WRITE_NAND (nand->data_buf[i] +
-                                   (nand->data_buf[i + 1] << 8),
-                                   nand->IO_ADDR);
-               }
-       } else {
-               for (i = 0; i < (nand->oobblock + nand->oobsize); i++)
-                       WRITE_NAND (nand->data_buf[i], nand->IO_ADDR);
-       }
-
-       /* Send command to actually program the data */
-       NanD_Command (nand, NAND_CMD_PAGEPROG);
-       NanD_Command (nand, NAND_CMD_STATUS);
-#ifdef NAND_NO_RB
-       {
-               u_char ret_val;
-
-               do {
-                       ret_val = READ_NAND (nandptr);  /* wait till ready */
-               } while ((ret_val & 0x40) != 0x40);
-       }
-#endif
-       /* See if device thinks it succeeded */
-       if (READ_NAND (nand->IO_ADDR) & 0x01) {
-               printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__,
-                       page);
-               return -1;
-       }
-#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
-       /*
-        * The NAND device assumes that it is always writing to
-        * a cleanly erased page. Hence, it performs its internal
-        * write verification only on bits that transitioned from
-        * 1 to 0. The device does NOT verify the whole page on a
-        * byte by byte basis. It is possible that the page was
-        * not completely erased or the page is becoming unusable
-        * due to wear. The read with ECC would catch the error
-        * later when the ECC page check fails, but we would rather
-        * catch it early in the page write stage. Better to write
-        * no data than invalid data.
-        */
-
-       /* Send command to read back the page */
-       if (col < nand->eccsize)
-               NanD_Command (nand, NAND_CMD_READ0);
-       else
-               NanD_Command (nand, NAND_CMD_READ1);
-       if (nand->bus16) {
-               NanD_Address (nand, ADDR_COLUMN_PAGE,
-                             (page << nand->page_shift) + (col >> 1));
-       } else {
-               NanD_Address (nand, ADDR_COLUMN_PAGE,
-                             (page << nand->page_shift) + col);
-       }
-
-       /* Loop through and verify the data */
-       if (nand->bus16) {
-               for (i = col; i < last; i = +2) {
-                       if ((nand->data_buf[i] +
-                            (nand->data_buf[i + 1] << 8)) != READ_NAND (nand->IO_ADDR)) {
-                               printf ("%s: Failed write verify, page 0x%08x ",
-                                       __FUNCTION__, page);
-                               return -1;
-                       }
-               }
-       } else {
-               for (i = col; i < last; i++) {
-                       if (nand->data_buf[i] != READ_NAND (nand->IO_ADDR)) {
-                               printf ("%s: Failed write verify, page 0x%08x ",
-                                       __FUNCTION__, page);
-                               return -1;
-                       }
-               }
-       }
-
-#ifdef CONFIG_MTD_NAND_ECC
-       /*
-        * We also want to check that the ECC bytes wrote
-        * correctly for the same reasons stated above.
-        */
-       NanD_Command (nand, NAND_CMD_READOOB);
-       if (nand->bus16) {
-               NanD_Address (nand, ADDR_COLUMN_PAGE,
-                             (page << nand->page_shift) + (col >> 1));
-       } else {
-               NanD_Address (nand, ADDR_COLUMN_PAGE,
-                             (page << nand->page_shift) + col);
-       }
-       if (nand->bus16) {
-               for (i = 0; i < nand->oobsize; i += 2) {
-                       u16 val;
-
-                       val = READ_NAND (nand->IO_ADDR);
-                       nand->data_buf[i] = val & 0xff;
-                       nand->data_buf[i + 1] = val >> 8;
-               }
-       } else {
-               for (i = 0; i < nand->oobsize; i++) {
-                       nand->data_buf[i] = READ_NAND (nand->IO_ADDR);
-               }
-       }
-       for (i = 0; i < ecc_bytes; i++) {
-               if ((nand->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) {
-                       printf ("%s: Failed ECC write "
-                               "verify, page 0x%08x, "
-                               "%6i bytes were succesful\n",
-                               __FUNCTION__, page, i);
-                       return -1;
-               }
-       }
-#endif /* CONFIG_MTD_NAND_ECC */
-#endif /* CONFIG_MTD_NAND_VERIFY_WRITE */
-       return 0;
-}
-
-static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
-                          size_t * retlen, const u_char * buf, u_char * ecc_code)
-{
-       int i, page, col, cnt, ret = 0;
-
-       /* Do not allow write past end of device */
-       if ((to + len) > nand->totlen) {
-               printf ("%s: Attempt to write past end of page\n", __FUNCTION__);
-               return -1;
-       }
-
-       /* Shift to get page */
-       page = ((int) to) >> nand->page_shift;
-
-       /* Get the starting column */
-       col = to & (nand->oobblock - 1);
-
-       /* Initialize return length value */
-       *retlen = 0;
-
-       /* Select the NAND device */
-#ifdef CONFIG_OMAP1510
-       archflashwp(0,0);
-#endif
-#ifdef CFG_NAND_WP
-       NAND_WP_OFF();
-#endif
-
-       NAND_ENABLE_CE(nand);  /* set pin low */
-
-       /* Check the WP bit */
-       NanD_Command(nand, NAND_CMD_STATUS);
-       if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
-               printf ("%s: Device is write protected!!!\n", __FUNCTION__);
-               ret = -1;
-               goto out;
-       }
-
-       /* Loop until all data is written */
-       while (*retlen < len) {
-               /* Invalidate cache, if we write to this page */
-               if (nand->cache_page == page)
-                       nand->cache_page = -1;
-
-               /* Write data into buffer */
-               if ((col + len) >= nand->oobblock) {
-                       for (i = col, cnt = 0; i < nand->oobblock; i++, cnt++) {
-                               nand->data_buf[i] = buf[(*retlen + cnt)];
-                       }
-               } else {
-                       for (i = col, cnt = 0; cnt < (len - *retlen); i++, cnt++) {
-                               nand->data_buf[i] = buf[(*retlen + cnt)];
-                       }
-               }
-               /* We use the same function for write and writev !) */
-               ret = nand_write_page (nand, page, col, i, ecc_code);
-               if (ret)
-                       goto out;
-
-               /* Next data start at page boundary */
-               col = 0;
-
-               /* Update written bytes count */
-               *retlen += cnt;
-
-               /* Increment page address */
-               page++;
-       }
-
-       /* Return happy */
-       *retlen = len;
-
-out:
-       /* De-select the NAND device */
-       NAND_DISABLE_CE(nand);  /* set pin high */
-#ifdef CONFIG_OMAP1510
-       archflashwp(0,1);
-#endif
-#ifdef CFG_NAND_WP
-       NAND_WP_ON();
-#endif
-
-       return ret;
-}
-
-/* read from the 16 bytes of oob data that correspond to a 512 byte
- * page or 2 256-byte pages.
- */
-int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
-                        size_t * retlen, u_char * buf)
-{
-       int len256 = 0;
-       struct Nand *mychip;
-       int ret = 0;
-
-       mychip = &nand->chips[ofs >> nand->chipshift];
-
-       /* update address for 2M x 8bit devices. OOB starts on the second */
-       /* page to maintain compatibility with nand_read_ecc. */
-       if (nand->page256) {
-               if (!(ofs & 0x8))
-                       ofs += 0x100;
-               else
-                       ofs -= 0x8;
-       }
-
-       NAND_ENABLE_CE(nand);  /* set pin low */
-       NanD_Command(nand, NAND_CMD_READOOB);
-       if (nand->bus16) {
-               NanD_Address(nand, ADDR_COLUMN_PAGE,
-                            ((ofs >> nand->page_shift) << nand->page_shift) +
-                               ((ofs & (nand->oobblock - 1)) >> 1));
-       } else {
-               NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
-       }
-
-       /* treat crossing 8-byte OOB data for 2M x 8bit devices */
-       /* Note: datasheet says it should automaticaly wrap to the */
-       /*       next OOB block, but it didn't work here. mf.      */
-       if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
-               len256 = (ofs | 0x7) + 1 - ofs;
-               NanD_ReadBuf(nand, buf, len256);
-
-               NanD_Command(nand, NAND_CMD_READOOB);
-               NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
-       }
-
-       NanD_ReadBuf(nand, &buf[len256], len - len256);
-
-       *retlen = len;
-       /* Reading the full OOB data drops us off of the end of the page,
-        * causing the flash device to go into busy mode, so we need
-        * to wait until ready 11.4.1 and Toshiba TC58256FT nands */
-
-       ret = NanD_WaitReady(nand, 1);
-       NAND_DISABLE_CE(nand);  /* set pin high */
-
-       return ret;
-
-}
-
-/* write to the 16 bytes of oob data that correspond to a 512 byte
- * page or 2 256-byte pages.
- */
-int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
-                 size_t * retlen, const u_char * buf)
-{
-       int len256 = 0;
-       int i;
-       unsigned long nandptr = nand->IO_ADDR;
-
-#ifdef PSYCHO_DEBUG
-       printf("nand_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",
-              (long)ofs, len, buf[0], buf[1], buf[2], buf[3],
-              buf[8], buf[9], buf[14],buf[15]);
-#endif
-
-       NAND_ENABLE_CE(nand);  /* set pin low to enable chip */
-
-       /* Reset the chip */
-       NanD_Command(nand, NAND_CMD_RESET);
-
-       /* issue the Read2 command to set the pointer to the Spare Data Area. */
-       NanD_Command(nand, NAND_CMD_READOOB);
-       if (nand->bus16) {
-               NanD_Address(nand, ADDR_COLUMN_PAGE,
-                            ((ofs >> nand->page_shift) << nand->page_shift) +
-                               ((ofs & (nand->oobblock - 1)) >> 1));
-       } else {
-               NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
-       }
-
-       /* update address for 2M x 8bit devices. OOB starts on the second */
-       /* page to maintain compatibility with nand_read_ecc. */
-       if (nand->page256) {
-               if (!(ofs & 0x8))
-                       ofs += 0x100;
-               else
-                       ofs -= 0x8;
-       }
-
-       /* issue the Serial Data In command to initial the Page Program process */
-       NanD_Command(nand, NAND_CMD_SEQIN);
-       if (nand->bus16) {
-               NanD_Address(nand, ADDR_COLUMN_PAGE,
-                            ((ofs >> nand->page_shift) << nand->page_shift) +
-                               ((ofs & (nand->oobblock - 1)) >> 1));
-       } else {
-               NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
-       }
-
-       /* treat crossing 8-byte OOB data for 2M x 8bit devices */
-       /* Note: datasheet says it should automaticaly wrap to the */
-       /*       next OOB block, but it didn't work here. mf.      */
-       if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
-               len256 = (ofs | 0x7) + 1 - ofs;
-               for (i = 0; i < len256; i++)
-                       WRITE_NAND(buf[i], nandptr);
-
-               NanD_Command(nand, NAND_CMD_PAGEPROG);
-               NanD_Command(nand, NAND_CMD_STATUS);
-#ifdef NAND_NO_RB
-               { u_char ret_val;
-                       do {
-                               ret_val = READ_NAND(nandptr); /* wait till ready */
-                       } while ((ret_val & 0x40) != 0x40);
-               }
-#endif
-               if (READ_NAND(nandptr) & 1) {
-                       puts ("Error programming oob data\n");
-                       /* There was an error */
-                       NAND_DISABLE_CE(nand);  /* set pin high */
-                       *retlen = 0;
-                       return -1;
-               }
-               NanD_Command(nand, NAND_CMD_SEQIN);
-               NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
-       }
-
-       if (nand->bus16) {
-               for (i = len256; i < len; i += 2) {
-                       WRITE_NAND(buf[i] + (buf[i+1] << 8), nandptr);
-               }
-       } else {
-               for (i = len256; i < len; i++)
-                       WRITE_NAND(buf[i], nandptr);
-       }
-
-       NanD_Command(nand, NAND_CMD_PAGEPROG);
-       NanD_Command(nand, NAND_CMD_STATUS);
-#ifdef NAND_NO_RB
-       {       u_char ret_val;
-               do {
-                       ret_val = READ_NAND(nandptr); /* wait till ready */
-               } while ((ret_val & 0x40) != 0x40);
-       }
-#endif
-       if (READ_NAND(nandptr) & 1) {
-               puts ("Error programming oob data\n");
-               /* There was an error */
-               NAND_DISABLE_CE(nand);  /* set pin high */
-               *retlen = 0;
-               return -1;
-       }
-
-       NAND_DISABLE_CE(nand);  /* set pin high */
-       *retlen = len;
-       return 0;
-
-}
-
-int nand_legacy_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean)
-{
-       /* This is defined as a structure so it will work on any system
-        * using native endian jffs2 (the default).
-        */
-       static struct jffs2_unknown_node clean_marker = {
-               JFFS2_MAGIC_BITMASK,
-               JFFS2_NODETYPE_CLEANMARKER,
-               8               /* 8 bytes in this node */
-       };
-       unsigned long nandptr;
-       struct Nand *mychip;
-       int ret = 0;
-
-       if (ofs & (nand->erasesize-1) || len & (nand->erasesize-1)) {
-               printf ("Offset and size must be sector aligned, erasesize = %d\n",
-                       (int) nand->erasesize);
-               return -1;
-       }
-
-       nandptr = nand->IO_ADDR;
-
-       /* Select the NAND device */
-#ifdef CONFIG_OMAP1510
-       archflashwp(0,0);
-#endif
-#ifdef CFG_NAND_WP
-       NAND_WP_OFF();
-#endif
-    NAND_ENABLE_CE(nand);  /* set pin low */
-
-       /* Check the WP bit */
-       NanD_Command(nand, NAND_CMD_STATUS);
-       if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
-               printf ("nand_write_ecc: Device is write protected!!!\n");
-               ret = -1;
-               goto out;
-       }
-
-       /* Check the WP bit */
-       NanD_Command(nand, NAND_CMD_STATUS);
-       if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
-               printf ("%s: Device is write protected!!!\n", __FUNCTION__);
-               ret = -1;
-               goto out;
-       }
-
-       /* FIXME: Do nand in the background. Use timers or schedule_task() */
-       while(len) {
-               /*mychip = &nand->chips[shr(ofs, nand->chipshift)];*/
-               mychip = &nand->chips[ofs >> nand->chipshift];
-
-               /* always check for bad block first, genuine bad blocks
-                * should _never_  be erased.
-                */
-               if (ALLOW_ERASE_BAD_DEBUG || !check_block(nand, ofs)) {
-                       /* Select the NAND device */
-                       NAND_ENABLE_CE(nand);  /* set pin low */
-
-                       NanD_Command(nand, NAND_CMD_ERASE1);
-                       NanD_Address(nand, ADDR_PAGE, ofs);
-                       NanD_Command(nand, NAND_CMD_ERASE2);
-
-                       NanD_Command(nand, NAND_CMD_STATUS);
-
-#ifdef NAND_NO_RB
-                       {       u_char ret_val;
-                               do {
-                                       ret_val = READ_NAND(nandptr); /* wait till ready */
-                               } while ((ret_val & 0x40) != 0x40);
-                       }
-#endif
-                       if (READ_NAND(nandptr) & 1) {
-                               printf ("%s: Error erasing at 0x%lx\n",
-                                       __FUNCTION__, (long)ofs);
-                               /* There was an error */
-                               ret = -1;
-                               goto out;
-                       }
-                       if (clean) {
-                               int n;  /* return value not used */
-                               int p, l;
-
-                               /* clean marker position and size depend
-                                * on the page size, since 256 byte pages
-                                * only have 8 bytes of oob data
-                                */
-                               if (nand->page256) {
-                                       p = NAND_JFFS2_OOB8_FSDAPOS;
-                                       l = NAND_JFFS2_OOB8_FSDALEN;
-                               } else {
-                                       p = NAND_JFFS2_OOB16_FSDAPOS;
-                                       l = NAND_JFFS2_OOB16_FSDALEN;
-                               }
-
-                               ret = nand_write_oob(nand, ofs + p, l, (size_t *)&n,
-                                                    (u_char *)&clean_marker);
-                               /* quit here if write failed */
-                               if (ret)
-                                       goto out;
-                       }
-               }
-               ofs += nand->erasesize;
-               len -= nand->erasesize;
-       }
-
-out:
-       /* De-select the NAND device */
-       NAND_DISABLE_CE(nand);  /* set pin high */
-#ifdef CONFIG_OMAP1510
-       archflashwp(0,1);
-#endif
-#ifdef CFG_NAND_WP
-       NAND_WP_ON();
-#endif
-
-       return ret;
-}
-
-
-static inline int nandcheck(unsigned long potential, unsigned long physadr)
-{
-       return 0;
-}
-
-unsigned long nand_probe(unsigned long physadr)
-{
-       struct nand_chip *nand = NULL;
-       int i = 0, ChipID = 1;
-
-#ifdef CONFIG_MTD_NAND_ECC_JFFS2
-       oob_config.ecc_pos[0] = NAND_JFFS2_OOB_ECCPOS0;
-       oob_config.ecc_pos[1] = NAND_JFFS2_OOB_ECCPOS1;
-       oob_config.ecc_pos[2] = NAND_JFFS2_OOB_ECCPOS2;
-       oob_config.ecc_pos[3] = NAND_JFFS2_OOB_ECCPOS3;
-       oob_config.ecc_pos[4] = NAND_JFFS2_OOB_ECCPOS4;
-       oob_config.ecc_pos[5] = NAND_JFFS2_OOB_ECCPOS5;
-       oob_config.eccvalid_pos = 4;
-#else
-       oob_config.ecc_pos[0] = NAND_NOOB_ECCPOS0;
-       oob_config.ecc_pos[1] = NAND_NOOB_ECCPOS1;
-       oob_config.ecc_pos[2] = NAND_NOOB_ECCPOS2;
-       oob_config.ecc_pos[3] = NAND_NOOB_ECCPOS3;
-       oob_config.ecc_pos[4] = NAND_NOOB_ECCPOS4;
-       oob_config.ecc_pos[5] = NAND_NOOB_ECCPOS5;
-       oob_config.eccvalid_pos = NAND_NOOB_ECCVPOS;
-#endif
-       oob_config.badblock_pos = 5;
-
-       for (i=0; i<CFG_MAX_NAND_DEVICE; i++) {
-               if (nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN) {
-                       nand = &nand_dev_desc[i];
-                       break;
-               }
-       }
-       if (!nand)
-               return (0);
-
-       memset((char *)nand, 0, sizeof(struct nand_chip));
-
-       nand->IO_ADDR = physadr;
-       nand->cache_page = -1;  /* init the cache page */
-       NanD_ScanChips(nand);
-
-       if (nand->totlen == 0) {
-               /* no chips found, clean up and quit */
-               memset((char *)nand, 0, sizeof(struct nand_chip));
-               nand->ChipID = NAND_ChipID_UNKNOWN;
-               return (0);
-       }
-
-       nand->ChipID = ChipID;
-       if (curr_device == -1)
-               curr_device = i;
-
-       nand->data_buf = malloc (nand->oobblock + nand->oobsize);
-       if (!nand->data_buf) {
-               puts ("Cannot allocate memory for data structures.\n");
-               return (0);
-       }
-
-       return (nand->totlen);
-}
-
-#ifdef CONFIG_MTD_NAND_ECC
-/*
- * Pre-calculated 256-way 1 byte column parity
- */
-static const u_char nand_ecc_precalc_table[] = {
-       0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
-       0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
-       0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
-       0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
-       0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
-       0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
-       0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
-       0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
-       0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
-       0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
-       0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
-       0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
-       0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
-       0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
-       0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
-       0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
-       0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
-       0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
-       0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
-       0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
-       0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
-       0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
-       0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
-       0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
-       0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
-       0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
-       0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
-       0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
-       0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
-       0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
-       0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
-       0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
-};
-
-
-/*
- * Creates non-inverted ECC code from line parity
- */
-static void nand_trans_result(u_char reg2, u_char reg3,
-       u_char *ecc_code)
-{
-       u_char a, b, i, tmp1, tmp2;
-
-       /* Initialize variables */
-       a = b = 0x80;
-       tmp1 = tmp2 = 0;
-
-       /* Calculate first ECC byte */
-       for (i = 0; i < 4; i++) {
-               if (reg3 & a)           /* LP15,13,11,9 --> ecc_code[0] */
-                       tmp1 |= b;
-               b >>= 1;
-               if (reg2 & a)           /* LP14,12,10,8 --> ecc_code[0] */
-                       tmp1 |= b;
-               b >>= 1;
-               a >>= 1;
-       }
-
-       /* Calculate second ECC byte */
-       b = 0x80;
-       for (i = 0; i < 4; i++) {
-               if (reg3 & a)           /* LP7,5,3,1 --> ecc_code[1] */
-                       tmp2 |= b;
-               b >>= 1;
-               if (reg2 & a)           /* LP6,4,2,0 --> ecc_code[1] */
-                       tmp2 |= b;
-               b >>= 1;
-               a >>= 1;
-       }
-
-       /* Store two of the ECC bytes */
-       ecc_code[0] = tmp1;
-       ecc_code[1] = tmp2;
-}
-
-/*
- * Calculate 3 byte ECC code for 256 byte block
- */
-static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code)
-{
-       u_char idx, reg1, reg3;
-       int j;
-
-       /* Initialize variables */
-       reg1 = reg3 = 0;
-       ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
-
-       /* Build up column parity */
-       for(j = 0; j < 256; j++) {
-
-               /* Get CP0 - CP5 from table */
-               idx = nand_ecc_precalc_table[dat[j]];
-               reg1 ^= idx;
-
-               /* All bit XOR = 1 ? */
-               if (idx & 0x40) {
-                       reg3 ^= (u_char) j;
-               }
-       }
-
-       /* Create non-inverted ECC code from line parity */
-       nand_trans_result((reg1 & 0x40) ? ~reg3 : reg3, reg3, ecc_code);
-
-       /* Calculate final ECC code */
-       ecc_code[0] = ~ecc_code[0];
-       ecc_code[1] = ~ecc_code[1];
-       ecc_code[2] = ((~reg1) << 2) | 0x03;
-}
-
-/*
- * Detect and correct a 1 bit error for 256 byte block
- */
-static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc)
-{
-       u_char a, b, c, d1, d2, d3, add, bit, i;
-
-       /* Do error detection */
-       d1 = calc_ecc[0] ^ read_ecc[0];
-       d2 = calc_ecc[1] ^ read_ecc[1];
-       d3 = calc_ecc[2] ^ read_ecc[2];
-
-       if ((d1 | d2 | d3) == 0) {
-               /* No errors */
-               return 0;
-       } else {
-               a = (d1 ^ (d1 >> 1)) & 0x55;
-               b = (d2 ^ (d2 >> 1)) & 0x55;
-               c = (d3 ^ (d3 >> 1)) & 0x54;
-
-               /* Found and will correct single bit error in the data */
-               if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
-                       c = 0x80;
-                       add = 0;
-                       a = 0x80;
-                       for (i=0; i<4; i++) {
-                               if (d1 & c)
-                                       add |= a;
-                               c >>= 2;
-                               a >>= 1;
-                       }
-                       c = 0x80;
-                       for (i=0; i<4; i++) {
-                               if (d2 & c)
-                                       add |= a;
-                               c >>= 2;
-                               a >>= 1;
-                       }
-                       bit = 0;
-                       b = 0x04;
-                       c = 0x80;
-                       for (i=0; i<3; i++) {
-                               if (d3 & c)
-                                       bit |= b;
-                               c >>= 2;
-                               b >>= 1;
-                       }
-                       b = 0x01;
-                       a = dat[add];
-                       a ^= (b << bit);
-                       dat[add] = a;
-                       return 1;
-               }
-               else {
-                       i = 0;
-                       while (d1) {
-                               if (d1 & 0x01)
-                                       ++i;
-                               d1 >>= 1;
-                       }
-                       while (d2) {
-                               if (d2 & 0x01)
-                                       ++i;
-                               d2 >>= 1;
-                       }
-                       while (d3) {
-                               if (d3 & 0x01)
-                                       ++i;
-                               d3 >>= 1;
-                       }
-                       if (i == 1) {
-                               /* ECC Code Error Correction */
-                               read_ecc[0] = calc_ecc[0];
-                               read_ecc[1] = calc_ecc[1];
-                               read_ecc[2] = calc_ecc[2];
-                               return 2;
-                       }
-                       else {
-                               /* Uncorrectable Error */
-                               return -1;
-                       }
-               }
-       }
-
-       /* Should never happen */
-       return -1;
-}
-
-#endif
-
-#ifdef CONFIG_JFFS2_NAND
-int read_jffs2_nand(size_t start, size_t len,
-               size_t * retlen, u_char * buf, int nanddev)
-{
-       return nand_legacy_rw(nand_dev_desc + nanddev, NANDRW_READ | NANDRW_JFFS2,
-                       start, len, retlen, buf);
-}
-#endif /* CONFIG_JFFS2_NAND */
-
-#endif
diff --git a/drivers/natsemi.c b/drivers/natsemi.c
deleted file mode 100644 (file)
index 075d6c5..0000000
+++ /dev/null
@@ -1,882 +0,0 @@
-/*
-   natsemi.c: A U-Boot driver for the NatSemi DP8381x series.
-   Author: Mark A. Rakes (mark_rakes@vivato.net)
-
-   Adapted from an Etherboot driver written by:
-
-   Copyright (C) 2001 Entity Cyber, Inc.
-
-   This development of this Etherboot driver was funded by
-
-      Sicom Systems: http://www.sicompos.com/
-
-   Author: Marty Connor (mdc@thinguin.org)
-   Adapted from a Linux driver which was written by Donald Becker
-
-   This software may be used and distributed according to the terms
-   of the GNU Public License (GPL), incorporated herein by reference.
-
-   Original Copyright Notice:
-
-   Written/copyright 1999-2001 by Donald Becker.
-
-   This software may be used and distributed according to the terms of
-   the GNU General Public License (GPL), incorporated herein by reference.
-   Drivers based on or derived from this code fall under the GPL and must
-   retain the authorship, copyright and license notice.  This file is not
-   a complete program and may only be used when the entire operating
-   system is licensed under the GPL.  License for under other terms may be
-   available.  Contact the original author for details.
-
-   The original author may be reached as becker@scyld.com, or at
-   Scyld Computing Corporation
-   410 Severn Ave., Suite 210
-   Annapolis MD 21403
-
-   Support information and updates available at
-   http://www.scyld.com/network/netsemi.html
-
-   References:
-   http://www.scyld.com/expert/100mbps.html
-   http://www.scyld.com/expert/NWay.html
-   Datasheet is available from:
-   http://www.national.com/pf/DP/DP83815.html
-*/
-
-/* Revision History
- * October 2002 mar    1.0
- *   Initial U-Boot Release.  Tested with Netgear FA311 board
- *   and dp83815 chipset on custom board
-*/
-
-/* Includes */
-#include <common.h>
-#include <malloc.h>
-#include <net.h>
-#include <asm/io.h>
-#include <pci.h>
-
-#if defined(CONFIG_CMD_NET) \
-       && defined(CONFIG_NET_MULTI) && defined(CONFIG_NATSEMI)
-
-/* defines */
-#define EEPROM_SIZE 0xb /*12 16-bit chunks, or 24 bytes*/
-
-#define DSIZE     0x00000FFF
-#define ETH_ALEN       6
-#define CRC_SIZE  4
-#define TOUT_LOOP   500000
-#define TX_BUF_SIZE    1536
-#define RX_BUF_SIZE    1536
-#define NUM_RX_DESC    4       /* Number of Rx descriptor registers. */
-
-/* Offsets to the device registers.
-   Unlike software-only systems, device drivers interact with complex hardware.
-   It's not useful to define symbolic names for every register bit in the
-   device.  */
-enum register_offsets {
-       ChipCmd         = 0x00,
-       ChipConfig      = 0x04,
-       EECtrl          = 0x08,
-       IntrMask        = 0x14,
-       IntrEnable      = 0x18,
-       TxRingPtr       = 0x20,
-       TxConfig        = 0x24,
-       RxRingPtr       = 0x30,
-       RxConfig        = 0x34,
-       ClkRun          = 0x3C,
-       RxFilterAddr    = 0x48,
-       RxFilterData    = 0x4C,
-       SiliconRev      = 0x58,
-       PCIPM           = 0x44,
-       BasicControl    = 0x80,
-       BasicStatus     = 0x84,
-       /* These are from the spec, around page 78... on a separate table. */
-       PGSEL           = 0xCC,
-       PMDCSR          = 0xE4,
-       TSTDAT          = 0xFC,
-       DSPCFG          = 0xF4,
-       SDCFG           = 0x8C
-};
-
-/* Bit in ChipCmd. */
-enum ChipCmdBits {
-       ChipReset       = 0x100,
-       RxReset         = 0x20,
-       TxReset         = 0x10,
-       RxOff           = 0x08,
-       RxOn            = 0x04,
-       TxOff           = 0x02,
-       TxOn            = 0x01
-};
-
-enum ChipConfigBits {
-       LinkSts         = 0x80000000,
-       HundSpeed       = 0x40000000,
-       FullDuplex      = 0x20000000,
-       TenPolarity     = 0x10000000,
-       AnegDone        = 0x08000000,
-       AnegEnBothBoth  = 0x0000E000,
-       AnegDis100Full  = 0x0000C000,
-       AnegEn100Both   = 0x0000A000,
-       AnegDis100Half  = 0x00008000,
-       AnegEnBothHalf  = 0x00006000,
-       AnegDis10Full   = 0x00004000,
-       AnegEn10Both    = 0x00002000,
-       DuplexMask      = 0x00008000,
-       SpeedMask       = 0x00004000,
-       AnegMask        = 0x00002000,
-       AnegDis10Half   = 0x00000000,
-       ExtPhy          = 0x00001000,
-       PhyRst          = 0x00000400,
-       PhyDis          = 0x00000200,
-       BootRomDisable  = 0x00000004,
-       BEMode          = 0x00000001,
-};
-
-enum TxConfig_bits {
-       TxDrthMask      = 0x3f,
-       TxFlthMask      = 0x3f00,
-       TxMxdmaMask     = 0x700000,
-       TxMxdma_512     = 0x0,
-       TxMxdma_4       = 0x100000,
-       TxMxdma_8       = 0x200000,
-       TxMxdma_16      = 0x300000,
-       TxMxdma_32      = 0x400000,
-       TxMxdma_64      = 0x500000,
-       TxMxdma_128     = 0x600000,
-       TxMxdma_256     = 0x700000,
-       TxCollRetry     = 0x800000,
-       TxAutoPad       = 0x10000000,
-       TxMacLoop       = 0x20000000,
-       TxHeartIgn      = 0x40000000,
-       TxCarrierIgn    = 0x80000000
-};
-
-enum RxConfig_bits {
-       RxDrthMask      = 0x3e,
-       RxMxdmaMask     = 0x700000,
-       RxMxdma_512     = 0x0,
-       RxMxdma_4       = 0x100000,
-       RxMxdma_8       = 0x200000,
-       RxMxdma_16      = 0x300000,
-       RxMxdma_32      = 0x400000,
-       RxMxdma_64      = 0x500000,
-       RxMxdma_128     = 0x600000,
-       RxMxdma_256     = 0x700000,
-       RxAcceptLong    = 0x8000000,
-       RxAcceptTx      = 0x10000000,
-       RxAcceptRunt    = 0x40000000,
-       RxAcceptErr     = 0x80000000
-};
-
-/* Bits in the RxMode register. */
-enum rx_mode_bits {
-       AcceptErr               = 0x20,
-       AcceptRunt              = 0x10,
-       AcceptBroadcast         = 0xC0000000,
-       AcceptMulticast         = 0x00200000,
-       AcceptAllMulticast      = 0x20000000,
-       AcceptAllPhys           = 0x10000000,
-       AcceptMyPhys            = 0x08000000
-};
-
-typedef struct _BufferDesc {
-       u32 link;
-       vu_long cmdsts;
-       u32 bufptr;
-       u32 software_use;
-} BufferDesc;
-
-/* Bits in network_desc.status */
-enum desc_status_bits {
-       DescOwn = 0x80000000, DescMore = 0x40000000, DescIntr = 0x20000000,
-       DescNoCRC = 0x10000000, DescPktOK = 0x08000000,
-       DescSizeMask = 0xfff,
-
-       DescTxAbort = 0x04000000, DescTxFIFO = 0x02000000,
-       DescTxCarrier = 0x01000000, DescTxDefer = 0x00800000,
-       DescTxExcDefer = 0x00400000, DescTxOOWCol = 0x00200000,
-       DescTxExcColl = 0x00100000, DescTxCollCount = 0x000f0000,
-
-       DescRxAbort = 0x04000000, DescRxOver = 0x02000000,
-       DescRxDest = 0x01800000, DescRxLong = 0x00400000,
-       DescRxRunt = 0x00200000, DescRxInvalid = 0x00100000,
-       DescRxCRC = 0x00080000, DescRxAlign = 0x00040000,
-       DescRxLoop = 0x00020000, DesRxColl = 0x00010000,
-};
-
-/* Globals */
-#ifdef NATSEMI_DEBUG
-static int natsemi_debug = 0;  /* 1 verbose debugging, 0 normal */
-#endif
-static u32 SavedClkRun;
-static unsigned int cur_rx;
-static unsigned int advertising;
-static unsigned int rx_config;
-static unsigned int tx_config;
-
-/* Note: transmit and receive buffers and descriptors must be
-   longword aligned */
-static BufferDesc txd __attribute__ ((aligned(4)));
-static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(4)));
-
-static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(4)));
-static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE]
-    __attribute__ ((aligned(4)));
-
-/* Function Prototypes */
-#if 0
-static void write_eeprom(struct eth_device *dev, long addr, int location,
-                        short value);
-#endif
-static int read_eeprom(struct eth_device *dev, long addr, int location);
-static int mdio_read(struct eth_device *dev, int phy_id, int location);
-static int natsemi_init(struct eth_device *dev, bd_t * bis);
-static void natsemi_reset(struct eth_device *dev);
-static void natsemi_init_rxfilter(struct eth_device *dev);
-static void natsemi_init_txd(struct eth_device *dev);
-static void natsemi_init_rxd(struct eth_device *dev);
-static void natsemi_set_rx_mode(struct eth_device *dev);
-static void natsemi_check_duplex(struct eth_device *dev);
-static int natsemi_send(struct eth_device *dev, volatile void *packet,
-                       int length);
-static int natsemi_poll(struct eth_device *dev);
-static void natsemi_disable(struct eth_device *dev);
-
-static struct pci_device_id supported[] = {
-       {PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815},
-       {}
-};
-
-#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a)
-#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
-
-static inline int
-INW(struct eth_device *dev, u_long addr)
-{
-       return le16_to_cpu(*(vu_short *) (addr + dev->iobase));
-}
-
-static int
-INL(struct eth_device *dev, u_long addr)
-{
-       return le32_to_cpu(*(vu_long *) (addr + dev->iobase));
-}
-
-static inline void
-OUTW(struct eth_device *dev, int command, u_long addr)
-{
-       *(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command);
-}
-
-static inline void
-OUTL(struct eth_device *dev, int command, u_long addr)
-{
-       *(vu_long *) ((addr + dev->iobase)) = cpu_to_le32(command);
-}
-
-/*
- * Function: natsemi_initialize
- *
- * Description: Retrieves the MAC address of the card, and sets up some
- * globals required by other routines,  and initializes the NIC, making it
- * ready to send and receive packets.
- *
- * Side effects:
- *            leaves the natsemi initialized, and ready to recieve packets.
- *
- * Returns:   struct eth_device *:          pointer to NIC data structure
- */
-
-int
-natsemi_initialize(bd_t * bis)
-{
-       pci_dev_t devno;
-       int card_number = 0;
-       struct eth_device *dev;
-       u32 iobase, status, chip_config;
-       int i, idx = 0;
-       int prev_eedata;
-       u32 tmp;
-
-       while (1) {
-               /* Find PCI device(s) */
-               if ((devno = pci_find_devices(supported, idx++)) < 0) {
-                       break;
-               }
-
-               pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase);
-               iobase &= ~0x3; /* bit 1: unused and bit 0: I/O Space Indicator */
-
-               pci_write_config_dword(devno, PCI_COMMAND,
-                                      PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
-
-               /* Check if I/O accesses and Bus Mastering are enabled. */
-               pci_read_config_dword(devno, PCI_COMMAND, &status);
-               if (!(status & PCI_COMMAND_MEMORY)) {
-                       printf("Error: Can not enable MEM access.\n");
-                       continue;
-               } else if (!(status & PCI_COMMAND_MASTER)) {
-                       printf("Error: Can not enable Bus Mastering.\n");
-                       continue;
-               }
-
-               dev = (struct eth_device *) malloc(sizeof *dev);
-
-               sprintf(dev->name, "dp83815#%d", card_number);
-               dev->iobase = bus_to_phys(iobase);
-#ifdef NATSEMI_DEBUG
-               printf("natsemi: NatSemi ns8381[56] @ %#x\n", dev->iobase);
-#endif
-               dev->priv = (void *) devno;
-               dev->init = natsemi_init;
-               dev->halt = natsemi_disable;
-               dev->send = natsemi_send;
-               dev->recv = natsemi_poll;
-
-               eth_register(dev);
-
-               card_number++;
-
-               /* Set the latency timer for value. */
-               pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20);
-
-               udelay(10 * 1000);
-
-               /* natsemi has a non-standard PM control register
-                * in PCI config space.  Some boards apparently need
-                * to be brought to D0 in this manner.  */
-               pci_read_config_dword(devno, PCIPM, &tmp);
-               if (tmp & (0x03 | 0x100)) {
-                       /* D0 state, disable PME assertion */
-                       u32 newtmp = tmp & ~(0x03 | 0x100);
-                       pci_write_config_dword(devno, PCIPM, newtmp);
-               }
-
-               printf("natsemi: EEPROM contents:\n");
-               for (i = 0; i <= EEPROM_SIZE; i++) {
-                       short eedata = read_eeprom(dev, EECtrl, i);
-                       printf(" %04hx", eedata);
-               }
-               printf("\n");
-
-               /* get MAC address */
-               prev_eedata = read_eeprom(dev, EECtrl, 6);
-               for (i = 0; i < 3; i++) {
-                       int eedata = read_eeprom(dev, EECtrl, i + 7);
-                       dev->enetaddr[i*2] = (eedata << 1) + (prev_eedata >> 15);
-                       dev->enetaddr[i*2+1] = eedata >> 7;
-                       prev_eedata = eedata;
-               }
-
-               /* Reset the chip to erase any previous misconfiguration. */
-               OUTL(dev, ChipReset, ChipCmd);
-
-               advertising = mdio_read(dev, 1, 4);
-               chip_config = INL(dev, ChipConfig);
-#ifdef NATSEMI_DEBUG
-               printf("%s: Transceiver status %#08X advertising %#08X\n",
-                       dev->name, (int) INL(dev, BasicStatus), advertising);
-               printf("%s: Transceiver default autoneg. %s 10%s %s duplex.\n",
-                       dev->name, chip_config & AnegMask ? "enabled, advertise" :
-                       "disabled, force", chip_config & SpeedMask ? "0" : "",
-                       chip_config & DuplexMask ? "full" : "half");
-#endif
-               chip_config |= AnegEnBothBoth;
-#ifdef NATSEMI_DEBUG
-               printf("%s: changed to autoneg. %s 10%s %s duplex.\n",
-                       dev->name, chip_config & AnegMask ? "enabled, advertise" :
-                       "disabled, force", chip_config & SpeedMask ? "0" : "",
-                       chip_config & DuplexMask ? "full" : "half");
-#endif
-               /*write new autoneg bits, reset phy*/
-               OUTL(dev, (chip_config | PhyRst), ChipConfig);
-               /*un-reset phy*/
-               OUTL(dev, chip_config, ChipConfig);
-
-               /* Disable PME:
-                * The PME bit is initialized from the EEPROM contents.
-                * PCI cards probably have PME disabled, but motherboard
-                * implementations may have PME set to enable WakeOnLan.
-                * With PME set the chip will scan incoming packets but
-                * nothing will be written to memory. */
-               SavedClkRun = INL(dev, ClkRun);
-               OUTL(dev, SavedClkRun & ~0x100, ClkRun);
-       }
-       return card_number;
-}
-
-/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
-   The EEPROM code is for common 93c06/46 EEPROMs w/ 6bit addresses.  */
-
-/* Delay between EEPROM clock transitions.
-   No extra delay is needed with 33Mhz PCI, but future 66Mhz
-   access may need a delay. */
-#define eeprom_delay(ee_addr)  INL(dev, ee_addr)
-
-enum EEPROM_Ctrl_Bits {
-       EE_ShiftClk = 0x04,
-       EE_DataIn = 0x01,
-       EE_ChipSelect = 0x08,
-       EE_DataOut = 0x02
-};
-
-#define EE_Write0 (EE_ChipSelect)
-#define EE_Write1 (EE_ChipSelect | EE_DataIn)
-/* The EEPROM commands include the alway-set leading bit. */
-enum EEPROM_Cmds {
-       EE_WrEnCmd = (4 << 6), EE_WriteCmd = (5 << 6),
-       EE_ReadCmd = (6 << 6), EE_EraseCmd = (7 << 6),
-};
-
-#if 0
-static void
-write_eeprom(struct eth_device *dev, long addr, int location, short value)
-{
-       int i;
-       int ee_addr = (typeof(ee_addr))addr;
-       short wren_cmd = EE_WrEnCmd | 0x30; /*wren is 100 + 11XXXX*/
-       short write_cmd = location | EE_WriteCmd;
-
-#ifdef NATSEMI_DEBUG
-       printf("write_eeprom: %08x, %04hx, %04hx\n",
-               dev->iobase + ee_addr, write_cmd, value);
-#endif
-       /* Shift the write enable command bits out. */
-       for (i = 9; i >= 0; i--) {
-               short cmdval = (wren_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
-               OUTL(dev, cmdval, ee_addr);
-               eeprom_delay(ee_addr);
-               OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
-               eeprom_delay(ee_addr);
-       }
-
-       OUTL(dev, 0, ee_addr); /*bring chip select low*/
-       OUTL(dev, EE_ShiftClk, ee_addr);
-       eeprom_delay(ee_addr);
-
-       /* Shift the write command bits out. */
-       for (i = 9; i >= 0; i--) {
-               short cmdval = (write_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
-               OUTL(dev, cmdval, ee_addr);
-               eeprom_delay(ee_addr);
-               OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
-               eeprom_delay(ee_addr);
-       }
-
-       for (i = 0; i < 16; i++) {
-               short cmdval = (value & (1 << i)) ? EE_Write1 : EE_Write0;
-               OUTL(dev, cmdval, ee_addr);
-               eeprom_delay(ee_addr);
-               OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
-               eeprom_delay(ee_addr);
-       }
-
-       OUTL(dev, 0, ee_addr); /*bring chip select low*/
-       OUTL(dev, EE_ShiftClk, ee_addr);
-       for (i = 0; i < 200000; i++) {
-               OUTL(dev, EE_Write0, ee_addr); /*poll for done*/
-               if (INL(dev, ee_addr) & EE_DataOut) {
-                   break; /*finished*/
-               }
-       }
-       eeprom_delay(ee_addr);
-
-       /* Terminate the EEPROM access. */
-       OUTL(dev, EE_Write0, ee_addr);
-       OUTL(dev, 0, ee_addr);
-       return;
-}
-#endif
-
-static int
-read_eeprom(struct eth_device *dev, long addr, int location)
-{
-       int i;
-       int retval = 0;
-       int ee_addr = (typeof(ee_addr))addr;
-       int read_cmd = location | EE_ReadCmd;
-
-       OUTL(dev, EE_Write0, ee_addr);
-
-       /* Shift the read command bits out. */
-       for (i = 10; i >= 0; i--) {
-               short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
-               OUTL(dev, dataval, ee_addr);
-               eeprom_delay(ee_addr);
-               OUTL(dev, dataval | EE_ShiftClk, ee_addr);
-               eeprom_delay(ee_addr);
-       }
-       OUTL(dev, EE_ChipSelect, ee_addr);
-       eeprom_delay(ee_addr);
-
-       for (i = 0; i < 16; i++) {
-               OUTL(dev, EE_ChipSelect | EE_ShiftClk, ee_addr);
-               eeprom_delay(ee_addr);
-               retval |= (INL(dev, ee_addr) & EE_DataOut) ? 1 << i : 0;
-               OUTL(dev, EE_ChipSelect, ee_addr);
-               eeprom_delay(ee_addr);
-       }
-
-       /* Terminate the EEPROM access. */
-       OUTL(dev, EE_Write0, ee_addr);
-       OUTL(dev, 0, ee_addr);
-#ifdef NATSEMI_DEBUG
-       if (natsemi_debug)
-               printf("read_eeprom: %08x, %08x, retval %08x\n",
-                       dev->iobase + ee_addr, read_cmd, retval);
-#endif
-       return retval;
-}
-
-/*  MII transceiver control section.
-       The 83815 series has an internal transceiver, and we present the
-       management registers as if they were MII connected. */
-
-static int
-mdio_read(struct eth_device *dev, int phy_id, int location)
-{
-       if (phy_id == 1 && location < 32)
-               return INL(dev, BasicControl+(location<<2))&0xffff;
-       else
-               return 0xffff;
-}
-
-/* Function: natsemi_init
- *
- * Description: resets the ethernet controller chip and configures
- *    registers and data structures required for sending and receiving packets.
- *
- * Arguments: struct eth_device *dev:          NIC data structure
- *
- * returns:    int.
- */
-
-static int
-natsemi_init(struct eth_device *dev, bd_t * bis)
-{
-
-       natsemi_reset(dev);
-
-       /* Disable PME:
-        * The PME bit is initialized from the EEPROM contents.
-        * PCI cards probably have PME disabled, but motherboard
-        * implementations may have PME set to enable WakeOnLan.
-        * With PME set the chip will scan incoming packets but
-        * nothing will be written to memory. */
-       OUTL(dev, SavedClkRun & ~0x100, ClkRun);
-
-       natsemi_init_rxfilter(dev);
-       natsemi_init_txd(dev);
-       natsemi_init_rxd(dev);
-
-       /* Configure the PCI bus bursts and FIFO thresholds. */
-       tx_config = TxAutoPad | TxCollRetry | TxMxdma_256 | (0x1002);
-       rx_config = RxMxdma_256 | 0x20;
-
-#ifdef NATSEMI_DEBUG
-       printf("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config);
-       printf("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config);
-#endif
-       OUTL(dev, tx_config, TxConfig);
-       OUTL(dev, rx_config, RxConfig);
-
-       natsemi_check_duplex(dev);
-       natsemi_set_rx_mode(dev);
-
-       OUTL(dev, (RxOn | TxOn), ChipCmd);
-       return 1;
-}
-
-/*
- * Function: natsemi_reset
- *
- * Description: soft resets the controller chip
- *
- * Arguments: struct eth_device *dev:          NIC data structure
- *
- * Returns:   void.
- */
-static void
-natsemi_reset(struct eth_device *dev)
-{
-       OUTL(dev, ChipReset, ChipCmd);
-
-       /* On page 78 of the spec, they recommend some settings for "optimum
-          performance" to be done in sequence.  These settings optimize some
-          of the 100Mbit autodetection circuitry.  Also, we only want to do
-          this for rev C of the chip.  */
-       if (INL(dev, SiliconRev) == 0x302) {
-               OUTW(dev, 0x0001, PGSEL);
-               OUTW(dev, 0x189C, PMDCSR);
-               OUTW(dev, 0x0000, TSTDAT);
-               OUTW(dev, 0x5040, DSPCFG);
-               OUTW(dev, 0x008C, SDCFG);
-       }
-       /* Disable interrupts using the mask. */
-       OUTL(dev, 0, IntrMask);
-       OUTL(dev, 0, IntrEnable);
-}
-
-/* Function: natsemi_init_rxfilter
- *
- * Description: sets receive filter address to our MAC address
- *
- * Arguments: struct eth_device *dev:          NIC data structure
- *
- * returns:   void.
- */
-
-static void
-natsemi_init_rxfilter(struct eth_device *dev)
-{
-       int i;
-
-       for (i = 0; i < ETH_ALEN; i += 2) {
-               OUTL(dev, i, RxFilterAddr);
-               OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8),
-                    RxFilterData);
-       }
-}
-
-/*
- * Function: natsemi_init_txd
- *
- * Description: initializes the Tx descriptor
- *
- * Arguments: struct eth_device *dev:          NIC data structure
- *
- * returns:   void.
- */
-
-static void
-natsemi_init_txd(struct eth_device *dev)
-{
-       txd.link = (u32) 0;
-       txd.cmdsts = (u32) 0;
-       txd.bufptr = (u32) & txb[0];
-
-       /* load Transmit Descriptor Register */
-       OUTL(dev, (u32) & txd, TxRingPtr);
-#ifdef NATSEMI_DEBUG
-       printf("natsemi_init_txd: TX descriptor reg loaded with: %#08X\n",
-              INL(dev, TxRingPtr));
-#endif
-}
-
-/* Function: natsemi_init_rxd
- *
- * Description: initializes the Rx descriptor ring
- *
- * Arguments: struct eth_device *dev:          NIC data structure
- *
- * Returns:   void.
- */
-
-static void
-natsemi_init_rxd(struct eth_device *dev)
-{
-       int i;
-
-       cur_rx = 0;
-
-       /* init RX descriptor */
-       for (i = 0; i < NUM_RX_DESC; i++) {
-               rxd[i].link =
-                   cpu_to_le32((i + 1 <
-                                NUM_RX_DESC) ? (u32) & rxd[i +
-                                                           1] : (u32) &
-                               rxd[0]);
-               rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE);
-               rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]);
-#ifdef NATSEMI_DEBUG
-               printf
-                   ("natsemi_init_rxd: rxd[%d]=%p link=%X cmdsts=%lX bufptr=%X\n",
-                       i, &rxd[i], le32_to_cpu(rxd[i].link),
-                               rxd[i].cmdsts, rxd[i].bufptr);
-#endif
-       }
-
-       /* load Receive Descriptor Register */
-       OUTL(dev, (u32) & rxd[0], RxRingPtr);
-
-#ifdef NATSEMI_DEBUG
-       printf("natsemi_init_rxd: RX descriptor register loaded with: %X\n",
-              INL(dev, RxRingPtr));
-#endif
-}
-
-/* Function: natsemi_set_rx_mode
- *
- * Description:
- *    sets the receive mode to accept all broadcast packets and packets
- *    with our MAC address, and reject all multicast packets.
- *
- * Arguments: struct eth_device *dev:          NIC data structure
- *
- * Returns:   void.
- */
-
-static void
-natsemi_set_rx_mode(struct eth_device *dev)
-{
-       u32 rx_mode = AcceptBroadcast | AcceptMyPhys;
-
-       OUTL(dev, rx_mode, RxFilterAddr);
-}
-
-static void
-natsemi_check_duplex(struct eth_device *dev)
-{
-       int duplex = INL(dev, ChipConfig) & FullDuplex ? 1 : 0;
-
-#ifdef NATSEMI_DEBUG
-       printf("%s: Setting %s-duplex based on negotiated link"
-              " capability.\n", dev->name, duplex ? "full" : "half");
-#endif
-       if (duplex) {
-               rx_config |= RxAcceptTx;
-               tx_config |= (TxCarrierIgn | TxHeartIgn);
-       } else {
-               rx_config &= ~RxAcceptTx;
-               tx_config &= ~(TxCarrierIgn | TxHeartIgn);
-       }
-       OUTL(dev, tx_config, TxConfig);
-       OUTL(dev, rx_config, RxConfig);
-}
-
-/* Function: natsemi_send
- *
- * Description: transmits a packet and waits for completion or timeout.
- *
- * Returns:   void.  */
-static int
-natsemi_send(struct eth_device *dev, volatile void *packet, int length)
-{
-       u32 i, status = 0;
-       u32 tx_status = 0;
-       vu_long *res = (vu_long *)&tx_status;
-
-       /* Stop the transmitter */
-       OUTL(dev, TxOff, ChipCmd);
-
-#ifdef NATSEMI_DEBUG
-       if (natsemi_debug)
-               printf("natsemi_send: sending %d bytes\n", (int) length);
-#endif
-
-       /* set the transmit buffer descriptor and enable Transmit State Machine */
-       txd.link = cpu_to_le32(0);
-       txd.bufptr = cpu_to_le32(phys_to_bus((u32) packet));
-       txd.cmdsts = cpu_to_le32(DescOwn | length);
-
-       /* load Transmit Descriptor Register */
-       OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr);
-#ifdef NATSEMI_DEBUG
-       if (natsemi_debug)
-           printf("natsemi_send: TX descriptor register loaded with: %#08X\n",
-            INL(dev, TxRingPtr));
-#endif
-       /* restart the transmitter */
-       OUTL(dev, TxOn, ChipCmd);
-
-       for (i = 0;
-            (*res = le32_to_cpu(txd.cmdsts)) & DescOwn;
-            i++) {
-               if (i >= TOUT_LOOP) {
-                       printf
-                           ("%s: tx error buffer not ready: txd.cmdsts == %#X\n",
-                            dev->name, tx_status);
-                       goto Done;
-               }
-       }
-
-       if (!(tx_status & DescPktOK)) {
-               printf("natsemi_send: Transmit error, Tx status %X.\n",
-                      tx_status);
-               goto Done;
-       }
-
-       status = 1;
-      Done:
-       return status;
-}
-
-/* Function: natsemi_poll
- *
- * Description: checks for a received packet and returns it if found.
- *
- * Arguments: struct eth_device *dev:          NIC data structure
- *
- * Returns:   1 if    packet was received.
- *            0 if no packet was received.
- *
- * Side effects:
- *            Returns (copies) the packet to the array dev->packet.
- *            Returns the length of the packet.
- */
-
-static int
-natsemi_poll(struct eth_device *dev)
-{
-       int retstat = 0;
-       int length = 0;
-       u32 rx_status = le32_to_cpu(rxd[cur_rx].cmdsts);
-
-       if (!(rx_status & (u32) DescOwn))
-               return retstat;
-#ifdef NATSEMI_DEBUG
-       if (natsemi_debug)
-               printf("natsemi_poll: got a packet: cur_rx:%d, status:%X\n",
-                      cur_rx, rx_status);
-#endif
-       length = (rx_status & DSIZE) - CRC_SIZE;
-
-       if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) {
-               printf
-                   ("natsemi_poll: Corrupted packet received, buffer status = %X\n",
-                    rx_status);
-               retstat = 0;
-       } else {                /* give packet to higher level routine */
-               NetReceive((rxb + cur_rx * RX_BUF_SIZE), length);
-               retstat = 1;
-       }
-
-       /* return the descriptor and buffer to receive ring */
-       rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE);
-       rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]);
-
-       if (++cur_rx == NUM_RX_DESC)
-               cur_rx = 0;
-
-       /* re-enable the potentially idle receive state machine */
-       OUTL(dev, RxOn, ChipCmd);
-
-       return retstat;
-}
-
-/* Function: natsemi_disable
- *
- * Description: Turns off interrupts and stops Tx and Rx engines
- *
- * Arguments: struct eth_device *dev:          NIC data structure
- *
- * Returns:   void.
- */
-
-static void
-natsemi_disable(struct eth_device *dev)
-{
-       /* Disable interrupts using the mask. */
-       OUTL(dev, 0, IntrMask);
-       OUTL(dev, 0, IntrEnable);
-
-       /* Stop the chip's Tx and Rx processes. */
-       OUTL(dev, RxOff | TxOff, ChipCmd);
-
-       /* Restore PME enable bit */
-       OUTL(dev, SavedClkRun, ClkRun);
-}
-
-#endif
diff --git a/drivers/ne2000.c b/drivers/ne2000.c
deleted file mode 100644 (file)
index 695a1dc..0000000
+++ /dev/null
@@ -1,947 +0,0 @@
-/*
-Ported to U-Boot  by Christian Pellegrin <chri@ascensit.com>
-
-Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
-eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
-are GPL, so this is, of course, GPL.
-
-
-==========================================================================
-
-dev/if_dp83902a.c
-
-Ethernet device driver for NS DP83902a ethernet controller
-
-==========================================================================
-####ECOSGPLCOPYRIGHTBEGIN####
--------------------------------------------
-This file is part of eCos, the Embedded Configurable Operating System.
-Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-
-eCos is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 or (at your option) any later version.
-
-eCos is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License along
-with eCos; if not, write to the Free Software Foundation, Inc.,
-59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
-As a special exception, if other files instantiate templates or use macros
-or inline functions from this file, or you compile this file and link it
-with other works to produce a work based on this file, this file does not
-by itself cause the resulting work to be covered by the GNU General Public
-License. However the source code for this file must still be made available
-in accordance with section (3) of the GNU General Public License.
-
-This exception does not invalidate any other reasons why a work based on
-this file might be covered by the GNU General Public License.
-
-Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-at http://sources.redhat.com/ecos/ecos-license/
--------------------------------------------
-####ECOSGPLCOPYRIGHTEND####
-####BSDCOPYRIGHTBEGIN####
-
--------------------------------------------
-
-Portions of this software may have been derived from OpenBSD or other sources,
-and are covered by the appropriate copyright disclaimers included herein.
-
--------------------------------------------
-
-####BSDCOPYRIGHTEND####
-==========================================================================
-#####DESCRIPTIONBEGIN####
-
-Author(s):    gthomas
-Contributors: gthomas, jskov, rsandifo
-Date:        2001-06-13
-Purpose:
-Description:
-
-FIXME:       Will fail if pinged with large packets (1520 bytes)
-Add promisc config
-Add SNMP
-
-####DESCRIPTIONEND####
-
-
-==========================================================================
-
-*/
-
-#include <common.h>
-#include <command.h>
-#include <net.h>
-#include <malloc.h>
-
-#ifdef CONFIG_DRIVER_NE2000
-
-/* wor around udelay resetting OCR */
-static void my_udelay(long us) {
-       long tmo;
-
-       tmo = get_timer (0) + us * CFG_HZ / 1000000; /* will this be much greater than 0 ? */
-       while (get_timer (0) < tmo);
-}
-
-#define mdelay(n)       my_udelay((n)*1000)
-
-/* forward definition of function used for the uboot interface */
-void uboot_push_packet_len(int len);
-void uboot_push_tx_done(int key, int val);
-
-/* timeout for tx/rx in s */
-#define TOUT 5
-
-#define ETHER_ADDR_LEN 6
-
-/*
-  ------------------------------------------------------------------------
-  Debugging details
-
-  Set to perms of:
-  0 disables all debug output
-  1 for process debug output
-  2 for added data IO output: get_reg, put_reg
-  4 for packet allocation/free output
-  8 for only startup status, so we can tell we're installed OK
-*/
-/*#define DEBUG 0xf*/
-#define DEBUG 0
-
-#if DEBUG & 1
-#define DEBUG_FUNCTION() do { printf("%s\n", __FUNCTION__); } while (0)
-#define DEBUG_LINE() do { printf("%d\n", __LINE__); } while (0)
-#else
-#define DEBUG_FUNCTION() do {} while(0)
-#define DEBUG_LINE() do {} while(0)
-#endif
-
-#include "ne2000.h"
-
-#if DEBUG & 1
-#define PRINTK(args...) printf(args)
-#else
-#define PRINTK(args...)
-#endif
-
-static dp83902a_priv_data_t nic; /* just one instance of the card supported */
-
-static bool
-dp83902a_init(void)
-{
-       dp83902a_priv_data_t *dp = &nic;
-       cyg_uint8* base;
-       int i;
-
-       DEBUG_FUNCTION();
-
-       base = dp->base;
-       if (!base) return false;  /* No device found */
-
-       DEBUG_LINE();
-
-       /* Prepare ESA */
-       DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1);  /* Select page 1 */
-       /* Use the address from the serial EEPROM */
-       for (i = 0; i < 6; i++)
-               DP_IN(base, DP_P1_PAR0+i, dp->esa[i]);
-       DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0);  /* Select page 0 */
-
-       printf("NE2000 - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
-              "eeprom",
-              dp->esa[0],
-              dp->esa[1],
-              dp->esa[2],
-              dp->esa[3],
-              dp->esa[4],
-              dp->esa[5] );
-
-       return true;
-}
-
-static void
-dp83902a_stop(void)
-{
-       dp83902a_priv_data_t *dp = &nic;
-       cyg_uint8 *base = dp->base;
-
-       DEBUG_FUNCTION();
-
-       DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP);  /* Brutal */
-       DP_OUT(base, DP_ISR, 0xFF);             /* Clear any pending interrupts */
-       DP_OUT(base, DP_IMR, 0x00);             /* Disable all interrupts */
-
-       dp->running = false;
-}
-
-/*
-  This function is called to "start up" the interface.  It may be called
-  multiple times, even when the hardware is already running.  It will be
-  called whenever something "hardware oriented" changes and should leave
-  the hardware ready to send/receive packets.
-*/
-static void
-dp83902a_start(unsigned char * enaddr)
-{
-       dp83902a_priv_data_t *dp = &nic;
-       cyg_uint8 *base = dp->base;
-       int i;
-
-       DEBUG_FUNCTION();
-
-       DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */
-       DP_OUT(base, DP_DCR, DP_DCR_INIT);
-       DP_OUT(base, DP_RBCH, 0);               /* Remote byte count */
-       DP_OUT(base, DP_RBCL, 0);
-       DP_OUT(base, DP_RCR, DP_RCR_MON);       /* Accept no packets */
-       DP_OUT(base, DP_TCR, DP_TCR_LOCAL);     /* Transmitter [virtually] off */
-       DP_OUT(base, DP_TPSR, dp->tx_buf1);     /* Transmitter start page */
-       dp->tx1 = dp->tx2 = 0;
-       dp->tx_next = dp->tx_buf1;
-       dp->tx_started = false;
-       DP_OUT(base, DP_PSTART, dp->rx_buf_start); /* Receive ring start page */
-       DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1); /* Receive ring boundary */
-       DP_OUT(base, DP_PSTOP, dp->rx_buf_end); /* Receive ring end page */
-       dp->rx_next = dp->rx_buf_start-1;
-       DP_OUT(base, DP_ISR, 0xFF);             /* Clear any pending interrupts */
-       DP_OUT(base, DP_IMR, DP_IMR_All);       /* Enable all interrupts */
-       DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1 | DP_CR_STOP);  /* Select page 1 */
-       DP_OUT(base, DP_P1_CURP, dp->rx_buf_start);   /* Current page - next free page for Rx */
-       for (i = 0;  i < ETHER_ADDR_LEN;  i++) {
-               DP_OUT(base, DP_P1_PAR0+i, enaddr[i]);
-       }
-       /* Enable and start device */
-       DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
-       DP_OUT(base, DP_TCR, DP_TCR_NORMAL); /* Normal transmit operations */
-       DP_OUT(base, DP_RCR, DP_RCR_AB);  /* Accept broadcast, no errors, no multicast */
-       dp->running = true;
-}
-
-/*
-  This routine is called to start the transmitter.  It is split out from the
-  data handling routine so it may be called either when data becomes first
-  available or when an Tx interrupt occurs
-*/
-
-static void
-dp83902a_start_xmit(int start_page, int len)
-{
-       dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *) &nic;
-       cyg_uint8 *base = dp->base;
-
-       DEBUG_FUNCTION();
-
-#if DEBUG & 1
-       printf("Tx pkt %d len %d\n", start_page, len);
-       if (dp->tx_started)
-               printf("TX already started?!?\n");
-#endif
-
-       DP_OUT(base, DP_ISR, (DP_ISR_TxP | DP_ISR_TxE));
-       DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
-       DP_OUT(base, DP_TBCL, len & 0xFF);
-       DP_OUT(base, DP_TBCH, len >> 8);
-       DP_OUT(base, DP_TPSR, start_page);
-       DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
-
-       dp->tx_started = true;
-}
-
-/*
-  This routine is called to send data to the hardware.  It is known a-priori
-  that there is free buffer space (dp->tx_next).
-*/
-static void
-dp83902a_send(unsigned char *data, int total_len, unsigned long key)
-{
-       struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
-       cyg_uint8 *base = dp->base;
-       int len, start_page, pkt_len, i, isr;
-#if DEBUG & 4
-       int dx;
-#endif
-
-       DEBUG_FUNCTION();
-
-       len = pkt_len = total_len;
-       if (pkt_len < IEEE_8023_MIN_FRAME) pkt_len = IEEE_8023_MIN_FRAME;
-
-       start_page = dp->tx_next;
-       if (dp->tx_next == dp->tx_buf1) {
-               dp->tx1 = start_page;
-               dp->tx1_len = pkt_len;
-               dp->tx1_key = key;
-               dp->tx_next = dp->tx_buf2;
-       } else {
-               dp->tx2 = start_page;
-               dp->tx2_len = pkt_len;
-               dp->tx2_key = key;
-               dp->tx_next = dp->tx_buf1;
-       }
-
-#if DEBUG & 5
-       printf("TX prep page %d len %d\n", start_page, pkt_len);
-#endif
-
-       DP_OUT(base, DP_ISR, DP_ISR_RDC);  /* Clear end of DMA */
-       {
-               /* Dummy read. The manual sez something slightly different, */
-               /* but the code is extended a bit to do what Hitachi's monitor */
-               /* does (i.e., also read data). */
-
-               cyg_uint16 tmp;
-               int len = 1;
-
-               DP_OUT(base, DP_RSAL, 0x100-len);
-               DP_OUT(base, DP_RSAH, (start_page-1) & 0xff);
-               DP_OUT(base, DP_RBCL, len);
-               DP_OUT(base, DP_RBCH, 0);
-               DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_RDMA | DP_CR_START);
-               DP_IN_DATA(dp->data, tmp);
-       }
-
-#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
-       /* Stall for a bit before continuing to work around random data */
-       /* corruption problems on some platforms. */
-       CYGACC_CALL_IF_DELAY_US(1);
-#endif
-
-       /* Send data to device buffer(s) */
-       DP_OUT(base, DP_RSAL, 0);
-       DP_OUT(base, DP_RSAH, start_page);
-       DP_OUT(base, DP_RBCL, pkt_len & 0xFF);
-       DP_OUT(base, DP_RBCH, pkt_len >> 8);
-       DP_OUT(base, DP_CR, DP_CR_WDMA | DP_CR_START);
-
-       /* Put data into buffer */
-#if DEBUG & 4
-       printf(" sg buf %08lx len %08x\n ", (unsigned long) data, len);
-       dx = 0;
-#endif
-       while (len > 0) {
-#if DEBUG & 4
-               printf(" %02x", *data);
-               if (0 == (++dx % 16)) printf("\n ");
-#endif
-               DP_OUT_DATA(dp->data, *data++);
-               len--;
-       }
-#if DEBUG & 4
-       printf("\n");
-#endif
-       if (total_len < pkt_len) {
-#if DEBUG & 4
-               printf("  + %d bytes of padding\n", pkt_len - total_len);
-#endif
-               /* Padding to 802.3 length was required */
-               for (i = total_len;  i < pkt_len;) {
-                       i++;
-                       DP_OUT_DATA(dp->data, 0);
-               }
-       }
-
-#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
-       /* After last data write, delay for a bit before accessing the */
-       /* device again, or we may get random data corruption in the last */
-       /* datum (on some platforms). */
-       CYGACC_CALL_IF_DELAY_US(1);
-#endif
-
-       /* Wait for DMA to complete */
-       do {
-               DP_IN(base, DP_ISR, isr);
-       } while ((isr & DP_ISR_RDC) == 0);
-       /* Then disable DMA */
-       DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
-
-       /* Start transmit if not already going */
-       if (!dp->tx_started) {
-               if (start_page == dp->tx1) {
-                       dp->tx_int = 1;  /* Expecting interrupt from BUF1 */
-               } else {
-                       dp->tx_int = 2;  /* Expecting interrupt from BUF2 */
-               }
-               dp83902a_start_xmit(start_page, pkt_len);
-       }
-}
-
-/*
-  This function is called when a packet has been received.  It's job is
-  to prepare to unload the packet from the hardware.  Once the length of
-  the packet is known, the upper layer of the driver can be told.  When
-  the upper layer is ready to unload the packet, the internal function
-  'dp83902a_recv' will be called to actually fetch it from the hardware.
-*/
-static void
-dp83902a_RxEvent(void)
-{
-       struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
-       cyg_uint8 *base = dp->base;
-       unsigned char rsr;
-       unsigned char rcv_hdr[4];
-       int i, len, pkt, cur;
-
-       DEBUG_FUNCTION();
-
-       DP_IN(base, DP_RSR, rsr);
-       while (true) {
-               /* Read incoming packet header */
-               DP_OUT(base, DP_CR, DP_CR_PAGE1 | DP_CR_NODMA | DP_CR_START);
-               DP_IN(base, DP_P1_CURP, cur);
-               DP_OUT(base, DP_P1_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
-               DP_IN(base, DP_BNDRY, pkt);
-
-               pkt += 1;
-               if (pkt == dp->rx_buf_end)
-                       pkt = dp->rx_buf_start;
-
-               if (pkt == cur) {
-                       break;
-               }
-               DP_OUT(base, DP_RBCL, sizeof(rcv_hdr));
-               DP_OUT(base, DP_RBCH, 0);
-               DP_OUT(base, DP_RSAL, 0);
-               DP_OUT(base, DP_RSAH, pkt);
-               if (dp->rx_next == pkt) {
-                       if (cur == dp->rx_buf_start)
-                               DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1);
-                       else
-                               DP_OUT(base, DP_BNDRY, cur-1); /* Update pointer */
-                       return;
-               }
-               dp->rx_next = pkt;
-               DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
-               DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
-#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
-               CYGACC_CALL_IF_DELAY_US(10);
-#endif
-
-               for (i = 0;  i < sizeof(rcv_hdr);) {
-                       DP_IN_DATA(dp->data, rcv_hdr[i++]);
-               }
-
-#if DEBUG & 5
-               printf("rx hdr %02x %02x %02x %02x\n",
-                      rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]);
-#endif
-               len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr);
-               uboot_push_packet_len(len);
-               if (rcv_hdr[1] == dp->rx_buf_start)
-                       DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1);
-               else
-                       DP_OUT(base, DP_BNDRY, rcv_hdr[1]-1); /* Update pointer */
-       }
-}
-
-/*
-  This function is called as a result of the "eth_drv_recv()" call above.
-  It's job is to actually fetch data for a packet from the hardware once
-  memory buffers have been allocated for the packet.  Note that the buffers
-  may come in pieces, using a scatter-gather list.  This allows for more
-  efficient processing in the upper layers of the stack.
-*/
-static void
-dp83902a_recv(unsigned char *data, int len)
-{
-       struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
-       cyg_uint8 *base = dp->base;
-       int i, mlen;
-       cyg_uint8 saved_char = 0;
-       bool saved;
-#if DEBUG & 4
-       int dx;
-#endif
-
-       DEBUG_FUNCTION();
-
-#if DEBUG & 5
-       printf("Rx packet %d length %d\n", dp->rx_next, len);
-#endif
-
-       /* Read incoming packet data */
-       DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
-       DP_OUT(base, DP_RBCL, len & 0xFF);
-       DP_OUT(base, DP_RBCH, len >> 8);
-       DP_OUT(base, DP_RSAL, 4);               /* Past header */
-       DP_OUT(base, DP_RSAH, dp->rx_next);
-       DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
-       DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
-#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
-       CYGACC_CALL_IF_DELAY_US(10);
-#endif
-
-       saved = false;
-       for (i = 0;  i < 1;  i++) {
-               if (data) {
-                       mlen = len;
-#if DEBUG & 4
-                       printf(" sg buf %08lx len %08x \n", (unsigned long) data, mlen);
-                       dx = 0;
-#endif
-                       while (0 < mlen) {
-                               /* Saved byte from previous loop? */
-                               if (saved) {
-                                       *data++ = saved_char;
-                                       mlen--;
-                                       saved = false;
-                                       continue;
-                               }
-
-                               {
-                                       cyg_uint8 tmp;
-                                       DP_IN_DATA(dp->data, tmp);
-#if DEBUG & 4
-                                       printf(" %02x", tmp);
-                                       if (0 == (++dx % 16)) printf("\n ");
-#endif
-                                       *data++ = tmp;;
-                                       mlen--;
-                               }
-                       }
-#if DEBUG & 4
-                       printf("\n");
-#endif
-               }
-       }
-}
-
-static void
-dp83902a_TxEvent(void)
-{
-       struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
-       cyg_uint8 *base = dp->base;
-       unsigned char tsr;
-       unsigned long key;
-
-       DEBUG_FUNCTION();
-
-       DP_IN(base, DP_TSR, tsr);
-       if (dp->tx_int == 1) {
-               key = dp->tx1_key;
-               dp->tx1 = 0;
-       } else {
-               key = dp->tx2_key;
-               dp->tx2 = 0;
-       }
-       /* Start next packet if one is ready */
-       dp->tx_started = false;
-       if (dp->tx1) {
-               dp83902a_start_xmit(dp->tx1, dp->tx1_len);
-               dp->tx_int = 1;
-       } else if (dp->tx2) {
-               dp83902a_start_xmit(dp->tx2, dp->tx2_len);
-               dp->tx_int = 2;
-       } else {
-               dp->tx_int = 0;
-       }
-       /* Tell higher level we sent this packet */
-       uboot_push_tx_done(key, 0);
-}
-
-/* Read the tally counters to clear them.  Called in response to a CNT */
-/* interrupt. */
-static void
-dp83902a_ClearCounters(void)
-{
-       struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
-       cyg_uint8 *base = dp->base;
-       cyg_uint8 cnt1, cnt2, cnt3;
-
-       DP_IN(base, DP_FER, cnt1);
-       DP_IN(base, DP_CER, cnt2);
-       DP_IN(base, DP_MISSED, cnt3);
-       DP_OUT(base, DP_ISR, DP_ISR_CNT);
-}
-
-/* Deal with an overflow condition.  This code follows the procedure set */
-/* out in section 7.0 of the datasheet. */
-static void
-dp83902a_Overflow(void)
-{
-       struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)&nic;
-       cyg_uint8 *base = dp->base;
-       cyg_uint8 isr;
-
-       /* Issue a stop command and wait 1.6ms for it to complete. */
-       DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA);
-       CYGACC_CALL_IF_DELAY_US(1600);
-
-       /* Clear the remote byte counter registers. */
-       DP_OUT(base, DP_RBCL, 0);
-       DP_OUT(base, DP_RBCH, 0);
-
-       /* Enter loopback mode while we clear the buffer. */
-       DP_OUT(base, DP_TCR, DP_TCR_LOCAL);
-       DP_OUT(base, DP_CR, DP_CR_START | DP_CR_NODMA);
-
-       /* Read in as many packets as we can and acknowledge any and receive */
-       /* interrupts.  Since the buffer has overflowed, a receive event of */
-       /* some kind will have occured. */
-       dp83902a_RxEvent();
-       DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE);
-
-       /* Clear the overflow condition and leave loopback mode. */
-       DP_OUT(base, DP_ISR, DP_ISR_OFLW);
-       DP_OUT(base, DP_TCR, DP_TCR_NORMAL);
-
-       /* If a transmit command was issued, but no transmit event has occured, */
-       /* restart it here. */
-       DP_IN(base, DP_ISR, isr);
-       if (dp->tx_started && !(isr & (DP_ISR_TxP|DP_ISR_TxE))) {
-               DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
-       }
-}
-
-static void
-dp83902a_poll(void)
-{
-       struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
-       cyg_uint8 *base = dp->base;
-       unsigned char isr;
-
-       DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0 | DP_CR_START);
-       DP_IN(base, DP_ISR, isr);
-       while (0 != isr) {
-               /* The CNT interrupt triggers when the MSB of one of the error */
-               /* counters is set.  We don't much care about these counters, but */
-               /* we should read their values to reset them. */
-               if (isr & DP_ISR_CNT) {
-                       dp83902a_ClearCounters();
-               }
-               /* Check for overflow.  It's a special case, since there's a */
-               /* particular procedure that must be followed to get back into */
-               /* a running state.a */
-               if (isr & DP_ISR_OFLW) {
-                       dp83902a_Overflow();
-               } else {
-                       /* Other kinds of interrupts can be acknowledged simply by */
-                       /* clearing the relevant bits of the ISR.  Do that now, then */
-                       /* handle the interrupts we care about. */
-                       DP_OUT(base, DP_ISR, isr);      /* Clear set bits */
-                       if (!dp->running) break;        /* Is this necessary? */
-                       /* Check for tx_started on TX event since these may happen */
-                       /* spuriously it seems. */
-                       if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) {
-                               dp83902a_TxEvent();
-                       }
-                       if (isr & (DP_ISR_RxP|DP_ISR_RxE)) {
-                               dp83902a_RxEvent();
-                       }
-               }
-               DP_IN(base, DP_ISR, isr);
-       }
-}
-
-/* find prom (taken from pc_net_cs.c from Linux) */
-
-#include "8390.h"
-
-typedef struct hw_info_t {
-       u_int   offset;
-       u_char  a0, a1, a2;
-       u_int   flags;
-} hw_info_t;
-
-#define DELAY_OUTPUT   0x01
-#define HAS_MISC_REG   0x02
-#define USE_BIG_BUF    0x04
-#define HAS_IBM_MISC   0x08
-#define IS_DL10019     0x10
-#define IS_DL10022     0x20
-#define HAS_MII                0x40
-#define USE_SHMEM      0x80    /* autodetected */
-
-#define AM79C9XX_HOME_PHY      0x00006B90  /* HomePNA PHY */
-#define AM79C9XX_ETH_PHY       0x00006B70  /* 10baseT PHY */
-#define MII_PHYID_REV_MASK     0xfffffff0
-#define MII_PHYID_REG1         0x02
-#define MII_PHYID_REG2         0x03
-
-static hw_info_t hw_info[] = {
-       { /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT },
-       { /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 },
-       { /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 },
-       { /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94,
-         DELAY_OUTPUT | HAS_IBM_MISC },
-       { /* Danpex EN-6200P2 */ 0x0110, 0x00, 0x40, 0xc7, 0 },
-       { /* DataTrek NetCard */ 0x0ff0, 0x00, 0x20, 0xe8, 0 },
-       { /* Dayna CommuniCard E */ 0x0110, 0x00, 0x80, 0x19, 0 },
-       { /* D-Link DE-650 */ 0x0040, 0x00, 0x80, 0xc8, 0 },
-       { /* EP-210 Ethernet */ 0x0110, 0x00, 0x40, 0x33, 0 },
-       { /* EP4000 Ethernet */ 0x01c0, 0x00, 0x00, 0xb4, 0 },
-       { /* Epson EEN10B */ 0x0ff0, 0x00, 0x00, 0x48,
-         HAS_MISC_REG | HAS_IBM_MISC },
-       { /* ELECOM Laneed LD-CDWA */ 0xb8, 0x08, 0x00, 0x42, 0 },
-       { /* Hypertec Ethernet */ 0x01c0, 0x00, 0x40, 0x4c, 0 },
-       { /* IBM CCAE */ 0x0ff0, 0x08, 0x00, 0x5a,
-         HAS_MISC_REG | HAS_IBM_MISC },
-       { /* IBM CCAE */ 0x0ff0, 0x00, 0x04, 0xac,
-         HAS_MISC_REG | HAS_IBM_MISC },
-       { /* IBM CCAE */ 0x0ff0, 0x00, 0x06, 0x29,
-         HAS_MISC_REG | HAS_IBM_MISC },
-       { /* IBM FME */ 0x0374, 0x08, 0x00, 0x5a,
-         HAS_MISC_REG | HAS_IBM_MISC },
-       { /* IBM FME */ 0x0374, 0x00, 0x04, 0xac,
-         HAS_MISC_REG | HAS_IBM_MISC },
-       { /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87,
-         HAS_MISC_REG | HAS_IBM_MISC },
-       { /* NSC DP83903 */ 0x0374, 0x08, 0x00, 0x17,
-         HAS_MISC_REG | HAS_IBM_MISC },
-       { /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8,
-         HAS_MISC_REG | HAS_IBM_MISC },
-       { /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0,
-         HAS_MISC_REG | HAS_IBM_MISC },
-       { /* NSC DP83903 */ 0x0198, 0x00, 0x20, 0xe0,
-         HAS_MISC_REG | HAS_IBM_MISC },
-       { /* I-O DATA PCLA/T */ 0x0ff0, 0x00, 0xa0, 0xb0, 0 },
-       { /* Katron PE-520 */ 0x0110, 0x00, 0x40, 0xf6, 0 },
-       { /* Kingston KNE-PCM/x */ 0x0ff0, 0x00, 0xc0, 0xf0,
-         HAS_MISC_REG | HAS_IBM_MISC },
-       { /* Kingston KNE-PCM/x */ 0x0ff0, 0xe2, 0x0c, 0x0f,
-         HAS_MISC_REG | HAS_IBM_MISC },
-       { /* Kingston KNE-PC2 */ 0x0180, 0x00, 0xc0, 0xf0, 0 },
-       { /* Maxtech PCN2000 */ 0x5000, 0x00, 0x00, 0xe8, 0 },
-       { /* NDC Instant-Link */ 0x003a, 0x00, 0x80, 0xc6, 0 },
-       { /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 },
-       { /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65,
-         HAS_MISC_REG | HAS_IBM_MISC },
-       { /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45,
-         HAS_MISC_REG | HAS_IBM_MISC },
-       { /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 },
-       { /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 },
-       { /* SCM Ethernet */ 0x0ff0, 0x00, 0x20, 0xcb, 0 },
-       { /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b,
-         DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF },
-       { /* Socket LP-E CF+ */ 0x01c0, 0x00, 0xc0, 0x1b, 0 },
-       { /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 },
-       { /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 },
-       { /* NEC PC-9801N-J12 */ 0x0ff0, 0x00, 0x00, 0x4c, 0 },
-       { /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 }
-};
-
-#define NR_INFO                (sizeof(hw_info)/sizeof(hw_info_t))
-
-static hw_info_t default_info = { 0, 0, 0, 0, 0 };
-
-unsigned char dev_addr[6];
-
-#define PCNET_CMD      0x00
-#define PCNET_DATAPORT 0x10    /* NatSemi-defined port window offset. */
-#define PCNET_RESET    0x1f    /* Issue a read to reset, a write to clear. */
-#define PCNET_MISC     0x18    /* For IBM CCAE and Socket EA cards */
-
-unsigned long nic_base;
-
-static void pcnet_reset_8390(void)
-{
-       int i, r;
-
-       PRINTK("nic base is %lx\n", nic_base);
-
-       n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
-       PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD));
-       n2k_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, E8390_CMD);
-       PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD));
-       n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
-       PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD));
-       n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
-
-       n2k_outb(n2k_inb(PCNET_RESET), PCNET_RESET);
-
-       for (i = 0; i < 100; i++) {
-               if ((r = (n2k_inb(EN0_ISR) & ENISR_RESET)) != 0)
-                       break;
-               PRINTK("got %x in reset\n", r);
-               my_udelay(100);
-       }
-       n2k_outb(ENISR_RESET, EN0_ISR); /* Ack intr. */
-
-       if (i == 100)
-               printf("pcnet_reset_8390() did not complete.\n");
-} /* pcnet_reset_8390 */
-
-static hw_info_t * get_prom(void ) {
-       unsigned char prom[32];
-       int i, j;
-       struct {
-               u_char value, offset;
-       } program_seq[] = {
-               {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
-               {0x48,  EN0_DCFG},      /* Set byte-wide (0x48) access. */
-               {0x00,  EN0_RCNTLO},    /* Clear the count regs. */
-               {0x00,  EN0_RCNTHI},
-               {0x00,  EN0_IMR},       /* Mask completion irq. */
-               {0xFF,  EN0_ISR},
-               {E8390_RXOFF, EN0_RXCR},        /* 0x20  Set to monitor */
-               {E8390_TXOFF, EN0_TXCR},        /* 0x02  and loopback mode. */
-               {32,    EN0_RCNTLO},
-               {0x00,  EN0_RCNTHI},
-               {0x00,  EN0_RSARLO},    /* DMA starting at 0x0000. */
-               {0x00,  EN0_RSARHI},
-               {E8390_RREAD+E8390_START, E8390_CMD},
-       };
-
-       PRINTK("trying to get MAC via prom reading\n");
-
-       pcnet_reset_8390();
-
-       mdelay(10);
-
-       for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
-               n2k_outb(program_seq[i].value, program_seq[i].offset);
-
-       PRINTK("PROM:");
-       for (i = 0; i < 32; i++) {
-               prom[i] = n2k_inb(PCNET_DATAPORT);
-               PRINTK(" %02x", prom[i]);
-       }
-       PRINTK("\n");
-       for (i = 0; i < NR_INFO; i++) {
-               if ((prom[0] == hw_info[i].a0) &&
-                   (prom[2] == hw_info[i].a1) &&
-                   (prom[4] == hw_info[i].a2)) {
-                       PRINTK("matched board %d\n", i);
-                       break;
-               }
-       }
-       if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) {
-               for (j = 0; j < 6; j++)
-                       dev_addr[j] = prom[j<<1];
-               PRINTK("on exit i is %d/%ld\n", i, NR_INFO);
-               PRINTK("MAC address is %02x:%02x:%02x:%02x:%02x:%02x\n",
-                      dev_addr[0],dev_addr[1],dev_addr[2],dev_addr[3],dev_addr[4],dev_addr[5]);
-               return (i < NR_INFO) ? hw_info+i : &default_info;
-       }
-       return NULL;
-}
-
-/* U-boot specific routines */
-
-#define NB 5
-
-static unsigned char *pbuf = NULL;
-static int plen[NB];
-static int nrx = 0;
-
-static int pkey = -1;
-static int initialized=0;
-
-void uboot_push_packet_len(int len) {
-       PRINTK("pushed len = %d, nrx = %d\n", len, nrx);
-       if (len>=2000) {
-               printf("NE2000: packet too big\n");
-               return;
-       }
-       if (nrx >= NB) {
-               printf("losing packets in rx\n");
-               return;
-       }
-       plen[nrx] = len;
-       dp83902a_recv(&pbuf[nrx*2000], len);
-
-       /*Just pass it to the upper layer*/
-       NetReceive(&pbuf[nrx*2000], plen[nrx]);
-}
-
-void uboot_push_tx_done(int key, int val) {
-       PRINTK("pushed key = %d\n", key);
-       pkey = key;
-}
-
-int eth_init(bd_t *bd) {
-       static hw_info_t * r;
-       char ethaddr[20];
-
-       PRINTK("### eth_init\n");
-
-       if (!pbuf) {
-               pbuf = malloc(NB*2000);
-               if (!pbuf) {
-                       printf("Cannot allocate rx buffers\n");
-                       return -1;
-               }
-       }
-
-#ifdef CONFIG_DRIVER_NE2000_CCR
-       {
-               volatile unsigned char *p =  (volatile unsigned char *) CONFIG_DRIVER_NE2000_CCR;
-
-               PRINTK("CCR before is %x\n", *p);
-               *p = CONFIG_DRIVER_NE2000_VAL;
-               PRINTK("CCR after is %x\n", *p);
-       }
-#endif
-
-       nic_base = CONFIG_DRIVER_NE2000_BASE;
-       nic.base = (cyg_uint8 *) CONFIG_DRIVER_NE2000_BASE;
-
-       r = get_prom();
-       if (!r)
-               return -1;
-
-       sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
-                dev_addr[0], dev_addr[1],
-                dev_addr[2], dev_addr[3],
-                dev_addr[4], dev_addr[5]) ;
-       PRINTK("Set environment from HW MAC addr = \"%s\"\n", ethaddr);
-       setenv ("ethaddr", ethaddr);
-
-
-#define DP_DATA                0x10
-       nic.data = nic.base + DP_DATA;
-       nic.tx_buf1 = 0x40;
-       nic.tx_buf2 = 0x48;
-       nic.rx_buf_start = 0x50;
-       nic.rx_buf_end = 0x80;
-
-       if (dp83902a_init() == false)
-               return -1;
-       dp83902a_start(dev_addr);
-       initialized=1;
-       return 0;
-}
-
-void eth_halt() {
-
-       PRINTK("### eth_halt\n");
-       if(initialized)
-               dp83902a_stop();
-       initialized=0;
-}
-
-int eth_rx() {
-dp83902a_poll();
-return 1;
-}
-
-int eth_send(volatile void *packet, int length) {
-       int tmo;
-
-       PRINTK("### eth_send\n");
-
-       pkey = -1;
-
-       dp83902a_send((unsigned char *) packet, length, 666);
-       tmo = get_timer (0) + TOUT * CFG_HZ;
-       while(1) {
-               dp83902a_poll();
-               if (pkey != -1) {
-                       PRINTK("Packet sucesfully sent\n");
-                       return 0;
-               }
-               if (get_timer (0) >= tmo) {
-                       printf("transmission error (timoeut)\n");
-                       return 0;
-               }
-
-       }
-       return 0;
-}
-#endif
diff --git a/drivers/ne2000.h b/drivers/ne2000.h
deleted file mode 100644 (file)
index c13d9f0..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
-Ported to U-Boot  by Christian Pellegrin <chri@ascensit.com>
-
-Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
-eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
-are GPL, so this is, of course, GPL.
-
-
-==========================================================================
-
-      dev/dp83902a.h
-
-      National Semiconductor DP83902a ethernet chip
-
-==========================================================================
-####ECOSGPLCOPYRIGHTBEGIN####
- -------------------------------------------
- This file is part of eCos, the Embedded Configurable Operating System.
- Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-
- eCos is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 or (at your option) any later version.
-
- eCos is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- for more details.
-
- You should have received a copy of the GNU General Public License along
- with eCos; if not, write to the Free Software Foundation, Inc.,
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
- As a special exception, if other files instantiate templates or use macros
- or inline functions from this file, or you compile this file and link it
- with other works to produce a work based on this file, this file does not
- by itself cause the resulting work to be covered by the GNU General Public
- License. However the source code for this file must still be made available
- in accordance with section (3) of the GNU General Public License.
-
- This exception does not invalidate any other reasons why a work based on
- this file might be covered by the GNU General Public License.
-
- Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
- at http://sources.redhat.com/ecos/ecos-license/
- -------------------------------------------
-####ECOSGPLCOPYRIGHTEND####
-####BSDCOPYRIGHTBEGIN####
-
- -------------------------------------------
-
- Portions of this software may have been derived from OpenBSD or other sources,
- and are covered by the appropriate copyright disclaimers included herein.
-
- -------------------------------------------
-
-####BSDCOPYRIGHTEND####
-==========================================================================
-#####DESCRIPTIONBEGIN####
-
- Author(s):    gthomas
- Contributors: gthomas, jskov
- Date:         2001-06-13
- Purpose:
- Description:
-
-####DESCRIPTIONEND####
-
-==========================================================================
-
-*/
-
-/*
- ------------------------------------------------------------------------
- Macros for accessing DP registers
- These can be overridden by the platform header
-*/
-
-#define DP_IN(_b_, _o_, _d_)  (_d_) = *( (volatile unsigned char *) ((_b_)+(_o_)))
-#define DP_OUT(_b_, _o_, _d_) *( (volatile unsigned char *) ((_b_)+(_o_))) = (_d_)
-
-#define DP_IN_DATA(_b_, _d_)  (_d_) = *( (volatile unsigned char *) ((_b_)))
-#define DP_OUT_DATA(_b_, _d_) *( (volatile unsigned char *) ((_b_))) = (_d_)
-
-
-/* here is all the data */
-
-#define cyg_uint8 unsigned char
-#define cyg_uint16 unsigned short
-#define bool int
-
-#define false 0
-#define true 1
-
-#define CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA 1
-#define CYGACC_CALL_IF_DELAY_US(X) my_udelay(X)
-
-typedef struct dp83902a_priv_data {
-    cyg_uint8* base;
-    cyg_uint8* data;
-    cyg_uint8* reset;
-    int tx_next;           /* First free Tx page */
-    int tx_int;            /* Expecting interrupt from this buffer */
-    int rx_next;           /* First free Rx page */
-    int tx1, tx2;          /* Page numbers for Tx buffers */
-    unsigned long tx1_key, tx2_key;   /* Used to ack when packet sent */
-    int tx1_len, tx2_len;
-    bool tx_started, running, hardwired_esa;
-    cyg_uint8 esa[6];
-    void* plf_priv;
-
-    /* Buffer allocation */
-    int tx_buf1, tx_buf2;
-    int rx_buf_start, rx_buf_end;
-} dp83902a_priv_data_t;
-
-/*
- ------------------------------------------------------------------------
- Some forward declarations
-*/
-static void dp83902a_poll(void);
-
-/* ------------------------------------------------------------------------ */
-/* Register offsets */
-
-#define DP_CR          0x00
-#define DP_CLDA0       0x01
-#define DP_PSTART      0x01             /* write */
-#define DP_CLDA1       0x02
-#define DP_PSTOP       0x02             /* write */
-#define DP_BNDRY       0x03
-#define DP_TSR         0x04
-#define DP_TPSR        0x04             /* write */
-#define DP_NCR         0x05
-#define DP_TBCL        0x05             /* write */
-#define DP_FIFO        0x06
-#define DP_TBCH        0x06             /* write */
-#define DP_ISR         0x07
-#define DP_CRDA0       0x08
-#define DP_RSAL        0x08             /* write */
-#define DP_CRDA1       0x09
-#define DP_RSAH        0x09             /* write */
-#define DP_RBCL        0x0a             /* write */
-#define DP_RBCH        0x0b             /* write */
-#define DP_RSR         0x0c
-#define DP_RCR         0x0c             /* write */
-#define DP_FER         0x0d
-#define DP_TCR         0x0d             /* write */
-#define DP_CER         0x0e
-#define DP_DCR         0x0e             /* write */
-#define DP_MISSED      0x0f
-#define DP_IMR         0x0f             /* write */
-#define DP_DATAPORT    0x10             /* "eprom" data port */
-
-#define DP_P1_CR       0x00
-#define DP_P1_PAR0     0x01
-#define DP_P1_PAR1     0x02
-#define DP_P1_PAR2     0x03
-#define DP_P1_PAR3     0x04
-#define DP_P1_PAR4     0x05
-#define DP_P1_PAR5     0x06
-#define DP_P1_CURP     0x07
-#define DP_P1_MAR0     0x08
-#define DP_P1_MAR1     0x09
-#define DP_P1_MAR2     0x0a
-#define DP_P1_MAR3     0x0b
-#define DP_P1_MAR4     0x0c
-#define DP_P1_MAR5     0x0d
-#define DP_P1_MAR6     0x0e
-#define DP_P1_MAR7     0x0f
-
-#define DP_P2_CR       0x00
-#define DP_P2_PSTART   0x01
-#define DP_P2_CLDA0    0x01             /* write */
-#define DP_P2_PSTOP    0x02
-#define DP_P2_CLDA1    0x02             /* write */
-#define DP_P2_RNPP     0x03
-#define DP_P2_TPSR     0x04
-#define DP_P2_LNPP     0x05
-#define DP_P2_ACH      0x06
-#define DP_P2_ACL      0x07
-#define DP_P2_RCR      0x0c
-#define DP_P2_TCR      0x0d
-#define DP_P2_DCR      0x0e
-#define DP_P2_IMR      0x0f
-
-/* Command register - common to all pages */
-
-#define DP_CR_STOP    0x01   /* Stop: software reset */
-#define DP_CR_START   0x02   /* Start: initialize device */
-#define DP_CR_TXPKT   0x04   /* Transmit packet */
-#define DP_CR_RDMA    0x08   /* Read DMA  (recv data from device) */
-#define DP_CR_WDMA    0x10   /* Write DMA (send data to device) */
-#define DP_CR_SEND    0x18   /* Send packet */
-#define DP_CR_NODMA   0x20   /* Remote (or no) DMA */
-#define DP_CR_PAGE0   0x00   /* Page select */
-#define DP_CR_PAGE1   0x40
-#define DP_CR_PAGE2   0x80
-#define DP_CR_PAGEMSK 0x3F   /* Used to mask out page bits */
-
-/* Data configuration register */
-
-#define DP_DCR_WTS    0x01   /* 1=16 bit word transfers */
-#define DP_DCR_BOS    0x02   /* 1=Little Endian */
-#define DP_DCR_LAS    0x04   /* 1=Single 32 bit DMA mode */
-#define DP_DCR_LS     0x08   /* 1=normal mode, 0=loopback */
-#define DP_DCR_ARM    0x10   /* 0=no send command (program I/O) */
-#define DP_DCR_FIFO_1 0x00   /* FIFO threshold */
-#define DP_DCR_FIFO_2 0x20
-#define DP_DCR_FIFO_4 0x40
-#define DP_DCR_FIFO_6 0x60
-
-#define DP_DCR_INIT   (DP_DCR_LS|DP_DCR_FIFO_4)
-
-/* Interrupt status register */
-
-#define DP_ISR_RxP    0x01   /* Packet received */
-#define DP_ISR_TxP    0x02   /* Packet transmitted */
-#define DP_ISR_RxE    0x04   /* Receive error */
-#define DP_ISR_TxE    0x08   /* Transmit error */
-#define DP_ISR_OFLW   0x10   /* Receive overflow */
-#define DP_ISR_CNT    0x20   /* Tally counters need emptying */
-#define DP_ISR_RDC    0x40   /* Remote DMA complete */
-#define DP_ISR_RESET  0x80   /* Device has reset (shutdown, error) */
-
-/* Interrupt mask register */
-
-#define DP_IMR_RxP    0x01   /* Packet received */
-#define DP_IMR_TxP    0x02   /* Packet transmitted */
-#define DP_IMR_RxE    0x04   /* Receive error */
-#define DP_IMR_TxE    0x08   /* Transmit error */
-#define DP_IMR_OFLW   0x10   /* Receive overflow */
-#define DP_IMR_CNT    0x20   /* Tall counters need emptying */
-#define DP_IMR_RDC    0x40   /* Remote DMA complete */
-
-#define DP_IMR_All    0x3F   /* Everything but remote DMA */
-
-/* Receiver control register */
-
-#define DP_RCR_SEP    0x01   /* Save bad(error) packets */
-#define DP_RCR_AR     0x02   /* Accept runt packets */
-#define DP_RCR_AB     0x04   /* Accept broadcast packets */
-#define DP_RCR_AM     0x08   /* Accept multicast packets */
-#define DP_RCR_PROM   0x10   /* Promiscuous mode */
-#define DP_RCR_MON    0x20   /* Monitor mode - 1=accept no packets */
-
-/* Receiver status register */
-
-#define DP_RSR_RxP    0x01   /* Packet received */
-#define DP_RSR_CRC    0x02   /* CRC error */
-#define DP_RSR_FRAME  0x04   /* Framing error */
-#define DP_RSR_FO     0x08   /* FIFO overrun */
-#define DP_RSR_MISS   0x10   /* Missed packet */
-#define DP_RSR_PHY    0x20   /* 0=pad match, 1=mad match */
-#define DP_RSR_DIS    0x40   /* Receiver disabled */
-#define DP_RSR_DFR    0x80   /* Receiver processing deferred */
-
-/* Transmitter control register */
-
-#define DP_TCR_NOCRC  0x01   /* 1=inhibit CRC */
-#define DP_TCR_NORMAL 0x00   /* Normal transmitter operation */
-#define DP_TCR_LOCAL  0x02   /* Internal NIC loopback */
-#define DP_TCR_INLOOP 0x04   /* Full internal loopback */
-#define DP_TCR_OUTLOOP 0x08  /* External loopback */
-#define DP_TCR_ATD    0x10   /* Auto transmit disable */
-#define DP_TCR_OFFSET 0x20   /* Collision offset adjust */
-
-/* Transmit status register */
-
-#define DP_TSR_TxP    0x01   /* Packet transmitted */
-#define DP_TSR_COL    0x04   /* Collision (at least one) */
-#define DP_TSR_ABT    0x08   /* Aborted because of too many collisions */
-#define DP_TSR_CRS    0x10   /* Lost carrier */
-#define DP_TSR_FU     0x20   /* FIFO underrun */
-#define DP_TSR_CDH    0x40   /* Collision Detect Heartbeat */
-#define DP_TSR_OWC    0x80   /* Collision outside normal window */
-
-#define IEEE_8023_MAX_FRAME         1518    /* Largest possible ethernet frame */
-#define IEEE_8023_MIN_FRAME           64    /* Smallest possible ethernet frame */
diff --git a/drivers/net/3c589.c b/drivers/net/3c589.c
new file mode 100644 (file)
index 0000000..080b686
--- /dev/null
@@ -0,0 +1,519 @@
+/*------------------------------------------------------------------------
+ . 3c589.c
+ . This is a driver for 3Com's 3C589 (Etherlink III) PCMCIA Ethernet device.
+ .
+ . (C) Copyright 2002
+ . Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ . Rolf Offermanns <rof@sysgo.de>
+ .
+ . This program is free software; you can redistribute it and/or modify
+ . it under the terms of the GNU General Public License as published by
+ . the Free Software Foundation; either version 2 of the License, or
+ . (at your option) any later version.
+ .
+ . This program is distributed in the hope that it will be useful,
+ . but WITHOUT ANY WARRANTY; without even the implied warranty of
+ . MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ . GNU General Public License for more details.
+ .
+ . You should have received a copy of the GNU General Public License
+ . along with this program; if not, write to the Free Software
+ . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ .
+ ----------------------------------------------------------------------------*/
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+
+#ifdef CONFIG_DRIVER_3C589
+
+#include "3c589.h"
+
+
+/* Use power-down feature of the chip */
+#define POWER_DOWN     0
+
+#define NO_AUTOPROBE
+
+static const char version[] =
+       "Your ad here! :P\n";
+
+
+#undef EL_DEBUG
+
+typedef unsigned char byte;
+typedef unsigned short word;
+typedef unsigned long int dword;
+/*------------------------------------------------------------------------
+ .
+ . Configuration options, for the experienced user to change.
+ .
+ -------------------------------------------------------------------------*/
+
+/*
+ . Wait time for memory to be free.  This probably shouldn't be
+ . tuned that much, as waiting for this means nothing else happens
+ . in the system
+*/
+#define MEMORY_WAIT_TIME 16
+
+
+#if (EL_DEBUG > 2 )
+#define PRINTK3(args...) printf(args)
+#else
+#define PRINTK3(args...)
+#endif
+
+#if EL_DEBUG > 1
+#define PRINTK2(args...) printf(args)
+#else
+#define PRINTK2(args...)
+#endif
+
+#ifdef EL_DEBUG
+#define PRINTK(args...) printf(args)
+#else
+#define PRINTK(args...)
+#endif
+
+#define outb(args...)  mmio_outb(args)
+#define mmio_outb(value, addr) (*((volatile byte *)(addr)) = value)
+
+#define inb(args...)   mmio_inb(args)
+#define mmio_inb(addr) (*((volatile byte *)(addr)))
+
+#define outw(args...)  mmio_outw(args)
+#define mmio_outw(value, addr) (*((volatile word *)(addr)) = value)
+
+#define inw(args...)   mmio_inw(args)
+#define mmio_inw(addr) (*((volatile word *)(addr)))
+
+#define outsw(args...) mmio_outsw(args)
+#define mmio_outsw(r,b,l)      ({      int __i; \
+                                       word *__b2; \
+                                       __b2 = (word *) b; \
+                                       for (__i = 0; __i < l; __i++) { \
+                                           mmio_outw( *(__b2 + __i), r); \
+                                       } \
+                               })
+
+#define insw(args...)  mmio_insw(args)
+#define mmio_insw(r,b,l)       ({      int __i ;  \
+                                       word *__b2;  \
+                                       __b2 = (word *) b;  \
+                                       for (__i = 0; __i < l; __i++) {  \
+                                         *(__b2 + __i) = mmio_inw(r);  \
+                                         mmio_inw(0);  \
+                                       };  \
+                               })
+
+/*------------------------------------------------------------------------
+ .
+ . The internal workings of the driver.  If you are changing anything
+ . here with the 3Com stuff, you should have the datasheet and know
+ . what you are doing.
+ .
+ -------------------------------------------------------------------------*/
+#define EL_BASE_ADDR   0x20000000
+
+
+/* Offsets from base I/O address. */
+#define EL3_DATA       0x00
+#define EL3_TIMER      0x0a
+#define EL3_CMD                0x0e
+#define EL3_STATUS     0x0e
+
+#define EEPROM_READ    0x0080
+
+#define EL3WINDOW(win_num) mmio_outw(SelectWindow + (win_num), EL_BASE_ADDR + EL3_CMD)
+
+/* The top five bits written to EL3_CMD are a command, the lower
+   11 bits are the parameter, if applicable. */
+enum c509cmd {
+    TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11,
+    RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11,
+    TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11,
+    FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11,
+    SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
+    SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11,
+    StatsDisable = 22<<11, StopCoax = 23<<11,
+};
+
+enum c509status {
+    IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
+    TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
+    IntReq = 0x0040, StatsFull = 0x0080, CmdBusy = 0x1000
+};
+
+/* The SetRxFilter command accepts the following classes: */
+enum RxFilter {
+    RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8
+};
+
+/* Register window 1 offsets, the window used in normal operation. */
+#define TX_FIFO                0x00
+#define RX_FIFO                0x00
+#define RX_STATUS      0x08
+#define TX_STATUS      0x0B
+#define TX_FREE                0x0C    /* Remaining free bytes in Tx buffer. */
+
+
+/*
+  Read a word from the EEPROM using the regular EEPROM access register.
+  Assume that we are in register window zero.
+*/
+static word read_eeprom(dword ioaddr, int index)
+{
+    int i;
+    outw(EEPROM_READ + index, ioaddr + 0xa);
+    /* Reading the eeprom takes 162 us */
+    for (i = 1620; i >= 0; i--)
+       if ((inw(ioaddr + 10) & EEPROM_BUSY) == 0)
+           break;
+    return inw(ioaddr + 0xc);
+}
+
+static void el_get_mac_addr( unsigned char *mac_addr )
+{
+       int i;
+       union
+       {
+               word w;
+               unsigned char b[2];
+       } wrd;
+       unsigned char old_window = inw( EL_BASE_ADDR + EL3_STATUS ) >> 13;
+       GO_WINDOW(0);
+       VX_BUSY_WAIT;
+       for (i = 0; i < 3; i++)
+       {
+               wrd.w = read_eeprom(EL_BASE_ADDR, 0xa+i);
+#ifdef __BIG_ENDIAN
+               mac_addr[2*i]   = wrd.b[0];
+               mac_addr[2*i+1] = wrd.b[1];
+#else
+               mac_addr[2*i]   = wrd.b[1];
+               mac_addr[2*i+1] = wrd.b[0];
+#endif
+       }
+       GO_WINDOW(old_window);
+       VX_BUSY_WAIT;
+}
+
+
+#if EL_DEBUG > 1
+static void print_packet( byte * buf, int length )
+{
+       int i;
+       int remainder;
+       int lines;
+
+       PRINTK2("Packet of length %d \n", length );
+
+       lines = length / 16;
+       remainder = length % 16;
+
+       for ( i = 0; i < lines ; i ++ ) {
+               int cur;
+
+               for ( cur = 0; cur < 8; cur ++ ) {
+                       byte a, b;
+
+                       a = *(buf ++ );
+                       b = *(buf ++ );
+                       PRINTK2("%02x%02x ", a, b );
+               }
+               PRINTK2("\n");
+       }
+       for ( i = 0; i < remainder/2 ; i++ ) {
+               byte a, b;
+
+               a = *(buf ++ );
+               b = *(buf ++ );
+               PRINTK2("%02x%02x ", a, b );
+       }
+       PRINTK2("\n");
+}
+#endif /* EL_DEBUG > 1 */
+
+
+/**************************************************************************
+ETH_RESET - Reset adapter
+***************************************************************************/
+static void el_reset(bd_t *bd)
+{
+       /***********************************************************
+                       Reset 3Com 595 card
+       *************************************************************/
+       /* QUICK HACK
+        * - adjust timing for 3c589
+        * - enable io for PCMCIA */
+       outw(0x0004, 0xa0000018);
+       udelay(100);
+       outw(0x0041, 0x28010000);
+       udelay(100);
+
+       /* issue global reset */
+       outw(GLOBAL_RESET, BASE + VX_COMMAND);
+
+       /* must wait for at least 1ms */
+       udelay(100000000);
+
+       /* set mac addr */
+       {
+               unsigned char *mac_addr = bd->bi_enetaddr;
+               int i;
+
+               el_get_mac_addr( mac_addr );
+
+               GO_WINDOW(2);
+               VX_BUSY_WAIT;
+
+               printf("3C589 MAC Addr.: ");
+               for (i = 0; i < 6; i++)
+               {
+                       printf("%02x", mac_addr[i]);
+                       outb(mac_addr[i], BASE + VX_W2_ADDR_0 + i);
+                       VX_BUSY_WAIT;
+               }
+               printf("\n\n");
+       }
+
+       /* set RX filter */
+       outw(SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST, BASE + VX_COMMAND);
+       VX_BUSY_WAIT;
+
+
+       /* set irq mask and read_zero */
+       outw(SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
+               S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
+       VX_BUSY_WAIT;
+
+       outw(SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
+               S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
+       VX_BUSY_WAIT;
+
+       /* enable TP Linkbeat */
+       GO_WINDOW(4);
+       VX_BUSY_WAIT;
+
+       outw( ENABLE_UTP, BASE + VX_W4_MEDIA_TYPE);
+       VX_BUSY_WAIT;
+
+
+/*
+ * Attempt to get rid of any stray interrupts that occured during
+ * configuration.  On the i386 this isn't possible because one may
+ * already be queued.  However, a single stray interrupt is
+ * unimportant.
+ */
+
+       outw(ACK_INTR | 0xff, BASE + VX_COMMAND);
+       VX_BUSY_WAIT;
+
+       /* enable TX and RX */
+       outw( RX_ENABLE, BASE + VX_COMMAND );
+       VX_BUSY_WAIT;
+
+       outw( TX_ENABLE, BASE + VX_COMMAND );
+       VX_BUSY_WAIT;
+
+
+       /* print the diag. regs. */
+       PRINTK2("Diag. Regs\n");
+       PRINTK2("--> MEDIA_TYPE:   %04x\n", inw(BASE + VX_W4_MEDIA_TYPE));
+       PRINTK2("--> NET_DIAG:     %04x\n", inw(BASE + VX_W4_NET_DIAG));
+       PRINTK2("--> FIFO_DIAG:    %04x\n", inw(BASE + VX_W4_FIFO_DIAG));
+       PRINTK2("--> CTRLR_STATUS: %04x\n", inw(BASE + VX_W4_CTRLR_STATUS));
+       PRINTK2("\n\n");
+
+       /* enter working mode */
+       GO_WINDOW(1);
+       VX_BUSY_WAIT;
+
+       /* wait for another 1ms */
+       udelay(100000000);
+}
+
+
+/*-----------------------------------------------------------------
+ .
+ .  The driver can be entered at any of the following entry points.
+ .
+ .------------------------------------------------------------------  */
+
+extern int eth_init(bd_t *bd);
+extern void eth_halt(void);
+extern int eth_rx(void);
+extern int eth_send(volatile void *packet, int length);
+
+
+/*
+ ------------------------------------------------------------
+ .
+ . Internal routines
+ .
+ ------------------------------------------------------------
+*/
+
+int eth_init(bd_t *bd)
+{
+       el_reset(bd);
+       return 0;
+}
+
+void eth_halt() {
+       return;
+}
+
+#define EDEBUG 1
+
+
+/**************************************************************************
+ETH_POLL - Wait for a frame
+***************************************************************************/
+
+int eth_rx()
+{
+       word status, rx_status, packet_size;
+
+       VX_BUSY_WAIT;
+
+       status = inw( BASE + VX_STATUS );
+
+       if ( (status & S_RX_COMPLETE) == 0 ) return 0; /* nothing to do */
+
+       /* Packet waiting -> check RX_STATUS */
+       rx_status = inw( BASE + VX_W1_RX_STATUS );
+
+       if ( rx_status & ERR_RX )
+       {
+               /* error in packet -> discard */
+               PRINTK("[ERROR] Invalid packet -> discarding\n");
+               PRINTK("-- error code 0x%02x\n", rx_status & ERR_MASK);
+               PRINTK("-- rx bytes 0x%04d\n", rx_status & ((1<<11) - 1));
+               PRINTK("[ERROR] Invalid packet -> discarding\n");
+               outw( RX_DISCARD_TOP_PACK, BASE + VX_COMMAND );
+               return 0;
+       }
+
+       /* correct pack. waiting in fifo */
+       packet_size = rx_status & RX_BYTES_MASK;
+
+       PRINTK("Correct packet waiting in fifo, size: %d\n", packet_size);
+
+       {
+               volatile word *packet_start = (word *)(BASE + VX_W1_RX_PIO_RD_1);
+               word *RcvBuffer = (word *)(NetRxPackets[0]);
+               int wcount = 0;
+
+               for (wcount = 0; wcount < (packet_size >> 1); wcount++)
+               {
+                       *RcvBuffer++ = *(packet_start);
+               }
+
+               /* handle odd packets */
+               if ( packet_size & 1 )
+               {
+                       *RcvBuffer++ = *(packet_start);
+               }
+       }
+
+       /* fifo should now be empty (besides the padding bytes) */
+       if ( ((*((word *)(BASE + VX_W1_RX_STATUS))) & RX_BYTES_MASK) > 3 )
+       {
+               PRINTK("[ERROR] Fifo not empty after packet read (remaining pkts: %d)\n",
+                       (((*(word *)(BASE + VX_W1_RX_STATUS))) & RX_BYTES_MASK));
+       }
+
+       /* discard packet */
+       *((word *)(BASE + VX_COMMAND)) = RX_DISCARD_TOP_PACK;
+
+       /* Pass Packets to upper Layer */
+       NetReceive(NetRxPackets[0], packet_size);
+       return packet_size;
+}
+
+
+/**************************************************************************
+ETH_TRANSMIT - Transmit a frame
+***************************************************************************/
+static char padmap[] = {
+       0, 3, 2, 1};
+
+
+int eth_send(volatile void *packet, int length) {
+       int pad;
+       int status;
+       volatile word *buf = (word *)packet;
+       int dummy = 0;
+
+       /* padding stuff */
+       pad = padmap[length & 3];
+
+       PRINTK("eth_send(), length: %d\n", length);
+       /* drop acknowledgements */
+       while(( status=inb(EL_BASE_ADDR + VX_W1_TX_STATUS) )& TXS_COMPLETE ) {
+               if(status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
+                       outw(TX_RESET, EL_BASE_ADDR + VX_COMMAND);
+                       outw(TX_ENABLE, EL_BASE_ADDR + VX_COMMAND);
+                       PRINTK("Bad status, resetting and reenabling transmitter\n");
+               }
+
+               outb(0x0, EL_BASE_ADDR + VX_W1_TX_STATUS);
+       }
+
+
+       while (inw(EL_BASE_ADDR + VX_W1_FREE_TX) < length + pad + 4) {
+               /* no room in FIFO */
+               if (dummy == 0)
+               {
+                       PRINTK("No room in FIFO, waiting...\n");
+                       dummy++;
+               }
+
+       }
+
+       PRINTK("    ---> FIFO ready\n");
+
+
+       outw(length, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
+
+       /* Second dword meaningless */
+       outw(0x0, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
+
+#if EL_DEBUG > 1
+       print_packet((byte *)buf, length);
+#endif
+
+       /* write packet */
+       {
+               unsigned int i, totw;
+
+               totw = ((length + 1) >> 1);
+               PRINTK("Buffer: (totw = %d)\n", totw);
+               for (i = 0; i < totw; i++) {
+                       outw( *(buf+i), EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
+                       udelay(10);
+               }
+               if(totw & 1)
+               {       /* pad to double word length */
+                       outw( 0, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
+                       udelay(10);
+               }
+               PRINTK("\n\n");
+       }
+
+       /* wait for Tx complete */
+       PRINTK("Waiting for Tx to complete...\n");
+       while(((status = inw(EL_BASE_ADDR + VX_STATUS)) & S_COMMAND_IN_PROGRESS) != 0)
+       {
+               udelay(10);
+       }
+       PRINTK("   ---> Tx completed, status = 0x%04x\n", status);
+
+       return length;
+}
+
+
+#endif /* CONFIG_DRIVER_3C589 */
diff --git a/drivers/net/3c589.h b/drivers/net/3c589.h
new file mode 100644 (file)
index 0000000..6735bf9
--- /dev/null
@@ -0,0 +1,435 @@
+/*
+ * Copyright (c) 1993 Herb Peyerl (hpeyerl@novatel.ca) All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer. 2. The name
+ * of the author may not be used to endorse or promote products derived from
+ * this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ October 2, 1994
+
+ Modified by: Andres Vega Garcia
+
+ INRIA - Sophia Antipolis, France
+ e-mail: avega@sophia.inria.fr
+ finger: avega@pax.inria.fr
+
+ */
+
+/*
+ * Created from if_epreg.h by Fred Gray (fgray@rice.edu) to support the
+ * 3c590 family.
+ */
+
+/*
+ * Modified by Shusuke Nisiyama <shu@athena.qe.eng.hokudai.ac.jp>
+ * for etherboot
+ * Mar. 14, 2000
+*/
+
+/*
+ * Ethernet software status per interface.
+ */
+
+/*
+ * Some global constants
+ */
+
+#define TX_INIT_RATE         16
+#define TX_INIT_MAX_RATE     64
+#define RX_INIT_LATENCY      64
+#define RX_INIT_EARLY_THRESH 64
+#define MIN_RX_EARLY_THRESHF   16 /* not less than ether_header */
+#define MIN_RX_EARLY_THRESHL   4
+
+#define EEPROMSIZE      0x40
+#define MAX_EEPROMBUSY  1000
+#define VX_LAST_TAG     0xd7
+#define VX_MAX_BOARDS   16
+#define VX_ID_PORT      0x100
+
+/*
+ * some macros to acces long named fields
+ */
+#define BASE   (EL_BASE_ADDR)
+
+/*
+ * Commands to read/write EEPROM trough EEPROM command register (Window 0,
+ * Offset 0xa)
+ */
+#define EEPROM_CMD_RD    0x0080        /* Read:  Address required (5 bits) */
+#define EEPROM_CMD_WR    0x0040        /* Write: Address required (5 bits) */
+#define EEPROM_CMD_ERASE 0x00c0        /* Erase: Address required (5 bits) */
+#define EEPROM_CMD_EWEN  0x0030        /* Erase/Write Enable: No data required */
+
+#define EEPROM_BUSY            (1<<15)
+
+/*
+ * Some short functions, worth to let them be a macro
+ */
+
+/**************************************************************************
+ *                                                                       *
+ * These define the EEPROM data structure.  They are used in the probe
+ * function to verify the existence of the adapter after having sent
+ * the ID_Sequence.
+ *
+ * There are others but only the ones we use are defined here.
+ *
+ **************************************************************************/
+
+#define EEPROM_NODE_ADDR_0     0x0     /* Word */
+#define EEPROM_NODE_ADDR_1     0x1     /* Word */
+#define EEPROM_NODE_ADDR_2     0x2     /* Word */
+#define EEPROM_PROD_ID         0x3     /* 0x9[0-f]50 */
+#define EEPROM_MFG_ID          0x7     /* 0x6d50 */
+#define EEPROM_ADDR_CFG                0x8     /* Base addr */
+#define EEPROM_RESOURCE_CFG    0x9     /* IRQ. Bits 12-15 */
+#define EEPROM_OEM_ADDR_0      0xa     /* Word */
+#define EEPROM_OEM_ADDR_1      0xb     /* Word */
+#define EEPROM_OEM_ADDR_2      0xc     /* Word */
+#define EEPROM_SOFT_INFO_2     0xf     /* Software information 2 */
+
+#define NO_RX_OVN_ANOMALY       (1<<5)
+
+/**************************************************************************
+ *                                                                               *
+ * These are the registers for the 3Com 3c509 and their bit patterns when *
+ * applicable.  They have been taken out the the "EtherLink III Parallel  *
+ * Tasking EISA and ISA Technical Reference" "Beta Draft 10/30/92" manual *
+ * from 3com.                                                            *
+ *                                                                               *
+ **************************************************************************/
+
+#define VX_COMMAND             0x0e    /* Write. BASE+0x0e is always a
+                                        * command reg. */
+#define VX_STATUS              0x0e    /* Read. BASE+0x0e is always status
+                                        * reg. */
+#define VX_WINDOW              0x0f    /* Read. BASE+0x0f is always window
+                                        * reg. */
+/*
+ * Window 0 registers. Setup.
+ */
+/* Write */
+#define VX_W0_EEPROM_DATA      0x0c
+#define VX_W0_EEPROM_COMMAND   0x0a
+#define VX_W0_RESOURCE_CFG     0x08
+#define VX_W0_ADDRESS_CFG      0x06
+#define VX_W0_CONFIG_CTRL      0x04
+       /* Read */
+#define VX_W0_PRODUCT_ID       0x02
+#define VX_W0_MFG_ID           0x00
+
+
+/*
+ * Window 1 registers. Operating Set.
+ */
+/* Write */
+#define VX_W1_TX_PIO_WR_2      0x02
+#define VX_W1_TX_PIO_WR_1      0x00
+/* Read */
+#define VX_W1_FREE_TX          0x0c
+#define VX_W1_TX_STATUS                0x0b    /* byte */
+#define VX_W1_TIMER            0x0a    /* byte */
+#define VX_W1_RX_STATUS                0x08
+#define VX_W1_RX_PIO_RD_2      0x02
+#define VX_W1_RX_PIO_RD_1      0x00
+
+/*
+ * Window 2 registers. Station Address Setup/Read
+ */
+/* Read/Write */
+#define VX_W2_ADDR_5           0x05
+#define VX_W2_ADDR_4           0x04
+#define VX_W2_ADDR_3           0x03
+#define VX_W2_ADDR_2           0x02
+#define VX_W2_ADDR_1           0x01
+#define VX_W2_ADDR_0           0x00
+
+/*
+ * Window 3 registers. FIFO Management.
+ */
+/* Read */
+#define VX_W3_INTERNAL_CFG     0x00
+#define VX_W3_RESET_OPT                0x08
+#define VX_W3_FREE_TX          0x0c
+#define VX_W3_FREE_RX          0x0a
+
+/*
+ * Window 4 registers. Diagnostics.
+ */
+/* Read/Write */
+#define VX_W4_MEDIA_TYPE       0x0a
+#define VX_W4_CTRLR_STATUS     0x08
+#define VX_W4_NET_DIAG         0x06
+#define VX_W4_FIFO_DIAG                0x04
+#define VX_W4_HOST_DIAG                0x02
+#define VX_W4_TX_DIAG          0x00
+
+/*
+ * Window 5 Registers.  Results and Internal status.
+ */
+/* Read */
+#define VX_W5_READ_0_MASK      0x0c
+#define VX_W5_INTR_MASK                0x0a
+#define VX_W5_RX_FILTER                0x08
+#define VX_W5_RX_EARLY_THRESH  0x06
+#define VX_W5_TX_AVAIL_THRESH  0x02
+#define VX_W5_TX_START_THRESH  0x00
+
+/*
+ * Window 6 registers. Statistics.
+ */
+/* Read/Write */
+#define TX_TOTAL_OK            0x0c
+#define RX_TOTAL_OK            0x0a
+#define TX_DEFERRALS           0x08
+#define RX_FRAMES_OK           0x07
+#define TX_FRAMES_OK           0x06
+#define RX_OVERRUNS            0x05
+#define TX_COLLISIONS          0x04
+#define TX_AFTER_1_COLLISION   0x03
+#define TX_AFTER_X_COLLISIONS  0x02
+#define TX_NO_SQE              0x01
+#define TX_CD_LOST             0x00
+
+/****************************************
+ *
+ * Register definitions.
+ *
+ ****************************************/
+
+/*
+ * Command register. All windows.
+ *
+ * 16 bit register.
+ *     15-11:  5-bit code for command to be executed.
+ *     10-0:   11-bit arg if any. For commands with no args;
+ *           this can be set to anything.
+ */
+#define GLOBAL_RESET           (unsigned short) 0x0000 /* Wait at least 1ms
+                                                        * after issuing */
+#define WINDOW_SELECT          (unsigned short) (0x1<<11)
+#define START_TRANSCEIVER      (unsigned short) (0x2<<11)      /* Read ADDR_CFG reg to
+                                                        * determine whether
+                                                        * this is needed. If
+                                                        * so; wait 800 uSec
+                                                        * before using trans-
+                                                        * ceiver. */
+#define RX_DISABLE             (unsigned short) (0x3<<11)      /* state disabled on
+                                                        * power-up */
+#define RX_ENABLE              (unsigned short) (0x4<<11)
+#define RX_RESET               (unsigned short) (0x5<<11)
+#define RX_DISCARD_TOP_PACK    (unsigned short) (0x8<<11)
+#define TX_ENABLE              (unsigned short) (0x9<<11)
+#define TX_DISABLE             (unsigned short) (0xa<<11)
+#define TX_RESET               (unsigned short) (0xb<<11)
+#define REQ_INTR               (unsigned short) (0xc<<11)
+/*
+ * The following C_* acknowledge the various interrupts. Some of them don't
+ * do anything.  See the manual.
+ */
+#define ACK_INTR               (unsigned short) (0x6800)
+#      define C_INTR_LATCH     (unsigned short) (ACK_INTR|0x1)
+#      define C_CARD_FAILURE   (unsigned short) (ACK_INTR|0x2)
+#      define C_TX_COMPLETE    (unsigned short) (ACK_INTR|0x4)
+#      define C_TX_AVAIL       (unsigned short) (ACK_INTR|0x8)
+#      define C_RX_COMPLETE    (unsigned short) (ACK_INTR|0x10)
+#      define C_RX_EARLY       (unsigned short) (ACK_INTR|0x20)
+#      define C_INT_RQD                (unsigned short) (ACK_INTR|0x40)
+#      define C_UPD_STATS      (unsigned short) (ACK_INTR|0x80)
+#define SET_INTR_MASK          (unsigned short) (0xe<<11)
+#define SET_RD_0_MASK          (unsigned short) (0xf<<11)
+#define SET_RX_FILTER          (unsigned short) (0x10<<11)
+#      define FIL_INDIVIDUAL   (unsigned short) (0x1)
+#      define FIL_MULTICAST     (unsigned short) (0x02)
+#      define FIL_BRDCST        (unsigned short) (0x04)
+#      define FIL_PROMISC       (unsigned short) (0x08)
+#define SET_RX_EARLY_THRESH    (unsigned short) (0x11<<11)
+#define SET_TX_AVAIL_THRESH    (unsigned short) (0x12<<11)
+#define SET_TX_START_THRESH    (unsigned short) (0x13<<11)
+#define STATS_ENABLE           (unsigned short) (0x15<<11)
+#define STATS_DISABLE          (unsigned short) (0x16<<11)
+#define STOP_TRANSCEIVER       (unsigned short) (0x17<<11)
+
+/*
+ * Status register. All windows.
+ *
+ *     15-13:  Window number(0-7).
+ *     12:     Command_in_progress.
+ *     11:     reserved.
+ *     10:     reserved.
+ *     9:      reserved.
+ *     8:      reserved.
+ *     7:      Update Statistics.
+ *     6:      Interrupt Requested.
+ *     5:      RX Early.
+ *     4:      RX Complete.
+ *     3:      TX Available.
+ *     2:      TX Complete.
+ *     1:      Adapter Failure.
+ *     0:      Interrupt Latch.
+ */
+#define S_INTR_LATCH           (unsigned short) (0x1)
+#define S_CARD_FAILURE         (unsigned short) (0x2)
+#define S_TX_COMPLETE          (unsigned short) (0x4)
+#define S_TX_AVAIL             (unsigned short) (0x8)
+#define S_RX_COMPLETE          (unsigned short) (0x10)
+#define S_RX_EARLY             (unsigned short) (0x20)
+#define S_INT_RQD              (unsigned short) (0x40)
+#define S_UPD_STATS            (unsigned short) (0x80)
+#define S_COMMAND_IN_PROGRESS  (unsigned short) (0x1000)
+
+#define VX_BUSY_WAIT while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS)
+
+/* Address Config. Register.
+ * Window 0/Port 06
+ */
+
+#define ACF_CONNECTOR_BITS     14
+#define ACF_CONNECTOR_UTP      0
+#define ACF_CONNECTOR_AUI      1
+#define ACF_CONNECTOR_BNC      3
+
+#define INTERNAL_CONNECTOR_BITS 20
+#define INTERNAL_CONNECTOR_MASK 0x01700000
+
+/*
+ * FIFO Registers. RX Status.
+ *
+ *     15:     Incomplete or FIFO empty.
+ *     14:     1: Error in RX Packet   0: Incomplete or no error.
+ *     13-11:  Type of error.
+ *           1000 = Overrun.
+ *           1011 = Run Packet Error.
+ *           1100 = Alignment Error.
+ *           1101 = CRC Error.
+ *           1001 = Oversize Packet Error (>1514 bytes)
+ *           0010 = Dribble Bits.
+ *           (all other error codes, no errors.)
+ *
+ *     10-0:   RX Bytes (0-1514)
+ */
+#define ERR_INCOMPLETE  (unsigned short) (0x8000)
+#define ERR_RX          (unsigned short) (0x4000)
+#define ERR_MASK        (unsigned short) (0x7800)
+#define ERR_OVERRUN     (unsigned short) (0x4000)
+#define ERR_RUNT        (unsigned short) (0x5800)
+#define ERR_ALIGNMENT   (unsigned short) (0x6000)
+#define ERR_CRC         (unsigned short) (0x6800)
+#define ERR_OVERSIZE    (unsigned short) (0x4800)
+#define ERR_DRIBBLE     (unsigned short) (0x1000)
+
+/*
+ * TX Status.
+ *
+ *   Reports the transmit status of a completed transmission. Writing this
+ *   register pops the transmit completion stack.
+ *
+ *   Window 1/Port 0x0b.
+ *
+ *     7:      Complete
+ *     6:      Interrupt on successful transmission requested.
+ *     5:      Jabber Error (TP Only, TX Reset required. )
+ *     4:      Underrun (TX Reset required. )
+ *     3:      Maximum Collisions.
+ *     2:      TX Status Overflow.
+ *     1-0:    Undefined.
+ *
+ */
+#define TXS_COMPLETE           0x80
+#define TXS_INTR_REQ           0x40
+#define TXS_JABBER             0x20
+#define TXS_UNDERRUN           0x10
+#define TXS_MAX_COLLISION      0x8
+#define TXS_STATUS_OVERFLOW    0x4
+
+#define RS_AUI                 (1<<5)
+#define RS_BNC                 (1<<4)
+#define RS_UTP                 (1<<3)
+#define        RS_T4                   (1<<0)
+#define        RS_TX                   (1<<1)
+#define        RS_FX                   (1<<2)
+#define        RS_MII                  (1<<6)
+
+
+/*
+ * FIFO Status (Window 4)
+ *
+ *   Supports FIFO diagnostics
+ *
+ *   Window 4/Port 0x04.1
+ *
+ *     15:     1=RX receiving (RO). Set when a packet is being received
+ *             into the RX FIFO.
+ *     14:     Reserved
+ *     13:     1=RX underrun (RO). Generates Adapter Failure interrupt.
+ *             Requires RX Reset or Global Reset command to recover.
+ *             It is generated when you read past the end of a packet -
+ *             reading past what has been received so far will give bad
+ *             data.
+ *     12:     1=RX status overrun (RO). Set when there are already 8
+ *             packets in the RX FIFO. While this bit is set, no additional
+ *             packets are received. Requires no action on the part of
+ *             the host. The condition is cleared once a packet has been
+ *             read out of the RX FIFO.
+ *     11:     1=RX overrun (RO). Set when the RX FIFO is full (there
+ *             may not be an overrun packet yet). While this bit is set,
+ *             no additional packets will be received (some additional
+ *             bytes can still be pending between the wire and the RX
+ *             FIFO). Requires no action on the part of the host. The
+ *             condition is cleared once a few bytes have been read out
+ *             from the RX FIFO.
+ *     10:     1=TX overrun (RO). Generates adapter failure interrupt.
+ *             Requires TX Reset or Global Reset command to recover.
+ *             Disables Transmitter.
+ *     9-8:    Unassigned.
+ *     7-0:    Built in self test bits for the RX and TX FIFO's.
+ */
+#define FIFOS_RX_RECEIVING     (unsigned short) 0x8000
+#define FIFOS_RX_UNDERRUN      (unsigned short) 0x2000
+#define FIFOS_RX_STATUS_OVERRUN        (unsigned short) 0x1000
+#define FIFOS_RX_OVERRUN       (unsigned short) 0x0800
+#define FIFOS_TX_OVERRUN       (unsigned short) 0x0400
+
+/*
+ * Misc defines for various things.
+ */
+#define TAG_ADAPTER                     0xd0
+#define ACTIVATE_ADAPTER_TO_CONFIG      0xff
+#define ENABLE_DRQ_IRQ                  0x0001
+#define MFG_ID                          0x506d  /* `TCM' */
+#define PROD_ID                         0x5090
+#define GO_WINDOW(x)           outw(WINDOW_SELECT|(x),BASE+VX_COMMAND)
+#define JABBER_GUARD_ENABLE    0x40
+#define LINKBEAT_ENABLE                0x80
+#define        ENABLE_UTP              (JABBER_GUARD_ENABLE | LINKBEAT_ENABLE)
+#define DISABLE_UTP            0x0
+#define RX_BYTES_MASK          (unsigned short) (0x07ff)
+#define RX_ERROR        0x4000
+#define RX_INCOMPLETE   0x8000
+#define TX_INDICATE            1<<15
+#define is_eeprom_busy(b)      (inw((b)+VX_W0_EEPROM_COMMAND)&EEPROM_BUSY)
+
+#define        VX_IOSIZE       0x20
+
+#define VX_CONNECTORS 8
+
+/*
+ * Local variables:
+ *  c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/net/5701rls.c b/drivers/net/5701rls.c
new file mode 100644 (file)
index 0000000..86950d0
--- /dev/null
@@ -0,0 +1,46 @@
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/*                                                                            */
+/******************************************************************************/
+
+#if INCLUDE_5701_AX_FIX
+
+#include "bcm570x_mm.h"
+#include "5701rls.h"
+
+LM_STATUS LM_LoadRlsFirmware(PLM_DEVICE_BLOCK pDevice)
+{
+  T3_FWIMG_INFO FwImgInfo;
+
+  FwImgInfo.StartAddress = t3FwStartAddr;
+  FwImgInfo.Text.Buffer = (PLM_UINT8)t3FwText;
+  FwImgInfo.Text.Offset  = t3FwTextAddr;
+  FwImgInfo.Text.Length  = t3FwTextLen;
+  FwImgInfo.ROnlyData.Buffer = (PLM_UINT8)t3FwRodata;
+  FwImgInfo.ROnlyData.Offset  = t3FwRodataAddr;
+  FwImgInfo.ROnlyData.Length  = t3FwRodataLen;
+  FwImgInfo.Data.Buffer = (PLM_UINT8)t3FwData;
+  FwImgInfo.Data.Offset  = t3FwDataAddr;
+  FwImgInfo.Data.Length  = t3FwDataLen;
+
+  if (LM_LoadFirmware(pDevice,
+                     &FwImgInfo,
+                     T3_RX_CPU_ID | T3_TX_CPU_ID,
+                     T3_RX_CPU_ID) != LM_STATUS_SUCCESS)
+    {
+      return LM_STATUS_FAILURE;
+    }
+
+  return LM_STATUS_SUCCESS;
+}
+
+#endif /* INCLUDE_5701_AX_FIX */
diff --git a/drivers/net/5701rls.h b/drivers/net/5701rls.h
new file mode 100644 (file)
index 0000000..30b127a
--- /dev/null
@@ -0,0 +1,198 @@
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/******************************************************************************/
+
+typedef unsigned long U32;
+int t3FwReleaseMajor = 0x0;
+int t3FwReleaseMinor = 0x0;
+int t3FwReleaseFix = 0x0;
+U32 t3FwStartAddr = 0x08000000;
+U32 t3FwTextAddr = 0x08000000;
+int t3FwTextLen = 0x9c0;
+U32 t3FwRodataAddr = 0x080009c0;
+int t3FwRodataLen = 0x60;
+U32 t3FwDataAddr = 0x08000a40;
+int t3FwDataLen = 0x20;
+U32 t3FwSbssAddr = 0x08000a60;
+int t3FwSbssLen = 0xc;
+U32 t3FwBssAddr = 0x08000a70;
+int t3FwBssLen = 0x10;
+U32 t3FwText[(0x9c0/4) + 1] = {
+0x0,
+0x10000003, 0x0, 0xd, 0xd,
+0x3c1d0800, 0x37bd3ffc, 0x3a0f021, 0x3c100800,
+0x26100000, 0xe000018, 0x0, 0xd,
+0x3c1d0800, 0x37bd3ffc, 0x3a0f021, 0x3c100800,
+0x26100034, 0xe00021c, 0x0, 0xd,
+0x0, 0x0, 0x0, 0x27bdffe0,
+0x3c1cc000, 0xafbf0018, 0xaf80680c, 0xe00004c,
+0x241b2105, 0x97850000, 0x97870002, 0x9782002c,
+0x9783002e, 0x3c040800, 0x248409c0, 0xafa00014,
+0x21400, 0x621825, 0x52c00, 0xafa30010,
+0x8f860010, 0xe52825, 0xe000060, 0x24070102,
+0x3c02ac00, 0x34420100, 0x3c03ac01, 0x34630100,
+0xaf820490, 0x3c02ffff, 0xaf820494, 0xaf830498,
+0xaf82049c, 0x24020001, 0xaf825ce0, 0xe00003f,
+0xaf825d00, 0xe000140, 0x0, 0x8fbf0018,
+0x3e00008, 0x27bd0020, 0x2402ffff, 0xaf825404,
+0x8f835400, 0x34630400, 0xaf835400, 0xaf825404,
+0x3c020800, 0x24420034, 0xaf82541c, 0x3e00008,
+0xaf805400, 0x0, 0x0, 0x3c020800,
+0x34423000, 0x3c030800, 0x34633000, 0x3c040800,
+0x348437ff, 0x3c010800, 0xac220a64, 0x24020040,
+0x3c010800, 0xac220a68, 0x3c010800, 0xac200a60,
+0xac600000, 0x24630004, 0x83102b, 0x5040fffd,
+0xac600000, 0x3e00008, 0x0, 0x804821,
+0x8faa0010, 0x3c020800, 0x8c420a60, 0x3c040800,
+0x8c840a68, 0x8fab0014, 0x24430001, 0x44102b,
+0x3c010800, 0xac230a60, 0x14400003, 0x4021,
+0x3c010800, 0xac200a60, 0x3c020800, 0x8c420a60,
+0x3c030800, 0x8c630a64, 0x91240000, 0x21140,
+0x431021, 0x481021, 0x25080001, 0xa0440000,
+0x29020008, 0x1440fff4, 0x25290001, 0x3c020800,
+0x8c420a60, 0x3c030800, 0x8c630a64, 0x8f84680c,
+0x21140, 0x431021, 0xac440008, 0xac45000c,
+0xac460010, 0xac470014, 0xac4a0018, 0x3e00008,
+0xac4b001c, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x2000008,
+0x0, 0xa0001e3, 0x3c0a0001, 0xa0001e3,
+0x3c0a0002, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x3c0a0007, 0xa0001e3, 0x3c0a0008, 0xa0001e3,
+0x3c0a0009, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x3c0a000b, 0xa0001e3,
+0x3c0a000c, 0xa0001e3, 0x3c0a000d, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x3c0a000e, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x0, 0xa0001e3,
+0x0, 0xa0001e3, 0x3c0a0013, 0xa0001e3,
+0x3c0a0014, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x27bdffe0,
+0x1821, 0x1021, 0xafbf0018, 0xafb10014,
+0xafb00010, 0x3c010800, 0x220821, 0xac200a70,
+0x3c010800, 0x220821, 0xac200a74, 0x3c010800,
+0x220821, 0xac200a78, 0x24630001, 0x1860fff5,
+0x2442000c, 0x24110001, 0x8f906810, 0x32020004,
+0x14400005, 0x24040001, 0x3c020800, 0x8c420a78,
+0x18400003, 0x2021, 0xe000182, 0x0,
+0x32020001, 0x10400003, 0x0, 0xe000169,
+0x0, 0xa000153, 0xaf915028, 0x8fbf0018,
+0x8fb10014, 0x8fb00010, 0x3e00008, 0x27bd0020,
+0x3c050800, 0x8ca50a70, 0x3c060800, 0x8cc60a80,
+0x3c070800, 0x8ce70a78, 0x27bdffe0, 0x3c040800,
+0x248409d0, 0xafbf0018, 0xafa00010, 0xe000060,
+0xafa00014, 0xe00017b, 0x2021, 0x8fbf0018,
+0x3e00008, 0x27bd0020, 0x24020001, 0x8f836810,
+0x821004, 0x21027, 0x621824, 0x3e00008,
+0xaf836810, 0x27bdffd8, 0xafbf0024, 0x1080002e,
+0xafb00020, 0x8f825cec, 0xafa20018, 0x8f825cec,
+0x3c100800, 0x26100a78, 0xafa2001c, 0x34028000,
+0xaf825cec, 0x8e020000, 0x18400016, 0x0,
+0x3c020800, 0x94420a74, 0x8fa3001c, 0x221c0,
+0xac830004, 0x8fa2001c, 0x3c010800, 0xe000201,
+0xac220a74, 0x10400005, 0x0, 0x8e020000,
+0x24420001, 0xa0001df, 0xae020000, 0x3c020800,
+0x8c420a70, 0x21c02, 0x321c0, 0xa0001c5,
+0xafa2001c, 0xe000201, 0x0, 0x1040001f,
+0x0, 0x8e020000, 0x8fa3001c, 0x24420001,
+0x3c010800, 0xac230a70, 0x3c010800, 0xac230a74,
+0xa0001df, 0xae020000, 0x3c100800, 0x26100a78,
+0x8e020000, 0x18400028, 0x0, 0xe000201,
+0x0, 0x14400024, 0x0, 0x8e020000,
+0x3c030800, 0x8c630a70, 0x2442ffff, 0xafa3001c,
+0x18400006, 0xae020000, 0x31402, 0x221c0,
+0x8c820004, 0x3c010800, 0xac220a70, 0x97a2001e,
+0x2442ff00, 0x2c420300, 0x1440000b, 0x24024000,
+0x3c040800, 0x248409dc, 0xafa00010, 0xafa00014,
+0x8fa6001c, 0x24050008, 0xe000060, 0x3821,
+0xa0001df, 0x0, 0xaf825cf8, 0x3c020800,
+0x8c420a40, 0x8fa3001c, 0x24420001, 0xaf835cf8,
+0x3c010800, 0xac220a40, 0x8fbf0024, 0x8fb00020,
+0x3e00008, 0x27bd0028, 0x27bdffe0, 0x3c040800,
+0x248409e8, 0x2821, 0x3021, 0x3821,
+0xafbf0018, 0xafa00010, 0xe000060, 0xafa00014,
+0x8fbf0018, 0x3e00008, 0x27bd0020, 0x8f82680c,
+0x8f85680c, 0x21827, 0x3182b, 0x31823,
+0x431024, 0x441021, 0xa2282b, 0x10a00006,
+0x0, 0x401821, 0x8f82680c, 0x43102b,
+0x1440fffd, 0x0, 0x3e00008, 0x0,
+0x3c040800, 0x8c840000, 0x3c030800, 0x8c630a40,
+0x64102b, 0x54400002, 0x831023, 0x641023,
+0x2c420008, 0x3e00008, 0x38420001, 0x27bdffe0,
+0x802821, 0x3c040800, 0x24840a00, 0x3021,
+0x3821, 0xafbf0018, 0xafa00010, 0xe000060,
+0xafa00014, 0xa000216, 0x0, 0x8fbf0018,
+0x3e00008, 0x27bd0020, 0x0, 0x27bdffe0,
+0x3c1cc000, 0xafbf0018, 0xe00004c, 0xaf80680c,
+0x3c040800, 0x24840a10, 0x3802821, 0x3021,
+0x3821, 0xafa00010, 0xe000060, 0xafa00014,
+0x2402ffff, 0xaf825404, 0x3c0200aa, 0xe000234,
+0xaf825434, 0x8fbf0018, 0x3e00008, 0x27bd0020,
+0x0, 0x0, 0x0, 0x27bdffe8,
+0xafb00010, 0x24100001, 0xafbf0014, 0x3c01c003,
+0xac200000, 0x8f826810, 0x30422000, 0x10400003,
+0x0, 0xe000246, 0x0, 0xa00023a,
+0xaf905428, 0x8fbf0014, 0x8fb00010, 0x3e00008,
+0x27bd0018, 0x27bdfff8, 0x8f845d0c, 0x3c0200ff,
+0x3c030800, 0x8c630a50, 0x3442fff8, 0x821024,
+0x1043001e, 0x3c0500ff, 0x34a5fff8, 0x3c06c003,
+0x3c074000, 0x851824, 0x8c620010, 0x3c010800,
+0xac230a50, 0x30420008, 0x10400005, 0x871025,
+0x8cc20000, 0x24420001, 0xacc20000, 0x871025,
+0xaf825d0c, 0x8fa20000, 0x24420001, 0xafa20000,
+0x8fa20000, 0x8fa20000, 0x24420001, 0xafa20000,
+0x8fa20000, 0x8f845d0c, 0x3c030800, 0x8c630a50,
+0x851024, 0x1443ffe8, 0x851824, 0x27bd0008,
+0x3e00008, 0x0, 0x0, 0x0 };
+U32 t3FwRodata[(0x60/4) + 1] = {
+0x35373031, 0x726c7341, 0x0,
+0x0, 0x53774576, 0x656e7430, 0x0,
+0x726c7045, 0x76656e74, 0x31000000, 0x556e6b6e,
+0x45766e74, 0x0, 0x0, 0x0,
+0x0, 0x66617461, 0x6c457272, 0x0,
+0x0, 0x4d61696e, 0x43707542, 0x0,
+0x0, 0x0 };
+U32 t3FwData[(0x20/4) + 1] = {
+0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0,
+0x0, 0x0 };
diff --git a/drivers/net/8390.h b/drivers/net/8390.h
new file mode 100644 (file)
index 0000000..f087217
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+
+Ported to U-Boot  by Christian Pellegrin <chri@ascensit.com>
+
+Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
+eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
+are GPL, so this is, of course, GPL.
+
+*/
+
+/* Generic NS8390 register definitions. */
+/* This file is part of Donald Becker's 8390 drivers, and is distributed
+   under the same license. Auto-loading of 8390.o only in v2.2 - Paul G.
+   Some of these names and comments originated from the Crynwr
+   packet drivers, which are distributed under the GPL. */
+
+#ifndef _8390_h
+#define _8390_h
+
+/* Some generic ethernet register configurations. */
+#define E8390_TX_IRQ_MASK      0xa     /* For register EN0_ISR */
+#define E8390_RX_IRQ_MASK      0x5
+#define E8390_RXCONFIG         0x4     /* EN0_RXCR: broadcasts, no multicast,errors */
+#define E8390_RXOFF            0x20    /* EN0_RXCR: Accept no packets */
+#define E8390_TXCONFIG         0x00    /* EN0_TXCR: Normal transmit mode */
+#define E8390_TXOFF            0x02    /* EN0_TXCR: Transmitter off */
+
+/*  Register accessed at EN_CMD, the 8390 base addr.  */
+#define E8390_STOP     0x01    /* Stop and reset the chip */
+#define E8390_START    0x02    /* Start the chip, clear reset */
+#define E8390_TRANS    0x04    /* Transmit a frame */
+#define E8390_RREAD    0x08    /* Remote read */
+#define E8390_RWRITE   0x10    /* Remote write  */
+#define E8390_NODMA    0x20    /* Remote DMA */
+#define E8390_PAGE0    0x00    /* Select page chip registers */
+#define E8390_PAGE1    0x40    /* using the two high-order bits */
+#define E8390_PAGE2    0x80    /* Page 3 is invalid. */
+
+/*
+ *     Only generate indirect loads given a machine that needs them.
+ *      - removed AMIGA_PCMCIA from this list, handled as ISA io now
+ */
+
+#define n2k_inb(port)   (*((volatile unsigned char *)(port+CONFIG_DRIVER_NE2000_BASE)))
+#define n2k_outb(val,port)  (*((volatile unsigned char *)(port+CONFIG_DRIVER_NE2000_BASE)) = val)
+
+#define EI_SHIFT(x)    (x)
+
+#define E8390_CMD      EI_SHIFT(0x00)  /* The command register (for all pages) */
+/* Page 0 register offsets. */
+#define EN0_CLDALO     EI_SHIFT(0x01)  /* Low byte of current local dma addr  RD */
+#define EN0_STARTPG    EI_SHIFT(0x01)  /* Starting page of ring bfr WR */
+#define EN0_CLDAHI     EI_SHIFT(0x02)  /* High byte of current local dma addr  RD */
+#define EN0_STOPPG     EI_SHIFT(0x02)  /* Ending page +1 of ring bfr WR */
+#define EN0_BOUNDARY   EI_SHIFT(0x03)  /* Boundary page of ring bfr RD WR */
+#define EN0_TSR                EI_SHIFT(0x04)  /* Transmit status reg RD */
+#define EN0_TPSR       EI_SHIFT(0x04)  /* Transmit starting page WR */
+#define EN0_NCR                EI_SHIFT(0x05)  /* Number of collision reg RD */
+#define EN0_TCNTLO     EI_SHIFT(0x05)  /* Low  byte of tx byte count WR */
+#define EN0_FIFO       EI_SHIFT(0x06)  /* FIFO RD */
+#define EN0_TCNTHI     EI_SHIFT(0x06)  /* High byte of tx byte count WR */
+#define EN0_ISR                EI_SHIFT(0x07)  /* Interrupt status reg RD WR */
+#define EN0_CRDALO     EI_SHIFT(0x08)  /* low byte of current remote dma address RD */
+#define EN0_RSARLO     EI_SHIFT(0x08)  /* Remote start address reg 0 */
+#define EN0_CRDAHI     EI_SHIFT(0x09)  /* high byte, current remote dma address RD */
+#define EN0_RSARHI     EI_SHIFT(0x09)  /* Remote start address reg 1 */
+#define EN0_RCNTLO     EI_SHIFT(0x0a)  /* Remote byte count reg WR */
+#define EN0_RCNTHI     EI_SHIFT(0x0b)  /* Remote byte count reg WR */
+#define EN0_RSR                EI_SHIFT(0x0c)  /* rx status reg RD */
+#define EN0_RXCR       EI_SHIFT(0x0c)  /* RX configuration reg WR */
+#define EN0_TXCR       EI_SHIFT(0x0d)  /* TX configuration reg WR */
+#define EN0_COUNTER0   EI_SHIFT(0x0d)  /* Rcv alignment error counter RD */
+#define EN0_DCFG       EI_SHIFT(0x0e)  /* Data configuration reg WR */
+#define EN0_COUNTER1   EI_SHIFT(0x0e)  /* Rcv CRC error counter RD */
+#define EN0_IMR                EI_SHIFT(0x0f)  /* Interrupt mask reg WR */
+#define EN0_COUNTER2   EI_SHIFT(0x0f)  /* Rcv missed frame error counter RD */
+
+/* Bits in EN0_ISR - Interrupt status register */
+#define ENISR_RX       0x01    /* Receiver, no error */
+#define ENISR_TX       0x02    /* Transmitter, no error */
+#define ENISR_RX_ERR   0x04    /* Receiver, with error */
+#define ENISR_TX_ERR   0x08    /* Transmitter, with error */
+#define ENISR_OVER     0x10    /* Receiver overwrote the ring */
+#define ENISR_COUNTERS 0x20    /* Counters need emptying */
+#define ENISR_RDC      0x40    /* remote dma complete */
+#define ENISR_RESET    0x80    /* Reset completed */
+#define ENISR_ALL      0x3f    /* Interrupts we will enable */
+
+/* Bits in EN0_DCFG - Data config register */
+#define ENDCFG_WTS     0x01    /* word transfer mode selection */
+#define ENDCFG_BOS     0x02    /* byte order selection */
+#define ENDCFG_AUTO_INIT   0x10        /* Auto-init to remove packets from ring */
+#define ENDCFG_FIFO            0x40    /* 8 bytes */
+
+/* Page 1 register offsets. */
+#define EN1_PHYS   EI_SHIFT(0x01)      /* This board's physical enet addr RD WR */
+#define EN1_PHYS_SHIFT(i)  EI_SHIFT(i+1) /* Get and set mac address */
+#define EN1_CURPAG EI_SHIFT(0x07)      /* Current memory page RD WR */
+#define EN1_MULT   EI_SHIFT(0x08)      /* Multicast filter mask array (8 bytes) RD WR */
+#define EN1_MULT_SHIFT(i)  EI_SHIFT(8+i) /* Get and set multicast filter */
+
+/* Bits in received packet status byte and EN0_RSR*/
+#define ENRSR_RXOK     0x01    /* Received a good packet */
+#define ENRSR_CRC      0x02    /* CRC error */
+#define ENRSR_FAE      0x04    /* frame alignment error */
+#define ENRSR_FO       0x08    /* FIFO overrun */
+#define ENRSR_MPA      0x10    /* missed pkt */
+#define ENRSR_PHY      0x20    /* physical/multicast address */
+#define ENRSR_DIS      0x40    /* receiver disable. set in monitor mode */
+#define ENRSR_DEF      0x80    /* deferring */
+
+/* Transmitted packet status, EN0_TSR. */
+#define ENTSR_PTX 0x01 /* Packet transmitted without error */
+#define ENTSR_ND  0x02 /* The transmit wasn't deferred. */
+#define ENTSR_COL 0x04 /* The transmit collided at least once. */
+#define ENTSR_ABT 0x08  /* The transmit collided 16 times, and was deferred. */
+#define ENTSR_CRS 0x10 /* The carrier sense was lost. */
+#define ENTSR_FU  0x20  /* A "FIFO underrun" occurred during transmit. */
+#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */
+#define ENTSR_OWC 0x80  /* There was an out-of-window collision. */
+
+#define NIC_RECEIVE_MONITOR_MODE 0x20
+
+#endif /* _8390_h */
index 37d69b9949bd94d6a97d272f32c6cc626d8b6a99..41e1bdeb3bc227513581b66dbc3170d26e3255ce 100644 (file)
@@ -25,8 +25,39 @@ include $(TOPDIR)/config.mk
 
 LIB    := $(obj)libnet.a
 
-COBJS  := mcffec.o
+COBJS-y += 3c589.o
+COBJS-y += bcm570x.o bcm570x_autoneg.o 5701rls.o
+COBJS-y += cs8900.o
+COBJS-y += dc2114x.o
+COBJS-y += dm9000x.o
+COBJS-y += e1000.o
+COBJS-y += eepro100.o
+COBJS-y += enc28j60.o
+COBJS-y += inca-ip_sw.o
+COBJS-y += ks8695eth.o
+COBJS-y += lan91c96.o
+COBJS-y += macb.o
+COBJS-y += mcffec.o
+COBJS-y += natsemi.o
+COBJS-y += ne2000.o
+COBJS-y += netarm_eth.o
+COBJS-y += netconsole.o
+COBJS-y += ns7520_eth.o
+COBJS-y += ns8382x.o
+COBJS-y += ns9750_eth.o
+COBJS-y += pcnet.o
+COBJS-y += plb2800_eth.o
+COBJS-y += rtl8019.o
+COBJS-y += rtl8139.o
+COBJS-y += rtl8169.o
+COBJS-y += s3c4510b_eth.o
+COBJS-y += smc91111.o
+COBJS-y += tigon3.o
+COBJS-y += tsec.o
+COBJS-y += tsi108_eth.o
+COBJS-y += uli526x.o
 
+COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS))
 
diff --git a/drivers/net/bcm570x.c b/drivers/net/bcm570x.c
new file mode 100644 (file)
index 0000000..c8f4064
--- /dev/null
@@ -0,0 +1,1603 @@
+/*
+ * Broadcom BCM570x Ethernet Driver for U-Boot.
+ * Support 5701, 5702, 5703, and 5704. Single instance driver.
+ * Copyright (C) 2002 James F. Dougherty (jfd@broadcom.com)
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_CMD_NET) \
+       && (!defined(CONFIG_NET_MULTI)) && defined(CONFIG_BCM570x)
+
+#ifdef CONFIG_BMW
+#include <mpc824x.h>
+#endif
+#include <net.h>
+#include "bcm570x_mm.h"
+#include "bcm570x_autoneg.h"
+#include <pci.h>
+#include <malloc.h>
+
+/*
+ * PCI Registers and definitions.
+ */
+#define PCI_CMD_MASK   0xffff0000      /* mask to save status bits */
+#define PCI_ANY_ID (~0)
+
+/*
+ * PCI memory base for Ethernet device as well as device Interrupt.
+ */
+#define BCM570X_MBAR   0x80100000
+#define BCM570X_ILINE   1
+
+#define SECOND_USEC    1000000
+#define MAX_PACKET_SIZE 1600
+#define MAX_UNITS       4
+
+/* Globals to this module */
+int initialized = 0;
+unsigned int ioBase = 0;
+volatile PLM_DEVICE_BLOCK pDevice = NULL;      /* 570x softc */
+volatile PUM_DEVICE_BLOCK pUmDevice = NULL;
+
+/* Used to pass the full-duplex flag, etc. */
+int line_speed[MAX_UNITS] = { 0, 0, 0, 0 };
+static int full_duplex[MAX_UNITS] = { 1, 1, 1, 1 };
+static int rx_flow_control[MAX_UNITS] = { 0, 0, 0, 0 };
+static int tx_flow_control[MAX_UNITS] = { 0, 0, 0, 0 };
+static int auto_flow_control[MAX_UNITS] = { 0, 0, 0, 0 };
+static int tx_checksum[MAX_UNITS] = { 1, 1, 1, 1 };
+static int rx_checksum[MAX_UNITS] = { 1, 1, 1, 1 };
+static int auto_speed[MAX_UNITS] = { 1, 1, 1, 1 };
+
+#if JUMBO_FRAMES
+/* Jumbo MTU for interfaces. */
+static int mtu[MAX_UNITS] = { 0, 0, 0, 0 };
+#endif
+
+/* Turn on Wake-on lan for a device unit */
+static int enable_wol[MAX_UNITS] = { 0, 0, 0, 0 };
+
+#define TX_DESC_CNT DEFAULT_TX_PACKET_DESC_COUNT
+static unsigned int tx_pkt_desc_cnt[MAX_UNITS] =
+    { TX_DESC_CNT, TX_DESC_CNT, TX_DESC_CNT, TX_DESC_CNT };
+
+#define RX_DESC_CNT DEFAULT_STD_RCV_DESC_COUNT
+static unsigned int rx_std_desc_cnt[MAX_UNITS] =
+    { RX_DESC_CNT, RX_DESC_CNT, RX_DESC_CNT, RX_DESC_CNT };
+
+static unsigned int rx_adaptive_coalesce[MAX_UNITS] = { 1, 1, 1, 1 };
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+#define JBO_DESC_CNT DEFAULT_JUMBO_RCV_DESC_COUNT
+static unsigned int rx_jumbo_desc_cnt[MAX_UNITS] =
+    { JBO_DESC_CNT, JBO_DESC_CNT, JBO_DESC_CNT, JBO_DESC_CNT };
+#endif
+#define RX_COAL_TK DEFAULT_RX_COALESCING_TICKS
+static unsigned int rx_coalesce_ticks[MAX_UNITS] =
+    { RX_COAL_TK, RX_COAL_TK, RX_COAL_TK, RX_COAL_TK };
+
+#define RX_COAL_FM DEFAULT_RX_MAX_COALESCED_FRAMES
+static unsigned int rx_max_coalesce_frames[MAX_UNITS] =
+    { RX_COAL_FM, RX_COAL_FM, RX_COAL_FM, RX_COAL_FM };
+
+#define TX_COAL_TK DEFAULT_TX_COALESCING_TICKS
+static unsigned int tx_coalesce_ticks[MAX_UNITS] =
+    { TX_COAL_TK, TX_COAL_TK, TX_COAL_TK, TX_COAL_TK };
+
+#define TX_COAL_FM DEFAULT_TX_MAX_COALESCED_FRAMES
+static unsigned int tx_max_coalesce_frames[MAX_UNITS] =
+    { TX_COAL_FM, TX_COAL_FM, TX_COAL_FM, TX_COAL_FM };
+
+#define ST_COAL_TK DEFAULT_STATS_COALESCING_TICKS
+static unsigned int stats_coalesce_ticks[MAX_UNITS] =
+    { ST_COAL_TK, ST_COAL_TK, ST_COAL_TK, ST_COAL_TK };
+
+/*
+ * Legitimate values for BCM570x device types
+ */
+typedef enum {
+       BCM5700VIGIL = 0,
+       BCM5700A6,
+       BCM5700T6,
+       BCM5700A9,
+       BCM5700T9,
+       BCM5700,
+       BCM5701A5,
+       BCM5701T1,
+       BCM5701T8,
+       BCM5701A7,
+       BCM5701A10,
+       BCM5701A12,
+       BCM5701,
+       BCM5702,
+       BCM5703,
+       BCM5703A31,
+       TC996T,
+       TC996ST,
+       TC996SSX,
+       TC996SX,
+       TC996BT,
+       TC997T,
+       TC997SX,
+       TC1000T,
+       TC940BR01,
+       TC942BR01,
+       NC6770,
+       NC7760,
+       NC7770,
+       NC7780
+} board_t;
+
+/* Chip-Rev names for each device-type */
+static struct {
+       char *name;
+} chip_rev[] = {
+       {
+       "BCM5700VIGIL"}, {
+       "BCM5700A6"}, {
+       "BCM5700T6"}, {
+       "BCM5700A9"}, {
+       "BCM5700T9"}, {
+       "BCM5700"}, {
+       "BCM5701A5"}, {
+       "BCM5701T1"}, {
+       "BCM5701T8"}, {
+       "BCM5701A7"}, {
+       "BCM5701A10"}, {
+       "BCM5701A12"}, {
+       "BCM5701"}, {
+       "BCM5702"}, {
+       "BCM5703"}, {
+       "BCM5703A31"}, {
+       "TC996T"}, {
+       "TC996ST"}, {
+       "TC996SSX"}, {
+       "TC996SX"}, {
+       "TC996BT"}, {
+       "TC997T"}, {
+       "TC997SX"}, {
+       "TC1000T"}, {
+       "TC940BR01"}, {
+       "TC942BR01"}, {
+       "NC6770"}, {
+       "NC7760"}, {
+       "NC7770"}, {
+       "NC7780"}, {
+       0}
+};
+
+/* indexed by board_t, above */
+static struct {
+       char *name;
+} board_info[] = {
+       {
+       "Broadcom Vigil B5700 1000Base-T"}, {
+       "Broadcom BCM5700 1000Base-T"}, {
+       "Broadcom BCM5700 1000Base-SX"}, {
+       "Broadcom BCM5700 1000Base-SX"}, {
+       "Broadcom BCM5700 1000Base-T"}, {
+       "Broadcom BCM5700"}, {
+       "Broadcom BCM5701 1000Base-T"}, {
+       "Broadcom BCM5701 1000Base-T"}, {
+       "Broadcom BCM5701 1000Base-T"}, {
+       "Broadcom BCM5701 1000Base-SX"}, {
+       "Broadcom BCM5701 1000Base-T"}, {
+       "Broadcom BCM5701 1000Base-T"}, {
+       "Broadcom BCM5701"}, {
+       "Broadcom BCM5702 1000Base-T"}, {
+       "Broadcom BCM5703 1000Base-T"}, {
+       "Broadcom BCM5703 1000Base-SX"}, {
+       "3Com 3C996 10/100/1000 Server NIC"}, {
+       "3Com 3C996 10/100/1000 Server NIC"}, {
+       "3Com 3C996 Gigabit Fiber-SX Server NIC"}, {
+       "3Com 3C996 Gigabit Fiber-SX Server NIC"}, {
+       "3Com 3C996B Gigabit Server NIC"}, {
+       "3Com 3C997 Gigabit Server NIC"}, {
+       "3Com 3C997 Gigabit Fiber-SX Server NIC"}, {
+       "3Com 3C1000 Gigabit NIC"}, {
+       "3Com 3C940 Gigabit LOM (21X21)"}, {
+       "3Com 3C942 Gigabit LOM (31X31)"}, {
+       "Compaq NC6770 Gigabit Server Adapter"}, {
+       "Compaq NC7760 Gigabit Server Adapter"}, {
+       "Compaq NC7770 Gigabit Server Adapter"}, {
+       "Compaq NC7780 Gigabit Server Adapter"}, {
+0},};
+
+/* PCI Devices which use the 570x chipset */
+struct pci_device_table {
+       unsigned short vendor_id, device_id;    /* Vendor/DeviceID */
+       unsigned short subvendor, subdevice;    /* Subsystem ID's or PCI_ANY_ID */
+       unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */
+       unsigned long board_id; /* Data private to the driver */
+       int io_size, min_latency;
+} bcm570xDevices[] = {
+       {
+       0x14e4, 0x1644, 0x1014, 0x0277, 0, 0, BCM5700VIGIL, 128, 32}, {
+       0x14e4, 0x1644, 0x14e4, 0x1644, 0, 0, BCM5700A6, 128, 32}, {
+       0x14e4, 0x1644, 0x14e4, 0x2, 0, 0, BCM5700T6, 128, 32}, {
+       0x14e4, 0x1644, 0x14e4, 0x3, 0, 0, BCM5700A9, 128, 32}, {
+       0x14e4, 0x1644, 0x14e4, 0x4, 0, 0, BCM5700T9, 128, 32}, {
+       0x14e4, 0x1644, 0x1028, 0xd1, 0, 0, BCM5700, 128, 32}, {
+       0x14e4, 0x1644, 0x1028, 0x0106, 0, 0, BCM5700, 128, 32}, {
+       0x14e4, 0x1644, 0x1028, 0x0109, 0, 0, BCM5700, 128, 32}, {
+       0x14e4, 0x1644, 0x1028, 0x010a, 0, 0, BCM5700, 128, 32}, {
+       0x14e4, 0x1644, 0x10b7, 0x1000, 0, 0, TC996T, 128, 32}, {
+       0x14e4, 0x1644, 0x10b7, 0x1001, 0, 0, TC996ST, 128, 32}, {
+       0x14e4, 0x1644, 0x10b7, 0x1002, 0, 0, TC996SSX, 128, 32}, {
+       0x14e4, 0x1644, 0x10b7, 0x1003, 0, 0, TC997T, 128, 32}, {
+       0x14e4, 0x1644, 0x10b7, 0x1005, 0, 0, TC997SX, 128, 32}, {
+       0x14e4, 0x1644, 0x10b7, 0x1008, 0, 0, TC942BR01, 128, 32}, {
+       0x14e4, 0x1644, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5700, 128, 32}, {
+       0x14e4, 0x1645, 0x14e4, 1, 0, 0, BCM5701A5, 128, 32}, {
+       0x14e4, 0x1645, 0x14e4, 5, 0, 0, BCM5701T1, 128, 32}, {
+       0x14e4, 0x1645, 0x14e4, 6, 0, 0, BCM5701T8, 128, 32}, {
+       0x14e4, 0x1645, 0x14e4, 7, 0, 0, BCM5701A7, 128, 32}, {
+       0x14e4, 0x1645, 0x14e4, 8, 0, 0, BCM5701A10, 128, 32}, {
+       0x14e4, 0x1645, 0x14e4, 0x8008, 0, 0, BCM5701A12, 128, 32}, {
+       0x14e4, 0x1645, 0x0e11, 0xc1, 0, 0, NC6770, 128, 32}, {
+       0x14e4, 0x1645, 0x0e11, 0x7c, 0, 0, NC7770, 128, 32}, {
+       0x14e4, 0x1645, 0x0e11, 0x85, 0, 0, NC7780, 128, 32}, {
+       0x14e4, 0x1645, 0x1028, 0x0121, 0, 0, BCM5701, 128, 32}, {
+       0x14e4, 0x1645, 0x10b7, 0x1004, 0, 0, TC996SX, 128, 32}, {
+       0x14e4, 0x1645, 0x10b7, 0x1006, 0, 0, TC996BT, 128, 32}, {
+       0x14e4, 0x1645, 0x10b7, 0x1007, 0, 0, TC1000T, 128, 32}, {
+       0x14e4, 0x1645, 0x10b7, 0x1008, 0, 0, TC940BR01, 128, 32}, {
+       0x14e4, 0x1645, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5701, 128, 32}, {
+       0x14e4, 0x1646, 0x14e4, 0x8009, 0, 0, BCM5702, 128, 32}, {
+       0x14e4, 0x1646, 0x0e11, 0xbb, 0, 0, NC7760, 128, 32}, {
+       0x14e4, 0x1646, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5702, 128, 32}, {
+       0x14e4, 0x16a6, 0x14e4, 0x8009, 0, 0, BCM5702, 128, 32}, {
+       0x14e4, 0x16a6, 0x0e11, 0xbb, 0, 0, NC7760, 128, 32}, {
+       0x14e4, 0x16a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5702, 128, 32}, {
+       0x14e4, 0x1647, 0x14e4, 0x0009, 0, 0, BCM5703, 128, 32}, {
+       0x14e4, 0x1647, 0x14e4, 0x000a, 0, 0, BCM5703A31, 128, 32}, {
+       0x14e4, 0x1647, 0x14e4, 0x000b, 0, 0, BCM5703, 128, 32}, {
+       0x14e4, 0x1647, 0x14e4, 0x800a, 0, 0, BCM5703, 128, 32}, {
+       0x14e4, 0x1647, 0x0e11, 0x9a, 0, 0, NC7770, 128, 32}, {
+       0x14e4, 0x1647, 0x0e11, 0x99, 0, 0, NC7780, 128, 32}, {
+       0x14e4, 0x1647, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5703, 128, 32}, {
+       0x14e4, 0x16a7, 0x14e4, 0x0009, 0, 0, BCM5703, 128, 32}, {
+       0x14e4, 0x16a7, 0x14e4, 0x000a, 0, 0, BCM5703A31, 128, 32}, {
+       0x14e4, 0x16a7, 0x14e4, 0x000b, 0, 0, BCM5703, 128, 32}, {
+       0x14e4, 0x16a7, 0x14e4, 0x800a, 0, 0, BCM5703, 128, 32}, {
+       0x14e4, 0x16a7, 0x0e11, 0x9a, 0, 0, NC7770, 128, 32}, {
+       0x14e4, 0x16a7, 0x0e11, 0x99, 0, 0, NC7780, 128, 32}, {
+       0x14e4, 0x16a7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5703, 128, 32}
+};
+
+#define n570xDevices   (sizeof(bcm570xDevices)/sizeof(bcm570xDevices[0]))
+
+/*
+ * Allocate a packet buffer from the bcm570x packet pool.
+ */
+void *bcm570xPktAlloc (int u, int pksize)
+{
+       return malloc (pksize);
+}
+
+/*
+ * Free a packet previously allocated from the bcm570x packet
+ * buffer pool.
+ */
+void bcm570xPktFree (int u, void *p)
+{
+       free (p);
+}
+
+int bcm570xReplenishRxBuffers (PUM_DEVICE_BLOCK pUmDevice)
+{
+       PLM_PACKET pPacket;
+       PUM_PACKET pUmPacket;
+       void *skb;
+       int queue_rx = 0;
+       int ret = 0;
+
+       while ((pUmPacket = (PUM_PACKET)
+               QQ_PopHead (&pUmDevice->rx_out_of_buf_q.Container)) != 0) {
+
+               pPacket = (PLM_PACKET) pUmPacket;
+
+               /* reuse an old skb */
+               if (pUmPacket->skbuff) {
+                       QQ_PushTail (&pDevice->RxPacketFreeQ.Container,
+                                    pPacket);
+                       queue_rx = 1;
+                       continue;
+               }
+               if ((skb = bcm570xPktAlloc (pUmDevice->index,
+                                           pPacket->u.Rx.RxBufferSize + 2)) ==
+                   0) {
+                       QQ_PushHead (&pUmDevice->rx_out_of_buf_q.Container,
+                                    pPacket);
+                       printf ("NOTICE: Out of RX memory.\n");
+                       ret = 1;
+                       break;
+               }
+
+               pUmPacket->skbuff = skb;
+               QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
+               queue_rx = 1;
+       }
+
+       if (queue_rx) {
+               LM_QueueRxPackets (pDevice);
+       }
+
+       return ret;
+}
+
+/*
+ * Probe, Map, and Init 570x device.
+ */
+int eth_init (bd_t * bis)
+{
+       int i, rv, devFound = FALSE;
+       pci_dev_t devbusfn;
+       unsigned short status;
+
+       /* Find PCI device, if it exists, configure ...  */
+       for (i = 0; i < n570xDevices; i++) {
+               devbusfn = pci_find_device (bcm570xDevices[i].vendor_id,
+                                           bcm570xDevices[i].device_id, 0);
+               if (devbusfn == -1) {
+                       continue;       /* No device of that vendor/device ID */
+               } else {
+
+                       /* Set ILINE */
+                       pci_write_config_byte (devbusfn,
+                                              PCI_INTERRUPT_LINE,
+                                              BCM570X_ILINE);
+
+                       /*
+                        * 0x10 - 0x14 define one 64-bit MBAR.
+                        * 0x14 is the higher-order address bits of the BAR.
+                        */
+                       pci_write_config_dword (devbusfn,
+                                               PCI_BASE_ADDRESS_1, 0);
+
+                       ioBase = BCM570X_MBAR;
+
+                       pci_write_config_dword (devbusfn,
+                                               PCI_BASE_ADDRESS_0, ioBase);
+
+                       /*
+                        * Enable PCI memory, IO, and Master -- don't
+                        * reset any status bits in doing so.
+                        */
+                       pci_read_config_word (devbusfn, PCI_COMMAND, &status);
+
+                       status |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+
+                       pci_write_config_word (devbusfn, PCI_COMMAND, status);
+
+                       printf
+                           ("\n%s: bus %d, device %d, function %d: MBAR=0x%x\n",
+                            board_info[bcm570xDevices[i].board_id].name,
+                            PCI_BUS (devbusfn), PCI_DEV (devbusfn),
+                            PCI_FUNC (devbusfn), ioBase);
+
+                       /* Allocate once, but always clear on init */
+                       if (!pDevice) {
+                               pDevice = malloc (sizeof (UM_DEVICE_BLOCK));
+                               pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
+                               memset (pDevice, 0x0, sizeof (UM_DEVICE_BLOCK));
+                       }
+
+                       /* Configure pci dev structure */
+                       pUmDevice->pdev = devbusfn;
+                       pUmDevice->index = 0;
+                       pUmDevice->tx_pkt = 0;
+                       pUmDevice->rx_pkt = 0;
+                       devFound = TRUE;
+                       break;
+               }
+       }
+
+       if (!devFound) {
+               printf
+                   ("eth_init: FAILURE: no BCM570x Ethernet devices found.\n");
+               return -1;
+       }
+
+       /* Setup defaults for chip */
+       pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;
+
+       if (pDevice->ChipRevId == T3_CHIP_ID_5700_B0) {
+               pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;
+       } else {
+
+               if (rx_checksum[i]) {
+                       pDevice->TaskToOffload |=
+                           LM_TASK_OFFLOAD_RX_TCP_CHECKSUM |
+                           LM_TASK_OFFLOAD_RX_UDP_CHECKSUM;
+               }
+
+               if (tx_checksum[i]) {
+                       pDevice->TaskToOffload |=
+                           LM_TASK_OFFLOAD_TX_TCP_CHECKSUM |
+                           LM_TASK_OFFLOAD_TX_UDP_CHECKSUM;
+                       pDevice->NoTxPseudoHdrChksum = TRUE;
+               }
+       }
+
+       /* Set Device PCI Memory base address */
+       pDevice->pMappedMemBase = (PLM_UINT8) ioBase;
+
+       /* Pull down adapter info */
+       if ((rv = LM_GetAdapterInfo (pDevice)) != LM_STATUS_SUCCESS) {
+               printf ("bcm570xEnd: LM_GetAdapterInfo failed: rv=%d!\n", rv);
+               return -2;
+       }
+
+       /* Lock not needed */
+       pUmDevice->do_global_lock = 0;
+
+       if (T3_ASIC_REV (pUmDevice->lm_dev.ChipRevId) == T3_ASIC_REV_5700) {
+               /* The 5700 chip works best without interleaved register */
+               /* accesses on certain machines. */
+               pUmDevice->do_global_lock = 1;
+       }
+
+       /* Setup timer delays */
+       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
+               pDevice->UseTaggedStatus = TRUE;
+               pUmDevice->timer_interval = CFG_HZ;
+       } else {
+               pUmDevice->timer_interval = CFG_HZ / 50;
+       }
+
+       /* Grab name .... */
+       pUmDevice->name =
+           (char *)malloc (strlen (board_info[bcm570xDevices[i].board_id].name)
+                           + 1);
+       strcpy (pUmDevice->name, board_info[bcm570xDevices[i].board_id].name);
+
+       memcpy (pDevice->NodeAddress, bis->bi_enetaddr, 6);
+       LM_SetMacAddress (pDevice, bis->bi_enetaddr);
+       /* Init queues  .. */
+       QQ_InitQueue (&pUmDevice->rx_out_of_buf_q.Container,
+                     MAX_RX_PACKET_DESC_COUNT);
+       pUmDevice->rx_last_cnt = pUmDevice->tx_last_cnt = 0;
+
+       /* delay for 4 seconds */
+       pUmDevice->delayed_link_ind = (4 * CFG_HZ) / pUmDevice->timer_interval;
+
+       pUmDevice->adaptive_expiry = CFG_HZ / pUmDevice->timer_interval;
+
+       /* Sometimes we get spurious ints. after reset when link is down. */
+       /* This field tells the isr to service the int. even if there is */
+       /* no status block update. */
+       pUmDevice->adapter_just_inited =
+           (3 * CFG_HZ) / pUmDevice->timer_interval;
+
+       /* Initialize 570x */
+       if (LM_InitializeAdapter (pDevice) != LM_STATUS_SUCCESS) {
+               printf ("ERROR: Adapter initialization failed.\n");
+               return ERROR;
+       }
+
+       /* Enable chip ISR */
+       LM_EnableInterrupt (pDevice);
+
+       /* Clear MC table */
+       LM_MulticastClear (pDevice);
+
+       /* Enable Multicast */
+       LM_SetReceiveMask (pDevice,
+                          pDevice->ReceiveMask | LM_ACCEPT_ALL_MULTICAST);
+
+       pUmDevice->opened = 1;
+       pUmDevice->tx_full = 0;
+       pUmDevice->tx_pkt = 0;
+       pUmDevice->rx_pkt = 0;
+       printf ("eth%d: %s @0x%lx,",
+               pDevice->index, pUmDevice->name, (unsigned long)ioBase);
+       printf ("node addr ");
+       for (i = 0; i < 6; i++) {
+               printf ("%2.2x", pDevice->NodeAddress[i]);
+       }
+       printf ("\n");
+
+       printf ("eth%d: ", pDevice->index);
+       printf ("%s with ", chip_rev[bcm570xDevices[i].board_id].name);
+
+       if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5400_PHY_ID)
+               printf ("Broadcom BCM5400 Copper ");
+       else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
+               printf ("Broadcom BCM5401 Copper ");
+       else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5411_PHY_ID)
+               printf ("Broadcom BCM5411 Copper ");
+       else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5701_PHY_ID)
+               printf ("Broadcom BCM5701 Integrated Copper ");
+       else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5703_PHY_ID)
+               printf ("Broadcom BCM5703 Integrated Copper ");
+       else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM8002_PHY_ID)
+               printf ("Broadcom BCM8002 SerDes ");
+       else if (pDevice->EnableTbi)
+               printf ("Agilent HDMP-1636 SerDes ");
+       else
+               printf ("Unknown ");
+       printf ("transceiver found\n");
+
+       printf ("eth%d: %s, MTU: %d,",
+               pDevice->index, pDevice->BusSpeedStr, 1500);
+
+       if ((pDevice->ChipRevId != T3_CHIP_ID_5700_B0) && rx_checksum[i])
+               printf ("Rx Checksum ON\n");
+       else
+               printf ("Rx Checksum OFF\n");
+       initialized++;
+
+       return 0;
+}
+
+/* Ethernet Interrupt service routine */
+void eth_isr (void)
+{
+       LM_UINT32 oldtag, newtag;
+       int i;
+
+       pUmDevice->interrupt = 1;
+
+       if (pDevice->UseTaggedStatus) {
+               if ((pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_UPDATED) ||
+                   pUmDevice->adapter_just_inited) {
+                       MB_REG_WR (pDevice, Mailbox.Interrupt[0].Low, 1);
+                       oldtag = pDevice->pStatusBlkVirt->StatusTag;
+
+                       for (i = 0;; i++) {
+                               pDevice->pStatusBlkVirt->Status &=
+                                   ~STATUS_BLOCK_UPDATED;
+                               LM_ServiceInterrupts (pDevice);
+                               newtag = pDevice->pStatusBlkVirt->StatusTag;
+                               if ((newtag == oldtag) || (i > 50)) {
+                                       MB_REG_WR (pDevice,
+                                                  Mailbox.Interrupt[0].Low,
+                                                  newtag << 24);
+                                       if (pDevice->UndiFix) {
+                                               REG_WR (pDevice, Grc.LocalCtrl,
+                                                       pDevice->
+                                                       GrcLocalCtrl | 0x2);
+                                       }
+                                       break;
+                               }
+                               oldtag = newtag;
+                       }
+               }
+       } else {
+               while (pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_UPDATED) {
+                       unsigned int dummy;
+
+                       pDevice->pMemView->Mailbox.Interrupt[0].Low = 1;
+                       pDevice->pStatusBlkVirt->Status &=
+                           ~STATUS_BLOCK_UPDATED;
+                       LM_ServiceInterrupts (pDevice);
+                       pDevice->pMemView->Mailbox.Interrupt[0].Low = 0;
+                       dummy = pDevice->pMemView->Mailbox.Interrupt[0].Low;
+               }
+       }
+
+       /* Allocate new RX buffers */
+       if (QQ_GetEntryCnt (&pUmDevice->rx_out_of_buf_q.Container)) {
+               bcm570xReplenishRxBuffers (pUmDevice);
+       }
+
+       /* Queue packets */
+       if (QQ_GetEntryCnt (&pDevice->RxPacketFreeQ.Container)) {
+               LM_QueueRxPackets (pDevice);
+       }
+
+       if (pUmDevice->tx_queued) {
+               pUmDevice->tx_queued = 0;
+       }
+
+       if (pUmDevice->tx_full) {
+               if (pDevice->LinkStatus != LM_STATUS_LINK_DOWN) {
+                       printf
+                           ("NOTICE: tx was previously blocked, restarting MUX\n");
+                       pUmDevice->tx_full = 0;
+               }
+       }
+
+       pUmDevice->interrupt = 0;
+
+}
+
+int eth_send (volatile void *packet, int length)
+{
+       int status = 0;
+#if ET_DEBUG
+       unsigned char *ptr = (unsigned char *)packet;
+#endif
+       PLM_PACKET pPacket;
+       PUM_PACKET pUmPacket;
+
+       /* Link down, return */
+       while (pDevice->LinkStatus == LM_STATUS_LINK_DOWN) {
+#if 0
+               printf ("eth%d: link down - check cable or link partner.\n",
+                       pUmDevice->index);
+#endif
+               eth_isr ();
+
+               /* Wait to see link for one-half a second before sending ... */
+               udelay (1500000);
+
+       }
+
+       /* Clear sent flag */
+       pUmDevice->tx_pkt = 0;
+
+       /* Previously blocked */
+       if (pUmDevice->tx_full) {
+               printf ("eth%d: tx blocked.\n", pUmDevice->index);
+               return 0;
+       }
+
+       pPacket = (PLM_PACKET)
+           QQ_PopHead (&pDevice->TxPacketFreeQ.Container);
+
+       if (pPacket == 0) {
+               pUmDevice->tx_full = 1;
+               printf ("bcm570xEndSend: TX full!\n");
+               return 0;
+       }
+
+       if (pDevice->SendBdLeft.counter == 0) {
+               pUmDevice->tx_full = 1;
+               printf ("bcm570xEndSend: no more TX descriptors!\n");
+               QQ_PushHead (&pDevice->TxPacketFreeQ.Container, pPacket);
+               return 0;
+       }
+
+       if (length <= 0) {
+               printf ("eth: bad packet size: %d\n", length);
+               goto out;
+       }
+
+       /* Get packet buffers and fragment list */
+       pUmPacket = (PUM_PACKET) pPacket;
+       /* Single DMA Descriptor transmit.
+        * Fragments may be provided, but one DMA descriptor max is
+        * used to send the packet.
+        */
+       if (MM_CoalesceTxBuffer (pDevice, pPacket) != LM_STATUS_SUCCESS) {
+               if (pUmPacket->skbuff == NULL) {
+                       /* Packet was discarded */
+                       printf ("TX: failed (1)\n");
+                       status = 1;
+               } else {
+                       printf ("TX: failed (2)\n");
+                       status = 2;
+               }
+               QQ_PushHead (&pDevice->TxPacketFreeQ.Container, pPacket);
+               return status;
+       }
+
+       /* Copy packet to DMA buffer */
+       memset (pUmPacket->skbuff, 0x0, MAX_PACKET_SIZE);
+       memcpy ((void *)pUmPacket->skbuff, (void *)packet, length);
+       pPacket->PacketSize = length;
+       pPacket->Flags |= SND_BD_FLAG_END | SND_BD_FLAG_COAL_NOW;
+       pPacket->u.Tx.FragCount = 1;
+       /* We've already provided a frame ready for transmission */
+       pPacket->Flags &= ~SND_BD_FLAG_TCP_UDP_CKSUM;
+
+       if (LM_SendPacket (pDevice, pPacket) == LM_STATUS_FAILURE) {
+               /*
+                *  A lower level send failure will push the packet descriptor back
+                *  in the free queue, so just deal with the VxWorks clusters.
+                */
+               if (pUmPacket->skbuff == NULL) {
+                       printf ("TX failed (1)!\n");
+                       /* Packet was discarded */
+                       status = 3;
+               } else {
+                       /* A resource problem ... */
+                       printf ("TX failed (2)!\n");
+                       status = 4;
+               }
+
+               if (QQ_GetEntryCnt (&pDevice->TxPacketFreeQ.Container) == 0) {
+                       printf ("TX: emptyQ!\n");
+                       pUmDevice->tx_full = 1;
+               }
+       }
+
+       while (pUmDevice->tx_pkt == 0) {
+               /* Service TX */
+               eth_isr ();
+       }
+#if ET_DEBUG
+       printf ("eth_send: 0x%x, %d bytes\n"
+               "[%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x] ...\n",
+               (int)pPacket, length,
+               ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5],
+               ptr[6], ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12],
+               ptr[13], ptr[14], ptr[15]);
+#endif
+       pUmDevice->tx_pkt = 0;
+       QQ_PushHead (&pDevice->TxPacketFreeQ.Container, pPacket);
+
+       /* Done with send */
+      out:
+       return status;
+}
+
+/* Ethernet receive */
+int eth_rx (void)
+{
+       PLM_PACKET pPacket = NULL;
+       PUM_PACKET pUmPacket = NULL;
+       void *skb;
+       int size = 0;
+
+       while (TRUE) {
+
+             bcm570x_service_isr:
+               /* Pull down packet if it is there */
+               eth_isr ();
+
+               /* Indicate RX packets called */
+               if (pUmDevice->rx_pkt) {
+                       /* printf("eth_rx: got a packet...\n"); */
+                       pUmDevice->rx_pkt = 0;
+               } else {
+                       /* printf("eth_rx: waiting for packet...\n"); */
+                       goto bcm570x_service_isr;
+               }
+
+               pPacket = (PLM_PACKET)
+                   QQ_PopHead (&pDevice->RxPacketReceivedQ.Container);
+
+               if (pPacket == 0) {
+                       printf ("eth_rx: empty packet!\n");
+                       goto bcm570x_service_isr;
+               }
+
+               pUmPacket = (PUM_PACKET) pPacket;
+#if ET_DEBUG
+               printf ("eth_rx: packet @0x%x\n", (int)pPacket);
+#endif
+               /* If the packet generated an error, reuse buffer */
+               if ((pPacket->PacketStatus != LM_STATUS_SUCCESS) ||
+                   ((size = pPacket->PacketSize) > pDevice->RxMtu)) {
+
+                       /* reuse skb */
+                       QQ_PushTail (&pDevice->RxPacketFreeQ.Container,
+                                    pPacket);
+                       printf ("eth_rx: error in packet dma!\n");
+                       goto bcm570x_service_isr;
+               }
+
+               /* Set size and address */
+               skb = pUmPacket->skbuff;
+               size = pPacket->PacketSize;
+
+               /* Pass the packet up to the protocol
+                * layers.
+                */
+               NetReceive (skb, size);
+
+               /* Free packet buffer */
+               bcm570xPktFree (pUmDevice->index, skb);
+               pUmPacket->skbuff = NULL;
+
+               /* Reuse SKB */
+               QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
+
+               return 0;       /* Got a packet, bail ... */
+       }
+       return size;
+}
+
+/* Shut down device */
+void eth_halt (void)
+{
+       int i;
+       if (initialized)
+               if (pDevice && pUmDevice && pUmDevice->opened) {
+                       printf ("\neth%d:%s,", pUmDevice->index,
+                               pUmDevice->name);
+                       printf ("HALT,");
+                       /* stop device */
+                       LM_Halt (pDevice);
+                       printf ("POWER DOWN,");
+                       LM_SetPowerState (pDevice, LM_POWER_STATE_D3);
+
+                       /* Free the memory allocated by the device in tigon3 */
+                       for (i = 0; i < pUmDevice->mem_list_num; i++) {
+                               if (pUmDevice->mem_list[i]) {
+                                       /* sanity check */
+                                       if (pUmDevice->dma_list[i]) {   /* cache-safe memory */
+                                               free (pUmDevice->mem_list[i]);
+                                       } else {
+                                               free (pUmDevice->mem_list[i]);  /* normal memory   */
+                                       }
+                               }
+                       }
+                       pUmDevice->opened = 0;
+                       free (pDevice);
+                       pDevice = NULL;
+                       pUmDevice = NULL;
+                       initialized = 0;
+                       printf ("done - offline.\n");
+               }
+}
+
+/*
+ *
+ * Middle Module: Interface between the HW driver (tigon3 modules) and
+ * the native (SENS) driver.  These routines implement the system
+ * interface for tigon3 on VxWorks.
+ */
+
+/* Middle module dependency - size of a packet descriptor */
+int MM_Packet_Desc_Size = sizeof (UM_PACKET);
+
+LM_STATUS
+MM_ReadConfig32 (PLM_DEVICE_BLOCK pDevice,
+                LM_UINT32 Offset, LM_UINT32 * pValue32)
+{
+       UM_DEVICE_BLOCK *pUmDevice;
+       pUmDevice = (UM_DEVICE_BLOCK *) pDevice;
+       pci_read_config_dword (pUmDevice->pdev, Offset, (u32 *) pValue32);
+       return LM_STATUS_SUCCESS;
+}
+
+LM_STATUS
+MM_WriteConfig32 (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, LM_UINT32 Value32)
+{
+       UM_DEVICE_BLOCK *pUmDevice;
+       pUmDevice = (UM_DEVICE_BLOCK *) pDevice;
+       pci_write_config_dword (pUmDevice->pdev, Offset, Value32);
+       return LM_STATUS_SUCCESS;
+}
+
+LM_STATUS
+MM_ReadConfig16 (PLM_DEVICE_BLOCK pDevice,
+                LM_UINT32 Offset, LM_UINT16 * pValue16)
+{
+       UM_DEVICE_BLOCK *pUmDevice;
+       pUmDevice = (UM_DEVICE_BLOCK *) pDevice;
+       pci_read_config_word (pUmDevice->pdev, Offset, (u16 *) pValue16);
+       return LM_STATUS_SUCCESS;
+}
+
+LM_STATUS
+MM_WriteConfig16 (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, LM_UINT16 Value16)
+{
+       UM_DEVICE_BLOCK *pUmDevice;
+       pUmDevice = (UM_DEVICE_BLOCK *) pDevice;
+       pci_write_config_word (pUmDevice->pdev, Offset, Value16);
+       return LM_STATUS_SUCCESS;
+}
+
+LM_STATUS
+MM_AllocateSharedMemory (PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
+                        PLM_VOID * pMemoryBlockVirt,
+                        PLM_PHYSICAL_ADDRESS pMemoryBlockPhy, LM_BOOL Cached)
+{
+       PLM_VOID pvirt;
+       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
+       dma_addr_t mapping;
+
+       pvirt = malloc (BlockSize);
+       mapping = (dma_addr_t) (pvirt);
+       if (!pvirt)
+               return LM_STATUS_FAILURE;
+
+       pUmDevice->mem_list[pUmDevice->mem_list_num] = pvirt;
+       pUmDevice->dma_list[pUmDevice->mem_list_num] = mapping;
+       pUmDevice->mem_size_list[pUmDevice->mem_list_num++] = BlockSize;
+       memset (pvirt, 0, BlockSize);
+
+       *pMemoryBlockVirt = (PLM_VOID) pvirt;
+       MM_SetAddr (pMemoryBlockPhy, (dma_addr_t) mapping);
+
+       return LM_STATUS_SUCCESS;
+}
+
+LM_STATUS
+MM_AllocateMemory (PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
+                  PLM_VOID * pMemoryBlockVirt)
+{
+       PLM_VOID pvirt;
+       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
+
+       pvirt = malloc (BlockSize);
+
+       if (!pvirt)
+               return LM_STATUS_FAILURE;
+
+       pUmDevice->mem_list[pUmDevice->mem_list_num] = pvirt;
+       pUmDevice->dma_list[pUmDevice->mem_list_num] = 0;
+       pUmDevice->mem_size_list[pUmDevice->mem_list_num++] = BlockSize;
+       memset (pvirt, 0, BlockSize);
+       *pMemoryBlockVirt = pvirt;
+
+       return LM_STATUS_SUCCESS;
+}
+
+LM_STATUS MM_MapMemBase (PLM_DEVICE_BLOCK pDevice)
+{
+       printf ("BCM570x PCI Memory base address @0x%x\n",
+               (unsigned int)pDevice->pMappedMemBase);
+       return LM_STATUS_SUCCESS;
+}
+
+LM_STATUS MM_InitializeUmPackets (PLM_DEVICE_BLOCK pDevice)
+{
+       int i;
+       void *skb;
+       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
+       PUM_PACKET pUmPacket = NULL;
+       PLM_PACKET pPacket = NULL;
+
+       for (i = 0; i < pDevice->RxPacketDescCnt; i++) {
+               pPacket = QQ_PopHead (&pDevice->RxPacketFreeQ.Container);
+               pUmPacket = (PUM_PACKET) pPacket;
+
+               if (pPacket == 0) {
+                       printf ("MM_InitializeUmPackets: Bad RxPacketFreeQ\n");
+               }
+
+               skb = bcm570xPktAlloc (pUmDevice->index,
+                                      pPacket->u.Rx.RxBufferSize + 2);
+
+               if (skb == 0) {
+                       pUmPacket->skbuff = 0;
+                       QQ_PushTail (&pUmDevice->rx_out_of_buf_q.Container,
+                                    pPacket);
+                       printf ("MM_InitializeUmPackets: out of buffer.\n");
+                       continue;
+               }
+
+               pUmPacket->skbuff = skb;
+               QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
+       }
+
+       pUmDevice->rx_low_buf_thresh = pDevice->RxPacketDescCnt / 8;
+
+       return LM_STATUS_SUCCESS;
+}
+
+LM_STATUS MM_GetConfig (PLM_DEVICE_BLOCK pDevice)
+{
+       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
+       int index = pDevice->index;
+
+       if (auto_speed[index] == 0)
+               pDevice->DisableAutoNeg = TRUE;
+       else
+               pDevice->DisableAutoNeg = FALSE;
+
+       if (line_speed[index] == 0) {
+               pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_AUTO;
+               pDevice->DisableAutoNeg = FALSE;
+       } else {
+               if (line_speed[index] == 1000) {
+                       if (pDevice->EnableTbi) {
+                               pDevice->RequestedMediaType =
+                                   LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS_FULL_DUPLEX;
+                       } else if (full_duplex[index]) {
+                               pDevice->RequestedMediaType =
+                                   LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS_FULL_DUPLEX;
+                       } else {
+                               pDevice->RequestedMediaType =
+                                   LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS;
+                       }
+                       if (!pDevice->EnableTbi)
+                               pDevice->DisableAutoNeg = FALSE;
+               } else if (line_speed[index] == 100) {
+                       if (full_duplex[index]) {
+                               pDevice->RequestedMediaType =
+                                   LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS_FULL_DUPLEX;
+                       } else {
+                               pDevice->RequestedMediaType =
+                                   LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS;
+                       }
+               } else if (line_speed[index] == 10) {
+                       if (full_duplex[index]) {
+                               pDevice->RequestedMediaType =
+                                   LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS_FULL_DUPLEX;
+                       } else {
+                               pDevice->RequestedMediaType =
+                                   LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS;
+                       }
+               } else {
+                       pDevice->RequestedMediaType =
+                           LM_REQUESTED_MEDIA_TYPE_AUTO;
+                       pDevice->DisableAutoNeg = FALSE;
+               }
+
+       }
+       pDevice->FlowControlCap = 0;
+       if (rx_flow_control[index] != 0) {
+               pDevice->FlowControlCap |= LM_FLOW_CONTROL_RECEIVE_PAUSE;
+       }
+       if (tx_flow_control[index] != 0) {
+               pDevice->FlowControlCap |= LM_FLOW_CONTROL_TRANSMIT_PAUSE;
+       }
+       if ((auto_flow_control[index] != 0) &&
+           (pDevice->DisableAutoNeg == FALSE)) {
+
+               pDevice->FlowControlCap |= LM_FLOW_CONTROL_AUTO_PAUSE;
+               if ((tx_flow_control[index] == 0) &&
+                   (rx_flow_control[index] == 0)) {
+                       pDevice->FlowControlCap |=
+                           LM_FLOW_CONTROL_TRANSMIT_PAUSE |
+                           LM_FLOW_CONTROL_RECEIVE_PAUSE;
+               }
+       }
+
+       /* Default MTU for now */
+       pUmDevice->mtu = 1500;
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+       if (pUmDevice->mtu > 1500) {
+               pDevice->RxMtu = pUmDevice->mtu;
+               pDevice->RxJumboDescCnt = DEFAULT_JUMBO_RCV_DESC_COUNT;
+       } else {
+               pDevice->RxJumboDescCnt = 0;
+       }
+       pDevice->RxJumboDescCnt = rx_jumbo_desc_cnt[index];
+#else
+       pDevice->RxMtu = pUmDevice->mtu;
+#endif
+
+       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
+               pDevice->UseTaggedStatus = TRUE;
+               pUmDevice->timer_interval = CFG_HZ;
+       } else {
+               pUmDevice->timer_interval = CFG_HZ / 50;
+       }
+
+       pDevice->TxPacketDescCnt = tx_pkt_desc_cnt[index];
+       pDevice->RxStdDescCnt = rx_std_desc_cnt[index];
+       /* Note:  adaptive coalescence really isn't adaptive in this driver */
+       pUmDevice->rx_adaptive_coalesce = rx_adaptive_coalesce[index];
+       if (!pUmDevice->rx_adaptive_coalesce) {
+               pDevice->RxCoalescingTicks = rx_coalesce_ticks[index];
+               if (pDevice->RxCoalescingTicks > MAX_RX_COALESCING_TICKS)
+                       pDevice->RxCoalescingTicks = MAX_RX_COALESCING_TICKS;
+               pUmDevice->rx_curr_coalesce_ticks = pDevice->RxCoalescingTicks;
+
+               pDevice->RxMaxCoalescedFrames = rx_max_coalesce_frames[index];
+               if (pDevice->RxMaxCoalescedFrames > MAX_RX_MAX_COALESCED_FRAMES)
+                       pDevice->RxMaxCoalescedFrames =
+                           MAX_RX_MAX_COALESCED_FRAMES;
+               pUmDevice->rx_curr_coalesce_frames =
+                   pDevice->RxMaxCoalescedFrames;
+               pDevice->StatsCoalescingTicks = stats_coalesce_ticks[index];
+               if (pDevice->StatsCoalescingTicks > MAX_STATS_COALESCING_TICKS)
+                       pDevice->StatsCoalescingTicks =
+                           MAX_STATS_COALESCING_TICKS;
+       } else {
+               pUmDevice->rx_curr_coalesce_frames =
+                   DEFAULT_RX_MAX_COALESCED_FRAMES;
+               pUmDevice->rx_curr_coalesce_ticks = DEFAULT_RX_COALESCING_TICKS;
+       }
+       pDevice->TxCoalescingTicks = tx_coalesce_ticks[index];
+       if (pDevice->TxCoalescingTicks > MAX_TX_COALESCING_TICKS)
+               pDevice->TxCoalescingTicks = MAX_TX_COALESCING_TICKS;
+       pDevice->TxMaxCoalescedFrames = tx_max_coalesce_frames[index];
+       if (pDevice->TxMaxCoalescedFrames > MAX_TX_MAX_COALESCED_FRAMES)
+               pDevice->TxMaxCoalescedFrames = MAX_TX_MAX_COALESCED_FRAMES;
+
+       if (enable_wol[index]) {
+               pDevice->WakeUpModeCap = LM_WAKE_UP_MODE_MAGIC_PACKET;
+               pDevice->WakeUpMode = LM_WAKE_UP_MODE_MAGIC_PACKET;
+       }
+       pDevice->NicSendBd = TRUE;
+
+       /* Don't update status blocks during interrupt */
+       pDevice->RxCoalescingTicksDuringInt = 0;
+       pDevice->TxCoalescingTicksDuringInt = 0;
+
+       return LM_STATUS_SUCCESS;
+
+}
+
+LM_STATUS MM_StartTxDma (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
+{
+       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
+       printf ("Start TX DMA: dev=%d packet @0x%x\n",
+               (int)pUmDevice->index, (unsigned int)pPacket);
+
+       return LM_STATUS_SUCCESS;
+}
+
+LM_STATUS MM_CompleteTxDma (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
+{
+       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
+       printf ("Complete TX DMA: dev=%d packet @0x%x\n",
+               (int)pUmDevice->index, (unsigned int)pPacket);
+       return LM_STATUS_SUCCESS;
+}
+
+LM_STATUS MM_IndicateStatus (PLM_DEVICE_BLOCK pDevice, LM_STATUS Status)
+{
+       char buf[128];
+       char lcd[4];
+       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
+       LM_FLOW_CONTROL flow_control;
+
+       pUmDevice->delayed_link_ind = 0;
+       memset (lcd, 0x0, 4);
+
+       if (Status == LM_STATUS_LINK_DOWN) {
+               sprintf (buf, "eth%d: %s: NIC Link is down\n",
+                        pUmDevice->index, pUmDevice->name);
+               lcd[0] = 'L';
+               lcd[1] = 'N';
+               lcd[2] = 'K';
+               lcd[3] = '?';
+       } else if (Status == LM_STATUS_LINK_ACTIVE) {
+               sprintf (buf, "eth%d:%s: ", pUmDevice->index, pUmDevice->name);
+
+               if (pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) {
+                       strcat (buf, "1000 Mbps ");
+                       lcd[0] = '1';
+                       lcd[1] = 'G';
+                       lcd[2] = 'B';
+               } else if (pDevice->LineSpeed == LM_LINE_SPEED_100MBPS) {
+                       strcat (buf, "100 Mbps ");
+                       lcd[0] = '1';
+                       lcd[1] = '0';
+                       lcd[2] = '0';
+               } else if (pDevice->LineSpeed == LM_LINE_SPEED_10MBPS) {
+                       strcat (buf, "10 Mbps ");
+                       lcd[0] = '1';
+                       lcd[1] = '0';
+                       lcd[2] = ' ';
+               }
+               if (pDevice->DuplexMode == LM_DUPLEX_MODE_FULL) {
+                       strcat (buf, "full duplex");
+                       lcd[3] = 'F';
+               } else {
+                       strcat (buf, "half duplex");
+                       lcd[3] = 'H';
+               }
+               strcat (buf, " link up");
+
+               flow_control = pDevice->FlowControl &
+                   (LM_FLOW_CONTROL_RECEIVE_PAUSE |
+                    LM_FLOW_CONTROL_TRANSMIT_PAUSE);
+
+               if (flow_control) {
+                       if (flow_control & LM_FLOW_CONTROL_RECEIVE_PAUSE) {
+                               strcat (buf, ", receive ");
+                               if (flow_control &
+                                   LM_FLOW_CONTROL_TRANSMIT_PAUSE)
+                                       strcat (buf, " & transmit ");
+                       } else {
+                               strcat (buf, ", transmit ");
+                       }
+                       strcat (buf, "flow control ON");
+               } else {
+                       strcat (buf, ", flow control OFF");
+               }
+               strcat (buf, "\n");
+               printf ("%s", buf);
+       }
+#if 0
+       sysLedDsply (lcd[0], lcd[1], lcd[2], lcd[3]);
+#endif
+       return LM_STATUS_SUCCESS;
+}
+
+LM_STATUS MM_FreeRxBuffer (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
+{
+
+       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
+       PUM_PACKET pUmPacket;
+       void *skb;
+
+       pUmPacket = (PUM_PACKET) pPacket;
+
+       if ((skb = pUmPacket->skbuff))
+               bcm570xPktFree (pUmDevice->index, skb);
+
+       pUmPacket->skbuff = 0;
+
+       return LM_STATUS_SUCCESS;
+}
+
+unsigned long MM_AnGetCurrentTime_us (PAN_STATE_INFO pAnInfo)
+{
+       return get_timer (0);
+}
+
+/*
+ *   Transform an MBUF chain into a single MBUF.
+ *   This routine will fail if the amount of data in the
+ *   chain overflows a transmit buffer.  In that case,
+ *   the incoming MBUF chain will be freed.  This routine can
+ *   also fail by not being able to allocate a new MBUF (including
+ *   cluster and mbuf headers).  In that case the failure is
+ *   non-fatal.  The incoming cluster chain is not freed, giving
+ *   the caller the choice of whether to try a retransmit later.
+ */
+LM_STATUS MM_CoalesceTxBuffer (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
+{
+       PUM_PACKET pUmPacket = (PUM_PACKET) pPacket;
+       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
+       void *skbnew;
+       int len = 0;
+
+       if (len == 0)
+               return (LM_STATUS_SUCCESS);
+
+       if (len > MAX_PACKET_SIZE) {
+               printf ("eth%d: xmit frame discarded, too big!, size = %d\n",
+                       pUmDevice->index, len);
+               return (LM_STATUS_FAILURE);
+       }
+
+       skbnew = bcm570xPktAlloc (pUmDevice->index, MAX_PACKET_SIZE);
+
+       if (skbnew == NULL) {
+               pUmDevice->tx_full = 1;
+               printf ("eth%d: out of transmit buffers", pUmDevice->index);
+               return (LM_STATUS_FAILURE);
+       }
+
+       /* New packet values */
+       pUmPacket->skbuff = skbnew;
+       pUmPacket->lm_packet.u.Tx.FragCount = 1;
+
+       return (LM_STATUS_SUCCESS);
+}
+
+LM_STATUS MM_IndicateRxPackets (PLM_DEVICE_BLOCK pDevice)
+{
+       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
+       pUmDevice->rx_pkt = 1;
+       return LM_STATUS_SUCCESS;
+}
+
+LM_STATUS MM_IndicateTxPackets (PLM_DEVICE_BLOCK pDevice)
+{
+       PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice;
+       PLM_PACKET pPacket;
+       PUM_PACKET pUmPacket;
+       void *skb;
+       while (TRUE) {
+
+               pPacket = (PLM_PACKET)
+                   QQ_PopHead (&pDevice->TxPacketXmittedQ.Container);
+
+               if (pPacket == 0)
+                       break;
+
+               pUmPacket = (PUM_PACKET) pPacket;
+               skb = (void *)pUmPacket->skbuff;
+
+               /*
+                * Free MBLK if we transmitted a fragmented packet or a
+                * non-fragmented packet straight from the VxWorks
+                * buffer pool. If packet was copied to a local transmit
+                * buffer, then there's no MBUF to free, just free
+                * the transmit buffer back to the cluster pool.
+                */
+
+               if (skb)
+                       bcm570xPktFree (pUmDevice->index, skb);
+
+               pUmPacket->skbuff = 0;
+               QQ_PushTail (&pDevice->TxPacketFreeQ.Container, pPacket);
+               pUmDevice->tx_pkt = 1;
+       }
+       if (pUmDevice->tx_full) {
+               if (QQ_GetEntryCnt (&pDevice->TxPacketFreeQ.Container) >=
+                   (QQ_GetSize (&pDevice->TxPacketFreeQ.Container) >> 1))
+                       pUmDevice->tx_full = 0;
+       }
+       return LM_STATUS_SUCCESS;
+}
+
+/*
+ *  Scan an MBUF chain until we reach fragment number "frag"
+ *  Return its length and physical address.
+ */
+void MM_MapTxDma
+    (PLM_DEVICE_BLOCK pDevice,
+     struct _LM_PACKET *pPacket,
+     T3_64BIT_HOST_ADDR * paddr, LM_UINT32 * len, int frag) {
+       PUM_PACKET pUmPacket = (PUM_PACKET) pPacket;
+       *len = pPacket->PacketSize;
+       MM_SetT3Addr (paddr, (dma_addr_t) pUmPacket->skbuff);
+}
+
+/*
+ *  Convert an mbuf address, a CPU local virtual address,
+ *  to a physical address as seen from a PCI device.  Store the
+ *  result at paddr.
+ */
+void MM_MapRxDma (PLM_DEVICE_BLOCK pDevice,
+                 struct _LM_PACKET *pPacket, T3_64BIT_HOST_ADDR * paddr)
+{
+       PUM_PACKET pUmPacket = (PUM_PACKET) pPacket;
+       MM_SetT3Addr (paddr, (dma_addr_t) pUmPacket->skbuff);
+}
+
+void MM_SetAddr (LM_PHYSICAL_ADDRESS * paddr, dma_addr_t addr)
+{
+#if (BITS_PER_LONG == 64)
+       paddr->High = ((unsigned long)addr) >> 32;
+       paddr->Low = ((unsigned long)addr) & 0xffffffff;
+#else
+       paddr->High = 0;
+       paddr->Low = (unsigned long)addr;
+#endif
+}
+
+void MM_SetT3Addr (T3_64BIT_HOST_ADDR * paddr, dma_addr_t addr)
+{
+       unsigned long baddr = (unsigned long)addr;
+#if (BITS_PER_LONG == 64)
+       set_64bit_addr (paddr, baddr & 0xffffffff, baddr >> 32);
+#else
+       set_64bit_addr (paddr, baddr, 0);
+#endif
+}
+
+/*
+ * This combination of `inline' and `extern' has almost the effect of a
+ * macro.  The way to use it is to put a function definition in a header
+ * file with these keywords, and put another copy of the definition
+ * (lacking `inline' and `extern') in a library file.  The definition in
+ * the header file will cause most calls to the function to be inlined.
+ * If any uses of the function remain, they will refer to the single copy
+ * in the library.
+ */
+void atomic_set (atomic_t * entry, int val)
+{
+       entry->counter = val;
+}
+
+int atomic_read (atomic_t * entry)
+{
+       return entry->counter;
+}
+
+void atomic_inc (atomic_t * entry)
+{
+       if (entry)
+               entry->counter++;
+}
+
+void atomic_dec (atomic_t * entry)
+{
+       if (entry)
+               entry->counter--;
+}
+
+void atomic_sub (int a, atomic_t * entry)
+{
+       if (entry)
+               entry->counter -= a;
+}
+
+void atomic_add (int a, atomic_t * entry)
+{
+       if (entry)
+               entry->counter += a;
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+void QQ_InitQueue (PQQ_CONTAINER pQueue, unsigned int QueueSize)
+{
+       pQueue->Head = 0;
+       pQueue->Tail = 0;
+       pQueue->Size = QueueSize + 1;
+       atomic_set (&pQueue->EntryCnt, 0);
+}                              /* QQ_InitQueue */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+char QQ_Full (PQQ_CONTAINER pQueue)
+{
+       unsigned int NewHead;
+
+       NewHead = (pQueue->Head + 1) % pQueue->Size;
+
+       return (NewHead == pQueue->Tail);
+}                              /* QQ_Full */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+char QQ_Empty (PQQ_CONTAINER pQueue)
+{
+       return (pQueue->Head == pQueue->Tail);
+}                              /* QQ_Empty */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+unsigned int QQ_GetSize (PQQ_CONTAINER pQueue)
+{
+       return pQueue->Size;
+}                              /* QQ_GetSize */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+unsigned int QQ_GetEntryCnt (PQQ_CONTAINER pQueue)
+{
+       return atomic_read (&pQueue->EntryCnt);
+}                              /* QQ_GetEntryCnt */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/*    TRUE entry was added successfully.                                      */
+/*    FALSE queue is full.                                                    */
+/******************************************************************************/
+char QQ_PushHead (PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry)
+{
+       unsigned int Head;
+
+       Head = (pQueue->Head + 1) % pQueue->Size;
+
+#if !defined(QQ_NO_OVERFLOW_CHECK)
+       if (Head == pQueue->Tail) {
+               return 0;
+       }                       /* if */
+#endif                         /* QQ_NO_OVERFLOW_CHECK */
+
+       pQueue->Array[pQueue->Head] = pEntry;
+       wmb ();
+       pQueue->Head = Head;
+       atomic_inc (&pQueue->EntryCnt);
+
+       return -1;
+}                              /* QQ_PushHead */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/*    TRUE entry was added successfully.                                      */
+/*    FALSE queue is full.                                                    */
+/******************************************************************************/
+char QQ_PushTail (PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry)
+{
+       unsigned int Tail;
+
+       Tail = pQueue->Tail;
+       if (Tail == 0) {
+               Tail = pQueue->Size;
+       }                       /* if */
+       Tail--;
+
+#if !defined(QQ_NO_OVERFLOW_CHECK)
+       if (Tail == pQueue->Head) {
+               return 0;
+       }                       /* if */
+#endif                         /* QQ_NO_OVERFLOW_CHECK */
+
+       pQueue->Array[Tail] = pEntry;
+       wmb ();
+       pQueue->Tail = Tail;
+       atomic_inc (&pQueue->EntryCnt);
+
+       return -1;
+}                              /* QQ_PushTail */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+PQQ_ENTRY QQ_PopHead (PQQ_CONTAINER pQueue)
+{
+       unsigned int Head;
+       PQQ_ENTRY Entry;
+
+       Head = pQueue->Head;
+
+#if !defined(QQ_NO_UNDERFLOW_CHECK)
+       if (Head == pQueue->Tail) {
+               return (PQQ_ENTRY) 0;
+       }                       /* if */
+#endif                         /* QQ_NO_UNDERFLOW_CHECK */
+
+       if (Head == 0) {
+               Head = pQueue->Size;
+       }                       /* if */
+       Head--;
+
+       Entry = pQueue->Array[Head];
+       membar ();
+
+       pQueue->Head = Head;
+       atomic_dec (&pQueue->EntryCnt);
+
+       return Entry;
+}                              /* QQ_PopHead */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+PQQ_ENTRY QQ_PopTail (PQQ_CONTAINER pQueue)
+{
+       unsigned int Tail;
+       PQQ_ENTRY Entry;
+
+       Tail = pQueue->Tail;
+
+#if !defined(QQ_NO_UNDERFLOW_CHECK)
+       if (Tail == pQueue->Head) {
+               return (PQQ_ENTRY) 0;
+       }                       /* if */
+#endif                         /* QQ_NO_UNDERFLOW_CHECK */
+
+       Entry = pQueue->Array[Tail];
+       membar ();
+       pQueue->Tail = (Tail + 1) % pQueue->Size;
+       atomic_dec (&pQueue->EntryCnt);
+
+       return Entry;
+}                              /* QQ_PopTail */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+PQQ_ENTRY QQ_GetHead (PQQ_CONTAINER pQueue, unsigned int Idx)
+{
+       if (Idx >= atomic_read (&pQueue->EntryCnt)) {
+               return (PQQ_ENTRY) 0;
+       }
+
+       if (pQueue->Head > Idx) {
+               Idx = pQueue->Head - Idx;
+       } else {
+               Idx = pQueue->Size - (Idx - pQueue->Head);
+       }
+       Idx--;
+
+       return pQueue->Array[Idx];
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+PQQ_ENTRY QQ_GetTail (PQQ_CONTAINER pQueue, unsigned int Idx)
+{
+       if (Idx >= atomic_read (&pQueue->EntryCnt)) {
+               return (PQQ_ENTRY) 0;
+       }
+
+       Idx += pQueue->Tail;
+       if (Idx >= pQueue->Size) {
+               Idx = Idx - pQueue->Size;
+       }
+
+       return pQueue->Array[Idx];
+}
+
+#endif
diff --git a/drivers/net/bcm570x_autoneg.c b/drivers/net/bcm570x_autoneg.c
new file mode 100644 (file)
index 0000000..9023796
--- /dev/null
@@ -0,0 +1,439 @@
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2001 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/******************************************************************************/
+#if !defined(CONFIG_NET_MULTI)
+#if INCLUDE_TBI_SUPPORT
+#include "bcm570x_autoneg.h"
+#include "bcm570x_mm.h"
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+void
+MM_AnTxConfig(
+    PAN_STATE_INFO pAnInfo)
+{
+    PLM_DEVICE_BLOCK pDevice;
+
+    pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext;
+
+    REG_WR(pDevice, MacCtrl.TxAutoNeg, (LM_UINT32) pAnInfo->TxConfig.AsUSHORT);
+
+    pDevice->MacMode |= MAC_MODE_SEND_CONFIGS;
+    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
+}
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+void
+MM_AnTxIdle(
+    PAN_STATE_INFO pAnInfo)
+{
+    PLM_DEVICE_BLOCK pDevice;
+
+    pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext;
+
+    pDevice->MacMode &= ~MAC_MODE_SEND_CONFIGS;
+    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
+}
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+char
+MM_AnRxConfig(
+    PAN_STATE_INFO pAnInfo,
+    unsigned short *pRxConfig)
+{
+    PLM_DEVICE_BLOCK pDevice;
+    LM_UINT32 Value32;
+    char Retcode;
+
+    Retcode = AN_FALSE;
+
+    pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext;
+
+    Value32 = REG_RD(pDevice, MacCtrl.Status);
+    if(Value32 & MAC_STATUS_RECEIVING_CFG)
+    {
+       Value32 = REG_RD(pDevice, MacCtrl.RxAutoNeg);
+       *pRxConfig = (unsigned short) Value32;
+
+       Retcode = AN_TRUE;
+    }
+
+    return Retcode;
+}
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+void
+AutonegInit(
+    PAN_STATE_INFO pAnInfo)
+{
+    unsigned long j;
+
+    for(j = 0; j < sizeof(AN_STATE_INFO); j++)
+    {
+       ((unsigned char *) pAnInfo)[j] = 0;
+    }
+
+    /* Initialize the default advertisement register. */
+    pAnInfo->mr_adv_full_duplex = 1;
+    pAnInfo->mr_adv_sym_pause = 1;
+    pAnInfo->mr_adv_asym_pause = 1;
+    pAnInfo->mr_an_enable = 1;
+}
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+AUTONEG_STATUS
+Autoneg8023z(
+    PAN_STATE_INFO pAnInfo)
+{
+    unsigned short RxConfig;
+    unsigned long Delta_us;
+    AUTONEG_STATUS AnRet;
+
+    /* Get the current time. */
+    if(pAnInfo->State == AN_STATE_UNKNOWN)
+    {
+       pAnInfo->RxConfig.AsUSHORT = 0;
+       pAnInfo->CurrentTime_us = 0;
+       pAnInfo->LinkTime_us = 0;
+       pAnInfo->AbilityMatchCfg = 0;
+       pAnInfo->AbilityMatchCnt = 0;
+       pAnInfo->AbilityMatch = AN_FALSE;
+       pAnInfo->IdleMatch = AN_FALSE;
+       pAnInfo->AckMatch = AN_FALSE;
+    }
+
+    /* Increment the timer tick.  This function is called every microsecon. */
+/*    pAnInfo->CurrentTime_us++; */
+
+    /* Set the AbilityMatch, IdleMatch, and AckMatch flags if their */
+    /* corresponding conditions are satisfied. */
+    if(MM_AnRxConfig(pAnInfo, &RxConfig))
+    {
+       if(RxConfig != pAnInfo->AbilityMatchCfg)
+       {
+           pAnInfo->AbilityMatchCfg = RxConfig;
+           pAnInfo->AbilityMatch = AN_FALSE;
+           pAnInfo->AbilityMatchCnt = 0;
+       }
+       else
+       {
+           pAnInfo->AbilityMatchCnt++;
+           if(pAnInfo->AbilityMatchCnt > 1)
+           {
+               pAnInfo->AbilityMatch = AN_TRUE;
+               pAnInfo->AbilityMatchCfg = RxConfig;
+           }
+       }
+
+       if(RxConfig & AN_CONFIG_ACK)
+       {
+           pAnInfo->AckMatch = AN_TRUE;
+       }
+       else
+       {
+           pAnInfo->AckMatch = AN_FALSE;
+       }
+
+       pAnInfo->IdleMatch = AN_FALSE;
+    }
+    else
+    {
+       pAnInfo->IdleMatch = AN_TRUE;
+
+       pAnInfo->AbilityMatchCfg = 0;
+       pAnInfo->AbilityMatchCnt = 0;
+       pAnInfo->AbilityMatch = AN_FALSE;
+       pAnInfo->AckMatch = AN_FALSE;
+
+       RxConfig = 0;
+    }
+
+    /* Save the last Config. */
+    pAnInfo->RxConfig.AsUSHORT = RxConfig;
+
+    /* Default return code. */
+    AnRet = AUTONEG_STATUS_OK;
+
+    /* Autoneg state machine as defined in 802.3z section 37.3.1.5. */
+    switch(pAnInfo->State)
+    {
+       case AN_STATE_UNKNOWN:
+           if(pAnInfo->mr_an_enable || pAnInfo->mr_restart_an)
+           {
+               pAnInfo->CurrentTime_us = 0;
+               pAnInfo->State = AN_STATE_AN_ENABLE;
+           }
+
+           /* Fall through.*/
+
+       case AN_STATE_AN_ENABLE:
+           pAnInfo->mr_an_complete = AN_FALSE;
+           pAnInfo->mr_page_rx = AN_FALSE;
+
+           if(pAnInfo->mr_an_enable)
+           {
+               pAnInfo->LinkTime_us = 0;
+               pAnInfo->AbilityMatchCfg = 0;
+               pAnInfo->AbilityMatchCnt = 0;
+               pAnInfo->AbilityMatch = AN_FALSE;
+               pAnInfo->IdleMatch = AN_FALSE;
+               pAnInfo->AckMatch = AN_FALSE;
+
+               pAnInfo->State = AN_STATE_AN_RESTART_INIT;
+           }
+           else
+           {
+               pAnInfo->State = AN_STATE_DISABLE_LINK_OK;
+           }
+           break;
+
+       case AN_STATE_AN_RESTART_INIT:
+           pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us;
+           pAnInfo->mr_np_loaded = AN_FALSE;
+
+           pAnInfo->TxConfig.AsUSHORT = 0;
+           MM_AnTxConfig(pAnInfo);
+
+           AnRet = AUTONEG_STATUS_TIMER_ENABLED;
+
+           pAnInfo->State = AN_STATE_AN_RESTART;
+
+           /* Fall through.*/
+
+       case AN_STATE_AN_RESTART:
+           /* Get the current time and compute the delta with the saved */
+           /* link timer. */
+           Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us;
+           if(Delta_us > AN_LINK_TIMER_INTERVAL_US)
+           {
+               pAnInfo->State = AN_STATE_ABILITY_DETECT_INIT;
+           }
+           else
+           {
+               AnRet = AUTONEG_STATUS_TIMER_ENABLED;
+           }
+           break;
+
+       case AN_STATE_DISABLE_LINK_OK:
+           AnRet = AUTONEG_STATUS_DONE;
+           break;
+
+       case AN_STATE_ABILITY_DETECT_INIT:
+           /* Note: in the state diagram, this variable is set to */
+           /* mr_adv_ability<12>.  Is this right?. */
+           pAnInfo->mr_toggle_tx = AN_FALSE;
+
+           /* Send the config as advertised in the advertisement register. */
+           pAnInfo->TxConfig.AsUSHORT = 0;
+           pAnInfo->TxConfig.D5_FD = pAnInfo->mr_adv_full_duplex;
+           pAnInfo->TxConfig.D6_HD = pAnInfo->mr_adv_half_duplex;
+           pAnInfo->TxConfig.D7_PS1 = pAnInfo->mr_adv_sym_pause;
+           pAnInfo->TxConfig.D8_PS2 = pAnInfo->mr_adv_asym_pause;
+           pAnInfo->TxConfig.D12_RF1 = pAnInfo->mr_adv_remote_fault1;
+           pAnInfo->TxConfig.D13_RF2 = pAnInfo->mr_adv_remote_fault2;
+           pAnInfo->TxConfig.D15_NP = pAnInfo->mr_adv_next_page;
+
+           MM_AnTxConfig(pAnInfo);
+
+           pAnInfo->State = AN_STATE_ABILITY_DETECT;
+
+           break;
+
+       case AN_STATE_ABILITY_DETECT:
+           if(pAnInfo->AbilityMatch == AN_TRUE &&
+               pAnInfo->RxConfig.AsUSHORT != 0)
+           {
+               pAnInfo->State = AN_STATE_ACK_DETECT_INIT;
+           }
+
+           break;
+
+       case AN_STATE_ACK_DETECT_INIT:
+           pAnInfo->TxConfig.D14_ACK = 1;
+           MM_AnTxConfig(pAnInfo);
+
+           pAnInfo->State = AN_STATE_ACK_DETECT;
+
+           /* Fall through. */
+
+       case AN_STATE_ACK_DETECT:
+           if(pAnInfo->AckMatch == AN_TRUE)
+           {
+               if((pAnInfo->RxConfig.AsUSHORT & ~AN_CONFIG_ACK) ==
+                   (pAnInfo->AbilityMatchCfg & ~AN_CONFIG_ACK))
+               {
+                   pAnInfo->State = AN_STATE_COMPLETE_ACK_INIT;
+               }
+               else
+               {
+                   pAnInfo->State = AN_STATE_AN_ENABLE;
+               }
+           }
+           else if(pAnInfo->AbilityMatch == AN_TRUE &&
+               pAnInfo->RxConfig.AsUSHORT == 0)
+           {
+               pAnInfo->State = AN_STATE_AN_ENABLE;
+           }
+
+           break;
+
+       case AN_STATE_COMPLETE_ACK_INIT:
+           /* Make sure invalid bits are not set. */
+           if(pAnInfo->RxConfig.bits.D0 || pAnInfo->RxConfig.bits.D1 ||
+               pAnInfo->RxConfig.bits.D2 || pAnInfo->RxConfig.bits.D3 ||
+               pAnInfo->RxConfig.bits.D4 || pAnInfo->RxConfig.bits.D9 ||
+               pAnInfo->RxConfig.bits.D10 || pAnInfo->RxConfig.bits.D11)
+           {
+               AnRet = AUTONEG_STATUS_FAILED;
+               break;
+           }
+
+           /* Set up the link partner advertisement register. */
+           pAnInfo->mr_lp_adv_full_duplex = pAnInfo->RxConfig.D5_FD;
+           pAnInfo->mr_lp_adv_half_duplex = pAnInfo->RxConfig.D6_HD;
+           pAnInfo->mr_lp_adv_sym_pause = pAnInfo->RxConfig.D7_PS1;
+           pAnInfo->mr_lp_adv_asym_pause = pAnInfo->RxConfig.D8_PS2;
+           pAnInfo->mr_lp_adv_remote_fault1 = pAnInfo->RxConfig.D12_RF1;
+           pAnInfo->mr_lp_adv_remote_fault2 = pAnInfo->RxConfig.D13_RF2;
+           pAnInfo->mr_lp_adv_next_page = pAnInfo->RxConfig.D15_NP;
+
+           pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us;
+
+           pAnInfo->mr_toggle_tx = !pAnInfo->mr_toggle_tx;
+           pAnInfo->mr_toggle_rx = pAnInfo->RxConfig.bits.D11;
+           pAnInfo->mr_np_rx = pAnInfo->RxConfig.D15_NP;
+           pAnInfo->mr_page_rx = AN_TRUE;
+
+           pAnInfo->State = AN_STATE_COMPLETE_ACK;
+           AnRet = AUTONEG_STATUS_TIMER_ENABLED;
+
+           break;
+
+       case AN_STATE_COMPLETE_ACK:
+           if(pAnInfo->AbilityMatch == AN_TRUE &&
+               pAnInfo->RxConfig.AsUSHORT == 0)
+           {
+               pAnInfo->State = AN_STATE_AN_ENABLE;
+               break;
+           }
+
+           Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us;
+
+           if(Delta_us > AN_LINK_TIMER_INTERVAL_US)
+           {
+               if(pAnInfo->mr_adv_next_page == 0 ||
+                   pAnInfo->mr_lp_adv_next_page == 0)
+               {
+                   pAnInfo->State = AN_STATE_IDLE_DETECT_INIT;
+               }
+               else
+               {
+                   if(pAnInfo->TxConfig.bits.D15 == 0 &&
+                       pAnInfo->mr_np_rx == 0)
+                   {
+                       pAnInfo->State = AN_STATE_IDLE_DETECT_INIT;
+                   }
+                   else
+                   {
+                       AnRet = AUTONEG_STATUS_FAILED;
+                   }
+               }
+           }
+
+           break;
+
+       case AN_STATE_IDLE_DETECT_INIT:
+           pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us;
+
+           MM_AnTxIdle(pAnInfo);
+
+           pAnInfo->State = AN_STATE_IDLE_DETECT;
+
+           AnRet = AUTONEG_STATUS_TIMER_ENABLED;
+
+           break;
+
+       case AN_STATE_IDLE_DETECT:
+           if(pAnInfo->AbilityMatch == AN_TRUE &&
+               pAnInfo->RxConfig.AsUSHORT == 0)
+           {
+               pAnInfo->State = AN_STATE_AN_ENABLE;
+               break;
+           }
+
+           Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us;
+           if(Delta_us > AN_LINK_TIMER_INTERVAL_US)
+           {
+#if 0
+/*                if(pAnInfo->IdleMatch == AN_TRUE) */
+/*                { */
+#endif
+                   pAnInfo->State = AN_STATE_LINK_OK;
+#if 0
+/*                } */
+/*                else */
+/*                { */
+/*                    AnRet = AUTONEG_STATUS_FAILED; */
+/*                    break; */
+/*                } */
+#endif
+           }
+
+           break;
+
+       case AN_STATE_LINK_OK:
+           pAnInfo->mr_an_complete = AN_TRUE;
+           pAnInfo->mr_link_ok = AN_TRUE;
+           AnRet = AUTONEG_STATUS_DONE;
+
+           break;
+
+       case AN_STATE_NEXT_PAGE_WAIT_INIT:
+           break;
+
+       case AN_STATE_NEXT_PAGE_WAIT:
+           break;
+
+       default:
+           AnRet = AUTONEG_STATUS_FAILED;
+           break;
+    }
+
+    return AnRet;
+}
+#endif /* INCLUDE_TBI_SUPPORT */
+
+#endif /* !defined(CONFIG_NET_MULTI) */
diff --git a/drivers/net/bcm570x_autoneg.h b/drivers/net/bcm570x_autoneg.h
new file mode 100644 (file)
index 0000000..7830944
--- /dev/null
@@ -0,0 +1,408 @@
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2001 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/******************************************************************************/
+
+
+#ifndef AUTONEG_H
+#define AUTONEG_H
+
+
+/******************************************************************************/
+/* Constants. */
+/******************************************************************************/
+
+#define AN_LINK_TIMER_INTERVAL_US           9000       /* 10ms */
+
+/* TRUE, FALSE */
+#define AN_TRUE                             1
+#define AN_FALSE                            0
+
+
+/******************************************************************************/
+/* Main data structure for keeping track of 802.3z auto-negotation state */
+/* variables as shown in Figure 37-6 of the IEEE 802.3z specification. */
+/******************************************************************************/
+
+typedef struct
+{
+    /* Current auto-negotiation state. */
+    unsigned long State;
+    #define AN_STATE_UNKNOWN                        0
+    #define AN_STATE_AN_ENABLE                      1
+    #define AN_STATE_AN_RESTART_INIT                2
+    #define AN_STATE_AN_RESTART                     3
+    #define AN_STATE_DISABLE_LINK_OK                4
+    #define AN_STATE_ABILITY_DETECT_INIT            5
+    #define AN_STATE_ABILITY_DETECT                 6
+    #define AN_STATE_ACK_DETECT_INIT                7
+    #define AN_STATE_ACK_DETECT                     8
+    #define AN_STATE_COMPLETE_ACK_INIT              9
+    #define AN_STATE_COMPLETE_ACK                   10
+    #define AN_STATE_IDLE_DETECT_INIT               11
+    #define AN_STATE_IDLE_DETECT                    12
+    #define AN_STATE_LINK_OK                        13
+    #define AN_STATE_NEXT_PAGE_WAIT_INIT            14
+    #define AN_STATE_NEXT_PAGE_WAIT                 16
+
+    /* Link timer. */
+    unsigned long LinkTime_us;
+
+    /* Current time. */
+    unsigned long CurrentTime_us;
+
+    /* Need these values for consistency check. */
+    unsigned short AbilityMatchCfg;
+
+    /* Ability, idle, and ack match functions. */
+    unsigned long AbilityMatchCnt;
+    char AbilityMatch;
+    char IdleMatch;
+    char AckMatch;
+
+    /* Tx config data */
+    union
+    {
+       /* The TxConfig register is arranged as follows:                      */
+       /*                                                                    */
+       /* MSB                                                           LSB  */
+       /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
+       /* | D7| D6| D5| D4| D3| D2| D1| D0|D15|D14|D13|D12|D11|D10| D9| D8|  */
+       /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
+       struct
+       {
+#ifdef BIG_ENDIAN_HOST
+           unsigned int D7:1;        /* PS1 */
+           unsigned int D6:1;        /* HD */
+           unsigned int D5:1;        /* FD */
+           unsigned int D4:1;
+           unsigned int D3:1;
+           unsigned int D2:1;
+           unsigned int D1:1;
+           unsigned int D0:1;
+           unsigned int D15:1;       /* NP */
+           unsigned int D14:1;       /* ACK */
+           unsigned int D13:1;       /* RF2 */
+           unsigned int D12:1;       /* RF1 */
+           unsigned int D11:1;
+           unsigned int D10:1;
+           unsigned int D9:1;
+           unsigned int D8:1;        /* PS2 */
+#else /* BIG_ENDIAN_HOST */
+           unsigned int D8:1;        /* PS2 */
+           unsigned int D9:1;
+           unsigned int D10:1;
+           unsigned int D11:1;
+           unsigned int D12:1;       /* RF1 */
+           unsigned int D13:1;       /* RF2 */
+           unsigned int D14:1;       /* ACK */
+           unsigned int D15:1;       /* NP */
+           unsigned int D0:1;
+           unsigned int D1:1;
+           unsigned int D2:1;
+           unsigned int D3:1;
+           unsigned int D4:1;
+           unsigned int D5:1;        /* FD */
+           unsigned int D6:1;        /* HD */
+           unsigned int D7:1;        /* PS1 */
+#endif
+       } bits;
+
+       unsigned short AsUSHORT;
+
+       #define D8_PS2                      bits.D8
+       #define D12_RF1                     bits.D12
+       #define D13_RF2                     bits.D13
+       #define D14_ACK                     bits.D14
+       #define D15_NP                      bits.D15
+       #define D5_FD                       bits.D5
+       #define D6_HD                       bits.D6
+       #define D7_PS1                      bits.D7
+    } TxConfig;
+
+    /* Rx config data */
+    union
+    {
+       /* The RxConfig register is arranged as follows:                      */
+       /*                                                                    */
+       /* MSB                                                           LSB  */
+       /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
+       /* | D7| D6| D5| D4| D3| D2| D1| D0|D15|D14|D13|D12|D11|D10| D9| D8|  */
+       /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
+       struct
+       {
+#ifdef BIG_ENDIAN_HOST
+           unsigned int D7:1;        /* PS1 */
+           unsigned int D6:1;        /* HD */
+           unsigned int D5:1;        /* FD */
+           unsigned int D4:1;
+           unsigned int D3:1;
+           unsigned int D2:1;
+           unsigned int D1:1;
+           unsigned int D0:1;
+           unsigned int D15:1;       /* NP */
+           unsigned int D14:1;       /* ACK */
+           unsigned int D13:1;       /* RF2 */
+           unsigned int D12:1;       /* RF1 */
+           unsigned int D11:1;
+           unsigned int D10:1;
+           unsigned int D9:1;
+           unsigned int D8:1;        /* PS2 */
+#else /* BIG_ENDIAN_HOST */
+           unsigned int D8:1;        /* PS2 */
+           unsigned int D9:1;
+           unsigned int D10:1;
+           unsigned int D11:1;
+           unsigned int D12:1;       /* RF1 */
+           unsigned int D13:1;       /* RF2 */
+           unsigned int D14:1;       /* ACK */
+           unsigned int D15:1;       /* NP */
+           unsigned int D0:1;
+           unsigned int D1:1;
+           unsigned int D2:1;
+           unsigned int D3:1;
+           unsigned int D4:1;
+           unsigned int D5:1;        /* FD */
+           unsigned int D6:1;        /* HD */
+           unsigned int D7:1;        /* PS1 */
+#endif
+       } bits;
+
+       unsigned short AsUSHORT;
+    } RxConfig;
+
+    #define AN_CONFIG_NP                            0x0080
+    #define AN_CONFIG_ACK                           0x0040
+    #define AN_CONFIG_RF2                           0x0020
+    #define AN_CONFIG_RF1                           0x0010
+    #define AN_CONFIG_PS2                           0x0001
+    #define AN_CONFIG_PS1                           0x8000
+    #define AN_CONFIG_HD                            0x4000
+    #define AN_CONFIG_FD                            0x2000
+
+
+    /* Management registers. */
+
+    /* Control register. */
+    union
+    {
+       struct
+       {
+           unsigned int an_enable:1;
+           unsigned int loopback:1;
+           unsigned int reset:1;
+           unsigned int restart_an:1;
+       } bits;
+
+       unsigned short AsUSHORT;
+
+       #define mr_an_enable                Mr0.bits.an_enable
+       #define mr_loopback                 Mr0.bits.loopback
+       #define mr_main_reset               Mr0.bits.reset
+       #define mr_restart_an               Mr0.bits.restart_an
+    } Mr0;
+
+    /* Status register. */
+    union
+    {
+       struct
+       {
+           unsigned int an_complete:1;
+           unsigned int link_ok:1;
+       } bits;
+
+       unsigned short AsUSHORT;
+
+       #define mr_an_complete              Mr1.bits.an_complete
+       #define mr_link_ok                  Mr1.bits.link_ok
+    } Mr1;
+
+    /* Advertisement register. */
+    union
+    {
+       struct
+       {
+           unsigned int reserved_4:5;
+           unsigned int full_duplex:1;
+           unsigned int half_duplex:1;
+           unsigned int sym_pause:1;
+           unsigned int asym_pause:1;
+           unsigned int reserved_11:3;
+           unsigned int remote_fault1:1;
+           unsigned int remote_fault2:1;
+           unsigned int reserved_14:1;
+           unsigned int next_page:1;
+       } bits;
+
+       unsigned short AsUSHORT;
+
+       #define mr_adv_full_duplex          Mr4.bits.full_duplex
+       #define mr_adv_half_duplex          Mr4.bits.half_duplex
+       #define mr_adv_sym_pause            Mr4.bits.sym_pause
+       #define mr_adv_asym_pause           Mr4.bits.asym_pause
+       #define mr_adv_remote_fault1        Mr4.bits.remote_fault1
+       #define mr_adv_remote_fault2        Mr4.bits.remote_fault2
+       #define mr_adv_next_page            Mr4.bits.next_page
+    } Mr4;
+
+    /* Link partner advertisement register. */
+    union
+    {
+       struct
+       {
+           unsigned int reserved_4:5;
+           unsigned int lp_full_duplex:1;
+           unsigned int lp_half_duplex:1;
+           unsigned int lp_sym_pause:1;
+           unsigned int lp_asym_pause:1;
+           unsigned int reserved_11:3;
+           unsigned int lp_remote_fault1:1;
+           unsigned int lp_remote_fault2:1;
+           unsigned int lp_ack:1;
+           unsigned int lp_next_page:1;
+       } bits;
+
+       unsigned short AsUSHORT;
+
+       #define mr_lp_adv_full_duplex       Mr5.bits.lp_full_duplex
+       #define mr_lp_adv_half_duplex       Mr5.bits.lp_half_duplex
+       #define mr_lp_adv_sym_pause         Mr5.bits.lp_sym_pause
+       #define mr_lp_adv_asym_pause        Mr5.bits.lp_asym_pause
+       #define mr_lp_adv_remote_fault1     Mr5.bits.lp_remote_fault1
+       #define mr_lp_adv_remote_fault2     Mr5.bits.lp_remote_fault2
+       #define mr_lp_adv_next_page         Mr5.bits.lp_next_page
+    } Mr5;
+
+    /* Auto-negotiation expansion register. */
+    union
+    {
+       struct
+       {
+           unsigned int reserved_0:1;
+           unsigned int page_received:1;
+           unsigned int next_pageable:1;
+           unsigned int reserved_15:13;
+       } bits;
+
+       unsigned short AsUSHORT;
+    } Mr6;
+
+    /* Auto-negotiation next page transmit register. */
+    union
+    {
+       struct
+       {
+           unsigned int code_field:11;
+           unsigned int toggle:1;
+           unsigned int ack2:1;
+           unsigned int message_page:1;
+           unsigned int reserved_14:1;
+           unsigned int next_page:1;
+       } bits;
+
+       unsigned short AsUSHORT;
+
+       #define mr_np_tx                    Mr7.AsUSHORT
+    } Mr7;
+
+    /* Auto-negotiation link partner ability register. */
+    union
+    {
+       struct
+       {
+           unsigned int code_field:11;
+           unsigned int toggle:1;
+           unsigned int ack2:1;
+           unsigned int message_page:1;
+           unsigned int ack:1;
+           unsigned int next_page:1;
+       } bits;
+
+       unsigned short AsUSHORT;
+
+       #define mr_lp_np_rx                 Mr8.AsUSHORT
+    } Mr8;
+
+    /* Extended status register. */
+    union
+    {
+       struct
+       {
+           unsigned int reserved_11:12;
+           unsigned int base1000_t_hd:1;
+           unsigned int base1000_t_fd:1;
+           unsigned int base1000_x_hd:1;
+           unsigned int base1000_x_fd:1;
+       } bits;
+
+       unsigned short AsUSHORT;
+    } Mr15;
+
+    /* Miscellaneous state variables. */
+    union
+    {
+       struct
+       {
+           unsigned int toggle_tx:1;
+           unsigned int toggle_rx:1;
+           unsigned int np_rx:1;
+           unsigned int page_rx:1;
+           unsigned int np_loaded:1;
+       } bits;
+
+       unsigned short AsUSHORT;
+
+       #define mr_toggle_tx                MrMisc.bits.toggle_tx
+       #define mr_toggle_rx                MrMisc.bits.toggle_rx
+       #define mr_np_rx                    MrMisc.bits.np_rx
+       #define mr_page_rx                  MrMisc.bits.page_rx
+       #define mr_np_loaded                MrMisc.bits.np_loaded
+    } MrMisc;
+
+
+    /* Implement specifics */
+
+    /* Pointer to the operating system specific data structure. */
+    void *pContext;
+} AN_STATE_INFO, *PAN_STATE_INFO;
+
+
+/******************************************************************************/
+/* Return code of Autoneg8023z. */
+/******************************************************************************/
+
+typedef enum
+{
+    AUTONEG_STATUS_OK               = 0,
+    AUTONEG_STATUS_DONE             = 1,
+    AUTONEG_STATUS_TIMER_ENABLED    = 2,
+    AUTONEG_STATUS_FAILED           = 0xfffffff
+} AUTONEG_STATUS, *PAUTONEG_STATUS;
+
+
+/******************************************************************************/
+/* Function prototypes. */
+/******************************************************************************/
+
+AUTONEG_STATUS Autoneg8023z(PAN_STATE_INFO pAnInfo);
+void AutonegInit(PAN_STATE_INFO pAnInfo);
+
+
+/******************************************************************************/
+/* The following functions are defined in the os-dependent module. */
+/******************************************************************************/
+
+void MM_AnTxConfig(PAN_STATE_INFO pAnInfo);
+void MM_AnTxIdle(PAN_STATE_INFO pAnInfo);
+char MM_AnRxConfig(PAN_STATE_INFO pAnInfo, unsigned short *pRxConfig);
+
+
+#endif /* AUTONEG_H */
diff --git a/drivers/net/bcm570x_bits.h b/drivers/net/bcm570x_bits.h
new file mode 100644 (file)
index 0000000..615d61e
--- /dev/null
@@ -0,0 +1,57 @@
+
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/*    02/25/00 Hav Khauv        Initial version.                              */
+/******************************************************************************/
+
+#ifndef BITS_H
+#define BITS_H
+
+
+/******************************************************************************/
+/* Bit Mask definitions */
+/******************************************************************************/
+#define BIT_NONE            0x00
+#define BIT_0               0x01
+#define BIT_1               0x02
+#define BIT_2               0x04
+#define BIT_3               0x08
+#define BIT_4               0x10
+#define BIT_5               0x20
+#define BIT_6               0x40
+#define BIT_7               0x80
+#define BIT_8               0x0100
+#define BIT_9               0x0200
+#define BIT_10              0x0400
+#define BIT_11              0x0800
+#define BIT_12              0x1000
+#define BIT_13              0x2000
+#define BIT_14              0x4000
+#define BIT_15              0x8000
+#define BIT_16              0x010000
+#define BIT_17              0x020000
+#define BIT_18              0x040000
+#define BIT_19              0x080000
+#define BIT_20              0x100000
+#define BIT_21              0x200000
+#define BIT_22              0x400000
+#define BIT_23              0x800000
+#define BIT_24              0x01000000
+#define BIT_25              0x02000000
+#define BIT_26              0x04000000
+#define BIT_27              0x08000000
+#define BIT_28              0x10000000
+#define BIT_29              0x20000000
+#define BIT_30              0x40000000
+#define BIT_31              0x80000000
+
+#endif /* BITS_H */
diff --git a/drivers/net/bcm570x_debug.h b/drivers/net/bcm570x_debug.h
new file mode 100644 (file)
index 0000000..88e209b
--- /dev/null
@@ -0,0 +1,109 @@
+
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/*    02/25/00 Hav Khauv        Initial version.                              */
+/******************************************************************************/
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#ifdef VXWORKS
+#include <vxWorks.h>
+#endif
+
+/******************************************************************************/
+/* Debug macros                                                               */
+/******************************************************************************/
+
+/* Code path for controlling output debug messages. */
+/* Define your code path here. */
+#define CP_INIT                     0x010000
+#define CP_SEND                     0x020000
+#define CP_RCV                      0x040000
+#define CP_INT                      0x080000
+#define CP_UINIT                    0x100000
+#define CP_RESET                    0x200000
+
+#define CP_ALL                      (CP_INIT | CP_SEND | CP_RCV | CP_INT | \
+                                   CP_RESET | CP_UINIT)
+
+#define CP_MASK                     0xffff0000
+
+
+/* Debug message levels. */
+#define LV_VERBOSE                  0x03
+#define LV_INFORM                   0x02
+#define LV_WARN                     0x01
+#define LV_FATAL                    0x00
+
+#define LV_MASK                     0xffff
+
+
+/* Code path and messsage level combined.  These are the first argument of */
+/* the DbgMessage macro. */
+#define INIT_V                      (CP_INIT | LV_VERBOSE)
+#define INIT_I                      (CP_INIT | LV_INFORM)
+#define INIT_W                      (CP_INIT | LV_WARN)
+#define SEND_V                      (CP_SEND | LV_VERBOSE)
+#define SEND_I                      (CP_SEND | LV_INFORM)
+#define SEND_W                      (CP_SEND | LV_WARN)
+#define RCV_V                       (CP_RCV | LV_VERBOSE)
+#define RCV_I                       (CP_RCV | LV_INFORM)
+#define RCV_W                       (CP_RCV | LV_WARN)
+#define INT_V                       (CP_INT | LV_VERBOSE)
+#define INT_I                       (CP_INT | LV_INFORM)
+#define INT_W                       (CP_INT | LV_WARN)
+#define UINIT_V                     (CP_UINIT | LV_VERBOSE)
+#define UINIT_I                     (CP_UINIT | LV_INFORM)
+#define UINIT_W                     (CP_UINIT | LV_WARN)
+#define RESET_V                     (CP_RESET | LV_VERBOSE)
+#define RESET_I                     (CP_RESET | LV_INFORM)
+#define RESET_W                     (CP_RESET | LV_WARN)
+#define CPALL_V                     (CP_ALL | LV_VERBOSE)
+#define CPALL_I                     (CP_ALL | LV_INFORM)
+#define CPALL_W                     (CP_ALL | LV_WARN)
+
+
+/* All code path message levels. */
+#define FATAL                       (CP_ALL | LV_FATAL)
+#define WARN                        (CP_ALL | LV_WARN)
+#define INFORM                      (CP_ALL | LV_INFORM)
+#define VERBOSE                     (CP_ALL | LV_VERBOSE)
+
+
+/* These constants control the message output. */
+/* Set your debug message output level and code path here. */
+#ifndef DBG_MSG_CP
+#define DBG_MSG_CP                  CP_ALL      /* Where to output messages. */
+#endif
+
+#ifndef DBG_MSG_LV
+#define DBG_MSG_LV                  LV_VERBOSE  /* Level of message output. */
+#endif
+
+/* DbgMessage macro. */
+#if DBG
+#define DbgMessage(CNTRL, MESSAGE)  \
+    if((CNTRL & DBG_MSG_CP) && ((CNTRL & LV_MASK) <= DBG_MSG_LV)) \
+       printf MESSAGE
+#define DbgBreak()                 DbgBreakPoint()
+#undef STATIC
+#define STATIC
+#else
+#define DbgMessage(CNTRL, MESSAGE)
+#define DbgBreak()
+#undef STATIC
+#define STATIC static
+#endif /* DBG */
+
+
+#endif /* DEBUG_H */
diff --git a/drivers/net/bcm570x_lm.h b/drivers/net/bcm570x_lm.h
new file mode 100644 (file)
index 0000000..2ea6ca8
--- /dev/null
@@ -0,0 +1,434 @@
+
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/*    02/25/00 Hav Khauv        Initial version.                              */
+/******************************************************************************/
+
+#ifndef LM_H
+#define LM_H
+
+#include "bcm570x_queue.h"
+#include "bcm570x_bits.h"
+
+/******************************************************************************/
+/* Basic types. */
+/******************************************************************************/
+
+typedef char LM_CHAR, *PLM_CHAR;
+typedef unsigned int LM_UINT, *PLM_UINT;
+typedef unsigned char LM_UINT8, *PLM_UINT8;
+typedef unsigned short LM_UINT16, *PLM_UINT16;
+typedef unsigned int LM_UINT32, *PLM_UINT32;
+typedef unsigned int LM_COUNTER, *PLM_COUNTER;
+typedef void LM_VOID, *PLM_VOID;
+typedef char LM_BOOL, *PLM_BOOL;
+
+/* 64bit value. */
+typedef struct {
+#ifdef BIG_ENDIAN_HOST
+       LM_UINT32 High;
+       LM_UINT32 Low;
+#else                          /* BIG_ENDIAN_HOST */
+       LM_UINT32 Low;
+       LM_UINT32 High;
+#endif                         /* !BIG_ENDIAN_HOST */
+} LM_UINT64, *PLM_UINT64;
+
+typedef LM_UINT64 LM_PHYSICAL_ADDRESS, *PLM_PHYSICAL_ADDRESS;
+
+/* void LM_INC_PHYSICAL_ADDRESS(PLM_PHYSICAL_ADDRESS pAddr,LM_UINT32 IncSize) */
+#define LM_INC_PHYSICAL_ADDRESS(pAddr, IncSize)             \
+    {                                                       \
+       LM_UINT32 OrgLow;                                   \
+                                                           \
+       OrgLow = (pAddr)->Low;                              \
+       (pAddr)->Low += IncSize;                            \
+       if((pAddr)->Low < OrgLow) {                         \
+           (pAddr)->High++; /* Wrap around. */             \
+       }                                                   \
+    }
+
+#ifndef NULL
+#define NULL                ((void *) 0)
+#endif                         /* NULL */
+
+#ifndef OFFSETOF
+#define OFFSETOF(_s, _m)    (MM_UINT_PTR(&(((_s *) 0)->_m)))
+#endif                         /* OFFSETOF */
+
+/******************************************************************************/
+/* Simple macros. */
+/******************************************************************************/
+
+#define IS_ETH_BROADCAST(_pEthAddr)                                         \
+    (((unsigned char *) (_pEthAddr))[0] == ((unsigned char) 0xff))
+
+#define IS_ETH_MULTICAST(_pEthAddr)                                         \
+    (((unsigned char *) (_pEthAddr))[0] & ((unsigned char) 0x01))
+
+#define IS_ETH_ADDRESS_EQUAL(_pEtherAddr1, _pEtherAddr2)                    \
+    ((((unsigned char *) (_pEtherAddr1))[0] ==                              \
+    ((unsigned char *) (_pEtherAddr2))[0]) &&                               \
+    (((unsigned char *) (_pEtherAddr1))[1] ==                               \
+    ((unsigned char *) (_pEtherAddr2))[1]) &&                               \
+    (((unsigned char *) (_pEtherAddr1))[2] ==                               \
+    ((unsigned char *) (_pEtherAddr2))[2]) &&                               \
+    (((unsigned char *) (_pEtherAddr1))[3] ==                               \
+    ((unsigned char *) (_pEtherAddr2))[3]) &&                               \
+    (((unsigned char *) (_pEtherAddr1))[4] ==                               \
+    ((unsigned char *) (_pEtherAddr2))[4]) &&                               \
+    (((unsigned char *) (_pEtherAddr1))[5] ==                               \
+    ((unsigned char *) (_pEtherAddr2))[5]))
+
+#define COPY_ETH_ADDRESS(_Src, _Dst)                                        \
+    ((unsigned char *) (_Dst))[0] = ((unsigned char *) (_Src))[0];          \
+    ((unsigned char *) (_Dst))[1] = ((unsigned char *) (_Src))[1];          \
+    ((unsigned char *) (_Dst))[2] = ((unsigned char *) (_Src))[2];          \
+    ((unsigned char *) (_Dst))[3] = ((unsigned char *) (_Src))[3];          \
+    ((unsigned char *) (_Dst))[4] = ((unsigned char *) (_Src))[4];          \
+    ((unsigned char *) (_Dst))[5] = ((unsigned char *) (_Src))[5];
+
+/******************************************************************************/
+/* Constants. */
+/******************************************************************************/
+
+#define ETHERNET_ADDRESS_SIZE           6
+#define ETHERNET_PACKET_HEADER_SIZE     14
+#define MIN_ETHERNET_PACKET_SIZE        64     /* with 4 byte crc. */
+#define MAX_ETHERNET_PACKET_SIZE        1518   /* with 4 byte crc. */
+#define MIN_ETHERNET_PACKET_SIZE_NO_CRC 60
+#define MAX_ETHERNET_PACKET_SIZE_NO_CRC 1514
+#define MAX_ETHERNET_PACKET_BUFFER_SIZE 1536   /* A nice even number. */
+
+#ifndef LM_MAX_MC_TABLE_SIZE
+#define LM_MAX_MC_TABLE_SIZE            32
+#endif                         /* LM_MAX_MC_TABLE_SIZE */
+#define LM_MC_ENTRY_SIZE                (ETHERNET_ADDRESS_SIZE+1)
+#define LM_MC_INSTANCE_COUNT_INDEX      (LM_MC_ENTRY_SIZE-1)
+
+/* Receive filter masks. */
+#define LM_ACCEPT_UNICAST               0x0001
+#define LM_ACCEPT_MULTICAST             0x0002
+#define LM_ACCEPT_ALL_MULTICAST         0x0004
+#define LM_ACCEPT_BROADCAST             0x0008
+#define LM_ACCEPT_ERROR_PACKET          0x0010
+
+#define LM_PROMISCUOUS_MODE             0x10000
+
+/******************************************************************************/
+/* PCI registers. */
+/******************************************************************************/
+
+#define PCI_VENDOR_ID_REG               0x00
+#define PCI_DEVICE_ID_REG               0x02
+
+#define PCI_COMMAND_REG                 0x04
+#define PCI_IO_SPACE_ENABLE             0x0001
+#define PCI_MEM_SPACE_ENABLE            0x0002
+#define PCI_BUSMASTER_ENABLE            0x0004
+#define PCI_MEMORY_WRITE_INVALIDATE     0x0010
+#define PCI_PARITY_ERROR_ENABLE         0x0040
+#define PCI_SYSTEM_ERROR_ENABLE         0x0100
+#define PCI_FAST_BACK_TO_BACK_ENABLE    0x0200
+
+#define PCI_STATUS_REG                  0x06
+#define PCI_REV_ID_REG                  0x08
+
+#define PCI_CACHE_LINE_SIZE_REG         0x0c
+
+#define PCI_IO_BASE_ADDR_REG            0x10
+#define PCI_IO_BASE_ADDR_MASK           0xfffffff0
+
+#define PCI_MEM_BASE_ADDR_LOW           0x10
+#define PCI_MEM_BASE_ADDR_HIGH          0x14
+
+#define PCI_SUBSYSTEM_VENDOR_ID_REG     0x2c
+#define PCI_SUBSYSTEM_ID_REG            0x2e
+#define PCI_INT_LINE_REG                0x3c
+
+#define PCIX_CAP_REG                    0x40
+#define PCIX_ENABLE_RELAXED_ORDERING    BIT_17
+
+/******************************************************************************/
+/* Fragment structure. */
+/******************************************************************************/
+
+typedef struct {
+       LM_UINT32 FragSize;
+       LM_PHYSICAL_ADDRESS FragBuf;
+} LM_FRAG, *PLM_FRAG;
+
+typedef struct {
+       /* FragCount is initialized for the caller to the maximum array size, on */
+       /* return FragCount is the number of the actual fragments in the array. */
+       LM_UINT32 FragCount;
+
+       /* Total buffer size. */
+       LM_UINT32 TotalSize;
+
+       /* Fragment array buffer. */
+       LM_FRAG Fragments[1];
+} LM_FRAG_LIST, *PLM_FRAG_LIST;
+
+#define DECLARE_FRAG_LIST_BUFFER_TYPE(_FRAG_LIST_TYPE_NAME, _MAX_FRAG_COUNT) \
+    typedef struct {                                                         \
+       LM_FRAG_LIST FragList;                                               \
+       LM_FRAG FragListBuffer[_MAX_FRAG_COUNT-1];                           \
+    } _FRAG_LIST_TYPE_NAME, *P##_FRAG_LIST_TYPE_NAME
+
+/******************************************************************************/
+/* Status codes. */
+/******************************************************************************/
+
+#define LM_STATUS_SUCCESS                                       0
+#define LM_STATUS_FAILURE                                       1
+
+#define LM_STATUS_INTERRUPT_ACTIVE                              2
+#define LM_STATUS_INTERRUPT_NOT_ACTIVE                          3
+
+#define LM_STATUS_LINK_ACTIVE                                   4
+#define LM_STATUS_LINK_DOWN                                     5
+#define LM_STATUS_LINK_SETTING_MISMATCH                         6
+
+#define LM_STATUS_TOO_MANY_FRAGMENTS                            7
+#define LM_STATUS_TRANSMIT_ABORTED                              8
+#define LM_STATUS_TRANSMIT_ERROR                                9
+#define LM_STATUS_RECEIVE_ABORTED                               10
+#define LM_STATUS_RECEIVE_ERROR                                 11
+#define LM_STATUS_INVALID_PACKET_SIZE                           12
+#define LM_STATUS_OUT_OF_MAP_REGISTERS                          13
+#define LM_STATUS_UNKNOWN_ADAPTER                               14
+
+typedef LM_UINT LM_STATUS, *PLM_STATUS;
+
+/******************************************************************************/
+/* Requested media type. */
+/******************************************************************************/
+
+#define LM_REQUESTED_MEDIA_TYPE_AUTO                            0
+#define LM_REQUESTED_MEDIA_TYPE_BNC                             1
+#define LM_REQUESTED_MEDIA_TYPE_UTP_AUTO                        2
+#define LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS                      3
+#define LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS_FULL_DUPLEX          4
+#define LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS                     5
+#define LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS_FULL_DUPLEX         6
+#define LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS                    7
+#define LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS_FULL_DUPLEX        8
+#define LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS                   9
+#define LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS_FULL_DUPLEX       10
+#define LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS                  11
+#define LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS_FULL_DUPLEX      12
+#define LM_REQUESTED_MEDIA_TYPE_MAC_LOOPBACK                    0xfffe
+#define LM_REQUESTED_MEDIA_TYPE_PHY_LOOPBACK                    0xffff
+
+typedef LM_UINT32 LM_REQUESTED_MEDIA_TYPE, *PLM_REQUESTED_MEDIA_TYPE;
+
+/******************************************************************************/
+/* Media type. */
+/******************************************************************************/
+
+#define LM_MEDIA_TYPE_UNKNOWN                                   -1
+#define LM_MEDIA_TYPE_AUTO                                      0
+#define LM_MEDIA_TYPE_UTP                                       1
+#define LM_MEDIA_TYPE_BNC                                       2
+#define LM_MEDIA_TYPE_AUI                                       3
+#define LM_MEDIA_TYPE_FIBER                                     4
+
+typedef LM_UINT32 LM_MEDIA_TYPE, *PLM_MEDIA_TYPE;
+
+/******************************************************************************/
+/* Line speed. */
+/******************************************************************************/
+
+#define LM_LINE_SPEED_UNKNOWN                                   0
+#define LM_LINE_SPEED_10MBPS                                    1
+#define LM_LINE_SPEED_100MBPS                                   2
+#define LM_LINE_SPEED_1000MBPS                                  3
+
+typedef LM_UINT32 LM_LINE_SPEED, *PLM_LINE_SPEED;
+
+/******************************************************************************/
+/* Duplex mode. */
+/******************************************************************************/
+
+#define LM_DUPLEX_MODE_UNKNOWN                                  0
+#define LM_DUPLEX_MODE_HALF                                     1
+#define LM_DUPLEX_MODE_FULL                                     2
+
+typedef LM_UINT32 LM_DUPLEX_MODE, *PLM_DUPLEX_MODE;
+
+/******************************************************************************/
+/* Power state. */
+/******************************************************************************/
+
+#define LM_POWER_STATE_D0       0
+#define LM_POWER_STATE_D1       1
+#define LM_POWER_STATE_D2       2
+#define LM_POWER_STATE_D3       3
+
+typedef LM_UINT32 LM_POWER_STATE, *PLM_POWER_STATE;
+
+/******************************************************************************/
+/* Task offloading. */
+/******************************************************************************/
+
+#define LM_TASK_OFFLOAD_NONE                    0x0000
+#define LM_TASK_OFFLOAD_TX_IP_CHECKSUM          0x0001
+#define LM_TASK_OFFLOAD_RX_IP_CHECKSUM          0x0002
+#define LM_TASK_OFFLOAD_TX_TCP_CHECKSUM         0x0004
+#define LM_TASK_OFFLOAD_RX_TCP_CHECKSUM         0x0008
+#define LM_TASK_OFFLOAD_TX_UDP_CHECKSUM         0x0010
+#define LM_TASK_OFFLOAD_RX_UDP_CHECKSUM         0x0020
+#define LM_TASK_OFFLOAD_TCP_SEGMENTATION        0x0040
+
+typedef LM_UINT32 LM_TASK_OFFLOAD, *PLM_TASK_OFFLOAD;
+
+/******************************************************************************/
+/* Flow control. */
+/******************************************************************************/
+
+#define LM_FLOW_CONTROL_NONE                    0x00
+#define LM_FLOW_CONTROL_RECEIVE_PAUSE           0x01
+#define LM_FLOW_CONTROL_TRANSMIT_PAUSE          0x02
+#define LM_FLOW_CONTROL_RX_TX_PAUSE (LM_FLOW_CONTROL_RECEIVE_PAUSE | \
+    LM_FLOW_CONTROL_TRANSMIT_PAUSE)
+
+/* This value can be or-ed with RECEIVE_PAUSE and TRANSMIT_PAUSE.  If the */
+/* auto-negotiation is disabled and the RECEIVE_PAUSE and TRANSMIT_PAUSE */
+/* bits are set, then flow control is enabled regardless of link partner's */
+/* flow control capability. */
+#define LM_FLOW_CONTROL_AUTO_PAUSE              0x80000000
+
+typedef LM_UINT32 LM_FLOW_CONTROL, *PLM_FLOW_CONTROL;
+
+/******************************************************************************/
+/* Wake up mode. */
+/******************************************************************************/
+
+#define LM_WAKE_UP_MODE_NONE                    0
+#define LM_WAKE_UP_MODE_MAGIC_PACKET            1
+#define LM_WAKE_UP_MODE_NWUF                    2
+#define LM_WAKE_UP_MODE_LINK_CHANGE             4
+
+typedef LM_UINT32 LM_WAKE_UP_MODE, *PLM_WAKE_UP_MODE;
+
+/******************************************************************************/
+/* Counters. */
+/******************************************************************************/
+
+#define LM_COUNTER_FRAMES_XMITTED_OK                            0
+#define LM_COUNTER_FRAMES_RECEIVED_OK                           1
+#define LM_COUNTER_ERRORED_TRANSMIT_COUNT                       2
+#define LM_COUNTER_ERRORED_RECEIVE_COUNT                        3
+#define LM_COUNTER_RCV_CRC_ERROR                                4
+#define LM_COUNTER_ALIGNMENT_ERROR                              5
+#define LM_COUNTER_SINGLE_COLLISION_FRAMES                      6
+#define LM_COUNTER_MULTIPLE_COLLISION_FRAMES                    7
+#define LM_COUNTER_FRAMES_DEFERRED                              8
+#define LM_COUNTER_MAX_COLLISIONS                               9
+#define LM_COUNTER_RCV_OVERRUN                                  10
+#define LM_COUNTER_XMIT_UNDERRUN                                11
+#define LM_COUNTER_UNICAST_FRAMES_XMIT                          12
+#define LM_COUNTER_MULTICAST_FRAMES_XMIT                        13
+#define LM_COUNTER_BROADCAST_FRAMES_XMIT                        14
+#define LM_COUNTER_UNICAST_FRAMES_RCV                           15
+#define LM_COUNTER_MULTICAST_FRAMES_RCV                         16
+#define LM_COUNTER_BROADCAST_FRAMES_RCV                         17
+
+typedef LM_UINT32 LM_COUNTER_TYPE, *PLM_COUNTER_TYPE;
+
+/******************************************************************************/
+/* Forward definition. */
+/******************************************************************************/
+
+typedef struct _LM_DEVICE_BLOCK *PLM_DEVICE_BLOCK;
+typedef struct _LM_PACKET *PLM_PACKET;
+
+/******************************************************************************/
+/* Function prototypes. */
+/******************************************************************************/
+
+LM_STATUS LM_GetAdapterInfo (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_InitializeAdapter (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_ResetAdapter (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_DisableInterrupt (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_EnableInterrupt (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_SendPacket (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
+LM_STATUS LM_ServiceInterrupts (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_QueueRxPackets (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_SetReceiveMask (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Mask);
+LM_STATUS LM_Halt (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_Abort (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_MulticastAdd (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress);
+LM_STATUS LM_MulticastDel (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress);
+LM_STATUS LM_MulticastClear (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_SetMacAddress (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMacAddress);
+LM_STATUS LM_LoopbackAddress (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pAddress);
+
+LM_UINT32 LM_GetCrcCounter (PLM_DEVICE_BLOCK pDevice);
+
+LM_WAKE_UP_MODE LM_PMCapabilities (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_NwufAdd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 ByteMaskSize,
+                     LM_UINT8 * pByteMask, LM_UINT8 * pPattern);
+LM_STATUS LM_NwufRemove (PLM_DEVICE_BLOCK pDevice, LM_UINT32 ByteMaskSize,
+                        LM_UINT8 * pByteMask, LM_UINT8 * pPattern);
+LM_STATUS LM_SetPowerState (PLM_DEVICE_BLOCK pDevice,
+                           LM_POWER_STATE PowerLevel);
+
+LM_VOID LM_ReadPhy (PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg,
+                   PLM_UINT32 pData32);
+LM_VOID LM_WritePhy (PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg,
+                    LM_UINT32 Data32);
+
+LM_STATUS LM_ControlLoopBack (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Control);
+LM_STATUS LM_SetupPhy (PLM_DEVICE_BLOCK pDevice);
+int LM_BlinkLED (PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlinkDuration);
+
+/******************************************************************************/
+/* These are the OS specific functions called by LMAC. */
+/******************************************************************************/
+
+LM_STATUS MM_ReadConfig16 (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
+                          LM_UINT16 * pValue16);
+LM_STATUS MM_WriteConfig16 (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
+                           LM_UINT16 Value16);
+LM_STATUS MM_ReadConfig32 (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
+                          LM_UINT32 * pValue32);
+LM_STATUS MM_WriteConfig32 (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset,
+                           LM_UINT32 Value32);
+LM_STATUS MM_MapMemBase (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_MapIoBase (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_IndicateRxPackets (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_IndicateTxPackets (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_StartTxDma (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
+LM_STATUS MM_CompleteTxDma (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
+LM_STATUS MM_AllocateMemory (PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize,
+                            PLM_VOID * pMemoryBlockVirt);
+LM_STATUS MM_AllocateSharedMemory (PLM_DEVICE_BLOCK pDevice,
+                                  LM_UINT32 BlockSize,
+                                  PLM_VOID * pMemoryBlockVirt,
+                                  PLM_PHYSICAL_ADDRESS pMemoryBlockPhy,
+                                  LM_BOOL Cached);
+LM_STATUS MM_GetConfig (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_IndicateStatus (PLM_DEVICE_BLOCK pDevice, LM_STATUS Status);
+LM_STATUS MM_InitializeUmPackets (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS MM_FreeRxBuffer (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
+LM_STATUS MM_CoalesceTxBuffer (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);
+LM_STATUS LM_MbufWorkAround (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_SetLinkSpeed (PLM_DEVICE_BLOCK pDevice,
+                          LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
+
+#if INCLUDE_5703_A0_FIX
+LM_STATUS LM_Load5703DmaWFirmware (PLM_DEVICE_BLOCK pDevice);
+#endif
+
+#endif                         /* LM_H */
diff --git a/drivers/net/bcm570x_mm.h b/drivers/net/bcm570x_mm.h
new file mode 100644 (file)
index 0000000..ff5302f
--- /dev/null
@@ -0,0 +1,158 @@
+
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/******************************************************************************/
+
+#ifndef MM_H
+#define MM_H
+
+#define __raw_readl readl
+#define __raw_writel writel
+
+#define BIG_ENDIAN_HOST 1
+#define readl(addr) (*(volatile unsigned int*)(addr))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+
+/* Define memory barrier function here if needed */
+#define wmb()
+#define membar()
+#include <common.h>
+#include <asm/types.h>
+#include "bcm570x_lm.h"
+#include "bcm570x_queue.h"
+#include "tigon3.h"
+#include <pci.h>
+
+#define FALSE 0
+#define TRUE  1
+#define ERROR -1
+
+#if DBG
+#define STATIC
+#else
+#define STATIC static
+#endif
+
+extern int MM_Packet_Desc_Size;
+
+#define MM_PACKET_DESC_SIZE MM_Packet_Desc_Size
+
+DECLARE_QUEUE_TYPE (UM_RX_PACKET_Q, MAX_RX_PACKET_DESC_COUNT + 1);
+
+#define MAX_MEM 16
+
+/* Synch */
+typedef int mutex_t;
+typedef int spinlock_t;
+
+/* Embedded device control */
+typedef struct _UM_DEVICE_BLOCK {
+       LM_DEVICE_BLOCK lm_dev;
+       pci_dev_t pdev;
+       char *name;
+       void *mem_list[MAX_MEM];
+       dma_addr_t dma_list[MAX_MEM];
+       int mem_size_list[MAX_MEM];
+       int mem_list_num;
+       int mtu;
+       int index;
+       int opened;
+       int delayed_link_ind;   /* Delay link status during initial load */
+       int adapter_just_inited;        /* the first few seconds after init. */
+       int spurious_int;       /* new -- unsupported */
+       int timer_interval;
+       int adaptive_expiry;
+       int crc_counter_expiry; /* new -- unsupported */
+       int poll_tib_expiry;    /* new -- unsupported */
+       int tx_full;
+       int tx_queued;
+       int line_speed;         /* in Mbps, 0 if link is down */
+       UM_RX_PACKET_Q rx_out_of_buf_q;
+       int rx_out_of_buf;
+       int rx_low_buf_thresh;  /* changed to rx_buf_repl_thresh */
+       int rx_buf_repl_panic_thresh;
+       int rx_buf_align;       /* new -- unsupported */
+       int do_global_lock;
+       mutex_t global_lock;
+       mutex_t undi_lock;
+       long undi_flags;
+       volatile int interrupt;
+       int tasklet_pending;
+       int tasklet_busy;       /* new -- unsupported */
+       int rx_pkt;
+       int tx_pkt;
+#ifdef NICE_SUPPORT            /* unsupported, this is a linux ioctl */
+       void (*nice_rx) (void *, void *);
+       void *nice_ctx;
+#endif                         /* NICE_SUPPORT */
+       int rx_adaptive_coalesce;
+       unsigned int rx_last_cnt;
+       unsigned int tx_last_cnt;
+       unsigned int rx_curr_coalesce_frames;
+       unsigned int rx_curr_coalesce_ticks;
+       unsigned int tx_curr_coalesce_frames;   /* new -- unsupported */
+#if TIGON3_DEBUG               /* new -- unsupported */
+       uint tx_zc_count;
+       uint tx_chksum_count;
+       uint tx_himem_count;
+       uint rx_good_chksum_count;
+#endif
+       unsigned int rx_bad_chksum_count;       /* new -- unsupported */
+       unsigned int rx_misc_errors;    /* new -- unsupported */
+} UM_DEVICE_BLOCK, *PUM_DEVICE_BLOCK;
+
+/* Physical/PCI DMA address */
+typedef union {
+       dma_addr_t dma_map;
+} dma_map_t;
+
+/* Packet */
+typedef struct
+    _UM_PACKET {
+       LM_PACKET lm_packet;
+       void *skbuff;           /* Address of packet buffer */
+} UM_PACKET, *PUM_PACKET;
+
+#define MM_ACQUIRE_UNDI_LOCK(_pDevice)
+#define MM_RELEASE_UNDI_LOCK(_pDevice)
+#define MM_ACQUIRE_INT_LOCK(_pDevice)
+#define MM_RELEASE_INT_LOCK(_pDevice)
+#define MM_UINT_PTR(_ptr)   ((unsigned long) (_ptr))
+
+/* Macro for setting 64bit address struct */
+#define set_64bit_addr(paddr, low, high) \
+       (paddr)->Low = low;             \
+       (paddr)->High = high;
+
+/* Assume that PCI controller's view of host memory is same as host */
+
+#define MEM_TO_PCI_PHYS(addr) (addr)
+
+extern void MM_SetAddr (LM_PHYSICAL_ADDRESS * paddr, dma_addr_t addr);
+extern void MM_SetT3Addr (T3_64BIT_HOST_ADDR * paddr, dma_addr_t addr);
+extern void MM_MapTxDma (PLM_DEVICE_BLOCK pDevice,
+                        struct _LM_PACKET *pPacket, T3_64BIT_HOST_ADDR * paddr,
+                        LM_UINT32 * len, int frag);
+extern void MM_MapRxDma (PLM_DEVICE_BLOCK pDevice,
+                        struct _LM_PACKET *pPacket,
+                        T3_64BIT_HOST_ADDR * paddr);
+
+/* BSP needs to provide sysUsecDelay and sysSerialPrintString */
+extern void sysSerialPrintString (char *s);
+#define MM_Wait(usec) udelay(usec)
+
+/* Define memory barrier function here if needed */
+#define wmb()
+
+#if 0
+#define cpu_to_le32(val) LONGSWAP(val)
+#endif
+#endif                         /* MM_H */
diff --git a/drivers/net/bcm570x_queue.h b/drivers/net/bcm570x_queue.h
new file mode 100644 (file)
index 0000000..336b3ca
--- /dev/null
@@ -0,0 +1,387 @@
+
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/* Queue functions.                                                           */
+/*    void          QQ_InitQueue(PQQ_CONTAINER pQueue)                        */
+/*    char          QQ_Full(PQQ_CONTAINER pQueue)                             */
+/*    char          QQ_Empty(PQQ_CONTAINER pQueue)                            */
+/*    unsigned int QQ_GetSize(PQQ_CONTAINER pQueue)                          */
+/*    unsigned int QQ_GetEntryCnt(PQQ_CONTAINER pQueue)                      */
+/*    char          QQ_PushHead(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry)       */
+/*    char          QQ_PushTail(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry)       */
+/*    PQQ_ENTRY     QQ_PopHead(PQQ_CONTAINER pQueue)                          */
+/*    PQQ_ENTRY     QQ_PopTail(PQQ_CONTAINER pQueue)                          */
+/*    PQQ_ENTRY     QQ_GetHead(PQQ_CONTAINER pQueue, unsigned int Idx)       */
+/*    PQQ_ENTRY     QQ_GetTail(PQQ_CONTAINER pQueue, unsigned int Idx)       */
+/*                                                                            */
+/*                                                                            */
+/* History:                                                                   */
+/*    02/25/00 Hav Khauv        Initial version.                              */
+/******************************************************************************/
+
+#ifndef BCM_QUEUE_H
+#define BCM_QUEUE_H
+#ifndef EMBEDDED
+#define EMBEDDED 1
+#endif
+
+/******************************************************************************/
+/* Queue definitions. */
+/******************************************************************************/
+
+/* Entry for queueing. */
+typedef void *PQQ_ENTRY;
+
+/* Linux Atomic Ops support */
+typedef struct { int counter; } atomic_t;
+
+
+/*
+ * This combination of `inline' and `extern' has almost the effect of a
+ * macro.  The way to use it is to put a function definition in a header
+ * file with these keywords, and put another copy of the definition
+ * (lacking `inline' and `extern') in a library file.  The definition in
+ * the header file will cause most calls to the function to be inlined.
+ * If any uses of the function remain, they will refer to the single copy
+ * in the library.
+ */
+extern __inline void
+atomic_set(atomic_t* entry, int val)
+{
+    entry->counter = val;
+}
+extern __inline int
+atomic_read(atomic_t* entry)
+{
+    return entry->counter;
+}
+extern __inline void
+atomic_inc(atomic_t* entry)
+{
+    if(entry)
+       entry->counter++;
+}
+
+extern __inline void
+atomic_dec(atomic_t* entry)
+{
+    if(entry)
+       entry->counter--;
+}
+
+extern __inline void
+atomic_sub(int a, atomic_t* entry)
+{
+    if(entry)
+       entry->counter -= a;
+}
+extern __inline void
+atomic_add(int a, atomic_t* entry)
+{
+    if(entry)
+       entry->counter += a;
+}
+
+
+/* Queue header -- base type. */
+typedef struct {
+    unsigned int Head;
+    unsigned int Tail;
+    unsigned int Size;
+    atomic_t EntryCnt;
+    PQQ_ENTRY Array[1];
+} QQ_CONTAINER, *PQQ_CONTAINER;
+
+
+/* Declare queue type macro. */
+#define DECLARE_QUEUE_TYPE(_QUEUE_TYPE, _QUEUE_SIZE)            \
+                                                               \
+    typedef struct {                                            \
+       QQ_CONTAINER Container;                                 \
+       PQQ_ENTRY EntryBuffer[_QUEUE_SIZE];                     \
+    } _QUEUE_TYPE, *P##_QUEUE_TYPE
+
+
+/******************************************************************************/
+/* Compilation switches. */
+/******************************************************************************/
+
+#if DBG
+#undef QQ_NO_OVERFLOW_CHECK
+#undef QQ_NO_UNDERFLOW_CHECK
+#endif /* DBG */
+
+#ifdef QQ_USE_MACROS
+/* notdone */
+#else
+
+#ifdef QQ_NO_INLINE
+#define __inline
+#endif /* QQ_NO_INLINE */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline void
+QQ_InitQueue(
+PQQ_CONTAINER pQueue,
+unsigned int QueueSize) {
+    pQueue->Head = 0;
+    pQueue->Tail = 0;
+    pQueue->Size = QueueSize+1;
+    atomic_set(&pQueue->EntryCnt, 0);
+} /* QQ_InitQueue */
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline char
+QQ_Full(
+PQQ_CONTAINER pQueue) {
+    unsigned int NewHead;
+
+    NewHead = (pQueue->Head + 1) % pQueue->Size;
+
+    return(NewHead == pQueue->Tail);
+} /* QQ_Full */
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline char
+QQ_Empty(
+PQQ_CONTAINER pQueue) {
+    return(pQueue->Head == pQueue->Tail);
+} /* QQ_Empty */
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline unsigned int
+QQ_GetSize(
+PQQ_CONTAINER pQueue) {
+    return pQueue->Size;
+} /* QQ_GetSize */
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline unsigned int
+QQ_GetEntryCnt(
+PQQ_CONTAINER pQueue) {
+    return atomic_read(&pQueue->EntryCnt);
+} /* QQ_GetEntryCnt */
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/*    TRUE entry was added successfully.                                      */
+/*    FALSE queue is full.                                                    */
+/******************************************************************************/
+extern __inline char
+QQ_PushHead(
+PQQ_CONTAINER pQueue,
+PQQ_ENTRY pEntry) {
+    unsigned int Head;
+
+    Head = (pQueue->Head + 1) % pQueue->Size;
+
+#if !defined(QQ_NO_OVERFLOW_CHECK)
+    if(Head == pQueue->Tail) {
+       return 0;
+    } /* if */
+#endif /* QQ_NO_OVERFLOW_CHECK */
+
+    pQueue->Array[pQueue->Head] = pEntry;
+    wmb();
+    pQueue->Head = Head;
+    atomic_inc(&pQueue->EntryCnt);
+
+    return -1;
+} /* QQ_PushHead */
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/*    TRUE entry was added successfully.                                      */
+/*    FALSE queue is full.                                                    */
+/******************************************************************************/
+extern __inline char
+QQ_PushTail(
+PQQ_CONTAINER pQueue,
+PQQ_ENTRY pEntry) {
+    unsigned int Tail;
+
+    Tail = pQueue->Tail;
+    if(Tail == 0) {
+       Tail = pQueue->Size;
+    } /* if */
+    Tail--;
+
+#if !defined(QQ_NO_OVERFLOW_CHECK)
+    if(Tail == pQueue->Head) {
+       return 0;
+    } /* if */
+#endif /* QQ_NO_OVERFLOW_CHECK */
+
+    pQueue->Array[Tail] = pEntry;
+    wmb();
+    pQueue->Tail = Tail;
+    atomic_inc(&pQueue->EntryCnt);
+
+    return -1;
+} /* QQ_PushTail */
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline PQQ_ENTRY
+QQ_PopHead(
+PQQ_CONTAINER pQueue) {
+    unsigned int Head;
+    PQQ_ENTRY Entry;
+
+    Head = pQueue->Head;
+
+#if !defined(QQ_NO_UNDERFLOW_CHECK)
+    if(Head == pQueue->Tail) {
+       return (PQQ_ENTRY) 0;
+    } /* if */
+#endif /* QQ_NO_UNDERFLOW_CHECK */
+
+    if(Head == 0) {
+       Head = pQueue->Size;
+    } /* if */
+    Head--;
+
+    Entry = pQueue->Array[Head];
+#ifdef EMBEDDED
+    membar();
+#else
+    mb();
+#endif
+    pQueue->Head = Head;
+    atomic_dec(&pQueue->EntryCnt);
+
+    return Entry;
+} /* QQ_PopHead */
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline PQQ_ENTRY
+QQ_PopTail(
+PQQ_CONTAINER pQueue) {
+    unsigned int Tail;
+    PQQ_ENTRY Entry;
+
+    Tail = pQueue->Tail;
+
+#if !defined(QQ_NO_UNDERFLOW_CHECK)
+    if(Tail == pQueue->Head) {
+       return (PQQ_ENTRY) 0;
+    } /* if */
+#endif /* QQ_NO_UNDERFLOW_CHECK */
+
+    Entry = pQueue->Array[Tail];
+#ifdef EMBEDDED
+    membar();
+#else
+    mb();
+#endif
+    pQueue->Tail = (Tail + 1) % pQueue->Size;
+    atomic_dec(&pQueue->EntryCnt);
+
+    return Entry;
+} /* QQ_PopTail */
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline PQQ_ENTRY
+QQ_GetHead(
+    PQQ_CONTAINER pQueue,
+    unsigned int Idx)
+{
+    if(Idx >= atomic_read(&pQueue->EntryCnt))
+    {
+       return (PQQ_ENTRY) 0;
+    }
+
+    if(pQueue->Head > Idx)
+    {
+       Idx = pQueue->Head - Idx;
+    }
+    else
+    {
+       Idx = pQueue->Size - (Idx - pQueue->Head);
+    }
+    Idx--;
+
+    return pQueue->Array[Idx];
+}
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+extern __inline PQQ_ENTRY
+QQ_GetTail(
+    PQQ_CONTAINER pQueue,
+    unsigned int Idx)
+{
+    if(Idx >= atomic_read(&pQueue->EntryCnt))
+    {
+       return (PQQ_ENTRY) 0;
+    }
+
+    Idx += pQueue->Tail;
+    if(Idx >= pQueue->Size)
+    {
+       Idx = Idx - pQueue->Size;
+    }
+
+    return pQueue->Array[Idx];
+}
+
+#endif /* QQ_USE_MACROS */
+
+
+#endif /* QUEUE_H */
diff --git a/drivers/net/cs8900.c b/drivers/net/cs8900.c
new file mode 100644 (file)
index 0000000..80c4ba2
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+ * Cirrus Logic CS8900A Ethernet
+ *
+ * (C) 2003 Wolfgang Denk, wd@denx.de
+ *     Extension to synchronize ethaddr environment variable
+ *     against value in EEPROM
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * Copyright (C) 1999 Ben Williamson <benw@pobox.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is loaded into SRAM in bootstrap mode, where it waits
+ * for commands on UART1 to read and write memory, jump to code etc.
+ * A design goal for this program is to be entirely independent of the
+ * target board.  Anything with a CL-PS7111 or EP7211 should be able to run
+ * this code in bootstrap mode.  All the board specifics can be handled on
+ * the host.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <common.h>
+#include <command.h>
+#include "cs8900.h"
+#include <net.h>
+
+#ifdef CONFIG_DRIVER_CS8900
+
+#if defined(CONFIG_CMD_NET)
+
+#undef DEBUG
+
+/* packet page register access functions */
+
+#ifdef CS8900_BUS32
+/* we don't need 16 bit initialisation on 32 bit bus */
+#define get_reg_init_bus(x) get_reg((x))
+#else
+static unsigned short get_reg_init_bus (int regno)
+{
+       /* force 16 bit busmode */
+       volatile unsigned char c;
+
+       c = CS8900_BUS16_0;
+       c = CS8900_BUS16_1;
+       c = CS8900_BUS16_0;
+       c = CS8900_BUS16_1;
+       c = CS8900_BUS16_0;
+
+       CS8900_PPTR = regno;
+       return (unsigned short) CS8900_PDATA;
+}
+#endif
+
+static unsigned short get_reg (int regno)
+{
+       CS8900_PPTR = regno;
+       return (unsigned short) CS8900_PDATA;
+}
+
+
+static void put_reg (int regno, unsigned short val)
+{
+       CS8900_PPTR = regno;
+       CS8900_PDATA = val;
+}
+
+static void eth_reset (void)
+{
+       int tmo;
+       unsigned short us;
+
+       /* reset NIC */
+       put_reg (PP_SelfCTL, get_reg (PP_SelfCTL) | PP_SelfCTL_Reset);
+
+       /* wait for 200ms */
+       udelay (200000);
+       /* Wait until the chip is reset */
+
+       tmo = get_timer (0) + 1 * CFG_HZ;
+       while ((((us = get_reg_init_bus (PP_SelfSTAT)) & PP_SelfSTAT_InitD) == 0)
+                  && tmo < get_timer (0))
+               /*NOP*/;
+}
+
+static void eth_reginit (void)
+{
+       /* receive only error free packets addressed to this card */
+       put_reg (PP_RxCTL, PP_RxCTL_IA | PP_RxCTL_Broadcast | PP_RxCTL_RxOK);
+       /* do not generate any interrupts on receive operations */
+       put_reg (PP_RxCFG, 0);
+       /* do not generate any interrupts on transmit operations */
+       put_reg (PP_TxCFG, 0);
+       /* do not generate any interrupts on buffer operations */
+       put_reg (PP_BufCFG, 0);
+       /* enable transmitter/receiver mode */
+       put_reg (PP_LineCTL, PP_LineCTL_Rx | PP_LineCTL_Tx);
+}
+
+void cs8900_get_enetaddr (uchar * addr)
+{
+       int i;
+       unsigned char env_enetaddr[6];
+       char *tmp = getenv ("ethaddr");
+       char *end;
+
+       for (i=0; i<6; i++) {
+               env_enetaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
+               if (tmp)
+                       tmp = (*end) ? end+1 : end;
+       }
+
+       /* verify chip id */
+       if (get_reg_init_bus (PP_ChipID) != 0x630e)
+               return;
+       eth_reset ();
+       if ((get_reg (PP_SelfST) & (PP_SelfSTAT_EEPROM | PP_SelfSTAT_EEPROM_OK)) ==
+                       (PP_SelfSTAT_EEPROM | PP_SelfSTAT_EEPROM_OK)) {
+
+               /* Load the MAC from EEPROM */
+               for (i = 0; i < 6 / 2; i++) {
+                       unsigned int Addr;
+
+                       Addr = get_reg (PP_IA + i * 2);
+                       addr[i * 2] = Addr & 0xFF;
+                       addr[i * 2 + 1] = Addr >> 8;
+               }
+
+               if (memcmp(env_enetaddr, "\0\0\0\0\0\0", 6) != 0 &&
+                   memcmp(env_enetaddr, addr, 6) != 0) {
+                       printf ("\nWarning: MAC addresses don't match:\n");
+                       printf ("\tHW MAC address:  "
+                               "%02X:%02X:%02X:%02X:%02X:%02X\n",
+                               addr[0], addr[1],
+                               addr[2], addr[3],
+                               addr[4], addr[5] );
+                       printf ("\t\"ethaddr\" value: "
+                               "%02X:%02X:%02X:%02X:%02X:%02X\n",
+                               env_enetaddr[0], env_enetaddr[1],
+                               env_enetaddr[2], env_enetaddr[3],
+                               env_enetaddr[4], env_enetaddr[5]) ;
+                       debug ("### Set MAC addr from environment\n");
+                       memcpy (addr, env_enetaddr, 6);
+               }
+               if (!tmp) {
+                       char ethaddr[20];
+                       sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
+                                addr[0], addr[1],
+                                addr[2], addr[3],
+                                addr[4], addr[5]) ;
+                       debug ("### Set environment from HW MAC addr = \"%s\"\n",                               ethaddr);
+                       setenv ("ethaddr", ethaddr);
+               }
+
+       }
+}
+
+void eth_halt (void)
+{
+       /* disable transmitter/receiver mode */
+       put_reg (PP_LineCTL, 0);
+
+       /* "shutdown" to show ChipID or kernel wouldn't find he cs8900 ... */
+       get_reg_init_bus (PP_ChipID);
+}
+
+int eth_init (bd_t * bd)
+{
+
+       /* verify chip id */
+       if (get_reg_init_bus (PP_ChipID) != 0x630e) {
+               printf ("CS8900 Ethernet chip not found?!\n");
+               return 0;
+       }
+
+       eth_reset ();
+       /* set the ethernet address */
+       put_reg (PP_IA + 0, bd->bi_enetaddr[0] | (bd->bi_enetaddr[1] << 8));
+       put_reg (PP_IA + 2, bd->bi_enetaddr[2] | (bd->bi_enetaddr[3] << 8));
+       put_reg (PP_IA + 4, bd->bi_enetaddr[4] | (bd->bi_enetaddr[5] << 8));
+
+       eth_reginit ();
+       return 0;
+}
+
+/* Get a data block via Ethernet */
+extern int eth_rx (void)
+{
+       int i;
+       unsigned short rxlen;
+       unsigned short *addr;
+       unsigned short status;
+
+       status = get_reg (PP_RER);
+
+       if ((status & PP_RER_RxOK) == 0)
+               return 0;
+
+       status = CS8900_RTDATA;         /* stat */
+       rxlen = CS8900_RTDATA;          /* len */
+
+#ifdef DEBUG
+       if (rxlen > PKTSIZE_ALIGN + PKTALIGN)
+               printf ("packet too big!\n");
+#endif
+       for (addr = (unsigned short *) NetRxPackets[0], i = rxlen >> 1; i > 0;
+                i--)
+               *addr++ = CS8900_RTDATA;
+       if (rxlen & 1)
+               *addr++ = CS8900_RTDATA;
+
+       /* Pass the packet up to the protocol layers. */
+       NetReceive (NetRxPackets[0], rxlen);
+
+       return rxlen;
+}
+
+/* Send a data block via Ethernet. */
+extern int eth_send (volatile void *packet, int length)
+{
+       volatile unsigned short *addr;
+       int tmo;
+       unsigned short s;
+
+retry:
+       /* initiate a transmit sequence */
+       CS8900_TxCMD = PP_TxCmd_TxStart_Full;
+       CS8900_TxLEN = length;
+
+       /* Test to see if the chip has allocated memory for the packet */
+       if ((get_reg (PP_BusSTAT) & PP_BusSTAT_TxRDY) == 0) {
+               /* Oops... this should not happen! */
+#ifdef DEBUG
+               printf ("cs: unable to send packet; retrying...\n");
+#endif
+               for (tmo = get_timer (0) + 5 * CFG_HZ; get_timer (0) < tmo;)
+                       /*NOP*/;
+               eth_reset ();
+               eth_reginit ();
+               goto retry;
+       }
+
+       /* Write the contents of the packet */
+       /* assume even number of bytes */
+       for (addr = packet; length > 0; length -= 2)
+               CS8900_RTDATA = *addr++;
+
+       /* wait for transfer to succeed */
+       tmo = get_timer (0) + 5 * CFG_HZ;
+       while ((s = get_reg (PP_TER) & ~0x1F) == 0) {
+               if (get_timer (0) >= tmo)
+                       break;
+       }
+
+       /* nothing */ ;
+       if ((s & (PP_TER_CRS | PP_TER_TxOK)) != PP_TER_TxOK) {
+#ifdef DEBUG
+               printf ("\ntransmission error %#x\n", s);
+#endif
+       }
+
+       return 0;
+}
+
+static void cs8900_e2prom_ready(void)
+{
+       while(get_reg(PP_SelfST) & SI_BUSY);
+}
+
+/***********************************************************/
+/* read a 16-bit word out of the EEPROM                    */
+/***********************************************************/
+
+int cs8900_e2prom_read(unsigned char addr, unsigned short *value)
+{
+       cs8900_e2prom_ready();
+       put_reg(PP_EECMD, EEPROM_READ_CMD | addr);
+       cs8900_e2prom_ready();
+       *value = get_reg(PP_EEData);
+
+       return 0;
+}
+
+
+/***********************************************************/
+/* write a 16-bit word into the EEPROM                     */
+/***********************************************************/
+
+int cs8900_e2prom_write(unsigned char addr, unsigned short value)
+{
+       cs8900_e2prom_ready();
+       put_reg(PP_EECMD, EEPROM_WRITE_EN);
+       cs8900_e2prom_ready();
+       put_reg(PP_EEData, value);
+       put_reg(PP_EECMD, EEPROM_WRITE_CMD | addr);
+       cs8900_e2prom_ready();
+       put_reg(PP_EECMD, EEPROM_WRITE_DIS);
+       cs8900_e2prom_ready();
+
+       return 0;
+}
+
+#endif /* COMMANDS & CFG_NET */
+
+#endif /* CONFIG_DRIVER_CS8900 */
diff --git a/drivers/net/cs8900.h b/drivers/net/cs8900.h
new file mode 100644 (file)
index 0000000..f886d10
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Cirrus Logic CS8900A Ethernet
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * Copyright (C) 1999 Ben Williamson <benw@pobox.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is loaded into SRAM in bootstrap mode, where it waits
+ * for commands on UART1 to read and write memory, jump to code etc.
+ * A design goal for this program is to be entirely independent of the
+ * target board.  Anything with a CL-PS7111 or EP7211 should be able to run
+ * this code in bootstrap mode.  All the board specifics can be handled on
+ * the host.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <asm/types.h>
+#include <config.h>
+
+#ifdef CONFIG_DRIVER_CS8900
+
+/* although the registers are 16 bit, they are 32-bit aligned on the
+   EDB7111. so we have to read them as 32-bit registers and ignore the
+   upper 16-bits. i'm not sure if this holds for the EDB7211. */
+
+#ifdef CS8900_BUS16
+  /* 16 bit aligned registers, 16 bit wide */
+  #define CS8900_REG u16
+  #define CS8900_OFF 0x02
+  #define CS8900_BUS16_0  *(volatile u8 *)(CS8900_BASE+0x00)
+  #define CS8900_BUS16_1  *(volatile u8 *)(CS8900_BASE+0x01)
+#elif  defined(CS8900_BUS32)
+  /* 32 bit aligned registers, 16 bit wide (we ignore upper 16 bits) */
+  #define CS8900_REG u32
+  #define CS8900_OFF 0x04
+#else
+  #error unknown bussize ...
+#endif
+
+#define CS8900_RTDATA *(volatile CS8900_REG *)(CS8900_BASE+0x00*CS8900_OFF)
+#define CS8900_TxCMD  *(volatile CS8900_REG *)(CS8900_BASE+0x02*CS8900_OFF)
+#define CS8900_TxLEN  *(volatile CS8900_REG *)(CS8900_BASE+0x03*CS8900_OFF)
+#define CS8900_ISQ    *(volatile CS8900_REG *)(CS8900_BASE+0x04*CS8900_OFF)
+#define CS8900_PPTR   *(volatile CS8900_REG *)(CS8900_BASE+0x05*CS8900_OFF)
+#define CS8900_PDATA  *(volatile CS8900_REG *)(CS8900_BASE+0x06*CS8900_OFF)
+
+
+#define ISQ_RxEvent     0x04
+#define ISQ_TxEvent     0x08
+#define ISQ_BufEvent    0x0C
+#define ISQ_RxMissEvent 0x10
+#define ISQ_TxColEvent  0x12
+#define ISQ_EventMask   0x3F
+
+/* packet page register offsets */
+
+/* bus interface registers */
+#define PP_ChipID    0x0000  /* Chip identifier - must be 0x630E */
+#define PP_ChipRev   0x0002  /* Chip revision, model codes */
+
+#define PP_IntReg    0x0022  /* Interrupt configuration */
+#define PP_IntReg_IRQ0         0x0000  /* Use INTR0 pin */
+#define PP_IntReg_IRQ1         0x0001  /* Use INTR1 pin */
+#define PP_IntReg_IRQ2         0x0002  /* Use INTR2 pin */
+#define PP_IntReg_IRQ3         0x0003  /* Use INTR3 pin */
+
+/* status and control registers */
+
+#define PP_RxCFG     0x0102  /* Receiver configuration */
+#define PP_RxCFG_Skip1         0x0040  /* Skip (i.e. discard) current frame */
+#define PP_RxCFG_Stream        0x0080  /* Enable streaming mode */
+#define PP_RxCFG_RxOK          0x0100  /* RxOK interrupt enable */
+#define PP_RxCFG_RxDMAonly     0x0200  /* Use RxDMA for all frames */
+#define PP_RxCFG_AutoRxDMA     0x0400  /* Select RxDMA automatically */
+#define PP_RxCFG_BufferCRC     0x0800  /* Include CRC characters in frame */
+#define PP_RxCFG_CRC           0x1000  /* Enable interrupt on CRC error */
+#define PP_RxCFG_RUNT          0x2000  /* Enable interrupt on RUNT frames */
+#define PP_RxCFG_EXTRA         0x4000  /* Enable interrupt on frames with extra data */
+
+#define PP_RxCTL     0x0104  /* Receiver control */
+#define PP_RxCTL_IAHash        0x0040  /* Accept frames that match hash */
+#define PP_RxCTL_Promiscuous   0x0080  /* Accept any frame */
+#define PP_RxCTL_RxOK          0x0100  /* Accept well formed frames */
+#define PP_RxCTL_Multicast     0x0200  /* Accept multicast frames */
+#define PP_RxCTL_IA            0x0400  /* Accept frame that matches IA */
+#define PP_RxCTL_Broadcast     0x0800  /* Accept broadcast frames */
+#define PP_RxCTL_CRC           0x1000  /* Accept frames with bad CRC */
+#define PP_RxCTL_RUNT          0x2000  /* Accept runt frames */
+#define PP_RxCTL_EXTRA         0x4000  /* Accept frames that are too long */
+
+#define PP_TxCFG     0x0106  /* Transmit configuration */
+#define PP_TxCFG_CRS           0x0040  /* Enable interrupt on loss of carrier */
+#define PP_TxCFG_SQE           0x0080  /* Enable interrupt on Signal Quality Error */
+#define PP_TxCFG_TxOK          0x0100  /* Enable interrupt on successful xmits */
+#define PP_TxCFG_Late          0x0200  /* Enable interrupt on "out of window" */
+#define PP_TxCFG_Jabber        0x0400  /* Enable interrupt on jabber detect */
+#define PP_TxCFG_Collision     0x0800  /* Enable interrupt if collision */
+#define PP_TxCFG_16Collisions  0x8000  /* Enable interrupt if > 16 collisions */
+
+#define PP_TxCmd     0x0108  /* Transmit command status */
+#define PP_TxCmd_TxStart_5     0x0000  /* Start after 5 bytes in buffer */
+#define PP_TxCmd_TxStart_381   0x0040  /* Start after 381 bytes in buffer */
+#define PP_TxCmd_TxStart_1021  0x0080  /* Start after 1021 bytes in buffer */
+#define PP_TxCmd_TxStart_Full  0x00C0  /* Start after all bytes loaded */
+#define PP_TxCmd_Force         0x0100  /* Discard any pending packets */
+#define PP_TxCmd_OneCollision  0x0200  /* Abort after a single collision */
+#define PP_TxCmd_NoCRC         0x1000  /* Do not add CRC */
+#define PP_TxCmd_NoPad         0x2000  /* Do not pad short packets */
+
+#define PP_BufCFG    0x010A  /* Buffer configuration */
+#define PP_BufCFG_SWI          0x0040  /* Force interrupt via software */
+#define PP_BufCFG_RxDMA        0x0080  /* Enable interrupt on Rx DMA */
+#define PP_BufCFG_TxRDY        0x0100  /* Enable interrupt when ready for Tx */
+#define PP_BufCFG_TxUE         0x0200  /* Enable interrupt in Tx underrun */
+#define PP_BufCFG_RxMiss       0x0400  /* Enable interrupt on missed Rx packets */
+#define PP_BufCFG_Rx128        0x0800  /* Enable Rx interrupt after 128 bytes */
+#define PP_BufCFG_TxCol        0x1000  /* Enable int on Tx collision ctr overflow */
+#define PP_BufCFG_Miss         0x2000  /* Enable int on Rx miss ctr overflow */
+#define PP_BufCFG_RxDest       0x8000  /* Enable int on Rx dest addr match */
+
+#define PP_LineCTL   0x0112  /* Line control */
+#define PP_LineCTL_Rx          0x0040  /* Enable receiver */
+#define PP_LineCTL_Tx          0x0080  /* Enable transmitter */
+#define PP_LineCTL_AUIonly     0x0100  /* AUI interface only */
+#define PP_LineCTL_AutoAUI10BT 0x0200  /* Autodetect AUI or 10BaseT interface */
+#define PP_LineCTL_ModBackoffE 0x0800  /* Enable modified backoff algorithm */
+#define PP_LineCTL_PolarityDis 0x1000  /* Disable Rx polarity autodetect */
+#define PP_LineCTL_2partDefDis 0x2000  /* Disable two-part defferal */
+#define PP_LineCTL_LoRxSquelch 0x4000  /* Reduce receiver squelch threshold */
+
+#define PP_SelfCTL   0x0114  /* Chip self control */
+#define PP_SelfCTL_Reset       0x0040  /* Self-clearing reset */
+#define PP_SelfCTL_SWSuspend   0x0100  /* Initiate suspend mode */
+#define PP_SelfCTL_HWSleepE    0x0200  /* Enable SLEEP input */
+#define PP_SelfCTL_HWStandbyE  0x0400  /* Enable standby mode */
+#define PP_SelfCTL_HC0E        0x1000  /* use HCB0 for LINK LED */
+#define PP_SelfCTL_HC1E        0x2000  /* use HCB1 for BSTATUS LED */
+#define PP_SelfCTL_HCB0        0x4000  /* control LINK LED if HC0E set */
+#define PP_SelfCTL_HCB1        0x8000  /* control BSTATUS LED if HC1E set */
+
+#define PP_BusCTL    0x0116  /* Bus control */
+#define PP_BusCTL_ResetRxDMA   0x0040  /* Reset RxDMA pointer */
+#define PP_BusCTL_DMAextend    0x0100  /* Extend DMA cycle */
+#define PP_BusCTL_UseSA        0x0200  /* Assert MEMCS16 on address decode */
+#define PP_BusCTL_MemoryE      0x0400  /* Enable memory mode */
+#define PP_BusCTL_DMAburst     0x0800  /* Limit DMA access burst */
+#define PP_BusCTL_IOCHRDYE     0x1000  /* Set IOCHRDY high impedence */
+#define PP_BusCTL_RxDMAsize    0x2000  /* Set DMA buffer size 64KB */
+#define PP_BusCTL_EnableIRQ    0x8000  /* Generate interrupt on interrupt event */
+
+#define PP_TestCTL   0x0118  /* Test control */
+#define PP_TestCTL_DisableLT   0x0080  /* Disable link status */
+#define PP_TestCTL_ENDECloop   0x0200  /* Internal loopback */
+#define PP_TestCTL_AUIloop     0x0400  /* AUI loopback */
+#define PP_TestCTL_DisBackoff  0x0800  /* Disable backoff algorithm */
+#define PP_TestCTL_FDX         0x4000  /* Enable full duplex mode */
+
+#define PP_ISQ       0x0120  /* Interrupt Status Queue */
+
+#define PP_RER       0x0124  /* Receive event */
+#define PP_RER_IAHash          0x0040  /* Frame hash match */
+#define PP_RER_Dribble         0x0080  /* Frame had 1-7 extra bits after last byte */
+#define PP_RER_RxOK            0x0100  /* Frame received with no errors */
+#define PP_RER_Hashed          0x0200  /* Frame address hashed OK */
+#define PP_RER_IA              0x0400  /* Frame address matched IA */
+#define PP_RER_Broadcast       0x0800  /* Broadcast frame */
+#define PP_RER_CRC             0x1000  /* Frame had CRC error */
+#define PP_RER_RUNT            0x2000  /* Runt frame */
+#define PP_RER_EXTRA           0x4000  /* Frame was too long */
+
+#define PP_TER       0x0128 /* Transmit event */
+#define PP_TER_CRS             0x0040  /* Carrier lost */
+#define PP_TER_SQE             0x0080  /* Signal Quality Error */
+#define PP_TER_TxOK            0x0100  /* Packet sent without error */
+#define PP_TER_Late            0x0200  /* Out of window */
+#define PP_TER_Jabber          0x0400  /* Stuck transmit? */
+#define PP_TER_NumCollisions   0x7800  /* Number of collisions */
+#define PP_TER_16Collisions    0x8000  /* > 16 collisions */
+
+#define PP_BER       0x012C /* Buffer event */
+#define PP_BER_SWint           0x0040 /* Software interrupt */
+#define PP_BER_RxDMAFrame      0x0080 /* Received framed DMAed */
+#define PP_BER_Rdy4Tx          0x0100 /* Ready for transmission */
+#define PP_BER_TxUnderrun      0x0200 /* Transmit underrun */
+#define PP_BER_RxMiss          0x0400 /* Received frame missed */
+#define PP_BER_Rx128           0x0800 /* 128 bytes received */
+#define PP_BER_RxDest          0x8000 /* Received framed passed address filter */
+
+#define PP_RxMiss    0x0130  /*  Receiver miss counter */
+
+#define PP_TxCol     0x0132  /*  Transmit collision counter */
+
+#define PP_LineSTAT  0x0134  /* Line status */
+#define PP_LineSTAT_LinkOK     0x0080  /* Line is connected and working */
+#define PP_LineSTAT_AUI        0x0100  /* Connected via AUI */
+#define PP_LineSTAT_10BT       0x0200  /* Connected via twisted pair */
+#define PP_LineSTAT_Polarity   0x1000  /* Line polarity OK (10BT only) */
+#define PP_LineSTAT_CRS        0x4000  /* Frame being received */
+
+#define PP_SelfSTAT  0x0136  /* Chip self status */
+#define PP_SelfSTAT_33VActive  0x0040  /* supply voltage is 3.3V */
+#define PP_SelfSTAT_InitD      0x0080  /* Chip initialization complete */
+#define PP_SelfSTAT_SIBSY      0x0100  /* EEPROM is busy */
+#define PP_SelfSTAT_EEPROM     0x0200  /* EEPROM present */
+#define PP_SelfSTAT_EEPROM_OK  0x0400  /* EEPROM checks out */
+#define PP_SelfSTAT_ELPresent  0x0800  /* External address latch logic available */
+#define PP_SelfSTAT_EEsize     0x1000  /* Size of EEPROM */
+
+#define PP_BusSTAT   0x0138  /* Bus status */
+#define PP_BusSTAT_TxBid       0x0080  /* Tx error */
+#define PP_BusSTAT_TxRDY       0x0100  /* Ready for Tx data */
+
+#define PP_TDR       0x013C  /* AUI Time Domain Reflectometer */
+
+/* initiate transmit registers */
+
+#define PP_TxCommand 0x0144  /* Tx Command */
+#define PP_TxLength  0x0146  /* Tx Length */
+
+
+/* address filter registers */
+
+#define PP_LAF       0x0150  /* Logical address filter (6 bytes) */
+#define PP_IA        0x0158  /* Individual address (MAC) */
+
+/* EEPROM Kram */
+#define SI_BUSY 0x0100
+#define PP_SelfST 0x0136       /*  Self State register */
+#define PP_EECMD 0x0040                /*  NVR Interface Command register */
+#define PP_EEData 0x0042       /*  NVR Interface Data Register */
+#define EEPROM_WRITE_EN                0x00F0
+#define EEPROM_WRITE_DIS       0x0000
+#define EEPROM_WRITE_CMD       0x0100
+#define EEPROM_READ_CMD                0x0200
+#define EEPROM_ERASE_CMD       0x0300
+
+extern int cs8900_e2prom_read(uchar, ushort *);
+extern int cs8900_e2prom_write(uchar, ushort);
+
+#endif /* CONFIG_DRIVER_CS8900 */
diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c
new file mode 100644 (file)
index 0000000..d5275dc
--- /dev/null
@@ -0,0 +1,771 @@
+/*
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_CMD_NET) \
+       && defined(CONFIG_NET_MULTI) && defined(CONFIG_TULIP)
+
+#include <malloc.h>
+#include <net.h>
+#include <pci.h>
+
+#undef DEBUG_SROM
+#undef DEBUG_SROM2
+
+#undef UPDATE_SROM
+
+/* PCI Registers.
+ */
+#define PCI_CFDA_PSM           0x43
+
+#define CFRV_RN                0x000000f0      /* Revision Number */
+
+#define WAKEUP         0x00            /* Power Saving Wakeup */
+#define SLEEP          0x80            /* Power Saving Sleep Mode */
+
+#define DC2114x_BRK    0x0020          /* CFRV break between DC21142 & DC21143 */
+
+/* Ethernet chip registers.
+ */
+#define DE4X5_BMR      0x000           /* Bus Mode Register */
+#define DE4X5_TPD      0x008           /* Transmit Poll Demand Reg */
+#define DE4X5_RRBA     0x018           /* RX Ring Base Address Reg */
+#define DE4X5_TRBA     0x020           /* TX Ring Base Address Reg */
+#define DE4X5_STS      0x028           /* Status Register */
+#define DE4X5_OMR      0x030           /* Operation Mode Register */
+#define DE4X5_SICR     0x068           /* SIA Connectivity Register */
+#define DE4X5_APROM    0x048           /* Ethernet Address PROM */
+
+/* Register bits.
+ */
+#define BMR_SWR                0x00000001      /* Software Reset */
+#define STS_TS         0x00700000      /* Transmit Process State */
+#define STS_RS         0x000e0000      /* Receive Process State */
+#define OMR_ST         0x00002000      /* Start/Stop Transmission Command */
+#define OMR_SR         0x00000002      /* Start/Stop Receive */
+#define OMR_PS         0x00040000      /* Port Select */
+#define OMR_SDP                0x02000000      /* SD Polarity - MUST BE ASSERTED */
+#define OMR_PM         0x00000080      /* Pass All Multicast */
+
+/* Descriptor bits.
+ */
+#define R_OWN          0x80000000      /* Own Bit */
+#define RD_RER         0x02000000      /* Receive End Of Ring */
+#define RD_LS          0x00000100      /* Last Descriptor */
+#define RD_ES          0x00008000      /* Error Summary */
+#define TD_TER         0x02000000      /* Transmit End Of Ring */
+#define T_OWN          0x80000000      /* Own Bit */
+#define TD_LS          0x40000000      /* Last Segment */
+#define TD_FS          0x20000000      /* First Segment */
+#define TD_ES          0x00008000      /* Error Summary */
+#define TD_SET         0x08000000      /* Setup Packet */
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define SROM_WRITE_CMD 5
+#define SROM_READ_CMD  6
+#define SROM_ERASE_CMD 7
+
+#define SROM_HWADD         0x0014      /* Hardware Address offset in SROM */
+#define SROM_RD                0x00004000      /* Read from Boot ROM */
+#define EE_DATA_WRITE        0x04      /* EEPROM chip data in. */
+#define EE_WRITE_0         0x4801
+#define EE_WRITE_1         0x4805
+#define EE_DATA_READ         0x08      /* EEPROM chip data out. */
+#define SROM_SR                0x00000800      /* Select Serial ROM when set */
+
+#define DT_IN          0x00000004      /* Serial Data In */
+#define DT_CLK         0x00000002      /* Serial ROM Clock */
+#define DT_CS          0x00000001      /* Serial ROM Chip Select */
+
+#define POLL_DEMAND    1
+
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+#define RESET_DM9102(dev) {\
+    unsigned long i;\
+    i=INL(dev, 0x0);\
+    udelay(1000);\
+    OUTL(dev, i | BMR_SWR, DE4X5_BMR);\
+    udelay(1000);\
+}
+#else
+#define RESET_DE4X5(dev) {\
+    int i;\
+    i=INL(dev, DE4X5_BMR);\
+    udelay(1000);\
+    OUTL(dev, i | BMR_SWR, DE4X5_BMR);\
+    udelay(1000);\
+    OUTL(dev, i, DE4X5_BMR);\
+    udelay(1000);\
+    for (i=0;i<5;i++) {INL(dev, DE4X5_BMR); udelay(10000);}\
+    udelay(1000);\
+}
+#endif
+
+#define START_DE4X5(dev) {\
+    s32 omr; \
+    omr = INL(dev, DE4X5_OMR);\
+    omr |= OMR_ST | OMR_SR;\
+    OUTL(dev, omr, DE4X5_OMR);         /* Enable the TX and/or RX */\
+}
+
+#define STOP_DE4X5(dev) {\
+    s32 omr; \
+    omr = INL(dev, DE4X5_OMR);\
+    omr &= ~(OMR_ST|OMR_SR);\
+    OUTL(dev, omr, DE4X5_OMR);         /* Disable the TX and/or RX */ \
+}
+
+#define NUM_RX_DESC PKTBUFSRX
+#ifndef CONFIG_TULIP_FIX_DAVICOM
+       #define NUM_TX_DESC 1                   /* Number of TX descriptors   */
+#else
+       #define NUM_TX_DESC 4
+#endif
+#define RX_BUFF_SZ  PKTSIZE_ALIGN
+
+#define TOUT_LOOP   1000000
+
+#define SETUP_FRAME_LEN 192
+#define ETH_ALEN       6
+
+struct de4x5_desc {
+       volatile s32 status;
+       u32 des1;
+       u32 buf;
+       u32 next;
+};
+
+static struct de4x5_desc rx_ring[NUM_RX_DESC] __attribute__ ((aligned(32))); /* RX descriptor ring         */
+static struct de4x5_desc tx_ring[NUM_TX_DESC] __attribute__ ((aligned(32))); /* TX descriptor ring         */
+static int rx_new;                             /* RX descriptor ring pointer */
+static int tx_new;                             /* TX descriptor ring pointer */
+
+static char rxRingSize;
+static char txRingSize;
+
+#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM)
+static void  sendto_srom(struct eth_device* dev, u_int command, u_long addr);
+static int   getfrom_srom(struct eth_device* dev, u_long addr);
+static int   do_eeprom_cmd(struct eth_device *dev, u_long ioaddr,int cmd,int cmd_len);
+static int   do_read_eeprom(struct eth_device *dev,u_long ioaddr,int location,int addr_len);
+#endif /* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */
+#ifdef UPDATE_SROM
+static int   write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value);
+static void  update_srom(struct eth_device *dev, bd_t *bis);
+#endif
+#ifndef CONFIG_TULIP_FIX_DAVICOM
+static int   read_srom(struct eth_device *dev, u_long ioaddr, int index);
+static void  read_hw_addr(struct eth_device* dev, bd_t * bis);
+#endif /* CONFIG_TULIP_FIX_DAVICOM */
+static void  send_setup_frame(struct eth_device* dev, bd_t * bis);
+
+static int   dc21x4x_init(struct eth_device* dev, bd_t* bis);
+static int   dc21x4x_send(struct eth_device* dev, volatile void *packet, int length);
+static int   dc21x4x_recv(struct eth_device* dev);
+static void  dc21x4x_halt(struct eth_device* dev);
+#ifdef CONFIG_TULIP_SELECT_MEDIA
+extern void  dc21x4x_select_media(struct eth_device* dev);
+#endif
+
+#if defined(CONFIG_E500)
+#define phys_to_bus(a) (a)
+#else
+#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
+#endif
+
+static int INL(struct eth_device* dev, u_long addr)
+{
+       return le32_to_cpu(*(volatile u_long *)(addr + dev->iobase));
+}
+
+static void OUTL(struct eth_device* dev, int command, u_long addr)
+{
+       *(volatile u_long *)(addr + dev->iobase) = cpu_to_le32(command);
+}
+
+static struct pci_device_id supported[] = {
+       { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST },
+       { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142 },
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+       { PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DAVICOM_DM9102A },
+#endif
+       { }
+};
+
+int dc21x4x_initialize(bd_t *bis)
+{
+       int                     idx=0;
+       int                     card_number = 0;
+       unsigned int            cfrv;
+       unsigned char           timer;
+       pci_dev_t               devbusfn;
+       unsigned int            iobase;
+       unsigned short          status;
+       struct eth_device*      dev;
+
+       while(1) {
+               devbusfn =  pci_find_devices(supported, idx++);
+               if (devbusfn == -1) {
+                       break;
+               }
+
+               /* Get the chip configuration revision register. */
+               pci_read_config_dword(devbusfn, PCI_REVISION_ID, &cfrv);
+
+#ifndef CONFIG_TULIP_FIX_DAVICOM
+               if ((cfrv & CFRV_RN) < DC2114x_BRK ) {
+                       printf("Error: The chip is not DC21143.\n");
+                       continue;
+               }
+#endif
+
+               pci_read_config_word(devbusfn, PCI_COMMAND, &status);
+               status |=
+#ifdef CONFIG_TULIP_USE_IO
+                 PCI_COMMAND_IO |
+#else
+                 PCI_COMMAND_MEMORY |
+#endif
+                 PCI_COMMAND_MASTER;
+               pci_write_config_word(devbusfn, PCI_COMMAND, status);
+
+               pci_read_config_word(devbusfn, PCI_COMMAND, &status);
+               if (!(status & PCI_COMMAND_IO)) {
+                       printf("Error: Can not enable I/O access.\n");
+                       continue;
+               }
+
+               if (!(status & PCI_COMMAND_IO)) {
+                       printf("Error: Can not enable I/O access.\n");
+                       continue;
+               }
+
+               if (!(status & PCI_COMMAND_MASTER)) {
+                       printf("Error: Can not enable Bus Mastering.\n");
+                       continue;
+               }
+
+               /* Check the latency timer for values >= 0x60. */
+               pci_read_config_byte(devbusfn, PCI_LATENCY_TIMER, &timer);
+
+               if (timer < 0x60) {
+                       pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x60);
+               }
+
+#ifdef CONFIG_TULIP_USE_IO
+               /* read BAR for memory space access */
+               pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase);
+               iobase &= PCI_BASE_ADDRESS_IO_MASK;
+#else
+               /* read BAR for memory space access */
+               pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &iobase);
+               iobase &= PCI_BASE_ADDRESS_MEM_MASK;
+#endif
+               debug ("dc21x4x: DEC 21142 PCI Device @0x%x\n", iobase);
+
+               dev = (struct eth_device*) malloc(sizeof *dev);
+
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+               sprintf(dev->name, "Davicom#%d", card_number);
+#else
+               sprintf(dev->name, "dc21x4x#%d", card_number);
+#endif
+
+#ifdef CONFIG_TULIP_USE_IO
+               dev->iobase = pci_io_to_phys(devbusfn, iobase);
+#else
+               dev->iobase = pci_mem_to_phys(devbusfn, iobase);
+#endif
+               dev->priv   = (void*) devbusfn;
+               dev->init   = dc21x4x_init;
+               dev->halt   = dc21x4x_halt;
+               dev->send   = dc21x4x_send;
+               dev->recv   = dc21x4x_recv;
+
+               /* Ensure we're not sleeping. */
+               pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP);
+
+               udelay(10 * 1000);
+
+#ifndef CONFIG_TULIP_FIX_DAVICOM
+               read_hw_addr(dev, bis);
+#endif
+               eth_register(dev);
+
+               card_number++;
+       }
+
+       return card_number;
+}
+
+static int dc21x4x_init(struct eth_device* dev, bd_t* bis)
+{
+       int             i;
+       int             devbusfn = (int) dev->priv;
+
+       /* Ensure we're not sleeping. */
+       pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP);
+
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+       RESET_DM9102(dev);
+#else
+       RESET_DE4X5(dev);
+#endif
+
+       if ((INL(dev, DE4X5_STS) & (STS_TS | STS_RS)) != 0) {
+               printf("Error: Cannot reset ethernet controller.\n");
+               return 0;
+       }
+
+#ifdef CONFIG_TULIP_SELECT_MEDIA
+       dc21x4x_select_media(dev);
+#else
+       OUTL(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR);
+#endif
+
+       for (i = 0; i < NUM_RX_DESC; i++) {
+               rx_ring[i].status = cpu_to_le32(R_OWN);
+               rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ);
+               rx_ring[i].buf = cpu_to_le32(phys_to_bus((u32) NetRxPackets[i]));
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+               rx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &rx_ring[(i+1) % NUM_RX_DESC]));
+#else
+               rx_ring[i].next = 0;
+#endif
+       }
+
+       for (i=0; i < NUM_TX_DESC; i++) {
+               tx_ring[i].status = 0;
+               tx_ring[i].des1 = 0;
+               tx_ring[i].buf = 0;
+
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+       tx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &tx_ring[(i+1) % NUM_TX_DESC]));
+#else
+               tx_ring[i].next = 0;
+#endif
+       }
+
+       rxRingSize = NUM_RX_DESC;
+       txRingSize = NUM_TX_DESC;
+
+       /* Write the end of list marker to the descriptor lists. */
+       rx_ring[rxRingSize - 1].des1 |= cpu_to_le32(RD_RER);
+       tx_ring[txRingSize - 1].des1 |= cpu_to_le32(TD_TER);
+
+       /* Tell the adapter where the TX/RX rings are located. */
+       OUTL(dev, phys_to_bus((u32) &rx_ring), DE4X5_RRBA);
+       OUTL(dev, phys_to_bus((u32) &tx_ring), DE4X5_TRBA);
+
+       START_DE4X5(dev);
+
+       tx_new = 0;
+       rx_new = 0;
+
+       send_setup_frame(dev, bis);
+
+       return 1;
+}
+
+static int dc21x4x_send(struct eth_device* dev, volatile void *packet, int length)
+{
+       int             status = -1;
+       int             i;
+
+       if (length <= 0) {
+               printf("%s: bad packet size: %d\n", dev->name, length);
+               goto Done;
+       }
+
+       for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+               if (i >= TOUT_LOOP) {
+                       printf("%s: tx error buffer not ready\n", dev->name);
+                       goto Done;
+               }
+       }
+
+       tx_ring[tx_new].buf    = cpu_to_le32(phys_to_bus((u32) packet));
+       tx_ring[tx_new].des1   = cpu_to_le32(TD_TER | TD_LS | TD_FS | length);
+       tx_ring[tx_new].status = cpu_to_le32(T_OWN);
+
+       OUTL(dev, POLL_DEMAND, DE4X5_TPD);
+
+       for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+               if (i >= TOUT_LOOP) {
+                       printf(".%s: tx buffer not ready\n", dev->name);
+                       goto Done;
+               }
+       }
+
+       if (le32_to_cpu(tx_ring[tx_new].status) & TD_ES) {
+#if 0 /* test-only */
+               printf("TX error status = 0x%08X\n",
+                       le32_to_cpu(tx_ring[tx_new].status));
+#endif
+               tx_ring[tx_new].status = 0x0;
+               goto Done;
+       }
+
+       status = length;
+
+ Done:
+    tx_new = (tx_new+1) % NUM_TX_DESC;
+       return status;
+}
+
+static int dc21x4x_recv(struct eth_device* dev)
+{
+       s32             status;
+       int             length    = 0;
+
+       for ( ; ; ) {
+               status = (s32)le32_to_cpu(rx_ring[rx_new].status);
+
+               if (status & R_OWN) {
+                       break;
+               }
+
+               if (status & RD_LS) {
+                       /* Valid frame status.
+                        */
+                       if (status & RD_ES) {
+
+                               /* There was an error.
+                                */
+                               printf("RX error status = 0x%08X\n", status);
+                       } else {
+                               /* A valid frame received.
+                                */
+                               length = (le32_to_cpu(rx_ring[rx_new].status) >> 16);
+
+                               /* Pass the packet up to the protocol
+                                * layers.
+                                */
+                               NetReceive(NetRxPackets[rx_new], length - 4);
+                       }
+
+                       /* Change buffer ownership for this frame, back
+                        * to the adapter.
+                        */
+                       rx_ring[rx_new].status = cpu_to_le32(R_OWN);
+               }
+
+               /* Update entry information.
+                */
+               rx_new = (rx_new + 1) % rxRingSize;
+       }
+
+       return length;
+}
+
+static void dc21x4x_halt(struct eth_device* dev)
+{
+       int             devbusfn = (int) dev->priv;
+
+       STOP_DE4X5(dev);
+       OUTL(dev, 0, DE4X5_SICR);
+
+       pci_write_config_byte(devbusfn, PCI_CFDA_PSM, SLEEP);
+}
+
+static void send_setup_frame(struct eth_device* dev, bd_t *bis)
+{
+       int             i;
+       char    setup_frame[SETUP_FRAME_LEN];
+       char    *pa = &setup_frame[0];
+
+       memset(pa, 0xff, SETUP_FRAME_LEN);
+
+       for (i = 0; i < ETH_ALEN; i++) {
+               *(pa + (i & 1)) = dev->enetaddr[i];
+               if (i & 0x01) {
+                       pa += 4;
+               }
+       }
+
+       for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+               if (i >= TOUT_LOOP) {
+                       printf("%s: tx error buffer not ready\n", dev->name);
+                       goto Done;
+               }
+       }
+
+       tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((u32) &setup_frame[0]));
+       tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_SET| SETUP_FRAME_LEN);
+       tx_ring[tx_new].status = cpu_to_le32(T_OWN);
+
+       OUTL(dev, POLL_DEMAND, DE4X5_TPD);
+
+       for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+               if (i >= TOUT_LOOP) {
+                       printf("%s: tx buffer not ready\n", dev->name);
+                       goto Done;
+               }
+       }
+
+       if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) {
+               printf("TX error status2 = 0x%08X\n", le32_to_cpu(tx_ring[tx_new].status));
+       }
+       tx_new = (tx_new+1) % NUM_TX_DESC;
+
+Done:
+       return;
+}
+
+#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM)
+/* SROM Read and write routines.
+ */
+static void
+sendto_srom(struct eth_device* dev, u_int command, u_long addr)
+{
+       OUTL(dev, command, addr);
+       udelay(1);
+}
+
+static int
+getfrom_srom(struct eth_device* dev, u_long addr)
+{
+       s32 tmp;
+
+       tmp = INL(dev, addr);
+       udelay(1);
+
+       return tmp;
+}
+
+/* Note: this routine returns extra data bits for size detection. */
+static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, int addr_len)
+{
+       int i;
+       unsigned retval = 0;
+       int read_cmd = location | (SROM_READ_CMD << addr_len);
+
+       sendto_srom(dev, SROM_RD | SROM_SR, ioaddr);
+       sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+
+#ifdef DEBUG_SROM
+       printf(" EEPROM read at %d ", location);
+#endif
+
+       /* Shift the read command bits out. */
+       for (i = 4 + addr_len; i >= 0; i--) {
+               short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+               sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval, ioaddr);
+               udelay(10);
+               sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval | DT_CLK, ioaddr);
+               udelay(10);
+#ifdef DEBUG_SROM2
+               printf("%X", getfrom_srom(dev, ioaddr) & 15);
+#endif
+               retval = (retval << 1) | ((getfrom_srom(dev, ioaddr) & EE_DATA_READ) ? 1 : 0);
+       }
+
+       sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+
+#ifdef DEBUG_SROM2
+       printf(" :%X:", getfrom_srom(dev, ioaddr) & 15);
+#endif
+
+       for (i = 16; i > 0; i--) {
+               sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr);
+               udelay(10);
+#ifdef DEBUG_SROM2
+               printf("%X", getfrom_srom(dev, ioaddr) & 15);
+#endif
+               retval = (retval << 1) | ((getfrom_srom(dev, ioaddr) & EE_DATA_READ) ? 1 : 0);
+               sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+               udelay(10);
+       }
+
+       /* Terminate the EEPROM access. */
+       sendto_srom(dev, SROM_RD | SROM_SR, ioaddr);
+
+#ifdef DEBUG_SROM2
+       printf(" EEPROM value at %d is %5.5x.\n", location, retval);
+#endif
+
+       return retval;
+}
+#endif /* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */
+
+/* This executes a generic EEPROM command, typically a write or write
+ * enable. It returns the data output from the EEPROM, and thus may
+ * also be used for reads.
+ */
+#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM)
+static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, int cmd_len)
+{
+       unsigned retval = 0;
+
+#ifdef DEBUG_SROM
+       printf(" EEPROM op 0x%x: ", cmd);
+#endif
+
+       sendto_srom(dev,SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr);
+
+       /* Shift the command bits out. */
+       do {
+               short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;
+               sendto_srom(dev,dataval, ioaddr);
+               udelay(10);
+
+#ifdef DEBUG_SROM2
+               printf("%X", getfrom_srom(dev,ioaddr) & 15);
+#endif
+
+               sendto_srom(dev,dataval | DT_CLK, ioaddr);
+               udelay(10);
+               retval = (retval << 1) | ((getfrom_srom(dev,ioaddr) & EE_DATA_READ) ? 1 : 0);
+       } while (--cmd_len >= 0);
+       sendto_srom(dev,SROM_RD | SROM_SR | DT_CS, ioaddr);
+
+       /* Terminate the EEPROM access. */
+       sendto_srom(dev,SROM_RD | SROM_SR, ioaddr);
+
+#ifdef DEBUG_SROM
+       printf(" EEPROM result is 0x%5.5x.\n", retval);
+#endif
+
+       return retval;
+}
+#endif /* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */
+
+#ifndef CONFIG_TULIP_FIX_DAVICOM
+static int read_srom(struct eth_device *dev, u_long ioaddr, int index)
+{
+       int ee_addr_size = do_read_eeprom(dev, ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
+
+       return do_eeprom_cmd(dev, ioaddr,
+                            (((SROM_READ_CMD << ee_addr_size) | index) << 16)
+                            | 0xffff, 3 + ee_addr_size + 16);
+}
+#endif /* CONFIG_TULIP_FIX_DAVICOM */
+
+#ifdef UPDATE_SROM
+static int write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value)
+{
+       int ee_addr_size = do_read_eeprom(dev, ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
+       int i;
+       unsigned short newval;
+
+       udelay(10*1000); /* test-only */
+
+#ifdef DEBUG_SROM
+       printf("ee_addr_size=%d.\n", ee_addr_size);
+       printf("Writing new entry 0x%4.4x to offset %d.\n", new_value, index);
+#endif
+
+       /* Enable programming modes. */
+       do_eeprom_cmd(dev, ioaddr, (0x4f << (ee_addr_size-4)), 3+ee_addr_size);
+
+       /* Do the actual write. */
+       do_eeprom_cmd(dev, ioaddr,
+                     (((SROM_WRITE_CMD<<ee_addr_size)|index) << 16) | new_value,
+                     3 + ee_addr_size + 16);
+
+       /* Poll for write finished. */
+       sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+       for (i = 0; i < 10000; i++)                     /* Typical 2000 ticks */
+               if (getfrom_srom(dev, ioaddr) & EE_DATA_READ)
+                       break;
+
+#ifdef DEBUG_SROM
+       printf(" Write finished after %d ticks.\n", i);
+#endif
+
+       /* Disable programming. */
+       do_eeprom_cmd(dev, ioaddr, (0x40 << (ee_addr_size-4)), 3 + ee_addr_size);
+
+       /* And read the result. */
+       newval = do_eeprom_cmd(dev, ioaddr,
+                              (((SROM_READ_CMD<<ee_addr_size)|index) << 16)
+                              | 0xffff, 3 + ee_addr_size + 16);
+#ifdef DEBUG_SROM
+       printf("  New value at offset %d is %4.4x.\n", index, newval);
+#endif
+       return 1;
+}
+#endif
+
+#ifndef CONFIG_TULIP_FIX_DAVICOM
+static void read_hw_addr(struct eth_device *dev, bd_t *bis)
+{
+       u_short tmp, *p = (u_short *)(&dev->enetaddr[0]);
+       int i, j = 0;
+
+       for (i = 0; i < (ETH_ALEN >> 1); i++) {
+               tmp = read_srom(dev, DE4X5_APROM, ((SROM_HWADD >> 1) + i));
+               *p = le16_to_cpu(tmp);
+               j += *p++;
+       }
+
+       if ((j == 0) || (j == 0x2fffd)) {
+               memset (dev->enetaddr, 0, ETH_ALEN);
+               debug ("Warning: can't read HW address from SROM.\n");
+               goto Done;
+       }
+
+       return;
+
+Done:
+#ifdef UPDATE_SROM
+       update_srom(dev, bis);
+#endif
+       return;
+}
+#endif /* CONFIG_TULIP_FIX_DAVICOM */
+
+#ifdef UPDATE_SROM
+static void update_srom(struct eth_device *dev, bd_t *bis)
+{
+       int i;
+       static unsigned short eeprom[0x40] = {
+               0x140b, 0x6610, 0x0000, 0x0000,         /* 00 */
+               0x0000, 0x0000, 0x0000, 0x0000,         /* 04 */
+               0x00a3, 0x0103, 0x0000, 0x0000,         /* 08 */
+               0x0000, 0x1f00, 0x0000, 0x0000,         /* 0c */
+               0x0108, 0x038d, 0x0000, 0x0000,         /* 10 */
+               0xe078, 0x0001, 0x0040, 0x0018,         /* 14 */
+               0x0000, 0x0000, 0x0000, 0x0000,         /* 18 */
+               0x0000, 0x0000, 0x0000, 0x0000,         /* 1c */
+               0x0000, 0x0000, 0x0000, 0x0000,         /* 20 */
+               0x0000, 0x0000, 0x0000, 0x0000,         /* 24 */
+               0x0000, 0x0000, 0x0000, 0x0000,         /* 28 */
+               0x0000, 0x0000, 0x0000, 0x0000,         /* 2c */
+               0x0000, 0x0000, 0x0000, 0x0000,         /* 30 */
+               0x0000, 0x0000, 0x0000, 0x0000,         /* 34 */
+               0x0000, 0x0000, 0x0000, 0x0000,         /* 38 */
+               0x0000, 0x0000, 0x0000, 0x4e07,         /* 3c */
+       };
+
+       /* Ethernet Addr... */
+       eeprom[0x0a] = ((bis->bi_enetaddr[1] & 0xff) << 8) | (bis->bi_enetaddr[0] & 0xff);
+       eeprom[0x0b] = ((bis->bi_enetaddr[3] & 0xff) << 8) | (bis->bi_enetaddr[2] & 0xff);
+       eeprom[0x0c] = ((bis->bi_enetaddr[5] & 0xff) << 8) | (bis->bi_enetaddr[4] & 0xff);
+
+       for (i=0; i<0x40; i++)
+       {
+               write_srom(dev, DE4X5_APROM, i, eeprom[i]);
+       }
+}
+#endif /* UPDATE_SROM */
+
+#endif
diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c
new file mode 100644 (file)
index 0000000..6131b5c
--- /dev/null
@@ -0,0 +1,620 @@
+/*
+  dm9000.c: Version 1.2 12/15/2003
+
+       A Davicom DM9000 ISA NIC fast Ethernet driver for Linux.
+       Copyright (C) 1997  Sten Wang
+
+       This program is free software; you can redistribute it and/or
+       modify it under the terms of the GNU General Public License
+       as published by the Free Software Foundation; either version 2
+       of the License, or (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+  (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved.
+
+V0.11  06/20/2001      REG_0A bit3=1, default enable BP with DA match
+       06/22/2001      Support DM9801 progrmming
+                       E3: R25 = ((R24 + NF) & 0x00ff) | 0xf000
+                       E4: R25 = ((R24 + NF) & 0x00ff) | 0xc200
+               R17 = (R17 & 0xfff0) | NF + 3
+                       E5: R25 = ((R24 + NF - 3) & 0x00ff) | 0xc200
+               R17 = (R17 & 0xfff0) | NF
+
+v1.00                  modify by simon 2001.9.5
+                       change for kernel 2.4.x
+
+v1.1   11/09/2001              fix force mode bug
+
+v1.2   03/18/2003       Weilun Huang <weilun_huang@davicom.com.tw>:
+                       Fixed phy reset.
+                       Added tx/rx 32 bit mode.
+                       Cleaned up for kernel merge.
+
+--------------------------------------
+
+       12/15/2003       Initial port to u-boot by Sascha Hauer <saschahauer@web.de>
+
+TODO: Homerun NIC and longrun NIC are not functional, only internal at the
+      moment.
+*/
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_DRIVER_DM9000
+
+#include "dm9000x.h"
+
+/* Board/System/Debug information/definition ---------------- */
+
+#define DM9801_NOISE_FLOOR     0x08
+#define DM9802_NOISE_FLOOR     0x05
+
+/* #define CONFIG_DM9000_DEBUG */
+
+#ifdef CONFIG_DM9000_DEBUG
+#define DM9000_DBG(fmt,args...) printf(fmt ,##args)
+#else                          /*  */
+#define DM9000_DBG(fmt,args...)
+#endif                         /*  */
+enum DM9000_PHY_mode { DM9000_10MHD = 0, DM9000_100MHD =
+           1, DM9000_10MFD = 4, DM9000_100MFD = 5, DM9000_AUTO =
+           8, DM9000_1M_HPNA = 0x10
+};
+enum DM9000_NIC_TYPE { FASTETHER_NIC = 0, HOMERUN_NIC = 1, LONGRUN_NIC = 2
+};
+
+/* Structure/enum declaration ------------------------------- */
+typedef struct board_info {
+       u32 runt_length_counter;        /* counter: RX length < 64byte */
+       u32 long_length_counter;        /* counter: RX length > 1514byte */
+       u32 reset_counter;      /* counter: RESET */
+       u32 reset_tx_timeout;   /* RESET caused by TX Timeout */
+       u32 reset_rx_status;    /* RESET caused by RX Statsus wrong */
+       u16 tx_pkt_cnt;
+       u16 queue_start_addr;
+       u16 dbug_cnt;
+       u8 phy_addr;
+       u8 device_wait_reset;   /* device state */
+       u8 nic_type;            /* NIC type */
+       unsigned char srom[128];
+} board_info_t;
+board_info_t dmfe_info;
+
+/* For module input parameter */
+static int media_mode = DM9000_AUTO;
+static u8 nfloor = 0;
+
+/* function declaration ------------------------------------- */
+int eth_init(bd_t * bd);
+int eth_send(volatile void *, int);
+int eth_rx(void);
+void eth_halt(void);
+static int dm9000_probe(void);
+static u16 phy_read(int);
+static void phy_write(int, u16);
+u16 read_srom_word(int);
+static u8 DM9000_ior(int);
+static void DM9000_iow(int reg, u8 value);
+
+/* DM9000 network board routine ---------------------------- */
+
+#define DM9000_outb(d,r) ( *(volatile u8 *)r = d )
+#define DM9000_outw(d,r) ( *(volatile u16 *)r = d )
+#define DM9000_outl(d,r) ( *(volatile u32 *)r = d )
+#define DM9000_inb(r) (*(volatile u8 *)r)
+#define DM9000_inw(r) (*(volatile u16 *)r)
+#define DM9000_inl(r) (*(volatile u32 *)r)
+
+#ifdef CONFIG_DM9000_DEBUG
+static void
+dump_regs(void)
+{
+       DM9000_DBG("\n");
+       DM9000_DBG("NCR   (0x00): %02x\n", DM9000_ior(0));
+       DM9000_DBG("NSR   (0x01): %02x\n", DM9000_ior(1));
+       DM9000_DBG("TCR   (0x02): %02x\n", DM9000_ior(2));
+       DM9000_DBG("TSRI  (0x03): %02x\n", DM9000_ior(3));
+       DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(4));
+       DM9000_DBG("RCR   (0x05): %02x\n", DM9000_ior(5));
+       DM9000_DBG("RSR   (0x06): %02x\n", DM9000_ior(6));
+       DM9000_DBG("ISR   (0xFE): %02x\n", DM9000_ior(ISR));
+       DM9000_DBG("\n");
+}
+#endif                         /*  */
+
+/*
+  Search DM9000 board, allocate space and register it
+*/
+int
+dm9000_probe(void)
+{
+       u32 id_val;
+       id_val = DM9000_ior(DM9000_VIDL);
+       id_val |= DM9000_ior(DM9000_VIDH) << 8;
+       id_val |= DM9000_ior(DM9000_PIDL) << 16;
+       id_val |= DM9000_ior(DM9000_PIDH) << 24;
+       if (id_val == DM9000_ID) {
+               printf("dm9000 i/o: 0x%x, id: 0x%x \n", CONFIG_DM9000_BASE,
+                      id_val);
+               return 0;
+       } else {
+               printf("dm9000 not found at 0x%08x id: 0x%08x\n",
+                      CONFIG_DM9000_BASE, id_val);
+               return -1;
+       }
+}
+
+/* Set PHY operationg mode
+*/
+static void
+set_PHY_mode(void)
+{
+       u16 phy_reg4 = 0x01e1, phy_reg0 = 0x1000;
+       if (!(media_mode & DM9000_AUTO)) {
+               switch (media_mode) {
+               case DM9000_10MHD:
+                       phy_reg4 = 0x21;
+                       phy_reg0 = 0x0000;
+                       break;
+               case DM9000_10MFD:
+                       phy_reg4 = 0x41;
+                       phy_reg0 = 0x1100;
+                       break;
+               case DM9000_100MHD:
+                       phy_reg4 = 0x81;
+                       phy_reg0 = 0x2000;
+                       break;
+               case DM9000_100MFD:
+                       phy_reg4 = 0x101;
+                       phy_reg0 = 0x3100;
+                       break;
+               }
+               phy_write(4, phy_reg4); /* Set PHY media mode */
+               phy_write(0, phy_reg0); /*  Tmp */
+       }
+       DM9000_iow(DM9000_GPCR, 0x01);  /* Let GPIO0 output */
+       DM9000_iow(DM9000_GPR, 0x00);   /* Enable PHY */
+}
+
+/*
+       Init HomeRun DM9801
+*/
+static void
+program_dm9801(u16 HPNA_rev)
+{
+       __u16 reg16, reg17, reg24, reg25;
+       if (!nfloor)
+               nfloor = DM9801_NOISE_FLOOR;
+       reg16 = phy_read(16);
+       reg17 = phy_read(17);
+       reg24 = phy_read(24);
+       reg25 = phy_read(25);
+       switch (HPNA_rev) {
+       case 0xb900:            /* DM9801 E3 */
+               reg16 |= 0x1000;
+               reg25 = ((reg24 + nfloor) & 0x00ff) | 0xf000;
+               break;
+       case 0xb901:            /* DM9801 E4 */
+               reg25 = ((reg24 + nfloor) & 0x00ff) | 0xc200;
+               reg17 = (reg17 & 0xfff0) + nfloor + 3;
+               break;
+       case 0xb902:            /* DM9801 E5 */
+       case 0xb903:            /* DM9801 E6 */
+       default:
+               reg16 |= 0x1000;
+               reg25 = ((reg24 + nfloor - 3) & 0x00ff) | 0xc200;
+               reg17 = (reg17 & 0xfff0) + nfloor;
+       }
+       phy_write(16, reg16);
+       phy_write(17, reg17);
+       phy_write(25, reg25);
+}
+
+/*
+       Init LongRun DM9802
+*/
+static void
+program_dm9802(void)
+{
+       __u16 reg25;
+       if (!nfloor)
+               nfloor = DM9802_NOISE_FLOOR;
+       reg25 = phy_read(25);
+       reg25 = (reg25 & 0xff00) + nfloor;
+       phy_write(25, reg25);
+}
+
+/* Identify NIC type
+*/
+static void
+identify_nic(void)
+{
+       struct board_info *db = &dmfe_info;     /* Point a board information structure */
+       u16 phy_reg3;
+       DM9000_iow(DM9000_NCR, NCR_EXT_PHY);
+       phy_reg3 = phy_read(3);
+       switch (phy_reg3 & 0xfff0) {
+       case 0xb900:
+               if (phy_read(31) == 0x4404) {
+                       db->nic_type = HOMERUN_NIC;
+                       program_dm9801(phy_reg3);
+                       DM9000_DBG("found homerun NIC\n");
+               } else {
+                       db->nic_type = LONGRUN_NIC;
+                       DM9000_DBG("found longrun NIC\n");
+                       program_dm9802();
+               }
+               break;
+       default:
+               db->nic_type = FASTETHER_NIC;
+               break;
+       }
+       DM9000_iow(DM9000_NCR, 0);
+}
+
+/* General Purpose dm9000 reset routine */
+static void
+dm9000_reset(void)
+{
+       DM9000_DBG("resetting\n");
+       DM9000_iow(DM9000_NCR, NCR_RST);
+       udelay(1000);           /* delay 1ms */
+}
+
+/* Initilize dm9000 board
+*/
+int
+eth_init(bd_t * bd)
+{
+       int i, oft, lnk;
+       DM9000_DBG("eth_init()\n");
+
+       /* RESET device */
+       dm9000_reset();
+       dm9000_probe();
+
+       /* NIC Type: FASTETHER, HOMERUN, LONGRUN */
+       identify_nic();
+
+       /* GPIO0 on pre-activate PHY */
+       DM9000_iow(DM9000_GPR, 0x00);   /*REG_1F bit0 activate phyxcer */
+
+       /* Set PHY */
+       set_PHY_mode();
+
+       /* Program operating register */
+       DM9000_iow(DM9000_NCR, 0x0);    /* only intern phy supported by now */
+       DM9000_iow(DM9000_TCR, 0);      /* TX Polling clear */
+       DM9000_iow(DM9000_BPTR, 0x3f);  /* Less 3Kb, 200us */
+       DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8));   /* Flow Control : High/Low Water */
+       DM9000_iow(DM9000_FCR, 0x0);    /* SH FIXME: This looks strange! Flow Control */
+       DM9000_iow(DM9000_SMCR, 0);     /* Special Mode */
+       DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);   /* clear TX status */
+       DM9000_iow(DM9000_ISR, 0x0f);   /* Clear interrupt status */
+
+       /* Set Node address */
+       for (i = 0; i < 6; i++)
+               ((u16 *) bd->bi_enetaddr)[i] = read_srom_word(i);
+
+       if (is_zero_ether_addr(bd->bi_enetaddr) ||
+           is_multicast_ether_addr(bd->bi_enetaddr)) {
+               /* try reading from environment */
+               u8 i;
+               char *s, *e;
+               s = getenv ("ethaddr");
+               for (i = 0; i < 6; ++i) {
+                       bd->bi_enetaddr[i] = s ?
+                               simple_strtoul (s, &e, 16) : 0;
+                       if (s)
+                               s = (*e) ? e + 1 : e;
+               }
+       }
+
+       printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", bd->bi_enetaddr[0],
+              bd->bi_enetaddr[1], bd->bi_enetaddr[2], bd->bi_enetaddr[3],
+              bd->bi_enetaddr[4], bd->bi_enetaddr[5]);
+       for (i = 0, oft = 0x10; i < 6; i++, oft++)
+               DM9000_iow(oft, bd->bi_enetaddr[i]);
+       for (i = 0, oft = 0x16; i < 8; i++, oft++)
+               DM9000_iow(oft, 0xff);
+
+       /* read back mac, just to be sure */
+       for (i = 0, oft = 0x10; i < 6; i++, oft++)
+               DM9000_DBG("%02x:", DM9000_ior(oft));
+       DM9000_DBG("\n");
+
+       /* Activate DM9000 */
+       DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);  /* RX enable */
+       DM9000_iow(DM9000_IMR, IMR_PAR);        /* Enable TX/RX interrupt mask */
+       i = 0;
+       while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */
+               udelay(1000);
+               i++;
+               if (i == 10000) {
+                       printf("could not establish link\n");
+                       return 0;
+               }
+       }
+
+       /* see what we've got */
+       lnk = phy_read(17) >> 12;
+       printf("operating at ");
+       switch (lnk) {
+       case 1:
+               printf("10M half duplex ");
+               break;
+       case 2:
+               printf("10M full duplex ");
+               break;
+       case 4:
+               printf("100M half duplex ");
+               break;
+       case 8:
+               printf("100M full duplex ");
+               break;
+       default:
+               printf("unknown: %d ", lnk);
+               break;
+       }
+       printf("mode\n");
+       return 0;
+}
+
+/*
+  Hardware start transmission.
+  Send a packet to media from the upper layer.
+*/
+int
+eth_send(volatile void *packet, int length)
+{
+       char *data_ptr;
+       u32 tmplen, i;
+       int tmo;
+       DM9000_DBG("eth_send: length: %d\n", length);
+       for (i = 0; i < length; i++) {
+               if (i % 8 == 0)
+                       DM9000_DBG("\nSend: 02x: ", i);
+               DM9000_DBG("%02x ", ((unsigned char *) packet)[i]);
+       } DM9000_DBG("\n");
+
+       /* Move data to DM9000 TX RAM */
+       data_ptr = (char *) packet;
+       DM9000_outb(DM9000_MWCMD, DM9000_IO);
+
+#ifdef CONFIG_DM9000_USE_8BIT
+       /* Byte mode */
+       for (i = 0; i < length; i++)
+               DM9000_outb((data_ptr[i] & 0xff), DM9000_DATA);
+
+#endif                         /*  */
+#ifdef CONFIG_DM9000_USE_16BIT
+       tmplen = (length + 1) / 2;
+       for (i = 0; i < tmplen; i++)
+               DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA);
+
+#endif                         /*  */
+#ifdef CONFIG_DM9000_USE_32BIT
+       tmplen = (length + 3) / 4;
+       for (i = 0; i < tmplen; i++)
+               DM9000_outl(((u32 *) data_ptr)[i], DM9000_DATA);
+
+#endif                         /*  */
+
+       /* Set TX length to DM9000 */
+       DM9000_iow(DM9000_TXPLL, length & 0xff);
+       DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff);
+
+       /* Issue TX polling command */
+       DM9000_iow(DM9000_TCR, TCR_TXREQ);      /* Cleared after TX complete */
+
+       /* wait for end of transmission */
+       tmo = get_timer(0) + 5 * CFG_HZ;
+       while (DM9000_ior(DM9000_TCR) & TCR_TXREQ) {
+               if (get_timer(0) >= tmo) {
+                       printf("transmission timeout\n");
+                       break;
+               }
+       }
+       DM9000_DBG("transmit done\n\n");
+       return 0;
+}
+
+/*
+  Stop the interface.
+  The interface is stopped when it is brought.
+*/
+void
+eth_halt(void)
+{
+       DM9000_DBG("eth_halt\n");
+
+       /* RESET devie */
+       phy_write(0, 0x8000);   /* PHY RESET */
+       DM9000_iow(DM9000_GPR, 0x01);   /* Power-Down PHY */
+       DM9000_iow(DM9000_IMR, 0x80);   /* Disable all interrupt */
+       DM9000_iow(DM9000_RCR, 0x00);   /* Disable RX */
+}
+
+/*
+  Received a packet and pass to upper layer
+*/
+int
+eth_rx(void)
+{
+       u8 rxbyte, *rdptr = (u8 *) NetRxPackets[0];
+       u16 RxStatus, RxLen = 0;
+       u32 tmplen, i;
+#ifdef CONFIG_DM9000_USE_32BIT
+       u32 tmpdata;
+#endif
+
+       /* Check packet ready or not */
+       DM9000_ior(DM9000_MRCMDX);      /* Dummy read */
+       rxbyte = DM9000_inb(DM9000_DATA);       /* Got most updated data */
+       if (rxbyte == 0)
+               return 0;
+
+       /* Status check: this byte must be 0 or 1 */
+       if (rxbyte > 1) {
+               DM9000_iow(DM9000_RCR, 0x00);   /* Stop Device */
+               DM9000_iow(DM9000_ISR, 0x80);   /* Stop INT request */
+               DM9000_DBG("rx status check: %d\n", rxbyte);
+       }
+       DM9000_DBG("receiving packet\n");
+
+       /* A packet ready now  & Get status/length */
+       DM9000_outb(DM9000_MRCMD, DM9000_IO);
+
+#ifdef CONFIG_DM9000_USE_8BIT
+       RxStatus = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8);
+       RxLen = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8);
+
+#endif                         /*  */
+#ifdef CONFIG_DM9000_USE_16BIT
+       RxStatus = DM9000_inw(DM9000_DATA);
+       RxLen = DM9000_inw(DM9000_DATA);
+
+#endif                         /*  */
+#ifdef CONFIG_DM9000_USE_32BIT
+       tmpdata = DM9000_inl(DM9000_DATA);
+       RxStatus = tmpdata;
+       RxLen = tmpdata >> 16;
+
+#endif                         /*  */
+       DM9000_DBG("rx status: 0x%04x rx len: %d\n", RxStatus, RxLen);
+
+       /* Move data from DM9000 */
+       /* Read received packet from RX SRAM */
+#ifdef CONFIG_DM9000_USE_8BIT
+       for (i = 0; i < RxLen; i++)
+               rdptr[i] = DM9000_inb(DM9000_DATA);
+
+#endif                         /*  */
+#ifdef CONFIG_DM9000_USE_16BIT
+       tmplen = (RxLen + 1) / 2;
+       for (i = 0; i < tmplen; i++)
+               ((u16 *) rdptr)[i] = DM9000_inw(DM9000_DATA);
+
+#endif                         /*  */
+#ifdef CONFIG_DM9000_USE_32BIT
+       tmplen = (RxLen + 3) / 4;
+       for (i = 0; i < tmplen; i++)
+               ((u32 *) rdptr)[i] = DM9000_inl(DM9000_DATA);
+
+#endif                         /*  */
+       if ((RxStatus & 0xbf00) || (RxLen < 0x40)
+           || (RxLen > DM9000_PKT_MAX)) {
+               if (RxStatus & 0x100) {
+                       printf("rx fifo error\n");
+               }
+               if (RxStatus & 0x200) {
+                       printf("rx crc error\n");
+               }
+               if (RxStatus & 0x8000) {
+                       printf("rx length error\n");
+               }
+               if (RxLen > DM9000_PKT_MAX) {
+                       printf("rx length too big\n");
+                       dm9000_reset();
+               }
+       } else {
+
+               /* Pass to upper layer */
+               DM9000_DBG("passing packet to upper layer\n");
+               NetReceive(NetRxPackets[0], RxLen);
+               return RxLen;
+       }
+       return 0;
+}
+
+/*
+  Read a word data from SROM
+*/
+u16
+read_srom_word(int offset)
+{
+       DM9000_iow(DM9000_EPAR, offset);
+       DM9000_iow(DM9000_EPCR, 0x4);
+       udelay(8000);
+       DM9000_iow(DM9000_EPCR, 0x0);
+       return (DM9000_ior(DM9000_EPDRL) + (DM9000_ior(DM9000_EPDRH) << 8));
+}
+
+void
+write_srom_word(int offset, u16 val)
+{
+       DM9000_iow(DM9000_EPAR, offset);
+       DM9000_iow(DM9000_EPDRH, ((val >> 8) & 0xff));
+       DM9000_iow(DM9000_EPDRL, (val & 0xff));
+       DM9000_iow(DM9000_EPCR, 0x12);
+       udelay(8000);
+       DM9000_iow(DM9000_EPCR, 0);
+}
+
+
+/*
+   Read a byte from I/O port
+*/
+static u8
+DM9000_ior(int reg)
+{
+       DM9000_outb(reg, DM9000_IO);
+       return DM9000_inb(DM9000_DATA);
+}
+
+/*
+   Write a byte to I/O port
+*/
+static void
+DM9000_iow(int reg, u8 value)
+{
+       DM9000_outb(reg, DM9000_IO);
+       DM9000_outb(value, DM9000_DATA);
+}
+
+/*
+   Read a word from phyxcer
+*/
+static u16
+phy_read(int reg)
+{
+       u16 val;
+
+       /* Fill the phyxcer register into REG_0C */
+       DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
+       DM9000_iow(DM9000_EPCR, 0xc);   /* Issue phyxcer read command */
+       udelay(100);            /* Wait read complete */
+       DM9000_iow(DM9000_EPCR, 0x0);   /* Clear phyxcer read command */
+       val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);
+
+       /* The read data keeps on REG_0D & REG_0E */
+       DM9000_DBG("phy_read(%d): %d\n", reg, val);
+       return val;
+}
+
+/*
+   Write a word to phyxcer
+*/
+static void
+phy_write(int reg, u16 value)
+{
+
+       /* Fill the phyxcer register into REG_0C */
+       DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
+
+       /* Fill the written data into REG_0D & REG_0E */
+       DM9000_iow(DM9000_EPDRL, (value & 0xff));
+       DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff));
+       DM9000_iow(DM9000_EPCR, 0xa);   /* Issue phyxcer write command */
+       udelay(500);            /* Wait write complete */
+       DM9000_iow(DM9000_EPCR, 0x0);   /* Clear phyxcer write command */
+       DM9000_DBG("phy_write(reg:%d, value:%d)\n", reg, value);
+}
+#endif                         /* CONFIG_DRIVER_DM9000 */
diff --git a/drivers/net/dm9000x.h b/drivers/net/dm9000x.h
new file mode 100644 (file)
index 0000000..f47ff8c
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * dm9000 Ethernet
+ */
+
+#ifdef CONFIG_DRIVER_DM9000
+
+#define DM9000_ID              0x90000A46
+#define DM9000_PKT_MAX         1536    /* Received packet max size */
+#define DM9000_PKT_RDY         0x01    /* Packet ready to receive */
+
+/* although the registers are 16 bit, they are 32-bit aligned.
+ */
+
+#define DM9000_NCR             0x00
+#define DM9000_NSR             0x01
+#define DM9000_TCR             0x02
+#define DM9000_TSR1            0x03
+#define DM9000_TSR2            0x04
+#define DM9000_RCR             0x05
+#define DM9000_RSR             0x06
+#define DM9000_ROCR            0x07
+#define DM9000_BPTR            0x08
+#define DM9000_FCTR            0x09
+#define DM9000_FCR             0x0A
+#define DM9000_EPCR            0x0B
+#define DM9000_EPAR            0x0C
+#define DM9000_EPDRL           0x0D
+#define DM9000_EPDRH           0x0E
+#define DM9000_WCR             0x0F
+
+#define DM9000_PAR             0x10
+#define DM9000_MAR             0x16
+
+#define DM9000_GPCR                    0x1e
+#define DM9000_GPR             0x1f
+#define DM9000_TRPAL           0x22
+#define DM9000_TRPAH           0x23
+#define DM9000_RWPAL           0x24
+#define DM9000_RWPAH           0x25
+
+#define DM9000_VIDL            0x28
+#define DM9000_VIDH            0x29
+#define DM9000_PIDL            0x2A
+#define DM9000_PIDH            0x2B
+
+#define DM9000_CHIPR           0x2C
+#define DM9000_SMCR            0x2F
+
+#define DM9000_PHY             0x40    /* PHY address 0x01 */
+
+#define DM9000_MRCMDX          0xF0
+#define DM9000_MRCMD           0xF2
+#define DM9000_MRRL            0xF4
+#define DM9000_MRRH            0xF5
+#define DM9000_MWCMDX                  0xF6
+#define DM9000_MWCMD           0xF8
+#define DM9000_MWRL            0xFA
+#define DM9000_MWRH            0xFB
+#define DM9000_TXPLL           0xFC
+#define DM9000_TXPLH           0xFD
+#define DM9000_ISR             0xFE
+#define DM9000_IMR             0xFF
+
+#define NCR_EXT_PHY            (1<<7)
+#define NCR_WAKEEN             (1<<6)
+#define NCR_FCOL               (1<<4)
+#define NCR_FDX                        (1<<3)
+#define NCR_LBK                        (3<<1)
+#define NCR_RST                        (1<<0)
+
+#define NSR_SPEED              (1<<7)
+#define NSR_LINKST             (1<<6)
+#define NSR_WAKEST             (1<<5)
+#define NSR_TX2END             (1<<3)
+#define NSR_TX1END             (1<<2)
+#define NSR_RXOV               (1<<1)
+
+#define TCR_TJDIS              (1<<6)
+#define TCR_EXCECM             (1<<5)
+#define TCR_PAD_DIS2   (1<<4)
+#define TCR_CRC_DIS2   (1<<3)
+#define TCR_PAD_DIS1   (1<<2)
+#define TCR_CRC_DIS1   (1<<1)
+#define TCR_TXREQ              (1<<0)
+
+#define TSR_TJTO               (1<<7)
+#define TSR_LC                 (1<<6)
+#define TSR_NC                 (1<<5)
+#define TSR_LCOL               (1<<4)
+#define TSR_COL                        (1<<3)
+#define TSR_EC                 (1<<2)
+
+#define RCR_WTDIS              (1<<6)
+#define RCR_DIS_LONG   (1<<5)
+#define RCR_DIS_CRC            (1<<4)
+#define RCR_ALL                        (1<<3)
+#define RCR_RUNT               (1<<2)
+#define RCR_PRMSC              (1<<1)
+#define RCR_RXEN               (1<<0)
+
+#define RSR_RF                 (1<<7)
+#define RSR_MF                 (1<<6)
+#define RSR_LCS                        (1<<5)
+#define RSR_RWTO               (1<<4)
+#define RSR_PLE                        (1<<3)
+#define RSR_AE                 (1<<2)
+#define RSR_CE                 (1<<1)
+#define RSR_FOE                        (1<<0)
+
+#define FCTR_HWOT(ot)  (( ot & 0xf ) << 4 )
+#define FCTR_LWOT(ot)  ( ot & 0xf )
+
+#define IMR_PAR                        (1<<7)
+#define IMR_ROOM               (1<<3)
+#define IMR_ROM                        (1<<2)
+#define IMR_PTM                        (1<<1)
+#define IMR_PRM                        (1<<0)
+
+#endif
diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c
new file mode 100644 (file)
index 0000000..f0741da
--- /dev/null
@@ -0,0 +1,3016 @@
+/**************************************************************************
+Inter Pro 1000 for ppcboot/das-u-boot
+Drivers are port from Intel's Linux driver e1000-4.3.15
+and from Etherboot pro 1000 driver by mrakes at vivato dot net
+tested on both gig copper and gig fiber boards
+***************************************************************************/
+/*******************************************************************************
+
+
+  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+
+  Contact Information:
+  Linux NICS <linux.nics@intel.com>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+/*
+ *  Copyright (C) Archway Digital Solutions.
+ *
+ *  written by Chrsitopher Li <cli at arcyway dot com> or <chrisl at gnuchina dot org>
+ *  2/9/2002
+ *
+ *  Copyright (C) Linux Networx.
+ *  Massive upgrade to work with the new intel gigabit NICs.
+ *  <ebiederman at lnxi dot com>
+ */
+
+#include "e1000.h"
+
+#if defined(CONFIG_CMD_NET) \
+       && defined(CONFIG_NET_MULTI) && defined(CONFIG_E1000)
+
+#define TOUT_LOOP   100000
+
+#undef virt_to_bus
+#define        virt_to_bus(x)  ((unsigned long)x)
+#define bus_to_phys(devno, a)  pci_mem_to_phys(devno, a)
+#define mdelay(n)       udelay((n)*1000)
+
+#define E1000_DEFAULT_PBA    0x00000030
+
+/* NIC specific static variables go here */
+
+static char tx_pool[128 + 16];
+static char rx_pool[128 + 16];
+static char packet[2096];
+
+static struct e1000_tx_desc *tx_base;
+static struct e1000_rx_desc *rx_base;
+
+static int tx_tail;
+static int rx_tail, rx_last;
+
+static struct pci_device_id supported[] = {
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82542},
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_FIBER},
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_COPPER},
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_COPPER},
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_FIBER},
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_COPPER},
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_LOM},
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM},
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_COPPER},
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_COPPER},
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_FIBER},
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER},
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM_LOM},
+};
+
+/* Function forward declarations */
+static int e1000_setup_link(struct eth_device *nic);
+static int e1000_setup_fiber_link(struct eth_device *nic);
+static int e1000_setup_copper_link(struct eth_device *nic);
+static int e1000_phy_setup_autoneg(struct e1000_hw *hw);
+static void e1000_config_collision_dist(struct e1000_hw *hw);
+static int e1000_config_mac_to_phy(struct e1000_hw *hw);
+static int e1000_config_fc_after_link_up(struct e1000_hw *hw);
+static int e1000_check_for_link(struct eth_device *nic);
+static int e1000_wait_autoneg(struct e1000_hw *hw);
+static void e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed,
+                                      uint16_t * duplex);
+static int e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr,
+                             uint16_t * phy_data);
+static int e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr,
+                              uint16_t phy_data);
+static void e1000_phy_hw_reset(struct e1000_hw *hw);
+static int e1000_phy_reset(struct e1000_hw *hw);
+static int e1000_detect_gig_phy(struct e1000_hw *hw);
+
+#define E1000_WRITE_REG(a, reg, value) (writel((value), ((a)->hw_addr + E1000_##reg)))
+#define E1000_READ_REG(a, reg) (readl((a)->hw_addr + E1000_##reg))
+#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) (\
+                       writel((value), ((a)->hw_addr + E1000_##reg + ((offset) << 2))))
+#define E1000_READ_REG_ARRAY(a, reg, offset) ( \
+       readl((a)->hw_addr + E1000_##reg + ((offset) << 2)))
+#define E1000_WRITE_FLUSH(a) {uint32_t x; x = E1000_READ_REG(a, STATUS);}
+
+#ifndef CONFIG_AP1000 /* remove for warnings */
+/******************************************************************************
+ * Raises the EEPROM's clock input.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * eecd - EECD's current value
+ *****************************************************************************/
+static void
+e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t * eecd)
+{
+       /* Raise the clock input to the EEPROM (by setting the SK bit), and then
+        * wait 50 microseconds.
+        */
+       *eecd = *eecd | E1000_EECD_SK;
+       E1000_WRITE_REG(hw, EECD, *eecd);
+       E1000_WRITE_FLUSH(hw);
+       udelay(50);
+}
+
+/******************************************************************************
+ * Lowers the EEPROM's clock input.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * eecd - EECD's current value
+ *****************************************************************************/
+static void
+e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t * eecd)
+{
+       /* Lower the clock input to the EEPROM (by clearing the SK bit), and then
+        * wait 50 microseconds.
+        */
+       *eecd = *eecd & ~E1000_EECD_SK;
+       E1000_WRITE_REG(hw, EECD, *eecd);
+       E1000_WRITE_FLUSH(hw);
+       udelay(50);
+}
+
+/******************************************************************************
+ * Shift data bits out to the EEPROM.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * data - data to send to the EEPROM
+ * count - number of bits to shift out
+ *****************************************************************************/
+static void
+e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t count)
+{
+       uint32_t eecd;
+       uint32_t mask;
+
+       /* We need to shift "count" bits out to the EEPROM. So, value in the
+        * "data" parameter will be shifted out to the EEPROM one bit at a time.
+        * In order to do this, "data" must be broken down into bits.
+        */
+       mask = 0x01 << (count - 1);
+       eecd = E1000_READ_REG(hw, EECD);
+       eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
+       do {
+               /* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
+                * and then raising and then lowering the clock (the SK bit controls
+                * the clock input to the EEPROM).  A "0" is shifted out to the EEPROM
+                * by setting "DI" to "0" and then raising and then lowering the clock.
+                */
+               eecd &= ~E1000_EECD_DI;
+
+               if (data & mask)
+                       eecd |= E1000_EECD_DI;
+
+               E1000_WRITE_REG(hw, EECD, eecd);
+               E1000_WRITE_FLUSH(hw);
+
+               udelay(50);
+
+               e1000_raise_ee_clk(hw, &eecd);
+               e1000_lower_ee_clk(hw, &eecd);
+
+               mask = mask >> 1;
+
+       } while (mask);
+
+       /* We leave the "DI" bit set to "0" when we leave this routine. */
+       eecd &= ~E1000_EECD_DI;
+       E1000_WRITE_REG(hw, EECD, eecd);
+}
+
+/******************************************************************************
+ * Shift data bits in from the EEPROM
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static uint16_t
+e1000_shift_in_ee_bits(struct e1000_hw *hw)
+{
+       uint32_t eecd;
+       uint32_t i;
+       uint16_t data;
+
+       /* In order to read a register from the EEPROM, we need to shift 16 bits
+        * in from the EEPROM. Bits are "shifted in" by raising the clock input to
+        * the EEPROM (setting the SK bit), and then reading the value of the "DO"
+        * bit.  During this "shifting in" process the "DI" bit should always be
+        * clear..
+        */
+
+       eecd = E1000_READ_REG(hw, EECD);
+
+       eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
+       data = 0;
+
+       for (i = 0; i < 16; i++) {
+               data = data << 1;
+               e1000_raise_ee_clk(hw, &eecd);
+
+               eecd = E1000_READ_REG(hw, EECD);
+
+               eecd &= ~(E1000_EECD_DI);
+               if (eecd & E1000_EECD_DO)
+                       data |= 1;
+
+               e1000_lower_ee_clk(hw, &eecd);
+       }
+
+       return data;
+}
+
+/******************************************************************************
+ * Prepares EEPROM for access
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
+ * function should be called before issuing a command to the EEPROM.
+ *****************************************************************************/
+static void
+e1000_setup_eeprom(struct e1000_hw *hw)
+{
+       uint32_t eecd;
+
+       eecd = E1000_READ_REG(hw, EECD);
+
+       /* Clear SK and DI */
+       eecd &= ~(E1000_EECD_SK | E1000_EECD_DI);
+       E1000_WRITE_REG(hw, EECD, eecd);
+
+       /* Set CS */
+       eecd |= E1000_EECD_CS;
+       E1000_WRITE_REG(hw, EECD, eecd);
+}
+
+/******************************************************************************
+ * Returns EEPROM to a "standby" state
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static void
+e1000_standby_eeprom(struct e1000_hw *hw)
+{
+       uint32_t eecd;
+
+       eecd = E1000_READ_REG(hw, EECD);
+
+       /* Deselct EEPROM */
+       eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
+       E1000_WRITE_REG(hw, EECD, eecd);
+       E1000_WRITE_FLUSH(hw);
+       udelay(50);
+
+       /* Clock high */
+       eecd |= E1000_EECD_SK;
+       E1000_WRITE_REG(hw, EECD, eecd);
+       E1000_WRITE_FLUSH(hw);
+       udelay(50);
+
+       /* Select EEPROM */
+       eecd |= E1000_EECD_CS;
+       E1000_WRITE_REG(hw, EECD, eecd);
+       E1000_WRITE_FLUSH(hw);
+       udelay(50);
+
+       /* Clock low */
+       eecd &= ~E1000_EECD_SK;
+       E1000_WRITE_REG(hw, EECD, eecd);
+       E1000_WRITE_FLUSH(hw);
+       udelay(50);
+}
+
+/******************************************************************************
+ * Reads a 16 bit word from the EEPROM.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * offset - offset of  word in the EEPROM to read
+ * data - word read from the EEPROM
+ *****************************************************************************/
+static int
+e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, uint16_t * data)
+{
+       uint32_t eecd;
+       uint32_t i = 0;
+       int large_eeprom = FALSE;
+
+       /* Request EEPROM Access */
+       if (hw->mac_type > e1000_82544) {
+               eecd = E1000_READ_REG(hw, EECD);
+               if (eecd & E1000_EECD_SIZE)
+                       large_eeprom = TRUE;
+               eecd |= E1000_EECD_REQ;
+               E1000_WRITE_REG(hw, EECD, eecd);
+               eecd = E1000_READ_REG(hw, EECD);
+               while ((!(eecd & E1000_EECD_GNT)) && (i < 100)) {
+                       i++;
+                       udelay(10);
+                       eecd = E1000_READ_REG(hw, EECD);
+               }
+               if (!(eecd & E1000_EECD_GNT)) {
+                       eecd &= ~E1000_EECD_REQ;
+                       E1000_WRITE_REG(hw, EECD, eecd);
+                       DEBUGOUT("Could not acquire EEPROM grant\n");
+                       return -E1000_ERR_EEPROM;
+               }
+       }
+
+       /*  Prepare the EEPROM for reading  */
+       e1000_setup_eeprom(hw);
+
+       /*  Send the READ command (opcode + addr)  */
+       e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE, 3);
+       e1000_shift_out_ee_bits(hw, offset, (large_eeprom) ? 8 : 6);
+
+       /* Read the data */
+       *data = e1000_shift_in_ee_bits(hw);
+
+       /* End this read operation */
+       e1000_standby_eeprom(hw);
+
+       /* Stop requesting EEPROM access */
+       if (hw->mac_type > e1000_82544) {
+               eecd = E1000_READ_REG(hw, EECD);
+               eecd &= ~E1000_EECD_REQ;
+               E1000_WRITE_REG(hw, EECD, eecd);
+       }
+
+       return 0;
+}
+
+#if 0
+static void
+e1000_eeprom_cleanup(struct e1000_hw *hw)
+{
+       uint32_t eecd;
+
+       eecd = E1000_READ_REG(hw, EECD);
+       eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
+       E1000_WRITE_REG(hw, EECD, eecd);
+       e1000_raise_ee_clk(hw, &eecd);
+       e1000_lower_ee_clk(hw, &eecd);
+}
+
+static uint16_t
+e1000_wait_eeprom_done(struct e1000_hw *hw)
+{
+       uint32_t eecd;
+       uint32_t i;
+
+       e1000_standby_eeprom(hw);
+       for (i = 0; i < 200; i++) {
+               eecd = E1000_READ_REG(hw, EECD);
+               if (eecd & E1000_EECD_DO)
+                       return (TRUE);
+               udelay(5);
+       }
+       return (FALSE);
+}
+
+static int
+e1000_write_eeprom(struct e1000_hw *hw, uint16_t Reg, uint16_t Data)
+{
+       uint32_t eecd;
+       int large_eeprom = FALSE;
+       int i = 0;
+
+       /* Request EEPROM Access */
+       if (hw->mac_type > e1000_82544) {
+               eecd = E1000_READ_REG(hw, EECD);
+               if (eecd & E1000_EECD_SIZE)
+                       large_eeprom = TRUE;
+               eecd |= E1000_EECD_REQ;
+               E1000_WRITE_REG(hw, EECD, eecd);
+               eecd = E1000_READ_REG(hw, EECD);
+               while ((!(eecd & E1000_EECD_GNT)) && (i < 100)) {
+                       i++;
+                       udelay(5);
+                       eecd = E1000_READ_REG(hw, EECD);
+               }
+               if (!(eecd & E1000_EECD_GNT)) {
+                       eecd &= ~E1000_EECD_REQ;
+                       E1000_WRITE_REG(hw, EECD, eecd);
+                       DEBUGOUT("Could not acquire EEPROM grant\n");
+                       return FALSE;
+               }
+       }
+       e1000_setup_eeprom(hw);
+       e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE, 5);
+       e1000_shift_out_ee_bits(hw, Reg, (large_eeprom) ? 6 : 4);
+       e1000_standby_eeprom(hw);
+       e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE, 3);
+       e1000_shift_out_ee_bits(hw, Reg, (large_eeprom) ? 8 : 6);
+       e1000_shift_out_ee_bits(hw, Data, 16);
+       if (!e1000_wait_eeprom_done(hw)) {
+               return FALSE;
+       }
+       e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE, 5);
+       e1000_shift_out_ee_bits(hw, Reg, (large_eeprom) ? 6 : 4);
+       e1000_eeprom_cleanup(hw);
+
+       /* Stop requesting EEPROM access */
+       if (hw->mac_type > e1000_82544) {
+               eecd = E1000_READ_REG(hw, EECD);
+               eecd &= ~E1000_EECD_REQ;
+               E1000_WRITE_REG(hw, EECD, eecd);
+       }
+       i = 0;
+       eecd = E1000_READ_REG(hw, EECD);
+       while (((eecd & E1000_EECD_GNT)) && (i < 500)) {
+               i++;
+               udelay(10);
+               eecd = E1000_READ_REG(hw, EECD);
+       }
+       if ((eecd & E1000_EECD_GNT)) {
+               DEBUGOUT("Could not release EEPROM grant\n");
+       }
+       return TRUE;
+}
+#endif
+
+/******************************************************************************
+ * Verifies that the EEPROM has a valid checksum
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Reads the first 64 16 bit words of the EEPROM and sums the values read.
+ * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
+ * valid.
+ *****************************************************************************/
+static int
+e1000_validate_eeprom_checksum(struct eth_device *nic)
+{
+       struct e1000_hw *hw = nic->priv;
+       uint16_t checksum = 0;
+       uint16_t i, eeprom_data;
+
+       DEBUGFUNC();
+
+       for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
+               if (e1000_read_eeprom(hw, i, &eeprom_data) < 0) {
+                       DEBUGOUT("EEPROM Read Error\n");
+                       return -E1000_ERR_EEPROM;
+               }
+               checksum += eeprom_data;
+       }
+
+       if (checksum == (uint16_t) EEPROM_SUM) {
+               return 0;
+       } else {
+               DEBUGOUT("EEPROM Checksum Invalid\n");
+               return -E1000_ERR_EEPROM;
+       }
+}
+#endif /* #ifndef CONFIG_AP1000 */
+
+/******************************************************************************
+ * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
+ * second function of dual function devices
+ *
+ * nic - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static int
+e1000_read_mac_addr(struct eth_device *nic)
+{
+#ifndef CONFIG_AP1000
+       struct e1000_hw *hw = nic->priv;
+       uint16_t offset;
+       uint16_t eeprom_data;
+       int i;
+
+       DEBUGFUNC();
+
+       for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
+               offset = i >> 1;
+               if (e1000_read_eeprom(hw, offset, &eeprom_data) < 0) {
+                       DEBUGOUT("EEPROM Read Error\n");
+                       return -E1000_ERR_EEPROM;
+               }
+               nic->enetaddr[i] = eeprom_data & 0xff;
+               nic->enetaddr[i + 1] = (eeprom_data >> 8) & 0xff;
+       }
+       if ((hw->mac_type == e1000_82546) &&
+           (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
+               /* Invert the last bit if this is the second device */
+               nic->enetaddr[5] += 1;
+       }
+#else
+       /*
+        * The AP1000's e1000 has no eeprom; the MAC address is stored in the
+        * environment variables.  Currently this does not support the addition
+        * of a PMC e1000 card, which is certainly a possibility, so this should
+        * be updated to properly use the env variable only for the onboard e1000
+        */
+
+       int ii;
+       char *s, *e;
+
+       DEBUGFUNC();
+
+       s = getenv ("ethaddr");
+       if (s == NULL){
+               return -E1000_ERR_EEPROM;
+       }
+       else{
+               for(ii = 0; ii < 6; ii++) {
+                       nic->enetaddr[ii] = s ? simple_strtoul (s, &e, 16) : 0;
+                       if (s){
+                               s = (*e) ? e + 1 : e;
+                       }
+               }
+       }
+#endif
+       return 0;
+}
+
+/******************************************************************************
+ * Initializes receive address filters.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Places the MAC address in receive address register 0 and clears the rest
+ * of the receive addresss registers. Clears the multicast table. Assumes
+ * the receiver is in reset when the routine is called.
+ *****************************************************************************/
+static void
+e1000_init_rx_addrs(struct eth_device *nic)
+{
+       struct e1000_hw *hw = nic->priv;
+       uint32_t i;
+       uint32_t addr_low;
+       uint32_t addr_high;
+
+       DEBUGFUNC();
+
+       /* Setup the receive address. */
+       DEBUGOUT("Programming MAC Address into RAR[0]\n");
+       addr_low = (nic->enetaddr[0] |
+                   (nic->enetaddr[1] << 8) |
+                   (nic->enetaddr[2] << 16) | (nic->enetaddr[3] << 24));
+
+       addr_high = (nic->enetaddr[4] | (nic->enetaddr[5] << 8) | E1000_RAH_AV);
+
+       E1000_WRITE_REG_ARRAY(hw, RA, 0, addr_low);
+       E1000_WRITE_REG_ARRAY(hw, RA, 1, addr_high);
+
+       /* Zero out the other 15 receive addresses. */
+       DEBUGOUT("Clearing RAR[1-15]\n");
+       for (i = 1; i < E1000_RAR_ENTRIES; i++) {
+               E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
+               E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
+       }
+}
+
+/******************************************************************************
+ * Clears the VLAN filer table
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static void
+e1000_clear_vfta(struct e1000_hw *hw)
+{
+       uint32_t offset;
+
+       for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++)
+               E1000_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
+}
+
+/******************************************************************************
+ * Set the mac type member in the hw struct.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static int
+e1000_set_mac_type(struct e1000_hw *hw)
+{
+       DEBUGFUNC();
+
+       switch (hw->device_id) {
+       case E1000_DEV_ID_82542:
+               switch (hw->revision_id) {
+               case E1000_82542_2_0_REV_ID:
+                       hw->mac_type = e1000_82542_rev2_0;
+                       break;
+               case E1000_82542_2_1_REV_ID:
+                       hw->mac_type = e1000_82542_rev2_1;
+                       break;
+               default:
+                       /* Invalid 82542 revision ID */
+                       return -E1000_ERR_MAC_TYPE;
+               }
+               break;
+       case E1000_DEV_ID_82543GC_FIBER:
+       case E1000_DEV_ID_82543GC_COPPER:
+               hw->mac_type = e1000_82543;
+               break;
+       case E1000_DEV_ID_82544EI_COPPER:
+       case E1000_DEV_ID_82544EI_FIBER:
+       case E1000_DEV_ID_82544GC_COPPER:
+       case E1000_DEV_ID_82544GC_LOM:
+               hw->mac_type = e1000_82544;
+               break;
+       case E1000_DEV_ID_82540EM:
+       case E1000_DEV_ID_82540EM_LOM:
+               hw->mac_type = e1000_82540;
+               break;
+       case E1000_DEV_ID_82545EM_COPPER:
+       case E1000_DEV_ID_82545EM_FIBER:
+               hw->mac_type = e1000_82545;
+               break;
+       case E1000_DEV_ID_82546EB_COPPER:
+       case E1000_DEV_ID_82546EB_FIBER:
+               hw->mac_type = e1000_82546;
+               break;
+       default:
+               /* Should never have loaded on this device */
+               return -E1000_ERR_MAC_TYPE;
+       }
+       return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Reset the transmit and receive units; mask and clear all interrupts.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+void
+e1000_reset_hw(struct e1000_hw *hw)
+{
+       uint32_t ctrl;
+       uint32_t ctrl_ext;
+       uint32_t icr;
+       uint32_t manc;
+
+       DEBUGFUNC();
+
+       /* For 82542 (rev 2.0), disable MWI before issuing a device reset */
+       if (hw->mac_type == e1000_82542_rev2_0) {
+               DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
+               pci_write_config_word(hw->pdev, PCI_COMMAND,
+                                     hw->
+                                     pci_cmd_word & ~PCI_COMMAND_INVALIDATE);
+       }
+
+       /* Clear interrupt mask to stop board from generating interrupts */
+       DEBUGOUT("Masking off all interrupts\n");
+       E1000_WRITE_REG(hw, IMC, 0xffffffff);
+
+       /* Disable the Transmit and Receive units.  Then delay to allow
+        * any pending transactions to complete before we hit the MAC with
+        * the global reset.
+        */
+       E1000_WRITE_REG(hw, RCTL, 0);
+       E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP);
+       E1000_WRITE_FLUSH(hw);
+
+       /* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
+       hw->tbi_compatibility_on = FALSE;
+
+       /* Delay to allow any outstanding PCI transactions to complete before
+        * resetting the device
+        */
+       mdelay(10);
+
+       /* Issue a global reset to the MAC.  This will reset the chip's
+        * transmit, receive, DMA, and link units.  It will not effect
+        * the current PCI configuration.  The global reset bit is self-
+        * clearing, and should clear within a microsecond.
+        */
+       DEBUGOUT("Issuing a global reset to MAC\n");
+       ctrl = E1000_READ_REG(hw, CTRL);
+
+#if 0
+       if (hw->mac_type > e1000_82543)
+               E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
+       else
+#endif
+               E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
+
+       /* Force a reload from the EEPROM if necessary */
+       if (hw->mac_type < e1000_82540) {
+               /* Wait for reset to complete */
+               udelay(10);
+               ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+               ctrl_ext |= E1000_CTRL_EXT_EE_RST;
+               E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+               E1000_WRITE_FLUSH(hw);
+               /* Wait for EEPROM reload */
+               mdelay(2);
+       } else {
+               /* Wait for EEPROM reload (it happens automatically) */
+               mdelay(4);
+               /* Dissable HW ARPs on ASF enabled adapters */
+               manc = E1000_READ_REG(hw, MANC);
+               manc &= ~(E1000_MANC_ARP_EN);
+               E1000_WRITE_REG(hw, MANC, manc);
+       }
+
+       /* Clear interrupt mask to stop board from generating interrupts */
+       DEBUGOUT("Masking off all interrupts\n");
+       E1000_WRITE_REG(hw, IMC, 0xffffffff);
+
+       /* Clear any pending interrupt events. */
+       icr = E1000_READ_REG(hw, ICR);
+
+       /* If MWI was previously enabled, reenable it. */
+       if (hw->mac_type == e1000_82542_rev2_0) {
+               pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word);
+       }
+}
+
+/******************************************************************************
+ * Performs basic configuration of the adapter.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Assumes that the controller has previously been reset and is in a
+ * post-reset uninitialized state. Initializes the receive address registers,
+ * multicast table, and VLAN filter table. Calls routines to setup link
+ * configuration and flow control settings. Clears all on-chip counters. Leaves
+ * the transmit and receive units disabled and uninitialized.
+ *****************************************************************************/
+static int
+e1000_init_hw(struct eth_device *nic)
+{
+       struct e1000_hw *hw = nic->priv;
+       uint32_t ctrl, status;
+       uint32_t i;
+       int32_t ret_val;
+       uint16_t pcix_cmd_word;
+       uint16_t pcix_stat_hi_word;
+       uint16_t cmd_mmrbc;
+       uint16_t stat_mmrbc;
+       e1000_bus_type bus_type = e1000_bus_type_unknown;
+
+       DEBUGFUNC();
+#if 0
+       /* Initialize Identification LED */
+       ret_val = e1000_id_led_init(hw);
+       if (ret_val < 0) {
+               DEBUGOUT("Error Initializing Identification LED\n");
+               return ret_val;
+       }
+#endif
+       /* Set the Media Type and exit with error if it is not valid. */
+       if (hw->mac_type != e1000_82543) {
+               /* tbi_compatibility is only valid on 82543 */
+               hw->tbi_compatibility_en = FALSE;
+       }
+
+       if (hw->mac_type >= e1000_82543) {
+               status = E1000_READ_REG(hw, STATUS);
+               if (status & E1000_STATUS_TBIMODE) {
+                       hw->media_type = e1000_media_type_fiber;
+                       /* tbi_compatibility not valid on fiber */
+                       hw->tbi_compatibility_en = FALSE;
+               } else {
+                       hw->media_type = e1000_media_type_copper;
+               }
+       } else {
+               /* This is an 82542 (fiber only) */
+               hw->media_type = e1000_media_type_fiber;
+       }
+
+       /* Disabling VLAN filtering. */
+       DEBUGOUT("Initializing the IEEE VLAN\n");
+       E1000_WRITE_REG(hw, VET, 0);
+
+       e1000_clear_vfta(hw);
+
+       /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
+       if (hw->mac_type == e1000_82542_rev2_0) {
+               DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
+               pci_write_config_word(hw->pdev, PCI_COMMAND,
+                                     hw->
+                                     pci_cmd_word & ~PCI_COMMAND_INVALIDATE);
+               E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST);
+               E1000_WRITE_FLUSH(hw);
+               mdelay(5);
+       }
+
+       /* Setup the receive address. This involves initializing all of the Receive
+        * Address Registers (RARs 0 - 15).
+        */
+       e1000_init_rx_addrs(nic);
+
+       /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
+       if (hw->mac_type == e1000_82542_rev2_0) {
+               E1000_WRITE_REG(hw, RCTL, 0);
+               E1000_WRITE_FLUSH(hw);
+               mdelay(1);
+               pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word);
+       }
+
+       /* Zero out the Multicast HASH table */
+       DEBUGOUT("Zeroing the MTA\n");
+       for (i = 0; i < E1000_MC_TBL_SIZE; i++)
+               E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
+
+#if 0
+       /* Set the PCI priority bit correctly in the CTRL register.  This
+        * determines if the adapter gives priority to receives, or if it
+        * gives equal priority to transmits and receives.
+        */
+       if (hw->dma_fairness) {
+               ctrl = E1000_READ_REG(hw, CTRL);
+               E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);
+       }
+#endif
+       if (hw->mac_type >= e1000_82543) {
+               status = E1000_READ_REG(hw, STATUS);
+               bus_type = (status & E1000_STATUS_PCIX_MODE) ?
+                   e1000_bus_type_pcix : e1000_bus_type_pci;
+       }
+       /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
+       if (bus_type == e1000_bus_type_pcix) {
+               pci_read_config_word(hw->pdev, PCIX_COMMAND_REGISTER,
+                                    &pcix_cmd_word);
+               pci_read_config_word(hw->pdev, PCIX_STATUS_REGISTER_HI,
+                                    &pcix_stat_hi_word);
+               cmd_mmrbc =
+                   (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >>
+                   PCIX_COMMAND_MMRBC_SHIFT;
+               stat_mmrbc =
+                   (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
+                   PCIX_STATUS_HI_MMRBC_SHIFT;
+               if (stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
+                       stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
+               if (cmd_mmrbc > stat_mmrbc) {
+                       pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;
+                       pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
+                       pci_write_config_word(hw->pdev, PCIX_COMMAND_REGISTER,
+                                             pcix_cmd_word);
+               }
+       }
+
+       /* Call a subroutine to configure the link and setup flow control. */
+       ret_val = e1000_setup_link(nic);
+
+       /* Set the transmit descriptor write-back policy */
+       if (hw->mac_type > e1000_82544) {
+               ctrl = E1000_READ_REG(hw, TXDCTL);
+               ctrl =
+                   (ctrl & ~E1000_TXDCTL_WTHRESH) |
+                   E1000_TXDCTL_FULL_TX_DESC_WB;
+               E1000_WRITE_REG(hw, TXDCTL, ctrl);
+       }
+#if 0
+       /* Clear all of the statistics registers (clear on read).  It is
+        * important that we do this after we have tried to establish link
+        * because the symbol error count will increment wildly if there
+        * is no link.
+        */
+       e1000_clear_hw_cntrs(hw);
+#endif
+
+       return ret_val;
+}
+
+/******************************************************************************
+ * Configures flow control and link settings.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Determines which flow control settings to use. Calls the apropriate media-
+ * specific link configuration function. Configures the flow control settings.
+ * Assuming the adapter has a valid link partner, a valid link should be
+ * established. Assumes the hardware has previously been reset and the
+ * transmitter and receiver are not enabled.
+ *****************************************************************************/
+static int
+e1000_setup_link(struct eth_device *nic)
+{
+       struct e1000_hw *hw = nic->priv;
+       uint32_t ctrl_ext;
+       int32_t ret_val;
+       uint16_t eeprom_data;
+
+       DEBUGFUNC();
+
+#ifndef CONFIG_AP1000
+       /* Read and store word 0x0F of the EEPROM. This word contains bits
+        * that determine the hardware's default PAUSE (flow control) mode,
+        * a bit that determines whether the HW defaults to enabling or
+        * disabling auto-negotiation, and the direction of the
+        * SW defined pins. If there is no SW over-ride of the flow
+        * control setting, then the variable hw->fc will
+        * be initialized based on a value in the EEPROM.
+        */
+       if (e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, &eeprom_data) < 0) {
+               DEBUGOUT("EEPROM Read Error\n");
+               return -E1000_ERR_EEPROM;
+       }
+#else
+       /* we have to hardcode the proper value for our hardware. */
+       /* this value is for the 82540EM pci card used for prototyping, and it works. */
+       eeprom_data = 0xb220;
+#endif
+
+       if (hw->fc == e1000_fc_default) {
+               if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
+                       hw->fc = e1000_fc_none;
+               else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
+                        EEPROM_WORD0F_ASM_DIR)
+                       hw->fc = e1000_fc_tx_pause;
+               else
+                       hw->fc = e1000_fc_full;
+       }
+
+       /* We want to save off the original Flow Control configuration just
+        * in case we get disconnected and then reconnected into a different
+        * hub or switch with different Flow Control capabilities.
+        */
+       if (hw->mac_type == e1000_82542_rev2_0)
+               hw->fc &= (~e1000_fc_tx_pause);
+
+       if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
+               hw->fc &= (~e1000_fc_rx_pause);
+
+       hw->original_fc = hw->fc;
+
+       DEBUGOUT("After fix-ups FlowControl is now = %x\n", hw->fc);
+
+       /* Take the 4 bits from EEPROM word 0x0F that determine the initial
+        * polarity value for the SW controlled pins, and setup the
+        * Extended Device Control reg with that info.
+        * This is needed because one of the SW controlled pins is used for
+        * signal detection.  So this should be done before e1000_setup_pcs_link()
+        * or e1000_phy_setup() is called.
+        */
+       if (hw->mac_type == e1000_82543) {
+               ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) <<
+                           SWDPIO__EXT_SHIFT);
+               E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+       }
+
+       /* Call the necessary subroutine to configure the link. */
+       ret_val = (hw->media_type == e1000_media_type_fiber) ?
+           e1000_setup_fiber_link(nic) : e1000_setup_copper_link(nic);
+       if (ret_val < 0) {
+               return ret_val;
+       }
+
+       /* Initialize the flow control address, type, and PAUSE timer
+        * registers to their default values.  This is done even if flow
+        * control is disabled, because it does not hurt anything to
+        * initialize these registers.
+        */
+       DEBUGOUT
+           ("Initializing the Flow Control address, type and timer regs\n");
+
+       E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW);
+       E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH);
+       E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE);
+       E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time);
+
+       /* Set the flow control receive threshold registers.  Normally,
+        * these registers will be set to a default threshold that may be
+        * adjusted later by the driver's runtime code.  However, if the
+        * ability to transmit pause frames in not enabled, then these
+        * registers will be set to 0.
+        */
+       if (!(hw->fc & e1000_fc_tx_pause)) {
+               E1000_WRITE_REG(hw, FCRTL, 0);
+               E1000_WRITE_REG(hw, FCRTH, 0);
+       } else {
+               /* We need to set up the Receive Threshold high and low water marks
+                * as well as (optionally) enabling the transmission of XON frames.
+                */
+               if (hw->fc_send_xon) {
+                       E1000_WRITE_REG(hw, FCRTL,
+                                       (hw->fc_low_water | E1000_FCRTL_XONE));
+                       E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
+               } else {
+                       E1000_WRITE_REG(hw, FCRTL, hw->fc_low_water);
+                       E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
+               }
+       }
+       return ret_val;
+}
+
+/******************************************************************************
+ * Sets up link for a fiber based adapter
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Manipulates Physical Coding Sublayer functions in order to configure
+ * link. Assumes the hardware has been previously reset and the transmitter
+ * and receiver are not enabled.
+ *****************************************************************************/
+static int
+e1000_setup_fiber_link(struct eth_device *nic)
+{
+       struct e1000_hw *hw = nic->priv;
+       uint32_t ctrl;
+       uint32_t status;
+       uint32_t txcw = 0;
+       uint32_t i;
+       uint32_t signal;
+       int32_t ret_val;
+
+       DEBUGFUNC();
+       /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be
+        * set when the optics detect a signal. On older adapters, it will be
+        * cleared when there is a signal
+        */
+       ctrl = E1000_READ_REG(hw, CTRL);
+       if ((hw->mac_type > e1000_82544) && !(ctrl & E1000_CTRL_ILOS))
+               signal = E1000_CTRL_SWDPIN1;
+       else
+               signal = 0;
+
+       printf("signal for %s is %x (ctrl %08x)!!!!\n", nic->name, signal,
+              ctrl);
+       /* Take the link out of reset */
+       ctrl &= ~(E1000_CTRL_LRST);
+
+       e1000_config_collision_dist(hw);
+
+       /* Check for a software override of the flow control settings, and setup
+        * the device accordingly.  If auto-negotiation is enabled, then software
+        * will have to set the "PAUSE" bits to the correct value in the Tranmsit
+        * Config Word Register (TXCW) and re-start auto-negotiation.  However, if
+        * auto-negotiation is disabled, then software will have to manually
+        * configure the two flow control enable bits in the CTRL register.
+        *
+        * The possible values of the "fc" parameter are:
+        *      0:  Flow control is completely disabled
+        *      1:  Rx flow control is enabled (we can receive pause frames, but
+        *          not send pause frames).
+        *      2:  Tx flow control is enabled (we can send pause frames but we do
+        *          not support receiving pause frames).
+        *      3:  Both Rx and TX flow control (symmetric) are enabled.
+        */
+       switch (hw->fc) {
+       case e1000_fc_none:
+               /* Flow control is completely disabled by a software over-ride. */
+               txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
+               break;
+       case e1000_fc_rx_pause:
+               /* RX Flow control is enabled and TX Flow control is disabled by a
+                * software over-ride. Since there really isn't a way to advertise
+                * that we are capable of RX Pause ONLY, we will advertise that we
+                * support both symmetric and asymmetric RX PAUSE. Later, we will
+                *  disable the adapter's ability to send PAUSE frames.
+                */
+               txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
+               break;
+       case e1000_fc_tx_pause:
+               /* TX Flow control is enabled, and RX Flow control is disabled, by a
+                * software over-ride.
+                */
+               txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
+               break;
+       case e1000_fc_full:
+               /* Flow control (both RX and TX) is enabled by a software over-ride. */
+               txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
+               break;
+       default:
+               DEBUGOUT("Flow control param set incorrectly\n");
+               return -E1000_ERR_CONFIG;
+               break;
+       }
+
+       /* Since auto-negotiation is enabled, take the link out of reset (the link
+        * will be in reset, because we previously reset the chip). This will
+        * restart auto-negotiation.  If auto-neogtiation is successful then the
+        * link-up status bit will be set and the flow control enable bits (RFCE
+        * and TFCE) will be set according to their negotiated value.
+        */
+       DEBUGOUT("Auto-negotiation enabled (%#x)\n", txcw);
+
+       E1000_WRITE_REG(hw, TXCW, txcw);
+       E1000_WRITE_REG(hw, CTRL, ctrl);
+       E1000_WRITE_FLUSH(hw);
+
+       hw->txcw = txcw;
+       mdelay(1);
+
+       /* If we have a signal (the cable is plugged in) then poll for a "Link-Up"
+        * indication in the Device Status Register.  Time-out if a link isn't
+        * seen in 500 milliseconds seconds (Auto-negotiation should complete in
+        * less than 500 milliseconds even if the other end is doing it in SW).
+        */
+       if ((E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) {
+               DEBUGOUT("Looking for Link\n");
+               for (i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
+                       mdelay(10);
+                       status = E1000_READ_REG(hw, STATUS);
+                       if (status & E1000_STATUS_LU)
+                               break;
+               }
+               if (i == (LINK_UP_TIMEOUT / 10)) {
+                       /* AutoNeg failed to achieve a link, so we'll call
+                        * e1000_check_for_link. This routine will force the link up if we
+                        * detect a signal. This will allow us to communicate with
+                        * non-autonegotiating link partners.
+                        */
+                       DEBUGOUT("Never got a valid link from auto-neg!!!\n");
+                       hw->autoneg_failed = 1;
+                       ret_val = e1000_check_for_link(nic);
+                       if (ret_val < 0) {
+                               DEBUGOUT("Error while checking for link\n");
+                               return ret_val;
+                       }
+                       hw->autoneg_failed = 0;
+               } else {
+                       hw->autoneg_failed = 0;
+                       DEBUGOUT("Valid Link Found\n");
+               }
+       } else {
+               DEBUGOUT("No Signal Detected\n");
+               return -E1000_ERR_NOLINK;
+       }
+       return 0;
+}
+
+/******************************************************************************
+* Detects which PHY is present and the speed and duplex
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static int
+e1000_setup_copper_link(struct eth_device *nic)
+{
+       struct e1000_hw *hw = nic->priv;
+       uint32_t ctrl;
+       int32_t ret_val;
+       uint16_t i;
+       uint16_t phy_data;
+
+       DEBUGFUNC();
+
+       ctrl = E1000_READ_REG(hw, CTRL);
+       /* With 82543, we need to force speed and duplex on the MAC equal to what
+        * the PHY speed and duplex configuration is. In addition, we need to
+        * perform a hardware reset on the PHY to take it out of reset.
+        */
+       if (hw->mac_type > e1000_82543) {
+               ctrl |= E1000_CTRL_SLU;
+               ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
+               E1000_WRITE_REG(hw, CTRL, ctrl);
+       } else {
+               ctrl |=
+                   (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU);
+               E1000_WRITE_REG(hw, CTRL, ctrl);
+               e1000_phy_hw_reset(hw);
+       }
+
+       /* Make sure we have a valid PHY */
+       ret_val = e1000_detect_gig_phy(hw);
+       if (ret_val < 0) {
+               DEBUGOUT("Error, did not detect valid phy.\n");
+               return ret_val;
+       }
+       DEBUGOUT("Phy ID = %x \n", hw->phy_id);
+
+       /* Enable CRS on TX. This must be set for half-duplex operation. */
+       if (e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
+               DEBUGOUT("PHY Read Error\n");
+               return -E1000_ERR_PHY;
+       }
+       phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+
+#if 0
+       /* Options:
+        *   MDI/MDI-X = 0 (default)
+        *   0 - Auto for all speeds
+        *   1 - MDI mode
+        *   2 - MDI-X mode
+        *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
+        */
+       phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+       switch (hw->mdix) {
+       case 1:
+               phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
+               break;
+       case 2:
+               phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
+               break;
+       case 3:
+               phy_data |= M88E1000_PSCR_AUTO_X_1000T;
+               break;
+       case 0:
+       default:
+               phy_data |= M88E1000_PSCR_AUTO_X_MODE;
+               break;
+       }
+#else
+       phy_data |= M88E1000_PSCR_AUTO_X_MODE;
+#endif
+
+#if 0
+       /* Options:
+        *   disable_polarity_correction = 0 (default)
+        *       Automatic Correction for Reversed Cable Polarity
+        *   0 - Disabled
+        *   1 - Enabled
+        */
+       phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
+       if (hw->disable_polarity_correction == 1)
+               phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
+#else
+       phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
+#endif
+       if (e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) {
+               DEBUGOUT("PHY Write Error\n");
+               return -E1000_ERR_PHY;
+       }
+
+       /* Force TX_CLK in the Extended PHY Specific Control Register
+        * to 25MHz clock.
+        */
+       if (e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data) < 0) {
+               DEBUGOUT("PHY Read Error\n");
+               return -E1000_ERR_PHY;
+       }
+       phy_data |= M88E1000_EPSCR_TX_CLK_25;
+       /* Configure Master and Slave downshift values */
+       phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
+                     M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
+       phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
+                    M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
+       if (e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data) < 0) {
+               DEBUGOUT("PHY Write Error\n");
+               return -E1000_ERR_PHY;
+       }
+
+       /* SW Reset the PHY so all changes take effect */
+       ret_val = e1000_phy_reset(hw);
+       if (ret_val < 0) {
+               DEBUGOUT("Error Resetting the PHY\n");
+               return ret_val;
+       }
+
+       /* Options:
+        *   autoneg = 1 (default)
+        *      PHY will advertise value(s) parsed from
+        *      autoneg_advertised and fc
+        *   autoneg = 0
+        *      PHY will be set to 10H, 10F, 100H, or 100F
+        *      depending on value parsed from forced_speed_duplex.
+        */
+
+       /* Is autoneg enabled?  This is enabled by default or by software override.
+        * If so, call e1000_phy_setup_autoneg routine to parse the
+        * autoneg_advertised and fc options. If autoneg is NOT enabled, then the
+        * user should have provided a speed/duplex override.  If so, then call
+        * e1000_phy_force_speed_duplex to parse and set this up.
+        */
+       /* Perform some bounds checking on the hw->autoneg_advertised
+        * parameter.  If this variable is zero, then set it to the default.
+        */
+       hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
+
+       /* If autoneg_advertised is zero, we assume it was not defaulted
+        * by the calling code so we set to advertise full capability.
+        */
+       if (hw->autoneg_advertised == 0)
+               hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+
+       DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
+       ret_val = e1000_phy_setup_autoneg(hw);
+       if (ret_val < 0) {
+               DEBUGOUT("Error Setting up Auto-Negotiation\n");
+               return ret_val;
+       }
+       DEBUGOUT("Restarting Auto-Neg\n");
+
+       /* Restart auto-negotiation by setting the Auto Neg Enable bit and
+        * the Auto Neg Restart bit in the PHY control register.
+        */
+       if (e1000_read_phy_reg(hw, PHY_CTRL, &phy_data) < 0) {
+               DEBUGOUT("PHY Read Error\n");
+               return -E1000_ERR_PHY;
+       }
+       phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
+       if (e1000_write_phy_reg(hw, PHY_CTRL, phy_data) < 0) {
+               DEBUGOUT("PHY Write Error\n");
+               return -E1000_ERR_PHY;
+       }
+#if 0
+       /* Does the user want to wait for Auto-Neg to complete here, or
+        * check at a later time (for example, callback routine).
+        */
+       if (hw->wait_autoneg_complete) {
+               ret_val = e1000_wait_autoneg(hw);
+               if (ret_val < 0) {
+                       DEBUGOUT
+                           ("Error while waiting for autoneg to complete\n");
+                       return ret_val;
+               }
+       }
+#else
+       /* If we do not wait for autonegtation to complete I
+        * do not see a valid link status.
+        */
+       ret_val = e1000_wait_autoneg(hw);
+       if (ret_val < 0) {
+               DEBUGOUT("Error while waiting for autoneg to complete\n");
+               return ret_val;
+       }
+#endif
+
+       /* Check link status. Wait up to 100 microseconds for link to become
+        * valid.
+        */
+       for (i = 0; i < 10; i++) {
+               if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+                       DEBUGOUT("PHY Read Error\n");
+                       return -E1000_ERR_PHY;
+               }
+               if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+                       DEBUGOUT("PHY Read Error\n");
+                       return -E1000_ERR_PHY;
+               }
+               if (phy_data & MII_SR_LINK_STATUS) {
+                       /* We have link, so we need to finish the config process:
+                        *   1) Set up the MAC to the current PHY speed/duplex
+                        *      if we are on 82543.  If we
+                        *      are on newer silicon, we only need to configure
+                        *      collision distance in the Transmit Control Register.
+                        *   2) Set up flow control on the MAC to that established with
+                        *      the link partner.
+                        */
+                       if (hw->mac_type >= e1000_82544) {
+                               e1000_config_collision_dist(hw);
+                       } else {
+                               ret_val = e1000_config_mac_to_phy(hw);
+                               if (ret_val < 0) {
+                                       DEBUGOUT
+                                           ("Error configuring MAC to PHY settings\n");
+                                       return ret_val;
+                               }
+                       }
+                       ret_val = e1000_config_fc_after_link_up(hw);
+                       if (ret_val < 0) {
+                               DEBUGOUT("Error Configuring Flow Control\n");
+                               return ret_val;
+                       }
+                       DEBUGOUT("Valid link established!!!\n");
+                       return 0;
+               }
+               udelay(10);
+       }
+
+       DEBUGOUT("Unable to establish link!!!\n");
+       return -E1000_ERR_NOLINK;
+}
+
+/******************************************************************************
+* Configures PHY autoneg and flow control advertisement settings
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static int
+e1000_phy_setup_autoneg(struct e1000_hw *hw)
+{
+       uint16_t mii_autoneg_adv_reg;
+       uint16_t mii_1000t_ctrl_reg;
+
+       DEBUGFUNC();
+
+       /* Read the MII Auto-Neg Advertisement Register (Address 4). */
+       if (e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg) < 0) {
+               DEBUGOUT("PHY Read Error\n");
+               return -E1000_ERR_PHY;
+       }
+
+       /* Read the MII 1000Base-T Control Register (Address 9). */
+       if (e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg) < 0) {
+               DEBUGOUT("PHY Read Error\n");
+               return -E1000_ERR_PHY;
+       }
+
+       /* Need to parse both autoneg_advertised and fc and set up
+        * the appropriate PHY registers.  First we will parse for
+        * autoneg_advertised software override.  Since we can advertise
+        * a plethora of combinations, we need to check each bit
+        * individually.
+        */
+
+       /* First we clear all the 10/100 mb speed bits in the Auto-Neg
+        * Advertisement Register (Address 4) and the 1000 mb speed bits in
+        * the  1000Base-T Control Register (Address 9).
+        */
+       mii_autoneg_adv_reg &= ~REG4_SPEED_MASK;
+       mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
+
+       DEBUGOUT("autoneg_advertised %x\n", hw->autoneg_advertised);
+
+       /* Do we want to advertise 10 Mb Half Duplex? */
+       if (hw->autoneg_advertised & ADVERTISE_10_HALF) {
+               DEBUGOUT("Advertise 10mb Half duplex\n");
+               mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
+       }
+
+       /* Do we want to advertise 10 Mb Full Duplex? */
+       if (hw->autoneg_advertised & ADVERTISE_10_FULL) {
+               DEBUGOUT("Advertise 10mb Full duplex\n");
+               mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
+       }
+
+       /* Do we want to advertise 100 Mb Half Duplex? */
+       if (hw->autoneg_advertised & ADVERTISE_100_HALF) {
+               DEBUGOUT("Advertise 100mb Half duplex\n");
+               mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
+       }
+
+       /* Do we want to advertise 100 Mb Full Duplex? */
+       if (hw->autoneg_advertised & ADVERTISE_100_FULL) {
+               DEBUGOUT("Advertise 100mb Full duplex\n");
+               mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
+       }
+
+       /* We do not allow the Phy to advertise 1000 Mb Half Duplex */
+       if (hw->autoneg_advertised & ADVERTISE_1000_HALF) {
+               DEBUGOUT
+                   ("Advertise 1000mb Half duplex requested, request denied!\n");
+       }
+
+       /* Do we want to advertise 1000 Mb Full Duplex? */
+       if (hw->autoneg_advertised & ADVERTISE_1000_FULL) {
+               DEBUGOUT("Advertise 1000mb Full duplex\n");
+               mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
+       }
+
+       /* Check for a software override of the flow control settings, and
+        * setup the PHY advertisement registers accordingly.  If
+        * auto-negotiation is enabled, then software will have to set the
+        * "PAUSE" bits to the correct value in the Auto-Negotiation
+        * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-negotiation.
+        *
+        * The possible values of the "fc" parameter are:
+        *      0:  Flow control is completely disabled
+        *      1:  Rx flow control is enabled (we can receive pause frames
+        *          but not send pause frames).
+        *      2:  Tx flow control is enabled (we can send pause frames
+        *          but we do not support receiving pause frames).
+        *      3:  Both Rx and TX flow control (symmetric) are enabled.
+        *  other:  No software override.  The flow control configuration
+        *          in the EEPROM is used.
+        */
+       switch (hw->fc) {
+       case e1000_fc_none:     /* 0 */
+               /* Flow control (RX & TX) is completely disabled by a
+                * software over-ride.
+                */
+               mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
+               break;
+       case e1000_fc_rx_pause: /* 1 */
+               /* RX Flow control is enabled, and TX Flow control is
+                * disabled, by a software over-ride.
+                */
+               /* Since there really isn't a way to advertise that we are
+                * capable of RX Pause ONLY, we will advertise that we
+                * support both symmetric and asymmetric RX PAUSE.  Later
+                * (in e1000_config_fc_after_link_up) we will disable the
+                *hw's ability to send PAUSE frames.
+                */
+               mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
+               break;
+       case e1000_fc_tx_pause: /* 2 */
+               /* TX Flow control is enabled, and RX Flow control is
+                * disabled, by a software over-ride.
+                */
+               mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
+               mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
+               break;
+       case e1000_fc_full:     /* 3 */
+               /* Flow control (both RX and TX) is enabled by a software
+                * over-ride.
+                */
+               mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
+               break;
+       default:
+               DEBUGOUT("Flow control param set incorrectly\n");
+               return -E1000_ERR_CONFIG;
+       }
+
+       if (e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg) < 0) {
+               DEBUGOUT("PHY Write Error\n");
+               return -E1000_ERR_PHY;
+       }
+
+       DEBUGOUT("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
+
+       if (e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg) < 0) {
+               DEBUGOUT("PHY Write Error\n");
+               return -E1000_ERR_PHY;
+       }
+       return 0;
+}
+
+/******************************************************************************
+* Sets the collision distance in the Transmit Control register
+*
+* hw - Struct containing variables accessed by shared code
+*
+* Link should have been established previously. Reads the speed and duplex
+* information from the Device Status register.
+******************************************************************************/
+static void
+e1000_config_collision_dist(struct e1000_hw *hw)
+{
+       uint32_t tctl;
+
+       tctl = E1000_READ_REG(hw, TCTL);
+
+       tctl &= ~E1000_TCTL_COLD;
+       tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
+
+       E1000_WRITE_REG(hw, TCTL, tctl);
+       E1000_WRITE_FLUSH(hw);
+}
+
+/******************************************************************************
+* Sets MAC speed and duplex settings to reflect the those in the PHY
+*
+* hw - Struct containing variables accessed by shared code
+* mii_reg - data to write to the MII control register
+*
+* The contents of the PHY register containing the needed information need to
+* be passed in.
+******************************************************************************/
+static int
+e1000_config_mac_to_phy(struct e1000_hw *hw)
+{
+       uint32_t ctrl;
+       uint16_t phy_data;
+
+       DEBUGFUNC();
+
+       /* Read the Device Control Register and set the bits to Force Speed
+        * and Duplex.
+        */
+       ctrl = E1000_READ_REG(hw, CTRL);
+       ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
+       ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);
+
+       /* Set up duplex in the Device Control and Transmit Control
+        * registers depending on negotiated values.
+        */
+       if (e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) {
+               DEBUGOUT("PHY Read Error\n");
+               return -E1000_ERR_PHY;
+       }
+       if (phy_data & M88E1000_PSSR_DPLX)
+               ctrl |= E1000_CTRL_FD;
+       else
+               ctrl &= ~E1000_CTRL_FD;
+
+       e1000_config_collision_dist(hw);
+
+       /* Set up speed in the Device Control register depending on
+        * negotiated values.
+        */
+       if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
+               ctrl |= E1000_CTRL_SPD_1000;
+       else if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
+               ctrl |= E1000_CTRL_SPD_100;
+       /* Write the configured values back to the Device Control Reg. */
+       E1000_WRITE_REG(hw, CTRL, ctrl);
+       return 0;
+}
+
+/******************************************************************************
+ * Forces the MAC's flow control settings.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Sets the TFCE and RFCE bits in the device control register to reflect
+ * the adapter settings. TFCE and RFCE need to be explicitly set by
+ * software when a Copper PHY is used because autonegotiation is managed
+ * by the PHY rather than the MAC. Software must also configure these
+ * bits when link is forced on a fiber connection.
+ *****************************************************************************/
+static int
+e1000_force_mac_fc(struct e1000_hw *hw)
+{
+       uint32_t ctrl;
+
+       DEBUGFUNC();
+
+       /* Get the current configuration of the Device Control Register */
+       ctrl = E1000_READ_REG(hw, CTRL);
+
+       /* Because we didn't get link via the internal auto-negotiation
+        * mechanism (we either forced link or we got link via PHY
+        * auto-neg), we have to manually enable/disable transmit an
+        * receive flow control.
+        *
+        * The "Case" statement below enables/disable flow control
+        * according to the "hw->fc" parameter.
+        *
+        * The possible values of the "fc" parameter are:
+        *      0:  Flow control is completely disabled
+        *      1:  Rx flow control is enabled (we can receive pause
+        *          frames but not send pause frames).
+        *      2:  Tx flow control is enabled (we can send pause frames
+        *          frames but we do not receive pause frames).
+        *      3:  Both Rx and TX flow control (symmetric) is enabled.
+        *  other:  No other values should be possible at this point.
+        */
+
+       switch (hw->fc) {
+       case e1000_fc_none:
+               ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
+               break;
+       case e1000_fc_rx_pause:
+               ctrl &= (~E1000_CTRL_TFCE);
+               ctrl |= E1000_CTRL_RFCE;
+               break;
+       case e1000_fc_tx_pause:
+               ctrl &= (~E1000_CTRL_RFCE);
+               ctrl |= E1000_CTRL_TFCE;
+               break;
+       case e1000_fc_full:
+               ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
+               break;
+       default:
+               DEBUGOUT("Flow control param set incorrectly\n");
+               return -E1000_ERR_CONFIG;
+       }
+
+       /* Disable TX Flow Control for 82542 (rev 2.0) */
+       if (hw->mac_type == e1000_82542_rev2_0)
+               ctrl &= (~E1000_CTRL_TFCE);
+
+       E1000_WRITE_REG(hw, CTRL, ctrl);
+       return 0;
+}
+
+/******************************************************************************
+ * Configures flow control settings after link is established
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Should be called immediately after a valid link has been established.
+ * Forces MAC flow control settings if link was forced. When in MII/GMII mode
+ * and autonegotiation is enabled, the MAC flow control settings will be set
+ * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
+ * and RFCE bits will be automaticaly set to the negotiated flow control mode.
+ *****************************************************************************/
+static int
+e1000_config_fc_after_link_up(struct e1000_hw *hw)
+{
+       int32_t ret_val;
+       uint16_t mii_status_reg;
+       uint16_t mii_nway_adv_reg;
+       uint16_t mii_nway_lp_ability_reg;
+       uint16_t speed;
+       uint16_t duplex;
+
+       DEBUGFUNC();
+
+       /* Check for the case where we have fiber media and auto-neg failed
+        * so we had to force link.  In this case, we need to force the
+        * configuration of the MAC to match the "fc" parameter.
+        */
+       if ((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) {
+               ret_val = e1000_force_mac_fc(hw);
+               if (ret_val < 0) {
+                       DEBUGOUT("Error forcing flow control settings\n");
+                       return ret_val;
+               }
+       }
+
+       /* Check for the case where we have copper media and auto-neg is
+        * enabled.  In this case, we need to check and see if Auto-Neg
+        * has completed, and if so, how the PHY and link partner has
+        * flow control configured.
+        */
+       if (hw->media_type == e1000_media_type_copper) {
+               /* Read the MII Status Register and check to see if AutoNeg
+                * has completed.  We read this twice because this reg has
+                * some "sticky" (latched) bits.
+                */
+               if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
+                       DEBUGOUT("PHY Read Error \n");
+                       return -E1000_ERR_PHY;
+               }
+               if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
+                       DEBUGOUT("PHY Read Error \n");
+                       return -E1000_ERR_PHY;
+               }
+
+               if (mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
+                       /* The AutoNeg process has completed, so we now need to
+                        * read both the Auto Negotiation Advertisement Register
+                        * (Address 4) and the Auto_Negotiation Base Page Ability
+                        * Register (Address 5) to determine how flow control was
+                        * negotiated.
+                        */
+                       if (e1000_read_phy_reg
+                           (hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg) < 0) {
+                               DEBUGOUT("PHY Read Error\n");
+                               return -E1000_ERR_PHY;
+                       }
+                       if (e1000_read_phy_reg
+                           (hw, PHY_LP_ABILITY,
+                            &mii_nway_lp_ability_reg) < 0) {
+                               DEBUGOUT("PHY Read Error\n");
+                               return -E1000_ERR_PHY;
+                       }
+
+                       /* Two bits in the Auto Negotiation Advertisement Register
+                        * (Address 4) and two bits in the Auto Negotiation Base
+                        * Page Ability Register (Address 5) determine flow control
+                        * for both the PHY and the link partner.  The following
+                        * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
+                        * 1999, describes these PAUSE resolution bits and how flow
+                        * control is determined based upon these settings.
+                        * NOTE:  DC = Don't Care
+                        *
+                        *   LOCAL DEVICE  |   LINK PARTNER
+                        * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
+                        *-------|---------|-------|---------|--------------------
+                        *   0   |    0    |  DC   |   DC    | e1000_fc_none
+                        *   0   |    1    |   0   |   DC    | e1000_fc_none
+                        *   0   |    1    |   1   |    0    | e1000_fc_none
+                        *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
+                        *   1   |    0    |   0   |   DC    | e1000_fc_none
+                        *   1   |   DC    |   1   |   DC    | e1000_fc_full
+                        *   1   |    1    |   0   |    0    | e1000_fc_none
+                        *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
+                        *
+                        */
+                       /* Are both PAUSE bits set to 1?  If so, this implies
+                        * Symmetric Flow Control is enabled at both ends.  The
+                        * ASM_DIR bits are irrelevant per the spec.
+                        *
+                        * For Symmetric Flow Control:
+                        *
+                        *   LOCAL DEVICE  |   LINK PARTNER
+                        * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+                        *-------|---------|-------|---------|--------------------
+                        *   1   |   DC    |   1   |   DC    | e1000_fc_full
+                        *
+                        */
+                       if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+                           (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
+                               /* Now we need to check if the user selected RX ONLY
+                                * of pause frames.  In this case, we had to advertise
+                                * FULL flow control because we could not advertise RX
+                                * ONLY. Hence, we must now check to see if we need to
+                                * turn OFF  the TRANSMISSION of PAUSE frames.
+                                */
+                               if (hw->original_fc == e1000_fc_full) {
+                                       hw->fc = e1000_fc_full;
+                                       DEBUGOUT("Flow Control = FULL.\r\n");
+                               } else {
+                                       hw->fc = e1000_fc_rx_pause;
+                                       DEBUGOUT
+                                           ("Flow Control = RX PAUSE frames only.\r\n");
+                               }
+                       }
+                       /* For receiving PAUSE frames ONLY.
+                        *
+                        *   LOCAL DEVICE  |   LINK PARTNER
+                        * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+                        *-------|---------|-------|---------|--------------------
+                        *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
+                        *
+                        */
+                       else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+                                (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
+                                (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
+                                (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
+                       {
+                               hw->fc = e1000_fc_tx_pause;
+                               DEBUGOUT
+                                   ("Flow Control = TX PAUSE frames only.\r\n");
+                       }
+                       /* For transmitting PAUSE frames ONLY.
+                        *
+                        *   LOCAL DEVICE  |   LINK PARTNER
+                        * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+                        *-------|---------|-------|---------|--------------------
+                        *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
+                        *
+                        */
+                       else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+                                (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
+                                !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
+                                (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
+                       {
+                               hw->fc = e1000_fc_rx_pause;
+                               DEBUGOUT
+                                   ("Flow Control = RX PAUSE frames only.\r\n");
+                       }
+                       /* Per the IEEE spec, at this point flow control should be
+                        * disabled.  However, we want to consider that we could
+                        * be connected to a legacy switch that doesn't advertise
+                        * desired flow control, but can be forced on the link
+                        * partner.  So if we advertised no flow control, that is
+                        * what we will resolve to.  If we advertised some kind of
+                        * receive capability (Rx Pause Only or Full Flow Control)
+                        * and the link partner advertised none, we will configure
+                        * ourselves to enable Rx Flow Control only.  We can do
+                        * this safely for two reasons:  If the link partner really
+                        * didn't want flow control enabled, and we enable Rx, no
+                        * harm done since we won't be receiving any PAUSE frames
+                        * anyway.  If the intent on the link partner was to have
+                        * flow control enabled, then by us enabling RX only, we
+                        * can at least receive pause frames and process them.
+                        * This is a good idea because in most cases, since we are
+                        * predominantly a server NIC, more times than not we will
+                        * be asked to delay transmission of packets than asking
+                        * our link partner to pause transmission of frames.
+                        */
+                       else if (hw->original_fc == e1000_fc_none ||
+                                hw->original_fc == e1000_fc_tx_pause) {
+                               hw->fc = e1000_fc_none;
+                               DEBUGOUT("Flow Control = NONE.\r\n");
+                       } else {
+                               hw->fc = e1000_fc_rx_pause;
+                               DEBUGOUT
+                                   ("Flow Control = RX PAUSE frames only.\r\n");
+                       }
+
+                       /* Now we need to do one last check...  If we auto-
+                        * negotiated to HALF DUPLEX, flow control should not be
+                        * enabled per IEEE 802.3 spec.
+                        */
+                       e1000_get_speed_and_duplex(hw, &speed, &duplex);
+
+                       if (duplex == HALF_DUPLEX)
+                               hw->fc = e1000_fc_none;
+
+                       /* Now we call a subroutine to actually force the MAC
+                        * controller to use the correct flow control settings.
+                        */
+                       ret_val = e1000_force_mac_fc(hw);
+                       if (ret_val < 0) {
+                               DEBUGOUT
+                                   ("Error forcing flow control settings\n");
+                               return ret_val;
+                       }
+               } else {
+                       DEBUGOUT
+                           ("Copper PHY and Auto Neg has not completed.\r\n");
+               }
+       }
+       return 0;
+}
+
+/******************************************************************************
+ * Checks to see if the link status of the hardware has changed.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Called by any function that needs to check the link status of the adapter.
+ *****************************************************************************/
+static int
+e1000_check_for_link(struct eth_device *nic)
+{
+       struct e1000_hw *hw = nic->priv;
+       uint32_t rxcw;
+       uint32_t ctrl;
+       uint32_t status;
+       uint32_t rctl;
+       uint32_t signal;
+       int32_t ret_val;
+       uint16_t phy_data;
+       uint16_t lp_capability;
+
+       DEBUGFUNC();
+
+       /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be
+        * set when the optics detect a signal. On older adapters, it will be
+        * cleared when there is a signal
+        */
+       ctrl = E1000_READ_REG(hw, CTRL);
+       if ((hw->mac_type > e1000_82544) && !(ctrl & E1000_CTRL_ILOS))
+               signal = E1000_CTRL_SWDPIN1;
+       else
+               signal = 0;
+
+       status = E1000_READ_REG(hw, STATUS);
+       rxcw = E1000_READ_REG(hw, RXCW);
+       DEBUGOUT("ctrl: %#08x status %#08x rxcw %#08x\n", ctrl, status, rxcw);
+
+       /* If we have a copper PHY then we only want to go out to the PHY
+        * registers to see if Auto-Neg has completed and/or if our link
+        * status has changed.  The get_link_status flag will be set if we
+        * receive a Link Status Change interrupt or we have Rx Sequence
+        * Errors.
+        */
+       if ((hw->media_type == e1000_media_type_copper) && hw->get_link_status) {
+               /* First we want to see if the MII Status Register reports
+                * link.  If so, then we want to get the current speed/duplex
+                * of the PHY.
+                * Read the register twice since the link bit is sticky.
+                */
+               if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+                       DEBUGOUT("PHY Read Error\n");
+                       return -E1000_ERR_PHY;
+               }
+               if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+                       DEBUGOUT("PHY Read Error\n");
+                       return -E1000_ERR_PHY;
+               }
+
+               if (phy_data & MII_SR_LINK_STATUS) {
+                       hw->get_link_status = FALSE;
+               } else {
+                       /* No link detected */
+                       return -E1000_ERR_NOLINK;
+               }
+
+               /* We have a M88E1000 PHY and Auto-Neg is enabled.  If we
+                * have Si on board that is 82544 or newer, Auto
+                * Speed Detection takes care of MAC speed/duplex
+                * configuration.  So we only need to configure Collision
+                * Distance in the MAC.  Otherwise, we need to force
+                * speed/duplex on the MAC to the current PHY speed/duplex
+                * settings.
+                */
+               if (hw->mac_type >= e1000_82544)
+                       e1000_config_collision_dist(hw);
+               else {
+                       ret_val = e1000_config_mac_to_phy(hw);
+                       if (ret_val < 0) {
+                               DEBUGOUT
+                                   ("Error configuring MAC to PHY settings\n");
+                               return ret_val;
+                       }
+               }
+
+               /* Configure Flow Control now that Auto-Neg has completed. First, we
+                * need to restore the desired flow control settings because we may
+                * have had to re-autoneg with a different link partner.
+                */
+               ret_val = e1000_config_fc_after_link_up(hw);
+               if (ret_val < 0) {
+                       DEBUGOUT("Error configuring flow control\n");
+                       return ret_val;
+               }
+
+               /* At this point we know that we are on copper and we have
+                * auto-negotiated link.  These are conditions for checking the link
+                * parter capability register.  We use the link partner capability to
+                * determine if TBI Compatibility needs to be turned on or off.  If
+                * the link partner advertises any speed in addition to Gigabit, then
+                * we assume that they are GMII-based, and TBI compatibility is not
+                * needed. If no other speeds are advertised, we assume the link
+                * partner is TBI-based, and we turn on TBI Compatibility.
+                */
+               if (hw->tbi_compatibility_en) {
+                       if (e1000_read_phy_reg
+                           (hw, PHY_LP_ABILITY, &lp_capability) < 0) {
+                               DEBUGOUT("PHY Read Error\n");
+                               return -E1000_ERR_PHY;
+                       }
+                       if (lp_capability & (NWAY_LPAR_10T_HD_CAPS |
+                                            NWAY_LPAR_10T_FD_CAPS |
+                                            NWAY_LPAR_100TX_HD_CAPS |
+                                            NWAY_LPAR_100TX_FD_CAPS |
+                                            NWAY_LPAR_100T4_CAPS)) {
+                               /* If our link partner advertises anything in addition to
+                                * gigabit, we do not need to enable TBI compatibility.
+                                */
+                               if (hw->tbi_compatibility_on) {
+                                       /* If we previously were in the mode, turn it off. */
+                                       rctl = E1000_READ_REG(hw, RCTL);
+                                       rctl &= ~E1000_RCTL_SBP;
+                                       E1000_WRITE_REG(hw, RCTL, rctl);
+                                       hw->tbi_compatibility_on = FALSE;
+                               }
+                       } else {
+                               /* If TBI compatibility is was previously off, turn it on. For
+                                * compatibility with a TBI link partner, we will store bad
+                                * packets. Some frames have an additional byte on the end and
+                                * will look like CRC errors to to the hardware.
+                                */
+                               if (!hw->tbi_compatibility_on) {
+                                       hw->tbi_compatibility_on = TRUE;
+                                       rctl = E1000_READ_REG(hw, RCTL);
+                                       rctl |= E1000_RCTL_SBP;
+                                       E1000_WRITE_REG(hw, RCTL, rctl);
+                               }
+                       }
+               }
+       }
+       /* If we don't have link (auto-negotiation failed or link partner cannot
+        * auto-negotiate), the cable is plugged in (we have signal), and our
+        * link partner is not trying to auto-negotiate with us (we are receiving
+        * idles or data), we need to force link up. We also need to give
+        * auto-negotiation time to complete, in case the cable was just plugged
+        * in. The autoneg_failed flag does this.
+        */
+       else if ((hw->media_type == e1000_media_type_fiber) &&
+                (!(status & E1000_STATUS_LU)) &&
+                ((ctrl & E1000_CTRL_SWDPIN1) == signal) &&
+                (!(rxcw & E1000_RXCW_C))) {
+               if (hw->autoneg_failed == 0) {
+                       hw->autoneg_failed = 1;
+                       return 0;
+               }
+               DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\r\n");
+
+               /* Disable auto-negotiation in the TXCW register */
+               E1000_WRITE_REG(hw, TXCW, (hw->txcw & ~E1000_TXCW_ANE));
+
+               /* Force link-up and also force full-duplex. */
+               ctrl = E1000_READ_REG(hw, CTRL);
+               ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
+               E1000_WRITE_REG(hw, CTRL, ctrl);
+
+               /* Configure Flow Control after forcing link up. */
+               ret_val = e1000_config_fc_after_link_up(hw);
+               if (ret_val < 0) {
+                       DEBUGOUT("Error configuring flow control\n");
+                       return ret_val;
+               }
+       }
+       /* If we are forcing link and we are receiving /C/ ordered sets, re-enable
+        * auto-negotiation in the TXCW register and disable forced link in the
+        * Device Control register in an attempt to auto-negotiate with our link
+        * partner.
+        */
+       else if ((hw->media_type == e1000_media_type_fiber) &&
+                (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
+               DEBUGOUT
+                   ("RXing /C/, enable AutoNeg and stop forcing link.\r\n");
+               E1000_WRITE_REG(hw, TXCW, hw->txcw);
+               E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU));
+       }
+       return 0;
+}
+
+/******************************************************************************
+ * Detects the current speed and duplex settings of the hardware.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * speed - Speed of the connection
+ * duplex - Duplex setting of the connection
+ *****************************************************************************/
+static void
+e1000_get_speed_and_duplex(struct e1000_hw *hw,
+                          uint16_t * speed, uint16_t * duplex)
+{
+       uint32_t status;
+
+       DEBUGFUNC();
+
+       if (hw->mac_type >= e1000_82543) {
+               status = E1000_READ_REG(hw, STATUS);
+               if (status & E1000_STATUS_SPEED_1000) {
+                       *speed = SPEED_1000;
+                       DEBUGOUT("1000 Mbs, ");
+               } else if (status & E1000_STATUS_SPEED_100) {
+                       *speed = SPEED_100;
+                       DEBUGOUT("100 Mbs, ");
+               } else {
+                       *speed = SPEED_10;
+                       DEBUGOUT("10 Mbs, ");
+               }
+
+               if (status & E1000_STATUS_FD) {
+                       *duplex = FULL_DUPLEX;
+                       DEBUGOUT("Full Duplex\r\n");
+               } else {
+                       *duplex = HALF_DUPLEX;
+                       DEBUGOUT(" Half Duplex\r\n");
+               }
+       } else {
+               DEBUGOUT("1000 Mbs, Full Duplex\r\n");
+               *speed = SPEED_1000;
+               *duplex = FULL_DUPLEX;
+       }
+}
+
+/******************************************************************************
+* Blocks until autoneg completes or times out (~4.5 seconds)
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static int
+e1000_wait_autoneg(struct e1000_hw *hw)
+{
+       uint16_t i;
+       uint16_t phy_data;
+
+       DEBUGFUNC();
+       DEBUGOUT("Waiting for Auto-Neg to complete.\n");
+
+       /* We will wait for autoneg to complete or 4.5 seconds to expire. */
+       for (i = PHY_AUTO_NEG_TIME; i > 0; i--) {
+               /* Read the MII Status Register and wait for Auto-Neg
+                * Complete bit to be set.
+                */
+               if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+                       DEBUGOUT("PHY Read Error\n");
+                       return -E1000_ERR_PHY;
+               }
+               if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+                       DEBUGOUT("PHY Read Error\n");
+                       return -E1000_ERR_PHY;
+               }
+               if (phy_data & MII_SR_AUTONEG_COMPLETE) {
+                       DEBUGOUT("Auto-Neg complete.\n");
+                       return 0;
+               }
+               mdelay(100);
+       }
+       DEBUGOUT("Auto-Neg timedout.\n");
+       return -E1000_ERR_TIMEOUT;
+}
+
+/******************************************************************************
+* Raises the Management Data Clock
+*
+* hw - Struct containing variables accessed by shared code
+* ctrl - Device control register's current value
+******************************************************************************/
+static void
+e1000_raise_mdi_clk(struct e1000_hw *hw, uint32_t * ctrl)
+{
+       /* Raise the clock input to the Management Data Clock (by setting the MDC
+        * bit), and then delay 2 microseconds.
+        */
+       E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
+       E1000_WRITE_FLUSH(hw);
+       udelay(2);
+}
+
+/******************************************************************************
+* Lowers the Management Data Clock
+*
+* hw - Struct containing variables accessed by shared code
+* ctrl - Device control register's current value
+******************************************************************************/
+static void
+e1000_lower_mdi_clk(struct e1000_hw *hw, uint32_t * ctrl)
+{
+       /* Lower the clock input to the Management Data Clock (by clearing the MDC
+        * bit), and then delay 2 microseconds.
+        */
+       E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
+       E1000_WRITE_FLUSH(hw);
+       udelay(2);
+}
+
+/******************************************************************************
+* Shifts data bits out to the PHY
+*
+* hw - Struct containing variables accessed by shared code
+* data - Data to send out to the PHY
+* count - Number of bits to shift out
+*
+* Bits are shifted out in MSB to LSB order.
+******************************************************************************/
+static void
+e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data, uint16_t count)
+{
+       uint32_t ctrl;
+       uint32_t mask;
+
+       /* We need to shift "count" number of bits out to the PHY. So, the value
+        * in the "data" parameter will be shifted out to the PHY one bit at a
+        * time. In order to do this, "data" must be broken down into bits.
+        */
+       mask = 0x01;
+       mask <<= (count - 1);
+
+       ctrl = E1000_READ_REG(hw, CTRL);
+
+       /* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
+       ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
+
+       while (mask) {
+               /* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and
+                * then raising and lowering the Management Data Clock. A "0" is
+                * shifted out to the PHY by setting the MDIO bit to "0" and then
+                * raising and lowering the clock.
+                */
+               if (data & mask)
+                       ctrl |= E1000_CTRL_MDIO;
+               else
+                       ctrl &= ~E1000_CTRL_MDIO;
+
+               E1000_WRITE_REG(hw, CTRL, ctrl);
+               E1000_WRITE_FLUSH(hw);
+
+               udelay(2);
+
+               e1000_raise_mdi_clk(hw, &ctrl);
+               e1000_lower_mdi_clk(hw, &ctrl);
+
+               mask = mask >> 1;
+       }
+}
+
+/******************************************************************************
+* Shifts data bits in from the PHY
+*
+* hw - Struct containing variables accessed by shared code
+*
+* Bits are shifted in in MSB to LSB order.
+******************************************************************************/
+static uint16_t
+e1000_shift_in_mdi_bits(struct e1000_hw *hw)
+{
+       uint32_t ctrl;
+       uint16_t data = 0;
+       uint8_t i;
+
+       /* In order to read a register from the PHY, we need to shift in a total
+        * of 18 bits from the PHY. The first two bit (turnaround) times are used
+        * to avoid contention on the MDIO pin when a read operation is performed.
+        * These two bits are ignored by us and thrown away. Bits are "shifted in"
+        * by raising the input to the Management Data Clock (setting the MDC bit),
+        * and then reading the value of the MDIO bit.
+        */
+       ctrl = E1000_READ_REG(hw, CTRL);
+
+       /* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */
+       ctrl &= ~E1000_CTRL_MDIO_DIR;
+       ctrl &= ~E1000_CTRL_MDIO;
+
+       E1000_WRITE_REG(hw, CTRL, ctrl);
+       E1000_WRITE_FLUSH(hw);
+
+       /* Raise and Lower the clock before reading in the data. This accounts for
+        * the turnaround bits. The first clock occurred when we clocked out the
+        * last bit of the Register Address.
+        */
+       e1000_raise_mdi_clk(hw, &ctrl);
+       e1000_lower_mdi_clk(hw, &ctrl);
+
+       for (data = 0, i = 0; i < 16; i++) {
+               data = data << 1;
+               e1000_raise_mdi_clk(hw, &ctrl);
+               ctrl = E1000_READ_REG(hw, CTRL);
+               /* Check to see if we shifted in a "1". */
+               if (ctrl & E1000_CTRL_MDIO)
+                       data |= 1;
+               e1000_lower_mdi_clk(hw, &ctrl);
+       }
+
+       e1000_raise_mdi_clk(hw, &ctrl);
+       e1000_lower_mdi_clk(hw, &ctrl);
+
+       return data;
+}
+
+/*****************************************************************************
+* Reads the value from a PHY register
+*
+* hw - Struct containing variables accessed by shared code
+* reg_addr - address of the PHY register to read
+******************************************************************************/
+static int
+e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t * phy_data)
+{
+       uint32_t i;
+       uint32_t mdic = 0;
+       const uint32_t phy_addr = 1;
+
+       if (reg_addr > MAX_PHY_REG_ADDRESS) {
+               DEBUGOUT("PHY Address %d is out of range\n", reg_addr);
+               return -E1000_ERR_PARAM;
+       }
+
+       if (hw->mac_type > e1000_82543) {
+               /* Set up Op-code, Phy Address, and register address in the MDI
+                * Control register.  The MAC will take care of interfacing with the
+                * PHY to retrieve the desired data.
+                */
+               mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
+                       (phy_addr << E1000_MDIC_PHY_SHIFT) |
+                       (E1000_MDIC_OP_READ));
+
+               E1000_WRITE_REG(hw, MDIC, mdic);
+
+               /* Poll the ready bit to see if the MDI read completed */
+               for (i = 0; i < 64; i++) {
+                       udelay(10);
+                       mdic = E1000_READ_REG(hw, MDIC);
+                       if (mdic & E1000_MDIC_READY)
+                               break;
+               }
+               if (!(mdic & E1000_MDIC_READY)) {
+                       DEBUGOUT("MDI Read did not complete\n");
+                       return -E1000_ERR_PHY;
+               }
+               if (mdic & E1000_MDIC_ERROR) {
+                       DEBUGOUT("MDI Error\n");
+                       return -E1000_ERR_PHY;
+               }
+               *phy_data = (uint16_t) mdic;
+       } else {
+               /* We must first send a preamble through the MDIO pin to signal the
+                * beginning of an MII instruction.  This is done by sending 32
+                * consecutive "1" bits.
+                */
+               e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
+
+               /* Now combine the next few fields that are required for a read
+                * operation.  We use this method instead of calling the
+                * e1000_shift_out_mdi_bits routine five different times. The format of
+                * a MII read instruction consists of a shift out of 14 bits and is
+                * defined as follows:
+                *    <Preamble><SOF><Op Code><Phy Addr><Reg Addr>
+                * followed by a shift in of 18 bits.  This first two bits shifted in
+                * are TurnAround bits used to avoid contention on the MDIO pin when a
+                * READ operation is performed.  These two bits are thrown away
+                * followed by a shift in of 16 bits which contains the desired data.
+                */
+               mdic = ((reg_addr) | (phy_addr << 5) |
+                       (PHY_OP_READ << 10) | (PHY_SOF << 12));
+
+               e1000_shift_out_mdi_bits(hw, mdic, 14);
+
+               /* Now that we've shifted out the read command to the MII, we need to
+                * "shift in" the 16-bit value (18 total bits) of the requested PHY
+                * register address.
+                */
+               *phy_data = e1000_shift_in_mdi_bits(hw);
+       }
+       return 0;
+}
+
+/******************************************************************************
+* Writes a value to a PHY register
+*
+* hw - Struct containing variables accessed by shared code
+* reg_addr - address of the PHY register to write
+* data - data to write to the PHY
+******************************************************************************/
+static int
+e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t phy_data)
+{
+       uint32_t i;
+       uint32_t mdic = 0;
+       const uint32_t phy_addr = 1;
+
+       if (reg_addr > MAX_PHY_REG_ADDRESS) {
+               DEBUGOUT("PHY Address %d is out of range\n", reg_addr);
+               return -E1000_ERR_PARAM;
+       }
+
+       if (hw->mac_type > e1000_82543) {
+               /* Set up Op-code, Phy Address, register address, and data intended
+                * for the PHY register in the MDI Control register.  The MAC will take
+                * care of interfacing with the PHY to send the desired data.
+                */
+               mdic = (((uint32_t) phy_data) |
+                       (reg_addr << E1000_MDIC_REG_SHIFT) |
+                       (phy_addr << E1000_MDIC_PHY_SHIFT) |
+                       (E1000_MDIC_OP_WRITE));
+
+               E1000_WRITE_REG(hw, MDIC, mdic);
+
+               /* Poll the ready bit to see if the MDI read completed */
+               for (i = 0; i < 64; i++) {
+                       udelay(10);
+                       mdic = E1000_READ_REG(hw, MDIC);
+                       if (mdic & E1000_MDIC_READY)
+                               break;
+               }
+               if (!(mdic & E1000_MDIC_READY)) {
+                       DEBUGOUT("MDI Write did not complete\n");
+                       return -E1000_ERR_PHY;
+               }
+       } else {
+               /* We'll need to use the SW defined pins to shift the write command
+                * out to the PHY. We first send a preamble to the PHY to signal the
+                * beginning of the MII instruction.  This is done by sending 32
+                * consecutive "1" bits.
+                */
+               e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
+
+               /* Now combine the remaining required fields that will indicate a
+                * write operation. We use this method instead of calling the
+                * e1000_shift_out_mdi_bits routine for each field in the command. The
+                * format of a MII write instruction is as follows:
+                * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.
+                */
+               mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) |
+                       (PHY_OP_WRITE << 12) | (PHY_SOF << 14));
+               mdic <<= 16;
+               mdic |= (uint32_t) phy_data;
+
+               e1000_shift_out_mdi_bits(hw, mdic, 32);
+       }
+       return 0;
+}
+
+/******************************************************************************
+* Returns the PHY to the power-on reset state
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static void
+e1000_phy_hw_reset(struct e1000_hw *hw)
+{
+       uint32_t ctrl;
+       uint32_t ctrl_ext;
+
+       DEBUGFUNC();
+
+       DEBUGOUT("Resetting Phy...\n");
+
+       if (hw->mac_type > e1000_82543) {
+               /* Read the device control register and assert the E1000_CTRL_PHY_RST
+                * bit. Then, take it out of reset.
+                */
+               ctrl = E1000_READ_REG(hw, CTRL);
+               E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
+               E1000_WRITE_FLUSH(hw);
+               mdelay(10);
+               E1000_WRITE_REG(hw, CTRL, ctrl);
+               E1000_WRITE_FLUSH(hw);
+       } else {
+               /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
+                * bit to put the PHY into reset. Then, take it out of reset.
+                */
+               ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+               ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
+               ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
+               E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+               E1000_WRITE_FLUSH(hw);
+               mdelay(10);
+               ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
+               E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+               E1000_WRITE_FLUSH(hw);
+       }
+       udelay(150);
+}
+
+/******************************************************************************
+* Resets the PHY
+*
+* hw - Struct containing variables accessed by shared code
+*
+* Sets bit 15 of the MII Control regiser
+******************************************************************************/
+static int
+e1000_phy_reset(struct e1000_hw *hw)
+{
+       uint16_t phy_data;
+
+       DEBUGFUNC();
+
+       if (e1000_read_phy_reg(hw, PHY_CTRL, &phy_data) < 0) {
+               DEBUGOUT("PHY Read Error\n");
+               return -E1000_ERR_PHY;
+       }
+       phy_data |= MII_CR_RESET;
+       if (e1000_write_phy_reg(hw, PHY_CTRL, phy_data) < 0) {
+               DEBUGOUT("PHY Write Error\n");
+               return -E1000_ERR_PHY;
+       }
+       udelay(1);
+       return 0;
+}
+
+/******************************************************************************
+* Probes the expected PHY address for known PHY IDs
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static int
+e1000_detect_gig_phy(struct e1000_hw *hw)
+{
+       uint16_t phy_id_high, phy_id_low;
+       int match = FALSE;
+
+       DEBUGFUNC();
+
+       /* Read the PHY ID Registers to identify which PHY is onboard. */
+       if (e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high) < 0) {
+               DEBUGOUT("PHY Read Error\n");
+               return -E1000_ERR_PHY;
+       }
+       hw->phy_id = (uint32_t) (phy_id_high << 16);
+       udelay(2);
+       if (e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low) < 0) {
+               DEBUGOUT("PHY Read Error\n");
+               return -E1000_ERR_PHY;
+       }
+       hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK);
+
+       switch (hw->mac_type) {
+       case e1000_82543:
+               if (hw->phy_id == M88E1000_E_PHY_ID)
+                       match = TRUE;
+               break;
+       case e1000_82544:
+               if (hw->phy_id == M88E1000_I_PHY_ID)
+                       match = TRUE;
+               break;
+       case e1000_82540:
+       case e1000_82545:
+       case e1000_82546:
+               if (hw->phy_id == M88E1011_I_PHY_ID)
+                       match = TRUE;
+               break;
+       default:
+               DEBUGOUT("Invalid MAC type %d\n", hw->mac_type);
+               return -E1000_ERR_CONFIG;
+       }
+       if (match) {
+               DEBUGOUT("PHY ID 0x%X detected\n", hw->phy_id);
+               return 0;
+       }
+       DEBUGOUT("Invalid PHY ID 0x%X\n", hw->phy_id);
+       return -E1000_ERR_PHY;
+}
+
+/**
+ * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
+ *
+ * e1000_sw_init initializes the Adapter private data structure.
+ * Fields are initialized based on PCI device information and
+ * OS network device settings (MTU size).
+ **/
+
+static int
+e1000_sw_init(struct eth_device *nic, int cardnum)
+{
+       struct e1000_hw *hw = (typeof(hw)) nic->priv;
+       int result;
+
+       /* PCI config space info */
+       pci_read_config_word(hw->pdev, PCI_VENDOR_ID, &hw->vendor_id);
+       pci_read_config_word(hw->pdev, PCI_DEVICE_ID, &hw->device_id);
+       pci_read_config_word(hw->pdev, PCI_SUBSYSTEM_VENDOR_ID,
+                            &hw->subsystem_vendor_id);
+       pci_read_config_word(hw->pdev, PCI_SUBSYSTEM_ID, &hw->subsystem_id);
+
+       pci_read_config_byte(hw->pdev, PCI_REVISION_ID, &hw->revision_id);
+       pci_read_config_word(hw->pdev, PCI_COMMAND, &hw->pci_cmd_word);
+
+       /* identify the MAC */
+       result = e1000_set_mac_type(hw);
+       if (result) {
+               E1000_ERR("Unknown MAC Type\n");
+               return result;
+       }
+
+       /* lan a vs. lan b settings */
+       if (hw->mac_type == e1000_82546)
+               /*this also works w/ multiple 82546 cards */
+               /*but not if they're intermingled /w other e1000s */
+               hw->lan_loc = (cardnum % 2) ? e1000_lan_b : e1000_lan_a;
+       else
+               hw->lan_loc = e1000_lan_a;
+
+       /* flow control settings */
+       hw->fc_high_water = E1000_FC_HIGH_THRESH;
+       hw->fc_low_water = E1000_FC_LOW_THRESH;
+       hw->fc_pause_time = E1000_FC_PAUSE_TIME;
+       hw->fc_send_xon = 1;
+
+       /* Media type - copper or fiber */
+
+       if (hw->mac_type >= e1000_82543) {
+               uint32_t status = E1000_READ_REG(hw, STATUS);
+
+               if (status & E1000_STATUS_TBIMODE) {
+                       DEBUGOUT("fiber interface\n");
+                       hw->media_type = e1000_media_type_fiber;
+               } else {
+                       DEBUGOUT("copper interface\n");
+                       hw->media_type = e1000_media_type_copper;
+               }
+       } else {
+               hw->media_type = e1000_media_type_fiber;
+       }
+
+       if (hw->mac_type < e1000_82543)
+               hw->report_tx_early = 0;
+       else
+               hw->report_tx_early = 1;
+
+       hw->tbi_compatibility_en = TRUE;
+#if 0
+       hw->wait_autoneg_complete = FALSE;
+       hw->adaptive_ifs = TRUE;
+
+       /* Copper options */
+       if (hw->media_type == e1000_media_type_copper) {
+               hw->mdix = AUTO_ALL_MODES;
+               hw->disable_polarity_correction = FALSE;
+       }
+#endif
+       return E1000_SUCCESS;
+}
+
+void
+fill_rx(struct e1000_hw *hw)
+{
+       struct e1000_rx_desc *rd;
+
+       rx_last = rx_tail;
+       rd = rx_base + rx_tail;
+       rx_tail = (rx_tail + 1) % 8;
+       memset(rd, 0, 16);
+       rd->buffer_addr = cpu_to_le64((u32) & packet);
+       E1000_WRITE_REG(hw, RDT, rx_tail);
+}
+
+/**
+ * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx unit of the MAC after a reset.
+ **/
+
+static void
+e1000_configure_tx(struct e1000_hw *hw)
+{
+       unsigned long ptr;
+       unsigned long tctl;
+       unsigned long tipg;
+
+       ptr = (u32) tx_pool;
+       if (ptr & 0xf)
+               ptr = (ptr + 0x10) & (~0xf);
+
+       tx_base = (typeof(tx_base)) ptr;
+
+       E1000_WRITE_REG(hw, TDBAL, (u32) tx_base);
+       E1000_WRITE_REG(hw, TDBAH, 0);
+
+       E1000_WRITE_REG(hw, TDLEN, 128);
+
+       /* Setup the HW Tx Head and Tail descriptor pointers */
+       E1000_WRITE_REG(hw, TDH, 0);
+       E1000_WRITE_REG(hw, TDT, 0);
+       tx_tail = 0;
+
+       /* Set the default values for the Tx Inter Packet Gap timer */
+       switch (hw->mac_type) {
+       case e1000_82542_rev2_0:
+       case e1000_82542_rev2_1:
+               tipg = DEFAULT_82542_TIPG_IPGT;
+               tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
+               tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
+               break;
+       default:
+               if (hw->media_type == e1000_media_type_fiber)
+                       tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
+               else
+                       tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
+               tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
+               tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
+       }
+       E1000_WRITE_REG(hw, TIPG, tipg);
+#if 0
+       /* Set the Tx Interrupt Delay register */
+       E1000_WRITE_REG(hw, TIDV, adapter->tx_int_delay);
+       if (hw->mac_type >= e1000_82540)
+               E1000_WRITE_REG(hw, TADV, adapter->tx_abs_int_delay);
+#endif
+       /* Program the Transmit Control Register */
+       tctl = E1000_READ_REG(hw, TCTL);
+       tctl &= ~E1000_TCTL_CT;
+       tctl |= E1000_TCTL_EN | E1000_TCTL_PSP |
+           (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
+       E1000_WRITE_REG(hw, TCTL, tctl);
+
+       e1000_config_collision_dist(hw);
+#if 0
+       /* Setup Transmit Descriptor Settings for this adapter */
+       adapter->txd_cmd = E1000_TXD_CMD_IFCS | E1000_TXD_CMD_IDE;
+
+       if (adapter->hw.report_tx_early == 1)
+               adapter->txd_cmd |= E1000_TXD_CMD_RS;
+       else
+               adapter->txd_cmd |= E1000_TXD_CMD_RPS;
+#endif
+}
+
+/**
+ * e1000_setup_rctl - configure the receive control register
+ * @adapter: Board private structure
+ **/
+static void
+e1000_setup_rctl(struct e1000_hw *hw)
+{
+       uint32_t rctl;
+
+       rctl = E1000_READ_REG(hw, RCTL);
+
+       rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
+
+       rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF;     /* |
+                                                                                                  (hw.mc_filter_type << E1000_RCTL_MO_SHIFT); */
+
+       if (hw->tbi_compatibility_on == 1)
+               rctl |= E1000_RCTL_SBP;
+       else
+               rctl &= ~E1000_RCTL_SBP;
+
+       rctl &= ~(E1000_RCTL_SZ_4096);
+#if 0
+       switch (adapter->rx_buffer_len) {
+       case E1000_RXBUFFER_2048:
+       default:
+#endif
+               rctl |= E1000_RCTL_SZ_2048;
+               rctl &= ~(E1000_RCTL_BSEX | E1000_RCTL_LPE);
+#if 0
+               break;
+       case E1000_RXBUFFER_4096:
+               rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
+               break;
+       case E1000_RXBUFFER_8192:
+               rctl |= E1000_RCTL_SZ_8192 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
+               break;
+       case E1000_RXBUFFER_16384:
+               rctl |= E1000_RCTL_SZ_16384 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
+               break;
+       }
+#endif
+       E1000_WRITE_REG(hw, RCTL, rctl);
+}
+
+/**
+ * e1000_configure_rx - Configure 8254x Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Rx unit of the MAC after a reset.
+ **/
+static void
+e1000_configure_rx(struct e1000_hw *hw)
+{
+       unsigned long ptr;
+       unsigned long rctl;
+#if 0
+       unsigned long rxcsum;
+#endif
+       rx_tail = 0;
+       /* make sure receives are disabled while setting up the descriptors */
+       rctl = E1000_READ_REG(hw, RCTL);
+       E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
+#if 0
+       /* set the Receive Delay Timer Register */
+
+       E1000_WRITE_REG(hw, RDTR, adapter->rx_int_delay);
+#endif
+       if (hw->mac_type >= e1000_82540) {
+#if 0
+               E1000_WRITE_REG(hw, RADV, adapter->rx_abs_int_delay);
+#endif
+               /* Set the interrupt throttling rate.  Value is calculated
+                * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns) */
+#define MAX_INTS_PER_SEC        8000
+#define DEFAULT_ITR             1000000000/(MAX_INTS_PER_SEC * 256)
+               E1000_WRITE_REG(hw, ITR, DEFAULT_ITR);
+       }
+
+       /* Setup the Base and Length of the Rx Descriptor Ring */
+       ptr = (u32) rx_pool;
+       if (ptr & 0xf)
+               ptr = (ptr + 0x10) & (~0xf);
+       rx_base = (typeof(rx_base)) ptr;
+       E1000_WRITE_REG(hw, RDBAL, (u32) rx_base);
+       E1000_WRITE_REG(hw, RDBAH, 0);
+
+       E1000_WRITE_REG(hw, RDLEN, 128);
+
+       /* Setup the HW Rx Head and Tail Descriptor Pointers */
+       E1000_WRITE_REG(hw, RDH, 0);
+       E1000_WRITE_REG(hw, RDT, 0);
+#if 0
+       /* Enable 82543 Receive Checksum Offload for TCP and UDP */
+       if ((adapter->hw.mac_type >= e1000_82543) && (adapter->rx_csum == TRUE)) {
+               rxcsum = E1000_READ_REG(hw, RXCSUM);
+               rxcsum |= E1000_RXCSUM_TUOFL;
+               E1000_WRITE_REG(hw, RXCSUM, rxcsum);
+       }
+#endif
+       /* Enable Receives */
+
+       E1000_WRITE_REG(hw, RCTL, rctl);
+       fill_rx(hw);
+}
+
+/**************************************************************************
+POLL - Wait for a frame
+***************************************************************************/
+static int
+e1000_poll(struct eth_device *nic)
+{
+       struct e1000_hw *hw = nic->priv;
+       struct e1000_rx_desc *rd;
+       /* return true if there's an ethernet packet ready to read */
+       rd = rx_base + rx_last;
+       if (!(le32_to_cpu(rd->status)) & E1000_RXD_STAT_DD)
+               return 0;
+       /*DEBUGOUT("recv: packet len=%d \n", rd->length); */
+       NetReceive((uchar *)packet, le32_to_cpu(rd->length));
+       fill_rx(hw);
+       return 1;
+}
+
+/**************************************************************************
+TRANSMIT - Transmit a frame
+***************************************************************************/
+static int
+e1000_transmit(struct eth_device *nic, volatile void *packet, int length)
+{
+       struct e1000_hw *hw = nic->priv;
+       struct e1000_tx_desc *txp;
+       int i = 0;
+
+       txp = tx_base + tx_tail;
+       tx_tail = (tx_tail + 1) % 8;
+
+       txp->buffer_addr = cpu_to_le64(virt_to_bus(packet));
+       txp->lower.data = cpu_to_le32(E1000_TXD_CMD_RPS | E1000_TXD_CMD_EOP |
+                                     E1000_TXD_CMD_IFCS | length);
+       txp->upper.data = 0;
+       E1000_WRITE_REG(hw, TDT, tx_tail);
+
+       while (!(le32_to_cpu(txp->upper.data) & E1000_TXD_STAT_DD)) {
+               if (i++ > TOUT_LOOP) {
+                       DEBUGOUT("e1000: tx timeout\n");
+                       return 0;
+               }
+               udelay(10);     /* give the nic a chance to write to the register */
+       }
+       return 1;
+}
+
+/*reset function*/
+static inline int
+e1000_reset(struct eth_device *nic)
+{
+       struct e1000_hw *hw = nic->priv;
+
+       e1000_reset_hw(hw);
+       if (hw->mac_type >= e1000_82544) {
+               E1000_WRITE_REG(hw, WUC, 0);
+       }
+       return e1000_init_hw(nic);
+}
+
+/**************************************************************************
+DISABLE - Turn off ethernet interface
+***************************************************************************/
+static void
+e1000_disable(struct eth_device *nic)
+{
+       struct e1000_hw *hw = nic->priv;
+
+       /* Turn off the ethernet interface */
+       E1000_WRITE_REG(hw, RCTL, 0);
+       E1000_WRITE_REG(hw, TCTL, 0);
+
+       /* Clear the transmit ring */
+       E1000_WRITE_REG(hw, TDH, 0);
+       E1000_WRITE_REG(hw, TDT, 0);
+
+       /* Clear the receive ring */
+       E1000_WRITE_REG(hw, RDH, 0);
+       E1000_WRITE_REG(hw, RDT, 0);
+
+       /* put the card in its initial state */
+#if 0
+       E1000_WRITE_REG(hw, CTRL, E1000_CTRL_RST);
+#endif
+       mdelay(10);
+
+}
+
+/**************************************************************************
+INIT - set up ethernet interface(s)
+***************************************************************************/
+static int
+e1000_init(struct eth_device *nic, bd_t * bis)
+{
+       struct e1000_hw *hw = nic->priv;
+       int ret_val = 0;
+
+       ret_val = e1000_reset(nic);
+       if (ret_val < 0) {
+               if ((ret_val == -E1000_ERR_NOLINK) ||
+                   (ret_val == -E1000_ERR_TIMEOUT)) {
+                       E1000_ERR("Valid Link not detected\n");
+               } else {
+                       E1000_ERR("Hardware Initialization Failed\n");
+               }
+               return 0;
+       }
+       e1000_configure_tx(hw);
+       e1000_setup_rctl(hw);
+       e1000_configure_rx(hw);
+       return 1;
+}
+
+/**************************************************************************
+PROBE - Look for an adapter, this routine's visible to the outside
+You should omit the last argument struct pci_device * for a non-PCI NIC
+***************************************************************************/
+int
+e1000_initialize(bd_t * bis)
+{
+       pci_dev_t devno;
+       int card_number = 0;
+       struct eth_device *nic = NULL;
+       struct e1000_hw *hw = NULL;
+       u32 iobase;
+       int idx = 0;
+       u32 PciCommandWord;
+
+       while (1) {             /* Find PCI device(s) */
+               if ((devno = pci_find_devices(supported, idx++)) < 0) {
+                       break;
+               }
+
+               pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase);
+               iobase &= ~0xf; /* Mask the bits that say "this is an io addr" */
+               DEBUGOUT("e1000#%d: iobase 0x%08x\n", card_number, iobase);
+
+               pci_write_config_dword(devno, PCI_COMMAND,
+                                      PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+               /* Check if I/O accesses and Bus Mastering are enabled. */
+               pci_read_config_dword(devno, PCI_COMMAND, &PciCommandWord);
+               if (!(PciCommandWord & PCI_COMMAND_MEMORY)) {
+                       printf("Error: Can not enable MEM access.\n");
+                       continue;
+               } else if (!(PciCommandWord & PCI_COMMAND_MASTER)) {
+                       printf("Error: Can not enable Bus Mastering.\n");
+                       continue;
+               }
+
+               nic = (struct eth_device *) malloc(sizeof (*nic));
+               hw = (struct e1000_hw *) malloc(sizeof (*hw));
+               hw->pdev = devno;
+               nic->priv = hw;
+               nic->iobase = bus_to_phys(devno, iobase);
+
+               sprintf(nic->name, "e1000#%d", card_number);
+
+               /* Are these variables needed? */
+#if 0
+               hw->fc = e1000_fc_none;
+               hw->original_fc = e1000_fc_none;
+#else
+               hw->fc = e1000_fc_default;
+               hw->original_fc = e1000_fc_default;
+#endif
+               hw->autoneg_failed = 0;
+               hw->get_link_status = TRUE;
+               hw->hw_addr = (typeof(hw->hw_addr)) iobase;
+               hw->mac_type = e1000_undefined;
+
+               /* MAC and Phy settings */
+               if (e1000_sw_init(nic, card_number) < 0) {
+                       free(hw);
+                       free(nic);
+                       return 0;
+               }
+#ifndef CONFIG_AP1000
+               if (e1000_validate_eeprom_checksum(nic) < 0) {
+                       printf("The EEPROM Checksum Is Not Valid\n");
+                       free(hw);
+                       free(nic);
+                       return 0;
+               }
+#endif
+               e1000_read_mac_addr(nic);
+
+               E1000_WRITE_REG(hw, PBA, E1000_DEFAULT_PBA);
+
+               printf("e1000: %02x:%02x:%02x:%02x:%02x:%02x\n",
+                      nic->enetaddr[0], nic->enetaddr[1], nic->enetaddr[2],
+                      nic->enetaddr[3], nic->enetaddr[4], nic->enetaddr[5]);
+
+               nic->init = e1000_init;
+               nic->recv = e1000_poll;
+               nic->send = e1000_transmit;
+               nic->halt = e1000_disable;
+
+               eth_register(nic);
+
+               card_number++;
+       }
+       return 1;
+}
+
+#endif
diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h
new file mode 100644 (file)
index 0000000..0fbdc90
--- /dev/null
@@ -0,0 +1,1758 @@
+/*******************************************************************************
+
+
+  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+
+  Contact Information:
+  Linux NICS <linux.nics@intel.com>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+/* e1000_hw.h
+ * Structures, enums, and macros for the MAC
+ */
+
+#ifndef _E1000_HW_H_
+#define _E1000_HW_H_
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#define E1000_ERR(args...) printf("e1000: " args)
+
+#ifdef E1000_DEBUG
+#define E1000_DBG(args...)     printf("e1000: " args)
+#define DEBUGOUT(fmt,args...) printf(fmt ,##args)
+#define DEBUGFUNC()        printf("%s\n", __FUNCTION__);
+#else
+#define E1000_DBG(args...)
+#define DEBUGFUNC()
+#define DEBUGOUT(fmt,args...)
+#endif
+
+/* Forward declarations of structures used by the shared code */
+struct e1000_hw;
+struct e1000_hw_stats;
+
+typedef enum {
+       FALSE = 0,
+       TRUE = 1
+} boolean_t;
+
+/* Enumerated types specific to the e1000 hardware */
+/* Media Access Controlers */
+typedef enum {
+       e1000_undefined = 0,
+       e1000_82542_rev2_0,
+       e1000_82542_rev2_1,
+       e1000_82543,
+       e1000_82544,
+       e1000_82540,
+       e1000_82545,
+       e1000_82546,
+       e1000_num_macs
+} e1000_mac_type;
+
+/* Media Types */
+typedef enum {
+       e1000_media_type_copper = 0,
+       e1000_media_type_fiber = 1,
+       e1000_num_media_types
+} e1000_media_type;
+
+typedef enum {
+       e1000_10_half = 0,
+       e1000_10_full = 1,
+       e1000_100_half = 2,
+       e1000_100_full = 3
+} e1000_speed_duplex_type;
+
+typedef enum {
+       e1000_lan_a = 0,
+       e1000_lan_b = 1
+} e1000_lan_loc;
+
+/* Flow Control Settings */
+typedef enum {
+       e1000_fc_none = 0,
+       e1000_fc_rx_pause = 1,
+       e1000_fc_tx_pause = 2,
+       e1000_fc_full = 3,
+       e1000_fc_default = 0xFF
+} e1000_fc_type;
+
+/* PCI bus types */
+typedef enum {
+       e1000_bus_type_unknown = 0,
+       e1000_bus_type_pci,
+       e1000_bus_type_pcix
+} e1000_bus_type;
+
+/* PCI bus speeds */
+typedef enum {
+       e1000_bus_speed_unknown = 0,
+       e1000_bus_speed_33,
+       e1000_bus_speed_66,
+       e1000_bus_speed_100,
+       e1000_bus_speed_133,
+       e1000_bus_speed_reserved
+} e1000_bus_speed;
+
+/* PCI bus widths */
+typedef enum {
+       e1000_bus_width_unknown = 0,
+       e1000_bus_width_32,
+       e1000_bus_width_64
+} e1000_bus_width;
+
+/* PHY status info structure and supporting enums */
+typedef enum {
+       e1000_cable_length_50 = 0,
+       e1000_cable_length_50_80,
+       e1000_cable_length_80_110,
+       e1000_cable_length_110_140,
+       e1000_cable_length_140,
+       e1000_cable_length_undefined = 0xFF
+} e1000_cable_length;
+
+typedef enum {
+       e1000_10bt_ext_dist_enable_normal = 0,
+       e1000_10bt_ext_dist_enable_lower,
+       e1000_10bt_ext_dist_enable_undefined = 0xFF
+} e1000_10bt_ext_dist_enable;
+
+typedef enum {
+       e1000_rev_polarity_normal = 0,
+       e1000_rev_polarity_reversed,
+       e1000_rev_polarity_undefined = 0xFF
+} e1000_rev_polarity;
+
+typedef enum {
+       e1000_polarity_reversal_enabled = 0,
+       e1000_polarity_reversal_disabled,
+       e1000_polarity_reversal_undefined = 0xFF
+} e1000_polarity_reversal;
+
+typedef enum {
+       e1000_auto_x_mode_manual_mdi = 0,
+       e1000_auto_x_mode_manual_mdix,
+       e1000_auto_x_mode_auto1,
+       e1000_auto_x_mode_auto2,
+       e1000_auto_x_mode_undefined = 0xFF
+} e1000_auto_x_mode;
+
+typedef enum {
+       e1000_1000t_rx_status_not_ok = 0,
+       e1000_1000t_rx_status_ok,
+       e1000_1000t_rx_status_undefined = 0xFF
+} e1000_1000t_rx_status;
+
+struct e1000_phy_info {
+       e1000_cable_length cable_length;
+       e1000_10bt_ext_dist_enable extended_10bt_distance;
+       e1000_rev_polarity cable_polarity;
+       e1000_polarity_reversal polarity_correction;
+       e1000_auto_x_mode mdix_mode;
+       e1000_1000t_rx_status local_rx;
+       e1000_1000t_rx_status remote_rx;
+};
+
+struct e1000_phy_stats {
+       uint32_t idle_errors;
+       uint32_t receive_errors;
+};
+
+/* Error Codes */
+#define E1000_SUCCESS      0
+#define E1000_ERR_EEPROM   1
+#define E1000_ERR_PHY      2
+#define E1000_ERR_CONFIG   3
+#define E1000_ERR_PARAM    4
+#define E1000_ERR_MAC_TYPE 5
+#define E1000_ERR_NOLINK   6
+#define E1000_ERR_TIMEOUT  7
+
+/* PCI Device IDs */
+#define E1000_DEV_ID_82542          0x1000
+#define E1000_DEV_ID_82543GC_FIBER  0x1001
+#define E1000_DEV_ID_82543GC_COPPER 0x1004
+#define E1000_DEV_ID_82544EI_COPPER 0x1008
+#define E1000_DEV_ID_82544EI_FIBER  0x1009
+#define E1000_DEV_ID_82544GC_COPPER 0x100C
+#define E1000_DEV_ID_82544GC_LOM    0x100D
+#define E1000_DEV_ID_82540EM        0x100E
+#define E1000_DEV_ID_82540EM_LOM    0x1015
+#define E1000_DEV_ID_82545EM_COPPER 0x100F
+#define E1000_DEV_ID_82545EM_FIBER  0x1011
+#define E1000_DEV_ID_82546EB_COPPER 0x1010
+#define E1000_DEV_ID_82546EB_FIBER  0x1012
+#define NUM_DEV_IDS 13
+
+#define NODE_ADDRESS_SIZE 6
+#define ETH_LENGTH_OF_ADDRESS 6
+
+/* MAC decode size is 128K - This is the size of BAR0 */
+#define MAC_DECODE_SIZE (128 * 1024)
+
+#define E1000_82542_2_0_REV_ID 2
+#define E1000_82542_2_1_REV_ID 3
+
+#define SPEED_10    10
+#define SPEED_100   100
+#define SPEED_1000  1000
+#define HALF_DUPLEX 1
+#define FULL_DUPLEX 2
+
+/* The sizes (in bytes) of a ethernet packet */
+#define ENET_HEADER_SIZE             14
+#define MAXIMUM_ETHERNET_FRAME_SIZE  1518      /* With FCS */
+#define MINIMUM_ETHERNET_FRAME_SIZE  64        /* With FCS */
+#define ETHERNET_FCS_SIZE            4
+#define MAXIMUM_ETHERNET_PACKET_SIZE \
+    (MAXIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE)
+#define MINIMUM_ETHERNET_PACKET_SIZE \
+    (MINIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE)
+#define CRC_LENGTH                   ETHERNET_FCS_SIZE
+#define MAX_JUMBO_FRAME_SIZE         0x3F00
+
+/* 802.1q VLAN Packet Sizes */
+#define VLAN_TAG_SIZE                     4    /* 802.3ac tag (not DMAed) */
+
+/* Ethertype field values */
+#define ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.3ac packet */
+#define ETHERNET_IP_TYPE        0x0800 /* IP packets */
+#define ETHERNET_ARP_TYPE       0x0806 /* Address Resolution Protocol (ARP) */
+
+/* Packet Header defines */
+#define IP_PROTOCOL_TCP    6
+#define IP_PROTOCOL_UDP    0x11
+
+/* This defines the bits that are set in the Interrupt Mask
+ * Set/Read Register.  Each bit is documented below:
+ *   o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
+ *   o RXSEQ  = Receive Sequence Error
+ */
+#define POLL_IMS_ENABLE_MASK ( \
+    E1000_IMS_RXDMT0 |         \
+    E1000_IMS_RXSEQ)
+
+/* This defines the bits that are set in the Interrupt Mask
+ * Set/Read Register.  Each bit is documented below:
+ *   o RXT0   = Receiver Timer Interrupt (ring 0)
+ *   o TXDW   = Transmit Descriptor Written Back
+ *   o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
+ *   o RXSEQ  = Receive Sequence Error
+ *   o LSC    = Link Status Change
+ */
+#define IMS_ENABLE_MASK ( \
+    E1000_IMS_RXT0   |    \
+    E1000_IMS_TXDW   |    \
+    E1000_IMS_RXDMT0 |    \
+    E1000_IMS_RXSEQ  |    \
+    E1000_IMS_LSC)
+
+/* The number of high/low register pairs in the RAR. The RAR (Receive Address
+ * Registers) holds the directed and multicast addresses that we monitor. We
+ * reserve one of these spots for our directed address, allowing us room for
+ * E1000_RAR_ENTRIES - 1 multicast addresses.
+ */
+#define E1000_RAR_ENTRIES 16
+
+#define MIN_NUMBER_OF_DESCRIPTORS 8
+#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
+
+/* Receive Descriptor */
+struct e1000_rx_desc {
+       uint64_t buffer_addr;   /* Address of the descriptor's data buffer */
+       uint16_t length;        /* Length of data DMAed into data buffer */
+       uint16_t csum;          /* Packet checksum */
+       uint8_t status;         /* Descriptor status */
+       uint8_t errors;         /* Descriptor Errors */
+       uint16_t special;
+};
+
+/* Receive Decriptor bit definitions */
+#define E1000_RXD_STAT_DD       0x01   /* Descriptor Done */
+#define E1000_RXD_STAT_EOP      0x02   /* End of Packet */
+#define E1000_RXD_STAT_IXSM     0x04   /* Ignore checksum */
+#define E1000_RXD_STAT_VP       0x08   /* IEEE VLAN Packet */
+#define E1000_RXD_STAT_TCPCS    0x20   /* TCP xsum calculated */
+#define E1000_RXD_STAT_IPCS     0x40   /* IP xsum calculated */
+#define E1000_RXD_STAT_PIF      0x80   /* passed in-exact filter */
+#define E1000_RXD_ERR_CE        0x01   /* CRC Error */
+#define E1000_RXD_ERR_SE        0x02   /* Symbol Error */
+#define E1000_RXD_ERR_SEQ       0x04   /* Sequence Error */
+#define E1000_RXD_ERR_CXE       0x10   /* Carrier Extension Error */
+#define E1000_RXD_ERR_TCPE      0x20   /* TCP/UDP Checksum Error */
+#define E1000_RXD_ERR_IPE       0x40   /* IP Checksum Error */
+#define E1000_RXD_ERR_RXE       0x80   /* Rx Data Error */
+#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
+#define E1000_RXD_SPC_PRI_MASK  0xE000 /* Priority is in upper 3 bits */
+#define E1000_RXD_SPC_PRI_SHIFT 0x000D /* Priority is in upper 3 of 16 */
+#define E1000_RXD_SPC_CFI_MASK  0x1000 /* CFI is bit 12 */
+#define E1000_RXD_SPC_CFI_SHIFT 0x000C /* CFI is bit 12 */
+
+/* mask to determine if packets should be dropped due to frame errors */
+#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
+    E1000_RXD_ERR_CE  |                \
+    E1000_RXD_ERR_SE  |                \
+    E1000_RXD_ERR_SEQ |                \
+    E1000_RXD_ERR_CXE |                \
+    E1000_RXD_ERR_RXE)
+
+/* Transmit Descriptor */
+struct e1000_tx_desc {
+       uint64_t buffer_addr;   /* Address of the descriptor's data buffer */
+       union {
+               uint32_t data;
+               struct {
+                       uint16_t length;        /* Data buffer length */
+                       uint8_t cso;    /* Checksum offset */
+                       uint8_t cmd;    /* Descriptor control */
+               } flags;
+       } lower;
+       union {
+               uint32_t data;
+               struct {
+                       uint8_t status; /* Descriptor status */
+                       uint8_t css;    /* Checksum start */
+                       uint16_t special;
+               } fields;
+       } upper;
+};
+
+/* Transmit Descriptor bit definitions */
+#define E1000_TXD_DTYP_D     0x00100000        /* Data Descriptor */
+#define E1000_TXD_DTYP_C     0x00000000        /* Context Descriptor */
+#define E1000_TXD_POPTS_IXSM 0x01      /* Insert IP checksum */
+#define E1000_TXD_POPTS_TXSM 0x02      /* Insert TCP/UDP checksum */
+#define E1000_TXD_CMD_EOP    0x01000000        /* End of Packet */
+#define E1000_TXD_CMD_IFCS   0x02000000        /* Insert FCS (Ethernet CRC) */
+#define E1000_TXD_CMD_IC     0x04000000        /* Insert Checksum */
+#define E1000_TXD_CMD_RS     0x08000000        /* Report Status */
+#define E1000_TXD_CMD_RPS    0x10000000        /* Report Packet Sent */
+#define E1000_TXD_CMD_DEXT   0x20000000        /* Descriptor extension (0 = legacy) */
+#define E1000_TXD_CMD_VLE    0x40000000        /* Add VLAN tag */
+#define E1000_TXD_CMD_IDE    0x80000000        /* Enable Tidv register */
+#define E1000_TXD_STAT_DD    0x00000001        /* Descriptor Done */
+#define E1000_TXD_STAT_EC    0x00000002        /* Excess Collisions */
+#define E1000_TXD_STAT_LC    0x00000004        /* Late Collisions */
+#define E1000_TXD_STAT_TU    0x00000008        /* Transmit underrun */
+#define E1000_TXD_CMD_TCP    0x01000000        /* TCP packet */
+#define E1000_TXD_CMD_IP     0x02000000        /* IP packet */
+#define E1000_TXD_CMD_TSE    0x04000000        /* TCP Seg enable */
+#define E1000_TXD_STAT_TC    0x00000004        /* Tx Underrun */
+
+/* Offload Context Descriptor */
+struct e1000_context_desc {
+       union {
+               uint32_t ip_config;
+               struct {
+                       uint8_t ipcss;  /* IP checksum start */
+                       uint8_t ipcso;  /* IP checksum offset */
+                       uint16_t ipcse; /* IP checksum end */
+               } ip_fields;
+       } lower_setup;
+       union {
+               uint32_t tcp_config;
+               struct {
+                       uint8_t tucss;  /* TCP checksum start */
+                       uint8_t tucso;  /* TCP checksum offset */
+                       uint16_t tucse; /* TCP checksum end */
+               } tcp_fields;
+       } upper_setup;
+       uint32_t cmd_and_length;        /* */
+       union {
+               uint32_t data;
+               struct {
+                       uint8_t status; /* Descriptor status */
+                       uint8_t hdr_len;        /* Header length */
+                       uint16_t mss;   /* Maximum segment size */
+               } fields;
+       } tcp_seg_setup;
+};
+
+/* Offload data descriptor */
+struct e1000_data_desc {
+       uint64_t buffer_addr;   /* Address of the descriptor's buffer address */
+       union {
+               uint32_t data;
+               struct {
+                       uint16_t length;        /* Data buffer length */
+                       uint8_t typ_len_ext;    /* */
+                       uint8_t cmd;    /* */
+               } flags;
+       } lower;
+       union {
+               uint32_t data;
+               struct {
+                       uint8_t status; /* Descriptor status */
+                       uint8_t popts;  /* Packet Options */
+                       uint16_t special;       /* */
+               } fields;
+       } upper;
+};
+
+/* Filters */
+#define E1000_NUM_UNICAST          16  /* Unicast filter entries */
+#define E1000_MC_TBL_SIZE          128 /* Multicast Filter Table (4096 bits) */
+#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
+
+/* Receive Address Register */
+struct e1000_rar {
+       volatile uint32_t low;  /* receive address low */
+       volatile uint32_t high; /* receive address high */
+};
+
+/* The number of entries in the Multicast Table Array (MTA). */
+#define E1000_NUM_MTA_REGISTERS 128
+
+/* IPv4 Address Table Entry */
+struct e1000_ipv4_at_entry {
+       volatile uint32_t ipv4_addr;    /* IP Address (RW) */
+       volatile uint32_t reserved;
+};
+
+/* Four wakeup IP addresses are supported */
+#define E1000_WAKEUP_IP_ADDRESS_COUNT_MAX 4
+#define E1000_IP4AT_SIZE                  E1000_WAKEUP_IP_ADDRESS_COUNT_MAX
+#define E1000_IP6AT_SIZE                  1
+
+/* IPv6 Address Table Entry */
+struct e1000_ipv6_at_entry {
+       volatile uint8_t ipv6_addr[16];
+};
+
+/* Flexible Filter Length Table Entry */
+struct e1000_fflt_entry {
+       volatile uint32_t length;       /* Flexible Filter Length (RW) */
+       volatile uint32_t reserved;
+};
+
+/* Flexible Filter Mask Table Entry */
+struct e1000_ffmt_entry {
+       volatile uint32_t mask; /* Flexible Filter Mask (RW) */
+       volatile uint32_t reserved;
+};
+
+/* Flexible Filter Value Table Entry */
+struct e1000_ffvt_entry {
+       volatile uint32_t value;        /* Flexible Filter Value (RW) */
+       volatile uint32_t reserved;
+};
+
+/* Four Flexible Filters are supported */
+#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4
+
+/* Each Flexible Filter is at most 128 (0x80) bytes in length */
+#define E1000_FLEXIBLE_FILTER_SIZE_MAX  128
+
+#define E1000_FFLT_SIZE E1000_FLEXIBLE_FILTER_COUNT_MAX
+#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
+#define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
+
+/* Register Set. (82543, 82544)
+ *
+ * Registers are defined to be 32 bits and  should be accessed as 32 bit values.
+ * These registers are physically located on the NIC, but are mapped into the
+ * host memory address space.
+ *
+ * RW - register is both readable and writable
+ * RO - register is read only
+ * WO - register is write only
+ * R/clr - register is read only and is cleared when read
+ * A - register array
+ */
+#define E1000_CTRL     0x00000 /* Device Control - RW */
+#define E1000_STATUS   0x00008 /* Device Status - RO */
+#define E1000_EECD     0x00010 /* EEPROM/Flash Control - RW */
+#define E1000_EERD     0x00014 /* EEPROM Read - RW */
+#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
+#define E1000_MDIC     0x00020 /* MDI Control - RW */
+#define E1000_FCAL     0x00028 /* Flow Control Address Low - RW */
+#define E1000_FCAH     0x0002C /* Flow Control Address High -RW */
+#define E1000_FCT      0x00030 /* Flow Control Type - RW */
+#define E1000_VET      0x00038 /* VLAN Ether Type - RW */
+#define E1000_ICR      0x000C0 /* Interrupt Cause Read - R/clr */
+#define E1000_ITR      0x000C4 /* Interrupt Throttling Rate - RW */
+#define E1000_ICS      0x000C8 /* Interrupt Cause Set - WO */
+#define E1000_IMS      0x000D0 /* Interrupt Mask Set - RW */
+#define E1000_IMC      0x000D8 /* Interrupt Mask Clear - WO */
+#define E1000_RCTL     0x00100 /* RX Control - RW */
+#define E1000_FCTTV    0x00170 /* Flow Control Transmit Timer Value - RW */
+#define E1000_TXCW     0x00178 /* TX Configuration Word - RW */
+#define E1000_RXCW     0x00180 /* RX Configuration Word - RO */
+#define E1000_TCTL     0x00400 /* TX Control - RW */
+#define E1000_TIPG     0x00410 /* TX Inter-packet gap -RW */
+#define E1000_TBT      0x00448 /* TX Burst Timer - RW */
+#define E1000_AIT      0x00458 /* Adaptive Interframe Spacing Throttle - RW */
+#define E1000_LEDCTL   0x00E00 /* LED Control - RW */
+#define E1000_PBA      0x01000 /* Packet Buffer Allocation - RW */
+#define E1000_FCRTL    0x02160 /* Flow Control Receive Threshold Low - RW */
+#define E1000_FCRTH    0x02168 /* Flow Control Receive Threshold High - RW */
+#define E1000_RDBAL    0x02800 /* RX Descriptor Base Address Low - RW */
+#define E1000_RDBAH    0x02804 /* RX Descriptor Base Address High - RW */
+#define E1000_RDLEN    0x02808 /* RX Descriptor Length - RW */
+#define E1000_RDH      0x02810 /* RX Descriptor Head - RW */
+#define E1000_RDT      0x02818 /* RX Descriptor Tail - RW */
+#define E1000_RDTR     0x02820 /* RX Delay Timer - RW */
+#define E1000_RXDCTL   0x02828 /* RX Descriptor Control - RW */
+#define E1000_RADV     0x0282C /* RX Interrupt Absolute Delay Timer - RW */
+#define E1000_RSRPD    0x02C00 /* RX Small Packet Detect - RW */
+#define E1000_TXDMAC   0x03000 /* TX DMA Control - RW */
+#define E1000_TDBAL    0x03800 /* TX Descriptor Base Address Low - RW */
+#define E1000_TDBAH    0x03804 /* TX Descriptor Base Address High - RW */
+#define E1000_TDLEN    0x03808 /* TX Descriptor Length - RW */
+#define E1000_TDH      0x03810 /* TX Descriptor Head - RW */
+#define E1000_TDT      0x03818 /* TX Descripotr Tail - RW */
+#define E1000_TIDV     0x03820 /* TX Interrupt Delay Value - RW */
+#define E1000_TXDCTL   0x03828 /* TX Descriptor Control - RW */
+#define E1000_TADV     0x0382C /* TX Interrupt Absolute Delay Val - RW */
+#define E1000_TSPMT    0x03830 /* TCP Segmentation PAD & Min Threshold - RW */
+#define E1000_CRCERRS  0x04000 /* CRC Error Count - R/clr */
+#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
+#define E1000_SYMERRS  0x04008 /* Symbol Error Count - R/clr */
+#define E1000_RXERRC   0x0400C /* Receive Error Count - R/clr */
+#define E1000_MPC      0x04010 /* Missed Packet Count - R/clr */
+#define E1000_SCC      0x04014 /* Single Collision Count - R/clr */
+#define E1000_ECOL     0x04018 /* Excessive Collision Count - R/clr */
+#define E1000_MCC      0x0401C /* Multiple Collision Count - R/clr */
+#define E1000_LATECOL  0x04020 /* Late Collision Count - R/clr */
+#define E1000_COLC     0x04028 /* Collision Count - R/clr */
+#define E1000_DC       0x04030 /* Defer Count - R/clr */
+#define E1000_TNCRS    0x04034 /* TX-No CRS - R/clr */
+#define E1000_SEC      0x04038 /* Sequence Error Count - R/clr */
+#define E1000_CEXTERR  0x0403C /* Carrier Extension Error Count - R/clr */
+#define E1000_RLEC     0x04040 /* Receive Length Error Count - R/clr */
+#define E1000_XONRXC   0x04048 /* XON RX Count - R/clr */
+#define E1000_XONTXC   0x0404C /* XON TX Count - R/clr */
+#define E1000_XOFFRXC  0x04050 /* XOFF RX Count - R/clr */
+#define E1000_XOFFTXC  0x04054 /* XOFF TX Count - R/clr */
+#define E1000_FCRUC    0x04058 /* Flow Control RX Unsupported Count- R/clr */
+#define E1000_PRC64    0x0405C /* Packets RX (64 bytes) - R/clr */
+#define E1000_PRC127   0x04060 /* Packets RX (65-127 bytes) - R/clr */
+#define E1000_PRC255   0x04064 /* Packets RX (128-255 bytes) - R/clr */
+#define E1000_PRC511   0x04068 /* Packets RX (255-511 bytes) - R/clr */
+#define E1000_PRC1023  0x0406C /* Packets RX (512-1023 bytes) - R/clr */
+#define E1000_PRC1522  0x04070 /* Packets RX (1024-1522 bytes) - R/clr */
+#define E1000_GPRC     0x04074 /* Good Packets RX Count - R/clr */
+#define E1000_BPRC     0x04078 /* Broadcast Packets RX Count - R/clr */
+#define E1000_MPRC     0x0407C /* Multicast Packets RX Count - R/clr */
+#define E1000_GPTC     0x04080 /* Good Packets TX Count - R/clr */
+#define E1000_GORCL    0x04088 /* Good Octets RX Count Low - R/clr */
+#define E1000_GORCH    0x0408C /* Good Octets RX Count High - R/clr */
+#define E1000_GOTCL    0x04090 /* Good Octets TX Count Low - R/clr */
+#define E1000_GOTCH    0x04094 /* Good Octets TX Count High - R/clr */
+#define E1000_RNBC     0x040A0 /* RX No Buffers Count - R/clr */
+#define E1000_RUC      0x040A4 /* RX Undersize Count - R/clr */
+#define E1000_RFC      0x040A8 /* RX Fragment Count - R/clr */
+#define E1000_ROC      0x040AC /* RX Oversize Count - R/clr */
+#define E1000_RJC      0x040B0 /* RX Jabber Count - R/clr */
+#define E1000_MGTPRC   0x040B4 /* Management Packets RX Count - R/clr */
+#define E1000_MGTPDC   0x040B8 /* Management Packets Dropped Count - R/clr */
+#define E1000_MGTPTC   0x040BC /* Management Packets TX Count - R/clr */
+#define E1000_TORL     0x040C0 /* Total Octets RX Low - R/clr */
+#define E1000_TORH     0x040C4 /* Total Octets RX High - R/clr */
+#define E1000_TOTL     0x040C8 /* Total Octets TX Low - R/clr */
+#define E1000_TOTH     0x040CC /* Total Octets TX High - R/clr */
+#define E1000_TPR      0x040D0 /* Total Packets RX - R/clr */
+#define E1000_TPT      0x040D4 /* Total Packets TX - R/clr */
+#define E1000_PTC64    0x040D8 /* Packets TX (64 bytes) - R/clr */
+#define E1000_PTC127   0x040DC /* Packets TX (65-127 bytes) - R/clr */
+#define E1000_PTC255   0x040E0 /* Packets TX (128-255 bytes) - R/clr */
+#define E1000_PTC511   0x040E4 /* Packets TX (256-511 bytes) - R/clr */
+#define E1000_PTC1023  0x040E8 /* Packets TX (512-1023 bytes) - R/clr */
+#define E1000_PTC1522  0x040EC /* Packets TX (1024-1522 Bytes) - R/clr */
+#define E1000_MPTC     0x040F0 /* Multicast Packets TX Count - R/clr */
+#define E1000_BPTC     0x040F4 /* Broadcast Packets TX Count - R/clr */
+#define E1000_TSCTC    0x040F8 /* TCP Segmentation Context TX - R/clr */
+#define E1000_TSCTFC   0x040FC /* TCP Segmentation Context TX Fail - R/clr */
+#define E1000_RXCSUM   0x05000 /* RX Checksum Control - RW */
+#define E1000_MTA      0x05200 /* Multicast Table Array - RW Array */
+#define E1000_RA       0x05400 /* Receive Address - RW Array */
+#define E1000_VFTA     0x05600 /* VLAN Filter Table Array - RW Array */
+#define E1000_WUC      0x05800 /* Wakeup Control - RW */
+#define E1000_WUFC     0x05808 /* Wakeup Filter Control - RW */
+#define E1000_WUS      0x05810 /* Wakeup Status - RO */
+#define E1000_MANC     0x05820 /* Management Control - RW */
+#define E1000_IPAV     0x05838 /* IP Address Valid - RW */
+#define E1000_IP4AT    0x05840 /* IPv4 Address Table - RW Array */
+#define E1000_IP6AT    0x05880 /* IPv6 Address Table - RW Array */
+#define E1000_WUPL     0x05900 /* Wakeup Packet Length - RW */
+#define E1000_WUPM     0x05A00 /* Wakeup Packet Memory - RO A */
+#define E1000_FFLT     0x05F00 /* Flexible Filter Length Table - RW Array */
+#define E1000_FFMT     0x09000 /* Flexible Filter Mask Table - RW Array */
+#define E1000_FFVT     0x09800 /* Flexible Filter Value Table - RW Array */
+
+/* Register Set (82542)
+ *
+ * Some of the 82542 registers are located at different offsets than they are
+ * in more current versions of the 8254x. Despite the difference in location,
+ * the registers function in the same manner.
+ */
+#define E1000_82542_CTRL     E1000_CTRL
+#define E1000_82542_STATUS   E1000_STATUS
+#define E1000_82542_EECD     E1000_EECD
+#define E1000_82542_EERD     E1000_EERD
+#define E1000_82542_CTRL_EXT E1000_CTRL_EXT
+#define E1000_82542_MDIC     E1000_MDIC
+#define E1000_82542_FCAL     E1000_FCAL
+#define E1000_82542_FCAH     E1000_FCAH
+#define E1000_82542_FCT      E1000_FCT
+#define E1000_82542_VET      E1000_VET
+#define E1000_82542_RA       0x00040
+#define E1000_82542_ICR      E1000_ICR
+#define E1000_82542_ITR      E1000_ITR
+#define E1000_82542_ICS      E1000_ICS
+#define E1000_82542_IMS      E1000_IMS
+#define E1000_82542_IMC      E1000_IMC
+#define E1000_82542_RCTL     E1000_RCTL
+#define E1000_82542_RDTR     0x00108
+#define E1000_82542_RDBAL    0x00110
+#define E1000_82542_RDBAH    0x00114
+#define E1000_82542_RDLEN    0x00118
+#define E1000_82542_RDH      0x00120
+#define E1000_82542_RDT      0x00128
+#define E1000_82542_FCRTH    0x00160
+#define E1000_82542_FCRTL    0x00168
+#define E1000_82542_FCTTV    E1000_FCTTV
+#define E1000_82542_TXCW     E1000_TXCW
+#define E1000_82542_RXCW     E1000_RXCW
+#define E1000_82542_MTA      0x00200
+#define E1000_82542_TCTL     E1000_TCTL
+#define E1000_82542_TIPG     E1000_TIPG
+#define E1000_82542_TDBAL    0x00420
+#define E1000_82542_TDBAH    0x00424
+#define E1000_82542_TDLEN    0x00428
+#define E1000_82542_TDH      0x00430
+#define E1000_82542_TDT      0x00438
+#define E1000_82542_TIDV     0x00440
+#define E1000_82542_TBT      E1000_TBT
+#define E1000_82542_AIT      E1000_AIT
+#define E1000_82542_VFTA     0x00600
+#define E1000_82542_LEDCTL   E1000_LEDCTL
+#define E1000_82542_PBA      E1000_PBA
+#define E1000_82542_RXDCTL   E1000_RXDCTL
+#define E1000_82542_RADV     E1000_RADV
+#define E1000_82542_RSRPD    E1000_RSRPD
+#define E1000_82542_TXDMAC   E1000_TXDMAC
+#define E1000_82542_TXDCTL   E1000_TXDCTL
+#define E1000_82542_TADV     E1000_TADV
+#define E1000_82542_TSPMT    E1000_TSPMT
+#define E1000_82542_CRCERRS  E1000_CRCERRS
+#define E1000_82542_ALGNERRC E1000_ALGNERRC
+#define E1000_82542_SYMERRS  E1000_SYMERRS
+#define E1000_82542_RXERRC   E1000_RXERRC
+#define E1000_82542_MPC      E1000_MPC
+#define E1000_82542_SCC      E1000_SCC
+#define E1000_82542_ECOL     E1000_ECOL
+#define E1000_82542_MCC      E1000_MCC
+#define E1000_82542_LATECOL  E1000_LATECOL
+#define E1000_82542_COLC     E1000_COLC
+#define E1000_82542_DC       E1000_DC
+#define E1000_82542_TNCRS    E1000_TNCRS
+#define E1000_82542_SEC      E1000_SEC
+#define E1000_82542_CEXTERR  E1000_CEXTERR
+#define E1000_82542_RLEC     E1000_RLEC
+#define E1000_82542_XONRXC   E1000_XONRXC
+#define E1000_82542_XONTXC   E1000_XONTXC
+#define E1000_82542_XOFFRXC  E1000_XOFFRXC
+#define E1000_82542_XOFFTXC  E1000_XOFFTXC
+#define E1000_82542_FCRUC    E1000_FCRUC
+#define E1000_82542_PRC64    E1000_PRC64
+#define E1000_82542_PRC127   E1000_PRC127
+#define E1000_82542_PRC255   E1000_PRC255
+#define E1000_82542_PRC511   E1000_PRC511
+#define E1000_82542_PRC1023  E1000_PRC1023
+#define E1000_82542_PRC1522  E1000_PRC1522
+#define E1000_82542_GPRC     E1000_GPRC
+#define E1000_82542_BPRC     E1000_BPRC
+#define E1000_82542_MPRC     E1000_MPRC
+#define E1000_82542_GPTC     E1000_GPTC
+#define E1000_82542_GORCL    E1000_GORCL
+#define E1000_82542_GORCH    E1000_GORCH
+#define E1000_82542_GOTCL    E1000_GOTCL
+#define E1000_82542_GOTCH    E1000_GOTCH
+#define E1000_82542_RNBC     E1000_RNBC
+#define E1000_82542_RUC      E1000_RUC
+#define E1000_82542_RFC      E1000_RFC
+#define E1000_82542_ROC      E1000_ROC
+#define E1000_82542_RJC      E1000_RJC
+#define E1000_82542_MGTPRC   E1000_MGTPRC
+#define E1000_82542_MGTPDC   E1000_MGTPDC
+#define E1000_82542_MGTPTC   E1000_MGTPTC
+#define E1000_82542_TORL     E1000_TORL
+#define E1000_82542_TORH     E1000_TORH
+#define E1000_82542_TOTL     E1000_TOTL
+#define E1000_82542_TOTH     E1000_TOTH
+#define E1000_82542_TPR      E1000_TPR
+#define E1000_82542_TPT      E1000_TPT
+#define E1000_82542_PTC64    E1000_PTC64
+#define E1000_82542_PTC127   E1000_PTC127
+#define E1000_82542_PTC255   E1000_PTC255
+#define E1000_82542_PTC511   E1000_PTC511
+#define E1000_82542_PTC1023  E1000_PTC1023
+#define E1000_82542_PTC1522  E1000_PTC1522
+#define E1000_82542_MPTC     E1000_MPTC
+#define E1000_82542_BPTC     E1000_BPTC
+#define E1000_82542_TSCTC    E1000_TSCTC
+#define E1000_82542_TSCTFC   E1000_TSCTFC
+#define E1000_82542_RXCSUM   E1000_RXCSUM
+#define E1000_82542_WUC      E1000_WUC
+#define E1000_82542_WUFC     E1000_WUFC
+#define E1000_82542_WUS      E1000_WUS
+#define E1000_82542_MANC     E1000_MANC
+#define E1000_82542_IPAV     E1000_IPAV
+#define E1000_82542_IP4AT    E1000_IP4AT
+#define E1000_82542_IP6AT    E1000_IP6AT
+#define E1000_82542_WUPL     E1000_WUPL
+#define E1000_82542_WUPM     E1000_WUPM
+#define E1000_82542_FFLT     E1000_FFLT
+#define E1000_82542_FFMT     E1000_FFMT
+#define E1000_82542_FFVT     E1000_FFVT
+
+/* Statistics counters collected by the MAC */
+struct e1000_hw_stats {
+       uint64_t crcerrs;
+       uint64_t algnerrc;
+       uint64_t symerrs;
+       uint64_t rxerrc;
+       uint64_t mpc;
+       uint64_t scc;
+       uint64_t ecol;
+       uint64_t mcc;
+       uint64_t latecol;
+       uint64_t colc;
+       uint64_t dc;
+       uint64_t tncrs;
+       uint64_t sec;
+       uint64_t cexterr;
+       uint64_t rlec;
+       uint64_t xonrxc;
+       uint64_t xontxc;
+       uint64_t xoffrxc;
+       uint64_t xofftxc;
+       uint64_t fcruc;
+       uint64_t prc64;
+       uint64_t prc127;
+       uint64_t prc255;
+       uint64_t prc511;
+       uint64_t prc1023;
+       uint64_t prc1522;
+       uint64_t gprc;
+       uint64_t bprc;
+       uint64_t mprc;
+       uint64_t gptc;
+       uint64_t gorcl;
+       uint64_t gorch;
+       uint64_t gotcl;
+       uint64_t gotch;
+       uint64_t rnbc;
+       uint64_t ruc;
+       uint64_t rfc;
+       uint64_t roc;
+       uint64_t rjc;
+       uint64_t mgprc;
+       uint64_t mgpdc;
+       uint64_t mgptc;
+       uint64_t torl;
+       uint64_t torh;
+       uint64_t totl;
+       uint64_t toth;
+       uint64_t tpr;
+       uint64_t tpt;
+       uint64_t ptc64;
+       uint64_t ptc127;
+       uint64_t ptc255;
+       uint64_t ptc511;
+       uint64_t ptc1023;
+       uint64_t ptc1522;
+       uint64_t mptc;
+       uint64_t bptc;
+       uint64_t tsctc;
+       uint64_t tsctfc;
+};
+
+/* Structure containing variables used by the shared code (e1000_hw.c) */
+struct e1000_hw {
+       pci_dev_t pdev;
+       uint8_t *hw_addr;
+       e1000_mac_type mac_type;
+       e1000_media_type media_type;
+       e1000_lan_loc lan_loc;
+       e1000_fc_type fc;
+#if 0
+       e1000_bus_speed bus_speed;
+       e1000_bus_width bus_width;
+       e1000_bus_type bus_type;
+       uint32_t io_base;
+#endif
+       uint32_t phy_id;
+       uint32_t phy_addr;
+       uint32_t original_fc;
+       uint32_t txcw;
+       uint32_t autoneg_failed;
+#if 0
+       uint32_t max_frame_size;
+       uint32_t min_frame_size;
+       uint32_t mc_filter_type;
+       uint32_t num_mc_addrs;
+       uint32_t collision_delta;
+       uint32_t tx_packet_delta;
+       uint32_t ledctl_default;
+       uint32_t ledctl_mode1;
+       uint32_t ledctl_mode2;
+#endif
+       uint16_t autoneg_advertised;
+       uint16_t pci_cmd_word;
+       uint16_t fc_high_water;
+       uint16_t fc_low_water;
+       uint16_t fc_pause_time;
+#if 0
+       uint16_t current_ifs_val;
+       uint16_t ifs_min_val;
+       uint16_t ifs_max_val;
+       uint16_t ifs_step_size;
+       uint16_t ifs_ratio;
+#endif
+       uint16_t device_id;
+       uint16_t vendor_id;
+       uint16_t subsystem_id;
+       uint16_t subsystem_vendor_id;
+       uint8_t revision_id;
+#if 0
+       uint8_t autoneg;
+       uint8_t mdix;
+       uint8_t forced_speed_duplex;
+       uint8_t wait_autoneg_complete;
+       uint8_t dma_fairness;
+#endif
+#if 0
+       uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
+       boolean_t disable_polarity_correction;
+#endif
+       boolean_t get_link_status;
+       boolean_t tbi_compatibility_en;
+       boolean_t tbi_compatibility_on;
+       boolean_t fc_send_xon;
+       boolean_t report_tx_early;
+#if 0
+       boolean_t adaptive_ifs;
+       boolean_t ifs_params_forced;
+       boolean_t in_ifs_mode;
+#endif
+};
+
+#define E1000_EEPROM_SWDPIN0   0x0001  /* SWDPIN 0 EEPROM Value */
+#define E1000_EEPROM_LED_LOGIC 0x0020  /* Led Logic Word */
+
+/* Register Bit Masks */
+/* Device Control */
+#define E1000_CTRL_FD       0x00000001 /* Full duplex.0=half; 1=full */
+#define E1000_CTRL_BEM      0x00000002 /* Endian Mode.0=little,1=big */
+#define E1000_CTRL_PRIOR    0x00000004 /* Priority on PCI. 0=rx,1=fair */
+#define E1000_CTRL_LRST     0x00000008 /* Link reset. 0=normal,1=reset */
+#define E1000_CTRL_TME      0x00000010 /* Test mode. 0=normal,1=test */
+#define E1000_CTRL_SLE      0x00000020 /* Serial Link on 0=dis,1=en */
+#define E1000_CTRL_ASDE     0x00000020 /* Auto-speed detect enable */
+#define E1000_CTRL_SLU      0x00000040 /* Set link up (Force Link) */
+#define E1000_CTRL_ILOS     0x00000080 /* Invert Loss-Of Signal */
+#define E1000_CTRL_SPD_SEL  0x00000300 /* Speed Select Mask */
+#define E1000_CTRL_SPD_10   0x00000000 /* Force 10Mb */
+#define E1000_CTRL_SPD_100  0x00000100 /* Force 100Mb */
+#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */
+#define E1000_CTRL_BEM32    0x00000400 /* Big Endian 32 mode */
+#define E1000_CTRL_FRCSPD   0x00000800 /* Force Speed */
+#define E1000_CTRL_FRCDPX   0x00001000 /* Force Duplex */
+#define E1000_CTRL_SWDPIN0  0x00040000 /* SWDPIN 0 value */
+#define E1000_CTRL_SWDPIN1  0x00080000 /* SWDPIN 1 value */
+#define E1000_CTRL_SWDPIN2  0x00100000 /* SWDPIN 2 value */
+#define E1000_CTRL_SWDPIN3  0x00200000 /* SWDPIN 3 value */
+#define E1000_CTRL_SWDPIO0  0x00400000 /* SWDPIN 0 Input or output */
+#define E1000_CTRL_SWDPIO1  0x00800000 /* SWDPIN 1 input or output */
+#define E1000_CTRL_SWDPIO2  0x01000000 /* SWDPIN 2 input or output */
+#define E1000_CTRL_SWDPIO3  0x02000000 /* SWDPIN 3 input or output */
+#define E1000_CTRL_RST      0x04000000 /* Global reset */
+#define E1000_CTRL_RFCE     0x08000000 /* Receive Flow Control enable */
+#define E1000_CTRL_TFCE     0x10000000 /* Transmit flow control enable */
+#define E1000_CTRL_RTE      0x20000000 /* Routing tag enable */
+#define E1000_CTRL_VME      0x40000000 /* IEEE VLAN mode enable */
+#define E1000_CTRL_PHY_RST  0x80000000 /* PHY Reset */
+
+/* Device Status */
+#define E1000_STATUS_FD         0x00000001     /* Full duplex.0=half,1=full */
+#define E1000_STATUS_LU         0x00000002     /* Link up.0=no,1=link */
+#define E1000_STATUS_FUNC_MASK  0x0000000C     /* PCI Function Mask */
+#define E1000_STATUS_FUNC_0     0x00000000     /* Function 0 */
+#define E1000_STATUS_FUNC_1     0x00000004     /* Function 1 */
+#define E1000_STATUS_TXOFF      0x00000010     /* transmission paused */
+#define E1000_STATUS_TBIMODE    0x00000020     /* TBI mode */
+#define E1000_STATUS_SPEED_MASK 0x000000C0
+#define E1000_STATUS_SPEED_10   0x00000000     /* Speed 10Mb/s */
+#define E1000_STATUS_SPEED_100  0x00000040     /* Speed 100Mb/s */
+#define E1000_STATUS_SPEED_1000 0x00000080     /* Speed 1000Mb/s */
+#define E1000_STATUS_ASDV       0x00000300     /* Auto speed detect value */
+#define E1000_STATUS_MTXCKOK    0x00000400     /* MTX clock running OK */
+#define E1000_STATUS_PCI66      0x00000800     /* In 66Mhz slot */
+#define E1000_STATUS_BUS64      0x00001000     /* In 64 bit slot */
+#define E1000_STATUS_PCIX_MODE  0x00002000     /* PCI-X mode */
+#define E1000_STATUS_PCIX_SPEED 0x0000C000     /* PCI-X bus speed */
+
+/* Constants used to intrepret the masked PCI-X bus speed. */
+#define E1000_STATUS_PCIX_SPEED_66  0x00000000 /* PCI-X bus speed  50-66 MHz */
+#define E1000_STATUS_PCIX_SPEED_100 0x00004000 /* PCI-X bus speed  66-100 MHz */
+#define E1000_STATUS_PCIX_SPEED_133 0x00008000 /* PCI-X bus speed 100-133 MHz */
+
+/* EEPROM/Flash Control */
+#define E1000_EECD_SK        0x00000001        /* EEPROM Clock */
+#define E1000_EECD_CS        0x00000002        /* EEPROM Chip Select */
+#define E1000_EECD_DI        0x00000004        /* EEPROM Data In */
+#define E1000_EECD_DO        0x00000008        /* EEPROM Data Out */
+#define E1000_EECD_FWE_MASK  0x00000030
+#define E1000_EECD_FWE_DIS   0x00000010        /* Disable FLASH writes */
+#define E1000_EECD_FWE_EN    0x00000020        /* Enable FLASH writes */
+#define E1000_EECD_FWE_SHIFT 4
+#define E1000_EECD_SIZE      0x00000200        /* EEPROM Size (0=64 word 1=256 word) */
+#define E1000_EECD_REQ       0x00000040        /* EEPROM Access Request */
+#define E1000_EECD_GNT       0x00000080        /* EEPROM Access Grant */
+#define E1000_EECD_PRES      0x00000100        /* EEPROM Present */
+
+/* EEPROM Read */
+#define E1000_EERD_START      0x00000001       /* Start Read */
+#define E1000_EERD_DONE       0x00000010       /* Read Done */
+#define E1000_EERD_ADDR_SHIFT 8
+#define E1000_EERD_ADDR_MASK  0x0000FF00       /* Read Address */
+#define E1000_EERD_DATA_SHIFT 16
+#define E1000_EERD_DATA_MASK  0xFFFF0000       /* Read Data */
+
+/* Extended Device Control */
+#define E1000_CTRL_EXT_GPI0_EN   0x00000001    /* Maps SDP4 to GPI0 */
+#define E1000_CTRL_EXT_GPI1_EN   0x00000002    /* Maps SDP5 to GPI1 */
+#define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN
+#define E1000_CTRL_EXT_GPI2_EN   0x00000004    /* Maps SDP6 to GPI2 */
+#define E1000_CTRL_EXT_GPI3_EN   0x00000008    /* Maps SDP7 to GPI3 */
+#define E1000_CTRL_EXT_SDP4_DATA 0x00000010    /* Value of SW Defineable Pin 4 */
+#define E1000_CTRL_EXT_SDP5_DATA 0x00000020    /* Value of SW Defineable Pin 5 */
+#define E1000_CTRL_EXT_PHY_INT   E1000_CTRL_EXT_SDP5_DATA
+#define E1000_CTRL_EXT_SDP6_DATA 0x00000040    /* Value of SW Defineable Pin 6 */
+#define E1000_CTRL_EXT_SWDPIN6          0x00000040     /* SWDPIN 6 value */
+#define E1000_CTRL_EXT_SDP7_DATA 0x00000080    /* Value of SW Defineable Pin 7 */
+#define E1000_CTRL_EXT_SWDPIN7          0x00000080     /* SWDPIN 7 value */
+#define E1000_CTRL_EXT_SDP4_DIR  0x00000100    /* Direction of SDP4 0=in 1=out */
+#define E1000_CTRL_EXT_SDP5_DIR  0x00000200    /* Direction of SDP5 0=in 1=out */
+#define E1000_CTRL_EXT_SDP6_DIR  0x00000400    /* Direction of SDP6 0=in 1=out */
+#define E1000_CTRL_EXT_SWDPIO6   0x00000400    /* SWDPIN 6 Input or output */
+#define E1000_CTRL_EXT_SDP7_DIR  0x00000800    /* Direction of SDP7 0=in 1=out */
+#define E1000_CTRL_EXT_SWDPIO7   0x00000800    /* SWDPIN 7 Input or output */
+#define E1000_CTRL_EXT_ASDCHK    0x00001000    /* Initiate an ASD sequence */
+#define E1000_CTRL_EXT_EE_RST    0x00002000    /* Reinitialize from EEPROM */
+#define E1000_CTRL_EXT_IPS       0x00004000    /* Invert Power State */
+#define E1000_CTRL_EXT_SPD_BYPS  0x00008000    /* Speed Select Bypass */
+#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
+#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
+#define E1000_CTRL_EXT_LINK_MODE_TBI  0x00C00000
+#define E1000_CTRL_EXT_WR_WMARK_MASK  0x03000000
+#define E1000_CTRL_EXT_WR_WMARK_256   0x00000000
+#define E1000_CTRL_EXT_WR_WMARK_320   0x01000000
+#define E1000_CTRL_EXT_WR_WMARK_384   0x02000000
+#define E1000_CTRL_EXT_WR_WMARK_448   0x03000000
+
+/* MDI Control */
+#define E1000_MDIC_DATA_MASK 0x0000FFFF
+#define E1000_MDIC_REG_MASK  0x001F0000
+#define E1000_MDIC_REG_SHIFT 16
+#define E1000_MDIC_PHY_MASK  0x03E00000
+#define E1000_MDIC_PHY_SHIFT 21
+#define E1000_MDIC_OP_WRITE  0x04000000
+#define E1000_MDIC_OP_READ   0x08000000
+#define E1000_MDIC_READY     0x10000000
+#define E1000_MDIC_INT_EN    0x20000000
+#define E1000_MDIC_ERROR     0x40000000
+
+/* LED Control */
+#define E1000_LEDCTL_LED0_MODE_MASK  0x0000000F
+#define E1000_LEDCTL_LED0_MODE_SHIFT 0
+#define E1000_LEDCTL_LED0_IVRT       0x00000040
+#define E1000_LEDCTL_LED0_BLINK      0x00000080
+#define E1000_LEDCTL_LED1_MODE_MASK  0x00000F00
+#define E1000_LEDCTL_LED1_MODE_SHIFT 8
+#define E1000_LEDCTL_LED1_IVRT       0x00004000
+#define E1000_LEDCTL_LED1_BLINK      0x00008000
+#define E1000_LEDCTL_LED2_MODE_MASK  0x000F0000
+#define E1000_LEDCTL_LED2_MODE_SHIFT 16
+#define E1000_LEDCTL_LED2_IVRT       0x00400000
+#define E1000_LEDCTL_LED2_BLINK      0x00800000
+#define E1000_LEDCTL_LED3_MODE_MASK  0x0F000000
+#define E1000_LEDCTL_LED3_MODE_SHIFT 24
+#define E1000_LEDCTL_LED3_IVRT       0x40000000
+#define E1000_LEDCTL_LED3_BLINK      0x80000000
+
+#define E1000_LEDCTL_MODE_LINK_10_1000  0x0
+#define E1000_LEDCTL_MODE_LINK_100_1000 0x1
+#define E1000_LEDCTL_MODE_LINK_UP       0x2
+#define E1000_LEDCTL_MODE_ACTIVITY      0x3
+#define E1000_LEDCTL_MODE_LINK_ACTIVITY 0x4
+#define E1000_LEDCTL_MODE_LINK_10       0x5
+#define E1000_LEDCTL_MODE_LINK_100      0x6
+#define E1000_LEDCTL_MODE_LINK_1000     0x7
+#define E1000_LEDCTL_MODE_PCIX_MODE     0x8
+#define E1000_LEDCTL_MODE_FULL_DUPLEX   0x9
+#define E1000_LEDCTL_MODE_COLLISION     0xA
+#define E1000_LEDCTL_MODE_BUS_SPEED     0xB
+#define E1000_LEDCTL_MODE_BUS_SIZE      0xC
+#define E1000_LEDCTL_MODE_PAUSED        0xD
+#define E1000_LEDCTL_MODE_LED_ON        0xE
+#define E1000_LEDCTL_MODE_LED_OFF       0xF
+
+/* Receive Address */
+#define E1000_RAH_AV  0x80000000       /* Receive descriptor valid */
+
+/* Interrupt Cause Read */
+#define E1000_ICR_TXDW    0x00000001   /* Transmit desc written back */
+#define E1000_ICR_TXQE    0x00000002   /* Transmit Queue empty */
+#define E1000_ICR_LSC     0x00000004   /* Link Status Change */
+#define E1000_ICR_RXSEQ   0x00000008   /* rx sequence error */
+#define E1000_ICR_RXDMT0  0x00000010   /* rx desc min. threshold (0) */
+#define E1000_ICR_RXO     0x00000040   /* rx overrun */
+#define E1000_ICR_RXT0    0x00000080   /* rx timer intr (ring 0) */
+#define E1000_ICR_MDAC    0x00000200   /* MDIO access complete */
+#define E1000_ICR_RXCFG   0x00000400   /* RX /c/ ordered set */
+#define E1000_ICR_GPI_EN0 0x00000800   /* GP Int 0 */
+#define E1000_ICR_GPI_EN1 0x00001000   /* GP Int 1 */
+#define E1000_ICR_GPI_EN2 0x00002000   /* GP Int 2 */
+#define E1000_ICR_GPI_EN3 0x00004000   /* GP Int 3 */
+#define E1000_ICR_TXD_LOW 0x00008000
+#define E1000_ICR_SRPD    0x00010000
+
+/* Interrupt Cause Set */
+#define E1000_ICS_TXDW    E1000_ICR_TXDW       /* Transmit desc written back */
+#define E1000_ICS_TXQE    E1000_ICR_TXQE       /* Transmit Queue empty */
+#define E1000_ICS_LSC     E1000_ICR_LSC        /* Link Status Change */
+#define E1000_ICS_RXSEQ   E1000_ICR_RXSEQ      /* rx sequence error */
+#define E1000_ICS_RXDMT0  E1000_ICR_RXDMT0     /* rx desc min. threshold */
+#define E1000_ICS_RXO     E1000_ICR_RXO        /* rx overrun */
+#define E1000_ICS_RXT0    E1000_ICR_RXT0       /* rx timer intr */
+#define E1000_ICS_MDAC    E1000_ICR_MDAC       /* MDIO access complete */
+#define E1000_ICS_RXCFG   E1000_ICR_RXCFG      /* RX /c/ ordered set */
+#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0    /* GP Int 0 */
+#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1    /* GP Int 1 */
+#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2    /* GP Int 2 */
+#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3    /* GP Int 3 */
+#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW
+#define E1000_ICS_SRPD    E1000_ICR_SRPD
+
+/* Interrupt Mask Set */
+#define E1000_IMS_TXDW    E1000_ICR_TXDW       /* Transmit desc written back */
+#define E1000_IMS_TXQE    E1000_ICR_TXQE       /* Transmit Queue empty */
+#define E1000_IMS_LSC     E1000_ICR_LSC        /* Link Status Change */
+#define E1000_IMS_RXSEQ   E1000_ICR_RXSEQ      /* rx sequence error */
+#define E1000_IMS_RXDMT0  E1000_ICR_RXDMT0     /* rx desc min. threshold */
+#define E1000_IMS_RXO     E1000_ICR_RXO        /* rx overrun */
+#define E1000_IMS_RXT0    E1000_ICR_RXT0       /* rx timer intr */
+#define E1000_IMS_MDAC    E1000_ICR_MDAC       /* MDIO access complete */
+#define E1000_IMS_RXCFG   E1000_ICR_RXCFG      /* RX /c/ ordered set */
+#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0    /* GP Int 0 */
+#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1    /* GP Int 1 */
+#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2    /* GP Int 2 */
+#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3    /* GP Int 3 */
+#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
+#define E1000_IMS_SRPD    E1000_ICR_SRPD
+
+/* Interrupt Mask Clear */
+#define E1000_IMC_TXDW    E1000_ICR_TXDW       /* Transmit desc written back */
+#define E1000_IMC_TXQE    E1000_ICR_TXQE       /* Transmit Queue empty */
+#define E1000_IMC_LSC     E1000_ICR_LSC        /* Link Status Change */
+#define E1000_IMC_RXSEQ   E1000_ICR_RXSEQ      /* rx sequence error */
+#define E1000_IMC_RXDMT0  E1000_ICR_RXDMT0     /* rx desc min. threshold */
+#define E1000_IMC_RXO     E1000_ICR_RXO        /* rx overrun */
+#define E1000_IMC_RXT0    E1000_ICR_RXT0       /* rx timer intr */
+#define E1000_IMC_MDAC    E1000_ICR_MDAC       /* MDIO access complete */
+#define E1000_IMC_RXCFG   E1000_ICR_RXCFG      /* RX /c/ ordered set */
+#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0    /* GP Int 0 */
+#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1    /* GP Int 1 */
+#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2    /* GP Int 2 */
+#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3    /* GP Int 3 */
+#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW
+#define E1000_IMC_SRPD    E1000_ICR_SRPD
+
+/* Receive Control */
+#define E1000_RCTL_RST          0x00000001     /* Software reset */
+#define E1000_RCTL_EN           0x00000002     /* enable */
+#define E1000_RCTL_SBP          0x00000004     /* store bad packet */
+#define E1000_RCTL_UPE          0x00000008     /* unicast promiscuous enable */
+#define E1000_RCTL_MPE          0x00000010     /* multicast promiscuous enab */
+#define E1000_RCTL_LPE          0x00000020     /* long packet enable */
+#define E1000_RCTL_LBM_NO       0x00000000     /* no loopback mode */
+#define E1000_RCTL_LBM_MAC      0x00000040     /* MAC loopback mode */
+#define E1000_RCTL_LBM_SLP      0x00000080     /* serial link loopback mode */
+#define E1000_RCTL_LBM_TCVR     0x000000C0     /* tcvr loopback mode */
+#define E1000_RCTL_RDMTS_HALF   0x00000000     /* rx desc min threshold size */
+#define E1000_RCTL_RDMTS_QUAT   0x00000100     /* rx desc min threshold size */
+#define E1000_RCTL_RDMTS_EIGTH  0x00000200     /* rx desc min threshold size */
+#define E1000_RCTL_MO_SHIFT     12     /* multicast offset shift */
+#define E1000_RCTL_MO_0         0x00000000     /* multicast offset 11:0 */
+#define E1000_RCTL_MO_1         0x00001000     /* multicast offset 12:1 */
+#define E1000_RCTL_MO_2         0x00002000     /* multicast offset 13:2 */
+#define E1000_RCTL_MO_3         0x00003000     /* multicast offset 15:4 */
+#define E1000_RCTL_MDR          0x00004000     /* multicast desc ring 0 */
+#define E1000_RCTL_BAM          0x00008000     /* broadcast enable */
+/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
+#define E1000_RCTL_SZ_2048      0x00000000     /* rx buffer size 2048 */
+#define E1000_RCTL_SZ_1024      0x00010000     /* rx buffer size 1024 */
+#define E1000_RCTL_SZ_512       0x00020000     /* rx buffer size 512 */
+#define E1000_RCTL_SZ_256       0x00030000     /* rx buffer size 256 */
+/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
+#define E1000_RCTL_SZ_16384     0x00010000     /* rx buffer size 16384 */
+#define E1000_RCTL_SZ_8192      0x00020000     /* rx buffer size 8192 */
+#define E1000_RCTL_SZ_4096      0x00030000     /* rx buffer size 4096 */
+#define E1000_RCTL_VFE          0x00040000     /* vlan filter enable */
+#define E1000_RCTL_CFIEN        0x00080000     /* canonical form enable */
+#define E1000_RCTL_CFI          0x00100000     /* canonical form indicator */
+#define E1000_RCTL_DPF          0x00400000     /* discard pause frames */
+#define E1000_RCTL_PMCF         0x00800000     /* pass MAC control frames */
+#define E1000_RCTL_BSEX         0x02000000     /* Buffer size extension */
+
+/* Receive Descriptor */
+#define E1000_RDT_DELAY 0x0000ffff     /* Delay timer (1=1024us) */
+#define E1000_RDT_FPDB  0x80000000     /* Flush descriptor block */
+#define E1000_RDLEN_LEN 0x0007ff80     /* descriptor length */
+#define E1000_RDH_RDH   0x0000ffff     /* receive descriptor head */
+#define E1000_RDT_RDT   0x0000ffff     /* receive descriptor tail */
+
+/* Flow Control */
+#define E1000_FCRTH_RTH  0x0000FFF8    /* Mask Bits[15:3] for RTH */
+#define E1000_FCRTH_XFCE 0x80000000    /* External Flow Control Enable */
+#define E1000_FCRTL_RTL  0x0000FFF8    /* Mask Bits[15:3] for RTL */
+#define E1000_FCRTL_XONE 0x80000000    /* Enable XON frame transmission */
+
+/* Receive Descriptor Control */
+#define E1000_RXDCTL_PTHRESH 0x0000003F        /* RXDCTL Prefetch Threshold */
+#define E1000_RXDCTL_HTHRESH 0x00003F00        /* RXDCTL Host Threshold */
+#define E1000_RXDCTL_WTHRESH 0x003F0000        /* RXDCTL Writeback Threshold */
+#define E1000_RXDCTL_GRAN    0x01000000        /* RXDCTL Granularity */
+
+/* Transmit Descriptor Control */
+#define E1000_TXDCTL_PTHRESH 0x000000FF        /* TXDCTL Prefetch Threshold */
+#define E1000_TXDCTL_HTHRESH 0x0000FF00        /* TXDCTL Host Threshold */
+#define E1000_TXDCTL_WTHRESH 0x00FF0000        /* TXDCTL Writeback Threshold */
+#define E1000_TXDCTL_GRAN    0x01000000        /* TXDCTL Granularity */
+#define E1000_TXDCTL_LWTHRESH 0xFE000000       /* TXDCTL Low Threshold */
+#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000        /* GRAN=1, WTHRESH=1 */
+
+/* Transmit Configuration Word */
+#define E1000_TXCW_FD         0x00000020       /* TXCW full duplex */
+#define E1000_TXCW_HD         0x00000040       /* TXCW half duplex */
+#define E1000_TXCW_PAUSE      0x00000080       /* TXCW sym pause request */
+#define E1000_TXCW_ASM_DIR    0x00000100       /* TXCW astm pause direction */
+#define E1000_TXCW_PAUSE_MASK 0x00000180       /* TXCW pause request mask */
+#define E1000_TXCW_RF         0x00003000       /* TXCW remote fault */
+#define E1000_TXCW_NP         0x00008000       /* TXCW next page */
+#define E1000_TXCW_CW         0x0000ffff       /* TxConfigWord mask */
+#define E1000_TXCW_TXC        0x40000000       /* Transmit Config control */
+#define E1000_TXCW_ANE        0x80000000       /* Auto-neg enable */
+
+/* Receive Configuration Word */
+#define E1000_RXCW_CW    0x0000ffff    /* RxConfigWord mask */
+#define E1000_RXCW_NC    0x04000000    /* Receive config no carrier */
+#define E1000_RXCW_IV    0x08000000    /* Receive config invalid */
+#define E1000_RXCW_CC    0x10000000    /* Receive config change */
+#define E1000_RXCW_C     0x20000000    /* Receive config */
+#define E1000_RXCW_SYNCH 0x40000000    /* Receive config synch */
+#define E1000_RXCW_ANC   0x80000000    /* Auto-neg complete */
+
+/* Transmit Control */
+#define E1000_TCTL_RST    0x00000001   /* software reset */
+#define E1000_TCTL_EN     0x00000002   /* enable tx */
+#define E1000_TCTL_BCE    0x00000004   /* busy check enable */
+#define E1000_TCTL_PSP    0x00000008   /* pad short packets */
+#define E1000_TCTL_CT     0x00000ff0   /* collision threshold */
+#define E1000_TCTL_COLD   0x003ff000   /* collision distance */
+#define E1000_TCTL_SWXOFF 0x00400000   /* SW Xoff transmission */
+#define E1000_TCTL_PBE    0x00800000   /* Packet Burst Enable */
+#define E1000_TCTL_RTLC   0x01000000   /* Re-transmit on late collision */
+#define E1000_TCTL_NRTU   0x02000000   /* No Re-transmit on underrun */
+
+/* Receive Checksum Control */
+#define E1000_RXCSUM_PCSS_MASK 0x000000FF      /* Packet Checksum Start */
+#define E1000_RXCSUM_IPOFL     0x00000100      /* IPv4 checksum offload */
+#define E1000_RXCSUM_TUOFL     0x00000200      /* TCP / UDP checksum offload */
+#define E1000_RXCSUM_IPV6OFL   0x00000400      /* IPv6 checksum offload */
+
+/* Definitions for power management and wakeup registers */
+/* Wake Up Control */
+#define E1000_WUC_APME       0x00000001        /* APM Enable */
+#define E1000_WUC_PME_EN     0x00000002        /* PME Enable */
+#define E1000_WUC_PME_STATUS 0x00000004        /* PME Status */
+#define E1000_WUC_APMPME     0x00000008        /* Assert PME on APM Wakeup */
+
+/* Wake Up Filter Control */
+#define E1000_WUFC_LNKC 0x00000001     /* Link Status Change Wakeup Enable */
+#define E1000_WUFC_MAG  0x00000002     /* Magic Packet Wakeup Enable */
+#define E1000_WUFC_EX   0x00000004     /* Directed Exact Wakeup Enable */
+#define E1000_WUFC_MC   0x00000008     /* Directed Multicast Wakeup Enable */
+#define E1000_WUFC_BC   0x00000010     /* Broadcast Wakeup Enable */
+#define E1000_WUFC_ARP  0x00000020     /* ARP Request Packet Wakeup Enable */
+#define E1000_WUFC_IPV4 0x00000040     /* Directed IPv4 Packet Wakeup Enable */
+#define E1000_WUFC_IPV6 0x00000080     /* Directed IPv6 Packet Wakeup Enable */
+#define E1000_WUFC_FLX0 0x00010000     /* Flexible Filter 0 Enable */
+#define E1000_WUFC_FLX1 0x00020000     /* Flexible Filter 1 Enable */
+#define E1000_WUFC_FLX2 0x00040000     /* Flexible Filter 2 Enable */
+#define E1000_WUFC_FLX3 0x00080000     /* Flexible Filter 3 Enable */
+#define E1000_WUFC_ALL_FILTERS 0x000F00FF      /* Mask for all wakeup filters */
+#define E1000_WUFC_FLX_OFFSET 16       /* Offset to the Flexible Filters bits */
+#define E1000_WUFC_FLX_FILTERS 0x000F0000      /* Mask for the 4 flexible filters */
+
+/* Wake Up Status */
+#define E1000_WUS_LNKC 0x00000001      /* Link Status Changed */
+#define E1000_WUS_MAG  0x00000002      /* Magic Packet Received */
+#define E1000_WUS_EX   0x00000004      /* Directed Exact Received */
+#define E1000_WUS_MC   0x00000008      /* Directed Multicast Received */
+#define E1000_WUS_BC   0x00000010      /* Broadcast Received */
+#define E1000_WUS_ARP  0x00000020      /* ARP Request Packet Received */
+#define E1000_WUS_IPV4 0x00000040      /* Directed IPv4 Packet Wakeup Received */
+#define E1000_WUS_IPV6 0x00000080      /* Directed IPv6 Packet Wakeup Received */
+#define E1000_WUS_FLX0 0x00010000      /* Flexible Filter 0 Match */
+#define E1000_WUS_FLX1 0x00020000      /* Flexible Filter 1 Match */
+#define E1000_WUS_FLX2 0x00040000      /* Flexible Filter 2 Match */
+#define E1000_WUS_FLX3 0x00080000      /* Flexible Filter 3 Match */
+#define E1000_WUS_FLX_FILTERS 0x000F0000       /* Mask for the 4 flexible filters */
+
+/* Management Control */
+#define E1000_MANC_SMBUS_EN      0x00000001    /* SMBus Enabled - RO */
+#define E1000_MANC_ASF_EN        0x00000002    /* ASF Enabled - RO */
+#define E1000_MANC_R_ON_FORCE    0x00000004    /* Reset on Force TCO - RO */
+#define E1000_MANC_RMCP_EN       0x00000100    /* Enable RCMP 026Fh Filtering */
+#define E1000_MANC_0298_EN       0x00000200    /* Enable RCMP 0298h Filtering */
+#define E1000_MANC_IPV4_EN       0x00000400    /* Enable IPv4 */
+#define E1000_MANC_IPV6_EN       0x00000800    /* Enable IPv6 */
+#define E1000_MANC_SNAP_EN       0x00001000    /* Accept LLC/SNAP */
+#define E1000_MANC_ARP_EN        0x00002000    /* Enable ARP Request Filtering */
+#define E1000_MANC_NEIGHBOR_EN   0x00004000    /* Enable Neighbor Discovery
+                                                * Filtering */
+#define E1000_MANC_TCO_RESET     0x00010000    /* TCO Reset Occurred */
+#define E1000_MANC_RCV_TCO_EN    0x00020000    /* Receive TCO Packets Enabled */
+#define E1000_MANC_REPORT_STATUS 0x00040000    /* Status Reporting Enabled */
+#define E1000_MANC_SMB_REQ       0x01000000    /* SMBus Request */
+#define E1000_MANC_SMB_GNT       0x02000000    /* SMBus Grant */
+#define E1000_MANC_SMB_CLK_IN    0x04000000    /* SMBus Clock In */
+#define E1000_MANC_SMB_DATA_IN   0x08000000    /* SMBus Data In */
+#define E1000_MANC_SMB_DATA_OUT  0x10000000    /* SMBus Data Out */
+#define E1000_MANC_SMB_CLK_OUT   0x20000000    /* SMBus Clock Out */
+
+#define E1000_MANC_SMB_DATA_OUT_SHIFT  28      /* SMBus Data Out Shift */
+#define E1000_MANC_SMB_CLK_OUT_SHIFT   29      /* SMBus Clock Out Shift */
+
+/* Wake Up Packet Length */
+#define E1000_WUPL_LENGTH_MASK 0x0FFF  /* Only the lower 12 bits are valid */
+
+#define E1000_MDALIGN          4096
+
+/* EEPROM Commands */
+#define EEPROM_READ_OPCODE  0x6        /* EERPOM read opcode */
+#define EEPROM_WRITE_OPCODE 0x5        /* EERPOM write opcode */
+#define EEPROM_ERASE_OPCODE 0x7        /* EERPOM erase opcode */
+#define EEPROM_EWEN_OPCODE  0x13       /* EERPOM erase/write enable */
+#define EEPROM_EWDS_OPCODE  0x10       /* EERPOM erast/write disable */
+
+/* EEPROM Word Offsets */
+#define EEPROM_COMPAT              0x0003
+#define EEPROM_ID_LED_SETTINGS     0x0004
+#define EEPROM_INIT_CONTROL1_REG   0x000A
+#define EEPROM_INIT_CONTROL2_REG   0x000F
+#define EEPROM_FLASH_VERSION       0x0032
+#define EEPROM_CHECKSUM_REG        0x003F
+
+/* Word definitions for ID LED Settings */
+#define ID_LED_RESERVED_0000 0x0000
+#define ID_LED_RESERVED_FFFF 0xFFFF
+#define ID_LED_DEFAULT       ((ID_LED_OFF1_ON2 << 12) | \
+                             (ID_LED_OFF1_OFF2 << 8) | \
+                             (ID_LED_DEF1_DEF2 << 4) | \
+                             (ID_LED_DEF1_DEF2))
+#define ID_LED_DEF1_DEF2     0x1
+#define ID_LED_DEF1_ON2      0x2
+#define ID_LED_DEF1_OFF2     0x3
+#define ID_LED_ON1_DEF2      0x4
+#define ID_LED_ON1_ON2       0x5
+#define ID_LED_ON1_OFF2      0x6
+#define ID_LED_OFF1_DEF2     0x7
+#define ID_LED_OFF1_ON2      0x8
+#define ID_LED_OFF1_OFF2     0x9
+
+/* Mask bits for fields in Word 0x03 of the EEPROM */
+#define EEPROM_COMPAT_SERVER 0x0400
+#define EEPROM_COMPAT_CLIENT 0x0200
+
+/* Mask bits for fields in Word 0x0a of the EEPROM */
+#define EEPROM_WORD0A_ILOS   0x0010
+#define EEPROM_WORD0A_SWDPIO 0x01E0
+#define EEPROM_WORD0A_LRST   0x0200
+#define EEPROM_WORD0A_FD     0x0400
+#define EEPROM_WORD0A_66MHZ  0x0800
+
+/* Mask bits for fields in Word 0x0f of the EEPROM */
+#define EEPROM_WORD0F_PAUSE_MASK 0x3000
+#define EEPROM_WORD0F_PAUSE      0x1000
+#define EEPROM_WORD0F_ASM_DIR    0x2000
+#define EEPROM_WORD0F_ANE        0x0800
+#define EEPROM_WORD0F_SWPDIO_EXT 0x00F0
+
+/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */
+#define EEPROM_SUM 0xBABA
+
+/* EEPROM Map defines (WORD OFFSETS)*/
+#define EEPROM_NODE_ADDRESS_BYTE_0 0
+#define EEPROM_PBA_BYTE_1          8
+
+/* EEPROM Map Sizes (Byte Counts) */
+#define PBA_SIZE 4
+
+/* Collision related configuration parameters */
+#define E1000_COLLISION_THRESHOLD       16
+#define E1000_CT_SHIFT                  4
+#define E1000_COLLISION_DISTANCE        64
+#define E1000_FDX_COLLISION_DISTANCE    E1000_COLLISION_DISTANCE
+#define E1000_HDX_COLLISION_DISTANCE    E1000_COLLISION_DISTANCE
+#define E1000_GB_HDX_COLLISION_DISTANCE 512
+#define E1000_COLD_SHIFT                12
+
+/* The number of Transmit and Receive Descriptors must be a multiple of 8 */
+#define REQ_TX_DESCRIPTOR_MULTIPLE  8
+#define REQ_RX_DESCRIPTOR_MULTIPLE  8
+
+/* Default values for the transmit IPG register */
+#define DEFAULT_82542_TIPG_IPGT        10
+#define DEFAULT_82543_TIPG_IPGT_FIBER  9
+#define DEFAULT_82543_TIPG_IPGT_COPPER 8
+
+#define E1000_TIPG_IPGT_MASK  0x000003FF
+#define E1000_TIPG_IPGR1_MASK 0x000FFC00
+#define E1000_TIPG_IPGR2_MASK 0x3FF00000
+
+#define DEFAULT_82542_TIPG_IPGR1 2
+#define DEFAULT_82543_TIPG_IPGR1 8
+#define E1000_TIPG_IPGR1_SHIFT  10
+
+#define DEFAULT_82542_TIPG_IPGR2 10
+#define DEFAULT_82543_TIPG_IPGR2 6
+#define E1000_TIPG_IPGR2_SHIFT  20
+
+#define E1000_TXDMAC_DPP 0x00000001
+
+/* Adaptive IFS defines */
+#define TX_THRESHOLD_START     8
+#define TX_THRESHOLD_INCREMENT 10
+#define TX_THRESHOLD_DECREMENT 1
+#define TX_THRESHOLD_STOP      190
+#define TX_THRESHOLD_DISABLE   0
+#define TX_THRESHOLD_TIMER_MS  10000
+#define MIN_NUM_XMITS          1000
+#define IFS_MAX                80
+#define IFS_STEP               10
+#define IFS_MIN                40
+#define IFS_RATIO              4
+
+/* PBA constants */
+#define E1000_PBA_16K 0x0010   /* 16KB, default TX allocation */
+#define E1000_PBA_24K 0x0018
+#define E1000_PBA_40K 0x0028
+#define E1000_PBA_48K 0x0030   /* 48KB, default RX allocation */
+
+/* Flow Control Constants */
+#define FLOW_CONTROL_ADDRESS_LOW  0x00C28001
+#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100
+#define FLOW_CONTROL_TYPE         0x8808
+
+/* The historical defaults for the flow control values are given below. */
+#define FC_DEFAULT_HI_THRESH        (0x8000)   /* 32KB */
+#define FC_DEFAULT_LO_THRESH        (0x4000)   /* 16KB */
+#define FC_DEFAULT_TX_TIMER         (0x100)    /* ~130 us */
+
+/* Flow Control High-Watermark: 43464 bytes */
+#define E1000_FC_HIGH_THRESH 0xA9C8
+/* Flow Control Low-Watermark: 43456 bytes */
+#define E1000_FC_LOW_THRESH 0xA9C0
+/* Flow Control Pause Time: 858 usec */
+#define E1000_FC_PAUSE_TIME 0x0680
+
+/* PCIX Config space */
+#define PCIX_COMMAND_REGISTER    0xE6
+#define PCIX_STATUS_REGISTER_LO  0xE8
+#define PCIX_STATUS_REGISTER_HI  0xEA
+
+#define PCIX_COMMAND_MMRBC_MASK      0x000C
+#define PCIX_COMMAND_MMRBC_SHIFT     0x2
+#define PCIX_STATUS_HI_MMRBC_MASK    0x0060
+#define PCIX_STATUS_HI_MMRBC_SHIFT   0x5
+#define PCIX_STATUS_HI_MMRBC_4K      0x3
+#define PCIX_STATUS_HI_MMRBC_2K      0x2
+
+/* The number of bits that we need to shift right to move the "pause"
+ * bits from the EEPROM (bits 13:12) to the "pause" (bits 8:7) field
+ * in the TXCW register
+ */
+#define PAUSE_SHIFT 5
+
+/* The number of bits that we need to shift left to move the "SWDPIO"
+ * bits from the EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field
+ * in the CTRL register
+ */
+#define SWDPIO_SHIFT 17
+
+/* The number of bits that we need to shift left to move the "SWDPIO_EXT"
+ * bits from the EEPROM word F (bits 7:4) to the bits 11:8 of The
+ * Extended CTRL register.
+ * in the CTRL register
+ */
+#define SWDPIO__EXT_SHIFT 4
+
+/* The number of bits that we need to shift left to move the "ILOS"
+ * bit from the EEPROM (bit 4) to the "ILOS" (bit 7) field
+ * in the CTRL register
+ */
+#define ILOS_SHIFT  3
+
+#define RECEIVE_BUFFER_ALIGN_SIZE  (256)
+
+/* The number of milliseconds we wait for auto-negotiation to complete */
+#define LINK_UP_TIMEOUT             500
+
+#define E1000_TX_BUFFER_SIZE ((uint32_t)1514)
+
+/* The carrier extension symbol, as received by the NIC. */
+#define CARRIER_EXTENSION   0x0F
+
+/* TBI_ACCEPT macro definition:
+ *
+ * This macro requires:
+ *      adapter = a pointer to struct e1000_hw
+ *      status = the 8 bit status field of the RX descriptor with EOP set
+ *      error = the 8 bit error field of the RX descriptor with EOP set
+ *      length = the sum of all the length fields of the RX descriptors that
+ *               make up the current frame
+ *      last_byte = the last byte of the frame DMAed by the hardware
+ *      max_frame_length = the maximum frame length we want to accept.
+ *      min_frame_length = the minimum frame length we want to accept.
+ *
+ * This macro is a conditional that should be used in the interrupt
+ * handler's Rx processing routine when RxErrors have been detected.
+ *
+ * Typical use:
+ *  ...
+ *  if (TBI_ACCEPT) {
+ *      accept_frame = TRUE;
+ *      e1000_tbi_adjust_stats(adapter, MacAddress);
+ *      frame_length--;
+ *  } else {
+ *      accept_frame = FALSE;
+ *  }
+ *  ...
+ */
+
+#define TBI_ACCEPT(adapter, status, errors, length, last_byte) \
+    ((adapter)->tbi_compatibility_on && \
+     (((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \
+     ((last_byte) == CARRIER_EXTENSION) && \
+     (((status) & E1000_RXD_STAT_VP) ? \
+         (((length) > ((adapter)->min_frame_size - VLAN_TAG_SIZE)) && \
+          ((length) <= ((adapter)->max_frame_size + 1))) : \
+         (((length) > (adapter)->min_frame_size) && \
+          ((length) <= ((adapter)->max_frame_size + VLAN_TAG_SIZE + 1)))))
+
+/* Structures, enums, and macros for the PHY */
+
+/* Bit definitions for the Management Data IO (MDIO) and Management Data
+ * Clock (MDC) pins in the Device Control Register.
+ */
+#define E1000_CTRL_PHY_RESET_DIR  E1000_CTRL_SWDPIO0
+#define E1000_CTRL_PHY_RESET      E1000_CTRL_SWDPIN0
+#define E1000_CTRL_MDIO_DIR       E1000_CTRL_SWDPIO2
+#define E1000_CTRL_MDIO           E1000_CTRL_SWDPIN2
+#define E1000_CTRL_MDC_DIR        E1000_CTRL_SWDPIO3
+#define E1000_CTRL_MDC            E1000_CTRL_SWDPIN3
+#define E1000_CTRL_PHY_RESET_DIR4 E1000_CTRL_EXT_SDP4_DIR
+#define E1000_CTRL_PHY_RESET4     E1000_CTRL_EXT_SDP4_DATA
+
+/* PHY 1000 MII Register/Bit Definitions */
+/* PHY Registers defined by IEEE */
+#define PHY_CTRL         0x00  /* Control Register */
+#define PHY_STATUS       0x01  /* Status Regiser */
+#define PHY_ID1          0x02  /* Phy Id Reg (word 1) */
+#define PHY_ID2          0x03  /* Phy Id Reg (word 2) */
+#define PHY_AUTONEG_ADV  0x04  /* Autoneg Advertisement */
+#define PHY_LP_ABILITY   0x05  /* Link Partner Ability (Base Page) */
+#define PHY_AUTONEG_EXP  0x06  /* Autoneg Expansion Reg */
+#define PHY_NEXT_PAGE_TX 0x07  /* Next Page TX */
+#define PHY_LP_NEXT_PAGE 0x08  /* Link Partner Next Page */
+#define PHY_1000T_CTRL   0x09  /* 1000Base-T Control Reg */
+#define PHY_1000T_STATUS 0x0A  /* 1000Base-T Status Reg */
+#define PHY_EXT_STATUS   0x0F  /* Extended Status Reg */
+
+/* M88E1000 Specific Registers */
+#define M88E1000_PHY_SPEC_CTRL     0x10        /* PHY Specific Control Register */
+#define M88E1000_PHY_SPEC_STATUS   0x11        /* PHY Specific Status Register */
+#define M88E1000_INT_ENABLE        0x12        /* Interrupt Enable Register */
+#define M88E1000_INT_STATUS        0x13        /* Interrupt Status Register */
+#define M88E1000_EXT_PHY_SPEC_CTRL 0x14        /* Extended PHY Specific Control */
+#define M88E1000_RX_ERR_CNTR       0x15        /* Receive Error Counter */
+
+#define MAX_PHY_REG_ADDRESS 0x1F       /* 5 bit address bus (0-0x1F) */
+
+/* PHY Control Register */
+#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */
+#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
+#define MII_CR_FULL_DUPLEX      0x0100 /* FDX =1, half duplex =0 */
+#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
+#define MII_CR_ISOLATE          0x0400 /* Isolate PHY from MII */
+#define MII_CR_POWER_DOWN       0x0800 /* Power down */
+#define MII_CR_AUTO_NEG_EN      0x1000 /* Auto Neg Enable */
+#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */
+#define MII_CR_LOOPBACK         0x4000 /* 0 = normal, 1 = loopback */
+#define MII_CR_RESET            0x8000 /* 0 = normal, 1 = PHY reset */
+
+/* PHY Status Register */
+#define MII_SR_EXTENDED_CAPS     0x0001        /* Extended register capabilities */
+#define MII_SR_JABBER_DETECT     0x0002        /* Jabber Detected */
+#define MII_SR_LINK_STATUS       0x0004        /* Link Status 1 = link */
+#define MII_SR_AUTONEG_CAPS      0x0008        /* Auto Neg Capable */
+#define MII_SR_REMOTE_FAULT      0x0010        /* Remote Fault Detect */
+#define MII_SR_AUTONEG_COMPLETE  0x0020        /* Auto Neg Complete */
+#define MII_SR_PREAMBLE_SUPPRESS 0x0040        /* Preamble may be suppressed */
+#define MII_SR_EXTENDED_STATUS   0x0100        /* Ext. status info in Reg 0x0F */
+#define MII_SR_100T2_HD_CAPS     0x0200        /* 100T2 Half Duplex Capable */
+#define MII_SR_100T2_FD_CAPS     0x0400        /* 100T2 Full Duplex Capable */
+#define MII_SR_10T_HD_CAPS       0x0800        /* 10T   Half Duplex Capable */
+#define MII_SR_10T_FD_CAPS       0x1000        /* 10T   Full Duplex Capable */
+#define MII_SR_100X_HD_CAPS      0x2000        /* 100X  Half Duplex Capable */
+#define MII_SR_100X_FD_CAPS      0x4000        /* 100X  Full Duplex Capable */
+#define MII_SR_100T4_CAPS        0x8000        /* 100T4 Capable */
+
+/* Autoneg Advertisement Register */
+#define NWAY_AR_SELECTOR_FIELD 0x0001  /* indicates IEEE 802.3 CSMA/CD */
+#define NWAY_AR_10T_HD_CAPS    0x0020  /* 10T   Half Duplex Capable */
+#define NWAY_AR_10T_FD_CAPS    0x0040  /* 10T   Full Duplex Capable */
+#define NWAY_AR_100TX_HD_CAPS  0x0080  /* 100TX Half Duplex Capable */
+#define NWAY_AR_100TX_FD_CAPS  0x0100  /* 100TX Full Duplex Capable */
+#define NWAY_AR_100T4_CAPS     0x0200  /* 100T4 Capable */
+#define NWAY_AR_PAUSE          0x0400  /* Pause operation desired */
+#define NWAY_AR_ASM_DIR        0x0800  /* Asymmetric Pause Direction bit */
+#define NWAY_AR_REMOTE_FAULT   0x2000  /* Remote Fault detected */
+#define NWAY_AR_NEXT_PAGE      0x8000  /* Next Page ability supported */
+
+/* Link Partner Ability Register (Base Page) */
+#define NWAY_LPAR_SELECTOR_FIELD 0x0000        /* LP protocol selector field */
+#define NWAY_LPAR_10T_HD_CAPS    0x0020        /* LP is 10T   Half Duplex Capable */
+#define NWAY_LPAR_10T_FD_CAPS    0x0040        /* LP is 10T   Full Duplex Capable */
+#define NWAY_LPAR_100TX_HD_CAPS  0x0080        /* LP is 100TX Half Duplex Capable */
+#define NWAY_LPAR_100TX_FD_CAPS  0x0100        /* LP is 100TX Full Duplex Capable */
+#define NWAY_LPAR_100T4_CAPS     0x0200        /* LP is 100T4 Capable */
+#define NWAY_LPAR_PAUSE          0x0400        /* LP Pause operation desired */
+#define NWAY_LPAR_ASM_DIR        0x0800        /* LP Asymmetric Pause Direction bit */
+#define NWAY_LPAR_REMOTE_FAULT   0x2000        /* LP has detected Remote Fault */
+#define NWAY_LPAR_ACKNOWLEDGE    0x4000        /* LP has rx'd link code word */
+#define NWAY_LPAR_NEXT_PAGE      0x8000        /* Next Page ability supported */
+
+/* Autoneg Expansion Register */
+#define NWAY_ER_LP_NWAY_CAPS      0x0001       /* LP has Auto Neg Capability */
+#define NWAY_ER_PAGE_RXD          0x0002       /* LP is 10T   Half Duplex Capable */
+#define NWAY_ER_NEXT_PAGE_CAPS    0x0004       /* LP is 10T   Full Duplex Capable */
+#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008       /* LP is 100TX Half Duplex Capable */
+#define NWAY_ER_PAR_DETECT_FAULT  0x0100       /* LP is 100TX Full Duplex Capable */
+
+/* Next Page TX Register */
+#define NPTX_MSG_CODE_FIELD 0x0001     /* NP msg code or unformatted data */
+#define NPTX_TOGGLE         0x0800     /* Toggles between exchanges
+                                        * of different NP
+                                        */
+#define NPTX_ACKNOWLDGE2    0x1000     /* 1 = will comply with msg
+                                        * 0 = cannot comply with msg
+                                        */
+#define NPTX_MSG_PAGE       0x2000     /* formatted(1)/unformatted(0) pg */
+#define NPTX_NEXT_PAGE      0x8000     /* 1 = addition NP will follow
+                                        * 0 = sending last NP
+                                        */
+
+/* Link Partner Next Page Register */
+#define LP_RNPR_MSG_CODE_FIELD 0x0001  /* NP msg code or unformatted data */
+#define LP_RNPR_TOGGLE         0x0800  /* Toggles between exchanges
+                                        * of different NP
+                                        */
+#define LP_RNPR_ACKNOWLDGE2    0x1000  /* 1 = will comply with msg
+                                        * 0 = cannot comply with msg
+                                        */
+#define LP_RNPR_MSG_PAGE       0x2000  /* formatted(1)/unformatted(0) pg */
+#define LP_RNPR_ACKNOWLDGE     0x4000  /* 1 = ACK / 0 = NO ACK */
+#define LP_RNPR_NEXT_PAGE      0x8000  /* 1 = addition NP will follow
+                                        * 0 = sending last NP
+                                        */
+
+/* 1000BASE-T Control Register */
+#define CR_1000T_ASYM_PAUSE      0x0080        /* Advertise asymmetric pause bit */
+#define CR_1000T_HD_CAPS         0x0100        /* Advertise 1000T HD capability */
+#define CR_1000T_FD_CAPS         0x0200        /* Advertise 1000T FD capability  */
+#define CR_1000T_REPEATER_DTE    0x0400        /* 1=Repeater/switch device port */
+                                       /* 0=DTE device */
+#define CR_1000T_MS_VALUE        0x0800        /* 1=Configure PHY as Master */
+                                       /* 0=Configure PHY as Slave */
+#define CR_1000T_MS_ENABLE       0x1000        /* 1=Master/Slave manual config value */
+                                       /* 0=Automatic Master/Slave config */
+#define CR_1000T_TEST_MODE_NORMAL 0x0000       /* Normal Operation */
+#define CR_1000T_TEST_MODE_1     0x2000        /* Transmit Waveform test */
+#define CR_1000T_TEST_MODE_2     0x4000        /* Master Transmit Jitter test */
+#define CR_1000T_TEST_MODE_3     0x6000        /* Slave Transmit Jitter test */
+#define CR_1000T_TEST_MODE_4     0x8000        /* Transmitter Distortion test */
+
+/* 1000BASE-T Status Register */
+#define SR_1000T_IDLE_ERROR_CNT   0x00FF       /* Num idle errors since last read */
+#define SR_1000T_ASYM_PAUSE_DIR   0x0100       /* LP asymmetric pause direction bit */
+#define SR_1000T_LP_HD_CAPS       0x0400       /* LP is 1000T HD capable */
+#define SR_1000T_LP_FD_CAPS       0x0800       /* LP is 1000T FD capable */
+#define SR_1000T_REMOTE_RX_STATUS 0x1000       /* Remote receiver OK */
+#define SR_1000T_LOCAL_RX_STATUS  0x2000       /* Local receiver OK */
+#define SR_1000T_MS_CONFIG_RES    0x4000       /* 1=Local TX is Master, 0=Slave */
+#define SR_1000T_MS_CONFIG_FAULT  0x8000       /* Master/Slave config fault */
+#define SR_1000T_REMOTE_RX_STATUS_SHIFT 12
+#define SR_1000T_LOCAL_RX_STATUS_SHIFT  13
+
+/* Extended Status Register */
+#define IEEE_ESR_1000T_HD_CAPS 0x1000  /* 1000T HD capable */
+#define IEEE_ESR_1000T_FD_CAPS 0x2000  /* 1000T FD capable */
+#define IEEE_ESR_1000X_HD_CAPS 0x4000  /* 1000X HD capable */
+#define IEEE_ESR_1000X_FD_CAPS 0x8000  /* 1000X FD capable */
+
+#define PHY_TX_POLARITY_MASK   0x0100  /* register 10h bit 8 (polarity bit) */
+#define PHY_TX_NORMAL_POLARITY 0       /* register 10h bit 8 (normal polarity) */
+
+#define AUTO_POLARITY_DISABLE  0x0010  /* register 11h bit 4 */
+                                     /* (0=enable, 1=disable) */
+
+/* M88E1000 PHY Specific Control Register */
+#define M88E1000_PSCR_JABBER_DISABLE    0x0001 /* 1=Jabber Function disabled */
+#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */
+#define M88E1000_PSCR_SQE_TEST          0x0004 /* 1=SQE Test enabled */
+#define M88E1000_PSCR_CLK125_DISABLE    0x0010 /* 1=CLK125 low,
+                                                * 0=CLK125 toggling
+                                                */
+#define M88E1000_PSCR_MDI_MANUAL_MODE  0x0000  /* MDI Crossover Mode bits 6:5 */
+                                              /* Manual MDI configuration */
+#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020  /* Manual MDIX configuration */
+#define M88E1000_PSCR_AUTO_X_1000T     0x0040  /* 1000BASE-T: Auto crossover,
+                                                *  100BASE-TX/10BASE-T:
+                                                *  MDI Mode
+                                                */
+#define M88E1000_PSCR_AUTO_X_MODE      0x0060  /* Auto crossover enabled
+                                                * all speeds.
+                                                */
+#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE 0x0080
+                                       /* 1=Enable Extended 10BASE-T distance
+                                        * (Lower 10BASE-T RX Threshold)
+                                        * 0=Normal 10BASE-T RX Threshold */
+#define M88E1000_PSCR_MII_5BIT_ENABLE      0x0100
+                                       /* 1=5-Bit interface in 100BASE-TX
+                                        * 0=MII interface in 100BASE-TX */
+#define M88E1000_PSCR_SCRAMBLER_DISABLE    0x0200      /* 1=Scrambler disable */
+#define M88E1000_PSCR_FORCE_LINK_GOOD      0x0400      /* 1=Force link good */
+#define M88E1000_PSCR_ASSERT_CRS_ON_TX     0x0800      /* 1=Assert CRS on Transmit */
+
+#define M88E1000_PSCR_POLARITY_REVERSAL_SHIFT    1
+#define M88E1000_PSCR_AUTO_X_MODE_SHIFT          5
+#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7
+
+/* M88E1000 PHY Specific Status Register */
+#define M88E1000_PSSR_JABBER             0x0001        /* 1=Jabber */
+#define M88E1000_PSSR_REV_POLARITY       0x0002        /* 1=Polarity reversed */
+#define M88E1000_PSSR_MDIX               0x0040        /* 1=MDIX; 0=MDI */
+#define M88E1000_PSSR_CABLE_LENGTH       0x0380        /* 0=<50M;1=50-80M;2=80-110M;
+                                                  * 3=110-140M;4=>140M */
+#define M88E1000_PSSR_LINK               0x0400        /* 1=Link up, 0=Link down */
+#define M88E1000_PSSR_SPD_DPLX_RESOLVED  0x0800        /* 1=Speed & Duplex resolved */
+#define M88E1000_PSSR_PAGE_RCVD          0x1000        /* 1=Page received */
+#define M88E1000_PSSR_DPLX               0x2000        /* 1=Duplex 0=Half Duplex */
+#define M88E1000_PSSR_SPEED              0xC000        /* Speed, bits 14:15 */
+#define M88E1000_PSSR_10MBS              0x0000        /* 00=10Mbs */
+#define M88E1000_PSSR_100MBS             0x4000        /* 01=100Mbs */
+#define M88E1000_PSSR_1000MBS            0x8000        /* 10=1000Mbs */
+
+#define M88E1000_PSSR_REV_POLARITY_SHIFT 1
+#define M88E1000_PSSR_MDIX_SHIFT         6
+#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
+
+/* M88E1000 Extended PHY Specific Control Register */
+#define M88E1000_EPSCR_FIBER_LOOPBACK 0x4000   /* 1=Fiber loopback */
+#define M88E1000_EPSCR_DOWN_NO_IDLE   0x8000   /* 1=Lost lock detect enabled.
+                                                * Will assert lost lock and bring
+                                                * link down if idle not seen
+                                                * within 1ms in 1000BASE-T
+                                                */
+/* Number of times we will attempt to autonegotiate before downshifting if we
+ * are the master */
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X   0x0000
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_2X   0x0400
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_3X   0x0800
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_4X   0x0C00
+/* Number of times we will attempt to autonegotiate before downshifting if we
+ * are the slave */
+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK  0x0300
+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_DIS   0x0000
+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X    0x0100
+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_2X    0x0200
+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_3X    0x0300
+#define M88E1000_EPSCR_TX_CLK_2_5     0x0060   /* 2.5 MHz TX_CLK */
+#define M88E1000_EPSCR_TX_CLK_25      0x0070   /* 25  MHz TX_CLK */
+#define M88E1000_EPSCR_TX_CLK_0       0x0000   /* NO  TX_CLK */
+
+/* Bit definitions for valid PHY IDs. */
+#define M88E1000_E_PHY_ID  0x01410C50
+#define M88E1000_I_PHY_ID  0x01410C30
+#define M88E1011_I_PHY_ID  0x01410C20
+#define M88E1000_12_PHY_ID M88E1000_E_PHY_ID
+#define M88E1000_14_PHY_ID M88E1000_E_PHY_ID
+
+/* Miscellaneous PHY bit definitions. */
+#define PHY_PREAMBLE        0xFFFFFFFF
+#define PHY_SOF             0x01
+#define PHY_OP_READ         0x02
+#define PHY_OP_WRITE        0x01
+#define PHY_TURNAROUND      0x02
+#define PHY_PREAMBLE_SIZE   32
+#define MII_CR_SPEED_1000   0x0040
+#define MII_CR_SPEED_100    0x2000
+#define MII_CR_SPEED_10     0x0000
+#define E1000_PHY_ADDRESS   0x01
+#define PHY_AUTO_NEG_TIME   45 /* 4.5 Seconds */
+#define PHY_FORCE_TIME      20 /* 2.0 Seconds */
+#define PHY_REVISION_MASK   0xFFFFFFF0
+#define DEVICE_SPEED_MASK   0x00000300 /* Device Ctrl Reg Speed Mask */
+#define REG4_SPEED_MASK     0x01E0
+#define REG9_SPEED_MASK     0x0300
+#define ADVERTISE_10_HALF   0x0001
+#define ADVERTISE_10_FULL   0x0002
+#define ADVERTISE_100_HALF  0x0004
+#define ADVERTISE_100_FULL  0x0008
+#define ADVERTISE_1000_HALF 0x0010
+#define ADVERTISE_1000_FULL 0x0020
+#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F /* Everything but 1000-Half */
+
+#endif                         /* _E1000_HW_H_ */
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
new file mode 100644 (file)
index 0000000..738146e
--- /dev/null
@@ -0,0 +1,948 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <pci.h>
+#include <miiphy.h>
+
+#undef DEBUG
+
+#if defined(CONFIG_CMD_NET) \
+       && defined(CONFIG_NET_MULTI) && defined(CONFIG_EEPRO100)
+
+       /* Ethernet chip registers.
+        */
+#define SCBStatus              0       /* Rx/Command Unit Status *Word* */
+#define SCBIntAckByte          1       /* Rx/Command Unit STAT/ACK byte */
+#define SCBCmd                 2       /* Rx/Command Unit Command *Word* */
+#define SCBIntrCtlByte         3       /* Rx/Command Unit Intr.Control Byte */
+#define SCBPointer             4       /* General purpose pointer. */
+#define SCBPort                        8       /* Misc. commands and operands. */
+#define SCBflash               12      /* Flash memory control. */
+#define SCBeeprom              14      /* EEPROM memory control. */
+#define SCBCtrlMDI             16      /* MDI interface control. */
+#define SCBEarlyRx             20      /* Early receive byte count. */
+#define SCBGenControl          28      /* 82559 General Control Register */
+#define SCBGenStatus           29      /* 82559 General Status register */
+
+       /* 82559 SCB status word defnitions
+        */
+#define SCB_STATUS_CX          0x8000  /* CU finished command (transmit) */
+#define SCB_STATUS_FR          0x4000  /* frame received */
+#define SCB_STATUS_CNA         0x2000  /* CU left active state */
+#define SCB_STATUS_RNR         0x1000  /* receiver left ready state */
+#define SCB_STATUS_MDI         0x0800  /* MDI read/write cycle done */
+#define SCB_STATUS_SWI         0x0400  /* software generated interrupt */
+#define SCB_STATUS_FCP         0x0100  /* flow control pause interrupt */
+
+#define SCB_INTACK_MASK                0xFD00  /* all the above */
+
+#define SCB_INTACK_TX          (SCB_STATUS_CX | SCB_STATUS_CNA)
+#define SCB_INTACK_RX          (SCB_STATUS_FR | SCB_STATUS_RNR)
+
+       /* System control block commands
+        */
+/* CU Commands */
+#define CU_NOP                 0x0000
+#define CU_START               0x0010
+#define CU_RESUME              0x0020
+#define CU_STATSADDR           0x0040  /* Load Dump Statistics ctrs addr */
+#define CU_SHOWSTATS           0x0050  /* Dump statistics counters. */
+#define CU_ADDR_LOAD           0x0060  /* Base address to add to CU commands */
+#define CU_DUMPSTATS           0x0070  /* Dump then reset stats counters. */
+
+/* RUC Commands */
+#define RUC_NOP                        0x0000
+#define RUC_START              0x0001
+#define RUC_RESUME             0x0002
+#define RUC_ABORT              0x0004
+#define RUC_ADDR_LOAD          0x0006  /* (seems not to clear on acceptance) */
+#define RUC_RESUMENR           0x0007
+
+#define CU_CMD_MASK            0x00f0
+#define RU_CMD_MASK            0x0007
+
+#define SCB_M                  0x0100  /* 0 = enable interrupt, 1 = disable */
+#define SCB_SWI                        0x0200  /* 1 - cause device to interrupt */
+
+#define CU_STATUS_MASK         0x00C0
+#define RU_STATUS_MASK         0x003C
+
+#define RU_STATUS_IDLE         (0<<2)
+#define RU_STATUS_SUS          (1<<2)
+#define RU_STATUS_NORES                (2<<2)
+#define RU_STATUS_READY                (4<<2)
+#define RU_STATUS_NO_RBDS_SUS  ((1<<2)|(8<<2))
+#define RU_STATUS_NO_RBDS_NORES ((2<<2)|(8<<2))
+#define RU_STATUS_NO_RBDS_READY ((4<<2)|(8<<2))
+
+       /* 82559 Port interface commands.
+        */
+#define I82559_RESET           0x00000000      /* Software reset */
+#define I82559_SELFTEST                0x00000001      /* 82559 Selftest command */
+#define I82559_SELECTIVE_RESET 0x00000002
+#define I82559_DUMP            0x00000003
+#define I82559_DUMP_WAKEUP     0x00000007
+
+       /* 82559 Eeprom interface.
+        */
+#define EE_SHIFT_CLK           0x01    /* EEPROM shift clock. */
+#define EE_CS                  0x02    /* EEPROM chip select. */
+#define EE_DATA_WRITE          0x04    /* EEPROM chip data in. */
+#define EE_WRITE_0             0x01
+#define EE_WRITE_1             0x05
+#define EE_DATA_READ           0x08    /* EEPROM chip data out. */
+#define EE_ENB                 (0x4800 | EE_CS)
+#define EE_CMD_BITS            3
+#define EE_DATA_BITS           16
+
+       /* The EEPROM commands include the alway-set leading bit.
+        */
+#define EE_EWENB_CMD           (4 << addr_len)
+#define EE_WRITE_CMD           (5 << addr_len)
+#define EE_READ_CMD            (6 << addr_len)
+#define EE_ERASE_CMD           (7 << addr_len)
+
+       /* Receive frame descriptors.
+        */
+struct RxFD {
+       volatile u16 status;
+       volatile u16 control;
+       volatile u32 link;              /* struct RxFD * */
+       volatile u32 rx_buf_addr;       /* void * */
+       volatile u32 count;
+
+       volatile u8 data[PKTSIZE_ALIGN];
+};
+
+#define RFD_STATUS_C           0x8000  /* completion of received frame */
+#define RFD_STATUS_OK          0x2000  /* frame received with no errors */
+
+#define RFD_CONTROL_EL         0x8000  /* 1=last RFD in RFA */
+#define RFD_CONTROL_S          0x4000  /* 1=suspend RU after receiving frame */
+#define RFD_CONTROL_H          0x0010  /* 1=RFD is a header RFD */
+#define RFD_CONTROL_SF         0x0008  /* 0=simplified, 1=flexible mode */
+
+#define RFD_COUNT_MASK         0x3fff
+#define RFD_COUNT_F            0x4000
+#define RFD_COUNT_EOF          0x8000
+
+#define RFD_RX_CRC             0x0800  /* crc error */
+#define RFD_RX_ALIGNMENT       0x0400  /* alignment error */
+#define RFD_RX_RESOURCE                0x0200  /* out of space, no resources */
+#define RFD_RX_DMA_OVER                0x0100  /* DMA overrun */
+#define RFD_RX_SHORT           0x0080  /* short frame error */
+#define RFD_RX_LENGTH          0x0020
+#define RFD_RX_ERROR           0x0010  /* receive error */
+#define RFD_RX_NO_ADR_MATCH    0x0004  /* no address match */
+#define RFD_RX_IA_MATCH                0x0002  /* individual address does not match */
+#define RFD_RX_TCO             0x0001  /* TCO indication */
+
+       /* Transmit frame descriptors
+        */
+struct TxFD {                          /* Transmit frame descriptor set. */
+       volatile u16 status;
+       volatile u16 command;
+       volatile u32 link;              /* void * */
+       volatile u32 tx_desc_addr;      /* Always points to the tx_buf_addr element. */
+       volatile s32 count;
+
+       volatile u32 tx_buf_addr0;      /* void *, frame to be transmitted.  */
+       volatile s32 tx_buf_size0;      /* Length of Tx frame. */
+       volatile u32 tx_buf_addr1;      /* void *, frame to be transmitted.  */
+       volatile s32 tx_buf_size1;      /* Length of Tx frame. */
+};
+
+#define TxCB_CMD_TRANSMIT      0x0004  /* transmit command */
+#define TxCB_CMD_SF            0x0008  /* 0=simplified, 1=flexible mode */
+#define TxCB_CMD_NC            0x0010  /* 0=CRC insert by controller */
+#define TxCB_CMD_I             0x2000  /* generate interrupt on completion */
+#define TxCB_CMD_S             0x4000  /* suspend on completion */
+#define TxCB_CMD_EL            0x8000  /* last command block in CBL */
+
+#define TxCB_COUNT_MASK                0x3fff
+#define TxCB_COUNT_EOF         0x8000
+
+       /* The Speedo3 Rx and Tx frame/buffer descriptors.
+        */
+struct descriptor {                    /* A generic descriptor. */
+       volatile u16 status;
+       volatile u16 command;
+       volatile u32 link;              /* struct descriptor *  */
+
+       unsigned char params[0];
+};
+
+#define CFG_CMD_EL             0x8000
+#define CFG_CMD_SUSPEND                0x4000
+#define CFG_CMD_INT            0x2000
+#define CFG_CMD_IAS            0x0001  /* individual address setup */
+#define CFG_CMD_CONFIGURE      0x0002  /* configure */
+
+#define CFG_STATUS_C           0x8000
+#define CFG_STATUS_OK          0x2000
+
+       /* Misc.
+        */
+#define NUM_RX_DESC            PKTBUFSRX
+#define NUM_TX_DESC            1       /* Number of TX descriptors   */
+
+#define TOUT_LOOP              1000000
+
+#define ETH_ALEN               6
+
+static struct RxFD rx_ring[NUM_RX_DESC];       /* RX descriptor ring         */
+static struct TxFD tx_ring[NUM_TX_DESC];       /* TX descriptor ring         */
+static int rx_next;                    /* RX descriptor ring pointer */
+static int tx_next;                    /* TX descriptor ring pointer */
+static int tx_threshold;
+
+/*
+ * The parameters for a CmdConfigure operation.
+ * There are so many options that it would be difficult to document
+ * each bit. We mostly use the default or recommended settings.
+ */
+static const char i82557_config_cmd[] = {
+       22, 0x08, 0, 0, 0, 0, 0x32, 0x03, 1,    /* 1=Use MII  0=Use AUI */
+       0, 0x2E, 0, 0x60, 0,
+       0xf2, 0x48, 0, 0x40, 0xf2, 0x80,        /* 0x40=Force full-duplex */
+       0x3f, 0x05,
+};
+static const char i82558_config_cmd[] = {
+       22, 0x08, 0, 1, 0, 0, 0x22, 0x03, 1,    /* 1=Use MII  0=Use AUI */
+       0, 0x2E, 0, 0x60, 0x08, 0x88,
+       0x68, 0, 0x40, 0xf2, 0x84,              /* Disable FC */
+       0x31, 0x05,
+};
+
+static void init_rx_ring (struct eth_device *dev);
+static void purge_tx_ring (struct eth_device *dev);
+
+static void read_hw_addr (struct eth_device *dev, bd_t * bis);
+
+static int eepro100_init (struct eth_device *dev, bd_t * bis);
+static int eepro100_send (struct eth_device *dev, volatile void *packet,
+                                                 int length);
+static int eepro100_recv (struct eth_device *dev);
+static void eepro100_halt (struct eth_device *dev);
+
+#if defined(CONFIG_E500) || defined(CONFIG_DB64360) || defined(CONFIG_DB64460)
+#define bus_to_phys(a) (a)
+#define phys_to_bus(a) (a)
+#else
+#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a)
+#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
+#endif
+
+static inline int INW (struct eth_device *dev, u_long addr)
+{
+       return le16_to_cpu (*(volatile u16 *) (addr + dev->iobase));
+}
+
+static inline void OUTW (struct eth_device *dev, int command, u_long addr)
+{
+       *(volatile u16 *) ((addr + dev->iobase)) = cpu_to_le16 (command);
+}
+
+static inline void OUTL (struct eth_device *dev, int command, u_long addr)
+{
+       *(volatile u32 *) ((addr + dev->iobase)) = cpu_to_le32 (command);
+}
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+static inline int INL (struct eth_device *dev, u_long addr)
+{
+       return le32_to_cpu (*(volatile u32 *) (addr + dev->iobase));
+}
+
+static int get_phyreg (struct eth_device *dev, unsigned char addr,
+               unsigned char reg, unsigned short *value)
+{
+       int cmd;
+       int timeout = 50;
+
+       /* read requested data */
+       cmd = (2 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16);
+       OUTL (dev, cmd, SCBCtrlMDI);
+
+       do {
+               udelay(1000);
+               cmd = INL (dev, SCBCtrlMDI);
+       } while (!(cmd & (1 << 28)) && (--timeout));
+
+       if (timeout == 0)
+               return -1;
+
+       *value = (unsigned short) (cmd & 0xffff);
+
+       return 0;
+}
+
+static int set_phyreg (struct eth_device *dev, unsigned char addr,
+               unsigned char reg, unsigned short value)
+{
+       int cmd;
+       int timeout = 50;
+
+       /* write requested data */
+       cmd = (1 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16);
+       OUTL (dev, cmd | value, SCBCtrlMDI);
+
+       while (!(INL (dev, SCBCtrlMDI) & (1 << 28)) && (--timeout))
+               udelay(1000);
+
+       if (timeout == 0)
+               return -1;
+
+       return 0;
+}
+
+/* Check if given phyaddr is valid, i.e. there is a PHY connected.
+ * Do this by checking model value field from ID2 register.
+ */
+static struct eth_device* verify_phyaddr (char *devname, unsigned char addr)
+{
+       struct eth_device *dev;
+       unsigned short value;
+       unsigned char model;
+
+       dev = eth_get_dev_by_name(devname);
+       if (dev == NULL) {
+               printf("%s: no such device\n", devname);
+               return NULL;
+       }
+
+       /* read id2 register */
+       if (get_phyreg(dev, addr, PHY_PHYIDR2, &value) != 0) {
+               printf("%s: mii read timeout!\n", devname);
+               return NULL;
+       }
+
+       /* get model */
+       model = (unsigned char)((value >> 4) & 0x003f);
+
+       if (model == 0) {
+               printf("%s: no PHY at address %d\n", devname, addr);
+               return NULL;
+       }
+
+       return dev;
+}
+
+static int eepro100_miiphy_read (char *devname, unsigned char addr,
+               unsigned char reg, unsigned short *value)
+{
+       struct eth_device *dev;
+
+       dev = verify_phyaddr(devname, addr);
+       if (dev == NULL)
+               return -1;
+
+       if (get_phyreg(dev, addr, reg, value) != 0) {
+               printf("%s: mii read timeout!\n", devname);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int eepro100_miiphy_write (char *devname, unsigned char addr,
+               unsigned char reg, unsigned short value)
+{
+       struct eth_device *dev;
+
+       dev = verify_phyaddr(devname, addr);
+       if (dev == NULL)
+               return -1;
+
+       if (set_phyreg(dev, addr, reg, value) != 0) {
+               printf("%s: mii write timeout!\n", devname);
+               return -1;
+       }
+
+       return 0;
+}
+
+#endif
+
+/* Wait for the chip get the command.
+*/
+static int wait_for_eepro100 (struct eth_device *dev)
+{
+       int i;
+
+       for (i = 0; INW (dev, SCBCmd) & (CU_CMD_MASK | RU_CMD_MASK); i++) {
+               if (i >= TOUT_LOOP) {
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
+static struct pci_device_id supported[] = {
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557},
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559},
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER},
+       {}
+};
+
+int eepro100_initialize (bd_t * bis)
+{
+       pci_dev_t devno;
+       int card_number = 0;
+       struct eth_device *dev;
+       u32 iobase, status;
+       int idx = 0;
+
+       while (1) {
+               /* Find PCI device
+                */
+               if ((devno = pci_find_devices (supported, idx++)) < 0) {
+                       break;
+               }
+
+               pci_read_config_dword (devno, PCI_BASE_ADDRESS_0, &iobase);
+               iobase &= ~0xf;
+
+#ifdef DEBUG
+               printf ("eepro100: Intel i82559 PCI EtherExpressPro @0x%x\n",
+                               iobase);
+#endif
+
+               pci_write_config_dword (devno,
+                                       PCI_COMMAND,
+                                       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+               /* Check if I/O accesses and Bus Mastering are enabled.
+                */
+               pci_read_config_dword (devno, PCI_COMMAND, &status);
+               if (!(status & PCI_COMMAND_MEMORY)) {
+                       printf ("Error: Can not enable MEM access.\n");
+                       continue;
+               }
+
+               if (!(status & PCI_COMMAND_MASTER)) {
+                       printf ("Error: Can not enable Bus Mastering.\n");
+                       continue;
+               }
+
+               dev = (struct eth_device *) malloc (sizeof *dev);
+
+               sprintf (dev->name, "i82559#%d", card_number);
+               dev->priv = (void *) devno; /* this have to come before bus_to_phys() */
+               dev->iobase = bus_to_phys (iobase);
+               dev->init = eepro100_init;
+               dev->halt = eepro100_halt;
+               dev->send = eepro100_send;
+               dev->recv = eepro100_recv;
+
+               eth_register (dev);
+
+#if defined (CONFIG_MII) || defined(CONFIG_CMD_MII)
+               /* register mii command access routines */
+               miiphy_register(dev->name,
+                               eepro100_miiphy_read, eepro100_miiphy_write);
+#endif
+
+               card_number++;
+
+               /* Set the latency timer for value.
+                */
+               pci_write_config_byte (devno, PCI_LATENCY_TIMER, 0x20);
+
+               udelay (10 * 1000);
+
+               read_hw_addr (dev, bis);
+       }
+
+       return card_number;
+}
+
+
+static int eepro100_init (struct eth_device *dev, bd_t * bis)
+{
+       int i, status = 0;
+       int tx_cur;
+       struct descriptor *ias_cmd, *cfg_cmd;
+
+       /* Reset the ethernet controller
+        */
+       OUTL (dev, I82559_SELECTIVE_RESET, SCBPort);
+       udelay (20);
+
+       OUTL (dev, I82559_RESET, SCBPort);
+       udelay (20);
+
+       if (!wait_for_eepro100 (dev)) {
+               printf ("Error: Can not reset ethernet controller.\n");
+               goto Done;
+       }
+       OUTL (dev, 0, SCBPointer);
+       OUTW (dev, SCB_M | RUC_ADDR_LOAD, SCBCmd);
+
+       if (!wait_for_eepro100 (dev)) {
+               printf ("Error: Can not reset ethernet controller.\n");
+               goto Done;
+       }
+       OUTL (dev, 0, SCBPointer);
+       OUTW (dev, SCB_M | CU_ADDR_LOAD, SCBCmd);
+
+       /* Initialize Rx and Tx rings.
+        */
+       init_rx_ring (dev);
+       purge_tx_ring (dev);
+
+       /* Tell the adapter where the RX ring is located.
+        */
+       if (!wait_for_eepro100 (dev)) {
+               printf ("Error: Can not reset ethernet controller.\n");
+               goto Done;
+       }
+
+       OUTL (dev, phys_to_bus ((u32) & rx_ring[rx_next]), SCBPointer);
+       OUTW (dev, SCB_M | RUC_START, SCBCmd);
+
+       /* Send the Configure frame */
+       tx_cur = tx_next;
+       tx_next = ((tx_next + 1) % NUM_TX_DESC);
+
+       cfg_cmd = (struct descriptor *) &tx_ring[tx_cur];
+       cfg_cmd->command = cpu_to_le16 ((CFG_CMD_SUSPEND | CFG_CMD_CONFIGURE));
+       cfg_cmd->status = 0;
+       cfg_cmd->link = cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next]));
+
+       memcpy (cfg_cmd->params, i82558_config_cmd,
+                       sizeof (i82558_config_cmd));
+
+       if (!wait_for_eepro100 (dev)) {
+               printf ("Error---CFG_CMD_CONFIGURE: Can not reset ethernet controller.\n");
+               goto Done;
+       }
+
+       OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer);
+       OUTW (dev, SCB_M | CU_START, SCBCmd);
+
+       for (i = 0;
+            !(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_C);
+            i++) {
+               if (i >= TOUT_LOOP) {
+                       printf ("%s: Tx error buffer not ready\n", dev->name);
+                       goto Done;
+               }
+       }
+
+       if (!(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_OK)) {
+               printf ("TX error status = 0x%08X\n",
+                       le16_to_cpu (tx_ring[tx_cur].status));
+               goto Done;
+       }
+
+       /* Send the Individual Address Setup frame
+        */
+       tx_cur = tx_next;
+       tx_next = ((tx_next + 1) % NUM_TX_DESC);
+
+       ias_cmd = (struct descriptor *) &tx_ring[tx_cur];
+       ias_cmd->command = cpu_to_le16 ((CFG_CMD_SUSPEND | CFG_CMD_IAS));
+       ias_cmd->status = 0;
+       ias_cmd->link = cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next]));
+
+       memcpy (ias_cmd->params, dev->enetaddr, 6);
+
+       /* Tell the adapter where the TX ring is located.
+        */
+       if (!wait_for_eepro100 (dev)) {
+               printf ("Error: Can not reset ethernet controller.\n");
+               goto Done;
+       }
+
+       OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer);
+       OUTW (dev, SCB_M | CU_START, SCBCmd);
+
+       for (i = 0; !(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_C);
+                i++) {
+               if (i >= TOUT_LOOP) {
+                       printf ("%s: Tx error buffer not ready\n",
+                               dev->name);
+                       goto Done;
+               }
+       }
+
+       if (!(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_OK)) {
+               printf ("TX error status = 0x%08X\n",
+                       le16_to_cpu (tx_ring[tx_cur].status));
+               goto Done;
+       }
+
+       status = 1;
+
+  Done:
+       return status;
+}
+
+static int eepro100_send (struct eth_device *dev, volatile void *packet, int length)
+{
+       int i, status = -1;
+       int tx_cur;
+
+       if (length <= 0) {
+               printf ("%s: bad packet size: %d\n", dev->name, length);
+               goto Done;
+       }
+
+       tx_cur = tx_next;
+       tx_next = (tx_next + 1) % NUM_TX_DESC;
+
+       tx_ring[tx_cur].command = cpu_to_le16 ( TxCB_CMD_TRANSMIT |
+                                               TxCB_CMD_SF     |
+                                               TxCB_CMD_S      |
+                                               TxCB_CMD_EL );
+       tx_ring[tx_cur].status = 0;
+       tx_ring[tx_cur].count = cpu_to_le32 (tx_threshold);
+       tx_ring[tx_cur].link =
+               cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next]));
+       tx_ring[tx_cur].tx_desc_addr =
+               cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_cur].tx_buf_addr0));
+       tx_ring[tx_cur].tx_buf_addr0 =
+               cpu_to_le32 (phys_to_bus ((u_long) packet));
+       tx_ring[tx_cur].tx_buf_size0 = cpu_to_le32 (length);
+
+       if (!wait_for_eepro100 (dev)) {
+               printf ("%s: Tx error ethernet controller not ready.\n",
+                               dev->name);
+               goto Done;
+       }
+
+       /* Send the packet.
+        */
+       OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer);
+       OUTW (dev, SCB_M | CU_START, SCBCmd);
+
+       for (i = 0; !(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_C);
+                i++) {
+               if (i >= TOUT_LOOP) {
+                       printf ("%s: Tx error buffer not ready\n", dev->name);
+                       goto Done;
+               }
+       }
+
+       if (!(le16_to_cpu (tx_ring[tx_cur].status) & CFG_STATUS_OK)) {
+               printf ("TX error status = 0x%08X\n",
+                       le16_to_cpu (tx_ring[tx_cur].status));
+               goto Done;
+       }
+
+       status = length;
+
+  Done:
+       return status;
+}
+
+static int eepro100_recv (struct eth_device *dev)
+{
+       u16 status, stat;
+       int rx_prev, length = 0;
+
+       stat = INW (dev, SCBStatus);
+       OUTW (dev, stat & SCB_STATUS_RNR, SCBStatus);
+
+       for (;;) {
+               status = le16_to_cpu (rx_ring[rx_next].status);
+
+               if (!(status & RFD_STATUS_C)) {
+                       break;
+               }
+
+               /* Valid frame status.
+                */
+               if ((status & RFD_STATUS_OK)) {
+                       /* A valid frame received.
+                        */
+                       length = le32_to_cpu (rx_ring[rx_next].count) & 0x3fff;
+
+                       /* Pass the packet up to the protocol
+                        * layers.
+                        */
+                       NetReceive (rx_ring[rx_next].data, length);
+               } else {
+                       /* There was an error.
+                        */
+                       printf ("RX error status = 0x%08X\n", status);
+               }
+
+               rx_ring[rx_next].control = cpu_to_le16 (RFD_CONTROL_S);
+               rx_ring[rx_next].status = 0;
+               rx_ring[rx_next].count = cpu_to_le32 (PKTSIZE_ALIGN << 16);
+
+               rx_prev = (rx_next + NUM_RX_DESC - 1) % NUM_RX_DESC;
+               rx_ring[rx_prev].control = 0;
+
+               /* Update entry information.
+                */
+               rx_next = (rx_next + 1) % NUM_RX_DESC;
+       }
+
+       if (stat & SCB_STATUS_RNR) {
+
+               printf ("%s: Receiver is not ready, restart it !\n", dev->name);
+
+               /* Reinitialize Rx ring.
+                */
+               init_rx_ring (dev);
+
+               if (!wait_for_eepro100 (dev)) {
+                       printf ("Error: Can not restart ethernet controller.\n");
+                       goto Done;
+               }
+
+               OUTL (dev, phys_to_bus ((u32) & rx_ring[rx_next]), SCBPointer);
+               OUTW (dev, SCB_M | RUC_START, SCBCmd);
+       }
+
+  Done:
+       return length;
+}
+
+static void eepro100_halt (struct eth_device *dev)
+{
+       /* Reset the ethernet controller
+        */
+       OUTL (dev, I82559_SELECTIVE_RESET, SCBPort);
+       udelay (20);
+
+       OUTL (dev, I82559_RESET, SCBPort);
+       udelay (20);
+
+       if (!wait_for_eepro100 (dev)) {
+               printf ("Error: Can not reset ethernet controller.\n");
+               goto Done;
+       }
+       OUTL (dev, 0, SCBPointer);
+       OUTW (dev, SCB_M | RUC_ADDR_LOAD, SCBCmd);
+
+       if (!wait_for_eepro100 (dev)) {
+               printf ("Error: Can not reset ethernet controller.\n");
+               goto Done;
+       }
+       OUTL (dev, 0, SCBPointer);
+       OUTW (dev, SCB_M | CU_ADDR_LOAD, SCBCmd);
+
+  Done:
+       return;
+}
+
+       /* SROM Read.
+        */
+static int read_eeprom (struct eth_device *dev, int location, int addr_len)
+{
+       unsigned short retval = 0;
+       int read_cmd = location | EE_READ_CMD;
+       int i;
+
+       OUTW (dev, EE_ENB & ~EE_CS, SCBeeprom);
+       OUTW (dev, EE_ENB, SCBeeprom);
+
+       /* Shift the read command bits out. */
+       for (i = 12; i >= 0; i--) {
+               short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+
+               OUTW (dev, EE_ENB | dataval, SCBeeprom);
+               udelay (1);
+               OUTW (dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);
+               udelay (1);
+       }
+       OUTW (dev, EE_ENB, SCBeeprom);
+
+       for (i = 15; i >= 0; i--) {
+               OUTW (dev, EE_ENB | EE_SHIFT_CLK, SCBeeprom);
+               udelay (1);
+               retval = (retval << 1) |
+                               ((INW (dev, SCBeeprom) & EE_DATA_READ) ? 1 : 0);
+               OUTW (dev, EE_ENB, SCBeeprom);
+               udelay (1);
+       }
+
+       /* Terminate the EEPROM access. */
+       OUTW (dev, EE_ENB & ~EE_CS, SCBeeprom);
+       return retval;
+}
+
+#ifdef CONFIG_EEPRO100_SROM_WRITE
+int eepro100_write_eeprom (struct eth_device* dev, int location, int addr_len, unsigned short data)
+{
+    unsigned short dataval;
+    int enable_cmd = 0x3f | EE_EWENB_CMD;
+    int write_cmd  = location | EE_WRITE_CMD;
+    int i;
+    unsigned long datalong, tmplong;
+
+    OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom);
+    udelay(1);
+    OUTW(dev, EE_ENB, SCBeeprom);
+
+    /* Shift the enable command bits out. */
+    for (i = (addr_len+EE_CMD_BITS-1); i >= 0; i--)
+    {
+       dataval = (enable_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+       OUTW(dev, EE_ENB | dataval, SCBeeprom);
+       udelay(1);
+       OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);
+       udelay(1);
+    }
+
+    OUTW(dev, EE_ENB, SCBeeprom);
+    udelay(1);
+    OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom);
+    udelay(1);
+    OUTW(dev, EE_ENB, SCBeeprom);
+
+
+    /* Shift the write command bits out. */
+    for (i = (addr_len+EE_CMD_BITS-1); i >= 0; i--)
+    {
+       dataval = (write_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+       OUTW(dev, EE_ENB | dataval, SCBeeprom);
+       udelay(1);
+       OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);
+       udelay(1);
+    }
+
+    /* Write the data */
+    datalong= (unsigned long) ((((data) & 0x00ff) << 8) | ( (data) >> 8));
+
+    for (i = 0; i< EE_DATA_BITS; i++)
+    {
+    /* Extract and move data bit to bit DI */
+    dataval = ((datalong & 0x8000)>>13) ? EE_DATA_WRITE : 0;
+
+    OUTW(dev, EE_ENB | dataval, SCBeeprom);
+    udelay(1);
+    OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);
+    udelay(1);
+    OUTW(dev, EE_ENB | dataval, SCBeeprom);
+    udelay(1);
+
+    datalong = datalong << 1;  /* Adjust significant data bit*/
+    }
+
+    /* Finish up command  (toggle CS) */
+    OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom);
+    udelay(1);                 /* delay for more than 250 ns */
+    OUTW(dev, EE_ENB, SCBeeprom);
+
+    /* Wait for programming ready (D0 = 1) */
+    tmplong = 10;
+    do
+    {
+       dataval = INW(dev, SCBeeprom);
+       if (dataval & EE_DATA_READ)
+           break;
+       udelay(10000);
+    }
+    while (-- tmplong);
+
+    if (tmplong == 0)
+    {
+       printf ("Write i82559 eeprom timed out (100 ms waiting for data ready.\n");
+       return -1;
+    }
+
+    /* Terminate the EEPROM access. */
+    OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom);
+
+    return 0;
+}
+#endif
+
+static void init_rx_ring (struct eth_device *dev)
+{
+       int i;
+
+       for (i = 0; i < NUM_RX_DESC; i++) {
+               rx_ring[i].status = 0;
+               rx_ring[i].control =
+                               (i == NUM_RX_DESC - 1) ? cpu_to_le16 (RFD_CONTROL_S) : 0;
+               rx_ring[i].link =
+                               cpu_to_le32 (phys_to_bus
+                                                        ((u32) & rx_ring[(i + 1) % NUM_RX_DESC]));
+               rx_ring[i].rx_buf_addr = 0xffffffff;
+               rx_ring[i].count = cpu_to_le32 (PKTSIZE_ALIGN << 16);
+       }
+
+       rx_next = 0;
+}
+
+static void purge_tx_ring (struct eth_device *dev)
+{
+       int i;
+
+       tx_next = 0;
+       tx_threshold = 0x01208000;
+
+       for (i = 0; i < NUM_TX_DESC; i++) {
+               tx_ring[i].status = 0;
+               tx_ring[i].command = 0;
+               tx_ring[i].link = 0;
+               tx_ring[i].tx_desc_addr = 0;
+               tx_ring[i].count = 0;
+
+               tx_ring[i].tx_buf_addr0 = 0;
+               tx_ring[i].tx_buf_size0 = 0;
+               tx_ring[i].tx_buf_addr1 = 0;
+               tx_ring[i].tx_buf_size1 = 0;
+       }
+}
+
+static void read_hw_addr (struct eth_device *dev, bd_t * bis)
+{
+       u16 eeprom[0x40];
+       u16 sum = 0;
+       int i, j;
+       int addr_len = read_eeprom (dev, 0, 6) == 0xffff ? 8 : 6;
+
+       for (j = 0, i = 0; i < 0x40; i++) {
+               u16 value = read_eeprom (dev, i, addr_len);
+
+               eeprom[i] = value;
+               sum += value;
+               if (i < 3) {
+                       dev->enetaddr[j++] = value;
+                       dev->enetaddr[j++] = value >> 8;
+               }
+       }
+
+       if (sum != 0xBABA) {
+               memset (dev->enetaddr, 0, ETH_ALEN);
+#ifdef DEBUG
+               printf ("%s: Invalid EEPROM checksum %#4.4x, "
+                       "check settings before activating this device!\n",
+                       dev->name, sum);
+#endif
+       }
+}
+
+#endif
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c
new file mode 100644 (file)
index 0000000..98303ac
--- /dev/null
@@ -0,0 +1,983 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <common.h>
+#ifdef CONFIG_ENC28J60
+#include <net.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/spi.h>
+
+/*
+ * Control Registers in Bank 0
+ */
+
+#define CTL_REG_ERDPTL  0x00
+#define CTL_REG_ERDPTH  0x01
+#define CTL_REG_EWRPTL  0x02
+#define CTL_REG_EWRPTH  0x03
+#define CTL_REG_ETXSTL  0x04
+#define CTL_REG_ETXSTH  0x05
+#define CTL_REG_ETXNDL  0x06
+#define CTL_REG_ETXNDH  0x07
+#define CTL_REG_ERXSTL  0x08
+#define CTL_REG_ERXSTH  0x09
+#define CTL_REG_ERXNDL  0x0A
+#define CTL_REG_ERXNDH  0x0B
+#define CTL_REG_ERXRDPTL 0x0C
+#define CTL_REG_ERXRDPTH 0x0D
+#define CTL_REG_ERXWRPTL 0x0E
+#define CTL_REG_ERXWRPTH 0x0F
+#define CTL_REG_EDMASTL  0x10
+#define CTL_REG_EDMASTH  0x11
+#define CTL_REG_EDMANDL  0x12
+#define CTL_REG_EDMANDH  0x13
+#define CTL_REG_EDMADSTL 0x14
+#define CTL_REG_EDMADSTH 0x15
+#define CTL_REG_EDMACSL  0x16
+#define CTL_REG_EDMACSH  0x17
+/* these are common in all banks */
+#define CTL_REG_EIE     0x1B
+#define CTL_REG_EIR     0x1C
+#define CTL_REG_ESTAT   0x1D
+#define CTL_REG_ECON2   0x1E
+#define CTL_REG_ECON1   0x1F
+
+/*
+ * Control Registers in Bank 1
+ */
+
+#define CTL_REG_EHT0   0x00
+#define CTL_REG_EHT1   0x01
+#define CTL_REG_EHT2   0x02
+#define CTL_REG_EHT3   0x03
+#define CTL_REG_EHT4   0x04
+#define CTL_REG_EHT5   0x05
+#define CTL_REG_EHT6   0x06
+#define CTL_REG_EHT7   0x07
+#define CTL_REG_EPMM0  0x08
+#define CTL_REG_EPMM1  0x09
+#define CTL_REG_EPMM2  0x0A
+#define CTL_REG_EPMM3  0x0B
+#define CTL_REG_EPMM4  0x0C
+#define CTL_REG_EPMM5  0x0D
+#define CTL_REG_EPMM6  0x0E
+#define CTL_REG_EPMM7  0x0F
+#define CTL_REG_EPMCSL 0x10
+#define CTL_REG_EPMCSH 0x11
+#define CTL_REG_EPMOL  0x14
+#define CTL_REG_EPMOH  0x15
+#define CTL_REG_EWOLIE 0x16
+#define CTL_REG_EWOLIR 0x17
+#define CTL_REG_ERXFCON 0x18
+#define CTL_REG_EPKTCNT 0x19
+
+/*
+ * Control Registers in Bank 2
+ */
+
+#define CTL_REG_MACON1  0x00
+#define CTL_REG_MACON2  0x01
+#define CTL_REG_MACON3  0x02
+#define CTL_REG_MACON4  0x03
+#define CTL_REG_MABBIPG  0x04
+#define CTL_REG_MAIPGL  0x06
+#define CTL_REG_MAIPGH  0x07
+#define CTL_REG_MACLCON1 0x08
+#define CTL_REG_MACLCON2 0x09
+#define CTL_REG_MAMXFLL  0x0A
+#define CTL_REG_MAMXFLH  0x0B
+#define CTL_REG_MAPHSUP  0x0D
+#define CTL_REG_MICON   0x11
+#define CTL_REG_MICMD   0x12
+#define CTL_REG_MIREGADR 0x14
+#define CTL_REG_MIWRL   0x16
+#define CTL_REG_MIWRH   0x17
+#define CTL_REG_MIRDL   0x18
+#define CTL_REG_MIRDH   0x19
+
+/*
+ * Control Registers in Bank 3
+ */
+
+#define CTL_REG_MAADR1 0x00
+#define CTL_REG_MAADR0 0x01
+#define CTL_REG_MAADR3 0x02
+#define CTL_REG_MAADR2 0x03
+#define CTL_REG_MAADR5 0x04
+#define CTL_REG_MAADR4 0x05
+#define CTL_REG_EBSTSD 0x06
+#define CTL_REG_EBSTCON 0x07
+#define CTL_REG_EBSTCSL 0x08
+#define CTL_REG_EBSTCSH 0x09
+#define CTL_REG_MISTAT 0x0A
+#define CTL_REG_EREVID 0x12
+#define CTL_REG_ECOCON 0x15
+#define CTL_REG_EFLOCON 0x17
+#define CTL_REG_EPAUSL 0x18
+#define CTL_REG_EPAUSH 0x19
+
+
+/*
+ * PHY Register
+ */
+
+#define PHY_REG_PHID1 0x02
+#define PHY_REG_PHID2 0x03
+/* taken from the Linux driver */
+#define PHY_REG_PHCON1 0x00
+#define PHY_REG_PHCON2 0x10
+#define PHY_REG_PHLCON 0x14
+
+/*
+ * Receive Filter Register (ERXFCON) bits
+ */
+
+#define ENC_RFR_UCEN  0x80
+#define ENC_RFR_ANDOR 0x40
+#define ENC_RFR_CRCEN 0x20
+#define ENC_RFR_PMEN  0x10
+#define ENC_RFR_MPEN  0x08
+#define ENC_RFR_HTEN  0x04
+#define ENC_RFR_MCEN  0x02
+#define ENC_RFR_BCEN  0x01
+
+/*
+ * ECON1 Register Bits
+ */
+
+#define ENC_ECON1_TXRST  0x80
+#define ENC_ECON1_RXRST  0x40
+#define ENC_ECON1_DMAST  0x20
+#define ENC_ECON1_CSUMEN 0x10
+#define ENC_ECON1_TXRTS  0x08
+#define ENC_ECON1_RXEN  0x04
+#define ENC_ECON1_BSEL1  0x02
+#define ENC_ECON1_BSEL0  0x01
+
+/*
+ * ECON2 Register Bits
+ */
+#define ENC_ECON2_AUTOINC 0x80
+#define ENC_ECON2_PKTDEC  0x40
+#define ENC_ECON2_PWRSV   0x20
+#define ENC_ECON2_VRPS   0x08
+
+/*
+ * EIR Register Bits
+ */
+#define ENC_EIR_PKTIF  0x40
+#define ENC_EIR_DMAIF  0x20
+#define ENC_EIR_LINKIF 0x10
+#define ENC_EIR_TXIF   0x08
+#define ENC_EIR_WOLIF  0x04
+#define ENC_EIR_TXERIF 0x02
+#define ENC_EIR_RXERIF 0x01
+
+/*
+ * ESTAT Register Bits
+ */
+
+#define ENC_ESTAT_INT    0x80
+#define ENC_ESTAT_LATECOL 0x10
+#define ENC_ESTAT_RXBUSY  0x04
+#define ENC_ESTAT_TXABRT  0x02
+#define ENC_ESTAT_CLKRDY  0x01
+
+/*
+ * EIE Register Bits
+ */
+
+#define ENC_EIE_INTIE  0x80
+#define ENC_EIE_PKTIE  0x40
+#define ENC_EIE_DMAIE  0x20
+#define ENC_EIE_LINKIE 0x10
+#define ENC_EIE_TXIE   0x08
+#define ENC_EIE_WOLIE  0x04
+#define ENC_EIE_TXERIE 0x02
+#define ENC_EIE_RXERIE 0x01
+
+/*
+ * MACON1 Register Bits
+ */
+#define ENC_MACON1_LOOPBK  0x10
+#define ENC_MACON1_TXPAUS  0x08
+#define ENC_MACON1_RXPAUS  0x04
+#define ENC_MACON1_PASSALL 0x02
+#define ENC_MACON1_MARXEN  0x01
+
+
+/*
+ * MACON2 Register Bits
+ */
+#define ENC_MACON2_MARST   0x80
+#define ENC_MACON2_RNDRST  0x40
+#define ENC_MACON2_MARXRST 0x08
+#define ENC_MACON2_RFUNRST 0x04
+#define ENC_MACON2_MATXRST 0x02
+#define ENC_MACON2_TFUNRST 0x01
+
+/*
+ * MACON3 Register Bits
+ */
+#define ENC_MACON3_PADCFG2 0x80
+#define ENC_MACON3_PADCFG1 0x40
+#define ENC_MACON3_PADCFG0 0x20
+#define ENC_MACON3_TXCRCEN 0x10
+#define ENC_MACON3_PHDRLEN 0x08
+#define ENC_MACON3_HFRMEN  0x04
+#define ENC_MACON3_FRMLNEN 0x02
+#define ENC_MACON3_FULDPX  0x01
+
+/*
+ * MICMD Register Bits
+ */
+#define ENC_MICMD_MIISCAN 0x02
+#define ENC_MICMD_MIIRD   0x01
+
+/*
+ * MISTAT Register Bits
+ */
+#define ENC_MISTAT_NVALID 0x04
+#define ENC_MISTAT_SCAN   0x02
+#define ENC_MISTAT_BUSY   0x01
+
+/*
+ * PHID1 and PHID2 values
+ */
+#define ENC_PHID1_VALUE 0x0083
+#define ENC_PHID2_VALUE 0x1400
+#define ENC_PHID2_MASK 0xFC00
+
+
+#define ENC_SPI_SLAVE_CS 0x00010000    /* pin P1.16 */
+#define ENC_RESET       0x00020000     /* pin P1.17 */
+
+#define FAILSAFE_VALUE 5000
+
+/*
+ * Controller memory layout:
+ *
+ * 0x0000 - 0x17ff  6k bytes receive buffer
+ * 0x1800 - 0x1fff  2k bytes transmit buffer
+ */
+/* Use the lower memory for receiver buffer. See errata pt. 5 */
+#define ENC_RX_BUF_START 0x0000
+#define ENC_TX_BUF_START 0x1800
+/* taken from the Linux driver */
+#define ENC_RX_BUF_END   0x17ff
+#define ENC_TX_BUF_END   0x1fff
+
+/* maximum frame length */
+#define ENC_MAX_FRM_LEN 1518
+
+#define enc_enable() PUT32(IO1CLR, ENC_SPI_SLAVE_CS)
+#define enc_disable() PUT32(IO1SET, ENC_SPI_SLAVE_CS)
+#define enc_cfg_spi() spi_set_cfg(0, 0, 0); spi_set_clock(8);
+
+
+static unsigned char encReadReg (unsigned char regNo);
+static void encWriteReg (unsigned char regNo, unsigned char data);
+static void encWriteRegRetry (unsigned char regNo, unsigned char data, int c);
+static void encReadBuff (unsigned short length, unsigned char *pBuff);
+static void encWriteBuff (unsigned short length, unsigned char *pBuff);
+static void encBitSet (unsigned char regNo, unsigned char data);
+static void encBitClr (unsigned char regNo, unsigned char data);
+static void encReset (void);
+static void encInit (unsigned char *pEthAddr);
+static unsigned short phyRead (unsigned char addr);
+static void phyWrite(unsigned char, unsigned short);
+static void encPoll (void);
+static void encRx (void);
+
+#define m_nic_read(reg) encReadReg(reg)
+#define m_nic_write(reg, data) encWriteReg(reg, data)
+#define m_nic_write_retry(reg, data, count) encWriteRegRetry(reg, data, count)
+#define m_nic_read_data(len, buf) encReadBuff((len), (buf))
+#define m_nic_write_data(len, buf) encWriteBuff((len), (buf))
+
+/* bit field set */
+#define m_nic_bfs(reg, data) encBitSet(reg, data)
+
+/* bit field clear */
+#define m_nic_bfc(reg, data) encBitClr(reg, data)
+
+static unsigned char bank = 0; /* current bank in enc28j60 */
+static unsigned char next_pointer_lsb;
+static unsigned char next_pointer_msb;
+
+static unsigned char buffer[ENC_MAX_FRM_LEN];
+static int rxResetCounter = 0;
+
+#define RX_RESET_COUNTER 1000;
+
+/*-----------------------------------------------------------------------------
+ * Always returns 0
+ */
+int eth_init (bd_t * bis)
+{
+       unsigned char estatVal;
+
+       /* configure GPIO */
+       (*((volatile unsigned long *) IO1DIR)) |= ENC_SPI_SLAVE_CS;
+       (*((volatile unsigned long *) IO1DIR)) |= ENC_RESET;
+
+       /* CS and RESET active low */
+       PUT32 (IO1SET, ENC_SPI_SLAVE_CS);
+       PUT32 (IO1SET, ENC_RESET);
+
+       spi_init ();
+
+       /* taken from the Linux driver - dangerous stuff here! */
+       /* Wait for CLKRDY to become set (i.e., check that we can communicate with
+          the ENC) */
+       do
+       {
+               estatVal = m_nic_read(CTL_REG_ESTAT);
+       } while ((estatVal & 0x08) || (~estatVal & ENC_ESTAT_CLKRDY));
+
+       /* initialize controller */
+       encReset ();
+       encInit (bis->bi_enetaddr);
+
+       m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_RXEN);      /* enable receive */
+
+       return 0;
+}
+
+int eth_send (volatile void *packet, int length)
+{
+       /* check frame length, etc. */
+       /* TODO: */
+
+       /* switch to bank 0 */
+       m_nic_bfc (CTL_REG_ECON1, (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0));
+
+       /* set EWRPT */
+       m_nic_write (CTL_REG_EWRPTL, (ENC_TX_BUF_START & 0xff));
+       m_nic_write (CTL_REG_EWRPTH, (ENC_TX_BUF_START >> 8));
+
+       /* set ETXND */
+       m_nic_write (CTL_REG_ETXNDL, (length + ENC_TX_BUF_START) & 0xFF);
+       m_nic_write (CTL_REG_ETXNDH, (length + ENC_TX_BUF_START) >> 8);
+
+       /* set ETXST */
+       m_nic_write (CTL_REG_ETXSTL, ENC_TX_BUF_START & 0xFF);
+       m_nic_write (CTL_REG_ETXSTH, ENC_TX_BUF_START >> 8);
+
+       /* write packet */
+       m_nic_write_data (length, (unsigned char *) packet);
+
+       /* taken from the Linux driver */
+       /* Verify that the internal transmit logic has not been altered by excessive
+          collisions.  See Errata B4 12 and 14.
+        */
+       if (m_nic_read(CTL_REG_EIR) & ENC_EIR_TXERIF) {
+               m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_TXRST);
+               m_nic_bfc(CTL_REG_ECON1, ENC_ECON1_TXRST);
+       }
+       m_nic_bfc(CTL_REG_EIR, (ENC_EIR_TXERIF | ENC_EIR_TXIF));
+
+       /* set ECON1.TXRTS */
+       m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_TXRTS);
+
+       return 0;
+}
+
+
+/*****************************************************************************
+ * This function resets the receiver only. This function may be called from
+ * interrupt-context.
+ */
+static void encReceiverReset (void)
+{
+       unsigned char econ1;
+
+       econ1 = m_nic_read (CTL_REG_ECON1);
+       if ((econ1 & ENC_ECON1_RXRST) == 0) {
+               m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_RXRST);
+               rxResetCounter = RX_RESET_COUNTER;
+       }
+}
+
+/*****************************************************************************
+ * receiver reset timer
+ */
+static void encReceiverResetCallback (void)
+{
+       m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_RXRST);
+       m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_RXEN);      /* enable receive */
+}
+
+/*-----------------------------------------------------------------------------
+ * Check for received packets. Call NetReceive for each packet. The return
+ * value is ignored by the caller.
+ */
+int eth_rx (void)
+{
+       if (rxResetCounter > 0 && --rxResetCounter == 0) {
+               encReceiverResetCallback ();
+       }
+
+       encPoll ();
+
+       return 0;
+}
+
+void eth_halt (void)
+{
+       m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_RXEN);      /* disable receive */
+}
+
+/*****************************************************************************/
+
+static void encPoll (void)
+{
+       unsigned char eir_reg;
+       volatile unsigned char estat_reg;
+       unsigned char pkt_cnt;
+
+#ifdef CONFIG_USE_IRQ
+       /* clear global interrupt enable bit in enc28j60 */
+       m_nic_bfc (CTL_REG_EIE, ENC_EIE_INTIE);
+#endif
+       estat_reg = m_nic_read (CTL_REG_ESTAT);
+
+       eir_reg = m_nic_read (CTL_REG_EIR);
+
+       if (eir_reg & ENC_EIR_TXIF) {
+               /* clear TXIF bit in EIR */
+               m_nic_bfc (CTL_REG_EIR, ENC_EIR_TXIF);
+       }
+
+       /* We have to use pktcnt and not pktif bit, see errata pt. 6 */
+
+       /* move to bank 1 */
+       m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_BSEL1);
+       m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_BSEL0);
+
+       /* read pktcnt */
+       pkt_cnt = m_nic_read (CTL_REG_EPKTCNT);
+
+       if (pkt_cnt > 0) {
+               if ((eir_reg & ENC_EIR_PKTIF) == 0) {
+                       /*printf("encPoll: pkt cnt > 0, but pktif not set\n"); */
+               }
+               encRx ();
+               /* clear PKTIF bit in EIR, this should not need to be done but it
+                  seems like we get problems if we do not */
+               m_nic_bfc (CTL_REG_EIR, ENC_EIR_PKTIF);
+       }
+
+       if (eir_reg & ENC_EIR_RXERIF) {
+               printf ("encPoll: rx error\n");
+               m_nic_bfc (CTL_REG_EIR, ENC_EIR_RXERIF);
+       }
+       if (eir_reg & ENC_EIR_TXERIF) {
+               printf ("encPoll: tx error\n");
+               m_nic_bfc (CTL_REG_EIR, ENC_EIR_TXERIF);
+       }
+
+#ifdef CONFIG_USE_IRQ
+       /* set global interrupt enable bit in enc28j60 */
+       m_nic_bfs (CTL_REG_EIE, ENC_EIE_INTIE);
+#endif
+}
+
+static void encRx (void)
+{
+       unsigned short pkt_len;
+       unsigned short copy_len;
+       unsigned short status;
+       unsigned char eir_reg;
+       unsigned char pkt_cnt = 0;
+       unsigned short rxbuf_rdpt;
+
+       /* switch to bank 0 */
+       m_nic_bfc (CTL_REG_ECON1, (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0));
+
+       m_nic_write (CTL_REG_ERDPTL, next_pointer_lsb);
+       m_nic_write (CTL_REG_ERDPTH, next_pointer_msb);
+
+       do {
+               m_nic_read_data (6, buffer);
+               next_pointer_lsb = buffer[0];
+               next_pointer_msb = buffer[1];
+               pkt_len = buffer[2];
+               pkt_len |= (unsigned short) buffer[3] << 8;
+               status = buffer[4];
+               status |= (unsigned short) buffer[5] << 8;
+
+               if (pkt_len <= ENC_MAX_FRM_LEN)
+                       copy_len = pkt_len;
+               else
+                       copy_len = 0;
+
+               if ((status & (1L << 7)) == 0) /* check Received Ok bit */
+                       copy_len = 0;
+
+               /* taken from the Linux driver */
+               /* check if next pointer is resonable */
+               if ((((unsigned int)next_pointer_msb << 8) |
+                       (unsigned int)next_pointer_lsb) >= ENC_TX_BUF_START)
+                       copy_len = 0;
+
+               if (copy_len > 0) {
+                       m_nic_read_data (copy_len, buffer);
+               }
+
+               /* advance read pointer to next pointer */
+               m_nic_write (CTL_REG_ERDPTL, next_pointer_lsb);
+               m_nic_write (CTL_REG_ERDPTH, next_pointer_msb);
+
+               /* decrease packet counter */
+               m_nic_bfs (CTL_REG_ECON2, ENC_ECON2_PKTDEC);
+
+               /* taken from the Linux driver */
+               /* Only odd values should be written to ERXRDPTL,
+                * see errata B4 pt.13
+                */
+               rxbuf_rdpt = (next_pointer_msb << 8 | next_pointer_lsb) - 1;
+               if ((rxbuf_rdpt < (m_nic_read(CTL_REG_ERXSTH) << 8 |
+                               m_nic_read(CTL_REG_ERXSTL))) || (rxbuf_rdpt >
+                               (m_nic_read(CTL_REG_ERXNDH) << 8 |
+                               m_nic_read(CTL_REG_ERXNDL)))) {
+                       m_nic_write(CTL_REG_ERXRDPTL, m_nic_read(CTL_REG_ERXNDL));
+                       m_nic_write(CTL_REG_ERXRDPTH, m_nic_read(CTL_REG_ERXNDH));
+               } else {
+                       m_nic_write(CTL_REG_ERXRDPTL, rxbuf_rdpt & 0xFF);
+                       m_nic_write(CTL_REG_ERXRDPTH, rxbuf_rdpt >> 8);
+               }
+
+               /* move to bank 1 */
+               m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_BSEL1);
+               m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_BSEL0);
+
+               /* read pktcnt */
+               pkt_cnt = m_nic_read (CTL_REG_EPKTCNT);
+
+               /* switch to bank 0 */
+               m_nic_bfc (CTL_REG_ECON1,
+                          (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0));
+
+               if (copy_len == 0) {
+                       eir_reg = m_nic_read (CTL_REG_EIR);
+                       encReceiverReset ();
+                       printf ("eth_rx: copy_len=0\n");
+                       continue;
+               }
+
+               NetReceive ((unsigned char *) buffer, pkt_len);
+
+               eir_reg = m_nic_read (CTL_REG_EIR);
+       } while (pkt_cnt);      /* Use EPKTCNT not EIR.PKTIF flag, see errata pt. 6 */
+}
+
+static void encWriteReg (unsigned char regNo, unsigned char data)
+{
+       spi_lock ();
+       enc_cfg_spi ();
+       enc_enable ();
+
+       spi_write (0x40 | regNo);       /* write in regNo */
+       spi_write (data);
+
+       enc_disable ();
+       enc_enable ();
+
+       spi_write (0x1f);       /* write reg 0x1f */
+
+       enc_disable ();
+       spi_unlock ();
+}
+
+static void encWriteRegRetry (unsigned char regNo, unsigned char data, int c)
+{
+       unsigned char readback;
+       int i;
+
+       spi_lock ();
+
+       for (i = 0; i < c; i++) {
+               enc_cfg_spi ();
+               enc_enable ();
+
+               spi_write (0x40 | regNo);       /* write in regNo */
+               spi_write (data);
+
+               enc_disable ();
+               enc_enable ();
+
+               spi_write (0x1f);       /* write reg 0x1f */
+
+               enc_disable ();
+
+               spi_unlock ();  /* we must unlock spi first */
+
+               readback = encReadReg (regNo);
+
+               spi_lock ();
+
+               if (readback == data)
+                       break;
+       }
+       spi_unlock ();
+
+       if (i == c) {
+               printf ("enc28j60: write reg %d failed\n", regNo);
+       }
+}
+
+static unsigned char encReadReg (unsigned char regNo)
+{
+       unsigned char rxByte;
+
+       spi_lock ();
+       enc_cfg_spi ();
+       enc_enable ();
+
+       spi_write (0x1f);       /* read reg 0x1f */
+
+       bank = spi_read () & 0x3;
+
+       enc_disable ();
+       enc_enable ();
+
+       spi_write (regNo);
+       rxByte = spi_read ();
+
+       /* check if MAC or MII register */
+       if (((bank == 2) && (regNo <= 0x1a)) ||
+           ((bank == 3) && (regNo <= 0x05 || regNo == 0x0a))) {
+               /* ignore first byte and read another byte */
+               rxByte = spi_read ();
+       }
+
+       enc_disable ();
+       spi_unlock ();
+
+       return rxByte;
+}
+
+static void encReadBuff (unsigned short length, unsigned char *pBuff)
+{
+       spi_lock ();
+       enc_cfg_spi ();
+       enc_enable ();
+
+       spi_write (0x20 | 0x1a);        /* read buffer memory */
+
+       while (length--) {
+               if (pBuff != NULL)
+                       *pBuff++ = spi_read ();
+               else
+                       spi_write (0);
+       }
+
+       enc_disable ();
+       spi_unlock ();
+}
+
+static void encWriteBuff (unsigned short length, unsigned char *pBuff)
+{
+       spi_lock ();
+       enc_cfg_spi ();
+       enc_enable ();
+
+       spi_write (0x60 | 0x1a);        /* write buffer memory */
+
+       spi_write (0x00);       /* control byte */
+
+       while (length--)
+               spi_write (*pBuff++);
+
+       enc_disable ();
+       spi_unlock ();
+}
+
+static void encBitSet (unsigned char regNo, unsigned char data)
+{
+       spi_lock ();
+       enc_cfg_spi ();
+       enc_enable ();
+
+       spi_write (0x80 | regNo);       /* bit field set */
+       spi_write (data);
+
+       enc_disable ();
+       spi_unlock ();
+}
+
+static void encBitClr (unsigned char regNo, unsigned char data)
+{
+       spi_lock ();
+       enc_cfg_spi ();
+       enc_enable ();
+
+       spi_write (0xA0 | regNo);       /* bit field clear */
+       spi_write (data);
+
+       enc_disable ();
+       spi_unlock ();
+}
+
+static void encReset (void)
+{
+       spi_lock ();
+       enc_cfg_spi ();
+       enc_enable ();
+
+       spi_write (0xff);       /* soft reset */
+
+       enc_disable ();
+       spi_unlock ();
+
+       /* sleep 1 ms. See errata pt. 2 */
+       udelay (1000);
+}
+
+static void encInit (unsigned char *pEthAddr)
+{
+       unsigned short phid1 = 0;
+       unsigned short phid2 = 0;
+
+       /* switch to bank 0 */
+       m_nic_bfc (CTL_REG_ECON1, (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0));
+
+       /*
+        * Setup the buffer space. The reset values are valid for the
+        * other pointers.
+        */
+       /* We shall not write to ERXST, see errata pt. 5. Instead we
+          have to make sure that ENC_RX_BUS_START is 0. */
+       m_nic_write_retry (CTL_REG_ERXSTL, (ENC_RX_BUF_START & 0xFF), 1);
+       m_nic_write_retry (CTL_REG_ERXSTH, (ENC_RX_BUF_START >> 8), 1);
+
+       /* taken from the Linux driver */
+       m_nic_write_retry (CTL_REG_ERXNDL, (ENC_RX_BUF_END & 0xFF), 1);
+       m_nic_write_retry (CTL_REG_ERXNDH, (ENC_RX_BUF_END >> 8), 1);
+
+       m_nic_write_retry (CTL_REG_ERDPTL, (ENC_RX_BUF_START & 0xFF), 1);
+       m_nic_write_retry (CTL_REG_ERDPTH, (ENC_RX_BUF_START >> 8), 1);
+
+       next_pointer_lsb = (ENC_RX_BUF_START & 0xFF);
+       next_pointer_msb = (ENC_RX_BUF_START >> 8);
+
+       /* verify identification */
+       phid1 = phyRead (PHY_REG_PHID1);
+       phid2 = phyRead (PHY_REG_PHID2);
+
+       if (phid1 != ENC_PHID1_VALUE
+           || (phid2 & ENC_PHID2_MASK) != ENC_PHID2_VALUE) {
+               printf ("ERROR: failed to identify controller\n");
+               printf ("phid1 = %x, phid2 = %x\n",
+                       phid1, (phid2 & ENC_PHID2_MASK));
+               printf ("should be phid1 = %x, phid2 = %x\n",
+                       ENC_PHID1_VALUE, ENC_PHID2_VALUE);
+       }
+
+       /*
+        * --- MAC Initialization ---
+        */
+
+       /* Pull MAC out of Reset */
+
+       /* switch to bank 2 */
+       m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_BSEL0);
+       m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_BSEL1);
+
+       /* enable MAC to receive frames */
+       /* added some bits from the Linux driver */
+       m_nic_write_retry (CTL_REG_MACON1
+               ,(ENC_MACON1_MARXEN | ENC_MACON1_TXPAUS | ENC_MACON1_RXPAUS)
+               ,10);
+
+       /* configure pad, tx-crc and duplex */
+       /* added a bit from the Linux driver */
+       m_nic_write_retry (CTL_REG_MACON3
+               ,(ENC_MACON3_PADCFG0 | ENC_MACON3_TXCRCEN | ENC_MACON3_FRMLNEN)
+               ,10);
+
+       /* added 4 new lines from the Linux driver */
+       /* Allow infinite deferals if the medium is continously busy */
+       m_nic_write_retry(CTL_REG_MACON4, (1<<6) /*ENC_MACON4_DEFER*/, 10);
+
+       /* Late collisions occur beyond 63 bytes */
+       m_nic_write_retry(CTL_REG_MACLCON2, 63, 10);
+
+       /* Set (low byte) Non-Back-to_Back Inter-Packet Gap. Recommended 0x12 */
+       m_nic_write_retry(CTL_REG_MAIPGL, 0x12, 10);
+
+       /*
+       * Set (high byte) Non-Back-to_Back Inter-Packet Gap. Recommended
+       * 0x0c for half-duplex. Nothing for full-duplex
+       */
+       m_nic_write_retry(CTL_REG_MAIPGH, 0x0C, 10);
+
+       /* set maximum frame length */
+       m_nic_write_retry (CTL_REG_MAMXFLL, (ENC_MAX_FRM_LEN & 0xff), 10);
+       m_nic_write_retry (CTL_REG_MAMXFLH, (ENC_MAX_FRM_LEN >> 8), 10);
+
+       /*
+        * Set MAC back-to-back inter-packet gap. Recommended 0x12 for half duplex
+        * and 0x15 for full duplex.
+        */
+       m_nic_write_retry (CTL_REG_MABBIPG, 0x12, 10);
+
+       /* set MAC address */
+
+       /* switch to bank 3 */
+       m_nic_bfs (CTL_REG_ECON1, (ENC_ECON1_BSEL0 | ENC_ECON1_BSEL1));
+
+       m_nic_write_retry (CTL_REG_MAADR0, pEthAddr[5], 1);
+       m_nic_write_retry (CTL_REG_MAADR1, pEthAddr[4], 1);
+       m_nic_write_retry (CTL_REG_MAADR2, pEthAddr[3], 1);
+       m_nic_write_retry (CTL_REG_MAADR3, pEthAddr[2], 1);
+       m_nic_write_retry (CTL_REG_MAADR4, pEthAddr[1], 1);
+       m_nic_write_retry (CTL_REG_MAADR5, pEthAddr[0], 1);
+
+       /*
+       * PHY Initialization taken from the Linux driver
+        */
+
+       /* Prevent automatic loopback of data beeing transmitted by setting
+          ENC_PHCON2_HDLDIS */
+       phyWrite(PHY_REG_PHCON2, (1<<8));
+
+       /* LEDs configuration
+        * LEDA: LACFG = 0100 -> display link status
+        * LEDB: LBCFG = 0111 -> display TX & RX activity
+        * STRCH = 1 -> LED pulses
+        */
+       phyWrite(PHY_REG_PHLCON, 0x0472);
+
+       /* Reset PDPXMD-bit => half duplex */
+       phyWrite(PHY_REG_PHCON1, 0);
+
+       /*
+        * Receive settings
+        */
+
+#ifdef CONFIG_USE_IRQ
+       /* enable interrupts */
+       m_nic_bfs (CTL_REG_EIE, ENC_EIE_PKTIE);
+       m_nic_bfs (CTL_REG_EIE, ENC_EIE_TXIE);
+       m_nic_bfs (CTL_REG_EIE, ENC_EIE_RXERIE);
+       m_nic_bfs (CTL_REG_EIE, ENC_EIE_TXERIE);
+       m_nic_bfs (CTL_REG_EIE, ENC_EIE_INTIE);
+#endif
+}
+
+/*****************************************************************************
+ *
+ * Description:
+ *    Read PHY registers.
+ *
+ *    NOTE! This function will change to Bank 2.
+ *
+ * Params:
+ *    [in] addr address of the register to read
+ *
+ * Returns:
+ *    The value in the register
+ */
+static unsigned short phyRead (unsigned char addr)
+{
+       unsigned short ret = 0;
+
+       /* move to bank 2 */
+       m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_BSEL0);
+       m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_BSEL1);
+
+       /* write address to MIREGADR */
+       m_nic_write (CTL_REG_MIREGADR, addr);
+
+       /* set MICMD.MIIRD */
+       m_nic_write (CTL_REG_MICMD, ENC_MICMD_MIIRD);
+
+       /* taken from the Linux driver */
+       /* move to bank 3 */
+       m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL0);
+       m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL1);
+
+       /* poll MISTAT.BUSY bit until operation is complete */
+       while ((m_nic_read (CTL_REG_MISTAT) & ENC_MISTAT_BUSY) != 0) {
+               static int cnt = 0;
+
+               if (cnt++ >= 1000) {
+                       /* GJ - this seems extremely dangerous! */
+                       /* printf("#"); */
+                       cnt = 0;
+               }
+       }
+
+       /* taken from the Linux driver */
+       /* move to bank 2 */
+       m_nic_bfc(CTL_REG_ECON1, ENC_ECON1_BSEL0);
+       m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL1);
+
+       /* clear MICMD.MIIRD */
+       m_nic_write (CTL_REG_MICMD, 0);
+
+       ret = (m_nic_read (CTL_REG_MIRDH) << 8);
+       ret |= (m_nic_read (CTL_REG_MIRDL) & 0xFF);
+
+       return ret;
+}
+
+/*****************************************************************************
+ *
+ * Taken from the Linux driver.
+ * Description:
+ * Write PHY registers.
+ *
+ * NOTE! This function will change to Bank 3.
+ *
+ * Params:
+ * [in] addr address of the register to write to
+ * [in] data to be written
+ *
+ * Returns:
+ *    None
+ */
+static void phyWrite(unsigned char addr, unsigned short data)
+{
+       /* move to bank 2 */
+       m_nic_bfc(CTL_REG_ECON1, ENC_ECON1_BSEL0);
+       m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL1);
+
+       /* write address to MIREGADR */
+       m_nic_write(CTL_REG_MIREGADR, addr);
+
+       m_nic_write(CTL_REG_MIWRL, data & 0xff);
+       m_nic_write(CTL_REG_MIWRH, data >> 8);
+
+       /* move to bank 3 */
+       m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL0);
+       m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL1);
+
+       /* poll MISTAT.BUSY bit until operation is complete */
+       while((m_nic_read(CTL_REG_MISTAT) & ENC_MISTAT_BUSY) != 0) {
+               static int cnt = 0;
+
+               if(cnt++ >= 1000) {
+                       cnt = 0;
+               }
+       }
+}
+
+#endif /* CONFIG_ENC28J60 */
diff --git a/drivers/net/inca-ip_sw.c b/drivers/net/inca-ip_sw.c
new file mode 100644 (file)
index 0000000..e4aaed6
--- /dev/null
@@ -0,0 +1,817 @@
+/*
+ * INCA-IP internal switch ethernet driver.
+ *
+ * (C) Copyright 2003-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include <common.h>
+
+#if defined(CONFIG_CMD_NET) \
+       && defined(CONFIG_NET_MULTI) && defined(CONFIG_INCA_IP_SWITCH)
+
+#include <malloc.h>
+#include <net.h>
+#include <asm/inca-ip.h>
+#include <asm/addrspace.h>
+
+
+#define NUM_RX_DESC    PKTBUFSRX
+#define NUM_TX_DESC    3
+#define TOUT_LOOP      1000000
+
+
+#define DELAY  udelay(10000)
+  /* Sometimes the store word instruction hangs while writing to one
+   * of the Switch registers. Moving the instruction into a separate
+   * function somehow makes the problem go away.
+   */
+static void SWORD(volatile u32 * reg, u32 value)
+{
+       *reg = value;
+}
+
+#define DMA_WRITE_REG(reg, value) *((volatile u32 *)reg) = (u32)value;
+#define DMA_READ_REG(reg, value)    value = (u32)*((volatile u32*)reg)
+#define SW_WRITE_REG(reg, value)   \
+       SWORD(reg, value);\
+       DELAY;\
+       SWORD(reg, value);
+
+#define SW_READ_REG(reg, value)           \
+       value = (u32)*((volatile u32*)reg);\
+       DELAY;\
+       value = (u32)*((volatile u32*)reg);
+
+#define INCA_DMA_TX_POLLING_TIME       0x07
+#define INCA_DMA_RX_POLLING_TIME       0x07
+
+#define INCA_DMA_TX_HOLD               0x80000000
+#define INCA_DMA_TX_EOP                        0x40000000
+#define INCA_DMA_TX_SOP                        0x20000000
+#define INCA_DMA_TX_ICPT               0x10000000
+#define INCA_DMA_TX_IEOP               0x08000000
+
+#define INCA_DMA_RX_C                  0x80000000
+#define INCA_DMA_RX_SOP                        0x40000000
+#define INCA_DMA_RX_EOP                        0x20000000
+
+#define INCA_SWITCH_PHY_SPEED_10H      0x1
+#define INCA_SWITCH_PHY_SPEED_10F      0x5
+#define INCA_SWITCH_PHY_SPEED_100H     0x2
+#define INCA_SWITCH_PHY_SPEED_100F     0x6
+
+/************************ Auto MDIX settings ************************/
+#define INCA_IP_AUTO_MDIX_LAN_PORTS_DIR                INCA_IP_Ports_P1_DIR
+#define INCA_IP_AUTO_MDIX_LAN_PORTS_ALTSEL     INCA_IP_Ports_P1_ALTSEL
+#define INCA_IP_AUTO_MDIX_LAN_PORTS_OUT                INCA_IP_Ports_P1_OUT
+#define INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX    16
+
+#define WAIT_SIGNAL_RETRIES                    100
+#define WAIT_LINK_RETRIES                      100
+#define LINK_RETRY_DELAY                       2000  /* ms */
+/********************************************************************/
+
+typedef struct
+{
+       union {
+               struct {
+                       volatile u32 HOLD               :1;
+                       volatile u32 ICpt               :1;
+                       volatile u32 IEop               :1;
+                       volatile u32 offset             :3;
+                       volatile u32 reserved0          :4;
+                       volatile u32 NFB                :22;
+               }field;
+
+               volatile u32 word;
+       }params;
+
+       volatile u32 nextRxDescPtr;
+
+       volatile u32 RxDataPtr;
+
+       union {
+               struct {
+                       volatile u32 C                  :1;
+                       volatile u32 Sop                :1;
+                       volatile u32 Eop                :1;
+                       volatile u32 reserved3          :12;
+                       volatile u32 NBT                :17;
+               }field;
+
+               volatile u32 word;
+       }status;
+
+} inca_rx_descriptor_t;
+
+
+typedef struct
+{
+       union {
+               struct {
+                       volatile u32 HOLD               :1;
+                       volatile u32 Eop                :1;
+                       volatile u32 Sop                :1;
+                       volatile u32 ICpt               :1;
+                       volatile u32 IEop               :1;
+                       volatile u32 reserved0          :5;
+                       volatile u32 NBA                :22;
+               }field;
+
+               volatile u32 word;
+       }params;
+
+       volatile u32 nextTxDescPtr;
+
+       volatile u32 TxDataPtr;
+
+       volatile u32 C                  :1;
+       volatile u32 reserved3          :31;
+
+} inca_tx_descriptor_t;
+
+
+static inca_rx_descriptor_t rx_ring[NUM_RX_DESC] __attribute__ ((aligned(16)));
+static inca_tx_descriptor_t tx_ring[NUM_TX_DESC] __attribute__ ((aligned(16)));
+
+static int tx_new, rx_new, tx_hold, rx_hold;
+static int tx_old_hold = -1;
+static int initialized = 0;
+
+
+static int inca_switch_init(struct eth_device *dev, bd_t * bis);
+static int inca_switch_send(struct eth_device *dev, volatile void *packet, int length);
+static int inca_switch_recv(struct eth_device *dev);
+static void inca_switch_halt(struct eth_device *dev);
+static void inca_init_switch_chip(void);
+static void inca_dma_init(void);
+static int inca_amdix(void);
+
+
+int inca_switch_initialize(bd_t * bis)
+{
+       struct eth_device *dev;
+
+#if 0
+       printf("Entered inca_switch_initialize()\n");
+#endif
+
+       if (!(dev = (struct eth_device *) malloc (sizeof *dev))) {
+               printf("Failed to allocate memory\n");
+               return 0;
+       }
+       memset(dev, 0, sizeof(*dev));
+
+       inca_dma_init();
+
+       inca_init_switch_chip();
+
+#if defined(CONFIG_INCA_IP_SWITCH_AMDIX)
+       inca_amdix();
+#endif
+
+       sprintf(dev->name, "INCA-IP Switch");
+       dev->init = inca_switch_init;
+       dev->halt = inca_switch_halt;
+       dev->send = inca_switch_send;
+       dev->recv = inca_switch_recv;
+
+       eth_register(dev);
+
+#if 0
+       printf("Leaving inca_switch_initialize()\n");
+#endif
+
+       return 1;
+}
+
+
+static int inca_switch_init(struct eth_device *dev, bd_t * bis)
+{
+       int i;
+       u32 v, regValue;
+       u16 wTmp;
+
+#if 0
+       printf("Entering inca_switch_init()\n");
+#endif
+
+       /* Set MAC address.
+        */
+       wTmp = (u16)dev->enetaddr[0];
+       regValue = (wTmp << 8) | dev->enetaddr[1];
+
+       SW_WRITE_REG(INCA_IP_Switch_PMAC_SA1, regValue);
+
+       wTmp = (u16)dev->enetaddr[2];
+       regValue = (wTmp << 8) | dev->enetaddr[3];
+       regValue = regValue << 16;
+       wTmp = (u16)dev->enetaddr[4];
+       regValue |= (wTmp<<8) | dev->enetaddr[5];
+
+       SW_WRITE_REG(INCA_IP_Switch_PMAC_SA2, regValue);
+
+       /* Initialize the descriptor rings.
+        */
+       for (i = 0; i < NUM_RX_DESC; i++) {
+               inca_rx_descriptor_t * rx_desc = KSEG1ADDR(&rx_ring[i]);
+               memset(rx_desc, 0, sizeof(rx_ring[i]));
+
+               /* Set maximum size of receive buffer.
+                */
+               rx_desc->params.field.NFB = PKTSIZE_ALIGN;
+
+               /* Set the offset of the receive buffer. Zero means
+                * that the offset mechanism is not used.
+                */
+               rx_desc->params.field.offset = 0;
+
+               /* Check if it is the last descriptor.
+                */
+               if (i == (NUM_RX_DESC - 1)) {
+                       /* Let the last descriptor point to the first
+                        * one.
+                        */
+                       rx_desc->nextRxDescPtr = KSEG1ADDR((u32)rx_ring);
+               } else {
+                       /* Set the address of the next descriptor.
+                        */
+                       rx_desc->nextRxDescPtr = (u32)KSEG1ADDR(&rx_ring[i+1]);
+               }
+
+               rx_desc->RxDataPtr = (u32)KSEG1ADDR(NetRxPackets[i]);
+       }
+
+#if 0
+       printf("rx_ring = 0x%08X 0x%08X\n", (u32)rx_ring, (u32)&rx_ring[0]);
+       printf("tx_ring = 0x%08X 0x%08X\n", (u32)tx_ring, (u32)&tx_ring[0]);
+#endif
+
+       for (i = 0; i < NUM_TX_DESC; i++) {
+               inca_tx_descriptor_t * tx_desc = KSEG1ADDR(&tx_ring[i]);
+
+               memset(tx_desc, 0, sizeof(tx_ring[i]));
+
+               tx_desc->params.word       = 0;
+               tx_desc->params.field.HOLD = 1;
+               tx_desc->C                 = 1;
+
+                       /* Check if it is the last descriptor.
+                        */
+               if (i == (NUM_TX_DESC - 1)) {
+                               /* Let the last descriptor point to the
+                                * first one.
+                                */
+                       tx_desc->nextTxDescPtr = KSEG1ADDR((u32)tx_ring);
+               } else {
+                               /* Set the address of the next descriptor.
+                                */
+                       tx_desc->nextTxDescPtr = (u32)KSEG1ADDR(&tx_ring[i+1]);
+               }
+       }
+
+       /* Initialize RxDMA.
+        */
+       DMA_READ_REG(INCA_IP_DMA_DMA_RXISR, v);
+#if 0
+       printf("RX status = 0x%08X\n", v);
+#endif
+
+       /* Writing to the FRDA of CHANNEL.
+        */
+       DMA_WRITE_REG(INCA_IP_DMA_DMA_RXFRDA0, (u32)rx_ring);
+
+       /* Writing to the COMMAND REG.
+        */
+       DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_INIT);
+
+       /* Initialize TxDMA.
+        */
+       DMA_READ_REG(INCA_IP_DMA_DMA_TXISR, v);
+#if 0
+       printf("TX status = 0x%08X\n", v);
+#endif
+
+       /* Writing to the FRDA of CHANNEL.
+        */
+       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXFRDA0, (u32)tx_ring);
+
+       tx_new = rx_new = 0;
+
+       tx_hold = NUM_TX_DESC - 1;
+       rx_hold = NUM_RX_DESC - 1;
+
+#if 0
+       rx_ring[rx_hold].params.field.HOLD = 1;
+#endif
+       /* enable spanning tree forwarding, enable the CPU port */
+       /* ST_PT:
+        *      CPS (CPU port status)   0x3 (forwarding)
+        *      LPS (LAN port status)   0x3 (forwarding)
+        *      PPS (PC port status)    0x3 (forwarding)
+        */
+       SW_WRITE_REG(INCA_IP_Switch_ST_PT,0x3f);
+
+#if 0
+       printf("Leaving inca_switch_init()\n");
+#endif
+
+       return 0;
+}
+
+
+static int inca_switch_send(struct eth_device *dev, volatile void *packet, int length)
+{
+       int                    i;
+       int                    res      = -1;
+       u32                    command;
+       u32                    regValue;
+       inca_tx_descriptor_t * tx_desc  = KSEG1ADDR(&tx_ring[tx_new]);
+
+#if 0
+       printf("Entered inca_switch_send()\n");
+#endif
+
+       if (length <= 0) {
+               printf ("%s: bad packet size: %d\n", dev->name, length);
+               goto Done;
+       }
+
+       for(i = 0; tx_desc->C == 0; i++) {
+               if (i >= TOUT_LOOP) {
+                       printf("%s: tx error buffer not ready\n", dev->name);
+                       goto Done;
+               }
+       }
+
+       if (tx_old_hold >= 0) {
+               KSEG1ADDR(&tx_ring[tx_old_hold])->params.field.HOLD = 1;
+       }
+       tx_old_hold = tx_hold;
+
+       tx_desc->params.word =
+                       (INCA_DMA_TX_SOP | INCA_DMA_TX_EOP | INCA_DMA_TX_HOLD);
+
+       tx_desc->C = 0;
+       tx_desc->TxDataPtr = (u32)packet;
+       tx_desc->params.field.NBA = length;
+
+       KSEG1ADDR(&tx_ring[tx_hold])->params.field.HOLD = 0;
+
+       tx_hold = tx_new;
+       tx_new  = (tx_new + 1) % NUM_TX_DESC;
+
+
+       if (! initialized) {
+               command = INCA_IP_DMA_DMA_TXCCR0_INIT;
+               initialized = 1;
+       } else {
+               command = INCA_IP_DMA_DMA_TXCCR0_HR;
+       }
+
+       DMA_READ_REG(INCA_IP_DMA_DMA_TXCCR0, regValue);
+       regValue |= command;
+#if 0
+       printf("regValue = 0x%x\n", regValue);
+#endif
+       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, regValue);
+
+#if 1
+       for(i = 0; KSEG1ADDR(&tx_ring[tx_hold])->C == 0; i++) {
+               if (i >= TOUT_LOOP) {
+                       printf("%s: tx buffer not ready\n", dev->name);
+                       goto Done;
+               }
+       }
+#endif
+       res = length;
+Done:
+#if 0
+       printf("Leaving inca_switch_send()\n");
+#endif
+       return res;
+}
+
+
+static int inca_switch_recv(struct eth_device *dev)
+{
+       int                    length  = 0;
+       inca_rx_descriptor_t * rx_desc;
+
+#if 0
+       printf("Entered inca_switch_recv()\n");
+#endif
+
+       for (;;) {
+               rx_desc = KSEG1ADDR(&rx_ring[rx_new]);
+
+               if (rx_desc->status.field.C == 0) {
+                       break;
+               }
+
+#if 0
+               rx_ring[rx_new].params.field.HOLD = 1;
+#endif
+
+               if (! rx_desc->status.field.Eop) {
+                       printf("Partly received packet!!!\n");
+                       break;
+               }
+
+               length = rx_desc->status.field.NBT;
+               rx_desc->status.word &=
+                        ~(INCA_DMA_RX_EOP | INCA_DMA_RX_SOP | INCA_DMA_RX_C);
+#if 0
+{
+  int i;
+  for (i=0;i<length - 4;i++) {
+    if (i % 16 == 0) printf("\n%04x: ", i);
+    printf("%02X ", NetRxPackets[rx_new][i]);
+  }
+  printf("\n");
+}
+#endif
+
+               if (length) {
+#if 0
+                       printf("Received %d bytes\n", length);
+#endif
+                       NetReceive((void*)KSEG1ADDR(NetRxPackets[rx_new]), length - 4);
+               } else {
+#if 1
+                       printf("Zero length!!!\n");
+#endif
+               }
+
+
+               KSEG1ADDR(&rx_ring[rx_hold])->params.field.HOLD = 0;
+
+               rx_hold = rx_new;
+
+               rx_new = (rx_new + 1) % NUM_RX_DESC;
+       }
+
+#if 0
+       printf("Leaving inca_switch_recv()\n");
+#endif
+
+       return length;
+}
+
+
+static void inca_switch_halt(struct eth_device *dev)
+{
+#if 0
+       printf("Entered inca_switch_halt()\n");
+#endif
+
+#if 1
+       initialized = 0;
+#endif
+#if 1
+       /* Disable forwarding to the CPU port.
+        */
+       SW_WRITE_REG(INCA_IP_Switch_ST_PT,0xf);
+
+       /* Close RxDMA channel.
+        */
+       DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF);
+
+       /* Close TxDMA channel.
+        */
+       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, INCA_IP_DMA_DMA_TXCCR0_OFF);
+
+
+#endif
+#if 0
+       printf("Leaving inca_switch_halt()\n");
+#endif
+}
+
+
+static void inca_init_switch_chip(void)
+{
+       u32 regValue;
+
+       /* To workaround a problem with collision counter
+        * (see Errata sheet).
+        */
+       SW_WRITE_REG(INCA_IP_Switch_PC_TX_CTL, 0x00000001);
+       SW_WRITE_REG(INCA_IP_Switch_LAN_TX_CTL, 0x00000001);
+
+#if 1
+       /* init MDIO configuration:
+        *      MDS (Poll speed):       0x01 (4ms)
+        *      PHY_LAN_ADDR:           0x06
+        *      PHY_PC_ADDR:            0x05
+        *      UEP (Use External PHY): 0x00 (Internal PHY is used)
+        *      PS (Port Select):       0x00 (PT/UMM for LAN)
+        *      PT (PHY Test):          0x00 (no test mode)
+        *      UMM (Use MDIO Mode):    0x00 (state machine is disabled)
+        */
+       SW_WRITE_REG(INCA_IP_Switch_MDIO_CFG, 0x4c50);
+
+       /* init PHY:
+        *      SL (Auto Neg. Speed for LAN)
+        *      SP (Auto Neg. Speed for PC)
+        *      LL (Link Status for LAN)
+        *      LP (Link Status for PC)
+        *      DL (Duplex Status for LAN)
+        *      DP (Duplex Status for PC)
+        *      PL (Auto Neg. Pause Status for LAN)
+        *      PP (Auto Neg. Pause Status for PC)
+        */
+       SW_WRITE_REG (INCA_IP_Switch_EPHY, 0xff);
+
+       /* MDIO_ACC:
+        *      RA (Request/Ack)  0x01 (Request)
+        *      RW (Read/Write)   0x01 (Write)
+        *      PHY_ADDR          0x05 (PC)
+        *      REG_ADDR          0x00 (PHY_BCR: basic control register)
+        *      PHY_DATA          0x8000
+        *                    Reset                   - software reset
+        *                    LB (loop back)          - normal
+        *                    SS (speed select)       - 10 Mbit/s
+        *                    ANE (auto neg. enable)  - enable
+        *                    PD (power down)         - normal
+        *                    ISO (isolate)           - normal
+        *                    RAN (restart auto neg.) - normal
+        *                    DM (duplex mode)        - half duplex
+        *                    CT (collision test)     - enable
+        */
+       SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, 0xc0a09000);
+
+       /* MDIO_ACC:
+        *      RA (Request/Ack)  0x01 (Request)
+        *      RW (Read/Write)   0x01 (Write)
+        *      PHY_ADDR          0x06 (LAN)
+        *      REG_ADDR          0x00 (PHY_BCR: basic control register)
+        *      PHY_DATA          0x8000
+        *                    Reset                   - software reset
+        *                    LB (loop back)          - normal
+        *                    SS (speed select)       - 10 Mbit/s
+        *                    ANE (auto neg. enable)  - enable
+        *                    PD (power down)         - normal
+        *                    ISO (isolate)           - normal
+        *                    RAN (restart auto neg.) - normal
+        *                    DM (duplex mode)        - half duplex
+        *                    CT (collision test)     - enable
+        */
+       SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, 0xc0c09000);
+
+#endif
+
+       /* Make sure the CPU port is disabled for now. We
+        * don't want packets to get stacked for us until
+        * we enable DMA and are prepared to receive them.
+        */
+       SW_WRITE_REG(INCA_IP_Switch_ST_PT,0xf);
+
+       SW_READ_REG(INCA_IP_Switch_ARL_CTL, regValue);
+
+       /* CRC GEN is enabled.
+        */
+       regValue |= 0x00000200;
+       SW_WRITE_REG(INCA_IP_Switch_ARL_CTL, regValue);
+
+       /* ADD TAG is disabled.
+        */
+       SW_READ_REG(INCA_IP_Switch_PMAC_HD_CTL, regValue);
+       regValue &= ~0x00000002;
+       SW_WRITE_REG(INCA_IP_Switch_PMAC_HD_CTL, regValue);
+}
+
+
+static void inca_dma_init(void)
+{
+       /* Switch off all DMA channels.
+        */
+       DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF);
+       DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR1, INCA_IP_DMA_DMA_RXCCR1_OFF);
+
+       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF);
+       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR1, INCA_IP_DMA_DMA_TXCCR1_OFF);
+       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR2, INCA_IP_DMA_DMA_TXCCR2_OFF);
+
+       /* Setup TX channel polling time.
+        */
+       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXPOLL, INCA_DMA_TX_POLLING_TIME);
+
+       /* Setup RX channel polling time.
+        */
+       DMA_WRITE_REG(INCA_IP_DMA_DMA_RXPOLL, INCA_DMA_RX_POLLING_TIME);
+
+       /* ERRATA: write reset value into the DMA RX IMR register.
+        */
+       DMA_WRITE_REG(INCA_IP_DMA_DMA_RXIMR, 0xFFFFFFFF);
+
+       /* Just in case: disable all transmit interrupts also.
+        */
+       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXIMR, 0xFFFFFFFF);
+
+       DMA_WRITE_REG(INCA_IP_DMA_DMA_TXISR, 0xFFFFFFFF);
+       DMA_WRITE_REG(INCA_IP_DMA_DMA_RXISR, 0xFFFFFFFF);
+}
+
+#if defined(CONFIG_INCA_IP_SWITCH_AMDIX)
+static int inca_amdix(void)
+{
+       u32 phyReg1 = 0;
+       u32 phyReg4 = 0;
+       u32 phyReg5 = 0;
+       u32 phyReg6 = 0;
+       u32 phyReg31 = 0;
+       u32 regEphy = 0;
+       int mdi_flag;
+       int retries;
+
+       /* Setup GPIO pins.
+        */
+       *INCA_IP_AUTO_MDIX_LAN_PORTS_DIR    |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
+       *INCA_IP_AUTO_MDIX_LAN_PORTS_ALTSEL |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
+
+#if 0
+       /* Wait for signal.
+        */
+       retries = WAIT_SIGNAL_RETRIES;
+       while (--retries) {
+               SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+                               (0x1 << 31) |   /* RA           */
+                               (0x0 << 30) |   /* Read         */
+                               (0x6 << 21) |   /* LAN          */
+                               (17  << 16));   /* PHY_MCSR     */
+               do {
+                       SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1);
+               } while (phyReg1 & (1 << 31));
+
+               if (phyReg1 & (1 << 1)) {
+                       /* Signal detected */
+                       break;
+               }
+       }
+
+       if (!retries)
+               goto Fail;
+#endif
+
+       /* Set MDI mode.
+        */
+       *INCA_IP_AUTO_MDIX_LAN_PORTS_OUT &= ~(1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
+       mdi_flag = 1;
+
+       /* Wait for link.
+        */
+       retries = WAIT_LINK_RETRIES;
+       while (--retries) {
+               udelay(LINK_RETRY_DELAY * 1000);
+               SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+                               (0x1 << 31) |   /* RA           */
+                               (0x0 << 30) |   /* Read         */
+                               (0x6 << 21) |   /* LAN          */
+                               (1   << 16));   /* PHY_BSR      */
+               do {
+                       SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1);
+               } while (phyReg1 & (1 << 31));
+
+               if (phyReg1 & (1 << 2)) {
+                       /* Link is up */
+                       break;
+               } else if (mdi_flag) {
+                       /* Set MDIX mode */
+                       *INCA_IP_AUTO_MDIX_LAN_PORTS_OUT |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
+                       mdi_flag = 0;
+               } else {
+                       /* Set MDI mode */
+                       *INCA_IP_AUTO_MDIX_LAN_PORTS_OUT &= ~(1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
+                       mdi_flag = 1;
+               }
+       }
+
+       if (!retries) {
+               goto Fail;
+       } else {
+               SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+                               (0x1 << 31) |   /* RA           */
+                               (0x0 << 30) |   /* Read         */
+                               (0x6 << 21) |   /* LAN          */
+                               (1   << 16));   /* PHY_BSR      */
+               do {
+                       SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1);
+               } while (phyReg1 & (1 << 31));
+
+               /* Auto-negotiation / Parallel detection complete
+                */
+               if (phyReg1 & (1 << 5)) {
+                       SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+                               (0x1 << 31) |   /* RA           */
+                               (0x0 << 30) |   /* Read         */
+                               (0x6 << 21) |   /* LAN          */
+                               (31  << 16));   /* PHY_SCSR     */
+                       do {
+                               SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg31);
+                       } while (phyReg31 & (1 << 31));
+
+                       switch ((phyReg31 >> 2) & 0x7) {
+                       case INCA_SWITCH_PHY_SPEED_10H:
+                               /* 10Base-T Half-duplex */
+                               regEphy = 0;
+                               break;
+                       case INCA_SWITCH_PHY_SPEED_10F:
+                               /* 10Base-T Full-duplex */
+                               regEphy = INCA_IP_Switch_EPHY_DL;
+                               break;
+                       case INCA_SWITCH_PHY_SPEED_100H:
+                               /* 100Base-TX Half-duplex */
+                               regEphy = INCA_IP_Switch_EPHY_SL;
+                               break;
+                       case INCA_SWITCH_PHY_SPEED_100F:
+                               /* 100Base-TX Full-duplex */
+                               regEphy = INCA_IP_Switch_EPHY_SL | INCA_IP_Switch_EPHY_DL;
+                               break;
+                       }
+
+                       /* In case of Auto-negotiation,
+                        * update the negotiated PAUSE support status
+                        */
+                       if (phyReg1 & (1 << 3)) {
+                               SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+                                       (0x1 << 31) |   /* RA           */
+                                       (0x0 << 30) |   /* Read         */
+                                       (0x6 << 21) |   /* LAN          */
+                                       (6   << 16));   /* PHY_ANER     */
+                               do {
+                                       SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg6);
+                               } while (phyReg6 & (1 << 31));
+
+                               /* We are Autoneg-able.
+                                * Is Link partner also able to autoneg?
+                                */
+                               if (phyReg6 & (1 << 0)) {
+                                       SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+                                               (0x1 << 31) |   /* RA           */
+                                               (0x0 << 30) |   /* Read         */
+                                               (0x6 << 21) |   /* LAN          */
+                                               (4   << 16));   /* PHY_ANAR     */
+                                       do {
+                                               SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg4);
+                                       } while (phyReg4 & (1 << 31));
+
+                                       /* We advertise PAUSE capab.
+                                        * Does link partner also advertise it?
+                                        */
+                                       if (phyReg4 & (1 << 10)) {
+                                               SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+                                                       (0x1 << 31) |   /* RA           */
+                                                       (0x0 << 30) |   /* Read         */
+                                                       (0x6 << 21) |   /* LAN          */
+                                                       (5   << 16));   /* PHY_ANLPAR   */
+                                               do {
+                                                       SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg5);
+                                               } while (phyReg5 & (1 << 31));
+
+                                               /* Link partner is PAUSE capab.
+                                                */
+                                               if (phyReg5 & (1 << 10)) {
+                                                       regEphy |= INCA_IP_Switch_EPHY_PL;
+                                               }
+                                       }
+                               }
+
+                       }
+
+                       /* Link is up */
+                       regEphy |= INCA_IP_Switch_EPHY_LL;
+
+                       SW_WRITE_REG(INCA_IP_Switch_EPHY, regEphy);
+               }
+       }
+
+       return 0;
+
+Fail:
+       printf("No Link on LAN port\n");
+       return -1;
+}
+#endif /* CONFIG_INCA_IP_SWITCH_AMDIX */
+
+#endif
diff --git a/drivers/net/ks8695eth.c b/drivers/net/ks8695eth.c
new file mode 100644 (file)
index 0000000..b598dd7
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * ks8695eth.c -- KS8695 ethernet driver
+ *
+ * (C) Copyright 2004-2005, Greg Ungerer <greg.ungerer@opengear.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/****************************************************************************/
+
+#include <common.h>
+
+#ifdef CONFIG_DRIVER_KS8695ETH
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <asm/arch/platform.h>
+
+/****************************************************************************/
+
+/*
+ * Hardware register access to the KS8695 LAN ethernet port
+ * (well, it is the 4 port switch really).
+ */
+#define        ks8695_read(a)    *((volatile unsigned long *) (KS8695_IO_BASE + (a)))
+#define        ks8695_write(a,v) *((volatile unsigned long *) (KS8695_IO_BASE + (a))) = (v)
+
+/****************************************************************************/
+
+/*
+ * Define the descriptor in-memory data structures.
+ */
+struct ks8695_txdesc {
+       uint32_t        owner;
+       uint32_t        ctrl;
+       uint32_t        addr;
+       uint32_t        next;
+};
+
+struct ks8695_rxdesc {
+       uint32_t        status;
+       uint32_t        ctrl;
+       uint32_t        addr;
+       uint32_t        next;
+};
+
+/****************************************************************************/
+
+/*
+ * Allocate local data structures to use for receiving and sending
+ * packets. Just to keep it all nice and simple.
+ */
+
+#define        TXDESCS         4
+#define        RXDESCS         4
+#define        BUFSIZE         2048
+
+volatile struct ks8695_txdesc ks8695_tx[TXDESCS] __attribute__((aligned(256)));
+volatile struct ks8695_rxdesc ks8695_rx[RXDESCS] __attribute__((aligned(256)));
+volatile uint8_t ks8695_bufs[BUFSIZE*(TXDESCS+RXDESCS)] __attribute__((aligned(2048)));;
+
+/****************************************************************************/
+
+/*
+ *     Ideally we want to use the MAC address stored in flash.
+ *     But we do some sanity checks in case they are not present
+ *     first.
+ */
+unsigned char eth_mac[] = {
+       0x00, 0x13, 0xc6, 0x00, 0x00, 0x00
+};
+
+void ks8695_getmac(void)
+{
+       unsigned char *fp;
+       int i;
+
+       /* Check if flash MAC is valid */
+       fp = (unsigned char *) 0x0201c000;
+       for (i = 0; (i < 6); i++) {
+               if ((fp[i] != 0) && (fp[i] != 0xff))
+                       break;
+       }
+
+       /* If we found a valid looking MAC address then use it */
+       if (i < 6)
+               memcpy(&eth_mac[0], fp, 6);
+}
+
+/****************************************************************************/
+
+void eth_reset(bd_t *bd)
+{
+       int i;
+
+       debug ("%s(%d): eth_reset()\n", __FILE__, __LINE__);
+
+       /* Reset the ethernet engines first */
+       ks8695_write(KS8695_LAN_DMA_TX, 0x80000000);
+       ks8695_write(KS8695_LAN_DMA_RX, 0x80000000);
+
+       ks8695_getmac();
+
+       /* Set MAC address */
+       ks8695_write(KS8695_LAN_MAC_LOW, (eth_mac[5] | (eth_mac[4] << 8) |
+               (eth_mac[3] << 16) | (eth_mac[2] << 24)));
+       ks8695_write(KS8695_LAN_MAC_HIGH, (eth_mac[1] | (eth_mac[0] << 8)));
+
+       /* Turn the 4 port switch on */
+       i = ks8695_read(KS8695_SWITCH_CTRL0);
+       ks8695_write(KS8695_SWITCH_CTRL0, (i | 0x1));
+       /* ks8695_write(KS8695_WAN_CONTROL, 0x3f000066); */
+
+       /* Initialize descriptor rings */
+       for (i = 0; (i < TXDESCS); i++) {
+               ks8695_tx[i].owner = 0;
+               ks8695_tx[i].ctrl = 0;
+               ks8695_tx[i].addr = (uint32_t) &ks8695_bufs[i*BUFSIZE];
+               ks8695_tx[i].next = (uint32_t) &ks8695_tx[i+1];
+       }
+       ks8695_tx[TXDESCS-1].ctrl = 0x02000000;
+       ks8695_tx[TXDESCS-1].next = (uint32_t) &ks8695_tx[0];
+
+       for (i = 0; (i < RXDESCS); i++) {
+               ks8695_rx[i].status = 0x80000000;
+               ks8695_rx[i].ctrl = BUFSIZE - 4;
+               ks8695_rx[i].addr = (uint32_t) &ks8695_bufs[(i+TXDESCS)*BUFSIZE];
+               ks8695_rx[i].next = (uint32_t) &ks8695_rx[i+1];
+       }
+       ks8695_rx[RXDESCS-1].ctrl |= 0x00080000;
+       ks8695_rx[RXDESCS-1].next = (uint32_t) &ks8695_rx[0];
+
+       /* The KS8695 is pretty slow reseting the ethernets... */
+       udelay(2000000);
+
+       /* Enable the ethernet engine */
+       ks8695_write(KS8695_LAN_TX_LIST, (uint32_t) &ks8695_tx[0]);
+       ks8695_write(KS8695_LAN_RX_LIST, (uint32_t) &ks8695_rx[0]);
+       ks8695_write(KS8695_LAN_DMA_TX, 0x3);
+       ks8695_write(KS8695_LAN_DMA_RX, 0x71);
+       ks8695_write(KS8695_LAN_DMA_RX_START, 0x1);
+
+       printf("KS8695 ETHERNET: ");
+       for (i = 0; (i < 5); i++) {
+               bd->bi_enetaddr[i] = eth_mac[i];
+               printf("%02x:", eth_mac[i]);
+       }
+       bd->bi_enetaddr[i] = eth_mac[i];
+       printf("%02x\n", eth_mac[i]);
+}
+
+/****************************************************************************/
+
+int eth_init(bd_t *bd)
+{
+       debug ("%s(%d): eth_init()\n", __FILE__, __LINE__);
+
+       eth_reset(bd);
+       return 0;
+}
+
+/****************************************************************************/
+
+void eth_halt(void)
+{
+       debug ("%s(%d): eth_halt()\n", __FILE__, __LINE__);
+
+       /* Reset the ethernet engines */
+       ks8695_write(KS8695_LAN_DMA_TX, 0x80000000);
+       ks8695_write(KS8695_LAN_DMA_RX, 0x80000000);
+}
+
+/****************************************************************************/
+
+int eth_rx(void)
+{
+       volatile struct ks8695_rxdesc *dp;
+       int i, len = 0;
+
+       debug ("%s(%d): eth_rx()\n", __FILE__, __LINE__);
+
+       for (i = 0; (i < RXDESCS); i++) {
+               dp= &ks8695_rx[i];
+               if ((dp->status & 0x80000000) == 0) {
+                       len = (dp->status & 0x7ff) - 4;
+                       NetReceive((void *) dp->addr, len);
+                       dp->status = 0x80000000;
+                       ks8695_write(KS8695_LAN_DMA_RX_START, 0x1);
+                       break;
+               }
+       }
+
+       return len;
+}
+
+/****************************************************************************/
+
+int eth_send(volatile void *packet, int len)
+{
+       volatile struct ks8695_txdesc *dp;
+       static int next = 0;
+
+       debug ("%s(%d): eth_send(packet=%x,len=%d)\n", __FILE__, __LINE__,
+               packet, len);
+
+       dp = &ks8695_tx[next];
+       memcpy((void *) dp->addr, (void *) packet, len);
+
+       if (len < 64) {
+               memset((void *) (dp->addr + len), 0, 64-len);
+               len = 64;
+       }
+
+       dp->ctrl = len | 0xe0000000;
+       dp->owner = 0x80000000;
+
+       ks8695_write(KS8695_LAN_DMA_TX, 0x3);
+       ks8695_write(KS8695_LAN_DMA_TX_START, 0x1);
+
+       if (++next >= TXDESCS)
+               next = 0;
+
+       return len;
+}
+
+#endif /* CONFIG_DRIVER_KS8695ETH */
diff --git a/drivers/net/lan91c96.c b/drivers/net/lan91c96.c
new file mode 100644 (file)
index 0000000..ecdcbd9
--- /dev/null
@@ -0,0 +1,967 @@
+/*------------------------------------------------------------------------
+ * lan91c96.c
+ * This is a driver for SMSC's LAN91C96 single-chip Ethernet device, based
+ * on the SMC91111 driver from U-boot.
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Rolf Offermanns <rof@sysgo.de>
+ *
+ * Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
+ *       Developed by Simple Network Magic Corporation (SNMC)
+ * Copyright (C) 1996 by Erik Stahlman (ES)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Information contained in this file was obtained from the LAN91C96
+ * manual from SMC.  To get a copy, if you really want one, you can find
+ * information under www.smsc.com.
+ *
+ *
+ * "Features" of the SMC chip:
+ *   6144 byte packet memory. ( for the 91C96 )
+ *   EEPROM for configuration
+ *   AUI/TP selection  ( mine has 10Base2/10BaseT select )
+ *
+ * Arguments:
+ *     io      = for the base address
+ *     irq     = for the IRQ
+ *
+ * author:
+ *     Erik Stahlman                           ( erik@vt.edu )
+ *     Daris A Nevil                           ( dnevil@snmc.com )
+ *
+ *
+ * Hardware multicast code from Peter Cammaert ( pc@denkart.be )
+ *
+ * Sources:
+ *    o   SMSC LAN91C96 databook (www.smsc.com)
+ *    o   smc91111.c (u-boot driver)
+ *    o   smc9194.c (linux kernel driver)
+ *    o   lan91c96.c (Intel Diagnostic Manager driver)
+ *
+ * History:
+ *     04/30/03  Mathijs Haarman       Modified smc91111.c (u-boot version)
+ *                                     for lan91c96
+ *---------------------------------------------------------------------------
+ */
+
+#include <common.h>
+#include <command.h>
+#include "lan91c96.h"
+#include <net.h>
+
+#ifdef CONFIG_DRIVER_LAN91C96
+
+#if defined(CONFIG_CMD_NET)
+
+/*------------------------------------------------------------------------
+ *
+ * Configuration options, for the experienced user to change.
+ *
+ -------------------------------------------------------------------------*/
+
+/* Use power-down feature of the chip */
+#define POWER_DOWN     0
+
+/*
+ * Wait time for memory to be free.  This probably shouldn't be
+ * tuned that much, as waiting for this means nothing else happens
+ * in the system
+*/
+#define MEMORY_WAIT_TIME 16
+
+#define SMC_DEBUG 0
+
+#if (SMC_DEBUG > 2 )
+#define PRINTK3(args...) printf(args)
+#else
+#define PRINTK3(args...)
+#endif
+
+#if SMC_DEBUG > 1
+#define PRINTK2(args...) printf(args)
+#else
+#define PRINTK2(args...)
+#endif
+
+#ifdef SMC_DEBUG
+#define PRINTK(args...) printf(args)
+#else
+#define PRINTK(args...)
+#endif
+
+
+/*------------------------------------------------------------------------
+ *
+ * The internal workings of the driver.  If you are changing anything
+ * here with the SMC stuff, you should have the datasheet and know
+ * what you are doing.
+ *
+ *------------------------------------------------------------------------
+ */
+#define CARDNAME "LAN91C96"
+
+#define SMC_BASE_ADDRESS CONFIG_LAN91C96_BASE
+
+#define SMC_DEV_NAME "LAN91C96"
+#define SMC_ALLOC_MAX_TRY 5
+#define SMC_TX_TIMEOUT 30
+
+#define ETH_ZLEN 60
+
+#ifdef  CONFIG_LAN91C96_USE_32_BIT
+#define USE_32_BIT  1
+#else
+#undef USE_32_BIT
+#endif
+
+/*-----------------------------------------------------------------
+ *
+ *  The driver can be entered at any of the following entry points.
+ *
+ *-----------------------------------------------------------------
+ */
+
+extern int eth_init (bd_t * bd);
+extern void eth_halt (void);
+extern int eth_rx (void);
+extern int eth_send (volatile void *packet, int length);
+#if 0
+static int smc_hw_init (void);
+#endif
+
+/*
+ * This is called by  register_netdev().  It is responsible for
+ * checking the portlist for the SMC9000 series chipset.  If it finds
+ * one, then it will initialize the device, find the hardware information,
+ * and sets up the appropriate device parameters.
+ * NOTE: Interrupts are *OFF* when this procedure is called.
+ *
+ * NB:This shouldn't be static since it is referred to externally.
+ */
+int smc_init (void);
+
+/*
+ * This is called by  unregister_netdev().  It is responsible for
+ * cleaning up before the driver is finally unregistered and discarded.
+ */
+void smc_destructor (void);
+
+/*
+ * The kernel calls this function when someone wants to use the device,
+ * typically 'ifconfig ethX up'.
+ */
+static int smc_open (bd_t *bd);
+
+
+/*
+ * This is called by the kernel in response to 'ifconfig ethX down'.  It
+ * is responsible for cleaning up everything that the open routine
+ * does, and maybe putting the card into a powerdown state.
+ */
+static int smc_close (void);
+
+/*
+ * This is a separate procedure to handle the receipt of a packet, to
+ * leave the interrupt code looking slightly cleaner
+ */
+static int smc_rcv (void);
+
+/* See if a MAC address is defined in the current environment. If so use it. If not
+ . print a warning and set the environment and other globals with the default.
+ . If an EEPROM is present it really should be consulted.
+*/
+int smc_get_ethaddr(bd_t *bd);
+int get_rom_mac(unsigned char *v_rom_mac);
+
+/* ------------------------------------------------------------
+ * Internal routines
+ * ------------------------------------------------------------
+ */
+
+static unsigned char smc_mac_addr[] = { 0xc0, 0x00, 0x00, 0x1b, 0x62, 0x9c };
+
+/*
+ * This function must be called before smc_open() if you want to override
+ * the default mac address.
+ */
+
+void smc_set_mac_addr (const unsigned char *addr)
+{
+       int i;
+
+       for (i = 0; i < sizeof (smc_mac_addr); i++) {
+               smc_mac_addr[i] = addr[i];
+       }
+}
+
+/*
+ * smc_get_macaddr is no longer used. If you want to override the default
+ * mac address, call smc_get_mac_addr as a part of the board initialisation.
+ */
+
+#if 0
+void smc_get_macaddr (byte * addr)
+{
+       /* MAC ADDRESS AT FLASHBLOCK 1 / OFFSET 0x10 */
+       unsigned char *dnp1110_mac = (unsigned char *) (0xE8000000 + 0x20010);
+       int i;
+
+
+       for (i = 0; i < 6; i++) {
+               addr[0] = *(dnp1110_mac + 0);
+               addr[1] = *(dnp1110_mac + 1);
+               addr[2] = *(dnp1110_mac + 2);
+               addr[3] = *(dnp1110_mac + 3);
+               addr[4] = *(dnp1110_mac + 4);
+               addr[5] = *(dnp1110_mac + 5);
+       }
+}
+#endif /* 0 */
+
+/***********************************************
+ * Show available memory                       *
+ ***********************************************/
+void dump_memory_info (void)
+{
+       word mem_info;
+       word old_bank;
+
+       old_bank = SMC_inw (LAN91C96_BANK_SELECT) & 0xF;
+
+       SMC_SELECT_BANK (0);
+       mem_info = SMC_inw (LAN91C96_MIR);
+       PRINTK2 ("Memory: %4d available\n", (mem_info >> 8) * 2048);
+
+       SMC_SELECT_BANK (old_bank);
+}
+
+/*
+ * A rather simple routine to print out a packet for debugging purposes.
+ */
+#if SMC_DEBUG > 2
+static void print_packet (byte *, int);
+#endif
+
+/* #define tx_done(dev) 1 */
+
+
+/* this does a soft reset on the device */
+static void smc_reset (void);
+
+/* Enable Interrupts, Receive, and Transmit */
+static void smc_enable (void);
+
+/* this puts the device in an inactive state */
+static void smc_shutdown (void);
+
+
+static int poll4int (byte mask, int timeout)
+{
+       int tmo = get_timer (0) + timeout * CFG_HZ;
+       int is_timeout = 0;
+       word old_bank = SMC_inw (LAN91C96_BANK_SELECT);
+
+       PRINTK2 ("Polling...\n");
+       SMC_SELECT_BANK (2);
+       while ((SMC_inw (LAN91C96_INT_STATS) & mask) == 0) {
+               if (get_timer (0) >= tmo) {
+                       is_timeout = 1;
+                       break;
+               }
+       }
+
+       /* restore old bank selection */
+       SMC_SELECT_BANK (old_bank);
+
+       if (is_timeout)
+               return 1;
+       else
+               return 0;
+}
+
+/*
+ * Function: smc_reset( void )
+ * Purpose:
+ *     This sets the SMC91111 chip to its normal state, hopefully from whatever
+ *     mess that any other DOS driver has put it in.
+ *
+ * Maybe I should reset more registers to defaults in here?  SOFTRST  should
+ * do that for me.
+ *
+ * Method:
+ *     1.  send a SOFT RESET
+ *     2.  wait for it to finish
+ *     3.  enable autorelease mode
+ *     4.  reset the memory management unit
+ *     5.  clear all interrupts
+ *
+*/
+static void smc_reset (void)
+{
+       PRINTK2 ("%s:smc_reset\n", SMC_DEV_NAME);
+
+       /* This resets the registers mostly to defaults, but doesn't
+          affect EEPROM.  That seems unnecessary */
+       SMC_SELECT_BANK (0);
+       SMC_outw (LAN91C96_RCR_SOFT_RST, LAN91C96_RCR);
+
+       udelay (10);
+
+       /* Disable transmit and receive functionality */
+       SMC_outw (0, LAN91C96_RCR);
+       SMC_outw (0, LAN91C96_TCR);
+
+       /* set the control register */
+       SMC_SELECT_BANK (1);
+       SMC_outw (SMC_inw (LAN91C96_CONTROL) | LAN91C96_CTR_BIT_8,
+                         LAN91C96_CONTROL);
+
+       /* Disable all interrupts */
+       SMC_outb (0, LAN91C96_INT_MASK);
+}
+
+/*
+ * Function: smc_enable
+ * Purpose: let the chip talk to the outside work
+ * Method:
+ *     1.  Initialize the Memory Configuration Register
+ *     2.  Enable the transmitter
+ *     3.  Enable the receiver
+*/
+static void smc_enable ()
+{
+       PRINTK2 ("%s:smc_enable\n", SMC_DEV_NAME);
+       SMC_SELECT_BANK (0);
+
+       /* Initialize the Memory Configuration Register. See page
+          49 of the LAN91C96 data sheet for details. */
+       SMC_outw (LAN91C96_MCR_TRANSMIT_PAGES, LAN91C96_MCR);
+
+       /* Initialize the Transmit Control Register */
+       SMC_outw (LAN91C96_TCR_TXENA, LAN91C96_TCR);
+       /* Initialize the Receive Control Register
+        * FIXME:
+        * The promiscuous bit set because I could not receive ARP reply
+        * packets from the server when I send a ARP request. It only works
+        * when I set the promiscuous bit
+        */
+       SMC_outw (LAN91C96_RCR_RXEN | LAN91C96_RCR_PRMS, LAN91C96_RCR);
+}
+
+/*
+ * Function: smc_shutdown
+ * Purpose:  closes down the SMC91xxx chip.
+ * Method:
+ *     1. zero the interrupt mask
+ *     2. clear the enable receive flag
+ *     3. clear the enable xmit flags
+ *
+ * TODO:
+ *   (1) maybe utilize power down mode.
+ *     Why not yet?  Because while the chip will go into power down mode,
+ *     the manual says that it will wake up in response to any I/O requests
+ *     in the register space.   Empirical results do not show this working.
+ */
+static void smc_shutdown ()
+{
+       PRINTK2 (CARDNAME ":smc_shutdown\n");
+
+       /* no more interrupts for me */
+       SMC_SELECT_BANK (2);
+       SMC_outb (0, LAN91C96_INT_MASK);
+
+       /* and tell the card to stay away from that nasty outside world */
+       SMC_SELECT_BANK (0);
+       SMC_outb (0, LAN91C96_RCR);
+       SMC_outb (0, LAN91C96_TCR);
+}
+
+
+/*
+ * Function:  smc_hardware_send_packet(struct net_device * )
+ * Purpose:
+ *     This sends the actual packet to the SMC9xxx chip.
+ *
+ * Algorithm:
+ *     First, see if a saved_skb is available.
+ *             ( this should NOT be called if there is no 'saved_skb'
+ *     Now, find the packet number that the chip allocated
+ *     Point the data pointers at it in memory
+ *     Set the length word in the chip's memory
+ *     Dump the packet to chip memory
+ *     Check if a last byte is needed ( odd length packet )
+ *             if so, set the control flag right
+ *     Tell the card to send it
+ *     Enable the transmit interrupt, so I know if it failed
+ *     Free the kernel data if I actually sent it.
+ */
+static int smc_send_packet (volatile void *packet, int packet_length)
+{
+       byte packet_no;
+       unsigned long ioaddr;
+       byte *buf;
+       int length;
+       int numPages;
+       int try = 0;
+       int time_out;
+       byte status;
+
+
+       PRINTK3 ("%s:smc_hardware_send_packet\n", SMC_DEV_NAME);
+
+       length = ETH_ZLEN < packet_length ? packet_length : ETH_ZLEN;
+
+       /* allocate memory
+        ** The MMU wants the number of pages to be the number of 256 bytes
+        ** 'pages', minus 1 ( since a packet can't ever have 0 pages :) )
+        **
+        ** The 91C111 ignores the size bits, but the code is left intact
+        ** for backwards and future compatibility.
+        **
+        ** Pkt size for allocating is data length +6 (for additional status
+        ** words, length and ctl!)
+        **
+        ** If odd size then last byte is included in this header.
+        */
+       numPages = ((length & 0xfffe) + 6);
+       numPages >>= 8;                         /* Divide by 256 */
+
+       if (numPages > 7) {
+               printf ("%s: Far too big packet error. \n", SMC_DEV_NAME);
+               return 0;
+       }
+
+       /* now, try to allocate the memory */
+
+       SMC_SELECT_BANK (2);
+       SMC_outw (LAN91C96_MMUCR_ALLOC_TX | numPages, LAN91C96_MMU);
+
+  again:
+       try++;
+       time_out = MEMORY_WAIT_TIME;
+       do {
+               status = SMC_inb (LAN91C96_INT_STATS);
+               if (status & LAN91C96_IST_ALLOC_INT) {
+
+                       SMC_outb (LAN91C96_IST_ALLOC_INT, LAN91C96_INT_STATS);
+                       break;
+               }
+       } while (--time_out);
+
+       if (!time_out) {
+               PRINTK2 ("%s: memory allocation, try %d failed ...\n",
+                                SMC_DEV_NAME, try);
+               if (try < SMC_ALLOC_MAX_TRY)
+                       goto again;
+               else
+                       return 0;
+       }
+
+       PRINTK2 ("%s: memory allocation, try %d succeeded ...\n",
+                        SMC_DEV_NAME, try);
+
+       /* I can send the packet now.. */
+
+       ioaddr = SMC_BASE_ADDRESS;
+
+       buf = (byte *) packet;
+
+       /* If I get here, I _know_ there is a packet slot waiting for me */
+       packet_no = SMC_inb (LAN91C96_ARR);
+       if (packet_no & LAN91C96_ARR_FAILED) {
+               /* or isn't there?  BAD CHIP! */
+               printf ("%s: Memory allocation failed. \n", SMC_DEV_NAME);
+               return 0;
+       }
+
+       /* we have a packet address, so tell the card to use it */
+       SMC_outb (packet_no, LAN91C96_PNR);
+
+       /* point to the beginning of the packet */
+       SMC_outw (LAN91C96_PTR_AUTO_INCR, LAN91C96_POINTER);
+
+       PRINTK3 ("%s: Trying to xmit packet of length %x\n",
+                        SMC_DEV_NAME, length);
+
+#if SMC_DEBUG > 2
+       printf ("Transmitting Packet\n");
+       print_packet (buf, length);
+#endif
+
+       /* send the packet length ( +6 for status, length and ctl byte )
+          and the status word ( set to zeros ) */
+#ifdef USE_32_BIT
+       SMC_outl ((length + 6) << 16, LAN91C96_DATA_HIGH);
+#else
+       SMC_outw (0, LAN91C96_DATA_HIGH);
+       /* send the packet length ( +6 for status words, length, and ctl */
+       SMC_outw ((length + 6), LAN91C96_DATA_HIGH);
+#endif /* USE_32_BIT */
+
+       /* send the actual data
+        * I _think_ it's faster to send the longs first, and then
+        * mop up by sending the last word.  It depends heavily
+        * on alignment, at least on the 486.  Maybe it would be
+        * a good idea to check which is optimal?  But that could take
+        * almost as much time as is saved?
+        */
+#ifdef USE_32_BIT
+       SMC_outsl (LAN91C96_DATA_HIGH, buf, length >> 2);
+       if (length & 0x2)
+               SMC_outw (*((word *) (buf + (length & 0xFFFFFFFC))),
+                                 LAN91C96_DATA_HIGH);
+#else
+       SMC_outsw (LAN91C96_DATA_HIGH, buf, (length) >> 1);
+#endif /* USE_32_BIT */
+
+       /* Send the last byte, if there is one.   */
+       if ((length & 1) == 0) {
+               SMC_outw (0, LAN91C96_DATA_HIGH);
+       } else {
+               SMC_outw (buf[length - 1] | 0x2000, LAN91C96_DATA_HIGH);
+       }
+
+       /* and let the chipset deal with it */
+       SMC_outw (LAN91C96_MMUCR_ENQUEUE, LAN91C96_MMU);
+
+       /* poll for TX INT */
+       if (poll4int (LAN91C96_MSK_TX_INT, SMC_TX_TIMEOUT)) {
+               /* sending failed */
+               PRINTK2 ("%s: TX timeout, sending failed...\n", SMC_DEV_NAME);
+
+               /* release packet */
+               SMC_outw (LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU);
+
+               /* wait for MMU getting ready (low) */
+               while (SMC_inw (LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY) {
+                       udelay (10);
+               }
+
+               PRINTK2 ("MMU ready\n");
+
+
+               return 0;
+       } else {
+               /* ack. int */
+               SMC_outw (LAN91C96_IST_TX_INT, LAN91C96_INT_STATS);
+
+               PRINTK2 ("%s: Sent packet of length %d \n", SMC_DEV_NAME, length);
+
+               /* release packet */
+               SMC_outw (LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU);
+
+               /* wait for MMU getting ready (low) */
+               while (SMC_inw (LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY) {
+                       udelay (10);
+               }
+
+               PRINTK2 ("MMU ready\n");
+       }
+
+       return length;
+}
+
+/*-------------------------------------------------------------------------
+ * smc_destructor( struct net_device * dev )
+ *   Input parameters:
+ *     dev, pointer to the device structure
+ *
+ *   Output:
+ *     None.
+ *--------------------------------------------------------------------------
+ */
+void smc_destructor ()
+{
+       PRINTK2 (CARDNAME ":smc_destructor\n");
+}
+
+
+/*
+ * Open and Initialize the board
+ *
+ * Set up everything, reset the card, etc ..
+ *
+ */
+static int smc_open (bd_t *bd)
+{
+       int i, err;                     /* used to set hw ethernet address */
+
+       PRINTK2 ("%s:smc_open\n", SMC_DEV_NAME);
+
+       /* reset the hardware */
+
+       smc_reset ();
+       smc_enable ();
+
+       SMC_SELECT_BANK (1);
+
+       err = smc_get_ethaddr (bd);     /* set smc_mac_addr, and sync it with u-boot globals */
+       if (err < 0) {
+               memset (bd->bi_enetaddr, 0, 6); /* hack to make error stick! upper code will abort if not set */
+               return (-1);    /* upper code ignores this, but NOT bi_enetaddr */
+       }
+#ifdef USE_32_BIT
+       for (i = 0; i < 6; i += 2) {
+               word address;
+
+               address = smc_mac_addr[i + 1] << 8;
+               address |= smc_mac_addr[i];
+               SMC_outw (address, LAN91C96_IA0 + i);
+       }
+#else
+       for (i = 0; i < 6; i++)
+               SMC_outb (smc_mac_addr[i], LAN91C96_IA0 + i);
+#endif
+       return 0;
+}
+
+/*-------------------------------------------------------------
+ *
+ * smc_rcv -  receive a packet from the card
+ *
+ * There is ( at least ) a packet waiting to be read from
+ * chip-memory.
+ *
+ * o Read the status
+ * o If an error, record it
+ * o otherwise, read in the packet
+ *-------------------------------------------------------------
+ */
+static int smc_rcv ()
+{
+       int packet_number;
+       word status;
+       word packet_length;
+       int is_error = 0;
+
+#ifdef USE_32_BIT
+       dword stat_len;
+#endif
+
+
+       SMC_SELECT_BANK (2);
+       packet_number = SMC_inw (LAN91C96_FIFO);
+
+       if (packet_number & LAN91C96_FIFO_RXEMPTY) {
+               return 0;
+       }
+
+       PRINTK3 ("%s:smc_rcv\n", SMC_DEV_NAME);
+       /*  start reading from the start of the packet */
+       SMC_outw (LAN91C96_PTR_READ | LAN91C96_PTR_RCV |
+                         LAN91C96_PTR_AUTO_INCR, LAN91C96_POINTER);
+
+       /* First two words are status and packet_length */
+#ifdef USE_32_BIT
+       stat_len = SMC_inl (LAN91C96_DATA_HIGH);
+       status = stat_len & 0xffff;
+       packet_length = stat_len >> 16;
+#else
+       status = SMC_inw (LAN91C96_DATA_HIGH);
+       packet_length = SMC_inw (LAN91C96_DATA_HIGH);
+#endif
+
+       packet_length &= 0x07ff;        /* mask off top bits */
+
+       PRINTK2 ("RCV: STATUS %4x LENGTH %4x\n", status, packet_length);
+
+       if (!(status & FRAME_FILTER)) {
+               /* Adjust for having already read the first two words */
+               packet_length -= 4;             /*4; */
+
+
+               /* set odd length for bug in LAN91C111, */
+               /* which never sets RS_ODDFRAME */
+               /* TODO ? */
+
+
+#ifdef USE_32_BIT
+               PRINTK3 (" Reading %d dwords (and %d bytes) \n",
+                        packet_length >> 2, packet_length & 3);
+               /* QUESTION:  Like in the TX routine, do I want
+                  to send the DWORDs or the bytes first, or some
+                  mixture.  A mixture might improve already slow PIO
+                  performance  */
+               SMC_insl (LAN91C96_DATA_HIGH, NetRxPackets[0], packet_length >> 2);
+               /* read the left over bytes */
+               if (packet_length & 3) {
+                       int i;
+
+                       byte *tail = (byte *) (NetRxPackets[0] + (packet_length & ~3));
+                       dword leftover = SMC_inl (LAN91C96_DATA_HIGH);
+
+                       for (i = 0; i < (packet_length & 3); i++)
+                               *tail++ = (byte) (leftover >> (8 * i)) & 0xff;
+               }
+#else
+               PRINTK3 (" Reading %d words and %d byte(s) \n",
+                                (packet_length >> 1), packet_length & 1);
+               SMC_insw (LAN91C96_DATA_HIGH, NetRxPackets[0], packet_length >> 1);
+
+#endif /* USE_32_BIT */
+
+#if    SMC_DEBUG > 2
+               printf ("Receiving Packet\n");
+               print_packet (NetRxPackets[0], packet_length);
+#endif
+       } else {
+               /* error ... */
+               /* TODO ? */
+               is_error = 1;
+       }
+
+       while (SMC_inw (LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
+               udelay (1);             /* Wait until not busy */
+
+       /*  error or good, tell the card to get rid of this packet */
+       SMC_outw (LAN91C96_MMUCR_RELEASE_RX, LAN91C96_MMU);
+
+       while (SMC_inw (LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
+               udelay (1);             /* Wait until not busy */
+
+       if (!is_error) {
+               /* Pass the packet up to the protocol layers. */
+               NetReceive (NetRxPackets[0], packet_length);
+               return packet_length;
+       } else {
+               return 0;
+       }
+
+}
+
+/*----------------------------------------------------
+ * smc_close
+ *
+ * this makes the board clean up everything that it can
+ * and not talk to the outside world.   Caused by
+ * an 'ifconfig ethX down'
+ *
+ -----------------------------------------------------*/
+static int smc_close ()
+{
+       PRINTK2 ("%s:smc_close\n", SMC_DEV_NAME);
+
+       /* clear everything */
+       smc_shutdown ();
+
+       return 0;
+}
+
+#if SMC_DEBUG > 2
+static void print_packet (byte * buf, int length)
+{
+#if 0
+       int i;
+       int remainder;
+       int lines;
+
+       printf ("Packet of length %d \n", length);
+
+       lines = length / 16;
+       remainder = length % 16;
+
+       for (i = 0; i < lines; i++) {
+               int cur;
+
+               for (cur = 0; cur < 8; cur++) {
+                       byte a, b;
+
+                       a = *(buf++);
+                       b = *(buf++);
+                       printf ("%02x%02x ", a, b);
+               }
+               printf ("\n");
+       }
+       for (i = 0; i < remainder / 2; i++) {
+               byte a, b;
+
+               a = *(buf++);
+               b = *(buf++);
+               printf ("%02x%02x ", a, b);
+       }
+       printf ("\n");
+#endif /* 0 */
+}
+#endif /* SMC_DEBUG > 2 */
+
+int eth_init (bd_t * bd)
+{
+       return (smc_open(bd));
+}
+
+void eth_halt ()
+{
+       smc_close ();
+}
+
+int eth_rx ()
+{
+       return smc_rcv ();
+}
+
+int eth_send (volatile void *packet, int length)
+{
+       return smc_send_packet (packet, length);
+}
+
+
+#if 0
+/*-------------------------------------------------------------------------
+ * smc_hw_init()
+ *
+ *   Function:
+ *      Reset and enable the device, check if the I/O space location
+ *      is correct
+ *
+ *   Input parameters:
+ *      None
+ *
+ *   Output:
+ *     0 --> success
+ *     1 --> error
+ *--------------------------------------------------------------------------
+ */
+static int smc_hw_init ()
+{
+       unsigned short status_test;
+
+       /* The attribute register of the LAN91C96 is located at address
+          0x0e000000 on the lubbock platform */
+       volatile unsigned *attaddr = (unsigned *) (0x0e000000);
+
+       /* first reset, then enable the device. Sequence is critical */
+       attaddr[LAN91C96_ECOR] |= LAN91C96_ECOR_SRESET;
+       udelay (100);
+       attaddr[LAN91C96_ECOR] &= ~LAN91C96_ECOR_SRESET;
+       attaddr[LAN91C96_ECOR] |= LAN91C96_ECOR_ENABLE;
+
+       /* force 16-bit mode */
+       attaddr[LAN91C96_ECSR] &= ~LAN91C96_ECSR_IOIS8;
+       udelay (100);
+
+       /* check if the I/O address is correct, the upper byte of the
+          bank select register should read 0x33 */
+
+       status_test = SMC_inw (LAN91C96_BANK_SELECT);
+       if ((status_test & 0xFF00) != 0x3300) {
+               printf ("Failed to initialize ethernetchip\n");
+               return 1;
+       }
+       return 0;
+}
+#endif /* 0 */
+
+#endif /* COMMANDS & CFG_NET */
+
+
+/* smc_get_ethaddr (bd_t * bd)
+ *
+ * This checks both the environment and the ROM for an ethernet address. If
+ * found, the environment takes precedence.
+ */
+
+int smc_get_ethaddr (bd_t * bd)
+{
+       int env_size = 0;
+       int rom_valid = 0;
+       int env_present = 0;
+       int reg = 0;
+       char *s = NULL;
+       char *e = NULL;
+       char *v_mac, es[] = "11:22:33:44:55:66";
+       char s_env_mac[64];
+       uchar v_env_mac[6];
+       uchar v_rom_mac[6];
+
+       env_size = getenv_r ("ethaddr", s_env_mac, sizeof (s_env_mac));
+       if (env_size != sizeof(es)) {   /* Ignore if env is bad or not set */
+               printf ("\n*** Warning: ethaddr is not set properly, ignoring!!\n");
+       } else {
+               env_present = 1;
+               s = s_env_mac;
+
+               for (reg = 0; reg < 6; ++reg) { /* turn string into mac value */
+                       v_env_mac[reg] = s ? simple_strtoul (s, &e, 16) : 0;
+                       if (s)
+                               s = (*e) ? e + 1 : e;
+               }
+       }
+
+       rom_valid = get_rom_mac (v_rom_mac);    /* get ROM mac value if any */
+
+       if (!env_present) {     /* if NO env */
+               if (rom_valid) {        /* but ROM is valid */
+                       v_mac = (char *)v_rom_mac;
+                       sprintf (s_env_mac, "%02X:%02X:%02X:%02X:%02X:%02X",
+                                v_mac[0], v_mac[1], v_mac[2], v_mac[3],
+                                v_mac[4], v_mac[5]);
+                       setenv ("ethaddr", s_env_mac);
+               } else {        /* no env, bad ROM */
+                       printf ("\n*** ERROR: ethaddr is NOT set !!\n");
+                       return (-1);
+               }
+       } else {                /* good env, don't care ROM */
+               v_mac = (char *)v_env_mac;      /* always use a good env over a ROM */
+       }
+
+       if (env_present && rom_valid) { /* if both env and ROM are good */
+               if (memcmp (v_env_mac, v_rom_mac, 6) != 0) {
+                       printf ("\nWarning: MAC addresses don't match:\n");
+                       printf ("\tHW MAC address:  "
+                               "%02X:%02X:%02X:%02X:%02X:%02X\n",
+                               v_rom_mac[0], v_rom_mac[1],
+                               v_rom_mac[2], v_rom_mac[3],
+                               v_rom_mac[4], v_rom_mac[5] );
+                       printf ("\t\"ethaddr\" value: "
+                               "%02X:%02X:%02X:%02X:%02X:%02X\n",
+                               v_env_mac[0], v_env_mac[1],
+                               v_env_mac[2], v_env_mac[3],
+                               v_env_mac[4], v_env_mac[5]) ;
+                       debug ("### Set MAC addr from environment\n");
+               }
+       }
+       memcpy (bd->bi_enetaddr, v_mac, 6);     /* update global address to match env (allows env changing) */
+       smc_set_mac_addr ((unsigned char *)v_mac); /* use old function to update smc default */
+       PRINTK("Using MAC Address %02X:%02X:%02X:%02X:%02X:%02X\n", v_mac[0], v_mac[1],
+               v_mac[2], v_mac[3], v_mac[4], v_mac[5]);
+       return (0);
+}
+
+/*
+ * get_rom_mac()
+ * Note, this has omly been tested for the OMAP730 P2.
+ */
+
+int get_rom_mac (unsigned char *v_rom_mac)
+{
+#ifdef HARDCODE_MAC    /* used for testing or to supress run time warnings */
+       char hw_mac_addr[] = { 0x02, 0x80, 0xad, 0x20, 0x31, 0xb8 };
+
+       memcpy (v_rom_mac, hw_mac_addr, 6);
+       return (1);
+#else
+       int i;
+       SMC_SELECT_BANK (1);
+       for (i=0; i<6; i++)
+       {
+               v_rom_mac[i] = SMC_inb (LAN91C96_IA0 + i);
+       }
+       return (1);
+#endif
+}
+
+#endif /* CONFIG_DRIVER_LAN91C96 */
diff --git a/drivers/net/lan91c96.h b/drivers/net/lan91c96.h
new file mode 100644 (file)
index 0000000..7d33a82
--- /dev/null
@@ -0,0 +1,643 @@
+/*------------------------------------------------------------------------
+ * lan91c96.h
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Rolf Offermanns <rof@sysgo.de>
+ * Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
+ *       Developed by Simple Network Magic Corporation (SNMC)
+ * Copyright (C) 1996 by Erik Stahlman (ES)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * This file contains register information and access macros for
+ * the LAN91C96 single chip ethernet controller.  It is a modified
+ * version of the smc9111.h file.
+ *
+ * Information contained in this file was obtained from the LAN91C96
+ * manual from SMC. To get a copy, if you really want one, you can find
+ * information under www.smsc.com.
+ *
+ * Authors
+ *     Erik Stahlman                           ( erik@vt.edu )
+ *     Daris A Nevil                           ( dnevil@snmc.com )
+ *
+ * History
+ * 04/30/03    Mathijs Haarman         Modified smc91111.h (u-boot version)
+ *                                     for lan91c96
+ *-------------------------------------------------------------------------
+ */
+#ifndef _LAN91C96_H_
+#define _LAN91C96_H_
+
+#include <asm/types.h>
+#include <asm/io.h>
+#include <config.h>
+
+/*
+ * This function may be called by the board specific initialisation code
+ * in order to override the default mac address.
+ */
+
+void smc_set_mac_addr(const unsigned char *addr);
+
+
+/* I want some simple types */
+
+typedef unsigned char                  byte;
+typedef unsigned short                 word;
+typedef unsigned long int              dword;
+
+/*
+ * DEBUGGING LEVELS
+ *
+ * 0 for normal operation
+ * 1 for slightly more details
+ * >2 for various levels of increasingly useless information
+ *    2 for interrupt tracking, status flags
+ *    3 for packet info
+ *    4 for complete packet dumps
+ */
+/*#define SMC_DEBUG 0 */
+
+/* Because of bank switching, the LAN91xxx uses only 16 I/O ports */
+
+#define        SMC_IO_EXTENT   16
+
+#ifdef CONFIG_PXA250
+
+#ifdef CONFIG_LUBBOCK
+#define        SMC_IO_SHIFT    2
+#undef USE_32_BIT
+
+#else
+#define        SMC_IO_SHIFT    0
+#endif
+
+#define        SMCREG(r)       (SMC_BASE_ADDRESS+((r)<<SMC_IO_SHIFT))
+
+#define        SMC_inl(r)      (*((volatile dword *)SMCREG(r)))
+#define        SMC_inw(r)      (*((volatile word *)SMCREG(r)))
+#define SMC_inb(p) ({ \
+       unsigned int __p = p; \
+       unsigned int __v = SMC_inw(__p & ~1); \
+       if (__p & 1) __v >>= 8; \
+       else __v &= 0xff; \
+       __v; })
+
+#define        SMC_outl(d,r)   (*((volatile dword *)SMCREG(r)) = d)
+#define        SMC_outw(d,r)   (*((volatile word *)SMCREG(r)) = d)
+#define        SMC_outb(d,r)   ({      word __d = (byte)(d);  \
+                               word __w = SMC_inw((r)&~1);  \
+                               __w &= ((r)&1) ? 0x00FF : 0xFF00;  \
+                               __w |= ((r)&1) ? __d<<8 : __d;  \
+                               SMC_outw(__w,(r)&~1);  \
+                       })
+
+#define SMC_outsl(r,b,l)       ({      int __i; \
+                                       dword *__b2; \
+                                       __b2 = (dword *) b; \
+                                       for (__i = 0; __i < l; __i++) { \
+                                           SMC_outl( *(__b2 + __i), r ); \
+                                       } \
+                               })
+
+#define SMC_outsw(r,b,l)       ({      int __i; \
+                                       word *__b2; \
+                                       __b2 = (word *) b; \
+                                       for (__i = 0; __i < l; __i++) { \
+                                           SMC_outw( *(__b2 + __i), r ); \
+                                       } \
+                               })
+
+#define SMC_insl(r,b,l)        ({      int __i ;  \
+                                       dword *__b2;  \
+                                       __b2 = (dword *) b;  \
+                                       for (__i = 0; __i < l; __i++) {  \
+                                         *(__b2 + __i) = SMC_inl(r);  \
+                                         SMC_inl(0);  \
+                                       };  \
+                               })
+
+#define SMC_insw(r,b,l)        ({      int __i ;  \
+                                       word *__b2;  \
+                                       __b2 = (word *) b;  \
+                                       for (__i = 0; __i < l; __i++) {  \
+                                         *(__b2 + __i) = SMC_inw(r);  \
+                                         SMC_inw(0);  \
+                                       };  \
+                               })
+
+#define SMC_insb(r,b,l)        ({      int __i ;  \
+                                       byte *__b2;  \
+                                       __b2 = (byte *) b;  \
+                                       for (__i = 0; __i < l; __i++) {  \
+                                         *(__b2 + __i) = SMC_inb(r);  \
+                                         SMC_inb(0);  \
+                                       };  \
+                               })
+
+#else /* if not CONFIG_PXA250 */
+
+/*
+ * We have only 16 Bit PCMCIA access on Socket 0
+ */
+
+#define        SMC_inw(r)      (*((volatile word *)(SMC_BASE_ADDRESS+(r))))
+#define  SMC_inb(r)    (((r)&1) ? SMC_inw((r)&~1)>>8 : SMC_inw(r)&0xFF)
+
+#define        SMC_outw(d,r)   (*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d)
+#define        SMC_outb(d,r)   ({      word __d = (byte)(d);  \
+                               word __w = SMC_inw((r)&~1);  \
+                               __w &= ((r)&1) ? 0x00FF : 0xFF00;  \
+                               __w |= ((r)&1) ? __d<<8 : __d;  \
+                               SMC_outw(__w,(r)&~1);  \
+                       })
+#if 0
+#define        SMC_outsw(r,b,l)        outsw(SMC_BASE_ADDRESS+(r), (b), (l))
+#else
+#define SMC_outsw(r,b,l)       ({      int __i; \
+                                       word *__b2; \
+                                       __b2 = (word *) b; \
+                                       for (__i = 0; __i < l; __i++) { \
+                                           SMC_outw( *(__b2 + __i), r); \
+                                       } \
+                               })
+#endif
+
+#if 0
+#define        SMC_insw(r,b,l)         insw(SMC_BASE_ADDRESS+(r), (b), (l))
+#else
+#define SMC_insw(r,b,l)        ({      int __i ;  \
+                                       word *__b2;  \
+                                       __b2 = (word *) b;  \
+                                       for (__i = 0; __i < l; __i++) {  \
+                                         *(__b2 + __i) = SMC_inw(r);  \
+                                         SMC_inw(0);  \
+                                       };  \
+                               })
+#endif
+
+#endif
+
+/*
+ ****************************************************************************
+ *     Bank Select Field
+ ****************************************************************************
+ */
+#define LAN91C96_BANK_SELECT  14       /* Bank Select Register */
+#define LAN91C96_BANKSELECT (0x3UC << 0)
+#define BANK0               0x00
+#define BANK1               0x01
+#define BANK2               0x02
+#define BANK3               0x03
+#define BANK4               0x04
+
+/*
+ ****************************************************************************
+ *     EEPROM Addresses.
+ ****************************************************************************
+ */
+#define EEPROM_MAC_OFFSET_1    0x6020
+#define EEPROM_MAC_OFFSET_2    0x6021
+#define EEPROM_MAC_OFFSET_3    0x6022
+
+/*
+ ****************************************************************************
+ *     Bank 0 Register Map in I/O Space
+ ****************************************************************************
+ */
+#define LAN91C96_TCR          0        /* Transmit Control Register */
+#define LAN91C96_EPH_STATUS   2        /* EPH Status Register */
+#define LAN91C96_RCR          4        /* Receive Control Register */
+#define LAN91C96_COUNTER      6        /* Counter Register */
+#define LAN91C96_MIR          8        /* Memory Information Register */
+#define LAN91C96_MCR          10       /* Memory Configuration Register */
+
+/*
+ ****************************************************************************
+ *     Transmit Control Register - Bank 0 - Offset 0
+ ****************************************************************************
+ */
+#define LAN91C96_TCR_TXENA        (0x1U << 0)
+#define LAN91C96_TCR_LOOP         (0x1U << 1)
+#define LAN91C96_TCR_FORCOL       (0x1U << 2)
+#define LAN91C96_TCR_TXP_EN       (0x1U << 3)
+#define LAN91C96_TCR_PAD_EN       (0x1U << 7)
+#define LAN91C96_TCR_NOCRC        (0x1U << 8)
+#define LAN91C96_TCR_MON_CSN      (0x1U << 10)
+#define LAN91C96_TCR_FDUPLX       (0x1U << 11)
+#define LAN91C96_TCR_STP_SQET     (0x1U << 12)
+#define LAN91C96_TCR_EPH_LOOP     (0x1U << 13)
+#define LAN91C96_TCR_ETEN_TYPE    (0x1U << 14)
+#define LAN91C96_TCR_FDSE         (0x1U << 15)
+
+/*
+ ****************************************************************************
+ *     EPH Status Register - Bank 0 - Offset 2
+ ****************************************************************************
+ */
+#define LAN91C96_EPHSR_TX_SUC     (0x1U << 0)
+#define LAN91C96_EPHSR_SNGL_COL   (0x1U << 1)
+#define LAN91C96_EPHSR_MUL_COL    (0x1U << 2)
+#define LAN91C96_EPHSR_LTX_MULT   (0x1U << 3)
+#define LAN91C96_EPHSR_16COL      (0x1U << 4)
+#define LAN91C96_EPHSR_SQET       (0x1U << 5)
+#define LAN91C96_EPHSR_LTX_BRD    (0x1U << 6)
+#define LAN91C96_EPHSR_TX_DEFR    (0x1U << 7)
+#define LAN91C96_EPHSR_WAKEUP     (0x1U << 8)
+#define LAN91C96_EPHSR_LATCOL     (0x1U << 9)
+#define LAN91C96_EPHSR_LOST_CARR  (0x1U << 10)
+#define LAN91C96_EPHSR_EXC_DEF    (0x1U << 11)
+#define LAN91C96_EPHSR_CTR_ROL    (0x1U << 12)
+
+#define LAN91C96_EPHSR_LINK_OK    (0x1U << 14)
+#define LAN91C96_EPHSR_TX_UNRN    (0x1U << 15)
+
+#define LAN91C96_EPHSR_ERRORS     (LAN91C96_EPHSR_SNGL_COL  |    \
+                                  LAN91C96_EPHSR_MUL_COL   |    \
+                                  LAN91C96_EPHSR_16COL     |    \
+                                  LAN91C96_EPHSR_SQET      |    \
+                                  LAN91C96_EPHSR_TX_DEFR   |    \
+                                  LAN91C96_EPHSR_LATCOL    |    \
+                                  LAN91C96_EPHSR_LOST_CARR |    \
+                                  LAN91C96_EPHSR_EXC_DEF   |    \
+                                  LAN91C96_EPHSR_LINK_OK   |    \
+                                  LAN91C96_EPHSR_TX_UNRN)
+
+/*
+ ****************************************************************************
+ *     Receive Control Register - Bank 0 - Offset 4
+ ****************************************************************************
+ */
+#define LAN91C96_RCR_RX_ABORT     (0x1U << 0)
+#define LAN91C96_RCR_PRMS         (0x1U << 1)
+#define LAN91C96_RCR_ALMUL        (0x1U << 2)
+#define LAN91C96_RCR_RXEN         (0x1U << 8)
+#define LAN91C96_RCR_STRIP_CRC    (0x1U << 9)
+#define LAN91C96_RCR_FILT_CAR     (0x1U << 14)
+#define LAN91C96_RCR_SOFT_RST     (0x1U << 15)
+
+/*
+ ****************************************************************************
+ *     Counter Register - Bank 0 - Offset 6
+ ****************************************************************************
+ */
+#define LAN91C96_ECR_SNGL_COL     (0xFU << 0)
+#define LAN91C96_ECR_MULT_COL     (0xFU << 5)
+#define LAN91C96_ECR_DEF_TX       (0xFU << 8)
+#define LAN91C96_ECR_EXC_DEF_TX   (0xFU << 12)
+
+/*
+ ****************************************************************************
+ *     Memory Information Register - Bank 0 - OFfset 8
+ ****************************************************************************
+ */
+#define LAN91C96_MIR_SIZE        (0x18 << 0)    /* 6144 bytes */
+
+/*
+ ****************************************************************************
+ *     Memory Configuration Register - Bank 0 - Offset 10
+ ****************************************************************************
+ */
+#define LAN91C96_MCR_MEM_RES      (0xFFU << 0)
+#define LAN91C96_MCR_MEM_MULT     (0x3U << 9)
+#define LAN91C96_MCR_HIGH_ID      (0x3U << 12)
+
+#define LAN91C96_MCR_TRANSMIT_PAGES 0x6
+
+/*
+ ****************************************************************************
+ *     Bank 1 Register Map in I/O Space
+ ****************************************************************************
+ */
+#define LAN91C96_CONFIG       0        /* Configuration Register */
+#define LAN91C96_BASE         2        /* Base Address Register */
+#define LAN91C96_IA0          4        /* Individual Address Register - 0 */
+#define LAN91C96_IA1          5        /* Individual Address Register - 1 */
+#define LAN91C96_IA2          6        /* Individual Address Register - 2 */
+#define LAN91C96_IA3          7        /* Individual Address Register - 3 */
+#define LAN91C96_IA4          8        /* Individual Address Register - 4 */
+#define LAN91C96_IA5          9        /* Individual Address Register - 5 */
+#define LAN91C96_GEN_PURPOSE  10       /* General Address Registers */
+#define LAN91C96_CONTROL      12       /* Control Register */
+
+/*
+ ****************************************************************************
+ *     Configuration Register - Bank 1 - Offset 0
+ ****************************************************************************
+ */
+#define LAN91C96_CR_INT_SEL0      (0x1U << 1)
+#define LAN91C96_CR_INT_SEL1      (0x1U << 2)
+#define LAN91C96_CR_RES           (0x3U << 3)
+#define LAN91C96_CR_DIS_LINK      (0x1U << 6)
+#define LAN91C96_CR_16BIT         (0x1U << 7)
+#define LAN91C96_CR_AUI_SELECT    (0x1U << 8)
+#define LAN91C96_CR_SET_SQLCH     (0x1U << 9)
+#define LAN91C96_CR_FULL_STEP     (0x1U << 10)
+#define LAN91C96_CR_NO_WAIT       (0x1U << 12)
+
+/*
+ ****************************************************************************
+ *     Base Address Register - Bank 1 - Offset 2
+ ****************************************************************************
+ */
+#define LAN91C96_BAR_RA_BITS      (0x27U << 0)
+#define LAN91C96_BAR_ROM_SIZE     (0x1U << 6)
+#define LAN91C96_BAR_A_BITS       (0xFFU << 8)
+
+/*
+ ****************************************************************************
+ *     Control Register - Bank 1 - Offset 12
+ ****************************************************************************
+ */
+#define LAN91C96_CTR_STORE        (0x1U << 0)
+#define LAN91C96_CTR_RELOAD       (0x1U << 1)
+#define LAN91C96_CTR_EEPROM       (0x1U << 2)
+#define LAN91C96_CTR_TE_ENABLE    (0x1U << 5)
+#define LAN91C96_CTR_CR_ENABLE    (0x1U << 6)
+#define LAN91C96_CTR_LE_ENABLE    (0x1U << 7)
+#define LAN91C96_CTR_BIT_8        (0x1U << 8)
+#define LAN91C96_CTR_AUTO_RELEASE (0x1U << 11)
+#define LAN91C96_CTR_WAKEUP_EN    (0x1U << 12)
+#define LAN91C96_CTR_PWRDN        (0x1U << 13)
+#define LAN91C96_CTR_RCV_BAD      (0x1U << 14)
+
+/*
+ ****************************************************************************
+ *     Bank 2 Register Map in I/O Space
+ ****************************************************************************
+ */
+#define LAN91C96_MMU            0      /* MMU Command Register */
+#define LAN91C96_AUTO_TX_START  1      /* Auto Tx Start Register */
+#define LAN91C96_PNR            2      /* Packet Number Register */
+#define LAN91C96_ARR            3      /* Allocation Result Register */
+#define LAN91C96_FIFO           4      /* FIFO Ports Register */
+#define LAN91C96_POINTER        6      /* Pointer Register */
+#define LAN91C96_DATA_HIGH      8      /* Data High Register */
+#define LAN91C96_DATA_LOW       10     /* Data Low Register */
+#define LAN91C96_INT_STATS      12     /* Interrupt Status Register - RO */
+#define LAN91C96_INT_ACK        12     /* Interrupt Acknowledge Register -WO */
+#define LAN91C96_INT_MASK       13     /* Interrupt Mask Register */
+
+/*
+ ****************************************************************************
+ *     MMU Command Register - Bank 2 - Offset 0
+ ****************************************************************************
+ */
+#define LAN91C96_MMUCR_NO_BUSY    (0x1U << 0)
+#define LAN91C96_MMUCR_N1         (0x1U << 1)
+#define LAN91C96_MMUCR_N2         (0x1U << 2)
+#define LAN91C96_MMUCR_COMMAND    (0xFU << 4)
+#define LAN91C96_MMUCR_ALLOC_TX   (0x2U << 4)    /* WXYZ = 0010 */
+#define LAN91C96_MMUCR_RESET_MMU  (0x4U << 4)    /* WXYZ = 0100 */
+#define LAN91C96_MMUCR_REMOVE_RX  (0x6U << 4)    /* WXYZ = 0110 */
+#define LAN91C96_MMUCR_REMOVE_TX  (0x7U << 4)    /* WXYZ = 0111 */
+#define LAN91C96_MMUCR_RELEASE_RX (0x8U << 4)    /* WXYZ = 1000 */
+#define LAN91C96_MMUCR_RELEASE_TX (0xAU << 4)    /* WXYZ = 1010 */
+#define LAN91C96_MMUCR_ENQUEUE    (0xCU << 4)    /* WXYZ = 1100 */
+#define LAN91C96_MMUCR_RESET_TX   (0xEU << 4)    /* WXYZ = 1110 */
+
+/*
+ ****************************************************************************
+ *     Auto Tx Start Register - Bank 2 - Offset 1
+ ****************************************************************************
+ */
+#define LAN91C96_AUTOTX           (0xFFU << 0)
+
+/*
+ ****************************************************************************
+ *     Packet Number Register - Bank 2 - Offset 2
+ ****************************************************************************
+ */
+#define LAN91C96_PNR_TX           (0x1FU << 0)
+
+/*
+ ****************************************************************************
+ *     Allocation Result Register - Bank 2 - Offset 3
+ ****************************************************************************
+ */
+#define LAN91C96_ARR_ALLOC_PN     (0x7FU << 0)
+#define LAN91C96_ARR_FAILED       (0x1U << 7)
+
+/*
+ ****************************************************************************
+ *     FIFO Ports Register - Bank 2 - Offset 4
+ ****************************************************************************
+ */
+#define LAN91C96_FIFO_TX_DONE_PN  (0x1FU << 0)
+#define LAN91C96_FIFO_TEMPTY      (0x1U << 7)
+#define LAN91C96_FIFO_RX_DONE_PN  (0x1FU << 8)
+#define LAN91C96_FIFO_RXEMPTY     (0x1U << 15)
+
+/*
+ ****************************************************************************
+ *     Pointer Register - Bank 2 - Offset 6
+ ****************************************************************************
+ */
+#define LAN91C96_PTR_LOW          (0xFFU << 0)
+#define LAN91C96_PTR_HIGH         (0x7U << 8)
+#define LAN91C96_PTR_AUTO_TX      (0x1U << 11)
+#define LAN91C96_PTR_ETEN         (0x1U << 12)
+#define LAN91C96_PTR_READ         (0x1U << 13)
+#define LAN91C96_PTR_AUTO_INCR    (0x1U << 14)
+#define LAN91C96_PTR_RCV          (0x1U << 15)
+
+#define LAN91C96_PTR_RX_FRAME     (LAN91C96_PTR_RCV       |    \
+                                  LAN91C96_PTR_AUTO_INCR |    \
+                                  LAN91C96_PTR_READ)
+
+/*
+ ****************************************************************************
+ *     Data Register - Bank 2 - Offset 8
+ ****************************************************************************
+ */
+#define LAN91C96_CONTROL_CRC      (0x1U << 4)    /* CRC bit */
+#define LAN91C96_CONTROL_ODD      (0x1U << 5)    /* ODD bit */
+
+/*
+ ****************************************************************************
+ *     Interrupt Status Register - Bank 2 - Offset 12
+ ****************************************************************************
+ */
+#define LAN91C96_IST_RCV_INT      (0x1U << 0)
+#define LAN91C96_IST_TX_INT       (0x1U << 1)
+#define LAN91C96_IST_TX_EMPTY_INT (0x1U << 2)
+#define LAN91C96_IST_ALLOC_INT    (0x1U << 3)
+#define LAN91C96_IST_RX_OVRN_INT  (0x1U << 4)
+#define LAN91C96_IST_EPH_INT      (0x1U << 5)
+#define LAN91C96_IST_ERCV_INT     (0x1U << 6)
+#define LAN91C96_IST_RX_IDLE_INT  (0x1U << 7)
+
+/*
+ ****************************************************************************
+ *     Interrupt Acknowledge Register - Bank 2 - Offset 12
+ ****************************************************************************
+ */
+#define LAN91C96_ACK_TX_INT       (0x1U << 1)
+#define LAN91C96_ACK_TX_EMPTY_INT (0x1U << 2)
+#define LAN91C96_ACK_RX_OVRN_INT  (0x1U << 4)
+#define LAN91C96_ACK_ERCV_INT     (0x1U << 6)
+
+/*
+ ****************************************************************************
+ *     Interrupt Mask Register - Bank 2 - Offset 13
+ ****************************************************************************
+ */
+#define LAN91C96_MSK_RCV_INT      (0x1U << 0)
+#define LAN91C96_MSK_TX_INT       (0x1U << 1)
+#define LAN91C96_MSK_TX_EMPTY_INT (0x1U << 2)
+#define LAN91C96_MSK_ALLOC_INT    (0x1U << 3)
+#define LAN91C96_MSK_RX_OVRN_INT  (0x1U << 4)
+#define LAN91C96_MSK_EPH_INT      (0x1U << 5)
+#define LAN91C96_MSK_ERCV_INT     (0x1U << 6)
+#define LAN91C96_MSK_TX_IDLE_INT  (0x1U << 7)
+
+/*
+ ****************************************************************************
+ *     Bank 3 Register Map in I/O Space
+ **************************************************************************
+ */
+#define LAN91C96_MGMT_MDO         (0x1U << 0)
+#define LAN91C96_MGMT_MDI         (0x1U << 1)
+#define LAN91C96_MGMT_MCLK        (0x1U << 2)
+#define LAN91C96_MGMT_MDOE        (0x1U << 3)
+#define LAN91C96_MGMT_LOW_ID      (0x3U << 4)
+#define LAN91C96_MGMT_IOS0        (0x1U << 8)
+#define LAN91C96_MGMT_IOS1        (0x1U << 9)
+#define LAN91C96_MGMT_IOS2        (0x1U << 10)
+#define LAN91C96_MGMT_nXNDEC      (0x1U << 11)
+#define LAN91C96_MGMT_HIGH_ID     (0x3U << 12)
+
+/*
+ ****************************************************************************
+ *     Revision Register - Bank 3 - Offset 10
+ ****************************************************************************
+ */
+#define LAN91C96_REV_REVID        (0xFU << 0)
+#define LAN91C96_REV_CHIPID       (0xFU << 4)
+
+/*
+ ****************************************************************************
+ *     Early RCV Register - Bank 3 - Offset 12
+ ****************************************************************************
+ */
+#define LAN91C96_ERCV_THRESHOLD   (0x1FU << 0)
+#define LAN91C96_ERCV_RCV_DISCRD  (0x1U << 7)
+
+/*
+ ****************************************************************************
+ *     PCMCIA Configuration Registers
+ ****************************************************************************
+ */
+#define LAN91C96_ECOR    0x8000        /* Ethernet Configuration Register */
+#define LAN91C96_ECSR    0x8002        /* Ethernet Configuration and Status */
+
+/*
+ ****************************************************************************
+ *     PCMCIA Ethernet Configuration Option Register (ECOR)
+ ****************************************************************************
+ */
+#define LAN91C96_ECOR_ENABLE       (0x1U << 0)
+#define LAN91C96_ECOR_WR_ATTRIB    (0x1U << 2)
+#define LAN91C96_ECOR_LEVEL_REQ    (0x1U << 6)
+#define LAN91C96_ECOR_SRESET       (0x1U << 7)
+
+/*
+ ****************************************************************************
+ *     PCMCIA Ethernet Configuration and Status Register (ECSR)
+ ****************************************************************************
+ */
+#define LAN91C96_ECSR_INTR        (0x1U << 1)
+#define LAN91C96_ECSR_PWRDWN      (0x1U << 2)
+#define LAN91C96_ECSR_IOIS8       (0x1U << 5)
+
+/*
+ ****************************************************************************
+ *     Receive Frame Status Word - See page 38 of the LAN91C96 specification.
+ ****************************************************************************
+ */
+#define LAN91C96_TOO_SHORT        (0x1U << 10)
+#define LAN91C96_TOO_LONG         (0x1U << 11)
+#define LAN91C96_ODD_FRM          (0x1U << 12)
+#define LAN91C96_BAD_CRC          (0x1U << 13)
+#define LAN91C96_BROD_CAST        (0x1U << 14)
+#define LAN91C96_ALGN_ERR         (0x1U << 15)
+
+#define FRAME_FILTER              (LAN91C96_TOO_SHORT | LAN91C96_TOO_LONG  | LAN91C96_BAD_CRC   | LAN91C96_ALGN_ERR)
+
+/*
+ ****************************************************************************
+ *     Default MAC Address
+ ****************************************************************************
+ */
+#define MAC_DEF_HI  0x0800
+#define MAC_DEF_MED 0x3333
+#define MAC_DEF_LO  0x0100
+
+/*
+ ****************************************************************************
+ *     Default I/O Signature - 0x33
+ ****************************************************************************
+ */
+#define LAN91C96_LOW_SIGNATURE        (0x33U << 0)
+#define LAN91C96_HIGH_SIGNATURE       (0x33U << 8)
+#define LAN91C96_SIGNATURE (LAN91C96_HIGH_SIGNATURE | LAN91C96_LOW_SIGNATURE)
+
+#define LAN91C96_MAX_PAGES     6        /* Maximum number of 256 pages. */
+#define ETHERNET_MAX_LENGTH 1514
+
+
+/*-------------------------------------------------------------------------
+ *  I define some macros to make it easier to do somewhat common
+ * or slightly complicated, repeated tasks.
+ *-------------------------------------------------------------------------
+ */
+
+/* select a register bank, 0 to 3  */
+
+#define SMC_SELECT_BANK(x)  { SMC_outw( x, LAN91C96_BANK_SELECT ); }
+
+/* this enables an interrupt in the interrupt mask register */
+#define SMC_ENABLE_INT(x) {\
+               unsigned char mask;\
+               SMC_SELECT_BANK(2);\
+               mask = SMC_inb( LAN91C96_INT_MASK );\
+               mask |= (x);\
+               SMC_outb( mask, LAN91C96_INT_MASK ); \
+}
+
+/* this disables an interrupt from the interrupt mask register */
+
+#define SMC_DISABLE_INT(x) {\
+               unsigned char mask;\
+               SMC_SELECT_BANK(2);\
+               mask = SMC_inb( LAN91C96_INT_MASK );\
+               mask &= ~(x);\
+               SMC_outb( mask, LAN91C96_INT_MASK ); \
+}
+
+/*----------------------------------------------------------------------
+ * Define the interrupts that I want to receive from the card
+ *
+ * I want:
+ *  LAN91C96_IST_EPH_INT, for nasty errors
+ *  LAN91C96_IST_RCV_INT, for happy received packets
+ *  LAN91C96_IST_RX_OVRN_INT, because I have to kick the receiver
+ *-------------------------------------------------------------------------
+ */
+#define SMC_INTERRUPT_MASK   (LAN91C96_IST_EPH_INT | LAN91C96_IST_RX_OVRN_INT | LAN91C96_IST_RCV_INT)
+
+#endif  /* _LAN91C96_H_ */
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
new file mode 100644 (file)
index 0000000..95cdc49
--- /dev/null
@@ -0,0 +1,587 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <common.h>
+
+#if defined(CONFIG_MACB) \
+       && (defined(CONFIG_CMD_NET) || defined(CONFIG_CMD_MII))
+
+/*
+ * The u-boot networking stack is a little weird.  It seems like the
+ * networking core allocates receive buffers up front without any
+ * regard to the hardware that's supposed to actually receive those
+ * packets.
+ *
+ * The MACB receives packets into 128-byte receive buffers, so the
+ * buffers allocated by the core isn't very practical to use.  We'll
+ * allocate our own, but we need one such buffer in case a packet
+ * wraps around the DMA ring so that we have to copy it.
+ *
+ * Therefore, define CFG_RX_ETH_BUFFER to 1 in the board-specific
+ * configuration header.  This way, the core allocates one RX buffer
+ * and one TX buffer, each of which can hold a ethernet packet of
+ * maximum size.
+ *
+ * For some reason, the networking core unconditionally specifies a
+ * 32-byte packet "alignment" (which really should be called
+ * "padding").  MACB shouldn't need that, but we'll refrain from any
+ * core modifications here...
+ */
+
+#include <net.h>
+#include <malloc.h>
+
+#include <linux/mii.h>
+#include <asm/io.h>
+#include <asm/dma-mapping.h>
+#include <asm/arch/clk.h>
+
+#include "macb.h"
+
+#define barrier() asm volatile("" ::: "memory")
+
+#define CFG_MACB_RX_BUFFER_SIZE                4096
+#define CFG_MACB_RX_RING_SIZE          (CFG_MACB_RX_BUFFER_SIZE / 128)
+#define CFG_MACB_TX_RING_SIZE          16
+#define CFG_MACB_TX_TIMEOUT            1000
+#define CFG_MACB_AUTONEG_TIMEOUT       5000000
+
+struct macb_dma_desc {
+       u32     addr;
+       u32     ctrl;
+};
+
+#define RXADDR_USED            0x00000001
+#define RXADDR_WRAP            0x00000002
+
+#define RXBUF_FRMLEN_MASK      0x00000fff
+#define RXBUF_FRAME_START      0x00004000
+#define RXBUF_FRAME_END                0x00008000
+#define RXBUF_TYPEID_MATCH     0x00400000
+#define RXBUF_ADDR4_MATCH      0x00800000
+#define RXBUF_ADDR3_MATCH      0x01000000
+#define RXBUF_ADDR2_MATCH      0x02000000
+#define RXBUF_ADDR1_MATCH      0x04000000
+#define RXBUF_BROADCAST                0x80000000
+
+#define TXBUF_FRMLEN_MASK      0x000007ff
+#define TXBUF_FRAME_END                0x00008000
+#define TXBUF_NOCRC            0x00010000
+#define TXBUF_EXHAUSTED                0x08000000
+#define TXBUF_UNDERRUN         0x10000000
+#define TXBUF_MAXRETRY         0x20000000
+#define TXBUF_WRAP             0x40000000
+#define TXBUF_USED             0x80000000
+
+struct macb_device {
+       void                    *regs;
+
+       unsigned int            rx_tail;
+       unsigned int            tx_head;
+       unsigned int            tx_tail;
+
+       void                    *rx_buffer;
+       void                    *tx_buffer;
+       struct macb_dma_desc    *rx_ring;
+       struct macb_dma_desc    *tx_ring;
+
+       unsigned long           rx_buffer_dma;
+       unsigned long           rx_ring_dma;
+       unsigned long           tx_ring_dma;
+
+       const struct device     *dev;
+       struct eth_device       netdev;
+       unsigned short          phy_addr;
+};
+#define to_macb(_nd) container_of(_nd, struct macb_device, netdev)
+
+static void macb_mdio_write(struct macb_device *macb, u8 reg, u16 value)
+{
+       unsigned long netctl;
+       unsigned long netstat;
+       unsigned long frame;
+
+       netctl = macb_readl(macb, NCR);
+       netctl |= MACB_BIT(MPE);
+       macb_writel(macb, NCR, netctl);
+
+       frame = (MACB_BF(SOF, 1)
+                | MACB_BF(RW, 1)
+                | MACB_BF(PHYA, macb->phy_addr)
+                | MACB_BF(REGA, reg)
+                | MACB_BF(CODE, 2)
+                | MACB_BF(DATA, value));
+       macb_writel(macb, MAN, frame);
+
+       do {
+               netstat = macb_readl(macb, NSR);
+       } while (!(netstat & MACB_BIT(IDLE)));
+
+       netctl = macb_readl(macb, NCR);
+       netctl &= ~MACB_BIT(MPE);
+       macb_writel(macb, NCR, netctl);
+}
+
+static u16 macb_mdio_read(struct macb_device *macb, u8 reg)
+{
+       unsigned long netctl;
+       unsigned long netstat;
+       unsigned long frame;
+
+       netctl = macb_readl(macb, NCR);
+       netctl |= MACB_BIT(MPE);
+       macb_writel(macb, NCR, netctl);
+
+       frame = (MACB_BF(SOF, 1)
+                | MACB_BF(RW, 2)
+                | MACB_BF(PHYA, macb->phy_addr)
+                | MACB_BF(REGA, reg)
+                | MACB_BF(CODE, 2));
+       macb_writel(macb, MAN, frame);
+
+       do {
+               netstat = macb_readl(macb, NSR);
+       } while (!(netstat & MACB_BIT(IDLE)));
+
+       frame = macb_readl(macb, MAN);
+
+       netctl = macb_readl(macb, NCR);
+       netctl &= ~MACB_BIT(MPE);
+       macb_writel(macb, NCR, netctl);
+
+       return MACB_BFEXT(DATA, frame);
+}
+
+#if defined(CONFIG_CMD_NET)
+
+static int macb_send(struct eth_device *netdev, volatile void *packet,
+                    int length)
+{
+       struct macb_device *macb = to_macb(netdev);
+       unsigned long paddr, ctrl;
+       unsigned int tx_head = macb->tx_head;
+       int i;
+
+       paddr = dma_map_single(packet, length, DMA_TO_DEVICE);
+
+       ctrl = length & TXBUF_FRMLEN_MASK;
+       ctrl |= TXBUF_FRAME_END;
+       if (tx_head == (CFG_MACB_TX_RING_SIZE - 1)) {
+               ctrl |= TXBUF_WRAP;
+               macb->tx_head = 0;
+       } else
+               macb->tx_head++;
+
+       macb->tx_ring[tx_head].ctrl = ctrl;
+       macb->tx_ring[tx_head].addr = paddr;
+       barrier();
+       macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));
+
+       /*
+        * I guess this is necessary because the networking core may
+        * re-use the transmit buffer as soon as we return...
+        */
+       for (i = 0; i <= CFG_MACB_TX_TIMEOUT; i++) {
+               barrier();
+               ctrl = macb->tx_ring[tx_head].ctrl;
+               if (ctrl & TXBUF_USED)
+                       break;
+               udelay(1);
+       }
+
+       dma_unmap_single(packet, length, paddr);
+
+       if (i <= CFG_MACB_TX_TIMEOUT) {
+               if (ctrl & TXBUF_UNDERRUN)
+                       printf("%s: TX underrun\n", netdev->name);
+               if (ctrl & TXBUF_EXHAUSTED)
+                       printf("%s: TX buffers exhausted in mid frame\n",
+                              netdev->name);
+       } else {
+               printf("%s: TX timeout\n", netdev->name);
+       }
+
+       /* No one cares anyway */
+       return 0;
+}
+
+static void reclaim_rx_buffers(struct macb_device *macb,
+                              unsigned int new_tail)
+{
+       unsigned int i;
+
+       i = macb->rx_tail;
+       while (i > new_tail) {
+               macb->rx_ring[i].addr &= ~RXADDR_USED;
+               i++;
+               if (i > CFG_MACB_RX_RING_SIZE)
+                       i = 0;
+       }
+
+       while (i < new_tail) {
+               macb->rx_ring[i].addr &= ~RXADDR_USED;
+               i++;
+       }
+
+       barrier();
+       macb->rx_tail = new_tail;
+}
+
+static int macb_recv(struct eth_device *netdev)
+{
+       struct macb_device *macb = to_macb(netdev);
+       unsigned int rx_tail = macb->rx_tail;
+       void *buffer;
+       int length;
+       int wrapped = 0;
+       u32 status;
+
+       for (;;) {
+               if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED))
+                       return -1;
+
+               status = macb->rx_ring[rx_tail].ctrl;
+               if (status & RXBUF_FRAME_START) {
+                       if (rx_tail != macb->rx_tail)
+                               reclaim_rx_buffers(macb, rx_tail);
+                       wrapped = 0;
+               }
+
+               if (status & RXBUF_FRAME_END) {
+                       buffer = macb->rx_buffer + 128 * macb->rx_tail;
+                       length = status & RXBUF_FRMLEN_MASK;
+                       if (wrapped) {
+                               unsigned int headlen, taillen;
+
+                               headlen = 128 * (CFG_MACB_RX_RING_SIZE
+                                                - macb->rx_tail);
+                               taillen = length - headlen;
+                               memcpy((void *)NetRxPackets[0],
+                                      buffer, headlen);
+                               memcpy((void *)NetRxPackets[0] + headlen,
+                                      macb->rx_buffer, taillen);
+                               buffer = (void *)NetRxPackets[0];
+                       }
+
+                       NetReceive(buffer, length);
+                       if (++rx_tail >= CFG_MACB_RX_RING_SIZE)
+                               rx_tail = 0;
+                       reclaim_rx_buffers(macb, rx_tail);
+               } else {
+                       if (++rx_tail >= CFG_MACB_RX_RING_SIZE) {
+                               wrapped = 1;
+                               rx_tail = 0;
+                       }
+               }
+               barrier();
+       }
+
+       return 0;
+}
+
+static void macb_phy_reset(struct macb_device *macb)
+{
+       struct eth_device *netdev = &macb->netdev;
+       int i;
+       u16 status, adv;
+
+       adv = ADVERTISE_CSMA | ADVERTISE_ALL;
+       macb_mdio_write(macb, MII_ADVERTISE, adv);
+       printf("%s: Starting autonegotiation...\n", netdev->name);
+       macb_mdio_write(macb, MII_BMCR, (BMCR_ANENABLE
+                                        | BMCR_ANRESTART));
+
+       for (i = 0; i < CFG_MACB_AUTONEG_TIMEOUT / 100; i++) {
+               status = macb_mdio_read(macb, MII_BMSR);
+               if (status & BMSR_ANEGCOMPLETE)
+                       break;
+               udelay(100);
+       }
+
+       if (status & BMSR_ANEGCOMPLETE)
+               printf("%s: Autonegotiation complete\n", netdev->name);
+       else
+               printf("%s: Autonegotiation timed out (status=0x%04x)\n",
+                      netdev->name, status);
+}
+
+static int macb_phy_init(struct macb_device *macb)
+{
+       struct eth_device *netdev = &macb->netdev;
+       u32 ncfgr;
+       u16 phy_id, status, adv, lpa;
+       int media, speed, duplex;
+       int i;
+
+       /* Check if the PHY is up to snuff... */
+       phy_id = macb_mdio_read(macb, MII_PHYSID1);
+       if (phy_id == 0xffff) {
+               printf("%s: No PHY present\n", netdev->name);
+               return 0;
+       }
+
+       status = macb_mdio_read(macb, MII_BMSR);
+       if (!(status & BMSR_LSTATUS)) {
+               /* Try to re-negotiate if we don't have link already. */
+               macb_phy_reset(macb);
+
+               for (i = 0; i < CFG_MACB_AUTONEG_TIMEOUT / 100; i++) {
+                       status = macb_mdio_read(macb, MII_BMSR);
+                       if (status & BMSR_LSTATUS)
+                               break;
+                       udelay(100);
+               }
+       }
+
+       if (!(status & BMSR_LSTATUS)) {
+               printf("%s: link down (status: 0x%04x)\n",
+                      netdev->name, status);
+               return 0;
+       } else {
+               adv = macb_mdio_read(macb, MII_ADVERTISE);
+               lpa = macb_mdio_read(macb, MII_LPA);
+               media = mii_nway_result(lpa & adv);
+               speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
+                        ? 1 : 0);
+               duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+               printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n",
+                      netdev->name,
+                      speed ? "100" : "10",
+                      duplex ? "full" : "half",
+                      lpa);
+
+               ncfgr = macb_readl(macb, NCFGR);
+               ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
+               if (speed)
+                       ncfgr |= MACB_BIT(SPD);
+               if (duplex)
+                       ncfgr |= MACB_BIT(FD);
+               macb_writel(macb, NCFGR, ncfgr);
+               return 1;
+       }
+}
+
+static int macb_init(struct eth_device *netdev, bd_t *bd)
+{
+       struct macb_device *macb = to_macb(netdev);
+       unsigned long paddr;
+       u32 hwaddr_bottom;
+       u16 hwaddr_top;
+       int i;
+
+       /*
+        * macb_halt should have been called at some point before now,
+        * so we'll assume the controller is idle.
+        */
+
+       /* initialize DMA descriptors */
+       paddr = macb->rx_buffer_dma;
+       for (i = 0; i < CFG_MACB_RX_RING_SIZE; i++) {
+               if (i == (CFG_MACB_RX_RING_SIZE - 1))
+                       paddr |= RXADDR_WRAP;
+               macb->rx_ring[i].addr = paddr;
+               macb->rx_ring[i].ctrl = 0;
+               paddr += 128;
+       }
+       for (i = 0; i < CFG_MACB_TX_RING_SIZE; i++) {
+               macb->tx_ring[i].addr = 0;
+               if (i == (CFG_MACB_TX_RING_SIZE - 1))
+                       macb->tx_ring[i].ctrl = TXBUF_USED | TXBUF_WRAP;
+               else
+                       macb->tx_ring[i].ctrl = TXBUF_USED;
+       }
+       macb->rx_tail = macb->tx_head = macb->tx_tail = 0;
+
+       macb_writel(macb, RBQP, macb->rx_ring_dma);
+       macb_writel(macb, TBQP, macb->tx_ring_dma);
+
+       /* set hardware address */
+       hwaddr_bottom = cpu_to_le32(*((u32 *)netdev->enetaddr));
+       macb_writel(macb, SA1B, hwaddr_bottom);
+       hwaddr_top = cpu_to_le16(*((u16 *)(netdev->enetaddr + 4)));
+       macb_writel(macb, SA1T, hwaddr_top);
+
+       /* choose RMII or MII mode. This depends on the board */
+#ifdef CONFIG_RMII
+       macb_writel(macb, USRIO, 0);
+#else
+       macb_writel(macb, USRIO, MACB_BIT(MII));
+#endif
+
+       if (!macb_phy_init(macb))
+               return 0;
+
+       /* Enable TX and RX */
+       macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE));
+
+       return 1;
+}
+
+static void macb_halt(struct eth_device *netdev)
+{
+       struct macb_device *macb = to_macb(netdev);
+       u32 ncr, tsr;
+
+       /* Halt the controller and wait for any ongoing transmission to end. */
+       ncr = macb_readl(macb, NCR);
+       ncr |= MACB_BIT(THALT);
+       macb_writel(macb, NCR, ncr);
+
+       do {
+               tsr = macb_readl(macb, TSR);
+       } while (tsr & MACB_BIT(TGO));
+
+       /* Disable TX and RX, and clear statistics */
+       macb_writel(macb, NCR, MACB_BIT(CLRSTAT));
+}
+
+int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)
+{
+       struct macb_device *macb;
+       struct eth_device *netdev;
+       unsigned long macb_hz;
+       u32 ncfgr;
+
+       macb = malloc(sizeof(struct macb_device));
+       if (!macb) {
+               printf("Error: Failed to allocate memory for MACB%d\n", id);
+               return -1;
+       }
+       memset(macb, 0, sizeof(struct macb_device));
+
+       netdev = &macb->netdev;
+
+       macb->rx_buffer = dma_alloc_coherent(CFG_MACB_RX_BUFFER_SIZE,
+                                            &macb->rx_buffer_dma);
+       macb->rx_ring = dma_alloc_coherent(CFG_MACB_RX_RING_SIZE
+                                          * sizeof(struct macb_dma_desc),
+                                          &macb->rx_ring_dma);
+       macb->tx_ring = dma_alloc_coherent(CFG_MACB_TX_RING_SIZE
+                                          * sizeof(struct macb_dma_desc),
+                                          &macb->tx_ring_dma);
+
+       macb->regs = regs;
+       macb->phy_addr = phy_addr;
+
+       sprintf(netdev->name, "macb%d", id);
+       netdev->init = macb_init;
+       netdev->halt = macb_halt;
+       netdev->send = macb_send;
+       netdev->recv = macb_recv;
+
+       /*
+        * Do some basic initialization so that we at least can talk
+        * to the PHY
+        */
+       macb_hz = get_macb_pclk_rate(id);
+       if (macb_hz < 20000000)
+               ncfgr = MACB_BF(CLK, MACB_CLK_DIV8);
+       else if (macb_hz < 40000000)
+               ncfgr = MACB_BF(CLK, MACB_CLK_DIV16);
+       else if (macb_hz < 80000000)
+               ncfgr = MACB_BF(CLK, MACB_CLK_DIV32);
+       else
+               ncfgr = MACB_BF(CLK, MACB_CLK_DIV64);
+
+       macb_writel(macb, NCFGR, ncfgr);
+
+       eth_register(netdev);
+
+       return 0;
+}
+
+#endif
+
+#if defined(CONFIG_CMD_MII)
+
+int miiphy_read(unsigned char addr, unsigned char reg, unsigned short *value)
+{
+       unsigned long netctl;
+       unsigned long netstat;
+       unsigned long frame;
+       int iflag;
+
+       iflag = disable_interrupts();
+       netctl = macb_readl(&macb, EMACB_NCR);
+       netctl |= MACB_BIT(MPE);
+       macb_writel(&macb, EMACB_NCR, netctl);
+       if (iflag)
+               enable_interrupts();
+
+       frame = (MACB_BF(SOF, 1)
+                | MACB_BF(RW, 2)
+                | MACB_BF(PHYA, addr)
+                | MACB_BF(REGA, reg)
+                | MACB_BF(CODE, 2));
+       macb_writel(&macb, EMACB_MAN, frame);
+
+       do {
+               netstat = macb_readl(&macb, EMACB_NSR);
+       } while (!(netstat & MACB_BIT(IDLE)));
+
+       frame = macb_readl(&macb, EMACB_MAN);
+       *value = MACB_BFEXT(DATA, frame);
+
+       iflag = disable_interrupts();
+       netctl = macb_readl(&macb, EMACB_NCR);
+       netctl &= ~MACB_BIT(MPE);
+       macb_writel(&macb, EMACB_NCR, netctl);
+       if (iflag)
+               enable_interrupts();
+
+       return 0;
+}
+
+int miiphy_write(unsigned char addr, unsigned char reg, unsigned short value)
+{
+       unsigned long netctl;
+       unsigned long netstat;
+       unsigned long frame;
+       int iflag;
+
+       iflag = disable_interrupts();
+       netctl = macb_readl(&macb, EMACB_NCR);
+       netctl |= MACB_BIT(MPE);
+       macb_writel(&macb, EMACB_NCR, netctl);
+       if (iflag)
+               enable_interrupts();
+
+       frame = (MACB_BF(SOF, 1)
+                | MACB_BF(RW, 1)
+                | MACB_BF(PHYA, addr)
+                | MACB_BF(REGA, reg)
+                | MACB_BF(CODE, 2)
+                | MACB_BF(DATA, value));
+       macb_writel(&macb, EMACB_MAN, frame);
+
+       do {
+               netstat = macb_readl(&macb, EMACB_NSR);
+       } while (!(netstat & MACB_BIT(IDLE)));
+
+       iflag = disable_interrupts();
+       netctl = macb_readl(&macb, EMACB_NCR);
+       netctl &= ~MACB_BIT(MPE);
+       macb_writel(&macb, EMACB_NCR, netctl);
+       if (iflag)
+               enable_interrupts();
+
+       return 0;
+}
+
+#endif
+
+#endif /* CONFIG_MACB */
diff --git a/drivers/net/macb.h b/drivers/net/macb.h
new file mode 100644 (file)
index 0000000..c778e4e
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __DRIVERS_MACB_H__
+#define __DRIVERS_MACB_H__
+
+/* MACB register offsets */
+#define MACB_NCR                               0x0000
+#define MACB_NCFGR                             0x0004
+#define MACB_NSR                               0x0008
+#define MACB_TSR                               0x0014
+#define MACB_RBQP                              0x0018
+#define MACB_TBQP                              0x001c
+#define MACB_RSR                               0x0020
+#define MACB_ISR                               0x0024
+#define MACB_IER                               0x0028
+#define MACB_IDR                               0x002c
+#define MACB_IMR                               0x0030
+#define MACB_MAN                               0x0034
+#define MACB_PTR                               0x0038
+#define MACB_PFR                               0x003c
+#define MACB_FTO                               0x0040
+#define MACB_SCF                               0x0044
+#define MACB_MCF                               0x0048
+#define MACB_FRO                               0x004c
+#define MACB_FCSE                              0x0050
+#define MACB_ALE                               0x0054
+#define MACB_DTF                               0x0058
+#define MACB_LCOL                              0x005c
+#define MACB_EXCOL                             0x0060
+#define MACB_TUND                              0x0064
+#define MACB_CSE                               0x0068
+#define MACB_RRE                               0x006c
+#define MACB_ROVR                              0x0070
+#define MACB_RSE                               0x0074
+#define MACB_ELE                               0x0078
+#define MACB_RJA                               0x007c
+#define MACB_USF                               0x0080
+#define MACB_STE                               0x0084
+#define MACB_RLE                               0x0088
+#define MACB_TPF                               0x008c
+#define MACB_HRB                               0x0090
+#define MACB_HRT                               0x0094
+#define MACB_SA1B                              0x0098
+#define MACB_SA1T                              0x009c
+#define MACB_SA2B                              0x00a0
+#define MACB_SA2T                              0x00a4
+#define MACB_SA3B                              0x00a8
+#define MACB_SA3T                              0x00ac
+#define MACB_SA4B                              0x00b0
+#define MACB_SA4T                              0x00b4
+#define MACB_TID                               0x00b8
+#define MACB_TPQ                               0x00bc
+#define MACB_USRIO                             0x00c0
+#define MACB_WOL                               0x00c4
+
+/* Bitfields in NCR */
+#define MACB_LB_OFFSET                         0
+#define MACB_LB_SIZE                           1
+#define MACB_LLB_OFFSET                                1
+#define MACB_LLB_SIZE                          1
+#define MACB_RE_OFFSET                         2
+#define MACB_RE_SIZE                           1
+#define MACB_TE_OFFSET                         3
+#define MACB_TE_SIZE                           1
+#define MACB_MPE_OFFSET                                4
+#define MACB_MPE_SIZE                          1
+#define MACB_CLRSTAT_OFFSET                    5
+#define MACB_CLRSTAT_SIZE                      1
+#define MACB_INCSTAT_OFFSET                    6
+#define MACB_INCSTAT_SIZE                      1
+#define MACB_WESTAT_OFFSET                     7
+#define MACB_WESTAT_SIZE                       1
+#define MACB_BP_OFFSET                         8
+#define MACB_BP_SIZE                           1
+#define MACB_TSTART_OFFSET                     9
+#define MACB_TSTART_SIZE                       1
+#define MACB_THALT_OFFSET                      10
+#define MACB_THALT_SIZE                                1
+#define MACB_NCR_TPF_OFFSET                    11
+#define MACB_NCR_TPF_SIZE                      1
+#define MACB_TZQ_OFFSET                                12
+#define MACB_TZQ_SIZE                          1
+
+/* Bitfields in NCFGR */
+#define MACB_SPD_OFFSET                                0
+#define MACB_SPD_SIZE                          1
+#define MACB_FD_OFFSET                         1
+#define MACB_FD_SIZE                           1
+#define MACB_BIT_RATE_OFFSET                   2
+#define MACB_BIT_RATE_SIZE                     1
+#define MACB_JFRAME_OFFSET                     3
+#define MACB_JFRAME_SIZE                       1
+#define MACB_CAF_OFFSET                                4
+#define MACB_CAF_SIZE                          1
+#define MACB_NBC_OFFSET                                5
+#define MACB_NBC_SIZE                          1
+#define MACB_NCFGR_MTI_OFFSET                  6
+#define MACB_NCFGR_MTI_SIZE                    1
+#define MACB_UNI_OFFSET                                7
+#define MACB_UNI_SIZE                          1
+#define MACB_BIG_OFFSET                                8
+#define MACB_BIG_SIZE                          1
+#define MACB_EAE_OFFSET                                9
+#define MACB_EAE_SIZE                          1
+#define MACB_CLK_OFFSET                                10
+#define MACB_CLK_SIZE                          2
+#define MACB_RTY_OFFSET                                12
+#define MACB_RTY_SIZE                          1
+#define MACB_PAE_OFFSET                                13
+#define MACB_PAE_SIZE                          1
+#define MACB_RBOF_OFFSET                       14
+#define MACB_RBOF_SIZE                         2
+#define MACB_RLCE_OFFSET                       16
+#define MACB_RLCE_SIZE                         1
+#define MACB_DRFCS_OFFSET                      17
+#define MACB_DRFCS_SIZE                                1
+#define MACB_EFRHD_OFFSET                      18
+#define MACB_EFRHD_SIZE                                1
+#define MACB_IRXFCS_OFFSET                     19
+#define MACB_IRXFCS_SIZE                       1
+
+/* Bitfields in NSR */
+#define MACB_NSR_LINK_OFFSET                   0
+#define MACB_NSR_LINK_SIZE                     1
+#define MACB_MDIO_OFFSET                       1
+#define MACB_MDIO_SIZE                         1
+#define MACB_IDLE_OFFSET                       2
+#define MACB_IDLE_SIZE                         1
+
+/* Bitfields in TSR */
+#define MACB_UBR_OFFSET                                0
+#define MACB_UBR_SIZE                          1
+#define MACB_COL_OFFSET                                1
+#define MACB_COL_SIZE                          1
+#define MACB_TSR_RLE_OFFSET                    2
+#define MACB_TSR_RLE_SIZE                      1
+#define MACB_TGO_OFFSET                                3
+#define MACB_TGO_SIZE                          1
+#define MACB_BEX_OFFSET                                4
+#define MACB_BEX_SIZE                          1
+#define MACB_COMP_OFFSET                       5
+#define MACB_COMP_SIZE                         1
+#define MACB_UND_OFFSET                                6
+#define MACB_UND_SIZE                          1
+
+/* Bitfields in RSR */
+#define MACB_BNA_OFFSET                                0
+#define MACB_BNA_SIZE                          1
+#define MACB_REC_OFFSET                                1
+#define MACB_REC_SIZE                          1
+#define MACB_OVR_OFFSET                                2
+#define MACB_OVR_SIZE                          1
+
+/* Bitfields in ISR/IER/IDR/IMR */
+#define MACB_MFD_OFFSET                                0
+#define MACB_MFD_SIZE                          1
+#define MACB_RCOMP_OFFSET                      1
+#define MACB_RCOMP_SIZE                                1
+#define MACB_RXUBR_OFFSET                      2
+#define MACB_RXUBR_SIZE                                1
+#define MACB_TXUBR_OFFSET                      3
+#define MACB_TXUBR_SIZE                                1
+#define MACB_ISR_TUND_OFFSET                   4
+#define MACB_ISR_TUND_SIZE                     1
+#define MACB_ISR_RLE_OFFSET                    5
+#define MACB_ISR_RLE_SIZE                      1
+#define MACB_TXERR_OFFSET                      6
+#define MACB_TXERR_SIZE                                1
+#define MACB_TCOMP_OFFSET                      7
+#define MACB_TCOMP_SIZE                                1
+#define MACB_ISR_LINK_OFFSET                   9
+#define MACB_ISR_LINK_SIZE                     1
+#define MACB_ISR_ROVR_OFFSET                   10
+#define MACB_ISR_ROVR_SIZE                     1
+#define MACB_HRESP_OFFSET                      11
+#define MACB_HRESP_SIZE                                1
+#define MACB_PFR_OFFSET                                12
+#define MACB_PFR_SIZE                          1
+#define MACB_PTZ_OFFSET                                13
+#define MACB_PTZ_SIZE                          1
+
+/* Bitfields in MAN */
+#define MACB_DATA_OFFSET                       0
+#define MACB_DATA_SIZE                         16
+#define MACB_CODE_OFFSET                       16
+#define MACB_CODE_SIZE                         2
+#define MACB_REGA_OFFSET                       18
+#define MACB_REGA_SIZE                         5
+#define MACB_PHYA_OFFSET                       23
+#define MACB_PHYA_SIZE                         5
+#define MACB_RW_OFFSET                         28
+#define MACB_RW_SIZE                           2
+#define MACB_SOF_OFFSET                                30
+#define MACB_SOF_SIZE                          2
+
+/* Bitfields in USRIO */
+#define MACB_MII_OFFSET                                0
+#define MACB_MII_SIZE                          1
+#define MACB_EAM_OFFSET                                1
+#define MACB_EAM_SIZE                          1
+#define MACB_TX_PAUSE_OFFSET                   2
+#define MACB_TX_PAUSE_SIZE                     1
+#define MACB_TX_PAUSE_ZERO_OFFSET              3
+#define MACB_TX_PAUSE_ZERO_SIZE                        1
+
+/* Bitfields in WOL */
+#define MACB_IP_OFFSET                         0
+#define MACB_IP_SIZE                           16
+#define MACB_MAG_OFFSET                                16
+#define MACB_MAG_SIZE                          1
+#define MACB_ARP_OFFSET                                17
+#define MACB_ARP_SIZE                          1
+#define MACB_SA1_OFFSET                                18
+#define MACB_SA1_SIZE                          1
+#define MACB_WOL_MTI_OFFSET                    19
+#define MACB_WOL_MTI_SIZE                      1
+
+/* Constants for CLK */
+#define MACB_CLK_DIV8                          0
+#define MACB_CLK_DIV16                         1
+#define MACB_CLK_DIV32                         2
+#define MACB_CLK_DIV64                         3
+
+/* Constants for MAN register */
+#define MACB_MAN_SOF                           1
+#define MACB_MAN_WRITE                         1
+#define MACB_MAN_READ                          2
+#define MACB_MAN_CODE                          2
+
+/* Bit manipulation macros */
+#define MACB_BIT(name)                                 \
+       (1 << MACB_##name##_OFFSET)
+#define MACB_BF(name,value)                            \
+       (((value) & ((1 << MACB_##name##_SIZE) - 1))    \
+        << MACB_##name##_OFFSET)
+#define MACB_BFEXT(name,value)\
+       (((value) >> MACB_##name##_OFFSET)              \
+        & ((1 << MACB_##name##_SIZE) - 1))
+#define MACB_BFINS(name,value,old)                     \
+       (((old) & ~(((1 << MACB_##name##_SIZE) - 1)     \
+                   << MACB_##name##_OFFSET))           \
+        | MACB_BF(name,value))
+
+/* Register access macros */
+#define macb_readl(port,reg)                           \
+       readl((port)->regs + MACB_##reg)
+#define macb_writel(port,reg,value)                    \
+       writel((value), (port)->regs + MACB_##reg)
+
+#endif /* __DRIVERS_MACB_H__ */
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
new file mode 100644 (file)
index 0000000..075d6c5
--- /dev/null
@@ -0,0 +1,882 @@
+/*
+   natsemi.c: A U-Boot driver for the NatSemi DP8381x series.
+   Author: Mark A. Rakes (mark_rakes@vivato.net)
+
+   Adapted from an Etherboot driver written by:
+
+   Copyright (C) 2001 Entity Cyber, Inc.
+
+   This development of this Etherboot driver was funded by
+
+      Sicom Systems: http://www.sicompos.com/
+
+   Author: Marty Connor (mdc@thinguin.org)
+   Adapted from a Linux driver which was written by Donald Becker
+
+   This software may be used and distributed according to the terms
+   of the GNU Public License (GPL), incorporated herein by reference.
+
+   Original Copyright Notice:
+
+   Written/copyright 1999-2001 by Donald Becker.
+
+   This software may be used and distributed according to the terms of
+   the GNU General Public License (GPL), incorporated herein by reference.
+   Drivers based on or derived from this code fall under the GPL and must
+   retain the authorship, copyright and license notice.  This file is not
+   a complete program and may only be used when the entire operating
+   system is licensed under the GPL.  License for under other terms may be
+   available.  Contact the original author for details.
+
+   The original author may be reached as becker@scyld.com, or at
+   Scyld Computing Corporation
+   410 Severn Ave., Suite 210
+   Annapolis MD 21403
+
+   Support information and updates available at
+   http://www.scyld.com/network/netsemi.html
+
+   References:
+   http://www.scyld.com/expert/100mbps.html
+   http://www.scyld.com/expert/NWay.html
+   Datasheet is available from:
+   http://www.national.com/pf/DP/DP83815.html
+*/
+
+/* Revision History
+ * October 2002 mar    1.0
+ *   Initial U-Boot Release.  Tested with Netgear FA311 board
+ *   and dp83815 chipset on custom board
+*/
+
+/* Includes */
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#if defined(CONFIG_CMD_NET) \
+       && defined(CONFIG_NET_MULTI) && defined(CONFIG_NATSEMI)
+
+/* defines */
+#define EEPROM_SIZE 0xb /*12 16-bit chunks, or 24 bytes*/
+
+#define DSIZE     0x00000FFF
+#define ETH_ALEN       6
+#define CRC_SIZE  4
+#define TOUT_LOOP   500000
+#define TX_BUF_SIZE    1536
+#define RX_BUF_SIZE    1536
+#define NUM_RX_DESC    4       /* Number of Rx descriptor registers. */
+
+/* Offsets to the device registers.
+   Unlike software-only systems, device drivers interact with complex hardware.
+   It's not useful to define symbolic names for every register bit in the
+   device.  */
+enum register_offsets {
+       ChipCmd         = 0x00,
+       ChipConfig      = 0x04,
+       EECtrl          = 0x08,
+       IntrMask        = 0x14,
+       IntrEnable      = 0x18,
+       TxRingPtr       = 0x20,
+       TxConfig        = 0x24,
+       RxRingPtr       = 0x30,
+       RxConfig        = 0x34,
+       ClkRun          = 0x3C,
+       RxFilterAddr    = 0x48,
+       RxFilterData    = 0x4C,
+       SiliconRev      = 0x58,
+       PCIPM           = 0x44,
+       BasicControl    = 0x80,
+       BasicStatus     = 0x84,
+       /* These are from the spec, around page 78... on a separate table. */
+       PGSEL           = 0xCC,
+       PMDCSR          = 0xE4,
+       TSTDAT          = 0xFC,
+       DSPCFG          = 0xF4,
+       SDCFG           = 0x8C
+};
+
+/* Bit in ChipCmd. */
+enum ChipCmdBits {
+       ChipReset       = 0x100,
+       RxReset         = 0x20,
+       TxReset         = 0x10,
+       RxOff           = 0x08,
+       RxOn            = 0x04,
+       TxOff           = 0x02,
+       TxOn            = 0x01
+};
+
+enum ChipConfigBits {
+       LinkSts         = 0x80000000,
+       HundSpeed       = 0x40000000,
+       FullDuplex      = 0x20000000,
+       TenPolarity     = 0x10000000,
+       AnegDone        = 0x08000000,
+       AnegEnBothBoth  = 0x0000E000,
+       AnegDis100Full  = 0x0000C000,
+       AnegEn100Both   = 0x0000A000,
+       AnegDis100Half  = 0x00008000,
+       AnegEnBothHalf  = 0x00006000,
+       AnegDis10Full   = 0x00004000,
+       AnegEn10Both    = 0x00002000,
+       DuplexMask      = 0x00008000,
+       SpeedMask       = 0x00004000,
+       AnegMask        = 0x00002000,
+       AnegDis10Half   = 0x00000000,
+       ExtPhy          = 0x00001000,
+       PhyRst          = 0x00000400,
+       PhyDis          = 0x00000200,
+       BootRomDisable  = 0x00000004,
+       BEMode          = 0x00000001,
+};
+
+enum TxConfig_bits {
+       TxDrthMask      = 0x3f,
+       TxFlthMask      = 0x3f00,
+       TxMxdmaMask     = 0x700000,
+       TxMxdma_512     = 0x0,
+       TxMxdma_4       = 0x100000,
+       TxMxdma_8       = 0x200000,
+       TxMxdma_16      = 0x300000,
+       TxMxdma_32      = 0x400000,
+       TxMxdma_64      = 0x500000,
+       TxMxdma_128     = 0x600000,
+       TxMxdma_256     = 0x700000,
+       TxCollRetry     = 0x800000,
+       TxAutoPad       = 0x10000000,
+       TxMacLoop       = 0x20000000,
+       TxHeartIgn      = 0x40000000,
+       TxCarrierIgn    = 0x80000000
+};
+
+enum RxConfig_bits {
+       RxDrthMask      = 0x3e,
+       RxMxdmaMask     = 0x700000,
+       RxMxdma_512     = 0x0,
+       RxMxdma_4       = 0x100000,
+       RxMxdma_8       = 0x200000,
+       RxMxdma_16      = 0x300000,
+       RxMxdma_32      = 0x400000,
+       RxMxdma_64      = 0x500000,
+       RxMxdma_128     = 0x600000,
+       RxMxdma_256     = 0x700000,
+       RxAcceptLong    = 0x8000000,
+       RxAcceptTx      = 0x10000000,
+       RxAcceptRunt    = 0x40000000,
+       RxAcceptErr     = 0x80000000
+};
+
+/* Bits in the RxMode register. */
+enum rx_mode_bits {
+       AcceptErr               = 0x20,
+       AcceptRunt              = 0x10,
+       AcceptBroadcast         = 0xC0000000,
+       AcceptMulticast         = 0x00200000,
+       AcceptAllMulticast      = 0x20000000,
+       AcceptAllPhys           = 0x10000000,
+       AcceptMyPhys            = 0x08000000
+};
+
+typedef struct _BufferDesc {
+       u32 link;
+       vu_long cmdsts;
+       u32 bufptr;
+       u32 software_use;
+} BufferDesc;
+
+/* Bits in network_desc.status */
+enum desc_status_bits {
+       DescOwn = 0x80000000, DescMore = 0x40000000, DescIntr = 0x20000000,
+       DescNoCRC = 0x10000000, DescPktOK = 0x08000000,
+       DescSizeMask = 0xfff,
+
+       DescTxAbort = 0x04000000, DescTxFIFO = 0x02000000,
+       DescTxCarrier = 0x01000000, DescTxDefer = 0x00800000,
+       DescTxExcDefer = 0x00400000, DescTxOOWCol = 0x00200000,
+       DescTxExcColl = 0x00100000, DescTxCollCount = 0x000f0000,
+
+       DescRxAbort = 0x04000000, DescRxOver = 0x02000000,
+       DescRxDest = 0x01800000, DescRxLong = 0x00400000,
+       DescRxRunt = 0x00200000, DescRxInvalid = 0x00100000,
+       DescRxCRC = 0x00080000, DescRxAlign = 0x00040000,
+       DescRxLoop = 0x00020000, DesRxColl = 0x00010000,
+};
+
+/* Globals */
+#ifdef NATSEMI_DEBUG
+static int natsemi_debug = 0;  /* 1 verbose debugging, 0 normal */
+#endif
+static u32 SavedClkRun;
+static unsigned int cur_rx;
+static unsigned int advertising;
+static unsigned int rx_config;
+static unsigned int tx_config;
+
+/* Note: transmit and receive buffers and descriptors must be
+   longword aligned */
+static BufferDesc txd __attribute__ ((aligned(4)));
+static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(4)));
+
+static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(4)));
+static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE]
+    __attribute__ ((aligned(4)));
+
+/* Function Prototypes */
+#if 0
+static void write_eeprom(struct eth_device *dev, long addr, int location,
+                        short value);
+#endif
+static int read_eeprom(struct eth_device *dev, long addr, int location);
+static int mdio_read(struct eth_device *dev, int phy_id, int location);
+static int natsemi_init(struct eth_device *dev, bd_t * bis);
+static void natsemi_reset(struct eth_device *dev);
+static void natsemi_init_rxfilter(struct eth_device *dev);
+static void natsemi_init_txd(struct eth_device *dev);
+static void natsemi_init_rxd(struct eth_device *dev);
+static void natsemi_set_rx_mode(struct eth_device *dev);
+static void natsemi_check_duplex(struct eth_device *dev);
+static int natsemi_send(struct eth_device *dev, volatile void *packet,
+                       int length);
+static int natsemi_poll(struct eth_device *dev);
+static void natsemi_disable(struct eth_device *dev);
+
+static struct pci_device_id supported[] = {
+       {PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815},
+       {}
+};
+
+#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a)
+#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
+
+static inline int
+INW(struct eth_device *dev, u_long addr)
+{
+       return le16_to_cpu(*(vu_short *) (addr + dev->iobase));
+}
+
+static int
+INL(struct eth_device *dev, u_long addr)
+{
+       return le32_to_cpu(*(vu_long *) (addr + dev->iobase));
+}
+
+static inline void
+OUTW(struct eth_device *dev, int command, u_long addr)
+{
+       *(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command);
+}
+
+static inline void
+OUTL(struct eth_device *dev, int command, u_long addr)
+{
+       *(vu_long *) ((addr + dev->iobase)) = cpu_to_le32(command);
+}
+
+/*
+ * Function: natsemi_initialize
+ *
+ * Description: Retrieves the MAC address of the card, and sets up some
+ * globals required by other routines,  and initializes the NIC, making it
+ * ready to send and receive packets.
+ *
+ * Side effects:
+ *            leaves the natsemi initialized, and ready to recieve packets.
+ *
+ * Returns:   struct eth_device *:          pointer to NIC data structure
+ */
+
+int
+natsemi_initialize(bd_t * bis)
+{
+       pci_dev_t devno;
+       int card_number = 0;
+       struct eth_device *dev;
+       u32 iobase, status, chip_config;
+       int i, idx = 0;
+       int prev_eedata;
+       u32 tmp;
+
+       while (1) {
+               /* Find PCI device(s) */
+               if ((devno = pci_find_devices(supported, idx++)) < 0) {
+                       break;
+               }
+
+               pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase);
+               iobase &= ~0x3; /* bit 1: unused and bit 0: I/O Space Indicator */
+
+               pci_write_config_dword(devno, PCI_COMMAND,
+                                      PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+               /* Check if I/O accesses and Bus Mastering are enabled. */
+               pci_read_config_dword(devno, PCI_COMMAND, &status);
+               if (!(status & PCI_COMMAND_MEMORY)) {
+                       printf("Error: Can not enable MEM access.\n");
+                       continue;
+               } else if (!(status & PCI_COMMAND_MASTER)) {
+                       printf("Error: Can not enable Bus Mastering.\n");
+                       continue;
+               }
+
+               dev = (struct eth_device *) malloc(sizeof *dev);
+
+               sprintf(dev->name, "dp83815#%d", card_number);
+               dev->iobase = bus_to_phys(iobase);
+#ifdef NATSEMI_DEBUG
+               printf("natsemi: NatSemi ns8381[56] @ %#x\n", dev->iobase);
+#endif
+               dev->priv = (void *) devno;
+               dev->init = natsemi_init;
+               dev->halt = natsemi_disable;
+               dev->send = natsemi_send;
+               dev->recv = natsemi_poll;
+
+               eth_register(dev);
+
+               card_number++;
+
+               /* Set the latency timer for value. */
+               pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20);
+
+               udelay(10 * 1000);
+
+               /* natsemi has a non-standard PM control register
+                * in PCI config space.  Some boards apparently need
+                * to be brought to D0 in this manner.  */
+               pci_read_config_dword(devno, PCIPM, &tmp);
+               if (tmp & (0x03 | 0x100)) {
+                       /* D0 state, disable PME assertion */
+                       u32 newtmp = tmp & ~(0x03 | 0x100);
+                       pci_write_config_dword(devno, PCIPM, newtmp);
+               }
+
+               printf("natsemi: EEPROM contents:\n");
+               for (i = 0; i <= EEPROM_SIZE; i++) {
+                       short eedata = read_eeprom(dev, EECtrl, i);
+                       printf(" %04hx", eedata);
+               }
+               printf("\n");
+
+               /* get MAC address */
+               prev_eedata = read_eeprom(dev, EECtrl, 6);
+               for (i = 0; i < 3; i++) {
+                       int eedata = read_eeprom(dev, EECtrl, i + 7);
+                       dev->enetaddr[i*2] = (eedata << 1) + (prev_eedata >> 15);
+                       dev->enetaddr[i*2+1] = eedata >> 7;
+                       prev_eedata = eedata;
+               }
+
+               /* Reset the chip to erase any previous misconfiguration. */
+               OUTL(dev, ChipReset, ChipCmd);
+
+               advertising = mdio_read(dev, 1, 4);
+               chip_config = INL(dev, ChipConfig);
+#ifdef NATSEMI_DEBUG
+               printf("%s: Transceiver status %#08X advertising %#08X\n",
+                       dev->name, (int) INL(dev, BasicStatus), advertising);
+               printf("%s: Transceiver default autoneg. %s 10%s %s duplex.\n",
+                       dev->name, chip_config & AnegMask ? "enabled, advertise" :
+                       "disabled, force", chip_config & SpeedMask ? "0" : "",
+                       chip_config & DuplexMask ? "full" : "half");
+#endif
+               chip_config |= AnegEnBothBoth;
+#ifdef NATSEMI_DEBUG
+               printf("%s: changed to autoneg. %s 10%s %s duplex.\n",
+                       dev->name, chip_config & AnegMask ? "enabled, advertise" :
+                       "disabled, force", chip_config & SpeedMask ? "0" : "",
+                       chip_config & DuplexMask ? "full" : "half");
+#endif
+               /*write new autoneg bits, reset phy*/
+               OUTL(dev, (chip_config | PhyRst), ChipConfig);
+               /*un-reset phy*/
+               OUTL(dev, chip_config, ChipConfig);
+
+               /* Disable PME:
+                * The PME bit is initialized from the EEPROM contents.
+                * PCI cards probably have PME disabled, but motherboard
+                * implementations may have PME set to enable WakeOnLan.
+                * With PME set the chip will scan incoming packets but
+                * nothing will be written to memory. */
+               SavedClkRun = INL(dev, ClkRun);
+               OUTL(dev, SavedClkRun & ~0x100, ClkRun);
+       }
+       return card_number;
+}
+
+/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
+   The EEPROM code is for common 93c06/46 EEPROMs w/ 6bit addresses.  */
+
+/* Delay between EEPROM clock transitions.
+   No extra delay is needed with 33Mhz PCI, but future 66Mhz
+   access may need a delay. */
+#define eeprom_delay(ee_addr)  INL(dev, ee_addr)
+
+enum EEPROM_Ctrl_Bits {
+       EE_ShiftClk = 0x04,
+       EE_DataIn = 0x01,
+       EE_ChipSelect = 0x08,
+       EE_DataOut = 0x02
+};
+
+#define EE_Write0 (EE_ChipSelect)
+#define EE_Write1 (EE_ChipSelect | EE_DataIn)
+/* The EEPROM commands include the alway-set leading bit. */
+enum EEPROM_Cmds {
+       EE_WrEnCmd = (4 << 6), EE_WriteCmd = (5 << 6),
+       EE_ReadCmd = (6 << 6), EE_EraseCmd = (7 << 6),
+};
+
+#if 0
+static void
+write_eeprom(struct eth_device *dev, long addr, int location, short value)
+{
+       int i;
+       int ee_addr = (typeof(ee_addr))addr;
+       short wren_cmd = EE_WrEnCmd | 0x30; /*wren is 100 + 11XXXX*/
+       short write_cmd = location | EE_WriteCmd;
+
+#ifdef NATSEMI_DEBUG
+       printf("write_eeprom: %08x, %04hx, %04hx\n",
+               dev->iobase + ee_addr, write_cmd, value);
+#endif
+       /* Shift the write enable command bits out. */
+       for (i = 9; i >= 0; i--) {
+               short cmdval = (wren_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
+               OUTL(dev, cmdval, ee_addr);
+               eeprom_delay(ee_addr);
+               OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
+               eeprom_delay(ee_addr);
+       }
+
+       OUTL(dev, 0, ee_addr); /*bring chip select low*/
+       OUTL(dev, EE_ShiftClk, ee_addr);
+       eeprom_delay(ee_addr);
+
+       /* Shift the write command bits out. */
+       for (i = 9; i >= 0; i--) {
+               short cmdval = (write_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
+               OUTL(dev, cmdval, ee_addr);
+               eeprom_delay(ee_addr);
+               OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
+               eeprom_delay(ee_addr);
+       }
+
+       for (i = 0; i < 16; i++) {
+               short cmdval = (value & (1 << i)) ? EE_Write1 : EE_Write0;
+               OUTL(dev, cmdval, ee_addr);
+               eeprom_delay(ee_addr);
+               OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
+               eeprom_delay(ee_addr);
+       }
+
+       OUTL(dev, 0, ee_addr); /*bring chip select low*/
+       OUTL(dev, EE_ShiftClk, ee_addr);
+       for (i = 0; i < 200000; i++) {
+               OUTL(dev, EE_Write0, ee_addr); /*poll for done*/
+               if (INL(dev, ee_addr) & EE_DataOut) {
+                   break; /*finished*/
+               }
+       }
+       eeprom_delay(ee_addr);
+
+       /* Terminate the EEPROM access. */
+       OUTL(dev, EE_Write0, ee_addr);
+       OUTL(dev, 0, ee_addr);
+       return;
+}
+#endif
+
+static int
+read_eeprom(struct eth_device *dev, long addr, int location)
+{
+       int i;
+       int retval = 0;
+       int ee_addr = (typeof(ee_addr))addr;
+       int read_cmd = location | EE_ReadCmd;
+
+       OUTL(dev, EE_Write0, ee_addr);
+
+       /* Shift the read command bits out. */
+       for (i = 10; i >= 0; i--) {
+               short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
+               OUTL(dev, dataval, ee_addr);
+               eeprom_delay(ee_addr);
+               OUTL(dev, dataval | EE_ShiftClk, ee_addr);
+               eeprom_delay(ee_addr);
+       }
+       OUTL(dev, EE_ChipSelect, ee_addr);
+       eeprom_delay(ee_addr);
+
+       for (i = 0; i < 16; i++) {
+               OUTL(dev, EE_ChipSelect | EE_ShiftClk, ee_addr);
+               eeprom_delay(ee_addr);
+               retval |= (INL(dev, ee_addr) & EE_DataOut) ? 1 << i : 0;
+               OUTL(dev, EE_ChipSelect, ee_addr);
+               eeprom_delay(ee_addr);
+       }
+
+       /* Terminate the EEPROM access. */
+       OUTL(dev, EE_Write0, ee_addr);
+       OUTL(dev, 0, ee_addr);
+#ifdef NATSEMI_DEBUG
+       if (natsemi_debug)
+               printf("read_eeprom: %08x, %08x, retval %08x\n",
+                       dev->iobase + ee_addr, read_cmd, retval);
+#endif
+       return retval;
+}
+
+/*  MII transceiver control section.
+       The 83815 series has an internal transceiver, and we present the
+       management registers as if they were MII connected. */
+
+static int
+mdio_read(struct eth_device *dev, int phy_id, int location)
+{
+       if (phy_id == 1 && location < 32)
+               return INL(dev, BasicControl+(location<<2))&0xffff;
+       else
+               return 0xffff;
+}
+
+/* Function: natsemi_init
+ *
+ * Description: resets the ethernet controller chip and configures
+ *    registers and data structures required for sending and receiving packets.
+ *
+ * Arguments: struct eth_device *dev:          NIC data structure
+ *
+ * returns:    int.
+ */
+
+static int
+natsemi_init(struct eth_device *dev, bd_t * bis)
+{
+
+       natsemi_reset(dev);
+
+       /* Disable PME:
+        * The PME bit is initialized from the EEPROM contents.
+        * PCI cards probably have PME disabled, but motherboard
+        * implementations may have PME set to enable WakeOnLan.
+        * With PME set the chip will scan incoming packets but
+        * nothing will be written to memory. */
+       OUTL(dev, SavedClkRun & ~0x100, ClkRun);
+
+       natsemi_init_rxfilter(dev);
+       natsemi_init_txd(dev);
+       natsemi_init_rxd(dev);
+
+       /* Configure the PCI bus bursts and FIFO thresholds. */
+       tx_config = TxAutoPad | TxCollRetry | TxMxdma_256 | (0x1002);
+       rx_config = RxMxdma_256 | 0x20;
+
+#ifdef NATSEMI_DEBUG
+       printf("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config);
+       printf("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config);
+#endif
+       OUTL(dev, tx_config, TxConfig);
+       OUTL(dev, rx_config, RxConfig);
+
+       natsemi_check_duplex(dev);
+       natsemi_set_rx_mode(dev);
+
+       OUTL(dev, (RxOn | TxOn), ChipCmd);
+       return 1;
+}
+
+/*
+ * Function: natsemi_reset
+ *
+ * Description: soft resets the controller chip
+ *
+ * Arguments: struct eth_device *dev:          NIC data structure
+ *
+ * Returns:   void.
+ */
+static void
+natsemi_reset(struct eth_device *dev)
+{
+       OUTL(dev, ChipReset, ChipCmd);
+
+       /* On page 78 of the spec, they recommend some settings for "optimum
+          performance" to be done in sequence.  These settings optimize some
+          of the 100Mbit autodetection circuitry.  Also, we only want to do
+          this for rev C of the chip.  */
+       if (INL(dev, SiliconRev) == 0x302) {
+               OUTW(dev, 0x0001, PGSEL);
+               OUTW(dev, 0x189C, PMDCSR);
+               OUTW(dev, 0x0000, TSTDAT);
+               OUTW(dev, 0x5040, DSPCFG);
+               OUTW(dev, 0x008C, SDCFG);
+       }
+       /* Disable interrupts using the mask. */
+       OUTL(dev, 0, IntrMask);
+       OUTL(dev, 0, IntrEnable);
+}
+
+/* Function: natsemi_init_rxfilter
+ *
+ * Description: sets receive filter address to our MAC address
+ *
+ * Arguments: struct eth_device *dev:          NIC data structure
+ *
+ * returns:   void.
+ */
+
+static void
+natsemi_init_rxfilter(struct eth_device *dev)
+{
+       int i;
+
+       for (i = 0; i < ETH_ALEN; i += 2) {
+               OUTL(dev, i, RxFilterAddr);
+               OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8),
+                    RxFilterData);
+       }
+}
+
+/*
+ * Function: natsemi_init_txd
+ *
+ * Description: initializes the Tx descriptor
+ *
+ * Arguments: struct eth_device *dev:          NIC data structure
+ *
+ * returns:   void.
+ */
+
+static void
+natsemi_init_txd(struct eth_device *dev)
+{
+       txd.link = (u32) 0;
+       txd.cmdsts = (u32) 0;
+       txd.bufptr = (u32) & txb[0];
+
+       /* load Transmit Descriptor Register */
+       OUTL(dev, (u32) & txd, TxRingPtr);
+#ifdef NATSEMI_DEBUG
+       printf("natsemi_init_txd: TX descriptor reg loaded with: %#08X\n",
+              INL(dev, TxRingPtr));
+#endif
+}
+
+/* Function: natsemi_init_rxd
+ *
+ * Description: initializes the Rx descriptor ring
+ *
+ * Arguments: struct eth_device *dev:          NIC data structure
+ *
+ * Returns:   void.
+ */
+
+static void
+natsemi_init_rxd(struct eth_device *dev)
+{
+       int i;
+
+       cur_rx = 0;
+
+       /* init RX descriptor */
+       for (i = 0; i < NUM_RX_DESC; i++) {
+               rxd[i].link =
+                   cpu_to_le32((i + 1 <
+                                NUM_RX_DESC) ? (u32) & rxd[i +
+                                                           1] : (u32) &
+                               rxd[0]);
+               rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE);
+               rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]);
+#ifdef NATSEMI_DEBUG
+               printf
+                   ("natsemi_init_rxd: rxd[%d]=%p link=%X cmdsts=%lX bufptr=%X\n",
+                       i, &rxd[i], le32_to_cpu(rxd[i].link),
+                               rxd[i].cmdsts, rxd[i].bufptr);
+#endif
+       }
+
+       /* load Receive Descriptor Register */
+       OUTL(dev, (u32) & rxd[0], RxRingPtr);
+
+#ifdef NATSEMI_DEBUG
+       printf("natsemi_init_rxd: RX descriptor register loaded with: %X\n",
+              INL(dev, RxRingPtr));
+#endif
+}
+
+/* Function: natsemi_set_rx_mode
+ *
+ * Description:
+ *    sets the receive mode to accept all broadcast packets and packets
+ *    with our MAC address, and reject all multicast packets.
+ *
+ * Arguments: struct eth_device *dev:          NIC data structure
+ *
+ * Returns:   void.
+ */
+
+static void
+natsemi_set_rx_mode(struct eth_device *dev)
+{
+       u32 rx_mode = AcceptBroadcast | AcceptMyPhys;
+
+       OUTL(dev, rx_mode, RxFilterAddr);
+}
+
+static void
+natsemi_check_duplex(struct eth_device *dev)
+{
+       int duplex = INL(dev, ChipConfig) & FullDuplex ? 1 : 0;
+
+#ifdef NATSEMI_DEBUG
+       printf("%s: Setting %s-duplex based on negotiated link"
+              " capability.\n", dev->name, duplex ? "full" : "half");
+#endif
+       if (duplex) {
+               rx_config |= RxAcceptTx;
+               tx_config |= (TxCarrierIgn | TxHeartIgn);
+       } else {
+               rx_config &= ~RxAcceptTx;
+               tx_config &= ~(TxCarrierIgn | TxHeartIgn);
+       }
+       OUTL(dev, tx_config, TxConfig);
+       OUTL(dev, rx_config, RxConfig);
+}
+
+/* Function: natsemi_send
+ *
+ * Description: transmits a packet and waits for completion or timeout.
+ *
+ * Returns:   void.  */
+static int
+natsemi_send(struct eth_device *dev, volatile void *packet, int length)
+{
+       u32 i, status = 0;
+       u32 tx_status = 0;
+       vu_long *res = (vu_long *)&tx_status;
+
+       /* Stop the transmitter */
+       OUTL(dev, TxOff, ChipCmd);
+
+#ifdef NATSEMI_DEBUG
+       if (natsemi_debug)
+               printf("natsemi_send: sending %d bytes\n", (int) length);
+#endif
+
+       /* set the transmit buffer descriptor and enable Transmit State Machine */
+       txd.link = cpu_to_le32(0);
+       txd.bufptr = cpu_to_le32(phys_to_bus((u32) packet));
+       txd.cmdsts = cpu_to_le32(DescOwn | length);
+
+       /* load Transmit Descriptor Register */
+       OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr);
+#ifdef NATSEMI_DEBUG
+       if (natsemi_debug)
+           printf("natsemi_send: TX descriptor register loaded with: %#08X\n",
+            INL(dev, TxRingPtr));
+#endif
+       /* restart the transmitter */
+       OUTL(dev, TxOn, ChipCmd);
+
+       for (i = 0;
+            (*res = le32_to_cpu(txd.cmdsts)) & DescOwn;
+            i++) {
+               if (i >= TOUT_LOOP) {
+                       printf
+                           ("%s: tx error buffer not ready: txd.cmdsts == %#X\n",
+                            dev->name, tx_status);
+                       goto Done;
+               }
+       }
+
+       if (!(tx_status & DescPktOK)) {
+               printf("natsemi_send: Transmit error, Tx status %X.\n",
+                      tx_status);
+               goto Done;
+       }
+
+       status = 1;
+      Done:
+       return status;
+}
+
+/* Function: natsemi_poll
+ *
+ * Description: checks for a received packet and returns it if found.
+ *
+ * Arguments: struct eth_device *dev:          NIC data structure
+ *
+ * Returns:   1 if    packet was received.
+ *            0 if no packet was received.
+ *
+ * Side effects:
+ *            Returns (copies) the packet to the array dev->packet.
+ *            Returns the length of the packet.
+ */
+
+static int
+natsemi_poll(struct eth_device *dev)
+{
+       int retstat = 0;
+       int length = 0;
+       u32 rx_status = le32_to_cpu(rxd[cur_rx].cmdsts);
+
+       if (!(rx_status & (u32) DescOwn))
+               return retstat;
+#ifdef NATSEMI_DEBUG
+       if (natsemi_debug)
+               printf("natsemi_poll: got a packet: cur_rx:%d, status:%X\n",
+                      cur_rx, rx_status);
+#endif
+       length = (rx_status & DSIZE) - CRC_SIZE;
+
+       if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) {
+               printf
+                   ("natsemi_poll: Corrupted packet received, buffer status = %X\n",
+                    rx_status);
+               retstat = 0;
+       } else {                /* give packet to higher level routine */
+               NetReceive((rxb + cur_rx * RX_BUF_SIZE), length);
+               retstat = 1;
+       }
+
+       /* return the descriptor and buffer to receive ring */
+       rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE);
+       rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]);
+
+       if (++cur_rx == NUM_RX_DESC)
+               cur_rx = 0;
+
+       /* re-enable the potentially idle receive state machine */
+       OUTL(dev, RxOn, ChipCmd);
+
+       return retstat;
+}
+
+/* Function: natsemi_disable
+ *
+ * Description: Turns off interrupts and stops Tx and Rx engines
+ *
+ * Arguments: struct eth_device *dev:          NIC data structure
+ *
+ * Returns:   void.
+ */
+
+static void
+natsemi_disable(struct eth_device *dev)
+{
+       /* Disable interrupts using the mask. */
+       OUTL(dev, 0, IntrMask);
+       OUTL(dev, 0, IntrEnable);
+
+       /* Stop the chip's Tx and Rx processes. */
+       OUTL(dev, RxOff | TxOff, ChipCmd);
+
+       /* Restore PME enable bit */
+       OUTL(dev, SavedClkRun, ClkRun);
+}
+
+#endif
diff --git a/drivers/net/ne2000.c b/drivers/net/ne2000.c
new file mode 100644 (file)
index 0000000..c978d62
--- /dev/null
@@ -0,0 +1,940 @@
+/*
+Ported to U-Boot  by Christian Pellegrin <chri@ascensit.com>
+
+Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
+eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
+are GPL, so this is, of course, GPL.
+
+
+==========================================================================
+
+dev/if_dp83902a.c
+
+Ethernet device driver for NS DP83902a ethernet controller
+
+==========================================================================
+####ECOSGPLCOPYRIGHTBEGIN####
+-------------------------------------------
+This file is part of eCos, the Embedded Configurable Operating System.
+Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+
+eCos is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 or (at your option) any later version.
+
+eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with eCos; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+As a special exception, if other files instantiate templates or use macros
+or inline functions from this file, or you compile this file and link it
+with other works to produce a work based on this file, this file does not
+by itself cause the resulting work to be covered by the GNU General Public
+License. However the source code for this file must still be made available
+in accordance with section (3) of the GNU General Public License.
+
+This exception does not invalidate any other reasons why a work based on
+this file might be covered by the GNU General Public License.
+
+Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+at http://sources.redhat.com/ecos/ecos-license/
+-------------------------------------------
+####ECOSGPLCOPYRIGHTEND####
+####BSDCOPYRIGHTBEGIN####
+
+-------------------------------------------
+
+Portions of this software may have been derived from OpenBSD or other sources,
+and are covered by the appropriate copyright disclaimers included herein.
+
+-------------------------------------------
+
+####BSDCOPYRIGHTEND####
+==========================================================================
+#####DESCRIPTIONBEGIN####
+
+Author(s):    gthomas
+Contributors: gthomas, jskov, rsandifo
+Date:        2001-06-13
+Purpose:
+Description:
+
+FIXME:       Will fail if pinged with large packets (1520 bytes)
+Add promisc config
+Add SNMP
+
+####DESCRIPTIONEND####
+
+
+==========================================================================
+
+*/
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <malloc.h>
+
+#ifdef CONFIG_DRIVER_NE2000
+
+/* wor around udelay resetting OCR */
+static void my_udelay(long us) {
+       long tmo;
+
+       tmo = get_timer (0) + us * CFG_HZ / 1000000; /* will this be much greater than 0 ? */
+       while (get_timer (0) < tmo);
+}
+
+#define mdelay(n)       my_udelay((n)*1000)
+
+/* forward definition of function used for the uboot interface */
+void uboot_push_packet_len(int len);
+void uboot_push_tx_done(int key, int val);
+
+/* timeout for tx/rx in s */
+#define TOUT 5
+
+#define ETHER_ADDR_LEN 6
+
+/*
+  ------------------------------------------------------------------------
+  Debugging details
+
+  Set to perms of:
+  0 disables all debug output
+  1 for process debug output
+  2 for added data IO output: get_reg, put_reg
+  4 for packet allocation/free output
+  8 for only startup status, so we can tell we're installed OK
+*/
+/*#define DEBUG 0xf*/
+#define DEBUG 0
+
+#if DEBUG & 1
+#define DEBUG_FUNCTION() do { printf("%s\n", __FUNCTION__); } while (0)
+#define DEBUG_LINE() do { printf("%d\n", __LINE__); } while (0)
+#else
+#define DEBUG_FUNCTION() do {} while(0)
+#define DEBUG_LINE() do {} while(0)
+#endif
+
+#include "ne2000.h"
+
+#if DEBUG & 1
+#define PRINTK(args...) printf(args)
+#else
+#define PRINTK(args...)
+#endif
+
+static dp83902a_priv_data_t nic; /* just one instance of the card supported */
+
+static bool
+dp83902a_init(void)
+{
+       dp83902a_priv_data_t *dp = &nic;
+       cyg_uint8* base;
+       int i;
+
+       DEBUG_FUNCTION();
+
+       base = dp->base;
+       if (!base) return false;  /* No device found */
+
+       DEBUG_LINE();
+
+       /* Prepare ESA */
+       DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1);  /* Select page 1 */
+       /* Use the address from the serial EEPROM */
+       for (i = 0; i < 6; i++)
+               DP_IN(base, DP_P1_PAR0+i, dp->esa[i]);
+       DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0);  /* Select page 0 */
+
+       printf("NE2000 - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+              "eeprom",
+              dp->esa[0],
+              dp->esa[1],
+              dp->esa[2],
+              dp->esa[3],
+              dp->esa[4],
+              dp->esa[5] );
+
+       return true;
+}
+
+static void
+dp83902a_stop(void)
+{
+       dp83902a_priv_data_t *dp = &nic;
+       cyg_uint8 *base = dp->base;
+
+       DEBUG_FUNCTION();
+
+       DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP);  /* Brutal */
+       DP_OUT(base, DP_ISR, 0xFF);             /* Clear any pending interrupts */
+       DP_OUT(base, DP_IMR, 0x00);             /* Disable all interrupts */
+
+       dp->running = false;
+}
+
+/*
+  This function is called to "start up" the interface.  It may be called
+  multiple times, even when the hardware is already running.  It will be
+  called whenever something "hardware oriented" changes and should leave
+  the hardware ready to send/receive packets.
+*/
+static void
+dp83902a_start(unsigned char * enaddr)
+{
+       dp83902a_priv_data_t *dp = &nic;
+       cyg_uint8 *base = dp->base;
+       int i;
+
+       DEBUG_FUNCTION();
+
+       DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */
+       DP_OUT(base, DP_DCR, DP_DCR_INIT);
+       DP_OUT(base, DP_RBCH, 0);               /* Remote byte count */
+       DP_OUT(base, DP_RBCL, 0);
+       DP_OUT(base, DP_RCR, DP_RCR_MON);       /* Accept no packets */
+       DP_OUT(base, DP_TCR, DP_TCR_LOCAL);     /* Transmitter [virtually] off */
+       DP_OUT(base, DP_TPSR, dp->tx_buf1);     /* Transmitter start page */
+       dp->tx1 = dp->tx2 = 0;
+       dp->tx_next = dp->tx_buf1;
+       dp->tx_started = false;
+       DP_OUT(base, DP_PSTART, dp->rx_buf_start); /* Receive ring start page */
+       DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1); /* Receive ring boundary */
+       DP_OUT(base, DP_PSTOP, dp->rx_buf_end); /* Receive ring end page */
+       dp->rx_next = dp->rx_buf_start-1;
+       DP_OUT(base, DP_ISR, 0xFF);             /* Clear any pending interrupts */
+       DP_OUT(base, DP_IMR, DP_IMR_All);       /* Enable all interrupts */
+       DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1 | DP_CR_STOP);  /* Select page 1 */
+       DP_OUT(base, DP_P1_CURP, dp->rx_buf_start);   /* Current page - next free page for Rx */
+       for (i = 0;  i < ETHER_ADDR_LEN;  i++) {
+               DP_OUT(base, DP_P1_PAR0+i, enaddr[i]);
+       }
+       /* Enable and start device */
+       DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
+       DP_OUT(base, DP_TCR, DP_TCR_NORMAL); /* Normal transmit operations */
+       DP_OUT(base, DP_RCR, DP_RCR_AB);  /* Accept broadcast, no errors, no multicast */
+       dp->running = true;
+}
+
+/*
+  This routine is called to start the transmitter.  It is split out from the
+  data handling routine so it may be called either when data becomes first
+  available or when an Tx interrupt occurs
+*/
+
+static void
+dp83902a_start_xmit(int start_page, int len)
+{
+       dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *) &nic;
+       cyg_uint8 *base = dp->base;
+
+       DEBUG_FUNCTION();
+
+#if DEBUG & 1
+       printf("Tx pkt %d len %d\n", start_page, len);
+       if (dp->tx_started)
+               printf("TX already started?!?\n");
+#endif
+
+       DP_OUT(base, DP_ISR, (DP_ISR_TxP | DP_ISR_TxE));
+       DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
+       DP_OUT(base, DP_TBCL, len & 0xFF);
+       DP_OUT(base, DP_TBCH, len >> 8);
+       DP_OUT(base, DP_TPSR, start_page);
+       DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
+
+       dp->tx_started = true;
+}
+
+/*
+  This routine is called to send data to the hardware.  It is known a-priori
+  that there is free buffer space (dp->tx_next).
+*/
+static void
+dp83902a_send(unsigned char *data, int total_len, unsigned long key)
+{
+       struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
+       cyg_uint8 *base = dp->base;
+       int len, start_page, pkt_len, i, isr;
+#if DEBUG & 4
+       int dx;
+#endif
+
+       DEBUG_FUNCTION();
+
+       len = pkt_len = total_len;
+       if (pkt_len < IEEE_8023_MIN_FRAME) pkt_len = IEEE_8023_MIN_FRAME;
+
+       start_page = dp->tx_next;
+       if (dp->tx_next == dp->tx_buf1) {
+               dp->tx1 = start_page;
+               dp->tx1_len = pkt_len;
+               dp->tx1_key = key;
+               dp->tx_next = dp->tx_buf2;
+       } else {
+               dp->tx2 = start_page;
+               dp->tx2_len = pkt_len;
+               dp->tx2_key = key;
+               dp->tx_next = dp->tx_buf1;
+       }
+
+#if DEBUG & 5
+       printf("TX prep page %d len %d\n", start_page, pkt_len);
+#endif
+
+       DP_OUT(base, DP_ISR, DP_ISR_RDC);  /* Clear end of DMA */
+       {
+               /* Dummy read. The manual sez something slightly different, */
+               /* but the code is extended a bit to do what Hitachi's monitor */
+               /* does (i.e., also read data). */
+
+               cyg_uint16 tmp;
+               int len = 1;
+
+               DP_OUT(base, DP_RSAL, 0x100-len);
+               DP_OUT(base, DP_RSAH, (start_page-1) & 0xff);
+               DP_OUT(base, DP_RBCL, len);
+               DP_OUT(base, DP_RBCH, 0);
+               DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_RDMA | DP_CR_START);
+               DP_IN_DATA(dp->data, tmp);
+       }
+
+#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
+       /* Stall for a bit before continuing to work around random data */
+       /* corruption problems on some platforms. */
+       CYGACC_CALL_IF_DELAY_US(1);
+#endif
+
+       /* Send data to device buffer(s) */
+       DP_OUT(base, DP_RSAL, 0);
+       DP_OUT(base, DP_RSAH, start_page);
+       DP_OUT(base, DP_RBCL, pkt_len & 0xFF);
+       DP_OUT(base, DP_RBCH, pkt_len >> 8);
+       DP_OUT(base, DP_CR, DP_CR_WDMA | DP_CR_START);
+
+       /* Put data into buffer */
+#if DEBUG & 4
+       printf(" sg buf %08lx len %08x\n ", (unsigned long) data, len);
+       dx = 0;
+#endif
+       while (len > 0) {
+#if DEBUG & 4
+               printf(" %02x", *data);
+               if (0 == (++dx % 16)) printf("\n ");
+#endif
+               DP_OUT_DATA(dp->data, *data++);
+               len--;
+       }
+#if DEBUG & 4
+       printf("\n");
+#endif
+       if (total_len < pkt_len) {
+#if DEBUG & 4
+               printf("  + %d bytes of padding\n", pkt_len - total_len);
+#endif
+               /* Padding to 802.3 length was required */
+               for (i = total_len;  i < pkt_len;) {
+                       i++;
+                       DP_OUT_DATA(dp->data, 0);
+               }
+       }
+
+#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
+       /* After last data write, delay for a bit before accessing the */
+       /* device again, or we may get random data corruption in the last */
+       /* datum (on some platforms). */
+       CYGACC_CALL_IF_DELAY_US(1);
+#endif
+
+       /* Wait for DMA to complete */
+       do {
+               DP_IN(base, DP_ISR, isr);
+       } while ((isr & DP_ISR_RDC) == 0);
+       /* Then disable DMA */
+       DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
+
+       /* Start transmit if not already going */
+       if (!dp->tx_started) {
+               if (start_page == dp->tx1) {
+                       dp->tx_int = 1;  /* Expecting interrupt from BUF1 */
+               } else {
+                       dp->tx_int = 2;  /* Expecting interrupt from BUF2 */
+               }
+               dp83902a_start_xmit(start_page, pkt_len);
+       }
+}
+
+/*
+  This function is called when a packet has been received.  It's job is
+  to prepare to unload the packet from the hardware.  Once the length of
+  the packet is known, the upper layer of the driver can be told.  When
+  the upper layer is ready to unload the packet, the internal function
+  'dp83902a_recv' will be called to actually fetch it from the hardware.
+*/
+static void
+dp83902a_RxEvent(void)
+{
+       struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
+       cyg_uint8 *base = dp->base;
+       unsigned char rsr;
+       unsigned char rcv_hdr[4];
+       int i, len, pkt, cur;
+
+       DEBUG_FUNCTION();
+
+       DP_IN(base, DP_RSR, rsr);
+       while (true) {
+               /* Read incoming packet header */
+               DP_OUT(base, DP_CR, DP_CR_PAGE1 | DP_CR_NODMA | DP_CR_START);
+               DP_IN(base, DP_P1_CURP, cur);
+               DP_OUT(base, DP_P1_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
+               DP_IN(base, DP_BNDRY, pkt);
+
+               pkt += 1;
+               if (pkt == dp->rx_buf_end)
+                       pkt = dp->rx_buf_start;
+
+               if (pkt == cur) {
+                       break;
+               }
+               DP_OUT(base, DP_RBCL, sizeof(rcv_hdr));
+               DP_OUT(base, DP_RBCH, 0);
+               DP_OUT(base, DP_RSAL, 0);
+               DP_OUT(base, DP_RSAH, pkt);
+               if (dp->rx_next == pkt) {
+                       if (cur == dp->rx_buf_start)
+                               DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1);
+                       else
+                               DP_OUT(base, DP_BNDRY, cur-1); /* Update pointer */
+                       return;
+               }
+               dp->rx_next = pkt;
+               DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
+               DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
+#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
+               CYGACC_CALL_IF_DELAY_US(10);
+#endif
+
+               for (i = 0;  i < sizeof(rcv_hdr);) {
+                       DP_IN_DATA(dp->data, rcv_hdr[i++]);
+               }
+
+#if DEBUG & 5
+               printf("rx hdr %02x %02x %02x %02x\n",
+                      rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]);
+#endif
+               len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr);
+               uboot_push_packet_len(len);
+               if (rcv_hdr[1] == dp->rx_buf_start)
+                       DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1);
+               else
+                       DP_OUT(base, DP_BNDRY, rcv_hdr[1]-1); /* Update pointer */
+       }
+}
+
+/*
+  This function is called as a result of the "eth_drv_recv()" call above.
+  It's job is to actually fetch data for a packet from the hardware once
+  memory buffers have been allocated for the packet.  Note that the buffers
+  may come in pieces, using a scatter-gather list.  This allows for more
+  efficient processing in the upper layers of the stack.
+*/
+static void
+dp83902a_recv(unsigned char *data, int len)
+{
+       struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
+       cyg_uint8 *base = dp->base;
+       int i, mlen;
+       cyg_uint8 saved_char = 0;
+       bool saved;
+#if DEBUG & 4
+       int dx;
+#endif
+
+       DEBUG_FUNCTION();
+
+#if DEBUG & 5
+       printf("Rx packet %d length %d\n", dp->rx_next, len);
+#endif
+
+       /* Read incoming packet data */
+       DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
+       DP_OUT(base, DP_RBCL, len & 0xFF);
+       DP_OUT(base, DP_RBCH, len >> 8);
+       DP_OUT(base, DP_RSAL, 4);               /* Past header */
+       DP_OUT(base, DP_RSAH, dp->rx_next);
+       DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
+       DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
+#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
+       CYGACC_CALL_IF_DELAY_US(10);
+#endif
+
+       saved = false;
+       for (i = 0;  i < 1;  i++) {
+               if (data) {
+                       mlen = len;
+#if DEBUG & 4
+                       printf(" sg buf %08lx len %08x \n", (unsigned long) data, mlen);
+                       dx = 0;
+#endif
+                       while (0 < mlen) {
+                               /* Saved byte from previous loop? */
+                               if (saved) {
+                                       *data++ = saved_char;
+                                       mlen--;
+                                       saved = false;
+                                       continue;
+                               }
+
+                               {
+                                       cyg_uint8 tmp;
+                                       DP_IN_DATA(dp->data, tmp);
+#if DEBUG & 4
+                                       printf(" %02x", tmp);
+                                       if (0 == (++dx % 16)) printf("\n ");
+#endif
+                                       *data++ = tmp;;
+                                       mlen--;
+                               }
+                       }
+#if DEBUG & 4
+                       printf("\n");
+#endif
+               }
+       }
+}
+
+static void
+dp83902a_TxEvent(void)
+{
+       struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
+       cyg_uint8 *base = dp->base;
+       unsigned char tsr;
+       unsigned long key;
+
+       DEBUG_FUNCTION();
+
+       DP_IN(base, DP_TSR, tsr);
+       if (dp->tx_int == 1) {
+               key = dp->tx1_key;
+               dp->tx1 = 0;
+       } else {
+               key = dp->tx2_key;
+               dp->tx2 = 0;
+       }
+       /* Start next packet if one is ready */
+       dp->tx_started = false;
+       if (dp->tx1) {
+               dp83902a_start_xmit(dp->tx1, dp->tx1_len);
+               dp->tx_int = 1;
+       } else if (dp->tx2) {
+               dp83902a_start_xmit(dp->tx2, dp->tx2_len);
+               dp->tx_int = 2;
+       } else {
+               dp->tx_int = 0;
+       }
+       /* Tell higher level we sent this packet */
+       uboot_push_tx_done(key, 0);
+}
+
+/* Read the tally counters to clear them.  Called in response to a CNT */
+/* interrupt. */
+static void
+dp83902a_ClearCounters(void)
+{
+       struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
+       cyg_uint8 *base = dp->base;
+       cyg_uint8 cnt1, cnt2, cnt3;
+
+       DP_IN(base, DP_FER, cnt1);
+       DP_IN(base, DP_CER, cnt2);
+       DP_IN(base, DP_MISSED, cnt3);
+       DP_OUT(base, DP_ISR, DP_ISR_CNT);
+}
+
+/* Deal with an overflow condition.  This code follows the procedure set */
+/* out in section 7.0 of the datasheet. */
+static void
+dp83902a_Overflow(void)
+{
+       struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)&nic;
+       cyg_uint8 *base = dp->base;
+       cyg_uint8 isr;
+
+       /* Issue a stop command and wait 1.6ms for it to complete. */
+       DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA);
+       CYGACC_CALL_IF_DELAY_US(1600);
+
+       /* Clear the remote byte counter registers. */
+       DP_OUT(base, DP_RBCL, 0);
+       DP_OUT(base, DP_RBCH, 0);
+
+       /* Enter loopback mode while we clear the buffer. */
+       DP_OUT(base, DP_TCR, DP_TCR_LOCAL);
+       DP_OUT(base, DP_CR, DP_CR_START | DP_CR_NODMA);
+
+       /* Read in as many packets as we can and acknowledge any and receive */
+       /* interrupts.  Since the buffer has overflowed, a receive event of */
+       /* some kind will have occured. */
+       dp83902a_RxEvent();
+       DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE);
+
+       /* Clear the overflow condition and leave loopback mode. */
+       DP_OUT(base, DP_ISR, DP_ISR_OFLW);
+       DP_OUT(base, DP_TCR, DP_TCR_NORMAL);
+
+       /* If a transmit command was issued, but no transmit event has occured, */
+       /* restart it here. */
+       DP_IN(base, DP_ISR, isr);
+       if (dp->tx_started && !(isr & (DP_ISR_TxP|DP_ISR_TxE))) {
+               DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
+       }
+}
+
+static void
+dp83902a_poll(void)
+{
+       struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
+       cyg_uint8 *base = dp->base;
+       unsigned char isr;
+
+       DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0 | DP_CR_START);
+       DP_IN(base, DP_ISR, isr);
+       while (0 != isr) {
+               /* The CNT interrupt triggers when the MSB of one of the error */
+               /* counters is set.  We don't much care about these counters, but */
+               /* we should read their values to reset them. */
+               if (isr & DP_ISR_CNT) {
+                       dp83902a_ClearCounters();
+               }
+               /* Check for overflow.  It's a special case, since there's a */
+               /* particular procedure that must be followed to get back into */
+               /* a running state.a */
+               if (isr & DP_ISR_OFLW) {
+                       dp83902a_Overflow();
+               } else {
+                       /* Other kinds of interrupts can be acknowledged simply by */
+                       /* clearing the relevant bits of the ISR.  Do that now, then */
+                       /* handle the interrupts we care about. */
+                       DP_OUT(base, DP_ISR, isr);      /* Clear set bits */
+                       if (!dp->running) break;        /* Is this necessary? */
+                       /* Check for tx_started on TX event since these may happen */
+                       /* spuriously it seems. */
+                       if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) {
+                               dp83902a_TxEvent();
+                       }
+                       if (isr & (DP_ISR_RxP|DP_ISR_RxE)) {
+                               dp83902a_RxEvent();
+                       }
+               }
+               DP_IN(base, DP_ISR, isr);
+       }
+}
+
+/* find prom (taken from pc_net_cs.c from Linux) */
+
+#include "8390.h"
+
+typedef struct hw_info_t {
+       u_int   offset;
+       u_char  a0, a1, a2;
+       u_int   flags;
+} hw_info_t;
+
+#define DELAY_OUTPUT   0x01
+#define HAS_MISC_REG   0x02
+#define USE_BIG_BUF    0x04
+#define HAS_IBM_MISC   0x08
+#define IS_DL10019     0x10
+#define IS_DL10022     0x20
+#define HAS_MII                0x40
+#define USE_SHMEM      0x80    /* autodetected */
+
+#define AM79C9XX_HOME_PHY      0x00006B90  /* HomePNA PHY */
+#define AM79C9XX_ETH_PHY       0x00006B70  /* 10baseT PHY */
+#define MII_PHYID_REV_MASK     0xfffffff0
+#define MII_PHYID_REG1         0x02
+#define MII_PHYID_REG2         0x03
+
+static hw_info_t hw_info[] = {
+       { /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT },
+       { /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 },
+       { /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 },
+       { /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94,
+         DELAY_OUTPUT | HAS_IBM_MISC },
+       { /* Danpex EN-6200P2 */ 0x0110, 0x00, 0x40, 0xc7, 0 },
+       { /* DataTrek NetCard */ 0x0ff0, 0x00, 0x20, 0xe8, 0 },
+       { /* Dayna CommuniCard E */ 0x0110, 0x00, 0x80, 0x19, 0 },
+       { /* D-Link DE-650 */ 0x0040, 0x00, 0x80, 0xc8, 0 },
+       { /* EP-210 Ethernet */ 0x0110, 0x00, 0x40, 0x33, 0 },
+       { /* EP4000 Ethernet */ 0x01c0, 0x00, 0x00, 0xb4, 0 },
+       { /* Epson EEN10B */ 0x0ff0, 0x00, 0x00, 0x48,
+         HAS_MISC_REG | HAS_IBM_MISC },
+       { /* ELECOM Laneed LD-CDWA */ 0xb8, 0x08, 0x00, 0x42, 0 },
+       { /* Hypertec Ethernet */ 0x01c0, 0x00, 0x40, 0x4c, 0 },
+       { /* IBM CCAE */ 0x0ff0, 0x08, 0x00, 0x5a,
+         HAS_MISC_REG | HAS_IBM_MISC },
+       { /* IBM CCAE */ 0x0ff0, 0x00, 0x04, 0xac,
+         HAS_MISC_REG | HAS_IBM_MISC },
+       { /* IBM CCAE */ 0x0ff0, 0x00, 0x06, 0x29,
+         HAS_MISC_REG | HAS_IBM_MISC },
+       { /* IBM FME */ 0x0374, 0x08, 0x00, 0x5a,
+         HAS_MISC_REG | HAS_IBM_MISC },
+       { /* IBM FME */ 0x0374, 0x00, 0x04, 0xac,
+         HAS_MISC_REG | HAS_IBM_MISC },
+       { /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87,
+         HAS_MISC_REG | HAS_IBM_MISC },
+       { /* NSC DP83903 */ 0x0374, 0x08, 0x00, 0x17,
+         HAS_MISC_REG | HAS_IBM_MISC },
+       { /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8,
+         HAS_MISC_REG | HAS_IBM_MISC },
+       { /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0,
+         HAS_MISC_REG | HAS_IBM_MISC },
+       { /* NSC DP83903 */ 0x0198, 0x00, 0x20, 0xe0,
+         HAS_MISC_REG | HAS_IBM_MISC },
+       { /* I-O DATA PCLA/T */ 0x0ff0, 0x00, 0xa0, 0xb0, 0 },
+       { /* Katron PE-520 */ 0x0110, 0x00, 0x40, 0xf6, 0 },
+       { /* Kingston KNE-PCM/x */ 0x0ff0, 0x00, 0xc0, 0xf0,
+         HAS_MISC_REG | HAS_IBM_MISC },
+       { /* Kingston KNE-PCM/x */ 0x0ff0, 0xe2, 0x0c, 0x0f,
+         HAS_MISC_REG | HAS_IBM_MISC },
+       { /* Kingston KNE-PC2 */ 0x0180, 0x00, 0xc0, 0xf0, 0 },
+       { /* Maxtech PCN2000 */ 0x5000, 0x00, 0x00, 0xe8, 0 },
+       { /* NDC Instant-Link */ 0x003a, 0x00, 0x80, 0xc6, 0 },
+       { /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 },
+       { /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65,
+         HAS_MISC_REG | HAS_IBM_MISC },
+       { /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45,
+         HAS_MISC_REG | HAS_IBM_MISC },
+       { /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 },
+       { /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 },
+       { /* SCM Ethernet */ 0x0ff0, 0x00, 0x20, 0xcb, 0 },
+       { /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b,
+         DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF },
+       { /* Socket LP-E CF+ */ 0x01c0, 0x00, 0xc0, 0x1b, 0 },
+       { /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 },
+       { /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 },
+       { /* NEC PC-9801N-J12 */ 0x0ff0, 0x00, 0x00, 0x4c, 0 },
+       { /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 },
+       { /* Qemu */ 0x0, 0x52, 0x54, 0x00, 0 }
+};
+
+#define NR_INFO                (sizeof(hw_info)/sizeof(hw_info_t))
+
+static hw_info_t default_info = { 0, 0, 0, 0, 0 };
+
+unsigned char dev_addr[6];
+
+#define PCNET_CMD      0x00
+#define PCNET_DATAPORT 0x10    /* NatSemi-defined port window offset. */
+#define PCNET_RESET    0x1f    /* Issue a read to reset, a write to clear. */
+#define PCNET_MISC     0x18    /* For IBM CCAE and Socket EA cards */
+
+unsigned long nic_base;
+
+static void pcnet_reset_8390(void)
+{
+       int i, r;
+
+       PRINTK("nic base is %lx\n", nic_base);
+
+       n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
+       PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD));
+       n2k_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, E8390_CMD);
+       PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD));
+       n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
+       PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD));
+       n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
+
+       n2k_outb(n2k_inb(PCNET_RESET), PCNET_RESET);
+
+       for (i = 0; i < 100; i++) {
+               if ((r = (n2k_inb(EN0_ISR) & ENISR_RESET)) != 0)
+                       break;
+               PRINTK("got %x in reset\n", r);
+               my_udelay(100);
+       }
+       n2k_outb(ENISR_RESET, EN0_ISR); /* Ack intr. */
+
+       if (i == 100)
+               printf("pcnet_reset_8390() did not complete.\n");
+} /* pcnet_reset_8390 */
+
+static hw_info_t * get_prom(void ) {
+       unsigned char prom[32];
+       int i, j;
+       struct {
+               u_char value, offset;
+       } program_seq[] = {
+               {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
+               {0x48,  EN0_DCFG},      /* Set byte-wide (0x48) access. */
+               {0x00,  EN0_RCNTLO},    /* Clear the count regs. */
+               {0x00,  EN0_RCNTHI},
+               {0x00,  EN0_IMR},       /* Mask completion irq. */
+               {0xFF,  EN0_ISR},
+               {E8390_RXOFF, EN0_RXCR},        /* 0x20  Set to monitor */
+               {E8390_TXOFF, EN0_TXCR},        /* 0x02  and loopback mode. */
+               {32,    EN0_RCNTLO},
+               {0x00,  EN0_RCNTHI},
+               {0x00,  EN0_RSARLO},    /* DMA starting at 0x0000. */
+               {0x00,  EN0_RSARHI},
+               {E8390_RREAD+E8390_START, E8390_CMD},
+       };
+
+       PRINTK("trying to get MAC via prom reading\n");
+
+       pcnet_reset_8390();
+
+       mdelay(10);
+
+       for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
+               n2k_outb(program_seq[i].value, program_seq[i].offset);
+
+       PRINTK("PROM:");
+       for (i = 0; i < 32; i++) {
+               prom[i] = n2k_inb(PCNET_DATAPORT);
+               PRINTK(" %02x", prom[i]);
+       }
+       PRINTK("\n");
+       for (i = 0; i < NR_INFO; i++) {
+               if ((prom[0] == hw_info[i].a0) &&
+                   (prom[2] == hw_info[i].a1) &&
+                   (prom[4] == hw_info[i].a2)) {
+                       PRINTK("matched board %d\n", i);
+                       break;
+               }
+       }
+       if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) {
+               for (j = 0; j < 6; j++)
+                       dev_addr[j] = prom[j<<1];
+               PRINTK("on exit i is %d/%ld\n", i, NR_INFO);
+               PRINTK("MAC address is %02x:%02x:%02x:%02x:%02x:%02x\n",
+                      dev_addr[0],dev_addr[1],dev_addr[2],dev_addr[3],dev_addr[4],dev_addr[5]);
+               return (i < NR_INFO) ? hw_info+i : &default_info;
+       }
+       return NULL;
+}
+
+/* U-boot specific routines */
+
+
+static unsigned char *pbuf = NULL;
+
+static int pkey = -1;
+static int initialized=0;
+
+void uboot_push_packet_len(int len) {
+       PRINTK("pushed len = %d\n", len);
+       if (len>=2000) {
+               printf("NE2000: packet too big\n");
+               return;
+       }
+       dp83902a_recv(&pbuf[0], len);
+
+       /*Just pass it to the upper layer*/
+       NetReceive(&pbuf[0], len);
+}
+
+void uboot_push_tx_done(int key, int val) {
+       PRINTK("pushed key = %d\n", key);
+       pkey = key;
+}
+
+int eth_init(bd_t *bd) {
+       static hw_info_t * r;
+       char ethaddr[20];
+
+       PRINTK("### eth_init\n");
+
+       if (!pbuf) {
+               pbuf = malloc(2000);
+               if (!pbuf) {
+                       printf("Cannot allocate rx buffer\n");
+                       return -1;
+               }
+       }
+
+#ifdef CONFIG_DRIVER_NE2000_CCR
+       {
+               volatile unsigned char *p =  (volatile unsigned char *) CONFIG_DRIVER_NE2000_CCR;
+
+               PRINTK("CCR before is %x\n", *p);
+               *p = CONFIG_DRIVER_NE2000_VAL;
+               PRINTK("CCR after is %x\n", *p);
+       }
+#endif
+
+       nic_base = CONFIG_DRIVER_NE2000_BASE;
+       nic.base = (cyg_uint8 *) CONFIG_DRIVER_NE2000_BASE;
+
+       r = get_prom();
+       if (!r)
+               return -1;
+
+       sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
+                dev_addr[0], dev_addr[1],
+                dev_addr[2], dev_addr[3],
+                dev_addr[4], dev_addr[5]) ;
+       PRINTK("Set environment from HW MAC addr = \"%s\"\n", ethaddr);
+       setenv ("ethaddr", ethaddr);
+
+
+#define DP_DATA                0x10
+       nic.data = nic.base + DP_DATA;
+       nic.tx_buf1 = 0x40;
+       nic.tx_buf2 = 0x48;
+       nic.rx_buf_start = 0x50;
+       nic.rx_buf_end = 0x80;
+
+       if (dp83902a_init() == false)
+               return -1;
+       dp83902a_start(dev_addr);
+       initialized=1;
+       return 0;
+}
+
+void eth_halt() {
+
+       PRINTK("### eth_halt\n");
+       if(initialized)
+               dp83902a_stop();
+       initialized=0;
+}
+
+int eth_rx() {
+dp83902a_poll();
+return 1;
+}
+
+int eth_send(volatile void *packet, int length) {
+       int tmo;
+
+       PRINTK("### eth_send\n");
+
+       pkey = -1;
+
+       dp83902a_send((unsigned char *) packet, length, 666);
+       tmo = get_timer (0) + TOUT * CFG_HZ;
+       while(1) {
+               dp83902a_poll();
+               if (pkey != -1) {
+                       PRINTK("Packet sucesfully sent\n");
+                       return 0;
+               }
+               if (get_timer (0) >= tmo) {
+                       printf("transmission error (timoeut)\n");
+                       return 0;
+               }
+
+       }
+       return 0;
+}
+#endif
diff --git a/drivers/net/ne2000.h b/drivers/net/ne2000.h
new file mode 100644 (file)
index 0000000..c13d9f0
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+Ported to U-Boot  by Christian Pellegrin <chri@ascensit.com>
+
+Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
+eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
+are GPL, so this is, of course, GPL.
+
+
+==========================================================================
+
+      dev/dp83902a.h
+
+      National Semiconductor DP83902a ethernet chip
+
+==========================================================================
+####ECOSGPLCOPYRIGHTBEGIN####
+ -------------------------------------------
+ This file is part of eCos, the Embedded Configurable Operating System.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+
+ eCos is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2 or (at your option) any later version.
+
+ eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with eCos; if not, write to the Free Software Foundation, Inc.,
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+ As a special exception, if other files instantiate templates or use macros
+ or inline functions from this file, or you compile this file and link it
+ with other works to produce a work based on this file, this file does not
+ by itself cause the resulting work to be covered by the GNU General Public
+ License. However the source code for this file must still be made available
+ in accordance with section (3) of the GNU General Public License.
+
+ This exception does not invalidate any other reasons why a work based on
+ this file might be covered by the GNU General Public License.
+
+ Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+ at http://sources.redhat.com/ecos/ecos-license/
+ -------------------------------------------
+####ECOSGPLCOPYRIGHTEND####
+####BSDCOPYRIGHTBEGIN####
+
+ -------------------------------------------
+
+ Portions of this software may have been derived from OpenBSD or other sources,
+ and are covered by the appropriate copyright disclaimers included herein.
+
+ -------------------------------------------
+
+####BSDCOPYRIGHTEND####
+==========================================================================
+#####DESCRIPTIONBEGIN####
+
+ Author(s):    gthomas
+ Contributors: gthomas, jskov
+ Date:         2001-06-13
+ Purpose:
+ Description:
+
+####DESCRIPTIONEND####
+
+==========================================================================
+
+*/
+
+/*
+ ------------------------------------------------------------------------
+ Macros for accessing DP registers
+ These can be overridden by the platform header
+*/
+
+#define DP_IN(_b_, _o_, _d_)  (_d_) = *( (volatile unsigned char *) ((_b_)+(_o_)))
+#define DP_OUT(_b_, _o_, _d_) *( (volatile unsigned char *) ((_b_)+(_o_))) = (_d_)
+
+#define DP_IN_DATA(_b_, _d_)  (_d_) = *( (volatile unsigned char *) ((_b_)))
+#define DP_OUT_DATA(_b_, _d_) *( (volatile unsigned char *) ((_b_))) = (_d_)
+
+
+/* here is all the data */
+
+#define cyg_uint8 unsigned char
+#define cyg_uint16 unsigned short
+#define bool int
+
+#define false 0
+#define true 1
+
+#define CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA 1
+#define CYGACC_CALL_IF_DELAY_US(X) my_udelay(X)
+
+typedef struct dp83902a_priv_data {
+    cyg_uint8* base;
+    cyg_uint8* data;
+    cyg_uint8* reset;
+    int tx_next;           /* First free Tx page */
+    int tx_int;            /* Expecting interrupt from this buffer */
+    int rx_next;           /* First free Rx page */
+    int tx1, tx2;          /* Page numbers for Tx buffers */
+    unsigned long tx1_key, tx2_key;   /* Used to ack when packet sent */
+    int tx1_len, tx2_len;
+    bool tx_started, running, hardwired_esa;
+    cyg_uint8 esa[6];
+    void* plf_priv;
+
+    /* Buffer allocation */
+    int tx_buf1, tx_buf2;
+    int rx_buf_start, rx_buf_end;
+} dp83902a_priv_data_t;
+
+/*
+ ------------------------------------------------------------------------
+ Some forward declarations
+*/
+static void dp83902a_poll(void);
+
+/* ------------------------------------------------------------------------ */
+/* Register offsets */
+
+#define DP_CR          0x00
+#define DP_CLDA0       0x01
+#define DP_PSTART      0x01             /* write */
+#define DP_CLDA1       0x02
+#define DP_PSTOP       0x02             /* write */
+#define DP_BNDRY       0x03
+#define DP_TSR         0x04
+#define DP_TPSR        0x04             /* write */
+#define DP_NCR         0x05
+#define DP_TBCL        0x05             /* write */
+#define DP_FIFO        0x06
+#define DP_TBCH        0x06             /* write */
+#define DP_ISR         0x07
+#define DP_CRDA0       0x08
+#define DP_RSAL        0x08             /* write */
+#define DP_CRDA1       0x09
+#define DP_RSAH        0x09             /* write */
+#define DP_RBCL        0x0a             /* write */
+#define DP_RBCH        0x0b             /* write */
+#define DP_RSR         0x0c
+#define DP_RCR         0x0c             /* write */
+#define DP_FER         0x0d
+#define DP_TCR         0x0d             /* write */
+#define DP_CER         0x0e
+#define DP_DCR         0x0e             /* write */
+#define DP_MISSED      0x0f
+#define DP_IMR         0x0f             /* write */
+#define DP_DATAPORT    0x10             /* "eprom" data port */
+
+#define DP_P1_CR       0x00
+#define DP_P1_PAR0     0x01
+#define DP_P1_PAR1     0x02
+#define DP_P1_PAR2     0x03
+#define DP_P1_PAR3     0x04
+#define DP_P1_PAR4     0x05
+#define DP_P1_PAR5     0x06
+#define DP_P1_CURP     0x07
+#define DP_P1_MAR0     0x08
+#define DP_P1_MAR1     0x09
+#define DP_P1_MAR2     0x0a
+#define DP_P1_MAR3     0x0b
+#define DP_P1_MAR4     0x0c
+#define DP_P1_MAR5     0x0d
+#define DP_P1_MAR6     0x0e
+#define DP_P1_MAR7     0x0f
+
+#define DP_P2_CR       0x00
+#define DP_P2_PSTART   0x01
+#define DP_P2_CLDA0    0x01             /* write */
+#define DP_P2_PSTOP    0x02
+#define DP_P2_CLDA1    0x02             /* write */
+#define DP_P2_RNPP     0x03
+#define DP_P2_TPSR     0x04
+#define DP_P2_LNPP     0x05
+#define DP_P2_ACH      0x06
+#define DP_P2_ACL      0x07
+#define DP_P2_RCR      0x0c
+#define DP_P2_TCR      0x0d
+#define DP_P2_DCR      0x0e
+#define DP_P2_IMR      0x0f
+
+/* Command register - common to all pages */
+
+#define DP_CR_STOP    0x01   /* Stop: software reset */
+#define DP_CR_START   0x02   /* Start: initialize device */
+#define DP_CR_TXPKT   0x04   /* Transmit packet */
+#define DP_CR_RDMA    0x08   /* Read DMA  (recv data from device) */
+#define DP_CR_WDMA    0x10   /* Write DMA (send data to device) */
+#define DP_CR_SEND    0x18   /* Send packet */
+#define DP_CR_NODMA   0x20   /* Remote (or no) DMA */
+#define DP_CR_PAGE0   0x00   /* Page select */
+#define DP_CR_PAGE1   0x40
+#define DP_CR_PAGE2   0x80
+#define DP_CR_PAGEMSK 0x3F   /* Used to mask out page bits */
+
+/* Data configuration register */
+
+#define DP_DCR_WTS    0x01   /* 1=16 bit word transfers */
+#define DP_DCR_BOS    0x02   /* 1=Little Endian */
+#define DP_DCR_LAS    0x04   /* 1=Single 32 bit DMA mode */
+#define DP_DCR_LS     0x08   /* 1=normal mode, 0=loopback */
+#define DP_DCR_ARM    0x10   /* 0=no send command (program I/O) */
+#define DP_DCR_FIFO_1 0x00   /* FIFO threshold */
+#define DP_DCR_FIFO_2 0x20
+#define DP_DCR_FIFO_4 0x40
+#define DP_DCR_FIFO_6 0x60
+
+#define DP_DCR_INIT   (DP_DCR_LS|DP_DCR_FIFO_4)
+
+/* Interrupt status register */
+
+#define DP_ISR_RxP    0x01   /* Packet received */
+#define DP_ISR_TxP    0x02   /* Packet transmitted */
+#define DP_ISR_RxE    0x04   /* Receive error */
+#define DP_ISR_TxE    0x08   /* Transmit error */
+#define DP_ISR_OFLW   0x10   /* Receive overflow */
+#define DP_ISR_CNT    0x20   /* Tally counters need emptying */
+#define DP_ISR_RDC    0x40   /* Remote DMA complete */
+#define DP_ISR_RESET  0x80   /* Device has reset (shutdown, error) */
+
+/* Interrupt mask register */
+
+#define DP_IMR_RxP    0x01   /* Packet received */
+#define DP_IMR_TxP    0x02   /* Packet transmitted */
+#define DP_IMR_RxE    0x04   /* Receive error */
+#define DP_IMR_TxE    0x08   /* Transmit error */
+#define DP_IMR_OFLW   0x10   /* Receive overflow */
+#define DP_IMR_CNT    0x20   /* Tall counters need emptying */
+#define DP_IMR_RDC    0x40   /* Remote DMA complete */
+
+#define DP_IMR_All    0x3F   /* Everything but remote DMA */
+
+/* Receiver control register */
+
+#define DP_RCR_SEP    0x01   /* Save bad(error) packets */
+#define DP_RCR_AR     0x02   /* Accept runt packets */
+#define DP_RCR_AB     0x04   /* Accept broadcast packets */
+#define DP_RCR_AM     0x08   /* Accept multicast packets */
+#define DP_RCR_PROM   0x10   /* Promiscuous mode */
+#define DP_RCR_MON    0x20   /* Monitor mode - 1=accept no packets */
+
+/* Receiver status register */
+
+#define DP_RSR_RxP    0x01   /* Packet received */
+#define DP_RSR_CRC    0x02   /* CRC error */
+#define DP_RSR_FRAME  0x04   /* Framing error */
+#define DP_RSR_FO     0x08   /* FIFO overrun */
+#define DP_RSR_MISS   0x10   /* Missed packet */
+#define DP_RSR_PHY    0x20   /* 0=pad match, 1=mad match */
+#define DP_RSR_DIS    0x40   /* Receiver disabled */
+#define DP_RSR_DFR    0x80   /* Receiver processing deferred */
+
+/* Transmitter control register */
+
+#define DP_TCR_NOCRC  0x01   /* 1=inhibit CRC */
+#define DP_TCR_NORMAL 0x00   /* Normal transmitter operation */
+#define DP_TCR_LOCAL  0x02   /* Internal NIC loopback */
+#define DP_TCR_INLOOP 0x04   /* Full internal loopback */
+#define DP_TCR_OUTLOOP 0x08  /* External loopback */
+#define DP_TCR_ATD    0x10   /* Auto transmit disable */
+#define DP_TCR_OFFSET 0x20   /* Collision offset adjust */
+
+/* Transmit status register */
+
+#define DP_TSR_TxP    0x01   /* Packet transmitted */
+#define DP_TSR_COL    0x04   /* Collision (at least one) */
+#define DP_TSR_ABT    0x08   /* Aborted because of too many collisions */
+#define DP_TSR_CRS    0x10   /* Lost carrier */
+#define DP_TSR_FU     0x20   /* FIFO underrun */
+#define DP_TSR_CDH    0x40   /* Collision Detect Heartbeat */
+#define DP_TSR_OWC    0x80   /* Collision outside normal window */
+
+#define IEEE_8023_MAX_FRAME         1518    /* Largest possible ethernet frame */
+#define IEEE_8023_MIN_FRAME           64    /* Smallest possible ethernet frame */
diff --git a/drivers/net/netarm_eth.c b/drivers/net/netarm_eth.c
new file mode 100644 (file)
index 0000000..a99ee5d
--- /dev/null
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2004 IMMS gGmbH <www.imms.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * author(s): Thomas Elste, <info@elste.org>
+ *            (some parts derived from uCLinux Netarm Ethernet Driver)
+ */
+
+
+#include <common.h>
+
+#ifdef CONFIG_DRIVER_NETARMETH
+#include <command.h>
+#include <net.h>
+#include "netarm_eth.h"
+#include <asm/arch/netarm_registers.h>
+
+
+#if defined(CONFIG_CMD_NET)
+
+static int na_mii_poll_busy (void);
+
+static void na_get_mac_addr (void)
+{
+       unsigned short p[3];
+       char *m_addr;
+       char ethaddr[20];
+
+       m_addr = (char *) p;
+
+       p[0] = (unsigned short) GET_EADDR (NETARM_ETH_SAL_STATION_ADDR_1);
+       p[1] = (unsigned short) GET_EADDR (NETARM_ETH_SAL_STATION_ADDR_2);
+       p[2] = (unsigned short) GET_EADDR (NETARM_ETH_SAL_STATION_ADDR_3);
+
+       sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
+                m_addr[0], m_addr[1],
+                m_addr[2], m_addr[3], m_addr[4], m_addr[5]);
+
+       printf ("HW-MAC Address:  %s\n", ethaddr);
+
+       /* set env, todo: check if already an adress is set */
+       setenv ("ethaddr", ethaddr);
+}
+
+
+static void na_mii_write (int reg, int value)
+{
+       int mii_addr;
+
+       /* Select register */
+       mii_addr = CFG_ETH_PHY_ADDR + reg;
+       SET_EADDR (NETARM_ETH_MII_ADDR, mii_addr);
+       /* Write value */
+       SET_EADDR (NETARM_ETH_MII_WRITE, value);
+       na_mii_poll_busy ();
+}
+
+static unsigned int na_mii_read (int reg)
+{
+       int mii_addr, val;
+
+       /* Select register */
+       mii_addr = CFG_ETH_PHY_ADDR + reg;
+       SET_EADDR (NETARM_ETH_MII_ADDR, mii_addr);
+       /* do one management cycle */
+       SET_EADDR (NETARM_ETH_MII_CMD,
+                  GET_EADDR (NETARM_ETH_MII_CMD) | NETARM_ETH_MIIC_RSTAT);
+       na_mii_poll_busy ();
+       /* Return read value */
+       val = GET_EADDR (NETARM_ETH_MII_READ);
+       return val;
+}
+
+static int na_mii_poll_busy (void)
+{
+       /* arm simple, non interrupt dependent timer */
+       reset_timer_masked ();
+       while (get_timer_masked () < NA_MII_POLL_BUSY_DELAY) {
+               if (!(GET_EADDR (NETARM_ETH_MII_IND) & NETARM_ETH_MIII_BUSY)) {
+                       return 1;
+               }
+       }
+       printf ("na_mii_busy timeout\n");
+       return (0);
+}
+
+static int na_mii_identify_phy (void)
+{
+       int id_reg_a = 0;
+
+       /* get phy id register */
+       id_reg_a = na_mii_read (MII_PHY_ID);
+
+       if (id_reg_a == 0x0043) {
+               /* This must be an Enable or a Lucent LU3X31 PHY chip */
+               return 1;
+       } else if (id_reg_a == 0x0013) {
+               /* it is an Intel LXT971A */
+               return 1;
+       }
+       return (0);
+}
+
+static int na_mii_negotiate (void)
+{
+       int i = 0;
+
+       /* Enable auto-negotiation */
+       na_mii_write (MII_PHY_AUTONEGADV, 0x01e1);
+       /* FIXME: 0x01E1 is 100Mb half and full duplex, 0x0061 is 10Mb only */
+       /* Restart auto-negotiation */
+       na_mii_write (MII_PHY_CONTROL, 0x1200);
+
+       /* status register is 0xffff after setting the autoneg restart bit */
+       while (na_mii_read (MII_PHY_STATUS) == 0xffff) {
+               i++;
+       }
+
+       /* na_mii_read uses the timer already, so we can't use it again for
+          timeout checking.
+          Instead we just try some times.
+        */
+       for (i = 0; i < 40000; i++) {
+               if ((na_mii_read (MII_PHY_STATUS) & 0x0024) == 0x0024) {
+                       return 0;
+               }
+       }
+       /*
+          printf("*Warning* autonegotiation timeout, status: 0x%x\n",na_mii_read(MII_PHY_STATUS));
+        */
+       return (1);
+}
+
+static unsigned int na_mii_check_speed (void)
+{
+       unsigned int status;
+
+       /* Read Status register */
+       status = na_mii_read (MII_PHY_STATUS);
+       /* Check link status.  If 0, default to 100 Mbps. */
+       if ((status & 0x0004) == 0) {
+               printf ("*Warning* no link detected, set default speed to 100Mbs\n");
+               return 1;
+       } else {
+               if ((na_mii_read (17) & 0x4000) != 0) {
+                       printf ("100Mbs link detected\n");
+                       return 1;
+               } else {
+                       printf ("10Mbs link detected\n");
+                       return 0;
+               }
+       }
+       return 0;
+}
+
+static int reset_eth (void)
+{
+       int pt;
+
+       na_get_mac_addr ();
+       pt = na_mii_identify_phy ();
+
+       /* reset the phy */
+       na_mii_write (MII_PHY_CONTROL, 0x8000);
+       reset_timer_masked ();
+       while (get_timer_masked () < NA_MII_NEGOTIATE_DELAY) {
+               if ((na_mii_read (MII_PHY_STATUS) & 0x8000) == 0) {
+                       break;
+               }
+       }
+       if (get_timer_masked () >= NA_MII_NEGOTIATE_DELAY)
+               printf ("phy reset timeout\n");
+
+       /* set the PCS reg */
+       SET_EADDR (NETARM_ETH_PCS_CFG, NETARM_ETH_PCSC_CLKS_25M |
+                  NETARM_ETH_PCSC_ENJAB | NETARM_ETH_PCSC_NOCFR);
+
+       na_mii_negotiate ();
+       na_mii_check_speed ();
+
+       /* Delay 10 millisecond.  (Maybe this should be 1 second.) */
+       udelay (10000);
+
+       /* Turn receive on.
+          Enable statistics register autozero on read.
+          Do not insert MAC address on transmit.
+          Do not enable special test modes.  */
+       SET_EADDR (NETARM_ETH_STL_CFG,
+                  (NETARM_ETH_STLC_AUTOZ | NETARM_ETH_STLC_RXEN));
+
+       /* Set the inter-packet gap delay to 0.96us for MII.
+          The NET+ARM H/W Reference Guide indicates that the Back-to-back IPG
+          Gap Timer Register should be set to 0x15 and the Non Back-to-back IPG
+          Gap Timer Register should be set to 0x00000C12 for the MII PHY. */
+       SET_EADDR (NETARM_ETH_B2B_IPG_GAP_TMR, 0x15);
+       SET_EADDR (NETARM_ETH_NB2B_IPG_GAP_TMR, 0x00000C12);
+
+       /* Add CRC to end of packets.
+          Pad packets to minimum length of 64 bytes.
+          Allow unlimited length transmit packets.
+          Receive all broadcast packets.
+          NOTE:  Multicast addressing is NOT enabled here currently. */
+       SET_EADDR (NETARM_ETH_MAC_CFG,
+                  (NETARM_ETH_MACC_CRCEN |
+                   NETARM_ETH_MACC_PADEN | NETARM_ETH_MACC_HUGEN));
+       SET_EADDR (NETARM_ETH_SAL_FILTER, NETARM_ETH_SALF_BROAD);
+
+       /* enable fifos */
+       SET_EADDR (NETARM_ETH_GEN_CTRL,
+                  (NETARM_ETH_GCR_ERX | NETARM_ETH_GCR_ETX));
+
+       return (0);
+}
+
+
+extern int eth_init (bd_t * bd)
+{
+       reset_eth ();
+       return 0;
+}
+
+extern void eth_halt (void)
+{
+       SET_EADDR (NETARM_ETH_GEN_CTRL, 0);
+}
+
+/* Get a data block via Ethernet */
+extern int eth_rx (void)
+{
+       int i;
+       unsigned short rxlen;
+       unsigned int *addr;
+       unsigned int rxstatus, lastrxlen;
+       char *pa;
+
+       /* RXBR is 1, data block was received */
+       if ((GET_EADDR (NETARM_ETH_GEN_STAT) & NETARM_ETH_GST_RXBR) == 0)
+               return 0;
+
+       /* get status register and the length of received block */
+       rxstatus = GET_EADDR (NETARM_ETH_RX_STAT);
+       rxlen = (rxstatus & NETARM_ETH_RXSTAT_SIZE) >> 16;
+
+       if (rxlen == 0)
+               return 0;
+
+       /* clear RXBR to make fifo available */
+       SET_EADDR (NETARM_ETH_GEN_STAT,
+                  GET_EADDR (NETARM_ETH_GEN_STAT) & ~NETARM_ETH_GST_RXBR);
+
+       /* clear TXBC to make fifo available */
+       /* According to NETARM50 data manual you just have to clear
+          RXBR but that has no effect. Only after clearing TXBC the
+          Fifo becomes readable. */
+       SET_EADDR (NETARM_ETH_GEN_STAT,
+                  GET_EADDR (NETARM_ETH_GEN_STAT) & ~NETARM_ETH_GST_TXBC);
+
+       addr = (unsigned int *) NetRxPackets[0];
+       pa = (char *) NetRxPackets[0];
+
+       /* read the fifo */
+       for (i = 0; i < rxlen / 4; i++) {
+               *addr = GET_EADDR (NETARM_ETH_FIFO_DAT1);
+               addr++;
+       }
+
+       if (GET_EADDR (NETARM_ETH_GEN_STAT) & NETARM_ETH_GST_RXREGR) {
+               /* RXFDB indicates wether the last word is 1,2,3 or 4 bytes long */
+               lastrxlen =
+                       (GET_EADDR (NETARM_ETH_GEN_STAT) &
+                        NETARM_ETH_GST_RXFDB) >> 28;
+               *addr = GET_EADDR (NETARM_ETH_FIFO_DAT1);
+               switch (lastrxlen) {
+               case 1:
+                       *addr &= 0xff000000;
+                       break;
+               case 2:
+                       *addr &= 0xffff0000;
+                       break;
+               case 3:
+                       *addr &= 0xffffff00;
+                       break;
+               }
+       }
+
+       /* Pass the packet up to the protocol layers. */
+       NetReceive (NetRxPackets[0], rxlen);
+
+       return rxlen;
+}
+
+/* Send a data block via Ethernet. */
+extern int eth_send (volatile void *packet, int length)
+{
+       int i, length32;
+       char *pa;
+       unsigned int *pa32, lastp = 0, rest;
+
+       pa = (char *) packet;
+       pa32 = (unsigned int *) packet;
+       length32 = length / 4;
+       rest = length % 4;
+
+       /* make sure there's no garbage in the last word */
+       switch (rest) {
+       case 0:
+               lastp = pa32[length32];
+               length32--;
+               break;
+       case 1:
+               lastp = pa32[length32] & 0x000000ff;
+               break;
+       case 2:
+               lastp = pa32[length32] & 0x0000ffff;
+               break;
+       case 3:
+               lastp = pa32[length32] & 0x00ffffff;
+               break;
+       }
+
+       /* write to the fifo */
+       for (i = 0; i < length32; i++)
+               SET_EADDR (NETARM_ETH_FIFO_DAT1, pa32[i]);
+
+       /* the last word is written to an extra register, this
+          starts the transmission */
+       SET_EADDR (NETARM_ETH_FIFO_DAT2, lastp);
+
+       /* NETARM_ETH_TXSTAT_TXOK should be checked, to know if the transmission
+          went fine. But we can't use the timer for a timeout loop because
+          of it is used already in upper layers. So we just try some times. */
+       i = 0;
+       while (i < 50000) {
+               if ((GET_EADDR (NETARM_ETH_TX_STAT) & NETARM_ETH_TXSTAT_TXOK)
+                   == NETARM_ETH_TXSTAT_TXOK)
+                       return 0;
+               i++;
+       }
+
+       printf ("eth_send timeout\n");
+       return 1;
+}
+
+#endif /* COMMANDS & CFG_NET */
+
+#endif /* CONFIG_DRIVER_NETARMETH */
diff --git a/drivers/net/netarm_eth.h b/drivers/net/netarm_eth.h
new file mode 100644 (file)
index 0000000..8edab82
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2003 IMMS gGmbH <www.imms.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * author(s): Thomas Elste, <info@elste.org>
+ */
+
+#include <asm/types.h>
+#include <config.h>
+
+#ifdef CONFIG_DRIVER_NETARMETH
+
+#define SET_EADDR(ad,val) *(volatile unsigned int*)(ad + NETARM_ETH_MODULE_BASE) = val
+#define GET_EADDR(ad) (*(volatile unsigned int*)(ad + NETARM_ETH_MODULE_BASE))
+
+#define NA_MII_POLL_BUSY_DELAY 900
+
+/* MII negotiation timeout value
+   500 jiffies = 5 seconds */
+#define NA_MII_NEGOTIATE_DELAY 30
+
+/* Registers in the physical layer chip */
+#define MII_PHY_CONTROL                0
+#define MII_PHY_STATUS         1
+#define MII_PHY_ID              2
+#define MII_PHY_AUTONEGADV     4
+
+#endif /* CONFIG_DRIVER_NETARMETH */
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
new file mode 100644 (file)
index 0000000..69089f9
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+ * (C) Copyright 2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_NETCONSOLE
+
+#include <command.h>
+#include <devices.h>
+#include <net.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static char input_buffer[512];
+static int input_size = 0;             /* char count in input buffer */
+static int input_offset = 0;           /* offset to valid chars in input buffer */
+static int input_recursion = 0;
+static int output_recursion = 0;
+static int net_timeout;
+static uchar nc_ether[6];              /* server enet address */
+static IPaddr_t nc_ip;                 /* server ip */
+static short nc_port;                  /* source/target port */
+static const char *output_packet;      /* used by first send udp */
+static int output_packet_len = 0;
+
+static void nc_wait_arp_handler (uchar * pkt, unsigned dest, unsigned src,
+                                unsigned len)
+{
+       NetState = NETLOOP_SUCCESS;     /* got arp reply - quit net loop */
+}
+
+static void nc_handler (uchar * pkt, unsigned dest, unsigned src,
+                       unsigned len)
+{
+       if (input_size)
+               NetState = NETLOOP_SUCCESS;     /* got input - quit net loop */
+}
+
+static void nc_timeout (void)
+{
+       NetState = NETLOOP_SUCCESS;
+}
+
+void NcStart (void)
+{
+       if (!output_packet_len || memcmp (nc_ether, NetEtherNullAddr, 6)) {
+               /* going to check for input packet */
+               NetSetHandler (nc_handler);
+               NetSetTimeout (net_timeout, nc_timeout);
+       } else {
+               /* send arp request */
+               uchar *pkt;
+               NetSetHandler (nc_wait_arp_handler);
+               pkt = (uchar *) NetTxPacket + NetEthHdrSize () + IP_HDR_SIZE;
+               memcpy (pkt, output_packet, output_packet_len);
+               NetSendUDPPacket (nc_ether, nc_ip, nc_port, nc_port, output_packet_len);
+       }
+}
+
+int nc_input_packet (uchar * pkt, unsigned dest, unsigned src, unsigned len)
+{
+       int end, chunk;
+
+       if (dest != nc_port || !len)
+               return 0;               /* not for us */
+
+       if (input_size == sizeof input_buffer)
+               return 1;               /* no space */
+       if (len > sizeof input_buffer - input_size)
+               len = sizeof input_buffer - input_size;
+
+       end = input_offset + input_size;
+       if (end > sizeof input_buffer)
+               end -= sizeof input_buffer;
+
+       chunk = len;
+       if (end + len > sizeof input_buffer) {
+               chunk = sizeof input_buffer - end;
+               memcpy(input_buffer, pkt + chunk, len - chunk);
+       }
+       memcpy (input_buffer + end, pkt, chunk);
+
+       input_size += len;
+
+       return 1;
+}
+
+static void nc_send_packet (const char *buf, int len)
+{
+       struct eth_device *eth;
+       int inited = 0;
+       uchar *pkt;
+       uchar *ether;
+       IPaddr_t ip;
+
+       if ((eth = eth_get_dev ()) == NULL) {
+               return;
+       }
+
+       if (!memcmp (nc_ether, NetEtherNullAddr, 6)) {
+               if (eth->state == ETH_STATE_ACTIVE)
+                       return; /* inside net loop */
+               output_packet = buf;
+               output_packet_len = len;
+               NetLoop (NETCONS);      /* wait for arp reply and send packet */
+               output_packet_len = 0;
+               return;
+       }
+
+       if (eth->state != ETH_STATE_ACTIVE) {
+               if (eth_init (gd->bd) < 0)
+                       return;
+               inited = 1;
+       }
+       pkt = (uchar *) NetTxPacket + NetEthHdrSize () + IP_HDR_SIZE;
+       memcpy (pkt, buf, len);
+       ether = nc_ether;
+       ip = nc_ip;
+       NetSendUDPPacket (ether, ip, nc_port, nc_port, len);
+
+       if (inited)
+               eth_halt ();
+}
+
+int nc_start (void)
+{
+       int netmask, our_ip;
+
+       nc_port = 6666;         /* default port */
+
+       if (getenv ("ncip")) {
+               char *p;
+
+               nc_ip = getenv_IPaddr ("ncip");
+               if (!nc_ip)
+                       return -1;      /* ncip is 0.0.0.0 */
+               if ((p = strchr (getenv ("ncip"), ':')) != NULL)
+                       nc_port = simple_strtoul (p + 1, NULL, 10);
+       } else
+               nc_ip = ~0;             /* ncip is not set */
+
+       our_ip = getenv_IPaddr ("ipaddr");
+       netmask = getenv_IPaddr ("netmask");
+
+       if (nc_ip == ~0 ||                              /* 255.255.255.255 */
+           ((netmask & our_ip) == (netmask & nc_ip) && /* on the same net */
+           (netmask | nc_ip) == ~0))                   /* broadcast to our net */
+               memset (nc_ether, 0xff, sizeof nc_ether);
+       else
+               memset (nc_ether, 0, sizeof nc_ether);  /* force arp request */
+
+       return 0;
+}
+
+void nc_putc (char c)
+{
+       if (output_recursion)
+               return;
+       output_recursion = 1;
+
+       nc_send_packet (&c, 1);
+
+       output_recursion = 0;
+}
+
+void nc_puts (const char *s)
+{
+       int len;
+
+       if (output_recursion)
+               return;
+       output_recursion = 1;
+
+       if ((len = strlen (s)) > 512)
+               len = 512;
+
+       nc_send_packet (s, len);
+
+       output_recursion = 0;
+}
+
+int nc_getc (void)
+{
+       uchar c;
+
+       input_recursion = 1;
+
+       net_timeout = 0;        /* no timeout */
+       while (!input_size)
+               NetLoop (NETCONS);
+
+       input_recursion = 0;
+
+       c = input_buffer[input_offset++];
+
+       if (input_offset >= sizeof input_buffer)
+               input_offset -= sizeof input_buffer;
+       input_size--;
+
+       return c;
+}
+
+int nc_tstc (void)
+{
+       struct eth_device *eth;
+
+       if (input_recursion)
+               return 0;
+
+       if (input_size)
+               return 1;
+
+       eth = eth_get_dev ();
+       if (eth && eth->state == ETH_STATE_ACTIVE)
+               return 0;       /* inside net loop */
+
+       input_recursion = 1;
+
+       net_timeout = 1;
+       NetLoop (NETCONS);      /* kind of poll */
+
+       input_recursion = 0;
+
+       return input_size != 0;
+}
+
+int drv_nc_init (void)
+{
+       device_t dev;
+       int rc;
+
+       memset (&dev, 0, sizeof (dev));
+
+       strcpy (dev.name, "nc");
+       dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+       dev.start = nc_start;
+       dev.putc = nc_putc;
+       dev.puts = nc_puts;
+       dev.getc = nc_getc;
+       dev.tstc = nc_tstc;
+
+       rc = device_register (&dev);
+
+       return (rc == 0) ? 1 : rc;
+}
+
+#endif /* CONFIG_NETCONSOLE */
diff --git a/drivers/net/nicext.h b/drivers/net/nicext.h
new file mode 100644 (file)
index 0000000..4074972
--- /dev/null
@@ -0,0 +1,109 @@
+/****************************************************************************
+ * Copyright(c) 2000-2001 Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ *
+ * Name:        nicext.h
+ *
+ * Description: Broadcom Network Interface Card Extension (NICE) is an
+ *              extension to Linux NET device kernel mode drivers.
+ *              NICE is designed to provide additional functionalities,
+ *              such as receive packet intercept. To support Broadcom NICE,
+ *              the network device driver can be modified by adding an
+ *              device ioctl handler and by indicating receiving packets
+ *              to the NICE receive handler. Broadcom NICE will only be
+ *              enabled by a NICE-aware intermediate driver, such as
+ *              Broadcom Advanced Server Program Driver (BASP). When NICE
+ *              is not enabled, the modified network device drivers
+ *              functions exactly as other non-NICE aware drivers.
+ *
+ * Author:      Frankie Fan
+ *
+ * Created:     September 17, 2000
+ *
+ ****************************************************************************/
+#ifndef _nicext_h_
+#define _nicext_h_
+
+/*
+ * ioctl for NICE
+ */
+#define SIOCNICE                       SIOCDEVPRIVATE+7
+
+/*
+ * SIOCNICE:
+ *
+ * The following structure needs to be less than IFNAMSIZ (16 bytes) because
+ * we're overloading ifreq.ifr_ifru.
+ *
+ * If 16 bytes is not enough, we should consider relaxing this because
+ * this is no field after ifr_ifru in the ifreq structure. But we may
+ * run into future compatiability problem in case of changing struct ifreq.
+ */
+struct nice_req
+{
+    __u32 cmd;
+
+    union
+    {
+#ifdef __KERNEL__
+       /* cmd = NICE_CMD_SET_RX or NICE_CMD_GET_RX */
+       struct
+       {
+           void (*nrqus1_rx)( struct sk_buff*, void* );
+           void* nrqus1_ctx;
+       } nrqu_nrqus1;
+
+       /* cmd = NICE_CMD_QUERY_SUPPORT */
+       struct
+       {
+           __u32 nrqus2_magic;
+           __u32 nrqus2_support_rx:1;
+           __u32 nrqus2_support_vlan:1;
+           __u32 nrqus2_support_get_speed:1;
+       } nrqu_nrqus2;
+#endif
+
+       /* cmd = NICE_CMD_GET_SPEED */
+       struct
+       {
+           unsigned int nrqus3_speed; /* 0 if link is down, */
+                                      /* otherwise speed in Mbps */
+       } nrqu_nrqus3;
+
+       /* cmd = NICE_CMD_BLINK_LED */
+       struct
+       {
+           unsigned int nrqus4_blink_time; /* blink duration in seconds */
+       } nrqu_nrqus4;
+
+    } nrq_nrqu;
+};
+
+#define nrq_rx           nrq_nrqu.nrqu_nrqus1.nrqus1_rx
+#define nrq_ctx          nrq_nrqu.nrqu_nrqus1.nrqus1_ctx
+#define nrq_support_rx   nrq_nrqu.nrqu_nrqus2.nrqus2_support_rx
+#define nrq_magic        nrq_nrqu.nrqu_nrqus2.nrqus2_magic
+#define nrq_support_vlan nrq_nrqu.nrqu_nrqus2.nrqus2_support_vlan
+#define nrq_support_get_speed nrq_nrqu.nrqu_nrqus2.nrqus2_support_get_speed
+#define nrq_speed        nrq_nrqu.nrqu_nrqus3.nrqus3_speed
+#define nrq_blink_time   nrq_nrqu.nrqu_nrqus4.nrqus4_blink_time
+
+/*
+ * magic constants
+ */
+#define NICE_REQUESTOR_MAGIC            0x4543494E /* NICE in ascii */
+#define NICE_DEVICE_MAGIC               0x4E494345 /* ECIN in ascii */
+
+/*
+ * command field
+ */
+#define NICE_CMD_QUERY_SUPPORT          0x00000001
+#define NICE_CMD_SET_RX                 0x00000002
+#define NICE_CMD_GET_RX                 0x00000003
+#define NICE_CMD_GET_SPEED              0x00000004
+#define NICE_CMD_BLINK_LED              0x00000005
+
+#endif  /* _nicext_h_ */
diff --git a/drivers/net/ns7520_eth.c b/drivers/net/ns7520_eth.c
new file mode 100644 (file)
index 0000000..a5a20df
--- /dev/null
@@ -0,0 +1,859 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2005 by Videon Central, Inc.
+ *
+ * $Id$
+ * @Author: Arthur Shipkowski
+ * @Descr: Ethernet driver for the NS7520. Uses polled Ethernet, like
+ *     the older netarmeth driver.  Note that attempting to filter
+ *     broadcast and multicast out in the SAFR register will cause
+ *     bad things due to released errata.
+ * @References: [1] NS7520 Hardware Reference, December 2003
+ *             [2] Intel LXT971 Datasheet #249414 Rev. 02
+ *
+ ***********************************************************************/
+
+#include <common.h>
+
+#if defined(CONFIG_DRIVER_NS7520_ETHERNET)
+
+#include <net.h>               /* NetSendPacket */
+#include <asm/arch/netarm_registers.h>
+#include <asm/arch/netarm_dma_module.h>
+
+#include "ns7520_eth.h"                /* for Ethernet and PHY */
+
+/**
+ * Send an error message to the terminal.
+ */
+#define ERROR(x) \
+do { \
+       char *__foo = strrchr(__FILE__, '/'); \
+       \
+       printf("%s: %d: %s(): ", (__foo == NULL ? __FILE__ : (__foo + 1)), \
+                       __LINE__, __FUNCTION__); \
+       printf x; printf("\n"); \
+} while (0);
+
+/* some definition to make transistion to linux easier */
+
+#define NS7520_DRIVER_NAME     "eth"
+#define KERN_WARNING           "Warning:"
+#define KERN_ERR               "Error:"
+#define KERN_INFO              "Info:"
+
+#if 1
+# define DEBUG
+#endif
+
+#ifdef DEBUG
+# define printk                        printf
+
+# define DEBUG_INIT            0x0001
+# define DEBUG_MINOR           0x0002
+# define DEBUG_RX              0x0004
+# define DEBUG_TX              0x0008
+# define DEBUG_INT             0x0010
+# define DEBUG_POLL            0x0020
+# define DEBUG_LINK            0x0040
+# define DEBUG_MII             0x0100
+# define DEBUG_MII_LOW         0x0200
+# define DEBUG_MEM             0x0400
+# define DEBUG_ERROR           0x4000
+# define DEBUG_ERROR_CRIT      0x8000
+
+static int nDebugLvl = DEBUG_ERROR_CRIT;
+
+# define DEBUG_ARGS0( FLG, a0 ) if( ( nDebugLvl & (FLG) ) == (FLG) ) \
+               printf("%s: " a0, __FUNCTION__, 0, 0, 0, 0, 0, 0 )
+# define DEBUG_ARGS1( FLG, a0, a1 ) if( ( nDebugLvl & (FLG) ) == (FLG)) \
+               printf("%s: " a0, __FUNCTION__, (int)(a1), 0, 0, 0, 0, 0 )
+# define DEBUG_ARGS2( FLG, a0, a1, a2 ) if( (nDebugLvl & (FLG)) ==(FLG))\
+               printf("%s: " a0, __FUNCTION__, (int)(a1), (int)(a2), 0, 0,0,0 )
+# define DEBUG_ARGS3( FLG, a0, a1, a2, a3 ) if((nDebugLvl &(FLG))==(FLG))\
+               printf("%s: "a0,__FUNCTION__,(int)(a1),(int)(a2),(int)(a3),0,0,0)
+# define DEBUG_FN( FLG ) if( (nDebugLvl & (FLG)) == (FLG) ) \
+               printf("\r%s:line %d\n", (int)__FUNCTION__, __LINE__, 0,0,0,0);
+# define ASSERT( expr, func ) if( !( expr ) ) { \
+               printf( "Assertion failed! %s:line %d %s\n", \
+               (int)__FUNCTION__,__LINE__,(int)(#expr),0,0,0); \
+               func }
+#else                          /* DEBUG */
+# define printk(...)
+# define DEBUG_ARGS0( FLG, a0 )
+# define DEBUG_ARGS1( FLG, a0, a1 )
+# define DEBUG_ARGS2( FLG, a0, a1, a2 )
+# define DEBUG_ARGS3( FLG, a0, a1, a2, a3 )
+# define DEBUG_FN( n )
+# define ASSERT(expr, func)
+#endif                         /* DEBUG */
+
+#define NS7520_MII_NEG_DELAY           (5*CFG_HZ)      /* in s */
+#define TX_TIMEOUT                     (5*CFG_HZ)      /* in s */
+#define RX_STALL_WORKAROUND_CNT 100
+
+static int ns7520_eth_reset(void);
+
+static void ns7520_link_auto_negotiate(void);
+static void ns7520_link_update_egcr(void);
+static void ns7520_link_print_changed(void);
+
+/* the PHY stuff */
+
+static char ns7520_mii_identify_phy(void);
+static unsigned short ns7520_mii_read(unsigned short uiRegister);
+static void ns7520_mii_write(unsigned short uiRegister,
+                            unsigned short uiData);
+static unsigned int ns7520_mii_get_clock_divisor(unsigned int
+                                                unMaxMDIOClk);
+static unsigned int ns7520_mii_poll_busy(void);
+
+static unsigned int nPhyMaxMdioClock = PHY_MDIO_MAX_CLK;
+static unsigned int uiLastLinkStatus;
+static PhyType phyDetected = PHY_NONE;
+
+/***********************************************************************
+ * @Function: eth_init
+ * @Return: -1 on failure otherwise 0
+ * @Descr: Initializes the ethernet engine and uses either FS Forth's default
+ *        MAC addr or the one in environment
+ ***********************************************************************/
+
+int eth_init(bd_t * pbis)
+{
+       unsigned char aucMACAddr[6];
+       char *pcTmp = getenv("ethaddr");
+       char *pcEnd;
+       int i;
+
+       DEBUG_FN(DEBUG_INIT);
+
+       /* no need to check for hardware */
+
+       if (!ns7520_eth_reset())
+               return -1;
+
+       if (NULL == pcTmp)
+               return -1;
+
+       for (i = 0; i < 6; i++) {
+               aucMACAddr[i] =
+                   pcTmp ? simple_strtoul(pcTmp, &pcEnd, 16) : 0;
+               pcTmp = (*pcTmp) ? pcEnd + 1 : pcEnd;
+       }
+
+       /* configure ethernet address */
+
+       *get_eth_reg_addr(NS7520_ETH_SA1) =
+           aucMACAddr[5] << 8 | aucMACAddr[4];
+       *get_eth_reg_addr(NS7520_ETH_SA2) =
+           aucMACAddr[3] << 8 | aucMACAddr[2];
+       *get_eth_reg_addr(NS7520_ETH_SA3) =
+           aucMACAddr[1] << 8 | aucMACAddr[0];
+
+       /* enable hardware */
+
+       *get_eth_reg_addr(NS7520_ETH_MAC1) = NS7520_ETH_MAC1_RXEN;
+       *get_eth_reg_addr(NS7520_ETH_SUPP) = NS7520_ETH_SUPP_JABBER;
+       *get_eth_reg_addr(NS7520_ETH_MAC1) = NS7520_ETH_MAC1_RXEN;
+
+       /* the linux kernel may give packets < 60 bytes, for example arp */
+       *get_eth_reg_addr(NS7520_ETH_MAC2) = NS7520_ETH_MAC2_CRCEN |
+           NS7520_ETH_MAC2_PADEN | NS7520_ETH_MAC2_HUGE;
+
+       /* Broadcast/multicast allowed; if you don't set this even unicast chokes */
+       /* Based on NS7520 errata documentation */
+       *get_eth_reg_addr(NS7520_ETH_SAFR) =
+           NS7520_ETH_SAFR_BROAD | NS7520_ETH_SAFR_PRM;
+
+       /* enable receive and transmit FIFO, use 10/100 Mbps MII */
+       *get_eth_reg_addr(NS7520_ETH_EGCR) |=
+           NS7520_ETH_EGCR_ETXWM_75 |
+           NS7520_ETH_EGCR_ERX |
+           NS7520_ETH_EGCR_ERXREG |
+           NS7520_ETH_EGCR_ERXBR | NS7520_ETH_EGCR_ETX;
+
+       return 0;
+}
+
+/***********************************************************************
+ * @Function: eth_send
+ * @Return: -1 on timeout otherwise 1
+ * @Descr: sends one frame by DMA
+ ***********************************************************************/
+
+int eth_send(volatile void *pPacket, int nLen)
+{
+       int i, length32, retval = 1;
+       char *pa;
+       unsigned int *pa32, lastp = 0, rest;
+       unsigned int status;
+
+       pa = (char *) pPacket;
+       pa32 = (unsigned int *) pPacket;
+       length32 = nLen / 4;
+       rest = nLen % 4;
+
+       /* make sure there's no garbage in the last word */
+       switch (rest) {
+       case 0:
+               lastp = pa32[length32 - 1];
+               length32--;
+               break;
+       case 1:
+               lastp = pa32[length32] & 0x000000ff;
+               break;
+       case 2:
+               lastp = pa32[length32] & 0x0000ffff;
+               break;
+       case 3:
+               lastp = pa32[length32] & 0x00ffffff;
+               break;
+       }
+
+       while (((*get_eth_reg_addr(NS7520_ETH_EGSR)) &
+               NS7520_ETH_EGSR_TXREGE)
+              == 0) {
+       }
+
+       /* write to the fifo */
+       for (i = 0; i < length32; i++)
+               *get_eth_reg_addr(NS7520_ETH_FIFO) = pa32[i];
+
+       /* the last word is written to an extra register, this
+          starts the transmission */
+       *get_eth_reg_addr(NS7520_ETH_FIFOL) = lastp;
+
+       /* Wait for it to be done */
+       while ((*get_eth_reg_addr(NS7520_ETH_EGSR) & NS7520_ETH_EGSR_TXBC)
+              == 0) {
+       }
+       status = (*get_eth_reg_addr(NS7520_ETH_ETSR));
+       *get_eth_reg_addr(NS7520_ETH_EGSR) = NS7520_ETH_EGSR_TXBC;      /* Clear it now */
+
+       if (status & NS7520_ETH_ETSR_TXOK) {
+               retval = 0;     /* We're OK! */
+       } else if (status & NS7520_ETH_ETSR_TXDEF) {
+               printf("Deferred, we'll see.\n");
+               retval = 0;
+       } else if (status & NS7520_ETH_ETSR_TXAL) {
+               printf("Late collision error, %d collisions.\n",
+                      (*get_eth_reg_addr(NS7520_ETH_ETSR)) &
+                      NS7520_ETH_ETSR_TXCOLC);
+       } else if (status & NS7520_ETH_ETSR_TXAEC) {
+               printf("Excessive collisions: %d\n",
+                      (*get_eth_reg_addr(NS7520_ETH_ETSR)) &
+                      NS7520_ETH_ETSR_TXCOLC);
+       } else if (status & NS7520_ETH_ETSR_TXAED) {
+               printf("Excessive deferral on xmit.\n");
+       } else if (status & NS7520_ETH_ETSR_TXAUR) {
+               printf("Packet underrun.\n");
+       } else if (status & NS7520_ETH_ETSR_TXAJ) {
+               printf("Jumbo packet error.\n");
+       } else {
+               printf("Error: Should never get here.\n");
+       }
+
+       return (retval);
+}
+
+/***********************************************************************
+ * @Function: eth_rx
+ * @Return: size of last frame in bytes or 0 if no frame available
+ * @Descr: gives one frame to U-Boot which has been copied by DMA engine already
+ *        to NetRxPackets[ 0 ].
+ ***********************************************************************/
+
+int eth_rx(void)
+{
+       int i;
+       unsigned short rxlen;
+       unsigned short totrxlen = 0;
+       unsigned int *addr;
+       unsigned int rxstatus, lastrxlen;
+       char *pa;
+
+       /* If RXBR is 1, data block was received */
+       while (((*get_eth_reg_addr(NS7520_ETH_EGSR)) &
+               NS7520_ETH_EGSR_RXBR) == NS7520_ETH_EGSR_RXBR) {
+
+               /* get status register and the length of received block */
+               rxstatus = *get_eth_reg_addr(NS7520_ETH_ERSR);
+               rxlen = (rxstatus & NS7520_ETH_ERSR_RXSIZE) >> 16;
+
+               /* clear RXBR to make fifo available */
+               *get_eth_reg_addr(NS7520_ETH_EGSR) = NS7520_ETH_EGSR_RXBR;
+
+               if (rxstatus & NS7520_ETH_ERSR_ROVER) {
+                       printf("Receive overrun, resetting FIFO.\n");
+                       *get_eth_reg_addr(NS7520_ETH_EGCR) &=
+                           ~NS7520_ETH_EGCR_ERX;
+                       udelay(20);
+                       *get_eth_reg_addr(NS7520_ETH_EGCR) |=
+                           NS7520_ETH_EGCR_ERX;
+               }
+               if (rxlen == 0) {
+                       printf("Nothing.\n");
+                       return 0;
+               }
+
+               addr = (unsigned int *) NetRxPackets[0];
+               pa = (char *) NetRxPackets[0];
+
+               /* read the fifo */
+               for (i = 0; i < rxlen / 4; i++) {
+                       *addr = *get_eth_reg_addr(NS7520_ETH_FIFO);
+                       addr++;
+               }
+
+               if ((*get_eth_reg_addr(NS7520_ETH_EGSR)) &
+                   NS7520_ETH_EGSR_RXREGR) {
+                       /* RXFDB indicates wether the last word is 1,2,3 or 4 bytes long */
+                       lastrxlen =
+                           ((*get_eth_reg_addr(NS7520_ETH_EGSR)) &
+                            NS7520_ETH_EGSR_RXFDB_MA) >> 28;
+                       *addr = *get_eth_reg_addr(NS7520_ETH_FIFO);
+                       switch (lastrxlen) {
+                       case 1:
+                               *addr &= 0xff000000;
+                               break;
+                       case 2:
+                               *addr &= 0xffff0000;
+                               break;
+                       case 3:
+                               *addr &= 0xffffff00;
+                               break;
+                       }
+               }
+
+               /* Pass the packet up to the protocol layers. */
+               NetReceive(NetRxPackets[0], rxlen - 4);
+               totrxlen += rxlen - 4;
+       }
+
+       return totrxlen;
+}
+
+/***********************************************************************
+ * @Function: eth_halt
+ * @Return: n/a
+ * @Descr: stops the ethernet engine
+ ***********************************************************************/
+
+void eth_halt(void)
+{
+       DEBUG_FN(DEBUG_INIT);
+
+       *get_eth_reg_addr(NS7520_ETH_MAC1) &= ~NS7520_ETH_MAC1_RXEN;
+       *get_eth_reg_addr(NS7520_ETH_EGCR) &= ~(NS7520_ETH_EGCR_ERX |
+                                               NS7520_ETH_EGCR_ERXDMA |
+                                               NS7520_ETH_EGCR_ERXREG |
+                                               NS7520_ETH_EGCR_ERXBR |
+                                               NS7520_ETH_EGCR_ETX |
+                                               NS7520_ETH_EGCR_ETXDMA);
+}
+
+/***********************************************************************
+ * @Function: ns7520_eth_reset
+ * @Return: 0 on failure otherwise 1
+ * @Descr: resets the ethernet interface and the PHY,
+ *        performs auto negotiation or fixed modes
+ ***********************************************************************/
+
+static int ns7520_eth_reset(void)
+{
+       DEBUG_FN(DEBUG_MINOR);
+
+       /* Reset important registers */
+       *get_eth_reg_addr(NS7520_ETH_EGCR) = 0; /* Null it out! */
+       *get_eth_reg_addr(NS7520_ETH_MAC1) &= NS7520_ETH_MAC1_SRST;
+       *get_eth_reg_addr(NS7520_ETH_MAC2) = 0;
+       /* Reset MAC */
+       *get_eth_reg_addr(NS7520_ETH_EGCR) |= NS7520_ETH_EGCR_MAC_RES;
+       udelay(5);
+       *get_eth_reg_addr(NS7520_ETH_EGCR) &= ~NS7520_ETH_EGCR_MAC_RES;
+
+       /* reset and initialize PHY */
+
+       *get_eth_reg_addr(NS7520_ETH_MAC1) &= ~NS7520_ETH_MAC1_SRST;
+
+       /* we don't support hot plugging of PHY, therefore we don't reset
+          phyDetected and nPhyMaxMdioClock here. The risk is if the setting is
+          incorrect the first open
+          may detect the PHY correctly but succeding will fail
+          For reseting the PHY and identifying we have to use the standard
+          MDIO CLOCK value 2.5 MHz only after hardware reset
+          After having identified the PHY we will do faster */
+
+       *get_eth_reg_addr(NS7520_ETH_MCFG) =
+           ns7520_mii_get_clock_divisor(nPhyMaxMdioClock);
+
+       /* reset PHY */
+       ns7520_mii_write(PHY_COMMON_CTRL, PHY_COMMON_CTRL_RESET);
+       ns7520_mii_write(PHY_COMMON_CTRL, 0);
+
+       udelay(3000);           /* [2] p.70 says at least 300us reset recovery time. */
+
+       /* MII clock has been setup to default, ns7520_mii_identify_phy should
+          work for all */
+
+       if (!ns7520_mii_identify_phy()) {
+               printk(KERN_ERR NS7520_DRIVER_NAME
+                      ": Unsupported PHY, aborting\n");
+               return 0;
+       }
+
+       /* now take the highest MDIO clock possible after detection */
+       *get_eth_reg_addr(NS7520_ETH_MCFG) =
+           ns7520_mii_get_clock_divisor(nPhyMaxMdioClock);
+
+       /* PHY has been detected, so there can be no abort reason and we can
+          finish initializing ethernet */
+
+       uiLastLinkStatus = 0xff;        /* undefined */
+
+       ns7520_link_auto_negotiate();
+
+       if (phyDetected == PHY_LXT971A)
+               /* set LED2 to link mode */
+               ns7520_mii_write(PHY_LXT971_LED_CFG,
+                                (PHY_LXT971_LED_CFG_LINK_ACT <<
+                                 PHY_LXT971_LED_CFG_SHIFT_LED2) |
+                                (PHY_LXT971_LED_CFG_TRANSMIT <<
+                                 PHY_LXT971_LED_CFG_SHIFT_LED1));
+
+       return 1;
+}
+
+/***********************************************************************
+ * @Function: ns7520_link_auto_negotiate
+ * @Return: void
+ * @Descr: performs auto-negotation of link.
+ ***********************************************************************/
+
+static void ns7520_link_auto_negotiate(void)
+{
+       unsigned long ulStartJiffies;
+       unsigned short uiStatus;
+
+       DEBUG_FN(DEBUG_LINK);
+
+       /* run auto-negotation */
+       /* define what we are capable of */
+       ns7520_mii_write(PHY_COMMON_AUTO_ADV,
+                        PHY_COMMON_AUTO_ADV_100BTXFD |
+                        PHY_COMMON_AUTO_ADV_100BTX |
+                        PHY_COMMON_AUTO_ADV_10BTFD |
+                        PHY_COMMON_AUTO_ADV_10BT |
+                        PHY_COMMON_AUTO_ADV_802_3);
+       /* start auto-negotiation */
+       ns7520_mii_write(PHY_COMMON_CTRL,
+                        PHY_COMMON_CTRL_AUTO_NEG |
+                        PHY_COMMON_CTRL_RES_AUTO);
+
+       /* wait for completion */
+
+       ulStartJiffies = get_timer(0);
+       while (get_timer(0) < ulStartJiffies + NS7520_MII_NEG_DELAY) {
+               uiStatus = ns7520_mii_read(PHY_COMMON_STAT);
+               if ((uiStatus &
+                    (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT))
+                   ==
+                   (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT)) {
+                       /* lucky we are, auto-negotiation succeeded */
+                       ns7520_link_print_changed();
+                       ns7520_link_update_egcr();
+                       return;
+               }
+       }
+
+       DEBUG_ARGS0(DEBUG_LINK, "auto-negotiation timed out\n");
+       /* ignore invalid link settings */
+}
+
+/***********************************************************************
+ * @Function: ns7520_link_update_egcr
+ * @Return: void
+ * @Descr: updates the EGCR and MAC2 link status after mode change or
+ *        auto-negotation
+ ***********************************************************************/
+
+static void ns7520_link_update_egcr(void)
+{
+       unsigned int unEGCR;
+       unsigned int unMAC2;
+       unsigned int unIPGT;
+
+       DEBUG_FN(DEBUG_LINK);
+
+       unEGCR = *get_eth_reg_addr(NS7520_ETH_EGCR);
+       unMAC2 = *get_eth_reg_addr(NS7520_ETH_MAC2);
+       unIPGT =
+           *get_eth_reg_addr(NS7520_ETH_IPGT) & ~NS7520_ETH_IPGT_IPGT;
+
+       unEGCR &= ~NS7520_ETH_EGCR_EFULLD;
+       unMAC2 &= ~NS7520_ETH_MAC2_FULLD;
+       if ((uiLastLinkStatus & PHY_LXT971_STAT2_DUPLEX_MODE)
+           == PHY_LXT971_STAT2_DUPLEX_MODE) {
+               unEGCR |= NS7520_ETH_EGCR_EFULLD;
+               unMAC2 |= NS7520_ETH_MAC2_FULLD;
+               unIPGT |= 0x15; /* see [1] p. 167 */
+       } else
+               unIPGT |= 0x12; /* see [1] p. 167 */
+
+       *get_eth_reg_addr(NS7520_ETH_MAC2) = unMAC2;
+       *get_eth_reg_addr(NS7520_ETH_EGCR) = unEGCR;
+       *get_eth_reg_addr(NS7520_ETH_IPGT) = unIPGT;
+}
+
+/***********************************************************************
+ * @Function: ns7520_link_print_changed
+ * @Return: void
+ * @Descr: checks whether the link status has changed and if so prints
+ *        the new mode
+ ***********************************************************************/
+
+static void ns7520_link_print_changed(void)
+{
+       unsigned short uiStatus;
+       unsigned short uiControl;
+
+       DEBUG_FN(DEBUG_LINK);
+
+       uiControl = ns7520_mii_read(PHY_COMMON_CTRL);
+
+       if ((uiControl & PHY_COMMON_CTRL_AUTO_NEG) ==
+           PHY_COMMON_CTRL_AUTO_NEG) {
+               /* PHY_COMMON_STAT_LNK_STAT is only set on autonegotiation */
+               uiStatus = ns7520_mii_read(PHY_COMMON_STAT);
+
+               if (!(uiStatus & PHY_COMMON_STAT_LNK_STAT)) {
+                       printk(KERN_WARNING NS7520_DRIVER_NAME
+                              ": link down\n");
+                       /* @TODO Linux: carrier_off */
+               } else {
+                       /* @TODO Linux: carrier_on */
+                       if (phyDetected == PHY_LXT971A) {
+                               uiStatus =
+                                   ns7520_mii_read(PHY_LXT971_STAT2);
+                               uiStatus &=
+                                   (PHY_LXT971_STAT2_100BTX |
+                                    PHY_LXT971_STAT2_DUPLEX_MODE |
+                                    PHY_LXT971_STAT2_AUTO_NEG);
+
+                               /* mask out all uninteresting parts */
+                       }
+                       /* other PHYs must store there link information in
+                          uiStatus as PHY_LXT971 */
+               }
+       } else {
+               /* mode has been forced, so uiStatus should be the same as the
+                  last link status, enforce printing */
+               uiStatus = uiLastLinkStatus;
+               uiLastLinkStatus = 0xff;
+       }
+
+       if (uiStatus != uiLastLinkStatus) {
+               /* save current link status */
+               uiLastLinkStatus = uiStatus;
+
+               /* print new link status */
+
+               printk(KERN_INFO NS7520_DRIVER_NAME
+                      ": link mode %i Mbps %s duplex %s\n",
+                      (uiStatus & PHY_LXT971_STAT2_100BTX) ? 100 : 10,
+                      (uiStatus & PHY_LXT971_STAT2_DUPLEX_MODE) ? "full" :
+                      "half",
+                      (uiStatus & PHY_LXT971_STAT2_AUTO_NEG) ? "(auto)" :
+                      "");
+       }
+}
+
+/***********************************************************************
+ * the MII low level stuff
+ ***********************************************************************/
+
+/***********************************************************************
+ * @Function: ns7520_mii_identify_phy
+ * @Return: 1 if supported PHY has been detected otherwise 0
+ * @Descr: checks for supported PHY and prints the IDs.
+ ***********************************************************************/
+
+static char ns7520_mii_identify_phy(void)
+{
+       unsigned short uiID1;
+       unsigned short uiID2;
+       unsigned char *szName;
+       char cRes = 0;
+
+       DEBUG_FN(DEBUG_MII);
+
+       phyDetected = (PhyType) uiID1 = ns7520_mii_read(PHY_COMMON_ID1);
+
+       switch (phyDetected) {
+       case PHY_LXT971A:
+               szName = "LXT971A";
+               uiID2 = ns7520_mii_read(PHY_COMMON_ID2);
+               nPhyMaxMdioClock = PHY_LXT971_MDIO_MAX_CLK;
+               cRes = 1;
+               break;
+       case PHY_NONE:
+       default:
+               /* in case uiID1 == 0 && uiID2 == 0 we may have the wrong
+                  address or reset sets the wrong NS7520_ETH_MCFG_CLKS */
+
+               uiID2 = 0;
+               szName = "unknown";
+               nPhyMaxMdioClock = PHY_MDIO_MAX_CLK;
+               phyDetected = PHY_NONE;
+       }
+
+       printk(KERN_INFO NS7520_DRIVER_NAME
+              ": PHY (0x%x, 0x%x) = %s detected\n", uiID1, uiID2, szName);
+
+       return cRes;
+}
+
+/***********************************************************************
+ * @Function: ns7520_mii_read
+ * @Return: the data read from PHY register uiRegister
+ * @Descr: the data read may be invalid if timed out. If so, a message
+ *        is printed but the invalid data is returned.
+ *        The fixed device address is being used.
+ ***********************************************************************/
+
+static unsigned short ns7520_mii_read(unsigned short uiRegister)
+{
+       DEBUG_FN(DEBUG_MII_LOW);
+
+       /* write MII register to be read */
+       *get_eth_reg_addr(NS7520_ETH_MADR) =
+           CONFIG_PHY_ADDR << 8 | uiRegister;
+
+       *get_eth_reg_addr(NS7520_ETH_MCMD) = NS7520_ETH_MCMD_READ;
+
+       if (!ns7520_mii_poll_busy())
+               printk(KERN_WARNING NS7520_DRIVER_NAME
+                      ": MII still busy in read\n");
+       /* continue to read */
+
+       *get_eth_reg_addr(NS7520_ETH_MCMD) = 0;
+
+       return (unsigned short) (*get_eth_reg_addr(NS7520_ETH_MRDD));
+}
+
+/***********************************************************************
+ * @Function: ns7520_mii_write
+ * @Return: nothing
+ * @Descr: writes the data to the PHY register. In case of a timeout,
+ *        no special handling is performed but a message printed
+ *        The fixed device address is being used.
+ ***********************************************************************/
+
+static void ns7520_mii_write(unsigned short uiRegister,
+                            unsigned short uiData)
+{
+       DEBUG_FN(DEBUG_MII_LOW);
+
+       /* write MII register to be written */
+       *get_eth_reg_addr(NS7520_ETH_MADR) =
+           CONFIG_PHY_ADDR << 8 | uiRegister;
+
+       *get_eth_reg_addr(NS7520_ETH_MWTD) = uiData;
+
+       if (!ns7520_mii_poll_busy()) {
+               printf(KERN_WARNING NS7520_DRIVER_NAME
+                      ": MII still busy in write\n");
+       }
+}
+
+/***********************************************************************
+ * @Function: ns7520_mii_get_clock_divisor
+ * @Return: the clock divisor that should be used in NS7520_ETH_MCFG_CLKS
+ * @Descr: if no clock divisor can be calculated for the
+ *        current SYSCLK and the maximum MDIO Clock, a warning is printed
+ *        and the greatest divisor is taken
+ ***********************************************************************/
+
+static unsigned int ns7520_mii_get_clock_divisor(unsigned int unMaxMDIOClk)
+{
+       struct {
+               unsigned int unSysClkDivisor;
+               unsigned int unClks;    /* field for NS7520_ETH_MCFG_CLKS */
+       } PHYClockDivisors[] = {
+               {
+               4, NS7520_ETH_MCFG_CLKS_4}, {
+               6, NS7520_ETH_MCFG_CLKS_6}, {
+               8, NS7520_ETH_MCFG_CLKS_8}, {
+               10, NS7520_ETH_MCFG_CLKS_10}, {
+               14, NS7520_ETH_MCFG_CLKS_14}, {
+               20, NS7520_ETH_MCFG_CLKS_20}, {
+               28, NS7520_ETH_MCFG_CLKS_28}
+       };
+
+       int nIndexSysClkDiv;
+       int nArraySize =
+           sizeof(PHYClockDivisors) / sizeof(PHYClockDivisors[0]);
+       unsigned int unClks = NS7520_ETH_MCFG_CLKS_28;  /* defaults to
+                                                          greatest div */
+
+       DEBUG_FN(DEBUG_INIT);
+
+       for (nIndexSysClkDiv = 0; nIndexSysClkDiv < nArraySize;
+            nIndexSysClkDiv++) {
+               /* find first sysclock divisor that isn't higher than 2.5 MHz
+                  clock */
+               if (NETARM_XTAL_FREQ /
+                   PHYClockDivisors[nIndexSysClkDiv].unSysClkDivisor <=
+                   unMaxMDIOClk) {
+                       unClks = PHYClockDivisors[nIndexSysClkDiv].unClks;
+                       break;
+               }
+       }
+
+       DEBUG_ARGS2(DEBUG_INIT,
+                   "Taking MDIO Clock bit mask 0x%0x for max clock %i\n",
+                   unClks, unMaxMDIOClk);
+
+       /* return greatest divisor */
+       return unClks;
+}
+
+/***********************************************************************
+ * @Function: ns7520_mii_poll_busy
+ * @Return: 0 if timed out otherwise the remaing timeout
+ * @Descr: waits until the MII has completed a command or it times out
+ *        code may be interrupted by hard interrupts.
+ *        It is not checked what happens on multiple actions when
+ *        the first is still being busy and we timeout.
+ ***********************************************************************/
+
+static unsigned int ns7520_mii_poll_busy(void)
+{
+       unsigned int unTimeout = 1000;
+
+       DEBUG_FN(DEBUG_MII_LOW);
+
+       while (((*get_eth_reg_addr(NS7520_ETH_MIND) & NS7520_ETH_MIND_BUSY)
+               == NS7520_ETH_MIND_BUSY) && unTimeout)
+               unTimeout--;
+
+       return unTimeout;
+}
+
+/* ----------------------------------------------------------------------------
+ * Net+ARM ethernet MII functionality.
+ */
+#if defined(CONFIG_MII)
+
+/**
+ * Maximum MII address we support
+ */
+#define MII_ADDRESS_MAX                        (31)
+
+/**
+ * Maximum MII register address we support
+ */
+#define MII_REGISTER_MAX               (31)
+
+/**
+ * Ethernet MII interface return values for public functions.
+ */
+enum mii_status {
+       MII_STATUS_SUCCESS = 0,
+       MII_STATUS_FAILURE = 1,
+};
+
+/**
+ * Read a 16-bit value from an MII register.
+ */
+extern int ns7520_miiphy_read(char *devname, unsigned char const addr,
+               unsigned char const reg, unsigned short *const value)
+{
+       int ret = MII_STATUS_FAILURE;
+
+       /* Parameter checks */
+       if (addr > MII_ADDRESS_MAX) {
+               ERROR(("invalid addr, 0x%02X", addr));
+               goto miiphy_read_failed_0;
+       }
+
+       if (reg > MII_REGISTER_MAX) {
+               ERROR(("invalid reg, 0x%02X", reg));
+               goto miiphy_read_failed_0;
+       }
+
+       if (value == NULL) {
+               ERROR(("NULL value"));
+               goto miiphy_read_failed_0;
+       }
+
+       DEBUG_FN(DEBUG_MII_LOW);
+
+       /* write MII register to be read */
+       *get_eth_reg_addr(NS7520_ETH_MADR) = (addr << 8) | reg;
+
+       *get_eth_reg_addr(NS7520_ETH_MCMD) = NS7520_ETH_MCMD_READ;
+
+       if (!ns7520_mii_poll_busy())
+               printk(KERN_WARNING NS7520_DRIVER_NAME
+                      ": MII still busy in read\n");
+       /* continue to read */
+
+       *get_eth_reg_addr(NS7520_ETH_MCMD) = 0;
+
+       *value = (*get_eth_reg_addr(NS7520_ETH_MRDD));
+       ret = MII_STATUS_SUCCESS;
+       /* Fall through */
+
+      miiphy_read_failed_0:
+       return (ret);
+}
+
+/**
+ * Write a 16-bit value to an MII register.
+ */
+extern int ns7520_miiphy_write(char *devname, unsigned char const addr,
+               unsigned char const reg, unsigned short const value)
+{
+       int ret = MII_STATUS_FAILURE;
+
+       /* Parameter checks */
+       if (addr > MII_ADDRESS_MAX) {
+               ERROR(("invalid addr, 0x%02X", addr));
+               goto miiphy_write_failed_0;
+       }
+
+       if (reg > MII_REGISTER_MAX) {
+               ERROR(("invalid reg, 0x%02X", reg));
+               goto miiphy_write_failed_0;
+       }
+
+       /* write MII register to be written */
+       *get_eth_reg_addr(NS7520_ETH_MADR) = (addr << 8) | reg;
+
+       *get_eth_reg_addr(NS7520_ETH_MWTD) = value;
+
+       if (!ns7520_mii_poll_busy()) {
+               printf(KERN_WARNING NS7520_DRIVER_NAME
+                      ": MII still busy in write\n");
+       }
+
+       ret = MII_STATUS_SUCCESS;
+       /* Fall through */
+
+      miiphy_write_failed_0:
+       return (ret);
+}
+#endif                         /* defined(CONFIG_MII) */
+#endif                         /* CONFIG_DRIVER_NS7520_ETHERNET */
+
+int ns7520_miiphy_initialize(bd_t *bis)
+{
+#if defined(CONFIG_DRIVER_NS7520_ETHERNET)
+#if defined(CONFIG_MII)
+       miiphy_register("ns7520phy", ns7520_miiphy_read, ns7520_miiphy_write);
+#endif
+#endif
+       return 0;
+}
diff --git a/drivers/net/ns8382x.c b/drivers/net/ns8382x.c
new file mode 100644 (file)
index 0000000..f8b143a
--- /dev/null
@@ -0,0 +1,863 @@
+/*
+   ns8382x.c: A U-Boot driver for the NatSemi DP8382[01].
+   ported by: Mark A. Rakes (mark_rakes@vivato.net)
+
+   Adapted from:
+   1. an Etherboot driver for DP8381[56] written by:
+          Copyright (C) 2001 Entity Cyber, Inc.
+
+          This development of this Etherboot driver was funded by
+                 Sicom Systems: http://www.sicompos.com/
+
+          Author: Marty Connor (mdc@thinguin.org)
+          Adapted from a Linux driver which was written by Donald Becker
+
+          This software may be used and distributed according to the terms
+          of the GNU Public License (GPL), incorporated herein by reference.
+
+   2. A Linux driver by Donald Becker, ns820.c:
+               Written/copyright 1999-2002 by Donald Becker.
+
+               This software may be used and distributed according to the terms of
+               the GNU General Public License (GPL), incorporated herein by reference.
+               Drivers based on or derived from this code fall under the GPL and must
+               retain the authorship, copyright and license notice.  This file is not
+               a complete program and may only be used when the entire operating
+               system is licensed under the GPL.  License for under other terms may be
+               available.  Contact the original author for details.
+
+               The original author may be reached as becker@scyld.com, or at
+               Scyld Computing Corporation
+               410 Severn Ave., Suite 210
+               Annapolis MD 21403
+
+               Support information and updates available at
+               http://www.scyld.com/network/netsemi.html
+
+   Datasheets available from:
+   http://www.national.com/pf/DP/DP83820.html
+   http://www.national.com/pf/DP/DP83821.html
+*/
+
+/* Revision History
+ * October 2002 mar    1.0
+ *   Initial U-Boot Release.
+ *     Tested with Netgear GA622T (83820)
+ *     and SMC9452TX (83821)
+ *     NOTE: custom boards with these chips may (likely) require
+ *     a programmed EEPROM device (if present) in order to work
+ *     correctly.
+*/
+
+/* Includes */
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#if defined(CONFIG_CMD_NET) \
+       && defined(CONFIG_NET_MULTI) && defined(CONFIG_NS8382X)
+
+/* defines */
+#define DSIZE     0x00000FFF
+#define ETH_ALEN               6
+#define CRC_SIZE  4
+#define TOUT_LOOP   500000
+#define TX_BUF_SIZE    1536
+#define RX_BUF_SIZE    1536
+#define NUM_RX_DESC    4       /* Number of Rx descriptor registers. */
+
+enum register_offsets {
+       ChipCmd = 0x00,
+       ChipConfig = 0x04,
+       EECtrl = 0x08,
+       IntrMask = 0x14,
+       IntrEnable = 0x18,
+       TxRingPtr = 0x20,
+       TxRingPtrHi = 0x24,
+       TxConfig = 0x28,
+       RxRingPtr = 0x30,
+       RxRingPtrHi = 0x34,
+       RxConfig = 0x38,
+       PriQueue = 0x3C,
+       RxFilterAddr = 0x48,
+       RxFilterData = 0x4C,
+       ClkRun = 0xCC,
+       PCIPM = 0x44,
+};
+
+enum ChipCmdBits {
+       ChipReset = 0x100,
+       RxReset = 0x20,
+       TxReset = 0x10,
+       RxOff = 0x08,
+       RxOn = 0x04,
+       TxOff = 0x02,
+       TxOn = 0x01
+};
+
+enum ChipConfigBits {
+       LinkSts = 0x80000000,
+       GigSpeed = 0x40000000,
+       HundSpeed = 0x20000000,
+       FullDuplex = 0x10000000,
+       TBIEn = 0x01000000,
+       Mode1000 = 0x00400000,
+       T64En = 0x00004000,
+       D64En = 0x00001000,
+       M64En = 0x00000800,
+       PhyRst = 0x00000400,
+       PhyDis = 0x00000200,
+       ExtStEn = 0x00000100,
+       BEMode = 0x00000001,
+};
+#define SpeedStatus_Polarity ( GigSpeed | HundSpeed | FullDuplex)
+
+enum TxConfig_bits {
+       TxDrthMask      = 0x000000ff,
+       TxFlthMask      = 0x0000ff00,
+       TxMxdmaMask     = 0x00700000,
+       TxMxdma_8       = 0x00100000,
+       TxMxdma_16      = 0x00200000,
+       TxMxdma_32      = 0x00300000,
+       TxMxdma_64      = 0x00400000,
+       TxMxdma_128     = 0x00500000,
+       TxMxdma_256     = 0x00600000,
+       TxMxdma_512     = 0x00700000,
+       TxMxdma_1024    = 0x00000000,
+       TxCollRetry     = 0x00800000,
+       TxAutoPad       = 0x10000000,
+       TxMacLoop       = 0x20000000,
+       TxHeartIgn      = 0x40000000,
+       TxCarrierIgn    = 0x80000000
+};
+
+enum RxConfig_bits {
+       RxDrthMask      = 0x0000003e,
+       RxMxdmaMask     = 0x00700000,
+       RxMxdma_8       = 0x00100000,
+       RxMxdma_16      = 0x00200000,
+       RxMxdma_32      = 0x00300000,
+       RxMxdma_64      = 0x00400000,
+       RxMxdma_128     = 0x00500000,
+       RxMxdma_256     = 0x00600000,
+       RxMxdma_512     = 0x00700000,
+       RxMxdma_1024    = 0x00000000,
+       RxAcceptLenErr  = 0x04000000,
+       RxAcceptLong    = 0x08000000,
+       RxAcceptTx      = 0x10000000,
+       RxStripCRC      = 0x20000000,
+       RxAcceptRunt    = 0x40000000,
+       RxAcceptErr     = 0x80000000,
+};
+
+/* Bits in the RxMode register. */
+enum rx_mode_bits {
+       RxFilterEnable          = 0x80000000,
+       AcceptAllBroadcast      = 0x40000000,
+       AcceptAllMulticast      = 0x20000000,
+       AcceptAllUnicast        = 0x10000000,
+       AcceptPerfectMatch      = 0x08000000,
+};
+
+typedef struct _BufferDesc {
+       u32 link;
+       u32 bufptr;
+       vu_long cmdsts;
+       u32 extsts;             /*not used here */
+} BufferDesc;
+
+/* Bits in network_desc.status */
+enum desc_status_bits {
+       DescOwn = 0x80000000, DescMore = 0x40000000, DescIntr = 0x20000000,
+       DescNoCRC = 0x10000000, DescPktOK = 0x08000000,
+       DescSizeMask = 0xfff,
+
+       DescTxAbort = 0x04000000, DescTxFIFO = 0x02000000,
+       DescTxCarrier = 0x01000000, DescTxDefer = 0x00800000,
+       DescTxExcDefer = 0x00400000, DescTxOOWCol = 0x00200000,
+       DescTxExcColl = 0x00100000, DescTxCollCount = 0x000f0000,
+
+       DescRxAbort = 0x04000000, DescRxOver = 0x02000000,
+       DescRxDest = 0x01800000, DescRxLong = 0x00400000,
+       DescRxRunt = 0x00200000, DescRxInvalid = 0x00100000,
+       DescRxCRC = 0x00080000, DescRxAlign = 0x00040000,
+       DescRxLoop = 0x00020000, DesRxColl = 0x00010000,
+};
+
+/* Bits in MEAR */
+enum mii_reg_bits {
+       MDIO_ShiftClk = 0x0040,
+       MDIO_EnbOutput = 0x0020,
+       MDIO_Data = 0x0010,
+};
+
+/* PHY Register offsets.  */
+enum phy_reg_offsets {
+       BMCR = 0x00,
+       BMSR = 0x01,
+       PHYIDR1 = 0x02,
+       PHYIDR2 = 0x03,
+       ANAR = 0x04,
+       KTCR = 0x09,
+};
+
+/* basic mode control register bits */
+enum bmcr_bits {
+       Bmcr_Reset = 0x8000,
+       Bmcr_Loop = 0x4000,
+       Bmcr_Speed0 = 0x2000,
+       Bmcr_AutoNegEn = 0x1000,        /*if set ignores Duplex, Speed[01] */
+       Bmcr_RstAutoNeg = 0x0200,
+       Bmcr_Duplex = 0x0100,
+       Bmcr_Speed1 = 0x0040,
+       Bmcr_Force10H = 0x0000,
+       Bmcr_Force10F = 0x0100,
+       Bmcr_Force100H = 0x2000,
+       Bmcr_Force100F = 0x2100,
+       Bmcr_Force1000H = 0x0040,
+       Bmcr_Force1000F = 0x0140,
+};
+
+/* auto negotiation advertisement register */
+enum anar_bits {
+       anar_adv_100F = 0x0100,
+       anar_adv_100H = 0x0080,
+       anar_adv_10F = 0x0040,
+       anar_adv_10H = 0x0020,
+       anar_ieee_8023 = 0x0001,
+};
+
+/* 1K-base T control register */
+enum ktcr_bits {
+       ktcr_adv_1000H = 0x0100,
+       ktcr_adv_1000F = 0x0200,
+};
+
+/* Globals */
+static u32 SavedClkRun;
+static unsigned int cur_rx;
+static unsigned int rx_config;
+static unsigned int tx_config;
+
+/* Note: transmit and receive buffers and descriptors must be
+   long long word aligned */
+static BufferDesc txd __attribute__ ((aligned(8)));
+static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(8)));
+static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(8)));
+static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE]
+    __attribute__ ((aligned(8)));
+
+/* Function Prototypes */
+static int mdio_read(struct eth_device *dev, int phy_id, int addr);
+static void mdio_write(struct eth_device *dev, int phy_id, int addr, int value);
+static void mdio_sync(struct eth_device *dev, u32 offset);
+static int ns8382x_init(struct eth_device *dev, bd_t * bis);
+static void ns8382x_reset(struct eth_device *dev);
+static void ns8382x_init_rxfilter(struct eth_device *dev);
+static void ns8382x_init_txd(struct eth_device *dev);
+static void ns8382x_init_rxd(struct eth_device *dev);
+static void ns8382x_set_rx_mode(struct eth_device *dev);
+static void ns8382x_check_duplex(struct eth_device *dev);
+static int ns8382x_send(struct eth_device *dev, volatile void *packet,
+                       int length);
+static int ns8382x_poll(struct eth_device *dev);
+static void ns8382x_disable(struct eth_device *dev);
+
+static struct pci_device_id supported[] = {
+       {PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83820},
+       {}
+};
+
+#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a)
+#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
+
+static inline int
+INW(struct eth_device *dev, u_long addr)
+{
+       return le16_to_cpu(*(vu_short *) (addr + dev->iobase));
+}
+
+static int
+INL(struct eth_device *dev, u_long addr)
+{
+       return le32_to_cpu(*(vu_long *) (addr + dev->iobase));
+}
+
+static inline void
+OUTW(struct eth_device *dev, int command, u_long addr)
+{
+       *(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command);
+}
+
+static inline void
+OUTL(struct eth_device *dev, int command, u_long addr)
+{
+       *(vu_long *) ((addr + dev->iobase)) = cpu_to_le32(command);
+}
+
+/* Function: ns8382x_initialize
+ * Description: Retrieves the MAC address of the card, and sets up some
+ *  globals required by other routines, and initializes the NIC, making it
+ *  ready to send and receive packets.
+ * Side effects: initializes ns8382xs, ready to recieve packets.
+ * Returns:   int:          number of cards found
+ */
+
+int
+ns8382x_initialize(bd_t * bis)
+{
+       pci_dev_t devno;
+       int card_number = 0;
+       struct eth_device *dev;
+       u32 iobase, status;
+       int i, idx = 0;
+       u32 phyAddress;
+       u32 tmp;
+       u32 chip_config;
+
+       while (1) {             /* Find PCI device(s) */
+               if ((devno = pci_find_devices(supported, idx++)) < 0)
+                       break;
+
+               pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase);
+               iobase &= ~0x3; /* 1: unused and 0:I/O Space Indicator */
+
+#ifdef NS8382X_DEBUG
+               printf("ns8382x: NatSemi dp8382x @ 0x%x\n", iobase);
+#endif
+
+               pci_write_config_dword(devno, PCI_COMMAND,
+                                      PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+               /* Check if I/O accesses and Bus Mastering are enabled. */
+               pci_read_config_dword(devno, PCI_COMMAND, &status);
+               if (!(status & PCI_COMMAND_MEMORY)) {
+                       printf("Error: Can not enable MEM access.\n");
+                       continue;
+               } else if (!(status & PCI_COMMAND_MASTER)) {
+                       printf("Error: Can not enable Bus Mastering.\n");
+                       continue;
+               }
+
+               dev = (struct eth_device *) malloc(sizeof *dev);
+
+               sprintf(dev->name, "dp8382x#%d", card_number);
+               dev->iobase = bus_to_phys(iobase);
+               dev->priv = (void *) devno;
+               dev->init = ns8382x_init;
+               dev->halt = ns8382x_disable;
+               dev->send = ns8382x_send;
+               dev->recv = ns8382x_poll;
+
+               /* ns8382x has a non-standard PM control register
+                * in PCI config space.  Some boards apparently need
+                * to be brought to D0 in this manner.  */
+               pci_read_config_dword(devno, PCIPM, &tmp);
+               if (tmp & (0x03 | 0x100)) {     /* D0 state, disable PME assertion */
+                       u32 newtmp = tmp & ~(0x03 | 0x100);
+                       pci_write_config_dword(devno, PCIPM, newtmp);
+               }
+
+               /* get MAC address */
+               for (i = 0; i < 3; i++) {
+                       u32 data;
+                       char *mac = (char *)&dev->enetaddr[i * 2];
+
+                       OUTL(dev, i * 2, RxFilterAddr);
+                       data = INL(dev, RxFilterData);
+                       *mac++ = data;
+                       *mac++ = data >> 8;
+               }
+               /* get PHY address, can't be zero */
+               for (phyAddress = 1; phyAddress < 32; phyAddress++) {
+                       u32 rev, phy1;
+
+                       phy1 = mdio_read(dev, phyAddress, PHYIDR1);
+                       if (phy1 == 0x2000) {   /*check for 83861/91 */
+                               rev = mdio_read(dev, phyAddress, PHYIDR2);
+                               if ((rev & ~(0x000f)) == 0x00005c50 ||
+                                   (rev & ~(0x000f)) == 0x00005c60) {
+#ifdef NS8382X_DEBUG
+                                       printf("phy rev is %x\n", rev);
+                                       printf("phy address is %x\n",
+                                              phyAddress);
+#endif
+                                       break;
+                               }
+                       }
+               }
+
+               /* set phy to autonegotiate && advertise everything */
+               mdio_write(dev, phyAddress, KTCR,
+                          (ktcr_adv_1000H | ktcr_adv_1000F));
+               mdio_write(dev, phyAddress, ANAR,
+                          (anar_adv_100F | anar_adv_100H | anar_adv_10H |
+                           anar_adv_10F | anar_ieee_8023));
+               mdio_write(dev, phyAddress, BMCR, 0x0); /*restore */
+               mdio_write(dev, phyAddress, BMCR,
+                          (Bmcr_AutoNegEn | Bmcr_RstAutoNeg));
+               /* Reset the chip to erase any previous misconfiguration. */
+               OUTL(dev, (ChipReset), ChipCmd);
+
+               chip_config = INL(dev, ChipConfig);
+               /* reset the phy */
+               OUTL(dev, (chip_config | PhyRst), ChipConfig);
+               /* power up and initialize transceiver */
+               OUTL(dev, (chip_config & ~(PhyDis)), ChipConfig);
+
+               mdio_sync(dev, EECtrl);
+#ifdef NS8382X_DEBUG
+               {
+                       u32 chpcfg =
+                           INL(dev, ChipConfig) ^ SpeedStatus_Polarity;
+
+                       printf("%s: Transceiver 10%s %s duplex.\n", dev->name,
+                              (chpcfg & GigSpeed) ? "00" : (chpcfg & HundSpeed)
+                              ? "0" : "",
+                              chpcfg & FullDuplex ? "full" : "half");
+                       printf("%s: %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
+                              dev->enetaddr[0], dev->enetaddr[1],
+                              dev->enetaddr[2], dev->enetaddr[3],
+                              dev->enetaddr[4], dev->enetaddr[5]);
+               }
+#endif
+               /* Disable PME:
+                * The PME bit is initialized from the EEPROM contents.
+                * PCI cards probably have PME disabled, but motherboard
+                * implementations may have PME set to enable WakeOnLan.
+                * With PME set the chip will scan incoming packets but
+                * nothing will be written to memory. */
+               SavedClkRun = INL(dev, ClkRun);
+               OUTL(dev, SavedClkRun & ~0x100, ClkRun);
+
+               eth_register(dev);
+
+               card_number++;
+
+               pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x60);
+
+               udelay(10 * 1000);
+       }
+       return card_number;
+}
+
+/*  MII transceiver control section.
+       Read and write MII registers using software-generated serial MDIO
+       protocol.  See the MII specifications or DP83840A data sheet for details.
+
+       The maximum data clock rate is 2.5 Mhz.  To meet minimum timing we
+       must flush writes to the PCI bus with a PCI read. */
+#define mdio_delay(mdio_addr) INL(dev, mdio_addr)
+
+#define MDIO_EnbIn  (0)
+#define MDIO_WRITE0 (MDIO_EnbOutput)
+#define MDIO_WRITE1 (MDIO_Data | MDIO_EnbOutput)
+
+/* Generate the preamble required for initial synchronization and
+   a few older transceivers. */
+static void
+mdio_sync(struct eth_device *dev, u32 offset)
+{
+       int bits = 32;
+
+       /* Establish sync by sending at least 32 logic ones. */
+       while (--bits >= 0) {
+               OUTL(dev, MDIO_WRITE1, offset);
+               mdio_delay(offset);
+               OUTL(dev, MDIO_WRITE1 | MDIO_ShiftClk, offset);
+               mdio_delay(offset);
+       }
+}
+
+static int
+mdio_read(struct eth_device *dev, int phy_id, int addr)
+{
+       int mii_cmd = (0xf6 << 10) | (phy_id << 5) | addr;
+       int i, retval = 0;
+
+       /* Shift the read command bits out. */
+       for (i = 15; i >= 0; i--) {
+               int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
+
+               OUTL(dev, dataval, EECtrl);
+               mdio_delay(EECtrl);
+               OUTL(dev, dataval | MDIO_ShiftClk, EECtrl);
+               mdio_delay(EECtrl);
+       }
+       /* Read the two transition, 16 data, and wire-idle bits. */
+       for (i = 19; i > 0; i--) {
+               OUTL(dev, MDIO_EnbIn, EECtrl);
+               mdio_delay(EECtrl);
+               retval =
+                   (retval << 1) | ((INL(dev, EECtrl) & MDIO_Data) ? 1 : 0);
+               OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl);
+               mdio_delay(EECtrl);
+       }
+       return (retval >> 1) & 0xffff;
+}
+
+static void
+mdio_write(struct eth_device *dev, int phy_id, int addr, int value)
+{
+       int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (addr << 18) | value;
+       int i;
+
+       /* Shift the command bits out. */
+       for (i = 31; i >= 0; i--) {
+               int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
+
+               OUTL(dev, dataval, EECtrl);
+               mdio_delay(EECtrl);
+               OUTL(dev, dataval | MDIO_ShiftClk, EECtrl);
+               mdio_delay(EECtrl);
+       }
+       /* Clear out extra bits. */
+       for (i = 2; i > 0; i--) {
+               OUTL(dev, MDIO_EnbIn, EECtrl);
+               mdio_delay(EECtrl);
+               OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl);
+               mdio_delay(EECtrl);
+       }
+       return;
+}
+
+/* Function: ns8382x_init
+ * Description: resets the ethernet controller chip and configures
+ *    registers and data structures required for sending and receiving packets.
+ * Arguments: struct eth_device *dev:       NIC data structure
+ * returns:    int.
+ */
+
+static int
+ns8382x_init(struct eth_device *dev, bd_t * bis)
+{
+       u32 config;
+
+       ns8382x_reset(dev);
+
+       /* Disable PME:
+        * The PME bit is initialized from the EEPROM contents.
+        * PCI cards probably have PME disabled, but motherboard
+        * implementations may have PME set to enable WakeOnLan.
+        * With PME set the chip will scan incoming packets but
+        * nothing will be written to memory. */
+       OUTL(dev, SavedClkRun & ~0x100, ClkRun);
+
+       ns8382x_init_rxfilter(dev);
+       ns8382x_init_txd(dev);
+       ns8382x_init_rxd(dev);
+
+       /*set up ChipConfig */
+       config = INL(dev, ChipConfig);
+       /*turn off 64 bit ops && Ten-bit interface
+        * && big-endian mode && extended status */
+       config &= ~(TBIEn | Mode1000 | T64En | D64En | M64En | BEMode | PhyDis | ExtStEn);
+       OUTL(dev, config, ChipConfig);
+
+       /* Configure the PCI bus bursts and FIFO thresholds. */
+       tx_config = TxCarrierIgn | TxHeartIgn | TxAutoPad
+           | TxCollRetry | TxMxdma_1024 | (0x1002);
+       rx_config = RxMxdma_1024 | 0x20;
+#ifdef NS8382X_DEBUG
+       printf("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config);
+       printf("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config);
+#endif
+       OUTL(dev, tx_config, TxConfig);
+       OUTL(dev, rx_config, RxConfig);
+
+       /*turn off priority queueing */
+       OUTL(dev, 0x0, PriQueue);
+
+       ns8382x_check_duplex(dev);
+       ns8382x_set_rx_mode(dev);
+
+       OUTL(dev, (RxOn | TxOn), ChipCmd);
+       return 1;
+}
+
+/* Function: ns8382x_reset
+ * Description: soft resets the controller chip
+ * Arguments: struct eth_device *dev:          NIC data structure
+ * Returns:   void.
+ */
+static void
+ns8382x_reset(struct eth_device *dev)
+{
+       OUTL(dev, ChipReset, ChipCmd);
+       while (INL(dev, ChipCmd))
+               /*wait until done */ ;
+       OUTL(dev, 0, IntrMask);
+       OUTL(dev, 0, IntrEnable);
+}
+
+/* Function: ns8382x_init_rxfilter
+ * Description: sets receive filter address to our MAC address
+ * Arguments: struct eth_device *dev:          NIC data structure
+ * returns:   void.
+ */
+
+static void
+ns8382x_init_rxfilter(struct eth_device *dev)
+{
+       int i;
+
+       for (i = 0; i < ETH_ALEN; i += 2) {
+               OUTL(dev, i, RxFilterAddr);
+               OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8),
+                    RxFilterData);
+       }
+}
+
+/* Function: ns8382x_init_txd
+ * Description: initializes the Tx descriptor
+ * Arguments: struct eth_device *dev:          NIC data structure
+ * returns:   void.
+ */
+
+static void
+ns8382x_init_txd(struct eth_device *dev)
+{
+       txd.link = (u32) 0;
+       txd.bufptr = cpu_to_le32((u32) & txb[0]);
+       txd.cmdsts = (u32) 0;
+       txd.extsts = (u32) 0;
+
+       OUTL(dev, 0x0, TxRingPtrHi);
+       OUTL(dev, phys_to_bus((u32)&txd), TxRingPtr);
+#ifdef NS8382X_DEBUG
+       printf("ns8382x_init_txd: TX descriptor register loaded with: %#08X (&txd: %p)\n",
+              INL(dev, TxRingPtr), &txd);
+#endif
+}
+
+/* Function: ns8382x_init_rxd
+ * Description: initializes the Rx descriptor ring
+ * Arguments: struct eth_device *dev:          NIC data structure
+ * Returns:   void.
+ */
+
+static void
+ns8382x_init_rxd(struct eth_device *dev)
+{
+       int i;
+
+       OUTL(dev, 0x0, RxRingPtrHi);
+
+       cur_rx = 0;
+       for (i = 0; i < NUM_RX_DESC; i++) {
+               rxd[i].link =
+                   cpu_to_le32((i + 1 <
+                                NUM_RX_DESC) ? (u32) & rxd[i +
+                                                           1] : (u32) &
+                               rxd[0]);
+               rxd[i].extsts = cpu_to_le32((u32) 0x0);
+               rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE);
+               rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]);
+#ifdef NS8382X_DEBUG
+               printf
+                   ("ns8382x_init_rxd: rxd[%d]=%p link=%X cmdsts=%X bufptr=%X\n",
+                    i, &rxd[i], le32_to_cpu(rxd[i].link),
+                    le32_to_cpu(rxd[i].cmdsts), le32_to_cpu(rxd[i].bufptr));
+#endif
+       }
+       OUTL(dev, phys_to_bus((u32) & rxd), RxRingPtr);
+
+#ifdef NS8382X_DEBUG
+       printf("ns8382x_init_rxd: RX descriptor register loaded with: %X\n",
+              INL(dev, RxRingPtr));
+#endif
+}
+
+/* Function: ns8382x_set_rx_mode
+ * Description:
+ *    sets the receive mode to accept all broadcast packets and packets
+ *    with our MAC address, and reject all multicast packets.
+ * Arguments: struct eth_device *dev:          NIC data structure
+ * Returns:   void.
+ */
+
+static void
+ns8382x_set_rx_mode(struct eth_device *dev)
+{
+       u32 rx_mode = 0x0;
+       /*spec says RxFilterEnable has to be 0 for rest of
+        * this stuff to be properly configured. Linux driver
+        * seems to support this*/
+/*     OUTL(dev, rx_mode, RxFilterAddr);*/
+       rx_mode = (RxFilterEnable | AcceptAllBroadcast | AcceptPerfectMatch);
+       OUTL(dev, rx_mode, RxFilterAddr);
+       printf("ns8382x_set_rx_mode: set to %X\n", rx_mode);
+       /*now we turn RxFilterEnable back on */
+       /*rx_mode |= RxFilterEnable;
+       OUTL(dev, rx_mode, RxFilterAddr);*/
+}
+
+static void
+ns8382x_check_duplex(struct eth_device *dev)
+{
+       int gig = 0;
+       int hun = 0;
+       int duplex = 0;
+       int config = (INL(dev, ChipConfig) ^ SpeedStatus_Polarity);
+
+       duplex = (config & FullDuplex) ? 1 : 0;
+       gig = (config & GigSpeed) ? 1 : 0;
+       hun = (config & HundSpeed) ? 1 : 0;
+#ifdef NS8382X_DEBUG
+       printf("%s: Setting 10%s %s-duplex based on negotiated link"
+              " capability.\n", dev->name, (gig) ? "00" : (hun) ? "0" : "",
+              duplex ? "full" : "half");
+#endif
+       if (duplex) {
+               rx_config |= RxAcceptTx;
+               tx_config |= (TxCarrierIgn | TxHeartIgn);
+       } else {
+               rx_config &= ~RxAcceptTx;
+               tx_config &= ~(TxCarrierIgn | TxHeartIgn);
+       }
+#ifdef NS8382X_DEBUG
+       printf("%s: Resetting TxConfig Register %#08X\n", dev->name, tx_config);
+       printf("%s: Resetting RxConfig Register %#08X\n", dev->name, rx_config);
+#endif
+       OUTL(dev, tx_config, TxConfig);
+       OUTL(dev, rx_config, RxConfig);
+
+       /*if speed is 10 or 100, remove MODE1000,
+        * if it's 1000, then set it */
+       config = INL(dev, ChipConfig);
+       if (gig)
+               config |= Mode1000;
+       else
+               config &= ~Mode1000;
+
+#ifdef NS8382X_DEBUG
+       printf("%s: %setting Mode1000\n", dev->name, (gig) ? "S" : "Uns");
+#endif
+       OUTL(dev, config, ChipConfig);
+}
+
+/* Function: ns8382x_send
+ * Description: transmits a packet and waits for completion or timeout.
+ * Returns:   void.  */
+static int
+ns8382x_send(struct eth_device *dev, volatile void *packet, int length)
+{
+       u32 i, status = 0;
+       vu_long tx_stat = 0;
+
+       /* Stop the transmitter */
+       OUTL(dev, TxOff, ChipCmd);
+#ifdef NS8382X_DEBUG
+       printf("ns8382x_send: sending %d bytes\n", (int)length);
+#endif
+
+       /* set the transmit buffer descriptor and enable Transmit State Machine */
+       txd.link = cpu_to_le32(0x0);
+       txd.bufptr = cpu_to_le32(phys_to_bus((u32)packet));
+       txd.extsts = cpu_to_le32(0x0);
+       txd.cmdsts = cpu_to_le32(DescOwn | length);
+
+       /* load Transmit Descriptor Register */
+       OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr);
+#ifdef NS8382X_DEBUG
+       printf("ns8382x_send: TX descriptor register loaded with: %#08X\n",
+              INL(dev, TxRingPtr));
+       printf("\ttxd.link:%X\tbufp:%X\texsts:%X\tcmdsts:%X\n",
+              le32_to_cpu(txd.link), le32_to_cpu(txd.bufptr),
+              le32_to_cpu(txd.extsts), le32_to_cpu(txd.cmdsts));
+#endif
+       /* restart the transmitter */
+       OUTL(dev, TxOn, ChipCmd);
+
+       for (i = 0; (tx_stat = le32_to_cpu(txd.cmdsts)) & DescOwn; i++) {
+               if (i >= TOUT_LOOP) {
+                       printf ("%s: tx error buffer not ready: txd.cmdsts %#X\n",
+                            dev->name, tx_stat);
+                       goto Done;
+               }
+       }
+
+       if (!(tx_stat & DescPktOK)) {
+               printf("ns8382x_send: Transmit error, Tx status %X.\n", tx_stat);
+               goto Done;
+       }
+#ifdef NS8382X_DEBUG
+       printf("ns8382x_send: tx_stat: %#08X\n", tx_stat);
+#endif
+
+       status = 1;
+      Done:
+       return status;
+}
+
+/* Function: ns8382x_poll
+ * Description: checks for a received packet and returns it if found.
+ * Arguments: struct eth_device *dev:          NIC data structure
+ * Returns:   1 if    packet was received.
+ *            0 if no packet was received.
+ * Side effects:
+ *            Returns (copies) the packet to the array dev->packet.
+ *            Returns the length of the packet.
+ */
+
+static int
+ns8382x_poll(struct eth_device *dev)
+{
+       int retstat = 0;
+       int length = 0;
+       vu_long rx_status = le32_to_cpu(rxd[cur_rx].cmdsts);
+
+       if (!(rx_status & (u32) DescOwn))
+               return retstat;
+#ifdef NS8382X_DEBUG
+       printf("ns8382x_poll: got a packet: cur_rx:%u, status:%lx\n",
+              cur_rx, rx_status);
+#endif
+       length = (rx_status & DSIZE) - CRC_SIZE;
+
+       if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) {
+               /* corrupted packet received */
+               printf("ns8382x_poll: Corrupted packet, status:%lx\n", rx_status);
+               retstat = 0;
+       } else {
+               /* give packet to higher level routine */
+               NetReceive((rxb + cur_rx * RX_BUF_SIZE), length);
+               retstat = 1;
+       }
+
+       /* return the descriptor and buffer to receive ring */
+       rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE);
+       rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]);
+
+       if (++cur_rx == NUM_RX_DESC)
+               cur_rx = 0;
+
+       /* re-enable the potentially idle receive state machine */
+       OUTL(dev, RxOn, ChipCmd);
+
+       return retstat;
+}
+
+/* Function: ns8382x_disable
+ * Description: Turns off interrupts and stops Tx and Rx engines
+ * Arguments: struct eth_device *dev:          NIC data structure
+ * Returns:   void.
+ */
+
+static void
+ns8382x_disable(struct eth_device *dev)
+{
+       /* Disable interrupts using the mask. */
+       OUTL(dev, 0, IntrMask);
+       OUTL(dev, 0, IntrEnable);
+
+       /* Stop the chip's Tx and Rx processes. */
+       OUTL(dev, (RxOff | TxOff), ChipCmd);
+
+       /* Restore PME enable bit */
+       OUTL(dev, SavedClkRun, ClkRun);
+}
+
+#endif
diff --git a/drivers/net/ns9750_eth.c b/drivers/net/ns9750_eth.c
new file mode 100644 (file)
index 0000000..067ff8e
--- /dev/null
@@ -0,0 +1,797 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2004 by FS Forth-Systeme GmbH.
+ * All rights reserved.
+ *
+ * $Id: ns9750_eth.c,v 1.2 2004/02/24 14:09:39 mpietrek Exp $
+ * @Author: Markus Pietrek
+ * @Descr: Ethernet driver for the NS9750. Uses DMA Engine with polling
+ *        interrupt status. But interrupts are not enabled.
+ *        Only one tx buffer descriptor and the RXA buffer descriptor are used
+ *        Currently no transmit lockup handling is included. eth_send has a 5s
+ *        timeout for sending frames. No retransmits are performed when an
+ *        error occurs.
+ * @References: [1] NS9750 Hardware Reference, December 2003
+ *             [2] Intel LXT971 Datasheet #249414 Rev. 02
+ *             [3] NS7520 Linux Ethernet Driver
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ***********************************************************************/
+
+#include <common.h>
+#include <net.h>               /* NetSendPacket */
+
+#include "ns9750_eth.h"                /* for Ethernet and PHY */
+
+#ifdef CONFIG_DRIVER_NS9750_ETHERNET
+
+/* some definition to make transistion to linux easier */
+
+#define NS9750_DRIVER_NAME     "eth"
+#define KERN_WARNING           "Warning:"
+#define KERN_ERR               "Error:"
+#define KERN_INFO              "Info:"
+
+#if 0
+# define DEBUG
+#endif
+
+#ifdef DEBUG
+# define printk                        printf
+
+# define DEBUG_INIT            0x0001
+# define DEBUG_MINOR           0x0002
+# define DEBUG_RX              0x0004
+# define DEBUG_TX              0x0008
+# define DEBUG_INT             0x0010
+# define DEBUG_POLL            0x0020
+# define DEBUG_LINK            0x0040
+# define DEBUG_MII             0x0100
+# define DEBUG_MII_LOW         0x0200
+# define DEBUG_MEM             0x0400
+# define DEBUG_ERROR           0x4000
+# define DEBUG_ERROR_CRIT      0x8000
+
+static int nDebugLvl = DEBUG_ERROR_CRIT;
+
+# define DEBUG_ARGS0( FLG, a0 ) if( ( nDebugLvl & (FLG) ) == (FLG) ) \
+               printf("%s: " a0, __FUNCTION__, 0, 0, 0, 0, 0, 0 )
+# define DEBUG_ARGS1( FLG, a0, a1 ) if( ( nDebugLvl & (FLG) ) == (FLG)) \
+               printf("%s: " a0, __FUNCTION__, (int)(a1), 0, 0, 0, 0, 0 )
+# define DEBUG_ARGS2( FLG, a0, a1, a2 ) if( (nDebugLvl & (FLG)) ==(FLG))\
+               printf("%s: " a0, __FUNCTION__, (int)(a1), (int)(a2), 0, 0,0,0 )
+# define DEBUG_ARGS3( FLG, a0, a1, a2, a3 ) if((nDebugLvl &(FLG))==(FLG))\
+               printf("%s: "a0,__FUNCTION__,(int)(a1),(int)(a2),(int)(a3),0,0,0)
+# define DEBUG_FN( FLG ) if( (nDebugLvl & (FLG)) == (FLG) ) \
+               printf("\r%s:line %d\n", (int)__FUNCTION__, __LINE__, 0,0,0,0);
+# define ASSERT( expr, func ) if( !( expr ) ) { \
+               printf( "Assertion failed! %s:line %d %s\n", \
+               (int)__FUNCTION__,__LINE__,(int)(#expr),0,0,0); \
+               func }
+#else /* DEBUG */
+# define printk(...)
+# define DEBUG_ARGS0( FLG, a0 )
+# define DEBUG_ARGS1( FLG, a0, a1 )
+# define DEBUG_ARGS2( FLG, a0, a1, a2 )
+# define DEBUG_ARGS3( FLG, a0, a1, a2, a3 )
+# define DEBUG_FN( n )
+# define ASSERT(expr, func)
+#endif /* DEBUG */
+
+#define NS9750_MII_NEG_DELAY           (5*CFG_HZ) /* in s */
+#define TX_TIMEOUT                     (5*CFG_HZ) /* in s */
+
+/* @TODO move it to eeprom.h */
+#define FS_EEPROM_AUTONEG_MASK         0x7
+#define FS_EEPROM_AUTONEG_SPEED_MASK   0x1
+#define FS_EEPROM_AUTONEG_SPEED_10     0x0
+#define FS_EEPROM_AUTONEG_SPEED_100    0x1
+#define FS_EEPROM_AUTONEG_DUPLEX_MASK  0x2
+#define FS_EEPROM_AUTONEG_DUPLEX_HALF  0x0
+#define FS_EEPROM_AUTONEG_DUPLEX_FULL  0x2
+#define FS_EEPROM_AUTONEG_ENABLE_MASK  0x4
+#define FS_EEPROM_AUTONEG_DISABLE      0x0
+#define FS_EEPROM_AUTONEG_ENABLE       0x4
+
+/* buffer descriptors taken from [1] p.306 */
+typedef struct
+{
+       unsigned int* punSrc;
+       unsigned int unLen;     /* 11 bits */
+       unsigned int* punDest;  /* unused */
+       union {
+               unsigned int unReg;
+               struct {
+                       unsigned uStatus : 16;
+                       unsigned uRes : 12;
+                       unsigned uFull : 1;
+                       unsigned uEnable : 1;
+                       unsigned uInt : 1;
+                       unsigned uWrap : 1;
+               } bits;
+       } s;
+} rx_buffer_desc_t;
+
+typedef struct
+{
+       unsigned int* punSrc;
+       unsigned int unLen;     /* 10 bits */
+       unsigned int* punDest;  /* unused */
+       union {
+               unsigned int unReg; /* only 32bit accesses may done to NS9750
+                                    * eth engine */
+               struct {
+                       unsigned uStatus : 16;
+                       unsigned uRes : 12;
+                       unsigned uFull : 1;
+                       unsigned uLast : 1;
+                       unsigned uInt : 1;
+                       unsigned uWrap : 1;
+               } bits;
+       } s;
+} tx_buffer_desc_t;
+
+static int ns9750_eth_reset( void );
+
+static void ns9750_link_force( void );
+static void ns9750_link_auto_negotiate( void );
+static void ns9750_link_update_egcr( void );
+static void ns9750_link_print_changed( void );
+
+/* the PHY stuff */
+
+static char ns9750_mii_identify_phy( void );
+static unsigned short ns9750_mii_read( unsigned short uiRegister );
+static void ns9750_mii_write( unsigned short uiRegister, unsigned short uiData );
+static unsigned int ns9750_mii_get_clock_divisor( unsigned int unMaxMDIOClk );
+static unsigned int ns9750_mii_poll_busy( void );
+
+static unsigned int nPhyMaxMdioClock = PHY_MDIO_MAX_CLK;
+static unsigned char ucLinkMode =      FS_EEPROM_AUTONEG_ENABLE;
+static unsigned int uiLastLinkStatus;
+static PhyType phyDetected = PHY_NONE;
+
+/* we use only one tx buffer descriptor */
+static tx_buffer_desc_t* pTxBufferDesc =
+       (tx_buffer_desc_t*) get_eth_reg_addr( NS9750_ETH_TXBD );
+
+/* we use only one rx buffer descriptor of the 4 */
+static rx_buffer_desc_t aRxBufferDesc[ 4 ];
+
+/***********************************************************************
+ * @Function: eth_init
+ * @Return: -1 on failure otherwise 0
+ * @Descr: Initializes the ethernet engine and uses either FS Forth's default
+ *        MAC addr or the one in environment
+ ***********************************************************************/
+
+int eth_init (bd_t * pbis)
+{
+       /* This default MAC Addr is reserved by FS Forth-Systeme for the case of
+          EEPROM failures */
+       unsigned char aucMACAddr[6] = { 0x00, 0x04, 0xf3, 0x00, 0x06, 0x35 };
+       char *pcTmp = getenv ("ethaddr");
+       char *pcEnd;
+       int i;
+
+       DEBUG_FN (DEBUG_INIT);
+
+       /* no need to check for hardware */
+
+       if (!ns9750_eth_reset ())
+               return -1;
+
+       if (pcTmp != NULL)
+               for (i = 0; i < 6; i++) {
+                       aucMACAddr[i] =
+                               pcTmp ? simple_strtoul (pcTmp, &pcEnd,
+                                                       16) : 0;
+                       pcTmp = (*pcTmp) ? pcEnd + 1 : pcEnd;
+               }
+
+       /* configure ethernet address */
+
+       *get_eth_reg_addr (NS9750_ETH_SA1) =
+               aucMACAddr[5] << 8 | aucMACAddr[4];
+       *get_eth_reg_addr (NS9750_ETH_SA2) =
+               aucMACAddr[3] << 8 | aucMACAddr[2];
+       *get_eth_reg_addr (NS9750_ETH_SA3) =
+               aucMACAddr[1] << 8 | aucMACAddr[0];
+
+       /* enable hardware */
+
+       *get_eth_reg_addr (NS9750_ETH_MAC1) = NS9750_ETH_MAC1_RXEN;
+
+       /* the linux kernel may give packets < 60 bytes, for example arp */
+       *get_eth_reg_addr (NS9750_ETH_MAC2) = NS9750_ETH_MAC2_CRCEN |
+               NS9750_ETH_MAC2_PADEN | NS9750_ETH_MAC2_HUGE;
+
+       /* enable receive and transmit FIFO, use 10/100 Mbps MII */
+       *get_eth_reg_addr (NS9750_ETH_EGCR1) =
+               NS9750_ETH_EGCR1_ETXWM |
+               NS9750_ETH_EGCR1_ERX |
+               NS9750_ETH_EGCR1_ERXDMA |
+               NS9750_ETH_EGCR1_ETX |
+               NS9750_ETH_EGCR1_ETXDMA | NS9750_ETH_EGCR1_ITXA;
+
+       /* prepare DMA descriptors */
+       for (i = 0; i < 4; i++) {
+               aRxBufferDesc[i].punSrc = 0;
+               aRxBufferDesc[i].unLen = 0;
+               aRxBufferDesc[i].s.bits.uWrap = 1;
+               aRxBufferDesc[i].s.bits.uInt = 1;
+               aRxBufferDesc[i].s.bits.uEnable = 0;
+               aRxBufferDesc[i].s.bits.uFull = 0;
+       }
+
+       /* NetRxPackets[ 0 ] is initialized before eth_init is called and never
+          changes. NetRxPackets is 32bit aligned */
+       aRxBufferDesc[0].punSrc = (unsigned int *) NetRxPackets[0];
+       aRxBufferDesc[0].s.bits.uEnable = 1;
+       aRxBufferDesc[0].unLen = 1522;  /* as stated in [1] p.307 */
+
+       *get_eth_reg_addr (NS9750_ETH_RXAPTR) =
+               (unsigned int) &aRxBufferDesc[0];
+
+       /* [1] Tab. 221 states less than 5us */
+       *get_eth_reg_addr (NS9750_ETH_EGCR1) |= NS9750_ETH_EGCR1_ERXINIT;
+       while (!
+              (*get_eth_reg_addr (NS9750_ETH_EGSR) & NS9750_ETH_EGSR_RXINIT))
+               /* wait for finish */
+               udelay (1);
+
+       /* @TODO do we need to clear RXINIT? */
+       *get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~NS9750_ETH_EGCR1_ERXINIT;
+
+       *get_eth_reg_addr (NS9750_ETH_RXFREE) = 0x1;
+
+       return 0;
+}
+
+/***********************************************************************
+ * @Function: eth_send
+ * @Return: -1 on timeout otherwise 1
+ * @Descr: sends one frame by DMA
+ ***********************************************************************/
+
+int eth_send (volatile void *pPacket, int nLen)
+{
+       ulong ulTimeout;
+
+       DEBUG_FN (DEBUG_TX);
+
+       /* clear old status values */
+       *get_eth_reg_addr (NS9750_ETH_EINTR) &=
+               *get_eth_reg_addr (NS9750_ETH_EINTR) & NS9750_ETH_EINTR_TX_MA;
+
+       /* prepare Tx Descriptors */
+
+       pTxBufferDesc->punSrc = (unsigned int *) pPacket;       /* pPacket is 32bit
+                                                                * aligned */
+       pTxBufferDesc->unLen = nLen;
+       /* only 32bit accesses allowed. wrap, full, interrupt and enabled to 1 */
+       pTxBufferDesc->s.unReg = 0xf0000000;
+       /* pTxBufferDesc is the first possible buffer descriptor */
+       *get_eth_reg_addr (NS9750_ETH_TXPTR) = 0x0;
+
+       /* enable processor for next frame */
+
+       *get_eth_reg_addr (NS9750_ETH_EGCR2) &= ~NS9750_ETH_EGCR2_TCLER;
+       *get_eth_reg_addr (NS9750_ETH_EGCR2) |= NS9750_ETH_EGCR2_TCLER;
+
+       ulTimeout = get_timer (0);
+
+       DEBUG_ARGS0 (DEBUG_TX | DEBUG_MINOR,
+                    "Waiting for transmission to finish\n");
+       while (!
+              (*get_eth_reg_addr (NS9750_ETH_EINTR) &
+               (NS9750_ETH_EINTR_TXDONE | NS9750_ETH_EINTR_TXERR))) {
+               /* do nothing, wait for completion */
+               if (get_timer (0) - ulTimeout > TX_TIMEOUT) {
+                       DEBUG_ARGS0 (DEBUG_TX, "Transmit Timed out\n");
+                       return -1;
+               }
+       }
+       DEBUG_ARGS0 (DEBUG_TX | DEBUG_MINOR, "transmitted...\n");
+
+       return 0;
+}
+
+/***********************************************************************
+ * @Function: eth_rx
+ * @Return: size of last frame in bytes or 0 if no frame available
+ * @Descr: gives one frame to U-Boot which has been copied by DMA engine already
+ *        to NetRxPackets[ 0 ].
+ ***********************************************************************/
+
+int eth_rx (void)
+{
+       int nLen = 0;
+       unsigned int unStatus;
+
+       unStatus =
+               *get_eth_reg_addr (NS9750_ETH_EINTR) & NS9750_ETH_EINTR_RX_MA;
+
+       if (!unStatus)
+               /* no packet available, return immediately */
+               return 0;
+
+       DEBUG_FN (DEBUG_RX);
+
+       /* unLen always < max(nLen) and discard checksum */
+       nLen = (int) aRxBufferDesc[0].unLen - 4;
+
+       /* acknowledge status register */
+       *get_eth_reg_addr (NS9750_ETH_EINTR) = unStatus;
+
+       aRxBufferDesc[0].unLen = 1522;
+       aRxBufferDesc[0].s.bits.uFull = 0;
+
+       /* Buffer A descriptor available again */
+       *get_eth_reg_addr (NS9750_ETH_RXFREE) |= 0x1;
+
+       /* NetReceive may call eth_send. Due to a possible bug of the NS9750 we
+        * have to acknowledge the received frame before sending a new one */
+       if (unStatus & NS9750_ETH_EINTR_RXDONEA)
+               NetReceive (NetRxPackets[0], nLen);
+
+       return nLen;
+}
+
+/***********************************************************************
+ * @Function: eth_halt
+ * @Return: n/a
+ * @Descr: stops the ethernet engine
+ ***********************************************************************/
+
+void eth_halt (void)
+{
+       DEBUG_FN (DEBUG_INIT);
+
+       *get_eth_reg_addr (NS9750_ETH_MAC1) &= ~NS9750_ETH_MAC1_RXEN;
+       *get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~(NS9750_ETH_EGCR1_ERX |
+                                                 NS9750_ETH_EGCR1_ERXDMA |
+                                                 NS9750_ETH_EGCR1_ETX |
+                                                 NS9750_ETH_EGCR1_ETXDMA);
+}
+
+/***********************************************************************
+ * @Function: ns9750_eth_reset
+ * @Return: 0 on failure otherwise 1
+ * @Descr: resets the ethernet interface and the PHY,
+ *        performs auto negotiation or fixed modes
+ ***********************************************************************/
+
+static int ns9750_eth_reset (void)
+{
+       DEBUG_FN (DEBUG_MINOR);
+
+       /* Reset MAC */
+       *get_eth_reg_addr (NS9750_ETH_EGCR1) |= NS9750_ETH_EGCR1_MAC_HRST;
+       udelay (5);             /* according to [1], p.322 */
+       *get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~NS9750_ETH_EGCR1_MAC_HRST;
+
+       /* reset and initialize PHY */
+
+       *get_eth_reg_addr (NS9750_ETH_MAC1) &= ~NS9750_ETH_MAC1_SRST;
+
+       /* we don't support hot plugging of PHY, therefore we don't reset
+          phyDetected and nPhyMaxMdioClock here. The risk is if the setting is
+          incorrect the first open
+          may detect the PHY correctly but succeding will fail
+          For reseting the PHY and identifying we have to use the standard
+          MDIO CLOCK value 2.5 MHz only after hardware reset
+          After having identified the PHY we will do faster */
+
+       *get_eth_reg_addr (NS9750_ETH_MCFG) =
+               ns9750_mii_get_clock_divisor (nPhyMaxMdioClock);
+
+       /* reset PHY */
+       ns9750_mii_write (PHY_COMMON_CTRL, PHY_COMMON_CTRL_RESET);
+       ns9750_mii_write (PHY_COMMON_CTRL, 0);
+
+       /* @TODO check time */
+       udelay (3000);          /* [2] p.70 says at least 300us reset recovery time. But
+                                  go sure, it didn't worked stable at higher timer
+                                  frequencies under LxNETES-2.x */
+
+       /* MII clock has been setup to default, ns9750_mii_identify_phy should
+          work for all */
+
+       if (!ns9750_mii_identify_phy ()) {
+               printk (KERN_ERR NS9750_DRIVER_NAME
+                       ": Unsupported PHY, aborting\n");
+               return 0;
+       }
+
+       /* now take the highest MDIO clock possible after detection */
+       *get_eth_reg_addr (NS9750_ETH_MCFG) =
+               ns9750_mii_get_clock_divisor (nPhyMaxMdioClock);
+
+
+       /* PHY has been detected, so there can be no abort reason and we can
+          finish initializing ethernet */
+
+       uiLastLinkStatus = 0xff;        /* undefined */
+
+       if ((ucLinkMode & FS_EEPROM_AUTONEG_ENABLE_MASK) ==
+           FS_EEPROM_AUTONEG_DISABLE)
+               /* use parameters defined */
+               ns9750_link_force ();
+       else
+               ns9750_link_auto_negotiate ();
+
+       if (phyDetected == PHY_LXT971A)
+               /* set LED2 to link mode */
+               ns9750_mii_write (PHY_LXT971_LED_CFG,
+                                 PHY_LXT971_LED_CFG_LINK_ACT <<
+                                 PHY_LXT971_LED_CFG_SHIFT_LED2);
+
+       return 1;
+}
+
+/***********************************************************************
+ * @Function: ns9750_link_force
+ * @Return: void
+ * @Descr: configures eth and MII to use the link mode defined in
+ *        ucLinkMode
+ ***********************************************************************/
+
+static void ns9750_link_force (void)
+{
+       unsigned short uiControl;
+
+       DEBUG_FN (DEBUG_LINK);
+
+       uiControl = ns9750_mii_read (PHY_COMMON_CTRL);
+       uiControl &= ~(PHY_COMMON_CTRL_SPD_MA |
+                      PHY_COMMON_CTRL_AUTO_NEG | PHY_COMMON_CTRL_DUPLEX);
+
+       uiLastLinkStatus = 0;
+
+       if ((ucLinkMode & FS_EEPROM_AUTONEG_SPEED_MASK) ==
+           FS_EEPROM_AUTONEG_SPEED_100) {
+               uiControl |= PHY_COMMON_CTRL_SPD_100;
+               uiLastLinkStatus |= PHY_LXT971_STAT2_100BTX;
+       } else
+               uiControl |= PHY_COMMON_CTRL_SPD_10;
+
+       if ((ucLinkMode & FS_EEPROM_AUTONEG_DUPLEX_MASK) ==
+           FS_EEPROM_AUTONEG_DUPLEX_FULL) {
+               uiControl |= PHY_COMMON_CTRL_DUPLEX;
+               uiLastLinkStatus |= PHY_LXT971_STAT2_DUPLEX_MODE;
+       }
+
+       ns9750_mii_write (PHY_COMMON_CTRL, uiControl);
+
+       ns9750_link_print_changed ();
+       ns9750_link_update_egcr ();
+}
+
+/***********************************************************************
+ * @Function: ns9750_link_auto_negotiate
+ * @Return: void
+ * @Descr: performs auto-negotation of link.
+ ***********************************************************************/
+
+static void ns9750_link_auto_negotiate (void)
+{
+       unsigned long ulStartJiffies;
+       unsigned short uiStatus;
+
+       DEBUG_FN (DEBUG_LINK);
+
+       /* run auto-negotation */
+       /* define what we are capable of */
+       ns9750_mii_write (PHY_COMMON_AUTO_ADV,
+                         PHY_COMMON_AUTO_ADV_100BTXFD |
+                         PHY_COMMON_AUTO_ADV_100BTX |
+                         PHY_COMMON_AUTO_ADV_10BTFD |
+                         PHY_COMMON_AUTO_ADV_10BT |
+                         PHY_COMMON_AUTO_ADV_802_3);
+       /* start auto-negotiation */
+       ns9750_mii_write (PHY_COMMON_CTRL,
+                         PHY_COMMON_CTRL_AUTO_NEG |
+                         PHY_COMMON_CTRL_RES_AUTO);
+
+       /* wait for completion */
+
+       ulStartJiffies = get_ticks ();
+       while (get_ticks () < ulStartJiffies + NS9750_MII_NEG_DELAY) {
+               uiStatus = ns9750_mii_read (PHY_COMMON_STAT);
+               if ((uiStatus &
+                    (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT)) ==
+                   (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT)) {
+                       /* lucky we are, auto-negotiation succeeded */
+                       ns9750_link_print_changed ();
+                       ns9750_link_update_egcr ();
+                       return;
+               }
+       }
+
+       DEBUG_ARGS0 (DEBUG_LINK, "auto-negotiation timed out\n");
+       /* ignore invalid link settings */
+}
+
+/***********************************************************************
+ * @Function: ns9750_link_update_egcr
+ * @Return: void
+ * @Descr: updates the EGCR and MAC2 link status after mode change or
+ *        auto-negotation
+ ***********************************************************************/
+
+static void ns9750_link_update_egcr (void)
+{
+       unsigned int unEGCR;
+       unsigned int unMAC2;
+       unsigned int unIPGT;
+
+       DEBUG_FN (DEBUG_LINK);
+
+       unEGCR = *get_eth_reg_addr (NS9750_ETH_EGCR1);
+       unMAC2 = *get_eth_reg_addr (NS9750_ETH_MAC2);
+       unIPGT = *get_eth_reg_addr (NS9750_ETH_IPGT) & ~NS9750_ETH_IPGT_MA;
+
+       unMAC2 &= ~NS9750_ETH_MAC2_FULLD;
+       if ((uiLastLinkStatus & PHY_LXT971_STAT2_DUPLEX_MODE)
+           == PHY_LXT971_STAT2_DUPLEX_MODE) {
+               unMAC2 |= NS9750_ETH_MAC2_FULLD;
+               unIPGT |= 0x15; /* see [1] p. 339 */
+       } else
+               unIPGT |= 0x12; /* see [1] p. 339 */
+
+       *get_eth_reg_addr (NS9750_ETH_MAC2) = unMAC2;
+       *get_eth_reg_addr (NS9750_ETH_EGCR1) = unEGCR;
+       *get_eth_reg_addr (NS9750_ETH_IPGT) = unIPGT;
+}
+
+/***********************************************************************
+ * @Function: ns9750_link_print_changed
+ * @Return: void
+ * @Descr: checks whether the link status has changed and if so prints
+ *        the new mode
+ ***********************************************************************/
+
+static void ns9750_link_print_changed (void)
+{
+       unsigned short uiStatus;
+       unsigned short uiControl;
+
+       DEBUG_FN (DEBUG_LINK);
+
+       uiControl = ns9750_mii_read (PHY_COMMON_CTRL);
+
+       if ((uiControl & PHY_COMMON_CTRL_AUTO_NEG) ==
+           PHY_COMMON_CTRL_AUTO_NEG) {
+               /* PHY_COMMON_STAT_LNK_STAT is only set on autonegotiation */
+               uiStatus = ns9750_mii_read (PHY_COMMON_STAT);
+
+               if (!(uiStatus & PHY_COMMON_STAT_LNK_STAT)) {
+                       printk (KERN_WARNING NS9750_DRIVER_NAME
+                               ": link down\n");
+                       /* @TODO Linux: carrier_off */
+               } else {
+                       /* @TODO Linux: carrier_on */
+                       if (phyDetected == PHY_LXT971A) {
+                               uiStatus = ns9750_mii_read (PHY_LXT971_STAT2);
+                               uiStatus &= (PHY_LXT971_STAT2_100BTX |
+                                            PHY_LXT971_STAT2_DUPLEX_MODE |
+                                            PHY_LXT971_STAT2_AUTO_NEG);
+
+                               /* mask out all uninteresting parts */
+                       }
+                       /* other PHYs must store there link information in
+                          uiStatus as PHY_LXT971 */
+               }
+       } else {
+               /* mode has been forced, so uiStatus should be the same as the
+                  last link status, enforce printing */
+               uiStatus = uiLastLinkStatus;
+               uiLastLinkStatus = 0xff;
+       }
+
+       if (uiStatus != uiLastLinkStatus) {
+               /* save current link status */
+               uiLastLinkStatus = uiStatus;
+
+               /* print new link status */
+
+               printk (KERN_INFO NS9750_DRIVER_NAME
+                       ": link mode %i Mbps %s duplex %s\n",
+                       (uiStatus & PHY_LXT971_STAT2_100BTX) ? 100 : 10,
+                       (uiStatus & PHY_LXT971_STAT2_DUPLEX_MODE) ? "full" :
+                       "half",
+                       (uiStatus & PHY_LXT971_STAT2_AUTO_NEG) ? "(auto)" :
+                       "");
+       }
+}
+
+/***********************************************************************
+ * the MII low level stuff
+ ***********************************************************************/
+
+/***********************************************************************
+ * @Function: ns9750_mii_identify_phy
+ * @Return: 1 if supported PHY has been detected otherwise 0
+ * @Descr: checks for supported PHY and prints the IDs.
+ ***********************************************************************/
+
+static char ns9750_mii_identify_phy (void)
+{
+       unsigned short uiID1;
+       unsigned short uiID2;
+       unsigned char *szName;
+       char cRes = 0;
+
+       DEBUG_FN (DEBUG_MII);
+
+       phyDetected = (PhyType) uiID1 = ns9750_mii_read (PHY_COMMON_ID1);
+
+       switch (phyDetected) {
+       case PHY_LXT971A:
+               szName = "LXT971A";
+               uiID2 = ns9750_mii_read (PHY_COMMON_ID2);
+               nPhyMaxMdioClock = PHY_LXT971_MDIO_MAX_CLK;
+               cRes = 1;
+               break;
+       case PHY_NONE:
+       default:
+               /* in case uiID1 == 0 && uiID2 == 0 we may have the wrong
+                  address or reset sets the wrong NS9750_ETH_MCFG_CLKS */
+
+               uiID2 = 0;
+               szName = "unknown";
+               nPhyMaxMdioClock = PHY_MDIO_MAX_CLK;
+               phyDetected = PHY_NONE;
+       }
+
+       printk (KERN_INFO NS9750_DRIVER_NAME
+               ": PHY (0x%x, 0x%x) = %s detected\n", uiID1, uiID2, szName);
+
+       return cRes;
+}
+
+/***********************************************************************
+ * @Function: ns9750_mii_read
+ * @Return: the data read from PHY register uiRegister
+ * @Descr: the data read may be invalid if timed out. If so, a message
+ *        is printed but the invalid data is returned.
+ *        The fixed device address is being used.
+ ***********************************************************************/
+
+static unsigned short ns9750_mii_read (unsigned short uiRegister)
+{
+       DEBUG_FN (DEBUG_MII_LOW);
+
+       /* write MII register to be read */
+       *get_eth_reg_addr (NS9750_ETH_MADR) =
+               NS9750_ETH_PHY_ADDRESS << 8 | uiRegister;
+
+       *get_eth_reg_addr (NS9750_ETH_MCMD) = NS9750_ETH_MCMD_READ;
+
+       if (!ns9750_mii_poll_busy ())
+               printk (KERN_WARNING NS9750_DRIVER_NAME
+                       ": MII still busy in read\n");
+       /* continue to read */
+
+       *get_eth_reg_addr (NS9750_ETH_MCMD) = 0;
+
+       return (unsigned short) (*get_eth_reg_addr (NS9750_ETH_MRDD));
+}
+
+
+/***********************************************************************
+ * @Function: ns9750_mii_write
+ * @Return: nothing
+ * @Descr: writes the data to the PHY register. In case of a timeout,
+ *        no special handling is performed but a message printed
+ *        The fixed device address is being used.
+ ***********************************************************************/
+
+static void ns9750_mii_write (unsigned short uiRegister,
+                             unsigned short uiData)
+{
+       DEBUG_FN (DEBUG_MII_LOW);
+
+       /* write MII register to be written */
+       *get_eth_reg_addr (NS9750_ETH_MADR) =
+               NS9750_ETH_PHY_ADDRESS << 8 | uiRegister;
+
+       *get_eth_reg_addr (NS9750_ETH_MWTD) = uiData;
+
+       if (!ns9750_mii_poll_busy ()) {
+               printf (KERN_WARNING NS9750_DRIVER_NAME
+                       ": MII still busy in write\n");
+       }
+}
+
+
+/***********************************************************************
+ * @Function: ns9750_mii_get_clock_divisor
+ * @Return: the clock divisor that should be used in NS9750_ETH_MCFG_CLKS
+ * @Descr: if no clock divisor can be calculated for the
+ *        current SYSCLK and the maximum MDIO Clock, a warning is printed
+ *        and the greatest divisor is taken
+ ***********************************************************************/
+
+static unsigned int ns9750_mii_get_clock_divisor (unsigned int unMaxMDIOClk)
+{
+       struct {
+               unsigned int unSysClkDivisor;
+               unsigned int unClks;    /* field for NS9750_ETH_MCFG_CLKS */
+       } PHYClockDivisors[] = {
+               {
+               4, NS9750_ETH_MCFG_CLKS_4}, {
+               6, NS9750_ETH_MCFG_CLKS_6}, {
+               8, NS9750_ETH_MCFG_CLKS_8}, {
+               10, NS9750_ETH_MCFG_CLKS_10}, {
+               20, NS9750_ETH_MCFG_CLKS_20}, {
+               30, NS9750_ETH_MCFG_CLKS_30}, {
+               40, NS9750_ETH_MCFG_CLKS_40}
+       };
+
+       int nIndexSysClkDiv;
+       int nArraySize =
+               sizeof (PHYClockDivisors) / sizeof (PHYClockDivisors[0]);
+       unsigned int unClks = NS9750_ETH_MCFG_CLKS_40;  /* defaults to
+                                                          greatest div */
+
+       DEBUG_FN (DEBUG_INIT);
+
+       for (nIndexSysClkDiv = 0; nIndexSysClkDiv < nArraySize;
+            nIndexSysClkDiv++) {
+               /* find first sysclock divisor that isn't higher than 2.5 MHz
+                  clock */
+               if (AHB_CLK_FREQ /
+                   PHYClockDivisors[nIndexSysClkDiv].unSysClkDivisor <=
+                   unMaxMDIOClk) {
+                       unClks = PHYClockDivisors[nIndexSysClkDiv].unClks;
+                       break;
+               }
+       }
+
+       DEBUG_ARGS2 (DEBUG_INIT,
+                    "Taking MDIO Clock bit mask 0x%0x for max clock %i\n",
+                    unClks, unMaxMDIOClk);
+
+       /* return greatest divisor */
+       return unClks;
+}
+
+/***********************************************************************
+ * @Function: ns9750_mii_poll_busy
+ * @Return: 0 if timed out otherwise the remaing timeout
+ * @Descr: waits until the MII has completed a command or it times out
+ *        code may be interrupted by hard interrupts.
+ *        It is not checked what happens on multiple actions when
+ *        the first is still being busy and we timeout.
+ ***********************************************************************/
+
+static unsigned int ns9750_mii_poll_busy (void)
+{
+       unsigned int unTimeout = 10000;
+
+       DEBUG_FN (DEBUG_MII_LOW);
+
+       while (((*get_eth_reg_addr (NS9750_ETH_MIND) & NS9750_ETH_MIND_BUSY)
+               == NS9750_ETH_MIND_BUSY) && unTimeout)
+               unTimeout--;
+
+       return unTimeout;
+}
+
+#endif /* CONFIG_DRIVER_NS9750_ETHERNET */
diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c
new file mode 100644 (file)
index 0000000..2af0e8f
--- /dev/null
@@ -0,0 +1,526 @@
+/*
+ * (C) Copyright 2002 Wolfgang Grandegger, wg@denx.de.
+ *
+ * This driver for AMD PCnet network controllers is derived from the
+ * Linux driver pcnet32.c written 1996-1999 by Thomas Bogendoerfer.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#if 0
+#define        PCNET_DEBUG_LEVEL       0 /* 0=off, 1=init, 2=rx/tx */
+#endif
+
+#if PCNET_DEBUG_LEVEL > 0
+#define        PCNET_DEBUG1(fmt,args...)       printf (fmt ,##args)
+#if PCNET_DEBUG_LEVEL > 1
+#define        PCNET_DEBUG2(fmt,args...)       printf (fmt ,##args)
+#else
+#define PCNET_DEBUG2(fmt,args...)
+#endif
+#else
+#define PCNET_DEBUG1(fmt,args...)
+#define PCNET_DEBUG2(fmt,args...)
+#endif
+
+#if defined(CONFIG_CMD_NET) \
+       && defined(CONFIG_NET_MULTI) && defined(CONFIG_PCNET)
+
+#if !defined(CONF_PCNET_79C973) && defined(CONF_PCNET_79C975)
+#error "Macro for PCnet chip version is not defined!"
+#endif
+
+/*
+ * Set the number of Tx and Rx buffers, using Log_2(# buffers).
+ * Reasonable default values are 4 Tx buffers, and 16 Rx buffers.
+ * That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4).
+ */
+#define PCNET_LOG_TX_BUFFERS   0
+#define PCNET_LOG_RX_BUFFERS   2
+
+#define TX_RING_SIZE           (1 << (PCNET_LOG_TX_BUFFERS))
+#define TX_RING_LEN_BITS       ((PCNET_LOG_TX_BUFFERS) << 12)
+
+#define RX_RING_SIZE           (1 << (PCNET_LOG_RX_BUFFERS))
+#define RX_RING_LEN_BITS       ((PCNET_LOG_RX_BUFFERS) << 4)
+
+#define PKT_BUF_SZ             1544
+
+/* The PCNET Rx and Tx ring descriptors. */
+struct pcnet_rx_head {
+    u32 base;
+    s16 buf_length;
+    s16 status;
+    u32 msg_length;
+    u32 reserved;
+};
+
+struct pcnet_tx_head {
+    u32 base;
+    s16 length;
+    s16 status;
+    u32 misc;
+    u32 reserved;
+};
+
+/* The PCNET 32-Bit initialization block, described in databook. */
+struct pcnet_init_block {
+    u16 mode;
+    u16 tlen_rlen;
+    u8 phys_addr[6];
+    u16 reserved;
+    u32 filter[2];
+    /* Receive and transmit ring base, along with extra bits. */
+    u32 rx_ring;
+    u32 tx_ring;
+    u32 reserved2;
+};
+
+typedef struct pcnet_priv {
+    struct pcnet_rx_head    rx_ring[RX_RING_SIZE];
+    struct pcnet_tx_head    tx_ring[TX_RING_SIZE];
+    struct pcnet_init_block init_block;
+    /* Receive Buffer space */
+    unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4];
+    int cur_rx;
+    int cur_tx;
+} pcnet_priv_t;
+
+static pcnet_priv_t *lp;
+
+/* Offsets from base I/O address for WIO mode */
+#define PCNET_RDP              0x10
+#define PCNET_RAP              0x12
+#define PCNET_RESET            0x14
+#define PCNET_BDP              0x16
+
+static u16 pcnet_read_csr (struct eth_device *dev, int index)
+{
+    outw (index, dev->iobase+PCNET_RAP);
+    return inw (dev->iobase+PCNET_RDP);
+}
+
+static void pcnet_write_csr (struct eth_device *dev, int index, u16 val)
+{
+    outw (index, dev->iobase+PCNET_RAP);
+    outw (val, dev->iobase+PCNET_RDP);
+}
+
+static u16 pcnet_read_bcr (struct eth_device *dev, int index)
+{
+    outw (index, dev->iobase+PCNET_RAP);
+    return inw (dev->iobase+PCNET_BDP);
+}
+
+static void pcnet_write_bcr (struct eth_device *dev, int index, u16 val)
+{
+    outw (index, dev->iobase+PCNET_RAP);
+    outw (val, dev->iobase+PCNET_BDP);
+}
+
+static void pcnet_reset (struct eth_device *dev)
+{
+    inw (dev->iobase+PCNET_RESET);
+}
+
+static int pcnet_check (struct eth_device *dev)
+{
+    outw (88, dev->iobase+PCNET_RAP);
+    return (inw (dev->iobase+PCNET_RAP) == 88);
+}
+
+static int  pcnet_init( struct eth_device* dev, bd_t *bis);
+static int  pcnet_send (struct eth_device* dev, volatile void *packet,
+                       int length);
+static int  pcnet_recv (struct eth_device* dev);
+static void pcnet_halt (struct eth_device* dev);
+static int  pcnet_probe(struct eth_device* dev, bd_t *bis, int dev_num);
+
+#define PCI_TO_MEM(d,a) pci_phys_to_mem((pci_dev_t)d->priv, (u_long)(a))
+#define PCI_TO_MEM_LE(d,a) (u32)(cpu_to_le32(PCI_TO_MEM(d,a)))
+
+static struct pci_device_id supported[] = {
+       { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE },
+       { }
+};
+
+
+int pcnet_initialize(bd_t *bis)
+{
+    pci_dev_t devbusfn;
+    struct eth_device* dev;
+    u16 command, status;
+    int dev_nr = 0;
+
+    PCNET_DEBUG1("\npcnet_initialize...\n");
+
+    for (dev_nr = 0; ; dev_nr++) {
+
+       /*
+        * Find the PCnet PCI device(s).
+        */
+       if ((devbusfn = pci_find_devices(supported, dev_nr)) < 0) {
+           break;
+       }
+
+       /*
+        * Allocate and pre-fill the device structure.
+        */
+       dev = (struct eth_device*) malloc(sizeof *dev);
+       dev->priv = (void *)devbusfn;
+       sprintf(dev->name, "pcnet#%d", dev_nr);
+
+       /*
+        * Setup the PCI device.
+        */
+       pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, (unsigned int *)&dev->iobase);
+       dev->iobase &= ~0xf;
+
+       PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%x: ",
+              dev->name, devbusfn, dev->iobase);
+
+       command = PCI_COMMAND_IO | PCI_COMMAND_MASTER;
+       pci_write_config_word(devbusfn, PCI_COMMAND, command);
+       pci_read_config_word(devbusfn, PCI_COMMAND, &status);
+       if ((status & command) != command) {
+           printf("%s: Couldn't enable IO access or Bus Mastering\n",
+                  dev->name);
+           free(dev);
+           continue;
+       }
+
+       pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x40);
+
+       /*
+        * Probe the PCnet chip.
+        */
+       if (pcnet_probe(dev, bis, dev_nr) < 0) {
+           free(dev);
+           continue;
+       }
+
+       /*
+        * Setup device structure and register the driver.
+        */
+       dev->init   = pcnet_init;
+       dev->halt   = pcnet_halt;
+       dev->send   = pcnet_send;
+       dev->recv   = pcnet_recv;
+
+       eth_register(dev);
+    }
+
+    udelay(10 * 1000);
+
+    return dev_nr;
+}
+
+static int pcnet_probe(struct eth_device* dev, bd_t *bis, int dev_nr)
+{
+    int chip_version;
+    char *chipname;
+#ifdef PCNET_HAS_PROM
+    int i;
+#endif
+
+    /* Reset the PCnet controller */
+    pcnet_reset(dev);
+
+    /* Check if register access is working */
+    if (pcnet_read_csr(dev, 0) != 4 || !pcnet_check(dev)) {
+       printf("%s: CSR register access check failed\n", dev->name);
+       return -1;
+    }
+
+    /* Identify the chip */
+    chip_version = pcnet_read_csr(dev, 88) | (pcnet_read_csr(dev,89) << 16);
+    if ((chip_version & 0xfff) != 0x003)
+       return -1;
+    chip_version = (chip_version >> 12) & 0xffff;
+    switch (chip_version) {
+#ifdef CONFIG_PCNET_79C973
+    case 0x2625:
+       chipname = "PCnet/FAST III 79C973"; /* PCI */
+       break;
+#endif
+#ifdef CONFIG_PCNET_79C975
+    case 0x2627:
+       chipname = "PCnet/FAST III 79C975"; /* PCI */
+       break;
+#endif
+    default:
+       printf("%s: PCnet version %#x not supported\n",
+              dev->name, chip_version);
+       return -1;
+    }
+
+    PCNET_DEBUG1("AMD %s\n", chipname);
+
+#ifdef PCNET_HAS_PROM
+    /*
+     * In most chips, after a chip reset, the ethernet address is read from
+     * the station address PROM at the base address and programmed into the
+     * "Physical Address Registers" CSR12-14.
+     */
+    for (i = 0; i < 3; i++) {
+       unsigned int val;
+       val = pcnet_read_csr(dev, i+12) & 0x0ffff;
+       /* There may be endianness issues here. */
+       dev->enetaddr[2*i  ] =  val       & 0x0ff;
+       dev->enetaddr[2*i+1] = (val >> 8) & 0x0ff;
+    }
+#endif /* PCNET_HAS_PROM */
+
+    return 0;
+}
+
+static int pcnet_init(struct eth_device* dev, bd_t *bis)
+{
+    int i, val;
+    u32 addr;
+
+    PCNET_DEBUG1("%s: pcnet_init...\n", dev->name);
+
+    /* Switch pcnet to 32bit mode */
+    pcnet_write_bcr (dev, 20, 2);
+
+#ifdef CONFIG_PN62
+    /* Setup LED registers */
+    val = pcnet_read_bcr (dev, 2) | 0x1000;
+    pcnet_write_bcr (dev, 2, val);    /* enable LEDPE */
+    pcnet_write_bcr (dev, 4, 0x5080); /* 100MBit */
+    pcnet_write_bcr (dev, 5, 0x40c0); /* LNKSE */
+    pcnet_write_bcr (dev, 6, 0x4090); /* TX Activity */
+    pcnet_write_bcr (dev, 7, 0x4084); /* RX Activity */
+#endif
+
+    /* Set/reset autoselect bit */
+    val = pcnet_read_bcr (dev, 2) & ~2;
+    val |= 2;
+    pcnet_write_bcr (dev, 2, val);
+
+    /* Enable auto negotiate, setup, disable fd */
+    val = pcnet_read_bcr(dev, 32) & ~0x98;
+    val |= 0x20;
+    pcnet_write_bcr(dev, 32, val);
+
+    /*
+     * We only maintain one structure because the drivers will never
+     * be used concurrently. In 32bit mode the RX and TX ring entries
+     * must be aligned on 16-byte boundaries.
+     */
+    if (lp == NULL) {
+       addr = (u32)malloc(sizeof(pcnet_priv_t) + 0x10);
+       addr = (addr + 0xf) & ~0xf;
+       lp = (pcnet_priv_t *)addr;
+    }
+
+    lp->init_block.mode = cpu_to_le16(0x0000);
+    lp->init_block.filter[0] = 0x00000000;
+    lp->init_block.filter[1] = 0x00000000;
+
+    /*
+     * Initialize the Rx ring.
+     */
+    lp->cur_rx = 0;
+    for (i = 0; i < RX_RING_SIZE; i++) {
+       lp->rx_ring[i].base = PCI_TO_MEM_LE(dev, lp->rx_buf[i]);
+       lp->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ);
+       lp->rx_ring[i].status = cpu_to_le16(0x8000);
+       PCNET_DEBUG1("Rx%d: base=0x%x buf_length=0x%hx status=0x%hx\n",
+              i, lp->rx_ring[i].base, lp->rx_ring[i].buf_length,
+              lp->rx_ring[i].status);
+    }
+
+    /*
+     * Initialize the Tx ring. The Tx buffer address is filled in as
+     * needed, but we do need to clear the upper ownership bit.
+     */
+    lp->cur_tx = 0;
+    for (i = 0; i < TX_RING_SIZE; i++) {
+       lp->tx_ring[i].base = 0;
+       lp->tx_ring[i].status = 0;
+    }
+
+    /*
+     * Setup Init Block.
+     */
+    PCNET_DEBUG1("Init block at 0x%p: MAC", &lp->init_block);
+
+    for (i = 0; i < 6; i++) {
+       lp->init_block.phys_addr[i] = dev->enetaddr[i];
+       PCNET_DEBUG1(" %02x", lp->init_block.phys_addr[i]);
+    }
+
+    lp->init_block.tlen_rlen = cpu_to_le16(TX_RING_LEN_BITS |
+                                          RX_RING_LEN_BITS);
+    lp->init_block.rx_ring = PCI_TO_MEM_LE(dev, lp->rx_ring);
+    lp->init_block.tx_ring = PCI_TO_MEM_LE(dev, lp->tx_ring);
+
+    PCNET_DEBUG1("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n",
+          lp->init_block.tlen_rlen,
+          lp->init_block.rx_ring, lp->init_block.tx_ring);
+
+    /*
+     * Tell the controller where the Init Block is located.
+     */
+    addr = PCI_TO_MEM(dev, &lp->init_block);
+    pcnet_write_csr(dev, 1, addr & 0xffff);
+    pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff);
+
+    pcnet_write_csr (dev, 4, 0x0915);
+    pcnet_write_csr (dev, 0, 0x0001); /* start */
+
+    /* Wait for Init Done bit */
+    for (i = 10000; i > 0; i--) {
+       if (pcnet_read_csr (dev, 0) & 0x0100)
+           break;
+       udelay(10);
+    }
+    if (i <= 0) {
+       printf("%s: TIMEOUT: controller init failed\n", dev->name);
+       pcnet_reset (dev);
+       return 0;
+    }
+
+    /*
+     * Finally start network controller operation.
+     */
+    pcnet_write_csr (dev, 0, 0x0002);
+
+    return 1;
+}
+
+static int pcnet_send(struct eth_device* dev, volatile void *packet, int pkt_len)
+{
+    int i, status;
+    struct pcnet_tx_head *entry = &lp->tx_ring[lp->cur_tx];
+
+    PCNET_DEBUG2("Tx%d: %d bytes from 0x%p ", lp->cur_tx, pkt_len, packet);
+
+    /* Wait for completion by testing the OWN bit */
+    for (i = 1000; i > 0; i--) {
+       status = le16_to_cpu(entry->status);
+       if ((status & 0x8000) == 0)
+           break;
+       udelay(100);
+       PCNET_DEBUG2(".");
+    }
+    if (i <= 0) {
+       printf("%s: TIMEOUT: Tx%d failed (status = 0x%x)\n",
+              dev->name, lp->cur_tx, status);
+       pkt_len = 0;
+       goto failure;
+    }
+
+    /*
+     * Setup Tx ring. Caution: the write order is important here,
+     * set the status with the "ownership" bits last.
+     */
+    status = 0x8300;
+    entry->length = le16_to_cpu(-pkt_len);
+    entry->misc   = 0x00000000;
+    entry->base   = PCI_TO_MEM_LE(dev, packet);
+    entry->status = le16_to_cpu(status);
+
+    /* Trigger an immediate send poll. */
+    pcnet_write_csr (dev, 0, 0x0008);
+
+ failure:
+    if (++lp->cur_tx >= TX_RING_SIZE)
+       lp->cur_tx = 0;
+
+    PCNET_DEBUG2("done\n");
+    return pkt_len;
+}
+
+static int pcnet_recv(struct eth_device* dev)
+{
+    struct pcnet_rx_head *entry;
+    int pkt_len = 0;
+    u16 status;
+
+    while (1) {
+       entry = &lp->rx_ring[lp->cur_rx];
+       /*
+        * If we own the next entry, it's a new packet. Send it up.
+        */
+       if (((status = le16_to_cpu(entry->status)) & 0x8000) != 0) {
+           break;
+       }
+       status >>= 8;
+
+       if (status != 0x03) {   /* There was an error. */
+
+           printf("%s: Rx%d", dev->name, lp->cur_rx);
+           PCNET_DEBUG1(" (status=0x%x)", status);
+           if (status & 0x20) printf(" Frame");
+           if (status & 0x10) printf(" Overflow");
+           if (status & 0x08) printf(" CRC");
+           if (status & 0x04) printf(" Fifo");
+           printf(" Error\n");
+           entry->status &= le16_to_cpu(0x03ff);
+
+       } else {
+
+           pkt_len = (le32_to_cpu(entry->msg_length) & 0xfff) - 4;
+           if (pkt_len < 60) {
+               printf("%s: Rx%d: invalid packet length %d\n",
+                      dev->name, lp->cur_rx, pkt_len);
+           } else {
+               NetReceive(lp->rx_buf[lp->cur_rx], pkt_len);
+               PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n",
+                      lp->cur_rx, pkt_len, lp->rx_buf[lp->cur_rx]);
+           }
+       }
+       entry->status |= cpu_to_le16(0x8000);
+
+       if (++lp->cur_rx >= RX_RING_SIZE)
+           lp->cur_rx = 0;
+    }
+    return pkt_len;
+}
+
+static void pcnet_halt(struct eth_device* dev)
+{
+    int i;
+
+    PCNET_DEBUG1("%s: pcnet_halt...\n", dev->name);
+
+    /* Reset the PCnet controller */
+    pcnet_reset (dev);
+
+    /* Wait for Stop bit */
+    for (i = 1000; i > 0; i--) {
+       if (pcnet_read_csr (dev, 0) & 0x4)
+           break;
+       udelay(10);
+    }
+    if (i <= 0) {
+       printf("%s: TIMEOUT: controller reset failed\n", dev->name);
+    }
+}
+
+#endif
diff --git a/drivers/net/plb2800_eth.c b/drivers/net/plb2800_eth.c
new file mode 100644 (file)
index 0000000..0ae5d80
--- /dev/null
@@ -0,0 +1,396 @@
+/*
+ * PLB2800 internal switch ethernet driver.
+ *
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_CMD_NET) \
+       && defined(CONFIG_NET_MULTI) && defined(CONFIG_PLB2800_ETHER)
+
+#include <malloc.h>
+#include <net.h>
+#include <asm/addrspace.h>
+
+
+#define NUM_RX_DESC    PKTBUFSRX
+#define TOUT_LOOP      1000000
+
+#define LONG_REF(addr) (*((volatile unsigned long*)addr))
+
+#define CMAC_CRX_CTRL  LONG_REF(0xb800c870)
+#define CMAC_CTX_CTRL  LONG_REF(0xb800c874)
+#define SYS_MAC_ADDR_0 LONG_REF(0xb800c878)
+#define SYS_MAC_ADDR_1 LONG_REF(0xb800c87c)
+#define MIPS_H_MASK    LONG_REF(0xB800C810)
+
+#define MA_LEARN       LONG_REF(0xb8008004)
+#define DA_LOOKUP      LONG_REF(0xb8008008)
+
+#define CMAC_CRX_CTRL_PD       0x00000001
+#define CMAC_CRX_CTRL_CG       0x00000002
+#define CMAC_CRX_CTRL_PL_SHIFT 2
+#define CMAC_CRIT              0x0
+#define CMAC_NON_CRIT          0x1
+#define MBOX_STAT_ID_SHF       28
+#define MBOX_STAT_CP           0x80000000
+#define MBOX_STAT_MB           0x00000001
+#define EN_MA_LEARN            0x02000000
+#define EN_DA_LKUP             0x01000000
+#define MA_DEST_SHF            11
+#define DA_DEST_SHF            11
+#define DA_STATE_SHF           19
+#define TSTAMP_MS              0x00000000
+#define SW_H_MBOX4_MASK                0x08000000
+#define SW_H_MBOX3_MASK                0x04000000
+#define SW_H_MBOX2_MASK                0x02000000
+#define SW_H_MBOX1_MASK                0x01000000
+
+typedef volatile struct {
+  unsigned int stat;
+  unsigned int cmd;
+  unsigned int cnt;
+  unsigned int adr;
+} mailbox_t;
+
+#define MBOX_REG(mb) ((mailbox_t*)(0xb800c830+(mb<<4)))
+
+typedef volatile struct {
+  unsigned int word0;
+  unsigned int word1;
+  unsigned int word2;
+} mbhdr_t;
+
+#define MBOX_MEM(mb) ((void*)(0xb800a000+((3-mb)<<11)))
+
+
+static int plb2800_eth_init(struct eth_device *dev, bd_t * bis);
+static int plb2800_eth_send(struct eth_device *dev, volatile void *packet,
+                                                 int length);
+static int plb2800_eth_recv(struct eth_device *dev);
+static void plb2800_eth_halt(struct eth_device *dev);
+
+static void plb2800_set_mac_addr(struct eth_device *dev, unsigned char * addr);
+static unsigned char * plb2800_get_mac_addr(void);
+
+static int rx_new;
+static int mac_addr_set = 0;
+
+
+int plb2800_eth_initialize(bd_t * bis)
+{
+       struct eth_device *dev;
+       ulong temp;
+
+#ifdef DEBUG
+       printf("Entered plb2800_eth_initialize()\n");
+#endif
+
+       if (!(dev = (struct eth_device *) malloc (sizeof *dev)))
+       {
+               printf("Failed to allocate memory\n");
+               return 0;
+       }
+       memset(dev, 0, sizeof(*dev));
+
+       sprintf(dev->name, "PLB2800 Switch");
+       dev->init = plb2800_eth_init;
+       dev->halt = plb2800_eth_halt;
+       dev->send = plb2800_eth_send;
+       dev->recv = plb2800_eth_recv;
+
+       eth_register(dev);
+
+       /* bug fix */
+       *(ulong *)0xb800e800 = 0x838;
+
+       /* Set MBOX ownership */
+       temp = CMAC_CRIT << MBOX_STAT_ID_SHF;
+       MBOX_REG(0)->stat = temp;
+       MBOX_REG(1)->stat = temp;
+
+       temp = CMAC_NON_CRIT << MBOX_STAT_ID_SHF;
+       MBOX_REG(2)->stat = temp;
+       MBOX_REG(3)->stat = temp;
+
+       plb2800_set_mac_addr(dev, plb2800_get_mac_addr());
+
+       /* Disable all Mbox interrupt */
+       temp = MIPS_H_MASK;
+       temp &= ~ (SW_H_MBOX1_MASK | SW_H_MBOX2_MASK | SW_H_MBOX3_MASK | SW_H_MBOX4_MASK) ;
+       MIPS_H_MASK = temp;
+
+#ifdef DEBUG
+       printf("Leaving plb2800_eth_initialize()\n");
+#endif
+
+       return 1;
+}
+
+static int plb2800_eth_init(struct eth_device *dev, bd_t * bis)
+{
+#ifdef DEBUG
+       printf("Entering plb2800_eth_init()\n");
+#endif
+
+       plb2800_set_mac_addr(dev, dev->enetaddr);
+
+       rx_new = 0;
+
+#ifdef DEBUG
+       printf("Leaving plb2800_eth_init()\n");
+#endif
+
+       return 0;
+}
+
+
+static int plb2800_eth_send(struct eth_device *dev, volatile void *packet,
+                                                 int length)
+{
+       int                    i;
+       int                    res         = -1;
+       u32                    temp;
+       mailbox_t *            mb          = MBOX_REG(0);
+       char      *            mem         = MBOX_MEM(0);
+
+#ifdef DEBUG
+       printf("Entered plb2800_eth_send()\n");
+#endif
+
+       if (length <= 0)
+       {
+               printf ("%s: bad packet size: %d\n", dev->name, length);
+               goto Done;
+       }
+
+       if (length < 64)
+       {
+               length = 64;
+       }
+
+       temp = CMAC_CRX_CTRL_CG | ((length + 4) << CMAC_CRX_CTRL_PL_SHIFT);
+
+#ifdef DEBUG
+       printf("0 mb->stat = 0x%x\n",  mb->stat);
+#endif
+
+       for(i = 0; mb->stat & (MBOX_STAT_CP | MBOX_STAT_MB); i++)
+       {
+               if (i >= TOUT_LOOP)
+               {
+                       printf("%s: tx buffer not ready\n", dev->name);
+                       printf("1 mb->stat = 0x%x\n",  mb->stat);
+                       goto Done;
+               }
+       }
+
+               /* For some strange reason, memcpy doesn't work, here!
+                */
+       do
+       {
+               int words = (length >> 2) + 1;
+               unsigned int* dst = (unsigned int*)(mem);
+               unsigned int* src = (unsigned int*)(packet);
+               for (i = 0; i < words; i++)
+               {
+                       *dst = *src;
+                       dst++;
+                       src++;
+               };
+       } while(0);
+
+       CMAC_CRX_CTRL = temp;
+       mb->cmd = MBOX_STAT_CP;
+
+#ifdef DEBUG
+       printf("2 mb->stat = 0x%x\n",  mb->stat);
+#endif
+
+       res = length;
+Done:
+
+#ifdef DEBUG
+       printf("Leaving plb2800_eth_send()\n");
+#endif
+
+       return res;
+}
+
+
+static int plb2800_eth_recv(struct eth_device *dev)
+{
+       int                    length  = 0;
+       mailbox_t            * mbox    = MBOX_REG(3);
+       unsigned char        * hdr     = MBOX_MEM(3);
+       unsigned int           stat;
+
+#ifdef DEBUG
+       printf("Entered plb2800_eth_recv()\n");
+#endif
+
+       for (;;)
+       {
+               stat = mbox->stat;
+
+               if (!(stat & MBOX_STAT_CP))
+               {
+                       break;
+               }
+
+               length = ((*(hdr + 6) & 0x3f) << 8) + *(hdr + 7);
+               memcpy((void *)NetRxPackets[rx_new], hdr + 12, length);
+
+               stat &= ~MBOX_STAT_CP;
+               mbox->stat = stat;
+#ifdef DEBUG
+               {
+                       int i;
+                       for (i=0;i<length - 4;i++)
+                       {
+                               if (i % 16 == 0) printf("\n%04x: ", i);
+                               printf("%02X ", NetRxPackets[rx_new][i]);
+                       }
+                       printf("\n");
+               }
+#endif
+
+               if (length)
+               {
+#ifdef DEBUG
+                       printf("Received %d bytes\n", length);
+#endif
+                       NetReceive((void*)(NetRxPackets[rx_new]),
+                                   length - 4);
+               }
+               else
+               {
+#if 1
+                       printf("Zero length!!!\n");
+#endif
+               }
+
+               rx_new = (rx_new + 1) % NUM_RX_DESC;
+       }
+
+#ifdef DEBUG
+       printf("Leaving plb2800_eth_recv()\n");
+#endif
+
+       return length;
+}
+
+
+static void plb2800_eth_halt(struct eth_device *dev)
+{
+#ifdef DEBUG
+       printf("Entered plb2800_eth_halt()\n");
+#endif
+
+#ifdef DEBUG
+       printf("Leaving plb2800_eth_halt()\n");
+#endif
+}
+
+static void plb2800_set_mac_addr(struct eth_device *dev, unsigned char * addr)
+{
+       char packet[60];
+       ulong temp;
+       int ix;
+
+       if (mac_addr_set ||
+           NULL == addr || memcmp(addr, "\0\0\0\0\0\0", 6) == 0)
+       {
+               return;
+       }
+
+       /* send one packet through CPU port
+        * in order to learn system MAC address
+        */
+
+       /* Set DA_LOOKUP register */
+       temp = EN_MA_LEARN | (0 << DA_STATE_SHF) | (63 << DA_DEST_SHF);
+       DA_LOOKUP = temp;
+
+       /* Set MA_LEARN register */
+       temp = 50 << MA_DEST_SHF;       /* static entry */
+       MA_LEARN = temp;
+
+       /* set destination address */
+       for (ix=0;ix<6;ix++)
+               packet[ix] = 0xff;
+
+       /* set source address = system MAC address */
+       for (ix=0;ix<6;ix++)
+               packet[6+ix] = addr[ix];
+
+       /* set type field */
+       packet[12]=0xaa;
+       packet[13]=0x55;
+
+       /* set data field */
+       for(ix=14;ix<60;ix++)
+               packet[ix] = 0x00;
+
+#ifdef DEBUG
+       for (ix=0;ix<6;ix++)
+               printf("mac_addr[%d]=%02X\n", ix, (unsigned char)packet[6+ix]);
+#endif
+
+       /* set one packet */
+       plb2800_eth_send(dev, packet, sizeof(packet));
+
+       /* delay for a while */
+       for(ix=0;ix<65535;ix++)
+               temp = ~temp;
+
+       /* Set CMAC_CTX_CTRL register */
+       temp = TSTAMP_MS;       /* no autocast */
+       CMAC_CTX_CTRL = temp;
+
+       /* Set DA_LOOKUP register */
+       temp = EN_DA_LKUP;
+       DA_LOOKUP = temp;
+
+       mac_addr_set = 1;
+}
+
+static unsigned char * plb2800_get_mac_addr(void)
+{
+       static unsigned char addr[6];
+       char *tmp, *end;
+       int i;
+
+       tmp = getenv ("ethaddr");
+       if (NULL == tmp) return NULL;
+
+       for (i=0; i<6; i++) {
+               addr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
+               if (tmp)
+                       tmp = (*end) ? end+1 : end;
+       }
+
+       return addr;
+}
+
+#endif /* CONFIG_PLB2800_ETHER */
diff --git a/drivers/net/rtl8019.c b/drivers/net/rtl8019.c
new file mode 100644 (file)
index 0000000..409a69f
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * Realtek 8019AS Ethernet
+ * (C) Copyright 2002-2003
+ * Xue Ligong(lgxue@hotmail.com),Wang Kehao, ESLAB, whut.edu.cn
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * This code works in 8bit mode.
+ * If you need to work in 16bit mode, PLS change it!
+ */
+
+#include <common.h>
+#include <command.h>
+#include "rtl8019.h"
+#include <net.h>
+
+#ifdef CONFIG_DRIVER_RTL8019
+
+#if defined(CONFIG_CMD_NET)
+
+
+/* packet page register access functions */
+
+
+static unsigned char get_reg (unsigned int regno)
+{
+       return (*(unsigned char *) regno);
+}
+
+
+static void put_reg (unsigned int regno, unsigned char val)
+{
+       *(volatile unsigned char *) regno = val;
+}
+
+static void eth_reset (void)
+{
+       unsigned char ucTemp;
+
+       /* reset NIC */
+       ucTemp = get_reg (RTL8019_RESET);
+       put_reg (RTL8019_RESET, ucTemp);
+       put_reg (RTL8019_INTERRUPTSTATUS, 0xff);
+       udelay (2000);          /* wait for 2ms */
+}
+
+void rtl8019_get_enetaddr (uchar * addr)
+{
+       unsigned char i;
+       unsigned char temp;
+
+       eth_reset ();
+
+       put_reg (RTL8019_COMMAND, RTL8019_REMOTEDMARD);
+       put_reg (RTL8019_DATACONFIGURATION, 0x48);
+       put_reg (RTL8019_REMOTESTARTADDRESS0, 0x00);
+       put_reg (RTL8019_REMOTESTARTADDRESS1, 0x00);
+       put_reg (RTL8019_REMOTEBYTECOUNT0, 12);
+       put_reg (RTL8019_REMOTEBYTECOUNT1, 0x00);
+       put_reg (RTL8019_COMMAND, RTL8019_REMOTEDMARD);
+       printf ("MAC: ");
+       for (i = 0; i < 6; i++) {
+               temp = get_reg (RTL8019_DMA_DATA);
+               *addr++ = temp;
+               temp = get_reg (RTL8019_DMA_DATA);
+               printf ("%x:", temp);
+       }
+
+       while ((!get_reg (RTL8019_INTERRUPTSTATUS) & 0x40));
+       printf ("\b \n");
+       put_reg (RTL8019_REMOTEBYTECOUNT0, 0x00);
+       put_reg (RTL8019_REMOTEBYTECOUNT1, 0x00);
+       put_reg (RTL8019_COMMAND, RTL8019_PAGE0);
+}
+
+
+void eth_halt (void)
+{
+       put_reg (RTL8019_COMMAND, 0x01);
+}
+
+int eth_init (bd_t * bd)
+{
+       eth_reset ();
+       put_reg (RTL8019_COMMAND, RTL8019_PAGE0STOP);
+       put_reg (RTL8019_DATACONFIGURATION, 0x48);
+       put_reg (RTL8019_REMOTEBYTECOUNT0, 0x00);
+       put_reg (RTL8019_REMOTEBYTECOUNT1, 0x00);
+       put_reg (RTL8019_RECEIVECONFIGURATION, 0x00);   /*00; */
+       put_reg (RTL8019_TRANSMITPAGE, RTL8019_TPSTART);
+       put_reg (RTL8019_TRANSMITCONFIGURATION, 0x02);
+       put_reg (RTL8019_PAGESTART, RTL8019_PSTART);
+       put_reg (RTL8019_BOUNDARY, RTL8019_PSTART);
+       put_reg (RTL8019_PAGESTOP, RTL8019_PSTOP);
+       put_reg (RTL8019_INTERRUPTSTATUS, 0xff);
+       put_reg (RTL8019_INTERRUPTMASK, 0x11);  /*b; */
+       put_reg (RTL8019_COMMAND, RTL8019_PAGE1STOP);
+       put_reg (RTL8019_PHYSICALADDRESS0, bd->bi_enetaddr[0]);
+       put_reg (RTL8019_PHYSICALADDRESS1, bd->bi_enetaddr[1]);
+       put_reg (RTL8019_PHYSICALADDRESS2, bd->bi_enetaddr[2]);
+       put_reg (RTL8019_PHYSICALADDRESS3, bd->bi_enetaddr[3]);
+       put_reg (RTL8019_PHYSICALADDRESS4, bd->bi_enetaddr[4]);
+       put_reg (RTL8019_PHYSICALADDRESS5, bd->bi_enetaddr[5]);
+       put_reg (RTL8019_MULTIADDRESS0, 0x00);
+       put_reg (RTL8019_MULTIADDRESS1, 0x00);
+       put_reg (RTL8019_MULTIADDRESS2, 0x00);
+       put_reg (RTL8019_MULTIADDRESS3, 0x00);
+       put_reg (RTL8019_MULTIADDRESS4, 0x00);
+       put_reg (RTL8019_MULTIADDRESS5, 0x00);
+       put_reg (RTL8019_MULTIADDRESS6, 0x00);
+       put_reg (RTL8019_MULTIADDRESS7, 0x00);
+       put_reg (RTL8019_CURRENT, RTL8019_PSTART);
+       put_reg (RTL8019_COMMAND, RTL8019_PAGE0);
+       put_reg (RTL8019_TRANSMITCONFIGURATION, 0xe0);  /*58; */
+
+       return 0;
+}
+
+
+static unsigned char nic_to_pc (void)
+{
+       unsigned char rec_head_status;
+       unsigned char next_packet_pointer;
+       unsigned char packet_length0;
+       unsigned char packet_length1;
+       unsigned short rxlen = 0;
+       unsigned int i = 4;
+       unsigned char current_point;
+       unsigned char *addr;
+
+       /*
+        * The RTL8019's first 4B is packet status,page of next packet
+        * and packet length(2B).So we receive the fist 4B.
+        */
+       put_reg (RTL8019_REMOTESTARTADDRESS1, get_reg (RTL8019_BOUNDARY));
+       put_reg (RTL8019_REMOTESTARTADDRESS0, 0x00);
+       put_reg (RTL8019_REMOTEBYTECOUNT1, 0x00);
+       put_reg (RTL8019_REMOTEBYTECOUNT0, 0x04);
+
+       put_reg (RTL8019_COMMAND, RTL8019_REMOTEDMARD);
+
+       rec_head_status = get_reg (RTL8019_DMA_DATA);
+       next_packet_pointer = get_reg (RTL8019_DMA_DATA);
+       packet_length0 = get_reg (RTL8019_DMA_DATA);
+       packet_length1 = get_reg (RTL8019_DMA_DATA);
+
+       put_reg (RTL8019_COMMAND, RTL8019_PAGE0);
+       /*Packet length is in two 8bit registers */
+       rxlen = packet_length1;
+       rxlen = (((rxlen << 8) & 0xff00) + packet_length0);
+       rxlen -= 4;
+
+       if (rxlen > PKTSIZE_ALIGN + PKTALIGN)
+               printf ("packet too big!\n");
+
+       /*Receive the packet */
+       put_reg (RTL8019_REMOTESTARTADDRESS0, 0x04);
+       put_reg (RTL8019_REMOTESTARTADDRESS1, get_reg (RTL8019_BOUNDARY));
+
+       put_reg (RTL8019_REMOTEBYTECOUNT0, (rxlen & 0xff));
+       put_reg (RTL8019_REMOTEBYTECOUNT1, ((rxlen >> 8) & 0xff));
+
+
+       put_reg (RTL8019_COMMAND, RTL8019_REMOTEDMARD);
+
+       for (addr = (unsigned char *) NetRxPackets[0], i = rxlen; i > 0; i--)
+               *addr++ = get_reg (RTL8019_DMA_DATA);
+       /* Pass the packet up to the protocol layers. */
+       NetReceive (NetRxPackets[0], rxlen);
+
+       while (!(get_reg (RTL8019_INTERRUPTSTATUS)) & 0x40);    /* wait for the op. */
+
+       /*
+        * To test whether the packets are all received,get the
+        * location of current point
+        */
+       put_reg (RTL8019_COMMAND, RTL8019_PAGE1);
+       current_point = get_reg (RTL8019_CURRENT);
+       put_reg (RTL8019_COMMAND, RTL8019_PAGE0);
+       put_reg (RTL8019_BOUNDARY, next_packet_pointer);
+       return current_point;
+}
+
+/* Get a data block via Ethernet */
+extern int eth_rx (void)
+{
+       unsigned char temp, current_point;
+
+       put_reg (RTL8019_COMMAND, RTL8019_PAGE0);
+
+       while (1) {
+               temp = get_reg (RTL8019_INTERRUPTSTATUS);
+
+               if (temp & 0x90) {
+                       /*overflow */
+                       put_reg (RTL8019_COMMAND, RTL8019_PAGE0STOP);
+                       udelay (2000);
+                       put_reg (RTL8019_REMOTEBYTECOUNT0, 0);
+                       put_reg (RTL8019_REMOTEBYTECOUNT1, 0);
+                       put_reg (RTL8019_TRANSMITCONFIGURATION, 2);
+                       do {
+                               current_point = nic_to_pc ();
+                       } while (get_reg (RTL8019_BOUNDARY) != current_point);
+
+                       put_reg (RTL8019_TRANSMITCONFIGURATION, 0xe0);
+               }
+
+               if (temp & 0x1) {
+                       /*packet received */
+                       do {
+                               put_reg (RTL8019_INTERRUPTSTATUS, 0x01);
+                               current_point = nic_to_pc ();
+                       } while (get_reg (RTL8019_BOUNDARY) != current_point);
+               }
+
+               if (!(temp & 0x1))
+                       return 0;
+               /* done and exit. */
+       }
+}
+
+/* Send a data block via Ethernet. */
+extern int eth_send (volatile void *packet, int length)
+{
+       volatile unsigned char *p;
+       unsigned int pn;
+
+       pn = length;
+       p = (volatile unsigned char *) packet;
+
+       while (get_reg (RTL8019_COMMAND) == RTL8019_TRANSMIT);
+
+       put_reg (RTL8019_REMOTESTARTADDRESS0, 0);
+       put_reg (RTL8019_REMOTESTARTADDRESS1, RTL8019_TPSTART);
+       put_reg (RTL8019_REMOTEBYTECOUNT0, (pn & 0xff));
+       put_reg (RTL8019_REMOTEBYTECOUNT1, ((pn >> 8) & 0xff));
+
+       put_reg (RTL8019_COMMAND, RTL8019_REMOTEDMAWR);
+       while (pn > 0) {
+               put_reg (RTL8019_DMA_DATA, *p++);
+               pn--;
+       }
+
+       pn = length;
+
+       while (pn < 60) {       /*Padding */
+               put_reg (RTL8019_DMA_DATA, 0);
+               pn++;
+       }
+
+       while (!(get_reg (RTL8019_INTERRUPTSTATUS)) & 0x40);
+
+       put_reg (RTL8019_INTERRUPTSTATUS, 0x40);
+       put_reg (RTL8019_TRANSMITPAGE, RTL8019_TPSTART);
+       put_reg (RTL8019_TRANSMITBYTECOUNT0, (pn & 0xff));
+       put_reg (RTL8019_TRANSMITBYTECOUNT1, ((pn >> 8 & 0xff)));
+       put_reg (RTL8019_COMMAND, RTL8019_TRANSMIT);
+
+       return 0;
+}
+
+#endif /* COMMANDS & CFG_NET */
+
+#endif /* CONFIG_DRIVER_RTL8019 */
diff --git a/drivers/net/rtl8019.h b/drivers/net/rtl8019.h
new file mode 100644 (file)
index 0000000..38116ad
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Realtek 8019AS Ethernet
+ * (C) Copyright 2002-2003
+ * Xue Ligong(lgxue@hotmail.com),Wang Kehao, ESLAB, whut.edu.cn
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * This code works in 8bit mode.
+ * If you need to work in 16bit mode, PLS change it!
+ */
+
+#include <asm/types.h>
+#include <config.h>
+
+
+#ifdef CONFIG_DRIVER_RTL8019
+
+#define                RTL8019_REG_00                  (RTL8019_BASE + 0x00)
+#define        RTL8019_REG_01                  (RTL8019_BASE + 0x01)
+#define        RTL8019_REG_02                  (RTL8019_BASE + 0x02)
+#define        RTL8019_REG_03                  (RTL8019_BASE + 0x03)
+#define        RTL8019_REG_04                  (RTL8019_BASE + 0x04)
+#define        RTL8019_REG_05                  (RTL8019_BASE + 0x05)
+#define        RTL8019_REG_06                  (RTL8019_BASE + 0x06)
+#define        RTL8019_REG_07                  (RTL8019_BASE + 0x07)
+#define        RTL8019_REG_08                  (RTL8019_BASE + 0x08)
+#define        RTL8019_REG_09                  (RTL8019_BASE + 0x09)
+#define        RTL8019_REG_0a                  (RTL8019_BASE + 0x0a)
+#define        RTL8019_REG_0b                  (RTL8019_BASE + 0x0b)
+#define        RTL8019_REG_0c                  (RTL8019_BASE + 0x0c)
+#define        RTL8019_REG_0d                  (RTL8019_BASE + 0x0d)
+#define        RTL8019_REG_0e                  (RTL8019_BASE + 0x0e)
+#define        RTL8019_REG_0f                  (RTL8019_BASE + 0x0f)
+#define        RTL8019_REG_10                  (RTL8019_BASE + 0x10)
+#define        RTL8019_REG_1f                  (RTL8019_BASE + 0x1f)
+
+#define                RTL8019_COMMAND                 RTL8019_REG_00
+#define                RTL8019_PAGESTART               RTL8019_REG_01
+#define                RTL8019_PAGESTOP                RTL8019_REG_02
+#define                RTL8019_BOUNDARY                RTL8019_REG_03
+#define                RTL8019_TRANSMITSTATUS          RTL8019_REG_04
+#define                RTL8019_TRANSMITPAGE            RTL8019_REG_04
+#define                RTL8019_TRANSMITBYTECOUNT0      RTL8019_REG_05
+#define                RTL8019_NCR                     RTL8019_REG_05
+#define                RTL8019_TRANSMITBYTECOUNT1      RTL8019_REG_06
+#define                RTL8019_INTERRUPTSTATUS         RTL8019_REG_07
+#define                RTL8019_CURRENT                 RTL8019_REG_07
+#define                RTL8019_REMOTESTARTADDRESS0     RTL8019_REG_08
+#define                RTL8019_CRDMA0                  RTL8019_REG_08
+#define                RTL8019_REMOTESTARTADDRESS1     RTL8019_REG_09
+#define                RTL8019_CRDMA1                  RTL8019_REG_09
+#define                RTL8019_REMOTEBYTECOUNT0        RTL8019_REG_0a
+#define                RTL8019_REMOTEBYTECOUNT1        RTL8019_REG_0b
+#define                RTL8019_RECEIVESTATUS           RTL8019_REG_0c
+#define                RTL8019_RECEIVECONFIGURATION    RTL8019_REG_0c
+#define                RTL8019_TRANSMITCONFIGURATION   RTL8019_REG_0d
+#define                RTL8019_FAE_TALLY               RTL8019_REG_0d
+#define                RTL8019_DATACONFIGURATION       RTL8019_REG_0e
+#define                RTL8019_CRC_TALLY               RTL8019_REG_0e
+#define                RTL8019_INTERRUPTMASK           RTL8019_REG_0f
+#define                RTL8019_MISS_PKT_TALLY          RTL8019_REG_0f
+#define                RTL8019_PHYSICALADDRESS0        RTL8019_REG_01
+#define        RTL8019_PHYSICALADDRESS1        RTL8019_REG_02
+#define                RTL8019_PHYSICALADDRESS2        RTL8019_REG_03
+#define                RTL8019_PHYSICALADDRESS3        RTL8019_REG_04
+#define                RTL8019_PHYSICALADDRESS4        RTL8019_REG_05
+#define                RTL8019_PHYSICALADDRESS5        RTL8019_REG_06
+#define                RTL8019_MULTIADDRESS0           RTL8019_REG_08
+#define                RTL8019_MULTIADDRESS1           RTL8019_REG_09
+#define                RTL8019_MULTIADDRESS2           RTL8019_REG_0a
+#define                RTL8019_MULTIADDRESS3           RTL8019_REG_0b
+#define                RTL8019_MULTIADDRESS4           RTL8019_REG_0c
+#define                RTL8019_MULTIADDRESS5           RTL8019_REG_0d
+#define                RTL8019_MULTIADDRESS6           RTL8019_REG_0e
+#define                RTL8019_MULTIADDRESS7           RTL8019_REG_0f
+#define                RTL8019_DMA_DATA                RTL8019_REG_10
+#define                RTL8019_RESET                   RTL8019_REG_1f
+
+
+#define        RTL8019_PAGE0                   0x22
+#define        RTL8019_PAGE1                   0x62
+#define        RTL8019_PAGE0DMAWRITE           0x12
+#define        RTL8019_PAGE2DMAWRITE           0x92
+#define        RTL8019_REMOTEDMAWR             0x12
+#define        RTL8019_REMOTEDMARD             0x0A
+#define        RTL8019_ABORTDMAWR              0x32
+#define        RTL8019_ABORTDMARD              0x2A
+#define        RTL8019_PAGE0STOP               0x21
+#define        RTL8019_PAGE1STOP               0x61
+#define        RTL8019_TRANSMIT                0x26
+#define        RTL8019_TXINPROGRESS            0x04
+#define        RTL8019_SEND                    0x1A
+
+#define                RTL8019_PSTART                  0x4c
+#define                RTL8019_PSTOP                   0x80
+#define                RTL8019_TPSTART                 0x40
+
+
+#endif /*end of CONFIG_DRIVER_RTL8019*/
diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c
new file mode 100644 (file)
index 0000000..2367180
--- /dev/null
@@ -0,0 +1,547 @@
+/*
+ * rtl8139.c : U-Boot driver for the RealTek RTL8139
+ *
+ * Masami Komiya (mkomiya@sonare.it)
+ *
+ * Most part is taken from rtl8139.c of etherboot
+ *
+ */
+
+/* rtl8139.c - etherboot driver for the Realtek 8139 chipset
+
+  ported from the linux driver written by Donald Becker
+  by Rainer Bawidamann (Rainer.Bawidamann@informatik.uni-ulm.de) 1999
+
+  This software may be used and distributed according to the terms
+  of the GNU Public License, incorporated herein by reference.
+
+  changes to the original driver:
+  - removed support for interrupts, switching to polling mode (yuck!)
+  - removed support for the 8129 chip (external MII)
+
+*/
+
+/*********************************************************************/
+/* Revision History                                                 */
+/*********************************************************************/
+
+/*
+  28 Dec 2002  ken_yap@users.sourceforge.net (Ken Yap)
+     Put in virt_to_bus calls to allow Etherboot relocation.
+
+  06 Apr 2001  ken_yap@users.sourceforge.net (Ken Yap)
+     Following email from Hyun-Joon Cha, added a disable routine, otherwise
+     NIC remains live and can crash the kernel later.
+
+  4 Feb 2000   espenlaub@informatik.uni-ulm.de (Klaus Espenlaub)
+     Shuffled things around, removed the leftovers from the 8129 support
+     that was in the Linux driver and added a bit more 8139 definitions.
+     Moved the 8K receive buffer to a fixed, available address outside the
+     0x98000-0x9ffff range.  This is a bit of a hack, but currently the only
+     way to make room for the Etherboot features that need substantial amounts
+     of code like the ANSI console support.  Currently the buffer is just below
+     0x10000, so this even conforms to the tagged boot image specification,
+     which reserves the ranges 0x00000-0x10000 and 0x98000-0xA0000.  My
+     interpretation of this "reserved" is that Etherboot may do whatever it
+     likes, as long as its environment is kept intact (like the BIOS
+     variables).  Hopefully fixed rtl_poll() once and for all. The symptoms
+     were that if Etherboot was left at the boot menu for several minutes, the
+     first eth_poll failed.  Seems like I am the only person who does this.
+     First of all I fixed the debugging code and then set out for a long bug
+     hunting session.  It took me about a week full time work - poking around
+     various places in the driver, reading Don Becker's and Jeff Garzik's Linux
+     driver and even the FreeBSD driver (what a piece of crap!) - and
+     eventually spotted the nasty thing: the transmit routine was acknowledging
+     each and every interrupt pending, including the RxOverrun and RxFIFIOver
+     interrupts.  This confused the RTL8139 thoroughly.         It destroyed the
+     Rx ring contents by dumping the 2K FIFO contents right where we wanted to
+     get the next packet.  Oh well, what fun.
+
+  18 Jan 2000  mdc@thinguin.org (Marty Connor)
+     Drastically simplified error handling.  Basically, if any error
+     in transmission or reception occurs, the card is reset.
+     Also, pointed all transmit descriptors to the same buffer to
+     save buffer space.         This should decrease driver size and avoid
+     corruption because of exceeding 32K during runtime.
+
+  28 Jul 1999  (Matthias Meixner - meixner@rbg.informatik.tu-darmstadt.de)
+     rtl_poll was quite broken: it used the RxOK interrupt flag instead
+     of the RxBufferEmpty flag which often resulted in very bad
+     transmission performace - below 1kBytes/s.
+
+*/
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
+       defined(CONFIG_RTL8139)
+
+#define TICKS_PER_SEC  CFG_HZ
+#define TICKS_PER_MS   (TICKS_PER_SEC/1000)
+
+#define RTL_TIMEOUT    (1*TICKS_PER_SEC)
+
+#define ETH_FRAME_LEN          1514
+#define ETH_ALEN               6
+#define ETH_ZLEN               60
+
+/* PCI Tuning Parameters
+   Threshold is bytes transferred to chip before transmission starts. */
+#define TX_FIFO_THRESH 256     /* In bytes, rounded down to 32 byte units. */
+#define RX_FIFO_THRESH 4       /* Rx buffer level before first PCI xfer.  */
+#define RX_DMA_BURST   4       /* Maximum PCI burst, '4' is 256 bytes */
+#define TX_DMA_BURST   4       /* Calculate as 16<<val. */
+#define NUM_TX_DESC    4       /* Number of Tx descriptor registers. */
+#define TX_BUF_SIZE    ETH_FRAME_LEN   /* FCS is added by the chip */
+#define RX_BUF_LEN_IDX 0       /* 0, 1, 2 is allowed - 8,16,32K rx buffer */
+#define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX)
+
+#undef DEBUG_TX
+#undef DEBUG_RX
+
+#define currticks()    get_timer(0)
+#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a)
+#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
+
+/* Symbolic offsets to registers. */
+enum RTL8139_registers {
+       MAC0=0,                 /* Ethernet hardware address. */
+       MAR0=8,                 /* Multicast filter. */
+       TxStatus0=0x10,         /* Transmit status (four 32bit registers). */
+       TxAddr0=0x20,           /* Tx descriptors (also four 32bit). */
+       RxBuf=0x30, RxEarlyCnt=0x34, RxEarlyStatus=0x36,
+       ChipCmd=0x37, RxBufPtr=0x38, RxBufAddr=0x3A,
+       IntrMask=0x3C, IntrStatus=0x3E,
+       TxConfig=0x40, RxConfig=0x44,
+       Timer=0x48,             /* general-purpose counter. */
+       RxMissed=0x4C,          /* 24 bits valid, write clears. */
+       Cfg9346=0x50, Config0=0x51, Config1=0x52,
+       TimerIntrReg=0x54,      /* intr if gp counter reaches this value */
+       MediaStatus=0x58,
+       Config3=0x59,
+       MultiIntr=0x5C,
+       RevisionID=0x5E,        /* revision of the RTL8139 chip */
+       TxSummary=0x60,
+       MII_BMCR=0x62, MII_BMSR=0x64, NWayAdvert=0x66, NWayLPAR=0x68,
+       NWayExpansion=0x6A,
+       DisconnectCnt=0x6C, FalseCarrierCnt=0x6E,
+       NWayTestReg=0x70,
+       RxCnt=0x72,             /* packet received counter */
+       CSCR=0x74,              /* chip status and configuration register */
+       PhyParm1=0x78,TwisterParm=0x7c,PhyParm2=0x80,   /* undocumented */
+       /* from 0x84 onwards are a number of power management/wakeup frame
+        * definitions we will probably never need to know about.  */
+};
+
+enum ChipCmdBits {
+       CmdReset=0x10, CmdRxEnb=0x08, CmdTxEnb=0x04, RxBufEmpty=0x01, };
+
+/* Interrupt register bits, using my own meaningful names. */
+enum IntrStatusBits {
+       PCIErr=0x8000, PCSTimeout=0x4000, CableLenChange= 0x2000,
+       RxFIFOOver=0x40, RxUnderrun=0x20, RxOverflow=0x10,
+       TxErr=0x08, TxOK=0x04, RxErr=0x02, RxOK=0x01,
+};
+enum TxStatusBits {
+       TxHostOwns=0x2000, TxUnderrun=0x4000, TxStatOK=0x8000,
+       TxOutOfWindow=0x20000000, TxAborted=0x40000000,
+       TxCarrierLost=0x80000000,
+};
+enum RxStatusBits {
+       RxMulticast=0x8000, RxPhysical=0x4000, RxBroadcast=0x2000,
+       RxBadSymbol=0x0020, RxRunt=0x0010, RxTooLong=0x0008, RxCRCErr=0x0004,
+       RxBadAlign=0x0002, RxStatusOK=0x0001,
+};
+
+enum MediaStatusBits {
+       MSRTxFlowEnable=0x80, MSRRxFlowEnable=0x40, MSRSpeed10=0x08,
+       MSRLinkFail=0x04, MSRRxPauseFlag=0x02, MSRTxPauseFlag=0x01,
+};
+
+enum MIIBMCRBits {
+       BMCRReset=0x8000, BMCRSpeed100=0x2000, BMCRNWayEnable=0x1000,
+       BMCRRestartNWay=0x0200, BMCRDuplex=0x0100,
+};
+
+enum CSCRBits {
+       CSCR_LinkOKBit=0x0400, CSCR_LinkChangeBit=0x0800,
+       CSCR_LinkStatusBits=0x0f000, CSCR_LinkDownOffCmd=0x003c0,
+       CSCR_LinkDownCmd=0x0f3c0,
+};
+
+/* Bits in RxConfig. */
+enum rx_mode_bits {
+       RxCfgWrap=0x80,
+       AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0x08,
+       AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01,
+};
+
+static int ioaddr;
+static unsigned int cur_rx,cur_tx;
+
+/* The RTL8139 can only transmit from a contiguous, aligned memory block.  */
+static unsigned char tx_buffer[TX_BUF_SIZE] __attribute__((aligned(4)));
+static unsigned char rx_ring[RX_BUF_LEN+16] __attribute__((aligned(4)));
+
+static int rtl8139_probe(struct eth_device *dev, bd_t *bis);
+static int read_eeprom(int location, int addr_len);
+static void rtl_reset(struct eth_device *dev);
+static int rtl_transmit(struct eth_device *dev, volatile void *packet, int length);
+static int rtl_poll(struct eth_device *dev);
+static void rtl_disable(struct eth_device *dev);
+#ifdef CONFIG_MCAST_TFTP/*  This driver already accepts all b/mcast */
+static int rtl_bcast_addr (struct eth_device *dev, u8 bcast_mac, u8 set)
+{
+       return (0);
+}
+#endif
+
+static struct pci_device_id supported[] = {
+       {PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139},
+       {PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_8139},
+       {}
+};
+
+int rtl8139_initialize(bd_t *bis)
+{
+       pci_dev_t devno;
+       int card_number = 0;
+       struct eth_device *dev;
+       u32 iobase;
+       int idx=0;
+
+       while(1){
+               /* Find RTL8139 */
+               if ((devno = pci_find_devices(supported, idx++)) < 0)
+                       break;
+
+               pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase);
+               iobase &= ~0xf;
+
+               debug ("rtl8139: REALTEK RTL8139 @0x%x\n", iobase);
+
+               dev = (struct eth_device *)malloc(sizeof *dev);
+
+               sprintf (dev->name, "RTL8139#%d", card_number);
+
+               dev->priv = (void *) devno;
+               dev->iobase = (int)bus_to_phys(iobase);
+               dev->init = rtl8139_probe;
+               dev->halt = rtl_disable;
+               dev->send = rtl_transmit;
+               dev->recv = rtl_poll;
+#ifdef CONFIG_MCAST_TFTP
+               dev->mcast = rtl_bcast_addr;
+#endif
+
+               eth_register (dev);
+
+               card_number++;
+
+               pci_write_config_byte (devno, PCI_LATENCY_TIMER, 0x20);
+
+               udelay (10 * 1000);
+       }
+
+       return card_number;
+}
+
+static int rtl8139_probe(struct eth_device *dev, bd_t *bis)
+{
+       int i;
+       int speed10, fullduplex;
+       int addr_len;
+       unsigned short *ap = (unsigned short *)dev->enetaddr;
+
+       ioaddr = dev->iobase;
+
+       /* Bring the chip out of low-power mode. */
+       outb(0x00, ioaddr + Config1);
+
+       addr_len = read_eeprom(0,8) == 0x8129 ? 8 : 6;
+       for (i = 0; i < 3; i++)
+               *ap++ = le16_to_cpu (read_eeprom(i + 7, addr_len));
+
+       speed10 = inb(ioaddr + MediaStatus) & MSRSpeed10;
+       fullduplex = inw(ioaddr + MII_BMCR) & BMCRDuplex;
+
+       rtl_reset(dev);
+
+       if (inb(ioaddr + MediaStatus) & MSRLinkFail) {
+               printf("Cable not connected or other link failure\n");
+               return(0);
+       }
+
+       return 1;
+}
+
+/* Serial EEPROM section. */
+
+/*  EEPROM_Ctrl bits. */
+#define EE_SHIFT_CLK   0x04    /* EEPROM shift clock. */
+#define EE_CS          0x08    /* EEPROM chip select. */
+#define EE_DATA_WRITE  0x02    /* EEPROM chip data in. */
+#define EE_WRITE_0     0x00
+#define EE_WRITE_1     0x02
+#define EE_DATA_READ   0x01    /* EEPROM chip data out. */
+#define EE_ENB         (0x80 | EE_CS)
+
+/*
+       Delay between EEPROM clock transitions.
+       No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
+*/
+
+#define eeprom_delay() inl(ee_addr)
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define EE_WRITE_CMD   (5)
+#define EE_READ_CMD    (6)
+#define EE_ERASE_CMD   (7)
+
+static int read_eeprom(int location, int addr_len)
+{
+       int i;
+       unsigned int retval = 0;
+       long ee_addr = ioaddr + Cfg9346;
+       int read_cmd = location | (EE_READ_CMD << addr_len);
+
+       outb(EE_ENB & ~EE_CS, ee_addr);
+       outb(EE_ENB, ee_addr);
+       eeprom_delay();
+
+       /* Shift the read command bits out. */
+       for (i = 4 + addr_len; i >= 0; i--) {
+               int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+               outb(EE_ENB | dataval, ee_addr);
+               eeprom_delay();
+               outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+               eeprom_delay();
+       }
+       outb(EE_ENB, ee_addr);
+       eeprom_delay();
+
+       for (i = 16; i > 0; i--) {
+               outb(EE_ENB | EE_SHIFT_CLK, ee_addr);
+               eeprom_delay();
+               retval = (retval << 1) | ((inb(ee_addr) & EE_DATA_READ) ? 1 : 0);
+               outb(EE_ENB, ee_addr);
+               eeprom_delay();
+       }
+
+       /* Terminate the EEPROM access. */
+       outb(~EE_CS, ee_addr);
+       eeprom_delay();
+       return retval;
+}
+
+static const unsigned int rtl8139_rx_config =
+       (RX_BUF_LEN_IDX << 11) |
+       (RX_FIFO_THRESH << 13) |
+       (RX_DMA_BURST << 8);
+
+static void set_rx_mode(struct eth_device *dev) {
+       unsigned int mc_filter[2];
+       int rx_mode;
+       /* !IFF_PROMISC */
+       rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+       mc_filter[1] = mc_filter[0] = 0xffffffff;
+
+       outl(rtl8139_rx_config | rx_mode, ioaddr + RxConfig);
+
+       outl(mc_filter[0], ioaddr + MAR0 + 0);
+       outl(mc_filter[1], ioaddr + MAR0 + 4);
+}
+
+static void rtl_reset(struct eth_device *dev)
+{
+       int i;
+
+       outb(CmdReset, ioaddr + ChipCmd);
+
+       cur_rx = 0;
+       cur_tx = 0;
+
+       /* Give the chip 10ms to finish the reset. */
+       for (i=0; i<100; ++i){
+               if ((inb(ioaddr + ChipCmd) & CmdReset) == 0) break;
+               udelay (100); /* wait 100us */
+       }
+
+
+       for (i = 0; i < ETH_ALEN; i++)
+               outb(dev->enetaddr[i], ioaddr + MAC0 + i);
+
+       /* Must enable Tx/Rx before setting transfer thresholds! */
+       outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
+       outl((RX_FIFO_THRESH<<13) | (RX_BUF_LEN_IDX<<11) | (RX_DMA_BURST<<8),
+               ioaddr + RxConfig);             /* accept no frames yet!  */
+       outl((TX_DMA_BURST<<8)|0x03000000, ioaddr + TxConfig);
+
+       /* The Linux driver changes Config1 here to use a different LED pattern
+        * for half duplex or full/autodetect duplex (for full/autodetect, the
+        * outputs are TX/RX, Link10/100, FULL, while for half duplex it uses
+        * TX/RX, Link100, Link10).  This is messy, because it doesn't match
+        * the inscription on the mounting bracket.  It should not be changed
+        * from the configuration EEPROM default, because the card manufacturer
+        * should have set that to match the card.  */
+
+#ifdef DEBUG_RX
+       printf("rx ring address is %X\n",(unsigned long)rx_ring);
+#endif
+       outl(phys_to_bus((int)rx_ring), ioaddr + RxBuf);
+
+       /* If we add multicast support, the MAR0 register would have to be
+        * initialized to 0xffffffffffffffff (two 32 bit accesses).  Etherboot
+        * only needs broadcast (for ARP/RARP/BOOTP/DHCP) and unicast.  */
+
+       outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
+
+       outl(rtl8139_rx_config, ioaddr + RxConfig);
+
+       /* Start the chip's Tx and Rx process. */
+       outl(0, ioaddr + RxMissed);
+
+       /* set_rx_mode */
+       set_rx_mode(dev);
+
+       /* Disable all known interrupts by setting the interrupt mask. */
+       outw(0, ioaddr + IntrMask);
+}
+
+static int rtl_transmit(struct eth_device *dev, volatile void *packet, int length)
+{
+       unsigned int status, to;
+       unsigned long txstatus;
+       unsigned int len = length;
+
+       ioaddr = dev->iobase;
+
+       memcpy((char *)tx_buffer, (char *)packet, (int)length);
+
+#ifdef DEBUG_TX
+       printf("sending %d bytes\n", len);
+#endif
+
+       /* Note: RTL8139 doesn't auto-pad, send minimum payload (another 4
+        * bytes are sent automatically for the FCS, totalling to 64 bytes). */
+       while (len < ETH_ZLEN) {
+               tx_buffer[len++] = '\0';
+       }
+
+       outl(phys_to_bus((int)tx_buffer), ioaddr + TxAddr0 + cur_tx*4);
+       outl(((TX_FIFO_THRESH<<11) & 0x003f0000) | len,
+               ioaddr + TxStatus0 + cur_tx*4);
+
+       to = currticks() + RTL_TIMEOUT;
+
+       do {
+               status = inw(ioaddr + IntrStatus);
+               /* Only acknlowledge interrupt sources we can properly handle
+                * here - the RxOverflow/RxFIFOOver MUST be handled in the
+                * rtl_poll() function.  */
+               outw(status & (TxOK | TxErr | PCIErr), ioaddr + IntrStatus);
+               if ((status & (TxOK | TxErr | PCIErr)) != 0) break;
+       } while (currticks() < to);
+
+       txstatus = inl(ioaddr + TxStatus0 + cur_tx*4);
+
+       if (status & TxOK) {
+               cur_tx = (cur_tx + 1) % NUM_TX_DESC;
+#ifdef DEBUG_TX
+               printf("tx done (%d ticks), status %hX txstatus %X\n",
+                       to-currticks(), status, txstatus);
+#endif
+               return length;
+       } else {
+#ifdef DEBUG_TX
+               printf("tx timeout/error (%d ticks), status %hX txstatus %X\n",
+                       currticks()-to, status, txstatus);
+#endif
+               rtl_reset(dev);
+
+               return 0;
+       }
+}
+
+static int rtl_poll(struct eth_device *dev)
+{
+       unsigned int status;
+       unsigned int ring_offs;
+       unsigned int rx_size, rx_status;
+       int length=0;
+
+       ioaddr = dev->iobase;
+
+       if (inb(ioaddr + ChipCmd) & RxBufEmpty) {
+               return 0;
+       }
+
+       status = inw(ioaddr + IntrStatus);
+       /* See below for the rest of the interrupt acknowledges.  */
+       outw(status & ~(RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus);
+
+#ifdef DEBUG_RX
+       printf("rtl_poll: int %hX ", status);
+#endif
+
+       ring_offs = cur_rx % RX_BUF_LEN;
+       rx_status = *(unsigned int*)KSEG1ADDR((rx_ring + ring_offs));
+       rx_size = rx_status >> 16;
+       rx_status &= 0xffff;
+
+       if ((rx_status & (RxBadSymbol|RxRunt|RxTooLong|RxCRCErr|RxBadAlign)) ||
+           (rx_size < ETH_ZLEN) || (rx_size > ETH_FRAME_LEN + 4)) {
+               printf("rx error %hX\n", rx_status);
+               rtl_reset(dev); /* this clears all interrupts still pending */
+               return 0;
+       }
+
+       /* Received a good packet */
+       length = rx_size - 4;   /* no one cares about the FCS */
+       if (ring_offs+4+rx_size-4 > RX_BUF_LEN) {
+               int semi_count = RX_BUF_LEN - ring_offs - 4;
+               unsigned char rxdata[RX_BUF_LEN];
+
+               memcpy(rxdata, rx_ring + ring_offs + 4, semi_count);
+               memcpy(&(rxdata[semi_count]), rx_ring, rx_size-4-semi_count);
+
+               NetReceive(rxdata, length);
+#ifdef DEBUG_RX
+               printf("rx packet %d+%d bytes", semi_count,rx_size-4-semi_count);
+#endif
+       } else {
+               NetReceive(rx_ring + ring_offs + 4, length);
+#ifdef DEBUG_RX
+               printf("rx packet %d bytes", rx_size-4);
+#endif
+       }
+
+       cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
+       outw(cur_rx - 16, ioaddr + RxBufPtr);
+       /* See RTL8139 Programming Guide V0.1 for the official handling of
+        * Rx overflow situations.  The document itself contains basically no
+        * usable information, except for a few exception handling rules.  */
+       outw(status & (RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus);
+       return length;
+}
+
+static void rtl_disable(struct eth_device *dev)
+{
+       int i;
+
+       ioaddr = dev->iobase;
+
+       /* reset the chip */
+       outb(CmdReset, ioaddr + ChipCmd);
+
+       /* Give the chip 10ms to finish the reset. */
+       for (i=0; i<100; ++i){
+               if ((inb(ioaddr + ChipCmd) & CmdReset) == 0) break;
+               udelay (100); /* wait 100us */
+       }
+}
+#endif
diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c
new file mode 100644 (file)
index 0000000..63ea2cc
--- /dev/null
@@ -0,0 +1,888 @@
+/*
+ * rtl8169.c : U-Boot driver for the RealTek RTL8169
+ *
+ * Masami Komiya (mkomiya@sonare.it)
+ *
+ * Most part is taken from r8169.c of etherboot
+ *
+ */
+
+/**************************************************************************
+*    r8169.c: Etherboot device driver for the RealTek RTL-8169 Gigabit
+*    Written 2003 by Timothy Legge <tlegge@rogers.com>
+*
+*    This program is free software; you can redistribute it and/or modify
+*    it under the terms of the GNU General Public License as published by
+*    the Free Software Foundation; either version 2 of the License, or
+*    (at your option) any later version.
+*
+*    This program is distributed in the hope that it will be useful,
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*    GNU General Public License for more details.
+*
+*    You should have received a copy of the GNU General Public License
+*    along with this program; if not, write to the Free Software
+*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*    Portions of this code based on:
+*      r8169.c: A RealTek RTL-8169 Gigabit Ethernet driver
+*              for Linux kernel 2.4.x.
+*
+*    Written 2002 ShuChen <shuchen@realtek.com.tw>
+*        See Linux Driver for full information
+*
+*    Linux Driver Version 1.27a, 10.02.2002
+*
+*    Thanks to:
+*      Jean Chen of RealTek Semiconductor Corp. for
+*      providing the evaluation NIC used to develop
+*      this driver.  RealTek's support for Etherboot
+*      is appreciated.
+*
+*    REVISION HISTORY:
+*    ================
+*
+*    v1.0      11-26-2003      timlegge        Initial port of Linux driver
+*    v1.5      01-17-2004      timlegge        Initial driver output cleanup
+*
+*    Indent Options: indent -kr -i8
+***************************************************************************/
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
+       defined(CONFIG_RTL8169)
+
+#undef DEBUG_RTL8169
+#undef DEBUG_RTL8169_TX
+#undef DEBUG_RTL8169_RX
+
+#define drv_version "v1.5"
+#define drv_date "01-17-2004"
+
+static u32 ioaddr;
+
+/* Condensed operations for readability. */
+#define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
+#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
+
+#define currticks()    get_timer(0)
+#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a)
+#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
+
+/* media options */
+#define MAX_UNITS 8
+static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
+
+/* MAC address length*/
+#define MAC_ADDR_LEN   6
+
+/* max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4).*/
+#define MAX_ETH_FRAME_SIZE     1536
+
+#define TX_FIFO_THRESH 256     /* In bytes */
+
+#define RX_FIFO_THRESH 7       /* 7 means NO threshold, Rx buffer level before first PCI xfer.  */
+#define RX_DMA_BURST   6       /* Maximum PCI burst, '6' is 1024 */
+#define TX_DMA_BURST   6       /* Maximum PCI burst, '6' is 1024 */
+#define EarlyTxThld    0x3F    /* 0x3F means NO early transmit */
+#define RxPacketMaxSize 0x0800 /* Maximum size supported is 16K-1 */
+#define InterFrameGap  0x03    /* 3 means InterFrameGap = the shortest one */
+
+#define NUM_TX_DESC    1       /* Number of Tx descriptor registers */
+#define NUM_RX_DESC    4       /* Number of Rx descriptor registers */
+#define RX_BUF_SIZE    1536    /* Rx Buffer size */
+#define RX_BUF_LEN     8192
+
+#define RTL_MIN_IO_SIZE 0x80
+#define TX_TIMEOUT  (6*HZ)
+
+/* write/read MMIO register */
+#define RTL_W8(reg, val8)      writeb ((val8), ioaddr + (reg))
+#define RTL_W16(reg, val16)    writew ((val16), ioaddr + (reg))
+#define RTL_W32(reg, val32)    writel ((val32), ioaddr + (reg))
+#define RTL_R8(reg)            readb (ioaddr + (reg))
+#define RTL_R16(reg)           readw (ioaddr + (reg))
+#define RTL_R32(reg)           ((unsigned long) readl (ioaddr + (reg)))
+
+#define ETH_FRAME_LEN  MAX_ETH_FRAME_SIZE
+#define ETH_ALEN       MAC_ADDR_LEN
+#define ETH_ZLEN       60
+
+enum RTL8169_registers {
+       MAC0 = 0,               /* Ethernet hardware address. */
+       MAR0 = 8,               /* Multicast filter. */
+       TxDescStartAddr = 0x20,
+       TxHDescStartAddr = 0x28,
+       FLASH = 0x30,
+       ERSR = 0x36,
+       ChipCmd = 0x37,
+       TxPoll = 0x38,
+       IntrMask = 0x3C,
+       IntrStatus = 0x3E,
+       TxConfig = 0x40,
+       RxConfig = 0x44,
+       RxMissed = 0x4C,
+       Cfg9346 = 0x50,
+       Config0 = 0x51,
+       Config1 = 0x52,
+       Config2 = 0x53,
+       Config3 = 0x54,
+       Config4 = 0x55,
+       Config5 = 0x56,
+       MultiIntr = 0x5C,
+       PHYAR = 0x60,
+       TBICSR = 0x64,
+       TBI_ANAR = 0x68,
+       TBI_LPAR = 0x6A,
+       PHYstatus = 0x6C,
+       RxMaxSize = 0xDA,
+       CPlusCmd = 0xE0,
+       RxDescStartAddr = 0xE4,
+       EarlyTxThres = 0xEC,
+       FuncEvent = 0xF0,
+       FuncEventMask = 0xF4,
+       FuncPresetState = 0xF8,
+       FuncForceEvent = 0xFC,
+};
+
+enum RTL8169_register_content {
+       /*InterruptStatusBits */
+       SYSErr = 0x8000,
+       PCSTimeout = 0x4000,
+       SWInt = 0x0100,
+       TxDescUnavail = 0x80,
+       RxFIFOOver = 0x40,
+       RxUnderrun = 0x20,
+       RxOverflow = 0x10,
+       TxErr = 0x08,
+       TxOK = 0x04,
+       RxErr = 0x02,
+       RxOK = 0x01,
+
+       /*RxStatusDesc */
+       RxRES = 0x00200000,
+       RxCRC = 0x00080000,
+       RxRUNT = 0x00100000,
+       RxRWT = 0x00400000,
+
+       /*ChipCmdBits */
+       CmdReset = 0x10,
+       CmdRxEnb = 0x08,
+       CmdTxEnb = 0x04,
+       RxBufEmpty = 0x01,
+
+       /*Cfg9346Bits */
+       Cfg9346_Lock = 0x00,
+       Cfg9346_Unlock = 0xC0,
+
+       /*rx_mode_bits */
+       AcceptErr = 0x20,
+       AcceptRunt = 0x10,
+       AcceptBroadcast = 0x08,
+       AcceptMulticast = 0x04,
+       AcceptMyPhys = 0x02,
+       AcceptAllPhys = 0x01,
+
+       /*RxConfigBits */
+       RxCfgFIFOShift = 13,
+       RxCfgDMAShift = 8,
+
+       /*TxConfigBits */
+       TxInterFrameGapShift = 24,
+       TxDMAShift = 8,         /* DMA burst value (0-7) is shift this many bits */
+
+       /*rtl8169_PHYstatus */
+       TBI_Enable = 0x80,
+       TxFlowCtrl = 0x40,
+       RxFlowCtrl = 0x20,
+       _1000bpsF = 0x10,
+       _100bps = 0x08,
+       _10bps = 0x04,
+       LinkStatus = 0x02,
+       FullDup = 0x01,
+
+       /*GIGABIT_PHY_registers */
+       PHY_CTRL_REG = 0,
+       PHY_STAT_REG = 1,
+       PHY_AUTO_NEGO_REG = 4,
+       PHY_1000_CTRL_REG = 9,
+
+       /*GIGABIT_PHY_REG_BIT */
+       PHY_Restart_Auto_Nego = 0x0200,
+       PHY_Enable_Auto_Nego = 0x1000,
+
+       /* PHY_STAT_REG = 1; */
+       PHY_Auto_Neco_Comp = 0x0020,
+
+       /* PHY_AUTO_NEGO_REG = 4; */
+       PHY_Cap_10_Half = 0x0020,
+       PHY_Cap_10_Full = 0x0040,
+       PHY_Cap_100_Half = 0x0080,
+       PHY_Cap_100_Full = 0x0100,
+
+       /* PHY_1000_CTRL_REG = 9; */
+       PHY_Cap_1000_Full = 0x0200,
+
+       PHY_Cap_Null = 0x0,
+
+       /*_MediaType*/
+       _10_Half = 0x01,
+       _10_Full = 0x02,
+       _100_Half = 0x04,
+       _100_Full = 0x08,
+       _1000_Full = 0x10,
+
+       /*_TBICSRBit*/
+       TBILinkOK = 0x02000000,
+};
+
+static struct {
+       const char *name;
+       u8 version;             /* depend on RTL8169 docs */
+       u32 RxConfigMask;       /* should clear the bits supported by this chip */
+} rtl_chip_info[] = {
+       {"RTL-8169", 0x00, 0xff7e1880,},
+       {"RTL-8169", 0x04, 0xff7e1880,},
+};
+
+enum _DescStatusBit {
+       OWNbit = 0x80000000,
+       EORbit = 0x40000000,
+       FSbit = 0x20000000,
+       LSbit = 0x10000000,
+};
+
+struct TxDesc {
+       u32 status;
+       u32 vlan_tag;
+       u32 buf_addr;
+       u32 buf_Haddr;
+};
+
+struct RxDesc {
+       u32 status;
+       u32 vlan_tag;
+       u32 buf_addr;
+       u32 buf_Haddr;
+};
+
+/* Define the TX Descriptor */
+static u8 tx_ring[NUM_TX_DESC * sizeof(struct TxDesc) + 256];
+/*     __attribute__ ((aligned(256))); */
+
+/* Create a static buffer of size RX_BUF_SZ for each
+TX Descriptor. All descriptors point to a
+part of this buffer */
+static unsigned char txb[NUM_TX_DESC * RX_BUF_SIZE];
+
+/* Define the RX Descriptor */
+static u8 rx_ring[NUM_RX_DESC * sizeof(struct TxDesc) + 256];
+  /*  __attribute__ ((aligned(256))); */
+
+/* Create a static buffer of size RX_BUF_SZ for each
+RX Descriptor  All descriptors point to a
+part of this buffer */
+static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE];
+
+struct rtl8169_private {
+       void *mmio_addr;        /* memory map physical address */
+       int chipset;
+       unsigned long cur_rx;   /* Index into the Rx descriptor buffer of next Rx pkt. */
+       unsigned long cur_tx;   /* Index into the Tx descriptor buffer of next Rx pkt. */
+       unsigned long dirty_tx;
+       unsigned char *TxDescArrays;    /* Index of Tx Descriptor buffer */
+       unsigned char *RxDescArrays;    /* Index of Rx Descriptor buffer */
+       struct TxDesc *TxDescArray;     /* Index of 256-alignment Tx Descriptor buffer */
+       struct RxDesc *RxDescArray;     /* Index of 256-alignment Rx Descriptor buffer */
+       unsigned char *RxBufferRings;   /* Index of Rx Buffer  */
+       unsigned char *RxBufferRing[NUM_RX_DESC];       /* Index of Rx Buffer array */
+       unsigned char *Tx_skbuff[NUM_TX_DESC];
+} tpx;
+
+static struct rtl8169_private *tpc;
+
+static const u16 rtl8169_intr_mask =
+    SYSErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver | TxErr |
+    TxOK | RxErr | RxOK;
+static const unsigned int rtl8169_rx_config =
+    (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
+
+static struct pci_device_id supported[] = {
+       {PCI_VENDOR_ID_REALTEK, 0x8169},
+       {}
+};
+
+void mdio_write(int RegAddr, int value)
+{
+       int i;
+
+       RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value);
+       udelay(1000);
+
+       for (i = 2000; i > 0; i--) {
+               /* Check if the RTL8169 has completed writing to the specified MII register */
+               if (!(RTL_R32(PHYAR) & 0x80000000)) {
+                       break;
+               } else {
+                       udelay(100);
+               }
+       }
+}
+
+int mdio_read(int RegAddr)
+{
+       int i, value = -1;
+
+       RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16);
+       udelay(1000);
+
+       for (i = 2000; i > 0; i--) {
+               /* Check if the RTL8169 has completed retrieving data from the specified MII register */
+               if (RTL_R32(PHYAR) & 0x80000000) {
+                       value = (int) (RTL_R32(PHYAR) & 0xFFFF);
+                       break;
+               } else {
+                       udelay(100);
+               }
+       }
+       return value;
+}
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+static int rtl8169_init_board(struct eth_device *dev)
+{
+       int i;
+       u32 tmp;
+
+#ifdef DEBUG_RTL8169
+       printf ("%s\n", __FUNCTION__);
+#endif
+       ioaddr = dev->iobase;
+
+       /* Soft reset the chip. */
+       RTL_W8(ChipCmd, CmdReset);
+
+       /* Check that the chip has finished the reset. */
+       for (i = 1000; i > 0; i--)
+               if ((RTL_R8(ChipCmd) & CmdReset) == 0)
+                       break;
+               else
+                       udelay(10);
+
+       /* identify chip attached to board */
+       tmp = RTL_R32(TxConfig);
+       tmp = ((tmp & 0x7c000000) + ((tmp & 0x00800000) << 2)) >> 24;
+
+       for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--){
+               if (tmp == rtl_chip_info[i].version) {
+                       tpc->chipset = i;
+                       goto match;
+               }
+       }
+
+       /* if unknown chip, assume array element #0, original RTL-8169 in this case */
+       printf("PCI device %s: unknown chip version, assuming RTL-8169\n", dev->name);
+       printf("PCI device: TxConfig = 0x%hX\n", (unsigned long) RTL_R32(TxConfig));
+       tpc->chipset = 0;
+
+match:
+       return 0;
+}
+
+/**************************************************************************
+RECV - Receive a frame
+***************************************************************************/
+static int rtl_recv(struct eth_device *dev)
+{
+       /* return true if there's an ethernet packet ready to read */
+       /* nic->packet should contain data on return */
+       /* nic->packetlen should contain length of data */
+       int cur_rx;
+       int length = 0;
+
+#ifdef DEBUG_RTL8169_RX
+       printf ("%s\n", __FUNCTION__);
+#endif
+       ioaddr = dev->iobase;
+
+       cur_rx = tpc->cur_rx;
+       if ((tpc->RxDescArray[cur_rx].status & OWNbit) == 0) {
+               if (!(tpc->RxDescArray[cur_rx].status & RxRES)) {
+                       unsigned char rxdata[RX_BUF_LEN];
+                       length = (int) (tpc->RxDescArray[cur_rx].
+                                               status & 0x00001FFF) - 4;
+
+                       memcpy(rxdata, tpc->RxBufferRing[cur_rx], length);
+                       NetReceive(rxdata, length);
+
+                       if (cur_rx == NUM_RX_DESC - 1)
+                               tpc->RxDescArray[cur_rx].status =
+                                   (OWNbit | EORbit) + RX_BUF_SIZE;
+                       else
+                               tpc->RxDescArray[cur_rx].status =
+                                   OWNbit + RX_BUF_SIZE;
+                       tpc->RxDescArray[cur_rx].buf_addr =
+                           virt_to_bus(tpc->RxBufferRing[cur_rx]);
+               } else {
+                       puts("Error Rx");
+               }
+               cur_rx = (cur_rx + 1) % NUM_RX_DESC;
+               tpc->cur_rx = cur_rx;
+               return 1;
+
+       }
+       tpc->cur_rx = cur_rx;
+       return (0);             /* initially as this is called to flush the input */
+}
+
+#define HZ 1000
+/**************************************************************************
+SEND - Transmit a frame
+***************************************************************************/
+static int rtl_send(struct eth_device *dev, volatile void *packet, int length)
+{
+       /* send the packet to destination */
+
+       u32 to;
+       u8 *ptxb;
+       int entry = tpc->cur_tx % NUM_TX_DESC;
+       u32 len = length;
+
+#ifdef DEBUG_RTL8169_TX
+       int stime = currticks();
+       printf ("%s\n", __FUNCTION__);
+       printf("sending %d bytes\n", len);
+#endif
+
+       ioaddr = dev->iobase;
+
+       /* point to the current txb incase multiple tx_rings are used */
+       ptxb = tpc->Tx_skbuff[entry * MAX_ETH_FRAME_SIZE];
+       memcpy(ptxb, (char *)packet, (int)length);
+
+       while (len < ETH_ZLEN)
+               ptxb[len++] = '\0';
+
+       tpc->TxDescArray[entry].buf_addr = virt_to_bus(ptxb);
+       if (entry != (NUM_TX_DESC - 1)) {
+               tpc->TxDescArray[entry].status =
+                   (OWNbit | FSbit | LSbit) | ((len > ETH_ZLEN) ?
+                                               len : ETH_ZLEN);
+       } else {
+               tpc->TxDescArray[entry].status =
+                   (OWNbit | EORbit | FSbit | LSbit) |
+                   ((len > ETH_ZLEN) ? length : ETH_ZLEN);
+       }
+       RTL_W8(TxPoll, 0x40);   /* set polling bit */
+
+       tpc->cur_tx++;
+       to = currticks() + TX_TIMEOUT;
+       while ((tpc->TxDescArray[entry].status & OWNbit) && (currticks() < to));        /* wait */
+
+       if (currticks() >= to) {
+#ifdef DEBUG_RTL8169_TX
+               puts ("tx timeout/error\n");
+               printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime);
+#endif
+               return 0;
+       } else {
+#ifdef DEBUG_RTL8169_TX
+               puts("tx done\n");
+#endif
+               return length;
+       }
+}
+
+static void rtl8169_set_rx_mode(struct eth_device *dev)
+{
+       u32 mc_filter[2];       /* Multicast hash filter */
+       int rx_mode;
+       u32 tmp = 0;
+
+#ifdef DEBUG_RTL8169
+       printf ("%s\n", __FUNCTION__);
+#endif
+
+       /* IFF_ALLMULTI */
+       /* Too many to filter perfectly -- accept all multicasts. */
+       rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+       mc_filter[1] = mc_filter[0] = 0xffffffff;
+
+       tmp = rtl8169_rx_config | rx_mode | (RTL_R32(RxConfig) &
+                                  rtl_chip_info[tpc->chipset].RxConfigMask);
+
+       RTL_W32(RxConfig, tmp);
+       RTL_W32(MAR0 + 0, mc_filter[0]);
+       RTL_W32(MAR0 + 4, mc_filter[1]);
+}
+
+static void rtl8169_hw_start(struct eth_device *dev)
+{
+       u32 i;
+
+#ifdef DEBUG_RTL8169
+       int stime = currticks();
+       printf ("%s\n", __FUNCTION__);
+#endif
+
+#if 0
+       /* Soft reset the chip. */
+       RTL_W8(ChipCmd, CmdReset);
+
+       /* Check that the chip has finished the reset. */
+       for (i = 1000; i > 0; i--) {
+               if ((RTL_R8(ChipCmd) & CmdReset) == 0)
+                       break;
+               else
+                       udelay(10);
+       }
+#endif
+
+       RTL_W8(Cfg9346, Cfg9346_Unlock);
+       RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+       RTL_W8(EarlyTxThres, EarlyTxThld);
+
+       /* For gigabit rtl8169 */
+       RTL_W16(RxMaxSize, RxPacketMaxSize);
+
+       /* Set Rx Config register */
+       i = rtl8169_rx_config | (RTL_R32(RxConfig) &
+                                rtl_chip_info[tpc->chipset].RxConfigMask);
+       RTL_W32(RxConfig, i);
+
+       /* Set DMA burst size and Interframe Gap Time */
+       RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) |
+                               (InterFrameGap << TxInterFrameGapShift));
+
+
+       tpc->cur_rx = 0;
+
+       RTL_W32(TxDescStartAddr, virt_to_le32desc(tpc->TxDescArray));
+       RTL_W32(RxDescStartAddr, virt_to_le32desc(tpc->RxDescArray));
+       RTL_W8(Cfg9346, Cfg9346_Lock);
+       udelay(10);
+
+       RTL_W32(RxMissed, 0);
+
+       rtl8169_set_rx_mode(dev);
+
+       /* no early-rx interrupts */
+       RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
+
+#ifdef DEBUG_RTL8169
+       printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime);
+#endif
+}
+
+static void rtl8169_init_ring(struct eth_device *dev)
+{
+       int i;
+
+#ifdef DEBUG_RTL8169
+       int stime = currticks();
+       printf ("%s\n", __FUNCTION__);
+#endif
+
+       tpc->cur_rx = 0;
+       tpc->cur_tx = 0;
+       tpc->dirty_tx = 0;
+       memset(tpc->TxDescArray, 0x0, NUM_TX_DESC * sizeof(struct TxDesc));
+       memset(tpc->RxDescArray, 0x0, NUM_RX_DESC * sizeof(struct RxDesc));
+
+       for (i = 0; i < NUM_TX_DESC; i++) {
+               tpc->Tx_skbuff[i] = &txb[i];
+       }
+
+       for (i = 0; i < NUM_RX_DESC; i++) {
+               if (i == (NUM_RX_DESC - 1))
+                       tpc->RxDescArray[i].status =
+                           (OWNbit | EORbit) + RX_BUF_SIZE;
+               else
+                       tpc->RxDescArray[i].status = OWNbit + RX_BUF_SIZE;
+
+               tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE];
+               tpc->RxDescArray[i].buf_addr =
+                   virt_to_bus(tpc->RxBufferRing[i]);
+       }
+
+#ifdef DEBUG_RTL8169
+       printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime);
+#endif
+}
+
+/**************************************************************************
+RESET - Finish setting up the ethernet interface
+***************************************************************************/
+static void rtl_reset(struct eth_device *dev, bd_t *bis)
+{
+       int i;
+       u8 diff;
+       u32 TxPhyAddr, RxPhyAddr;
+
+#ifdef DEBUG_RTL8169
+       int stime = currticks();
+       printf ("%s\n", __FUNCTION__);
+#endif
+
+       tpc->TxDescArrays = tx_ring;
+       if (tpc->TxDescArrays == 0)
+               puts("Allot Error");
+       /* Tx Desscriptor needs 256 bytes alignment; */
+       TxPhyAddr = virt_to_bus(tpc->TxDescArrays);
+       diff = 256 - (TxPhyAddr - ((TxPhyAddr >> 8) << 8));
+       TxPhyAddr += diff;
+       tpc->TxDescArray = (struct TxDesc *) (tpc->TxDescArrays + diff);
+
+       tpc->RxDescArrays = rx_ring;
+       /* Rx Desscriptor needs 256 bytes alignment; */
+       RxPhyAddr = virt_to_bus(tpc->RxDescArrays);
+       diff = 256 - (RxPhyAddr - ((RxPhyAddr >> 8) << 8));
+       RxPhyAddr += diff;
+       tpc->RxDescArray = (struct RxDesc *) (tpc->RxDescArrays + diff);
+
+       if (tpc->TxDescArrays == NULL || tpc->RxDescArrays == NULL) {
+               puts("Allocate RxDescArray or TxDescArray failed\n");
+               return;
+       }
+
+       rtl8169_init_ring(dev);
+       rtl8169_hw_start(dev);
+       /* Construct a perfect filter frame with the mac address as first match
+        * and broadcast for all others */
+       for (i = 0; i < 192; i++)
+               txb[i] = 0xFF;
+
+       txb[0] = dev->enetaddr[0];
+       txb[1] = dev->enetaddr[1];
+       txb[2] = dev->enetaddr[2];
+       txb[3] = dev->enetaddr[3];
+       txb[4] = dev->enetaddr[4];
+       txb[5] = dev->enetaddr[5];
+
+#ifdef DEBUG_RTL8169
+       printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime);
+#endif
+}
+
+/**************************************************************************
+HALT - Turn off ethernet interface
+***************************************************************************/
+static void rtl_halt(struct eth_device *dev)
+{
+       int i;
+
+#ifdef DEBUG_RTL8169
+       printf ("%s\n", __FUNCTION__);
+#endif
+
+       ioaddr = dev->iobase;
+
+       /* Stop the chip's Tx and Rx DMA processes. */
+       RTL_W8(ChipCmd, 0x00);
+
+       /* Disable interrupts by clearing the interrupt mask. */
+       RTL_W16(IntrMask, 0x0000);
+
+       RTL_W32(RxMissed, 0);
+
+       tpc->TxDescArrays = NULL;
+       tpc->RxDescArrays = NULL;
+       tpc->TxDescArray = NULL;
+       tpc->RxDescArray = NULL;
+       for (i = 0; i < NUM_RX_DESC; i++) {
+               tpc->RxBufferRing[i] = NULL;
+       }
+}
+
+/**************************************************************************
+INIT - Look for an adapter, this routine's visible to the outside
+***************************************************************************/
+
+#define board_found 1
+#define valid_link 0
+static int rtl_init(struct eth_device *dev, bd_t *bis)
+{
+       static int board_idx = -1;
+       static int printed_version = 0;
+       int i, rc;
+       int option = -1, Cap10_100 = 0, Cap1000 = 0;
+
+#ifdef DEBUG_RTL8169
+       printf ("%s\n", __FUNCTION__);
+#endif
+
+       ioaddr = dev->iobase;
+
+       board_idx++;
+
+       printed_version = 1;
+
+       /* point to private storage */
+       tpc = &tpx;
+
+       rc = rtl8169_init_board(dev);
+       if (rc)
+               return rc;
+
+       /* Get MAC address.  FIXME: read EEPROM */
+       for (i = 0; i < MAC_ADDR_LEN; i++)
+               dev->enetaddr[i] = RTL_R8(MAC0 + i);
+
+#ifdef DEBUG_RTL8169
+       printf("MAC Address");
+       for (i = 0; i < MAC_ADDR_LEN; i++)
+               printf(":%02x", dev->enetaddr[i]);
+       putc('\n');
+#endif
+
+#ifdef DEBUG_RTL8169
+       /* Print out some hardware info */
+       printf("%s: at ioaddr 0x%x\n", dev->name, ioaddr);
+#endif
+
+       /* if TBI is not endbled */
+       if (!(RTL_R8(PHYstatus) & TBI_Enable)) {
+               int val = mdio_read(PHY_AUTO_NEGO_REG);
+
+               option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx];
+               /* Force RTL8169 in 10/100/1000 Full/Half mode. */
+               if (option > 0) {
+#ifdef DEBUG_RTL8169
+                       printf("%s: Force-mode Enabled.\n", dev->name);
+#endif
+                       Cap10_100 = 0, Cap1000 = 0;
+                       switch (option) {
+                       case _10_Half:
+                               Cap10_100 = PHY_Cap_10_Half;
+                               Cap1000 = PHY_Cap_Null;
+                               break;
+                       case _10_Full:
+                               Cap10_100 = PHY_Cap_10_Full;
+                               Cap1000 = PHY_Cap_Null;
+                               break;
+                       case _100_Half:
+                               Cap10_100 = PHY_Cap_100_Half;
+                               Cap1000 = PHY_Cap_Null;
+                               break;
+                       case _100_Full:
+                               Cap10_100 = PHY_Cap_100_Full;
+                               Cap1000 = PHY_Cap_Null;
+                               break;
+                       case _1000_Full:
+                               Cap10_100 = PHY_Cap_Null;
+                               Cap1000 = PHY_Cap_1000_Full;
+                               break;
+                       default:
+                               break;
+                       }
+                       mdio_write(PHY_AUTO_NEGO_REG, Cap10_100 | (val & 0x1F));        /* leave PHY_AUTO_NEGO_REG bit4:0 unchanged */
+                       mdio_write(PHY_1000_CTRL_REG, Cap1000);
+               } else {
+#ifdef DEBUG_RTL8169
+                       printf("%s: Auto-negotiation Enabled.\n",
+                              dev->name);
+#endif
+                       /* enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged */
+                       mdio_write(PHY_AUTO_NEGO_REG,
+                                  PHY_Cap_10_Half | PHY_Cap_10_Full |
+                                  PHY_Cap_100_Half | PHY_Cap_100_Full |
+                                  (val & 0x1F));
+
+                       /* enable 1000 Full Mode */
+                       mdio_write(PHY_1000_CTRL_REG, PHY_Cap_1000_Full);
+
+               }
+
+               /* Enable auto-negotiation and restart auto-nigotiation */
+               mdio_write(PHY_CTRL_REG,
+                          PHY_Enable_Auto_Nego | PHY_Restart_Auto_Nego);
+               udelay(100);
+
+               /* wait for auto-negotiation process */
+               for (i = 10000; i > 0; i--) {
+                       /* check if auto-negotiation complete */
+                       if (mdio_read(PHY_STAT_REG) & PHY_Auto_Neco_Comp) {
+                               udelay(100);
+                               option = RTL_R8(PHYstatus);
+                               if (option & _1000bpsF) {
+#ifdef DEBUG_RTL8169
+                                       printf("%s: 1000Mbps Full-duplex operation.\n",
+                                            dev->name);
+#endif
+                               } else {
+#ifdef DEBUG_RTL8169
+                                       printf
+                                           ("%s: %sMbps %s-duplex operation.\n",
+                                            dev->name,
+                                            (option & _100bps) ? "100" :
+                                            "10",
+                                            (option & FullDup) ? "Full" :
+                                            "Half");
+#endif
+                               }
+                               break;
+                       } else {
+                               udelay(100);
+                       }
+               }               /* end for-loop to wait for auto-negotiation process */
+
+       } else {
+               udelay(100);
+#ifdef DEBUG_RTL8169
+               printf
+                   ("%s: 1000Mbps Full-duplex operation, TBI Link %s!\n",
+                    dev->name,
+                    (RTL_R32(TBICSR) & TBILinkOK) ? "OK" : "Failed");
+#endif
+       }
+
+       return 1;
+}
+
+int rtl8169_initialize(bd_t *bis)
+{
+       pci_dev_t devno;
+       int card_number = 0;
+       struct eth_device *dev;
+       u32 iobase;
+       int idx=0;
+
+       while(1){
+               /* Find RTL8169 */
+               if ((devno = pci_find_devices(supported, idx++)) < 0)
+                       break;
+
+               pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase);
+               iobase &= ~0xf;
+
+               debug ("rtl8169: REALTEK RTL8169 @0x%x\n", iobase);
+
+               dev = (struct eth_device *)malloc(sizeof *dev);
+
+               sprintf (dev->name, "RTL8169#%d", card_number);
+
+               dev->priv = (void *) devno;
+               dev->iobase = (int)bus_to_phys(iobase);
+
+               dev->init = rtl_reset;
+               dev->halt = rtl_halt;
+               dev->send = rtl_send;
+               dev->recv = rtl_recv;
+
+               eth_register (dev);
+
+               rtl_init(dev, bis);
+
+               card_number++;
+       }
+       return card_number;
+}
+
+#endif
diff --git a/drivers/net/s3c4510b_eth.c b/drivers/net/s3c4510b_eth.c
new file mode 100644 (file)
index 0000000..3d9066a
--- /dev/null
@@ -0,0 +1,246 @@
+/***********************************************************************
+ *
+ * Copyright (c) 2004  Cucy Systems (http://www.cucy.com)
+ * Curt Brune <curt@cucy.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Description:   Ethernet interface for Samsung S3C4510B SoC
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DRIVER_S3C4510_ETH
+
+#include <command.h>
+#include <net.h>
+#include <asm/hardware.h>
+#include "s3c4510b_eth.h"
+
+static TX_FrameDescriptor    txFDbase[ETH_MaxTxFrames];
+static MACFrame           txFrameBase[ETH_MaxTxFrames];
+static RX_FrameDescriptor    rxFDbase[PKTBUFSRX];
+static ETH                      m_eth;
+
+static s32 TxFDinit( ETH *eth) {
+
+       s32 i;
+       MACFrame *txFrmBase;
+
+       /* disable cache for access to the TX buffers */
+       txFrmBase = (MACFrame *)( (u32)txFrameBase | CACHE_DISABLE_MASK);
+
+       /* store start of Tx descriptors and set current */
+       eth->m_curTX_FD  =  (TX_FrameDescriptor *) ((u32)txFDbase | CACHE_DISABLE_MASK);
+       eth->m_baseTX_FD = eth->m_curTX_FD;
+
+       for ( i = 0; i < ETH_MaxTxFrames; i++) {
+               eth->m_baseTX_FD[i].m_frameDataPtr.bf.dataPtr = (u32)&txFrmBase[i];
+               eth->m_baseTX_FD[i].m_frameDataPtr.bf.owner   = 0x0; /* CPU owner */
+               eth->m_baseTX_FD[i].m_opt.ui                  = 0x0;
+               eth->m_baseTX_FD[i].m_status.ui               = 0x0;
+               eth->m_baseTX_FD[i].m_nextFD                  = &eth->m_baseTX_FD[i+1];
+       }
+
+       /* make the list circular */
+       eth->m_baseTX_FD[i-1].m_nextFD          = &eth->m_baseTX_FD[0];
+
+       PUT_REG( REG_BDMATXPTR, (u32)eth->m_curTX_FD);
+
+       return 0;
+}
+
+static s32 RxFDinit( ETH *eth) {
+
+       s32 i;
+       /*  MACFrame *rxFrmBase; */
+
+       /* disable cache for access to the RX buffers */
+       /*  rxFrmBase = (MACFrame *)( (u32)rxFrameBase | CACHE_DISABLE_MASK); */
+
+       /* store start of Rx descriptors and set current */
+       eth->m_curRX_FD = (RX_FrameDescriptor *)((u32)rxFDbase | CACHE_DISABLE_MASK);
+       eth->m_baseRX_FD = eth->m_curRX_FD;
+       for ( i = 0; i < PKTBUFSRX; i++) {
+               eth->m_baseRX_FD[i].m_frameDataPtr.bf.dataPtr = (u32)NetRxPackets[i] | CACHE_DISABLE_MASK;
+               eth->m_baseRX_FD[i].m_frameDataPtr.bf.owner   = 0x1; /* BDMA owner */
+               eth->m_baseRX_FD[i].m_reserved                = 0x0;
+               eth->m_baseRX_FD[i].m_status.ui               = 0x0;
+               eth->m_baseRX_FD[i].m_nextFD                  = &eth->m_baseRX_FD[i+1];
+       }
+
+       /* make the list circular */
+       eth->m_baseRX_FD[i-1].m_nextFD                  = &eth->m_baseRX_FD[0];
+
+       PUT_REG( REG_BDMARXPTR, (u32)eth->m_curRX_FD);
+
+       return 0;
+}
+
+/*
+ * Public u-boot interface functions below
+ */
+
+int eth_init(bd_t *bis)
+{
+
+       ETH *eth = &m_eth;
+
+       /* store our MAC address */
+       eth->m_mac = bis->bi_enetaddr;
+
+       /* setup DBMA and MAC */
+       PUT_REG( REG_BDMARXCON, ETH_BRxRS);   /* reset BDMA RX machine */
+       PUT_REG( REG_BDMATXCON, ETH_BTxRS);   /* reset BDMA TX machine */
+       PUT_REG( REG_MACCON   , ETH_SwReset); /* reset MAC machine */
+       PUT_REG( REG_BDMARXLSZ, sizeof(MACFrame));
+       PUT_REG( REG_MACCON   , 0);           /* reset MAC machine */
+
+       /* init frame descriptors */
+       TxFDinit( eth);
+       RxFDinit( eth);
+
+       /* init the CAM with our MAC address */
+       PUT_REG( REG_CAM_BASE,       (eth->m_mac[0] << 24) |
+               (eth->m_mac[1] << 16) |
+               (eth->m_mac[2] <<  8) |
+               (eth->m_mac[3]));
+       PUT_REG( REG_CAM_BASE + 0x4, (eth->m_mac[4] << 24) |
+               (eth->m_mac[5] << 16));
+
+       /* enable CAM address 1 -- the MAC we just loaded */
+       PUT_REG( REG_CAMEN, 0x1);
+
+       PUT_REG( REG_CAMCON,
+               ETH_BroadAcc |  /* accept broadcast packetes */
+               ETH_CompEn); /* enable compare mode (check against the CAM) */
+
+       /* configure the BDMA Transmitter control */
+       PUT_REG( REG_BDMATXCON,
+               ETH_BTxBRST   | /* BDMA Tx burst size 16 words  */
+               ETH_BTxMSL110 | /* BDMA Tx wait to fill 6/8 of the BDMA */
+               ETH_BTxSTSKO  | /* BDMA Tx interrupt(Stop) on non-owner TX FD */
+               ETH_BTxEn);     /* BDMA Tx Enable  */
+
+       /* configure the MAC Transmitter control */
+       PUT_REG( REG_MACTXCON,
+               ETH_EnComp | /* interrupt when the MAC transmits or discards packet */
+               ETH_TxEn);      /* MAC transmit enable */
+
+       /* configure the BDMA Receiver control */
+       PUT_REG( REG_BDMARXCON,
+               ETH_BRxBRST   | /* BDMA Rx Burst Size 16 words */
+               ETH_BRxSTSKO  | /* BDMA Rx interrupt(Stop) on non-owner RX FD */
+               ETH_BRxMAINC  | /* BDMA Rx Memory Address increment */
+               ETH_BRxDIE    | /* BDMA Rx Every Received Frame Interrupt Enable */
+               ETH_BRxNLIE   | /* BDMA Rx NULL List Interrupt Enable */
+               ETH_BRxNOIE   | /* BDMA Rx Not Owner Interrupt Enable */
+               ETH_BRxLittle | /* BDMA Rx Little endian */
+               ETH_BRxEn);     /* BDMA Rx Enable */
+
+       /* configure the MAC Receiver control */
+       PUT_REG( REG_MACRXCON,
+               ETH_RxEn);      /* MAC ETH_RxEn */
+
+       return 0;
+
+}
+
+/* Send a packet       */
+s32 eth_send(volatile void *packet, s32 length)
+{
+
+       u32 i;
+       ETH *eth = &m_eth;
+
+       if ( eth->m_curTX_FD->m_frameDataPtr.bf.owner) {
+               printf("eth_send(): TX Frame.  CPU not owner.\n");
+               return -1;
+       }
+
+       /* copy user data into frame data pointer */
+       memcpy((void *)((u32)(eth->m_curTX_FD->m_frameDataPtr.bf.dataPtr)),
+              (void *)packet,
+              length);
+
+       /* Set TX Frame flags */
+       eth->m_curTX_FD->m_opt.bf.widgetAlign  = 0;
+       eth->m_curTX_FD->m_opt.bf.frameDataDir = 1;
+       eth->m_curTX_FD->m_opt.bf.littleEndian = 1;
+       eth->m_curTX_FD->m_opt.bf.macTxIrqEnbl = 1;
+       eth->m_curTX_FD->m_opt.bf.no_crc       = 0;
+       eth->m_curTX_FD->m_opt.bf.no_padding   = 0;
+
+       /* Set TX Frame length */
+       eth->m_curTX_FD->m_status.bf.len       = length;
+
+       /* Change ownership to BDMA */
+       eth->m_curTX_FD->m_frameDataPtr.bf.owner = 1;
+
+       /* Enable MAC and BDMA Tx control register */
+       SET_REG( REG_BDMATXCON, ETH_BTxEn);
+       SET_REG( REG_MACTXCON,  ETH_TxEn);
+
+       /* poll on TX completion status */
+       while ( !eth->m_curTX_FD->m_status.bf.complete) {
+               /* sleep  */
+               for ( i = 0; i < 0x10000; i ++);
+       }
+
+       /* Change the Tx frame descriptor for next use */
+       eth->m_curTX_FD = eth->m_curTX_FD->m_nextFD;
+
+       return 0;
+}
+
+/* Check for received packets  */
+s32 eth_rx (void)
+{
+       s32 nLen = 0;
+       ETH *eth = &m_eth;
+
+       /* check if packet ready */
+       if ( (GET_REG( REG_BDMASTAT)) & ETH_S_BRxRDF) {
+               /* process all waiting packets */
+               while ( !eth->m_curRX_FD->m_frameDataPtr.bf.owner) {
+                       nLen = eth->m_curRX_FD->m_status.bf.len;
+                       /* call back u-boot -- may call eth_send() */
+                       NetReceive ((u8 *)eth->m_curRX_FD->m_frameDataPtr.ui, nLen);
+                       /* set owner back to CPU */
+                       eth->m_curRX_FD->m_frameDataPtr.bf.owner = 1;
+                       /* clear status */
+                       eth->m_curRX_FD->m_status.ui = 0x0;
+                       /* advance to next descriptor */
+                       eth->m_curRX_FD = eth->m_curRX_FD->m_nextFD;
+                       /* clear received frame bit */
+                       PUT_REG( REG_BDMASTAT, ETH_S_BRxRDF);
+               }
+       }
+
+       return nLen;
+}
+
+/* Halt ethernet engine */
+void eth_halt(void)
+{
+       /* disable MAC */
+       PUT_REG( REG_MACCON, ETH_HaltReg);
+}
+
+#endif
diff --git a/drivers/net/s3c4510b_eth.h b/drivers/net/s3c4510b_eth.h
new file mode 100644 (file)
index 0000000..cbddba7
--- /dev/null
@@ -0,0 +1,302 @@
+#ifndef __S3C4510B_ETH_H
+#define __S3C4510B_ETH_H
+/*
+ * Copyright (c) 2004  Cucy Systems (http://www.cucy.com)
+ * Curt Brune <curt@cucy.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * MODULE:        $Id:$
+ * Description:   Ethernet interface
+ * Runtime Env:   ARM7TDMI
+ * Change History:
+ *     03-02-04    Create (Curt Brune) curt@cucy.com
+ *
+ */
+
+#define __packed    __attribute__ ((packed))
+
+#define ETH_MAC_ADDR_SIZE           (6)    /*  dst,src addr is 6bytes each */
+#define ETH_MaxTxFrames             (16)   /*  Max number of Tx Frames */
+
+/*  Buffered DMA Receiver Control Register  */
+#define ETH_BRxBRST     0x0000F  /*  BDMA Rx Burst Size * BRxBRST  */
+                                /*  = Burst Data Size 16 */
+#define ETH_BRxSTSKO    0x00020  /*  BDMA Rx Stop/Skip  Frame or Interrupt(=1)  */
+                                /*  case of not OWNER the current Frame  */
+#define ETH_BRxMAINC    0x00040  /*  BDMA Rx Memory Address Inc/Dec  */
+#define ETH_BRxDIE      0x00080  /*  BDMA Rx Every Received Frame Interrupt Enable */
+#define ETH_BRxNLIE     0x00100  /*  BDMA Rx NULL List Interrupt Enable  */
+#define ETH_BRxNOIE     0x00200  /*  BDMA Rx Not Owner Interrupt Enable */
+#define ETH_BRxMSOIE    0x00400  /*  BDMA Rx Maximum Size over Interrupr Enable  */
+#define ETH_BRxLittle   0x00800  /*  BDMA Rx Big/Little Endian  */
+#define ETH_BRxBig      0x00000  /*  BDMA Rx Big/Little Endian */
+#define ETH_BRxWA01     0x01000  /*  BDMA Rx Word Alignment- one invalid byte  */
+#define ETH_BRxWA10     0x02000  /*  BDMA Rx Word Alignment- two invalid byte */
+#define ETH_BRxWA11     0x03000  /*  BDMA Rx Word Alignment- three invalid byte  */
+#define ETH_BRxEn       0x04000  /*  BDMA Rx Enable */
+#define ETH_BRxRS       0x08000  /*  BDMA Rx Reset */
+#define ETH_RxEmpty     0x10000  /*  BDMA Rx Buffer empty interrupt  */
+#define ETH_BRxEarly    0x20000  /*  BDMA Rx Early notify Interrupt */
+
+/*  Buffered DMA Trasmit Control Register(BDMATXCON)  */
+#define ETH_BTxBRST     0x0000F  /*  BDMA Tx Burst Size = 16  */
+#define ETH_BTxSTSKO    0x00020  /*  BDMA Tx Stop/Skip Frame or Interrupt in case */
+                                /*  of not Owner the current frame  */
+#define ETH_BTxCPIE     0x00080  /*  BDMA Tx Complete to send control  */
+                                /*  packet Enable */
+#define ETH_BTxNOIE     0x00200  /*  BDMA Tx Buffer Not Owner */
+#define ETH_BTxEmpty    0x00400  /*  BDMA Tx Buffer Empty Interrupt  */
+
+/*  BDMA Tx buffer can be moved to the MAC Tx IO when the new frame comes in.  */
+#define ETH_BTxMSL000   0x00000  /*  No wait to fill the BDMA  */
+#define ETH_BTxMSL001   0x00800  /*  wait to fill 1/8 of the BDMA  */
+#define ETH_BTxMSL010   0x01000  /*  wait to fill 2/8 of the BDMA */
+#define ETH_BTxMSL011   0x01800  /*  wait to fill 3/8 of the BDMA */
+#define ETH_BTxMSL100   0x02000  /*  wait to fill 4/8 of the BDMA */
+#define ETH_BTxMSL101   0x02800  /*  wait to fill 5/8 of the BDMA */
+#define ETH_BTxMSL110   0x03000  /*  wait to fill 6/8 of the BDMA */
+#define ETH_BTxMSL111   0x03800  /*  wait to fill 7/8 of the BDMA */
+#define ETH_BTxEn       0x04000  /*  BDMA Tx Enable  */
+#define ETH_BTxRS       0x08000  /*  BDMA Tx Reset  */
+
+/*  BDMA Status Register  */
+#define ETH_S_BRxRDF    0x00001  /*  BDMA Rx Done Every Received Frame  */
+#define ETH_S_BRxNL     0x00002  /*  BDMA Rx NULL List  */
+#define ETH_S_BRxNO     0x00004  /*  BDMA Rx Not Owner  */
+#define ETH_S_BRxMSO    0x00008  /*  BDMA Rx Maximum Size Over  */
+#define ETH_S_BRxEmpty  0x00010  /*  BDMA Rx Buffer Empty  */
+#define ETH_S_BRxSEarly 0x00020  /*  Early Notify  */
+#define ETH_S_BRxFRF    0x00080  /*  One more frame data in BDMA receive buffer  */
+#define ETH_S_BTxCCP    0x10000  /*  BDMA Tx Complete to send Control Packet  */
+#define ETH_S_BTxNL     0x20000  /*  BDMA Tx Null List  */
+#define ETH_S_BTxNO     0x40000  /*  BDMA Tx Not Owner */
+#define ETH_S_BTxEmpty  0x100000 /*  BDMA Tx Buffer Empty  */
+
+/*  MAC Control Register  */
+#define ETH_HaltReg     0x0001   /*  stop transmission and reception  */
+                                /*  after completion of any current packets  */
+#define ETH_HaltImm     0x0002   /*  Stop transmission and reception immediately  */
+#define ETH_SwReset     0x0004   /*  reset all Ethernet controller state machines */
+                                /*  and FIFOs  */
+#define ETH_FullDup     0x0008   /*  allow transmission to begin while reception */
+                                /*  is occurring  */
+#define ETH_MACLoop     0x0010   /*  MAC loopback */
+#define ETH_ConnM00     0x0000   /*  Automatic-default  */
+#define ETH_ConnM01     0x0020   /*  Force 10Mbits endec */
+#define ETH_ConnM10     0x0040   /*  Force MII (rate determined by MII clock  */
+#define ETH_MIIOFF      0x0040   /*  Force MII (rate determined by MII clock  */
+#define ETH_Loop10      0x0080   /*  Loop 10Mbps  */
+#define ETH_MissRoll    0x0400   /*  Missed error counter rolled over  */
+#define ETH_MDCOFF      0x1000   /*  MII Station Management Clock Off */
+#define ETH_EnMissRoll  0x2000   /*  Interrupt when missed error counter rolls  */
+                                /*  over  */
+#define ETH_Link10      0x8000   /*  Link status 10Mbps  */
+
+/*  CAM control register(CAMCON)  */
+#define ETH_StationAcc  0x0001   /*  Accept any packet with a unicast station  */
+                                /*  address  */
+#define ETH_GroupAcc    0x0002   /*  Accept any packet with multicast-group  */
+                                /*  station address   */
+#define ETH_BroadAcc    0x0004   /*  Accept any packet with a broadcast station */
+                                /*  address  */
+#define ETH_NegCAM      0x0008   /*  0: Accept packets CAM recognizes,  */
+                                /*     reject others */
+                                /*  1: reject packets CAM recognizes,  */
+                                /*     accept others  */
+#define ETH_CompEn      0x0010   /*  Compare Enable mode */
+
+/*  Transmit Control Register(MACTXCON) */
+#define ETH_TxEn        0x0001   /*  transmit Enable  */
+#define ETH_TxHalt      0x0002   /*  Transmit Halt Request  */
+#define ETH_NoPad       0x0004   /*  suppress Padding  */
+#define ETH_NoCRC       0x0008   /*  Suppress CRC  */
+#define ETH_FBack       0x0010   /*  Fast Back-off */
+#define ETH_NoDef       0x0020   /*  Disable the defer counter */
+#define ETH_SdPause     0x0040   /*  Send Pause */
+#define ETH_MII10En     0x0080   /*  MII 10Mbps mode enable */
+#define ETH_EnUnder     0x0100   /*  Enable Underrun */
+#define ETH_EnDefer     0x0200   /*  Enable Deferral */
+#define ETH_EnNCarr     0x0400   /*  Enable No Carrier  */
+#define ETH_EnExColl    0x0800   /*  interrupt if 16 collision occur  */
+                                /*  in the same packet  */
+#define ETH_EnLateColl  0x1000   /*  interrupt if collision occurs after  */
+                                /*  512 bit times(64 bytes times)  */
+#define ETH_EnTxPar     0x2000   /*  interrupt if the MAC transmit FIFO  */
+                                /*  has a parity error  */
+#define ETH_EnComp      0x4000   /*  interrupt when the MAC transmits or  */
+                                /*  discards one packet  */
+
+/*  Transmit Status Register(MACTXSTAT) */
+#define ETH_ExColl      0x0010   /*  Excessive collision  */
+#define ETH_TxDeffered  0x0020   /*  set if 16 collisions occur for same packet */
+#define ETH_Paused      0x0040   /*  packet waited because of pause during  */
+                                /*  transmission  */
+#define ETH_IntTx       0x0080   /*  set if transmission of packet causes an  */
+                                /*  interrupt condiftion  */
+#define ETH_Under       0x0100   /*  MAC transmit FIFO becomes empty during  */
+                                /*  transmission  */
+#define ETH_Defer       0x0200   /*  MAC defers for MAC deferral  */
+#define ETH_NCarr       0x0400   /*  No carrier sense detected during the  */
+                                /*  transmission of a packet  */
+#define ETH_SQE         0x0800   /*  Signal Quality Error */
+#define ETH_LateColl    0x1000   /*  a collision occures after 512 bit times  */
+#define ETH_TxPar       0x2000   /*  MAC transmit FIFO has detected a parity error */
+#define ETH_Comp        0x4000   /*  MAC transmit or discards one packet  */
+#define ETH_TxHalted    0x8000   /*  Transmission was halted by clearing  */
+                                /*  TxEn or Halt immedite  */
+
+/*  Receive Control Register (MACRXCON)  */
+#define ETH_RxEn        0x0001
+#define ETH_RxHalt      0x0002
+#define ETH_LongEn      0x0004
+#define ETH_ShortEn     0x0008
+#define ETH_StripCRC    0x0010
+#define ETH_PassCtl     0x0020
+#define ETH_IgnoreCRC   0x0040
+#define ETH_EnAlign     0x0100
+#define ETH_EnCRCErr    0x0200
+#define ETH_EnOver      0x0400
+#define ETH_EnLongErr   0x0800
+#define ETH_EnRxPar     0x2000
+#define ETH_EnGood      0x4000
+
+/*  Receive Status Register(MACRXSTAT) */
+#define ETH_MCtlRecd    0x0020
+#define ETH_MIntRx      0x0040
+#define ETH_MRx10Stat   0x0080
+#define ETH_MAllignErr  0x0100
+#define ETH_MCRCErr     0x0200
+#define ETH_MOverflow   0x0400
+#define ETH_MLongErr    0x0800
+#define ETH_MRxPar      0x2000
+#define ETH_MRxGood     0x4000
+#define ETH_MRxHalted   0x8000
+
+/*  type of ethernet packets */
+#define ETH_TYPE_ARP  (0x0806)
+#define ETH_TYPE_IP   (0x0800)
+
+#define ETH_HDR_SIZE  (14)
+
+/*  bit field for frame data pointer word */
+typedef struct __BF_FrameDataPtr {
+       u32 dataPtr:31;
+       u32   owner: 1;
+} BF_FrameDataPtr;
+
+typedef union _FrameDataPtr {
+       u32             ui;
+       BF_FrameDataPtr bf;
+} FrameDataPtr;
+
+typedef struct __BF_TX_Options {
+       u32    no_padding: 1;
+       u32        no_crc: 1;
+       u32  macTxIrqEnbl: 1;
+       u32  littleEndian: 1;
+       u32  frameDataDir: 1;
+       u32   widgetAlign: 2;
+       u32      reserved:25;
+} BF_TX_Options;
+
+typedef union _TX_Options {
+       u32    ui;
+       BF_TX_Options   bf;
+} TX_Options;
+
+typedef struct __BF_RX_Status {
+       u32           len:16;   /*  frame length */
+       u32     reserved1: 3;
+       u32       overMax: 1;
+       u32     reserved2: 1;
+       u32       ctrlRcv: 1;
+       u32         intRx: 1;
+       u32      rx10stat: 1;
+       u32      alignErr: 1;
+       u32        crcErr: 1;
+       u32      overFlow: 1;
+       u32       longErr: 1;
+       u32     reserved3: 1;
+       u32     parityErr: 1;
+       u32          good: 1;
+       u32        halted: 1;
+} BF_RX_Status;
+
+typedef union _RX_Status {
+       u32             ui;
+       BF_RX_Status    bf;
+} RX_Status;
+
+typedef struct __BF_TX_Status {
+       u32           len:16;   /*  frame length */
+       u32     txCollCnt: 4;
+       u32        exColl: 1;
+       u32       txDefer: 1;
+       u32        paused: 1;
+       u32         intTx: 1;
+       u32      underRun: 1;
+       u32         defer: 1;
+       u32     noCarrier: 1;
+       u32         SQErr: 1;
+       u32      lateColl: 1;
+       u32     parityErr: 1;
+       u32      complete: 1;
+       u32        halted: 1;
+} BF_TX_Status;
+
+typedef union _TX_Status {
+       u32    ui;
+       BF_TX_Status    bf;
+} TX_Status;
+
+/*  TX descriptor structure  */
+typedef struct __TX_FrameDescriptor {
+       volatile FrameDataPtr  m_frameDataPtr;
+       TX_Options                      m_opt;
+       volatile TX_Status           m_status;
+       struct __TX_FrameDescriptor *m_nextFD;
+} TX_FrameDescriptor;
+
+/*  RX descriptor structure  */
+typedef struct __RX_FrameDescriptor {
+       volatile FrameDataPtr  m_frameDataPtr;
+       u32                        m_reserved;
+       volatile RX_Status           m_status;
+       struct __RX_FrameDescriptor *m_nextFD;
+} RX_FrameDescriptor;
+
+/*  MAC Frame Structure */
+typedef struct __MACFrame {
+       u8     m_dstAddr[6] __packed;
+       u8     m_srcAddr[6] __packed;
+       u16  m_lengthOrType __packed;
+       u8  m_payload[1506] __packed;
+} MACFrame;
+
+/* Ethernet Control block */
+typedef struct __ETH {
+       TX_FrameDescriptor   *m_curTX_FD; /*  pointer to current TX frame descriptor */
+       TX_FrameDescriptor  *m_baseTX_FD; /*  pointer to base TX frame descriptor    */
+       RX_FrameDescriptor   *m_curRX_FD; /*  pointer to current RX frame descriptor */
+       RX_FrameDescriptor  *m_baseRX_FD; /*  pointer to base RX frame descriptor    */
+       u8                        *m_mac; /*  pointer to our MAC address             */
+} ETH;
+
+#endif
diff --git a/drivers/net/sk98lin/Makefile b/drivers/net/sk98lin/Makefile
new file mode 100644 (file)
index 0000000..a7d4a3b
--- /dev/null
@@ -0,0 +1,120 @@
+#
+# (C) Copyright 2003-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+# File: drivers/sk98lin/Makefile
+#
+# Makefile for the SysKonnect SK-98xx device driver.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libsk98lin.a
+
+COBJS-y += skge.o
+COBJS-y += skaddr.o
+COBJS-y += skgehwt.o
+COBJS-y += skgeinit.o
+COBJS-y += skgepnmi.o
+COBJS-y += skgesirq.o
+COBJS-y += ski2c.o
+COBJS-y += sklm80.o
+COBJS-y += skqueue.o
+COBJS-y += skrlmt.o
+COBJS-y += sktimer.o
+COBJS-y += skvpd.o
+COBJS-y += skxmac2.o
+COBJS-y += skcsum.o
+#COBJS-y += skproc.o
+
+COBJS-y += uboot_skb.o
+COBJS-y += uboot_drv.o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+# DBGDEF =  \
+# -DDEBUG
+
+ifdef DEBUG
+DBGDEF +=  \
+-DSK_DEBUG_CHKMOD=0x00000000L \
+-DSK_DEBUG_CHKCAT=0x00000000L
+endif
+
+
+# **** possible debug modules for SK_DEBUG_CHKMOD *****************
+# SK_DBGMOD_MERR        0x00000001L     /* general module error indication */
+# SK_DBGMOD_HWM         0x00000002L     /* Hardware init module */
+# SK_DBGMOD_RLMT        0x00000004L     /* RLMT module */
+# SK_DBGMOD_VPD         0x00000008L     /* VPD module */
+# SK_DBGMOD_I2C         0x00000010L     /* I2C module */
+# SK_DBGMOD_PNMI        0x00000020L     /* PNMI module */
+# SK_DBGMOD_CSUM        0x00000040L     /* CSUM module */
+# SK_DBGMOD_ADDR        0x00000080L     /* ADDR module */
+# SK_DBGMOD_DRV         0x00010000L     /* DRV module */
+
+# **** possible debug categories for SK_DEBUG_CHKCAT **************
+# *** common modules ***
+# SK_DBGCAT_INIT        0x00000001L     module/driver initialization
+# SK_DBGCAT_CTRL        0x00000002L     controlling: add/rmv MCA/MAC and other controls (IOCTL)
+# SK_DBGCAT_ERR         0x00000004L     error handling paths
+# SK_DBGCAT_TX          0x00000008L     transmit path
+# SK_DBGCAT_RX          0x00000010L     receive path
+# SK_DBGCAT_IRQ         0x00000020L     general IRQ handling
+# SK_DBGCAT_QUEUE       0x00000040L     any queue management
+# SK_DBGCAT_DUMP        0x00000080L     large data output e.g. hex dump
+# SK_DBGCAT_FATAL       0x00000100L     large data output e.g. hex dump
+
+# *** driver (file skge.c) ***
+# SK_DBGCAT_DRV_ENTRY           0x00010000      entry points
+# SK_DBGCAT_DRV_???             0x00020000      not used
+# SK_DBGCAT_DRV_MCA             0x00040000      multicast
+# SK_DBGCAT_DRV_TX_PROGRESS     0x00080000      tx path
+# SK_DBGCAT_DRV_RX_PROGRESS     0x00100000      rx path
+# SK_DBGCAT_DRV_PROGRESS        0x00200000      general runtime
+# SK_DBGCAT_DRV_???             0x00400000      not used
+# SK_DBGCAT_DRV_PROM            0x00800000      promiscuous mode
+# SK_DBGCAT_DRV_TX_FRAME        0x01000000      display tx frames
+# SK_DBGCAT_DRV_ERROR           0x02000000      error conditions
+# SK_DBGCAT_DRV_INT_SRC         0x04000000      interrupts sources
+# SK_DBGCAT_DRV_EVENT           0x08000000      driver events
+
+EXTRA_CFLAGS += -I. -DSK_USE_CSUM $(DBGDEF)
+
+CFLAGS += $(EXTRA_CFLAGS)
+HOST_CFLAGS += $(EXTRA_CFLAGS)
+
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/net/sk98lin/h/lm80.h b/drivers/net/sk98lin/h/lm80.h
new file mode 100644 (file)
index 0000000..981a4ca
--- /dev/null
@@ -0,0 +1,197 @@
+/******************************************************************************
+ *
+ * Name:       lm80.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.4 $
+ * Date:       $Date: 2002/04/25 11:04:10 $
+ * Purpose:    Contains all defines for the LM80 Chip
+ *             (National Semiconductor).
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2002 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *     $Log: lm80.h,v $
+ *     Revision 1.4  2002/04/25 11:04:10  rschmidt
+ *     Editorial changes
+ *
+ *     Revision 1.3  1999/11/22 13:41:19  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.2  1999/03/12 13:26:51  malthoff
+ *     remove __STDC__.
+ *
+ *     Revision 1.1  1998/06/19 09:28:31  malthoff
+ *     created.
+ *
+ *
+ ******************************************************************************/
+
+#ifndef __INC_LM80_H
+#define __INC_LM80_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* defines ********************************************************************/
+
+/*
+ * LM80 register definition
+ *
+ * All registers are 8 bit wide
+ */
+#define        LM80_CFG                        0x00    /* Configuration Register */
+#define        LM80_ISRC_1                     0x01    /* Interrupt Status Register 1 */
+#define LM80_ISRC_2                    0x02    /* Interrupt Status Register 2 */
+#define LM80_IMSK_1                    0x03    /* Interrupt Mask Register 1 */
+#define LM80_IMSK_2                    0x04    /* Interrupt Mask Register 2 */
+#define LM80_FAN_CTRL          0x05    /* Fan Devisor/RST#/OS# Register */
+#define LM80_TEMP_CTRL         0x06    /* OS# Config, Temp Res. Reg */
+       /* 0x07 - 0x1f reserved */
+       /* current values */
+#define LM80_VT0_IN                    0x20    /* current Voltage 0 value */
+#define LM80_VT1_IN                    0x21    /* current Voltage 1 value */
+#define LM80_VT2_IN                    0x22    /* current Voltage 2 value */
+#define LM80_VT3_IN                    0x23    /* current Voltage 3 value */
+#define LM80_VT4_IN                    0x24    /* current Voltage 4 value */
+#define LM80_VT5_IN                    0x25    /* current Voltage 5 value */
+#define LM80_VT6_IN                    0x26    /* current Voltage 6 value */
+#define LM80_TEMP_IN           0x27    /* current Temperature value */
+#define LM80_FAN1_IN           0x28    /* current Fan 1 count */
+#define LM80_FAN2_IN           0x29    /* current Fan 2 count */
+       /* limit values */
+#define LM80_VT0_HIGH_LIM      0x2a    /* high limit val for Voltage 0 */
+#define LM80_VT0_LOW_LIM       0x2b    /* low limit val for Voltage 0 */
+#define LM80_VT1_HIGH_LIM      0x2c    /* high limit val for Voltage 1 */
+#define LM80_VT1_LOW_LIM       0x2d    /* low limit val for Voltage 1 */
+#define LM80_VT2_HIGH_LIM      0x2e    /* high limit val for Voltage 2 */
+#define LM80_VT2_LOW_LIM       0x2f    /* low limit val for Voltage 2 */
+#define LM80_VT3_HIGH_LIM      0x30    /* high limit val for Voltage 3 */
+#define LM80_VT3_LOW_LIM       0x31    /* low limit val for Voltage 3 */
+#define LM80_VT4_HIGH_LIM      0x32    /* high limit val for Voltage 4 */
+#define LM80_VT4_LOW_LIM       0x33    /* low limit val for Voltage 4 */
+#define LM80_VT5_HIGH_LIM      0x34    /* high limit val for Voltage 5 */
+#define LM80_VT5_LOW_LIM       0x35    /* low limit val for Voltage 5 */
+#define LM80_VT6_HIGH_LIM      0x36    /* high limit val for Voltage 6 */
+#define LM80_VT6_LOW_LIM       0x37    /* low limit val for Voltage 6 */
+#define LM80_THOT_LIM_UP       0x38    /* hot temperature limit (high) */
+#define LM80_THOT_LIM_LO       0x39    /* hot temperature limit (low) */
+#define LM80_TOS_LIM_UP                0x3a    /* OS temperature limit (high) */
+#define LM80_TOS_LIM_LO                0x3b    /* OS temperature limit (low) */
+#define        LM80_FAN1_COUNT_LIM     0x3c    /* Fan 1 count limit (high) */
+#define        LM80_FAN2_COUNT_LIM     0x3d    /* Fan 2 count limit (low) */
+       /* 0x3e - 0x3f reserved */
+
+/*
+ * LM80 bit definitions
+ */
+
+/*     LM80_CFG                Configuration Register */
+#define LM80_CFG_START         (1<<0)  /* start monitoring operation */
+#define LM80_CFG_INT_ENA       (1<<1)  /* enables the INT# Interrupt output */
+#define LM80_CFG_INT_POL       (1<<2)  /* INT# pol: 0 act low, 1 act high */
+#define LM80_CFG_INT_CLR       (1<<3)  /* disables INT#/RST_OUT#/OS# outputs */
+#define LM80_CFG_RESET         (1<<4)  /* signals a reset */
+#define LM80_CFG_CHASS_CLR     (1<<5)  /* clears Chassis Intrusion (CI) pin */
+#define LM80_CFG_GPO           (1<<6)  /* drives the GPO# pin */
+#define LM80_CFG_INIT          (1<<7)  /* restore power on defaults */
+
+/*     LM80_ISRC_1             Interrupt Status Register 1 */
+/*     LM80_IMSK_1             Interrupt Mask Register 1 */
+#define LM80_IS_VT0                    (1<<0)  /* limit exceeded for Voltage 0 */
+#define LM80_IS_VT1                    (1<<1)  /* limit exceeded for Voltage 1 */
+#define LM80_IS_VT2                    (1<<2)  /* limit exceeded for Voltage 2 */
+#define LM80_IS_VT3                    (1<<3)  /* limit exceeded for Voltage 3 */
+#define LM80_IS_VT4                    (1<<4)  /* limit exceeded for Voltage 4 */
+#define LM80_IS_VT5                    (1<<5)  /* limit exceeded for Voltage 5 */
+#define LM80_IS_VT6                    (1<<6)  /* limit exceeded for Voltage 6 */
+#define LM80_IS_INT_IN         (1<<7)  /* state of INT_IN# */
+
+/*     LM80_ISRC_2             Interrupt Status Register 2 */
+/*     LM80_IMSK_2             Interrupt Mask Register 2 */
+#define        LM80_IS_TEMP            (1<<0)  /* HOT temperature limit exceeded */
+#define LM80_IS_BTI                    (1<<1)  /* state of BTI# pin */
+#define LM80_IS_FAN1           (1<<2)  /* count limit exceeded for Fan 1 */
+#define LM80_IS_FAN2           (1<<3)  /* count limit exceeded for Fan 2 */
+#define LM80_IS_CI                     (1<<4)  /* Chassis Intrusion occured */
+#define LM80_IS_OS                     (1<<5)  /* OS temperature limit exceeded */
+       /* bit 6 and 7 are reserved in LM80_ISRC_2 */
+#define LM80_IS_HT_IRQ_MD      (1<<6)  /* Hot temperature interrupt mode */
+#define LM80_IS_OT_IRQ_MD      (1<<7)  /* OS temperature interrupt mode */
+
+/*     LM80_FAN_CTRL           Fan Devisor/RST#/OS# Register */
+#define LM80_FAN1_MD_SEL       (1<<0)  /* Fan 1 mode select */
+#define LM80_FAN2_MD_SEL       (1<<1)  /* Fan 2 mode select */
+#define LM80_FAN1_PRM_CTL      (3<<2)  /* Fan 1 speed control */
+#define LM80_FAN2_PRM_CTL      (3<<4)  /* Fan 2 speed control */
+#define LM80_FAN_OS_ENA                (1<<6)  /* enable OS mode on RST_OUT#/OS# pins*/
+#define LM80_FAN_RST_ENA       (1<<7)  /* sets RST_OUT#/OS# pins in RST mode */
+
+/*     LM80_TEMP_CTRL          OS# Config, Temp Res. Reg */
+#define        LM80_TEMP_OS_STAT       (1<<0)  /* mirrors the state of RST_OUT#/OS# */
+#define LM80_TEMP_OS_POL       (1<<1)  /* select OS# polarity */
+#define LM80_TEMP_OS_MODE      (1<<2)  /* selects Interrupt mode */
+#define LM80_TEMP_RES          (1<<3)  /* selects 9 or 11 bit temp resulution*/
+#define LM80_TEMP_LSB          (0xf<<4)/* 4 LSBs of 11 bit temp data */
+#define LM80_TEMP_LSB_9                (1<<7)  /* LSB of 9 bit temperature data */
+
+       /* 0x07 - 0x1f reserved */
+/*     LM80_VT0_IN             current Voltage 0 value */
+/*     LM80_VT1_IN             current Voltage 1 value */
+/*     LM80_VT2_IN             current Voltage 2 value */
+/*     LM80_VT3_IN             current Voltage 3 value */
+/*     LM80_VT4_IN             current Voltage 4 value */
+/*     LM80_VT5_IN             current Voltage 5 value */
+/*     LM80_VT6_IN             current Voltage 6 value */
+/*     LM80_TEMP_IN            current temperature value */
+/*     LM80_FAN1_IN            current Fan 1 count */
+/*     LM80_FAN2_IN            current Fan 2 count */
+/*     LM80_VT0_HIGH_LIM       high limit val for Voltage 0 */
+/*     LM80_VT0_LOW_LIM        low limit val for Voltage 0 */
+/*     LM80_VT1_HIGH_LIM       high limit val for Voltage 1 */
+/*     LM80_VT1_LOW_LIM        low limit val for Voltage 1 */
+/*     LM80_VT2_HIGH_LIM       high limit val for Voltage 2 */
+/*     LM80_VT2_LOW_LIM        low limit val for Voltage 2 */
+/*     LM80_VT3_HIGH_LIM       high limit val for Voltage 3 */
+/*     LM80_VT3_LOW_LIM        low limit val for Voltage 3 */
+/*     LM80_VT4_HIGH_LIM       high limit val for Voltage 4 */
+/*     LM80_VT4_LOW_LIM        low limit val for Voltage 4 */
+/*     LM80_VT5_HIGH_LIM       high limit val for Voltage 5 */
+/*     LM80_VT5_LOW_LIM        low limit val for Voltage 5 */
+/*     LM80_VT6_HIGH_LIM       high limit val for Voltage 6 */
+/*     LM80_VT6_LOW_LIM        low limit val for Voltage 6 */
+/*     LM80_THOT_LIM_UP        hot temperature limit (high) */
+/*     LM80_THOT_LIM_LO        hot temperature limit (low) */
+/*     LM80_TOS_LIM_UP         OS temperature limit (high) */
+/*     LM80_TOS_LIM_LO         OS temperature limit (low) */
+/*     LM80_FAN1_COUNT_LIM     Fan 1 count limit (high) */
+/*     LM80_FAN2_COUNT_LIM     Fan 2 count limit (low) */
+       /* 0x3e - 0x3f reserved */
+
+#define LM80_ADDR              0x28    /* LM80 default addr */
+
+/* typedefs *******************************************************************/
+
+
+/* function prototypes ********************************************************/
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __INC_LM80_H */
diff --git a/drivers/net/sk98lin/h/skaddr.h b/drivers/net/sk98lin/h/skaddr.h
new file mode 100644 (file)
index 0000000..711f873
--- /dev/null
@@ -0,0 +1,425 @@
+/******************************************************************************
+ *
+ * Name:       skaddr.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.26 $
+ * Date:       $Date: 2002/11/15 07:24:42 $
+ * Purpose:    Header file for Address Management (MC, UC, Prom).
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2001 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skaddr.h,v $
+ *     Revision 1.26  2002/11/15 07:24:42  tschilli
+ *     SK_ADDR_EQUAL macro fixed.
+ *
+ *     Revision 1.25  2002/06/10 13:55:18  tschilli
+ *     Changes for handling YUKON.
+ *     All changes are internally and not visible to the programmer
+ *     using this module.
+ *
+ *     Revision 1.24  2001/01/22 13:41:34  rassmann
+ *     Supporting two nets on dual-port adapters.
+ *
+ *     Revision 1.23  2000/08/10 11:27:50  rassmann
+ *     Editorial changes.
+ *     Preserving 32-bit alignment in structs for the adapter context.
+ *
+ *     Revision 1.22  2000/08/07 11:10:40  rassmann
+ *     Editorial changes.
+ *
+ *     Revision 1.21  2000/05/04 09:39:59  rassmann
+ *     Editorial changes.
+ *     Corrected multicast address hashing.
+ *
+ *     Revision 1.20  1999/11/22 13:46:14  cgoos
+ *     Changed license header to GPL.
+ *     Allowing overwrite for SK_ADDR_EQUAL.
+ *
+ *     Revision 1.19  1999/05/28 10:56:07  rassmann
+ *     Editorial changes.
+ *
+ *     Revision 1.18  1999/04/06 17:22:04  rassmann
+ *     Added private "ActivePort".
+ *
+ *     Revision 1.17  1999/01/14 16:18:19  rassmann
+ *     Corrected multicast initialization.
+ *
+ *     Revision 1.16  1999/01/04 10:30:36  rassmann
+ *     SkAddrOverride only possible after SK_INIT_IO phase.
+ *
+ *     Revision 1.15  1998/12/29 13:13:11  rassmann
+ *     An address override is now preserved in the SK_INIT_IO phase.
+ *     All functions return an int now.
+ *     Extended parameter checking.
+ *
+ *     Revision 1.14  1998/11/24 12:39:45  rassmann
+ *     Reserved multicast entry for BPDU address.
+ *     13 multicast entries left for protocol.
+ *
+ *     Revision 1.13  1998/11/13 17:24:32  rassmann
+ *     Changed return value of SkAddrOverride to int.
+ *
+ *     Revision 1.12  1998/11/13 16:56:19  rassmann
+ *     Added macro SK_ADDR_COMPARE.
+ *     Changed return type of SkAddrOverride to SK_BOOL.
+ *
+ *     Revision 1.11  1998/10/28 18:16:35  rassmann
+ *     Avoiding I/Os before SK_INIT_RUN level.
+ *     Aligning InexactFilter.
+ *
+ *     Revision 1.10  1998/10/22 11:39:10  rassmann
+ *     Corrected signed/unsigned mismatches.
+ *
+ *     Revision 1.9  1998/10/15 15:15:49  rassmann
+ *     Changed Flags Parameters from SK_U8 to int.
+ *     Checked with lint.
+ *
+ *     Revision 1.8  1998/09/24 19:15:12  rassmann
+ *     Code cleanup.
+ *
+ *     Revision 1.7  1998/09/18 20:22:13  rassmann
+ *     Added HW access.
+ *
+ *     Revision 1.6  1998/09/04 19:40:20  rassmann
+ *     Interface enhancements.
+ *
+ *     Revision 1.5  1998/09/04 12:40:57  rassmann
+ *     Interface cleanup.
+ *
+ *     Revision 1.4  1998/09/04 12:14:13  rassmann
+ *     Interface cleanup.
+ *
+ *     Revision 1.3  1998/09/02 16:56:40  rassmann
+ *     Updated interface.
+ *
+ *     Revision 1.2  1998/08/27 14:26:09  rassmann
+ *     Updated interface.
+ *
+ *     Revision 1.1  1998/08/21 08:31:08  rassmann
+ *     First public version.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * This module is intended to manage multicast addresses and promiscuous mode
+ * on GEnesis adapters.
+ *
+ * Include File Hierarchy:
+ *
+ *     "skdrv1st.h"
+ *     ...
+ *     "sktypes.h"
+ *     "skqueue.h"
+ *     "skaddr.h"
+ *     ...
+ *     "skdrv2nd.h"
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKADDR_H
+#define __INC_SKADDR_H
+
+#ifdef __cplusplus
+#error C++ is not yet supported.
+extern "C" {
+#endif /* cplusplus */
+
+/* defines ********************************************************************/
+
+#define SK_MAC_ADDR_LEN                                6       /* Length of MAC address. */
+#define        SK_MAX_ADDRS                            14      /* #Addrs for exact match. */
+
+/* ----- Common return values ----- */
+
+#define SK_ADDR_SUCCESS                                0       /* Function returned successfully. */
+#define SK_ADDR_ILLEGAL_PORT                   100     /* Port number too high. */
+#define SK_ADDR_TOO_EARLY                      101     /* Function called too early. */
+
+/* ----- Clear/Add flag bits ----- */
+
+#define SK_ADDR_PERMANENT                      1       /* RLMT Address */
+
+/* ----- Additional Clear flag bits ----- */
+
+#define SK_MC_SW_ONLY                          2       /* Do not update HW when clearing. */
+
+/* ----- Override flag bits ----- */
+
+#define SK_ADDR_LOGICAL_ADDRESS                0
+#define SK_ADDR_VIRTUAL_ADDRESS                (SK_ADDR_LOGICAL_ADDRESS)       /* old */
+#define SK_ADDR_PHYSICAL_ADDRESS       1
+#define SK_ADDR_CLEAR_LOGICAL          2
+#define SK_ADDR_SET_LOGICAL                    4
+
+/* ----- Override return values ----- */
+
+#define SK_ADDR_OVERRIDE_SUCCESS       (SK_ADDR_SUCCESS)
+#define SK_ADDR_DUPLICATE_ADDRESS      1
+#define SK_ADDR_MULTICAST_ADDRESS      2
+
+/* ----- Partitioning of excact match table ----- */
+
+#define SK_ADDR_EXACT_MATCHES          16      /* #Exact match entries. */
+
+#define SK_ADDR_FIRST_MATCH_RLMT       1
+#define SK_ADDR_LAST_MATCH_RLMT                2
+#define SK_ADDR_FIRST_MATCH_DRV                3
+#define SK_ADDR_LAST_MATCH_DRV         (SK_ADDR_EXACT_MATCHES - 1)
+
+/* ----- SkAddrMcAdd/SkAddrMcUpdate return values ----- */
+
+#define SK_MC_FILTERING_EXACT          0       /* Exact filtering. */
+#define SK_MC_FILTERING_INEXACT                1       /* Inexact filtering. */
+
+/* ----- Additional SkAddrMcAdd return values ----- */
+
+#define SK_MC_ILLEGAL_ADDRESS          2       /* Illegal address. */
+#define SK_MC_ILLEGAL_PORT                     3       /* Illegal port (not the active one). */
+#define SK_MC_RLMT_OVERFLOW                    4       /* Too many RLMT mc addresses. */
+
+/* Promiscuous mode bits ----- */
+
+#define SK_PROM_MODE_NONE                      0       /* Normal receive. */
+#define SK_PROM_MODE_LLC                       1       /* Receive all LLC frames. */
+#define SK_PROM_MODE_ALL_MC                    2       /* Receive all multicast frames. */
+/* #define SK_PROM_MODE_NON_LLC                4 */    /* Receive all non-LLC frames. */
+
+/* Macros */
+
+#if 0
+#ifndef SK_ADDR_EQUAL
+/*
+ * "&" instead of "&&" allows better optimization on IA-64.
+ * The replacement is safe here, as all bytes exist.
+ */
+#ifndef SK_ADDR_DWORD_COMPARE
+#define SK_ADDR_EQUAL(A1,A2)   ( \
+       (((SK_U8 *)(A1))[5] == ((SK_U8 *)(A2))[5]) & \
+       (((SK_U8 *)(A1))[4] == ((SK_U8 *)(A2))[4]) & \
+       (((SK_U8 *)(A1))[3] == ((SK_U8 *)(A2))[3]) & \
+       (((SK_U8 *)(A1))[2] == ((SK_U8 *)(A2))[2]) & \
+       (((SK_U8 *)(A1))[1] == ((SK_U8 *)(A2))[1]) & \
+       (((SK_U8 *)(A1))[0] == ((SK_U8 *)(A2))[0]))
+#else  /* SK_ADDR_DWORD_COMPARE */
+#define SK_ADDR_EQUAL(A1,A2)   ( \
+       (*(SK_U32 *)&(((SK_U8 *)(A1))[2]) == *(SK_U32 *)&(((SK_U8 *)(A2))[2])) & \
+       (*(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0])))
+#endif /* SK_ADDR_DWORD_COMPARE */
+#endif /* SK_ADDR_EQUAL */
+#endif /* 0 */
+
+#ifndef SK_ADDR_EQUAL
+#ifndef SK_ADDR_DWORD_COMPARE
+#define SK_ADDR_EQUAL(A1,A2)   ( \
+       (((SK_U8 *)(A1))[5] == ((SK_U8 *)(A2))[5]) & \
+       (((SK_U8 *)(A1))[4] == ((SK_U8 *)(A2))[4]) & \
+       (((SK_U8 *)(A1))[3] == ((SK_U8 *)(A2))[3]) & \
+       (((SK_U8 *)(A1))[2] == ((SK_U8 *)(A2))[2]) & \
+       (((SK_U8 *)(A1))[1] == ((SK_U8 *)(A2))[1]) & \
+       (((SK_U8 *)(A1))[0] == ((SK_U8 *)(A2))[0]))
+#else  /* SK_ADDR_DWORD_COMPARE */
+#define SK_ADDR_EQUAL(A1,A2)   ( \
+       (*(SK_U16 *)&(((SK_U8 *)(A1))[4]) == *(SK_U16 *)&(((SK_U8 *)(A2))[4])) && \
+       (*(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0])))
+#endif /* SK_ADDR_DWORD_COMPARE */
+#endif /* SK_ADDR_EQUAL */
+
+/* typedefs *******************************************************************/
+
+typedef struct s_MacAddr {
+       SK_U8   a[SK_MAC_ADDR_LEN];
+} SK_MAC_ADDR;
+
+
+/* SK_FILTER is used to ensure alignment of the filter. */
+typedef union s_InexactFilter {
+       SK_U8   Bytes[8];
+       SK_U64  Val;    /* Dummy entry for alignment only. */
+} SK_FILTER64;
+
+
+typedef struct s_AddrNet SK_ADDR_NET;
+
+
+typedef struct s_AddrPort {
+
+/* ----- Public part (read-only) ----- */
+
+       SK_MAC_ADDR     CurrentMacAddress;      /* Current physical MAC Address. */
+       SK_MAC_ADDR     PermanentMacAddress;    /* Permanent physical MAC Address. */
+       int             PromMode;               /* Promiscuous Mode. */
+
+/* ----- Private part ----- */
+
+       SK_MAC_ADDR     PreviousMacAddress;     /* Prev. phys. MAC Address. */
+       SK_BOOL         CurrentMacAddressSet;   /* CurrentMacAddress is set. */
+       SK_U8           Align01;
+
+       SK_U32          FirstExactMatchRlmt;
+       SK_U32          NextExactMatchRlmt;
+       SK_U32          FirstExactMatchDrv;
+       SK_U32          NextExactMatchDrv;
+       SK_MAC_ADDR     Exact[SK_ADDR_EXACT_MATCHES];
+       SK_FILTER64     InexactFilter;                  /* For 64-bit hash register. */
+       SK_FILTER64     InexactRlmtFilter;              /* For 64-bit hash register. */
+       SK_FILTER64     InexactDrvFilter;               /* For 64-bit hash register. */
+} SK_ADDR_PORT;
+
+
+struct s_AddrNet {
+/* ----- Public part (read-only) ----- */
+
+       SK_MAC_ADDR             CurrentMacAddress;      /* Logical MAC Address. */
+       SK_MAC_ADDR             PermanentMacAddress;    /* Logical MAC Address. */
+
+/* ----- Private part ----- */
+
+       SK_U32                  ActivePort;             /* View of module ADDR. */
+       SK_BOOL                 CurrentMacAddressSet;   /* CurrentMacAddress is set. */
+       SK_U8                   Align01;
+       SK_U16                  Align02;
+};
+
+
+typedef struct s_Addr {
+
+/* ----- Public part (read-only) ----- */
+
+       SK_ADDR_NET             Net[SK_MAX_NETS];
+       SK_ADDR_PORT    Port[SK_MAX_MACS];
+
+/* ----- Private part ----- */
+} SK_ADDR;
+
+/* function prototypes ********************************************************/
+
+#ifndef SK_KR_PROTO
+
+/* Functions provided by SkAddr */
+
+/* ANSI/C++ compliant function prototypes */
+
+extern int     SkAddrInit(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int     Level);
+
+extern int     SkAddrMcClear(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       SK_U32  PortNumber,
+       int     Flags);
+
+extern int     SkAddrXmacMcClear(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       SK_U32  PortNumber,
+       int     Flags);
+
+extern int     SkAddrGmacMcClear(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       SK_U32  PortNumber,
+       int     Flags);
+
+extern int     SkAddrMcAdd(
+       SK_AC           *pAC,
+       SK_IOC          IoC,
+       SK_U32          PortNumber,
+       SK_MAC_ADDR     *pMc,
+       int             Flags);
+
+extern int     SkAddrXmacMcAdd(
+       SK_AC           *pAC,
+       SK_IOC          IoC,
+       SK_U32          PortNumber,
+       SK_MAC_ADDR     *pMc,
+       int             Flags);
+
+extern int     SkAddrGmacMcAdd(
+       SK_AC           *pAC,
+       SK_IOC          IoC,
+       SK_U32          PortNumber,
+       SK_MAC_ADDR     *pMc,
+       int             Flags);
+
+extern int     SkAddrMcUpdate(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       SK_U32  PortNumber);
+
+extern int     SkAddrXmacMcUpdate(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       SK_U32  PortNumber);
+
+extern int     SkAddrGmacMcUpdate(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       SK_U32  PortNumber);
+
+extern int     SkAddrOverride(
+       SK_AC           *pAC,
+       SK_IOC          IoC,
+       SK_U32          PortNumber,
+       SK_MAC_ADDR     *pNewAddr,
+       int             Flags);
+
+extern int     SkAddrPromiscuousChange(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       SK_U32  PortNumber,
+       int     NewPromMode);
+
+extern int     SkAddrXmacPromiscuousChange(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       SK_U32  PortNumber,
+       int     NewPromMode);
+
+extern int     SkAddrGmacPromiscuousChange(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       SK_U32  PortNumber,
+       int     NewPromMode);
+
+extern int     SkAddrSwap(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       SK_U32  FromPortNumber,
+       SK_U32  ToPortNumber);
+
+#else  /* defined(SK_KR_PROTO)) */
+
+/* Non-ANSI/C++ compliant function prototypes */
+
+#error KR-style prototypes are not yet provided.
+
+#endif /* defined(SK_KR_PROTO)) */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __INC_SKADDR_H */
diff --git a/drivers/net/sk98lin/h/skcsum.h b/drivers/net/sk98lin/h/skcsum.h
new file mode 100644 (file)
index 0000000..2acae32
--- /dev/null
@@ -0,0 +1,261 @@
+/******************************************************************************
+ *
+ * Name:       skcsum.h
+ * Project:    GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx)
+ * Version:    $Revision: 1.9 $
+ * Date:       $Date: 2001/02/06 11:21:39 $
+ * Purpose:    Store/verify Internet checksum in send/receive packets.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2001 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skcsum.h,v $
+ *     Revision 1.9  2001/02/06 11:21:39  rassmann
+ *     Editorial changes.
+ *
+ *     Revision 1.8  2001/02/06 11:15:36  rassmann
+ *     Supporting two nets on dual-port adapters.
+ *
+ *     Revision 1.7  2000/06/29 13:17:05  rassmann
+ *     Corrected reception of a packet with UDP checksum == 0 (which means there
+ *     is no UDP checksum).
+ *
+ *     Revision 1.6  2000/02/28 12:33:44  cgoos
+ *     Changed C++ style comments to C style.
+ *
+ *     Revision 1.5  2000/02/21 12:10:05  cgoos
+ *     Fixed license comment.
+ *
+ *     Revision 1.4  2000/02/21 11:08:37  cgoos
+ *     Merged changes back into common source.
+ *
+ *     Revision 1.1  1999/07/26 14:47:49  mkarl
+ *     changed from common source to windows specific source
+ *     added return SKCS_STATUS_IP_CSUM_ERROR_UDP and
+ *     SKCS_STATUS_IP_CSUM_ERROR_TCP to pass the NidsTester
+ *     changes for Tx csum offload
+ *
+ *     Revision 1.2  1998/09/04 12:16:34  mhaveman
+ *     Checked in for Stephan to allow compilation.
+ *     -Added definition SK_CSUM_EVENT_CLEAR_PROTO_STATS to clear statistic
+ *     -Added prototype for SkCsEvent()
+ *
+ *     Revision 1.1  1998/09/01 15:36:53  swolf
+ *     initial revision
+ *
+ *     01-Sep-1998 sw  Created.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * Public header file for the "GEnesis" common module "CSUM".
+ *
+ * "GEnesis" is an abbreviation of "Gigabit Ethernet Network System in Silicon"
+ * and is the code name of this SysKonnect project.
+ *
+ * Compilation Options:
+ *
+ *     SK_USE_CSUM - Define if CSUM is to be used. Otherwise, CSUM will be an
+ *     empty module.
+ *
+ *     SKCS_OVERWRITE_PROTO - Define to overwrite the default protocol id
+ *     definitions. In this case, all SKCS_PROTO_xxx definitions must be made
+ *     external.
+ *
+ *     SKCS_OVERWRITE_STATUS - Define to overwrite the default return status
+ *     definitions. In this case, all SKCS_STATUS_xxx definitions must be made
+ *     external.
+ *
+ * Include File Hierarchy:
+ *
+ *     "h/skcsum.h"
+ *      "h/sktypes.h"
+ *      "h/skqueue.h"
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKCSUM_H
+#define __INC_SKCSUM_H
+
+#include "h/sktypes.h"
+#include "h/skqueue.h"
+
+/* defines ********************************************************************/
+
+/*
+ * Define the default bit flags for 'SKCS_PACKET_INFO.ProtocolFlags'  if no user
+ * overwrite.
+ */
+#ifndef SKCS_OVERWRITE_PROTO   /* User overwrite? */
+#define SKCS_PROTO_IP  0x1     /* IP (Internet Protocol version 4) */
+#define SKCS_PROTO_TCP 0x2     /* TCP (Transmission Control Protocol) */
+#define SKCS_PROTO_UDP 0x4     /* UDP (User Datagram Protocol) */
+
+/* Indices for protocol statistics. */
+#define SKCS_PROTO_STATS_IP    0
+#define SKCS_PROTO_STATS_UDP   1
+#define SKCS_PROTO_STATS_TCP   2
+#define SKCS_NUM_PROTOCOLS     3       /* Number of supported protocols. */
+#endif /* !SKCS_OVERWRITE_PROTO */
+
+/*
+ * Define the default SKCS_STATUS type and values if no user overwrite.
+ *
+ *     SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.
+ *     SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.
+ *     SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.
+ *     SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame
+ *     SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).
+ *     SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).
+ *     SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).
+ *     SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).
+ *     SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.
+ *     SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.
+ *     SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum.
+ */
+#ifndef SKCS_OVERWRITE_STATUS  /* User overwrite? */
+#define SKCS_STATUS    int     /* Define status type. */
+
+#define SKCS_STATUS_UNKNOWN_IP_VERSION 1
+#define SKCS_STATUS_IP_CSUM_ERROR              2
+#define SKCS_STATUS_IP_FRAGMENT                        3
+#define SKCS_STATUS_IP_CSUM_OK                 4
+#define SKCS_STATUS_TCP_CSUM_ERROR             5
+#define SKCS_STATUS_UDP_CSUM_ERROR             6
+#define SKCS_STATUS_TCP_CSUM_OK                        7
+#define SKCS_STATUS_UDP_CSUM_OK                        8
+/* needed for Microsoft */
+#define SKCS_STATUS_IP_CSUM_ERROR_UDP  9
+#define SKCS_STATUS_IP_CSUM_ERROR_TCP  10
+/* UDP checksum may be omitted */
+#define SKCS_STATUS_IP_CSUM_OK_NO_UDP  11
+#endif /* !SKCS_OVERWRITE_STATUS */
+
+/* Clear protocol statistics event. */
+#define SK_CSUM_EVENT_CLEAR_PROTO_STATS        1
+
+/*
+ * Add two values in one's complement.
+ *
+ * Note: One of the two input values may be "longer" than 16-bit, but then the
+ * resulting sum may be 17 bits long. In this case, add zero to the result using
+ * SKCS_OC_ADD() again.
+ *
+ *     Result = Value1 + Value2
+ */
+#define SKCS_OC_ADD(Result, Value1, Value2) {                          \
+       unsigned long Sum;                                              \
+                                                                       \
+       Sum = (unsigned long) (Value1) + (unsigned long) (Value2);      \
+       /* Add-in any carry. */                                         \
+       (Result) = (Sum & 0xffff) + (Sum >> 16);                        \
+}
+
+/*
+ * Subtract two values in one's complement.
+ *
+ *     Result = Value1 - Value2
+ */
+#define SKCS_OC_SUB(Result, Value1, Value2)    \
+       SKCS_OC_ADD((Result), (Value1), ~(Value2) & 0xffff)
+
+/* typedefs *******************************************************************/
+
+/*
+ * SKCS_PROTO_STATS - The CSUM protocol statistics structure.
+ *
+ * There is one instance of this structure for each protocol supported.
+ */
+typedef struct s_CsProtocolStatistics {
+       SK_U64 RxOkCts;         /* Receive checksum ok. */
+       SK_U64 RxUnableCts;     /* Unable to verify receive checksum. */
+       SK_U64 RxErrCts;        /* Receive checksum error. */
+       SK_U64 TxOkCts;         /* Transmit checksum ok. */
+       SK_U64 TxUnableCts;     /* Unable to calculate checksum in hw. */
+} SKCS_PROTO_STATS;
+
+/*
+ * s_Csum - The CSUM module context structure.
+ */
+typedef struct s_Csum {
+       /* Enabled receive SK_PROTO_XXX bit flags. */
+       unsigned ReceiveFlags[SK_MAX_NETS];
+#ifdef TX_CSUM
+       unsigned TransmitFlags[SK_MAX_NETS];
+#endif /* TX_CSUM */
+
+       /* The protocol statistics structure; one per supported protocol. */
+       SKCS_PROTO_STATS ProtoStats[SK_MAX_NETS][SKCS_NUM_PROTOCOLS];
+} SK_CSUM;
+
+/*
+ * SKCS_PACKET_INFO - The packet information structure.
+ */
+typedef struct s_CsPacketInfo {
+       /* Bit field specifiying the desired/found protocols. */
+       unsigned ProtocolFlags;
+
+       /* Length of complete IP header, including any option fields. */
+       unsigned IpHeaderLength;
+
+       /* IP header checksum. */
+       unsigned IpHeaderChecksum;
+
+       /* TCP/UDP pseudo header checksum. */
+       unsigned PseudoHeaderChecksum;
+} SKCS_PACKET_INFO;
+
+/* function prototypes ********************************************************/
+
+#ifndef SkCsCalculateChecksum
+extern unsigned SkCsCalculateChecksum(
+       void            *pData,
+       unsigned        Length);
+#endif
+
+extern int SkCsEvent(
+       SK_AC           *pAc,
+       SK_IOC          Ioc,
+       SK_U32          Event,
+       SK_EVPARA       Param);
+
+extern SKCS_STATUS SkCsGetReceiveInfo(
+       SK_AC           *pAc,
+       void            *pIpHeader,
+       unsigned        Checksum1,
+       unsigned        Checksum2,
+       int                     NetNumber);
+
+extern void SkCsGetSendInfo(
+       SK_AC                           *pAc,
+       void                            *pIpHeader,
+       SKCS_PACKET_INFO        *pPacketInfo,
+       int                                     NetNumber);
+
+extern void SkCsSetReceiveFlags(
+       SK_AC           *pAc,
+       unsigned        ReceiveFlags,
+       unsigned        *pChecksum1Offset,
+       unsigned        *pChecksum2Offset,
+       int                     NetNumber);
+
+#endif /* __INC_SKCSUM_H */
diff --git a/drivers/net/sk98lin/h/skdebug.h b/drivers/net/sk98lin/h/skdebug.h
new file mode 100644 (file)
index 0000000..cf5b5ad
--- /dev/null
@@ -0,0 +1,119 @@
+/******************************************************************************
+ *
+ * Name:       skdebug.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.12 $
+ * Date:       $Date: 2002/07/15 15:37:13 $
+ * Purpose:    SK specific DEBUG support
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2002 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *     $Log: skdebug.h,v $
+ *     Revision 1.12  2002/07/15 15:37:13  rschmidt
+ *     Power Management support
+ *     Editorial changes
+ *
+ *     Revision 1.11  2002/04/25 11:04:39  rschmidt
+ *     Editorial changes
+ *
+ *     Revision 1.10  1999/11/22 13:47:40  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.9  1999/09/14 14:02:43  rwahl
+ *     Added SK_DBGMOD_PECP.
+ *
+ *     Revision 1.8  1998/11/25 08:31:54  gklug
+ *     fix: no C++ comments allowed in common sources
+ *
+ *     Revision 1.7  1998/11/24 16:47:24  swolf
+ *     Driver may now define its own SK_DBG_MSG() (eg. in "h/skdrv1st.h").
+ *
+ *     Revision 1.6  1998/10/28 10:23:55  rassmann
+ *     ADDED SK_DBGMOD_ADDR.
+ *
+ *     Revision 1.5  1998/10/22 09:43:55  gklug
+ *     add: CSUM module
+ *
+ *     Revision 1.4  1998/10/01 07:54:44  gklug
+ *     add: PNMI debug module
+ *
+ *     Revision 1.3  1998/09/18 08:32:34  afischer
+ *     Macros changed according ssr-spec.:
+ *             SK_DBG_MODCHK -> SK_DBG_CHKMOD
+ *             SK_DBG_CATCHK -> SK_DBG_CHKCAT
+ *
+ *     Revision 1.2  1998/07/03 14:38:25  malthoff
+ *     Add category SK_DBGCAT_FATAL.
+ *
+ *     Revision 1.1  1998/06/19 13:39:01  malthoff
+ *     created.
+ *
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKDEBUG_H
+#define __INC_SKDEBUG_H
+
+#ifdef DEBUG
+#ifndef SK_DBG_MSG
+#define SK_DBG_MSG(pAC,comp,cat,arg) \
+               if ( ((comp) & SK_DBG_CHKMOD(pAC)) &&   \
+                     ((cat) & SK_DBG_CHKCAT(pAC)) ) {  \
+                       SK_DBG_PRINTF arg ;             \
+               }
+#endif
+#else
+#define SK_DBG_MSG(pAC,comp,lev,arg)
+#endif
+
+/* PLS NOTE:
+ * =========
+ * Due to any restrictions of kernel printf routines do not use other
+ * format identifiers as: %x %d %c %s .
+ * Never use any combined format identifiers such as: %lx %ld in your
+ * printf - argument (arg) because some OS specific kernel printfs may
+ * only support some basic identifiers.
+ */
+
+/* Debug modules */
+
+#define SK_DBGMOD_MERR 0x00000001L     /* general module error indication */
+#define SK_DBGMOD_HWM  0x00000002L     /* Hardware init module */
+#define SK_DBGMOD_RLMT 0x00000004L     /* RLMT module */
+#define SK_DBGMOD_VPD  0x00000008L     /* VPD module */
+#define SK_DBGMOD_I2C  0x00000010L     /* I2C module */
+#define SK_DBGMOD_PNMI 0x00000020L     /* PNMI module */
+#define SK_DBGMOD_CSUM 0x00000040L     /* CSUM module */
+#define SK_DBGMOD_ADDR 0x00000080L     /* ADDR module */
+#define SK_DBGMOD_PECP 0x00000100L     /* PECP module */
+#define SK_DBGMOD_POWM 0x00000200L     /* Power Management module */
+
+/* Debug events */
+
+#define SK_DBGCAT_INIT 0x00000001L     /* module/driver initialization */
+#define SK_DBGCAT_CTRL 0x00000002L     /* controlling devices */
+#define SK_DBGCAT_ERR  0x00000004L     /* error handling paths */
+#define SK_DBGCAT_TX   0x00000008L     /* transmit path */
+#define SK_DBGCAT_RX   0x00000010L     /* receive path */
+#define SK_DBGCAT_IRQ  0x00000020L     /* general IRQ handling */
+#define SK_DBGCAT_QUEUE        0x00000040L     /* any queue management */
+#define SK_DBGCAT_DUMP 0x00000080L     /* large data output e.g. hex dump */
+#define SK_DBGCAT_FATAL        0x00000100L     /* fatal error */
+
+#endif /* __INC_SKDEBUG_H */
diff --git a/drivers/net/sk98lin/h/skdrv1st.h b/drivers/net/sk98lin/h/skdrv1st.h
new file mode 100644 (file)
index 0000000..af34d7b
--- /dev/null
@@ -0,0 +1,264 @@
+/******************************************************************************
+ *
+ * Name:       skdrv1st.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.11 $
+ * Date:       $Date: 2003/02/25 14:16:40 $
+ * Purpose:    First header file for driver and all other modules
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2003 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skdrv1st.h,v $
+ *     Revision 1.11  2003/02/25 14:16:40  mlindner
+ *     Fix: Copyright statement
+ *
+ *     Revision 1.10  2002/10/02 12:46:02  mlindner
+ *     Add: Support for Yukon
+ *
+ *     Revision 1.9.2.2  2001/12/07 12:06:42  mlindner
+ *     Fix: malloc -> slab changes
+ *
+ *     Revision 1.9.2.1  2001/03/12 16:50:59  mlindner
+ *     chg: kernel 2.4 adaption
+ *
+ *     Revision 1.9  2001/01/22 14:16:04  mlindner
+ *     added ProcFs functionality
+ *     Dual Net functionality integrated
+ *     Rlmt networks added
+ *
+ *     Revision 1.8  2000/02/21 12:19:18  cgoos
+ *     Added default for SK_DEBUG_CHKMOD/_CHKCAT
+ *
+ *     Revision 1.7  1999/11/22 13:50:00  cgoos
+ *     Changed license header to GPL.
+ *     Added overwrite for several functions.
+ *     Removed linux 2.0.x definitions.
+ *     Removed PCI vendor ID definition (now in kernel).
+ *
+ *     Revision 1.6  1999/07/27 08:03:33  cgoos
+ *     Changed SK_IN/OUT macros to readX/writeX instead of memory
+ *     accesses (necessary for ALPHA).
+ *
+ *     Revision 1.5  1999/07/23 12:10:21  cgoos
+ *     Removed SK_RLMT_SLOW_LOOKAHEAD define.
+ *
+ *     Revision 1.4  1999/07/14 12:31:13  cgoos
+ *     Added SK_RLMT_SLOW_LOOKAHEAD define.
+ *
+ *     Revision 1.3  1999/04/07 10:12:54  cgoos
+ *     Added check for KERNEL and OPTIMIZATION defines.
+ *
+ *     Revision 1.2  1999/03/01 08:51:47  cgoos
+ *     Fixed pcibios_read/write definitions.
+ *
+ *     Revision 1.1  1999/02/16 07:40:49  cgoos
+ *     First version.
+ *
+ *
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * This is the first include file of the driver, which includes all
+ * neccessary system header files and some of the GEnesis header files.
+ * It also defines some basic items.
+ *
+ * Include File Hierarchy:
+ *
+ *     see skge.c
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKDRV1ST_H
+#define __INC_SKDRV1ST_H
+
+#if 0
+/* Check kernel version */
+#include <linux/version.h>
+#if (LINUX_VERSION_CODE > 0x020300)
+#endif
+#endif
+
+typedef struct s_AC    SK_AC;
+
+/* override some default functions with optimized linux functions */
+
+#define SK_PNMI_STORE_U16(p,v)         memcpy((char*)(p),(char*)&(v),2)
+#define SK_PNMI_STORE_U32(p,v)         memcpy((char*)(p),(char*)&(v),4)
+#define SK_PNMI_STORE_U64(p,v)         memcpy((char*)(p),(char*)&(v),8)
+#define SK_PNMI_READ_U16(p,v)          memcpy((char*)&(v),(char*)(p),2)
+#define SK_PNMI_READ_U32(p,v)          memcpy((char*)&(v),(char*)(p),2)
+#define SK_PNMI_READ_U64(p,v)          memcpy((char*)&(v),(char*)(p),2)
+
+#define SkCsCalculateChecksum(p,l)     ((~ip_compute_csum(p, l)) & 0xffff)
+
+#define SK_ADDR_EQUAL(a1,a2)           (!memcmp(a1,a2,6))
+
+
+#if !defined(__OPTIMIZE__)  ||  !defined(__KERNEL__)
+#warning  You must compile this file with the correct options!
+#warning  See the last lines of the source file.
+#error You must compile this driver with "-O".
+#endif
+
+#if 0
+#include <linux/version.h>
+#endif
+#include <linux/types.h>
+#if 0
+#include <linux/kernel.h>
+#endif
+#include <linux/string.h>
+#if 0
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#endif
+#include <asm/byteorder.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#if 0
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <net/checksum.h>
+#endif
+
+#include       "h/sktypes.h"
+#include       "h/skerror.h"
+#include       "h/skdebug.h"
+#include       "h/lm80.h"
+#include       "h/xmac_ii.h"
+
+#include "u-boot_compat.h"
+
+#ifdef __LITTLE_ENDIAN
+#define SK_LITTLE_ENDIAN
+#else
+#define SK_BIG_ENDIAN
+#endif
+
+#if 0
+#define SK_NET_DEVICE  net_device
+#else
+#define SK_NET_DEVICE  eth_device
+#endif
+
+
+/* we use gethrtime(), return unit: nanoseconds */
+#if 0
+#define SK_TICKS_PER_SEC       HZ
+#else
+#define SK_TICKS_PER_SEC       CFG_HZ
+#endif
+
+#define        SK_MEM_MAPPED_IO
+
+/* #define SK_RLMT_SLOW_LOOKAHEAD */
+
+#define SK_MAX_MACS            2
+#define SK_MAX_NETS            2
+
+#define SK_IOC                 char*
+
+typedef struct s_DrvRlmtMbuf SK_MBUF;
+
+#define        SK_CONST64      INT64_C
+#define        SK_CONSTU64     UINT64_C
+
+#define SK_MEMCPY(dest,src,size)       memcpy(dest,src,size)
+#define SK_MEMCMP(s1,s2,size)          memcmp(s1,s2,size)
+#define SK_MEMSET(dest,val,size)       memset(dest,val,size)
+#define SK_STRLEN(pStr)                        strlen((char*)(pStr))
+#define SK_STRNCPY(pDest,pSrc,size)    strncpy((char*)(pDest),(char*)(pSrc),size)
+#define SK_STRCMP(pStr1,pStr2)         strcmp((char*)(pStr1),(char*)(pStr2))
+
+/* macros to access the adapter */
+#define SK_OUT8(b,a,v)         writeb((v), ((b)+(a)))
+#define SK_OUT16(b,a,v)                writew((v), ((b)+(a)))
+#define SK_OUT32(b,a,v)                writel((v), ((b)+(a)))
+#define SK_IN8(b,a,pv)         (*(pv) = readb((b)+(a)))
+#define SK_IN16(b,a,pv)                (*(pv) = readw((b)+(a)))
+#define SK_IN32(b,a,pv)                (*(pv) = readl((b)+(a)))
+
+#define int8_t         char
+#define int16_t                short
+#define int32_t                long
+#define int64_t                long long
+#define uint8_t                u_char
+#define uint16_t       u_short
+#define uint32_t       u_long
+#define uint64_t       unsigned long long
+#define t_scalar_t     int
+#define t_uscalar_t    unsigned int
+#define uintptr_t      unsigned long
+
+#define __CONCAT__(A,B) A##B
+
+#define INT32_C(a)             __CONCAT__(a,L)
+#define INT64_C(a)             __CONCAT__(a,LL)
+#define UINT32_C(a)            __CONCAT__(a,UL)
+#define UINT64_C(a)            __CONCAT__(a,ULL)
+
+#ifdef DEBUG
+#define SK_DBG_PRINTF          printk
+#ifndef SK_DEBUG_CHKMOD
+#define SK_DEBUG_CHKMOD                0
+#endif
+#ifndef SK_DEBUG_CHKCAT
+#define SK_DEBUG_CHKCAT                0
+#endif
+/* those come from the makefile */
+#define SK_DBG_CHKMOD(pAC)     (SK_DEBUG_CHKMOD)
+#define SK_DBG_CHKCAT(pAC)     (SK_DEBUG_CHKCAT)
+
+extern void SkDbgPrintf(const char *format,...);
+
+#define SK_DBGMOD_DRV                  0x00010000
+
+/**** possible driver debug categories ********************************/
+#define SK_DBGCAT_DRV_ENTRY            0x00010000
+#define SK_DBGCAT_DRV_SAP              0x00020000
+#define SK_DBGCAT_DRV_MCA              0x00040000
+#define SK_DBGCAT_DRV_TX_PROGRESS      0x00080000
+#define SK_DBGCAT_DRV_RX_PROGRESS      0x00100000
+#define SK_DBGCAT_DRV_PROGRESS         0x00200000
+#define SK_DBGCAT_DRV_MSG              0x00400000
+#define SK_DBGCAT_DRV_PROM             0x00800000
+#define SK_DBGCAT_DRV_TX_FRAME         0x01000000
+#define SK_DBGCAT_DRV_ERROR            0x02000000
+#define SK_DBGCAT_DRV_INT_SRC          0x04000000
+#define SK_DBGCAT_DRV_EVENT            0x08000000
+
+#endif
+
+#define SK_ERR_LOG             SkErrorLog
+
+extern void SkErrorLog(SK_AC*, int, int, char*);
+
+#endif
diff --git a/drivers/net/sk98lin/h/skdrv2nd.h b/drivers/net/sk98lin/h/skdrv2nd.h
new file mode 100644 (file)
index 0000000..a311827
--- /dev/null
@@ -0,0 +1,561 @@
+/******************************************************************************
+ *
+ * Name:       skdrv2nd.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.15 $
+ * Date:       $Date: 2003/02/25 14:16:40 $
+ * Purpose:    Second header file for driver and all other modules
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2003 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skdrv2nd.h,v $
+ *     Revision 1.15  2003/02/25 14:16:40  mlindner
+ *     Fix: Copyright statement
+ *
+ *     Revision 1.14  2003/02/25 13:26:26  mlindner
+ *     Add: Support for various vendors
+ *
+ *     Revision 1.13  2002/10/02 12:46:02  mlindner
+ *     Add: Support for Yukon
+ *
+ *     Revision 1.12.2.2  2001/09/05 12:14:50  mlindner
+ *     add: New hardware revision int
+ *
+ *     Revision 1.12.2.1  2001/03/12 16:50:59  mlindner
+ *     chg: kernel 2.4 adaption
+ *
+ *     Revision 1.12  2001/03/01 12:52:15  mlindner
+ *     Fixed ring size
+ *
+ *     Revision 1.11  2001/02/19 13:28:02  mlindner
+ *     Changed PNMI parameter values
+ *
+ *     Revision 1.10  2001/01/22 14:16:04  mlindner
+ *     added ProcFs functionality
+ *     Dual Net functionality integrated
+ *     Rlmt networks added
+ *
+ *     Revision 1.1  2000/10/05 19:46:50  phargrov
+ *     Add directory src/vipk_devs_nonlbl/vipk_sk98lin/
+ *     This is the SysKonnect SK-98xx Gigabit Ethernet driver,
+ *     contributed by SysKonnect.
+ *
+ *     Revision 1.9  2000/02/21 10:39:55  cgoos
+ *     Added flag for jumbo support usage.
+ *
+ *     Revision 1.8  1999/11/22 13:50:44  cgoos
+ *     Changed license header to GPL.
+ *     Fixed two comments.
+ *
+ *     Revision 1.7  1999/09/28 12:38:21  cgoos
+ *     Added CheckQueue to SK_AC.
+ *
+ *     Revision 1.6  1999/07/27 08:04:05  cgoos
+ *     Added checksumming variables to SK_AC.
+ *
+ *     Revision 1.5  1999/03/29 12:33:26  cgoos
+ *     Rreversed to fine lock granularity.
+ *
+ *     Revision 1.4  1999/03/15 12:14:02  cgoos
+ *     Added DriverLock to SK_AC.
+ *     Removed other locks.
+ *
+ *     Revision 1.3  1999/03/01 08:52:27  cgoos
+ *     Changed pAC->PciDev declaration.
+ *
+ *     Revision 1.2  1999/02/18 10:57:14  cgoos
+ *     Removed SkDrvTimeStamp prototype.
+ *     Fixed SkGeOsGetTime prototype.
+ *
+ *     Revision 1.1  1999/02/16 07:41:01  cgoos
+ *     First version.
+ *
+ *
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * This is the second include file of the driver, which includes all other
+ * neccessary files and defines all structures and constants used by the
+ * driver and the common modules.
+ *
+ * Include File Hierarchy:
+ *
+ *     see skge.c
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKDRV2ND_H
+#define __INC_SKDRV2ND_H
+
+#include "h/skqueue.h"
+#include "h/skgehwt.h"
+#include "h/sktimer.h"
+#include "h/ski2c.h"
+#include "h/skgepnmi.h"
+#include "h/skvpd.h"
+#include "h/skgehw.h"
+#include "h/skgeinit.h"
+#include "h/skaddr.h"
+#include "h/skgesirq.h"
+#include "h/skcsum.h"
+#include "h/skrlmt.h"
+#include "h/skgedrv.h"
+
+#define SK_PCI_ISCOMPLIANT(result, pdev) {     \
+    result = SK_FALSE; /* default */     \
+    /* 3Com (0x10b7) */     \
+    if (pdev->vendor == 0x10b7) {     \
+       /* Gigabit Ethernet Adapter (0x1700) */     \
+       if ((pdev->device == 0x1700)) { \
+           result = SK_TRUE;     \
+       }     \
+    /* SysKonnect (0x1148) */     \
+    } else if (pdev->vendor == 0x1148) {     \
+       /* SK-98xx Gigabit Ethernet Server Adapter (0x4300) */     \
+       /* SK-98xx V2 Gigabit Ethernet Adapter (0x4320) */     \
+       if ((pdev->device == 0x4300) || \
+           (pdev->device == 0x4320)) { \
+           result = SK_TRUE;     \
+       }     \
+    /* D-Link (0x1186) */     \
+    } else if (pdev->vendor == 0x1186) {     \
+       /* Gigabit Ethernet Adapter (0x4c00) */     \
+       if ((pdev->device == 0x4c00)) { \
+           result = SK_TRUE;     \
+       }     \
+    /* CNet (0x1371) */     \
+    } else if (pdev->vendor == 0x1371) {     \
+       /* GigaCard Network Adapter (0x434e) */     \
+       if ((pdev->device == 0x434e)) { \
+           result = SK_TRUE;     \
+       }     \
+    /* Linksys (0x1737) */     \
+    } else if (pdev->vendor == 0x1737) {     \
+       /* Gigabit Network Adapter (0x1032) */     \
+       /* Gigabit Network Adapter (0x1064) */     \
+       if ((pdev->device == 0x1032) || \
+           (pdev->device == 0x1064)) { \
+           result = SK_TRUE;     \
+       }     \
+    } else {     \
+       result = SK_FALSE;     \
+    }     \
+}
+
+
+extern SK_MBUF         *SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned);
+extern void            SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*);
+extern SK_U64          SkOsGetTime(SK_AC*);
+extern int             SkPciReadCfgDWord(SK_AC*, int, SK_U32*);
+extern int             SkPciReadCfgWord(SK_AC*, int, SK_U16*);
+extern int             SkPciReadCfgByte(SK_AC*, int, SK_U8*);
+extern int             SkPciWriteCfgDWord(SK_AC*, int, SK_U32);
+extern int             SkPciWriteCfgWord(SK_AC*, int, SK_U16);
+extern int             SkPciWriteCfgByte(SK_AC*, int, SK_U8);
+extern int             SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
+
+struct s_DrvRlmtMbuf {
+       SK_MBUF         *pNext;         /* Pointer to next RLMT Mbuf. */
+       SK_U8           *pData;         /* Data buffer (virtually contig.). */
+       unsigned        Size;           /* Data buffer size. */
+       unsigned        Length;         /* Length of packet (<= Size). */
+       SK_U32          PortIdx;        /* Receiving/transmitting port. */
+#ifdef SK_RLMT_MBUF_PRIVATE
+       SK_RLMT_MBUF    Rlmt;           /* Private part for RLMT. */
+#endif  /* SK_RLMT_MBUF_PRIVATE */
+       struct sk_buff  *pOs;           /* Pointer to message block */
+};
+
+
+/*
+ * ioctl definitions
+ */
+#define                SK_IOCTL_BASE           (SIOCDEVPRIVATE)
+#define                SK_IOCTL_GETMIB         (SK_IOCTL_BASE + 0)
+#define                SK_IOCTL_SETMIB         (SK_IOCTL_BASE + 1)
+#define                SK_IOCTL_PRESETMIB      (SK_IOCTL_BASE + 2)
+
+typedef struct s_IOCTL SK_GE_IOCTL;
+
+struct s_IOCTL {
+       char*           pData;
+       unsigned int    Len;
+};
+
+
+/*
+ * define sizes of descriptor rings in bytes
+ */
+
+#if 0
+#define                TX_RING_SIZE    (8*1024)
+#define                RX_RING_SIZE    (24*1024)
+#else
+#define                TX_RING_SIZE    (10 * 40)
+#define                RX_RING_SIZE    (10 * 40)
+#endif
+
+/*
+ * Buffer size for ethernet packets
+ */
+#define        ETH_BUF_SIZE    1540
+#define        ETH_MAX_MTU     1514
+#define ETH_MIN_MTU    60
+#define ETH_MULTICAST_BIT      0x01
+#define SK_JUMBO_MTU   9000
+
+/*
+ * transmit priority selects the queue: LOW=asynchron, HIGH=synchron
+ */
+#define TX_PRIO_LOW    0
+#define TX_PRIO_HIGH   1
+
+/*
+ * alignment of rx/tx descriptors
+ */
+#define DESCR_ALIGN    8
+
+/*
+ * definitions for pnmi. TODO
+ */
+#define SK_DRIVER_RESET(pAC, IoC)      0
+#define SK_DRIVER_SENDEVENT(pAC, IoC)  0
+#define SK_DRIVER_SELFTEST(pAC, IoC)   0
+/* For get mtu you must add an own function */
+#define SK_DRIVER_GET_MTU(pAc,IoC,i)   0
+#define SK_DRIVER_SET_MTU(pAc,IoC,i,v) 0
+#define SK_DRIVER_PRESET_MTU(pAc,IoC,i,v)      0
+
+
+/* TX and RX descriptors *****************************************************/
+
+typedef struct s_RxD RXD; /* the receive descriptor */
+
+struct s_RxD {
+       volatile SK_U32 RBControl;      /* Receive Buffer Control */
+       SK_U32          VNextRxd;       /* Next receive descriptor,low dword */
+       SK_U32          VDataLow;       /* Receive buffer Addr, low dword */
+       SK_U32          VDataHigh;      /* Receive buffer Addr, high dword */
+       SK_U32          FrameStat;      /* Receive Frame Status word */
+       SK_U32          TimeStamp;      /* Time stamp from XMAC */
+       SK_U32          TcpSums;        /* TCP Sum 2 / TCP Sum 1 */
+       SK_U32          TcpSumStarts;   /* TCP Sum Start 2 / TCP Sum Start 1 */
+       RXD             *pNextRxd;      /* Pointer to next Rxd */
+       struct sk_buff  *pMBuf;         /* Pointer to Linux' socket buffer */
+};
+
+typedef struct s_TxD TXD; /* the transmit descriptor */
+
+struct s_TxD {
+       volatile SK_U32 TBControl;      /* Transmit Buffer Control */
+       SK_U32          VNextTxd;       /* Next transmit descriptor,low dword */
+       SK_U32          VDataLow;       /* Transmit Buffer Addr, low dword */
+       SK_U32          VDataHigh;      /* Transmit Buffer Addr, high dword */
+       SK_U32          FrameStat;      /* Transmit Frame Status Word */
+       SK_U32          TcpSumOfs;      /* Reserved / TCP Sum Offset */
+       SK_U16          TcpSumSt;       /* TCP Sum Start */
+       SK_U16          TcpSumWr;       /* TCP Sum Write */
+       SK_U32          TcpReserved;    /* not used */
+       TXD             *pNextTxd;      /* Pointer to next Txd */
+       struct sk_buff  *pMBuf;         /* Pointer to Linux' socket buffer */
+};
+
+
+/* definition of flags in descriptor control field */
+#define        RX_CTRL_OWN_BMU         UINT32_C(0x80000000)
+#define        RX_CTRL_STF             UINT32_C(0x40000000)
+#define        RX_CTRL_EOF             UINT32_C(0x20000000)
+#define        RX_CTRL_EOB_IRQ         UINT32_C(0x10000000)
+#define        RX_CTRL_EOF_IRQ         UINT32_C(0x08000000)
+#define RX_CTRL_DEV_NULL       UINT32_C(0x04000000)
+#define RX_CTRL_STAT_VALID     UINT32_C(0x02000000)
+#define RX_CTRL_TIME_VALID     UINT32_C(0x01000000)
+#define RX_CTRL_CHECK_DEFAULT  UINT32_C(0x00550000)
+#define RX_CTRL_CHECK_CSUM     UINT32_C(0x00560000)
+#define        RX_CTRL_LEN_MASK        UINT32_C(0x0000FFFF)
+
+#define        TX_CTRL_OWN_BMU         UINT32_C(0x80000000)
+#define        TX_CTRL_STF             UINT32_C(0x40000000)
+#define        TX_CTRL_EOF             UINT32_C(0x20000000)
+#define        TX_CTRL_EOB_IRQ         UINT32_C(0x10000000)
+#define        TX_CTRL_EOF_IRQ         UINT32_C(0x08000000)
+#define TX_CTRL_ST_FWD         UINT32_C(0x04000000)
+#define TX_CTRL_DISAB_CRC      UINT32_C(0x02000000)
+#define TX_CTRL_SOFTWARE       UINT32_C(0x01000000)
+#define TX_CTRL_CHECK_DEFAULT  UINT32_C(0x00550000)
+#define TX_CTRL_CHECK_CSUM     UINT32_C(0x00560000)
+#define        TX_CTRL_LEN_MASK        UINT32_C(0x0000FFFF)
+
+
+/* The offsets of registers in the TX and RX queue control io area ***********/
+
+#define RX_Q_BUF_CTRL_CNT      0x00
+#define RX_Q_NEXT_DESCR_LOW    0x04
+#define RX_Q_BUF_ADDR_LOW      0x08
+#define RX_Q_BUF_ADDR_HIGH     0x0c
+#define RX_Q_FRAME_STAT                0x10
+#define RX_Q_TIME_STAMP                0x14
+#define RX_Q_CSUM_1_2          0x18
+#define RX_Q_CSUM_START_1_2    0x1c
+#define RX_Q_CUR_DESCR_LOW     0x20
+#define RX_Q_DESCR_HIGH                0x24
+#define RX_Q_CUR_ADDR_LOW      0x28
+#define RX_Q_CUR_ADDR_HIGH     0x2c
+#define RX_Q_CUR_BYTE_CNT      0x30
+#define RX_Q_CTRL              0x34
+#define RX_Q_FLAG              0x38
+#define RX_Q_TEST1             0x3c
+#define RX_Q_TEST2             0x40
+#define RX_Q_TEST3             0x44
+
+#define TX_Q_BUF_CTRL_CNT      0x00
+#define TX_Q_NEXT_DESCR_LOW    0x04
+#define TX_Q_BUF_ADDR_LOW      0x08
+#define TX_Q_BUF_ADDR_HIGH     0x0c
+#define TX_Q_FRAME_STAT                0x10
+#define TX_Q_CSUM_START                0x14
+#define TX_Q_CSUM_START_POS    0x18
+#define TX_Q_RESERVED          0x1c
+#define TX_Q_CUR_DESCR_LOW     0x20
+#define TX_Q_DESCR_HIGH                0x24
+#define TX_Q_CUR_ADDR_LOW      0x28
+#define TX_Q_CUR_ADDR_HIGH     0x2c
+#define TX_Q_CUR_BYTE_CNT      0x30
+#define TX_Q_CTRL              0x34
+#define TX_Q_FLAG              0x38
+#define TX_Q_TEST1             0x3c
+#define TX_Q_TEST2             0x40
+#define TX_Q_TEST3             0x44
+
+/* definition of flags in the queue control field */
+#define RX_Q_CTRL_POLL_ON      0x00000080
+#define RX_Q_CTRL_POLL_OFF     0x00000040
+#define RX_Q_CTRL_STOP         0x00000020
+#define RX_Q_CTRL_START                0x00000010
+#define RX_Q_CTRL_CLR_I_PAR    0x00000008
+#define RX_Q_CTRL_CLR_I_EOB    0x00000004
+#define RX_Q_CTRL_CLR_I_EOF    0x00000002
+#define RX_Q_CTRL_CLR_I_ERR    0x00000001
+
+#define TX_Q_CTRL_POLL_ON      0x00000080
+#define TX_Q_CTRL_POLL_OFF     0x00000040
+#define TX_Q_CTRL_STOP         0x00000020
+#define TX_Q_CTRL_START                0x00000010
+#define TX_Q_CTRL_CLR_I_EOB    0x00000004
+#define TX_Q_CTRL_CLR_I_EOF    0x00000002
+#define TX_Q_CTRL_CLR_I_ERR    0x00000001
+
+
+/* Interrupt bits in the interrupts source register **************************/
+#define IRQ_HW_ERROR           0x80000000
+#define IRQ_RESERVED           0x40000000
+#define IRQ_PKT_TOUT_RX1       0x20000000
+#define IRQ_PKT_TOUT_RX2       0x10000000
+#define IRQ_PKT_TOUT_TX1       0x08000000
+#define IRQ_PKT_TOUT_TX2       0x04000000
+#define IRQ_I2C_READY          0x02000000
+#define IRQ_SW                 0x01000000
+#define IRQ_EXTERNAL_REG       0x00800000
+#define IRQ_TIMER              0x00400000
+#define IRQ_MAC1               0x00200000
+#define IRQ_LINK_SYNC_C_M1     0x00100000
+#define IRQ_MAC2               0x00080000
+#define IRQ_LINK_SYNC_C_M2     0x00040000
+#define IRQ_EOB_RX1            0x00020000
+#define IRQ_EOF_RX1            0x00010000
+#define IRQ_CHK_RX1            0x00008000
+#define IRQ_EOB_RX2            0x00004000
+#define IRQ_EOF_RX2            0x00002000
+#define IRQ_CHK_RX2            0x00001000
+#define IRQ_EOB_SY_TX1         0x00000800
+#define IRQ_EOF_SY_TX1         0x00000400
+#define IRQ_CHK_SY_TX1         0x00000200
+#define IRQ_EOB_AS_TX1         0x00000100
+#define IRQ_EOF_AS_TX1         0x00000080
+#define IRQ_CHK_AS_TX1         0x00000040
+#define IRQ_EOB_SY_TX2         0x00000020
+#define IRQ_EOF_SY_TX2         0x00000010
+#define IRQ_CHK_SY_TX2         0x00000008
+#define IRQ_EOB_AS_TX2         0x00000004
+#define IRQ_EOF_AS_TX2         0x00000002
+#define IRQ_CHK_AS_TX2         0x00000001
+
+#define DRIVER_IRQS    (IRQ_SW | IRQ_EOF_RX1 | IRQ_EOF_RX2 | \
+                       IRQ_EOF_SY_TX1 | IRQ_EOF_AS_TX1 | \
+                       IRQ_EOF_SY_TX2 | IRQ_EOF_AS_TX2)
+
+#define SPECIAL_IRQS   (IRQ_HW_ERROR | IRQ_PKT_TOUT_RX1 | IRQ_PKT_TOUT_RX2 | \
+                       IRQ_PKT_TOUT_TX1 | IRQ_PKT_TOUT_TX2 | \
+                       IRQ_I2C_READY | IRQ_EXTERNAL_REG | IRQ_TIMER | \
+                       IRQ_MAC1 | IRQ_LINK_SYNC_C_M1 | \
+                       IRQ_MAC2 | IRQ_LINK_SYNC_C_M2 | \
+                       IRQ_CHK_RX1 | IRQ_CHK_RX2 | \
+                       IRQ_CHK_SY_TX1 | IRQ_CHK_AS_TX1 | \
+                       IRQ_CHK_SY_TX2 | IRQ_CHK_AS_TX2)
+
+#define IRQ_MASK       (IRQ_SW | IRQ_EOB_RX1 | IRQ_EOF_RX1 | \
+                       IRQ_EOB_RX2 | IRQ_EOF_RX2 | \
+                       IRQ_EOB_SY_TX1 | IRQ_EOF_SY_TX1 | \
+                       IRQ_EOB_AS_TX1 | IRQ_EOF_AS_TX1 | \
+                       IRQ_EOB_SY_TX2 | IRQ_EOF_SY_TX2 | \
+                       IRQ_EOB_AS_TX2 | IRQ_EOF_AS_TX2 | \
+                       IRQ_HW_ERROR | IRQ_PKT_TOUT_RX1 | IRQ_PKT_TOUT_RX2 | \
+                       IRQ_PKT_TOUT_TX1 | IRQ_PKT_TOUT_TX2 | \
+                       IRQ_I2C_READY | IRQ_EXTERNAL_REG | IRQ_TIMER | \
+                       IRQ_MAC1 | \
+                       IRQ_MAC2 | \
+                       IRQ_CHK_RX1 | IRQ_CHK_RX2 | \
+                       IRQ_CHK_SY_TX1 | IRQ_CHK_AS_TX1 | \
+                       IRQ_CHK_SY_TX2 | IRQ_CHK_AS_TX2)
+
+#define IRQ_HWE_MASK   0x00000FFF /* enable all HW irqs */
+
+typedef struct s_DevNet DEV_NET;
+
+struct s_DevNet {
+       int             PortNr;
+       int             NetNr;
+       int             Mtu;
+       int             Up;
+       SK_AC   *pAC;
+};
+
+typedef struct s_TxPort                TX_PORT;
+
+struct s_TxPort {
+       /* the transmit descriptor rings */
+       caddr_t         pTxDescrRing;   /* descriptor area memory */
+       SK_U64          VTxDescrRing;   /* descr. area bus virt. addr. */
+       TXD             *pTxdRingHead;  /* Head of Tx rings */
+       TXD             *pTxdRingTail;  /* Tail of Tx rings */
+       TXD             *pTxdRingPrev;  /* descriptor sent previously */
+       int             TxdRingFree;    /* # of free entrys */
+#if 0
+       spinlock_t      TxDesRingLock;  /* serialize descriptor accesses */
+#endif
+       caddr_t         HwAddr;         /* bmu registers address */
+       int             PortIndex;      /* index number of port (0 or 1) */
+};
+
+typedef struct s_RxPort                RX_PORT;
+
+struct s_RxPort {
+       /* the receive descriptor rings */
+       caddr_t         pRxDescrRing;   /* descriptor area memory */
+       SK_U64          VRxDescrRing;   /* descr. area bus virt. addr. */
+       RXD             *pRxdRingHead;  /* Head of Rx rings */
+       RXD             *pRxdRingTail;  /* Tail of Rx rings */
+       RXD             *pRxdRingPrev;  /* descriptor given to BMU previously */
+       int             RxdRingFree;    /* # of free entrys */
+#if 0
+       spinlock_t      RxDesRingLock;  /* serialize descriptor accesses */
+#endif
+       int             RxFillLimit;    /* limit for buffers in ring */
+       caddr_t         HwAddr;         /* bmu registers address */
+       int             PortIndex;      /* index number of port (0 or 1) */
+};
+
+typedef struct s_PerStrm       PER_STRM;
+
+#define SK_ALLOC_IRQ   0x00000001
+
+/****************************************************************************
+ * Per board structure / Adapter Context structure:
+ *     Allocated within attach(9e) and freed within detach(9e).
+ *     Contains all 'per device' necessary handles, flags, locks etc.:
+ */
+struct s_AC  {
+       SK_GEINIT       GIni;           /* GE init struct */
+       SK_PNMI         Pnmi;           /* PNMI data struct */
+       SK_VPD          vpd;            /* vpd data struct */
+       SK_QUEUE        Event;          /* Event queue */
+       SK_HWT          Hwt;            /* Hardware Timer control struct */
+       SK_TIMCTRL      Tim;            /* Software Timer control struct */
+       SK_I2C          I2c;            /* I2C relevant data structure */
+       SK_ADDR         Addr;           /* for Address module */
+       SK_CSUM         Csum;           /* for checksum module */
+       SK_RLMT         Rlmt;           /* for rlmt module */
+#if 0
+       spinlock_t      SlowPathLock;   /* Normal IRQ lock */
+#endif
+       SK_PNMI_STRUCT_DATA PnmiStruct; /* structure to get all Pnmi-Data */
+       int                     RlmtMode;       /* link check mode to set */
+       int                     RlmtNets;       /* Number of nets */
+
+       SK_IOC          IoBase;         /* register set of adapter */
+       int             BoardLevel;     /* level of active hw init (0-2) */
+       char            DeviceStr[80];  /* adapter string from vpd */
+       SK_U32          AllocFlag;      /* flag allocation of resources */
+#if 0
+       struct pci_dev  *PciDev;        /* for access to pci config space */
+       SK_U32          PciDevId;       /* pci device id */
+#else
+       int             PciDev;
+#endif
+       struct SK_NET_DEVICE    *dev[2];        /* pointer to device struct */
+       char            Name[30];       /* driver name */
+       struct SK_NET_DEVICE    *Next;          /* link all devices (for clearing) */
+       int             RxBufSize;      /* length of receive buffers */
+#if 0
+       struct net_device_stats stats;  /* linux 'netstat -i' statistics */
+#endif
+       int             Index;          /* internal board index number */
+
+       /* adapter RAM sizes for queues of active port */
+       int             RxQueueSize;    /* memory used for receive queue */
+       int             TxSQueueSize;   /* memory used for sync. tx queue */
+       int             TxAQueueSize;   /* memory used for async. tx queue */
+
+       int             PromiscCount;   /* promiscuous mode counter  */
+       int             AllMultiCount;  /* allmulticast mode counter */
+       int             MulticCount;    /* number of different MC    */
+                                       /*  addresses for this board */
+                                       /*  (may be more than HW can)*/
+
+       int             HWRevision;     /* Hardware revision */
+       int             ActivePort;     /* the active XMAC port */
+       int             MaxPorts;               /* number of activated ports */
+       int             TxDescrPerRing; /* # of descriptors per tx ring */
+       int             RxDescrPerRing; /* # of descriptors per rx ring */
+
+       caddr_t         pDescrMem;      /* Pointer to the descriptor area */
+       dma_addr_t      pDescrMemDMA;   /* PCI DMA address of area */
+
+       /* the port structures with descriptor rings */
+       TX_PORT         TxPort[SK_MAX_MACS][2];
+       RX_PORT         RxPort[SK_MAX_MACS];
+
+       unsigned int    CsOfs1;         /* for checksum calculation */
+       unsigned int    CsOfs2;         /* for checksum calculation */
+       SK_U32          CsOfs;          /* for checksum calculation */
+
+       SK_BOOL         CheckQueue;     /* check event queue soon */
+
+       /* Only for tests */
+       int             PortUp;
+       int             PortDown;
+
+};
+
+#endif /* __INC_SKDRV2ND_H */
diff --git a/drivers/net/sk98lin/h/skerror.h b/drivers/net/sk98lin/h/skerror.h
new file mode 100644 (file)
index 0000000..a454d9d
--- /dev/null
@@ -0,0 +1,80 @@
+/******************************************************************************
+ *
+ * Name:       skerror.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.5 $
+ * Date:       $Date: 2002/04/25 11:05:10 $
+ * Purpose:    SK specific Error log support
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2002 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *     $Log: skerror.h,v $
+ *     Revision 1.5  2002/04/25 11:05:10  rschmidt
+ *     Editorial changes
+ *
+ *     Revision 1.4  1999/11/22 13:51:59  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.3  1999/09/14 14:04:42  rwahl
+ *     Added error base SK_ERRBASE_PECP.
+ *     Changed error base for driver.
+ *
+ *     Revision 1.2  1998/08/11 11:15:41  gklug
+ *     chg: comments
+ *
+ *     Revision 1.1  1998/08/11 11:09:38  gklug
+ *     add: error bases
+ *     add: error Classes
+ *     first version
+ *
+ *
+ *
+ ******************************************************************************/
+
+#ifndef _INC_SKERROR_H_
+#define _INC_SKERROR_H_
+
+/*
+ * Define Error Classes
+ */
+#define        SK_ERRCL_OTHER          (0)             /* Other error */
+#define        SK_ERRCL_CONFIG         (1L<<0) /* Configuration error */
+#define        SK_ERRCL_INIT           (1L<<1) /* Initialization error */
+#define        SK_ERRCL_NORES          (1L<<2) /* Out of Resources error */
+#define        SK_ERRCL_SW                     (1L<<3) /* Internal Software error */
+#define        SK_ERRCL_HW                     (1L<<4) /* Hardware Failure */
+#define        SK_ERRCL_COMM           (1L<<5) /* Communication error */
+
+
+/*
+ * Define Error Code Bases
+ */
+#define        SK_ERRBASE_RLMT          100    /* Base Error number for RLMT */
+#define        SK_ERRBASE_HWINIT        200    /* Base Error number for HWInit */
+#define        SK_ERRBASE_VPD           300    /* Base Error number for VPD */
+#define        SK_ERRBASE_PNMI          400    /* Base Error number for PNMI */
+#define        SK_ERRBASE_CSUM          500    /* Base Error number for Checksum */
+#define        SK_ERRBASE_SIRQ          600    /* Base Error number for Special IRQ */
+#define        SK_ERRBASE_I2C           700    /* Base Error number for I2C module */
+#define        SK_ERRBASE_QUEUE         800    /* Base Error number for Scheduler */
+#define        SK_ERRBASE_ADDR          900    /* Base Error number for Address module */
+#define SK_ERRBASE_PECP                1000    /* Base Error number for PECP */
+#define        SK_ERRBASE_DRV          1100    /* Base Error number for Driver */
+
+#endif /* _INC_SKERROR_H_ */
diff --git a/drivers/net/sk98lin/h/skgedrv.h b/drivers/net/sk98lin/h/skgedrv.h
new file mode 100644 (file)
index 0000000..72ba9ce
--- /dev/null
@@ -0,0 +1,72 @@
+/******************************************************************************
+ *
+ * Name:       skgedrv.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.6 $
+ * Date:       $Date: 2002/07/15 15:38:01 $
+ * Purpose:    Interface with the driver
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2002 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skgedrv.h,v $
+ *     Revision 1.6  2002/07/15 15:38:01  rschmidt
+ *     Power Management support
+ *     Editorial changes
+ *
+ *     Revision 1.5  2002/04/25 11:05:47  rschmidt
+ *     Editorial changes
+ *
+ *     Revision 1.4  1999/11/22 13:52:46  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.3  1998/12/01 13:31:39  cgoos
+ *     SWITCH INTERN Event added.
+ *
+ *     Revision 1.2  1998/11/25 08:28:38  gklug
+ *     rmv: PORT SWITCH Event
+ *
+ *     Revision 1.1  1998/09/29 06:14:07  gklug
+ *     add: driver events (initial version)
+ *
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKGEDRV_H_
+#define __INC_SKGEDRV_H_
+
+/* defines ********************************************************************/
+
+/*
+ * Define the driver events.
+ * Usually the events are defined by the destination module.
+ * In case of the driver we put the definition of the events here.
+ */
+#define SK_DRV_PORT_RESET               1      /* The port needs to be reset */
+#define SK_DRV_NET_UP                   2      /* The net is operational */
+#define SK_DRV_NET_DOWN                         3      /* The net is down */
+#define SK_DRV_SWITCH_SOFT              4      /* Ports switch with both links connected */
+#define SK_DRV_SWITCH_HARD              5      /* Port switch due to link failure */
+#define SK_DRV_RLMT_SEND                6      /* Send a RLMT packet */
+#define SK_DRV_ADAP_FAIL                7      /* The whole adapter fails */
+#define SK_DRV_PORT_FAIL                8      /* One port fails */
+#define SK_DRV_SWITCH_INTERN    9      /* Port switch by the driver itself */
+#define SK_DRV_POWER_DOWN              10      /* Power down mode */
+
+#endif /* __INC_SKGEDRV_H_ */
diff --git a/drivers/net/sk98lin/h/skgehw.h b/drivers/net/sk98lin/h/skgehw.h
new file mode 100644 (file)
index 0000000..2c98427
--- /dev/null
@@ -0,0 +1,2336 @@
+/******************************************************************************
+ *
+ * Name:       skgehw.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.49 $
+ * Date:       $Date: 2003/01/28 09:43:49 $
+ * Purpose:    Defines and Macros for the Gigabit Ethernet Adapter Product Family
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2003 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ * $Log: skgehw.h,v $
+ * Revision 1.49  2003/01/28 09:43:49  rschmidt
+ * Added defines for PCI-Spec. 2.3 IRQ
+ * Added defines for CLK_RUN (YUKON-Lite)
+ * Editorial changes
+ *
+ * Revision 1.48  2002/12/05 10:25:11  rschmidt
+ * Added defines for Half Duplex Burst Mode On/Off
+ * Added defines for Rx GMAC FIFO Flush feature
+ * Editorial changes
+ *
+ * Revision 1.47  2002/11/12 17:01:31  rschmidt
+ * Added defines for WOL_CTL_DEFAULT
+ * Editorial changes
+ *
+ * Revision 1.46  2002/10/14 14:47:57  rschmidt
+ * Corrected bit mask for HW self test results
+ * Added defines for WOL Registers
+ * Editorial changes
+ *
+ * Revision 1.45  2002/10/11 09:25:22  mkarl
+ * Added bit mask for HW self test results.
+ *
+ * Revision 1.44  2002/08/16 14:44:36  rschmidt
+ * Added define GPC_HWCFG_GMII_FIB for YUKON Fiber
+ *
+ * Revision 1.43  2002/08/12 13:31:50  rschmidt
+ * Corrected macros for GMAC Address Registers: GM_INADDR(),
+ * GM_OUTADDR(), GM_INHASH, GM_OUTHASH.
+ * Editorial changes
+ *
+ * Revision 1.42  2002/08/08 15:37:56  rschmidt
+ * Added defines for Power Management Capabilities
+ * Editorial changes
+ *
+ * Revision 1.41  2002/07/23 16:02:25  rschmidt
+ * Added macro WOL_REG() to access WOL reg. (HW-Bug in YUKON 1st rev.)
+ *
+ * Revision 1.40  2002/07/15 15:41:37  rschmidt
+ * Added new defines for Power Management Cap. & Control
+ * Editorial changes
+ *
+ * Revision 1.39  2002/06/10 09:37:07  rschmidt
+ * Added macros for the ADDR-Modul
+ *
+ * Revision 1.38  2002/06/05 08:15:19  rschmidt
+ * Added defines for WOL Registers
+ * Editorial changes
+ *
+ * Revision 1.37  2002/04/25 11:39:23  rschmidt
+ * Added new defines for PCI Our Register 1
+ * Added new registers and defines for YUKON (Rx FIFO, Tx FIFO,
+ * Time Stamp Timer, GMAC Control, GPHY Control,Link Control,
+ * GMAC IRQ Source and Mask, Wake-up Frame Pattern Match);
+ * Added new defines for Control/Status (VAUX available)
+ * Added Chip ID for YUKON
+ * Added define for descriptors with UDP ext. for YUKON
+ * Added macros to access the GMAC
+ * Added new Phy Type for Marvell 88E1011S (GPHY)
+ * Editorial changes
+ *
+ * Revision 1.36  2000/11/09 12:32:49  rassmann
+ * Renamed variables.
+ *
+ * Revision 1.35  2000/05/19 10:17:13  cgoos
+ * Added inactivity check in PHY_READ (in DEBUG mode only).
+ *
+ * Revision 1.34  1999/11/22 13:53:40  cgoos
+ * Changed license header to GPL.
+ *
+ * Revision 1.33  1999/08/27 11:17:10  malthoff
+ * It's more savely to put brackets around macro parameters.
+ * Brackets added for PHY_READ and PHY_WRITE.
+ *
+ * Revision 1.32  1999/05/19 07:31:01  cgoos
+ * Changes for 1000Base-T.
+ * Added HWAC_LINK_LED macro.
+ *
+ * Revision 1.31  1999/03/12 13:27:40  malthoff
+ * Remove __STDC__.
+ *
+ * Revision 1.30  1999/02/09 09:28:20  malthoff
+ * Add PCI_ERRBITS.
+ *
+ * Revision 1.29  1999/01/26 08:55:48  malthoff
+ * Bugfix: The 16 bit field relations inside the descriptor are
+ *     endianess dependend if the descriptor reversal feature
+ *     (PCI_REV_DESC bit in PCI_OUR_REG_2) is enabled.
+ *     Drivers which use this feature has to set the define
+ *     SK_USE_REV_DESC.
+ *
+ * Revision 1.28  1998/12/10 11:10:22  malthoff
+ * bug fix: IS_IRQ_STAT and IS_IRQ_MST_ERR has been twisted.
+ *
+ * Revision 1.27  1998/11/13 14:19:21  malthoff
+ * Bug Fix: The bit definition of B3_PA_CTRL has completely
+ * changed from HW Spec v1.3 to v1.5.
+ *
+ * Revision 1.26  1998/11/04 08:31:48  cgoos
+ * Fixed byte ordering in XM_OUTADDR/XM_OUTHASH macros.
+ *
+ * Revision 1.25  1998/11/04 07:16:25  cgoos
+ * Changed byte ordering in XM_INADDR/XM_INHASH again.
+ *
+ * Revision 1.24  1998/11/02 11:08:43  malthoff
+ * RxCtrl and TxCtrl must be volatile.
+ *
+ * Revision 1.23  1998/10/28 13:50:45  malthoff
+ * Fix: Endian support missing in XM_IN/OUT-ADDR/HASH macros.
+ *
+ * Revision 1.22  1998/10/26 08:01:36  malthoff
+ * RX_MFF_CTRL1 is split up into RX_MFF_CTRL1,
+ * RX_MFF_STAT_TO, and RX_MFF_TIST_TO.
+ * TX_MFF_CTRL1 is split up TX_MFF_CTRL1 and TX_MFF_WAF.
+ *
+ * Revision 1.21  1998/10/20 07:43:10  malthoff
+ * Fix: XM_IN/OUT/ADDR/HASH macros:
+ * The pointer must be casted.
+ *
+ * Revision 1.20  1998/10/19 15:53:59  malthoff
+ * Remove ML proto definitions.
+ *
+ * Revision 1.19  1998/10/16 14:40:17  gklug
+ * fix: typo B0_XM_IMSK regs
+ *
+ * Revision 1.18  1998/10/16 09:46:54  malthoff
+ * Remove temp defines for ML diag prototype.
+ * Fix register definition for B0_XM1_PHY_DATA, B0_XM1_PHY_DATA
+ * B0_XM2_PHY_DATA, B0_XM2_PHY_ADDR, B0_XA1_CSR, B0_XS1_CSR,
+ * B0_XS2_CSR, and B0_XA2_CSR.
+ *
+ * Revision 1.17  1998/10/14 06:03:14  cgoos
+ * Changed shifted constant to ULONG.
+ *
+ * Revision 1.16  1998/10/09 07:05:41  malthoff
+ * Rename ALL_PA_ENA_TO to PA_ENA_TO_ALL.
+ *
+ * Revision 1.15  1998/10/05 07:54:23  malthoff
+ * Split up RB_CTRL and it's bit definition into
+ * RB_CTRL, RB_TST1, and RB_TST2.
+ * Rename RB_RX_HTPP to RB_RX_LTPP.
+ * Add ALL_PA_ENA_TO. Modify F_WATER_MARK
+ * according to HW Spec. v1.5.
+ * Add MFF_TX_CTRL_DEF.
+ *
+ * Revision 1.14  1998/09/28 13:31:16  malthoff
+ * bug fix: B2_MAC_3 is 0x110 not 0x114
+ *
+ * Revision 1.13  1998/09/24 14:42:56  malthoff
+ * Split the RX_MFF_TST into RX_MFF_CTRL2,
+ * RX_MFF_TST1, and RX_MFF_TST2.
+ * Rename RX_MFF_CTRL to RX_MFF_CTRL1.
+ * Add BMU bit CSR_SV_IDLE.
+ * Add macros PHY_READ() and PHY_WRITE().
+ * Rename macro SK_ADDR() to SK_HW_ADDR()
+ * because of conflicts with the Address Module.
+ *
+ * Revision 1.12  1998/09/16 07:25:33  malthoff
+ * Change the parameter order in the XM_INxx and XM_OUTxx macros,
+ * to have the IoC as first parameter.
+ *
+ * Revision 1.11  1998/09/03 09:58:41  malthoff
+ * Rework the XM_xxx macros. Use {} instead of () to
+ * be compatible with SK_xxx macros which are defined
+ * with {}.
+ *
+ * Revision 1.10  1998/09/02 11:16:39  malthoff
+ * Temporary modify B2_I2C_SW to make tests with
+ * the GE/ML prototype.
+ *
+ * Revision 1.9  1998/08/19 09:11:49  gklug
+ * fix: struct are removed from c-source (see CCC)
+ * add: typedefs for all structs
+ *
+ * Revision 1.8  1998/08/18 08:27:27  malthoff
+ * Add some temporary workarounds to test GE
+ * sources with the ML.
+ *
+ * Revision 1.7  1998/07/03 14:42:26  malthoff
+ * bug fix: Correct macro XMA().
+ * Add temporary workaround to access the PCI config space over I/O
+ *
+ * Revision 1.6  1998/06/23 11:30:36  malthoff
+ * Remove ';' with ',' in macors.
+ *
+ * Revision 1.5  1998/06/22 14:20:57  malthoff
+ * Add macro SK_ADDR(Base,Addr).
+ *
+ * Revision 1.4  1998/06/19 13:35:43  malthoff
+ * change 'pGec' with 'pAC'
+ *
+ * Revision 1.3  1998/06/17 14:58:16  cvs
+ * Lost keywords reinserted.
+ *
+ * Revision 1.1  1998/06/17 14:16:36  cvs
+ * created
+ *
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKGEHW_H
+#define __INC_SKGEHW_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* defines ********************************************************************/
+
+#define BIT_31         (1UL << 31)
+#define BIT_30         (1L << 30)
+#define BIT_29         (1L << 29)
+#define BIT_28         (1L << 28)
+#define BIT_27         (1L << 27)
+#define BIT_26         (1L << 26)
+#define BIT_25         (1L << 25)
+#define BIT_24         (1L << 24)
+#define BIT_23         (1L << 23)
+#define BIT_22         (1L << 22)
+#define BIT_21         (1L << 21)
+#define BIT_20         (1L << 20)
+#define BIT_19         (1L << 19)
+#define BIT_18         (1L << 18)
+#define BIT_17         (1L << 17)
+#define BIT_16         (1L << 16)
+#define BIT_15         (1L << 15)
+#define BIT_14         (1L << 14)
+#define BIT_13         (1L << 13)
+#define BIT_12         (1L << 12)
+#define BIT_11         (1L << 11)
+#define BIT_10         (1L << 10)
+#define BIT_9          (1L << 9)
+#define BIT_8          (1L << 8)
+#define BIT_7          (1L << 7)
+#define BIT_6          (1L << 6)
+#define BIT_5          (1L << 5)
+#define BIT_4          (1L << 4)
+#define BIT_3          (1L << 3)
+#define BIT_2          (1L << 2)
+#define BIT_1          (1L << 1)
+#define BIT_0          1L
+
+#define BIT_15S                (1U << 15)
+#define BIT_14S                (1 << 14)
+#define BIT_13S                (1 << 13)
+#define BIT_12S                (1 << 12)
+#define BIT_11S                (1 << 11)
+#define BIT_10S                (1 << 10)
+#define BIT_9S         (1 << 9)
+#define BIT_8S         (1 << 8)
+#define BIT_7S                 (1 << 7)
+#define BIT_6S         (1 << 6)
+#define BIT_5S         (1 << 5)
+#define BIT_4S         (1 << 4)
+#define BIT_3S         (1 << 3)
+#define BIT_2S         (1 << 2)
+#define BIT_1S         (1 << 1)
+#define BIT_0S         1
+
+#define SHIFT31(x)     ((x) << 31)
+#define SHIFT30(x)     ((x) << 30)
+#define SHIFT29(x)     ((x) << 29)
+#define SHIFT28(x)     ((x) << 28)
+#define SHIFT27(x)     ((x) << 27)
+#define SHIFT26(x)     ((x) << 26)
+#define SHIFT25(x)     ((x) << 25)
+#define SHIFT24(x)     ((x) << 24)
+#define SHIFT23(x)     ((x) << 23)
+#define SHIFT22(x)     ((x) << 22)
+#define SHIFT21(x)     ((x) << 21)
+#define SHIFT20(x)     ((x) << 20)
+#define SHIFT19(x)     ((x) << 19)
+#define SHIFT18(x)     ((x) << 18)
+#define SHIFT17(x)     ((x) << 17)
+#define SHIFT16(x)     ((x) << 16)
+#define SHIFT15(x)     ((x) << 15)
+#define SHIFT14(x)     ((x) << 14)
+#define SHIFT13(x)     ((x) << 13)
+#define SHIFT12(x)     ((x) << 12)
+#define SHIFT11(x)     ((x) << 11)
+#define SHIFT10(x)     ((x) << 10)
+#define SHIFT9(x)      ((x) << 9)
+#define SHIFT8(x)      ((x) << 8)
+#define SHIFT7(x)      ((x) << 7)
+#define SHIFT6(x)      ((x) << 6)
+#define SHIFT5(x)      ((x) << 5)
+#define SHIFT4(x)      ((x) << 4)
+#define SHIFT3(x)      ((x) << 3)
+#define SHIFT2(x)      ((x) << 2)
+#define SHIFT1(x)      ((x) << 1)
+#define SHIFT0(x)      ((x) << 0)
+
+/*
+ * Configuration Space header
+ * Since this module is used for different OS', those may be
+ * duplicate on some of them (e.g. Linux). But to keep the
+ * common source, we have to live with this...
+ */
+#define PCI_VENDOR_ID  0x00    /* 16 bit       Vendor ID */
+#define PCI_DEVICE_ID  0x02    /* 16 bit       Device ID */
+#define PCI_COMMAND            0x04    /* 16 bit       Command */
+#define PCI_STATUS             0x06    /* 16 bit       Status */
+#define PCI_REV_ID             0x08    /*  8 bit       Revision ID */
+#if 0
+#define PCI_CLASS_CODE 0x09    /* 24 bit       Class Code */
+#endif
+#define PCI_CACHE_LSZ  0x0c    /*  8 bit       Cache Line Size */
+#define PCI_LAT_TIM            0x0d    /*  8 bit       Latency Timer */
+#define PCI_HEADER_T   0x0e    /*  8 bit       Header Type */
+#define PCI_BIST               0x0f    /*  8 bit       Built-in selftest */
+#define PCI_BASE_1ST   0x10    /* 32 bit       1st Base address */
+#define PCI_BASE_2ND   0x14    /* 32 bit       2nd Base address */
+       /* Byte 0x18..0x2b:     reserved */
+#define PCI_SUB_VID            0x2c    /* 16 bit       Subsystem Vendor ID */
+#define PCI_SUB_ID             0x2e    /* 16 bit       Subsystem ID */
+#define PCI_BASE_ROM   0x30    /* 32 bit       Expansion ROM Base Address */
+#define PCI_CAP_PTR            0x34    /*  8 bit       Capabilities Ptr */
+       /* Byte 35..3b: reserved */
+#define PCI_IRQ_LINE   0x3c    /*  8 bit       Interrupt Line */
+#define PCI_IRQ_PIN            0x3d    /*  8 bit       Interrupt Pin */
+#define PCI_MIN_GNT            0x3e    /*  8 bit       Min_Gnt */
+#define PCI_MAX_LAT            0x3f    /*  8 bit       Max_Lat */
+       /* Device Dependent Region */
+#define PCI_OUR_REG_1  0x40    /* 32 bit       Our Register 1 */
+#define PCI_OUR_REG_2  0x44    /* 32 bit       Our Register 2 */
+       /* Power Management Region */
+#define PCI_PM_CAP_ID  0x48    /*  8 bit       Power Management Cap. ID */
+#define PCI_PM_NITEM   0x49    /*  8 bit       Next Item Ptr */
+#define PCI_PM_CAP_REG 0x4a    /* 16 bit       Power Management Capabilities */
+#define PCI_PM_CTL_STS 0x4c    /* 16 bit       Power Manag. Control/Status */
+       /* Byte 0x4e:   reserved */
+#define PCI_PM_DAT_REG 0x4f    /*  8 bit       Power Manag. Data Register */
+       /* VPD Region */
+#define PCI_VPD_CAP_ID 0x50    /*  8 bit       VPD Cap. ID */
+#define PCI_VPD_NITEM  0x51    /*  8 bit       Next Item Ptr */
+#define PCI_VPD_ADR_REG        0x52    /* 16 bit       VPD Address Register */
+#define PCI_VPD_DAT_REG        0x54    /* 32 bit       VPD Data Register */
+       /* Byte 0x58..0xff:     reserved */
+
+/*
+ * I2C Address (PCI Config)
+ *
+ * Note: The temperature and voltage sensors are relocated on a different
+ *      I2C bus.
+ */
+#define I2C_ADDR_VPD   0xA0    /* I2C address for the VPD EEPROM */
+
+/*
+ * Define Bits and Values of the registers
+ */
+/*     PCI_COMMAND     16 bit  Command */
+                                                               /* Bit 15..11:  reserved */
+#define PCI_INT_DIS            BIT_10S         /* Interrupt INTx# disable (PCI 2.3) */
+#define PCI_FBTEN              BIT_9S          /* Fast Back-To-Back enable */
+#define PCI_SERREN             BIT_8S          /* SERR enable */
+#define PCI_ADSTEP             BIT_7S          /* Address Stepping */
+#define PCI_PERREN             BIT_6S          /* Parity Report Response enable */
+#define PCI_VGA_SNOOP  BIT_5S          /* VGA palette snoop */
+#define PCI_MWIEN              BIT_4S          /* Memory write an inv cycl ena */
+#define PCI_SCYCEN             BIT_3S          /* Special Cycle enable */
+#define PCI_BMEN               BIT_2S          /* Bus Master enable */
+#define PCI_MEMEN              BIT_1S          /* Memory Space Access enable */
+#define PCI_IOEN               BIT_0S          /* I/O Space Access enable */
+
+#define PCI_COMMAND_VAL        (PCI_FBTEN | PCI_SERREN | PCI_PERREN | PCI_MWIEN |\
+                                                PCI_BMEN | PCI_MEMEN | PCI_IOEN)
+
+/*     PCI_STATUS      16 bit  Status */
+#define PCI_PERR               BIT_15S         /* Parity Error */
+#define PCI_SERR               BIT_14S         /* Signaled SERR */
+#define PCI_RMABORT            BIT_13S         /* Received Master Abort */
+#define PCI_RTABORT            BIT_12S         /* Received Target Abort */
+                                                               /* Bit 11:      reserved */
+#define PCI_DEVSEL             (3<<9)          /* Bit 10.. 9:  DEVSEL Timing */
+#define PCI_DEV_FAST   (0<<9)          /*              fast */
+#define PCI_DEV_MEDIUM (1<<9)          /*              medium */
+#define PCI_DEV_SLOW   (2<<9)          /*              slow */
+#define PCI_DATAPERR   BIT_8S          /* DATA Parity error detected */
+#define PCI_FB2BCAP            BIT_7S          /* Fast Back-to-Back Capability */
+#define PCI_UDF                        BIT_6S          /* User Defined Features */
+#define PCI_66MHZCAP   BIT_5S          /* 66 MHz PCI bus clock capable */
+#define PCI_NEWCAP             BIT_4S          /* New cap. list implemented */
+#define PCI_INT_STAT   BIT_3S          /* Interrupt INTx# Status (PCI 2.3) */
+                                                               /* Bit  2.. 0:  reserved */
+
+#define PCI_ERRBITS    (PCI_PERR | PCI_SERR | PCI_RMABORT | PCI_RTABORT |\
+                       PCI_DATAPERR)
+
+/*     PCI_CLASS_CODE  24 bit  Class Code */
+/*     Byte 2:         Base Class              (02) */
+/*     Byte 1:         SubClass                (00) */
+/*     Byte 0:         Programming Interface   (00) */
+
+/*     PCI_CACHE_LSZ   8 bit   Cache Line Size */
+/*     Possible values: 0,2,4,8,16,32,64,128   */
+
+/*     PCI_HEADER_T    8 bit   Header Type */
+#define PCI_HD_MF_DEV  BIT_7S  /* 0= single, 1= multi-func dev */
+#define PCI_HD_TYPE            0x7f    /* Bit 6..0:    Header Layout 0= normal */
+
+/*     PCI_BIST        8 bit   Built-in selftest */
+/*     Built-in Self test not supported (optional) */
+
+/*     PCI_BASE_1ST    32 bit  1st Base address */
+#define PCI_MEMSIZE            0x4000L         /* use 16 kB Memory Base */
+#define PCI_MEMBASE_MSK 0xffffc000L    /* Bit 31..14:  Memory Base Address */
+#define PCI_MEMSIZE_MSK 0x00003ff0L    /* Bit 13.. 4:  Memory Size Req. */
+#define PCI_PREFEN             BIT_3           /* Prefetchable */
+#define PCI_MEM_TYP            (3L<<2)         /* Bit  2.. 1:  Memory Type */
+#define PCI_MEM32BIT   (0L<<1)         /* Base addr anywhere in 32 Bit range */
+#define PCI_MEM1M              (1L<<1)         /* Base addr below 1 MegaByte */
+#define PCI_MEM64BIT   (2L<<1)         /* Base addr anywhere in 64 Bit range */
+#define PCI_MEMSPACE   BIT_0           /* Memory Space Indic. */
+
+/*     PCI_BASE_2ND    32 bit  2nd Base address */
+#define PCI_IOBASE             0xffffff00L     /* Bit 31.. 8:  I/O Base address */
+#define PCI_IOSIZE             0x000000fcL     /* Bit  7.. 2:  I/O Size Requirements */
+                                                                       /* Bit  1:      reserved */
+#define PCI_IOSPACE            BIT_0           /* I/O Space Indicator */
+
+/*     PCI_BASE_ROM    32 bit  Expansion ROM Base Address */
+#define PCI_ROMBASE            0xfffe0000L     /* Bit 31..17:  ROM BASE address (1st)*/
+#define PCI_ROMBASZ            (0x1cL<<14)     /* Bit 16..14:  Treat as BASE or SIZE */
+#define PCI_ROMSIZE            (0x38L<<11)     /* Bit 13..11:  ROM Size Requirements */
+                                                                       /* Bit 10.. 1:  reserved */
+#define PCI_ROMEN              BIT_0           /* Address Decode enable */
+
+/* Device Dependent Region */
+/*     PCI_OUR_REG_1           32 bit  Our Register 1 */
+                                                                       /* Bit 31..29:  reserved */
+#define PCI_PHY_COMA   BIT_28          /* Set PHY to Coma Mode */
+#define PCI_EN_CAL             BIT_27          /* Enable  PCI buffer strength calibr. */
+#define PCI_DIS_CAL            BIT_26          /* Disable PCI buffer strength calibr. */
+#define PCI_VIO                        BIT_25          /* PCI I/O Voltage, 0 = 3.3V, 1 = 5V */
+#define PCI_DIS_BOOT   BIT_24          /* Disable BOOT via ROM */
+#define PCI_EN_IO              BIT_23          /* Mapping to I/O space */
+#define PCI_EN_FPROM   BIT_22          /* Enable FLASH mapping to memory */
+                                                                       /*              1 = Map Flash to memory */
+                                                                       /*              0 = Disable addr. dec */
+#define PCI_PAGESIZE   (3L<<20)        /* Bit 21..20:  FLASH Page Size */
+#define PCI_PAGE_16            (0L<<20)        /*              16 k pages      */
+#define PCI_PAGE_32K   (1L<<20)        /*              32 k pages      */
+#define PCI_PAGE_64K   (2L<<20)        /*              64 k pages      */
+#define PCI_PAGE_128K  (3L<<20)        /*              128 k pages     */
+                                                                       /* Bit 19:      reserved        */
+#define PCI_PAGEREG            (7L<<16)        /* Bit 18..16:  Page Register   */
+#define PCI_NOTAR              BIT_15          /* No turnaround cycle */
+#define PCI_FORCE_BE   BIT_14          /* Assert all BEs on MR */
+#define PCI_DIS_MRL            BIT_13          /* Disable Mem Read Line */
+#define PCI_DIS_MRM            BIT_12          /* Disable Mem Read Multiple */
+#define PCI_DIS_MWI            BIT_11          /* Disable Mem Write & Invalidate */
+#define PCI_DISC_CLS   BIT_10          /* Disc: cacheLsz bound */
+#define PCI_BURST_DIS  BIT_9           /* Burst Disable */
+#define PCI_DIS_PCI_CLK        BIT_8           /* Disable PCI clock driving */
+#define PCI_SKEW_DAS   (0xfL<<4)       /* Bit  7.. 4:  Skew Ctrl, DAS Ext */
+#define PCI_SKEW_BASE  0xfL            /* Bit  3.. 0:  Skew Ctrl, Base */
+
+
+/*     PCI_OUR_REG_2           32 bit  Our Register 2 */
+#define PCI_VPD_WR_THR (0xffL<<24)     /* Bit 31..24:  VPD Write Threshold */
+#define PCI_DEV_SEL            (0x7fL<<17)     /* Bit 23..17:  EEPROM Device Select */
+#define PCI_VPD_ROM_SZ (7L<<14)        /* Bit 16..14:  VPD ROM Size    */
+                                                                       /* Bit 13..12:  reserved        */
+#define PCI_PATCH_DIR  (0xfL<<8)       /* Bit 11.. 8:  Ext Patches dir 3..0 */
+#define PCI_PATCH_DIR_3        BIT_11
+#define PCI_PATCH_DIR_2        BIT_10
+#define PCI_PATCH_DIR_1        BIT_9
+#define PCI_PATCH_DIR_0        BIT_8
+#define PCI_EXT_PATCHS (0xfL<<4)       /* Bit  7.. 4:  Extended Patches 3..0 */
+#define PCI_EXT_PATCH_3        BIT_7
+#define PCI_EXT_PATCH_2        BIT_6
+#define PCI_EXT_PATCH_1        BIT_5
+#define PCI_EXT_PATCH_0        BIT_4
+#define PCI_EN_DUMMY_RD        BIT_3           /* Enable Dummy Read */
+#define PCI_REV_DESC   BIT_2           /* Reverse Desc. Bytes */
+                                                                       /* Bit  1:      reserved */
+#define PCI_USEDATA64  BIT_0           /* Use 64Bit Data bus ext */
+
+
+/* Power Management Region */
+/*     PCI_PM_CAP_REG          16 bit  Power Management Capabilities */
+#define PCI_PME_SUP_MSK        (0x1f<<11)      /* Bit 15..11:  PM Event Support Mask */
+#define PCI_PME_D3C_SUP        BIT_15S         /* PME from D3cold Support (if Vaux) */
+#define PCI_PME_D3H_SUP        BIT_14S         /* PME from D3hot Support */
+#define PCI_PME_D2_SUP BIT_13S         /* PME from D2 Support */
+#define PCI_PME_D1_SUP BIT_12S         /* PME from D1 Support */
+#define PCI_PME_D0_SUP BIT_11S         /* PME from D0 Support */
+#define PCI_PM_D2_SUP  BIT_10S         /* D2 Support in 33 MHz mode */
+#define PCI_PM_D1_SUP  BIT_9S          /* D1 Support */
+                                                                       /* Bit  8.. 6:  reserved */
+#define PCI_PM_DSI             BIT_5S          /* Device Specific Initialization */
+#define PCI_PM_APS             BIT_4S          /* Auxialiary Power Source */
+#define PCI_PME_CLOCK  BIT_3S          /* PM Event Clock */
+#define PCI_PM_VER_MSK         7               /* Bit  2.. 0:  PM PCI Spec. version */
+
+/*     PCI_PM_CTL_STS          16 bit  Power Management Control/Status */
+#define PCI_PME_STATUS BIT_15S         /* PME Status (YUKON only) */
+#define PCI_PM_DAT_SCL (3<<13)         /* Bit 14..13:  Data Reg. scaling factor */
+#define PCI_PM_DAT_SEL (0xf<<9)        /* Bit 12.. 9:  PM data selector field */
+#define PCI_PME_EN             BIT_8S          /* Enable PME# generation (YUKON only) */
+                                                                       /* Bit  7.. 2:  reserved */
+#define PCI_PM_STATE_MSK       3               /* Bit  1.. 0:  Power Management State */
+
+#define PCI_PM_STATE_D0                0               /* D0:  Operational (default) */
+#define PCI_PM_STATE_D1                1               /* D1:  (YUKON only) */
+#define PCI_PM_STATE_D2                2               /* D2:  (YUKON only) */
+#define PCI_PM_STATE_D3        3               /* D3:  HOT, Power Down and Reset */
+
+/* VPD Region */
+/*     PCI_VPD_ADR_REG         16 bit  VPD Address Register */
+#define PCI_VPD_FLAG   BIT_15S         /* starts VPD rd/wr cycle */
+#define PCI_VPD_ADR_MSK        0x7fffL         /* Bit 14.. 0:  VPD address mask */
+
+/*     Control Register File (Address Map) */
+
+/*
+ *     Bank 0
+ */
+#define B0_RAP                 0x0000  /*  8 bit       Register Address Port */
+       /* 0x0001 - 0x0003:     reserved */
+#define B0_CTST                        0x0004  /* 16 bit       Control/Status register */
+#define B0_LED                 0x0006  /*  8 Bit       LED register */
+#define B0_POWER_CTRL  0x0007  /*  8 Bit       Power Control reg (YUKON only) */
+#define B0_ISRC                        0x0008  /* 32 bit       Interrupt Source Register */
+#define B0_IMSK                        0x000c  /* 32 bit       Interrupt Mask Register */
+#define B0_HWE_ISRC            0x0010  /* 32 bit       HW Error Interrupt Src Reg */
+#define B0_HWE_IMSK            0x0014  /* 32 bit       HW Error Interrupt Mask Reg */
+#define B0_SP_ISRC             0x0018  /* 32 bit       Special Interrupt Source Reg */
+       /* 0x001c:              reserved */
+
+/* B0 XMAC 1 registers (GENESIS only) */
+#define B0_XM1_IMSK            0x0020  /* 16 bit r/w   XMAC 1 Interrupt Mask Register*/
+       /* 0x0022 - 0x0027:     reserved */
+#define B0_XM1_ISRC            0x0028  /* 16 bit ro    XMAC 1 Interrupt Status Reg */
+       /* 0x002a - 0x002f:     reserved */
+#define B0_XM1_PHY_ADDR 0x0030 /* 16 bit r/w   XMAC 1 PHY Address Register */
+       /* 0x0032 - 0x0033:     reserved */
+#define B0_XM1_PHY_DATA 0x0034 /* 16 bit r/w   XMAC 1 PHY Data Register */
+       /* 0x0036 - 0x003f:     reserved */
+
+/* B0 XMAC 2 registers (GENESIS only) */
+#define B0_XM2_IMSK            0x0040  /* 16 bit r/w   XMAC 2 Interrupt Mask Register*/
+       /* 0x0042 - 0x0047:     reserved */
+#define B0_XM2_ISRC            0x0048  /* 16 bit ro    XMAC 2 Interrupt Status Reg */
+       /* 0x004a - 0x004f:     reserved */
+#define B0_XM2_PHY_ADDR 0x0050 /* 16 bit r/w   XMAC 2 PHY Address Register */
+       /* 0x0052 - 0x0053:     reserved */
+#define B0_XM2_PHY_DATA 0x0054 /* 16 bit r/w   XMAC 2 PHY Data Register */
+       /* 0x0056 - 0x005f:     reserved */
+
+/* BMU Control Status Registers */
+#define B0_R1_CSR              0x0060  /* 32 bit       BMU Ctrl/Stat Rx Queue 1 */
+#define B0_R2_CSR              0x0064  /* 32 bit       BMU Ctrl/Stat Rx Queue 2 */
+#define B0_XS1_CSR             0x0068  /* 32 bit       BMU Ctrl/Stat Sync Tx Queue 1 */
+#define B0_XA1_CSR             0x006c  /* 32 bit       BMU Ctrl/Stat Async Tx Queue 1*/
+#define B0_XS2_CSR             0x0070  /* 32 bit       BMU Ctrl/Stat Sync Tx Queue 2 */
+#define B0_XA2_CSR             0x0074  /* 32 bit       BMU Ctrl/Stat Async Tx Queue 2*/
+       /* 0x0078 - 0x007f:     reserved */
+
+/*
+ *     Bank 1
+ *     - completely empty (this is the RAP Block window)
+ *     Note: if RAP = 1 this page is reserved
+ */
+
+/*
+ *     Bank 2
+ */
+/* NA reg = 48 bit Network Address Register, 3x16 or 8x8 bit readable */
+#define B2_MAC_1               0x0100  /* NA reg        MAC Address 1 */
+       /* 0x0106 - 0x0107:     reserved */
+#define B2_MAC_2               0x0108  /* NA reg        MAC Address 2 */
+       /* 0x010e - 0x010f:     reserved */
+#define B2_MAC_3               0x0110  /* NA reg        MAC Address 3 */
+       /* 0x0116 - 0x0117:     reserved */
+#define B2_CONN_TYP            0x0118  /*  8 bit       Connector type */
+#define B2_PMD_TYP             0x0119  /*  8 bit       PMD type */
+#define B2_MAC_CFG             0x011a  /*  8 bit       MAC Configuration / Chip Revision */
+#define B2_CHIP_ID             0x011b  /*  8 bit       Chip Identification Number */
+       /* Eprom registers are currently of no use */
+#define B2_E_0                 0x011c  /*  8 bit       EPROM Byte 0 (ext. SRAM size */
+#define B2_E_1                 0x011d  /*  8 bit       EPROM Byte 1 (PHY type) */
+#define B2_E_2                 0x011e  /*  8 bit       EPROM Byte 2 */
+#define B2_E_3                 0x011f  /*  8 bit       EPROM Byte 3 */
+#define B2_FAR                 0x0120  /* 32 bit       Flash-Prom Addr Reg/Cnt */
+#define B2_FDP                 0x0124  /*  8 bit       Flash-Prom Data Port */
+       /* 0x0125 - 0x0127:     reserved */
+#define B2_LD_CRTL             0x0128  /*  8 bit       EPROM loader control register */
+#define B2_LD_TEST             0x0129  /*  8 bit       EPROM loader test register */
+       /* 0x012a - 0x012f:     reserved */
+#define B2_TI_INI              0x0130  /* 32 bit       Timer Init Value */
+#define B2_TI_VAL              0x0134  /* 32 bit       Timer Value */
+#define B2_TI_CRTL             0x0138  /*  8 bit       Timer Control */
+#define B2_TI_TEST             0x0139  /*  8 Bit       Timer Test */
+       /* 0x013a - 0x013f:     reserved */
+#define B2_IRQM_INI            0x0140  /* 32 bit       IRQ Moderation Timer Init Reg.*/
+#define B2_IRQM_VAL            0x0144  /* 32 bit       IRQ Moderation Timer Value */
+#define B2_IRQM_CTRL   0x0148  /*  8 bit       IRQ Moderation Timer Control */
+#define B2_IRQM_TEST   0x0149  /*  8 bit       IRQ Moderation Timer Test */
+#define B2_IRQM_MSK    0x014c  /* 32 bit       IRQ Moderation Mask */
+#define B2_IRQM_HWE_MSK 0x0150 /* 32 bit       IRQ Moderation HW Error Mask */
+       /* 0x0154 - 0x0157:     reserved */
+#define B2_TST_CTRL1   0x0158  /*  8 bit       Test Control Register 1 */
+#define B2_TST_CTRL2   0x0159  /*  8 bit       Test Control Register 2 */
+       /* 0x015a - 0x015b:     reserved */
+#define B2_GP_IO               0x015c  /* 32 bit       General Purpose I/O Register */
+#define B2_I2C_CTRL            0x0160  /* 32 bit       I2C HW Control Register */
+#define B2_I2C_DATA            0x0164  /* 32 bit       I2C HW Data Register */
+#define B2_I2C_IRQ             0x0168  /* 32 bit       I2C HW IRQ Register */
+#define B2_I2C_SW              0x016c  /* 32 bit       I2C SW Port Register */
+
+/* Blink Source Counter (GENESIS only) */
+#define B2_BSC_INI             0x0170  /* 32 bit       Blink Source Counter Init Val */
+#define B2_BSC_VAL             0x0174  /* 32 bit       Blink Source Counter Value */
+#define B2_BSC_CTRL            0x0178  /*  8 bit       Blink Source Counter Control */
+#define B2_BSC_STAT            0x0179  /*  8 bit       Blink Source Counter Status */
+#define B2_BSC_TST             0x017a  /* 16 bit       Blink Source Counter Test Reg */
+       /* 0x017c - 0x017f:     reserved */
+
+/*
+ *     Bank 3
+ */
+/* RAM Random Registers */
+#define B3_RAM_ADDR            0x0180  /* 32 bit       RAM Address, to read or write */
+#define B3_RAM_DATA_LO 0x0184  /* 32 bit       RAM Data Word (low dWord) */
+#define B3_RAM_DATA_HI 0x0188  /* 32 bit       RAM Data Word (high dWord) */
+       /* 0x018c - 0x018f:     reserved */
+
+/* RAM Interface Registers */
+/*
+ * The HW-Spec. calls this registers Timeout Value 0..11. But this names are
+ * not usable in SW. Please notice these are NOT real timeouts, these are
+ * the number of qWords transferred continuously.
+ */
+#define B3_RI_WTO_R1   0x0190  /*  8 bit       WR Timeout Queue R1             (TO0) */
+#define B3_RI_WTO_XA1  0x0191  /*  8 bit       WR Timeout Queue XA1    (TO1) */
+#define B3_RI_WTO_XS1  0x0192  /*  8 bit       WR Timeout Queue XS1    (TO2) */
+#define B3_RI_RTO_R1   0x0193  /*  8 bit       RD Timeout Queue R1             (TO3) */
+#define B3_RI_RTO_XA1  0x0194  /*  8 bit       RD Timeout Queue XA1    (TO4) */
+#define B3_RI_RTO_XS1  0x0195  /*  8 bit       RD Timeout Queue XS1    (TO5) */
+#define B3_RI_WTO_R2   0x0196  /*  8 bit       WR Timeout Queue R2             (TO6) */
+#define B3_RI_WTO_XA2  0x0197  /*  8 bit       WR Timeout Queue XA2    (TO7) */
+#define B3_RI_WTO_XS2  0x0198  /*  8 bit       WR Timeout Queue XS2    (TO8) */
+#define B3_RI_RTO_R2   0x0199  /*  8 bit       RD Timeout Queue R2             (TO9) */
+#define B3_RI_RTO_XA2  0x019a  /*  8 bit       RD Timeout Queue XA2    (TO10)*/
+#define B3_RI_RTO_XS2  0x019b  /*  8 bit       RD Timeout Queue XS2    (TO11)*/
+#define B3_RI_TO_VAL   0x019c  /*  8 bit       Current Timeout Count Val */
+       /* 0x019d - 0x019f:     reserved */
+#define B3_RI_CTRL             0x01a0  /* 16 bit       RAM Interface Control Register */
+#define B3_RI_TEST             0x01a2  /*  8 bit       RAM Interface Test Register */
+       /* 0x01a3 - 0x01af:     reserved */
+
+/* MAC Arbiter Registers (GENESIS only) */
+/* these are the no. of qWord transferred continuously and NOT real timeouts */
+#define B3_MA_TOINI_RX1        0x01b0  /*  8 bit       Timeout Init Val Rx Path MAC 1 */
+#define B3_MA_TOINI_RX2        0x01b1  /*  8 bit       Timeout Init Val Rx Path MAC 2 */
+#define B3_MA_TOINI_TX1        0x01b2  /*  8 bit       Timeout Init Val Tx Path MAC 1 */
+#define B3_MA_TOINI_TX2        0x01b3  /*  8 bit       Timeout Init Val Tx Path MAC 2 */
+#define B3_MA_TOVAL_RX1        0x01b4  /*  8 bit       Timeout Value Rx Path MAC 1 */
+#define B3_MA_TOVAL_RX2        0x01b5  /*  8 bit       Timeout Value Rx Path MAC 1 */
+#define B3_MA_TOVAL_TX1        0x01b6  /*  8 bit       Timeout Value Tx Path MAC 2 */
+#define B3_MA_TOVAL_TX2        0x01b7  /*  8 bit       Timeout Value Tx Path MAC 2 */
+#define B3_MA_TO_CTRL  0x01b8  /* 16 bit       MAC Arbiter Timeout Ctrl Reg */
+#define B3_MA_TO_TEST  0x01ba  /* 16 bit       MAC Arbiter Timeout Test Reg */
+       /* 0x01bc - 0x01bf:     reserved */
+#define B3_MA_RCINI_RX1        0x01c0  /*  8 bit       Recovery Init Val Rx Path MAC 1 */
+#define B3_MA_RCINI_RX2        0x01c1  /*  8 bit       Recovery Init Val Rx Path MAC 2 */
+#define B3_MA_RCINI_TX1        0x01c2  /*  8 bit       Recovery Init Val Tx Path MAC 1 */
+#define B3_MA_RCINI_TX2        0x01c3  /*  8 bit       Recovery Init Val Tx Path MAC 2 */
+#define B3_MA_RCVAL_RX1        0x01c4  /*  8 bit       Recovery Value Rx Path MAC 1 */
+#define B3_MA_RCVAL_RX2        0x01c5  /*  8 bit       Recovery Value Rx Path MAC 1 */
+#define B3_MA_RCVAL_TX1        0x01c6  /*  8 bit       Recovery Value Tx Path MAC 2 */
+#define B3_MA_RCVAL_TX2        0x01c7  /*  8 bit       Recovery Value Tx Path MAC 2 */
+#define B3_MA_RC_CTRL  0x01c8  /* 16 bit       MAC Arbiter Recovery Ctrl Reg */
+#define B3_MA_RC_TEST  0x01ca  /* 16 bit       MAC Arbiter Recovery Test Reg */
+       /* 0x01cc - 0x01cf:     reserved */
+
+/* Packet Arbiter Registers (GENESIS only) */
+/* these are real timeouts */
+#define B3_PA_TOINI_RX1        0x01d0  /* 16 bit       Timeout Init Val Rx Path MAC 1 */
+       /* 0x01d2 - 0x01d3:     reserved */
+#define B3_PA_TOINI_RX2        0x01d4  /* 16 bit       Timeout Init Val Rx Path MAC 2 */
+       /* 0x01d6 - 0x01d7:     reserved */
+#define B3_PA_TOINI_TX1        0x01d8  /* 16 bit       Timeout Init Val Tx Path MAC 1 */
+       /* 0x01da - 0x01db:     reserved */
+#define B3_PA_TOINI_TX2        0x01dc  /* 16 bit       Timeout Init Val Tx Path MAC 2 */
+       /* 0x01de - 0x01df:     reserved */
+#define B3_PA_TOVAL_RX1        0x01e0  /* 16 bit       Timeout Val Rx Path MAC 1 */
+       /* 0x01e2 - 0x01e3:     reserved */
+#define B3_PA_TOVAL_RX2        0x01e4  /* 16 bit       Timeout Val Rx Path MAC 2 */
+       /* 0x01e6 - 0x01e7:     reserved */
+#define B3_PA_TOVAL_TX1        0x01e8  /* 16 bit       Timeout Val Tx Path MAC 1 */
+       /* 0x01ea - 0x01eb:     reserved */
+#define B3_PA_TOVAL_TX2        0x01ec  /* 16 bit       Timeout Val Tx Path MAC 2 */
+       /* 0x01ee - 0x01ef:     reserved */
+#define B3_PA_CTRL     0x01f0  /* 16 bit       Packet Arbiter Ctrl Register */
+#define B3_PA_TEST     0x01f2  /* 16 bit       Packet Arbiter Test Register */
+       /* 0x01f4 - 0x01ff:     reserved */
+
+/*
+ *     Bank 4 - 5
+ */
+/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
+#define TXA_ITI_INI            0x0200  /* 32 bit       Tx Arb Interval Timer Init Val*/
+#define TXA_ITI_VAL            0x0204  /* 32 bit       Tx Arb Interval Timer Value */
+#define TXA_LIM_INI            0x0208  /* 32 bit       Tx Arb Limit Counter Init Val */
+#define TXA_LIM_VAL            0x020c  /* 32 bit       Tx Arb Limit Counter Value */
+#define TXA_CTRL               0x0210  /*  8 bit       Tx Arbiter Control Register */
+#define TXA_TEST               0x0211  /*  8 bit       Tx Arbiter Test Register */
+#define TXA_STAT               0x0212  /*  8 bit       Tx Arbiter Status Register */
+       /* 0x0213 - 0x027f:     reserved */
+       /* 0x0280 - 0x0292:     MAC 2 */
+       /* 0x0213 - 0x027f:     reserved */
+
+/*
+ *     Bank 6
+ */
+/* External registers (GENESIS only) */
+#define B6_EXT_REG             0x0300
+
+/*
+ *     Bank 7
+ */
+/* This is a copy of the Configuration register file (lower half) */
+#define B7_CFG_SPC             0x0380
+
+/*
+ *     Bank 8 - 15
+ */
+/* Receive and Transmit Queue Registers, use Q_ADDR() to access */
+#define B8_Q_REGS              0x0400
+
+/* Queue Register Offsets, use Q_ADDR() to access */
+#define Q_D            0x00    /* 8*32 bit     Current Descriptor */
+#define Q_DA_L 0x20    /* 32 bit       Current Descriptor Address Low dWord */
+#define Q_DA_H 0x24    /* 32 bit       Current Descriptor Address High dWord */
+#define Q_AC_L 0x28    /* 32 bit       Current Address Counter Low dWord */
+#define Q_AC_H 0x2c    /* 32 bit       Current Address Counter High dWord */
+#define Q_BC   0x30    /* 32 bit       Current Byte Counter */
+#define Q_CSR  0x34    /* 32 bit       BMU Control/Status Register */
+#define Q_F            0x38    /* 32 bit       Flag Register */
+#define Q_T1   0x3c    /* 32 bit       Test Register 1 */
+#define Q_T1_TR        0x3c    /*  8 bit       Test Register 1 Transfer SM */
+#define Q_T1_WR        0x3d    /*  8 bit       Test Register 1 Write Descriptor SM */
+#define Q_T1_RD        0x3e    /*  8 bit       Test Register 1 Read Descriptor SM */
+#define Q_T1_SV        0x3f    /*  8 bit       Test Register 1 Supervisor SM */
+#define Q_T2   0x40    /* 32 bit       Test Register 2 */
+#define Q_T3   0x44    /* 32 bit       Test Register 3 */
+       /* 0x48 - 0x7f: reserved */
+
+/*
+ *     Bank 16 - 23
+ */
+/* RAM Buffer Registers */
+#define B16_RAM_REGS   0x0800
+
+/* RAM Buffer Register Offsets, use RB_ADDR() to access */
+#define RB_START               0x00    /* 32 bit       RAM Buffer Start Address */
+#define RB_END                 0x04    /* 32 bit       RAM Buffer End Address */
+#define RB_WP                  0x08    /* 32 bit       RAM Buffer Write Pointer */
+#define RB_RP                  0x0c    /* 32 bit       RAM Buffer Read Pointer */
+#define RB_RX_UTPP             0x10    /* 32 bit       Rx Upper Threshold, Pause Pack */
+#define RB_RX_LTPP             0x14    /* 32 bit       Rx Lower Threshold, Pause Pack */
+#define RB_RX_UTHP             0x18    /* 32 bit       Rx Upper Threshold, High Prio */
+#define RB_RX_LTHP             0x1c    /* 32 bit       Rx Lower Threshold, High Prio */
+       /* 0x10 - 0x1f: reserved at Tx RAM Buffer Registers */
+#define RB_PC                  0x20    /* 32 bit       RAM Buffer Packet Counter */
+#define RB_LEV                 0x24    /* 32 bit       RAM Buffer Level Register */
+#define RB_CTRL                        0x28    /*  8 bit       RAM Buffer Control Register */
+#define RB_TST1                        0x29    /*  8 bit       RAM Buffer Test Register 1 */
+#define RB_TST2                        0x2A    /*  8 bit       RAM Buffer Test Register 2 */
+       /* 0x2c - 0x7f: reserved */
+
+/*
+ *     Bank 24
+ */
+/*
+ * Receive MAC FIFO, Receive LED, and Link_Sync regs (GENESIS only)
+ * use MR_ADDR() to access
+ */
+#define RX_MFF_EA              0x0c00  /* 32 bit       Receive MAC FIFO End Address */
+#define RX_MFF_WP              0x0c04  /* 32 bit       Receive MAC FIFO Write Pointer */
+       /* 0x0c08 - 0x0c0b:     reserved */
+#define RX_MFF_RP              0x0c0c  /* 32 bit       Receive MAC FIFO Read Pointer */
+#define RX_MFF_PC              0x0c10  /* 32 bit       Receive MAC FIFO Packet Cnt */
+#define RX_MFF_LEV             0x0c14  /* 32 bit       Receive MAC FIFO Level */
+#define RX_MFF_CTRL1   0x0c18  /* 16 bit       Receive MAC FIFO Control Reg 1*/
+#define RX_MFF_STAT_TO 0x0c1a  /*  8 bit       Receive MAC Status Timeout */
+#define RX_MFF_TIST_TO 0x0c1b  /*  8 bit       Receive MAC Time Stamp Timeout */
+#define RX_MFF_CTRL2   0x0c1c  /*  8 bit       Receive MAC FIFO Control Reg 2*/
+#define RX_MFF_TST1            0x0c1d  /*  8 bit       Receive MAC FIFO Test Reg 1 */
+#define RX_MFF_TST2            0x0c1e  /*  8 bit       Receive MAC FIFO Test Reg 2 */
+       /* 0x0c1f:      reserved */
+#define RX_LED_INI             0x0c20  /* 32 bit       Receive LED Cnt Init Value */
+#define RX_LED_VAL             0x0c24  /* 32 bit       Receive LED Cnt Current Value */
+#define RX_LED_CTRL            0x0c28  /*  8 bit       Receive LED Cnt Control Reg */
+#define RX_LED_TST             0x0c29  /*  8 bit       Receive LED Cnt Test Register */
+       /* 0x0c2a - 0x0c2f:     reserved */
+#define LNK_SYNC_INI   0x0c30  /* 32 bit       Link Sync Cnt Init Value */
+#define LNK_SYNC_VAL   0x0c34  /* 32 bit       Link Sync Cnt Current Value */
+#define LNK_SYNC_CTRL  0x0c38  /*  8 bit       Link Sync Cnt Control Register */
+#define LNK_SYNC_TST   0x0c39  /*  8 bit       Link Sync Cnt Test Register */
+       /* 0x0c3a - 0x0c3b:     reserved */
+#define LNK_LED_REG            0x0c3c  /*  8 bit       Link LED Register */
+       /* 0x0c3d - 0x0c3f:     reserved */
+
+/* Receive GMAC FIFO (YUKON only), use MR_ADDR() to access */
+#define RX_GMF_EA              0x0c40  /* 32 bit       Rx GMAC FIFO End Address */
+#define RX_GMF_AF_THR  0x0c44  /* 32 bit       Rx GMAC FIFO Almost Full Thresh. */
+#define RX_GMF_CTRL_T  0x0c48  /* 32 bit       Rx GMAC FIFO Control/Test */
+#define RX_GMF_FL_MSK  0x0c4c  /* 32 bit       Rx GMAC FIFO Flush Mask */
+#define RX_GMF_FL_THR  0x0c50  /* 32 bit       Rx GMAC FIFO Flush Threshold */
+       /* 0x0c54 - 0x0c5f:     reserved */
+#define RX_GMF_WP              0x0c60  /* 32 bit       Rx GMAC FIFO Write Pointer */
+       /* 0x0c64 - 0x0c67:     reserved */
+#define RX_GMF_WLEV            0x0c68  /* 32 bit       Rx GMAC FIFO Write Level */
+       /* 0x0c6c - 0x0c6f:     reserved */
+#define RX_GMF_RP              0x0c70  /* 32 bit       Rx GMAC FIFO Read Pointer */
+       /* 0x0c74 - 0x0c77:     reserved */
+#define RX_GMF_RLEV            0x0c78  /* 32 bit       Rx GMAC FIFO Read Level */
+       /* 0x0c7c - 0x0c7f:     reserved */
+
+/*
+ *     Bank 25
+ */
+       /* 0x0c80 - 0x0cbf:     MAC 2 */
+       /* 0x0cc0 - 0x0cff:     reserved */
+
+/*
+ *     Bank 26
+ */
+/*
+ * Transmit MAC FIFO and Transmit LED Registers (GENESIS only),
+ * use MR_ADDR() to access
+ */
+#define TX_MFF_EA              0x0d00  /* 32 bit       Transmit MAC FIFO End Address */
+#define TX_MFF_WP              0x0d04  /* 32 bit       Transmit MAC FIFO WR Pointer */
+#define TX_MFF_WSP             0x0d08  /* 32 bit       Transmit MAC FIFO WR Shadow Ptr */
+#define TX_MFF_RP              0x0d0c  /* 32 bit       Transmit MAC FIFO RD Pointer */
+#define TX_MFF_PC              0x0d10  /* 32 bit       Transmit MAC FIFO Packet Cnt */
+#define TX_MFF_LEV             0x0d14  /* 32 bit       Transmit MAC FIFO Level */
+#define TX_MFF_CTRL1   0x0d18  /* 16 bit       Transmit MAC FIFO Ctrl Reg 1 */
+#define TX_MFF_WAF             0x0d1a  /*  8 bit       Transmit MAC Wait after flush */
+       /* 0x0c1b:      reserved */
+#define TX_MFF_CTRL2   0x0d1c  /*  8 bit       Transmit MAC FIFO Ctrl Reg 2 */
+#define TX_MFF_TST1            0x0d1d  /*  8 bit       Transmit MAC FIFO Test Reg 1 */
+#define TX_MFF_TST2            0x0d1e  /*  8 bit       Transmit MAC FIFO Test Reg 2 */
+       /* 0x0d1f:      reserved */
+#define TX_LED_INI             0x0d20  /* 32 bit       Transmit LED Cnt Init Value */
+#define TX_LED_VAL             0x0d24  /* 32 bit       Transmit LED Cnt Current Val */
+#define TX_LED_CTRL            0x0d28  /*  8 bit       Transmit LED Cnt Control Reg */
+#define TX_LED_TST             0x0d29  /*  8 bit       Transmit LED Cnt Test Reg */
+       /* 0x0d2a - 0x0d3f:     reserved */
+
+/* Transmit GMAC FIFO (YUKON only), use MR_ADDR() to access */
+#define TX_GMF_EA              0x0d40  /* 32 bit       Tx GMAC FIFO End Address */
+#define TX_GMF_AE_THR  0x0d44  /* 32 bit       Tx GMAC FIFO Almost Empty Thresh.*/
+#define TX_GMF_CTRL_T  0x0d48  /* 32 bit       Tx GMAC FIFO Control/Test */
+       /* 0x0d4c - 0x0d5f:     reserved */
+#define TX_GMF_WP              0x0d60  /* 32 bit       Tx GMAC FIFO Write Pointer */
+#define TX_GMF_WSP             0x0d64  /* 32 bit       Tx GMAC FIFO Write Shadow Ptr. */
+#define TX_GMF_WLEV            0x0d68  /* 32 bit       Tx GMAC FIFO Write Level */
+       /* 0x0d6c - 0x0d6f:     reserved */
+#define TX_GMF_RP              0x0d70  /* 32 bit       Tx GMAC FIFO Read Pointer */
+#define TX_GMF_RSTP            0x0d74  /* 32 bit       Tx GMAC FIFO Restart Pointer */
+#define TX_GMF_RLEV            0x0d78  /* 32 bit       Tx GMAC FIFO Read Level */
+       /* 0x0d7c - 0x0d7f:     reserved */
+
+/*
+ *     Bank 27
+ */
+       /* 0x0d80 - 0x0dbf:     MAC 2 */
+       /* 0x0daa - 0x0dff:     reserved */
+
+/*
+ *     Bank 28
+ */
+/* Descriptor Poll Timer Registers */
+#define B28_DPT_INI            0x0e00  /* 24 bit       Descriptor Poll Timer Init Val */
+#define B28_DPT_VAL            0x0e04  /* 24 bit       Descriptor Poll Timer Curr Val */
+#define B28_DPT_CTRL   0x0e08  /*  8 bit       Descriptor Poll Timer Ctrl Reg */
+       /* 0x0e09:      reserved */
+#define B28_DPT_TST            0x0e0a  /*  8 bit       Descriptor Poll Timer Test Reg */
+       /* 0x0e0b:      reserved */
+
+/* Time Stamp Timer Registers (YUKON only) */
+       /* 0x0e10:      reserved */
+#define GMAC_TI_ST_VAL 0x0e14  /* 32 bit       Time Stamp Timer Curr Val */
+#define GMAC_TI_ST_CTRL        0x0e18  /*  8 bit       Time Stamp Timer Ctrl Reg */
+       /* 0x0e19:      reserved */
+#define GMAC_TI_ST_TST 0x0e1a  /*  8 bit       Time Stamp Timer Test Reg */
+       /* 0x0e1b - 0x0e7f:     reserved */
+
+/*
+ *     Bank 29
+ */
+       /* 0x0e80 - 0x0efc:     reserved */
+
+/*
+ *     Bank 30
+ */
+/* GMAC and GPHY Control Registers (YUKON only) */
+#define GMAC_CTRL              0x0f00  /* 32 bit       GMAC Control Reg */
+#define GPHY_CTRL              0x0f04  /* 32 bit       GPHY Control Reg */
+#define GMAC_IRQ_SRC   0x0f08  /*  8 bit       GMAC Interrupt Source Reg */
+       /* 0x0f09 - 0x0f0b:     reserved */
+#define GMAC_IRQ_MSK   0x0f0c  /*  8 bit       GMAC Interrupt Mask Reg */
+       /* 0x0f0d - 0x0f0f:     reserved */
+#define GMAC_LINK_CTRL 0x0f10  /* 16 bit       Link Control Reg */
+       /* 0x0f14 - 0x0f1f:     reserved */
+
+/* Wake-up Frame Pattern Match Control Registers (YUKON only) */
+
+#define WOL_REG_OFFS   0x20    /* HW-Bug: Address is + 0x20 against spec. */
+
+#define WOL_CTRL_STAT  0x0f20  /* 16 bit       WOL Control/Status Reg */
+#define WOL_MATCH_CTL  0x0f22  /*  8 bit       WOL Match Control Reg */
+#define WOL_MATCH_RES  0x0f23  /*  8 bit       WOL Match Result Reg */
+#define WOL_MAC_ADDR_LO        0x0f24  /* 32 bit       WOL MAC Address Low */
+#define WOL_MAC_ADDR_HI        0x0f28  /* 16 bit       WOL MAC Address High */
+#define WOL_PATT_RPTR  0x0f2c  /*  8 bit       WOL Pattern Read Ptr */
+
+/* use this macro to access above registers */
+#define WOL_REG(Reg)   ((Reg) + (pAC->GIni.GIWolOffs))
+
+
+/* WOL Pattern Length Registers (YUKON only) */
+
+#define WOL_PATT_LEN_LO        0x0f30          /* 32 bit       WOL Pattern Length 3..0 */
+#define WOL_PATT_LEN_HI        0x0f34          /* 24 bit       WOL Pattern Length 6..4 */
+
+/* WOL Pattern Counter Registers (YUKON only) */
+
+#define WOL_PATT_CNT_0 0x0f38          /* 32 bit       WOL Pattern Counter 3..0 */
+#define WOL_PATT_CNT_4 0x0f3c          /* 24 bit       WOL Pattern Counter 6..4 */
+       /* 0x0f40 - 0x0f7f:     reserved */
+
+/*
+ *     Bank 31
+ */
+/* 0x0f80 - 0x0fff:    reserved */
+
+/*
+ *     Bank 32 - 33
+ */
+#define WOL_PATT_RAM_1 0x1000  /*  WOL Pattern RAM Link 1 */
+
+/*
+ *     Bank 0x22 - 0x3f
+ */
+/* 0x1100 - 0x1fff:    reserved */
+
+/*
+ *     Bank 0x40 - 0x4f
+ */
+#define BASE_XMAC_1            0x2000  /* XMAC 1 registers */
+
+/*
+ *     Bank 0x50 - 0x5f
+ */
+
+#define BASE_GMAC_1            0x2800  /* GMAC 1 registers */
+
+/*
+ *     Bank 0x60 - 0x6f
+ */
+#define BASE_XMAC_2            0x3000  /* XMAC 2 registers */
+
+/*
+ *     Bank 0x70 - 0x7f
+ */
+#define BASE_GMAC_2            0x3800  /* GMAC 2 registers */
+
+/*
+ *     Control Register Bit Definitions:
+ */
+/*     B0_RAP          8 bit   Register Address Port */
+                                                               /* Bit 7:       reserved */
+#define RAP_RAP                        0x3f    /* Bit 6..0:    0 = block 0,..,6f = block 6f */
+
+/*     B0_CTST         16 bit  Control/Status register */
+                                                               /* Bit 15..14:  reserved */
+#define CS_CLK_RUN_HOT BIT_13S         /* CLK_RUN hot m. (YUKON-Lite only) */
+#define CS_CLK_RUN_RST BIT_12S         /* CLK_RUN reset  (YUKON-Lite only) */
+#define CS_CLK_RUN_ENA BIT_11S         /* CLK_RUN enable (YUKON-Lite only) */
+#define CS_VAUX_AVAIL  BIT_10S         /* VAUX available (YUKON only) */
+#define CS_BUS_CLOCK   BIT_9S          /* Bus Clock 0/1 = 33/66 MHz */
+#define CS_BUS_SLOT_SZ BIT_8S          /* Slot Size 0/1 = 32/64 bit slot */
+#define CS_ST_SW_IRQ   BIT_7S          /* Set IRQ SW Request */
+#define CS_CL_SW_IRQ   BIT_6S          /* Clear IRQ SW Request */
+#define CS_STOP_DONE   BIT_5S          /* Stop Master is finished */
+#define CS_STOP_MAST   BIT_4S          /* Command Bit to stop the master */
+#define CS_MRST_CLR            BIT_3S          /* Clear Master reset   */
+#define CS_MRST_SET            BIT_2S          /* Set Master reset     */
+#define CS_RST_CLR             BIT_1S          /* Clear Software reset */
+#define CS_RST_SET             BIT_0S          /* Set   Software reset */
+
+/*     B0_LED           8 Bit  LED register */
+                                                               /* Bit  7.. 2:  reserved */
+#define LED_STAT_ON            BIT_1S          /* Status LED on        */
+#define LED_STAT_OFF   BIT_0S          /* Status LED off       */
+
+/*     B0_POWER_CTRL    8 Bit  Power Control reg (YUKON only) */
+#define PC_VAUX_ENA            BIT_7           /* Switch VAUX Enable  */
+#define PC_VAUX_DIS            BIT_6       /* Switch VAUX Disable */
+#define PC_VCC_ENA             BIT_5       /* Switch VCC Enable  */
+#define PC_VCC_DIS             BIT_4       /* Switch VCC Disable */
+#define PC_VAUX_ON             BIT_3       /* Switch VAUX On  */
+#define PC_VAUX_OFF            BIT_2       /* Switch VAUX Off */
+#define PC_VCC_ON              BIT_1       /* Switch VCC On  */
+#define PC_VCC_OFF             BIT_0       /* Switch VCC Off */
+
+/*     B0_ISRC         32 bit  Interrupt Source Register */
+/*     B0_IMSK         32 bit  Interrupt Mask Register */
+/*     B0_SP_ISRC      32 bit  Special Interrupt Source Reg */
+/*     B2_IRQM_MSK     32 bit  IRQ Moderation Mask */
+#define IS_ALL_MSK             0xbfffffffL     /*              All Interrupt bits */
+#define IS_HW_ERR              BIT_31          /* Interrupt HW Error */
+                                                               /* Bit 30:      reserved */
+#define IS_PA_TO_RX1   BIT_29          /* Packet Arb Timeout Rx1 */
+#define IS_PA_TO_RX2   BIT_28          /* Packet Arb Timeout Rx2 */
+#define IS_PA_TO_TX1   BIT_27          /* Packet Arb Timeout Tx1 */
+#define IS_PA_TO_TX2   BIT_26          /* Packet Arb Timeout Tx2 */
+#define IS_I2C_READY   BIT_25          /* IRQ on end of I2C Tx */
+#define IS_IRQ_SW              BIT_24          /* SW forced IRQ        */
+#define IS_EXT_REG             BIT_23          /* IRQ from LM80 or PHY (GENESIS only) */
+                                                                       /* IRQ from PHY (YUKON only) */
+#define IS_TIMINT              BIT_22          /* IRQ from Timer       */
+#define IS_MAC1                        BIT_21          /* IRQ from MAC 1       */
+#define IS_LNK_SYNC_M1 BIT_20          /* Link Sync Cnt wrap MAC 1 */
+#define IS_MAC2                        BIT_19          /* IRQ from MAC 2       */
+#define IS_LNK_SYNC_M2 BIT_18          /* Link Sync Cnt wrap MAC 2 */
+/* Receive Queue 1 */
+#define IS_R1_B                        BIT_17          /* Q_R1 End of Buffer */
+#define IS_R1_F                        BIT_16          /* Q_R1 End of Frame */
+#define IS_R1_C                        BIT_15          /* Q_R1 Encoding Error */
+/* Receive Queue 2 */
+#define IS_R2_B                        BIT_14          /* Q_R2 End of Buffer */
+#define IS_R2_F                        BIT_13          /* Q_R2 End of Frame */
+#define IS_R2_C                        BIT_12          /* Q_R2 Encoding Error */
+/* Synchronous Transmit Queue 1 */
+#define IS_XS1_B               BIT_11          /* Q_XS1 End of Buffer */
+#define IS_XS1_F               BIT_10          /* Q_XS1 End of Frame */
+#define IS_XS1_C               BIT_9           /* Q_XS1 Encoding Error */
+/* Asynchronous Transmit Queue 1 */
+#define IS_XA1_B               BIT_8           /* Q_XA1 End of Buffer */
+#define IS_XA1_F               BIT_7           /* Q_XA1 End of Frame */
+#define IS_XA1_C               BIT_6           /* Q_XA1 Encoding Error */
+/* Synchronous Transmit Queue 2 */
+#define IS_XS2_B               BIT_5           /* Q_XS2 End of Buffer */
+#define IS_XS2_F               BIT_4           /* Q_XS2 End of Frame */
+#define IS_XS2_C               BIT_3           /* Q_XS2 Encoding Error */
+/* Asynchronous Transmit Queue 2 */
+#define IS_XA2_B               BIT_2           /* Q_XA2 End of Buffer */
+#define IS_XA2_F               BIT_1           /* Q_XA2 End of Frame */
+#define IS_XA2_C               BIT_0           /* Q_XA2 Encoding Error */
+
+
+/*     B0_HWE_ISRC     32 bit  HW Error Interrupt Src Reg */
+/*     B0_HWE_IMSK     32 bit  HW Error Interrupt Mask Reg */
+/*     B2_IRQM_HWE_MSK 32 bit  IRQ Moderation HW Error Mask */
+#define IS_ERR_MSK             0x00000fffL     /*              All Error bits */
+                                                               /* Bit 31..14:  reserved */
+#define IS_IRQ_TIST_OV BIT_13  /* Time Stamp Timer Overflow (YUKON only) */
+#define IS_IRQ_SENSOR  BIT_12  /* IRQ from Sensor (YUKON only) */
+#define IS_IRQ_MST_ERR BIT_11  /* IRQ master error detected */
+#define IS_IRQ_STAT            BIT_10  /* IRQ status exception */
+#define IS_NO_STAT_M1  BIT_9   /* No Rx Status from MAC 1 */
+#define IS_NO_STAT_M2  BIT_8   /* No Rx Status from MAC 2 */
+#define IS_NO_TIST_M1  BIT_7   /* No Time Stamp from MAC 1 */
+#define IS_NO_TIST_M2  BIT_6   /* No Time Stamp from MAC 2 */
+#define IS_RAM_RD_PAR  BIT_5   /* RAM Read  Parity Error */
+#define IS_RAM_WR_PAR  BIT_4   /* RAM Write Parity Error */
+#define IS_M1_PAR_ERR  BIT_3   /* MAC 1 Parity Error */
+#define IS_M2_PAR_ERR  BIT_2   /* MAC 2 Parity Error */
+#define IS_R1_PAR_ERR  BIT_1   /* Queue R1 Parity Error */
+#define IS_R2_PAR_ERR  BIT_0   /* Queue R2 Parity Error */
+
+/*     B2_CONN_TYP      8 bit  Connector type */
+/*     B2_PMD_TYP       8 bit  PMD type */
+/*     Values of connector and PMD type comply to SysKonnect internal std */
+
+/*     B2_MAC_CFG       8 bit  MAC Configuration / Chip Revision */
+#define CFG_CHIP_R_MSK (0xf<<4)        /* Bit 7.. 4: Chip Revision */
+                                                                       /* Bit 3.. 2:   reserved */
+#define CFG_DIS_M2_CLK BIT_1S          /* Disable Clock for 2nd MAC */
+#define CFG_SNG_MAC            BIT_0S          /* MAC Config: 0=2 MACs / 1=1 MAC*/
+
+/*     B2_CHIP_ID       8 bit  Chip Identification Number */
+#define CHIP_ID_GENESIS        0x0a            /* Chip ID for GENESIS */
+#define CHIP_ID_YUKON  0xb0            /* Chip ID for YUKON */
+
+/*     B2_FAR          32 bit  Flash-Prom Addr Reg/Cnt */
+#define FAR_ADDR               0x1ffffL        /* Bit 16.. 0:  FPROM Address mask */
+
+/*     B2_LD_CRTL       8 bit  EPROM loader control register */
+/*     Bits are currently reserved */
+
+/*     B2_LD_TEST       8 bit  EPROM loader test register */
+                                                               /* Bit 7.. 4:   reserved */
+#define LD_T_ON                        BIT_3S  /* Loader Test mode on */
+#define LD_T_OFF               BIT_2S  /* Loader Test mode off */
+#define LD_T_STEP              BIT_1S  /* Decrement FPROM addr. Counter */
+#define LD_START               BIT_0S  /* Start loading FPROM */
+
+/*
+ *     Timer Section
+ */
+/*     B2_TI_CRTL       8 bit  Timer control */
+/*     B2_IRQM_CTRL     8 bit  IRQ Moderation Timer Control */
+                                                               /* Bit 7.. 3:   reserved */
+#define TIM_START              BIT_2S  /* Start Timer */
+#define TIM_STOP               BIT_1S  /* Stop  Timer */
+#define TIM_CLR_IRQ            BIT_0S  /* Clear Timer IRQ (!IRQM) */
+
+/*     B2_TI_TEST       8 Bit  Timer Test */
+/*     B2_IRQM_TEST     8 bit  IRQ Moderation Timer Test */
+/*     B28_DPT_TST      8 bit  Descriptor Poll Timer Test Reg */
+                                                               /* Bit 7.. 3:   reserved */
+#define TIM_T_ON               BIT_2S  /* Test mode on */
+#define TIM_T_OFF              BIT_1S  /* Test mode off */
+#define TIM_T_STEP             BIT_0S  /* Test step */
+
+/*     B28_DPT_INI     32 bit  Descriptor Poll Timer Init Val */
+/*     B28_DPT_VAL     32 bit  Descriptor Poll Timer Curr Val */
+                                                               /* Bit 31..24:  reserved */
+#define DPT_MSK                0x00ffffffL     /* Bit 23.. 0:  Desc Poll Timer Bits */
+
+/*     B28_DPT_CTRL     8 bit  Descriptor Poll Timer Ctrl Reg */
+                                                               /* Bit  7.. 2:  reserved */
+#define DPT_START              BIT_1S  /* Start Descriptor Poll Timer */
+#define DPT_STOP               BIT_0S  /* Stop  Descriptor Poll Timer */
+
+/*     B2_E_3                   8 bit  lower 4 bits used for HW self test result */
+#define B2_E3_RES_MASK 0x0f
+
+/*     B2_TST_CTRL1     8 bit  Test Control Register 1 */
+#define TST_FRC_DPERR_MR       BIT_7S  /* force DATAPERR on MST RD */
+#define TST_FRC_DPERR_MW       BIT_6S  /* force DATAPERR on MST WR */
+#define TST_FRC_DPERR_TR       BIT_5S  /* force DATAPERR on TRG RD */
+#define TST_FRC_DPERR_TW       BIT_4S  /* force DATAPERR on TRG WR */
+#define TST_FRC_APERR_M                BIT_3S  /* force ADDRPERR on MST */
+#define TST_FRC_APERR_T                BIT_2S  /* force ADDRPERR on TRG */
+#define TST_CFG_WRITE_ON       BIT_1S  /* Enable  Config Reg WR */
+#define TST_CFG_WRITE_OFF      BIT_0S  /* Disable Config Reg WR */
+
+/*     B2_TST_CTRL2     8 bit  Test Control Register 2 */
+                                                                       /* Bit 7.. 4:   reserved */
+                       /* force the following error on the next master read/write      */
+#define TST_FRC_DPERR_MR64     BIT_3S  /* DataPERR RD 64       */
+#define TST_FRC_DPERR_MW64     BIT_2S  /* DataPERR WR 64       */
+#define TST_FRC_APERR_1M64     BIT_1S  /* AddrPERR on 1. phase */
+#define TST_FRC_APERR_2M64     BIT_0S  /* AddrPERR on 2. phase */
+
+/*     B2_GP_IO        32 bit  General Purpose I/O Register */
+                                                       /* Bit 31..26:  reserved */
+#define GP_DIR_9       BIT_25  /* IO_9 direct, 0=I/1=O */
+#define GP_DIR_8       BIT_24  /* IO_8 direct, 0=I/1=O */
+#define GP_DIR_7       BIT_23  /* IO_7 direct, 0=I/1=O */
+#define GP_DIR_6       BIT_22  /* IO_6 direct, 0=I/1=O */
+#define GP_DIR_5       BIT_21  /* IO_5 direct, 0=I/1=O */
+#define GP_DIR_4       BIT_20  /* IO_4 direct, 0=I/1=O */
+#define GP_DIR_3       BIT_19  /* IO_3 direct, 0=I/1=O */
+#define GP_DIR_2       BIT_18  /* IO_2 direct, 0=I/1=O */
+#define GP_DIR_1       BIT_17  /* IO_1 direct, 0=I/1=O */
+#define GP_DIR_0       BIT_16  /* IO_0 direct, 0=I/1=O */
+                                               /* Bit 15..10:  reserved */
+#define GP_IO_9                BIT_9   /* IO_9 pin */
+#define GP_IO_8                BIT_8   /* IO_8 pin */
+#define GP_IO_7                BIT_7   /* IO_7 pin */
+#define GP_IO_6                BIT_6   /* IO_6 pin */
+#define GP_IO_5                BIT_5   /* IO_5 pin */
+#define GP_IO_4                BIT_4   /* IO_4 pin */
+#define GP_IO_3                BIT_3   /* IO_3 pin */
+#define GP_IO_2                BIT_2   /* IO_2 pin */
+#define GP_IO_1                BIT_1   /* IO_1 pin */
+#define GP_IO_0                BIT_0   /* IO_0 pin */
+
+/*     B2_I2C_CTRL     32 bit  I2C HW Control Register */
+#define I2C_FLAG               BIT_31          /* Start read/write if WR */
+#define I2C_ADDR               (0x7fffL<<16)   /* Bit 30..16:  Addr to be RD/WR */
+#define I2C_DEV_SEL            (0x7fL<<9)              /* Bit 15.. 9:  I2C Device Select */
+                                                               /* Bit  8.. 5:  reserved        */
+#define I2C_BURST_LEN  BIT_4           /* Burst Len, 1/4 bytes */
+#define I2C_DEV_SIZE   (7L<<1)         /* Bit  3.. 1:  I2C Device Size */
+#define I2C_025K_DEV   (0L<<1)         /*              0: 256 Bytes or smal. */
+#define I2C_05K_DEV            (1L<<1)         /*              1: 512  Bytes   */
+#define I2C_1K_DEV             (2L<<1)         /*              2: 1024 Bytes   */
+#define I2C_2K_DEV             (3L<<1)         /*              3: 2048 Bytes   */
+#define I2C_4K_DEV             (4L<<1)         /*              4: 4096 Bytes   */
+#define I2C_8K_DEV             (5L<<1)         /*              5: 8192 Bytes   */
+#define I2C_16K_DEV            (6L<<1)         /*              6: 16384 Bytes  */
+#define I2C_32K_DEV            (7L<<1)         /*              7: 32768 Bytes  */
+#define I2C_STOP               BIT_0           /* Interrupt I2C transfer */
+
+/*     B2_I2C_IRQ      32 bit  I2C HW IRQ Register */
+                                                               /* Bit 31.. 1   reserved */
+#define I2C_CLR_IRQ            BIT_0   /* Clear I2C IRQ */
+
+/*     B2_I2C_SW       32 bit (8 bit access)   I2C HW SW Port Register */
+                                                               /* Bit  7.. 3:  reserved */
+#define I2C_DATA_DIR   BIT_2S          /* direction of I2C_DATA */
+#define I2C_DATA               BIT_1S          /* I2C Data Port        */
+#define I2C_CLK                        BIT_0S          /* I2C Clock Port       */
+
+/*
+ * I2C Address
+ */
+#define I2C_SENS_ADDR  LM80_ADDR       /* I2C Sensor Address, (Volt and Temp)*/
+
+
+/*     B2_BSC_CTRL      8 bit  Blink Source Counter Control */
+                                                       /* Bit  7.. 2:  reserved */
+#define BSC_START      BIT_1S          /* Start Blink Source Counter */
+#define BSC_STOP       BIT_0S          /* Stop  Blink Source Counter */
+
+/*     B2_BSC_STAT      8 bit  Blink Source Counter Status */
+                                                       /* Bit  7.. 1:  reserved */
+#define BSC_SRC                BIT_0S          /* Blink Source, 0=Off / 1=On */
+
+/*     B2_BSC_TST      16 bit  Blink Source Counter Test Reg */
+#define BSC_T_ON       BIT_2S          /* Test mode on */
+#define BSC_T_OFF      BIT_1S          /* Test mode off */
+#define BSC_T_STEP     BIT_0S          /* Test step */
+
+
+/*     B3_RAM_ADDR     32 bit  RAM Address, to read or write */
+                                       /* Bit 31..19:  reserved */
+#define RAM_ADR_RAN    0x0007ffffL     /* Bit 18.. 0:  RAM Address Range */
+
+/* RAM Interface Registers */
+/*     B3_RI_CTRL      16 bit  RAM Iface Control Register */
+                                                               /* Bit 15..10:  reserved */
+#define RI_CLR_RD_PERR BIT_9S  /* Clear IRQ RAM Read Parity Err */
+#define RI_CLR_WR_PERR BIT_8S  /* Clear IRQ RAM Write Parity Err*/
+                                                               /* Bit  7.. 2:  reserved */
+#define RI_RST_CLR             BIT_1S  /* Clear RAM Interface Reset */
+#define RI_RST_SET             BIT_0S  /* Set   RAM Interface Reset */
+
+/*     B3_RI_TEST       8 bit  RAM Iface Test Register */
+                                                               /* Bit 15.. 4:  reserved */
+#define RI_T_EV                        BIT_3S  /* Timeout Event occured */
+#define RI_T_ON                        BIT_2S  /* Timeout Timer Test On */
+#define RI_T_OFF               BIT_1S  /* Timeout Timer Test Off */
+#define RI_T_STEP              BIT_0S  /* Timeout Timer Step */
+
+/* MAC Arbiter Registers */
+/*     B3_MA_TO_CTRL   16 bit  MAC Arbiter Timeout Ctrl Reg */
+                                                               /* Bit 15.. 4:  reserved */
+#define MA_FOE_ON              BIT_3S  /* XMAC Fast Output Enable ON */
+#define MA_FOE_OFF             BIT_2S  /* XMAC Fast Output Enable OFF */
+#define MA_RST_CLR             BIT_1S  /* Clear MAC Arbiter Reset */
+#define MA_RST_SET             BIT_0S  /* Set   MAC Arbiter Reset */
+
+/*     B3_MA_RC_CTRL   16 bit  MAC Arbiter Recovery Ctrl Reg */
+                                                               /* Bit 15.. 8:  reserved */
+#define MA_ENA_REC_TX2 BIT_7S  /* Enable  Recovery Timer TX2 */
+#define MA_DIS_REC_TX2 BIT_6S  /* Disable Recovery Timer TX2 */
+#define MA_ENA_REC_TX1 BIT_5S  /* Enable  Recovery Timer TX1 */
+#define MA_DIS_REC_TX1 BIT_4S  /* Disable Recovery Timer TX1 */
+#define MA_ENA_REC_RX2 BIT_3S  /* Enable  Recovery Timer RX2 */
+#define MA_DIS_REC_RX2 BIT_2S  /* Disable Recovery Timer RX2 */
+#define MA_ENA_REC_RX1 BIT_1S  /* Enable  Recovery Timer RX1 */
+#define MA_DIS_REC_RX1 BIT_0S  /* Disable Recovery Timer RX1 */
+
+/* Packet Arbiter Registers */
+/*     B3_PA_CTRL      16 bit  Packet Arbiter Ctrl Register */
+                                                               /* Bit 15..14:  reserved */
+#define PA_CLR_TO_TX2  BIT_13S /* Clear IRQ Packet Timeout TX2 */
+#define PA_CLR_TO_TX1  BIT_12S /* Clear IRQ Packet Timeout TX1 */
+#define PA_CLR_TO_RX2  BIT_11S /* Clear IRQ Packet Timeout RX2 */
+#define PA_CLR_TO_RX1  BIT_10S /* Clear IRQ Packet Timeout RX1 */
+#define PA_ENA_TO_TX2  BIT_9S  /* Enable  Timeout Timer TX2 */
+#define PA_DIS_TO_TX2  BIT_8S  /* Disable Timeout Timer TX2 */
+#define PA_ENA_TO_TX1  BIT_7S  /* Enable  Timeout Timer TX1 */
+#define PA_DIS_TO_TX1  BIT_6S  /* Disable Timeout Timer TX1 */
+#define PA_ENA_TO_RX2  BIT_5S  /* Enable  Timeout Timer RX2 */
+#define PA_DIS_TO_RX2  BIT_4S  /* Disable Timeout Timer RX2 */
+#define PA_ENA_TO_RX1  BIT_3S  /* Enable  Timeout Timer RX1 */
+#define PA_DIS_TO_RX1  BIT_2S  /* Disable Timeout Timer RX1 */
+#define PA_RST_CLR             BIT_1S  /* Clear MAC Arbiter Reset */
+#define PA_RST_SET             BIT_0S  /* Set   MAC Arbiter Reset */
+
+#define PA_ENA_TO_ALL  (PA_ENA_TO_RX1 | PA_ENA_TO_RX2 |\
+                                               PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
+
+/* Rx/Tx Path related Arbiter Test Registers */
+/*     B3_MA_TO_TEST   16 bit  MAC Arbiter Timeout Test Reg */
+/*     B3_MA_RC_TEST   16 bit  MAC Arbiter Recovery Test Reg */
+/*     B3_PA_TEST      16 bit  Packet Arbiter Test Register */
+/*                     Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */
+#define TX2_T_EV       BIT_15S         /* TX2 Timeout/Recv Event occured */
+#define TX2_T_ON       BIT_14S         /* TX2 Timeout/Recv Timer Test On */
+#define TX2_T_OFF      BIT_13S         /* TX2 Timeout/Recv Timer Tst Off */
+#define TX2_T_STEP     BIT_12S         /* TX2 Timeout/Recv Timer Step */
+#define TX1_T_EV       BIT_11S         /* TX1 Timeout/Recv Event occured */
+#define TX1_T_ON       BIT_10S         /* TX1 Timeout/Recv Timer Test On */
+#define TX1_T_OFF      BIT_9S          /* TX1 Timeout/Recv Timer Tst Off */
+#define TX1_T_STEP     BIT_8S          /* TX1 Timeout/Recv Timer Step */
+#define RX2_T_EV       BIT_7S          /* RX2 Timeout/Recv Event occured */
+#define RX2_T_ON       BIT_6S          /* RX2 Timeout/Recv Timer Test On */
+#define RX2_T_OFF      BIT_5S          /* RX2 Timeout/Recv Timer Tst Off */
+#define RX2_T_STEP     BIT_4S          /* RX2 Timeout/Recv Timer Step */
+#define RX1_T_EV       BIT_3S          /* RX1 Timeout/Recv Event occured */
+#define RX1_T_ON       BIT_2S          /* RX1 Timeout/Recv Timer Test On */
+#define RX1_T_OFF      BIT_1S          /* RX1 Timeout/Recv Timer Tst Off */
+#define RX1_T_STEP     BIT_0S          /* RX1 Timeout/Recv Timer Step */
+
+
+/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
+/*     TXA_ITI_INI     32 bit  Tx Arb Interval Timer Init Val */
+/*     TXA_ITI_VAL     32 bit  Tx Arb Interval Timer Value */
+/*     TXA_LIM_INI     32 bit  Tx Arb Limit Counter Init Val */
+/*     TXA_LIM_VAL     32 bit  Tx Arb Limit Counter Value */
+                                                               /* Bit 31..24:  reserved */
+#define TXA_MAX_VAL    0x00ffffffL     /* Bit 23.. 0:  Max TXA Timer/Cnt Val */
+
+/*     TXA_CTRL         8 bit  Tx Arbiter Control Register */
+#define TXA_ENA_FSYNC  BIT_7S  /* Enable  force of sync Tx queue */
+#define TXA_DIS_FSYNC  BIT_6S  /* Disable force of sync Tx queue */
+#define TXA_ENA_ALLOC  BIT_5S  /* Enable  alloc of free bandwidth */
+#define TXA_DIS_ALLOC  BIT_4S  /* Disable alloc of free bandwidth */
+#define TXA_START_RC   BIT_3S  /* Start sync Rate Control */
+#define TXA_STOP_RC            BIT_2S  /* Stop  sync Rate Control */
+#define TXA_ENA_ARB            BIT_1S  /* Enable  Tx Arbiter */
+#define TXA_DIS_ARB            BIT_0S  /* Disable Tx Arbiter */
+
+/*     TXA_TEST         8 bit  Tx Arbiter Test Register */
+                                                               /* Bit 7.. 6:   reserved */
+#define TXA_INT_T_ON   BIT_5S  /* Tx Arb Interval Timer Test On */
+#define TXA_INT_T_OFF  BIT_4S  /* Tx Arb Interval Timer Test Off */
+#define TXA_INT_T_STEP BIT_3S  /* Tx Arb Interval Timer Step */
+#define TXA_LIM_T_ON   BIT_2S  /* Tx Arb Limit Timer Test On */
+#define TXA_LIM_T_OFF  BIT_1S  /* Tx Arb Limit Timer Test Off */
+#define TXA_LIM_T_STEP BIT_0S  /* Tx Arb Limit Timer Step */
+
+/*     TXA_STAT         8 bit  Tx Arbiter Status Register */
+                                                               /* Bit 7.. 1:   reserved */
+#define TXA_PRIO_XS            BIT_0S  /* sync queue has prio to send */
+
+/*     Q_BC    32 bit  Current Byte Counter */
+                                                               /* Bit 31..16:  reserved */
+#define BC_MAX                 0xffff  /* Bit 15.. 0:  Byte counter */
+
+/* BMU Control Status Registers */
+/*     B0_R1_CSR       32 bit  BMU Ctrl/Stat Rx Queue 1 */
+/*     B0_R2_CSR       32 bit  BMU Ctrl/Stat Rx Queue 2 */
+/*     B0_XA1_CSR      32 bit  BMU Ctrl/Stat Sync Tx Queue 1 */
+/*     B0_XS1_CSR      32 bit  BMU Ctrl/Stat Async Tx Queue 1 */
+/*     B0_XA2_CSR      32 bit  BMU Ctrl/Stat Sync Tx Queue 2 */
+/*     B0_XS2_CSR      32 bit  BMU Ctrl/Stat Async Tx Queue 2 */
+/*     Q_CSR           32 bit  BMU Control/Status Register */
+                                                               /* Bit 31..25:  reserved */
+#define CSR_SV_IDLE            BIT_24          /* BMU SM Idle */
+                                                               /* Bit 23..22:  reserved */
+#define CSR_DESC_CLR   BIT_21          /* Clear Reset for Descr */
+#define CSR_DESC_SET   BIT_20          /* Set   Reset for Descr */
+#define CSR_FIFO_CLR   BIT_19          /* Clear Reset for FIFO */
+#define CSR_FIFO_SET   BIT_18          /* Set   Reset for FIFO */
+#define CSR_HPI_RUN            BIT_17          /* Release HPI SM */
+#define CSR_HPI_RST            BIT_16          /* Reset   HPI SM to Idle */
+#define CSR_SV_RUN             BIT_15          /* Release Supervisor SM */
+#define CSR_SV_RST             BIT_14          /* Reset   Supervisor SM */
+#define CSR_DREAD_RUN  BIT_13          /* Release Descr Read SM */
+#define CSR_DREAD_RST  BIT_12          /* Reset   Descr Read SM */
+#define CSR_DWRITE_RUN BIT_11          /* Release Descr Write SM */
+#define CSR_DWRITE_RST BIT_10          /* Reset   Descr Write SM */
+#define CSR_TRANS_RUN  BIT_9           /* Release Transfer SM */
+#define CSR_TRANS_RST  BIT_8           /* Reset   Transfer SM */
+#define CSR_ENA_POL            BIT_7           /* Enable  Descr Polling */
+#define CSR_DIS_POL            BIT_6           /* Disable Descr Polling */
+#define CSR_STOP               BIT_5           /* Stop  Rx/Tx Queue */
+#define CSR_START              BIT_4           /* Start Rx/Tx Queue */
+#define CSR_IRQ_CL_P   BIT_3           /* (Rx) Clear Parity IRQ */
+#define CSR_IRQ_CL_B   BIT_2           /* Clear EOB IRQ */
+#define CSR_IRQ_CL_F   BIT_1           /* Clear EOF IRQ */
+#define CSR_IRQ_CL_C   BIT_0           /* Clear ERR IRQ */
+
+#define CSR_SET_RESET  (CSR_DESC_SET | CSR_FIFO_SET | CSR_HPI_RST |\
+                                               CSR_SV_RST | CSR_DREAD_RST | CSR_DWRITE_RST |\
+                                               CSR_TRANS_RST)
+#define CSR_CLR_RESET  (CSR_DESC_CLR | CSR_FIFO_CLR | CSR_HPI_RUN |\
+                                               CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\
+                                               CSR_TRANS_RUN)
+
+/*     Q_F     32 bit  Flag Register */
+                                                                       /* Bit 31..28:  reserved */
+#define F_ALM_FULL             BIT_27          /* Rx FIFO: almost full */
+#define F_EMPTY                        BIT_27          /* Tx FIFO: empty flag */
+#define F_FIFO_EOF             BIT_26          /* Tag (EOF Flag) bit in FIFO */
+#define F_WM_REACHED   BIT_25          /* Watermark reached */
+                                                                       /* reserved */
+#define F_FIFO_LEVEL   (0x1fL<<16)     /* Bit 23..16:  # of Qwords in FIFO */
+                                                                       /* Bit 15..11:  reserved */
+#define F_WATER_MARK   0x0007ffL       /* Bit 10.. 0:  Watermark */
+
+/*     Q_T1    32 bit  Test Register 1 */
+/*             Holds four State Machine control Bytes */
+#define SM_CRTL_SV_MSK (0xffL<<24)     /* Bit 31..24:  Control Supervisor SM */
+#define SM_CRTL_RD_MSK (0xffL<<16)     /* Bit 23..16:  Control Read Desc SM */
+#define SM_CRTL_WR_MSK (0xffL<<8)      /* Bit 15.. 8:  Control Write Desc SM */
+#define SM_CRTL_TR_MSK 0xffL           /* Bit  7.. 0:  Control Transfer SM */
+
+/*     Q_T1_TR  8 bit  Test Register 1 Transfer SM */
+/*     Q_T1_WR  8 bit  Test Register 1 Write Descriptor SM */
+/*     Q_T1_RD  8 bit  Test Register 1 Read Descriptor SM */
+/*     Q_T1_SV  8 bit  Test Register 1 Supervisor SM */
+
+/* The control status byte of each machine looks like ... */
+#define SM_STATE               0xf0    /* Bit 7.. 4:   State which shall be loaded */
+#define SM_LOAD                        BIT_3S  /* Load the SM with SM_STATE */
+#define SM_TEST_ON             BIT_2S  /* Switch on SM Test Mode */
+#define SM_TEST_OFF            BIT_1S  /* Go off the Test Mode */
+#define SM_STEP                        BIT_0S  /* Step the State Machine */
+/* The encoding of the states is not supported by the Diagnostics Tool */
+
+/*     Q_T2    32 bit  Test Register 2 */
+                                                               /* Bit 31.. 8:  reserved */
+#define T2_AC_T_ON             BIT_7   /* Address Counter Test Mode on */
+#define T2_AC_T_OFF            BIT_6   /* Address Counter Test Mode off */
+#define T2_BC_T_ON             BIT_5   /* Byte Counter Test Mode on */
+#define T2_BC_T_OFF            BIT_4   /* Byte Counter Test Mode off */
+#define T2_STEP04              BIT_3   /* Inc AC/Dec BC by 4 */
+#define T2_STEP03              BIT_2   /* Inc AC/Dec BC by 3 */
+#define T2_STEP02              BIT_1   /* Inc AC/Dec BC by 2 */
+#define T2_STEP01              BIT_0   /* Inc AC/Dec BC by 1 */
+
+/*     Q_T3    32 bit  Test Register 3 */
+                                                               /* Bit 31.. 7:  reserved */
+#define T3_MUX_MSK             (7<<4)  /* Bit  6.. 4:  Mux Position */
+                                                               /* Bit  3:      reserved */
+#define T3_VRAM_MSK            7               /* Bit  2.. 0:  Virtual RAM Buffer Address */
+
+/* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */
+/*     RB_START        32 bit  RAM Buffer Start Address */
+/*     RB_END          32 bit  RAM Buffer End Address */
+/*     RB_WP           32 bit  RAM Buffer Write Pointer */
+/*     RB_RP           32 bit  RAM Buffer Read Pointer */
+/*     RB_RX_UTPP      32 bit  Rx Upper Threshold, Pause Pack */
+/*     RB_RX_LTPP      32 bit  Rx Lower Threshold, Pause Pack */
+/*     RB_RX_UTHP      32 bit  Rx Upper Threshold, High Prio */
+/*     RB_RX_LTHP      32 bit  Rx Lower Threshold, High Prio */
+/*     RB_PC           32 bit  RAM Buffer Packet Counter */
+/*     RB_LEV          32 bit  RAM Buffer Level Register */
+                               /* Bit 31..19:  reserved */
+#define RB_MSK 0x0007ffff      /* Bit 18.. 0:  RAM Buffer Pointer Bits */
+
+/*     RB_TST2                  8 bit  RAM Buffer Test Register 2 */
+                                                               /* Bit 7.. 4:   reserved */
+#define RB_PC_DEC              BIT_3S  /* Packet Counter Decrem */
+#define RB_PC_T_ON             BIT_2S  /* Packet Counter Test On */
+#define RB_PC_T_OFF            BIT_1S  /* Packet Counter Tst Off */
+#define RB_PC_INC              BIT_0S  /* Packet Counter Increm */
+
+/*     RB_TST1                  8 bit  RAM Buffer Test Register 1 */
+                                                       /* Bit 7:       reserved */
+#define RB_WP_T_ON             BIT_6S  /* Write Pointer Test On */
+#define RB_WP_T_OFF            BIT_5S  /* Write Pointer Test Off */
+#define RB_WP_INC              BIT_4S  /* Write Pointer Increm */
+                                                               /* Bit 3:       reserved */
+#define RB_RP_T_ON             BIT_2S  /* Read Pointer Test On */
+#define RB_RP_T_OFF            BIT_1S  /* Read Pointer Test Off */
+#define RB_RP_DEC              BIT_0S  /* Read Pointer Decrement */
+
+/*     RB_CTRL                  8 bit  RAM Buffer Control Register */
+                                                               /* Bit 7.. 6:   reserved */
+#define RB_ENA_STFWD   BIT_5S  /* Enable  Store & Forward */
+#define RB_DIS_STFWD   BIT_4S  /* Disable Store & Forward */
+#define RB_ENA_OP_MD   BIT_3S  /* Enable  Operation Mode */
+#define RB_DIS_OP_MD   BIT_2S  /* Disable Operation Mode */
+#define RB_RST_CLR             BIT_1S  /* Clear RAM Buf STM Reset */
+#define RB_RST_SET             BIT_0S  /* Set   RAM Buf STM Reset */
+
+
+/* Receive and Transmit MAC FIFO Registers (GENESIS only) */
+
+/*     RX_MFF_EA       32 bit  Receive MAC FIFO End Address */
+/*     RX_MFF_WP       32 bit  Receive MAC FIFO Write Pointer */
+/*     RX_MFF_RP       32 bit  Receive MAC FIFO Read Pointer */
+/*     RX_MFF_PC       32 bit  Receive MAC FIFO Packet Counter */
+/*     RX_MFF_LEV      32 bit  Receive MAC FIFO Level */
+/*     TX_MFF_EA       32 bit  Transmit MAC FIFO End Address */
+/*     TX_MFF_WP       32 bit  Transmit MAC FIFO Write Pointer */
+/*     TX_MFF_WSP      32 bit  Transmit MAC FIFO WR Shadow Pointer */
+/*     TX_MFF_RP       32 bit  Transmit MAC FIFO Read Pointer */
+/*     TX_MFF_PC       32 bit  Transmit MAC FIFO Packet Cnt */
+/*     TX_MFF_LEV      32 bit  Transmit MAC FIFO Level */
+                                                               /* Bit 31.. 6:  reserved */
+#define MFF_MSK                        0x007fL /* Bit  5.. 0:  MAC FIFO Address/Ptr Bits */
+
+/*     RX_MFF_CTRL1    16 bit  Receive MAC FIFO Control Reg 1 */
+                                                               /* Bit 15..14:  reserved */
+#define MFF_ENA_RDY_PAT        BIT_13S         /* Enable  Ready Patch */
+#define MFF_DIS_RDY_PAT        BIT_12S         /* Disable Ready Patch */
+#define MFF_ENA_TIM_PAT        BIT_11S         /* Enable  Timing Patch */
+#define MFF_DIS_TIM_PAT        BIT_10S         /* Disable Timing Patch */
+#define MFF_ENA_ALM_FUL        BIT_9S          /* Enable  AlmostFull Sign */
+#define MFF_DIS_ALM_FUL        BIT_8S          /* Disable AlmostFull Sign */
+#define MFF_ENA_PAUSE  BIT_7S          /* Enable  Pause Signaling */
+#define MFF_DIS_PAUSE  BIT_6S          /* Disable Pause Signaling */
+#define MFF_ENA_FLUSH  BIT_5S          /* Enable  Frame Flushing */
+#define MFF_DIS_FLUSH  BIT_4S          /* Disable Frame Flushing */
+#define MFF_ENA_TIST   BIT_3S          /* Enable  Time Stamp Gener */
+#define MFF_DIS_TIST   BIT_2S          /* Disable Time Stamp Gener */
+#define MFF_CLR_INTIST BIT_1S          /* Clear IRQ No Time Stamp */
+#define MFF_CLR_INSTAT BIT_0S          /* Clear IRQ No Status */
+
+#define MFF_RX_CTRL_DEF MFF_ENA_TIM_PAT
+
+/*     TX_MFF_CTRL1    16 bit  Transmit MAC FIFO Control Reg 1 */
+#define MFF_CLR_PERR   BIT_15S         /* Clear Parity Error IRQ */
+                                                               /* Bit 14:      reserved */
+#define MFF_ENA_PKT_REC        BIT_13S         /* Enable  Packet Recovery */
+#define MFF_DIS_PKT_REC BIT_12S                /* Disable Packet Recovery */
+/*     MFF_ENA_TIM_PAT  (see RX_MFF_CTRL1) Bit 11:     Enable  Timing Patch */
+/*     MFF_DIS_TIM_PAT  (see RX_MFF_CTRL1) Bit 10:     Disable Timing Patch */
+/*     MFF_ENA_ALM_FUL  (see RX_MFF_CTRL1) Bit  9:     Enable  Almost Full Sign */
+/*     MFF_DIS_ALM_FUL  (see RX_MFF_CTRL1) Bit  8:     Disable Almost Full Sign */
+#define MFF_ENA_W4E            BIT_7S          /* Enable  Wait for Empty */
+#define MFF_DIS_W4E            BIT_6S          /* Disable Wait for Empty */
+/*     MFF_ENA_FLUSH    (see RX_MFF_CTRL1) Bit  5:     Enable  Frame Flushing */
+/*     MFF_DIS_FLUSH    (see RX_MFF_CTRL1) Bit  4:     Disable Frame Flushing */
+#define MFF_ENA_LOOPB  BIT_3S          /* Enable  Loopback */
+#define MFF_DIS_LOOPB  BIT_2S          /* Disable Loopback */
+#define MFF_CLR_MAC_RST        BIT_1S          /* Clear XMAC Reset */
+#define MFF_SET_MAC_RST        BIT_0S          /* Set   XMAC Reset */
+
+#define MFF_TX_CTRL_DEF        (MFF_ENA_PKT_REC | MFF_ENA_TIM_PAT | MFF_ENA_FLUSH)
+
+/*     RX_MFF_TST2              8 bit  Receive MAC FIFO Test Register 2 */
+/*     TX_MFF_TST2              8 bit  Transmit MAC FIFO Test Register 2 */
+                                                               /* Bit 7:       reserved */
+#define MFF_WSP_T_ON   BIT_6S  /* Tx: Write Shadow Ptr TestOn */
+#define MFF_WSP_T_OFF  BIT_5S  /* Tx: Write Shadow Ptr TstOff */
+#define MFF_WSP_INC            BIT_4S  /* Tx: Write Shadow Ptr Increment */
+#define MFF_PC_DEC             BIT_3S  /* Packet Counter Decrement */
+#define MFF_PC_T_ON            BIT_2S  /* Packet Counter Test On */
+#define MFF_PC_T_OFF   BIT_1S  /* Packet Counter Test Off */
+#define MFF_PC_INC             BIT_0S  /* Packet Counter Increment */
+
+/*     RX_MFF_TST1              8 bit  Receive MAC FIFO Test Register 1 */
+/*     TX_MFF_TST1              8 bit  Transmit MAC FIFO Test Register 1 */
+                                       /* Bit 7:       reserved */
+#define MFF_WP_T_ON            BIT_6S  /* Write Pointer Test On */
+#define MFF_WP_T_OFF   BIT_5S  /* Write Pointer Test Off */
+#define MFF_WP_INC             BIT_4S  /* Write Pointer Increm */
+                                                       /* Bit 3:       reserved */
+#define MFF_RP_T_ON            BIT_2S  /* Read Pointer Test On */
+#define MFF_RP_T_OFF   BIT_1S  /* Read Pointer Test Off */
+#define MFF_RP_DEC             BIT_0S  /* Read Pointer Decrement */
+
+/*     RX_MFF_CTRL2     8 bit  Receive MAC FIFO Control Reg 2 */
+/*     TX_MFF_CTRL2     8 bit  Transmit MAC FIFO Control Reg 2 */
+                                                               /* Bit 7..4:    reserved */
+#define MFF_ENA_OP_MD  BIT_3S  /* Enable  Operation Mode */
+#define MFF_DIS_OP_MD  BIT_2S  /* Disable Operation Mode */
+#define MFF_RST_CLR            BIT_1S  /* Clear MAC FIFO Reset */
+#define MFF_RST_SET            BIT_0S  /* Set   MAC FIFO Reset */
+
+
+/*     Link LED Counter Registers (GENESIS only) */
+
+/*     RX_LED_CTRL              8 bit  Receive LED Cnt Control Reg */
+/*     TX_LED_CTRL              8 bit  Transmit LED Cnt Control Reg */
+/*     LNK_SYNC_CTRL    8 bit  Link Sync Cnt Control Register */
+                                                       /* Bit 7.. 3:   reserved */
+#define LED_START              BIT_2S  /* Start Timer */
+#define LED_STOP               BIT_1S  /* Stop Timer */
+#define LED_STATE              BIT_0S  /* Rx/Tx: LED State, 1=LED on */
+#define LED_CLR_IRQ            BIT_0S  /* Lnk:         Clear Link IRQ */
+
+/*     RX_LED_TST               8 bit  Receive LED Cnt Test Register */
+/*     TX_LED_TST               8 bit  Transmit LED Cnt Test Register */
+/*     LNK_SYNC_TST     8 bit  Link Sync Cnt Test Register */
+                                                       /* Bit 7.. 3:   reserved */
+#define LED_T_ON               BIT_2S  /* LED Counter Test mode On */
+#define LED_T_OFF              BIT_1S  /* LED Counter Test mode Off */
+#define LED_T_STEP             BIT_0S  /* LED Counter Step */
+
+/*     LNK_LED_REG              8 bit  Link LED Register */
+                                                               /* Bit 7.. 6:   reserved */
+#define LED_BLK_ON             BIT_5S  /* Link LED Blinking On */
+#define LED_BLK_OFF            BIT_4S  /* Link LED Blinking Off */
+#define LED_SYNC_ON            BIT_3S  /* Use Sync Wire to switch LED */
+#define LED_SYNC_OFF   BIT_2S  /* Disable Sync Wire Input */
+#define LED_ON                 BIT_1S  /* switch LED on */
+#define LED_OFF                        BIT_0S  /* switch LED off */
+
+/*     Receive and Transmit GMAC FIFO Registers (YUKON only) */
+
+/*     RX_GMF_EA               32 bit  Rx GMAC FIFO End Address */
+/*     RX_GMF_AF_THR   32 bit  Rx GMAC FIFO Almost Full Thresh. */
+/*     RX_GMF_WP               32 bit  Rx GMAC FIFO Write Pointer */
+/*     RX_GMF_WLEV             32 bit  Rx GMAC FIFO Write Level */
+/*     RX_GMF_RP               32 bit  Rx GMAC FIFO Read Pointer */
+/*     RX_GMF_RLEV             32 bit  Rx GMAC FIFO Read Level */
+/*     TX_GMF_EA               32 bit  Tx GMAC FIFO End Address */
+/*     TX_GMF_AE_THR   32 bit  Tx GMAC FIFO Almost Empty Thresh.*/
+/*     TX_GMF_WP               32 bit  Tx GMAC FIFO Write Pointer */
+/*     TX_GMF_WSP              32 bit  Tx GMAC FIFO Write Shadow Ptr. */
+/*     TX_GMF_WLEV             32 bit  Tx GMAC FIFO Write Level */
+/*     TX_GMF_RP               32 bit  Tx GMAC FIFO Read Pointer */
+/*     TX_GMF_RSTP             32 bit  Tx GMAC FIFO Restart Pointer */
+/*     TX_GMF_RLEV             32 bit  Tx GMAC FIFO Read Level */
+
+/*     RX_GMF_CTRL_T   32 bit  Rx GMAC FIFO Control/Test */
+                                               /* Bits 31..15: reserved */
+#define GMF_WP_TST_ON  BIT_14          /* Write Pointer Test On */
+#define GMF_WP_TST_OFF BIT_13          /* Write Pointer Test Off */
+#define GMF_WP_STEP            BIT_12          /* Write Pointer Step/Increment */
+                                               /* Bit 11:      reserved */
+#define GMF_RP_TST_ON  BIT_10          /* Read Pointer Test On */
+#define GMF_RP_TST_OFF BIT_9           /* Read Pointer Test Off */
+#define GMF_RP_STEP            BIT_8           /* Read Pointer Step/Increment */
+#define GMF_RX_F_FL_ON BIT_7           /* Rx FIFO Flush Mode On */
+#define GMF_RX_F_FL_OFF        BIT_6           /* Rx FIFO Flush Mode Off */
+#define GMF_CLI_RX_FO  BIT_5           /* Clear IRQ Rx FIFO Overrun */
+#define GMF_CLI_RX_FC  BIT_4           /* Clear IRQ Rx Frame Complete */
+#define GMF_OPER_ON            BIT_3           /* Operational Mode On */
+#define GMF_OPER_OFF   BIT_2           /* Operational Mode Off */
+#define GMF_RST_CLR            BIT_1           /* Clear GMAC FIFO Reset */
+#define GMF_RST_SET            BIT_0           /* Set   GMAC FIFO Reset */
+
+/*     TX_GMF_CTRL_T   32 bit  Tx GMAC FIFO Control/Test */
+                                               /* Bits 31..19: reserved */
+#define GMF_WSP_TST_ON BIT_18          /* Write Shadow Pointer Test On */
+#define GMF_WSP_TST_OFF        BIT_17          /* Write Shadow Pointer Test Off */
+#define GMF_WSP_STEP   BIT_16          /* Write Shadow Pointer Step/Increment */
+                                               /* Bits 15..7: same as for RX_GMF_CTRL_T */
+#define GMF_CLI_TX_FU  BIT_6           /* Clear IRQ Tx FIFO Underrun */
+#define GMF_CLI_TX_FC  BIT_5           /* Clear IRQ Tx Frame Complete */
+#define GMF_CLI_TX_PE  BIT_4           /* Clear IRQ Tx Parity Error */
+                                               /* Bits 3..0: same as for RX_GMF_CTRL_T */
+
+#define GMF_RX_CTRL_DEF                (GMF_OPER_ON | GMF_RX_F_FL_ON)
+#define GMF_TX_CTRL_DEF                GMF_OPER_ON
+
+#define RX_GMF_FL_THR_DEF      0x0a    /* Rx GMAC FIFO Flush Threshold default */
+
+/*     GMAC_TI_ST_CTRL           8 bit Time Stamp Timer Ctrl Reg (YUKON only) */
+                                                               /* Bit 7.. 3:   reserved */
+#define GMT_ST_START   BIT_2S          /* Start Time Stamp Timer */
+#define GMT_ST_STOP            BIT_1S          /* Stop  Time Stamp Timer */
+#define GMT_ST_CLR_IRQ BIT_0S          /* Clear Time Stamp Timer IRQ */
+
+/*     GMAC_CTRL               32 bit  GMAC Control Reg (YUKON only) */
+                                               /* Bits 31.. 8: reserved */
+#define GMC_H_BURST_ON BIT_7           /* Half Duplex Burst Mode On */
+#define GMC_H_BURST_OFF        BIT_6           /* Half Duplex Burst Mode Off */
+#define GMC_F_LOOPB_ON BIT_5           /* FIFO Loopback On */
+#define GMC_F_LOOPB_OFF        BIT_4           /* FIFO Loopback Off */
+#define GMC_PAUSE_ON   BIT_3           /* Pause On */
+#define GMC_PAUSE_OFF  BIT_2           /* Pause Off */
+#define GMC_RST_CLR            BIT_1           /* Clear GMAC Reset */
+#define GMC_RST_SET            BIT_0           /* Set   GMAC Reset */
+
+/*     GPHY_CTRL               32 bit  GPHY Control Reg (YUKON only) */
+                                               /* Bits 31..29: reserved */
+#define GPC_SEL_BDT            BIT_28  /* Select Bi-Dir. Transfer for MDC/MDIO */
+#define GPC_INT_POL_HI BIT_27  /* IRQ Polarity is Active HIGH */
+#define GPC_75_OHM             BIT_26  /* Use 75 Ohm Termination instead of 50 */
+#define GPC_DIS_FC             BIT_25  /* Disable Automatic Fiber/Copper Detection */
+#define GPC_DIS_SLEEP  BIT_24  /* Disable Energy Detect */
+#define GPC_HWCFG_M_3  BIT_23  /* HWCFG_MODE[3] */
+#define GPC_HWCFG_M_2  BIT_22  /* HWCFG_MODE[2] */
+#define GPC_HWCFG_M_1  BIT_21  /* HWCFG_MODE[1] */
+#define GPC_HWCFG_M_0  BIT_20  /* HWCFG_MODE[0] */
+#define GPC_ANEG_0             BIT_19  /* ANEG[0] */
+#define GPC_ENA_XC             BIT_18  /* Enable MDI crossover */
+#define GPC_DIS_125            BIT_17  /* Disable 125 MHz clock */
+#define GPC_ANEG_3             BIT_16  /* ANEG[3] */
+#define GPC_ANEG_2             BIT_15  /* ANEG[2] */
+#define GPC_ANEG_1             BIT_14  /* ANEG[1] */
+#define GPC_ENA_PAUSE  BIT_13  /* Enable Pause (SYM_OR_REM) */
+#define GPC_PHYADDR_4  BIT_12  /* Bit 4 of Phy Addr */
+#define GPC_PHYADDR_3  BIT_11  /* Bit 3 of Phy Addr */
+#define GPC_PHYADDR_2  BIT_10  /* Bit 2 of Phy Addr */
+#define GPC_PHYADDR_1  BIT_9   /* Bit 1 of Phy Addr */
+#define GPC_PHYADDR_0  BIT_8   /* Bit 0 of Phy Addr */
+                                               /* Bits  7..2:  reserved */
+#define GPC_RST_CLR            BIT_1   /* Clear GPHY Reset */
+#define GPC_RST_SET            BIT_0   /* Set   GPHY Reset */
+
+#define GPC_HWCFG_GMII_COP     (GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | \
+                                                        GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
+
+#define GPC_HWCFG_GMII_FIB     (                                GPC_HWCFG_M_2 | \
+                                                        GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
+
+#define GPC_ANEG_ADV_ALL_M     (GPC_ANEG_3 | GPC_ANEG_2 | \
+                                                        GPC_ANEG_1 | GPC_ANEG_0)
+
+/* forced speed and duplex mode (don't mix with other ANEG bits) */
+#define GPC_FRC10MBIT_HALF     0
+#define GPC_FRC10MBIT_FULL     GPC_ANEG_0
+#define GPC_FRC100MBIT_HALF    GPC_ANEG_1
+#define GPC_FRC100MBIT_FULL    (GPC_ANEG_0 | GPC_ANEG_1)
+
+/* auto-negotiation with limited advertised speeds */
+/* mix only with master/slave settings (for copper) */
+#define GPC_ADV_1000_HALF      GPC_ANEG_2
+#define GPC_ADV_1000_FULL      GPC_ANEG_3
+#define GPC_ADV_ALL                    (GPC_ANEG_2 | GPC_ANEG_3)
+
+/* master/slave settings */
+/* only for copper with 1000 Mbps */
+#define GPC_FORCE_MASTER       0
+#define GPC_FORCE_SLAVE                GPC_ANEG_0
+#define GPC_PREF_MASTER                GPC_ANEG_1
+#define GPC_PREF_SLAVE         (GPC_ANEG_1 | GPC_ANEG_0)
+
+/*     GMAC_IRQ_SRC     8 bit  GMAC Interrupt Source Reg (YUKON only) */
+/*     GMAC_IRQ_MSK     8 bit  GMAC Interrupt Mask   Reg (YUKON only) */
+#define GM_IS_TX_CO_OV BIT_5           /* Transmit Counter Overflow IRQ */
+#define GM_IS_RX_CO_OV BIT_4           /* Receive Counter Overflow IRQ */
+#define GM_IS_TX_FF_UR BIT_3           /* Transmit FIFO Underrun */
+#define GM_IS_TX_COMPL BIT_2           /* Frame Transmission Complete */
+#define GM_IS_RX_FF_OR BIT_1           /* Receive FIFO Overrun */
+#define GM_IS_RX_COMPL BIT_0           /* Frame Reception Complete */
+
+#define GMAC_DEF_MSK   (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \
+                                               GM_IS_TX_FF_UR)
+
+/*     GMAC_LINK_CTRL          16 bit  GMAC Link Control Reg (YUKON only) */
+                                               /* Bits 15.. 2: reserved */
+#define GMLC_RST_CLR   BIT_1S          /* Clear GMAC Link Reset */
+#define GMLC_RST_SET   BIT_0S          /* Set   GMAC Link Reset */
+
+
+/*     WOL_CTRL_STAT           16 bit  WOL Control/Status Reg */
+#define WOL_CTL_LINK_CHG_OCC                   BIT_15S
+#define WOL_CTL_MAGIC_PKT_OCC                  BIT_14S
+#define WOL_CTL_PATTERN_OCC                            BIT_13S
+
+#define WOL_CTL_CLEAR_RESULT                   BIT_12S
+
+#define WOL_CTL_ENA_PME_ON_LINK_CHG            BIT_11S
+#define WOL_CTL_DIS_PME_ON_LINK_CHG            BIT_10S
+#define WOL_CTL_ENA_PME_ON_MAGIC_PKT   BIT_9S
+#define WOL_CTL_DIS_PME_ON_MAGIC_PKT   BIT_8S
+#define WOL_CTL_ENA_PME_ON_PATTERN             BIT_7S
+#define WOL_CTL_DIS_PME_ON_PATTERN             BIT_6S
+
+#define WOL_CTL_ENA_LINK_CHG_UNIT              BIT_5S
+#define WOL_CTL_DIS_LINK_CHG_UNIT              BIT_4S
+#define WOL_CTL_ENA_MAGIC_PKT_UNIT             BIT_3S
+#define WOL_CTL_DIS_MAGIC_PKT_UNIT             BIT_2S
+#define WOL_CTL_ENA_PATTERN_UNIT               BIT_1S
+#define WOL_CTL_DIS_PATTERN_UNIT               BIT_0S
+
+#define WOL_CTL_DEFAULT                                \
+       (WOL_CTL_DIS_PME_ON_LINK_CHG |  \
+       WOL_CTL_DIS_PME_ON_PATTERN |    \
+       WOL_CTL_DIS_PME_ON_MAGIC_PKT |  \
+       WOL_CTL_DIS_LINK_CHG_UNIT |             \
+       WOL_CTL_DIS_PATTERN_UNIT |              \
+       WOL_CTL_DIS_MAGIC_PKT_UNIT)
+
+/*     WOL_MATCH_CTL            8 bit  WOL Match Control Reg */
+#define WOL_CTL_PATT_ENA(x)                            (BIT_0 << (x))
+
+#define SK_NUM_WOL_PATTERN             7
+#define SK_PATTERN_PER_WORD            4
+#define SK_BITMASK_PATTERN             7
+#define SK_POW_PATTERN_LENGTH  128
+
+#define WOL_LENGTH_MSK         0x7f
+#define WOL_LENGTH_SHIFT       8
+
+
+/* Receive and Transmit Descriptors ******************************************/
+
+/* Transmit Descriptor struct */
+typedef        struct s_HwTxd {
+       SK_U32 volatile TxCtrl; /* Transmit Buffer Control Field */
+       SK_U32  TxNext;                 /* Physical Address Pointer to the next TxD */
+       SK_U32  TxAdrLo;                /* Physical Tx Buffer Address lower dword */
+       SK_U32  TxAdrHi;                /* Physical Tx Buffer Address upper dword */
+       SK_U32  TxStat;                 /* Transmit Frame Status Word */
+#ifndef        SK_USE_REV_DESC
+       SK_U16  TxTcpOffs;              /* TCP Checksum Calculation Start Value */
+       SK_U16  TxRes1;                 /* 16 bit reserved field */
+       SK_U16  TxTcpWp;                /* TCP Checksum Write Position */
+       SK_U16  TxTcpSp;                /* TCP Checksum Calculation Start Position */
+#else  /* SK_USE_REV_DESC */
+       SK_U16  TxRes1;                 /* 16 bit reserved field */
+       SK_U16  TxTcpOffs;              /* TCP Checksum Calculation Start Value */
+       SK_U16  TxTcpSp;                /* TCP Checksum Calculation Start Position */
+       SK_U16  TxTcpWp;                /* TCP Checksum Write Position */
+#endif /* SK_USE_REV_DESC */
+       SK_U32  TxRes2;                 /* 32 bit reserved field */
+} SK_HWTXD;
+
+/* Receive Descriptor struct */
+typedef        struct s_HwRxd {
+       SK_U32 volatile RxCtrl; /* Receive Buffer Control Field */
+       SK_U32  RxNext;                 /* Physical Address Pointer to the next RxD */
+       SK_U32  RxAdrLo;                /* Physical Rx Buffer Address lower dword */
+       SK_U32  RxAdrHi;                /* Physical Rx Buffer Address upper dword */
+       SK_U32  RxStat;                 /* Receive Frame Status Word */
+       SK_U32  RxTiSt;                 /* Receive Time Stamp (from XMAC on GENESIS) */
+#ifndef        SK_USE_REV_DESC
+       SK_U16  RxTcpSum1;              /* TCP Checksum 1 */
+       SK_U16  RxTcpSum2;              /* TCP Checksum 2 */
+       SK_U16  RxTcpSp1;               /* TCP Checksum Calculation Start Position 1 */
+       SK_U16  RxTcpSp2;               /* TCP Checksum Calculation Start Position 2 */
+#else  /* SK_USE_REV_DESC */
+       SK_U16  RxTcpSum2;              /* TCP Checksum 2 */
+       SK_U16  RxTcpSum1;              /* TCP Checksum 1 */
+       SK_U16  RxTcpSp2;               /* TCP Checksum Calculation Start Position 2 */
+       SK_U16  RxTcpSp1;               /* TCP Checksum Calculation Start Position 1 */
+#endif /* SK_USE_REV_DESC */
+} SK_HWRXD;
+
+/*
+ * Drivers which use the reverse descriptor feature (PCI_OUR_REG_2)
+ * should set the define SK_USE_REV_DESC.
+ * Structures are 'normaly' not endianess dependent. But in
+ * this case the SK_U16 fields are bound to bit positions inside the
+ * descriptor. RxTcpSum1 e.g. must start at bit 0 within the 6.th DWord.
+ * The bit positions inside a DWord are of course endianess dependent and
+ * swaps if the DWord is swapped by the hardware.
+ */
+
+
+/* Descriptor Bit Definition */
+/*     TxCtrl          Transmit Buffer Control Field */
+/*     RxCtrl          Receive  Buffer Control Field */
+#define BMU_OWN                        BIT_31  /* OWN bit: 0=host/1=BMU */
+#define BMU_STF                        BIT_30  /* Start of Frame */
+#define BMU_EOF                        BIT_29  /* End of Frame */
+#define BMU_IRQ_EOB            BIT_28  /* Req "End of Buffer" IRQ */
+#define BMU_IRQ_EOF            BIT_27  /* Req "End of Frame" IRQ */
+/* TxCtrl specific bits */
+#define BMU_STFWD              BIT_26  /* (Tx) Store & Forward Frame */
+#define BMU_NO_FCS             BIT_25  /* (Tx) Disable MAC FCS (CRC) generation */
+#define BMU_SW                 BIT_24  /* (Tx) 1 bit res. for SW use */
+/* RxCtrl specific bits */
+#define BMU_DEV_0              BIT_26  /* (Rx) Transfer data to Dev0 */
+#define BMU_STAT_VAL   BIT_25  /* (Rx) Rx Status Valid */
+#define BMU_TIST_VAL   BIT_24  /* (Rx) Rx TimeStamp Valid */
+                                                               /* Bit 23..16:  BMU Check Opcodes */
+#define BMU_CHECK              (0x55L<<16)     /* Default BMU check */
+#define BMU_TCP_CHECK  (0x56L<<16)     /* Descr with TCP ext */
+#define BMU_UDP_CHECK  (0x57L<<16)     /* Descr with UDP ext (YUKON only) */
+#define BMU_BBC                        0xFFFFL /* Bit 15.. 0:  Buffer Byte Counter */
+
+/*     TxStat          Transmit Frame Status Word */
+/*     RxStat          Receive Frame Status Word */
+/*
+ *Note: TxStat is reserved for ASIC loopback mode only
+ *
+ *     The Bits of the Status words are defined in xmac_ii.h
+ *     (see XMR_FS bits)
+ */
+
+/* other defines *************************************************************/
+
+/*
+ * FlashProm specification
+ */
+#define MAX_PAGES      0x20000L        /* Every byte has a single page */
+#define MAX_FADDR      1                       /* 1 byte per page */
+#define SKFDDI_PSZ     8                       /* address PROM size */
+
+/* macros ********************************************************************/
+
+/*
+ * Receive and Transmit Queues
+ */
+#define Q_R1   0x0000          /* Receive Queue 1 */
+#define Q_R2   0x0080          /* Receive Queue 2 */
+#define Q_XS1  0x0200          /* Synchronous Transmit Queue 1 */
+#define Q_XA1  0x0280          /* Asynchronous Transmit Queue 1 */
+#define Q_XS2  0x0300          /* Synchronous Transmit Queue 2 */
+#define Q_XA2  0x0380          /* Asynchronous Transmit Queue 2 */
+
+/*
+ *     Macro Q_ADDR()
+ *
+ *     Use this macro to access the Receive and Transmit Queue Registers.
+ *
+ * para:
+ *     Queue   Queue to access.
+ *                             Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2
+ *     Offs    Queue register offset.
+ *                             Values: Q_D, Q_DA_L ... Q_T2, Q_T3
+ *
+ * usage       SK_IN32(pAC, Q_ADDR(Q_R2, Q_BC), pVal)
+ */
+#define Q_ADDR(Queue, Offs)    (B8_Q_REGS + (Queue) + (Offs))
+
+/*
+ *     Macro RB_ADDR()
+ *
+ *     Use this macro to access the RAM Buffer Registers.
+ *
+ * para:
+ *     Queue   Queue to access.
+ *                             Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2
+ *     Offs    Queue register offset.
+ *                             Values: RB_START, RB_END ... RB_LEV, RB_CTRL
+ *
+ * usage       SK_IN32(pAC, RB_ADDR(Q_R2, RB_RP), pVal)
+ */
+#define RB_ADDR(Queue, Offs)   (B16_RAM_REGS + (Queue) + (Offs))
+
+
+/*
+ * MAC Related Registers
+ */
+#define MAC_1          0       /* belongs to the port near the slot */
+#define MAC_2          1       /* belongs to the port far away from the slot */
+
+/*
+ *     Macro MR_ADDR()
+ *
+ *     Use this macro to access a MAC Related Registers inside the ASIC.
+ *
+ * para:
+ *     Mac             MAC to access.
+ *                             Values: MAC_1, MAC_2
+ *     Offs    MAC register offset.
+ *                             Values: RX_MFF_EA, RX_MFF_WP ... LNK_LED_REG,
+ *                                             TX_MFF_EA, TX_MFF_WP ... TX_LED_TST
+ *
+ * usage       SK_IN32(pAC, MR_ADDR(MAC_1, TX_MFF_EA), pVal)
+ */
+#define MR_ADDR(Mac, Offs)     (((Mac) << 7) + (Offs))
+
+#ifdef SK_LITTLE_ENDIAN
+#define XM_WORD_LO     0
+#define XM_WORD_HI     1
+#else  /* !SK_LITTLE_ENDIAN */
+#define XM_WORD_LO     1
+#define XM_WORD_HI     0
+#endif /* !SK_LITTLE_ENDIAN */
+
+
+/*
+ * macros to access the XMAC (GENESIS only)
+ *
+ * XM_IN16(),          to read a 16 bit register (e.g. XM_MMU_CMD)
+ * XM_OUT16(),         to write a 16 bit register (e.g. XM_MMU_CMD)
+ * XM_IN32(),          to read a 32 bit register (e.g. XM_TX_EV_CNT)
+ * XM_OUT32(),         to write a 32 bit register (e.g. XM_TX_EV_CNT)
+ * XM_INADDR(),                to read a network address register (e.g. XM_SRC_CHK)
+ * XM_OUTADDR(),       to write a network address register (e.g. XM_SRC_CHK)
+ * XM_INHASH(),                to read the XM_HSM_CHK register
+ * XM_OUTHASH()                to write the XM_HSM_CHK register
+ *
+ * para:
+ *     Mac             XMAC to access          values: MAC_1 or MAC_2
+ *     IoC             I/O context needed for SK I/O macros
+ *     Reg             XMAC Register to read or write
+ *     (p)Val  Value or pointer to the value which should be read or written
+ *
+ * usage:      XM_OUT16(IoC, MAC_1, XM_MMU_CMD, Value);
+ */
+
+#define XMA(Mac, Reg)                                                                  \
+       ((BASE_XMAC_1 + (Mac) * (BASE_XMAC_2 - BASE_XMAC_1)) | ((Reg) << 1))
+
+#define XM_IN16(IoC, Mac, Reg, pVal)                                   \
+       SK_IN16((IoC), XMA((Mac), (Reg)), (pVal))
+
+#define XM_OUT16(IoC, Mac, Reg, Val)                                   \
+       SK_OUT16((IoC), XMA((Mac), (Reg)), (Val))
+
+#define XM_IN32(IoC, Mac, Reg, pVal) {                                 \
+       SK_IN16((IoC), XMA((Mac), (Reg)),                                       \
+               (SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_LO]);             \
+       SK_IN16((IoC), XMA((Mac), (Reg+2)),                                     \
+               (SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_HI]);             \
+}
+
+#define XM_OUT32(IoC, Mac, Reg, Val) {                                                                         \
+       SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL));                  \
+       SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)(((Val) >> 16) & 0xffffL));\
+}
+
+/* Remember: we are always writing to / reading from LITTLE ENDIAN memory */
+
+#define XM_INADDR(IoC, Mac, Reg, pVal) {                               \
+       SK_U16  Word;                                                                           \
+       SK_U8   *pByte;                                                                         \
+       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
+       SK_IN16((IoC), XMA((Mac), (Reg)), &Word);                       \
+       pByte[0] = (SK_U8)(Word  & 0x00ff);                                     \
+       pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+       SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word);                     \
+       pByte[2] = (SK_U8)(Word  & 0x00ff);                                     \
+       pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+       SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word);                     \
+       pByte[4] = (SK_U8)(Word  & 0x00ff);                                     \
+       pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+}
+
+#define XM_OUTADDR(IoC, Mac, Reg, pVal) {                              \
+       SK_U8   *pByte;                                                                         \
+       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
+       SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)                     \
+               (((SK_U16)(pByte[0]) & 0x00ff) |                                \
+               (((SK_U16)(pByte[1]) << 8) & 0xff00)));                 \
+       SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)           \
+               (((SK_U16)(pByte[2]) & 0x00ff) |                                \
+               (((SK_U16)(pByte[3]) << 8) & 0xff00)));                 \
+       SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16)           \
+               (((SK_U16)(pByte[4]) & 0x00ff) |                                \
+               (((SK_U16)(pByte[5]) << 8) & 0xff00)));                 \
+}
+
+#define XM_INHASH(IoC, Mac, Reg, pVal) {                               \
+       SK_U16  Word;                                                                           \
+       SK_U8   *pByte;                                                                         \
+       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
+       SK_IN16((IoC), XMA((Mac), (Reg)), &Word);                       \
+       pByte[0] = (SK_U8)(Word  & 0x00ff);                                     \
+       pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+       SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word);                     \
+       pByte[2] = (SK_U8)(Word  & 0x00ff);                                     \
+       pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+       SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word);                     \
+       pByte[4] = (SK_U8)(Word  & 0x00ff);                                     \
+       pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+       SK_IN16((IoC), XMA((Mac), (Reg+6)), &Word);                     \
+       pByte[6] = (SK_U8)(Word  & 0x00ff);                                     \
+       pByte[7] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+}
+
+#define XM_OUTHASH(IoC, Mac, Reg, pVal) {                              \
+       SK_U8   *pByte;                                                                         \
+       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
+       SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)                     \
+               (((SK_U16)(pByte[0]) & 0x00ff)|                                 \
+               (((SK_U16)(pByte[1]) << 8) & 0xff00)));                 \
+       SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)           \
+               (((SK_U16)(pByte[2]) & 0x00ff)|                                 \
+               (((SK_U16)(pByte[3]) << 8) & 0xff00)));                 \
+       SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16)           \
+               (((SK_U16)(pByte[4]) & 0x00ff)|                                 \
+               (((SK_U16)(pByte[5]) << 8) & 0xff00)));                 \
+       SK_OUT16((IoC), XMA((Mac), (Reg+6)), (SK_U16)           \
+               (((SK_U16)(pByte[6]) & 0x00ff)|                                 \
+               (((SK_U16)(pByte[7]) << 8) & 0xff00)));                 \
+}
+
+/*
+ * macros to access the GMAC (YUKON only)
+ *
+ * GM_IN16(),          to read  a 16 bit register (e.g. GM_GP_STAT)
+ * GM_OUT16(),         to write a 16 bit register (e.g. GM_GP_CTRL)
+ * GM_IN32(),          to read  a 32 bit register (e.g. GM_)
+ * GM_OUT32(),         to write a 32 bit register (e.g. GM_)
+ * GM_INADDR(),                to read  a network address register (e.g. GM_SRC_ADDR_1L)
+ * GM_OUTADDR(),       to write a network address register (e.g. GM_SRC_ADDR_2L)
+ * GM_INHASH(),                to read  the GM_MC_ADDR_H1 register
+ * GM_OUTHASH()                to write the GM_MC_ADDR_H1 register
+ *
+ * para:
+ *     Mac             GMAC to access          values: MAC_1 or MAC_2
+ *     IoC             I/O context needed for SK I/O macros
+ *     Reg             GMAC Register to read or write
+ *     (p)Val  Value or pointer to the value which should be read or written
+ *
+ * usage:      GM_OUT16(IoC, MAC_1, GM_GP_CTRL, Value);
+ */
+
+#define GMA(Mac, Reg)                                                                  \
+       ((BASE_GMAC_1 + (Mac) * (BASE_GMAC_2 - BASE_GMAC_1)) | (Reg))
+
+#define GM_IN16(IoC, Mac, Reg, pVal)                                   \
+       SK_IN16((IoC), GMA((Mac), (Reg)), (pVal))
+
+#define GM_OUT16(IoC, Mac, Reg, Val)                                   \
+       SK_OUT16((IoC), GMA((Mac), (Reg)), (Val))
+
+#define GM_IN32(IoC, Mac, Reg, pVal) {                                 \
+       SK_IN16((IoC), GMA((Mac), (Reg)),                                       \
+               (SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_LO]);             \
+       SK_IN16((IoC), GMA((Mac), (Reg+4)),                                     \
+               (SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_HI]);             \
+}
+
+#define GM_OUT32(IoC, Mac, Reg, Val) {                                                                         \
+       SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL));                  \
+       SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)(((Val) >> 16) & 0xffffL));\
+}
+
+#define GM_INADDR(IoC, Mac, Reg, pVal) {                               \
+       SK_U16  Word;                                                                           \
+       SK_U8   *pByte;                                                                         \
+       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
+       SK_IN16((IoC), GMA((Mac), (Reg)), &Word);                       \
+       pByte[0] = (SK_U8)(Word  & 0x00ff);                                     \
+       pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+       SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word);                     \
+       pByte[2] = (SK_U8)(Word  & 0x00ff);                                     \
+       pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+       SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word);                     \
+       pByte[4] = (SK_U8)(Word  & 0x00ff);                                     \
+       pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+}
+
+#define GM_OUTADDR(IoC, Mac, Reg, pVal) {                              \
+       SK_U8   *pByte;                                                                         \
+       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
+       SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)                     \
+               (((SK_U16)(pByte[0]) & 0x00ff) |                                \
+               (((SK_U16)(pByte[1]) << 8) & 0xff00)));                 \
+       SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)           \
+               (((SK_U16)(pByte[2]) & 0x00ff) |                                \
+               (((SK_U16)(pByte[3]) << 8) & 0xff00)));                 \
+       SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16)           \
+               (((SK_U16)(pByte[4]) & 0x00ff) |                                \
+               (((SK_U16)(pByte[5]) << 8) & 0xff00)));                 \
+}
+
+#define GM_INHASH(IoC, Mac, Reg, pVal) {                               \
+       SK_U16  Word;                                                                           \
+       SK_U8   *pByte;                                                                         \
+       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
+       SK_IN16((IoC), GMA((Mac), (Reg)), &Word);                       \
+       pByte[0] = (SK_U8)(Word  & 0x00ff);                                     \
+       pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+       SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word);                     \
+       pByte[2] = (SK_U8)(Word  & 0x00ff);                                     \
+       pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+       SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word);                     \
+       pByte[4] = (SK_U8)(Word  & 0x00ff);                                     \
+       pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+       SK_IN16((IoC), GMA((Mac), (Reg+12)), &Word);            \
+       pByte[6] = (SK_U8)(Word  & 0x00ff);                                     \
+       pByte[7] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+}
+
+#define GM_OUTHASH(IoC, Mac, Reg, pVal) {                              \
+       SK_U8   *pByte;                                                                         \
+       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
+       SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)                     \
+               (((SK_U16)(pByte[0]) & 0x00ff)|                                 \
+               (((SK_U16)(pByte[1]) << 8) & 0xff00)));                 \
+       SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)           \
+               (((SK_U16)(pByte[2]) & 0x00ff)|                                 \
+               (((SK_U16)(pByte[3]) << 8) & 0xff00)));                 \
+       SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16)           \
+               (((SK_U16)(pByte[4]) & 0x00ff)|                                 \
+               (((SK_U16)(pByte[5]) << 8) & 0xff00)));                 \
+       SK_OUT16((IoC), GMA((Mac), (Reg+12)), (SK_U16)          \
+               (((SK_U16)(pByte[6]) & 0x00ff)|                                 \
+               (((SK_U16)(pByte[7]) << 8) & 0xff00)));                 \
+}
+
+/*
+ * Different MAC Types
+ */
+#define SK_MAC_XMAC            0       /* Xaqti XMAC II */
+#define SK_MAC_GMAC            1       /* Marvell GMAC */
+
+/*
+ * Different PHY Types
+ */
+#define SK_PHY_XMAC                    0       /* integrated in XMAC II */
+#define SK_PHY_BCOM                    1       /* Broadcom BCM5400 */
+#define SK_PHY_LONE                    2       /* Level One LXT1000 */
+#define SK_PHY_NAT                     3       /* National DP83891 */
+#define SK_PHY_MARV_COPPER     4       /* Marvell 88E1011S */
+#define SK_PHY_MARV_FIBER      5       /* Marvell 88E1011S working on fiber */
+
+/*
+ * PHY addresses (bits 12..8 of PHY address reg)
+ */
+#define PHY_ADDR_XMAC  (0<<8)
+#define PHY_ADDR_BCOM  (1<<8)
+#define PHY_ADDR_LONE  (3<<8)
+#define PHY_ADDR_NAT   (0<<8)
+
+/* GPHY address (bits 15..11 of SMI control reg) */
+#define PHY_ADDR_MARV  0
+
+/*
+ * macros to access the PHY
+ *
+ * PHY_READ()          read a 16 bit value from the PHY
+ * PHY_WRITE()         write a 16 bit value to the PHY
+ *
+ * para:
+ *     IoC             I/O context needed for SK I/O macros
+ *     pPort   Pointer to port struct for PhyAddr
+ *     Mac             XMAC to access          values: MAC_1 or MAC_2
+ *     PhyReg  PHY Register to read or write
+ *     (p)Val  Value or pointer to the value which should be read or
+ *                     written.
+ *
+ * usage:      PHY_READ(IoC, pPort, MAC_1, PHY_CTRL, Value);
+ * Warning: a PHY_READ on an uninitialized PHY (PHY still in reset) never
+ *          comes back. This is checked in DEBUG mode.
+ */
+#ifndef DEBUG
+#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) {                                              \
+       SK_U16 Mmu;                                                                                                             \
+                                                                                                                                               \
+       XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr);       \
+       XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));                                                     \
+       if ((pPort)->PhyType != SK_PHY_XMAC) {                                                          \
+               do {                                                                                                                    \
+                       XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);                                        \
+               } while ((Mmu & XM_MMU_PHY_RDY) == 0);                                                  \
+               XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));                                             \
+       }                                                                                                                                       \
+}
+#else
+#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) {                                              \
+       SK_U16 Mmu;                                                                                                             \
+       int __i = 0;                                                                                                            \
+                                                                                                                                               \
+       XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr);       \
+       XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));                                                     \
+       if ((pPort)->PhyType != SK_PHY_XMAC) {                                                          \
+               do {                                                                                                                    \
+                       XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);                                        \
+                       __i++;                                                                                                          \
+                       if (__i > 100000) {                                                                                     \
+                               SK_DBG_PRINTF("*****************************\n");               \
+                               SK_DBG_PRINTF("PHY_READ on uninitialized PHY\n");               \
+                               SK_DBG_PRINTF("*****************************\n");               \
+                               break;                                                                                                  \
+                       }                                                                                                                       \
+               } while ((Mmu & XM_MMU_PHY_RDY) == 0);                                                  \
+               XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));                                             \
+       }                                                                                                                                       \
+}
+#endif /* DEBUG */
+
+#define PHY_WRITE(IoC, pPort, Mac, PhyReg, Val) {                                              \
+       SK_U16 Mmu;                                                                                                                     \
+                                                                                                                                               \
+       if ((pPort)->PhyType != SK_PHY_XMAC) {                                                          \
+               do {                                                                                                                    \
+                       XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);                                        \
+               } while ((Mmu & XM_MMU_PHY_BUSY) != 0);                                                 \
+       }                                                                                                                                       \
+       XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr);       \
+       XM_OUT16((IoC), (Mac), XM_PHY_DATA, (Val));                                                     \
+       if ((pPort)->PhyType != SK_PHY_XMAC) {                                                          \
+               do {                                                                                                                    \
+                       XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);                                        \
+               } while ((Mmu & XM_MMU_PHY_BUSY) != 0);                                                 \
+       }                                                                                                                                       \
+}
+
+/*
+ *     Macro PCI_C()
+ *
+ *     Use this macro to access PCI config register from the I/O space.
+ *
+ * para:
+ *     Addr    PCI configuration register to access.
+ *                     Values: PCI_VENDOR_ID ... PCI_VPD_ADR_REG,
+ *
+ * usage       SK_IN16(pAC, PCI_C(PCI_VENDOR_ID), pVal);
+ */
+#define PCI_C(Addr)    (B7_CFG_SPC + (Addr))   /* PCI Config Space */
+
+/*
+ *     Macro SK_HW_ADDR(Base, Addr)
+ *
+ *     Calculates the effective HW address
+ *
+ * para:
+ *     Base    I/O or memory base address
+ *     Addr    Address offset
+ *
+ * usage:      May be used in SK_INxx and SK_OUTxx macros
+ *             #define SK_IN8(pAC, Addr, pVal) ...\
+ *                     *pVal = (SK_U8)inp(SK_HW_ADDR(pAC->Hw.Iop, Addr)))
+ */
+#ifdef SK_MEM_MAPPED_IO
+#define SK_HW_ADDR(Base, Addr) ((Base) + (Addr))
+#else  /* SK_MEM_MAPPED_IO */
+#define SK_HW_ADDR(Base, Addr) \
+                       ((Base) + (((Addr) & 0x7f) | (((Addr) >> 7 > 0) ? 0x80 : 0)))
+#endif /* SK_MEM_MAPPED_IO */
+
+#define SZ_LONG        (sizeof(SK_U32))
+
+/*
+ *     Macro SK_HWAC_LINK_LED()
+ *
+ *     Use this macro to set the link LED mode.
+ * para:
+ *     pAC             Pointer to adapter context struct
+ *     IoC             I/O context needed for SK I/O macros
+ *  Port       Port number
+ *     Mode    Mode to set for this LED
+ */
+#define SK_HWAC_LINK_LED(pAC, IoC, Port, Mode) \
+       SK_OUT8(IoC, MR_ADDR(Port, LNK_LED_REG), Mode);
+
+
+/* typedefs *******************************************************************/
+
+
+/* function prototypes ********************************************************/
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __INC_SKGEHW_H */
diff --git a/drivers/net/sk98lin/h/skgehwt.h b/drivers/net/sk98lin/h/skgehwt.h
new file mode 100644 (file)
index 0000000..8aa9edd
--- /dev/null
@@ -0,0 +1,74 @@
+/******************************************************************************
+ *
+ * Name:       skhwt.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.5 $
+ * Date:       $Date: 1999/11/22 13:54:24 $
+ * Purpose:    Defines for the hardware timer functions
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998,1999 SysKonnect,
+ *     a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skgehwt.h,v $
+ *     Revision 1.5  1999/11/22 13:54:24  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.4  1998/08/19 09:50:58  gklug
+ *     fix: remove struct keyword from c-code (see CCC) add typedefs
+ *
+ *     Revision 1.3  1998/08/14 07:09:29  gklug
+ *     fix: chg pAc -> pAC
+ *
+ *     Revision 1.2  1998/08/07 12:54:21  gklug
+ *     fix: first compiled version
+ *
+ *     Revision 1.1  1998/08/07 09:32:58  gklug
+ *     first version
+ *
+ *
+ *
+ *
+ *
+ ******************************************************************************/
+
+/*
+ * SKGEHWT.H   contains all defines and types for the timer functions
+ */
+
+#ifndef        _SKGEHWT_H_
+#define _SKGEHWT_H_
+
+/*
+ * SK Hardware Timer
+ * - needed wherever the HWT module is used
+ * - use in Adapters context name pAC->Hwt
+ */
+typedef        struct s_Hwt {
+       SK_U32          TStart ;        /* HWT start */
+       SK_U32          TStop ;         /* HWT stop */
+       int             TActive ;       /* HWT: flag : active/inactive */
+} SK_HWT;
+
+extern void SkHwtInit(SK_AC *pAC, SK_IOC Ioc);
+extern void SkHwtStart(SK_AC *pAC, SK_IOC Ioc, SK_U32 Time);
+extern void SkHwtStop(SK_AC *pAC, SK_IOC Ioc);
+extern SK_U32 SkHwtRead(SK_AC *pAC,SK_IOC Ioc);
+extern void SkHwtIsr(SK_AC *pAC, SK_IOC Ioc);
+#endif /* _SKGEHWT_H_ */
diff --git a/drivers/net/sk98lin/h/skgei2c.h b/drivers/net/sk98lin/h/skgei2c.h
new file mode 100644 (file)
index 0000000..e639f73
--- /dev/null
@@ -0,0 +1,299 @@
+/******************************************************************************
+ *
+ * Name:       skgei2c.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.23 $
+ * Date:       $Date: 2002/12/19 14:34:27 $
+ * Purpose:    Special GEnesis defines for TWSI
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2002 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skgei2c.h,v $
+ *     Revision 1.23  2002/12/19 14:34:27  rschmidt
+ *     Added cast in macros SK_I2C_SET_BIT() and SK_I2C_CLR_BIT()
+ *     Editorial changes (TWSI)
+ *
+ *     Revision 1.22  2002/10/14 16:45:56  rschmidt
+ *     Editorial changes (TWSI)
+ *
+ *     Revision 1.21  2002/08/13 08:42:24  rschmidt
+ *     Changed define for SK_MIN_SENSORS back to 5
+ *     Merged defines for PHY PLL 3V3 voltage (A and B)
+ *     Editorial changes
+ *
+ *     Revision 1.20  2002/08/06 09:43:56  jschmalz
+ *     Extensions and changes for Yukon
+ *
+ *     Revision 1.19  2002/08/02 12:00:08  rschmidt
+ *     Added defines for YUKON sensors
+ *     Editorial changes
+ *
+ *     Revision 1.18  2001/08/16 12:44:33  afischer
+ *     LM80 sensor init values corrected
+ *
+ *     Revision 1.17  1999/11/22 13:55:25  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.16  1999/11/12 08:24:10  malthoff
+ *     Change voltage warning and error limits
+ *     (warning +-5%, error +-10%).
+ *
+ *     Revision 1.15  1999/09/14 14:14:43  malthoff
+ *     The 1000BT Dual Link adapter has got only one Fan.
+ *     The second Fan has been removed.
+ *
+ *     Revision 1.14  1999/05/27 13:40:50  malthoff
+ *     Fan Divisor = 1. Assuming fan with 6500 rpm.
+ *
+ *     Revision 1.13  1999/05/20 14:56:55  malthoff
+ *     Bug Fix: Missing brace in SK_LM80_FAN_FAKTOR.
+ *
+ *     Revision 1.12  1999/05/20 09:22:00  cgoos
+ *     Changes for 1000Base-T (Fan sensors).
+ *
+ *     Revision 1.11  1998/10/14 05:57:22  cgoos
+ *     Fixed compilation warnings.
+ *
+ *     Revision 1.10  1998/09/04 08:37:00  malthoff
+ *     bugfix: correct the SK_I2C_GET_CTL() macro.
+ *
+ *     Revision 1.9  1998/08/25 06:10:03  gklug
+ *     add: thresholds for all sensors
+ *
+ *     Revision 1.8  1998/08/20 11:37:42  gklug
+ *     chg: change Ioc to IoC
+ *
+ *     Revision 1.7  1998/08/20 08:53:11  gklug
+ *     fix: compiler errors
+ *     add: Threshold values
+ *
+ *     Revision 1.6  1998/08/17 11:37:09  malthoff
+ *     Bugfix in SK_I2C_CTL macro. The parameter 'dev'
+ *     has to be shifted 9 bits.
+ *
+ *     Revision 1.5  1998/08/17 06:52:21  malthoff
+ *     Remove unrequired macros.
+ *     Add macros for accessing TWSI SW register.
+ *
+ *     Revision 1.4  1998/08/13 08:30:18  gklug
+ *     add: conversion factors for read values
+ *     add: new state SEN_VALEXT to read extension value of temperature sensor
+ *
+ *     Revision 1.3  1998/08/12 13:37:56  gklug
+ *     rmv: error numbers and messages
+ *
+ *     Revision 1.2  1998/08/11 07:54:38  gklug
+ *     add: sensor states for GE sensors
+ *     add: Macro to access TWSI hardware register
+ *     chg: Error messages for TWSI errors
+ *
+ *     Revision 1.1  1998/07/17 11:27:56  gklug
+ *     Created.
+ *
+ *
+ *
+ ******************************************************************************/
+
+/*
+ * SKGEI2C.H   contains all SK-98xx specific defines for the TWSI handling
+ */
+
+#ifndef _INC_SKGEI2C_H_
+#define _INC_SKGEI2C_H_
+
+/*
+ * Macros to access the B2_I2C_CTRL
+ */
+#define SK_I2C_CTL(IoC, flag, dev, reg, burst) \
+       SK_OUT32(IoC, B2_I2C_CTRL,\
+               (flag ? 0x80000000UL : 0x0L) | \
+               (((SK_U32) reg << 16) & I2C_ADDR) | \
+               (((SK_U32) dev << 9) & I2C_DEV_SEL) | \
+               (( burst << 4) & I2C_BURST_LEN))
+
+#define SK_I2C_STOP(IoC) {                             \
+       SK_U32  I2cCtrl;                                \
+       SK_IN32(IoC, B2_I2C_CTRL, &I2cCtrl);            \
+       SK_OUT32(IoC, B2_I2C_CTRL, I2cCtrl | I2C_STOP); \
+}
+
+#define SK_I2C_GET_CTL(IoC, pI2cCtrl)  SK_IN32(IoC, B2_I2C_CTRL, pI2cCtrl)
+
+/*
+ * Macros to access the TWSI SW Registers
+ */
+#define SK_I2C_SET_BIT(IoC, SetBits) {                 \
+       SK_U8   OrgBits;                                \
+       SK_IN8(IoC, B2_I2C_SW, &OrgBits);               \
+       SK_OUT8(IoC, B2_I2C_SW, OrgBits | (SK_U8)(SetBits));    \
+}
+
+#define SK_I2C_CLR_BIT(IoC, ClrBits) {                 \
+       SK_U8   OrgBits;                                \
+       SK_IN8(IoC, B2_I2C_SW, &OrgBits);               \
+       SK_OUT8(IoC, B2_I2C_SW, OrgBits & ~((SK_U8)(ClrBits))); \
+}
+
+#define SK_I2C_GET_SW(IoC, pI2cSw)     SK_IN8(IoC, B2_I2C_SW, pI2cSw)
+
+/*
+ * define the possible sensor states
+ */
+#define        SK_SEN_IDLE             0       /* Idle: sensor not read */
+#define        SK_SEN_VALUE    1       /* Value Read cycle */
+#define        SK_SEN_VALEXT   2       /* Extended Value Read cycle */
+
+/*
+ * Conversion factor to convert read Voltage sensor to milli Volt
+ * Conversion factor to convert read Temperature sensor to 10th degree Celsius
+ */
+#define        SK_LM80_VT_LSB          22      /* 22mV LSB resolution */
+#define        SK_LM80_TEMP_LSB        10      /* 1 degree LSB resolution */
+#define        SK_LM80_TEMPEXT_LSB     5       /* 0.5 degree LSB resolution for the
+                                        * extension value
+                                        */
+#define SK_LM80_FAN_FAKTOR     ((22500L*60)/(1*2))
+/* formula: counter = (22500*60)/(rpm * divisor * pulses/2)
+ * assuming: 6500rpm, 4 pulses, divisor 1
+ */
+
+/*
+ * Define sensor management data
+ * Maximum is reached on copperfield with dual Broadcom.
+ * Board specific maximum is in pAC->I2c.MaxSens
+ */
+#define        SK_MAX_SENSORS  8       /* maximal no. of installed sensors */
+#define        SK_MIN_SENSORS  5       /* minimal no. of installed sensors */
+
+/*
+ * To watch the statemachine (JS) use the timer in two ways instead of one as hitherto
+ */
+#define        SK_TIMER_WATCH_STATEMACHINE     0       /* Watch the statemachine to finish in a specific time */
+#define        SK_TIMER_NEW_GAUGING            1       /* Start a new gauging when timer expires */
+
+
+/*
+ * Defines for the individual Thresholds
+ */
+
+/* Temperature sensor */
+#define        SK_SEN_TEMP_HIGH_ERR    800     /* Temperature High Err  Threshold */
+#define        SK_SEN_TEMP_HIGH_WARN   700     /* Temperature High Warn Threshold */
+#define        SK_SEN_TEMP_LOW_WARN    100     /* Temperature Low  Warn Threshold */
+#define        SK_SEN_TEMP_LOW_ERR       0     /* Temperature Low  Err  Threshold */
+
+/* VCC which should be 5 V */
+#define        SK_SEN_PCI_5V_HIGH_ERR          5588    /* Voltage PCI High Err  Threshold */
+#define        SK_SEN_PCI_5V_HIGH_WARN     5346        /* Voltage PCI High Warn Threshold */
+#define        SK_SEN_PCI_5V_LOW_WARN          4664    /* Voltage PCI Low  Warn Threshold */
+#define        SK_SEN_PCI_5V_LOW_ERR           4422    /* Voltage PCI Low  Err  Threshold */
+
+/*
+ * VIO may be 5 V or 3.3 V. Initialization takes two parts:
+ * 1. Initialize lowest lower limit and highest higher limit.
+ * 2. After the first value is read correct the upper or the lower limit to
+ *    the appropriate C constant.
+ *
+ * Warning limits are +-5% of the exepected voltage.
+ * Error limits are +-10% of the expected voltage.
+ */
+
+/* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */
+
+#define        SK_SEN_PCI_IO_5V_HIGH_ERR       5566    /* + 10% V PCI-IO High Err Threshold */
+#define        SK_SEN_PCI_IO_5V_HIGH_WARN      5324    /* +  5% V PCI-IO High Warn Threshold */
+                                       /*              5000    mVolt */
+#define        SK_SEN_PCI_IO_5V_LOW_WARN       4686    /* -  5% V PCI-IO Low Warn Threshold */
+#define        SK_SEN_PCI_IO_5V_LOW_ERR        4444    /* - 10% V PCI-IO Low Err Threshold */
+
+#define        SK_SEN_PCI_IO_RANGE_LIMITER     4000    /* 4000 mV range delimiter */
+
+/* correction values for the second pass */
+#define        SK_SEN_PCI_IO_3V3_HIGH_ERR      3850    /* + 15% V PCI-IO High Err Threshold */
+#define        SK_SEN_PCI_IO_3V3_HIGH_WARN     3674    /* + 10% V PCI-IO High Warn Threshold */
+                                       /*              3300    mVolt */
+#define        SK_SEN_PCI_IO_3V3_LOW_WARN  2926        /* - 10% V PCI-IO Low Warn Threshold */
+#define        SK_SEN_PCI_IO_3V3_LOW_ERR   2772        /* - 15% V PCI-IO Low Err  Threshold */
+
+
+/*
+ * VDD voltage
+ */
+#define        SK_SEN_VDD_HIGH_ERR         3630        /* Voltage ASIC High Err  Threshold */
+#define        SK_SEN_VDD_HIGH_WARN    3476    /* Voltage ASIC High Warn Threshold */
+#define        SK_SEN_VDD_LOW_WARN     3146    /* Voltage ASIC Low  Warn Threshold */
+#define        SK_SEN_VDD_LOW_ERR      2970    /* Voltage ASIC Low  Err  Threshold */
+
+/*
+ * PHY PLL 3V3 voltage
+ */
+#define        SK_SEN_PLL_3V3_HIGH_ERR         3630    /* Voltage PMA High Err  Threshold */
+#define        SK_SEN_PLL_3V3_HIGH_WARN        3476    /* Voltage PMA High Warn Threshold */
+#define        SK_SEN_PLL_3V3_LOW_WARN         3146    /* Voltage PMA Low  Warn Threshold */
+#define        SK_SEN_PLL_3V3_LOW_ERR          2970    /* Voltage PMA Low  Err  Threshold */
+
+/*
+ * VAUX (YUKON only)
+ */
+#define        SK_SEN_VAUX_3V3_HIGH_ERR        3630    /* Voltage VAUX High Err Threshold */
+#define        SK_SEN_VAUX_3V3_HIGH_WARN       3476    /* Voltage VAUX High Warn Threshold */
+#define        SK_SEN_VAUX_3V3_LOW_WARN        3146    /* Voltage VAUX Low Warn Threshold */
+#define        SK_SEN_VAUX_3V3_LOW_ERR     2970        /* Voltage VAUX Low Err Threshold */
+#define        SK_SEN_VAUX_0V_WARN_ERR        0        /* if VAUX not present */
+#define        SK_SEN_VAUX_RANGE_LIMITER       1000    /* 1000 mV range delimiter */
+
+/*
+ * PHY 2V5 voltage
+ */
+#define        SK_SEN_PHY_2V5_HIGH_ERR         2750    /* Voltage PHY High Err Threshold */
+#define        SK_SEN_PHY_2V5_HIGH_WARN        2640    /* Voltage PHY High Warn Threshold */
+#define        SK_SEN_PHY_2V5_LOW_WARN         2376    /* Voltage PHY Low Warn Threshold */
+#define        SK_SEN_PHY_2V5_LOW_ERR          2222    /* Voltage PHY Low Err Threshold */
+
+/*
+ * ASIC Core 1V5 voltage (YUKON only)
+ */
+#define        SK_SEN_CORE_1V5_HIGH_ERR    1650        /* Voltage ASIC Core High Err Threshold */
+#define        SK_SEN_CORE_1V5_HIGH_WARN       1575    /* Voltage ASIC Core High Warn Threshold */
+#define        SK_SEN_CORE_1V5_LOW_WARN        1425    /* Voltage ASIC Core Low Warn Threshold */
+#define        SK_SEN_CORE_1V5_LOW_ERR         1350    /* Voltage ASIC Core Low Err Threshold */
+
+/*
+ * FAN 1 speed
+ */
+/* assuming: 6500rpm +-15%, 4 pulses,
+ * warning at: 80 %
+ * error at:   70 %
+ * no upper limit
+ */
+#define        SK_SEN_FAN_HIGH_ERR             20000   /* FAN Speed High Err Threshold */
+#define        SK_SEN_FAN_HIGH_WARN    20000   /* FAN Speed High Warn Threshold */
+#define        SK_SEN_FAN_LOW_WARN     5200    /* FAN Speed Low Warn Threshold */
+#define        SK_SEN_FAN_LOW_ERR              4550    /* FAN Speed Low Err Threshold */
+
+/*
+ * Some Voltages need dynamic thresholds
+ */
+#define        SK_SEN_DYN_INIT_NONE             0  /* No dynamic init of thresholds */
+#define        SK_SEN_DYN_INIT_PCI_IO          10  /* Init PCI-IO with new thresholds */
+#define        SK_SEN_DYN_INIT_VAUX            11  /* Init VAUX with new thresholds */
+
+extern int SkLm80ReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
+#endif /* n_INC_SKGEI2C_H */
diff --git a/drivers/net/sk98lin/h/skgeinit.h b/drivers/net/sk98lin/h/skgeinit.h
new file mode 100644 (file)
index 0000000..cdddef9
--- /dev/null
@@ -0,0 +1,1113 @@
+/******************************************************************************
+ *
+ * Name:       skgeinit.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.75 $
+ * Date:       $Date: 2003/02/05 13:36:39 $
+ * Purpose:    Structures and prototypes for the GE Init Module
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2003 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skgeinit.h,v $
+ *     Revision 1.75  2003/02/05 13:36:39  rschmidt
+ *     Added define SK_FACT_78 for YUKON's Host Clock of 78.12 MHz
+ *     Editorial changes
+ *
+ *     Revision 1.74  2003/01/28 09:39:16  rschmidt
+ *     Added entry GIYukonLite in s_GeInit structure
+ *     Editorial changes
+ *
+ *     Revision 1.73  2002/11/15 12:47:25  rschmidt
+ *     Replaced error message SKERR_HWI_E024 for Cable Diagnostic with
+ *     Rx queue error in SkGeStopPort().
+ *
+ *     Revision 1.72  2002/11/12 17:08:35  rschmidt
+ *     Added entries for Cable Diagnostic to Port structure
+ *     Added entries GIPciSlot64 and GIPciClock66 in s_GeInit structure
+ *     Added error message for Cable Diagnostic
+ *     Added prototypes for SkGmCableDiagStatus()
+ *     Editorial changes
+ *
+ *     Revision 1.71  2002/10/21 11:26:10  mkarl
+ *     Changed interface of SkGeInitAssignRamToQueues().
+ *
+ *     Revision 1.70  2002/10/14 08:21:32  rschmidt
+ *     Changed type of GICopperType, GIVauxAvail to SK_BOOL
+ *     Added entry PRxOverCnt to Port structure
+ *     Added entry GIYukon32Bit in s_GeInit structure
+ *     Editorial changes
+ *
+ *     Revision 1.69  2002/10/09 16:57:15  mkarl
+ *     Added some constants and macros for SkGeInitAssignRamToQueues().
+ *
+ *     Revision 1.68  2002/09/12 08:58:51  rwahl
+ *     Retrieve counters needed for XMAC errata workarounds directly because
+ *     PNMI returns corrected counter values (e.g. #10620).
+ *
+ *     Revision 1.67  2002/08/16 14:40:30  rschmidt
+ *     Added entries GIGenesis and GICopperType in s_GeInit structure
+ *     Added prototypes for SkMacHashing()
+ *     Editorial changes
+ *
+ *     Revision 1.66  2002/08/12 13:27:21  rschmidt
+ *     Added defines for Link speed capabilities
+ *     Added entry PLinkSpeedCap to Port structure
+ *     Added entry GIVauxAvail in s_GeInit structure
+ *     Added prototypes for SkMacPromiscMode()
+ *     Editorial changes
+ *
+ *     Revision 1.65  2002/08/08 15:46:18  rschmidt
+ *     Added define SK_PHY_ACC_TO for PHY access timeout
+ *     Added define SK_XM_RX_HI_WM for XMAC Rx High Watermark
+ *     Added define SK_MIN_TXQ_SIZE for Min RAM Buffer Tx Queue Size
+ *     Added entry PhyId1 to Port structure
+ *
+ *     Revision 1.64  2002/07/23 16:02:56  rschmidt
+ *     Added entry GIWolOffs in s_GeInit struct (HW-Bug in YUKON 1st rev.)
+ *     Added prototypes for: SkGePhyRead(), SkGePhyWrite()
+ *
+ *     Revision 1.63  2002/07/18 08:17:38  rwahl
+ *     Corrected definitions for SK_LSPEED_xxx & SK_LSPEED_STAT_xxx.
+ *
+ *     Revision 1.62  2002/07/17 18:21:55  rwahl
+ *     Added SK_LSPEED_INDETERMINATED define.
+ *
+ *     Revision 1.61  2002/07/17 17:16:03  rwahl
+ *     - MacType now member of GIni struct.
+ *     - Struct alignment to 32bit.
+ *     - Editorial change.
+ *
+ *     Revision 1.60  2002/07/15 18:23:39  rwahl
+ *     Added GeMacFunc to GE Init structure.
+ *     Added prototypes for SkXmUpdateStats(), SkGmUpdateStats(),
+ *       SkXmMacStatistic(), SkGmMacStatistic(), SkXmResetCounter(),
+ *       SkGmResetCounter(), SkXmOverflowStatus(), SkGmOverflowStatus().
+ *     Added defines for current link speed state.
+ *     Added ERRMSG defintions for MacUpdateStat() & MacStatistics().
+ *
+ *     Revision 1.59  2002/07/15 15:40:22  rschmidt
+ *     Added entry PLinkSpeedUsed to Port structure
+ *     Editorial changes
+ *
+ *     Revision 1.58  2002/06/10 09:36:30  rschmidt
+ *     Editorial changes.
+ *
+ *     Revision 1.57  2002/06/05 08:18:00  rschmidt
+ *     Corrected alignment in Port Structure
+ *     Added new prototypes for GMAC
+ *     Editorial changes
+ *
+ *     Revision 1.56  2002/04/25 11:38:12  rschmidt
+ *     Added defines for Link speed values
+ *     Added defines for Loopback parameters for MAC and PHY
+ *     Removed entry PRxCmd from Port structure
+ *     Added entry PLinkSpeed to Port structure
+ *     Added entries GIChipId and GIChipRev to GE Init structure
+ *     Removed entry GIAnyPortAct from GE Init structure
+ *     Added prototypes for: SkMacInit(), SkMacInitPhy(),
+ *     SkMacRxTxDisable(), SkMacSoftRst(), SkMacHardRst(), SkMacIrq(),
+ *     SkMacIrqDisable(), SkMacFlushTxFifo(), SkMacFlushRxFifo(),
+ *     SkMacAutoNegDone(), SkMacAutoNegLipaPhy(), SkMacSetRxTxEn(),
+ *     SkXmPhyRead(), SkXmPhyRead(), SkGmPhyWrite(), SkGmPhyWrite();
+ *     Removed prototypes for static functions in SkXmac2.c
+ *     Editorial changes
+ *
+ *     Revision 1.55  2002/02/26 15:24:53  rwahl
+ *     Fix: no link with manual configuration (#10673). The previous fix for
+ *     #10639 was removed. So for RLMT mode = CLS the RLMT may switch to
+ *     misconfigured port. It should not occur for the other RLMT modes.
+ *
+ *     Revision 1.54  2002/01/18 16:52:52  rwahl
+ *     Editorial corrections.
+ *
+ *     Revision 1.53  2001/11/20 09:19:58  rwahl
+ *     Reworked bugfix #10639 (no dependency to RLMT mode).
+ *
+ *     Revision 1.52  2001/10/26 07:52:23  afischer
+ *     Port switching bug in `check local link` mode
+ *
+ *     Revision 1.51  2001/02/09 12:26:38  cgoos
+ *     Inserted #ifdef DIAG for half duplex workaround timer.
+ *
+ *     Revision 1.50  2001/02/07 07:56:40  rassmann
+ *     Corrected copyright.
+ *
+ *     Revision 1.49  2001/01/31 15:32:18  gklug
+ *     fix: problem with autosensing an SR8800 switch
+ *     add: counter for autoneg timeouts
+ *
+ *     Revision 1.48  2000/11/09 11:30:10  rassmann
+ *     WA: Waiting after releasing reset until BCom chip is accessible.
+ *
+ *     Revision 1.47  2000/10/18 12:22:40  cgoos
+ *     Added workaround for half duplex hangup.
+ *
+ *     Revision 1.46  2000/08/10 11:28:00  rassmann
+ *     Editorial changes.
+ *     Preserving 32-bit alignment in structs for the adapter context.
+ *
+ *     Revision 1.45  1999/11/22 13:56:19  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.44  1999/10/26 07:34:15  malthoff
+ *     The define SK_LNK_ON has been lost in v1.41.
+ *
+ *     Revision 1.43  1999/10/06 09:30:16  cgoos
+ *     Changed SK_XM_THR_JUMBO.
+ *
+ *     Revision 1.42  1999/09/16 12:58:26  cgoos
+ *     Changed SK_LED_STANDY macro to be independent of HW link sync.
+ *
+ *     Revision 1.41  1999/07/30 06:56:14  malthoff
+ *     Correct comment for SK_MS_STAT_UNSET.
+ *
+ *     Revision 1.40  1999/05/27 13:38:46  cgoos
+ *     Added SK_BMU_TX_WM.
+ *     Made SK_BMU_TX_WM and SK_BMU_RX_WM user-definable.
+ *     Changed XMAC Tx treshold to max. values.
+ *
+ *     Revision 1.39  1999/05/20 14:35:26  malthoff
+ *     Remove prototypes for SkGeLinkLED().
+ *
+ *     Revision 1.38  1999/05/19 11:59:12  cgoos
+ *     Added SK_MS_CAP_INDETERMINATED define.
+ *
+ *     Revision 1.37  1999/05/19 07:32:33  cgoos
+ *     Changes for 1000Base-T.
+ *     LED-defines for HWAC_LINK_LED macro.
+ *
+ *     Revision 1.36  1999/04/08 14:00:24  gklug
+ *     add:Port struct field PLinkResCt
+ *
+ *     Revision 1.35  1999/03/25 07:43:07  malthoff
+ *     Add error string for SKERR_HWI_E018MSG.
+ *
+ *     Revision 1.34  1999/03/12 16:25:57  malthoff
+ *     Remove PPollRxD and PPollTxD.
+ *     Add SKERR_HWI_E017MSG. and SK_DPOLL_MAX.
+ *
+ *     Revision 1.33  1999/03/12 13:34:41  malthoff
+ *     Add Autonegotiation error codes.
+ *     Change defines for parameter Mode in SkXmSetRxCmd().
+ *     Replace __STDC__ by SK_KR_PROTO.
+ *
+ *     Revision 1.32  1999/01/25 14:40:20  mhaveman
+ *     Added new return states for the virtual management port if multiple
+ *     ports are active but differently configured.
+ *
+ *     Revision 1.31  1998/12/11 15:17:02  gklug
+ *     add: Link partnet autoneg states : Unknown Manual and Auto-negotiation
+ *
+ *     Revision 1.30  1998/12/07 12:17:04  gklug
+ *     add: Link Partner auto-negotiation flag
+ *
+ *     Revision 1.29  1998/12/01 10:54:42  gklug
+ *     add: variables for XMAC Errata
+ *
+ *     Revision 1.28  1998/12/01 10:14:15  gklug
+ *     add: PIsave saves the Interrupt status word
+ *
+ *     Revision 1.27  1998/11/26 15:24:52  mhaveman
+ *     Added link status states SK_LMODE_STAT_AUTOHALF and
+ *     SK_LMODE_STAT_AUTOFULL which are used by PNMI.
+ *
+ *     Revision 1.26  1998/11/26 14:53:01  gklug
+ *     add:autoNeg Timeout variable
+ *
+ *     Revision 1.25  1998/11/26 08:58:50  gklug
+ *     add: Link Mode configuration (AUTO Sense mode)
+ *
+ *     Revision 1.24  1998/11/24 13:30:27  gklug
+ *     add: PCheckPar to port struct
+ *
+ *     Revision 1.23  1998/11/18 13:23:26  malthoff
+ *     Add SK_PKT_TO_MAX.
+ *
+ *     Revision 1.22  1998/11/18 13:19:54  gklug
+ *     add: PPrevShorts and PLinkBroken to port struct for WA XMAC Errata #C1
+ *
+ *     Revision 1.21  1998/10/26 08:02:57  malthoff
+ *     Add GIRamOffs.
+ *
+ *     Revision 1.20  1998/10/19 07:28:37  malthoff
+ *     Add prototype for SkGeInitRamIface().
+ *
+ *     Revision 1.19  1998/10/14 14:47:48  malthoff
+ *     SK_TIMER should not be defined for Diagnostics.
+ *     Add SKERR_HWI_E015MSG and SKERR_HWI_E016MSG.
+ *
+ *     Revision 1.18  1998/10/14 14:00:03  gklug
+ *     add: timer to port struct for workaround of Errata #2
+ *
+ *     Revision 1.17  1998/10/14 11:23:09  malthoff
+ *     Add prototype for SkXmAutoNegDone().
+ *     Fix SkXmSetRxCmd() prototype statement.
+ *
+ *     Revision 1.16  1998/10/14 05:42:29  gklug
+ *     add: HWLinkUp flag to Port struct
+ *
+ *     Revision 1.15  1998/10/09 08:26:33  malthoff
+ *     Rename SK_RB_ULPP_B to SK_RB_LLPP_B.
+ *
+ *     Revision 1.14  1998/10/09 07:11:13  malthoff
+ *     bug fix: SK_FACT_53 is 85 not 117.
+ *     Rework time out init values.
+ *     Add GIPortUsage and corresponding defines.
+ *     Add some error log messages.
+ *
+ *     Revision 1.13  1998/10/06 14:13:14  malthoff
+ *     Add prototype for SkGeLoadLnkSyncCnt().
+ *
+ *     Revision 1.12  1998/10/05 11:29:53  malthoff
+ *     bug fix: A comment was not closed.
+ *
+ *     Revision 1.11  1998/10/05 08:01:59  malthoff
+ *     Add default Timeout- Threshold- and
+ *     Watermark constants. Add QRam start and end
+ *     variables. Also add vars to store the polling
+ *     mode and receive command. Add new Error Log
+ *     Messages and function prototypes.
+ *
+ *     Revision 1.10  1998/09/28 13:34:48  malthoff
+ *     Add mode bits for LED functions.
+ *     Move Autoneg and Flow Ctrl bits from shgesirq.h
+ *     Add the required Error Log Entries
+ *     and Function Prototypes.
+ *
+ *     Revision 1.9  1998/09/16 14:38:41  malthoff
+ *     Rework the SK_LNK_xxx defines.
+ *     Add error log message defines.
+ *     Add prototypes for skxmac2.c
+ *
+ *     Revision 1.8  1998/09/11 05:29:18  gklug
+ *     add: init state of a port
+ *
+ *     Revision 1.7  1998/09/08 08:35:52  gklug
+ *     add: defines of the Init Levels
+ *
+ *     Revision 1.6  1998/09/03 13:48:42  gklug
+ *     add: Link strati, capabilities to Port struct
+ *
+ *     Revision 1.5  1998/09/03 13:30:59  malthoff
+ *     Add SK_LNK_BLINK and SK_LNK_PERM.
+ *
+ *     Revision 1.4  1998/09/03 09:55:31  malthoff
+ *     Add constants for parameters Dir and RstMode
+ *     when calling SkGeStopPort().
+ *     Rework the prototype section.
+ *     Add Queue Address offsets PRxQOff, PXsQOff, and PXaQOff.
+ *     Remove Ioc with IoC.
+ *
+ *     Revision 1.3  1998/08/19 09:11:54  gklug
+ *     fix: struct are removed from c-source (see CCC)
+ *     add: typedefs for all structs
+ *
+ *     Revision 1.2  1998/07/28 12:38:26  malthoff
+ *     The prototypes got the parameter 'IoC'.
+ *
+ *     Revision 1.1  1998/07/23 09:50:24  malthoff
+ *     Created.
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKGEINIT_H_
+#define __INC_SKGEINIT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* defines ********************************************************************/
+
+/* modifying Link LED behaviour (used with SkGeLinkLED()) */
+#define SK_LNK_OFF             LED_OFF
+#define SK_LNK_ON              (LED_ON | LED_BLK_OFF | LED_SYNC_OFF)
+#define SK_LNK_BLINK   (LED_ON | LED_BLK_ON  | LED_SYNC_ON)
+#define SK_LNK_PERM            (LED_ON | LED_BLK_OFF | LED_SYNC_ON)
+#define SK_LNK_TST             (LED_ON | LED_BLK_ON  | LED_SYNC_OFF)
+
+/* parameter 'Mode' when calling SK_HWAC_LINK_LED() */
+#define SK_LED_OFF             LED_OFF
+#define SK_LED_ACTIVE  (LED_ON | LED_BLK_OFF | LED_SYNC_OFF)
+#define SK_LED_STANDBY (LED_ON | LED_BLK_ON  | LED_SYNC_OFF)
+
+/* addressing LED Registers in SkGeXmitLED() */
+#define XMIT_LED_INI   0
+#define XMIT_LED_CNT   (RX_LED_VAL - RX_LED_INI)
+#define XMIT_LED_CTRL  (RX_LED_CTRL- RX_LED_INI)
+#define XMIT_LED_TST   (RX_LED_TST - RX_LED_INI)
+
+/* parameter 'Mode' when calling SkGeXmitLED() */
+#define SK_LED_DIS     0
+#define SK_LED_ENA     1
+#define SK_LED_TST     2
+
+/* Counter and Timer constants, for a host clock of 62.5 MHz */
+#define SK_XMIT_DUR            0x002faf08L             /*  50 ms */
+#define SK_BLK_DUR             0x01dcd650L             /* 500 ms */
+
+#define SK_DPOLL_DEF   0x00ee6b28L             /* 250 ms at 62.5 MHz */
+
+#define SK_DPOLL_MAX   0x00ffffffL             /* 268 ms at 62.5 MHz */
+                                                                               /* 215 ms at 78.12 MHz */
+
+#define SK_FACT_62             100                     /* is given in percent */
+#define SK_FACT_53              85         /* on GENESIS:      53.12 MHz */
+#define SK_FACT_78             125                     /* on YUKON:    78.12 MHz */
+
+/* Timeout values */
+#define SK_MAC_TO_53   72                      /* MAC arbiter timeout */
+#define SK_PKT_TO_53   0x2000          /* Packet arbiter timeout */
+#define SK_PKT_TO_MAX  0xffff          /* Maximum value */
+#define SK_RI_TO_53            36                      /* RAM interface timeout */
+
+#define SK_PHY_ACC_TO  600000          /* PHY access timeout */
+
+/* RAM Buffer High Pause Threshold values */
+#define SK_RB_ULPP             ( 8 * 1024)     /* Upper Level in kB/8 */
+#define SK_RB_LLPP_S   (10 * 1024)     /* Lower Level for small Queues */
+#define SK_RB_LLPP_B   (16 * 1024)     /* Lower Level for big Queues */
+
+#ifndef SK_BMU_RX_WM
+#define SK_BMU_RX_WM   0x600           /* BMU Rx Watermark */
+#endif
+#ifndef SK_BMU_TX_WM
+#define SK_BMU_TX_WM   0x600           /* BMU Tx Watermark */
+#endif
+
+/* XMAC II Rx High Watermark */
+#define SK_XM_RX_HI_WM 0x05aa          /* 1450 */
+
+/* XMAC II Tx Threshold */
+#define SK_XM_THR_REDL 0x01fb          /* .. for redundant link usage */
+#define SK_XM_THR_SL   0x01fb          /* .. for single link adapters */
+#define SK_XM_THR_MULL 0x01fb          /* .. for multiple link usage */
+#define SK_XM_THR_JUMBO        0x03fc          /* .. for jumbo frame usage */
+
+/* values for GIPortUsage */
+#define SK_RED_LINK            1               /* redundant link usage */
+#define SK_MUL_LINK            2               /* multiple link usage */
+#define SK_JUMBO_LINK  3               /* driver uses jumbo frames */
+
+/* Minimum RAM Buffer Rx Queue Size */
+#define SK_MIN_RXQ_SIZE        16              /* 16 kB */
+
+/* Minimum RAM Buffer Tx Queue Size */
+#define SK_MIN_TXQ_SIZE        16              /* 16 kB */
+
+/* Queue Size units */
+#define QZ_UNITS               0x7
+#define QZ_STEP                        8
+
+/* Percentage of queue size from whole memory */
+/* 80 % for receive */
+#define RAM_QUOTA_RX   80L
+/* 0% for sync transfer */
+#define        RAM_QUOTA_SYNC  0L
+/* the rest (20%) is taken for async transfer */
+
+/* Get the rounded queue size in Bytes in 8k steps */
+#define ROUND_QUEUE_SIZE(SizeInBytes)                                  \
+       ((((unsigned long) (SizeInBytes) + (QZ_STEP*1024L)-1) / 1024) & \
+       ~(QZ_STEP-1))
+
+/* Get the rounded queue size in KBytes in 8k steps */
+#define ROUND_QUEUE_SIZE_KB(Kilobytes) \
+       ROUND_QUEUE_SIZE((Kilobytes) * 1024L)
+
+/* Types of RAM Buffer Queues */
+#define SK_RX_SRAM_Q   1       /* small receive queue */
+#define SK_RX_BRAM_Q   2       /* big receive queue */
+#define SK_TX_RAM_Q            3       /* small or big transmit queue */
+
+/* parameter 'Dir' when calling SkGeStopPort() */
+#define SK_STOP_TX     1       /* Stops the transmit path, resets the XMAC */
+#define SK_STOP_RX     2       /* Stops the receive path */
+#define SK_STOP_ALL    3       /* Stops Rx and Tx path, resets the XMAC */
+
+/* parameter 'RstMode' when calling SkGeStopPort() */
+#define SK_SOFT_RST    1       /* perform a software reset */
+#define SK_HARD_RST    2       /* perform a hardware reset */
+
+/* Init Levels */
+#define SK_INIT_DATA   0       /* Init level 0: init data structures */
+#define SK_INIT_IO             1       /* Init level 1: init with IOs */
+#define SK_INIT_RUN            2       /* Init level 2: init for run time */
+
+/* Link Mode Parameter */
+#define SK_LMODE_HALF          1       /* Half Duplex Mode */
+#define SK_LMODE_FULL          2       /* Full Duplex Mode */
+#define SK_LMODE_AUTOHALF      3       /* AutoHalf Duplex Mode */
+#define SK_LMODE_AUTOFULL      4       /* AutoFull Duplex Mode */
+#define SK_LMODE_AUTOBOTH      5       /* AutoBoth Duplex Mode */
+#define SK_LMODE_AUTOSENSE     6       /* configured mode auto sensing */
+#define SK_LMODE_INDETERMINATED        7       /* indeterminated */
+
+/* Auto-negotiation timeout in 100ms granularity */
+#define SK_AND_MAX_TO          6       /* Wait 600 msec before link comes up */
+
+/* Auto-negotiation error codes */
+#define SK_AND_OK                      0       /* no error */
+#define SK_AND_OTHER           1       /* other error than below */
+#define SK_AND_DUP_CAP         2       /* Duplex capabilities error */
+
+
+/* Link Speed Capabilities */
+#define SK_LSPEED_CAP_AUTO                     (1<<0)  /* Automatic resolution */
+#define SK_LSPEED_CAP_10MBPS           (1<<1)  /* 10 Mbps */
+#define SK_LSPEED_CAP_100MBPS          (1<<2)  /* 100 Mbps */
+#define SK_LSPEED_CAP_1000MBPS         (1<<3)  /* 1000 Mbps */
+#define SK_LSPEED_CAP_INDETERMINATED (1<<4) /* indeterminated */
+
+/* Link Speed Parameter */
+#define SK_LSPEED_AUTO                         1       /* Automatic resolution */
+#define SK_LSPEED_10MBPS                       2       /* 10 Mbps */
+#define SK_LSPEED_100MBPS                      3       /* 100 Mbps */
+#define SK_LSPEED_1000MBPS                     4       /* 1000 Mbps */
+#define SK_LSPEED_INDETERMINATED       5       /* indeterminated */
+
+/* Link Speed Current State */
+#define SK_LSPEED_STAT_UNKNOWN         1
+#define SK_LSPEED_STAT_10MBPS          2
+#define SK_LSPEED_STAT_100MBPS                 3
+#define SK_LSPEED_STAT_1000MBPS                4
+#define SK_LSPEED_STAT_INDETERMINATED 5
+
+
+/* Link Capability Parameter */
+#define SK_LMODE_CAP_HALF              (1<<0)  /* Half Duplex Mode */
+#define SK_LMODE_CAP_FULL              (1<<1)  /* Full Duplex Mode */
+#define SK_LMODE_CAP_AUTOHALF  (1<<2)  /* AutoHalf Duplex Mode */
+#define SK_LMODE_CAP_AUTOFULL  (1<<3)  /* AutoFull Duplex Mode */
+#define SK_LMODE_CAP_INDETERMINATED (1<<4) /* indeterminated */
+
+/* Link Mode Current State */
+#define SK_LMODE_STAT_UNKNOWN  1       /* Unknown Duplex Mode */
+#define SK_LMODE_STAT_HALF             2       /* Half Duplex Mode */
+#define SK_LMODE_STAT_FULL             3       /* Full Duplex Mode */
+#define SK_LMODE_STAT_AUTOHALF 4       /* Half Duplex Mode obtained by Auto-Neg */
+#define SK_LMODE_STAT_AUTOFULL 5       /* Full Duplex Mode obtained by Auto-Neg */
+#define SK_LMODE_STAT_INDETERMINATED 6 /* indeterminated */
+
+/* Flow Control Mode Parameter (and capabilities) */
+#define SK_FLOW_MODE_NONE              1       /* No Flow-Control */
+#define SK_FLOW_MODE_LOC_SEND  2       /* Local station sends PAUSE */
+#define SK_FLOW_MODE_SYMMETRIC 3       /* Both stations may send PAUSE */
+#define SK_FLOW_MODE_SYM_OR_REM        4       /* Both stations may send PAUSE or
+                                        * just the remote station may send PAUSE
+                                        */
+#define SK_FLOW_MODE_INDETERMINATED 5  /* indeterminated */
+
+/* Flow Control Status Parameter */
+#define SK_FLOW_STAT_NONE              1       /* No Flow Control */
+#define SK_FLOW_STAT_REM_SEND  2       /* Remote Station sends PAUSE */
+#define SK_FLOW_STAT_LOC_SEND  3       /* Local station sends PAUSE */
+#define SK_FLOW_STAT_SYMMETRIC 4       /* Both station may send PAUSE */
+#define SK_FLOW_STAT_INDETERMINATED 5  /* indeterminated */
+
+/* Master/Slave Mode Capabilities */
+#define SK_MS_CAP_AUTO         (1<<0)  /* Automatic resolution */
+#define SK_MS_CAP_MASTER       (1<<1)  /* This station is master */
+#define SK_MS_CAP_SLAVE                (1<<2)  /* This station is slave */
+#define SK_MS_CAP_INDETERMINATED (1<<3)        /* indeterminated */
+
+/* Set Master/Slave Mode Parameter (and capabilities) */
+#define SK_MS_MODE_AUTO                1       /* Automatic resolution */
+#define SK_MS_MODE_MASTER      2       /* This station is master */
+#define SK_MS_MODE_SLAVE       3       /* This station is slave */
+#define SK_MS_MODE_INDETERMINATED 4    /* indeterminated */
+
+/* Master/Slave Status Parameter */
+#define SK_MS_STAT_UNSET       1       /* The M/S status is not set */
+#define SK_MS_STAT_MASTER      2       /* This station is Master */
+#define SK_MS_STAT_SLAVE       3       /* This station is Dlave */
+#define SK_MS_STAT_FAULT       4       /* M/S resolution failed */
+#define SK_MS_STAT_INDETERMINATED 5    /* indeterminated */
+
+/* parameter 'Mode' when calling SkXmSetRxCmd() */
+#define SK_STRIP_FCS_ON                (1<<0)  /* Enable  FCS stripping of Rx frames */
+#define SK_STRIP_FCS_OFF       (1<<1)  /* Disable FCS stripping of Rx frames */
+#define SK_STRIP_PAD_ON                (1<<2)  /* Enable  pad byte stripping of Rx fr */
+#define SK_STRIP_PAD_OFF       (1<<3)  /* Disable pad byte stripping of Rx fr */
+#define SK_LENERR_OK_ON                (1<<4)  /* Don't chk fr for in range len error */
+#define SK_LENERR_OK_OFF       (1<<5)  /* Check frames for in range len error */
+#define SK_BIG_PK_OK_ON                (1<<6)  /* Don't set Rx Error bit for big frames */
+#define SK_BIG_PK_OK_OFF       (1<<7)  /* Set Rx Error bit for big frames */
+#define SK_SELF_RX_ON          (1<<8)  /* Enable  Rx of own packets */
+#define SK_SELF_RX_OFF         (1<<9)  /* Disable Rx of own packets */
+
+/* parameter 'Para' when calling SkMacSetRxTxEn() */
+#define SK_MAC_LOOPB_ON                (1<<0)  /* Enable  MAC Loopback Mode */
+#define SK_MAC_LOOPB_OFF       (1<<1)  /* Disable MAC Loopback Mode */
+#define SK_PHY_LOOPB_ON                (1<<2)  /* Enable  PHY Loopback Mode */
+#define SK_PHY_LOOPB_OFF       (1<<3)  /* Disable PHY Loopback Mode */
+#define SK_PHY_FULLD_ON                (1<<4)  /* Enable  GMII Full Duplex */
+#define SK_PHY_FULLD_OFF       (1<<5)  /* Disable GMII Full Duplex */
+
+/* States of PState */
+#define SK_PRT_RESET   0       /* the port is reset */
+#define SK_PRT_STOP            1       /* the port is stopped (similar to SW reset) */
+#define SK_PRT_INIT            2       /* the port is initialized */
+#define SK_PRT_RUN             3       /* the port has an active link */
+
+/* Default receive frame limit for Workaround of XMAC Errata */
+#define SK_DEF_RX_WA_LIM       SK_CONSTU64(100)
+
+/* Link Partner Status */
+#define SK_LIPA_UNKNOWN        0       /* Link partner is in unknown state */
+#define SK_LIPA_MANUAL 1       /* Link partner is in detected manual state */
+#define SK_LIPA_AUTO   2       /* Link partner is in auto-negotiation state */
+
+/* Maximum Restarts before restart is ignored (3Com WA) */
+#define SK_MAX_LRESTART        3       /* Max. 3 times the link is restarted */
+
+/* Max. Auto-neg. timeouts before link detection in sense mode is reset */
+#define SK_MAX_ANEG_TO 10      /* Max. 10 times the sense mode is reset */
+
+/* structures *****************************************************************/
+
+/*
+ * MAC specific functions
+ */
+typedef struct s_GeMacFunc {
+       int  (*pFnMacUpdateStats)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
+       int  (*pFnMacStatistic)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
+                                                       SK_U16 StatAddr, SK_U32 *pVal);
+       int  (*pFnMacResetCounter)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
+       int  (*pFnMacOverflow)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
+                                                  SK_U16 IStatus, SK_U64 *pVal);
+} SK_GEMACFUNC;
+
+/*
+ * Port Structure
+ */
+typedef        struct s_GePort {
+#ifndef SK_DIAG
+       SK_TIMER        PWaTimer;       /* Workaround Timer */
+       SK_TIMER        HalfDupChkTimer;
+#endif /* SK_DIAG */
+       SK_U32  PPrevShorts;    /* Previous short Counter checking */
+       SK_U32  PPrevFcs;               /* Previous FCS Error Counter checking */
+       SK_U64  PPrevRx;                /* Previous RxOk Counter checking */
+       SK_U64  PRxLim;                 /* Previous RxOk Counter checking */
+       SK_U64  LastOctets;             /* For half duplex hang check */
+       int             PLinkResCt;             /* Link Restart Counter */
+       int             PAutoNegTimeOut;/* Auto-negotiation timeout current value */
+       int             PAutoNegTOCt;   /* Auto-negotiation Timeout Counter */
+       int             PRxQSize;               /* Port Rx Queue Size in kB */
+       int             PXSQSize;               /* Port Synchronous  Transmit Queue Size in kB */
+       int             PXAQSize;               /* Port Asynchronous Transmit Queue Size in kB */
+       SK_U32  PRxQRamStart;   /* Receive Queue RAM Buffer Start Address */
+       SK_U32  PRxQRamEnd;             /* Receive Queue RAM Buffer End Address */
+       SK_U32  PXsQRamStart;   /* Sync Tx Queue RAM Buffer Start Address */
+       SK_U32  PXsQRamEnd;             /* Sync Tx Queue RAM Buffer End Address */
+       SK_U32  PXaQRamStart;   /* Async Tx Queue RAM Buffer Start Address */
+       SK_U32  PXaQRamEnd;             /* Async Tx Queue RAM Buffer End Address */
+       SK_U32  PRxOverCnt;             /* Receive Overflow Counter */
+       int             PRxQOff;                /* Rx Queue Address Offset */
+       int             PXsQOff;                /* Synchronous Tx Queue Address Offset */
+       int             PXaQOff;                /* Asynchronous Tx Queue Address Offset */
+       int             PhyType;                /* PHY used on this port */
+       SK_U16  PhyId1;                 /* PHY Id1 on this port */
+       SK_U16  PhyAddr;                /* MDIO/MDC PHY address */
+       SK_U16  PIsave;                 /* Saved Interrupt status word */
+       SK_U16  PSsave;                 /* Saved PHY status word */
+       SK_BOOL PHWLinkUp;              /* The hardware Link is up (wiring) */
+       SK_BOOL PState;                 /* Is port initialized ? */
+       SK_BOOL PLinkBroken;    /* Is Link broken ? */
+       SK_BOOL PCheckPar;              /* Do we check for parity errors ? */
+       SK_BOOL HalfDupTimerActive;
+       SK_U8   PLinkCap;               /* Link Capabilities */
+       SK_U8   PLinkModeConf;  /* Link Mode configured */
+       SK_U8   PLinkMode;              /* Link Mode currently used */
+       SK_U8   PLinkModeStatus;/* Link Mode Status */
+       SK_U8   PLinkSpeedCap;  /* Link Speed Capabilities(10/100/1000 Mbps) */
+       SK_U8   PLinkSpeed;             /* configured Link Speed (10/100/1000 Mbps) */
+       SK_U8   PLinkSpeedUsed; /* current Link Speed (10/100/1000 Mbps) */
+       SK_U8   PFlowCtrlCap;   /* Flow Control Capabilities */
+       SK_U8   PFlowCtrlMode;  /* Flow Control Mode */
+       SK_U8   PFlowCtrlStatus;/* Flow Control Status */
+       SK_U8   PMSCap;                 /* Master/Slave Capabilities */
+       SK_U8   PMSMode;                /* Master/Slave Mode */
+       SK_U8   PMSStatus;              /* Master/Slave Status */
+       SK_U8   PAutoNegFail;   /* Auto-negotiation fail flag */
+       SK_U8   PLipaAutoNeg;   /* Auto-negotiation possible with Link Partner */
+       SK_U8   PCableLen;              /* Cable Length */
+       SK_U8   PMdiPairLen[4]; /* MDI[0..3] Pair Length */
+       SK_U8   PMdiPairSts[4]; /* MDI[0..3] Pair Diagnostic Status */
+} SK_GEPORT;
+
+/*
+ * Gigabit Ethernet Initialization Struct
+ * (has to be included in the adapter context)
+ */
+typedef        struct s_GeInit {
+       SK_U8           GIPciHwRev;             /* PCI HW Revision Number */
+       SK_U8           GIChipId;               /* Chip Identification Number */
+       SK_U8           GIChipRev;              /* Chip Revision Number */
+       SK_BOOL         GIGenesis;              /* Genesis adapter ? */
+       SK_BOOL         GICopperType;   /* Copper Type adapter ? */
+       SK_BOOL         GIPciSlot64;    /* 64-bit PCI Slot */
+       SK_BOOL         GIPciClock66;   /* 66 MHz PCI Clock */
+       SK_BOOL         GIVauxAvail;    /* VAUX available (YUKON) */
+       SK_BOOL         GIYukon32Bit;   /* 32-Bit YUKON adapter */
+       SK_BOOL         GIYukonLite;    /* YUKON-Lite chip */
+       int                     GIMacsFound;    /* Number of MACs found on this adapter */
+       int                     GIMacType;              /* MAC Type used on this adapter */
+       int                     GIHstClkFact;   /* Host Clock Factor (62.5 / HstClk * 100) */
+       int                     GIPortUsage;    /* Driver Port Usage */
+       int                     GILevel;                /* Initialization Level completed */
+       int                     GIRamSize;              /* The RAM size of the adapter in kB */
+       int                     GIWolOffs;              /* WOL Register Offset (HW-Bug in Rev. A) */
+       SK_U32          GIRamOffs;              /* RAM Address Offset for addr calculation */
+       SK_U32          GIPollTimerVal; /* Descr. Poll Timer Init Val (HstClk ticks) */
+       SK_GEPORT       GP[SK_MAX_MACS];/* Port Dependent Information */
+       SK_GEMACFUNC GIFunc;            /* MAC depedent functions */
+} SK_GEINIT;
+
+/*
+ * Error numbers and messages for skxmac2.c and skgeinit.c
+ */
+#define SKERR_HWI_E001         (SK_ERRBASE_HWINIT)
+#define SKERR_HWI_E001MSG      "SkXmClrExactAddr() has got illegal parameters"
+#define SKERR_HWI_E002         (SKERR_HWI_E001+1)
+#define SKERR_HWI_E002MSG      "SkGeInit(): Level 1 call missing"
+#define SKERR_HWI_E003         (SKERR_HWI_E002+1)
+#define SKERR_HWI_E003MSG      "SkGeInit() called with illegal init Level"
+#define SKERR_HWI_E004         (SKERR_HWI_E003+1)
+#define SKERR_HWI_E004MSG      "SkGeInitPort(): Queue Size illegal configured"
+#define SKERR_HWI_E005         (SKERR_HWI_E004+1)
+#define SKERR_HWI_E005MSG      "SkGeInitPort(): cannot init running ports"
+#define SKERR_HWI_E006         (SKERR_HWI_E005+1)
+#define SKERR_HWI_E006MSG      "SkGeMacInit(): PState does not match HW state"
+#define SKERR_HWI_E007         (SKERR_HWI_E006+1)
+#define SKERR_HWI_E007MSG      "SkXmInitDupMd() called with invalid Dup Mode"
+#define SKERR_HWI_E008         (SKERR_HWI_E007+1)
+#define SKERR_HWI_E008MSG      "SkXmSetRxCmd() called with invalid Mode"
+#define SKERR_HWI_E009         (SKERR_HWI_E008+1)
+#define SKERR_HWI_E009MSG      "SkGeCfgSync() called although PXSQSize zero"
+#define SKERR_HWI_E010         (SKERR_HWI_E009+1)
+#define SKERR_HWI_E010MSG      "SkGeCfgSync() called with invalid parameters"
+#define SKERR_HWI_E011         (SKERR_HWI_E010+1)
+#define SKERR_HWI_E011MSG      "SkGeInitPort(): Receive Queue Size too small"
+#define SKERR_HWI_E012         (SKERR_HWI_E011+1)
+#define SKERR_HWI_E012MSG      "SkGeInitPort(): invalid Queue Size specified"
+#define SKERR_HWI_E013         (SKERR_HWI_E012+1)
+#define SKERR_HWI_E013MSG      "SkGeInitPort(): cfg changed for running queue"
+#define SKERR_HWI_E014         (SKERR_HWI_E013+1)
+#define SKERR_HWI_E014MSG      "SkGeInitPort(): unknown GIPortUsage specified"
+#define SKERR_HWI_E015         (SKERR_HWI_E014+1)
+#define SKERR_HWI_E015MSG      "Illegal Link mode parameter"
+#define SKERR_HWI_E016         (SKERR_HWI_E015+1)
+#define SKERR_HWI_E016MSG      "Illegal Flow control mode parameter"
+#define SKERR_HWI_E017         (SKERR_HWI_E016+1)
+#define SKERR_HWI_E017MSG      "Illegal value specified for GIPollTimerVal"
+#define SKERR_HWI_E018         (SKERR_HWI_E017+1)
+#define SKERR_HWI_E018MSG      "FATAL: SkGeStopPort() does not terminate (Tx)"
+#define SKERR_HWI_E019         (SKERR_HWI_E018+1)
+#define SKERR_HWI_E019MSG      "Illegal Speed parameter"
+#define SKERR_HWI_E020         (SKERR_HWI_E019+1)
+#define SKERR_HWI_E020MSG      "Illegal Master/Slave parameter"
+#define SKERR_HWI_E021         (SKERR_HWI_E020+1)
+#define        SKERR_HWI_E021MSG       "MacUpdateStats(): cannot update statistic counter"
+#define        SKERR_HWI_E022          (SKERR_HWI_E021+1)
+#define        SKERR_HWI_E022MSG       "MacStatistic(): illegal statistic base address"
+#define SKERR_HWI_E023         (SKERR_HWI_E022+1)
+#define SKERR_HWI_E023MSG      "SkGeInitPort(): Transmit Queue Size too small"
+#define SKERR_HWI_E024         (SKERR_HWI_E023+1)
+#define SKERR_HWI_E024MSG      "FATAL: SkGeStopPort() does not terminate (Rx)"
+#define SKERR_HWI_E025         (SKERR_HWI_E024+1)
+#define SKERR_HWI_E025MSG      ""
+
+/* function prototypes ********************************************************/
+
+#ifndef        SK_KR_PROTO
+
+/*
+ * public functions in skgeinit.c
+ */
+extern void    SkGePollRxD(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       SK_BOOL PollRxD);
+
+extern void    SkGePollTxD(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       SK_BOOL PollTxD);
+
+extern void    SkGeYellowLED(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             State);
+
+extern int     SkGeCfgSync(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       SK_U32  IntTime,
+       SK_U32  LimCount,
+       int             SyncMode);
+
+extern void    SkGeLoadLnkSyncCnt(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       SK_U32  CntVal);
+
+extern void    SkGeStopPort(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       int             Dir,
+       int             RstMode);
+
+extern int     SkGeInit(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Level);
+
+extern void    SkGeDeInit(
+       SK_AC   *pAC,
+       SK_IOC  IoC);
+
+extern int     SkGeInitPort(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port);
+
+extern void    SkGeXmitLED(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Led,
+       int             Mode);
+
+extern void    SkGeInitRamIface(
+       SK_AC   *pAC,
+       SK_IOC  IoC);
+
+extern int     SkGeInitAssignRamToQueues(
+       SK_AC   *pAC,
+       int             ActivePort,
+       SK_BOOL DualNet);
+
+/*
+ * public functions in skxmac2.c
+ */
+extern void SkMacRxTxDisable(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port);
+
+extern void    SkMacSoftRst(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port);
+
+extern void    SkMacHardRst(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port);
+
+extern void    SkXmInitMac(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port);
+
+extern void    SkGmInitMac(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port);
+
+extern void SkMacInitPhy(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       SK_BOOL DoLoop);
+
+extern void SkMacIrqDisable(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port);
+
+extern void    SkMacFlushTxFifo(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port);
+
+extern void    SkMacFlushRxFifo(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port);
+
+extern void    SkMacIrq(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port);
+
+extern int     SkMacAutoNegDone(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port);
+
+extern void    SkMacAutoNegLipaPhy(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       SK_U16  IStatus);
+
+extern void  SkMacSetRxTxEn(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       int             Para);
+
+extern int  SkMacRxTxEnable(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port);
+
+extern void    SkMacPromiscMode(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       SK_BOOL Enable);
+
+extern void    SkMacHashing(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       SK_BOOL Enable);
+
+extern void    SkXmPhyRead(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       int             Addr,
+       SK_U16  *pVal);
+
+extern void    SkXmPhyWrite(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       int             Addr,
+       SK_U16  Val);
+
+extern void    SkGmPhyRead(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       int             Addr,
+       SK_U16  *pVal);
+
+extern void    SkGmPhyWrite(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       int             Addr,
+       SK_U16  Val);
+
+extern void    SkGePhyRead(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       int             Addr,
+       SK_U16  *pVal);
+
+extern void    SkGePhyWrite(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       int             Addr,
+       SK_U16  Val);
+
+extern void    SkXmClrExactAddr(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       int             StartNum,
+       int             StopNum);
+
+extern void    SkXmInitDupMd(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port);
+
+extern void    SkXmInitPauseMd(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port);
+
+extern void    SkXmAutoNegLipaXmac(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       SK_U16  IStatus);
+
+extern int SkXmUpdateStats(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       unsigned int Port);
+
+extern int SkGmUpdateStats(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       unsigned int Port);
+
+extern int SkXmMacStatistic(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       unsigned int Port,
+       SK_U16  StatAddr,
+       SK_U32  *pVal);
+
+extern int SkGmMacStatistic(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       unsigned int Port,
+       SK_U16  StatAddr,
+       SK_U32  *pVal);
+
+extern int SkXmResetCounter(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       unsigned int Port);
+
+extern int SkGmResetCounter(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       unsigned int Port);
+
+extern int SkXmOverflowStatus(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       unsigned int Port,
+       SK_U16  IStatus,
+       SK_U64  *pStatus);
+
+extern int SkGmOverflowStatus(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       unsigned int Port,
+       SK_U16  MacStatus,
+       SK_U64  *pStatus);
+
+extern int SkGmCableDiagStatus(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       SK_BOOL StartTest);
+
+#ifdef SK_DIAG
+extern void    SkMacSetRxCmd(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       int             Mode);
+extern void    SkMacCrcGener(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       SK_BOOL Enable);
+extern void    SkMacTimeStamp(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       SK_BOOL Enable);
+extern void    SkXmSendCont(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       SK_BOOL Enable);
+#endif /* SK_DIAG */
+
+#else  /* SK_KR_PROTO */
+
+/*
+ * public functions in skgeinit.c
+ */
+extern void    SkGePollRxD();
+extern void    SkGePollTxD();
+extern void    SkGeYellowLED();
+extern int     SkGeCfgSync();
+extern void    SkGeLoadLnkSyncCnt();
+extern void    SkGeStopPort();
+extern int     SkGeInit();
+extern void    SkGeDeInit();
+extern int     SkGeInitPort();
+extern void    SkGeXmitLED();
+extern void    SkGeInitRamIface();
+extern int     SkGeInitAssignRamToQueues();
+
+/*
+ * public functions in skxmac2.c
+ */
+extern void SkMacRxTxDisable();
+extern void    SkMacSoftRst();
+extern void    SkMacHardRst();
+extern void SkMacInitPhy();
+extern int  SkMacRxTxEnable();
+extern void SkMacPromiscMode();
+extern void SkMacHashing();
+extern void SkMacIrqDisable();
+extern void    SkMacFlushTxFifo();
+extern void    SkMacFlushRxFifo();
+extern void    SkMacIrq();
+extern int     SkMacAutoNegDone();
+extern void    SkMacAutoNegLipaPhy();
+extern void SkMacSetRxTxEn();
+extern void    SkGePhyRead();
+extern void    SkGePhyWrite();
+extern void    SkXmInitMac();
+extern void    SkXmPhyRead();
+extern void    SkXmPhyWrite();
+extern void    SkGmInitMac();
+extern void    SkGmPhyRead();
+extern void    SkGmPhyWrite();
+extern void    SkXmClrExactAddr();
+extern void    SkXmInitDupMd();
+extern void    SkXmInitPauseMd();
+extern void    SkXmAutoNegLipaXmac();
+extern int     SkXmUpdateStats();
+extern int     SkGmUpdateStats();
+extern int     SkXmMacStatistic();
+extern int     SkGmMacStatistic();
+extern int     SkXmResetCounter();
+extern int     SkGmResetCounter();
+extern int     SkXmOverflowStatus();
+extern int     SkGmOverflowStatus();
+extern int     SkGmCableDiagStatus();
+
+#ifdef SK_DIAG
+extern void    SkMacSetRxCmd();
+extern void    SkMacCrcGener();
+extern void    SkMacTimeStamp();
+extern void    SkXmSendCont();
+#endif /* SK_DIAG */
+
+#endif /* SK_KR_PROTO */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __INC_SKGEINIT_H_ */
diff --git a/drivers/net/sk98lin/h/skgepnm2.h b/drivers/net/sk98lin/h/skgepnm2.h
new file mode 100644 (file)
index 0000000..5c44f47
--- /dev/null
@@ -0,0 +1,462 @@
+/*****************************************************************************
+ *
+ * Name:       skgepnm2.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.34 $
+ * Date:       $Date: 2002/12/16 09:05:18 $
+ * Purpose:    Defines for Private Network Management Interface
+ *
+ ****************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2001 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/*****************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skgepnm2.h,v $
+ *     Revision 1.34  2002/12/16 09:05:18  tschilli
+ *     Code for VCT handling added.
+ *
+ *     Revision 1.33  2002/09/10 09:00:03  rwahl
+ *     Adapted boolean definitions according sktypes.
+ *
+ *     Revision 1.32  2002/08/09 09:47:01  rwahl
+ *     Added write-only flag to oid access defines.
+ *     Editorial changes.
+ *
+ *     Revision 1.31  2002/07/17 19:23:18  rwahl
+ *     - Replaced MAC counter definitions by enumeration.
+ *     - Added definition SK_PNMI_MAC_TYPES.
+ *     - Added chipset defnition for Yukon.
+ *
+ *     Revision 1.30  2001/02/06 10:03:41  mkunz
+ *     - Pnmi V4 dual net support added. Interface functions and macros extended
+ *     - Vpd bug fixed
+ *     - OID_SKGE_MTU added
+ *
+ *     Revision 1.29  2001/01/22 13:41:37  rassmann
+ *     Supporting two nets on dual-port adapters.
+ *
+ *     Revision 1.28  2000/08/03 15:12:48  rwahl
+ *     - Additional comment for MAC statistic data structure.
+ *
+ *     Revision 1.27  2000/08/01 16:10:18  rwahl
+ *     - Added mac statistic data structure for StatRxLongFrame counter.
+ *
+ *     Revision 1.26  2000/03/31 13:51:34  rwahl
+ *     Added SK_UPTR cast to offset calculation for PNMI struct fields;
+ *     missing cast caused compiler warnings by Win64 compiler.
+ *
+ *     Revision 1.25  1999/11/22 13:57:41  cgoos
+ *     Changed license header to GPL.
+ *     Allowing overwrite for SK_PNMI_STORE/_READ defines.
+ *
+ *     Revision 1.24  1999/04/13 15:11:11  mhaveman
+ *     Changed copyright.
+ *
+ *     Revision 1.23  1999/01/28 15:07:12  mhaveman
+ *     Changed default threshold for port switches per hour from 10
+ *     to 240 which means 4 switches per minute. This fits better
+ *     the granularity of 32 for the port switch estimate
+ *     counter.
+ *
+ *     Revision 1.22  1999/01/05 12:52:30  mhaveman
+ *     Removed macro SK_PNMI_MICRO_SEC.
+ *
+ *     Revision 1.21  1999/01/05 12:50:34  mhaveman
+ *     Enlarged macro definition SK_PNMI_HUNDREDS_SEC() so that no 64-bit
+ *     arithmetic is necessary if SK_TICKS_PER_SEC is 100.
+ *
+ *     Revision 1.20  1998/12/09 14:02:53  mhaveman
+ *     Defined macro SK_PNMI_DEF_RLMT_CHG_THRES for default port switch
+ *     threshold.
+ *
+ *     Revision 1.19  1998/12/03 11:28:41  mhaveman
+ *     Removed SK_PNMI_CHECKPTR macro.
+ *
+ *     Revision 1.18  1998/12/03 11:21:00  mhaveman
+ *     -Added pointer check macro SK_PNMI_CHECKPTR
+ *     -Added macros SK_PNMI_VPD_ARR_SIZE and SK_PNMI_VPD_STR_SIZE for
+ *      VPD key evaluation.
+ *
+ *     Revision 1.17  1998/11/20 13:20:33  mhaveman
+ *     Fixed bug in SK_PNMI_SET_STAT macro. ErrorStatus was not correctly set.
+ *
+ *     Revision 1.16  1998/11/20 08:08:49  mhaveman
+ *     Macro SK_PNMI_CHECKFLAGS has got a if clause.
+ *
+ *     Revision 1.15  1998/11/03 13:53:40  mhaveman
+ *     Fixed alignment problem in macor SK_PNMI_SET_STAT macro.
+ *
+ *     Revision 1.14  1998/10/30 15:50:13  mhaveman
+ *     Added macro SK_PNMI_MICRO_SEC()
+ *
+ *     Revision 1.13  1998/10/30 12:32:20  mhaveman
+ *     Added forgotten cast in SK_PNMI_READ_U32 macro.
+ *
+ *     Revision 1.12  1998/10/29 15:40:26  mhaveman
+ *     -Changed SK_PNMI_TRAP_SENSOR_LEN because SensorDescr has now
+ *      variable string length.
+ *     -Defined SK_PNMI_CHECKFLAGS macro
+ *
+ *     Revision 1.11  1998/10/29 08:53:34  mhaveman
+ *     Removed SK_PNMI_RLM_XXX table indexed because these counters need
+ *     not been saved over XMAC resets.
+ *
+ *     Revision 1.10  1998/10/28 08:48:20  mhaveman
+ *     -Added macros for storage according to alignment
+ *     -Changed type of Instance to SK_U32 because of VPD
+ *     -Removed trap structures. Not needed because of alignment problem
+ *     -Changed type of Action form SK_U8 to int
+ *
+ *     Revision 1.9  1998/10/21 13:34:45  mhaveman
+ *     Shit, mismatched calculation of SK_PNMI_HUNDREDS_SEC. Corrected.
+ *
+ *     Revision 1.8  1998/10/21 13:24:58  mhaveman
+ *     Changed calculation of hundreds of seconds.
+ *
+ *     Revision 1.7  1998/10/20 07:31:41  mhaveman
+ *     Made type changes to unsigned int where possible.
+ *
+ *     Revision 1.6  1998/09/04 17:04:05  mhaveman
+ *     Added Sync counters to offset storage to provided settled values on
+ *     port switch.
+ *
+ *     Revision 1.5  1998/09/04 12:45:35  mhaveman
+ *     Removed dummies for SK_DRIVER_ macros. They should be added by driver
+ *     writer in skdrv2nd.h.
+ *
+ *     Revision 1.4  1998/09/04 11:59:50  mhaveman
+ *     Everything compiles now. Driver Macros for counting still missing.
+ *
+ *     Revision 1.3  1998/08/24 12:01:35  mhaveman
+ *     Intermediate state.
+ *
+ *     Revision 1.2  1998/08/17 07:51:40  mhaveman
+ *     Intermediate state.
+ *
+ *     Revision 1.1  1998/08/11 09:08:40  mhaveman
+ *     Intermediate state.
+ *
+ ****************************************************************************/
+
+#ifndef _SKGEPNM2_H_
+#define _SKGEPNM2_H_
+
+/*
+ * General definitions
+ */
+#define SK_PNMI_CHIPSET_XMAC   1       /* XMAC11800FP */
+#define SK_PNMI_CHIPSET_YUKON  2       /* YUKON */
+
+#define        SK_PNMI_BUS_PCI         1       /* PCI bus*/
+
+/*
+ * Actions
+ */
+#define SK_PNMI_ACT_IDLE               1
+#define SK_PNMI_ACT_RESET              2
+#define SK_PNMI_ACT_SELFTEST   3
+#define SK_PNMI_ACT_RESETCNT   4
+
+/*
+ * VPD releated defines
+ */
+
+#define SK_PNMI_VPD_RW         1
+#define SK_PNMI_VPD_RO         2
+
+#define SK_PNMI_VPD_OK                 0
+#define SK_PNMI_VPD_NOTFOUND   1
+#define SK_PNMI_VPD_CUT                        2
+#define SK_PNMI_VPD_TIMEOUT            3
+#define SK_PNMI_VPD_FULL               4
+#define SK_PNMI_VPD_NOWRITE            5
+#define SK_PNMI_VPD_FATAL              6
+
+#define SK_PNMI_VPD_IGNORE     0
+#define SK_PNMI_VPD_CREATE     1
+#define SK_PNMI_VPD_DELETE     2
+
+
+/*
+ * RLMT related defines
+ */
+#define SK_PNMI_DEF_RLMT_CHG_THRES     240     /* 4 changes per minute */
+
+
+/*
+ * VCT internal status values
+ */
+#define SK_PNMI_VCT_PENDING    32
+#define SK_PNMI_VCT_TEST_DONE  64
+#define SK_PNMI_VCT_LINK       128
+
+/*
+ * Internal table definitions
+ */
+#define SK_PNMI_GET            0
+#define SK_PNMI_PRESET 1
+#define SK_PNMI_SET            2
+
+#define SK_PNMI_RO             0
+#define SK_PNMI_RW             1
+#define SK_PNMI_WO             2
+
+typedef struct s_OidTabEntry {
+       SK_U32                  Id;
+       SK_U32                  InstanceNo;
+       unsigned int    StructSize;
+       unsigned int    Offset;
+       int                             Access;
+       int                             (* Func)(SK_AC *pAc, SK_IOC pIo, int action,
+                                                        SK_U32 Id, char* pBuf, unsigned int* pLen,
+                                                        SK_U32 Instance, unsigned int TableIndex,
+                                                        SK_U32 NetNumber);
+       SK_U16                  Param;
+} SK_PNMI_TAB_ENTRY;
+
+
+/*
+ * Trap lengths
+ */
+#define SK_PNMI_TRAP_SIMPLE_LEN                        17
+#define SK_PNMI_TRAP_SENSOR_LEN_BASE   46
+#define SK_PNMI_TRAP_RLMT_CHANGE_LEN   23
+#define SK_PNMI_TRAP_RLMT_PORT_LEN             23
+
+/*
+ * Number of MAC types supported
+ */
+#define SK_PNMI_MAC_TYPES      (SK_MAC_GMAC + 1)
+
+/*
+ * MAC statistic data list (overall set for MAC types used)
+ */
+enum SK_MACSTATS {
+       SK_PNMI_HTX                             = 0,
+       SK_PNMI_HTX_OCTET,
+       SK_PNMI_HTX_OCTETHIGH   = SK_PNMI_HTX_OCTET,
+       SK_PNMI_HTX_OCTETLOW,
+       SK_PNMI_HTX_BROADCAST,
+       SK_PNMI_HTX_MULTICAST,
+       SK_PNMI_HTX_UNICAST,
+       SK_PNMI_HTX_BURST,
+       SK_PNMI_HTX_PMACC,
+       SK_PNMI_HTX_MACC,
+       SK_PNMI_HTX_COL,
+       SK_PNMI_HTX_SINGLE_COL,
+       SK_PNMI_HTX_MULTI_COL,
+       SK_PNMI_HTX_EXCESS_COL,
+       SK_PNMI_HTX_LATE_COL,
+       SK_PNMI_HTX_DEFFERAL,
+       SK_PNMI_HTX_EXCESS_DEF,
+       SK_PNMI_HTX_UNDERRUN,
+       SK_PNMI_HTX_CARRIER,
+       SK_PNMI_HTX_UTILUNDER,
+       SK_PNMI_HTX_UTILOVER,
+       SK_PNMI_HTX_64,
+       SK_PNMI_HTX_127,
+       SK_PNMI_HTX_255,
+       SK_PNMI_HTX_511,
+       SK_PNMI_HTX_1023,
+       SK_PNMI_HTX_MAX,
+       SK_PNMI_HTX_LONGFRAMES,
+       SK_PNMI_HTX_SYNC,
+       SK_PNMI_HTX_SYNC_OCTET,
+       SK_PNMI_HTX_RESERVED,
+
+       SK_PNMI_HRX,
+       SK_PNMI_HRX_OCTET,
+       SK_PNMI_HRX_OCTETHIGH   = SK_PNMI_HRX_OCTET,
+       SK_PNMI_HRX_OCTETLOW,
+       SK_PNMI_HRX_BADOCTET,
+       SK_PNMI_HRX_BADOCTETHIGH = SK_PNMI_HRX_BADOCTET,
+       SK_PNMI_HRX_BADOCTETLOW,
+       SK_PNMI_HRX_BROADCAST,
+       SK_PNMI_HRX_MULTICAST,
+       SK_PNMI_HRX_UNICAST,
+       SK_PNMI_HRX_PMACC,
+       SK_PNMI_HRX_MACC,
+       SK_PNMI_HRX_PMACC_ERR,
+       SK_PNMI_HRX_MACC_UNKWN,
+       SK_PNMI_HRX_BURST,
+       SK_PNMI_HRX_MISSED,
+       SK_PNMI_HRX_FRAMING,
+       SK_PNMI_HRX_UNDERSIZE,
+       SK_PNMI_HRX_OVERFLOW,
+       SK_PNMI_HRX_JABBER,
+       SK_PNMI_HRX_CARRIER,
+       SK_PNMI_HRX_IRLENGTH,
+       SK_PNMI_HRX_SYMBOL,
+       SK_PNMI_HRX_SHORTS,
+       SK_PNMI_HRX_RUNT,
+       SK_PNMI_HRX_TOO_LONG,
+       SK_PNMI_HRX_FCS,
+       SK_PNMI_HRX_CEXT,
+       SK_PNMI_HRX_UTILUNDER,
+       SK_PNMI_HRX_UTILOVER,
+       SK_PNMI_HRX_64,
+       SK_PNMI_HRX_127,
+       SK_PNMI_HRX_255,
+       SK_PNMI_HRX_511,
+       SK_PNMI_HRX_1023,
+       SK_PNMI_HRX_MAX,
+       SK_PNMI_HRX_LONGFRAMES,
+
+       SK_PNMI_HRX_RESERVED,
+
+       SK_PNMI_MAX_IDX         /* NOTE: Ensure SK_PNMI_CNT_NO is set to this value */
+};
+
+/*
+ * MAC specific data
+ */
+typedef struct s_PnmiStatAddr {
+       SK_U16          Reg;            /* MAC register containing the value */
+       SK_BOOL         GetOffset;      /* TRUE: Offset managed by PNMI (call GetStatVal())*/
+} SK_PNMI_STATADDR;
+
+
+/*
+ * SK_PNMI_STRUCT_DATA copy offset evaluation macros
+ */
+#define SK_PNMI_OFF(e)         ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
+#define SK_PNMI_MAI_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
+#define SK_PNMI_VPD_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_VPD *)0)->e))
+#define SK_PNMI_SEN_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_SENSOR *)0)->e))
+#define SK_PNMI_CHK_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_CHECKSUM *)0)->e))
+#define SK_PNMI_STA_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_STAT *)0)->e))
+#define SK_PNMI_CNF_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_CONF *)0)->e))
+#define SK_PNMI_RLM_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT *)0)->e))
+#define SK_PNMI_MON_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT_MONITOR *)0)->e))
+#define SK_PNMI_TRP_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_TRAP *)0)->e))
+
+#define SK_PNMI_SET_STAT(b,s,o)        {SK_U32 Val32; char *pVal; \
+                                       Val32 = (s); \
+                                       pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
+                                               &(((SK_PNMI_STRUCT_DATA *)0)-> \
+                                               ReturnStatus.ErrorStatus)); \
+                                       SK_PNMI_STORE_U32(pVal, Val32); \
+                                       Val32 = (o); \
+                                       pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
+                                               &(((SK_PNMI_STRUCT_DATA *)0)-> \
+                                               ReturnStatus.ErrorOffset)); \
+                                       SK_PNMI_STORE_U32(pVal, Val32);}
+
+/*
+ * Time macros
+ */
+#if SK_TICKS_PER_SEC == 100
+#define SK_PNMI_HUNDREDS_SEC(t)        (t)
+#else
+#define SK_PNMI_HUNDREDS_SEC(t)        (((t) * 100) / (SK_TICKS_PER_SEC))
+#endif
+
+/*
+ * Macros to work around alignment problems
+ */
+#ifndef SK_PNMI_STORE_U16
+#define SK_PNMI_STORE_U16(p,v) {*(char *)(p) = *((char *)&(v)); \
+                                       *((char *)(p) + 1) = \
+                                               *(((char *)&(v)) + 1);}
+#endif
+
+#ifndef SK_PNMI_STORE_U32
+#define SK_PNMI_STORE_U32(p,v) {*(char *)(p) = *((char *)&(v)); \
+                                       *((char *)(p) + 1) = \
+                                               *(((char *)&(v)) + 1); \
+                                       *((char *)(p) + 2) = \
+                                               *(((char *)&(v)) + 2); \
+                                       *((char *)(p) + 3) = \
+                                               *(((char *)&(v)) + 3);}
+#endif
+
+#ifndef SK_PNMI_STORE_U64
+#define SK_PNMI_STORE_U64(p,v) {*(char *)(p) = *((char *)&(v)); \
+                                       *((char *)(p) + 1) = \
+                                               *(((char *)&(v)) + 1); \
+                                       *((char *)(p) + 2) = \
+                                               *(((char *)&(v)) + 2); \
+                                       *((char *)(p) + 3) = \
+                                               *(((char *)&(v)) + 3); \
+                                       *((char *)(p) + 4) = \
+                                               *(((char *)&(v)) + 4); \
+                                       *((char *)(p) + 5) = \
+                                               *(((char *)&(v)) + 5); \
+                                       *((char *)(p) + 6) = \
+                                               *(((char *)&(v)) + 6); \
+                                       *((char *)(p) + 7) = \
+                                               *(((char *)&(v)) + 7);}
+#endif
+
+#ifndef SK_PNMI_READ_U16
+#define SK_PNMI_READ_U16(p,v)  {*((char *)&(v)) = *(char *)(p); \
+                                       *(((char *)&(v)) + 1) = \
+                                               *((char *)(p) + 1);}
+#endif
+
+#ifndef SK_PNMI_READ_U32
+#define SK_PNMI_READ_U32(p,v)  {*((char *)&(v)) = *(char *)(p); \
+                                       *(((char *)&(v)) + 1) = \
+                                               *((char *)(p) + 1); \
+                                       *(((char *)&(v)) + 2) = \
+                                               *((char *)(p) + 2); \
+                                       *(((char *)&(v)) + 3) = \
+                                               *((char *)(p) + 3);}
+#endif
+
+#ifndef SK_PNMI_READ_U64
+#define SK_PNMI_READ_U64(p,v)  {*((char *)&(v)) = *(char *)(p); \
+                                       *(((char *)&(v)) + 1) = \
+                                               *((char *)(p) + 1); \
+                                       *(((char *)&(v)) + 2) = \
+                                               *((char *)(p) + 2); \
+                                       *(((char *)&(v)) + 3) = \
+                                               *((char *)(p) + 3); \
+                                       *(((char *)&(v)) + 4) = \
+                                               *((char *)(p) + 4); \
+                                       *(((char *)&(v)) + 5) = \
+                                               *((char *)(p) + 5); \
+                                       *(((char *)&(v)) + 6) = \
+                                               *((char *)(p) + 6); \
+                                       *(((char *)&(v)) + 7) = \
+                                               *((char *)(p) + 7);}
+#endif
+
+/*
+ * Macros for Debug
+ */
+#ifdef DEBUG
+
+#define SK_PNMI_CHECKFLAGS(vSt)        {if (pAC->Pnmi.MacUpdatedFlag > 0 || \
+                                       pAC->Pnmi.RlmtUpdatedFlag > 0 || \
+                                       pAC->Pnmi.SirqUpdatedFlag > 0) { \
+                                               SK_DBG_MSG(pAC, \
+                                               SK_DBGMOD_PNMI, \
+                                               SK_DBGCAT_CTRL, \
+                                               ("PNMI: ERR: %s MacUFlag=%d, RlmtUFlag=%d, SirqUFlag=%d\n", \
+                                               vSt, \
+                                               pAC->Pnmi.MacUpdatedFlag, \
+                                               pAC->Pnmi.RlmtUpdatedFlag, \
+                                               pAC->Pnmi.SirqUpdatedFlag))}}
+
+#else  /* !DEBUG */
+
+#define SK_PNMI_CHECKFLAGS(vSt)        /* Nothing */
+
+#endif /* !DEBUG */
+
+#endif /* _SKGEPNM2_H_ */
diff --git a/drivers/net/sk98lin/h/skgepnmi.h b/drivers/net/sk98lin/h/skgepnmi.h
new file mode 100644 (file)
index 0000000..7532313
--- /dev/null
@@ -0,0 +1,1114 @@
+/*****************************************************************************
+ *
+ * Name:       skgepnmi.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.59 $
+ * Date:       $Date: 2002/12/16 14:03:50 $
+ * Purpose:    Defines for Private Network Management Interface
+ *
+ ****************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2001 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/*****************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skgepnmi.h,v $
+ *     Revision 1.59  2002/12/16 14:03:50  tschilli
+ *     New defines for VCT added.
+ *
+ *     Revision 1.58  2002/12/16 09:04:59  tschilli
+ *     Code for VCT handling added.
+ *
+ *     Revision 1.57  2002/09/26 12:41:05  tschilli
+ *     SK_PNMI_PORT BufPort entry in struct SK_PNMI added.
+ *
+ *     Revision 1.56  2002/08/16 11:10:41  rwahl
+ *     - Replaced c++ comment.
+ *
+ *     Revision 1.55  2002/08/09 15:40:21  rwahl
+ *     Editorial change (renamed ConfSpeedCap).
+ *
+ *     Revision 1.54  2002/08/09 11:06:07  rwahl
+ *     Added OID_SKGE_SPEED_CAP.
+ *
+ *     Revision 1.53  2002/08/09 09:45:28  rwahl
+ *     Added support for NDIS OID_PNP_xxx.
+ *     Editorial changes.
+ *
+ *     Revision 1.52  2002/08/06 17:54:07  rwahl
+ *     - Added speed cap to PNMI config struct.
+ *
+ *     Revision 1.51  2002/07/17 19:19:26  rwahl
+ *     - Added OID_SKGE_SPEED_MODE and OID_SKGE_SPEED_STATUS.
+ *     - Added SK_PNMI_CNT_RX_PMACC_ERR() & SK_PNMI_CNT_RX_LONGFRAMES().
+ *     - Added speed mode & status to PNMI config struct.
+ *     - Editorial changes.
+ *
+ *     Revision 1.50  2002/05/22 08:59:37  rwahl
+ *     Added string definitions for error msgs.
+ *
+ *     Revision 1.49  2001/11/20 09:23:50  rwahl
+ *     - pnmi struct: reordered and aligned to 32bit.
+ *
+ *     Revision 1.48  2001/02/23 14:34:24  mkunz
+ *     Changed macro PHYS2INST. Added pAC to Interface
+ *
+ *     Revision 1.47  2001/02/07 08:28:23  mkunz
+ *     - Added Oids:   OID_SKGE_DIAG_ACTION
+ *                                     OID_SKGE_DIAG_RESULT
+ *                                     OID_SKGE_MULTICAST_LIST
+ *                                     OID_SKGE_CURRENT_PACKET_FILTER
+ *                                     OID_SKGE_INTERMEDIATE_SUPPORT
+ *     - Changed value of OID_SKGE_MTU
+ *
+ *     Revision 1.46  2001/02/06 10:01:41  mkunz
+ *     - Pnmi V4 dual net support added. Interface functions and macros extended
+ *     - Vpd bug fixed
+ *     - OID_SKGE_MTU added
+ *
+ *     Revision 1.45  2001/01/22 13:41:37  rassmann
+ *     Supporting two nets on dual-port adapters.
+ *
+ *     Revision 1.44  2000/09/07 07:35:27  rwahl
+ *     - removed NDIS counter specific data type.
+ *     - fixed spelling for OID_SKGE_RLMT_PORT_PREFERRED.
+ *
+ *     Revision 1.43  2000/08/04 11:41:08  rwahl
+ *     - Fixed compiler warning (port is always >= 0) for macros
+ *       SK_PNMI_CNT_RX_LONGFRAMES & SK_PNMI_CNT_SYNC_OCTETS
+ *
+ *     Revision 1.42  2000/08/03 15:14:07  rwahl
+ *     - Corrected error in driver macros addressing a physical port.
+ *
+ *     Revision 1.41  2000/08/01 16:22:29  rwahl
+ *     - Changed MDB version to 3.1.
+ *     - Added definitions for StatRxLongFrames counter.
+ *     - Added macro to be used by driver to count long frames received.
+ *     - Added directive to control width (default = 32bit) of NDIS statistic
+ *       counters (SK_NDIS_64BIT_CTR).
+ *
+ *     Revision 1.40  2000/03/31 13:51:34  rwahl
+ *     Added SK_UPTR cast to offset calculation for PNMI struct fields;
+ *     missing cast caused compiler warnings by Win64 compiler.
+ *
+ *     Revision 1.39  1999/12/06 10:09:47  rwahl
+ *     Added new error log message.
+ *
+ *     Revision 1.38  1999/11/22 13:57:55  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.37  1999/09/14 14:25:32  rwahl
+ *     Set MDB version for 1000Base-T (sensors, Master/Slave) changes.
+ *
+ *     Revision 1.36  1999/05/20 09:24:56  cgoos
+ *     Changes for 1000Base-T (sensors, Master/Slave).
+ *
+ *     Revision 1.35  1999/04/13 15:10:51  mhaveman
+ *     Replaced RLMT macros SK_RLMT_CHECK_xxx again by those of PNMI to
+ *     grant unified interface. But PNMI macros will store the same
+ *     value as RLMT macros.
+ *
+ *     Revision 1.34  1999/04/13 15:03:49  mhaveman
+ *     -Changed copyright
+ *     -Removed SK_PNMI_RLMT_MODE_CHK_xxx macros. Those of RLMT should be
+ *      used.
+ *
+ *     Revision 1.33  1999/03/23 10:41:02  mhaveman
+ *     Changed comments.
+ *
+ *     Revision 1.32  1999/01/25 15:01:33  mhaveman
+ *     Added support for multiple simultaniously active ports.
+ *
+ *     Revision 1.31  1999/01/19 10:06:26  mhaveman
+ *     Added new error log message.
+ *
+ *     Revision 1.30  1999/01/05 10:34:49  mhaveman
+ *     Fixed little error in RlmtChangeEstimate calculation.
+ *
+ *     Revision 1.29  1999/01/05 09:59:41  mhaveman
+ *     Redesigned port switch average calculation to avoid 64bit
+ *     arithmetic.
+ *
+ *     Revision 1.28  1998/12/08 10:05:48  mhaveman
+ *     Defined macro SK_PNMI_MIN_STRUCT_SIZE.
+ *
+ *     Revision 1.27  1998/12/03 14:39:35  mhaveman
+ *     Fixed problem that LSTAT was enumerated wrong.
+ *
+ *     Revision 1.26  1998/12/03 11:19:51  mhaveman
+ *     Changed contents of errlog message SK_PNMI_ERR016MSG
+ *
+ *     Revision 1.25  1998/12/01 10:40:04  mhaveman
+ *     Changed size of SensorNumber, ChecksumNumber and RlmtPortNumber in
+ *     SK_PNMI_STRUCT_DATA to be conform with OID definition.
+ *
+ *     Revision 1.24  1998/11/20 08:09:27  mhaveman
+ *     Added macros to convert between logical, physical port indexes and
+ *     instances.
+ *
+ *     Revision 1.23  1998/11/10 13:41:13  mhaveman
+ *     Needed to change interface, because NT driver needs a return value
+ *     of needed buffer space on TOO_SHORT errors. Therefore all
+ *     SkPnmiGet/Preset/Set functions now have a pointer to the length
+ *     parameter, where the needed space on error is returned.
+ *
+ *     Revision 1.22  1998/11/03 12:05:51  mhaveman
+ *     Added pAC parameter to counter macors.
+ *
+ *     Revision 1.21  1998/11/02 10:47:36  mhaveman
+ *     Added syslog messages for internal errors.
+ *
+ *     Revision 1.20  1998/10/30 15:49:36  mhaveman
+ *     -Removed unused SK_PNMI_UTILIZATION_BASE and EstOldCnt.
+ *     -Redefined SK_PNMI_CHG_EST_BASE to hundreds of seconds.
+ *
+ *     Revision 1.19  1998/10/29 15:38:44  mhaveman
+ *     Changed string lengths of PNMI_STRUCT_DATA structure because
+ *     string OIDs are now encoded with leading length ocetet.
+ *
+ *     Revision 1.18  1998/10/29 08:52:27  mhaveman
+ *     -Added byte to strings in PNMI_STRUCT_DATA structure.
+ *     -Shortened SK_PNMI_RLMT structure to SK_MAX_MACS elements.
+ *
+ *     Revision 1.17  1998/10/28 08:49:50  mhaveman
+ *     -Changed type of Instance back to SK_U32 because of VPD
+ *     -Changed type from SK_U8 to char of PciBusSpeed, PciBusWidth, PMD,
+ *      and Connector.
+ *
+ *     Revision 1.16  1998/10/22 10:42:31  mhaveman
+ *     -Removed (SK_U32) casts for OIDs
+ *     -excluded NDIS OIDs when they are already defined with ifndef _NDIS_
+ *
+ *     Revision 1.15  1998/10/20 13:56:28  mhaveman
+ *     Headerfile includes now directly other header files to comile correctly.
+ *
+ *     Revision 1.14  1998/10/20 07:31:09  mhaveman
+ *     Made type changes to unsigned int where possible.
+ *
+ *     Revision 1.13  1998/10/19 10:53:13  mhaveman
+ *     -Casted OID definitions to SK_U32
+ *     -Renamed RlmtMAC... to RlmtPort...
+ *     -Changed wrong type of VpdEntriesList from SK_U32 to char *
+ *
+ *     Revision 1.12  1998/10/13 07:42:27  mhaveman
+ *     -Added OIDs OID_SKGE_TRAP_NUMBER and OID_SKGE_ALL_DATA
+ *     -Removed old cvs history entries
+ *     -Renamed MacNumber to PortNumber
+ *
+ *     Revision 1.11  1998/10/07 10:55:24  mhaveman
+ *     -Added OID_MDB_VERSION. Therefore was a renumbering of the VPD OIDs
+ *      necessary.
+ *     -Added OID_GEN_ Ids to support the windows driver.
+ *
+ *     Revision 1.10  1998/09/30 13:41:10  mhaveman
+ *     Renamed some OIDs to reduce usage of 'MAC' which is replaced by 'PORT'.
+ *
+ *     Revision 1.9  1998/09/04 17:06:17  mhaveman
+ *     -Added SyncCounter as macro.
+ *     -Renamed OID_SKGE_.._NO_DESCR_CTS to OID_SKGE_.._NO_BUF_CTS.
+ *     -Added macros for driver description and version strings.
+ *
+ *     Revision 1.8  1998/09/04 14:36:52  mhaveman
+ *     Added OIDs and Structure to access value of macro counters which are
+ *     counted by the driver.
+ *
+ *     Revision 1.7  1998/09/04 11:59:36  mhaveman
+ *     Everything compiles now. Driver Macros for counting still missing.
+ *
+ ****************************************************************************/
+
+#ifndef _SKGEPNMI_H_
+#define _SKGEPNMI_H_
+
+/*
+ * Include dependencies
+ */
+#include "h/sktypes.h"
+#include "h/skerror.h"
+#include "h/sktimer.h"
+#include "h/ski2c.h"
+#include "h/skaddr.h"
+#include "h/skrlmt.h"
+#include "h/skvpd.h"
+
+/*
+ * Management Database Version
+ */
+#define SK_PNMI_MDB_VERSION            0x00030001      /* 3.1 */
+
+
+/*
+ * Event definitions
+ */
+#define SK_PNMI_EVT_SIRQ_OVERFLOW              1       /* Counter overflow */
+#define SK_PNMI_EVT_SEN_WAR_LOW                        2       /* Lower war thres exceeded */
+#define SK_PNMI_EVT_SEN_WAR_UPP                        3       /* Upper war thres exceeded */
+#define SK_PNMI_EVT_SEN_ERR_LOW                        4       /* Lower err thres exceeded */
+#define SK_PNMI_EVT_SEN_ERR_UPP                        5       /* Upper err thres exceeded */
+#define SK_PNMI_EVT_CHG_EST_TIMER              6       /* Timer event for RLMT Chg */
+#define SK_PNMI_EVT_UTILIZATION_TIMER  7       /* Timer event for Utiliza. */
+#define SK_PNMI_EVT_CLEAR_COUNTER              8       /* Clear statistic counters */
+#define SK_PNMI_EVT_XMAC_RESET                 9       /* XMAC will be reset */
+
+#define SK_PNMI_EVT_RLMT_PORT_UP               10      /* Port came logically up */
+#define SK_PNMI_EVT_RLMT_PORT_DOWN             11      /* Port went logically down */
+#define SK_PNMI_EVT_RLMT_SEGMENTATION  13      /* Two SP root bridges found */
+#define SK_PNMI_EVT_RLMT_ACTIVE_DOWN   14      /* Port went logically down */
+#define SK_PNMI_EVT_RLMT_ACTIVE_UP             15      /* Port came logically up */
+#define SK_PNMI_EVT_RLMT_SET_NETS              16      /* 1. Parameter is number of nets
+                                                                                               1 = single net; 2 = dual net */
+#define SK_PNMI_EVT_VCT_RESET          17      /* VCT port reset timer event started with SET. */
+
+
+/*
+ * Return values
+ */
+#define SK_PNMI_ERR_OK                         0
+#define SK_PNMI_ERR_GENERAL                    1
+#define SK_PNMI_ERR_TOO_SHORT          2
+#define SK_PNMI_ERR_BAD_VALUE          3
+#define SK_PNMI_ERR_READ_ONLY          4
+#define SK_PNMI_ERR_UNKNOWN_OID                5
+#define SK_PNMI_ERR_UNKNOWN_INST       6
+#define SK_PNMI_ERR_UNKNOWN_NET        7
+
+
+/*
+ * Return values of driver reset function SK_DRIVER_RESET() and
+ * driver event function SK_DRIVER_EVENT()
+ */
+#define SK_PNMI_ERR_OK                 0
+#define SK_PNMI_ERR_FAIL               1
+
+
+/*
+ * Return values of driver test function SK_DRIVER_SELFTEST()
+ */
+#define SK_PNMI_TST_UNKNOWN            (1 << 0)
+#define SK_PNMI_TST_TRANCEIVER         (1 << 1)
+#define SK_PNMI_TST_ASIC               (1 << 2)
+#define SK_PNMI_TST_SENSOR             (1 << 3)
+#define SK_PNMI_TST_POWERMGMT          (1 << 4)
+#define SK_PNMI_TST_PCI                        (1 << 5)
+#define SK_PNMI_TST_MAC                        (1 << 6)
+
+
+/*
+ * RLMT specific definitions
+ */
+#define SK_PNMI_RLMT_STATUS_STANDBY    1
+#define SK_PNMI_RLMT_STATUS_ACTIVE     2
+#define SK_PNMI_RLMT_STATUS_ERROR      3
+
+#define SK_PNMI_RLMT_LSTAT_PHY_DOWN    1
+#define SK_PNMI_RLMT_LSTAT_AUTONEG     2
+#define SK_PNMI_RLMT_LSTAT_LOG_DOWN    3
+#define SK_PNMI_RLMT_LSTAT_LOG_UP      4
+#define SK_PNMI_RLMT_LSTAT_INDETERMINATED 5
+
+#define SK_PNMI_RLMT_MODE_CHK_LINK     (SK_RLMT_CHECK_LINK)
+#define SK_PNMI_RLMT_MODE_CHK_RX       (SK_RLMT_CHECK_LOC_LINK)
+#define SK_PNMI_RLMT_MODE_CHK_SPT      (SK_RLMT_CHECK_SEG)
+/* #define SK_PNMI_RLMT_MODE_CHK_EX */
+
+/*
+ * OID definition
+ */
+#ifndef _NDIS_ /* Check, whether NDIS already included OIDs */
+
+#define OID_GEN_XMIT_OK                                        0x00020101
+#define OID_GEN_RCV_OK                                 0x00020102
+#define OID_GEN_XMIT_ERROR                             0x00020103
+#define OID_GEN_RCV_ERROR                              0x00020104
+#define OID_GEN_RCV_NO_BUFFER                  0x00020105
+
+/* #define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 */
+#define OID_GEN_DIRECTED_FRAMES_XMIT   0x00020202
+/* #define OID_GEN_MULTICAST_BYTES_XMIT        0x00020203 */
+#define OID_GEN_MULTICAST_FRAMES_XMIT  0x00020204
+/* #define OID_GEN_BROADCAST_BYTES_XMIT        0x00020205 */
+#define OID_GEN_BROADCAST_FRAMES_XMIT  0x00020206
+/* #define OID_GEN_DIRECTED_BYTES_RCV  0x00020207 */
+#define OID_GEN_DIRECTED_FRAMES_RCV            0x00020208
+/* #define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 */
+#define OID_GEN_MULTICAST_FRAMES_RCV   0x0002020A
+/* #define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B */
+#define OID_GEN_BROADCAST_FRAMES_RCV   0x0002020C
+#define OID_GEN_RCV_CRC_ERROR                  0x0002020D
+#define OID_GEN_TRANSMIT_QUEUE_LENGTH  0x0002020E
+
+#define OID_802_3_PERMANENT_ADDRESS            0x01010101
+#define OID_802_3_CURRENT_ADDRESS              0x01010102
+/* #define OID_802_3_MULTICAST_LIST            0x01010103 */
+/* #define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 */
+/* #define OID_802_3_MAC_OPTIONS               0x01010105 */
+
+#define OID_802_3_RCV_ERROR_ALIGNMENT  0x01020101
+#define OID_802_3_XMIT_ONE_COLLISION   0x01020102
+#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103
+#define OID_802_3_XMIT_DEFERRED                        0x01020201
+#define OID_802_3_XMIT_MAX_COLLISIONS  0x01020202
+#define OID_802_3_RCV_OVERRUN                  0x01020203
+#define OID_802_3_XMIT_UNDERRUN                        0x01020204
+#define OID_802_3_XMIT_TIMES_CRS_LOST  0x01020206
+#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
+
+/*
+ * PnP and PM OIDs
+ */
+#ifdef SK_POWER_MGMT
+#define OID_PNP_CAPABILITIES                   0xFD010100
+#define OID_PNP_SET_POWER                              0xFD010101
+#define OID_PNP_QUERY_POWER                            0xFD010102
+#define OID_PNP_ADD_WAKE_UP_PATTERN            0xFD010103
+#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104
+#define OID_PNP_ENABLE_WAKE_UP                 0xFD010106
+#endif /* SK_POWER_MGMT */
+
+#endif /* _NDIS_ */
+
+#define OID_SKGE_MDB_VERSION                   0xFF010100
+#define OID_SKGE_SUPPORTED_LIST                        0xFF010101
+#define OID_SKGE_VPD_FREE_BYTES                        0xFF010102
+#define OID_SKGE_VPD_ENTRIES_LIST              0xFF010103
+#define OID_SKGE_VPD_ENTRIES_NUMBER            0xFF010104
+#define OID_SKGE_VPD_KEY                               0xFF010105
+#define OID_SKGE_VPD_VALUE                             0xFF010106
+#define OID_SKGE_VPD_ACCESS                            0xFF010107
+#define OID_SKGE_VPD_ACTION                            0xFF010108
+
+#define OID_SKGE_PORT_NUMBER                   0xFF010110
+#define OID_SKGE_DEVICE_TYPE                   0xFF010111
+#define OID_SKGE_DRIVER_DESCR                  0xFF010112
+#define OID_SKGE_DRIVER_VERSION                        0xFF010113
+#define OID_SKGE_HW_DESCR                              0xFF010114
+#define OID_SKGE_HW_VERSION                            0xFF010115
+#define OID_SKGE_CHIPSET                               0xFF010116
+#define OID_SKGE_ACTION                                        0xFF010117
+#define OID_SKGE_RESULT                                        0xFF010118
+#define OID_SKGE_BUS_TYPE                              0xFF010119
+#define OID_SKGE_BUS_SPEED                             0xFF01011A
+#define OID_SKGE_BUS_WIDTH                             0xFF01011B
+/* 0xFF01011C unused */
+#define OID_SKGE_DIAG_ACTION                   0xFF01011D
+#define OID_SKGE_DIAG_RESULT                   0xFF01011E
+#define OID_SKGE_MTU                                   0xFF01011F
+#define OID_SKGE_PHYS_CUR_ADDR                 0xFF010120
+#define OID_SKGE_PHYS_FAC_ADDR                 0xFF010121
+#define OID_SKGE_PMD                                   0xFF010122
+#define OID_SKGE_CONNECTOR                             0xFF010123
+#define OID_SKGE_LINK_CAP                              0xFF010124
+#define OID_SKGE_LINK_MODE                             0xFF010125
+#define OID_SKGE_LINK_MODE_STATUS              0xFF010126
+#define OID_SKGE_LINK_STATUS                   0xFF010127
+#define OID_SKGE_FLOWCTRL_CAP                  0xFF010128
+#define OID_SKGE_FLOWCTRL_MODE                 0xFF010129
+#define OID_SKGE_FLOWCTRL_STATUS               0xFF01012A
+#define OID_SKGE_PHY_OPERATION_CAP             0xFF01012B
+#define OID_SKGE_PHY_OPERATION_MODE            0xFF01012C
+#define OID_SKGE_PHY_OPERATION_STATUS  0xFF01012D
+#define OID_SKGE_MULTICAST_LIST                        0xFF01012E
+#define OID_SKGE_CURRENT_PACKET_FILTER 0xFF01012F
+
+#define OID_SKGE_TRAP                                  0xFF010130
+#define OID_SKGE_TRAP_NUMBER                   0xFF010131
+
+#define OID_SKGE_RLMT_MODE                             0xFF010140
+#define OID_SKGE_RLMT_PORT_NUMBER              0xFF010141
+#define OID_SKGE_RLMT_PORT_ACTIVE              0xFF010142
+#define OID_SKGE_RLMT_PORT_PREFERRED   0xFF010143
+#define OID_SKGE_INTERMEDIATE_SUPPORT  0xFF010160
+
+#define OID_SKGE_SPEED_CAP                             0xFF010170
+#define OID_SKGE_SPEED_MODE                            0xFF010171
+#define OID_SKGE_SPEED_STATUS                  0xFF010172
+
+#define OID_SKGE_SENSOR_NUMBER                 0xFF020100
+#define OID_SKGE_SENSOR_INDEX                  0xFF020101
+#define OID_SKGE_SENSOR_DESCR                  0xFF020102
+#define OID_SKGE_SENSOR_TYPE                   0xFF020103
+#define OID_SKGE_SENSOR_VALUE                  0xFF020104
+#define OID_SKGE_SENSOR_WAR_THRES_LOW  0xFF020105
+#define OID_SKGE_SENSOR_WAR_THRES_UPP  0xFF020106
+#define OID_SKGE_SENSOR_ERR_THRES_LOW  0xFF020107
+#define OID_SKGE_SENSOR_ERR_THRES_UPP  0xFF020108
+#define OID_SKGE_SENSOR_STATUS                 0xFF020109
+#define OID_SKGE_SENSOR_WAR_CTS                        0xFF02010A
+#define OID_SKGE_SENSOR_ERR_CTS                        0xFF02010B
+#define OID_SKGE_SENSOR_WAR_TIME               0xFF02010C
+#define OID_SKGE_SENSOR_ERR_TIME               0xFF02010D
+
+#define OID_SKGE_CHKSM_NUMBER                  0xFF020110
+#define OID_SKGE_CHKSM_RX_OK_CTS               0xFF020111
+#define OID_SKGE_CHKSM_RX_UNABLE_CTS   0xFF020112
+#define OID_SKGE_CHKSM_RX_ERR_CTS              0xFF020113
+#define OID_SKGE_CHKSM_TX_OK_CTS               0xFF020114
+#define OID_SKGE_CHKSM_TX_UNABLE_CTS   0xFF020115
+
+#define OID_SKGE_STAT_TX                               0xFF020120
+#define OID_SKGE_STAT_TX_OCTETS                        0xFF020121
+#define OID_SKGE_STAT_TX_BROADCAST             0xFF020122
+#define OID_SKGE_STAT_TX_MULTICAST             0xFF020123
+#define OID_SKGE_STAT_TX_UNICAST               0xFF020124
+#define OID_SKGE_STAT_TX_LONGFRAMES            0xFF020125
+#define OID_SKGE_STAT_TX_BURST                 0xFF020126
+#define OID_SKGE_STAT_TX_PFLOWC                        0xFF020127
+#define OID_SKGE_STAT_TX_FLOWC                 0xFF020128
+#define OID_SKGE_STAT_TX_SINGLE_COL            0xFF020129
+#define OID_SKGE_STAT_TX_MULTI_COL             0xFF02012A
+#define OID_SKGE_STAT_TX_EXCESS_COL            0xFF02012B
+#define OID_SKGE_STAT_TX_LATE_COL              0xFF02012C
+#define OID_SKGE_STAT_TX_DEFFERAL              0xFF02012D
+#define OID_SKGE_STAT_TX_EXCESS_DEF            0xFF02012E
+#define OID_SKGE_STAT_TX_UNDERRUN              0xFF02012F
+#define OID_SKGE_STAT_TX_CARRIER               0xFF020130
+/* #define OID_SKGE_STAT_TX_UTIL               0xFF020131 */
+#define OID_SKGE_STAT_TX_64                            0xFF020132
+#define OID_SKGE_STAT_TX_127                   0xFF020133
+#define OID_SKGE_STAT_TX_255                   0xFF020134
+#define OID_SKGE_STAT_TX_511                   0xFF020135
+#define OID_SKGE_STAT_TX_1023                  0xFF020136
+#define OID_SKGE_STAT_TX_MAX                   0xFF020137
+#define OID_SKGE_STAT_TX_SYNC                  0xFF020138
+#define OID_SKGE_STAT_TX_SYNC_OCTETS   0xFF020139
+#define OID_SKGE_STAT_RX                               0xFF02013A
+#define OID_SKGE_STAT_RX_OCTETS                        0xFF02013B
+#define OID_SKGE_STAT_RX_BROADCAST             0xFF02013C
+#define OID_SKGE_STAT_RX_MULTICAST             0xFF02013D
+#define OID_SKGE_STAT_RX_UNICAST               0xFF02013E
+#define OID_SKGE_STAT_RX_PFLOWC                        0xFF02013F
+#define OID_SKGE_STAT_RX_FLOWC                 0xFF020140
+#define OID_SKGE_STAT_RX_PFLOWC_ERR            0xFF020141
+#define OID_SKGE_STAT_RX_FLOWC_UNKWN   0xFF020142
+#define OID_SKGE_STAT_RX_BURST                 0xFF020143
+#define OID_SKGE_STAT_RX_MISSED                        0xFF020144
+#define OID_SKGE_STAT_RX_FRAMING               0xFF020145
+#define OID_SKGE_STAT_RX_OVERFLOW              0xFF020146
+#define OID_SKGE_STAT_RX_JABBER                        0xFF020147
+#define OID_SKGE_STAT_RX_CARRIER               0xFF020148
+#define OID_SKGE_STAT_RX_IR_LENGTH             0xFF020149
+#define OID_SKGE_STAT_RX_SYMBOL                        0xFF02014A
+#define OID_SKGE_STAT_RX_SHORTS                        0xFF02014B
+#define OID_SKGE_STAT_RX_RUNT                  0xFF02014C
+#define OID_SKGE_STAT_RX_CEXT                  0xFF02014D
+#define OID_SKGE_STAT_RX_TOO_LONG              0xFF02014E
+#define OID_SKGE_STAT_RX_FCS                   0xFF02014F
+/* #define OID_SKGE_STAT_RX_UTIL               0xFF020150 */
+#define OID_SKGE_STAT_RX_64                            0xFF020151
+#define OID_SKGE_STAT_RX_127                   0xFF020152
+#define OID_SKGE_STAT_RX_255                   0xFF020153
+#define OID_SKGE_STAT_RX_511                   0xFF020154
+#define OID_SKGE_STAT_RX_1023                  0xFF020155
+#define OID_SKGE_STAT_RX_MAX                   0xFF020156
+#define OID_SKGE_STAT_RX_LONGFRAMES            0xFF020157
+
+#define OID_SKGE_RLMT_CHANGE_CTS               0xFF020160
+#define OID_SKGE_RLMT_CHANGE_TIME              0xFF020161
+#define OID_SKGE_RLMT_CHANGE_ESTIM             0xFF020162
+#define OID_SKGE_RLMT_CHANGE_THRES             0xFF020163
+
+#define OID_SKGE_RLMT_PORT_INDEX               0xFF020164
+#define OID_SKGE_RLMT_STATUS                   0xFF020165
+#define OID_SKGE_RLMT_TX_HELLO_CTS             0xFF020166
+#define OID_SKGE_RLMT_RX_HELLO_CTS             0xFF020167
+#define OID_SKGE_RLMT_TX_SP_REQ_CTS            0xFF020168
+#define OID_SKGE_RLMT_RX_SP_CTS                        0xFF020169
+
+#define OID_SKGE_RLMT_MONITOR_NUMBER   0xFF010150
+#define OID_SKGE_RLMT_MONITOR_INDEX            0xFF010151
+#define OID_SKGE_RLMT_MONITOR_ADDR             0xFF010152
+#define OID_SKGE_RLMT_MONITOR_ERRS             0xFF010153
+#define OID_SKGE_RLMT_MONITOR_TIMESTAMP        0xFF010154
+#define OID_SKGE_RLMT_MONITOR_ADMIN            0xFF010155
+
+#define OID_SKGE_TX_SW_QUEUE_LEN               0xFF020170
+#define OID_SKGE_TX_SW_QUEUE_MAX               0xFF020171
+#define OID_SKGE_TX_RETRY                              0xFF020172
+#define OID_SKGE_RX_INTR_CTS                   0xFF020173
+#define OID_SKGE_TX_INTR_CTS                   0xFF020174
+#define OID_SKGE_RX_NO_BUF_CTS                 0xFF020175
+#define OID_SKGE_TX_NO_BUF_CTS                 0xFF020176
+#define OID_SKGE_TX_USED_DESCR_NO              0xFF020177
+#define OID_SKGE_RX_DELIVERED_CTS              0xFF020178
+#define OID_SKGE_RX_OCTETS_DELIV_CTS   0xFF020179
+#define OID_SKGE_RX_HW_ERROR_CTS               0xFF02017A
+#define OID_SKGE_TX_HW_ERROR_CTS               0xFF02017B
+#define OID_SKGE_IN_ERRORS_CTS                 0xFF02017C
+#define OID_SKGE_OUT_ERROR_CTS                 0xFF02017D
+#define OID_SKGE_ERR_RECOVERY_CTS              0xFF02017E
+#define OID_SKGE_SYSUPTIME                             0xFF02017F
+
+#define OID_SKGE_ALL_DATA                              0xFF020190
+
+/* Defines for VCT. */
+#define OID_SKGE_VCT_GET                       0xFF020200
+#define OID_SKGE_VCT_SET                       0xFF020201
+#define OID_SKGE_VCT_STATUS                    0xFF020202
+
+
+/* VCT struct to store a backup copy of VCT data after a port reset. */
+typedef struct s_PnmiVct {
+       SK_U8                   VctStatus;
+       SK_U8                   PCableLen;
+       SK_U32                  PMdiPairLen[4];
+       SK_U8                   PMdiPairSts[4];
+} SK_PNMI_VCT;
+
+
+/* VCT status values (to be given to CPA via OID_SKGE_VCT_STATUS). */
+#define SK_PNMI_VCT_NONE               0
+#define SK_PNMI_VCT_OLD_VCT_DATA       1
+#define SK_PNMI_VCT_NEW_VCT_DATA       2
+#define SK_PNMI_VCT_OLD_DSP_DATA       4
+#define SK_PNMI_VCT_NEW_DSP_DATA       8
+#define SK_PNMI_VCT_RUNNING            16
+
+
+/* VCT cable test status. */
+#define SK_PNMI_VCT_NORMAL_CABLE               0
+#define SK_PNMI_VCT_SHORT_CABLE                        1
+#define SK_PNMI_VCT_OPEN_CABLE                 2
+#define SK_PNMI_VCT_TEST_FAIL                  3
+#define SK_PNMI_VCT_IMPEDANCE_MISMATCH         4
+
+#define        OID_SKGE_TRAP_SEN_WAR_LOW               500
+#define OID_SKGE_TRAP_SEN_WAR_UPP              501
+#define        OID_SKGE_TRAP_SEN_ERR_LOW               502
+#define OID_SKGE_TRAP_SEN_ERR_UPP              503
+#define OID_SKGE_TRAP_RLMT_CHANGE_THRES        520
+#define OID_SKGE_TRAP_RLMT_CHANGE_PORT 521
+#define OID_SKGE_TRAP_RLMT_PORT_DOWN   522
+#define OID_SKGE_TRAP_RLMT_PORT_UP             523
+#define OID_SKGE_TRAP_RLMT_SEGMENTATION        524
+
+
+/*
+ * Define error numbers and messages for syslog
+ */
+#define SK_PNMI_ERR001         (SK_ERRBASE_PNMI + 1)
+#define SK_PNMI_ERR001MSG      "SkPnmiGetStruct: Unknown OID"
+#define SK_PNMI_ERR002         (SK_ERRBASE_PNMI + 2)
+#define SK_PNMI_ERR002MSG      "SkPnmiGetStruct: Cannot read VPD keys"
+#define SK_PNMI_ERR003         (SK_ERRBASE_PNMI + 3)
+#define SK_PNMI_ERR003MSG      "OidStruct: Called with wrong OID"
+#define SK_PNMI_ERR004         (SK_ERRBASE_PNMI + 4)
+#define SK_PNMI_ERR004MSG      "OidStruct: Called with wrong action"
+#define SK_PNMI_ERR005         (SK_ERRBASE_PNMI + 5)
+#define SK_PNMI_ERR005MSG      "Perform: Cannot reset driver"
+#define SK_PNMI_ERR006         (SK_ERRBASE_PNMI + 6)
+#define SK_PNMI_ERR006MSG      "Perform: Unknown OID action command"
+#define SK_PNMI_ERR007         (SK_ERRBASE_PNMI + 7)
+#define SK_PNMI_ERR007MSG      "General: Driver description not initialized"
+#define SK_PNMI_ERR008         (SK_ERRBASE_PNMI + 8)
+#define SK_PNMI_ERR008MSG      "Addr: Tried to get unknown OID"
+#define SK_PNMI_ERR009         (SK_ERRBASE_PNMI + 9)
+#define SK_PNMI_ERR009MSG      "Addr: Unknown OID"
+#define SK_PNMI_ERR010         (SK_ERRBASE_PNMI + 10)
+#define SK_PNMI_ERR010MSG      "CsumStat: Unknown OID"
+#define SK_PNMI_ERR011         (SK_ERRBASE_PNMI + 11)
+#define SK_PNMI_ERR011MSG      "SensorStat: Sensor descr string too long"
+#define SK_PNMI_ERR012         (SK_ERRBASE_PNMI + 12)
+#define SK_PNMI_ERR012MSG      "SensorStat: Unknown OID"
+#define SK_PNMI_ERR013         (SK_ERRBASE_PNMI + 13)
+#define SK_PNMI_ERR013MSG      ""
+#define SK_PNMI_ERR014         (SK_ERRBASE_PNMI + 14)
+#define SK_PNMI_ERR014MSG      "Vpd: Cannot read VPD keys"
+#define SK_PNMI_ERR015         (SK_ERRBASE_PNMI + 15)
+#define SK_PNMI_ERR015MSG      "Vpd: Internal array for VPD keys to small"
+#define SK_PNMI_ERR016         (SK_ERRBASE_PNMI + 16)
+#define SK_PNMI_ERR016MSG      "Vpd: Key string too long"
+#define SK_PNMI_ERR017         (SK_ERRBASE_PNMI + 17)
+#define SK_PNMI_ERR017MSG      "Vpd: Invalid VPD status pointer"
+#define SK_PNMI_ERR018         (SK_ERRBASE_PNMI + 18)
+#define SK_PNMI_ERR018MSG      "Vpd: VPD data not valid"
+#define SK_PNMI_ERR019         (SK_ERRBASE_PNMI + 19)
+#define SK_PNMI_ERR019MSG      "Vpd: VPD entries list string too long"
+#define SK_PNMI_ERR021         (SK_ERRBASE_PNMI + 21)
+#define SK_PNMI_ERR021MSG      "Vpd: VPD data string too long"
+#define SK_PNMI_ERR022         (SK_ERRBASE_PNMI + 22)
+#define SK_PNMI_ERR022MSG      "Vpd: VPD data string too long should be errored before"
+#define SK_PNMI_ERR023         (SK_ERRBASE_PNMI + 23)
+#define SK_PNMI_ERR023MSG      "Vpd: Unknown OID in get action"
+#define SK_PNMI_ERR024         (SK_ERRBASE_PNMI + 24)
+#define SK_PNMI_ERR024MSG      "Vpd: Unknown OID in preset/set action"
+#define SK_PNMI_ERR025         (SK_ERRBASE_PNMI + 25)
+#define SK_PNMI_ERR025MSG      "Vpd: Cannot write VPD after modify entry"
+#define SK_PNMI_ERR026         (SK_ERRBASE_PNMI + 26)
+#define SK_PNMI_ERR026MSG      "Vpd: Cannot update VPD"
+#define SK_PNMI_ERR027         (SK_ERRBASE_PNMI + 27)
+#define SK_PNMI_ERR027MSG      "Vpd: Cannot delete VPD entry"
+#define SK_PNMI_ERR028         (SK_ERRBASE_PNMI + 28)
+#define SK_PNMI_ERR028MSG      "Vpd: Cannot update VPD after delete entry"
+#define SK_PNMI_ERR029         (SK_ERRBASE_PNMI + 29)
+#define SK_PNMI_ERR029MSG      "General: Driver description string too long"
+#define SK_PNMI_ERR030         (SK_ERRBASE_PNMI + 30)
+#define SK_PNMI_ERR030MSG      "General: Driver version not initialized"
+#define SK_PNMI_ERR031         (SK_ERRBASE_PNMI + 31)
+#define SK_PNMI_ERR031MSG      "General: Driver version string too long"
+#define SK_PNMI_ERR032         (SK_ERRBASE_PNMI + 32)
+#define SK_PNMI_ERR032MSG      "General: Cannot read VPD Name for HW descr"
+#define SK_PNMI_ERR033         (SK_ERRBASE_PNMI + 33)
+#define SK_PNMI_ERR033MSG      "General: HW description string too long"
+#define SK_PNMI_ERR034         (SK_ERRBASE_PNMI + 34)
+#define SK_PNMI_ERR034MSG      "General: Unknown OID"
+#define SK_PNMI_ERR035         (SK_ERRBASE_PNMI + 35)
+#define SK_PNMI_ERR035MSG      "Rlmt: Unknown OID"
+#define SK_PNMI_ERR036         (SK_ERRBASE_PNMI + 36)
+#define SK_PNMI_ERR036MSG      ""
+#define SK_PNMI_ERR037         (SK_ERRBASE_PNMI + 37)
+#define SK_PNMI_ERR037MSG      "Rlmt: SK_RLMT_MODE_CHANGE event return not 0"
+#define SK_PNMI_ERR038         (SK_ERRBASE_PNMI + 38)
+#define SK_PNMI_ERR038MSG      "Rlmt: SK_RLMT_PREFPORT_CHANGE event return not 0"
+#define SK_PNMI_ERR039         (SK_ERRBASE_PNMI + 39)
+#define SK_PNMI_ERR039MSG      "RlmtStat: Unknown OID"
+#define SK_PNMI_ERR040         (SK_ERRBASE_PNMI + 40)
+#define SK_PNMI_ERR040MSG      "PowerManagement: Unknown OID"
+#define SK_PNMI_ERR041         (SK_ERRBASE_PNMI + 41)
+#define SK_PNMI_ERR041MSG      "MacPrivateConf: Unknown OID"
+#define SK_PNMI_ERR042         (SK_ERRBASE_PNMI + 42)
+#define SK_PNMI_ERR042MSG      "MacPrivateConf: SK_HWEV_SET_ROLE returned not 0"
+#define SK_PNMI_ERR043         (SK_ERRBASE_PNMI + 43)
+#define SK_PNMI_ERR043MSG      "MacPrivateConf: SK_HWEV_SET_LMODE returned not 0"
+#define SK_PNMI_ERR044         (SK_ERRBASE_PNMI + 44)
+#define SK_PNMI_ERR044MSG      "MacPrivateConf: SK_HWEV_SET_FLOWMODE returned not 0"
+#define SK_PNMI_ERR045         (SK_ERRBASE_PNMI + 45)
+#define SK_PNMI_ERR045MSG      "MacPrivateConf: SK_HWEV_SET_SPEED returned not 0"
+#define SK_PNMI_ERR046         (SK_ERRBASE_PNMI + 46)
+#define SK_PNMI_ERR046MSG      "Monitor: Unknown OID"
+#define SK_PNMI_ERR047         (SK_ERRBASE_PNMI + 47)
+#define SK_PNMI_ERR047MSG      "SirqUpdate: Event function returns not 0"
+#define SK_PNMI_ERR048         (SK_ERRBASE_PNMI + 48)
+#define SK_PNMI_ERR048MSG      "RlmtUpdate: Event function returns not 0"
+#define SK_PNMI_ERR049         (SK_ERRBASE_PNMI + 49)
+#define SK_PNMI_ERR049MSG      "SkPnmiInit: Invalid size of 'CounterOffset' struct!!"
+#define SK_PNMI_ERR050         (SK_ERRBASE_PNMI + 50)
+#define SK_PNMI_ERR050MSG      "SkPnmiInit: Invalid size of 'StatAddr' table!!"
+#define SK_PNMI_ERR051         (SK_ERRBASE_PNMI + 51)
+#define SK_PNMI_ERR051MSG      "SkPnmiEvent: Port switch suspicious"
+#define SK_PNMI_ERR052         (SK_ERRBASE_PNMI + 52)
+#define SK_PNMI_ERR052MSG      ""
+
+/*
+ * Management counter macros called by the driver
+ */
+#define SK_PNMI_SET_DRIVER_DESCR(pAC,v)        ((pAC)->Pnmi.pDriverDescription = \
+       (char *)(v))
+
+#define SK_PNMI_SET_DRIVER_VER(pAC,v)  ((pAC)->Pnmi.pDriverVersion = \
+       (char *)(v))
+
+
+#define SK_PNMI_CNT_TX_QUEUE_LEN(pAC,v,p) \
+       { \
+               (pAC)->Pnmi.Port[p].TxSwQueueLen = (SK_U64)(v); \
+               if ((pAC)->Pnmi.Port[p].TxSwQueueLen > (pAC)->Pnmi.Port[p].TxSwQueueMax) { \
+                       (pAC)->Pnmi.Port[p].TxSwQueueMax = (pAC)->Pnmi.Port[p].TxSwQueueLen; \
+               } \
+       }
+#define SK_PNMI_CNT_TX_RETRY(pAC,p)    (((pAC)->Pnmi.Port[p].TxRetryCts)++)
+#define SK_PNMI_CNT_RX_INTR(pAC,p)     (((pAC)->Pnmi.Port[p].RxIntrCts)++)
+#define SK_PNMI_CNT_TX_INTR(pAC,p)     (((pAC)->Pnmi.Port[p].TxIntrCts)++)
+#define SK_PNMI_CNT_NO_RX_BUF(pAC,p)   (((pAC)->Pnmi.Port[p].RxNoBufCts)++)
+#define SK_PNMI_CNT_NO_TX_BUF(pAC,p)   (((pAC)->Pnmi.Port[p].TxNoBufCts)++)
+#define SK_PNMI_CNT_USED_TX_DESCR(pAC,v,p) \
+       ((pAC)->Pnmi.Port[p].TxUsedDescrNo=(SK_U64)(v));
+#define SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,v,p) \
+       { \
+               ((pAC)->Pnmi.Port[p].RxDeliveredCts)++; \
+               (pAC)->Pnmi.Port[p].RxOctetsDeliveredCts += (SK_U64)(v); \
+       }
+#define SK_PNMI_CNT_ERR_RECOVERY(pAC,p)        (((pAC)->Pnmi.Port[p].ErrRecoveryCts)++);
+
+#define SK_PNMI_CNT_SYNC_OCTETS(pAC,p,v) \
+       { \
+               if ((p) < SK_MAX_MACS) { \
+                       ((pAC)->Pnmi.Port[p].StatSyncCts)++; \
+                       (pAC)->Pnmi.Port[p].StatSyncOctetsCts += (SK_U64)(v); \
+               } \
+       }
+
+#define SK_PNMI_CNT_RX_LONGFRAMES(pAC,p) \
+       { \
+               if ((p) < SK_MAX_MACS) { \
+                       ((pAC)->Pnmi.Port[p].StatRxLongFrameCts++); \
+               } \
+       }
+
+#define SK_PNMI_CNT_RX_FRAMETOOLONG(pAC,p) \
+       { \
+               if ((p) < SK_MAX_MACS) { \
+                       ((pAC)->Pnmi.Port[p].StatRxFrameTooLongCts++); \
+               } \
+       }
+
+#define SK_PNMI_CNT_RX_PMACC_ERR(pAC,p) \
+       { \
+               if ((p) < SK_MAX_MACS) { \
+                       ((pAC)->Pnmi.Port[p].StatRxPMaccErr++); \
+               } \
+       }
+
+/*
+ * Conversion Macros
+ */
+#define SK_PNMI_PORT_INST2LOG(i)       ((unsigned int)(i) - 1)
+#define SK_PNMI_PORT_LOG2INST(l)       ((unsigned int)(l) + 1)
+#define SK_PNMI_PORT_PHYS2LOG(p)       ((unsigned int)(p) + 1)
+#define SK_PNMI_PORT_LOG2PHYS(pAC,l)   ((unsigned int)(l) - 1)
+#define SK_PNMI_PORT_PHYS2INST(pAC,p)  \
+       (pAC->Pnmi.DualNetActiveFlag ? 2 : ((unsigned int)(p) + 2))
+#define SK_PNMI_PORT_INST2PHYS(pAC,i)  ((unsigned int)(i) - 2)
+
+/*
+ * Structure definition for SkPnmiGetStruct and SkPnmiSetStruct
+ */
+#define SK_PNMI_VPD_KEY_SIZE   5
+#define SK_PNMI_VPD_BUFSIZE            (VPD_SIZE)
+#define SK_PNMI_VPD_ENTRIES            (VPD_SIZE / 4)
+#define SK_PNMI_VPD_DATALEN            128 /*  Number of data bytes */
+
+#define SK_PNMI_MULTICAST_LISTLEN      64
+#define SK_PNMI_SENSOR_ENTRIES         (SK_MAX_SENSORS)
+#define SK_PNMI_CHECKSUM_ENTRIES       3
+#define SK_PNMI_MAC_ENTRIES                    (SK_MAX_MACS + 1)
+#define SK_PNMI_MONITOR_ENTRIES                20
+#define SK_PNMI_TRAP_ENTRIES           10
+#define SK_PNMI_TRAPLEN                                128
+#define SK_PNMI_STRINGLEN1                     80
+#define SK_PNMI_STRINGLEN2                     25
+#define SK_PNMI_TRAP_QUEUE_LEN         512
+
+typedef struct s_PnmiVpd {
+       char                    VpdKey[SK_PNMI_VPD_KEY_SIZE];
+       char                    VpdValue[SK_PNMI_VPD_DATALEN];
+       SK_U8                   VpdAccess;
+       SK_U8                   VpdAction;
+} SK_PNMI_VPD;
+
+typedef struct s_PnmiSensor {
+       SK_U8                   SensorIndex;
+       char                    SensorDescr[SK_PNMI_STRINGLEN2];
+       SK_U8                   SensorType;
+       SK_U32                  SensorValue;
+       SK_U32                  SensorWarningThresholdLow;
+       SK_U32                  SensorWarningThresholdHigh;
+       SK_U32                  SensorErrorThresholdLow;
+       SK_U32                  SensorErrorThresholdHigh;
+       SK_U8                   SensorStatus;
+       SK_U64                  SensorWarningCts;
+       SK_U64                  SensorErrorCts;
+       SK_U64                  SensorWarningTimestamp;
+       SK_U64                  SensorErrorTimestamp;
+} SK_PNMI_SENSOR;
+
+typedef struct s_PnmiChecksum {
+       SK_U64                  ChecksumRxOkCts;
+       SK_U64                  ChecksumRxUnableCts;
+       SK_U64                  ChecksumRxErrCts;
+       SK_U64                  ChecksumTxOkCts;
+       SK_U64                  ChecksumTxUnableCts;
+} SK_PNMI_CHECKSUM;
+
+typedef struct s_PnmiStat {
+       SK_U64                  StatTxOkCts;
+       SK_U64                  StatTxOctetsOkCts;
+       SK_U64                  StatTxBroadcastOkCts;
+       SK_U64                  StatTxMulticastOkCts;
+       SK_U64                  StatTxUnicastOkCts;
+       SK_U64                  StatTxLongFramesCts;
+       SK_U64                  StatTxBurstCts;
+       SK_U64                  StatTxPauseMacCtrlCts;
+       SK_U64                  StatTxMacCtrlCts;
+       SK_U64                  StatTxSingleCollisionCts;
+       SK_U64                  StatTxMultipleCollisionCts;
+       SK_U64                  StatTxExcessiveCollisionCts;
+       SK_U64                  StatTxLateCollisionCts;
+       SK_U64                  StatTxDeferralCts;
+       SK_U64                  StatTxExcessiveDeferralCts;
+       SK_U64                  StatTxFifoUnderrunCts;
+       SK_U64                  StatTxCarrierCts;
+       SK_U64                  Dummy1; /* StatTxUtilization */
+       SK_U64                  StatTx64Cts;
+       SK_U64                  StatTx127Cts;
+       SK_U64                  StatTx255Cts;
+       SK_U64                  StatTx511Cts;
+       SK_U64                  StatTx1023Cts;
+       SK_U64                  StatTxMaxCts;
+       SK_U64                  StatTxSyncCts;
+       SK_U64                  StatTxSyncOctetsCts;
+       SK_U64                  StatRxOkCts;
+       SK_U64                  StatRxOctetsOkCts;
+       SK_U64                  StatRxBroadcastOkCts;
+       SK_U64                  StatRxMulticastOkCts;
+       SK_U64                  StatRxUnicastOkCts;
+       SK_U64                  StatRxLongFramesCts;
+       SK_U64                  StatRxPauseMacCtrlCts;
+       SK_U64                  StatRxMacCtrlCts;
+       SK_U64                  StatRxPauseMacCtrlErrorCts;
+       SK_U64                  StatRxMacCtrlUnknownCts;
+       SK_U64                  StatRxBurstCts;
+       SK_U64                  StatRxMissedCts;
+       SK_U64                  StatRxFramingCts;
+       SK_U64                  StatRxFifoOverflowCts;
+       SK_U64                  StatRxJabberCts;
+       SK_U64                  StatRxCarrierCts;
+       SK_U64                  StatRxIRLengthCts;
+       SK_U64                  StatRxSymbolCts;
+       SK_U64                  StatRxShortsCts;
+       SK_U64                  StatRxRuntCts;
+       SK_U64                  StatRxCextCts;
+       SK_U64                  StatRxTooLongCts;
+       SK_U64                  StatRxFcsCts;
+       SK_U64                  Dummy2; /* StatRxUtilization */
+       SK_U64                  StatRx64Cts;
+       SK_U64                  StatRx127Cts;
+       SK_U64                  StatRx255Cts;
+       SK_U64                  StatRx511Cts;
+       SK_U64                  StatRx1023Cts;
+       SK_U64                  StatRxMaxCts;
+} SK_PNMI_STAT;
+
+typedef struct s_PnmiConf {
+       char                    ConfMacCurrentAddr[6];
+       char                    ConfMacFactoryAddr[6];
+       SK_U8                   ConfPMD;
+       SK_U8                   ConfConnector;
+       SK_U8                   ConfLinkCapability;
+       SK_U8                   ConfLinkMode;
+       SK_U8                   ConfLinkModeStatus;
+       SK_U8                   ConfLinkStatus;
+       SK_U8                   ConfFlowCtrlCapability;
+       SK_U8                   ConfFlowCtrlMode;
+       SK_U8                   ConfFlowCtrlStatus;
+       SK_U8                   ConfPhyOperationCapability;
+       SK_U8                   ConfPhyOperationMode;
+       SK_U8                   ConfPhyOperationStatus;
+       SK_U8                   ConfSpeedCapability;
+       SK_U8                   ConfSpeedMode;
+       SK_U8                   ConfSpeedStatus;
+} SK_PNMI_CONF;
+
+typedef struct s_PnmiRlmt {
+       SK_U32                  RlmtIndex;
+       SK_U32                  RlmtStatus;
+       SK_U64                  RlmtTxHelloCts;
+       SK_U64                  RlmtRxHelloCts;
+       SK_U64                  RlmtTxSpHelloReqCts;
+       SK_U64                  RlmtRxSpHelloCts;
+} SK_PNMI_RLMT;
+
+typedef struct s_PnmiRlmtMonitor {
+       SK_U32                  RlmtMonitorIndex;
+       char                    RlmtMonitorAddr[6];
+       SK_U64                  RlmtMonitorErrorCts;
+       SK_U64                  RlmtMonitorTimestamp;
+       SK_U8                   RlmtMonitorAdmin;
+} SK_PNMI_RLMT_MONITOR;
+
+typedef struct s_PnmiRequestStatus {
+       SK_U32                  ErrorStatus;
+       SK_U32                  ErrorOffset;
+} SK_PNMI_REQUEST_STATUS;
+
+typedef struct s_PnmiStrucData {
+       SK_U32                  MgmtDBVersion;
+       SK_PNMI_REQUEST_STATUS  ReturnStatus;
+       SK_U32                  VpdFreeBytes;
+       char                    VpdEntriesList[SK_PNMI_VPD_ENTRIES * SK_PNMI_VPD_KEY_SIZE];
+       SK_U32                  VpdEntriesNumber;
+       SK_PNMI_VPD             Vpd[SK_PNMI_VPD_ENTRIES];
+       SK_U32                  PortNumber;
+       SK_U32                  DeviceType;
+       char                    DriverDescr[SK_PNMI_STRINGLEN1];
+       char                    DriverVersion[SK_PNMI_STRINGLEN2];
+       char                    HwDescr[SK_PNMI_STRINGLEN1];
+       char                    HwVersion[SK_PNMI_STRINGLEN2];
+       SK_U16                  Chipset;
+       SK_U32                  MtuSize;
+       SK_U32                  Action;
+       SK_U32                  TestResult;
+       SK_U8                   BusType;
+       SK_U8                   BusSpeed;
+       SK_U8                   BusWidth;
+       SK_U8                   SensorNumber;
+       SK_PNMI_SENSOR  Sensor[SK_PNMI_SENSOR_ENTRIES];
+       SK_U8                   ChecksumNumber;
+       SK_PNMI_CHECKSUM        Checksum[SK_PNMI_CHECKSUM_ENTRIES];
+       SK_PNMI_STAT    Stat[SK_PNMI_MAC_ENTRIES];
+       SK_PNMI_CONF    Conf[SK_PNMI_MAC_ENTRIES];
+       SK_U8                   RlmtMode;
+       SK_U32                  RlmtPortNumber;
+       SK_U8                   RlmtPortActive;
+       SK_U8                   RlmtPortPreferred;
+       SK_U64                  RlmtChangeCts;
+       SK_U64                  RlmtChangeTime;
+       SK_U64                  RlmtChangeEstimate;
+       SK_U64                  RlmtChangeThreshold;
+       SK_PNMI_RLMT    Rlmt[SK_MAX_MACS];
+       SK_U32                  RlmtMonitorNumber;
+       SK_PNMI_RLMT_MONITOR    RlmtMonitor[SK_PNMI_MONITOR_ENTRIES];
+       SK_U32                  TrapNumber;
+       SK_U8                   Trap[SK_PNMI_TRAP_QUEUE_LEN];
+       SK_U64                  TxSwQueueLen;
+       SK_U64                  TxSwQueueMax;
+       SK_U64                  TxRetryCts;
+       SK_U64                  RxIntrCts;
+       SK_U64                  TxIntrCts;
+       SK_U64                  RxNoBufCts;
+       SK_U64                  TxNoBufCts;
+       SK_U64                  TxUsedDescrNo;
+       SK_U64                  RxDeliveredCts;
+       SK_U64                  RxOctetsDeliveredCts;
+       SK_U64                  RxHwErrorsCts;
+       SK_U64                  TxHwErrorsCts;
+       SK_U64                  InErrorsCts;
+       SK_U64                  OutErrorsCts;
+       SK_U64                  ErrRecoveryCts;
+       SK_U64                  SysUpTime;
+} SK_PNMI_STRUCT_DATA;
+
+#define SK_PNMI_STRUCT_SIZE    (sizeof(SK_PNMI_STRUCT_DATA))
+#define SK_PNMI_MIN_STRUCT_SIZE        ((unsigned int)(SK_UPTR)\
+                                &(((SK_PNMI_STRUCT_DATA *)0)->VpdFreeBytes))
+                                                                                                               /*
+                                                                                                                * ReturnStatus field
+                                                                                                                * must be located
+                                                                                                                * before VpdFreeBytes
+                                                                                                                */
+
+/*
+ * Various definitions
+ */
+#define SK_PNMI_MAX_PROTOS             3
+
+#define SK_PNMI_CNT_NO                 66      /* Must have the value of the enum
+                                                                        * SK_PNMI_MAX_IDX. Define SK_PNMI_CHECK
+                                                                        * for check while init phase 1
+                                                                        */
+
+/*
+ * Estimate data structure
+ */
+typedef struct s_PnmiEstimate {
+       unsigned int    EstValueIndex;
+       SK_U64                  EstValue[7];
+       SK_U64                  Estimate;
+       SK_TIMER                EstTimer;
+} SK_PNMI_ESTIMATE;
+
+
+/*
+ * VCT timer data structure
+ */
+typedef struct s_VctTimer {
+       SK_TIMER                VctTimer;
+} SK_PNMI_VCT_TIMER;
+
+
+/*
+ * PNMI specific adapter context structure
+ */
+typedef struct s_PnmiPort {
+       SK_U64                  StatSyncCts;
+       SK_U64                  StatSyncOctetsCts;
+       SK_U64                  StatRxLongFrameCts;
+       SK_U64                  StatRxFrameTooLongCts;
+       SK_U64                  StatRxPMaccErr;
+       SK_U64                  TxSwQueueLen;
+       SK_U64                  TxSwQueueMax;
+       SK_U64                  TxRetryCts;
+       SK_U64                  RxIntrCts;
+       SK_U64                  TxIntrCts;
+       SK_U64                  RxNoBufCts;
+       SK_U64                  TxNoBufCts;
+       SK_U64                  TxUsedDescrNo;
+       SK_U64                  RxDeliveredCts;
+       SK_U64                  RxOctetsDeliveredCts;
+       SK_U64                  RxHwErrorsCts;
+       SK_U64                  TxHwErrorsCts;
+       SK_U64                  InErrorsCts;
+       SK_U64                  OutErrorsCts;
+       SK_U64                  ErrRecoveryCts;
+       SK_U64                  RxShortZeroMark;
+       SK_U64                  CounterOffset[SK_PNMI_CNT_NO];
+       SK_U32                  CounterHigh[SK_PNMI_CNT_NO];
+       SK_BOOL                 ActiveFlag;
+       SK_U8                   Align[3];
+} SK_PNMI_PORT;
+
+
+typedef struct s_PnmiData {
+       SK_PNMI_PORT    Port    [SK_MAX_MACS];
+       SK_PNMI_PORT    BufPort [SK_MAX_MACS]; /* 2002-09-13 pweber  */
+       SK_U64                  VirtualCounterOffset[SK_PNMI_CNT_NO];
+       SK_U32                  TestResult;
+       char                    HwVersion[10];
+       SK_U16                  Align01;
+
+       char                    *pDriverDescription;
+       char                    *pDriverVersion;
+
+       int                             MacUpdatedFlag;
+       int                             RlmtUpdatedFlag;
+       int                             SirqUpdatedFlag;
+
+       SK_U64                  RlmtChangeCts;
+       SK_U64                  RlmtChangeTime;
+       SK_PNMI_ESTIMATE        RlmtChangeEstimate;
+       SK_U64                  RlmtChangeThreshold;
+
+       SK_U64                  StartUpTime;
+       SK_U32                  DeviceType;
+       char                    PciBusSpeed;
+       char                    PciBusWidth;
+       char                    Chipset;
+       char                    PMD;
+       char                    Connector;
+       SK_BOOL                 DualNetActiveFlag;
+       SK_U16                  Align02;
+
+       char                    TrapBuf[SK_PNMI_TRAP_QUEUE_LEN];
+       unsigned int    TrapBufFree;
+       unsigned int    TrapQueueBeg;
+       unsigned int    TrapQueueEnd;
+       unsigned int    TrapBufPad;
+       unsigned int    TrapUnique;
+       SK_U8           VctStatus[SK_MAX_MACS];
+       SK_PNMI_VCT     VctBackup[SK_MAX_MACS];
+       SK_PNMI_VCT_TIMER VctTimeout[SK_MAX_MACS];
+} SK_PNMI;
+
+
+/*
+ * Function prototypes
+ */
+extern int SkPnmiInit(SK_AC *pAc, SK_IOC IoC, int level);
+extern int SkPnmiGetVar(SK_AC *pAc, SK_IOC IoC, SK_U32 Id, void* pBuf,
+       unsigned int* pLen, SK_U32 Instance, SK_U32 NetIndex);
+extern int SkPnmiPreSetVar(SK_AC *pAc, SK_IOC IoC, SK_U32 Id,
+       void* pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
+extern int SkPnmiSetVar(SK_AC *pAc, SK_IOC IoC, SK_U32 Id, void* pBuf,
+       unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
+extern int SkPnmiGetStruct(SK_AC *pAc, SK_IOC IoC, void* pBuf,
+       unsigned int *pLen, SK_U32 NetIndex);
+extern int SkPnmiPreSetStruct(SK_AC *pAc, SK_IOC IoC, void* pBuf,
+       unsigned int *pLen, SK_U32 NetIndex);
+extern int SkPnmiSetStruct(SK_AC *pAc, SK_IOC IoC, void* pBuf,
+       unsigned int *pLen, SK_U32 NetIndex);
+extern int SkPnmiEvent(SK_AC *pAc, SK_IOC IoC, SK_U32 Event,
+       SK_EVPARA Param);
+
+#endif
diff --git a/drivers/net/sk98lin/h/skgesirq.h b/drivers/net/sk98lin/h/skgesirq.h
new file mode 100644 (file)
index 0000000..fc001b2
--- /dev/null
@@ -0,0 +1,194 @@
+/******************************************************************************
+ *
+ * Name:       skgesirq.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.26 $
+ * Date:       $Date: 2002/10/14 09:52:36 $
+ * Purpose:    SK specific Gigabit Ethernet special IRQ functions
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2002 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *     $Log: skgesirq.h,v $
+ *     Revision 1.26  2002/10/14 09:52:36  rschmidt
+ *     Added SKERR_SIRQ_E023 and SKERR_SIRQ_E023 for GPHY (Yukon)
+ *     Editorial changes
+ *
+ *     Revision 1.25  2002/07/15 18:15:52  rwahl
+ *     Editorial changes.
+ *
+ *     Revision 1.24  2002/07/15 15:39:21  rschmidt
+ *     Corrected define for SKERR_SIRQ_E022
+ *     Editorial changes
+ *
+ *     Revision 1.23  2002/04/25 11:09:45  rschmidt
+ *     Removed declarations for SkXmInitPhy(), SkXmRxTxEnable()
+ *     Editorial changes
+ *
+ *     Revision 1.22  2000/11/09 11:30:10  rassmann
+ *     WA: Waiting after releasing reset until BCom chip is accessible.
+ *
+ *     Revision 1.21  2000/10/18 12:22:40  cgoos
+ *     Added workaround for half duplex hangup.
+ *
+ *     Revision 1.20  1999/12/06 10:00:44  cgoos
+ *     Added SET event for role.
+ *
+ *     Revision 1.19  1999/11/22 13:58:26  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.18  1999/05/19 07:32:59  cgoos
+ *     Changes for 1000Base-T.
+ *
+ *     Revision 1.17  1999/03/12 13:29:31  malthoff
+ *     Move Autonegotiation Error Codes to skgeinit.h.
+ *
+ *     Revision 1.16  1999/03/08 10:11:28  gklug
+ *     add: AutoNegDone return codes
+ *
+ *     Revision 1.15  1998/11/18 13:20:53  gklug
+ *     add: different timeouts for active and non-active links
+ *
+ *     Revision 1.14  1998/11/04 07:18:14  cgoos
+ *     Added prototype for SkXmRxTxEnable.
+ *
+ *     Revision 1.13  1998/10/21 05:52:23  gklug
+ *     add: parameter DoLoop to InitPhy function
+ *
+ *     Revision 1.12  1998/10/19 06:45:03  cgoos
+ *     Added prototype for SkXmInitPhy.
+ *
+ *     Revision 1.11  1998/10/15 14:34:10  gklug
+ *     add: WA_TIME is 500 msec
+ *
+ *     Revision 1.10  1998/10/14 14:49:41  malthoff
+ *     Remove err log defines E021 and E022. They are
+ *     defined in skgeinit.h now.
+ *
+ *     Revision 1.9  1998/10/14 14:00:39  gklug
+ *     add: error logs for init phys
+ *
+ *     Revision 1.8  1998/10/14 05:44:05  gklug
+ *     add: E020
+ *
+ *     Revision 1.7  1998/10/02 06:24:58  gklug
+ *     add: error messages
+ *
+ *     Revision 1.6  1998/10/01 07:54:45  gklug
+ *     add: PNMI debug module
+ *
+ *     Revision 1.5  1998/09/28 13:36:31  malthoff
+ *     Move the bit definitions for Autonegotiation
+ *     and Flow Control to skgeinit.h.
+ *
+ *     Revision 1.4  1998/09/15 12:29:34  gklug
+ *     add: error logs
+ *
+ *     Revision 1.3  1998/09/03 13:54:02  gklug
+ *     add: function prototypes
+ *
+ *     Revision 1.2  1998/09/03 10:24:36  gklug
+ *     add: Events send by PNMI
+ *     add: parameter definition for Flow Control etc.
+ *
+ *     Revision 1.1  1998/08/27 11:50:27  gklug
+ *     initial revision
+ *
+ *
+ ******************************************************************************/
+
+#ifndef _INC_SKGESIRQ_H_
+#define _INC_SKGESIRQ_H_
+
+/*
+ * Define the Event the special IRQ/INI module can handle
+ */
+#define SK_HWEV_WATIM                  1       /* Timeout for WA errata #2 XMAC */
+#define SK_HWEV_PORT_START             2       /* Port Start Event by RLMT */
+#define SK_HWEV_PORT_STOP              3       /* Port Stop Event by RLMT */
+#define SK_HWEV_CLEAR_STAT             4       /* Clear Statistics by PNMI */
+#define SK_HWEV_UPDATE_STAT            5       /* Update Statistics by PNMI */
+#define SK_HWEV_SET_LMODE              6       /* Set Link Mode by PNMI */
+#define SK_HWEV_SET_FLOWMODE   7       /* Set Flow Control Mode by PNMI */
+#define SK_HWEV_SET_ROLE               8       /* Set Master/Slave (Role) by PNMI */
+#define SK_HWEV_SET_SPEED              9       /* Set Link Speed by PNMI */
+#define SK_HWEV_HALFDUP_CHK            10      /* Half Duplex Hangup Workaround */
+
+#define SK_WA_ACT_TIME         (5000000L)      /* 5 sec */
+#define SK_WA_INA_TIME         (100000L)       /* 100 msec */
+
+#define SK_HALFDUP_CHK_TIME    (10000L)        /* 10 msec */
+
+/*
+ * Define the error numbers and messages
+ */
+#define SKERR_SIRQ_E001                (SK_ERRBASE_SIRQ+0)
+#define SKERR_SIRQ_E001MSG     "Unknown event"
+#define SKERR_SIRQ_E002                (SKERR_SIRQ_E001+1)
+#define SKERR_SIRQ_E002MSG     "Packet timeout RX1"
+#define SKERR_SIRQ_E003                (SKERR_SIRQ_E002+1)
+#define SKERR_SIRQ_E003MSG     "Packet timeout RX2"
+#define SKERR_SIRQ_E004                (SKERR_SIRQ_E003+1)
+#define SKERR_SIRQ_E004MSG     "MAC 1 not correctly initialized"
+#define SKERR_SIRQ_E005                (SKERR_SIRQ_E004+1)
+#define SKERR_SIRQ_E005MSG     "MAC 2 not correctly initialized"
+#define SKERR_SIRQ_E006                (SKERR_SIRQ_E005+1)
+#define SKERR_SIRQ_E006MSG     "CHECK failure R1"
+#define SKERR_SIRQ_E007                (SKERR_SIRQ_E006+1)
+#define SKERR_SIRQ_E007MSG     "CHECK failure R2"
+#define SKERR_SIRQ_E008                (SKERR_SIRQ_E007+1)
+#define SKERR_SIRQ_E008MSG     "CHECK failure XS1"
+#define SKERR_SIRQ_E009                (SKERR_SIRQ_E008+1)
+#define SKERR_SIRQ_E009MSG     "CHECK failure XA1"
+#define SKERR_SIRQ_E010                (SKERR_SIRQ_E009+1)
+#define SKERR_SIRQ_E010MSG     "CHECK failure XS2"
+#define SKERR_SIRQ_E011                (SKERR_SIRQ_E010+1)
+#define SKERR_SIRQ_E011MSG     "CHECK failure XA2"
+#define SKERR_SIRQ_E012                (SKERR_SIRQ_E011+1)
+#define SKERR_SIRQ_E012MSG     "unexpected IRQ Master error"
+#define SKERR_SIRQ_E013                (SKERR_SIRQ_E012+1)
+#define SKERR_SIRQ_E013MSG     "unexpected IRQ Status error"
+#define SKERR_SIRQ_E014                (SKERR_SIRQ_E013+1)
+#define SKERR_SIRQ_E014MSG     "Parity error on RAM (read)"
+#define SKERR_SIRQ_E015                (SKERR_SIRQ_E014+1)
+#define SKERR_SIRQ_E015MSG     "Parity error on RAM (write)"
+#define SKERR_SIRQ_E016                (SKERR_SIRQ_E015+1)
+#define SKERR_SIRQ_E016MSG     "Parity error MAC 1"
+#define SKERR_SIRQ_E017                (SKERR_SIRQ_E016+1)
+#define SKERR_SIRQ_E017MSG     "Parity error MAC 2"
+#define SKERR_SIRQ_E018                (SKERR_SIRQ_E017+1)
+#define SKERR_SIRQ_E018MSG     "Parity error RX 1"
+#define SKERR_SIRQ_E019                (SKERR_SIRQ_E018+1)
+#define SKERR_SIRQ_E019MSG     "Parity error RX 2"
+#define SKERR_SIRQ_E020                (SKERR_SIRQ_E019+1)
+#define SKERR_SIRQ_E020MSG     "MAC transmit FIFO underrun"
+#define SKERR_SIRQ_E021                (SKERR_SIRQ_E020+1)
+#define SKERR_SIRQ_E021MSG     "Spurious TWSI interrupt"
+#define SKERR_SIRQ_E022                (SKERR_SIRQ_E021+1)
+#define SKERR_SIRQ_E022MSG     "Cable pair swap error"
+#define SKERR_SIRQ_E023                (SKERR_SIRQ_E022+1)
+#define SKERR_SIRQ_E023MSG     "Auto-negotiation error"
+#define SKERR_SIRQ_E024                (SKERR_SIRQ_E023+1)
+#define SKERR_SIRQ_E024MSG     "FIFO overflow error"
+
+extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus);
+extern int  SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
+extern void SkHWLinkUp(SK_AC *pAC, SK_IOC IoC, int Port);
+extern void SkHWLinkDown(SK_AC *pAC, SK_IOC IoC, int Port);
+
+#endif /* _INC_SKGESIRQ_H_ */
diff --git a/drivers/net/sk98lin/h/ski2c.h b/drivers/net/sk98lin/h/ski2c.h
new file mode 100644 (file)
index 0000000..5ffaf6e
--- /dev/null
@@ -0,0 +1,292 @@
+/******************************************************************************
+ *
+ * Name:       ski2c.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.34 $
+ * Date:       $Date: 2003/01/28 09:11:21 $
+ * Purpose:    Defines to access Voltage and Temperature Sensor
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2003 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: ski2c.h,v $
+ *     Revision 1.34  2003/01/28 09:11:21  rschmidt
+ *     Editorial changes
+ *
+ *     Revision 1.33  2002/10/14 16:40:50  rschmidt
+ *     Editorial changes (TWSI)
+ *
+ *     Revision 1.32  2002/08/13 08:55:07  rschmidt
+ *     Editorial changes
+ *
+ *     Revision 1.31  2002/08/06 09:44:22  jschmalz
+ *     Extensions and changes for Yukon
+ *
+ *     Revision 1.30  2001/04/05 11:38:09  rassmann
+ *     Set SenState to idle in SkI2cWaitIrq().
+ *     Changed error message in SkI2cWaitIrq().
+ *
+ *     Revision 1.29  2000/08/03 14:28:17  rassmann
+ *     - Added function to wait for I2C being ready before resetting the board.
+ *     - Replaced one duplicate "out of range" message with correct one.
+ *
+ *     Revision 1.28  1999/11/22 13:55:46  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.27  1999/05/20 09:23:10  cgoos
+ *     Changes for 1000Base-T (Fan sensors).
+ *
+ *     Revision 1.26  1998/12/01 13:45:47  gklug
+ *     add: InitLevel to I2c struct
+ *
+ *     Revision 1.25  1998/11/03 06:55:16  gklug
+ *     add: Dummy Reads to I2c struct
+ *
+ *     Revision 1.24  1998/10/02 14:28:59  cgoos
+ *     Added prototype for SkI2cIsr.
+ *
+ *     Revision 1.23  1998/09/08 12:20:11  gklug
+ *     add: prototypes for init and read functions
+ *
+ *     Revision 1.22  1998/09/08 07:37:56  gklug
+ *     add: log error if PCI_IO voltage sensor could not be initialized
+ *
+ *     Revision 1.21  1998/09/04 08:38:05  malthoff
+ *     Change the values for I2C_READ and I2C_WRITE
+ *
+ *     Revision 1.20  1998/08/25 07:52:22  gklug
+ *     chg: Timestamps (last) added for logging
+ *
+ *     Revision 1.19  1998/08/25 06:09:00  gklug
+ *     rmv: warning and error levels of the individual sensors.
+ *     add: timing definitions for sending traps and logging errors
+ *
+ *     Revision 1.18  1998/08/20 11:41:15  gklug
+ *     chg: omit STRCPY macro by using char * as Sensor Description
+ *
+ *     Revision 1.17  1998/08/20 11:37:43  gklug
+ *     chg: change Ioc to IoC
+ *
+ *     Revision 1.16  1998/08/20 11:30:38  gklug
+ *     fix: SenRead declaration
+ *
+ *     Revision 1.15  1998/08/20 11:27:53  gklug
+ *     fix: Compile bugs with new awrning constants
+ *
+ *     Revision 1.14  1998/08/20 08:53:12  gklug
+ *     fix: compiler errors
+ *     add: Threshold values
+ *
+ *     Revision 1.13  1998/08/19 12:21:16  gklug
+ *     fix: remove struct from C files (see CCC)
+ *     add: typedefs for all structs
+ *
+ *     Revision 1.12  1998/08/19 10:57:41  gklug
+ *     add: Warning levels
+ *
+ *     Revision 1.11  1998/08/18 08:37:02  malthoff
+ *     Prototypes not required for SK_DIAG.
+ *
+ *     Revision 1.10  1998/08/17 13:54:00  gklug
+ *     fix: declaration of event function
+ *
+ *     Revision 1.9  1998/08/17 06:48:39  malthoff
+ *     Remove some unrequired macros.
+ *     Fix the compiler errors.
+ *
+ *     Revision 1.8  1998/08/14 06:47:19  gklug
+ *     fix: Values are intergers
+ *
+ *     Revision 1.7  1998/08/14 06:26:05  gklug
+ *     add: Init error message
+ *
+ *     Revision 1.6  1998/08/13 08:31:08  gklug
+ *     add: Error message
+ *
+ *     Revision 1.5  1998/08/12 14:32:04  gklug
+ *     add: new error code/message
+ *
+ *     Revision 1.4  1998/08/12 13:39:08  gklug
+ *     chg: names of error messages
+ *     add: defines for Sensor type and thresholds
+ *
+ *     Revision 1.3  1998/08/11 07:57:16  gklug
+ *     add: sensor struct
+ *     add: Timeout defines
+ *     add: I2C control struct for pAC
+ *
+ *     Revision 1.2  1998/07/17 11:29:02  gklug
+ *     rmv: Microwire and SMTPANIC
+ *
+ *     Revision 1.1  1998/06/19 14:30:10  malthoff
+ *     Created. Sources taken from ML Project.
+ *
+ *
+ ******************************************************************************/
+
+/*
+ * SKI2C.H     contains all I2C specific defines
+ */
+
+#ifndef _SKI2C_H_
+#define _SKI2C_H_
+
+typedef struct  s_Sensor SK_SENSOR;
+
+#include "h/skgei2c.h"
+
+/*
+ * Define the I2C events.
+ */
+#define SK_I2CEV_IRQ   1       /* IRQ happened Event */
+#define SK_I2CEV_TIM   2       /* Timeout event */
+#define SK_I2CEV_CLEAR 3       /* Clear MIB Values */
+
+/*
+ * Define READ and WRITE Constants.
+ */
+#undef I2C_READ                /* just in case */
+#undef I2C_WRITE               /* just in case */
+#define I2C_READ       0
+#define I2C_WRITE      1
+#define I2C_BURST      1
+#define I2C_SINGLE     0
+
+#define SKERR_I2C_E001         (SK_ERRBASE_I2C+0)
+#define SKERR_I2C_E001MSG      "Sensor index unknown"
+#define SKERR_I2C_E002         (SKERR_I2C_E001+1)
+#define SKERR_I2C_E002MSG      "TWSI: transfer does not complete"
+#define SKERR_I2C_E003         (SKERR_I2C_E002+1)
+#define SKERR_I2C_E003MSG      "LM80: NAK on device send"
+#define SKERR_I2C_E004         (SKERR_I2C_E003+1)
+#define SKERR_I2C_E004MSG      "LM80: NAK on register send"
+#define SKERR_I2C_E005         (SKERR_I2C_E004+1)
+#define SKERR_I2C_E005MSG      "LM80: NAK on device (2) send"
+#define SKERR_I2C_E006         (SKERR_I2C_E005+1)
+#define SKERR_I2C_E006MSG      "Unknown event"
+#define SKERR_I2C_E007         (SKERR_I2C_E006+1)
+#define SKERR_I2C_E007MSG      "LM80 read out of state"
+#define SKERR_I2C_E008         (SKERR_I2C_E007+1)
+#define SKERR_I2C_E008MSG      "Unexpected sensor read completed"
+#define SKERR_I2C_E009         (SKERR_I2C_E008+1)
+#define SKERR_I2C_E009MSG      "WARNING: temperature sensor out of range"
+#define SKERR_I2C_E010         (SKERR_I2C_E009+1)
+#define SKERR_I2C_E010MSG      "WARNING: voltage sensor out of range"
+#define SKERR_I2C_E011         (SKERR_I2C_E010+1)
+#define SKERR_I2C_E011MSG      "ERROR: temperature sensor out of range"
+#define SKERR_I2C_E012         (SKERR_I2C_E011+1)
+#define SKERR_I2C_E012MSG      "ERROR: voltage sensor out of range"
+#define SKERR_I2C_E013         (SKERR_I2C_E012+1)
+#define SKERR_I2C_E013MSG      "ERROR: couldn't init sensor"
+#define SKERR_I2C_E014         (SKERR_I2C_E013+1)
+#define SKERR_I2C_E014MSG      "WARNING: fan sensor out of range"
+#define SKERR_I2C_E015         (SKERR_I2C_E014+1)
+#define SKERR_I2C_E015MSG      "ERROR: fan sensor out of range"
+#define SKERR_I2C_E016         (SKERR_I2C_E015+1)
+#define SKERR_I2C_E016MSG      "TWSI: active transfer does not complete"
+
+/*
+ * Define Timeout values
+ */
+#define SK_I2C_TIM_LONG                2000000L        /* 2 seconds */
+#define SK_I2C_TIM_SHORT        100000L        /* 100 milliseconds */
+#define SK_I2C_TIM_WATCH       1000000L        /* 1 second */
+
+/*
+ * Define trap and error log hold times
+ */
+#ifndef        SK_SEN_ERR_TR_HOLD
+#define SK_SEN_ERR_TR_HOLD             (4*SK_TICKS_PER_SEC)
+#endif
+#ifndef        SK_SEN_ERR_LOG_HOLD
+#define SK_SEN_ERR_LOG_HOLD            (60*SK_TICKS_PER_SEC)
+#endif
+#ifndef        SK_SEN_WARN_TR_HOLD
+#define SK_SEN_WARN_TR_HOLD            (15*SK_TICKS_PER_SEC)
+#endif
+#ifndef        SK_SEN_WARN_LOG_HOLD
+#define SK_SEN_WARN_LOG_HOLD   (15*60*SK_TICKS_PER_SEC)
+#endif
+
+/*
+ * Defines for SenType
+ */
+#define SK_SEN_UNKNOWN 0
+#define SK_SEN_TEMP            1
+#define SK_SEN_VOLT            2
+#define SK_SEN_FAN             3
+
+/*
+ * Define for the SenErrorFlag
+ */
+#define SK_SEN_ERR_NOT_PRESENT 0       /* Error Flag: Sensor not present */
+#define SK_SEN_ERR_OK                  1       /* Error Flag: O.K. */
+#define SK_SEN_ERR_WARN                        2       /* Error Flag: Warning */
+#define SK_SEN_ERR_ERR                 3       /* Error Flag: Error */
+#define SK_SEN_ERR_FAULTY              4       /* Error Flag: Faulty */
+
+/*
+ * Define the Sensor struct
+ */
+struct s_Sensor {
+       char    *SenDesc;                       /* Description */
+       int             SenType;                        /* Voltage or Temperature */
+       SK_I32  SenValue;                       /* Current value of the sensor */
+       SK_I32  SenThreErrHigh;         /* High error Threshhold of this sensor */
+       SK_I32  SenThreWarnHigh;        /* High warning Threshhold of this sensor */
+       SK_I32  SenThreErrLow;          /* Lower error Threshold of the sensor */
+       SK_I32  SenThreWarnLow;         /* Lower warning Threshold of the sensor */
+       int             SenErrFlag;                     /* Sensor indicated an error */
+       SK_BOOL SenInit;                        /* Is sensor initialized ? */
+       SK_U64  SenErrCts;                      /* Error  trap counter */
+       SK_U64  SenWarnCts;                     /* Warning trap counter */
+       SK_U64  SenBegErrTS;            /* Begin error timestamp */
+       SK_U64  SenBegWarnTS;           /* Begin warning timestamp */
+       SK_U64  SenLastErrTrapTS;       /* Last error trap timestamp */
+       SK_U64  SenLastErrLogTS;        /* Last error log timestamp */
+       SK_U64  SenLastWarnTrapTS;      /* Last warning trap timestamp */
+       SK_U64  SenLastWarnLogTS;       /* Last warning log timestamp */
+       int             SenState;                       /* Sensor State (see HW specific include) */
+       int             (*SenRead)(SK_AC *pAC, SK_IOC IoC, struct s_Sensor *pSen);
+                                                               /* Sensors read function */
+       SK_U16  SenReg;                         /* Register Address for this sensor */
+       SK_U8   SenDev;                         /* Device Selection for this sensor */
+};
+
+typedef        struct  s_I2c {
+       SK_SENSOR       SenTable[SK_MAX_SENSORS];       /* Sensor Table */
+       int                     CurrSens;       /* Which sensor is currently queried */
+       int                     MaxSens;        /* Max. number of sensors */
+       int                     TimerMode;      /* Use the timer also to watch the state machine */
+       int                     InitLevel;      /* Initialized Level */
+#ifndef SK_DIAG
+       int                     DummyReads;     /* Number of non-checked dummy reads */
+       SK_TIMER        SenTimer;       /* Sensors timer */
+#endif /* !SK_DIAG */
+} SK_I2C;
+
+extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
+#ifndef SK_DIAG
+extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
+extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level);
+extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC);
+extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC);
+
+#endif
+#endif /* n_SKI2C_H */
diff --git a/drivers/net/sk98lin/h/skqueue.h b/drivers/net/sk98lin/h/skqueue.h
new file mode 100644 (file)
index 0000000..bce20a7
--- /dev/null
@@ -0,0 +1,147 @@
+/******************************************************************************
+ *
+ * Name:       skqueue.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.14 $
+ * Date:       $Date: 2002/03/15 10:52:13 $
+ * Purpose:    Defines for the Event queue
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998,1999 SysKonnect,
+ *     a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skqueue.h,v $
+ *     Revision 1.14  2002/03/15 10:52:13  mkunz
+ *     Added event classes for link aggregation
+ *
+ *     Revision 1.13  1999/11/22 13:59:05  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.12  1998/09/08 08:48:01  gklug
+ *     add: init level handling
+ *
+ *     Revision 1.11  1998/09/03 14:15:11  gklug
+ *     add: CSUM and HWAC Eventclass and function.
+ *     fix: pParaPtr according to CCC
+ *
+ *     Revision 1.10  1998/08/20 12:43:03  gklug
+ *     add: typedef SK_QUEUE
+ *
+ *     Revision 1.9  1998/08/19 09:50:59  gklug
+ *     fix: remove struct keyword from c-code (see CCC) add typedefs
+ *
+ *     Revision 1.8  1998/08/18 07:00:01  gklug
+ *     fix: SK_PTR not defined use void * instead.
+ *
+ *     Revision 1.7  1998/08/17 13:43:19  gklug
+ *     chg: Parameter will be union of 64bit para, 2 times SK_U32 or SK_PTR
+ *
+ *     Revision 1.6  1998/08/14 07:09:30  gklug
+ *     fix: chg pAc -> pAC
+ *
+ *     Revision 1.5  1998/08/11 14:26:44  gklug
+ *     chg: Event Dispatcher returns now int.
+ *
+ *     Revision 1.4  1998/08/11 12:15:21  gklug
+ *     add: Error numbers of skqueue module
+ *
+ *     Revision 1.3  1998/08/07 12:54:23  gklug
+ *     fix: first compiled version
+ *
+ *     Revision 1.2  1998/08/07 09:34:00  gklug
+ *     adapt structure defs to CCC
+ *     add: prototypes for functions
+ *
+ *     Revision 1.1  1998/07/30 14:52:12  gklug
+ *     Initial version.
+ *     Defines Event Classes, Event structs and queue management variables.
+ *
+ *
+ *
+ ******************************************************************************/
+
+/*
+ * SKQUEUE.H   contains all defines and types for the event queue
+ */
+
+#ifndef _SKQUEUE_H_
+#define _SKQUEUE_H_
+
+
+/*
+ * define the event classes to be served
+ */
+#define        SKGE_DRV        1       /* Driver Event Class */
+#define        SKGE_RLMT       2       /* RLMT Event Class */
+#define        SKGE_I2C        3       /* i2C Event Class */
+#define        SKGE_PNMI       4       /* PNMI Event Class */
+#define        SKGE_CSUM       5       /* Checksum Event Class */
+#define        SKGE_HWAC       6       /* Hardware Access Event Class */
+
+#define        SKGE_SWT        9       /* Software Timer Event Class */
+#define        SKGE_LACP       10      /* LACP Aggregation Event Class */
+#define        SKGE_RSF        11      /* RSF Aggregation Event Class */
+#define        SKGE_MARKER     12      /* MARKER Aggregation Event Class */
+#define        SKGE_FD         13      /* FD Distributor Event Class */
+
+/*
+ * define event queue as circular buffer
+ */
+#define SK_MAX_EVENT   64
+
+/*
+ * Parameter union for the Para stuff
+ */
+typedef        union u_EvPara {
+       void    *pParaPtr;      /* Parameter Pointer */
+       SK_U64  Para64;         /* Parameter 64bit version */
+       SK_U32  Para32[2];      /* Parameter Array of 32bit parameters */
+} SK_EVPARA;
+
+/*
+ * Event Queue
+ *     skqueue.c
+ * events are class/value pairs
+ *     class   is addressee, e.g. RMT, PCM etc.
+ *     value   is command, e.g. line state change, ring op change etc.
+ */
+typedef        struct s_EventElem {
+       SK_U32          Class ;                 /* Event class */
+       SK_U32          Event ;                 /* Event value */
+       SK_EVPARA       Para ;                  /* Event parameter */
+} SK_EVENTELEM;
+
+typedef        struct s_Queue {
+       SK_EVENTELEM    EvQueue[SK_MAX_EVENT];
+       SK_EVENTELEM    *EvPut ;
+       SK_EVENTELEM    *EvGet ;
+} SK_QUEUE;
+
+extern void SkEventInit(SK_AC *pAC, SK_IOC Ioc, int Level);
+extern void SkEventQueue(SK_AC *pAC, SK_U32 Class, SK_U32 Event,
+       SK_EVPARA Para);
+extern int SkEventDispatcher(SK_AC *pAC,SK_IOC Ioc);
+
+
+/* Define Error Numbers and messages */
+#define        SKERR_Q_E001    (SK_ERRBASE_QUEUE+0)
+#define        SKERR_Q_E001MSG "Event queue overflow"
+#define        SKERR_Q_E002    (SKERR_Q_E001+1)
+#define        SKERR_Q_E002MSG "Undefined event class"
+#endif /* _SKQUEUE_H_ */
diff --git a/drivers/net/sk98lin/h/skrlmt.h b/drivers/net/sk98lin/h/skrlmt.h
new file mode 100644 (file)
index 0000000..04d025b
--- /dev/null
@@ -0,0 +1,563 @@
+/******************************************************************************
+ *
+ * Name:       skrlmt.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.35 $
+ * Date:       $Date: 2003/01/31 14:12:41 $
+ * Purpose:    Header file for Redundant Link ManagemenT.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2001 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skrlmt.h,v $
+ *     Revision 1.35  2003/01/31 14:12:41  mkunz
+ *     single port adapter runs now with two identical MAC addresses
+ *
+ *     Revision 1.34  2002/09/23 15:13:41  rwahl
+ *     Editorial changes.
+ *
+ *     Revision 1.33  2001/07/03 12:16:48  mkunz
+ *     New Flag ChgBcPrio (Change priority of last broadcast received)
+ *
+ *     Revision 1.32  2001/02/14 14:06:31  rassmann
+ *     Editorial changes.
+ *
+ *     Revision 1.31  2001/02/05 14:25:26  rassmann
+ *     Prepared RLMT for transparent operation.
+ *
+ *     Revision 1.30  2001/01/22 13:41:39  rassmann
+ *     Supporting two nets on dual-port adapters.
+ *
+ *     Revision 1.29  2000/11/17 08:58:00  rassmann
+ *     Moved CheckSwitch from SK_RLMT_PACKET_RECEIVED to SK_RLMT_TIM event.
+ *
+ *     Revision 1.28  2000/11/09 12:24:34  rassmann
+ *     Editorial changes.
+ *
+ *     Revision 1.27  1999/11/22 13:59:56  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.26  1999/10/04 14:01:19  rassmann
+ *     Corrected reaction to reception of BPDU frames (#10441).
+ *
+ *     Revision 1.25  1999/07/20 12:53:39  rassmann
+ *     Fixed documentation errors for lookahead macros.
+ *
+ *     Revision 1.24  1999/05/28 11:15:56  rassmann
+ *     Changed behaviour to reflect Design Spec v1.2.
+ *     Controlling Link LED(s).
+ *     Introduced RLMT Packet Version field in RLMT Packet.
+ *     Newstyle lookahead macros (checking meta-information before looking at
+ *       the packet).
+ *
+ *     Revision 1.23  1999/01/28 12:50:42  rassmann
+ *     Not using broadcast time stamps in CheckLinkState mode.
+ *
+ *     Revision 1.22  1999/01/27 14:13:04  rassmann
+ *     Monitoring broadcast traffic.
+ *     Switching more reliably and not too early if switch is
+ *      configured for spanning tree.
+ *
+ *     Revision 1.21  1998/12/08 13:11:25  rassmann
+ *     Stopping SegTimer at RlmtStop.
+ *
+ *     Revision 1.20  1998/11/24 12:37:33  rassmann
+ *     Implemented segmentation check.
+ *
+ *     Revision 1.19  1998/11/17 13:43:06  rassmann
+ *     Handling (logical) tx failure.
+ *     Sending packet on logical address after PORT_SWITCH.
+ *
+ *     Revision 1.18  1998/11/13 16:56:56  rassmann
+ *     Added macro version of SkRlmtLookaheadPacket.
+ *
+ *     Revision 1.17  1998/11/06 18:06:05  rassmann
+ *     Corrected timing when RLMT checks fail.
+ *     Clearing tx counter earlier in periodical checks.
+ *
+ *     Revision 1.16  1998/11/03 13:53:50  rassmann
+ *     RLMT should switch now (at least in mode 3).
+ *
+ *     Revision 1.15  1998/10/22 11:39:52  rassmann
+ *     Corrected signed/unsigned mismatches.
+ *     Corrected receive list handling and address recognition.
+ *
+ *     Revision 1.14  1998/10/15 15:16:36  rassmann
+ *     Finished Spanning Tree checking.
+ *     Checked with lint.
+ *
+ *     Revision 1.13  1998/09/24 19:16:08  rassmann
+ *     Code cleanup.
+ *     Introduced Timer for PORT_DOWN due to no RX.
+ *
+ *     Revision 1.12  1998/09/16 11:09:52  rassmann
+ *     Syntax corrections.
+ *
+ *     Revision 1.11  1998/09/15 11:28:50  rassmann
+ *     Syntax corrections.
+ *
+ *     Revision 1.10  1998/09/14 17:07:38  rassmann
+ *     Added code for port checking via LAN.
+ *     Changed Mbuf definition.
+ *
+ *     Revision 1.9  1998/09/07 11:14:15  rassmann
+ *     Syntax corrections.
+ *
+ *     Revision 1.8  1998/09/07 09:06:08  rassmann
+ *     Syntax corrections.
+ *
+ *     Revision 1.7  1998/09/04 19:41:34  rassmann
+ *     Syntax corrections.
+ *     Started entering code for checking local links.
+ *
+ *     Revision 1.6  1998/09/04 12:14:28  rassmann
+ *     Interface cleanup.
+ *
+ *     Revision 1.5  1998/09/02 16:55:29  rassmann
+ *     Updated to reflect new DRV/HWAC/RLMT interface.
+ *
+ *     Revision 1.4  1998/09/02 07:26:02  afischer
+ *     typedef for SK_RLMT_PORT
+ *
+ *     Revision 1.3  1998/08/27 14:29:03  rassmann
+ *     Code cleanup.
+ *
+ *     Revision 1.2  1998/08/27 14:26:25  rassmann
+ *     Updated interface.
+ *
+ *     Revision 1.1  1998/08/21 08:29:10  rassmann
+ *     First public version.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * This is the header file for Redundant Link ManagemenT.
+ *
+ * Include File Hierarchy:
+ *
+ *     "skdrv1st.h"
+ *     ...
+ *     "sktypes.h"
+ *     "skqueue.h"
+ *     "skaddr.h"
+ *     "skrlmt.h"
+ *     ...
+ *     "skdrv2nd.h"
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKRLMT_H
+#define __INC_SKRLMT_H
+
+#ifdef __cplusplus
+#error C++ is not yet supported.
+extern "C" {
+#endif /* cplusplus */
+
+/* defines ********************************************************************/
+
+#define        SK_RLMT_NET_DOWN_TEMP   1       /* NET_DOWN due to last port down. */
+#define        SK_RLMT_NET_DOWN_FINAL  2       /* NET_DOWN due to RLMT_STOP. */
+
+/* ----- Default queue sizes - must be multiples of 8 KB ----- */
+
+/* Less than 8 KB free in RX queue => pause frames. */
+#define SK_RLMT_STANDBY_QRXSIZE        128     /* Size of rx standby queue in KB. */
+#define SK_RLMT_STANDBY_QXASIZE        32      /* Size of async standby queue in KB. */
+#define SK_RLMT_STANDBY_QXSSIZE        0       /* Size of sync standby queue in KB. */
+
+#define SK_RLMT_MAX_TX_BUF_SIZE        60      /* Maximum RLMT transmit size. */
+
+/* ----- PORT states ----- */
+
+#define SK_RLMT_PS_INIT                        0       /* Port state: Init. */
+#define SK_RLMT_PS_LINK_DOWN   1       /* Port state: Link down. */
+#define SK_RLMT_PS_DOWN                        2       /* Port state: Port down. */
+#define SK_RLMT_PS_GOING_UP            3       /* Port state: Going up. */
+#define SK_RLMT_PS_UP                  4       /* Port state: Up. */
+
+/* ----- RLMT states ----- */
+
+#define SK_RLMT_RS_INIT                        0       /* RLMT state: Init. */
+#define SK_RLMT_RS_NET_DOWN            1       /* RLMT state: Net down. */
+#define SK_RLMT_RS_NET_UP              2       /* RLMT state: Net up. */
+
+/* ----- PORT events ----- */
+
+#define SK_RLMT_LINK_UP                        1001    /* Link came up. */
+#define SK_RLMT_LINK_DOWN              1002    /* Link went down. */
+#define SK_RLMT_PORT_ADDR              1003    /* Port address changed. */
+
+/* ----- RLMT events ----- */
+
+#define SK_RLMT_START                  2001    /* Start RLMT. */
+#define SK_RLMT_STOP                   2002    /* Stop RLMT. */
+#define SK_RLMT_PACKET_RECEIVED        2003    /* Packet was received for RLMT. */
+#define SK_RLMT_STATS_CLEAR            2004    /* Clear statistics. */
+#define SK_RLMT_STATS_UPDATE   2005    /* Update statistics. */
+#define SK_RLMT_PREFPORT_CHANGE        2006    /* Change preferred port. */
+#define SK_RLMT_MODE_CHANGE            2007    /* New RlmtMode. */
+#define SK_RLMT_SET_NETS               2008    /* Number of Nets (1 or 2). */
+
+/* ----- RLMT mode bits ----- */
+
+/*
+ * CAUTION:    These defines are private to RLMT.
+ *                     Please use the RLMT mode defines below.
+ */
+
+#define SK_RLMT_CHECK_LINK               1             /* Check Link. */
+#define SK_RLMT_CHECK_LOC_LINK   2             /* Check other link on same adapter. */
+#define SK_RLMT_CHECK_SEG                4             /* Check segmentation. */
+
+#ifndef RLMT_CHECK_REMOTE
+#define SK_RLMT_CHECK_OTHERS   SK_RLMT_CHECK_LOC_LINK
+#else  /* RLMT_CHECK_REMOTE */
+#define SK_RLMT_CHECK_REM_LINK   8             /* Check link(s) on other adapter(s). */
+#define SK_RLMT_MAX_REMOTE_PORTS_CHECKED       3
+#define SK_RLMT_CHECK_OTHERS   \
+               (SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
+#endif /* RLMT_CHECK_REMOTE */
+
+#ifndef SK_RLMT_ENABLE_TRANSPARENT
+#define SK_RLMT_TRANSPARENT              0             /* RLMT transparent - inactive. */
+#else  /* SK_RLMT_ENABLE_TRANSPARENT */
+#define SK_RLMT_TRANSPARENT            128             /* RLMT transparent. */
+#endif /* SK_RLMT_ENABLE_TRANSPARENT */
+
+/* ----- RLMT modes ----- */
+
+/* Check Link State. */
+#define SK_RLMT_MODE_CLS       (SK_RLMT_CHECK_LINK)
+
+/* Check Local Ports: check other links on the same adapter. */
+#define SK_RLMT_MODE_CLP       (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK)
+
+/* Check Local Ports and Segmentation Status. */
+#define SK_RLMT_MODE_CLPSS     \
+               (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_SEG)
+
+#ifdef RLMT_CHECK_REMOTE
+/* Check Local and Remote Ports: check links (local or remote). */
+       Name of define TBD!
+#define SK_RLMT_MODE_CRP       \
+               (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
+
+/* Check Local and Remote Ports and Segmentation Status. */
+       Name of define TBD!
+#define SK_RLMT_MODE_CRPSS     \
+               (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | \
+               SK_RLMT_CHECK_REM_LINK | SK_RLMT_CHECK_SEG)
+#endif /* RLMT_CHECK_REMOTE */
+
+/* ----- RLMT lookahead result bits ----- */
+
+#define SK_RLMT_RX_RLMT                        1       /* Give packet to RLMT. */
+#define SK_RLMT_RX_PROTOCOL            2       /* Give packet to protocol. */
+
+/* Macros */
+
+#if 0
+SK_AC          *pAC            /* adapter context */
+SK_U32         PortNum         /* receiving port */
+unsigned       PktLen          /* received packet's length */
+SK_BOOL                IsBc            /* Flag: packet is broadcast */
+unsigned       *pOffset        /* offs. of bytes to present to SK_RLMT_LOOKAHEAD */
+unsigned       *pNumBytes      /* #Bytes to present to SK_RLMT_LOOKAHEAD */
+#endif /* 0 */
+
+#define SK_RLMT_PRE_LOOKAHEAD(pAC,PortNum,PktLen,IsBc,pOffset,pNumBytes) { \
+       SK_AC   *_pAC; \
+       SK_U32  _PortNum; \
+       _pAC = (pAC); \
+       _PortNum = (SK_U32)(PortNum); \
+       /* _pAC->Rlmt.Port[_PortNum].PacketsRx++; */ \
+       _pAC->Rlmt.Port[_PortNum].PacketsPerTimeSlot++; \
+    if (_pAC->Rlmt.RlmtOff) { \
+               *(pNumBytes) = 0; \
+    } \
+    else {\
+       if ((_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_TRANSPARENT) != 0) { \
+               *(pNumBytes) = 0; \
+       } \
+       else if (IsBc) { \
+               if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode != SK_RLMT_MODE_CLS) { \
+                       *(pNumBytes) = 6; \
+                       *(pOffset) = 6; \
+               } \
+               else { \
+                       *(pNumBytes) = 0; \
+               } \
+       } \
+       else { \
+               if ((PktLen) > SK_RLMT_MAX_TX_BUF_SIZE) { \
+                       /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
+                       *(pNumBytes) = 0; \
+               } \
+               else { \
+                       *(pNumBytes) = 6; \
+                       *(pOffset) = 0; \
+               } \
+       } \
+    } \
+}
+
+#if 0
+SK_AC          *pAC            /* adapter context */
+SK_U32         PortNum         /* receiving port */
+SK_U8          *pLaPacket,     /* received packet's data (points to pOffset) */
+SK_BOOL                IsBc            /* Flag: packet is broadcast */
+SK_BOOL                IsMc            /* Flag: packet is multicast */
+unsigned       *pForRlmt       /* Result: bits SK_RLMT_RX_RLMT, SK_RLMT_RX_PROTOCOL */
+SK_RLMT_LOOKAHEAD() expects *pNumBytes from
+packet offset *pOffset (s.a.) at *pLaPacket.
+
+If you use SK_RLMT_LOOKAHEAD in a path where you already know if the packet is
+BC, MC, or UC, you should use constants for IsBc and IsMc, so that your compiler
+can trash unneeded parts of the if construction.
+#endif /* 0 */
+
+#define SK_RLMT_LOOKAHEAD(pAC,PortNum,pLaPacket,IsBc,IsMc,pForRlmt) { \
+       SK_AC   *_pAC; \
+       SK_U32  _PortNum; \
+       SK_U8   *_pLaPacket; \
+       _pAC = (pAC); \
+       _PortNum = (SK_U32)(PortNum); \
+       _pLaPacket = (SK_U8 *)(pLaPacket); \
+       if (IsBc) {\
+               if (!SK_ADDR_EQUAL(_pLaPacket, _pAC->Addr.Net[_pAC->Rlmt.Port[ \
+                       _PortNum].Net->NetNumber].CurrentMacAddress.a)) { \
+                       _pAC->Rlmt.Port[_PortNum].BcTimeStamp = SkOsGetTime(_pAC); \
+                       _pAC->Rlmt.CheckSwitch = SK_TRUE; \
+               } \
+               /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
+               *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
+       } \
+       else if (IsMc) { \
+               if (SK_ADDR_EQUAL(_pLaPacket, BridgeMcAddr.a)) { \
+                       _pAC->Rlmt.Port[_PortNum].BpduPacketsPerTimeSlot++; \
+                       if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_CHECK_SEG) { \
+                               *(pForRlmt) = SK_RLMT_RX_RLMT | SK_RLMT_RX_PROTOCOL; \
+                       } \
+                       else { \
+                               *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
+                       } \
+               } \
+               else if (SK_ADDR_EQUAL(_pLaPacket, SkRlmtMcAddr.a)) { \
+                       *(pForRlmt) = SK_RLMT_RX_RLMT; \
+               } \
+               else { \
+                       /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
+                       *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
+               } \
+       } \
+       else { \
+               if (SK_ADDR_EQUAL( \
+                       _pLaPacket, \
+                       _pAC->Addr.Port[_PortNum].CurrentMacAddress.a)) { \
+                       *(pForRlmt) = SK_RLMT_RX_RLMT; \
+               } \
+               else { \
+                       /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
+                       *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
+               } \
+       } \
+}
+
+#ifdef SK_RLMT_FAST_LOOKAHEAD
+Error: SK_RLMT_FAST_LOOKAHEAD no longer used. Use new macros for lookahead.
+#endif /* SK_RLMT_FAST_LOOKAHEAD */
+#ifdef SK_RLMT_SLOW_LOOKAHEAD
+Error: SK_RLMT_SLOW_LOOKAHEAD no longer used. Use new macros for lookahead.
+#endif /* SK_RLMT_SLOW_LOOKAHEAD */
+
+/* typedefs *******************************************************************/
+
+#ifdef SK_RLMT_MBUF_PRIVATE
+typedef struct s_RlmtMbuf {
+       some content
+} SK_RLMT_MBUF;
+#endif /* SK_RLMT_MBUF_PRIVATE */
+
+
+#ifdef SK_LA_INFO
+typedef struct s_Rlmt_PacketInfo {
+       unsigned        PacketLength;                   /* Length of packet. */
+       unsigned        PacketType;                             /* Directed/Multicast/Broadcast. */
+} SK_RLMT_PINFO;
+#endif /* SK_LA_INFO */
+
+
+typedef struct s_RootId {
+       SK_U8           Id[8];                                  /* Root Bridge Id. */
+} SK_RLMT_ROOT_ID;
+
+
+typedef struct s_port {
+       SK_MAC_ADDR     CheckAddr;
+       SK_BOOL         SuspectTx;
+} SK_PORT_CHECK;
+
+
+typedef struct s_RlmtNet SK_RLMT_NET;
+
+
+typedef struct s_RlmtPort {
+
+/* ----- Public part (read-only) ----- */
+
+       SK_U8                   PortState;                              /* Current state of this port. */
+
+       /* For PNMI */
+       SK_BOOL                 LinkDown;
+       SK_BOOL                 PortDown;
+       SK_U8                   Align01;
+
+       SK_U32                  PortNumber;                             /* Number of port on adapter. */
+       SK_RLMT_NET *   Net;                                    /* Net port belongs to. */
+
+       SK_U64                  TxHelloCts;
+       SK_U64                  RxHelloCts;
+       SK_U64                  TxSpHelloReqCts;
+       SK_U64                  RxSpHelloCts;
+
+/* ----- Private part ----- */
+
+/*     SK_U64                  PacketsRx; */                           /* Total packets received. */
+       SK_U32                  PacketsPerTimeSlot;             /* Packets rxed between TOs. */
+/*     SK_U32                  DataPacketsPerTimeSlot; */      /* Data packets ... */
+       SK_U32                  BpduPacketsPerTimeSlot; /* BPDU packets rxed in TS. */
+       SK_U64                  BcTimeStamp;                    /* Time of last BC receive. */
+       SK_U64                  GuTimeStamp;                    /* Time of entering GOING_UP. */
+
+       SK_TIMER                UpTimer;                                /* Timer struct Link/Port up. */
+       SK_TIMER                DownRxTimer;                    /* Timer struct down rx. */
+       SK_TIMER                DownTxTimer;                    /* Timer struct down tx. */
+
+       SK_U32                  CheckingState;                  /* Checking State. */
+
+       SK_ADDR_PORT *  AddrPort;
+
+       SK_U8                   Random[4];                              /* Random value. */
+       unsigned                PortsChecked;                   /* #ports checked. */
+       unsigned                PortsSuspect;                   /* #ports checked that are s. */
+       SK_PORT_CHECK   PortCheck[1];
+/*     SK_PORT_CHECK   PortCheck[SK_MAX_MACS - 1]; */
+
+       SK_BOOL                 PortStarted;                    /* Port is started. */
+       SK_BOOL                 PortNoRx;                               /* NoRx for >= 1 time slot. */
+       SK_BOOL                 RootIdSet;
+       SK_RLMT_ROOT_ID Root;                                   /* Root Bridge Id. */
+} SK_RLMT_PORT;
+
+
+struct s_RlmtNet {
+
+/* ----- Public part (read-only) ----- */
+
+       SK_U32                  NetNumber;                      /* Number of net. */
+
+       SK_RLMT_PORT *  Port[SK_MAX_MACS];      /* Ports that belong to this net. */
+       SK_U32                  NumPorts;                       /* Number of ports. */
+       SK_U32                  PrefPort;                       /* Preferred port. */
+
+       /* For PNMI */
+
+       SK_U32                  ChgBcPrio;                      /* Change Priority of last broadcast received */
+       SK_U32                  RlmtMode;                       /* Check ... */
+       SK_U32                  ActivePort;                     /* Active port. */
+       SK_U32                  Preference;             /* 0xFFFFFFFF: Automatic. */
+
+       SK_U8                   RlmtState;                      /* Current RLMT state. */
+
+/* ----- Private part ----- */
+       SK_BOOL                 RootIdSet;
+       SK_U16                  Align01;
+
+       int                             LinksUp;                        /* #Links up. */
+       int                             PortsUp;                        /* #Ports up. */
+       SK_U32                  TimeoutValue;           /* RLMT timeout value. */
+
+       SK_U32                  CheckingState;          /* Checking State. */
+       SK_RLMT_ROOT_ID Root;                           /* Root Bridge Id. */
+
+       SK_TIMER                LocTimer;                       /* Timer struct. */
+       SK_TIMER                SegTimer;                       /* Timer struct. */
+};
+
+
+typedef struct s_Rlmt {
+
+/* ----- Public part (read-only) ----- */
+
+       SK_U32                  NumNets;                        /* Number of nets. */
+       SK_U32                  NetsStarted;            /* Number of nets started. */
+       SK_RLMT_NET             Net[SK_MAX_NETS];       /* Array of available nets. */
+       SK_RLMT_PORT    Port[SK_MAX_MACS];      /* Array of available ports. */
+
+/* ----- Private part ----- */
+       SK_BOOL                 CheckSwitch;
+       SK_BOOL                 RlmtOff;            /* set to zero if the Mac addresses
+                                          are equal or the second one
+                                          is zero */
+       SK_U16                  Align01;
+
+} SK_RLMT;
+
+
+extern SK_MAC_ADDR     BridgeMcAddr;
+extern SK_MAC_ADDR     SkRlmtMcAddr;
+
+/* function prototypes ********************************************************/
+
+
+#ifndef SK_KR_PROTO
+
+/* Functions provided by SkRlmt */
+
+/* ANSI/C++ compliant function prototypes */
+
+extern void    SkRlmtInit(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Level);
+
+extern int     SkRlmtEvent(
+       SK_AC           *pAC,
+       SK_IOC          IoC,
+       SK_U32          Event,
+       SK_EVPARA       Para);
+
+#else  /* defined(SK_KR_PROTO) */
+
+/* Non-ANSI/C++ compliant function prototypes */
+
+#error KR-style function prototypes are not yet provided.
+
+#endif /* defined(SK_KR_PROTO)) */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __INC_SKRLMT_H */
diff --git a/drivers/net/sk98lin/h/sktimer.h b/drivers/net/sk98lin/h/sktimer.h
new file mode 100644 (file)
index 0000000..36f8ccb
--- /dev/null
@@ -0,0 +1,99 @@
+/******************************************************************************
+ *
+ * Name:       sktimer.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.9 $
+ * Date:       $Date: 1999/11/22 14:00:29 $
+ * Purpose:    Defines for the timer functions
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998,1999 SysKonnect,
+ *     a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: sktimer.h,v $
+ *     Revision 1.9  1999/11/22 14:00:29  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.8  1998/09/08 08:48:02  gklug
+ *     add: init level handling
+ *
+ *     Revision 1.7  1998/08/20 12:31:29  gklug
+ *     fix: SK_TIMCTRL needs to be defined
+ *
+ *     Revision 1.6  1998/08/19 09:51:00  gklug
+ *     fix: remove struct keyword from c-code (see CCC) add typedefs
+ *
+ *     Revision 1.5  1998/08/17 13:43:21  gklug
+ *     chg: Parameter will be union of 64bit para, 2 times SK_U32 or SK_PTR
+ *
+ *     Revision 1.4  1998/08/14 07:09:31  gklug
+ *     fix: chg pAc -> pAC
+ *
+ *     Revision 1.3  1998/08/07 12:54:24  gklug
+ *     fix: first compiled version
+ *
+ *     Revision 1.2  1998/08/07 09:35:29  gklug
+ *     add: Timer control struct for Adapters context
+ *     add: function prototypes
+ *
+ *     Revision 1.1  1998/08/05 11:27:01  gklug
+ *     First version: adapted from SMT
+ *
+ *
+ ******************************************************************************/
+
+/*
+ * SKTIMER.H   contains all defines and types for the timer functions
+ */
+
+#ifndef        _SKTIMER_H_
+#define _SKTIMER_H_
+
+#include "h/skqueue.h"
+
+/*
+ * SK timer
+ * - needed wherever a timer is used. Put this in your data structure
+ *   wherever you want.
+ */
+typedef        struct s_Timer SK_TIMER;
+
+struct s_Timer {
+       SK_TIMER        *TmNext ;       /* linked list */
+       SK_U32          TmClass ;       /* Timer Event class */
+       SK_U32          TmEvent ;       /* Timer Event value */
+       SK_EVPARA       TmPara ;        /* Timer Event parameter */
+       SK_U32          TmDelta ;       /* delta time */
+       int             TmActive ;      /* flag : active/inactive */
+} ;
+
+/*
+ * Timer control struct.
+ * - use in Adapters context name pAC->Tim
+ */
+typedef        struct s_TimCtrl {
+       SK_TIMER        *StQueue ;      /* Head of Timer queue */
+} SK_TIMCTRL ;
+
+extern void SkTimerInit(SK_AC *pAC,SK_IOC Ioc, int Level);
+extern void SkTimerStop(SK_AC *pAC,SK_IOC Ioc,SK_TIMER *pTimer);
+extern void SkTimerStart(SK_AC *pAC,SK_IOC Ioc,SK_TIMER *pTimer,
+       SK_U32 Time,SK_U32 Class,SK_U32 Event,SK_EVPARA Para);
+extern void SkTimerDone(SK_AC *pAC,SK_IOC Ioc);
+#endif /* _SKTIMER_H_ */
diff --git a/drivers/net/sk98lin/h/sktypes.h b/drivers/net/sk98lin/h/sktypes.h
new file mode 100644 (file)
index 0000000..e657016
--- /dev/null
@@ -0,0 +1,87 @@
+/******************************************************************************
+ *
+ * Name:       sktypes.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.3 $
+ * Date:       $Date: 2003/02/25 14:16:40 $
+ * Purpose:    Define data types for Linux
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2003 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+ /*****************************************************************************
+ *
+ * History:
+ *
+ *     $Log: sktypes.h,v $
+ *     Revision 1.3  2003/02/25 14:16:40  mlindner
+ *     Fix: Copyright statement
+ *
+ *     Revision 1.2  1999/11/22 14:01:58  cgoos
+ *     Changed license header to GPL.
+ *     Now using Linux' fixed size types instead of standard types.
+ *
+ *     Revision 1.1  1999/02/16 07:41:40  cgoos
+ *     First version.
+ *
+ *
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * In this file, all data types that are needed by the common modules
+ * are mapped to Linux data types.
+ *
+ *
+ * Include File Hierarchy:
+ *
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKTYPES_H
+#define __INC_SKTYPES_H
+
+
+/* defines *******************************************************************/
+
+/*
+ * Data types with a specific size. 'I' = signed, 'U' = unsigned.
+ */
+#define SK_I8  s8
+#define SK_U8  u8
+#define SK_I16 s16
+#define SK_U16 u16
+#define SK_I32 s32
+#define SK_U32 u32
+#define SK_I64 s64
+#define SK_U64 u64
+
+#define SK_UPTR        ulong           /* casting pointer <-> integral */
+
+/*
+* Boolean type.
+*/
+#define SK_BOOL                SK_U8
+#define SK_FALSE       0
+#define SK_TRUE                (!SK_FALSE)
+
+/* typedefs *******************************************************************/
+
+/* function prototypes ********************************************************/
+
+#endif /* __INC_SKTYPES_H */
diff --git a/drivers/net/sk98lin/h/skversion.h b/drivers/net/sk98lin/h/skversion.h
new file mode 100644 (file)
index 0000000..ef46685
--- /dev/null
@@ -0,0 +1,52 @@
+/******************************************************************************
+ *
+ * Name:       version.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.4 $
+ * Date:       $Date: 2003/02/25 14:16:40 $
+ * Purpose:    SK specific Error log support
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2003 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *     $Log: skversion.h,v $
+ *     Revision 1.4  2003/02/25 14:16:40  mlindner
+ *     Fix: Copyright statement
+ *
+ *     Revision 1.3  2003/02/25 13:30:18  mlindner
+ *     Add: Support for various vendors
+ *
+ *     Revision 1.1.2.1  2001/09/05 13:38:30  mlindner
+ *     Removed FILE description
+ *
+ *     Revision 1.1  2001/03/06 09:25:00  mlindner
+ *     first version
+ *
+ *
+ *
+ ******************************************************************************/
+
+
+static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH.";
+static const char SysKonnectBuildNumber[] =
+       "@(#)SK-BUILD: 6.05 PL: 01";
+
+#define BOOT_STRING    "sk98lin: Network Device Driver v6.05\n" \
+                       "(C)Copyright 1999-2003 Marvell(R)."
+
+#define VER_STRING     "6.05"
diff --git a/drivers/net/sk98lin/h/skvpd.h b/drivers/net/sk98lin/h/skvpd.h
new file mode 100644 (file)
index 0000000..1be34c5
--- /dev/null
@@ -0,0 +1,335 @@
+/******************************************************************************
+ *
+ * Name:       skvpd.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.15 $
+ * Date:       $Date: 2003/01/13 10:39:38 $
+ * Purpose:    Defines and Macros for VPD handling
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2003 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skvpd.h,v $
+ *     Revision 1.15  2003/01/13 10:39:38  rschmidt
+ *     Replaced define for PCI device Id for YUKON with GENESIS
+ *     Editorial changes
+ *
+ *     Revision 1.14  2002/11/14 15:18:10  gheinig
+ *     Added const specifier to key and buf parameters for VpdPara,VpdRead
+ *     and VpdWrite. This is necessary for the Diag 7 GUI API
+ *
+ *     Revision 1.13  2002/10/14 15:58:18  rschmidt
+ *     Added entry in rom_size struct s_vpd
+ *     Editorial changes
+ *
+ *     Revision 1.12  2002/09/09 14:43:51  mkarl
+ *     added PCI Id of Yukon for reading VPD in diag before the adapter has
+ *     been initialized
+ *     editorial changes
+ *
+ *     Revision 1.11  2002/07/26 13:19:16  mkarl
+ *     added support for Yukon
+ *     added vpd_size to VPD struct
+ *
+ *     Revision 1.10  2000/08/10 11:29:07  rassmann
+ *     Editorial changes.
+ *     Preserving 32-bit alignment in structs for the adapter context.
+ *     Removed unused function VpdWriteDword() (#if 0).
+ *     Made VpdReadKeyword() available for SKDIAG only.
+ *
+ *     Revision 1.9  1999/11/22 14:02:27  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.8  1999/03/11 14:26:40  malthoff
+ *     Replace __STDC__ with SK_KR_PROTO.
+ *
+ *     Revision 1.7  1998/10/28 07:27:17  gklug
+ *     rmv: SWAP macros
+ *     add: VPD_IN/OUT8 macros
+ *     chg: interface definition
+ *
+ *     Revision 1.6  1998/10/22 10:03:44  gklug
+ *     fix: use SK_OUT16 instead of SK_OUTW
+ *
+ *     Revision 1.5  1998/10/14 07:05:31  cgoos
+ *     Changed constants in SK_SWAP_32 to UL.
+ *
+ *     Revision 1.4  1998/08/19 08:14:09  gklug
+ *     fix: remove struct keyword as much as possible from the C-code (see CCC)
+ *
+ *     Revision 1.3  1998/08/18 08:18:56  malthoff
+ *     Modify VPD in and out macros for SK_DIAG
+ *
+ *     Revision 1.2  1998/07/03 14:49:08  malthoff
+ *     Add VPD_INxx() and VPD_OUTxx() macros for the Diagnostics tool.
+ *
+ *     Revision 1.1  1998/06/19 14:08:03  malthoff
+ *     Created.
+ *
+ *
+ ******************************************************************************/
+
+/*
+ * skvpd.h     contains Diagnostic specific defines for VPD handling
+ */
+
+#ifndef __INC_SKVPD_H_
+#define __INC_SKVPD_H_
+
+/*
+ * Define Resource Type Identifiers and VPD keywords
+ */
+#define        RES_ID          0x82    /* Resource Type ID String (Product Name) */
+#define RES_VPD_R      0x90    /* start of VPD read only area */
+#define RES_VPD_W      0x91    /* start of VPD read/write area */
+#define RES_END                0x78    /* Resource Type End Tag */
+
+#ifndef VPD_NAME
+#define VPD_NAME       "Name"  /* Product Name, VPD name of RES_ID */
+#endif /* VPD_NAME */
+#define VPD_PN         "PN"    /* Adapter Part Number */
+#define        VPD_EC          "EC"    /* Adapter Engineering Level */
+#define VPD_MN         "MN"    /* Manufacture ID */
+#define VPD_SN         "SN"    /* Serial Number */
+#define VPD_CP         "CP"    /* Extended Capability */
+#define VPD_RV         "RV"    /* Checksum and Reserved */
+#define        VPD_YA          "YA"    /* Asset Tag Identifier */
+#define VPD_VL         "VL"    /* First Error Log Message (SK specific) */
+#define VPD_VF         "VF"    /* Second Error Log Message (SK specific) */
+#define VPD_RW         "RW"    /* Remaining Read / Write Area */
+
+/* 'type' values for vpd_setup_para() */
+#define VPD_RO_KEY     1       /* RO keys are "PN", "EC", "MN", "SN", "RV" */
+#define VPD_RW_KEY     2       /* RW keys are "Yx", "Vx", and "RW" */
+
+/* 'op' values for vpd_setup_para() */
+#define        ADD_KEY         1       /* add the key at the pos "RV" or "RW" */
+#define OWR_KEY                2       /* overwrite key if already exists */
+
+/*
+ * Define READ and WRITE Constants.
+ */
+
+#define VPD_DEV_ID_GENESIS     0x4300
+
+#define        VPD_SIZE_YUKON          256
+#define        VPD_SIZE_GENESIS        512
+#define        VPD_SIZE                        512
+#define VPD_READ       0x0000
+#define VPD_WRITE      0x8000
+
+#define VPD_STOP(pAC,IoC)      VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG,VPD_WRITE)
+
+#define VPD_GET_RES_LEN(p)     ((unsigned int) \
+                                       (* (SK_U8 *)&(p)[1]) |\
+                                       ((* (SK_U8 *)&(p)[2]) << 8))
+#define VPD_GET_VPD_LEN(p)     ((unsigned int)(* (SK_U8 *)&(p)[2]))
+#define VPD_GET_VAL(p)         ((char *)&(p)[3])
+
+#define VPD_MAX_LEN    50
+
+/* VPD status */
+       /* bit 7..1 reserved */
+#define VPD_VALID      (1<<0)  /* VPD data buffer, vpd_free_ro, */
+                                                       /* and vpd_free_rw valid         */
+
+/*
+ * VPD structs
+ */
+typedef        struct s_vpd_status {
+       unsigned short  Align01;                        /* Alignment */
+       unsigned short  vpd_status;                     /* VPD status, description see above */
+       int                             vpd_free_ro;            /* unused bytes in read only area */
+       int                             vpd_free_rw;            /* bytes available in read/write area */
+} SK_VPD_STATUS;
+
+typedef        struct s_vpd {
+       SK_VPD_STATUS   v;                                      /* VPD status structure */
+       char                    vpd_buf[VPD_SIZE];      /* VPD buffer */
+       int                             rom_size;                       /* VPD ROM Size from PCI_OUR_REG_2 */
+       int                             vpd_size;                       /* saved VPD-size */
+} SK_VPD;
+
+typedef        struct s_vpd_para {
+       unsigned int    p_len;  /* parameter length */
+       char                    *p_val; /* points to the value */
+} SK_VPD_PARA;
+
+/*
+ * structure of Large Resource Type Identifiers
+ */
+
+/* was removed because of alignment problems */
+
+/*
+ * structure of VPD keywords
+ */
+typedef        struct s_vpd_key {
+       char                    p_key[2];       /* 2 bytes ID string */
+       unsigned char   p_len;          /* 1 byte length */
+       char                    p_val;          /* start of the value string */
+} SK_VPD_KEY;
+
+
+/*
+ * System specific VPD macros
+ */
+#ifndef SKDIAG
+#ifndef VPD_DO_IO
+#define VPD_OUT8(pAC,IoC,Addr,Val)     (void)SkPciWriteCfgByte(pAC,Addr,Val)
+#define VPD_OUT16(pAC,IoC,Addr,Val)    (void)SkPciWriteCfgWord(pAC,Addr,Val)
+#define VPD_OUT32(pAC,IoC,Addr,Val)    (void)SkPciWriteCfgDWord(pAC,Addr,Val)
+#define VPD_IN8(pAC,IoC,Addr,pVal)     (void)SkPciReadCfgByte(pAC,Addr,pVal)
+#define VPD_IN16(pAC,IoC,Addr,pVal)    (void)SkPciReadCfgWord(pAC,Addr,pVal)
+#define VPD_IN32(pAC,IoC,Addr,pVal)    (void)SkPciReadCfgDWord(pAC,Addr,pVal)
+#else  /* VPD_DO_IO */
+#define VPD_OUT8(pAC,IoC,Addr,Val)     SK_OUT8(IoC,PCI_C(Addr),Val)
+#define VPD_OUT16(pAC,IoC,Addr,Val)    SK_OUT16(IoC,PCI_C(Addr),Val)
+#define VPD_OUT32(pAC,IoC,Addr,Val)    SK_OUT32(IoC,PCI_C(Addr),Val)
+#define VPD_IN8(pAC,IoC,Addr,pVal)     SK_IN8(IoC,PCI_C(Addr),pVal)
+#define VPD_IN16(pAC,IoC,Addr,pVal)    SK_IN16(IoC,PCI_C(Addr),pVal)
+#define VPD_IN32(pAC,IoC,Addr,pVal)    SK_IN32(IoC,PCI_C(Addr),pVal)
+#endif /* VPD_DO_IO */
+#else  /* SKDIAG */
+#define VPD_OUT8(pAC,Ioc,Addr,Val) {                   \
+               if ((pAC)->DgT.DgUseCfgCycle)                   \
+                       SkPciWriteCfgByte(pAC,Addr,Val);        \
+               else                                                                    \
+                       SK_OUT8(pAC,PCI_C(Addr),Val);           \
+               }
+#define VPD_OUT16(pAC,Ioc,Addr,Val) {                  \
+               if ((pAC)->DgT.DgUseCfgCycle)                   \
+                       SkPciWriteCfgWord(pAC,Addr,Val);        \
+               else                                            \
+                       SK_OUT16(pAC,PCI_C(Addr),Val);          \
+               }
+#define VPD_OUT32(pAC,Ioc,Addr,Val) {                  \
+               if ((pAC)->DgT.DgUseCfgCycle)                   \
+                       SkPciWriteCfgDWord(pAC,Addr,Val);       \
+               else                                            \
+                       SK_OUT32(pAC,PCI_C(Addr),Val);          \
+               }
+#define VPD_IN8(pAC,Ioc,Addr,pVal) {                   \
+               if ((pAC)->DgT.DgUseCfgCycle)                   \
+                       SkPciReadCfgByte(pAC,Addr,pVal);        \
+               else                                            \
+                       SK_IN8(pAC,PCI_C(Addr),pVal);           \
+               }
+#define VPD_IN16(pAC,Ioc,Addr,pVal) {                  \
+               if ((pAC)->DgT.DgUseCfgCycle)                   \
+                       SkPciReadCfgWord(pAC,Addr,pVal);        \
+               else                                            \
+                       SK_IN16(pAC,PCI_C(Addr),pVal);          \
+               }
+#define VPD_IN32(pAC,Ioc,Addr,pVal) {                  \
+               if ((pAC)->DgT.DgUseCfgCycle)                   \
+                       SkPciReadCfgDWord(pAC,Addr,pVal);       \
+               else                                            \
+                       SK_IN32(pAC,PCI_C(Addr),pVal);          \
+               }
+#endif /* nSKDIAG */
+
+/* function prototypes ********************************************************/
+
+#ifndef        SK_KR_PROTO
+#ifdef SKDIAG
+extern SK_U32  VpdReadDWord(
+       SK_AC           *pAC,
+       SK_IOC          IoC,
+       int                     addr);
+#endif /* SKDIAG */
+
+extern int     VpdSetupPara(
+       SK_AC           *pAC,
+       const char      *key,
+       const char      *buf,
+       int                     len,
+       int                     type,
+       int                     op);
+
+extern SK_VPD_STATUS   *VpdStat(
+       SK_AC           *pAC,
+       SK_IOC          IoC);
+
+extern int     VpdKeys(
+       SK_AC           *pAC,
+       SK_IOC          IoC,
+       char            *buf,
+       int                     *len,
+       int                     *elements);
+
+extern int     VpdRead(
+       SK_AC           *pAC,
+       SK_IOC          IoC,
+       const char      *key,
+       char            *buf,
+       int                     *len);
+
+extern SK_BOOL VpdMayWrite(
+       char            *key);
+
+extern int     VpdWrite(
+       SK_AC           *pAC,
+       SK_IOC          IoC,
+       const char      *key,
+       const char      *buf);
+
+extern int     VpdDelete(
+       SK_AC           *pAC,
+       SK_IOC          IoC,
+       char            *key);
+
+extern int     VpdUpdate(
+       SK_AC           *pAC,
+       SK_IOC          IoC);
+
+extern void    VpdErrLog(
+       SK_AC           *pAC,
+       SK_IOC          IoC,
+       char            *msg);
+
+#ifdef SKDIAG
+extern int     VpdReadBlock(
+       SK_AC           *pAC,
+       SK_IOC          IoC,
+       char            *buf,
+       int                     addr,
+       int                     len);
+
+extern int     VpdWriteBlock(
+       SK_AC           *pAC,
+       SK_IOC          IoC,
+       char            *buf,
+       int                     addr,
+       int                     len);
+#endif /* SKDIAG */
+#else  /* SK_KR_PROTO */
+extern SK_U32  VpdReadDWord();
+extern int     VpdSetupPara();
+extern SK_VPD_STATUS   *VpdStat();
+extern int     VpdKeys();
+extern int     VpdRead();
+extern SK_BOOL VpdMayWrite();
+extern int     VpdWrite();
+extern int     VpdDelete();
+extern int     VpdUpdate();
+extern void    VpdErrLog();
+#endif /* SK_KR_PROTO */
+
+#endif /* __INC_SKVPD_H_ */
diff --git a/drivers/net/sk98lin/h/xmac_ii.h b/drivers/net/sk98lin/h/xmac_ii.h
new file mode 100644 (file)
index 0000000..2ef903a
--- /dev/null
@@ -0,0 +1,1738 @@
+/******************************************************************************
+ *
+ * Name:       xmac_ii.h
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.46 $
+ * Date:       $Date: 2003/01/28 09:47:45 $
+ * Purpose:    Defines and Macros for Gigabit Ethernet Controller
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2003 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: xmac_ii.h,v $
+ *     Revision 1.46  2003/01/28 09:47:45  rschmidt
+ *     Added defines for copper MDI/MDIX configuration
+ *     Added defines for LED Control Register
+ *     Editorial changes
+ *
+ *     Revision 1.45  2002/12/10 14:35:13  rschmidt
+ *     Corrected defines for Extended PHY Specific Control
+ *     Added defines for Ext. PHY Specific Ctrl 2 Reg. (Fiber specific)
+ *
+ *     Revision 1.44  2002/12/09 14:58:41  rschmidt
+ *     Added defines for Ext. PHY Specific Ctrl Reg. (downshift feature)
+ *     Added 'GMR_FS_UN_SIZE'-Bit to Rx GMAC FIFO Flush Mask
+ *
+ *     Revision 1.43  2002/12/05 10:14:45  rschmidt
+ *     Added define for GMAC's Half Duplex Burst Mode
+ *     Added define for Rx GMAC FIFO Flush Mask (default)
+ *
+ *     Revision 1.42  2002/11/12 16:48:19  rschmidt
+ *     Added defines for Cable Diagnostic Register (GPHY)
+ *     Editorial changes
+ *
+ *     Revision 1.41  2002/10/21 11:20:22  rschmidt
+ *     Added bit GMR_FS_GOOD_FC to GMR_FS_ANY_ERR
+ *     Editorial changes
+ *
+ *     Revision 1.40  2002/10/14 14:54:14  rschmidt
+ *     Added defines for GPHY Specific Status and GPHY Interrupt Status
+ *     Added bits PHY_M_IS_AN_ERROR and PHY_M_IS_FIFO_ERROR to PHY_M_DEF_MSK
+ *     Editorial changes
+ *
+ *     Revision 1.39  2002/10/10 15:53:44  mkarl
+ *     added some bit definitions for link speed status and LED's
+ *
+ *     Revision 1.38  2002/08/21 16:23:46  rschmidt
+ *     Added defines for PHY Specific Ctrl Reg
+ *     Editorial changes
+ *
+ *     Revision 1.37  2002/08/16 14:50:33  rschmidt
+ *     Added defines for Auto-Neg. Advertisement YUKON Fiber (88E1011S only)
+ *     Changed define PHY_M_DEF_MSK for GPHY IRQ Mask
+ *     Editorial changes
+ *
+ *     Revision 1.36  2002/08/12 13:21:10  rschmidt
+ *     Added defines for different Broadcom PHY Ids
+ *
+ *     Revision 1.35  2002/08/08 15:58:01  rschmidt
+ *     Added defines for Manual LED Override register (YUKON)
+ *     Editorial changes
+ *
+ *     Revision 1.34  2002/07/31 17:23:36  rwahl
+ *     Added define GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR).
+ *
+ *     Revision 1.33  2002/07/23 16:03:37  rschmidt
+ *     Added defines for GPHY registers
+ *     Editorial changes
+ *
+ *     Revision 1.32  2002/07/15 18:14:37  rwahl
+ *     Added GMAC MIB counters definitions.
+ *     Editorial changes.
+ *
+ *     Revision 1.31  2002/07/15 15:42:50  rschmidt
+ *     Removed defines from PHY specific reg. which are
+ *     common to all PHYs
+ *     Added defines for GMAC MIB Counters
+ *     Editorial changes
+ *
+ *     Revision 1.30  2002/06/05 08:22:12  rschmidt
+ *     Changed defines for GMAC Rx Control Register and Rx Status
+ *     Editorial changes
+ *
+ *     Revision 1.29  2002/04/25 11:43:56  rschmidt
+ *     Added define PHY_B_AS_PAUSE_MSK for BCom Pause Res.
+ *     Added new registers and defines for YUKON (GMAC, GPHY)
+ *     Added Receive Frame Status Encoding for YUKON
+ *     Editorial changes
+ *
+ *     Revision 1.28  2000/11/09 12:32:49  rassmann
+ *     Renamed variables.
+ *
+ *     Revision 1.27  2000/05/17 11:00:46  malthoff
+ *     Add bit for enable/disable power management in BCOM chip.
+ *
+ *     Revision 1.26  1999/11/22 14:03:00  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.25  1999/08/12 19:19:38  malthoff
+ *     Add PHY_B_AC_TX_TST bit according to BCOM A1 errata sheet.
+ *
+ *     Revision 1.24  1999/07/30 11:27:21  cgoos
+ *     Fixed a missing end-of-comment.
+ *
+ *     Revision 1.23  1999/07/30 07:03:31  malthoff
+ *     Cut some long comments.
+ *     Correct the XMAC PHY ID definitions.
+ *
+ *     Revision 1.22  1999/05/19 07:33:18  cgoos
+ *     Changes for 1000Base-T.
+ *
+ *     Revision 1.21  1999/03/25 07:46:11  malthoff
+ *     Add XM_HW_CFG, XM_TS_READ, and XM_TS_LOAD registers.
+ *
+ *     Revision 1.20  1999/03/12 13:36:09  malthoff
+ *     Remove __STDC__.
+ *
+ *     Revision 1.19  1998/12/10 12:22:54  gklug
+ *     fix: RX_PAGE must be in interrupt mask
+ *
+ *     Revision 1.18  1998/12/10 10:36:36  gklug
+ *     fix: swap of pause bits
+ *
+ *     Revision 1.17  1998/11/18 13:21:45  gklug
+ *     fix: Default interrupt mask
+ *
+ *     Revision 1.16  1998/10/29 15:53:21  gklug
+ *     fix: Default mask uses ASS (GP0) signal
+ *
+ *     Revision 1.15  1998/10/28 13:52:52  malthoff
+ *     Add new bits in RX_CMD register.
+ *
+ *     Revision 1.14  1998/10/19 15:34:53  gklug
+ *     fix: typos
+ *
+ *     Revision 1.13  1998/10/14 07:19:03  malthoff
+ *     bug fix: Every define which describes bit 31
+ *     must be declared as unsigned long 'UL'.
+ *     fix bit definitions of PHY_AN_RFB and PHY_AN_PAUSE.
+ *     Remove ANP defines. Rework the RFB defines.
+ *
+ *     Revision 1.12  1998/10/14 06:22:44  cgoos
+ *     Changed shifted constant to ULONG.
+ *
+ *     Revision 1.11  1998/10/14 05:43:26  gklug
+ *     add: shift pause coding
+ *     fix: PAUSE bits definition
+ *
+ *     Revision 1.10  1998/10/13 09:19:21  malthoff
+ *     Again change XMR_FS_ANY_ERR because of new info from XaQti.
+ *
+ *     Revision 1.9  1998/10/09 07:58:30  malthoff
+ *     Add XMR_FS_FCS_ERR to XMR_FS_ANY_ERR.
+ *
+ *     Revision 1.8  1998/10/09 07:18:17  malthoff
+ *     bug fix of a bug fix: XM_PAUSE_MODE and XM_DEF_MODE
+ *     are not inverted! Bug XM_DEF_MSK is inverted.
+ *
+ *     Revision 1.7  1998/10/05 08:04:32  malthoff
+ *     bug fix: XM_PAUSE_MODE and XM_DEF_MODE
+ *     must be inverted declarations.
+ *
+ *     Revision 1.6  1998/09/28 13:38:18  malthoff
+ *     Add default modes and masks XM_DEF_MSK,
+ *     XM_PAUSE_MODE and XM_DEF_MODE
+ *
+ *     Revision 1.5  1998/09/16 14:42:04  malthoff
+ *     Bug Fix: XM_GP_PORT is a 32 bit (not a 16 bit) register.
+ *
+ *     Revision 1.4  1998/08/20 14:59:47  malthoff
+ *     Rework this file after reading the XaQti data sheet
+ *     "Differences between Rev. B2 & Rev. C XMAC II".
+ *     This file is now 100% XMAC II Rev. C complained.
+ *
+ *     Revision 1.3  1998/06/29 12:18:23  malthoff
+ *     Correct XMR_FS_ANY_ERR definition.
+ *
+ *     Revision 1.2  1998/06/29 12:10:56  malthoff
+ *     Add define XMR_FS_ANY_ERR.
+ *
+ *     Revision 1.1  1998/06/19 13:37:17  malthoff
+ *     created.
+ *
+ *
+ ******************************************************************************/
+
+#ifndef __INC_XMAC_H
+#define __INC_XMAC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* defines ********************************************************************/
+
+/*
+ * XMAC II registers
+ *
+ * The XMAC registers are 16 or 32 bits wide.
+ * The XMACs host processor interface is set to 16 bit mode,
+ * therefore ALL registers will be addressed with 16 bit accesses.
+ *
+ * The following macros are provided to access the XMAC registers
+ * XM_IN16(), XM_OUT16, XM_IN32(), XM_OUT32(), XM_INADR(), XM_OUTADR(),
+ * XM_INHASH(), and XM_OUTHASH().
+ * The macros are defined in SkGeHw.h.
+ *
+ * Note:       NA reg  = Network Address e.g DA, SA etc.
+ *
+ */
+#define XM_MMU_CMD             0x0000  /* 16 bit r/w   MMU Command Register */
+       /* 0x0004:              reserved */
+#define XM_POFF                        0x0008  /* 32 bit r/w   Packet Offset Register */
+#define XM_BURST               0x000c  /* 32 bit r/w   Burst Register for half duplex*/
+#define XM_1L_VLAN_TAG 0x0010  /* 16 bit r/w   One Level VLAN Tag ID */
+#define XM_2L_VLAN_TAG 0x0014  /* 16 bit r/w   Two Level VLAN Tag ID */
+       /* 0x0018 - 0x001e:     reserved */
+#define XM_TX_CMD              0x0020  /* 16 bit r/w   Transmit Command Register */
+#define XM_TX_RT_LIM   0x0024  /* 16 bit r/w   Transmit Retry Limit Register */
+#define XM_TX_STIME            0x0028  /* 16 bit r/w   Transmit Slottime Register */
+#define XM_TX_IPG              0x002c  /* 16 bit r/w   Transmit Inter Packet Gap */
+#define XM_RX_CMD              0x0030  /* 16 bit r/w   Receive Command Register */
+#define XM_PHY_ADDR            0x0034  /* 16 bit r/w   PHY Address Register */
+#define XM_PHY_DATA            0x0038  /* 16 bit r/w   PHY Data Register */
+       /* 0x003c:              reserved */
+#define XM_GP_PORT             0x0040  /* 32 bit r/w   General Purpose Port Register */
+#define XM_IMSK                        0x0044  /* 16 bit r/w   Interrupt Mask Register */
+#define XM_ISRC                        0x0048  /* 16 bit r/o   Interrupt Status Register */
+#define XM_HW_CFG              0x004c  /* 16 bit r/w   Hardware Config Register */
+       /* 0x0050 - 0x005e:     reserved */
+#define XM_TX_LO_WM            0x0060  /* 16 bit r/w   Tx FIFO Low Water Mark */
+#define XM_TX_HI_WM            0x0062  /* 16 bit r/w   Tx FIFO High Water Mark */
+#define XM_TX_THR              0x0064  /* 16 bit r/w   Tx Request Threshold */
+#define XM_HT_THR              0x0066  /* 16 bit r/w   Host Request Threshold */
+#define XM_PAUSE_DA            0x0068  /* NA reg r/w   Pause Destination Address */
+       /* 0x006e:              reserved */
+#define XM_CTL_PARA            0x0070  /* 32 bit r/w   Control Parameter Register */
+#define XM_MAC_OPCODE  0x0074  /* 16 bit r/w   Opcode for MAC control frames */
+#define XM_MAC_PTIME   0x0076  /* 16 bit r/w   Pause time for MAC ctrl frames*/
+#define XM_TX_STAT             0x0078  /* 32 bit r/o   Tx Status LIFO Register */
+
+       /* 0x0080 - 0x00fc:     16 NA reg r/w   Exact Match Address Registers */
+       /*                              use the XM_EXM() macro to address */
+#define XM_EXM_START   0x0080  /* r/w  Start Address of the EXM Regs */
+
+       /*
+        * XM_EXM(Reg)
+        *
+        * returns the XMAC address offset of specified Exact Match Addr Reg
+        *
+        * para:        Reg     EXM register to addr    (0 .. 15)
+        *
+        * usage:       XM_INADDR(IoC, MAC_1, XM_EXM(i), &val[i]);
+        */
+#define XM_EXM(Reg)    (XM_EXM_START + ((Reg) << 3))
+
+#define XM_SRC_CHK             0x0100  /* NA reg r/w   Source Check Address Register */
+#define XM_SA                  0x0108  /* NA reg r/w   Station Address Register */
+#define XM_HSM                 0x0110  /* 64 bit r/w   Hash Match Address Registers */
+#define XM_RX_LO_WM            0x0118  /* 16 bit r/w   Receive Low Water Mark */
+#define XM_RX_HI_WM            0x011a  /* 16 bit r/w   Receive High Water Mark */
+#define XM_RX_THR              0x011c  /* 32 bit r/w   Receive Request Threshold */
+#define XM_DEV_ID              0x0120  /* 32 bit r/o   Device ID Register */
+#define XM_MODE                        0x0124  /* 32 bit r/w   Mode Register */
+#define XM_LSA                 0x0128  /* NA reg r/o   Last Source Register */
+       /* 0x012e:              reserved */
+#define XM_TS_READ             0x0130  /* 32 bit r/o   Time Stamp Read Register */
+#define XM_TS_LOAD             0x0134  /* 32 bit r/o   Time Stamp Load Value */
+       /* 0x0138 - 0x01fe:     reserved */
+#define XM_STAT_CMD    0x0200  /* 16 bit r/w   Statistics Command Register */
+#define XM_RX_CNT_EV   0x0204  /* 32 bit r/o   Rx Counter Event Register */
+#define XM_TX_CNT_EV   0x0208  /* 32 bit r/o   Tx Counter Event Register */
+#define XM_RX_EV_MSK   0x020c  /* 32 bit r/w   Rx Counter Event Mask */
+#define XM_TX_EV_MSK   0x0210  /* 32 bit r/w   Tx Counter Event Mask */
+       /* 0x0204 - 0x027e:     reserved */
+#define XM_TXF_OK              0x0280  /* 32 bit r/o   Frames Transmitted OK Conuter */
+#define XM_TXO_OK_HI   0x0284  /* 32 bit r/o   Octets Transmitted OK High Cnt*/
+#define XM_TXO_OK_LO   0x0288  /* 32 bit r/o   Octets Transmitted OK Low Cnt */
+#define XM_TXF_BC_OK   0x028c  /* 32 bit r/o   Broadcast Frames Xmitted OK */
+#define XM_TXF_MC_OK   0x0290  /* 32 bit r/o   Multicast Frames Xmitted OK */
+#define XM_TXF_UC_OK   0x0294  /* 32 bit r/o   Unicast Frames Xmitted OK */
+#define XM_TXF_LONG            0x0298  /* 32 bit r/o   Tx Long Frame Counter */
+#define XM_TXE_BURST   0x029c  /* 32 bit r/o   Tx Burst Event Counter */
+#define XM_TXF_MPAUSE  0x02a0  /* 32 bit r/o   Tx Pause MAC Ctrl Frame Cnt */
+#define XM_TXF_MCTRL   0x02a4  /* 32 bit r/o   Tx MAC Ctrl Frame Counter */
+#define XM_TXF_SNG_COL 0x02a8  /* 32 bit r/o   Tx Single Collision Counter */
+#define XM_TXF_MUL_COL 0x02ac  /* 32 bit r/o   Tx Multiple Collision Counter */
+#define XM_TXF_ABO_COL 0x02b0  /* 32 bit r/o   Tx aborted due to Exces. Col. */
+#define XM_TXF_LAT_COL 0x02b4  /* 32 bit r/o   Tx Late Collision Counter */
+#define XM_TXF_DEF             0x02b8  /* 32 bit r/o   Tx Deferred Frame Counter */
+#define XM_TXF_EX_DEF  0x02bc  /* 32 bit r/o   Tx Excessive Deferall Counter */
+#define XM_TXE_FIFO_UR 0x02c0  /* 32 bit r/o   Tx FIFO Underrun Event Cnt */
+#define XM_TXE_CS_ERR  0x02c4  /* 32 bit r/o   Tx Carrier Sense Error Cnt */
+#define XM_TXP_UTIL            0x02c8  /* 32 bit r/o   Tx Utilization in % */
+       /* 0x02cc - 0x02ce:     reserved */
+#define XM_TXF_64B             0x02d0  /* 32 bit r/o   64 Byte Tx Frame Counter */
+#define XM_TXF_127B            0x02d4  /* 32 bit r/o   65-127 Byte Tx Frame Counter */
+#define XM_TXF_255B            0x02d8  /* 32 bit r/o   128-255 Byte Tx Frame Counter */
+#define XM_TXF_511B            0x02dc  /* 32 bit r/o   256-511 Byte Tx Frame Counter */
+#define XM_TXF_1023B   0x02e0  /* 32 bit r/o   512-1023 Byte Tx Frame Counter*/
+#define XM_TXF_MAX_SZ  0x02e4  /* 32 bit r/o   1024-MaxSize Byte Tx Frame Cnt*/
+       /* 0x02e8 - 0x02fe:     reserved */
+#define XM_RXF_OK              0x0300  /* 32 bit r/o   Frames Received OK */
+#define XM_RXO_OK_HI   0x0304  /* 32 bit r/o   Octets Received OK High Cnt */
+#define XM_RXO_OK_LO   0x0308  /* 32 bit r/o   Octets Received OK Low Counter*/
+#define XM_RXF_BC_OK   0x030c  /* 32 bit r/o   Broadcast Frames Received OK */
+#define XM_RXF_MC_OK   0x0310  /* 32 bit r/o   Multicast Frames Received OK */
+#define XM_RXF_UC_OK   0x0314  /* 32 bit r/o   Unicast Frames Received OK */
+#define XM_RXF_MPAUSE  0x0318  /* 32 bit r/o   Rx Pause MAC Ctrl Frame Cnt */
+#define XM_RXF_MCTRL   0x031c  /* 32 bit r/o   Rx MAC Ctrl Frame Counter */
+#define XM_RXF_INV_MP  0x0320  /* 32 bit r/o   Rx invalid Pause Frame Cnt */
+#define XM_RXF_INV_MOC 0x0324  /* 32 bit r/o   Rx Frames with inv. MAC Opcode*/
+#define XM_RXE_BURST   0x0328  /* 32 bit r/o   Rx Burst Event Counter */
+#define XM_RXE_FMISS   0x032c  /* 32 bit r/o   Rx Missed Frames Event Cnt */
+#define XM_RXF_FRA_ERR 0x0330  /* 32 bit r/o   Rx Framing Error Counter */
+#define XM_RXE_FIFO_OV 0x0334  /* 32 bit r/o   Rx FIFO overflow Event Cnt */
+#define XM_RXF_JAB_PKT 0x0338  /* 32 bit r/o   Rx Jabber Packet Frame Cnt */
+#define XM_RXE_CAR_ERR 0x033c  /* 32 bit r/o   Rx Carrier Event Error Cnt */
+#define XM_RXF_LEN_ERR 0x0340  /* 32 bit r/o   Rx in Range Length Error */
+#define XM_RXE_SYM_ERR 0x0344  /* 32 bit r/o   Rx Symbol Error Counter */
+#define XM_RXE_SHT_ERR 0x0348  /* 32 bit r/o   Rx Short Event Error Cnt */
+#define XM_RXE_RUNT            0x034c  /* 32 bit r/o   Rx Runt Event Counter */
+#define XM_RXF_LNG_ERR 0x0350  /* 32 bit r/o   Rx Frame too Long Error Cnt */
+#define XM_RXF_FCS_ERR 0x0354  /* 32 bit r/o   Rx Frame Check Seq. Error Cnt */
+       /* 0x0358 - 0x035a:     reserved */
+#define XM_RXF_CEX_ERR 0x035c  /* 32 bit r/o   Rx Carrier Ext Error Frame Cnt*/
+#define XM_RXP_UTIL            0x0360  /* 32 bit r/o   Rx Utilization in % */
+       /* 0x0364 - 0x0366:     reserved */
+#define XM_RXF_64B             0x0368  /* 32 bit r/o   64 Byte Rx Frame Counter */
+#define XM_RXF_127B            0x036c  /* 32 bit r/o   65-127 Byte Rx Frame Counter */
+#define XM_RXF_255B            0x0370  /* 32 bit r/o   128-255 Byte Rx Frame Counter */
+#define XM_RXF_511B            0x0374  /* 32 bit r/o   256-511 Byte Rx Frame Counter */
+#define XM_RXF_1023B   0x0378  /* 32 bit r/o   512-1023 Byte Rx Frame Counter*/
+#define XM_RXF_MAX_SZ  0x037c  /* 32 bit r/o   1024-MaxSize Byte Rx Frame Cnt*/
+       /* 0x02e8 - 0x02fe:     reserved */
+
+
+/*----------------------------------------------------------------------------*/
+/*
+ * XMAC Bit Definitions
+ *
+ * If the bit access behaviour differs from the register access behaviour
+ * (r/w, r/o) this is documented after the bit number.
+ * The following bit access behaviours are used:
+ *     (sc)    self clearing
+ *     (ro)    read only
+ */
+
+/*     XM_MMU_CMD      16 bit r/w      MMU Command Register */
+                                                               /* Bit 15..13:  reserved */
+#define XM_MMU_PHY_RDY (1<<12) /* Bit 12:      PHY Read Ready */
+#define XM_MMU_PHY_BUSY        (1<<11) /* Bit 11:      PHY Busy */
+#define XM_MMU_IGN_PF  (1<<10) /* Bit 10:      Ignore Pause Frame */
+#define XM_MMU_MAC_LB  (1<<9)  /* Bit  9:      Enable MAC Loopback */
+                                                               /* Bit  8:      reserved */
+#define XM_MMU_FRC_COL (1<<7)  /* Bit  7:      Force Collision */
+#define XM_MMU_SIM_COL (1<<6)  /* Bit  6:      Simulate Collision */
+#define XM_MMU_NO_PRE  (1<<5)  /* Bit  5:      No MDIO Preamble */
+#define XM_MMU_GMII_FD (1<<4)  /* Bit  4:      GMII uses Full Duplex */
+#define XM_MMU_RAT_CTRL        (1<<3)  /* Bit  3:      Enable Rate Control */
+#define XM_MMU_GMII_LOOP (1<<2)        /* Bit  2:      PHY is in Loopback Mode */
+#define XM_MMU_ENA_RX  (1<<1)  /* Bit  1:      Enable Receiver */
+#define XM_MMU_ENA_TX  (1<<0)  /* Bit  0:      Enable Transmitter */
+
+
+/*     XM_TX_CMD       16 bit r/w      Transmit Command Register */
+                                                               /* Bit 15..7:   reserved */
+#define XM_TX_BK2BK            (1<<6)  /* Bit  6:      Ignor Carrier Sense (Tx Bk2Bk)*/
+#define XM_TX_ENC_BYP  (1<<5)  /* Bit  5:      Set Encoder in Bypass Mode */
+#define XM_TX_SAM_LINE (1<<4)  /* Bit  4: (sc) Start utilization calculation */
+#define XM_TX_NO_GIG_MD        (1<<3)  /* Bit  3:      Disable Carrier Extension */
+#define XM_TX_NO_PRE   (1<<2)  /* Bit  2:      Disable Preamble Generation */
+#define XM_TX_NO_CRC   (1<<1)  /* Bit  1:      Disable CRC Generation */
+#define XM_TX_AUTO_PAD (1<<0)  /* Bit  0:      Enable Automatic Padding */
+
+
+/*     XM_TX_RT_LIM    16 bit r/w      Transmit Retry Limit Register */
+                                                               /* Bit 15..5:   reserved */
+#define XM_RT_LIM_MSK  0x1f    /* Bit  4..0:   Tx Retry Limit */
+
+
+/*     XM_TX_STIME     16 bit r/w      Transmit Slottime Register */
+                                                               /* Bit 15..7:   reserved */
+#define XM_STIME_MSK   0x7f    /* Bit  6..0:   Tx Slottime bits */
+
+
+/*     XM_TX_IPG       16 bit r/w      Transmit Inter Packet Gap */
+                                                               /* Bit 15..8:   reserved */
+#define XM_IPG_MSK             0xff    /* Bit  7..0:   IPG value bits */
+
+
+/*     XM_RX_CMD       16 bit r/w      Receive Command Register */
+                                                               /* Bit 15..9:   reserved */
+#define XM_RX_LENERR_OK (1<<8) /* Bit  8       don't set Rx Err bit for */
+                                                               /*              inrange error packets */
+#define XM_RX_BIG_PK_OK        (1<<7)  /* Bit  7       don't set Rx Err bit for */
+                                                               /*              jumbo packets */
+#define XM_RX_IPG_CAP  (1<<6)  /* Bit  6       repl. type field with IPG */
+#define XM_RX_TP_MD            (1<<5)  /* Bit  5:      Enable transparent Mode */
+#define XM_RX_STRIP_FCS        (1<<4)  /* Bit  4:      Enable FCS Stripping */
+#define XM_RX_SELF_RX  (1<<3)  /* Bit  3:      Enable Rx of own packets */
+#define XM_RX_SAM_LINE (1<<2)  /* Bit  2: (sc) Start utilization calculation */
+#define XM_RX_STRIP_PAD        (1<<1)  /* Bit  1:      Strip pad bytes of Rx frames */
+#define XM_RX_DIS_CEXT (1<<0)  /* Bit  0:      Disable carrier ext. check */
+
+
+/*     XM_PHY_ADDR     16 bit r/w      PHY Address Register */
+                                                               /* Bit 15..5:   reserved */
+#define XM_PHY_ADDR_SZ 0x1f    /* Bit  4..0:   PHY Address bits */
+
+
+/*     XM_GP_PORT      32 bit r/w      General Purpose Port Register */
+                                                               /* Bit 31..7:   reserved */
+#define XM_GP_ANIP             (1L<<6) /* Bit  6: (ro) Auto-Neg. in progress */
+#define XM_GP_FRC_INT  (1L<<5) /* Bit  5: (sc) Force Interrupt */
+                                                               /* Bit  4:      reserved */
+#define XM_GP_RES_MAC  (1L<<3) /* Bit  3: (sc) Reset MAC and FIFOs */
+#define XM_GP_RES_STAT (1L<<2) /* Bit  2: (sc) Reset the statistics module */
+                                                               /* Bit  1:      reserved */
+#define XM_GP_INP_ASS  (1L<<0) /* Bit  0: (ro) GP Input Pin asserted */
+
+
+/*     XM_IMSK         16 bit r/w      Interrupt Mask Register */
+/*     XM_ISRC         16 bit r/o      Interrupt Status Register */
+                                                               /* Bit 15:      reserved */
+#define XM_IS_LNK_AE   (1<<14) /* Bit 14:      Link Asynchronous Event */
+#define XM_IS_TX_ABORT (1<<13) /* Bit 13:      Transmit Abort, late Col. etc */
+#define XM_IS_FRC_INT  (1<<12) /* Bit 12:      Force INT bit set in GP */
+#define XM_IS_INP_ASS  (1<<11) /* Bit 11:      Input Asserted, GP bit 0 set */
+#define XM_IS_LIPA_RC  (1<<10) /* Bit 10:      Link Partner requests config */
+#define XM_IS_RX_PAGE  (1<<9)  /* Bit  9:      Page Received */
+#define XM_IS_TX_PAGE  (1<<8)  /* Bit  8:      Next Page Loaded for Transmit */
+#define XM_IS_AND              (1<<7)  /* Bit  7:      Auto-Negotiation Done */
+#define XM_IS_TSC_OV   (1<<6)  /* Bit  6:      Time Stamp Counter Overflow */
+#define XM_IS_RXC_OV   (1<<5)  /* Bit  5:      Rx Counter Event Overflow */
+#define XM_IS_TXC_OV   (1<<4)  /* Bit  4:      Tx Counter Event Overflow */
+#define XM_IS_RXF_OV   (1<<3)  /* Bit  3:      Receive FIFO Overflow */
+#define XM_IS_TXF_UR   (1<<2)  /* Bit  2:      Transmit FIFO Underrun */
+#define XM_IS_TX_COMP  (1<<1)  /* Bit  1:      Frame Tx Complete */
+#define XM_IS_RX_COMP  (1<<0)  /* Bit  0:      Frame Rx Complete */
+
+#define XM_DEF_MSK     (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE |\
+                       XM_IS_AND | XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_TXF_UR))
+
+
+/*     XM_HW_CFG       16 bit r/w      Hardware Config Register */
+                                                               /* Bit 15.. 4:  reserved */
+#define XM_HW_GEN_EOP  (1<<3)  /* Bit  3:      generate End of Packet pulse */
+#define XM_HW_COM4SIG  (1<<2)  /* Bit  2:      use Comma Detect for Sig. Det.*/
+                                                               /* Bit  1:      reserved */
+#define XM_HW_GMII_MD  (1<<0)  /* Bit  0:      GMII Interface selected */
+
+
+/*     XM_TX_LO_WM     16 bit r/w      Tx FIFO Low Water Mark */
+/*     XM_TX_HI_WM     16 bit r/w      Tx FIFO High Water Mark */
+                                                               /* Bit 15..10   reserved */
+#define XM_TX_WM_MSK   0x01ff  /* Bit  9.. 0   Tx FIFO Watermark bits */
+
+/*     XM_TX_THR       16 bit r/w      Tx Request Threshold */
+/*     XM_HT_THR       16 bit r/w      Host Request Threshold */
+/*     XM_RX_THR       16 bit r/w      Rx Request Threshold */
+                                                               /* Bit 15..11   reserved */
+#define XM_THR_MSK             0x03ff  /* Bit 10.. 0   Rx/Tx Request Threshold bits */
+
+
+/*     XM_TX_STAT      32 bit r/o      Tx Status LIFO Register */
+#define XM_ST_VALID            (1UL<<31)       /* Bit 31:      Status Valid */
+#define XM_ST_BYTE_CNT (0x3fffL<<17)   /* Bit 30..17:  Tx frame Length */
+#define XM_ST_RETRY_CNT        (0x1fL<<12)     /* Bit 16..12:  Retry Count */
+#define XM_ST_EX_COL   (1L<<11)        /* Bit 11:      Excessive Collisions */
+#define XM_ST_EX_DEF   (1L<<10)        /* Bit 10:      Excessive Deferral */
+#define XM_ST_BURST            (1L<<9)         /* Bit  9:      p. xmitted in burst md*/
+#define XM_ST_DEFER            (1L<<8)         /* Bit  8:      packet was defered */
+#define XM_ST_BC               (1L<<7)         /* Bit  7:      Broadcast packet */
+#define XM_ST_MC               (1L<<6)         /* Bit  6:      Multicast packet */
+#define XM_ST_UC               (1L<<5)         /* Bit  5:      Unicast packet */
+#define XM_ST_TX_UR            (1L<<4)         /* Bit  4:      FIFO Underrun occured */
+#define XM_ST_CS_ERR   (1L<<3)         /* Bit  3:      Carrier Sense Error */
+#define XM_ST_LAT_COL  (1L<<2)         /* Bit  2:      Late Collision Error */
+#define XM_ST_MUL_COL  (1L<<1)         /* Bit  1:      Multiple Collisions */
+#define XM_ST_SGN_COL  (1L<<0)         /* Bit  0:      Single Collision */
+
+/*     XM_RX_LO_WM     16 bit r/w      Receive Low Water Mark */
+/*     XM_RX_HI_WM     16 bit r/w      Receive High Water Mark */
+                                                                       /* Bit 15..11:  reserved */
+#define XM_RX_WM_MSK   0x03ff          /* Bit 11.. 0:  Rx FIFO Watermark bits */
+
+
+/*     XM_DEV_ID       32 bit r/o      Device ID Register */
+#define XM_DEV_OUI     (0x00ffffffUL<<8)       /* Bit 31..8:   Device OUI */
+#define XM_DEV_REV     (0x07L << 5)            /* Bit  7..5:   Chip Rev Num */
+
+
+/*     XM_MODE         32 bit r/w      Mode Register */
+                                                                       /* Bit 31..27:  reserved */
+#define XM_MD_ENA_REJ  (1L<<26)        /* Bit 26:      Enable Frame Reject */
+#define XM_MD_SPOE_E   (1L<<25)        /* Bit 25:      Send Pause on Edge */
+                                                                       /*              extern generated */
+#define XM_MD_TX_REP   (1L<<24)        /* Bit 24:      Transmit Repeater Mode */
+#define XM_MD_SPOFF_I  (1L<<23)        /* Bit 23:      Send Pause on FIFO full */
+                                                                       /*              intern generated */
+#define XM_MD_LE_STW   (1L<<22)        /* Bit 22:      Rx Stat Word in Little Endian */
+#define XM_MD_TX_CONT  (1L<<21)        /* Bit 21:      Send Continuous */
+#define XM_MD_TX_PAUSE (1L<<20)        /* Bit 20: (sc) Send Pause Frame */
+#define XM_MD_ATS              (1L<<19)        /* Bit 19:      Append Time Stamp */
+#define XM_MD_SPOL_I   (1L<<18)        /* Bit 18:      Send Pause on Low */
+                                                                       /*              intern generated */
+#define XM_MD_SPOH_I   (1L<<17)        /* Bit 17:      Send Pause on High */
+                                                                       /*              intern generated */
+#define XM_MD_CAP              (1L<<16)        /* Bit 16:      Check Address Pair */
+#define XM_MD_ENA_HASH (1L<<15)        /* Bit 15:      Enable Hashing */
+#define XM_MD_CSA              (1L<<14)        /* Bit 14:      Check Station Address */
+#define XM_MD_CAA              (1L<<13)        /* Bit 13:      Check Address Array */
+#define XM_MD_RX_MCTRL (1L<<12)        /* Bit 12:      Rx MAC Control Frame */
+#define XM_MD_RX_RUNT  (1L<<11)        /* Bit 11:      Rx Runt Frames */
+#define XM_MD_RX_IRLE  (1L<<10)        /* Bit 10:      Rx in Range Len Err Frame */
+#define XM_MD_RX_LONG  (1L<<9)         /* Bit  9:      Rx Long Frame */
+#define XM_MD_RX_CRCE  (1L<<8)         /* Bit  8:      Rx CRC Error Frame */
+#define XM_MD_RX_ERR   (1L<<7)         /* Bit  7:      Rx Error Frame */
+#define XM_MD_DIS_UC   (1L<<6)         /* Bit  6:      Disable Rx Unicast */
+#define XM_MD_DIS_MC   (1L<<5)         /* Bit  5:      Disable Rx Multicast */
+#define XM_MD_DIS_BC   (1L<<4)         /* Bit  4:      Disable Rx Broadcast */
+#define XM_MD_ENA_PROM (1L<<3)         /* Bit  3:      Enable Promiscuous */
+#define XM_MD_ENA_BE   (1L<<2)         /* Bit  2:      Enable Big Endian */
+#define XM_MD_FTF              (1L<<1)         /* Bit  1: (sc) Flush Tx FIFO */
+#define XM_MD_FRF              (1L<<0)         /* Bit  0: (sc) Flush Rx FIFO */
+
+#define XM_PAUSE_MODE  (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I)
+#define XM_DEF_MODE            (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
+                               XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA)
+
+/*     XM_STAT_CMD     16 bit r/w      Statistics Command Register */
+                                                               /* Bit 16..6:   reserved */
+#define XM_SC_SNP_RXC  (1<<5)  /* Bit  5: (sc) Snap Rx Counters */
+#define XM_SC_SNP_TXC  (1<<4)  /* Bit  4: (sc) Snap Tx Counters */
+#define XM_SC_CP_RXC   (1<<3)  /* Bit  3:      Copy Rx Counters Continuously */
+#define XM_SC_CP_TXC   (1<<2)  /* Bit  2:      Copy Tx Counters Continuously */
+#define XM_SC_CLR_RXC  (1<<1)  /* Bit  1: (sc) Clear Rx Counters */
+#define XM_SC_CLR_TXC  (1<<0)  /* Bit  0: (sc) Clear Tx Counters */
+
+
+/*     XM_RX_CNT_EV    32 bit r/o      Rx Counter Event Register */
+/*     XM_RX_EV_MSK    32 bit r/w      Rx Counter Event Mask */
+#define XMR_MAX_SZ_OV  (1UL<<31)       /* Bit 31:      1024-MaxSize Rx Cnt Ov*/
+#define XMR_1023B_OV   (1L<<30)        /* Bit 30:      512-1023Byte Rx Cnt Ov*/
+#define XMR_511B_OV            (1L<<29)        /* Bit 29:      256-511 Byte Rx Cnt Ov*/
+#define XMR_255B_OV            (1L<<28)        /* Bit 28:      128-255 Byte Rx Cnt Ov*/
+#define XMR_127B_OV            (1L<<27)        /* Bit 27:      65-127 Byte Rx Cnt Ov */
+#define XMR_64B_OV             (1L<<26)        /* Bit 26:      64 Byte Rx Cnt Ov */
+#define XMR_UTIL_OV            (1L<<25)        /* Bit 25:      Rx Util Cnt Overflow */
+#define XMR_UTIL_UR            (1L<<24)        /* Bit 24:      Rx Util Cnt Underrun */
+#define XMR_CEX_ERR_OV (1L<<23)        /* Bit 23:      CEXT Err Cnt Ov */
+                                                                       /* Bit 22:      reserved */
+#define XMR_FCS_ERR_OV (1L<<21)        /* Bit 21:      Rx FCS Error Cnt Ov */
+#define XMR_LNG_ERR_OV (1L<<20)        /* Bit 20:      Rx too Long Err Cnt Ov*/
+#define XMR_RUNT_OV            (1L<<19)        /* Bit 19:      Runt Event Cnt Ov */
+#define XMR_SHT_ERR_OV (1L<<18)        /* Bit 18:      Rx Short Ev Err Cnt Ov*/
+#define XMR_SYM_ERR_OV (1L<<17)        /* Bit 17:      Rx Sym Err Cnt Ov */
+                                                                       /* Bit 16:      reserved */
+#define XMR_CAR_ERR_OV (1L<<15)        /* Bit 15:      Rx Carr Ev Err Cnt Ov */
+#define XMR_JAB_PKT_OV (1L<<14)        /* Bit 14:      Rx Jabb Packet Cnt Ov */
+#define XMR_FIFO_OV            (1L<<13)        /* Bit 13:      Rx FIFO Ov Ev Cnt Ov */
+#define XMR_FRA_ERR_OV (1L<<12)        /* Bit 12:      Rx Framing Err Cnt Ov */
+#define XMR_FMISS_OV   (1L<<11)        /* Bit 11:      Rx Missed Ev Cnt Ov */
+#define XMR_BURST              (1L<<10)        /* Bit 10:      Rx Burst Event Cnt Ov */
+#define XMR_INV_MOC            (1L<<9)         /* Bit  9:      Rx with inv. MAC OC Ov*/
+#define XMR_INV_MP             (1L<<8)         /* Bit  8:      Rx inv Pause Frame Ov */
+#define XMR_MCTRL_OV   (1L<<7)         /* Bit  7:      Rx MAC Ctrl-F Cnt Ov */
+#define XMR_MPAUSE_OV  (1L<<6)         /* Bit  6:      Rx Pause MAC Ctrl-F Ov*/
+#define XMR_UC_OK_OV   (1L<<5)         /* Bit  5:      Rx Unicast Frame CntOv*/
+#define XMR_MC_OK_OV   (1L<<4)         /* Bit  4:      Rx Multicast Cnt Ov */
+#define XMR_BC_OK_OV   (1L<<3)         /* Bit  3:      Rx Broadcast Cnt Ov */
+#define XMR_OK_LO_OV   (1L<<2)         /* Bit  2:      Octets Rx OK Low CntOv*/
+#define XMR_OK_HI_OV   (1L<<1)         /* Bit  1:      Octets Rx OK Hi Cnt Ov*/
+#define XMR_OK_OV              (1L<<0)         /* Bit  0:      Frames Received Ok Ov */
+
+#define XMR_DEF_MSK            (XMR_OK_LO_OV | XMR_OK_HI_OV)
+
+/*     XM_TX_CNT_EV    32 bit r/o      Tx Counter Event Register */
+/*     XM_TX_EV_MSK    32 bit r/w      Tx Counter Event Mask */
+                                                                       /* Bit 31..26:  reserved */
+#define XMT_MAX_SZ_OV  (1L<<25)        /* Bit 25:      1024-MaxSize Tx Cnt Ov*/
+#define XMT_1023B_OV   (1L<<24)        /* Bit 24:      512-1023Byte Tx Cnt Ov*/
+#define XMT_511B_OV            (1L<<23)        /* Bit 23:      256-511 Byte Tx Cnt Ov*/
+#define XMT_255B_OV            (1L<<22)        /* Bit 22:      128-255 Byte Tx Cnt Ov*/
+#define XMT_127B_OV            (1L<<21)        /* Bit 21:      65-127 Byte Tx Cnt Ov */
+#define XMT_64B_OV             (1L<<20)        /* Bit 20:      64 Byte Tx Cnt Ov */
+#define XMT_UTIL_OV            (1L<<19)        /* Bit 19:      Tx Util Cnt Overflow */
+#define XMT_UTIL_UR            (1L<<18)        /* Bit 18:      Tx Util Cnt Underrun */
+#define XMT_CS_ERR_OV  (1L<<17)        /* Bit 17:      Tx Carr Sen Err Cnt Ov*/
+#define XMT_FIFO_UR_OV (1L<<16)        /* Bit 16:      Tx FIFO Ur Ev Cnt Ov */
+#define XMT_EX_DEF_OV  (1L<<15)        /* Bit 15:      Tx Ex Deferall Cnt Ov */
+#define XMT_DEF                        (1L<<14)        /* Bit 14:      Tx Deferred Cnt Ov */
+#define XMT_LAT_COL_OV (1L<<13)        /* Bit 13:      Tx Late Col Cnt Ov */
+#define XMT_ABO_COL_OV (1L<<12)        /* Bit 12:      Tx abo dueto Ex Col Ov*/
+#define XMT_MUL_COL_OV (1L<<11)        /* Bit 11:      Tx Mult Col Cnt Ov */
+#define XMT_SNG_COL            (1L<<10)        /* Bit 10:      Tx Single Col Cnt Ov */
+#define XMT_MCTRL_OV   (1L<<9)         /* Bit  9:      Tx MAC Ctrl Counter Ov*/
+#define XMT_MPAUSE             (1L<<8)         /* Bit  8:      Tx Pause MAC Ctrl-F Ov*/
+#define XMT_BURST              (1L<<7)         /* Bit  7:      Tx Burst Event Cnt Ov */
+#define XMT_LONG               (1L<<6)         /* Bit  6:      Tx Long Frame Cnt Ov */
+#define XMT_UC_OK_OV   (1L<<5)         /* Bit  5:      Tx Unicast Cnt Ov */
+#define XMT_MC_OK_OV   (1L<<4)         /* Bit  4:      Tx Multicast Cnt Ov */
+#define XMT_BC_OK_OV   (1L<<3)         /* Bit  3:      Tx Broadcast Cnt Ov */
+#define XMT_OK_LO_OV   (1L<<2)         /* Bit  2:      Octets Tx OK Low CntOv*/
+#define XMT_OK_HI_OV   (1L<<1)         /* Bit  1:      Octets Tx OK Hi Cnt Ov*/
+#define XMT_OK_OV              (1L<<0)         /* Bit  0:      Frames Tx Ok Ov */
+
+#define XMT_DEF_MSK            (XMT_OK_LO_OV | XMT_OK_HI_OV)
+
+/*
+ * Receive Frame Status Encoding
+ */
+#define XMR_FS_LEN     (0x3fffUL<<18)  /* Bit 31..18:  Rx Frame Length */
+#define XMR_FS_2L_VLAN (1L<<17)        /* Bit 17:      tagged wh 2Lev VLAN ID*/
+#define XMR_FS_1L_VLAN (1L<<16)        /* Bit 16:      tagged wh 1Lev VLAN ID*/
+#define XMR_FS_BC              (1L<<15)        /* Bit 15:      Broadcast Frame */
+#define XMR_FS_MC              (1L<<14)        /* Bit 14:      Multicast Frame */
+#define XMR_FS_UC              (1L<<13)        /* Bit 13:      Unicast Frame */
+                                                                       /* Bit 12:      reserved */
+#define XMR_FS_BURST   (1L<<11)        /* Bit 11:      Burst Mode */
+#define XMR_FS_CEX_ERR (1L<<10)        /* Bit 10:      Carrier Ext. Error */
+#define XMR_FS_802_3   (1L<<9)         /* Bit  9:      802.3 Frame */
+#define XMR_FS_COL_ERR (1L<<8)         /* Bit  8:      Collision Error */
+#define XMR_FS_CAR_ERR (1L<<7)         /* Bit  7:      Carrier Event Error */
+#define XMR_FS_LEN_ERR (1L<<6)         /* Bit  6:      In-Range Length Error */
+#define XMR_FS_FRA_ERR (1L<<5)         /* Bit  5:      Framing Error */
+#define XMR_FS_RUNT            (1L<<4)         /* Bit  4:      Runt Frame */
+#define XMR_FS_LNG_ERR (1L<<3)         /* Bit  3:      Giant (Jumbo) Frame */
+#define XMR_FS_FCS_ERR (1L<<2)         /* Bit  2:      Frame Check Sequ Err */
+#define XMR_FS_ERR             (1L<<1)         /* Bit  1:      Frame Error */
+#define XMR_FS_MCTRL   (1L<<0)         /* Bit  0:      MAC Control Packet */
+
+/*
+ * XMR_FS_ERR will be set if
+ *     XMR_FS_FCS_ERR, XMR_FS_LNG_ERR, XMR_FS_RUNT,
+ *     XMR_FS_FRA_ERR, XMR_FS_LEN_ERR, or XMR_FS_CEX_ERR
+ * is set. XMR_FS_LNG_ERR and XMR_FS_LEN_ERR will issue
+ * XMR_FS_ERR unless the corresponding bit in the Receive Command
+ * Register is set.
+ */
+#define XMR_FS_ANY_ERR XMR_FS_ERR
+
+/*----------------------------------------------------------------------------*/
+/*
+ * XMAC-PHY Registers, indirect addressed over the XMAC
+ */
+#define PHY_XMAC_CTRL          0x00    /* 16 bit r/w   PHY Control Register */
+#define PHY_XMAC_STAT          0x01    /* 16 bit r/w   PHY Status Register */
+#define PHY_XMAC_ID0           0x02    /* 16 bit r/o   PHY ID0 Register */
+#define PHY_XMAC_ID1           0x03    /* 16 bit r/o   PHY ID1 Register */
+#define PHY_XMAC_AUNE_ADV      0x04    /* 16 bit r/w   Auto-Neg. Advertisement */
+#define PHY_XMAC_AUNE_LP       0x05    /* 16 bit r/o   Link Partner Abi Reg */
+#define PHY_XMAC_AUNE_EXP      0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
+#define PHY_XMAC_NEPG          0x07    /* 16 bit r/w   Next Page Register */
+#define PHY_XMAC_NEPG_LP       0x08    /* 16 bit r/o   Next Page Link P Reg */
+       /* 0x09 - 0x0e:         reserved */
+#define PHY_XMAC_EXT_STAT      0x0f    /* 16 bit r/o   Ext Status Register */
+#define PHY_XMAC_RES_ABI       0x10    /* 16 bit r/o   PHY Resolved Ability */
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Broadcom-PHY Registers, indirect addressed over XMAC
+ */
+#define PHY_BCOM_CTRL          0x00    /* 16 bit r/w   PHY Control Register */
+#define PHY_BCOM_STAT          0x01    /* 16 bit r/o   PHY Status Register */
+#define PHY_BCOM_ID0           0x02    /* 16 bit r/o   PHY ID0 Register */
+#define PHY_BCOM_ID1           0x03    /* 16 bit r/o   PHY ID1 Register */
+#define PHY_BCOM_AUNE_ADV      0x04    /* 16 bit r/w   Auto-Neg. Advertisement */
+#define PHY_BCOM_AUNE_LP       0x05    /* 16 bit r/o   Link Part Ability Reg */
+#define PHY_BCOM_AUNE_EXP      0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
+#define PHY_BCOM_NEPG          0x07    /* 16 bit r/w   Next Page Register */
+#define PHY_BCOM_NEPG_LP       0x08    /* 16 bit r/o   Next Page Link P Reg */
+       /* Broadcom-specific registers */
+#define PHY_BCOM_1000T_CTRL    0x09    /* 16 bit r/w   1000Base-T Ctrl Reg */
+#define PHY_BCOM_1000T_STAT    0x0a    /* 16 bit r/o   1000Base-T Status Reg */
+       /* 0x0b - 0x0e:         reserved */
+#define PHY_BCOM_EXT_STAT      0x0f    /* 16 bit r/o   Extended Status Reg */
+#define PHY_BCOM_P_EXT_CTRL    0x10    /* 16 bit r/w   PHY Extended Ctrl Reg */
+#define PHY_BCOM_P_EXT_STAT    0x11    /* 16 bit r/o   PHY Extended Stat Reg */
+#define PHY_BCOM_RE_CTR                0x12    /* 16 bit r/w   Receive Error Counter */
+#define PHY_BCOM_FC_CTR                0x13    /* 16 bit r/w   False Carr Sense Cnt */
+#define PHY_BCOM_RNO_CTR       0x14    /* 16 bit r/w   Receiver NOT_OK Cnt */
+       /* 0x15 - 0x17:         reserved */
+#define PHY_BCOM_AUX_CTRL      0x18    /* 16 bit r/w   Auxiliary Control Reg */
+#define PHY_BCOM_AUX_STAT      0x19    /* 16 bit r/o   Auxiliary Stat Summary */
+#define PHY_BCOM_INT_STAT      0x1a    /* 16 bit r/o   Interrupt Status Reg */
+#define PHY_BCOM_INT_MASK      0x1b    /* 16 bit r/w   Interrupt Mask Reg */
+       /* 0x1c:                reserved */
+       /* 0x1d - 0x1f:         test registers */
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Marvel-PHY Registers, indirect addressed over GMAC
+ */
+#define PHY_MARV_CTRL          0x00    /* 16 bit r/w   PHY Control Register */
+#define PHY_MARV_STAT          0x01    /* 16 bit r/o   PHY Status Register */
+#define PHY_MARV_ID0           0x02    /* 16 bit r/o   PHY ID0 Register */
+#define PHY_MARV_ID1           0x03    /* 16 bit r/o   PHY ID1 Register */
+#define PHY_MARV_AUNE_ADV      0x04    /* 16 bit r/w   Auto-Neg. Advertisement */
+#define PHY_MARV_AUNE_LP       0x05    /* 16 bit r/o   Link Part Ability Reg */
+#define PHY_MARV_AUNE_EXP      0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
+#define PHY_MARV_NEPG          0x07    /* 16 bit r/w   Next Page Register */
+#define PHY_MARV_NEPG_LP       0x08    /* 16 bit r/o   Next Page Link P Reg */
+       /* Marvel-specific registers */
+#define PHY_MARV_1000T_CTRL    0x09    /* 16 bit r/w   1000Base-T Ctrl Reg */
+#define PHY_MARV_1000T_STAT    0x0a    /* 16 bit r/o   1000Base-T Status Reg */
+       /* 0x0b - 0x0e:         reserved */
+#define PHY_MARV_EXT_STAT      0x0f    /* 16 bit r/o   Extended Status Reg */
+#define PHY_MARV_PHY_CTRL      0x10    /* 16 bit r/w   PHY Specific Ctrl Reg */
+#define PHY_MARV_PHY_STAT      0x11    /* 16 bit r/o   PHY Specific Stat Reg */
+#define PHY_MARV_INT_MASK      0x12    /* 16 bit r/w   Interrupt Mask Reg */
+#define PHY_MARV_INT_STAT      0x13    /* 16 bit r/o   Interrupt Status Reg */
+#define PHY_MARV_EXT_CTRL      0x14    /* 16 bit r/w   Ext. PHY Specific Ctrl */
+#define PHY_MARV_RXE_CNT       0x15    /* 16 bit r/w   Receive Error Counter */
+#define PHY_MARV_EXT_ADR       0x16    /* 16 bit r/w   Ext. Ad. for Cable Diag. */
+       /* 0x17:                reserved */
+#define PHY_MARV_LED_CTRL      0x18    /* 16 bit r/w   LED Control Reg */
+#define PHY_MARV_LED_OVER      0x19    /* 16 bit r/w   Manual LED Override Reg */
+#define PHY_MARV_EXT_CTRL_2    0x1a    /* 16 bit r/w   Ext. PHY Specific Ctrl 2 */
+#define PHY_MARV_EXT_P_STAT    0x1b    /* 16 bit r/w   Ext. PHY Spec. Stat Reg */
+#define PHY_MARV_CABLE_DIAG    0x1c    /* 16 bit r/o   Cable Diagnostic Reg */
+       /* 0x1d - 0x1f:         reserved */
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Level One-PHY Registers, indirect addressed over XMAC
+ */
+#define PHY_LONE_CTRL          0x00    /* 16 bit r/w   PHY Control Register */
+#define PHY_LONE_STAT          0x01    /* 16 bit r/o   PHY Status Register */
+#define PHY_LONE_ID0           0x02    /* 16 bit r/o   PHY ID0 Register */
+#define PHY_LONE_ID1           0x03    /* 16 bit r/o   PHY ID1 Register */
+#define PHY_LONE_AUNE_ADV      0x04    /* 16 bit r/w   Auto-Neg. Advertisement */
+#define PHY_LONE_AUNE_LP       0x05    /* 16 bit r/o   Link Part Ability Reg */
+#define PHY_LONE_AUNE_EXP      0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
+#define PHY_LONE_NEPG          0x07    /* 16 bit r/w   Next Page Register */
+#define PHY_LONE_NEPG_LP       0x08    /* 16 bit r/o   Next Page Link Partner*/
+       /* Level One-specific registers */
+#define PHY_LONE_1000T_CTRL    0x09    /* 16 bit r/w   1000Base-T Control Reg*/
+#define PHY_LONE_1000T_STAT    0x0a    /* 16 bit r/o   1000Base-T Status Reg */
+       /* 0x0b -0x0e:          reserved */
+#define PHY_LONE_EXT_STAT      0x0f    /* 16 bit r/o   Extended Status Reg */
+#define PHY_LONE_PORT_CFG      0x10    /* 16 bit r/w   Port Configuration Reg*/
+#define PHY_LONE_Q_STAT                0x11    /* 16 bit r/o   Quick Status Reg */
+#define PHY_LONE_INT_ENAB      0x12    /* 16 bit r/w   Interrupt Enable Reg */
+#define PHY_LONE_INT_STAT      0x13    /* 16 bit r/o   Interrupt Status Reg */
+#define PHY_LONE_LED_CFG       0x14    /* 16 bit r/w   LED Configuration Reg */
+#define PHY_LONE_PORT_CTRL     0x15    /* 16 bit r/w   Port Control Reg */
+#define PHY_LONE_CIM           0x16    /* 16 bit r/o   CIM Reg */
+       /* 0x17 -0x1c:          reserved */
+
+/*----------------------------------------------------------------------------*/
+/*
+ * National-PHY Registers, indirect addressed over XMAC
+ */
+#define PHY_NAT_CTRL           0x00    /* 16 bit r/w   PHY Control Register */
+#define PHY_NAT_STAT           0x01    /* 16 bit r/w   PHY Status Register */
+#define PHY_NAT_ID0                    0x02    /* 16 bit r/o   PHY ID0 Register */
+#define PHY_NAT_ID1                    0x03    /* 16 bit r/o   PHY ID1 Register */
+#define PHY_NAT_AUNE_ADV       0x04    /* 16 bit r/w   Auto-Neg. Advertisement */
+#define PHY_NAT_AUNE_LP                0x05    /* 16 bit r/o   Link Partner Ability Reg */
+#define PHY_NAT_AUNE_EXP       0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
+#define PHY_NAT_NEPG           0x07    /* 16 bit r/w   Next Page Register */
+#define PHY_NAT_NEPG_LP                0x08    /* 16 bit r/o   Next Page Link Partner Reg */
+       /* National-specific registers */
+#define PHY_NAT_1000T_CTRL     0x09    /* 16 bit r/w   1000Base-T Control Reg */
+#define PHY_NAT_1000T_STAT     0x0a    /* 16 bit r/o   1000Base-T Status Reg */
+       /* 0x0b -0x0e:          reserved */
+#define PHY_NAT_EXT_STAT       0x0f    /* 16 bit r/o   Extended Status Register */
+#define PHY_NAT_EXT_CTRL1      0x10    /* 16 bit r/o   Extended Control Reg1 */
+#define PHY_NAT_Q_STAT1                0x11    /* 16 bit r/o   Quick Status Reg1 */
+#define PHY_NAT_10B_OP         0x12    /* 16 bit r/o   10Base-T Operations Reg */
+#define PHY_NAT_EXT_CTRL2      0x13    /* 16 bit r/o   Extended Control Reg1 */
+#define PHY_NAT_Q_STAT2                0x14    /* 16 bit r/o   Quick Status Reg2 */
+       /* 0x15 -0x18:          reserved */
+#define PHY_NAT_PHY_ADDR       0x19    /* 16 bit r/o   PHY Address Register */
+
+
+/*----------------------------------------------------------------------------*/
+
+/*
+ * PHY bit definitions
+ * Bits defined as PHY_X_..., PHY_B_..., PHY_L_... or PHY_N_... are
+ * Xmac/Broadcom/LevelOne/National-specific.
+ * All other are general.
+ */
+
+/*****  PHY_XMAC_CTRL  16 bit r/w      PHY Control Register *****/
+/*****  PHY_BCOM_CTRL  16 bit r/w      PHY Control Register *****/
+/*****  PHY_LONE_CTRL  16 bit r/w      PHY Control Register *****/
+#define PHY_CT_RESET   (1<<15) /* Bit 15: (sc) clear all PHY related regs */
+#define PHY_CT_LOOP            (1<<14) /* Bit 14:      enable Loopback over PHY */
+#define PHY_CT_SPS_LSB (1<<13) /* Bit 13: (BC,L1) Speed select, lower bit */
+#define PHY_CT_ANE             (1<<12) /* Bit 12:      Auto-Negotiation Enabled */
+#define PHY_CT_PDOWN   (1<<11) /* Bit 11: (BC,L1) Power Down Mode */
+#define PHY_CT_ISOL            (1<<10) /* Bit 10: (BC,L1) Isolate Mode */
+#define PHY_CT_RE_CFG  (1<<9)  /* Bit  9: (sc) Restart Auto-Negotiation */
+#define PHY_CT_DUP_MD  (1<<8)  /* Bit  8:      Duplex Mode */
+#define PHY_CT_COL_TST (1<<7)  /* Bit  7: (BC,L1) Collision Test enabled */
+#define PHY_CT_SPS_MSB (1<<6)  /* Bit  6: (BC,L1) Speed select, upper bit */
+                                                               /* Bit  5..0:   reserved */
+
+#define PHY_CT_SP1000  PHY_CT_SPS_MSB  /* enable speed of 1000 Mbps */
+#define PHY_CT_SP100   PHY_CT_SPS_LSB  /* enable speed of  100 Mbps */
+#define PHY_CT_SP10            (0)                             /* enable speed of   10 Mbps */
+
+
+/*****  PHY_XMAC_STAT  16 bit r/w      PHY Status Register *****/
+/*****  PHY_BCOM_STAT  16 bit r/w      PHY Status Register *****/
+/*****  PHY_MARV_STAT  16 bit r/w      PHY Status Register *****/
+/*****  PHY_LONE_STAT  16 bit r/w      PHY Status Register *****/
+                                                               /* Bit 15..9:   reserved */
+                               /*      (BC/L1) 100/10 Mbps cap bits ignored*/
+#define PHY_ST_EXT_ST  (1<<8)  /* Bit  8:      Extended Status Present */
+                                                               /* Bit  7:      reserved */
+#define PHY_ST_PRE_SUP (1<<6)  /* Bit  6: (BC/L1) preamble suppression */
+#define PHY_ST_AN_OVER (1<<5)  /* Bit  5:      Auto-Negotiation Over */
+#define PHY_ST_REM_FLT (1<<4)  /* Bit  4:      Remote Fault Condition Occured */
+#define PHY_ST_AN_CAP  (1<<3)  /* Bit  3:      Auto-Negotiation Capability */
+#define PHY_ST_LSYNC   (1<<2)  /* Bit  2:      Link Synchronized */
+#define PHY_ST_JAB_DET (1<<1)  /* Bit  1: (BC/L1) Jabber Detected */
+#define PHY_ST_EXT_REG (1<<0)  /* Bit  0:      Extended Register available */
+
+
+/***** PHY_XMAC_ID1            16 bit r/o      PHY ID1 Register */
+/***** PHY_BCOM_ID1            16 bit r/o      PHY ID1 Register */
+/***** PHY_MARV_ID1            16 bit r/o      PHY ID1 Register */
+/***** PHY_LONE_ID1            16 bit r/o      PHY ID1 Register */
+#define PHY_I1_OUI_MSK (0x3f<<10)      /* Bit 15..10:  Organization Unique ID */
+#define PHY_I1_MOD_NUM (0x3f<<4)       /* Bit  9.. 4:  Model Number */
+#define PHY_I1_REV_MSK 0x0f            /* Bit  3.. 0:  Revision Number */
+
+/* different Broadcom PHY Ids */
+#define PHY_BCOM_ID1_A1                0x6041
+#define PHY_BCOM_ID1_B2                0x6043
+#define PHY_BCOM_ID1_C0                0x6044
+#define PHY_BCOM_ID1_C5                0x6047
+
+
+/*****  PHY_XMAC_AUNE_ADV      16 bit r/w      Auto-Negotiation Advertisement *****/
+/*****  PHY_XMAC_AUNE_LP       16 bit r/o      Link Partner Ability Reg *****/
+#define PHY_AN_NXT_PG  (1<<15) /* Bit 15:      Request Next Page */
+#define PHY_X_AN_ACK   (1<<14) /* Bit 14: (ro) Acknowledge Received */
+#define PHY_X_AN_RFB   (3<<12) /* Bit 13..12:  Remote Fault Bits */
+                                                               /* Bit 11.. 9:  reserved */
+#define PHY_X_AN_PAUSE (3<<7)  /* Bit  8.. 7:  Pause Bits */
+#define PHY_X_AN_HD            (1<<6)  /* Bit  6:      Half Duplex */
+#define PHY_X_AN_FD            (1<<5)  /* Bit  5:      Full Duplex */
+                                                               /* Bit  4.. 0:  reserved */
+
+/*****  PHY_BCOM_AUNE_ADV      16 bit r/w      Auto-Negotiation Advertisement *****/
+/*****  PHY_BCOM_AUNE_LP       16 bit r/o      Link Partner Ability Reg *****/
+/*     PHY_AN_NXT_PG           (see XMAC) Bit 15:      Request Next Page */
+                                                               /* Bit 14:      reserved */
+#define PHY_B_AN_RF            (1<<13) /* Bit 13:      Remote Fault */
+                                                               /* Bit 12:      reserved */
+#define PHY_B_AN_ASP   (1<<11) /* Bit 11:      Asymmetric Pause */
+#define PHY_B_AN_PC            (1<<10) /* Bit 10:      Pause Capable */
+                                                               /* Bit  9..5:   100/10 BT cap bits ingnored */
+#define PHY_B_AN_SEL   0x1f    /* Bit 4..0:    Selector Field, 00001=Ethernet*/
+
+/*****  PHY_LONE_AUNE_ADV      16 bit r/w      Auto-Negotiation Advertisement *****/
+/*****  PHY_LONE_AUNE_LP       16 bit r/o      Link Partner Ability Reg *****/
+/*     PHY_AN_NXT_PG           (see XMAC) Bit 15:      Request Next Page */
+                                                               /* Bit 14:      reserved */
+#define PHY_L_AN_RF            (1<<13) /* Bit 13:      Remote Fault */
+                                                               /* Bit 12:      reserved */
+#define PHY_L_AN_ASP   (1<<11) /* Bit 11:      Asymmetric Pause */
+#define PHY_L_AN_PC            (1<<10) /* Bit 10:      Pause Capable */
+                                                               /* Bit  9..5:   100/10 BT cap bits ingnored */
+#define PHY_L_AN_SEL   0x1f    /* Bit 4..0:    Selector Field, 00001=Ethernet*/
+
+/*****  PHY_NAT_AUNE_ADV       16 bit r/w      Auto-Negotiation Advertisement *****/
+/*****  PHY_NAT_AUNE_LP                16 bit r/o      Link Partner Ability Reg *****/
+/*     PHY_AN_NXT_PG           (see XMAC) Bit 15:      Request Next Page */
+                                                               /* Bit 14:      reserved */
+#define PHY_N_AN_RF            (1<<13) /* Bit 13:      Remote Fault */
+                                                               /* Bit 12:      reserved */
+#define PHY_N_AN_100F  (1<<11) /* Bit 11:      100Base-T2 FD Support */
+#define PHY_N_AN_100H  (1<<10) /* Bit 10:      100Base-T2 HD Support */
+                                                               /* Bit  9..5:   100/10 BT cap bits ingnored */
+#define PHY_N_AN_SEL   0x1f    /* Bit 4..0:    Selector Field, 00001=Ethernet*/
+
+/* field type definition for PHY_x_AN_SEL */
+#define PHY_SEL_TYPE   0x01    /* 00001 = Ethernet */
+
+/*****  PHY_XMAC_AUNE_EXP      16 bit r/o      Auto-Negotiation Expansion Reg *****/
+                                                               /* Bit 15..4:   reserved */
+#define PHY_AN_LP_NP   (1<<3)  /* Bit  3:      Link Partner can Next Page */
+#define PHY_AN_LOC_NP  (1<<2)  /* Bit  2:      Local PHY can Next Page */
+#define PHY_AN_RX_PG   (1<<1)  /* Bit  1:      Page Received */
+                                                               /* Bit  0:      reserved */
+
+/*****  PHY_BCOM_AUNE_EXP      16 bit r/o      Auto-Negotiation Expansion Reg *****/
+                                                               /* Bit 15..5:   reserved */
+#define PHY_B_AN_PDF   (1<<4)  /* Bit  4:      Parallel Detection Fault */
+/*     PHY_AN_LP_NP            (see XMAC) Bit  3:      Link Partner can Next Page */
+/*     PHY_AN_LOC_NP           (see XMAC) Bit  2:      Local PHY can Next Page */
+/*     PHY_AN_RX_PG            (see XMAC) Bit  1:      Page Received */
+#define PHY_B_AN_LP_CAP        (1<<0)  /* Bit  0:      Link Partner Auto-Neg. Cap. */
+
+/*****  PHY_LONE_AUNE_EXP      16 bit r/o      Auto-Negotiation Expansion Reg *****/
+#define PHY_L_AN_BP            (1<<5)  /* Bit  5:      Base Page Indication */
+#define PHY_L_AN_PDF   (1<<4)  /* Bit  4:      Parallel Detection Fault */
+/*     PHY_AN_LP_NP            (see XMAC) Bit  3:      Link Partner can Next Page */
+/*     PHY_AN_LOC_NP           (see XMAC) Bit  2:      Local PHY can Next Page */
+/*     PHY_AN_RX_PG            (see XMAC) Bit  1:      Page Received */
+#define PHY_B_AN_LP_CAP        (1<<0)  /* Bit  0:      Link Partner Auto-Neg. Cap. */
+
+
+/*****  PHY_XMAC_NEPG          16 bit r/w      Next Page Register *****/
+/*****  PHY_BCOM_NEPG          16 bit r/w      Next Page Register *****/
+/*****  PHY_LONE_NEPG          16 bit r/w      Next Page Register *****/
+/*****  PHY_XMAC_NEPG_LP       16 bit r/o      Next Page Link Partner *****/
+/*****  PHY_BCOM_NEPG_LP       16 bit r/o      Next Page Link Partner *****/
+/*****  PHY_LONE_NEPG_LP       16 bit r/o      Next Page Link Partner *****/
+#define PHY_NP_MORE            (1<<15) /* Bit 15:      More, Next Pages to follow */
+#define PHY_NP_ACK1            (1<<14) /* Bit 14: (ro) Ack 1, for receiving a message*/
+#define PHY_NP_MSG_VAL (1<<13) /* Bit 13:      Message Page valid */
+#define PHY_NP_ACK2            (1<<12) /* Bit 12:      Ack 2, comply with msg content*/
+#define PHY_NP_TOG             (1<<11) /* Bit 11:      Toggle Bit, ensure sync */
+#define PHY_NP_MSG             0x07ff  /* Bit 10..0:   Message from/to Link Partner */
+
+/*
+ * XMAC-Specific
+ */
+/*****  PHY_XMAC_EXT_STAT      16 bit r/w      Extended Status Register *****/
+#define PHY_X_EX_FD            (1<<15) /* Bit 15:      Device Supports Full Duplex */
+#define PHY_X_EX_HD            (1<<14) /* Bit 14:      Device Supports Half Duplex */
+                                                               /* Bit 13..0:   reserved */
+
+/*****  PHY_XMAC_RES_ABI       16 bit r/o      PHY Resolved Ability *****/
+                                                               /* Bit 15..9:   reserved */
+#define PHY_X_RS_PAUSE (3<<7)  /* Bit  8..7:   selected Pause Mode */
+#define PHY_X_RS_HD            (1<<6)  /* Bit  6:      Half Duplex Mode selected */
+#define PHY_X_RS_FD            (1<<5)  /* Bit  5:      Full Duplex Mode selected */
+#define PHY_X_RS_ABLMIS (1<<4) /* Bit  4:      duplex or pause cap mismatch */
+#define PHY_X_RS_PAUMIS (1<<3) /* Bit  3:      pause capability missmatch */
+                                                               /* Bit  2..0:   reserved */
+/*
+ * Remote Fault Bits (PHY_X_AN_RFB) encoding
+ */
+#define X_RFB_OK               (0<<12) /* Bit 13..12   No errors, Link OK */
+#define X_RFB_LF               (1<<12) /* Bit 13..12   Link Failure */
+#define X_RFB_OFF              (2<<12) /* Bit 13..12   Offline */
+#define X_RFB_AN_ERR   (3<<12) /* Bit 13..12   Auto-Negotiation Error */
+
+/*
+ * Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding
+ */
+#define PHY_X_P_NO_PAUSE       (0<<7)  /* Bit  8..7:   no Pause Mode */
+#define PHY_X_P_SYM_MD         (1<<7)  /* Bit  8..7:   symmetric Pause Mode */
+#define PHY_X_P_ASYM_MD                (2<<7)  /* Bit  8..7:   asymmetric Pause Mode */
+#define PHY_X_P_BOTH_MD                (3<<7)  /* Bit  8..7:   both Pause Mode */
+
+
+/*
+ * Broadcom-Specific
+ */
+/*****  PHY_BCOM_1000T_CTRL    16 bit r/w      1000Base-T Control Reg *****/
+#define PHY_B_1000C_TEST       (7<<13) /* Bit 15..13:  Test Modes */
+#define PHY_B_1000C_MSE                (1<<12) /* Bit 12:      Master/Slave Enable */
+#define PHY_B_1000C_MSC                (1<<11) /* Bit 11:      M/S Configuration */
+#define PHY_B_1000C_RD         (1<<10) /* Bit 10:      Repeater/DTE */
+#define PHY_B_1000C_AFD                (1<<9)  /* Bit  9:      Advertise Full Duplex */
+#define PHY_B_1000C_AHD                (1<<8)  /* Bit  8:      Advertise Half Duplex */
+                                                                       /* Bit  7..0:   reserved */
+
+/*****  PHY_BCOM_1000T_STAT    16 bit r/o      1000Base-T Status Reg *****/
+#define PHY_B_1000S_MSF                (1<<15) /* Bit 15:      Master/Slave Fault */
+#define PHY_B_1000S_MSR                (1<<14) /* Bit 14:      Master/Slave Result */
+#define PHY_B_1000S_LRS                (1<<13) /* Bit 13:      Local Receiver Status */
+#define PHY_B_1000S_RRS                (1<<12) /* Bit 12:      Remote Receiver Status */
+#define PHY_B_1000S_LP_FD      (1<<11) /* Bit 11:      Link Partner can FD */
+#define PHY_B_1000S_LP_HD      (1<<10) /* Bit 10:      Link Partner can HD */
+                                                                       /* Bit  9..8:   reserved */
+#define PHY_B_1000S_IEC                0xff    /* Bit  7..0:   Idle Error Count */
+
+/*****  PHY_BCOM_EXT_STAT      16 bit r/o      Extended Status Register *****/
+#define PHY_B_ES_X_FD_CAP      (1<<15) /* Bit 15:      1000Base-X FD capable */
+#define PHY_B_ES_X_HD_CAP      (1<<14) /* Bit 14:      1000Base-X HD capable */
+#define PHY_B_ES_T_FD_CAP      (1<<13) /* Bit 13:      1000Base-T FD capable */
+#define PHY_B_ES_T_HD_CAP      (1<<12) /* Bit 12:      1000Base-T HD capable */
+                                                                       /* Bit 11..0:   reserved */
+
+/*****  PHY_BCOM_P_EXT_CTRL    16 bit r/w      PHY Extended Control Reg *****/
+#define PHY_B_PEC_MAC_PHY      (1<<15) /* Bit 15:      10BIT/GMI-Interface */
+#define PHY_B_PEC_DIS_CROSS    (1<<14) /* Bit 14:      Disable MDI Crossover */
+#define PHY_B_PEC_TX_DIS       (1<<13) /* Bit 13:      Tx output Disabled */
+#define PHY_B_PEC_INT_DIS      (1<<12) /* Bit 12:      Interrupts Disabled */
+#define PHY_B_PEC_F_INT                (1<<11) /* Bit 11:      Force Interrupt */
+#define PHY_B_PEC_BY_45                (1<<10) /* Bit 10:      Bypass 4B5B-Decoder */
+#define PHY_B_PEC_BY_SCR       (1<<9)  /* Bit  9:      Bypass Scrambler */
+#define PHY_B_PEC_BY_MLT3      (1<<8)  /* Bit  8:      Bypass MLT3 Encoder */
+#define PHY_B_PEC_BY_RXA       (1<<7)  /* Bit  7:      Bypass Rx Alignm. */
+#define PHY_B_PEC_RES_SCR      (1<<6)  /* Bit  6:      Reset Scrambler */
+#define PHY_B_PEC_EN_LTR       (1<<5)  /* Bit  5:      Ena LED Traffic Mode */
+#define PHY_B_PEC_LED_ON       (1<<4)  /* Bit  4:      Force LED's on */
+#define PHY_B_PEC_LED_OFF      (1<<3)  /* Bit  3:      Force LED's off */
+#define PHY_B_PEC_EX_IPG       (1<<2)  /* Bit  2:      Extend Tx IPG Mode */
+#define PHY_B_PEC_3_LED                (1<<1)  /* Bit  1:      Three Link LED mode */
+#define PHY_B_PEC_HIGH_LA      (1<<0)  /* Bit  0:      GMII FIFO Elasticy */
+
+/*****  PHY_BCOM_P_EXT_STAT    16 bit r/o      PHY Extended Status Reg *****/
+                                                                       /* Bit 15..14:  reserved */
+#define PHY_B_PES_CROSS_STAT   (1<<13) /* Bit 13:      MDI Crossover Status */
+#define PHY_B_PES_INT_STAT     (1<<12) /* Bit 12:      Interrupt Status */
+#define PHY_B_PES_RRS          (1<<11) /* Bit 11:      Remote Receiver Stat. */
+#define PHY_B_PES_LRS          (1<<10) /* Bit 10:      Local Receiver Stat. */
+#define PHY_B_PES_LOCKED       (1<<9)  /* Bit  9:      Locked */
+#define PHY_B_PES_LS           (1<<8)  /* Bit  8:      Link Status */
+#define PHY_B_PES_RF           (1<<7)  /* Bit  7:      Remote Fault */
+#define PHY_B_PES_CE_ER                (1<<6)  /* Bit  6:      Carrier Ext Error */
+#define PHY_B_PES_BAD_SSD      (1<<5)  /* Bit  5:      Bad SSD */
+#define PHY_B_PES_BAD_ESD      (1<<4)  /* Bit  4:      Bad ESD */
+#define PHY_B_PES_RX_ER                (1<<3)  /* Bit  3:      Receive Error */
+#define PHY_B_PES_TX_ER                (1<<2)  /* Bit  2:      Transmit Error */
+#define PHY_B_PES_LOCK_ER      (1<<1)  /* Bit  1:      Lock Error */
+#define PHY_B_PES_MLT3_ER      (1<<0)  /* Bit  0:      MLT3 code Error */
+
+/*****  PHY_BCOM_FC_CTR                16 bit r/w      False Carrier Counter *****/
+                                                                       /* Bit 15..8:   reserved */
+#define PHY_B_FC_CTR           0xff    /* Bit  7..0:   False Carrier Counter */
+
+/*****  PHY_BCOM_RNO_CTR       16 bit r/w      Receive NOT_OK Counter *****/
+#define PHY_B_RC_LOC_MSK       0xff00  /* Bit 15..8:   Local Rx NOT_OK cnt */
+#define PHY_B_RC_REM_MSK       0x00ff  /* Bit  7..0:   Remote Rx NOT_OK cnt */
+
+/*****  PHY_BCOM_AUX_CTRL      16 bit r/w      Auxiliary Control Reg *****/
+#define PHY_B_AC_L_SQE         (1<<15) /* Bit 15:      Low Squelch */
+#define PHY_B_AC_LONG_PACK     (1<<14) /* Bit 14:      Rx Long Packets */
+#define PHY_B_AC_ER_CTRL       (3<<12) /* Bit 13..12:  Edgerate Control */
+                                                                       /* Bit 11:      reserved */
+#define PHY_B_AC_TX_TST                (1<<10) /* Bit 10:      Tx test bit, always 1 */
+                                                                       /* Bit  9.. 8:  reserved */
+#define PHY_B_AC_DIS_PRF       (1<<7)  /* Bit  7:      dis part resp filter */
+                                                                       /* Bit  6:      reserved */
+#define PHY_B_AC_DIS_PM                (1<<5)  /* Bit  5:      dis power management */
+                                                                       /* Bit  4:      reserved */
+#define PHY_B_AC_DIAG          (1<<3)  /* Bit  3:      Diagnostic Mode */
+                                                                       /* Bit  2.. 0:  reserved */
+
+/*****  PHY_BCOM_AUX_STAT      16 bit r/o      Auxiliary Status Reg *****/
+#define PHY_B_AS_AN_C          (1<<15) /* Bit 15:      AutoNeg complete */
+#define PHY_B_AS_AN_CA         (1<<14) /* Bit 14:      AN Complete Ack */
+#define PHY_B_AS_ANACK_D       (1<<13) /* Bit 13:      AN Ack Detect */
+#define PHY_B_AS_ANAB_D                (1<<12) /* Bit 12:      AN Ability Detect */
+#define PHY_B_AS_NPW           (1<<11) /* Bit 11:      AN Next Page Wait */
+#define PHY_B_AS_AN_RES_MSK    (7<<8)  /* Bit 10..8:   AN HDC */
+#define PHY_B_AS_PDF           (1<<7)  /* Bit  7:      Parallel Detect. Fault */
+#define PHY_B_AS_RF                    (1<<6)  /* Bit  6:      Remote Fault */
+#define PHY_B_AS_ANP_R         (1<<5)  /* Bit  5:      AN Page Received */
+#define PHY_B_AS_LP_ANAB       (1<<4)  /* Bit  4:      LP AN Ability */
+#define PHY_B_AS_LP_NPAB       (1<<3)  /* Bit  3:      LP Next Page Ability */
+#define PHY_B_AS_LS                    (1<<2)  /* Bit  2:      Link Status */
+#define PHY_B_AS_PRR           (1<<1)  /* Bit  1:      Pause Resolution-Rx */
+#define PHY_B_AS_PRT           (1<<0)  /* Bit  0:      Pause Resolution-Tx */
+
+#define PHY_B_AS_PAUSE_MSK     (PHY_B_AS_PRR | PHY_B_AS_PRT)
+
+/*****  PHY_BCOM_INT_STAT      16 bit r/o      Interrupt Status Reg *****/
+/*****  PHY_BCOM_INT_MASK      16 bit r/w      Interrupt Mask Reg *****/
+                                                                       /* Bit 15:      reserved */
+#define PHY_B_IS_PSE           (1<<14) /* Bit 14:      Pair Swap Error */
+#define PHY_B_IS_MDXI_SC       (1<<13) /* Bit 13:      MDIX Status Change */
+#define PHY_B_IS_HCT           (1<<12) /* Bit 12:      counter above 32k */
+#define PHY_B_IS_LCT           (1<<11) /* Bit 11:      counter above 128 */
+#define PHY_B_IS_AN_PR         (1<<10) /* Bit 10:      Page Received */
+#define PHY_B_IS_NO_HDCL       (1<<9)  /* Bit  9:      No HCD Link */
+#define PHY_B_IS_NO_HDC                (1<<8)  /* Bit  8:      No HCD */
+#define PHY_B_IS_NEG_USHDC     (1<<7)  /* Bit  7:      Negotiated Unsup. HCD */
+#define PHY_B_IS_SCR_S_ER      (1<<6)  /* Bit  6:      Scrambler Sync Error */
+#define PHY_B_IS_RRS_CHANGE    (1<<5)  /* Bit  5:      Remote Rx Stat Change */
+#define PHY_B_IS_LRS_CHANGE    (1<<4)  /* Bit  4:      Local Rx Stat Change */
+#define PHY_B_IS_DUP_CHANGE    (1<<3)  /* Bit  3:      Duplex Mode Change */
+#define PHY_B_IS_LSP_CHANGE    (1<<2)  /* Bit  2:      Link Speed Change */
+#define PHY_B_IS_LST_CHANGE    (1<<1)  /* Bit  1:      Link Status Changed */
+#define PHY_B_IS_CRC_ER                (1<<0)  /* Bit  0:      CRC Error */
+
+#define PHY_B_DEF_MSK  (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
+
+/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */
+#define PHY_B_P_NO_PAUSE       (0<<10) /* Bit 11..10:  no Pause Mode */
+#define PHY_B_P_SYM_MD         (1<<10) /* Bit 11..10:  symmetric Pause Mode */
+#define PHY_B_P_ASYM_MD                (2<<10) /* Bit 11..10:  asymmetric Pause Mode */
+#define PHY_B_P_BOTH_MD                (3<<10) /* Bit 11..10:  both Pause Mode */
+
+/*
+ * Resolved Duplex mode and Capabilities (Aux Status Summary Reg)
+ */
+#define PHY_B_RES_1000FD       (7<<8)  /* Bit 10..8:   1000Base-T Full Dup. */
+#define PHY_B_RES_1000HD       (6<<8)  /* Bit 10..8:   1000Base-T Half Dup. */
+/* others: 100/10: invalid for us */
+
+/*
+ * Level One-Specific
+ */
+/*****  PHY_LONE_1000T_CTRL    16 bit r/w      1000Base-T Control Reg *****/
+#define PHY_L_1000C_TEST       (7<<13) /* Bit 15..13:  Test Modes */
+#define PHY_L_1000C_MSE                (1<<12) /* Bit 12:      Master/Slave Enable */
+#define PHY_L_1000C_MSC                (1<<11) /* Bit 11:      M/S Configuration */
+#define PHY_L_1000C_RD         (1<<10) /* Bit 10:      Repeater/DTE */
+#define PHY_L_1000C_AFD                (1<<9)  /* Bit  9:      Advertise Full Duplex */
+#define PHY_L_1000C_AHD                (1<<8)  /* Bit  8:      Advertise Half Duplex */
+                                                                       /* Bit  7..0:   reserved */
+
+/*****  PHY_LONE_1000T_STAT    16 bit r/o      1000Base-T Status Reg *****/
+#define PHY_L_1000S_MSF                (1<<15) /* Bit 15:      Master/Slave Fault */
+#define PHY_L_1000S_MSR                (1<<14) /* Bit 14:      Master/Slave Result */
+#define PHY_L_1000S_LRS                (1<<13) /* Bit 13:      Local Receiver Status */
+#define PHY_L_1000S_RRS                (1<<12) /* Bit 12:      Remote Receiver Status*/
+#define PHY_L_1000S_LP_FD      (1<<11) /* Bit 11:      Link Partner can FD */
+#define PHY_L_1000S_LP_HD      (1<<10) /* Bit 10:      Link Partner can HD */
+                                                                       /* Bit  9..8:   reserved */
+#define PHY_B_1000S_IEC                0xff    /* Bit  7..0:   Idle Error Count */
+
+/*****  PHY_LONE_EXT_STAT      16 bit r/o      Extended Status Register *****/
+#define PHY_L_ES_X_FD_CAP      (1<<15) /* Bit 15:      1000Base-X FD capable */
+#define PHY_L_ES_X_HD_CAP      (1<<14) /* Bit 14:      1000Base-X HD capable */
+#define PHY_L_ES_T_FD_CAP      (1<<13) /* Bit 13:      1000Base-T FD capable */
+#define PHY_L_ES_T_HD_CAP      (1<<12) /* Bit 12:      1000Base-T HD capable */
+                                                                       /* Bit 11..0:   reserved */
+
+/*****  PHY_LONE_PORT_CFG      16 bit r/w      Port Configuration Reg *****/
+#define PHY_L_PC_REP_MODE      (1<<15) /* Bit 15:      Repeater Mode */
+                                                                       /* Bit 14:      reserved */
+#define PHY_L_PC_TX_DIS                (1<<13) /* Bit 13:      Tx output Disabled */
+#define PHY_L_PC_BY_SCR                (1<<12) /* Bit 12:      Bypass Scrambler */
+#define PHY_L_PC_BY_45         (1<<11) /* Bit 11:      Bypass 4B5B-Decoder */
+#define PHY_L_PC_JAB_DIS       (1<<10) /* Bit 10:      Jabber Disabled */
+#define PHY_L_PC_SQE           (1<<9)  /* Bit  9:      Enable Heartbeat */
+#define PHY_L_PC_TP_LOOP       (1<<8)  /* Bit  8:      TP Loopback */
+#define PHY_L_PC_SSS           (1<<7)  /* Bit  7:      Smart Speed Selection */
+#define PHY_L_PC_FIFO_SIZE     (1<<6)  /* Bit  6:      FIFO Size */
+#define PHY_L_PC_PRE_EN                (1<<5)  /* Bit  5:      Preamble Enable */
+#define PHY_L_PC_CIM           (1<<4)  /* Bit  4:      Carrier Integrity Mon */
+#define PHY_L_PC_10_SER                (1<<3)  /* Bit  3:      Use Serial Output */
+#define PHY_L_PC_ANISOL                (1<<2)  /* Bit  2:      Unisolate Port */
+#define PHY_L_PC_TEN_BIT       (1<<1)  /* Bit  1:      10bit iface mode on */
+#define PHY_L_PC_ALTCLOCK      (1<<0)  /* Bit  0: (ro) ALTCLOCK Mode on */
+
+/*****  PHY_LONE_Q_STAT                16 bit r/o      Quick Status Reg *****/
+#define PHY_L_QS_D_RATE                (3<<14) /* Bit 15..14:  Data Rate */
+#define PHY_L_QS_TX_STAT       (1<<13) /* Bit 13:      Transmitting */
+#define PHY_L_QS_RX_STAT       (1<<12) /* Bit 12:      Receiving */
+#define PHY_L_QS_COL_STAT      (1<<11) /* Bit 11:      Collision */
+#define PHY_L_QS_L_STAT                (1<<10) /* Bit 10:      Link is up */
+#define PHY_L_QS_DUP_MOD       (1<<9)  /* Bit  9:      Full/Half Duplex */
+#define PHY_L_QS_AN                    (1<<8)  /* Bit  8:      AutoNeg is On */
+#define PHY_L_QS_AN_C          (1<<7)  /* Bit  7:      AN is Complete */
+#define PHY_L_QS_LLE           (7<<4)  /* Bit  6:      Line Length Estim. */
+#define PHY_L_QS_PAUSE         (1<<3)  /* Bit  3:      LP advertised Pause */
+#define PHY_L_QS_AS_PAUSE      (1<<2)  /* Bit  2:      LP adv. asym. Pause */
+#define PHY_L_QS_ISOLATE       (1<<1)  /* Bit  1:      CIM Isolated */
+#define PHY_L_QS_EVENT         (1<<0)  /* Bit  0:      Event has occurred */
+
+/*****  PHY_LONE_INT_ENAB      16 bit r/w      Interrupt Enable Reg *****/
+/*****  PHY_LONE_INT_STAT      16 bit r/o      Interrupt Status Reg *****/
+                                                                       /* Bit 15..14:  reserved */
+#define PHY_L_IS_AN_F          (1<<13) /* Bit 13:      Auto-Negotiation fault */
+                                                                       /* Bit 12:      not described */
+#define PHY_L_IS_CROSS         (1<<11) /* Bit 11:      Crossover used */
+#define PHY_L_IS_POL           (1<<10) /* Bit 10:      Polarity correct. used*/
+#define PHY_L_IS_SS                    (1<<9)  /* Bit  9:      Smart Speed Downgrade*/
+#define PHY_L_IS_CFULL         (1<<8)  /* Bit  8:      Counter Full */
+#define PHY_L_IS_AN_C          (1<<7)  /* Bit  7:      AutoNeg Complete */
+#define PHY_L_IS_SPEED         (1<<6)  /* Bit  6:      Speed Changed */
+#define PHY_L_IS_DUP           (1<<5)  /* Bit  5:      Duplex Changed */
+#define PHY_L_IS_LS                    (1<<4)  /* Bit  4:      Link Status Changed */
+#define PHY_L_IS_ISOL          (1<<3)  /* Bit  3:      Isolate Occured */
+#define PHY_L_IS_MDINT         (1<<2)  /* Bit  2: (ro) STAT: MII Int Pending */
+#define PHY_L_IS_INTEN         (1<<1)  /* Bit  1:      ENAB: Enable IRQs */
+#define PHY_L_IS_FORCE         (1<<0)  /* Bit  0:      ENAB: Force Interrupt */
+
+/* int. mask */
+#define PHY_L_DEF_MSK          (PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN)
+
+/*****  PHY_LONE_LED_CFG       16 bit r/w      LED Configuration Reg *****/
+#define PHY_L_LC_LEDC          (3<<14) /* Bit 15..14:  Col/Blink/On/Off */
+#define PHY_L_LC_LEDR          (3<<12) /* Bit 13..12:  Rx/Blink/On/Off */
+#define PHY_L_LC_LEDT          (3<<10) /* Bit 11..10:  Tx/Blink/On/Off */
+#define PHY_L_LC_LEDG          (3<<8)  /* Bit  9..8:   Giga/Blink/On/Off */
+#define PHY_L_LC_LEDS          (3<<6)  /* Bit  7..6:   10-100/Blink/On/Off */
+#define PHY_L_LC_LEDL          (3<<4)  /* Bit  5..4:   Link/Blink/On/Off */
+#define PHY_L_LC_LEDF          (3<<2)  /* Bit  3..2:   Duplex/Blink/On/Off */
+#define PHY_L_LC_PSTRECH       (1<<1)  /* Bit  1:      Strech LED Pulses */
+#define PHY_L_LC_FREQ          (1<<0)  /* Bit  0:      30/100 ms */
+
+/*****  PHY_LONE_PORT_CTRL     16 bit r/w      Port Control Reg *****/
+#define PHY_L_PC_TX_TCLK       (1<<15) /* Bit 15:      Enable TX_TCLK */
+                                                                       /* Bit 14:      reserved */
+#define PHY_L_PC_ALT_NP                (1<<13) /* Bit 14:      Alternate Next Page */
+#define PHY_L_PC_GMII_ALT      (1<<12) /* Bit 13:      Alternate GMII driver */
+                                                                       /* Bit 11:      reserved */
+#define PHY_L_PC_TEN_CRS       (1<<10) /* Bit 10:      Extend CRS*/
+                                                                       /* Bit  9..0:   not described */
+
+/*****  PHY_LONE_CIM           16 bit r/o      CIM Reg *****/
+#define PHY_L_CIM_ISOL         (255<<8)/* Bit 15..8:   Isolate Count */
+#define PHY_L_CIM_FALSE_CAR    (255<<0)/* Bit  7..0:   False Carrier Count */
+
+
+/*
+ * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding
+ */
+#define PHY_L_P_NO_PAUSE       (0<<10) /* Bit 11..10:  no Pause Mode */
+#define PHY_L_P_SYM_MD         (1<<10) /* Bit 11..10:  symmetric Pause Mode */
+#define PHY_L_P_ASYM_MD                (2<<10) /* Bit 11..10:  asymmetric Pause Mode */
+#define PHY_L_P_BOTH_MD                (3<<10) /* Bit 11..10:  both Pause Mode */
+
+
+/*
+ * National-Specific
+ */
+/*****  PHY_NAT_1000T_CTRL     16 bit r/w      1000Base-T Control Reg *****/
+#define PHY_N_1000C_TEST       (7<<13) /* Bit 15..13:  Test Modes */
+#define PHY_N_1000C_MSE                (1<<12) /* Bit 12:      Master/Slave Enable */
+#define PHY_N_1000C_MSC                (1<<11) /* Bit 11:      M/S Configuration */
+#define PHY_N_1000C_RD         (1<<10) /* Bit 10:      Repeater/DTE */
+#define PHY_N_1000C_AFD                (1<<9)  /* Bit  9:      Advertise Full Duplex */
+#define PHY_N_1000C_AHD                (1<<8)  /* Bit  8:      Advertise Half Duplex */
+#define PHY_N_1000C_APC                (1<<7)  /* Bit  7:      Asymmetric Pause Cap. */
+                                                                       /* Bit  6..0:   reserved */
+
+/*****  PHY_NAT_1000T_STAT     16 bit r/o      1000Base-T Status Reg *****/
+#define PHY_N_1000S_MSF                (1<<15) /* Bit 15:      Master/Slave Fault */
+#define PHY_N_1000S_MSR                (1<<14) /* Bit 14:      Master/Slave Result */
+#define PHY_N_1000S_LRS                (1<<13) /* Bit 13:      Local Receiver Status */
+#define PHY_N_1000S_RRS                (1<<12) /* Bit 12:      Remote Receiver Status*/
+#define PHY_N_1000S_LP_FD      (1<<11) /* Bit 11:      Link Partner can FD */
+#define PHY_N_1000S_LP_HD      (1<<10) /* Bit 10:      Link Partner can HD */
+#define PHY_N_1000C_LP_APC     (1<<9)  /* Bit  9:      LP Asym. Pause Cap. */
+                                                                       /* Bit  8:      reserved */
+#define PHY_N_1000S_IEC                0xff    /* Bit  7..0:   Idle Error Count */
+
+/*****  PHY_NAT_EXT_STAT       16 bit r/o      Extended Status Register *****/
+#define PHY_N_ES_X_FD_CAP      (1<<15) /* Bit 15:      1000Base-X FD capable */
+#define PHY_N_ES_X_HD_CAP      (1<<14) /* Bit 14:      1000Base-X HD capable */
+#define PHY_N_ES_T_FD_CAP      (1<<13) /* Bit 13:      1000Base-T FD capable */
+#define PHY_N_ES_T_HD_CAP      (1<<12) /* Bit 12:      1000Base-T HD capable */
+                                                                       /* Bit 11..0:   reserved */
+
+/* todo: those are still missing */
+/*****  PHY_NAT_EXT_CTRL1      16 bit r/o      Extended Control Reg1 *****/
+/*****  PHY_NAT_Q_STAT1                16 bit r/o      Quick Status Reg1 *****/
+/*****  PHY_NAT_10B_OP         16 bit r/o      10Base-T Operations Reg *****/
+/*****  PHY_NAT_EXT_CTRL2      16 bit r/o      Extended Control Reg1 *****/
+/*****  PHY_NAT_Q_STAT2                16 bit r/o      Quick Status Reg2 *****/
+/*****  PHY_NAT_PHY_ADDR       16 bit r/o      PHY Address Register *****/
+
+/*
+ * Marvell-Specific
+ */
+/*****  PHY_MARV_AUNE_ADV      16 bit r/w      Auto-Negotiation Advertisement *****/
+/*****  PHY_MARV_AUNE_LP       16 bit r/w      Link Part Ability Reg *****/
+#define PHY_M_AN_NXT_PG                BIT_15  /* Request Next Page */
+#define PHY_M_AN_ACK           BIT_14  /* (ro) Acknowledge Received */
+#define PHY_M_AN_RF                    BIT_13  /* Remote Fault */
+                                                                       /* Bit 12:      reserved */
+#define PHY_M_AN_ASP           BIT_11  /* Asymmetric Pause */
+#define PHY_M_AN_PC                    BIT_10  /* MAC Pause implemented */
+#define PHY_M_AN_100_FD                BIT_8   /* Advertise 100Base-TX Full Duplex */
+#define PHY_M_AN_100_HD                BIT_7   /* Advertise 100Base-TX Half Duplex */
+#define PHY_M_AN_10_FD         BIT_6   /* Advertise 10Base-TX Full Duplex */
+#define PHY_M_AN_10_HD         BIT_5   /* Advertise 10Base-TX Half Duplex */
+
+/* special defines for FIBER (88E1011S only) */
+#define PHY_M_AN_ASP_X         BIT_8   /* Asymmetric Pause */
+#define PHY_M_AN_PC_X          BIT_7   /* MAC Pause implemented */
+#define PHY_M_AN_1000X_AHD     BIT_6   /* Advertise 10000Base-X Half Duplex */
+#define PHY_M_AN_1000X_AFD     BIT_5   /* Advertise 10000Base-X Full Duplex */
+
+/* Pause Bits (PHY_M_AN_ASP_X and PHY_M_AN_PC_X) encoding */
+#define PHY_M_P_NO_PAUSE_X     (0<<7)  /* Bit  8.. 7:  no Pause Mode */
+#define PHY_M_P_SYM_MD_X       (1<<7)  /* Bit  8.. 7:  symmetric Pause Mode */
+#define PHY_M_P_ASYM_MD_X      (2<<7)  /* Bit  8.. 7:  asymmetric Pause Mode */
+#define PHY_M_P_BOTH_MD_X      (3<<7)  /* Bit  8.. 7:  both Pause Mode */
+
+/*****  PHY_MARV_1000T_CTRL    16 bit r/w      1000Base-T Control Reg *****/
+#define PHY_M_1000C_TEST       (7<<13) /* Bit 15..13:  Test Modes */
+#define PHY_M_1000C_MSE                (1<<12) /* Bit 12:      Manual Master/Slave Enable */
+#define PHY_M_1000C_MSC                (1<<11) /* Bit 11:      M/S Configuration (1=Master) */
+#define PHY_M_1000C_MPD                (1<<10) /* Bit 10:      Multi-Port Device */
+#define PHY_M_1000C_AFD                (1<<9)  /* Bit  9:      Advertise Full Duplex */
+#define PHY_M_1000C_AHD                (1<<8)  /* Bit  8:      Advertise Half Duplex */
+                                                                       /* Bit  7..0:   reserved */
+
+/*****  PHY_MARV_PHY_CTRL      16 bit r/w      PHY Specific Ctrl Reg *****/
+
+#define PHY_M_PC_TX_FFD_MSK    (3<<14) /* Bit 15..14:  Tx FIFO Depth Mask */
+#define PHY_M_PC_RX_FFD_MSK    (3<<12) /* Bit 13..12:  Rx FIFO Depth Mask */
+#define PHY_M_PC_ASS_CRS_TX    (1<<11) /* Bit 11:      Assert CRS on Transmit */
+#define PHY_M_PC_FL_GOOD       (1<<10) /* Bit 10:      Force Link Good */
+#define PHY_M_PC_EN_DET_MSK    (3<<8)  /* Bit  9.. 8:  Energy Detect Mask */
+#define PHY_M_PC_ENA_EXT_D     (1<<7)  /* Bit  7:      Enable Ext. Distance (10BT) */
+#define PHY_M_PC_MDIX_MSK      (3<<5)  /* Bit  6.. 5:  MDI/MDIX Config. Mask */
+#define PHY_M_PC_DIS_125CLK    (1<<4)  /* Bit  4:      Disable 125 CLK */
+#define PHY_M_PC_MAC_POW_UP    (1<<3)  /* Bit  3:      MAC Power up */
+#define PHY_M_PC_SQE_T_ENA     (1<<2)  /* Bit  2:      SQE Test Enabled */
+#define PHY_M_PC_POL_R_DIS     (1<<1)  /* Bit  1:      Polarity Reversal Disabled */
+#define PHY_M_PC_DIS_JABBER    (1<<0)  /* Bit  0:      Disable Jabber */
+
+#define PHY_M_PC_MDI_XMODE(x)  SHIFT5(x)
+#define PHY_M_PC_MAN_MDI       0       /* 00 = Manual MDI configuration */
+#define PHY_M_PC_MAN_MDIX      1               /* 01 = Manual MDIX configuration */
+#define PHY_M_PC_ENA_AUTO      3               /* 11 = Enable Automatic Crossover */
+
+/*****  PHY_MARV_PHY_STAT      16 bit r/o      PHY Specific Status Reg *****/
+#define PHY_M_PS_SPEED_MSK     (3<<14) /* Bit 15..14:  Speed Mask */
+#define PHY_M_PS_SPEED_1000    (1<<15) /*       10 = 1000 Mbps */
+#define PHY_M_PS_SPEED_100     (1<<14) /*       01 =  100 Mbps */
+#define PHY_M_PS_SPEED_10      0               /*       00 =   10 Mbps */
+#define PHY_M_PS_FULL_DUP      (1<<13) /* Bit 13:      Full Duplex */
+#define PHY_M_PS_PAGE_REC      (1<<12) /* Bit 12:      Page Received */
+#define PHY_M_PS_SPDUP_RES     (1<<11) /* Bit 11:      Speed & Duplex Resolved */
+#define PHY_M_PS_LINK_UP       (1<<10) /* Bit 10:      Link Up */
+#define PHY_M_PS_CABLE_MSK     (3<<7)  /* Bit  9.. 7:  Cable Length Mask */
+#define PHY_M_PS_MDI_X_STAT    (1<<6)  /* Bit  6:      MDI Crossover Stat (1=MDIX) */
+#define PHY_M_PS_DOWNS_STAT    (1<<5)  /* Bit  5:      Downshift Status (1=downsh.) */
+#define PHY_M_PS_ENDET_STAT    (1<<4)  /* Bit  4:      Energy Detect Status (1=act) */
+#define PHY_M_PS_TX_P_EN       (1<<3)  /* Bit  3:      Tx Pause Enabled */
+#define PHY_M_PS_RX_P_EN       (1<<2)  /* Bit  2:      Rx Pause Enabled */
+#define PHY_M_PS_POL_REV       (1<<1)  /* Bit  1:      Polarity Reversed */
+#define PHY_M_PC_JABBER                (1<<0)  /* Bit  0:      Jabber */
+
+#define PHY_M_PS_PAUSE_MSK     (PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN)
+
+/*****  PHY_MARV_INT_MASK      16 bit r/w      Interrupt Mask Reg *****/
+/*****  PHY_MARV_INT_STAT      16 bit r/o      Interrupt Status Reg *****/
+#define PHY_M_IS_AN_ERROR      (1<<15) /* Bit 15:      Auto-Negotiation Error */
+#define PHY_M_IS_LSP_CHANGE    (1<<14) /* Bit 14:      Link Speed Changed */
+#define PHY_M_IS_DUP_CHANGE    (1<<13) /* Bit 13:      Duplex Mode Changed */
+#define PHY_M_IS_AN_PR         (1<<12) /* Bit 12:      Page Received */
+#define PHY_M_IS_AN_COMPL      (1<<11) /* Bit 11:      Auto-Negotiation Completed */
+#define PHY_M_IS_LST_CHANGE    (1<<10) /* Bit 10:      Link Status Changed */
+#define PHY_M_IS_SYMB_ERROR    (1<<9)  /* Bit  9:      Symbol Error */
+#define PHY_M_IS_FALSE_CARR    (1<<8)  /* Bit  8:      False Carrier */
+#define PHY_M_IS_FIFO_ERROR    (1<<7)  /* Bit  7:      FIFO Overflow/Underrun Error */
+#define PHY_M_IS_MDI_CHANGE    (1<<6)  /* Bit  6:      MDI Crossover Changed */
+#define PHY_M_IS_DOWNSH_DET    (1<<5)  /* Bit  5:      Downshift Detected */
+#define PHY_M_IS_END_CHANGE    (1<<4)  /* Bit  4:      Energy Detect Changed */
+                                                                       /* Bit  3..2:   reserved */
+#define PHY_M_IS_POL_CHANGE    (1<<1)  /* Bit  1:      Polarity Changed */
+#define PHY_M_IS_JABBER                (1<<0)  /* Bit  0:      Jabber */
+
+#define PHY_M_DEF_MSK          (PHY_M_IS_AN_ERROR | PHY_M_IS_AN_PR | \
+                                                       PHY_M_IS_LST_CHANGE | PHY_M_IS_FIFO_ERROR)
+
+/*****  PHY_MARV_EXT_CTRL      16 bit r/w      Ext. PHY Specific Ctrl *****/
+#define PHY_M_EC_M_DSC_MSK     (3<<10) /* Bit 11..10:  Master downshift counter */
+#define PHY_M_EC_S_DSC_MSK     (3<<8)  /* Bit  9.. 8:  Slave  downshift counter */
+#define PHY_M_EC_MAC_S_MSK     (7<<4)  /* Bit  6.. 4:  Def. MAC interface speed */
+
+#define PHY_M_EC_M_DSC(x)              SHIFT10(x)      /* 00=1x; 01=2x; 10=3x; 11=4x */
+#define PHY_M_EC_S_DSC(x)              SHIFT8(x)       /* 00=dis; 01=1x; 10=2x; 11=3x */
+#define PHY_M_EC_MAC_S(x)              SHIFT4(x)       /* 01X=0; 110=2.5; 111=25 (MHz) */
+
+#define MAC_TX_CLK_0_MHZ       2
+#define MAC_TX_CLK_2_5_MHZ     6
+#define MAC_TX_CLK_25_MHZ      7
+
+/*****  PHY_MARV_LED_CTRL      16 bit r/w      LED Control Reg *****/
+#define PHY_M_LEDC_DIS_LED     (1<<15) /* Bit 15:      Disable LED */
+#define PHY_M_LEDC_PULS_MSK    (7<<12) /* Bit 14..12:  Pulse Stretch Mask */
+#define PHY_M_LEDC_F_INT       (1<<11) /* Bit 11:      Force Interrupt */
+#define PHY_M_LEDC_BL_R_MSK    (7<<8)  /* Bit 10.. 8:  Blink Rate Mask */
+                                                                       /* Bit  7.. 5:  reserved */
+#define PHY_M_LEDC_LINK_MSK    (3<<3)  /* Bit  4.. 3:  Link Control Mask */
+#define PHY_M_LEDC_DP_CTRL     (1<<2)  /* Bit  2:      Duplex Control */
+#define PHY_M_LEDC_RX_CTRL     (1<<1)  /* Bit  1:      Rx activity / Link */
+#define PHY_M_LEDC_TX_CTRL     (1<<0)  /* Bit  0:      Tx activity / Link */
+
+#define PHY_M_LED_PULS_DUR(x)  SHIFT12(x)      /* Pulse Stretch Duration */
+
+#define        PULS_NO_STR             0               /* no pulse stretching */
+#define        PULS_21MS               1               /* 21 ms to 42 ms */
+#define PULS_42MS              2               /* 42 ms to 84 ms */
+#define PULS_84MS              3               /* 84 ms to 170 ms */
+#define PULS_170MS             4               /* 170 ms to 340 ms */
+#define PULS_340MS             5               /* 340 ms to 670 ms */
+#define PULS_670MS             6               /* 670 ms to 1.3 s */
+#define PULS_1300MS            7               /* 1.3 s to 2.7 s */
+
+#define PHY_M_LED_BLINK_RT(x)  SHIFT8(x)       /* Blink Rate */
+
+#define BLINK_42MS             0               /* 42 ms */
+#define BLINK_84MS             1               /* 84 ms */
+#define BLINK_170MS            2               /* 170 ms */
+#define BLINK_340MS            3               /* 340 ms */
+#define BLINK_670MS            4               /* 670 ms */
+                                                               /* values 5 - 7: reserved */
+
+/*****  PHY_MARV_LED_OVER      16 bit r/w      Manual LED Override Reg *****/
+#define PHY_M_LED_MO_DUP(x)            SHIFT10(x)      /* Bit 11..10:  Duplex */
+#define PHY_M_LED_MO_10(x)             SHIFT8(x)       /* Bit  9.. 8:  Link 10 */
+#define PHY_M_LED_MO_100(x)            SHIFT6(x)       /* Bit  7.. 6:  Link 100 */
+#define PHY_M_LED_MO_1000(x)   SHIFT4(x)       /* Bit  5.. 4:  Link 1000 */
+#define PHY_M_LED_MO_RX(x)             SHIFT2(x)       /* Bit  3.. 2:  Rx */
+#define PHY_M_LED_MO_TX(x)             SHIFT0(x)       /* Bit  1.. 0:  Tx */
+
+#define MO_LED_NORM                    0
+#define MO_LED_BLINK           1
+#define MO_LED_OFF                     2
+#define MO_LED_ON                      3
+
+/*****  PHY_MARV_EXT_CTRL_2    16 bit r/w      Ext. PHY Specific Ctrl 2 *****/
+                                                                       /* Bit 15.. 7:  reserved */
+#define PHY_M_EC2_FI_IMPED     (1<<6)  /* Bit  6:      Fiber Input  Impedance */
+#define PHY_M_EC2_FO_IMPED     (1<<5)  /* Bit  5:      Fiber Output Impedance */
+#define PHY_M_EC2_FO_M_CLK     (1<<4)  /* Bit  4:      Fiber Mode Clock Enable */
+#define PHY_M_EC2_FO_BOOST     (1<<3)  /* Bit  3:      Fiber Output Boost */
+#define PHY_M_EC2_FO_AM_MSK    7               /* Bit  2.. 0:  Fiber Output Amplitude */
+
+/*****  PHY_MARV_CABLE_DIAG    16 bit r/o      Cable Diagnostic Reg *****/
+#define PHY_M_CABD_ENA_TEST    (1<<15) /* Bit 15:      Enable Test */
+#define PHY_M_CABD_STAT_MSK    (3<<13) /* Bit 14..13:  Status */
+                                                                       /* Bit 12.. 8:  reserved */
+#define PHY_M_CABD_DIST_MSK    0xff    /* Bit  7.. 0:  Distance */
+
+/* values for Cable Diagnostic Status (11=fail; 00=OK; 10=open; 01=short) */
+#define CABD_STAT_NORMAL       0
+#define CABD_STAT_SHORT                1
+#define CABD_STAT_OPEN         2
+#define CABD_STAT_FAIL         3
+
+
+/*
+ * GMAC registers
+ *
+ * The GMAC registers are 16 or 32 bits wide.
+ * The GMACs host processor interface is 16 bits wide,
+ * therefore ALL registers will be addressed with 16 bit accesses.
+ *
+ * The following macros are provided to access the GMAC registers
+ * GM_IN16(), GM_OUT16, GM_IN32(), GM_OUT32(), GM_INADR(), GM_OUTADR(),
+ * GM_INHASH(), and GM_OUTHASH().
+ * The macros are defined in SkGeHw.h.
+ *
+ * Note:       NA reg  = Network Address e.g DA, SA etc.
+ *
+ */
+
+/* Port Registers */
+#define GM_GP_STAT             0x0000          /* 16 bit r/o   General Purpose Status */
+#define GM_GP_CTRL             0x0004          /* 16 bit r/w   General Purpose Control */
+#define GM_TX_CTRL             0x0008          /* 16 bit r/w   Transmit Control Reg. */
+#define GM_RX_CTRL             0x000c          /* 16 bit r/w   Receive Control Reg. */
+#define GM_TX_FLOW_CTRL        0x0010          /* 16 bit r/w   Transmit Flow Control */
+#define GM_TX_PARAM            0x0014          /* 16 bit r/w   Transmit Parameter Reg. */
+#define GM_SERIAL_MODE 0x0018          /* 16 bit r/w   Serial Mode Register */
+
+/* Source Address Registers */
+#define GM_SRC_ADDR_1L 0x001c          /* 16 bit r/w   Source Address 1 (low) */
+#define GM_SRC_ADDR_1M 0x0020          /* 16 bit r/w   Source Address 1 (middle) */
+#define GM_SRC_ADDR_1H 0x0024          /* 16 bit r/w   Source Address 1 (high) */
+#define GM_SRC_ADDR_2L 0x0028          /* 16 bit r/w   Source Address 2 (low) */
+#define GM_SRC_ADDR_2M 0x002c          /* 16 bit r/w   Source Address 2 (middle) */
+#define GM_SRC_ADDR_2H 0x0030          /* 16 bit r/w   Source Address 2 (high) */
+
+/* Multicast Address Hash Registers */
+#define GM_MC_ADDR_H1  0x0034          /* 16 bit r/w   Multicast Address Hash 1 */
+#define GM_MC_ADDR_H2  0x0038          /* 16 bit r/w   Multicast Address Hash 2 */
+#define GM_MC_ADDR_H3  0x003c          /* 16 bit r/w   Multicast Address Hash 3 */
+#define GM_MC_ADDR_H4  0x0040          /* 16 bit r/w   Multicast Address Hash 4 */
+
+/* Interrupt Source Registers */
+#define GM_TX_IRQ_SRC  0x0044          /* 16 bit r/o   Tx Overflow IRQ Source */
+#define GM_RX_IRQ_SRC  0x0048          /* 16 bit r/o   Rx Overflow IRQ Source */
+#define GM_TR_IRQ_SRC  0x004c          /* 16 bit r/o   Tx/Rx Over. IRQ Source */
+
+/* Interrupt Mask Registers */
+#define GM_TX_IRQ_MSK  0x0050          /* 16 bit r/w   Tx Overflow IRQ Mask */
+#define GM_RX_IRQ_MSK  0x0054          /* 16 bit r/w   Rx Overflow IRQ Mask */
+#define GM_TR_IRQ_MSK  0x0058          /* 16 bit r/w   Tx/Rx Over. IRQ Mask */
+
+/* Serial Management Interface (SMI) Registers */
+#define GM_SMI_CTRL            0x0080          /* 16 bit r/w   SMI Control Register */
+#define GM_SMI_DATA            0x0084          /* 16 bit r/w   SMI Data Register */
+#define GM_PHY_ADDR            0x0088          /* 16 bit r/w   GPHY Address Register */
+
+/* MIB Counters */
+#define GM_MIB_CNT_BASE        0x0100          /* Base Address of MIB Counters */
+#define GM_MIB_CNT_SIZE        44                      /* Number of MIB Counters */
+
+/*
+ * MIB Counters base address definitions (low word) -
+ * use offset 4 for access to high word        (32 bit r/o)
+ */
+#define GM_RXF_UC_OK \
+                       (GM_MIB_CNT_BASE + 0)   /* Unicast Frames Received OK */
+#define GM_RXF_BC_OK \
+                       (GM_MIB_CNT_BASE + 8)   /* Broadcast Frames Received OK */
+#define GM_RXF_MPAUSE \
+                       (GM_MIB_CNT_BASE + 16)  /* Pause MAC Ctrl Frames Received */
+#define GM_RXF_MC_OK \
+                       (GM_MIB_CNT_BASE + 24)  /* Multicast Frames Received OK */
+#define GM_RXF_FCS_ERR \
+                       (GM_MIB_CNT_BASE + 32)  /* Rx Frame Check Seq. Error */
+       /* GM_MIB_CNT_BASE + 40:        reserved */
+#define GM_RXO_OK_LO \
+                       (GM_MIB_CNT_BASE + 48)  /* Octets Received OK Low */
+#define GM_RXO_OK_HI \
+                       (GM_MIB_CNT_BASE + 56)  /* Octets Received OK High */
+#define GM_RXO_ERR_LO \
+                       (GM_MIB_CNT_BASE + 64)  /* Octets Received Invalid Low */
+#define GM_RXO_ERR_HI \
+                       (GM_MIB_CNT_BASE + 72)  /* Octets Received Invalid High */
+#define GM_RXF_SHT \
+                       (GM_MIB_CNT_BASE + 80)  /* Frames <64 Byte Received OK */
+#define GM_RXE_FRAG \
+                       (GM_MIB_CNT_BASE + 88)  /* Frames <64 Byte Receeived with FCS Err */
+#define GM_RXF_64B \
+                       (GM_MIB_CNT_BASE + 96)  /* 64 Byte Rx Frame */
+#define GM_RXF_127B \
+                       (GM_MIB_CNT_BASE + 104) /* 65-127 Byte Rx Frame */
+#define GM_RXF_255B \
+                       (GM_MIB_CNT_BASE + 112) /* 128-255 Byte Rx Frame */
+#define GM_RXF_511B \
+                       (GM_MIB_CNT_BASE + 120) /* 256-511 Byte Rx Frame */
+#define GM_RXF_1023B \
+                       (GM_MIB_CNT_BASE + 128) /* 512-1023 Byte Rx Frame */
+#define GM_RXF_1518B \
+                       (GM_MIB_CNT_BASE + 136) /* 1024-1518 Byte Rx Frame */
+#define GM_RXF_MAX_SZ \
+                       (GM_MIB_CNT_BASE + 144) /* 1519-MaxSize Byte Rx Frame */
+#define GM_RXF_LNG_ERR \
+                       (GM_MIB_CNT_BASE + 152) /* Rx Frame too Long Error */
+#define GM_RXF_JAB_PKT \
+                       (GM_MIB_CNT_BASE + 160) /* Rx Jabber Packet Frame */
+       /* GM_MIB_CNT_BASE + 168:       reserved */
+#define GM_RXE_FIFO_OV \
+                       (GM_MIB_CNT_BASE + 176) /* Rx FIFO overflow Event */
+       /* GM_MIB_CNT_BASE + 184:       reserved */
+#define GM_TXF_UC_OK \
+                       (GM_MIB_CNT_BASE + 192) /* Unicast Frames Xmitted OK */
+#define GM_TXF_BC_OK \
+                       (GM_MIB_CNT_BASE + 200) /* Broadcast Frames Xmitted OK */
+#define GM_TXF_MPAUSE \
+                       (GM_MIB_CNT_BASE + 208) /* Pause MAC Ctrl Frames Xmitted */
+#define GM_TXF_MC_OK \
+                       (GM_MIB_CNT_BASE + 216) /* Multicast Frames Xmitted OK */
+#define GM_TXO_OK_LO \
+                       (GM_MIB_CNT_BASE + 224) /* Octets Transmitted OK Low */
+#define GM_TXO_OK_HI \
+                       (GM_MIB_CNT_BASE + 232) /* Octets Transmitted OK High */
+#define GM_TXF_64B \
+                       (GM_MIB_CNT_BASE + 240) /* 64 Byte Tx Frame */
+#define GM_TXF_127B \
+                       (GM_MIB_CNT_BASE + 248) /* 65-127 Byte Tx Frame */
+#define GM_TXF_255B \
+                       (GM_MIB_CNT_BASE + 256) /* 128-255 Byte Tx Frame */
+#define GM_TXF_511B \
+                       (GM_MIB_CNT_BASE + 264) /* 256-511 Byte Tx Frame */
+#define GM_TXF_1023B \
+                       (GM_MIB_CNT_BASE + 272) /* 512-1023 Byte Tx Frame */
+#define GM_TXF_1518B \
+                       (GM_MIB_CNT_BASE + 280) /* 1024-1518 Byte Tx Frame */
+#define GM_TXF_MAX_SZ \
+                       (GM_MIB_CNT_BASE + 288) /* 1519-MaxSize Byte Tx Frame */
+       /* GM_MIB_CNT_BASE + 296:       reserved */
+#define GM_TXF_COL \
+                       (GM_MIB_CNT_BASE + 304) /* Tx Collision */
+#define GM_TXF_LAT_COL \
+                       (GM_MIB_CNT_BASE + 312) /* Tx Late Collision */
+#define GM_TXF_ABO_COL \
+                       (GM_MIB_CNT_BASE + 320) /* Tx aborted due to Exces. Col. */
+#define GM_TXF_MUL_COL \
+                       (GM_MIB_CNT_BASE + 328) /* Tx Multiple Collision */
+#define GM_TXF_SNG_COL \
+                       (GM_MIB_CNT_BASE + 336) /* Tx Single Collision */
+#define GM_TXE_FIFO_UR \
+                       (GM_MIB_CNT_BASE + 344) /* Tx FIFO Underrun Event */
+
+/*----------------------------------------------------------------------------*/
+/*
+ * GMAC Bit Definitions
+ *
+ * If the bit access behaviour differs from the register access behaviour
+ * (r/w, r/o) this is documented after the bit number.
+ * The following bit access behaviours are used:
+ *     (sc)    self clearing
+ *     (r/o)   read only
+ */
+
+/*     GM_GP_STAT      16 bit r/o      General Purpose Status Register */
+
+#define GM_GPSR_SPEED          (1<<15) /* Bit 15:      Port Speed (1 = 100 Mbps) */
+#define GM_GPSR_DUPLEX         (1<<14) /* Bit 14:      Duplex Mode (1 = Full) */
+#define GM_GPSR_FC_TX_DIS      (1<<13) /* Bit 13:      Tx Flow Control Mode Disabled */
+#define GM_GPSR_LINK_UP                (1<<12) /* Bit 12:      Link Up Status */
+#define GM_GPSR_PAUSE          (1<<11) /* Bit 11:      Pause State */
+#define GM_GPSR_TX_ACTIVE      (1<<10) /* Bit 10:      Tx in Progress */
+#define GM_GPSR_EXC_COL                (1<<9)  /* Bit  9:      Excessive Collisions Occured */
+#define GM_GPSR_LAT_COL                (1<<8)  /* Bit  8:      Late Collisions Occured */
+                                                               /* Bit  7..6:   reserved */
+#define GM_GPSR_PHY_ST_CH      (1<<5)  /* Bit  5:      PHY Status Change */
+#define GM_GPSR_GIG_SPEED      (1<<4)  /* Bit  4:      Gigabit Speed (1 = 1000 Mbps) */
+#define GM_GPSR_PART_MODE      (1<<3)  /* Bit  3:      Partition mode */
+#define GM_GPSR_FC_RX_DIS      (1<<2)  /* Bit  2:      Rx Flow Control Mode Disabled */
+#define GM_GPSR_PROM_EN                (1<<1)  /* Bit  1:      Promiscuous Mode Enabled */
+                                                               /* Bit  0:      reserved */
+
+/*     GM_GP_CTRL      16 bit r/w      General Purpose Control Register */
+                                                               /* Bit 15:      reserved */
+#define GM_GPCR_PROM_ENA       (1<<14) /* Bit 14:      Enable Promiscuous Mode */
+#define GM_GPCR_FC_TX_DIS      (1<<13) /* Bit 13:      Disable Tx Flow Control Mode */
+#define GM_GPCR_TX_ENA         (1<<12) /* Bit 12:      Enable Transmit */
+#define GM_GPCR_RX_ENA         (1<<11) /* Bit 11:      Enable Receive */
+#define GM_GPCR_BURST_ENA      (1<<10) /* Bit 10:      Enable Burst Mode */
+#define GM_GPCR_LOOP_ENA       (1<<9)  /* Bit  9:      Enable MAC Loopback Mode */
+#define GM_GPCR_PART_ENA       (1<<8)  /* Bit  8:      Enable Partition Mode */
+#define GM_GPCR_GIGS_ENA       (1<<7)  /* Bit  7:      Gigabit Speed (1000 Mbps) */
+#define GM_GPCR_FL_PASS                (1<<6)  /* Bit  6:      Force Link Pass */
+#define GM_GPCR_DUP_FULL       (1<<5)  /* Bit  5:      Full Duplex Mode */
+#define GM_GPCR_FC_RX_DIS      (1<<4)  /* Bit  4:      Disable Rx Flow Control Mode */
+#define GM_GPCR_SPEED_100      (1<<3)  /* Bit  3:      Port Speed 100 Mbps */
+#define GM_GPCR_AU_DUP_DIS     (1<<2)  /* Bit  2:      Disable Auto-Update for Duplex */
+#define GM_GPCR_AU_FCT_DIS     (1<<1)  /* Bit  1:      Disable Auto-Update for Flow-c. */
+#define GM_GPCR_AU_SPD_DIS     (1<<0)  /* Bit  0:      Disable Auto-Update for Speed */
+
+#define GM_GPCR_SPEED_1000     (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
+#define GM_GPCR_AU_ALL_DIS     (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |\
+                                                        GM_GPCR_AU_SPD_DIS)
+
+/*     GM_TX_CTRL                              16 bit r/w      Transmit Control Register */
+
+#define GM_TXCR_FORCE_JAM      (1<<15) /* Bit 15:      Force Jam / Flow-Control */
+#define GM_TXCR_CRC_DIS                (1<<14) /* Bit 14:      Disable insertion of CRC */
+#define GM_TXCR_PAD_DIS                (1<<13) /* Bit 13:      Disable padding of packets */
+#define GM_TXCR_COL_THR                (4<<10) /* Bit 12..10:  Collision Threshold */
+
+/*     GM_RX_CTRL                              16 bit r/w      Receive Control Register */
+#define GM_RXCR_UCF_ENA                (1<<15) /* Bit 15:      Enable Unicast filtering */
+#define GM_RXCR_MCF_ENA                (1<<14) /* Bit 14:      Enable Multicast filtering */
+#define GM_RXCR_CRC_DIS                (1<<13) /* Bit 13:      Remove 4-byte CRC */
+#define GM_RXCR_PASS_FC                (1<<12) /* Bit 12:      Pass FC packets to FIFO */
+
+/*     GM_TX_PARAM                             16 bit r/w      Transmit Parameter Register */
+#define GM_TXPA_JAMLEN_MSK     (0x03<<14)      /* Bit 15..14:  Jam Length */
+#define GM_TXPA_JAMIPG_MSK     (0x1f<<9)       /* Bit 13..9:   Jam IPG */
+#define GM_TXPA_JAMDAT_MSK     (0x1f<<4)       /* Bit  8..4:   IPG Jam to Data */
+                                                               /* Bit  3..0:   reserved */
+#define JAM_LEN_VAL(x)         SHIFT14(x)
+#define JAM_IPG_VAL(x)         SHIFT9(x)
+#define IPG_JAM_DATA(x)                SHIFT4(x)
+
+/*     GM_SERIAL_MODE                  16 bit r/w      Serial Mode Register */
+#define GM_SMOD_DATABL_MSK     (0x1f<<11)      /* Bit 15..11:  Data Blinder */
+#define GM_SMOD_LIMIT_4                (1<<10) /* Bit 10:      4 consecutive transmit trials */
+#define GM_SMOD_VLAN_ENA       (1<<9)  /* Bit  9:      Enable VLAN  (Max. Frame Length) */
+#define GM_SMOD_JUMBO_ENA      (1<<8)  /* Bit  8:      Enable Jumbo (Max. Frame Length) */
+                                                               /* Bit  7..5:   reserved */
+#define GM_SMOD_IPG_MSK                0x1f    /* Bit 4..0:    Inter-Packet Gap (IPG) */
+
+#define DATA_BLIND_VAL(x)      SHIFT11(x)
+#define DATA_BLIND_FAST_ETH    0x1c
+#define DATA_BLIND_GIGABIT     4
+
+#define IPG_VAL_FAST_ETH       0x1e
+#define IPG_VAL_GIGABIT                6
+
+/*     GM_SMI_CTRL                             16 bit r/w      SMI Control Register */
+
+#define GM_SMI_CT_PHY_AD(x)    SHIFT11(x)
+#define GM_SMI_CT_REG_AD(x)    SHIFT6(x)
+#define GM_SMI_CT_OP_RD                (1<<5)  /* Bit  5:      OpCode Read (0=Write)*/
+#define GM_SMI_CT_RD_VAL       (1<<4)  /* Bit  4:      Read Valid (Read completed) */
+#define GM_SMI_CT_BUSY         (1<<3)  /* Bit  3:      Busy (Operation in progress) */
+                                                               /* Bit   2..0:  reserved */
+
+/*     GM_PHY_ADDR                             16 bit r/w      GPHY Address Register */
+                                                               /* Bit  15..6:  reserved */
+#define GM_PAR_MIB_CLR         (1<<5)  /* Bit  5:      Set MIB Clear Counter Mode */
+#define GM_PAR_MIB_TST         (1<<4)  /* Bit  4:      MIB Load Counter (Test Mode) */
+                                                               /* Bit   3..0:  reserved */
+
+/* Receive Frame Status Encoding */
+#define GMR_FS_LEN     (0xffffUL<<16)  /* Bit 31..16:  Rx Frame Length */
+                                                               /* Bit  15..14: reserved */
+#define GMR_FS_VLAN            (1L<<13)        /* Bit 13:      VLAN Packet */
+#define GMR_FS_JABBER  (1L<<12)        /* Bit 12:      Jabber Packet */
+#define GMR_FS_UN_SIZE (1L<<11)        /* Bit 11:      Undersize Packet */
+#define GMR_FS_MC              (1L<<10)        /* Bit 10:      Multicast Packet */
+#define GMR_FS_BC              (1L<<9)         /* Bit  9:      Broadcast Packet */
+#define GMR_FS_RX_OK   (1L<<8)         /* Bit  8:      Receive OK (Good Packet) */
+#define GMR_FS_GOOD_FC (1L<<7)         /* Bit  7:      Good Flow-Control Packet */
+#define GMR_FS_BAD_FC  (1L<<6)         /* Bit  6:      Bad  Flow-Control Packet */
+#define GMR_FS_MII_ERR (1L<<5)         /* Bit  5:      MII Error */
+#define GMR_FS_LONG_ERR        (1L<<4)         /* Bit  4:      Too Long Packet */
+#define GMR_FS_FRAGMENT        (1L<<3)         /* Bit  3:      Fragment */
+                                                               /* Bit  2:      reserved */
+#define GMR_FS_CRC_ERR (1L<<1)         /* Bit  1:      CRC Error */
+#define GMR_FS_RX_FF_OV        (1L<<0)         /* Bit  0:      Rx FIFO Overflow */
+
+/*
+ * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR)
+ */
+#define GMR_FS_ANY_ERR (GMR_FS_CRC_ERR | \
+                       GMR_FS_LONG_ERR | \
+                       GMR_FS_MII_ERR | \
+                       GMR_FS_BAD_FC | \
+                       GMR_FS_GOOD_FC | \
+                       GMR_FS_JABBER)
+
+/* Rx GMAC FIFO Flush Mask (default) */
+#define RX_FF_FL_DEF_MSK       (GMR_FS_CRC_ERR | \
+                       GMR_FS_RX_FF_OV | \
+                       GMR_FS_MII_ERR | \
+                       GMR_FS_BAD_FC | \
+                       GMR_FS_GOOD_FC | \
+                       GMR_FS_UN_SIZE | \
+                       GMR_FS_JABBER)
+
+/* typedefs *******************************************************************/
+
+
+/* function prototypes ********************************************************/
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __INC_XMAC_H */
diff --git a/drivers/net/sk98lin/skaddr.c b/drivers/net/sk98lin/skaddr.c
new file mode 100644 (file)
index 0000000..ed79c04
--- /dev/null
@@ -0,0 +1,1879 @@
+/******************************************************************************
+ *
+ * Name:       skaddr.c
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.48 $
+ * Date:       $Date: 2003/02/12 17:09:37 $
+ * Purpose:    Manage Addresses (Multicast and Unicast) and Promiscuous Mode.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2002 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skaddr.c,v $
+ *     Revision 1.48  2003/02/12 17:09:37  tschilli
+ *     Fix in SkAddrOverride() to set both (physical and logical) MAC addresses
+ *     in case that both addresses are identical.
+ *
+ *     Revision 1.47  2002/09/17 06:31:10  tschilli
+ *     Handling of SK_PROM_MODE_ALL_MC flag in SkAddrGmacMcUpdate()
+ *     and SkAddrGmacPromiscuousChange() fixed.
+ *     Editorial changes.
+ *
+ *     Revision 1.46  2002/08/22 07:55:41  tschilli
+ *     New function SkGmacMcHash() for GMAC multicast hashing algorithm added.
+ *     Editorial changes.
+ *
+ *     Revision 1.45  2002/08/15 12:29:35  tschilli
+ *     SkAddrGmacMcUpdate() and SkAddrGmacPromiscuousChange() changed.
+ *
+ *     Revision 1.44  2002/08/14 12:18:03  rschmidt
+ *     Replaced direct handling of MAC Hashing (XMAC and GMAC)
+ *     with routine SkMacHashing().
+ *     Replaced wrong 3rd para 'i' with 'PortNumber' in SkMacPromiscMode().
+ *
+ *     Revision 1.43  2002/08/13 09:37:43  rschmidt
+ *     Corrected some SK_DBG_MSG outputs.
+ *     Replaced wrong 2nd para pAC with IoC in SkMacPromiscMode().
+ *     Editorial changes.
+ *
+ *     Revision 1.42  2002/08/12 11:24:36  rschmidt
+ *     Remove setting of logical MAC address GM_SRC_ADDR_2 in SkAddrInit().
+ *     Replaced direct handling of MAC Promiscuous Mode (XMAC and GMAC)
+ *     with routine SkMacPromiscMode().
+ *     Editorial changes.
+ *
+ *     Revision 1.41  2002/06/10 13:52:18  tschilli
+ *     Changes for handling YUKON.
+ *     All changes are internally and not visible to the programmer
+ *     using this module.
+ *
+ *     Revision 1.40  2001/02/14 14:04:59  rassmann
+ *     Editorial changes.
+ *
+ *     Revision 1.39  2001/01/30 10:30:04  rassmann
+ *     Editorial changes.
+ *
+ *     Revision 1.38  2001/01/25 16:26:52  rassmann
+ *     Ensured that logical address overrides are done on net's active port.
+ *
+ *     Revision 1.37  2001/01/22 13:41:34  rassmann
+ *     Supporting two nets on dual-port adapters.
+ *
+ *     Revision 1.36  2000/08/07 11:10:39  rassmann
+ *     Editorial changes.
+ *
+ *     Revision 1.35  2000/05/04 09:38:41  rassmann
+ *     Editorial changes.
+ *     Corrected multicast address hashing.
+ *
+ *     Revision 1.34  1999/11/22 13:23:44  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.33  1999/05/28 10:56:06  rassmann
+ *     Editorial changes.
+ *
+ *     Revision 1.32  1999/03/31 10:59:20  rassmann
+ *     Returning Success instead of DupAddr if address shall be overridden
+ *     with same value.
+ *
+ *     Revision 1.31  1999/01/14 16:18:17  rassmann
+ *     Corrected multicast initialization.
+ *
+ *     Revision 1.30  1999/01/04 10:30:35  rassmann
+ *     SkAddrOverride only possible after SK_INIT_IO phase.
+ *
+ *     Revision 1.29  1998/12/29 13:13:10  rassmann
+ *     An address override is now preserved in the SK_INIT_IO phase.
+ *     All functions return an int now.
+ *     Extended parameter checking.
+ *
+ *     Revision 1.28  1998/12/01 11:45:53  rassmann
+ *     Code cleanup.
+ *
+ *     Revision 1.27  1998/12/01 09:22:49  rassmann
+ *     SkAddrMcAdd and SkAddrMcUpdate returned SK_MC_FILTERING_INEXACT
+ *     too often.
+ *
+ *     Revision 1.26  1998/11/24 12:39:44  rassmann
+ *     Reserved multicast entry for BPDU address.
+ *     13 multicast entries left for protocol.
+ *
+ *     Revision 1.25  1998/11/17 16:54:23  rassmann
+ *     Using exact match for up to 14 multicast addresses.
+ *     Still receiving all multicasts if more addresses are added.
+ *
+ *     Revision 1.24  1998/11/13 17:24:31  rassmann
+ *     Changed return value of SkAddrOverride to int.
+ *
+ *     Revision 1.23  1998/11/13 16:56:18  rassmann
+ *     Added macro SK_ADDR_COMPARE.
+ *     Changed return type of SkAddrOverride to SK_BOOL.
+ *
+ *     Revision 1.22  1998/11/04 17:06:17  rassmann
+ *     Corrected McUpdate and PromiscuousChange functions.
+ *
+ *     Revision 1.21  1998/10/29 14:34:04  rassmann
+ *     Clearing SK_ADDR struct at startup.
+ *
+ *     Revision 1.20  1998/10/28 18:16:34  rassmann
+ *     Avoiding I/Os before SK_INIT_RUN level.
+ *     Aligning InexactFilter.
+ *
+ *     Revision 1.19  1998/10/28 11:29:28  rassmann
+ *     Programming physical address in SkAddrMcUpdate.
+ *     Corrected programming of exact match entries.
+ *
+ *     Revision 1.18  1998/10/28 10:34:48  rassmann
+ *     Corrected reading of physical addresses.
+ *
+ *     Revision 1.17  1998/10/28 10:26:13  rassmann
+ *     Getting ports' current MAC addresses from EPROM now.
+ *     Added debug output.
+ *
+ *     Revision 1.16  1998/10/27 16:20:12  rassmann
+ *     Reading MAC address byte by byte.
+ *
+ *     Revision 1.15  1998/10/22 11:39:09  rassmann
+ *     Corrected signed/unsigned mismatches.
+ *
+ *     Revision 1.14  1998/10/19 17:12:35  rassmann
+ *     Syntax corrections.
+ *
+ *     Revision 1.13  1998/10/19 17:02:19  rassmann
+ *     Now reading permanent MAC addresses from CRF.
+ *
+ *     Revision 1.12  1998/10/15 15:15:48  rassmann
+ *     Changed Flags Parameters from SK_U8 to int.
+ *     Checked with lint.
+ *
+ *     Revision 1.11  1998/09/24 19:15:12  rassmann
+ *     Code cleanup.
+ *
+ *     Revision 1.10  1998/09/18 20:18:54  rassmann
+ *     Added HW access.
+ *     Implemented swapping.
+ *
+ *     Revision 1.9  1998/09/16 11:32:00  rassmann
+ *     Including skdrv1st.h again. :(
+ *
+ *     Revision 1.8  1998/09/16 11:09:34  rassmann
+ *     Syntax corrections.
+ *
+ *     Revision 1.7  1998/09/14 17:06:34  rassmann
+ *     Minor changes.
+ *
+ *     Revision 1.6  1998/09/07 08:45:41  rassmann
+ *     Syntax corrections.
+ *
+ *     Revision 1.5  1998/09/04 19:40:19  rassmann
+ *     Interface enhancements.
+ *
+ *     Revision 1.4  1998/09/04 12:14:12  rassmann
+ *     Interface cleanup.
+ *
+ *     Revision 1.3  1998/09/02 16:56:40  rassmann
+ *     Updated interface.
+ *
+ *     Revision 1.2  1998/08/27 14:26:09  rassmann
+ *     Updated interface.
+ *
+ *     Revision 1.1  1998/08/21 08:30:22  rassmann
+ *     First public version.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * This module is intended to manage multicast addresses, address override,
+ * and promiscuous mode on GEnesis and Yukon adapters.
+ *
+ * Address Layout:
+ *     port address:           physical MAC address
+ *     1st exact match:        logical MAC address (GEnesis only)
+ *     2nd exact match:        RLMT multicast (GEnesis only)
+ *     exact match 3-13:       OS-specific multicasts (GEnesis only)
+ *
+ * Include File Hierarchy:
+ *
+ *     "skdrv1st.h"
+ *     "skdrv2nd.h"
+ *
+ ******************************************************************************/
+
+#include <config.h>
+
+#ifdef CONFIG_SK98
+
+#ifndef        lint
+static const char SysKonnectFileId[] =
+       "@(#) $Id: skaddr.c,v 1.48 2003/02/12 17:09:37 tschilli Exp $ (C) SysKonnect.";
+#endif /* !defined(lint) */
+
+#define __SKADDR_C
+
+#ifdef __cplusplus
+#error C++ is not yet supported.
+extern "C" {
+#endif /* cplusplus */
+
+#include "h/skdrv1st.h"
+#include "h/skdrv2nd.h"
+
+/* defines ********************************************************************/
+
+
+#define XMAC_POLY      0xEDB88320UL    /* CRC32-Poly - XMAC: Little Endian */
+#define GMAC_POLY      0x04C11DB7L     /* CRC16-Poly - GMAC: Little Endian */
+#define HASH_BITS      6                               /* #bits in hash */
+#define        SK_MC_BIT       0x01
+
+/* Error numbers and messages. */
+
+#define SKERR_ADDR_E001                (SK_ERRBASE_ADDR + 0)
+#define SKERR_ADDR_E001MSG     "Bad Flags."
+#define SKERR_ADDR_E002                (SKERR_ADDR_E001 + 1)
+#define SKERR_ADDR_E002MSG     "New Error."
+
+/* typedefs *******************************************************************/
+
+/* None. */
+
+/* global variables ***********************************************************/
+
+/* 64-bit hash values with all bits set. */
+
+SK_U16 OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
+
+/* local variables ************************************************************/
+
+#ifdef DEBUG
+static int     Next0[SK_MAX_MACS] = {0, 0};
+#endif /* DEBUG */
+
+/* functions ******************************************************************/
+
+/******************************************************************************
+ *
+ *     SkAddrInit - initialize data, set state to init
+ *
+ * Description:
+ *
+ *     SK_INIT_DATA
+ *     ============
+ *
+ *     This routine clears the multicast tables and resets promiscuous mode.
+ *     Some entries are reserved for the "logical MAC address", the
+ *     SK-RLMT multicast address, and the BPDU multicast address.
+ *
+ *
+ *     SK_INIT_IO
+ *     ==========
+ *
+ *     All permanent MAC addresses are read from EPROM.
+ *     If the current MAC addresses are not already set in software,
+ *     they are set to the values of the permanent addresses.
+ *     The current addresses are written to the corresponding MAC.
+ *
+ *
+ *     SK_INIT_RUN
+ *     ===========
+ *
+ *     Nothing.
+ *
+ * Context:
+ *     init, pageable
+ *
+ * Returns:
+ *     SK_ADDR_SUCCESS
+ */
+int    SkAddrInit(
+SK_AC  *pAC,   /* the adapter context */
+SK_IOC IoC,    /* I/O context */
+int            Level)  /* initialization level */
+{
+       int                     j;
+       SK_U32          i;
+       SK_U8           *InAddr;
+       SK_U16          *OutAddr;
+       SK_ADDR_PORT    *pAPort;
+
+       switch (Level) {
+       case SK_INIT_DATA:
+               SK_MEMSET((char *) &pAC->Addr, 0, sizeof(SK_ADDR));
+
+               for (i = 0; i < SK_MAX_MACS; i++) {
+                       pAPort = &pAC->Addr.Port[i];
+                       pAPort->PromMode = SK_PROM_MODE_NONE;
+
+                       pAPort->FirstExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
+                       pAPort->FirstExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
+                       pAPort->NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
+                       pAPort->NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
+               }
+#ifdef xDEBUG
+               for (i = 0; i < SK_MAX_MACS; i++) {
+                       if (pAC->Addr.Port[i].NextExactMatchRlmt <
+                               SK_ADDR_FIRST_MATCH_RLMT) {
+                               Next0[i] |= 4;
+                       }
+               }
+#endif /* DEBUG */
+               /* pAC->Addr.InitDone = SK_INIT_DATA; */
+               break;
+
+       case SK_INIT_IO:
+               for (i = 0; i < SK_MAX_NETS; i++) {
+                       pAC->Addr.Net[i].ActivePort = pAC->Rlmt.Net[i].ActivePort;
+               }
+#ifdef xDEBUG
+               for (i = 0; i < SK_MAX_MACS; i++) {
+                       if (pAC->Addr.Port[i].NextExactMatchRlmt <
+                               SK_ADDR_FIRST_MATCH_RLMT) {
+                               Next0[i] |= 8;
+                       }
+               }
+#endif /* DEBUG */
+
+               /* Read permanent logical MAC address from Control Register File. */
+               for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
+                       InAddr = (SK_U8 *) &pAC->Addr.Net[0].PermanentMacAddress.a[j];
+                       SK_IN8(IoC, B2_MAC_1 + j, InAddr);
+               }
+
+               if (!pAC->Addr.Net[0].CurrentMacAddressSet) {
+                       /* Set the current logical MAC address to the permanent one. */
+                       pAC->Addr.Net[0].CurrentMacAddress =
+                               pAC->Addr.Net[0].PermanentMacAddress;
+                       pAC->Addr.Net[0].CurrentMacAddressSet = SK_TRUE;
+               }
+
+               /* Set the current logical MAC address. */
+               pAC->Addr.Port[pAC->Addr.Net[0].ActivePort].Exact[0] =
+                       pAC->Addr.Net[0].CurrentMacAddress;
+#if SK_MAX_NETS > 1
+               /* Set logical MAC address for net 2 to (log | 3). */
+               if (!pAC->Addr.Net[1].CurrentMacAddressSet) {
+                       pAC->Addr.Net[1].PermanentMacAddress =
+                               pAC->Addr.Net[0].PermanentMacAddress;
+                       pAC->Addr.Net[1].PermanentMacAddress.a[5] |= 3;
+                       /* Set the current logical MAC address to the permanent one. */
+                       pAC->Addr.Net[1].CurrentMacAddress =
+                               pAC->Addr.Net[1].PermanentMacAddress;
+                       pAC->Addr.Net[1].CurrentMacAddressSet = SK_TRUE;
+               }
+#endif /* SK_MAX_NETS > 1 */
+
+#ifdef DEBUG
+               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
+                       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
+                               ("Permanent MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
+                                       i,
+                                       pAC->Addr.Net[i].PermanentMacAddress.a[0],
+                                       pAC->Addr.Net[i].PermanentMacAddress.a[1],
+                                       pAC->Addr.Net[i].PermanentMacAddress.a[2],
+                                       pAC->Addr.Net[i].PermanentMacAddress.a[3],
+                                       pAC->Addr.Net[i].PermanentMacAddress.a[4],
+                                       pAC->Addr.Net[i].PermanentMacAddress.a[5]))
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
+                               ("Logical MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
+                                       i,
+                                       pAC->Addr.Net[i].CurrentMacAddress.a[0],
+                                       pAC->Addr.Net[i].CurrentMacAddress.a[1],
+                                       pAC->Addr.Net[i].CurrentMacAddress.a[2],
+                                       pAC->Addr.Net[i].CurrentMacAddress.a[3],
+                                       pAC->Addr.Net[i].CurrentMacAddress.a[4],
+                                       pAC->Addr.Net[i].CurrentMacAddress.a[5]))
+               }
+#endif /* DEBUG */
+
+               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
+                       pAPort = &pAC->Addr.Port[i];
+
+                       /* Read permanent port addresses from Control Register File. */
+                       for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
+                               InAddr = (SK_U8 *) &pAPort->PermanentMacAddress.a[j];
+                               SK_IN8(IoC, B2_MAC_2 + 8 * i + j, InAddr);
+                       }
+
+                       if (!pAPort->CurrentMacAddressSet) {
+                               /*
+                                * Set the current and previous physical MAC address
+                                * of this port to its permanent MAC address.
+                                */
+                               pAPort->CurrentMacAddress = pAPort->PermanentMacAddress;
+                               pAPort->PreviousMacAddress = pAPort->PermanentMacAddress;
+                               pAPort->CurrentMacAddressSet = SK_TRUE;
+                       }
+
+                       /* Set port's current physical MAC address. */
+                       OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
+
+                       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+                               XM_OUTADDR(IoC, i, XM_SA, OutAddr);
+                       }
+                       else {
+                               GM_OUTADDR(IoC, i, GM_SRC_ADDR_1L, OutAddr);
+                       }
+#ifdef DEBUG
+                       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
+                               ("SkAddrInit: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
+                                       pAPort->PermanentMacAddress.a[0],
+                                       pAPort->PermanentMacAddress.a[1],
+                                       pAPort->PermanentMacAddress.a[2],
+                                       pAPort->PermanentMacAddress.a[3],
+                                       pAPort->PermanentMacAddress.a[4],
+                                       pAPort->PermanentMacAddress.a[5]))
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
+                               ("SkAddrInit: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
+                                       pAPort->CurrentMacAddress.a[0],
+                                       pAPort->CurrentMacAddress.a[1],
+                                       pAPort->CurrentMacAddress.a[2],
+                                       pAPort->CurrentMacAddress.a[3],
+                                       pAPort->CurrentMacAddress.a[4],
+                                       pAPort->CurrentMacAddress.a[5]))
+#endif /* DEBUG */
+               }
+               /* pAC->Addr.InitDone = SK_INIT_IO; */
+               break;
+
+       case SK_INIT_RUN:
+#ifdef xDEBUG
+               for (i = 0; i < SK_MAX_MACS; i++) {
+                       if (pAC->Addr.Port[i].NextExactMatchRlmt <
+                               SK_ADDR_FIRST_MATCH_RLMT) {
+                               Next0[i] |= 16;
+                       }
+               }
+#endif /* DEBUG */
+
+               /* pAC->Addr.InitDone = SK_INIT_RUN; */
+               break;
+
+       default:        /* error */
+               break;
+       }
+
+       return (SK_ADDR_SUCCESS);
+
+}      /* SkAddrInit */
+
+
+/******************************************************************************
+ *
+ *     SkAddrMcClear - clear the multicast table
+ *
+ * Description:
+ *     This routine clears the multicast table.
+ *
+ *     If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
+ *     immediately.
+ *
+ *     It calls either SkAddrXmacMcClear or SkAddrGmacMcClear, according
+ *     to the adapter in use. The real work is done there.
+ *
+ * Context:
+ *     runtime, pageable
+ *     may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
+ *     may be called after SK_INIT_IO without limitation
+ *
+ * Returns:
+ *     SK_ADDR_SUCCESS
+ *     SK_ADDR_ILLEGAL_PORT
+ */
+int    SkAddrMcClear(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* I/O context */
+SK_U32 PortNumber,     /* Index of affected port */
+int            Flags)          /* permanent/non-perm, sw-only */
+{
+       int ReturnCode;
+
+       if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
+               return (SK_ADDR_ILLEGAL_PORT);
+       }
+
+       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+               ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags);
+       }
+       else {
+               ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags);
+       }
+
+       return (ReturnCode);
+
+}      /* SkAddrMcClear */
+
+
+/******************************************************************************
+ *
+ *     SkAddrXmacMcClear - clear the multicast table
+ *
+ * Description:
+ *     This routine clears the multicast table
+ *     (either entry 2 or entries 3-16 and InexactFilter) of the given port.
+ *     If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
+ *     immediately.
+ *
+ * Context:
+ *     runtime, pageable
+ *     may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
+ *     may be called after SK_INIT_IO without limitation
+ *
+ * Returns:
+ *     SK_ADDR_SUCCESS
+ *     SK_ADDR_ILLEGAL_PORT
+ */
+int    SkAddrXmacMcClear(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* I/O context */
+SK_U32 PortNumber,     /* Index of affected port */
+int            Flags)          /* permanent/non-perm, sw-only */
+{
+       int i;
+
+       if (Flags & SK_ADDR_PERMANENT) {        /* permanent => RLMT */
+
+               /* Clear RLMT multicast addresses. */
+               pAC->Addr.Port[PortNumber].NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
+       }
+       else {  /* not permanent => DRV */
+
+               /* Clear InexactFilter */
+               for (i = 0; i < 8; i++) {
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
+               }
+
+               /* Clear DRV multicast addresses. */
+
+               pAC->Addr.Port[PortNumber].NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
+       }
+
+       if (!(Flags & SK_MC_SW_ONLY)) {
+               (void) SkAddrXmacMcUpdate(pAC, IoC, PortNumber);
+       }
+
+       return (SK_ADDR_SUCCESS);
+
+}      /* SkAddrXmacMcClear */
+
+
+/******************************************************************************
+ *
+ *     SkAddrGmacMcClear - clear the multicast table
+ *
+ * Description:
+ *     This routine clears the multicast hashing table (InexactFilter)
+ *     (either the RLMT or the driver bits) of the given port.
+ *
+ *     If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
+ *     immediately.
+ *
+ * Context:
+ *     runtime, pageable
+ *     may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
+ *     may be called after SK_INIT_IO without limitation
+ *
+ * Returns:
+ *     SK_ADDR_SUCCESS
+ *     SK_ADDR_ILLEGAL_PORT
+ */
+int    SkAddrGmacMcClear(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* I/O context */
+SK_U32 PortNumber,     /* Index of affected port */
+int            Flags)          /* permanent/non-perm, sw-only */
+{
+       int i;
+
+#ifdef DEBUG
+       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+               ("GMAC InexactFilter (not cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n",
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
+#endif /* DEBUG */
+
+       /* Clear InexactFilter */
+       for (i = 0; i < 8; i++) {
+               pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
+       }
+
+       if (Flags & SK_ADDR_PERMANENT) {        /* permanent => RLMT */
+
+               /* Copy DRV bits to InexactFilter. */
+               for (i = 0; i < 8; i++) {
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
+                               pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i];
+
+                       /* Clear InexactRlmtFilter. */
+                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i] = 0;
+
+               }
+       }
+       else {  /* not permanent => DRV */
+
+               /* Copy RLMT bits to InexactFilter. */
+               for (i = 0; i < 8; i++) {
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
+                               pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i];
+
+                       /* Clear InexactDrvFilter. */
+                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i] = 0;
+               }
+       }
+
+#ifdef DEBUG
+       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+               ("GMAC InexactFilter (cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n",
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
+#endif /* DEBUG */
+
+       if (!(Flags & SK_MC_SW_ONLY)) {
+               (void) SkAddrGmacMcUpdate(pAC, IoC, PortNumber);
+       }
+
+       return (SK_ADDR_SUCCESS);
+
+}      /* SkAddrGmacMcClear */
+
+#ifndef SK_ADDR_CHEAT
+
+/******************************************************************************
+ *
+ *     SkXmacMcHash - hash multicast address
+ *
+ * Description:
+ *     This routine computes the hash value for a multicast address.
+ *     A CRC32 algorithm is used.
+ *
+ * Notes:
+ *     The code was adapted from the XaQti data sheet.
+ *
+ * Context:
+ *     runtime, pageable
+ *
+ * Returns:
+ *     Hash value of multicast address.
+ */
+SK_U32 SkXmacMcHash(
+unsigned char *pMc)    /* Multicast address */
+{
+       SK_U32 Idx;
+       SK_U32 Bit;
+       SK_U32 Data;
+       SK_U32 Crc;
+
+       Crc = 0xFFFFFFFFUL;
+       for (Idx = 0; Idx < SK_MAC_ADDR_LEN; Idx++) {
+               Data = *pMc++;
+               for (Bit = 0; Bit < 8; Bit++, Data >>= 1) {
+                       Crc = (Crc >> 1) ^ (((Crc ^ Data) & 1) ? XMAC_POLY : 0);
+               }
+       }
+
+       return (Crc & ((1 << HASH_BITS) - 1));
+
+}      /* SkXmacMcHash */
+
+
+/******************************************************************************
+ *
+ *     SkGmacMcHash - hash multicast address
+ *
+ * Description:
+ *     This routine computes the hash value for a multicast address.
+ *     A CRC16 algorithm is used.
+ *
+ * Notes:
+ *
+ *
+ * Context:
+ *     runtime, pageable
+ *
+ * Returns:
+ *     Hash value of multicast address.
+ */
+SK_U32 SkGmacMcHash(
+unsigned char *pMc)    /* Multicast address */
+{
+       SK_U32 Data;
+       SK_U32 TmpData;
+       SK_U32 Crc;
+       int Byte;
+       int Bit;
+
+       Crc = 0xFFFFFFFFUL;
+       for (Byte = 0; Byte < 6; Byte++) {
+               /* Get next byte. */
+               Data = (SK_U32) pMc[Byte];
+
+               /* Change bit order in byte. */
+               TmpData = Data;
+               for (Bit = 0; Bit < 8; Bit++) {
+                       if (TmpData & 1L) {
+                               Data |=  1L << (7 - Bit);
+                       }
+                       else {
+                               Data &= ~(1L << (7 - Bit));
+                       }
+                       TmpData >>= 1;
+               }
+
+               Crc ^= (Data << 24);
+               for (Bit = 0; Bit < 8; Bit++) {
+                       if (Crc & 0x80000000) {
+                               Crc = (Crc << 1) ^ GMAC_POLY;
+                       }
+                       else {
+                               Crc <<= 1;
+                       }
+               }
+       }
+
+       return (Crc & ((1 << HASH_BITS) - 1));
+
+}      /* SkGmacMcHash */
+
+#endif /* not SK_ADDR_CHEAT */
+
+/******************************************************************************
+ *
+ *     SkAddrMcAdd - add a multicast address to a port
+ *
+ * Description:
+ *     This routine enables reception for a given address on the given port.
+ *
+ *     It calls either SkAddrXmacMcAdd or SkAddrGmacMcAdd, according to the
+ *     adapter in use. The real work is done there.
+ *
+ * Notes:
+ *     The return code is only valid for SK_PROM_MODE_NONE.
+ *
+ * Context:
+ *     runtime, pageable
+ *     may be called after SK_INIT_DATA
+ *
+ * Returns:
+ *     SK_MC_FILTERING_EXACT
+ *     SK_MC_FILTERING_INEXACT
+ *     SK_MC_ILLEGAL_ADDRESS
+ *     SK_MC_ILLEGAL_PORT
+ *     SK_MC_RLMT_OVERFLOW
+ */
+int    SkAddrMcAdd(
+SK_AC          *pAC,           /* adapter context */
+SK_IOC         IoC,            /* I/O context */
+SK_U32         PortNumber,     /* Port Number */
+SK_MAC_ADDR    *pMc,           /* multicast address to be added */
+int                    Flags)          /* permanent/non-permanent */
+{
+       int ReturnCode;
+
+       if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
+               return (SK_ADDR_ILLEGAL_PORT);
+       }
+
+       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+               ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
+       }
+       else {
+               ReturnCode = SkAddrGmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
+       }
+
+       return (ReturnCode);
+
+}      /* SkAddrMcAdd */
+
+
+/******************************************************************************
+ *
+ *     SkAddrXmacMcAdd - add a multicast address to a port
+ *
+ * Description:
+ *     This routine enables reception for a given address on the given port.
+ *
+ * Notes:
+ *     The return code is only valid for SK_PROM_MODE_NONE.
+ *
+ *     The multicast bit is only checked if there are no free exact match
+ *     entries.
+ *
+ * Context:
+ *     runtime, pageable
+ *     may be called after SK_INIT_DATA
+ *
+ * Returns:
+ *     SK_MC_FILTERING_EXACT
+ *     SK_MC_FILTERING_INEXACT
+ *     SK_MC_ILLEGAL_ADDRESS
+ *     SK_MC_RLMT_OVERFLOW
+ */
+int    SkAddrXmacMcAdd(
+SK_AC          *pAC,           /* adapter context */
+SK_IOC         IoC,            /* I/O context */
+SK_U32         PortNumber,     /* Port Number */
+SK_MAC_ADDR    *pMc,           /* multicast address to be added */
+int            Flags)          /* permanent/non-permanent */
+{
+       int     i;
+       SK_U8   Inexact;
+#ifndef SK_ADDR_CHEAT
+       SK_U32 HashBit;
+#endif /* !defined(SK_ADDR_CHEAT) */
+
+       if (Flags & SK_ADDR_PERMANENT) {        /* permanent => RLMT */
+#ifdef xDEBUG
+               if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt <
+                       SK_ADDR_FIRST_MATCH_RLMT) {
+                       Next0[PortNumber] |= 1;
+                       return (SK_MC_RLMT_OVERFLOW);
+               }
+#endif /* DEBUG */
+
+               if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt >
+                       SK_ADDR_LAST_MATCH_RLMT) {
+                       return (SK_MC_RLMT_OVERFLOW);
+               }
+
+               /* Set a RLMT multicast address. */
+
+               pAC->Addr.Port[PortNumber].Exact[
+                       pAC->Addr.Port[PortNumber].NextExactMatchRlmt++] = *pMc;
+
+               return (SK_MC_FILTERING_EXACT);
+       }
+
+#ifdef xDEBUG
+       if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <
+               SK_ADDR_FIRST_MATCH_DRV) {
+                       Next0[PortNumber] |= 2;
+               return (SK_MC_RLMT_OVERFLOW);
+       }
+#endif /* DEBUG */
+
+       if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
+
+               /* Set exact match entry. */
+               pAC->Addr.Port[PortNumber].Exact[
+                       pAC->Addr.Port[PortNumber].NextExactMatchDrv++] = *pMc;
+
+               /* Clear InexactFilter */
+               for (i = 0; i < 8; i++) {
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
+               }
+       }
+       else {
+               if (!(pMc->a[0] & SK_MC_BIT)) {
+                       /* Hashing only possible with multicast addresses. */
+                       return (SK_MC_ILLEGAL_ADDRESS);
+               }
+#ifndef SK_ADDR_CHEAT
+               /* Compute hash value of address. */
+               HashBit = 63 - SkXmacMcHash(&pMc->a[0]);
+
+               /* Add bit to InexactFilter. */
+               pAC->Addr.Port[PortNumber].InexactFilter.Bytes[HashBit / 8] |=
+                       1 << (HashBit % 8);
+#else  /* SK_ADDR_CHEAT */
+               /* Set all bits in InexactFilter. */
+               for (i = 0; i < 8; i++) {
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
+               }
+#endif /* SK_ADDR_CHEAT */
+       }
+
+       for (Inexact = 0, i = 0; i < 8; i++) {
+               Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
+       }
+
+       if (Inexact == 0 && pAC->Addr.Port[PortNumber].PromMode == 0) {
+               return (SK_MC_FILTERING_EXACT);
+       }
+       else {
+               return (SK_MC_FILTERING_INEXACT);
+       }
+
+}      /* SkAddrXmacMcAdd */
+
+
+/******************************************************************************
+ *
+ *     SkAddrGmacMcAdd - add a multicast address to a port
+ *
+ * Description:
+ *     This routine enables reception for a given address on the given port.
+ *
+ * Notes:
+ *     The return code is only valid for SK_PROM_MODE_NONE.
+ *
+ * Context:
+ *     runtime, pageable
+ *     may be called after SK_INIT_DATA
+ *
+ * Returns:
+ *     SK_MC_FILTERING_INEXACT
+ *     SK_MC_ILLEGAL_ADDRESS
+ */
+int    SkAddrGmacMcAdd(
+SK_AC          *pAC,           /* adapter context */
+SK_IOC         IoC,            /* I/O context */
+SK_U32         PortNumber,     /* Port Number */
+SK_MAC_ADDR    *pMc,           /* multicast address to be added */
+int            Flags)          /* permanent/non-permanent */
+{
+       int     i;
+#ifndef SK_ADDR_CHEAT
+       SK_U32 HashBit;
+#endif /* !defined(SK_ADDR_CHEAT) */
+
+       if (!(pMc->a[0] & SK_MC_BIT)) {
+               /* Hashing only possible with multicast addresses. */
+               return (SK_MC_ILLEGAL_ADDRESS);
+       }
+
+#ifndef SK_ADDR_CHEAT
+
+       /* Compute hash value of address. */
+       HashBit = SkGmacMcHash(&pMc->a[0]);
+
+       if (Flags & SK_ADDR_PERMANENT) {        /* permanent => RLMT */
+
+               /* Add bit to InexactRlmtFilter. */
+               pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[HashBit / 8] |=
+                       1 << (HashBit % 8);
+
+               /* Copy bit to InexactFilter. */
+               for (i = 0; i < 8; i++) {
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
+                               pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i];
+               }
+#ifdef DEBUG
+               SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+               ("GMAC InexactRlmtFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n",
+                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[0],
+                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[1],
+                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[2],
+                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[3],
+                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[4],
+                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[5],
+                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[6],
+                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7]))
+#endif /* DEBUG */
+       }
+       else {  /* not permanent => DRV */
+
+               /* Add bit to InexactDrvFilter. */
+               pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[HashBit / 8] |=
+                       1 << (HashBit % 8);
+
+               /* Copy bit to InexactFilter. */
+               for (i = 0; i < 8; i++) {
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
+                               pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i];
+               }
+#ifdef DEBUG
+               SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+               ("GMAC InexactDrvFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n",
+                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[0],
+                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[1],
+                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[2],
+                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[3],
+                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[4],
+                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[5],
+                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[6],
+                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7]))
+#endif /* DEBUG */
+       }
+
+#else  /* SK_ADDR_CHEAT */
+
+       /* Set all bits in InexactFilter. */
+       for (i = 0; i < 8; i++) {
+               pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
+       }
+#endif /* SK_ADDR_CHEAT */
+
+       return (SK_MC_FILTERING_INEXACT);
+
+}      /* SkAddrGmacMcAdd */
+
+
+/******************************************************************************
+ *
+ *     SkAddrMcUpdate - update the HW MC address table and set the MAC address
+ *
+ * Description:
+ *     This routine enables reception of the addresses contained in a local
+ *     table for a given port.
+ *     It also programs the port's current physical MAC address.
+ *
+ *     It calls either SkAddrXmacMcUpdate or SkAddrGmacMcUpdate, according
+ *     to the adapter in use. The real work is done there.
+ *
+ * Notes:
+ *     The return code is only valid for SK_PROM_MODE_NONE.
+ *
+ * Context:
+ *     runtime, pageable
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     SK_MC_FILTERING_EXACT
+ *     SK_MC_FILTERING_INEXACT
+ *     SK_ADDR_ILLEGAL_PORT
+ */
+int    SkAddrMcUpdate(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* I/O context */
+SK_U32 PortNumber)     /* Port Number */
+{
+       int ReturnCode;
+
+       if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
+               return (SK_ADDR_ILLEGAL_PORT);
+       }
+
+       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+               ReturnCode = SkAddrXmacMcUpdate(pAC, IoC, PortNumber);
+       }
+       else {
+               ReturnCode = SkAddrGmacMcUpdate(pAC, IoC, PortNumber);
+       }
+
+       return (ReturnCode);
+
+}      /* SkAddrMcUpdate */
+
+
+/******************************************************************************
+ *
+ *     SkAddrXmacMcUpdate - update the HW MC address table and set the MAC address
+ *
+ * Description:
+ *     This routine enables reception of the addresses contained in a local
+ *     table for a given port.
+ *     It also programs the port's current physical MAC address.
+ *
+ * Notes:
+ *     The return code is only valid for SK_PROM_MODE_NONE.
+ *
+ * Context:
+ *     runtime, pageable
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     SK_MC_FILTERING_EXACT
+ *     SK_MC_FILTERING_INEXACT
+ *     SK_ADDR_ILLEGAL_PORT
+ */
+int    SkAddrXmacMcUpdate(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* I/O context */
+SK_U32 PortNumber)     /* Port Number */
+{
+       SK_U32          i;
+       SK_U8           Inexact;
+       SK_U16          *OutAddr;
+       SK_ADDR_PORT    *pAPort;
+
+       SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+               ("SkAddrXmacMcUpdate on Port %u.\n", PortNumber))
+
+       pAPort = &pAC->Addr.Port[PortNumber];
+
+#ifdef DEBUG
+       SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+               ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
+#endif /* DEBUG */
+
+       /* Start with 0 to also program the logical MAC address. */
+       for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
+               /* Set exact match address i on XMAC */
+               OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0];
+               XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
+       }
+
+       /* Clear other permanent exact match addresses on XMAC */
+       if (pAPort->NextExactMatchRlmt <= SK_ADDR_LAST_MATCH_RLMT) {
+
+               SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchRlmt,
+                       SK_ADDR_LAST_MATCH_RLMT);
+       }
+
+       for (i = pAPort->FirstExactMatchDrv; i < pAPort->NextExactMatchDrv; i++) {
+               OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0];
+               XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
+       }
+
+       /* Clear other non-permanent exact match addresses on XMAC */
+       if (pAPort->NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
+
+               SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchDrv,
+                       SK_ADDR_LAST_MATCH_DRV);
+       }
+
+       for (Inexact = 0, i = 0; i < 8; i++) {
+               Inexact |= pAPort->InexactFilter.Bytes[i];
+       }
+
+       if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
+
+               /* Set all bits in 64-bit hash register. */
+               XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
+
+               /* Enable Hashing */
+               SkMacHashing(pAC, IoC, PortNumber, SK_TRUE);
+       }
+       else if (Inexact != 0) {
+
+               /* Set 64-bit hash register to InexactFilter. */
+               XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAPort->InexactFilter.Bytes[0]);
+
+               /* Enable Hashing */
+               SkMacHashing(pAC, IoC, PortNumber, SK_TRUE);
+       }
+       else {
+               /* Disable Hashing */
+               SkMacHashing(pAC, IoC, PortNumber, SK_FALSE);
+       }
+
+       if (pAPort->PromMode != SK_PROM_MODE_NONE) {
+               (void) SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
+       }
+
+       /* Set port's current physical MAC address. */
+       OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
+
+       XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
+
+#ifdef xDEBUG
+       for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
+               SK_U8           InAddr8[6];
+               SK_U16          *InAddr;
+
+               /* Get exact match address i from port PortNumber. */
+               InAddr = (SK_U16 *) &InAddr8[0];
+
+               XM_INADDR(IoC, PortNumber, XM_EXM(i), InAddr);
+
+               SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+                       ("SkAddrXmacMcUpdate: MC address %d on Port %u: ",
+                        "%02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x\n",
+                               i,
+                               PortNumber,
+                               InAddr8[0],
+                               InAddr8[1],
+                               InAddr8[2],
+                               InAddr8[3],
+                               InAddr8[4],
+                               InAddr8[5],
+                               pAPort->Exact[i].a[0],
+                               pAPort->Exact[i].a[1],
+                               pAPort->Exact[i].a[2],
+                               pAPort->Exact[i].a[3],
+                               pAPort->Exact[i].a[4],
+                               pAPort->Exact[i].a[5]))
+       }
+#endif /* DEBUG */
+
+       /* Determine return value. */
+       if (Inexact == 0 && pAPort->PromMode == 0) {
+               return (SK_MC_FILTERING_EXACT);
+       }
+       else {
+               return (SK_MC_FILTERING_INEXACT);
+       }
+
+}      /* SkAddrXmacMcUpdate */
+
+
+/******************************************************************************
+ *
+ *     SkAddrGmacMcUpdate - update the HW MC address table and set the MAC address
+ *
+ * Description:
+ *     This routine enables reception of the addresses contained in a local
+ *     table for a given port.
+ *     It also programs the port's current physical MAC address.
+ *
+ * Notes:
+ *     The return code is only valid for SK_PROM_MODE_NONE.
+ *
+ * Context:
+ *     runtime, pageable
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     SK_MC_FILTERING_EXACT
+ *     SK_MC_FILTERING_INEXACT
+ *     SK_ADDR_ILLEGAL_PORT
+ */
+int    SkAddrGmacMcUpdate(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* I/O context */
+SK_U32 PortNumber)     /* Port Number */
+{
+       SK_U32          i;
+       SK_U8           Inexact;
+       SK_U16          *OutAddr;
+       SK_ADDR_PORT    *pAPort;
+
+       SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+               ("SkAddrGmacMcUpdate on Port %u.\n", PortNumber))
+
+       pAPort = &pAC->Addr.Port[PortNumber];
+
+#ifdef DEBUG
+       SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+               ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
+#endif /* DEBUG */
+
+       for (Inexact = 0, i = 0; i < 8; i++) {
+               Inexact |= pAPort->InexactFilter.Bytes[i];
+       }
+
+       /* Set 64-bit hash register to InexactFilter. */
+       GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1,
+               &pAPort->InexactFilter.Bytes[0]);
+
+       if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
+
+               /* Set all bits in 64-bit hash register. */
+               GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
+
+               /* Enable Hashing */
+               SkMacHashing(pAC, IoC, PortNumber, SK_TRUE);
+       }
+       else {
+               /* Enable Hashing. */
+               SkMacHashing(pAC, IoC, PortNumber, SK_TRUE);
+       }
+
+       if (pAPort->PromMode != SK_PROM_MODE_NONE) {
+               (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
+       }
+
+       /* Set port's current physical MAC address. */
+       OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
+       GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr);
+
+       /* Set port's current logical MAC address. */
+       OutAddr = (SK_U16 *) &pAPort->Exact[0].a[0];
+       GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_2L, OutAddr);
+
+#ifdef DEBUG
+       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+               ("SkAddrGmacMcUpdate: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
+                       pAPort->Exact[0].a[0],
+                       pAPort->Exact[0].a[1],
+                       pAPort->Exact[0].a[2],
+                       pAPort->Exact[0].a[3],
+                       pAPort->Exact[0].a[4],
+                       pAPort->Exact[0].a[5]))
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+               ("SkAddrGmacMcUpdate: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
+                       pAPort->CurrentMacAddress.a[0],
+                       pAPort->CurrentMacAddress.a[1],
+                       pAPort->CurrentMacAddress.a[2],
+                       pAPort->CurrentMacAddress.a[3],
+                       pAPort->CurrentMacAddress.a[4],
+                       pAPort->CurrentMacAddress.a[5]))
+#endif /* DEBUG */
+
+       /* Determine return value. */
+       if (Inexact == 0 && pAPort->PromMode == 0) {
+               return (SK_MC_FILTERING_EXACT);
+       }
+       else {
+               return (SK_MC_FILTERING_INEXACT);
+       }
+
+}      /* SkAddrGmacMcUpdate */
+
+
+/******************************************************************************
+ *
+ *     SkAddrOverride - override a port's MAC address
+ *
+ * Description:
+ *     This routine overrides the MAC address of one port.
+ *
+ * Context:
+ *     runtime, pageable
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     SK_ADDR_SUCCESS if successful.
+ *     SK_ADDR_DUPLICATE_ADDRESS if duplicate MAC address.
+ *     SK_ADDR_MULTICAST_ADDRESS if multicast or broadcast address.
+ *     SK_ADDR_TOO_EARLY if SK_INIT_IO was not executed before.
+ */
+int    SkAddrOverride(
+SK_AC          *pAC,           /* adapter context */
+SK_IOC         IoC,            /* I/O context */
+SK_U32         PortNumber,     /* Port Number */
+SK_MAC_ADDR    *pNewAddr,      /* new MAC address */
+int                    Flags)          /* logical/physical MAC address */
+{
+       SK_EVPARA       Para;
+       SK_U32          NetNumber;
+       SK_U32          i;
+       SK_U16          *OutAddr;
+
+       NetNumber = pAC->Rlmt.Port[PortNumber].Net->NetNumber;
+
+       if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
+               return (SK_ADDR_ILLEGAL_PORT);
+       }
+
+       if (pNewAddr != NULL && (pNewAddr->a[0] & SK_MC_BIT) != 0) {
+               return (SK_ADDR_MULTICAST_ADDRESS);
+       }
+
+       if (!pAC->Addr.Net[NetNumber].CurrentMacAddressSet) {
+               return (SK_ADDR_TOO_EARLY);
+       }
+
+       if (Flags & SK_ADDR_SET_LOGICAL) {      /* Activate logical MAC address. */
+               /* Parameter *pNewAddr is ignored. */
+               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
+                       if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
+                               return (SK_ADDR_TOO_EARLY);
+                       }
+               }
+
+               /* Set PortNumber to number of net's active port. */
+               PortNumber = pAC->Rlmt.Net[NetNumber].
+                       Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
+
+               pAC->Addr.Port[PortNumber].Exact[0] =
+                       pAC->Addr.Net[NetNumber].CurrentMacAddress;
+
+               /* Write address to first exact match entry of active port. */
+               (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
+       }
+       else if (Flags & SK_ADDR_CLEAR_LOGICAL) {
+               /* Deactivate logical MAC address. */
+               /* Parameter *pNewAddr is ignored. */
+               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
+                       if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
+                               return (SK_ADDR_TOO_EARLY);
+                       }
+               }
+
+               /* Set PortNumber to number of net's active port. */
+               PortNumber = pAC->Rlmt.Net[NetNumber].
+                       Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
+
+               for (i = 0; i < SK_MAC_ADDR_LEN; i++ ) {
+                       pAC->Addr.Port[PortNumber].Exact[0].a[i] = 0;
+               }
+
+               /* Write address to first exact match entry of active port. */
+               (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
+       }
+       else if (Flags & SK_ADDR_PHYSICAL_ADDRESS) {    /* Physical MAC address. */
+               if (SK_ADDR_EQUAL(pNewAddr->a,
+                       pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
+                       return (SK_ADDR_DUPLICATE_ADDRESS);
+               }
+
+               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
+                       if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
+                               return (SK_ADDR_TOO_EARLY);
+                       }
+
+                       if (SK_ADDR_EQUAL(pNewAddr->a,
+                               pAC->Addr.Port[i].CurrentMacAddress.a)) {
+                               if (i == PortNumber) {
+                                       return (SK_ADDR_SUCCESS);
+                               }
+                               else {
+                                       return (SK_ADDR_DUPLICATE_ADDRESS);
+                               }
+                       }
+               }
+
+               pAC->Addr.Port[PortNumber].PreviousMacAddress =
+                       pAC->Addr.Port[PortNumber].CurrentMacAddress;
+               pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;
+
+               /* Change port's physical MAC address. */
+               OutAddr = (SK_U16 *) pNewAddr;
+
+               if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+                       XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
+               }
+               else {
+                       GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr);
+               }
+
+               /* Report address change to RLMT. */
+               Para.Para32[0] = PortNumber;
+               Para.Para32[0] = -1;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
+       }
+       else {  /* Logical MAC address. */
+               if (SK_ADDR_EQUAL(pNewAddr->a,
+                       pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
+                       return (SK_ADDR_SUCCESS);
+               }
+
+               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
+                       if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
+                               return (SK_ADDR_TOO_EARLY);
+                       }
+
+                       if (SK_ADDR_EQUAL(pNewAddr->a,
+                               pAC->Addr.Port[i].CurrentMacAddress.a)) {
+                               return (SK_ADDR_DUPLICATE_ADDRESS);
+                       }
+               }
+
+               /*
+                * In case that the physical and the logical MAC addresses are equal
+                * we must also change the physical MAC address here.
+                * In this case we have an adapter which initially was programmed with
+                * two identical MAC addresses.
+                */
+               if (SK_ADDR_EQUAL(pAC->Addr.Port[PortNumber].CurrentMacAddress.a,
+                               pAC->Addr.Port[PortNumber].Exact[0].a)) {
+
+                       pAC->Addr.Port[PortNumber].PreviousMacAddress =
+                               pAC->Addr.Port[PortNumber].CurrentMacAddress;
+                       pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;
+
+                       /* Report address change to RLMT. */
+                       Para.Para32[0] = PortNumber;
+                       Para.Para32[0] = -1;
+                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
+               }
+
+               /* Set PortNumber to number of net's active port. */
+               PortNumber = pAC->Rlmt.Net[NetNumber].
+                       Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
+
+               pAC->Addr.Net[NetNumber].CurrentMacAddress = *pNewAddr;
+               pAC->Addr.Port[PortNumber].Exact[0] = *pNewAddr;
+#ifdef DEBUG
+               SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+                       ("SkAddrOverride: Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n",
+                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[0],
+                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[1],
+                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[2],
+                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[3],
+                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[4],
+                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5]))
+
+               SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+                       ("SkAddrOverride: New logical MAC Address: %02X %02X %02X %02X %02X %02X\n",
+                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[0],
+                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[1],
+                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[2],
+                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[3],
+                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[4],
+                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5]))
+#endif /* DEBUG */
+
+       /* Write address to first exact match entry of active port. */
+               (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
+       }
+
+       return (SK_ADDR_SUCCESS);
+
+}      /* SkAddrOverride */
+
+
+/******************************************************************************
+ *
+ *     SkAddrPromiscuousChange - set promiscuous mode for given port
+ *
+ * Description:
+ *     This routine manages promiscuous mode:
+ *     - none
+ *     - all LLC frames
+ *     - all MC frames
+ *
+ *     It calls either SkAddrXmacPromiscuousChange or
+ *     SkAddrGmacPromiscuousChange, according to the adapter in use.
+ *     The real work is done there.
+ *
+ * Context:
+ *     runtime, pageable
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     SK_ADDR_SUCCESS
+ *     SK_ADDR_ILLEGAL_PORT
+ */
+int    SkAddrPromiscuousChange(
+SK_AC  *pAC,                   /* adapter context */
+SK_IOC IoC,                    /* I/O context */
+SK_U32 PortNumber,             /* port whose promiscuous mode changes */
+int            NewPromMode)    /* new promiscuous mode */
+{
+       int ReturnCode;
+
+       if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
+               return (SK_ADDR_ILLEGAL_PORT);
+       }
+
+       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+               ReturnCode = SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode);
+       }
+       else {
+               ReturnCode = SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode);
+       }
+
+       return (ReturnCode);
+
+}      /* SkAddrPromiscuousChange */
+
+
+/******************************************************************************
+ *
+ *     SkAddrXmacPromiscuousChange - set promiscuous mode for given port
+ *
+ * Description:
+ *     This routine manages promiscuous mode:
+ *     - none
+ *     - all LLC frames
+ *     - all MC frames
+ *
+ * Context:
+ *     runtime, pageable
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     SK_ADDR_SUCCESS
+ *     SK_ADDR_ILLEGAL_PORT
+ */
+int    SkAddrXmacPromiscuousChange(
+SK_AC  *pAC,                   /* adapter context */
+SK_IOC IoC,                    /* I/O context */
+SK_U32 PortNumber,             /* port whose promiscuous mode changes */
+int            NewPromMode)    /* new promiscuous mode */
+{
+       int                     i;
+       SK_BOOL         InexactModeBit;
+       SK_U8           Inexact;
+       SK_U8           HwInexact;
+       SK_FILTER64     HwInexactFilter;
+       SK_U16          LoMode;         /* Lower 16 bits of XMAC Mode Register. */
+       int                     CurPromMode = SK_PROM_MODE_NONE;
+
+       /* Read CurPromMode from Hardware. */
+       XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
+
+       if ((LoMode & XM_MD_ENA_PROM) != 0) {
+               /* Promiscuous mode! */
+               CurPromMode |= SK_PROM_MODE_LLC;
+       }
+
+       for (Inexact = 0xFF, i = 0; i < 8; i++) {
+               Inexact &= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
+       }
+       if (Inexact == 0xFF) {
+               CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
+       }
+       else {
+               /* Get InexactModeBit (bit XM_MD_ENA_HASH in mode register) */
+               XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
+
+               InexactModeBit = (LoMode & XM_MD_ENA_HASH) != 0;
+
+               /* Read 64-bit hash register from XMAC */
+               XM_INHASH(IoC, PortNumber, XM_HSM, &HwInexactFilter.Bytes[0]);
+
+               for (HwInexact = 0xFF, i = 0; i < 8; i++) {
+                       HwInexact &= HwInexactFilter.Bytes[i];
+               }
+
+               if (InexactModeBit && (HwInexact == 0xFF)) {
+                       CurPromMode |= SK_PROM_MODE_ALL_MC;
+               }
+       }
+
+       pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
+
+       if (NewPromMode == CurPromMode) {
+               return (SK_ADDR_SUCCESS);
+       }
+
+       if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
+               !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC. */
+
+               /* Set all bits in 64-bit hash register. */
+               XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
+
+               /* Enable Hashing */
+               SkMacHashing(pAC, IoC, PortNumber, SK_TRUE);
+       }
+       else if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
+               !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm MC. */
+               for (Inexact = 0, i = 0; i < 8; i++) {
+                       Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
+               }
+               if (Inexact == 0) {
+                       /* Disable Hashing */
+                       SkMacHashing(pAC, IoC, PortNumber, SK_FALSE);
+               }
+               else {
+                       /* Set 64-bit hash register to InexactFilter. */
+                       XM_OUTHASH(IoC, PortNumber, XM_HSM,
+                               &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
+
+                       /* Enable Hashing */
+                       SkMacHashing(pAC, IoC, PortNumber, SK_TRUE);
+               }
+       }
+
+       if ((NewPromMode & SK_PROM_MODE_LLC) &&
+               !(CurPromMode & SK_PROM_MODE_LLC)) {    /* Prom. LLC */
+               /* Set the MAC in Promiscuous Mode */
+               SkMacPromiscMode(pAC, IoC, PortNumber, SK_TRUE);
+       }
+       else if ((CurPromMode & SK_PROM_MODE_LLC) &&
+               !(NewPromMode & SK_PROM_MODE_LLC)) {    /* Norm. LLC. */
+               /* Clear Promiscuous Mode */
+               SkMacPromiscMode(pAC, IoC, PortNumber, SK_FALSE);
+       }
+
+       return (SK_ADDR_SUCCESS);
+
+}      /* SkAddrXmacPromiscuousChange */
+
+
+/******************************************************************************
+ *
+ *     SkAddrGmacPromiscuousChange - set promiscuous mode for given port
+ *
+ * Description:
+ *     This routine manages promiscuous mode:
+ *     - none
+ *     - all LLC frames
+ *     - all MC frames
+ *
+ * Context:
+ *     runtime, pageable
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     SK_ADDR_SUCCESS
+ *     SK_ADDR_ILLEGAL_PORT
+ */
+int    SkAddrGmacPromiscuousChange(
+SK_AC  *pAC,                   /* adapter context */
+SK_IOC IoC,                    /* I/O context */
+SK_U32 PortNumber,             /* port whose promiscuous mode changes */
+int            NewPromMode)    /* new promiscuous mode */
+{
+       SK_U16          ReceiveControl; /* GMAC Receive Control Register */
+       int             CurPromMode = SK_PROM_MODE_NONE;
+
+       /* Read CurPromMode from Hardware. */
+       GM_IN16(IoC, PortNumber, GM_RX_CTRL, &ReceiveControl);
+
+       if ((ReceiveControl & (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA)) == 0) {
+               /* Promiscuous mode! */
+               CurPromMode |= SK_PROM_MODE_LLC;
+       }
+
+       if ((ReceiveControl & GM_RXCR_MCF_ENA) == 0) {
+               /* All Multicast mode! */
+               CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
+       }
+
+       pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
+
+       if (NewPromMode == CurPromMode) {
+               return (SK_ADDR_SUCCESS);
+       }
+
+       if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
+               !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC */
+
+               /* Set all bits in 64-bit hash register. */
+               GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
+
+               /* Enable Hashing */
+               SkMacHashing(pAC, IoC, PortNumber, SK_TRUE);
+       }
+
+       if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
+               !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm. MC */
+
+               /* Set 64-bit hash register to InexactFilter. */
+               GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1,
+                       &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
+
+               /* Enable Hashing. */
+               SkMacHashing(pAC, IoC, PortNumber, SK_TRUE);
+       }
+
+       if ((NewPromMode & SK_PROM_MODE_LLC) &&
+               !(CurPromMode & SK_PROM_MODE_LLC)) {    /* Prom. LLC */
+
+               /* Set the MAC to Promiscuous Mode. */
+               SkMacPromiscMode(pAC, IoC, PortNumber, SK_TRUE);
+       }
+       else if ((CurPromMode & SK_PROM_MODE_LLC) &&
+               !(NewPromMode & SK_PROM_MODE_LLC)) {    /* Norm. LLC */
+
+               /* Clear Promiscuous Mode. */
+               SkMacPromiscMode(pAC, IoC, PortNumber, SK_FALSE);
+       }
+
+       return (SK_ADDR_SUCCESS);
+
+}      /* SkAddrGmacPromiscuousChange */
+
+
+/******************************************************************************
+ *
+ *     SkAddrSwap - swap address info
+ *
+ * Description:
+ *     This routine swaps address info of two ports.
+ *
+ * Context:
+ *     runtime, pageable
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     SK_ADDR_SUCCESS
+ *     SK_ADDR_ILLEGAL_PORT
+ */
+int    SkAddrSwap(
+SK_AC  *pAC,                   /* adapter context */
+SK_IOC IoC,                    /* I/O context */
+SK_U32 FromPortNumber,         /* Port1 Index */
+SK_U32 ToPortNumber)           /* Port2 Index */
+{
+       int                     i;
+       SK_U8           Byte;
+       SK_MAC_ADDR     MacAddr;
+       SK_U32          DWord;
+
+       if (FromPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
+               return (SK_ADDR_ILLEGAL_PORT);
+       }
+
+       if (ToPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
+               return (SK_ADDR_ILLEGAL_PORT);
+       }
+
+       if (pAC->Rlmt.Port[FromPortNumber].Net != pAC->Rlmt.Port[ToPortNumber].Net) {
+               return (SK_ADDR_ILLEGAL_PORT);
+       }
+
+       /*
+        * Swap:
+        * - Exact Match Entries (GEnesis and Yukon)
+        *   Yukon uses first entry for the logical MAC
+        *   address (stored in the second GMAC register).
+        * - FirstExactMatchRlmt (GEnesis only)
+        * - NextExactMatchRlmt (GEnesis only)
+        * - FirstExactMatchDrv (GEnesis only)
+        * - NextExactMatchDrv (GEnesis only)
+        * - 64-bit filter (InexactFilter)
+        * - Promiscuous Mode
+        * of ports.
+        */
+
+       for (i = 0; i < SK_ADDR_EXACT_MATCHES; i++) {
+               MacAddr = pAC->Addr.Port[FromPortNumber].Exact[i];
+               pAC->Addr.Port[FromPortNumber].Exact[i] =
+                       pAC->Addr.Port[ToPortNumber].Exact[i];
+               pAC->Addr.Port[ToPortNumber].Exact[i] = MacAddr;
+       }
+
+       for (i = 0; i < 8; i++) {
+               Byte = pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i];
+               pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i] =
+                       pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i];
+               pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i] = Byte;
+       }
+
+       i = pAC->Addr.Port[FromPortNumber].PromMode;
+       pAC->Addr.Port[FromPortNumber].PromMode = pAC->Addr.Port[ToPortNumber].PromMode;
+       pAC->Addr.Port[ToPortNumber].PromMode = i;
+
+       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+               DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt;
+               pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt =
+                       pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt;
+               pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt = DWord;
+
+               DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt;
+               pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt =
+                       pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt;
+               pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt = DWord;
+
+               DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv;
+               pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv =
+                       pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv;
+               pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv = DWord;
+
+               DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchDrv;
+               pAC->Addr.Port[FromPortNumber].NextExactMatchDrv =
+                       pAC->Addr.Port[ToPortNumber].NextExactMatchDrv;
+               pAC->Addr.Port[ToPortNumber].NextExactMatchDrv = DWord;
+       }
+
+       /* CAUTION: Solution works if only ports of one adapter are in use. */
+       for (i = 0; (SK_U32) i < pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].
+               Net->NetNumber].NumPorts; i++) {
+               if (pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
+                       Port[i]->PortNumber == ToPortNumber) {
+                       pAC->Addr.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
+                               ActivePort = i;
+                       /* 20001207 RA: Was "ToPortNumber;". */
+               }
+       }
+
+       (void) SkAddrMcUpdate(pAC, IoC, FromPortNumber);
+       (void) SkAddrMcUpdate(pAC, IoC, ToPortNumber);
+
+       return (SK_ADDR_SUCCESS);
+
+}      /* SkAddrSwap */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* CONFIG_SK98 */
diff --git a/drivers/net/sk98lin/skcsum.c b/drivers/net/sk98lin/skcsum.c
new file mode 100644 (file)
index 0000000..a5dc572
--- /dev/null
@@ -0,0 +1,929 @@
+/******************************************************************************
+ *
+ * Name:       skcsum.c
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.10 $
+ * Date:       $Date: 2002/04/11 10:02:04 $
+ * Purpose:    Store/verify Internet checksum in send/receive packets.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2001 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skcsum.c,v $
+ *     Revision 1.10  2002/04/11 10:02:04  rwahl
+ *     Fix in SkCsGetSendInfo():
+ *     - function did not return ProtocolFlags in every case.
+ *     - pseudo header csum calculated wrong for big endian.
+ *
+ *     Revision 1.9  2001/06/13 07:42:08  gklug
+ *     fix: NetNumber was wrong in CLEAR_STAT event
+ *     add: check for good NetNumber in Clear STAT
+ *
+ *     Revision 1.8  2001/02/06 11:15:36  rassmann
+ *     Supporting two nets on dual-port adapters.
+ *
+ *     Revision 1.7  2000/06/29 13:17:05  rassmann
+ *     Corrected reception of a packet with UDP checksum == 0 (which means there
+ *     is no UDP checksum).
+ *
+ *     Revision 1.6  2000/02/21 12:35:10  cgoos
+ *     Fixed license header comment.
+ *
+ *     Revision 1.5  2000/02/21 11:05:19  cgoos
+ *     Merged changes back to common source.
+ *     Fixed rx path for BIG ENDIAN architecture.
+ *
+ *     Revision 1.1  1999/07/26 15:28:12  mkarl
+ *     added return SKCS_STATUS_IP_CSUM_ERROR_UDP and
+ *     SKCS_STATUS_IP_CSUM_ERROR_TCP to pass the NidsTester
+ *     changed from common source to windows specific source
+ *     therefore restarting with v1.0
+ *
+ *     Revision 1.3  1999/05/10 08:39:33  mkarl
+ *     prevent overflows in SKCS_HTON16
+ *     fixed a bug in pseudo header checksum calculation
+ *     added some comments
+ *
+ *     Revision 1.2  1998/10/22 11:53:28  swolf
+ *     Now using SK_DBG_MSG.
+ *
+ *     Revision 1.1  1998/09/01 15:35:41  swolf
+ *     initial revision
+ *
+ *     13-May-1998 sw  Created.
+ *
+ ******************************************************************************/
+
+#include <config.h>
+
+#ifdef CONFIG_SK98
+
+#ifdef SK_USE_CSUM     /* Check if CSUM is to be used. */
+
+#ifndef lint
+static const char SysKonnectFileId[] = "@(#)"
+       "$Id: skcsum.c,v 1.10 2002/04/11 10:02:04 rwahl Exp $"
+       " (C) SysKonnect.";
+#endif /* !lint */
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * This is the "GEnesis" common module "CSUM".
+ *
+ * This module contains the code necessary to calculate, store, and verify the
+ * Internet Checksum of IP, TCP, and UDP frames.
+ *
+ * "GEnesis" is an abbreviation of "Gigabit Ethernet Network System in Silicon"
+ * and is the code name of this SysKonnect project.
+ *
+ * Compilation Options:
+ *
+ *     SK_USE_CSUM - Define if CSUM is to be used. Otherwise, CSUM will be an
+ *     empty module.
+ *
+ *     SKCS_OVERWRITE_PROTO - Define to overwrite the default protocol id
+ *     definitions. In this case, all SKCS_PROTO_xxx definitions must be made
+ *     external.
+ *
+ *     SKCS_OVERWRITE_STATUS - Define to overwrite the default return status
+ *     definitions. In this case, all SKCS_STATUS_xxx definitions must be made
+ *     external.
+ *
+ * Include File Hierarchy:
+ *
+ *     "h/skdrv1st.h"
+ *     "h/skcsum.h"
+ *      "h/sktypes.h"
+ *      "h/skqueue.h"
+ *     "h/skdrv2nd.h"
+ *
+ ******************************************************************************/
+
+#include "h/skdrv1st.h"
+#include "h/skcsum.h"
+#include "h/skdrv2nd.h"
+
+/* defines ********************************************************************/
+
+/* The size of an Ethernet MAC header. */
+#define SKCS_ETHERNET_MAC_HEADER_SIZE                  (6+6+2)
+
+/* The size of the used topology's MAC header. */
+#define        SKCS_MAC_HEADER_SIZE    SKCS_ETHERNET_MAC_HEADER_SIZE
+
+/* The size of the IP header without any option fields. */
+#define SKCS_IP_HEADER_SIZE                                            20
+
+/*
+ * Field offsets within the IP header.
+ */
+
+/* "Internet Header Version" and "Length". */
+#define SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH  0
+
+/* "Total Length". */
+#define SKCS_OFS_IP_TOTAL_LENGTH                               2
+
+/* "Flags" "Fragment Offset". */
+#define SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET  6
+
+/* "Next Level Protocol" identifier. */
+#define SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL                        9
+
+/* Source IP address. */
+#define SKCS_OFS_IP_SOURCE_ADDRESS                             12
+
+/* Destination IP address. */
+#define SKCS_OFS_IP_DESTINATION_ADDRESS                        16
+
+
+/*
+ * Field offsets within the UDP header.
+ */
+
+/* UDP checksum. */
+#define SKCS_OFS_UDP_CHECKSUM                                  6
+
+/* IP "Next Level Protocol" identifiers (see RFC 790). */
+#define SKCS_PROTO_ID_TCP              6       /* Transport Control Protocol */
+#define SKCS_PROTO_ID_UDP              17      /* User Datagram Protocol */
+
+/* IP "Don't Fragment" bit. */
+#define SKCS_IP_DONT_FRAGMENT  SKCS_HTON16(0x4000)
+
+/* Add a byte offset to a pointer. */
+#define SKCS_IDX(pPtr, Ofs)    ((void *) ((char *) (pPtr) + (Ofs)))
+
+/*
+ * Macros that convert host to network representation and vice versa, i.e.
+ * little/big endian conversion on little endian machines only.
+ */
+#ifdef SK_LITTLE_ENDIAN
+#define SKCS_HTON16(Val16)     (((unsigned) (Val16) >> 8) | (((Val16) & 0xFF) << 8))
+#endif /* SK_LITTLE_ENDIAN */
+#ifdef SK_BIG_ENDIAN
+#define SKCS_HTON16(Val16)     (Val16)
+#endif /* SK_BIG_ENDIAN */
+#define SKCS_NTOH16(Val16)     SKCS_HTON16(Val16)
+
+/* typedefs *******************************************************************/
+
+/* function prototypes ********************************************************/
+
+/******************************************************************************
+ *
+ *     SkCsGetSendInfo - get checksum information for a send packet
+ *
+ * Description:
+ *     Get all checksum information necessary to send a TCP or UDP packet. The
+ *     function checks the IP header passed to it. If the high-level protocol
+ *     is either TCP or UDP the pseudo header checksum is calculated and
+ *     returned.
+ *
+ *     The function returns the total length of the IP header (including any
+ *     IP option fields), which is the same as the start offset of the IP data
+ *     which in turn is the start offset of the TCP or UDP header.
+ *
+ *     The function also returns the TCP or UDP pseudo header checksum, which
+ *     should be used as the start value for the hardware checksum calculation.
+ *     (Note that any actual pseudo header checksum can never calculate to
+ *     zero.)
+ *
+ * Note:
+ *     There is a bug in the ASIC which may lead to wrong checksums.
+ *
+ * Arguments:
+ *     pAc - A pointer to the adapter context struct.
+ *
+ *     pIpHeader - Pointer to IP header. Must be at least the IP header *not*
+ *     including any option fields, i.e. at least 20 bytes.
+ *
+ *     Note: This pointer will be used to address 8-, 16-, and 32-bit
+ *     variables with the respective alignment offsets relative to the pointer.
+ *     Thus, the pointer should point to a 32-bit aligned address. If the
+ *     target system cannot address 32-bit variables on non 32-bit aligned
+ *     addresses, then the pointer *must* point to a 32-bit aligned address.
+ *
+ *     pPacketInfo - A pointer to the packet information structure for this
+ *     packet. Before calling this SkCsGetSendInfo(), the following field must
+ *     be initialized:
+ *
+ *             ProtocolFlags - Initialize with any combination of
+ *             SKCS_PROTO_XXX bit flags. SkCsGetSendInfo() will only work on
+ *             the protocols specified here. Any protocol(s) not specified
+ *             here will be ignored.
+ *
+ *             Note: Only one checksum can be calculated in hardware. Thus, if
+ *             SKCS_PROTO_IP is specified in the 'ProtocolFlags',
+ *             SkCsGetSendInfo() must calculate the IP header checksum in
+ *             software. It might be a better idea to have the calling
+ *             protocol stack calculate the IP header checksum.
+ *
+ * Returns: N/A
+ *     On return, the following fields in 'pPacketInfo' may or may not have
+ *     been filled with information, depending on the protocol(s) found in the
+ *     packet:
+ *
+ *     ProtocolFlags - Returns the SKCS_PROTO_XXX bit flags of the protocol(s)
+ *     that were both requested by the caller and actually found in the packet.
+ *     Protocol(s) not specified by the caller and/or not found in the packet
+ *     will have their respective SKCS_PROTO_XXX bit flags reset.
+ *
+ *     Note: For IP fragments, TCP and UDP packet information is ignored.
+ *
+ *     IpHeaderLength - The total length in bytes of the complete IP header
+ *     including any option fields is returned here. This is the start offset
+ *     of the IP data, i.e. the TCP or UDP header if present.
+ *
+ *     IpHeaderChecksum - If IP has been specified in the 'ProtocolFlags', the
+ *     16-bit Internet Checksum of the IP header is returned here. This value
+ *     is to be stored into the packet's 'IP Header Checksum' field.
+ *
+ *     PseudoHeaderChecksum - If this is a TCP or UDP packet and if TCP or UDP
+ *     has been specified in the 'ProtocolFlags', the 16-bit Internet Checksum
+ *     of the TCP or UDP pseudo header is returned here.
+ */
+#if 0
+void SkCsGetSendInfo(
+SK_AC                          *pAc,                   /* Adapter context struct. */
+void                           *pIpHeader,             /* IP header. */
+SKCS_PACKET_INFO       *pPacketInfo,   /* Packet information struct. */
+int                                    NetNumber)              /* Net number */
+{
+       /* Internet Header Version found in IP header. */
+       unsigned InternetHeaderVersion;
+
+       /* Length of the IP header as found in IP header. */
+       unsigned IpHeaderLength;
+
+       /* Bit field specifiying the desired/found protocols. */
+       unsigned ProtocolFlags;
+
+       /* Next level protocol identifier found in IP header. */
+       unsigned NextLevelProtocol;
+
+       /* Length of IP data portion. */
+       unsigned IpDataLength;
+
+       /* TCP/UDP pseudo header checksum. */
+       unsigned long PseudoHeaderChecksum;
+
+       /* Pointer to next level protocol statistics structure. */
+       SKCS_PROTO_STATS *NextLevelProtoStats;
+
+       /* Temporary variable. */
+       unsigned Tmp;
+
+       Tmp = *(SK_U8 *)
+               SKCS_IDX(pIpHeader, SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH);
+
+       /* Get the Internet Header Version (IHV). */
+       /* Note: The IHV is stored in the upper four bits. */
+
+       InternetHeaderVersion = Tmp >> 4;
+
+       /* Check the Internet Header Version. */
+       /* Note: We currently only support IP version 4. */
+
+       if (InternetHeaderVersion != 4) {       /* IPv4? */
+               SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_TX,
+                       ("Tx: Unknown Internet Header Version %u.\n",
+                       InternetHeaderVersion));
+               pPacketInfo->ProtocolFlags = 0;
+               pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxUnableCts++;
+               return;
+       }
+
+       /* Get the IP header length (IHL). */
+       /*
+        * Note: The IHL is stored in the lower four bits as the number of
+        * 4-byte words.
+        */
+
+       IpHeaderLength = (Tmp & 0xf) * 4;
+       pPacketInfo->IpHeaderLength = IpHeaderLength;
+
+       /* Check the IP header length. */
+
+       /* 04-Aug-1998 sw - Really check the IHL? Necessary? */
+
+       if (IpHeaderLength < 5*4) {
+               SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_TX,
+                       ("Tx: Invalid IP Header Length %u.\n", IpHeaderLength));
+               pPacketInfo->ProtocolFlags = 0;
+               pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxUnableCts++;
+               return;
+       }
+
+       /* This is an IPv4 frame with a header of valid length. */
+
+       pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxOkCts++;
+
+       /* Check if we should calculate the IP header checksum. */
+
+       ProtocolFlags = pPacketInfo->ProtocolFlags;
+
+       if (ProtocolFlags & SKCS_PROTO_IP) {
+               pPacketInfo->IpHeaderChecksum =
+                       SkCsCalculateChecksum(pIpHeader, IpHeaderLength);
+       }
+
+       /* Get the next level protocol identifier. */
+
+       NextLevelProtocol =
+               *(SK_U8 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL);
+
+       /*
+        * Check if this is a TCP or UDP frame and if we should calculate the
+        * TCP/UDP pseudo header checksum.
+        *
+        * Also clear all protocol bit flags of protocols not present in the
+        * frame.
+        */
+
+       if ((ProtocolFlags & SKCS_PROTO_TCP) != 0 &&
+               NextLevelProtocol == SKCS_PROTO_ID_TCP) {
+               /* TCP/IP frame. */
+               ProtocolFlags &= SKCS_PROTO_TCP | SKCS_PROTO_IP;
+               NextLevelProtoStats =
+                       &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_TCP];
+       }
+       else if ((ProtocolFlags & SKCS_PROTO_UDP) != 0 &&
+               NextLevelProtocol == SKCS_PROTO_ID_UDP) {
+               /* UDP/IP frame. */
+               ProtocolFlags &= SKCS_PROTO_UDP | SKCS_PROTO_IP;
+               NextLevelProtoStats =
+                       &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_UDP];
+       }
+       else {
+               /*
+                * Either not a TCP or UDP frame and/or TCP/UDP processing not
+                * specified.
+                */
+               pPacketInfo->ProtocolFlags = ProtocolFlags & SKCS_PROTO_IP;
+               return;
+       }
+
+       /* Check if this is an IP fragment. */
+
+       /*
+        * Note: An IP fragment has a non-zero "Fragment Offset" field and/or
+        * the "More Fragments" bit set. Thus, if both the "Fragment Offset"
+        * and the "More Fragments" are zero, it is *not* a fragment. We can
+        * easily check both at the same time since they are in the same 16-bit
+        * word.
+        */
+
+       if ((*(SK_U16 *)
+               SKCS_IDX(pIpHeader, SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET) &
+               ~SKCS_IP_DONT_FRAGMENT) != 0) {
+               /* IP fragment; ignore all other protocols. */
+               pPacketInfo->ProtocolFlags = ProtocolFlags & SKCS_PROTO_IP;
+               NextLevelProtoStats->TxUnableCts++;
+               return;
+       }
+
+       /*
+        * Calculate the TCP/UDP pseudo header checksum.
+        */
+
+       /* Get total length of IP header and data. */
+
+       IpDataLength =
+               *(SK_U16 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_TOTAL_LENGTH);
+
+       /* Get length of IP data portion. */
+
+       IpDataLength = SKCS_NTOH16(IpDataLength) - IpHeaderLength;
+
+       /* Calculate the sum of all pseudo header fields (16-bit). */
+
+       PseudoHeaderChecksum =
+               (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
+                       SKCS_OFS_IP_SOURCE_ADDRESS + 0) +
+               (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
+                       SKCS_OFS_IP_SOURCE_ADDRESS + 2) +
+               (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
+                       SKCS_OFS_IP_DESTINATION_ADDRESS + 0) +
+               (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
+                       SKCS_OFS_IP_DESTINATION_ADDRESS + 2) +
+               (unsigned long) SKCS_HTON16(NextLevelProtocol) +
+               (unsigned long) SKCS_HTON16(IpDataLength);
+
+       /* Add-in any carries. */
+
+       SKCS_OC_ADD(PseudoHeaderChecksum, PseudoHeaderChecksum, 0);
+
+       /* Add-in any new carry. */
+
+       SKCS_OC_ADD(pPacketInfo->PseudoHeaderChecksum, PseudoHeaderChecksum, 0);
+
+       pPacketInfo->ProtocolFlags = ProtocolFlags;
+       NextLevelProtoStats->TxOkCts++; /* Success. */
+}      /* SkCsGetSendInfo */
+
+
+/******************************************************************************
+ *
+ *     SkCsGetReceiveInfo - verify checksum information for a received packet
+ *
+ * Description:
+ *     Verify a received frame's checksum. The function returns a status code
+ *     reflecting the result of the verification.
+ *
+ * Note:
+ *     Before calling this function you have to verify that the frame is
+ *     not padded and Checksum1 and Checksum2 are bigger than 1.
+ *
+ * Arguments:
+ *     pAc - Pointer to adapter context struct.
+ *
+ *     pIpHeader - Pointer to IP header. Must be at least the length in bytes
+ *     of the received IP header including any option fields. For UDP packets,
+ *     8 additional bytes are needed to access the UDP checksum.
+ *
+ *     Note: The actual length of the IP header is stored in the lower four
+ *     bits of the first octet of the IP header as the number of 4-byte words,
+ *     so it must be multiplied by four to get the length in bytes. Thus, the
+ *     maximum IP header length is 15 * 4 = 60 bytes.
+ *
+ *     Checksum1 - The first 16-bit Internet Checksum calculated by the
+ *     hardware starting at the offset returned by SkCsSetReceiveFlags().
+ *
+ *     Checksum2 - The second 16-bit Internet Checksum calculated by the
+ *     hardware starting at the offset returned by SkCsSetReceiveFlags().
+ *
+ * Returns:
+ *     SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.
+ *     SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.
+ *     SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.
+ *     SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame
+ *     SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).
+ *     SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).
+ *     SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).
+ *     SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).
+ *     SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.
+ *     SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.
+ *     SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum.
+ *
+ *     Note: If SKCS_OVERWRITE_STATUS is defined, the SKCS_STATUS_XXX values
+ *     returned here can be defined in some header file by the module using CSUM.
+ *     In this way, the calling module can assign return values for its own needs,
+ *     e.g. by assigning bit flags to the individual protocols.
+ */
+SKCS_STATUS SkCsGetReceiveInfo(
+SK_AC          *pAc,           /* Adapter context struct. */
+void           *pIpHeader,     /* IP header. */
+unsigned       Checksum1,      /* Hardware checksum 1. */
+unsigned       Checksum2,      /* Hardware checksum 2. */
+int                    NetNumber)      /* Net number */
+{
+       /* Internet Header Version found in IP header. */
+       unsigned InternetHeaderVersion;
+
+       /* Length of the IP header as found in IP header. */
+       unsigned IpHeaderLength;
+
+       /* Length of IP data portion. */
+       unsigned IpDataLength;
+
+       /* IP header checksum. */
+       unsigned IpHeaderChecksum;
+
+       /* IP header options checksum, if any. */
+       unsigned IpOptionsChecksum;
+
+       /* IP data checksum, i.e. TCP/UDP checksum. */
+       unsigned IpDataChecksum;
+
+       /* Next level protocol identifier found in IP header. */
+       unsigned NextLevelProtocol;
+
+       /* The checksum of the "next level protocol", i.e. TCP or UDP. */
+       unsigned long NextLevelProtocolChecksum;
+
+       /* Pointer to next level protocol statistics structure. */
+       SKCS_PROTO_STATS *NextLevelProtoStats;
+
+       /* Temporary variable. */
+       unsigned Tmp;
+
+       Tmp = *(SK_U8 *)
+               SKCS_IDX(pIpHeader, SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH);
+
+       /* Get the Internet Header Version (IHV). */
+       /* Note: The IHV is stored in the upper four bits. */
+
+       InternetHeaderVersion = Tmp >> 4;
+
+       /* Check the Internet Header Version. */
+       /* Note: We currently only support IP version 4. */
+
+       if (InternetHeaderVersion != 4) {       /* IPv4? */
+               SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_RX,
+                       ("Rx: Unknown Internet Header Version %u.\n",
+                       InternetHeaderVersion));
+               pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxUnableCts++;
+               return (SKCS_STATUS_UNKNOWN_IP_VERSION);
+       }
+
+       /* Get the IP header length (IHL). */
+       /*
+        * Note: The IHL is stored in the lower four bits as the number of
+        * 4-byte words.
+        */
+
+       IpHeaderLength = (Tmp & 0xf) * 4;
+
+       /* Check the IP header length. */
+
+       /* 04-Aug-1998 sw - Really check the IHL? Necessary? */
+
+       if (IpHeaderLength < 5*4) {
+               SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_RX,
+                       ("Rx: Invalid IP Header Length %u.\n", IpHeaderLength));
+               pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxErrCts++;
+               return (SKCS_STATUS_IP_CSUM_ERROR);
+       }
+
+       /* This is an IPv4 frame with a header of valid length. */
+
+       /* Get the IP header and data checksum. */
+
+       IpDataChecksum = Checksum2;
+
+       /*
+        * The IP header checksum is calculated as follows:
+        *
+        *      IpHeaderChecksum = Checksum1 - Checksum2
+        */
+
+       SKCS_OC_SUB(IpHeaderChecksum, Checksum1, Checksum2);
+
+       /* Check if any IP header options. */
+
+       if (IpHeaderLength > SKCS_IP_HEADER_SIZE) {
+
+               /* Get the IP options checksum. */
+
+               IpOptionsChecksum = SkCsCalculateChecksum(
+                       SKCS_IDX(pIpHeader, SKCS_IP_HEADER_SIZE),
+                       IpHeaderLength - SKCS_IP_HEADER_SIZE);
+
+               /* Adjust the IP header and IP data checksums. */
+
+               SKCS_OC_ADD(IpHeaderChecksum, IpHeaderChecksum, IpOptionsChecksum);
+
+               SKCS_OC_SUB(IpDataChecksum, IpDataChecksum, IpOptionsChecksum);
+       }
+
+       /*
+        * Check if the IP header checksum is ok.
+        *
+        * NOTE: We must check the IP header checksum even if the caller just wants
+        * us to check upper-layer checksums, because we cannot do any further
+        * processing of the packet without a valid IP checksum.
+        */
+
+       /* Get the next level protocol identifier. */
+
+       NextLevelProtocol = *(SK_U8 *)
+               SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL);
+
+       if (IpHeaderChecksum != 0xFFFF) {
+               pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxErrCts++;
+               /* the NDIS tester wants to know the upper level protocol too */
+               if (NextLevelProtocol == SKCS_PROTO_ID_TCP) {
+                       return(SKCS_STATUS_IP_CSUM_ERROR_TCP);
+               }
+               else if (NextLevelProtocol == SKCS_PROTO_ID_UDP) {
+                       return(SKCS_STATUS_IP_CSUM_ERROR_UDP);
+               }
+               return (SKCS_STATUS_IP_CSUM_ERROR);
+       }
+
+       /*
+        * Check if this is a TCP or UDP frame and if we should calculate the
+        * TCP/UDP pseudo header checksum.
+        *
+        * Also clear all protocol bit flags of protocols not present in the
+        * frame.
+        */
+
+       if ((pAc->Csum.ReceiveFlags[NetNumber] & SKCS_PROTO_TCP) != 0 &&
+               NextLevelProtocol == SKCS_PROTO_ID_TCP) {
+               /* TCP/IP frame. */
+               NextLevelProtoStats =
+                       &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_TCP];
+       }
+       else if ((pAc->Csum.ReceiveFlags[NetNumber] & SKCS_PROTO_UDP) != 0 &&
+               NextLevelProtocol == SKCS_PROTO_ID_UDP) {
+               /* UDP/IP frame. */
+               NextLevelProtoStats =
+                       &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_UDP];
+       }
+       else {
+               /*
+                * Either not a TCP or UDP frame and/or TCP/UDP processing not
+                * specified.
+                */
+               return (SKCS_STATUS_IP_CSUM_OK);
+       }
+
+       /* Check if this is an IP fragment. */
+
+       /*
+        * Note: An IP fragment has a non-zero "Fragment Offset" field and/or
+        * the "More Fragments" bit set. Thus, if both the "Fragment Offset"
+        * and the "More Fragments" are zero, it is *not* a fragment. We can
+        * easily check both at the same time since they are in the same 16-bit
+        * word.
+        */
+
+       if ((*(SK_U16 *)
+               SKCS_IDX(pIpHeader, SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET) &
+               ~SKCS_IP_DONT_FRAGMENT) != 0) {
+               /* IP fragment; ignore all other protocols. */
+               NextLevelProtoStats->RxUnableCts++;
+               return (SKCS_STATUS_IP_FRAGMENT);
+       }
+
+       /*
+        * 08-May-2000 ra
+        *
+        * From RFC 768 (UDP)
+        * If the computed checksum is zero, it is transmitted as all ones (the
+        * equivalent in one's complement arithmetic).  An all zero transmitted
+        * checksum value means that the transmitter generated no checksum (for
+        * debugging or for higher level protocols that don't care).
+        */
+
+       if (NextLevelProtocol == SKCS_PROTO_ID_UDP &&
+               *(SK_U16*)SKCS_IDX(pIpHeader, IpHeaderLength + 6) == 0x0000) {
+
+               NextLevelProtoStats->RxOkCts++;
+
+               return (SKCS_STATUS_IP_CSUM_OK_NO_UDP);
+       }
+
+       /*
+        * Calculate the TCP/UDP checksum.
+        */
+
+       /* Get total length of IP header and data. */
+
+       IpDataLength =
+               *(SK_U16 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_TOTAL_LENGTH);
+
+       /* Get length of IP data portion. */
+
+       IpDataLength = SKCS_NTOH16(IpDataLength) - IpHeaderLength;
+
+       NextLevelProtocolChecksum =
+
+               /* Calculate the pseudo header checksum. */
+
+               (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
+                       SKCS_OFS_IP_SOURCE_ADDRESS + 0) +
+               (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
+                       SKCS_OFS_IP_SOURCE_ADDRESS + 2) +
+               (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
+                       SKCS_OFS_IP_DESTINATION_ADDRESS + 0) +
+               (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
+                       SKCS_OFS_IP_DESTINATION_ADDRESS + 2) +
+               (unsigned long) SKCS_HTON16(NextLevelProtocol) +
+               (unsigned long) SKCS_HTON16(IpDataLength) +
+
+               /* Add the TCP/UDP header checksum. */
+
+               (unsigned long) IpDataChecksum;
+
+       /* Add-in any carries. */
+
+       SKCS_OC_ADD(NextLevelProtocolChecksum, NextLevelProtocolChecksum, 0);
+
+       /* Add-in any new carry. */
+
+       SKCS_OC_ADD(NextLevelProtocolChecksum, NextLevelProtocolChecksum, 0);
+
+       /* Check if the TCP/UDP checksum is ok. */
+
+       if ((unsigned) NextLevelProtocolChecksum == 0xFFFF) {
+
+               /* TCP/UDP checksum ok. */
+
+               NextLevelProtoStats->RxOkCts++;
+
+               return (NextLevelProtocol == SKCS_PROTO_ID_TCP ?
+                       SKCS_STATUS_TCP_CSUM_OK : SKCS_STATUS_UDP_CSUM_OK);
+       }
+
+       /* TCP/UDP checksum error. */
+
+       NextLevelProtoStats->RxErrCts++;
+
+       return (NextLevelProtocol == SKCS_PROTO_ID_TCP ?
+               SKCS_STATUS_TCP_CSUM_ERROR : SKCS_STATUS_UDP_CSUM_ERROR);
+}      /* SkCsGetReceiveInfo */
+#endif
+
+
+/******************************************************************************
+ *
+ *     SkCsSetReceiveFlags - set checksum receive flags
+ *
+ * Description:
+ *     Use this function to set the various receive flags. According to the
+ *     protocol flags set by the caller, the start offsets within received
+ *     packets of the two hardware checksums are returned. These offsets must
+ *     be stored in all receive descriptors.
+ *
+ * Arguments:
+ *     pAc - Pointer to adapter context struct.
+ *
+ *     ReceiveFlags - Any combination of SK_PROTO_XXX flags of the protocols
+ *     for which the caller wants checksum information on received frames.
+ *
+ *     pChecksum1Offset - The start offset of the first receive descriptor
+ *     hardware checksum to be calculated for received frames is returned
+ *     here.
+ *
+ *     pChecksum2Offset - The start offset of the second receive descriptor
+ *     hardware checksum to be calculated for received frames is returned
+ *     here.
+ *
+ * Returns: N/A
+ *     Returns the two hardware checksum start offsets.
+ */
+void SkCsSetReceiveFlags(
+SK_AC          *pAc,                           /* Adapter context struct. */
+unsigned       ReceiveFlags,           /* New receive flags. */
+unsigned       *pChecksum1Offset,      /* Offset for hardware checksum 1. */
+unsigned       *pChecksum2Offset,      /* Offset for hardware checksum 2. */
+int                    NetNumber)
+{
+       /* Save the receive flags. */
+
+       pAc->Csum.ReceiveFlags[NetNumber] = ReceiveFlags;
+
+       /* First checksum start offset is the IP header. */
+       *pChecksum1Offset = SKCS_MAC_HEADER_SIZE;
+
+       /*
+        * Second checksum start offset is the IP data. Note that this may vary
+        * if there are any IP header options in the actual packet.
+        */
+       *pChecksum2Offset = SKCS_MAC_HEADER_SIZE + SKCS_IP_HEADER_SIZE;
+}      /* SkCsSetReceiveFlags */
+
+#ifndef SkCsCalculateChecksum
+
+/******************************************************************************
+ *
+ *     SkCsCalculateChecksum - calculate checksum for specified data
+ *
+ * Description:
+ *     Calculate and return the 16-bit Internet Checksum for the specified
+ *     data.
+ *
+ * Arguments:
+ *     pData - Pointer to data for which the checksum shall be calculated.
+ *     Note: The pointer should be aligned on a 16-bit boundary.
+ *
+ *     Length - Length in bytes of data to checksum.
+ *
+ * Returns:
+ *     The 16-bit Internet Checksum for the specified data.
+ *
+ *     Note: The checksum is calculated in the machine's natural byte order,
+ *     i.e. little vs. big endian. Thus, the resulting checksum is different
+ *     for the same input data on little and big endian machines.
+ *
+ *     However, when written back to the network packet, the byte order is
+ *     always in correct network order.
+ */
+unsigned SkCsCalculateChecksum(
+void           *pData,         /* Data to checksum. */
+unsigned       Length)         /* Length of data. */
+{
+       SK_U16 *pU16;           /* Pointer to the data as 16-bit words. */
+       unsigned long Checksum; /* Checksum; must be at least 32 bits. */
+
+       /* Sum up all 16-bit words. */
+
+       pU16 = (SK_U16 *) pData;
+       for (Checksum = 0; Length > 1; Length -= 2) {
+               Checksum += *pU16++;
+       }
+
+       /* If this is an odd number of bytes, add-in the last byte. */
+
+       if (Length > 0) {
+#ifdef SK_BIG_ENDIAN
+               /* Add the last byte as the high byte. */
+               Checksum += ((unsigned) *(SK_U8 *) pU16) << 8;
+#else  /* !SK_BIG_ENDIAN */
+               /* Add the last byte as the low byte. */
+               Checksum += *(SK_U8 *) pU16;
+#endif /* !SK_BIG_ENDIAN */
+       }
+
+       /* Add-in any carries. */
+
+       SKCS_OC_ADD(Checksum, Checksum, 0);
+
+       /* Add-in any new carry. */
+
+       SKCS_OC_ADD(Checksum, Checksum, 0);
+
+       /* Note: All bits beyond the 16-bit limit are now zero. */
+
+       return ((unsigned) Checksum);
+}      /* SkCsCalculateChecksum */
+
+#endif /* SkCsCalculateChecksum */
+
+/******************************************************************************
+ *
+ *     SkCsEvent - the CSUM event dispatcher
+ *
+ * Description:
+ *     This is the event handler for the CSUM module.
+ *
+ * Arguments:
+ *     pAc - Pointer to adapter context.
+ *
+ *     Ioc - I/O context.
+ *
+ *     Event -  Event id.
+ *
+ *     Param - Event dependent parameter.
+ *
+ * Returns:
+ *     The 16-bit Internet Checksum for the specified data.
+ *
+ *     Note: The checksum is calculated in the machine's natural byte order,
+ *     i.e. little vs. big endian. Thus, the resulting checksum is different
+ *     for the same input data on little and big endian machines.
+ *
+ *     However, when written back to the network packet, the byte order is
+ *     always in correct network order.
+ */
+int SkCsEvent(
+SK_AC          *pAc,   /* Pointer to adapter context. */
+SK_IOC         Ioc,    /* I/O context. */
+SK_U32         Event,  /* Event id. */
+SK_EVPARA      Param)  /* Event dependent parameter. */
+{
+       int ProtoIndex;
+       int     NetNumber;
+
+       switch (Event) {
+       /*
+        * Clear protocol statistics.
+        *
+        * Param - Protocol index, or -1 for all protocols.
+        *               - Net number.
+        */
+       case SK_CSUM_EVENT_CLEAR_PROTO_STATS:
+
+               ProtoIndex = (int)Param.Para32[1];
+               NetNumber = (int)Param.Para32[0];
+               if (ProtoIndex < 0) {   /* Clear for all protocols. */
+                       if (NetNumber >= 0) {
+                               memset(&pAc->Csum.ProtoStats[NetNumber][0], 0,
+                                       sizeof(pAc->Csum.ProtoStats[NetNumber]));
+                       }
+               }
+               else {                                  /* Clear for individual protocol. */
+                       memset(&pAc->Csum.ProtoStats[NetNumber][ProtoIndex], 0,
+                               sizeof(pAc->Csum.ProtoStats[NetNumber][ProtoIndex]));
+               }
+               break;
+       default:
+               break;
+       }
+       return (0);     /* Success. */
+}      /* SkCsEvent */
+
+#endif /* SK_USE_CSUM */
+
+#endif /* CONFIG_SK98 */
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
new file mode 100644 (file)
index 0000000..61a6094
--- /dev/null
@@ -0,0 +1,4864 @@
+/******************************************************************************
+ *
+ * Name:    skge.c
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.46 $
+ * Date:               $Date: 2003/02/25 14:16:36 $
+ * Purpose:    The main driver source module
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2003 SysKonnect GmbH.
+ *
+ *     Driver for SysKonnect Gigabit Ethernet Server Adapters:
+ *
+ *     SK-9871 (single link 1000Base-ZX)
+ *     SK-9872 (dual link   1000Base-ZX)
+ *     SK-9861 (single link 1000Base-SX, VF45 Volition Plug)
+ *     SK-9862 (dual link   1000Base-SX, VF45 Volition Plug)
+ *     SK-9841 (single link 1000Base-LX)
+ *     SK-9842 (dual link   1000Base-LX)
+ *     SK-9843 (single link 1000Base-SX)
+ *     SK-9844 (dual link   1000Base-SX)
+ *     SK-9821 (single link 1000Base-T)
+ *     SK-9822 (dual link   1000Base-T)
+ *     SK-9881 (single link 1000Base-SX V2 LC)
+ *     SK-9871 (single link 1000Base-ZX V2)
+ *     SK-9861 (single link 1000Base-SX V2, VF45 Volition Plug)
+ *     SK-9841 (single link 1000Base-LX V2)
+ *     SK-9843 (single link 1000Base-SX V2)
+ *     SK-9821 (single link 1000Base-T V2)
+ *
+ *     Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and
+ *     SysKonnects GEnesis Solaris driver
+ *     Author: Christoph Goos (cgoos@syskonnect.de)
+ *             Mirko Lindner (mlindner@syskonnect.de)
+ *
+ *     Address all question to: linux@syskonnect.de
+ *
+ *     The technical manual for the adapters is available from SysKonnect's
+ *     web pages: www.syskonnect.com
+ *     Goto "Support" and search Knowledge Base for "manual".
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skge.c,v $
+ *     Revision 1.46  2003/02/25 14:16:36  mlindner
+ *     Fix: Copyright statement
+ *
+ *     Revision 1.45  2003/02/25 13:25:55  mlindner
+ *     Add: Performance improvements
+ *     Add: Support for various vendors
+ *     Fix: Init function
+ *
+ *     Revision 1.44  2003/01/09 09:25:26  mlindner
+ *     Fix: Remove useless init_module/cleanup_module forward declarations
+ *
+ *     Revision 1.43  2002/11/29 08:42:41  mlindner
+ *     Fix: Boot message
+ *
+ *     Revision 1.42  2002/11/28 13:30:23  mlindner
+ *     Add: New frame check
+ *
+ *     Revision 1.41  2002/11/27 13:55:18  mlindner
+ *     Fix: Drop wrong csum packets
+ *     Fix: Initialize proc_entry after hw check
+ *
+ *     Revision 1.40  2002/10/31 07:50:37  tschilli
+ *     Function SkGeInitAssignRamToQueues() from common module inserted.
+ *     Autonegotiation is set to ON for all adapters.
+ *     LinkSpeedUsed is used in link up status report.
+ *     Role parameter will show up for 1000 Mbps links only.
+ *     GetConfiguration() inserted after init level 1 in SkGeChangeMtu().
+ *     All return values of SkGeInit() and SkGeInitPort() are checked.
+ *
+ *     Revision 1.39  2002/10/02 12:56:05  mlindner
+ *     Add: Support for Yukon
+ *     Add: Support for ZEROCOPY, scatter-gather and hw checksum
+ *     Add: New transmit ring function (use SG and TCP/UDP hardware checksumming)
+ *     Add: New init function
+ *     Add: Speed check and setup
+ *     Add: Merge source for kernel 2.2.x and 2.4.x
+ *     Add: Opcode check for tcp
+ *     Add: Frame length check
+ *     Fix: Transmit complete interrupt
+ *     Fix: Interrupt moderation
+ *
+ *     Revision 1.29.2.13  2002/01/14 12:44:52  mlindner
+ *     Fix: Rlmt modes
+ *
+ *     Revision 1.29.2.12  2001/12/07 12:06:18  mlindner
+ *     Fix: malloc -> slab changes
+ *
+ *     Revision 1.29.2.11  2001/12/06 15:19:20  mlindner
+ *     Add: DMA attributes
+ *     Fix: Module initialisation
+ *     Fix: pci_map_single and pci_unmap_single replaced
+ *
+ *     Revision 1.29.2.10  2001/12/06 09:56:50  mlindner
+ *     Corrected some printk's
+ *
+ *     Revision 1.29.2.9  2001/09/05 12:15:34  mlindner
+ *     Add: LBFO Changes
+ *     Fix: Counter Errors (Jumbo == to long errors)
+ *     Fix: Changed pAC->PciDev declaration
+ *     Fix: too short counters
+ *
+ *     Revision 1.29.2.8  2001/06/25 12:10:44  mlindner
+ *     fix: ReceiveIrq() changed.
+ *
+ *     Revision 1.29.2.7  2001/06/25 08:07:05  mlindner
+ *     fix: RLMT locking in ReceiveIrq() changed.
+ *
+ *     Revision 1.29.2.6  2001/05/21 07:59:29  mlindner
+ *     fix: MTU init problems
+ *
+ *     Revision 1.29.2.5  2001/05/08 11:25:08  mlindner
+ *     fix: removed VLAN error message
+ *
+ *     Revision 1.29.2.4  2001/05/04 13:31:43  gklug
+ *     fix: do not handle eth_copy on bad fragments received.
+ *
+ *     Revision 1.29.2.3  2001/04/23 08:06:43  mlindner
+ *     Fix: error handling
+ *
+ *     Revision 1.29.2.2  2001/03/15 12:04:54  mlindner
+ *     Fixed memory problem
+ *
+ *     Revision 1.29.2.1  2001/03/12 16:41:44  mlindner
+ *     add: procfs function
+ *     add: dual-net function
+ *     add: RLMT networks
+ *     add: extended PNMI features
+ *
+ *     Kernel 2.4.x specific:
+ *     Revision 1.xx  2000/09/12 13:31:56  cgoos
+ *     Fixed missign "dev=NULL in skge_probe.
+ *     Added counting for jumbo frames (corrects error statistic).
+ *     Removed VLAN tag check (enables VLAN support).
+ *
+ *     Kernel 2.2.x specific:
+ *     Revision 1.29  2000/02/21 13:31:56  cgoos
+ *     Fixed "unused" warning for UltraSPARC change.
+ *
+ *     Partially kernel 2.2.x specific:
+ *     Revision 1.28  2000/02/21 10:32:36  cgoos
+ *     Added fixes for UltraSPARC.
+ *     Now printing RlmtMode and PrefPort setting at startup.
+ *     Changed XmitFrame return value.
+ *     Fixed rx checksum calculation for BIG ENDIAN systems.
+ *     Fixed rx jumbo frames counted as ierrors.
+ *
+ *
+ *     Revision 1.27  1999/11/25 09:06:28  cgoos
+ *     Changed base_addr to unsigned long.
+ *
+ *     Revision 1.26  1999/11/22 13:29:16  cgoos
+ *     Changed license header to GPL.
+ *     Changes for inclusion in linux kernel (2.2.13).
+ *     Removed 2.0.x defines.
+ *     Changed SkGeProbe to skge_probe.
+ *     Added checks in SkGeIoctl.
+ *
+ *     Revision 1.25  1999/10/07 14:47:52  cgoos
+ *     Changed 984x to 98xx.
+ *
+ *     Revision 1.24  1999/09/30 07:21:01  cgoos
+ *     Removed SK_RLMT_SLOW_LOOKAHEAD option.
+ *     Giving spanning tree packets also to OS now.
+ *
+ *     Revision 1.23  1999/09/29 07:36:50  cgoos
+ *     Changed assignment for IsBc/IsMc.
+ *
+ *     Revision 1.22  1999/09/28 12:57:09  cgoos
+ *     Added CheckQueue also to Single-Port-ISR.
+ *
+ *     Revision 1.21  1999/09/28 12:42:41  cgoos
+ *     Changed parameter strings for RlmtMode.
+ *
+ *     Revision 1.20  1999/09/28 12:37:57  cgoos
+ *     Added CheckQueue for fast delivery of RLMT frames.
+ *
+ *     Revision 1.19  1999/09/16 07:57:25  cgoos
+ *     Copperfield changes.
+ *
+ *     Revision 1.18  1999/09/03 13:06:30  cgoos
+ *     Fixed RlmtMode=CheckSeg bug: wrong DEV_KFREE_SKB in RLMT_SEND caused
+ *     double allocated skb's.
+ *     FrameStat in ReceiveIrq was accessed via wrong Rxd.
+ *     Queue size for async. standby Tx queue was zero.
+ *     FillRxLimit of 0 could cause problems with ReQueue, changed to 1.
+ *     Removed debug output of checksum statistic.
+ *
+ *     Revision 1.17  1999/08/11 13:55:27  cgoos
+ *     Transmit descriptor polling was not reenabled after SkGePortInit.
+ *
+ *     Revision 1.16  1999/07/27 15:17:29  cgoos
+ *     Added some "\n" in output strings (removed while debuging...).
+ *
+ *     Revision 1.15  1999/07/23 12:09:30  cgoos
+ *     Performance optimization, rx checksumming, large frame support.
+ *
+ *     Revision 1.14  1999/07/14 11:26:27  cgoos
+ *     Removed Link LED settings (now in RLMT).
+ *     Added status output at NET UP.
+ *     Fixed SMP problems with Tx and SWITCH running in parallel.
+ *     Fixed return code problem at RLMT_SEND event.
+ *
+ *     Revision 1.13  1999/04/07 10:11:42  cgoos
+ *     Fixed Single Port problems.
+ *     Fixed Multi-Adapter problems.
+ *     Always display startup string.
+ *
+ *     Revision 1.12  1999/03/29 12:26:37  cgoos
+ *     Reversed locking to fine granularity.
+ *     Fixed skb double alloc problem (caused by incorrect xmit return code).
+ *     Enhanced function descriptions.
+ *
+ *     Revision 1.11  1999/03/15 13:10:51  cgoos
+ *     Changed device identifier in output string to ethX.
+ *
+ *     Revision 1.10  1999/03/15 12:12:34  cgoos
+ *     Changed copyright notice.
+ *
+ *     Revision 1.9  1999/03/15 12:10:17  cgoos
+ *     Changed locking to one driver lock.
+ *     Added check of SK_AC-size (for consistency with library).
+ *
+ *     Revision 1.8  1999/03/08 11:44:02  cgoos
+ *     Fixed missing dev->tbusy in SkGeXmit.
+ *     Changed large frame (jumbo) buffer number.
+ *     Added copying of short frames.
+ *
+ *     Revision 1.7  1999/03/04 13:26:57  cgoos
+ *     Fixed spinlock calls for SMP.
+ *
+ *     Revision 1.6  1999/03/02 09:53:51  cgoos
+ *     Added descriptor revertion for big endian machines.
+ *
+ *     Revision 1.5  1999/03/01 08:50:59  cgoos
+ *     Fixed SkGeChangeMtu.
+ *     Fixed pci config space accesses.
+ *
+ *     Revision 1.4  1999/02/18 15:48:44  cgoos
+ *     Corrected some printk's.
+ *
+ *     Revision 1.3  1999/02/18 12:45:55  cgoos
+ *     Changed SK_MAX_CARD_PARAM to default 16
+ *
+ *     Revision 1.2  1999/02/18 10:55:32  cgoos
+ *     Removed SkGeDrvTimeStamp function.
+ *     Printing "ethX:" before adapter type at adapter init.
+ *
+ *
+ *     10-Feb-1999 cg  Created, based on Linux' acenic.c, 3c59x.c and
+ *                     SysKonnects GEnesis Solaris driver
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Possible compiler options (#define xxx / -Dxxx):
+ *
+ *     debugging can be enable by changing SK_DEBUG_CHKMOD and
+ *     SK_DEBUG_CHKCAT in makefile (described there).
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ *     This is the main module of the Linux GE driver.
+ *
+ *     All source files except skge.c, skdrv1st.h, skdrv2nd.h and sktypes.h
+ *     are part of SysKonnect's COMMON MODULES for the SK-98xx adapters.
+ *     Those are used for drivers on multiple OS', so some thing may seem
+ *     unnecessary complicated on Linux. Please do not try to 'clean up'
+ *     them without VERY good reasons, because this will make it more
+ *     difficult to keep the Linux driver in synchronisation with the
+ *     other versions.
+ *
+ * Include file hierarchy:
+ *
+ *     <linux/module.h>
+ *
+ *     "h/skdrv1st.h"
+ *             <linux/version.h>
+ *             <linux/types.h>
+ *             <linux/kernel.h>
+ *             <linux/string.h>
+ *             <linux/errno.h>
+ *             <linux/ioport.h>
+ *             <linux/slab.h>
+ *             <linux/interrupt.h>
+ *             <linux/pci.h>
+ *             <asm/byteorder.h>
+ *             <asm/bitops.h>
+ *             <asm/io.h>
+ *             <linux/netdevice.h>
+ *             <linux/etherdevice.h>
+ *             <linux/skbuff.h>
+ *         those three depending on kernel version used:
+ *             <linux/bios32.h>
+ *             <linux/init.h>
+ *             <asm/uaccess.h>
+ *             <net/checksum.h>
+ *
+ *             "h/skerror.h"
+ *             "h/skdebug.h"
+ *             "h/sktypes.h"
+ *             "h/lm80.h"
+ *             "h/xmac_ii.h"
+ *
+ *      "h/skdrv2nd.h"
+ *             "h/skqueue.h"
+ *             "h/skgehwt.h"
+ *             "h/sktimer.h"
+ *             "h/ski2c.h"
+ *             "h/skgepnmi.h"
+ *             "h/skvpd.h"
+ *             "h/skgehw.h"
+ *             "h/skgeinit.h"
+ *             "h/skaddr.h"
+ *             "h/skgesirq.h"
+ *             "h/skcsum.h"
+ *             "h/skrlmt.h"
+ *
+ ******************************************************************************/
+
+#include <config.h>
+
+#ifdef CONFIG_SK98
+
+#include       "h/skversion.h"
+#if 0
+#include       <linux/module.h>
+#include       <linux/init.h>
+#include       <linux/proc_fs.h>
+#endif
+#include       "h/skdrv1st.h"
+#include       "h/skdrv2nd.h"
+
+
+/* defines ******************************************************************/
+/* for debuging on x86 only */
+/* #define BREAKPOINT() asm(" int $3"); */
+
+/* use the scatter-gather functionality with sendfile() */
+#if 0
+#define SK_ZEROCOPY
+#endif
+
+/* use of a transmit complete interrupt */
+#define USE_TX_COMPLETE
+
+/* use interrupt moderation (for tx complete only) */
+#define USE_INT_MOD
+#define INTS_PER_SEC   1000
+
+/*
+ * threshold for copying small receive frames
+ * set to 0 to avoid copying, set to 9001 to copy all frames
+ */
+#define SK_COPY_THRESHOLD      50
+
+/* number of adapters that can be configured via command line params */
+#define SK_MAX_CARD_PARAM      16
+
+
+/*
+ * use those defines for a compile-in version of the driver instead
+ * of command line parameters
+ */
+/* #define LINK_SPEED_A        {"Auto", }              */
+/* #define LINK_SPEED_B        {"Auto", }              */
+/* #define AUTO_NEG_A  {"Sense", }             */
+/* #define AUTO_NEG_B  {"Sense", }             */
+/* #define DUP_CAP_A   {"Both", }              */
+/* #define DUP_CAP_B   {"Both", }              */
+/* #define FLOW_CTRL_A {"SymOrRem", }          */
+/* #define FLOW_CTRL_B {"SymOrRem", }          */
+/* #define ROLE_A      {"Auto", }              */
+/* #define ROLE_B      {"Auto", }              */
+/* #define PREF_PORT   {"A", }                 */
+/* #define RLMT_MODE   {"CheckLinkState", }    */
+
+#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
+#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb)
+#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb)
+
+/* function prototypes ******************************************************/
+static void    FreeResources(struct SK_NET_DEVICE *dev);
+static int     SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC);
+static SK_BOOL BoardAllocMem(SK_AC *pAC);
+static void    BoardFreeMem(SK_AC *pAC);
+static void    BoardInitMem(SK_AC *pAC);
+static void    SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**,
+                       int*, SK_BOOL);
+
+#if 0
+static void    SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs);
+static void    SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs);
+static int     SkGeOpen(struct SK_NET_DEVICE *dev);
+static int     SkGeClose(struct SK_NET_DEVICE *dev);
+static int     SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev);
+static int     SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p);
+static void    SkGeSetRxMode(struct SK_NET_DEVICE *dev);
+static struct  net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev);
+static int     SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd);
+#else
+void   SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs);
+void   SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs);
+int    SkGeOpen(struct SK_NET_DEVICE *dev);
+int    SkGeClose(struct SK_NET_DEVICE *dev);
+int    SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev);
+#endif
+static void    GetConfiguration(SK_AC*);
+static void    ProductStr(SK_AC*);
+static int     XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*);
+static void    FreeTxDescriptors(SK_AC*pAC, TX_PORT*);
+static void    FillRxRing(SK_AC*, RX_PORT*);
+static SK_BOOL FillRxDescriptor(SK_AC*, RX_PORT*);
+#if 0
+static void    ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL);
+#else
+void   ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL);
+#endif
+static void ClearAndStartRx(SK_AC*, int);
+static void    ClearTxIrq(SK_AC*, int, int);
+static void    ClearRxRing(SK_AC*, RX_PORT*);
+static void    ClearTxRing(SK_AC*, TX_PORT*);
+#if 0
+static void    SetQueueSizes(SK_AC     *pAC);
+
+static int     SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu);
+#endif
+static void    PortReInitBmu(SK_AC*, int);
+#if 0
+static int     SkGeIocMib(DEV_NET*, unsigned int, int);
+static int     XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*);
+#endif
+
+/*Extern */
+
+/* external Proc function */
+extern int proc_read(
+       char    *buffer,
+       char    **buffer_location,
+       off_t   offset,
+       int             buffer_length,
+       int             *eof,
+       void    *data);
+
+#ifdef DEBUG
+static void    DumpMsg(struct sk_buff*, char*);
+static void    DumpData(char*, int);
+static void    DumpLong(char*, int);
+#endif
+void dump_frag( SK_U8 *data, int length);
+
+/* global variables *********************************************************/
+#if 0
+static const char *BootString = BOOT_STRING;
+#endif
+struct SK_NET_DEVICE *SkGeRootDev = NULL;
+static int probed __initdata = 0;
+
+/* local variables **********************************************************/
+static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
+static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
+
+
+/* local variables **********************************************************/
+const char SK_Root_Dir_entry[8];
+
+#if 0
+static struct proc_dir_entry   *pSkRootDir;
+#endif
+
+
+static struct pci_device_id supported[] = {
+       {PCI_VENDOR_ID_3COM, 0x1700},
+       {PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE},
+       {PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU},
+       {}
+};
+
+
+/*****************************************************************************
+ *
+ *     skge_probe - find all SK-98xx adapters
+ *
+ * Description:
+ *     This function scans the PCI bus for SK-98xx adapters. Resources for
+ *     each adapter are allocated and the adapter is brought into Init 1
+ *     state.
+ *
+ * Returns:
+ *     0, if everything is ok
+ *     !=0, on error
+ */
+#if 0
+static int __init skge_probe (void)
+#else
+int skge_probe (struct eth_device ** ret_dev)
+#endif
+{
+#if 0
+       int                     proc_root_initialized = 0;
+#endif
+       int                     boards_found = 0;
+#if 0
+       int                     vendor_flag = SK_FALSE;
+#endif
+       SK_AC                   *pAC;
+       DEV_NET                 *pNet = NULL;
+#if 0
+       struct proc_dir_entry   *pProcFile;
+       struct pci_dev  *pdev = NULL;
+       unsigned long           base_address;
+#else
+       u32                     base_address;
+#endif
+       struct SK_NET_DEVICE *dev = NULL;
+#if 0
+       SK_BOOL DeviceFound = SK_FALSE;
+#endif
+       SK_BOOL BootStringCount = SK_FALSE;
+#if 1
+       pci_dev_t devno;
+#endif
+
+       if (probed)
+               return -ENODEV;
+       probed++;
+
+       if (!pci_present())             /* is PCI support present? */
+               return -ENODEV;
+
+#if 0
+               while((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, pdev)))
+#else
+               while((devno = pci_find_devices (supported, boards_found)) >= 0)
+#endif
+               {
+
+               dev = NULL;
+               pNet = NULL;
+
+
+#if 0
+               SK_PCI_ISCOMPLIANT(vendor_flag, pdev);
+               if (!vendor_flag)
+                       continue;
+#endif
+
+/*             if ((pdev->vendor != PCI_VENDOR_ID_SYSKONNECT) &&
+                       ((pdev->device != PCI_DEVICE_ID_SYSKONNECT_GE) ||
+                       (pdev->device != PCI_DEVICE_ID_SYSKONNECT_YU))){
+                       continue;
+               }
+*/
+#if 0
+               /* Configure DMA attributes. */
+               if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff) &&
+                       pci_set_dma_mask(pdev, (u64) 0xffffffff))
+                       continue;
+#endif
+
+
+#if 0
+               if ((dev = init_etherdev(dev, sizeof(DEV_NET))) == NULL) {
+                       printk(KERN_ERR "Unable to allocate etherdev "
+                              "structure!\n");
+                       break;
+               }
+#else
+               dev = malloc (sizeof *dev);
+               memset(dev, 0, sizeof(*dev));
+               dev->priv = malloc(sizeof(DEV_NET));
+#endif
+
+               if (dev->priv == NULL) {
+                       printk(KERN_ERR "Unable to allocate adapter "
+                              "structure!\n");
+                       break;
+               }
+
+               pNet = dev->priv;
+               pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
+               if (pNet->pAC == NULL){
+                       kfree(dev->priv);
+                       printk(KERN_ERR "Unable to allocate adapter "
+                              "structure!\n");
+                       break;
+               }
+
+               /* Print message */
+               if (!BootStringCount) {
+                       /* set display flag to TRUE so that */
+                       /* we only display this string ONCE */
+                       BootStringCount = SK_TRUE;
+#ifdef SK98_INFO
+                       printk("%s\n", BootString);
+#endif
+               }
+
+               memset(pNet->pAC, 0, sizeof(SK_AC));
+               pAC = pNet->pAC;
+#if 0
+               pAC->PciDev = pdev;
+               pAC->PciDevId = pdev->device;
+               pAC->dev[0] = dev;
+               pAC->dev[1] = dev;
+#else
+               pAC->PciDev = devno;
+               ret_dev[0] = pAC->dev[0] = dev;
+               ret_dev[1] = pAC->dev[1] = dev;
+#endif
+               sprintf(pAC->Name, "SysKonnect SK-98xx");
+               pAC->CheckQueue = SK_FALSE;
+
+               pNet->Mtu = 1500;
+               pNet->Up = 0;
+#if 0
+               dev->irq = pdev->irq;
+
+               dev->open =             &SkGeOpen;
+               dev->stop =             &SkGeClose;
+               dev->hard_start_xmit =  &SkGeXmit;
+               dev->get_stats =        &SkGeStats;
+               dev->set_multicast_list = &SkGeSetRxMode;
+               dev->set_mac_address =  &SkGeSetMacAddr;
+               dev->do_ioctl =         &SkGeIoctl;
+               dev->change_mtu =       &SkGeChangeMtu;
+               dev->flags &=           ~IFF_RUNNING;
+#endif
+
+#ifdef SK_ZEROCOPY
+               if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
+                       /* Use only if yukon hardware */
+                       /* SK and ZEROCOPY - fly baby... */
+                       dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+               }
+#endif
+
+#if 0
+               /*
+                * Dummy value.
+                */
+               dev->base_addr = 42;
+               pci_set_master(pdev);
+
+               pci_set_master(pdev);
+               base_address = pci_resource_start (pdev, 0);
+#else
+               pci_write_config_dword(devno,
+                                      PCI_COMMAND,
+                                      PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+               pci_read_config_dword (devno, PCI_BASE_ADDRESS_0,
+                                      &base_address);
+#endif
+
+#ifdef SK_BIG_ENDIAN
+               /*
+                * On big endian machines, we use the adapter's aibility of
+                * reading the descriptors as big endian.
+                */
+               {
+               SK_U32          our2;
+                       SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2);
+                       our2 |= PCI_REV_DESC;
+                       SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2);
+               }
+#endif
+
+               /*
+                * Remap the regs into kernel space.
+                */
+#if 0
+               pAC->IoBase = (char*)ioremap(base_address, 0x4000);
+#else
+               pAC->IoBase = (char*)pci_mem_to_phys(devno, base_address);
+#endif
+
+               if (!pAC->IoBase){
+                       printk(KERN_ERR "%s:  Unable to map I/O register, "
+                              "SK 98xx No. %i will be disabled.\n",
+                              dev->name, boards_found);
+                       kfree(dev);
+                       break;
+               }
+
+               pAC->Index = boards_found;
+               if (SkGeBoardInit(dev, pAC)) {
+                       FreeResources(dev);
+                       kfree(dev);
+                       continue;
+               }
+
+#if 0
+               memcpy((caddr_t) &dev->dev_addr,
+                       (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
+#else
+               memcpy((caddr_t) &dev->enetaddr,
+                       (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
+#endif
+
+#if 0
+               /* First adapter... Create proc and print message */
+               if (!DeviceFound) {
+                       DeviceFound = SK_TRUE;
+                       SK_MEMCPY(&SK_Root_Dir_entry, BootString,
+                               sizeof(SK_Root_Dir_entry) - 1);
+
+                       /*Create proc (directory)*/
+                       if(!proc_root_initialized) {
+                               pSkRootDir = create_proc_entry(SK_Root_Dir_entry,
+                                       S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net);
+                               proc_root_initialized = 1;
+                       }
+
+                       pSkRootDir->owner = THIS_MODULE;
+               }
+
+
+               /* Create proc file */
+               pProcFile = create_proc_entry(dev->name,
+                       S_IFREG | S_IXUSR | S_IWGRP | S_IROTH,
+                       pSkRootDir);
+
+
+               pProcFile->read_proc = proc_read;
+               pProcFile->write_proc = NULL;
+               pProcFile->nlink = 1;
+               pProcFile->size = sizeof(dev->name + 1);
+               pProcFile->data = (void *)pProcFile;
+#endif
+
+               pNet->PortNr = 0;
+               pNet->NetNr = 0;
+
+#ifdef SK_ZEROCOPY
+                       if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
+                               /* SG and ZEROCOPY - fly baby... */
+                               dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+                       }
+#endif
+
+               boards_found++;
+
+               /* More then one port found */
+               if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
+#if 0
+                       if ((dev = init_etherdev(NULL, sizeof(DEV_NET))) == 0) {
+                               printk(KERN_ERR "Unable to allocate etherdev "
+                                       "structure!\n");
+                               break;
+                       }
+#else
+                       dev = malloc (sizeof *dev);
+                       memset(dev, 0, sizeof(*dev));
+                       dev->priv = malloc(sizeof(DEV_NET));
+#endif
+
+                       pAC->dev[1] = dev;
+                       pNet = dev->priv;
+                       pNet->PortNr = 1;
+                       pNet->NetNr = 1;
+                       pNet->pAC = pAC;
+                       pNet->Mtu = 1500;
+                       pNet->Up = 0;
+
+#if 0
+                       dev->open =             &SkGeOpen;
+                       dev->stop =             &SkGeClose;
+                       dev->hard_start_xmit =  &SkGeXmit;
+                       dev->get_stats =        &SkGeStats;
+                       dev->set_multicast_list = &SkGeSetRxMode;
+                       dev->set_mac_address =  &SkGeSetMacAddr;
+                       dev->do_ioctl =         &SkGeIoctl;
+                       dev->change_mtu =       &SkGeChangeMtu;
+                       dev->flags &=           ~IFF_RUNNING;
+#endif
+
+#ifdef SK_ZEROCOPY
+                       if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
+                               /* SG and ZEROCOPY - fly baby... */
+                               dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+                       }
+#endif
+
+#if 0
+                       pProcFile = create_proc_entry(dev->name,
+                               S_IFREG | S_IXUSR | S_IWGRP | S_IROTH,
+                               pSkRootDir);
+
+
+                       pProcFile->read_proc = proc_read;
+                       pProcFile->write_proc = NULL;
+                       pProcFile->nlink = 1;
+                       pProcFile->size = sizeof(dev->name + 1);
+                       pProcFile->data = (void *)pProcFile;
+#endif
+
+#if 0
+                       memcpy((caddr_t) &dev->dev_addr,
+                       (caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6);
+#else
+                       memcpy((caddr_t) &dev->enetaddr,
+                       (caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6);
+#endif
+
+                       printk("%s: %s\n", dev->name, pAC->DeviceStr);
+                       printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");
+
+               }
+
+
+               /* Save the hardware revision */
+               pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
+                       (pAC->GIni.GIPciHwRev & 0x0F);
+
+               /*
+                * This is bollocks, but we need to tell the net-init
+                * code that it shall go for the next device.
+                */
+#if 0
+#ifndef MODULE
+               dev->base_addr = 0;
+#endif
+#endif
+       }
+
+       /*
+        * If we're at this point we're going through skge_probe() for
+        * the first time.  Return success (0) if we've initialized 1
+        * or more boards. Otherwise, return failure (-ENODEV).
+        */
+
+       return boards_found;
+} /* skge_probe */
+
+
+/*****************************************************************************
+ *
+ *     FreeResources - release resources allocated for adapter
+ *
+ * Description:
+ *     This function releases the IRQ, unmaps the IO and
+ *     frees the desriptor ring.
+ *
+ * Returns: N/A
+ *
+ */
+static void FreeResources(struct SK_NET_DEVICE *dev)
+{
+SK_U32 AllocFlag;
+DEV_NET                *pNet;
+SK_AC          *pAC;
+
+       if (dev->priv) {
+               pNet = (DEV_NET*) dev->priv;
+               pAC = pNet->pAC;
+               AllocFlag = pAC->AllocFlag;
+#if 0
+               if (AllocFlag & SK_ALLOC_IRQ) {
+                       free_irq(dev->irq, dev);
+               }
+               if (pAC->IoBase) {
+                       iounmap(pAC->IoBase);
+               }
+#endif
+               if (pAC->pDescrMem) {
+                       BoardFreeMem(pAC);
+               }
+       }
+
+} /* FreeResources */
+
+#if 0
+MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
+MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");
+MODULE_LICENSE("GPL");
+MODULE_PARM(Speed_A,    "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+MODULE_PARM(Speed_B,    "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+MODULE_PARM(AutoNeg_A,  "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+MODULE_PARM(AutoNeg_B,  "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+MODULE_PARM(DupCap_A,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+MODULE_PARM(DupCap_B,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+MODULE_PARM(FlowCtrl_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+MODULE_PARM(FlowCtrl_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+MODULE_PARM(Role_A,        "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+MODULE_PARM(Role_B,        "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+MODULE_PARM(PrefPort,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+MODULE_PARM(RlmtMode,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+/* not used, just there because every driver should have them: */
+MODULE_PARM(options,    "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i");
+MODULE_PARM(debug,      "i");
+#endif
+
+
+#ifdef LINK_SPEED_A
+static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED_A;
+#else
+static char *Speed_A[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef LINK_SPEED_B
+static char *Speed_B[SK_MAX_CARD_PARAM] = LINK_SPEED_B;
+#else
+static char *Speed_B[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef AUTO_NEG_A
+static char *AutoNeg_A[SK_MAX_CARD_PARAM] = AUTO_NEG_A;
+#else
+static char *AutoNeg_A[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef DUP_CAP_A
+static char *DupCap_A[SK_MAX_CARD_PARAM] = DUP_CAP_A;
+#else
+static char *DupCap_A[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef FLOW_CTRL_A
+static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = FLOW_CTRL_A;
+#else
+static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef ROLE_A
+static char *Role_A[SK_MAX_CARD_PARAM] = ROLE_A;
+#else
+static char *Role_A[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef AUTO_NEG_B
+static char *AutoNeg_B[SK_MAX_CARD_PARAM] = AUTO_NEG_B;
+#else
+static char *AutoNeg_B[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef DUP_CAP_B
+static char *DupCap_B[SK_MAX_CARD_PARAM] = DUP_CAP_B;
+#else
+static char *DupCap_B[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef FLOW_CTRL_B
+static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = FLOW_CTRL_B;
+#else
+static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef ROLE_B
+static char *Role_B[SK_MAX_CARD_PARAM] = ROLE_B;
+#else
+static char *Role_B[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef PREF_PORT
+static char *PrefPort[SK_MAX_CARD_PARAM] = PREF_PORT;
+#else
+static char *PrefPort[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef RLMT_MODE
+static char *RlmtMode[SK_MAX_CARD_PARAM] = RLMT_MODE;
+#else
+static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#if 0
+static int debug = 0; /* not used */
+static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */
+
+
+/*****************************************************************************
+ *
+ *     skge_init_module - module initialization function
+ *
+ * Description:
+ *     Very simple, only call skge_probe and return approriate result.
+ *
+ * Returns:
+ *     0, if everything is ok
+ *     !=0, on error
+ */
+static int __init skge_init_module(void)
+{
+       int cards;
+       SkGeRootDev = NULL;
+
+       /* just to avoid warnings ... */
+       debug = 0;
+       options[0] = 0;
+
+       cards = skge_probe();
+       if (cards == 0) {
+               printk("sk98lin: No adapter found.\n");
+       }
+       return cards ? 0 : -ENODEV;
+} /* skge_init_module */
+
+
+/*****************************************************************************
+ *
+ *     skge_cleanup_module - module unload function
+ *
+ * Description:
+ *     Disable adapter if it is still running, free resources,
+ *     free device struct.
+ *
+ * Returns: N/A
+ */
+static void __exit skge_cleanup_module(void)
+{
+DEV_NET                *pNet;
+SK_AC          *pAC;
+struct SK_NET_DEVICE *next;
+unsigned long Flags;
+SK_EVPARA EvPara;
+
+       while (SkGeRootDev) {
+               pNet = (DEV_NET*) SkGeRootDev->priv;
+               pAC = pNet->pAC;
+               next = pAC->Next;
+
+               netif_stop_queue(SkGeRootDev);
+               SkGeYellowLED(pAC, pAC->IoBase, 0);
+
+               if(pAC->BoardLevel == 2) {
+                       /* board is still alive */
+                       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+                       EvPara.Para32[0] = 0;
+                       EvPara.Para32[1] = -1;
+                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+                       EvPara.Para32[0] = 1;
+                       EvPara.Para32[1] = -1;
+                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+                       SkEventDispatcher(pAC, pAC->IoBase);
+                       /* disable interrupts */
+                       SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+                       SkGeDeInit(pAC, pAC->IoBase);
+                       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+                       pAC->BoardLevel = 0;
+                       /* We do NOT check here, if IRQ was pending, of course*/
+               }
+
+               if(pAC->BoardLevel == 1) {
+                       /* board is still alive */
+                       SkGeDeInit(pAC, pAC->IoBase);
+                       pAC->BoardLevel = 0;
+               }
+
+               if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){
+                       unregister_netdev(pAC->dev[1]);
+                       kfree(pAC->dev[1]);
+               }
+
+               FreeResources(SkGeRootDev);
+
+               SkGeRootDev->get_stats = NULL;
+               /*
+                * otherwise unregister_netdev calls get_stats with
+                * invalid IO ...  :-(
+                */
+               unregister_netdev(SkGeRootDev);
+               kfree(SkGeRootDev);
+               kfree(pAC);
+               SkGeRootDev = next;
+       }
+
+       /* clear proc-dir */
+       remove_proc_entry(pSkRootDir->name, proc_net);
+
+} /* skge_cleanup_module */
+
+module_init(skge_init_module);
+module_exit(skge_cleanup_module);
+#endif
+
+
+/*****************************************************************************
+ *
+ *     SkGeBoardInit - do level 0 and 1 initialization
+ *
+ * Description:
+ *     This function prepares the board hardware for running. The desriptor
+ *     ring is set up, the IRQ is allocated and the configuration settings
+ *     are examined.
+ *
+ * Returns:
+ *     0, if everything is ok
+ *     !=0, on error
+ */
+static int __init SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC)
+{
+short  i;
+unsigned long Flags;
+char   *DescrString = "sk98lin: Driver for Linux"; /* this is given to PNMI */
+char   *VerStr = VER_STRING;
+#if 0
+int    Ret;                    /* return code of request_irq */
+#endif
+SK_BOOL        DualNet;
+
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("IoBase: %08lX\n", (unsigned long)pAC->IoBase));
+       for (i=0; i<SK_MAX_MACS; i++) {
+               pAC->TxPort[i][0].HwAddr = pAC->IoBase + TxQueueAddr[i][0];
+               pAC->TxPort[i][0].PortIndex = i;
+               pAC->RxPort[i].HwAddr = pAC->IoBase + RxQueueAddr[i];
+               pAC->RxPort[i].PortIndex = i;
+       }
+
+       /* Initialize the mutexes */
+       for (i=0; i<SK_MAX_MACS; i++) {
+               spin_lock_init(&pAC->TxPort[i][0].TxDesRingLock);
+               spin_lock_init(&pAC->RxPort[i].RxDesRingLock);
+       }
+       spin_lock_init(&pAC->SlowPathLock);
+
+       /* level 0 init common modules here */
+
+       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+       /* Does a RESET on board ...*/
+       if (SkGeInit(pAC, pAC->IoBase, 0) != 0) {
+               printk("HWInit (0) failed.\n");
+               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+               return(-EAGAIN);
+       }
+       SkI2cInit(  pAC, pAC->IoBase, 0);
+       SkEventInit(pAC, pAC->IoBase, 0);
+       SkPnmiInit( pAC, pAC->IoBase, 0);
+       SkAddrInit( pAC, pAC->IoBase, 0);
+       SkRlmtInit( pAC, pAC->IoBase, 0);
+       SkTimerInit(pAC, pAC->IoBase, 0);
+
+       pAC->BoardLevel = 0;
+       pAC->RxBufSize = ETH_BUF_SIZE;
+
+       SK_PNMI_SET_DRIVER_DESCR(pAC, DescrString);
+       SK_PNMI_SET_DRIVER_VER(pAC, VerStr);
+
+       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+
+       /* level 1 init common modules here (HW init) */
+       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+       if (SkGeInit(pAC, pAC->IoBase, 1) != 0) {
+               printk("HWInit (1) failed.\n");
+               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+               return(-EAGAIN);
+       }
+       SkI2cInit(  pAC, pAC->IoBase, 1);
+       SkEventInit(pAC, pAC->IoBase, 1);
+       SkPnmiInit( pAC, pAC->IoBase, 1);
+       SkAddrInit( pAC, pAC->IoBase, 1);
+       SkRlmtInit( pAC, pAC->IoBase, 1);
+       SkTimerInit(pAC, pAC->IoBase, 1);
+
+       GetConfiguration(pAC);
+       if (pAC->RlmtNets == 2) {
+               pAC->GIni.GIPortUsage = SK_MUL_LINK;
+       }
+
+       pAC->BoardLevel = 1;
+       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+
+#if 0
+       if (pAC->GIni.GIMacsFound == 2) {
+                Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
+       } else if (pAC->GIni.GIMacsFound == 1) {
+               Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ,
+                       pAC->Name, dev);
+       } else {
+               printk(KERN_WARNING "%s: Illegal number of ports: %d\n",
+                      dev->name, pAC->GIni.GIMacsFound);
+               return -EAGAIN;
+       }
+
+       if (Ret) {
+               printk(KERN_WARNING "%s: Requested IRQ %d is busy.\n",
+                      dev->name, dev->irq);
+               return -EAGAIN;
+       }
+#endif
+       pAC->AllocFlag |= SK_ALLOC_IRQ;
+
+       /* Alloc memory for this board (Mem for RxD/TxD) : */
+       if(!BoardAllocMem(pAC)) {
+               printk("No memory for descriptor rings.\n");
+               return(-EAGAIN);
+       }
+
+       SkCsSetReceiveFlags(pAC,
+               SKCS_PROTO_IP | SKCS_PROTO_TCP | SKCS_PROTO_UDP,
+               &pAC->CsOfs1, &pAC->CsOfs2, 0);
+       pAC->CsOfs = (pAC->CsOfs2 << 16) | pAC->CsOfs1;
+
+       BoardInitMem(pAC);
+#if 0
+       SetQueueSizes(pAC);
+#else
+       /* tschilling: New common function with minimum size check. */
+       DualNet = SK_FALSE;
+       if (pAC->RlmtNets == 2) {
+               DualNet = SK_TRUE;
+       }
+
+       if (SkGeInitAssignRamToQueues(
+               pAC,
+               pAC->ActivePort,
+               DualNet)) {
+               BoardFreeMem(pAC);
+               printk("SkGeInitAssignRamToQueues failed.\n");
+               return(-EAGAIN);
+       }
+#endif
+
+       /* Print adapter specific string from vpd */
+       ProductStr(pAC);
+#ifdef SK98_INFO
+       printk("%s: %s\n", dev->name, pAC->DeviceStr);
+
+       /* Print configuration settings */
+       printk("      PrefPort:%c  RlmtMode:%s\n",
+               'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
+               (pAC->RlmtMode==0)  ? "Check Link State" :
+               ((pAC->RlmtMode==1) ? "Check Link State" :
+               ((pAC->RlmtMode==3) ? "Check Local Port" :
+               ((pAC->RlmtMode==7) ? "Check Segmentation" :
+               ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
+#endif
+
+       SkGeYellowLED(pAC, pAC->IoBase, 1);
+
+       /*
+        * Register the device here
+        */
+       pAC->Next = SkGeRootDev;
+       SkGeRootDev = dev;
+
+       return (0);
+} /* SkGeBoardInit */
+
+
+/*****************************************************************************
+ *
+ *     BoardAllocMem - allocate the memory for the descriptor rings
+ *
+ * Description:
+ *     This function allocates the memory for all descriptor rings.
+ *     Each ring is aligned for the desriptor alignment and no ring
+ *     has a 4 GByte boundary in it (because the upper 32 bit must
+ *     be constant for all descriptiors in one rings).
+ *
+ * Returns:
+ *     SK_TRUE, if all memory could be allocated
+ *     SK_FALSE, if not
+ */
+static SK_BOOL BoardAllocMem(
+SK_AC  *pAC)
+{
+caddr_t                pDescrMem;      /* pointer to descriptor memory area */
+size_t         AllocLength;    /* length of complete descriptor area */
+int            i;              /* loop counter */
+unsigned long  BusAddr;
+
+
+       /* rings plus one for alignment (do not cross 4 GB boundary) */
+       /* RX_RING_SIZE is assumed bigger than TX_RING_SIZE */
+#if (BITS_PER_LONG == 32)
+       AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
+#else
+       AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
+               + RX_RING_SIZE + 8;
+#endif
+
+       pDescrMem = pci_alloc_consistent(pAC->PciDev, AllocLength,
+                                        &pAC->pDescrMemDMA);
+
+       if (pDescrMem == NULL) {
+               return (SK_FALSE);
+       }
+       pAC->pDescrMem = pDescrMem;
+       BusAddr = (unsigned long) pAC->pDescrMemDMA;
+
+       /* Descriptors need 8 byte alignment, and this is ensured
+        * by pci_alloc_consistent.
+        */
+       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+                       ("TX%d/A: pDescrMem: %lX,   PhysDescrMem: %lX\n",
+                       i, (unsigned long) pDescrMem,
+                       BusAddr));
+               pAC->TxPort[i][0].pTxDescrRing = pDescrMem;
+               pAC->TxPort[i][0].VTxDescrRing = BusAddr;
+               pDescrMem += TX_RING_SIZE;
+               BusAddr += TX_RING_SIZE;
+
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+                       ("RX%d: pDescrMem: %lX,   PhysDescrMem: %lX\n",
+                       i, (unsigned long) pDescrMem,
+                       (unsigned long)BusAddr));
+               pAC->RxPort[i].pRxDescrRing = pDescrMem;
+               pAC->RxPort[i].VRxDescrRing = BusAddr;
+               pDescrMem += RX_RING_SIZE;
+               BusAddr += RX_RING_SIZE;
+       } /* for */
+
+       return (SK_TRUE);
+} /* BoardAllocMem */
+
+
+/****************************************************************************
+ *
+ *     BoardFreeMem - reverse of BoardAllocMem
+ *
+ * Description:
+ *     Free all memory allocated in BoardAllocMem: adapter context,
+ *     descriptor rings, locks.
+ *
+ * Returns:    N/A
+ */
+static void BoardFreeMem(
+SK_AC          *pAC)
+{
+size_t         AllocLength;    /* length of complete descriptor area */
+
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("BoardFreeMem\n"));
+#if (BITS_PER_LONG == 32)
+       AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
+#else
+       AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
+               + RX_RING_SIZE + 8;
+#endif
+
+       pci_free_consistent(pAC->PciDev, AllocLength,
+                           pAC->pDescrMem, pAC->pDescrMemDMA);
+       pAC->pDescrMem = NULL;
+} /* BoardFreeMem */
+
+
+/*****************************************************************************
+ *
+ *     BoardInitMem - initiate the descriptor rings
+ *
+ * Description:
+ *     This function sets the descriptor rings up in memory.
+ *     The adapter is initialized with the descriptor start addresses.
+ *
+ * Returns:    N/A
+ */
+static void BoardInitMem(
+SK_AC  *pAC)   /* pointer to adapter context */
+{
+int    i;              /* loop counter */
+int    RxDescrSize;    /* the size of a rx descriptor rounded up to alignment*/
+int    TxDescrSize;    /* the size of a tx descriptor rounded up to alignment*/
+
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("BoardInitMem\n"));
+
+       RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
+       pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize;
+       TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
+       pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize;
+
+       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+               SetupRing(
+                       pAC,
+                       pAC->TxPort[i][0].pTxDescrRing,
+                       pAC->TxPort[i][0].VTxDescrRing,
+                       (RXD**)&pAC->TxPort[i][0].pTxdRingHead,
+                       (RXD**)&pAC->TxPort[i][0].pTxdRingTail,
+                       (RXD**)&pAC->TxPort[i][0].pTxdRingPrev,
+                       &pAC->TxPort[i][0].TxdRingFree,
+                       SK_TRUE);
+               SetupRing(
+                       pAC,
+                       pAC->RxPort[i].pRxDescrRing,
+                       pAC->RxPort[i].VRxDescrRing,
+                       &pAC->RxPort[i].pRxdRingHead,
+                       &pAC->RxPort[i].pRxdRingTail,
+                       &pAC->RxPort[i].pRxdRingPrev,
+                       &pAC->RxPort[i].RxdRingFree,
+                       SK_FALSE);
+       }
+} /* BoardInitMem */
+
+
+/*****************************************************************************
+ *
+ *     SetupRing - create one descriptor ring
+ *
+ * Description:
+ *     This function creates one descriptor ring in the given memory area.
+ *     The head, tail and number of free descriptors in the ring are set.
+ *
+ * Returns:
+ *     none
+ */
+static void SetupRing(
+SK_AC          *pAC,
+void           *pMemArea,      /* a pointer to the memory area for the ring */
+uintptr_t      VMemArea,       /* the virtual bus address of the memory area */
+RXD            **ppRingHead,   /* address where the head should be written */
+RXD            **ppRingTail,   /* address where the tail should be written */
+RXD            **ppRingPrev,   /* address where the tail should be written */
+int            *pRingFree,     /* address where the # of free descr. goes */
+SK_BOOL                IsTx)           /* flag: is this a tx ring */
+{
+int    i;              /* loop counter */
+int    DescrSize;      /* the size of a descriptor rounded up to alignment*/
+int    DescrNum;       /* number of descriptors per ring */
+RXD    *pDescr;        /* pointer to a descriptor (receive or transmit) */
+RXD    *pNextDescr;    /* pointer to the next descriptor */
+RXD    *pPrevDescr;    /* pointer to the previous descriptor */
+uintptr_t VNextDescr;  /* the virtual bus address of the next descriptor */
+
+       if (IsTx == SK_TRUE) {
+               DescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) *
+                       DESCR_ALIGN;
+               DescrNum = TX_RING_SIZE / DescrSize;
+       } else {
+               DescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) *
+                       DESCR_ALIGN;
+               DescrNum = RX_RING_SIZE / DescrSize;
+       }
+
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+               ("Descriptor size: %d   Descriptor Number: %d\n",
+               DescrSize,DescrNum));
+
+       pDescr = (RXD*) pMemArea;
+       pPrevDescr = NULL;
+       pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
+       VNextDescr = VMemArea + DescrSize;
+       for(i=0; i<DescrNum; i++) {
+               /* set the pointers right */
+               pDescr->VNextRxd = VNextDescr & 0xffffffffULL;
+               pDescr->pNextRxd = pNextDescr;
+               pDescr->TcpSumStarts = pAC->CsOfs;
+
+               /* advance one step */
+               pPrevDescr = pDescr;
+               pDescr = pNextDescr;
+               pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
+               VNextDescr += DescrSize;
+       }
+       pPrevDescr->pNextRxd = (RXD*) pMemArea;
+       pPrevDescr->VNextRxd = VMemArea;
+       pDescr = (RXD*) pMemArea;
+       *ppRingHead = (RXD*) pMemArea;
+       *ppRingTail = *ppRingHead;
+       *ppRingPrev = pPrevDescr;
+       *pRingFree = DescrNum;
+} /* SetupRing */
+
+
+/*****************************************************************************
+ *
+ *     PortReInitBmu - re-initiate the descriptor rings for one port
+ *
+ * Description:
+ *     This function reinitializes the descriptor rings of one port
+ *     in memory. The port must be stopped before.
+ *     The HW is initialized with the descriptor start addresses.
+ *
+ * Returns:
+ *     none
+ */
+static void PortReInitBmu(
+SK_AC  *pAC,           /* pointer to adapter context */
+int    PortIndex)      /* index of the port for which to re-init */
+{
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("PortReInitBmu "));
+
+       /* set address of first descriptor of ring in BMU */
+       SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+
+               TX_Q_CUR_DESCR_LOW,
+               (uint32_t)(((caddr_t)
+               (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
+               pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
+               pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) &
+               0xFFFFFFFF));
+       SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+
+               TX_Q_DESCR_HIGH,
+               (uint32_t)(((caddr_t)
+               (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
+               pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
+               pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) >> 32));
+       SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+RX_Q_CUR_DESCR_LOW,
+               (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
+               pAC->RxPort[PortIndex].pRxDescrRing +
+               pAC->RxPort[PortIndex].VRxDescrRing) & 0xFFFFFFFF));
+       SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+RX_Q_DESCR_HIGH,
+               (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
+               pAC->RxPort[PortIndex].pRxDescrRing +
+               pAC->RxPort[PortIndex].VRxDescrRing) >> 32));
+} /* PortReInitBmu */
+
+
+/****************************************************************************
+ *
+ *     SkGeIsr - handle adapter interrupts
+ *
+ * Description:
+ *     The interrupt routine is called when the network adapter
+ *     generates an interrupt. It may also be called if another device
+ *     shares this interrupt vector with the driver.
+ *
+ * Returns: N/A
+ *
+ */
+#if 0
+static void SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs)
+#else
+void SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs)
+#endif
+{
+struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
+DEV_NET                *pNet;
+SK_AC          *pAC;
+SK_U32         IntSrc;         /* interrupts source register contents */
+
+       pNet = (DEV_NET*) dev->priv;
+       pAC = pNet->pAC;
+
+       /*
+        * Check and process if its our interrupt
+        */
+       SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
+       if (IntSrc == 0) {
+               return;
+       }
+
+       while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
+#if 0 /* software irq currently not used */
+               if (IntSrc & IRQ_SW) {
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("Software IRQ\n"));
+               }
+#endif
+               if (IntSrc & IRQ_EOF_RX1) {
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF RX1 IRQ\n"));
+                       ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
+                       SK_PNMI_CNT_RX_INTR(pAC, 0);
+               }
+               if (IntSrc & IRQ_EOF_RX2) {
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF RX2 IRQ\n"));
+                       ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
+                       SK_PNMI_CNT_RX_INTR(pAC, 1);
+               }
+#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
+               if (IntSrc & IRQ_EOF_AS_TX1) {
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF AS TX1 IRQ\n"));
+                       SK_PNMI_CNT_TX_INTR(pAC, 0);
+                       spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
+                       FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
+                       spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
+               }
+               if (IntSrc & IRQ_EOF_AS_TX2) {
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF AS TX2 IRQ\n"));
+                       SK_PNMI_CNT_TX_INTR(pAC, 1);
+                       spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
+                       FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]);
+                       spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
+               }
+#if 0 /* only if sync. queues used */
+               if (IntSrc & IRQ_EOF_SY_TX1) {
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF SY TX1 IRQ\n"));
+                       SK_PNMI_CNT_TX_INTR(pAC, 1);
+                       spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
+                       FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
+                       spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
+                       ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
+               }
+               if (IntSrc & IRQ_EOF_SY_TX2) {
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF SY TX2 IRQ\n"));
+                       SK_PNMI_CNT_TX_INTR(pAC, 1);
+                       spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
+                       FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH);
+                       spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
+                       ClearTxIrq(pAC, 1, TX_PRIO_HIGH);
+               }
+#endif
+#endif
+
+               /* do all IO at once */
+               if (IntSrc & IRQ_EOF_RX1)
+                       ClearAndStartRx(pAC, 0);
+               if (IntSrc & IRQ_EOF_RX2)
+                       ClearAndStartRx(pAC, 1);
+#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
+               if (IntSrc & IRQ_EOF_AS_TX1)
+                       ClearTxIrq(pAC, 0, TX_PRIO_LOW);
+               if (IntSrc & IRQ_EOF_AS_TX2)
+                       ClearTxIrq(pAC, 1, TX_PRIO_LOW);
+#endif
+               SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
+       } /* while (IntSrc & IRQ_MASK != 0) */
+
+       if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+                       ("SPECIAL IRQ DP-Cards => %x\n", IntSrc));
+               pAC->CheckQueue = SK_FALSE;
+               spin_lock(&pAC->SlowPathLock);
+               if (IntSrc & SPECIAL_IRQS)
+                       SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
+
+               SkEventDispatcher(pAC, pAC->IoBase);
+               spin_unlock(&pAC->SlowPathLock);
+       }
+       /*
+        * do it all again is case we cleared an interrupt that
+        * came in after handling the ring (OUTs may be delayed
+        * in hardware buffers, but are through after IN)
+        */
+
+       ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
+       ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
+
+       if (pAC->CheckQueue) {
+               pAC->CheckQueue = SK_FALSE;
+               spin_lock(&pAC->SlowPathLock);
+               SkEventDispatcher(pAC, pAC->IoBase);
+               spin_unlock(&pAC->SlowPathLock);
+       }
+
+
+       /* IRQ is processed - Enable IRQs again*/
+       SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK);
+
+       return;
+} /* SkGeIsr */
+
+
+/****************************************************************************
+ *
+ *     SkGeIsrOnePort - handle adapter interrupts for single port adapter
+ *
+ * Description:
+ *     The interrupt routine is called when the network adapter
+ *     generates an interrupt. It may also be called if another device
+ *     shares this interrupt vector with the driver.
+ *     This is the same as above, but handles only one port.
+ *
+ * Returns: N/A
+ *
+ */
+#if 0
+static void SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs)
+#else
+void SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs)
+#endif
+{
+struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
+DEV_NET                *pNet;
+SK_AC          *pAC;
+SK_U32         IntSrc;         /* interrupts source register contents */
+
+       pNet = (DEV_NET*) dev->priv;
+       pAC = pNet->pAC;
+
+       /*
+        * Check and process if its our interrupt
+        */
+       SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
+       if (IntSrc == 0) {
+               return;
+       }
+
+       while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
+#if 0 /* software irq currently not used */
+               if (IntSrc & IRQ_SW) {
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("Software IRQ\n"));
+               }
+#endif
+               if (IntSrc & IRQ_EOF_RX1) {
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF RX1 IRQ\n"));
+                       ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
+                       SK_PNMI_CNT_RX_INTR(pAC, 0);
+               }
+#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
+               if (IntSrc & IRQ_EOF_AS_TX1) {
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF AS TX1 IRQ\n"));
+                       SK_PNMI_CNT_TX_INTR(pAC, 0);
+                       spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
+                       FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
+                       spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
+               }
+#if 0 /* only if sync. queues used */
+               if (IntSrc & IRQ_EOF_SY_TX1) {
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF SY TX1 IRQ\n"));
+                       SK_PNMI_CNT_TX_INTR(pAC, 0);
+                       spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
+                       FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
+                       spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
+                       ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
+               }
+#endif
+#endif
+
+               /* do all IO at once */
+               if (IntSrc & IRQ_EOF_RX1)
+                       ClearAndStartRx(pAC, 0);
+#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
+               if (IntSrc & IRQ_EOF_AS_TX1)
+                       ClearTxIrq(pAC, 0, TX_PRIO_LOW);
+#endif
+               SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
+       } /* while (IntSrc & IRQ_MASK != 0) */
+
+       if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+                       ("SPECIAL IRQ SP-Cards => %x\n", IntSrc));
+               pAC->CheckQueue = SK_FALSE;
+               spin_lock(&pAC->SlowPathLock);
+               if (IntSrc & SPECIAL_IRQS)
+                       SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
+
+               SkEventDispatcher(pAC, pAC->IoBase);
+               spin_unlock(&pAC->SlowPathLock);
+       }
+       /*
+        * do it all again is case we cleared an interrupt that
+        * came in after handling the ring (OUTs may be delayed
+        * in hardware buffers, but are through after IN)
+        */
+       ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
+
+       /* IRQ is processed - Enable IRQs again*/
+       SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK);
+
+       return;
+} /* SkGeIsrOnePort */
+
+
+/****************************************************************************
+ *
+ *     SkGeOpen - handle start of initialized adapter
+ *
+ * Description:
+ *     This function starts the initialized adapter.
+ *     The board level variable is set and the adapter is
+ *     brought to full functionality.
+ *     The device flags are set for operation.
+ *     Do all necessary level 2 initialization, enable interrupts and
+ *     give start command to RLMT.
+ *
+ * Returns:
+ *     0 on success
+ *     != 0 on error
+ */
+#if 0
+static int SkGeOpen(
+#else
+int SkGeOpen(
+#endif
+struct SK_NET_DEVICE   *dev)
+{
+       DEV_NET                 *pNet;
+       SK_AC                   *pAC;
+       unsigned long   Flags;          /* for spin lock */
+       int                             i;
+       SK_EVPARA               EvPara;         /* an event parameter union */
+
+       pNet = (DEV_NET*) dev->priv;
+       pAC = pNet->pAC;
+
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC));
+
+       if (pAC->BoardLevel == 0) {
+               /* level 1 init common modules here */
+               if (SkGeInit(pAC, pAC->IoBase, 1) != 0) {
+                       printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name);
+                       return (-1);
+               }
+               SkI2cInit       (pAC, pAC->IoBase, 1);
+               SkEventInit     (pAC, pAC->IoBase, 1);
+               SkPnmiInit      (pAC, pAC->IoBase, 1);
+               SkAddrInit      (pAC, pAC->IoBase, 1);
+               SkRlmtInit      (pAC, pAC->IoBase, 1);
+               SkTimerInit     (pAC, pAC->IoBase, 1);
+               pAC->BoardLevel = 1;
+       }
+
+       if (pAC->BoardLevel != 2) {
+               /* tschilling: Level 2 init modules here, check return value. */
+               if (SkGeInit(pAC, pAC->IoBase, 2) != 0) {
+                       printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name);
+                       return (-1);
+               }
+               SkI2cInit       (pAC, pAC->IoBase, 2);
+               SkEventInit     (pAC, pAC->IoBase, 2);
+               SkPnmiInit      (pAC, pAC->IoBase, 2);
+               SkAddrInit      (pAC, pAC->IoBase, 2);
+               SkRlmtInit      (pAC, pAC->IoBase, 2);
+               SkTimerInit     (pAC, pAC->IoBase, 2);
+               pAC->BoardLevel = 2;
+       }
+
+       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+               /* Enable transmit descriptor polling. */
+               SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
+               FillRxRing(pAC, &pAC->RxPort[i]);
+       }
+       SkGeYellowLED(pAC, pAC->IoBase, 1);
+
+#ifdef USE_INT_MOD
+/* moderate only TX complete interrupts (these are not time critical) */
+#define IRQ_MOD_MASK (IRQ_EOF_AS_TX1 | IRQ_EOF_AS_TX2)
+       {
+               unsigned long ModBase;
+               ModBase = 53125000 / INTS_PER_SEC;
+               SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
+               SK_OUT32(pAC->IoBase, B2_IRQM_MSK, IRQ_MOD_MASK);
+               SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
+       }
+#endif
+
+       /* enable Interrupts */
+       SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK);
+       SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
+
+       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+
+       if ((pAC->RlmtMode != 0) && (pAC->MaxPorts == 0)) {
+               EvPara.Para32[0] = pAC->RlmtNets;
+               EvPara.Para32[1] = -1;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
+                       EvPara);
+               EvPara.Para32[0] = pAC->RlmtMode;
+               EvPara.Para32[1] = 0;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE,
+                       EvPara);
+       }
+
+       EvPara.Para32[0] = pNet->NetNr;
+       EvPara.Para32[1] = -1;
+       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+       SkEventDispatcher(pAC, pAC->IoBase);
+       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+
+       pAC->MaxPorts++;
+       pNet->Up = 1;
+
+       MOD_INC_USE_COUNT;
+
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeOpen suceeded\n"));
+
+       return (0);
+} /* SkGeOpen */
+
+
+/****************************************************************************
+ *
+ *     SkGeClose - Stop initialized adapter
+ *
+ * Description:
+ *     Close initialized adapter.
+ *
+ * Returns:
+ *     0 - on success
+ *     error code - on error
+ */
+#if 0
+static int SkGeClose(
+#else
+int SkGeClose(
+#endif
+struct SK_NET_DEVICE   *dev)
+{
+       DEV_NET                 *pNet;
+       SK_AC                   *pAC;
+
+       unsigned long   Flags;          /* for spin lock */
+       int                             i;
+       int                             PortIdx;
+       SK_EVPARA               EvPara;
+
+       netif_stop_queue(dev);
+       pNet = (DEV_NET*) dev->priv;
+       pAC = pNet->pAC;
+
+       if (pAC->RlmtNets == 1)
+               PortIdx = pAC->ActivePort;
+       else
+               PortIdx = pNet->NetNr;
+
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
+
+       /*
+        * Clear multicast table, promiscuous mode ....
+        */
+       SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
+       SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
+               SK_PROM_MODE_NONE);
+
+       if (pAC->MaxPorts == 1) {
+               spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+               /* disable interrupts */
+               SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+               EvPara.Para32[0] = pNet->NetNr;
+               EvPara.Para32[1] = -1;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+               SkEventDispatcher(pAC, pAC->IoBase);
+               SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+               /* stop the hardware */
+               SkGeDeInit(pAC, pAC->IoBase);
+               pAC->BoardLevel = 0;
+               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+       } else {
+
+               spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+               EvPara.Para32[0] = pNet->NetNr;
+               EvPara.Para32[1] = -1;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+               SkEventDispatcher(pAC, pAC->IoBase);
+               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+
+               /* Stop port */
+               spin_lock_irqsave(&pAC->TxPort[pNet->PortNr]
+                       [TX_PRIO_LOW].TxDesRingLock, Flags);
+               SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr,
+                       SK_STOP_ALL, SK_HARD_RST);
+               spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr]
+                       [TX_PRIO_LOW].TxDesRingLock, Flags);
+       }
+
+       if (pAC->RlmtNets == 1) {
+               /* clear all descriptor rings */
+               for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+                       ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
+                       ClearRxRing(pAC, &pAC->RxPort[i]);
+                       ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]);
+               }
+       } else {
+               /* clear port descriptor rings */
+               ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE);
+               ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
+               ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]);
+       }
+
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeClose: done "));
+
+       pAC->MaxPorts--;
+       pNet->Up = 0;
+       MOD_DEC_USE_COUNT;
+
+       return (0);
+} /* SkGeClose */
+
+
+/*****************************************************************************
+ *
+ *     SkGeXmit - Linux frame transmit function
+ *
+ * Description:
+ *     The system calls this function to send frames onto the wire.
+ *     It puts the frame in the tx descriptor ring. If the ring is
+ *     full then, the 'tbusy' flag is set.
+ *
+ * Returns:
+ *     0, if everything is ok
+ *     !=0, on error
+ * WARNING: returning 1 in 'tbusy' case caused system crashes (double
+ *     allocated skb's) !!!
+ */
+#if 0
+static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev)
+#else
+int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev)
+#endif
+{
+DEV_NET                *pNet;
+SK_AC          *pAC;
+int                    Rc;     /* return code of XmitFrame */
+
+       pNet = (DEV_NET*) dev->priv;
+       pAC = pNet->pAC;
+
+#if 0
+       if ((!skb_shinfo(skb)->nr_frags) ||
+#else
+       if (1 ||
+#endif
+               (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) {
+               /* Don't activate scatter-gather and hardware checksum */
+
+               if (pAC->RlmtNets == 2)
+                       Rc = XmitFrame(
+                               pAC,
+                               &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
+                               skb);
+               else
+                       Rc = XmitFrame(
+                               pAC,
+                               &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
+                               skb);
+       } else {
+#if 0
+               /* scatter-gather and hardware TCP checksumming anabled*/
+               if (pAC->RlmtNets == 2)
+                       Rc = XmitFrameSG(
+                               pAC,
+                               &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
+                               skb);
+               else
+                       Rc = XmitFrameSG(
+                               pAC,
+                               &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
+                               skb);
+#endif
+       }
+
+       /* Transmitter out of resources? */
+       if (Rc <= 0) {
+               netif_stop_queue(dev);
+       }
+
+       /* If not taken, give buffer ownership back to the
+        * queueing layer.
+        */
+       if (Rc < 0)
+               return (1);
+
+#if 0
+       dev->trans_start = jiffies;
+#endif
+       return (0);
+} /* SkGeXmit */
+
+
+/*****************************************************************************
+ *
+ *     XmitFrame - fill one socket buffer into the transmit ring
+ *
+ * Description:
+ *     This function puts a message into the transmit descriptor ring
+ *     if there is a descriptors left.
+ *     Linux skb's consist of only one continuous buffer.
+ *     The first step locks the ring. It is held locked
+ *     all time to avoid problems with SWITCH_../PORT_RESET.
+ *     Then the descriptoris allocated.
+ *     The second part is linking the buffer to the descriptor.
+ *     At the very last, the Control field of the descriptor
+ *     is made valid for the BMU and a start TX command is given
+ *     if necessary.
+ *
+ * Returns:
+ *     > 0 - on succes: the number of bytes in the message
+ *     = 0 - on resource shortage: this frame sent or dropped, now
+ *             the ring is full ( -> set tbusy)
+ *     < 0 - on failure: other problems ( -> return failure to upper layers)
+ */
+static int XmitFrame(
+SK_AC          *pAC,           /* pointer to adapter context */
+TX_PORT                *pTxPort,       /* pointer to struct of port to send to */
+struct sk_buff *pMessage)      /* pointer to send-message */
+{
+TXD            *pTxd;          /* the rxd to fill */
+unsigned long  Flags;
+SK_U64         PhysAddr;
+int            BytesSend;
+
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+               ("X"));
+
+       spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
+#ifndef USE_TX_COMPLETE
+       FreeTxDescriptors(pAC, pTxPort);
+#endif
+       if (pTxPort->TxdRingFree == 0) {
+               /* no enough free descriptors in ring at the moment */
+               FreeTxDescriptors(pAC, pTxPort);
+               if (pTxPort->TxdRingFree == 0) {
+                       spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
+                       SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_TX_PROGRESS,
+                               ("XmitFrame failed\n"));
+                       /* this message can not be sent now */
+                       /* Because tbusy seems to be set, the message should not be freed here */
+                       /* It will be used by the scheduler of the ethernet handler */
+                       return (-1);
+               }
+       }
+       /* advance head counter behind descriptor needed for this frame */
+       pTxd = pTxPort->pTxdRingHead;
+       pTxPort->pTxdRingHead = pTxd->pNextTxd;
+       pTxPort->TxdRingFree--;
+       /* the needed descriptor is reserved now */
+
+       /*
+        * everything allocated ok, so add buffer to descriptor
+        */
+
+#ifdef SK_DUMP_TX
+       DumpMsg(pMessage, "XmitFrame");
+#endif
+
+       /* set up descriptor and CONTROL dword */
+#if 0
+       PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
+               virt_to_page(pMessage->data),
+               ((unsigned long) pMessage->data &
+               ~PAGE_MASK),
+               pMessage->len,
+               PCI_DMA_TODEVICE);
+#else
+       PhysAddr = (SK_U64) pci_phys_to_mem(pAC->PciDev, (u32) pMessage->data);
+#endif
+       pTxd->VDataLow = (SK_U32)  (PhysAddr & 0xffffffff);
+       pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
+       pTxd->pMBuf = pMessage;
+       pTxd->TBControl = TX_CTRL_OWN_BMU | TX_CTRL_STF |
+               TX_CTRL_CHECK_DEFAULT | TX_CTRL_SOFTWARE |
+#ifdef USE_TX_COMPLETE
+               TX_CTRL_EOF | TX_CTRL_EOF_IRQ | pMessage->len;
+#else
+               TX_CTRL_EOF | pMessage->len;
+#endif
+
+       if ((pTxPort->pTxdRingPrev->TBControl & TX_CTRL_OWN_BMU) == 0) {
+               /* previous descriptor already done, so give tx start cmd */
+               /* StartTx(pAC, pTxPort->HwAddr); */
+               SK_OUT8(pTxPort->HwAddr, TX_Q_CTRL, TX_Q_CTRL_START);
+       }
+       pTxPort->pTxdRingPrev = pTxd;
+
+
+       BytesSend = pMessage->len;
+       spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
+       /* after releasing the lock, the skb may be immidiately freed */
+       if (pTxPort->TxdRingFree != 0)
+               return (BytesSend);
+       else
+               return (0);
+
+} /* XmitFrame */
+
+/*****************************************************************************
+ *
+ *     XmitFrameSG - fill one socket buffer into the transmit ring
+ *                (use SG and TCP/UDP hardware checksumming)
+ *
+ * Description:
+ *     This function puts a message into the transmit descriptor ring
+ *     if there is a descriptors left.
+ *
+ * Returns:
+ *     > 0 - on succes: the number of bytes in the message
+ *     = 0 - on resource shortage: this frame sent or dropped, now
+ *             the ring is full ( -> set tbusy)
+ *     < 0 - on failure: other problems ( -> return failure to upper layers)
+ */
+#if 0
+static int XmitFrameSG(
+SK_AC          *pAC,                   /* pointer to adapter context */
+TX_PORT                *pTxPort,               /* pointer to struct of port to send to */
+struct sk_buff *pMessage)      /* pointer to send-message */
+{
+
+       int             i;
+       int                     BytesSend;
+       int                     hlength;
+       int                     protocol;
+       skb_frag_t              *sk_frag;
+       TXD                     *pTxd;
+       TXD                     *pTxdFst;
+       TXD                     *pTxdLst;
+       SK_U64          PhysAddr;
+       unsigned long   Flags;
+
+       spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
+#ifndef USE_TX_COMPLETE
+       FreeTxDescriptors(pAC, pTxPort);
+#endif
+       if ((skb_shinfo(pMessage)->nr_frags +1) > pTxPort->TxdRingFree) {
+               FreeTxDescriptors(pAC, pTxPort);
+               if ((skb_shinfo(pMessage)->nr_frags + 1) > pTxPort->TxdRingFree) {
+                       spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
+                       SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_TX_PROGRESS,
+                               ("XmitFrameSG failed - Ring full\n"));
+                               /* this message can not be sent now */
+                       return(-1);
+               }
+       }
+
+
+       pTxd = pTxPort->pTxdRingHead;
+       pTxdFst = pTxd;
+       pTxdLst = pTxd;
+       BytesSend = 0;
+       protocol = 0;
+
+       /* map first fragment (header) */
+       PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
+                       virt_to_page(pMessage->data),
+                       ((unsigned long) pMessage->data & ~PAGE_MASK),
+                       skb_headlen(pMessage),
+                       PCI_DMA_TODEVICE);
+
+       pTxd->VDataLow = (SK_U32)  (PhysAddr & 0xffffffff);
+       pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
+
+       /* HW checksum? */
+       if (pMessage->ip_summed == CHECKSUM_HW) {
+               pTxd->TBControl = TX_CTRL_STF |
+                                 TX_CTRL_ST_FWD |
+                                 skb_headlen(pMessage);
+
+               /* We have to use the opcode for tcp here because the opcode for
+               udp is not working in the hardware yet (revision 2.0)*/
+               protocol = ((SK_U8)pMessage->data[23] & 0xf);
+               if ((protocol == 17) && (pAC->GIni.GIChipRev != 0))
+                       pTxd->TBControl |=  BMU_UDP_CHECK;
+               else
+                       pTxd->TBControl |= BMU_TCP_CHECK ;
+
+               hlength = ((SK_U8)pMessage->data[14] & 0xf) * 4;
+               pTxd->TcpSumOfs = 0; /* PH-Checksum already claculated */
+               pTxd->TcpSumSt = 14+hlength+16;
+               pTxd->TcpSumWr = 14+hlength;
+
+       } else {
+               pTxd->TBControl = TX_CTRL_CHECK_DEFAULT |
+                                 TX_CTRL_SOFTWARE |
+                                 TX_CTRL_STF |
+                                 skb_headlen(pMessage);
+       }
+
+       pTxd = pTxd->pNextTxd;
+       pTxPort->TxdRingFree--;
+       BytesSend += skb_headlen(pMessage);
+
+
+       /* Map SG fragments */
+       for (i = 0; i < skb_shinfo(pMessage)->nr_frags; i++) {
+               sk_frag = &skb_shinfo(pMessage)->frags[i];
+
+               /* we already have the proper value in entry */
+               PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
+                                                sk_frag->page,
+                                                sk_frag->page_offset,
+                                                sk_frag->size,
+                                                PCI_DMA_TODEVICE);
+
+               pTxd->VDataLow = (SK_U32)  (PhysAddr & 0xffffffff);
+               pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
+               pTxd->pMBuf = pMessage;
+
+               /* HW checksum */
+               if (pMessage->ip_summed == CHECKSUM_HW) {
+                       pTxd->TBControl = TX_CTRL_OWN_BMU |
+                                         TX_CTRL_SOFTWARE |
+                                         TX_CTRL_ST_FWD;
+
+                       /* We have to use the opcode for tcp here because the opcode for
+                       udp is not working in the hardware yet (revision 2.0)*/
+                       if ((protocol == 17) && (pAC->GIni.GIChipRev != 0))
+                               pTxd->TBControl |= BMU_UDP_CHECK ;
+                       else
+                               pTxd->TBControl |= BMU_TCP_CHECK ;
+
+               } else {
+                       pTxd->TBControl = TX_CTRL_CHECK_DEFAULT |
+                                         TX_CTRL_SOFTWARE |
+                                         TX_CTRL_OWN_BMU;
+               }
+
+               /* Last fragment  */
+               if( (i+1) == skb_shinfo(pMessage)->nr_frags )  {
+#ifdef USE_TX_COMPLETE
+                       pTxd->TBControl |= TX_CTRL_EOF |
+                                          TX_CTRL_EOF_IRQ |
+                                          sk_frag->size;
+#else
+                       pTxd->TBControl |= TX_CTRL_EOF |
+                                          sk_frag->size;
+#endif
+                       pTxdFst->TBControl |= TX_CTRL_OWN_BMU |
+                                             TX_CTRL_SOFTWARE;
+
+               } else {
+                       pTxd->TBControl |= sk_frag->size;
+               }
+               pTxdLst = pTxd;
+               pTxd = pTxd->pNextTxd;
+               pTxPort->TxdRingFree--;
+               BytesSend += sk_frag->size;
+       }
+
+       if ((pTxPort->pTxdRingPrev->TBControl & TX_CTRL_OWN_BMU) == 0) {
+               /* previous descriptor already done, so give tx start cmd */
+               /* StartTx(pAC, pTxPort->HwAddr); */
+               SK_OUT8(pTxPort->HwAddr, TX_Q_CTRL, TX_Q_CTRL_START);
+       }
+
+       pTxPort->pTxdRingPrev = pTxdLst;
+       pTxPort->pTxdRingHead = pTxd;
+
+       spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
+
+       if (pTxPort->TxdRingFree > 0)
+               return (BytesSend);
+       else
+               return (0);
+}
+#endif
+
+
+void dump_frag( SK_U8 *data, int length)
+{
+       int i;
+
+       printk("Length: %d\n", length);
+       for( i=0; i < length; i++ ) {
+               printk(" %02x", (SK_U8)*(data + i) );
+               if( !((i+1) % 20) )
+                 printk("\n");
+       }
+       printk("\n\n");
+
+}
+
+
+/*****************************************************************************
+ *
+ *     FreeTxDescriptors - release descriptors from the descriptor ring
+ *
+ * Description:
+ *     This function releases descriptors from a transmit ring if they
+ *     have been sent by the BMU.
+ *     If a descriptors is sent, it can be freed and the message can
+ *     be freed, too.
+ *     The SOFTWARE controllable bit is used to prevent running around a
+ *     completely free ring for ever. If this bit is no set in the
+ *     frame (by XmitFrame), this frame has never been sent or is
+ *     already freed.
+ *     The Tx descriptor ring lock must be held while calling this function !!!
+ *
+ * Returns:
+ *     none
+ */
+static void FreeTxDescriptors(
+SK_AC  *pAC,           /* pointer to the adapter context */
+TX_PORT        *pTxPort)       /* pointer to destination port structure */
+{
+TXD    *pTxd;          /* pointer to the checked descriptor */
+TXD    *pNewTail;      /* pointer to 'end' of the ring */
+SK_U32 Control;        /* TBControl field of descriptor */
+SK_U64 PhysAddr;       /* address of DMA mapping */
+
+       pNewTail = pTxPort->pTxdRingTail;
+       pTxd = pNewTail;
+       /*
+        * loop forever; exits if TX_CTRL_SOFTWARE bit not set in start frame
+        * or TX_CTRL_OWN_BMU bit set in any frame
+        */
+       while (1) {
+               Control = pTxd->TBControl;
+               if ((Control & TX_CTRL_SOFTWARE) == 0) {
+                       /*
+                        * software controllable bit is set in first
+                        * fragment when given to BMU. Not set means that
+                        * this fragment was never sent or is already
+                        * freed ( -> ring completely free now).
+                        */
+                       pTxPort->pTxdRingTail = pTxd;
+                       netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
+                       return;
+               }
+               if (Control & TX_CTRL_OWN_BMU) {
+                       pTxPort->pTxdRingTail = pTxd;
+                       if (pTxPort->TxdRingFree > 0) {
+                               netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
+                       }
+                       return;
+               }
+
+               /* release the DMA mapping */
+               PhysAddr = ((SK_U64) pTxd->VDataHigh) << (SK_U64) 32;
+               PhysAddr |= (SK_U64) pTxd->VDataLow;
+               pci_unmap_page(pAC->PciDev, PhysAddr,
+                                pTxd->pMBuf->len,
+                                PCI_DMA_TODEVICE);
+
+               if (Control & TX_CTRL_EOF)
+                       DEV_KFREE_SKB_ANY(pTxd->pMBuf); /* free message */
+
+               pTxPort->TxdRingFree++;
+               pTxd->TBControl &= ~TX_CTRL_SOFTWARE;
+               pTxd = pTxd->pNextTxd; /* point behind fragment with EOF */
+       } /* while(forever) */
+} /* FreeTxDescriptors */
+
+/*****************************************************************************
+ *
+ *     FillRxRing - fill the receive ring with valid descriptors
+ *
+ * Description:
+ *     This function fills the receive ring descriptors with data
+ *     segments and makes them valid for the BMU.
+ *     The active ring is filled completely, if possible.
+ *     The non-active ring is filled only partial to save memory.
+ *
+ * Description of rx ring structure:
+ *     head - points to the descriptor which will be used next by the BMU
+ *     tail - points to the next descriptor to give to the BMU
+ *
+ * Returns:    N/A
+ */
+static void FillRxRing(
+SK_AC          *pAC,           /* pointer to the adapter context */
+RX_PORT                *pRxPort)       /* ptr to port struct for which the ring
+                                  should be filled */
+{
+unsigned long  Flags;
+
+       spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
+       while (pRxPort->RxdRingFree > pRxPort->RxFillLimit) {
+               if(!FillRxDescriptor(pAC, pRxPort))
+                       break;
+       }
+       spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
+} /* FillRxRing */
+
+
+/*****************************************************************************
+ *
+ *     FillRxDescriptor - fill one buffer into the receive ring
+ *
+ * Description:
+ *     The function allocates a new receive buffer and
+ *     puts it into the next descriptor.
+ *
+ * Returns:
+ *     SK_TRUE - a buffer was added to the ring
+ *     SK_FALSE - a buffer could not be added
+ */
+static SK_BOOL FillRxDescriptor(
+SK_AC          *pAC,           /* pointer to the adapter context struct */
+RX_PORT                *pRxPort)       /* ptr to port struct of ring to fill */
+{
+struct sk_buff *pMsgBlock;     /* pointer to a new message block */
+RXD            *pRxd;          /* the rxd to fill */
+SK_U16         Length;         /* data fragment length */
+SK_U64         PhysAddr;       /* physical address of a rx buffer */
+
+       pMsgBlock = alloc_skb(pAC->RxBufSize, GFP_ATOMIC);
+       if (pMsgBlock == NULL) {
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                       SK_DBGCAT_DRV_ENTRY,
+                       ("%s: Allocation of rx buffer failed !\n",
+                       pAC->dev[pRxPort->PortIndex]->name));
+               SK_PNMI_CNT_NO_RX_BUF(pAC, pRxPort->PortIndex);
+               return(SK_FALSE);
+       }
+       skb_reserve(pMsgBlock, 2); /* to align IP frames */
+       /* skb allocated ok, so add buffer */
+       pRxd = pRxPort->pRxdRingTail;
+       pRxPort->pRxdRingTail = pRxd->pNextRxd;
+       pRxPort->RxdRingFree--;
+       Length = pAC->RxBufSize;
+#if 0
+       PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
+               virt_to_page(pMsgBlock->data),
+               ((unsigned long) pMsgBlock->data &
+               ~PAGE_MASK),
+               pAC->RxBufSize - 2,
+               PCI_DMA_FROMDEVICE);
+#else
+       PhysAddr = (SK_U64) pci_phys_to_mem(pAC->PciDev, (u32)pMsgBlock->data);
+#endif
+       pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
+       pRxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
+       pRxd->pMBuf = pMsgBlock;
+       pRxd->RBControl = RX_CTRL_OWN_BMU | RX_CTRL_STF |
+               RX_CTRL_EOF_IRQ | RX_CTRL_CHECK_CSUM | Length;
+       return (SK_TRUE);
+
+} /* FillRxDescriptor */
+
+
+/*****************************************************************************
+ *
+ *     ReQueueRxBuffer - fill one buffer back into the receive ring
+ *
+ * Description:
+ *     Fill a given buffer back into the rx ring. The buffer
+ *     has been previously allocated and aligned, and its phys.
+ *     address calculated, so this is no more necessary.
+ *
+ * Returns: N/A
+ */
+static void ReQueueRxBuffer(
+SK_AC          *pAC,           /* pointer to the adapter context struct */
+RX_PORT                *pRxPort,       /* ptr to port struct of ring to fill */
+struct sk_buff *pMsg,          /* pointer to the buffer */
+SK_U32         PhysHigh,       /* phys address high dword */
+SK_U32         PhysLow)        /* phys address low dword */
+{
+RXD            *pRxd;          /* the rxd to fill */
+SK_U16         Length;         /* data fragment length */
+
+       pRxd = pRxPort->pRxdRingTail;
+       pRxPort->pRxdRingTail = pRxd->pNextRxd;
+       pRxPort->RxdRingFree--;
+       Length = pAC->RxBufSize;
+       pRxd->VDataLow = PhysLow;
+       pRxd->VDataHigh = PhysHigh;
+       pRxd->pMBuf = pMsg;
+       pRxd->RBControl = RX_CTRL_OWN_BMU | RX_CTRL_STF |
+               RX_CTRL_EOF_IRQ | RX_CTRL_CHECK_CSUM | Length;
+       return;
+} /* ReQueueRxBuffer */
+
+
+/*****************************************************************************
+ *
+ *     ReceiveIrq - handle a receive IRQ
+ *
+ * Description:
+ *     This function is called when a receive IRQ is set.
+ *     It walks the receive descriptor ring and sends up all
+ *     frames that are complete.
+ *
+ * Returns:    N/A
+ */
+#if 0
+static void ReceiveIrq(
+#else
+void ReceiveIrq(
+#endif
+       SK_AC           *pAC,                   /* pointer to adapter context */
+       RX_PORT         *pRxPort,               /* pointer to receive port struct */
+       SK_BOOL         SlowPathLock)   /* indicates if SlowPathLock is needed */
+{
+RXD                            *pRxd;                  /* pointer to receive descriptors */
+SK_U32                 Control;                /* control field of descriptor */
+struct sk_buff *pMsg;                  /* pointer to message holding frame */
+struct sk_buff *pNewMsg;               /* pointer to a new message for copying frame */
+int                            FrameLength;    /* total length of received frame */
+SK_MBUF                        *pRlmtMbuf;             /* ptr to a buffer for giving a frame to rlmt */
+SK_EVPARA              EvPara;                 /* an event parameter union */
+unsigned long  Flags;                  /* for spin lock */
+int                            PortIndex = pRxPort->PortIndex;
+unsigned int   Offset;
+unsigned int   NumBytes;
+unsigned int   ForRlmt;
+SK_BOOL                        IsBc;
+SK_BOOL                        IsMc;
+SK_BOOL  IsBadFrame;                   /* Bad frame */
+
+SK_U32                 FrameStat;
+unsigned short Csum1;
+unsigned short Csum2;
+unsigned short Type;
+#if 0
+int                            Result;
+#endif
+SK_U64                 PhysAddr;
+
+rx_start:
+       /* do forever; exit if RX_CTRL_OWN_BMU found */
+       for ( pRxd = pRxPort->pRxdRingHead ;
+                 pRxPort->RxdRingFree < pAC->RxDescrPerRing ;
+                 pRxd = pRxd->pNextRxd,
+                 pRxPort->pRxdRingHead = pRxd,
+                 pRxPort->RxdRingFree ++) {
+
+               /*
+                * For a better understanding of this loop
+                * Go through every descriptor beginning at the head
+                * Please note: the ring might be completely received so the OWN bit
+                * set is not a good crirteria to leave that loop.
+                * Therefore the RingFree counter is used.
+                * On entry of this loop pRxd is a pointer to the Rxd that needs
+                * to be checked next.
+                */
+
+               Control = pRxd->RBControl;
+
+               /* check if this descriptor is ready */
+               if ((Control & RX_CTRL_OWN_BMU) != 0) {
+                       /* this descriptor is not yet ready */
+                       /* This is the usual end of the loop */
+                       /* We don't need to start the ring again */
+                       FillRxRing(pAC, pRxPort);
+                       return;
+               }
+
+               /* get length of frame and check it */
+               FrameLength = Control & RX_CTRL_LEN_MASK;
+               if (FrameLength > pAC->RxBufSize) {
+                       goto rx_failed;
+               }
+
+               /* check for STF and EOF */
+               if ((Control & (RX_CTRL_STF | RX_CTRL_EOF)) !=
+                       (RX_CTRL_STF | RX_CTRL_EOF)) {
+                       goto rx_failed;
+               }
+
+               /* here we have a complete frame in the ring */
+               pMsg = pRxd->pMBuf;
+
+               FrameStat = pRxd->FrameStat;
+
+               /* check for frame length mismatch */
+#define XMR_FS_LEN_SHIFT        18
+#define GMR_FS_LEN_SHIFT        16
+               if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+                       if (FrameLength != (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)) {
+                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                                       SK_DBGCAT_DRV_RX_PROGRESS,
+                                       ("skge: Frame length mismatch (%u/%u).\n",
+                                       FrameLength,
+                                       (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
+                               goto rx_failed;
+                       }
+               }
+               else {
+                       if (FrameLength != (SK_U32) (FrameStat >> GMR_FS_LEN_SHIFT)) {
+                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                                       SK_DBGCAT_DRV_RX_PROGRESS,
+                                       ("skge: Frame length mismatch (%u/%u).\n",
+                                       FrameLength,
+                                       (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
+                               goto rx_failed;
+                       }
+               }
+
+               /* Set Rx Status */
+               if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+                       IsBc = (FrameStat & XMR_FS_BC) != 0;
+                       IsMc = (FrameStat & XMR_FS_MC) != 0;
+                       IsBadFrame = (FrameStat &
+                               (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0;
+               } else {
+                       IsBc = (FrameStat & GMR_FS_BC) != 0;
+                       IsMc = (FrameStat & GMR_FS_MC) != 0;
+                       IsBadFrame = (((FrameStat & GMR_FS_ANY_ERR) != 0) ||
+                                                       ((FrameStat & GMR_FS_RX_OK) == 0));
+               }
+
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
+                       ("Received frame of length %d on port %d\n",
+                       FrameLength, PortIndex));
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
+                       ("Number of free rx descriptors: %d\n",
+                       pRxPort->RxdRingFree));
+/* DumpMsg(pMsg, "Rx");        */
+
+               if ((Control & RX_CTRL_STAT_VALID) != RX_CTRL_STAT_VALID ||
+                       (IsBadFrame)) {
+#if 0
+                       (FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) {
+#endif
+                       /* there is a receive error in this frame */
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_RX_PROGRESS,
+                               ("skge: Error in received frame, dropped!\n"
+                               "Control: %x\nRxStat: %x\n",
+                               Control, FrameStat));
+
+                       PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
+                       PhysAddr |= (SK_U64) pRxd->VDataLow;
+                       pci_dma_sync_single(pAC->PciDev,
+                                               (dma_addr_t) PhysAddr,
+                                               FrameLength,
+                                               PCI_DMA_FROMDEVICE);
+                       ReQueueRxBuffer(pAC, pRxPort, pMsg,
+                               pRxd->VDataHigh, pRxd->VDataLow);
+
+                       continue;
+               }
+
+               /*
+                * if short frame then copy data to reduce memory waste
+                */
+               if ((FrameLength < SK_COPY_THRESHOLD) &&
+                       ((pNewMsg = alloc_skb(FrameLength+2, GFP_ATOMIC)) != NULL)) {
+                       /*
+                        * Short frame detected and allocation successfull
+                        */
+                       /* use new skb and copy data */
+                       skb_reserve(pNewMsg, 2);
+                       skb_put(pNewMsg, FrameLength);
+                       PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
+                       PhysAddr |= (SK_U64) pRxd->VDataLow;
+
+                       pci_dma_sync_single(pAC->PciDev,
+                                               (dma_addr_t) PhysAddr,
+                                               FrameLength,
+                                               PCI_DMA_FROMDEVICE);
+                       eth_copy_and_sum(pNewMsg, pMsg->data,
+                               FrameLength, 0);
+                       ReQueueRxBuffer(pAC, pRxPort, pMsg,
+                               pRxd->VDataHigh, pRxd->VDataLow);
+                       pMsg = pNewMsg;
+
+               }
+               else {
+                       /*
+                        * if large frame, or SKB allocation failed, pass
+                        * the SKB directly to the networking
+                        */
+
+                       PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
+                       PhysAddr |= (SK_U64) pRxd->VDataLow;
+
+                       /* release the DMA mapping */
+                       pci_unmap_single(pAC->PciDev,
+                                        PhysAddr,
+                                        pAC->RxBufSize - 2,
+                                        PCI_DMA_FROMDEVICE);
+
+                       /* set length in message */
+                       skb_put(pMsg, FrameLength);
+                       /* hardware checksum */
+                       Type = ntohs(*((short*)&pMsg->data[12]));
+                       if (Type == 0x800) {
+                               Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff);
+                               Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff);
+#if 0
+                               if ((((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) &&
+                                       (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) ||
+                                       (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
+                                       Result = SkCsGetReceiveInfo(pAC,
+                                               &pMsg->data[14],
+                                               Csum1, Csum2, pRxPort->PortIndex);
+                                       if (Result ==
+                                               SKCS_STATUS_IP_FRAGMENT ||
+                                               Result ==
+                                               SKCS_STATUS_IP_CSUM_OK ||
+                                               Result ==
+                                               SKCS_STATUS_TCP_CSUM_OK ||
+                                               Result ==
+                                               SKCS_STATUS_UDP_CSUM_OK) {
+                                                       pMsg->ip_summed =
+                                                       CHECKSUM_UNNECESSARY;
+                                       } else {
+                                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                                               SK_DBGCAT_DRV_RX_PROGRESS,
+                                               ("skge: CRC error. Frame dropped!\n"));
+                                               goto rx_failed;
+                                       }
+                               }/* checksumControl calculation valid */
+#endif
+                       } /* IP frame */
+               } /* frame > SK_COPY_TRESHOLD */
+
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V"));
+               ForRlmt = SK_RLMT_RX_PROTOCOL;
+#if 0
+               IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC;
+#endif
+               SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength,
+                       IsBc, &Offset, &NumBytes);
+               if (NumBytes != 0) {
+#if 0
+                       IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC;
+#endif
+                       SK_RLMT_LOOKAHEAD(pAC, PortIndex,
+                               &pMsg->data[Offset],
+                               IsBc, IsMc, &ForRlmt);
+               }
+               if (ForRlmt == SK_RLMT_RX_PROTOCOL) {
+                                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("W"));
+                       /* send up only frames from active port */
+                       if ((PortIndex == pAC->ActivePort) ||
+                               (pAC->RlmtNets == 2)) {
+                               /* frame for upper layer */
+                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("U"));
+#ifdef xDEBUG
+                               DumpMsg(pMsg, "Rx");
+#endif
+                               SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
+                                       FrameLength, pRxPort->PortIndex);
+
+#if 0
+                               pMsg->dev = pAC->dev[pRxPort->PortIndex];
+                               pMsg->protocol = eth_type_trans(pMsg,
+                                       pAC->dev[pRxPort->PortIndex]);
+                               netif_rx(pMsg);
+                               pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
+#else
+                               NetReceive(pMsg->data, pMsg->len);
+                               dev_kfree_skb_any(pMsg);
+#endif
+                       }
+                       else {
+                               /* drop frame */
+                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                                       SK_DBGCAT_DRV_RX_PROGRESS,
+                                       ("D"));
+                               DEV_KFREE_SKB(pMsg);
+                       }
+
+               } /* if not for rlmt */
+               else {
+                       /* packet for rlmt */
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_RX_PROGRESS, ("R"));
+                       pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
+                               pAC->IoBase, FrameLength);
+                       if (pRlmtMbuf != NULL) {
+                               pRlmtMbuf->pNext = NULL;
+                               pRlmtMbuf->Length = FrameLength;
+                               pRlmtMbuf->PortIdx = PortIndex;
+                               EvPara.pParaPtr = pRlmtMbuf;
+                               memcpy((char*)(pRlmtMbuf->pData),
+                                          (char*)(pMsg->data),
+                                          FrameLength);
+
+                               /* SlowPathLock needed? */
+                               if (SlowPathLock == SK_TRUE) {
+                                       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+                                       SkEventQueue(pAC, SKGE_RLMT,
+                                               SK_RLMT_PACKET_RECEIVED,
+                                               EvPara);
+                                       pAC->CheckQueue = SK_TRUE;
+                                       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+                               } else {
+                                       SkEventQueue(pAC, SKGE_RLMT,
+                                               SK_RLMT_PACKET_RECEIVED,
+                                               EvPara);
+                                       pAC->CheckQueue = SK_TRUE;
+                               }
+
+                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                                       SK_DBGCAT_DRV_RX_PROGRESS,
+                                       ("Q"));
+                       }
+#if 0
+                       if ((pAC->dev[pRxPort->PortIndex]->flags &
+                               (IFF_PROMISC | IFF_ALLMULTI)) != 0 ||
+                               (ForRlmt & SK_RLMT_RX_PROTOCOL) ==
+                               SK_RLMT_RX_PROTOCOL) {
+                               pMsg->dev = pAC->dev[pRxPort->PortIndex];
+                               pMsg->protocol = eth_type_trans(pMsg,
+                                       pAC->dev[pRxPort->PortIndex]);
+                               netif_rx(pMsg);
+                               pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
+                       }
+#else
+                       if (0) {
+                       }
+#endif
+                       else {
+                               DEV_KFREE_SKB(pMsg);
+                       }
+
+               } /* if packet for rlmt */
+       } /* for ... scanning the RXD ring */
+
+       /* RXD ring is empty -> fill and restart */
+       FillRxRing(pAC, pRxPort);
+       /* do not start if called from Close */
+       if (pAC->BoardLevel > 0) {
+               ClearAndStartRx(pAC, PortIndex);
+       }
+       return;
+
+rx_failed:
+       /* remove error frame */
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
+               ("Schrottdescriptor, length: 0x%x\n", FrameLength));
+
+       /* release the DMA mapping */
+
+       PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
+       PhysAddr |= (SK_U64) pRxd->VDataLow;
+       pci_unmap_page(pAC->PciDev,
+                        PhysAddr,
+                        pAC->RxBufSize - 2,
+                        PCI_DMA_FROMDEVICE);
+       DEV_KFREE_SKB_IRQ(pRxd->pMBuf);
+       pRxd->pMBuf = NULL;
+       pRxPort->RxdRingFree++;
+       pRxPort->pRxdRingHead = pRxd->pNextRxd;
+       goto rx_start;
+
+} /* ReceiveIrq */
+
+
+/*****************************************************************************
+ *
+ *     ClearAndStartRx - give a start receive command to BMU, clear IRQ
+ *
+ * Description:
+ *     This function sends a start command and a clear interrupt
+ *     command for one receive queue to the BMU.
+ *
+ * Returns: N/A
+ *     none
+ */
+static void ClearAndStartRx(
+SK_AC  *pAC,           /* pointer to the adapter context */
+int    PortIndex)      /* index of the receive port (XMAC) */
+{
+       SK_OUT8(pAC->IoBase, RxQueueAddr[PortIndex]+RX_Q_CTRL,
+               RX_Q_CTRL_START | RX_Q_CTRL_CLR_I_EOF);
+} /* ClearAndStartRx */
+
+
+/*****************************************************************************
+ *
+ *     ClearTxIrq - give a clear transmit IRQ command to BMU
+ *
+ * Description:
+ *     This function sends a clear tx IRQ command for one
+ *     transmit queue to the BMU.
+ *
+ * Returns: N/A
+ */
+static void ClearTxIrq(
+SK_AC  *pAC,           /* pointer to the adapter context */
+int    PortIndex,      /* index of the transmit port (XMAC) */
+int    Prio)           /* priority or normal queue */
+{
+       SK_OUT8(pAC->IoBase, TxQueueAddr[PortIndex][Prio]+TX_Q_CTRL,
+               TX_Q_CTRL_CLR_I_EOF);
+} /* ClearTxIrq */
+
+
+/*****************************************************************************
+ *
+ *     ClearRxRing - remove all buffers from the receive ring
+ *
+ * Description:
+ *     This function removes all receive buffers from the ring.
+ *     The receive BMU must be stopped before calling this function.
+ *
+ * Returns: N/A
+ */
+static void ClearRxRing(
+SK_AC  *pAC,           /* pointer to adapter context */
+RX_PORT        *pRxPort)       /* pointer to rx port struct */
+{
+RXD            *pRxd;  /* pointer to the current descriptor */
+unsigned long  Flags;
+SK_U64         PhysAddr;
+
+       if (pRxPort->RxdRingFree == pAC->RxDescrPerRing) {
+               return;
+       }
+       spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
+       pRxd = pRxPort->pRxdRingHead;
+       do {
+               if (pRxd->pMBuf != NULL) {
+
+                       PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
+                       PhysAddr |= (SK_U64) pRxd->VDataLow;
+                       pci_unmap_page(pAC->PciDev,
+                                        PhysAddr,
+                                        pAC->RxBufSize - 2,
+                                        PCI_DMA_FROMDEVICE);
+                       DEV_KFREE_SKB(pRxd->pMBuf);
+                       pRxd->pMBuf = NULL;
+               }
+               pRxd->RBControl &= RX_CTRL_OWN_BMU;
+               pRxd = pRxd->pNextRxd;
+               pRxPort->RxdRingFree++;
+       } while (pRxd != pRxPort->pRxdRingTail);
+       pRxPort->pRxdRingTail = pRxPort->pRxdRingHead;
+       spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
+} /* ClearRxRing */
+
+
+/*****************************************************************************
+ *
+ *     ClearTxRing - remove all buffers from the transmit ring
+ *
+ * Description:
+ *     This function removes all transmit buffers from the ring.
+ *     The transmit BMU must be stopped before calling this function
+ *     and transmitting at the upper level must be disabled.
+ *     The BMU own bit of all descriptors is cleared, the rest is
+ *     done by calling FreeTxDescriptors.
+ *
+ * Returns: N/A
+ */
+static void ClearTxRing(
+SK_AC  *pAC,           /* pointer to adapter context */
+TX_PORT        *pTxPort)       /* pointer to tx prt struct */
+{
+TXD            *pTxd;          /* pointer to the current descriptor */
+int            i;
+unsigned long  Flags;
+
+       spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
+       pTxd = pTxPort->pTxdRingHead;
+       for (i=0; i<pAC->TxDescrPerRing; i++) {
+               pTxd->TBControl &= ~TX_CTRL_OWN_BMU;
+               pTxd = pTxd->pNextTxd;
+       }
+       FreeTxDescriptors(pAC, pTxPort);
+       spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
+} /* ClearTxRing */
+
+
+#if 0
+/*****************************************************************************
+ *
+ *     SetQueueSizes - configure the sizes of rx and tx queues
+ *
+ * Description:
+ *     This function assigns the sizes for active and passive port
+ *     to the appropriate HWinit structure variables.
+ *     The passive port(s) get standard values, all remaining RAM
+ *     is given to the active port.
+ *     The queue sizes are in kbyte and must be multiple of 8.
+ *     The limits for the number of buffers filled into the rx rings
+ *     is also set in this routine.
+ *
+ * Returns:
+ *     none
+ */
+static void SetQueueSizes(
+SK_AC  *pAC)   /* pointer to the adapter context */
+{
+int    StandbyRam;     /* adapter RAM used for a standby port */
+int    RemainingRam;   /* adapter RAM available for the active port */
+int    RxRam;          /* RAM used for the active port receive queue */
+int    i;              /* loop counter */
+
+if (pAC->RlmtNets == 1) {
+       StandbyRam = SK_RLMT_STANDBY_QRXSIZE + SK_RLMT_STANDBY_QXASIZE +
+               SK_RLMT_STANDBY_QXSSIZE;
+       RemainingRam = pAC->GIni.GIRamSize -
+               (pAC->GIni.GIMacsFound-1) * StandbyRam;
+       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+               pAC->GIni.GP[i].PRxQSize = SK_RLMT_STANDBY_QRXSIZE;
+               pAC->GIni.GP[i].PXSQSize = SK_RLMT_STANDBY_QXSSIZE;
+               pAC->GIni.GP[i].PXAQSize = SK_RLMT_STANDBY_QXASIZE;
+       }
+       RxRam = (RemainingRam * 8 / 10) & ~7;
+       pAC->GIni.GP[pAC->ActivePort].PRxQSize = RxRam;
+       pAC->GIni.GP[pAC->ActivePort].PXSQSize = 0;
+       pAC->GIni.GP[pAC->ActivePort].PXAQSize =
+               (RemainingRam - RxRam) & ~7;
+       pAC->RxQueueSize = RxRam;
+       pAC->TxSQueueSize = 0;
+       pAC->TxAQueueSize = (RemainingRam - RxRam) & ~7;
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("queue sizes settings - rx:%d  txA:%d txS:%d\n",
+               pAC->RxQueueSize,pAC->TxAQueueSize, pAC->TxSQueueSize));
+} else {
+       RemainingRam = pAC->GIni.GIRamSize/pAC->GIni.GIMacsFound;
+       RxRam = (RemainingRam * 8 / 10) & ~7;
+       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+               pAC->GIni.GP[i].PRxQSize = RxRam;
+               pAC->GIni.GP[i].PXSQSize = 0;
+               pAC->GIni.GP[i].PXAQSize = (RemainingRam - RxRam) & ~7;
+       }
+
+       pAC->RxQueueSize = RxRam;
+       pAC->TxSQueueSize = 0;
+       pAC->TxAQueueSize = (RemainingRam - RxRam) & ~7;
+}
+       for (i=0; i<SK_MAX_MACS; i++) {
+               pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing;
+       }
+
+       if (pAC->RlmtNets == 2) {
+               for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+                       pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 100;
+               }
+       } else {
+               for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+                       pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 100;
+               }
+               /*
+                * Do not set the Limit to 0, because this could cause
+                * wrap around with ReQueue'ed buffers (a buffer could
+                * be requeued in the same position, made accessable to
+                * the hardware, and the hardware could change its
+                * contents!
+                */
+               pAC->RxPort[pAC->ActivePort].RxFillLimit = 1;
+       }
+
+#ifdef DEBUG
+       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+                       ("i: %d,  RxQSize: %d,  PXSQsize: %d, PXAQSize: %d\n",
+                       i,
+                       pAC->GIni.GP[i].PRxQSize,
+                       pAC->GIni.GP[i].PXSQSize,
+                       pAC->GIni.GP[i].PXAQSize));
+       }
+#endif
+} /* SetQueueSizes */
+
+
+/*****************************************************************************
+ *
+ *     SkGeSetMacAddr - Set the hardware MAC address
+ *
+ * Description:
+ *     This function sets the MAC address used by the adapter.
+ *
+ * Returns:
+ *     0, if everything is ok
+ *     !=0, on error
+ */
+static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p)
+{
+
+DEV_NET *pNet = (DEV_NET*) dev->priv;
+SK_AC  *pAC = pNet->pAC;
+
+struct sockaddr        *addr = p;
+unsigned long  Flags;
+
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeSetMacAddr starts now...\n"));
+       if(netif_running(dev))
+               return -EBUSY;
+
+       memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
+
+       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+
+       if (pAC->RlmtNets == 2)
+               SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr,
+                       (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
+       else
+               SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort,
+                       (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
+
+
+       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+       return 0;
+} /* SkGeSetMacAddr */
+#endif
+
+
+/*****************************************************************************
+ *
+ *     SkGeSetRxMode - set receive mode
+ *
+ * Description:
+ *     This function sets the receive mode of an adapter. The adapter
+ *     supports promiscuous mode, allmulticast mode and a number of
+ *     multicast addresses. If more multicast addresses the available
+ *     are selected, a hash function in the hardware is used.
+ *
+ * Returns:
+ *     0, if everything is ok
+ *     !=0, on error
+ */
+#if 0
+static void SkGeSetRxMode(struct SK_NET_DEVICE *dev)
+{
+
+DEV_NET                *pNet;
+SK_AC          *pAC;
+
+struct dev_mc_list     *pMcList;
+int                    i;
+int                    PortIdx;
+unsigned long          Flags;
+
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeSetRxMode starts now... "));
+
+       pNet = (DEV_NET*) dev->priv;
+       pAC = pNet->pAC;
+       if (pAC->RlmtNets == 1)
+               PortIdx = pAC->ActivePort;
+       else
+               PortIdx = pNet->NetNr;
+
+       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+       if (dev->flags & IFF_PROMISC) {
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+                       ("PROMISCUOUS mode\n"));
+               SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
+                       SK_PROM_MODE_LLC);
+       } else if (dev->flags & IFF_ALLMULTI) {
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+                       ("ALLMULTI mode\n"));
+               SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
+                       SK_PROM_MODE_ALL_MC);
+       } else {
+               SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
+                       SK_PROM_MODE_NONE);
+               SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
+
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+                       ("Number of MC entries: %d ", dev->mc_count));
+
+               pMcList = dev->mc_list;
+               for (i=0; i<dev->mc_count; i++, pMcList = pMcList->next) {
+                       SkAddrMcAdd(pAC, pAC->IoBase, PortIdx,
+                               (SK_MAC_ADDR*)pMcList->dmi_addr, 0);
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MCA,
+                               ("%02x:%02x:%02x:%02x:%02x:%02x\n",
+                               pMcList->dmi_addr[0],
+                               pMcList->dmi_addr[1],
+                               pMcList->dmi_addr[2],
+                               pMcList->dmi_addr[3],
+                               pMcList->dmi_addr[4],
+                               pMcList->dmi_addr[5]));
+               }
+               SkAddrMcUpdate(pAC, pAC->IoBase, PortIdx);
+       }
+       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+
+       return;
+} /* SkGeSetRxMode */
+
+
+/*****************************************************************************
+ *
+ *     SkGeChangeMtu - set the MTU to another value
+ *
+ * Description:
+ *     This function sets is called whenever the MTU size is changed
+ *     (ifconfig mtu xxx dev ethX). If the MTU is bigger than standard
+ *     ethernet MTU size, long frame support is activated.
+ *
+ * Returns:
+ *     0, if everything is ok
+ *     !=0, on error
+ */
+static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu)
+{
+DEV_NET                *pNet;
+DEV_NET                *pOtherNet;
+SK_AC          *pAC;
+unsigned long  Flags;
+int            i;
+SK_EVPARA      EvPara;
+
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeChangeMtu starts now...\n"));
+
+       pNet = (DEV_NET*) dev->priv;
+       pAC = pNet->pAC;
+
+       if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) {
+               return -EINVAL;
+       }
+
+       if(pAC->BoardLevel != 2) {
+               return -EINVAL;
+       }
+
+       pNet->Mtu = NewMtu;
+       pOtherNet = (DEV_NET*)pAC->dev[1 - pNet->NetNr]->priv;
+       if ((pOtherNet->Mtu > 1500) && (NewMtu <= 1500) && (pOtherNet->Up==1)) {
+               return(0);
+       }
+
+       EvPara.Para32[0] = pNet->NetNr;
+       EvPara.Para32[1] = -1;
+
+       pAC->RxBufSize = NewMtu + 32;
+       dev->mtu = NewMtu;
+
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("New MTU: %d\n", NewMtu));
+
+       /* prevent reconfiguration while changing the MTU */
+
+       /* disable interrupts */
+       SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+
+       /* Found more than one port */
+       if ((pAC->GIni.GIMacsFound == 2 ) &&
+               (pAC->RlmtNets == 2)) {
+                       /* Stop both ports */
+                       EvPara.Para32[0] = 0;
+                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+                       EvPara.Para32[0] = 1;
+                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+       } else {
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+       }
+
+       SkEventDispatcher(pAC, pAC->IoBase);
+
+       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+               spin_lock_irqsave(
+                       &pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock, Flags);
+               netif_stop_queue(pAC->dev[i]);
+
+       }
+
+       /*
+        * adjust number of rx buffers allocated
+        */
+       if (NewMtu > 1500) {
+               /* use less rx buffers */
+               for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+                       /* Found more than one port */
+                       if ((pAC->GIni.GIMacsFound == 2 ) &&
+                               (pAC->RlmtNets == 2)) {
+                                       pAC->RxPort[i].RxFillLimit =
+                                               pAC->RxDescrPerRing - 100;
+                       } else {
+                               if (i == pAC->ActivePort)
+                                       pAC->RxPort[i].RxFillLimit =
+                                               pAC->RxDescrPerRing - 100;
+                               else
+                                       pAC->RxPort[i].RxFillLimit =
+                                               pAC->RxDescrPerRing - 10;
+                       }
+               }
+       }
+       else {
+               /* use normal amount of rx buffers */
+               for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+                       /* Found more than one port */
+                       if ((pAC->GIni.GIMacsFound == 2 ) &&
+                               (pAC->RlmtNets == 2)) {
+                                       pAC->RxPort[i].RxFillLimit = 1;
+                       } else {
+                               if (i == pAC->ActivePort)
+                                       pAC->RxPort[i].RxFillLimit = 1;
+                               else
+                                       pAC->RxPort[i].RxFillLimit =
+                                               pAC->RxDescrPerRing - 100;
+                       }
+               }
+       }
+
+       SkGeDeInit(pAC, pAC->IoBase);
+
+       /*
+        * enable/disable hardware support for long frames
+        */
+       if (NewMtu > 1500) {
+/*             pAC->JumboActivated = SK_TRUE; /#* is never set back !!! */
+               pAC->GIni.GIPortUsage = SK_JUMBO_LINK;
+       }
+       else {
+               if ((pAC->GIni.GIMacsFound == 2 ) &&
+                       (pAC->RlmtNets == 2)) {
+                       pAC->GIni.GIPortUsage = SK_MUL_LINK;
+               } else {
+                       pAC->GIni.GIPortUsage = SK_RED_LINK;
+               }
+       }
+
+       SkGeInit(   pAC, pAC->IoBase, 1);
+       SkI2cInit(  pAC, pAC->IoBase, 1);
+       SkEventInit(pAC, pAC->IoBase, 1);
+       SkPnmiInit( pAC, pAC->IoBase, 1);
+       SkAddrInit( pAC, pAC->IoBase, 1);
+       SkRlmtInit( pAC, pAC->IoBase, 1);
+       SkTimerInit(pAC, pAC->IoBase, 1);
+
+       /*
+        * tschilling:
+        * Speed and others are set back to default in level 1 init!
+        */
+       GetConfiguration(pAC);
+
+       SkGeInit(   pAC, pAC->IoBase, 2);
+       SkI2cInit(  pAC, pAC->IoBase, 2);
+       SkEventInit(pAC, pAC->IoBase, 2);
+       SkPnmiInit( pAC, pAC->IoBase, 2);
+       SkAddrInit( pAC, pAC->IoBase, 2);
+       SkRlmtInit( pAC, pAC->IoBase, 2);
+       SkTimerInit(pAC, pAC->IoBase, 2);
+
+       /*
+        * clear and reinit the rx rings here
+        */
+       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+               ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
+               ClearRxRing(pAC, &pAC->RxPort[i]);
+               FillRxRing(pAC, &pAC->RxPort[i]);
+
+               /* Enable transmit descriptor polling. */
+               SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
+               FillRxRing(pAC, &pAC->RxPort[i]);
+       };
+
+       SkGeYellowLED(pAC, pAC->IoBase, 1);
+
+#ifdef USE_INT_MOD
+       {
+               unsigned long ModBase;
+               ModBase = 53125000 / INTS_PER_SEC;
+               SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
+               SK_OUT32(pAC->IoBase, B2_IRQM_MSK, IRQ_MOD_MASK);
+               SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
+       }
+#endif
+
+       netif_start_queue(pAC->dev[pNet->PortNr]);
+       for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) {
+               spin_unlock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
+       }
+
+       /* enable Interrupts */
+       SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK);
+       SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
+
+       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+       SkEventDispatcher(pAC, pAC->IoBase);
+
+       /* Found more than one port */
+       if ((pAC->GIni.GIMacsFound == 2 ) &&
+               (pAC->RlmtNets == 2)) {
+                       /* Start both ports */
+                       EvPara.Para32[0] = pAC->RlmtNets;
+                       EvPara.Para32[1] = -1;
+                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
+                               EvPara);
+
+
+                       EvPara.Para32[1] = -1;
+                       EvPara.Para32[0] = pNet->PortNr;
+                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+
+                       if (pOtherNet->Up) {
+                               EvPara.Para32[0] = pOtherNet->PortNr;
+                               SkEventQueue(pAC, SKGE_RLMT,
+                                       SK_RLMT_START, EvPara);
+                       }
+       } else {
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+       }
+
+       SkEventDispatcher(pAC, pAC->IoBase);
+       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+
+       return 0;
+} /* SkGeChangeMtu */
+
+
+/*****************************************************************************
+ *
+ *     SkGeStats - return ethernet device statistics
+ *
+ * Description:
+ *     This function return statistic data about the ethernet device
+ *     to the operating system.
+ *
+ * Returns:
+ *     pointer to the statistic structure.
+ */
+static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev)
+{
+DEV_NET *pNet = (DEV_NET*) dev->priv;
+SK_AC  *pAC = pNet->pAC;
+SK_PNMI_STRUCT_DATA *pPnmiStruct;       /* structure for all Pnmi-Data */
+SK_PNMI_STAT    *pPnmiStat;             /* pointer to virtual XMAC stat. data */
+SK_PNMI_CONF    *pPnmiConf;             /* pointer to virtual link config. */
+unsigned int    Size;                   /* size of pnmi struct */
+unsigned long  Flags;                  /* for spin lock */
+
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeStats starts now...\n"));
+       pPnmiStruct = &pAC->PnmiStruct;
+       memset(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
+       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+       Size = SK_PNMI_STRUCT_SIZE;
+               SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
+       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+       pPnmiStat = &pPnmiStruct->Stat[0];
+       pPnmiConf = &pPnmiStruct->Conf[0];
+
+       pAC->stats.rx_packets = (SK_U32) pPnmiStruct->RxDeliveredCts & 0xFFFFFFFF;
+       pAC->stats.tx_packets = (SK_U32) pPnmiStat->StatTxOkCts & 0xFFFFFFFF;
+       pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts;
+       pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts;
+
+       if (pNet->Mtu <= 1500) {
+               pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
+       } else {
+               pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts -
+                       pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF);
+       }
+
+
+       if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && pAC->HWRevision < 12)
+               pAC->stats.rx_errors = pAC->stats.rx_errors - pPnmiStat->StatRxShortsCts;
+
+       pAC->stats.tx_errors = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
+       pAC->stats.rx_dropped = (SK_U32) pPnmiStruct->RxNoBufCts & 0xFFFFFFFF;
+       pAC->stats.tx_dropped = (SK_U32) pPnmiStruct->TxNoBufCts & 0xFFFFFFFF;
+       pAC->stats.multicast = (SK_U32) pPnmiStat->StatRxMulticastOkCts & 0xFFFFFFFF;
+       pAC->stats.collisions = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
+
+       /* detailed rx_errors: */
+       pAC->stats.rx_length_errors = (SK_U32) pPnmiStat->StatRxRuntCts & 0xFFFFFFFF;
+       pAC->stats.rx_over_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
+       pAC->stats.rx_crc_errors = (SK_U32) pPnmiStat->StatRxFcsCts & 0xFFFFFFFF;
+       pAC->stats.rx_frame_errors = (SK_U32) pPnmiStat->StatRxFramingCts & 0xFFFFFFFF;
+       pAC->stats.rx_fifo_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
+       pAC->stats.rx_missed_errors = (SK_U32) pPnmiStat->StatRxMissedCts & 0xFFFFFFFF;
+
+       /* detailed tx_errors */
+       pAC->stats.tx_aborted_errors = (SK_U32) 0;
+       pAC->stats.tx_carrier_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
+       pAC->stats.tx_fifo_errors = (SK_U32) pPnmiStat->StatTxFifoUnderrunCts & 0xFFFFFFFF;
+       pAC->stats.tx_heartbeat_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
+       pAC->stats.tx_window_errors = (SK_U32) 0;
+
+       return(&pAC->stats);
+} /* SkGeStats */
+
+
+/*****************************************************************************
+ *
+ *     SkGeIoctl - IO-control function
+ *
+ * Description:
+ *     This function is called if an ioctl is issued on the device.
+ *     There are three subfunction for reading, writing and test-writing
+ *     the private MIB data structure (usefull for SysKonnect-internal tools).
+ *
+ * Returns:
+ *     0, if everything is ok
+ *     !=0, on error
+ */
+static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd)
+{
+DEV_NET                *pNet;
+SK_AC          *pAC;
+
+SK_GE_IOCTL    Ioctl;
+unsigned int   Err = 0;
+int            Size;
+
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeIoctl starts now...\n"));
+
+       pNet = (DEV_NET*) dev->priv;
+       pAC = pNet->pAC;
+
+       if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
+               return -EFAULT;
+       }
+
+       switch(cmd) {
+       case SK_IOCTL_SETMIB:
+       case SK_IOCTL_PRESETMIB:
+               if (!capable(CAP_NET_ADMIN)) return -EPERM;
+       case SK_IOCTL_GETMIB:
+               if(copy_from_user(&pAC->PnmiStruct, Ioctl.pData,
+                       Ioctl.Len<sizeof(pAC->PnmiStruct)?
+                       Ioctl.Len : sizeof(pAC->PnmiStruct))) {
+                       return -EFAULT;
+               }
+               Size = SkGeIocMib(pNet, Ioctl.Len, cmd);
+               if(copy_to_user(Ioctl.pData, &pAC->PnmiStruct,
+                       Ioctl.Len<Size? Ioctl.Len : Size)) {
+                       return -EFAULT;
+               }
+               Ioctl.Len = Size;
+               if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
+                       return -EFAULT;
+               }
+               break;
+       default:
+               Err = -EOPNOTSUPP;
+       }
+       return(Err);
+} /* SkGeIoctl */
+
+
+/*****************************************************************************
+ *
+ *     SkGeIocMib - handle a GetMib, SetMib- or PresetMib-ioctl message
+ *
+ * Description:
+ *     This function reads/writes the MIB data using PNMI (Private Network
+ *     Management Interface).
+ *     The destination for the data must be provided with the
+ *     ioctl call and is given to the driver in the form of
+ *     a user space address.
+ *     Copying from the user-provided data area into kernel messages
+ *     and back is done by copy_from_user and copy_to_user calls in
+ *     SkGeIoctl.
+ *
+ * Returns:
+ *     returned size from PNMI call
+ */
+static int SkGeIocMib(
+DEV_NET                *pNet,  /* pointer to the adapter context */
+unsigned int   Size,   /* length of ioctl data */
+int            mode)   /* flag for set/preset */
+{
+unsigned long  Flags;  /* for spin lock */
+SK_AC          *pAC;
+
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeIocMib starts now...\n"));
+       pAC = pNet->pAC;
+       /* access MIB */
+       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+       switch(mode) {
+       case SK_IOCTL_GETMIB:
+               SkPnmiGetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
+                       pNet->NetNr);
+               break;
+       case SK_IOCTL_PRESETMIB:
+               SkPnmiPreSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
+                       pNet->NetNr);
+               break;
+       case SK_IOCTL_SETMIB:
+               SkPnmiSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
+                       pNet->NetNr);
+               break;
+       default:
+               break;
+       }
+       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("MIB data access succeeded\n"));
+       return (Size);
+} /* SkGeIocMib */
+#endif
+
+
+/*****************************************************************************
+ *
+ *     GetConfiguration - read configuration information
+ *
+ * Description:
+ *     This function reads per-adapter configuration information from
+ *     the options provided on the command line.
+ *
+ * Returns:
+ *     none
+ */
+static void GetConfiguration(
+SK_AC  *pAC)   /* pointer to the adapter context structure */
+{
+SK_I32 Port;           /* preferred port */
+int    LinkSpeed;      /* Link speed */
+int    AutoNeg;        /* auto negotiation off (0) or on (1) */
+int    DuplexCap;      /* duplex capabilities (0=both, 1=full, 2=half */
+int    MSMode;         /* master / slave mode selection */
+SK_BOOL        AutoSet;
+SK_BOOL DupSet;
+/*
+ *     The two parameters AutoNeg. and DuplexCap. map to one configuration
+ *     parameter. The mapping is described by this table:
+ *     DuplexCap ->    |       both    |       full    |       half    |
+ *     AutoNeg         |               |               |               |
+ *     -----------------------------------------------------------------
+ *     Off             |    illegal    |       Full    |       Half    |
+ *     -----------------------------------------------------------------
+ *     On              |   AutoBoth    |   AutoFull    |   AutoHalf    |
+ *     -----------------------------------------------------------------
+ *     Sense           |   AutoSense   |   AutoSense   |   AutoSense   |
+ */
+int    Capabilities[3][3] =
+               { {               -1, SK_LMODE_FULL,     SK_LMODE_HALF},
+                 {SK_LMODE_AUTOBOTH, SK_LMODE_AUTOFULL, SK_LMODE_AUTOHALF},
+                 {SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE} };
+#define DC_BOTH        0
+#define DC_FULL 1
+#define DC_HALF 2
+#define AN_OFF 0
+#define AN_ON  1
+#define AN_SENS        2
+
+       /* settings for port A */
+       /* settings link speed */
+       LinkSpeed = SK_LSPEED_AUTO;     /* default: do auto select */
+       if (Speed_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+               Speed_A[pAC->Index] != NULL) {
+               if (strcmp(Speed_A[pAC->Index],"")==0) {
+                       LinkSpeed = SK_LSPEED_AUTO;
+               }
+               else if (strcmp(Speed_A[pAC->Index],"Auto")==0) {
+                       LinkSpeed = SK_LSPEED_AUTO;
+               }
+               else if (strcmp(Speed_A[pAC->Index],"10")==0) {
+                       LinkSpeed = SK_LSPEED_10MBPS;
+               }
+               else if (strcmp(Speed_A[pAC->Index],"100")==0) {
+                       LinkSpeed = SK_LSPEED_100MBPS;
+               }
+               else if (strcmp(Speed_A[pAC->Index],"1000")==0) {
+                       LinkSpeed = SK_LSPEED_1000MBPS;
+               }
+               else printk("%s: Illegal value for Speed_A\n",
+                       pAC->dev[0]->name);
+       }
+
+       /* Check speed parameter */
+       /* Only copper type adapter and GE V2 cards */
+       if (((pAC->GIni.GIChipId != CHIP_ID_YUKON) ||
+               (pAC->GIni.GICopperType != SK_TRUE)) &&
+               ((LinkSpeed != SK_LSPEED_AUTO) &&
+               (LinkSpeed != SK_LSPEED_1000MBPS))) {
+               printk("%s: Illegal value for Speed_A. "
+                       "Not a copper card or GE V2 card\n    Using "
+                       "speed 1000\n", pAC->dev[0]->name);
+               LinkSpeed = SK_LSPEED_1000MBPS;
+       }
+       pAC->GIni.GP[0].PLinkSpeed = LinkSpeed;
+
+       /* Autonegotiation */
+       AutoNeg = AN_ON; /* tschilling: Default: Autonegotiation on! */
+       AutoSet = SK_FALSE;
+       if (AutoNeg_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+               AutoNeg_A[pAC->Index] != NULL) {
+               AutoSet = SK_TRUE;
+               if (strcmp(AutoNeg_A[pAC->Index],"")==0) {
+                       AutoSet = SK_FALSE;
+               }
+               else if (strcmp(AutoNeg_A[pAC->Index],"On")==0) {
+                       AutoNeg = AN_ON;
+               }
+               else if (strcmp(AutoNeg_A[pAC->Index],"Off")==0) {
+                       AutoNeg = AN_OFF;
+               }
+               else if (strcmp(AutoNeg_A[pAC->Index],"Sense")==0) {
+                       AutoNeg = AN_SENS;
+               }
+               else printk("%s: Illegal value for AutoNeg_A\n",
+                       pAC->dev[0]->name);
+       }
+
+       DuplexCap = DC_BOTH;
+       DupSet = SK_FALSE;
+       if (DupCap_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+               DupCap_A[pAC->Index] != NULL) {
+               DupSet = SK_TRUE;
+               if (strcmp(DupCap_A[pAC->Index],"")==0) {
+                       DupSet = SK_FALSE;
+               }
+               else if (strcmp(DupCap_A[pAC->Index],"Both")==0) {
+                       DuplexCap = DC_BOTH;
+               }
+               else if (strcmp(DupCap_A[pAC->Index],"Full")==0) {
+                       DuplexCap = DC_FULL;
+               }
+               else if (strcmp(DupCap_A[pAC->Index],"Half")==0) {
+                       DuplexCap = DC_HALF;
+               }
+               else printk("%s: Illegal value for DupCap_A\n",
+                       pAC->dev[0]->name);
+       }
+
+       /* check for illegal combinations */
+       if (AutoSet && AutoNeg==AN_SENS && DupSet) {
+               printk("%s, Port A: DuplexCapabilities"
+                       " ignored using Sense mode\n", pAC->dev[0]->name);
+       }
+       if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
+               printk("%s, Port A: Illegal combination"
+                       " of values AutoNeg. and DuplexCap.\n    Using "
+                       "Full Duplex\n", pAC->dev[0]->name);
+
+               DuplexCap = DC_FULL;
+       }
+       if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
+               DuplexCap = DC_FULL;
+       }
+
+       if (!AutoSet && DupSet) {
+               printk("%s, Port A: Duplex setting not"
+                       " possible in\n    default AutoNegotiation mode"
+                       " (Sense).\n    Using AutoNegotiation On\n",
+                       pAC->dev[0]->name);
+               AutoNeg = AN_ON;
+       }
+
+       /* set the desired mode */
+       pAC->GIni.GP[0].PLinkModeConf =
+               Capabilities[AutoNeg][DuplexCap];
+
+       pAC->GIni.GP[0].PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
+       if (FlowCtrl_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+               FlowCtrl_A[pAC->Index] != NULL) {
+               if (strcmp(FlowCtrl_A[pAC->Index],"") == 0) {
+               }
+               else if (strcmp(FlowCtrl_A[pAC->Index],"SymOrRem") == 0) {
+                       pAC->GIni.GP[0].PFlowCtrlMode =
+                               SK_FLOW_MODE_SYM_OR_REM;
+               }
+               else if (strcmp(FlowCtrl_A[pAC->Index],"Sym")==0) {
+                       pAC->GIni.GP[0].PFlowCtrlMode =
+                               SK_FLOW_MODE_SYMMETRIC;
+               }
+               else if (strcmp(FlowCtrl_A[pAC->Index],"LocSend")==0) {
+                       pAC->GIni.GP[0].PFlowCtrlMode =
+                               SK_FLOW_MODE_LOC_SEND;
+               }
+               else if (strcmp(FlowCtrl_A[pAC->Index],"None")==0) {
+                       pAC->GIni.GP[0].PFlowCtrlMode =
+                               SK_FLOW_MODE_NONE;
+               }
+               else printk("Illegal value for FlowCtrl_A\n");
+       }
+       if (AutoNeg==AN_OFF && pAC->GIni.GP[0].PFlowCtrlMode!=
+               SK_FLOW_MODE_NONE) {
+               printk("%s, Port A: FlowControl"
+                       " impossible without AutoNegotiation,"
+                       " disabled\n", pAC->dev[0]->name);
+               pAC->GIni.GP[0].PFlowCtrlMode = SK_FLOW_MODE_NONE;
+       }
+
+       MSMode = SK_MS_MODE_AUTO; /* default: do auto select */
+       if (Role_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+               Role_A[pAC->Index] != NULL) {
+               if (strcmp(Role_A[pAC->Index],"")==0) {
+               }
+               else if (strcmp(Role_A[pAC->Index],"Auto")==0) {
+                       MSMode = SK_MS_MODE_AUTO;
+               }
+               else if (strcmp(Role_A[pAC->Index],"Master")==0) {
+                       MSMode = SK_MS_MODE_MASTER;
+               }
+               else if (strcmp(Role_A[pAC->Index],"Slave")==0) {
+                       MSMode = SK_MS_MODE_SLAVE;
+               }
+               else printk("%s: Illegal value for Role_A\n",
+                       pAC->dev[0]->name);
+       }
+       pAC->GIni.GP[0].PMSMode = MSMode;
+
+
+       /* settings for port B */
+       /* settings link speed */
+       LinkSpeed = SK_LSPEED_AUTO;     /* default: do auto select */
+       if (Speed_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+               Speed_B[pAC->Index] != NULL) {
+               if (strcmp(Speed_B[pAC->Index],"")==0) {
+                       LinkSpeed = SK_LSPEED_AUTO;
+               }
+               else if (strcmp(Speed_B[pAC->Index],"Auto")==0) {
+                       LinkSpeed = SK_LSPEED_AUTO;
+               }
+               else if (strcmp(Speed_B[pAC->Index],"10")==0) {
+                       LinkSpeed = SK_LSPEED_10MBPS;
+               }
+               else if (strcmp(Speed_B[pAC->Index],"100")==0) {
+                       LinkSpeed = SK_LSPEED_100MBPS;
+               }
+               else if (strcmp(Speed_B[pAC->Index],"1000")==0) {
+                       LinkSpeed = SK_LSPEED_1000MBPS;
+               }
+               else printk("%s: Illegal value for Speed_B\n",
+                       pAC->dev[1]->name);
+       }
+
+       /* Check speed parameter */
+       /* Only copper type adapter and GE V2 cards */
+       if (((pAC->GIni.GIChipId != CHIP_ID_YUKON) ||
+               (pAC->GIni.GICopperType != SK_TRUE)) &&
+               ((LinkSpeed != SK_LSPEED_AUTO) &&
+               (LinkSpeed != SK_LSPEED_1000MBPS))) {
+               printk("%s: Illegal value for Speed_B. "
+                       "Not a copper card or GE V2 card\n    Using "
+                       "speed 1000\n", pAC->dev[1]->name);
+               LinkSpeed = SK_LSPEED_1000MBPS;
+       }
+       pAC->GIni.GP[1].PLinkSpeed = LinkSpeed;
+
+       /* Auto negotiation */
+       AutoNeg = AN_SENS; /* default: do auto Sense */
+       AutoSet = SK_FALSE;
+       if (AutoNeg_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+               AutoNeg_B[pAC->Index] != NULL) {
+               AutoSet = SK_TRUE;
+               if (strcmp(AutoNeg_B[pAC->Index],"")==0) {
+                       AutoSet = SK_FALSE;
+               }
+               else if (strcmp(AutoNeg_B[pAC->Index],"On")==0) {
+                       AutoNeg = AN_ON;
+               }
+               else if (strcmp(AutoNeg_B[pAC->Index],"Off")==0) {
+                       AutoNeg = AN_OFF;
+               }
+               else if (strcmp(AutoNeg_B[pAC->Index],"Sense")==0) {
+                       AutoNeg = AN_SENS;
+               }
+               else printk("Illegal value for AutoNeg_B\n");
+       }
+
+       DuplexCap = DC_BOTH;
+       DupSet = SK_FALSE;
+       if (DupCap_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+               DupCap_B[pAC->Index] != NULL) {
+               DupSet = SK_TRUE;
+               if (strcmp(DupCap_B[pAC->Index],"")==0) {
+                       DupSet = SK_FALSE;
+               }
+               else if (strcmp(DupCap_B[pAC->Index],"Both")==0) {
+                       DuplexCap = DC_BOTH;
+               }
+               else if (strcmp(DupCap_B[pAC->Index],"Full")==0) {
+                       DuplexCap = DC_FULL;
+               }
+               else if (strcmp(DupCap_B[pAC->Index],"Half")==0) {
+                       DuplexCap = DC_HALF;
+               }
+               else printk("Illegal value for DupCap_B\n");
+       }
+
+       /* check for illegal combinations */
+       if (AutoSet && AutoNeg==AN_SENS && DupSet) {
+               printk("%s, Port B: DuplexCapabilities"
+                       " ignored using Sense mode\n", pAC->dev[1]->name);
+       }
+       if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
+               printk("%s, Port B: Illegal combination"
+                       " of values AutoNeg. and DuplexCap.\n    Using "
+                       "Full Duplex\n", pAC->dev[1]->name);
+
+               DuplexCap = DC_FULL;
+       }
+       if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
+               DuplexCap = DC_FULL;
+       }
+
+       if (!AutoSet && DupSet) {
+               printk("%s, Port B: Duplex setting not"
+                       " possible in\n    default AutoNegotiation mode"
+                       " (Sense).\n    Using AutoNegotiation On\n",
+                       pAC->dev[1]->name);
+               AutoNeg = AN_ON;
+       }
+
+       /* set the desired mode */
+       pAC->GIni.GP[1].PLinkModeConf =
+               Capabilities[AutoNeg][DuplexCap];
+
+       pAC->GIni.GP[1].PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
+       if (FlowCtrl_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+               FlowCtrl_B[pAC->Index] != NULL) {
+               if (strcmp(FlowCtrl_B[pAC->Index],"") == 0) {
+               }
+               else if (strcmp(FlowCtrl_B[pAC->Index],"SymOrRem") == 0) {
+                       pAC->GIni.GP[1].PFlowCtrlMode =
+                               SK_FLOW_MODE_SYM_OR_REM;
+               }
+               else if (strcmp(FlowCtrl_B[pAC->Index],"Sym")==0) {
+                       pAC->GIni.GP[1].PFlowCtrlMode =
+                               SK_FLOW_MODE_SYMMETRIC;
+               }
+               else if (strcmp(FlowCtrl_B[pAC->Index],"LocSend")==0) {
+                       pAC->GIni.GP[1].PFlowCtrlMode =
+                               SK_FLOW_MODE_LOC_SEND;
+               }
+               else if (strcmp(FlowCtrl_B[pAC->Index],"None")==0) {
+                       pAC->GIni.GP[1].PFlowCtrlMode =
+                               SK_FLOW_MODE_NONE;
+               }
+               else printk("Illegal value for FlowCtrl_B\n");
+       }
+       if (AutoNeg==AN_OFF && pAC->GIni.GP[1].PFlowCtrlMode!=
+               SK_FLOW_MODE_NONE) {
+               printk("%s, Port B: FlowControl"
+                       " impossible without AutoNegotiation,"
+                       " disabled\n", pAC->dev[1]->name);
+               pAC->GIni.GP[1].PFlowCtrlMode = SK_FLOW_MODE_NONE;
+       }
+
+       MSMode = SK_MS_MODE_AUTO; /* default: do auto select */
+       if (Role_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+               Role_B[pAC->Index] != NULL) {
+               if (strcmp(Role_B[pAC->Index],"")==0) {
+               }
+               else if (strcmp(Role_B[pAC->Index],"Auto")==0) {
+                       MSMode = SK_MS_MODE_AUTO;
+               }
+               else if (strcmp(Role_B[pAC->Index],"Master")==0) {
+                       MSMode = SK_MS_MODE_MASTER;
+               }
+               else if (strcmp(Role_B[pAC->Index],"Slave")==0) {
+                       MSMode = SK_MS_MODE_SLAVE;
+               }
+               else printk("%s: Illegal value for Role_B\n",
+                       pAC->dev[1]->name);
+       }
+       pAC->GIni.GP[1].PMSMode = MSMode;
+
+
+       /* settings for both ports */
+       pAC->ActivePort = 0;
+       if (PrefPort != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+               PrefPort[pAC->Index] != NULL) {
+               if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */
+                       pAC->ActivePort = 0;
+                       pAC->Rlmt.Net[0].Preference = -1; /* auto */
+                       pAC->Rlmt.Net[0].PrefPort = 0;
+               }
+               else if (strcmp(PrefPort[pAC->Index],"A") == 0) {
+                       /*
+                        * do not set ActivePort here, thus a port
+                        * switch is issued after net up.
+                        */
+                       Port = 0;
+                       pAC->Rlmt.Net[0].Preference = Port;
+                       pAC->Rlmt.Net[0].PrefPort = Port;
+               }
+               else if (strcmp(PrefPort[pAC->Index],"B") == 0) {
+                       /*
+                        * do not set ActivePort here, thus a port
+                        * switch is issued after net up.
+                        */
+                       Port = 1;
+                       pAC->Rlmt.Net[0].Preference = Port;
+                       pAC->Rlmt.Net[0].PrefPort = Port;
+               }
+               else printk("%s: Illegal value for PrefPort\n",
+                       pAC->dev[0]->name);
+       }
+
+       pAC->RlmtNets = 1;
+
+       if (RlmtMode != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+               RlmtMode[pAC->Index] != NULL) {
+               if (strcmp(RlmtMode[pAC->Index], "") == 0) {
+                       pAC->RlmtMode = 0;
+               }
+               else if (strcmp(RlmtMode[pAC->Index], "CheckLinkState") == 0) {
+                       pAC->RlmtMode = SK_RLMT_CHECK_LINK;
+               }
+               else if (strcmp(RlmtMode[pAC->Index], "CheckLocalPort") == 0) {
+                       pAC->RlmtMode = SK_RLMT_CHECK_LINK |
+                               SK_RLMT_CHECK_LOC_LINK;
+               }
+               else if (strcmp(RlmtMode[pAC->Index], "CheckSeg") == 0) {
+                       pAC->RlmtMode = SK_RLMT_CHECK_LINK |
+                               SK_RLMT_CHECK_LOC_LINK |
+                               SK_RLMT_CHECK_SEG;
+               }
+               else if ((strcmp(RlmtMode[pAC->Index], "DualNet") == 0) &&
+                       (pAC->GIni.GIMacsFound == 2)) {
+                               pAC->RlmtMode = SK_RLMT_CHECK_LINK;
+                               pAC->RlmtNets = 2;
+               }
+               else {
+                       printk("%s: Illegal value for"
+                               " RlmtMode, using default\n", pAC->dev[0]->name);
+                       pAC->RlmtMode = 0;
+               }
+       }
+       else {
+               pAC->RlmtMode = 0;
+       }
+} /* GetConfiguration */
+
+
+/*****************************************************************************
+ *
+ *     ProductStr - return a adapter identification string from vpd
+ *
+ * Description:
+ *     This function reads the product name string from the vpd area
+ *     and puts it the field pAC->DeviceString.
+ *
+ * Returns: N/A
+ */
+static void ProductStr(
+SK_AC  *pAC            /* pointer to adapter context */
+)
+{
+int    StrLen = 80;            /* length of the string, defined in SK_AC */
+char   Keyword[] = VPD_NAME;   /* vpd productname identifier */
+int    ReturnCode;             /* return code from vpd_read */
+unsigned long Flags;
+
+       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+       ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, pAC->DeviceStr,
+               &StrLen);
+       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+       if (ReturnCode != 0) {
+               /* there was an error reading the vpd data */
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
+                       ("Error reading VPD data: %d\n", ReturnCode));
+               pAC->DeviceStr[0] = '\0';
+       }
+} /* ProductStr */
+
+
+/****************************************************************************/
+/* functions for common modules *********************************************/
+/****************************************************************************/
+
+
+/*****************************************************************************
+ *
+ *     SkDrvAllocRlmtMbuf - allocate an RLMT mbuf
+ *
+ * Description:
+ *     This routine returns an RLMT mbuf or NULL. The RLMT Mbuf structure
+ *     is embedded into a socket buff data area.
+ *
+ * Context:
+ *     runtime
+ *
+ * Returns:
+ *     NULL or pointer to Mbuf.
+ */
+SK_MBUF *SkDrvAllocRlmtMbuf(
+SK_AC          *pAC,           /* pointer to adapter context */
+SK_IOC         IoC,            /* the IO-context */
+unsigned       BufferSize)     /* size of the requested buffer */
+{
+SK_MBUF                *pRlmtMbuf;     /* pointer to a new rlmt-mbuf structure */
+struct sk_buff *pMsgBlock;     /* pointer to a new message block */
+
+       pMsgBlock = alloc_skb(BufferSize + sizeof(SK_MBUF), GFP_ATOMIC);
+       if (pMsgBlock == NULL) {
+               return (NULL);
+       }
+       pRlmtMbuf = (SK_MBUF*) pMsgBlock->data;
+       skb_reserve(pMsgBlock, sizeof(SK_MBUF));
+       pRlmtMbuf->pNext = NULL;
+       pRlmtMbuf->pOs = pMsgBlock;
+       pRlmtMbuf->pData = pMsgBlock->data;     /* Data buffer. */
+       pRlmtMbuf->Size = BufferSize;           /* Data buffer size. */
+       pRlmtMbuf->Length = 0;          /* Length of packet (<= Size). */
+       return (pRlmtMbuf);
+
+} /* SkDrvAllocRlmtMbuf */
+
+
+/*****************************************************************************
+ *
+ *     SkDrvFreeRlmtMbuf - free an RLMT mbuf
+ *
+ * Description:
+ *     This routine frees one or more RLMT mbuf(s).
+ *
+ * Context:
+ *     runtime
+ *
+ * Returns:
+ *     Nothing
+ */
+void  SkDrvFreeRlmtMbuf(
+SK_AC          *pAC,           /* pointer to adapter context */
+SK_IOC         IoC,            /* the IO-context */
+SK_MBUF                *pMbuf)         /* size of the requested buffer */
+{
+SK_MBUF                *pFreeMbuf;
+SK_MBUF                *pNextMbuf;
+
+       pFreeMbuf = pMbuf;
+       do {
+               pNextMbuf = pFreeMbuf->pNext;
+               DEV_KFREE_SKB_ANY(pFreeMbuf->pOs);
+               pFreeMbuf = pNextMbuf;
+       } while ( pFreeMbuf != NULL );
+} /* SkDrvFreeRlmtMbuf */
+
+
+/*****************************************************************************
+ *
+ *     SkOsGetTime - provide a time value
+ *
+ * Description:
+ *     This routine provides a time value. The unit is 1/HZ (defined by Linux).
+ *     It is not used for absolute time, but only for time differences.
+ *
+ *
+ * Returns:
+ *     Time value
+ */
+SK_U64 SkOsGetTime(SK_AC *pAC)
+{
+#if 0
+       return jiffies;
+#else
+       return get_timer(0);
+#endif
+} /* SkOsGetTime */
+
+
+/*****************************************************************************
+ *
+ *     SkPciReadCfgDWord - read a 32 bit value from pci config space
+ *
+ * Description:
+ *     This routine reads a 32 bit value from the pci configuration
+ *     space.
+ *
+ * Returns:
+ *     0 - indicate everything worked ok.
+ *     != 0 - error indication
+ */
+int SkPciReadCfgDWord(
+SK_AC *pAC,            /* Adapter Control structure pointer */
+int PciAddr,           /* PCI register address */
+SK_U32 *pVal)          /* pointer to store the read value */
+{
+       pci_read_config_dword(pAC->PciDev, PciAddr, pVal);
+       return(0);
+} /* SkPciReadCfgDWord */
+
+
+/*****************************************************************************
+ *
+ *     SkPciReadCfgWord - read a 16 bit value from pci config space
+ *
+ * Description:
+ *     This routine reads a 16 bit value from the pci configuration
+ *     space.
+ *
+ * Returns:
+ *     0 - indicate everything worked ok.
+ *     != 0 - error indication
+ */
+int SkPciReadCfgWord(
+SK_AC *pAC,    /* Adapter Control structure pointer */
+int PciAddr,           /* PCI register address */
+SK_U16 *pVal)          /* pointer to store the read value */
+{
+       pci_read_config_word(pAC->PciDev, PciAddr, pVal);
+       return(0);
+} /* SkPciReadCfgWord */
+
+
+/*****************************************************************************
+ *
+ *     SkPciReadCfgByte - read a 8 bit value from pci config space
+ *
+ * Description:
+ *     This routine reads a 8 bit value from the pci configuration
+ *     space.
+ *
+ * Returns:
+ *     0 - indicate everything worked ok.
+ *     != 0 - error indication
+ */
+int SkPciReadCfgByte(
+SK_AC *pAC,    /* Adapter Control structure pointer */
+int PciAddr,           /* PCI register address */
+SK_U8 *pVal)           /* pointer to store the read value */
+{
+       pci_read_config_byte(pAC->PciDev, PciAddr, pVal);
+       return(0);
+} /* SkPciReadCfgByte */
+
+
+/*****************************************************************************
+ *
+ *     SkPciWriteCfgDWord - write a 32 bit value to pci config space
+ *
+ * Description:
+ *     This routine writes a 32 bit value to the pci configuration
+ *     space.
+ *
+ * Returns:
+ *     0 - indicate everything worked ok.
+ *     != 0 - error indication
+ */
+int SkPciWriteCfgDWord(
+SK_AC *pAC,    /* Adapter Control structure pointer */
+int PciAddr,           /* PCI register address */
+SK_U32 Val)            /* pointer to store the read value */
+{
+       pci_write_config_dword(pAC->PciDev, PciAddr, Val);
+       return(0);
+} /* SkPciWriteCfgDWord */
+
+
+/*****************************************************************************
+ *
+ *     SkPciWriteCfgWord - write a 16 bit value to pci config space
+ *
+ * Description:
+ *     This routine writes a 16 bit value to the pci configuration
+ *     space. The flag PciConfigUp indicates whether the config space
+ *     is accesible or must be set up first.
+ *
+ * Returns:
+ *     0 - indicate everything worked ok.
+ *     != 0 - error indication
+ */
+int SkPciWriteCfgWord(
+SK_AC *pAC,    /* Adapter Control structure pointer */
+int PciAddr,           /* PCI register address */
+SK_U16 Val)            /* pointer to store the read value */
+{
+       pci_write_config_word(pAC->PciDev, PciAddr, Val);
+       return(0);
+} /* SkPciWriteCfgWord */
+
+
+/*****************************************************************************
+ *
+ *     SkPciWriteCfgWord - write a 8 bit value to pci config space
+ *
+ * Description:
+ *     This routine writes a 8 bit value to the pci configuration
+ *     space. The flag PciConfigUp indicates whether the config space
+ *     is accesible or must be set up first.
+ *
+ * Returns:
+ *     0 - indicate everything worked ok.
+ *     != 0 - error indication
+ */
+int SkPciWriteCfgByte(
+SK_AC *pAC,    /* Adapter Control structure pointer */
+int PciAddr,           /* PCI register address */
+SK_U8 Val)             /* pointer to store the read value */
+{
+       pci_write_config_byte(pAC->PciDev, PciAddr, Val);
+       return(0);
+} /* SkPciWriteCfgByte */
+
+
+/*****************************************************************************
+ *
+ *     SkDrvEvent - handle driver events
+ *
+ * Description:
+ *     This function handles events from all modules directed to the driver
+ *
+ * Context:
+ *     Is called under protection of slow path lock.
+ *
+ * Returns:
+ *     0 if everything ok
+ *     < 0  on error
+ *
+ */
+int SkDrvEvent(
+SK_AC *pAC,            /* pointer to adapter context */
+SK_IOC IoC,            /* io-context */
+SK_U32 Event,          /* event-id */
+SK_EVPARA Param)       /* event-parameter */
+{
+SK_MBUF                *pRlmtMbuf;     /* pointer to a rlmt-mbuf structure */
+struct sk_buff *pMsg;          /* pointer to a message block */
+int            FromPort;       /* the port from which we switch away */
+int            ToPort;         /* the port we switch to */
+SK_EVPARA      NewPara;        /* parameter for further events */
+#if 0
+int            Stat;
+#endif
+unsigned long  Flags;
+SK_BOOL                DualNet;
+
+       switch (Event) {
+       case SK_DRV_ADAP_FAIL:
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+                       ("ADAPTER FAIL EVENT\n"));
+               printk("%s: Adapter failed.\n", pAC->dev[0]->name);
+               /* disable interrupts */
+               SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+               /* cgoos */
+               break;
+       case SK_DRV_PORT_FAIL:
+               FromPort = Param.Para32[0];
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+                       ("PORT FAIL EVENT, Port: %d\n", FromPort));
+               if (FromPort == 0) {
+                       printk("%s: Port A failed.\n", pAC->dev[0]->name);
+               } else {
+                       printk("%s: Port B failed.\n", pAC->dev[1]->name);
+               }
+               /* cgoos */
+               break;
+       case SK_DRV_PORT_RESET:  /* SK_U32 PortIdx */
+               /* action list 4 */
+               FromPort = Param.Para32[0];
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+                       ("PORT RESET EVENT, Port: %d ", FromPort));
+               NewPara.Para64 = FromPort;
+               SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
+               spin_lock_irqsave(
+                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+                       Flags);
+               SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
+#if 0
+               pAC->dev[Param.Para32[0]]->flags &= ~IFF_RUNNING;
+#endif
+               spin_unlock_irqrestore(
+                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+                       Flags);
+
+               /* clear rx ring from received frames */
+               ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE);
+
+               ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
+               spin_lock_irqsave(
+                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+                       Flags);
+
+               /* tschilling: Handling of return value inserted. */
+               if (SkGeInitPort(pAC, IoC, FromPort)) {
+                       if (FromPort == 0) {
+                               printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name);
+                       } else {
+                               printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name);
+                       }
+               }
+               SkAddrMcUpdate(pAC,IoC, FromPort);
+               PortReInitBmu(pAC, FromPort);
+               SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
+               ClearAndStartRx(pAC, FromPort);
+               spin_unlock_irqrestore(
+                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+                       Flags);
+               break;
+       case SK_DRV_NET_UP:      /* SK_U32 PortIdx */
+               /* action list 5 */
+               FromPort = Param.Para32[0];
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+                       ("NET UP EVENT, Port: %d ", Param.Para32[0]));
+#ifdef SK98_INFO
+               printk("%s: network connection up using"
+                       " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]);
+
+               /* tschilling: Values changed according to LinkSpeedUsed. */
+               Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed;
+               if (Stat == SK_LSPEED_STAT_10MBPS) {
+                       printk("    speed:           10\n");
+               } else if (Stat == SK_LSPEED_STAT_100MBPS) {
+                       printk("    speed:           100\n");
+               } else if (Stat == SK_LSPEED_STAT_1000MBPS) {
+                       printk("    speed:           1000\n");
+               } else {
+                       printk("    speed:           unknown\n");
+               }
+
+               Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
+               if (Stat == SK_LMODE_STAT_AUTOHALF ||
+                       Stat == SK_LMODE_STAT_AUTOFULL) {
+                       printk("    autonegotiation: yes\n");
+               }
+               else {
+                       printk("    autonegotiation: no\n");
+               }
+               if (Stat == SK_LMODE_STAT_AUTOHALF ||
+                       Stat == SK_LMODE_STAT_HALF) {
+                       printk("    duplex mode:     half\n");
+               }
+               else {
+                       printk("    duplex mode:     full\n");
+               }
+               Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus;
+               if (Stat == SK_FLOW_STAT_REM_SEND ) {
+                       printk("    flowctrl:        remote send\n");
+               }
+               else if (Stat == SK_FLOW_STAT_LOC_SEND ){
+                       printk("    flowctrl:        local send\n");
+               }
+               else if (Stat == SK_FLOW_STAT_SYMMETRIC ){
+                       printk("    flowctrl:        symmetric\n");
+               }
+               else {
+                       printk("    flowctrl:        none\n");
+               }
+
+               /* tschilling: Check against CopperType now. */
+               if ((pAC->GIni.GICopperType == SK_TRUE) &&
+                       (pAC->GIni.GP[FromPort].PLinkSpeedUsed ==
+                       SK_LSPEED_STAT_1000MBPS)) {
+                       Stat = pAC->GIni.GP[FromPort].PMSStatus;
+                       if (Stat == SK_MS_STAT_MASTER ) {
+                               printk("    role:            master\n");
+                       }
+                       else if (Stat == SK_MS_STAT_SLAVE ) {
+                               printk("    role:            slave\n");
+                       }
+                       else {
+                               printk("    role:            ???\n");
+                       }
+               }
+
+#ifdef SK_ZEROCOPY
+               if (pAC->GIni.GIChipId == CHIP_ID_YUKON)
+                       printk("    scatter-gather:  enabled\n");
+               else
+                       printk("    scatter-gather:  disabled\n");
+
+#else
+                       printk("    scatter-gather:  disabled\n");
+#endif
+#endif /* SK98_INFO */
+
+               if ((Param.Para32[0] != pAC->ActivePort) &&
+                       (pAC->RlmtNets == 1)) {
+                       NewPara.Para32[0] = pAC->ActivePort;
+                       NewPara.Para32[1] = Param.Para32[0];
+                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN,
+                               NewPara);
+               }
+
+               /* Inform the world that link protocol is up. */
+#if 0
+               pAC->dev[Param.Para32[0]]->flags |= IFF_RUNNING;
+#endif
+
+               break;
+       case SK_DRV_NET_DOWN:    /* SK_U32 Reason */
+               /* action list 7 */
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+                       ("NET DOWN EVENT "));
+#ifdef SK98_INFO
+               printk("%s: network connection down\n", pAC->dev[Param.Para32[1]]->name);
+#endif
+#if 0
+               pAC->dev[Param.Para32[1]]->flags &= ~IFF_RUNNING;
+#endif
+               break;
+       case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+                       ("PORT SWITCH HARD "));
+       case SK_DRV_SWITCH_SOFT: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
+       /* action list 6 */
+               printk("%s: switching to port %c\n", pAC->dev[0]->name,
+                       'A'+Param.Para32[1]);
+       case SK_DRV_SWITCH_INTERN: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
+               FromPort = Param.Para32[0];
+               ToPort = Param.Para32[1];
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+                       ("PORT SWITCH EVENT, From: %d  To: %d (Pref %d) ",
+                       FromPort, ToPort, pAC->Rlmt.Net[0].PrefPort));
+               NewPara.Para64 = FromPort;
+               SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
+               NewPara.Para64 = ToPort;
+               SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
+               spin_lock_irqsave(
+                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+                       Flags);
+               spin_lock_irqsave(
+                       &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
+               SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST);
+               SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST);
+               spin_unlock_irqrestore(
+                       &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
+               spin_unlock_irqrestore(
+                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+                       Flags);
+
+               ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */
+               ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */
+
+               ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
+               ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]);
+               spin_lock_irqsave(
+                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+                       Flags);
+               spin_lock_irqsave(
+                       &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
+               pAC->ActivePort = ToPort;
+#if 0
+               SetQueueSizes(pAC);
+#else
+               /* tschilling: New common function with minimum size check. */
+               DualNet = SK_FALSE;
+               if (pAC->RlmtNets == 2) {
+                       DualNet = SK_TRUE;
+               }
+
+               if (SkGeInitAssignRamToQueues(
+                       pAC,
+                       pAC->ActivePort,
+                       DualNet)) {
+                       spin_unlock_irqrestore(
+                               &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
+                       spin_unlock_irqrestore(
+                               &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+                               Flags);
+                       printk("SkGeInitAssignRamToQueues failed.\n");
+                       break;
+               }
+#endif
+               /* tschilling: Handling of return values inserted. */
+               if (SkGeInitPort(pAC, IoC, FromPort) ||
+                       SkGeInitPort(pAC, IoC, ToPort)) {
+                       printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name);
+               }
+               if (Event == SK_DRV_SWITCH_SOFT) {
+                       SkMacRxTxEnable(pAC, IoC, FromPort);
+               }
+               SkMacRxTxEnable(pAC, IoC, ToPort);
+               SkAddrSwap(pAC, IoC, FromPort, ToPort);
+               SkAddrMcUpdate(pAC, IoC, FromPort);
+               SkAddrMcUpdate(pAC, IoC, ToPort);
+               PortReInitBmu(pAC, FromPort);
+               PortReInitBmu(pAC, ToPort);
+               SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
+               SkGePollTxD(pAC, IoC, ToPort, SK_TRUE);
+               ClearAndStartRx(pAC, FromPort);
+               ClearAndStartRx(pAC, ToPort);
+               spin_unlock_irqrestore(
+                       &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
+               spin_unlock_irqrestore(
+                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+                       Flags);
+               break;
+       case SK_DRV_RLMT_SEND:   /* SK_MBUF *pMb */
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+                       ("RLS "));
+               pRlmtMbuf = (SK_MBUF*) Param.pParaPtr;
+               pMsg = (struct sk_buff*) pRlmtMbuf->pOs;
+               skb_put(pMsg, pRlmtMbuf->Length);
+               if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW],
+                       pMsg) < 0)
+
+                       DEV_KFREE_SKB_ANY(pMsg);
+               break;
+       default:
+               break;
+       }
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+               ("END EVENT "));
+
+       return (0);
+} /* SkDrvEvent */
+
+
+/*****************************************************************************
+ *
+ *     SkErrorLog - log errors
+ *
+ * Description:
+ *     This function logs errors to the system buffer and to the console
+ *
+ * Returns:
+ *     0 if everything ok
+ *     < 0  on error
+ *
+ */
+void SkErrorLog(
+SK_AC  *pAC,
+int    ErrClass,
+int    ErrNum,
+char   *pErrorMsg)
+{
+char   ClassStr[80];
+
+       switch (ErrClass) {
+       case SK_ERRCL_OTHER:
+               strcpy(ClassStr, "Other error");
+               break;
+       case SK_ERRCL_CONFIG:
+               strcpy(ClassStr, "Configuration error");
+               break;
+       case SK_ERRCL_INIT:
+               strcpy(ClassStr, "Initialization error");
+               break;
+       case SK_ERRCL_NORES:
+               strcpy(ClassStr, "Out of resources error");
+               break;
+       case SK_ERRCL_SW:
+               strcpy(ClassStr, "internal Software error");
+               break;
+       case SK_ERRCL_HW:
+               strcpy(ClassStr, "Hardware failure");
+               break;
+       case SK_ERRCL_COMM:
+               strcpy(ClassStr, "Communication error");
+               break;
+       }
+       printk(KERN_INFO "%s: -- ERROR --\n        Class:  %s\n"
+               "        Nr:  0x%x\n        Msg:  %s\n", pAC->dev[0]->name,
+               ClassStr, ErrNum, pErrorMsg);
+
+} /* SkErrorLog */
+
+#ifdef DEBUG
+/****************************************************************************/
+/* "debug only" section *****************************************************/
+/****************************************************************************/
+
+
+/*****************************************************************************
+ *
+ *     DumpMsg - print a frame
+ *
+ * Description:
+ *     This function prints frames to the system logfile/to the console.
+ *
+ * Returns: N/A
+ *
+ */
+static void DumpMsg(struct sk_buff *skb, char *str)
+{
+       int     msglen;
+
+       if (skb == NULL) {
+               printk("DumpMsg(): NULL-Message\n");
+               return;
+       }
+
+       if (skb->data == NULL) {
+               printk("DumpMsg(): Message empty\n");
+               return;
+       }
+
+       msglen = skb->len;
+       if (msglen > 64)
+               msglen = 64;
+
+       printk("--- Begin of message from %s , len %d (from %d) ----\n", str, msglen, skb->len);
+
+       DumpData((char *)skb->data, msglen);
+
+       printk("------- End of message ---------\n");
+} /* DumpMsg */
+
+
+/*****************************************************************************
+ *
+ *     DumpData - print a data area
+ *
+ * Description:
+ *     This function prints a area of data to the system logfile/to the
+ *     console.
+ *
+ * Returns: N/A
+ *
+ */
+static void DumpData(char *p, int size)
+{
+register int    i;
+int    haddr, addr;
+char   hex_buffer[180];
+char   asc_buffer[180];
+char   HEXCHAR[] = "0123456789ABCDEF";
+
+       addr = 0;
+       haddr = 0;
+       hex_buffer[0] = 0;
+       asc_buffer[0] = 0;
+       for (i=0; i < size; ) {
+               if (*p >= '0' && *p <='z')
+                       asc_buffer[addr] = *p;
+               else
+                       asc_buffer[addr] = '.';
+               addr++;
+               asc_buffer[addr] = 0;
+               hex_buffer[haddr] = HEXCHAR[(*p & 0xf0) >> 4];
+               haddr++;
+               hex_buffer[haddr] = HEXCHAR[*p & 0x0f];
+               haddr++;
+               hex_buffer[haddr] = ' ';
+               haddr++;
+               hex_buffer[haddr] = 0;
+               p++;
+               i++;
+               if (i%16 == 0) {
+                       printk("%s  %s\n", hex_buffer, asc_buffer);
+                       addr = 0;
+                       haddr = 0;
+               }
+       }
+} /* DumpData */
+
+
+/*****************************************************************************
+ *
+ *     DumpLong - print a data area as long values
+ *
+ * Description:
+ *     This function prints a area of data to the system logfile/to the
+ *     console.
+ *
+ * Returns: N/A
+ *
+ */
+static void DumpLong(char *pc, int size)
+{
+register int    i;
+int    haddr, addr;
+char   hex_buffer[180];
+char   asc_buffer[180];
+char   HEXCHAR[] = "0123456789ABCDEF";
+long   *p;
+int    l;
+
+       addr = 0;
+       haddr = 0;
+       hex_buffer[0] = 0;
+       asc_buffer[0] = 0;
+       p = (long*) pc;
+       for (i=0; i < size; ) {
+               l = (long) *p;
+               hex_buffer[haddr] = HEXCHAR[(l >> 28) & 0xf];
+               haddr++;
+               hex_buffer[haddr] = HEXCHAR[(l >> 24) & 0xf];
+               haddr++;
+               hex_buffer[haddr] = HEXCHAR[(l >> 20) & 0xf];
+               haddr++;
+               hex_buffer[haddr] = HEXCHAR[(l >> 16) & 0xf];
+               haddr++;
+               hex_buffer[haddr] = HEXCHAR[(l >> 12) & 0xf];
+               haddr++;
+               hex_buffer[haddr] = HEXCHAR[(l >> 8) & 0xf];
+               haddr++;
+               hex_buffer[haddr] = HEXCHAR[(l >> 4) & 0xf];
+               haddr++;
+               hex_buffer[haddr] = HEXCHAR[l & 0x0f];
+               haddr++;
+               hex_buffer[haddr] = ' ';
+               haddr++;
+               hex_buffer[haddr] = 0;
+               p++;
+               i++;
+               if (i%8 == 0) {
+                       printk("%4x %s\n", (i-8)*4, hex_buffer);
+                       haddr = 0;
+               }
+       }
+       printk("------------------------\n");
+} /* DumpLong */
+
+#endif
+
+#endif /* CONFIG_SK98 */
diff --git a/drivers/net/sk98lin/skgehwt.c b/drivers/net/sk98lin/skgehwt.c
new file mode 100644 (file)
index 0000000..f8681a8
--- /dev/null
@@ -0,0 +1,220 @@
+/******************************************************************************
+ *
+ * Name:       skgehwt.c
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.13 $
+ * Date:       $Date: 1999/11/22 13:31:12 $
+ * Purpose:    Hardware Timer.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998,1999 SysKonnect,
+ *     a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skgehwt.c,v $
+ *     Revision 1.13  1999/11/22 13:31:12  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.12  1998/10/15 15:11:34  gklug
+ *     fix: ID_sccs to SysKonnectFileId
+ *
+ *     Revision 1.11  1998/10/08 15:27:51  gklug
+ *     chg: correction factor is host clock dependent
+ *
+ *     Revision 1.10  1998/09/15 14:18:31  cgoos
+ *     Changed more BOOLEANs to SK_xxx
+ *
+ *     Revision 1.9  1998/09/15 14:16:06  cgoos
+ *     Changed line 107: FALSE to SK_FALSE
+ *
+ *     Revision 1.8  1998/08/24 13:04:44  gklug
+ *     fix: typo
+ *
+ *     Revision 1.7  1998/08/19 09:50:49  gklug
+ *     fix: remove struct keyword from c-code (see CCC) add typedefs
+ *
+ *     Revision 1.6  1998/08/17 09:59:02  gklug
+ *     fix: typos
+ *
+ *     Revision 1.5  1998/08/14 07:09:10  gklug
+ *     fix: chg pAc -> pAC
+ *
+ *     Revision 1.4  1998/08/10 14:14:52  gklug
+ *     rmv: unneccessary SK_ADDR macro
+ *
+ *     Revision 1.3  1998/08/07 12:53:44  gklug
+ *     fix: first compiled version
+ *
+ *     Revision 1.2  1998/08/07 09:19:29  gklug
+ *     adapt functions to the C coding conventions
+ *     rmv unneccessary functions.
+ *
+ *     Revision 1.1  1998/08/05 11:28:36  gklug
+ *     first version: adapted from SMT/FDDI
+ *
+ *
+ *
+ *
+ ******************************************************************************/
+
+
+#include <config.h>
+
+#ifdef CONFIG_SK98
+
+/*
+       Event queue and dispatcher
+*/
+static const char SysKonnectFileId[] =
+       "$Header: /usr56/projects/ge/schedule/skgehwt.c,v 1.13 1999/11/22 13:31:12 cgoos Exp $" ;
+
+#include "h/skdrv1st.h"                /* Driver Specific Definitions */
+#include "h/skdrv2nd.h"                /* Adapter Control- and Driver specific Def. */
+
+#ifdef __C2MAN__
+/*
+       Hardware Timer function queue management.
+
+       General Description:
+
+ */
+intro()
+{}
+#endif
+
+/*
+ * Prototypes of local functions.
+ */
+#define        SK_HWT_MAX      (65000)
+
+/* correction factor */
+#define        SK_HWT_FAC      (1000 * (SK_U32)pAC->GIni.GIHstClkFact / 100)
+
+/*
+ * Initialize hardware timer.
+ *
+ * Must be called during init level 1.
+ */
+void   SkHwtInit(
+SK_AC  *pAC,   /* Adapters context */
+SK_IOC Ioc)    /* IoContext */
+{
+       pAC->Hwt.TStart = 0 ;
+       pAC->Hwt.TStop  = 0 ;
+       pAC->Hwt.TActive = SK_FALSE ;
+
+       SkHwtStop(pAC,Ioc) ;
+}
+
+/*
+ *
+ * Start hardware timer (clock ticks are 16us).
+ *
+ */
+void   SkHwtStart(
+SK_AC  *pAC,   /* Adapters context */
+SK_IOC Ioc,    /* IoContext */
+SK_U32 Time)   /* Time in units of 16us to load the timer with. */
+{
+       SK_U32  Cnt ;
+
+       if (Time > SK_HWT_MAX)
+               Time = SK_HWT_MAX ;
+
+       pAC->Hwt.TStart = Time ;
+       pAC->Hwt.TStop = 0L ;
+
+       Cnt = Time ;
+
+       /*
+        * if time < 16 us
+        *      time = 16 us
+        */
+       if (!Cnt) {
+               Cnt++ ;
+       }
+
+       SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC) ;
+       SK_OUT16(Ioc, B2_TI_CRTL, TIM_START) ;  /* Start timer. */
+
+       pAC->Hwt.TActive = SK_TRUE ;
+}
+
+/*
+ * Stop hardware timer.
+ * and clear the timer IRQ
+ */
+void   SkHwtStop(
+SK_AC  *pAC,   /* Adapters context */
+SK_IOC Ioc)    /* IoContext */
+{
+       SK_OUT16(Ioc, B2_TI_CRTL, TIM_STOP) ;
+       SK_OUT16(Ioc, B2_TI_CRTL, TIM_CLR_IRQ) ;
+
+       pAC->Hwt.TActive = SK_FALSE ;
+}
+
+
+/*
+ *     Stop hardware timer and read time elapsed since last start.
+ *
+ * returns
+ *     The elapsed time since last start in units of 16us.
+ *
+ */
+SK_U32 SkHwtRead(
+SK_AC  *pAC,   /* Adapters context */
+SK_IOC Ioc)    /* IoContext */
+{
+       SK_U32  TRead ;
+       SK_U32  IStatus ;
+
+       if (pAC->Hwt.TActive) {
+               SkHwtStop(pAC,Ioc) ;
+
+               SK_IN32(Ioc, B2_TI_VAL, &TRead);
+               TRead /= SK_HWT_FAC;
+
+               SK_IN32(Ioc, B0_ISRC, &IStatus);
+
+               /* Check if timer expired (or wraparound). */
+               if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) {
+                       SkHwtStop(pAC,Ioc) ;
+                       pAC->Hwt.TStop = pAC->Hwt.TStart ;
+               } else {
+                       pAC->Hwt.TStop = pAC->Hwt.TStart - TRead ;
+               }
+       }
+       return (pAC->Hwt.TStop) ;
+}
+
+/*
+ * interrupt source= timer
+ */
+void   SkHwtIsr(
+SK_AC  *pAC,   /* Adapters context */
+SK_IOC Ioc)    /* IoContext */
+{
+       SkHwtStop(pAC,Ioc);
+       pAC->Hwt.TStop = pAC->Hwt.TStart;
+       SkTimerDone(pAC,Ioc) ;
+}
+
+#endif /* CONFIG_SK98 */
+
+/* End of file */
diff --git a/drivers/net/sk98lin/skgeinit.c b/drivers/net/sk98lin/skgeinit.c
new file mode 100644 (file)
index 0000000..a18dc0a
--- /dev/null
@@ -0,0 +1,2372 @@
+/******************************************************************************
+ *
+ * Name:       skgeinit.c
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.85 $
+ * Date:       $Date: 2003/02/05 15:30:33 $
+ * Purpose:    Contains functions to initialize the GE HW
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2003 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skgeinit.c,v $
+ *     Revision 1.85  2003/02/05 15:30:33  rschmidt
+ *     Corrected setting of GIHstClkFact (Host Clock Factor) and
+ *     GIPollTimerVal (Descr. Poll Timer Init Value) for YUKON.
+ *     Editorial changes.
+ *
+ *     Revision 1.84  2003/01/28 09:57:25  rschmidt
+ *     Added detection of YUKON-Lite Rev. A0 (stored in GIYukonLite).
+ *     Disabled Rx GMAC FIFO Flush for YUKON-Lite Rev. A0.
+ *     Added support for CLK_RUN (YUKON-Lite).
+ *     Added additional check of PME from D3cold for setting GIVauxAvail.
+ *     Editorial changes.
+ *
+ *     Revision 1.83  2002/12/17 16:15:41  rschmidt
+ *     Added default setting of PhyType (Copper) for YUKON.
+ *     Added define around check for HW self test results.
+ *     Editorial changes.
+ *
+ *     Revision 1.82  2002/12/05 13:40:21  rschmidt
+ *     Added setting of Rx GMAC FIFO Flush Mask register.
+ *     Corrected PhyType with new define SK_PHY_MARV_FIBER when
+ *     YUKON Fiber board was found.
+ *     Editorial changes.
+ *
+ *     Revision 1.81  2002/11/15 12:48:35  rschmidt
+ *     Replaced message SKERR_HWI_E018 with SKERR_HWI_E024 for Rx queue error
+ *     in SkGeStopPort().
+ *     Added init for pAC->GIni.GIGenesis with SK_FALSE in YUKON-branch.
+ *     Editorial changes.
+ *
+ *     Revision 1.80  2002/11/12 17:28:30  rschmidt
+ *     Initialized GIPciSlot64 and GIPciClock66 in SkGeInit1().
+ *     Reduced PCI FIFO watermarks for 32bit/33MHz bus in SkGeInitBmu().
+ *     Editorial changes.
+ *
+ *     Revision 1.79  2002/10/21 09:31:02  mkarl
+ *     Changed SkGeInitAssignRamToQueues(), removed call to
+ *     SkGeInitAssignRamToQueues in SkGeInit1 and fixed compiler warning in
+ *     SkGeInit1.
+ *
+ *     Revision 1.78  2002/10/16 15:55:07  mkarl
+ *     Fixed a bug in SkGeInitAssignRamToQueues.
+ *
+ *     Revision 1.77  2002/10/14 15:07:22  rschmidt
+ *     Corrected timeout handling for Rx queue in SkGeStopPort() (#10748)
+ *     Editorial changes.
+ *
+ *     Revision 1.76  2002/10/11 09:24:38  mkarl
+ *     Added check for HW self test results.
+ *
+ *     Revision 1.75  2002/10/09 16:56:44  mkarl
+ *     Now call SkGeInitAssignRamToQueues() in Init Level 1 in order to assign
+ *     the adapter memory to the queues. This default assignment is not suitable
+ *     for dual net mode.
+ *
+ *     Revision 1.74  2002/09/12 08:45:06  rwahl
+ *     Set defaults for PMSCap, PLinkSpeed & PLinkSpeedCap dependent on PHY.
+ *
+ *     Revision 1.73  2002/08/16 15:19:45  rschmidt
+ *     Corrected check for Tx queues in SkGeCheckQSize().
+ *     Added init for new entry GIGenesis and GICopperType
+ *     Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis.
+ *     Replaced wrong 1st para pAC with IoC in SK_IN/OUT macros.
+ *
+ *     Revision 1.72  2002/08/12 13:38:55  rschmidt
+ *     Added check if VAUX is available (stored in GIVauxAvail)
+ *     Initialized PLinkSpeedCap in Port struct with SK_LSPEED_CAP_1000MBPS
+ *     Editorial changes.
+ *
+ *     Revision 1.71  2002/08/08 16:32:58  rschmidt
+ *     Added check for Tx queues in SkGeCheckQSize().
+ *     Added start of Time Stamp Timer (YUKON) in SkGeInit2().
+ *     Editorial changes.
+ *
+ *     Revision 1.70  2002/07/23 16:04:26  rschmidt
+ *     Added init for GIWolOffs (HW-Bug in YUKON 1st rev.)
+ *     Minor changes
+ *
+ *     Revision 1.69  2002/07/17 17:07:08  rwahl
+ *     - SkGeInit1(): fixed PHY type debug output; corrected init of GIFunc
+ *       table & GIMacType.
+ *     - Editorial changes.
+ *
+ *     Revision 1.68  2002/07/15 18:38:31  rwahl
+ *     Added initialization for MAC type dependent function table.
+ *
+ *     Revision 1.67  2002/07/15 15:45:39  rschmidt
+ *     Added Tx Store & Forward for YUKON (GMAC Tx FIFO is only 1 kB)
+ *     Replaced SK_PHY_MARV by SK_PHY_MARV_COPPER
+ *     Editorial changes
+ *
+ *     Revision 1.66  2002/06/10 09:35:08  rschmidt
+ *     Replaced C++ comments (//)
+ *     Editorial changes
+ *
+ *     Revision 1.65  2002/06/05 08:33:37  rschmidt
+ *     Changed GIRamSize and Reset sequence for YUKON.
+ *     SkMacInit() replaced by SkXmInitMac() resp. SkGmInitMac()
+ *
+ *     Revision 1.64  2002/04/25 13:03:20  rschmidt
+ *     Changes for handling YUKON.
+ *     Removed reference to xmac_ii.h (not necessary).
+ *     Moved all defines into header file.
+ *     Replaced all SkXm...() functions with SkMac...() to handle also
+ *     YUKON's GMAC.
+ *     Added handling for GMAC FIFO in SkGeInitMacFifo(), SkGeStopPort().
+ *     Removed 'goto'-directive from SkGeCfgSync(), SkGeCheckQSize().
+ *     Replaced all XMAC-access macros by functions: SkMacRxTxDisable(),
+ *     SkMacFlushTxFifo().
+ *     Optimized timeout handling in SkGeStopPort().
+ *     Initialized PLinkSpeed in Port struct with SK_LSPEED_AUTO.
+ *     Release of GMAC Link Control reset in SkGeInit1().
+ *     Initialized GIChipId and GIChipRev in GE Init structure.
+ *     Added GIRamSize and PhyType values for YUKON.
+ *     Removed use of PRxCmd to setup XMAC.
+ *     Moved setting of XM_RX_DIS_CEXT to SkXmInitMac().
+ *     Use of SkGeXmitLED() only for GENESIS.
+ *     Changes for V-CPU support.
+ *     Editorial changes.
+ *
+ *     Revision 1.63  2001/04/05 11:02:09  rassmann
+ *     Stop Port check of the STOP bit did not take 2/18 sec as wanted.
+ *
+ *     Revision 1.62  2001/02/07 07:54:21  rassmann
+ *     Corrected copyright.
+ *
+ *     Revision 1.61  2001/01/31 15:31:40  gklug
+ *     fix: problem with autosensing an SR8800 switch
+ *
+ *     Revision 1.60  2000/10/18 12:22:21  cgoos
+ *     Added workaround for half duplex hangup.
+ *
+ *     Revision 1.59  2000/10/10 11:22:06  gklug
+ *     add: in manual half duplex mode ignore carrier extension errors
+ *
+ *     Revision 1.58  2000/10/02 14:10:27  rassmann
+ *     Reading BCOM PHY after releasing reset until it returns a valid value.
+ *
+ *     Revision 1.57  2000/08/03 14:55:28  rassmann
+ *     Waiting for I2C to be ready before de-initializing adapter
+ *     (prevents sensors from hanging up).
+ *
+ *     Revision 1.56  2000/07/27 12:16:48  gklug
+ *     fix: Stop Port check of the STOP bit does now take 2/18 sec as wanted
+ *
+ *     Revision 1.55  1999/11/22 13:32:26  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.54  1999/10/26 07:32:54  malthoff
+ *     Initialize PHWLinkUp with SK_FALSE. Required for Diagnostics.
+ *
+ *     Revision 1.53  1999/08/12 19:13:50  malthoff
+ *     Fix for 1000BT. Do not owerwrite XM_MMU_CMD when
+ *     disabling receiver and transmitter. Other bits
+ *     may be lost.
+ *
+ *     Revision 1.52  1999/07/01 09:29:54  gklug
+ *     fix: DoInitRamQueue needs pAC
+ *
+ *     Revision 1.51  1999/07/01 08:42:21  gklug
+ *     chg: use Store & forward for RAM buffer when Jumbos are used
+ *
+ *     Revision 1.50  1999/05/27 13:19:38  cgoos
+ *     Added Tx PCI watermark initialization.
+ *     Removed Tx RAM queue Store & Forward setting.
+ *
+ *     Revision 1.49  1999/05/20 14:32:45  malthoff
+ *     SkGeLinkLED() is completly removed now.
+ *
+ *     Revision 1.48  1999/05/19 07:28:24  cgoos
+ *     SkGeLinkLED no more available for drivers.
+ *     Changes for 1000Base-T.
+ *
+ *     Revision 1.47  1999/04/08 13:57:45  gklug
+ *     add: Init of new port struct fiels PLinkResCt
+ *     chg: StopPort Timer check
+ *
+ *     Revision 1.46  1999/03/25 07:42:15  malthoff
+ *     SkGeStopPort(): Add workaround for cache incoherency.
+ *                     Create error log entry, disable port, and
+ *                     exit loop if it does not terminate.
+ *     Add XM_RX_LENERR_OK to the default value for the
+ *     XMAC receive command register.
+ *
+ *     Revision 1.45  1999/03/12 16:24:47  malthoff
+ *     Remove PPollRxD and PPollTxD.
+ *     Add check for GIPollTimerVal.
+ *
+ *     Revision 1.44  1999/03/12 13:40:23  malthoff
+ *     Fix: SkGeXmitLED(), SK_LED_TST mode does not work.
+ *     Add: Jumbo frame support.
+ *     Chg: Resolution of parameter IntTime in SkGeCfgSync().
+ *
+ *     Revision 1.43  1999/02/09 10:29:46  malthoff
+ *     Bugfix: The previous modification again also for the second location.
+ *
+ *     Revision 1.42  1999/02/09 09:35:16  malthoff
+ *     Bugfix: The bits '66 MHz Capable' and 'NEWCAP are reset while
+ *             clearing the error bits in the PCI status register.
+ *
+ *     Revision 1.41  1999/01/18 13:07:02  malthoff
+ *     Bugfix: Do not use CFG cycles after during Init- or Runtime, because
+ *             they may not be available after Boottime.
+ *
+ *     Revision 1.40  1999/01/11 12:40:49  malthoff
+ *     Bug fix: PCI_STATUS: clearing error bits sets the UDF bit.
+ *
+ *     Revision 1.39  1998/12/11 15:17:33  gklug
+ *     chg: Init LipaAutoNeg with Unknown
+ *
+ *     Revision 1.38  1998/12/10 11:02:57  malthoff
+ *     Disable Error Log Message when calling SkGeInit(level 2)
+ *     more than once.
+ *
+ *     Revision 1.37  1998/12/07 12:18:25  gklug
+ *     add: refinement of autosense mode: take into account the autoneg cap of LiPa
+ *
+ *     Revision 1.36  1998/12/07 07:10:39  gklug
+ *     fix: init values of LinkBroken/ Capabilities for management
+ *
+ *     Revision 1.35  1998/12/02 10:56:20  gklug
+ *     fix: do NOT init LoinkSync Counter.
+ *
+ *     Revision 1.34  1998/12/01 10:53:21  gklug
+ *     add: init of additional Counters for workaround
+ *
+ *     Revision 1.33  1998/12/01 10:00:49  gklug
+ *     add: init PIsave var in Port struct
+ *
+ *     Revision 1.32  1998/11/26 14:50:40  gklug
+ *     chg: Default is autosensing with AUTOFULL mode
+ *
+ *     Revision 1.31  1998/11/25 15:36:16  gklug
+ *     fix: do NOT stop LED Timer when port should be stopped
+ *
+ *     Revision 1.30  1998/11/24 13:15:28  gklug
+ *     add: Init PCkeckPar struct member
+ *
+ *     Revision 1.29  1998/11/18 13:19:27  malthoff
+ *     Disable packet arbiter timeouts on receive side.
+ *     Use maximum timeout value for packet arbiter
+ *     transmit timeouts.
+ *     Add TestStopBit() function to handle stop RX/TX
+ *     problem with active descriptor poll timers.
+ *     Bug Fix: Descriptor Poll Timer not started, because
+ *     GIPollTimerVal was initialized with 0.
+ *
+ *     Revision 1.28  1998/11/13 14:24:26  malthoff
+ *     Bug Fix: SkGeStopPort() may hang if a Packet Arbiter Timout
+ *     is pending or occurs while waiting for TX_STOP and RX_STOP.
+ *     The PA timeout is cleared now while waiting for TX- or RX_STOP.
+ *
+ *     Revision 1.27  1998/11/02 11:04:36  malthoff
+ *     fix the last fix
+ *
+ *     Revision 1.26  1998/11/02 10:37:03  malthoff
+ *     Fix: SkGePollTxD() enables always the synchronounous poll timer.
+ *
+ *     Revision 1.25  1998/10/28 07:12:43  cgoos
+ *     Fixed "LED_STOP" in SkGeLnkSyncCnt, "== SK_INIT_IO" in SkGeInit.
+ *     Removed: Reset of RAM Interface in SkGeStopPort.
+ *
+ *     Revision 1.24  1998/10/27 08:13:12  malthoff
+ *     Remove temporary code.
+ *
+ *     Revision 1.23  1998/10/26 07:45:03  malthoff
+ *     Add Address Calculation Workaround: If the EPROM byte
+ *     Id is 3, the address offset is 512 kB.
+ *     Initialize default values for PLinkMode and PFlowCtrlMode.
+ *
+ *     Revision 1.22  1998/10/22 09:46:47  gklug
+ *     fix SysKonnectFileId typo
+ *
+ *     Revision 1.21  1998/10/20 12:11:56  malthoff
+ *     Don't dendy the Queue config if the size of the unused
+ *     Rx qeueu is zero.
+ *
+ *     Revision 1.20  1998/10/19 07:27:58  malthoff
+ *     SkGeInitRamIface() is public to be called by diagnostics.
+ *
+ *     Revision 1.19  1998/10/16 13:33:45  malthoff
+ *     Fix: enabling descriptor polling is not allowed until
+ *     the descriptor addresses are set. Descriptor polling
+ *     must be handled by the driver.
+ *
+ *     Revision 1.18  1998/10/16 10:58:27  malthoff
+ *     Remove temp. code for Diag prototype.
+ *     Remove lint warning for dummy reads.
+ *     Call SkGeLoadLnkSyncCnt() during SkGeInitPort().
+ *
+ *     Revision 1.17  1998/10/14 09:16:06  malthoff
+ *     Change parameter LimCount and programming of
+ *     the limit counter in SkGeCfgSync().
+ *
+ *     Revision 1.16  1998/10/13 09:21:16  malthoff
+ *     Don't set XM_RX_SELF_RX in RxCmd Reg, because it's
+ *     like a Loopback Mode in half duplex.
+ *
+ *     Revision 1.15  1998/10/09 06:47:40  malthoff
+ *     SkGeInitMacArb(): set recovery counters init value
+ *     to zero although this counters are not uesd.
+ *     Bug fix in Rx Upper/Lower Pause Threshold calculation.
+ *     Add XM_RX_SELF_RX to RxCmd.
+ *
+ *     Revision 1.14  1998/10/06 15:15:53  malthoff
+ *     Make sure no pending IRQ is cleared in SkGeLoadLnkSyncCnt().
+ *
+ *     Revision 1.13  1998/10/06 14:09:36  malthoff
+ *     Add SkGeLoadLnkSyncCnt(). Modify
+ *     the 'port stopped' condition according
+ *     to the current problem report.
+ *
+ *     Revision 1.12  1998/10/05 08:17:21  malthoff
+ *     Add functions: SkGePollRxD(), SkGePollTxD(),
+ *     DoCalcAddr(), SkGeCheckQSize(),
+ *     DoInitRamQueue(), and SkGeCfgSync().
+ *     Add coding for SkGeInitMacArb(), SkGeInitPktArb(),
+ *     SkGeInitMacFifo(), SkGeInitRamBufs(),
+ *     SkGeInitRamIface(), and SkGeInitBmu().
+ *
+ *     Revision 1.11  1998/09/29 08:26:29  malthoff
+ *     bug fix: SkGeInit0() 'i' should be increment.
+ *
+ *     Revision 1.10  1998/09/28 13:19:01  malthoff
+ *     Coding time: Save the done work.
+ *     Modify SkGeLinkLED(), add SkGeXmitLED(),
+ *     define SkGeCheckQSize(), SkGeInitMacArb(),
+ *     SkGeInitPktArb(), SkGeInitMacFifo(),
+ *     SkGeInitRamBufs(), SkGeInitRamIface(),
+ *     and SkGeInitBmu(). Do coding for SkGeStopPort(),
+ *     SkGeInit1(), SkGeInit2(), and SkGeInit3().
+ *     Do coding for SkGeDinit() and SkGeInitPort().
+ *
+ *     Revision 1.9  1998/09/16 14:29:05  malthoff
+ *     Some minor changes.
+ *
+ *     Revision 1.8  1998/09/11 05:29:14  gklug
+ *     add: init state of a port
+ *
+ *     Revision 1.7  1998/09/04 09:26:25  malthoff
+ *     Short temporary modification.
+ *
+ *     Revision 1.6  1998/09/04 08:27:59  malthoff
+ *     Remark the do-while in StopPort() because it never ends
+ *     without a GE adapter.
+ *
+ *     Revision 1.5  1998/09/03 14:05:45  malthoff
+ *     Change comment for SkGeInitPort(). Do not
+ *     repair the queue sizes if invalid.
+ *
+ *     Revision 1.4  1998/09/03 10:03:19  malthoff
+ *     Implement the new interface according to the
+ *     reviewed interface specification.
+ *
+ *     Revision 1.3  1998/08/19 09:11:25  gklug
+ *     fix: struct are removed from c-source (see CCC)
+ *
+ *     Revision 1.2  1998/07/28 12:33:58  malthoff
+ *     Add 'IoC' parameter in function declaration and SK IO macros.
+ *
+ *     Revision 1.1  1998/07/23 09:48:57  malthoff
+ *     Creation. First dummy 'C' file.
+ *     SkGeInit(Level 0) is card_start for GE.
+ *     SkGeDeInit() is card_stop for GE.
+ *
+ *
+ ******************************************************************************/
+
+#include <config.h>
+
+#ifdef CONFIG_SK98
+
+#include "h/skdrv1st.h"
+#include "h/skdrv2nd.h"
+
+/* global variables ***********************************************************/
+
+/* local variables ************************************************************/
+
+static const char SysKonnectFileId[] =
+       "@(#)$Id: skgeinit.c,v 1.85 2003/02/05 15:30:33 rschmidt Exp $ (C) SK ";
+
+struct s_QOffTab {
+       int     RxQOff;         /* Receive Queue Address Offset */
+       int     XsQOff;         /* Sync Tx Queue Address Offset */
+       int     XaQOff;         /* Async Tx Queue Address Offset */
+};
+static struct s_QOffTab QOffTab[] = {
+       {Q_R1, Q_XS1, Q_XA1}, {Q_R2, Q_XS2, Q_XA2}
+};
+
+
+/******************************************************************************
+ *
+ *     SkGePollRxD() - Enable / Disable Descriptor Polling of RxD Ring
+ *
+ * Description:
+ *     Enable or disable the descriptor polling of the receive descriptor
+ *     ring (RxD) for port 'Port'.
+ *     The new configuration is *not* saved over any SkGeStopPort() and
+ *     SkGeInitPort() calls.
+ *
+ * Returns:
+ *     nothing
+ */
+void SkGePollRxD(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+SK_BOOL PollRxD)       /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */
+{
+       SK_GEPORT *pPrt;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), (PollRxD) ?
+               CSR_ENA_POL : CSR_DIS_POL);
+}      /* SkGePollRxD */
+
+
+/******************************************************************************
+ *
+ *     SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings
+ *
+ * Description:
+ *     Enable or disable the descriptor polling of the transmit descriptor
+ *     ring(s) (TxD) for port 'Port'.
+ *     The new configuration is *not* saved over any SkGeStopPort() and
+ *     SkGeInitPort() calls.
+ *
+ * Returns:
+ *     nothing
+ */
+void SkGePollTxD(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+SK_BOOL PollTxD)       /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */
+{
+       SK_GEPORT *pPrt;
+       SK_U32  DWord;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       DWord = (PollTxD) ? CSR_ENA_POL : CSR_DIS_POL;
+
+       if (pPrt->PXSQSize != 0) {
+               SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord);
+       }
+
+       if (pPrt->PXAQSize != 0) {
+               SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord);
+       }
+}      /* SkGePollTxD */
+
+
+/******************************************************************************
+ *
+ *     SkGeYellowLED() - Switch the yellow LED on or off.
+ *
+ * Description:
+ *     Switch the yellow LED on or off.
+ *
+ * Note:
+ *     This function may be called any time after SkGeInit(Level 1).
+ *
+ * Returns:
+ *     nothing
+ */
+void SkGeYellowLED(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            State)          /* yellow LED state, 0 = OFF, 0 != ON */
+{
+       if (State == 0) {
+               /* Switch yellow LED OFF */
+               SK_OUT8(IoC, B0_LED, LED_STAT_OFF);
+       }
+       else {
+               /* Switch yellow LED ON */
+               SK_OUT8(IoC, B0_LED, LED_STAT_ON);
+       }
+}      /* SkGeYellowLED */
+
+
+/******************************************************************************
+ *
+ *     SkGeXmitLED() - Modify the Operational Mode of a transmission LED.
+ *
+ * Description:
+ *     The Rx or Tx LED which is specified by 'Led' will be
+ *     enabled, disabled or switched on in test mode.
+ *
+ * Note:
+ *     'Led' must contain the address offset of the LEDs INI register.
+ *
+ * Usage:
+ *     SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
+ *
+ * Returns:
+ *     nothing
+ */
+void SkGeXmitLED(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Led,            /* offset to the LED Init Value register */
+int            Mode)           /* Mode may be SK_LED_DIS, SK_LED_ENA, SK_LED_TST */
+{
+       SK_U32  LedIni;
+
+       switch (Mode) {
+       case SK_LED_ENA:
+               LedIni = SK_XMIT_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100;
+               SK_OUT32(IoC, Led + XMIT_LED_INI, LedIni);
+               SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
+               break;
+       case SK_LED_TST:
+               SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_ON);
+               SK_OUT32(IoC, Led + XMIT_LED_CNT, 100);
+               SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
+               break;
+       case SK_LED_DIS:
+       default:
+               /*
+                * Do NOT stop the LED Timer here. The LED might be
+                * in on state. But it needs to go off.
+                */
+               SK_OUT32(IoC, Led + XMIT_LED_CNT, 0);
+               SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_OFF);
+               break;
+       }
+
+       /*
+        * 1000BT: The Transmit LED is driven by the PHY.
+        * But the default LED configuration is used for
+        * Level One and Broadcom PHYs.
+        * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set.)
+        * (In this case it has to be added here. But we will see. XXX)
+        */
+}      /* SkGeXmitLED */
+
+
+/******************************************************************************
+ *
+ *     DoCalcAddr() - Calculates the start and the end address of a queue.
+ *
+ * Description:
+ *     This function calculates the start and the end address of a queue.
+ *  Afterwards the 'StartVal' is incremented to the next start position.
+ *     If the port is already initialized the calculated values
+ *     will be checked against the configured values and an
+ *     error will be returned, if they are not equal.
+ *     If the port is not initialized the values will be written to
+ *     *StartAdr and *EndAddr.
+ *
+ * Returns:
+ *     0:      success
+ *     1:      configuration error
+ */
+static int DoCalcAddr(
+SK_AC          *pAC,                   /* adapter context */
+SK_GEPORT      *pPrt,                  /* port index */
+int                    QuSize,                 /* size of the queue to configure in kB */
+SK_U32         *StartVal,              /* start value for address calculation */
+SK_U32         *QuStartAddr,   /* start addr to calculate */
+SK_U32         *QuEndAddr)             /* end address to calculate */
+{
+       SK_U32  EndVal;
+       SK_U32  NextStart;
+       int             Rtv;
+
+       Rtv = 0;
+       if (QuSize == 0) {
+               EndVal = *StartVal;
+               NextStart = EndVal;
+       }
+       else {
+               EndVal = *StartVal + ((SK_U32)QuSize * 1024) - 1;
+               NextStart = EndVal + 1;
+       }
+
+       if (pPrt->PState >= SK_PRT_INIT) {
+               if (*StartVal != *QuStartAddr || EndVal != *QuEndAddr) {
+                       Rtv = 1;
+               }
+       }
+       else {
+               *QuStartAddr = *StartVal;
+               *QuEndAddr = EndVal;
+       }
+
+       *StartVal = NextStart;
+       return(Rtv);
+}      /* DoCalcAddr */
+
+/******************************************************************************
+ *
+ *     SkGeInitAssignRamToQueues() - allocate default queue sizes
+ *
+ * Description:
+ *     This function assigns the memory to the different queues and ports.
+ *     When DualNet is set to SK_TRUE all ports get the same amount of memory.
+ *  Otherwise the first port gets most of the memory and all the
+ *     other ports just the required minimum.
+ *     This function can only be called when pAC->GIni.GIRamSize and
+ *     pAC->GIni.GIMacsFound have been initialized, usually this happens
+ *     at init level 1
+ *
+ * Returns:
+ *     0 - ok
+ *     1 - invalid input values
+ *     2 - not enough memory
+ */
+
+int SkGeInitAssignRamToQueues(
+SK_AC  *pAC,                   /* Adapter context */
+int            ActivePort,             /* Active Port in RLMT mode */
+SK_BOOL        DualNet)                /* adapter context */
+{
+       int     i;
+       int     UsedKilobytes;                  /* memory already assigned */
+       int     ActivePortKilobytes;    /* memory available for active port */
+       SK_GEPORT *pGePort;
+
+       UsedKilobytes = 0;
+
+       if (ActivePort >= pAC->GIni.GIMacsFound) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+                       ("SkGeInitAssignRamToQueues: ActivePort (%d) invalid\n",
+                       ActivePort));
+               return(1);
+       }
+       if (((pAC->GIni.GIMacsFound * (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE)) +
+               ((RAM_QUOTA_SYNC == 0) ? 0 : SK_MIN_TXQ_SIZE)) > pAC->GIni.GIRamSize) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+                       ("SkGeInitAssignRamToQueues: Not enough memory (%d)\n",
+                        pAC->GIni.GIRamSize));
+               return(2);
+       }
+
+
+       if (DualNet) {
+               /* every port gets the same amount of memory */
+               ActivePortKilobytes = pAC->GIni.GIRamSize / pAC->GIni.GIMacsFound;
+               for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+
+                       pGePort = &pAC->GIni.GP[i];
+
+                       /* take away the minimum memory for active queues */
+                       ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
+
+                       /* receive queue gets the minimum + 80% of the rest */
+                       pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((
+                               ActivePortKilobytes * (unsigned long) RAM_QUOTA_RX) / 100))
+                               + SK_MIN_RXQ_SIZE;
+
+                       ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
+
+                       /* synchronous transmit queue */
+                       pGePort->PXSQSize = 0;
+
+                       /* asynchronous transmit queue */
+                       pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes +
+                               SK_MIN_TXQ_SIZE);
+               }
+       }
+       else {
+               /* Rlmt Mode or single link adapter */
+
+               /* Set standby queue size defaults for all standby ports */
+               for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+
+                       if (i != ActivePort) {
+                               pGePort = &pAC->GIni.GP[i];
+
+                               pGePort->PRxQSize = SK_MIN_RXQ_SIZE;
+                               pGePort->PXAQSize = SK_MIN_TXQ_SIZE;
+                               pGePort->PXSQSize = 0;
+
+                               /* Count used RAM */
+                               UsedKilobytes += pGePort->PRxQSize + pGePort->PXAQSize;
+                       }
+               }
+               /* what's left? */
+               ActivePortKilobytes = pAC->GIni.GIRamSize - UsedKilobytes;
+
+               /* assign it to the active port */
+               /* first take away the minimum memory */
+               ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
+               pGePort = &pAC->GIni.GP[ActivePort];
+
+               /* receive queue get's the minimum + 80% of the rest */
+               pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((ActivePortKilobytes *
+                       (unsigned long) RAM_QUOTA_RX) / 100)) + SK_MIN_RXQ_SIZE;
+
+               ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
+
+               /* synchronous transmit queue */
+               pGePort->PXSQSize = 0;
+
+               /* asynchronous transmit queue */
+               pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes) +
+                       SK_MIN_TXQ_SIZE;
+       }
+#ifdef VCPU
+       VCPUprintf(0, "PRxQSize=%u, PXSQSize=%u, PXAQSize=%u\n",
+               pGePort->PRxQSize, pGePort->PXSQSize, pGePort->PXAQSize);
+#endif /* VCPU */
+
+       return(0);
+}      /* SkGeInitAssignRamToQueues */
+
+/******************************************************************************
+ *
+ *     SkGeCheckQSize() - Checks the Adapters Queue Size Configuration
+ *
+ * Description:
+ *     This function verifies the Queue Size Configuration specified
+ *     in the variables PRxQSize, PXSQSize, and PXAQSize of all
+ *     used ports.
+ *     This requirements must be fullfilled to have a valid configuration:
+ *             - The size of all queues must not exceed GIRamSize.
+ *             - The queue sizes must be specified in units of 8 kB.
+ *             - The size of Rx queues of available ports must not be
+ *               smaller than 16 kB.
+ *             - The size of at least one Tx queue (synch. or asynch.)
+ *        of available ports must not be smaller than 16 kB
+ *        when Jumbo Frames are used.
+ *             - The RAM start and end addresses must not be changed
+ *               for ports which are already initialized.
+ *     Furthermore SkGeCheckQSize() defines the Start and End Addresses
+ *  of all ports and stores them into the HWAC port    structure.
+ *
+ * Returns:
+ *     0:      Queue Size Configuration valid
+ *     1:      Queue Size Configuration invalid
+ */
+static int SkGeCheckQSize(
+SK_AC   *pAC,          /* adapter context */
+int             Port)          /* port index */
+{
+       SK_GEPORT *pPrt;
+       int     UsedMem;        /* total memory used (max. found ports) */
+       int     i;
+       int     Rtv;
+       int     Rtv2;
+       SK_U32  StartAddr;
+
+       UsedMem = 0;
+       Rtv = 0;
+       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+               pPrt = &pAC->GIni.GP[i];
+
+               if ((pPrt->PRxQSize & QZ_UNITS) != 0 ||
+                       (pPrt->PXSQSize & QZ_UNITS) != 0 ||
+                       (pPrt->PXAQSize & QZ_UNITS) != 0) {
+
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
+                       return(1);
+               }
+
+               if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) {
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG);
+                       return(1);
+               }
+
+               /*
+                * the size of at least one Tx queue (synch. or asynch.) has to be > 0.
+                * if Jumbo Frames are used, this size has to be >= 16 kB.
+                */
+               if ((i == Port && pPrt->PXSQSize == 0 && pPrt->PXAQSize == 0) ||
+                       (pAC->GIni.GIPortUsage == SK_JUMBO_LINK &&
+           ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) ||
+                        (pPrt->PXAQSize > 0 && pPrt->PXAQSize < SK_MIN_TXQ_SIZE)))) {
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E023, SKERR_HWI_E023MSG);
+                               return(1);
+               }
+
+               UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize;
+       }
+
+       if (UsedMem > pAC->GIni.GIRamSize) {
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
+               return(1);
+       }
+
+       /* Now start address calculation */
+       StartAddr = pAC->GIni.GIRamOffs;
+       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+               pPrt = &pAC->GIni.GP[i];
+
+               /* Calculate/Check values for the receive queue */
+               Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PRxQSize, &StartAddr,
+                       &pPrt->PRxQRamStart, &pPrt->PRxQRamEnd);
+               Rtv |= Rtv2;
+
+               /* Calculate/Check values for the synchronous Tx queue */
+               Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXSQSize, &StartAddr,
+                       &pPrt->PXsQRamStart, &pPrt->PXsQRamEnd);
+               Rtv |= Rtv2;
+
+               /* Calculate/Check values for the asynchronous Tx queue */
+               Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXAQSize, &StartAddr,
+                       &pPrt->PXaQRamStart, &pPrt->PXaQRamEnd);
+               Rtv |= Rtv2;
+
+               if (Rtv) {
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E013, SKERR_HWI_E013MSG);
+                       return(1);
+               }
+       }
+
+       return(0);
+}      /* SkGeCheckQSize */
+
+
+/******************************************************************************
+ *
+ *     SkGeInitMacArb() - Initialize the MAC Arbiter
+ *
+ * Description:
+ *     This function initializes the MAC Arbiter.
+ *     It must not be called if there is still an
+ *     initialized or active port.
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkGeInitMacArb(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC)            /* IO context */
+{
+       /* release local reset */
+       SK_OUT16(IoC, B3_MA_TO_CTRL, MA_RST_CLR);
+
+       /* configure timeout values */
+       SK_OUT8(IoC, B3_MA_TOINI_RX1, SK_MAC_TO_53);
+       SK_OUT8(IoC, B3_MA_TOINI_RX2, SK_MAC_TO_53);
+       SK_OUT8(IoC, B3_MA_TOINI_TX1, SK_MAC_TO_53);
+       SK_OUT8(IoC, B3_MA_TOINI_TX2, SK_MAC_TO_53);
+
+       SK_OUT8(IoC, B3_MA_RCINI_RX1, 0);
+       SK_OUT8(IoC, B3_MA_RCINI_RX2, 0);
+       SK_OUT8(IoC, B3_MA_RCINI_TX1, 0);
+       SK_OUT8(IoC, B3_MA_RCINI_TX2, 0);
+
+       /* recovery values are needed for XMAC II Rev. B2 only */
+       /* Fast Output Enable Mode was intended to use with Rev. B2, but now? */
+
+       /*
+        * There is no start or enable button to push, therefore
+        * the MAC arbiter is configured and enabled now.
+        */
+}      /* SkGeInitMacArb */
+
+
+/******************************************************************************
+ *
+ *     SkGeInitPktArb() - Initialize the Packet Arbiter
+ *
+ * Description:
+ *     This function initializes the Packet Arbiter.
+ *     It must not be called if there is still an
+ *     initialized or active port.
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkGeInitPktArb(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC)            /* IO context */
+{
+       /* release local reset */
+       SK_OUT16(IoC, B3_PA_CTRL, PA_RST_CLR);
+
+       /* configure timeout values */
+       SK_OUT16(IoC, B3_PA_TOINI_RX1, SK_PKT_TO_MAX);
+       SK_OUT16(IoC, B3_PA_TOINI_RX2, SK_PKT_TO_MAX);
+       SK_OUT16(IoC, B3_PA_TOINI_TX1, SK_PKT_TO_MAX);
+       SK_OUT16(IoC, B3_PA_TOINI_TX2, SK_PKT_TO_MAX);
+
+       /*
+        * enable timeout timers if jumbo frames not used
+        * NOTE: the packet arbiter timeout interrupt is needed for
+        * half duplex hangup workaround
+        */
+       if (pAC->GIni.GIPortUsage != SK_JUMBO_LINK) {
+               if (pAC->GIni.GIMacsFound == 1) {
+                       SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1);
+               }
+               else {
+                       SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1 | PA_ENA_TO_TX2);
+               }
+       }
+}      /* SkGeInitPktArb */
+
+
+/******************************************************************************
+ *
+ *     SkGeInitMacFifo() - Initialize the MAC FIFOs
+ *
+ * Description:
+ *     Initialize all MAC FIFOs of the specified port
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkGeInitMacFifo(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       SK_U16  Word;
+#ifdef VCPU
+       SK_U32  DWord;
+#endif /* VCPU */
+       /*
+        * For each FIFO:
+        *      - release local reset
+        *      - use default value for MAC FIFO size
+        *      - setup defaults for the control register
+        *      - enable the FIFO
+        */
+
+       Word = GMF_RX_CTRL_DEF;
+
+       if (pAC->GIni.GIGenesis) {
+               /* Configure Rx MAC FIFO */
+               SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR);
+               SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF);
+               SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD);
+
+               /* Configure Tx MAC FIFO */
+               SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR);
+               SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
+               SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD);
+
+               /* Enable frame flushing if jumbo frames used */
+               if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
+                       SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH);
+               }
+       }
+       else {
+               /* set Rx GMAC FIFO Flush Mask */
+               SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK);
+
+               if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipId == CHIP_ID_YUKON) {
+
+                       Word &= ~GMF_RX_F_FL_ON;
+               }
+
+               /* Configure Rx MAC FIFO */
+               SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
+               SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), Word);
+
+               /* set Rx GMAC FIFO Flush Threshold (default: 0x0a -> 56 bytes) */
+               SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
+
+               /* Configure Tx MAC FIFO */
+               SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
+               SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U16)GMF_TX_CTRL_DEF);
+
+#ifdef VCPU
+               SK_IN32(IoC, MR_ADDR(Port, RX_GMF_AF_THR), &DWord);
+               SK_IN32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), &DWord);
+#endif /* VCPU */
+
+               /* set Tx GMAC FIFO Almost Empty Threshold */
+/*             SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), 0); */
+       }
+}      /* SkGeInitMacFifo */
+
+
+/******************************************************************************
+ *
+ *     SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting
+ *
+ * Description:
+ *     This function starts the Link Sync Counter of the specified
+ *     port and enables the generation of an Link Sync IRQ.
+ *     The Link Sync Counter may be used to detect an active link,
+ *     if autonegotiation is not used.
+ *
+ * Note:
+ *     o To ensure receiving the Link Sync Event the LinkSyncCounter
+ *       should be initialized BEFORE clearing the XMAC's reset!
+ *     o Enable IS_LNK_SYNC_M1 and IS_LNK_SYNC_M2 after calling this
+ *       function.
+ *
+ * Returns:
+ *     nothing
+ */
+void SkGeLoadLnkSyncCnt(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+SK_U32 CntVal)         /* Counter value */
+{
+       SK_U32  OrgIMsk;
+       SK_U32  NewIMsk;
+       SK_U32  ISrc;
+       SK_BOOL IrqPend;
+
+       /* stop counter */
+       SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_STOP);
+
+       /*
+        * ASIC problem:
+        * Each time starting the Link Sync Counter an IRQ is generated
+        * by the adapter. See problem report entry from 21.07.98
+        *
+        * Workaround:  Disable Link Sync IRQ and clear the unexpeced IRQ
+        *              if no IRQ is already pending.
+        */
+       IrqPend = SK_FALSE;
+       SK_IN32(IoC, B0_ISRC, &ISrc);
+       SK_IN32(IoC, B0_IMSK, &OrgIMsk);
+       if (Port == MAC_1) {
+               NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M1;
+               if ((ISrc & IS_LNK_SYNC_M1) != 0) {
+                       IrqPend = SK_TRUE;
+               }
+       }
+       else {
+               NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M2;
+               if ((ISrc & IS_LNK_SYNC_M2) != 0) {
+                       IrqPend = SK_TRUE;
+               }
+       }
+       if (!IrqPend) {
+               SK_OUT32(IoC, B0_IMSK, NewIMsk);
+       }
+
+       /* load counter */
+       SK_OUT32(IoC, MR_ADDR(Port, LNK_SYNC_INI), CntVal);
+
+       /* start counter */
+       SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_START);
+
+       if (!IrqPend) {
+               /* clear the unexpected IRQ, and restore the interrupt mask */
+               SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_CLR_IRQ);
+               SK_OUT32(IoC, B0_IMSK, OrgIMsk);
+       }
+}      /* SkGeLoadLnkSyncCnt*/
+
+
+/******************************************************************************
+ *
+ *     SkGeCfgSync() - Configure synchronous bandwidth for this port.
+ *
+ * Description:
+ *     This function may be used to configure synchronous bandwidth
+ *     to the specified port. This may be done any time after
+ *     initializing the port. The configuration values are NOT saved
+ *     in the HWAC port structure and will be overwritten any
+ *     time when stopping and starting the port.
+ *     Any values for the synchronous configuration will be ignored
+ *     if the size of the synchronous queue is zero!
+ *
+ *     The default configuration for the synchronous service is
+ *     TXA_ENA_FSYNC. This means if the size of
+ *     the synchronous queue is unequal zero but no specific
+ *     synchronous bandwidth is configured, the synchronous queue
+ *     will always have the 'unlimited' transmit priority!
+ *
+ *     This mode will be restored if the synchronous bandwidth is
+ *     deallocated ('IntTime' = 0 and 'LimCount' = 0).
+ *
+ * Returns:
+ *     0:      success
+ *     1:      parameter configuration error
+ *     2:      try to configure quality of service although no
+ *             synchronous queue is configured
+ */
+int SkGeCfgSync(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+SK_U32 IntTime,        /* Interval Timer Value in units of 8ns */
+SK_U32 LimCount,       /* Number of bytes to transfer during IntTime */
+int            SyncMode)       /* Sync Mode: TXA_ENA_ALLOC | TXA_DIS_ALLOC | 0 */
+{
+       int Rtv;
+
+       Rtv = 0;
+
+       /* check the parameters */
+       if (LimCount > IntTime ||
+               (LimCount == 0 && IntTime != 0) ||
+               (LimCount != 0 && IntTime == 0)) {
+
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
+               return(1);
+       }
+
+       if (pAC->GIni.GP[Port].PXSQSize == 0) {
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG);
+               return(2);
+       }
+
+       /* calculate register values */
+       IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100;
+       LimCount = LimCount / 8;
+
+       if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) {
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
+               return(1);
+       }
+
+       /*
+        * - Enable 'Force Sync' to ensure the synchronous queue
+        *   has the priority while configuring the new values.
+        * - Also 'disable alloc' to ensure the settings complies
+        *   to the SyncMode parameter.
+        * - Disable 'Rate Control' to configure the new values.
+        * - write IntTime and LimCount
+        * - start 'Rate Control' and disable 'Force Sync'
+        *   if Interval Timer or Limit Counter not zero.
+        */
+       SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
+               TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
+
+       SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime);
+       SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount);
+
+       SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
+               (SK_U8)(SyncMode & (TXA_ENA_ALLOC | TXA_DIS_ALLOC)));
+
+       if (IntTime != 0 || LimCount != 0) {
+               SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_START_RC);
+       }
+
+       return(0);
+}      /* SkGeCfgSync */
+
+
+/******************************************************************************
+ *
+ *     DoInitRamQueue() - Initialize the RAM Buffer Address of a single Queue
+ *
+ * Desccription:
+ *     If the queue is used, enable and initialize it.
+ *     Make sure the queue is still reset, if it is not used.
+ *
+ * Returns:
+ *     nothing
+ */
+static void DoInitRamQueue(
+SK_AC  *pAC,                   /* adapter context */
+SK_IOC IoC,                    /* IO context */
+int            QuIoOffs,               /* Queue IO Address Offset */
+SK_U32 QuStartAddr,    /* Queue Start Address */
+SK_U32 QuEndAddr,              /* Queue End Address */
+int            QuType)                 /* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */
+{
+       SK_U32  RxUpThresVal;
+       SK_U32  RxLoThresVal;
+
+       if (QuStartAddr != QuEndAddr) {
+               /* calculate thresholds, assume we have a big Rx queue */
+               RxUpThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_ULPP) / 8;
+               RxLoThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_LLPP_B)/8;
+
+               /* build HW address format */
+               QuStartAddr = QuStartAddr / 8;
+               QuEndAddr = QuEndAddr / 8;
+
+               /* release local reset */
+               SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_CLR);
+
+               /* configure addresses */
+               SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_START), QuStartAddr);
+               SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_END), QuEndAddr);
+               SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_WP), QuStartAddr);
+               SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RP), QuStartAddr);
+
+               switch (QuType) {
+               case SK_RX_SRAM_Q:
+                       /* configure threshold for small Rx Queue */
+                       RxLoThresVal += (SK_RB_LLPP_B - SK_RB_LLPP_S) / 8;
+
+                       /* continue with SK_RX_BRAM_Q */
+               case SK_RX_BRAM_Q:
+                       /* write threshold for Rx Queue */
+
+                       SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal);
+                       SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_LTPP), RxLoThresVal);
+
+                       /* the high priority threshold not used */
+                       break;
+               case SK_TX_RAM_Q:
+                       /*
+                        * Do NOT use Store & Forward under normal operation due to
+                        * performance optimization (GENESIS only).
+                        * But if Jumbo Frames are configured (XMAC Tx FIFO is only 4 kB)
+                        * or YUKON is used ((GMAC Tx FIFO is only 1 kB)
+                        * we NEED Store & Forward of the RAM buffer.
+                        */
+                       if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK ||
+                               !pAC->GIni.GIGenesis) {
+                               /* enable Store & Forward Mode for the Tx Side */
+                               SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD);
+                       }
+                       break;
+               }
+
+               /* set queue operational */
+               SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_OP_MD);
+       }
+       else {
+               /* ensure the queue is still disabled */
+               SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_SET);
+       }
+}      /* DoInitRamQueue */
+
+
+/******************************************************************************
+ *
+ *     SkGeInitRamBufs() - Initialize the RAM Buffer Queues
+ *
+ * Description:
+ *     Initialize all RAM Buffer Queues of the specified port
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkGeInitRamBufs(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT *pPrt;
+       int RxQType;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       if (pPrt->PRxQSize == SK_MIN_RXQ_SIZE) {
+               RxQType = SK_RX_SRAM_Q;         /* small Rx Queue */
+       }
+       else {
+               RxQType = SK_RX_BRAM_Q;         /* big Rx Queue */
+       }
+
+       DoInitRamQueue(pAC, IoC, pPrt->PRxQOff, pPrt->PRxQRamStart,
+               pPrt->PRxQRamEnd, RxQType);
+
+       DoInitRamQueue(pAC, IoC, pPrt->PXsQOff, pPrt->PXsQRamStart,
+               pPrt->PXsQRamEnd, SK_TX_RAM_Q);
+
+       DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart,
+               pPrt->PXaQRamEnd, SK_TX_RAM_Q);
+
+}      /* SkGeInitRamBufs */
+
+
+/******************************************************************************
+ *
+ *     SkGeInitRamIface() - Initialize the RAM Interface
+ *
+ * Description:
+ *     This function initializes the Adapters RAM Interface.
+ *
+ * Note:
+ *     This function is used in the diagnostics.
+ *
+ * Returns:
+ *     nothing
+ */
+void SkGeInitRamIface(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC)            /* IO context */
+{
+       /* release local reset */
+       SK_OUT16(IoC, B3_RI_CTRL, RI_RST_CLR);
+
+       /* configure timeout values */
+       SK_OUT8(IoC, B3_RI_WTO_R1, SK_RI_TO_53);
+       SK_OUT8(IoC, B3_RI_WTO_XA1, SK_RI_TO_53);
+       SK_OUT8(IoC, B3_RI_WTO_XS1, SK_RI_TO_53);
+       SK_OUT8(IoC, B3_RI_RTO_R1, SK_RI_TO_53);
+       SK_OUT8(IoC, B3_RI_RTO_XA1, SK_RI_TO_53);
+       SK_OUT8(IoC, B3_RI_RTO_XS1, SK_RI_TO_53);
+       SK_OUT8(IoC, B3_RI_WTO_R2, SK_RI_TO_53);
+       SK_OUT8(IoC, B3_RI_WTO_XA2, SK_RI_TO_53);
+       SK_OUT8(IoC, B3_RI_WTO_XS2, SK_RI_TO_53);
+       SK_OUT8(IoC, B3_RI_RTO_R2, SK_RI_TO_53);
+       SK_OUT8(IoC, B3_RI_RTO_XA2, SK_RI_TO_53);
+       SK_OUT8(IoC, B3_RI_RTO_XS2, SK_RI_TO_53);
+
+}      /* SkGeInitRamIface */
+
+
+/******************************************************************************
+ *
+ *     SkGeInitBmu() - Initialize the BMU state machines
+ *
+ * Description:
+ *     Initialize all BMU state machines of the specified port
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkGeInitBmu(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;
+       SK_U32          RxWm;
+       SK_U32          TxWm;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       RxWm = SK_BMU_RX_WM;
+       TxWm = SK_BMU_TX_WM;
+
+       if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) {
+               /* for better performance */
+               RxWm /= 2;
+               TxWm /= 2;
+       }
+
+       /* Rx Queue: Release all local resets and set the watermark */
+       SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET);
+       SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm);
+
+       /*
+        * Tx Queue: Release all local resets if the queue is used !
+        *              set watermark
+        */
+       if (pPrt->PXSQSize != 0) {
+               SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET);
+               SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm);
+       }
+
+       if (pPrt->PXAQSize != 0) {
+               SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET);
+               SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm);
+       }
+       /*
+        * Do NOT enable the descriptor poll timers here, because
+        * the descriptor addresses are not specified yet.
+        */
+}      /* SkGeInitBmu */
+
+
+/******************************************************************************
+ *
+ *     TestStopBit() - Test the stop bit of the queue
+ *
+ * Description:
+ *     Stopping a queue is not as simple as it seems to be.
+ *     If descriptor polling is enabled, it may happen
+ *     that RX/TX stop is done and SV idle is NOT set.
+ *     In this case we have to issue another stop command.
+ *
+ * Returns:
+ *     The queues control status register
+ */
+static SK_U32 TestStopBit(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* IO Context */
+int            QuIoOffs)       /* Queue IO Address Offset */
+{
+       SK_U32  QuCsr;  /* CSR contents */
+
+       SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
+
+       if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) {
+               /* Stop Descriptor overridden by start command */
+               SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP);
+
+               SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
+       }
+
+       return(QuCsr);
+}      /* TestStopBit */
+
+
+/******************************************************************************
+ *
+ *     SkGeStopPort() - Stop the Rx/Tx activity of the port 'Port'.
+ *
+ * Description:
+ *     After calling this function the descriptor rings and Rx and Tx
+ *     queues of this port may be reconfigured.
+ *
+ *     It is possible to stop the receive and transmit path separate or
+ *     both together.
+ *
+ *     Dir =   SK_STOP_TX      Stops the transmit path only and resets the MAC.
+ *                             The receive queue is still active and
+ *                             the pending Rx frames may be still transferred
+ *                             into the RxD.
+ *             SK_STOP_RX      Stop the receive path. The tansmit path
+ *                             has to be stopped once before.
+ *             SK_STOP_ALL     SK_STOP_TX + SK_STOP_RX
+ *
+ *     RstMode = SK_SOFT_RST   Resets the MAC. The PHY is still alive.
+ *                     SK_HARD_RST     Resets the MAC and the PHY.
+ *
+ * Example:
+ *     1) A Link Down event was signaled for a port. Therefore the activity
+ *     of this port should be stopped and a hardware reset should be issued
+ *     to enable the workaround of XMAC errata #2. But the received frames
+ *     should not be discarded.
+ *             ...
+ *             SkGeStopPort(pAC, IoC, Port, SK_STOP_TX, SK_HARD_RST);
+ *             (transfer all pending Rx frames)
+ *             SkGeStopPort(pAC, IoC, Port, SK_STOP_RX, SK_HARD_RST);
+ *             ...
+ *
+ *     2) An event was issued which request the driver to switch
+ *     the 'virtual active' link to an other already active port
+ *     as soon as possible. The frames in the receive queue of this
+ *     port may be lost. But the PHY must not be reset during this
+ *     event.
+ *             ...
+ *             SkGeStopPort(pAC, IoC, Port, SK_STOP_ALL, SK_SOFT_RST);
+ *             ...
+ *
+ * Extended Description:
+ *     If SK_STOP_TX is set,
+ *             o disable the MAC's receive and transmitter to prevent
+ *               from sending incomplete frames
+ *             o stop the port's transmit queues before terminating the
+ *               BMUs to prevent from performing incomplete PCI cycles
+ *               on the PCI bus
+ *             - The network Rx and Tx activity and PCI Tx transfer is
+ *               disabled now.
+ *             o reset the MAC depending on the RstMode
+ *             o Stop Interval Timer and Limit Counter of Tx Arbiter,
+ *               also disable Force Sync bit and Enable Alloc bit.
+ *             o perform a local reset of the port's Tx path
+ *                     - reset the PCI FIFO of the async Tx queue
+ *                     - reset the PCI FIFO of the sync Tx queue
+ *                     - reset the RAM Buffer async Tx queue
+ *                     - reset the RAM Buffer sync Tx queue
+ *                     - reset the MAC Tx FIFO
+ *             o switch Link and Tx LED off, stop the LED counters
+ *
+ *     If SK_STOP_RX is set,
+ *             o stop the port's receive queue
+ *             - The path data transfer activity is fully stopped now.
+ *             o perform a local reset of the port's Rx path
+ *                     - reset the PCI FIFO of the Rx queue
+ *                     - reset the RAM Buffer receive queue
+ *                     - reset the MAC Rx FIFO
+ *             o switch Rx LED off, stop the LED counter
+ *
+ *     If all ports are stopped,
+ *             o reset the RAM Interface.
+ *
+ * Notes:
+ *     o This function may be called during the driver states RESET_PORT and
+ *       SWITCH_PORT.
+ */
+void SkGeStopPort(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* I/O context */
+int            Port,   /* port to stop (MAC_1 + n) */
+int            Dir,    /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */
+int            RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */
+{
+#ifndef SK_DIAG
+       SK_EVPARA Para;
+#endif /* !SK_DIAG */
+       SK_GEPORT *pPrt;
+       SK_U32  DWord;
+       SK_U32  XsCsr;
+       SK_U32  XaCsr;
+       SK_U64  ToutStart;
+       int             i;
+       int             ToutCnt;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       if ((Dir & SK_STOP_TX) != 0) {
+               /* disable receiver and transmitter */
+               SkMacRxTxDisable(pAC, IoC, Port);
+
+               /* stop both transmit queues */
+               /*
+                * If the BMU is in the reset state CSR_STOP will terminate
+                * immediately.
+                */
+               SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_STOP);
+               SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_STOP);
+
+               ToutStart = SkOsGetTime(pAC);
+               ToutCnt = 0;
+               do {
+                       /*
+                        * Clear packet arbiter timeout to make sure
+                        * this loop will terminate.
+                        */
+                       SK_OUT16(IoC, B3_PA_CTRL, (Port == MAC_1) ? PA_CLR_TO_TX1 :
+                               PA_CLR_TO_TX2);
+
+                       /*
+                        * If the transfer stucks at the MAC the STOP command will not
+                        * terminate if we don't flush the XMAC's transmit FIFO !
+                        */
+                       SkMacFlushTxFifo(pAC, IoC, Port);
+
+                       XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff);
+                       XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff);
+
+                       if (SkOsGetTime(pAC) - ToutStart > (SK_TICKS_PER_SEC / 18)) {
+                               /*
+                                * Timeout of 1/18 second reached.
+                                * This needs to be checked at 1/18 sec only.
+                                */
+                               ToutCnt++;
+                               if (ToutCnt > 1) {
+                                       /* Might be a problem when the driver event handler
+                                        * calls StopPort again. XXX.
+                                        */
+
+                                       /* Fatal Error, Loop aborted */
+                                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E018,
+                                               SKERR_HWI_E018MSG);
+#ifndef SK_DIAG
+                                       Para.Para64 = Port;
+                                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+#endif /* !SK_DIAG */
+                                       return;
+                               }
+                               /*
+                                * Cache incoherency workaround: Assume a start command
+                                * has been lost while sending the frame.
+                                */
+                               ToutStart = SkOsGetTime(pAC);
+
+                               if ((XsCsr & CSR_STOP) != 0) {
+                                       SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START);
+                               }
+                               if ((XaCsr & CSR_STOP) != 0) {
+                                       SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START);
+                               }
+                       }
+
+                       /*
+                        * Because of the ASIC problem report entry from 21.08.1998 it is
+                        * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set.
+                        */
+               } while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE ||
+                                (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
+
+               /* Reset the MAC depending on the RstMode */
+               if (RstMode == SK_SOFT_RST) {
+                       SkMacSoftRst(pAC, IoC, Port);
+               }
+               else {
+                       SkMacHardRst(pAC, IoC, Port);
+               }
+
+               /* Disable Force Sync bit and Enable Alloc bit */
+               SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
+                       TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
+
+               /* Stop Interval Timer and Limit Counter of Tx Arbiter */
+               SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0L);
+               SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0L);
+
+               /* Perform a local reset of the port's Tx path */
+
+               /* Reset the PCI FIFO of the async Tx queue */
+               SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET);
+               /* Reset the PCI FIFO of the sync Tx queue */
+               SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET);
+               /* Reset the RAM Buffer async Tx queue */
+               SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET);
+               /* Reset the RAM Buffer sync Tx queue */
+               SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET);
+
+               /* Reset Tx MAC FIFO */
+               if (pAC->GIni.GIGenesis) {
+                       /* Note: MFF_RST_SET does NOT reset the XMAC ! */
+                       SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_SET);
+
+                       /* switch Link and Tx LED off, stop the LED counters */
+                       /* Link LED is switched off by the RLMT and the Diag itself */
+                       SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS);
+               }
+               else {
+                       /* Reset TX MAC FIFO */
+                       SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
+               }
+       }
+
+       if ((Dir & SK_STOP_RX) != 0) {
+               /*
+                * The RX Stop Command will not terminate if no buffers
+                * are queued in the RxD ring. But it will always reach
+                * the Idle state. Therefore we can use this feature to
+                * stop the transfer of received packets.
+                */
+               /* stop the port's receive queue */
+               SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP);
+
+               i = 100;
+               do {
+                       /*
+                        * Clear packet arbiter timeout to make sure
+                        * this loop will terminate
+                        */
+                       SK_OUT16(IoC, B3_PA_CTRL, (Port == MAC_1) ? PA_CLR_TO_RX1 :
+                               PA_CLR_TO_RX2);
+
+                       DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff);
+
+                       /* timeout if i==0 (bug fix for #10748) */
+                       if (--i == 0) {
+                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024,
+                                       SKERR_HWI_E024MSG);
+                               break;
+                       }
+                       /*
+                        * because of the ASIC problem report entry from 21.08.98
+                        * it is required to wait until CSR_STOP is reset and
+                        * CSR_SV_IDLE is set.
+                        */
+               } while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
+
+               /* The path data transfer activity is fully stopped now */
+
+               /* Perform a local reset of the port's Rx path */
+
+                /*     Reset the PCI FIFO of the Rx queue */
+               SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET);
+               /* Reset the RAM Buffer receive queue */
+               SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET);
+
+               /* Reset Rx MAC FIFO */
+               if (pAC->GIni.GIGenesis) {
+
+                       SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET);
+
+                       /* switch Rx LED off, stop the LED counter */
+                       SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS);
+               }
+               else {
+                       /* Reset Rx MAC FIFO */
+                       SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
+               }
+       }
+}      /* SkGeStopPort */
+
+
+/******************************************************************************
+ *
+ *     SkGeInit0() - Level 0 Initialization
+ *
+ * Description:
+ *     - Initialize the BMU address offsets
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkGeInit0(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC)            /* IO context */
+{
+       int i;
+       SK_GEPORT *pPrt;
+
+       for (i = 0; i < SK_MAX_MACS; i++) {
+               pPrt = &pAC->GIni.GP[i];
+
+               pPrt->PState = SK_PRT_RESET;
+               pPrt->PRxQOff = QOffTab[i].RxQOff;
+               pPrt->PXsQOff = QOffTab[i].XsQOff;
+               pPrt->PXaQOff = QOffTab[i].XaQOff;
+               pPrt->PCheckPar = SK_FALSE;
+               pPrt->PIsave = 0;
+               pPrt->PPrevShorts = 0;
+               pPrt->PLinkResCt = 0;
+               pPrt->PAutoNegTOCt = 0;
+               pPrt->PPrevRx = 0;
+               pPrt->PPrevFcs = 0;
+               pPrt->PRxLim = SK_DEF_RX_WA_LIM;
+               pPrt->PLinkMode = SK_LMODE_AUTOFULL;
+               pPrt->PLinkSpeedCap = SK_LSPEED_CAP_1000MBPS;
+               pPrt->PLinkSpeed = SK_LSPEED_1000MBPS;
+               pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_UNKNOWN;
+               pPrt->PLinkModeConf = SK_LMODE_AUTOSENSE;
+               pPrt->PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
+               pPrt->PLinkBroken = SK_TRUE; /* See WA code */
+               pPrt->PLinkCap = (SK_LMODE_CAP_HALF | SK_LMODE_CAP_FULL |
+                               SK_LMODE_CAP_AUTOHALF | SK_LMODE_CAP_AUTOFULL);
+               pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN;
+               pPrt->PFlowCtrlCap = SK_FLOW_MODE_SYM_OR_REM;
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
+               pPrt->PMSCap = 0;
+               pPrt->PMSMode = SK_MS_MODE_AUTO;
+               pPrt->PMSStatus = SK_MS_STAT_UNSET;
+               pPrt->PAutoNegFail = SK_FALSE;
+               pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
+               pPrt->PHWLinkUp = SK_FALSE;
+       }
+
+       pAC->GIni.GIPortUsage = SK_RED_LINK;
+
+}      /* SkGeInit0*/
+
+#ifdef SK_PCI_RESET
+
+/******************************************************************************
+ *
+ *     SkGePciReset() - Reset PCI interface
+ *
+ * Description:
+ *     o Read PCI configuration.
+ *     o Change power state to 3.
+ *     o Change power state to 0.
+ *     o Restore PCI configuration.
+ *
+ * Returns:
+ *     0:      Success.
+ *     1:      Power state could not be changed to 3.
+ */
+static int SkGePciReset(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC)            /* IO context */
+{
+       int             i;
+       SK_U16  PmCtlSts;
+       SK_U32  Bp1;
+       SK_U32  Bp2;
+       SK_U16  PciCmd;
+       SK_U8   Cls;
+       SK_U8   Lat;
+       SK_U8   ConfigSpace[PCI_CFG_SIZE];
+
+       /*
+        * Note: Switching to D3 state is like a software reset.
+        *               Switching from D3 to D0 is a hardware reset.
+        *               We have to save and restore the configuration space.
+        */
+       for (i = 0; i < PCI_CFG_SIZE; i++) {
+               SkPciReadCfgDWord(pAC, i*4, &ConfigSpace[i]);
+       }
+
+       /* We know the RAM Interface Arbiter is enabled. */
+       SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D3);
+       SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts);
+
+       if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D3) {
+               return(1);
+       }
+
+       /* Return to D0 state. */
+       SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D0);
+
+       /* Check for D0 state. */
+       SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts);
+
+       if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D0) {
+               return(1);
+       }
+
+       /* Check PCI Config Registers. */
+       SkPciReadCfgWord(pAC, PCI_COMMAND, &PciCmd);
+       SkPciReadCfgByte(pAC, PCI_CACHE_LSZ, &Cls);
+       SkPciReadCfgDWord(pAC, PCI_BASE_1ST, &Bp1);
+       SkPciReadCfgDWord(pAC, PCI_BASE_2ND, &Bp2);
+       SkPciReadCfgByte(pAC, PCI_LAT_TIM, &Lat);
+
+       if (PciCmd != 0 || Cls != 0 || (Bp1 & 0xfffffff0L) != 0 || Bp2 != 1 ||
+               Lat != 0) {
+               return(1);
+       }
+
+       /* Restore PCI Config Space. */
+       for (i = 0; i < PCI_CFG_SIZE; i++) {
+               SkPciWriteCfgDWord(pAC, i*4, ConfigSpace[i]);
+       }
+
+       return(0);
+}      /* SkGePciReset */
+
+#endif /* SK_PCI_RESET */
+
+/******************************************************************************
+ *
+ *     SkGeInit1() - Level 1 Initialization
+ *
+ * Description:
+ *     o Do a software reset.
+ *     o Clear all reset bits.
+ *     o Verify that the detected hardware is present.
+ *       Return an error if not.
+ *     o Get the hardware configuration
+ *             + Read the number of MACs/Ports.
+ *             + Read the RAM size.
+ *             + Read the PCI Revision Id.
+ *             + Find out the adapters host clock speed
+ *             + Read and check the PHY type
+ *
+ * Returns:
+ *     0:      success
+ *     5:      Unexpected PHY type detected
+ *     6:      HW self test failed
+ */
+static int SkGeInit1(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC)            /* IO context */
+{
+       SK_U8   Byte;
+       SK_U16  Word;
+       SK_U16  CtrlStat;
+       SK_U32  FlashAddr;
+       int     RetVal;
+       int     i;
+
+       RetVal = 0;
+
+       /* save CLK_RUN bits (YUKON-Lite) */
+       SK_IN16(IoC, B0_CTST, &CtrlStat);
+
+#ifdef SK_PCI_RESET
+       (void)SkGePciReset(pAC, IoC);
+#endif /* SK_PCI_RESET */
+
+       /* do the SW-reset */
+       SK_OUT8(IoC, B0_CTST, CS_RST_SET);
+
+       /* release the SW-reset */
+       SK_OUT8(IoC, B0_CTST, CS_RST_CLR);
+
+       /* reset all error bits in the PCI STATUS register */
+       /*
+        * Note: PCI Cfg cycles cannot be used, because they are not
+        *               available on some platforms after 'boot time'.
+        */
+       SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
+
+       SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+       SK_OUT16(IoC, PCI_C(PCI_STATUS), Word | PCI_ERRBITS);
+       SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+       /* release Master Reset */
+       SK_OUT8(IoC, B0_CTST, CS_MRST_CLR);
+
+#ifdef CLK_RUN
+       CtrlStat |= CS_CLK_RUN_ENA;
+#endif /* CLK_RUN */
+
+       /* restore CLK_RUN bits */
+       SK_OUT16(IoC, B0_CTST, CtrlStat &
+               (CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA));
+
+       /* read Chip Identification Number */
+       SK_IN8(IoC, B2_CHIP_ID, &Byte);
+       pAC->GIni.GIChipId = Byte;
+
+       /* read number of MACs */
+       SK_IN8(IoC, B2_MAC_CFG, &Byte);
+       pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2;
+
+       /* get Chip Revision Number */
+       pAC->GIni.GIChipRev = (SK_U8)((Byte & CFG_CHIP_R_MSK) >> 4);
+
+       /* get diff. PCI parameters */
+       SK_IN16(IoC, B0_CTST, &CtrlStat);
+
+       /* read the adapters RAM size */
+       SK_IN8(IoC, B2_E_0, &Byte);
+
+       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+
+               pAC->GIni.GIGenesis = SK_TRUE;
+
+               if (Byte == 3) {
+                       /* special case: 4 x 64k x 36, offset = 0x80000 */
+                       pAC->GIni.GIRamSize = 1024;
+                       pAC->GIni.GIRamOffs = (SK_U32)512 * 1024;
+               }
+               else {
+                       pAC->GIni.GIRamSize = (int)Byte * 512;
+                       pAC->GIni.GIRamOffs = 0;
+               }
+               /* all GE adapters work with 53.125 MHz host clock */
+               pAC->GIni.GIHstClkFact = SK_FACT_53;
+
+               /* set Descr. Poll Timer Init Value to 250 ms */
+               pAC->GIni.GIPollTimerVal =
+                       SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100;
+       }
+       else {
+               pAC->GIni.GIGenesis = SK_FALSE;
+
+#ifndef VCPU
+               pAC->GIni.GIRamSize = (Byte == 0) ? 128 : (int)Byte * 4;
+#else
+               pAC->GIni.GIRamSize = 128;
+#endif
+               pAC->GIni.GIRamOffs = 0;
+
+               /* WA for chip Rev. A */
+               pAC->GIni.GIWolOffs = (pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0;
+
+               /* get PM Capabilities of PCI config space */
+               SK_IN16(IoC, PCI_C(PCI_PM_CAP_REG), &Word);
+
+               /* check if VAUX is available */
+               if (((CtrlStat & CS_VAUX_AVAIL) != 0) &&
+                       /* check also if PME from D3cold is set */
+                       ((Word & PCI_PME_D3C_SUP) != 0)) {
+                       /* set entry in GE init struct */
+                       pAC->GIni.GIVauxAvail = SK_TRUE;
+               }
+
+               /* save Flash-Address Register */
+               SK_IN32(IoC, B2_FAR, &FlashAddr);
+
+               /* test Flash-Address Register */
+               SK_OUT8(IoC, B2_FAR + 3, 0xff);
+               SK_IN8(IoC, B2_FAR + 3, &Byte);
+
+               pAC->GIni.GIYukonLite = (SK_BOOL)(Byte != 0);
+
+               /* restore Flash-Address Register */
+               SK_OUT32(IoC, B2_FAR, FlashAddr);
+
+               for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+                       /* set GMAC Link Control reset */
+                       SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET);
+
+                       /* clear GMAC Link Control reset */
+                       SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
+               }
+               /* all YU chips work with 78.125 MHz host clock */
+               pAC->GIni.GIHstClkFact = SK_FACT_78;
+
+               pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX;        /* 215 ms */
+       }
+
+       /* check if 64-bit PCI Slot is present */
+       pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0);
+
+       /* check if 66 MHz PCI Clock is active */
+       pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0);
+
+       /* read PCI HW Revision Id. */
+       SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte);
+       pAC->GIni.GIPciHwRev = Byte;
+
+       /* read the PMD type */
+       SK_IN8(IoC, B2_PMD_TYP, &Byte);
+       pAC->GIni.GICopperType = (SK_U8)(Byte == 'T');
+
+       /* read the PHY type */
+       SK_IN8(IoC, B2_E_1, &Byte);
+
+       Byte &= 0x0f;   /* the PHY type is stored in the lower nibble */
+       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+
+               if (pAC->GIni.GIGenesis) {
+                       switch (Byte) {
+                       case SK_PHY_XMAC:
+                               pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC;
+                               break;
+                       case SK_PHY_BCOM:
+                               pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM;
+                               pAC->GIni.GP[i].PMSCap =
+                                       SK_MS_CAP_AUTO | SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE;
+                               break;
+#ifdef OTHER_PHY
+                       case SK_PHY_LONE:
+                               pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE;
+                               break;
+                       case SK_PHY_NAT:
+                               pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT;
+                               break;
+#endif /* OTHER_PHY */
+                       default:
+                               /* ERROR: unexpected PHY type detected */
+                               RetVal = 5;
+                               break;
+                       }
+               }
+               else {
+                       if (Byte == 0) {
+                               /* if this field is not initialized */
+                               Byte = SK_PHY_MARV_COPPER;
+                               pAC->GIni.GICopperType = SK_TRUE;
+                       }
+                       pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV;
+
+                       if (pAC->GIni.GICopperType) {
+                               pAC->GIni.GP[i].PLinkSpeedCap = SK_LSPEED_CAP_AUTO |
+                                       SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS |
+                                       SK_LSPEED_CAP_1000MBPS;
+                               pAC->GIni.GP[i].PLinkSpeed = SK_LSPEED_AUTO;
+                               pAC->GIni.GP[i].PMSCap =
+                                       SK_MS_CAP_AUTO | SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE;
+                       }
+                       else {
+                               Byte = SK_PHY_MARV_FIBER;
+                       }
+               }
+
+               pAC->GIni.GP[i].PhyType = Byte;
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+                       ("PHY type: %d  PHY addr: %04x\n", Byte,
+                       pAC->GIni.GP[i].PhyAddr));
+       }
+
+       /* get Mac Type & set function pointers dependent on */
+       if (pAC->GIni.GIGenesis) {
+               pAC->GIni.GIMacType = SK_MAC_XMAC;
+
+               pAC->GIni.GIFunc.pFnMacUpdateStats      = SkXmUpdateStats;
+               pAC->GIni.GIFunc.pFnMacStatistic        = SkXmMacStatistic;
+               pAC->GIni.GIFunc.pFnMacResetCounter     = SkXmResetCounter;
+               pAC->GIni.GIFunc.pFnMacOverflow         = SkXmOverflowStatus;
+       }
+       else {
+               pAC->GIni.GIMacType = SK_MAC_GMAC;
+
+               pAC->GIni.GIFunc.pFnMacUpdateStats      = SkGmUpdateStats;
+               pAC->GIni.GIFunc.pFnMacStatistic        = SkGmMacStatistic;
+               pAC->GIni.GIFunc.pFnMacResetCounter     = SkGmResetCounter;
+               pAC->GIni.GIFunc.pFnMacOverflow         = SkGmOverflowStatus;
+
+#ifdef SPECIAL_HANDLING
+               if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
+                       /* check HW self test result */
+                       SK_IN8(IoC, B2_E_3, &Byte);
+                       if ((Byte & B2_E3_RES_MASK) != 0) {
+                               RetVal = 6;
+                       }
+               }
+#endif
+       }
+       return(RetVal);
+}      /* SkGeInit1 */
+
+
+/******************************************************************************
+ *
+ *     SkGeInit2() - Level 2 Initialization
+ *
+ * Description:
+ *     - start the Blink Source Counter
+ *     - start the Descriptor Poll Timer
+ *     - configure the MAC-Arbiter
+ *     - configure the Packet-Arbiter
+ *     - enable the Tx Arbiters
+ *     - enable the RAM Interface Arbiter
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkGeInit2(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC)            /* IO context */
+{
+       SK_U32  DWord;
+       int             i;
+
+       /* start the Descriptor Poll Timer */
+       if (pAC->GIni.GIPollTimerVal != 0) {
+               if (pAC->GIni.GIPollTimerVal > SK_DPOLL_MAX) {
+                       pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX;
+
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E017, SKERR_HWI_E017MSG);
+               }
+               SK_OUT32(IoC, B28_DPT_INI, pAC->GIni.GIPollTimerVal);
+               SK_OUT8(IoC, B28_DPT_CTRL, DPT_START);
+       }
+
+       if (pAC->GIni.GIGenesis) {
+               /* start the Blink Source Counter */
+               DWord = SK_BLK_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100;
+
+               SK_OUT32(IoC, B2_BSC_INI, DWord);
+               SK_OUT8(IoC, B2_BSC_CTRL, BSC_START);
+
+               /*
+                * Configure the MAC Arbiter and the Packet Arbiter.
+                * They will be started once and never be stopped.
+                */
+               SkGeInitMacArb(pAC, IoC);
+
+               SkGeInitPktArb(pAC, IoC);
+       }
+       else {
+               /* start Time Stamp Timer */
+               SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START);
+       }
+
+       /* enable the Tx Arbiters */
+       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+               SK_OUT8(IoC, MR_ADDR(i, TXA_CTRL), TXA_ENA_ARB);
+       }
+
+       /* enable the RAM Interface Arbiter */
+       SkGeInitRamIface(pAC, IoC);
+
+}      /* SkGeInit2 */
+
+/******************************************************************************
+ *
+ *     SkGeInit() - Initialize the GE Adapter with the specified level.
+ *
+ * Description:
+ *     Level   0:      Initialize the Module structures.
+ *     Level   1:      Generic Hardware Initialization. The IOP/MemBase pointer has
+ *                             to be set before calling this level.
+ *
+ *                     o Do a software reset.
+ *                     o Clear all reset bits.
+ *                     o Verify that the detected hardware is present.
+ *                       Return an error if not.
+ *                     o Get the hardware configuration
+ *                             + Set GIMacsFound with the number of MACs.
+ *                             + Store the RAM size in GIRamSize.
+ *                             + Save the PCI Revision ID in GIPciHwRev.
+ *                     o return an error
+ *                             if Number of MACs > SK_MAX_MACS
+ *
+ *                     After returning from Level 0 the adapter
+ *                     may be accessed with IO operations.
+ *
+ *     Level   2:      start the Blink Source Counter
+ *
+ * Returns:
+ *     0:      success
+ *     1:      Number of MACs exceeds SK_MAX_MACS      (after level 1)
+ *     2:      Adapter not present or not accessible
+ *     3:      Illegal initialization level
+ *     4:      Initialization Level 1 Call missing
+ *     5:      Unexpected PHY type detected
+ *     6:      HW self test failed
+ */
+int    SkGeInit(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Level)          /* initialization level */
+{
+       int             RetVal;         /* return value */
+       SK_U32  DWord;
+
+       RetVal = 0;
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+               ("SkGeInit(Level %d)\n", Level));
+
+       switch (Level) {
+       case SK_INIT_DATA:
+               /* Initialization Level 0 */
+               SkGeInit0(pAC, IoC);
+               pAC->GIni.GILevel = SK_INIT_DATA;
+               break;
+
+       case SK_INIT_IO:
+               /* Initialization Level 1 */
+               RetVal = SkGeInit1(pAC, IoC);
+               if (RetVal != 0) {
+                       break;
+               }
+
+               /* check if the adapter seems to be accessible */
+               SK_OUT32(IoC, B2_IRQM_INI, 0x11335577L);
+               SK_IN32(IoC, B2_IRQM_INI, &DWord);
+               SK_OUT32(IoC, B2_IRQM_INI, 0L);
+
+               if (DWord != 0x11335577L) {
+                       RetVal = 2;
+                       break;
+               }
+
+               /* check if the number of GIMacsFound matches SK_MAX_MACS */
+               if (pAC->GIni.GIMacsFound > SK_MAX_MACS) {
+                       RetVal = 1;
+                       break;
+               }
+
+               /* Level 1 successfully passed */
+               pAC->GIni.GILevel = SK_INIT_IO;
+               break;
+
+       case SK_INIT_RUN:
+               /* Initialization Level 2 */
+               if (pAC->GIni.GILevel != SK_INIT_IO) {
+#ifndef SK_DIAG
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E002, SKERR_HWI_E002MSG);
+#endif /* !SK_DIAG */
+                       RetVal = 4;
+                       break;
+               }
+               SkGeInit2(pAC, IoC);
+
+               /* Level 2 successfully passed */
+               pAC->GIni.GILevel = SK_INIT_RUN;
+               break;
+
+       default:
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG);
+               RetVal = 3;
+               break;
+       }
+
+       return(RetVal);
+}      /* SkGeInit */
+
+
+/******************************************************************************
+ *
+ *     SkGeDeInit() - Deinitialize the adapter
+ *
+ * Description:
+ *     All ports of the adapter will be stopped if not already done.
+ *     Do a software reset and switch off all LEDs.
+ *
+ * Returns:
+ *     nothing
+ */
+void SkGeDeInit(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC)            /* IO context */
+{
+       int     i;
+       SK_U16  Word;
+
+#ifndef VCPU
+       /* ensure I2C is ready */
+       SkI2cWaitIrq(pAC, IoC);
+#endif
+
+       /* stop all current transfer activity */
+       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+               if (pAC->GIni.GP[i].PState != SK_PRT_STOP &&
+                       pAC->GIni.GP[i].PState != SK_PRT_RESET) {
+
+                       SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST);
+               }
+       }
+
+       /* Reset all bits in the PCI STATUS register */
+       /*
+        * Note: PCI Cfg cycles cannot be used, because they are not
+        *       available on some platforms after 'boot time'.
+        */
+       SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
+
+       SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+       SK_OUT16(IoC, PCI_C(PCI_STATUS), Word | PCI_ERRBITS);
+       SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+       /* do the reset, all LEDs are switched off now */
+       SK_OUT8(IoC, B0_CTST, CS_RST_SET);
+}      /* SkGeDeInit */
+
+
+/******************************************************************************
+ *
+ *     SkGeInitPort()  Initialize the specified port.
+ *
+ * Description:
+ *     PRxQSize, PXSQSize, and PXAQSize has to be
+ *     configured for the specified port before calling this function.
+ *  The descriptor rings has to be initialized too.
+ *
+ *     o (Re)configure queues of the specified port.
+ *     o configure the MAC of the specified port.
+ *     o put ASIC and MAC(s) in operational mode.
+ *     o initialize Rx/Tx and Sync LED
+ *     o initialize RAM Buffers and MAC FIFOs
+ *
+ *     The port is ready to connect when returning.
+ *
+ * Note:
+ *     The MAC's Rx and Tx state machine is still disabled when returning.
+ *
+ * Returns:
+ *     0:      success
+ *     1:      Queue size initialization error. The configured values
+ *             for PRxQSize, PXSQSize, or PXAQSize are invalid for one
+ *             or more queues. The specified port was NOT initialized.
+ *             An error log entry was generated.
+ *     2:      The port has to be stopped before it can be initialized again.
+ */
+int SkGeInitPort(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port to configure */
+{
+       SK_GEPORT *pPrt;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       if (SkGeCheckQSize(pAC, Port) != 0) {
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG);
+               return(1);
+       }
+
+       if (pPrt->PState == SK_PRT_INIT || pPrt->PState == SK_PRT_RUN) {
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E005, SKERR_HWI_E005MSG);
+               return(2);
+       }
+
+       /* configuration ok, initialize the Port now */
+
+       if (pAC->GIni.GIGenesis) {
+               /* initialize Rx, Tx and Link LED */
+               /*
+                * If 1000BT Phy needs LED initialization than swap
+                * LED and XMAC initialization order
+                */
+               SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
+               SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA);
+               /* The Link LED is initialized by RLMT or Diagnostics itself */
+
+               SkXmInitMac(pAC, IoC, Port);
+       }
+       else {
+
+               SkGmInitMac(pAC, IoC, Port);
+       }
+
+       /* do NOT initialize the Link Sync Counter */
+
+       SkGeInitMacFifo(pAC, IoC, Port);
+
+       SkGeInitRamBufs(pAC, IoC, Port);
+
+       if (pPrt->PXSQSize != 0) {
+               /* enable Force Sync bit if synchronous queue available */
+               SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC);
+       }
+
+       SkGeInitBmu(pAC, IoC, Port);
+
+       /* mark port as initialized */
+       pPrt->PState = SK_PRT_INIT;
+
+       return(0);
+}      /* SkGeInitPort */
+
+#endif /* CONFIG_SK98 */
diff --git a/drivers/net/sk98lin/skgemib.c b/drivers/net/sk98lin/skgemib.c
new file mode 100644 (file)
index 0000000..4a9e9e6
--- /dev/null
@@ -0,0 +1,1060 @@
+/*****************************************************************************
+ *
+ * Name:       skgemib.c
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.7 $
+ * Date:       $Date: 2002/12/16 09:04:34 $
+ * Purpose:    Private Network Management Interface Management Database
+ *
+ ****************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 2002 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/*****************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skgemib.c,v $
+ *     Revision 1.7  2002/12/16 09:04:34  tschilli
+ *     Code for VCT handling added.
+ *
+ *     Revision 1.6  2002/08/09 15:40:21  rwahl
+ *     Editorial change (renamed ConfSpeedCap).
+ *
+ *     Revision 1.5  2002/08/09 11:05:34  rwahl
+ *     Added oid handling for link speed cap.
+ *
+ *     Revision 1.4  2002/08/09 09:40:27  rwahl
+ *     Added support for NDIS OID_PNP_xxx.
+ *
+ *     Revision 1.3  2002/07/17 19:39:54  rwahl
+ *     Added handler for OID_SKGE_SPEED_MODE & OID_SKGE_SPEED_STATUS.
+ *
+ *     Revision 1.2  2002/05/22 08:59:00  rwahl
+ *     - static functions only for release build.
+ *     - Source file must be included.
+ *
+ *     Revision 1.1  2002/05/22 08:12:42  rwahl
+ *     Initial version.
+ *
+ ****************************************************************************/
+
+#include <config.h>
+
+#ifdef CONFIG_SK98
+
+/*
+ * PRIVATE OID handler function prototypes
+ */
+PNMI_STATIC int Addr(SK_AC *pAC, SK_IOC IoC, int action,
+       SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance,
+       unsigned int TableIndex, SK_U32 NetIndex);
+PNMI_STATIC int CsumStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
+       char *pBuf, unsigned int *pLen, SK_U32 Instance,
+       unsigned int TableIndex, SK_U32 NetIndex);
+PNMI_STATIC int General(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
+       char *pBuf, unsigned int *pLen, SK_U32 Instance,
+       unsigned int TableIndex, SK_U32 NetIndex);
+PNMI_STATIC int Mac8023Stat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
+       char *pBuf, unsigned int *pLen, SK_U32 Instance,
+       unsigned int TableIndex, SK_U32 NetIndex);
+PNMI_STATIC int MacPrivateConf(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
+       char *pBuf, unsigned int *pLen, SK_U32 Instance,
+       unsigned int TableIndex, SK_U32 NetIndex);
+PNMI_STATIC int MacPrivateStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
+       char *pBuf, unsigned int *pLen, SK_U32 Instance,
+       unsigned int TableIndex, SK_U32 NetIndex);
+PNMI_STATIC int Monitor(SK_AC *pAC, SK_IOC IoC, int action,
+       SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance,
+       unsigned int TableIndex, SK_U32 NetIndex);
+PNMI_STATIC int OidStruct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
+       char *pBuf, unsigned int *pLen, SK_U32 Instance,
+       unsigned int TableIndex, SK_U32 NetIndex);
+PNMI_STATIC int Perform(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
+       char *pBuf, unsigned int* pLen, SK_U32 Instance,
+       unsigned int TableIndex, SK_U32 NetIndex);
+PNMI_STATIC int Rlmt(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
+       char *pBuf, unsigned int *pLen, SK_U32 Instance,
+       unsigned int TableIndex, SK_U32 NetIndex);
+PNMI_STATIC int RlmtStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
+       char *pBuf, unsigned int *pLen, SK_U32 Instance,
+       unsigned int TableIndex, SK_U32 NetIndex);
+PNMI_STATIC int SensorStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
+       char *pBuf, unsigned int *pLen, SK_U32 Instance,
+       unsigned int TableIndex, SK_U32 NetIndex);
+PNMI_STATIC int Vpd(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
+       char *pBuf, unsigned int *pLen, SK_U32 Instance,
+       unsigned int TableIndex, SK_U32 NetIndex);
+PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
+       char *pBuf, unsigned int *pLen, SK_U32 Instance,
+       unsigned int TableIndex, SK_U32 NetIndex);
+
+#ifdef SK_POWER_MGMT
+PNMI_STATIC int PowerManagement(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
+       char *pBuf, unsigned int *pLen, SK_U32 Instance,
+       unsigned int TableIndex, SK_U32 NetIndex);
+#endif
+
+
+/* defines *******************************************************************/
+#define ID_TABLE_SIZE (sizeof(IdTable)/sizeof(IdTable[0]))
+
+
+/* global variables **********************************************************/
+
+/*
+ * Table to correlate OID with handler function and index to
+ * hardware register stored in StatAddress if applicable.
+ */
+PNMI_STATIC const SK_PNMI_TAB_ENTRY IdTable[] = {
+       {OID_GEN_XMIT_OK,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX},
+       {OID_GEN_RCV_OK,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX},
+       {OID_GEN_XMIT_ERROR,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, General, 0},
+       {OID_GEN_RCV_ERROR,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, General, 0},
+       {OID_GEN_RCV_NO_BUFFER,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, General, 0},
+       {OID_GEN_DIRECTED_FRAMES_XMIT,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNICAST},
+       {OID_GEN_MULTICAST_FRAMES_XMIT,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTICAST},
+       {OID_GEN_BROADCAST_FRAMES_XMIT,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_BROADCAST},
+       {OID_GEN_DIRECTED_FRAMES_RCV,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_UNICAST},
+       {OID_GEN_MULTICAST_FRAMES_RCV,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_MULTICAST},
+       {OID_GEN_BROADCAST_FRAMES_RCV,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_BROADCAST},
+       {OID_GEN_RCV_CRC_ERROR,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FCS},
+       {OID_GEN_TRANSMIT_QUEUE_LENGTH,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, General, 0},
+       {OID_802_3_PERMANENT_ADDRESS,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, 0},
+       {OID_802_3_CURRENT_ADDRESS,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, 0},
+       {OID_802_3_RCV_ERROR_ALIGNMENT,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FRAMING},
+       {OID_802_3_XMIT_ONE_COLLISION,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_SINGLE_COL},
+       {OID_802_3_XMIT_MORE_COLLISIONS,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTI_COL},
+       {OID_802_3_XMIT_DEFERRED,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_DEFFERAL},
+       {OID_802_3_XMIT_MAX_COLLISIONS,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_EXCESS_COL},
+       {OID_802_3_RCV_OVERRUN,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_OVERFLOW},
+       {OID_802_3_XMIT_UNDERRUN,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNDERRUN},
+       {OID_802_3_XMIT_TIMES_CRS_LOST,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_CARRIER},
+       {OID_802_3_XMIT_LATE_COLLISIONS,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_LATE_COL},
+#ifdef SK_POWER_MGMT
+       {OID_PNP_CAPABILITIES,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, PowerManagement, 0},
+       {OID_PNP_SET_POWER,
+               0,
+               0,
+               0,
+               SK_PNMI_WO, PowerManagement, 0},
+       {OID_PNP_QUERY_POWER,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, PowerManagement, 0},
+       {OID_PNP_ADD_WAKE_UP_PATTERN,
+               0,
+               0,
+               0,
+               SK_PNMI_WO, PowerManagement, 0},
+       {OID_PNP_REMOVE_WAKE_UP_PATTERN,
+               0,
+               0,
+               0,
+               SK_PNMI_WO, PowerManagement, 0},
+       {OID_PNP_ENABLE_WAKE_UP,
+               0,
+               0,
+               0,
+               SK_PNMI_RW, PowerManagement, 0},
+#endif /* SK_POWER_MGMT */
+       {OID_SKGE_MDB_VERSION,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(MgmtDBVersion),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_SUPPORTED_LIST,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_ALL_DATA,
+               0,
+               0,
+               0,
+               SK_PNMI_RW, OidStruct, 0},
+       {OID_SKGE_VPD_FREE_BYTES,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(VpdFreeBytes),
+               SK_PNMI_RO, Vpd, 0},
+       {OID_SKGE_VPD_ENTRIES_LIST,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(VpdEntriesList),
+               SK_PNMI_RO, Vpd, 0},
+       {OID_SKGE_VPD_ENTRIES_NUMBER,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(VpdEntriesNumber),
+               SK_PNMI_RO, Vpd, 0},
+       {OID_SKGE_VPD_KEY,
+               SK_PNMI_VPD_ENTRIES,
+               sizeof(SK_PNMI_VPD),
+               SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdKey),
+               SK_PNMI_RO, Vpd, 0},
+       {OID_SKGE_VPD_VALUE,
+               SK_PNMI_VPD_ENTRIES,
+               sizeof(SK_PNMI_VPD),
+               SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdValue),
+               SK_PNMI_RO, Vpd, 0},
+       {OID_SKGE_VPD_ACCESS,
+               SK_PNMI_VPD_ENTRIES,
+               sizeof(SK_PNMI_VPD),
+               SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAccess),
+               SK_PNMI_RO, Vpd, 0},
+       {OID_SKGE_VPD_ACTION,
+               SK_PNMI_VPD_ENTRIES,
+               sizeof(SK_PNMI_VPD),
+               SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAction),
+               SK_PNMI_RW, Vpd, 0},
+       {OID_SKGE_PORT_NUMBER,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(PortNumber),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_DEVICE_TYPE,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(DeviceType),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_DRIVER_DESCR,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(DriverDescr),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_DRIVER_VERSION,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(DriverVersion),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_HW_DESCR,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(HwDescr),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_HW_VERSION,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(HwVersion),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_CHIPSET,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(Chipset),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_ACTION,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(Action),
+               SK_PNMI_RW, Perform, 0},
+       {OID_SKGE_RESULT,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(TestResult),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_BUS_TYPE,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(BusType),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_BUS_SPEED,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(BusSpeed),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_BUS_WIDTH,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(BusWidth),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_TX_SW_QUEUE_LEN,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(TxSwQueueLen),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_TX_SW_QUEUE_MAX,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(TxSwQueueMax),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_TX_RETRY,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(TxRetryCts),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_RX_INTR_CTS,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(RxIntrCts),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_TX_INTR_CTS,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(TxIntrCts),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_RX_NO_BUF_CTS,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(RxNoBufCts),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_TX_NO_BUF_CTS,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(TxNoBufCts),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_TX_USED_DESCR_NO,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(TxUsedDescrNo),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_RX_DELIVERED_CTS,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(RxDeliveredCts),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_RX_OCTETS_DELIV_CTS,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(RxOctetsDeliveredCts),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_RX_HW_ERROR_CTS,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(RxHwErrorsCts),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_TX_HW_ERROR_CTS,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(TxHwErrorsCts),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_IN_ERRORS_CTS,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(InErrorsCts),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_OUT_ERROR_CTS,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(OutErrorsCts),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_ERR_RECOVERY_CTS,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(ErrRecoveryCts),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_SYSUPTIME,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(SysUpTime),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_SENSOR_NUMBER,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(SensorNumber),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_SENSOR_INDEX,
+               SK_PNMI_SENSOR_ENTRIES,
+               sizeof(SK_PNMI_SENSOR),
+               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorIndex),
+               SK_PNMI_RO, SensorStat, 0},
+       {OID_SKGE_SENSOR_DESCR,
+               SK_PNMI_SENSOR_ENTRIES,
+               sizeof(SK_PNMI_SENSOR),
+               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorDescr),
+               SK_PNMI_RO, SensorStat, 0},
+       {OID_SKGE_SENSOR_TYPE,
+               SK_PNMI_SENSOR_ENTRIES,
+               sizeof(SK_PNMI_SENSOR),
+               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorType),
+               SK_PNMI_RO, SensorStat, 0},
+       {OID_SKGE_SENSOR_VALUE,
+               SK_PNMI_SENSOR_ENTRIES,
+               sizeof(SK_PNMI_SENSOR),
+               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorValue),
+               SK_PNMI_RO, SensorStat, 0},
+       {OID_SKGE_SENSOR_WAR_THRES_LOW,
+               SK_PNMI_SENSOR_ENTRIES,
+               sizeof(SK_PNMI_SENSOR),
+               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdLow),
+               SK_PNMI_RO, SensorStat, 0},
+       {OID_SKGE_SENSOR_WAR_THRES_UPP,
+               SK_PNMI_SENSOR_ENTRIES,
+               sizeof(SK_PNMI_SENSOR),
+               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdHigh),
+               SK_PNMI_RO, SensorStat, 0},
+       {OID_SKGE_SENSOR_ERR_THRES_LOW,
+               SK_PNMI_SENSOR_ENTRIES,
+               sizeof(SK_PNMI_SENSOR),
+               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdLow),
+               SK_PNMI_RO, SensorStat, 0},
+       {OID_SKGE_SENSOR_ERR_THRES_UPP,
+               SK_PNMI_SENSOR_ENTRIES,
+               sizeof(SK_PNMI_SENSOR),
+               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdHigh),
+               SK_PNMI_RO, SensorStat, 0},
+       {OID_SKGE_SENSOR_STATUS,
+               SK_PNMI_SENSOR_ENTRIES,
+               sizeof(SK_PNMI_SENSOR),
+               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorStatus),
+               SK_PNMI_RO, SensorStat, 0},
+       {OID_SKGE_SENSOR_WAR_CTS,
+               SK_PNMI_SENSOR_ENTRIES,
+               sizeof(SK_PNMI_SENSOR),
+               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningCts),
+               SK_PNMI_RO, SensorStat, 0},
+       {OID_SKGE_SENSOR_ERR_CTS,
+               SK_PNMI_SENSOR_ENTRIES,
+               sizeof(SK_PNMI_SENSOR),
+               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorCts),
+               SK_PNMI_RO, SensorStat, 0},
+       {OID_SKGE_SENSOR_WAR_TIME,
+               SK_PNMI_SENSOR_ENTRIES,
+               sizeof(SK_PNMI_SENSOR),
+               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningTimestamp),
+               SK_PNMI_RO, SensorStat, 0},
+       {OID_SKGE_SENSOR_ERR_TIME,
+               SK_PNMI_SENSOR_ENTRIES,
+               sizeof(SK_PNMI_SENSOR),
+               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorTimestamp),
+               SK_PNMI_RO, SensorStat, 0},
+       {OID_SKGE_CHKSM_NUMBER,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(ChecksumNumber),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_CHKSM_RX_OK_CTS,
+               SKCS_NUM_PROTOCOLS,
+               sizeof(SK_PNMI_CHECKSUM),
+               SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxOkCts),
+               SK_PNMI_RO, CsumStat, 0},
+       {OID_SKGE_CHKSM_RX_UNABLE_CTS,
+               SKCS_NUM_PROTOCOLS,
+               sizeof(SK_PNMI_CHECKSUM),
+               SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxUnableCts),
+               SK_PNMI_RO, CsumStat, 0},
+       {OID_SKGE_CHKSM_RX_ERR_CTS,
+               SKCS_NUM_PROTOCOLS,
+               sizeof(SK_PNMI_CHECKSUM),
+               SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxErrCts),
+               SK_PNMI_RO, CsumStat, 0},
+       {OID_SKGE_CHKSM_TX_OK_CTS,
+               SKCS_NUM_PROTOCOLS,
+               sizeof(SK_PNMI_CHECKSUM),
+               SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxOkCts),
+               SK_PNMI_RO, CsumStat, 0},
+       {OID_SKGE_CHKSM_TX_UNABLE_CTS,
+               SKCS_NUM_PROTOCOLS,
+               sizeof(SK_PNMI_CHECKSUM),
+               SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxUnableCts),
+               SK_PNMI_RO, CsumStat, 0},
+       {OID_SKGE_STAT_TX,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOkCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX},
+       {OID_SKGE_STAT_TX_OCTETS,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOctetsOkCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_OCTET},
+       {OID_SKGE_STAT_TX_BROADCAST,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBroadcastOkCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BROADCAST},
+       {OID_SKGE_STAT_TX_MULTICAST,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMulticastOkCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTICAST},
+       {OID_SKGE_STAT_TX_UNICAST,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUnicastOkCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNICAST},
+       {OID_SKGE_STAT_TX_LONGFRAMES,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLongFramesCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LONGFRAMES},
+       {OID_SKGE_STAT_TX_BURST,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBurstCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BURST},
+       {OID_SKGE_STAT_TX_PFLOWC,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxPauseMacCtrlCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_PMACC},
+       {OID_SKGE_STAT_TX_FLOWC,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMacCtrlCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MACC},
+       {OID_SKGE_STAT_TX_SINGLE_COL,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSingleCollisionCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SINGLE_COL},
+       {OID_SKGE_STAT_TX_MULTI_COL,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMultipleCollisionCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTI_COL},
+       {OID_SKGE_STAT_TX_EXCESS_COL,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveCollisionCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_COL},
+       {OID_SKGE_STAT_TX_LATE_COL,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLateCollisionCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LATE_COL},
+       {OID_SKGE_STAT_TX_DEFFERAL,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxDeferralCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_DEFFERAL},
+       {OID_SKGE_STAT_TX_EXCESS_DEF,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveDeferralCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_DEF},
+       {OID_SKGE_STAT_TX_UNDERRUN,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxFifoUnderrunCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNDERRUN},
+       {OID_SKGE_STAT_TX_CARRIER,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxCarrierCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_CARRIER},
+/*     {OID_SKGE_STAT_TX_UTIL,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUtilization),
+               SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */
+       {OID_SKGE_STAT_TX_64,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx64Cts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_64},
+       {OID_SKGE_STAT_TX_127,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx127Cts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_127},
+       {OID_SKGE_STAT_TX_255,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx255Cts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_255},
+       {OID_SKGE_STAT_TX_511,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx511Cts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_511},
+       {OID_SKGE_STAT_TX_1023,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx1023Cts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_1023},
+       {OID_SKGE_STAT_TX_MAX,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMaxCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MAX},
+       {OID_SKGE_STAT_TX_SYNC,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC},
+       {OID_SKGE_STAT_TX_SYNC_OCTETS,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncOctetsCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC_OCTET},
+       {OID_SKGE_STAT_RX,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOkCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX},
+       {OID_SKGE_STAT_RX_OCTETS,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOctetsOkCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OCTET},
+       {OID_SKGE_STAT_RX_BROADCAST,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBroadcastOkCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BROADCAST},
+       {OID_SKGE_STAT_RX_MULTICAST,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMulticastOkCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MULTICAST},
+       {OID_SKGE_STAT_RX_UNICAST,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUnicastOkCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_UNICAST},
+       {OID_SKGE_STAT_RX_LONGFRAMES,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxLongFramesCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_LONGFRAMES},
+       {OID_SKGE_STAT_RX_PFLOWC,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC},
+       {OID_SKGE_STAT_RX_FLOWC,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC},
+       {OID_SKGE_STAT_RX_PFLOWC_ERR,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlErrorCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC_ERR},
+       {OID_SKGE_STAT_RX_FLOWC_UNKWN,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlUnknownCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC_UNKWN},
+       {OID_SKGE_STAT_RX_BURST,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBurstCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BURST},
+       {OID_SKGE_STAT_RX_MISSED,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMissedCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MISSED},
+       {OID_SKGE_STAT_RX_FRAMING,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFramingCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FRAMING},
+       {OID_SKGE_STAT_RX_OVERFLOW,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFifoOverflowCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OVERFLOW},
+       {OID_SKGE_STAT_RX_JABBER,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxJabberCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_JABBER},
+       {OID_SKGE_STAT_RX_CARRIER,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCarrierCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CARRIER},
+       {OID_SKGE_STAT_RX_IR_LENGTH,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxIRLengthCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_IRLENGTH},
+       {OID_SKGE_STAT_RX_SYMBOL,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxSymbolCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SYMBOL},
+       {OID_SKGE_STAT_RX_SHORTS,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxShortsCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SHORTS},
+       {OID_SKGE_STAT_RX_RUNT,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxRuntCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_RUNT},
+       {OID_SKGE_STAT_RX_CEXT,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCextCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CEXT},
+       {OID_SKGE_STAT_RX_TOO_LONG,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxTooLongCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_TOO_LONG},
+       {OID_SKGE_STAT_RX_FCS,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFcsCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FCS},
+/*     {OID_SKGE_STAT_RX_UTIL,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUtilization),
+               SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */
+       {OID_SKGE_STAT_RX_64,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx64Cts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_64},
+       {OID_SKGE_STAT_RX_127,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx127Cts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_127},
+       {OID_SKGE_STAT_RX_255,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx255Cts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_255},
+       {OID_SKGE_STAT_RX_511,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx511Cts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_511},
+       {OID_SKGE_STAT_RX_1023,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx1023Cts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_1023},
+       {OID_SKGE_STAT_RX_MAX,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_STAT),
+               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMaxCts),
+               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MAX},
+       {OID_SKGE_PHYS_CUR_ADDR,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacCurrentAddr),
+               SK_PNMI_RW, Addr, 0},
+       {OID_SKGE_PHYS_FAC_ADDR,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacFactoryAddr),
+               SK_PNMI_RO, Addr, 0},
+       {OID_SKGE_PMD,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPMD),
+               SK_PNMI_RO, MacPrivateConf, 0},
+       {OID_SKGE_CONNECTOR,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfConnector),
+               SK_PNMI_RO, MacPrivateConf, 0},
+       {OID_SKGE_LINK_CAP,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkCapability),
+               SK_PNMI_RO, MacPrivateConf, 0},
+       {OID_SKGE_LINK_MODE,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkMode),
+               SK_PNMI_RW, MacPrivateConf, 0},
+       {OID_SKGE_LINK_MODE_STATUS,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkModeStatus),
+               SK_PNMI_RO, MacPrivateConf, 0},
+       {OID_SKGE_LINK_STATUS,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkStatus),
+               SK_PNMI_RO, MacPrivateConf, 0},
+       {OID_SKGE_FLOWCTRL_CAP,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlCapability),
+               SK_PNMI_RO, MacPrivateConf, 0},
+       {OID_SKGE_FLOWCTRL_MODE,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlMode),
+               SK_PNMI_RW, MacPrivateConf, 0},
+       {OID_SKGE_FLOWCTRL_STATUS,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlStatus),
+               SK_PNMI_RO, MacPrivateConf, 0},
+       {OID_SKGE_PHY_OPERATION_CAP,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationCapability),
+               SK_PNMI_RO, MacPrivateConf, 0},
+       {OID_SKGE_PHY_OPERATION_MODE,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationMode),
+               SK_PNMI_RW, MacPrivateConf, 0},
+       {OID_SKGE_PHY_OPERATION_STATUS,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationStatus),
+               SK_PNMI_RO, MacPrivateConf, 0},
+       {OID_SKGE_SPEED_CAP,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedCapability),
+               SK_PNMI_RO, MacPrivateConf, 0},
+       {OID_SKGE_SPEED_MODE,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedMode),
+               SK_PNMI_RW, MacPrivateConf, 0},
+       {OID_SKGE_SPEED_STATUS,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedStatus),
+               SK_PNMI_RO, MacPrivateConf, 0},
+       {OID_SKGE_TRAP,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(Trap),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_TRAP_NUMBER,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(TrapNumber),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_RLMT_MODE,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(RlmtMode),
+               SK_PNMI_RW, Rlmt, 0},
+       {OID_SKGE_RLMT_PORT_NUMBER,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(RlmtPortNumber),
+               SK_PNMI_RO, Rlmt, 0},
+       {OID_SKGE_RLMT_PORT_ACTIVE,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(RlmtPortActive),
+               SK_PNMI_RO, Rlmt, 0},
+       {OID_SKGE_RLMT_PORT_PREFERRED,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(RlmtPortPreferred),
+               SK_PNMI_RW, Rlmt, 0},
+       {OID_SKGE_RLMT_CHANGE_CTS,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(RlmtChangeCts),
+               SK_PNMI_RO, Rlmt, 0},
+       {OID_SKGE_RLMT_CHANGE_TIME,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(RlmtChangeTime),
+               SK_PNMI_RO, Rlmt, 0},
+       {OID_SKGE_RLMT_CHANGE_ESTIM,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(RlmtChangeEstimate),
+               SK_PNMI_RO, Rlmt, 0},
+       {OID_SKGE_RLMT_CHANGE_THRES,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(RlmtChangeThreshold),
+               SK_PNMI_RW, Rlmt, 0},
+       {OID_SKGE_RLMT_PORT_INDEX,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_RLMT),
+               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtIndex),
+               SK_PNMI_RO, RlmtStat, 0},
+       {OID_SKGE_RLMT_STATUS,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_RLMT),
+               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtStatus),
+               SK_PNMI_RO, RlmtStat, 0},
+       {OID_SKGE_RLMT_TX_HELLO_CTS,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_RLMT),
+               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxHelloCts),
+               SK_PNMI_RO, RlmtStat, 0},
+       {OID_SKGE_RLMT_RX_HELLO_CTS,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_RLMT),
+               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxHelloCts),
+               SK_PNMI_RO, RlmtStat, 0},
+       {OID_SKGE_RLMT_TX_SP_REQ_CTS,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_RLMT),
+               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxSpHelloReqCts),
+               SK_PNMI_RO, RlmtStat, 0},
+       {OID_SKGE_RLMT_RX_SP_CTS,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_RLMT),
+               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxSpHelloCts),
+               SK_PNMI_RO, RlmtStat, 0},
+       {OID_SKGE_RLMT_MONITOR_NUMBER,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(RlmtMonitorNumber),
+               SK_PNMI_RO, General, 0},
+       {OID_SKGE_RLMT_MONITOR_INDEX,
+               SK_PNMI_MONITOR_ENTRIES,
+               sizeof(SK_PNMI_RLMT_MONITOR),
+               SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorIndex),
+               SK_PNMI_RO, Monitor, 0},
+       {OID_SKGE_RLMT_MONITOR_ADDR,
+               SK_PNMI_MONITOR_ENTRIES,
+               sizeof(SK_PNMI_RLMT_MONITOR),
+               SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAddr),
+               SK_PNMI_RO, Monitor, 0},
+       {OID_SKGE_RLMT_MONITOR_ERRS,
+               SK_PNMI_MONITOR_ENTRIES,
+               sizeof(SK_PNMI_RLMT_MONITOR),
+               SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorErrorCts),
+               SK_PNMI_RO, Monitor, 0},
+       {OID_SKGE_RLMT_MONITOR_TIMESTAMP,
+               SK_PNMI_MONITOR_ENTRIES,
+               sizeof(SK_PNMI_RLMT_MONITOR),
+               SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorTimestamp),
+               SK_PNMI_RO, Monitor, 0},
+       {OID_SKGE_RLMT_MONITOR_ADMIN,
+               SK_PNMI_MONITOR_ENTRIES,
+               sizeof(SK_PNMI_RLMT_MONITOR),
+               SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAdmin),
+               SK_PNMI_RW, Monitor, 0},
+       {OID_SKGE_MTU,
+               1,
+               0,
+               SK_PNMI_MAI_OFF(MtuSize),
+               SK_PNMI_RW, MacPrivateConf, 0},
+       {OID_SKGE_VCT_GET,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Vct, 0},
+       {OID_SKGE_VCT_SET,
+               0,
+               0,
+               0,
+               SK_PNMI_WO, Vct, 0},
+       {OID_SKGE_VCT_STATUS,
+               0,
+               0,
+               0,
+               SK_PNMI_RO, Vct, 0},
+};
+
+#endif /* CONFIG_SK98 */
diff --git a/drivers/net/sk98lin/skgepnmi.c b/drivers/net/sk98lin/skgepnmi.c
new file mode 100644 (file)
index 0000000..b5d32b0
--- /dev/null
@@ -0,0 +1,8310 @@
+/*****************************************************************************
+ *
+ * Name:       skgepnmi.c
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.102 $
+ * Date:       $Date: 2002/12/16 14:03:24 $
+ * Purpose:    Private Network Management Interface
+ *
+ ****************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2002 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/*****************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skgepnmi.c,v $
+ *     Revision 1.102  2002/12/16 14:03:24  tschilli
+ *     VCT code in Vct() changed.
+ *
+ *     Revision 1.101  2002/12/16 09:04:10  tschilli
+ *     Code for VCT handling added.
+ *
+ *     Revision 1.100  2002/09/26 14:28:13  tschilli
+ *     For XMAC the values in the SK_PNMI_PORT Port struct are copied to
+ *     the new SK_PNMI_PORT BufPort struct during a MacUpdate() call.
+ *     These values are used when GetPhysStatVal() is called. With this
+ *     mechanism you get the best results when software corrections for
+ *     counters are needed. Example: RX_LONGFRAMES.
+ *
+ *     Revision 1.99  2002/09/17 12:31:19  tschilli
+ *     OID_SKGE_TX_HW_ERROR_CTS, OID_SKGE_OUT_ERROR_CTS, OID_GEN_XMIT_ERROR:
+ *     Double count of SK_PNMI_HTX_EXCESS_COL in function General() removed.
+ *     OID_PNP_CAPABILITIES: sizeof(SK_PM_WAKE_UP_CAPABILITIES) changed to
+ *     sizeof(SK_PNP_CAPABILITIES) in function PowerManagement().
+ *
+ *     Revision 1.98  2002/09/10 09:00:03  rwahl
+ *     Adapted boolean definitions according sktypes.
+ *
+ *     Revision 1.97  2002/09/05 15:07:03  rwahl
+ *     Editorial changes.
+ *
+ *     Revision 1.96  2002/09/05 11:04:14  rwahl
+ *     - Rx/Tx packets statistics of virtual port were zero on link down (#10750)
+ *     - For GMAC the overflow IRQ for Rx longframe counter was not counted.
+ *     - Incorrect calculation for oids OID_SKGE_RX_HW_ERROR_CTS,
+ *       OID_SKGE_IN_ERRORS_CTS,  OID_GEN_RCV_ERROR.
+ *     - Moved correction for OID_SKGE_STAT_RX_TOO_LONG to GetPhysStatVal().
+ *     - Editorial changes.
+ *
+ *     Revision 1.95  2002/09/04 08:53:37  rwahl
+ *     - Incorrect statistics for Rx_too_long counter with jumbo frame (#10751)
+ *     - StatRxFrameTooLong & StatRxPMaccErr counters were not reset.
+ *     - Fixed compiler warning for debug msg arg types.
+ *
+ *     Revision 1.94  2002/08/09 15:42:14  rwahl
+ *     - Fixed StatAddr table for GMAC.
+ *     - VirtualConf(): returned indeterminated status for speed oids if no
+ *       active port.
+ *
+ *     Revision 1.93  2002/08/09 11:04:59  rwahl
+ *     Added handler for link speed caps.
+ *
+ *     Revision 1.92  2002/08/09 09:43:03  rwahl
+ *     - Added handler for NDIS OID_PNP_xxx ids.
+ *
+ *     Revision 1.91  2002/07/17 19:53:03  rwahl
+ *     - Added StatOvrflwBit table for XMAC & GMAC.
+ *     - Extended StatAddr table for GMAC. Added check of number of counters
+ *       in enumeration and size of StatAddr table on init level.
+ *     - Added use of GIFunc table.
+ *     - ChipSet is not static anymore,
+ *     - Extended SIRQ event handler for both mac types.
+ *     - Fixed rx short counter bug (#10620)
+ *     - Added handler for oids SKGE_SPEED_MODE & SKGE_SPEED_STATUS.
+ *     - Extendet GetPhysStatVal() for GMAC.
+ *     - Editorial changes.
+ *
+ *     Revision 1.90  2002/05/22 08:56:25  rwahl
+ *     - Moved OID table to separate source file.
+ *     - Fix: TX_DEFFERAL counter incremented in full-duplex mode.
+ *     - Use string definitions for error msgs.
+ *
+ *     Revision 1.89  2001/09/18 10:01:30  mkunz
+ *     some OID's fixed for dualnetmode
+ *
+ *     Revision 1.88  2001/08/02 07:58:08  rwahl
+ *     - Fixed NetIndex to csum module at ResetCounter().
+ *
+ *     Revision 1.87  2001/04/06 13:35:09  mkunz
+ *     -Bugs fixed in handling of OID_SKGE_MTU and the VPD OID's
+ *
+ *     Revision 1.86  2001/03/09 09:18:03  mkunz
+ *     Changes in SK_DBG_MSG
+ *
+ *     Revision 1.85  2001/03/08 09:37:31  mkunz
+ *     Bugfix in ResetCounter for Pnmi.Port structure
+ *
+ *     Revision 1.84  2001/03/06 09:04:55  mkunz
+ *     Made some changes in instance calculation
+ *
+ *     Revision 1.83  2001/02/15 09:15:32  mkunz
+ *     Necessary changes for dual net mode added
+ *
+ *     Revision 1.82  2001/02/07 08:24:19  mkunz
+ *     -Made changes in handling of OID_SKGE_MTU
+ *
+ *     Revision 1.81  2001/02/06 09:58:00  mkunz
+ *     -Vpd bug fixed
+ *     -OID_SKGE_MTU added
+ *     -pnmi support for dual net mode. Interface function and macros extended
+ *
+ *     Revision 1.80  2001/01/22 13:41:35  rassmann
+ *     Supporting two nets on dual-port adapters.
+ *
+ *     Revision 1.79  2000/12/05 14:57:40  cgoos
+ *     SetStruct failed before first Link Up (link mode of virtual
+ *     port "INDETERMINATED").
+ *
+ *     Revision 1.78  2000/09/12 10:44:58  cgoos
+ *     Fixed SK_PNMI_STORE_U32 calls with typecasted argument.
+ *
+ *     Revision 1.77  2000/09/07 08:10:19  rwahl
+ *     - Modified algorithm for 64bit NDIS statistic counters;
+ *       returns 64bit or 32bit value depending on passed buffer
+ *       size. Indicate capability for 64bit NDIS counter, if passed
+ *       buffer size is zero. OID_GEN_XMIT_ERROR, OID_GEN_RCV_ERROR,
+ *       and OID_GEN_RCV_NO_BUFFER handled as 64bit counter, too.
+ *     - corrected OID_SKGE_RLMT_PORT_PREFERRED.
+ *
+ *     Revision 1.76  2000/08/03 15:23:39  rwahl
+ *     - Correction for FrameTooLong counter has to be moved to OID handling
+ *       routines (instead of statistic counter routine).
+ *     - Fix in XMAC Reset Event handling: Only offset counter for hardware
+ *       statistic registers are updated.
+ *
+ *     Revision 1.75  2000/08/01 16:46:05  rwahl
+ *     - Added StatRxLongFrames counter and correction of FrameTooLong counter.
+ *     - Added directive to control width (default = 32bit) of NDIS statistic
+ *       counters (SK_NDIS_64BIT_CTR).
+ *
+ *     Revision 1.74  2000/07/04 11:41:53  rwahl
+ *     - Added volition connector type.
+ *
+ *     Revision 1.73  2000/03/15 16:33:10  rwahl
+ *     Fixed bug 10510; wrong reset of virtual port statistic counters.
+ *
+ *     Revision 1.72  1999/12/06 16:15:53  rwahl
+ *     Fixed problem of instance range for current and factory MAC address.
+ *
+ *     Revision 1.71  1999/12/06 10:14:20  rwahl
+ *     Fixed bug 10476; set operation for PHY_OPERATION_MODE.
+ *
+ *     Revision 1.70  1999/11/22 13:33:34  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.69  1999/10/18 11:42:15  rwahl
+ *     Added typecasts for checking event dependent param (debug only).
+ *
+ *     Revision 1.68  1999/10/06 09:35:59  cgoos
+ *     Added state check to PHY_READ call (hanged if called during startup).
+ *
+ *     Revision 1.67  1999/09/22 09:53:20  rwahl
+ *     - Read Broadcom register for updating fcs error counter (1000Base-T).
+ *
+ *     Revision 1.66  1999/08/26 13:47:56  rwahl
+ *     Added SK_DRIVER_SENDEVENT when queueing RLMT_CHANGE_THRES trap.
+ *
+ *     Revision 1.65  1999/07/26 07:49:35  cgoos
+ *     Added two typecasts to avoid compiler warnings.
+ *
+ *     Revision 1.64  1999/05/20 09:24:12  cgoos
+ *     Changes for 1000Base-T (sensors, Master/Slave).
+ *
+ *     Revision 1.63  1999/04/13 15:11:58  mhaveman
+ *     Moved include of rlmt.h to header skgepnmi.h because some macros
+ *     are needed there.
+ *
+ *     Revision 1.62  1999/04/13 15:08:07  mhaveman
+ *     Replaced again SK_RLMT_CHECK_LINK with SK_PNMI_RLMT_MODE_CHK_LINK
+ *     to grant unified interface by only using the PNMI header file.
+ *     SK_PNMI_RLMT_MODE_CHK_LINK is defined the same as SK_RLMT_CHECK_LINK.
+ *
+ *     Revision 1.61  1999/04/13 15:02:48  mhaveman
+ *     Changes caused by review:
+ *     -Changed some comments
+ *     -Removed redundant check for OID_SKGE_PHYS_FAC_ADDR
+ *     -Optimized PRESET check.
+ *     -Meaning of error SK_ADDR_DUPLICATE_ADDRESS changed. Set of same
+ *      address will now not cause this error. Removed corresponding check.
+ *
+ *     Revision 1.60  1999/03/23 10:41:23  mhaveman
+ *     Added comments.
+ *
+ *     Revision 1.59  1999/02/19 08:01:28  mhaveman
+ *     Fixed bug 10372 that after counter reset all ports were displayed
+ *     as inactive.
+ *
+ *     Revision 1.58  1999/02/16 18:04:47  mhaveman
+ *     Fixed problem of twisted OIDs SENSOR_WAR_TIME and SENSOR_ERR_TIME.
+ *
+ *     Revision 1.56  1999/01/27 12:29:11  mhaveman
+ *     SkTimerStart was called with time value in milli seconds but needs
+ *     micro seconds.
+ *
+ *     Revision 1.55  1999/01/25 15:00:38  mhaveman
+ *     Added support to allow multiple ports to be active. If this feature in
+ *     future will be used, the Management Data Base variables PORT_ACTIVE
+ *     and PORT_PREFERED should be moved to the port specific part of RLMT.
+ *     Currently they return the values of the first active physical port
+ *     found. A set to the virtual port will actually change all active
+ *     physical ports. A get returns the melted values of all active physical
+ *     ports. If the port values differ a return value INDETERMINATED will
+ *     be returned. This effects especially the CONF group.
+ *
+ *     Revision 1.54  1999/01/19 10:10:22  mhaveman
+ *     -Fixed bug 10354: Counter values of virtual port were wrong after port
+ *      switches
+ *     -Added check if a switch to the same port is notified.
+ *
+ *     Revision 1.53  1999/01/07 09:25:21  mhaveman
+ *     Forgot to initialize a variable.
+ *
+ *     Revision 1.52  1999/01/05 10:34:33  mhaveman
+ *     Fixed little error in RlmtChangeEstimate calculation.
+ *
+ *     Revision 1.51  1999/01/05 09:59:07  mhaveman
+ *     -Moved timer start to init level 2
+ *     -Redesigned port switch average calculation to avoid 64bit
+ *      arithmetic.
+ *
+ *     Revision 1.50  1998/12/10 15:13:59  mhaveman
+ *     -Fixed: PHYS_CUR_ADDR returned wrong addresses
+ *     -Fixed: RLMT_PORT_PREFERED and RLMT_CHANGE_THRES preset returned
+ *             always BAD_VALUE.
+ *     -Fixed: TRAP buffer seemed to sometimes suddenly empty
+ *
+ *     Revision 1.49  1998/12/09 16:17:07  mhaveman
+ *     Fixed: Couldnot delete VPD keys on UNIX.
+ *
+ *     Revision 1.48  1998/12/09 14:11:10  mhaveman
+ *     -Add: Debugmessage for XMAC_RESET supressed to minimize output.
+ *     -Fixed: RlmtChangeThreshold will now be initialized.
+ *     -Fixed: VPD_ENTRIES_LIST extended value with unnecessary space char.
+ *     -Fixed: On VPD key creation an invalid key name could be created
+ *             (e.g. A5)
+ *     -Some minor changes in comments and code.
+ *
+ *     Revision 1.47  1998/12/08 16:00:31  mhaveman
+ *     -Fixed: For RLMT_PORT_ACTIVE will now be returned a 0 if no port
+ *             is active.
+ *     -Fixed: For the RLMT statistics group only the last value was
+ *             returned and the rest of the buffer was filled with 0xff
+ *     -Fixed: Mysteriously the preset on RLMT_MODE still returned
+ *             BAD_VALUE.
+ *     Revision 1.46  1998/12/08 10:04:56  mhaveman
+ *     -Fixed: Preset on RLMT_MODE returned always BAD_VALUE error.
+ *     -Fixed: Alignment error in GetStruct
+ *     -Fixed: If for Get/Preset/SetStruct the buffer size is equal or
+ *             larger than SK_PNMI_MIN_STRUCT_SIZE the return value is stored
+ *             to the buffer. In this case the caller should always return
+ *             ok to its upper routines. Only if the buffer size is less
+ *             than SK_PNMI_MIN_STRUCT_SIZE and the return value is unequal
+ *             to 0, an error should be returned by the caller.
+ *     -Fixed: Wrong number of instances with RLMT statistic.
+ *     -Fixed: Return now SK_LMODE_STAT_UNKNOWN if the LinkModeStatus is 0.
+ *
+ *     Revision 1.45  1998/12/03 17:17:24  mhaveman
+ *     -Removed for VPD create action the buffer size limitation to 4 bytes.
+ *     -Pass now physical/active physical port to ADDR for CUR_ADDR set
+ *
+ *     Revision 1.44  1998/12/03 15:14:35  mhaveman
+ *     Another change to Vpd instance evaluation.
+ *
+ *     Revision 1.43  1998/12/03 14:18:10  mhaveman
+ *     -Fixed problem in PnmiSetStruct. It was impossible to set any value.
+ *     -Removed VPD key evaluation for VPD_FREE_BYTES and VPD_ACTION.
+ *
+ *     Revision 1.42  1998/12/03 11:31:47  mhaveman
+ *     Inserted cast to satisfy lint.
+ *
+ *     Revision 1.41  1998/12/03 11:28:16  mhaveman
+ *     Removed SK_PNMI_CHECKPTR
+ *
+ *     Revision 1.40  1998/12/03 11:19:07  mhaveman
+ *     Fixed problems
+ *     -A set to virtual port will now be ignored. A set with broadcast
+ *      address to any port will be ignored.
+ *     -GetStruct function made VPD instance calculation wrong.
+ *     -Prefered port returned -1 instead of 0.
+ *
+ *     Revision 1.39  1998/11/26 15:30:29  mhaveman
+ *     Added sense mode to link mode.
+ *
+ *     Revision 1.38  1998/11/23 15:34:00  mhaveman
+ *     -Fixed bug for RX counters. On an RX overflow interrupt the high
+ *      words of all RX counters were incremented.
+ *     -SET operations on FLOWCTRL_MODE and LINK_MODE accept now the
+ *      value 0, which has no effect. It is usefull for multiple instance
+ *      SETs.
+ *
+ *     Revision 1.37  1998/11/20 08:02:04  mhaveman
+ *     -Fixed: Ports were compared with MAX_SENSORS
+ *     -Fixed: Crash in GetTrapEntry with MEMSET macro
+ *     -Fixed: Conversions between physical, logical port index and instance
+ *
+ *     Revision 1.36  1998/11/16 07:48:53  mhaveman
+ *     Casted SK_DRIVER_SENDEVENT with (void) to eleminate compiler warnings
+ *     on Solaris.
+ *
+ *     Revision 1.35  1998/11/16 07:45:34  mhaveman
+ *     SkAddrOverride now returns value and will be checked.
+ *
+ *     Revision 1.34  1998/11/10 13:40:37  mhaveman
+ *     Needed to change interface, because NT driver needs a return value
+ *     of needed buffer space on TOO_SHORT errors. Therefore all
+ *     SkPnmiGet/Preset/Set functions now have a pointer to the length
+ *     parameter, where the needed space on error is returned.
+ *
+ *     Revision 1.33  1998/11/03 13:52:46  mhaveman
+ *     Made file lint conform.
+ *
+ *     Revision 1.32  1998/11/03 13:19:07  mhaveman
+ *     The events SK_HWEV_SET_LMODE and SK_HWEV_SET_FLOWMODE pass now in
+ *     Para32[0] the physical MAC index and in Para32[1] the new mode.
+ *
+ *     Revision 1.31  1998/11/03 12:30:40  gklug
+ *     fix: compiler warning memset
+ *
+ *     Revision 1.30  1998/11/03 12:04:46  mhaveman
+ *     Fixed problem in SENSOR_VALUE, which wrote beyond the buffer end
+ *     Fixed alignment problem with CHIPSET.
+ *
+ *     Revision 1.29  1998/11/02 11:23:54  mhaveman
+ *     Corrected SK_ERROR_LOG to SK_ERR_LOG. Sorry.
+ *
+ *     Revision 1.28  1998/11/02 10:47:16  mhaveman
+ *     Added syslog messages for internal errors.
+ *
+ *     Revision 1.27  1998/10/30 15:48:06  mhaveman
+ *     Fixed problems after simulation of SK_PNMI_EVT_CHG_EST_TIMER and
+ *     RlmtChangeThreshold calculation.
+ *
+ *     Revision 1.26  1998/10/29 15:36:55  mhaveman
+ *     -Fixed bug in trap buffer handling.
+ *     -OID_SKGE_DRIVER_DESCR, OID_SKGE_DRIVER_VERSION, OID_SKGE_HW_DESCR,
+ *      OID_SKGE_HW_VERSION, OID_SKGE_VPD_ENTRIES_LIST, OID_SKGE_VPD_KEY,
+ *      OID_SKGE_VPD_VALUE, and OID_SKGE_SENSOR_DESCR return values with
+ *      a leading octet before each string storing the string length.
+ *     -Perform a RlmtUpdate during SK_PNMI_EVT_XMAC_RESET to minimize
+ *      RlmtUpdate calls in GetStatVal.
+ *     -Inserted SK_PNMI_CHECKFLAGS macro increase readability.
+ *
+ *     Revision 1.25  1998/10/29 08:50:36  mhaveman
+ *     Fixed problems after second event simulation.
+ *
+ *     Revision 1.24  1998/10/28 08:44:37  mhaveman
+ *     -Fixed alignment problem
+ *     -Fixed problems during event simulation
+ *     -Fixed sequence of error return code (INSTANCE -> ACCESS -> SHORT)
+ *     -Changed type of parameter Instance back to SK_U32 because of VPD
+ *     -Updated new VPD function calls
+ *
+ *     Revision 1.23  1998/10/23 10:16:37  mhaveman
+ *     Fixed bugs after buffer test simulation.
+ *
+ *     Revision 1.22  1998/10/21 13:23:52  mhaveman
+ *     -Call syntax of SkOsGetTime() changed to SkOsGetTime(pAc).
+ *     -Changed calculation of hundrets of seconds.
+ *
+ *     Revision 1.20  1998/10/20 07:30:45  mhaveman
+ *     Made type changes to unsigned integer where possible.
+ *
+ *     Revision 1.19  1998/10/19 10:51:30  mhaveman
+ *     -Made Bug fixes after simulation run
+ *     -Renamed RlmtMAC... to RlmtPort...
+ *     -Marked workarounds with Errata comments
+ *
+ *     Revision 1.18  1998/10/14 07:50:08  mhaveman
+ *     -For OID_SKGE_LINK_STATUS the link down detection has moved from RLMT
+ *      to HWACCESS.
+ *     -Provided all MEMCPY/MEMSET macros with (char *) pointers, because
+ *      Solaris throwed warnings when mapping to bcopy/bset.
+ *
+ *     Revision 1.17  1998/10/13 07:42:01  mhaveman
+ *     -Added OIDs OID_SKGE_TRAP_NUMBER and OID_SKGE_ALL_DATA
+ *     -Removed old cvs history entries
+ *     -Renamed MacNumber to PortNumber
+ *
+ *     Revision 1.16  1998/10/07 10:52:49  mhaveman
+ *     -Inserted handling of some OID_GEN_ Ids for windows
+ *     -Fixed problem with 803.2 statistic.
+ *
+ *     Revision 1.15  1998/10/01 09:16:29  mhaveman
+ *     Added Debug messages for function call and UpdateFlag tracing.
+ *
+ *     Revision 1.14  1998/09/30 13:39:09  mhaveman
+ *     -Reduced namings of 'MAC' by replacing them with 'PORT'.
+ *     -Completed counting of OID_SKGE_RX_HW_ERROR_CTS,
+ *       OID_SKGE_TX_HW_ERROR_CTS,
+ *      OID_SKGE_IN_ERRORS_CTS, and OID_SKGE_OUT_ERROR_CTS.
+ *     -SET check for RlmtMode
+ *
+ *     Revision 1.13  1998/09/28 13:13:08  mhaveman
+ *     Hide strcmp, strlen, and strncpy behind macros SK_STRCMP, SK_STRLEN,
+ *     and SK_STRNCPY. (Same reasons as for mem.. and MEM..)
+ *
+ *     Revision 1.12  1998/09/16 08:18:36  cgoos
+ *     Fix: XM_INxx and XM_OUTxx called with different parameter order:
+ *      sometimes IoC,Mac,...  sometimes Mac,IoC,... Now always first variant.
+ *     Fix: inserted "Pnmi." into some pAC->pDriverDescription / Version.
+ *     Change: memset, memcpy to makros SK_MEMSET, SK_MEMCPY
+ *
+ *     Revision 1.11  1998/09/04 17:01:45  mhaveman
+ *     Added SyncCounter as macro and OID_SKGE_.._NO_DESCR_CTS to
+ *     OID_SKGE_RX_NO_BUF_CTS.
+ *
+ *     Revision 1.10  1998/09/04 14:35:35  mhaveman
+ *     Added macro counters, that are counted by driver.
+ *
+ ****************************************************************************/
+
+
+#include <config.h>
+
+#ifdef CONFIG_SK98
+
+static const char SysKonnectFileId[] =
+       "@(#) $Id: skgepnmi.c,v 1.102 2002/12/16 14:03:24 tschilli Exp $"
+       " (C) SysKonnect.";
+
+#include "h/skdrv1st.h"
+#include "h/sktypes.h"
+#include "h/xmac_ii.h"
+#include "h/skdebug.h"
+#include "h/skqueue.h"
+#include "h/skgepnmi.h"
+#include "h/skgesirq.h"
+#include "h/skcsum.h"
+#include "h/skvpd.h"
+#include "h/skgehw.h"
+#include "h/skgeinit.h"
+#include "h/skdrv2nd.h"
+#include "h/skgepnm2.h"
+#ifdef SK_POWER_MGMT
+#include "h/skgepmgt.h"
+#endif
+/* defines *******************************************************************/
+
+#ifndef DEBUG
+#define PNMI_STATIC    static
+#else  /* DEBUG */
+#define PNMI_STATIC
+#endif /* DEBUG */
+
+/*
+ * Public Function prototypes
+ */
+int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
+int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
+       unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
+int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
+       unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
+int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
+       unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
+int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
+       unsigned int *pLen, SK_U32 NetIndex);
+int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
+       unsigned int *pLen, SK_U32 NetIndex);
+int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
+       unsigned int *pLen, SK_U32 NetIndex);
+int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
+
+
+/*
+ * Private Function prototypes
+ */
+
+PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
+       PhysPortIndex);
+PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
+       PhysPortIndex);
+PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
+PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
+PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
+       unsigned int PhysPortIndex, unsigned int StatIndex);
+PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
+       unsigned int StatIndex, SK_U32 NetIndex);
+PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
+PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
+       unsigned int *pEntries);
+PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
+       unsigned int KeyArrLen, unsigned int *pKeyNo);
+PNMI_STATIC int LookupId(SK_U32 Id);
+PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
+       unsigned int LastMac);
+PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
+       unsigned int *pLen, SK_U32 NetIndex);
+PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
+       char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
+PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
+PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
+       unsigned int PortIndex);
+PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
+       unsigned int SensorIndex);
+PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
+PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
+PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
+PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
+PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
+PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
+       unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
+PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
+
+/*
+ * Table to correlate OID with handler function and index to
+ * hardware register stored in StatAddress if applicable.
+ */
+#include "skgemib.c"
+
+/* global variables **********************************************************/
+
+/*
+ * Overflow status register bit table and corresponding counter
+ * dependent on MAC type - the number relates to the size of overflow
+ * mask returned by the pFnMacOverflow function
+ */
+PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
+/* Bit0  */    { SK_PNMI_HTX,                          SK_PNMI_HTX_UNICAST},
+/* Bit1  */    { SK_PNMI_HTX_OCTETHIGH,        SK_PNMI_HTX_BROADCAST},
+/* Bit2  */    { SK_PNMI_HTX_OCTETLOW,         SK_PNMI_HTX_PMACC},
+/* Bit3  */    { SK_PNMI_HTX_BROADCAST,        SK_PNMI_HTX_MULTICAST},
+/* Bit4  */    { SK_PNMI_HTX_MULTICAST,        SK_PNMI_HTX_OCTETLOW},
+/* Bit5  */    { SK_PNMI_HTX_UNICAST,          SK_PNMI_HTX_OCTETHIGH},
+/* Bit6  */    { SK_PNMI_HTX_LONGFRAMES,       SK_PNMI_HTX_64},
+/* Bit7  */    { SK_PNMI_HTX_BURST,            SK_PNMI_HTX_127},
+/* Bit8  */    { SK_PNMI_HTX_PMACC,            SK_PNMI_HTX_255},
+/* Bit9  */    { SK_PNMI_HTX_MACC,             SK_PNMI_HTX_511},
+/* Bit10 */    { SK_PNMI_HTX_SINGLE_COL,       SK_PNMI_HTX_1023},
+/* Bit11 */    { SK_PNMI_HTX_MULTI_COL,        SK_PNMI_HTX_MAX},
+/* Bit12 */    { SK_PNMI_HTX_EXCESS_COL,       SK_PNMI_HTX_LONGFRAMES},
+/* Bit13 */    { SK_PNMI_HTX_LATE_COL,         SK_PNMI_HTX_RESERVED},
+/* Bit14 */    { SK_PNMI_HTX_DEFFERAL,         SK_PNMI_HTX_COL},
+/* Bit15 */    { SK_PNMI_HTX_EXCESS_DEF,       SK_PNMI_HTX_LATE_COL},
+/* Bit16 */    { SK_PNMI_HTX_UNDERRUN,         SK_PNMI_HTX_EXCESS_COL},
+/* Bit17 */    { SK_PNMI_HTX_CARRIER,          SK_PNMI_HTX_MULTI_COL},
+/* Bit18 */    { SK_PNMI_HTX_UTILUNDER,        SK_PNMI_HTX_SINGLE_COL},
+/* Bit19 */    { SK_PNMI_HTX_UTILOVER,         SK_PNMI_HTX_UNDERRUN},
+/* Bit20 */    { SK_PNMI_HTX_64,                       SK_PNMI_HTX_RESERVED},
+/* Bit21 */    { SK_PNMI_HTX_127,                      SK_PNMI_HTX_RESERVED},
+/* Bit22 */    { SK_PNMI_HTX_255,                      SK_PNMI_HTX_RESERVED},
+/* Bit23 */    { SK_PNMI_HTX_511,                      SK_PNMI_HTX_RESERVED},
+/* Bit24 */    { SK_PNMI_HTX_1023,             SK_PNMI_HTX_RESERVED},
+/* Bit25 */    { SK_PNMI_HTX_MAX,                      SK_PNMI_HTX_RESERVED},
+/* Bit26 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
+/* Bit27 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
+/* Bit28 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
+/* Bit29 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
+/* Bit30 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
+/* Bit31 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
+/* Bit32 */    { SK_PNMI_HRX,                          SK_PNMI_HRX_UNICAST},
+/* Bit33 */    { SK_PNMI_HRX_OCTETHIGH,        SK_PNMI_HRX_BROADCAST},
+/* Bit34 */    { SK_PNMI_HRX_OCTETLOW,         SK_PNMI_HRX_PMACC},
+/* Bit35 */    { SK_PNMI_HRX_BROADCAST,        SK_PNMI_HRX_MULTICAST},
+/* Bit36 */    { SK_PNMI_HRX_MULTICAST,        SK_PNMI_HRX_FCS},
+/* Bit37 */    { SK_PNMI_HRX_UNICAST,          SK_PNMI_HRX_RESERVED},
+/* Bit38 */    { SK_PNMI_HRX_PMACC,            SK_PNMI_HRX_OCTETLOW},
+/* Bit39 */    { SK_PNMI_HRX_MACC,             SK_PNMI_HRX_OCTETHIGH},
+/* Bit40 */    { SK_PNMI_HRX_PMACC_ERR,        SK_PNMI_HRX_BADOCTETLOW},
+/* Bit41 */    { SK_PNMI_HRX_MACC_UNKWN,       SK_PNMI_HRX_BADOCTETHIGH},
+/* Bit42 */    { SK_PNMI_HRX_BURST,            SK_PNMI_HRX_UNDERSIZE},
+/* Bit43 */    { SK_PNMI_HRX_MISSED,           SK_PNMI_HRX_RUNT},
+/* Bit44 */    { SK_PNMI_HRX_FRAMING,          SK_PNMI_HRX_64},
+/* Bit45 */    { SK_PNMI_HRX_OVERFLOW,         SK_PNMI_HRX_127},
+/* Bit46 */    { SK_PNMI_HRX_JABBER,           SK_PNMI_HRX_255},
+/* Bit47 */    { SK_PNMI_HRX_CARRIER,          SK_PNMI_HRX_511},
+/* Bit48 */    { SK_PNMI_HRX_IRLENGTH,         SK_PNMI_HRX_1023},
+/* Bit49 */    { SK_PNMI_HRX_SYMBOL,           SK_PNMI_HRX_MAX},
+/* Bit50 */    { SK_PNMI_HRX_SHORTS,           SK_PNMI_HRX_LONGFRAMES},
+/* Bit51 */    { SK_PNMI_HRX_RUNT,             SK_PNMI_HRX_TOO_LONG},
+/* Bit52 */    { SK_PNMI_HRX_TOO_LONG,         SK_PNMI_HRX_JABBER},
+/* Bit53 */    { SK_PNMI_HRX_FCS,                      SK_PNMI_HRX_RESERVED},
+/* Bit54 */    { SK_PNMI_HRX_RESERVED,         SK_PNMI_HRX_OVERFLOW},
+/* Bit55 */    { SK_PNMI_HRX_CEXT,             SK_PNMI_HRX_RESERVED},
+/* Bit56 */    { SK_PNMI_HRX_UTILUNDER,        SK_PNMI_HRX_RESERVED},
+/* Bit57 */    { SK_PNMI_HRX_UTILOVER,         SK_PNMI_HRX_RESERVED},
+/* Bit58 */    { SK_PNMI_HRX_64,                       SK_PNMI_HRX_RESERVED},
+/* Bit59 */    { SK_PNMI_HRX_127,                      SK_PNMI_HRX_RESERVED},
+/* Bit60 */    { SK_PNMI_HRX_255,                      SK_PNMI_HRX_RESERVED},
+/* Bit61 */    { SK_PNMI_HRX_511,                      SK_PNMI_HRX_RESERVED},
+/* Bit62 */    { SK_PNMI_HRX_1023,             SK_PNMI_HRX_RESERVED},
+/* Bit63 */    { SK_PNMI_HRX_MAX,                      SK_PNMI_HRX_RESERVED}
+};
+
+/*
+ * Table for hardware register saving on resets and port switches
+ */
+PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
+       /* SK_PNMI_HTX */
+       {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HTX_OCTETHIGH */
+       {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
+       /* SK_PNMI_HTX_OCTETLOW */
+       {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
+       /* SK_PNMI_HTX_BROADCAST */
+       {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
+       /* SK_PNMI_HTX_MULTICAST */
+       {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
+       /* SK_PNMI_HTX_UNICAST */
+       {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
+       /* SK_PNMI_HTX_BURST */
+       {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HTX_PMACC */
+       {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
+       /* SK_PNMI_HTX_MACC */
+       {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HTX_COL */
+       {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
+       /* SK_PNMI_HTX_SINGLE_COL */
+       {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
+       /* SK_PNMI_HTX_MULTI_COL */
+       {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
+       /* SK_PNMI_HTX_EXCESS_COL */
+       {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
+       /* SK_PNMI_HTX_LATE_COL */
+       {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
+       /* SK_PNMI_HTX_DEFFERAL */
+       {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HTX_EXCESS_DEF */
+       {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HTX_UNDERRUN */
+       {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
+       /* SK_PNMI_HTX_CARRIER */
+       {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HTX_UTILUNDER */
+       {{0, SK_FALSE}, {0, SK_FALSE}},
+       /* SK_PNMI_HTX_UTILOVER */
+       {{0, SK_FALSE}, {0, SK_FALSE}},
+       /* SK_PNMI_HTX_64 */
+       {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
+       /* SK_PNMI_HTX_127 */
+       {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
+       /* SK_PNMI_HTX_255 */
+       {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
+       /* SK_PNMI_HTX_511 */
+       {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
+       /* SK_PNMI_HTX_1023 */
+       {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
+       /* SK_PNMI_HTX_MAX */
+       {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
+       /* SK_PNMI_HTX_LONGFRAMES  */
+       {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
+       /* SK_PNMI_HTX_SYNC */
+       {{0, SK_FALSE}, {0, SK_FALSE}},
+       /* SK_PNMI_HTX_SYNC_OCTET */
+       {{0, SK_FALSE}, {0, SK_FALSE}},
+       /* SK_PNMI_HTX_RESERVED */
+       {{0, SK_FALSE}, {0, SK_FALSE}},
+       /* SK_PNMI_HRX */
+       {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HRX_OCTETHIGH */
+       {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
+       /* SK_PNMI_HRX_OCTETLOW */
+       {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
+       /* SK_PNMI_HRX_BADOCTETHIGH */
+       {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
+       /* SK_PNMI_HRX_BADOCTETLOW */
+       {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
+       /* SK_PNMI_HRX_BROADCAST */
+       {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
+       /* SK_PNMI_HRX_MULTICAST */
+       {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
+       /* SK_PNMI_HRX_UNICAST */
+       {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
+       /* SK_PNMI_HRX_PMACC */
+       {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
+       /* SK_PNMI_HRX_MACC */
+       {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HRX_PMACC_ERR */
+       {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HRX_MACC_UNKWN */
+       {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HRX_BURST */
+       {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HRX_MISSED */
+       {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HRX_FRAMING */
+       {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HRX_UNDERSIZE */
+       {{0, SK_FALSE},{GM_RXF_SHT, SK_TRUE}},
+       /* SK_PNMI_HRX_OVERFLOW */
+       {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
+       /* SK_PNMI_HRX_JABBER */
+       {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
+       /* SK_PNMI_HRX_CARRIER */
+       {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HRX_IRLENGTH */
+       {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HRX_SYMBOL */
+       {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HRX_SHORTS */
+       {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HRX_RUNT */
+       {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
+       /* SK_PNMI_HRX_TOO_LONG */
+       {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
+       /* SK_PNMI_HRX_FCS */
+       {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
+       /* SK_PNMI_HRX_CEXT */
+       {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
+       /* SK_PNMI_HRX_UTILUNDER */
+       {{0, SK_FALSE}, {0, SK_FALSE}},
+       /* SK_PNMI_HRX_UTILOVER */
+       {{0, SK_FALSE}, {0, SK_FALSE}},
+       /* SK_PNMI_HRX_64 */
+       {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
+       /* SK_PNMI_HRX_127 */
+       {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
+       /* SK_PNMI_HRX_255 */
+       {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
+       /* SK_PNMI_HRX_511 */
+       {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
+       /* SK_PNMI_HRX_1023 */
+       {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
+       /* SK_PNMI_HRX_MAX */
+       {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
+       /* SK_PNMI_HRX_LONGFRAMES */
+       {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
+       /* SK_PNMI_HRX_RESERVED */
+       {{0, SK_FALSE}, {0, SK_FALSE}}
+};
+
+
+/*****************************************************************************
+ *
+ * Public functions
+ *
+ */
+
+/*****************************************************************************
+ *
+ * SkPnmiInit - Init function of PNMI
+ *
+ * Description:
+ *     SK_INIT_DATA: Initialises the data structures
+ *     SK_INIT_IO:   Resets the XMAC statistics, determines the device and
+ *                   connector type.
+ *     SK_INIT_RUN:  Starts a timer event for port switch per hour
+ *                   calculation.
+ *
+ * Returns:
+ *     Always 0
+ */
+int SkPnmiInit(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int Level)             /* Initialization level */
+{
+       unsigned int    PortMax;        /* Number of ports */
+       unsigned int    PortIndex;      /* Current port index in loop */
+       SK_U16          Val16;          /* Multiple purpose 16 bit variable */
+       SK_U8           Val8;           /* Mulitple purpose 8 bit variable */
+       SK_EVPARA       EventParam;     /* Event struct for timer event */
+       SK_GEPORT       *pPrt;
+       SK_PNMI_VCT     *pVctBackupData;
+
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+               ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
+
+       switch (Level) {
+
+       case SK_INIT_DATA:
+               SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
+               pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
+               pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
+               pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
+               for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
+
+                       pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
+                       pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
+               }
+
+#ifdef SK_PNMI_CHECK
+               if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
+
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
+                                          ("CounterOffset struct size (%d) differs from"
+                                               "SK_PNMI_MAX_IDX (%d)\n",
+                                               SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
+                       BRK;
+               }
+
+               if (SK_PNMI_MAX_IDX !=
+                       (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
+
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
+                                          ("StatAddr table size (%d) differs from "
+                                               "SK_PNMI_MAX_IDX (%d)\n",
+                                               (sizeof(StatAddr) /
+                                                (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
+                                                SK_PNMI_MAX_IDX));
+                       BRK;
+               }
+#endif /* SK_PNMI_CHECK */
+               break;
+
+       case SK_INIT_IO:
+               /*
+                * Reset MAC counters
+                */
+               PortMax = pAC->GIni.GIMacsFound;
+
+               for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
+
+                       pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
+               }
+
+               /* Initialize DSP variables for Vct() to 0xff => Never written! */
+               for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
+                       pPrt = &pAC->GIni.GP[PortIndex];
+                       pPrt->PCableLen =0xff;
+                       pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
+                       pVctBackupData->PCableLen = 0xff;
+               }
+
+               /*
+                * Get pci bus speed
+                */
+               SK_IN16(IoC, B0_CTST, &Val16);
+               if ((Val16 & CS_BUS_CLOCK) == 0) {
+
+                       pAC->Pnmi.PciBusSpeed = 33;
+               }
+               else {
+                       pAC->Pnmi.PciBusSpeed = 66;
+               }
+
+               /*
+                * Get pci bus width
+                */
+               SK_IN16(IoC, B0_CTST, &Val16);
+               if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
+
+                       pAC->Pnmi.PciBusWidth = 32;
+               }
+               else {
+                       pAC->Pnmi.PciBusWidth = 64;
+               }
+
+               /*
+                * Get chipset
+                */
+               switch (pAC->GIni.GIChipId) {
+               case CHIP_ID_GENESIS:
+                       pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
+                       break;
+
+               case CHIP_ID_YUKON:
+                       pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
+                       break;
+
+               default:
+                       break;
+               }
+
+               /*
+                * Get PMD and DeviceType
+                */
+               SK_IN8(IoC, B2_PMD_TYP, &Val8);
+               switch (Val8) {
+               case 'S':
+                       pAC->Pnmi.PMD = 3;
+                       if (pAC->GIni.GIMacsFound > 1) {
+
+                               pAC->Pnmi.DeviceType = 0x00020002;
+                       }
+                       else {
+                               pAC->Pnmi.DeviceType = 0x00020001;
+                       }
+                       break;
+
+               case 'L':
+                       pAC->Pnmi.PMD = 2;
+                       if (pAC->GIni.GIMacsFound > 1) {
+
+                               pAC->Pnmi.DeviceType = 0x00020004;
+                       }
+                       else {
+                               pAC->Pnmi.DeviceType = 0x00020003;
+                       }
+                       break;
+
+               case 'C':
+                       pAC->Pnmi.PMD = 4;
+                       if (pAC->GIni.GIMacsFound > 1) {
+
+                               pAC->Pnmi.DeviceType = 0x00020006;
+                       }
+                       else {
+                               pAC->Pnmi.DeviceType = 0x00020005;
+                       }
+                       break;
+
+               case 'T':
+                       pAC->Pnmi.PMD = 5;
+                       if (pAC->GIni.GIMacsFound > 1) {
+
+                               pAC->Pnmi.DeviceType = 0x00020008;
+                       }
+                       else {
+                               pAC->Pnmi.DeviceType = 0x00020007;
+                       }
+                       break;
+
+               default :
+                       pAC->Pnmi.PMD = 1;
+                       pAC->Pnmi.DeviceType = 0;
+                       break;
+               }
+
+               /*
+                * Get connector
+                */
+               SK_IN8(IoC, B2_CONN_TYP, &Val8);
+               switch (Val8) {
+               case 'C':
+                       pAC->Pnmi.Connector = 2;
+                       break;
+
+               case 'D':
+                       pAC->Pnmi.Connector = 3;
+                       break;
+
+               case 'F':
+                       pAC->Pnmi.Connector = 4;
+                       break;
+
+               case 'J':
+                       pAC->Pnmi.Connector = 5;
+                       break;
+
+               case 'V':
+                       pAC->Pnmi.Connector = 6;
+                       break;
+
+               default:
+                       pAC->Pnmi.Connector = 1;
+                       break;
+               }
+               break;
+
+       case SK_INIT_RUN:
+               /*
+                * Start timer for RLMT change counter
+                */
+               SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
+               SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
+                       28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
+                       EventParam);
+               break;
+
+       default:
+               break; /* Nothing todo */
+       }
+
+       return (0);
+}
+
+/*****************************************************************************
+ *
+ * SkPnmiGetVar - Retrieves the value of a single OID
+ *
+ * Description:
+ *     Calls a general sub-function for all this stuff. If the instance
+ *     -1 is passed, the values of all instances are returned in an
+ *     array of values.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
+ *                              the data.
+ *     SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter.
+ */
+int SkPnmiGetVar(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+SK_U32 Id,             /* Object ID that is to be processed */
+void *pBuf,            /* Buffer to which to mgmt data will be retrieved */
+unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
+SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+               ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
+                       Id, *pLen, Instance, NetIndex));
+
+       return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
+               Instance, NetIndex));
+}
+
+/*****************************************************************************
+ *
+ * SkPnmiPreSetVar - Presets the value of a single OID
+ *
+ * Description:
+ *     Calls a general sub-function for all this stuff. The preset does
+ *     the same as a set, but returns just before finally setting the
+ *     new value. This is usefull to check if a set might be successfull.
+ *     If as instance a -1 is passed, an array of values is supposed and
+ *     all instance of the OID will be set.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
+ *                              value range.
+ *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
+ *     SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown.
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter.
+ */
+int SkPnmiPreSetVar(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+SK_U32 Id,             /* Object ID that is to be processed */
+void *pBuf,            /* Buffer which stores the mgmt data to be set */
+unsigned int *pLen,    /* Total length of mgmt data */
+SK_U32 Instance,       /* Instance (1..n) that is to be set or -1 */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+               ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
+                       Id, *pLen, Instance, NetIndex));
+
+
+       return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
+               Instance, NetIndex));
+}
+
+/*****************************************************************************
+ *
+ * SkPnmiSetVar - Sets the value of a single OID
+ *
+ * Description:
+ *     Calls a general sub-function for all this stuff. The preset does
+ *     the same as a set, but returns just before finally setting the
+ *     new value. This is usefull to check if a set might be successfull.
+ *     If as instance a -1 is passed, an array of values is supposed and
+ *     all instance of the OID will be set.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
+ *                              value range.
+ *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
+ *     SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown.
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter.
+ */
+int SkPnmiSetVar(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+SK_U32 Id,             /* Object ID that is to be processed */
+void *pBuf,            /* Buffer which stores the mgmt data to be set */
+unsigned int *pLen,    /* Total length of mgmt data */
+SK_U32 Instance,       /* Instance (1..n) that is to be set or -1 */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+               ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
+                       Id, *pLen, Instance, NetIndex));
+
+       return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
+               Instance, NetIndex));
+}
+
+/*****************************************************************************
+ *
+ * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
+ *
+ * Description:
+ *     Runs through the IdTable, queries the single OIDs and stores the
+ *     returned data into the management database structure
+ *     SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
+ *     is stored in the IdTable. The return value of the function will also
+ *     be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
+ *     minimum size of SK_PNMI_MIN_STRUCT_SIZE.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
+ *                              the data.
+ *     SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
+ */
+int SkPnmiGetStruct(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+void *pBuf,            /* Buffer which will store the retrieved data */
+unsigned int *pLen,    /* Length of buffer */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       int             Ret;
+       unsigned int    TableIndex;
+       unsigned int    DstOffset;
+       unsigned int    InstanceNo;
+       unsigned int    InstanceCnt;
+       SK_U32          Instance;
+       unsigned int    TmpLen;
+       char            KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
+
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+               ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
+                       *pLen, NetIndex));
+
+       if (*pLen < SK_PNMI_STRUCT_SIZE) {
+
+               if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
+
+                       SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
+                               (SK_U32)(-1));
+               }
+
+               *pLen = SK_PNMI_STRUCT_SIZE;
+               return (SK_PNMI_ERR_TOO_SHORT);
+       }
+
+    /*
+     * Check NetIndex
+     */
+       if (NetIndex >= pAC->Rlmt.NumNets) {
+               return (SK_PNMI_ERR_UNKNOWN_NET);
+       }
+
+       /* Update statistic */
+       SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
+
+       if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
+               SK_PNMI_ERR_OK) {
+
+               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
+               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
+               return (Ret);
+       }
+
+       if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
+
+               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
+               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
+               return (Ret);
+       }
+
+       if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
+
+               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
+               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
+               return (Ret);
+       }
+
+       /*
+        * Increment semaphores to indicate that an update was
+        * already done
+        */
+       pAC->Pnmi.MacUpdatedFlag ++;
+       pAC->Pnmi.RlmtUpdatedFlag ++;
+       pAC->Pnmi.SirqUpdatedFlag ++;
+
+       /* Get vpd keys for instance calculation */
+       Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
+       if (Ret != SK_PNMI_ERR_OK) {
+
+               pAC->Pnmi.MacUpdatedFlag --;
+               pAC->Pnmi.RlmtUpdatedFlag --;
+               pAC->Pnmi.SirqUpdatedFlag --;
+
+               SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
+               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
+               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
+               return (SK_PNMI_ERR_GENERAL);
+       }
+
+       /* Retrieve values */
+       SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
+       for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
+
+               InstanceNo = IdTable[TableIndex].InstanceNo;
+               for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
+                       InstanceCnt ++) {
+
+                       DstOffset = IdTable[TableIndex].Offset +
+                               (InstanceCnt - 1) *
+                               IdTable[TableIndex].StructSize;
+
+                       /*
+                        * For the VPD the instance is not an index number
+                        * but the key itself. Determin with the instance
+                        * counter the VPD key to be used.
+                        */
+                       if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
+                               IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
+                               IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
+                               IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
+
+                               SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
+                       }
+                       else {
+                               Instance = (SK_U32)InstanceCnt;
+                       }
+
+                       TmpLen = *pLen - DstOffset;
+                       Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
+                               IdTable[TableIndex].Id, (char *)pBuf +
+                               DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
+
+                       /*
+                        * An unknown instance error means that we reached
+                        * the last instance of that variable. Proceed with
+                        * the next OID in the table and ignore the return
+                        * code.
+                        */
+                       if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
+
+               break;
+                       }
+
+                       if (Ret != SK_PNMI_ERR_OK) {
+
+                               pAC->Pnmi.MacUpdatedFlag --;
+                               pAC->Pnmi.RlmtUpdatedFlag --;
+                               pAC->Pnmi.SirqUpdatedFlag --;
+
+                               SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
+                               SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
+                               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
+                               return (Ret);
+                       }
+               }
+       }
+
+       pAC->Pnmi.MacUpdatedFlag --;
+       pAC->Pnmi.RlmtUpdatedFlag --;
+       pAC->Pnmi.SirqUpdatedFlag --;
+
+       *pLen = SK_PNMI_STRUCT_SIZE;
+       SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
+       SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
+ *
+ * Description:
+ *     Calls a general sub-function for all this set stuff. The preset does
+ *     the same as a set, but returns just before finally setting the
+ *     new value. This is usefull to check if a set might be successfull.
+ *     The sub-function runs through the IdTable, checks which OIDs are able
+ *     to set, and calls the handler function of the OID to perform the
+ *     preset. The return value of the function will also be stored in
+ *     SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
+ *     SK_PNMI_MIN_STRUCT_SIZE.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
+ *                              value range.
+ */
+int SkPnmiPreSetStruct(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+void *pBuf,            /* Buffer which contains the data to be set */
+unsigned int *pLen,    /* Length of buffer */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+               ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
+                       *pLen, NetIndex));
+
+       return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
+                                       pLen, NetIndex));
+}
+
+/*****************************************************************************
+ *
+ * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
+ *
+ * Description:
+ *     Calls a general sub-function for all this set stuff. The return value
+ *     of the function will also be stored in SK_PNMI_STRUCT_DATA if the
+ *     passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
+ *     The sub-function runs through the IdTable, checks which OIDs are able
+ *     to set, and calls the handler function of the OID to perform the
+ *     set. The return value of the function will also be stored in
+ *     SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
+ *     SK_PNMI_MIN_STRUCT_SIZE.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
+ *                              value range.
+ */
+int SkPnmiSetStruct(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+void *pBuf,            /* Buffer which contains the data to be set */
+unsigned int *pLen,    /* Length of buffer */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+               ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
+                       *pLen, NetIndex));
+
+       return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
+                                       pLen, NetIndex));
+}
+
+/*****************************************************************************
+ *
+ * SkPnmiEvent - Event handler
+ *
+ * Description:
+ *     Handles the following events:
+ *     SK_PNMI_EVT_SIRQ_OVERFLOW     When a hardware counter overflows an
+ *                                   interrupt will be generated which is
+ *                                   first handled by SIRQ which generates a
+ *                                   this event. The event increments the
+ *                                   upper 32 bit of the 64 bit counter.
+ *     SK_PNMI_EVT_SEN_XXX           The event is generated by the I2C module
+ *                                   when a sensor reports a warning or
+ *                                   error. The event will store a trap
+ *                                   message in the trap buffer.
+ *     SK_PNMI_EVT_CHG_EST_TIMER     The timer event was initiated by this
+ *                                   module and is used to calculate the
+ *                                   port switches per hour.
+ *     SK_PNMI_EVT_CLEAR_COUNTER     The event clears all counters and
+ *                                   timestamps.
+ *     SK_PNMI_EVT_XMAC_RESET        The event is generated by the driver
+ *                                   before a hard reset of the XMAC is
+ *                                   performed. All counters will be saved
+ *                                   and added to the hardware counter
+ *                                   values after reset to grant continuous
+ *                                   counter values.
+ *     SK_PNMI_EVT_RLMT_PORT_UP      Generated by RLMT to notify that a port
+ *                                   went logically up. A trap message will
+ *                                   be stored to the trap buffer.
+ *     SK_PNMI_EVT_RLMT_PORT_DOWN    Generated by RLMT to notify that a port
+ *                                   went logically down. A trap message will
+ *                                   be stored to the trap buffer.
+ *     SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
+ *                                   spanning tree root bridges were
+ *                                   detected. A trap message will be stored
+ *                                   to the trap buffer.
+ *     SK_PNMI_EVT_RLMT_ACTIVE_DOWN  Notifies PNMI that an active port went
+ *                                   down. PNMI will not further add the
+ *                                   statistic values to the virtual port.
+ *     SK_PNMI_EVT_RLMT_ACTIVE_UP    Notifies PNMI that a port went up and
+ *                                   is now an active port. PNMI will now
+ *                                   add the statistic data of this port to
+ *                                   the virtual port.
+ *     SK_PNMI_EVT_RLMT_SET_NETS     Notifies PNMI about the net mode. The first Parameter
+ *                                   contains the number of nets. 1 means single net, 2 means
+ *                                   dual net. The second Parameter is -1
+ *
+ * Returns:
+ *     Always 0
+ */
+int SkPnmiEvent(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+SK_U32 Event,          /* Event-Id */
+SK_EVPARA Param)       /* Event dependent parameter */
+{
+       unsigned int    PhysPortIndex;
+       unsigned int    MaxNetNumber;
+       int                     CounterIndex;
+       int                     Ret;
+       SK_U16          MacStatus;
+       SK_U64          OverflowStatus;
+       SK_U64          Mask;
+       int                     MacType;
+       SK_U64          Value;
+       SK_U32          Val32;
+       SK_U16          Register;
+       SK_EVPARA       EventParam;
+       SK_U64          NewestValue;
+       SK_U64          OldestValue;
+       SK_U64          Delta;
+       SK_PNMI_ESTIMATE *pEst;
+       SK_U32          NetIndex;
+       SK_GEPORT       *pPrt;
+       SK_PNMI_VCT     *pVctBackupData;
+       SK_U32          RetCode;
+       int             i;
+       SK_U32          CableLength;
+
+
+#ifdef DEBUG
+       if (Event != SK_PNMI_EVT_XMAC_RESET) {
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+                       ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
+                       (unsigned int)Event, (unsigned int)Param.Para64));
+       }
+#endif
+       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
+
+       MacType = pAC->GIni.GIMacType;
+
+       switch (Event) {
+
+       case SK_PNMI_EVT_SIRQ_OVERFLOW:
+               PhysPortIndex = (int)Param.Para32[0];
+               MacStatus = (SK_U16)Param.Para32[1];
+#ifdef DEBUG
+               if (PhysPortIndex >= SK_MAX_MACS) {
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
+                                " wrong, PhysPortIndex=0x%x\n",
+                               PhysPortIndex));
+                       return (0);
+               }
+#endif
+               OverflowStatus = 0;
+
+               /*
+                * Check which source caused an overflow interrupt.
+                */
+               if ((pAC->GIni.GIFunc.pFnMacOverflow(
+                        pAC, IoC, PhysPortIndex, MacStatus, &OverflowStatus) != 0) ||
+                       (OverflowStatus == 0)) {
+
+                       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
+                       return (0);
+               }
+
+               /*
+                * Check the overflow status register and increment
+                * the upper dword of corresponding counter.
+                */
+               for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
+                       CounterIndex ++) {
+
+                       Mask = (SK_U64)1 << CounterIndex;
+                       if ((OverflowStatus & Mask) == 0) {
+
+                               continue;
+                       }
+
+                       switch (StatOvrflwBit[CounterIndex][MacType]) {
+
+                       case SK_PNMI_HTX_UTILUNDER:
+                       case SK_PNMI_HTX_UTILOVER:
+                               XM_IN16(IoC, PhysPortIndex, XM_TX_CMD,
+                                       &Register);
+                               Register |= XM_TX_SAM_LINE;
+                               XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD,
+                                       Register);
+                               break;
+
+                       case SK_PNMI_HRX_UTILUNDER:
+                       case SK_PNMI_HRX_UTILOVER:
+                               XM_IN16(IoC, PhysPortIndex, XM_RX_CMD,
+                                       &Register);
+                               Register |= XM_RX_SAM_LINE;
+                               XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD,
+                                       Register);
+                               break;
+
+                       case SK_PNMI_HTX_OCTETHIGH:
+                       case SK_PNMI_HTX_OCTETLOW:
+                       case SK_PNMI_HTX_RESERVED:
+                       case SK_PNMI_HRX_OCTETHIGH:
+                       case SK_PNMI_HRX_OCTETLOW:
+                       case SK_PNMI_HRX_IRLENGTH:
+                       case SK_PNMI_HRX_RESERVED:
+
+                       /*
+                        * the following counters aren't be handled (id > 63)
+                        */
+                       case SK_PNMI_HTX_SYNC:
+                       case SK_PNMI_HTX_SYNC_OCTET:
+                               break;
+
+                       case SK_PNMI_HRX_LONGFRAMES:
+                               if (MacType == SK_MAC_GMAC) {
+                                       pAC->Pnmi.Port[PhysPortIndex].
+                                               CounterHigh[CounterIndex] ++;
+                               }
+                               break;
+
+                       default:
+                               pAC->Pnmi.Port[PhysPortIndex].
+                                       CounterHigh[CounterIndex] ++;
+                       }
+               }
+               break;
+
+       case SK_PNMI_EVT_SEN_WAR_LOW:
+#ifdef DEBUG
+               if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
+                               (unsigned int)Param.Para64));
+                       return (0);
+               }
+#endif
+               /*
+                * Store a trap message in the trap buffer and generate
+                * an event for user space applications with the
+                * SK_DRIVER_SENDEVENT macro.
+                */
+               QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
+                       (unsigned int)Param.Para64);
+               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
+               break;
+
+       case SK_PNMI_EVT_SEN_WAR_UPP:
+#ifdef DEBUG
+               if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+                               ("PNMI: ERR:SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
+                               (unsigned int)Param.Para64));
+                       return (0);
+               }
+#endif
+               /*
+                * Store a trap message in the trap buffer and generate
+                * an event for user space applications with the
+                * SK_DRIVER_SENDEVENT macro.
+                */
+               QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
+                       (unsigned int)Param.Para64);
+               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
+               break;
+
+       case SK_PNMI_EVT_SEN_ERR_LOW:
+#ifdef DEBUG
+               if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
+                               (unsigned int)Param.Para64));
+                       return (0);
+               }
+#endif
+               /*
+                * Store a trap message in the trap buffer and generate
+                * an event for user space applications with the
+                * SK_DRIVER_SENDEVENT macro.
+                */
+               QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
+                       (unsigned int)Param.Para64);
+               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
+               break;
+
+       case SK_PNMI_EVT_SEN_ERR_UPP:
+#ifdef DEBUG
+               if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
+                               (unsigned int)Param.Para64));
+                       return (0);
+               }
+#endif
+               /*
+                * Store a trap message in the trap buffer and generate
+                * an event for user space applications with the
+                * SK_DRIVER_SENDEVENT macro.
+                */
+               QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
+                       (unsigned int)Param.Para64);
+               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
+               break;
+
+       case SK_PNMI_EVT_CHG_EST_TIMER:
+               /*
+                * Calculate port switch average on a per hour basis
+                *   Time interval for check       : 28125 ms
+                *   Number of values for average  : 8
+                *
+                * Be careful in changing these values, on change check
+                *   - typedef of SK_PNMI_ESTIMATE (Size of EstValue
+                *     array one less than value number)
+                *   - Timer initilization SkTimerStart() in SkPnmiInit
+                *   - Delta value below must be multiplicated with
+                *     power of 2
+                *
+                */
+               pEst = &pAC->Pnmi.RlmtChangeEstimate;
+               CounterIndex = pEst->EstValueIndex + 1;
+               if (CounterIndex == 7) {
+
+                       CounterIndex = 0;
+               }
+               pEst->EstValueIndex = CounterIndex;
+
+               NewestValue = pAC->Pnmi.RlmtChangeCts;
+               OldestValue = pEst->EstValue[CounterIndex];
+               pEst->EstValue[CounterIndex] = NewestValue;
+
+               /*
+                * Calculate average. Delta stores the number of
+                * port switches per 28125 * 8 = 225000 ms
+                */
+               if (NewestValue >= OldestValue) {
+
+                       Delta = NewestValue - OldestValue;
+               }
+               else {
+                       /* Overflow situation */
+                       Delta = (SK_U64)(0 - OldestValue) + NewestValue;
+               }
+
+               /*
+                * Extrapolate delta to port switches per hour.
+                *     Estimate = Delta * (3600000 / 225000)
+                *              = Delta * 16
+                *              = Delta << 4
+                */
+               pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
+
+               /*
+                * Check if threshold is exceeded. If the threshold is
+                * permanently exceeded every 28125 ms an event will be
+                * generated to remind the user of this condition.
+                */
+               if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
+                       (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
+                       pAC->Pnmi.RlmtChangeThreshold)) {
+
+                       QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
+                       (void)SK_DRIVER_SENDEVENT(pAC, IoC);
+               }
+
+               SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
+               SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
+                       28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
+                       EventParam);
+               break;
+
+       case SK_PNMI_EVT_CLEAR_COUNTER:
+               /*
+                *  Param.Para32[0] contains the NetIndex (0 ..1).
+                *  Param.Para32[1] is reserved, contains -1.
+                */
+               NetIndex = (SK_U32)Param.Para32[0];
+
+#ifdef DEBUG
+               if (NetIndex >= pAC->Rlmt.NumNets) {
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
+                               NetIndex));
+
+                       return (0);
+               }
+#endif
+
+               /*
+                * Set all counters and timestamps to zero
+                */
+               ResetCounter(pAC, IoC, NetIndex); /* the according NetIndex is required
+                                                                                               as a Parameter of the Event */
+               break;
+
+       case SK_PNMI_EVT_XMAC_RESET:
+               /*
+                * To grant continuous counter values store the current
+                * XMAC statistic values to the entries 1..n of the
+                * CounterOffset array. XMAC Errata #2
+                */
+#ifdef DEBUG
+               if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
+                               (unsigned int)Param.Para64));
+                       return (0);
+               }
+#endif
+               PhysPortIndex = (unsigned int)Param.Para64;
+
+               /*
+                * Update XMAC statistic to get fresh values
+                */
+               Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
+               if (Ret != SK_PNMI_ERR_OK) {
+
+                       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
+                       return (0);
+               }
+               /*
+                * Increment semaphore to indicate that an update was
+                * already done
+                */
+               pAC->Pnmi.MacUpdatedFlag ++;
+
+               for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
+                       CounterIndex ++) {
+
+                       if (!StatAddr[CounterIndex][MacType].GetOffset) {
+
+                               continue;
+                       }
+
+                       pAC->Pnmi.Port[PhysPortIndex].
+                               CounterOffset[CounterIndex] = GetPhysStatVal(
+                               pAC, IoC, PhysPortIndex, CounterIndex);
+                       pAC->Pnmi.Port[PhysPortIndex].
+                               CounterHigh[CounterIndex] = 0;
+               }
+
+               pAC->Pnmi.MacUpdatedFlag --;
+               break;
+
+       case SK_PNMI_EVT_RLMT_PORT_UP:
+               PhysPortIndex = (unsigned int)Param.Para32[0];
+#ifdef DEBUG
+               if (PhysPortIndex >= SK_MAX_MACS) {
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
+                " wrong, PhysPortIndex=%d\n", PhysPortIndex));
+
+                       return (0);
+               }
+#endif
+               /*
+                * Store a trap message in the trap buffer and generate an event for
+                * user space applications with the SK_DRIVER_SENDEVENT macro.
+                */
+               QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
+               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
+
+               /* Bugfix for XMAC errata (#10620)*/
+               if (pAC->GIni.GIMacType == SK_MAC_XMAC){
+
+                       /* Add incremental difference to offset (#10620)*/
+                       (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                               XM_RXE_SHT_ERR, &Val32);
+
+                       Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
+                                CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
+                       pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
+                               Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
+               }
+
+               /* Tell VctStatus() that a link was up meanwhile. */
+               pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
+               break;
+
+    case SK_PNMI_EVT_RLMT_PORT_DOWN:
+               PhysPortIndex = (unsigned int)Param.Para32[0];
+
+#ifdef DEBUG
+               if (PhysPortIndex >= SK_MAX_MACS) {
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
+                " wrong, PhysPortIndex=%d\n", PhysPortIndex));
+
+                       return (0);
+               }
+#endif
+               /*
+                * Store a trap message in the trap buffer and generate an event for
+                * user space applications with the SK_DRIVER_SENDEVENT macro.
+                */
+               QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
+               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
+
+               /* Bugfix #10620 - get zero level for incremental difference */
+               if ((pAC->GIni.GIMacType == SK_MAC_XMAC)) {
+
+                       (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                               XM_RXE_SHT_ERR, &Val32);
+                       pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
+                               (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
+                                CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
+               }
+               break;
+
+       case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
+               PhysPortIndex = (unsigned int)Param.Para32[0];
+               NetIndex = (SK_U32)Param.Para32[1];
+
+#ifdef DEBUG
+               if (PhysPortIndex >= SK_MAX_MACS) {
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
+                               PhysPortIndex));
+               }
+
+               if (NetIndex >= pAC->Rlmt.NumNets) {
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
+                               NetIndex));
+               }
+#endif
+               /*
+                * For now, ignore event if NetIndex != 0.
+                */
+               if (Param.Para32[1] != 0) {
+
+                       return (0);
+               }
+
+               /*
+                * Nothing to do if port is already inactive
+                */
+               if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
+
+                       return (0);
+               }
+
+               /*
+                * Update statistic counters to calculate new offset for the virtual
+                * port and increment semaphore to indicate that an update was already
+                * done.
+                */
+               if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
+                       SK_PNMI_ERR_OK) {
+
+                       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
+                       return (0);
+               }
+               pAC->Pnmi.MacUpdatedFlag ++;
+
+               /*
+                * Calculate new counter offset for virtual port to grant continous
+                * counting on port switches. The virtual port consists of all currently
+                * active ports. The port down event indicates that a port is removed
+                * from the virtual port. Therefore add the counter value of the removed
+                * port to the CounterOffset for the virtual port to grant the same
+                * counter value.
+                */
+               for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
+                       CounterIndex ++) {
+
+                       if (!StatAddr[CounterIndex][MacType].GetOffset) {
+
+                               continue;
+                       }
+
+                       Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
+
+                       pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
+               }
+
+               /*
+                * Set port to inactive
+                */
+               pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
+
+               pAC->Pnmi.MacUpdatedFlag --;
+               break;
+
+       case SK_PNMI_EVT_RLMT_ACTIVE_UP:
+               PhysPortIndex = (unsigned int)Param.Para32[0];
+               NetIndex = (SK_U32)Param.Para32[1];
+
+#ifdef DEBUG
+               if (PhysPortIndex >= SK_MAX_MACS) {
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
+                               PhysPortIndex));
+               }
+
+               if (NetIndex >= pAC->Rlmt.NumNets) {
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
+                               NetIndex));
+               }
+#endif
+               /*
+                * For now, ignore event if NetIndex != 0.
+                */
+               if (Param.Para32[1] != 0) {
+
+                       return (0);
+               }
+
+               /*
+                * Nothing to do if port is already active
+                */
+               if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
+
+                       return (0);
+               }
+
+               /*
+                * Statistic maintenance
+                */
+               pAC->Pnmi.RlmtChangeCts ++;
+               pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
+
+               /*
+                * Store a trap message in the trap buffer and generate an event for
+                * user space applications with the SK_DRIVER_SENDEVENT macro.
+                */
+               QueueRlmtNewMacTrap(pAC, PhysPortIndex);
+               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
+
+               /*
+                * Update statistic counters to calculate new offset for the virtual
+                * port and increment semaphore to indicate that an update was
+                * already done.
+                */
+               if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
+                       SK_PNMI_ERR_OK) {
+
+                       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
+                       return (0);
+               }
+               pAC->Pnmi.MacUpdatedFlag ++;
+
+               /*
+                * Calculate new counter offset for virtual port to grant continous
+                * counting on port switches. A new port is added to the virtual port.
+                * Therefore substract the counter value of the new port from the
+                * CounterOffset for the virtual port to grant the same value.
+                */
+               for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
+                       CounterIndex ++) {
+
+                       if (!StatAddr[CounterIndex][MacType].GetOffset) {
+
+                               continue;
+                       }
+
+                       Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
+
+                       pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
+               }
+
+               /*
+                * Set port to active
+                */
+               pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
+
+               pAC->Pnmi.MacUpdatedFlag --;
+               break;
+
+       case SK_PNMI_EVT_RLMT_SEGMENTATION:
+               /*
+                * Para.Para32[0] contains the NetIndex.
+                */
+
+               /*
+                * Store a trap message in the trap buffer and generate an event for
+                * user space applications with the SK_DRIVER_SENDEVENT macro.
+                */
+               QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
+               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
+               break;
+
+    case SK_PNMI_EVT_RLMT_SET_NETS:
+               /*
+                *  Param.Para32[0] contains the number of Nets.
+                *  Param.Para32[1] is reserved, contains -1.
+                */
+           /*
+        * Check number of nets
+                */
+               MaxNetNumber = pAC->GIni.GIMacsFound;
+               if (((unsigned int)Param.Para32[0] < 1)
+                       || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
+                       return (SK_PNMI_ERR_UNKNOWN_NET);
+               }
+
+       if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
+               pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
+       }
+       else { /* dual net mode */
+               pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
+       }
+       break;
+
+    case SK_PNMI_EVT_VCT_RESET:
+       PhysPortIndex = Param.Para32[0];
+       pPrt = &pAC->GIni.GP[PhysPortIndex];
+       pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
+
+       if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
+               RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
+               if (RetCode == 2) {
+                       /*
+                        * VCT test is still running.
+                        * Start VCT timer counter again.
+                        */
+                       SK_MEMSET((char *) &Param, 0, sizeof(Param));
+                       Param.Para32[0] = PhysPortIndex;
+                       Param.Para32[1] = -1;
+                       SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
+                               4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
+                       break;
+               }
+               pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
+               pAC->Pnmi.VctStatus[PhysPortIndex] |=
+                       (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
+
+               /* Copy results for later use to PNMI struct. */
+               for (i = 0; i < 4; i++)  {
+                       if (pPrt->PMdiPairLen[i] > 35) {
+                               CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
+                       }
+                       else {
+                               CableLength = 0;
+                       }
+                       pVctBackupData->PMdiPairLen[i] = CableLength;
+                       pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
+               }
+
+               Param.Para32[0] = PhysPortIndex;
+               Param.Para32[1] = -1;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
+               SkEventDispatcher(pAC, IoC);
+       }
+
+       break;
+
+       default:
+               break;
+       }
+
+       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
+       return (0);
+}
+
+
+/******************************************************************************
+ *
+ * Private functions
+ *
+ */
+
+/*****************************************************************************
+ *
+ * PnmiVar - Gets, presets, and sets single OIDs
+ *
+ * Description:
+ *     Looks up the requested OID, calls the corresponding handler
+ *     function, and passes the parameters with the get, preset, or
+ *     set command. The function is called by SkGePnmiGetVar,
+ *     SkGePnmiPreSetVar, or SkGePnmiSetVar.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_XXX. For details have a look to the description of the
+ *     calling functions.
+ *     SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
+ */
+PNMI_STATIC int PnmiVar(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int Action,            /* Get/PreSet/Set action */
+SK_U32 Id,             /* Object ID that is to be processed */
+char *pBuf,            /* Buffer which stores the mgmt data to be set */
+unsigned int *pLen,    /* Total length of mgmt data */
+SK_U32 Instance,       /* Instance (1..n) that is to be set or -1 */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       unsigned int    TableIndex;
+       int             Ret;
+
+
+       if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_UNKNOWN_OID);
+       }
+
+    /*
+     * Check NetIndex
+     */
+       if (NetIndex >= pAC->Rlmt.NumNets) {
+               return (SK_PNMI_ERR_UNKNOWN_NET);
+       }
+
+       SK_PNMI_CHECKFLAGS("PnmiVar: On call");
+
+       Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
+               Instance, TableIndex, NetIndex);
+
+       SK_PNMI_CHECKFLAGS("PnmiVar: On return");
+
+       return (Ret);
+}
+
+/*****************************************************************************
+ *
+ * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
+ *
+ * Description:
+ *     The return value of the function will also be stored in
+ *     SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
+ *     SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
+ *     checks which OIDs are able to set, and calls the handler function of
+ *     the OID to perform the set. The return value of the function will
+ *     also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
+ *     minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
+ *     by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_XXX. The codes are described in the calling functions.
+ *     SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
+ */
+PNMI_STATIC int PnmiStruct(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int  Action,           /* Set action to be performed */
+char *pBuf,            /* Buffer which contains the data to be set */
+unsigned int *pLen,    /* Length of buffer */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       int             Ret;
+       unsigned int    TableIndex;
+       unsigned int    DstOffset;
+       unsigned int    Len;
+       unsigned int    InstanceNo;
+       unsigned int    InstanceCnt;
+       SK_U32          Instance;
+       SK_U32          Id;
+
+
+       /* Check if the passed buffer has the right size */
+       if (*pLen < SK_PNMI_STRUCT_SIZE) {
+
+               /* Check if we can return the error within the buffer */
+               if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
+
+                       SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
+                               (SK_U32)(-1));
+               }
+
+               *pLen = SK_PNMI_STRUCT_SIZE;
+               return (SK_PNMI_ERR_TOO_SHORT);
+       }
+
+    /*
+     * Check NetIndex
+     */
+       if (NetIndex >= pAC->Rlmt.NumNets) {
+               return (SK_PNMI_ERR_UNKNOWN_NET);
+       }
+
+       SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
+
+       /*
+        * Update the values of RLMT and SIRQ and increment semaphores to
+        * indicate that an update was already done.
+        */
+       if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
+
+               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
+               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
+               return (Ret);
+       }
+
+       if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
+
+               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
+               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
+               return (Ret);
+       }
+
+       pAC->Pnmi.RlmtUpdatedFlag ++;
+       pAC->Pnmi.SirqUpdatedFlag ++;
+
+       /* Preset/Set values */
+       for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
+
+               if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
+                       (IdTable[TableIndex].Access != SK_PNMI_WO)) {
+
+                       continue;
+               }
+
+               InstanceNo = IdTable[TableIndex].InstanceNo;
+               Id = IdTable[TableIndex].Id;
+
+               for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
+                       InstanceCnt ++) {
+
+                       DstOffset = IdTable[TableIndex].Offset +
+                               (InstanceCnt - 1) *
+                               IdTable[TableIndex].StructSize;
+
+                       /*
+                        * Because VPD multiple instance variables are
+                        * not setable we do not need to evaluate VPD
+                        * instances. Have a look to VPD instance
+                        * calculation in SkPnmiGetStruct().
+                        */
+                       Instance = (SK_U32)InstanceCnt;
+
+                       /*
+                        * Evaluate needed buffer length
+                        */
+                       Len = 0;
+                       Ret = IdTable[TableIndex].Func(pAC, IoC,
+                               SK_PNMI_GET, IdTable[TableIndex].Id,
+                               NULL, &Len, Instance, TableIndex, NetIndex);
+
+                       if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
+
+                               break;
+                       }
+                       if (Ret != SK_PNMI_ERR_TOO_SHORT) {
+
+                               pAC->Pnmi.RlmtUpdatedFlag --;
+                               pAC->Pnmi.SirqUpdatedFlag --;
+
+                               SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
+                               SK_PNMI_SET_STAT(pBuf,
+                                       SK_PNMI_ERR_GENERAL, DstOffset);
+                               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
+                               return (SK_PNMI_ERR_GENERAL);
+                       }
+                       if (Id == OID_SKGE_VPD_ACTION) {
+
+                               switch (*(pBuf + DstOffset)) {
+
+                               case SK_PNMI_VPD_CREATE:
+                                       Len = 3 + *(pBuf + DstOffset + 3);
+                                       break;
+
+                               case SK_PNMI_VPD_DELETE:
+                                       Len = 3;
+                                       break;
+
+                               default:
+                                       Len = 1;
+                                       break;
+                               }
+                       }
+
+                       /* Call the OID handler function */
+                       Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
+                               IdTable[TableIndex].Id, pBuf + DstOffset,
+                               &Len, Instance, TableIndex, NetIndex);
+
+                       if (Ret != SK_PNMI_ERR_OK) {
+
+                               pAC->Pnmi.RlmtUpdatedFlag --;
+                               pAC->Pnmi.SirqUpdatedFlag --;
+
+                               SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
+                               SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
+                                       DstOffset);
+                               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+               }
+       }
+
+       pAC->Pnmi.RlmtUpdatedFlag --;
+       pAC->Pnmi.SirqUpdatedFlag --;
+
+       SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
+       SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * LookupId - Lookup an OID in the IdTable
+ *
+ * Description:
+ *     Scans the IdTable to find the table entry of an OID.
+ *
+ * Returns:
+ *     The table index or -1 if not found.
+ */
+PNMI_STATIC int LookupId(
+SK_U32 Id)             /* Object identifier to be searched */
+{
+       int i;
+
+       for (i = 0; i < ID_TABLE_SIZE; i++) {
+
+               if (IdTable[i].Id == Id) {
+
+                       return i;
+               }
+       }
+
+       return (-1);
+}
+
+/*****************************************************************************
+ *
+ * OidStruct - Handler of OID_SKGE_ALL_DATA
+ *
+ * Description:
+ *     This OID performs a Get/Preset/SetStruct call and returns all data
+ *     in a SK_PNMI_STRUCT_DATA structure.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
+ *                              value range.
+ *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter.
+ */
+PNMI_STATIC int OidStruct(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int Action,            /* Get/PreSet/Set action */
+SK_U32 Id,             /* Object ID that is to be processed */
+char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
+unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
+SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       if (Id != OID_SKGE_ALL_DATA) {
+
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
+                       SK_PNMI_ERR003MSG);
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_GENERAL);
+       }
+
+       /*
+        * Check instance. We only handle single instance variables
+        */
+       if (Instance != (SK_U32)(-1) && Instance != 1) {
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_UNKNOWN_INST);
+       }
+
+       switch (Action) {
+
+       case SK_PNMI_GET:
+               return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
+
+       case SK_PNMI_PRESET:
+               return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
+
+       case SK_PNMI_SET:
+               return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
+       }
+
+       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
+
+       *pLen = 0;
+       return (SK_PNMI_ERR_GENERAL);
+}
+
+/*****************************************************************************
+ *
+ * Perform - OID handler of OID_SKGE_ACTION
+ *
+ * Description:
+ *     None.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
+ *                              value range.
+ *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter.
+ */
+PNMI_STATIC int Perform(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int Action,            /* Get/PreSet/Set action */
+SK_U32 Id,             /* Object ID that is to be processed */
+char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
+unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
+SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       int     Ret;
+       SK_U32  ActionOp;
+
+
+       /*
+        * Check instance. We only handle single instance variables
+        */
+       if (Instance != (SK_U32)(-1) && Instance != 1) {
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_UNKNOWN_INST);
+       }
+
+       if (*pLen < sizeof(SK_U32)) {
+
+               *pLen = sizeof(SK_U32);
+               return (SK_PNMI_ERR_TOO_SHORT);
+       }
+
+       /* Check if a get should be performed */
+       if (Action == SK_PNMI_GET) {
+
+               /* A get is easy. We always return the same value */
+               ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
+               SK_PNMI_STORE_U32(pBuf, ActionOp);
+               *pLen = sizeof(SK_U32);
+
+               return (SK_PNMI_ERR_OK);
+       }
+
+       /* Continue with PRESET/SET action */
+       if (*pLen > sizeof(SK_U32)) {
+
+               return (SK_PNMI_ERR_BAD_VALUE);
+       }
+
+       /* Check if the command is a known one */
+       SK_PNMI_READ_U32(pBuf, ActionOp);
+       if (*pLen > sizeof(SK_U32) ||
+               (ActionOp != SK_PNMI_ACT_IDLE &&
+               ActionOp != SK_PNMI_ACT_RESET &&
+               ActionOp != SK_PNMI_ACT_SELFTEST &&
+               ActionOp != SK_PNMI_ACT_RESETCNT)) {
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_BAD_VALUE);
+       }
+
+       /* A preset ends here */
+       if (Action == SK_PNMI_PRESET) {
+
+               return (SK_PNMI_ERR_OK);
+       }
+
+       switch (ActionOp) {
+
+       case SK_PNMI_ACT_IDLE:
+               /* Nothing to do */
+               break;
+
+       case SK_PNMI_ACT_RESET:
+               /*
+                * Perform a driver reset or something that comes near
+                * to this.
+                */
+               Ret = SK_DRIVER_RESET(pAC, IoC);
+               if (Ret != 0) {
+
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
+                               SK_PNMI_ERR005MSG);
+
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+               break;
+
+       case SK_PNMI_ACT_SELFTEST:
+               /*
+                * Perform a driver selftest or something similar to this.
+                * Currently this feature is not used and will probably
+                * implemented in another way.
+                */
+               Ret = SK_DRIVER_SELFTEST(pAC, IoC);
+               pAC->Pnmi.TestResult = Ret;
+               break;
+
+       case SK_PNMI_ACT_RESETCNT:
+               /* Set all counters and timestamps to zero */
+               ResetCounter(pAC, IoC, NetIndex);
+               break;
+
+       default:
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
+                       SK_PNMI_ERR006MSG);
+
+               return (SK_PNMI_ERR_GENERAL);
+       }
+
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
+ *
+ * Description:
+ *     Retrieves the statistic values of the virtual port (logical
+ *     index 0). Only special OIDs of NDIS are handled which consist
+ *     of a 32 bit instead of a 64 bit value. The OIDs are public
+ *     because perhaps some other platform can use them too.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter.
+ */
+PNMI_STATIC int Mac8023Stat(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int Action,            /* Get/PreSet/Set action */
+SK_U32 Id,             /* Object ID that is to be processed */
+char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
+unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
+SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
+unsigned int TableIndex,       /* Index to the Id table */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       int     Ret;
+       SK_U64  StatVal;
+       SK_U32  StatVal32;
+       SK_BOOL Is64BitReq = SK_FALSE;
+
+       /*
+        * Only the active Mac is returned
+        */
+       if (Instance != (SK_U32)(-1) && Instance != 1) {
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_UNKNOWN_INST);
+       }
+
+       /*
+        * Check action type
+        */
+       if (Action != SK_PNMI_GET) {
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_READ_ONLY);
+       }
+
+       /*
+        * Check length
+        */
+       switch (Id) {
+
+       case OID_802_3_PERMANENT_ADDRESS:
+       case OID_802_3_CURRENT_ADDRESS:
+               if (*pLen < sizeof(SK_MAC_ADDR)) {
+
+                       *pLen = sizeof(SK_MAC_ADDR);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               break;
+
+       default:
+#ifndef SK_NDIS_64BIT_CTR
+               if (*pLen < sizeof(SK_U32)) {
+                       *pLen = sizeof(SK_U32);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+
+#else /* SK_NDIS_64BIT_CTR */
+
+               /*
+                * for compatibility, at least 32bit are required for oid
+                */
+               if (*pLen < sizeof(SK_U32)) {
+                       /*
+                       * but indicate handling for 64bit values,
+                       * if insufficient space is provided
+                       */
+                       *pLen = sizeof(SK_U64);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+
+               Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
+#endif /* SK_NDIS_64BIT_CTR */
+               break;
+       }
+
+       /*
+        * Update all statistics, because we retrieve virtual MAC, which
+        * consists of multiple physical statistics and increment semaphore
+        * to indicate that an update was already done.
+        */
+       Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
+       if ( Ret != SK_PNMI_ERR_OK) {
+
+               *pLen = 0;
+               return (Ret);
+       }
+       pAC->Pnmi.MacUpdatedFlag ++;
+
+       /*
+        * Get value (MAC Index 0 identifies the virtual MAC)
+        */
+       switch (Id) {
+
+       case OID_802_3_PERMANENT_ADDRESS:
+               CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
+               *pLen = sizeof(SK_MAC_ADDR);
+               break;
+
+       case OID_802_3_CURRENT_ADDRESS:
+               CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
+               *pLen = sizeof(SK_MAC_ADDR);
+               break;
+
+       default:
+               StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
+
+               /*
+                * by default 32bit values are evaluated
+                */
+               if (!Is64BitReq) {
+                       StatVal32 = (SK_U32)StatVal;
+                       SK_PNMI_STORE_U32(pBuf, StatVal32);
+                       *pLen = sizeof(SK_U32);
+               }
+               else {
+                       SK_PNMI_STORE_U64(pBuf, StatVal);
+                       *pLen = sizeof(SK_U64);
+               }
+               break;
+       }
+
+       pAC->Pnmi.MacUpdatedFlag --;
+
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
+ *
+ * Description:
+ *     Retrieves the XMAC statistic data.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter.
+ */
+PNMI_STATIC int MacPrivateStat(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int Action,            /* Get/PreSet/Set action */
+SK_U32 Id,             /* Object ID that is to be processed */
+char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
+unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
+SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       unsigned int    LogPortMax;
+       unsigned int    LogPortIndex;
+       unsigned int    PhysPortMax;
+       unsigned int    Limit;
+       unsigned int    Offset;
+       int                             Ret;
+       SK_U64                  StatVal;
+
+
+       /*
+        * Calculate instance if wished. MAC index 0 is the virtual
+        * MAC.
+        */
+       PhysPortMax = pAC->GIni.GIMacsFound;
+       LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
+
+       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
+               LogPortMax--;
+       }
+
+       if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
+               /* Check instance range */
+               if ((Instance < 1) || (Instance > LogPortMax)) {
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_UNKNOWN_INST);
+               }
+               LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
+               Limit = LogPortIndex + 1;
+       }
+
+       else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
+
+               LogPortIndex = 0;
+               Limit = LogPortMax;
+       }
+
+
+       /*
+        * Check action
+        */
+       if (Action != SK_PNMI_GET) {
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_READ_ONLY);
+       }
+
+       /*
+        * Check length
+        */
+       if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
+
+               *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
+               return (SK_PNMI_ERR_TOO_SHORT);
+       }
+
+       /*
+        * Update XMAC statistic and increment semaphore to indicate that
+        * an update was already done.
+        */
+       Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
+       if (Ret != SK_PNMI_ERR_OK) {
+
+               *pLen = 0;
+               return (Ret);
+       }
+       pAC->Pnmi.MacUpdatedFlag ++;
+
+       /*
+        * Get value
+        */
+       Offset = 0;
+       for (; LogPortIndex < Limit; LogPortIndex ++) {
+
+               switch (Id) {
+
+/* XXX not yet implemented due to XMAC problems
+               case OID_SKGE_STAT_TX_UTIL:
+                       return (SK_PNMI_ERR_GENERAL);
+*/
+/* XXX not yet implemented due to XMAC problems
+               case OID_SKGE_STAT_RX_UTIL:
+                       return (SK_PNMI_ERR_GENERAL);
+*/
+               case OID_SKGE_STAT_RX:
+               case OID_SKGE_STAT_TX:
+                       switch (pAC->GIni.GIMacType) {
+                       case SK_MAC_XMAC:
+                               StatVal = GetStatVal(pAC, IoC, LogPortIndex,
+                                       IdTable[TableIndex].Param, NetIndex);
+                               break;
+
+                       case SK_MAC_GMAC:
+                               if (Id == OID_SKGE_STAT_TX) {
+
+                                       StatVal =
+                                               GetStatVal(pAC, IoC, LogPortIndex,
+                                                                  SK_PNMI_HTX_BROADCAST, NetIndex) +
+                                               GetStatVal(pAC, IoC, LogPortIndex,
+                                                                  SK_PNMI_HTX_MULTICAST, NetIndex) +
+                                               GetStatVal(pAC, IoC, LogPortIndex,
+                                                                  SK_PNMI_HTX_UNICAST, NetIndex);
+                               }
+                               else {
+                                       StatVal =
+                                               GetStatVal(pAC, IoC, LogPortIndex,
+                                                                  SK_PNMI_HRX_BROADCAST, NetIndex) +
+                                               GetStatVal(pAC, IoC, LogPortIndex,
+                                                                  SK_PNMI_HRX_MULTICAST, NetIndex) +
+                                               GetStatVal(pAC, IoC, LogPortIndex,
+                                                                  SK_PNMI_HRX_UNICAST, NetIndex) +
+                                               GetStatVal(pAC, IoC, LogPortIndex,
+                                                                  SK_PNMI_HRX_UNDERSIZE, NetIndex);
+                               }
+                               break;
+
+                       default:
+                               StatVal = 0;
+                               break;
+                       }
+
+                       SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
+                       break;
+
+               default:
+                       StatVal = GetStatVal(pAC, IoC, LogPortIndex,
+                               IdTable[TableIndex].Param, NetIndex);
+                       SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
+                       break;
+               }
+
+               Offset += sizeof(SK_U64);
+       }
+       *pLen = Offset;
+
+       pAC->Pnmi.MacUpdatedFlag --;
+
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
+ *
+ * Description:
+ *     Get/Presets/Sets the current and factory MAC address. The MAC
+ *     address of the virtual port, which is reported to the OS, may
+ *     not be changed, but the physical ones. A set to the virtual port
+ *     will be ignored. No error should be reported because otherwise
+ *     a multiple instance set (-1) would always fail.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
+ *                              value range.
+ *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter.
+ */
+PNMI_STATIC int Addr(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int Action,            /* Get/PreSet/Set action */
+SK_U32 Id,             /* Object ID that is to be processed */
+char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
+unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
+SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       int             Ret;
+       unsigned int    LogPortMax;
+       unsigned int    PhysPortMax;
+       unsigned int    LogPortIndex;
+       unsigned int    PhysPortIndex;
+       unsigned int    Limit;
+       unsigned int    Offset = 0;
+
+       /*
+        * Calculate instance if wished. MAC index 0 is the virtual
+        * MAC.
+        */
+       PhysPortMax = pAC->GIni.GIMacsFound;
+       LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
+
+       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
+               LogPortMax--;
+       }
+
+       if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
+               /* Check instance range */
+               if ((Instance < 1) || (Instance > LogPortMax)) {
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_UNKNOWN_INST);
+               }
+               LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
+               Limit = LogPortIndex + 1;
+       }
+
+       else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
+
+               LogPortIndex = 0;
+               Limit = LogPortMax;
+       }
+
+       /*
+        * Perform Action
+        */
+       if (Action == SK_PNMI_GET) {
+
+               /*
+                * Check length
+               */
+               if (*pLen < (Limit - LogPortIndex) * 6) {
+
+                       *pLen = (Limit - LogPortIndex) * 6;
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+
+               /*
+                * Get value
+                */
+               for (; LogPortIndex < Limit; LogPortIndex ++) {
+
+                       switch (Id) {
+
+                       case OID_SKGE_PHYS_CUR_ADDR:
+                               if (LogPortIndex == 0) {
+                                       CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
+                               }
+                               else {
+                                       PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
+
+                                       CopyMac(pBuf + Offset,
+                                               &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
+                               }
+                               Offset += 6;
+                               break;
+
+                       case OID_SKGE_PHYS_FAC_ADDR:
+                               if (LogPortIndex == 0) {
+                                       CopyMac(pBuf + Offset,
+                                               &pAC->Addr.Net[NetIndex].PermanentMacAddress);
+                               }
+                               else {
+                                       PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                               pAC, LogPortIndex);
+
+                                       CopyMac(pBuf + Offset,
+                                               &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
+                               }
+                               Offset += 6;
+                               break;
+
+                       default:
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
+                                       SK_PNMI_ERR008MSG);
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_GENERAL);
+                       }
+               }
+
+               *pLen = Offset;
+       }
+       else {
+               /*
+                * The logical MAC address may not be changed only
+                * the physical ones
+                */
+               if (Id == OID_SKGE_PHYS_FAC_ADDR) {
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_READ_ONLY);
+               }
+
+               /*
+                * Only the current address may be changed
+                */
+               if (Id != OID_SKGE_PHYS_CUR_ADDR) {
+
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
+                               SK_PNMI_ERR009MSG);
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+
+               /*
+                * Check length
+               */
+               if (*pLen < (Limit - LogPortIndex) * 6) {
+
+                       *pLen = (Limit - LogPortIndex) * 6;
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               if (*pLen > (Limit - LogPortIndex) * 6) {
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_BAD_VALUE);
+               }
+
+               /*
+                * Check Action
+                */
+               if (Action == SK_PNMI_PRESET) {
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_OK);
+               }
+
+               /*
+                * Set OID_SKGE_MAC_CUR_ADDR
+                */
+               for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
+
+                       /*
+                        * A set to virtual port and set of broadcast
+                        * address will be ignored
+                        */
+                       if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
+                               "\xff\xff\xff\xff\xff\xff", 6) == 0) {
+
+                               continue;
+                       }
+
+                       PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
+                               LogPortIndex);
+
+                       Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
+                               (SK_MAC_ADDR *)(pBuf + Offset),
+                               (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
+                               SK_ADDR_PHYSICAL_ADDRESS));
+                       if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
+
+                               return (SK_PNMI_ERR_GENERAL);
+                       }
+               }
+               *pLen = Offset;
+       }
+
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
+ *
+ * Description:
+ *     Retrieves the statistic values of the CSUM module. The CSUM data
+ *     structure must be available in the SK_AC even if the CSUM module
+ *     is not included, because PNMI reads the statistic data from the
+ *     CSUM part of SK_AC directly.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter.
+ */
+PNMI_STATIC int CsumStat(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int Action,            /* Get/PreSet/Set action */
+SK_U32 Id,             /* Object ID that is to be processed */
+char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
+unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
+SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       unsigned int    Index;
+       unsigned int    Limit;
+       unsigned int    Offset = 0;
+       SK_U64          StatVal;
+
+
+       /*
+        * Calculate instance if wished
+        */
+       if (Instance != (SK_U32)(-1)) {
+
+               if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_UNKNOWN_INST);
+               }
+               Index = (unsigned int)Instance - 1;
+               Limit = Index + 1;
+       }
+       else {
+               Index = 0;
+               Limit = SKCS_NUM_PROTOCOLS;
+       }
+
+       /*
+        * Check action
+        */
+       if (Action != SK_PNMI_GET) {
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_READ_ONLY);
+       }
+
+       /*
+        * Check length
+        */
+       if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
+
+               *pLen = (Limit - Index) * sizeof(SK_U64);
+               return (SK_PNMI_ERR_TOO_SHORT);
+       }
+
+       /*
+        * Get value
+        */
+       for (; Index < Limit; Index ++) {
+
+               switch (Id) {
+
+               case OID_SKGE_CHKSM_RX_OK_CTS:
+                       StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
+                       break;
+
+               case OID_SKGE_CHKSM_RX_UNABLE_CTS:
+                       StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
+                       break;
+
+               case OID_SKGE_CHKSM_RX_ERR_CTS:
+                       StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
+                       break;
+
+               case OID_SKGE_CHKSM_TX_OK_CTS:
+                       StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
+                       break;
+
+               case OID_SKGE_CHKSM_TX_UNABLE_CTS:
+                       StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
+                       break;
+
+               default:
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
+                               SK_PNMI_ERR010MSG);
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+
+               SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
+               Offset += sizeof(SK_U64);
+       }
+
+       /*
+        * Store used buffer space
+        */
+       *pLen = Offset;
+
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
+ *
+ * Description:
+ *     Retrieves the statistic values of the I2C module, which handles
+ *     the temperature and voltage sensors.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter.
+ */
+PNMI_STATIC int SensorStat(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int Action,            /* Get/PreSet/Set action */
+SK_U32 Id,             /* Object ID that is to be processed */
+char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
+unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
+SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       unsigned int    i;
+       unsigned int    Index;
+       unsigned int    Limit;
+       unsigned int    Offset;
+       unsigned int    Len;
+       SK_U32          Val32;
+       SK_U64          Val64;
+
+
+       /*
+        * Calculate instance if wished
+        */
+       if ((Instance != (SK_U32)(-1))) {
+
+               if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_UNKNOWN_INST);
+               }
+
+               Index = (unsigned int)Instance -1;
+               Limit = (unsigned int)Instance;
+       }
+       else {
+               Index = 0;
+               Limit = (unsigned int) pAC->I2c.MaxSens;
+       }
+
+       /*
+        * Check action
+        */
+       if (Action != SK_PNMI_GET) {
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_READ_ONLY);
+       }
+
+       /*
+        * Check length
+        */
+       switch (Id) {
+
+       case OID_SKGE_SENSOR_VALUE:
+       case OID_SKGE_SENSOR_WAR_THRES_LOW:
+       case OID_SKGE_SENSOR_WAR_THRES_UPP:
+       case OID_SKGE_SENSOR_ERR_THRES_LOW:
+       case OID_SKGE_SENSOR_ERR_THRES_UPP:
+               if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
+
+                       *pLen = (Limit - Index) * sizeof(SK_U32);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               break;
+
+       case OID_SKGE_SENSOR_DESCR:
+               for (Offset = 0, i = Index; i < Limit; i ++) {
+
+                       Len = (unsigned int)
+                               SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
+                       if (Len >= SK_PNMI_STRINGLEN2) {
+
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
+                                       SK_PNMI_ERR011MSG);
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_GENERAL);
+                       }
+                       Offset += Len;
+               }
+               if (*pLen < Offset) {
+
+                       *pLen = Offset;
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               break;
+
+       case OID_SKGE_SENSOR_INDEX:
+       case OID_SKGE_SENSOR_TYPE:
+       case OID_SKGE_SENSOR_STATUS:
+               if (*pLen < Limit - Index) {
+
+                       *pLen = Limit - Index;
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               break;
+
+       case OID_SKGE_SENSOR_WAR_CTS:
+       case OID_SKGE_SENSOR_WAR_TIME:
+       case OID_SKGE_SENSOR_ERR_CTS:
+       case OID_SKGE_SENSOR_ERR_TIME:
+               if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
+
+                       *pLen = (Limit - Index) * sizeof(SK_U64);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               break;
+
+       default:
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
+                       SK_PNMI_ERR012MSG);
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_GENERAL);
+
+       }
+
+       /*
+        * Get value
+        */
+       for (Offset = 0; Index < Limit; Index ++) {
+
+               switch (Id) {
+
+               case OID_SKGE_SENSOR_INDEX:
+                       *(pBuf + Offset) = (char)Index;
+                       Offset += sizeof(char);
+                       break;
+
+               case OID_SKGE_SENSOR_DESCR:
+                       Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
+                       SK_MEMCPY(pBuf + Offset + 1,
+                               pAC->I2c.SenTable[Index].SenDesc, Len);
+                       *(pBuf + Offset) = (char)Len;
+                       Offset += Len + 1;
+                       break;
+
+               case OID_SKGE_SENSOR_TYPE:
+                       *(pBuf + Offset) =
+                               (char)pAC->I2c.SenTable[Index].SenType;
+                       Offset += sizeof(char);
+                       break;
+
+               case OID_SKGE_SENSOR_VALUE:
+                       Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
+                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
+                       Offset += sizeof(SK_U32);
+                       break;
+
+               case OID_SKGE_SENSOR_WAR_THRES_LOW:
+                       Val32 = (SK_U32)pAC->I2c.SenTable[Index].
+                               SenThreWarnLow;
+                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
+                       Offset += sizeof(SK_U32);
+                       break;
+
+               case OID_SKGE_SENSOR_WAR_THRES_UPP:
+                       Val32 = (SK_U32)pAC->I2c.SenTable[Index].
+                               SenThreWarnHigh;
+                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
+                       Offset += sizeof(SK_U32);
+                       break;
+
+               case OID_SKGE_SENSOR_ERR_THRES_LOW:
+                       Val32 = (SK_U32)pAC->I2c.SenTable[Index].
+                               SenThreErrLow;
+                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
+                       Offset += sizeof(SK_U32);
+                       break;
+
+               case OID_SKGE_SENSOR_ERR_THRES_UPP:
+                       Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
+                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
+                       Offset += sizeof(SK_U32);
+                       break;
+
+               case OID_SKGE_SENSOR_STATUS:
+                       *(pBuf + Offset) =
+                               (char)pAC->I2c.SenTable[Index].SenErrFlag;
+                       Offset += sizeof(char);
+                       break;
+
+               case OID_SKGE_SENSOR_WAR_CTS:
+                       Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
+                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
+                       Offset += sizeof(SK_U64);
+                       break;
+
+               case OID_SKGE_SENSOR_ERR_CTS:
+                       Val64 = pAC->I2c.SenTable[Index].SenErrCts;
+                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
+                       Offset += sizeof(SK_U64);
+                       break;
+
+               case OID_SKGE_SENSOR_WAR_TIME:
+                       Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
+                               SenBegWarnTS);
+                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
+                       Offset += sizeof(SK_U64);
+                       break;
+
+               case OID_SKGE_SENSOR_ERR_TIME:
+                       Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
+                               SenBegErrTS);
+                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
+                       Offset += sizeof(SK_U64);
+                       break;
+
+               default:
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
+                               ("SensorStat: Unknown OID should be handled before"));
+
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+       }
+
+       /*
+        * Store used buffer space
+        */
+       *pLen = Offset;
+
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * Vpd - OID handler function of OID_SKGE_VPD_XXX
+ *
+ * Description:
+ *     Get/preset/set of VPD data. As instance the name of a VPD key
+ *     can be passed. The Instance parameter is a SK_U32 and can be
+ *     used as a string buffer for the VPD key, because their maximum
+ *     length is 4 byte.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
+ *                              value range.
+ *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter.
+ */
+PNMI_STATIC int Vpd(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int Action,            /* Get/PreSet/Set action */
+SK_U32 Id,             /* Object ID that is to be processed */
+char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
+unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
+SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       SK_VPD_STATUS   *pVpdStatus;
+       unsigned int    BufLen;
+       char            Buf[256];
+       char            KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
+       char            KeyStr[SK_PNMI_VPD_KEY_SIZE];
+       unsigned int    KeyNo;
+       unsigned int    Offset;
+       unsigned int    Index;
+       unsigned int    FirstIndex;
+       unsigned int    LastIndex;
+       unsigned int    Len;
+       int             Ret;
+       SK_U32          Val32;
+
+       /*
+        * Get array of all currently stored VPD keys
+        */
+       Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr),
+               &KeyNo);
+       if (Ret != SK_PNMI_ERR_OK) {
+               *pLen = 0;
+               return (Ret);
+       }
+
+       /*
+        * If instance is not -1, try to find the requested VPD key for
+        * the multiple instance variables. The other OIDs as for example
+        * OID VPD_ACTION are single instance variables and must be
+        * handled separatly.
+        */
+       FirstIndex = 0;
+       LastIndex = KeyNo;
+
+       if ((Instance != (SK_U32)(-1))) {
+
+               if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
+                       Id == OID_SKGE_VPD_ACCESS) {
+
+                       SK_STRNCPY(KeyStr, (char *)&Instance, 4);
+                       KeyStr[4] = 0;
+
+                       for (Index = 0; Index < KeyNo; Index ++) {
+
+                               if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
+                                       FirstIndex = Index;
+                                       LastIndex = Index+1;
+                                       break;
+                               }
+                       }
+                       if (Index == KeyNo) {
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_UNKNOWN_INST);
+                       }
+               }
+               else if (Instance != 1) {
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_UNKNOWN_INST);
+               }
+       }
+
+       /*
+        * Get value, if a query should be performed
+        */
+       if (Action == SK_PNMI_GET) {
+
+               switch (Id) {
+
+               case OID_SKGE_VPD_FREE_BYTES:
+                       /* Check length of buffer */
+                       if (*pLen < sizeof(SK_U32)) {
+
+                               *pLen = sizeof(SK_U32);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       /* Get number of free bytes */
+                       pVpdStatus = VpdStat(pAC, IoC);
+                       if (pVpdStatus == NULL) {
+
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
+                                       SK_PNMI_ERR017MSG);
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_GENERAL);
+                       }
+                       if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
+
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
+                                       SK_PNMI_ERR018MSG);
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_GENERAL);
+                       }
+
+                       Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
+                       SK_PNMI_STORE_U32(pBuf, Val32);
+                       *pLen = sizeof(SK_U32);
+                       break;
+
+               case OID_SKGE_VPD_ENTRIES_LIST:
+                       /* Check length */
+                       for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
+
+                               Len += SK_STRLEN(KeyArr[Index]) + 1;
+                       }
+                       if (*pLen < Len) {
+
+                               *pLen = Len;
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+
+                       /* Get value */
+                       *(pBuf) = (char)Len - 1;
+                       for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
+
+                               Len = SK_STRLEN(KeyArr[Index]);
+                               SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
+
+                               Offset += Len;
+
+                               if (Index < KeyNo - 1) {
+
+                                       *(pBuf + Offset) = ' ';
+                                       Offset ++;
+                               }
+                       }
+                       *pLen = Offset;
+                       break;
+
+               case OID_SKGE_VPD_ENTRIES_NUMBER:
+                       /* Check length */
+                       if (*pLen < sizeof(SK_U32)) {
+
+                               *pLen = sizeof(SK_U32);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+
+                       Val32 = (SK_U32)KeyNo;
+                       SK_PNMI_STORE_U32(pBuf, Val32);
+                       *pLen = sizeof(SK_U32);
+                       break;
+
+               case OID_SKGE_VPD_KEY:
+                       /* Check buffer length, if it is large enough */
+                       for (Len = 0, Index = FirstIndex;
+                               Index < LastIndex; Index ++) {
+
+                               Len += SK_STRLEN(KeyArr[Index]) + 1;
+                       }
+                       if (*pLen < Len) {
+
+                               *pLen = Len;
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+
+                       /*
+                        * Get the key to an intermediate buffer, because
+                        * we have to prepend a length byte.
+                        */
+                       for (Offset = 0, Index = FirstIndex;
+                               Index < LastIndex; Index ++) {
+
+                               Len = SK_STRLEN(KeyArr[Index]);
+
+                               *(pBuf + Offset) = (char)Len;
+                               SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
+                                       Len);
+                               Offset += Len + 1;
+                       }
+                       *pLen = Offset;
+                       break;
+
+               case OID_SKGE_VPD_VALUE:
+                       /* Check the buffer length if it is large enough */
+                       for (Offset = 0, Index = FirstIndex;
+                               Index < LastIndex; Index ++) {
+
+                               BufLen = 256;
+                               if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
+                                       (int *)&BufLen) > 0 ||
+                                       BufLen >= SK_PNMI_VPD_DATALEN) {
+
+                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
+                                               SK_PNMI_ERR021,
+                                               SK_PNMI_ERR021MSG);
+
+                                       return (SK_PNMI_ERR_GENERAL);
+                               }
+                               Offset += BufLen + 1;
+                       }
+                       if (*pLen < Offset) {
+
+                               *pLen = Offset;
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+
+                       /*
+                        * Get the value to an intermediate buffer, because
+                        * we have to prepend a length byte.
+                        */
+                       for (Offset = 0, Index = FirstIndex;
+                               Index < LastIndex; Index ++) {
+
+                               BufLen = 256;
+                               if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
+                                       (int *)&BufLen) > 0 ||
+                                       BufLen >= SK_PNMI_VPD_DATALEN) {
+
+                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
+                                               SK_PNMI_ERR022,
+                                               SK_PNMI_ERR022MSG);
+
+                                       *pLen = 0;
+                                       return (SK_PNMI_ERR_GENERAL);
+                               }
+
+                               *(pBuf + Offset) = (char)BufLen;
+                               SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
+                               Offset += BufLen + 1;
+                       }
+                       *pLen = Offset;
+                       break;
+
+               case OID_SKGE_VPD_ACCESS:
+                       if (*pLen < LastIndex - FirstIndex) {
+
+                               *pLen = LastIndex - FirstIndex;
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+
+                       for (Offset = 0, Index = FirstIndex;
+                               Index < LastIndex; Index ++) {
+
+                               if (VpdMayWrite(KeyArr[Index])) {
+
+                                       *(pBuf + Offset) = SK_PNMI_VPD_RW;
+                               }
+                               else {
+                                       *(pBuf + Offset) = SK_PNMI_VPD_RO;
+                               }
+                               Offset ++;
+                       }
+                       *pLen = Offset;
+                       break;
+
+               case OID_SKGE_VPD_ACTION:
+                       Offset = LastIndex - FirstIndex;
+                       if (*pLen < Offset) {
+
+                               *pLen = Offset;
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       SK_MEMSET(pBuf, 0, Offset);
+                       *pLen = Offset;
+                       break;
+
+               default:
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
+                               SK_PNMI_ERR023MSG);
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+       }
+       else {
+               /* The only OID which can be set is VPD_ACTION */
+               if (Id != OID_SKGE_VPD_ACTION) {
+
+                       if (Id == OID_SKGE_VPD_FREE_BYTES ||
+                               Id == OID_SKGE_VPD_ENTRIES_LIST ||
+                               Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
+                               Id == OID_SKGE_VPD_KEY ||
+                               Id == OID_SKGE_VPD_VALUE ||
+                               Id == OID_SKGE_VPD_ACCESS) {
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_READ_ONLY);
+                       }
+
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
+                               SK_PNMI_ERR024MSG);
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+
+               /*
+                * From this point we handle VPD_ACTION. Check the buffer
+                * length. It should at least have the size of one byte.
+                */
+               if (*pLen < 1) {
+
+                       *pLen = 1;
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+
+               /*
+                * The first byte contains the VPD action type we should
+                * perform.
+                */
+               switch (*pBuf) {
+
+               case SK_PNMI_VPD_IGNORE:
+                       /* Nothing to do */
+                       break;
+
+               case SK_PNMI_VPD_CREATE:
+                       /*
+                        * We have to create a new VPD entry or we modify
+                        * an existing one. Check first the buffer length.
+                        */
+                       if (*pLen < 4) {
+
+                               *pLen = 4;
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       KeyStr[0] = pBuf[1];
+                       KeyStr[1] = pBuf[2];
+                       KeyStr[2] = 0;
+
+                       /*
+                        * Is the entry writable or does it belong to the
+                        * read-only area?
+                        */
+                       if (!VpdMayWrite(KeyStr)) {
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+
+                       Offset = (int)pBuf[3] & 0xFF;
+
+                       SK_MEMCPY(Buf, pBuf + 4, Offset);
+                       Buf[Offset] = 0;
+
+                       /* A preset ends here */
+                       if (Action == SK_PNMI_PRESET) {
+
+                               return (SK_PNMI_ERR_OK);
+                       }
+
+                       /* Write the new entry or modify an existing one */
+                       Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
+                       if (Ret == SK_PNMI_VPD_NOWRITE ) {
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+                       else if (Ret != SK_PNMI_VPD_OK) {
+
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
+                                       SK_PNMI_ERR025MSG);
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_GENERAL);
+                       }
+
+                       /*
+                        * Perform an update of the VPD data. This is
+                        * not mandantory, but just to be sure.
+                        */
+                       Ret = VpdUpdate(pAC, IoC);
+                       if (Ret != SK_PNMI_VPD_OK) {
+
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
+                                       SK_PNMI_ERR026MSG);
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_GENERAL);
+                       }
+                       break;
+
+               case SK_PNMI_VPD_DELETE:
+                       /* Check if the buffer size is plausible */
+                       if (*pLen < 3) {
+
+                               *pLen = 3;
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       if (*pLen > 3) {
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+                       KeyStr[0] = pBuf[1];
+                       KeyStr[1] = pBuf[2];
+                       KeyStr[2] = 0;
+
+                       /* Find the passed key in the array */
+                       for (Index = 0; Index < KeyNo; Index ++) {
+
+                               if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
+
+                                       break;
+                               }
+                       }
+                       /*
+                        * If we cannot find the key it is wrong, so we
+                        * return an appropriate error value.
+                        */
+                       if (Index == KeyNo) {
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+
+                       if (Action == SK_PNMI_PRESET) {
+
+                               return (SK_PNMI_ERR_OK);
+                       }
+
+                       /* Ok, you wanted it and you will get it */
+                       Ret = VpdDelete(pAC, IoC, KeyStr);
+                       if (Ret != SK_PNMI_VPD_OK) {
+
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
+                                       SK_PNMI_ERR027MSG);
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_GENERAL);
+                       }
+
+                       /*
+                        * Perform an update of the VPD data. This is
+                        * not mandantory, but just to be sure.
+                        */
+                       Ret = VpdUpdate(pAC, IoC);
+                       if (Ret != SK_PNMI_VPD_OK) {
+
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
+                                       SK_PNMI_ERR028MSG);
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_GENERAL);
+                       }
+                       break;
+
+               default:
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_BAD_VALUE);
+               }
+       }
+
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * General - OID handler function of various single instance OIDs
+ *
+ * Description:
+ *     The code is simple. No description necessary.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter.
+ */
+PNMI_STATIC int General(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int Action,            /* Get/PreSet/Set action */
+SK_U32 Id,             /* Object ID that is to be processed */
+char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
+unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
+SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       int             Ret;
+       unsigned int    Index;
+       unsigned int    Len;
+       unsigned int    Offset;
+       unsigned int    Val;
+       SK_U8           Val8;
+       SK_U16          Val16;
+       SK_U32          Val32;
+       SK_U64          Val64;
+       SK_U64          Val64RxHwErrs = 0;
+       SK_U64          Val64TxHwErrs = 0;
+       SK_BOOL         Is64BitReq = SK_FALSE;
+       char            Buf[256];
+       int                     MacType;
+
+       /*
+        * Check instance. We only handle single instance variables
+        */
+       if (Instance != (SK_U32)(-1) && Instance != 1) {
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_UNKNOWN_INST);
+       }
+
+       /*
+        * Check action. We only allow get requests.
+        */
+       if (Action != SK_PNMI_GET) {
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_READ_ONLY);
+       }
+
+       MacType = pAC->GIni.GIMacType;
+
+       /*
+        * Check length for the various supported OIDs
+        */
+       switch (Id) {
+
+       case OID_GEN_XMIT_ERROR:
+       case OID_GEN_RCV_ERROR:
+       case OID_GEN_RCV_NO_BUFFER:
+#ifndef SK_NDIS_64BIT_CTR
+               if (*pLen < sizeof(SK_U32)) {
+                       *pLen = sizeof(SK_U32);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+
+#else /* SK_NDIS_64BIT_CTR */
+
+               /*
+                * for compatibility, at least 32bit are required for oid
+                */
+               if (*pLen < sizeof(SK_U32)) {
+                       /*
+                       * but indicate handling for 64bit values,
+                       * if insufficient space is provided
+                       */
+                       *pLen = sizeof(SK_U64);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+
+               Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
+#endif /* SK_NDIS_64BIT_CTR */
+               break;
+
+       case OID_SKGE_PORT_NUMBER:
+       case OID_SKGE_DEVICE_TYPE:
+       case OID_SKGE_RESULT:
+       case OID_SKGE_RLMT_MONITOR_NUMBER:
+       case OID_GEN_TRANSMIT_QUEUE_LENGTH:
+       case OID_SKGE_TRAP_NUMBER:
+       case OID_SKGE_MDB_VERSION:
+               if (*pLen < sizeof(SK_U32)) {
+
+                       *pLen = sizeof(SK_U32);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               break;
+
+       case OID_SKGE_CHIPSET:
+               if (*pLen < sizeof(SK_U16)) {
+
+                       *pLen = sizeof(SK_U16);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               break;
+
+       case OID_SKGE_BUS_TYPE:
+       case OID_SKGE_BUS_SPEED:
+       case OID_SKGE_BUS_WIDTH:
+       case OID_SKGE_SENSOR_NUMBER:
+       case OID_SKGE_CHKSM_NUMBER:
+               if (*pLen < sizeof(SK_U8)) {
+
+                       *pLen = sizeof(SK_U8);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               break;
+
+       case OID_SKGE_TX_SW_QUEUE_LEN:
+       case OID_SKGE_TX_SW_QUEUE_MAX:
+       case OID_SKGE_TX_RETRY:
+       case OID_SKGE_RX_INTR_CTS:
+       case OID_SKGE_TX_INTR_CTS:
+       case OID_SKGE_RX_NO_BUF_CTS:
+       case OID_SKGE_TX_NO_BUF_CTS:
+       case OID_SKGE_TX_USED_DESCR_NO:
+       case OID_SKGE_RX_DELIVERED_CTS:
+       case OID_SKGE_RX_OCTETS_DELIV_CTS:
+       case OID_SKGE_RX_HW_ERROR_CTS:
+       case OID_SKGE_TX_HW_ERROR_CTS:
+       case OID_SKGE_IN_ERRORS_CTS:
+       case OID_SKGE_OUT_ERROR_CTS:
+       case OID_SKGE_ERR_RECOVERY_CTS:
+       case OID_SKGE_SYSUPTIME:
+               if (*pLen < sizeof(SK_U64)) {
+
+                       *pLen = sizeof(SK_U64);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               break;
+
+       default:
+               /* Checked later */
+               break;
+       }
+
+       /* Update statistic */
+       if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
+               Id == OID_SKGE_TX_HW_ERROR_CTS ||
+               Id == OID_SKGE_IN_ERRORS_CTS ||
+               Id == OID_SKGE_OUT_ERROR_CTS ||
+               Id == OID_GEN_XMIT_ERROR ||
+               Id == OID_GEN_RCV_ERROR) {
+
+               /* Force the XMAC to update its statistic counters and
+                * Increment semaphore to indicate that an update was
+                * already done.
+                */
+               Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
+               if (Ret != SK_PNMI_ERR_OK) {
+
+                       *pLen = 0;
+                       return (Ret);
+               }
+               pAC->Pnmi.MacUpdatedFlag ++;
+
+               /*
+                * Some OIDs consist of multiple hardware counters. Those
+                * values which are contained in all of them will be added
+                * now.
+                */
+               switch (Id) {
+
+               case OID_SKGE_RX_HW_ERROR_CTS:
+               case OID_SKGE_IN_ERRORS_CTS:
+               case OID_GEN_RCV_ERROR:
+                       Val64RxHwErrs =
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex)+
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex)+
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
+               break;
+
+               case OID_SKGE_TX_HW_ERROR_CTS:
+               case OID_SKGE_OUT_ERROR_CTS:
+               case OID_GEN_XMIT_ERROR:
+                       Val64TxHwErrs =
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex)+
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex)+
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
+                       break;
+               }
+       }
+
+       /*
+        * Retrieve value
+        */
+       switch (Id) {
+
+       case OID_SKGE_SUPPORTED_LIST:
+               Len = ID_TABLE_SIZE * sizeof(SK_U32);
+               if (*pLen < Len) {
+
+                       *pLen = Len;
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               for (Offset = 0, Index = 0; Offset < Len;
+                       Offset += sizeof(SK_U32), Index ++) {
+
+                       Val32 = (SK_U32)IdTable[Index].Id;
+                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
+               }
+               *pLen = Len;
+               break;
+
+       case OID_SKGE_PORT_NUMBER:
+               Val32 = (SK_U32)pAC->GIni.GIMacsFound;
+               SK_PNMI_STORE_U32(pBuf, Val32);
+               *pLen = sizeof(SK_U32);
+               break;
+
+       case OID_SKGE_DEVICE_TYPE:
+               Val32 = (SK_U32)pAC->Pnmi.DeviceType;
+               SK_PNMI_STORE_U32(pBuf, Val32);
+               *pLen = sizeof(SK_U32);
+               break;
+
+       case OID_SKGE_DRIVER_DESCR:
+               if (pAC->Pnmi.pDriverDescription == NULL) {
+
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
+                               SK_PNMI_ERR007MSG);
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+
+               Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
+               if (Len > SK_PNMI_STRINGLEN1) {
+
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
+                               SK_PNMI_ERR029MSG);
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+
+               if (*pLen < Len) {
+
+                       *pLen = Len;
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               *pBuf = (char)(Len - 1);
+               SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
+               *pLen = Len;
+               break;
+
+       case OID_SKGE_DRIVER_VERSION:
+               if (pAC->Pnmi.pDriverVersion == NULL) {
+
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
+                               SK_PNMI_ERR030MSG);
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+
+               Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
+               if (Len > SK_PNMI_STRINGLEN1) {
+
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
+                               SK_PNMI_ERR031MSG);
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+
+               if (*pLen < Len) {
+
+                       *pLen = Len;
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               *pBuf = (char)(Len - 1);
+               SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
+               *pLen = Len;
+               break;
+
+       case OID_SKGE_HW_DESCR:
+               /*
+                * The hardware description is located in the VPD. This
+                * query may move to the initialisation routine. But
+                * the VPD data is cached and therefore a call here
+                * will not make much difference.
+                */
+               Len = 256;
+               if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
+
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
+                               SK_PNMI_ERR032MSG);
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+               Len ++;
+               if (Len > SK_PNMI_STRINGLEN1) {
+
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
+                               SK_PNMI_ERR033MSG);
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+               if (*pLen < Len) {
+
+                       *pLen = Len;
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               *pBuf = (char)(Len - 1);
+               SK_MEMCPY(pBuf + 1, Buf, Len - 1);
+               *pLen = Len;
+               break;
+
+       case OID_SKGE_HW_VERSION:
+               /* Oh, I love to do some string manipulation */
+               if (*pLen < 5) {
+
+                       *pLen = 5;
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
+               pBuf[0] = 4;
+               pBuf[1] = 'v';
+               pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
+               pBuf[3] = '.';
+               pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
+               *pLen = 5;
+               break;
+
+       case OID_SKGE_CHIPSET:
+               Val16 = pAC->Pnmi.Chipset;
+               SK_PNMI_STORE_U16(pBuf, Val16);
+               *pLen = sizeof(SK_U16);
+               break;
+
+       case OID_SKGE_BUS_TYPE:
+               *pBuf = (char)SK_PNMI_BUS_PCI;
+               *pLen = sizeof(char);
+               break;
+
+       case OID_SKGE_BUS_SPEED:
+               *pBuf = pAC->Pnmi.PciBusSpeed;
+               *pLen = sizeof(char);
+               break;
+
+       case OID_SKGE_BUS_WIDTH:
+               *pBuf = pAC->Pnmi.PciBusWidth;
+               *pLen = sizeof(char);
+               break;
+
+       case OID_SKGE_RESULT:
+               Val32 = pAC->Pnmi.TestResult;
+               SK_PNMI_STORE_U32(pBuf, Val32);
+               *pLen = sizeof(SK_U32);
+               break;
+
+       case OID_SKGE_SENSOR_NUMBER:
+               *pBuf = (char)pAC->I2c.MaxSens;
+               *pLen = sizeof(char);
+               break;
+
+       case OID_SKGE_CHKSM_NUMBER:
+               *pBuf = SKCS_NUM_PROTOCOLS;
+               *pLen = sizeof(char);
+               break;
+
+       case OID_SKGE_TRAP_NUMBER:
+               GetTrapQueueLen(pAC, &Len, &Val);
+               Val32 = (SK_U32)Val;
+               SK_PNMI_STORE_U32(pBuf, Val32);
+               *pLen = sizeof(SK_U32);
+               break;
+
+       case OID_SKGE_TRAP:
+               GetTrapQueueLen(pAC, &Len, &Val);
+               if (*pLen < Len) {
+
+                       *pLen = Len;
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               CopyTrapQueue(pAC, pBuf);
+               *pLen = Len;
+               break;
+
+       case OID_SKGE_RLMT_MONITOR_NUMBER:
+/* XXX Not yet implemented by RLMT therefore we return zero elements */
+               Val32 = 0;
+               SK_PNMI_STORE_U32(pBuf, Val32);
+               *pLen = sizeof(SK_U32);
+               break;
+
+       case OID_SKGE_TX_SW_QUEUE_LEN:
+               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
+               if (MacType == SK_MAC_XMAC) {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
+                                       pAC->Pnmi.BufPort[1].TxSwQueueLen;
+                       }
+               }
+               else {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
+                                       pAC->Pnmi.Port[1].TxSwQueueLen;
+                       }
+               }
+               SK_PNMI_STORE_U64(pBuf, Val64);
+               *pLen = sizeof(SK_U64);
+               break;
+
+
+       case OID_SKGE_TX_SW_QUEUE_MAX:
+               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
+               if (MacType == SK_MAC_XMAC) {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
+                                       pAC->Pnmi.BufPort[1].TxSwQueueMax;
+                       }
+               }
+               else {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
+                                       pAC->Pnmi.Port[1].TxSwQueueMax;
+                       }
+               }
+               SK_PNMI_STORE_U64(pBuf, Val64);
+               *pLen = sizeof(SK_U64);
+               break;
+
+       case OID_SKGE_TX_RETRY:
+               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
+               if (MacType == SK_MAC_XMAC) {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
+                                       pAC->Pnmi.BufPort[1].TxRetryCts;
+                       }
+               }
+               else {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].TxRetryCts +
+                                       pAC->Pnmi.Port[1].TxRetryCts;
+                       }
+               }
+               SK_PNMI_STORE_U64(pBuf, Val64);
+               *pLen = sizeof(SK_U64);
+               break;
+
+       case OID_SKGE_RX_INTR_CTS:
+               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
+               if (MacType == SK_MAC_XMAC) {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
+                                       pAC->Pnmi.BufPort[1].RxIntrCts;
+                       }
+               }
+               else {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].RxIntrCts +
+                                       pAC->Pnmi.Port[1].RxIntrCts;
+                       }
+               }
+               SK_PNMI_STORE_U64(pBuf, Val64);
+               *pLen = sizeof(SK_U64);
+               break;
+
+       case OID_SKGE_TX_INTR_CTS:
+               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
+               if (MacType == SK_MAC_XMAC) {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
+                                       pAC->Pnmi.BufPort[1].TxIntrCts;
+                       }
+               }
+               else {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].TxIntrCts +
+                                       pAC->Pnmi.Port[1].TxIntrCts;
+                       }
+               }
+               SK_PNMI_STORE_U64(pBuf, Val64);
+               *pLen = sizeof(SK_U64);
+               break;
+
+       case OID_SKGE_RX_NO_BUF_CTS:
+               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
+               if (MacType == SK_MAC_XMAC) {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
+                                       pAC->Pnmi.BufPort[1].RxNoBufCts;
+                       }
+               }
+               else {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
+                                       pAC->Pnmi.Port[1].RxNoBufCts;
+                       }
+               }
+               SK_PNMI_STORE_U64(pBuf, Val64);
+               *pLen = sizeof(SK_U64);
+               break;
+
+       case OID_SKGE_TX_NO_BUF_CTS:
+               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
+               if (MacType == SK_MAC_XMAC) {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
+                                       pAC->Pnmi.BufPort[1].TxNoBufCts;
+                       }
+               }
+               else {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
+                                       pAC->Pnmi.Port[1].TxNoBufCts;
+                       }
+               }
+               SK_PNMI_STORE_U64(pBuf, Val64);
+               *pLen = sizeof(SK_U64);
+               break;
+
+       case OID_SKGE_TX_USED_DESCR_NO:
+               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
+               if (MacType == SK_MAC_XMAC) {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
+                                       pAC->Pnmi.BufPort[1].TxUsedDescrNo;
+                       }
+               }
+               else {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
+                                       pAC->Pnmi.Port[1].TxUsedDescrNo;
+                       }
+               }
+               SK_PNMI_STORE_U64(pBuf, Val64);
+               *pLen = sizeof(SK_U64);
+               break;
+
+       case OID_SKGE_RX_DELIVERED_CTS:
+               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
+               if (MacType == SK_MAC_XMAC) {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
+                                       pAC->Pnmi.BufPort[1].RxDeliveredCts;
+                       }
+               }
+               else {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
+                                       pAC->Pnmi.Port[1].RxDeliveredCts;
+                       }
+               }
+               SK_PNMI_STORE_U64(pBuf, Val64);
+               *pLen = sizeof(SK_U64);
+               break;
+
+       case OID_SKGE_RX_OCTETS_DELIV_CTS:
+               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
+               if (MacType == SK_MAC_XMAC) {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
+                                       pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
+                       }
+               }
+               else {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
+                                       pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
+                       }
+               }
+               SK_PNMI_STORE_U64(pBuf, Val64);
+               *pLen = sizeof(SK_U64);
+               break;
+
+       case OID_SKGE_RX_HW_ERROR_CTS:
+               SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
+               *pLen = sizeof(SK_U64);
+               break;
+
+       case OID_SKGE_TX_HW_ERROR_CTS:
+               SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
+               *pLen = sizeof(SK_U64);
+               break;
+
+       case OID_SKGE_IN_ERRORS_CTS:
+               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
+               if (MacType == SK_MAC_XMAC) {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = Val64RxHwErrs +
+                                       pAC->Pnmi.BufPort[0].RxNoBufCts +
+                                       pAC->Pnmi.BufPort[1].RxNoBufCts;
+                       }
+               }
+               else {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = Val64RxHwErrs +
+                                       pAC->Pnmi.Port[0].RxNoBufCts +
+                                       pAC->Pnmi.Port[1].RxNoBufCts;
+                       }
+               }
+               SK_PNMI_STORE_U64(pBuf, Val64);
+               *pLen = sizeof(SK_U64);
+               break;
+
+       case OID_SKGE_OUT_ERROR_CTS:
+               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
+               if (MacType == SK_MAC_XMAC) {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = Val64TxHwErrs +
+                                       pAC->Pnmi.BufPort[0].TxNoBufCts +
+                                       pAC->Pnmi.BufPort[1].TxNoBufCts;
+                       }
+               }
+               else {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = Val64TxHwErrs +
+                                       pAC->Pnmi.Port[0].TxNoBufCts +
+                                       pAC->Pnmi.Port[1].TxNoBufCts;
+                       }
+               }
+               SK_PNMI_STORE_U64(pBuf, Val64);
+               *pLen = sizeof(SK_U64);
+               break;
+
+       case OID_SKGE_ERR_RECOVERY_CTS:
+               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
+               if (MacType == SK_MAC_XMAC) {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
+                                       pAC->Pnmi.BufPort[1].ErrRecoveryCts;
+                       }
+               }
+               else {
+                       /* Dual net mode */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
+                       }
+                       /* Single net mode */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
+                                       pAC->Pnmi.Port[1].ErrRecoveryCts;
+                       }
+               }
+               SK_PNMI_STORE_U64(pBuf, Val64);
+               *pLen = sizeof(SK_U64);
+               break;
+
+       case OID_SKGE_SYSUPTIME:
+               Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
+               Val64 -= pAC->Pnmi.StartUpTime;
+               SK_PNMI_STORE_U64(pBuf, Val64);
+               *pLen = sizeof(SK_U64);
+               break;
+
+       case OID_SKGE_MDB_VERSION:
+               Val32 = SK_PNMI_MDB_VERSION;
+               SK_PNMI_STORE_U32(pBuf, Val32);
+               *pLen = sizeof(SK_U32);
+               break;
+
+       case OID_GEN_RCV_ERROR:
+               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
+               if (MacType == SK_MAC_XMAC) {
+                       Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
+               }
+               else {
+                       Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
+               }
+
+               /*
+                * by default 32bit values are evaluated
+                */
+               if (!Is64BitReq) {
+                       Val32 = (SK_U32)Val64;
+                       SK_PNMI_STORE_U32(pBuf, Val32);
+                       *pLen = sizeof(SK_U32);
+               }
+               else {
+                       SK_PNMI_STORE_U64(pBuf, Val64);
+                       *pLen = sizeof(SK_U64);
+               }
+               break;
+
+       case OID_GEN_XMIT_ERROR:
+               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
+               if (MacType == SK_MAC_XMAC) {
+                       Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
+               }
+               else {
+                       Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
+               }
+
+               /*
+                * by default 32bit values are evaluated
+                */
+               if (!Is64BitReq) {
+                       Val32 = (SK_U32)Val64;
+                       SK_PNMI_STORE_U32(pBuf, Val32);
+                       *pLen = sizeof(SK_U32);
+               }
+               else {
+                       SK_PNMI_STORE_U64(pBuf, Val64);
+                       *pLen = sizeof(SK_U64);
+               }
+               break;
+
+       case OID_GEN_RCV_NO_BUFFER:
+               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
+               if (MacType == SK_MAC_XMAC) {
+                       Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
+               }
+               else {
+                       Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
+               }
+
+               /*
+                * by default 32bit values are evaluated
+                */
+               if (!Is64BitReq) {
+                       Val32 = (SK_U32)Val64;
+                       SK_PNMI_STORE_U32(pBuf, Val32);
+                       *pLen = sizeof(SK_U32);
+               }
+               else {
+                       SK_PNMI_STORE_U64(pBuf, Val64);
+                       *pLen = sizeof(SK_U64);
+               }
+               break;
+
+       case OID_GEN_TRANSMIT_QUEUE_LENGTH:
+               Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
+               SK_PNMI_STORE_U32(pBuf, Val32);
+               *pLen = sizeof(SK_U32);
+               break;
+
+       default:
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
+                       SK_PNMI_ERR034MSG);
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_GENERAL);
+       }
+
+       if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
+               Id == OID_SKGE_TX_HW_ERROR_CTS ||
+               Id == OID_SKGE_IN_ERRORS_CTS ||
+               Id == OID_SKGE_OUT_ERROR_CTS ||
+               Id == OID_GEN_XMIT_ERROR ||
+               Id == OID_GEN_RCV_ERROR) {
+
+               pAC->Pnmi.MacUpdatedFlag --;
+       }
+
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
+ *
+ * Description:
+ *     Get/Presets/Sets the RLMT OIDs.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
+ *                              value range.
+ *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter.
+ */
+PNMI_STATIC int Rlmt(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int Action,            /* Get/PreSet/Set action */
+SK_U32 Id,             /* Object ID that is to be processed */
+char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
+unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
+SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       int             Ret;
+       unsigned int    PhysPortIndex;
+       unsigned int    PhysPortMax;
+       SK_EVPARA       EventParam;
+       SK_U32          Val32;
+       SK_U64          Val64;
+
+
+       /*
+        * Check instance. Only single instance OIDs are allowed here.
+        */
+       if (Instance != (SK_U32)(-1) && Instance != 1) {
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_UNKNOWN_INST);
+       }
+
+       /*
+        * Perform the requested action
+        */
+       if (Action == SK_PNMI_GET) {
+
+               /*
+                * Check if the buffer length is large enough.
+                */
+
+               switch (Id) {
+
+               case OID_SKGE_RLMT_MODE:
+               case OID_SKGE_RLMT_PORT_ACTIVE:
+               case OID_SKGE_RLMT_PORT_PREFERRED:
+                       if (*pLen < sizeof(SK_U8)) {
+
+                               *pLen = sizeof(SK_U8);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       break;
+
+               case OID_SKGE_RLMT_PORT_NUMBER:
+                       if (*pLen < sizeof(SK_U32)) {
+
+                               *pLen = sizeof(SK_U32);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       break;
+
+               case OID_SKGE_RLMT_CHANGE_CTS:
+               case OID_SKGE_RLMT_CHANGE_TIME:
+               case OID_SKGE_RLMT_CHANGE_ESTIM:
+               case OID_SKGE_RLMT_CHANGE_THRES:
+                       if (*pLen < sizeof(SK_U64)) {
+
+                               *pLen = sizeof(SK_U64);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       break;
+
+               default:
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
+                               SK_PNMI_ERR035MSG);
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+
+               /*
+                * Update RLMT statistic and increment semaphores to indicate
+                * that an update was already done. Maybe RLMT will hold its
+                * statistic always up to date some time. Then we can
+                * remove this type of call.
+                */
+               if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
+
+                       *pLen = 0;
+                       return (Ret);
+               }
+               pAC->Pnmi.RlmtUpdatedFlag ++;
+
+               /*
+                * Retrieve Value
+               */
+               switch (Id) {
+
+               case OID_SKGE_RLMT_MODE:
+                       *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
+                       *pLen = sizeof(char);
+                       break;
+
+               case OID_SKGE_RLMT_PORT_NUMBER:
+                       Val32 = (SK_U32)pAC->GIni.GIMacsFound;
+                       SK_PNMI_STORE_U32(pBuf, Val32);
+                       *pLen = sizeof(SK_U32);
+                       break;
+
+               case OID_SKGE_RLMT_PORT_ACTIVE:
+                       *pBuf = 0;
+                       /*
+                        * If multiple ports may become active this OID
+                        * doesn't make sense any more. A new variable in
+                        * the port structure should be created. However,
+                        * for this variable the first active port is
+                        * returned.
+                        */
+                       PhysPortMax = pAC->GIni.GIMacsFound;
+
+                       for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
+                               PhysPortIndex ++) {
+
+                               if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
+
+                                       *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
+                                       break;
+                               }
+                       }
+                       *pLen = sizeof(char);
+                       break;
+
+               case OID_SKGE_RLMT_PORT_PREFERRED:
+                       *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
+                       *pLen = sizeof(char);
+                       break;
+
+               case OID_SKGE_RLMT_CHANGE_CTS:
+                       Val64 = pAC->Pnmi.RlmtChangeCts;
+                       SK_PNMI_STORE_U64(pBuf, Val64);
+                       *pLen = sizeof(SK_U64);
+                       break;
+
+               case OID_SKGE_RLMT_CHANGE_TIME:
+                       Val64 = pAC->Pnmi.RlmtChangeTime;
+                       SK_PNMI_STORE_U64(pBuf, Val64);
+                       *pLen = sizeof(SK_U64);
+                       break;
+
+               case OID_SKGE_RLMT_CHANGE_ESTIM:
+                       Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
+                       SK_PNMI_STORE_U64(pBuf, Val64);
+                       *pLen = sizeof(SK_U64);
+                       break;
+
+               case OID_SKGE_RLMT_CHANGE_THRES:
+                       Val64 = pAC->Pnmi.RlmtChangeThreshold;
+                       SK_PNMI_STORE_U64(pBuf, Val64);
+                       *pLen = sizeof(SK_U64);
+                       break;
+
+               default:
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
+                               ("Rlmt: Unknown OID should be handled before"));
+
+                       pAC->Pnmi.RlmtUpdatedFlag --;
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+
+               pAC->Pnmi.RlmtUpdatedFlag --;
+       }
+       else {
+               /* Perform a preset or set */
+               switch (Id) {
+
+               case OID_SKGE_RLMT_MODE:
+                       /* Check if the buffer length is plausible */
+                       if (*pLen < sizeof(char)) {
+
+                               *pLen = sizeof(char);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       /* Check if the value range is correct */
+                       if (*pLen != sizeof(char) ||
+                               (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
+                               *(SK_U8 *)pBuf > 15) {
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+                       /* The preset ends here */
+                       if (Action == SK_PNMI_PRESET) {
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_OK);
+                       }
+                       /* Send an event to RLMT to change the mode */
+                       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
+                       EventParam.Para32[0] |= (SK_U32)(*pBuf);
+                       EventParam.Para32[1] = 0;
+                       if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
+                               EventParam) > 0) {
+
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
+                                       SK_PNMI_ERR037MSG);
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_GENERAL);
+                       }
+                       break;
+
+               case OID_SKGE_RLMT_PORT_PREFERRED:
+                       /* Check if the buffer length is plausible */
+                       if (*pLen < sizeof(char)) {
+
+                               *pLen = sizeof(char);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       /* Check if the value range is correct */
+                       if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
+                               (SK_U8)pAC->GIni.GIMacsFound) {
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+                       /* The preset ends here */
+                       if (Action == SK_PNMI_PRESET) {
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_OK);
+                       }
+
+                       /*
+                        * Send an event to RLMT change the preferred port.
+                        * A param of -1 means automatic mode. RLMT will
+                        * make the decision which is the preferred port.
+                        */
+                       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
+                       EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
+                       EventParam.Para32[1] = NetIndex;
+                       if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
+                               EventParam) > 0) {
+
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
+                                       SK_PNMI_ERR038MSG);
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_GENERAL);
+                       }
+                       break;
+
+               case OID_SKGE_RLMT_CHANGE_THRES:
+                       /* Check if the buffer length is plausible */
+                       if (*pLen < sizeof(SK_U64)) {
+
+                               *pLen = sizeof(SK_U64);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       /*
+                        * There are not many restrictions to the
+                        * value range.
+                        */
+                       if (*pLen != sizeof(SK_U64)) {
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+                       /* A preset ends here */
+                       if (Action == SK_PNMI_PRESET) {
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_OK);
+                       }
+                       /*
+                        * Store the new threshold, which will be taken
+                        * on the next timer event.
+                        */
+                       SK_PNMI_READ_U64(pBuf, Val64);
+                       pAC->Pnmi.RlmtChangeThreshold = Val64;
+                       break;
+
+               default:
+                       /* The other OIDs are not be able for set */
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_READ_ONLY);
+               }
+       }
+
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
+ *
+ * Description:
+ *     Performs get requests on multiple instance variables.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter.
+ */
+PNMI_STATIC int RlmtStat(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int Action,            /* Get/PreSet/Set action */
+SK_U32 Id,             /* Object ID that is to be processed */
+char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
+unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
+SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       unsigned int    PhysPortMax;
+       unsigned int    PhysPortIndex;
+       unsigned int    Limit;
+       unsigned int    Offset;
+       int             Ret;
+       SK_U32          Val32;
+       SK_U64          Val64;
+
+       /*
+        * Calculate the port indexes from the instance
+        */
+       PhysPortMax = pAC->GIni.GIMacsFound;
+
+       if ((Instance != (SK_U32)(-1))) {
+               /* Check instance range */
+               if ((Instance < 1) || (Instance > PhysPortMax)) {
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_UNKNOWN_INST);
+               }
+
+               /* Single net mode */
+               PhysPortIndex = Instance - 1;
+
+               /* Dual net mode */
+               if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                       PhysPortIndex = NetIndex;
+               }
+
+               /* Both net modes */
+               Limit = PhysPortIndex + 1;
+       }
+       else {
+               /* Single net mode */
+               PhysPortIndex = 0;
+               Limit = PhysPortMax;
+
+               /* Dual net mode */
+               if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                       PhysPortIndex = NetIndex;
+                       Limit = PhysPortIndex + 1;
+               }
+       }
+
+       /*
+        * Currently only get requests are allowed.
+        */
+       if (Action != SK_PNMI_GET) {
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_READ_ONLY);
+       }
+
+       /*
+        * Check if the buffer length is large enough.
+        */
+       switch (Id) {
+
+       case OID_SKGE_RLMT_PORT_INDEX:
+       case OID_SKGE_RLMT_STATUS:
+               if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
+
+                       *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               break;
+
+       case OID_SKGE_RLMT_TX_HELLO_CTS:
+       case OID_SKGE_RLMT_RX_HELLO_CTS:
+       case OID_SKGE_RLMT_TX_SP_REQ_CTS:
+       case OID_SKGE_RLMT_RX_SP_CTS:
+               if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
+
+                       *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               break;
+
+       default:
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
+                       SK_PNMI_ERR039MSG);
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_GENERAL);
+
+       }
+
+       /*
+        * Update statistic and increment semaphores to indicate that
+        * an update was already done.
+        */
+       if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
+
+               *pLen = 0;
+               return (Ret);
+       }
+       pAC->Pnmi.RlmtUpdatedFlag ++;
+
+       /*
+        * Get value
+        */
+       Offset = 0;
+       for (; PhysPortIndex < Limit; PhysPortIndex ++) {
+
+               switch (Id) {
+
+               case OID_SKGE_RLMT_PORT_INDEX:
+                       Val32 = PhysPortIndex;
+                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
+                       Offset += sizeof(SK_U32);
+                       break;
+
+               case OID_SKGE_RLMT_STATUS:
+                       if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
+                               SK_RLMT_PS_INIT ||
+                               pAC->Rlmt.Port[PhysPortIndex].PortState ==
+                               SK_RLMT_PS_DOWN) {
+
+                               Val32 = SK_PNMI_RLMT_STATUS_ERROR;
+                       }
+                       else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
+
+                               Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
+                       }
+                       else {
+                               Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
+                       }
+                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
+                       Offset += sizeof(SK_U32);
+                       break;
+
+               case OID_SKGE_RLMT_TX_HELLO_CTS:
+                       Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
+                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
+                       Offset += sizeof(SK_U64);
+                       break;
+
+               case OID_SKGE_RLMT_RX_HELLO_CTS:
+                       Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
+                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
+                       Offset += sizeof(SK_U64);
+                       break;
+
+               case OID_SKGE_RLMT_TX_SP_REQ_CTS:
+                       Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
+                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
+                       Offset += sizeof(SK_U64);
+                       break;
+
+               case OID_SKGE_RLMT_RX_SP_CTS:
+                       Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
+                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
+                       Offset += sizeof(SK_U64);
+                       break;
+
+               default:
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
+                               ("RlmtStat: Unknown OID should be errored before"));
+
+                       pAC->Pnmi.RlmtUpdatedFlag --;
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+       }
+       *pLen = Offset;
+
+       pAC->Pnmi.RlmtUpdatedFlag --;
+
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * MacPrivateConf - OID handler function of OIDs concerning the configuration
+ *
+ * Description:
+ *     Get/Presets/Sets the OIDs concerning the configuration.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
+ *                              value range.
+ *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter.
+ */
+PNMI_STATIC int MacPrivateConf(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int Action,            /* Get/PreSet/Set action */
+SK_U32 Id,             /* Object ID that is to be processed */
+char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
+unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
+SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       unsigned int    PhysPortMax;
+       unsigned int    PhysPortIndex;
+       unsigned int    LogPortMax;
+       unsigned int    LogPortIndex;
+       unsigned int    Limit;
+       unsigned int    Offset;
+       char            Val8;
+       int             Ret;
+       SK_EVPARA       EventParam;
+       SK_U32          Val32;
+
+
+       /*
+        * Calculate instance if wished. MAC index 0 is the virtual
+        * MAC.
+        */
+       PhysPortMax = pAC->GIni.GIMacsFound;
+       LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
+
+       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
+               LogPortMax--;
+       }
+
+       if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
+               /* Check instance range */
+               if ((Instance < 1) || (Instance > LogPortMax)) {
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_UNKNOWN_INST);
+               }
+               LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
+               Limit = LogPortIndex + 1;
+       }
+
+       else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
+
+               LogPortIndex = 0;
+               Limit = LogPortMax;
+       }
+
+       /*
+        * Perform action
+        */
+       if (Action == SK_PNMI_GET) {
+
+               /*
+                * Check length
+                */
+               switch (Id) {
+
+               case OID_SKGE_PMD:
+               case OID_SKGE_CONNECTOR:
+               case OID_SKGE_LINK_CAP:
+               case OID_SKGE_LINK_MODE:
+               case OID_SKGE_LINK_MODE_STATUS:
+               case OID_SKGE_LINK_STATUS:
+               case OID_SKGE_FLOWCTRL_CAP:
+               case OID_SKGE_FLOWCTRL_MODE:
+               case OID_SKGE_FLOWCTRL_STATUS:
+               case OID_SKGE_PHY_OPERATION_CAP:
+               case OID_SKGE_PHY_OPERATION_MODE:
+               case OID_SKGE_PHY_OPERATION_STATUS:
+               case OID_SKGE_SPEED_CAP:
+               case OID_SKGE_SPEED_MODE:
+               case OID_SKGE_SPEED_STATUS:
+                       if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
+
+                               *pLen = (Limit - LogPortIndex) *
+                                       sizeof(SK_U8);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       break;
+
+       case OID_SKGE_MTU:
+                       if (*pLen < sizeof(SK_U32)) {
+
+                               *pLen = sizeof(SK_U32);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       break;
+
+               default:
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
+                               SK_PNMI_ERR041MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+
+               /*
+                * Update statistic and increment semaphore to indicate
+                * that an update was already done.
+                */
+               if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
+
+                       *pLen = 0;
+                       return (Ret);
+               }
+               pAC->Pnmi.SirqUpdatedFlag ++;
+
+               /*
+                * Get value
+                */
+               Offset = 0;
+               for (; LogPortIndex < Limit; LogPortIndex ++) {
+
+                       switch (Id) {
+
+                       case OID_SKGE_PMD:
+                               *(pBuf + Offset) = pAC->Pnmi.PMD;
+                               Offset += sizeof(char);
+                               break;
+
+                       case OID_SKGE_CONNECTOR:
+                               *(pBuf + Offset) = pAC->Pnmi.Connector;
+                               Offset += sizeof(char);
+                               break;
+
+                       case OID_SKGE_LINK_CAP:
+                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+                                       if (LogPortIndex == 0) {
+
+                                               /* Get value for virtual port */
+                                               VirtualConf(pAC, IoC, Id, pBuf +
+                                                       Offset);
+                                       }
+                                       else {
+                                               /* Get value for physical ports */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+
+                                               *(pBuf + Offset) = pAC->GIni.GP[
+                                                       PhysPortIndex].PLinkCap;
+                                       }
+                                       Offset += sizeof(char);
+                               }
+                               else { /* DualNetMode */
+
+                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkCap;
+                                       Offset += sizeof(char);
+                               }
+                               break;
+
+                       case OID_SKGE_LINK_MODE:
+                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+                                       if (LogPortIndex == 0) {
+
+                                               /* Get value for virtual port */
+                                               VirtualConf(pAC, IoC, Id, pBuf +
+                                               Offset);
+                                       }
+                                       else {
+                                               /* Get value for physical ports */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+
+                                               *(pBuf + Offset) = pAC->GIni.GP[
+                                                       PhysPortIndex].PLinkModeConf;
+                                       }
+                                       Offset += sizeof(char);
+                               }
+                               else { /* DualNetMode */
+
+                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkModeConf;
+                                       Offset += sizeof(char);
+                               }
+                               break;
+
+                       case OID_SKGE_LINK_MODE_STATUS:
+                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+                                       if (LogPortIndex == 0) {
+
+                                               /* Get value for virtual port */
+                                               VirtualConf(pAC, IoC, Id, pBuf +
+                                                       Offset);
+                                       }
+                                       else {
+                                               /* Get value for physical port */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+
+                                               *(pBuf + Offset) =
+                                                       CalculateLinkModeStatus(pAC,
+                                                               IoC, PhysPortIndex);
+                                       }
+                                       Offset += sizeof(char);
+                               }
+                               else { /* DualNetMode */
+                                       *(pBuf + Offset) = CalculateLinkModeStatus(pAC, IoC, NetIndex);
+                                       Offset += sizeof(char);
+                               }
+                               break;
+
+                       case OID_SKGE_LINK_STATUS:
+                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+                                       if (LogPortIndex == 0) {
+
+                                               /* Get value for virtual port */
+                                               VirtualConf(pAC, IoC, Id, pBuf +
+                                                       Offset);
+                                       }
+                                       else {
+                                               /* Get value for physical ports */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+
+                                               *(pBuf + Offset) =
+                                                       CalculateLinkStatus(pAC,
+                                                               IoC, PhysPortIndex);
+                                       }
+                                       Offset += sizeof(char);
+                               }
+                               else { /* DualNetMode */
+
+                                       *(pBuf + Offset) = CalculateLinkStatus(pAC, IoC, NetIndex);
+                                       Offset += sizeof(char);
+                               }
+                               break;
+
+                       case OID_SKGE_FLOWCTRL_CAP:
+                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+                                       if (LogPortIndex == 0) {
+
+                                               /* Get value for virtual port */
+                                               VirtualConf(pAC, IoC, Id, pBuf +
+                                                       Offset);
+                                       }
+                                       else {
+                                               /* Get value for physical ports */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+
+                                               *(pBuf + Offset) = pAC->GIni.GP[
+                                                       PhysPortIndex].PFlowCtrlCap;
+                                       }
+                                       Offset += sizeof(char);
+                               }
+                               else { /* DualNetMode */
+
+                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
+                                       Offset += sizeof(char);
+                               }
+                               break;
+
+                       case OID_SKGE_FLOWCTRL_MODE:
+                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+                                       if (LogPortIndex == 0) {
+
+                                               /* Get value for virtual port */
+                                               VirtualConf(pAC, IoC, Id, pBuf +
+                                                       Offset);
+                                       }
+                                       else {
+                                               /* Get value for physical port */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+
+                                               *(pBuf + Offset) = pAC->GIni.GP[
+                                                       PhysPortIndex].PFlowCtrlMode;
+                                       }
+                                       Offset += sizeof(char);
+                               }
+                               else { /* DualNetMode */
+
+                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
+                                       Offset += sizeof(char);
+                               }
+                               break;
+
+                       case OID_SKGE_FLOWCTRL_STATUS:
+                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+                                       if (LogPortIndex == 0) {
+
+                                               /* Get value for virtual port */
+                                               VirtualConf(pAC, IoC, Id, pBuf +
+                                                       Offset);
+                                       }
+                                       else {
+                                               /* Get value for physical port */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+
+                                               *(pBuf + Offset) = pAC->GIni.GP[
+                                                       PhysPortIndex].PFlowCtrlStatus;
+                                       }
+                                       Offset += sizeof(char);
+                               }
+                               else { /* DualNetMode */
+
+                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
+                                       Offset += sizeof(char);
+                               }
+                               break;
+
+                       case OID_SKGE_PHY_OPERATION_CAP:
+                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+                                       if (LogPortIndex == 0) {
+
+                                               /* Get value for virtual port */
+                                               VirtualConf(pAC, IoC, Id, pBuf +
+                                                       Offset);
+                                       }
+                                       else {
+                                               /* Get value for physical ports */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+
+                                               *(pBuf + Offset) = pAC->GIni.GP[
+                                                       PhysPortIndex].PMSCap;
+                                       }
+                                       Offset += sizeof(char);
+                               }
+                               else { /* DualNetMode */
+
+                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSCap;
+                                       Offset += sizeof(char);
+                               }
+                               break;
+
+                       case OID_SKGE_PHY_OPERATION_MODE:
+                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+                                       if (LogPortIndex == 0) {
+
+                                               /* Get value for virtual port */
+                                               VirtualConf(pAC, IoC, Id, pBuf + Offset);
+                                       }
+                                       else {
+                                               /* Get value for physical port */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+
+                                               *(pBuf + Offset) = pAC->GIni.GP[
+                                                       PhysPortIndex].PMSMode;
+                                       }
+                                       Offset += sizeof(char);
+                               }
+                               else { /* DualNetMode */
+
+                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSMode;
+                                       Offset += sizeof(char);
+                               }
+                               break;
+
+                       case OID_SKGE_PHY_OPERATION_STATUS:
+                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+                                       if (LogPortIndex == 0) {
+
+                                               /* Get value for virtual port */
+                                               VirtualConf(pAC, IoC, Id, pBuf + Offset);
+                                       }
+                                       else {
+                                               /* Get value for physical port */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+
+                                               *(pBuf + Offset) = pAC->GIni.GP[
+                                                       PhysPortIndex].PMSStatus;
+                                       }
+                                       Offset += sizeof(char);
+                               }
+                               else {
+
+                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSStatus;
+                                       Offset += sizeof(char);
+                               }
+                               break;
+
+                       case OID_SKGE_SPEED_CAP:
+                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+                                       if (LogPortIndex == 0) {
+
+                                               /* Get value for virtual port */
+                                               VirtualConf(pAC, IoC, Id, pBuf +
+                                                       Offset);
+                                       }
+                                       else {
+                                               /* Get value for physical ports */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+
+                                               *(pBuf + Offset) = pAC->GIni.GP[
+                                                       PhysPortIndex].PLinkSpeedCap;
+                                       }
+                                       Offset += sizeof(char);
+                               }
+                               else { /* DualNetMode */
+
+                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
+                                       Offset += sizeof(char);
+                               }
+                               break;
+
+                       case OID_SKGE_SPEED_MODE:
+                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+                                       if (LogPortIndex == 0) {
+
+                                               /* Get value for virtual port */
+                                               VirtualConf(pAC, IoC, Id, pBuf + Offset);
+                                       }
+                                       else {
+                                               /* Get value for physical port */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+
+                                               *(pBuf + Offset) = pAC->GIni.GP[
+                                                       PhysPortIndex].PLinkSpeed;
+                                       }
+                                       Offset += sizeof(char);
+                               }
+                               else { /* DualNetMode */
+
+                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeed;
+                                       Offset += sizeof(char);
+                               }
+                               break;
+
+                       case OID_SKGE_SPEED_STATUS:
+                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+                                       if (LogPortIndex == 0) {
+
+                                               /* Get value for virtual port */
+                                               VirtualConf(pAC, IoC, Id, pBuf + Offset);
+                                       }
+                                       else {
+                                               /* Get value for physical port */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+
+                                               *(pBuf + Offset) = pAC->GIni.GP[
+                                                       PhysPortIndex].PLinkSpeedUsed;
+                                       }
+                                       Offset += sizeof(char);
+                               }
+                               else { /* DualNetMode */
+
+                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
+                                       Offset += sizeof(char);
+                               }
+                               break;
+
+                       case OID_SKGE_MTU:
+                               Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
+                               SK_PNMI_STORE_U32(pBuf + Offset, Val32);
+                               Offset += sizeof(SK_U32);
+                               break;
+
+                       default:
+                               SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
+                                       ("MacPrivateConf: Unknown OID should be handled before"));
+
+                               pAC->Pnmi.SirqUpdatedFlag --;
+                               return (SK_PNMI_ERR_GENERAL);
+                       }
+               }
+               *pLen = Offset;
+               pAC->Pnmi.SirqUpdatedFlag --;
+
+               return (SK_PNMI_ERR_OK);
+       }
+
+       /*
+        * From here SET or PRESET action. Check if the passed
+        * buffer length is plausible.
+        */
+       switch (Id) {
+
+       case OID_SKGE_LINK_MODE:
+       case OID_SKGE_FLOWCTRL_MODE:
+       case OID_SKGE_PHY_OPERATION_MODE:
+       case OID_SKGE_SPEED_MODE:
+               if (*pLen < Limit - LogPortIndex) {
+
+                       *pLen = Limit - LogPortIndex;
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               if (*pLen != Limit - LogPortIndex) {
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_BAD_VALUE);
+               }
+               break;
+
+       case OID_SKGE_MTU:
+               if (*pLen < sizeof(SK_U32)) {
+
+                       *pLen = sizeof(SK_U32);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               if (*pLen != sizeof(SK_U32)) {
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_BAD_VALUE);
+               }
+               break;
+
+    default:
+               *pLen = 0;
+               return (SK_PNMI_ERR_READ_ONLY);
+       }
+
+       /*
+        * Perform preset or set
+        */
+       Offset = 0;
+       for (; LogPortIndex < Limit; LogPortIndex ++) {
+
+               switch (Id) {
+
+               case OID_SKGE_LINK_MODE:
+                       /* Check the value range */
+                       Val8 = *(pBuf + Offset);
+                       if (Val8 == 0) {
+
+                               Offset += sizeof(char);
+                               break;
+                       }
+                       if (Val8 < SK_LMODE_HALF ||
+                               (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
+                               (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+
+                       /* The preset ends here */
+                       if (Action == SK_PNMI_PRESET) {
+
+                               return (SK_PNMI_ERR_OK);
+                       }
+
+                       if (LogPortIndex == 0) {
+
+                               /*
+                                * The virtual port consists of all currently
+                                * active ports. Find them and send an event
+                                * with the new link mode to SIRQ.
+                                */
+                               for (PhysPortIndex = 0;
+                                       PhysPortIndex < PhysPortMax;
+                                       PhysPortIndex ++) {
+
+                                       if (!pAC->Pnmi.Port[PhysPortIndex].
+                                               ActiveFlag) {
+
+                                               continue;
+                                       }
+
+                                       EventParam.Para32[0] = PhysPortIndex;
+                                       EventParam.Para32[1] = (SK_U32)Val8;
+                                       if (SkGeSirqEvent(pAC, IoC,
+                                               SK_HWEV_SET_LMODE,
+                                               EventParam) > 0) {
+
+                                               SK_ERR_LOG(pAC, SK_ERRCL_SW,
+                                                       SK_PNMI_ERR043,
+                                                       SK_PNMI_ERR043MSG);
+
+                                               *pLen = 0;
+                                               return (SK_PNMI_ERR_GENERAL);
+                                       }
+                               }
+                       }
+                       else {
+                               /*
+                                * Send an event with the new link mode to
+                                * the SIRQ module.
+                                */
+                               EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
+                                       pAC, LogPortIndex);
+                               EventParam.Para32[1] = (SK_U32)Val8;
+                               if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
+                                       EventParam) > 0) {
+
+                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
+                                               SK_PNMI_ERR043,
+                                               SK_PNMI_ERR043MSG);
+
+                                       *pLen = 0;
+                                       return (SK_PNMI_ERR_GENERAL);
+                               }
+                       }
+                       Offset += sizeof(char);
+                       break;
+
+               case OID_SKGE_FLOWCTRL_MODE:
+                       /* Check the value range */
+                       Val8 = *(pBuf + Offset);
+                       if (Val8 == 0) {
+
+                               Offset += sizeof(char);
+                               break;
+                       }
+                       if (Val8 < SK_FLOW_MODE_NONE ||
+                               (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
+                               (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+
+                       /* The preset ends here */
+                       if (Action == SK_PNMI_PRESET) {
+
+                               return (SK_PNMI_ERR_OK);
+                       }
+
+                       if (LogPortIndex == 0) {
+
+                               /*
+                                * The virtual port consists of all currently
+                                * active ports. Find them and send an event
+                                * with the new flow control mode to SIRQ.
+                                */
+                               for (PhysPortIndex = 0;
+                                       PhysPortIndex < PhysPortMax;
+                                       PhysPortIndex ++) {
+
+                                       if (!pAC->Pnmi.Port[PhysPortIndex].
+                                               ActiveFlag) {
+
+                                               continue;
+                                       }
+
+                                       EventParam.Para32[0] = PhysPortIndex;
+                                       EventParam.Para32[1] = (SK_U32)Val8;
+                                       if (SkGeSirqEvent(pAC, IoC,
+                                               SK_HWEV_SET_FLOWMODE,
+                                               EventParam) > 0) {
+
+                                               SK_ERR_LOG(pAC, SK_ERRCL_SW,
+                                                       SK_PNMI_ERR044,
+                                                       SK_PNMI_ERR044MSG);
+
+                                               *pLen = 0;
+                                               return (SK_PNMI_ERR_GENERAL);
+                                       }
+                               }
+                       }
+                       else {
+                               /*
+                                * Send an event with the new flow control
+                                * mode to the SIRQ module.
+                                */
+                               EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
+                                       pAC, LogPortIndex);
+                               EventParam.Para32[1] = (SK_U32)Val8;
+                               if (SkGeSirqEvent(pAC, IoC,
+                                       SK_HWEV_SET_FLOWMODE, EventParam)
+                                       > 0) {
+
+                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
+                                               SK_PNMI_ERR044,
+                                               SK_PNMI_ERR044MSG);
+
+                                       *pLen = 0;
+                                       return (SK_PNMI_ERR_GENERAL);
+                               }
+                       }
+                       Offset += sizeof(char);
+                       break;
+
+               case OID_SKGE_PHY_OPERATION_MODE :
+                       /* Check the value range */
+                       Val8 = *(pBuf + Offset);
+                       if (Val8 == 0) {
+                               /* mode of this port remains unchanged */
+                               Offset += sizeof(char);
+                               break;
+                       }
+                       if (Val8 < SK_MS_MODE_AUTO ||
+                               (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
+                               (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+
+                       /* The preset ends here */
+                       if (Action == SK_PNMI_PRESET) {
+
+                               return (SK_PNMI_ERR_OK);
+                       }
+
+                       if (LogPortIndex == 0) {
+
+                               /*
+                                * The virtual port consists of all currently
+                                * active ports. Find them and send an event
+                                * with new master/slave (role) mode to SIRQ.
+                                */
+                               for (PhysPortIndex = 0;
+                                       PhysPortIndex < PhysPortMax;
+                                       PhysPortIndex ++) {
+
+                                       if (!pAC->Pnmi.Port[PhysPortIndex].
+                                               ActiveFlag) {
+
+                                               continue;
+                                       }
+
+                                       EventParam.Para32[0] = PhysPortIndex;
+                                       EventParam.Para32[1] = (SK_U32)Val8;
+                                       if (SkGeSirqEvent(pAC, IoC,
+                                               SK_HWEV_SET_ROLE,
+                                               EventParam) > 0) {
+
+                                               SK_ERR_LOG(pAC, SK_ERRCL_SW,
+                                                       SK_PNMI_ERR042,
+                                                       SK_PNMI_ERR042MSG);
+
+                                               *pLen = 0;
+                                               return (SK_PNMI_ERR_GENERAL);
+                                       }
+                               }
+                       }
+                       else {
+                               /*
+                                * Send an event with the new master/slave
+                                * (role) mode to the SIRQ module.
+                                */
+                               EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
+                                       pAC, LogPortIndex);
+                               EventParam.Para32[1] = (SK_U32)Val8;
+                               if (SkGeSirqEvent(pAC, IoC,
+                                       SK_HWEV_SET_ROLE, EventParam) > 0) {
+
+                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
+                                               SK_PNMI_ERR042,
+                                               SK_PNMI_ERR042MSG);
+
+                                       *pLen = 0;
+                                       return (SK_PNMI_ERR_GENERAL);
+                               }
+                       }
+
+                       Offset += sizeof(char);
+                       break;
+
+               case OID_SKGE_SPEED_MODE:
+                       /* Check the value range */
+                       Val8 = *(pBuf + Offset);
+                       if (Val8 == 0) {
+
+                               Offset += sizeof(char);
+                               break;
+                       }
+                       if (Val8 < (SK_LSPEED_AUTO) ||
+                               (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
+                               (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+
+                       /* The preset ends here */
+                       if (Action == SK_PNMI_PRESET) {
+
+                               return (SK_PNMI_ERR_OK);
+                       }
+
+                       if (LogPortIndex == 0) {
+
+                               /*
+                                * The virtual port consists of all currently
+                                * active ports. Find them and send an event
+                                * with the new flow control mode to SIRQ.
+                                */
+                               for (PhysPortIndex = 0;
+                                       PhysPortIndex < PhysPortMax;
+                                       PhysPortIndex ++) {
+
+                                       if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
+
+                                               continue;
+                                       }
+
+                                       EventParam.Para32[0] = PhysPortIndex;
+                                       EventParam.Para32[1] = (SK_U32)Val8;
+                                       if (SkGeSirqEvent(pAC, IoC,
+                                               SK_HWEV_SET_SPEED,
+                                               EventParam) > 0) {
+
+                                               SK_ERR_LOG(pAC, SK_ERRCL_SW,
+                                                       SK_PNMI_ERR045,
+                                                       SK_PNMI_ERR045MSG);
+
+                                               *pLen = 0;
+                                               return (SK_PNMI_ERR_GENERAL);
+                                       }
+                               }
+                       }
+                       else {
+                               /*
+                                * Send an event with the new flow control
+                                * mode to the SIRQ module.
+                                */
+                               EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
+                                       pAC, LogPortIndex);
+                               EventParam.Para32[1] = (SK_U32)Val8;
+                               if (SkGeSirqEvent(pAC, IoC,
+                                       SK_HWEV_SET_SPEED,
+                                       EventParam) > 0) {
+
+                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
+                                               SK_PNMI_ERR045,
+                                               SK_PNMI_ERR045MSG);
+
+                                       *pLen = 0;
+                                       return (SK_PNMI_ERR_GENERAL);
+                               }
+                       }
+                       Offset += sizeof(char);
+                       break;
+
+               case OID_SKGE_MTU :
+                       /* Check the value range */
+                       Val32 = *(SK_U32*)(pBuf + Offset);
+                       if (Val32 == 0) {
+                               /* mtu of this port remains unchanged */
+                               Offset += sizeof(SK_U32);
+                               break;
+                       }
+                       if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+
+                       /* The preset ends here */
+                       if (Action == SK_PNMI_PRESET) {
+                               return (SK_PNMI_ERR_OK);
+                       }
+
+                       if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
+                               return (SK_PNMI_ERR_GENERAL);
+                       }
+
+                       Offset += sizeof(SK_U32);
+                       break;
+
+               default:
+           SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
+               ("MacPrivateConf: Unknown OID should be handled before set"));
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+       }
+
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * Monitor - OID handler function for RLMT_MONITOR_XXX
+ *
+ * Description:
+ *     Because RLMT currently does not support the monitoring of
+ *     remote adapter cards, we return always an empty table.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
+ *                              value range.
+ *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter.
+ */
+PNMI_STATIC int Monitor(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int Action,            /* Get/PreSet/Set action */
+SK_U32 Id,             /* Object ID that is to be processed */
+char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
+unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
+SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       unsigned int    Index;
+       unsigned int    Limit;
+       unsigned int    Offset;
+       unsigned int    Entries;
+
+
+       /*
+        * Calculate instance if wished.
+        */
+/* XXX Not yet implemented. Return always an empty table. */
+       Entries = 0;
+
+       if ((Instance != (SK_U32)(-1))) {
+
+               if ((Instance < 1) || (Instance > Entries)) {
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_UNKNOWN_INST);
+               }
+
+               Index = (unsigned int)Instance - 1;
+               Limit = (unsigned int)Instance;
+       }
+       else {
+               Index = 0;
+               Limit = Entries;
+       }
+
+       /*
+        * Get/Set value
+       */
+       if (Action == SK_PNMI_GET) {
+
+               for (Offset=0; Index < Limit; Index ++) {
+
+                       switch (Id) {
+
+                       case OID_SKGE_RLMT_MONITOR_INDEX:
+                       case OID_SKGE_RLMT_MONITOR_ADDR:
+                       case OID_SKGE_RLMT_MONITOR_ERRS:
+                       case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
+                       case OID_SKGE_RLMT_MONITOR_ADMIN:
+                               break;
+
+                       default:
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
+                                       SK_PNMI_ERR046MSG);
+
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_GENERAL);
+                       }
+               }
+               *pLen = Offset;
+       }
+       else {
+               /* Only MONITOR_ADMIN can be set */
+               if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_READ_ONLY);
+               }
+
+               /* Check if the length is plausible */
+               if (*pLen < (Limit - Index)) {
+
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               /* Okay, we have a wide value range */
+               if (*pLen != (Limit - Index)) {
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_BAD_VALUE);
+               }
+/*
+               for (Offset=0; Index < Limit; Index ++) {
+               }
+*/
+/*
+ * XXX Not yet implemented. Return always BAD_VALUE, because the table
+ * is empty.
+ */
+               *pLen = 0;
+               return (SK_PNMI_ERR_BAD_VALUE);
+       }
+
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * VirtualConf - Calculates the values of configuration OIDs for virtual port
+ *
+ * Description:
+ *     We handle here the get of the configuration group OIDs, which are
+ *     a little bit complicated. The virtual port consists of all currently
+ *     active physical ports. If multiple ports are active and configured
+ *     differently we get in some trouble to return a single value. So we
+ *     get the value of the first active port and compare it with that of
+ *     the other active ports. If they are not the same, we return a value
+ *     that indicates that the state is indeterminated.
+ *
+ * Returns:
+ *     Nothing
+ */
+PNMI_STATIC void VirtualConf(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+SK_U32 Id,             /* Object ID that is to be processed */
+char *pBuf)            /* Buffer to which to mgmt data will be retrieved */
+{
+       unsigned int    PhysPortMax;
+       unsigned int    PhysPortIndex;
+       SK_U8           Val8;
+       SK_BOOL         PortActiveFlag;
+
+
+       *pBuf = 0;
+       PortActiveFlag = SK_FALSE;
+       PhysPortMax = pAC->GIni.GIMacsFound;
+
+       for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
+               PhysPortIndex ++) {
+
+               /* Check if the physical port is active */
+               if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
+
+                       continue;
+               }
+
+               PortActiveFlag = SK_TRUE;
+
+               switch (Id) {
+
+               case OID_SKGE_LINK_CAP:
+
+                       /*
+                        * Different capabilities should not happen, but
+                        * in the case of the cases OR them all together.
+                        * From a curious point of view the virtual port
+                        * is capable of all found capabilities.
+                        */
+                       *pBuf |= pAC->GIni.GP[PhysPortIndex].PLinkCap;
+                       break;
+
+               case OID_SKGE_LINK_MODE:
+                       /* Check if it is the first active port */
+                       if (*pBuf == 0) {
+
+                               *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
+                               continue;
+                       }
+
+                       /*
+                        * If we find an active port with a different link
+                        * mode than the first one we return a value that
+                        * indicates that the link mode is indeterminated.
+                        */
+                       if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkModeConf
+                               ) {
+
+                               *pBuf = SK_LMODE_INDETERMINATED;
+                       }
+                       break;
+
+               case OID_SKGE_LINK_MODE_STATUS:
+                       /* Get the link mode of the physical port */
+                       Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
+
+                       /* Check if it is the first active port */
+                       if (*pBuf == 0) {
+
+                               *pBuf = Val8;
+                               continue;
+                       }
+
+                       /*
+                        * If we find an active port with a different link
+                        * mode status than the first one we return a value
+                        * that indicates that the link mode status is
+                        * indeterminated.
+                        */
+                       if (*pBuf != Val8) {
+
+                               *pBuf = SK_LMODE_STAT_INDETERMINATED;
+                       }
+                       break;
+
+               case OID_SKGE_LINK_STATUS:
+                       /* Get the link status of the physical port */
+                       Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
+
+                       /* Check if it is the first active port */
+                       if (*pBuf == 0) {
+
+                               *pBuf = Val8;
+                               continue;
+                       }
+
+                       /*
+                        * If we find an active port with a different link
+                        * status than the first one, we return a value
+                        * that indicates that the link status is
+                        * indeterminated.
+                        */
+                       if (*pBuf != Val8) {
+
+                               *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
+                       }
+                       break;
+
+               case OID_SKGE_FLOWCTRL_CAP:
+                       /* Check if it is the first active port */
+                       if (*pBuf == 0) {
+
+                               *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
+                               continue;
+                       }
+
+                       /*
+                        * From a curious point of view the virtual port
+                        * is capable of all found capabilities.
+                        */
+                       *pBuf |= pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
+                       break;
+
+               case OID_SKGE_FLOWCTRL_MODE:
+                       /* Check if it is the first active port */
+                       if (*pBuf == 0) {
+
+                               *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
+                               continue;
+                       }
+
+                       /*
+                        * If we find an active port with a different flow
+                        * control mode than the first one, we return a value
+                        * that indicates that the mode is indeterminated.
+                        */
+                       if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode) {
+
+                               *pBuf = SK_FLOW_MODE_INDETERMINATED;
+                       }
+                       break;
+
+               case OID_SKGE_FLOWCTRL_STATUS:
+                       /* Check if it is the first active port */
+                       if (*pBuf == 0) {
+
+                               *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
+                               continue;
+                       }
+
+                       /*
+                        * If we find an active port with a different flow
+                        * control status than the first one, we return a
+                        * value that indicates that the status is
+                        * indeterminated.
+                        */
+                       if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus) {
+
+                               *pBuf = SK_FLOW_STAT_INDETERMINATED;
+                       }
+                       break;
+
+               case OID_SKGE_PHY_OPERATION_CAP:
+                       /* Check if it is the first active port */
+                       if (*pBuf == 0) {
+
+                               *pBuf = pAC->GIni.GP[PhysPortIndex].PMSCap;
+                               continue;
+                       }
+
+                       /*
+                        * From a curious point of view the virtual port
+                        * is capable of all found capabilities.
+                        */
+                       *pBuf |= pAC->GIni.GP[PhysPortIndex].PMSCap;
+                       break;
+
+               case OID_SKGE_PHY_OPERATION_MODE:
+                       /* Check if it is the first active port */
+                       if (*pBuf == 0) {
+
+                               *pBuf = pAC->GIni.GP[PhysPortIndex].PMSMode;
+                               continue;
+                       }
+
+                       /*
+                        * If we find an active port with a different master/
+                        * slave mode than the first one, we return a value
+                        * that indicates that the mode is indeterminated.
+                        */
+                       if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSMode) {
+
+                               *pBuf = SK_MS_MODE_INDETERMINATED;
+                       }
+                       break;
+
+               case OID_SKGE_PHY_OPERATION_STATUS:
+                       /* Check if it is the first active port */
+                       if (*pBuf == 0) {
+
+                               *pBuf = pAC->GIni.GP[PhysPortIndex].PMSStatus;
+                               continue;
+                       }
+
+                       /*
+                        * If we find an active port with a different master/
+                        * slave status than the first one, we return a
+                        * value that indicates that the status is
+                        * indeterminated.
+                        */
+                       if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSStatus) {
+
+                               *pBuf = SK_MS_STAT_INDETERMINATED;
+                       }
+                       break;
+
+               case OID_SKGE_SPEED_MODE:
+                       /* Check if it is the first active port */
+                       if (*pBuf == 0) {
+
+                               *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
+                               continue;
+                       }
+
+                       /*
+                        * If we find an active port with a different flow
+                        * control mode than the first one, we return a value
+                        * that indicates that the mode is indeterminated.
+                        */
+                       if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeed) {
+
+                               *pBuf = SK_LSPEED_INDETERMINATED;
+                       }
+                       break;
+
+               case OID_SKGE_SPEED_STATUS:
+                       /* Check if it is the first active port */
+                       if (*pBuf == 0) {
+
+                               *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
+                               continue;
+                       }
+
+                       /*
+                        * If we find an active port with a different flow
+                        * control status than the first one, we return a
+                        * value that indicates that the status is
+                        * indeterminated.
+                        */
+                       if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed) {
+
+                               *pBuf = SK_LSPEED_STAT_INDETERMINATED;
+                       }
+                       break;
+               }
+       }
+
+       /*
+        * If no port is active return an indeterminated answer
+        */
+       if (!PortActiveFlag) {
+
+               switch (Id) {
+
+               case OID_SKGE_LINK_CAP:
+                       *pBuf = SK_LMODE_CAP_INDETERMINATED;
+                       break;
+
+               case OID_SKGE_LINK_MODE:
+                       *pBuf = SK_LMODE_INDETERMINATED;
+                       break;
+
+               case OID_SKGE_LINK_MODE_STATUS:
+                       *pBuf = SK_LMODE_STAT_INDETERMINATED;
+                       break;
+
+               case OID_SKGE_LINK_STATUS:
+                       *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
+                       break;
+
+               case OID_SKGE_FLOWCTRL_CAP:
+               case OID_SKGE_FLOWCTRL_MODE:
+                       *pBuf = SK_FLOW_MODE_INDETERMINATED;
+                       break;
+
+               case OID_SKGE_FLOWCTRL_STATUS:
+                       *pBuf = SK_FLOW_STAT_INDETERMINATED;
+                       break;
+
+               case OID_SKGE_PHY_OPERATION_CAP:
+                       *pBuf = SK_MS_CAP_INDETERMINATED;
+                       break;
+
+               case OID_SKGE_PHY_OPERATION_MODE:
+                       *pBuf = SK_MS_MODE_INDETERMINATED;
+                       break;
+
+               case OID_SKGE_PHY_OPERATION_STATUS:
+                       *pBuf = SK_MS_STAT_INDETERMINATED;
+                       break;
+               case OID_SKGE_SPEED_CAP:
+                       *pBuf = SK_LSPEED_CAP_INDETERMINATED;
+                       break;
+
+               case OID_SKGE_SPEED_MODE:
+                       *pBuf = SK_LSPEED_INDETERMINATED;
+                       break;
+
+               case OID_SKGE_SPEED_STATUS:
+                       *pBuf = SK_LSPEED_STAT_INDETERMINATED;
+                       break;
+               }
+       }
+}
+
+/*****************************************************************************
+ *
+ * CalculateLinkStatus - Determins the link status of a physical port
+ *
+ * Description:
+ *     Determins the link status the following way:
+ *       LSTAT_PHY_DOWN:  Link is down
+ *       LSTAT_AUTONEG:   Auto-negotiation failed
+ *       LSTAT_LOG_DOWN:  Link is up but RLMT did not yet put the port
+ *                        logically up.
+ *       LSTAT_LOG_UP:    RLMT marked the port as up
+ *
+ * Returns:
+ *     Link status of physical port
+ */
+PNMI_STATIC SK_U8 CalculateLinkStatus(
+SK_AC *pAC,                    /* Pointer to adapter context */
+SK_IOC IoC,                    /* IO context handle */
+unsigned int PhysPortIndex)    /* Physical port index */
+{
+       SK_U8   Result;
+
+
+       if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
+
+               Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
+       }
+       else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
+
+               Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
+                               }
+       else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
+
+               Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
+       }
+       else {
+               Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
+       }
+
+       return (Result);
+}
+
+/*****************************************************************************
+ *
+ * CalculateLinkModeStatus - Determins the link mode status of a phys. port
+ *
+ * Description:
+ *     The COMMON module only tells us if the mode is half or full duplex.
+ *     But in the decade of auto sensing it is usefull for the user to
+ *     know if the mode was negotiated or forced. Therefore we have a
+ *     look to the mode, which was last used by the negotiation process.
+ *
+ * Returns:
+ *     The link mode status
+ */
+PNMI_STATIC SK_U8 CalculateLinkModeStatus(
+SK_AC *pAC,                    /* Pointer to adapter context */
+SK_IOC IoC,                    /* IO context handle */
+unsigned int PhysPortIndex)    /* Physical port index */
+{
+       SK_U8   Result;
+
+
+       /* Get the current mode, which can be full or half duplex */
+       Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
+
+       /* Check if no valid mode could be found (link is down) */
+       if (Result < SK_LMODE_STAT_HALF) {
+
+               Result = SK_LMODE_STAT_UNKNOWN;
+       }
+       else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
+
+               /*
+                * Auto-negotiation was used to bring up the link. Change
+                * the already found duplex status that it indicates
+                * auto-negotiation was involved.
+                */
+               if (Result == SK_LMODE_STAT_HALF) {
+
+                       Result = SK_LMODE_STAT_AUTOHALF;
+               }
+               else if (Result == SK_LMODE_STAT_FULL) {
+
+                       Result = SK_LMODE_STAT_AUTOFULL;
+               }
+       }
+
+       return (Result);
+}
+
+/*****************************************************************************
+ *
+ * GetVpdKeyArr - Obtain an array of VPD keys
+ *
+ * Description:
+ *     Read the VPD keys and build an array of VPD keys, which are
+ *     easy to access.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK       Task successfully performed.
+ *     SK_PNMI_ERR_GENERAL  Something went wrong.
+ */
+PNMI_STATIC int GetVpdKeyArr(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+char *pKeyArr,         /* Ptr KeyArray */
+unsigned int KeyArrLen,        /* Length of array in bytes */
+unsigned int *pKeyNo)  /* Number of keys */
+{
+       unsigned int            BufKeysLen = SK_PNMI_VPD_BUFSIZE;
+       char                    BufKeys[SK_PNMI_VPD_BUFSIZE];
+       unsigned int            StartOffset;
+       unsigned int            Offset;
+       int                     Index;
+       int                     Ret;
+
+
+       SK_MEMSET(pKeyArr, 0, KeyArrLen);
+
+       /*
+        * Get VPD key list
+        */
+       Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
+               (int *)pKeyNo);
+       if (Ret > 0) {
+
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
+                       SK_PNMI_ERR014MSG);
+
+               return (SK_PNMI_ERR_GENERAL);
+       }
+       /* If no keys are available return now */
+       if (*pKeyNo == 0 || BufKeysLen == 0) {
+
+               return (SK_PNMI_ERR_OK);
+       }
+       /*
+        * If the key list is too long for us trunc it and give a
+        * errorlog notification. This case should not happen because
+        * the maximum number of keys is limited due to RAM limitations
+        */
+       if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
+
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
+                       SK_PNMI_ERR015MSG);
+
+               *pKeyNo = SK_PNMI_VPD_ENTRIES;
+       }
+
+       /*
+        * Now build an array of fixed string length size and copy
+        * the keys together.
+        */
+       for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
+               Offset ++) {
+
+               if (BufKeys[Offset] != 0) {
+
+                       continue;
+               }
+
+               if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
+
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
+                               SK_PNMI_ERR016MSG);
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+
+               SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
+                       &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
+
+               Index ++;
+               StartOffset = Offset + 1;
+       }
+
+       /* Last key not zero terminated? Get it anyway */
+       if (StartOffset < Offset) {
+
+               SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
+                       &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
+       }
+
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * SirqUpdate - Let the SIRQ update its internal values
+ *
+ * Description:
+ *     Just to be sure that the SIRQ module holds its internal data
+ *     structures up to date, we send an update event before we make
+ *     any access.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK       Task successfully performed.
+ *     SK_PNMI_ERR_GENERAL  Something went wrong.
+ */
+PNMI_STATIC int SirqUpdate(
+SK_AC *pAC,    /* Pointer to adapter context */
+SK_IOC IoC)    /* IO context handle */
+{
+       SK_EVPARA       EventParam;
+
+
+       /* Was the module already updated during the current PNMI call? */
+       if (pAC->Pnmi.SirqUpdatedFlag > 0) {
+
+               return (SK_PNMI_ERR_OK);
+       }
+
+       /* Send an synchronuous update event to the module */
+       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
+       if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
+
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
+                       SK_PNMI_ERR047MSG);
+
+               return (SK_PNMI_ERR_GENERAL);
+       }
+
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * RlmtUpdate - Let the RLMT update its internal values
+ *
+ * Description:
+ *     Just to be sure that the RLMT module holds its internal data
+ *     structures up to date, we send an update event before we make
+ *     any access.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK       Task successfully performed.
+ *     SK_PNMI_ERR_GENERAL  Something went wrong.
+ */
+PNMI_STATIC int RlmtUpdate(
+SK_AC *pAC,    /* Pointer to adapter context */
+SK_IOC IoC,    /* IO context handle */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       SK_EVPARA       EventParam;
+
+
+       /* Was the module already updated during the current PNMI call? */
+       if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
+
+               return (SK_PNMI_ERR_OK);
+       }
+
+       /* Send an synchronuous update event to the module */
+       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
+       EventParam.Para32[0] = NetIndex;
+       EventParam.Para32[1] = (SK_U32)-1;
+       if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
+
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
+                       SK_PNMI_ERR048MSG);
+
+               return (SK_PNMI_ERR_GENERAL);
+       }
+
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * MacUpdate - Force the XMAC to output the current statistic
+ *
+ * Description:
+ *     The XMAC holds its statistic internally. To obtain the current
+ *     values we send a command so that the statistic data will
+ *     be written to apredefined memory area on the adapter.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK       Task successfully performed.
+ *     SK_PNMI_ERR_GENERAL  Something went wrong.
+ */
+PNMI_STATIC int MacUpdate(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+unsigned int FirstMac, /* Index of the first Mac to be updated */
+unsigned int LastMac)  /* Index of the last Mac to be updated */
+{
+       unsigned int    MacIndex;
+
+       /*
+        * Were the statistics already updated during the
+        * current PNMI call?
+        */
+       if (pAC->Pnmi.MacUpdatedFlag > 0) {
+
+               return (SK_PNMI_ERR_OK);
+       }
+
+       /* Send an update command to all MACs specified */
+       for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
+
+               /*
+                * 2002-09-13 pweber:   Freeze the current sw counters.
+                *                      (That should be done as close as
+                *                      possible to the update of the
+                *                      hw counters)
+                */
+               if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
+                       pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
+               }
+
+               /* 2002-09-13 pweber:  Update the hw counter  */
+               if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
+
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+       }
+
+       return (SK_PNMI_ERR_OK);
+}
+
+/*****************************************************************************
+ *
+ * GetStatVal - Retrieve an XMAC statistic counter
+ *
+ * Description:
+ *     Retrieves the statistic counter of a virtual or physical port. The
+ *     virtual port is identified by the index 0. It consists of all
+ *     currently active ports. To obtain the counter value for this port
+ *     we must add the statistic counter of all active ports. To grant
+ *     continuous counter values for the virtual port even when port
+ *     switches occur we must additionally add a delta value, which was
+ *     calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
+ *
+ * Returns:
+ *     Requested statistic value
+ */
+PNMI_STATIC SK_U64 GetStatVal(
+SK_AC *pAC,                                    /* Pointer to adapter context */
+SK_IOC IoC,                                    /* IO context handle */
+unsigned int LogPortIndex,     /* Index of the logical Port to be processed */
+unsigned int StatIndex,                /* Index to statistic value */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+       unsigned int    PhysPortIndex;
+       unsigned int    PhysPortMax;
+       SK_U64                  Val = 0;
+
+
+       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {   /* Dual net mode */
+
+               PhysPortIndex = NetIndex;
+               Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
+       }
+       else {  /* Single Net mode */
+
+               if (LogPortIndex == 0) {
+
+                       PhysPortMax = pAC->GIni.GIMacsFound;
+
+                       /* Add counter of all active ports */
+                       for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
+                               PhysPortIndex ++) {
+
+                               if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
+
+                                       Val += GetPhysStatVal(pAC, IoC, PhysPortIndex,
+                                               StatIndex);
+                               }
+                       }
+
+                       /* Correct value because of port switches */
+                       Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
+               }
+               else {
+                       /* Get counter value of physical port */
+                       PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
+                       Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
+               }
+       }
+       return (Val);
+}
+
+/*****************************************************************************
+ *
+ * GetPhysStatVal - Get counter value for physical port
+ *
+ * Description:
+ *     Builds a 64bit counter value. Except for the octet counters
+ *     the lower 32bit are counted in hardware and the upper 32bit
+ *     in software by monitoring counter overflow interrupts in the
+ *     event handler. To grant continous counter values during XMAC
+ *     resets (caused by a workaround) we must add a delta value.
+ *     The delta was calculated in the event handler when a
+ *     SK_PNMI_EVT_XMAC_RESET was received.
+ *
+ * Returns:
+ *     Counter value
+ */
+PNMI_STATIC SK_U64 GetPhysStatVal(
+SK_AC *pAC,                                    /* Pointer to adapter context */
+SK_IOC IoC,                                    /* IO context handle */
+unsigned int PhysPortIndex,    /* Index of the logical Port to be processed */
+unsigned int StatIndex)                /* Index to statistic value */
+{
+       SK_U64  Val = 0;
+       SK_U32  LowVal = 0;
+       SK_U32  HighVal = 0;
+       SK_U16  Word;
+       int             MacType;
+
+       SK_PNMI_PORT    *pPnmiPrt;
+       SK_GEMACFUNC    *pFnMac;
+
+       MacType = pAC->GIni.GIMacType;
+
+       /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
+       if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
+               pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
+       }
+       else {
+               pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
+       }
+
+       pFnMac   = &pAC->GIni.GIFunc;
+
+       switch (StatIndex) {
+       case SK_PNMI_HTX:
+       case SK_PNMI_HRX:
+               /* Not supported by GMAC */
+               if (MacType == SK_MAC_GMAC) {
+                       return (Val);
+               }
+
+               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                                                         StatAddr[StatIndex][MacType].Reg,
+                                                                         &LowVal);
+               HighVal = pPnmiPrt->CounterHigh[StatIndex];
+               break;
+
+       case SK_PNMI_HTX_OCTET:
+       case SK_PNMI_HRX_OCTET:
+               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                                                         StatAddr[StatIndex][MacType].Reg,
+                                                                         &HighVal);
+               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                                                         StatAddr[StatIndex + 1][MacType].Reg,
+                                                                         &LowVal);
+               break;
+
+       case SK_PNMI_HTX_BURST:
+       case SK_PNMI_HTX_EXCESS_DEF:
+       case SK_PNMI_HTX_CARRIER:
+               /* Not supported by GMAC */
+               if (MacType == SK_MAC_GMAC) {
+                       return (Val);
+               }
+
+               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                                                         StatAddr[StatIndex][MacType].Reg,
+                                                                         &LowVal);
+               HighVal = pPnmiPrt->CounterHigh[StatIndex];
+               break;
+
+       case SK_PNMI_HTX_MACC:
+               /* GMAC only supports PAUSE MAC control frames */
+               if (MacType == SK_MAC_GMAC) {
+                       Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, SK_PNMI_HTX_PMACC);
+
+                       return (Val);
+               }
+
+               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                                                         StatAddr[StatIndex][MacType].Reg,
+                                                                         &LowVal);
+               HighVal = pPnmiPrt->CounterHigh[StatIndex];
+               break;
+
+       case SK_PNMI_HTX_COL:
+       case SK_PNMI_HRX_UNDERSIZE:
+               /* Not supported by XMAC */
+               if (MacType == SK_MAC_XMAC) {
+                       return (Val);
+               }
+
+               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                                                         StatAddr[StatIndex][MacType].Reg,
+                                                                         &LowVal);
+               HighVal = pPnmiPrt->CounterHigh[StatIndex];
+               break;
+
+
+       case SK_PNMI_HTX_DEFFERAL:
+               /* Not supported by GMAC */
+               if (MacType == SK_MAC_GMAC) {
+                       return (Val);
+               }
+
+               /*
+                * XMAC counts frames with deferred transmission
+                * even in full-duplex mode.
+                *
+                * In full-duplex mode the counter remains constant!
+                */
+               if ((pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
+                       (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_FULL)) {
+
+                       LowVal = 0;
+                       HighVal = 0;
+               }
+               else {
+                       /* Otherwise get contents of hardware register. */
+                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                                                                 StatAddr[SK_PNMI_HTX_DEFFERAL][MacType].Reg,
+                                                                                 &LowVal);
+                       HighVal = pPnmiPrt->CounterHigh[StatIndex];
+               }
+               break;
+
+       case SK_PNMI_HRX_BADOCTET:
+               /* Not supported by XMAC */
+               if (MacType == SK_MAC_XMAC) {
+                       return (Val);
+               }
+
+               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                                                         StatAddr[StatIndex][MacType].Reg,
+                                                                         &HighVal);
+               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                                                         StatAddr[StatIndex + 1][MacType].Reg,
+                                     &LowVal);
+               break;
+
+       case SK_PNMI_HTX_OCTETLOW:
+       case SK_PNMI_HRX_OCTETLOW:
+       case SK_PNMI_HRX_BADOCTETLOW:
+               return (Val);
+
+       case SK_PNMI_HRX_LONGFRAMES:
+               /* For XMAC the SW counter is managed by PNMI */
+               if (MacType == SK_MAC_XMAC) {
+                       return (pPnmiPrt->StatRxLongFrameCts);
+               }
+
+               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                                                         StatAddr[StatIndex][MacType].Reg,
+                                                                         &LowVal);
+               HighVal = pPnmiPrt->CounterHigh[StatIndex];
+               break;
+
+       case SK_PNMI_HRX_TOO_LONG:
+               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                               StatAddr[StatIndex][MacType].Reg,
+                                                               &LowVal);
+               HighVal = pPnmiPrt->CounterHigh[StatIndex];
+
+               Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
+
+               switch (MacType) {
+               case SK_MAC_GMAC:
+                       /* For GMAC the SW counter is additionally managed by PNMI */
+                       Val += pPnmiPrt->StatRxFrameTooLongCts;
+                       break;
+
+               case SK_MAC_XMAC:
+                       /*
+                        * Frames longer than IEEE 802.3 frame max size are counted
+                        * by XMAC in frame_too_long counter even reception of long
+                        * frames was enabled and the frame was correct.
+                        * So correct the value by subtracting RxLongFrame counter.
+                        */
+                       Val -= pPnmiPrt->StatRxLongFrameCts;
+                       break;
+
+               default:
+                       break;
+               }
+
+               LowVal = (SK_U32)Val;
+               HighVal = (SK_U32)(Val >> 32);
+               break;
+
+       case SK_PNMI_HRX_SHORTS:
+               /* Not supported by GMAC */
+               if (MacType == SK_MAC_GMAC) {
+                       /* GM_RXE_FRAG?? */
+                       return (Val);
+               }
+
+               /*
+                * XMAC counts short frame errors even if link down (#10620)
+                *
+                * If link-down the counter remains constant
+                */
+               if (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
+
+                       /* Otherwise get incremental difference */
+                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                                                                 StatAddr[StatIndex][MacType].Reg,
+                                                                                 &LowVal);
+                       HighVal = pPnmiPrt->CounterHigh[StatIndex];
+
+                       Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
+                       Val -= pPnmiPrt->RxShortZeroMark;
+
+                       LowVal = (SK_U32)Val;
+                       HighVal = (SK_U32)(Val >> 32);
+               }
+               break;
+
+       case SK_PNMI_HRX_MACC:
+       case SK_PNMI_HRX_MACC_UNKWN:
+       case SK_PNMI_HRX_BURST:
+       case SK_PNMI_HRX_MISSED:
+       case SK_PNMI_HRX_FRAMING:
+       case SK_PNMI_HRX_CARRIER:
+       case SK_PNMI_HRX_IRLENGTH:
+       case SK_PNMI_HRX_SYMBOL:
+       case SK_PNMI_HRX_CEXT:
+               /* Not supported by GMAC */
+               if (MacType == SK_MAC_GMAC) {
+                       /* GM_RXE_FRAG?? */
+                       return (Val);
+               }
+
+               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                                                         StatAddr[StatIndex][MacType].Reg,
+                                                                         &LowVal);
+               HighVal = pPnmiPrt->CounterHigh[StatIndex];
+               break;
+
+       case SK_PNMI_HRX_PMACC_ERR:
+               /* For GMAC the SW counter is managed by PNMI */
+               if (MacType == SK_MAC_GMAC) {
+                       return (pPnmiPrt->StatRxPMaccErr);
+               }
+
+               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                                                         StatAddr[StatIndex][MacType].Reg,
+                                                                         &LowVal);
+               HighVal = pPnmiPrt->CounterHigh[StatIndex];
+               break;
+
+       /* SW counter managed by PNMI */
+       case SK_PNMI_HTX_SYNC:
+               LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
+               HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
+               break;
+
+       /* SW counter managed by PNMI */
+       case SK_PNMI_HTX_SYNC_OCTET:
+               LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
+               HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
+               break;
+
+       case SK_PNMI_HRX_FCS:
+               /*
+                * Broadcom filters fcs errors and counts it in
+                * Receive Error Counter register
+                */
+               if (pAC->GIni.GP[PhysPortIndex].PhyType == SK_PHY_BCOM) {
+                       /* do not read while not initialized (PHY_READ hangs!)*/
+                       if (pAC->GIni.GP[PhysPortIndex].PState) {
+                               PHY_READ(IoC, &pAC->GIni.GP[PhysPortIndex],
+                                                PhysPortIndex, PHY_BCOM_RE_CTR,
+                                                &Word);
+
+                               LowVal = Word;
+                       }
+                       HighVal = pPnmiPrt->CounterHigh[StatIndex];
+               }
+               else {
+                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                                                                 StatAddr[StatIndex][MacType].Reg,
+                                                                                 &LowVal);
+                       HighVal = pPnmiPrt->CounterHigh[StatIndex];
+               }
+               break;
+
+       default:
+               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                                                         StatAddr[StatIndex][MacType].Reg,
+                                                                         &LowVal);
+               HighVal = pPnmiPrt->CounterHigh[StatIndex];
+               break;
+       }
+
+       Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
+
+       /* Correct value because of possible XMAC reset. XMAC Errata #2 */
+       Val += pPnmiPrt->CounterOffset[StatIndex];
+
+       return (Val);
+}
+
+/*****************************************************************************
+ *
+ * ResetCounter - Set all counters and timestamps to zero
+ *
+ * Description:
+ *     Notifies other common modules which store statistic data to
+ *     reset their counters and finally reset our own counters.
+ *
+ * Returns:
+ *     Nothing
+ */
+PNMI_STATIC void ResetCounter(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+SK_U32 NetIndex)
+{
+       unsigned int    PhysPortIndex;
+       SK_EVPARA       EventParam;
+
+
+       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
+
+       /* Notify sensor module */
+       SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
+
+       /* Notify RLMT module */
+       EventParam.Para32[0] = NetIndex;
+       EventParam.Para32[1] = (SK_U32)-1;
+       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
+       EventParam.Para32[1] = 0;
+
+       /* Notify SIRQ module */
+       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
+
+       /* Notify CSUM module */
+#ifdef SK_USE_CSUM
+       EventParam.Para32[0] = NetIndex;
+       EventParam.Para32[1] = (SK_U32)-1;
+       SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
+               EventParam);
+#endif
+
+       /* Clear XMAC statistic */
+       for (PhysPortIndex = 0; PhysPortIndex <
+               (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
+
+               (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
+
+               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
+                       0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
+               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
+                       CounterOffset, 0, sizeof(pAC->Pnmi.Port[
+                       PhysPortIndex].CounterOffset));
+               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
+                       0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
+               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
+                       StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
+                       PhysPortIndex].StatSyncOctetsCts));
+               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
+                       StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
+                       PhysPortIndex].StatRxLongFrameCts));
+               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
+                                 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
+                       PhysPortIndex].StatRxFrameTooLongCts));
+               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
+                                 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
+                       PhysPortIndex].StatRxPMaccErr));
+       }
+
+       /*
+        * Clear local statistics
+        */
+       SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
+                 sizeof(pAC->Pnmi.VirtualCounterOffset));
+       pAC->Pnmi.RlmtChangeCts = 0;
+       pAC->Pnmi.RlmtChangeTime = 0;
+       SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
+               sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
+       pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
+       pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
+       pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
+       pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
+       pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
+       pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
+       pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
+       pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
+       pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
+       pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
+       pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
+       pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
+}
+
+/*****************************************************************************
+ *
+ * GetTrapEntry - Get an entry in the trap buffer
+ *
+ * Description:
+ *     The trap buffer stores various events. A user application somehow
+ *     gets notified that an event occured and retrieves the trap buffer
+ *     contens (or simply polls the buffer). The buffer is organized as
+ *     a ring which stores the newest traps at the beginning. The oldest
+ *     traps are overwritten by the newest ones. Each trap entry has a
+ *     unique number, so that applications may detect new trap entries.
+ *
+ * Returns:
+ *     A pointer to the trap entry
+ */
+PNMI_STATIC char* GetTrapEntry(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_U32 TrapId,         /* SNMP ID of the trap */
+unsigned int Size)     /* Space needed for trap entry */
+{
+       unsigned int            BufPad = pAC->Pnmi.TrapBufPad;
+       unsigned int            BufFree = pAC->Pnmi.TrapBufFree;
+       unsigned int            Beg = pAC->Pnmi.TrapQueueBeg;
+       unsigned int            End = pAC->Pnmi.TrapQueueEnd;
+       char                    *pBuf = &pAC->Pnmi.TrapBuf[0];
+       int                     Wrap;
+       unsigned int            NeededSpace;
+       unsigned int            EntrySize;
+       SK_U32                  Val32;
+       SK_U64                  Val64;
+
+
+       /* Last byte of entry will get a copy of the entry length */
+       Size ++;
+
+       /*
+        * Calculate needed buffer space */
+       if (Beg >= Size) {
+
+               NeededSpace = Size;
+               Wrap = SK_FALSE;
+       }
+       else {
+               NeededSpace = Beg + Size;
+               Wrap = SK_TRUE;
+       }
+
+       /*
+        * Check if enough buffer space is provided. Otherwise
+        * free some entries. Leave one byte space between begin
+        * and end of buffer to make it possible to detect whether
+        * the buffer is full or empty
+        */
+       while (BufFree < NeededSpace + 1) {
+
+               if (End == 0) {
+
+                       End = SK_PNMI_TRAP_QUEUE_LEN;
+               }
+
+               EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
+               BufFree += EntrySize;
+               End -= EntrySize;
+#ifdef DEBUG
+               SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
+#endif
+               if (End == BufPad) {
+#ifdef DEBUG
+                       SK_MEMSET(pBuf, (char)(-1), End);
+#endif
+                       BufFree += End;
+                       End = 0;
+                       BufPad = 0;
+               }
+       }
+
+       /*
+        * Insert new entry as first entry. Newest entries are
+        * stored at the beginning of the queue.
+        */
+       if (Wrap) {
+
+               BufPad = Beg;
+               Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
+       }
+       else {
+               Beg = Beg - Size;
+       }
+       BufFree -= NeededSpace;
+
+       /* Save the current offsets */
+       pAC->Pnmi.TrapQueueBeg = Beg;
+       pAC->Pnmi.TrapQueueEnd = End;
+       pAC->Pnmi.TrapBufPad = BufPad;
+       pAC->Pnmi.TrapBufFree = BufFree;
+
+       /* Initialize the trap entry */
+       *(pBuf + Beg + Size - 1) = (char)Size;
+       *(pBuf + Beg) = (char)Size;
+       Val32 = (pAC->Pnmi.TrapUnique) ++;
+       SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
+       SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
+       Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
+       SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
+
+       return (pBuf + Beg);
+}
+
+/*****************************************************************************
+ *
+ * CopyTrapQueue - Copies the trap buffer for the TRAP OID
+ *
+ * Description:
+ *     On a query of the TRAP OID the trap buffer contents will be
+ *     copied continuously to the request buffer, which must be large
+ *     enough. No length check is performed.
+ *
+ * Returns:
+ *     Nothing
+ */
+PNMI_STATIC void CopyTrapQueue(
+SK_AC *pAC,            /* Pointer to adapter context */
+char *pDstBuf)         /* Buffer to which the queued traps will be copied */
+{
+       unsigned int    BufPad = pAC->Pnmi.TrapBufPad;
+       unsigned int    Trap = pAC->Pnmi.TrapQueueBeg;
+       unsigned int    End = pAC->Pnmi.TrapQueueEnd;
+       char            *pBuf = &pAC->Pnmi.TrapBuf[0];
+       unsigned int    Len;
+       unsigned int    DstOff = 0;
+
+
+       while (Trap != End) {
+
+               Len = (unsigned int)*(pBuf + Trap);
+
+               /*
+                * Last byte containing a copy of the length will
+                * not be copied.
+                */
+               *(pDstBuf + DstOff) = (char)(Len - 1);
+               SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
+               DstOff += Len - 1;
+
+               Trap += Len;
+               if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
+
+                       Trap = BufPad;
+               }
+       }
+}
+
+/*****************************************************************************
+ *
+ * GetTrapQueueLen - Get the length of the trap buffer
+ *
+ * Description:
+ *     Evaluates the number of currently stored traps and the needed
+ *     buffer size to retrieve them.
+ *
+ * Returns:
+ *     Nothing
+ */
+PNMI_STATIC void GetTrapQueueLen(
+SK_AC *pAC,            /* Pointer to adapter context */
+unsigned int *pLen,    /* Length in Bytes of all queued traps */
+unsigned int *pEntries)        /* Returns number of trapes stored in queue */
+{
+       unsigned int    BufPad = pAC->Pnmi.TrapBufPad;
+       unsigned int    Trap = pAC->Pnmi.TrapQueueBeg;
+       unsigned int    End = pAC->Pnmi.TrapQueueEnd;
+       char            *pBuf = &pAC->Pnmi.TrapBuf[0];
+       unsigned int    Len;
+       unsigned int    Entries = 0;
+       unsigned int    TotalLen = 0;
+
+
+       while (Trap != End) {
+
+               Len = (unsigned int)*(pBuf + Trap);
+               TotalLen += Len - 1;
+               Entries ++;
+
+               Trap += Len;
+               if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
+
+                       Trap = BufPad;
+               }
+       }
+
+       *pEntries = Entries;
+       *pLen = TotalLen;
+}
+
+/*****************************************************************************
+ *
+ * QueueSimpleTrap - Store a simple trap to the trap buffer
+ *
+ * Description:
+ *     A simple trap is a trap with now additional data. It consists
+ *     simply of a trap code.
+ *
+ * Returns:
+ *     Nothing
+ */
+PNMI_STATIC void QueueSimpleTrap(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_U32 TrapId)         /* Type of sensor trap */
+{
+       GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
+}
+
+/*****************************************************************************
+ *
+ * QueueSensorTrap - Stores a sensor trap in the trap buffer
+ *
+ * Description:
+ *     Gets an entry in the trap buffer and fills it with sensor related
+ *     data.
+ *
+ * Returns:
+ *     Nothing
+ */
+PNMI_STATIC void QueueSensorTrap(
+SK_AC *pAC,                    /* Pointer to adapter context */
+SK_U32 TrapId,                 /* Type of sensor trap */
+unsigned int SensorIndex)      /* Index of sensor which caused the trap */
+{
+       char            *pBuf;
+       unsigned int    Offset;
+       unsigned int    DescrLen;
+       SK_U32          Val32;
+
+
+       /* Get trap buffer entry */
+       DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
+       pBuf = GetTrapEntry(pAC, TrapId,
+               SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
+       Offset = SK_PNMI_TRAP_SIMPLE_LEN;
+
+       /* Store additionally sensor trap related data */
+       Val32 = OID_SKGE_SENSOR_INDEX;
+       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
+       *(pBuf + Offset + 4) = 4;
+       Val32 = (SK_U32)SensorIndex;
+       SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
+       Offset += 9;
+
+       Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
+       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
+       *(pBuf + Offset + 4) = (char)DescrLen;
+       SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
+               DescrLen);
+       Offset += DescrLen + 5;
+
+       Val32 = OID_SKGE_SENSOR_TYPE;
+       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
+       *(pBuf + Offset + 4) = 1;
+       *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
+       Offset += 6;
+
+       Val32 = OID_SKGE_SENSOR_VALUE;
+       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
+       *(pBuf + Offset + 4) = 4;
+       Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
+       SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
+}
+
+/*****************************************************************************
+ *
+ * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
+ *
+ * Description:
+ *     Nothing further to explain.
+ *
+ * Returns:
+ *     Nothing
+ */
+PNMI_STATIC void QueueRlmtNewMacTrap(
+SK_AC *pAC,            /* Pointer to adapter context */
+unsigned int ActiveMac)        /* Index (0..n) of the currently active port */
+{
+       char    *pBuf;
+       SK_U32  Val32;
+
+
+       pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
+               SK_PNMI_TRAP_RLMT_CHANGE_LEN);
+
+       Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
+       SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
+       *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
+       *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
+}
+
+/*****************************************************************************
+ *
+ * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
+ *
+ * Description:
+ *     Nothing further to explain.
+ *
+ * Returns:
+ *     Nothing
+ */
+PNMI_STATIC void QueueRlmtPortTrap(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_U32 TrapId,         /* Type of RLMT port trap */
+unsigned int PortIndex)        /* Index of the port, which changed its state */
+{
+       char    *pBuf;
+       SK_U32  Val32;
+
+
+       pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
+
+       Val32 = OID_SKGE_RLMT_PORT_INDEX;
+       SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
+       *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
+       *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
+}
+
+/*****************************************************************************
+ *
+ * CopyMac - Copies a MAC address
+ *
+ * Description:
+ *     Nothing further to explain.
+ *
+ * Returns:
+ *     Nothing
+ */
+PNMI_STATIC void CopyMac(
+char *pDst,            /* Pointer to destination buffer */
+SK_MAC_ADDR *pMac)     /* Pointer of Source */
+{
+       int     i;
+
+
+       for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
+
+               *(pDst + i) = pMac->a[i];
+       }
+}
+
+
+#ifdef SK_POWER_MGMT
+/*****************************************************************************
+ *
+ * PowerManagement - OID handler function of PowerManagement OIDs
+ *
+ * Description:
+ *     The code is simple. No description necessary.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was successfully performed.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter.
+ */
+
+PNMI_STATIC int PowerManagement(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int Action,            /* Get/PreSet/Set action */
+SK_U32 Id,             /* Object ID that is to be processed */
+char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
+unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
+SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
+{
+
+       SK_U32  RetCode = SK_PNMI_ERR_GENERAL;
+
+       /*
+        * Check instance. We only handle single instance variables
+        */
+       if (Instance != (SK_U32)(-1) && Instance != 1) {
+
+               *pLen = 0;
+               return (SK_PNMI_ERR_UNKNOWN_INST);
+       }
+
+       /*
+        * Perform action
+        */
+       if (Action == SK_PNMI_GET) {
+
+               /*
+                * Check length
+                */
+               switch (Id) {
+
+               case OID_PNP_CAPABILITIES:
+                       if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
+
+                               *pLen = sizeof(SK_PNP_CAPABILITIES);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       break;
+
+               case OID_PNP_QUERY_POWER:
+               case OID_PNP_ENABLE_WAKE_UP:
+                       if (*pLen < sizeof(SK_U32)) {
+
+                               *pLen = sizeof(SK_U32);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       break;
+
+               case OID_PNP_SET_POWER:
+               case OID_PNP_ADD_WAKE_UP_PATTERN:
+               case OID_PNP_REMOVE_WAKE_UP_PATTERN:
+                       break;
+
+               default:
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040,
+                               SK_PNMI_ERR040MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+
+               /*
+                * Get value
+                */
+               switch (Id) {
+
+               case OID_PNP_CAPABILITIES:
+                       RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
+                       break;
+
+               case OID_PNP_QUERY_POWER:
+                       /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
+                        the miniport to indicate whether it can transition its NIC
+                        to the low-power state.
+                        A miniport driver must always return NDIS_STATUS_SUCCESS
+                        to a query of OID_PNP_QUERY_POWER. */
+                       RetCode = SK_PNMI_ERR_OK;
+                       break;
+
+                       /* NDIS handles these OIDs as write-only.
+                        * So in case of get action the buffer with written length = 0
+                        * is returned
+                        */
+               case OID_PNP_SET_POWER:
+               case OID_PNP_ADD_WAKE_UP_PATTERN:
+               case OID_PNP_REMOVE_WAKE_UP_PATTERN:
+                       *pLen = 0;
+                       RetCode = SK_PNMI_ERR_OK;
+                       break;
+
+               case OID_PNP_ENABLE_WAKE_UP:
+                       RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
+                       break;
+
+               default:
+                       RetCode = SK_PNMI_ERR_GENERAL;
+                       break;
+               }
+
+               return (RetCode);
+       }
+
+       /*
+        * From here SET or PRESET action. Check if the passed
+        * buffer length is plausible.
+        */
+       switch (Id) {
+       case OID_PNP_SET_POWER:
+       case OID_PNP_ENABLE_WAKE_UP:
+               if (*pLen < sizeof(SK_U32)) {
+
+                       *pLen = sizeof(SK_U32);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               if (*pLen != sizeof(SK_U32)) {
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_BAD_VALUE);
+               }
+               break;
+
+       case OID_PNP_ADD_WAKE_UP_PATTERN:
+       case OID_PNP_REMOVE_WAKE_UP_PATTERN:
+               if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
+
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_BAD_VALUE);
+               }
+               break;
+
+    default:
+               *pLen = 0;
+               return (SK_PNMI_ERR_READ_ONLY);
+       }
+
+       /*
+        * Perform preset or set
+        */
+
+       /* POWER module does not support PRESET action */
+       if (Action == SK_PNMI_PRESET) {
+               return (SK_PNMI_ERR_OK);
+       }
+
+       switch (Id) {
+       case OID_PNP_SET_POWER:
+               RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
+               break;
+
+       case OID_PNP_ADD_WAKE_UP_PATTERN:
+               RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
+               break;
+
+       case OID_PNP_REMOVE_WAKE_UP_PATTERN:
+               RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
+               break;
+
+       case OID_PNP_ENABLE_WAKE_UP:
+               RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
+               break;
+
+       default:
+               RetCode = SK_PNMI_ERR_GENERAL;
+       }
+
+       return (RetCode);
+}
+#endif /* SK_POWER_MGMT */
+
+
+/*****************************************************************************
+ *
+ * Vct - OID handler function of  OIDs
+ *
+ * Description:
+ *     The code is simple. No description necessary.
+ *
+ * Returns:
+ *     SK_PNMI_ERR_OK           The request was performed successfully.
+ *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                              the correct data (e.g. a 32bit value is
+ *                              needed, but a 16 bit value was passed).
+ *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                               exist (e.g. port instance 3 on a two port
+ *                              adapter).
+ *     SK_PNMI_ERR_READ_ONLY    Only the Get action is allowed.
+ *
+ */
+
+PNMI_STATIC int Vct(
+SK_AC *pAC,            /* Pointer to adapter context */
+SK_IOC IoC,            /* IO context handle */
+int Action,            /* Get/PreSet/Set action */
+SK_U32 Id,             /* Object ID that is to be processed */
+char *pBuf,            /* Buffer to which the mgmt data will be copied */
+unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
+SK_U32 Instance,       /* Instance (-1,2..n) that is to be queried */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
+{
+       SK_GEPORT       *pPrt;
+       SK_PNMI_VCT     *pVctBackupData;
+       SK_U32          LogPortMax;
+       SK_U32          PhysPortMax;
+       SK_U32          PhysPortIndex;
+       SK_U32          Limit;
+       SK_U32          Offset;
+       SK_BOOL         Link;
+       SK_U32          RetCode = SK_PNMI_ERR_GENERAL;
+       int             i;
+       SK_EVPARA       Para;
+       SK_U32          CableLength;
+
+       /*
+        * Calculate the port indexes from the instance.
+        */
+       PhysPortMax = pAC->GIni.GIMacsFound;
+       LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
+
+       /* Dual net mode? */
+       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+               LogPortMax--;
+       }
+
+       if ((Instance != (SK_U32) (-1))) {
+               /* Check instance range. */
+               if ((Instance < 2) || (Instance > LogPortMax)) {
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_UNKNOWN_INST);
+               }
+
+               if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                       PhysPortIndex = NetIndex;
+               }
+               else {
+                       PhysPortIndex = Instance - 2;
+               }
+               Limit = PhysPortIndex + 1;
+       }
+       else {  /*
+                * Instance == (SK_U32) (-1), get all Instances of that OID.
+                *
+                * Not implemented yet. May be used in future releases.
+                */
+               PhysPortIndex = 0;
+               Limit = PhysPortMax;
+       }
+
+       pPrt = &pAC->GIni.GP[PhysPortIndex];
+       if (pPrt->PHWLinkUp) {
+               Link = SK_TRUE;
+       }
+       else {
+               Link = SK_FALSE;
+       }
+
+       /*
+        * Check MAC type.
+        */
+       if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
+               *pLen = 0;
+               return (SK_PNMI_ERR_GENERAL);
+       }
+
+       /* Initialize backup data pointer. */
+       pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
+
+       /*
+        * Check action type.
+        */
+       if (Action == SK_PNMI_GET) {
+               /*
+                * Check length.
+                */
+               switch (Id) {
+
+               case OID_SKGE_VCT_GET:
+                       if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
+                               *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       break;
+
+               case OID_SKGE_VCT_STATUS:
+                       if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
+                               *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       break;
+
+               default:
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+
+               /*
+                * Get value.
+                */
+               Offset = 0;
+               for (; PhysPortIndex < Limit; PhysPortIndex++) {
+                       switch (Id) {
+
+                       case OID_SKGE_VCT_GET:
+                               if ((Link == SK_FALSE) &&
+                                       (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
+                                       RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
+                                       if (RetCode == 0) {
+                                               pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
+                                               pAC->Pnmi.VctStatus[PhysPortIndex] |=
+                                                       (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
+
+                                               /* Copy results for later use to PNMI struct. */
+                                               for (i = 0; i < 4; i++)  {
+                                                       if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
+                                                               if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
+                                                                       pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
+                                                               }
+                                                       }
+                                                       if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
+                                                               CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
+                                                       }
+                                                       else {
+                                                               CableLength = 0;
+                                                       }
+                                                       pVctBackupData->PMdiPairLen[i] = CableLength;
+                                                       pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
+                                               }
+
+                                               Para.Para32[0] = PhysPortIndex;
+                                               Para.Para32[1] = -1;
+                                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
+                                               SkEventDispatcher(pAC, IoC);
+                                       }
+                                       else {
+                                               ; /* VCT test is running. */
+                                       }
+                               }
+
+                               /* Get all results. */
+                               CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
+                               Offset += sizeof(SK_U8);
+                               *(pBuf + Offset) = pPrt->PCableLen;
+                               Offset += sizeof(SK_U8);
+                               for (i = 0; i < 4; i++)  {
+                                       SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
+                                       Offset += sizeof(SK_U32);
+                               }
+                               for (i = 0; i < 4; i++)  {
+                                       *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
+                                       Offset += sizeof(SK_U8);
+                               }
+
+                               RetCode = SK_PNMI_ERR_OK;
+                               break;
+
+                       case OID_SKGE_VCT_STATUS:
+                               CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
+                               Offset += sizeof(SK_U8);
+                               RetCode = SK_PNMI_ERR_OK;
+                               break;
+
+                       default:
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_GENERAL);
+                       }
+               } /* for */
+               *pLen = Offset;
+               return (RetCode);
+
+       } /* if SK_PNMI_GET */
+
+       /*
+        * From here SET or PRESET action. Check if the passed
+        * buffer length is plausible.
+        */
+
+       /*
+        * Check length.
+        */
+       switch (Id) {
+       case OID_SKGE_VCT_SET:
+               if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
+                       *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               break;
+
+       default:
+               *pLen = 0;
+               return (SK_PNMI_ERR_GENERAL);
+       }
+
+       /*
+        * Perform preset or set.
+        */
+
+       /* VCT does not support PRESET action. */
+       if (Action == SK_PNMI_PRESET) {
+               return (SK_PNMI_ERR_OK);
+       }
+
+       Offset = 0;
+       for (; PhysPortIndex < Limit; PhysPortIndex++) {
+               switch (Id) {
+               case OID_SKGE_VCT_SET: /* Start VCT test. */
+                       if (Link == SK_FALSE) {
+                               SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
+
+                               RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
+                               if (RetCode == 0) { /* RetCode: 0 => Start! */
+                                       pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
+                                       pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
+                                       pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
+
+                                       /*
+                                        * Start VCT timer counter.
+                                        */
+                                       SK_MEMSET((char *) &Para, 0, sizeof(Para));
+                                       Para.Para32[0] = PhysPortIndex;
+                                       Para.Para32[1] = -1;
+                                       SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
+                                               4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
+                                       SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
+                                       RetCode = SK_PNMI_ERR_OK;
+                               }
+                               else { /* RetCode: 2 => Running! */
+                                       SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
+                                       RetCode = SK_PNMI_ERR_OK;
+                               }
+                       }
+                       else { /* RetCode: 4 => Link! */
+                               RetCode = 4;
+                               SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
+                               RetCode = SK_PNMI_ERR_OK;
+                       }
+                       Offset += sizeof(SK_U32);
+                       break;
+
+               default:
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+       } /* for */
+       *pLen = Offset;
+       return (RetCode);
+
+} /* Vct */
+
+
+PNMI_STATIC void CheckVctStatus(
+SK_AC          *pAC,
+SK_IOC         IoC,
+char           *pBuf,
+SK_U32         Offset,
+SK_U32         PhysPortIndex)
+{
+       SK_GEPORT       *pPrt;
+       SK_PNMI_VCT     *pVctData;
+       SK_U32          RetCode;
+       SK_U8           LinkSpeedUsed;
+
+       pPrt = &pAC->GIni.GP[PhysPortIndex];
+
+       pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
+       pVctData->VctStatus = SK_PNMI_VCT_NONE;
+
+       if (!pPrt->PHWLinkUp) {
+
+               /* Was a VCT test ever made before? */
+               if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
+                       if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
+                               pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
+                       }
+                       else {
+                               pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
+                       }
+               }
+
+               /* Check VCT test status. */
+               RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
+               if (RetCode == 2) { /* VCT test is running. */
+                       pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
+               }
+               else { /* VCT data was copied to pAC here. Check PENDING state. */
+                       if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
+                               pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
+                       }
+               }
+
+               if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
+                       pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
+               }
+       }
+       else {
+
+               /* Was a VCT test ever made before? */
+               if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
+                       pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
+                       pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
+               }
+
+               /* DSP only valid in 100/1000 modes. */
+               LinkSpeedUsed = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
+               if (LinkSpeedUsed != SK_LSPEED_STAT_10MBPS) {
+                       pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
+               }
+       }
+
+} /* CheckVctStatus */
+
+#endif /* CONFIG_SK98 */
diff --git a/drivers/net/sk98lin/skgesirq.c b/drivers/net/sk98lin/skgesirq.c
new file mode 100644 (file)
index 0000000..e5a4f7e
--- /dev/null
@@ -0,0 +1,2417 @@
+/******************************************************************************
+ *
+ * Name:       skgesirq.c
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.83 $
+ * Date:       $Date: 2003/02/05 15:10:59 $
+ * Purpose:    Special IRQ module
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2003 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skgesirq.c,v $
+ *     Revision 1.83  2003/02/05 15:10:59  rschmidt
+ *     Fixed setting of PLinkSpeedUsed in SkHWLinkUp() when
+ *     auto-negotiation is disabled.
+ *     Editorial changes.
+ *
+ *     Revision 1.82  2003/01/29 13:34:33  rschmidt
+ *     Added some typecasts to avoid compiler warnings.
+ *
+ *     Revision 1.81  2002/12/05 10:49:51  rschmidt
+ *     Fixed missing Link Down Event for fiber (Bug Id #10768)
+ *     Added reading of cable length when link is up
+ *     Removed testing of unused error bits in PHY ISR
+ *     Editorial changes.
+ *
+ *     Revision 1.80  2002/11/12 17:15:21  rschmidt
+ *     Replaced SkPnmiGetVar() by ...MacStatistic() in SkMacParity().
+ *     Editorial changes.
+ *
+ *     Revision 1.79  2002/10/14 15:14:51  rschmidt
+ *     Changed clearing of IS_M1_PAR_ERR (MAC 1 Parity Error) in
+ *     SkMacParity() depending on GIChipRev (HW-Bug #8).
+ *     Added error messages for GPHY Auto-Negotiation Error and
+ *     FIFO Overflow/Underrun in SkPhyIsrGmac().
+ *     Editorial changes.
+ *
+ *     Revision 1.78  2002/10/10 15:54:29  mkarl
+ *     changes for PLinkSpeedUsed
+ *
+ *     Revision 1.77  2002/09/12 08:58:51  rwahl
+ *     Retrieve counters needed for XMAC errata workarounds directly because
+ *     PNMI returns corrected counter values (e.g. #10620).
+ *
+ *     Revision 1.76  2002/08/16 15:21:54  rschmidt
+ *     Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis.
+ *     Replaced wrong 1st para pAC with IoC in SK_IN/OUT macros.
+ *     Editorial changes.
+ *
+ *     Revision 1.75  2002/08/12 13:50:47  rschmidt
+ *     Changed clearing of IS_M1_PAR_ERR (MAC 1 Parity Error) in
+ *     SkMacParity() by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE (HW-Bug #8).
+ *     Added clearing of IS_IRQ_TIST_OV and IS_IRQ_SENSOR in SkGeHwErr().
+ *     Corrected handling of Link Up and Auto-Negotiation Over for GPHY.
+ *     in SkGePortCheckUpGmac().
+ *     Editorial changes.
+ *
+ *     Revision 1.74  2002/08/08 16:17:04  rschmidt
+ *     Added PhyType check for SK_HWEV_SET_ROLE event (copper only)
+ *     Changed Link Up check reading PHY Specific Status (YUKON)
+ *     Editorial changes
+ *
+ *     Revision 1.73  2002/07/15 18:36:53  rwahl
+ *     Editorial changes.
+ *
+ *     Revision 1.72  2002/07/15 15:46:26  rschmidt
+ *     Added new event: SK_HWEV_SET_SPEED
+ *     Editorial changes
+ *
+ *     Revision 1.71  2002/06/10 09:34:19  rschmidt
+ *     Editorial changes
+ *
+ *     Revision 1.70  2002/06/05 08:29:18  rschmidt
+ *     SkXmRxTxEnable() replaced by SkMacRxTxEnable().
+ *     Editorial changes.
+ *
+ *     Revision 1.69  2002/04/25 13:03:49  rschmidt
+ *     Changes for handling YUKON.
+ *     Use of #ifdef OTHER_PHY to eliminate code for unused Phy types.
+ *     Replaced all XMAC-access macros by functions: SkMacRxTxDisable(),
+ *     SkMacIrqDisable().
+ *     Added handling for GMAC FIFO in SkMacParity().
+ *     Replaced all SkXm...() functions with SkMac...() to handle also
+ *     YUKON's GMAC.
+ *     Macros for XMAC PHY access PHY_READ(), PHY_WRITE() replaced
+ *     by functions SkXmPhyRead(), SkXmPhyWrite().
+ *     Disabling all PHY interrupts moved to SkMacIrqDisable().
+ *     Added handling for GPHY IRQ in SkGeSirqIsr().
+ *     Removed status parameter from MAC IRQ handler SkMacIrq().
+ *     Added SkGePortCheckUpGmac(), SkPhyIsrGmac() for GMAC.
+ *     Editorial changes
+ *
+ *     Revision 1.68  2002/02/26 15:24:53  rwahl
+ *     Fix: no link with manual configuration (#10673). The previous fix for
+ *     #10639 was removed. So for RLMT mode = CLS the RLMT may switch to
+ *     misconfigured port. It should not occur for the other RLMT modes.
+ *
+ *     Revision 1.67  2001/11/20 09:19:58  rwahl
+ *     Reworked bugfix #10639 (no dependency to RLMT mode).
+ *
+ *     Revision 1.66  2001/10/26 07:52:53  afischer
+ *     Port switching bug in `check local link` mode
+ *
+ *     Revision 1.65  2001/02/23 13:41:51  gklug
+ *     fix: PHYS2INST should be used correctly for Dual Net operation
+ *     chg: do no longer work with older PNMI
+ *
+ *     Revision 1.64  2001/02/15 11:27:04  rassmann
+ *     Working with RLMT v1 if SK_MAX_NETS undefined.
+ *
+ *     Revision 1.63  2001/02/06 10:44:23  mkunz
+ *     - NetIndex added to interface functions of pnmi V4 with dual net support
+ *
+ *     Revision 1.62  2001/01/31 15:31:41  gklug
+ *     fix: problem with autosensing an SR8800 switch
+ *
+ *     Revision 1.61  2000/11/09 11:30:09  rassmann
+ *     WA: Waiting after releasing reset until BCom chip is accessible.
+ *
+ *     Revision 1.60  2000/10/18 12:37:48  cgoos
+ *     Reinserted the comment for version 1.56.
+ *
+ *     Revision 1.59  2000/10/18 12:22:20  cgoos
+ *     Added workaround for half duplex hangup.
+ *
+ *     Revision 1.58  2000/09/28 13:06:04  gklug
+ *     fix: BCom may NOT be touched if XMAC is in RESET state
+ *
+ *     Revision 1.57  2000/09/08 12:38:39  cgoos
+ *     Added forgotten variable declaration.
+ *
+ *     Revision 1.56  2000/09/08 08:12:13  cgoos
+ *     Changed handling of parity errors in SkGeHwErr (correct reset of error).
+ *
+ *     Revision 1.55  2000/06/19 08:36:25  cgoos
+ *     Changed comment.
+ *
+ *     Revision 1.54  2000/05/22 08:45:57  malthoff
+ *     Fix: #10523 is valid for all BCom PHYs.
+ *
+ *     Revision 1.53  2000/05/19 10:20:30  cgoos
+ *     Removed Solaris debug output code.
+ *
+ *     Revision 1.52  2000/05/19 10:19:37  cgoos
+ *     Added PHY state check in HWLinkDown.
+ *     Move PHY interrupt code to IS_EXT_REG case in SkGeSirqIsr.
+ *
+ *     Revision 1.51  2000/05/18 05:56:20  cgoos
+ *     Fixed typo.
+ *
+ *     Revision 1.50  2000/05/17 12:49:49  malthoff
+ *     Fixes BCom link bugs (#10523).
+ *
+ *     Revision 1.49  1999/12/17 11:02:50  gklug
+ *     fix: read PHY_STAT of Broadcom chip more often to assure good status
+ *
+ *     Revision 1.48  1999/12/06 10:01:17  cgoos
+ *     Added SET function for Role.
+ *
+ *     Revision 1.47  1999/11/22 13:34:24  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.46  1999/09/16 10:30:07  cgoos
+ *     Removed debugging output statement from Linux.
+ *
+ *     Revision 1.45  1999/09/16 07:32:55  cgoos
+ *     Fixed dual-port copperfield bug (PHY_READ from resetted port).
+ *     Removed some unused variables.
+ *
+ *     Revision 1.44  1999/08/03 15:25:04  cgoos
+ *     Removed workaround for disabled interrupts in half duplex mode.
+ *
+ *     Revision 1.43  1999/08/03 14:27:58  cgoos
+ *     Removed SENSE mode code from SkGePortCheckUpBcom.
+ *
+ *     Revision 1.42  1999/07/26 09:16:54  cgoos
+ *     Added some typecasts to avoid compiler warnings.
+ *
+ *     Revision 1.41  1999/05/19 07:28:59  cgoos
+ *     Changes for 1000Base-T.
+ *
+ *     Revision 1.40  1999/04/08 13:59:39  gklug
+ *     fix: problem with 3Com switches endless RESTARTs
+ *
+ *     Revision 1.39  1999/03/08 10:10:52  gklug
+ *     fix: AutoSensing did switch to next mode even if LiPa indicated offline
+ *
+ *     Revision 1.38  1999/03/08 09:49:03  gklug
+ *     fix: Bug using pAC instead of IoC, causing AIX problems
+ *     fix: change compare for Linux compiler bug workaround
+ *
+ *     Revision 1.37  1999/01/28 14:51:33  gklug
+ *     fix: monitor for autosensing and extra RESETS the RX on wire counters
+ *
+ *     Revision 1.36  1999/01/22 09:19:55  gklug
+ *     fix: Init DupMode and InitPauseMd are now called in RxTxEnable
+ *
+ *     Revision 1.35  1998/12/11 15:22:59  gklug
+ *     chg: autosensing: check for receive if manual mode was guessed
+ *     chg: simplified workaround for XMAC errata
+ *     chg: wait additional 100 ms before link goes up.
+ *     chg: autoneg timeout to 600 ms
+ *     chg: restart autoneg even if configured to autonegotiation
+ *
+ *     Revision 1.34  1998/12/10 10:33:14  gklug
+ *     add: more debug messages
+ *     fix: do a new InitPhy if link went down (AutoSensing problem)
+ *     chg: Check for zero shorts if link is NOT up
+ *     chg: reset Port if link goes down
+ *     chg: wait additional 100 ms when link comes up to check shorts
+ *     fix: dummy read extended autoneg status to prevent link going down immediately
+ *
+ *     Revision 1.33  1998/12/07 12:18:29  gklug
+ *     add: refinement of autosense mode: take into account the autoneg cap of LiPa
+ *
+ *     Revision 1.32  1998/12/07 07:11:21  gklug
+ *     fix: compiler warning
+ *
+ *     Revision 1.31  1998/12/02 09:29:05  gklug
+ *     fix: WA XMAC Errata: FCSCt check was not correct.
+ *     fix: WA XMAC Errata: Prec Counter were NOT updated in case of short checks.
+ *     fix: Clear Stat : now clears the Prev counters of all known Ports
+ *
+ *     Revision 1.30  1998/12/01 10:54:15  gklug
+ *     dd: workaround for XMAC errata changed. Check RX count and CRC err Count, too.
+ *
+ *     Revision 1.29  1998/12/01 10:01:53  gklug
+ *     fix: if MAC IRQ occurs during port down, this will be handled correctly
+ *
+ *     Revision 1.28  1998/11/26 16:22:11  gklug
+ *     fix: bug in autosense if manual modes are used
+ *
+ *     Revision 1.27  1998/11/26 15:50:06  gklug
+ *     fix: PNMI needs to set PLinkModeConf
+ *
+ *     Revision 1.26  1998/11/26 14:51:58  gklug
+ *     add: AutoSensing functionalty
+ *
+ *     Revision 1.25  1998/11/26 07:34:37  gklug
+ *     fix: Init PrevShorts when restarting port due to Link connection
+ *
+ *     Revision 1.24  1998/11/25 10:57:32  gklug
+ *     fix: remove unreferenced local vars
+ *
+ *     Revision 1.23  1998/11/25 08:26:40  gklug
+ *     fix: don't do a RESET on a starting or stopping port
+ *
+ *     Revision 1.22  1998/11/24 13:29:44  gklug
+ *     add: Workaround for MAC parity errata
+ *
+ *     Revision 1.21  1998/11/18 15:31:06  gklug
+ *     fix: lint bugs
+ *
+ *     Revision 1.20  1998/11/18 12:58:54  gklug
+ *     fix: use PNMI query instead of hardware access
+ *
+ *     Revision 1.19  1998/11/18 12:54:55  gklug
+ *     chg: add new workaround for XMAC Errata
+ *     add: short event counter monitoring on active link too
+ *
+ *     Revision 1.18  1998/11/13 14:27:41  malthoff
+ *     Bug Fix: Packet Arbiter Timeout was not cleared correctly
+ *     for timeout on TX1 and TX2.
+ *
+ *     Revision 1.17  1998/11/04 07:01:59  cgoos
+ *     Moved HW link poll sequence.
+ *     Added call to SkXmRxTxEnable.
+ *
+ *     Revision 1.16  1998/11/03 13:46:03  gklug
+ *     add: functionality of SET_LMODE and SET_FLOW_MODE
+ *     fix: send RLMT LinkDown event when Port stop is given with LinkUp
+ *
+ *     Revision 1.15  1998/11/03 12:56:47  gklug
+ *     fix: Needs more events
+ *
+ *     Revision 1.14  1998/10/30 07:36:35  gklug
+ *     rmv: unnecessary code
+ *
+ *     Revision 1.13  1998/10/29 15:21:57  gklug
+ *     add: Poll link feature for activating HW link
+ *     fix: Deactivate HWLink when Port STOP is given
+ *
+ *     Revision 1.12  1998/10/28 07:38:57  cgoos
+ *     Checking link status at begin of SkHWLinkUp.
+ *
+ *     Revision 1.11  1998/10/22 09:46:50  gklug
+ *     fix SysKonnectFileId typo
+ *
+ *     Revision 1.10  1998/10/14 13:57:47  gklug
+ *     add: Port start/stop event
+ *
+ *     Revision 1.9  1998/10/14 05:48:29  cgoos
+ *     Added definition for Para.
+ *
+ *     Revision 1.8  1998/10/14 05:40:09  gklug
+ *     add: Hardware Linkup signal used
+ *
+ *     Revision 1.7  1998/10/09 06:50:20  malthoff
+ *     Remove ID_sccs by SysKonnectFileId.
+ *
+ *     Revision 1.6  1998/10/08 09:11:49  gklug
+ *     add: clear IRQ commands
+ *
+ *     Revision 1.5  1998/10/02 14:27:35  cgoos
+ *     Fixed some typos and wrong event names.
+ *
+ *     Revision 1.4  1998/10/02 06:24:17  gklug
+ *     add: HW error function
+ *     fix: OUT macros
+ *
+ *     Revision 1.3  1998/10/01 07:03:00  gklug
+ *     add: ISR for the usual interrupt source register
+ *
+ *     Revision 1.2  1998/09/03 13:50:33  gklug
+ *     add: function prototypes
+ *
+ *     Revision 1.1  1998/08/27 11:50:21  gklug
+ *     initial revision
+ *
+ *
+ *
+ ******************************************************************************/
+
+#include <config.h>
+
+#ifdef CONFIG_SK98
+
+/*
+ *     Special Interrupt handler
+ *
+ *     The following abstract should show how this module is included
+ *     in the driver path:
+ *
+ *     In the ISR of the driver the bits for frame transmission complete and
+ *     for receive complete are checked and handled by the driver itself.
+ *     The bits of the slow path mask are checked after that and then the
+ *     entry into the so-called "slow path" is prepared. It is an implementors
+ *     decision whether this is executed directly or just scheduled by
+ *     disabling the mask. In the interrupt service routine some events may be
+ *     generated, so it would be a good idea to call the EventDispatcher
+ *     right after this ISR.
+ *
+ *     The Interrupt source register of the adapter is NOT read by this module.
+ *  SO if the drivers implementor needs a while loop around the
+ *     slow data paths interrupt bits, he needs to call the SkGeSirqIsr() for
+ *     each loop entered.
+ *
+ *     However, the MAC Interrupt status registers are read in a while loop.
+ *
+ */
+
+static const char SysKonnectFileId[] =
+       "$Id: skgesirq.c,v 1.83 2003/02/05 15:10:59 rschmidt Exp $" ;
+
+#include "h/skdrv1st.h"                /* Driver Specific Definitions */
+#include "h/skgepnmi.h"                /* PNMI Definitions */
+#include "h/skrlmt.h"          /* RLMT Definitions */
+#include "h/skdrv2nd.h"                /* Adapter Control and Driver specific Def. */
+
+/* local function prototypes */
+static int     SkGePortCheckUpXmac(SK_AC*, SK_IOC, int);
+static int     SkGePortCheckUpBcom(SK_AC*, SK_IOC, int);
+static int     SkGePortCheckUpGmac(SK_AC*, SK_IOC, int);
+static void    SkPhyIsrBcom(SK_AC*, SK_IOC, int, SK_U16);
+static void    SkPhyIsrGmac(SK_AC*, SK_IOC, int, SK_U16);
+#ifdef OTHER_PHY
+static int     SkGePortCheckUpLone(SK_AC*, SK_IOC, int);
+static int     SkGePortCheckUpNat(SK_AC*, SK_IOC, int);
+static void    SkPhyIsrLone(SK_AC*, SK_IOC, int, SK_U16);
+#endif /* OTHER_PHY */
+
+/*
+ * array of Rx counter from XMAC which are checked
+ * in AutoSense mode to check whether a link is not able to auto-negotiate.
+ */
+static const SK_U16 SkGeRxRegs[]= {
+       XM_RXF_64B,
+       XM_RXF_127B,
+       XM_RXF_255B,
+       XM_RXF_511B,
+       XM_RXF_1023B,
+       XM_RXF_MAX_SZ
+} ;
+
+#ifdef __C2MAN__
+/*
+ *     Special IRQ function
+ *
+ *     General Description:
+ *
+ */
+intro()
+{}
+#endif
+
+/* Define return codes of SkGePortCheckUp and CheckShort */
+#define        SK_HW_PS_NONE           0       /* No action needed */
+#define        SK_HW_PS_RESTART        1       /* Restart needed */
+#define        SK_HW_PS_LINK           2       /* Link Up actions needed */
+
+/******************************************************************************
+ *
+ *     SkHWInitDefSense() - Default Autosensing mode initialization
+ *
+ * Description: sets the PLinkMode for HWInit
+ *
+ * Returns: N/A
+ */
+static void SkHWInitDefSense(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* IO context */
+int            Port)   /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       pPrt->PAutoNegTimeOut = 0;
+
+       if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
+               pPrt->PLinkMode = pPrt->PLinkModeConf;
+               return;
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+               ("AutoSensing: First mode %d on Port %d\n",
+               (int)SK_LMODE_AUTOFULL, Port));
+
+       pPrt->PLinkMode = SK_LMODE_AUTOFULL;
+
+       return;
+}      /* SkHWInitDefSense */
+
+
+/******************************************************************************
+ *
+ *     SkHWSenseGetNext() - Get Next Autosensing Mode
+ *
+ * Description: gets the appropriate next mode
+ *
+ * Note:
+ *
+ */
+SK_U8 SkHWSenseGetNext(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* IO context */
+int            Port)   /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       pPrt->PAutoNegTimeOut = 0;
+
+       if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
+               /* Leave all as configured */
+               return(pPrt->PLinkModeConf);
+       }
+
+       if (pPrt->PLinkMode == SK_LMODE_AUTOFULL) {
+               /* Return next mode AUTOBOTH */
+               return(SK_LMODE_AUTOBOTH);
+       }
+
+       /* Return default autofull */
+       return(SK_LMODE_AUTOFULL);
+}      /* SkHWSenseGetNext */
+
+
+/******************************************************************************
+ *
+ *     SkHWSenseSetNext() - Autosensing Set next mode
+ *
+ * Description:        sets the appropriate next mode
+ *
+ * Returns: N/A
+ */
+void SkHWSenseSetNext(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+SK_U8  NewMode)        /* New Mode to be written in sense mode */
+{
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       pPrt->PAutoNegTimeOut = 0;
+
+       if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
+               return;
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+               ("AutoSensing: next mode %d on Port %d\n",
+               (int)NewMode, Port));
+
+       pPrt->PLinkMode = NewMode;
+
+       return;
+}      /* SkHWSenseSetNext */
+
+
+/******************************************************************************
+ *
+ *     SkHWLinkDown() - Link Down handling
+ *
+ * Description: handles the hardware link down signal
+ *
+ * Returns: N/A
+ */
+void SkHWLinkDown(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       /* Disable all MAC interrupts */
+       SkMacIrqDisable(pAC, IoC, Port);
+
+       /* Disable Receiver and Transmitter */
+       SkMacRxTxDisable(pAC, IoC, Port);
+
+       /* Init default sense mode */
+       SkHWInitDefSense(pAC, IoC, Port);
+
+       if (!pPrt->PHWLinkUp) {
+               return;
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+               ("Link down Port %d\n", Port));
+
+       /* Set Link to DOWN */
+       pPrt->PHWLinkUp = SK_FALSE;
+
+       /* Reset Port stati */
+       pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN;
+       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
+       pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_INDETERMINATED;
+
+       /* Re-init Phy especially when the AutoSense default is set now */
+       SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
+
+       /* GP0: used for workaround of Rev. C Errata 2 */
+
+       /* Do NOT signal to RLMT */
+
+       /* Do NOT start the timer here */
+}      /* SkHWLinkDown */
+
+
+/******************************************************************************
+ *
+ *     SkHWLinkUp() - Link Up handling
+ *
+ * Description: handles the hardware link up signal
+ *
+ * Returns: N/A
+ */
+void SkHWLinkUp(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* IO context */
+int            Port)   /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       if (pPrt->PHWLinkUp) {
+               /* We do NOT need to proceed on active link */
+               return;
+       }
+
+       pPrt->PHWLinkUp = SK_TRUE;
+       pPrt->PAutoNegFail = SK_FALSE;
+       pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN;
+
+       if (pPrt->PLinkMode != SK_LMODE_AUTOHALF &&
+           pPrt->PLinkMode != SK_LMODE_AUTOFULL &&
+           pPrt->PLinkMode != SK_LMODE_AUTOBOTH) {
+               /* Link is up and no Auto-negotiation should be done */
+
+               /* Link speed should be the configured one */
+               switch (pPrt->PLinkSpeed) {
+               case SK_LSPEED_AUTO:
+                       /* default is 1000 Mbps */
+               case SK_LSPEED_1000MBPS:
+                       pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
+                       break;
+               case SK_LSPEED_100MBPS:
+                       pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_100MBPS;
+                       break;
+               case SK_LSPEED_10MBPS:
+                       pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_10MBPS;
+                       break;
+               }
+
+               /* Set Link Mode Status */
+               if (pPrt->PLinkMode == SK_LMODE_FULL) {
+                       pPrt->PLinkModeStatus = SK_LMODE_STAT_FULL;
+               }
+               else {
+                       pPrt->PLinkModeStatus = SK_LMODE_STAT_HALF;
+               }
+
+               /* No flow control without auto-negotiation */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
+
+               /* enable Rx/Tx */
+               SkMacRxTxEnable(pAC, IoC, Port);
+       }
+}      /* SkHWLinkUp */
+
+
+/******************************************************************************
+ *
+ *     SkMacParity() - MAC parity workaround
+ *
+ * Description: handles MAC parity errors correctly
+ *
+ * Returns: N/A
+ */
+static void SkMacParity(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* IO context */
+int            Port)   /* Port Index of the port failed */
+{
+       SK_EVPARA       Para;
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+       SK_U32          TxMax;          /* TxMax Counter */
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       /* Clear IRQ Tx Parity Error */
+       if (pAC->GIni.GIGenesis) {
+               SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_PERR);
+       }
+       else {
+               /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */
+               SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T),
+                       (SK_U8)((pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE));
+       }
+
+       if (pPrt->PCheckPar) {
+               if (Port == MAC_1) {
+                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG);
+               }
+               else {
+                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E017, SKERR_SIRQ_E017MSG);
+               }
+               Para.Para64 = Port;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+               Para.Para32[0] = Port;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+
+               return;
+       }
+
+       /* Check whether frames with a size of 1k were sent */
+       if (pAC->GIni.GIGenesis) {
+               /* Snap statistic counters */
+               (void)SkXmUpdateStats(pAC, IoC, Port);
+
+               (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax);
+       }
+       else {
+               (void)SkGmMacStatistic(pAC, IoC, Port, GM_TXF_1518B, &TxMax);
+       }
+
+       if (TxMax > 0) {
+               /* From now on check the parity */
+               pPrt->PCheckPar = SK_TRUE;
+       }
+}      /* SkMacParity */
+
+
+/******************************************************************************
+ *
+ *     SkGeHwErr() - Hardware Error service routine
+ *
+ * Description: handles all HW Error interrupts
+ *
+ * Returns: N/A
+ */
+static void SkGeHwErr(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+SK_U32 HwStatus)       /* Interrupt status word */
+{
+       SK_EVPARA       Para;
+       SK_U16          Word;
+
+       if ((HwStatus & (IS_IRQ_MST_ERR | IS_IRQ_STAT)) != 0) {
+               /* PCI Errors occured */
+               if ((HwStatus & IS_IRQ_STAT) != 0) {
+                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG);
+               }
+               else {
+                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG);
+               }
+
+               /* Reset all bits in the PCI STATUS register */
+               SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
+
+               SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+               SK_OUT16(IoC, PCI_C(PCI_STATUS), Word | PCI_ERRBITS);
+               SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+               Para.Para64 = 0;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
+       }
+
+       if (pAC->GIni.GIGenesis) {
+               if ((HwStatus & IS_NO_STAT_M1) != 0) {
+                       /* Ignore it */
+                       /* This situation is also indicated in the descriptor */
+                       SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INSTAT);
+               }
+
+               if ((HwStatus & IS_NO_STAT_M2) != 0) {
+                       /* Ignore it */
+                       /* This situation is also indicated in the descriptor */
+                       SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INSTAT);
+               }
+
+               if ((HwStatus & IS_NO_TIST_M1) != 0) {
+                       /* Ignore it */
+                       /* This situation is also indicated in the descriptor */
+                       SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INTIST);
+               }
+
+               if ((HwStatus & IS_NO_TIST_M2) != 0) {
+                       /* Ignore it */
+                       /* This situation is also indicated in the descriptor */
+                       SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INTIST);
+               }
+       }
+       else {  /* YUKON */
+               /* This is necessary only for Rx timing measurements */
+               if ((HwStatus & IS_IRQ_TIST_OV) != 0) {
+                       /* Clear Time Stamp Timer IRQ */
+                       SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ);
+               }
+
+               if ((HwStatus & IS_IRQ_SENSOR) != 0) {
+                       /* Clear I2C IRQ */
+                       SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
+               }
+       }
+
+       if ((HwStatus & IS_RAM_RD_PAR) != 0) {
+               SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR);
+               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG);
+               Para.Para64 = 0;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
+       }
+
+       if ((HwStatus & IS_RAM_WR_PAR) != 0) {
+               SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR);
+               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG);
+               Para.Para64 = 0;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
+       }
+
+       if ((HwStatus & IS_M1_PAR_ERR) != 0) {
+               SkMacParity(pAC, IoC, MAC_1);
+       }
+
+       if ((HwStatus & IS_M2_PAR_ERR) != 0) {
+               SkMacParity(pAC, IoC, MAC_2);
+       }
+
+       if ((HwStatus & IS_R1_PAR_ERR) != 0) {
+               /* Clear IRQ */
+               SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_P);
+
+               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG);
+               Para.Para64 = MAC_1;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+               Para.Para32[0] = MAC_1;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+       }
+
+       if ((HwStatus & IS_R2_PAR_ERR) != 0) {
+               /* Clear IRQ */
+               SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_P);
+
+               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG);
+               Para.Para64 = MAC_2;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+               Para.Para32[0] = MAC_2;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+       }
+}      /* SkGeHwErr */
+
+
+/******************************************************************************
+ *
+ *     SkGeSirqIsr() - Special Interrupt Service Routine
+ *
+ * Description: handles all non data transfer specific interrupts (slow path)
+ *
+ * Returns: N/A
+ */
+void SkGeSirqIsr(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+SK_U32 Istatus)        /* Interrupt status word */
+{
+       SK_EVPARA       Para;
+       SK_U32          RegVal32;       /* Read register value */
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+       unsigned        Len;
+       SK_U64          Octets;
+       SK_U16          PhyInt;
+       SK_U16          PhyIMsk;
+       int                     i;
+
+       if ((Istatus & IS_HW_ERR) != 0) {
+               /* read the HW Error Interrupt source */
+               SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
+
+               SkGeHwErr(pAC, IoC, RegVal32);
+       }
+
+       /*
+        * Packet Timeout interrupts
+        */
+       /* Check whether MACs are correctly initialized */
+       if (((Istatus & (IS_PA_TO_RX1 | IS_PA_TO_TX1)) != 0) &&
+               pAC->GIni.GP[MAC_1].PState == SK_PRT_RESET) {
+               /* MAC 1 was not initialized but Packet timeout occured */
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E004,
+                       SKERR_SIRQ_E004MSG);
+       }
+
+       if (((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) != 0) &&
+           pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) {
+               /* MAC 2 was not initialized but Packet timeout occured */
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005,
+                       SKERR_SIRQ_E005MSG);
+       }
+
+       if ((Istatus & IS_PA_TO_RX1) != 0) {
+               /* Means network is filling us up */
+               SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E002,
+                       SKERR_SIRQ_E002MSG);
+               SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX1);
+       }
+
+       if ((Istatus & IS_PA_TO_RX2) != 0) {
+               /* Means network is filling us up */
+               SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E003,
+                       SKERR_SIRQ_E003MSG);
+               SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX2);
+       }
+
+       if ((Istatus & IS_PA_TO_TX1) != 0) {
+
+               pPrt = &pAC->GIni.GP[0];
+
+               /* May be a normal situation in a server with a slow network */
+               SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1);
+
+               /*
+                * workaround: if in half duplex mode, check for Tx hangup.
+                * Read number of TX'ed bytes, wait for 10 ms, then compare
+                * the number with current value. If nothing changed, we assume
+                * that Tx is hanging and do a FIFO flush (see event routine).
+                */
+               if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
+                   pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
+                   !pPrt->HalfDupTimerActive) {
+                       /*
+                        * many more pack. arb. timeouts may come in between,
+                        * we ignore those
+                        */
+                       pPrt->HalfDupTimerActive = SK_TRUE;
+
+                       Len = sizeof(SK_U64);
+                       SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
+                               &Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(pAC, 0),
+                               pAC->Rlmt.Port[0].Net->NetNumber);
+
+                       pPrt->LastOctets = Octets;
+
+                       Para.Para32[0] = 0;
+                       SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
+                               SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
+               }
+       }
+
+       if ((Istatus & IS_PA_TO_TX2) != 0) {
+
+               pPrt = &pAC->GIni.GP[1];
+
+               /* May be a normal situation in a server with a slow network */
+               SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2);
+
+               /* workaround: see above */
+               if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
+                    pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
+                   !pPrt->HalfDupTimerActive) {
+                       pPrt->HalfDupTimerActive = SK_TRUE;
+
+                       Len = sizeof(SK_U64);
+                       SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
+                               &Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(pAC, 1),
+                               pAC->Rlmt.Port[1].Net->NetNumber);
+
+                       pPrt->LastOctets = Octets;
+
+                       Para.Para32[0] = 1;
+                       SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
+                               SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
+               }
+       }
+
+       /* Check interrupts of the particular queues */
+       if ((Istatus & IS_R1_C) != 0) {
+               /* Clear IRQ */
+               SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C);
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006,
+                       SKERR_SIRQ_E006MSG);
+               Para.Para64 = MAC_1;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+               Para.Para32[0] = MAC_1;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+       }
+
+       if ((Istatus & IS_R2_C) != 0) {
+               /* Clear IRQ */
+               SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C);
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007,
+                       SKERR_SIRQ_E007MSG);
+               Para.Para64 = MAC_2;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+               Para.Para32[0] = MAC_2;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+       }
+
+       if ((Istatus & IS_XS1_C) != 0) {
+               /* Clear IRQ */
+               SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C);
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008,
+                       SKERR_SIRQ_E008MSG);
+               Para.Para64 = MAC_1;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+               Para.Para32[0] = MAC_1;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+       }
+
+       if ((Istatus & IS_XA1_C) != 0) {
+               /* Clear IRQ */
+               SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C);
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009,
+                       SKERR_SIRQ_E009MSG);
+               Para.Para64 = MAC_1;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+               Para.Para32[0] = MAC_1;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+       }
+
+       if ((Istatus & IS_XS2_C) != 0) {
+               /* Clear IRQ */
+               SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C);
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010,
+                       SKERR_SIRQ_E010MSG);
+               Para.Para64 = MAC_2;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+               Para.Para32[0] = MAC_2;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+       }
+
+       if ((Istatus & IS_XA2_C) != 0) {
+               /* Clear IRQ */
+               SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C);
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011,
+                       SKERR_SIRQ_E011MSG);
+               Para.Para64 = MAC_2;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+               Para.Para32[0] = MAC_2;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+       }
+
+       /* External reg interrupt */
+       if ((Istatus & IS_EXT_REG) != 0) {
+               /* Test IRQs from PHY */
+               for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+
+                       pPrt = &pAC->GIni.GP[i];
+
+                       if (pPrt->PState == SK_PRT_RESET) {
+                               continue;
+                       }
+
+                       switch (pPrt->PhyType) {
+
+                       case SK_PHY_XMAC:
+                               break;
+
+                       case SK_PHY_BCOM:
+                               SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt);
+                               SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_MASK, &PhyIMsk);
+
+                               if ((PhyInt & ~PhyIMsk) != 0) {
+                                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                                               ("Port %d Bcom Int: 0x%04X Mask: 0x%04X\n",
+                                               i, PhyInt, PhyIMsk));
+                                       SkPhyIsrBcom(pAC, IoC, i, PhyInt);
+                               }
+                               break;
+
+                       case SK_PHY_MARV_COPPER:
+                       case SK_PHY_MARV_FIBER:
+                               SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt);
+                               SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_MASK, &PhyIMsk);
+
+                               if ((PhyInt & PhyIMsk) != 0) {
+                                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                                               ("Port %d Marv Int: 0x%04X Mask: 0x%04X\n",
+                                               i, PhyInt, PhyIMsk));
+                                       SkPhyIsrGmac(pAC, IoC, i, PhyInt);
+                               }
+                               break;
+
+#ifdef OTHER_PHY
+                       case SK_PHY_LONE:
+                               SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt);
+                               SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_ENAB, &PhyIMsk);
+
+                               if ((PhyInt & PhyIMsk) != 0) {
+                                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                                               ("Port %d Lone Int: %x Mask: %x\n",
+                                               i, PhyInt, PhyIMsk));
+                                       SkPhyIsrLone(pAC, IoC, i, PhyInt);
+                               }
+                               break;
+                       case SK_PHY_NAT:
+                               /* todo: National */
+                               break;
+#endif /* OTHER_PHY */
+                       }
+               }
+       }
+
+       /* I2C Ready interrupt */
+       if ((Istatus & IS_I2C_READY) != 0) {
+               SkI2cIsr(pAC, IoC);
+       }
+
+       if ((Istatus & IS_LNK_SYNC_M1) != 0) {
+               /*
+                * We do NOT need the Link Sync interrupt, because it shows
+                * us only a link going down.
+                */
+               /* clear interrupt */
+               SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ);
+       }
+
+       /* Check MAC after link sync counter */
+       if ((Istatus & IS_MAC1) != 0) {
+               /* IRQ from MAC 1 */
+               SkMacIrq(pAC, IoC, MAC_1);
+       }
+
+       if ((Istatus & IS_LNK_SYNC_M2) != 0) {
+               /*
+                * We do NOT need the Link Sync interrupt, because it shows
+                * us only a link going down.
+                */
+               /* clear interrupt */
+               SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ);
+       }
+
+       /* Check MAC after link sync counter */
+       if ((Istatus & IS_MAC2) != 0) {
+               /* IRQ from MAC 2 */
+               SkMacIrq(pAC, IoC, MAC_2);
+       }
+
+       /* Timer interrupt (served last) */
+       if ((Istatus & IS_TIMINT) != 0) {
+               SkHwtIsr(pAC, IoC);
+       }
+}      /* SkGeSirqIsr */
+
+
+/******************************************************************************
+ *
+ * SkGePortCheckShorts() - Implementing XMAC Workaround Errata # 2
+ *
+ * return:
+ *     0       o.k. nothing needed
+ *     1       Restart needed on this port
+ */
+static int     SkGePortCheckShorts(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* IO Context */
+int            Port)           /* Which port should be checked */
+{
+       SK_U32          Shorts;                 /* Short Event Counter */
+       SK_U32          CheckShorts;    /* Check value for Short Event Counter */
+       SK_U64          RxCts;                  /* Rx Counter (packets on network) */
+       SK_U32          RxTmp;                  /* Rx temp. Counter */
+       SK_U32          FcsErrCts;              /* FCS Error Counter */
+       SK_GEPORT       *pPrt;                  /* GIni Port struct pointer */
+       int                     Rtv;                    /* Return value */
+       int                     i;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       /* Default: no action */
+       Rtv = SK_HW_PS_NONE;
+
+       (void)SkXmUpdateStats(pAC, IoC, Port);
+
+       /* Extra precaution: check for short Event counter */
+       (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
+
+       /*
+        * Read Rx counter (packets seen on the network and not necessarily
+        * really received.
+        */
+       RxCts = 0;
+
+       for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) {
+               (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp);
+               RxCts += (SK_U64)RxTmp;
+       }
+
+       /* On default: check shorts against zero */
+       CheckShorts = 0;
+
+       /* Extra precaution on active links */
+       if (pPrt->PHWLinkUp) {
+               /* Reset Link Restart counter */
+               pPrt->PLinkResCt = 0;
+               pPrt->PAutoNegTOCt = 0;
+
+               /* If link is up check for 2 */
+               CheckShorts = 2;
+
+               (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts);
+
+               if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
+                   pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN &&
+                   (pPrt->PLinkMode == SK_LMODE_HALF ||
+                        pPrt->PLinkMode == SK_LMODE_FULL)) {
+                       /*
+                        * This is autosensing and we are in the fallback
+                        * manual full/half duplex mode.
+                        */
+                       if (RxCts == pPrt->PPrevRx) {
+                               /* Nothing received, restart link */
+                               pPrt->PPrevFcs = FcsErrCts;
+                               pPrt->PPrevShorts = Shorts;
+
+                               return(SK_HW_PS_RESTART);
+                       }
+                       else {
+                               pPrt->PLipaAutoNeg = SK_LIPA_MANUAL;
+                       }
+               }
+
+               if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) ||
+                   (!(FcsErrCts - pPrt->PPrevFcs))) {
+                       /*
+                        * Note: The compare with zero above has to be done the way shown,
+                        * otherwise the Linux driver will have a problem.
+                        */
+                       /*
+                        * We received a bunch of frames or no CRC error occured on the
+                        * network -> ok.
+                        */
+                       pPrt->PPrevRx = RxCts;
+                       pPrt->PPrevFcs = FcsErrCts;
+                       pPrt->PPrevShorts = Shorts;
+
+                       return(SK_HW_PS_NONE);
+               }
+
+               pPrt->PPrevFcs = FcsErrCts;
+       }
+
+
+       if ((Shorts - pPrt->PPrevShorts) > CheckShorts) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                       ("Short Event Count Restart Port %d \n", Port));
+               Rtv = SK_HW_PS_RESTART;
+       }
+
+       pPrt->PPrevShorts = Shorts;
+       pPrt->PPrevRx = RxCts;
+
+       return(Rtv);
+}      /* SkGePortCheckShorts */
+
+
+/******************************************************************************
+ *
+ * SkGePortCheckUp() - Check if the link is up
+ *
+ * return:
+ *     0       o.k. nothing needed
+ *     1       Restart needed on this port
+ *     2       Link came up
+ */
+static int     SkGePortCheckUp(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* IO Context */
+int            Port)           /* Which port should be checked */
+{
+       switch (pAC->GIni.GP[Port].PhyType) {
+       case SK_PHY_XMAC:
+               return(SkGePortCheckUpXmac(pAC, IoC, Port));
+       case SK_PHY_BCOM:
+               return(SkGePortCheckUpBcom(pAC, IoC, Port));
+       case SK_PHY_MARV_COPPER:
+       case SK_PHY_MARV_FIBER:
+               return(SkGePortCheckUpGmac(pAC, IoC, Port));
+#ifdef OTHER_PHY
+       case SK_PHY_LONE:
+               return(SkGePortCheckUpLone(pAC, IoC, Port));
+       case SK_PHY_NAT:
+               return(SkGePortCheckUpNat(pAC, IoC, Port));
+#endif /* OTHER_PHY */
+       }
+       return(SK_HW_PS_NONE);
+}      /* SkGePortCheckUp */
+
+
+/******************************************************************************
+ *
+ * SkGePortCheckUpXmac() - Implementing of the Workaround Errata # 2
+ *
+ * return:
+ *     0       o.k. nothing needed
+ *     1       Restart needed on this port
+ *     2       Link came up
+ */
+static int SkGePortCheckUpXmac(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* IO Context */
+int            Port)           /* Which port should be checked */
+{
+       SK_U32          Shorts;         /* Short Event Counter */
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+       int                     Done;
+       SK_U32          GpReg;          /* General Purpose register value */
+       SK_U16          Isrc;           /* Interrupt source register */
+       SK_U16          IsrcSum;        /* Interrupt source register sum */
+       SK_U16          LpAb;           /* Link Partner Ability */
+       SK_U16          ResAb;          /* Resolved Ability */
+       SK_U16          ExtStat;        /* Extended Status Register */
+       SK_BOOL         AutoNeg;        /* Is Auto-negotiation used ? */
+       SK_U8           NextMode;       /* Next AutoSensing Mode */
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       if (pPrt->PHWLinkUp) {
+               if (pPrt->PhyType != SK_PHY_XMAC) {
+                       return(SK_HW_PS_NONE);
+               }
+               else {
+                       return(SkGePortCheckShorts(pAC, IoC, Port));
+               }
+       }
+
+       IsrcSum = pPrt->PIsave;
+       pPrt->PIsave = 0;
+
+       /* Now wait for each port's link */
+       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
+               AutoNeg = SK_FALSE;
+       }
+       else {
+               AutoNeg = SK_TRUE;
+       }
+
+       if (pPrt->PLinkBroken) {
+               /* Link was broken */
+               XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
+
+               if ((GpReg & XM_GP_INP_ASS) == 0) {
+                       /* The Link is in sync */
+                       XM_IN16(IoC, Port, XM_ISRC, &Isrc);
+                       IsrcSum |= Isrc;
+                       SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
+
+                       if ((Isrc & XM_IS_INP_ASS) == 0) {
+                               /* It has been in sync since last time */
+                               /* Restart the PORT */
+                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                                       ("Link in sync Restart Port %d\n", Port));
+
+                               (void)SkXmUpdateStats(pAC, IoC, Port);
+
+                               /* We now need to reinitialize the PrevShorts counter */
+                               (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
+                               pPrt->PPrevShorts = Shorts;
+
+                               pPrt->PLinkBroken = SK_FALSE;
+
+                               /*
+                                * Link Restart Workaround:
+                                *  it may be possible that the other Link side
+                                *  restarts its link as well an we detect
+                                *  another LinkBroken. To prevent this
+                                *  happening we check for a maximum number
+                                *  of consecutive restart. If those happens,
+                                *  we do NOT restart the active link and
+                                *  check whether the link is now o.k.
+                                */
+                               pPrt->PLinkResCt++;
+
+                               pPrt->PAutoNegTimeOut = 0;
+
+                               if (pPrt->PLinkResCt < SK_MAX_LRESTART) {
+                                       return(SK_HW_PS_RESTART);
+                               }
+
+                               pPrt->PLinkResCt = 0;
+
+                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                                       ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum));
+                       }
+                       else {
+                               pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
+
+                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                                       ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum));
+
+                               /* Do nothing more if link is broken */
+                               return(SK_HW_PS_NONE);
+                       }
+               }
+               else {
+                       /* Do nothing more if link is broken */
+                       return(SK_HW_PS_NONE);
+               }
+
+       }
+       else {
+               /* Link was not broken, check if it is */
+               XM_IN16(IoC, Port, XM_ISRC, &Isrc);
+               IsrcSum |= Isrc;
+               if ((Isrc & XM_IS_INP_ASS) != 0) {
+                       XM_IN16(IoC, Port, XM_ISRC, &Isrc);
+                       IsrcSum |= Isrc;
+                       if ((Isrc & XM_IS_INP_ASS) != 0) {
+                               XM_IN16(IoC, Port, XM_ISRC, &Isrc);
+                               IsrcSum |= Isrc;
+                               if ((Isrc & XM_IS_INP_ASS) != 0) {
+                                       pPrt->PLinkBroken = SK_TRUE;
+                                       /* Re-Init Link partner Autoneg flag */
+                                       pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
+                                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                                               ("Link broken Port %d\n", Port));
+
+                                       /* Cable removed-> reinit sense mode */
+                                       SkHWInitDefSense(pAC, IoC, Port);
+
+                                       return(SK_HW_PS_RESTART);
+                               }
+                       }
+               }
+               else {
+                       SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc);
+                       if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) {
+                               return(SK_HW_PS_RESTART);
+                       }
+               }
+       }
+
+       /*
+        * here we usually can check whether the link is in sync and
+        * auto-negotiation is done.
+        */
+       XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
+       XM_IN16(IoC, Port, XM_ISRC, &Isrc);
+       IsrcSum |= Isrc;
+
+       SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
+
+       if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) {
+               if ((GpReg & XM_GP_INP_ASS) == 0) {
+                       /* Save Auto-negotiation Done interrupt only if link is in sync */
+                       pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
+               }
+#ifdef DEBUG
+               if ((pPrt->PIsave & XM_IS_AND) != 0) {
+                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                               ("AutoNeg done rescheduled Port %d\n", Port));
+               }
+#endif /* DEBUG */
+               return(SK_HW_PS_NONE);
+       }
+
+       if (AutoNeg) {
+               if ((IsrcSum & XM_IS_AND) != 0) {
+                       SkHWLinkUp(pAC, IoC, Port);
+                       Done = SkMacAutoNegDone(pAC, IoC, Port);
+                       if (Done != SK_AND_OK) {
+                               /* Get PHY parameters, for debugging only */
+                               SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb);
+                               SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
+                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                                       ("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n",
+                                        Port, LpAb, ResAb));
+
+                               /* Try next possible mode */
+                               NextMode = SkHWSenseGetNext(pAC, IoC, Port);
+                               SkHWLinkDown(pAC, IoC, Port);
+                               if (Done == SK_AND_DUP_CAP) {
+                                       /* GoTo next mode */
+                                       SkHWSenseSetNext(pAC, IoC, Port, NextMode);
+                               }
+
+                               return(SK_HW_PS_RESTART);
+                       }
+                       /*
+                        * Dummy Read extended status to prevent extra link down/ups
+                        * (clear Page Received bit if set)
+                        */
+                       SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat);
+                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                               ("AutoNeg done Port %d\n", Port));
+                       return(SK_HW_PS_LINK);
+               }
+
+               /* AutoNeg not done, but HW link is up. Check for timeouts */
+               pPrt->PAutoNegTimeOut++;
+               if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
+                       /* Increase the Timeout counter */
+                       pPrt->PAutoNegTOCt++;
+
+                       /* Timeout occured */
+                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                               ("AutoNeg timeout Port %d\n", Port));
+                       if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
+                               pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
+                               /* Set Link manually up */
+                               SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
+                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                                       ("Set manual full duplex Port %d\n", Port));
+                       }
+
+                       if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
+                               pPrt->PLipaAutoNeg == SK_LIPA_AUTO &&
+                               pPrt->PAutoNegTOCt >= SK_MAX_ANEG_TO) {
+                               /*
+                                * This is rather complicated.
+                                * we need to check here whether the LIPA_AUTO
+                                * we saw before is false alert. We saw at one
+                                * switch ( SR8800) that on boot time it sends
+                                * just one auto-neg packet and does no further
+                                * auto-negotiation.
+                                * Solution: we restart the autosensing after
+                                * a few timeouts.
+                                */
+                               pPrt->PAutoNegTOCt = 0;
+                               pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
+                               SkHWInitDefSense(pAC, IoC, Port);
+                       }
+
+                       /* Do the restart */
+                       return(SK_HW_PS_RESTART);
+               }
+       }
+       else {
+               /* Link is up and we don't need more */
+#ifdef DEBUG
+               if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
+                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                               ("ERROR: Lipa auto detected on port %d\n", Port));
+               }
+#endif /* DEBUG */
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                       ("Link sync(GP), Port %d\n", Port));
+               SkHWLinkUp(pAC, IoC, Port);
+
+               /*
+                * Link sync (GP) and so assume a good connection. But if not received
+                * a bunch of frames received in a time slot (maybe broken tx cable)
+                * the port is restart.
+                */
+               return(SK_HW_PS_LINK);
+       }
+
+       return(SK_HW_PS_NONE);
+}      /* SkGePortCheckUpXmac */
+
+
+/******************************************************************************
+ *
+ * SkGePortCheckUpBcom() - Check if the link is up on Bcom PHY
+ *
+ * return:
+ *     0       o.k. nothing needed
+ *     1       Restart needed on this port
+ *     2       Link came up
+ */
+static int SkGePortCheckUpBcom(
+SK_AC  *pAC,   /* Adapter Context */
+SK_IOC IoC,    /* IO Context */
+int            Port)   /* Which port should be checked */
+{
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+       int                     Done;
+       SK_U16          Isrc;           /* Interrupt source register */
+       SK_U16          PhyStat;        /* Phy Status Register */
+       SK_U16          ResAb;          /* Master/Slave resolution */
+       SK_U16          Ctrl;           /* Broadcom control flags */
+#ifdef DEBUG
+       SK_U16          LpAb;
+       SK_U16          ExtStat;
+#endif /* DEBUG */
+       SK_BOOL         AutoNeg;        /* Is Auto-negotiation used ? */
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       /* Check for No HCD Link events (#10523) */
+       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc);
+
+#ifdef xDEBUG
+       if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT) ==
+               (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) {
+
+               SK_U32  Stat1, Stat2, Stat3;
+
+               Stat1 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
+               CMSMPrintString(
+                       pAC->pConfigTable,
+                       MSG_TYPE_RUNTIME_INFO,
+                       "CheckUp1 - Stat: %x, Mask: %x",
+                       (void *)Isrc,
+                       (void *)Stat1);
+
+               Stat1 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
+               Stat2 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2);
+               Stat1 = Stat1 << 16 | Stat2;
+               Stat2 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
+               Stat3 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
+               Stat2 = Stat2 << 16 | Stat3;
+               CMSMPrintString(
+                       pAC->pConfigTable,
+                       MSG_TYPE_RUNTIME_INFO,
+                       "Ctrl/Stat: %x, AN Adv/LP: %x",
+                       (void *)Stat1,
+                       (void *)Stat2);
+
+               Stat1 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
+               Stat2 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
+               Stat1 = Stat1 << 16 | Stat2;
+               Stat2 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
+               Stat3 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3);
+               Stat2 = Stat2 << 16 | Stat3;
+               CMSMPrintString(
+                       pAC->pConfigTable,
+                       MSG_TYPE_RUNTIME_INFO,
+                       "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
+                       (void *)Stat1,
+                       (void *)Stat2);
+
+               Stat1 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
+               Stat2 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
+               Stat1 = Stat1 << 16 | Stat2;
+               Stat2 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
+               Stat3 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
+               Stat2 = Stat2 << 16 | Stat3;
+               CMSMPrintString(
+                       pAC->pConfigTable,
+                       MSG_TYPE_RUNTIME_INFO,
+                       "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
+                       (void *)Stat1,
+                       (void *)Stat2);
+       }
+#endif /* DEBUG */
+
+       if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) {
+               /*
+                * Workaround BCom Errata:
+                *      enable and disable loopback mode if "NO HCD" occurs.
+                */
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Ctrl);
+               SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
+                       (SK_U16)(Ctrl | PHY_CT_LOOP));
+               SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
+                       (SK_U16)(Ctrl & ~PHY_CT_LOOP));
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("No HCD Link event, Port %d\n", Port));
+#ifdef xDEBUG
+               CMSMPrintString(
+                       pAC->pConfigTable,
+                       MSG_TYPE_RUNTIME_INFO,
+                       "No HCD link event, port %d.",
+                       (void *)Port,
+                       (void *)NULL);
+#endif /* DEBUG */
+       }
+
+       /* Not obsolete: link status bit is latched to 0 and autoclearing! */
+       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
+
+       if (pPrt->PHWLinkUp) {
+               return(SK_HW_PS_NONE);
+       }
+
+#ifdef xDEBUG
+       {
+               SK_U32  Stat1, Stat2, Stat3;
+
+               Stat1 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
+               CMSMPrintString(
+                       pAC->pConfigTable,
+                       MSG_TYPE_RUNTIME_INFO,
+                       "CheckUp1a - Stat: %x, Mask: %x",
+                       (void *)Isrc,
+                       (void *)Stat1);
+
+               Stat1 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
+               Stat2 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
+               Stat1 = Stat1 << 16 | PhyStat;
+               Stat2 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
+               Stat3 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
+               Stat2 = Stat2 << 16 | Stat3;
+               CMSMPrintString(
+                       pAC->pConfigTable,
+                       MSG_TYPE_RUNTIME_INFO,
+                       "Ctrl/Stat: %x, AN Adv/LP: %x",
+                       (void *)Stat1,
+                       (void *)Stat2);
+
+               Stat1 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
+               Stat2 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
+               Stat1 = Stat1 << 16 | Stat2;
+               Stat2 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
+               Stat3 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
+               Stat2 = Stat2 << 16 | ResAb;
+               CMSMPrintString(
+                       pAC->pConfigTable,
+                       MSG_TYPE_RUNTIME_INFO,
+                       "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
+                       (void *)Stat1,
+                       (void *)Stat2);
+
+               Stat1 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
+               Stat2 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
+               Stat1 = Stat1 << 16 | Stat2;
+               Stat2 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
+               Stat3 = 0;
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
+               Stat2 = Stat2 << 16 | Stat3;
+               CMSMPrintString(
+                       pAC->pConfigTable,
+                       MSG_TYPE_RUNTIME_INFO,
+                       "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
+                       (void *)Stat1,
+                       (void *)Stat2);
+       }
+#endif /* DEBUG */
+
+       /* Now wait for each port's link */
+       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
+               AutoNeg = SK_FALSE;
+       }
+       else {
+               AutoNeg = SK_TRUE;
+       }
+
+       /*
+        * Here we usually can check whether the link is in sync and
+        * auto-negotiation is done.
+        */
+
+       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
+
+       SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat));
+
+       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
+
+       if ((ResAb & PHY_B_1000S_MSF) != 0) {
+               /* Error */
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("Master/Slave Fault port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               pPrt->PMSStatus = SK_MS_STAT_FAULT;
+
+               return(SK_HW_PS_RESTART);
+       }
+
+       if ((PhyStat & PHY_ST_LSYNC) == 0) {
+               return(SK_HW_PS_NONE);
+       }
+
+       pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
+               SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat));
+
+       if (AutoNeg) {
+               if ((PhyStat & PHY_ST_AN_OVER) != 0) {
+                       SkHWLinkUp(pAC, IoC, Port);
+                       Done = SkMacAutoNegDone(pAC, IoC, Port);
+                       if (Done != SK_AND_OK) {
+#ifdef DEBUG
+                               /* Get PHY parameters, for debugging only */
+                               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb);
+                               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ExtStat);
+                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                                       ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
+                                       Port, LpAb, ExtStat));
+#endif /* DEBUG */
+                               return(SK_HW_PS_RESTART);
+                       }
+                       else {
+#ifdef xDEBUG
+                               /* Dummy read ISR to prevent extra link downs/ups */
+                               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
+
+                               if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
+                                       CMSMPrintString(
+                                               pAC->pConfigTable,
+                                               MSG_TYPE_RUNTIME_INFO,
+                                               "CheckUp2 - Stat: %x",
+                                               (void *)ExtStat,
+                                               (void *)NULL);
+                               }
+#endif /* DEBUG */
+
+                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                                       ("AutoNeg done Port %d\n", Port));
+                               return(SK_HW_PS_LINK);
+                       }
+               }
+       }
+       else {  /* !AutoNeg */
+               /* Link is up and we don't need more. */
+#ifdef DEBUG
+               if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
+                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                               ("ERROR: Lipa auto detected on port %d\n", Port));
+               }
+#endif /* DEBUG */
+
+#ifdef xDEBUG
+               /* Dummy read ISR to prevent extra link downs/ups */
+               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
+
+               if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
+                       CMSMPrintString(
+                               pAC->pConfigTable,
+                               MSG_TYPE_RUNTIME_INFO,
+                               "CheckUp3 - Stat: %x",
+                               (void *)ExtStat,
+                               (void *)NULL);
+               }
+#endif /* DEBUG */
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                       ("Link sync(GP), Port %d\n", Port));
+               SkHWLinkUp(pAC, IoC, Port);
+               return(SK_HW_PS_LINK);
+       }
+
+       return(SK_HW_PS_NONE);
+}      /* SkGePortCheckUpBcom */
+
+
+/******************************************************************************
+ *
+ * SkGePortCheckUpGmac() - Check if the link is up on Marvell PHY
+ *
+ * return:
+ *     0       o.k. nothing needed
+ *     1       Restart needed on this port
+ *     2       Link came up
+ */
+static int SkGePortCheckUpGmac(
+SK_AC  *pAC,   /* Adapter Context */
+SK_IOC IoC,    /* IO Context */
+int            Port)   /* Which port should be checked */
+{
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+       int                     Done;
+       SK_U16          Isrc;           /* Interrupt source */
+       SK_U16          PhyStat;        /* Phy Status */
+       SK_U16          PhySpecStat;/* Phy Specific Status */
+       SK_U16          ResAb;          /* Master/Slave resolution */
+       SK_BOOL         AutoNeg;        /* Is Auto-negotiation used ? */
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       /* Read PHY Interrupt Status */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &Isrc);
+
+       if ((Isrc & PHY_M_IS_AN_COMPL) != 0) {
+               /* TBD */
+       }
+
+       if ((Isrc & PHY_M_IS_DOWNSH_DET) != 0) {
+               /* TBD */
+       }
+
+       if (pPrt->PHWLinkUp) {
+               return(SK_HW_PS_NONE);
+       }
+
+       /* Now wait for each port's link */
+       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
+               AutoNeg = SK_FALSE;
+       }
+       else {
+               AutoNeg = SK_TRUE;
+       }
+
+       /* Read PHY Status */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat));
+
+       SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
+
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
+
+       if ((ResAb & PHY_B_1000S_MSF) != 0) {
+               /* Error */
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("Master/Slave Fault port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               pPrt->PMSStatus = SK_MS_STAT_FAULT;
+
+               return(SK_HW_PS_RESTART);
+       }
+
+       /* Read PHY Specific Status */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("AutoNeg: %d, PhySpecStat: 0x%04x\n", AutoNeg, PhySpecStat));
+
+       if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) {
+               return(SK_HW_PS_NONE);
+       }
+
+       pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
+               SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
+
+       pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7);
+
+       if (AutoNeg) {
+               /* Auto-Negotiation Over ? */
+               if ((PhyStat & PHY_ST_AN_OVER) != 0) {
+
+                       SkHWLinkUp(pAC, IoC, Port);
+
+                       Done = SkMacAutoNegDone(pAC, IoC, Port);
+
+                       if (Done != SK_AND_OK) {
+                               return(SK_HW_PS_RESTART);
+                       }
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                               ("AutoNeg done Port %d\n", Port));
+                       return(SK_HW_PS_LINK);
+               }
+       }
+       else {  /* !AutoNeg */
+               /* Link is up and we don't need more */
+#ifdef DEBUG
+               if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
+                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                               ("ERROR: Lipa auto detected on port %d\n", Port));
+               }
+#endif /* DEBUG */
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                       ("Link sync, Port %d\n", Port));
+               SkHWLinkUp(pAC, IoC, Port);
+
+               return(SK_HW_PS_LINK);
+       }
+
+       return(SK_HW_PS_NONE);
+}      /* SkGePortCheckUpGmac */
+
+
+#ifdef OTHER_PHY
+/******************************************************************************
+ *
+ * SkGePortCheckUpLone() - Check if the link is up on Level One PHY
+ *
+ * return:
+ *     0       o.k. nothing needed
+ *     1       Restart needed on this port
+ *     2       Link came up
+ */
+static int SkGePortCheckUpLone(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* IO Context */
+int            Port)           /* Which port should be checked */
+{
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+       int                     Done;
+       SK_U16          Isrc;           /* Interrupt source register */
+       SK_U16          LpAb;           /* Link Partner Ability */
+       SK_U16          ExtStat;        /* Extended Status Register */
+       SK_U16          PhyStat;        /* Phy Status Register */
+       SK_U16          StatSum;
+       SK_BOOL         AutoNeg;        /* Is Auto-negotiation used ? */
+       SK_U8           NextMode;       /* Next AutoSensing Mode */
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       if (pPrt->PHWLinkUp) {
+               return(SK_HW_PS_NONE);
+       }
+
+       StatSum = pPrt->PIsave;
+       pPrt->PIsave = 0;
+
+       /* Now wait for each ports link */
+       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
+               AutoNeg = SK_FALSE;
+       }
+       else {
+               AutoNeg = SK_TRUE;
+       }
+
+       /*
+        * here we usually can check whether the link is in sync and
+        * auto-negotiation is done.
+        */
+       SkXmPhyRead(pAC, IoC, Port, PHY_LONE_STAT, &PhyStat);
+       StatSum |= PhyStat;
+
+       SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
+
+       if ((PhyStat & PHY_ST_LSYNC) == 0) {
+               /* Save Auto-negotiation Done bit */
+               pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER);
+#ifdef DEBUG
+               if ((pPrt->PIsave & PHY_ST_AN_OVER) != 0) {
+                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                               ("AutoNeg done rescheduled Port %d\n", Port));
+               }
+#endif /* DEBUG */
+               return(SK_HW_PS_NONE);
+       }
+
+       if (AutoNeg) {
+               if ((StatSum & PHY_ST_AN_OVER) != 0) {
+                       SkHWLinkUp(pAC, IoC, Port);
+                       Done = SkMacAutoNegDone(pAC, IoC, Port);
+                       if (Done != SK_AND_OK) {
+                               /* Get PHY parameters, for debugging only */
+                               SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb);
+                               SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ExtStat);
+                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                                       ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
+                                        Port, LpAb, ExtStat));
+
+                               /* Try next possible mode */
+                               NextMode = SkHWSenseGetNext(pAC, IoC, Port);
+                               SkHWLinkDown(pAC, IoC, Port);
+                               if (Done == SK_AND_DUP_CAP) {
+                                       /* GoTo next mode */
+                                       SkHWSenseSetNext(pAC, IoC, Port, NextMode);
+                               }
+
+                               return(SK_HW_PS_RESTART);
+
+                       }
+                       else {
+                               /*
+                                * Dummy Read interrupt status to prevent
+                                * extra link down/ups
+                                */
+                               SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
+                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                                       ("AutoNeg done Port %d\n", Port));
+                               return(SK_HW_PS_LINK);
+                       }
+               }
+
+               /* AutoNeg not done, but HW link is up. Check for timeouts */
+               pPrt->PAutoNegTimeOut++;
+               if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
+                       /* Timeout occured */
+                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                               ("AutoNeg timeout Port %d\n", Port));
+                       if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
+                               pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
+                               /* Set Link manually up */
+                               SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
+                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                                       ("Set manual full duplex Port %d\n", Port));
+                       }
+
+                       /* Do the restart */
+                       return(SK_HW_PS_RESTART);
+               }
+       }
+       else {
+               /* Link is up and we don't need more */
+#ifdef DEBUG
+               if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
+                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                               ("ERROR: Lipa auto detected on port %d\n", Port));
+               }
+#endif /* DEBUG */
+
+               /*
+                * Dummy Read interrupt status to prevent
+                * extra link down/ups
+                */
+               SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                       ("Link sync(GP), Port %d\n", Port));
+               SkHWLinkUp(pAC, IoC, Port);
+               return(SK_HW_PS_LINK);
+       }
+
+       return(SK_HW_PS_NONE);
+}      /* SkGePortCheckUpLone */
+
+
+/******************************************************************************
+ *
+ * SkGePortCheckUpNat() - Check if the link is up on National PHY
+ *
+ * return:
+ *     0       o.k. nothing needed
+ *     1       Restart needed on this port
+ *     2       Link came up
+ */
+static int SkGePortCheckUpNat(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* IO Context */
+int            Port)           /* Which port should be checked */
+{
+       /* todo: National */
+       return(SK_HW_PS_NONE);
+}      /* SkGePortCheckUpNat */
+#endif /* OTHER_PHY */
+
+
+/******************************************************************************
+ *
+ *     SkGeSirqEvent() - Event Service Routine
+ *
+ * Description:
+ *
+ * Notes:
+ */
+int    SkGeSirqEvent(
+SK_AC          *pAC,           /* Adapter Context */
+SK_IOC         IoC,            /* Io Context */
+SK_U32         Event,          /* Module specific Event */
+SK_EVPARA      Para)           /* Event specific Parameter */
+{
+       SK_U64          Octets;
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+       SK_U32          Port;
+       SK_U32          Time;
+       unsigned        Len;
+       int                     PortStat;
+       SK_U8           Val8;
+
+       Port = Para.Para32[0];
+       pPrt = &pAC->GIni.GP[Port];
+
+       switch (Event) {
+       case SK_HWEV_WATIM:
+               /* Check whether port came up */
+               PortStat = SkGePortCheckUp(pAC, IoC, Port);
+
+               switch (PortStat) {
+               case SK_HW_PS_RESTART:
+                       if (pPrt->PHWLinkUp) {
+                               /*
+                                * Set Link to down.
+                                */
+                               SkHWLinkDown(pAC, IoC, Port);
+
+                               /*
+                                * Signal directly to RLMT to ensure correct
+                                * sequence of SWITCH and RESET event.
+                                */
+                               SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
+                       }
+
+                       /* Restart needed */
+                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
+                       break;
+
+               case SK_HW_PS_LINK:
+                       /* Signal to RLMT */
+                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para);
+                       break;
+
+               }
+
+               /* Start again the check Timer */
+               if (pPrt->PHWLinkUp) {
+                       Time = SK_WA_ACT_TIME;
+               }
+               else {
+                       Time = SK_WA_INA_TIME;
+               }
+
+               /* Todo: still needed for non-XMAC PHYs??? */
+               /* Start workaround Errata #2 timer */
+               SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Time,
+                       SKGE_HWAC, SK_HWEV_WATIM, Para);
+               break;
+
+       case SK_HWEV_PORT_START:
+               if (pPrt->PHWLinkUp) {
+                       /*
+                        * Signal directly to RLMT to ensure correct
+                        * sequence of SWITCH and RESET event.
+                        */
+                       SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
+               }
+
+               SkHWLinkDown(pAC, IoC, Port);
+
+               /* Schedule Port RESET */
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
+
+               /* Start workaround Errata #2 timer */
+               SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
+                       SKGE_HWAC, SK_HWEV_WATIM, Para);
+               break;
+
+       case SK_HWEV_PORT_STOP:
+               if (pPrt->PHWLinkUp) {
+                       /*
+                        * Signal directly to RLMT to ensure correct
+                        * sequence of SWITCH and RESET event.
+                        */
+                       SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
+               }
+
+               /* Stop Workaround Timer */
+               SkTimerStop(pAC, IoC, &pPrt->PWaTimer);
+
+               SkHWLinkDown(pAC, IoC, Port);
+               break;
+
+       case SK_HWEV_UPDATE_STAT:
+               /* We do NOT need to update any statistics */
+               break;
+
+       case SK_HWEV_CLEAR_STAT:
+               /* We do NOT need to clear any statistics */
+               for (Port = 0; Port < (SK_U32)pAC->GIni.GIMacsFound; Port++) {
+                       pPrt->PPrevRx = 0;
+                       pPrt->PPrevFcs = 0;
+                       pPrt->PPrevShorts = 0;
+               }
+               break;
+
+       case SK_HWEV_SET_LMODE:
+               Val8 = (SK_U8)Para.Para32[1];
+               if (pPrt->PLinkModeConf != Val8) {
+                       /* Set New link mode */
+                       pPrt->PLinkModeConf = Val8;
+
+                       /* Restart Port */
+                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
+                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
+               }
+               break;
+
+       case SK_HWEV_SET_FLOWMODE:
+               Val8 = (SK_U8)Para.Para32[1];
+               if (pPrt->PFlowCtrlMode != Val8) {
+                       /* Set New Flow Control mode */
+                       pPrt->PFlowCtrlMode = Val8;
+
+                       /* Restart Port */
+                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
+                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
+               }
+               break;
+
+       case SK_HWEV_SET_ROLE:
+               /* not possible for fiber */
+               if (!pAC->GIni.GICopperType) {
+                       break;
+               }
+               Val8 = (SK_U8)Para.Para32[1];
+               if (pPrt->PMSMode != Val8) {
+                       /* Set New link mode */
+                       pPrt->PMSMode = Val8;
+
+                       /* Restart Port */
+                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
+                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
+               }
+               break;
+
+       case SK_HWEV_SET_SPEED:
+               if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
+                       break;
+               }
+               Val8 = (SK_U8)Para.Para32[1];
+               if (pPrt->PLinkSpeed != Val8) {
+                       /* Set New Speed parameter */
+                       pPrt->PLinkSpeed = Val8;
+
+                       /* Restart Port */
+                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
+                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
+               }
+               break;
+
+       case SK_HWEV_HALFDUP_CHK:
+               /*
+                * half duplex hangup workaround.
+                * See packet arbiter timeout interrupt for description
+                */
+               pPrt->HalfDupTimerActive = SK_FALSE;
+               if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
+                   pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) {
+
+                       Len = sizeof(SK_U64);
+                       SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
+                               &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port),
+                               pAC->Rlmt.Port[Port].Net->NetNumber);
+
+                       if (pPrt->LastOctets == Octets) {
+                               /* Tx hanging, a FIFO flush restarts it */
+                               SkMacFlushTxFifo(pAC, IoC, Port);
+                       }
+               }
+               break;
+
+       default:
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG);
+               break;
+       }
+
+       return(0);
+}      /* SkGeSirqEvent */
+
+
+/******************************************************************************
+ *
+ *     SkPhyIsrBcom() - PHY interrupt service routine
+ *
+ * Description: handles all interrupts from BCom PHY
+ *
+ * Returns: N/A
+ */
+static void SkPhyIsrBcom(
+SK_AC          *pAC,           /* Adapter Context */
+SK_IOC         IoC,            /* Io Context */
+int                    Port,           /* Port Num = PHY Num */
+SK_U16         IStatus)        /* Interrupt Status */
+{
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+       SK_EVPARA       Para;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       if ((IStatus & PHY_B_IS_PSE) != 0) {
+               /* Incorrectable pair swap error */
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E022,
+                       SKERR_SIRQ_E022MSG);
+       }
+
+       if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) {
+               Para.Para32[0] = (SK_U32)Port;
+
+               SkHWLinkDown(pAC, IoC, Port);
+
+               /* Signal to RLMT */
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+
+               /* Start workaround Errata #2 timer */
+               SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
+                       SKGE_HWAC, SK_HWEV_WATIM, Para);
+       }
+
+}      /* SkPhyIsrBcom */
+
+
+/******************************************************************************
+ *
+ *     SkPhyIsrGmac() - PHY interrupt service routine
+ *
+ * Description: handles all interrupts from Marvell PHY
+ *
+ * Returns: N/A
+ */
+static void SkPhyIsrGmac(
+SK_AC          *pAC,           /* Adapter Context */
+SK_IOC         IoC,            /* Io Context */
+int                    Port,           /* Port Num = PHY Num */
+SK_U16         IStatus)        /* Interrupt Status */
+{
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+       SK_EVPARA       Para;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) {
+               Para.Para32[0] = (SK_U32)Port;
+
+               SkHWLinkDown(pAC, IoC, Port);
+
+               /* Signal to RLMT */
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+       }
+
+       if ((IStatus & PHY_M_IS_AN_ERROR) != 0) {
+               /* Auto-Negotiation Error */
+               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG);
+       }
+
+       if ((IStatus & PHY_M_IS_LSP_CHANGE) != 0) {
+               /* TBD */
+       }
+
+       if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) {
+               /* FIFO Overflow/Underrun Error */
+               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG);
+       }
+}      /* SkPhyIsrGmac */
+
+
+#ifdef OTHER_PHY
+/******************************************************************************
+ *
+ *     SkPhyIsrLone() - PHY interrupt service routine
+ *
+ * Description: handles all interrupts from LONE PHY
+ *
+ * Returns: N/A
+ */
+static void SkPhyIsrLone(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* Io Context */
+int            Port,           /* Port Num = PHY Num */
+SK_U16 IStatus)        /* Interrupt Status */
+{
+       SK_EVPARA       Para;
+
+       if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) {
+               SkHWLinkDown(pAC, IoC, Port);
+
+               /* Signal to RLMT */
+               Para.Para32[0] = (SK_U32)Port;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+       }
+
+}      /* SkPhyIsrLone */
+#endif /* OTHER_PHY */
+
+#endif /* CONFIG_SK98 */
+
+/* End of File */
diff --git a/drivers/net/sk98lin/ski2c.c b/drivers/net/sk98lin/ski2c.c
new file mode 100644 (file)
index 0000000..2ab635a
--- /dev/null
@@ -0,0 +1,1505 @@
+/******************************************************************************
+ *
+ * Name:       ski2c.c
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.57 $
+ * Date:       $Date: 2003/01/28 09:17:38 $
+ * Purpose:    Functions to access Voltage and Temperature Sensor
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2003 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: ski2c.c,v $
+ *     Revision 1.57  2003/01/28 09:17:38  rschmidt
+ *     Fixed handling for sensors on YUKON Fiber.
+ *     Editorial changes.
+ *
+ *     Revision 1.56  2002/12/19 14:20:41  rschmidt
+ *     Added debugging code in SkI2cWait().
+ *     Replaced all I2C-write operations with function SkI2cWrite().
+ *     Fixed compiler warning because of uninitialized 'Time' in SkI2cEvent().
+ *     Editorial changes.
+ *
+ *     Revision 1.55  2002/10/15 07:23:55  rschmidt
+ *     Added setting of the GIYukon32Bit bool variable to distinguish
+ *     32-bit adapters.
+ *     Editorial changes (TWSI).
+ *
+ *     Revision 1.54  2002/08/13 09:05:06  rschmidt
+ *     Added new thresholds if VAUX is not available (GIVauxAvail).
+ *     Merged defines for PHY PLL 3V3 voltage (A and B).
+ *     Editorial changes.
+ *
+ *     Revision 1.53  2002/08/08 11:04:53  rwahl
+ *     Added missing comment for revision 1.51
+ *
+ *     Revision 1.52  2002/08/08 10:09:02  jschmalz
+ *     Sensor init state caused wrong error log entry
+ *
+ *     Revision 1.51  2002/08/06 09:43:03  jschmalz
+ *     Extensions and changes for Yukon
+ *
+ *     Revision 1.50  2002/08/02 12:09:22  rschmidt
+ *     Added support for YUKON sensors.
+ *     Editorial changes.
+ *
+ *     Revision 1.49  2002/07/30 11:07:52  rschmidt
+ *     Replaced MaxSens init by update for Copper in SkI2cInit1(),
+ *     because it was already initialized in SkI2cInit0().
+ *     Editorial changes.
+ *
+ *     Revision 1.48  2001/08/16 12:44:33  afischer
+ *     LM80 sensor init values corrected
+ *
+ *     Revision 1.47  2001/04/05 11:38:09  rassmann
+ *     Set SenState to idle in SkI2cWaitIrq().
+ *     Changed error message in SkI2cWaitIrq().
+ *
+ *     Revision 1.46  2001/04/02 14:03:35  rassmann
+ *     Changed pAC to IoC in SK_IN32().
+ *
+ *     Revision 1.45  2001/03/21 12:12:49  rassmann
+ *     Resetting I2C_READY interrupt in SkI2cInit1().
+ *
+ *     Revision 1.44  2000/08/07 15:49:03  gklug
+ *     Fix: SK_INFAST only in NetWare driver.
+ *
+ *     Revision 1.43  2000/08/03 14:28:17  rassmann
+ *     Added function to wait for I2C being ready before resetting the board.
+ *     Replaced one duplicate "out of range" message with correct one.
+ *
+ *     Revision 1.42  1999/11/22 13:35:12  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.41  1999/09/14 14:11:30  malthoff
+ *     The 1000BT Dual Link adapter has got only one Fan.
+ *     The second Fan has been removed.
+ *
+ *     Revision 1.40  1999/05/27 13:37:27  malthoff
+ *     Set divisor of 1 for fan count calculation.
+ *
+ *     Revision 1.39  1999/05/20 14:54:43  malthoff
+ *     I2c.DummyReads is not used in Diagnostics.
+ *
+ *     Revision 1.38  1999/05/20 09:20:56  cgoos
+ *     Changes for 1000Base-T (up to 9 sensors and fans).
+ *
+ *     Revision 1.37  1999/03/25 15:11:36  gklug
+ *     fix: reset error flag if sensor reads correct value
+ *
+ *     Revision 1.36  1999/01/07 14:11:16  gklug
+ *     fix: break added
+ *
+ *     Revision 1.35  1999/01/05 15:31:49  gklug
+ *     fix: CLEAR STAT command is now added correctly
+ *
+ *     Revision 1.34  1998/12/01 13:45:16  gklug
+ *     fix: introduced Init level, because we don't need reinits
+ *
+ *     Revision 1.33  1998/11/09 14:54:25  malthoff
+ *     Modify I2C Transfer Timeout handling for Diagnostics.
+ *
+ *     Revision 1.32  1998/11/03 06:54:35  gklug
+ *     fix: Need dummy reads at the beginning to init sensors
+ *
+ *     Revision 1.31  1998/11/03 06:42:42  gklug
+ *     fix: select correctVIO range only if between warning levels
+ *
+ *     Revision 1.30  1998/11/02 07:36:53  gklug
+ *     fix: Error should not include WARNING message
+ *
+ *     Revision 1.29  1998/10/30 15:07:43  malthoff
+ *     Disable 'I2C does not compelete' error log for diagnostics.
+ *
+ *     Revision 1.28  1998/10/22 09:48:11  gklug
+ *     fix: SysKonnectFileId typo
+ *
+ *     Revision 1.27  1998/10/20 09:59:46  gklug
+ *     add: parameter to SkOsGetTime
+ *
+ *     Revision 1.26  1998/10/09 06:10:59  malthoff
+ *     Remove ID_sccs by SysKonnectFileId.
+ *
+ *     Revision 1.25  1998/09/08 12:40:26  gklug
+ *     fix: syntax error in if clause
+ *
+ *     Revision 1.24  1998/09/08 12:19:42  gklug
+ *     chg: INIT Level checking
+ *
+ *     Revision 1.23  1998/09/08 07:37:20  gklug
+ *     fix: log error if PCI_IO voltage sensor could not be initialized
+ *
+ *     Revision 1.22  1998/09/04 08:30:03  malthoff
+ *     Bugfixes during SK_DIAG testing:
+ *     - correct NS2BCLK() macro
+ *     - correct SkI2cSndDev()
+ *     - correct SkI2cWait() loop waiting for an event
+ *
+ *     Revision 1.21  1998/08/27 14:46:01  gklug
+ *     chg: if-then-else replaced by switch
+ *
+ *     Revision 1.20  1998/08/27 14:40:07  gklug
+ *     test: integral types
+ *
+ *     Revision 1.19  1998/08/25 07:51:54  gklug
+ *     fix: typos for compiling
+ *
+ *     Revision 1.18  1998/08/25 06:12:24  gklug
+ *     add: count errors and warnings
+ *     fix: check not the sensor state but the ErrFlag!
+ *
+ *     Revision 1.17  1998/08/25 05:56:48  gklug
+ *     add: CheckSensor function
+ *
+ *     Revision 1.16  1998/08/20 11:41:10  gklug
+ *     chg: omit STRCPY macro by using char * as Sensor Description
+ *
+ *     Revision 1.15  1998/08/20 11:37:35  gklug
+ *     chg: change Ioc to IoC
+ *
+ *     Revision 1.14  1998/08/20 11:32:52  gklug
+ *     fix: Para compile error
+ *
+ *     Revision 1.13  1998/08/20 11:27:41  gklug
+ *     fix: Compile bugs with new awrning constants
+ *
+ *     Revision 1.12  1998/08/20 08:53:05  gklug
+ *     fix: compiler errors
+ *     add: Threshold values
+ *
+ *     Revision 1.11  1998/08/19 12:39:22  malthoff
+ *     Compiler Fix: Some names have changed.
+ *
+ *     Revision 1.10  1998/08/19 12:20:56  gklug
+ *     fix: remove struct from C files (see CCC)
+ *
+ *     Revision 1.9  1998/08/19 06:28:46  malthoff
+ *     SkOsGetTime returns SK_U64 now.
+ *
+ *     Revision 1.8  1998/08/17 13:53:33  gklug
+ *     fix: Parameter of event function and its result
+ *
+ *     Revision 1.7  1998/08/17 07:02:15  malthoff
+ *     Modify the functions for accessing the I2C SW Registers.
+ *     Modify SkI2cWait().
+ *     Put Lm80RcvReg into sklm80.c
+ *     Remove Compiler Errors.
+ *
+ *     Revision 1.6  1998/08/14 07:13:20  malthoff
+ *     remove pAc with pAC
+ *     remove smc with pAC
+ *     change names to new convention
+ *
+ *     Revision 1.5  1998/08/14 06:24:49  gklug
+ *     add: init level 1 and 2
+ *
+ *     Revision 1.4  1998/08/12 14:31:12  gklug
+ *     add: error log for unknown event
+ *
+ *     Revision 1.3  1998/08/12 13:37:04  gklug
+ *     add: Init 0 function
+ *
+ *     Revision 1.2  1998/08/11 07:27:15  gklug
+ *     add: functions of the interface
+ *     adapt rest of source to C coding Conventions
+ *     rmv: unnecessary code taken from Mona Lisa
+ *
+ *     Revision 1.1  1998/06/19 14:28:43  malthoff
+ *     Created. Sources taken from ML Projekt.
+ *     Sources have to be reworked for GE.
+ *
+ *
+ ******************************************************************************/
+
+
+#include <config.h>
+
+#ifdef CONFIG_SK98
+
+/*
+ *     I2C Protocol
+ */
+static const char SysKonnectFileId[] =
+       "$Id: ski2c.c,v 1.57 2003/01/28 09:17:38 rschmidt Exp $";
+
+#include "h/skdrv1st.h"                /* Driver Specific Definitions */
+#include "h/lm80.h"
+#include "h/skdrv2nd.h"                /* Adapter Control- and Driver specific Def. */
+
+#ifdef __C2MAN__
+/*
+       I2C protocol implementation.
+
+       General Description:
+
+       The I2C protocol is used for the temperature sensors and for
+       the serial EEPROM which hold the configuration.
+
+       This file covers functions that allow to read write and do
+       some bulk requests a specified I2C address.
+
+       The Genesis has 2 I2C buses. One for the EEPROM which holds
+       the VPD Data and one for temperature and voltage sensor.
+       The following picture shows the I2C buses, I2C devices and
+       their control registers.
+
+       Note: The VPD functions are in skvpd.c
+.
+.      PCI Config I2C Bus for VPD Data:
+.
+.                    +------------+
+.                    | VPD EEPROM |
+.                    +------------+
+.                           |
+.                           | <-- I2C
+.                           |
+.               +-----------+-----------+
+.               |                       |
+.      +-----------------+     +-----------------+
+.      | PCI_VPD_ADR_REG |     | PCI_VPD_DAT_REG |
+.      +-----------------+     +-----------------+
+.
+.
+.      I2C Bus for LM80 sensor:
+.
+.                      +-----------------+
+.                      | Temperature and |
+.                      | Voltage Sensor  |
+.                      |       LM80      |
+.                      +-----------------+
+.                              |
+.                              |
+.                      I2C --> |
+.                              |
+.                           +----+
+.           +-------------->| OR |<--+
+.           |               +----+   |
+.     +------+------+                |
+.     |                    |                 |
+. +--------+   +--------+      +----------+
+. | B2_I2C |   | B2_I2C |      |  B2_I2C  |
+. | _CTRL  |   | _DATA  |      |   _SW    |
+. +--------+   +--------+      +----------+
+.
+       The I2C bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL
+       and B2_I2C_DATA registers.
+       For driver software it is recommended to use the I2C control and
+       data register, because I2C bus timing is done by the ASIC and
+       an interrupt may be received when the I2C request is completed.
+
+       Clock Rate Timing:                      MIN     MAX     generated by
+               VPD EEPROM:                     50 kHz  100 kHz         HW
+               LM80 over I2C Ctrl/Data reg.    50 kHz  100 kHz         HW
+               LM80 over B2_I2C_SW register    0       400 kHz         SW
+
+       Note:   The clock generated by the hardware is dependend on the
+               PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD
+               clock is 50 kHz.
+ */
+intro()
+{}
+#endif
+
+#ifdef SK_DIAG
+/*
+ * I2C Fast Mode timing values used by the LM80.
+ * If new devices are added to the I2C bus the timing values have to be checked.
+ */
+#ifndef I2C_SLOW_TIMING
+#define        T_CLK_LOW                       1300L   /* clock low time in ns */
+#define        T_CLK_HIGH                       600L   /* clock high time in ns */
+#define T_DATA_IN_SETUP                 100L   /* data in Set-up Time */
+#define T_START_HOLD            600L   /* start condition hold time */
+#define T_START_SETUP           600L   /* start condition Set-up time */
+#define        T_STOP_SETUP             600L   /* stop condition Set-up time */
+#define T_BUS_IDLE                     1300L   /* time the bus must free after Tx */
+#define        T_CLK_2_DATA_OUT         900L   /* max. clock low to data output valid */
+#else  /* I2C_SLOW_TIMING */
+/* I2C Standard Mode Timing */
+#define        T_CLK_LOW                       4700L   /* clock low time in ns */
+#define        T_CLK_HIGH                      4000L   /* clock high time in ns */
+#define T_DATA_IN_SETUP                 250L   /* data in Set-up Time */
+#define T_START_HOLD           4000L   /* start condition hold time */
+#define T_START_SETUP          4700L   /* start condition Set-up time */
+#define        T_STOP_SETUP            4000L   /* stop condition Set-up time */
+#define T_BUS_IDLE                     4700L   /* time the bus must free after Tx */
+#endif /* !I2C_SLOW_TIMING */
+
+#define NS2BCLK(x)     (((x)*125)/10000)
+
+/*
+ * I2C Wire Operations
+ *
+ * About I2C_CLK_LOW():
+ *
+ * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting
+ * clock to low, to prevent the ASIC and the I2C data client from driving the
+ * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client
+ * send an 'ACK'). See also Concentrator Bugreport No. 10192.
+ */
+#define I2C_DATA_HIGH(IoC)     SK_I2C_SET_BIT(IoC, I2C_DATA)
+#define        I2C_DATA_LOW(IoC)       SK_I2C_CLR_BIT(IoC, I2C_DATA)
+#define        I2C_DATA_OUT(IoC)       SK_I2C_SET_BIT(IoC, I2C_DATA_DIR)
+#define        I2C_DATA_IN(IoC)        SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA)
+#define        I2C_CLK_HIGH(IoC)       SK_I2C_SET_BIT(IoC, I2C_CLK)
+#define        I2C_CLK_LOW(IoC)        SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR)
+#define        I2C_START_COND(IoC)     SK_I2C_CLR_BIT(IoC, I2C_CLK)
+
+#define NS2CLKT(x)     ((x*125L)/10000)
+
+/*--------------- I2C Interface Register Functions --------------- */
+
+/*
+ * sending one bit
+ */
+void SkI2cSndBit(
+SK_IOC IoC,    /* I/O Context */
+SK_U8  Bit)    /* Bit to send */
+{
+       I2C_DATA_OUT(IoC);
+       if (Bit) {
+               I2C_DATA_HIGH(IoC);
+       }
+       else {
+               I2C_DATA_LOW(IoC);
+       }
+       SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
+       I2C_CLK_HIGH(IoC);
+       SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
+       I2C_CLK_LOW(IoC);
+}      /* SkI2cSndBit*/
+
+
+/*
+ * Signal a start to the I2C Bus.
+ *
+ * A start is signaled when data goes to low in a high clock cycle.
+ *
+ * Ends with Clock Low.
+ *
+ * Status: not tested
+ */
+void SkI2cStart(
+SK_IOC IoC)    /* I/O Context */
+{
+       /* Init data and Clock to output lines */
+       /* Set Data high */
+       I2C_DATA_OUT(IoC);
+       I2C_DATA_HIGH(IoC);
+       /* Set Clock high */
+       I2C_CLK_HIGH(IoC);
+
+       SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
+
+       /* Set Data Low */
+       I2C_DATA_LOW(IoC);
+
+       SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
+
+       /* Clock low without Data to Input */
+       I2C_START_COND(IoC);
+
+       SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
+}      /* SkI2cStart */
+
+
+void SkI2cStop(
+SK_IOC IoC)    /* I/O Context */
+{
+       /* Init data and Clock to output lines */
+       /* Set Data low */
+       I2C_DATA_OUT(IoC);
+       I2C_DATA_LOW(IoC);
+
+       SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
+
+       /* Set Clock high */
+       I2C_CLK_HIGH(IoC);
+
+       SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
+
+       /*
+        * Set Data High:       Do it by setting the Data Line to Input.
+        *                      Because of a pull up resistor the Data Line
+        *                      floods to high.
+        */
+       I2C_DATA_IN(IoC);
+
+       /*
+        *      When I2C activity is stopped
+        *       o      DATA should be set to input and
+        *       o      CLOCK should be set to high!
+        */
+       SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
+}      /* SkI2cStop */
+
+
+/*
+ * Receive just one bit via the I2C bus.
+ *
+ * Note:       Clock must be set to LOW before calling this function.
+ *
+ * Returns The received bit.
+ */
+int SkI2cRcvBit(
+SK_IOC IoC)    /* I/O Context */
+{
+       int     Bit;
+       SK_U8   I2cSwCtrl;
+
+       /* Init data as input line */
+       I2C_DATA_IN(IoC);
+
+       SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
+
+       I2C_CLK_HIGH(IoC);
+
+       SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
+
+       SK_I2C_GET_SW(IoC, &I2cSwCtrl);
+
+       Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
+
+       I2C_CLK_LOW(IoC);
+       SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
+
+       return(Bit);
+}      /* SkI2cRcvBit */
+
+
+/*
+ * Receive an ACK.
+ *
+ * returns     0 If acknowledged
+ *             1 in case of an error
+ */
+int SkI2cRcvAck(
+SK_IOC IoC)    /* I/O Context */
+{
+       /*
+        * Received bit must be zero.
+        */
+       return(SkI2cRcvBit(IoC) != 0);
+}      /* SkI2cRcvAck */
+
+
+/*
+ * Send an NACK.
+ */
+void SkI2cSndNAck(
+SK_IOC IoC)    /* I/O Context */
+{
+       /*
+        * Received bit must be zero.
+        */
+       SkI2cSndBit(IoC, 1);
+}      /* SkI2cSndNAck */
+
+
+/*
+ * Send an ACK.
+ */
+void SkI2cSndAck(
+SK_IOC IoC)    /* I/O Context */
+{
+       /*
+        * Received bit must be zero.
+        *
+        */
+       SkI2cSndBit(IoC, 0);
+}      /* SkI2cSndAck */
+
+
+/*
+ * Send one byte to the I2C device and wait for ACK.
+ *
+ * Return acknowleged status.
+ */
+int SkI2cSndByte(
+SK_IOC IoC,    /* I/O Context */
+int            Byte)   /* byte to send */
+{
+       int     i;
+
+       for (i = 0; i < 8; i++) {
+               if (Byte & (1<<(7-i))) {
+                       SkI2cSndBit(IoC, 1);
+               }
+               else {
+                       SkI2cSndBit(IoC, 0);
+               }
+       }
+
+       return(SkI2cRcvAck(IoC));
+}      /* SkI2cSndByte */
+
+
+/*
+ * Receive one byte and ack it.
+ *
+ * Return byte.
+ */
+int SkI2cRcvByte(
+SK_IOC IoC,    /* I/O Context */
+int            Last)   /* Last Byte Flag */
+{
+       int     i;
+       int     Byte = 0;
+
+       for (i = 0; i < 8; i++) {
+               Byte <<= 1;
+               Byte |= SkI2cRcvBit(IoC);
+       }
+
+       if (Last) {
+               SkI2cSndNAck(IoC);
+       }
+       else {
+               SkI2cSndAck(IoC);
+       }
+
+       return(Byte);
+}      /* SkI2cRcvByte */
+
+
+/*
+ * Start dialog and send device address
+ *
+ * Return 0 if acknowleged, 1 in case of an error
+ */
+int    SkI2cSndDev(
+SK_IOC IoC,    /* I/O Context */
+int            Addr,   /* Device Address */
+int            Rw)             /* Read / Write Flag */
+{
+       SkI2cStart(IoC);
+       Rw = ~Rw;
+       Rw &= I2C_WRITE;
+       return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
+}      /* SkI2cSndDev */
+
+#endif /* SK_DIAG */
+
+/*----------------- I2C CTRL Register Functions ----------*/
+
+/*
+ * waits for a completion of an I2C transfer
+ *
+ * returns     0:      success, transfer completes
+ *                     1:      error,   transfer does not complete, I2C transfer
+ *                                              killed, wait loop terminated.
+ */
+int    SkI2cWait(
+SK_AC  *pAC,   /* Adapter Context */
+SK_IOC IoC,    /* I/O Context */
+int            Event)  /* complete event to wait for (I2C_READ or I2C_WRITE) */
+{
+       SK_U64  StartTime;
+       SK_U64  CurrentTime;
+       SK_U32  I2cCtrl;
+
+       StartTime = SkOsGetTime(pAC);
+
+       do {
+               CurrentTime = SkOsGetTime(pAC);
+
+               if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
+
+                       SK_I2C_STOP(IoC);
+#ifndef SK_DIAG
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
+#endif /* !SK_DIAG */
+                       return(1);
+               }
+
+               SK_I2C_GET_CTL(IoC, &I2cCtrl);
+
+#ifdef xYUKON_DBG
+               printf("StartTime=%lu, CurrentTime=%lu\n",
+                       StartTime, CurrentTime);
+               if (kbhit()) {
+                       return(1);
+               }
+#endif /* YUKON_DBG */
+
+       } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
+
+       return(0);
+}      /* SkI2cWait */
+
+
+/*
+ * waits for a completion of an I2C transfer
+ *
+ * Returns
+ *     Nothing
+ */
+void SkI2cWaitIrq(
+SK_AC  *pAC,   /* Adapter Context */
+SK_IOC IoC)    /* I/O Context */
+{
+       SK_SENSOR       *pSen;
+       SK_U64          StartTime;
+       SK_U32          IrqSrc;
+
+       pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
+
+       if (pSen->SenState == SK_SEN_IDLE) {
+               return;
+       }
+
+       StartTime = SkOsGetTime(pAC);
+       do {
+               if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
+                       SK_I2C_STOP(IoC);
+#ifndef SK_DIAG
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
+#endif /* !SK_DIAG */
+                       return;
+               }
+               SK_IN32(IoC, B0_ISRC, &IrqSrc);
+       } while ((IrqSrc & IS_I2C_READY) == 0);
+
+       pSen->SenState = SK_SEN_IDLE;
+       return;
+}      /* SkI2cWaitIrq */
+
+/*
+ * writes a single byte or 4 bytes into the I2C device
+ *
+ * returns     0:      success
+ *                     1:      error
+ */
+int SkI2cWrite(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* I/O Context */
+SK_U32 I2cData,        /* I2C Data to write */
+int            I2cDev,         /* I2C Device Address */
+int            I2cReg,         /* I2C Device Register Address */
+int            I2cBurst)       /* I2C Burst Flag */
+{
+       SK_OUT32(IoC, B2_I2C_DATA, I2cData);
+       SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cReg, I2cBurst);
+
+       return(SkI2cWait(pAC, IoC, I2C_WRITE));
+}      /* SkI2cWrite*/
+
+
+#ifdef SK_DIAG
+
+/*
+ * reads a single byte or 4 bytes from the I2C device
+ *
+ * returns     the word read
+ */
+SK_U32 SkI2cRead(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* I/O Context */
+int            I2cDev,         /* I2C Device Address */
+int            I2cReg,         /* I2C Device Register Address */
+int            I2cBurst)       /* I2C Burst Flag */
+{
+       SK_U32  Data;
+
+       SK_OUT32(IoC, B2_I2C_DATA, 0);
+       SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cReg, I2cBurst);
+
+       if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
+               w_print("%s\n", SKERR_I2C_E002MSG);
+       }
+
+       SK_IN32(IoC, B2_I2C_DATA, &Data);
+       return(Data);
+}      /* SkI2cRead */
+
+#endif /* SK_DIAG */
+
+
+/*
+ * read a sensor's value
+ *
+ * This function reads a sensor's value from the I2C sensor chip. The sensor
+ * is defined by its index into the sensors database in the struct pAC points
+ * to.
+ * Returns
+ *             1 if the read is completed
+ *             0 if the read must be continued (I2C Bus still allocated)
+ */
+int    SkI2cReadSensor(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_SENSOR      *pSen)  /* Sensor to be read */
+{
+    if (pSen->SenRead != NULL) {
+       return((*pSen->SenRead)(pAC, IoC, pSen));
+    }
+    else
+       return(0); /* no success */
+}      /* SkI2cReadSensor*/
+
+/*
+ * Do the Init state 0 initialization
+ */
+static int SkI2cInit0(
+SK_AC  *pAC)   /* Adapter Context */
+{
+       int     i;
+
+       /* Begin with first sensor */
+       pAC->I2c.CurrSens = 0;
+
+       /* Begin with timeout control for state machine */
+       pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
+
+       /* Set sensor number to zero */
+       pAC->I2c.MaxSens = 0;
+
+#ifndef        SK_DIAG
+       /* Initialize Number of Dummy Reads */
+       pAC->I2c.DummyReads = SK_MAX_SENSORS;
+#endif
+
+       for (i = 0; i < SK_MAX_SENSORS; i++) {
+               pAC->I2c.SenTable[i].SenDesc = "unknown";
+               pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN;
+               pAC->I2c.SenTable[i].SenThreErrHigh = 0;
+               pAC->I2c.SenTable[i].SenThreErrLow = 0;
+               pAC->I2c.SenTable[i].SenThreWarnHigh = 0;
+               pAC->I2c.SenTable[i].SenThreWarnLow = 0;
+               pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
+               pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE;
+               pAC->I2c.SenTable[i].SenValue = 0;
+               pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT;
+               pAC->I2c.SenTable[i].SenErrCts = 0;
+               pAC->I2c.SenTable[i].SenBegErrTS = 0;
+               pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
+               pAC->I2c.SenTable[i].SenRead = NULL;
+               pAC->I2c.SenTable[i].SenDev = 0;
+       }
+
+       /* Now we are "INIT data"ed */
+       pAC->I2c.InitLevel = SK_INIT_DATA;
+       return(0);
+}      /* SkI2cInit0*/
+
+
+/*
+ * Do the init state 1 initialization
+ *
+ * initialize the following register of the LM80:
+ * Configuration register:
+ * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
+ *
+ * Interrupt Mask Register 1:
+ * - all interrupts are Disabled (0xff)
+ *
+ * Interrupt Mask Register 2:
+ * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
+ *
+ * Fan Divisor/RST_OUT register:
+ * - Divisors set to 1 (bits 00), all others 0s.
+ *
+ * OS# Configuration/Temperature resolution Register:
+ * - all 0s
+ *
+ */
+static int SkI2cInit1(
+SK_AC  *pAC,   /* Adapter Context */
+SK_IOC IoC)    /* I/O Context */
+{
+    int i;
+    SK_U8 I2cSwCtrl;
+       SK_GEPORT *pPrt;        /* GIni Port struct pointer */
+
+       if (pAC->I2c.InitLevel != SK_INIT_DATA) {
+               /* ReInit not needed in I2C module */
+               return(0);
+       }
+
+    /* Set the Direction of I2C-Data Pin to IN */
+    SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA);
+    /* Check for 32-Bit Yukon with Low at I2C-Data Pin */
+       SK_I2C_GET_SW(IoC, &I2cSwCtrl);
+
+       if ((I2cSwCtrl & I2C_DATA) == 0) {
+               /* this is a 32-Bit board */
+               pAC->GIni.GIYukon32Bit = SK_TRUE;
+       return(0);
+    }
+
+       /* Check for 64 Bit Yukon without sensors */
+       if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_CFG, 0) != 0) {
+       return(0);
+    }
+
+       (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_1, 0);
+
+       (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_2, 0);
+
+       (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_FAN_CTRL, 0);
+
+       (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_TEMP_CTRL, 0);
+
+       (void)SkI2cWrite(pAC, IoC, LM80_CFG_START, LM80_ADDR, LM80_CFG, 0);
+
+       /*
+        * MaxSens has to be updated here, because PhyType is not
+        * set when performing Init Level 0
+        */
+    pAC->I2c.MaxSens = 5;
+
+       pPrt = &pAC->GIni.GP[0];
+
+       if (pAC->GIni.GIGenesis) {
+               if (pPrt->PhyType == SK_PHY_BCOM) {
+                       if (pAC->GIni.GIMacsFound == 1) {
+                               pAC->I2c.MaxSens += 1;
+                       }
+                       else {
+                               pAC->I2c.MaxSens += 3;
+                       }
+               }
+       }
+       else {
+               pAC->I2c.MaxSens += 3;
+       }
+
+       for (i = 0; i < pAC->I2c.MaxSens; i++) {
+               switch (i) {
+               case 0:
+                       pAC->I2c.SenTable[i].SenDesc = "Temperature";
+                       pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP;
+                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR;
+                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN;
+                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN;
+                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR;
+                       pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN;
+                       break;
+               case 1:
+                       pAC->I2c.SenTable[i].SenDesc = "Voltage PCI";
+                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR;
+                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN;
+                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN;
+                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR;
+                       pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN;
+                       break;
+               case 2:
+                       pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO";
+                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR;
+                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN;
+                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN;
+                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR;
+                       pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN;
+                       pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO;
+                       break;
+               case 3:
+                       pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC";
+                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR;
+                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN;
+                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN;
+                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR;
+                       pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN;
+                       break;
+               case 4:
+                       if (pAC->GIni.GIGenesis) {
+                               if (pPrt->PhyType == SK_PHY_BCOM) {
+                                       pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL";
+                                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
+                                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
+                                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
+                                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
+                               }
+                               else {
+                                       pAC->I2c.SenTable[i].SenDesc = "Voltage PMA";
+                                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
+                                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
+                                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
+                                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
+                               }
+                       }
+                       else {
+                               pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX";
+                               pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR;
+                               pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN;
+                               if (pAC->GIni.GIVauxAvail) {
+                                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
+                                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
+                               }
+                               else {
+                                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR;
+                                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR;
+                               }
+                       }
+                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+                       pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN;
+                       break;
+               case 5:
+                       if (pAC->GIni.GIGenesis) {
+                               pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
+                               pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
+                               pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
+                               pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
+                               pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
+                       }
+                       else {
+                               pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC-Co 1V5";
+                               pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
+                               pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
+                               pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
+                               pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
+                       }
+                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+                       pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN;
+                       break;
+               case 6:
+                       if (pAC->GIni.GIGenesis) {
+                               pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL";
+                       }
+                       else {
+                               pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3";
+                       }
+                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
+                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
+                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
+                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
+                       pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN;
+                       break;
+               case 7:
+                       if (pAC->GIni.GIGenesis) {
+                               pAC->I2c.SenTable[i].SenDesc = "Speed Fan";
+                               pAC->I2c.SenTable[i].SenType = SK_SEN_FAN;
+                               pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR;
+                               pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN;
+                               pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN;
+                               pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR;
+                               pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
+                       }
+                       else {
+                               pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
+                               pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+                               pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
+                               pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
+                               pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
+                               pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
+                               pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN;
+                       }
+                       break;
+               default:
+                       SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
+                               SKERR_I2C_E001, SKERR_I2C_E001MSG);
+                       break;
+               }
+
+               pAC->I2c.SenTable[i].SenValue = 0;
+               pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
+               pAC->I2c.SenTable[i].SenErrCts = 0;
+               pAC->I2c.SenTable[i].SenBegErrTS = 0;
+               pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
+               pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor;
+               pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
+       }
+
+#ifndef        SK_DIAG
+       pAC->I2c.DummyReads = pAC->I2c.MaxSens;
+#endif /* !SK_DIAG */
+
+       /* Clear I2C IRQ */
+       SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
+
+       /* Now we are I/O initialized */
+       pAC->I2c.InitLevel = SK_INIT_IO;
+       return(0);
+}      /* SkI2cInit1 */
+
+
+/*
+ * Init level 2: Start first sensor read.
+ */
+static int SkI2cInit2(
+SK_AC  *pAC,   /* Adapter Context */
+SK_IOC IoC)    /* I/O Context */
+{
+       int             ReadComplete;
+       SK_SENSOR       *pSen;
+
+       if (pAC->I2c.InitLevel != SK_INIT_IO) {
+               /* ReInit not needed in I2C module */
+               /* Init0 and Init2 not permitted */
+               return(0);
+       }
+
+       pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
+       ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
+
+       if (ReadComplete) {
+               SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
+       }
+
+       /* Now we are correctly initialized */
+       pAC->I2c.InitLevel = SK_INIT_RUN;
+
+       return(0);
+}      /* SkI2cInit2*/
+
+
+/*
+ * Initialize I2C devices
+ *
+ * Get the first voltage value and discard it.
+ * Go into temperature read mode. A default pointer is not set.
+ *
+ * The things to be done depend on the init level in the parameter list:
+ * Level 0:
+ *     Initialize only the data structures. Do NOT access hardware.
+ * Level 1:
+ *     Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
+ * Level 2:
+ *     Everything is possible. Interrupts may be used from now on.
+ *
+ * return:
+ *     0 = success
+ *     other = error.
+ */
+int    SkI2cInit(
+SK_AC  *pAC,   /* Adapter Context */
+SK_IOC IoC,    /* I/O Context needed in levels 1 and 2 */
+int            Level)  /* Init Level */
+{
+
+       switch (Level) {
+       case SK_INIT_DATA:
+               return(SkI2cInit0(pAC));
+       case SK_INIT_IO:
+               return(SkI2cInit1(pAC, IoC));
+       case SK_INIT_RUN:
+               return(SkI2cInit2(pAC, IoC));
+       default:
+               break;
+       }
+
+       return(0);
+}      /* SkI2cInit */
+
+
+#ifndef SK_DIAG
+
+/*
+ * Interrupt service function for the I2C Interface
+ *
+ * Clears the Interrupt source
+ *
+ * Reads the register and check it for sending a trap.
+ *
+ * Starts the timer if necessary.
+ */
+void SkI2cIsr(
+SK_AC  *pAC,   /* Adapter Context */
+SK_IOC IoC)    /* I/O Context */
+{
+       SK_EVPARA       Para;
+
+       /* Clear I2C IRQ */
+       SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
+
+       Para.Para64 = 0;
+       SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
+}      /* SkI2cIsr */
+
+
+/*
+ * Check this sensors Value against the threshold and send events.
+ */
+static void SkI2cCheckSensor(
+SK_AC          *pAC,   /* Adapter Context */
+SK_SENSOR      *pSen)
+{
+       SK_EVPARA       ParaLocal;
+       SK_BOOL         TooHigh;        /* Is sensor too high? */
+       SK_BOOL         TooLow;         /* Is sensor too low? */
+       SK_U64          CurrTime;       /* Current Time */
+       SK_BOOL         DoTrapSend;     /* We need to send a trap */
+       SK_BOOL         DoErrLog;       /* We need to log the error */
+       SK_BOOL         IsError;        /* We need to log the error */
+
+       /* Check Dummy Reads first */
+       if (pAC->I2c.DummyReads > 0) {
+               pAC->I2c.DummyReads--;
+               return;
+       }
+
+       /* Get the current time */
+       CurrTime = SkOsGetTime(pAC);
+
+       /* Set para to the most useful setting: The current sensor. */
+       ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
+
+       /* Check the Value against the thresholds. First: Error Thresholds */
+       TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
+       TooLow = (pSen->SenValue < pSen->SenThreErrLow);
+
+       IsError = SK_FALSE;
+       if (TooHigh || TooLow) {
+               /* Error condition is satisfied */
+               DoTrapSend = SK_TRUE;
+               DoErrLog = SK_TRUE;
+
+               /* Now error condition is satisfied */
+               IsError = SK_TRUE;
+
+               if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
+                       /* This state is the former one */
+
+                       /* So check first whether we have to send a trap */
+                       if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD >
+                           CurrTime) {
+                               /*
+                                * Do NOT send the Trap. The hold back time
+                                * has to run out first.
+                                */
+                               DoTrapSend = SK_FALSE;
+                       }
+
+                       /* Check now whether we have to log an Error */
+                       if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD >
+                           CurrTime) {
+                               /*
+                                * Do NOT log the error. The hold back time
+                                * has to run out first.
+                                */
+                               DoErrLog = SK_FALSE;
+                       }
+               }
+               else {
+                       /* We came from a different state -> Set Begin Time Stamp */
+                       pSen->SenBegErrTS = CurrTime;
+                       pSen->SenErrFlag = SK_SEN_ERR_ERR;
+               }
+
+               if (DoTrapSend) {
+                       /* Set current Time */
+                       pSen->SenLastErrTrapTS = CurrTime;
+                       pSen->SenErrCts++;
+
+                       /* Queue PNMI Event */
+                       SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
+                               SK_PNMI_EVT_SEN_ERR_UPP :
+                               SK_PNMI_EVT_SEN_ERR_LOW),
+                               ParaLocal);
+               }
+
+               if (DoErrLog) {
+                       /* Set current Time */
+                       pSen->SenLastErrLogTS = CurrTime;
+
+                       if (pSen->SenType == SK_SEN_TEMP) {
+                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011,
+                                       SKERR_I2C_E011MSG);
+                       } else if (pSen->SenType == SK_SEN_VOLT) {
+                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012,
+                                       SKERR_I2C_E012MSG);
+                       } else
+                       {
+                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015,
+                                       SKERR_I2C_E015MSG);
+                       }
+               }
+       }
+
+       /* Check the Value against the thresholds */
+       /* 2nd: Warning thresholds */
+       TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
+       TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
+
+       if (!IsError && (TooHigh || TooLow)) {
+               /* Error condition is satisfied */
+               DoTrapSend = SK_TRUE;
+               DoErrLog = SK_TRUE;
+
+               if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
+                       /* This state is the former one */
+
+                       /* So check first whether we have to send a trap */
+                       if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD >
+                           CurrTime) {
+                               /*
+                                * Do NOT send the Trap. The hold back time
+                                * has to run out first.
+                                */
+                               DoTrapSend = SK_FALSE;
+                       }
+
+                       /* Check now whether we have to log an Error */
+                       if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD >
+                           CurrTime) {
+                               /*
+                                * Do NOT log the error. The hold back time
+                                * has to run out first.
+                                */
+                               DoErrLog = SK_FALSE;
+                       }
+               }
+               else {
+                       /* We came from a different state -> Set Begin Time Stamp */
+                       pSen->SenBegWarnTS = CurrTime;
+                       pSen->SenErrFlag = SK_SEN_ERR_WARN;
+               }
+
+               if (DoTrapSend) {
+                       /* Set current Time */
+                       pSen->SenLastWarnTrapTS = CurrTime;
+                       pSen->SenWarnCts++;
+
+                       /* Queue PNMI Event */
+                       SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
+                               SK_PNMI_EVT_SEN_WAR_UPP :
+                               SK_PNMI_EVT_SEN_WAR_LOW),
+                               ParaLocal);
+               }
+
+               if (DoErrLog) {
+                       /* Set current Time */
+                       pSen->SenLastWarnLogTS = CurrTime;
+
+                       if (pSen->SenType == SK_SEN_TEMP) {
+                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009,
+                                       SKERR_I2C_E009MSG);
+                       } else if (pSen->SenType == SK_SEN_VOLT) {
+                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010,
+                                       SKERR_I2C_E010MSG);
+                       } else
+                       {
+                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014,
+                                       SKERR_I2C_E014MSG);
+                       }
+               }
+       }
+
+       /* Check for NO error at all */
+       if (!IsError && !TooHigh && !TooLow) {
+               /* Set o.k. Status if no error and no warning condition */
+               pSen->SenErrFlag = SK_SEN_ERR_OK;
+       }
+
+       /* End of check against the thresholds */
+
+       /* Bug fix AF: 16.Aug.2001: Correct the init base
+        * of LM80 sensor.
+        */
+       if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
+
+       pSen->SenInit = SK_SEN_DYN_INIT_NONE;
+
+               if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) {
+                       /* 5V PCI-IO Voltage */
+                       pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN;
+                       pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR;
+               }
+               else {
+                       /* 3.3V PCI-IO Voltage */
+                       pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN;
+                       pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR;
+               }
+       }
+
+#if 0
+    /* Dynamic thresholds also for VAUX of LM80 sensor */
+       if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
+
+       pSen->SenInit = SK_SEN_DYN_INIT_NONE;
+
+               /* 3.3V VAUX Voltage */
+               if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) {
+                       pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
+                       pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
+               }
+               /* 0V VAUX Voltage */
+               else {
+                       pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
+                       pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
+               }
+       }
+
+       /*
+        * Check initialization state:
+        * The VIO Thresholds need adaption
+        */
+       if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
+            pSen->SenValue > SK_SEN_WARNLOW2C &&
+            pSen->SenValue < SK_SEN_WARNHIGH2) {
+               pSen->SenThreErrLow = SK_SEN_ERRLOW2C;
+               pSen->SenThreWarnLow = SK_SEN_WARNLOW2C;
+               pSen->SenInit = SK_TRUE;
+       }
+
+       if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
+            pSen->SenValue > SK_SEN_WARNLOW2 &&
+            pSen->SenValue < SK_SEN_WARNHIGH2C) {
+               pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C;
+               pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C;
+               pSen->SenInit = SK_TRUE;
+       }
+#endif
+
+       if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
+               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
+       }
+}      /* SkI2cCheckSensor*/
+
+
+/*
+ * The only Event to be served is the timeout event
+ *
+ */
+int    SkI2cEvent(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_U32         Event,  /* Module specific Event */
+SK_EVPARA      Para)   /* Event specific Parameter */
+{
+       int                     ReadComplete;
+       SK_SENSOR       *pSen;
+       SK_U32          Time;
+       SK_EVPARA       ParaLocal;
+       int                     i;
+
+       /* New case: no sensors */
+       if (pAC->I2c.MaxSens == 0) {
+               return(0);
+       }
+
+       switch (Event) {
+       case SK_I2CEV_IRQ:
+               pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
+               ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
+
+               if (ReadComplete) {
+                       /* Check sensor against defined thresholds */
+                       SkI2cCheckSensor (pAC, pSen);
+
+                       /* Increment Current sensor and set appropriate Timeout */
+                       pAC->I2c.CurrSens++;
+                       if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) {
+                               pAC->I2c.CurrSens = 0;
+                               Time = SK_I2C_TIM_LONG;
+                       }
+                       else {
+                               Time = SK_I2C_TIM_SHORT;
+                       }
+
+                       /* Start Timer */
+                       ParaLocal.Para64 = (SK_U64)0;
+
+                       pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
+
+                       SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
+                               SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
+               }
+       else {
+                       /* Start Timer */
+                       ParaLocal.Para64 = (SK_U64)0;
+
+                       pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
+
+           SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
+                               SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
+               }
+               break;
+       case SK_I2CEV_TIM:
+               if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
+
+                       ParaLocal.Para64 = (SK_U64)0;
+                       SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
+
+                       pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
+                       ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
+
+                       if (ReadComplete) {
+                               /* Check sensor against defined thresholds */
+                               SkI2cCheckSensor (pAC, pSen);
+
+                               /* Increment Current sensor and set appropriate Timeout */
+                               pAC->I2c.CurrSens++;
+                               if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
+                                       pAC->I2c.CurrSens = 0;
+                                       Time = SK_I2C_TIM_LONG;
+                               }
+                               else {
+                                       Time = SK_I2C_TIM_SHORT;
+                               }
+
+                               /* Start Timer */
+                               ParaLocal.Para64 = (SK_U64)0;
+
+                               pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
+
+                               SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
+                                       SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
+                       }
+               }
+               else {
+                       pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
+                       pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
+                       SK_I2C_STOP(IoC);
+
+                       /* Increment Current sensor and set appropriate Timeout */
+                       pAC->I2c.CurrSens++;
+                       if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
+                               pAC->I2c.CurrSens = 0;
+                               Time = SK_I2C_TIM_LONG;
+                       }
+                       else {
+                               Time = SK_I2C_TIM_SHORT;
+                       }
+
+                       /* Start Timer */
+                       ParaLocal.Para64 = (SK_U64)0;
+
+                       pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
+
+                       SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
+                               SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
+               }
+               break;
+       case SK_I2CEV_CLEAR:
+               for (i = 0; i < SK_MAX_SENSORS; i++) {
+                       pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
+                       pAC->I2c.SenTable[i].SenErrCts = 0;
+                       pAC->I2c.SenTable[i].SenWarnCts = 0;
+                       pAC->I2c.SenTable[i].SenBegErrTS = 0;
+                       pAC->I2c.SenTable[i].SenBegWarnTS = 0;
+                       pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0;
+                       pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0;
+                       pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0;
+                       pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0;
+               }
+               break;
+       default:
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
+       }
+
+       return(0);
+}      /* SkI2cEvent*/
+
+#endif /* !SK_DIAG */
+
+#endif /* CONFIG_SK98 */
diff --git a/drivers/net/sk98lin/sklm80.c b/drivers/net/sk98lin/sklm80.c
new file mode 100644 (file)
index 0000000..687572b
--- /dev/null
@@ -0,0 +1,292 @@
+/******************************************************************************
+ *
+ * Name:       sklm80.c
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.20 $
+ * Date:       $Date: 2002/08/13 09:16:27 $
+ * Purpose:    Funktions to access Voltage and Temperature Sensor (LM80)
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2002 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: sklm80.c,v $
+ *     Revision 1.20  2002/08/13 09:16:27  rschmidt
+ *     Changed return value for SkLm80ReadSensor() back to 'int'
+ *     Editorial changes
+ *
+ *     Revision 1.19  2002/08/06 09:43:31  jschmalz
+ *     Extensions and changes for Yukon
+ *
+ *     Revision 1.18  2002/08/02 12:26:57  rschmidt
+ *     Editorial changes
+ *
+ *     Revision 1.17  1999/11/22 13:35:51  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.16  1999/05/27 14:05:47  malthoff
+ *     Fans: Set SenVal to 0 if the fan value is 0 or 0xff. Both values
+ *     are outside the limits (0: div zero error, 0xff: value not in
+ *     range, assume 0).
+ *
+ *     Revision 1.15  1999/05/27 13:38:51  malthoff
+ *     Pervent from Division by zero errors.
+ *
+ *     Revision 1.14  1999/05/20 09:20:01  cgoos
+ *     Changes for 1000Base-T (Fan sensors).
+ *
+ *     Revision 1.13  1998/10/22 09:48:14  gklug
+ *     fix: SysKonnectFileId typo
+ *
+ *     Revision 1.12  1998/10/09 06:12:06  malthoff
+ *     Remove ID_sccs by SysKonnectFileId.
+ *
+ *     Revision 1.11  1998/09/04 08:33:48  malthoff
+ *     bug fix: SenState = SK_SEN_IDLE when
+ *     leaving SK_SEN_VALEXT state
+ *
+ *     Revision 1.10  1998/08/20 12:02:10  gklug
+ *     fix: compiler warnings type mismatch
+ *
+ *     Revision 1.9  1998/08/20 11:37:38  gklug
+ *     chg: change Ioc to IoC
+ *
+ *     Revision 1.8  1998/08/19 12:20:58  gklug
+ *     fix: remove struct from C files (see CCC)
+ *
+ *     Revision 1.7  1998/08/17 07:04:57  malthoff
+ *     Take SkLm80RcvReg() function from ski2c.c.
+ *     Add IoC parameter to BREAK_OR_WAIT() macro.
+ *
+ *     Revision 1.6  1998/08/14 07:11:28  malthoff
+ *     remove pAc with pAC.
+ *
+ *     Revision 1.5  1998/08/14 06:46:55  gklug
+ *     fix: temperature can get negative
+ *
+ *     Revision 1.4  1998/08/13 08:27:04  gklug
+ *     add: temperature reading now o.k.
+ *     fix: pSen declaration, SK_ERR_LOG call, ADDR macro
+ *
+ *     Revision 1.3  1998/08/13 07:28:21  gklug
+ *     fix: pSen was wrong initialized
+ *     add: correct conversion for voltage readings
+ *
+ *     Revision 1.2  1998/08/11 07:52:14  gklug
+ *     add: Lm80 read sensor function
+ *
+ *     Revision 1.1  1998/07/17 09:57:12  gklug
+ *     initial version
+ *
+ *
+ *
+ ******************************************************************************/
+
+
+#include <config.h>
+
+#ifdef CONFIG_SK98
+
+/*
+       LM80 functions
+*/
+static const char SysKonnectFileId[] =
+       "$Id: sklm80.c,v 1.20 2002/08/13 09:16:27 rschmidt Exp $" ;
+
+#include "h/skdrv1st.h"                /* Driver Specific Definitions */
+#include "h/lm80.h"
+#include "h/skdrv2nd.h"                /* Adapter Control- and Driver specific Def. */
+
+#ifdef SK_DIAG
+#define        BREAK_OR_WAIT(pAC,IoC,Event)    SkI2cWait(pAC,IoC,Event)
+#else  /* nSK_DIAG */
+#define        BREAK_OR_WAIT(pAC,IoC,Event)    break
+#endif /* nSK_DIAG */
+
+#ifdef SK_DIAG
+/*
+ * read the register 'Reg' from the device 'Dev'
+ *
+ * return      read error      -1
+ *             success         the read value
+ */
+int    SkLm80RcvReg(
+SK_IOC IoC,            /* Adapter Context */
+int            Dev,            /* I2C device address */
+int            Reg)            /* register to read */
+{
+       int     Val = 0;
+       int     TempExt;
+
+       /* Signal device number */
+       if (SkI2cSndDev(IoC, Dev, I2C_WRITE)) {
+               return(-1);
+       }
+
+       if (SkI2cSndByte(IoC, Reg)) {
+               return(-1);
+       }
+
+       /* repeat start */
+       if (SkI2cSndDev(IoC, Dev, I2C_READ)) {
+               return(-1);
+       }
+
+       switch (Reg) {
+       case LM80_TEMP_IN:
+               Val = (int)SkI2cRcvByte(IoC, 1);
+
+               /* First: correct the value: it might be negative */
+               if ((Val & 0x80) != 0) {
+                       /* Value is negative */
+                       Val = Val - 256;
+               }
+               Val = Val * SK_LM80_TEMP_LSB;
+               SkI2cStop(IoC);
+
+               TempExt = (int)SkLm80RcvReg(IoC, LM80_ADDR, LM80_TEMP_CTRL);
+
+               if (Val > 0) {
+                       Val += ((TempExt >> 7) * SK_LM80_TEMPEXT_LSB);
+               }
+               else {
+                       Val -= ((TempExt >> 7) * SK_LM80_TEMPEXT_LSB);
+               }
+               return(Val);
+               break;
+       case LM80_VT0_IN:
+       case LM80_VT1_IN:
+       case LM80_VT2_IN:
+       case LM80_VT3_IN:
+               Val = (int)SkI2cRcvByte(IoC, 1) * SK_LM80_VT_LSB;
+               break;
+
+       default:
+               Val = (int)SkI2cRcvByte(IoC, 1);
+               break;
+       }
+
+       SkI2cStop(IoC);
+       return(Val);
+}
+#endif /* SK_DIAG */
+
+/*
+ * read a sensors value (LM80 specific)
+ *
+ * This function reads a sensors value from the I2C sensor chip LM80.
+ * The sensor is defined by its index into the sensors database in the struct
+ * pAC points to.
+ *
+ * Returns     1 if the read is completed
+ *             0 if the read must be continued (I2C Bus still allocated)
+ */
+int SkLm80ReadSensor(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context needed in level 1 and 2 */
+SK_SENSOR      *pSen)  /* Sensor to be read */
+{
+       SK_I32          Value;
+
+       switch (pSen->SenState) {
+       case SK_SEN_IDLE:
+               /* Send address to ADDR register */
+               SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, pSen->SenReg, 0);
+
+               pSen->SenState = SK_SEN_VALUE ;
+               BREAK_OR_WAIT(pAC, IoC, I2C_READ);
+
+       case SK_SEN_VALUE:
+               /* Read value from data register */
+               SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value));
+
+               Value &= 0xff; /* only least significant byte is valid */
+
+               /* Do NOT check the Value against the thresholds */
+               /* Checking is done in the calling instance */
+
+               if (pSen->SenType == SK_SEN_VOLT) {
+                       /* Voltage sensor */
+                       pSen->SenValue = Value * SK_LM80_VT_LSB;
+                       pSen->SenState = SK_SEN_IDLE ;
+                       return(1);
+               }
+
+               if (pSen->SenType == SK_SEN_FAN) {
+                       if (Value != 0 && Value != 0xff) {
+                               /* Fan speed counter */
+                               pSen->SenValue = SK_LM80_FAN_FAKTOR/Value;
+                       }
+                       else {
+                               /* Indicate Fan error */
+                               pSen->SenValue = 0;
+                       }
+                       pSen->SenState = SK_SEN_IDLE ;
+                       return(1);
+               }
+
+               /* First: correct the value: it might be negative */
+               if ((Value & 0x80) != 0) {
+                       /* Value is negative */
+                       Value = Value - 256;
+               }
+
+               /* We have a temperature sensor and need to get the signed extension.
+                * For now we get the extension from the last reading, so in the normal
+                * case we won't see flickering temperatures.
+                */
+               pSen->SenValue = (Value * SK_LM80_TEMP_LSB) +
+                       (pSen->SenValue % SK_LM80_TEMP_LSB);
+
+               /* Send address to ADDR register */
+               SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, LM80_TEMP_CTRL, 0);
+
+               pSen->SenState = SK_SEN_VALEXT ;
+               BREAK_OR_WAIT(pAC, IoC, I2C_READ);
+
+       case SK_SEN_VALEXT:
+               /* Read value from data register */
+               SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value));
+               Value &= LM80_TEMP_LSB_9; /* only bit 7 is valid */
+
+               /* cut the LSB bit */
+               pSen->SenValue = ((pSen->SenValue / SK_LM80_TEMP_LSB) *
+                       SK_LM80_TEMP_LSB);
+
+               if (pSen->SenValue < 0) {
+                       /* Value negative: The bit value must be subtracted */
+                       pSen->SenValue -= ((Value >> 7) * SK_LM80_TEMPEXT_LSB);
+               }
+               else {
+                       /* Value positive: The bit value must be added */
+                       pSen->SenValue += ((Value >> 7) * SK_LM80_TEMPEXT_LSB);
+               }
+
+               pSen->SenState = SK_SEN_IDLE ;
+               return(1);
+
+       default:
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E007, SKERR_I2C_E007MSG);
+               return(1);
+       }
+
+       /* Not completed */
+       return(0);
+}
+
+#endif /* CONFIG_SK98 */
diff --git a/drivers/net/sk98lin/skproc.c b/drivers/net/sk98lin/skproc.c
new file mode 100644 (file)
index 0000000..4e34073
--- /dev/null
@@ -0,0 +1,515 @@
+/******************************************************************************
+ *
+ * Name:    skproc.c
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.4 $
+ * Date:    $Date: 2003/02/25 14:16:37 $
+ * Purpose:    Funktions to display statictic data
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2003 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     Created 22-Nov-2000
+ *     Author: Mirko Lindner (mlindner@syskonnect.de)
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skproc.c,v $
+ *     Revision 1.4  2003/02/25 14:16:37  mlindner
+ *     Fix: Copyright statement
+ *
+ *     Revision 1.3  2002/10/02 12:59:51  mlindner
+ *     Add: Support for Yukon
+ *     Add: Speed check and setup
+ *     Add: Merge source for kernel 2.2.x and 2.4.x
+ *     Add: Read sensor names directly from VPD
+ *     Fix: Volt values
+ *
+ *     Revision 1.2.2.7  2002/01/14 12:45:15  mlindner
+ *     Fix: Editorial changes
+ *
+ *     Revision 1.2.2.6  2001/12/06 15:26:07  mlindner
+ *     Fix: Return value of proc_read
+ *
+ *     Revision 1.2.2.5  2001/12/06 09:57:39  mlindner
+ *     New ProcFs entries
+ *
+ *     Revision 1.2.2.4  2001/09/05 12:16:02  mlindner
+ *     Add: New ProcFs entries
+ *     Fix: Counter Errors (Jumbo == to long errors)
+ *     Fix: Kernel error compilation
+ *     Fix: too short counters
+ *
+ *     Revision 1.2.2.3  2001/06/25 07:26:26  mlindner
+ *     Add: More error messages
+ *
+ *     Revision 1.2.2.2  2001/03/15 12:50:13  mlindner
+ *     fix: ProcFS owner protection
+ *
+ *     Revision 1.2.2.1  2001/03/12 16:43:48  mlindner
+ *     chg: 2.4 requirements for procfs
+ *
+ *     Revision 1.1  2001/01/22 14:15:31  mlindner
+ *     added ProcFs functionality
+ *     Dual Net functionality integrated
+ *     Rlmt networks added
+ *
+ *
+ ******************************************************************************/
+
+#include <config.h>
+
+#ifdef CONFIG_SK98
+
+#include <linux/proc_fs.h>
+
+#include "h/skdrv1st.h"
+#include "h/skdrv2nd.h"
+#define ZEROPAD                1               /* pad with zero */
+#define SIGN           2               /* unsigned/signed long */
+#define PLUS           4               /* show plus */
+#define SPACE          8               /* space if plus */
+#define LEFT           16              /* left justified */
+#define SPECIALX       32              /* 0x */
+#define LARGE          64
+
+extern SK_AC                           *pACList;
+extern struct net_device       *SkGeRootDev;
+
+extern char * SkNumber(
+       char * str,
+       long long num,
+       int base,
+       int size,
+       int precision,
+       int type);
+
+
+/*****************************************************************************
+ *
+ *     proc_read - print "summaries" entry
+ *
+ * Description:
+ *  This function fills the proc entry with statistic data about
+ *  the ethernet device.
+ *
+ *
+ * Returns: buffer with statistic data
+ *
+ */
+int proc_read(char *buffer,
+char **buffer_location,
+off_t offset,
+int buffer_length,
+int *eof,
+void *data)
+{
+       int len = 0;
+       int t;
+       int i;
+       DEV_NET                                 *pNet;
+       SK_AC                                   *pAC;
+       char                                    test_buf[100];
+       char                                    sens_msg[50];
+       unsigned long                   Flags;
+       unsigned int                    Size;
+       struct SK_NET_DEVICE            *next;
+       struct SK_NET_DEVICE            *SkgeProcDev = SkGeRootDev;
+
+       SK_PNMI_STRUCT_DATA     *pPnmiStruct;
+       SK_PNMI_STAT            *pPnmiStat;
+       struct proc_dir_entry *file = (struct proc_dir_entry*) data;
+
+       while (SkgeProcDev) {
+               pNet = (DEV_NET*) SkgeProcDev->priv;
+               pAC = pNet->pAC;
+               next = pAC->Next;
+               pPnmiStruct = &pAC->PnmiStruct;
+               /* NetIndex in GetStruct is now required, zero is only dummy */
+
+               for (t=pAC->GIni.GIMacsFound; t > 0; t--) {
+                       if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1)
+                               t--;
+
+                       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+                       Size = SK_PNMI_STRUCT_SIZE;
+                       SkPnmiGetStruct(pAC, pAC->IoBase,
+                               pPnmiStruct, &Size, t-1);
+                       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+
+                       if (strcmp(pAC->dev[t-1]->name, file->name) == 0) {
+                               pPnmiStat = &pPnmiStruct->Stat[0];
+                               len = sprintf(buffer,
+                                       "\nDetailed statistic for device %s\n",
+                                       pAC->dev[t-1]->name);
+                               len += sprintf(buffer + len,
+                                       "=======================================\n");
+
+                               /* Board statistics */
+                               len += sprintf(buffer + len,
+                                       "\nBoard statistics\n\n");
+                               len += sprintf(buffer + len,
+                                       "Active Port                    %c\n",
+                                       'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
+                                       Net[t-1].PrefPort]->PortNumber);
+                               len += sprintf(buffer + len,
+                                       "Preferred Port                 %c\n",
+                                       'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
+                                       Net[t-1].PrefPort]->PortNumber);
+
+                               len += sprintf(buffer + len,
+                                       "Bus speed (MHz)                %d\n",
+                                       pPnmiStruct->BusSpeed);
+
+                               len += sprintf(buffer + len,
+                                       "Bus width (Bit)                %d\n",
+                                       pPnmiStruct->BusWidth);
+                               len += sprintf(buffer + len,
+                                       "Hardware revision              v%d.%d\n",
+                                       (pAC->GIni.GIPciHwRev >> 4) & 0x0F,
+                                       pAC->GIni.GIPciHwRev & 0x0F);
+
+                               /* Print sensor informations */
+                               for (i=0; i < pAC->I2c.MaxSens; i ++) {
+                                       /* Check type */
+                                       switch (pAC->I2c.SenTable[i].SenType) {
+                                       case 1:
+                                               strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+                                               strcat(sens_msg, " (C)");
+                                               len += sprintf(buffer + len,
+                                                       "%-25s      %d.%02d\n",
+                                                       sens_msg,
+                                                       pAC->I2c.SenTable[i].SenValue / 10,
+                                                       pAC->I2c.SenTable[i].SenValue % 10);
+
+                                               strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+                                               strcat(sens_msg, " (F)");
+                                               len += sprintf(buffer + len,
+                                                       "%-25s      %d.%02d\n",
+                                                       sens_msg,
+                                                       ((((pAC->I2c.SenTable[i].SenValue)
+                                                       *10)*9)/5 + 3200)/100,
+                                                       ((((pAC->I2c.SenTable[i].SenValue)
+                                                       *10)*9)/5 + 3200) % 10);
+                                               break;
+                                       case 2:
+                                               strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+                                               strcat(sens_msg, " (V)");
+                                               len += sprintf(buffer + len,
+                                                       "%-25s      %d.%03d\n",
+                                                       sens_msg,
+                                                       pAC->I2c.SenTable[i].SenValue / 1000,
+                                                       pAC->I2c.SenTable[i].SenValue % 1000);
+                                               break;
+                                       case 3:
+                                               strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+                                               strcat(sens_msg, " (rpm)");
+                                               len += sprintf(buffer + len,
+                                                       "%-25s      %d\n",
+                                                       sens_msg,
+                                                       pAC->I2c.SenTable[i].SenValue);
+                                               break;
+                                       default:
+                                               break;
+                                       }
+                               }
+
+                               /*Receive statistics */
+                               len += sprintf(buffer + len,
+                               "\nReceive statistics\n\n");
+
+                               len += sprintf(buffer + len,
+                                       "Received bytes                 %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatRxOctetsOkCts,
+                                       10,0,-1,0));
+                               len += sprintf(buffer + len,
+                                       "Received packets               %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatRxOkCts,
+                                       10,0,-1,0));
+#if 0
+                               if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC &&
+                                       pAC->HWRevision < 12) {
+                                       pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
+                                               pPnmiStat->StatRxShortsCts;
+                                       pPnmiStat->StatRxShortsCts = 0;
+                               }
+#endif
+                               if (pNet->Mtu > 1500)
+                                       pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
+                                               pPnmiStat->StatRxTooLongCts;
+
+                               len += sprintf(buffer + len,
+                                       "Receive errors                 %s\n",
+                                       SkNumber(test_buf, pPnmiStruct->InErrorsCts,
+                                       10,0,-1,0));
+                               len += sprintf(buffer + len,
+                                       "Receive drops                  %s\n",
+                                       SkNumber(test_buf, pPnmiStruct->RxNoBufCts,
+                                       10,0,-1,0));
+                               len += sprintf(buffer + len,
+                                       "Received multicast             %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatRxMulticastOkCts,
+                                       10,0,-1,0));
+                               len += sprintf(buffer + len,
+                                       "Receive error types\n");
+                               len += sprintf(buffer + len,
+                                       "   length                      %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatRxRuntCts,
+                                       10, 0, -1, 0));
+                               len += sprintf(buffer + len,
+                                       "   buffer overflow             %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatRxFifoOverflowCts,
+                                       10, 0, -1, 0));
+                               len += sprintf(buffer + len,
+                                       "   bad crc                     %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatRxFcsCts,
+                                       10, 0, -1, 0));
+                               len += sprintf(buffer + len,
+                                       "   framing                     %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatRxFramingCts,
+                                       10, 0, -1, 0));
+                               len += sprintf(buffer + len,
+                                       "   missed frames               %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatRxMissedCts,
+                                       10, 0, -1, 0));
+
+                               if (pNet->Mtu > 1500)
+                                       pPnmiStat->StatRxTooLongCts = 0;
+
+                               len += sprintf(buffer + len,
+                                       "   too long                    %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatRxTooLongCts,
+                                       10, 0, -1, 0));
+                               len += sprintf(buffer + len,
+                                       "   carrier extension           %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatRxCextCts,
+                                       10, 0, -1, 0));
+                               len += sprintf(buffer + len,
+                                       "   too short                   %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatRxShortsCts,
+                                       10, 0, -1, 0));
+                               len += sprintf(buffer + len,
+                                       "   symbol                      %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatRxSymbolCts,
+                                       10, 0, -1, 0));
+                               len += sprintf(buffer + len,
+                                       "   LLC MAC size                %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatRxIRLengthCts,
+                                       10, 0, -1, 0));
+                               len += sprintf(buffer + len,
+                                       "   carrier event               %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatRxCarrierCts,
+                                       10, 0, -1, 0));
+                               len += sprintf(buffer + len,
+                                       "   jabber                      %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatRxJabberCts,
+                                       10, 0, -1, 0));
+
+
+                               /*Transmit statistics */
+                               len += sprintf(buffer + len,
+                               "\nTransmit statistics\n\n");
+
+                               len += sprintf(buffer + len,
+                                       "Transmited bytes               %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatTxOctetsOkCts,
+                                       10,0,-1,0));
+                               len += sprintf(buffer + len,
+                                       "Transmited packets             %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatTxOkCts,
+                                       10,0,-1,0));
+                               len += sprintf(buffer + len,
+                                       "Transmit errors                %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatTxSingleCollisionCts,
+                                       10,0,-1,0));
+                               len += sprintf(buffer + len,
+                                       "Transmit dropped               %s\n",
+                                       SkNumber(test_buf, pPnmiStruct->TxNoBufCts,
+                                       10,0,-1,0));
+                               len += sprintf(buffer + len,
+                                       "Transmit collisions            %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatTxSingleCollisionCts,
+                                       10,0,-1,0));
+                               len += sprintf(buffer + len,
+                                       "Transmit errors types\n");
+                               len += sprintf(buffer + len,
+                                       "   excessive collision         %ld\n",
+                                       pAC->stats.tx_aborted_errors);
+                               len += sprintf(buffer + len,
+                                       "   carrier                     %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatTxCarrierCts,
+                                       10, 0, -1, 0));
+                               len += sprintf(buffer + len,
+                                       "   fifo underrun               %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatTxFifoUnderrunCts,
+                                       10, 0, -1, 0));
+                               len += sprintf(buffer + len,
+                                       "   heartbeat                   %s\n",
+                                       SkNumber(test_buf, pPnmiStat->StatTxCarrierCts,
+                                       10, 0, -1, 0));
+                               len += sprintf(buffer + len,
+                                       "   window                      %ld\n",
+                                       pAC->stats.tx_window_errors);
+
+                       }
+               }
+               SkgeProcDev = next;
+       }
+       if (offset >= len) {
+               *eof = 1;
+               return 0;
+       }
+
+       *buffer_location = buffer + offset;
+       if (buffer_length >= len - offset) {
+               *eof = 1;
+       }
+       return (min_t(int, buffer_length, len - offset));
+}
+
+
+/*****************************************************************************
+ *
+ * SkDoDiv - convert 64bit number
+ *
+ * Description:
+ *     This function "converts" a long long number.
+ *
+ * Returns:
+ *     remainder of division
+ */
+static long SkDoDiv (long long Dividend, int Divisor, long long *pErg)
+{
+ long          Rest;
+ long long     Ergebnis;
+ long          Akku;
+
+
+ Akku  = Dividend >> 32;
+
+ Ergebnis = ((long long) (Akku / Divisor)) << 32;
+ Rest = Akku % Divisor ;
+
+ Akku = Rest << 16;
+ Akku |= ((Dividend & 0xFFFF0000) >> 16);
+
+
+ Ergebnis += ((long long) (Akku / Divisor)) << 16;
+ Rest = Akku % Divisor ;
+
+ Akku = Rest << 16;
+ Akku |= (Dividend & 0xFFFF);
+
+ Ergebnis += (Akku / Divisor);
+ Rest = Akku % Divisor ;
+
+ *pErg = Ergebnis;
+ return (Rest);
+}
+
+
+#if 0
+#define do_div(n,base) ({ \
+long long __res; \
+__res = ((unsigned long long) n) % (unsigned) base; \
+n = ((unsigned long long) n) / (unsigned) base; \
+__res; })
+
+#endif
+
+
+/*****************************************************************************
+ *
+ * SkNumber - Print results
+ *
+ * Description:
+ *     This function converts a long long number into a string.
+ *
+ * Returns:
+ *     number as string
+ */
+char * SkNumber(char * str, long long num, int base, int size, int precision
+       ,int type)
+{
+       char c,sign,tmp[66], *strorg = str;
+       const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
+       int i;
+
+       if (type & LARGE)
+               digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+       if (type & LEFT)
+               type &= ~ZEROPAD;
+       if (base < 2 || base > 36)
+               return 0;
+       c = (type & ZEROPAD) ? '0' : ' ';
+       sign = 0;
+       if (type & SIGN) {
+               if (num < 0) {
+                       sign = '-';
+                       num = -num;
+                       size--;
+               } else if (type & PLUS) {
+                       sign = '+';
+                       size--;
+               } else if (type & SPACE) {
+                       sign = ' ';
+                       size--;
+               }
+       }
+       if (type & SPECIALX) {
+               if (base == 16)
+                       size -= 2;
+               else if (base == 8)
+                       size--;
+       }
+       i = 0;
+       if (num == 0)
+               tmp[i++]='0';
+       else while (num != 0)
+               tmp[i++] = digits[SkDoDiv(num,base, &num)];
+
+       if (i > precision)
+               precision = i;
+       size -= precision;
+       if (!(type&(ZEROPAD+LEFT)))
+               while(size-->0)
+                       *str++ = ' ';
+       if (sign)
+               *str++ = sign;
+       if (type & SPECIALX) {
+               if (base==8)
+                       *str++ = '0';
+               else if (base==16) {
+                       *str++ = '0';
+                       *str++ = digits[33];
+               }
+       }
+       if (!(type & LEFT))
+               while (size-- > 0)
+                       *str++ = c;
+       while (i < precision--)
+               *str++ = '0';
+       while (i-- > 0)
+               *str++ = tmp[i];
+       while (size-- > 0)
+               *str++ = ' ';
+
+       str[0] = '\0';
+
+       return strorg;
+}
+
+#endif /* CONFIG_SK98 */
diff --git a/drivers/net/sk98lin/skqueue.c b/drivers/net/sk98lin/skqueue.c
new file mode 100644 (file)
index 0000000..c49baed
--- /dev/null
@@ -0,0 +1,242 @@
+/******************************************************************************
+ *
+ * Name:       skqueue.c
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.18 $
+ * Date:       $Date: 2002/05/07 14:11:11 $
+ * Purpose:    Management of an event queue.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998,1999 SysKonnect,
+ *     a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skqueue.c,v $
+ *     Revision 1.18  2002/05/07 14:11:11  rwahl
+ *     Fixed Watcom Precompiler error.
+ *
+ *     Revision 1.17  2002/03/25 10:06:41  mkunz
+ *     SkIgnoreEvent deleted
+ *
+ *     Revision 1.16  2002/03/15 10:51:59  mkunz
+ *     Added event classes for link aggregation
+ *
+ *     Revision 1.15  1999/11/22 13:36:29  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.14  1998/10/15 15:11:35  gklug
+ *     fix: ID_sccs to SysKonnectFileId
+ *
+ *     Revision 1.13  1998/09/08 08:47:52  gklug
+ *     add: init level handling
+ *
+ *     Revision 1.12  1998/09/08 07:43:20  gklug
+ *     fix: Sirq Event function name
+ *
+ *     Revision 1.11  1998/09/08 05:54:34  gklug
+ *     chg: define SK_CSUM is replaced by SK_USE_CSUM
+ *
+ *     Revision 1.10  1998/09/03 14:14:49  gklug
+ *     add: CSUM and HWAC Eventclass and function.
+ *
+ *     Revision 1.9  1998/08/19 09:50:50  gklug
+ *     fix: remove struct keyword from c-code (see CCC) add typedefs
+ *
+ *     Revision 1.8  1998/08/17 13:43:11  gklug
+ *     chg: Parameter will be union of 64bit para, 2 times SK_U32 or SK_PTR
+ *
+ *     Revision 1.7  1998/08/14 07:09:11  gklug
+ *     fix: chg pAc -> pAC
+ *
+ *     Revision 1.6  1998/08/11 12:13:14  gklug
+ *     add: return code feature of Event service routines
+ *     add: correct Error log calls
+ *
+ *     Revision 1.5  1998/08/07 12:53:45  gklug
+ *     fix: first compiled version
+ *
+ *     Revision 1.4  1998/08/07 09:20:48  gklug
+ *     adapt functions to C coding conventions.
+ *
+ *     Revision 1.3  1998/08/05 11:29:32  gklug
+ *     rmv: Timer event entry. Timer will queue event directly
+ *
+ *     Revision 1.2  1998/07/31 11:22:40  gklug
+ *     Initial version
+ *
+ *     Revision 1.1  1998/07/30 15:14:01  gklug
+ *     Initial version. Adapted from SMT
+ *
+ *
+ *
+ ******************************************************************************/
+
+
+#include <config.h>
+
+#ifdef CONFIG_SK98
+
+/*
+       Event queue and dispatcher
+*/
+static const char SysKonnectFileId[] =
+       "$Header: /usr56/projects/ge/schedule/skqueue.c,v 1.18 2002/05/07 14:11:11 rwahl Exp $" ;
+
+#include "h/skdrv1st.h"                /* Driver Specific Definitions */
+#include "h/skqueue.h"         /* Queue Definitions */
+#include "h/skdrv2nd.h"                /* Adapter Control- and Driver specific Def. */
+
+#ifdef __C2MAN__
+/*
+       Event queue management.
+
+       General Description:
+
+ */
+intro()
+{}
+#endif
+
+#define PRINTF(a,b,c)
+
+/*
+ * init event queue management
+ *
+ * Must be called during init level 0.
+ */
+void   SkEventInit(
+SK_AC  *pAC,   /* Adapter context */
+SK_IOC Ioc,    /* IO context */
+int    Level)  /* Init level */
+{
+       switch (Level) {
+       case SK_INIT_DATA:
+               pAC->Event.EvPut = pAC->Event.EvGet = pAC->Event.EvQueue ;
+               break;
+       default:
+               break;
+       }
+}
+
+/*
+ * add event to queue
+ */
+void   SkEventQueue(
+SK_AC          *pAC,   /* Adapters context */
+SK_U32         Class,  /* Event Class */
+SK_U32         Event,  /* Event to be queued */
+SK_EVPARA      Para)   /* Event parameter */
+{
+       pAC->Event.EvPut->Class = Class ;
+       pAC->Event.EvPut->Event = Event ;
+       pAC->Event.EvPut->Para = Para ;
+       if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT])
+               pAC->Event.EvPut = pAC->Event.EvQueue ;
+
+       if (pAC->Event.EvPut == pAC->Event.EvGet) {
+               SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG) ;
+       }
+}
+
+/*
+ * event dispatcher
+ *     while event queue is not empty
+ *             get event from queue
+ *             send command to state machine
+ *     end
+ *     return error reported by individual Event function
+ *             0 if no error occured.
+ */
+int    SkEventDispatcher(
+SK_AC  *pAC,   /* Adapters Context */
+SK_IOC Ioc)    /* Io context */
+{
+       SK_EVENTELEM    *pEv ;  /* pointer into queue */
+       SK_U32                  Class ;
+       int                     Rtv ;
+
+       pEv = pAC->Event.EvGet ;
+       PRINTF("dispatch get %x put %x\n",pEv,pAC->Event.ev_put) ;
+       while (pEv != pAC->Event.EvPut) {
+               PRINTF("dispatch Class %d Event %d\n",pEv->Class,pEv->Event) ;
+               switch(Class = pEv->Class) {
+#ifndef SK_USE_LAC_EV
+               case SKGE_RLMT :        /* RLMT Event */
+                       Rtv = SkRlmtEvent(pAC,Ioc,pEv->Event,pEv->Para);
+                       break ;
+               case SKGE_I2C :         /* I2C Event */
+                       Rtv = SkI2cEvent(pAC,Ioc,pEv->Event,pEv->Para);
+                       break ;
+               case SKGE_PNMI :
+                       Rtv = SkPnmiEvent(pAC,Ioc,pEv->Event,pEv->Para);
+                       break ;
+#endif /* SK_USE_LAC_EV */
+               case SKGE_DRV :         /* Driver Event */
+                       Rtv = SkDrvEvent(pAC,Ioc,pEv->Event,pEv->Para);
+                       break ;
+#ifndef SK_USE_SW_TIMER
+               case SKGE_HWAC :
+                       Rtv = SkGeSirqEvent(pAC,Ioc,pEv->Event,pEv->Para);
+                       break ;
+#else /* !SK_USE_SW_TIMER */
+       case SKGE_SWT :
+                       Rtv = SkSwtEvent(pAC,Ioc,pEv->Event,pEv->Para);
+                       break ;
+#endif /* !SK_USE_SW_TIMER */
+#ifdef SK_USE_LAC_EV
+               case SKGE_LACP :
+                       Rtv = SkLacpEvent(pAC,Ioc,pEv->Event,pEv->Para);
+                       break ;
+               case SKGE_RSF :
+                       Rtv = SkRsfEvent(pAC,Ioc,pEv->Event,pEv->Para);
+                       break ;
+               case SKGE_MARKER :
+                       Rtv = SkMarkerEvent(pAC,Ioc,pEv->Event,pEv->Para);
+                       break ;
+               case SKGE_FD :
+                       Rtv = SkFdEvent(pAC,Ioc,pEv->Event,pEv->Para);
+                       break ;
+#endif /* SK_USE_LAC_EV */
+#ifdef SK_USE_CSUM
+               case SKGE_CSUM :
+                       Rtv = SkCsEvent(pAC,Ioc,pEv->Event,pEv->Para);
+                       break ;
+#endif /* SK_USE_CSUM */
+               default :
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E002,
+                               SKERR_Q_E002MSG) ;
+                       Rtv = 0;
+               }
+
+               if (Rtv != 0) {
+                       return(Rtv) ;
+               }
+
+               if (++pEv == &pAC->Event.EvQueue[SK_MAX_EVENT])
+                       pEv = pAC->Event.EvQueue ;
+
+               /* Renew get: it is used in queue_events to detect overruns */
+               pAC->Event.EvGet = pEv;
+       }
+
+       return(0) ;
+}
+
+#endif /* CONFIG_SK98 */
+
+/* End of file */
diff --git a/drivers/net/sk98lin/skrlmt.c b/drivers/net/sk98lin/skrlmt.c
new file mode 100644 (file)
index 0000000..f8a3b41
--- /dev/null
@@ -0,0 +1,3508 @@
+/******************************************************************************
+ *
+ * Name:       skrlmt.c
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.68 $
+ * Date:       $Date: 2003/01/31 15:26:56 $
+ * Purpose:    Manage links on SK-NET Adapters, esp. redundant ones.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2001 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skrlmt.c,v $
+ *     Revision 1.68  2003/01/31 15:26:56  rschmidt
+ *     Added init for local variables in RlmtInit().
+ *
+ *     Revision 1.67  2003/01/31 14:12:41  mkunz
+ *     single port adapter runs now with two identical MAC addresses
+ *
+ *     Revision 1.66  2002/09/23 15:14:19  rwahl
+ *     - Reset broadcast timestamp on link down.
+ *     - Editorial corrections.
+ *
+ *     Revision 1.65  2002/07/22 14:29:48  rwahl
+ *     - Removed BRK statement from debug check.
+ *
+ *     Revision 1.64  2001/11/28 19:36:14  rwahl
+ *     - RLMT Packets sent to an invalid MAC address in CLP/CLPSS mode
+ *       (#10650).
+ *     - Reworked fix for port switching in CLS mode (#10639)
+ *      (no dependency to RLMT module).
+ *     - Enabled dbg output for entry/exit of event functions.
+ *     - Editorial changes.
+ *
+ *     Revision 1.63  2001/10/26 07:53:18  afischer
+ *     Port switching bug in `check local link` mode
+ *
+ *     Revision 1.62  2001/07/03 12:16:30  mkunz
+ *     New Flag ChgBcPrio (Change priority of last broadcast received)
+ *
+ *     Revision 1.61  2001/03/14 12:52:08  rassmann
+ *     Fixed reporting of active port up/down to PNMI.
+ *
+ *     Revision 1.60  2001/02/21 16:02:25  gklug
+ *     fix: when RLMT starts set Active Port for PNMI
+ *
+ *     Revision 1.59  2001/02/16 14:38:19  rassmann
+ *     Initializing some pointers earlier in the init phase.
+ *     Rx Mbufs are freed if the net which they belong to is stopped.
+ *
+ *     Revision 1.58  2001/02/14 14:06:31  rassmann
+ *     Editorial changes.
+ *
+ *     Revision 1.57  2001/02/05 14:25:26  rassmann
+ *     Prepared RLMT for transparent operation.
+ *
+ *     Revision 1.56  2001/01/30 10:29:09  rassmann
+ *     Not checking switching befor RlmtStart.
+ *     Editorial changes.
+ *
+ *     Revision 1.55  2001/01/22 13:41:38  rassmann
+ *     Supporting two nets on dual-port adapters.
+ *
+ *     Revision 1.54  2000/11/30 13:25:07  rassmann
+ *     Setting SK_TICK_INCR to 1 by default.
+ *
+ *     Revision 1.53  2000/11/30 10:48:07  cgoos
+ *     Changed definition of SK_RLMT_BC_DELTA.
+ *
+ *     Revision 1.52  2000/11/27 12:50:03  rassmann
+ *     Checking ports after receiving broadcasts.
+ *
+ *     Revision 1.51  2000/11/17 08:58:00  rassmann
+ *     Moved CheckSwitch from SK_RLMT_PACKET_RECEIVED to SK_RLMT_TIM event.
+ *
+ *     Revision 1.50  2000/11/09 12:24:34  rassmann
+ *     Indicating that segmentation check is not running anymore after
+ *       SkRlmtCheckSeg().
+ *     Restarting segmentation timer after segmentation log.
+ *     Editorial changes.
+ *
+ *     Revision 1.49  1999/11/22 13:38:02  cgoos
+ *     Changed license header to GPL.
+ *     Added initialization to some variables to avoid compiler warnings.
+ *
+ *     Revision 1.48  1999/10/04 14:01:17  rassmann
+ *     Corrected reaction to reception of BPDU frames (#10441).
+ *
+ *     Revision 1.47  1999/07/20 12:53:36  rassmann
+ *     Fixed documentation errors for lookahead macros.
+ *
+ *     Revision 1.46  1999/05/28 13:29:16  rassmann
+ *     Replaced C++-style comment.
+ *
+ *     Revision 1.45  1999/05/28 13:28:08  rassmann
+ *     Corrected syntax error (xxx).
+ *
+ *     Revision 1.44  1999/05/28 11:15:54  rassmann
+ *     Changed behaviour to reflect Design Spec v1.2.
+ *     Controlling Link LED(s).
+ *     Introduced RLMT Packet Version field in RLMT Packet.
+ *     Newstyle lookahead macros (checking meta-information before looking at
+ *       the packet).
+ *
+ *     Revision 1.43  1999/01/28 13:12:43  rassmann
+ *     Corrected Lookahead (bug introduced in previous Rev.).
+ *
+ *     Revision 1.42  1999/01/28 12:50:41  rassmann
+ *     Not using broadcast time stamps in CheckLinkState mode.
+ *
+ *     Revision 1.41  1999/01/27 14:13:02  rassmann
+ *     Monitoring broadcast traffic.
+ *     Switching more reliably and not too early if switch is
+ *      configured for spanning tree.
+ *
+ *     Revision 1.40  1999/01/22 13:17:30  rassmann
+ *     Informing PNMI of NET_UP.
+ *     Clearing RLMT multicast addresses before setting them for the first time.
+ *     Reporting segmentation earlier, setting a "quiet time"
+ *      after a report.
+ *
+ *     Revision 1.39  1998/12/10 15:29:53  rassmann
+ *     Corrected SuspectStatus in SkRlmtBuildCheckChain().
+ *     Corrected CHECK_SEG mode.
+ *
+ *     Revision 1.38  1998/12/08 13:11:23  rassmann
+ *     Stopping SegTimer at RlmtStop.
+ *
+ *     Revision 1.37  1998/12/07 16:51:42  rassmann
+ *     Corrected comments.
+ *
+ *     Revision 1.36  1998/12/04 10:58:56  rassmann
+ *     Setting next pointer to NULL when receiving.
+ *
+ *     Revision 1.35  1998/12/03 16:12:42  rassmann
+ *     Ignoring/correcting illegal PrefPort values.
+ *
+ *     Revision 1.34  1998/12/01 11:45:35  rassmann
+ *     Code cleanup.
+ *
+ *     Revision 1.33  1998/12/01 10:29:32  rassmann
+ *     Starting standby ports before getting the net up.
+ *     Checking if a port is started when the link comes up.
+ *
+ *     Revision 1.32  1998/11/30 16:19:50  rassmann
+ *     New default for PortNoRx.
+ *
+ *     Revision 1.31  1998/11/27 19:17:13  rassmann
+ *     Corrected handling of LINK_DOWN coming shortly after LINK_UP.
+ *
+ *     Revision 1.30  1998/11/24 12:37:31  rassmann
+ *     Implemented segmentation check.
+ *
+ *     Revision 1.29  1998/11/18 13:04:32  rassmann
+ *     Secured PortUpTimer event.
+ *     Waiting longer before starting standby port(s).
+ *
+ *     Revision 1.28  1998/11/17 13:43:04  rassmann
+ *     Handling (logical) tx failure.
+ *     Sending packet on logical address after PORT_SWITCH.
+ *
+ *     Revision 1.27  1998/11/13 17:09:50  rassmann
+ *     Secured some events against being called in wrong state.
+ *
+ *     Revision 1.26  1998/11/13 16:56:54  rassmann
+ *     Added macro version of SkRlmtLookaheadPacket.
+ *
+ *     Revision 1.25  1998/11/06 18:06:04  rassmann
+ *     Corrected timing when RLMT checks fail.
+ *     Clearing tx counter earlier in periodical checks.
+ *
+ *     Revision 1.24  1998/11/05 10:37:27  rassmann
+ *     Checking destination address in Lookahead.
+ *
+ *     Revision 1.23  1998/11/03 13:53:49  rassmann
+ *     RLMT should switch now (at least in mode 3).
+ *
+ *     Revision 1.22  1998/10/29 14:34:49  rassmann
+ *     Clearing SK_RLMT struct at startup.
+ *     Initializing PortsUp during SK_RLMT_START.
+ *
+ *     Revision 1.21  1998/10/28 11:30:17  rassmann
+ *     Default mode is now SK_RLMT_CHECK_LOC_LINK.
+ *
+ *     Revision 1.20  1998/10/26 16:02:03  rassmann
+ *     Ignoring LINK_DOWN for links that are down.
+ *
+ *     Revision 1.19  1998/10/22 15:54:01  rassmann
+ *     Corrected EtherLen.
+ *     Starting Link Check when second port comes up.
+ *
+ *     Revision 1.18  1998/10/22 11:39:50  rassmann
+ *     Corrected signed/unsigned mismatches.
+ *     Corrected receive list handling and address recognition.
+ *
+ *     Revision 1.17  1998/10/19 17:01:20  rassmann
+ *     More detailed checking of received packets.
+ *
+ *     Revision 1.16  1998/10/15 15:16:34  rassmann
+ *     Finished Spanning Tree checking.
+ *     Checked with lint.
+ *
+ *     Revision 1.15  1998/09/24 19:16:07  rassmann
+ *     Code cleanup.
+ *     Introduced Timer for PORT_DOWN due to no RX.
+ *
+ *     Revision 1.14  1998/09/18 20:27:14  rassmann
+ *     Added address override.
+ *
+ *     Revision 1.13  1998/09/16 11:31:48  rassmann
+ *     Including skdrv1st.h again. :(
+ *
+ *     Revision 1.12  1998/09/16 11:09:50  rassmann
+ *     Syntax corrections.
+ *
+ *     Revision 1.11  1998/09/15 12:32:03  rassmann
+ *     Syntax correction.
+ *
+ *     Revision 1.10  1998/09/15 11:28:49  rassmann
+ *     Syntax corrections.
+ *
+ *     Revision 1.9  1998/09/14 17:07:37  rassmann
+ *     Added code for port checking via LAN.
+ *     Changed Mbuf definition.
+ *
+ *     Revision 1.8  1998/09/07 11:14:14  rassmann
+ *     Syntax corrections.
+ *
+ *     Revision 1.7  1998/09/07 09:06:07  rassmann
+ *     Syntax corrections.
+ *
+ *     Revision 1.6  1998/09/04 19:41:33  rassmann
+ *     Syntax corrections.
+ *     Started entering code for checking local links.
+ *
+ *     Revision 1.5  1998/09/04 12:14:27  rassmann
+ *     Interface cleanup.
+ *
+ *     Revision 1.4  1998/09/02 16:55:28  rassmann
+ *     Updated to reflect new DRV/HWAC/RLMT interface.
+ *
+ *     Revision 1.3  1998/08/27 14:29:03  rassmann
+ *     Code cleanup.
+ *
+ *     Revision 1.2  1998/08/27 14:26:24  rassmann
+ *     Updated interface.
+ *
+ *     Revision 1.1  1998/08/21 08:26:49  rassmann
+ *     First public version.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * This module contains code for Link ManagemenT (LMT) of SK-NET Adapters.
+ * It is mainly intended for adapters with more than one link.
+ * For such adapters, this module realizes Redundant Link ManagemenT (RLMT).
+ *
+ * Include File Hierarchy:
+ *
+ *     "skdrv1st.h"
+ *     "skdrv2nd.h"
+ *
+ ******************************************************************************/
+
+#include <config.h>
+
+#ifdef CONFIG_SK98
+
+#ifndef        lint
+static const char SysKonnectFileId[] =
+       "@(#) $Id: skrlmt.c,v 1.68 2003/01/31 15:26:56 rschmidt Exp $ (C) SysKonnect.";
+#endif /* !defined(lint) */
+
+#define __SKRLMT_C
+
+#ifdef __cplusplus
+#error C++ is not yet supported.
+extern "C" {
+#endif /* cplusplus */
+
+#include "h/skdrv1st.h"
+#include "h/skdrv2nd.h"
+
+/* defines ********************************************************************/
+
+#ifndef SK_HWAC_LINK_LED
+#define SK_HWAC_LINK_LED(a,b,c,d)
+#endif /* !defined(SK_HWAC_LINK_LED) */
+
+#ifndef DEBUG
+#define RLMT_STATIC    static
+#else  /* DEBUG */
+#define RLMT_STATIC
+
+#ifndef SK_LITTLE_ENDIAN
+/* First 32 bits */
+#define OFFS_LO32      1
+
+/* Second 32 bits */
+#define OFFS_HI32      0
+#else  /* SK_LITTLE_ENDIAN */
+/* First 32 bits */
+#define OFFS_LO32      0
+
+/* Second 32 bits */
+#define OFFS_HI32      1
+#endif /* SK_LITTLE_ENDIAN */
+
+#endif /* DEBUG */
+
+/* ----- Private timeout values ----- */
+
+#define SK_RLMT_MIN_TO_VAL                        125000       /* 1/8 sec. */
+#define SK_RLMT_DEF_TO_VAL                       1000000       /* 1 sec. */
+#define SK_RLMT_PORTDOWN_TIM_VAL          900000       /* another 0.9 sec. */
+#define SK_RLMT_PORTSTART_TIM_VAL         100000       /* 0.1 sec. */
+#define SK_RLMT_PORTUP_TIM_VAL           2500000       /* 2.5 sec. */
+#define SK_RLMT_SEG_TO_VAL                     900000000       /* 15 min. */
+
+/* Assume tick counter increment is 1 - may be set OS-dependent. */
+#ifndef SK_TICK_INCR
+#define SK_TICK_INCR   SK_CONSTU64(1)
+#endif /* !defined(SK_TICK_INCR) */
+
+/*
+ * Amount that a time stamp must be later to be recognized as "substantially
+ * later". This is about 1/128 sec, but above 1 tick counter increment.
+ */
+#define SK_RLMT_BC_DELTA               (1 + ((SK_TICKS_PER_SEC >> 7) > SK_TICK_INCR ? \
+                                                                       (SK_TICKS_PER_SEC >> 7) : SK_TICK_INCR))
+
+/* ----- Private RLMT defaults ----- */
+
+#define SK_RLMT_DEF_PREF_PORT  0                                       /* "Lower" port. */
+#define SK_RLMT_DEF_MODE               SK_RLMT_CHECK_LINK      /* Default RLMT Mode. */
+
+/* ----- Private RLMT checking states ----- */
+
+#define SK_RLMT_RCS_SEG                        1               /* RLMT Check State: check seg. */
+#define SK_RLMT_RCS_START_SEG  2               /* RLMT Check State: start check seg. */
+#define SK_RLMT_RCS_SEND_SEG   4               /* RLMT Check State: send BPDU packet */
+#define SK_RLMT_RCS_REPORT_SEG 8               /* RLMT Check State: report seg. */
+
+/* ----- Private PORT checking states ----- */
+
+#define SK_RLMT_PCS_TX                 1               /* Port Check State: check tx. */
+#define SK_RLMT_PCS_RX                 2               /* Port Check State: check rx. */
+
+/* ----- Private PORT events ----- */
+
+/* Note: Update simulation when changing these. */
+#define SK_RLMT_PORTSTART_TIM  1100    /* Port start timeout. */
+#define SK_RLMT_PORTUP_TIM             1101    /* Port can now go up. */
+#define SK_RLMT_PORTDOWN_RX_TIM        1102    /* Port did not receive once ... */
+#define SK_RLMT_PORTDOWN               1103    /* Port went down. */
+#define SK_RLMT_PORTDOWN_TX_TIM        1104    /* Partner did not receive ... */
+
+/* ----- Private RLMT events ----- */
+
+/* Note: Update simulation when changing these. */
+#define SK_RLMT_TIM                            2100    /* RLMT timeout. */
+#define SK_RLMT_SEG_TIM                        2101    /* RLMT segmentation check timeout. */
+
+#define TO_SHORTEN(tim)        ((tim) / 2)
+
+/* Error numbers and messages. */
+#define SKERR_RLMT_E001                (SK_ERRBASE_RLMT + 0)
+#define SKERR_RLMT_E001_MSG    "No Packet."
+#define SKERR_RLMT_E002                (SKERR_RLMT_E001 + 1)
+#define SKERR_RLMT_E002_MSG    "Short Packet."
+#define SKERR_RLMT_E003                (SKERR_RLMT_E002 + 1)
+#define SKERR_RLMT_E003_MSG    "Unknown RLMT event."
+#define SKERR_RLMT_E004                (SKERR_RLMT_E003 + 1)
+#define SKERR_RLMT_E004_MSG    "PortsUp incorrect."
+#define SKERR_RLMT_E005                (SKERR_RLMT_E004 + 1)
+#define SKERR_RLMT_E005_MSG    \
+ "Net seems to be segmented (different root bridges are reported on the ports)."
+#define SKERR_RLMT_E006                (SKERR_RLMT_E005 + 1)
+#define SKERR_RLMT_E006_MSG    "Duplicate MAC Address detected."
+#define SKERR_RLMT_E007                (SKERR_RLMT_E006 + 1)
+#define SKERR_RLMT_E007_MSG    "LinksUp incorrect."
+#define SKERR_RLMT_E008                (SKERR_RLMT_E007 + 1)
+#define SKERR_RLMT_E008_MSG    "Port not started but link came up."
+#define SKERR_RLMT_E009                (SKERR_RLMT_E008 + 1)
+#define SKERR_RLMT_E009_MSG    "Corrected illegal setting of Preferred Port."
+#define SKERR_RLMT_E010                (SKERR_RLMT_E009 + 1)
+#define SKERR_RLMT_E010_MSG    "Ignored illegal Preferred Port."
+
+/* LLC field values. */
+#define LLC_COMMAND_RESPONSE_BIT               1
+#define LLC_TEST_COMMAND                               0xE3
+#define LLC_UI                                                 0x03
+
+/* RLMT Packet fields. */
+#define        SK_RLMT_DSAP                                    0
+#define        SK_RLMT_SSAP                                    0
+#define SK_RLMT_CTRL                                   (LLC_TEST_COMMAND)
+#define SK_RLMT_INDICATOR0                             0x53    /* S */
+#define SK_RLMT_INDICATOR1                             0x4B    /* K */
+#define SK_RLMT_INDICATOR2                             0x2D    /* - */
+#define SK_RLMT_INDICATOR3                             0x52    /* R */
+#define SK_RLMT_INDICATOR4                             0x4C    /* L */
+#define SK_RLMT_INDICATOR5                             0x4D    /* M */
+#define SK_RLMT_INDICATOR6                             0x54    /* T */
+#define SK_RLMT_PACKET_VERSION                 0
+
+/* RLMT SPT Flag values. */
+#define        SK_RLMT_SPT_FLAG_CHANGE                 0x01
+#define        SK_RLMT_SPT_FLAG_CHANGE_ACK             0x80
+
+/* RLMT SPT Packet fields. */
+#define        SK_RLMT_SPT_DSAP                                0x42
+#define        SK_RLMT_SPT_SSAP                                0x42
+#define SK_RLMT_SPT_CTRL                               (LLC_UI)
+#define        SK_RLMT_SPT_PROTOCOL_ID0                0x00
+#define        SK_RLMT_SPT_PROTOCOL_ID1                0x00
+#define        SK_RLMT_SPT_PROTOCOL_VERSION_ID 0x00
+#define        SK_RLMT_SPT_BPDU_TYPE                   0x00
+#define        SK_RLMT_SPT_FLAGS                               0x00    /* ?? */
+#define        SK_RLMT_SPT_ROOT_ID0                    0xFF    /* Lowest possible priority. */
+#define        SK_RLMT_SPT_ROOT_ID1                    0xFF    /* Lowest possible priority. */
+
+/* Remaining 6 bytes will be the current port address. */
+#define        SK_RLMT_SPT_ROOT_PATH_COST0             0x00
+#define        SK_RLMT_SPT_ROOT_PATH_COST1             0x00
+#define        SK_RLMT_SPT_ROOT_PATH_COST2             0x00
+#define        SK_RLMT_SPT_ROOT_PATH_COST3             0x00
+#define        SK_RLMT_SPT_BRIDGE_ID0                  0xFF    /* Lowest possible priority. */
+#define        SK_RLMT_SPT_BRIDGE_ID1                  0xFF    /* Lowest possible priority. */
+
+/* Remaining 6 bytes will be the current port address. */
+#define        SK_RLMT_SPT_PORT_ID0                    0xFF    /* Lowest possible priority. */
+#define        SK_RLMT_SPT_PORT_ID1                    0xFF    /* Lowest possible priority. */
+#define        SK_RLMT_SPT_MSG_AGE0                    0x00
+#define        SK_RLMT_SPT_MSG_AGE1                    0x00
+#define        SK_RLMT_SPT_MAX_AGE0                    0x00
+#define        SK_RLMT_SPT_MAX_AGE1                    0xFF
+#define        SK_RLMT_SPT_HELLO_TIME0                 0x00
+#define        SK_RLMT_SPT_HELLO_TIME1                 0xFF
+#define        SK_RLMT_SPT_FWD_DELAY0                  0x00
+#define        SK_RLMT_SPT_FWD_DELAY1                  0x40
+
+/* Size defines. */
+#define SK_RLMT_MIN_PACKET_SIZE                        34
+#define SK_RLMT_MAX_PACKET_SIZE                        (SK_RLMT_MAX_TX_BUF_SIZE)
+#define SK_PACKET_DATA_LEN                             (SK_RLMT_MAX_PACKET_SIZE - \
+                                                                               SK_RLMT_MIN_PACKET_SIZE)
+
+/* ----- RLMT packet types ----- */
+#define SK_PACKET_ANNOUNCE                             1       /* Port announcement. */
+#define SK_PACKET_ALIVE                                        2       /* Alive packet to port. */
+#define SK_PACKET_ADDR_CHANGED                 3       /* Port address changed. */
+#define SK_PACKET_CHECK_TX                             4       /* Check your tx line. */
+
+#ifdef SK_LITTLE_ENDIAN
+#define SK_U16_TO_NETWORK_ORDER(Val,Addr) { \
+       SK_U8   *_Addr = (SK_U8*)(Addr); \
+       SK_U16  _Val = (SK_U16)(Val); \
+       *_Addr++ = (SK_U8)(_Val >> 8); \
+       *_Addr = (SK_U8)(_Val & 0xFF); \
+}
+#endif /* SK_LITTLE_ENDIAN */
+
+#ifdef SK_BIG_ENDIAN
+#define SK_U16_TO_NETWORK_ORDER(Val,Addr) (*(SK_U16*)(Addr) = (SK_U16)(Val))
+#endif /* SK_BIG_ENDIAN */
+
+#define AUTONEG_FAILED SK_FALSE
+#define AUTONEG_SUCCESS        SK_TRUE
+
+
+/* typedefs *******************************************************************/
+
+/* RLMT packet.  Length: SK_RLMT_MAX_PACKET_SIZE (60) bytes. */
+typedef struct s_RlmtPacket {
+       SK_U8   DstAddr[SK_MAC_ADDR_LEN];
+       SK_U8   SrcAddr[SK_MAC_ADDR_LEN];
+       SK_U8   TypeLen[2];
+       SK_U8   DSap;
+       SK_U8   SSap;
+       SK_U8   Ctrl;
+       SK_U8   Indicator[7];
+       SK_U8   RlmtPacketType[2];
+       SK_U8   Align1[2];
+       SK_U8   Random[4];                              /* Random value of requesting(!) station. */
+       SK_U8   RlmtPacketVersion[2];   /* RLMT Packet version. */
+       SK_U8   Data[SK_PACKET_DATA_LEN];
+} SK_RLMT_PACKET;
+
+typedef struct s_SpTreeRlmtPacket {
+       SK_U8   DstAddr[SK_MAC_ADDR_LEN];
+       SK_U8   SrcAddr[SK_MAC_ADDR_LEN];
+       SK_U8   TypeLen[2];
+       SK_U8   DSap;
+       SK_U8   SSap;
+       SK_U8   Ctrl;
+       SK_U8   ProtocolId[2];
+       SK_U8   ProtocolVersionId;
+       SK_U8   BpduType;
+       SK_U8   Flags;
+       SK_U8   RootId[8];
+       SK_U8   RootPathCost[4];
+       SK_U8   BridgeId[8];
+       SK_U8   PortId[2];
+       SK_U8   MessageAge[2];
+       SK_U8   MaxAge[2];
+       SK_U8   HelloTime[2];
+       SK_U8   ForwardDelay[2];
+} SK_SPTREE_PACKET;
+
+/* global variables ***********************************************************/
+
+SK_MAC_ADDR    SkRlmtMcAddr =  {{0x01,  0x00,  0x5A,  0x52,  0x4C,  0x4D}};
+SK_MAC_ADDR    BridgeMcAddr =  {{0x01,  0x80,  0xC2,  0x00,  0x00,  0x00}};
+SK_MAC_ADDR    BcAddr =                {{0xFF,  0xFF,  0xFF,  0xFF,  0xFF,  0xFF}};
+
+/* local variables ************************************************************/
+
+/* None. */
+
+/* functions ******************************************************************/
+
+RLMT_STATIC void       SkRlmtCheckSwitch(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       SK_U32  NetIdx);
+RLMT_STATIC void       SkRlmtCheckSeg(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       SK_U32  NetIdx);
+RLMT_STATIC void       SkRlmtEvtSetNets(
+       SK_AC           *pAC,
+       SK_IOC          IoC,
+       SK_EVPARA       Para);
+
+/******************************************************************************
+ *
+ *     SkRlmtInit - initialize data, set state to init
+ *
+ * Description:
+ *
+ *     SK_INIT_DATA
+ *     ============
+ *
+ *     This routine initializes all RLMT-related variables to a known state.
+ *     The initial state is SK_RLMT_RS_INIT.
+ *     All ports are initialized to SK_RLMT_PS_INIT.
+ *
+ *
+ *     SK_INIT_IO
+ *     ==========
+ *
+ *     Nothing.
+ *
+ *
+ *     SK_INIT_RUN
+ *     ===========
+ *
+ *     Determine the adapter's random value.
+ *     Set the hw registers, the "logical MAC address", the
+ *     RLMT multicast address, and eventually the BPDU multicast address.
+ *
+ * Context:
+ *     init, pageable
+ *
+ * Returns:
+ *     Nothing.
+ */
+void   SkRlmtInit(
+SK_AC  *pAC,   /* Adapter Context */
+SK_IOC IoC,    /* I/O Context */
+int            Level)  /* Initialization Level */
+{
+       SK_U32          i, j;
+       SK_U64          Random;
+       SK_EVPARA       Para;
+    SK_MAC_ADDR                VirtualMacAddress;
+    SK_MAC_ADDR                PhysicalAMacAddress;
+    SK_BOOL            VirtualMacAddressSet;
+    SK_BOOL            PhysicalAMacAddressSet;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
+               ("RLMT Init level %d.\n", Level))
+
+       switch (Level) {
+       case SK_INIT_DATA:      /* Initialize data structures. */
+               SK_MEMSET((char *)&pAC->Rlmt, 0, sizeof(SK_RLMT));
+
+               for (i = 0; i < SK_MAX_MACS; i++) {
+                       pAC->Rlmt.Port[i].PortState = SK_RLMT_PS_INIT;
+                       pAC->Rlmt.Port[i].LinkDown = SK_TRUE;
+                       pAC->Rlmt.Port[i].PortDown = SK_TRUE;
+                       pAC->Rlmt.Port[i].PortStarted = SK_FALSE;
+                       pAC->Rlmt.Port[i].PortNoRx = SK_FALSE;
+                       pAC->Rlmt.Port[i].RootIdSet = SK_FALSE;
+                       pAC->Rlmt.Port[i].PortNumber = i;
+                       pAC->Rlmt.Port[i].Net = &pAC->Rlmt.Net[0];
+                       pAC->Rlmt.Port[i].AddrPort = &pAC->Addr.Port[i];
+               }
+
+               pAC->Rlmt.NumNets = 1;
+               for (i = 0; i < SK_MAX_NETS; i++) {
+                       pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
+                       pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
+                       pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
+                       pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF;         /* Automatic. */
+                       /* Just assuming. */
+                       pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
+                       pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
+                       pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
+                       pAC->Rlmt.Net[i].NetNumber = i;
+               }
+
+               pAC->Rlmt.Net[0].Port[0] = &pAC->Rlmt.Port[0];
+               pAC->Rlmt.Net[0].Port[1] = &pAC->Rlmt.Port[1];
+#if SK_MAX_NETS > 1
+               pAC->Rlmt.Net[1].Port[0] = &pAC->Rlmt.Port[1];
+#endif /* SK_MAX_NETS > 1 */
+               break;
+
+       case SK_INIT_IO:        /* GIMacsFound first available here. */
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
+                       ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound))
+
+               pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
+
+               /* Initialize HW registers? */
+               if (pAC->GIni.GIMacsFound == 1) {
+                       Para.Para32[0] = SK_RLMT_MODE_CLS;
+                       Para.Para32[1] = 0;
+                       (void)SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, Para);
+               }
+               break;
+
+       case SK_INIT_RUN:
+               /* Ensure RLMT is set to one net. */
+               if (pAC->Rlmt.NumNets > 1) {
+                       Para.Para32[0] = 1;
+                       Para.Para32[1] = -1;
+                       SkRlmtEvtSetNets(pAC, IoC, Para);
+               }
+
+               for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
+                       Random = SkOsGetTime(pAC);
+                       *(SK_U32*)&pAC->Rlmt.Port[i].Random = *(SK_U32*)&Random;
+
+                       for (j = 0; j < 4; j++) {
+                               pAC->Rlmt.Port[i].Random[j] ^= pAC->Rlmt.Port[i].AddrPort->
+                                       CurrentMacAddress.a[SK_MAC_ADDR_LEN - 1 - j];
+                       }
+
+                       (void)SkAddrMcClear(pAC, IoC, i, SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
+
+                       /* Add RLMT MC address. */
+                       (void)SkAddrMcAdd(pAC, IoC, i, &SkRlmtMcAddr, SK_ADDR_PERMANENT);
+
+                       if (pAC->Rlmt.Net[0].RlmtMode & SK_RLMT_CHECK_SEG) {
+                               /* Add BPDU MC address. */
+                               (void)SkAddrMcAdd(pAC, IoC, i, &BridgeMcAddr, SK_ADDR_PERMANENT);
+                       }
+
+                       (void)SkAddrMcUpdate(pAC, IoC, i);
+               }
+
+       VirtualMacAddressSet = SK_FALSE;
+               /* Read virtual MAC address from Control Register File. */
+               for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
+
+           SK_IN8(IoC, B2_MAC_1 + j, &VirtualMacAddress.a[j]);
+           VirtualMacAddressSet |= VirtualMacAddress.a[j];
+               }
+
+       PhysicalAMacAddressSet = SK_FALSE;
+               /* Read physical MAC address for MAC A from Control Register File. */
+               for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
+
+           SK_IN8(IoC, B2_MAC_2 + j, &PhysicalAMacAddress.a[j]);
+           PhysicalAMacAddressSet |= PhysicalAMacAddress.a[j];
+               }
+
+       /* check if the two mac addresses contain reasonable values */
+       if (!VirtualMacAddressSet || !PhysicalAMacAddressSet) {
+
+           pAC->Rlmt.RlmtOff = SK_TRUE;
+       }
+
+       /* if the two mac addresses are equal switch off the RLMT_PRE_LOOKAHEAD
+          and the RLMT_LOOKAHEAD macros */
+       else if (SK_ADDR_EQUAL(PhysicalAMacAddress.a, VirtualMacAddress.a)) {
+
+           pAC->Rlmt.RlmtOff = SK_TRUE;
+       }
+               else {
+                       pAC->Rlmt.RlmtOff = SK_FALSE;
+               }
+               break;
+
+       default:        /* error */
+               break;
+       }
+       return;
+}      /* SkRlmtInit */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtBuildCheckChain - build the check chain
+ *
+ * Description:
+ *     This routine builds the local check chain:
+ *     - Each port that is up checks the next port.
+ *     - The last port that is up checks the first port that is up.
+ *
+ * Notes:
+ *     - Currently only local ports are considered when building the chain.
+ *     - Currently the SuspectState is just reset;
+ *       it would be better to save it ...
+ *
+ * Context:
+ *     runtime, pageable?
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtBuildCheckChain(
+SK_AC  *pAC,   /* Adapter Context */
+SK_U32 NetIdx) /* Net Number */
+{
+       SK_U32                  i;
+       SK_U32                  NumMacsUp;
+       SK_RLMT_PORT *  FirstMacUp;
+       SK_RLMT_PORT *  PrevMacUp;
+
+       FirstMacUp      = NULL;
+       PrevMacUp       = NULL;
+
+       if (!(pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
+               for (i = 0; i < pAC->Rlmt.Net[i].NumPorts; i++) {
+                       pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
+               }
+               return; /* Done. */
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SkRlmtBuildCheckChain.\n"))
+
+       NumMacsUp = 0;
+
+       for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
+               pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
+               pAC->Rlmt.Net[NetIdx].Port[i]->PortsSuspect = 0;
+               pAC->Rlmt.Net[NetIdx].Port[i]->CheckingState &=
+                       ~(SK_RLMT_PCS_RX | SK_RLMT_PCS_TX);
+
+               /*
+                * If more than two links are detected we should consider
+                * checking at least two other ports:
+                * 1. the next port that is not LinkDown and
+                * 2. the next port that is not PortDown.
+                */
+               if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
+                       if (NumMacsUp == 0) {
+                               FirstMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
+                       }
+                       else {
+                               PrevMacUp->PortCheck[
+                                       pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked].CheckAddr =
+                                       pAC->Rlmt.Net[NetIdx].Port[i]->AddrPort->CurrentMacAddress;
+                               PrevMacUp->PortCheck[
+                                       PrevMacUp->PortsChecked].SuspectTx = SK_FALSE;
+                               PrevMacUp->PortsChecked++;
+                       }
+                       PrevMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
+                       NumMacsUp++;
+               }
+       }
+
+       if (NumMacsUp > 1) {
+               PrevMacUp->PortCheck[PrevMacUp->PortsChecked].CheckAddr =
+                       FirstMacUp->AddrPort->CurrentMacAddress;
+               PrevMacUp->PortCheck[PrevMacUp->PortsChecked].SuspectTx =
+                       SK_FALSE;
+               PrevMacUp->PortsChecked++;
+       }
+
+#ifdef DEBUG
+       for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Port %d checks %d other ports: %2X.\n", i,
+                               pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked,
+                               pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5]))
+       }
+#endif /* DEBUG */
+
+       return;
+}      /* SkRlmtBuildCheckChain */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtBuildPacket - build an RLMT packet
+ *
+ * Description:
+ *     This routine sets up an RLMT packet.
+ *
+ * Context:
+ *     runtime, pageable?
+ *
+ * Returns:
+ *     NULL or pointer to RLMT mbuf
+ */
+RLMT_STATIC SK_MBUF    *SkRlmtBuildPacket(
+SK_AC          *pAC,           /* Adapter Context */
+SK_IOC         IoC,            /* I/O Context */
+SK_U32         PortNumber,     /* Sending port */
+SK_U16         PacketType,     /* RLMT packet type */
+SK_MAC_ADDR    *SrcAddr,       /* Source address */
+SK_MAC_ADDR    *DestAddr)      /* Destination address */
+{
+       int             i;
+       SK_U16          Length;
+       SK_MBUF         *pMb;
+       SK_RLMT_PACKET  *pPacket;
+
+#ifdef DEBUG
+       SK_U8   CheckSrc  = 0;
+       SK_U8   CheckDest = 0;
+
+       for (i = 0; i < SK_MAC_ADDR_LEN; ++i) {
+               CheckSrc  |= SrcAddr->a[i];
+               CheckDest |= DestAddr->a[i];
+       }
+
+       if ((CheckSrc == 0) || (CheckDest == 0)) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_ERR,
+                       ("SkRlmtBuildPacket: Invalid %s%saddr.\n",
+                        (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : "")))
+       }
+#endif
+
+       if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) != NULL) {
+               pPacket = (SK_RLMT_PACKET*)pMb->pData;
+               for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
+                       pPacket->DstAddr[i] = DestAddr->a[i];
+                       pPacket->SrcAddr[i] = SrcAddr->a[i];
+               }
+               pPacket->DSap = SK_RLMT_DSAP;
+               pPacket->SSap = SK_RLMT_SSAP;
+               pPacket->Ctrl = SK_RLMT_CTRL;
+               pPacket->Indicator[0] = SK_RLMT_INDICATOR0;
+               pPacket->Indicator[1] = SK_RLMT_INDICATOR1;
+               pPacket->Indicator[2] = SK_RLMT_INDICATOR2;
+               pPacket->Indicator[3] = SK_RLMT_INDICATOR3;
+               pPacket->Indicator[4] = SK_RLMT_INDICATOR4;
+               pPacket->Indicator[5] = SK_RLMT_INDICATOR5;
+               pPacket->Indicator[6] = SK_RLMT_INDICATOR6;
+
+               SK_U16_TO_NETWORK_ORDER(PacketType, &pPacket->RlmtPacketType[0]);
+
+               for (i = 0; i < 4; i++) {
+                       pPacket->Random[i] = pAC->Rlmt.Port[PortNumber].Random[i];
+               }
+
+               SK_U16_TO_NETWORK_ORDER(
+                       SK_RLMT_PACKET_VERSION, &pPacket->RlmtPacketVersion[0]);
+
+               for (i = 0; i < SK_PACKET_DATA_LEN; i++) {
+                       pPacket->Data[i] = 0x00;
+               }
+
+               Length = SK_RLMT_MAX_PACKET_SIZE;       /* Or smaller. */
+               pMb->Length = Length;
+               pMb->PortIdx = PortNumber;
+               Length -= 14;
+               SK_U16_TO_NETWORK_ORDER(Length, &pPacket->TypeLen[0]);
+
+               if (PacketType == SK_PACKET_ALIVE) {
+                       pAC->Rlmt.Port[PortNumber].TxHelloCts++;
+               }
+       }
+
+       return (pMb);
+}      /* SkRlmtBuildPacket */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtBuildSpanningTreePacket - build spanning tree check packet
+ *
+ * Description:
+ *     This routine sets up a BPDU packet for spanning tree check.
+ *
+ * Context:
+ *     runtime, pageable?
+ *
+ * Returns:
+ *     NULL or pointer to RLMT mbuf
+ */
+RLMT_STATIC SK_MBUF    *SkRlmtBuildSpanningTreePacket(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* I/O Context */
+SK_U32 PortNumber)     /* Sending port */
+{
+       unsigned                        i;
+       SK_U16                          Length;
+       SK_MBUF                         *pMb;
+       SK_SPTREE_PACKET        *pSPacket;
+
+       if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) !=
+               NULL) {
+               pSPacket = (SK_SPTREE_PACKET*)pMb->pData;
+               for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
+                       pSPacket->DstAddr[i] = BridgeMcAddr.a[i];
+                       pSPacket->SrcAddr[i] =
+                               pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
+               }
+               pSPacket->DSap = SK_RLMT_SPT_DSAP;
+               pSPacket->SSap = SK_RLMT_SPT_SSAP;
+               pSPacket->Ctrl = SK_RLMT_SPT_CTRL;
+
+               pSPacket->ProtocolId[0] = SK_RLMT_SPT_PROTOCOL_ID0;
+               pSPacket->ProtocolId[1] = SK_RLMT_SPT_PROTOCOL_ID1;
+               pSPacket->ProtocolVersionId = SK_RLMT_SPT_PROTOCOL_VERSION_ID;
+               pSPacket->BpduType = SK_RLMT_SPT_BPDU_TYPE;
+               pSPacket->Flags = SK_RLMT_SPT_FLAGS;
+               pSPacket->RootId[0] = SK_RLMT_SPT_ROOT_ID0;
+               pSPacket->RootId[1] = SK_RLMT_SPT_ROOT_ID1;
+               pSPacket->RootPathCost[0] = SK_RLMT_SPT_ROOT_PATH_COST0;
+               pSPacket->RootPathCost[1] = SK_RLMT_SPT_ROOT_PATH_COST1;
+               pSPacket->RootPathCost[2] = SK_RLMT_SPT_ROOT_PATH_COST2;
+               pSPacket->RootPathCost[3] = SK_RLMT_SPT_ROOT_PATH_COST3;
+               pSPacket->BridgeId[0] = SK_RLMT_SPT_BRIDGE_ID0;
+               pSPacket->BridgeId[1] = SK_RLMT_SPT_BRIDGE_ID1;
+
+               /*
+                * Use logical MAC address as bridge ID and filter these packets
+                * on receive.
+                */
+               for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
+                       pSPacket->BridgeId[i + 2] = pSPacket->RootId[i + 2] =
+                               pAC->Addr.Net[pAC->Rlmt.Port[PortNumber].Net->NetNumber].
+                                       CurrentMacAddress.a[i];
+               }
+               pSPacket->PortId[0] = SK_RLMT_SPT_PORT_ID0;
+               pSPacket->PortId[1] = SK_RLMT_SPT_PORT_ID1;
+               pSPacket->MessageAge[0] = SK_RLMT_SPT_MSG_AGE0;
+               pSPacket->MessageAge[1] = SK_RLMT_SPT_MSG_AGE1;
+               pSPacket->MaxAge[0] = SK_RLMT_SPT_MAX_AGE0;
+               pSPacket->MaxAge[1] = SK_RLMT_SPT_MAX_AGE1;
+               pSPacket->HelloTime[0] = SK_RLMT_SPT_HELLO_TIME0;
+               pSPacket->HelloTime[1] = SK_RLMT_SPT_HELLO_TIME1;
+               pSPacket->ForwardDelay[0] = SK_RLMT_SPT_FWD_DELAY0;
+               pSPacket->ForwardDelay[1] = SK_RLMT_SPT_FWD_DELAY1;
+
+               Length = SK_RLMT_MAX_PACKET_SIZE;       /* Or smaller. */
+               pMb->Length = Length;
+               pMb->PortIdx = PortNumber;
+               Length -= 14;
+               SK_U16_TO_NETWORK_ORDER(Length, &pSPacket->TypeLen[0]);
+
+               pAC->Rlmt.Port[PortNumber].TxSpHelloReqCts++;
+       }
+
+       return (pMb);
+}      /* SkRlmtBuildSpanningTreePacket */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtSend - build and send check packets
+ *
+ * Description:
+ *     Depending on the RLMT state and the checking state, several packets
+ *     are sent through the indicated port.
+ *
+ * Context:
+ *     runtime, pageable?
+ *
+ * Returns:
+ *     Nothing.
+ */
+RLMT_STATIC void       SkRlmtSend(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* I/O Context */
+SK_U32 PortNumber)     /* Sending port */
+{
+       unsigned        j;
+       SK_EVPARA       Para;
+       SK_RLMT_PORT    *pRPort;
+
+       pRPort = &pAC->Rlmt.Port[PortNumber];
+       if (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
+               if (pRPort->CheckingState & (SK_RLMT_PCS_TX | SK_RLMT_PCS_RX)) {
+                       /* Port is suspicious. Send the RLMT packet to the RLMT mc addr. */
+                       if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
+                               SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
+                               &SkRlmtMcAddr)) != NULL) {
+                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
+                       }
+               }
+               else {
+                       /*
+                        * Send a directed RLMT packet to all ports that are
+                        * checked by the indicated port.
+                        */
+                       for (j = 0; j < pRPort->PortsChecked; j++) {
+                               if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
+                                       SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
+                                       &pRPort->PortCheck[j].CheckAddr)) != NULL) {
+                                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
+                               }
+                       }
+               }
+       }
+
+       if ((pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
+               (pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEND_SEG)) {
+               /*
+                * Send a BPDU packet to make a connected switch tell us
+                * the correct root bridge.
+                */
+               if ((Para.pParaPtr =
+                       SkRlmtBuildSpanningTreePacket(pAC, IoC, PortNumber)) != NULL) {
+                       pAC->Rlmt.Port[PortNumber].Net->CheckingState &= ~SK_RLMT_RCS_SEND_SEG;
+                       pRPort->RootIdSet = SK_FALSE;
+
+                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX,
+                               ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber))
+               }
+       }
+       return;
+}      /* SkRlmtSend */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtPortReceives - check if port is (going) down and bring it up
+ *
+ * Description:
+ *     This routine checks if a port who received a non-BPDU packet
+ *     needs to go up or needs to be stopped going down.
+ *
+ * Context:
+ *     runtime, pageable?
+ *
+ * Returns:
+ *     Nothing.
+ */
+RLMT_STATIC void       SkRlmtPortReceives(
+SK_AC  *pAC,                   /* Adapter Context */
+SK_IOC IoC,                    /* I/O Context */
+SK_U32 PortNumber)             /* Port to check */
+{
+       SK_RLMT_PORT    *pRPort;
+       SK_EVPARA               Para;
+
+       pRPort = &pAC->Rlmt.Port[PortNumber];
+       pRPort->PortNoRx = SK_FALSE;
+
+       if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
+               !(pRPort->CheckingState & SK_RLMT_PCS_TX)) {
+               /*
+                * Port is marked down (rx), but received a non-BPDU packet.
+                * Bring it up.
+                */
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+                       ("SkRlmtPacketReceive: Received on PortDown.\n"))
+
+               pRPort->PortState = SK_RLMT_PS_GOING_UP;
+               pRPort->GuTimeStamp = SkOsGetTime(pAC);
+               Para.Para32[0] = PortNumber;
+               Para.Para32[1] = (SK_U32)-1;
+               SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
+                       SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para);
+               pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
+               /* pAC->Rlmt.CheckSwitch = SK_TRUE; */
+               SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
+       }       /* PortDown && !SuspectTx */
+       else if (pRPort->CheckingState & SK_RLMT_PCS_RX) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+                       ("SkRlmtPacketReceive: Stop bringing port down.\n"))
+               SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
+               pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
+               /* pAC->Rlmt.CheckSwitch = SK_TRUE; */
+               SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
+       }       /* PortGoingDown */
+
+       return;
+}      /* SkRlmtPortReceives */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtPacketReceive - receive a packet for closer examination
+ *
+ * Description:
+ *     This routine examines a packet more closely than SK_RLMT_LOOKAHEAD.
+ *
+ * Context:
+ *     runtime, pageable?
+ *
+ * Returns:
+ *     Nothing.
+ */
+RLMT_STATIC void       SkRlmtPacketReceive(
+SK_AC  *pAC,   /* Adapter Context */
+SK_IOC IoC,    /* I/O Context */
+SK_MBUF        *pMb)   /* Received packet */
+{
+#ifdef xDEBUG
+       extern  void DumpData(char *p, int size);
+#endif /* DEBUG */
+       int                                     i;
+       unsigned                        j;
+       SK_U16                          PacketType;
+       SK_U32                          PortNumber;
+       SK_ADDR_PORT            *pAPort;
+       SK_RLMT_PORT            *pRPort;
+       SK_RLMT_PACKET          *pRPacket;
+       SK_SPTREE_PACKET        *pSPacket;
+       SK_EVPARA                       Para;
+
+       PortNumber      = pMb->PortIdx;
+       pAPort = &pAC->Addr.Port[PortNumber];
+       pRPort = &pAC->Rlmt.Port[PortNumber];
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+               ("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber))
+
+       pRPacket = (SK_RLMT_PACKET*)pMb->pData;
+       pSPacket = (SK_SPTREE_PACKET*)pRPacket;
+
+#ifdef xDEBUG
+       DumpData((char *)pRPacket, 32);
+#endif /* DEBUG */
+
+       if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) != 0) {
+               SkRlmtPortReceives(pAC, IoC, PortNumber);
+       }
+
+       /* Check destination address. */
+
+       if (!SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->DstAddr) &&
+               !SK_ADDR_EQUAL(SkRlmtMcAddr.a, pRPacket->DstAddr) &&
+               !SK_ADDR_EQUAL(BridgeMcAddr.a, pRPacket->DstAddr)) {
+
+               /* Not sent to current MAC or registered MC address => Trash it. */
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+                       ("SkRlmtPacketReceive: Not for me.\n"))
+
+               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
+               return;
+       }
+       else if (SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->SrcAddr)) {
+
+               /*
+                * Was sent by same port (may happen during port switching
+                * or in case of duplicate MAC addresses).
+                */
+
+               /*
+                * Check for duplicate address here:
+                * If Packet.Random != My.Random => DupAddr.
+                */
+               for (i = 3; i >= 0; i--) {
+                       if (pRPort->Random[i] != pRPacket->Random[i]) {
+                               break;
+                       }
+               }
+
+               /*
+                * CAUTION: Do not check for duplicate MAC address in RLMT Alive Reply
+                * packets (they have the LLC_COMMAND_RESPONSE_BIT set in
+                * pRPacket->SSap).
+                */
+               if (i >= 0 && pRPacket->DSap == SK_RLMT_DSAP &&
+                       pRPacket->Ctrl == SK_RLMT_CTRL &&
+                       pRPacket->SSap == SK_RLMT_SSAP &&
+                       pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&
+                       pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&
+                       pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&
+                       pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&
+                       pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&
+                       pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
+                       pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+                               ("SkRlmtPacketReceive: Duplicate MAC Address.\n"))
+
+                       /* Error Log entry. */
+                       SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E006, SKERR_RLMT_E006_MSG);
+               }
+               else {
+                       /* Simply trash it. */
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+                               ("SkRlmtPacketReceive: Sent by me.\n"))
+               }
+
+               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
+               return;
+       }
+
+       /* Check SuspectTx entries. */
+       if (pRPort->PortsSuspect > 0) {
+               for (j = 0; j < pRPort->PortsChecked; j++) {
+                       if (pRPort->PortCheck[j].SuspectTx &&
+                               SK_ADDR_EQUAL(
+                                       pRPacket->SrcAddr, pRPort->PortCheck[j].CheckAddr.a)) {
+                               pRPort->PortCheck[j].SuspectTx = SK_FALSE;
+                               pRPort->PortsSuspect--;
+                               break;
+                       }
+               }
+       }
+
+       /* Determine type of packet. */
+       if (pRPacket->DSap == SK_RLMT_DSAP &&
+               pRPacket->Ctrl == SK_RLMT_CTRL &&
+               (pRPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SSAP &&
+               pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&
+               pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&
+               pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&
+               pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&
+               pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&
+               pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
+               pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
+
+               /* It's an RLMT packet. */
+               PacketType = (SK_U16)((pRPacket->RlmtPacketType[0] << 8) |
+                       pRPacket->RlmtPacketType[1]);
+
+               switch (PacketType) {
+               case SK_PACKET_ANNOUNCE:        /* Not yet used. */
+#if 0
+                       /* Build the check chain. */
+                       SkRlmtBuildCheckChain(pAC);
+#endif /* 0 */
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+                               ("SkRlmtPacketReceive: Announce.\n"))
+
+                       SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
+                       break;
+
+               case SK_PACKET_ALIVE:
+                       if (pRPacket->SSap & LLC_COMMAND_RESPONSE_BIT) {
+                               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+                                       ("SkRlmtPacketReceive: Alive Reply.\n"))
+
+                               if (!(pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_LLC) ||
+                                       SK_ADDR_EQUAL(
+                                               pRPacket->DstAddr, pAPort->CurrentMacAddress.a)) {
+                                       /* Obviously we could send something. */
+                                       if (pRPort->CheckingState & SK_RLMT_PCS_TX) {
+                                               pRPort->CheckingState &=  ~SK_RLMT_PCS_TX;
+                                               SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
+                                       }
+
+                                       if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
+                                               !(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
+                                               pRPort->PortState = SK_RLMT_PS_GOING_UP;
+                                               pRPort->GuTimeStamp = SkOsGetTime(pAC);
+
+                                               SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
+
+                                               Para.Para32[0] = PortNumber;
+                                               Para.Para32[1] = (SK_U32)-1;
+                                               SkTimerStart(pAC, IoC, &pRPort->UpTimer,
+                                                       SK_RLMT_PORTUP_TIM_VAL, SKGE_RLMT,
+                                                       SK_RLMT_PORTUP_TIM, Para);
+                                       }
+                               }
+
+                               /* Mark sending port as alive? */
+                               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
+                       }
+                       else {  /* Alive Request Packet. */
+                               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+                                       ("SkRlmtPacketReceive: Alive Request.\n"))
+
+                               pRPort->RxHelloCts++;
+
+                               /* Answer. */
+                               for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
+                                       pRPacket->DstAddr[i] = pRPacket->SrcAddr[i];
+                                       pRPacket->SrcAddr[i] =
+                                               pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
+                               }
+                               pRPacket->SSap |= LLC_COMMAND_RESPONSE_BIT;
+
+                               Para.pParaPtr = pMb;
+                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
+                       }
+                       break;
+
+               case SK_PACKET_CHECK_TX:
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+                               ("SkRlmtPacketReceive: Check your tx line.\n"))
+
+                       /* A port checking us requests us to check our tx line. */
+                       pRPort->CheckingState |= SK_RLMT_PCS_TX;
+
+                       /* Start PortDownTx timer. */
+                       Para.Para32[0] = PortNumber;
+                       Para.Para32[1] = (SK_U32)-1;
+                       SkTimerStart(pAC, IoC, &pRPort->DownTxTimer,
+                               SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
+                               SK_RLMT_PORTDOWN_TX_TIM, Para);
+
+                       SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
+
+                       if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
+                               SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
+                               &SkRlmtMcAddr)) != NULL) {
+                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
+                       }
+                       break;
+
+               case SK_PACKET_ADDR_CHANGED:
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+                               ("SkRlmtPacketReceive: Address Change.\n"))
+
+                       /* Build the check chain. */
+                       SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
+                       SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
+                       break;
+
+               default:
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+                               ("SkRlmtPacketReceive: Unknown RLMT packet.\n"))
+
+                       /* RA;:;: ??? */
+                       SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
+               }
+       }
+       else if (pSPacket->DSap == SK_RLMT_SPT_DSAP &&
+               pSPacket->Ctrl == SK_RLMT_SPT_CTRL &&
+               (pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SPT_SSAP) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+                       ("SkRlmtPacketReceive: BPDU Packet.\n"))
+
+               /* Spanning Tree packet. */
+               pRPort->RxSpHelloCts++;
+
+               if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pAC->Addr.Net[pAC->Rlmt.
+                       Port[PortNumber].Net->NetNumber].CurrentMacAddress.a[0])) {
+                       /*
+                        * Check segmentation if a new root bridge is set and
+                        * the segmentation check is not currently running.
+                        */
+                       if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pRPort->Root.Id[2]) &&
+                               (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
+                               (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG)
+                               != 0 && (pAC->Rlmt.Port[PortNumber].Net->CheckingState &
+                               SK_RLMT_RCS_SEG) == 0) {
+                               pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
+                                       SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
+                       }
+
+                       /* Store tree view of this port. */
+                       for (i = 0; i < 8; i++) {
+                               pRPort->Root.Id[i] = pSPacket->RootId[i];
+                       }
+                       pRPort->RootIdSet = SK_TRUE;
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
+                               ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
+                                       PortNumber,
+                                       pRPort->Root.Id[0], pRPort->Root.Id[1],
+                                       pRPort->Root.Id[2], pRPort->Root.Id[3],
+                                       pRPort->Root.Id[4], pRPort->Root.Id[5],
+                                       pRPort->Root.Id[6], pRPort->Root.Id[7]))
+               }
+
+               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
+               if ((pAC->Rlmt.Port[PortNumber].Net->CheckingState &
+                       SK_RLMT_RCS_REPORT_SEG) != 0) {
+                       SkRlmtCheckSeg(pAC, IoC, pAC->Rlmt.Port[PortNumber].Net->NetNumber);
+               }
+       }
+       else {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+                       ("SkRlmtPacketReceive: Unknown Packet Type.\n"))
+
+               /* Unknown packet. */
+               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
+       }
+       return;
+}      /* SkRlmtPacketReceive */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtCheckPort - check if a port works
+ *
+ * Description:
+ *     This routine checks if a port whose link is up received something
+ *     and if it seems to transmit successfully.
+ *
+ *     # PortState: PsInit, PsLinkDown, PsDown, PsGoingUp, PsUp
+ *     # PortCheckingState (Bitfield): ChkTx, ChkRx, ChkSeg
+ *     # RlmtCheckingState (Bitfield): ChkSeg, StartChkSeg, ReportSeg
+ *
+ *     if (Rx - RxBpdu == 0) { # No rx.
+ *             if (state == PsUp) {
+ *                     PortCheckingState |= ChkRx
+ *             }
+ *             if (ModeCheckSeg && (Timeout ==
+ *                     TO_SHORTEN(RLMT_DEFAULT_TIMEOUT))) {
+ *                     RlmtCheckingState |= ChkSeg)
+ *                     PortCheckingState |= ChkSeg
+ *             }
+ *             NewTimeout = TO_SHORTEN(Timeout)
+ *             if (NewTimeout < RLMT_MIN_TIMEOUT) {
+ *                     NewTimeout = RLMT_MIN_TIMEOUT
+ *                     PortState = PsDown
+ *                     ...
+ *             }
+ *     }
+ *     else {  # something was received
+ *             # Set counter to 0 at LinkDown?
+ *             #   No - rx may be reported after LinkDown ???
+ *             PortCheckingState &= ~ChkRx
+ *             NewTimeout = RLMT_DEFAULT_TIMEOUT
+ *             if (RxAck == 0) {
+ *                     possible reasons:
+ *                     is my tx line bad? --
+ *                             send RLMT multicast and report
+ *                             back internally? (only possible
+ *                             between ports on same adapter)
+ *             }
+ *             if (RxChk == 0) {
+ *                     possible reasons:
+ *                     - tx line of port set to check me
+ *                       maybe bad
+ *                     - no other port/adapter available or set
+ *                       to check me
+ *                     - adapter checking me has a longer
+ *                       timeout
+ *                     ??? anything that can be done here?
+ *             }
+ *     }
+ *
+ * Context:
+ *     runtime, pageable?
+ *
+ * Returns:
+ *     New timeout value.
+ */
+RLMT_STATIC SK_U32     SkRlmtCheckPort(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* I/O Context */
+SK_U32 PortNumber)     /* Port to check */
+{
+       unsigned                i;
+       SK_U32                  NewTimeout;
+       SK_RLMT_PORT    *pRPort;
+       SK_EVPARA               Para;
+
+       pRPort = &pAC->Rlmt.Port[PortNumber];
+
+       if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) == 0) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SkRlmtCheckPort %d: No (%d) receives in last time slot.\n",
+                               PortNumber, pRPort->PacketsPerTimeSlot))
+
+               /*
+                * Check segmentation if there was no receive at least twice
+                * in a row (PortNoRx is already set) and the segmentation
+                * check is not currently running.
+                */
+
+               if (pRPort->PortNoRx && (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
+                       (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
+                       !(pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEG)) {
+                       pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
+                               SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
+               }
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SkRlmtCheckPort: PortsSuspect %d, PcsRx %d.\n",
+                               pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX))
+
+               if (pRPort->PortState != SK_RLMT_PS_DOWN) {
+                       NewTimeout = TO_SHORTEN(pAC->Rlmt.Port[PortNumber].Net->TimeoutValue);
+                       if (NewTimeout < SK_RLMT_MIN_TO_VAL) {
+                               NewTimeout = SK_RLMT_MIN_TO_VAL;
+                       }
+
+                       if (!(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
+                               Para.Para32[0] = PortNumber;
+                               pRPort->CheckingState |= SK_RLMT_PCS_RX;
+
+                               /*
+                                * What shall we do if the port checked by this one receives
+                                * our request frames?  What's bad - our rx line or his tx line?
+                                */
+                               Para.Para32[1] = (SK_U32)-1;
+                               SkTimerStart(pAC, IoC, &pRPort->DownRxTimer,
+                                       SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
+                                       SK_RLMT_PORTDOWN_RX_TIM, Para);
+
+                               for (i = 0; i < pRPort->PortsChecked; i++) {
+                                       if (pRPort->PortCheck[i].SuspectTx) {
+                                               continue;
+                                       }
+                                       pRPort->PortCheck[i].SuspectTx = SK_TRUE;
+                                       pRPort->PortsSuspect++;
+                                       if ((Para.pParaPtr =
+                                               SkRlmtBuildPacket(pAC, IoC, PortNumber, SK_PACKET_CHECK_TX,
+                                                       &pAC->Addr.Port[PortNumber].CurrentMacAddress,
+                                                       &pRPort->PortCheck[i].CheckAddr)) != NULL) {
+                                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
+                                       }
+                               }
+                       }
+               }
+               else {  /* PortDown -- or all partners suspect. */
+                       NewTimeout = SK_RLMT_DEF_TO_VAL;
+               }
+               pRPort->PortNoRx = SK_TRUE;
+       }
+       else {  /* A non-BPDU packet was received. */
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SkRlmtCheckPort %d: %d (%d) receives in last time slot.\n",
+                               PortNumber,
+                               pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot,
+                               pRPort->PacketsPerTimeSlot))
+
+               SkRlmtPortReceives(pAC, IoC, PortNumber);
+               if (pAC->Rlmt.CheckSwitch) {
+                       SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
+               }
+
+               NewTimeout = SK_RLMT_DEF_TO_VAL;
+       }
+
+       return (NewTimeout);
+}      /* SkRlmtCheckPort */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtSelectBcRx - select new active port, criteria 1 (CLP)
+ *
+ * Description:
+ *     This routine selects the port that received a broadcast frame
+ *     substantially later than all other ports.
+ *
+ * Context:
+ *     runtime, pageable?
+ *
+ * Returns:
+ *     SK_BOOL
+ */
+RLMT_STATIC SK_BOOL    SkRlmtSelectBcRx(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* I/O Context */
+SK_U32 Active,         /* Active port */
+SK_U32 PrefPort,       /* Preferred port */
+SK_U32 *pSelect)       /* New active port */
+{
+       SK_U64          BcTimeStamp;
+       SK_U32          i;
+       SK_BOOL         PortFound;
+
+       BcTimeStamp = 0;        /* Not totally necessary, but feeling better. */
+       PortFound = SK_FALSE;
+
+       /* Select port with the latest TimeStamp. */
+       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("TimeStamp Port %d (Down: %d, NoRx: %d): %08x %08x.\n",
+                               i,
+                               pAC->Rlmt.Port[i].PortDown, pAC->Rlmt.Port[i].PortNoRx,
+                               *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32),
+                               *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32)))
+
+               if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx) {
+                       if (!PortFound || pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) {
+                               BcTimeStamp = pAC->Rlmt.Port[i].BcTimeStamp;
+                               *pSelect = i;
+                               PortFound = SK_TRUE;
+                       }
+               }
+       }
+
+       if (PortFound) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Port %d received the last broadcast.\n", *pSelect))
+
+               /* Look if another port's time stamp is similar. */
+               for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
+                       if (i == *pSelect) {
+                               continue;
+                       }
+                       if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx &&
+                               (pAC->Rlmt.Port[i].BcTimeStamp >
+                                BcTimeStamp - SK_RLMT_BC_DELTA ||
+                               pAC->Rlmt.Port[i].BcTimeStamp +
+                                SK_RLMT_BC_DELTA > BcTimeStamp)) {
+                               PortFound = SK_FALSE;
+
+                               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                                       ("Port %d received a broadcast at a similar time.\n", i))
+                               break;
+                       }
+               }
+       }
+
+#ifdef DEBUG
+       if (PortFound) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_SELECT_BCRX found Port %d receiving the substantially "
+                        "latest broadcast (%u).\n",
+                               *pSelect,
+                               BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp))
+       }
+#endif /* DEBUG */
+
+       return (PortFound);
+}      /* SkRlmtSelectBcRx */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtSelectNotSuspect - select new active port, criteria 2 (CLP)
+ *
+ * Description:
+ *     This routine selects a good port (it is PortUp && !SuspectRx).
+ *
+ * Context:
+ *     runtime, pageable?
+ *
+ * Returns:
+ *     SK_BOOL
+ */
+RLMT_STATIC SK_BOOL    SkRlmtSelectNotSuspect(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* I/O Context */
+SK_U32 Active,         /* Active port */
+SK_U32 PrefPort,       /* Preferred port */
+SK_U32 *pSelect)       /* New active port */
+{
+       SK_U32          i;
+       SK_BOOL         PortFound;
+
+       PortFound = SK_FALSE;
+
+       /* Select first port that is PortUp && !SuspectRx. */
+       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
+               if (!pAC->Rlmt.Port[i].PortDown &&
+                       !(pAC->Rlmt.Port[i].CheckingState & SK_RLMT_PCS_RX)) {
+                       *pSelect = i;
+                       if (!pAC->Rlmt.Port[Active].PortDown &&
+                               !(pAC->Rlmt.Port[Active].CheckingState & SK_RLMT_PCS_RX)) {
+                               *pSelect = Active;
+                       }
+                       if (!pAC->Rlmt.Port[PrefPort].PortDown &&
+                               !(pAC->Rlmt.Port[PrefPort].CheckingState & SK_RLMT_PCS_RX)) {
+                               *pSelect = PrefPort;
+                       }
+                       PortFound = SK_TRUE;
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                               ("SK_RLMT_SELECT_NOTSUSPECT found Port %d up and not check RX.\n",
+                                       *pSelect))
+                       break;
+               }
+       }
+       return (PortFound);
+}      /* SkRlmtSelectNotSuspect */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtSelectUp - select new active port, criteria 3, 4 (CLP)
+ *
+ * Description:
+ *     This routine selects a port that is up.
+ *
+ * Context:
+ *     runtime, pageable?
+ *
+ * Returns:
+ *     SK_BOOL
+ */
+RLMT_STATIC SK_BOOL    SkRlmtSelectUp(
+SK_AC  *pAC,                   /* Adapter Context */
+SK_IOC IoC,                    /* I/O Context */
+SK_U32 Active,                 /* Active port */
+SK_U32 PrefPort,               /* Preferred port */
+SK_U32 *pSelect,               /* New active port */
+SK_BOOL        AutoNegDone)    /* Successfully auto-negotiated? */
+{
+       SK_U32          i;
+       SK_BOOL         PortFound;
+
+       PortFound = SK_FALSE;
+
+       /* Select first port that is PortUp. */
+       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
+               if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_UP &&
+                       pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
+                       *pSelect = i;
+                       if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_UP &&
+                               pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
+                               *pSelect = Active;
+                       }
+                       if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_UP &&
+                               pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
+                               *pSelect = PrefPort;
+                       }
+                       PortFound = SK_TRUE;
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                               ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect))
+                       break;
+               }
+       }
+       return (PortFound);
+}      /* SkRlmtSelectUp */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtSelectGoingUp - select new active port, criteria 5, 6 (CLP)
+ *
+ * Description:
+ *     This routine selects the port that is going up for the longest time.
+ *
+ * Context:
+ *     runtime, pageable?
+ *
+ * Returns:
+ *     SK_BOOL
+ */
+RLMT_STATIC SK_BOOL    SkRlmtSelectGoingUp(
+SK_AC  *pAC,                   /* Adapter Context */
+SK_IOC IoC,                    /* I/O Context */
+SK_U32 Active,                 /* Active port */
+SK_U32 PrefPort,               /* Preferred port */
+SK_U32 *pSelect,               /* New active port */
+SK_BOOL        AutoNegDone)    /* Successfully auto-negotiated? */
+{
+       SK_U64          GuTimeStamp;
+       SK_U32          i;
+       SK_BOOL         PortFound;
+
+       GuTimeStamp = 0;
+       PortFound = SK_FALSE;
+
+       /* Select port that is PortGoingUp for the longest time. */
+       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
+               if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
+                       pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
+                       GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
+                       *pSelect = i;
+                       PortFound = SK_TRUE;
+                       break;
+               }
+       }
+
+       if (!PortFound) {
+               return (SK_FALSE);
+       }
+
+       for (i = *pSelect + 1; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
+               if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
+                       pAC->Rlmt.Port[i].GuTimeStamp < GuTimeStamp &&
+                       pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
+                       GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
+                       *pSelect = i;
+               }
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect))
+       return (SK_TRUE);
+}      /* SkRlmtSelectGoingUp */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtSelectDown - select new active port, criteria 7, 8 (CLP)
+ *
+ * Description:
+ *     This routine selects a port that is down.
+ *
+ * Context:
+ *     runtime, pageable?
+ *
+ * Returns:
+ *     SK_BOOL
+ */
+RLMT_STATIC SK_BOOL    SkRlmtSelectDown(
+SK_AC  *pAC,                   /* Adapter Context */
+SK_IOC IoC,                    /* I/O Context */
+SK_U32 Active,                 /* Active port */
+SK_U32 PrefPort,               /* Preferred port */
+SK_U32 *pSelect,               /* New active port */
+SK_BOOL        AutoNegDone)    /* Successfully auto-negotiated? */
+{
+       SK_U32          i;
+       SK_BOOL         PortFound;
+
+       PortFound = SK_FALSE;
+
+       /* Select first port that is PortDown. */
+       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
+               if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_DOWN &&
+                       pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
+                       *pSelect = i;
+                       if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_DOWN &&
+                               pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
+                               *pSelect = Active;
+                       }
+                       if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_DOWN &&
+                               pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
+                               *pSelect = PrefPort;
+                       }
+                       PortFound = SK_TRUE;
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                               ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect))
+                       break;
+               }
+       }
+       return (PortFound);
+}      /* SkRlmtSelectDown */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtCheckSwitch - select new active port and switch to it
+ *
+ * Description:
+ *     This routine decides which port should be the active one and queues
+ *     port switching if necessary.
+ *
+ * Context:
+ *     runtime, pageable?
+ *
+ * Returns:
+ *     Nothing.
+ */
+RLMT_STATIC void       SkRlmtCheckSwitch(
+SK_AC  *pAC,   /* Adapter Context */
+SK_IOC IoC,    /* I/O Context */
+SK_U32 NetIdx) /* Net index */
+{
+       SK_EVPARA       Para;
+       SK_U32          Active;
+       SK_U32          PrefPort;
+       SK_U32          i;
+       SK_BOOL         PortFound;
+
+       Active = pAC->Rlmt.Net[NetIdx].ActivePort;      /* Index of active port. */
+       PrefPort = pAC->Rlmt.Net[NetIdx].PrefPort;      /* Index of preferred port. */
+       PortFound = SK_FALSE;
+       pAC->Rlmt.CheckSwitch = SK_FALSE;
+
+#if 0  /* RW 2001/10/18 - active port becomes always prefered one */
+       if (pAC->Rlmt.Net[NetIdx].Preference == 0xFFFFFFFF) { /* Automatic */
+               /* disable auto-fail back */
+               PrefPort = Active;
+       }
+#endif
+
+       if (pAC->Rlmt.Net[NetIdx].LinksUp == 0) {
+               /* Last link went down - shut down the net. */
+               pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_DOWN;
+               Para.Para32[0] = SK_RLMT_NET_DOWN_TEMP;
+               Para.Para32[1] = NetIdx;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para);
+
+               Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
+                       Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
+               Para.Para32[1] = NetIdx;
+               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
+               return;
+       }       /* pAC->Rlmt.LinksUp == 0 */
+       else if (pAC->Rlmt.Net[NetIdx].LinksUp == 1 &&
+               pAC->Rlmt.Net[NetIdx].RlmtState == SK_RLMT_RS_NET_DOWN) {
+               /* First link came up - get the net up. */
+               pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_UP;
+
+               /*
+                * If pAC->Rlmt.ActivePort != Para.Para32[0],
+                * the DRV switches to the port that came up.
+                */
+               for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
+                       if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
+                               if (!pAC->Rlmt.Net[NetIdx].Port[Active]->LinkDown) {
+                                       i = Active;
+                               }
+                               if (!pAC->Rlmt.Net[NetIdx].Port[PrefPort]->LinkDown) {
+                                       i = PrefPort;
+                               }
+                               PortFound = SK_TRUE;
+                               break;
+                       }
+               }
+
+               if (PortFound) {
+                       Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
+                       Para.Para32[1] = NetIdx;
+                       SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
+
+                       pAC->Rlmt.Net[NetIdx].ActivePort = i;
+                       Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
+                       Para.Para32[1] = NetIdx;
+                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para);
+
+                       if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
+                               (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC,
+                               pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber,
+                               SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].
+                               CurrentMacAddress, &SkRlmtMcAddr)) != NULL) {
+                               /*
+                                * Send announce packet to RLMT multicast address to force
+                                * switches to learn the new location of the logical MAC address.
+                                */
+                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
+                       }
+               }
+               else {
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E007, SKERR_RLMT_E007_MSG);
+               }
+
+               return;
+       }       /* LinksUp == 1 && RlmtState == SK_RLMT_RS_NET_DOWN */
+       else {  /* Cannot be reached in dual-net mode. */
+               Para.Para32[0] = Active;
+
+               /*
+                * Preselection:
+                *      If RLMT Mode != CheckLinkState
+                *              select port that received a broadcast frame substantially later
+                *              than all other ports
+                *      else select first port that is not SuspectRx
+                *      else select first port that is PortUp
+                *      else select port that is PortGoingUp for the longest time
+                *      else select first port that is PortDown
+                *      else stop.
+                *
+                * For the preselected port:
+                *      If ActivePort is equal in quality, select ActivePort.
+                *
+                *      If PrefPort is equal in quality, select PrefPort.
+                *
+                *      If ActivePort != SelectedPort,
+                *              If old ActivePort is LinkDown,
+                *                      SwitchHard
+                *              else
+                *                      SwitchSoft
+                */
+               /* check of ChgBcPrio flag added */
+               if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) &&
+                       (!pAC->Rlmt.Net[0].ChgBcPrio)) {
+
+                       if (!PortFound) {
+                               PortFound = SkRlmtSelectBcRx(
+                                       pAC, IoC, Active, PrefPort, &Para.Para32[1]);
+                       }
+
+                       if (!PortFound) {
+                               PortFound = SkRlmtSelectNotSuspect(
+                                       pAC, IoC, Active, PrefPort, &Para.Para32[1]);
+                       }
+               }       /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
+
+               /* with changed priority for last broadcast received */
+               if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) &&
+                       (pAC->Rlmt.Net[0].ChgBcPrio)) {
+                       if (!PortFound) {
+                               PortFound = SkRlmtSelectNotSuspect(
+                                       pAC, IoC, Active, PrefPort, &Para.Para32[1]);
+                       }
+
+                       if (!PortFound) {
+                               PortFound = SkRlmtSelectBcRx(
+                                       pAC, IoC, Active, PrefPort, &Para.Para32[1]);
+                       }
+               }       /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
+
+               if (!PortFound) {
+                       PortFound = SkRlmtSelectUp(
+                               pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
+               }
+
+               if (!PortFound) {
+                       PortFound = SkRlmtSelectUp(
+                               pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
+               }
+
+               if (!PortFound) {
+                       PortFound = SkRlmtSelectGoingUp(
+                               pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
+               }
+
+               if (!PortFound) {
+                       PortFound = SkRlmtSelectGoingUp(
+                               pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
+               }
+
+               if (pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) {
+                       if (!PortFound) {
+                               PortFound = SkRlmtSelectDown(pAC, IoC,
+                                       Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
+                       }
+
+                       if (!PortFound) {
+                               PortFound = SkRlmtSelectDown(pAC, IoC,
+                                       Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
+                       }
+               }       /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
+
+               if (PortFound) {
+
+                       if (Para.Para32[1] != Active) {
+                               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                                       ("Active: %d, Para1: %d.\n", Active, Para.Para32[1]))
+                               pAC->Rlmt.Net[NetIdx].ActivePort = Para.Para32[1];
+                               Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
+                                       Port[Para.Para32[0]]->PortNumber;
+                               Para.Para32[1] = pAC->Rlmt.Net[NetIdx].
+                                       Port[Para.Para32[1]]->PortNumber;
+                               SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[1], SK_LED_ACTIVE);
+                               if (pAC->Rlmt.Port[Active].LinkDown) {
+                                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_HARD, Para);
+                               }
+                               else {
+                                       SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
+                                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_SOFT, Para);
+                               }
+                               Para.Para32[1] = NetIdx;
+                               Para.Para32[0] =
+                                       pAC->Rlmt.Net[NetIdx].Port[Para.Para32[0]]->PortNumber;
+                               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
+                               Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
+                                       Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
+                               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
+                               if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
+                                       (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, Para.Para32[0],
+                                       SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].CurrentMacAddress,
+                                       &SkRlmtMcAddr)) != NULL) {
+                                       /*
+                                        * Send announce packet to RLMT multicast address to force
+                                        * switches to learn the new location of the logical
+                                        * MAC address.
+                                        */
+                                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
+                               }       /* (Para.pParaPtr = SkRlmtBuildPacket(...)) != NULL */
+                       }       /* Para.Para32[1] != Active */
+               }       /* PortFound */
+               else {
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E004, SKERR_RLMT_E004_MSG);
+               }
+       }       /* LinksUp > 1 || LinksUp == 1 && RlmtState != SK_RLMT_RS_NET_DOWN */
+       return;
+}      /* SkRlmtCheckSwitch */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtCheckSeg - Report if segmentation is detected
+ *
+ * Description:
+ *     This routine checks if the ports see different root bridges and reports
+ *     segmentation in such a case.
+ *
+ * Context:
+ *     runtime, pageable?
+ *
+ * Returns:
+ *     Nothing.
+ */
+RLMT_STATIC void       SkRlmtCheckSeg(
+SK_AC  *pAC,   /* Adapter Context */
+SK_IOC IoC,    /* I/O Context */
+SK_U32 NetIdx) /* Net number */
+{
+       SK_EVPARA       Para;
+       SK_RLMT_NET     *pNet;
+       SK_U32          i, j;
+       SK_BOOL         Equal;
+
+       pNet = &pAC->Rlmt.Net[NetIdx];
+       pNet->RootIdSet = SK_FALSE;
+       Equal = SK_TRUE;
+
+       for (i = 0; i < pNet->NumPorts; i++) {
+               if (pNet->Port[i]->LinkDown || !pNet->Port[i]->RootIdSet) {
+                       continue;
+               }
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
+                       ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n", i,
+                               pNet->Port[i]->Root.Id[0], pNet->Port[i]->Root.Id[1],
+                               pNet->Port[i]->Root.Id[2], pNet->Port[i]->Root.Id[3],
+                               pNet->Port[i]->Root.Id[4], pNet->Port[i]->Root.Id[5],
+                               pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7]))
+
+               if (!pNet->RootIdSet) {
+                       pNet->Root = pNet->Port[i]->Root;
+                       pNet->RootIdSet = SK_TRUE;
+                       continue;
+               }
+
+               for (j = 0; j < 8; j ++) {
+                       Equal &= pNet->Port[i]->Root.Id[j] == pNet->Root.Id[j];
+                       if (!Equal) {
+                               break;
+                       }
+               }
+
+               if (!Equal) {
+                       SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E005, SKERR_RLMT_E005_MSG);
+                       Para.Para32[0] = NetIdx;
+                       Para.Para32[1] = (SK_U32)-1;
+                       SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SEGMENTATION, Para);
+
+                       pNet->CheckingState &= ~SK_RLMT_RCS_REPORT_SEG;
+
+                       /* 2000-03-06 RA: New. */
+                       Para.Para32[0] = NetIdx;
+                       Para.Para32[1] = (SK_U32)-1;
+                       SkTimerStart(pAC, IoC, &pNet->SegTimer, SK_RLMT_SEG_TO_VAL,
+                               SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
+                       break;
+               }
+       }       /* for (i = 0; i < pNet->NumPorts; i++) */
+
+       /* 2000-03-06 RA: Moved here. */
+       /* Segmentation check not running anymore. */
+       pNet->CheckingState &= ~SK_RLMT_RCS_SEG;
+
+}      /* SkRlmtCheckSeg */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtPortStart - initialize port variables and start port
+ *
+ * Description:
+ *     This routine initializes a port's variables and issues a PORT_START
+ *     to the HWAC module.  This handles retries if the start fails or the
+ *     link eventually goes down.
+ *
+ * Context:
+ *     runtime, pageable?
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtPortStart(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* I/O Context */
+SK_U32 PortNumber)     /* Port number */
+{
+       SK_EVPARA       Para;
+
+       pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_LINK_DOWN;
+       pAC->Rlmt.Port[PortNumber].PortStarted = SK_TRUE;
+       pAC->Rlmt.Port[PortNumber].LinkDown = SK_TRUE;
+       pAC->Rlmt.Port[PortNumber].PortDown = SK_TRUE;
+       pAC->Rlmt.Port[PortNumber].CheckingState = 0;
+       pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
+       Para.Para32[0] = PortNumber;
+       Para.Para32[1] = (SK_U32)-1;
+       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
+}      /* SkRlmtPortStart */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtEvtPortStartTim - PORT_START_TIM
+ *
+ * Description:
+ *     This routine handles PORT_START_TIM events.
+ *
+ * Context:
+ *     runtime, pageable?
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtEvtPortStartTim(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 -1 */
+{
+       SK_U32                  i;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0]))
+
+               if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad Parameter.\n"))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n"))
+               return;
+       }
+
+       /*
+        * Used to start non-preferred ports if the preferred one
+        * does not come up.
+        * This timeout needs only be set when starting the first
+        * (preferred) port.
+        */
+       if (pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
+               /* PORT_START failed. */
+               for (i = 0; i < pAC->Rlmt.Port[Para.Para32[0]].Net->NumPorts; i++) {
+                       if (!pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortStarted) {
+                               SkRlmtPortStart(pAC, IoC,
+                                       pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortNumber);
+                       }
+               }
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n"))
+}      /* SkRlmtEvtPortStartTim */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtEvtLinkUp - LINK_UP
+ *
+ * Description:
+ *     This routine handles LLINK_UP events.
+ *
+ * Context:
+ *     runtime, pageable?
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtEvtLinkUp(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 Undefined */
+{
+       SK_U32                  i;
+       SK_RLMT_PORT    *pRPort;
+       SK_EVPARA               Para2;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0]))
+
+       pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
+       if (!pRPort->PortStarted) {
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E008, SKERR_RLMT_E008_MSG);
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                               ("SK_RLMT_LINK_UP Event EMPTY.\n"))
+               return;
+       }
+
+       if (!pRPort->LinkDown) {
+               /* RA;:;: Any better solution? */
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_LINK_UP Event EMPTY.\n"))
+               return;
+       }
+
+       SkTimerStop(pAC, IoC, &pRPort->UpTimer);
+       SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
+       SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
+
+       /* Do something if timer already fired? */
+
+       pRPort->LinkDown = SK_FALSE;
+       pRPort->PortState = SK_RLMT_PS_GOING_UP;
+       pRPort->GuTimeStamp = SkOsGetTime(pAC);
+       pRPort->BcTimeStamp = 0;
+       pRPort->Net->LinksUp++;
+       if (pRPort->Net->LinksUp == 1) {
+               SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_ACTIVE);
+       }
+       else {
+               SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
+       }
+
+       for (i = 0; i < pRPort->Net->NumPorts; i++) {
+               if (!pRPort->Net->Port[i]->PortStarted) {
+                       SkRlmtPortStart(pAC, IoC, pRPort->Net->Port[i]->PortNumber);
+               }
+       }
+
+       SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
+
+       if (pRPort->Net->LinksUp >= 2) {
+               if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
+                       /* Build the check chain. */
+                       SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
+               }
+       }
+
+       /* If the first link comes up, start the periodical RLMT timeout. */
+       if (pRPort->Net->NumPorts > 1 && pRPort->Net->LinksUp == 1 &&
+               (pRPort->Net->RlmtMode & SK_RLMT_CHECK_OTHERS) != 0) {
+               Para2.Para32[0] = pRPort->Net->NetNumber;
+               Para2.Para32[1] = (SK_U32)-1;
+               SkTimerStart(pAC, IoC, &pRPort->Net->LocTimer,
+                       pRPort->Net->TimeoutValue, SKGE_RLMT, SK_RLMT_TIM, Para2);
+       }
+
+       Para2 = Para;
+       Para2.Para32[1] = (SK_U32)-1;
+       SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
+               SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para2);
+
+       /* Later: if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) && */
+       if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
+               (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 &&
+               (Para2.pParaPtr =
+                       SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE,
+                       &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr)
+               ) != NULL) {
+               /* Send "new" packet to RLMT multicast address. */
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
+       }
+
+       if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_SEG) {
+               if ((Para2.pParaPtr =
+                       SkRlmtBuildSpanningTreePacket(pAC, IoC, Para.Para32[0])) != NULL) {
+                       pAC->Rlmt.Port[Para.Para32[0]].RootIdSet = SK_FALSE;
+                       pRPort->Net->CheckingState |=
+                               SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
+
+                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
+
+                       Para.Para32[1] = (SK_U32)-1;
+                       SkTimerStart(pAC, IoC, &pRPort->Net->SegTimer,
+                               SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
+               }
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_LINK_UP Event END.\n"))
+}      /* SkRlmtEvtLinkUp */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtEvtPortUpTim - PORT_UP_TIM
+ *
+ * Description:
+ *     This routine handles PORT_UP_TIM events.
+ *
+ * Context:
+ *     runtime, pageable?
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtEvtPortUpTim(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 -1 */
+{
+       SK_RLMT_PORT    *pRPort;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0]))
+
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad Parameter.\n"))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_PORTUP_TIM Event EMPTY.\n"))
+               return;
+       }
+
+       pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
+       if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0]))
+               return;
+       }
+
+       pRPort->PortDown = SK_FALSE;
+       pRPort->PortState = SK_RLMT_PS_UP;
+       pRPort->Net->PortsUp++;
+       if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
+               if (pAC->Rlmt.NumNets <= 1) {
+                       SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
+               }
+               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_UP, Para);
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_PORTUP_TIM Event END.\n"))
+}      /* SkRlmtEvtPortUpTim */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtEvtPortDownTim - PORT_DOWN_*
+ *
+ * Description:
+ *     This routine handles PORT_DOWN_* events.
+ *
+ * Context:
+ *     runtime, pageable?
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtEvtPortDownX(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_U32         Event,  /* Event code */
+SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 -1 */
+{
+       SK_RLMT_PORT    *pRPort;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n",
+                       Para.Para32[0], Event))
+
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad Parameter.\n"))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_PORTDOWN* Event EMPTY.\n"))
+               return;
+       }
+
+       pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
+       if (!pRPort->PortStarted || (Event == SK_RLMT_PORTDOWN_TX_TIM &&
+               !(pRPort->CheckingState & SK_RLMT_PCS_TX))) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event))
+               return;
+       }
+
+       /* Stop port's timers. */
+       SkTimerStop(pAC, IoC, &pRPort->UpTimer);
+       SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
+       SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
+
+       if (pRPort->PortState != SK_RLMT_PS_LINK_DOWN) {
+               pRPort->PortState = SK_RLMT_PS_DOWN;
+       }
+
+       if (!pRPort->PortDown) {
+               pRPort->Net->PortsUp--;
+               pRPort->PortDown = SK_TRUE;
+               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_DOWN, Para);
+       }
+
+       pRPort->PacketsPerTimeSlot = 0;
+       /* pRPort->DataPacketsPerTimeSlot = 0; */
+       pRPort->BpduPacketsPerTimeSlot = 0;
+       pRPort->BcTimeStamp = 0;
+
+       /*
+        * RA;:;: To be checked:
+        * - actions at RLMT_STOP: We should not switch anymore.
+        */
+       if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
+               if (Para.Para32[0] ==
+                       pRPort->Net->Port[pRPort->Net->ActivePort]->PortNumber) {
+                       /* Active Port went down. */
+                       SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
+               }
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event))
+}      /* SkRlmtEvtPortDownX */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtEvtLinkDown - LINK_DOWN
+ *
+ * Description:
+ *     This routine handles LINK_DOWN events.
+ *
+ * Context:
+ *     runtime, pageable?
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtEvtLinkDown(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 Undefined */
+{
+       SK_RLMT_PORT    *pRPort;
+
+       pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0]))
+
+       if (!pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
+               pRPort->Net->LinksUp--;
+               pRPort->LinkDown = SK_TRUE;
+               pRPort->PortState = SK_RLMT_PS_LINK_DOWN;
+               SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_OFF);
+
+               if ((pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) != 0) {
+                       /* Build the check chain. */
+                       SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
+               }
+
+               /* Ensure that port is marked down. */
+               Para.Para32[1] = -1;
+               (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PORTDOWN, Para);
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_LINK_DOWN Event END.\n"))
+}      /* SkRlmtEvtLinkDown */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtEvtPortAddr - PORT_ADDR
+ *
+ * Description:
+ *     This routine handles PORT_ADDR events.
+ *
+ * Context:
+ *     runtime, pageable?
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtEvtPortAddr(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 -1 */
+{
+       SK_U32                  i, j;
+       SK_RLMT_PORT    *pRPort;
+       SK_MAC_ADDR             *pOldMacAddr;
+       SK_MAC_ADDR             *pNewMacAddr;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0]))
+
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad Parameter.\n"))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_PORT_ADDR Event EMPTY.\n"))
+               return;
+       }
+
+       /* Port's physical MAC address changed. */
+       pOldMacAddr = &pAC->Addr.Port[Para.Para32[0]].PreviousMacAddress;
+       pNewMacAddr = &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress;
+
+       /*
+        * NOTE: This is not scalable for solutions where ports are
+        *       checked remotely.  There, we need to send an RLMT
+        *       address change packet - and how do we ensure delivery?
+        */
+       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
+               pRPort = &pAC->Rlmt.Port[i];
+               for (j = 0; j < pRPort->PortsChecked; j++) {
+                       if (SK_ADDR_EQUAL(
+                               pRPort->PortCheck[j].CheckAddr.a, pOldMacAddr->a)) {
+                               pRPort->PortCheck[j].CheckAddr = *pNewMacAddr;
+                       }
+               }
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_PORT_ADDR Event END.\n"))
+}      /* SkRlmtEvtPortAddr */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtEvtStart - START
+ *
+ * Description:
+ *     This routine handles START events.
+ *
+ * Context:
+ *     runtime, pageable?
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtEvtStart(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
+{
+       SK_EVPARA       Para2;
+       SK_U32          PortIdx;
+       SK_U32          PortNumber;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0]))
+
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad Parameter.\n"))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_START Event EMPTY.\n"))
+               return;
+       }
+
+       if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad NetNumber %d.\n", Para.Para32[0]))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_START Event EMPTY.\n"))
+               return;
+       }
+
+       if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState != SK_RLMT_RS_INIT) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_START Event EMPTY.\n"))
+               return;
+       }
+
+       if (pAC->Rlmt.NetsStarted >= pAC->Rlmt.NumNets) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("All nets should have been started.\n"))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_START Event EMPTY.\n"))
+               return;
+       }
+
+       if (pAC->Rlmt.Net[Para.Para32[0]].PrefPort >=
+               pAC->Rlmt.Net[Para.Para32[0]].NumPorts) {
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E009, SKERR_RLMT_E009_MSG);
+
+               /* Change PrefPort to internal default. */
+               Para2.Para32[0] = 0xFFFFFFFF;
+               Para2.Para32[1] = Para.Para32[0];
+               (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE, Para2);
+       }
+
+       PortIdx = pAC->Rlmt.Net[Para.Para32[0]].PrefPort;
+       PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[PortIdx]->PortNumber;
+
+       pAC->Rlmt.Net[Para.Para32[0]].LinksUp = 0;
+       pAC->Rlmt.Net[Para.Para32[0]].PortsUp = 0;
+       pAC->Rlmt.Net[Para.Para32[0]].CheckingState = 0;
+       pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_NET_DOWN;
+
+       /* Start preferred port. */
+       SkRlmtPortStart(pAC, IoC, PortNumber);
+
+       /* Start Timer (for first port only). */
+       Para2.Para32[0] = PortNumber;
+       Para2.Para32[1] = (SK_U32)-1;
+       SkTimerStart(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer,
+               SK_RLMT_PORTSTART_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTSTART_TIM, Para2);
+
+       pAC->Rlmt.NetsStarted++;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_START Event END.\n"))
+}      /* SkRlmtEvtStart */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtEvtStop - STOP
+ *
+ * Description:
+ *     This routine handles STOP events.
+ *
+ * Context:
+ *     runtime, pageable?
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtEvtStop(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
+{
+       SK_EVPARA       Para2;
+       SK_U32          PortNumber;
+       SK_U32          i;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0]))
+
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad Parameter.\n"))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_STOP Event EMPTY.\n"))
+               return;
+       }
+
+       if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad NetNumber %d.\n", Para.Para32[0]))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_STOP Event EMPTY.\n"))
+               return;
+       }
+
+       if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState == SK_RLMT_RS_INIT) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_STOP Event EMPTY.\n"))
+               return;
+       }
+
+       if (pAC->Rlmt.NetsStarted == 0) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("All nets are stopped.\n"))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_STOP Event EMPTY.\n"))
+               return;
+       }
+
+       /* Stop RLMT timers. */
+       SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer);
+       SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer);
+
+       /* Stop net. */
+       pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_INIT;
+       pAC->Rlmt.Net[Para.Para32[0]].RootIdSet = SK_FALSE;
+       Para2.Para32[0] = SK_RLMT_NET_DOWN_FINAL;
+       Para2.Para32[1] = Para.Para32[0];                       /* Net# */
+       SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para2);
+
+       /* Stop ports. */
+       for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
+               PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
+               if (pAC->Rlmt.Port[PortNumber].PortState != SK_RLMT_PS_INIT) {
+                       SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer);
+                       SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownRxTimer);
+                       SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownTxTimer);
+
+                       pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_INIT;
+                       pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
+                       pAC->Rlmt.Port[PortNumber].PortStarted = SK_FALSE;
+                       Para2.Para32[0] = PortNumber;
+                       Para2.Para32[1] = (SK_U32)-1;
+                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para2);
+               }
+       }
+
+       pAC->Rlmt.NetsStarted--;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_STOP Event END.\n"))
+}      /* SkRlmtEvtStop */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtEvtTim - TIM
+ *
+ * Description:
+ *     This routine handles TIM events.
+ *
+ * Context:
+ *     runtime, pageable?
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtEvtTim(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
+{
+       SK_RLMT_PORT    *pRPort;
+       SK_U32                  Timeout;
+       SK_U32                  NewTimeout;
+       SK_U32                  PortNumber;
+       SK_U32                  i;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_TIM Event BEGIN.\n"))
+
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad Parameter.\n"))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_TIM Event EMPTY.\n"))
+               return;
+       }
+
+       if ((pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_OTHERS) == 0 ||
+               pAC->Rlmt.Net[Para.Para32[0]].LinksUp == 0) {
+               /* Mode changed or all links down: No more link checking. */
+               return;
+       }
+
+#if 0
+       pAC->Rlmt.SwitchCheckCounter--;
+       if (pAC->Rlmt.SwitchCheckCounter == 0) {
+               pAC->Rlmt.SwitchCheckCounter;
+       }
+#endif /* 0 */
+
+       NewTimeout = SK_RLMT_DEF_TO_VAL;
+       for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
+               PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
+               pRPort = &pAC->Rlmt.Port[PortNumber];
+               if (!pRPort->LinkDown) {
+                       Timeout = SkRlmtCheckPort(pAC, IoC, PortNumber);
+                       if (Timeout < NewTimeout) {
+                               NewTimeout = Timeout;
+                       }
+
+                       /*
+                        * These counters should be set to 0 for all ports before the
+                        * first frame is sent in the next loop.
+                        */
+                       pRPort->PacketsPerTimeSlot = 0;
+                       /* pRPort->DataPacketsPerTimeSlot = 0; */
+                       pRPort->BpduPacketsPerTimeSlot = 0;
+               }
+       }
+       pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue = NewTimeout;
+
+       if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1) {
+               /*
+                * If checking remote ports, also send packets if
+                *   (LinksUp == 1) &&
+                *   this port checks at least one (remote) port.
+                */
+
+               /*
+                * Must be new loop, as SkRlmtCheckPort can request to
+                * check segmentation when e.g. checking the last port.
+                */
+               for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
+                       if (!pAC->Rlmt.Net[Para.Para32[0]].Port[i]->LinkDown) {
+                               SkRlmtSend(pAC, IoC,
+                                       pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber);
+                       }
+               }
+       }
+
+       SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer,
+               pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue, SKGE_RLMT, SK_RLMT_TIM,
+               Para);
+
+       if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1 &&
+               (pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_SEG) &&
+               (pAC->Rlmt.Net[Para.Para32[0]].CheckingState & SK_RLMT_RCS_START_SEG)) {
+               SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer,
+                       SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
+               pAC->Rlmt.Net[Para.Para32[0]].CheckingState &= ~SK_RLMT_RCS_START_SEG;
+               pAC->Rlmt.Net[Para.Para32[0]].CheckingState |=
+                       SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_TIM Event END.\n"))
+}      /* SkRlmtEvtTim */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtEvtSegTim - SEG_TIM
+ *
+ * Description:
+ *     This routine handles SEG_TIM events.
+ *
+ * Context:
+ *     runtime, pageable?
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtEvtSegTim(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
+{
+#ifdef xDEBUG
+       int j;
+#endif /* DEBUG */
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_SEG_TIM Event BEGIN.\n"))
+
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad Parameter.\n"))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_SEG_TIM Event EMPTY.\n"))
+               return;
+       }
+
+#ifdef xDEBUG
+       for (j = 0; j < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; j++) {
+               SK_ADDR_PORT    *pAPort;
+               SK_U32                  k;
+               SK_U16                  *InAddr;
+               SK_U8                   InAddr8[6];
+
+               InAddr = (SK_U16 *)&InAddr8[0];
+               pAPort = pAC->Rlmt.Net[Para.Para32[0]].Port[j]->AddrPort;
+               for (k = 0; k < pAPort->NextExactMatchRlmt; k++) {
+                       /* Get exact match address k from port j. */
+                       XM_INADDR(IoC, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
+                               XM_EXM(k), InAddr);
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                               ("MC address %d on Port %u: %02x %02x %02x %02x %02x %02x --  %02x %02x %02x %02x %02x %02x.\n",
+                                       k, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
+                                       InAddr8[0], InAddr8[1], InAddr8[2],
+                                       InAddr8[3], InAddr8[4], InAddr8[5],
+                                       pAPort->Exact[k].a[0], pAPort->Exact[k].a[1],
+                                       pAPort->Exact[k].a[2], pAPort->Exact[k].a[3],
+                                       pAPort->Exact[k].a[4], pAPort->Exact[k].a[5]))
+               }
+       }
+#endif /* xDEBUG */
+
+       SkRlmtCheckSeg(pAC, IoC, Para.Para32[0]);
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_SEG_TIM Event END.\n"))
+}      /* SkRlmtEvtSegTim */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtEvtPacketRx - PACKET_RECEIVED
+ *
+ * Description:
+ *     This routine handles PACKET_RECEIVED events.
+ *
+ * Context:
+ *     runtime, pageable?
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtEvtPacketRx(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_EVPARA      Para)   /* SK_MBUF *pMb */
+{
+       SK_MBUF *pMb;
+       SK_MBUF *pNextMb;
+       SK_U32  NetNumber;
+
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n"))
+
+       /* Should we ignore frames during port switching? */
+
+#ifdef DEBUG
+       pMb = Para.pParaPtr;
+       if (pMb == NULL) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n"))
+       }
+       else if (pMb->pNext != NULL) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("More than one mbuf or pMb->pNext not set.\n"))
+       }
+#endif /* DEBUG */
+
+       for (pMb = Para.pParaPtr; pMb != NULL; pMb = pNextMb) {
+               pNextMb = pMb->pNext;
+               pMb->pNext = NULL;
+
+               NetNumber = pAC->Rlmt.Port[pMb->PortIdx].Net->NetNumber;
+               if (pAC->Rlmt.Net[NetNumber].RlmtState == SK_RLMT_RS_INIT) {
+                       SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
+               }
+               else {
+                       SkRlmtPacketReceive(pAC, IoC, pMb);
+               }
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_PACKET_RECEIVED Event END.\n"))
+}      /* SkRlmtEvtPacketRx */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtEvtStatsClear - STATS_CLEAR
+ *
+ * Description:
+ *     This routine handles STATS_CLEAR events.
+ *
+ * Context:
+ *     runtime, pageable?
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtEvtStatsClear(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
+{
+       SK_U32                  i;
+       SK_RLMT_PORT    *pRPort;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_STATS_CLEAR Event BEGIN.\n"))
+
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad Parameter.\n"))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
+               return;
+       }
+
+       if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad NetNumber %d.\n", Para.Para32[0]))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
+               return;
+       }
+
+       /* Clear statistics for logical and physical ports. */
+       for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
+               pRPort =
+                       &pAC->Rlmt.Port[pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber];
+               pRPort->TxHelloCts = 0;
+               pRPort->RxHelloCts = 0;
+               pRPort->TxSpHelloReqCts = 0;
+               pRPort->RxSpHelloCts = 0;
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_STATS_CLEAR Event END.\n"))
+}      /* SkRlmtEvtStatsClear */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtEvtStatsUpdate - STATS_UPDATE
+ *
+ * Description:
+ *     This routine handles STATS_UPDATE events.
+ *
+ * Context:
+ *     runtime, pageable?
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtEvtStatsUpdate(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
+{
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_STATS_UPDATE Event BEGIN.\n"))
+
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad Parameter.\n"))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
+               return;
+       }
+
+       if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad NetNumber %d.\n", Para.Para32[0]))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
+               return;
+       }
+
+       /* Update statistics - currently always up-to-date. */
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_STATS_UPDATE Event END.\n"))
+}      /* SkRlmtEvtStatsUpdate */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtEvtPrefportChange - PREFPORT_CHANGE
+ *
+ * Description:
+ *     This routine handles PREFPORT_CHANGE events.
+ *
+ * Context:
+ *     runtime, pageable?
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtEvtPrefportChange(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_EVPARA      Para)   /* SK_U32 PortIndex; SK_U32 NetNumber */
+{
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0]))
+
+       if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad NetNumber %d.\n", Para.Para32[1]))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
+               return;
+       }
+
+       /* 0xFFFFFFFF == auto-mode. */
+       if (Para.Para32[0] == 0xFFFFFFFF) {
+               pAC->Rlmt.Net[Para.Para32[1]].PrefPort = SK_RLMT_DEF_PREF_PORT;
+       }
+       else {
+               if (Para.Para32[0] >= pAC->Rlmt.Net[Para.Para32[1]].NumPorts) {
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E010, SKERR_RLMT_E010_MSG);
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                               ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
+                       return;
+               }
+
+               pAC->Rlmt.Net[Para.Para32[1]].PrefPort = Para.Para32[0];
+       }
+
+       pAC->Rlmt.Net[Para.Para32[1]].Preference = Para.Para32[0];
+
+       if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
+               SkRlmtCheckSwitch(pAC, IoC, Para.Para32[1]);
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_PREFPORT_CHANGE Event END.\n"))
+}      /* SkRlmtEvtPrefportChange */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtEvtSetNets - SET_NETS
+ *
+ * Description:
+ *     This routine handles SET_NETS events.
+ *
+ * Context:
+ *     runtime, pageable?
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtEvtSetNets(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_EVPARA      Para)   /* SK_U32 NumNets; SK_U32 -1 */
+{
+       int i;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_SET_NETS Event BEGIN.\n"))
+
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad Parameter.\n"))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_SET_NETS Event EMPTY.\n"))
+               return;
+       }
+
+       if (Para.Para32[0] == 0 || Para.Para32[0] > SK_MAX_NETS ||
+               Para.Para32[0] > (SK_U32)pAC->GIni.GIMacsFound) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad number of nets: %d.\n", Para.Para32[0]))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_SET_NETS Event EMPTY.\n"))
+               return;
+       }
+
+       if (Para.Para32[0] == pAC->Rlmt.NumNets) {      /* No change. */
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_SET_NETS Event EMPTY.\n"))
+               return;
+       }
+
+       /* Entering and leaving dual mode only allowed while nets are stopped. */
+       if (pAC->Rlmt.NetsStarted > 0) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Changing dual mode only allowed while all nets are stopped.\n"))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_SET_NETS Event EMPTY.\n"))
+               return;
+       }
+
+       if (Para.Para32[0] == 1) {
+               if (pAC->Rlmt.NumNets > 1) {
+                       /* Clear logical MAC addr from second net's active port. */
+                       (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
+                               Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_CLEAR_LOGICAL);
+                       pAC->Rlmt.Net[1].NumPorts = 0;
+               }
+
+               pAC->Rlmt.NumNets = Para.Para32[0];
+               for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
+                       pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
+                       pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
+                       pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF;         /* "Automatic" */
+                       pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
+                       /* Just assuming. */
+                       pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
+                       pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
+                       pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
+                       pAC->Rlmt.Net[i].NetNumber = i;
+               }
+
+               pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[0];
+               pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
+
+               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("RLMT: Changed to one net with two ports.\n"))
+       }
+       else if (Para.Para32[0] == 2) {
+               pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[1];
+               pAC->Rlmt.Net[1].NumPorts = pAC->GIni.GIMacsFound - 1;
+               pAC->Rlmt.Net[0].NumPorts =
+                       pAC->GIni.GIMacsFound - pAC->Rlmt.Net[1].NumPorts;
+
+               pAC->Rlmt.NumNets = Para.Para32[0];
+               for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
+                       pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
+                       pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
+                       pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF;         /* "Automatic" */
+                       pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
+                       /* Just assuming. */
+                       pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
+                       pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
+                       pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
+
+                       pAC->Rlmt.Net[i].NetNumber = i;
+               }
+
+               /* Set logical MAC addr on second net's active port. */
+               (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
+                       Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_SET_LOGICAL);
+
+               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("RLMT: Changed to two nets with one port each.\n"))
+       }
+       else {
+               /* Not implemented for more than two nets. */
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SetNets not implemented for more than two nets.\n"))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_SET_NETS Event EMPTY.\n"))
+               return;
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_SET_NETS Event END.\n"))
+}      /* SkRlmtSetNets */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtEvtModeChange - MODE_CHANGE
+ *
+ * Description:
+ *     This routine handles MODE_CHANGE events.
+ *
+ * Context:
+ *     runtime, pageable?
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     Nothing
+ */
+RLMT_STATIC void       SkRlmtEvtModeChange(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_EVPARA      Para)   /* SK_U32 NewMode; SK_U32 NetNumber */
+{
+       SK_EVPARA       Para2;
+       SK_U32          i;
+       SK_U32          PrevRlmtMode;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_MODE_CHANGE Event BEGIN.\n"))
+
+       if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Bad NetNumber %d.\n", Para.Para32[1]))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
+               return;
+       }
+
+       Para.Para32[0] |= SK_RLMT_CHECK_LINK;
+
+       if ((pAC->Rlmt.Net[Para.Para32[1]].NumPorts == 1) &&
+               Para.Para32[0] != SK_RLMT_MODE_CLS) {
+               pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = SK_RLMT_MODE_CLS;
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Forced RLMT mode to CLS on single port net.\n"))
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
+               return;
+       }
+
+       /* Update RLMT mode. */
+       PrevRlmtMode = pAC->Rlmt.Net[Para.Para32[1]].RlmtMode;
+       pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = Para.Para32[0];
+
+       if ((PrevRlmtMode & SK_RLMT_CHECK_LOC_LINK) !=
+               (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
+               /* SK_RLMT_CHECK_LOC_LINK bit changed. */
+               if ((PrevRlmtMode & SK_RLMT_CHECK_OTHERS) == 0 &&
+                       pAC->Rlmt.Net[Para.Para32[1]].NumPorts > 1 &&
+                       pAC->Rlmt.Net[Para.Para32[1]].PortsUp >= 1) {
+                       /* 20001207 RA: Was "PortsUp == 1". */
+                       Para2.Para32[0] = Para.Para32[1];
+                       Para2.Para32[1] = (SK_U32)-1;
+                       SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].LocTimer,
+                               pAC->Rlmt.Net[Para.Para32[1]].TimeoutValue,
+                               SKGE_RLMT, SK_RLMT_TIM, Para2);
+               }
+       }
+
+       if ((PrevRlmtMode & SK_RLMT_CHECK_SEG) !=
+               (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG)) {
+               /* SK_RLMT_CHECK_SEG bit changed. */
+               for (i = 0; i < pAC->Rlmt.Net[Para.Para32[1]].NumPorts; i++) {
+                       (void)SkAddrMcClear(pAC, IoC,
+                               pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
+                               SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
+
+                       /* Add RLMT MC address. */
+                       (void)SkAddrMcAdd(pAC, IoC,
+                               pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
+                               &SkRlmtMcAddr, SK_ADDR_PERMANENT);
+
+                       if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode &
+                               SK_RLMT_CHECK_SEG) != 0) {
+                               /* Add BPDU MC address. */
+                               (void)SkAddrMcAdd(pAC, IoC,
+                                       pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
+                                       &BridgeMcAddr, SK_ADDR_PERMANENT);
+
+                               if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
+                                       if (!pAC->Rlmt.Net[Para.Para32[1]].Port[i]->LinkDown &&
+                                               (Para2.pParaPtr = SkRlmtBuildSpanningTreePacket(
+                                               pAC, IoC, i)) != NULL) {
+                                               pAC->Rlmt.Net[Para.Para32[1]].Port[i]->RootIdSet =
+                                                       SK_FALSE;
+                                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
+                                       }
+                               }
+                       }
+                       (void)SkAddrMcUpdate(pAC, IoC,
+                               pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber);
+               }       /* for ... */
+
+               if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG) != 0) {
+                       Para2.Para32[0] = Para.Para32[1];
+                       Para2.Para32[1] = (SK_U32)-1;
+                       SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].SegTimer,
+                               SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para2);
+               }
+       }       /* SK_RLMT_CHECK_SEG bit changed. */
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SK_RLMT_MODE_CHANGE Event END.\n"))
+}      /* SkRlmtEvtModeChange */
+
+
+/******************************************************************************
+ *
+ *     SkRlmtEvent - a PORT- or an RLMT-specific event happened
+ *
+ * Description:
+ *     This routine calls subroutines to handle PORT- and RLMT-specific events.
+ *
+ * Context:
+ *     runtime, pageable?
+ *     may be called after SK_INIT_IO
+ *
+ * Returns:
+ *     0
+ */
+int    SkRlmtEvent(
+SK_AC          *pAC,   /* Adapter Context */
+SK_IOC         IoC,    /* I/O Context */
+SK_U32         Event,  /* Event code */
+SK_EVPARA      Para)   /* Event-specific parameter */
+{
+       switch (Event) {
+
+       /* ----- PORT events ----- */
+
+       case SK_RLMT_PORTSTART_TIM:     /* From RLMT via TIME. */
+               SkRlmtEvtPortStartTim(pAC, IoC, Para);
+               break;
+       case SK_RLMT_LINK_UP:           /* From SIRQ. */
+               SkRlmtEvtLinkUp(pAC, IoC, Para);
+               break;
+       case SK_RLMT_PORTUP_TIM:        /* From RLMT via TIME. */
+               SkRlmtEvtPortUpTim(pAC, IoC, Para);
+               break;
+       case SK_RLMT_PORTDOWN:                  /* From RLMT. */
+       case SK_RLMT_PORTDOWN_RX_TIM:   /* From RLMT via TIME. */
+       case SK_RLMT_PORTDOWN_TX_TIM:   /* From RLMT via TIME. */
+               SkRlmtEvtPortDownX(pAC, IoC, Event, Para);
+               break;
+       case SK_RLMT_LINK_DOWN:         /* From SIRQ. */
+               SkRlmtEvtLinkDown(pAC, IoC, Para);
+               break;
+       case SK_RLMT_PORT_ADDR:         /* From ADDR. */
+               SkRlmtEvtPortAddr(pAC, IoC, Para);
+               break;
+
+       /* ----- RLMT events ----- */
+
+       case SK_RLMT_START:             /* From DRV. */
+               SkRlmtEvtStart(pAC, IoC, Para);
+               break;
+       case SK_RLMT_STOP:              /* From DRV. */
+               SkRlmtEvtStop(pAC, IoC, Para);
+               break;
+       case SK_RLMT_TIM:               /* From RLMT via TIME. */
+               SkRlmtEvtTim(pAC, IoC, Para);
+               break;
+       case SK_RLMT_SEG_TIM:
+               SkRlmtEvtSegTim(pAC, IoC, Para);
+               break;
+       case SK_RLMT_PACKET_RECEIVED:   /* From DRV. */
+               SkRlmtEvtPacketRx(pAC, IoC, Para);
+               break;
+       case SK_RLMT_STATS_CLEAR:       /* From PNMI. */
+               SkRlmtEvtStatsClear(pAC, IoC, Para);
+               break;
+       case SK_RLMT_STATS_UPDATE:      /* From PNMI. */
+               SkRlmtEvtStatsUpdate(pAC, IoC, Para);
+               break;
+       case SK_RLMT_PREFPORT_CHANGE:   /* From PNMI. */
+               SkRlmtEvtPrefportChange(pAC, IoC, Para);
+               break;
+       case SK_RLMT_MODE_CHANGE:       /* From PNMI. */
+               SkRlmtEvtModeChange(pAC, IoC, Para);
+               break;
+       case SK_RLMT_SET_NETS:  /* From DRV. */
+               SkRlmtEvtSetNets(pAC, IoC, Para);
+               break;
+
+       /* ----- Unknown events ----- */
+
+       default:        /* Create error log entry. */
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Unknown RLMT Event %d.\n", Event))
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E003, SKERR_RLMT_E003_MSG);
+               break;
+       }       /* switch() */
+
+       return (0);
+}      /* SkRlmtEvent */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* CONFIG_SK98 */
diff --git a/drivers/net/sk98lin/sktimer.c b/drivers/net/sk98lin/sktimer.c
new file mode 100644 (file)
index 0000000..37cd4c9
--- /dev/null
@@ -0,0 +1,297 @@
+/******************************************************************************
+ *
+ * Name:       sktimer.c
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.12 $
+ * Date:       $Date: 1999/11/22 13:38:51 $
+ * Purpose:    High level timer functions.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998,1999 SysKonnect,
+ *     a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: sktimer.c,v $
+ *     Revision 1.12  1999/11/22 13:38:51  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.11  1998/12/17 13:24:13  gklug
+ *     fix: restart problem: do NOT destroy timer queue if init 1 is done
+ *
+ *     Revision 1.10  1998/10/15 15:11:36  gklug
+ *     fix: ID_sccs to SysKonnectFileId
+ *
+ *     Revision 1.9  1998/09/15 15:15:04  cgoos
+ *     Changed TRUE/FALSE to SK_TRUE/SK_FALSE
+ *
+ *     Revision 1.8  1998/09/08 08:47:55  gklug
+ *     add: init level handling
+ *
+ *     Revision 1.7  1998/08/19 09:50:53  gklug
+ *     fix: remove struct keyword from c-code (see CCC) add typedefs
+ *
+ *     Revision 1.6  1998/08/17 13:43:13  gklug
+ *     chg: Parameter will be union of 64bit para, 2 times SK_U32 or SK_PTR
+ *
+ *     Revision 1.5  1998/08/14 07:09:14  gklug
+ *     fix: chg pAc -> pAC
+ *
+ *     Revision 1.4  1998/08/07 12:53:46  gklug
+ *     fix: first compiled version
+ *
+ *     Revision 1.3  1998/08/07 09:31:53  gklug
+ *     fix: delta spelling
+ *
+ *     Revision 1.2  1998/08/07 09:31:02  gklug
+ *     adapt functions to new c coding conventions
+ *     rmv: "fast" handling
+ *     chg: inserting of new timer in queue.
+ *     chg: event queue generation when timer runs out
+ *
+ *     Revision 1.1  1998/08/05 11:27:55  gklug
+ *     first version: adapted from SMT
+ *
+ *
+ *
+ *
+ ******************************************************************************/
+
+
+#include <config.h>
+
+#ifdef CONFIG_SK98
+
+/*
+       Event queue and dispatcher
+*/
+static const char SysKonnectFileId[] =
+       "$Header: /usr56/projects/ge/schedule/sktimer.c,v 1.12 1999/11/22 13:38:51 cgoos Exp $" ;
+
+#include "h/skdrv1st.h"                /* Driver Specific Definitions */
+#include "h/skdrv2nd.h"                /* Adapter Control- and Driver specific Def. */
+
+#ifdef __C2MAN__
+/*
+       Event queue management.
+
+       General Description:
+
+ */
+intro()
+{}
+#endif
+
+
+/* Forward declaration */
+static void timer_done(SK_AC *pAC,SK_IOC Ioc,int Restart);
+
+
+/*
+ * Inits the software timer
+ *
+ * needs to be called during Init level 1.
+ */
+void   SkTimerInit(
+SK_AC  *pAC,           /* Adapters context */
+SK_IOC Ioc,            /* IoContext */
+int    Level)          /* Init Level */
+{
+       switch (Level) {
+       case SK_INIT_DATA:
+               pAC->Tim.StQueue = 0 ;
+               break;
+       case SK_INIT_IO:
+               SkHwtInit(pAC,Ioc) ;
+               SkTimerDone(pAC, Ioc);
+               break;
+       default:
+               break;
+       }
+}
+
+/*
+ * Stops a high level timer
+ * - If a timer is not in the queue the function returns normally, too.
+ */
+void   SkTimerStop(
+SK_AC          *pAC,           /* Adapters context */
+SK_IOC         Ioc,            /* IoContext */
+SK_TIMER       *pTimer)        /* Timer Pointer to be started */
+{
+       SK_TIMER        **ppTimPrev ;
+       SK_TIMER        *pTm ;
+
+       /*
+        * remove timer from queue
+        */
+       pTimer->TmActive = SK_FALSE ;
+       if (pAC->Tim.StQueue == pTimer && !pTimer->TmNext) {
+               SkHwtStop(pAC,Ioc) ;
+       }
+       for (ppTimPrev = &pAC->Tim.StQueue ; (pTm = *ppTimPrev) ;
+               ppTimPrev = &pTm->TmNext ) {
+               if (pTm == pTimer) {
+                       /*
+                        * Timer found in queue
+                        * - dequeue it and
+                        * - correct delta of the next timer
+                        */
+                       *ppTimPrev = pTm->TmNext ;
+
+                       if (pTm->TmNext) {
+                               /* correct delta of next timer in queue */
+                               pTm->TmNext->TmDelta += pTm->TmDelta ;
+                       }
+                       return ;
+               }
+       }
+}
+
+/*
+ * Start a high level software timer
+ */
+void   SkTimerStart(
+SK_AC          *pAC,           /* Adapters context */
+SK_IOC         Ioc,            /* IoContext */
+SK_TIMER       *pTimer,        /* Timer Pointer to be started */
+SK_U32         Time,           /* Time value */
+SK_U32         Class,          /* Event Class for this timer */
+SK_U32         Event,          /* Event Value for this timer */
+SK_EVPARA      Para)           /* Event Parameter for this timer */
+{
+       SK_TIMER        **ppTimPrev ;
+       SK_TIMER        *pTm ;
+       SK_U32          Delta ;
+
+       Time /= 16 ;            /* input is uS, clock ticks are 16uS */
+       if (!Time)
+               Time = 1 ;
+
+       SkTimerStop(pAC,Ioc,pTimer) ;
+
+       pTimer->TmClass = Class ;
+       pTimer->TmEvent = Event ;
+       pTimer->TmPara = Para ;
+       pTimer->TmActive = SK_TRUE ;
+
+       if (!pAC->Tim.StQueue) {
+               /* First Timer to be started */
+               pAC->Tim.StQueue = pTimer ;
+               pTimer->TmNext = 0 ;
+               pTimer->TmDelta = Time ;
+               SkHwtStart(pAC,Ioc,Time) ;
+               return ;
+       }
+
+       /*
+        * timer correction
+        */
+       timer_done(pAC,Ioc,0) ;
+
+       /*
+        * find position in queue
+        */
+       Delta = 0 ;
+       for (ppTimPrev = &pAC->Tim.StQueue ; (pTm = *ppTimPrev) ;
+               ppTimPrev = &pTm->TmNext ) {
+               if (Delta + pTm->TmDelta > Time) {
+                       /* Position found */
+                       /* Here the timer needs to be inserted. */
+                       break ;
+               }
+               Delta += pTm->TmDelta ;
+       }
+
+       /* insert in queue */
+       *ppTimPrev = pTimer ;
+       pTimer->TmNext = pTm ;
+       pTimer->TmDelta = Time - Delta ;
+
+       if (pTm) {
+               /* There is a next timer
+                * -> correct its Delta value.
+                */
+               pTm->TmDelta -= pTimer->TmDelta ;
+       }
+
+       /*
+        * start new with first
+        */
+       SkHwtStart(pAC,Ioc,pAC->Tim.StQueue->TmDelta) ;
+}
+
+
+void   SkTimerDone(
+SK_AC  *pAC,           /* Adapters context */
+SK_IOC Ioc)            /* IoContext */
+{
+       timer_done(pAC,Ioc,1) ;
+}
+
+
+static void    timer_done(
+SK_AC  *pAC,           /* Adapters context */
+SK_IOC Ioc,            /* IoContext */
+int    Restart)        /* Do we need to restart the Hardware timer ? */
+{
+       SK_U32          Delta ;
+       SK_TIMER        *pTm ;
+       SK_TIMER        *pTComp ;       /* Timer completed now now */
+       SK_TIMER        **ppLast ;      /* Next field of Last timer to be deq */
+       int             Done = 0 ;
+
+       Delta = SkHwtRead(pAC,Ioc) ;
+       ppLast = &pAC->Tim.StQueue ;
+       pTm = pAC->Tim.StQueue ;
+       while (pTm && !Done) {
+               if (Delta >= pTm->TmDelta) {
+                       /* Timer ran out */
+                       pTm->TmActive = SK_FALSE ;
+                       Delta -= pTm->TmDelta ;
+                       ppLast = &pTm->TmNext ;
+                       pTm = pTm->TmNext ;
+               } else {
+                       /* We found the first timer that did not run out */
+                       pTm->TmDelta -= Delta ;
+                       Delta = 0 ;
+                       Done = 1 ;
+               }
+       }
+       *ppLast = 0 ;
+       /*
+        * pTm points to the first Timer that did not run out.
+        * StQueue points to the first Timer that run out.
+        */
+
+       for ( pTComp = pAC->Tim.StQueue ; pTComp ; pTComp = pTComp->TmNext) {
+               SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent,
+                       pTComp->TmPara) ;
+       }
+
+       /* Set head of timer queue to the first timer that did not run out */
+       pAC->Tim.StQueue = pTm ;
+
+       if (Restart && pAC->Tim.StQueue) {
+               /* Restart HW timer */
+               SkHwtStart(pAC,Ioc,pAC->Tim.StQueue->TmDelta) ;
+       }
+}
+
+#endif /* CONFIG_SK98 */
+
+/* End of file */
diff --git a/drivers/net/sk98lin/skvpd.c b/drivers/net/sk98lin/skvpd.c
new file mode 100644 (file)
index 0000000..3b81e67
--- /dev/null
@@ -0,0 +1,1329 @@
+/******************************************************************************
+ *
+ * Name:       skvpd.c
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.37 $
+ * Date:       $Date: 2003/01/13 10:42:45 $
+ * Purpose:    Shared software to read and write VPD data
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2003 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skvpd.c,v $
+ *     Revision 1.37  2003/01/13 10:42:45  rschmidt
+ *     Replaced check for PCI device Id from YUKON with GENESIS
+ *     to set the VPD size in VpdInit()
+ *     Editorial changes
+ *
+ *     Revision 1.36  2002/11/14 15:16:56  gheinig
+ *     Added const specifier to key and buf parameters for VpdPara, VpdRead
+ *     and VpdWrite for Diag 7 GUI
+ *
+ *     Revision 1.35  2002/10/21 14:31:59  gheinig
+ *     Took out CVS web garbage at head of file
+ *
+ *     Revision 1.34  2002/10/21 11:47:24  gheinig
+ *     Reverted to version 1.32 due to unwanted commit
+ *
+ *     Revision 1.32  2002/10/14 16:04:29  rschmidt
+ *     Added saving of VPD ROM Size from PCI_OUR_REG_2
+ *     Avoid reading of PCI_OUR_REG_2 in VpdTransferBlock()
+ *     Editorial changes
+ *
+ *     Revision 1.31  2002/09/10 09:21:32  mkarl
+ *     Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis
+ *
+ *     Revision 1.30  2002/09/09 14:43:03  mkarl
+ *     changes for diagnostics in order to read VPD data before the adapter
+ *     has been initialized
+ *     editorial changes
+ *
+ *     Revision 1.29  2002/07/26 13:20:43  mkarl
+ *     added Yukon support
+ *     save size of VPD in pAC->vpd.vpd_size
+ *
+ *     Revision 1.28  2002/04/02 15:31:47  afischer
+ *     Bug fix in VpdWait()
+ *
+ *     Revision 1.27  2000/08/10 11:29:06  rassmann
+ *     Editorial changes.
+ *     Preserving 32-bit alignment in structs for the adapter context.
+ *     Removed unused function VpdWriteDword() (#if 0).
+ *     Made VpdReadKeyword() available for SKDIAG only.
+ *
+ *     Revision 1.26  2000/06/13 08:00:01  mkarl
+ *     additional cast to avoid compile problems in 64 bit environment
+ *
+ *     Revision 1.25  1999/11/22 13:39:32  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.24  1999/03/11 14:25:49  malthoff
+ *     Replace __STDC__ with SK_KR_PROTO.
+ *
+ *     Revision 1.23  1999/01/11 15:13:11  gklug
+ *     fix: syntax error
+ *
+ *     Revision 1.22  1998/10/30 06:41:15  gklug
+ *     rmv: WARNING
+ *
+ *     Revision 1.21  1998/10/29 07:15:14  gklug
+ *     fix: Write Stream function needs verify.
+ *
+ *     Revision 1.20  1998/10/28 18:05:08  gklug
+ *     chg: no DEBUG in VpdMayWrite
+ *
+ *     Revision 1.19  1998/10/28 15:56:11  gklug
+ *     fix: Return len at end of ReadStream
+ *     fix: Write even less than 4 bytes correctly
+ *
+ *     Revision 1.18  1998/10/28 09:00:47  gklug
+ *     fix: unreferenced local vars
+ *
+ *     Revision 1.17  1998/10/28 08:25:45  gklug
+ *     fix: WARNING
+ *
+ *     Revision 1.16  1998/10/28 08:17:30  gklug
+ *     fix: typo
+ *
+ *     Revision 1.15  1998/10/28 07:50:32  gklug
+ *     fix: typo
+ *
+ *     Revision 1.14  1998/10/28 07:20:38  gklug
+ *     chg: Interface functions to use IoC as parameter as well
+ *     fix: VpdRead/WriteDWord now returns SK_U32
+ *     chg: VPD_IN/OUT names conform to SK_IN/OUT
+ *     add: usage of VPD_IN/OUT8 macros
+ *     add: VpdRead/Write Stream functions to r/w a stream of data
+ *     fix: VpdTransferBlock swapped illegal
+ *     add: VpdMayWrite
+ *
+ *     Revision 1.13  1998/10/22 10:02:37  gklug
+ *     fix: SysKonnectFileId typo
+ *
+ *     Revision 1.12  1998/10/20 10:01:01  gklug
+ *     fix: parameter to SkOsGetTime
+ *
+ *     Revision 1.11  1998/10/15 12:51:48  malthoff
+ *     Remove unrequired parameter p in vpd_setup_para().
+ *
+ *     Revision 1.10  1998/10/08 14:52:43  malthoff
+ *     Remove CvsId by SysKonnectFileId.
+ *
+ *     Revision 1.9  1998/09/16 07:33:52  malthoff
+ *     replace memcmp() by SK_MEMCMP and
+ *     memcpy() by SK_MEMCPY() to be
+ *     independent from the 'C' Standard Library.
+ *
+ *     Revision 1.8  1998/08/19 12:52:35  malthoff
+ *     compiler fix: use SK_VPD_KEY instead of S_VPD.
+ *
+ *     Revision 1.7  1998/08/19 08:14:01  gklug
+ *     fix: remove struct keyword as much as possible from the C-code (see CCC)
+ *
+ *     Revision 1.6  1998/08/18 13:03:58  gklug
+ *     SkOsGetTime now returns SK_U64
+ *
+ *     Revision 1.5  1998/08/18 08:17:29  malthoff
+ *     Ensure we issue a VPD read in vpd_read_dword().
+ *     Discard all VPD keywords other than Vx or Yx, where
+ *     x is '0..9' or 'A..Z'.
+ *
+ *     Revision 1.4  1998/07/03 14:52:19  malthoff
+ *     Add category SK_DBGCAT_FATAL to some debug macros.
+ *     bug fix: correct the keyword name check in vpd_write().
+ *
+ *     Revision 1.3  1998/06/26 11:16:53  malthoff
+ *     Correct the modified File Identifier.
+ *
+ *     Revision 1.2  1998/06/26 11:13:43  malthoff
+ *     Modify the File Identifier.
+ *
+ *     Revision 1.1  1998/06/19 14:11:08  malthoff
+ *     Created, Tests with AIX were performed successfully
+ *
+ *
+ ******************************************************************************/
+
+#include <config.h>
+
+#ifdef CONFIG_SK98
+
+/*
+       Please refer skvpd.txt for infomation how to include this module
+ */
+static const char SysKonnectFileId[] =
+       "@(#)$Id: skvpd.c,v 1.37 2003/01/13 10:42:45 rschmidt Exp $ (C) SK";
+
+#include "h/skdrv1st.h"
+#include "h/sktypes.h"
+#include "h/skdebug.h"
+#include "h/skdrv2nd.h"
+
+/*
+ * Static functions
+ */
+#ifndef SK_KR_PROTO
+static SK_VPD_PARA     *vpd_find_para(
+       SK_AC   *pAC,
+       const char      *key,
+       SK_VPD_PARA *p);
+#else  /* SK_KR_PROTO */
+static SK_VPD_PARA     *vpd_find_para();
+#endif /* SK_KR_PROTO */
+
+/*
+ * waits for a completion of a VPD transfer
+ * The VPD transfer must complete within SK_TICKS_PER_SEC/16
+ *
+ * returns     0:      success, transfer completes
+ *             error   exit(9) with a error message
+ */
+static int VpdWait(
+SK_AC  *pAC,   /* Adapters context */
+SK_IOC IoC,    /* IO Context */
+int            event)  /* event to wait for (VPD_READ / VPD_write) completion*/
+{
+       SK_U64  start_time;
+       SK_U16  state;
+
+       SK_DBG_MSG(pAC,SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+               ("VPD wait for %s\n", event?"Write":"Read"));
+       start_time = SkOsGetTime(pAC);
+       do {
+               if (SkOsGetTime(pAC) - start_time > SK_TICKS_PER_SEC) {
+
+                       /* Bug fix AF: Thu Mar 28 2002
+                        * Do not call: VPD_STOP(pAC, IoC);
+                        * A pending VPD read cycle can not be aborted by writing
+                        * VPD_WRITE to the PCI_VPD_ADR_REG (VPD address register).
+                        * Although the write threshold in the OUR-register protects
+                        * VPD read only space from being overwritten this does not
+                        * protect a VPD read from being `converted` into a VPD write
+                        * operation (on the fly). As a consequence the VPD_STOP would
+                        * delete VPD read only data. In case of any problems with the
+                        * I2C bus we exit the loop here. The I2C read operation can
+                        * not be aborted except by a reset (->LR).
+                        */
+                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_FATAL | SK_DBGCAT_ERR,
+                               ("ERROR:VPD wait timeout\n"));
+                       return(1);
+               }
+
+               VPD_IN16(pAC, IoC, PCI_VPD_ADR_REG, &state);
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+                       ("state = %x, event %x\n",state,event));
+       } while((int)(state & PCI_VPD_FLAG) == event);
+
+       return(0);
+}
+
+#ifdef SKDIAG
+
+/*
+ * Read the dword at address 'addr' from the VPD EEPROM.
+ *
+ * Needed Time:        MIN 1,3 ms      MAX 2,6 ms
+ *
+ * Note: The DWord is returned in the endianess of the machine the routine
+ *       is running on.
+ *
+ * Returns the data read.
+ */
+SK_U32 VpdReadDWord(
+SK_AC  *pAC,   /* Adapters context */
+SK_IOC IoC,    /* IO Context */
+int            addr)   /* VPD address */
+{
+       SK_U32  Rtv;
+
+       /* start VPD read */
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+               ("VPD read dword at 0x%x\n",addr));
+       addr &= ~VPD_WRITE;             /* ensure the R/W bit is set to read */
+
+       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)addr);
+
+       /* ignore return code here */
+       (void)VpdWait(pAC, IoC, VPD_READ);
+
+       /* Don't swap here, it's a data stream of bytes */
+       Rtv = 0;
+
+       VPD_IN32(pAC, IoC, PCI_VPD_DAT_REG, &Rtv);
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+               ("VPD read dword data = 0x%x\n",Rtv));
+       return(Rtv);
+}
+
+#endif /* SKDIAG */
+
+#if 0
+
+/*
+       Write the dword 'data' at address 'addr' into the VPD EEPROM, and
+       verify that the data is written.
+
+ Needed Time:
+
+.                              MIN             MAX
+. -------------------------------------------------------------------
+. write                                1.8 ms          3.6 ms
+. internal write cyles         0.7 ms          7.0 ms
+. -------------------------------------------------------------------
+. over all program time                2.5 ms          10.6 ms
+. read                         1.3 ms          2.6 ms
+. -------------------------------------------------------------------
+. over all                     3.8 ms          13.2 ms
+.
+
+
+ Returns       0:      success
+                       1:      error,  I2C transfer does not terminate
+                       2:      error,  data verify error
+
+ */
+static int VpdWriteDWord(
+SK_AC  *pAC,   /* pAC pointer */
+SK_IOC IoC,    /* IO Context */
+int            addr,   /* VPD address */
+SK_U32 data)   /* VPD data to write */
+{
+       /* start VPD write */
+       /* Don't swap here, it's a data stream of bytes */
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+               ("VPD write dword at addr 0x%x, data = 0x%x\n",addr,data));
+       VPD_OUT32(pAC, IoC, PCI_VPD_DAT_REG, (SK_U32)data);
+       /* But do it here */
+       addr |= VPD_WRITE;
+
+       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)(addr | VPD_WRITE));
+
+       /* this may take up to 10,6 ms */
+       if (VpdWait(pAC, IoC, VPD_WRITE)) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                       ("Write Timed Out\n"));
+               return(1);
+       };
+
+       /* verify data */
+       if (VpdReadDWord(pAC, IoC, addr) != data) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+                       ("Data Verify Error\n"));
+               return(2);
+       }
+       return(0);
+}      /* VpdWriteDWord */
+
+#endif /* 0 */
+
+/*
+ *     Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
+ *     or to the I2C EEPROM.
+ *
+ * Returns number of bytes read / written.
+ */
+static int VpdWriteStream(
+SK_AC  *pAC,   /* Adapters context */
+SK_IOC IoC,    /* IO Context */
+char   *buf,   /* data buffer */
+int            Addr,   /* VPD start address */
+int            Len)    /* number of bytes to read / to write */
+{
+       int             i;
+       int             j;
+       SK_U16  AdrReg;
+       int             Rtv;
+       SK_U8   * pComp;        /* Compare pointer */
+       SK_U8   Data;           /* Input Data for Compare */
+
+       /* Init Compare Pointer */
+       pComp = (SK_U8 *) buf;
+
+       for (i = 0; i < Len; i++, buf++) {
+               if ((i%sizeof(SK_U32)) == 0) {
+                       /*
+                        * At the begin of each cycle read the Data Reg
+                        * So it is initialized even if only a few bytes
+                        * are written.
+                        */
+                       AdrReg = (SK_U16) Addr;
+                       AdrReg &= ~VPD_WRITE;   /* READ operation */
+
+                       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
+
+                       /* Wait for termination */
+                       Rtv = VpdWait(pAC, IoC, VPD_READ);
+                       if (Rtv != 0) {
+                               return(i);
+                       }
+               }
+
+               /* Write current Byte */
+               VPD_OUT8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)),
+                               *(SK_U8*)buf);
+
+               if (((i%sizeof(SK_U32)) == 3) || (i == (Len - 1))) {
+                       /* New Address needs to be written to VPD_ADDR reg */
+                       AdrReg = (SK_U16) Addr;
+                       Addr += sizeof(SK_U32);
+                       AdrReg |= VPD_WRITE;    /* WRITE operation */
+
+                       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
+
+                       /* Wait for termination */
+                       Rtv = VpdWait(pAC, IoC, VPD_WRITE);
+                       if (Rtv != 0) {
+                               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                                       ("Write Timed Out\n"));
+                               return(i - (i%sizeof(SK_U32)));
+                       }
+
+                       /*
+                        * Now re-read to verify
+                        */
+                       AdrReg &= ~VPD_WRITE;   /* READ operation */
+
+                       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
+
+                       /* Wait for termination */
+                       Rtv = VpdWait(pAC, IoC, VPD_READ);
+                       if (Rtv != 0) {
+                               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                                       ("Verify Timed Out\n"));
+                               return(i - (i%sizeof(SK_U32)));
+                       }
+
+                       for (j = 0; j <= (int)(i%sizeof(SK_U32)); j++, pComp++) {
+
+                               VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + j, &Data);
+
+                               if (Data != *pComp) {
+                                       /* Verify Error */
+                                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                                               ("WriteStream Verify Error\n"));
+                                       return(i - (i%sizeof(SK_U32)) + j);
+                               }
+                       }
+               }
+       }
+
+       return(Len);
+}
+
+
+/*
+ *     Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
+ *     or to the I2C EEPROM.
+ *
+ * Returns number of bytes read / written.
+ */
+static int VpdReadStream(
+SK_AC  *pAC,   /* Adapters context */
+SK_IOC IoC,    /* IO Context */
+char   *buf,   /* data buffer */
+int            Addr,   /* VPD start address */
+int            Len)    /* number of bytes to read / to write */
+{
+       int             i;
+       SK_U16  AdrReg;
+       int             Rtv;
+
+       for (i = 0; i < Len; i++, buf++) {
+               if ((i%sizeof(SK_U32)) == 0) {
+                       /* New Address needs to be written to VPD_ADDR reg */
+                       AdrReg = (SK_U16) Addr;
+                       Addr += sizeof(SK_U32);
+                       AdrReg &= ~VPD_WRITE;   /* READ operation */
+
+                       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
+
+                       /* Wait for termination */
+                       Rtv = VpdWait(pAC, IoC, VPD_READ);
+                       if (Rtv != 0) {
+                               return(i);
+                       }
+               }
+               VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)),
+                       (SK_U8 *)buf);
+       }
+
+       return(Len);
+}
+
+/*
+ *     Read ore writes 'len' bytes of VPD data, starting at 'addr' from
+ *     or to the I2C EEPROM.
+ *
+ * Returns number of bytes read / written.
+ */
+static int VpdTransferBlock(
+SK_AC  *pAC,   /* Adapters context */
+SK_IOC IoC,    /* IO Context */
+char   *buf,   /* data buffer */
+int            addr,   /* VPD start address */
+int            len,    /* number of bytes to read / to write */
+int            dir)    /* transfer direction may be VPD_READ or VPD_WRITE */
+{
+       int             Rtv;    /* Return value */
+       int             vpd_rom_size;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+               ("VPD %s block, addr = 0x%x, len = %d\n",
+               dir ? "write" : "read", addr, len));
+
+       if (len == 0)
+               return(0);
+
+       vpd_rom_size = pAC->vpd.rom_size;
+
+       if (addr > vpd_rom_size - 4) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+                       ("Address error: 0x%x, exp. < 0x%x\n",
+                       addr, vpd_rom_size - 4));
+               return(0);
+       }
+
+       if (addr + len > vpd_rom_size) {
+               len = vpd_rom_size - addr;
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                       ("Warning: len was cut to %d\n", len));
+       }
+
+       if (dir == VPD_READ) {
+               Rtv = VpdReadStream(pAC, IoC, buf, addr, len);
+       }
+       else {
+               Rtv = VpdWriteStream(pAC, IoC, buf, addr, len);
+       }
+
+       return(Rtv);
+}
+
+#ifdef SKDIAG
+
+/*
+ *     Read 'len' bytes of VPD data, starting at 'addr'.
+ *
+ * Returns number of bytes read.
+ */
+int VpdReadBlock(
+SK_AC  *pAC,   /* pAC pointer */
+SK_IOC IoC,    /* IO Context */
+char   *buf,   /* buffer were the data should be stored */
+int            addr,   /* start reading at the VPD address */
+int            len)    /* number of bytes to read */
+{
+       return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ));
+}
+
+/*
+ *     Write 'len' bytes of *but to the VPD EEPROM, starting at 'addr'.
+ *
+ * Returns number of bytes writes.
+ */
+int VpdWriteBlock(
+SK_AC  *pAC,   /* pAC pointer */
+SK_IOC IoC,    /* IO Context */
+char   *buf,   /* buffer, holds the data to write */
+int            addr,   /* start writing at the VPD address */
+int            len)    /* number of bytes to write */
+{
+       return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE));
+}
+#endif /* SKDIAG */
+
+/*
+ * (re)initialize the VPD buffer
+ *
+ * Reads the VPD data from the EEPROM into the VPD buffer.
+ * Get the remaining read only and read / write space.
+ *
+ * return      0:      success
+ *             1:      fatal VPD error
+ */
+static int VpdInit(
+SK_AC  *pAC,   /* Adapters context */
+SK_IOC IoC)    /* IO Context */
+{
+       SK_VPD_PARA *r, rp;     /* RW or RV */
+       int             i;
+       unsigned char   x;
+       int             vpd_size;
+       SK_U16  dev_id;
+       SK_U32  our_reg2;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit .. "));
+
+       VPD_IN16(pAC, IoC, PCI_DEVICE_ID, &dev_id);
+
+       VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2);
+
+       pAC->vpd.rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14);
+
+       /*
+        * this function might get used before the hardware is initialized
+        * therefore we cannot always trust in GIChipId
+        */
+       if (((pAC->vpd.v.vpd_status & VPD_VALID) == 0 &&
+               dev_id != VPD_DEV_ID_GENESIS) ||
+               ((pAC->vpd.v.vpd_status & VPD_VALID) != 0 &&
+               !pAC->GIni.GIGenesis)) {
+
+               /* for Yukon the VPD size is always 256 */
+               vpd_size = VPD_SIZE_YUKON;
+       }
+       else {
+               /* Genesis uses the maximum ROM size up to 512 for VPD */
+               if (pAC->vpd.rom_size > VPD_SIZE_GENESIS) {
+                       vpd_size = VPD_SIZE_GENESIS;
+               }
+               else {
+                       vpd_size = pAC->vpd.rom_size;
+               }
+       }
+
+       /* read the VPD data into the VPD buffer */
+       if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf, 0, vpd_size, VPD_READ)
+               != vpd_size) {
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                       ("Block Read Error\n"));
+               return(1);
+       }
+
+       pAC->vpd.vpd_size = vpd_size;
+
+       /* find the end tag of the RO area */
+       if (!(r = vpd_find_para(pAC, VPD_RV, &rp))) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+                       ("Encoding Error: RV Tag not found\n"));
+               return(1);
+       }
+
+       if (r->p_val + r->p_len > pAC->vpd.vpd_buf + vpd_size/2) {
+               SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+                       ("Encoding Error: Invalid VPD struct size\n"));
+               return(1);
+       }
+       pAC->vpd.v.vpd_free_ro = r->p_len - 1;
+
+       /* test the checksum */
+       for (i = 0, x = 0; (unsigned)i <= (unsigned)vpd_size/2 - r->p_len; i++) {
+               x += pAC->vpd.vpd_buf[i];
+       }
+
+       if (x != 0) {
+               /* checksum error */
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+                       ("VPD Checksum Error\n"));
+               return(1);
+       }
+
+       /* find and check the end tag of the RW area */
+       if (!(r = vpd_find_para(pAC, VPD_RW, &rp))) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+                       ("Encoding Error: RV Tag not found\n"));
+               return(1);
+       }
+
+       if (r->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+                       ("Encoding Error: Invalid VPD struct size\n"));
+               return(1);
+       }
+       pAC->vpd.v.vpd_free_rw = r->p_len;
+
+       /* everything seems to be ok */
+       if (pAC->GIni.GIChipId != 0) {
+               pAC->vpd.v.vpd_status |= VPD_VALID;
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT,
+               ("done. Free RO = %d, Free RW = %d\n",
+               pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
+
+       return(0);
+}
+
+/*
+ *     find the Keyword 'key' in the VPD buffer and fills the
+ *     parameter struct 'p' with it's values
+ *
+ * returns     *p      success
+ *             0:      parameter was not found or VPD encoding error
+ */
+static SK_VPD_PARA *vpd_find_para(
+SK_AC          *pAC,   /* common data base */
+const char     *key,   /* keyword to find (e.g. "MN") */
+SK_VPD_PARA *p)                /* parameter description struct */
+{
+       char *v ;       /* points to VPD buffer */
+       int max;        /* Maximum Number of Iterations */
+
+       v = pAC->vpd.vpd_buf;
+       max = 128;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+               ("VPD find para %s .. ",key));
+
+       /* check mandatory resource type ID string (Product Name) */
+       if (*v != (char)RES_ID) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+                       ("Error: 0x%x missing\n", RES_ID));
+               return(0);
+       }
+
+       if (strcmp(key, VPD_NAME) == 0) {
+               p->p_len = VPD_GET_RES_LEN(v);
+               p->p_val = VPD_GET_VAL(v);
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+                       ("found, len = %d\n", p->p_len));
+               return(p);
+       }
+
+       v += 3 + VPD_GET_RES_LEN(v) + 3;
+       for (;; ) {
+               if (SK_MEMCMP(key,v,2) == 0) {
+                       p->p_len = VPD_GET_VPD_LEN(v);
+                       p->p_val = VPD_GET_VAL(v);
+                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+                               ("found, len = %d\n",p->p_len));
+                       return(p);
+               }
+
+               /* exit when reaching the "RW" Tag or the maximum of itera. */
+               max--;
+               if (SK_MEMCMP(VPD_RW,v,2) == 0 || max == 0) {
+                       break;
+               }
+
+               if (SK_MEMCMP(VPD_RV,v,2) == 0) {
+                       v += 3 + VPD_GET_VPD_LEN(v) + 3;        /* skip VPD-W */
+               }
+               else {
+                       v += 3 + VPD_GET_VPD_LEN(v);
+               }
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+                       ("scanning '%c%c' len = %d\n",v[0],v[1],v[2]));
+       }
+
+#ifdef DEBUG
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ("not found\n"));
+       if (max == 0) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+                       ("Key/Len Encoding error\n"));
+       }
+#endif /* DEBUG */
+       return(0);
+}
+
+/*
+ *     Move 'n' bytes. Begin with the last byte if 'n' is > 0,
+ *     Start with the last byte if n is < 0.
+ *
+ * returns nothing
+ */
+static void vpd_move_para(
+char   *start,         /* start of memory block */
+char   *end,           /* end of memory block to move */
+int            n)                      /* number of bytes the memory block has to be moved */
+{
+       char *p;
+       int i;          /* number of byte copied */
+
+       if (n == 0)
+               return;
+
+       i = (int) (end - start + 1);
+       if (n < 0) {
+               p = start + n;
+               while (i != 0) {
+                       *p++ = *start++;
+                       i--;
+               }
+       }
+       else {
+               p = end + n;
+               while (i != 0) {
+                       *p-- = *end--;
+                       i--;
+               }
+       }
+}
+
+/*
+ *     setup the VPD keyword 'key' at 'ip'.
+ *
+ * returns nothing
+ */
+static void vpd_insert_key(
+const char     *key,   /* keyword to insert */
+const char     *buf,   /* buffer with the keyword value */
+int            len,            /* length of the value string */
+char   *ip)            /* inseration point */
+{
+       SK_VPD_KEY *p;
+
+       p = (SK_VPD_KEY *) ip;
+       p->p_key[0] = key[0];
+       p->p_key[1] = key[1];
+       p->p_len = (unsigned char) len;
+       SK_MEMCPY(&p->p_val,buf,len);
+}
+
+/*
+ *     Setup the VPD end tag "RV" / "RW".
+ *     Also correct the remaining space variables vpd_free_ro / vpd_free_rw.
+ *
+ * returns     0:      success
+ *             1:      encoding error
+ */
+static int vpd_mod_endtag(
+SK_AC  *pAC,           /* common data base */
+char   *etp)           /* end pointer input position */
+{
+       SK_VPD_KEY *p;
+       unsigned char   x;
+       int     i;
+       int     vpd_size;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+               ("VPD modify endtag at 0x%x = '%c%c'\n",etp,etp[0],etp[1]));
+
+       vpd_size = pAC->vpd.vpd_size;
+
+       p = (SK_VPD_KEY *) etp;
+
+       if (p->p_key[0] != 'R' || (p->p_key[1] != 'V' && p->p_key[1] != 'W')) {
+               /* something wrong here, encoding error */
+               SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+                       ("Encoding Error: invalid end tag\n"));
+               return(1);
+       }
+       if (etp > pAC->vpd.vpd_buf + vpd_size/2) {
+               /* create "RW" tag */
+               p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size-etp-3-1);
+               pAC->vpd.v.vpd_free_rw = (int) p->p_len;
+               i = pAC->vpd.v.vpd_free_rw;
+               etp += 3;
+       }
+       else {
+               /* create "RV" tag */
+               p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size/2-etp-3);
+               pAC->vpd.v.vpd_free_ro = (int) p->p_len - 1;
+
+               /* setup checksum */
+               for (i = 0, x = 0; i < vpd_size/2 - p->p_len; i++) {
+                       x += pAC->vpd.vpd_buf[i];
+               }
+               p->p_val = (char) 0 - x;
+               i = pAC->vpd.v.vpd_free_ro;
+               etp += 4;
+       }
+       while (i) {
+               *etp++ = 0x00;
+               i--;
+       }
+
+       return(0);
+}
+
+/*
+ *     Insert a VPD keyword into the VPD buffer.
+ *
+ *     The keyword 'key' is inserted at the position 'ip' in the
+ *     VPD buffer.
+ *     The keywords behind the input position will
+ *     be moved. The VPD end tag "RV" or "RW" is generated again.
+ *
+ * returns     0:      success
+ *             2:      value string was cut
+ *             4:      VPD full, keyword was not written
+ *             6:      fatal VPD error
+ *
+ */
+int    VpdSetupPara(
+SK_AC  *pAC,           /* common data base */
+const char     *key,   /* keyword to insert */
+const char     *buf,   /* buffer with the keyword value */
+int            len,            /* length of the keyword value */
+int            type,           /* VPD_RO_KEY or VPD_RW_KEY */
+int            op)                     /* operation to do: ADD_KEY or OWR_KEY */
+{
+       SK_VPD_PARA vp;
+       char    *etp;           /* end tag position */
+       int     free;           /* remaining space in selected area */
+       char    *ip;            /* input position inside the VPD buffer */
+       int     rtv;            /* return code */
+       int     head;           /* additional haeder bytes to move */
+       int     found;          /* additinoal bytes if the keyword was found */
+       int vpd_size;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+               ("VPD setup para key = %s, val = %s\n",key,buf));
+
+       vpd_size = pAC->vpd.vpd_size;
+
+       rtv = 0;
+       ip = 0;
+       if (type == VPD_RW_KEY) {
+               /* end tag is "RW" */
+               free = pAC->vpd.v.vpd_free_rw;
+               etp = pAC->vpd.vpd_buf + (vpd_size - free - 1 - 3);
+       }
+       else {
+               /* end tag is "RV" */
+               free = pAC->vpd.v.vpd_free_ro;
+               etp = pAC->vpd.vpd_buf + (vpd_size/2 - free - 4);
+       }
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+               ("Free RO = %d, Free RW = %d\n",
+               pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
+
+       head = 0;
+       found = 0;
+       if (op == OWR_KEY) {
+               if (vpd_find_para(pAC, key, &vp)) {
+                       found = 3;
+                       ip = vp.p_val - 3;
+                       free += vp.p_len + 3;
+                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+                               ("Overwrite Key\n"));
+               }
+               else {
+                       op = ADD_KEY;
+                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+                               ("Add Key\n"));
+               }
+       }
+       if (op == ADD_KEY) {
+               ip = etp;
+               vp.p_len = 0;
+               head = 3;
+       }
+
+       if (len + 3 > free) {
+               if (free < 7) {
+                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                               ("VPD Buffer Overflow, keyword not written\n"));
+                       return(4);
+               }
+               /* cut it again */
+               len = free - 3;
+               rtv = 2;
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                       ("VPD Buffer Full, Keyword was cut\n"));
+       }
+
+       vpd_move_para(ip + vp.p_len + found, etp+2, len-vp.p_len+head);
+       vpd_insert_key(key, buf, len, ip);
+       if (vpd_mod_endtag(pAC, etp + len - vp.p_len + head)) {
+               pAC->vpd.v.vpd_status &= ~VPD_VALID;
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                       ("VPD Encoding Error\n"));
+               return(6);
+       }
+
+       return(rtv);
+}
+
+
+/*
+ *     Read the contents of the VPD EEPROM and copy it to the
+ *     VPD buffer if not already done.
+ *
+ * return:     A pointer to the vpd_status structure. The structure contains
+ *             this fields.
+ */
+SK_VPD_STATUS *VpdStat(
+SK_AC  *pAC,   /* Adapters context */
+SK_IOC IoC)    /* IO Context */
+{
+       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
+               (void)VpdInit(pAC, IoC);
+       }
+       return(&pAC->vpd.v);
+}
+
+
+/*
+ *     Read the contents of the VPD EEPROM and copy it to the VPD
+ *     buffer if not already done.
+ *     Scan the VPD buffer for VPD keywords and create the VPD
+ *     keyword list by copying the keywords to 'buf', all after
+ *     each other and terminated with a '\0'.
+ *
+ * Exceptions: o The Resource Type ID String (product name) is called "Name"
+ *             o The VPD end tags 'RV' and 'RW' are not listed
+ *
+ *     The number of copied keywords is counted in 'elements'.
+ *
+ * returns     0:      success
+ *             2:      buffer overfull, one or more keywords are missing
+ *             6:      fatal VPD error
+ *
+ *     example values after returning:
+ *
+ *             buf =   "Name\0PN\0EC\0MN\0SN\0CP\0VF\0VL\0YA\0"
+ *             *len =          30
+ *             *elements =      9
+ */
+int VpdKeys(
+SK_AC  *pAC,           /* common data base */
+SK_IOC IoC,            /* IO Context */
+char   *buf,           /* buffer where to copy the keywords */
+int            *len,           /* buffer length */
+int            *elements)      /* number of keywords returned */
+{
+       char *v;
+       int n;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("list VPD keys .. "));
+       *elements = 0;
+       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
+               if (VpdInit(pAC, IoC) != 0) {
+                       *len = 0;
+                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                               ("VPD Init Error, terminated\n"));
+                       return(6);
+               }
+       }
+
+       if ((signed)strlen(VPD_NAME) + 1 <= *len) {
+               v = pAC->vpd.vpd_buf;
+               strcpy(buf,VPD_NAME);
+               n = strlen(VPD_NAME) + 1;
+               buf += n;
+               *elements = 1;
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
+                       ("'%c%c' ",v[0],v[1]));
+       }
+       else {
+               *len = 0;
+               SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
+                       ("buffer overflow\n"));
+               return(2);
+       }
+
+       v += 3 + VPD_GET_RES_LEN(v) + 3;
+       for (;; ) {
+               /* exit when reaching the "RW" Tag */
+               if (SK_MEMCMP(VPD_RW,v,2) == 0) {
+                       break;
+               }
+
+               if (SK_MEMCMP(VPD_RV,v,2) == 0) {
+                       v += 3 + VPD_GET_VPD_LEN(v) + 3;        /* skip VPD-W */
+                       continue;
+               }
+
+               if (n+3 <= *len) {
+                       SK_MEMCPY(buf,v,2);
+                       buf += 2;
+                       *buf++ = '\0';
+                       n += 3;
+                       v += 3 + VPD_GET_VPD_LEN(v);
+                       *elements += 1;
+                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
+                               ("'%c%c' ",v[0],v[1]));
+               }
+               else {
+                       *len = n;
+                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                               ("buffer overflow\n"));
+                       return(2);
+               }
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("\n"));
+       *len = n;
+       return(0);
+}
+
+
+/*
+ *     Read the contents of the VPD EEPROM and copy it to the
+ *     VPD buffer if not already done. Search for the VPD keyword
+ *     'key' and copy its value to 'buf'. Add a terminating '\0'.
+ *     If the value does not fit into the buffer cut it after
+ *     'len' - 1 bytes.
+ *
+ * returns     0:      success
+ *             1:      keyword not found
+ *             2:      value string was cut
+ *             3:      VPD transfer timeout
+ *             6:      fatal VPD error
+ */
+int VpdRead(
+SK_AC          *pAC,   /* common data base */
+SK_IOC         IoC,    /* IO Context */
+const char     *key,   /* keyword to read (e.g. "MN") */
+char           *buf,   /* buffer where to copy the keyword value */
+int                    *len)   /* buffer length */
+{
+       SK_VPD_PARA *p, vp;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("VPD read %s .. ", key));
+       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
+               if (VpdInit(pAC, IoC) != 0) {
+                       *len = 0;
+                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                               ("VPD init error\n"));
+                       return(6);
+               }
+       }
+
+       if ((p = vpd_find_para(pAC, key, &vp)) != NULL) {
+               if (p->p_len > (*(unsigned *)len)-1) {
+                       p->p_len = *len - 1;
+               }
+               SK_MEMCPY(buf, p->p_val, p->p_len);
+               buf[p->p_len] = '\0';
+               *len = p->p_len;
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
+                       ("%c%c%c%c.., len = %d\n",
+                       buf[0],buf[1],buf[2],buf[3],*len));
+       }
+       else {
+               *len = 0;
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("not found\n"));
+               return(1);
+       }
+       return(0);
+}
+
+
+/*
+ *     Check whether a given key may be written
+ *
+ * returns
+ *     SK_TRUE         Yes it may be written
+ *     SK_FALSE        No it may be written
+ */
+SK_BOOL VpdMayWrite(
+char   *key)   /* keyword to write (allowed values "Yx", "Vx") */
+{
+       if ((*key != 'Y' && *key != 'V') ||
+               key[1] < '0' || key[1] > 'Z' ||
+               (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
+
+               return(SK_FALSE);
+       }
+       return(SK_TRUE);
+}
+
+/*
+ *     Read the contents of the VPD EEPROM and copy it to the VPD
+ *     buffer if not already done. Insert/overwrite the keyword 'key'
+ *     in the VPD buffer. Cut the keyword value if it does not fit
+ *     into the VPD read / write area.
+ *
+ * returns     0:      success
+ *             2:      value string was cut
+ *             3:      VPD transfer timeout
+ *             4:      VPD full, keyword was not written
+ *             5:      keyword cannot be written
+ *             6:      fatal VPD error
+ */
+int VpdWrite(
+SK_AC          *pAC,   /* common data base */
+SK_IOC         IoC,    /* IO Context */
+const char     *key,   /* keyword to write (allowed values "Yx", "Vx") */
+const char     *buf)   /* buffer where the keyword value can be read from */
+{
+       int len;                /* length of the keyword to write */
+       int rtv;                /* return code */
+       int rtv2;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX,
+               ("VPD write %s = %s\n",key,buf));
+
+       if ((*key != 'Y' && *key != 'V') ||
+               key[1] < '0' || key[1] > 'Z' ||
+               (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                       ("illegal key tag, keyword not written\n"));
+               return(5);
+       }
+
+       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
+               if (VpdInit(pAC, IoC) != 0) {
+                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                               ("VPD init error\n"));
+                       return(6);
+               }
+       }
+
+       rtv = 0;
+       len = strlen(buf);
+       if (len > VPD_MAX_LEN) {
+               /* cut it */
+               len = VPD_MAX_LEN;
+               rtv = 2;
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                       ("keyword too long, cut after %d bytes\n",VPD_MAX_LEN));
+       }
+       if ((rtv2 = VpdSetupPara(pAC, key, buf, len, VPD_RW_KEY, OWR_KEY)) != 0) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                       ("VPD write error\n"));
+               return(rtv2);
+       }
+
+       return(rtv);
+}
+
+/*
+ *     Read the contents of the VPD EEPROM and copy it to the
+ *     VPD buffer if not already done. Remove the VPD keyword
+ *     'key' from the VPD buffer.
+ *     Only the keywords in the read/write area can be deleted.
+ *     Keywords in the read only area cannot be deleted.
+ *
+ * returns     0:      success, keyword was removed
+ *             1:      keyword not found
+ *             5:      keyword cannot be deleted
+ *             6:      fatal VPD error
+ */
+int VpdDelete(
+SK_AC  *pAC,   /* common data base */
+SK_IOC IoC,    /* IO Context */
+char   *key)   /* keyword to read (e.g. "MN") */
+{
+       SK_VPD_PARA *p, vp;
+       char *etp;
+       int     vpd_size;
+
+       vpd_size = pAC->vpd.vpd_size;
+
+       SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("VPD delete key %s\n",key));
+       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
+               if (VpdInit(pAC, IoC) != 0) {
+                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                               ("VPD init error\n"));
+                       return(6);
+               }
+       }
+
+       if ((p = vpd_find_para(pAC, key, &vp)) != NULL) {
+               if (p->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
+                       /* try to delete read only keyword */
+                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                               ("cannot delete RO keyword\n"));
+                       return(5);
+               }
+
+               etp = pAC->vpd.vpd_buf + (vpd_size-pAC->vpd.v.vpd_free_rw-1-3);
+
+               vpd_move_para(vp.p_val+vp.p_len, etp+2,
+                       - ((int)(vp.p_len + 3)));
+               if (vpd_mod_endtag(pAC, etp - vp.p_len - 3)) {
+                       pAC->vpd.v.vpd_status &= ~VPD_VALID;
+                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                               ("VPD encoding error\n"));
+                       return(6);
+               }
+       }
+       else {
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                       ("keyword not found\n"));
+               return(1);
+       }
+
+       return(0);
+}
+
+/*
+ *     If the VPD buffer contains valid data write the VPD
+ *     read/write area back to the VPD EEPROM.
+ *
+ * returns     0:      success
+ *             3:      VPD transfer timeout
+ */
+int VpdUpdate(
+SK_AC  *pAC,   /* Adapters context */
+SK_IOC IoC)    /* IO Context */
+{
+       int vpd_size;
+
+       vpd_size = pAC->vpd.vpd_size;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("VPD update .. "));
+       if ((pAC->vpd.v.vpd_status & VPD_VALID) != 0) {
+               if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf + vpd_size/2,
+                       vpd_size/2, vpd_size/2, VPD_WRITE) != vpd_size/2) {
+
+                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                               ("transfer timed out\n"));
+                       return(3);
+               }
+       }
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("done\n"));
+       return(0);
+}
+
+
+/*
+ *     Read the contents of the VPD EEPROM and copy it to the VPD buffer
+ *     if not already done. If the keyword "VF" is not present it will be
+ *     created and the error log message will be stored to this keyword.
+ *     If "VF" is not present the error log message will be stored to the
+ *     keyword "VL". "VL" will created or overwritten if "VF" is present.
+ *     The VPD read/write area is saved to the VPD EEPROM.
+ *
+ * returns nothing, errors will be ignored.
+ */
+void VpdErrLog(
+SK_AC  *pAC,   /* common data base */
+SK_IOC IoC,    /* IO Context */
+char   *msg)   /* error log message */
+{
+       SK_VPD_PARA *v, vf;     /* VF */
+       int len;
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX,
+               ("VPD error log msg %s\n", msg));
+       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
+               if (VpdInit(pAC, IoC) != 0) {
+                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                               ("VPD init error\n"));
+                       return;
+               }
+       }
+
+       len = strlen(msg);
+       if (len > VPD_MAX_LEN) {
+               /* cut it */
+               len = VPD_MAX_LEN;
+       }
+       if ((v = vpd_find_para(pAC, VPD_VF, &vf)) != NULL) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("overwrite VL\n"));
+               (void)VpdSetupPara(pAC, VPD_VL, msg, len, VPD_RW_KEY, OWR_KEY);
+       }
+       else {
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("write VF\n"));
+               (void)VpdSetupPara(pAC, VPD_VF, msg, len, VPD_RW_KEY, ADD_KEY);
+       }
+
+       (void)VpdUpdate(pAC, IoC);
+}
+
+#endif /* CONFIG_SK98 */
diff --git a/drivers/net/sk98lin/skxmac2.c b/drivers/net/sk98lin/skxmac2.c
new file mode 100644 (file)
index 0000000..e6b5a95
--- /dev/null
@@ -0,0 +1,4396 @@
+/******************************************************************************
+ *
+ * Name:       skxmac2.c
+ * Project:    GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:    $Revision: 1.91 $
+ * Date:       $Date: 2003/02/05 15:09:34 $
+ * Purpose:    Contains functions to initialize the MACs and PHYs
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *     (C)Copyright 1998-2003 SysKonnect GmbH.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *     $Log: skxmac2.c,v $
+ *     Revision 1.91  2003/02/05 15:09:34  rschmidt
+ *     Removed setting of 'Collision Test'-bit in SkGmInitPhyMarv().
+ *     Disabled auto-update for speed, duplex and flow-control when
+ *     auto-negotiation is not enabled (Bug Id #10766).
+ *     Editorial changes.
+ *
+ *     Revision 1.90  2003/01/29 13:35:19  rschmidt
+ *     Increment Rx FIFO Overflow counter only in DEBUG-mode.
+ *     Corrected define for blinking active LED.
+ *
+ *     Revision 1.89  2003/01/28 16:37:45  rschmidt
+ *     Changed init for blinking active LED
+ *
+ *     Revision 1.88  2003/01/28 10:09:38  rschmidt
+ *     Added debug outputs in SkGmInitMac().
+ *     Added customized init of LED registers in SkGmInitPhyMarv(),
+ *     for blinking active LED (#ifdef ACT_LED_BLINK) and
+ *     for normal duplex LED (#ifdef DUP_LED_NORMAL).
+ *     Editorial changes.
+ *
+ *     Revision 1.87  2002/12/10 14:39:05  rschmidt
+ *     Improved initialization of GPHY in SkGmInitPhyMarv().
+ *     Editorial changes.
+ *
+ *     Revision 1.86  2002/12/09 15:01:12  rschmidt
+ *     Added setup of Ext. PHY Specific Ctrl Reg (downshift feature).
+ *
+ *     Revision 1.85  2002/12/05 14:09:16  rschmidt
+ *     Improved avoiding endless loop in SkGmPhyWrite(), SkGmPhyWrite().
+ *     Added additional advertising for 10Base-T when 100Base-T is selected.
+ *     Added case SK_PHY_MARV_FIBER for YUKON Fiber adapter.
+ *     Editorial changes.
+ *
+ *     Revision 1.84  2002/11/15 12:50:09  rschmidt
+ *     Changed SkGmCableDiagStatus() when getting results.
+ *
+ *     Revision 1.83  2002/11/13 10:28:29  rschmidt
+ *     Added some typecasts to avoid compiler warnings.
+ *
+ *     Revision 1.82  2002/11/13 09:20:46  rschmidt
+ *     Replaced for(..) with do {} while (...) in SkXmUpdateStats().
+ *     Replaced 2 macros GM_IN16() with 1 GM_IN32() in SkGmMacStatistic().
+ *     Added SkGmCableDiagStatus() for Virtual Cable Test (VCT).
+ *     Editorial changes.
+ *
+ *     Revision 1.81  2002/10/28 14:28:08  rschmidt
+ *     Changed MAC address setup for GMAC in SkGmInitMac().
+ *     Optimized handling of counter overflow IRQ in SkGmOverflowStatus().
+ *     Editorial changes.
+ *
+ *     Revision 1.80  2002/10/14 15:29:44  rschmidt
+ *     Corrected disabling of all PHY IRQs.
+ *     Added WA for deviation #16 (address used for pause packets).
+ *     Set Pause Mode in SkMacRxTxEnable() only for Genesis.
+ *     Added IRQ and counter for Receive FIFO Overflow in DEBUG-mode.
+ *     SkXmTimeStamp() replaced by SkMacTimeStamp().
+ *     Added clearing of GMAC Tx FIFO Underrun IRQ in SkGmIrq().
+ *     Editorial changes.
+ *
+ *     Revision 1.79  2002/10/10 15:55:36  mkarl
+ *     changes for PLinkSpeedUsed
+ *
+ *     Revision 1.78  2002/09/12 09:39:51  rwahl
+ *     Removed deactivate code for SIRQ overflow event separate for TX/RX.
+ *
+ *     Revision 1.77  2002/09/09 12:26:37  mkarl
+ *     added handling for Yukon to SkXmTimeStamp
+ *
+ *     Revision 1.76  2002/08/21 16:41:16  rschmidt
+ *     Added bit GPC_ENA_XC (Enable MDI crossover) in HWCFG_MODE.
+ *     Added forced speed settings in SkGmInitPhyMarv().
+ *     Added settings of full/half duplex capabilities for YUKON Fiber.
+ *     Editorial changes.
+ *
+ *     Revision 1.75  2002/08/16 15:12:01  rschmidt
+ *     Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis.
+ *     Added function SkMacHashing() for ADDR-Module.
+ *     Removed functions SkXmClrSrcCheck(), SkXmClrHashAddr() (calls replaced
+ *     with macros).
+ *     Removed functions SkGmGetMuxConfig().
+ *     Added HWCFG_MODE init for YUKON Fiber.
+ *     Changed initialization of GPHY in SkGmInitPhyMarv().
+ *     Changed check of parameter in SkXmMacStatistic().
+ *     Editorial changes.
+ *
+ *     Revision 1.74  2002/08/12 14:00:17  rschmidt
+ *     Replaced usage of Broadcom PHY Ids with defines.
+ *     Corrected error messages in SkGmMacStatistic().
+ *     Made SkMacPromiscMode() public for ADDR-Modul.
+ *     Editorial changes.
+ *
+ *     Revision 1.73  2002/08/08 16:26:24  rschmidt
+ *     Improved reset sequence for YUKON in SkGmHardRst() and SkGmInitMac().
+ *     Replaced XMAC Rx High Watermark init value with SK_XM_RX_HI_WM.
+ *     Editorial changes.
+ *
+ *     Revision 1.72  2002/07/24 15:11:19  rschmidt
+ *     Fixed wrong placement of parenthesis.
+ *     Editorial changes.
+ *
+ *     Revision 1.71  2002/07/23 16:05:18  rschmidt
+ *     Added global functions for PHY: SkGePhyRead(), SkGePhyWrite().
+ *     Fixed Tx Counter Overflow IRQ (Bug ID #10730).
+ *     Editorial changes.
+ *
+ *     Revision 1.70  2002/07/18 14:27:27  rwahl
+ *     Fixed syntax error.
+ *
+ *     Revision 1.69  2002/07/17 17:08:47  rwahl
+ *     Fixed check in SkXmMacStatistic().
+ *
+ *     Revision 1.68  2002/07/16 07:35:24  rwahl
+ *     Removed check for cleared mib counter in SkGmResetCounter().
+ *
+ *     Revision 1.67  2002/07/15 18:35:56  rwahl
+ *     Added SkXmUpdateStats(), SkGmUpdateStats(), SkXmMacStatistic(),
+ *       SkGmMacStatistic(), SkXmResetCounter(), SkGmResetCounter(),
+ *       SkXmOverflowStatus(), SkGmOverflowStatus().
+ *     Changes to SkXmIrq() & SkGmIrq(): Combined SIRQ Overflow for both
+ *       RX & TX.
+ *     Changes to SkGmInitMac(): call to SkGmResetCounter().
+ *     Editorial changes.
+ *
+ *     Revision 1.66  2002/07/15 15:59:30  rschmidt
+ *     Added PHY Address in SkXmPhyRead(), SkXmPhyWrite().
+ *     Added MIB Clear Counter in SkGmInitMac().
+ *     Added Duplex and Flow-Control settings.
+ *     Reset all Multicast filtering Hash reg. in SkGmInitMac().
+ *     Added new function: SkGmGetMuxConfig().
+ *     Editorial changes.
+ *
+ *     Revision 1.65  2002/06/10 09:35:39  rschmidt
+ *     Replaced C++ comments (//).
+ *     Added #define VCPU around VCPUwaitTime.
+ *     Editorial changes.
+ *
+ *     Revision 1.64  2002/06/05 08:41:10  rschmidt
+ *     Added function for XMAC2: SkXmTimeStamp().
+ *     Added function for YUKON: SkGmSetRxCmd().
+ *     Changed SkGmInitMac() resp. SkGmHardRst().
+ *     Fixed wrong variable in SkXmAutoNegLipaXmac() (debug mode).
+ *     SkXmRxTxEnable() replaced by SkMacRxTxEnable().
+ *     Editorial changes.
+ *
+ *     Revision 1.63  2002/04/25 13:04:44  rschmidt
+ *     Changes for handling YUKON.
+ *     Use of #ifdef OTHER_PHY to eliminate code for unused Phy types.
+ *     Macros for XMAC PHY access PHY_READ(), PHY_WRITE() replaced
+ *     by functions SkXmPhyRead(), SkXmPhyWrite();
+ *     Removed use of PRxCmd to setup XMAC.
+ *     Added define PHY_B_AS_PAUSE_MSK for BCom Pause Res.
+ *     Added setting of XM_RX_DIS_CEXT in SkXmInitMac().
+ *     Removed status parameter from MAC IRQ handler SkMacIrq(),
+ *     SkXmIrq() and SkGmIrq().
+ *     SkXmAutoNegLipa...() for ext. Phy replaced by SkMacAutoNegLipaPhy().
+ *     Added SkMac...() functions to handle both XMAC and GMAC.
+ *     Added functions for YUKON: SkGmHardRst(), SkGmSoftRst(),
+ *     SkGmSetRxTxEn(), SkGmIrq(), SkGmInitMac(), SkGmInitPhyMarv(),
+ *     SkGmAutoNegDoneMarv(), SkGmPhyRead(), SkGmPhyWrite().
+ *     Changes for V-CPU support.
+ *     Editorial changes.
+ *
+ *     Revision 1.62  2001/08/06 09:50:14  rschmidt
+ *     Workaround BCOM Errata #1 for the C5 type.
+ *     Editorial changes.
+ *
+ *     Revision 1.61  2001/02/09 15:40:59  rassmann
+ *     Editorial changes.
+ *
+ *     Revision 1.60  2001/02/07 15:02:01  cgoos
+ *     Added workaround for Fujitsu switch link down.
+ *
+ *     Revision 1.59  2001/01/10 09:38:06  cgoos
+ *     Fixed Broadcom C0/A1 Id check for workaround.
+ *
+ *     Revision 1.58  2000/11/29 11:30:38  cgoos
+ *     Changed DEBUG sections with NW output to xDEBUG
+ *
+ *     Revision 1.57  2000/11/27 12:40:40  rassmann
+ *     Suppressing preamble after first access to BCom, not before (#10556).
+ *
+ *     Revision 1.56  2000/11/09 12:32:48  rassmann
+ *     Renamed variables.
+ *
+ *     Revision 1.55  2000/11/09 11:30:10  rassmann
+ *     WA: Waiting after releasing reset until BCom chip is accessible.
+ *
+ *     Revision 1.54  2000/10/02 14:10:27  rassmann
+ *     Reading BCOM PHY after releasing reset until it returns a valid value.
+ *
+ *     Revision 1.53  2000/07/27 12:22:11  gklug
+ *     fix: possible endless loop in XmHardRst.
+ *
+ *     Revision 1.52  2000/05/22 08:48:31  malthoff
+ *     Fix: #10523 errata valid for all BCOM PHYs.
+ *
+ *     Revision 1.51  2000/05/17 12:52:18  malthoff
+ *     Fixes BCom link errata (#10523).
+ *
+ *     Revision 1.50  1999/11/22 13:40:14  cgoos
+ *     Changed license header to GPL.
+ *
+ *     Revision 1.49  1999/11/22 08:12:13  malthoff
+ *     Add workaround for power consumption feature of BCom C0 chip.
+ *
+ *     Revision 1.48  1999/11/16 08:39:01  malthoff
+ *     Fix: MDIO preamble suppression is port dependent.
+ *
+ *     Revision 1.47  1999/08/27 08:55:35  malthoff
+ *     1000BT: Optimizing MDIO transfer by oppressing MDIO preamble.
+ *
+ *     Revision 1.46  1999/08/13 11:01:12  malthoff
+ *     Fix for 1000BT: pFlowCtrlMode was not set correctly.
+ *
+ *     Revision 1.45  1999/08/12 19:18:28  malthoff
+ *     1000BT Fixes: Do not owerwrite XM_MMU_CMD.
+ *     Do not execute BCOM A1 workaround for B1 chips.
+ *     Fix pause frame setting.
+ *     Always set PHY_B_AC_TX_TST in PHY_BCOM_AUX_CTRL.
+ *
+ *     Revision 1.44  1999/08/03 15:23:48  cgoos
+ *     Fixed setting of PHY interrupt mask in half duplex mode.
+ *
+ *     Revision 1.43  1999/08/03 15:22:17  cgoos
+ *     Added some debug output.
+ *     Disabled XMac GP0 interrupt for external PHYs.
+ *
+ *     Revision 1.42  1999/08/02 08:39:23  malthoff
+ *     BCOM PHY: TX LED: To get the mono flop behaviour it is required
+ *     to set the LED Traffic Mode bit in PHY_BCOM_P_EXT_CTRL.
+ *
+ *     Revision 1.41  1999/07/30 06:54:31  malthoff
+ *     Add temp. workarounds for the BCOM Phy revision A1.
+ *
+ *     Revision 1.40  1999/06/01 07:43:26  cgoos
+ *     Changed Link Mode Status in SkXmAutoNegDone... from FULL/HALF to
+ *     AUTOFULL/AUTOHALF.
+ *
+ *     Revision 1.39  1999/05/19 07:29:51  cgoos
+ *     Changes for 1000Base-T.
+ *
+ *     Revision 1.38  1999/04/08 14:35:10  malthoff
+ *     Add code for enabling signal detect. Enabling signal detect is disabled.
+ *
+ *     Revision 1.37  1999/03/12 13:42:54  malthoff
+ *     Add: Jumbo Frame Support.
+ *     Add: Receive modes SK_LENERR_OK_ON/OFF and
+ *     SK_BIG_PK_OK_ON/OFF in SkXmSetRxCmd().
+ *
+ *     Revision 1.36  1999/03/08 10:10:55  gklug
+ *     fix: AutoSensing did switch to next mode even if LiPa indicated offline
+ *
+ *     Revision 1.35  1999/02/22 15:16:41  malthoff
+ *     Remove some compiler warnings.
+ *
+ *     Revision 1.34  1999/01/22 09:19:59  gklug
+ *     fix: Init DupMode and InitPauseMd are now called in RxTxEnable
+ *
+ *     Revision 1.33  1998/12/11 15:19:11  gklug
+ *     chg: lipa autoneg stati
+ *     chg: debug messages
+ *     chg: do NOT use spurious XmIrq
+ *
+ *     Revision 1.32  1998/12/10 11:08:44  malthoff
+ *     bug fix: pAC has been used for IOs in SkXmHardRst().
+ *     SkXmInitPhy() is also called for the Diag in SkXmInitMac().
+ *
+ *     Revision 1.31  1998/12/10 10:39:11  gklug
+ *     fix: do 4 RESETS of the XMAC at the beginning
+ *     fix: dummy read interrupt source register BEFORE initializing the Phy
+ *     add: debug messages
+ *     fix: Linkpartners autoneg capability cannot be shown by TX_PAGE interrupt
+ *
+ *     Revision 1.30  1998/12/07 12:18:32  gklug
+ *     add: refinement of autosense mode: take into account the autoneg cap of LiPa
+ *
+ *     Revision 1.29  1998/12/07 07:12:29  gklug
+ *     fix: if page is received the link is  down.
+ *
+ *     Revision 1.28  1998/12/01 10:12:47  gklug
+ *     chg: if spurious IRQ from XMAC encountered, save it
+ *
+ *     Revision 1.27  1998/11/26 07:33:38  gklug
+ *     add: InitPhy call is now in XmInit function
+ *
+ *     Revision 1.26  1998/11/18 13:38:24  malthoff
+ *     'Imsk' is also unused in SkXmAutoNegDone.
+ *
+ *     Revision 1.25  1998/11/18 13:28:01  malthoff
+ *     Remove unused variable 'Reg' in SkXmAutoNegDone().
+ *
+ *     Revision 1.24  1998/11/18 13:18:45  gklug
+ *     add: workaround for xmac errata #1
+ *     add: detect Link Down also when Link partner requested config
+ *     chg: XMIrq is only used when link is up
+ *
+ *     Revision 1.23  1998/11/04 07:07:04  cgoos
+ *     Added function SkXmRxTxEnable.
+ *
+ *     Revision 1.22  1998/10/30 07:35:54  gklug
+ *     fix: serve LinkDown interrupt when link is already down
+ *
+ *     Revision 1.21  1998/10/29 15:32:03  gklug
+ *     fix: Link Down signaling
+ *
+ *     Revision 1.20  1998/10/29 11:17:27  gklug
+ *     fix: AutoNegDone bug
+ *
+ *     Revision 1.19  1998/10/29 10:14:43  malthoff
+ *     Add endainesss comment for reading/writing MAC addresses.
+ *
+ *     Revision 1.18  1998/10/28 07:48:55  cgoos
+ *     Fix: ASS somtimes signaled although link is up.
+ *
+ *     Revision 1.17  1998/10/26 07:55:39  malthoff
+ *     Fix in SkXmInitPauseMd(): Pause Mode
+ *     was disabled and not enabled.
+ *     Fix in SkXmAutoNegDone(): Checking Mode bits
+ *     always failed, becaues of some missing braces.
+ *
+ *     Revision 1.16  1998/10/22 09:46:52  gklug
+ *     fix SysKonnectFileId typo
+ *
+ *     Revision 1.15  1998/10/21 05:51:37  gklug
+ *     add: para DoLoop to InitPhy function for loopback set-up
+ *
+ *     Revision 1.14  1998/10/16 10:59:23  malthoff
+ *     Remove Lint warning for dummy reads.
+ *
+ *     Revision 1.13  1998/10/15 14:01:20  malthoff
+ *     Fix: SkXmAutoNegDone() is (int) but does not return a value.
+ *
+ *     Revision 1.12  1998/10/14 14:45:04  malthoff
+ *     Remove SKERR_SIRQ_E0xx and SKERR_SIRQ_E0xxMSG by
+ *     SKERR_HWI_Exx and SKERR_HWI_E0xxMSG to be independent
+ *     from the Sirq module.
+ *
+ *     Revision 1.11  1998/10/14 13:59:01  gklug
+ *     add: InitPhy function
+ *
+ *     Revision 1.10  1998/10/14 11:20:57  malthoff
+ *     Make SkXmAutoNegDone() public, because it's
+ *     used in diagnostics, too.
+ *     The Link Up event to the RLMT is issued in SkXmIrq().
+ *  SkXmIrq() is not available in diagnostics.
+ *  Use PHY_READ when reading PHY registers.
+ *
+ *     Revision 1.9  1998/10/14 05:50:10  cgoos
+ *     Added definition for Para.
+ *
+ *     Revision 1.8  1998/10/14 05:41:28  gklug
+ *     add: Xmac IRQ
+ *     add: auto-negotiation done function
+ *
+ *     Revision 1.7  1998/10/09 06:55:20  malthoff
+ *     The configuration of the XMACs Tx Request Threshold
+ *     depends from the drivers port usage now. The port
+ *     usage is configured in GIPortUsage.
+ *
+ *     Revision 1.6  1998/10/05 07:48:00  malthoff
+ *     minor changes
+ *
+ *     Revision 1.5  1998/10/01 07:03:54  gklug
+ *     add: dummy function for XMAC ISR
+ *
+ *     Revision 1.4  1998/09/30 12:37:44  malthoff
+ *     Add SkXmSetRxCmd() and related code.
+ *
+ *     Revision 1.3  1998/09/28 13:26:40  malthoff
+ *     Add SkXmInitMac(), SkXmInitDupMd(), and SkXmInitPauseMd()
+ *
+ *     Revision 1.2  1998/09/16 14:34:21  malthoff
+ *     Add SkXmClrExactAddr(), SkXmClrSrcCheck(),
+ *     SkXmClrHashAddr(), SkXmFlushTxFifo(),
+ *     SkXmFlushRxFifo(), and SkXmHardRst().
+ *     Finish Coding of SkXmSoftRst().
+ *     The sources may be compiled now.
+ *
+ *     Revision 1.1  1998/09/04 10:05:56  malthoff
+ *     Created.
+ *
+ *
+ ******************************************************************************/
+
+#include <config.h>
+
+#ifdef CONFIG_SK98
+
+#include "h/skdrv1st.h"
+#include "h/skdrv2nd.h"
+
+/* typedefs *******************************************************************/
+
+/* BCOM PHY magic pattern list */
+typedef struct s_PhyHack {
+       int             PhyReg;         /* Phy register */
+       SK_U16  PhyVal;         /* Value to write */
+} BCOM_HACK;
+
+/* local variables ************************************************************/
+static const char SysKonnectFileId[] =
+       "@(#)$Id: skxmac2.c,v 1.91 2003/02/05 15:09:34 rschmidt Exp $ (C) SK ";
+
+BCOM_HACK BcomRegA1Hack[] = {
+ { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 },
+ { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 },
+ { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 },
+ { 0, 0 }
+};
+BCOM_HACK BcomRegC0Hack[] = {
+ { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 }, { 0x17, 0x0013 },
+ { 0x15, 0x0A04 }, { 0x18, 0x0420 },
+ { 0, 0 }
+};
+
+/* function prototypes ********************************************************/
+static void    SkXmInitPhyXmac(SK_AC*, SK_IOC, int, SK_BOOL);
+static void    SkXmInitPhyBcom(SK_AC*, SK_IOC, int, SK_BOOL);
+static void    SkGmInitPhyMarv(SK_AC*, SK_IOC, int, SK_BOOL);
+static int     SkXmAutoNegDoneXmac(SK_AC*, SK_IOC, int);
+static int     SkXmAutoNegDoneBcom(SK_AC*, SK_IOC, int);
+static int     SkGmAutoNegDoneMarv(SK_AC*, SK_IOC, int);
+#ifdef OTHER_PHY
+static void    SkXmInitPhyLone(SK_AC*, SK_IOC, int, SK_BOOL);
+static void    SkXmInitPhyNat (SK_AC*, SK_IOC, int, SK_BOOL);
+static int     SkXmAutoNegDoneLone(SK_AC*, SK_IOC, int);
+static int     SkXmAutoNegDoneNat (SK_AC*, SK_IOC, int);
+#endif /* OTHER_PHY */
+
+
+/******************************************************************************
+ *
+ *     SkXmPhyRead() - Read from XMAC PHY register
+ *
+ * Description:        reads a 16-bit word from XMAC PHY or ext. PHY
+ *
+ * Returns:
+ *     nothing
+ */
+void SkXmPhyRead(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* I/O Context */
+int            Port,           /* Port Index (MAC_1 + n) */
+int            PhyReg,         /* Register Address (Offset) */
+SK_U16 *pVal)          /* Pointer to Value */
+{
+       SK_U16          Mmu;
+       SK_GEPORT       *pPrt;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       /* write the PHY register's address */
+       XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
+
+       /* get the PHY register's value */
+       XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
+
+       if (pPrt->PhyType != SK_PHY_XMAC) {
+               do {
+                       XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
+                       /* wait until 'Ready' is set */
+               } while ((Mmu & XM_MMU_PHY_RDY) == 0);
+
+               /* get the PHY register's value */
+               XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
+       }
+}      /* SkXmPhyRead */
+
+
+/******************************************************************************
+ *
+ *     SkXmPhyWrite() - Write to XMAC PHY register
+ *
+ * Description:        writes a 16-bit word to XMAC PHY or ext. PHY
+ *
+ * Returns:
+ *     nothing
+ */
+void SkXmPhyWrite(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* I/O Context */
+int            Port,           /* Port Index (MAC_1 + n) */
+int            PhyReg,         /* Register Address (Offset) */
+SK_U16 Val)            /* Value */
+{
+       SK_U16          Mmu;
+       SK_GEPORT       *pPrt;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       if (pPrt->PhyType != SK_PHY_XMAC) {
+               do {
+                       XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
+                       /* wait until 'Busy' is cleared */
+               } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
+       }
+
+       /* write the PHY register's address */
+       XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
+
+       /* write the PHY register's value */
+       XM_OUT16(IoC, Port, XM_PHY_DATA, Val);
+
+       if (pPrt->PhyType != SK_PHY_XMAC) {
+               do {
+                       XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
+                       /* wait until 'Busy' is cleared */
+               } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
+       }
+}      /* SkXmPhyWrite */
+
+
+/******************************************************************************
+ *
+ *     SkGmPhyRead() - Read from GPHY register
+ *
+ * Description:        reads a 16-bit word from GPHY through MDIO
+ *
+ * Returns:
+ *     nothing
+ */
+void SkGmPhyRead(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* I/O Context */
+int            Port,           /* Port Index (MAC_1 + n) */
+int            PhyReg,         /* Register Address (Offset) */
+SK_U16 *pVal)          /* Pointer to Value */
+{
+       SK_U16  Ctrl;
+       SK_GEPORT       *pPrt;
+#ifdef VCPU
+       u_long SimCyle;
+       u_long SimLowTime;
+
+       VCPUgetTime(&SimCyle, &SimLowTime);
+       VCPUprintf(0, "SkGmPhyRead(%u), SimCyle=%u, SimLowTime=%u\n",
+               PhyReg, SimCyle, SimLowTime);
+#endif /* VCPU */
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       /* set PHY-Register offset and 'Read' OpCode (= 1) */
+       *pVal = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) |
+               GM_SMI_CT_REG_AD(PhyReg) | GM_SMI_CT_OP_RD);
+
+       GM_OUT16(IoC, Port, GM_SMI_CTRL, *pVal);
+
+       GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
+
+       /* additional check for MDC/MDIO activity */
+       if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
+               *pVal = 0;
+               return;
+       }
+
+       *pVal |= GM_SMI_CT_BUSY;
+
+       do {
+#ifdef VCPU
+               VCPUwaitTime(1000);
+#endif /* VCPU */
+
+               GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
+
+       /* wait until 'ReadValid' is set */
+       } while (Ctrl == *pVal);
+
+       /* get the PHY register's value */
+       GM_IN16(IoC, Port, GM_SMI_DATA, pVal);
+
+#ifdef VCPU
+       VCPUgetTime(&SimCyle, &SimLowTime);
+       VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
+               SimCyle, SimLowTime);
+#endif /* VCPU */
+}      /* SkGmPhyRead */
+
+
+/******************************************************************************
+ *
+ *     SkGmPhyWrite() - Write to GPHY register
+ *
+ * Description:        writes a 16-bit word to GPHY through MDIO
+ *
+ * Returns:
+ *     nothing
+ */
+void SkGmPhyWrite(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* I/O Context */
+int            Port,           /* Port Index (MAC_1 + n) */
+int            PhyReg,         /* Register Address (Offset) */
+SK_U16 Val)            /* Value */
+{
+       SK_U16  Ctrl;
+       SK_GEPORT       *pPrt;
+#ifdef VCPU
+       SK_U32  DWord;
+       u_long  SimCyle;
+       u_long  SimLowTime;
+
+       VCPUgetTime(&SimCyle, &SimLowTime);
+       VCPUprintf(0, "SkGmPhyWrite(Reg=%u, Val=0x%04x), SimCyle=%u, SimLowTime=%u\n",
+               PhyReg, Val, SimCyle, SimLowTime);
+#endif /* VCPU */
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       /* write the PHY register's value */
+       GM_OUT16(IoC, Port, GM_SMI_DATA, Val);
+
+       /* set PHY-Register offset and 'Write' OpCode (= 0) */
+       Val = GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg);
+
+       GM_OUT16(IoC, Port, GM_SMI_CTRL, Val);
+
+       GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
+
+       /* additional check for MDC/MDIO activity */
+       if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
+               return;
+       }
+
+       Val |= GM_SMI_CT_BUSY;
+
+       do {
+#ifdef VCPU
+               /* read Timer value */
+               SK_IN32(IoC, B2_TI_VAL, &DWord);
+
+               VCPUwaitTime(1000);
+#endif /* VCPU */
+
+               GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
+
+       /* wait until 'Busy' is cleared */
+       } while (Ctrl == Val);
+
+#ifdef VCPU
+       VCPUgetTime(&SimCyle, &SimLowTime);
+       VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
+               SimCyle, SimLowTime);
+#endif /* VCPU */
+}      /* SkGmPhyWrite */
+
+
+/******************************************************************************
+ *
+ *     SkGePhyRead() - Read from PHY register
+ *
+ * Description:        calls a read PHY routine dep. on board type
+ *
+ * Returns:
+ *     nothing
+ */
+void SkGePhyRead(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* I/O Context */
+int            Port,           /* Port Index (MAC_1 + n) */
+int            PhyReg,         /* Register Address (Offset) */
+SK_U16 *pVal)          /* Pointer to Value */
+{
+       void (*r_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 *pVal);
+
+       if (pAC->GIni.GIGenesis) {
+               r_func = SkXmPhyRead;
+       }
+       else {
+               r_func = SkGmPhyRead;
+       }
+
+       r_func(pAC, IoC, Port, PhyReg, pVal);
+}      /* SkGePhyRead */
+
+
+/******************************************************************************
+ *
+ *     SkGePhyWrite() - Write to PHY register
+ *
+ * Description:        calls a write PHY routine dep. on board type
+ *
+ * Returns:
+ *     nothing
+ */
+void SkGePhyWrite(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* I/O Context */
+int            Port,           /* Port Index (MAC_1 + n) */
+int            PhyReg,         /* Register Address (Offset) */
+SK_U16 Val)            /* Value */
+{
+       void (*w_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 Val);
+
+       if (pAC->GIni.GIGenesis) {
+               w_func = SkXmPhyWrite;
+       }
+       else {
+               w_func = SkGmPhyWrite;
+       }
+
+       w_func(pAC, IoC, Port, PhyReg, Val);
+}      /* SkGePhyWrite */
+
+
+/******************************************************************************
+ *
+ *     SkMacPromiscMode() - Enable / Disable Promiscuous Mode
+ *
+ * Description:
+ *   enables / disables promiscuous mode by setting Mode Register (XMAC) or
+ *   Receive Control Register (GMAC) dep. on board type
+ *
+ * Returns:
+ *     nothing
+ */
+void SkMacPromiscMode(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* IO context */
+int            Port,   /* Port Index (MAC_1 + n) */
+SK_BOOL        Enable) /* Enable / Disable */
+{
+       SK_U16  RcReg;
+       SK_U32  MdReg;
+
+       if (pAC->GIni.GIGenesis) {
+
+               XM_IN32(IoC, Port, XM_MODE, &MdReg);
+               /* enable or disable promiscuous mode */
+               if (Enable) {
+                       MdReg |= XM_MD_ENA_PROM;
+               }
+               else {
+                       MdReg &= ~XM_MD_ENA_PROM;
+               }
+               /* setup Mode Register */
+               XM_OUT32(IoC, Port, XM_MODE, MdReg);
+       }
+       else {
+
+               GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
+
+               /* enable or disable unicast and multicast filtering */
+               if (Enable) {
+                       RcReg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
+               }
+               else {
+                       RcReg |= (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
+               }
+               /* setup Receive Control Register */
+               GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);
+       }
+}      /* SkMacPromiscMode*/
+
+
+/******************************************************************************
+ *
+ *     SkMacHashing() - Enable / Disable Hashing
+ *
+ * Description:
+ *   enables / disables hashing by setting Mode Register (XMAC) or
+ *   Receive Control Register (GMAC) dep. on board type
+ *
+ * Returns:
+ *     nothing
+ */
+void SkMacHashing(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* IO context */
+int            Port,   /* Port Index (MAC_1 + n) */
+SK_BOOL        Enable) /* Enable / Disable */
+{
+       SK_U16  RcReg;
+       SK_U32  MdReg;
+
+       if (pAC->GIni.GIGenesis) {
+
+               XM_IN32(IoC, Port, XM_MODE, &MdReg);
+               /* enable or disable hashing */
+               if (Enable) {
+                       MdReg |= XM_MD_ENA_HASH;
+               }
+               else {
+                       MdReg &= ~XM_MD_ENA_HASH;
+               }
+               /* setup Mode Register */
+               XM_OUT32(IoC, Port, XM_MODE, MdReg);
+       }
+       else {
+
+               GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
+
+               /* enable or disable multicast filtering */
+               if (Enable) {
+                       RcReg |= GM_RXCR_MCF_ENA;
+               }
+               else {
+                       RcReg &= ~GM_RXCR_MCF_ENA;
+               }
+               /* setup Receive Control Register */
+               GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);
+       }
+}      /* SkMacHashing*/
+
+
+#ifdef SK_DIAG
+/******************************************************************************
+ *
+ *     SkXmSetRxCmd() - Modify the value of the XMAC's Rx Command Register
+ *
+ * Description:
+ *     The features
+ *      - FCS stripping,                                       SK_STRIP_FCS_ON/OFF
+ *      - pad byte stripping,                          SK_STRIP_PAD_ON/OFF
+ *      - don't set XMR_FS_ERR in status       SK_LENERR_OK_ON/OFF
+ *        for inrange length error frames
+ *      - don't set XMR_FS_ERR in status       SK_BIG_PK_OK_ON/OFF
+ *        for frames > 1514 bytes
+ *   - enable Rx of own packets         SK_SELF_RX_ON/OFF
+ *
+ *     for incoming packets may be enabled/disabled by this function.
+ *     Additional modes may be added later.
+ *     Multiple modes can be enabled/disabled at the same time.
+ *     The new configuration is written to the Rx Command register immediately.
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkXmSetRxCmd(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+int            Mode)           /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
+                                          SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
+{
+       SK_U16  OldRxCmd;
+       SK_U16  RxCmd;
+
+       XM_IN16(IoC, Port, XM_RX_CMD, &OldRxCmd);
+
+       RxCmd = OldRxCmd;
+
+       switch (Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) {
+       case SK_STRIP_FCS_ON:
+               RxCmd |= XM_RX_STRIP_FCS;
+               break;
+       case SK_STRIP_FCS_OFF:
+               RxCmd &= ~XM_RX_STRIP_FCS;
+               break;
+       }
+
+       switch (Mode & (SK_STRIP_PAD_ON | SK_STRIP_PAD_OFF)) {
+       case SK_STRIP_PAD_ON:
+               RxCmd |= XM_RX_STRIP_PAD;
+               break;
+       case SK_STRIP_PAD_OFF:
+               RxCmd &= ~XM_RX_STRIP_PAD;
+               break;
+       }
+
+       switch (Mode & (SK_LENERR_OK_ON | SK_LENERR_OK_OFF)) {
+       case SK_LENERR_OK_ON:
+               RxCmd |= XM_RX_LENERR_OK;
+               break;
+       case SK_LENERR_OK_OFF:
+               RxCmd &= ~XM_RX_LENERR_OK;
+               break;
+       }
+
+       switch (Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) {
+       case SK_BIG_PK_OK_ON:
+               RxCmd |= XM_RX_BIG_PK_OK;
+               break;
+       case SK_BIG_PK_OK_OFF:
+               RxCmd &= ~XM_RX_BIG_PK_OK;
+               break;
+       }
+
+       switch (Mode & (SK_SELF_RX_ON | SK_SELF_RX_OFF)) {
+       case SK_SELF_RX_ON:
+               RxCmd |= XM_RX_SELF_RX;
+               break;
+       case SK_SELF_RX_OFF:
+               RxCmd &= ~XM_RX_SELF_RX;
+               break;
+       }
+
+       /* Write the new mode to the Rx command register if required */
+       if (OldRxCmd != RxCmd) {
+               XM_OUT16(IoC, Port, XM_RX_CMD, RxCmd);
+       }
+}      /* SkXmSetRxCmd */
+
+
+/******************************************************************************
+ *
+ *     SkGmSetRxCmd() - Modify the value of the GMAC's Rx Control Register
+ *
+ * Description:
+ *     The features
+ *      - FCS (CRC) stripping,                         SK_STRIP_FCS_ON/OFF
+ *      - don't set GMR_FS_LONG_ERR            SK_BIG_PK_OK_ON/OFF
+ *        for frames > 1514 bytes
+ *   - enable Rx of own packets         SK_SELF_RX_ON/OFF
+ *
+ *     for incoming packets may be enabled/disabled by this function.
+ *     Additional modes may be added later.
+ *     Multiple modes can be enabled/disabled at the same time.
+ *     The new configuration is written to the Rx Command register immediately.
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkGmSetRxCmd(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+int            Mode)           /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
+                                          SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
+{
+       SK_U16  OldRxCmd;
+       SK_U16  RxCmd;
+
+       if ((Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) != 0) {
+
+               GM_IN16(IoC, Port, GM_RX_CTRL, &OldRxCmd);
+
+               RxCmd = OldRxCmd;
+
+               if ((Mode & SK_STRIP_FCS_ON) != 0) {
+                       RxCmd |= GM_RXCR_CRC_DIS;
+               }
+               else {
+                       RxCmd &= ~GM_RXCR_CRC_DIS;
+               }
+               /* Write the new mode to the Rx control register if required */
+               if (OldRxCmd != RxCmd) {
+                       GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd);
+               }
+       }
+
+       if ((Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) != 0) {
+
+               GM_IN16(IoC, Port, GM_SERIAL_MODE, &OldRxCmd);
+
+               RxCmd = OldRxCmd;
+
+               if ((Mode & SK_BIG_PK_OK_ON) != 0) {
+                       RxCmd |= GM_SMOD_JUMBO_ENA;
+               }
+               else {
+                       RxCmd &= ~GM_SMOD_JUMBO_ENA;
+               }
+               /* Write the new mode to the Rx control register if required */
+               if (OldRxCmd != RxCmd) {
+                       GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd);
+               }
+       }
+}      /* SkGmSetRxCmd */
+
+
+/******************************************************************************
+ *
+ *     SkMacSetRxCmd() - Modify the value of the MAC's Rx Control Register
+ *
+ * Description:        modifies the MAC's Rx Control reg. dep. on board type
+ *
+ * Returns:
+ *     nothing
+ */
+void SkMacSetRxCmd(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+int            Mode)           /* Rx Mode */
+{
+       if (pAC->GIni.GIGenesis) {
+
+               SkXmSetRxCmd(pAC, IoC, Port, Mode);
+       }
+       else {
+
+               SkGmSetRxCmd(pAC, IoC, Port, Mode);
+       }
+}      /* SkMacSetRxCmd */
+
+
+/******************************************************************************
+ *
+ *     SkMacCrcGener() - Enable / Disable CRC Generation
+ *
+ * Description:        enables / disables CRC generation dep. on board type
+ *
+ * Returns:
+ *     nothing
+ */
+void SkMacCrcGener(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* IO context */
+int            Port,   /* Port Index (MAC_1 + n) */
+SK_BOOL        Enable) /* Enable / Disable */
+{
+       SK_U16  Word;
+
+       if (pAC->GIni.GIGenesis) {
+
+               XM_IN16(IoC, Port, XM_TX_CMD, &Word);
+
+               if (Enable) {
+                       Word &= ~XM_TX_NO_CRC;
+               }
+               else {
+                       Word |= XM_TX_NO_CRC;
+               }
+               /* setup Tx Command Register */
+               XM_OUT16(pAC, Port, XM_TX_CMD, Word);
+       }
+       else {
+
+               GM_IN16(IoC, Port, GM_TX_CTRL, &Word);
+
+               if (Enable) {
+                       Word &= ~GM_TXCR_CRC_DIS;
+               }
+               else {
+                       Word |= GM_TXCR_CRC_DIS;
+               }
+               /* setup Tx Control Register */
+               GM_OUT16(IoC, Port, GM_TX_CTRL, Word);
+       }
+}      /* SkMacCrcGener*/
+
+#endif /* SK_DIAG */
+
+
+/******************************************************************************
+ *
+ *     SkXmClrExactAddr() - Clear Exact Match Address Registers
+ *
+ * Description:
+ *     All Exact Match Address registers of the XMAC 'Port' will be
+ *     cleared starting with 'StartNum' up to (and including) the
+ *     Exact Match address number of 'StopNum'.
+ *
+ * Returns:
+ *     nothing
+ */
+void SkXmClrExactAddr(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+int            StartNum,       /* Begin with this Address Register Index (0..15) */
+int            StopNum)        /* Stop after finished with this Register Idx (0..15) */
+{
+       int             i;
+       SK_U16  ZeroAddr[3] = {0x0000, 0x0000, 0x0000};
+
+       if ((unsigned)StartNum > 15 || (unsigned)StopNum > 15 ||
+               StartNum > StopNum) {
+
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E001, SKERR_HWI_E001MSG);
+               return;
+       }
+
+       for (i = StartNum; i <= StopNum; i++) {
+               XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]);
+       }
+}      /* SkXmClrExactAddr */
+
+
+/******************************************************************************
+ *
+ *     SkMacFlushTxFifo() - Flush the MAC's transmit FIFO
+ *
+ * Description:
+ *     Flush the transmit FIFO of the MAC specified by the index 'Port'
+ *
+ * Returns:
+ *     nothing
+ */
+void SkMacFlushTxFifo(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* IO context */
+int            Port)   /* Port Index (MAC_1 + n) */
+{
+       SK_U32  MdReg;
+
+       if (pAC->GIni.GIGenesis) {
+
+               XM_IN32(IoC, Port, XM_MODE, &MdReg);
+
+               XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FTF);
+       }
+       else {
+               /* no way to flush the FIFO we have to issue a reset */
+               /* TBD */
+       }
+}      /* SkMacFlushTxFifo */
+
+
+/******************************************************************************
+ *
+ *     SkMacFlushRxFifo() - Flush the MAC's receive FIFO
+ *
+ * Description:
+ *     Flush the receive FIFO of the MAC specified by the index 'Port'
+ *
+ * Returns:
+ *     nothing
+ */
+void SkMacFlushRxFifo(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* IO context */
+int            Port)   /* Port Index (MAC_1 + n) */
+{
+       SK_U32  MdReg;
+
+       if (pAC->GIni.GIGenesis) {
+
+               XM_IN32(IoC, Port, XM_MODE, &MdReg);
+
+               XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FRF);
+       }
+       else {
+               /* no way to flush the FIFO we have to issue a reset */
+               /* TBD */
+       }
+}      /* SkMacFlushRxFifo */
+
+
+/******************************************************************************
+ *
+ *     SkXmSoftRst() - Do a XMAC software reset
+ *
+ * Description:
+ *     The PHY registers should not be destroyed during this
+ *     kind of software reset. Therefore the XMAC Software Reset
+ *     (XM_GP_RES_MAC bit in XM_GP_PORT) must not be used!
+ *
+ *     The software reset is done by
+ *             - disabling the Rx and Tx state machine,
+ *             - resetting the statistics module,
+ *             - clear all other significant XMAC Mode,
+ *               Command, and Control Registers
+ *             - clearing the Hash Register and the
+ *               Exact Match Address registers, and
+ *             - flushing the XMAC's Rx and Tx FIFOs.
+ *
+ * Note:
+ *     Another requirement when stopping the XMAC is to
+ *     avoid sending corrupted frames on the network.
+ *     Disabling the Tx state machine will NOT interrupt
+ *     the currently transmitted frame. But we must take care
+ *     that the Tx FIFO is cleared AFTER the current frame
+ *     is complete sent to the network.
+ *
+ *     It takes about 12ns to send a frame with 1538 bytes.
+ *     One PCI clock goes at least 15ns (66MHz). Therefore
+ *     after reading XM_GP_PORT back, we are sure that the
+ *     transmitter is disabled AND idle. And this means
+ *     we may flush the transmit FIFO now.
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkXmSoftRst(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* IO context */
+int            Port)   /* Port Index (MAC_1 + n) */
+{
+       SK_U16  ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000};
+
+       /* reset the statistics module */
+       XM_OUT32(IoC, Port, XM_GP_PORT, XM_GP_RES_STAT);
+
+       /* disable all XMAC IRQs */
+       XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
+
+       XM_OUT32(IoC, Port, XM_MODE, 0);                /* clear Mode Reg */
+
+       XM_OUT16(IoC, Port, XM_TX_CMD, 0);              /* reset TX CMD Reg */
+       XM_OUT16(IoC, Port, XM_RX_CMD, 0);              /* reset RX CMD Reg */
+
+       /* disable all PHY IRQs */
+       switch (pAC->GIni.GP[Port].PhyType) {
+       case SK_PHY_BCOM:
+                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff);
+                       break;
+#ifdef OTHER_PHY
+               case SK_PHY_LONE:
+                       SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0);
+                       break;
+               case SK_PHY_NAT:
+                       /* todo: National
+                        SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */
+                       break;
+#endif /* OTHER_PHY */
+       }
+
+       /* clear the Hash Register */
+       XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr);
+
+       /* clear the Exact Match Address registers */
+       SkXmClrExactAddr(pAC, IoC, Port, 0, 15);
+
+       /* clear the Source Check Address registers */
+       XM_OUTHASH(IoC, Port, XM_SRC_CHK, &ZeroAddr);
+
+}      /* SkXmSoftRst */
+
+
+/******************************************************************************
+ *
+ *     SkXmHardRst() - Do a XMAC hardware reset
+ *
+ * Description:
+ *     The XMAC of the specified 'Port' and all connected devices
+ *     (PHY and SERDES) will receive a reset signal on its *Reset pins.
+ *     External PHYs must be reset be clearing a bit in the GPIO register
+ *  (Timing requirements: Broadcom: 400ns, Level One: none, National: 80ns).
+ *
+ * ATTENTION:
+ *     It is absolutely necessary to reset the SW_RST Bit first
+ *     before calling this function.
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkXmHardRst(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* IO context */
+int            Port)   /* Port Index (MAC_1 + n) */
+{
+       SK_U32  Reg;
+       int             i;
+       int             TOut;
+       SK_U16  Word;
+
+       for (i = 0; i < 4; i++) {
+               /* TX_MFF_CTRL1 has 32 bits, but only the lowest 16 bits are used */
+               SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
+
+               TOut = 0;
+               do {
+                       if (TOut++ > 10000) {
+                               /*
+                                * Adapter seems to be in RESET state.
+                                * Registers cannot be written.
+                                */
+                               return;
+                       }
+
+                       SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
+
+                       SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &Word);
+
+               } while ((Word & MFF_SET_MAC_RST) == 0);
+       }
+
+       /* For external PHYs there must be special handling */
+       if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
+               /* reset external PHY */
+               SK_IN32(IoC, B2_GP_IO, &Reg);
+               if (Port == 0) {
+                       Reg |= GP_DIR_0; /* set to output */
+                       Reg &= ~GP_IO_0;
+               }
+               else {
+                       Reg |= GP_DIR_2; /* set to output */
+                       Reg &= ~GP_IO_2;
+               }
+               SK_OUT32(IoC, B2_GP_IO, Reg);
+
+               /* short delay */
+               SK_IN32(IoC, B2_GP_IO, &Reg);
+       }
+
+}      /* SkXmHardRst */
+
+
+/******************************************************************************
+ *
+ *     SkGmSoftRst() - Do a GMAC software reset
+ *
+ * Description:
+ *     The GPHY registers should not be destroyed during this
+ *     kind of software reset.
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkGmSoftRst(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* IO context */
+int            Port)   /* Port Index (MAC_1 + n) */
+{
+       SK_U16  EmptyHash[4] = {0x0000, 0x0000, 0x0000, 0x0000};
+       SK_U16  RxCtrl;
+
+       /* reset the statistics module */
+
+       /* disable all GMAC IRQs */
+       SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
+
+       /* disable all PHY IRQs */
+       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
+
+       /* clear the Hash Register */
+       GM_OUTHASH(IoC, Port, GM_MC_ADDR_H1, EmptyHash);
+
+       /* Enable Unicast and Multicast filtering */
+       GM_IN16(IoC, Port, GM_RX_CTRL, &RxCtrl);
+
+       GM_OUT16(IoC, Port, GM_RX_CTRL,
+               RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
+
+}      /* SkGmSoftRst */
+
+
+/******************************************************************************
+ *
+ *     SkGmHardRst() - Do a GMAC hardware reset
+ *
+ * Description:
+ *
+ * ATTENTION:
+ *     It is absolutely necessary to reset the SW_RST Bit first
+ *     before calling this function.
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkGmHardRst(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* IO context */
+int            Port)   /* Port Index (MAC_1 + n) */
+{
+       /* set GPHY Control reset */
+       SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
+
+       /* set GMAC Control reset */
+       SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
+
+}      /* SkGmHardRst */
+
+
+/******************************************************************************
+ *
+ *     SkMacSoftRst() - Do a MAC software reset
+ *
+ * Description:        calls a MAC software reset routine dep. on board type
+ *
+ * Returns:
+ *     nothing
+ */
+void SkMacSoftRst(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* IO context */
+int            Port)   /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       /* disable receiver and transmitter */
+       SkMacRxTxDisable(pAC, IoC, Port);
+
+       if (pAC->GIni.GIGenesis) {
+
+               SkXmSoftRst(pAC, IoC, Port);
+       }
+       else {
+
+               SkGmSoftRst(pAC, IoC, Port);
+       }
+
+       /* flush the MAC's Rx and Tx FIFOs */
+       SkMacFlushTxFifo(pAC, IoC, Port);
+
+       SkMacFlushRxFifo(pAC, IoC, Port);
+
+       pPrt->PState = SK_PRT_STOP;
+
+}      /* SkMacSoftRst */
+
+
+/******************************************************************************
+ *
+ *     SkMacHardRst() - Do a MAC hardware reset
+ *
+ * Description:        calls a MAC hardware reset routine dep. on board type
+ *
+ * Returns:
+ *     nothing
+ */
+void SkMacHardRst(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* IO context */
+int            Port)   /* Port Index (MAC_1 + n) */
+{
+
+       if (pAC->GIni.GIGenesis) {
+
+               SkXmHardRst(pAC, IoC, Port);
+       }
+       else {
+
+               SkGmHardRst(pAC, IoC, Port);
+       }
+
+       pAC->GIni.GP[Port].PState = SK_PRT_RESET;
+
+}      /* SkMacHardRst */
+
+
+/******************************************************************************
+ *
+ *     SkXmInitMac() - Initialize the XMAC II
+ *
+ * Description:
+ *     Initialize the XMAC of the specified port.
+ *     The XMAC must be reset or stopped before calling this function.
+ *
+ * Note:
+ *     The XMAC's Rx and Tx state machine is still disabled when returning.
+ *
+ * Returns:
+ *     nothing
+ */
+void SkXmInitMac(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;
+       SK_U32          Reg;
+       int                     i;
+       SK_U16          SWord;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       if (pPrt->PState == SK_PRT_STOP) {
+               /* Port State: SK_PRT_STOP */
+               /* Verify that the reset bit is cleared */
+               SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
+
+               if ((SWord & MFF_SET_MAC_RST) != 0) {
+                       /* PState does not match HW state */
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
+                       /* Correct it */
+                       pPrt->PState = SK_PRT_RESET;
+               }
+       }
+
+       if (pPrt->PState == SK_PRT_RESET) {
+               /*
+                * clear HW reset
+                * Note: The SW reset is self clearing, therefore there is
+                *       nothing to do here.
+                */
+               SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
+
+               /* Ensure that XMAC reset release is done (errata from LReinbold?) */
+               SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
+
+               /* Clear PHY reset */
+               if (pPrt->PhyType != SK_PHY_XMAC) {
+
+                       SK_IN32(IoC, B2_GP_IO, &Reg);
+
+                       if (Port == 0) {
+                               Reg |= (GP_DIR_0 | GP_IO_0); /* set to output */
+                       }
+                       else {
+                               Reg |= (GP_DIR_2 | GP_IO_2); /* set to output */
+                       }
+                       SK_OUT32(IoC, B2_GP_IO, Reg);
+
+                       /* Enable GMII interface */
+                       XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);
+
+                       /* read Id from external PHY (all have the same address) */
+                       SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_ID1, &pPrt->PhyId1);
+
+                       /*
+                        * Optimize MDIO transfer by suppressing preamble.
+                        * Must be done AFTER first access to BCOM chip.
+                        */
+                       XM_IN16(IoC, Port, XM_MMU_CMD, &SWord);
+
+                       XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE);
+
+                       if (pPrt->PhyId1 == PHY_BCOM_ID1_C0) {
+                               /*
+                                * Workaround BCOM Errata for the C0 type.
+                                * Write magic patterns to reserved registers.
+                                */
+                               i = 0;
+                               while (BcomRegC0Hack[i].PhyReg != 0) {
+                                       SkXmPhyWrite(pAC, IoC, Port, BcomRegC0Hack[i].PhyReg,
+                                               BcomRegC0Hack[i].PhyVal);
+                                       i++;
+                               }
+                       }
+                       else if (pPrt->PhyId1 == PHY_BCOM_ID1_A1) {
+                               /*
+                                * Workaround BCOM Errata for the A1 type.
+                                * Write magic patterns to reserved registers.
+                                */
+                               i = 0;
+                               while (BcomRegA1Hack[i].PhyReg != 0) {
+                                       SkXmPhyWrite(pAC, IoC, Port, BcomRegA1Hack[i].PhyReg,
+                                               BcomRegA1Hack[i].PhyVal);
+                                       i++;
+                               }
+                       }
+
+                       /*
+                        * Workaround BCOM Errata (#10523) for all BCom PHYs.
+                        * Disable Power Management after reset.
+                        */
+                       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
+
+                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
+                               (SK_U16)(SWord | PHY_B_AC_DIS_PM));
+
+                       /* PHY LED initialization is done in SkGeXmitLED() */
+               }
+
+               /* Dummy read the Interrupt source register */
+               XM_IN16(IoC, Port, XM_ISRC, &SWord);
+
+               /*
+                * The auto-negotiation process starts immediately after
+                * clearing the reset. The auto-negotiation process should be
+                * started by the SIRQ, therefore stop it here immediately.
+                */
+               SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
+
+#if 0
+               /* temp. code: enable signal detect */
+               /* WARNING: do not override GMII setting above */
+               XM_OUT16(pAC, Port, XM_HW_CFG, XM_HW_COM4SIG);
+#endif
+       }
+
+       /*
+        * configure the XMACs Station Address
+        * B2_MAC_2 = xx xx xx xx xx x1 is programmed to XMAC A
+        * B2_MAC_3 = xx xx xx xx xx x2 is programmed to XMAC B
+        */
+       for (i = 0; i < 3; i++) {
+               /*
+                * The following 2 statements are together endianess
+                * independent. Remember this when changing.
+                */
+               SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
+
+               XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord);
+       }
+
+       /* Tx Inter Packet Gap (XM_TX_IPG):     use default */
+       /* Tx High Water Mark (XM_TX_HI_WM):    use default */
+       /* Tx Low Water Mark (XM_TX_LO_WM):     use default */
+       /* Host Request Threshold (XM_HT_THR):  use default */
+       /* Rx Request Threshold (XM_RX_THR):    use default */
+       /* Rx Low Water Mark (XM_RX_LO_WM):     use default */
+
+       /* configure Rx High Water Mark (XM_RX_HI_WM) */
+       XM_OUT16(IoC, Port, XM_RX_HI_WM, SK_XM_RX_HI_WM);
+
+       /* Configure Tx Request Threshold */
+       SWord = SK_XM_THR_SL;                           /* for single port */
+
+       if (pAC->GIni.GIMacsFound > 1) {
+               switch (pAC->GIni.GIPortUsage) {
+               case SK_RED_LINK:
+                       SWord = SK_XM_THR_REDL;         /* redundant link */
+                       break;
+               case SK_MUL_LINK:
+                       SWord = SK_XM_THR_MULL;         /* load balancing */
+                       break;
+               case SK_JUMBO_LINK:
+                       SWord = SK_XM_THR_JUMBO;        /* jumbo frames */
+                       break;
+               default:
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E014, SKERR_HWI_E014MSG);
+                       break;
+               }
+       }
+       XM_OUT16(IoC, Port, XM_TX_THR, SWord);
+
+       /* setup register defaults for the Tx Command Register */
+       XM_OUT16(IoC, Port, XM_TX_CMD, XM_TX_AUTO_PAD);
+
+       /* setup register defaults for the Rx Command Register */
+       SWord = XM_RX_STRIP_FCS | XM_RX_LENERR_OK;
+
+       if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
+               SWord |= XM_RX_BIG_PK_OK;
+       }
+
+       if (pPrt->PLinkModeConf == SK_LMODE_HALF) {
+               /*
+                * If in manual half duplex mode the other side might be in
+                * full duplex mode, so ignore if a carrier extension is not seen
+                * on frames received
+                */
+               SWord |= XM_RX_DIS_CEXT;
+       }
+
+       XM_OUT16(IoC, Port, XM_RX_CMD, SWord);
+
+       /*
+        * setup register defaults for the Mode Register
+        *      - Don't strip error frames to avoid Store & Forward
+        *        on the Rx side.
+        *      - Enable 'Check Station Address' bit
+        *      - Enable 'Check Address Array' bit
+        */
+       XM_OUT32(IoC, Port, XM_MODE, XM_DEF_MODE);
+
+       /*
+        * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)
+        *      - Enable all bits excepting 'Octets Rx OK Low CntOv'
+        *        and 'Octets Rx OK Hi Cnt Ov'.
+        */
+       XM_OUT32(IoC, Port, XM_RX_EV_MSK, XMR_DEF_MSK);
+
+       /*
+        * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)
+        *      - Enable all bits excepting 'Octets Tx OK Low CntOv'
+        *        and 'Octets Tx OK Hi Cnt Ov'.
+        */
+       XM_OUT32(IoC, Port, XM_TX_EV_MSK, XMT_DEF_MSK);
+
+       /*
+        * Do NOT init XMAC interrupt mask here.
+        * All interrupts remain disable until link comes up!
+        */
+
+       /*
+        * Any additional configuration changes may be done now.
+        * The last action is to enable the Rx and Tx state machine.
+        * This should be done after the auto-negotiation process
+        * has been completed successfully.
+        */
+}      /* SkXmInitMac */
+
+/******************************************************************************
+ *
+ *     SkGmInitMac() - Initialize the GMAC
+ *
+ * Description:
+ *     Initialize the GMAC of the specified port.
+ *     The GMAC must be reset or stopped before calling this function.
+ *
+ * Note:
+ *     The GMAC's Rx and Tx state machine is still disabled when returning.
+ *
+ * Returns:
+ *     nothing
+ */
+void SkGmInitMac(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;
+       int                     i;
+       SK_U16          SWord;
+       SK_U32          DWord;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       if (pPrt->PState == SK_PRT_STOP) {
+               /* Port State: SK_PRT_STOP */
+               /* Verify that the reset bit is cleared */
+               SK_IN32(IoC, MR_ADDR(Port, GMAC_CTRL), &DWord);
+
+               if ((DWord & GMC_RST_SET) != 0) {
+                       /* PState does not match HW state */
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
+                       /* Correct it */
+                       pPrt->PState = SK_PRT_RESET;
+               }
+       }
+
+       if (pPrt->PState == SK_PRT_RESET) {
+               /* set GPHY Control reset */
+               SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
+
+               /* set GMAC Control reset */
+               SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
+
+               /* clear GMAC Control reset */
+               SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR);
+
+               /* set GMAC Control reset */
+               SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
+
+               /* set HWCFG_MODE */
+               DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
+                       GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
+                       (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
+                       GPC_HWCFG_GMII_FIB);
+
+               /* set GPHY Control reset */
+               SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
+
+               /* release GPHY Control reset */
+               SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
+
+               /* clear GMAC Control reset */
+               SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
+
+               /* Dummy read the Interrupt source register */
+               SK_IN16(IoC, GMAC_IRQ_SRC, &SWord);
+
+#ifndef VCPU
+               /* read Id from PHY */
+               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1);
+
+               SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
+#endif /* VCPU */
+       }
+
+       (void)SkGmResetCounter(pAC, IoC, Port);
+
+       SWord =  0;
+
+       /* speed settings */
+       switch (pPrt->PLinkSpeed) {
+       case SK_LSPEED_AUTO:
+       case SK_LSPEED_1000MBPS:
+               SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100;
+               break;
+       case SK_LSPEED_100MBPS:
+               SWord |= GM_GPCR_SPEED_100;
+               break;
+       case SK_LSPEED_10MBPS:
+               break;
+       }
+
+       /* duplex settings */
+       if (pPrt->PLinkMode != SK_LMODE_HALF) {
+               /* set full duplex */
+               SWord |= GM_GPCR_DUP_FULL;
+       }
+
+       /* flow control settings */
+       switch (pPrt->PFlowCtrlMode) {
+       case SK_FLOW_MODE_NONE:
+               /* disable auto-negotiation for flow-control */
+               SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS;
+               break;
+       case SK_FLOW_MODE_LOC_SEND:
+               SWord |= GM_GPCR_FC_RX_DIS;
+               break;
+       case SK_FLOW_MODE_SYMMETRIC:
+               /* TBD */
+       case SK_FLOW_MODE_SYM_OR_REM:
+               /* enable auto-negotiation for flow-control and */
+               /* enable Rx and Tx of pause frames */
+               break;
+       }
+
+       /* Auto-negotiation ? */
+       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
+               /* disable auto-update for speed, duplex and flow-control */
+               SWord |= GM_GPCR_AU_ALL_DIS;
+       }
+
+       /* setup General Purpose Control Register */
+       GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
+
+       /* setup Transmit Control Register */
+       GM_OUT16(IoC, Port, GM_TX_CTRL, GM_TXCR_COL_THR);
+
+       /* setup Receive Control Register */
+       GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA |
+               GM_RXCR_CRC_DIS);
+
+       /* setup Transmit Flow Control Register */
+       GM_OUT16(IoC, Port, GM_TX_FLOW_CTRL, 0xffff);
+
+       /* setup Transmit Parameter Register */
+#ifdef VCPU
+       GM_IN16(IoC, Port, GM_TX_PARAM, &SWord);
+#endif /* VCPU */
+
+       SWord = JAM_LEN_VAL(3) | JAM_IPG_VAL(11) | IPG_JAM_DATA(26);
+
+       GM_OUT16(IoC, Port, GM_TX_PARAM, SWord);
+
+       /* configure the Serial Mode Register */
+#ifdef VCPU
+       GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord);
+#endif /* VCPU */
+
+       SWord = GM_SMOD_VLAN_ENA | IPG_VAL_FAST_ETH;
+
+       if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
+               /* enable jumbo mode (Max. Frame Length = 9018) */
+               SWord |= GM_SMOD_JUMBO_ENA;
+       }
+
+       GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord);
+
+       /*
+        * configure the GMACs Station Addresses
+        * in PROM you can find our addresses at:
+        * B2_MAC_1 = xx xx xx xx xx x0 virtual address
+        * B2_MAC_2 = xx xx xx xx xx x1 is programmed to GMAC A
+        * B2_MAC_3 = xx xx xx xx xx x2 is reserved for DualPort
+        */
+
+       for (i = 0; i < 3; i++) {
+               /*
+                * The following 2 statements are together endianess
+                * independent. Remember this when changing.
+                */
+               /* physical address: will be used for pause frames */
+               SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
+
+#ifdef WA_DEV_16
+               /* WA for deviation #16 */
+               if (pAC->GIni.GIChipRev == 0) {
+                       /* swap the address bytes */
+                       SWord = ((SWord & 0xff00) >> 8) | ((SWord & 0x00ff) << 8);
+
+                       /* write to register in reversed order */
+                       GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + (2 - i) * 4), SWord);
+               }
+               else {
+                       GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
+               }
+#else
+               GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
+#endif /* WA_DEV_16 */
+
+               /* virtual address: will be used for data */
+               SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord);
+
+               GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord);
+
+               /* reset Multicast filtering Hash registers 1-3 */
+               GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + 4*i, 0);
+       }
+
+       /* reset Multicast filtering Hash register 4 */
+       GM_OUT16(IoC, Port, GM_MC_ADDR_H4, 0);
+
+       /* enable interrupt mask for counter overflows */
+       GM_OUT16(IoC, Port, GM_TX_IRQ_MSK, 0);
+       GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0);
+       GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0);
+
+       /* read General Purpose Status */
+       GM_IN16(IoC, Port, GM_GP_STAT, &SWord);
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("MAC Stat Reg=0x%04X\n", SWord));
+
+#ifdef SK_DIAG
+       c_print("MAC Stat Reg=0x%04X\n", SWord);
+#endif /* SK_DIAG */
+
+}      /* SkGmInitMac */
+
+
+/******************************************************************************
+ *
+ *     SkXmInitDupMd() - Initialize the XMACs Duplex Mode
+ *
+ * Description:
+ *     This function initializes the XMACs Duplex Mode.
+ *     It should be called after successfully finishing
+ *     the Auto-negotiation Process
+ *
+ * Returns:
+ *     nothing
+ */
+void SkXmInitDupMd(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       switch (pAC->GIni.GP[Port].PLinkModeStatus) {
+       case SK_LMODE_STAT_AUTOHALF:
+       case SK_LMODE_STAT_HALF:
+               /* Configuration Actions for Half Duplex Mode */
+               /*
+                * XM_BURST = default value. We are probable not quick
+                *      enough at the 'XMAC' bus to burst 8kB.
+                *      The XMAC stops bursting if no transmit frames
+                *      are available or the burst limit is exceeded.
+                */
+               /* XM_TX_RT_LIM = default value (15) */
+               /* XM_TX_STIME = default value (0xff = 4096 bit times) */
+               break;
+       case SK_LMODE_STAT_AUTOFULL:
+       case SK_LMODE_STAT_FULL:
+               /* Configuration Actions for Full Duplex Mode */
+               /*
+                * The duplex mode is configured by the PHY,
+                * therefore it seems to be that there is nothing
+                * to do here.
+                */
+               break;
+       case SK_LMODE_STAT_UNKNOWN:
+       default:
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E007, SKERR_HWI_E007MSG);
+               break;
+       }
+}      /* SkXmInitDupMd */
+
+
+/******************************************************************************
+ *
+ *     SkXmInitPauseMd() - initialize the Pause Mode to be used for this port
+ *
+ * Description:
+ *     This function initializes the Pause Mode which should
+ *     be used for this port.
+ *     It should be called after successfully finishing
+ *     the Auto-negotiation Process
+ *
+ * Returns:
+ *     nothing
+ */
+void SkXmInitPauseMd(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;
+       SK_U32          DWord;
+       SK_U16          Word;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
+
+       if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE ||
+               pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
+
+               /* Disable Pause Frame Reception */
+               Word |= XM_MMU_IGN_PF;
+       }
+       else {
+               /*
+                * enabling pause frame reception is required for 1000BT
+                * because the XMAC is not reset if the link is going down
+                */
+               /* Enable Pause Frame Reception */
+               Word &= ~XM_MMU_IGN_PF;
+       }
+
+       XM_OUT16(IoC, Port, XM_MMU_CMD, Word);
+
+       XM_IN32(IoC, Port, XM_MODE, &DWord);
+
+       if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_SYMMETRIC ||
+               pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
+
+               /*
+                * Configure Pause Frame Generation
+                * Use internal and external Pause Frame Generation.
+                * Sending pause frames is edge triggered.
+                * Send a Pause frame with the maximum pause time if
+                * internal oder external FIFO full condition occurs.
+                * Send a zero pause time frame to re-start transmission.
+                */
+
+               /* XM_PAUSE_DA = '010000C28001' (default) */
+
+               /* XM_MAC_PTIME = 0xffff (maximum) */
+               /* remember this value is defined in big endian (!) */
+               XM_OUT16(IoC, Port, XM_MAC_PTIME, 0xffff);
+
+               /* Set Pause Mode in Mode Register */
+               DWord |= XM_PAUSE_MODE;
+
+               /* Set Pause Mode in MAC Rx FIFO */
+               SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_PAUSE);
+       }
+       else {
+               /*
+                * disable pause frame generation is required for 1000BT
+                * because the XMAC is not reset if the link is going down
+                */
+               /* Disable Pause Mode in Mode Register */
+               DWord &= ~XM_PAUSE_MODE;
+
+               /* Disable Pause Mode in MAC Rx FIFO */
+               SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_DIS_PAUSE);
+       }
+
+       XM_OUT32(IoC, Port, XM_MODE, DWord);
+}      /* SkXmInitPauseMd*/
+
+
+/******************************************************************************
+ *
+ *     SkXmInitPhyXmac() - Initialize the XMAC Phy registers
+ *
+ * Description:        initializes all the XMACs Phy registers
+ *
+ * Note:
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkXmInitPhyXmac(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
+{
+       SK_GEPORT       *pPrt;
+       SK_U16          Ctrl;
+
+       pPrt = &pAC->GIni.GP[Port];
+       Ctrl = 0;
+
+       /* Auto-negotiation ? */
+       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("InitPhyXmac: no auto-negotiation Port %d\n", Port));
+               /* Set DuplexMode in Config register */
+               if (pPrt->PLinkMode == SK_LMODE_FULL) {
+                       Ctrl |= PHY_CT_DUP_MD;
+               }
+
+               /*
+                * Do NOT enable Auto-negotiation here. This would hold
+                * the link down because no IDLEs are transmitted
+                */
+       }
+       else {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("InitPhyXmac: with auto-negotiation Port %d\n", Port));
+               /* Set Auto-negotiation advertisement */
+
+               /* Set Full/half duplex capabilities */
+               switch (pPrt->PLinkMode) {
+               case SK_LMODE_AUTOHALF:
+                       Ctrl |= PHY_X_AN_HD;
+                       break;
+               case SK_LMODE_AUTOFULL:
+                       Ctrl |= PHY_X_AN_FD;
+                       break;
+               case SK_LMODE_AUTOBOTH:
+                       Ctrl |= PHY_X_AN_FD | PHY_X_AN_HD;
+                       break;
+               default:
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
+                               SKERR_HWI_E015MSG);
+               }
+
+               switch (pPrt->PFlowCtrlMode) {
+               case SK_FLOW_MODE_NONE:
+                       Ctrl |= PHY_X_P_NO_PAUSE;
+                       break;
+               case SK_FLOW_MODE_LOC_SEND:
+                       Ctrl |= PHY_X_P_ASYM_MD;
+                       break;
+               case SK_FLOW_MODE_SYMMETRIC:
+                       Ctrl |= PHY_X_P_SYM_MD;
+                       break;
+               case SK_FLOW_MODE_SYM_OR_REM:
+                       Ctrl |= PHY_X_P_BOTH_MD;
+                       break;
+               default:
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
+                               SKERR_HWI_E016MSG);
+               }
+
+               /* Write AutoNeg Advertisement Register */
+               SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_AUNE_ADV, Ctrl);
+
+               /* Restart Auto-negotiation */
+               Ctrl = PHY_CT_ANE | PHY_CT_RE_CFG;
+       }
+
+       if (DoLoop) {
+               /* Set the Phy Loopback bit, too */
+               Ctrl |= PHY_CT_LOOP;
+       }
+
+       /* Write to the Phy control register */
+       SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_CTRL, Ctrl);
+}      /* SkXmInitPhyXmac */
+
+
+/******************************************************************************
+ *
+ *     SkXmInitPhyBcom() - Initialize the Broadcom Phy registers
+ *
+ * Description:        initializes all the Broadcom Phy registers
+ *
+ * Note:
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkXmInitPhyBcom(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
+{
+       SK_GEPORT       *pPrt;
+       SK_U16          Ctrl1;
+       SK_U16          Ctrl2;
+       SK_U16          Ctrl3;
+       SK_U16          Ctrl4;
+       SK_U16          Ctrl5;
+
+       Ctrl1 = PHY_CT_SP1000;
+       Ctrl2 = 0;
+       Ctrl3 = PHY_SEL_TYPE;
+       Ctrl4 = PHY_B_PEC_EN_LTR;
+       Ctrl5 = PHY_B_AC_TX_TST;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       /* manually Master/Slave ? */
+       if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
+               Ctrl2 |= PHY_B_1000C_MSE;
+
+               if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
+                       Ctrl2 |= PHY_B_1000C_MSC;
+               }
+       }
+       /* Auto-negotiation ? */
+       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("InitPhyBcom: no auto-negotiation Port %d\n", Port));
+               /* Set DuplexMode in Config register */
+               Ctrl1 |= (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
+
+               /* Determine Master/Slave manually if not already done */
+               if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
+                       Ctrl2 |= PHY_B_1000C_MSE;       /* set it to Slave */
+               }
+
+               /*
+                * Do NOT enable Auto-negotiation here. This would hold
+                * the link down because no IDLES are transmitted
+                */
+       }
+       else {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("InitPhyBcom: with auto-negotiation Port %d\n", Port));
+               /* Set Auto-negotiation advertisement */
+
+               /*
+                * Workaround BCOM Errata #1 for the C5 type.
+                * 1000Base-T Link Acquisition Failure in Slave Mode
+                * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
+                */
+               Ctrl2 |= PHY_B_1000C_RD;
+
+                /* Set Full/half duplex capabilities */
+               switch (pPrt->PLinkMode) {
+               case SK_LMODE_AUTOHALF:
+                       Ctrl2 |= PHY_B_1000C_AHD;
+                       break;
+               case SK_LMODE_AUTOFULL:
+                       Ctrl2 |= PHY_B_1000C_AFD;
+                       break;
+               case SK_LMODE_AUTOBOTH:
+                       Ctrl2 |= PHY_B_1000C_AFD | PHY_B_1000C_AHD;
+                       break;
+               default:
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
+                               SKERR_HWI_E015MSG);
+               }
+
+               switch (pPrt->PFlowCtrlMode) {
+               case SK_FLOW_MODE_NONE:
+                       Ctrl3 |= PHY_B_P_NO_PAUSE;
+                       break;
+               case SK_FLOW_MODE_LOC_SEND:
+                       Ctrl3 |= PHY_B_P_ASYM_MD;
+                       break;
+               case SK_FLOW_MODE_SYMMETRIC:
+                       Ctrl3 |= PHY_B_P_SYM_MD;
+                       break;
+               case SK_FLOW_MODE_SYM_OR_REM:
+                       Ctrl3 |= PHY_B_P_BOTH_MD;
+                       break;
+               default:
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
+                               SKERR_HWI_E016MSG);
+               }
+
+               /* Restart Auto-negotiation */
+               Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG;
+       }
+
+       /* Initialize LED register here? */
+       /* No. Please do it in SkDgXmitLed() (if required) and swap
+          init order of LEDs and XMAC. (MAl) */
+
+       /* Write 1000Base-T Control Register */
+       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
+
+       /* Write AutoNeg Advertisement Register */
+       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("Auto-Neg. Adv. Reg=0x%04X\n", Ctrl3));
+
+       if (DoLoop) {
+               /* Set the Phy Loopback bit, too */
+               Ctrl1 |= PHY_CT_LOOP;
+       }
+
+       if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
+               /* configure FIFO to high latency for transmission of ext. packets */
+               Ctrl4 |= PHY_B_PEC_HIGH_LA;
+
+               /* configure reception of extended packets */
+               Ctrl5 |= PHY_B_AC_LONG_PACK;
+
+               SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, Ctrl5);
+       }
+
+       /* Configure LED Traffic Mode and Jumbo Frame usage if specified */
+       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4);
+
+       /* Write to the Phy control register */
+       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, Ctrl1);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("PHY Control Reg=0x%04X\n", Ctrl1));
+}      /* SkXmInitPhyBcom */
+
+
+/******************************************************************************
+ *
+ *     SkGmInitPhyMarv() - Initialize the Marvell Phy registers
+ *
+ * Description:        initializes all the Marvell Phy registers
+ *
+ * Note:
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkGmInitPhyMarv(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
+{
+       SK_GEPORT       *pPrt;
+       SK_U16          PhyCtrl;
+       SK_U16          C1000BaseT;
+       SK_U16          AutoNegAdv;
+       SK_U16          ExtPhyCtrl;
+       SK_U16          PhyStat;
+       SK_U16          PhyStat1;
+       SK_U16          PhySpecStat;
+       SK_U16          LedCtrl;
+       SK_BOOL         AutoNeg;
+
+#ifdef VCPU
+       VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n",
+               Port, DoLoop);
+#else /* VCPU */
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       /* Auto-negotiation ? */
+       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
+               AutoNeg = SK_FALSE;
+       }
+       else {
+               AutoNeg = SK_TRUE;
+       }
+
+       if (!DoLoop) {
+               /* Read Ext. PHY Specific Control */
+               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
+
+               ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
+                       PHY_M_EC_MAC_S_MSK);
+
+               ExtPhyCtrl |= PHY_M_EC_M_DSC(1) | PHY_M_EC_S_DSC(1) |
+                       PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);
+
+               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl);
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("Ext.PHYCtrl=0x%04X\n", ExtPhyCtrl));
+
+               /* Read PHY Control */
+               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
+
+               /* Assert software reset */
+               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL,
+                       (SK_U16)(PhyCtrl | PHY_CT_RESET));
+       }
+#endif /* VCPU */
+
+       PhyCtrl = 0 /* PHY_CT_COL_TST */;
+       C1000BaseT = 0;
+       AutoNegAdv = PHY_SEL_TYPE;
+
+       /* manually Master/Slave ? */
+       if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
+               /* enable Manual Master/Slave */
+               C1000BaseT |= PHY_M_1000C_MSE;
+
+               if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
+                       C1000BaseT |= PHY_M_1000C_MSC;  /* set it to Master */
+               }
+       }
+
+       /* Auto-negotiation ? */
+       if (!AutoNeg) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("InitPhyMarv: no auto-negotiation Port %d\n", Port));
+
+               if (pPrt->PLinkMode == SK_LMODE_FULL) {
+                       /* Set Full Duplex Mode */
+                       PhyCtrl |= PHY_CT_DUP_MD;
+               }
+
+               /* Set Master/Slave manually if not already done */
+               if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
+                       C1000BaseT |= PHY_M_1000C_MSE;  /* set it to Slave */
+               }
+
+               /* Set Speed */
+               switch (pPrt->PLinkSpeed) {
+               case SK_LSPEED_AUTO:
+               case SK_LSPEED_1000MBPS:
+                       PhyCtrl |= PHY_CT_SP1000;
+                       break;
+               case SK_LSPEED_100MBPS:
+                       PhyCtrl |= PHY_CT_SP100;
+                       break;
+               case SK_LSPEED_10MBPS:
+                       break;
+               default:
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
+                               SKERR_HWI_E019MSG);
+               }
+
+               if (!DoLoop) {
+                       PhyCtrl |= PHY_CT_RESET;
+               }
+               /*
+                * Do NOT enable Auto-negotiation here. This would hold
+                * the link down because no IDLES are transmitted
+                */
+       }
+       else {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("InitPhyMarv: with auto-negotiation Port %d\n", Port));
+
+               PhyCtrl |= PHY_CT_ANE;
+
+               if (pAC->GIni.GICopperType) {
+                       /* Set Speed capabilities */
+                       switch (pPrt->PLinkSpeed) {
+                       case SK_LSPEED_AUTO:
+                               C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
+                               AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
+                                       PHY_M_AN_10_FD | PHY_M_AN_10_HD;
+                               break;
+                       case SK_LSPEED_1000MBPS:
+                               C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
+                               break;
+                       case SK_LSPEED_100MBPS:
+                               AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
+                                       PHY_M_AN_10_FD | PHY_M_AN_10_HD;
+                               break;
+                       case SK_LSPEED_10MBPS:
+                               AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD;
+                               break;
+                       default:
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
+                                       SKERR_HWI_E019MSG);
+                       }
+
+                       /* Set Full/half duplex capabilities */
+                       switch (pPrt->PLinkMode) {
+                       case SK_LMODE_AUTOHALF:
+                               C1000BaseT &= ~PHY_M_1000C_AFD;
+                               AutoNegAdv &= ~(PHY_M_AN_100_FD | PHY_M_AN_10_FD);
+                               break;
+                       case SK_LMODE_AUTOFULL:
+                               C1000BaseT &= ~PHY_M_1000C_AHD;
+                               AutoNegAdv &= ~(PHY_M_AN_100_HD | PHY_M_AN_10_HD);
+                               break;
+                       case SK_LMODE_AUTOBOTH:
+                               break;
+                       default:
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
+                                       SKERR_HWI_E015MSG);
+                       }
+
+                       /* Set Auto-negotiation advertisement */
+                       switch (pPrt->PFlowCtrlMode) {
+                       case SK_FLOW_MODE_NONE:
+                               AutoNegAdv |= PHY_B_P_NO_PAUSE;
+                               break;
+                       case SK_FLOW_MODE_LOC_SEND:
+                               AutoNegAdv |= PHY_B_P_ASYM_MD;
+                               break;
+                       case SK_FLOW_MODE_SYMMETRIC:
+                               AutoNegAdv |= PHY_B_P_SYM_MD;
+                               break;
+                       case SK_FLOW_MODE_SYM_OR_REM:
+                               AutoNegAdv |= PHY_B_P_BOTH_MD;
+                               break;
+                       default:
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
+                                       SKERR_HWI_E016MSG);
+                       }
+               }
+               else {  /* special defines for FIBER (88E1011S only) */
+
+                       /* Set Full/half duplex capabilities */
+                       switch (pPrt->PLinkMode) {
+                       case SK_LMODE_AUTOHALF:
+                               AutoNegAdv |= PHY_M_AN_1000X_AHD;
+                               break;
+                       case SK_LMODE_AUTOFULL:
+                               AutoNegAdv |= PHY_M_AN_1000X_AFD;
+                               break;
+                       case SK_LMODE_AUTOBOTH:
+                               AutoNegAdv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
+                               break;
+                       default:
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
+                                       SKERR_HWI_E015MSG);
+                       }
+
+                       /* Set Auto-negotiation advertisement */
+                       switch (pPrt->PFlowCtrlMode) {
+                       case SK_FLOW_MODE_NONE:
+                               AutoNegAdv |= PHY_M_P_NO_PAUSE_X;
+                               break;
+                       case SK_FLOW_MODE_LOC_SEND:
+                               AutoNegAdv |= PHY_M_P_ASYM_MD_X;
+                               break;
+                       case SK_FLOW_MODE_SYMMETRIC:
+                               AutoNegAdv |= PHY_M_P_SYM_MD_X;
+                               break;
+                       case SK_FLOW_MODE_SYM_OR_REM:
+                               AutoNegAdv |= PHY_M_P_BOTH_MD_X;
+                               break;
+                       default:
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
+                                       SKERR_HWI_E016MSG);
+                       }
+               }
+
+               if (!DoLoop) {
+                       /* Restart Auto-negotiation */
+                       PhyCtrl |= PHY_CT_RE_CFG;
+               }
+       }
+
+#ifdef VCPU
+       /*
+        * E-mail from Gu Lin (08-03-2002):
+        */
+
+       /* Program PHY register 30 as 16'h0708 for simulation speed up */
+       SkGmPhyWrite(pAC, IoC, Port, 30, 0x0708);
+
+       VCpuWait(2000);
+
+#else /* VCPU */
+
+       /* Write 1000Base-T Control Register */
+       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("1000B-T Ctrl=0x%04X\n", C1000BaseT));
+
+       /* Write AutoNeg Advertisement Register */
+       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("Auto-Neg.Ad.=0x%04X\n", AutoNegAdv));
+#endif /* VCPU */
+
+       if (DoLoop) {
+               /* Set the PHY Loopback bit */
+               PhyCtrl |= PHY_CT_LOOP;
+
+               /* Program PHY register 16 as 16'h0400 to force link good */
+               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD);
+
+#if 0
+               if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) {
+                       /* Write Ext. PHY Specific Control */
+                       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL,
+                               (SK_U16)((pPrt->PLinkSpeed + 2) << 4));
+               }
+       }
+       else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) {
+                       /* Write PHY Specific Control */
+                       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_EN_DET_MSK);
+               }
+#endif /* 0 */
+       }
+
+       /* Write to the PHY Control register */
+       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
+
+#ifdef VCPU
+       VCpuWait(2000);
+#else
+
+       LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS) | PHY_M_LED_BLINK_RT(BLINK_84MS);
+
+#ifdef ACT_LED_BLINK
+       LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL;
+#endif /* ACT_LED_BLINK */
+
+#ifdef DUP_LED_NORMAL
+       LedCtrl |= PHY_M_LEDC_DP_CTRL;
+#endif /* DUP_LED_NORMAL */
+
+       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl);
+
+#endif /* VCPU */
+
+#ifdef SK_DIAG
+       c_print("Set PHY Ctrl=0x%04X\n", PhyCtrl);
+       c_print("Set 1000 B-T=0x%04X\n", C1000BaseT);
+       c_print("Set Auto-Neg=0x%04X\n", AutoNegAdv);
+       c_print("Set Ext Ctrl=0x%04X\n", ExtPhyCtrl);
+#endif /* SK_DIAG */
+
+#ifndef xDEBUG
+       /* Read PHY Control */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
+
+       /* Read 1000Base-T Control Register */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("1000B-T Ctrl =0x%04X\n", C1000BaseT));
+
+       /* Read AutoNeg Advertisement Register */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("Auto-Neg. Ad.=0x%04X\n", AutoNegAdv));
+
+       /* Read Ext. PHY Specific Control */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("Ext PHY Ctrl=0x%04X\n", ExtPhyCtrl));
+
+       /* Read PHY Status */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("PHY Stat Reg.=0x%04X\n", PhyStat));
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat1);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("PHY Stat Reg.=0x%04X\n", PhyStat1));
+
+       /* Read PHY Specific Status */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("PHY Spec Stat=0x%04X\n", PhySpecStat));
+#endif /* DEBUG */
+
+#ifdef SK_DIAG
+       c_print("PHY Ctrl Reg=0x%04X\n", PhyCtrl);
+       c_print("PHY 1000 Reg=0x%04X\n", C1000BaseT);
+       c_print("PHY AnAd Reg=0x%04X\n", AutoNegAdv);
+       c_print("Ext Ctrl Reg=0x%04X\n", ExtPhyCtrl);
+       c_print("PHY Stat Reg=0x%04X\n", PhyStat);
+       c_print("PHY Stat Reg=0x%04X\n", PhyStat1);
+       c_print("PHY Spec Reg=0x%04X\n", PhySpecStat);
+#endif /* SK_DIAG */
+
+}      /* SkGmInitPhyMarv */
+
+
+#ifdef OTHER_PHY
+/******************************************************************************
+ *
+ *     SkXmInitPhyLone() - Initialize the Level One Phy registers
+ *
+ * Description:        initializes all the Level One Phy registers
+ *
+ * Note:
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkXmInitPhyLone(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
+{
+       SK_GEPORT       *pPrt;
+       SK_U16          Ctrl1;
+       SK_U16          Ctrl2;
+       SK_U16          Ctrl3;
+
+       Ctrl1 = PHY_CT_SP1000;
+       Ctrl2 = 0;
+       Ctrl3 = PHY_SEL_TYPE;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       /* manually Master/Slave ? */
+       if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
+               Ctrl2 |= PHY_L_1000C_MSE;
+
+               if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
+                       Ctrl2 |= PHY_L_1000C_MSC;
+               }
+       }
+       /* Auto-negotiation ? */
+       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
+               /*
+                * level one spec say: "1000Mbps: manual mode not allowed"
+                * but lets see what happens...
+                */
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("InitPhyLone: no auto-negotiation Port %d\n", Port));
+               /* Set DuplexMode in Config register */
+               Ctrl1 = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
+
+               /* Determine Master/Slave manually if not already done */
+               if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
+                       Ctrl2 |= PHY_L_1000C_MSE;       /* set it to Slave */
+               }
+
+               /*
+                * Do NOT enable Auto-negotiation here. This would hold
+                * the link down because no IDLES are transmitted
+                */
+       }
+       else {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("InitPhyLone: with auto-negotiation Port %d\n", Port));
+               /* Set Auto-negotiation advertisement */
+
+               /* Set Full/half duplex capabilities */
+               switch (pPrt->PLinkMode) {
+               case SK_LMODE_AUTOHALF:
+                       Ctrl2 |= PHY_L_1000C_AHD;
+                       break;
+               case SK_LMODE_AUTOFULL:
+                       Ctrl2 |= PHY_L_1000C_AFD;
+                       break;
+               case SK_LMODE_AUTOBOTH:
+                       Ctrl2 |= PHY_L_1000C_AFD | PHY_L_1000C_AHD;
+                       break;
+               default:
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
+                               SKERR_HWI_E015MSG);
+               }
+
+               switch (pPrt->PFlowCtrlMode) {
+               case SK_FLOW_MODE_NONE:
+                       Ctrl3 |= PHY_L_P_NO_PAUSE;
+                       break;
+               case SK_FLOW_MODE_LOC_SEND:
+                       Ctrl3 |= PHY_L_P_ASYM_MD;
+                       break;
+               case SK_FLOW_MODE_SYMMETRIC:
+                       Ctrl3 |= PHY_L_P_SYM_MD;
+                       break;
+               case SK_FLOW_MODE_SYM_OR_REM:
+                       Ctrl3 |= PHY_L_P_BOTH_MD;
+                       break;
+               default:
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
+                               SKERR_HWI_E016MSG);
+               }
+
+               /* Restart Auto-negotiation */
+               Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG;
+
+       }
+
+       /* Initialize LED register here ? */
+       /* No. Please do it in SkDgXmitLed() (if required) and swap
+          init order of LEDs and XMAC. (MAl) */
+
+       /* Write 1000Base-T Control Register */
+       SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
+
+       /* Write AutoNeg Advertisement Register */
+       SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("Auto-Neg. Adv. Reg=0x%04X\n", Ctrl3));
+
+
+       if (DoLoop) {
+               /* Set the Phy Loopback bit, too */
+               Ctrl1 |= PHY_CT_LOOP;
+       }
+
+       /* Write to the Phy control register */
+       SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_CTRL, Ctrl1);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("PHY Control Reg=0x%04X\n", Ctrl1));
+}      /* SkXmInitPhyLone */
+
+
+/******************************************************************************
+ *
+ *     SkXmInitPhyNat() - Initialize the National Phy registers
+ *
+ * Description:        initializes all the National Phy registers
+ *
+ * Note:
+ *
+ * Returns:
+ *     nothing
+ */
+static void SkXmInitPhyNat(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
+{
+/* todo: National */
+}      /* SkXmInitPhyNat */
+#endif /* OTHER_PHY */
+
+
+/******************************************************************************
+ *
+ *     SkMacInitPhy() - Initialize the PHY registers
+ *
+ * Description:        calls the Init PHY routines dep. on board type
+ *
+ * Note:
+ *
+ * Returns:
+ *     nothing
+ */
+void SkMacInitPhy(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
+{
+       SK_GEPORT       *pPrt;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       switch (pPrt->PhyType) {
+       case SK_PHY_XMAC:
+               SkXmInitPhyXmac(pAC, IoC, Port, DoLoop);
+               break;
+       case SK_PHY_BCOM:
+               SkXmInitPhyBcom(pAC, IoC, Port, DoLoop);
+               break;
+       case SK_PHY_MARV_COPPER:
+       case SK_PHY_MARV_FIBER:
+               SkGmInitPhyMarv(pAC, IoC, Port, DoLoop);
+               break;
+#ifdef OTHER_PHY
+       case SK_PHY_LONE:
+               SkXmInitPhyLone(pAC, IoC, Port, DoLoop);
+               break;
+       case SK_PHY_NAT:
+               SkXmInitPhyNat(pAC, IoC, Port, DoLoop);
+               break;
+#endif /* OTHER_PHY */
+       }
+}      /* SkMacInitPhy */
+
+
+#ifndef SK_DIAG
+/******************************************************************************
+ *
+ *     SkXmAutoNegLipaXmac() - Decides whether Link Partner could do auto-neg
+ *
+ *     This function analyses the Interrupt status word. If any of the
+ *     Auto-negotiating interrupt bits are set, the PLipaAutoNeg variable
+ *     is set true.
+ */
+void SkXmAutoNegLipaXmac(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+SK_U16 IStatus)        /* Interrupt Status word to analyse */
+{
+       SK_GEPORT       *pPrt;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
+               (IStatus & (XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND)) != 0) {
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("AutoNegLipa: AutoNeg detected on Port %d, IStatus=0x%04x\n",
+                       Port, IStatus));
+               pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
+       }
+}      /* SkXmAutoNegLipaXmac */
+
+
+/******************************************************************************
+ *
+ *     SkMacAutoNegLipaPhy() - Decides whether Link Partner could do auto-neg
+ *
+ *     This function analyses the PHY status word.
+ *  If any of the Auto-negotiating bits are set, the PLipaAutoNeg variable
+ *     is set true.
+ */
+void SkMacAutoNegLipaPhy(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+SK_U16 PhyStat)        /* PHY Status word to analyse */
+{
+       SK_GEPORT       *pPrt;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
+               (PhyStat & PHY_ST_AN_OVER) != 0) {
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat=0x%04x\n",
+                       Port, PhyStat));
+               pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
+       }
+}      /* SkMacAutoNegLipaPhy */
+#endif /* SK_DIAG */
+
+
+/******************************************************************************
+ *
+ *     SkXmAutoNegDoneXmac() - Auto-negotiation handling
+ *
+ * Description:
+ *     This function handles the auto-negotiation if the Done bit is set.
+ *
+ * Returns:
+ *     SK_AND_OK       o.k.
+ *     SK_AND_DUP_CAP  Duplex capability error happened
+ *     SK_AND_OTHER    Other error happened
+ */
+static int SkXmAutoNegDoneXmac(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;
+       SK_U16          ResAb;          /* Resolved Ability */
+       SK_U16          LPAb;           /* Link Partner Ability */
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("AutoNegDoneXmac, Port %d\n",Port));
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       /* Get PHY parameters */
+       SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LPAb);
+       SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
+
+       if ((LPAb & PHY_X_AN_RFB) != 0) {
+               /* At least one of the remote fault bit is set */
+               /* Error */
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("AutoNegFail: Remote fault bit set Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               return(SK_AND_OTHER);
+       }
+
+       /* Check Duplex mismatch */
+       if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) {
+               pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
+       }
+       else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) {
+               pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
+       }
+       else {
+               /* Error */
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               return(SK_AND_DUP_CAP);
+       }
+
+       /* Check PAUSE mismatch */
+       /* We are NOT using chapter 4.23 of the Xaqti manual */
+       /* We are using IEEE 802.3z/D5.0 Table 37-4 */
+       if ((pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC ||
+            pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) &&
+           (LPAb & PHY_X_P_SYM_MD) != 0) {
+               /* Symmetric PAUSE */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
+       }
+       else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM &&
+                  (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) {
+               /* Enable PAUSE receive, disable PAUSE transmit */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
+       }
+       else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND &&
+                  (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) {
+               /* Disable PAUSE receive, enable PAUSE transmit */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
+       }
+       else {
+               /* PAUSE mismatch -> no PAUSE */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
+       }
+       pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
+
+       return(SK_AND_OK);
+}      /* SkXmAutoNegDoneXmac */
+
+
+/******************************************************************************
+ *
+ *     SkXmAutoNegDoneBcom() - Auto-negotiation handling
+ *
+ * Description:
+ *     This function handles the auto-negotiation if the Done bit is set.
+ *
+ * Returns:
+ *     SK_AND_OK       o.k.
+ *     SK_AND_DUP_CAP  Duplex capability error happened
+ *     SK_AND_OTHER    Other error happened
+ */
+static int SkXmAutoNegDoneBcom(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;
+       SK_U16          LPAb;           /* Link Partner Ability */
+       SK_U16          AuxStat;        /* Auxiliary Status */
+
+#if 0
+01-Sep-2000 RA;:;:
+       SK_U16          ResAb;          /* Resolved Ability */
+#endif /* 0 */
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("AutoNegDoneBcom, Port %d\n", Port));
+       pPrt = &pAC->GIni.GP[Port];
+
+       /* Get PHY parameters */
+       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LPAb);
+#if 0
+01-Sep-2000 RA;:;:
+       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
+#endif /* 0 */
+
+       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &AuxStat);
+
+       if ((LPAb & PHY_B_AN_RF) != 0) {
+               /* Remote fault bit is set: Error */
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("AutoNegFail: Remote fault bit set Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               return(SK_AND_OTHER);
+       }
+
+       /* Check Duplex mismatch */
+       if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000FD) {
+               pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
+       }
+       else if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000HD) {
+               pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
+       }
+       else {
+               /* Error */
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               return(SK_AND_DUP_CAP);
+       }
+
+#if 0
+01-Sep-2000 RA;:;:
+       /* Check Master/Slave resolution */
+       if ((ResAb & PHY_B_1000S_MSF) != 0) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("Master/Slave Fault Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               pPrt->PMSStatus = SK_MS_STAT_FAULT;
+               return(SK_AND_OTHER);
+       }
+
+       pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
+               SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
+#endif /* 0 */
+
+       /* Check PAUSE mismatch */
+       /* We are using IEEE 802.3z/D5.0 Table 37-4 */
+       if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PAUSE_MSK) {
+               /* Symmetric PAUSE */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
+       }
+       else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRR) {
+               /* Enable PAUSE receive, disable PAUSE transmit */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
+       }
+       else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRT) {
+               /* Disable PAUSE receive, enable PAUSE transmit */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
+       }
+       else {
+               /* PAUSE mismatch -> no PAUSE */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
+       }
+       pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
+
+       return(SK_AND_OK);
+}      /* SkXmAutoNegDoneBcom */
+
+
+/******************************************************************************
+ *
+ *     SkGmAutoNegDoneMarv() - Auto-negotiation handling
+ *
+ * Description:
+ *     This function handles the auto-negotiation if the Done bit is set.
+ *
+ * Returns:
+ *     SK_AND_OK       o.k.
+ *     SK_AND_DUP_CAP  Duplex capability error happened
+ *     SK_AND_OTHER    Other error happened
+ */
+static int SkGmAutoNegDoneMarv(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;
+       SK_U16          LPAb;           /* Link Partner Ability */
+       SK_U16          ResAb;          /* Resolved Ability */
+       SK_U16          AuxStat;        /* Auxiliary Status */
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("AutoNegDoneMarv, Port %d\n", Port));
+       pPrt = &pAC->GIni.GP[Port];
+
+       /* Get PHY parameters */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb);
+
+       if ((LPAb & PHY_M_AN_RF) != 0) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("AutoNegFail: Remote fault bit set Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               return(SK_AND_OTHER);
+       }
+
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
+
+       /* Check Master/Slave resolution */
+       if ((ResAb & PHY_B_1000S_MSF) != 0) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("Master/Slave Fault Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               pPrt->PMSStatus = SK_MS_STAT_FAULT;
+               return(SK_AND_OTHER);
+       }
+
+       pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
+               (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE;
+
+       /* Read PHY Specific Status */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &AuxStat);
+
+       /* Check Speed & Duplex resolved */
+       if ((AuxStat & PHY_M_PS_SPDUP_RES) == 0) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("AutoNegFail: Speed & Duplex not resolved Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN;
+               return(SK_AND_DUP_CAP);
+       }
+
+       if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) {
+               pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
+       }
+       else {
+               pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
+       }
+
+       /* Check PAUSE mismatch */
+       /* We are using IEEE 802.3z/D5.0 Table 37-4 */
+       if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_PAUSE_MSK) {
+               /* Symmetric PAUSE */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
+       }
+       else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_RX_P_EN) {
+               /* Enable PAUSE receive, disable PAUSE transmit */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
+       }
+       else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_TX_P_EN) {
+               /* Disable PAUSE receive, enable PAUSE transmit */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
+       }
+       else {
+               /* PAUSE mismatch -> no PAUSE */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
+       }
+
+       /* set used link speed */
+       switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) {
+       case (unsigned)PHY_M_PS_SPEED_1000:
+               pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
+               break;
+       case PHY_M_PS_SPEED_100:
+               pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_100MBPS;
+               break;
+       default:
+               pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_10MBPS;
+       }
+
+       return(SK_AND_OK);
+}      /* SkGmAutoNegDoneMarv */
+
+
+#ifdef OTHER_PHY
+/******************************************************************************
+ *
+ *     SkXmAutoNegDoneLone() - Auto-negotiation handling
+ *
+ * Description:
+ *     This function handles the auto-negotiation if the Done bit is set.
+ *
+ * Returns:
+ *     SK_AND_OK       o.k.
+ *     SK_AND_DUP_CAP  Duplex capability error happened
+ *     SK_AND_OTHER    Other error happened
+ */
+static int SkXmAutoNegDoneLone(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;
+       SK_U16          ResAb;          /* Resolved Ability */
+       SK_U16          LPAb;           /* Link Partner Ability */
+       SK_U16          QuickStat;      /* Auxiliary Status */
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("AutoNegDoneLone, Port %d\n",Port));
+       pPrt = &pAC->GIni.GP[Port];
+
+       /* Get PHY parameters */
+       SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LPAb);
+       SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ResAb);
+       SkXmPhyRead(pAC, IoC, Port, PHY_LONE_Q_STAT, &QuickStat);
+
+       if ((LPAb & PHY_L_AN_RF) != 0) {
+               /* Remote fault bit is set */
+               /* Error */
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("AutoNegFail: Remote fault bit set Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               return(SK_AND_OTHER);
+       }
+
+       /* Check Duplex mismatch */
+       if ((QuickStat & PHY_L_QS_DUP_MOD) != 0) {
+               pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
+       }
+       else {
+               pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
+       }
+
+       /* Check Master/Slave resolution */
+       if ((ResAb & PHY_L_1000S_MSF) != 0) {
+               /* Error */
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("Master/Slave Fault Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               pPrt->PMSStatus = SK_MS_STAT_FAULT;
+               return(SK_AND_OTHER);
+       }
+       else if (ResAb & PHY_L_1000S_MSR) {
+               pPrt->PMSStatus = SK_MS_STAT_MASTER;
+       }
+       else {
+               pPrt->PMSStatus = SK_MS_STAT_SLAVE;
+       }
+
+       /* Check PAUSE mismatch */
+       /* We are using IEEE 802.3z/D5.0 Table 37-4 */
+       /* we must manually resolve the abilities here */
+       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
+       switch (pPrt->PFlowCtrlMode) {
+       case SK_FLOW_MODE_NONE:
+               /* default */
+               break;
+       case SK_FLOW_MODE_LOC_SEND:
+               if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
+                       (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) {
+                       /* Disable PAUSE receive, enable PAUSE transmit */
+                       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
+               }
+               break;
+       case SK_FLOW_MODE_SYMMETRIC:
+               if ((QuickStat & PHY_L_QS_PAUSE) != 0) {
+                       /* Symmetric PAUSE */
+                       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
+               }
+               break;
+       case SK_FLOW_MODE_SYM_OR_REM:
+               if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
+                       PHY_L_QS_AS_PAUSE) {
+                       /* Enable PAUSE receive, disable PAUSE transmit */
+                       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
+               }
+               else if ((QuickStat & PHY_L_QS_PAUSE) != 0) {
+                       /* Symmetric PAUSE */
+                       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
+               }
+               break;
+       default:
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
+                       SKERR_HWI_E016MSG);
+       }
+
+       return(SK_AND_OK);
+}      /* SkXmAutoNegDoneLone */
+
+
+/******************************************************************************
+ *
+ *     SkXmAutoNegDoneNat() - Auto-negotiation handling
+ *
+ * Description:
+ *     This function handles the auto-negotiation if the Done bit is set.
+ *
+ * Returns:
+ *     SK_AND_OK       o.k.
+ *     SK_AND_DUP_CAP  Duplex capability error happened
+ *     SK_AND_OTHER    Other error happened
+ */
+static int SkXmAutoNegDoneNat(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+/* todo: National */
+       return(SK_AND_OK);
+}      /* SkXmAutoNegDoneNat */
+#endif /* OTHER_PHY */
+
+
+/******************************************************************************
+ *
+ *     SkMacAutoNegDone() - Auto-negotiation handling
+ *
+ * Description:        calls the auto-negotiation done routines dep. on board type
+ *
+ * Returns:
+ *     SK_AND_OK       o.k.
+ *     SK_AND_DUP_CAP  Duplex capability error happened
+ *     SK_AND_OTHER    Other error happened
+ */
+int    SkMacAutoNegDone(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;
+       int     Rtv;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       switch (pPrt->PhyType) {
+       case SK_PHY_XMAC:
+               Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port);
+               break;
+       case SK_PHY_BCOM:
+               Rtv = SkXmAutoNegDoneBcom(pAC, IoC, Port);
+               break;
+       case SK_PHY_MARV_COPPER:
+       case SK_PHY_MARV_FIBER:
+               Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port);
+               break;
+#ifdef OTHER_PHY
+       case SK_PHY_LONE:
+               Rtv = SkXmAutoNegDoneLone(pAC, IoC, Port);
+               break;
+       case SK_PHY_NAT:
+               Rtv = SkXmAutoNegDoneNat(pAC, IoC, Port);
+               break;
+#endif /* OTHER_PHY */
+       default:
+               return(SK_AND_OTHER);
+       }
+
+       if (Rtv != SK_AND_OK) {
+               return(Rtv);
+       }
+
+       /* We checked everything and may now enable the link */
+       pPrt->PAutoNegFail = SK_FALSE;
+
+       SkMacRxTxEnable(pAC, IoC, Port);
+
+       return(SK_AND_OK);
+}      /* SkMacAutoNegDone */
+
+
+/******************************************************************************
+ *
+ *     SkXmSetRxTxEn() - Special Set Rx/Tx Enable and some features in XMAC
+ *
+ * Description:
+ *  sets MAC or PHY LoopBack and Duplex Mode in the MMU Command Reg.
+ *  enables Rx/Tx
+ *
+ * Returns: N/A
+ */
+static void SkXmSetRxTxEn(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+int            Para)           /* Parameter to set: MAC or PHY LoopBack, Duplex Mode */
+{
+       SK_U16  Word;
+
+       XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
+
+       switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) {
+       case SK_MAC_LOOPB_ON:
+               Word |= XM_MMU_MAC_LB;
+               break;
+       case SK_MAC_LOOPB_OFF:
+               Word &= ~XM_MMU_MAC_LB;
+               break;
+       }
+
+       switch (Para & (SK_PHY_LOOPB_ON | SK_PHY_LOOPB_OFF)) {
+       case SK_PHY_LOOPB_ON:
+               Word |= XM_MMU_GMII_LOOP;
+               break;
+       case SK_PHY_LOOPB_OFF:
+               Word &= ~XM_MMU_GMII_LOOP;
+               break;
+       }
+
+       switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) {
+       case SK_PHY_FULLD_ON:
+               Word |= XM_MMU_GMII_FD;
+               break;
+       case SK_PHY_FULLD_OFF:
+               Word &= ~XM_MMU_GMII_FD;
+               break;
+       }
+
+       XM_OUT16(IoC, Port, XM_MMU_CMD, Word | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
+
+       /* dummy read to ensure writing */
+       XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
+
+}      /* SkXmSetRxTxEn */
+
+
+/******************************************************************************
+ *
+ *     SkGmSetRxTxEn() - Special Set Rx/Tx Enable and some features in GMAC
+ *
+ * Description:
+ *  sets MAC LoopBack and Duplex Mode in the General Purpose Control Reg.
+ *  enables Rx/Tx
+ *
+ * Returns: N/A
+ */
+static void SkGmSetRxTxEn(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+int            Para)           /* Parameter to set: MAC LoopBack, Duplex Mode */
+{
+       SK_U16  Ctrl;
+
+       GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl);
+
+       switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) {
+       case SK_MAC_LOOPB_ON:
+               Ctrl |= GM_GPCR_LOOP_ENA;
+               break;
+       case SK_MAC_LOOPB_OFF:
+               Ctrl &= ~GM_GPCR_LOOP_ENA;
+               break;
+       }
+
+       switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) {
+       case SK_PHY_FULLD_ON:
+               Ctrl |= GM_GPCR_DUP_FULL;
+               break;
+       case SK_PHY_FULLD_OFF:
+               Ctrl &= ~GM_GPCR_DUP_FULL;
+               break;
+       }
+
+       GM_OUT16(IoC, Port, GM_GP_CTRL, Ctrl | GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
+
+       /* dummy read to ensure writing */
+       GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl);
+
+}      /* SkGmSetRxTxEn */
+
+
+/******************************************************************************
+ *
+ *     SkMacSetRxTxEn() - Special Set Rx/Tx Enable and parameters
+ *
+ * Description:        calls the Special Set Rx/Tx Enable routines dep. on board type
+ *
+ * Returns: N/A
+ */
+void SkMacSetRxTxEn(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+int            Para)
+{
+       if (pAC->GIni.GIGenesis) {
+
+               SkXmSetRxTxEn(pAC, IoC, Port, Para);
+       }
+       else {
+
+               SkGmSetRxTxEn(pAC, IoC, Port, Para);
+       }
+
+}      /* SkMacSetRxTxEn */
+
+
+/******************************************************************************
+ *
+ *     SkMacRxTxEnable() - Enable Rx/Tx activity if port is up
+ *
+ * Description:        enables Rx/Tx dep. on board type
+ *
+ * Returns:
+ *     0       o.k.
+ *     != 0    Error happened
+ */
+int SkMacRxTxEnable(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;
+       SK_U16          Reg;            /* 16-bit register value */
+       SK_U16          IntMask;        /* MAC interrupt mask */
+       SK_U16          SWord;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       if (!pPrt->PHWLinkUp) {
+               /* The Hardware link is NOT up */
+               return(0);
+       }
+
+       if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF ||
+            pPrt->PLinkMode == SK_LMODE_AUTOFULL ||
+            pPrt->PLinkMode == SK_LMODE_AUTOBOTH) &&
+            pPrt->PAutoNegFail) {
+               /* Auto-negotiation is not done or failed */
+               return(0);
+       }
+
+       if (pAC->GIni.GIGenesis) {
+               /* set Duplex Mode and Pause Mode */
+               SkXmInitDupMd(pAC, IoC, Port);
+
+               SkXmInitPauseMd(pAC, IoC, Port);
+
+               /*
+                * Initialize the Interrupt Mask Register. Default IRQs are...
+                *      - Link Asynchronous Event
+                *      - Link Partner requests config
+                *      - Auto Negotiation Done
+                *      - Rx Counter Event Overflow
+                *      - Tx Counter Event Overflow
+                *      - Transmit FIFO Underrun
+                */
+               IntMask = XM_DEF_MSK;
+
+#ifdef DEBUG
+               /* add IRQ for Receive FIFO Overflow */
+               IntMask &= ~XM_IS_RXF_OV;
+#endif /* DEBUG */
+
+               if (pPrt->PhyType != SK_PHY_XMAC) {
+                       /* disable GP0 interrupt bit */
+                       IntMask |= XM_IS_INP_ASS;
+               }
+               XM_OUT16(IoC, Port, XM_IMSK, IntMask);
+
+               /* get MMU Command Reg. */
+               XM_IN16(IoC, Port, XM_MMU_CMD, &Reg);
+
+               if (pPrt->PhyType != SK_PHY_XMAC &&
+                       (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
+                        pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) {
+                       /* set to Full Duplex */
+                       Reg |= XM_MMU_GMII_FD;
+               }
+
+               switch (pPrt->PhyType) {
+               case SK_PHY_BCOM:
+                       /*
+                        * Workaround BCOM Errata (#10523) for all BCom Phys
+                        * Enable Power Management after link up
+                        */
+                       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
+                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
+                               (SK_U16)(SWord & ~PHY_B_AC_DIS_PM));
+                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
+                       break;
+#ifdef OTHER_PHY
+               case SK_PHY_LONE:
+                       SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, PHY_L_DEF_MSK);
+                       break;
+               case SK_PHY_NAT:
+                       /* todo National:
+                       SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, PHY_N_DEF_MSK); */
+                       /* no interrupts possible from National ??? */
+                       break;
+#endif /* OTHER_PHY */
+               }
+
+               /* enable Rx/Tx */
+               XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
+       }
+       else {
+               /*
+                * Initialize the Interrupt Mask Register. Default IRQs are...
+                *      - Rx Counter Event Overflow
+                *      - Tx Counter Event Overflow
+                *      - Transmit FIFO Underrun
+                */
+               IntMask = GMAC_DEF_MSK;
+
+#ifdef DEBUG
+               /* add IRQ for Receive FIFO Overrun */
+               IntMask |= GM_IS_RX_FF_OR;
+#endif /* DEBUG */
+
+               SK_OUT8(IoC, GMAC_IRQ_MSK, (SK_U8)IntMask);
+
+               /* get General Purpose Control */
+               GM_IN16(IoC, Port, GM_GP_CTRL, &Reg);
+
+               if (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
+                       pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) {
+                       /* set to Full Duplex */
+                       Reg |= GM_GPCR_DUP_FULL;
+               }
+
+               /* enable Rx/Tx */
+               GM_OUT16(IoC, Port, GM_GP_CTRL, Reg | GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
+
+#ifndef VCPU
+               /* Enable all PHY interrupts */
+               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
+#endif /* VCPU */
+       }
+
+       return(0);
+
+}      /* SkMacRxTxEnable */
+
+
+/******************************************************************************
+ *
+ *     SkMacRxTxDisable() - Disable Receiver and Transmitter
+ *
+ * Description:        disables Rx/Tx dep. on board type
+ *
+ * Returns: N/A
+ */
+void SkMacRxTxDisable(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       SK_U16  Word;
+
+       if (pAC->GIni.GIGenesis) {
+
+               XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
+
+               XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
+
+               /* dummy read to ensure writing */
+               XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
+       }
+       else {
+
+               GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
+
+               GM_OUT16(IoC, Port, GM_GP_CTRL, Word & ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA));
+
+               /* dummy read to ensure writing */
+               GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
+       }
+}      /* SkMacRxTxDisable */
+
+
+/******************************************************************************
+ *
+ *     SkMacIrqDisable() - Disable IRQ from MAC
+ *
+ * Description:        sets the IRQ-mask to disable IRQ dep. on board type
+ *
+ * Returns: N/A
+ */
+void SkMacIrqDisable(
+SK_AC  *pAC,           /* Adapter Context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;
+       SK_U16          Word;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       if (pAC->GIni.GIGenesis) {
+
+               /* disable all XMAC IRQs */
+               XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
+
+               /* Disable all PHY interrupts */
+               switch (pPrt->PhyType) {
+                       case SK_PHY_BCOM:
+                               /* Make sure that PHY is initialized */
+                               if (pPrt->PState != SK_PRT_RESET) {
+                                       /* NOT allowed if BCOM is in RESET state */
+                                       /* Workaround BCOM Errata (#10523) all BCom */
+                                       /* Disable Power Management if link is down */
+                                       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Word);
+                                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
+                                               (SK_U16)(Word | PHY_B_AC_DIS_PM));
+                                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff);
+                               }
+                               break;
+#ifdef OTHER_PHY
+                       case SK_PHY_LONE:
+                               SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0);
+                               break;
+                       case SK_PHY_NAT:
+                               /* todo: National
+                               SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */
+                               break;
+#endif /* OTHER_PHY */
+               }
+       }
+       else {
+               /* disable all GMAC IRQs */
+               SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
+
+#ifndef VCPU
+               /* Disable all PHY interrupts */
+               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
+#endif /* VCPU */
+       }
+}      /* SkMacIrqDisable */
+
+
+#ifdef SK_DIAG
+/******************************************************************************
+ *
+ *     SkXmSendCont() - Enable / Disable Send Continuous Mode
+ *
+ * Description:        enable / disable Send Continuous Mode on XMAC
+ *
+ * Returns:
+ *     nothing
+ */
+void SkXmSendCont(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* IO context */
+int            Port,   /* Port Index (MAC_1 + n) */
+SK_BOOL        Enable) /* Enable / Disable */
+{
+       SK_U32  MdReg;
+
+       XM_IN32(IoC, Port, XM_MODE, &MdReg);
+
+       if (Enable) {
+               MdReg |= XM_MD_TX_CONT;
+       }
+       else {
+               MdReg &= ~XM_MD_TX_CONT;
+       }
+       /* setup Mode Register */
+       XM_OUT32(IoC, Port, XM_MODE, MdReg);
+
+}      /* SkXmSendCont*/
+
+/******************************************************************************
+ *
+ *     SkMacTimeStamp() - Enable / Disable Time Stamp
+ *
+ * Description:        enable / disable Time Stamp generation for Rx packets
+ *
+ * Returns:
+ *     nothing
+ */
+void SkMacTimeStamp(
+SK_AC  *pAC,   /* adapter context */
+SK_IOC IoC,    /* IO context */
+int            Port,   /* Port Index (MAC_1 + n) */
+SK_BOOL        Enable) /* Enable / Disable */
+{
+       SK_U32  MdReg;
+       SK_U8   TimeCtrl;
+
+       if (pAC->GIni.GIGenesis) {
+
+               XM_IN32(IoC, Port, XM_MODE, &MdReg);
+
+               if (Enable) {
+                       MdReg |= XM_MD_ATS;
+               }
+               else {
+                       MdReg &= ~XM_MD_ATS;
+               }
+               /* setup Mode Register */
+               XM_OUT32(IoC, Port, XM_MODE, MdReg);
+       }
+       else {
+               if (Enable) {
+                       TimeCtrl = GMT_ST_START | GMT_ST_CLR_IRQ;
+               }
+               else {
+                       TimeCtrl = GMT_ST_STOP | GMT_ST_CLR_IRQ;
+               }
+               /* Start/Stop Time Stamp Timer */
+               SK_OUT8(pAC, GMAC_TI_ST_CTRL, TimeCtrl);
+       }
+}      /* SkMacTimeStamp*/
+
+#else /* SK_DIAG */
+
+/******************************************************************************
+ *
+ *     SkXmIrq() - Interrupt Service Routine
+ *
+ * Description:        services an Interrupt Request of the XMAC
+ *
+ * Note:
+ *     With an external PHY, some interrupt bits are not meaningfull any more:
+ *     - LinkAsyncEvent (bit #14)              XM_IS_LNK_AE
+ *     - LinkPartnerReqConfig (bit #10)        XM_IS_LIPA_RC
+ *     - Page Received (bit #9)                XM_IS_RX_PAGE
+ *     - NextPageLoadedForXmt (bit #8)         XM_IS_TX_PAGE
+ *     - AutoNegDone (bit #7)                  XM_IS_AND
+ *     Also probably not valid any more is the GP0 input bit:
+ *     - GPRegisterBit0set                     XM_IS_INP_ASS
+ *
+ * Returns:
+ *     nothing
+ */
+void SkXmIrq(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;
+       SK_EVPARA       Para;
+       SK_U16          IStatus;        /* Interrupt status read from the XMAC */
+       SK_U16          IStatus2;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       XM_IN16(IoC, Port, XM_ISRC, &IStatus);
+
+       /* LinkPartner Auto-negable? */
+       if (pPrt->PhyType == SK_PHY_XMAC) {
+               SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus);
+       }
+       else {
+               /* mask bits that are not used with ext. PHY */
+               IStatus &= ~(XM_IS_LNK_AE | XM_IS_LIPA_RC |
+                       XM_IS_RX_PAGE | XM_IS_TX_PAGE |
+                       XM_IS_AND | XM_IS_INP_ASS);
+       }
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+               ("XmacIrq Port %d Isr 0x%04x\n", Port, IStatus));
+
+       if (!pPrt->PHWLinkUp) {
+               /* Spurious XMAC interrupt */
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                       ("SkXmIrq: spurious interrupt on Port %d\n", Port));
+               return;
+       }
+
+       if ((IStatus & XM_IS_INP_ASS) != 0) {
+               /* Reread ISR Register if link is not in sync */
+               XM_IN16(IoC, Port, XM_ISRC, &IStatus2);
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                       ("SkXmIrq: Link async. Double check Port %d 0x%04x 0x%04x\n",
+                        Port, IStatus, IStatus2));
+               IStatus &= ~XM_IS_INP_ASS;
+               IStatus |= IStatus2;
+       }
+
+       if ((IStatus & XM_IS_LNK_AE) != 0) {
+               /* not used, GP0 is used instead */
+       }
+
+       if ((IStatus & XM_IS_TX_ABORT) != 0) {
+               /* not used */
+       }
+
+       if ((IStatus & XM_IS_FRC_INT) != 0) {
+               /* not used, use ASIC IRQ instead if needed */
+       }
+
+       if ((IStatus & (XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE)) != 0) {
+               SkHWLinkDown(pAC, IoC, Port);
+
+               /* Signal to RLMT */
+               Para.Para32[0] = (SK_U32)Port;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+
+               /* Start workaround Errata #2 timer */
+               SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
+                       SKGE_HWAC, SK_HWEV_WATIM, Para);
+       }
+
+       if ((IStatus & XM_IS_RX_PAGE) != 0) {
+               /* not used */
+       }
+
+       if ((IStatus & XM_IS_TX_PAGE) != 0) {
+               /* not used */
+       }
+
+       if ((IStatus & XM_IS_AND) != 0) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                       ("SkXmIrq: AND on link that is up Port %d\n", Port));
+       }
+
+       if ((IStatus & XM_IS_TSC_OV) != 0) {
+               /* not used */
+       }
+
+       /* Combined Tx & Rx Counter Overflow SIRQ Event */
+       if ((IStatus & (XM_IS_RXC_OV | XM_IS_TXC_OV)) != 0) {
+               Para.Para32[0] = (SK_U32)Port;
+               Para.Para32[1] = (SK_U32)IStatus;
+               SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
+       }
+
+       if ((IStatus & XM_IS_RXF_OV) != 0) {
+               /* normal situation -> no effect */
+#ifdef DEBUG
+               pPrt->PRxOverCnt++;
+#endif /* DEBUG */
+       }
+
+       if ((IStatus & XM_IS_TXF_UR) != 0) {
+               /* may NOT happen -> error log */
+               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG);
+       }
+
+       if ((IStatus & XM_IS_TX_COMP) != 0) {
+               /* not served here */
+       }
+
+       if ((IStatus & XM_IS_RX_COMP) != 0) {
+               /* not served here */
+       }
+}      /* SkXmIrq */
+
+
+/******************************************************************************
+ *
+ *     SkGmIrq() - Interrupt Service Routine
+ *
+ * Description:        services an Interrupt Request of the GMAC
+ *
+ * Note:
+ *
+ * Returns:
+ *     nothing
+ */
+void SkGmIrq(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;
+       SK_EVPARA       Para;
+       SK_U8           IStatus;        /* Interrupt status */
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       SK_IN8(IoC, GMAC_IRQ_SRC, &IStatus);
+
+       /* LinkPartner Auto-negable? */
+       SkMacAutoNegLipaPhy(pAC, IoC, Port, IStatus);
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+               ("GmacIrq Port %d Isr 0x%04x\n", Port, IStatus));
+
+       /* Combined Tx & Rx Counter Overflow SIRQ Event */
+       if (IStatus & (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV)) {
+               /* these IRQs will be cleared by reading GMACs register */
+               Para.Para32[0] = (SK_U32)Port;
+               Para.Para32[1] = (SK_U32)IStatus;
+               SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
+       }
+
+       if (IStatus & GM_IS_RX_FF_OR) {
+               /* clear GMAC Rx FIFO Overrun IRQ */
+               SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_CLI_RX_FO);
+#ifdef DEBUG
+               pPrt->PRxOverCnt++;
+#endif /* DEBUG */
+       }
+
+       if (IStatus & GM_IS_TX_FF_UR) {
+               /* clear GMAC Tx FIFO Underrun IRQ */
+               SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_CLI_TX_FU);
+               /* may NOT happen -> error log */
+               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG);
+       }
+
+       if (IStatus & GM_IS_TX_COMPL) {
+               /* not served here */
+       }
+
+       if (IStatus & GM_IS_RX_COMPL) {
+               /* not served here */
+       }
+}      /* SkGmIrq */
+
+/******************************************************************************
+ *
+ *     SkMacIrq() - Interrupt Service Routine for MAC
+ *
+ * Description:        calls the Interrupt Service Routine dep. on board type
+ *
+ * Returns:
+ *     nothing
+ */
+void SkMacIrq(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port)           /* Port Index (MAC_1 + n) */
+{
+
+       if (pAC->GIni.GIGenesis) {
+               /* IRQ from XMAC */
+               SkXmIrq(pAC, IoC, Port);
+       }
+       else {
+               /* IRQ from GMAC */
+               SkGmIrq(pAC, IoC, Port);
+       }
+}      /* SkMacIrq */
+
+#endif /* !SK_DIAG */
+
+/******************************************************************************
+ *
+ *     SkXmUpdateStats() - Force the XMAC to output the current statistic
+ *
+ * Description:
+ *     The XMAC holds its statistic internally. To obtain the current
+ *     values a command must be sent so that the statistic data will
+ *     be written to a predefined memory area on the adapter.
+ *
+ * Returns:
+ *     0:  success
+ *     1:  something went wrong
+ */
+int SkXmUpdateStats(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+unsigned int Port)     /* Port Index (MAC_1 + n) */
+{
+       SK_GEPORT       *pPrt;
+       SK_U16          StatReg;
+       int                     WaitIndex;
+
+       pPrt = &pAC->GIni.GP[Port];
+       WaitIndex = 0;
+
+       /* Send an update command to XMAC specified */
+       XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC);
+
+       /*
+        * It is an auto-clearing register. If the command bits
+        * went to zero again, the statistics are transferred.
+        * Normally the command should be executed immediately.
+        * But just to be sure we execute a loop.
+        */
+       do {
+
+               XM_IN16(IoC, Port, XM_STAT_CMD, &StatReg);
+
+               if (++WaitIndex > 10) {
+
+                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E021, SKERR_HWI_E021MSG);
+
+                       return(1);
+               }
+       } while ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) != 0);
+
+       return(0);
+}      /* SkXmUpdateStats */
+
+/******************************************************************************
+ *
+ *     SkGmUpdateStats() - Force the GMAC to output the current statistic
+ *
+ * Description:
+ *     Empty function for GMAC. Statistic data is accessible in direct way.
+ *
+ * Returns:
+ *     0:  success
+ *     1:  something went wrong
+ */
+int SkGmUpdateStats(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+unsigned int Port)     /* Port Index (MAC_1 + n) */
+{
+       return(0);
+}
+
+/******************************************************************************
+ *
+ *     SkXmMacStatistic() - Get XMAC counter value
+ *
+ * Description:
+ *     Gets the 32bit counter value. Except for the octet counters
+ *     the lower 32bit are counted in hardware and the upper 32bit
+ *     must be counted in software by monitoring counter overflow interrupts.
+ *
+ * Returns:
+ *     0:  success
+ *     1:  something went wrong
+ */
+int SkXmMacStatistic(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+unsigned int Port,     /* Port Index (MAC_1 + n) */
+SK_U16 StatAddr,       /* MIB counter base address */
+SK_U32 *pVal)          /* ptr to return statistic value */
+{
+       if ((StatAddr < XM_TXF_OK) || (StatAddr > XM_RXF_MAX_SZ)) {
+
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
+
+               return(1);
+       }
+
+       XM_IN32(IoC, Port, StatAddr, pVal);
+
+       return(0);
+}      /* SkXmMacStatistic */
+
+/******************************************************************************
+ *
+ *     SkGmMacStatistic() - Get GMAC counter value
+ *
+ * Description:
+ *     Gets the 32bit counter value. Except for the octet counters
+ *     the lower 32bit are counted in hardware and the upper 32bit
+ *     must be counted in software by monitoring counter overflow interrupts.
+ *
+ * Returns:
+ *     0:  success
+ *     1:  something went wrong
+ */
+int SkGmMacStatistic(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+unsigned int Port,     /* Port Index (MAC_1 + n) */
+SK_U16 StatAddr,       /* MIB counter base address */
+SK_U32 *pVal)          /* ptr to return statistic value */
+{
+
+       if ((StatAddr < GM_RXF_UC_OK) || (StatAddr > GM_TXE_FIFO_UR)) {
+
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
+
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("SkGmMacStat: wrong MIB counter 0x%04X\n", StatAddr));
+               return(1);
+       }
+
+       GM_IN32(IoC, Port, StatAddr, pVal);
+
+       return(0);
+}      /* SkGmMacStatistic */
+
+/******************************************************************************
+ *
+ *     SkXmResetCounter() - Clear MAC statistic counter
+ *
+ * Description:
+ *     Force the XMAC to clear its statistic counter.
+ *
+ * Returns:
+ *     0:  success
+ *     1:  something went wrong
+ */
+int SkXmResetCounter(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+unsigned int Port)     /* Port Index (MAC_1 + n) */
+{
+       XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
+       /* Clear two times according to Errata #3 */
+       XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
+
+       return(0);
+}      /* SkXmResetCounter */
+
+/******************************************************************************
+ *
+ *     SkGmResetCounter() - Clear MAC statistic counter
+ *
+ * Description:
+ *     Force GMAC to clear its statistic counter.
+ *
+ * Returns:
+ *     0:  success
+ *     1:  something went wrong
+ */
+int SkGmResetCounter(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+unsigned int Port)     /* Port Index (MAC_1 + n) */
+{
+       SK_U16  Reg;    /* Phy Address Register */
+       SK_U16  Word;
+       int             i;
+
+       GM_IN16(IoC, Port, GM_PHY_ADDR, &Reg);
+
+#ifndef VCPU
+       /* set MIB Clear Counter Mode */
+       GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg | GM_PAR_MIB_CLR);
+
+       /* read all MIB Counters with Clear Mode set */
+       for (i = 0; i < GM_MIB_CNT_SIZE; i++) {
+               /* the reset is performed only when the lower 16 bits are read */
+               GM_IN16(IoC, Port, GM_MIB_CNT_BASE + 8*i, &Word);
+       }
+
+       /* clear MIB Clear Counter Mode */
+       GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg);
+#endif /* !VCPU */
+
+       return(0);
+}      /* SkGmResetCounter */
+
+/******************************************************************************
+ *
+ *     SkXmOverflowStatus() - Gets the status of counter overflow interrupt
+ *
+ * Description:
+ *     Checks the source causing an counter overflow interrupt. On success the
+ *     resulting counter overflow status is written to <pStatus>, whereas the
+ *     upper dword stores the XMAC ReceiveCounterEvent register and the lower
+ *     dword the XMAC TransmitCounterEvent register.
+ *
+ * Note:
+ *     For XMAC the interrupt source is a self-clearing register, so the source
+ *     must be checked only once. SIRQ module does another check to be sure
+ *     that no interrupt get lost during process time.
+ *
+ * Returns:
+ *     0:  success
+ *     1:  something went wrong
+ */
+int SkXmOverflowStatus(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+unsigned int Port,     /* Port Index (MAC_1 + n) */
+SK_U16  IStatus,       /* Interupt Status from MAC */
+SK_U64 *pStatus)       /* ptr for return overflow status value */
+{
+       SK_U64  Status; /* Overflow status */
+       SK_U32  RegVal;
+
+       Status = 0;
+
+       if ((IStatus & XM_IS_RXC_OV) != 0) {
+
+               XM_IN32(IoC, Port, XM_RX_CNT_EV, &RegVal);
+               Status |= (SK_U64)RegVal << 32;
+       }
+
+       if ((IStatus & XM_IS_TXC_OV) != 0) {
+
+               XM_IN32(IoC, Port, XM_TX_CNT_EV, &RegVal);
+               Status |= (SK_U64)RegVal;
+       }
+
+       *pStatus = Status;
+
+       return(0);
+}      /* SkXmOverflowStatus */
+
+
+/******************************************************************************
+ *
+ *     SkGmOverflowStatus() - Gets the status of counter overflow interrupt
+ *
+ * Description:
+ *     Checks the source causing an counter overflow interrupt. On success the
+ *     resulting counter overflow status is written to <pStatus>, whereas the
+ *     the following bit coding is used:
+ *     63:56 - unused
+ *     55:48 - TxRx interrupt register bit7:0
+ *     32:47 - Rx interrupt register
+ *     31:24 - unused
+ *     23:16 - TxRx interrupt register bit15:8
+ *     15:0  - Tx interrupt register
+ *
+ * Returns:
+ *     0:  success
+ *     1:  something went wrong
+ */
+int SkGmOverflowStatus(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+unsigned int Port,     /* Port Index (MAC_1 + n) */
+SK_U16  IStatus,       /* Interupt Status from MAC */
+SK_U64 *pStatus)       /* ptr for return overflow status value */
+{
+       SK_U64  Status;         /* Overflow status */
+       SK_U16  RegVal;
+
+       Status = 0;
+
+       if ((IStatus & GM_IS_RX_CO_OV) != 0) {
+               /* this register is self-clearing after read */
+               GM_IN16(IoC, Port, GM_RX_IRQ_SRC, &RegVal);
+               Status |= (SK_U64)RegVal << 32;
+       }
+
+       if ((IStatus & GM_IS_TX_CO_OV) != 0) {
+               /* this register is self-clearing after read */
+               GM_IN16(IoC, Port, GM_TX_IRQ_SRC, &RegVal);
+               Status |= (SK_U64)RegVal;
+       }
+
+       /* this register is self-clearing after read */
+       GM_IN16(IoC, Port, GM_TR_IRQ_SRC, &RegVal);
+       /* Rx overflow interrupt register bits (LoByte)*/
+       Status |= (SK_U64)((SK_U8)RegVal) << 48;
+       /* Tx overflow interrupt register bits (HiByte)*/
+       Status |= (SK_U64)(RegVal >> 8) << 16;
+
+       *pStatus = Status;
+
+       return(0);
+}      /* SkGmOverflowStatus */
+
+/******************************************************************************
+ *
+ *     SkGmCableDiagStatus() - Starts / Gets status of cable diagnostic test
+ *
+ * Description:
+ *  starts the cable diagnostic test if 'StartTest' is true
+ *  gets the results if 'StartTest' is true
+ *
+ * NOTE:       this test is meaningful only when link is down
+ *
+ * Returns:
+ *     0:  success
+ *     1:      no YUKON copper
+ *     2:      test in progress
+ */
+int SkGmCableDiagStatus(
+SK_AC  *pAC,           /* adapter context */
+SK_IOC IoC,            /* IO context */
+int            Port,           /* Port Index (MAC_1 + n) */
+SK_BOOL        StartTest)      /* flag for start / get result */
+{
+       int             i;
+       SK_U16  RegVal;
+       SK_GEPORT       *pPrt;
+
+       pPrt = &pAC->GIni.GP[Port];
+
+       if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
+
+               return(1);
+       }
+
+       if (StartTest) {
+               /* only start the cable test */
+               if ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4) {
+                       /* apply TDR workaround from Marvell */
+                       SkGmPhyWrite(pAC, IoC, Port, 29, 0x001e);
+
+                       SkGmPhyWrite(pAC, IoC, Port, 30, 0xcc00);
+                       SkGmPhyWrite(pAC, IoC, Port, 30, 0xc800);
+                       SkGmPhyWrite(pAC, IoC, Port, 30, 0xc400);
+                       SkGmPhyWrite(pAC, IoC, Port, 30, 0xc000);
+                       SkGmPhyWrite(pAC, IoC, Port, 30, 0xc100);
+               }
+
+               /* set address to 0 for MDI[0] */
+               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0);
+
+               /* Read Cable Diagnostic Reg */
+               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
+
+               /* start Cable Diagnostic Test */
+               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CABLE_DIAG,
+                       (SK_U16)(RegVal | PHY_M_CABD_ENA_TEST));
+
+               return(0);
+       }
+
+       /* Read Cable Diagnostic Reg */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
+
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("PHY Cable Diag.=0x%04X\n", RegVal));
+
+       if ((RegVal & PHY_M_CABD_ENA_TEST) != 0) {
+               /* test is running */
+               return(2);
+       }
+
+       /* get the test results */
+       for (i = 0; i < 4; i++)  {
+               /* set address to i for MDI[i] */
+               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i);
+
+               /* get Cable Diagnostic values */
+               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
+
+               pPrt->PMdiPairLen[i] = (SK_U8)(RegVal & PHY_M_CABD_DIST_MSK);
+
+               pPrt->PMdiPairSts[i] = (SK_U8)((RegVal & PHY_M_CABD_STAT_MSK) >> 13);
+       }
+
+       return(0);
+}      /* SkGmCableDiagStatus */
+
+#endif /* CONFIG_SK98 */
+
+/* End of file */
diff --git a/drivers/net/sk98lin/u-boot_compat.h b/drivers/net/sk98lin/u-boot_compat.h
new file mode 100644 (file)
index 0000000..1e385f8
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _UBOOT_COMPAT_H__
+#define _UBOOT_COMPAT_H__
+
+
+#include <pci.h>
+#include <pci_ids.h>
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+
+#define        __initdata
+#define __init
+#define __exit
+
+#define netif_stop_queue(x)
+#define netif_wake_queue(x)
+#define netif_running(x)               0
+#define unregister_netdev(x)
+#define remove_proc_entry(x,y)
+
+#define dev_addr                       enetaddr
+
+#define        spin_lock_irqsave(x,y) y = 0;
+#define spin_lock_init(x)
+#define spin_lock(x)
+#define spin_unlock_irqrestore(x,y)
+#define spin_unlock(x)
+
+
+#define ENODEV                         1
+#define EAGAIN                         2
+#define EBUSY                          3
+
+#define HZ                             CFG_HZ
+
+
+#define printk                         printf
+#define KERN_ERR
+#define KERN_WARNING
+#define KERN_INFO
+
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+
+
+#define kmalloc(x,y)                   malloc(x)
+#define kfree(x)                       free(x)
+#define GFP_ATOMIC                     0
+
+#define pci_alloc_consistent(x,y,z)    (void *)(*(dma_addr_t *)(z) = (dma_addr_t)malloc(y))
+#define pci_free_consistent(x,y,z,d)   free(z)
+#define pci_dma_sync_single(x,y,z,d)
+#define pci_unmap_page(x,y,z,d)
+#define pci_unmap_single(x,y,z,d)
+#define pci_present()                  1
+
+struct sk_buff
+{
+       u8 * data;
+       u32 len;
+       u8 * data_unaligned;
+};
+
+struct sk_buff * alloc_skb(u32 size, int dummy);
+void dev_kfree_skb_any(struct sk_buff *skb);
+void skb_reserve(struct sk_buff *skb, unsigned int len);
+void skb_put(struct sk_buff *skb, unsigned int len);
+
+#define dev_kfree_skb                          dev_kfree_skb_any
+#define dev_kfree_skb_irq                      dev_kfree_skb_any
+
+#define eth_copy_and_sum(dest,src,len,base)    memcpy(dest->data,src,len);
+
+
+#endif /* _UBOOT_COMPAT_H__ */
diff --git a/drivers/net/sk98lin/uboot_drv.c b/drivers/net/sk98lin/uboot_drv.c
new file mode 100644 (file)
index 0000000..d02cd1b
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Driver for SysKonnect Gigabit Ethernet Server Adapters.
+ *
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
+       defined(CONFIG_SK98)
+
+#include "h/skdrv1st.h"
+#include "h/skdrv2nd.h"
+#include "u-boot_compat.h"
+
+
+#define SKGE_MAX_CARDS 2
+
+
+extern int skge_probe(struct eth_device **);
+extern void SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs);
+extern void SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs);
+extern int SkGeOpen(struct eth_device *);
+extern int SkGeClose(struct eth_device *);
+extern int SkGeXmit(struct sk_buff *skb, struct eth_device *dev);
+extern void ReceiveIrq(SK_AC *pAC, RX_PORT *pRxPort, SK_BOOL SlowPathLock);
+
+static int skge_init(struct eth_device *dev, bd_t * bis);
+static int skge_send(struct eth_device *dev, volatile void *packet, int length);
+static int skge_recv(struct eth_device *dev);
+static void skge_halt(struct eth_device *dev);
+
+int skge_initialize(bd_t * bis)
+{
+       int numdev, i;
+       struct eth_device *dev[SKGE_MAX_CARDS];
+
+       numdev = skge_probe(&dev[0]);
+
+       if (numdev > SKGE_MAX_CARDS)
+       {
+               printf("ERROR: numdev > SKGE_MAX_CARDS\n");
+       }
+
+       for (i = 0; i < numdev; i++)
+       {
+               sprintf (dev[i]->name, "SK98#%d", i);
+
+               dev[i]->init = skge_init;
+               dev[i]->halt = skge_halt;
+               dev[i]->send = skge_send;
+               dev[i]->recv = skge_recv;
+
+               eth_register(dev[i]);
+       }
+
+       return numdev;
+}
+
+
+static int skge_init(struct eth_device *dev, bd_t * bis)
+{
+       int ret;
+       SK_AC * pAC = ((DEV_NET*)dev->priv)->pAC;
+       int i;
+
+       ret = SkGeOpen(dev);
+
+       while (pAC->Rlmt.Port[0].PortState != SK_RLMT_PS_GOING_UP)
+       {
+               SkGeIsrOnePort (0, pAC->dev[0], 0);
+       }
+
+       for (i = 0; i < 100; i ++)
+       {
+               udelay(1000);
+       }
+
+       return ret;
+}
+
+
+static void skge_halt(struct eth_device *dev)
+{
+       SkGeClose(dev);
+}
+
+
+static int skge_send(struct eth_device *dev, volatile void *packet,
+                                                 int length)
+{
+       int ret = -1;
+       struct sk_buff * skb = alloc_skb(length, 0);
+
+       if (! skb)
+       {
+               printf("skge_send: failed to alloc skb\n");
+               goto Done;
+       }
+
+       memcpy(skb->data, (void*)packet, length);
+       ret = SkGeXmit(skb, dev);
+
+Done:
+       return ret;
+}
+
+
+static int skge_recv(struct eth_device *dev)
+{
+       DEV_NET         *pNet;
+       SK_AC           *pAC;
+       int             FromPort = 0;
+
+       pNet = (DEV_NET*) dev->priv;
+       pAC = pNet->pAC;
+
+       ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE);
+
+       return 0;
+}
+
+
+#endif /* CONFIG_SK98 */
diff --git a/drivers/net/sk98lin/uboot_skb.c b/drivers/net/sk98lin/uboot_skb.c
new file mode 100644 (file)
index 0000000..3a487a8
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Definitions for the 'struct sk_buff' memory handlers in U-Boot.
+ *
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+
+#ifdef CONFIG_SK98
+
+#include <common.h>
+#include "u-boot_compat.h"
+
+#define MAX_SKB                50
+
+static struct sk_buff *sk_table[MAX_SKB];
+
+
+struct sk_buff * alloc_skb(u32 size, int dummy)
+{
+       int i;
+       struct sk_buff * ret = NULL;
+
+       for (i = 0; i < MAX_SKB; i++)
+       {
+               if (sk_table[i])
+               {
+                               /* Already allocated.
+                                */
+                       continue;
+               }
+
+               sk_table[i] = malloc(sizeof(struct sk_buff));
+               if (! sk_table[i])
+               {
+                       printf("alloc_skb: malloc failed\n");
+                       break;
+               }
+
+               memset(sk_table[i], 0, sizeof(struct sk_buff));
+               sk_table[i]->data = sk_table[i]->data_unaligned =
+                                                           malloc(size + 16);
+               if (! sk_table[i]->data)
+               {
+                       printf("alloc_skb: malloc failed\n");
+                       free(sk_table[i]);
+                       sk_table[i] = NULL;
+                       break;
+               }
+
+               sk_table[i]->data += 16 - ((u32)sk_table[i]->data & 15);
+               sk_table[i]->len = size;
+
+               break;
+       }
+
+       if (i < MAX_SKB)
+       {
+               ret = sk_table[i];
+       }
+
+       if (! ret)
+       {
+               printf("Unable to allocate skb!\n");
+       }
+
+       return ret;
+}
+
+void dev_kfree_skb_any(struct sk_buff *skb)
+{
+       int i;
+
+       for (i = 0; i < MAX_SKB; i++)
+       {
+               if (sk_table[i] != skb)
+               {
+                       continue;
+               }
+
+               free(skb->data_unaligned);
+               free(skb);
+               sk_table[i] = NULL;
+               break;
+       }
+
+       if (i == MAX_SKB)
+       {
+               printf("SKB allocation error!\n");
+       }
+}
+
+void skb_reserve(struct sk_buff *skb, unsigned int len)
+{
+       skb->data+=len;
+}
+
+void skb_put(struct sk_buff *skb, unsigned int len)
+{
+       skb->len+=len;
+}
+
+#endif /* CONFIG_SK98 */
diff --git a/drivers/net/smc91111.c b/drivers/net/smc91111.c
new file mode 100644 (file)
index 0000000..8061f12
--- /dev/null
@@ -0,0 +1,1623 @@
+/*------------------------------------------------------------------------
+ . smc91111.c
+ . This is a driver for SMSC's 91C111 single-chip Ethernet device.
+ .
+ . (C) Copyright 2002
+ . Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ . Rolf Offermanns <rof@sysgo.de>
+ .
+ . Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
+ .      Developed by Simple Network Magic Corporation (SNMC)
+ . Copyright (C) 1996 by Erik Stahlman (ES)
+ .
+ . This program is free software; you can redistribute it and/or modify
+ . it under the terms of the GNU General Public License as published by
+ . the Free Software Foundation; either version 2 of the License, or
+ . (at your option) any later version.
+ .
+ . This program is distributed in the hope that it will be useful,
+ . but WITHOUT ANY WARRANTY; without even the implied warranty of
+ . MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ . GNU General Public License for more details.
+ .
+ . You should have received a copy of the GNU General Public License
+ . along with this program; if not, write to the Free Software
+ . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307         USA
+ .
+ . Information contained in this file was obtained from the LAN91C111
+ . manual from SMC.  To get a copy, if you really want one, you can find
+ . information under www.smsc.com.
+ .
+ .
+ . "Features" of the SMC chip:
+ .   Integrated PHY/MAC for 10/100BaseT Operation
+ .   Supports internal and external MII
+ .   Integrated 8K packet memory
+ .   EEPROM interface for configuration
+ .
+ . Arguments:
+ .     io      = for the base address
+ .     irq     = for the IRQ
+ .
+ . author:
+ .     Erik Stahlman                           ( erik@vt.edu )
+ .     Daris A Nevil                           ( dnevil@snmc.com )
+ .
+ .
+ . Hardware multicast code from Peter Cammaert ( pc@denkart.be )
+ .
+ . Sources:
+ .    o          SMSC LAN91C111 databook (www.smsc.com)
+ .    o          smc9194.c by Erik Stahlman
+ .    o          skeleton.c by Donald Becker ( becker@cesdis.gsfc.nasa.gov )
+ .
+ . History:
+ .     06/19/03  Richard Woodruff Made u-boot environment aware and added mac addr checks.
+ .     10/17/01  Marco Hasewinkel Modify for DNP/1110
+ .     07/25/01  Woojung Huh      Modify for ADS Bitsy
+ .     04/25/01  Daris A Nevil    Initial public release through SMSC
+ .     03/16/01  Daris A Nevil    Modified smc9194.c for use with LAN91C111
+ ----------------------------------------------------------------------------*/
+
+#include <common.h>
+#include <command.h>
+#include <config.h>
+#include "smc91111.h"
+#include <net.h>
+
+#ifdef CONFIG_DRIVER_SMC91111
+
+/* Use power-down feature of the chip */
+#define POWER_DOWN     0
+
+#define NO_AUTOPROBE
+
+#define SMC_DEBUG 0
+
+#if SMC_DEBUG > 1
+static const char version[] =
+       "smc91111.c:v1.0 04/25/01 by Daris A Nevil (dnevil@snmc.com)\n";
+#endif
+
+/* Autonegotiation timeout in seconds */
+#ifndef CONFIG_SMC_AUTONEG_TIMEOUT
+#define CONFIG_SMC_AUTONEG_TIMEOUT 10
+#endif
+
+/*------------------------------------------------------------------------
+ .
+ . Configuration options, for the experienced user to change.
+ .
+ -------------------------------------------------------------------------*/
+
+/*
+ . Wait time for memory to be free.  This probably shouldn't be
+ . tuned that much, as waiting for this means nothing else happens
+ . in the system
+*/
+#define MEMORY_WAIT_TIME 16
+
+
+#if (SMC_DEBUG > 2 )
+#define PRINTK3(args...) printf(args)
+#else
+#define PRINTK3(args...)
+#endif
+
+#if SMC_DEBUG > 1
+#define PRINTK2(args...) printf(args)
+#else
+#define PRINTK2(args...)
+#endif
+
+#ifdef SMC_DEBUG
+#define PRINTK(args...) printf(args)
+#else
+#define PRINTK(args...)
+#endif
+
+
+/*------------------------------------------------------------------------
+ .
+ . The internal workings of the driver.         If you are changing anything
+ . here with the SMC stuff, you should have the datasheet and know
+ . what you are doing.
+ .
+ -------------------------------------------------------------------------*/
+#define CARDNAME "LAN91C111"
+
+/* Memory sizing constant */
+#define LAN91C111_MEMORY_MULTIPLIER    (1024*2)
+
+#ifndef CONFIG_SMC91111_BASE
+#define CONFIG_SMC91111_BASE 0x20000300
+#endif
+
+#define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE
+
+#define SMC_DEV_NAME "SMC91111"
+#define SMC_PHY_ADDR 0x0000
+#define SMC_ALLOC_MAX_TRY 5
+#define SMC_TX_TIMEOUT 30
+
+#define SMC_PHY_CLOCK_DELAY 1000
+
+#define ETH_ZLEN 60
+
+#ifdef CONFIG_SMC_USE_32_BIT
+#define USE_32_BIT  1
+#else
+#undef USE_32_BIT
+#endif
+/*-----------------------------------------------------------------
+ .
+ .  The driver can be entered at any of the following entry points.
+ .
+ .------------------------------------------------------------------  */
+
+extern int eth_init(bd_t *bd);
+extern void eth_halt(void);
+extern int eth_rx(void);
+extern int eth_send(volatile void *packet, int length);
+
+#ifdef SHARED_RESOURCES
+       extern void swap_to(int device_id);
+#endif
+
+/*
+ . This is called by  register_netdev().  It is responsible for
+ . checking the portlist for the SMC9000 series chipset.  If it finds
+ . one, then it will initialize the device, find the hardware information,
+ . and sets up the appropriate device parameters.
+ . NOTE: Interrupts are *OFF* when this procedure is called.
+ .
+ . NB:This shouldn't be static since it is referred to externally.
+*/
+int smc_init(void);
+
+/*
+ . This is called by  unregister_netdev().  It is responsible for
+ . cleaning up before the driver is finally unregistered and discarded.
+*/
+void smc_destructor(void);
+
+/*
+ . The kernel calls this function when someone wants to use the device,
+ . typically 'ifconfig ethX up'.
+*/
+static int smc_open(bd_t *bd);
+
+
+/*
+ . This is called by the kernel in response to 'ifconfig ethX down'.  It
+ . is responsible for cleaning up everything that the open routine
+ . does, and maybe putting the card into a powerdown state.
+*/
+static int smc_close(void);
+
+/*
+ . Configures the PHY through the MII Management interface
+*/
+#ifndef CONFIG_SMC91111_EXT_PHY
+static void smc_phy_configure(void);
+#endif /* !CONFIG_SMC91111_EXT_PHY */
+
+/*
+ . This is a separate procedure to handle the receipt of a packet, to
+ . leave the interrupt code looking slightly cleaner
+*/
+static int smc_rcv(void);
+
+/* See if a MAC address is defined in the current environment. If so use it. If not
+ . print a warning and set the environment and other globals with the default.
+ . If an EEPROM is present it really should be consulted.
+*/
+int smc_get_ethaddr(bd_t *bd);
+int get_rom_mac(uchar *v_rom_mac);
+
+/*
+ ------------------------------------------------------------
+ .
+ . Internal routines
+ .
+ ------------------------------------------------------------
+*/
+
+#ifdef CONFIG_SMC_USE_IOFUNCS
+/*
+ * input and output functions
+ *
+ * Implemented due to inx,outx macros accessing the device improperly
+ * and putting the device into an unkown state.
+ *
+ * For instance, on Sharp LPD7A400 SDK, affects were chip memory
+ * could not be free'd (hence the alloc failures), duplicate packets,
+ * packets being corrupt (shifted) on the wire, etc.  Switching to the
+ * inx,outx functions fixed this problem.
+ */
+static inline word SMC_inw(dword offset);
+static inline void SMC_outw(word value, dword offset);
+static inline byte SMC_inb(dword offset);
+static inline void SMC_outb(byte value, dword offset);
+static inline void SMC_insw(dword offset, volatile uchar* buf, dword len);
+static inline void SMC_outsw(dword offset, uchar* buf, dword len);
+
+#define barrier() __asm__ __volatile__("": : :"memory")
+
+static inline word SMC_inw(dword offset)
+{
+       word v;
+       v = *((volatile word*)(SMC_BASE_ADDRESS+offset));
+       barrier(); *(volatile u32*)(0xc0000000);
+       return v;
+}
+
+static inline void SMC_outw(word value, dword offset)
+{
+       *((volatile word*)(SMC_BASE_ADDRESS+offset)) = value;
+       barrier(); *(volatile u32*)(0xc0000000);
+}
+
+static inline byte SMC_inb(dword offset)
+{
+       word  _w;
+
+       _w = SMC_inw(offset & ~((dword)1));
+       return (offset & 1) ? (byte)(_w >> 8) : (byte)(_w);
+}
+
+static inline void SMC_outb(byte value, dword offset)
+{
+       word  _w;
+
+       _w = SMC_inw(offset & ~((dword)1));
+       if (offset & 1)
+                       *((volatile word*)(SMC_BASE_ADDRESS+(offset & ~((dword)1)))) = (value<<8) | (_w & 0x00ff);
+       else
+                       *((volatile word*)(SMC_BASE_ADDRESS+offset)) = value | (_w & 0xff00);
+}
+
+static inline void SMC_insw(dword offset, volatile uchar* buf, dword len)
+{
+       volatile word *p = (volatile word *)buf;
+
+       while (len-- > 0) {
+               *p++ = SMC_inw(offset);
+               barrier();
+               *((volatile u32*)(0xc0000000));
+       }
+}
+
+static inline void SMC_outsw(dword offset, uchar* buf, dword len)
+{
+       volatile word *p = (volatile word *)buf;
+
+       while (len-- > 0) {
+               SMC_outw(*p++, offset);
+               barrier();
+               *(volatile u32*)(0xc0000000);
+       }
+}
+#endif  /* CONFIG_SMC_USE_IOFUNCS */
+
+static char unsigned smc_mac_addr[6] = {0x02, 0x80, 0xad, 0x20, 0x31, 0xb8};
+
+/*
+ * This function must be called before smc_open() if you want to override
+ * the default mac address.
+ */
+
+void smc_set_mac_addr(const unsigned char *addr) {
+       int i;
+
+       for (i=0; i < sizeof(smc_mac_addr); i++){
+               smc_mac_addr[i] = addr[i];
+       }
+}
+
+/*
+ * smc_get_macaddr is no longer used. If you want to override the default
+ * mac address, call smc_get_mac_addr as a part of the board initialization.
+ */
+
+#if 0
+void smc_get_macaddr( byte *addr ) {
+       /* MAC ADDRESS AT FLASHBLOCK 1 / OFFSET 0x10 */
+       unsigned char *dnp1110_mac = (unsigned char *) (0xE8000000 + 0x20010);
+       int i;
+
+
+       for (i=0; i<6; i++) {
+           addr[0] = *(dnp1110_mac+0);
+           addr[1] = *(dnp1110_mac+1);
+           addr[2] = *(dnp1110_mac+2);
+           addr[3] = *(dnp1110_mac+3);
+           addr[4] = *(dnp1110_mac+4);
+           addr[5] = *(dnp1110_mac+5);
+       }
+}
+#endif /* 0 */
+
+/***********************************************
+ * Show available memory                      *
+ ***********************************************/
+void dump_memory_info(void)
+{
+       word mem_info;
+       word old_bank;
+
+       old_bank = SMC_inw(BANK_SELECT)&0xF;
+
+       SMC_SELECT_BANK(0);
+       mem_info = SMC_inw( MIR_REG );
+       PRINTK2("Memory: %4d available\n", (mem_info >> 8)*2048);
+
+       SMC_SELECT_BANK(old_bank);
+}
+/*
+ . A rather simple routine to print out a packet for debugging purposes.
+*/
+#if SMC_DEBUG > 2
+static void print_packet( byte *, int );
+#endif
+
+#define tx_done(dev) 1
+
+
+/* this does a soft reset on the device */
+static void smc_reset( void );
+
+/* Enable Interrupts, Receive, and Transmit */
+static void smc_enable( void );
+
+/* this puts the device in an inactive state */
+static void smc_shutdown( void );
+
+/* Routines to Read and Write the PHY Registers across the
+   MII Management Interface
+*/
+
+#ifndef CONFIG_SMC91111_EXT_PHY
+static word smc_read_phy_register(byte phyreg);
+static void smc_write_phy_register(byte phyreg, word phydata);
+#endif /* !CONFIG_SMC91111_EXT_PHY */
+
+
+static int poll4int (byte mask, int timeout)
+{
+       int tmo = get_timer (0) + timeout * CFG_HZ;
+       int is_timeout = 0;
+       word old_bank = SMC_inw (BSR_REG);
+
+       PRINTK2 ("Polling...\n");
+       SMC_SELECT_BANK (2);
+       while ((SMC_inw (SMC91111_INT_REG) & mask) == 0) {
+               if (get_timer (0) >= tmo) {
+                       is_timeout = 1;
+                       break;
+               }
+       }
+
+       /* restore old bank selection */
+       SMC_SELECT_BANK (old_bank);
+
+       if (is_timeout)
+               return 1;
+       else
+               return 0;
+}
+
+/* Only one release command at a time, please */
+static inline void smc_wait_mmu_release_complete (void)
+{
+       int count = 0;
+
+       /* assume bank 2 selected */
+       while (SMC_inw (MMU_CMD_REG) & MC_BUSY) {
+               udelay (1);     /* Wait until not busy */
+               if (++count > 200)
+                       break;
+       }
+}
+
+/*
+ . Function: smc_reset( void )
+ . Purpose:
+ .     This sets the SMC91111 chip to its normal state, hopefully from whatever
+ .     mess that any other DOS driver has put it in.
+ .
+ . Maybe I should reset more registers to defaults in here?  SOFTRST  should
+ . do that for me.
+ .
+ . Method:
+ .     1.  send a SOFT RESET
+ .     2.  wait for it to finish
+ .     3.  enable autorelease mode
+ .     4.  reset the memory management unit
+ .     5.  clear all interrupts
+ .
+*/
+static void smc_reset (void)
+{
+       PRINTK2 ("%s: smc_reset\n", SMC_DEV_NAME);
+
+       /* This resets the registers mostly to defaults, but doesn't
+          affect EEPROM.  That seems unnecessary */
+       SMC_SELECT_BANK (0);
+       SMC_outw (RCR_SOFTRST, RCR_REG);
+
+       /* Setup the Configuration Register */
+       /* This is necessary because the CONFIG_REG is not affected */
+       /* by a soft reset */
+
+       SMC_SELECT_BANK (1);
+#if defined(CONFIG_SMC91111_EXT_PHY)
+       SMC_outw (CONFIG_DEFAULT | CONFIG_EXT_PHY, CONFIG_REG);
+#else
+       SMC_outw (CONFIG_DEFAULT, CONFIG_REG);
+#endif
+
+
+       /* Release from possible power-down state */
+       /* Configuration register is not affected by Soft Reset */
+       SMC_outw (SMC_inw (CONFIG_REG) | CONFIG_EPH_POWER_EN, CONFIG_REG);
+
+       SMC_SELECT_BANK (0);
+
+       /* this should pause enough for the chip to be happy */
+       udelay (10);
+
+       /* Disable transmit and receive functionality */
+       SMC_outw (RCR_CLEAR, RCR_REG);
+       SMC_outw (TCR_CLEAR, TCR_REG);
+
+       /* set the control register */
+       SMC_SELECT_BANK (1);
+       SMC_outw (CTL_DEFAULT, CTL_REG);
+
+       /* Reset the MMU */
+       SMC_SELECT_BANK (2);
+       smc_wait_mmu_release_complete ();
+       SMC_outw (MC_RESET, MMU_CMD_REG);
+       while (SMC_inw (MMU_CMD_REG) & MC_BUSY)
+               udelay (1);     /* Wait until not busy */
+
+       /* Note:  It doesn't seem that waiting for the MMU busy is needed here,
+          but this is a place where future chipsets _COULD_ break.  Be wary
+          of issuing another MMU command right after this */
+
+       /* Disable all interrupts */
+       SMC_outb (0, IM_REG);
+}
+
+/*
+ . Function: smc_enable
+ . Purpose: let the chip talk to the outside work
+ . Method:
+ .     1.  Enable the transmitter
+ .     2.  Enable the receiver
+ .     3.  Enable interrupts
+*/
+static void smc_enable()
+{
+       PRINTK2("%s: smc_enable\n", SMC_DEV_NAME);
+       SMC_SELECT_BANK( 0 );
+       /* see the header file for options in TCR/RCR DEFAULT*/
+       SMC_outw( TCR_DEFAULT, TCR_REG );
+       SMC_outw( RCR_DEFAULT, RCR_REG );
+
+       /* clear MII_DIS */
+/*     smc_write_phy_register(PHY_CNTL_REG, 0x0000); */
+}
+
+/*
+ . Function: smc_shutdown
+ . Purpose:  closes down the SMC91xxx chip.
+ . Method:
+ .     1. zero the interrupt mask
+ .     2. clear the enable receive flag
+ .     3. clear the enable xmit flags
+ .
+ . TODO:
+ .   (1) maybe utilize power down mode.
+ .     Why not yet?  Because while the chip will go into power down mode,
+ .     the manual says that it will wake up in response to any I/O requests
+ .     in the register space.   Empirical results do not show this working.
+*/
+static void smc_shutdown()
+{
+       PRINTK2(CARDNAME ": smc_shutdown\n");
+
+       /* no more interrupts for me */
+       SMC_SELECT_BANK( 2 );
+       SMC_outb( 0, IM_REG );
+
+       /* and tell the card to stay away from that nasty outside world */
+       SMC_SELECT_BANK( 0 );
+       SMC_outb( RCR_CLEAR, RCR_REG );
+       SMC_outb( TCR_CLEAR, TCR_REG );
+#ifdef SHARED_RESOURCES
+       swap_to(FLASH);
+#endif
+}
+
+
+/*
+ . Function:  smc_hardware_send_packet(struct net_device * )
+ . Purpose:
+ .     This sends the actual packet to the SMC9xxx chip.
+ .
+ . Algorithm:
+ .     First, see if a saved_skb is available.
+ .             ( this should NOT be called if there is no 'saved_skb'
+ .     Now, find the packet number that the chip allocated
+ .     Point the data pointers at it in memory
+ .     Set the length word in the chip's memory
+ .     Dump the packet to chip memory
+ .     Check if a last byte is needed ( odd length packet )
+ .             if so, set the control flag right
+ .     Tell the card to send it
+ .     Enable the transmit interrupt, so I know if it failed
+ .     Free the kernel data if I actually sent it.
+*/
+static int smc_send_packet (volatile void *packet, int packet_length)
+{
+       byte packet_no;
+       unsigned long ioaddr;
+       byte *buf;
+       int length;
+       int numPages;
+       int try = 0;
+       int time_out;
+       byte status;
+       byte saved_pnr;
+       word saved_ptr;
+
+       /* save PTR and PNR registers before manipulation */
+       SMC_SELECT_BANK (2);
+       saved_pnr = SMC_inb( PN_REG );
+       saved_ptr = SMC_inw( PTR_REG );
+
+       PRINTK3 ("%s: smc_hardware_send_packet\n", SMC_DEV_NAME);
+
+       length = ETH_ZLEN < packet_length ? packet_length : ETH_ZLEN;
+
+       /* allocate memory
+        ** The MMU wants the number of pages to be the number of 256 bytes
+        ** 'pages', minus 1 ( since a packet can't ever have 0 pages :) )
+        **
+        ** The 91C111 ignores the size bits, but the code is left intact
+        ** for backwards and future compatibility.
+        **
+        ** Pkt size for allocating is data length +6 (for additional status
+        ** words, length and ctl!)
+        **
+        ** If odd size then last byte is included in this header.
+        */
+       numPages = ((length & 0xfffe) + 6);
+       numPages >>= 8;         /* Divide by 256 */
+
+       if (numPages > 7) {
+               printf ("%s: Far too big packet error. \n", SMC_DEV_NAME);
+               return 0;
+       }
+
+       /* now, try to allocate the memory */
+       SMC_SELECT_BANK (2);
+       SMC_outw (MC_ALLOC | numPages, MMU_CMD_REG);
+
+       /* FIXME: the ALLOC_INT bit never gets set *
+        * so the following will always give a     *
+        * memory allocation error.                *
+        * same code works in armboot though       *
+        * -ro
+        */
+
+again:
+       try++;
+       time_out = MEMORY_WAIT_TIME;
+       do {
+               status = SMC_inb (SMC91111_INT_REG);
+               if (status & IM_ALLOC_INT) {
+                       /* acknowledge the interrupt */
+                       SMC_outb (IM_ALLOC_INT, SMC91111_INT_REG);
+                       break;
+               }
+       } while (--time_out);
+
+       if (!time_out) {
+               PRINTK2 ("%s: memory allocation, try %d failed ...\n",
+                        SMC_DEV_NAME, try);
+               if (try < SMC_ALLOC_MAX_TRY)
+                       goto again;
+               else
+                       return 0;
+       }
+
+       PRINTK2 ("%s: memory allocation, try %d succeeded ...\n",
+                SMC_DEV_NAME, try);
+
+       /* I can send the packet now.. */
+
+       ioaddr = SMC_BASE_ADDRESS;
+
+       buf = (byte *) packet;
+
+       /* If I get here, I _know_ there is a packet slot waiting for me */
+       packet_no = SMC_inb (AR_REG);
+       if (packet_no & AR_FAILED) {
+               /* or isn't there?  BAD CHIP! */
+               printf ("%s: Memory allocation failed. \n", SMC_DEV_NAME);
+               return 0;
+       }
+
+       /* we have a packet address, so tell the card to use it */
+#ifndef CONFIG_XAENIAX
+       SMC_outb (packet_no, PN_REG);
+#else
+       /* On Xaeniax board, we can't use SMC_outb here because that way
+        * the Allocate MMU command will end up written to the command register
+        * as well, which will lead to a problem.
+        */
+       SMC_outl (packet_no << 16, 0);
+#endif
+       /* do not write new ptr value if Write data fifo not empty */
+       while ( saved_ptr & PTR_NOTEMPTY )
+               printf ("Write data fifo not empty!\n");
+
+       /* point to the beginning of the packet */
+       SMC_outw (PTR_AUTOINC, PTR_REG);
+
+       PRINTK3 ("%s: Trying to xmit packet of length %x\n",
+                SMC_DEV_NAME, length);
+
+#if SMC_DEBUG > 2
+       printf ("Transmitting Packet\n");
+       print_packet (buf, length);
+#endif
+
+       /* send the packet length ( +6 for status, length and ctl byte )
+          and the status word ( set to zeros ) */
+#ifdef USE_32_BIT
+       SMC_outl ((length + 6) << 16, SMC91111_DATA_REG);
+#else
+       SMC_outw (0, SMC91111_DATA_REG);
+       /* send the packet length ( +6 for status words, length, and ctl */
+       SMC_outw ((length + 6), SMC91111_DATA_REG);
+#endif
+
+       /* send the actual data
+          . I _think_ it's faster to send the longs first, and then
+          . mop up by sending the last word.  It depends heavily
+          . on alignment, at least on the 486.  Maybe it would be
+          . a good idea to check which is optimal?  But that could take
+          . almost as much time as is saved?
+        */
+#ifdef USE_32_BIT
+       SMC_outsl (SMC91111_DATA_REG, buf, length >> 2);
+#ifndef CONFIG_XAENIAX
+       if (length & 0x2)
+               SMC_outw (*((word *) (buf + (length & 0xFFFFFFFC))),
+                         SMC91111_DATA_REG);
+#else
+       /* On XANEIAX, we can only use 32-bit writes, so we need to handle
+        * unaligned tail part specially. The standard code doesn't work.
+        */
+       if ((length & 3) == 3) {
+               u16 * ptr = (u16*) &buf[length-3];
+               SMC_outl((*ptr) | ((0x2000 | buf[length-1]) << 16),
+                               SMC91111_DATA_REG);
+       } else if ((length & 2) == 2) {
+               u16 * ptr = (u16*) &buf[length-2];
+               SMC_outl(*ptr, SMC91111_DATA_REG);
+       } else if (length & 1) {
+               SMC_outl((0x2000 | buf[length-1]), SMC91111_DATA_REG);
+       } else {
+               SMC_outl(0, SMC91111_DATA_REG);
+       }
+#endif
+#else
+       SMC_outsw (SMC91111_DATA_REG, buf, (length) >> 1);
+#endif /* USE_32_BIT */
+
+#ifndef CONFIG_XAENIAX
+       /* Send the last byte, if there is one.   */
+       if ((length & 1) == 0) {
+               SMC_outw (0, SMC91111_DATA_REG);
+       } else {
+               SMC_outw (buf[length - 1] | 0x2000, SMC91111_DATA_REG);
+       }
+#endif
+
+       /* and let the chipset deal with it */
+       SMC_outw (MC_ENQUEUE, MMU_CMD_REG);
+
+       /* poll for TX INT */
+       /* if (poll4int (IM_TX_INT, SMC_TX_TIMEOUT)) { */
+       /* poll for TX_EMPTY INT - autorelease enabled */
+       if (poll4int(IM_TX_EMPTY_INT, SMC_TX_TIMEOUT)) {
+               /* sending failed */
+               PRINTK2 ("%s: TX timeout, sending failed...\n", SMC_DEV_NAME);
+
+               /* release packet */
+               /* no need to release, MMU does that now */
+#ifdef CONFIG_XAENIAX
+                SMC_outw (MC_FREEPKT, MMU_CMD_REG);
+#endif
+
+               /* wait for MMU getting ready (low) */
+               while (SMC_inw (MMU_CMD_REG) & MC_BUSY) {
+                       udelay (10);
+               }
+
+               PRINTK2 ("MMU ready\n");
+
+
+               return 0;
+       } else {
+               /* ack. int */
+               SMC_outb (IM_TX_EMPTY_INT, SMC91111_INT_REG);
+               /* SMC_outb (IM_TX_INT, SMC91111_INT_REG); */
+               PRINTK2 ("%s: Sent packet of length %d \n", SMC_DEV_NAME,
+                        length);
+
+               /* release packet */
+               /* no need to release, MMU does that now */
+#ifdef CONFIG_XAENIAX
+               SMC_outw (MC_FREEPKT, MMU_CMD_REG);
+#endif
+
+               /* wait for MMU getting ready (low) */
+               while (SMC_inw (MMU_CMD_REG) & MC_BUSY) {
+                       udelay (10);
+               }
+
+               PRINTK2 ("MMU ready\n");
+
+
+       }
+
+       /* restore previously saved registers */
+#ifndef CONFIG_XAENIAX
+       SMC_outb( saved_pnr, PN_REG );
+#else
+       /* On Xaeniax board, we can't use SMC_outb here because that way
+        * the Allocate MMU command will end up written to the command register
+        * as well, which will lead to a problem.
+        */
+       SMC_outl(saved_pnr << 16, 0);
+#endif
+       SMC_outw( saved_ptr, PTR_REG );
+
+       return length;
+}
+
+/*-------------------------------------------------------------------------
+ |
+ | smc_destructor( struct net_device * dev )
+ |   Input parameters:
+ |     dev, pointer to the device structure
+ |
+ |   Output:
+ |     None.
+ |
+ ---------------------------------------------------------------------------
+*/
+void smc_destructor()
+{
+       PRINTK2(CARDNAME ": smc_destructor\n");
+}
+
+
+/*
+ * Open and Initialize the board
+ *
+ * Set up everything, reset the card, etc ..
+ *
+ */
+static int smc_open (bd_t * bd)
+{
+       int i, err;
+
+       PRINTK2 ("%s: smc_open\n", SMC_DEV_NAME);
+
+       /* reset the hardware */
+       smc_reset ();
+       smc_enable ();
+
+       /* Configure the PHY */
+#ifndef CONFIG_SMC91111_EXT_PHY
+       smc_phy_configure ();
+#endif
+
+       /* conservative setting (10Mbps, HalfDuplex, no AutoNeg.) */
+/*     SMC_SELECT_BANK(0); */
+/*     SMC_outw(0, RPC_REG); */
+       SMC_SELECT_BANK (1);
+
+       err = smc_get_ethaddr (bd);     /* set smc_mac_addr, and sync it with u-boot globals */
+       if (err < 0) {
+               memset (bd->bi_enetaddr, 0, 6); /* hack to make error stick! upper code will abort if not set */
+               return (-1);    /* upper code ignores this, but NOT bi_enetaddr */
+       }
+#ifdef USE_32_BIT
+       for (i = 0; i < 6; i += 2) {
+               word address;
+
+               address = smc_mac_addr[i + 1] << 8;
+               address |= smc_mac_addr[i];
+               SMC_outw (address, (ADDR0_REG + i));
+       }
+#else
+       for (i = 0; i < 6; i++)
+               SMC_outb (smc_mac_addr[i], (ADDR0_REG + i));
+#endif
+
+       return 0;
+}
+
+/*-------------------------------------------------------------
+ .
+ . smc_rcv -  receive a packet from the card
+ .
+ . There is ( at least ) a packet waiting to be read from
+ . chip-memory.
+ .
+ . o Read the status
+ . o If an error, record it
+ . o otherwise, read in the packet
+ --------------------------------------------------------------
+*/
+static int smc_rcv()
+{
+       int     packet_number;
+       word    status;
+       word    packet_length;
+       int     is_error = 0;
+#ifdef USE_32_BIT
+       dword stat_len;
+#endif
+       byte saved_pnr;
+       word saved_ptr;
+
+       SMC_SELECT_BANK(2);
+       /* save PTR and PTR registers */
+       saved_pnr = SMC_inb( PN_REG );
+       saved_ptr = SMC_inw( PTR_REG );
+
+       packet_number = SMC_inw( RXFIFO_REG );
+
+       if ( packet_number & RXFIFO_REMPTY ) {
+
+               return 0;
+       }
+
+       PRINTK3("%s: smc_rcv\n", SMC_DEV_NAME);
+       /*  start reading from the start of the packet */
+       SMC_outw( PTR_READ | PTR_RCV | PTR_AUTOINC, PTR_REG );
+
+       /* First two words are status and packet_length */
+#ifdef USE_32_BIT
+       stat_len = SMC_inl(SMC91111_DATA_REG);
+       status = stat_len & 0xffff;
+       packet_length = stat_len >> 16;
+#else
+       status          = SMC_inw( SMC91111_DATA_REG );
+       packet_length   = SMC_inw( SMC91111_DATA_REG );
+#endif
+
+       packet_length &= 0x07ff;  /* mask off top bits */
+
+       PRINTK2("RCV: STATUS %4x LENGTH %4x\n", status, packet_length );
+
+       if ( !(status & RS_ERRORS ) ){
+               /* Adjust for having already read the first two words */
+               packet_length -= 4; /*4; */
+
+
+               /* set odd length for bug in LAN91C111, */
+               /* which never sets RS_ODDFRAME */
+               /* TODO ? */
+
+
+#ifdef USE_32_BIT
+               PRINTK3(" Reading %d dwords (and %d bytes) \n",
+                       packet_length >> 2, packet_length & 3 );
+               /* QUESTION:  Like in the TX routine, do I want
+                  to send the DWORDs or the bytes first, or some
+                  mixture.  A mixture might improve already slow PIO
+                  performance  */
+               SMC_insl( SMC91111_DATA_REG , NetRxPackets[0], packet_length >> 2 );
+               /* read the left over bytes */
+               if (packet_length & 3) {
+                       int i;
+
+                       byte *tail = (byte *)(NetRxPackets[0] + (packet_length & ~3));
+                       dword leftover = SMC_inl(SMC91111_DATA_REG);
+                       for (i=0; i<(packet_length & 3); i++)
+                               *tail++ = (byte) (leftover >> (8*i)) & 0xff;
+               }
+#else
+               PRINTK3(" Reading %d words and %d byte(s) \n",
+                       (packet_length >> 1 ), packet_length & 1 );
+               SMC_insw(SMC91111_DATA_REG , NetRxPackets[0], packet_length >> 1);
+
+#endif /* USE_32_BIT */
+
+#if    SMC_DEBUG > 2
+               printf("Receiving Packet\n");
+               print_packet( NetRxPackets[0], packet_length );
+#endif
+       } else {
+               /* error ... */
+               /* TODO ? */
+               is_error = 1;
+       }
+
+       while ( SMC_inw( MMU_CMD_REG ) & MC_BUSY )
+               udelay(1); /* Wait until not busy */
+
+       /*  error or good, tell the card to get rid of this packet */
+       SMC_outw( MC_RELEASE, MMU_CMD_REG );
+
+       while ( SMC_inw( MMU_CMD_REG ) & MC_BUSY )
+               udelay(1); /* Wait until not busy */
+
+       /* restore saved registers */
+#ifndef CONFIG_XAENIAX
+       SMC_outb( saved_pnr, PN_REG );
+#else
+       /* On Xaeniax board, we can't use SMC_outb here because that way
+        * the Allocate MMU command will end up written to the command register
+        * as well, which will lead to a problem.
+        */
+       SMC_outl( saved_pnr << 16, 0);
+#endif
+       SMC_outw( saved_ptr, PTR_REG );
+
+       if (!is_error) {
+               /* Pass the packet up to the protocol layers. */
+               NetReceive(NetRxPackets[0], packet_length);
+               return packet_length;
+       } else {
+               return 0;
+       }
+
+}
+
+
+/*----------------------------------------------------
+ . smc_close
+ .
+ . this makes the board clean up everything that it can
+ . and not talk to the outside world.  Caused by
+ . an 'ifconfig ethX down'
+ .
+ -----------------------------------------------------*/
+static int smc_close()
+{
+       PRINTK2("%s: smc_close\n", SMC_DEV_NAME);
+
+       /* clear everything */
+       smc_shutdown();
+
+       return 0;
+}
+
+
+#if 0
+/*------------------------------------------------------------
+ . Modify a bit in the LAN91C111 register set
+ .-------------------------------------------------------------*/
+static word smc_modify_regbit(int bank, int ioaddr, int reg,
+       unsigned int bit, int val)
+{
+       word regval;
+
+       SMC_SELECT_BANK( bank );
+
+       regval = SMC_inw( reg );
+       if (val)
+               regval |= bit;
+       else
+               regval &= ~bit;
+
+       SMC_outw( regval, 0 );
+       return(regval);
+}
+
+
+/*------------------------------------------------------------
+ . Retrieve a bit in the LAN91C111 register set
+ .-------------------------------------------------------------*/
+static int smc_get_regbit(int bank, int ioaddr, int reg, unsigned int bit)
+{
+       SMC_SELECT_BANK( bank );
+       if ( SMC_inw( reg ) & bit)
+               return(1);
+       else
+               return(0);
+}
+
+
+/*------------------------------------------------------------
+ . Modify a LAN91C111 register (word access only)
+ .-------------------------------------------------------------*/
+static void smc_modify_reg(int bank, int ioaddr, int reg, word val)
+{
+       SMC_SELECT_BANK( bank );
+       SMC_outw( val, reg );
+}
+
+
+/*------------------------------------------------------------
+ . Retrieve a LAN91C111 register (word access only)
+ .-------------------------------------------------------------*/
+static int smc_get_reg(int bank, int ioaddr, int reg)
+{
+       SMC_SELECT_BANK( bank );
+       return(SMC_inw( reg ));
+}
+
+#endif /* 0 */
+
+/*---PHY CONTROL AND CONFIGURATION----------------------------------------- */
+
+#if (SMC_DEBUG > 2 )
+
+/*------------------------------------------------------------
+ . Debugging function for viewing MII Management serial bitstream
+ .-------------------------------------------------------------*/
+static void smc_dump_mii_stream (byte * bits, int size)
+{
+       int i;
+
+       printf ("BIT#:");
+       for (i = 0; i < size; ++i) {
+               printf ("%d", i % 10);
+       }
+
+       printf ("\nMDOE:");
+       for (i = 0; i < size; ++i) {
+               if (bits[i] & MII_MDOE)
+                       printf ("1");
+               else
+                       printf ("0");
+       }
+
+       printf ("\nMDO :");
+       for (i = 0; i < size; ++i) {
+               if (bits[i] & MII_MDO)
+                       printf ("1");
+               else
+                       printf ("0");
+       }
+
+       printf ("\nMDI :");
+       for (i = 0; i < size; ++i) {
+               if (bits[i] & MII_MDI)
+                       printf ("1");
+               else
+                       printf ("0");
+       }
+
+       printf ("\n");
+}
+#endif
+
+/*------------------------------------------------------------
+ . Reads a register from the MII Management serial interface
+ .-------------------------------------------------------------*/
+#ifndef CONFIG_SMC91111_EXT_PHY
+static word smc_read_phy_register (byte phyreg)
+{
+       int oldBank;
+       int i;
+       byte mask;
+       word mii_reg;
+       byte bits[64];
+       int clk_idx = 0;
+       int input_idx;
+       word phydata;
+       byte phyaddr = SMC_PHY_ADDR;
+
+       /* 32 consecutive ones on MDO to establish sync */
+       for (i = 0; i < 32; ++i)
+               bits[clk_idx++] = MII_MDOE | MII_MDO;
+
+       /* Start code <01> */
+       bits[clk_idx++] = MII_MDOE;
+       bits[clk_idx++] = MII_MDOE | MII_MDO;
+
+       /* Read command <10> */
+       bits[clk_idx++] = MII_MDOE | MII_MDO;
+       bits[clk_idx++] = MII_MDOE;
+
+       /* Output the PHY address, msb first */
+       mask = (byte) 0x10;
+       for (i = 0; i < 5; ++i) {
+               if (phyaddr & mask)
+                       bits[clk_idx++] = MII_MDOE | MII_MDO;
+               else
+                       bits[clk_idx++] = MII_MDOE;
+
+               /* Shift to next lowest bit */
+               mask >>= 1;
+       }
+
+       /* Output the phy register number, msb first */
+       mask = (byte) 0x10;
+       for (i = 0; i < 5; ++i) {
+               if (phyreg & mask)
+                       bits[clk_idx++] = MII_MDOE | MII_MDO;
+               else
+                       bits[clk_idx++] = MII_MDOE;
+
+               /* Shift to next lowest bit */
+               mask >>= 1;
+       }
+
+       /* Tristate and turnaround (2 bit times) */
+       bits[clk_idx++] = 0;
+       /*bits[clk_idx++] = 0; */
+
+       /* Input starts at this bit time */
+       input_idx = clk_idx;
+
+       /* Will input 16 bits */
+       for (i = 0; i < 16; ++i)
+               bits[clk_idx++] = 0;
+
+       /* Final clock bit */
+       bits[clk_idx++] = 0;
+
+       /* Save the current bank */
+       oldBank = SMC_inw (BANK_SELECT);
+
+       /* Select bank 3 */
+       SMC_SELECT_BANK (3);
+
+       /* Get the current MII register value */
+       mii_reg = SMC_inw (MII_REG);
+
+       /* Turn off all MII Interface bits */
+       mii_reg &= ~(MII_MDOE | MII_MCLK | MII_MDI | MII_MDO);
+
+       /* Clock all 64 cycles */
+       for (i = 0; i < sizeof bits; ++i) {
+               /* Clock Low - output data */
+               SMC_outw (mii_reg | bits[i], MII_REG);
+               udelay (SMC_PHY_CLOCK_DELAY);
+
+
+               /* Clock Hi - input data */
+               SMC_outw (mii_reg | bits[i] | MII_MCLK, MII_REG);
+               udelay (SMC_PHY_CLOCK_DELAY);
+               bits[i] |= SMC_inw (MII_REG) & MII_MDI;
+       }
+
+       /* Return to idle state */
+       /* Set clock to low, data to low, and output tristated */
+       SMC_outw (mii_reg, MII_REG);
+       udelay (SMC_PHY_CLOCK_DELAY);
+
+       /* Restore original bank select */
+       SMC_SELECT_BANK (oldBank);
+
+       /* Recover input data */
+       phydata = 0;
+       for (i = 0; i < 16; ++i) {
+               phydata <<= 1;
+
+               if (bits[input_idx++] & MII_MDI)
+                       phydata |= 0x0001;
+       }
+
+#if (SMC_DEBUG > 2 )
+       printf ("smc_read_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n",
+               phyaddr, phyreg, phydata);
+       smc_dump_mii_stream (bits, sizeof bits);
+#endif
+
+       return (phydata);
+}
+
+
+/*------------------------------------------------------------
+ . Writes a register to the MII Management serial interface
+ .-------------------------------------------------------------*/
+static void smc_write_phy_register (byte phyreg, word phydata)
+{
+       int oldBank;
+       int i;
+       word mask;
+       word mii_reg;
+       byte bits[65];
+       int clk_idx = 0;
+       byte phyaddr = SMC_PHY_ADDR;
+
+       /* 32 consecutive ones on MDO to establish sync */
+       for (i = 0; i < 32; ++i)
+               bits[clk_idx++] = MII_MDOE | MII_MDO;
+
+       /* Start code <01> */
+       bits[clk_idx++] = MII_MDOE;
+       bits[clk_idx++] = MII_MDOE | MII_MDO;
+
+       /* Write command <01> */
+       bits[clk_idx++] = MII_MDOE;
+       bits[clk_idx++] = MII_MDOE | MII_MDO;
+
+       /* Output the PHY address, msb first */
+       mask = (byte) 0x10;
+       for (i = 0; i < 5; ++i) {
+               if (phyaddr & mask)
+                       bits[clk_idx++] = MII_MDOE | MII_MDO;
+               else
+                       bits[clk_idx++] = MII_MDOE;
+
+               /* Shift to next lowest bit */
+               mask >>= 1;
+       }
+
+       /* Output the phy register number, msb first */
+       mask = (byte) 0x10;
+       for (i = 0; i < 5; ++i) {
+               if (phyreg & mask)
+                       bits[clk_idx++] = MII_MDOE | MII_MDO;
+               else
+                       bits[clk_idx++] = MII_MDOE;
+
+               /* Shift to next lowest bit */
+               mask >>= 1;
+       }
+
+       /* Tristate and turnaround (2 bit times) */
+       bits[clk_idx++] = 0;
+       bits[clk_idx++] = 0;
+
+       /* Write out 16 bits of data, msb first */
+       mask = 0x8000;
+       for (i = 0; i < 16; ++i) {
+               if (phydata & mask)
+                       bits[clk_idx++] = MII_MDOE | MII_MDO;
+               else
+                       bits[clk_idx++] = MII_MDOE;
+
+               /* Shift to next lowest bit */
+               mask >>= 1;
+       }
+
+       /* Final clock bit (tristate) */
+       bits[clk_idx++] = 0;
+
+       /* Save the current bank */
+       oldBank = SMC_inw (BANK_SELECT);
+
+       /* Select bank 3 */
+       SMC_SELECT_BANK (3);
+
+       /* Get the current MII register value */
+       mii_reg = SMC_inw (MII_REG);
+
+       /* Turn off all MII Interface bits */
+       mii_reg &= ~(MII_MDOE | MII_MCLK | MII_MDI | MII_MDO);
+
+       /* Clock all cycles */
+       for (i = 0; i < sizeof bits; ++i) {
+               /* Clock Low - output data */
+               SMC_outw (mii_reg | bits[i], MII_REG);
+               udelay (SMC_PHY_CLOCK_DELAY);
+
+
+               /* Clock Hi - input data */
+               SMC_outw (mii_reg | bits[i] | MII_MCLK, MII_REG);
+               udelay (SMC_PHY_CLOCK_DELAY);
+               bits[i] |= SMC_inw (MII_REG) & MII_MDI;
+       }
+
+       /* Return to idle state */
+       /* Set clock to low, data to low, and output tristated */
+       SMC_outw (mii_reg, MII_REG);
+       udelay (SMC_PHY_CLOCK_DELAY);
+
+       /* Restore original bank select */
+       SMC_SELECT_BANK (oldBank);
+
+#if (SMC_DEBUG > 2 )
+       printf ("smc_write_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n",
+               phyaddr, phyreg, phydata);
+       smc_dump_mii_stream (bits, sizeof bits);
+#endif
+}
+#endif /* !CONFIG_SMC91111_EXT_PHY */
+
+
+/*------------------------------------------------------------
+ . Waits the specified number of milliseconds - kernel friendly
+ .-------------------------------------------------------------*/
+#ifndef CONFIG_SMC91111_EXT_PHY
+static void smc_wait_ms(unsigned int ms)
+{
+       udelay(ms*1000);
+}
+#endif /* !CONFIG_SMC91111_EXT_PHY */
+
+
+/*------------------------------------------------------------
+ . Configures the specified PHY using Autonegotiation. Calls
+ . smc_phy_fixed() if the user has requested a certain config.
+ .-------------------------------------------------------------*/
+#ifndef CONFIG_SMC91111_EXT_PHY
+static void smc_phy_configure ()
+{
+       int timeout;
+       byte phyaddr;
+       word my_phy_caps;       /* My PHY capabilities */
+       word my_ad_caps;        /* My Advertised capabilities */
+       word status = 0;        /*;my status = 0 */
+       int failed = 0;
+
+       PRINTK3 ("%s: smc_program_phy()\n", SMC_DEV_NAME);
+
+
+       /* Get the detected phy address */
+       phyaddr = SMC_PHY_ADDR;
+
+       /* Reset the PHY, setting all other bits to zero */
+       smc_write_phy_register (PHY_CNTL_REG, PHY_CNTL_RST);
+
+       /* Wait for the reset to complete, or time out */
+       timeout = 6;            /* Wait up to 3 seconds */
+       while (timeout--) {
+               if (!(smc_read_phy_register (PHY_CNTL_REG)
+                     & PHY_CNTL_RST)) {
+                       /* reset complete */
+                       break;
+               }
+
+               smc_wait_ms (500);      /* wait 500 millisecs */
+       }
+
+       if (timeout < 1) {
+               printf ("%s:PHY reset timed out\n", SMC_DEV_NAME);
+               goto smc_phy_configure_exit;
+       }
+
+       /* Read PHY Register 18, Status Output */
+       /* lp->lastPhy18 = smc_read_phy_register(PHY_INT_REG); */
+
+       /* Enable PHY Interrupts (for register 18) */
+       /* Interrupts listed here are disabled */
+       smc_write_phy_register (PHY_MASK_REG, 0xffff);
+
+       /* Configure the Receive/Phy Control register */
+       SMC_SELECT_BANK (0);
+       SMC_outw (RPC_DEFAULT, RPC_REG);
+
+       /* Copy our capabilities from PHY_STAT_REG to PHY_AD_REG */
+       my_phy_caps = smc_read_phy_register (PHY_STAT_REG);
+       my_ad_caps = PHY_AD_CSMA;       /* I am CSMA capable */
+
+       if (my_phy_caps & PHY_STAT_CAP_T4)
+               my_ad_caps |= PHY_AD_T4;
+
+       if (my_phy_caps & PHY_STAT_CAP_TXF)
+               my_ad_caps |= PHY_AD_TX_FDX;
+
+       if (my_phy_caps & PHY_STAT_CAP_TXH)
+               my_ad_caps |= PHY_AD_TX_HDX;
+
+       if (my_phy_caps & PHY_STAT_CAP_TF)
+               my_ad_caps |= PHY_AD_10_FDX;
+
+       if (my_phy_caps & PHY_STAT_CAP_TH)
+               my_ad_caps |= PHY_AD_10_HDX;
+
+       /* Update our Auto-Neg Advertisement Register */
+       smc_write_phy_register (PHY_AD_REG, my_ad_caps);
+
+       /* Read the register back.  Without this, it appears that when */
+       /* auto-negotiation is restarted, sometimes it isn't ready and */
+       /* the link does not come up. */
+       smc_read_phy_register(PHY_AD_REG);
+
+       PRINTK2 ("%s: phy caps=%x\n", SMC_DEV_NAME, my_phy_caps);
+       PRINTK2 ("%s: phy advertised caps=%x\n", SMC_DEV_NAME, my_ad_caps);
+
+       /* Restart auto-negotiation process in order to advertise my caps */
+       smc_write_phy_register (PHY_CNTL_REG,
+                               PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST);
+
+       /* Wait for the auto-negotiation to complete.  This may take from */
+       /* 2 to 3 seconds. */
+       /* Wait for the reset to complete, or time out */
+       timeout = CONFIG_SMC_AUTONEG_TIMEOUT * 2;
+       while (timeout--) {
+
+               status = smc_read_phy_register (PHY_STAT_REG);
+               if (status & PHY_STAT_ANEG_ACK) {
+                       /* auto-negotiate complete */
+                       break;
+               }
+
+               smc_wait_ms (500);      /* wait 500 millisecs */
+
+               /* Restart auto-negotiation if remote fault */
+               if (status & PHY_STAT_REM_FLT) {
+                       printf ("%s: PHY remote fault detected\n",
+                               SMC_DEV_NAME);
+
+                       /* Restart auto-negotiation */
+                       printf ("%s: PHY restarting auto-negotiation\n",
+                               SMC_DEV_NAME);
+                       smc_write_phy_register (PHY_CNTL_REG,
+                                               PHY_CNTL_ANEG_EN |
+                                               PHY_CNTL_ANEG_RST |
+                                               PHY_CNTL_SPEED |
+                                               PHY_CNTL_DPLX);
+               }
+       }
+
+       if (timeout < 1) {
+               printf ("%s: PHY auto-negotiate timed out\n", SMC_DEV_NAME);
+               failed = 1;
+       }
+
+       /* Fail if we detected an auto-negotiate remote fault */
+       if (status & PHY_STAT_REM_FLT) {
+               printf ("%s: PHY remote fault detected\n", SMC_DEV_NAME);
+               failed = 1;
+       }
+
+       /* Re-Configure the Receive/Phy Control register */
+       SMC_outw (RPC_DEFAULT, RPC_REG);
+
+smc_phy_configure_exit:        ;
+
+}
+#endif /* !CONFIG_SMC91111_EXT_PHY */
+
+
+#if SMC_DEBUG > 2
+static void print_packet( byte * buf, int length )
+{
+       int i;
+       int remainder;
+       int lines;
+
+       printf("Packet of length %d \n", length );
+
+#if SMC_DEBUG > 3
+       lines = length / 16;
+       remainder = length % 16;
+
+       for ( i = 0; i < lines ; i ++ ) {
+               int cur;
+
+               for ( cur = 0; cur < 8; cur ++ ) {
+                       byte a, b;
+
+                       a = *(buf ++ );
+                       b = *(buf ++ );
+                       printf("%02x%02x ", a, b );
+               }
+               printf("\n");
+       }
+       for ( i = 0; i < remainder/2 ; i++ ) {
+               byte a, b;
+
+               a = *(buf ++ );
+               b = *(buf ++ );
+               printf("%02x%02x ", a, b );
+       }
+       printf("\n");
+#endif
+}
+#endif
+
+int eth_init(bd_t *bd) {
+#ifdef SHARED_RESOURCES
+       swap_to(ETHERNET);
+#endif
+       return (smc_open(bd));
+}
+
+void eth_halt() {
+       smc_close();
+}
+
+int eth_rx() {
+       return smc_rcv();
+}
+
+int eth_send(volatile void *packet, int length) {
+       return smc_send_packet(packet, length);
+}
+
+int smc_get_ethaddr (bd_t * bd)
+{
+       int env_size, rom_valid, env_present = 0, reg;
+       char *s = NULL, *e, es[] = "11:22:33:44:55:66";
+       char s_env_mac[64];
+       uchar v_env_mac[6], v_rom_mac[6], *v_mac;
+
+       env_size = getenv_r ("ethaddr", s_env_mac, sizeof (s_env_mac));
+       if ((env_size > 0) && (env_size < sizeof (es))) {       /* exit if env is bad */
+               printf ("\n*** ERROR: ethaddr is not set properly!!\n");
+               return (-1);
+       }
+
+       if (env_size > 0) {
+               env_present = 1;
+               s = s_env_mac;
+       }
+
+       for (reg = 0; reg < 6; ++reg) { /* turn string into mac value */
+               v_env_mac[reg] = s ? simple_strtoul (s, &e, 16) : 0;
+               if (s)
+                       s = (*e) ? e + 1 : e;
+       }
+
+       rom_valid = get_rom_mac (v_rom_mac);    /* get ROM mac value if any */
+
+       if (!env_present) {     /* if NO env */
+               if (rom_valid) {        /* but ROM is valid */
+                       v_mac = v_rom_mac;
+                       sprintf (s_env_mac, "%02X:%02X:%02X:%02X:%02X:%02X",
+                                v_mac[0], v_mac[1], v_mac[2], v_mac[3],
+                                v_mac[4], v_mac[5]);
+                       setenv ("ethaddr", s_env_mac);
+               } else {        /* no env, bad ROM */
+                       printf ("\n*** ERROR: ethaddr is NOT set !!\n");
+                       return (-1);
+               }
+       } else {                /* good env, don't care ROM */
+               v_mac = v_env_mac;      /* always use a good env over a ROM */
+       }
+
+       if (env_present && rom_valid) { /* if both env and ROM are good */
+               if (memcmp (v_env_mac, v_rom_mac, 6) != 0) {
+                       printf ("\nWarning: MAC addresses don't match:\n");
+                       printf ("\tHW MAC address:  "
+                               "%02X:%02X:%02X:%02X:%02X:%02X\n",
+                               v_rom_mac[0], v_rom_mac[1],
+                               v_rom_mac[2], v_rom_mac[3],
+                               v_rom_mac[4], v_rom_mac[5] );
+                       printf ("\t\"ethaddr\" value: "
+                               "%02X:%02X:%02X:%02X:%02X:%02X\n",
+                               v_env_mac[0], v_env_mac[1],
+                               v_env_mac[2], v_env_mac[3],
+                               v_env_mac[4], v_env_mac[5]) ;
+                       debug ("### Set MAC addr from environment\n");
+               }
+       }
+       memcpy (bd->bi_enetaddr, v_mac, 6);     /* update global address to match env (allows env changing) */
+       smc_set_mac_addr ((uchar *)v_mac);      /* use old function to update smc default */
+       PRINTK("Using MAC Address %02X:%02X:%02X:%02X:%02X:%02X\n", v_mac[0], v_mac[1],
+               v_mac[2], v_mac[3], v_mac[4], v_mac[5]);
+       return (0);
+}
+
+int get_rom_mac (uchar *v_rom_mac)
+{
+#ifdef HARDCODE_MAC    /* used for testing or to supress run time warnings */
+       char hw_mac_addr[] = { 0x02, 0x80, 0xad, 0x20, 0x31, 0xb8 };
+
+       memcpy (v_rom_mac, hw_mac_addr, 6);
+       return (1);
+#else
+       int i;
+       int valid_mac = 0;
+
+       SMC_SELECT_BANK (1);
+       for (i=0; i<6; i++)
+       {
+               v_rom_mac[i] = SMC_inb ((ADDR0_REG + i));
+               valid_mac |= v_rom_mac[i];
+       }
+
+       return (valid_mac ? 1 : 0);
+#endif
+}
+#endif /* CONFIG_DRIVER_SMC91111 */
diff --git a/drivers/net/smc91111.h b/drivers/net/smc91111.h
new file mode 100644 (file)
index 0000000..d03cbc3
--- /dev/null
@@ -0,0 +1,719 @@
+/*------------------------------------------------------------------------
+ . smc91111.h - macros for the LAN91C111 Ethernet Driver
+ .
+ . (C) Copyright 2002
+ . Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ . Rolf Offermanns <rof@sysgo.de>
+ . Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
+ .       Developed by Simple Network Magic Corporation (SNMC)
+ . Copyright (C) 1996 by Erik Stahlman (ES)
+ .
+ . This program is free software; you can redistribute it and/or modify
+ . it under the terms of the GNU General Public License as published by
+ . the Free Software Foundation; either version 2 of the License, or
+ . (at your option) any later version.
+ .
+ . This program is distributed in the hope that it will be useful,
+ . but WITHOUT ANY WARRANTY; without even the implied warranty of
+ . MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ . GNU General Public License for more details.
+ .
+ . You should have received a copy of the GNU General Public License
+ . along with this program; if not, write to the Free Software
+ . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ .
+ . This file contains register information and access macros for
+ . the LAN91C111 single chip ethernet controller.  It is a modified
+ . version of the smc9194.h file.
+ .
+ . Information contained in this file was obtained from the LAN91C111
+ . manual from SMC.  To get a copy, if you really want one, you can find
+ . information under www.smsc.com.
+ .
+ . Authors
+ .     Erik Stahlman                           ( erik@vt.edu )
+ .     Daris A Nevil                           ( dnevil@snmc.com )
+ .
+ . History
+ . 03/16/01            Daris A Nevil   Modified for use with LAN91C111 device
+ .
+ ---------------------------------------------------------------------------*/
+#ifndef _SMC91111_H_
+#define _SMC91111_H_
+
+#include <asm/types.h>
+#include <config.h>
+
+/*
+ * This function may be called by the board specific initialisation code
+ * in order to override the default mac address.
+ */
+
+void smc_set_mac_addr (const unsigned char *addr);
+
+
+/* I want some simple types */
+
+typedef unsigned char                  byte;
+typedef unsigned short                 word;
+typedef unsigned long int              dword;
+
+/*
+ . DEBUGGING LEVELS
+ .
+ . 0 for normal operation
+ . 1 for slightly more details
+ . >2 for various levels of increasingly useless information
+ .    2 for interrupt tracking, status flags
+ .    3 for packet info
+ .    4 for complete packet dumps
+*/
+/*#define SMC_DEBUG 0 */
+
+/* Because of bank switching, the LAN91xxx uses only 16 I/O ports */
+
+#define        SMC_IO_EXTENT   16
+
+#ifdef CONFIG_PXA250
+
+#ifdef CONFIG_XSENGINE
+#define        SMC_inl(r)      (*((volatile dword *)(SMC_BASE_ADDRESS+(r<<1))))
+#define        SMC_inw(r)      (*((volatile word *)(SMC_BASE_ADDRESS+(r<<1))))
+#define SMC_inb(p)     ({ \
+       unsigned int __p = (unsigned int)(SMC_BASE_ADDRESS + (p<<1)); \
+       unsigned int __v = *(volatile unsigned short *)((__p) & ~2); \
+       if (__p & 2) __v >>= 8; \
+       else __v &= 0xff; \
+       __v; })
+#elif defined(CONFIG_XAENIAX)
+#define SMC_inl(r)     (*((volatile dword *)(SMC_BASE_ADDRESS+(r))))
+#define SMC_inw(z)     ({ \
+       unsigned int __p = (unsigned int)(SMC_BASE_ADDRESS + (z)); \
+       unsigned int __v = *(volatile unsigned int *)((__p) & ~3); \
+       if (__p & 3) __v >>= 16; \
+       else __v &= 0xffff; \
+       __v; })
+#define SMC_inb(p)     ({ \
+       unsigned int ___v = SMC_inw((p) & ~1); \
+       if (p & 1) ___v >>= 8; \
+       else ___v &= 0xff; \
+       ___v; })
+#else
+#define        SMC_inl(r)      (*((volatile dword *)(SMC_BASE_ADDRESS+(r))))
+#define        SMC_inw(r)      (*((volatile word *)(SMC_BASE_ADDRESS+(r))))
+#define SMC_inb(p)     ({ \
+       unsigned int __p = (unsigned int)(SMC_BASE_ADDRESS + (p)); \
+       unsigned int __v = *(volatile unsigned short *)((__p) & ~1); \
+       if (__p & 1) __v >>= 8; \
+       else __v &= 0xff; \
+       __v; })
+#endif
+
+#ifdef CONFIG_XSENGINE
+#define        SMC_outl(d,r)   (*((volatile dword *)(SMC_BASE_ADDRESS+(r<<1))) = d)
+#define        SMC_outw(d,r)   (*((volatile word *)(SMC_BASE_ADDRESS+(r<<1))) = d)
+#elif defined (CONFIG_XAENIAX)
+#define SMC_outl(d,r)  (*((volatile dword *)(SMC_BASE_ADDRESS+(r))) = d)
+#define SMC_outw(d,p)  ({ \
+       dword __dwo = SMC_inl((p) & ~3); \
+       dword __dwn = (word)(d); \
+       __dwo &= ((p) & 3) ? 0x0000ffff : 0xffff0000; \
+       __dwo |= ((p) & 3) ? __dwn << 16 : __dwn; \
+       SMC_outl(__dwo, (p) & ~3); \
+})
+#else
+#define        SMC_outl(d,r)   (*((volatile dword *)(SMC_BASE_ADDRESS+(r))) = d)
+#define        SMC_outw(d,r)   (*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d)
+#endif
+
+#define        SMC_outb(d,r)   ({      word __d = (byte)(d);  \
+                               word __w = SMC_inw((r)&~1);  \
+                               __w &= ((r)&1) ? 0x00FF : 0xFF00;  \
+                               __w |= ((r)&1) ? __d<<8 : __d;  \
+                               SMC_outw(__w,(r)&~1);  \
+                       })
+
+#define SMC_outsl(r,b,l)       ({      int __i; \
+                                       dword *__b2; \
+                                       __b2 = (dword *) b; \
+                                       for (__i = 0; __i < l; __i++) { \
+                                           SMC_outl( *(__b2 + __i), r); \
+                                       } \
+                               })
+
+#define SMC_outsw(r,b,l)       ({      int __i; \
+                                       word *__b2; \
+                                       __b2 = (word *) b; \
+                                       for (__i = 0; __i < l; __i++) { \
+                                           SMC_outw( *(__b2 + __i), r); \
+                                       } \
+                               })
+
+#define SMC_insl(r,b,l)        ({      int __i ;  \
+                                       dword *__b2;  \
+                                       __b2 = (dword *) b;  \
+                                       for (__i = 0; __i < l; __i++) {  \
+                                         *(__b2 + __i) = SMC_inl(r);  \
+                                         SMC_inl(0);  \
+                                       };  \
+                               })
+
+#define SMC_insw(r,b,l)        ({      int __i ;  \
+                                       word *__b2;  \
+                                       __b2 = (word *) b;  \
+                                       for (__i = 0; __i < l; __i++) {  \
+                                         *(__b2 + __i) = SMC_inw(r);  \
+                                         SMC_inw(0);  \
+                                       };  \
+                               })
+
+#define SMC_insb(r,b,l)        ({      int __i ;  \
+                                       byte *__b2;  \
+                                       __b2 = (byte *) b;  \
+                                       for (__i = 0; __i < l; __i++) {  \
+                                         *(__b2 + __i) = SMC_inb(r);  \
+                                         SMC_inb(0);  \
+                                       };  \
+                               })
+
+#else /* if not CONFIG_PXA250 */
+
+#ifndef CONFIG_SMC_USE_IOFUNCS /* these macros don't work on some boards */
+/*
+ * We have only 16 Bit PCMCIA access on Socket 0
+ */
+
+#ifdef CONFIG_ADNPESC1
+#define        SMC_inw(r)      (*((volatile word *)(SMC_BASE_ADDRESS+((r)<<1))))
+#elif CONFIG_BLACKFIN
+#define        SMC_inw(r)      ({ word __v = (*((volatile word *)(SMC_BASE_ADDRESS+(r)))); asm("ssync;"); __v;})
+#else
+#define        SMC_inw(r)      (*((volatile word *)(SMC_BASE_ADDRESS+(r))))
+#endif
+#define  SMC_inb(r)    (((r)&1) ? SMC_inw((r)&~1)>>8 : SMC_inw(r)&0xFF)
+
+#ifdef CONFIG_ADNPESC1
+#define        SMC_outw(d,r)   (*((volatile word *)(SMC_BASE_ADDRESS+((r)<<1))) = d)
+#elif CONFIG_BLACKFIN
+#define        SMC_outw(d,r)   {(*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d);asm("ssync;");}
+#else
+#define        SMC_outw(d,r)   (*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d)
+#endif
+#define        SMC_outb(d,r)   ({      word __d = (byte)(d);  \
+                               word __w = SMC_inw((r)&~1);  \
+                               __w &= ((r)&1) ? 0x00FF : 0xFF00;  \
+                               __w |= ((r)&1) ? __d<<8 : __d;  \
+                               SMC_outw(__w,(r)&~1);  \
+                       })
+#if 0
+#define        SMC_outsw(r,b,l)        outsw(SMC_BASE_ADDRESS+(r), (b), (l))
+#else
+#define SMC_outsw(r,b,l)       ({      int __i; \
+                                       word *__b2; \
+                                       __b2 = (word *) b; \
+                                       for (__i = 0; __i < l; __i++) { \
+                                           SMC_outw( *(__b2 + __i), r); \
+                                       } \
+                               })
+#endif
+
+#if 0
+#define        SMC_insw(r,b,l)         insw(SMC_BASE_ADDRESS+(r), (b), (l))
+#else
+#define SMC_insw(r,b,l)        ({      int __i ;  \
+                                       word *__b2;  \
+                                       __b2 = (word *) b;  \
+                                       for (__i = 0; __i < l; __i++) {  \
+                                         *(__b2 + __i) = SMC_inw(r);  \
+                                         SMC_inw(0);  \
+                                       };  \
+                               })
+#endif
+
+#endif  /* CONFIG_SMC_USE_IOFUNCS */
+
+#if defined(CONFIG_SMC_USE_32_BIT)
+
+#ifdef CONFIG_XSENGINE
+#define        SMC_inl(r)      (*((volatile dword *)(SMC_BASE_ADDRESS+(r<<1))))
+#else
+#define        SMC_inl(r)      (*((volatile dword *)(SMC_BASE_ADDRESS+(r))))
+#endif
+
+#define SMC_insl(r,b,l)        ({      int __i ;  \
+                                       dword *__b2;  \
+                                       __b2 = (dword *) b;  \
+                                       for (__i = 0; __i < l; __i++) {  \
+                                         *(__b2 + __i) = SMC_inl(r);  \
+                                         SMC_inl(0);  \
+                                       };  \
+                               })
+
+#ifdef CONFIG_XSENGINE
+#define        SMC_outl(d,r)   (*((volatile dword *)(SMC_BASE_ADDRESS+(r<<1))) = d)
+#else
+#define        SMC_outl(d,r)   (*((volatile dword *)(SMC_BASE_ADDRESS+(r))) = d)
+#endif
+#define SMC_outsl(r,b,l)       ({      int __i; \
+                                       dword *__b2; \
+                                       __b2 = (dword *) b; \
+                                       for (__i = 0; __i < l; __i++) { \
+                                           SMC_outl( *(__b2 + __i), r); \
+                                       } \
+                               })
+
+#endif /* CONFIG_SMC_USE_32_BIT */
+
+#endif
+
+/*---------------------------------------------------------------
+ .
+ . A description of the SMSC registers is probably in order here,
+ . although for details, the SMC datasheet is invaluable.
+ .
+ . Basically, the chip has 4 banks of registers ( 0 to 3 ), which
+ . are accessed by writing a number into the BANK_SELECT register
+ . ( I also use a SMC_SELECT_BANK macro for this ).
+ .
+ . The banks are configured so that for most purposes, bank 2 is all
+ . that is needed for simple run time tasks.
+ -----------------------------------------------------------------------*/
+
+/*
+ . Bank Select Register:
+ .
+ .             yyyy yyyy 0000 00xx
+ .             xx              = bank number
+ .             yyyy yyyy       = 0x33, for identification purposes.
+*/
+#define        BANK_SELECT             14
+
+/* Transmit Control Register */
+/* BANK 0  */
+#define        TCR_REG         0x0000  /* transmit control register */
+#define TCR_ENABLE     0x0001  /* When 1 we can transmit */
+#define TCR_LOOP       0x0002  /* Controls output pin LBK */
+#define TCR_FORCOL     0x0004  /* When 1 will force a collision */
+#define TCR_PAD_EN     0x0080  /* When 1 will pad tx frames < 64 bytes w/0 */
+#define TCR_NOCRC      0x0100  /* When 1 will not append CRC to tx frames */
+#define TCR_MON_CSN    0x0400  /* When 1 tx monitors carrier */
+#define TCR_FDUPLX     0x0800  /* When 1 enables full duplex operation */
+#define TCR_STP_SQET   0x1000  /* When 1 stops tx if Signal Quality Error */
+#define        TCR_EPH_LOOP    0x2000  /* When 1 enables EPH block loopback */
+#define        TCR_SWFDUP      0x8000  /* When 1 enables Switched Full Duplex mode */
+
+#define        TCR_CLEAR       0       /* do NOTHING */
+/* the default settings for the TCR register : */
+/* QUESTION: do I want to enable padding of short packets ? */
+#define        TCR_DEFAULT     TCR_ENABLE
+
+
+/* EPH Status Register */
+/* BANK 0  */
+#define EPH_STATUS_REG 0x0002
+#define ES_TX_SUC      0x0001  /* Last TX was successful */
+#define ES_SNGL_COL    0x0002  /* Single collision detected for last tx */
+#define ES_MUL_COL     0x0004  /* Multiple collisions detected for last tx */
+#define ES_LTX_MULT    0x0008  /* Last tx was a multicast */
+#define ES_16COL       0x0010  /* 16 Collisions Reached */
+#define ES_SQET                0x0020  /* Signal Quality Error Test */
+#define ES_LTXBRD      0x0040  /* Last tx was a broadcast */
+#define ES_TXDEFR      0x0080  /* Transmit Deferred */
+#define ES_LATCOL      0x0200  /* Late collision detected on last tx */
+#define ES_LOSTCARR    0x0400  /* Lost Carrier Sense */
+#define ES_EXC_DEF     0x0800  /* Excessive Deferral */
+#define ES_CTR_ROL     0x1000  /* Counter Roll Over indication */
+#define ES_LINK_OK     0x4000  /* Driven by inverted value of nLNK pin */
+#define ES_TXUNRN      0x8000  /* Tx Underrun */
+
+
+/* Receive Control Register */
+/* BANK 0  */
+#define        RCR_REG         0x0004
+#define        RCR_RX_ABORT    0x0001  /* Set if a rx frame was aborted */
+#define        RCR_PRMS        0x0002  /* Enable promiscuous mode */
+#define        RCR_ALMUL       0x0004  /* When set accepts all multicast frames */
+#define RCR_RXEN       0x0100  /* IFF this is set, we can receive packets */
+#define        RCR_STRIP_CRC   0x0200  /* When set strips CRC from rx packets */
+#define        RCR_ABORT_ENB   0x0200  /* When set will abort rx on collision */
+#define        RCR_FILT_CAR    0x0400  /* When set filters leading 12 bit s of carrier */
+#define RCR_SOFTRST    0x8000  /* resets the chip */
+
+/* the normal settings for the RCR register : */
+#define        RCR_DEFAULT     (RCR_STRIP_CRC | RCR_RXEN)
+#define RCR_CLEAR      0x0     /* set it to a base state */
+
+/* Counter Register */
+/* BANK 0  */
+#define        COUNTER_REG     0x0006
+
+/* Memory Information Register */
+/* BANK 0  */
+#define        MIR_REG         0x0008
+
+/* Receive/Phy Control Register */
+/* BANK 0  */
+#define        RPC_REG         0x000A
+#define        RPC_SPEED       0x2000  /* When 1 PHY is in 100Mbps mode. */
+#define        RPC_DPLX        0x1000  /* When 1 PHY is in Full-Duplex Mode */
+#define        RPC_ANEG        0x0800  /* When 1 PHY is in Auto-Negotiate Mode */
+#define        RPC_LSXA_SHFT   5       /* Bits to shift LS2A,LS1A,LS0A to lsb */
+#define        RPC_LSXB_SHFT   2       /* Bits to get LS2B,LS1B,LS0B to lsb */
+#define RPC_LED_100_10 (0x00)  /* LED = 100Mbps OR's with 10Mbps link detect */
+#define RPC_LED_RES    (0x01)  /* LED = Reserved */
+#define RPC_LED_10     (0x02)  /* LED = 10Mbps link detect */
+#define RPC_LED_FD     (0x03)  /* LED = Full Duplex Mode */
+#define RPC_LED_TX_RX  (0x04)  /* LED = TX or RX packet occurred */
+#define RPC_LED_100    (0x05)  /* LED = 100Mbps link dectect */
+#define RPC_LED_TX     (0x06)  /* LED = TX packet occurred */
+#define RPC_LED_RX     (0x07)  /* LED = RX packet occurred */
+#if defined(CONFIG_DK1C20) || defined(CONFIG_DK1S10)
+/* buggy schematic: LEDa -> yellow, LEDb --> green */
+#define RPC_DEFAULT    ( RPC_SPEED | RPC_DPLX | RPC_ANEG       \
+                       | (RPC_LED_TX_RX << RPC_LSXA_SHFT)      \
+                       | (RPC_LED_100_10 << RPC_LSXB_SHFT)     )
+#elif defined(CONFIG_ADNPESC1)
+/* SSV ADNP/ESC1 has only one LED: LEDa -> Rx/Tx indicator */
+#define RPC_DEFAULT    ( RPC_SPEED | RPC_DPLX | RPC_ANEG       \
+                       | (RPC_LED_TX_RX << RPC_LSXA_SHFT)      \
+                       | (RPC_LED_100_10 << RPC_LSXB_SHFT)     )
+#else
+/* SMSC reference design: LEDa --> green, LEDb --> yellow */
+#define RPC_DEFAULT    ( RPC_SPEED | RPC_DPLX | RPC_ANEG       \
+                       | (RPC_LED_100_10 << RPC_LSXA_SHFT)     \
+                       | (RPC_LED_TX_RX << RPC_LSXB_SHFT)      )
+#endif
+
+/* Bank 0 0x000C is reserved */
+
+/* Bank Select Register */
+/* All Banks */
+#define BSR_REG        0x000E
+
+
+/* Configuration Reg */
+/* BANK 1 */
+#define CONFIG_REG     0x0000
+#define CONFIG_EXT_PHY 0x0200  /* 1=external MII, 0=internal Phy */
+#define CONFIG_GPCNTRL 0x0400  /* Inverse value drives pin nCNTRL */
+#define CONFIG_NO_WAIT 0x1000  /* When 1 no extra wait states on ISA bus */
+#define CONFIG_EPH_POWER_EN 0x8000 /* When 0 EPH is placed into low power mode. */
+
+/* Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low */
+#define CONFIG_DEFAULT (CONFIG_EPH_POWER_EN)
+
+
+/* Base Address Register */
+/* BANK 1 */
+#define        BASE_REG        0x0002
+
+
+/* Individual Address Registers */
+/* BANK 1 */
+#define        ADDR0_REG       0x0004
+#define        ADDR1_REG       0x0006
+#define        ADDR2_REG       0x0008
+
+
+/* General Purpose Register */
+/* BANK 1 */
+#define        GP_REG          0x000A
+
+
+/* Control Register */
+/* BANK 1 */
+#define        CTL_REG         0x000C
+#define CTL_RCV_BAD    0x4000 /* When 1 bad CRC packets are received */
+#define CTL_AUTO_RELEASE 0x0800 /* When 1 tx pages are released automatically */
+#define        CTL_LE_ENABLE   0x0080 /* When 1 enables Link Error interrupt */
+#define        CTL_CR_ENABLE   0x0040 /* When 1 enables Counter Rollover interrupt */
+#define        CTL_TE_ENABLE   0x0020 /* When 1 enables Transmit Error interrupt */
+#define        CTL_EEPROM_SELECT 0x0004 /* Controls EEPROM reload & store */
+#define        CTL_RELOAD      0x0002 /* When set reads EEPROM into registers */
+#define        CTL_STORE       0x0001 /* When set stores registers into EEPROM */
+#define CTL_DEFAULT     (0x1A10) /* Autorelease enabled*/
+
+/* MMU Command Register */
+/* BANK 2 */
+#define MMU_CMD_REG    0x0000
+#define MC_BUSY                1       /* When 1 the last release has not completed */
+#define MC_NOP         (0<<5)  /* No Op */
+#define        MC_ALLOC        (1<<5)  /* OR with number of 256 byte packets */
+#define        MC_RESET        (2<<5)  /* Reset MMU to initial state */
+#define        MC_REMOVE       (3<<5)  /* Remove the current rx packet */
+#define MC_RELEASE     (4<<5)  /* Remove and release the current rx packet */
+#define MC_FREEPKT     (5<<5)  /* Release packet in PNR register */
+#define MC_ENQUEUE     (6<<5)  /* Enqueue the packet for transmit */
+#define MC_RSTTXFIFO   (7<<5)  /* Reset the TX FIFOs */
+
+
+/* Packet Number Register */
+/* BANK 2 */
+#define        PN_REG          0x0002
+
+
+/* Allocation Result Register */
+/* BANK 2 */
+#define        AR_REG          0x0003
+#define AR_FAILED      0x80    /* Alocation Failed */
+
+
+/* RX FIFO Ports Register */
+/* BANK 2 */
+#define RXFIFO_REG     0x0004  /* Must be read as a word */
+#define RXFIFO_REMPTY  0x8000  /* RX FIFO Empty */
+
+
+/* TX FIFO Ports Register */
+/* BANK 2 */
+#define TXFIFO_REG     RXFIFO_REG      /* Must be read as a word */
+#define TXFIFO_TEMPTY  0x80    /* TX FIFO Empty */
+
+
+/* Pointer Register */
+/* BANK 2 */
+#define PTR_REG                0x0006
+#define        PTR_RCV         0x8000 /* 1=Receive area, 0=Transmit area */
+#define        PTR_AUTOINC     0x4000 /* Auto increment the pointer on each access */
+#define PTR_READ       0x2000 /* When 1 the operation is a read */
+#define PTR_NOTEMPTY   0x0800 /* When 1 _do not_ write fifo DATA REG */
+
+
+/* Data Register */
+/* BANK 2 */
+#define        SMC91111_DATA_REG       0x0008
+
+
+/* Interrupt Status/Acknowledge Register */
+/* BANK 2 */
+#define        SMC91111_INT_REG        0x000C
+
+
+/* Interrupt Mask Register */
+/* BANK 2 */
+#define IM_REG         0x000D
+#define        IM_MDINT        0x80 /* PHY MI Register 18 Interrupt */
+#define        IM_ERCV_INT     0x40 /* Early Receive Interrupt */
+#define        IM_EPH_INT      0x20 /* Set by Etheret Protocol Handler section */
+#define        IM_RX_OVRN_INT  0x10 /* Set by Receiver Overruns */
+#define        IM_ALLOC_INT    0x08 /* Set when allocation request is completed */
+#define        IM_TX_EMPTY_INT 0x04 /* Set if the TX FIFO goes empty */
+#define        IM_TX_INT       0x02 /* Transmit Interrrupt */
+#define IM_RCV_INT     0x01 /* Receive Interrupt */
+
+
+/* Multicast Table Registers */
+/* BANK 3 */
+#define        MCAST_REG1      0x0000
+#define        MCAST_REG2      0x0002
+#define        MCAST_REG3      0x0004
+#define        MCAST_REG4      0x0006
+
+
+/* Management Interface Register (MII) */
+/* BANK 3 */
+#define        MII_REG         0x0008
+#define MII_MSK_CRS100 0x4000 /* Disables CRS100 detection during tx half dup */
+#define MII_MDOE       0x0008 /* MII Output Enable */
+#define MII_MCLK       0x0004 /* MII Clock, pin MDCLK */
+#define MII_MDI                0x0002 /* MII Input, pin MDI */
+#define MII_MDO                0x0001 /* MII Output, pin MDO */
+
+
+/* Revision Register */
+/* BANK 3 */
+#define        REV_REG         0x000A /* ( hi: chip id   low: rev # ) */
+
+
+/* Early RCV Register */
+/* BANK 3 */
+/* this is NOT on SMC9192 */
+#define        ERCV_REG        0x000C
+#define ERCV_RCV_DISCRD        0x0080 /* When 1 discards a packet being received */
+#define ERCV_THRESHOLD 0x001F /* ERCV Threshold Mask */
+
+/* External Register */
+/* BANK 7 */
+#define        EXT_REG         0x0000
+
+
+#define CHIP_9192      3
+#define CHIP_9194      4
+#define CHIP_9195      5
+#define CHIP_9196      6
+#define CHIP_91100     7
+#define CHIP_91100FD   8
+#define CHIP_91111FD   9
+
+#if 0
+static const char * chip_ids[ 15 ] =  {
+       NULL, NULL, NULL,
+       /* 3 */ "SMC91C90/91C92",
+       /* 4 */ "SMC91C94",
+       /* 5 */ "SMC91C95",
+       /* 6 */ "SMC91C96",
+       /* 7 */ "SMC91C100",
+       /* 8 */ "SMC91C100FD",
+       /* 9 */ "SMC91C111",
+       NULL, NULL,
+       NULL, NULL, NULL};
+#endif
+
+/*
+ . Transmit status bits
+*/
+#define TS_SUCCESS 0x0001
+#define TS_LOSTCAR 0x0400
+#define TS_LATCOL  0x0200
+#define TS_16COL   0x0010
+
+/*
+ . Receive status bits
+*/
+#define RS_ALGNERR     0x8000
+#define RS_BRODCAST    0x4000
+#define RS_BADCRC      0x2000
+#define RS_ODDFRAME    0x1000  /* bug: the LAN91C111 never sets this on receive */
+#define RS_TOOLONG     0x0800
+#define RS_TOOSHORT    0x0400
+#define RS_MULTICAST   0x0001
+#define RS_ERRORS      (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
+
+
+/* PHY Types */
+enum {
+       PHY_LAN83C183 = 1,      /* LAN91C111 Internal PHY */
+       PHY_LAN83C180
+};
+
+
+/* PHY Register Addresses (LAN91C111 Internal PHY) */
+
+/* PHY Control Register */
+#define PHY_CNTL_REG           0x00
+#define PHY_CNTL_RST           0x8000  /* 1=PHY Reset */
+#define PHY_CNTL_LPBK          0x4000  /* 1=PHY Loopback */
+#define PHY_CNTL_SPEED         0x2000  /* 1=100Mbps, 0=10Mpbs */
+#define PHY_CNTL_ANEG_EN       0x1000 /* 1=Enable Auto negotiation */
+#define PHY_CNTL_PDN           0x0800  /* 1=PHY Power Down mode */
+#define PHY_CNTL_MII_DIS       0x0400  /* 1=MII 4 bit interface disabled */
+#define PHY_CNTL_ANEG_RST      0x0200 /* 1=Reset Auto negotiate */
+#define PHY_CNTL_DPLX          0x0100  /* 1=Full Duplex, 0=Half Duplex */
+#define PHY_CNTL_COLTST                0x0080  /* 1= MII Colision Test */
+
+/* PHY Status Register */
+#define PHY_STAT_REG           0x01
+#define PHY_STAT_CAP_T4                0x8000  /* 1=100Base-T4 capable */
+#define PHY_STAT_CAP_TXF       0x4000  /* 1=100Base-X full duplex capable */
+#define PHY_STAT_CAP_TXH       0x2000  /* 1=100Base-X half duplex capable */
+#define PHY_STAT_CAP_TF                0x1000  /* 1=10Mbps full duplex capable */
+#define PHY_STAT_CAP_TH                0x0800  /* 1=10Mbps half duplex capable */
+#define PHY_STAT_CAP_SUPR      0x0040  /* 1=recv mgmt frames with not preamble */
+#define PHY_STAT_ANEG_ACK      0x0020  /* 1=ANEG has completed */
+#define PHY_STAT_REM_FLT       0x0010  /* 1=Remote Fault detected */
+#define PHY_STAT_CAP_ANEG      0x0008  /* 1=Auto negotiate capable */
+#define PHY_STAT_LINK          0x0004  /* 1=valid link */
+#define PHY_STAT_JAB           0x0002  /* 1=10Mbps jabber condition */
+#define PHY_STAT_EXREG         0x0001  /* 1=extended registers implemented */
+
+/* PHY Identifier Registers */
+#define PHY_ID1_REG            0x02    /* PHY Identifier 1 */
+#define PHY_ID2_REG            0x03    /* PHY Identifier 2 */
+
+/* PHY Auto-Negotiation Advertisement Register */
+#define PHY_AD_REG             0x04
+#define PHY_AD_NP              0x8000  /* 1=PHY requests exchange of Next Page */
+#define PHY_AD_ACK             0x4000  /* 1=got link code word from remote */
+#define PHY_AD_RF              0x2000  /* 1=advertise remote fault */
+#define PHY_AD_T4              0x0200  /* 1=PHY is capable of 100Base-T4 */
+#define PHY_AD_TX_FDX          0x0100  /* 1=PHY is capable of 100Base-TX FDPLX */
+#define PHY_AD_TX_HDX          0x0080  /* 1=PHY is capable of 100Base-TX HDPLX */
+#define PHY_AD_10_FDX          0x0040  /* 1=PHY is capable of 10Base-T FDPLX */
+#define PHY_AD_10_HDX          0x0020  /* 1=PHY is capable of 10Base-T HDPLX */
+#define PHY_AD_CSMA            0x0001  /* 1=PHY is capable of 802.3 CMSA */
+
+/* PHY Auto-negotiation Remote End Capability Register */
+#define PHY_RMT_REG            0x05
+/* Uses same bit definitions as PHY_AD_REG */
+
+/* PHY Configuration Register 1 */
+#define PHY_CFG1_REG           0x10
+#define PHY_CFG1_LNKDIS                0x8000  /* 1=Rx Link Detect Function disabled */
+#define PHY_CFG1_XMTDIS                0x4000  /* 1=TP Transmitter Disabled */
+#define PHY_CFG1_XMTPDN                0x2000  /* 1=TP Transmitter Powered Down */
+#define PHY_CFG1_BYPSCR                0x0400  /* 1=Bypass scrambler/descrambler */
+#define PHY_CFG1_UNSCDS                0x0200  /* 1=Unscramble Idle Reception Disable */
+#define PHY_CFG1_EQLZR         0x0100  /* 1=Rx Equalizer Disabled */
+#define PHY_CFG1_CABLE         0x0080  /* 1=STP(150ohm), 0=UTP(100ohm) */
+#define PHY_CFG1_RLVL0         0x0040  /* 1=Rx Squelch level reduced by 4.5db */
+#define PHY_CFG1_TLVL_SHIFT    2       /* Transmit Output Level Adjust */
+#define PHY_CFG1_TLVL_MASK     0x003C
+#define PHY_CFG1_TRF_MASK      0x0003  /* Transmitter Rise/Fall time */
+
+
+/* PHY Configuration Register 2 */
+#define PHY_CFG2_REG           0x11
+#define PHY_CFG2_APOLDIS       0x0020  /* 1=Auto Polarity Correction disabled */
+#define PHY_CFG2_JABDIS                0x0010  /* 1=Jabber disabled */
+#define PHY_CFG2_MREG          0x0008  /* 1=Multiple register access (MII mgt) */
+#define PHY_CFG2_INTMDIO       0x0004  /* 1=Interrupt signaled with MDIO pulseo */
+
+/* PHY Status Output (and Interrupt status) Register */
+#define PHY_INT_REG            0x12    /* Status Output (Interrupt Status) */
+#define PHY_INT_INT            0x8000  /* 1=bits have changed since last read */
+#define        PHY_INT_LNKFAIL         0x4000  /* 1=Link Not detected */
+#define PHY_INT_LOSSSYNC       0x2000  /* 1=Descrambler has lost sync */
+#define PHY_INT_CWRD           0x1000  /* 1=Invalid 4B5B code detected on rx */
+#define PHY_INT_SSD            0x0800  /* 1=No Start Of Stream detected on rx */
+#define PHY_INT_ESD            0x0400  /* 1=No End Of Stream detected on rx */
+#define PHY_INT_RPOL           0x0200  /* 1=Reverse Polarity detected */
+#define PHY_INT_JAB            0x0100  /* 1=Jabber detected */
+#define PHY_INT_SPDDET         0x0080  /* 1=100Base-TX mode, 0=10Base-T mode */
+#define PHY_INT_DPLXDET                0x0040  /* 1=Device in Full Duplex */
+
+/* PHY Interrupt/Status Mask Register */
+#define PHY_MASK_REG           0x13    /* Interrupt Mask */
+/* Uses the same bit definitions as PHY_INT_REG */
+
+
+/*-------------------------------------------------------------------------
+ .  I define some macros to make it easier to do somewhat common
+ . or slightly complicated, repeated tasks.
+ --------------------------------------------------------------------------*/
+
+/* select a register bank, 0 to 3  */
+
+#define SMC_SELECT_BANK(x)  { SMC_outw( x, BANK_SELECT ); }
+
+/* this enables an interrupt in the interrupt mask register */
+#define SMC_ENABLE_INT(x) {\
+               unsigned char mask;\
+               SMC_SELECT_BANK(2);\
+               mask = SMC_inb( IM_REG );\
+               mask |= (x);\
+               SMC_outb( mask, IM_REG ); \
+}
+
+/* this disables an interrupt from the interrupt mask register */
+
+#define SMC_DISABLE_INT(x) {\
+               unsigned char mask;\
+               SMC_SELECT_BANK(2);\
+               mask = SMC_inb( IM_REG );\
+               mask &= ~(x);\
+               SMC_outb( mask, IM_REG ); \
+}
+
+/*----------------------------------------------------------------------
+ . Define the interrupts that I want to receive from the card
+ .
+ . I want:
+ .  IM_EPH_INT, for nasty errors
+ .  IM_RCV_INT, for happy received packets
+ .  IM_RX_OVRN_INT, because I have to kick the receiver
+ .  IM_MDINT, for PHY Register 18 Status Changes
+ --------------------------------------------------------------------------*/
+#define SMC_INTERRUPT_MASK   (IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT | \
+       IM_MDINT)
+
+#endif  /* _SMC_91111_H_ */
diff --git a/drivers/net/tigon3.c b/drivers/net/tigon3.c
new file mode 100644 (file)
index 0000000..5f6a4ec
--- /dev/null
@@ -0,0 +1,5699 @@
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/******************************************************************************/
+#include <common.h>
+#include <asm/types.h>
+#if defined(CONFIG_CMD_NET) && !defined(CONFIG_NET_MULTI) && \
+       defined(CONFIG_TIGON3)
+#ifdef CONFIG_BMW
+#include <mpc824x.h>
+#endif
+#include <malloc.h>
+#include <linux/byteorder/big_endian.h>
+#include "bcm570x_mm.h"
+
+#define EMBEDDED 1
+/******************************************************************************/
+/* Local functions. */
+/******************************************************************************/
+
+LM_STATUS LM_Abort (PLM_DEVICE_BLOCK pDevice);
+LM_STATUS LM_QueueRxPackets (PLM_DEVICE_BLOCK pDevice);
+
+static LM_STATUS LM_TranslateRequestedMediaType (LM_REQUESTED_MEDIA_TYPE
+                                                RequestedMediaType,
+                                                PLM_MEDIA_TYPE pMediaType,
+                                                PLM_LINE_SPEED pLineSpeed,
+                                                PLM_DUPLEX_MODE pDuplexMode);
+
+static LM_STATUS LM_InitBcm540xPhy (PLM_DEVICE_BLOCK pDevice);
+
+__inline static LM_VOID LM_ServiceRxInterrupt (PLM_DEVICE_BLOCK pDevice);
+__inline static LM_VOID LM_ServiceTxInterrupt (PLM_DEVICE_BLOCK pDevice);
+
+static LM_STATUS LM_ForceAutoNegBcm540xPhy (PLM_DEVICE_BLOCK pDevice,
+                                           LM_REQUESTED_MEDIA_TYPE
+                                           RequestedMediaType);
+static LM_STATUS LM_ForceAutoNeg (PLM_DEVICE_BLOCK pDevice,
+                                 LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
+static LM_UINT32 GetPhyAdFlowCntrlSettings (PLM_DEVICE_BLOCK pDevice);
+STATIC LM_STATUS LM_SetFlowControl (PLM_DEVICE_BLOCK pDevice,
+                                   LM_UINT32 LocalPhyAd,
+                                   LM_UINT32 RemotePhyAd);
+#if INCLUDE_TBI_SUPPORT
+STATIC LM_STATUS LM_SetupFiberPhy (PLM_DEVICE_BLOCK pDevice);
+STATIC LM_STATUS LM_InitBcm800xPhy (PLM_DEVICE_BLOCK pDevice);
+#endif
+STATIC LM_STATUS LM_SetupCopperPhy (PLM_DEVICE_BLOCK pDevice);
+STATIC PLM_ADAPTER_INFO LM_GetAdapterInfoBySsid (LM_UINT16 Svid,
+                                                LM_UINT16 Ssid);
+STATIC LM_STATUS LM_DmaTest (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
+                            LM_PHYSICAL_ADDRESS BufferPhy,
+                            LM_UINT32 BufferSize);
+STATIC LM_STATUS LM_HaltCpu (PLM_DEVICE_BLOCK pDevice, LM_UINT32 cpu_number);
+STATIC LM_STATUS LM_ResetChip (PLM_DEVICE_BLOCK pDevice);
+STATIC LM_STATUS LM_Test4GBoundary (PLM_DEVICE_BLOCK pDevice,
+                                   PLM_PACKET pPacket, PT3_SND_BD pSendBd);
+
+/******************************************************************************/
+/* External functions. */
+/******************************************************************************/
+
+LM_STATUS LM_LoadRlsFirmware (PLM_DEVICE_BLOCK pDevice);
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_UINT32 LM_RegRdInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register)
+{
+       LM_UINT32 Value32;
+
+#if PCIX_TARGET_WORKAROUND
+       MM_ACQUIRE_UNDI_LOCK (pDevice);
+#endif
+       MM_WriteConfig32 (pDevice, T3_PCI_REG_ADDR_REG, Register);
+       MM_ReadConfig32 (pDevice, T3_PCI_REG_DATA_REG, &Value32);
+#if PCIX_TARGET_WORKAROUND
+       MM_RELEASE_UNDI_LOCK (pDevice);
+#endif
+
+       return Value32;
+}                              /* LM_RegRdInd */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_VOID
+LM_RegWrInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register, LM_UINT32 Value32)
+{
+
+#if PCIX_TARGET_WORKAROUND
+       MM_ACQUIRE_UNDI_LOCK (pDevice);
+#endif
+       MM_WriteConfig32 (pDevice, T3_PCI_REG_ADDR_REG, Register);
+       MM_WriteConfig32 (pDevice, T3_PCI_REG_DATA_REG, Value32);
+#if PCIX_TARGET_WORKAROUND
+       MM_RELEASE_UNDI_LOCK (pDevice);
+#endif
+}                              /* LM_RegWrInd */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_UINT32 LM_MemRdInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr)
+{
+       LM_UINT32 Value32;
+
+       MM_ACQUIRE_UNDI_LOCK (pDevice);
+#ifdef BIG_ENDIAN_HOST
+       MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
+       Value32 = REG_RD (pDevice, PciCfg.MemWindowData);
+       /*    Value32 = REG_RD(pDevice,uIntMem.Mbuf[(MemAddr & 0x7fff)/4]); */
+#else
+       MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
+       MM_ReadConfig32 (pDevice, T3_PCI_MEM_WIN_DATA_REG, &Value32);
+#endif
+       MM_RELEASE_UNDI_LOCK (pDevice);
+
+       return Value32;
+}                              /* LM_MemRdInd */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_VOID
+LM_MemWrInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr, LM_UINT32 Value32)
+{
+       MM_ACQUIRE_UNDI_LOCK (pDevice);
+#ifdef BIG_ENDIAN_HOST
+       REG_WR (pDevice, PciCfg.MemWindowBaseAddr, MemAddr);
+       REG_WR (pDevice, uIntMem.Mbuf[(MemAddr & 0x7fff) / 4], Value32);
+#else
+       MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
+       MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_DATA_REG, Value32);
+#endif
+       MM_RELEASE_UNDI_LOCK (pDevice);
+}                              /* LM_MemWrInd */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS LM_QueueRxPackets (PLM_DEVICE_BLOCK pDevice)
+{
+       LM_STATUS Lmstatus;
+       PLM_PACKET pPacket;
+       PT3_RCV_BD pRcvBd;
+       LM_UINT32 StdBdAdded = 0;
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+       LM_UINT32 JumboBdAdded = 0;
+#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+       Lmstatus = LM_STATUS_SUCCESS;
+
+       pPacket = (PLM_PACKET) QQ_PopHead (&pDevice->RxPacketFreeQ.Container);
+       while (pPacket) {
+               switch (pPacket->u.Rx.RcvProdRing) {
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+               case T3_JUMBO_RCV_PROD_RING:    /* Jumbo Receive Ring. */
+                       /* Initialize the buffer descriptor. */
+                       pRcvBd =
+                           &pDevice->pRxJumboBdVirt[pDevice->RxJumboProdIdx];
+                       pRcvBd->Flags =
+                           RCV_BD_FLAG_END | RCV_BD_FLAG_JUMBO_RING;
+                       pRcvBd->Len = (LM_UINT16) pDevice->RxJumboBufferSize;
+
+                       /* Initialize the receive buffer pointer */
+#if 0                          /* Jimmy, deleted in new */
+                       pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low;
+                       pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;
+#endif
+                       MM_MapRxDma (pDevice, pPacket, &pRcvBd->HostAddr);
+
+                       /* The opaque field may point to an offset from a fix addr. */
+                       pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR (pPacket) -
+                                                     MM_UINT_PTR (pDevice->
+                                                                  pPacketDescBase));
+
+                       /* Update the producer index. */
+                       pDevice->RxJumboProdIdx =
+                           (pDevice->RxJumboProdIdx +
+                            1) & T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
+
+                       JumboBdAdded++;
+                       break;
+#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+               case T3_STD_RCV_PROD_RING:      /* Standard Receive Ring. */
+                       /* Initialize the buffer descriptor. */
+                       pRcvBd = &pDevice->pRxStdBdVirt[pDevice->RxStdProdIdx];
+                       pRcvBd->Flags = RCV_BD_FLAG_END;
+                       pRcvBd->Len = MAX_STD_RCV_BUFFER_SIZE;
+
+                       /* Initialize the receive buffer pointer */
+#if 0                          /* Jimmy, deleted in new replaced with MM_MapRxDma */
+                       pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low;
+                       pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;
+#endif
+                       MM_MapRxDma (pDevice, pPacket, &pRcvBd->HostAddr);
+
+                       /* The opaque field may point to an offset from a fix addr. */
+                       pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR (pPacket) -
+                                                     MM_UINT_PTR (pDevice->
+                                                                  pPacketDescBase));
+
+                       /* Update the producer index. */
+                       pDevice->RxStdProdIdx = (pDevice->RxStdProdIdx + 1) &
+                           T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
+
+                       StdBdAdded++;
+                       break;
+
+               case T3_UNKNOWN_RCV_PROD_RING:
+               default:
+                       Lmstatus = LM_STATUS_FAILURE;
+                       break;
+               }               /* switch */
+
+               /* Bail out if there is any error. */
+               if (Lmstatus != LM_STATUS_SUCCESS) {
+                       break;
+               }
+
+               pPacket =
+                   (PLM_PACKET) QQ_PopHead (&pDevice->RxPacketFreeQ.Container);
+       }                       /* while */
+
+       wmb ();
+       /* Update the procedure index. */
+       if (StdBdAdded) {
+               MB_REG_WR (pDevice, Mailbox.RcvStdProdIdx.Low,
+                          pDevice->RxStdProdIdx);
+       }
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+       if (JumboBdAdded) {
+               MB_REG_WR (pDevice, Mailbox.RcvJumboProdIdx.Low,
+                          pDevice->RxJumboProdIdx);
+       }
+#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+       return Lmstatus;
+}                              /* LM_QueueRxPackets */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+STATIC LM_VOID LM_NvramInit (PLM_DEVICE_BLOCK pDevice)
+{
+       LM_UINT32 Value32;
+       LM_UINT32 j;
+
+       /* Intialize clock period and state machine. */
+       Value32 = SEEPROM_ADDR_CLK_PERD (SEEPROM_CLOCK_PERIOD) |
+           SEEPROM_ADDR_FSM_RESET;
+       REG_WR (pDevice, Grc.EepromAddr, Value32);
+
+       for (j = 0; j < 100; j++) {
+               MM_Wait (10);
+       }
+
+       /* Serial eeprom access using the Grc.EepromAddr/EepromData registers. */
+       Value32 = REG_RD (pDevice, Grc.LocalCtrl);
+       REG_WR (pDevice, Grc.LocalCtrl,
+               Value32 | GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM);
+
+       /* Set the 5701 compatibility mode if we are using EEPROM. */
+       if (T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
+           T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5701) {
+               Value32 = REG_RD (pDevice, Nvram.Config1);
+               if ((Value32 & FLASH_INTERFACE_ENABLE) == 0) {
+                       /* Use the new interface to read EEPROM. */
+                       Value32 &= ~FLASH_COMPAT_BYPASS;
+
+                       REG_WR (pDevice, Nvram.Config1, Value32);
+               }
+       }
+}                              /* LM_NvRamInit */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+STATIC LM_STATUS
+LM_EepromRead (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, LM_UINT32 * pData)
+{
+       LM_UINT32 Value32;
+       LM_UINT32 Addr;
+       LM_UINT32 Dev;
+       LM_UINT32 j;
+
+       if (Offset > SEEPROM_CHIP_SIZE) {
+               return LM_STATUS_FAILURE;
+       }
+
+       Dev = Offset / SEEPROM_CHIP_SIZE;
+       Addr = Offset % SEEPROM_CHIP_SIZE;
+
+       Value32 = REG_RD (pDevice, Grc.EepromAddr);
+       Value32 &= ~(SEEPROM_ADDR_ADDRESS_MASK | SEEPROM_ADDR_DEV_ID_MASK |
+                    SEEPROM_ADDR_RW_MASK);
+       REG_WR (pDevice, Grc.EepromAddr, Value32 | SEEPROM_ADDR_DEV_ID (Dev) |
+               SEEPROM_ADDR_ADDRESS (Addr) | SEEPROM_ADDR_START |
+               SEEPROM_ADDR_READ);
+
+       for (j = 0; j < 1000; j++) {
+               Value32 = REG_RD (pDevice, Grc.EepromAddr);
+               if (Value32 & SEEPROM_ADDR_COMPLETE) {
+                       break;
+               }
+               MM_Wait (10);
+       }
+
+       if (Value32 & SEEPROM_ADDR_COMPLETE) {
+               Value32 = REG_RD (pDevice, Grc.EepromData);
+               *pData = Value32;
+
+               return LM_STATUS_SUCCESS;
+       }
+
+       return LM_STATUS_FAILURE;
+}                              /* LM_EepromRead */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+STATIC LM_STATUS
+LM_NvramRead (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, LM_UINT32 * pData)
+{
+       LM_UINT32 Value32;
+       LM_STATUS Status;
+       LM_UINT32 j;
+
+       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+           T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
+               Status = LM_EepromRead (pDevice, Offset, pData);
+       } else {
+               /* Determine if we have flash or EEPROM. */
+               Value32 = REG_RD (pDevice, Nvram.Config1);
+               if (Value32 & FLASH_INTERFACE_ENABLE) {
+                       if (Value32 & FLASH_SSRAM_BUFFERRED_MODE) {
+                               Offset = ((Offset / BUFFERED_FLASH_PAGE_SIZE) <<
+                                         BUFFERED_FLASH_PAGE_POS) +
+                                   (Offset % BUFFERED_FLASH_PAGE_SIZE);
+                       }
+               }
+
+               REG_WR (pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
+               for (j = 0; j < 1000; j++) {
+                       if (REG_RD (pDevice, Nvram.SwArb) & SW_ARB_GNT1) {
+                               break;
+                       }
+                       MM_Wait (20);
+               }
+               if (j == 1000) {
+                       return LM_STATUS_FAILURE;
+               }
+
+               /* Read from flash or EEPROM with the new 5703/02 interface. */
+               REG_WR (pDevice, Nvram.Addr, Offset & NVRAM_ADDRESS_MASK);
+
+               REG_WR (pDevice, Nvram.Cmd, NVRAM_CMD_RD | NVRAM_CMD_DO_IT |
+                       NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
+
+               /* Wait for the done bit to clear. */
+               for (j = 0; j < 500; j++) {
+                       MM_Wait (10);
+
+                       Value32 = REG_RD (pDevice, Nvram.Cmd);
+                       if (!(Value32 & NVRAM_CMD_DONE)) {
+                               break;
+                       }
+               }
+
+               /* Wait for the done bit. */
+               if (!(Value32 & NVRAM_CMD_DONE)) {
+                       for (j = 0; j < 500; j++) {
+                               MM_Wait (10);
+
+                               Value32 = REG_RD (pDevice, Nvram.Cmd);
+                               if (Value32 & NVRAM_CMD_DONE) {
+                                       MM_Wait (10);
+
+                                       *pData =
+                                           REG_RD (pDevice, Nvram.ReadData);
+
+                                       /* Change the endianess. */
+                                       *pData =
+                                           ((*pData & 0xff) << 24) |
+                                           ((*pData & 0xff00) << 8) |
+                                           ((*pData & 0xff0000) >> 8) |
+                                           ((*pData >> 24) & 0xff);
+
+                                       break;
+                               }
+                       }
+               }
+
+               REG_WR (pDevice, Nvram.SwArb, SW_ARB_REQ_CLR1);
+               if (Value32 & NVRAM_CMD_DONE) {
+                       Status = LM_STATUS_SUCCESS;
+               } else {
+                       Status = LM_STATUS_FAILURE;
+               }
+       }
+
+       return Status;
+}                              /* LM_NvramRead */
+
+STATIC void LM_ReadVPD (PLM_DEVICE_BLOCK pDevice)
+{
+       LM_UINT32 Vpd_arr[256 / 4];
+       LM_UINT8 *Vpd = (LM_UINT8 *) & Vpd_arr[0];
+       LM_UINT32 *Vpd_dptr = &Vpd_arr[0];
+       LM_UINT32 Value32;
+       unsigned int j;
+
+       /* Read PN from VPD */
+       for (j = 0; j < 256; j += 4, Vpd_dptr++) {
+               if (LM_NvramRead (pDevice, 0x100 + j, &Value32) !=
+                   LM_STATUS_SUCCESS) {
+                       printf ("BCM570x: LM_ReadVPD: VPD read failed"
+                               " (no EEPROM onboard)\n");
+                       return;
+               }
+               *Vpd_dptr = cpu_to_le32 (Value32);
+       }
+       for (j = 0; j < 256;) {
+               unsigned int Vpd_r_len;
+               unsigned int Vpd_r_end;
+
+               if ((Vpd[j] == 0x82) || (Vpd[j] == 0x91)) {
+                       j = j + 3 + Vpd[j + 1] + (Vpd[j + 2] << 8);
+               } else if (Vpd[j] == 0x90) {
+                       Vpd_r_len = Vpd[j + 1] + (Vpd[j + 2] << 8);
+                       j += 3;
+                       Vpd_r_end = Vpd_r_len + j;
+                       while (j < Vpd_r_end) {
+                               if ((Vpd[j] == 'P') && (Vpd[j + 1] == 'N')) {
+                                       unsigned int len = Vpd[j + 2];
+
+                                       if (len <= 24) {
+                                               memcpy (pDevice->PartNo,
+                                                       &Vpd[j + 3], len);
+                                       }
+                                       break;
+                               } else {
+                                       if (Vpd[j + 2] == 0) {
+                                               break;
+                                       }
+                                       j = j + Vpd[j + 2];
+                               }
+                       }
+                       break;
+               } else {
+                       break;
+               }
+       }
+}
+
+STATIC void LM_ReadBootCodeVersion (PLM_DEVICE_BLOCK pDevice)
+{
+       LM_UINT32 Value32, offset, ver_offset;
+       int i;
+
+       if (LM_NvramRead (pDevice, 0x0, &Value32) != LM_STATUS_SUCCESS)
+               return;
+       if (Value32 != 0xaa559966)
+               return;
+       if (LM_NvramRead (pDevice, 0xc, &offset) != LM_STATUS_SUCCESS)
+               return;
+
+       offset = ((offset & 0xff) << 24) | ((offset & 0xff00) << 8) |
+           ((offset & 0xff0000) >> 8) | ((offset >> 24) & 0xff);
+       if (LM_NvramRead (pDevice, offset, &Value32) != LM_STATUS_SUCCESS)
+               return;
+       if ((Value32 == 0x0300000e) &&
+           (LM_NvramRead (pDevice, offset + 4, &Value32) == LM_STATUS_SUCCESS)
+           && (Value32 == 0)) {
+
+               if (LM_NvramRead (pDevice, offset + 8, &ver_offset) !=
+                   LM_STATUS_SUCCESS)
+                       return;
+               ver_offset = ((ver_offset & 0xff0000) >> 8) |
+                   ((ver_offset >> 24) & 0xff);
+               for (i = 0; i < 16; i += 4) {
+                       if (LM_NvramRead
+                           (pDevice, offset + ver_offset + i,
+                            &Value32) != LM_STATUS_SUCCESS) {
+                               return;
+                       }
+                       *((LM_UINT32 *) & pDevice->BootCodeVer[i]) =
+                           cpu_to_le32 (Value32);
+               }
+       } else {
+               char c;
+
+               if (LM_NvramRead (pDevice, 0x94, &Value32) != LM_STATUS_SUCCESS)
+                       return;
+
+               i = 0;
+               c = ((Value32 & 0xff0000) >> 16);
+
+               if (c < 10) {
+                       pDevice->BootCodeVer[i++] = c + '0';
+               } else {
+                       pDevice->BootCodeVer[i++] = (c / 10) + '0';
+                       pDevice->BootCodeVer[i++] = (c % 10) + '0';
+               }
+               pDevice->BootCodeVer[i++] = '.';
+               c = (Value32 & 0xff000000) >> 24;
+               if (c < 10) {
+                       pDevice->BootCodeVer[i++] = c + '0';
+               } else {
+                       pDevice->BootCodeVer[i++] = (c / 10) + '0';
+                       pDevice->BootCodeVer[i++] = (c % 10) + '0';
+               }
+               pDevice->BootCodeVer[i] = 0;
+       }
+}
+
+STATIC void LM_GetBusSpeed (PLM_DEVICE_BLOCK pDevice)
+{
+       LM_UINT32 PciState = pDevice->PciState;
+       LM_UINT32 ClockCtrl;
+       char *SpeedStr = "";
+
+       if (PciState & T3_PCI_STATE_32BIT_PCI_BUS) {
+               strcpy (pDevice->BusSpeedStr, "32-bit ");
+       } else {
+               strcpy (pDevice->BusSpeedStr, "64-bit ");
+       }
+       if (PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) {
+               strcat (pDevice->BusSpeedStr, "PCI ");
+               if (PciState & T3_PCI_STATE_HIGH_BUS_SPEED) {
+                       SpeedStr = "66MHz";
+               } else {
+                       SpeedStr = "33MHz";
+               }
+       } else {
+               strcat (pDevice->BusSpeedStr, "PCIX ");
+               if (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE) {
+                       SpeedStr = "133MHz";
+               } else {
+                       ClockCtrl = REG_RD (pDevice, PciCfg.ClockCtrl) & 0x1f;
+                       switch (ClockCtrl) {
+                       case 0:
+                               SpeedStr = "33MHz";
+                               break;
+
+                       case 2:
+                               SpeedStr = "50MHz";
+                               break;
+
+                       case 4:
+                               SpeedStr = "66MHz";
+                               break;
+
+                       case 6:
+                               SpeedStr = "100MHz";
+                               break;
+
+                       case 7:
+                               SpeedStr = "133MHz";
+                               break;
+                       }
+               }
+       }
+       strcat (pDevice->BusSpeedStr, SpeedStr);
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This routine initializes default parameters and reads the PCI           */
+/*    configurations.                                                         */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS LM_GetAdapterInfo (PLM_DEVICE_BLOCK pDevice)
+{
+       PLM_ADAPTER_INFO pAdapterInfo;
+       LM_UINT32 Value32;
+       LM_STATUS Status;
+       LM_UINT32 j;
+       LM_UINT32 EeSigFound;
+       LM_UINT32 EePhyTypeSerdes = 0;
+       LM_UINT32 EePhyLedMode = 0;
+       LM_UINT32 EePhyId = 0;
+
+       /* Get Device Id and Vendor Id */
+       Status = MM_ReadConfig32 (pDevice, PCI_VENDOR_ID_REG, &Value32);
+       if (Status != LM_STATUS_SUCCESS) {
+               return Status;
+       }
+       pDevice->PciVendorId = (LM_UINT16) Value32;
+       pDevice->PciDeviceId = (LM_UINT16) (Value32 >> 16);
+
+       /* If we are not getting the write adapter, exit. */
+       if ((Value32 != T3_PCI_ID_BCM5700) &&
+           (Value32 != T3_PCI_ID_BCM5701) &&
+           (Value32 != T3_PCI_ID_BCM5702) &&
+           (Value32 != T3_PCI_ID_BCM5702x) &&
+           (Value32 != T3_PCI_ID_BCM5702FE) &&
+           (Value32 != T3_PCI_ID_BCM5703) &&
+           (Value32 != T3_PCI_ID_BCM5703x) && (Value32 != T3_PCI_ID_BCM5704)) {
+               return LM_STATUS_FAILURE;
+       }
+
+       Status = MM_ReadConfig32 (pDevice, PCI_REV_ID_REG, &Value32);
+       if (Status != LM_STATUS_SUCCESS) {
+               return Status;
+       }
+       pDevice->PciRevId = (LM_UINT8) Value32;
+
+       /* Get IRQ. */
+       Status = MM_ReadConfig32 (pDevice, PCI_INT_LINE_REG, &Value32);
+       if (Status != LM_STATUS_SUCCESS) {
+               return Status;
+       }
+       pDevice->Irq = (LM_UINT8) Value32;
+
+       /* Get interrupt pin. */
+       pDevice->IntPin = (LM_UINT8) (Value32 >> 8);
+
+       /* Get chip revision id. */
+       Status = MM_ReadConfig32 (pDevice, T3_PCI_MISC_HOST_CTRL_REG, &Value32);
+       pDevice->ChipRevId = Value32 >> 16;
+
+       /* Get subsystem vendor. */
+       Status =
+           MM_ReadConfig32 (pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG, &Value32);
+       if (Status != LM_STATUS_SUCCESS) {
+               return Status;
+       }
+       pDevice->SubsystemVendorId = (LM_UINT16) Value32;
+
+       /* Get PCI subsystem id. */
+       pDevice->SubsystemId = (LM_UINT16) (Value32 >> 16);
+
+       /* Get the cache line size. */
+       MM_ReadConfig32 (pDevice, PCI_CACHE_LINE_SIZE_REG, &Value32);
+       pDevice->CacheLineSize = (LM_UINT8) Value32;
+       pDevice->SavedCacheLineReg = Value32;
+
+       if (pDevice->ChipRevId != T3_CHIP_ID_5703_A1 &&
+           pDevice->ChipRevId != T3_CHIP_ID_5703_A2 &&
+           pDevice->ChipRevId != T3_CHIP_ID_5704_A0) {
+               pDevice->UndiFix = FALSE;
+       }
+#if !PCIX_TARGET_WORKAROUND
+       pDevice->UndiFix = FALSE;
+#endif
+       /* Map the memory base to system address space. */
+       if (!pDevice->UndiFix) {
+               Status = MM_MapMemBase (pDevice);
+               if (Status != LM_STATUS_SUCCESS) {
+                       return Status;
+               }
+               /* Initialize the memory view pointer. */
+               pDevice->pMemView = (PT3_STD_MEM_MAP) pDevice->pMappedMemBase;
+       }
+#if PCIX_TARGET_WORKAROUND
+       /* store whether we are in PCI are PCI-X mode */
+       pDevice->EnablePciXFix = FALSE;
+
+       MM_ReadConfig32 (pDevice, T3_PCI_STATE_REG, &Value32);
+       if ((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0) {
+               /* Enable PCI-X workaround only if we are running on 5700 BX. */
+               if (T3_CHIP_REV (pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) {
+                       pDevice->EnablePciXFix = TRUE;
+               }
+       }
+       if (pDevice->UndiFix) {
+               pDevice->EnablePciXFix = TRUE;
+       }
+#endif
+       /* Bx bug: due to the "byte_enable bug" in PCI-X mode, the power */
+       /* management register may be clobbered which may cause the */
+       /* BCM5700 to go into D3 state.  While in this state, we will */
+       /* not have memory mapped register access.  As a workaround, we */
+       /* need to restore the device to D0 state. */
+       MM_ReadConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, &Value32);
+       Value32 |= T3_PM_PME_ASSERTED;
+       Value32 &= ~T3_PM_POWER_STATE_MASK;
+       Value32 |= T3_PM_POWER_STATE_D0;
+       MM_WriteConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, Value32);
+
+       /* read the current PCI command word */
+       MM_ReadConfig32 (pDevice, PCI_COMMAND_REG, &Value32);
+
+       /* Make sure bus-mastering is enabled. */
+       Value32 |= PCI_BUSMASTER_ENABLE;
+
+#if PCIX_TARGET_WORKAROUND
+       /* if we are in PCI-X mode, also make sure mem-mapping and SERR#/PERR#
+          are enabled */
+       if (pDevice->EnablePciXFix == TRUE) {
+               Value32 |= (PCI_MEM_SPACE_ENABLE | PCI_SYSTEM_ERROR_ENABLE |
+                           PCI_PARITY_ERROR_ENABLE);
+       }
+       if (pDevice->UndiFix) {
+               Value32 &= ~PCI_MEM_SPACE_ENABLE;
+       }
+#endif
+
+       if (pDevice->EnableMWI) {
+               Value32 |= PCI_MEMORY_WRITE_INVALIDATE;
+       } else {
+               Value32 &= (~PCI_MEMORY_WRITE_INVALIDATE);
+       }
+
+       /* Error out if mem-mapping is NOT enabled for PCI systems */
+       if (!(Value32 | PCI_MEM_SPACE_ENABLE)) {
+               return LM_STATUS_FAILURE;
+       }
+
+       /* save the value we are going to write into the PCI command word */
+       pDevice->PciCommandStatusWords = Value32;
+
+       Status = MM_WriteConfig32 (pDevice, PCI_COMMAND_REG, Value32);
+       if (Status != LM_STATUS_SUCCESS) {
+               return Status;
+       }
+
+       /* Set power state to D0. */
+       LM_SetPowerState (pDevice, LM_POWER_STATE_D0);
+
+#ifdef BIG_ENDIAN_PCI
+       pDevice->MiscHostCtrl =
+           MISC_HOST_CTRL_MASK_PCI_INT |
+           MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
+           MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
+           MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
+#else                          /* No CPU Swap modes for PCI IO */
+
+       /* Setup the mode registers. */
+       pDevice->MiscHostCtrl =
+           MISC_HOST_CTRL_MASK_PCI_INT |
+           MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
+#ifdef BIG_ENDIAN_HOST
+           MISC_HOST_CTRL_ENABLE_ENDIAN_BYTE_SWAP |
+#endif                         /* BIG_ENDIAN_HOST */
+           MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
+           MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
+#endif                         /* !BIG_ENDIAN_PCI */
+
+       /* write to PCI misc host ctr first in order to enable indirect accesses */
+       MM_WriteConfig32 (pDevice, T3_PCI_MISC_HOST_CTRL_REG,
+                         pDevice->MiscHostCtrl);
+
+       REG_WR (pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl);
+
+#ifdef BIG_ENDIAN_PCI
+       Value32 = GRC_MODE_WORD_SWAP_DATA | GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
+#else
+/* No CPU Swap modes for PCI IO */
+#ifdef BIG_ENDIAN_HOST
+       Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
+           GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
+#else
+       Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
+#endif
+#endif                         /* !BIG_ENDIAN_PCI */
+
+       REG_WR (pDevice, Grc.Mode, Value32);
+
+       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
+               REG_WR (pDevice, Grc.LocalCtrl,
+                       GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
+                       GRC_MISC_LOCAL_CTRL_GPIO_OE1);
+       }
+       MM_Wait (40);
+
+       /* Enable indirect memory access */
+       REG_WR (pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
+
+       if (REG_RD (pDevice, PciCfg.ClockCtrl) & T3_PCI_44MHZ_CORE_CLOCK) {
+               REG_WR (pDevice, PciCfg.ClockCtrl, T3_PCI_44MHZ_CORE_CLOCK |
+                       T3_PCI_SELECT_ALTERNATE_CLOCK);
+               REG_WR (pDevice, PciCfg.ClockCtrl,
+                       T3_PCI_SELECT_ALTERNATE_CLOCK);
+               MM_Wait (40);   /* required delay is 27usec */
+       }
+       REG_WR (pDevice, PciCfg.ClockCtrl, 0);
+       REG_WR (pDevice, PciCfg.MemWindowBaseAddr, 0);
+
+#if PCIX_TARGET_WORKAROUND
+       MM_ReadConfig32 (pDevice, T3_PCI_STATE_REG, &Value32);
+       if ((pDevice->EnablePciXFix == FALSE) &&
+           ((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0)) {
+               if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+                   pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
+                   pDevice->ChipRevId == T3_CHIP_ID_5701_B2 ||
+                   pDevice->ChipRevId == T3_CHIP_ID_5701_B5) {
+                       __raw_writel (0,
+                                     &(pDevice->pMemView->uIntMem.
+                                       MemBlock32K[0x300]));
+                       __raw_writel (0,
+                                     &(pDevice->pMemView->uIntMem.
+                                       MemBlock32K[0x301]));
+                       __raw_writel (0xffffffff,
+                                     &(pDevice->pMemView->uIntMem.
+                                       MemBlock32K[0x301]));
+                       if (__raw_readl
+                           (&(pDevice->pMemView->uIntMem.MemBlock32K[0x300])))
+                       {
+                               pDevice->EnablePciXFix = TRUE;
+                       }
+               }
+       }
+#endif
+#if 1
+       /*
+        *  This code was at the beginning of else block below, but that's
+        *  a bug if node address in shared memory.
+        */
+       MM_Wait (50);
+       LM_NvramInit (pDevice);
+#endif
+       /* Get the node address.  First try to get in from the shared memory. */
+       /* If the signature is not present, then get it from the NVRAM. */
+       Value32 = MEM_RD_OFFSET (pDevice, T3_MAC_ADDR_HIGH_MAILBOX);
+       if ((Value32 >> 16) == 0x484b) {
+
+               pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 8);
+               pDevice->NodeAddress[1] = (LM_UINT8) Value32;
+
+               Value32 = MEM_RD_OFFSET (pDevice, T3_MAC_ADDR_LOW_MAILBOX);
+
+               pDevice->NodeAddress[2] = (LM_UINT8) (Value32 >> 24);
+               pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 16);
+               pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 8);
+               pDevice->NodeAddress[5] = (LM_UINT8) Value32;
+
+               Status = LM_STATUS_SUCCESS;
+       } else {
+               Status = LM_NvramRead (pDevice, 0x7c, &Value32);
+               if (Status == LM_STATUS_SUCCESS) {
+                       pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 16);
+                       pDevice->NodeAddress[1] = (LM_UINT8) (Value32 >> 24);
+
+                       Status = LM_NvramRead (pDevice, 0x80, &Value32);
+
+                       pDevice->NodeAddress[2] = (LM_UINT8) Value32;
+                       pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 8);
+                       pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 16);
+                       pDevice->NodeAddress[5] = (LM_UINT8) (Value32 >> 24);
+               }
+       }
+
+       /* Assign a default address. */
+       if (Status != LM_STATUS_SUCCESS) {
+#ifndef EMBEDDED
+               printk (KERN_ERR
+                       "Cannot get MAC addr from NVRAM. Using default.\n");
+#endif
+               pDevice->NodeAddress[0] = 0x00;
+               pDevice->NodeAddress[1] = 0x10;
+               pDevice->NodeAddress[2] = 0x18;
+               pDevice->NodeAddress[3] = 0x68;
+               pDevice->NodeAddress[4] = 0x61;
+               pDevice->NodeAddress[5] = 0x76;
+       }
+
+       pDevice->PermanentNodeAddress[0] = pDevice->NodeAddress[0];
+       pDevice->PermanentNodeAddress[1] = pDevice->NodeAddress[1];
+       pDevice->PermanentNodeAddress[2] = pDevice->NodeAddress[2];
+       pDevice->PermanentNodeAddress[3] = pDevice->NodeAddress[3];
+       pDevice->PermanentNodeAddress[4] = pDevice->NodeAddress[4];
+       pDevice->PermanentNodeAddress[5] = pDevice->NodeAddress[5];
+
+       /* Initialize the default values. */
+       pDevice->NoTxPseudoHdrChksum = FALSE;
+       pDevice->NoRxPseudoHdrChksum = FALSE;
+       pDevice->NicSendBd = FALSE;
+       pDevice->TxPacketDescCnt = DEFAULT_TX_PACKET_DESC_COUNT;
+       pDevice->RxStdDescCnt = DEFAULT_STD_RCV_DESC_COUNT;
+       pDevice->RxCoalescingTicks = DEFAULT_RX_COALESCING_TICKS;
+       pDevice->TxCoalescingTicks = DEFAULT_TX_COALESCING_TICKS;
+       pDevice->RxMaxCoalescedFrames = DEFAULT_RX_MAX_COALESCED_FRAMES;
+       pDevice->TxMaxCoalescedFrames = DEFAULT_TX_MAX_COALESCED_FRAMES;
+       pDevice->RxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
+       pDevice->TxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
+       pDevice->RxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
+       pDevice->TxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
+       pDevice->StatsCoalescingTicks = DEFAULT_STATS_COALESCING_TICKS;
+       pDevice->EnableMWI = FALSE;
+       pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
+       pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
+       pDevice->DisableAutoNeg = FALSE;
+       pDevice->PhyIntMode = T3_PHY_INT_MODE_AUTO;
+       pDevice->LinkChngMode = T3_LINK_CHNG_MODE_AUTO;
+       pDevice->LedMode = LED_MODE_AUTO;
+       pDevice->ResetPhyOnInit = TRUE;
+       pDevice->DelayPciGrant = TRUE;
+       pDevice->UseTaggedStatus = FALSE;
+       pDevice->OneDmaAtOnce = BAD_DEFAULT_VALUE;
+
+       pDevice->DmaMbufLowMark = T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO;
+       pDevice->RxMacMbufLowMark = T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO;
+       pDevice->MbufHighMark = T3_DEF_MBUF_HIGH_WMARK_JUMBO;
+
+       pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_AUTO;
+       pDevice->TaskOffloadCap = LM_TASK_OFFLOAD_NONE;
+       pDevice->FlowControlCap = LM_FLOW_CONTROL_AUTO_PAUSE;
+       pDevice->EnableTbi = FALSE;
+#if INCLUDE_TBI_SUPPORT
+       pDevice->PollTbiLink = BAD_DEFAULT_VALUE;
+#endif
+
+       switch (T3_ASIC_REV (pDevice->ChipRevId)) {
+       case T3_ASIC_REV_5704:
+               pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
+               pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE64;
+               break;
+       default:
+               pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
+               pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE96;
+               break;
+       }
+
+       pDevice->LinkStatus = LM_STATUS_LINK_DOWN;
+       pDevice->QueueRxPackets = TRUE;
+
+       pDevice->EnableWireSpeed = TRUE;
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+       pDevice->RxJumboDescCnt = DEFAULT_JUMBO_RCV_DESC_COUNT;
+#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+       /* Make this is a known adapter. */
+       pAdapterInfo = LM_GetAdapterInfoBySsid (pDevice->SubsystemVendorId,
+                                               pDevice->SubsystemId);
+
+       pDevice->BondId = REG_RD (pDevice, Grc.MiscCfg) & GRC_MISC_BD_ID_MASK;
+       if (pDevice->BondId != GRC_MISC_BD_ID_5700 &&
+           pDevice->BondId != GRC_MISC_BD_ID_5701 &&
+           pDevice->BondId != GRC_MISC_BD_ID_5702FE &&
+           pDevice->BondId != GRC_MISC_BD_ID_5703 &&
+           pDevice->BondId != GRC_MISC_BD_ID_5703S &&
+           pDevice->BondId != GRC_MISC_BD_ID_5704 &&
+           pDevice->BondId != GRC_MISC_BD_ID_5704CIOBE) {
+               return LM_STATUS_UNKNOWN_ADAPTER;
+       }
+
+       pDevice->SplitModeEnable = SPLIT_MODE_DISABLE;
+       if ((pDevice->ChipRevId == T3_CHIP_ID_5704_A0) &&
+           (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE)) {
+               pDevice->SplitModeEnable = SPLIT_MODE_ENABLE;
+               pDevice->SplitModeMaxReq = SPLIT_MODE_5704_MAX_REQ;
+       }
+
+       /* Get Eeprom info. */
+       Value32 = MEM_RD_OFFSET (pDevice, T3_NIC_DATA_SIG_ADDR);
+       if (Value32 == T3_NIC_DATA_SIG) {
+               EeSigFound = TRUE;
+               Value32 = MEM_RD_OFFSET (pDevice, T3_NIC_DATA_NIC_CFG_ADDR);
+
+               /* Determine PHY type. */
+               switch (Value32 & T3_NIC_CFG_PHY_TYPE_MASK) {
+               case T3_NIC_CFG_PHY_TYPE_COPPER:
+                       EePhyTypeSerdes = FALSE;
+                       break;
+
+               case T3_NIC_CFG_PHY_TYPE_FIBER:
+                       EePhyTypeSerdes = TRUE;
+                       break;
+
+               default:
+                       EePhyTypeSerdes = FALSE;
+                       break;
+               }
+
+               /* Determine PHY led mode. */
+               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
+                       switch (Value32 & T3_NIC_CFG_LED_MODE_MASK) {
+                       case T3_NIC_CFG_LED_MODE_TRIPLE_SPEED:
+                               EePhyLedMode = LED_MODE_THREE_LINK;
+                               break;
+
+                       case T3_NIC_CFG_LED_MODE_LINK_SPEED:
+                               EePhyLedMode = LED_MODE_LINK10;
+                               break;
+
+                       default:
+                               EePhyLedMode = LED_MODE_AUTO;
+                               break;
+                       }
+               } else {
+                       switch (Value32 & T3_NIC_CFG_LED_MODE_MASK) {
+                       case T3_NIC_CFG_LED_MODE_OPEN_DRAIN:
+                               EePhyLedMode = LED_MODE_OPEN_DRAIN;
+                               break;
+
+                       case T3_NIC_CFG_LED_MODE_OUTPUT:
+                               EePhyLedMode = LED_MODE_OUTPUT;
+                               break;
+
+                       default:
+                               EePhyLedMode = LED_MODE_AUTO;
+                               break;
+                       }
+               }
+               if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1 ||
+                   pDevice->ChipRevId == T3_CHIP_ID_5703_A2) {
+                       /* Enable EEPROM write protection. */
+                       if (Value32 & T3_NIC_EEPROM_WP) {
+                               pDevice->EepromWp = TRUE;
+                       }
+               }
+
+               /* Get the PHY Id. */
+               Value32 = MEM_RD_OFFSET (pDevice, T3_NIC_DATA_PHY_ID_ADDR);
+               if (Value32) {
+                       EePhyId = (((Value32 & T3_NIC_PHY_ID1_MASK) >> 16) &
+                                  PHY_ID1_OUI_MASK) << 10;
+
+                       Value32 = Value32 & T3_NIC_PHY_ID2_MASK;
+
+                       EePhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
+                           (Value32 & PHY_ID2_MODEL_MASK) | (Value32 &
+                                                             PHY_ID2_REV_MASK);
+               } else {
+                       EePhyId = 0;
+               }
+       } else {
+               EeSigFound = FALSE;
+       }
+
+       /* Set the PHY address. */
+       pDevice->PhyAddr = PHY_DEVICE_ID;
+
+       /* Disable auto polling. */
+       pDevice->MiMode = 0xc0000;
+       REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
+       MM_Wait (40);
+
+       /* Get the PHY id. */
+       LM_ReadPhy (pDevice, PHY_ID1_REG, &Value32);
+       pDevice->PhyId = (Value32 & PHY_ID1_OUI_MASK) << 10;
+
+       LM_ReadPhy (pDevice, PHY_ID2_REG, &Value32);
+       pDevice->PhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
+           (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
+
+       /* Set the EnableTbi flag to false if we have a copper PHY. */
+       switch (pDevice->PhyId & PHY_ID_MASK) {
+       case PHY_BCM5400_PHY_ID:
+               pDevice->EnableTbi = FALSE;
+               break;
+
+       case PHY_BCM5401_PHY_ID:
+               pDevice->EnableTbi = FALSE;
+               break;
+
+       case PHY_BCM5411_PHY_ID:
+               pDevice->EnableTbi = FALSE;
+               break;
+
+       case PHY_BCM5701_PHY_ID:
+               pDevice->EnableTbi = FALSE;
+               break;
+
+       case PHY_BCM5703_PHY_ID:
+               pDevice->EnableTbi = FALSE;
+               break;
+
+       case PHY_BCM5704_PHY_ID:
+               pDevice->EnableTbi = FALSE;
+               break;
+
+       case PHY_BCM8002_PHY_ID:
+               pDevice->EnableTbi = TRUE;
+               break;
+
+       default:
+
+               if (pAdapterInfo) {
+                       pDevice->PhyId = pAdapterInfo->PhyId;
+                       pDevice->EnableTbi = pAdapterInfo->Serdes;
+               } else if (EeSigFound) {
+                       pDevice->PhyId = EePhyId;
+                       pDevice->EnableTbi = EePhyTypeSerdes;
+               }
+               break;
+       }
+
+       /* Bail out if we don't know the copper PHY id. */
+       if (UNKNOWN_PHY_ID (pDevice->PhyId) && !pDevice->EnableTbi) {
+               return LM_STATUS_FAILURE;
+       }
+
+       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5703) {
+               if ((pDevice->SavedCacheLineReg & 0xff00) < 0x4000) {
+                       pDevice->SavedCacheLineReg &= 0xffff00ff;
+                       pDevice->SavedCacheLineReg |= 0x4000;
+               }
+       }
+       /* Change driver parameters. */
+       Status = MM_GetConfig (pDevice);
+       if (Status != LM_STATUS_SUCCESS) {
+               return Status;
+       }
+#if INCLUDE_5701_AX_FIX
+       if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+           pDevice->ChipRevId == T3_CHIP_ID_5701_B0) {
+               pDevice->ResetPhyOnInit = TRUE;
+       }
+#endif
+
+       /* Save the current phy link status. */
+       if (!pDevice->EnableTbi) {
+               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
+               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
+
+               /* If we don't have link reset the PHY. */
+               if (!(Value32 & PHY_STATUS_LINK_PASS)
+                   || pDevice->ResetPhyOnInit) {
+
+                       LM_WritePhy (pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
+
+                       for (j = 0; j < 100; j++) {
+                               MM_Wait (10);
+
+                               LM_ReadPhy (pDevice, PHY_CTRL_REG, &Value32);
+                               if (Value32 && !(Value32 & PHY_CTRL_PHY_RESET)) {
+                                       MM_Wait (40);
+                                       break;
+                               }
+                       }
+
+#if INCLUDE_5701_AX_FIX
+                       /* 5701_AX_BX bug:  only advertises 10mb speed. */
+                       if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+                           pDevice->ChipRevId == T3_CHIP_ID_5701_B0) {
+
+                               Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
+                                   PHY_AN_AD_10BASET_HALF |
+                                   PHY_AN_AD_10BASET_FULL |
+                                   PHY_AN_AD_100BASETX_FULL |
+                                   PHY_AN_AD_100BASETX_HALF;
+                               Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
+                               LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
+                               pDevice->advertising = Value32;
+
+                               Value32 = BCM540X_AN_AD_1000BASET_HALF |
+                                   BCM540X_AN_AD_1000BASET_FULL |
+                                   BCM540X_CONFIG_AS_MASTER |
+                                   BCM540X_ENABLE_CONFIG_AS_MASTER;
+                               LM_WritePhy (pDevice,
+                                            BCM540X_1000BASET_CTRL_REG,
+                                            Value32);
+                               pDevice->advertising1000 = Value32;
+
+                               LM_WritePhy (pDevice, PHY_CTRL_REG,
+                                            PHY_CTRL_AUTO_NEG_ENABLE |
+                                            PHY_CTRL_RESTART_AUTO_NEG);
+                       }
+#endif
+                       if (T3_ASIC_REV (pDevice->ChipRevId) ==
+                           T3_ASIC_REV_5703) {
+                               LM_WritePhy (pDevice, 0x18, 0x0c00);
+                               LM_WritePhy (pDevice, 0x17, 0x201f);
+                               LM_WritePhy (pDevice, 0x15, 0x2aaa);
+                       }
+                       if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
+                               LM_WritePhy (pDevice, 0x1c, 0x8d68);
+                               LM_WritePhy (pDevice, 0x1c, 0x8d68);
+                       }
+                       /* Enable Ethernet@WireSpeed. */
+                       if (pDevice->EnableWireSpeed) {
+                               LM_WritePhy (pDevice, 0x18, 0x7007);
+                               LM_ReadPhy (pDevice, 0x18, &Value32);
+                               LM_WritePhy (pDevice, 0x18,
+                                            Value32 | BIT_15 | BIT_4);
+                       }
+               }
+       }
+
+       /* Turn off tap power management. */
+       if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID) {
+               LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x0c20);
+               LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
+               LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x1804);
+               LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
+               LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x1204);
+               LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
+               LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0132);
+               LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
+               LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0232);
+               LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
+               LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
+
+               MM_Wait (40);
+       }
+#if INCLUDE_TBI_SUPPORT
+       pDevice->IgnoreTbiLinkChange = FALSE;
+
+       if (pDevice->EnableTbi) {
+               pDevice->WakeUpModeCap = LM_WAKE_UP_MODE_NONE;
+               pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
+               if ((pDevice->PollTbiLink == BAD_DEFAULT_VALUE) ||
+                   pDevice->DisableAutoNeg) {
+                       pDevice->PollTbiLink = FALSE;
+               }
+       } else {
+               pDevice->PollTbiLink = FALSE;
+       }
+#endif                         /* INCLUDE_TBI_SUPPORT */
+
+       /* UseTaggedStatus is only valid for 5701 and later. */
+       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
+               pDevice->UseTaggedStatus = FALSE;
+
+               pDevice->CoalesceMode = 0;
+       } else {
+               pDevice->CoalesceMode =
+                   HOST_COALESCE_CLEAR_TICKS_ON_RX_BD_EVENT |
+                   HOST_COALESCE_CLEAR_TICKS_ON_TX_BD_EVENT;
+       }
+
+       /* Set the status block size. */
+       if (T3_CHIP_REV (pDevice->ChipRevId) != T3_CHIP_REV_5700_AX &&
+           T3_CHIP_REV (pDevice->ChipRevId) != T3_CHIP_REV_5700_BX) {
+               pDevice->CoalesceMode |= HOST_COALESCE_32_BYTE_STATUS_MODE;
+       }
+
+       /* Check the DURING_INT coalescing ticks parameters. */
+       if (pDevice->UseTaggedStatus) {
+               if (pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE) {
+                       pDevice->RxCoalescingTicksDuringInt =
+                           DEFAULT_RX_COALESCING_TICKS_DURING_INT;
+               }
+
+               if (pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE) {
+                       pDevice->TxCoalescingTicksDuringInt =
+                           DEFAULT_TX_COALESCING_TICKS_DURING_INT;
+               }
+
+               if (pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE) {
+                       pDevice->RxMaxCoalescedFramesDuringInt =
+                           DEFAULT_RX_MAX_COALESCED_FRAMES_DURING_INT;
+               }
+
+               if (pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE) {
+                       pDevice->TxMaxCoalescedFramesDuringInt =
+                           DEFAULT_TX_MAX_COALESCED_FRAMES_DURING_INT;
+               }
+       } else {
+               if (pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE) {
+                       pDevice->RxCoalescingTicksDuringInt = 0;
+               }
+
+               if (pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE) {
+                       pDevice->TxCoalescingTicksDuringInt = 0;
+               }
+
+               if (pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE) {
+                       pDevice->RxMaxCoalescedFramesDuringInt = 0;
+               }
+
+               if (pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE) {
+                       pDevice->TxMaxCoalescedFramesDuringInt = 0;
+               }
+       }
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+       if (pDevice->RxMtu <= (MAX_STD_RCV_BUFFER_SIZE - 8 /* CRC */ )) {
+               pDevice->RxJumboDescCnt = 0;
+               if (pDevice->RxMtu <= MAX_ETHERNET_PACKET_SIZE_NO_CRC) {
+                       pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
+               }
+       } else {
+               pDevice->RxJumboBufferSize =
+                   (pDevice->RxMtu + 8 /* CRC + VLAN */  +
+                    COMMON_CACHE_LINE_SIZE - 1) & ~COMMON_CACHE_LINE_MASK;
+
+               if (pDevice->RxJumboBufferSize > MAX_JUMBO_RCV_BUFFER_SIZE) {
+                       pDevice->RxJumboBufferSize =
+                           DEFAULT_JUMBO_RCV_BUFFER_SIZE;
+                       pDevice->RxMtu =
+                           pDevice->RxJumboBufferSize - 8 /* CRC + VLAN */ ;
+               }
+               pDevice->TxMtu = pDevice->RxMtu;
+
+       }
+#else
+       pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
+#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+       pDevice->RxPacketDescCnt =
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+           pDevice->RxJumboDescCnt +
+#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+           pDevice->RxStdDescCnt;
+
+       if (pDevice->TxMtu < MAX_ETHERNET_PACKET_SIZE_NO_CRC) {
+               pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
+       }
+
+       if (pDevice->TxMtu > MAX_JUMBO_TX_BUFFER_SIZE) {
+               pDevice->TxMtu = MAX_JUMBO_TX_BUFFER_SIZE;
+       }
+
+       /* Configure the proper ways to get link change interrupt. */
+       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO) {
+               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
+                       pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
+               } else {
+                       pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
+               }
+       } else if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
+               /* Auto-polling does not work on 5700_AX and 5700_BX. */
+               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
+                       pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
+               }
+       }
+
+       /* Determine the method to get link change status. */
+       if (pDevice->LinkChngMode == T3_LINK_CHNG_MODE_AUTO) {
+               /* The link status bit in the status block does not work on 5700_AX */
+               /* and 5700_BX chips. */
+               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
+                       pDevice->LinkChngMode =
+                           T3_LINK_CHNG_MODE_USE_STATUS_REG;
+               } else {
+                       pDevice->LinkChngMode =
+                           T3_LINK_CHNG_MODE_USE_STATUS_BLOCK;
+               }
+       }
+
+       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT ||
+           T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
+               pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
+       }
+
+       /* Configure PHY led mode. */
+       if (pDevice->LedMode == LED_MODE_AUTO) {
+               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
+                       if (pDevice->SubsystemVendorId == T3_SVID_DELL) {
+                               pDevice->LedMode = LED_MODE_LINK10;
+                       } else {
+                               pDevice->LedMode = LED_MODE_THREE_LINK;
+
+                               if (EeSigFound && EePhyLedMode != LED_MODE_AUTO) {
+                                       pDevice->LedMode = EePhyLedMode;
+                               }
+                       }
+
+                       /* bug? 5701 in LINK10 mode does not seem to work when */
+                       /* PhyIntMode is LINK_READY. */
+                       if (T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5700
+                           &&
+#if INCLUDE_TBI_SUPPORT
+                           pDevice->EnableTbi == FALSE &&
+#endif
+                           pDevice->LedMode == LED_MODE_LINK10) {
+                               pDevice->PhyIntMode =
+                                   T3_PHY_INT_MODE_MI_INTERRUPT;
+                               pDevice->LinkChngMode =
+                                   T3_LINK_CHNG_MODE_USE_STATUS_REG;
+                       }
+
+                       if (pDevice->EnableTbi) {
+                               pDevice->LedMode = LED_MODE_THREE_LINK;
+                       }
+               } else {
+                       if (EeSigFound && EePhyLedMode != LED_MODE_AUTO) {
+                               pDevice->LedMode = EePhyLedMode;
+                       } else {
+                               pDevice->LedMode = LED_MODE_OPEN_DRAIN;
+                       }
+               }
+       }
+
+       /* Enable OneDmaAtOnce. */
+       if (pDevice->OneDmaAtOnce == BAD_DEFAULT_VALUE) {
+               pDevice->OneDmaAtOnce = FALSE;
+       }
+
+       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+           pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+           pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
+           pDevice->ChipRevId == T3_CHIP_ID_5701_B2) {
+               pDevice->WolSpeed = WOL_SPEED_10MB;
+       } else {
+               pDevice->WolSpeed = WOL_SPEED_100MB;
+       }
+
+       /* Offloadings. */
+       pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;
+
+       /* Turn off task offloading on Ax. */
+       if (pDevice->ChipRevId == T3_CHIP_ID_5700_B0) {
+               pDevice->TaskOffloadCap &= ~(LM_TASK_OFFLOAD_TX_TCP_CHECKSUM |
+                                            LM_TASK_OFFLOAD_TX_UDP_CHECKSUM);
+       }
+       pDevice->PciState = REG_RD (pDevice, PciCfg.PciState);
+       LM_ReadVPD (pDevice);
+       LM_ReadBootCodeVersion (pDevice);
+       LM_GetBusSpeed (pDevice);
+
+       return LM_STATUS_SUCCESS;
+}                              /* LM_GetAdapterInfo */
+
+STATIC PLM_ADAPTER_INFO LM_GetAdapterInfoBySsid (LM_UINT16 Svid, LM_UINT16 Ssid)
+{
+       static LM_ADAPTER_INFO AdapterArr[] = {
+               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A6,
+                PHY_BCM5401_PHY_ID, 0},
+               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A5,
+                PHY_BCM5701_PHY_ID, 0},
+               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700T6,
+                PHY_BCM8002_PHY_ID, 1},
+               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A9, 0, 1},
+               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T1,
+                PHY_BCM5701_PHY_ID, 0},
+               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T8,
+                PHY_BCM5701_PHY_ID, 0},
+               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A7, 0, 1},
+               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A10,
+                PHY_BCM5701_PHY_ID, 0},
+               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A12,
+                PHY_BCM5701_PHY_ID, 0},
+               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax1,
+                PHY_BCM5701_PHY_ID, 0},
+               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax2,
+                PHY_BCM5701_PHY_ID, 0},
+
+               {T3_SVID_3COM, T3_SSID_3COM_3C996T, PHY_BCM5401_PHY_ID, 0},
+               {T3_SVID_3COM, T3_SSID_3COM_3C996BT, PHY_BCM5701_PHY_ID, 0},
+               {T3_SVID_3COM, T3_SSID_3COM_3C996SX, 0, 1},
+               {T3_SVID_3COM, T3_SSID_3COM_3C1000T, PHY_BCM5701_PHY_ID, 0},
+               {T3_SVID_3COM, T3_SSID_3COM_3C940BR01, PHY_BCM5701_PHY_ID, 0},
+
+               {T3_SVID_DELL, T3_SSID_DELL_VIPER, PHY_BCM5401_PHY_ID, 0},
+               {T3_SVID_DELL, T3_SSID_DELL_JAGUAR, PHY_BCM5401_PHY_ID, 0},
+               {T3_SVID_DELL, T3_SSID_DELL_MERLOT, PHY_BCM5411_PHY_ID, 0},
+               {T3_SVID_DELL, T3_SSID_DELL_SLIM_MERLOT, PHY_BCM5411_PHY_ID, 0},
+
+               {T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE, PHY_BCM5701_PHY_ID, 0},
+               {T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE_2, PHY_BCM5701_PHY_ID,
+                0},
+               {T3_SVID_COMPAQ, T3_SSID_COMPAQ_CHANGELING, 0, 1},
+               {T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780, PHY_BCM5701_PHY_ID, 0},
+               {T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780_2, PHY_BCM5701_PHY_ID,
+                0},
+
+       };
+       LM_UINT32 j;
+
+       for (j = 0; j < sizeof (AdapterArr) / sizeof (LM_ADAPTER_INFO); j++) {
+               if (AdapterArr[j].Svid == Svid && AdapterArr[j].Ssid == Ssid) {
+                       return &AdapterArr[j];
+               }
+       }
+
+       return NULL;
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This routine sets up receive/transmit buffer descriptions queues.       */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS LM_InitializeAdapter (PLM_DEVICE_BLOCK pDevice)
+{
+       LM_PHYSICAL_ADDRESS MemPhy;
+       PLM_UINT8 pMemVirt;
+       PLM_PACKET pPacket;
+       LM_STATUS Status;
+       LM_UINT32 Size;
+       LM_UINT32 j;
+
+       /* Set power state to D0. */
+       LM_SetPowerState (pDevice, LM_POWER_STATE_D0);
+
+       /* Intialize the queues. */
+       QQ_InitQueue (&pDevice->RxPacketReceivedQ.Container,
+                     MAX_RX_PACKET_DESC_COUNT);
+       QQ_InitQueue (&pDevice->RxPacketFreeQ.Container,
+                     MAX_RX_PACKET_DESC_COUNT);
+
+       QQ_InitQueue (&pDevice->TxPacketFreeQ.Container,
+                     MAX_TX_PACKET_DESC_COUNT);
+       QQ_InitQueue (&pDevice->TxPacketActiveQ.Container,
+                     MAX_TX_PACKET_DESC_COUNT);
+       QQ_InitQueue (&pDevice->TxPacketXmittedQ.Container,
+                     MAX_TX_PACKET_DESC_COUNT);
+
+       /* Allocate shared memory for: status block, the buffers for receive */
+       /* rings -- standard, mini, jumbo, and return rings. */
+       Size = T3_STATUS_BLOCK_SIZE + sizeof (T3_STATS_BLOCK) +
+           T3_STD_RCV_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD) +
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+           T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD) +
+#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+           T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD);
+
+       /* Memory for host based Send BD. */
+       if (pDevice->NicSendBd == FALSE) {
+               Size += sizeof (T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
+       }
+
+       /* Allocate the memory block. */
+       Status =
+           MM_AllocateSharedMemory (pDevice, Size, (PLM_VOID) & pMemVirt,
+                                    &MemPhy, FALSE);
+       if (Status != LM_STATUS_SUCCESS) {
+               return Status;
+       }
+
+       /* Program DMA Read/Write */
+       if (pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS) {
+               pDevice->DmaReadWriteCtrl = 0x763f000f;
+       } else {
+               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5704) {
+                       pDevice->DmaReadWriteCtrl = 0x761f0000;
+               } else {
+                       pDevice->DmaReadWriteCtrl = 0x761b000f;
+               }
+               if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1 ||
+                   pDevice->ChipRevId == T3_CHIP_ID_5703_A2) {
+                       pDevice->OneDmaAtOnce = TRUE;
+               }
+       }
+       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5703) {
+               pDevice->DmaReadWriteCtrl &= 0xfffffff0;
+       }
+
+       if (pDevice->OneDmaAtOnce) {
+               pDevice->DmaReadWriteCtrl |= DMA_CTRL_WRITE_ONE_DMA_AT_ONCE;
+       }
+       REG_WR (pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
+
+       if (LM_DmaTest (pDevice, pMemVirt, MemPhy, 0x400) != LM_STATUS_SUCCESS) {
+               return LM_STATUS_FAILURE;
+       }
+
+       /* Status block. */
+       pDevice->pStatusBlkVirt = (PT3_STATUS_BLOCK) pMemVirt;
+       pDevice->StatusBlkPhy = MemPhy;
+       pMemVirt += T3_STATUS_BLOCK_SIZE;
+       LM_INC_PHYSICAL_ADDRESS (&MemPhy, T3_STATUS_BLOCK_SIZE);
+
+       /* Statistics block. */
+       pDevice->pStatsBlkVirt = (PT3_STATS_BLOCK) pMemVirt;
+       pDevice->StatsBlkPhy = MemPhy;
+       pMemVirt += sizeof (T3_STATS_BLOCK);
+       LM_INC_PHYSICAL_ADDRESS (&MemPhy, sizeof (T3_STATS_BLOCK));
+
+       /* Receive standard BD buffer. */
+       pDevice->pRxStdBdVirt = (PT3_RCV_BD) pMemVirt;
+       pDevice->RxStdBdPhy = MemPhy;
+
+       pMemVirt += T3_STD_RCV_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD);
+       LM_INC_PHYSICAL_ADDRESS (&MemPhy,
+                                T3_STD_RCV_RCB_ENTRY_COUNT *
+                                sizeof (T3_RCV_BD));
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+       /* Receive jumbo BD buffer. */
+       pDevice->pRxJumboBdVirt = (PT3_RCV_BD) pMemVirt;
+       pDevice->RxJumboBdPhy = MemPhy;
+
+       pMemVirt += T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD);
+       LM_INC_PHYSICAL_ADDRESS (&MemPhy,
+                                T3_JUMBO_RCV_RCB_ENTRY_COUNT *
+                                sizeof (T3_RCV_BD));
+#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+       /* Receive return BD buffer. */
+       pDevice->pRcvRetBdVirt = (PT3_RCV_BD) pMemVirt;
+       pDevice->RcvRetBdPhy = MemPhy;
+
+       pMemVirt += T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD);
+       LM_INC_PHYSICAL_ADDRESS (&MemPhy,
+                                T3_RCV_RETURN_RCB_ENTRY_COUNT *
+                                sizeof (T3_RCV_BD));
+
+       /* Set up Send BD. */
+       if (pDevice->NicSendBd == FALSE) {
+               pDevice->pSendBdVirt = (PT3_SND_BD) pMemVirt;
+               pDevice->SendBdPhy = MemPhy;
+
+               pMemVirt += sizeof (T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
+               LM_INC_PHYSICAL_ADDRESS (&MemPhy,
+                                        sizeof (T3_SND_BD) *
+                                        T3_SEND_RCB_ENTRY_COUNT);
+       } else {
+               pDevice->pSendBdVirt = (PT3_SND_BD)
+                   pDevice->pMemView->uIntMem.First32k.BufferDesc;
+               pDevice->SendBdPhy.High = 0;
+               pDevice->SendBdPhy.Low = T3_NIC_SND_BUFFER_DESC_ADDR;
+       }
+
+       /* Allocate memory for packet descriptors. */
+       Size = (pDevice->RxPacketDescCnt +
+               pDevice->TxPacketDescCnt) * MM_PACKET_DESC_SIZE;
+       Status = MM_AllocateMemory (pDevice, Size, (PLM_VOID *) & pPacket);
+       if (Status != LM_STATUS_SUCCESS) {
+               return Status;
+       }
+       pDevice->pPacketDescBase = (PLM_VOID) pPacket;
+
+       /* Create transmit packet descriptors from the memory block and add them */
+       /* to the TxPacketFreeQ for each send ring. */
+       for (j = 0; j < pDevice->TxPacketDescCnt; j++) {
+               /* Ring index. */
+               pPacket->Flags = 0;
+
+               /* Queue the descriptor in the TxPacketFreeQ of the 'k' ring. */
+               QQ_PushTail (&pDevice->TxPacketFreeQ.Container, pPacket);
+
+               /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
+               /* is the total size of the packet descriptor including the */
+               /* os-specific extensions in the UM_PACKET structure. */
+               pPacket =
+                   (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
+       }                       /* for(j.. */
+
+       /* Create receive packet descriptors from the memory block and add them */
+       /* to the RxPacketFreeQ.  Create the Standard packet descriptors. */
+       for (j = 0; j < pDevice->RxStdDescCnt; j++) {
+               /* Receive producer ring. */
+               pPacket->u.Rx.RcvProdRing = T3_STD_RCV_PROD_RING;
+
+               /* Receive buffer size. */
+               pPacket->u.Rx.RxBufferSize = MAX_STD_RCV_BUFFER_SIZE;
+
+               /* Add the descriptor to RxPacketFreeQ. */
+               QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
+
+               /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
+               /* is the total size of the packet descriptor including the */
+               /* os-specific extensions in the UM_PACKET structure. */
+               pPacket =
+                   (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
+       }                       /* for */
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+       /* Create the Jumbo packet descriptors. */
+       for (j = 0; j < pDevice->RxJumboDescCnt; j++) {
+               /* Receive producer ring. */
+               pPacket->u.Rx.RcvProdRing = T3_JUMBO_RCV_PROD_RING;
+
+               /* Receive buffer size. */
+               pPacket->u.Rx.RxBufferSize = pDevice->RxJumboBufferSize;
+
+               /* Add the descriptor to RxPacketFreeQ. */
+               QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
+
+               /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
+               /* is the total size of the packet descriptor including the */
+               /* os-specific extensions in the UM_PACKET structure. */
+               pPacket =
+                   (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
+       }                       /* for */
+#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+       /* Initialize the rest of the packet descriptors. */
+       Status = MM_InitializeUmPackets (pDevice);
+       if (Status != LM_STATUS_SUCCESS) {
+               return Status;
+       }
+
+       /* if */
+       /* Default receive mask. */
+       pDevice->ReceiveMask = LM_ACCEPT_MULTICAST | LM_ACCEPT_BROADCAST |
+           LM_ACCEPT_UNICAST;
+
+       /* Make sure we are in the first 32k memory window or NicSendBd. */
+       REG_WR (pDevice, PciCfg.MemWindowBaseAddr, 0);
+
+       /* Initialize the hardware. */
+       Status = LM_ResetAdapter (pDevice);
+       if (Status != LM_STATUS_SUCCESS) {
+               return Status;
+       }
+
+       /* We are done with initialization. */
+       pDevice->InitDone = TRUE;
+
+       return LM_STATUS_SUCCESS;
+}                              /* LM_InitializeAdapter */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This function Enables/Disables a given block.                          */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS
+LM_CntrlBlock (PLM_DEVICE_BLOCK pDevice, LM_UINT32 mask, LM_UINT32 cntrl)
+{
+       LM_UINT32 j, i, data;
+       LM_UINT32 MaxWaitCnt;
+
+       MaxWaitCnt = 2;
+       j = 0;
+
+       for (i = 0; i < 32; i++) {
+               if (!(mask & (1 << i)))
+                       continue;
+
+               switch (1 << i) {
+               case T3_BLOCK_DMA_RD:
+                       data = REG_RD (pDevice, DmaRead.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~DMA_READ_MODE_ENABLE;
+                               REG_WR (pDevice, DmaRead.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, DmaRead.Mode) &
+                                            DMA_READ_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, DmaRead.Mode,
+                                       data | DMA_READ_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_DMA_COMP:
+                       data = REG_RD (pDevice, DmaComp.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~DMA_COMP_MODE_ENABLE;
+                               REG_WR (pDevice, DmaComp.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, DmaComp.Mode) &
+                                            DMA_COMP_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, DmaComp.Mode,
+                                       data | DMA_COMP_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_RX_BD_INITIATOR:
+                       data = REG_RD (pDevice, RcvBdIn.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~RCV_BD_IN_MODE_ENABLE;
+                               REG_WR (pDevice, RcvBdIn.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, RcvBdIn.Mode) &
+                                            RCV_BD_IN_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, RcvBdIn.Mode,
+                                       data | RCV_BD_IN_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_RX_BD_COMP:
+                       data = REG_RD (pDevice, RcvBdComp.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~RCV_BD_COMP_MODE_ENABLE;
+                               REG_WR (pDevice, RcvBdComp.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, RcvBdComp.Mode) &
+                                            RCV_BD_COMP_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, RcvBdComp.Mode,
+                                       data | RCV_BD_COMP_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_DMA_WR:
+                       data = REG_RD (pDevice, DmaWrite.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~DMA_WRITE_MODE_ENABLE;
+                               REG_WR (pDevice, DmaWrite.Mode, data);
+
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, DmaWrite.Mode) &
+                                            DMA_WRITE_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, DmaWrite.Mode,
+                                       data | DMA_WRITE_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_MSI_HANDLER:
+                       data = REG_RD (pDevice, Msi.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~MSI_MODE_ENABLE;
+                               REG_WR (pDevice, Msi.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, Msi.Mode) &
+                                            MSI_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, Msi.Mode,
+                                       data | MSI_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_RX_LIST_PLMT:
+                       data = REG_RD (pDevice, RcvListPlmt.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~RCV_LIST_PLMT_MODE_ENABLE;
+                               REG_WR (pDevice, RcvListPlmt.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, RcvListPlmt.Mode)
+                                            & RCV_LIST_PLMT_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, RcvListPlmt.Mode,
+                                       data | RCV_LIST_PLMT_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_RX_LIST_SELECTOR:
+                       data = REG_RD (pDevice, RcvListSel.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~RCV_LIST_SEL_MODE_ENABLE;
+                               REG_WR (pDevice, RcvListSel.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, RcvListSel.Mode) &
+                                            RCV_LIST_SEL_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, RcvListSel.Mode,
+                                       data | RCV_LIST_SEL_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_RX_DATA_INITIATOR:
+                       data = REG_RD (pDevice, RcvDataBdIn.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~RCV_DATA_BD_IN_MODE_ENABLE;
+                               REG_WR (pDevice, RcvDataBdIn.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, RcvDataBdIn.Mode)
+                                            & RCV_DATA_BD_IN_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, RcvDataBdIn.Mode,
+                                       data | RCV_DATA_BD_IN_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_RX_DATA_COMP:
+                       data = REG_RD (pDevice, RcvDataComp.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~RCV_DATA_COMP_MODE_ENABLE;
+                               REG_WR (pDevice, RcvDataComp.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, RcvDataBdIn.Mode)
+                                            & RCV_DATA_COMP_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, RcvDataComp.Mode,
+                                       data | RCV_DATA_COMP_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_HOST_COALESING:
+                       data = REG_RD (pDevice, HostCoalesce.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~HOST_COALESCE_ENABLE;
+                               REG_WR (pDevice, HostCoalesce.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, SndBdIn.Mode) &
+                                            HOST_COALESCE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, HostCoalesce.Mode,
+                                       data | HOST_COALESCE_ENABLE);
+                       break;
+
+               case T3_BLOCK_MAC_RX_ENGINE:
+                       if (cntrl == LM_DISABLE) {
+                               pDevice->RxMode &= ~RX_MODE_ENABLE;
+                               REG_WR (pDevice, MacCtrl.RxMode,
+                                       pDevice->RxMode);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, MacCtrl.RxMode) &
+                                            RX_MODE_ENABLE)) {
+                                               break;
+                                       }
+                                       MM_Wait (10);
+                               }
+                       } else {
+                               pDevice->RxMode |= RX_MODE_ENABLE;
+                               REG_WR (pDevice, MacCtrl.RxMode,
+                                       pDevice->RxMode);
+                       }
+                       break;
+
+               case T3_BLOCK_MBUF_CLUSTER_FREE:
+                       data = REG_RD (pDevice, MbufClusterFree.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~MBUF_CLUSTER_FREE_MODE_ENABLE;
+                               REG_WR (pDevice, MbufClusterFree.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD
+                                            (pDevice,
+                                             MbufClusterFree.
+                                             Mode) &
+                                            MBUF_CLUSTER_FREE_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, MbufClusterFree.Mode,
+                                       data | MBUF_CLUSTER_FREE_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_SEND_BD_INITIATOR:
+                       data = REG_RD (pDevice, SndBdIn.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~SND_BD_IN_MODE_ENABLE;
+                               REG_WR (pDevice, SndBdIn.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, SndBdIn.Mode) &
+                                            SND_BD_IN_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, SndBdIn.Mode,
+                                       data | SND_BD_IN_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_SEND_BD_COMP:
+                       data = REG_RD (pDevice, SndBdComp.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~SND_BD_COMP_MODE_ENABLE;
+                               REG_WR (pDevice, SndBdComp.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, SndBdComp.Mode) &
+                                            SND_BD_COMP_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, SndBdComp.Mode,
+                                       data | SND_BD_COMP_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_SEND_BD_SELECTOR:
+                       data = REG_RD (pDevice, SndBdSel.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~SND_BD_SEL_MODE_ENABLE;
+                               REG_WR (pDevice, SndBdSel.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, SndBdSel.Mode) &
+                                            SND_BD_SEL_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, SndBdSel.Mode,
+                                       data | SND_BD_SEL_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_SEND_DATA_INITIATOR:
+                       data = REG_RD (pDevice, SndDataIn.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~T3_SND_DATA_IN_MODE_ENABLE;
+                               REG_WR (pDevice, SndDataIn.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, SndDataIn.Mode) &
+                                            T3_SND_DATA_IN_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, SndDataIn.Mode,
+                                       data | T3_SND_DATA_IN_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_SEND_DATA_COMP:
+                       data = REG_RD (pDevice, SndDataComp.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~SND_DATA_COMP_MODE_ENABLE;
+                               REG_WR (pDevice, SndDataComp.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, SndDataComp.Mode)
+                                            & SND_DATA_COMP_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, SndDataComp.Mode,
+                                       data | SND_DATA_COMP_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_MAC_TX_ENGINE:
+                       if (cntrl == LM_DISABLE) {
+                               pDevice->TxMode &= ~TX_MODE_ENABLE;
+                               REG_WR (pDevice, MacCtrl.TxMode,
+                                       pDevice->TxMode);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, MacCtrl.TxMode) &
+                                            TX_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else {
+                               pDevice->TxMode |= TX_MODE_ENABLE;
+                               REG_WR (pDevice, MacCtrl.TxMode,
+                                       pDevice->TxMode);
+                       }
+                       break;
+
+               case T3_BLOCK_MEM_ARBITOR:
+                       data = REG_RD (pDevice, MemArbiter.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~T3_MEM_ARBITER_MODE_ENABLE;
+                               REG_WR (pDevice, MemArbiter.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, MemArbiter.Mode) &
+                                            T3_MEM_ARBITER_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, MemArbiter.Mode,
+                                       data | T3_MEM_ARBITER_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_MBUF_MANAGER:
+                       data = REG_RD (pDevice, BufMgr.Mode);
+                       if (cntrl == LM_DISABLE) {
+                               data &= ~BUFMGR_MODE_ENABLE;
+                               REG_WR (pDevice, BufMgr.Mode, data);
+                               for (j = 0; j < MaxWaitCnt; j++) {
+                                       if (!
+                                           (REG_RD (pDevice, BufMgr.Mode) &
+                                            BUFMGR_MODE_ENABLE))
+                                               break;
+                                       MM_Wait (10);
+                               }
+                       } else
+                               REG_WR (pDevice, BufMgr.Mode,
+                                       data | BUFMGR_MODE_ENABLE);
+                       break;
+
+               case T3_BLOCK_MAC_GLOBAL:
+                       if (cntrl == LM_DISABLE) {
+                               pDevice->MacMode &= ~(MAC_MODE_ENABLE_TDE |
+                                                     MAC_MODE_ENABLE_RDE |
+                                                     MAC_MODE_ENABLE_FHDE);
+                       } else {
+                               pDevice->MacMode |= (MAC_MODE_ENABLE_TDE |
+                                                    MAC_MODE_ENABLE_RDE |
+                                                    MAC_MODE_ENABLE_FHDE);
+                       }
+                       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
+                       break;
+
+               default:
+                       return LM_STATUS_FAILURE;
+               }               /* switch */
+
+               if (j >= MaxWaitCnt) {
+                       return LM_STATUS_FAILURE;
+               }
+       }
+
+       return LM_STATUS_SUCCESS;
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This function reinitializes the adapter.                                */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS LM_ResetAdapter (PLM_DEVICE_BLOCK pDevice)
+{
+       LM_UINT32 Value32;
+       LM_UINT16 Value16;
+       LM_UINT32 j, k;
+
+       /* Disable interrupt. */
+       LM_DisableInterrupt (pDevice);
+
+       /* May get a spurious interrupt */
+       pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED;
+
+       /* Disable transmit and receive DMA engines.  Abort all pending requests. */
+       if (pDevice->InitDone) {
+               LM_Abort (pDevice);
+       }
+
+       pDevice->ShuttingDown = FALSE;
+
+       LM_ResetChip (pDevice);
+
+       /* Bug: Athlon fix for B3 silicon only.  This bit does not do anything */
+       /* in other chip revisions. */
+       if (pDevice->DelayPciGrant) {
+               Value32 = REG_RD (pDevice, PciCfg.ClockCtrl);
+               REG_WR (pDevice, PciCfg.ClockCtrl, Value32 | BIT_31);
+       }
+
+       if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
+               if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)) {
+                       Value32 = REG_RD (pDevice, PciCfg.PciState);
+                       Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
+                       REG_WR (pDevice, PciCfg.PciState, Value32);
+               }
+       }
+
+       /* Enable TaggedStatus mode. */
+       if (pDevice->UseTaggedStatus) {
+               pDevice->MiscHostCtrl |=
+                   MISC_HOST_CTRL_ENABLE_TAGGED_STATUS_MODE;
+       }
+
+       /* Restore PCI configuration registers. */
+       MM_WriteConfig32 (pDevice, PCI_CACHE_LINE_SIZE_REG,
+                         pDevice->SavedCacheLineReg);
+       MM_WriteConfig32 (pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
+                         (pDevice->SubsystemId << 16) | pDevice->
+                         SubsystemVendorId);
+
+       /* Clear the statistics block. */
+       for (j = 0x0300; j < 0x0b00; j++) {
+               MEM_WR_OFFSET (pDevice, j, 0);
+       }
+
+       /* Initialize the statistis Block */
+       pDevice->pStatusBlkVirt->Status = 0;
+       pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
+       pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
+       pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
+
+       for (j = 0; j < 16; j++) {
+               pDevice->pStatusBlkVirt->Idx[j].RcvProdIdx = 0;
+               pDevice->pStatusBlkVirt->Idx[j].SendConIdx = 0;
+       }
+
+       for (k = 0; k < T3_STD_RCV_RCB_ENTRY_COUNT; k++) {
+               pDevice->pRxStdBdVirt[k].HostAddr.High = 0;
+               pDevice->pRxStdBdVirt[k].HostAddr.Low = 0;
+       }
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+       /* Receive jumbo BD buffer. */
+       for (k = 0; k < T3_JUMBO_RCV_RCB_ENTRY_COUNT; k++) {
+               pDevice->pRxJumboBdVirt[k].HostAddr.High = 0;
+               pDevice->pRxJumboBdVirt[k].HostAddr.Low = 0;
+       }
+#endif
+
+       REG_WR (pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
+
+       /* GRC mode control register. */
+#ifdef BIG_ENDIAN_PCI          /* Jimmy, this ifdef block deleted in new code! */
+       Value32 =
+           GRC_MODE_WORD_SWAP_DATA |
+           GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
+           GRC_MODE_INT_ON_MAC_ATTN | GRC_MODE_HOST_STACK_UP;
+#else
+       /* No CPU Swap modes for PCI IO */
+       Value32 =
+#ifdef BIG_ENDIAN_HOST
+           GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
+           GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
+           GRC_MODE_BYTE_SWAP_DATA | GRC_MODE_WORD_SWAP_DATA |
+#else
+           GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
+           GRC_MODE_BYTE_SWAP_DATA | GRC_MODE_WORD_SWAP_DATA |
+#endif
+           GRC_MODE_INT_ON_MAC_ATTN | GRC_MODE_HOST_STACK_UP;
+#endif                         /* !BIG_ENDIAN_PCI */
+
+       /* Configure send BD mode. */
+       if (pDevice->NicSendBd == FALSE) {
+               Value32 |= GRC_MODE_HOST_SEND_BDS;
+       } else {
+               Value32 |= GRC_MODE_4X_NIC_BASED_SEND_RINGS;
+       }
+
+       /* Configure pseudo checksum mode. */
+       if (pDevice->NoTxPseudoHdrChksum) {
+               Value32 |= GRC_MODE_TX_NO_PSEUDO_HEADER_CHKSUM;
+       }
+
+       if (pDevice->NoRxPseudoHdrChksum) {
+               Value32 |= GRC_MODE_RX_NO_PSEUDO_HEADER_CHKSUM;
+       }
+
+       REG_WR (pDevice, Grc.Mode, Value32);
+
+       /* Setup the timer prescalar register. */
+       REG_WR (pDevice, Grc.MiscCfg, 65 << 1); /* Clock is alwasy 66Mhz. */
+
+       /* Set up the MBUF pool base address and size. */
+       REG_WR (pDevice, BufMgr.MbufPoolAddr, pDevice->MbufBase);
+       REG_WR (pDevice, BufMgr.MbufPoolSize, pDevice->MbufSize);
+
+       /* Set up the DMA descriptor pool base address and size. */
+       REG_WR (pDevice, BufMgr.DmaDescPoolAddr, T3_NIC_DMA_DESC_POOL_ADDR);
+       REG_WR (pDevice, BufMgr.DmaDescPoolSize, T3_NIC_DMA_DESC_POOL_SIZE);
+
+       /* Configure MBUF and Threshold watermarks */
+       /* Configure the DMA read MBUF low water mark. */
+       if (pDevice->DmaMbufLowMark) {
+               REG_WR (pDevice, BufMgr.MbufReadDmaLowWaterMark,
+                       pDevice->DmaMbufLowMark);
+       } else {
+               if (pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE) {
+                       REG_WR (pDevice, BufMgr.MbufReadDmaLowWaterMark,
+                               T3_DEF_DMA_MBUF_LOW_WMARK);
+               } else {
+                       REG_WR (pDevice, BufMgr.MbufReadDmaLowWaterMark,
+                               T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO);
+               }
+       }
+
+       /* Configure the MAC Rx MBUF low water mark. */
+       if (pDevice->RxMacMbufLowMark) {
+               REG_WR (pDevice, BufMgr.MbufMacRxLowWaterMark,
+                       pDevice->RxMacMbufLowMark);
+       } else {
+               if (pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE) {
+                       REG_WR (pDevice, BufMgr.MbufMacRxLowWaterMark,
+                               T3_DEF_RX_MAC_MBUF_LOW_WMARK);
+               } else {
+                       REG_WR (pDevice, BufMgr.MbufMacRxLowWaterMark,
+                               T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO);
+               }
+       }
+
+       /* Configure the MBUF high water mark. */
+       if (pDevice->MbufHighMark) {
+               REG_WR (pDevice, BufMgr.MbufHighWaterMark,
+                       pDevice->MbufHighMark);
+       } else {
+               if (pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE) {
+                       REG_WR (pDevice, BufMgr.MbufHighWaterMark,
+                               T3_DEF_MBUF_HIGH_WMARK);
+               } else {
+                       REG_WR (pDevice, BufMgr.MbufHighWaterMark,
+                               T3_DEF_MBUF_HIGH_WMARK_JUMBO);
+               }
+       }
+
+       REG_WR (pDevice, BufMgr.DmaLowWaterMark, T3_DEF_DMA_DESC_LOW_WMARK);
+       REG_WR (pDevice, BufMgr.DmaHighWaterMark, T3_DEF_DMA_DESC_HIGH_WMARK);
+
+       /* Enable buffer manager. */
+       REG_WR (pDevice, BufMgr.Mode,
+               BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE);
+
+       for (j = 0; j < 2000; j++) {
+               if (REG_RD (pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE)
+                       break;
+               MM_Wait (10);
+       }
+
+       if (j >= 2000) {
+               return LM_STATUS_FAILURE;
+       }
+
+       /* Enable the FTQs. */
+       REG_WR (pDevice, Ftq.Reset, 0xffffffff);
+       REG_WR (pDevice, Ftq.Reset, 0);
+
+       /* Wait until FTQ is ready */
+       for (j = 0; j < 2000; j++) {
+               if (REG_RD (pDevice, Ftq.Reset) == 0)
+                       break;
+               MM_Wait (10);
+       }
+
+       if (j >= 2000) {
+               return LM_STATUS_FAILURE;
+       }
+
+       /* Initialize the Standard Receive RCB. */
+       REG_WR (pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.High,
+               pDevice->RxStdBdPhy.High);
+       REG_WR (pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.Low,
+               pDevice->RxStdBdPhy.Low);
+       REG_WR (pDevice, RcvDataBdIn.StdRcvRcb.u.MaxLen_Flags,
+               MAX_STD_RCV_BUFFER_SIZE << 16);
+
+       /* Initialize the Jumbo Receive RCB. */
+       REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags,
+               T3_RCB_FLAG_RING_DISABLED);
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+       REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.High,
+               pDevice->RxJumboBdPhy.High);
+       REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.Low,
+               pDevice->RxJumboBdPhy.Low);
+
+       REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags, 0);
+
+#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+       /* Initialize the Mini Receive RCB. */
+       REG_WR (pDevice, RcvDataBdIn.MiniRcvRcb.u.MaxLen_Flags,
+               T3_RCB_FLAG_RING_DISABLED);
+
+       {
+               REG_WR (pDevice, RcvDataBdIn.StdRcvRcb.NicRingAddr,
+                       (LM_UINT32) T3_NIC_STD_RCV_BUFFER_DESC_ADDR);
+               REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.NicRingAddr,
+                       (LM_UINT32) T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR);
+       }
+
+       /* Receive BD Ring replenish threshold. */
+       REG_WR (pDevice, RcvBdIn.StdRcvThreshold, pDevice->RxStdDescCnt / 8);
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+       REG_WR (pDevice, RcvBdIn.JumboRcvThreshold,
+               pDevice->RxJumboDescCnt / 8);
+#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+       /* Disable all the unused rings. */
+       for (j = 0; j < T3_MAX_SEND_RCB_COUNT; j++) {
+               MEM_WR (pDevice, SendRcb[j].u.MaxLen_Flags,
+                       T3_RCB_FLAG_RING_DISABLED);
+       }                       /* for */
+
+       /* Initialize the indices. */
+       pDevice->SendProdIdx = 0;
+       pDevice->SendConIdx = 0;
+
+       MB_REG_WR (pDevice, Mailbox.SendHostProdIdx[0].Low, 0);
+       MB_REG_WR (pDevice, Mailbox.SendNicProdIdx[0].Low, 0);
+
+       /* Set up host or NIC based send RCB. */
+       if (pDevice->NicSendBd == FALSE) {
+               MEM_WR (pDevice, SendRcb[0].HostRingAddr.High,
+                       pDevice->SendBdPhy.High);
+               MEM_WR (pDevice, SendRcb[0].HostRingAddr.Low,
+                       pDevice->SendBdPhy.Low);
+
+               /* Set up the NIC ring address in the RCB. */
+               MEM_WR (pDevice, SendRcb[0].NicRingAddr,
+                       T3_NIC_SND_BUFFER_DESC_ADDR);
+
+               /* Setup the RCB. */
+               MEM_WR (pDevice, SendRcb[0].u.MaxLen_Flags,
+                       T3_SEND_RCB_ENTRY_COUNT << 16);
+
+               for (k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++) {
+                       pDevice->pSendBdVirt[k].HostAddr.High = 0;
+                       pDevice->pSendBdVirt[k].HostAddr.Low = 0;
+               }
+       } else {
+               MEM_WR (pDevice, SendRcb[0].HostRingAddr.High, 0);
+               MEM_WR (pDevice, SendRcb[0].HostRingAddr.Low, 0);
+               MEM_WR (pDevice, SendRcb[0].NicRingAddr,
+                       pDevice->SendBdPhy.Low);
+
+               for (k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++) {
+                       __raw_writel (0,
+                                     &(pDevice->pSendBdVirt[k].HostAddr.High));
+                       __raw_writel (0,
+                                     &(pDevice->pSendBdVirt[k].HostAddr.Low));
+                       __raw_writel (0,
+                                     &(pDevice->pSendBdVirt[k].u1.Len_Flags));
+                       pDevice->ShadowSendBd[k].HostAddr.High = 0;
+                       pDevice->ShadowSendBd[k].u1.Len_Flags = 0;
+               }
+       }
+       atomic_set (&pDevice->SendBdLeft, T3_SEND_RCB_ENTRY_COUNT - 1);
+
+       /* Configure the receive return rings. */
+       for (j = 0; j < T3_MAX_RCV_RETURN_RCB_COUNT; j++) {
+               MEM_WR (pDevice, RcvRetRcb[j].u.MaxLen_Flags,
+                       T3_RCB_FLAG_RING_DISABLED);
+       }
+
+       pDevice->RcvRetConIdx = 0;
+
+       MEM_WR (pDevice, RcvRetRcb[0].HostRingAddr.High,
+               pDevice->RcvRetBdPhy.High);
+       MEM_WR (pDevice, RcvRetRcb[0].HostRingAddr.Low,
+               pDevice->RcvRetBdPhy.Low);
+
+       /* Set up the NIC ring address in the RCB. */
+       /* Not very clear from the spec.  I am guessing that for Receive */
+       /* Return Ring, NicRingAddr is not used. */
+       MEM_WR (pDevice, RcvRetRcb[0].NicRingAddr, 0);
+
+       /* Setup the RCB. */
+       MEM_WR (pDevice, RcvRetRcb[0].u.MaxLen_Flags,
+               T3_RCV_RETURN_RCB_ENTRY_COUNT << 16);
+
+       /* Reinitialize RX ring producer index */
+       MB_REG_WR (pDevice, Mailbox.RcvStdProdIdx.Low, 0);
+       MB_REG_WR (pDevice, Mailbox.RcvJumboProdIdx.Low, 0);
+       MB_REG_WR (pDevice, Mailbox.RcvMiniProdIdx.Low, 0);
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+       pDevice->RxJumboProdIdx = 0;
+       pDevice->RxJumboQueuedCnt = 0;
+#endif
+
+       /* Reinitialize our copy of the indices. */
+       pDevice->RxStdProdIdx = 0;
+       pDevice->RxStdQueuedCnt = 0;
+
+#if T3_JUMBO_RCV_ENTRY_COUNT
+       pDevice->RxJumboProdIdx = 0;
+#endif                         /* T3_JUMBO_RCV_ENTRY_COUNT */
+
+       /* Configure the MAC address. */
+       LM_SetMacAddress (pDevice, pDevice->NodeAddress);
+
+       /* Initialize the transmit random backoff seed. */
+       Value32 = (pDevice->NodeAddress[0] + pDevice->NodeAddress[1] +
+                  pDevice->NodeAddress[2] + pDevice->NodeAddress[3] +
+                  pDevice->NodeAddress[4] + pDevice->NodeAddress[5]) &
+           MAC_TX_BACKOFF_SEED_MASK;
+       REG_WR (pDevice, MacCtrl.TxBackoffSeed, Value32);
+
+       /* Receive MTU.  Frames larger than the MTU is marked as oversized. */
+       REG_WR (pDevice, MacCtrl.MtuSize, pDevice->RxMtu + 8);  /* CRC + VLAN. */
+
+       /* Configure Time slot/IPG per 802.3 */
+       REG_WR (pDevice, MacCtrl.TxLengths, 0x2620);
+
+       /*
+        * Configure Receive Rules so that packets don't match
+        * Programmble rule will be queued to Return Ring 1
+        */
+       REG_WR (pDevice, MacCtrl.RcvRuleCfg, RX_RULE_DEFAULT_CLASS);
+
+       /*
+        * Configure to have 16 Classes of Services (COS) and one
+        * queue per class.  Bad frames are queued to RRR#1.
+        * And frames don't match rules are also queued to COS#1.
+        */
+       REG_WR (pDevice, RcvListPlmt.Config, 0x181);
+
+       /* Enable Receive Placement Statistics */
+       REG_WR (pDevice, RcvListPlmt.StatsEnableMask, 0xffffff);
+       REG_WR (pDevice, RcvListPlmt.StatsCtrl, RCV_LIST_STATS_ENABLE);
+
+       /* Enable Send Data Initator Statistics */
+       REG_WR (pDevice, SndDataIn.StatsEnableMask, 0xffffff);
+       REG_WR (pDevice, SndDataIn.StatsCtrl,
+               T3_SND_DATA_IN_STATS_CTRL_ENABLE |
+               T3_SND_DATA_IN_STATS_CTRL_FASTER_UPDATE);
+
+       /* Disable the host coalescing state machine before configuring it's */
+       /* parameters. */
+       REG_WR (pDevice, HostCoalesce.Mode, 0);
+       for (j = 0; j < 2000; j++) {
+               Value32 = REG_RD (pDevice, HostCoalesce.Mode);
+               if (!(Value32 & HOST_COALESCE_ENABLE)) {
+                       break;
+               }
+               MM_Wait (10);
+       }
+
+       /* Host coalescing configurations. */
+       REG_WR (pDevice, HostCoalesce.RxCoalescingTicks,
+               pDevice->RxCoalescingTicks);
+       REG_WR (pDevice, HostCoalesce.TxCoalescingTicks,
+               pDevice->TxCoalescingTicks);
+       REG_WR (pDevice, HostCoalesce.RxMaxCoalescedFrames,
+               pDevice->RxMaxCoalescedFrames);
+       REG_WR (pDevice, HostCoalesce.TxMaxCoalescedFrames,
+               pDevice->TxMaxCoalescedFrames);
+       REG_WR (pDevice, HostCoalesce.RxCoalescedTickDuringInt,
+               pDevice->RxCoalescingTicksDuringInt);
+       REG_WR (pDevice, HostCoalesce.TxCoalescedTickDuringInt,
+               pDevice->TxCoalescingTicksDuringInt);
+       REG_WR (pDevice, HostCoalesce.RxMaxCoalescedFramesDuringInt,
+               pDevice->RxMaxCoalescedFramesDuringInt);
+       REG_WR (pDevice, HostCoalesce.TxMaxCoalescedFramesDuringInt,
+               pDevice->TxMaxCoalescedFramesDuringInt);
+
+       /* Initialize the address of the status block.  The NIC will DMA */
+       /* the status block to this memory which resides on the host. */
+       REG_WR (pDevice, HostCoalesce.StatusBlkHostAddr.High,
+               pDevice->StatusBlkPhy.High);
+       REG_WR (pDevice, HostCoalesce.StatusBlkHostAddr.Low,
+               pDevice->StatusBlkPhy.Low);
+
+       /* Initialize the address of the statistics block.  The NIC will DMA */
+       /* the statistics to this block of memory. */
+       REG_WR (pDevice, HostCoalesce.StatsBlkHostAddr.High,
+               pDevice->StatsBlkPhy.High);
+       REG_WR (pDevice, HostCoalesce.StatsBlkHostAddr.Low,
+               pDevice->StatsBlkPhy.Low);
+
+       REG_WR (pDevice, HostCoalesce.StatsCoalescingTicks,
+               pDevice->StatsCoalescingTicks);
+
+       REG_WR (pDevice, HostCoalesce.StatsBlkNicAddr, 0x300);
+       REG_WR (pDevice, HostCoalesce.StatusBlkNicAddr, 0xb00);
+
+       /* Enable Host Coalesing state machine */
+       REG_WR (pDevice, HostCoalesce.Mode, HOST_COALESCE_ENABLE |
+               pDevice->CoalesceMode);
+
+       /* Enable the Receive BD Completion state machine. */
+       REG_WR (pDevice, RcvBdComp.Mode, RCV_BD_COMP_MODE_ENABLE |
+               RCV_BD_COMP_MODE_ATTN_ENABLE);
+
+       /* Enable the Receive List Placement state machine. */
+       REG_WR (pDevice, RcvListPlmt.Mode, RCV_LIST_PLMT_MODE_ENABLE);
+
+       /* Enable the Receive List Selector state machine. */
+       REG_WR (pDevice, RcvListSel.Mode, RCV_LIST_SEL_MODE_ENABLE |
+               RCV_LIST_SEL_MODE_ATTN_ENABLE);
+
+       /* Enable transmit DMA, clear statistics. */
+       pDevice->MacMode = MAC_MODE_ENABLE_TX_STATISTICS |
+           MAC_MODE_ENABLE_RX_STATISTICS | MAC_MODE_ENABLE_TDE |
+           MAC_MODE_ENABLE_RDE | MAC_MODE_ENABLE_FHDE;
+       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode |
+               MAC_MODE_CLEAR_RX_STATISTICS | MAC_MODE_CLEAR_TX_STATISTICS);
+
+       /* GRC miscellaneous local control register. */
+       pDevice->GrcLocalCtrl = GRC_MISC_LOCAL_CTRL_INT_ON_ATTN |
+           GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM;
+
+       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
+               pDevice->GrcLocalCtrl |= GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
+                   GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1;
+       }
+
+       REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
+       MM_Wait (40);
+
+       /* Reset RX counters. */
+       for (j = 0; j < sizeof (LM_RX_COUNTERS); j++) {
+               ((PLM_UINT8) & pDevice->RxCounters)[j] = 0;
+       }
+
+       /* Reset TX counters. */
+       for (j = 0; j < sizeof (LM_TX_COUNTERS); j++) {
+               ((PLM_UINT8) & pDevice->TxCounters)[j] = 0;
+       }
+
+       MB_REG_WR (pDevice, Mailbox.Interrupt[0].Low, 0);
+
+       /* Enable the DMA Completion state machine. */
+       REG_WR (pDevice, DmaComp.Mode, DMA_COMP_MODE_ENABLE);
+
+       /* Enable the DMA Write state machine. */
+       Value32 = DMA_WRITE_MODE_ENABLE |
+           DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE |
+           DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE |
+           DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE |
+           DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
+           DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE |
+           DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
+           DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE |
+           DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE;
+       REG_WR (pDevice, DmaWrite.Mode, Value32);
+
+       if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)) {
+               if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
+                       Value16 = REG_RD (pDevice, PciCfg.PciXCommand);
+                       Value16 &=
+                           ~(PCIX_CMD_MAX_SPLIT_MASK |
+                             PCIX_CMD_MAX_BURST_MASK);
+                       Value16 |=
+                           ((PCIX_CMD_MAX_BURST_CPIOB <<
+                             PCIX_CMD_MAX_BURST_SHL) &
+                            PCIX_CMD_MAX_BURST_MASK);
+                       if (pDevice->SplitModeEnable == SPLIT_MODE_ENABLE) {
+                               Value16 |=
+                                   (pDevice->
+                                    SplitModeMaxReq << PCIX_CMD_MAX_SPLIT_SHL)
+                                   & PCIX_CMD_MAX_SPLIT_MASK;
+                       }
+                       REG_WR (pDevice, PciCfg.PciXCommand, Value16);
+               }
+       }
+
+       /* Enable the Read DMA state machine. */
+       Value32 = DMA_READ_MODE_ENABLE |
+           DMA_READ_MODE_TARGET_ABORT_ATTN_ENABLE |
+           DMA_READ_MODE_MASTER_ABORT_ATTN_ENABLE |
+           DMA_READ_MODE_PARITY_ERROR_ATTN_ENABLE |
+           DMA_READ_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
+           DMA_READ_MODE_FIFO_OVERRUN_ATTN_ENABLE |
+           DMA_READ_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
+           DMA_READ_MODE_FIFO_OVERREAD_ATTN_ENABLE |
+           DMA_READ_MODE_LONG_READ_ATTN_ENABLE;
+
+       if (pDevice->SplitModeEnable == SPLIT_MODE_ENABLE) {
+               Value32 |= DMA_READ_MODE_SPLIT_ENABLE;
+       }
+       REG_WR (pDevice, DmaRead.Mode, Value32);
+
+       /* Enable the Receive Data Completion state machine. */
+       REG_WR (pDevice, RcvDataComp.Mode, RCV_DATA_COMP_MODE_ENABLE |
+               RCV_DATA_COMP_MODE_ATTN_ENABLE);
+
+       /* Enable the Mbuf Cluster Free state machine. */
+       REG_WR (pDevice, MbufClusterFree.Mode, MBUF_CLUSTER_FREE_MODE_ENABLE);
+
+       /* Enable the Send Data Completion state machine. */
+       REG_WR (pDevice, SndDataComp.Mode, SND_DATA_COMP_MODE_ENABLE);
+
+       /* Enable the Send BD Completion state machine. */
+       REG_WR (pDevice, SndBdComp.Mode, SND_BD_COMP_MODE_ENABLE |
+               SND_BD_COMP_MODE_ATTN_ENABLE);
+
+       /* Enable the Receive BD Initiator state machine. */
+       REG_WR (pDevice, RcvBdIn.Mode, RCV_BD_IN_MODE_ENABLE |
+               RCV_BD_IN_MODE_BD_IN_DIABLED_RCB_ATTN_ENABLE);
+
+       /* Enable the Receive Data and Receive BD Initiator state machine. */
+       REG_WR (pDevice, RcvDataBdIn.Mode, RCV_DATA_BD_IN_MODE_ENABLE |
+               RCV_DATA_BD_IN_MODE_INVALID_RING_SIZE);
+
+       /* Enable the Send Data Initiator state machine. */
+       REG_WR (pDevice, SndDataIn.Mode, T3_SND_DATA_IN_MODE_ENABLE);
+
+       /* Enable the Send BD Initiator state machine. */
+       REG_WR (pDevice, SndBdIn.Mode, SND_BD_IN_MODE_ENABLE |
+               SND_BD_IN_MODE_ATTN_ENABLE);
+
+       /* Enable the Send BD Selector state machine. */
+       REG_WR (pDevice, SndBdSel.Mode, SND_BD_SEL_MODE_ENABLE |
+               SND_BD_SEL_MODE_ATTN_ENABLE);
+
+#if INCLUDE_5701_AX_FIX
+       /* Load the firmware for the 5701_A0 workaround. */
+       if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0) {
+               LM_LoadRlsFirmware (pDevice);
+       }
+#endif
+
+       /* Enable the transmitter. */
+       pDevice->TxMode = TX_MODE_ENABLE;
+       REG_WR (pDevice, MacCtrl.TxMode, pDevice->TxMode);
+
+       /* Enable the receiver. */
+       pDevice->RxMode = RX_MODE_ENABLE;
+       REG_WR (pDevice, MacCtrl.RxMode, pDevice->RxMode);
+
+       if (pDevice->RestoreOnWakeUp) {
+               pDevice->RestoreOnWakeUp = FALSE;
+               pDevice->DisableAutoNeg = pDevice->WakeUpDisableAutoNeg;
+               pDevice->RequestedMediaType = pDevice->WakeUpRequestedMediaType;
+       }
+
+       /* Disable auto polling. */
+       pDevice->MiMode = 0xc0000;
+       REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
+
+       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+           T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
+               Value32 = LED_CTRL_PHY_MODE_1;
+       } else {
+               if (pDevice->LedMode == LED_MODE_OUTPUT) {
+                       Value32 = LED_CTRL_PHY_MODE_2;
+               } else {
+                       Value32 = LED_CTRL_PHY_MODE_1;
+               }
+       }
+       REG_WR (pDevice, MacCtrl.LedCtrl, Value32);
+
+       /* Activate Link to enable MAC state machine */
+       REG_WR (pDevice, MacCtrl.MiStatus, MI_STATUS_ENABLE_LINK_STATUS_ATTN);
+
+       if (pDevice->EnableTbi) {
+               REG_WR (pDevice, MacCtrl.RxMode, RX_MODE_RESET);
+               MM_Wait (10);
+               REG_WR (pDevice, MacCtrl.RxMode, pDevice->RxMode);
+               if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1) {
+                       REG_WR (pDevice, MacCtrl.SerdesCfg, 0x616000);
+               }
+       }
+       /* Setup the phy chip. */
+       LM_SetupPhy (pDevice);
+
+       if (!pDevice->EnableTbi) {
+               /* Clear CRC stats */
+               LM_ReadPhy (pDevice, 0x1e, &Value32);
+               LM_WritePhy (pDevice, 0x1e, Value32 | 0x8000);
+               LM_ReadPhy (pDevice, 0x14, &Value32);
+       }
+
+       /* Set up the receive mask. */
+       LM_SetReceiveMask (pDevice, pDevice->ReceiveMask);
+
+       /* Queue Rx packet buffers. */
+       if (pDevice->QueueRxPackets) {
+               LM_QueueRxPackets (pDevice);
+       }
+
+       /* Enable interrupt to the host. */
+       if (pDevice->InitDone) {
+               LM_EnableInterrupt (pDevice);
+       }
+
+       return LM_STATUS_SUCCESS;
+}                              /* LM_ResetAdapter */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This routine disables the adapter from generating interrupts.           */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS LM_DisableInterrupt (PLM_DEVICE_BLOCK pDevice)
+{
+       REG_WR (pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl |
+               MISC_HOST_CTRL_MASK_PCI_INT);
+       MB_REG_WR (pDevice, Mailbox.Interrupt[0].Low, 1);
+
+       return LM_STATUS_SUCCESS;
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This routine enables the adapter to generate interrupts.                */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS LM_EnableInterrupt (PLM_DEVICE_BLOCK pDevice)
+{
+       REG_WR (pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl &
+               ~MISC_HOST_CTRL_MASK_PCI_INT);
+       MB_REG_WR (pDevice, Mailbox.Interrupt[0].Low, 0);
+
+       if (pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_UPDATED) {
+               REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
+                       GRC_MISC_LOCAL_CTRL_SET_INT);
+       }
+
+       return LM_STATUS_SUCCESS;
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This routine puts a packet on the wire if there is a transmit DMA       */
+/*    descriptor available; otherwise the packet is queued for later          */
+/*    transmission.  If the second argue is NULL, this routine will put       */
+/*    the queued packet on the wire if possible.                              */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+#if 0
+LM_STATUS LM_SendPacket (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
+{
+       LM_UINT32 FragCount;
+       PT3_SND_BD pSendBd;
+       PT3_SND_BD pShadowSendBd;
+       LM_UINT32 Value32, Len;
+       LM_UINT32 Idx;
+
+       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
+               return LM_5700SendPacket (pDevice, pPacket);
+       }
+
+       /* Update the SendBdLeft count. */
+       atomic_sub (pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
+
+       /* Initalize the send buffer descriptors. */
+       Idx = pDevice->SendProdIdx;
+
+       pSendBd = &pDevice->pSendBdVirt[Idx];
+
+       /* Next producer index. */
+       if (pDevice->NicSendBd == TRUE) {
+               T3_64BIT_HOST_ADDR paddr;
+
+               pShadowSendBd = &pDevice->ShadowSendBd[Idx];
+               for (FragCount = 0;;) {
+                       MM_MapTxDma (pDevice, pPacket, &paddr, &Len, FragCount);
+                       /* Initialize the pointer to the send buffer fragment. */
+                       if (paddr.High != pShadowSendBd->HostAddr.High) {
+                               __raw_writel (paddr.High,
+                                             &(pSendBd->HostAddr.High));
+                               pShadowSendBd->HostAddr.High = paddr.High;
+                       }
+                       __raw_writel (paddr.Low, &(pSendBd->HostAddr.Low));
+
+                       /* Setup the control flags and send buffer size. */
+                       Value32 = (Len << 16) | pPacket->Flags;
+
+                       Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
+
+                       FragCount++;
+                       if (FragCount >= pPacket->u.Tx.FragCount) {
+                               Value32 |= SND_BD_FLAG_END;
+                               if (Value32 != pShadowSendBd->u1.Len_Flags) {
+                                       __raw_writel (Value32,
+                                                     &(pSendBd->u1.Len_Flags));
+                                       pShadowSendBd->u1.Len_Flags = Value32;
+                               }
+                               if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
+                                       __raw_writel (pPacket->VlanTag,
+                                                     &(pSendBd->u2.VlanTag));
+                               }
+                               break;
+                       } else {
+                               if (Value32 != pShadowSendBd->u1.Len_Flags) {
+                                       __raw_writel (Value32,
+                                                     &(pSendBd->u1.Len_Flags));
+                                       pShadowSendBd->u1.Len_Flags = Value32;
+                               }
+                               if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
+                                       __raw_writel (pPacket->VlanTag,
+                                                     &(pSendBd->u2.VlanTag));
+                               }
+                       }
+
+                       pSendBd++;
+                       pShadowSendBd++;
+                       if (Idx == 0) {
+                               pSendBd = &pDevice->pSendBdVirt[0];
+                               pShadowSendBd = &pDevice->ShadowSendBd[0];
+                       }
+               }               /* for */
+
+               /* Put the packet descriptor in the ActiveQ. */
+               QQ_PushTail (&pDevice->TxPacketActiveQ.Container, pPacket);
+
+               wmb ();
+               MB_REG_WR (pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
+
+       } else {
+               for (FragCount = 0;;) {
+                       /* Initialize the pointer to the send buffer fragment. */
+                       MM_MapTxDma (pDevice, pPacket, &pSendBd->HostAddr, &Len,
+                                    FragCount);
+
+                       pSendBd->u2.VlanTag = pPacket->VlanTag;
+
+                       /* Setup the control flags and send buffer size. */
+                       Value32 = (Len << 16) | pPacket->Flags;
+
+                       Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
+
+                       FragCount++;
+                       if (FragCount >= pPacket->u.Tx.FragCount) {
+                               pSendBd->u1.Len_Flags =
+                                   Value32 | SND_BD_FLAG_END;
+                               break;
+                       } else {
+                               pSendBd->u1.Len_Flags = Value32;
+                       }
+                       pSendBd++;
+                       if (Idx == 0) {
+                               pSendBd = &pDevice->pSendBdVirt[0];
+                       }
+               }               /* for */
+
+               /* Put the packet descriptor in the ActiveQ. */
+               QQ_PushTail (&pDevice->TxPacketActiveQ.Container, pPacket);
+
+               wmb ();
+               MB_REG_WR (pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
+
+       }
+
+       /* Update the producer index. */
+       pDevice->SendProdIdx = Idx;
+
+       return LM_STATUS_SUCCESS;
+}
+#endif
+
+LM_STATUS LM_SendPacket (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
+{
+       LM_UINT32 FragCount;
+       PT3_SND_BD pSendBd, pTmpSendBd, pShadowSendBd;
+       T3_SND_BD NicSendBdArr[MAX_FRAGMENT_COUNT];
+       LM_UINT32 StartIdx, Idx;
+
+       while (1) {
+               /* Initalize the send buffer descriptors. */
+               StartIdx = Idx = pDevice->SendProdIdx;
+
+               if (pDevice->NicSendBd) {
+                       pTmpSendBd = pSendBd = &NicSendBdArr[0];
+               } else {
+                       pTmpSendBd = pSendBd = &pDevice->pSendBdVirt[Idx];
+               }
+
+               /* Next producer index. */
+               for (FragCount = 0;;) {
+                       LM_UINT32 Value32, Len;
+
+                       /* Initialize the pointer to the send buffer fragment. */
+                       MM_MapTxDma (pDevice, pPacket, &pSendBd->HostAddr, &Len,
+                                    FragCount);
+
+                       pSendBd->u2.VlanTag = pPacket->VlanTag;
+
+                       /* Setup the control flags and send buffer size. */
+                       Value32 = (Len << 16) | pPacket->Flags;
+
+                       Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
+
+                       FragCount++;
+                       if (FragCount >= pPacket->u.Tx.FragCount) {
+                               pSendBd->u1.Len_Flags =
+                                   Value32 | SND_BD_FLAG_END;
+                               break;
+                       } else {
+                               pSendBd->u1.Len_Flags = Value32;
+                       }
+                       pSendBd++;
+                       if ((Idx == 0) && !pDevice->NicSendBd) {
+                               pSendBd = &pDevice->pSendBdVirt[0];
+                       }
+               }               /* for */
+               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
+                       if (LM_Test4GBoundary (pDevice, pPacket, pTmpSendBd) ==
+                           LM_STATUS_SUCCESS) {
+                               if (MM_CoalesceTxBuffer (pDevice, pPacket) !=
+                                   LM_STATUS_SUCCESS) {
+                                       QQ_PushHead (&pDevice->TxPacketFreeQ.
+                                                    Container, pPacket);
+                                       return LM_STATUS_FAILURE;
+                               }
+                               continue;
+                       }
+               }
+               break;
+       }
+       /* Put the packet descriptor in the ActiveQ. */
+       QQ_PushTail (&pDevice->TxPacketActiveQ.Container, pPacket);
+
+       if (pDevice->NicSendBd) {
+               pSendBd = &pDevice->pSendBdVirt[StartIdx];
+               pShadowSendBd = &pDevice->ShadowSendBd[StartIdx];
+
+               while (StartIdx != Idx) {
+                       LM_UINT32 Value32;
+
+                       if ((Value32 = pTmpSendBd->HostAddr.High) !=
+                           pShadowSendBd->HostAddr.High) {
+                               __raw_writel (Value32,
+                                             &(pSendBd->HostAddr.High));
+                               pShadowSendBd->HostAddr.High = Value32;
+                       }
+
+                       __raw_writel (pTmpSendBd->HostAddr.Low,
+                                     &(pSendBd->HostAddr.Low));
+
+                       if ((Value32 = pTmpSendBd->u1.Len_Flags) !=
+                           pShadowSendBd->u1.Len_Flags) {
+                               __raw_writel (Value32,
+                                             &(pSendBd->u1.Len_Flags));
+                               pShadowSendBd->u1.Len_Flags = Value32;
+                       }
+
+                       if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
+                               __raw_writel (pTmpSendBd->u2.VlanTag,
+                                             &(pSendBd->u2.VlanTag));
+                       }
+
+                       StartIdx =
+                           (StartIdx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
+                       if (StartIdx == 0)
+                               pSendBd = &pDevice->pSendBdVirt[0];
+                       else
+                               pSendBd++;
+                       pTmpSendBd++;
+               }
+               wmb ();
+               MB_REG_WR (pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
+
+               if (T3_CHIP_REV (pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) {
+                       MB_REG_WR (pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
+               }
+       } else {
+               wmb ();
+               MB_REG_WR (pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
+
+               if (T3_CHIP_REV (pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) {
+                       MB_REG_WR (pDevice, Mailbox.SendHostProdIdx[0].Low,
+                                  Idx);
+               }
+       }
+
+       /* Update the SendBdLeft count. */
+       atomic_sub (pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
+
+       /* Update the producer index. */
+       pDevice->SendProdIdx = Idx;
+
+       return LM_STATUS_SUCCESS;
+}
+
+STATIC LM_STATUS
+LM_Test4GBoundary (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
+                  PT3_SND_BD pSendBd)
+{
+       int FragCount;
+       LM_UINT32 Idx, Base, Len;
+
+       Idx = pDevice->SendProdIdx;
+       for (FragCount = 0;;) {
+               Len = pSendBd->u1.Len_Flags >> 16;
+               if (((Base = pSendBd->HostAddr.Low) > 0xffffdcc0) &&
+                   (pSendBd->HostAddr.High == 0) &&
+                   ((Base + 8 + Len) < Base)) {
+                       return LM_STATUS_SUCCESS;
+               }
+               FragCount++;
+               if (FragCount >= pPacket->u.Tx.FragCount) {
+                       break;
+               }
+               pSendBd++;
+               if (!pDevice->NicSendBd) {
+                       Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
+                       if (Idx == 0) {
+                               pSendBd = &pDevice->pSendBdVirt[0];
+                       }
+               }
+       }
+       return LM_STATUS_FAILURE;
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+__inline static unsigned long
+ComputeCrc32 (unsigned char *pBuffer, unsigned long BufferSize)
+{
+       unsigned long Reg;
+       unsigned long Tmp;
+       unsigned long j, k;
+
+       Reg = 0xffffffff;
+
+       for (j = 0; j < BufferSize; j++) {
+               Reg ^= pBuffer[j];
+
+               for (k = 0; k < 8; k++) {
+                       Tmp = Reg & 0x01;
+
+                       Reg >>= 1;
+
+                       if (Tmp) {
+                               Reg ^= 0xedb88320;
+                       }
+               }
+       }
+
+       return ~Reg;
+}                              /* ComputeCrc32 */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This routine sets the receive control register according to ReceiveMask */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS LM_SetReceiveMask (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Mask)
+{
+       LM_UINT32 ReceiveMask;
+       LM_UINT32 RxMode;
+       LM_UINT32 j, k;
+
+       ReceiveMask = Mask;
+
+       RxMode = pDevice->RxMode;
+
+       if (Mask & LM_ACCEPT_UNICAST) {
+               Mask &= ~LM_ACCEPT_UNICAST;
+       }
+
+       if (Mask & LM_ACCEPT_MULTICAST) {
+               Mask &= ~LM_ACCEPT_MULTICAST;
+       }
+
+       if (Mask & LM_ACCEPT_ALL_MULTICAST) {
+               Mask &= ~LM_ACCEPT_ALL_MULTICAST;
+       }
+
+       if (Mask & LM_ACCEPT_BROADCAST) {
+               Mask &= ~LM_ACCEPT_BROADCAST;
+       }
+
+       RxMode &= ~RX_MODE_PROMISCUOUS_MODE;
+       if (Mask & LM_PROMISCUOUS_MODE) {
+               RxMode |= RX_MODE_PROMISCUOUS_MODE;
+               Mask &= ~LM_PROMISCUOUS_MODE;
+       }
+
+       RxMode &= ~(RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED);
+       if (Mask & LM_ACCEPT_ERROR_PACKET) {
+               RxMode |= RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED;
+               Mask &= ~LM_ACCEPT_ERROR_PACKET;
+       }
+
+       /* Make sure all the bits are valid before committing changes. */
+       if (Mask) {
+               return LM_STATUS_FAILURE;
+       }
+
+       /* Commit the new filter. */
+       pDevice->RxMode = RxMode;
+       REG_WR (pDevice, MacCtrl.RxMode, RxMode);
+
+       pDevice->ReceiveMask = ReceiveMask;
+
+       /* Set up the MC hash table. */
+       if (ReceiveMask & LM_ACCEPT_ALL_MULTICAST) {
+               for (k = 0; k < 4; k++) {
+                       REG_WR (pDevice, MacCtrl.HashReg[k], 0xffffffff);
+               }
+       } else if (ReceiveMask & LM_ACCEPT_MULTICAST) {
+               LM_UINT32 HashReg[4];
+
+               HashReg[0] = 0;
+               HashReg[1] = 0;
+               HashReg[2] = 0;
+               HashReg[3] = 0;
+               for (j = 0; j < pDevice->McEntryCount; j++) {
+                       LM_UINT32 RegIndex;
+                       LM_UINT32 Bitpos;
+                       LM_UINT32 Crc32;
+
+                       Crc32 =
+                           ComputeCrc32 (pDevice->McTable[j],
+                                         ETHERNET_ADDRESS_SIZE);
+
+                       /* The most significant 7 bits of the CRC32 (no inversion), */
+                       /* are used to index into one of the possible 128 bit positions. */
+                       Bitpos = ~Crc32 & 0x7f;
+
+                       /* Hash register index. */
+                       RegIndex = (Bitpos & 0x60) >> 5;
+
+                       /* Bit to turn on within a hash register. */
+                       Bitpos &= 0x1f;
+
+                       /* Enable the multicast bit. */
+                       HashReg[RegIndex] |= (1 << Bitpos);
+               }
+
+               /* REV_AX has problem with multicast filtering where it uses both */
+               /* DA and SA to perform hashing. */
+               for (k = 0; k < 4; k++) {
+                       REG_WR (pDevice, MacCtrl.HashReg[k], HashReg[k]);
+               }
+       } else {
+               /* Reject all multicast frames. */
+               for (j = 0; j < 4; j++) {
+                       REG_WR (pDevice, MacCtrl.HashReg[j], 0);
+               }
+       }
+
+       /* By default, Tigon3 will accept broadcast frames.  We need to setup */
+       if (ReceiveMask & LM_ACCEPT_BROADCAST) {
+               REG_WR (pDevice,
+                       MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
+                       REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
+               REG_WR (pDevice,
+                       MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
+                       REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
+               REG_WR (pDevice,
+                       MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
+                       REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
+               REG_WR (pDevice,
+                       MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
+                       REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
+       } else {
+               REG_WR (pDevice,
+                       MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
+                       REJECT_BROADCAST_RULE1_RULE);
+               REG_WR (pDevice,
+                       MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
+                       REJECT_BROADCAST_RULE1_VALUE);
+               REG_WR (pDevice,
+                       MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
+                       REJECT_BROADCAST_RULE2_RULE);
+               REG_WR (pDevice,
+                       MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
+                       REJECT_BROADCAST_RULE2_VALUE);
+       }
+
+       /* disable the rest of the rules. */
+       for (j = RCV_LAST_RULE_IDX; j < 16; j++) {
+               REG_WR (pDevice, MacCtrl.RcvRules[j].Rule, 0);
+               REG_WR (pDevice, MacCtrl.RcvRules[j].Value, 0);
+       }
+
+       return LM_STATUS_SUCCESS;
+}                              /* LM_SetReceiveMask */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    Disable the interrupt and put the transmitter and receiver engines in   */
+/*    an idle state.  Also aborts all pending send requests and receive       */
+/*    buffers.                                                                */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS LM_Abort (PLM_DEVICE_BLOCK pDevice)
+{
+       PLM_PACKET pPacket;
+       LM_UINT Idx;
+
+       LM_DisableInterrupt (pDevice);
+
+       /* Disable all the state machines. */
+       LM_CntrlBlock (pDevice, T3_BLOCK_MAC_RX_ENGINE, LM_DISABLE);
+       LM_CntrlBlock (pDevice, T3_BLOCK_RX_BD_INITIATOR, LM_DISABLE);
+       LM_CntrlBlock (pDevice, T3_BLOCK_RX_LIST_PLMT, LM_DISABLE);
+       LM_CntrlBlock (pDevice, T3_BLOCK_RX_LIST_SELECTOR, LM_DISABLE);
+       LM_CntrlBlock (pDevice, T3_BLOCK_RX_DATA_INITIATOR, LM_DISABLE);
+       LM_CntrlBlock (pDevice, T3_BLOCK_RX_DATA_COMP, LM_DISABLE);
+       LM_CntrlBlock (pDevice, T3_BLOCK_RX_BD_COMP, LM_DISABLE);
+
+       LM_CntrlBlock (pDevice, T3_BLOCK_SEND_BD_SELECTOR, LM_DISABLE);
+       LM_CntrlBlock (pDevice, T3_BLOCK_SEND_BD_INITIATOR, LM_DISABLE);
+       LM_CntrlBlock (pDevice, T3_BLOCK_SEND_DATA_INITIATOR, LM_DISABLE);
+       LM_CntrlBlock (pDevice, T3_BLOCK_DMA_RD, LM_DISABLE);
+       LM_CntrlBlock (pDevice, T3_BLOCK_SEND_DATA_COMP, LM_DISABLE);
+       LM_CntrlBlock (pDevice, T3_BLOCK_DMA_COMP, LM_DISABLE);
+       LM_CntrlBlock (pDevice, T3_BLOCK_SEND_BD_COMP, LM_DISABLE);
+
+       /* Clear TDE bit */
+       pDevice->MacMode &= ~MAC_MODE_ENABLE_TDE;
+       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
+
+       LM_CntrlBlock (pDevice, T3_BLOCK_MAC_TX_ENGINE, LM_DISABLE);
+       LM_CntrlBlock (pDevice, T3_BLOCK_HOST_COALESING, LM_DISABLE);
+       LM_CntrlBlock (pDevice, T3_BLOCK_DMA_WR, LM_DISABLE);
+       LM_CntrlBlock (pDevice, T3_BLOCK_MBUF_CLUSTER_FREE, LM_DISABLE);
+
+       /* Reset all FTQs */
+       REG_WR (pDevice, Ftq.Reset, 0xffffffff);
+       REG_WR (pDevice, Ftq.Reset, 0x0);
+
+       LM_CntrlBlock (pDevice, T3_BLOCK_MBUF_MANAGER, LM_DISABLE);
+       LM_CntrlBlock (pDevice, T3_BLOCK_MEM_ARBITOR, LM_DISABLE);
+
+       MM_ACQUIRE_INT_LOCK (pDevice);
+
+       /* Abort packets that have already queued to go out. */
+       pPacket = (PLM_PACKET) QQ_PopHead (&pDevice->TxPacketActiveQ.Container);
+       while (pPacket) {
+
+               pPacket->PacketStatus = LM_STATUS_TRANSMIT_ABORTED;
+               pDevice->TxCounters.TxPacketAbortedCnt++;
+
+               atomic_add (pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
+
+               QQ_PushTail (&pDevice->TxPacketXmittedQ.Container, pPacket);
+
+               pPacket = (PLM_PACKET)
+                   QQ_PopHead (&pDevice->TxPacketActiveQ.Container);
+       }
+
+       /* Cleanup the receive return rings. */
+       LM_ServiceRxInterrupt (pDevice);
+
+       /* Don't want to indicate rx packets in Ndis miniport shutdown context. */
+       /* Doing so may cause system crash. */
+       if (!pDevice->ShuttingDown) {
+               /* Indicate packets to the protocol. */
+               MM_IndicateTxPackets (pDevice);
+
+               /* Indicate received packets to the protocols. */
+               MM_IndicateRxPackets (pDevice);
+       } else {
+               /* Move the receive packet descriptors in the ReceivedQ to the */
+               /* free queue. */
+               for (;;) {
+                       pPacket =
+                           (PLM_PACKET) QQ_PopHead (&pDevice->
+                                                    RxPacketReceivedQ.
+                                                    Container);
+                       if (pPacket == NULL) {
+                               break;
+                       }
+                       QQ_PushTail (&pDevice->RxPacketFreeQ.Container,
+                                    pPacket);
+               }
+       }
+
+       /* Clean up the Std Receive Producer ring. */
+       Idx = pDevice->pStatusBlkVirt->RcvStdConIdx;
+
+       while (Idx != pDevice->RxStdProdIdx) {
+               pPacket = (PLM_PACKET) (MM_UINT_PTR (pDevice->pPacketDescBase) +
+                                       MM_UINT_PTR (pDevice->pRxStdBdVirt[Idx].
+                                                    Opaque));
+
+               QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
+
+               Idx = (Idx + 1) & T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
+       }                       /* while */
+
+       /* Reinitialize our copy of the indices. */
+       pDevice->RxStdProdIdx = 0;
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+       /* Clean up the Jumbo Receive Producer ring. */
+       Idx = pDevice->pStatusBlkVirt->RcvJumboConIdx;
+
+       while (Idx != pDevice->RxJumboProdIdx) {
+               pPacket = (PLM_PACKET) (MM_UINT_PTR (pDevice->pPacketDescBase) +
+                                       MM_UINT_PTR (pDevice->
+                                                    pRxJumboBdVirt[Idx].
+                                                    Opaque));
+
+               QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
+
+               Idx = (Idx + 1) & T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
+       }                       /* while */
+
+       /* Reinitialize our copy of the indices. */
+       pDevice->RxJumboProdIdx = 0;
+#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+       MM_RELEASE_INT_LOCK (pDevice);
+
+       /* Initialize the statistis Block */
+       pDevice->pStatusBlkVirt->Status = 0;
+       pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
+       pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
+       pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
+
+       return LM_STATUS_SUCCESS;
+}                              /* LM_Abort */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    Disable the interrupt and put the transmitter and receiver engines in   */
+/*    an idle state.  Aborts all pending send requests and receive buffers.   */
+/*    Also free all the receive buffers.                                      */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS LM_Halt (PLM_DEVICE_BLOCK pDevice)
+{
+       PLM_PACKET pPacket;
+       LM_UINT32 EntryCnt;
+
+       LM_Abort (pDevice);
+
+       /* Get the number of entries in the queue. */
+       EntryCnt = QQ_GetEntryCnt (&pDevice->RxPacketFreeQ.Container);
+
+       /* Make sure all the packets have been accounted for. */
+       for (EntryCnt = 0; EntryCnt < pDevice->RxPacketDescCnt; EntryCnt++) {
+               pPacket =
+                   (PLM_PACKET) QQ_PopHead (&pDevice->RxPacketFreeQ.Container);
+               if (pPacket == 0)
+                       break;
+
+               MM_FreeRxBuffer (pDevice, pPacket);
+
+               QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
+       }
+
+       LM_ResetChip (pDevice);
+
+       /* Restore PCI configuration registers. */
+       MM_WriteConfig32 (pDevice, PCI_CACHE_LINE_SIZE_REG,
+                         pDevice->SavedCacheLineReg);
+       LM_RegWrInd (pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
+                    (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
+
+       /* Reprogram the MAC address. */
+       LM_SetMacAddress (pDevice, pDevice->NodeAddress);
+
+       return LM_STATUS_SUCCESS;
+}                              /* LM_Halt */
+
+STATIC LM_STATUS LM_ResetChip (PLM_DEVICE_BLOCK pDevice)
+{
+       LM_UINT32 Value32;
+       LM_UINT32 j;
+
+       /* Wait for access to the nvram interface before resetting.  This is */
+       /* a workaround to prevent EEPROM corruption. */
+       if (T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
+           T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5701) {
+               /* Request access to the flash interface. */
+               REG_WR (pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
+
+               for (j = 0; j < 100000; j++) {
+                       Value32 = REG_RD (pDevice, Nvram.SwArb);
+                       if (Value32 & SW_ARB_GNT1) {
+                               break;
+                       }
+                       MM_Wait (10);
+               }
+       }
+
+       /* Global reset. */
+       REG_WR (pDevice, Grc.MiscCfg, GRC_MISC_CFG_CORE_CLOCK_RESET);
+       MM_Wait (40);
+       MM_Wait (40);
+       MM_Wait (40);
+
+       /* make sure we re-enable indirect accesses */
+       MM_WriteConfig32 (pDevice, T3_PCI_MISC_HOST_CTRL_REG,
+                         pDevice->MiscHostCtrl);
+
+       /* Set MAX PCI retry to zero. */
+       Value32 =
+           T3_PCI_STATE_PCI_ROM_ENABLE | T3_PCI_STATE_PCI_ROM_RETRY_ENABLE;
+       if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
+               if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)) {
+                       Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
+               }
+       }
+       MM_WriteConfig32 (pDevice, T3_PCI_STATE_REG, Value32);
+
+       /* Restore PCI command register. */
+       MM_WriteConfig32 (pDevice, PCI_COMMAND_REG,
+                         pDevice->PciCommandStatusWords);
+
+       /* Disable PCI-X relaxed ordering bit. */
+       MM_ReadConfig32 (pDevice, PCIX_CAP_REG, &Value32);
+       Value32 &= ~PCIX_ENABLE_RELAXED_ORDERING;
+       MM_WriteConfig32 (pDevice, PCIX_CAP_REG, Value32);
+
+       /* Enable memory arbiter. */
+       REG_WR (pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
+
+#ifdef BIG_ENDIAN_PCI          /* This from jfd */
+       Value32 = GRC_MODE_WORD_SWAP_DATA | GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
+#else
+#ifdef BIG_ENDIAN_HOST
+       /* Reconfigure the mode register. */
+       Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
+           GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
+           GRC_MODE_BYTE_SWAP_DATA | GRC_MODE_WORD_SWAP_DATA;
+#else
+       /* Reconfigure the mode register. */
+       Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
+#endif
+#endif
+       REG_WR (pDevice, Grc.Mode, Value32);
+
+       /* Prevent PXE from restarting. */
+       MEM_WR_OFFSET (pDevice, 0x0b50, T3_MAGIC_NUM);
+
+       if (pDevice->EnableTbi) {
+               pDevice->MacMode = MAC_MODE_PORT_MODE_TBI;
+               REG_WR (pDevice, MacCtrl.Mode, MAC_MODE_PORT_MODE_TBI);
+       } else {
+               REG_WR (pDevice, MacCtrl.Mode, 0);
+       }
+
+       /* Wait for the firmware to finish initialization. */
+       for (j = 0; j < 100000; j++) {
+               MM_Wait (10);
+
+               Value32 = MEM_RD_OFFSET (pDevice, 0x0b50);
+               if (Value32 == ~T3_MAGIC_NUM) {
+                       break;
+               }
+       }
+       return LM_STATUS_SUCCESS;
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+__inline static void LM_ServiceTxInterrupt (PLM_DEVICE_BLOCK pDevice)
+{
+       PLM_PACKET pPacket;
+       LM_UINT32 HwConIdx;
+       LM_UINT32 SwConIdx;
+
+       HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
+
+       /* Get our copy of the consumer index.  The buffer descriptors */
+       /* that are in between the consumer indices are freed. */
+       SwConIdx = pDevice->SendConIdx;
+
+       /* Move the packets from the TxPacketActiveQ that are sent out to */
+       /* the TxPacketXmittedQ.  Packets that are sent use the */
+       /* descriptors that are between SwConIdx and HwConIdx. */
+       while (SwConIdx != HwConIdx) {
+               /* Get the packet that was sent from the TxPacketActiveQ. */
+               pPacket =
+                   (PLM_PACKET) QQ_PopHead (&pDevice->TxPacketActiveQ.
+                                            Container);
+
+               /* Set the return status. */
+               pPacket->PacketStatus = LM_STATUS_SUCCESS;
+
+               /* Put the packet in the TxPacketXmittedQ for indication later. */
+               QQ_PushTail (&pDevice->TxPacketXmittedQ.Container, pPacket);
+
+               /* Move to the next packet's BD. */
+               SwConIdx = (SwConIdx + pPacket->u.Tx.FragCount) &
+                   T3_SEND_RCB_ENTRY_COUNT_MASK;
+
+               /* Update the number of unused BDs. */
+               atomic_add (pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
+
+               /* Get the new updated HwConIdx. */
+               HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
+       }                       /* while */
+
+       /* Save the new SwConIdx. */
+       pDevice->SendConIdx = SwConIdx;
+
+}                              /* LM_ServiceTxInterrupt */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+__inline static void LM_ServiceRxInterrupt (PLM_DEVICE_BLOCK pDevice)
+{
+       PLM_PACKET pPacket;
+       PT3_RCV_BD pRcvBd;
+       LM_UINT32 HwRcvRetProdIdx;
+       LM_UINT32 SwRcvRetConIdx;
+
+       /* Loop thru the receive return rings for received packets. */
+       HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
+
+       SwRcvRetConIdx = pDevice->RcvRetConIdx;
+       while (SwRcvRetConIdx != HwRcvRetProdIdx) {
+               pRcvBd = &pDevice->pRcvRetBdVirt[SwRcvRetConIdx];
+
+               /* Get the received packet descriptor. */
+               pPacket = (PLM_PACKET) (MM_UINT_PTR (pDevice->pPacketDescBase) +
+                                       MM_UINT_PTR (pRcvBd->Opaque));
+
+               /* Check the error flag. */
+               if (pRcvBd->ErrorFlag &&
+                   pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII) {
+                       pPacket->PacketStatus = LM_STATUS_FAILURE;
+
+                       pDevice->RxCounters.RxPacketErrCnt++;
+
+                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_BAD_CRC) {
+                               pDevice->RxCounters.RxErrCrcCnt++;
+                       }
+
+                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_COLL_DETECT) {
+                               pDevice->RxCounters.RxErrCollCnt++;
+                       }
+
+                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_LINK_LOST_DURING_PKT) {
+                               pDevice->RxCounters.RxErrLinkLostCnt++;
+                       }
+
+                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_PHY_DECODE_ERR) {
+                               pDevice->RxCounters.RxErrPhyDecodeCnt++;
+                       }
+
+                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_ODD_NIBBLED_RCVD_MII) {
+                               pDevice->RxCounters.RxErrOddNibbleCnt++;
+                       }
+
+                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_MAC_ABORT) {
+                               pDevice->RxCounters.RxErrMacAbortCnt++;
+                       }
+
+                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_LEN_LT_64) {
+                               pDevice->RxCounters.RxErrShortPacketCnt++;
+                       }
+
+                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_TRUNC_NO_RESOURCES) {
+                               pDevice->RxCounters.RxErrNoResourceCnt++;
+                       }
+
+                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_GIANT_FRAME_RCVD) {
+                               pDevice->RxCounters.RxErrLargePacketCnt++;
+                       }
+               } else {
+                       pPacket->PacketStatus = LM_STATUS_SUCCESS;
+                       pPacket->PacketSize = pRcvBd->Len - 4;
+
+                       pPacket->Flags = pRcvBd->Flags;
+                       if (pRcvBd->Flags & RCV_BD_FLAG_VLAN_TAG) {
+                               pPacket->VlanTag = pRcvBd->VlanTag;
+                       }
+
+                       pPacket->u.Rx.TcpUdpChecksum = pRcvBd->TcpUdpCksum;
+               }
+
+               /* Put the packet descriptor containing the received packet */
+               /* buffer in the RxPacketReceivedQ for indication later. */
+               QQ_PushTail (&pDevice->RxPacketReceivedQ.Container, pPacket);
+
+               /* Go to the next buffer descriptor. */
+               SwRcvRetConIdx = (SwRcvRetConIdx + 1) &
+                   T3_RCV_RETURN_RCB_ENTRY_COUNT_MASK;
+
+               /* Get the updated HwRcvRetProdIdx. */
+               HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
+       }                       /* while */
+
+       pDevice->RcvRetConIdx = SwRcvRetConIdx;
+
+       /* Update the receive return ring consumer index. */
+       MB_REG_WR (pDevice, Mailbox.RcvRetConIdx[0].Low, SwRcvRetConIdx);
+}                              /* LM_ServiceRxInterrupt */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    This is the interrupt event handler routine. It acknowledges all        */
+/*    pending interrupts and process all pending events.                      */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_SUCCESS                                                       */
+/******************************************************************************/
+LM_STATUS LM_ServiceInterrupts (PLM_DEVICE_BLOCK pDevice)
+{
+       LM_UINT32 Value32;
+       int ServicePhyInt = FALSE;
+
+       /* Setup the phy chip whenever the link status changes. */
+       if (pDevice->LinkChngMode == T3_LINK_CHNG_MODE_USE_STATUS_REG) {
+               Value32 = REG_RD (pDevice, MacCtrl.Status);
+               if (pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT) {
+                       if (Value32 & MAC_STATUS_MI_INTERRUPT) {
+                               ServicePhyInt = TRUE;
+                       }
+               } else if (Value32 & MAC_STATUS_LINK_STATE_CHANGED) {
+                       ServicePhyInt = TRUE;
+               }
+       } else {
+               if (pDevice->pStatusBlkVirt->
+                   Status & STATUS_BLOCK_LINK_CHANGED_STATUS) {
+                       pDevice->pStatusBlkVirt->Status =
+                           STATUS_BLOCK_UPDATED | (pDevice->pStatusBlkVirt->
+                                                   Status &
+                                                   ~STATUS_BLOCK_LINK_CHANGED_STATUS);
+                       ServicePhyInt = TRUE;
+               }
+       }
+#if INCLUDE_TBI_SUPPORT
+       if (pDevice->IgnoreTbiLinkChange == TRUE) {
+               ServicePhyInt = FALSE;
+       }
+#endif
+       if (ServicePhyInt == TRUE) {
+               LM_SetupPhy (pDevice);
+       }
+
+       /* Service receive and transmit interrupts. */
+       LM_ServiceRxInterrupt (pDevice);
+       LM_ServiceTxInterrupt (pDevice);
+
+       /* No spinlock for this queue since this routine is serialized. */
+       if (!QQ_Empty (&pDevice->RxPacketReceivedQ.Container)) {
+               /* Indicate receive packets. */
+               MM_IndicateRxPackets (pDevice);
+               /*       LM_QueueRxPackets(pDevice); */
+       }
+
+       /* No spinlock for this queue since this routine is serialized. */
+       if (!QQ_Empty (&pDevice->TxPacketXmittedQ.Container)) {
+               MM_IndicateTxPackets (pDevice);
+       }
+
+       return LM_STATUS_SUCCESS;
+}                              /* LM_ServiceInterrupts */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS LM_MulticastAdd (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress)
+{
+       PLM_UINT8 pEntry;
+       LM_UINT32 j;
+
+       pEntry = pDevice->McTable[0];
+       for (j = 0; j < pDevice->McEntryCount; j++) {
+               if (IS_ETH_ADDRESS_EQUAL (pEntry, pMcAddress)) {
+                       /* Found a match, increment the instance count. */
+                       pEntry[LM_MC_INSTANCE_COUNT_INDEX] += 1;
+
+                       return LM_STATUS_SUCCESS;
+               }
+
+               pEntry += LM_MC_ENTRY_SIZE;
+       }
+
+       if (pDevice->McEntryCount >= LM_MAX_MC_TABLE_SIZE) {
+               return LM_STATUS_FAILURE;
+       }
+
+       pEntry = pDevice->McTable[pDevice->McEntryCount];
+
+       COPY_ETH_ADDRESS (pMcAddress, pEntry);
+       pEntry[LM_MC_INSTANCE_COUNT_INDEX] = 1;
+
+       pDevice->McEntryCount++;
+
+       LM_SetReceiveMask (pDevice, pDevice->ReceiveMask | LM_ACCEPT_MULTICAST);
+
+       return LM_STATUS_SUCCESS;
+}                              /* LM_MulticastAdd */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS LM_MulticastDel (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress)
+{
+       PLM_UINT8 pEntry;
+       LM_UINT32 j;
+
+       pEntry = pDevice->McTable[0];
+       for (j = 0; j < pDevice->McEntryCount; j++) {
+               if (IS_ETH_ADDRESS_EQUAL (pEntry, pMcAddress)) {
+                       /* Found a match, decrement the instance count. */
+                       pEntry[LM_MC_INSTANCE_COUNT_INDEX] -= 1;
+
+                       /* No more instance left, remove the address from the table. */
+                       /* Move the last entry in the table to the delete slot. */
+                       if (pEntry[LM_MC_INSTANCE_COUNT_INDEX] == 0 &&
+                           pDevice->McEntryCount > 1) {
+
+                               COPY_ETH_ADDRESS (pDevice->
+                                                 McTable[pDevice->
+                                                         McEntryCount - 1],
+                                                 pEntry);
+                               pEntry[LM_MC_INSTANCE_COUNT_INDEX] =
+                                   pDevice->McTable[pDevice->McEntryCount - 1]
+                                   [LM_MC_INSTANCE_COUNT_INDEX];
+                       }
+                       pDevice->McEntryCount--;
+
+                       /* Update the receive mask if the table is empty. */
+                       if (pDevice->McEntryCount == 0) {
+                               LM_SetReceiveMask (pDevice,
+                                                  pDevice->
+                                                  ReceiveMask &
+                                                  ~LM_ACCEPT_MULTICAST);
+                       }
+
+                       return LM_STATUS_SUCCESS;
+               }
+
+               pEntry += LM_MC_ENTRY_SIZE;
+       }
+
+       return LM_STATUS_FAILURE;
+}                              /* LM_MulticastDel */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS LM_MulticastClear (PLM_DEVICE_BLOCK pDevice)
+{
+       pDevice->McEntryCount = 0;
+
+       LM_SetReceiveMask (pDevice,
+                          pDevice->ReceiveMask & ~LM_ACCEPT_MULTICAST);
+
+       return LM_STATUS_SUCCESS;
+}                              /* LM_MulticastClear */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS LM_SetMacAddress (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMacAddress)
+{
+       LM_UINT32 j;
+
+       for (j = 0; j < 4; j++) {
+               REG_WR (pDevice, MacCtrl.MacAddr[j].High,
+                       (pMacAddress[0] << 8) | pMacAddress[1]);
+               REG_WR (pDevice, MacCtrl.MacAddr[j].Low,
+                       (pMacAddress[2] << 24) | (pMacAddress[3] << 16) |
+                       (pMacAddress[4] << 8) | pMacAddress[5]);
+       }
+
+       return LM_STATUS_SUCCESS;
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*    Sets up the default line speed, and duplex modes based on the requested */
+/*    media type.                                                             */
+/*                                                                            */
+/* Return:                                                                    */
+/*    None.                                                                   */
+/******************************************************************************/
+static LM_STATUS
+LM_TranslateRequestedMediaType (LM_REQUESTED_MEDIA_TYPE RequestedMediaType,
+                               PLM_MEDIA_TYPE pMediaType,
+                               PLM_LINE_SPEED pLineSpeed,
+                               PLM_DUPLEX_MODE pDuplexMode)
+{
+       *pMediaType = LM_MEDIA_TYPE_AUTO;
+       *pLineSpeed = LM_LINE_SPEED_UNKNOWN;
+       *pDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
+
+       /* determine media type */
+       switch (RequestedMediaType) {
+       case LM_REQUESTED_MEDIA_TYPE_BNC:
+               *pMediaType = LM_MEDIA_TYPE_BNC;
+               *pLineSpeed = LM_LINE_SPEED_10MBPS;
+               *pDuplexMode = LM_DUPLEX_MODE_HALF;
+               break;
+
+       case LM_REQUESTED_MEDIA_TYPE_UTP_AUTO:
+               *pMediaType = LM_MEDIA_TYPE_UTP;
+               break;
+
+       case LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS:
+               *pMediaType = LM_MEDIA_TYPE_UTP;
+               *pLineSpeed = LM_LINE_SPEED_10MBPS;
+               *pDuplexMode = LM_DUPLEX_MODE_HALF;
+               break;
+
+       case LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS_FULL_DUPLEX:
+               *pMediaType = LM_MEDIA_TYPE_UTP;
+               *pLineSpeed = LM_LINE_SPEED_10MBPS;
+               *pDuplexMode = LM_DUPLEX_MODE_FULL;
+               break;
+
+       case LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS:
+               *pMediaType = LM_MEDIA_TYPE_UTP;
+               *pLineSpeed = LM_LINE_SPEED_100MBPS;
+               *pDuplexMode = LM_DUPLEX_MODE_HALF;
+               break;
+
+       case LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS_FULL_DUPLEX:
+               *pMediaType = LM_MEDIA_TYPE_UTP;
+               *pLineSpeed = LM_LINE_SPEED_100MBPS;
+               *pDuplexMode = LM_DUPLEX_MODE_FULL;
+               break;
+
+       case LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS:
+               *pMediaType = LM_MEDIA_TYPE_UTP;
+               *pLineSpeed = LM_LINE_SPEED_1000MBPS;
+               *pDuplexMode = LM_DUPLEX_MODE_HALF;
+               break;
+
+       case LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS_FULL_DUPLEX:
+               *pMediaType = LM_MEDIA_TYPE_UTP;
+               *pLineSpeed = LM_LINE_SPEED_1000MBPS;
+               *pDuplexMode = LM_DUPLEX_MODE_FULL;
+               break;
+
+       case LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS:
+               *pMediaType = LM_MEDIA_TYPE_FIBER;
+               *pLineSpeed = LM_LINE_SPEED_100MBPS;
+               *pDuplexMode = LM_DUPLEX_MODE_HALF;
+               break;
+
+       case LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS_FULL_DUPLEX:
+               *pMediaType = LM_MEDIA_TYPE_FIBER;
+               *pLineSpeed = LM_LINE_SPEED_100MBPS;
+               *pDuplexMode = LM_DUPLEX_MODE_FULL;
+               break;
+
+       case LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS:
+               *pMediaType = LM_MEDIA_TYPE_FIBER;
+               *pLineSpeed = LM_LINE_SPEED_1000MBPS;
+               *pDuplexMode = LM_DUPLEX_MODE_HALF;
+               break;
+
+       case LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS_FULL_DUPLEX:
+               *pMediaType = LM_MEDIA_TYPE_FIBER;
+               *pLineSpeed = LM_LINE_SPEED_1000MBPS;
+               *pDuplexMode = LM_DUPLEX_MODE_FULL;
+               break;
+
+       default:
+               break;
+       }                       /* switch */
+
+       return LM_STATUS_SUCCESS;
+}                              /* LM_TranslateRequestedMediaType */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_LINK_ACTIVE                                                   */
+/*    LM_STATUS_LINK_DOWN                                                     */
+/******************************************************************************/
+static LM_STATUS LM_InitBcm540xPhy (PLM_DEVICE_BLOCK pDevice)
+{
+       LM_LINE_SPEED CurrentLineSpeed;
+       LM_DUPLEX_MODE CurrentDuplexMode;
+       LM_STATUS CurrentLinkStatus;
+       LM_UINT32 Value32;
+       LM_UINT32 j;
+
+#if 1                          /* jmb: bugfix -- moved here, out of code that sets initial pwr state */
+       LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x2);
+#endif
+       if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID) {
+               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
+               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
+
+               if (!pDevice->InitDone) {
+                       Value32 = 0;
+               }
+
+               if (!(Value32 & PHY_STATUS_LINK_PASS)) {
+                       LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x0c20);
+
+                       LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
+                       LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x1804);
+
+                       LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
+                       LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x1204);
+
+                       LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
+                       LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0132);
+
+                       LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
+                       LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0232);
+
+                       LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
+                       LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
+
+                       LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
+                       for (j = 0; j < 1000; j++) {
+                               MM_Wait (10);
+
+                               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
+                               if (Value32 & PHY_STATUS_LINK_PASS) {
+                                       MM_Wait (40);
+                                       break;
+                               }
+                       }
+
+                       if ((pDevice->PhyId & PHY_ID_REV_MASK) ==
+                           PHY_BCM5401_B0_REV) {
+                               if (!(Value32 & PHY_STATUS_LINK_PASS)
+                                   && (pDevice->OldLineSpeed ==
+                                       LM_LINE_SPEED_1000MBPS)) {
+                                       LM_WritePhy (pDevice, PHY_CTRL_REG,
+                                                    PHY_CTRL_PHY_RESET);
+                                       for (j = 0; j < 100; j++) {
+                                               MM_Wait (10);
+
+                                               LM_ReadPhy (pDevice,
+                                                           PHY_CTRL_REG,
+                                                           &Value32);
+                                               if (!
+                                                   (Value32 &
+                                                    PHY_CTRL_PHY_RESET)) {
+                                                       MM_Wait (40);
+                                                       break;
+                                               }
+                                       }
+
+                                       LM_WritePhy (pDevice, BCM5401_AUX_CTRL,
+                                                    0x0c20);
+
+                                       LM_WritePhy (pDevice,
+                                                    BCM540X_DSP_ADDRESS_REG,
+                                                    0x0012);
+                                       LM_WritePhy (pDevice,
+                                                    BCM540X_DSP_RW_PORT,
+                                                    0x1804);
+
+                                       LM_WritePhy (pDevice,
+                                                    BCM540X_DSP_ADDRESS_REG,
+                                                    0x0013);
+                                       LM_WritePhy (pDevice,
+                                                    BCM540X_DSP_RW_PORT,
+                                                    0x1204);
+
+                                       LM_WritePhy (pDevice,
+                                                    BCM540X_DSP_ADDRESS_REG,
+                                                    0x8006);
+                                       LM_WritePhy (pDevice,
+                                                    BCM540X_DSP_RW_PORT,
+                                                    0x0132);
+
+                                       LM_WritePhy (pDevice,
+                                                    BCM540X_DSP_ADDRESS_REG,
+                                                    0x8006);
+                                       LM_WritePhy (pDevice,
+                                                    BCM540X_DSP_RW_PORT,
+                                                    0x0232);
+
+                                       LM_WritePhy (pDevice,
+                                                    BCM540X_DSP_ADDRESS_REG,
+                                                    0x201f);
+                                       LM_WritePhy (pDevice,
+                                                    BCM540X_DSP_RW_PORT,
+                                                    0x0a20);
+                               }
+                       }
+               }
+       } else if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+                  pDevice->ChipRevId == T3_CHIP_ID_5701_B0) {
+               /* Bug: 5701 A0, B0 TX CRC workaround. */
+               LM_WritePhy (pDevice, 0x15, 0x0a75);
+               LM_WritePhy (pDevice, 0x1c, 0x8c68);
+               LM_WritePhy (pDevice, 0x1c, 0x8d68);
+               LM_WritePhy (pDevice, 0x1c, 0x8c68);
+       }
+
+       /* Acknowledge interrupts. */
+       LM_ReadPhy (pDevice, BCM540X_INT_STATUS_REG, &Value32);
+       LM_ReadPhy (pDevice, BCM540X_INT_STATUS_REG, &Value32);
+
+       /* Configure the interrupt mask. */
+       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT) {
+               LM_WritePhy (pDevice, BCM540X_INT_MASK_REG,
+                            ~BCM540X_INT_LINK_CHANGE);
+       }
+
+       /* Configure PHY led mode. */
+       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
+           (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700)) {
+               if (pDevice->LedMode == LED_MODE_THREE_LINK) {
+                       LM_WritePhy (pDevice, BCM540X_EXT_CTRL_REG,
+                                    BCM540X_EXT_CTRL_LINK3_LED_MODE);
+               } else {
+                       LM_WritePhy (pDevice, BCM540X_EXT_CTRL_REG, 0);
+               }
+       }
+
+       CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+
+       /* Get current link and duplex mode. */
+       for (j = 0; j < 100; j++) {
+               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
+               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
+
+               if (Value32 & PHY_STATUS_LINK_PASS) {
+                       break;
+               }
+               MM_Wait (40);
+       }
+
+       if (Value32 & PHY_STATUS_LINK_PASS) {
+
+               /* Determine the current line and duplex settings. */
+               LM_ReadPhy (pDevice, BCM540X_AUX_STATUS_REG, &Value32);
+               for (j = 0; j < 2000; j++) {
+                       MM_Wait (10);
+
+                       LM_ReadPhy (pDevice, BCM540X_AUX_STATUS_REG, &Value32);
+                       if (Value32) {
+                               break;
+                       }
+               }
+
+               switch (Value32 & BCM540X_AUX_SPEED_MASK) {
+               case BCM540X_AUX_10BASET_HD:
+                       CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
+                       CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
+                       break;
+
+               case BCM540X_AUX_10BASET_FD:
+                       CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
+                       CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
+                       break;
+
+               case BCM540X_AUX_100BASETX_HD:
+                       CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
+                       CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
+                       break;
+
+               case BCM540X_AUX_100BASETX_FD:
+                       CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
+                       CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
+                       break;
+
+               case BCM540X_AUX_100BASET_HD:
+                       CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
+                       CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
+                       break;
+
+               case BCM540X_AUX_100BASET_FD:
+                       CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
+                       CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
+                       break;
+
+               default:
+
+                       CurrentLineSpeed = LM_LINE_SPEED_UNKNOWN;
+                       CurrentDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
+                       break;
+               }
+
+               /* Make sure we are in auto-neg mode. */
+               for (j = 0; j < 200; j++) {
+                       LM_ReadPhy (pDevice, PHY_CTRL_REG, &Value32);
+                       if (Value32 && Value32 != 0x7fff) {
+                               break;
+                       }
+
+                       if (Value32 == 0 && pDevice->RequestedMediaType ==
+                           LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS) {
+                               break;
+                       }
+
+                       MM_Wait (10);
+               }
+
+               /* Use the current line settings for "auto" mode. */
+               if (pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO
+                   || pDevice->RequestedMediaType ==
+                   LM_REQUESTED_MEDIA_TYPE_UTP_AUTO) {
+                       if (Value32 & PHY_CTRL_AUTO_NEG_ENABLE) {
+                               CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
+
+                               /* We may be exiting low power mode and the link is in */
+                               /* 10mb.  In this case, we need to restart autoneg. */
+                               LM_ReadPhy (pDevice, BCM540X_1000BASET_CTRL_REG,
+                                           &Value32);
+                               pDevice->advertising1000 = Value32;
+                               /* 5702FE supports 10/100Mb only. */
+                               if (T3_ASIC_REV (pDevice->ChipRevId) !=
+                                   T3_ASIC_REV_5703
+                                   || pDevice->BondId !=
+                                   GRC_MISC_BD_ID_5702FE) {
+                                       if (!
+                                           (Value32 &
+                                            (BCM540X_AN_AD_1000BASET_HALF |
+                                             BCM540X_AN_AD_1000BASET_FULL))) {
+                                               CurrentLinkStatus =
+                                                   LM_STATUS_LINK_SETTING_MISMATCH;
+                                       }
+                               }
+                       } else {
+                               CurrentLinkStatus =
+                                   LM_STATUS_LINK_SETTING_MISMATCH;
+                       }
+               } else {
+                       /* Force line settings. */
+                       /* Use the current setting if it matches the user's requested */
+                       /* setting. */
+                       LM_ReadPhy (pDevice, PHY_CTRL_REG, &Value32);
+                       if ((pDevice->LineSpeed == CurrentLineSpeed) &&
+                           (pDevice->DuplexMode == CurrentDuplexMode)) {
+                               if ((pDevice->DisableAutoNeg &&
+                                    !(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)) ||
+                                   (!pDevice->DisableAutoNeg &&
+                                    (Value32 & PHY_CTRL_AUTO_NEG_ENABLE))) {
+                                       CurrentLinkStatus =
+                                           LM_STATUS_LINK_ACTIVE;
+                               } else {
+                                       CurrentLinkStatus =
+                                           LM_STATUS_LINK_SETTING_MISMATCH;
+                               }
+                       } else {
+                               CurrentLinkStatus =
+                                   LM_STATUS_LINK_SETTING_MISMATCH;
+                       }
+               }
+
+               /* Save line settings. */
+               pDevice->LineSpeed = CurrentLineSpeed;
+               pDevice->DuplexMode = CurrentDuplexMode;
+               pDevice->MediaType = LM_MEDIA_TYPE_UTP;
+       }
+
+       return CurrentLinkStatus;
+}                              /* LM_InitBcm540xPhy */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS
+LM_SetFlowControl (PLM_DEVICE_BLOCK pDevice,
+                  LM_UINT32 LocalPhyAd, LM_UINT32 RemotePhyAd)
+{
+       LM_FLOW_CONTROL FlowCap;
+
+       /* Resolve flow control. */
+       FlowCap = LM_FLOW_CONTROL_NONE;
+
+       /* See Table 28B-3 of 802.3ab-1999 spec. */
+       if (pDevice->FlowControlCap & LM_FLOW_CONTROL_AUTO_PAUSE) {
+               if (LocalPhyAd & PHY_AN_AD_PAUSE_CAPABLE) {
+                       if (LocalPhyAd & PHY_AN_AD_ASYM_PAUSE) {
+                               if (RemotePhyAd &
+                                   PHY_LINK_PARTNER_PAUSE_CAPABLE) {
+                                       FlowCap =
+                                           LM_FLOW_CONTROL_TRANSMIT_PAUSE |
+                                           LM_FLOW_CONTROL_RECEIVE_PAUSE;
+                               } else if (RemotePhyAd &
+                                          PHY_LINK_PARTNER_ASYM_PAUSE) {
+                                       FlowCap = LM_FLOW_CONTROL_RECEIVE_PAUSE;
+                               }
+                       } else {
+                               if (RemotePhyAd &
+                                   PHY_LINK_PARTNER_PAUSE_CAPABLE) {
+                                       FlowCap =
+                                           LM_FLOW_CONTROL_TRANSMIT_PAUSE |
+                                           LM_FLOW_CONTROL_RECEIVE_PAUSE;
+                               }
+                       }
+               } else if (LocalPhyAd & PHY_AN_AD_ASYM_PAUSE) {
+                       if ((RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE) &&
+                           (RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE)) {
+                               FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE;
+                       }
+               }
+       } else {
+               FlowCap = pDevice->FlowControlCap;
+       }
+
+       /* Enable/disable rx PAUSE. */
+       pDevice->RxMode &= ~RX_MODE_ENABLE_FLOW_CONTROL;
+       if (FlowCap & LM_FLOW_CONTROL_RECEIVE_PAUSE &&
+           (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
+            pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)) {
+               pDevice->FlowControl |= LM_FLOW_CONTROL_RECEIVE_PAUSE;
+               pDevice->RxMode |= RX_MODE_ENABLE_FLOW_CONTROL;
+
+       }
+       REG_WR (pDevice, MacCtrl.RxMode, pDevice->RxMode);
+
+       /* Enable/disable tx PAUSE. */
+       pDevice->TxMode &= ~TX_MODE_ENABLE_FLOW_CONTROL;
+       if (FlowCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE &&
+           (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
+            pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)) {
+               pDevice->FlowControl |= LM_FLOW_CONTROL_TRANSMIT_PAUSE;
+               pDevice->TxMode |= TX_MODE_ENABLE_FLOW_CONTROL;
+
+       }
+       REG_WR (pDevice, MacCtrl.TxMode, pDevice->TxMode);
+
+       return LM_STATUS_SUCCESS;
+}
+
+#if INCLUDE_TBI_SUPPORT
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+STATIC LM_STATUS LM_InitBcm800xPhy (PLM_DEVICE_BLOCK pDevice)
+{
+       LM_UINT32 Value32;
+       LM_UINT32 j;
+
+       Value32 = REG_RD (pDevice, MacCtrl.Status);
+
+       /* Reset the SERDES during init and when we have link. */
+       if (!pDevice->InitDone || Value32 & MAC_STATUS_PCS_SYNCED) {
+               /* Set PLL lock range. */
+               LM_WritePhy (pDevice, 0x16, 0x8007);
+
+               /* Software reset. */
+               LM_WritePhy (pDevice, 0x00, 0x8000);
+
+               /* Wait for reset to complete. */
+               for (j = 0; j < 500; j++) {
+                       MM_Wait (10);
+               }
+
+               /* Config mode; seletct PMA/Ch 1 regs. */
+               LM_WritePhy (pDevice, 0x10, 0x8411);
+
+               /* Enable auto-lock and comdet, select txclk for tx. */
+               LM_WritePhy (pDevice, 0x11, 0x0a10);
+
+               LM_WritePhy (pDevice, 0x18, 0x00a0);
+               LM_WritePhy (pDevice, 0x16, 0x41ff);
+
+               /* Assert and deassert POR. */
+               LM_WritePhy (pDevice, 0x13, 0x0400);
+               MM_Wait (40);
+               LM_WritePhy (pDevice, 0x13, 0x0000);
+
+               LM_WritePhy (pDevice, 0x11, 0x0a50);
+               MM_Wait (40);
+               LM_WritePhy (pDevice, 0x11, 0x0a10);
+
+               /* Delay for signal to stabilize. */
+               for (j = 0; j < 15000; j++) {
+                       MM_Wait (10);
+               }
+
+               /* Deselect the channel register so we can read the PHY id later. */
+               LM_WritePhy (pDevice, 0x10, 0x8011);
+       }
+
+       return LM_STATUS_SUCCESS;
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+STATIC LM_STATUS LM_SetupFiberPhy (PLM_DEVICE_BLOCK pDevice)
+{
+       LM_STATUS CurrentLinkStatus;
+       AUTONEG_STATUS AnStatus = 0;
+       LM_UINT32 Value32;
+       LM_UINT32 Cnt;
+       LM_UINT32 j, k;
+
+       pDevice->MacMode &= ~(MAC_MODE_HALF_DUPLEX | MAC_MODE_PORT_MODE_MASK);
+
+       /* Initialize the send_config register. */
+       REG_WR (pDevice, MacCtrl.TxAutoNeg, 0);
+
+       /* Enable TBI and full duplex mode. */
+       pDevice->MacMode |= MAC_MODE_PORT_MODE_TBI;
+       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
+
+       /* Initialize the BCM8002 SERDES PHY. */
+       switch (pDevice->PhyId & PHY_ID_MASK) {
+       case PHY_BCM8002_PHY_ID:
+               LM_InitBcm800xPhy (pDevice);
+               break;
+
+       default:
+               break;
+       }
+
+       /* Enable link change interrupt. */
+       REG_WR (pDevice, MacCtrl.MacEvent,
+               MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
+
+       /* Default to link down. */
+       CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+
+       /* Get the link status. */
+       Value32 = REG_RD (pDevice, MacCtrl.Status);
+       if (Value32 & MAC_STATUS_PCS_SYNCED) {
+               if ((pDevice->RequestedMediaType ==
+                    LM_REQUESTED_MEDIA_TYPE_AUTO)
+                   || (pDevice->DisableAutoNeg == FALSE)) {
+                       /* auto-negotiation mode. */
+                       /* Initialize the autoneg default capaiblities. */
+                       AutonegInit (&pDevice->AnInfo);
+
+                       /* Set the context pointer to point to the main device structure. */
+                       pDevice->AnInfo.pContext = pDevice;
+
+                       /* Setup flow control advertisement register. */
+                       Value32 = GetPhyAdFlowCntrlSettings (pDevice);
+                       if (Value32 & PHY_AN_AD_PAUSE_CAPABLE) {
+                               pDevice->AnInfo.mr_adv_sym_pause = 1;
+                       } else {
+                               pDevice->AnInfo.mr_adv_sym_pause = 0;
+                       }
+
+                       if (Value32 & PHY_AN_AD_ASYM_PAUSE) {
+                               pDevice->AnInfo.mr_adv_asym_pause = 1;
+                       } else {
+                               pDevice->AnInfo.mr_adv_asym_pause = 0;
+                       }
+
+                       /* Try to autoneg up to six times. */
+                       if (pDevice->IgnoreTbiLinkChange) {
+                               Cnt = 1;
+                       } else {
+                               Cnt = 6;
+                       }
+                       for (j = 0; j < Cnt; j++) {
+                               REG_WR (pDevice, MacCtrl.TxAutoNeg, 0);
+
+                               Value32 =
+                                   pDevice->MacMode & ~MAC_MODE_PORT_MODE_MASK;
+                               REG_WR (pDevice, MacCtrl.Mode, Value32);
+                               MM_Wait (20);
+
+                               REG_WR (pDevice, MacCtrl.Mode,
+                                       pDevice->
+                                       MacMode | MAC_MODE_SEND_CONFIGS);
+
+                               MM_Wait (20);
+
+                               pDevice->AnInfo.State = AN_STATE_UNKNOWN;
+                               pDevice->AnInfo.CurrentTime_us = 0;
+
+                               REG_WR (pDevice, Grc.Timer, 0);
+                               for (k = 0;
+                                    (pDevice->AnInfo.CurrentTime_us < 75000)
+                                    && (k < 75000); k++) {
+                                       AnStatus =
+                                           Autoneg8023z (&pDevice->AnInfo);
+
+                                       if ((AnStatus == AUTONEG_STATUS_DONE) ||
+                                           (AnStatus == AUTONEG_STATUS_FAILED))
+                                       {
+                                               break;
+                                       }
+
+                                       pDevice->AnInfo.CurrentTime_us =
+                                           REG_RD (pDevice, Grc.Timer);
+
+                               }
+                               if ((AnStatus == AUTONEG_STATUS_DONE) ||
+                                   (AnStatus == AUTONEG_STATUS_FAILED)) {
+                                       break;
+                               }
+                               if (j >= 1) {
+                                       if (!(REG_RD (pDevice, MacCtrl.Status) &
+                                             MAC_STATUS_PCS_SYNCED)) {
+                                               break;
+                                       }
+                               }
+                       }
+
+                       /* Stop sending configs. */
+                       MM_AnTxIdle (&pDevice->AnInfo);
+
+                       /* Resolve flow control settings. */
+                       if ((AnStatus == AUTONEG_STATUS_DONE) &&
+                           pDevice->AnInfo.mr_an_complete
+                           && pDevice->AnInfo.mr_link_ok
+                           && pDevice->AnInfo.mr_lp_adv_full_duplex) {
+                               LM_UINT32 RemotePhyAd;
+                               LM_UINT32 LocalPhyAd;
+
+                               LocalPhyAd = 0;
+                               if (pDevice->AnInfo.mr_adv_sym_pause) {
+                                       LocalPhyAd |= PHY_AN_AD_PAUSE_CAPABLE;
+                               }
+
+                               if (pDevice->AnInfo.mr_adv_asym_pause) {
+                                       LocalPhyAd |= PHY_AN_AD_ASYM_PAUSE;
+                               }
+
+                               RemotePhyAd = 0;
+                               if (pDevice->AnInfo.mr_lp_adv_sym_pause) {
+                                       RemotePhyAd |=
+                                           PHY_LINK_PARTNER_PAUSE_CAPABLE;
+                               }
+
+                               if (pDevice->AnInfo.mr_lp_adv_asym_pause) {
+                                       RemotePhyAd |=
+                                           PHY_LINK_PARTNER_ASYM_PAUSE;
+                               }
+
+                               LM_SetFlowControl (pDevice, LocalPhyAd,
+                                                  RemotePhyAd);
+
+                               CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
+                       }
+                       for (j = 0; j < 30; j++) {
+                               MM_Wait (20);
+                               REG_WR (pDevice, MacCtrl.Status,
+                                       MAC_STATUS_SYNC_CHANGED |
+                                       MAC_STATUS_CFG_CHANGED);
+                               MM_Wait (20);
+                               if ((REG_RD (pDevice, MacCtrl.Status) &
+                                    (MAC_STATUS_SYNC_CHANGED |
+                                     MAC_STATUS_CFG_CHANGED)) == 0)
+                                       break;
+                       }
+                       if (pDevice->PollTbiLink) {
+                               Value32 = REG_RD (pDevice, MacCtrl.Status);
+                               if (Value32 & MAC_STATUS_RECEIVING_CFG) {
+                                       pDevice->IgnoreTbiLinkChange = TRUE;
+                               } else {
+                                       pDevice->IgnoreTbiLinkChange = FALSE;
+                               }
+                       }
+                       Value32 = REG_RD (pDevice, MacCtrl.Status);
+                       if (CurrentLinkStatus == LM_STATUS_LINK_DOWN &&
+                           (Value32 & MAC_STATUS_PCS_SYNCED) &&
+                           ((Value32 & MAC_STATUS_RECEIVING_CFG) == 0)) {
+                               CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
+                       }
+               } else {
+                       /* We are forcing line speed. */
+                       pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
+                       LM_SetFlowControl (pDevice, 0, 0);
+
+                       CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
+                       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode |
+                               MAC_MODE_SEND_CONFIGS);
+               }
+       }
+       /* Set the link polarity bit. */
+       pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
+       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
+
+       pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
+           (pDevice->pStatusBlkVirt->
+            Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
+
+       for (j = 0; j < 100; j++) {
+               REG_WR (pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
+                       MAC_STATUS_CFG_CHANGED);
+               MM_Wait (5);
+               if ((REG_RD (pDevice, MacCtrl.Status) &
+                    (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
+                       break;
+       }
+
+       Value32 = REG_RD (pDevice, MacCtrl.Status);
+       if ((Value32 & MAC_STATUS_PCS_SYNCED) == 0) {
+               CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+               if (pDevice->DisableAutoNeg == FALSE) {
+                       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode |
+                               MAC_MODE_SEND_CONFIGS);
+                       MM_Wait (1);
+                       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
+               }
+       }
+
+       /* Initialize the current link status. */
+       if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) {
+               pDevice->LineSpeed = LM_LINE_SPEED_1000MBPS;
+               pDevice->DuplexMode = LM_DUPLEX_MODE_FULL;
+               REG_WR (pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
+                       LED_CTRL_1000MBPS_LED_ON);
+       } else {
+               pDevice->LineSpeed = LM_LINE_SPEED_UNKNOWN;
+               pDevice->DuplexMode = LM_DUPLEX_MODE_UNKNOWN;
+               REG_WR (pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
+                       LED_CTRL_OVERRIDE_TRAFFIC_LED);
+       }
+
+       /* Indicate link status. */
+       if (pDevice->LinkStatus != CurrentLinkStatus) {
+               pDevice->LinkStatus = CurrentLinkStatus;
+               MM_IndicateStatus (pDevice, CurrentLinkStatus);
+       }
+
+       return LM_STATUS_SUCCESS;
+}
+#endif                         /* INCLUDE_TBI_SUPPORT */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS LM_SetupCopperPhy (PLM_DEVICE_BLOCK pDevice)
+{
+       LM_STATUS CurrentLinkStatus;
+       LM_UINT32 Value32;
+
+       /* Assume there is not link first. */
+       CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+
+       /* Disable phy link change attention. */
+       REG_WR (pDevice, MacCtrl.MacEvent, 0);
+
+       /* Clear link change attention. */
+       REG_WR (pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
+               MAC_STATUS_CFG_CHANGED);
+
+       /* Disable auto-polling for the moment. */
+       pDevice->MiMode = 0xc0000;
+       REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
+       MM_Wait (40);
+
+       /* Determine the requested line speed and duplex. */
+       pDevice->OldLineSpeed = pDevice->LineSpeed;
+       LM_TranslateRequestedMediaType (pDevice->RequestedMediaType,
+                                       &pDevice->MediaType,
+                                       &pDevice->LineSpeed,
+                                       &pDevice->DuplexMode);
+
+       /* Initialize the phy chip. */
+       switch (pDevice->PhyId & PHY_ID_MASK) {
+       case PHY_BCM5400_PHY_ID:
+       case PHY_BCM5401_PHY_ID:
+       case PHY_BCM5411_PHY_ID:
+       case PHY_BCM5701_PHY_ID:
+       case PHY_BCM5703_PHY_ID:
+       case PHY_BCM5704_PHY_ID:
+               CurrentLinkStatus = LM_InitBcm540xPhy (pDevice);
+               break;
+
+       default:
+               break;
+       }
+
+       if (CurrentLinkStatus == LM_STATUS_LINK_SETTING_MISMATCH) {
+               CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+       }
+
+       /* Setup flow control. */
+       pDevice->FlowControl = LM_FLOW_CONTROL_NONE;
+       if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) {
+               LM_FLOW_CONTROL FlowCap;        /* Flow control capability. */
+
+               FlowCap = LM_FLOW_CONTROL_NONE;
+
+               if (pDevice->DuplexMode == LM_DUPLEX_MODE_FULL) {
+                       if (pDevice->DisableAutoNeg == FALSE ||
+                           pDevice->RequestedMediaType ==
+                           LM_REQUESTED_MEDIA_TYPE_AUTO
+                           || pDevice->RequestedMediaType ==
+                           LM_REQUESTED_MEDIA_TYPE_UTP_AUTO) {
+                               LM_UINT32 ExpectedPhyAd;
+                               LM_UINT32 LocalPhyAd;
+                               LM_UINT32 RemotePhyAd;
+
+                               LM_ReadPhy (pDevice, PHY_AN_AD_REG,
+                                           &LocalPhyAd);
+                               pDevice->advertising = LocalPhyAd;
+                               LocalPhyAd &=
+                                   (PHY_AN_AD_ASYM_PAUSE |
+                                    PHY_AN_AD_PAUSE_CAPABLE);
+
+                               ExpectedPhyAd =
+                                   GetPhyAdFlowCntrlSettings (pDevice);
+
+                               if (LocalPhyAd != ExpectedPhyAd) {
+                                       CurrentLinkStatus = LM_STATUS_LINK_DOWN;
+                               } else {
+                                       LM_ReadPhy (pDevice,
+                                                   PHY_LINK_PARTNER_ABILITY_REG,
+                                                   &RemotePhyAd);
+
+                                       LM_SetFlowControl (pDevice, LocalPhyAd,
+                                                          RemotePhyAd);
+                               }
+                       } else {
+                               pDevice->FlowControlCap &=
+                                   ~LM_FLOW_CONTROL_AUTO_PAUSE;
+                               LM_SetFlowControl (pDevice, 0, 0);
+                       }
+               }
+       }
+
+       if (CurrentLinkStatus == LM_STATUS_LINK_DOWN) {
+               LM_ForceAutoNeg (pDevice, pDevice->RequestedMediaType);
+
+               /* If we force line speed, we make get link right away. */
+               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
+               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
+               if (Value32 & PHY_STATUS_LINK_PASS) {
+                       CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
+               }
+       }
+
+       /* GMII interface. */
+       pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
+       if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) {
+               if (pDevice->LineSpeed == LM_LINE_SPEED_100MBPS ||
+                   pDevice->LineSpeed == LM_LINE_SPEED_10MBPS) {
+                       pDevice->MacMode |= MAC_MODE_PORT_MODE_MII;
+               } else {
+                       pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
+               }
+       } else {
+               pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
+       }
+
+       /* Set the MAC to operate in the appropriate duplex mode. */
+       pDevice->MacMode &= ~MAC_MODE_HALF_DUPLEX;
+       if (pDevice->DuplexMode == LM_DUPLEX_MODE_HALF) {
+               pDevice->MacMode |= MAC_MODE_HALF_DUPLEX;
+       }
+
+       /* Set the link polarity bit. */
+       pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
+       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
+               if ((pDevice->LedMode == LED_MODE_LINK10) ||
+                   (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE &&
+                    pDevice->LineSpeed == LM_LINE_SPEED_10MBPS)) {
+                       pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
+               }
+       } else {
+               if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) {
+                       pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
+               }
+
+               /* Set LED mode. */
+               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
+                       Value32 = LED_CTRL_PHY_MODE_1;
+               } else {
+                       if (pDevice->LedMode == LED_MODE_OUTPUT) {
+                               Value32 = LED_CTRL_PHY_MODE_2;
+                       } else {
+                               Value32 = LED_CTRL_PHY_MODE_1;
+                       }
+               }
+               REG_WR (pDevice, MacCtrl.LedCtrl, Value32);
+       }
+
+       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
+
+       /* Enable auto polling. */
+       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
+               pDevice->MiMode |= MI_MODE_AUTO_POLLING_ENABLE;
+               REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
+       }
+
+       /* Enable phy link change attention. */
+       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT) {
+               REG_WR (pDevice, MacCtrl.MacEvent,
+                       MAC_EVENT_ENABLE_MI_INTERRUPT);
+       } else {
+               REG_WR (pDevice, MacCtrl.MacEvent,
+                       MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
+       }
+       if ((T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) &&
+           (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) &&
+           (pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
+           (((pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) &&
+             (pDevice->PciState & T3_PCI_STATE_BUS_SPEED_HIGH)) ||
+            !(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))) {
+               MM_Wait (120);
+               REG_WR (pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
+                       MAC_STATUS_CFG_CHANGED);
+               MEM_WR_OFFSET (pDevice, T3_FIRMWARE_MAILBOX,
+                              T3_MAGIC_NUM_DISABLE_DMAW_ON_LINK_CHANGE);
+       }
+
+       /* Indicate link status. */
+       if (pDevice->LinkStatus != CurrentLinkStatus) {
+               pDevice->LinkStatus = CurrentLinkStatus;
+               MM_IndicateStatus (pDevice, CurrentLinkStatus);
+       }
+
+       return LM_STATUS_SUCCESS;
+}                              /* LM_SetupCopperPhy */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS LM_SetupPhy (PLM_DEVICE_BLOCK pDevice)
+{
+       LM_STATUS LmStatus;
+       LM_UINT32 Value32;
+
+#if INCLUDE_TBI_SUPPORT
+       if (pDevice->EnableTbi) {
+               LmStatus = LM_SetupFiberPhy (pDevice);
+       } else
+#endif                         /* INCLUDE_TBI_SUPPORT */
+       {
+               LmStatus = LM_SetupCopperPhy (pDevice);
+       }
+       if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
+               if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)) {
+                       Value32 = REG_RD (pDevice, PciCfg.PciState);
+                       REG_WR (pDevice, PciCfg.PciState,
+                               Value32 | T3_PCI_STATE_RETRY_SAME_DMA);
+               }
+       }
+       if ((pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
+           (pDevice->DuplexMode == LM_DUPLEX_MODE_HALF)) {
+               REG_WR (pDevice, MacCtrl.TxLengths, 0x26ff);
+       } else {
+               REG_WR (pDevice, MacCtrl.TxLengths, 0x2620);
+       }
+
+       return LmStatus;
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_VOID
+LM_ReadPhy (PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg, PLM_UINT32 pData32)
+{
+       LM_UINT32 Value32;
+       LM_UINT32 j;
+
+       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
+               REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode &
+                       ~MI_MODE_AUTO_POLLING_ENABLE);
+               MM_Wait (40);
+       }
+
+       Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
+           ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) <<
+            MI_COM_FIRST_PHY_REG_ADDR_BIT) | MI_COM_CMD_READ | MI_COM_START;
+
+       REG_WR (pDevice, MacCtrl.MiCom, Value32);
+
+       for (j = 0; j < 20; j++) {
+               MM_Wait (25);
+
+               Value32 = REG_RD (pDevice, MacCtrl.MiCom);
+
+               if (!(Value32 & MI_COM_BUSY)) {
+                       MM_Wait (5);
+                       Value32 = REG_RD (pDevice, MacCtrl.MiCom);
+                       Value32 &= MI_COM_PHY_DATA_MASK;
+                       break;
+               }
+       }
+
+       if (Value32 & MI_COM_BUSY) {
+               Value32 = 0;
+       }
+
+       *pData32 = Value32;
+
+       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
+               REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
+               MM_Wait (40);
+       }
+}                              /* LM_ReadPhy */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_VOID
+LM_WritePhy (PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg, LM_UINT32 Data32)
+{
+       LM_UINT32 Value32;
+       LM_UINT32 j;
+
+       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
+               REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode &
+                       ~MI_MODE_AUTO_POLLING_ENABLE);
+               MM_Wait (40);
+       }
+
+       Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
+           ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) <<
+            MI_COM_FIRST_PHY_REG_ADDR_BIT) | (Data32 & MI_COM_PHY_DATA_MASK) |
+           MI_COM_CMD_WRITE | MI_COM_START;
+
+       REG_WR (pDevice, MacCtrl.MiCom, Value32);
+
+       for (j = 0; j < 20; j++) {
+               MM_Wait (25);
+
+               Value32 = REG_RD (pDevice, MacCtrl.MiCom);
+
+               if (!(Value32 & MI_COM_BUSY)) {
+                       MM_Wait (5);
+                       break;
+               }
+       }
+
+       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
+               REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
+               MM_Wait (40);
+       }
+}                              /* LM_WritePhy */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS LM_SetPowerState (PLM_DEVICE_BLOCK pDevice, LM_POWER_STATE PowerLevel)
+{
+       LM_UINT32 PmeSupport;
+       LM_UINT32 Value32;
+       LM_UINT32 PmCtrl;
+
+       /* make sureindirect accesses are enabled */
+       MM_WriteConfig32 (pDevice, T3_PCI_MISC_HOST_CTRL_REG,
+                         pDevice->MiscHostCtrl);
+
+       /* Clear the PME_ASSERT bit and the power state bits.  Also enable */
+       /* the PME bit. */
+       MM_ReadConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, &PmCtrl);
+
+       PmCtrl |= T3_PM_PME_ASSERTED;
+       PmCtrl &= ~T3_PM_POWER_STATE_MASK;
+
+       /* Set the appropriate power state. */
+       if (PowerLevel == LM_POWER_STATE_D0) {
+
+               /* Bring the card out of low power mode. */
+               PmCtrl |= T3_PM_POWER_STATE_D0;
+               MM_WriteConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
+
+               REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
+               MM_Wait (40);
+#if 0                          /* Bugfix by jmb...can't call WritePhy here because pDevice not fully initialized */
+               LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x02);
+#endif
+
+               return LM_STATUS_SUCCESS;
+       } else if (PowerLevel == LM_POWER_STATE_D1) {
+               PmCtrl |= T3_PM_POWER_STATE_D1;
+       } else if (PowerLevel == LM_POWER_STATE_D2) {
+               PmCtrl |= T3_PM_POWER_STATE_D2;
+       } else if (PowerLevel == LM_POWER_STATE_D3) {
+               PmCtrl |= T3_PM_POWER_STATE_D3;
+       } else {
+               return LM_STATUS_FAILURE;
+       }
+       PmCtrl |= T3_PM_PME_ENABLE;
+
+       /* Mask out all interrupts so LM_SetupPhy won't be called while we are */
+       /* setting new line speed. */
+       Value32 = REG_RD (pDevice, PciCfg.MiscHostCtrl);
+       REG_WR (pDevice, PciCfg.MiscHostCtrl,
+               Value32 | MISC_HOST_CTRL_MASK_PCI_INT);
+
+       if (!pDevice->RestoreOnWakeUp) {
+               pDevice->RestoreOnWakeUp = TRUE;
+               pDevice->WakeUpDisableAutoNeg = pDevice->DisableAutoNeg;
+               pDevice->WakeUpRequestedMediaType = pDevice->RequestedMediaType;
+       }
+
+       /* Force auto-negotiation to 10 line speed. */
+       pDevice->DisableAutoNeg = FALSE;
+       pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS;
+       LM_SetupPhy (pDevice);
+
+       /* Put the driver in the initial state, and go through the power down */
+       /* sequence. */
+       LM_Halt (pDevice);
+
+       MM_ReadConfig32 (pDevice, T3_PCI_PM_CAP_REG, &PmeSupport);
+
+       if (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE) {
+
+               /* Enable WOL. */
+               LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x5a);
+               MM_Wait (40);
+
+               /* Set LED mode. */
+               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
+                       Value32 = LED_CTRL_PHY_MODE_1;
+               } else {
+                       if (pDevice->LedMode == LED_MODE_OUTPUT) {
+                               Value32 = LED_CTRL_PHY_MODE_2;
+                       } else {
+                               Value32 = LED_CTRL_PHY_MODE_1;
+                       }
+               }
+
+               Value32 = MAC_MODE_PORT_MODE_MII;
+               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
+                       if (pDevice->LedMode == LED_MODE_LINK10 ||
+                           pDevice->WolSpeed == WOL_SPEED_10MB) {
+                               Value32 |= MAC_MODE_LINK_POLARITY;
+                       }
+               } else {
+                       Value32 |= MAC_MODE_LINK_POLARITY;
+               }
+               REG_WR (pDevice, MacCtrl.Mode, Value32);
+               MM_Wait (40);
+               MM_Wait (40);
+               MM_Wait (40);
+
+               /* Always enable magic packet wake-up if we have vaux. */
+               if ((PmeSupport & T3_PCI_PM_CAP_PME_D3COLD) &&
+                   (pDevice->WakeUpModeCap & LM_WAKE_UP_MODE_MAGIC_PACKET)) {
+                       Value32 |= MAC_MODE_DETECT_MAGIC_PACKET_ENABLE;
+               }
+
+               REG_WR (pDevice, MacCtrl.Mode, Value32);
+
+               /* Enable the receiver. */
+               REG_WR (pDevice, MacCtrl.RxMode, RX_MODE_ENABLE);
+       }
+
+       /* Disable tx/rx clocks, and seletect an alternate clock. */
+       if (pDevice->WolSpeed == WOL_SPEED_100MB) {
+               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
+                       Value32 =
+                           T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
+                           T3_PCI_SELECT_ALTERNATE_CLOCK;
+               } else {
+                       Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK;
+               }
+               REG_WR (pDevice, PciCfg.ClockCtrl, Value32);
+
+               MM_Wait (40);
+
+               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
+                       Value32 =
+                           T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
+                           T3_PCI_SELECT_ALTERNATE_CLOCK |
+                           T3_PCI_44MHZ_CORE_CLOCK;
+               } else {
+                       Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK |
+                           T3_PCI_44MHZ_CORE_CLOCK;
+               }
+
+               REG_WR (pDevice, PciCfg.ClockCtrl, Value32);
+
+               MM_Wait (40);
+
+               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
+                       Value32 =
+                           T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
+                           T3_PCI_44MHZ_CORE_CLOCK;
+               } else {
+                       Value32 = T3_PCI_44MHZ_CORE_CLOCK;
+               }
+
+               REG_WR (pDevice, PciCfg.ClockCtrl, Value32);
+       } else {
+               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
+                       Value32 =
+                           T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
+                           T3_PCI_SELECT_ALTERNATE_CLOCK |
+                           T3_PCI_POWER_DOWN_PCI_PLL133;
+               } else {
+                       Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK |
+                           T3_PCI_POWER_DOWN_PCI_PLL133;
+               }
+
+               REG_WR (pDevice, PciCfg.ClockCtrl, Value32);
+       }
+
+       MM_Wait (40);
+
+       if (!pDevice->EepromWp
+           && (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE)) {
+               /* Switch adapter to auxilliary power. */
+               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
+                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
+                       /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
+                       REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
+                       MM_Wait (40);
+               } else {
+                       /* GPIO0 = 0, GPIO1 = 1, GPIO2 = 1. */
+                       REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
+                       MM_Wait (40);
+
+                       /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 1. */
+                       REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
+                       MM_Wait (40);
+
+                       /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
+                       REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
+                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
+                       MM_Wait (40);
+               }
+       }
+
+       /* Set the phy to low power mode. */
+       /* Put the the hardware in low power mode. */
+       MM_WriteConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
+
+       return LM_STATUS_SUCCESS;
+}                              /* LM_SetPowerState */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+static LM_UINT32 GetPhyAdFlowCntrlSettings (PLM_DEVICE_BLOCK pDevice)
+{
+       LM_UINT32 Value32;
+
+       Value32 = 0;
+
+       /* Auto negotiation flow control only when autonegotiation is enabled. */
+       if (pDevice->DisableAutoNeg == FALSE ||
+           pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO ||
+           pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_UTP_AUTO) {
+               /* Please refer to Table 28B-3 of the 802.3ab-1999 spec. */
+               if ((pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE) ||
+                   ((pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)
+                    && (pDevice->
+                        FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE))) {
+                       Value32 |= PHY_AN_AD_PAUSE_CAPABLE;
+               } else if (pDevice->
+                          FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE) {
+                       Value32 |= PHY_AN_AD_ASYM_PAUSE;
+               } else if (pDevice->
+                          FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE) {
+                       Value32 |=
+                           PHY_AN_AD_PAUSE_CAPABLE | PHY_AN_AD_ASYM_PAUSE;
+               }
+       }
+
+       return Value32;
+}
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/*    LM_STATUS_FAILURE                                                       */
+/*    LM_STATUS_SUCCESS                                                       */
+/*                                                                            */
+/******************************************************************************/
+static LM_STATUS
+LM_ForceAutoNegBcm540xPhy (PLM_DEVICE_BLOCK pDevice,
+                          LM_REQUESTED_MEDIA_TYPE RequestedMediaType)
+{
+       LM_MEDIA_TYPE MediaType;
+       LM_LINE_SPEED LineSpeed;
+       LM_DUPLEX_MODE DuplexMode;
+       LM_UINT32 NewPhyCtrl;
+       LM_UINT32 Value32;
+       LM_UINT32 Cnt;
+
+       /* Get the interface type, line speed, and duplex mode. */
+       LM_TranslateRequestedMediaType (RequestedMediaType, &MediaType,
+                                       &LineSpeed, &DuplexMode);
+
+       if (pDevice->RestoreOnWakeUp) {
+               LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG, 0);
+               pDevice->advertising1000 = 0;
+               Value32 = PHY_AN_AD_10BASET_FULL | PHY_AN_AD_10BASET_HALF;
+               if (pDevice->WolSpeed == WOL_SPEED_100MB) {
+                       Value32 |=
+                           PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
+               }
+               Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
+               Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
+               LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
+               pDevice->advertising = Value32;
+       }
+       /* Setup the auto-negotiation advertisement register. */
+       else if (LineSpeed == LM_LINE_SPEED_UNKNOWN) {
+               /* Setup the 10/100 Mbps auto-negotiation advertisement register. */
+               Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
+                   PHY_AN_AD_10BASET_HALF | PHY_AN_AD_10BASET_FULL |
+                   PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
+               Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
+
+               LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
+               pDevice->advertising = Value32;
+
+               /* Advertise 1000Mbps */
+               Value32 =
+                   BCM540X_AN_AD_1000BASET_HALF | BCM540X_AN_AD_1000BASET_FULL;
+
+#if INCLUDE_5701_AX_FIX
+               /* Bug: workaround for CRC error in gigabit mode when we are in */
+               /* slave mode.  This will force the PHY to operate in */
+               /* master mode. */
+               if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
+                   pDevice->ChipRevId == T3_CHIP_ID_5701_B0) {
+                       Value32 |= BCM540X_CONFIG_AS_MASTER |
+                           BCM540X_ENABLE_CONFIG_AS_MASTER;
+               }
+#endif
+
+               LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
+               pDevice->advertising1000 = Value32;
+       } else {
+               if (LineSpeed == LM_LINE_SPEED_1000MBPS) {
+                       Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
+                       Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
+
+                       LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
+                       pDevice->advertising = Value32;
+
+                       if (DuplexMode != LM_DUPLEX_MODE_FULL) {
+                               Value32 = BCM540X_AN_AD_1000BASET_HALF;
+                       } else {
+                               Value32 = BCM540X_AN_AD_1000BASET_FULL;
+                       }
+
+                       LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG,
+                                    Value32);
+                       pDevice->advertising1000 = Value32;
+               } else if (LineSpeed == LM_LINE_SPEED_100MBPS) {
+                       LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG, 0);
+                       pDevice->advertising1000 = 0;
+
+                       if (DuplexMode != LM_DUPLEX_MODE_FULL) {
+                               Value32 = PHY_AN_AD_100BASETX_HALF;
+                       } else {
+                               Value32 = PHY_AN_AD_100BASETX_FULL;
+                       }
+
+                       Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
+                       Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
+
+                       LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
+                       pDevice->advertising = Value32;
+               } else if (LineSpeed == LM_LINE_SPEED_10MBPS) {
+                       LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG, 0);
+                       pDevice->advertising1000 = 0;
+
+                       if (DuplexMode != LM_DUPLEX_MODE_FULL) {
+                               Value32 = PHY_AN_AD_10BASET_HALF;
+                       } else {
+                               Value32 = PHY_AN_AD_10BASET_FULL;
+                       }
+
+                       Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
+                       Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
+
+                       LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
+                       pDevice->advertising = Value32;
+               }
+       }
+
+       /* Force line speed if auto-negotiation is disabled. */
+       if (pDevice->DisableAutoNeg && LineSpeed != LM_LINE_SPEED_UNKNOWN) {
+               /* This code path is executed only when there is link. */
+               pDevice->MediaType = MediaType;
+               pDevice->LineSpeed = LineSpeed;
+               pDevice->DuplexMode = DuplexMode;
+
+               /* Force line seepd. */
+               NewPhyCtrl = 0;
+               switch (LineSpeed) {
+               case LM_LINE_SPEED_10MBPS:
+                       NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_10MBPS;
+                       break;
+               case LM_LINE_SPEED_100MBPS:
+                       NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_100MBPS;
+                       break;
+               case LM_LINE_SPEED_1000MBPS:
+                       NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
+                       break;
+               default:
+                       NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
+                       break;
+               }
+
+               if (DuplexMode == LM_DUPLEX_MODE_FULL) {
+                       NewPhyCtrl |= PHY_CTRL_FULL_DUPLEX_MODE;
+               }
+
+               /* Don't do anything if the PHY_CTRL is already what we wanted. */
+               LM_ReadPhy (pDevice, PHY_CTRL_REG, &Value32);
+               if (Value32 != NewPhyCtrl) {
+                       /* Temporary bring the link down before forcing line speed. */
+                       LM_WritePhy (pDevice, PHY_CTRL_REG,
+                                    PHY_CTRL_LOOPBACK_MODE);
+
+                       /* Wait for link to go down. */
+                       for (Cnt = 0; Cnt < 15000; Cnt++) {
+                               MM_Wait (10);
+
+                               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
+                               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
+
+                               if (!(Value32 & PHY_STATUS_LINK_PASS)) {
+                                       MM_Wait (40);
+                                       break;
+                               }
+                       }
+
+                       LM_WritePhy (pDevice, PHY_CTRL_REG, NewPhyCtrl);
+                       MM_Wait (40);
+               }
+       } else {
+               LM_WritePhy (pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
+                            PHY_CTRL_RESTART_AUTO_NEG);
+       }
+
+       return LM_STATUS_SUCCESS;
+}                              /* LM_ForceAutoNegBcm540xPhy */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+static LM_STATUS
+LM_ForceAutoNeg (PLM_DEVICE_BLOCK pDevice,
+                LM_REQUESTED_MEDIA_TYPE RequestedMediaType)
+{
+       LM_STATUS LmStatus;
+
+       /* Initialize the phy chip. */
+       switch (pDevice->PhyId & PHY_ID_MASK) {
+       case PHY_BCM5400_PHY_ID:
+       case PHY_BCM5401_PHY_ID:
+       case PHY_BCM5411_PHY_ID:
+       case PHY_BCM5701_PHY_ID:
+       case PHY_BCM5703_PHY_ID:
+       case PHY_BCM5704_PHY_ID:
+               LmStatus =
+                   LM_ForceAutoNegBcm540xPhy (pDevice, RequestedMediaType);
+               break;
+
+       default:
+               LmStatus = LM_STATUS_FAILURE;
+               break;
+       }
+
+       return LmStatus;
+}                              /* LM_ForceAutoNeg */
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+LM_STATUS LM_LoadFirmware (PLM_DEVICE_BLOCK pDevice,
+                          PT3_FWIMG_INFO pFwImg,
+                          LM_UINT32 LoadCpu, LM_UINT32 StartCpu)
+{
+       LM_UINT32 i;
+       LM_UINT32 address;
+
+       if (LoadCpu & T3_RX_CPU_ID) {
+               if (LM_HaltCpu (pDevice, T3_RX_CPU_ID) != LM_STATUS_SUCCESS) {
+                       return LM_STATUS_FAILURE;
+               }
+
+               /* First of all clear scrach pad memory */
+               for (i = 0; i < T3_RX_CPU_SPAD_SIZE; i += 4) {
+                       LM_RegWrInd (pDevice, T3_RX_CPU_SPAD_ADDR + i, 0);
+               }
+
+               /* Copy code first */
+               address = T3_RX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
+               for (i = 0; i <= pFwImg->Text.Length; i += 4) {
+                       LM_RegWrInd (pDevice, address + i,
+                                    ((LM_UINT32 *) pFwImg->Text.Buffer)[i /
+                                                                        4]);
+               }
+
+               address =
+                   T3_RX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
+               for (i = 0; i <= pFwImg->ROnlyData.Length; i += 4) {
+                       LM_RegWrInd (pDevice, address + i,
+                                    ((LM_UINT32 *) pFwImg->ROnlyData.
+                                     Buffer)[i / 4]);
+               }
+
+               address = T3_RX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
+               for (i = 0; i <= pFwImg->Data.Length; i += 4) {
+                       LM_RegWrInd (pDevice, address + i,
+                                    ((LM_UINT32 *) pFwImg->Data.Buffer)[i /
+                                                                        4]);
+               }
+       }
+
+       if (LoadCpu & T3_TX_CPU_ID) {
+               if (LM_HaltCpu (pDevice, T3_TX_CPU_ID) != LM_STATUS_SUCCESS) {
+                       return LM_STATUS_FAILURE;
+               }
+
+               /* First of all clear scrach pad memory */
+               for (i = 0; i < T3_TX_CPU_SPAD_SIZE; i += 4) {
+                       LM_RegWrInd (pDevice, T3_TX_CPU_SPAD_ADDR + i, 0);
+               }
+
+               /* Copy code first */
+               address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
+               for (i = 0; i <= pFwImg->Text.Length; i += 4) {
+                       LM_RegWrInd (pDevice, address + i,
+                                    ((LM_UINT32 *) pFwImg->Text.Buffer)[i /
+                                                                        4]);
+               }
+
+               address =
+                   T3_TX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
+               for (i = 0; i <= pFwImg->ROnlyData.Length; i += 4) {
+                       LM_RegWrInd (pDevice, address + i,
+                                    ((LM_UINT32 *) pFwImg->ROnlyData.
+                                     Buffer)[i / 4]);
+               }
+
+               address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
+               for (i = 0; i <= pFwImg->Data.Length; i += 4) {
+                       LM_RegWrInd (pDevice, address + i,
+                                    ((LM_UINT32 *) pFwImg->Data.Buffer)[i /
+                                                                        4]);
+               }
+       }
+
+       if (StartCpu & T3_RX_CPU_ID) {
+               /* Start Rx CPU */
+               REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
+               REG_WR (pDevice, rxCpu.reg.PC, pFwImg->StartAddress);
+               for (i = 0; i < 5; i++) {
+                       if (pFwImg->StartAddress ==
+                           REG_RD (pDevice, rxCpu.reg.PC))
+                               break;
+
+                       REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
+                       REG_WR (pDevice, rxCpu.reg.mode, CPU_MODE_HALT);
+                       REG_WR (pDevice, rxCpu.reg.PC, pFwImg->StartAddress);
+                       MM_Wait (1000);
+               }
+
+               REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
+               REG_WR (pDevice, rxCpu.reg.mode, 0);
+       }
+
+       if (StartCpu & T3_TX_CPU_ID) {
+               /* Start Tx CPU */
+               REG_WR (pDevice, txCpu.reg.state, 0xffffffff);
+               REG_WR (pDevice, txCpu.reg.PC, pFwImg->StartAddress);
+               for (i = 0; i < 5; i++) {
+                       if (pFwImg->StartAddress ==
+                           REG_RD (pDevice, txCpu.reg.PC))
+                               break;
+
+                       REG_WR (pDevice, txCpu.reg.state, 0xffffffff);
+                       REG_WR (pDevice, txCpu.reg.mode, CPU_MODE_HALT);
+                       REG_WR (pDevice, txCpu.reg.PC, pFwImg->StartAddress);
+                       MM_Wait (1000);
+               }
+
+               REG_WR (pDevice, txCpu.reg.state, 0xffffffff);
+               REG_WR (pDevice, txCpu.reg.mode, 0);
+       }
+
+       return LM_STATUS_SUCCESS;
+}
+
+STATIC LM_STATUS LM_HaltCpu (PLM_DEVICE_BLOCK pDevice, LM_UINT32 cpu_number)
+{
+       LM_UINT32 i;
+
+       if (cpu_number == T3_RX_CPU_ID) {
+               for (i = 0; i < 10000; i++) {
+                       REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
+                       REG_WR (pDevice, rxCpu.reg.mode, CPU_MODE_HALT);
+
+                       if (REG_RD (pDevice, rxCpu.reg.mode) & CPU_MODE_HALT)
+                               break;
+               }
+
+               REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
+               REG_WR (pDevice, rxCpu.reg.mode, CPU_MODE_HALT);
+               MM_Wait (10);
+       } else {
+               for (i = 0; i < 10000; i++) {
+                       REG_WR (pDevice, txCpu.reg.state, 0xffffffff);
+                       REG_WR (pDevice, txCpu.reg.mode, CPU_MODE_HALT);
+
+                       if (REG_RD (pDevice, txCpu.reg.mode) & CPU_MODE_HALT)
+                               break;
+               }
+       }
+
+       return ((i == 10000) ? LM_STATUS_FAILURE : LM_STATUS_SUCCESS);
+}
+
+int LM_BlinkLED (PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlinkDurationSec)
+{
+       LM_UINT32 Oldcfg;
+       int j;
+       int ret = 0;
+
+       if (BlinkDurationSec == 0) {
+               return 0;
+       }
+       if (BlinkDurationSec > 120) {
+               BlinkDurationSec = 120;
+       }
+
+       Oldcfg = REG_RD (pDevice, MacCtrl.LedCtrl);
+       for (j = 0; j < BlinkDurationSec * 2; j++) {
+               if (j % 2) {
+                       /* Turn on the LEDs. */
+                       REG_WR (pDevice, MacCtrl.LedCtrl,
+                               LED_CTRL_OVERRIDE_LINK_LED |
+                               LED_CTRL_1000MBPS_LED_ON |
+                               LED_CTRL_100MBPS_LED_ON |
+                               LED_CTRL_10MBPS_LED_ON |
+                               LED_CTRL_OVERRIDE_TRAFFIC_LED |
+                               LED_CTRL_BLINK_TRAFFIC_LED |
+                               LED_CTRL_TRAFFIC_LED);
+               } else {
+                       /* Turn off the LEDs. */
+                       REG_WR (pDevice, MacCtrl.LedCtrl,
+                               LED_CTRL_OVERRIDE_LINK_LED |
+                               LED_CTRL_OVERRIDE_TRAFFIC_LED);
+               }
+
+#ifndef EMBEDDED
+               current->state = TASK_INTERRUPTIBLE;
+               if (schedule_timeout (HZ / 2) != 0) {
+                       ret = -EINTR;
+                       break;
+               }
+#else
+               udelay (100000);        /* 1s sleep */
+#endif
+       }
+       REG_WR (pDevice, MacCtrl.LedCtrl, Oldcfg);
+       return ret;
+}
+
+int t3_do_dma (PLM_DEVICE_BLOCK pDevice,
+              LM_PHYSICAL_ADDRESS host_addr_phy, int length, int dma_read)
+{
+       T3_DMA_DESC dma_desc;
+       int i;
+       LM_UINT32 dma_desc_addr;
+       LM_UINT32 value32;
+
+       REG_WR (pDevice, BufMgr.Mode, 0);
+       REG_WR (pDevice, Ftq.Reset, 0);
+
+       dma_desc.host_addr.High = host_addr_phy.High;
+       dma_desc.host_addr.Low = host_addr_phy.Low;
+       dma_desc.nic_mbuf = 0x2100;
+       dma_desc.len = length;
+       dma_desc.flags = 0x00000004;    /* Generate Rx-CPU event */
+
+       if (dma_read) {
+               dma_desc.cqid_sqid = (T3_QID_RX_BD_COMP << 8) |
+                   T3_QID_DMA_HIGH_PRI_READ;
+               REG_WR (pDevice, DmaRead.Mode, DMA_READ_MODE_ENABLE);
+       } else {
+               dma_desc.cqid_sqid = (T3_QID_RX_DATA_COMP << 8) |
+                   T3_QID_DMA_HIGH_PRI_WRITE;
+               REG_WR (pDevice, DmaWrite.Mode, DMA_WRITE_MODE_ENABLE);
+       }
+
+       dma_desc_addr = T3_NIC_DMA_DESC_POOL_ADDR;
+
+       /* Writing this DMA descriptor to DMA memory */
+       for (i = 0; i < sizeof (T3_DMA_DESC); i += 4) {
+               value32 = *((PLM_UINT32) (((PLM_UINT8) & dma_desc) + i));
+               MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG,
+                                 dma_desc_addr + i);
+               MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_DATA_REG,
+                                 cpu_to_le32 (value32));
+       }
+       MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG, 0);
+
+       if (dma_read)
+               REG_WR (pDevice, Ftq.DmaHighReadFtqFifoEnqueueDequeue,
+                       dma_desc_addr);
+       else
+               REG_WR (pDevice, Ftq.DmaHighWriteFtqFifoEnqueueDequeue,
+                       dma_desc_addr);
+
+       for (i = 0; i < 40; i++) {
+               if (dma_read)
+                       value32 =
+                           REG_RD (pDevice,
+                                   Ftq.RcvBdCompFtqFifoEnqueueDequeue);
+               else
+                       value32 =
+                           REG_RD (pDevice,
+                                   Ftq.RcvDataCompFtqFifoEnqueueDequeue);
+
+               if ((value32 & 0xffff) == dma_desc_addr)
+                       break;
+
+               MM_Wait (10);
+       }
+
+       return LM_STATUS_SUCCESS;
+}
+
+STATIC LM_STATUS
+LM_DmaTest (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
+           LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize)
+{
+       int j;
+       LM_UINT32 *ptr;
+       int dma_success = 0;
+
+       if (T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
+           T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5701) {
+               return LM_STATUS_SUCCESS;
+       }
+       while (!dma_success) {
+               /* Fill data with incremental patterns */
+               ptr = (LM_UINT32 *) pBufferVirt;
+               for (j = 0; j < BufferSize / 4; j++)
+                       *ptr++ = j;
+
+               if (t3_do_dma (pDevice, BufferPhy, BufferSize, 1) ==
+                   LM_STATUS_FAILURE) {
+                       return LM_STATUS_FAILURE;
+               }
+
+               MM_Wait (40);
+               ptr = (LM_UINT32 *) pBufferVirt;
+               /* Fill data with zero */
+               for (j = 0; j < BufferSize / 4; j++)
+                       *ptr++ = 0;
+
+               if (t3_do_dma (pDevice, BufferPhy, BufferSize, 0) ==
+                   LM_STATUS_FAILURE) {
+                       return LM_STATUS_FAILURE;
+               }
+
+               MM_Wait (40);
+               /* Check for data */
+               ptr = (LM_UINT32 *) pBufferVirt;
+               for (j = 0; j < BufferSize / 4; j++) {
+                       if (*ptr++ != j) {
+                               if ((pDevice->
+                                    DmaReadWriteCtrl &
+                                    DMA_CTRL_WRITE_BOUNDARY_MASK)
+                                   == DMA_CTRL_WRITE_BOUNDARY_DISABLE) {
+                                       pDevice->DmaReadWriteCtrl =
+                                           (pDevice->
+                                            DmaReadWriteCtrl &
+                                            ~DMA_CTRL_WRITE_BOUNDARY_MASK) |
+                                           DMA_CTRL_WRITE_BOUNDARY_16;
+                                       REG_WR (pDevice,
+                                               PciCfg.DmaReadWriteCtrl,
+                                               pDevice->DmaReadWriteCtrl);
+                                       break;
+                               } else {
+                                       return LM_STATUS_FAILURE;
+                               }
+                       }
+               }
+               if (j == (BufferSize / 4))
+                       dma_success = 1;
+       }
+       return LM_STATUS_SUCCESS;
+}
+
+#endif
diff --git a/drivers/net/tigon3.h b/drivers/net/tigon3.h
new file mode 100644 (file)
index 0000000..c03347f
--- /dev/null
@@ -0,0 +1,3339 @@
+
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/*                                                                            */
+/******************************************************************************/
+
+#ifndef TIGON3_H
+#define TIGON3_H
+
+#include "bcm570x_lm.h"
+#if INCLUDE_TBI_SUPPORT
+#include "bcm570x_autoneg.h"
+#endif
+
+/* io defines */
+#if !defined(BIG_ENDIAN_HOST)
+#define readl(addr) \
+             (LONGSWAP((*(volatile unsigned int *)(addr))))
+#define writel(b,addr) \
+             ((*(volatile unsigned int *)(addr)) = (LONGSWAP(b)))
+#else
+#if 0                          /* !defined(PPC603) */
+#define readl(addr) (*(volatile unsigned int*)(0xa0000000 + (unsigned long)(addr)))
+#define writel(b,addr) ((*(volatile unsigned int *) ((unsigned long)(addr) + 0xa0000000)) = (b))
+#else
+#if 1
+#define readl(addr) (*(volatile unsigned int*)(addr))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+#else
+extern int sprintf (char *buf, const char *f, ...);
+static __inline unsigned int readl (void *addr)
+{
+       char buf[128];
+       unsigned int tmp = (*(volatile unsigned int *)(addr));
+       sprintf (buf, "%s:%s: read 0x%x from 0x%x\n", __FILE__, __LINE__, tmp,
+                addr, 0, 0);
+       sysSerialPrintString (buf);
+       return tmp;
+}
+static __inline void writel (unsigned int b, unsigned int addr)
+{
+       char buf[128];
+       ((*(volatile unsigned int *)(addr)) = (b));
+       sprintf (buf, "%s:%s: write 0x%x to 0x%x\n", __FILE__, __LINE__, b,
+                addr, 0, 0);
+       sysSerialPrintString (buf);
+}
+#endif
+#endif                         /* PPC603 */
+#endif
+
+/******************************************************************************/
+/* Constants. */
+/******************************************************************************/
+
+/* Maxim number of packet descriptors used for sending packets. */
+#define MAX_TX_PACKET_DESC_COUNT            600
+#define DEFAULT_TX_PACKET_DESC_COUNT        2
+
+/* Maximum number of packet descriptors used for receiving packets. */
+#if T3_JUMBO_RCB_ENTRY_COUNT
+#define MAX_RX_PACKET_DESC_COUNT                                            \
+    (T3_STD_RCV_RCB_ENTRY_COUNT + T3_JUMBO_RCV_RCB_ENTRY_COUNT)
+#else
+#define MAX_RX_PACKET_DESC_COUNT            800
+#endif
+#define DEFAULT_RX_PACKET_DESC_COUNT        2
+
+/* Threshhold for double copying small tx packets.  0 will disable double */
+/* copying of small Tx packets. */
+#define DEFAULT_TX_COPY_BUFFER_SIZE         0
+#define MIN_TX_COPY_BUFFER_SIZE             64
+#define MAX_TX_COPY_BUFFER_SIZE             512
+
+/* Cache line. */
+#define COMMON_CACHE_LINE_SIZE              0x20
+#define COMMON_CACHE_LINE_MASK              (COMMON_CACHE_LINE_SIZE-1)
+
+/* Maximum number of fragment we can handle. */
+#ifndef MAX_FRAGMENT_COUNT
+#define MAX_FRAGMENT_COUNT                  32
+#endif
+
+/* B0 bug. */
+#define BCM5700_BX_MIN_FRAG_SIZE            10
+#define BCM5700_BX_MIN_FRAG_BUF_SIZE        16 /* nice aligned size. */
+#define BCM5700_BX_MIN_FRAG_BUF_SIZE_MASK   (BCM5700_BX_MIN_FRAG_BUF_SIZE-1)
+#define BCM5700_BX_TX_COPY_BUF_SIZE         (BCM5700_BX_MIN_FRAG_BUF_SIZE * \
+                                           MAX_FRAGMENT_COUNT)
+
+/* MAGIC number. */
+/* #define T3_MAGIC_NUM                        'KevT' */
+#define T3_FIRMWARE_MAILBOX                0x0b50
+#define T3_MAGIC_NUM                       0x4B657654
+#define T3_MAGIC_NUM_DISABLE_DMAW_ON_LINK_CHANGE 0x4861764b
+
+#define T3_NIC_DATA_SIG_ADDR               0x0b54
+#define T3_NIC_DATA_SIG                    0x4b657654
+
+#define T3_NIC_DATA_NIC_CFG_ADDR           0x0b58
+#define T3_NIC_CFG_LED_MODE_UNKNOWN        BIT_NONE
+#define T3_NIC_CFG_LED_MODE_TRIPLE_SPEED   BIT_2
+#define T3_NIC_CFG_LED_MODE_LINK_SPEED     BIT_3
+#define T3_NIC_CFG_LED_MODE_OPEN_DRAIN     BIT_2
+#define T3_NIC_CFG_LED_MODE_OUTPUT         BIT_3
+#define T3_NIC_CFG_LED_MODE_MASK           (BIT_2 | BIT_3)
+#define T3_NIC_CFG_PHY_TYPE_UNKNOWN         BIT_NONE
+#define T3_NIC_CFG_PHY_TYPE_COPPER          BIT_4
+#define T3_NIC_CFG_PHY_TYPE_FIBER           BIT_5
+#define T3_NIC_CFG_PHY_TYPE_MASK            (BIT_4 | BIT_5)
+#define T3_NIC_CFG_ENABLE_WOL               BIT_6
+#define T3_NIC_CFG_ENABLE_ASF               BIT_7
+#define T3_NIC_EEPROM_WP                    BIT_8
+
+#define T3_NIC_DATA_PHY_ID_ADDR            0x0b74
+#define T3_NIC_PHY_ID1_MASK                0xffff0000
+#define T3_NIC_PHY_ID2_MASK                0x0000ffff
+
+#define T3_CMD_MAILBOX                      0x0b78
+#define T3_CMD_NICDRV_ALIVE                 0x01
+#define T3_CMD_NICDRV_PAUSE_FW              0x02
+#define T3_CMD_NICDRV_IPV4ADDR_CHANGE       0x03
+#define T3_CMD_NICDRV_IPV6ADDR_CHANGE       0x04
+#define T3_CMD_5703A0_FIX_DMAFW_DMAR        0x05
+#define T3_CMD_5703A0_FIX_DMAFW_DMAW        0x06
+
+#define T3_CMD_LENGTH_MAILBOX               0x0b7c
+#define T3_CMD_DATA_MAILBOX                 0x0b80
+
+#define T3_ASF_FW_STATUS_MAILBOX            0x0c00
+
+#define T3_DRV_STATE_MAILBOX                0x0c04
+#define T3_DRV_STATE_START                  0x01
+#define T3_DRV_STATE_UNLOAD                 0x02
+#define T3_DRV_STATE_WOL                    0x03
+#define T3_DRV_STATE_SUSPEND                0x04
+
+#define T3_FW_RESET_TYPE_MAILBOX            0x0c08
+
+#define T3_MAC_ADDR_HIGH_MAILBOX            0x0c14
+#define T3_MAC_ADDR_LOW_MAILBOX             0x0c18
+
+/******************************************************************************/
+/* Hardware constants. */
+/******************************************************************************/
+
+/* Number of entries in the send ring:  must be 512. */
+#define T3_SEND_RCB_ENTRY_COUNT             512
+#define T3_SEND_RCB_ENTRY_COUNT_MASK        (T3_SEND_RCB_ENTRY_COUNT-1)
+
+/* Number of send RCBs.  May be 1-16 but for now, only support one. */
+#define T3_MAX_SEND_RCB_COUNT               16
+
+/* Number of entries in the Standard Receive RCB.  Must be 512 entries. */
+#define T3_STD_RCV_RCB_ENTRY_COUNT          512
+#define T3_STD_RCV_RCB_ENTRY_COUNT_MASK     (T3_STD_RCV_RCB_ENTRY_COUNT-1)
+#define DEFAULT_STD_RCV_DESC_COUNT          200        /* Must be < 512. */
+#define MAX_STD_RCV_BUFFER_SIZE             0x600
+
+/* Number of entries in the Mini Receive RCB.  This value can either be */
+/* 0, 1024.  Currently Mini Receive RCB is disabled. */
+#ifndef T3_MINI_RCV_RCB_ENTRY_COUNT
+#define T3_MINI_RCV_RCB_ENTRY_COUNT         0
+#endif                         /* T3_MINI_RCV_RCB_ENTRY_COUNT */
+#define T3_MINI_RCV_RCB_ENTRY_COUNT_MASK    (T3_MINI_RCV_RCB_ENTRY_COUNT-1)
+#define MAX_MINI_RCV_BUFFER_SIZE            512
+#define DEFAULT_MINI_RCV_BUFFER_SIZE        64
+#define DEFAULT_MINI_RCV_DESC_COUNT         100        /* Must be < 1024. */
+
+/* Number of entries in the Jumbo Receive RCB.  This value must 256 or 0. */
+/* Currently, Jumbo Receive RCB is disabled. */
+#ifndef T3_JUMBO_RCV_RCB_ENTRY_COUNT
+#define T3_JUMBO_RCV_RCB_ENTRY_COUNT        0
+#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+#define T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK   (T3_JUMBO_RCV_RCB_ENTRY_COUNT-1)
+
+#define MAX_JUMBO_RCV_BUFFER_SIZE           (10 * 1024)        /* > 1514 */
+#define DEFAULT_JUMBO_RCV_BUFFER_SIZE       (4 * 1024) /* > 1514 */
+#define DEFAULT_JUMBO_RCV_DESC_COUNT        128        /* Must be < 256. */
+
+#define MAX_JUMBO_TX_BUFFER_SIZE            (8 * 1024) /* > 1514 */
+#define DEFAULT_JUMBO_TX_BUFFER_SIZE        (4 * 1024) /* > 1514 */
+
+/* Number of receive return RCBs.  Maybe 1-16 but for now, only support one. */
+#define T3_MAX_RCV_RETURN_RCB_COUNT         16
+
+/* Number of entries in a Receive Return ring.  This value is either 1024 */
+/* or 2048. */
+#ifndef T3_RCV_RETURN_RCB_ENTRY_COUNT
+#define T3_RCV_RETURN_RCB_ENTRY_COUNT       1024
+#endif                         /* T3_RCV_RETURN_RCB_ENTRY_COUNT */
+#define T3_RCV_RETURN_RCB_ENTRY_COUNT_MASK  (T3_RCV_RETURN_RCB_ENTRY_COUNT-1)
+
+/* Default coalescing parameters. */
+#define DEFAULT_RX_COALESCING_TICKS         100
+#define MAX_RX_COALESCING_TICKS             500
+#define DEFAULT_TX_COALESCING_TICKS         400
+#define MAX_TX_COALESCING_TICKS             500
+#define DEFAULT_RX_MAX_COALESCED_FRAMES     10
+#define MAX_RX_MAX_COALESCED_FRAMES         100
+#define ADAPTIVE_LO_RX_MAX_COALESCED_FRAMES    5
+#define ADAPTIVE_HI_RX_MAX_COALESCED_FRAMES    42
+#define ADAPTIVE_LO_RX_COALESCING_TICKS         50
+#define ADAPTIVE_HI_RX_COALESCING_TICKS         300
+#define ADAPTIVE_LO_PKT_THRESH              30000
+#define ADAPTIVE_HI_PKT_THRESH              74000
+#define DEFAULT_TX_MAX_COALESCED_FRAMES     40
+#define ADAPTIVE_LO_TX_MAX_COALESCED_FRAMES    25
+#define ADAPTIVE_HI_TX_MAX_COALESCED_FRAMES    75
+#define MAX_TX_MAX_COALESCED_FRAMES         100
+
+#define DEFAULT_RX_COALESCING_TICKS_DURING_INT          25
+#define DEFAULT_TX_COALESCING_TICKS_DURING_INT          25
+#define DEFAULT_RX_MAX_COALESCED_FRAMES_DURING_INT      5
+#define DEFAULT_TX_MAX_COALESCED_FRAMES_DURING_INT      5
+
+#define BAD_DEFAULT_VALUE                               0xffffffff
+
+#define DEFAULT_STATS_COALESCING_TICKS      1000000
+#define MAX_STATS_COALESCING_TICKS          3600000000U
+
+/* Receive BD Replenish thresholds. */
+#define DEFAULT_RCV_STD_BD_REPLENISH_THRESHOLD      4
+#define DEFAULT_RCV_JUMBO_BD_REPLENISH_THRESHOLD    4
+
+#define SPLIT_MODE_DISABLE                          0
+#define SPLIT_MODE_ENABLE                           1
+
+#define SPLIT_MODE_5704_MAX_REQ                     3
+
+/* Maximum physical fragment size. */
+#define MAX_FRAGMENT_SIZE                   (64 * 1024)
+
+/* Standard view. */
+#define T3_STD_VIEW_SIZE                    (64 * 1024)
+#define T3_FLAT_VIEW_SIZE                   (32 * 1024 * 1024)
+
+/* Buffer descriptor base address on the NIC's memory. */
+
+#define T3_NIC_SND_BUFFER_DESC_ADDR         0x4000
+#define T3_NIC_STD_RCV_BUFFER_DESC_ADDR     0x6000
+#define T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR   0x7000
+
+#define T3_NIC_STD_RCV_BUFFER_DESC_ADDR_EXT_MEM     0xc000
+#define T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR_EXT_MEM   0xd000
+#define T3_NIC_MINI_RCV_BUFFER_DESC_ADDR_EXT_MEM    0xe000
+
+#define T3_NIC_SND_BUFFER_DESC_SIZE         (T3_SEND_RCB_ENTRY_COUNT * \
+                                           sizeof(T3_SND_BD) / 4)
+
+#define T3_NIC_STD_RCV_BUFFER_DESC_SIZE     (T3_STD_RCV_RCB_ENTRY_COUNT * \
+                                           sizeof(T3_RCV_BD) / 4)
+
+#define T3_NIC_JUMBO_RCV_BUFFER_DESC_SIZE   (T3_JUMBO_RCV_RCB_ENTRY_COUNT * \
+                                           sizeof(T3_EXT_RCV_BD) / 4)
+
+/* MBUF pool. */
+#define T3_NIC_MBUF_POOL_ADDR               0x8000
+/* #define T3_NIC_MBUF_POOL_SIZE               0x18000 */
+#define T3_NIC_MBUF_POOL_SIZE96             0x18000
+#define T3_NIC_MBUF_POOL_SIZE64             0x10000
+
+#define T3_NIC_MBUF_POOL_ADDR_EXT_MEM       0x20000
+
+/* DMA descriptor pool */
+#define T3_NIC_DMA_DESC_POOL_ADDR           0x2000
+#define T3_NIC_DMA_DESC_POOL_SIZE           0x2000     /* 8KB. */
+
+#define T3_DEF_DMA_MBUF_LOW_WMARK           0x40
+#define T3_DEF_RX_MAC_MBUF_LOW_WMARK        0x20
+#define T3_DEF_MBUF_HIGH_WMARK              0x60
+
+#define T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO     304
+#define T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO  152
+#define T3_DEF_MBUF_HIGH_WMARK_JUMBO        380
+
+#define T3_DEF_DMA_DESC_LOW_WMARK           5
+#define T3_DEF_DMA_DESC_HIGH_WMARK          10
+
+/* Maximum size of giant TCP packet can be sent */
+#define T3_TCP_SEG_MAX_OFFLOAD_SIZE         64*1000
+#define T3_TCP_SEG_MIN_NUM_SEG              20
+
+#define T3_RX_CPU_ID    0x1
+#define T3_TX_CPU_ID    0x2
+#define T3_RX_CPU_SPAD_ADDR  0x30000
+#define T3_RX_CPU_SPAD_SIZE  0x4000
+#define T3_TX_CPU_SPAD_ADDR  0x34000
+#define T3_TX_CPU_SPAD_SIZE  0x4000
+
+typedef struct T3_DIR_ENTRY {
+       PLM_UINT8 Buffer;
+       LM_UINT32 Offset;
+       LM_UINT32 Length;
+} T3_DIR_ENTRY, *PT3_DIR_ENTRY;
+
+typedef struct T3_FWIMG_INFO {
+       LM_UINT32 StartAddress;
+       T3_DIR_ENTRY Text;
+       T3_DIR_ENTRY ROnlyData;
+       T3_DIR_ENTRY Data;
+       T3_DIR_ENTRY Sbss;
+       T3_DIR_ENTRY Bss;
+} T3_FWIMG_INFO, *PT3_FWIMG_INFO;
+
+/******************************************************************************/
+/* Tigon3 PCI Registers. */
+/******************************************************************************/
+#define T3_PCI_ID_BCM5700                   0x164414e4
+#define T3_PCI_ID_BCM5701                   0x164514e4
+#define T3_PCI_ID_BCM5702                   0x164614e4
+#define T3_PCI_ID_BCM5702x                  0x16A614e4
+#define T3_PCI_ID_BCM5703                   0x164714e4
+#define T3_PCI_ID_BCM5703x                  0x16A714e4
+#define T3_PCI_ID_BCM5702FE                 0x164D14e4
+#define T3_PCI_ID_BCM5704                   0x164814e4
+
+#define T3_PCI_VENDOR_ID                    (T3_PCI_ID & 0xffff)
+#define T3_PCI_DEVICE_ID                    (T3_PCI_ID >> 16)
+
+#define T3_PCI_MISC_HOST_CTRL_REG           0x68
+
+/* The most significant 16bit of register 0x68. */
+/* ChipId:4, ChipRev:4, MetalRev:8 */
+#define T3_CHIP_ID_5700_A0                  0x7000
+#define T3_CHIP_ID_5700_A1                  0x7001
+#define T3_CHIP_ID_5700_B0                  0x7100
+#define T3_CHIP_ID_5700_B1                  0x7101
+#define T3_CHIP_ID_5700_C0                  0x7200
+
+#define T3_CHIP_ID_5701_A0                  0x0000
+#define T3_CHIP_ID_5701_B0                  0x0100
+#define T3_CHIP_ID_5701_B2                  0x0102
+#define T3_CHIP_ID_5701_B5                  0x0105
+
+#define T3_CHIP_ID_5703_A0                  0x1000
+#define T3_CHIP_ID_5703_A1                  0x1001
+#define T3_CHIP_ID_5703_A2                  0x1002
+
+#define T3_CHIP_ID_5704_A0                  0x2000
+
+/* Chip Id. */
+#define T3_ASIC_REV(_ChipRevId)             ((_ChipRevId) >> 12)
+#define T3_ASIC_REV_5700                    0x07
+#define T3_ASIC_REV_5701                    0x00
+#define T3_ASIC_REV_5703                    0x01
+#define T3_ASIC_REV_5704                    0x02
+
+/* Chip id and revision. */
+#define T3_CHIP_REV(_ChipRevId)             ((_ChipRevId) >> 8)
+#define T3_CHIP_REV_5700_AX                 0x70
+#define T3_CHIP_REV_5700_BX                 0x71
+#define T3_CHIP_REV_5700_CX                 0x72
+#define T3_CHIP_REV_5701_AX                 0x00
+
+/* Metal revision. */
+#define T3_METAL_REV(_ChipRevId)            ((_ChipRevId) & 0xff)
+#define T3_METAL_REV_A0                     0x00
+#define T3_METAL_REV_A1                     0x01
+#define T3_METAL_REV_B0                     0x00
+#define T3_METAL_REV_B1                     0x01
+#define T3_METAL_REV_B2                     0x02
+
+#define T3_PCI_REG_CLOCK_CTRL               0x74
+
+#define T3_PCI_DISABLE_RX_CLOCK             BIT_10
+#define T3_PCI_DISABLE_TX_CLOCK             BIT_11
+#define T3_PCI_SELECT_ALTERNATE_CLOCK       BIT_12
+#define T3_PCI_POWER_DOWN_PCI_PLL133        BIT_15
+#define T3_PCI_44MHZ_CORE_CLOCK             BIT_18
+
+#define T3_PCI_REG_ADDR_REG                 0x78
+#define T3_PCI_REG_DATA_REG                 0x80
+
+#define T3_PCI_MEM_WIN_ADDR_REG             0x7c
+#define T3_PCI_MEM_WIN_DATA_REG             0x84
+
+#define T3_PCI_PM_CAP_REG                   0x48
+
+#define T3_PCI_PM_CAP_PME_D3COLD            BIT_31
+#define T3_PCI_PM_CAP_PME_D3HOT             BIT_30
+
+#define T3_PCI_PM_STATUS_CTRL_REG           0x4c
+
+#define T3_PM_POWER_STATE_MASK              (BIT_0 | BIT_1)
+#define T3_PM_POWER_STATE_D0                BIT_NONE
+#define T3_PM_POWER_STATE_D1                BIT_0
+#define T3_PM_POWER_STATE_D2                BIT_1
+#define T3_PM_POWER_STATE_D3                (BIT_0 | BIT_1)
+
+#define T3_PM_PME_ENABLE                    BIT_8
+#define T3_PM_PME_ASSERTED                  BIT_15
+
+/* PCI state register. */
+#define T3_PCI_STATE_REG                    0x70
+
+#define T3_PCI_STATE_FORCE_RESET            BIT_0
+#define T3_PCI_STATE_INT_NOT_ACTIVE         BIT_1
+#define T3_PCI_STATE_CONVENTIONAL_PCI_MODE  BIT_2
+#define T3_PCI_STATE_BUS_SPEED_HIGH         BIT_3
+#define T3_PCI_STATE_32BIT_PCI_BUS          BIT_4
+
+/* Broadcom subsystem/subvendor IDs. */
+#define T3_SVID_BROADCOM                            0x14e4
+
+#define T3_SSID_BROADCOM_BCM95700A6                 0x1644
+#define T3_SSID_BROADCOM_BCM95701A5                 0x0001
+#define T3_SSID_BROADCOM_BCM95700T6                 0x0002     /* BCM8002 */
+#define T3_SSID_BROADCOM_BCM95700A9                 0x0003     /* Agilent */
+#define T3_SSID_BROADCOM_BCM95701T1                 0x0005
+#define T3_SSID_BROADCOM_BCM95701T8                 0x0006
+#define T3_SSID_BROADCOM_BCM95701A7                 0x0007     /* Agilent */
+#define T3_SSID_BROADCOM_BCM95701A10                0x0008
+#define T3_SSID_BROADCOM_BCM95701A12                0x8008
+#define T3_SSID_BROADCOM_BCM95703Ax1                0x0009
+#define T3_SSID_BROADCOM_BCM95703Ax2                0x8009
+
+/* 3COM subsystem/subvendor IDs. */
+#define T3_SVID_3COM                                0x10b7
+
+#define T3_SSID_3COM_3C996T                         0x1000
+#define T3_SSID_3COM_3C996BT                        0x1006
+#define T3_SSID_3COM_3C996CT                        0x1002
+#define T3_SSID_3COM_3C997T                         0x1003
+#define T3_SSID_3COM_3C1000T                        0x1007
+#define T3_SSID_3COM_3C940BR01                      0x1008
+
+/* Fiber boards. */
+#define T3_SSID_3COM_3C996SX                        0x1004
+#define T3_SSID_3COM_3C997SX                        0x1005
+
+/* Dell subsystem/subvendor IDs. */
+
+#define T3_SVID_DELL                                0x1028
+
+#define T3_SSID_DELL_VIPER                          0x00d1
+#define T3_SSID_DELL_JAGUAR                         0x0106
+#define T3_SSID_DELL_MERLOT                         0x0109
+#define T3_SSID_DELL_SLIM_MERLOT                    0x010a
+
+/* Compaq subsystem/subvendor IDs */
+
+#define T3_SVID_COMPAQ                              0x0e11
+
+#define T3_SSID_COMPAQ_BANSHEE                      0x007c
+#define T3_SSID_COMPAQ_BANSHEE_2                    0x009a
+#define T3_SSID_COMPAQ_CHANGELING                   0x007d
+#define T3_SSID_COMPAQ_NC7780                       0x0085
+#define T3_SSID_COMPAQ_NC7780_2                     0x0099
+
+/******************************************************************************/
+/* MII registers. */
+/******************************************************************************/
+
+/* Control register. */
+#define PHY_CTRL_REG                                0x00
+
+#define PHY_CTRL_SPEED_MASK                         (BIT_6 | BIT_13)
+#define PHY_CTRL_SPEED_SELECT_10MBPS                BIT_NONE
+#define PHY_CTRL_SPEED_SELECT_100MBPS               BIT_13
+#define PHY_CTRL_SPEED_SELECT_1000MBPS              BIT_6
+#define PHY_CTRL_COLLISION_TEST_ENABLE              BIT_7
+#define PHY_CTRL_FULL_DUPLEX_MODE                   BIT_8
+#define PHY_CTRL_RESTART_AUTO_NEG                   BIT_9
+#define PHY_CTRL_ISOLATE_PHY                        BIT_10
+#define PHY_CTRL_LOWER_POWER_MODE                   BIT_11
+#define PHY_CTRL_AUTO_NEG_ENABLE                    BIT_12
+#define PHY_CTRL_LOOPBACK_MODE                      BIT_14
+#define PHY_CTRL_PHY_RESET                          BIT_15
+
+/* Status register. */
+#define PHY_STATUS_REG                              0x01
+
+#define PHY_STATUS_LINK_PASS                        BIT_2
+#define PHY_STATUS_AUTO_NEG_COMPLETE                BIT_5
+
+/* Phy Id registers. */
+#define PHY_ID1_REG                                 0x02
+#define PHY_ID1_OUI_MASK                            0xffff
+
+#define PHY_ID2_REG                                 0x03
+#define PHY_ID2_REV_MASK                            0x000f
+#define PHY_ID2_MODEL_MASK                          0x03f0
+#define PHY_ID2_OUI_MASK                            0xfc00
+
+/* Auto-negotiation advertisement register. */
+#define PHY_AN_AD_REG                               0x04
+
+#define PHY_AN_AD_ASYM_PAUSE                        BIT_11
+#define PHY_AN_AD_PAUSE_CAPABLE                     BIT_10
+#define PHY_AN_AD_10BASET_HALF                      BIT_5
+#define PHY_AN_AD_10BASET_FULL                      BIT_6
+#define PHY_AN_AD_100BASETX_HALF                    BIT_7
+#define PHY_AN_AD_100BASETX_FULL                    BIT_8
+#define PHY_AN_AD_PROTOCOL_802_3_CSMA_CD            0x01
+
+/* Auto-negotiation Link Partner Ability register. */
+#define PHY_LINK_PARTNER_ABILITY_REG                0x05
+
+#define PHY_LINK_PARTNER_ASYM_PAUSE                 BIT_11
+#define PHY_LINK_PARTNER_PAUSE_CAPABLE              BIT_10
+
+/* Auto-negotiation expansion register. */
+#define PHY_AN_EXPANSION_REG                        0x06
+
+/******************************************************************************/
+/* BCM5400 and BCM5401 phy info. */
+/******************************************************************************/
+
+#define PHY_DEVICE_ID           1
+
+/* OUI: bit 31-10;   Model#: bit 9-4;   Rev# bit 3-0. */
+#define PHY_UNKNOWN_PHY                             0x00000000
+#define PHY_BCM5400_PHY_ID                          0x60008040
+#define PHY_BCM5401_PHY_ID                          0x60008050
+#define PHY_BCM5411_PHY_ID                          0x60008070
+#define PHY_BCM5701_PHY_ID                          0x60008110
+#define PHY_BCM5703_PHY_ID                          0x60008160
+#define PHY_BCM5704_PHY_ID                          0x60008190
+#define PHY_BCM8002_PHY_ID                          0x60010140
+
+#define PHY_BCM5401_B0_REV                          0x1
+#define PHY_BCM5401_B2_REV                          0x3
+#define PHY_BCM5401_C0_REV                          0x6
+
+#define PHY_ID_OUI_MASK                             0xfffffc00
+#define PHY_ID_MODEL_MASK                           0x000003f0
+#define PHY_ID_REV_MASK                             0x0000000f
+#define PHY_ID_MASK                                 (PHY_ID_OUI_MASK |      \
+                                                   PHY_ID_MODEL_MASK)
+
+#define UNKNOWN_PHY_ID(x)   ((((x) & PHY_ID_MASK) != PHY_BCM5400_PHY_ID) && \
+                           (((x) & PHY_ID_MASK) != PHY_BCM5401_PHY_ID) && \
+                           (((x) & PHY_ID_MASK) != PHY_BCM5411_PHY_ID) && \
+                           (((x) & PHY_ID_MASK) != PHY_BCM5701_PHY_ID) && \
+                           (((x) & PHY_ID_MASK) != PHY_BCM5703_PHY_ID) && \
+                           (((x) & PHY_ID_MASK) != PHY_BCM5704_PHY_ID) && \
+                           (((x) & PHY_ID_MASK) != PHY_BCM8002_PHY_ID))
+
+/* 1000Base-T control register. */
+#define BCM540X_1000BASET_CTRL_REG                  0x09
+
+#define BCM540X_AN_AD_1000BASET_HALF                BIT_8
+#define BCM540X_AN_AD_1000BASET_FULL                BIT_9
+#define BCM540X_CONFIG_AS_MASTER                    BIT_11
+#define BCM540X_ENABLE_CONFIG_AS_MASTER             BIT_12
+
+/* Extended control register. */
+#define BCM540X_EXT_CTRL_REG                        0x10
+
+#define BCM540X_EXT_CTRL_LINK3_LED_MODE             BIT_1
+#define BCM540X_EXT_CTRL_TBI                        BIT_15
+
+/* PHY extended status register. */
+#define BCM540X_EXT_STATUS_REG                      0x11
+
+#define BCM540X_EXT_STATUS_LINK_PASS                BIT_8
+
+/* DSP Coefficient Read/Write Port. */
+#define BCM540X_DSP_RW_PORT                         0x15
+
+/* DSP Coeficient Address Register. */
+#define BCM540X_DSP_ADDRESS_REG                     0x17
+
+#define BCM540X_DSP_TAP_NUMBER_MASK                 0x00
+#define BCM540X_DSP_AGC_A                           0x00
+#define BCM540X_DSP_AGC_B                           0x01
+#define BCM540X_DSP_MSE_PAIR_STATUS                 0x02
+#define BCM540X_DSP_SOFT_DECISION                   0x03
+#define BCM540X_DSP_PHASE_REG                       0x04
+#define BCM540X_DSP_SKEW                            0x05
+#define BCM540X_DSP_POWER_SAVER_UPPER_BOUND         0x06
+#define BCM540X_DSP_POWER_SAVER_LOWER_BOUND         0x07
+#define BCM540X_DSP_LAST_ECHO                       0x08
+#define BCM540X_DSP_FREQUENCY                       0x09
+#define BCM540X_DSP_PLL_BANDWIDTH                   0x0a
+#define BCM540X_DSP_PLL_PHASE_OFFSET                0x0b
+
+#define BCM540X_DSP_FILTER_DCOFFSET                 (BIT_10 | BIT_11)
+#define BCM540X_DSP_FILTER_FEXT3                    (BIT_8 | BIT_9 | BIT_11)
+#define BCM540X_DSP_FILTER_FEXT2                    (BIT_9 | BIT_11)
+#define BCM540X_DSP_FILTER_FEXT1                    (BIT_8 | BIT_11)
+#define BCM540X_DSP_FILTER_FEXT0                    BIT_11
+#define BCM540X_DSP_FILTER_NEXT3                    (BIT_8 | BIT_9 | BIT_10)
+#define BCM540X_DSP_FILTER_NEXT2                    (BIT_9 | BIT_10)
+#define BCM540X_DSP_FILTER_NEXT1                    (BIT_8 | BIT_10)
+#define BCM540X_DSP_FILTER_NEXT0                    BIT_10
+#define BCM540X_DSP_FILTER_ECHO                     (BIT_8 | BIT_9)
+#define BCM540X_DSP_FILTER_DFE                      BIT_9
+#define BCM540X_DSP_FILTER_FFE                      BIT_8
+
+#define BCM540X_DSP_CONTROL_ALL_FILTERS             BIT_12
+
+#define BCM540X_DSP_SEL_CH_0                        BIT_NONE
+#define BCM540X_DSP_SEL_CH_1                        BIT_13
+#define BCM540X_DSP_SEL_CH_2                        BIT_14
+#define BCM540X_DSP_SEL_CH_3                        (BIT_13 | BIT_14)
+
+#define BCM540X_CONTROL_ALL_CHANNELS                BIT_15
+
+/* Auxilliary Control Register (Shadow Register) */
+#define BCM5401_AUX_CTRL                            0x18
+
+#define BCM5401_SHADOW_SEL_MASK                     0x7
+#define BCM5401_SHADOW_SEL_NORMAL                   0x00
+#define BCM5401_SHADOW_SEL_10BASET                  0x01
+#define BCM5401_SHADOW_SEL_POWER_CONTROL            0x02
+#define BCM5401_SHADOW_SEL_IP_PHONE                 0x03
+#define BCM5401_SHADOW_SEL_MISC_TEST1               0x04
+#define BCM5401_SHADOW_SEL_MISC_TEST2               0x05
+#define BCM5401_SHADOW_SEL_IP_PHONE_SEED            0x06
+
+/* Shadow register selector == '000' */
+#define BCM5401_SHDW_NORMAL_DIAG_MODE               BIT_3
+#define BCM5401_SHDW_NORMAL_DISABLE_MBP             BIT_4
+#define BCM5401_SHDW_NORMAL_DISABLE_LOW_PWR         BIT_5
+#define BCM5401_SHDW_NORMAL_DISABLE_INV_PRF         BIT_6
+#define BCM5401_SHDW_NORMAL_DISABLE_PRF             BIT_7
+#define BCM5401_SHDW_NORMAL_RX_SLICING_NORMAL       BIT_NONE
+#define BCM5401_SHDW_NORMAL_RX_SLICING_4D           BIT_8
+#define BCM5401_SHDW_NORMAL_RX_SLICING_3LVL_1D      BIT_9
+#define BCM5401_SHDW_NORMAL_RX_SLICING_5LVL_1D      (BIT_8 | BIT_9)
+#define BCM5401_SHDW_NORMAL_TX_6DB_CODING           BIT_10
+#define BCM5401_SHDW_NORMAL_ENABLE_SM_DSP_CLOCK     BIT_11
+#define BCM5401_SHDW_NORMAL_EDGERATE_CTRL_4NS       BIT_NONE
+#define BCM5401_SHDW_NORMAL_EDGERATE_CTRL_5NS       BIT_12
+#define BCM5401_SHDW_NORMAL_EDGERATE_CTRL_3NS       BIT_13
+#define BCM5401_SHDW_NORMAL_EDGERATE_CTRL_0NS       (BIT_12 | BIT_13)
+#define BCM5401_SHDW_NORMAL_EXT_PACKET_LENGTH       BIT_14
+#define BCM5401_SHDW_NORMAL_EXTERNAL_LOOPBACK       BIT_15
+
+/* Auxilliary status summary. */
+#define BCM540X_AUX_STATUS_REG                      0x19
+
+#define BCM540X_AUX_LINK_PASS                       BIT_2
+#define BCM540X_AUX_SPEED_MASK                      (BIT_8 | BIT_9 | BIT_10)
+#define BCM540X_AUX_10BASET_HD                      BIT_8
+#define BCM540X_AUX_10BASET_FD                      BIT_9
+#define BCM540X_AUX_100BASETX_HD                    (BIT_8 | BIT_9)
+#define BCM540X_AUX_100BASET4                       BIT_10
+#define BCM540X_AUX_100BASETX_FD                    (BIT_8 | BIT_10)
+#define BCM540X_AUX_100BASET_HD                     (BIT_9 | BIT_10)
+#define BCM540X_AUX_100BASET_FD                     (BIT_8 | BIT_9 | BIT_10)
+
+/* Interrupt status. */
+#define BCM540X_INT_STATUS_REG                      0x1a
+
+#define BCM540X_INT_LINK_CHANGE                     BIT_1
+#define BCM540X_INT_SPEED_CHANGE                    BIT_2
+#define BCM540X_INT_DUPLEX_CHANGE                   BIT_3
+#define BCM540X_INT_AUTO_NEG_PAGE_RX                BIT_10
+
+/* Interrupt mask register. */
+#define BCM540X_INT_MASK_REG                        0x1b
+
+/******************************************************************************/
+/* Register definitions. */
+/******************************************************************************/
+
+typedef volatile LM_UINT8 T3_8BIT_REGISTER, *PT3_8BIT_REGISTER;
+typedef volatile LM_UINT16 T3_16BIT_REGISTER, *PT3_16BIT_REGISTER;
+typedef volatile LM_UINT32 T3_32BIT_REGISTER, *PT3_32BIT_REGISTER;
+
+typedef struct {
+       /* Big endian format. */
+       T3_32BIT_REGISTER High;
+       T3_32BIT_REGISTER Low;
+} T3_64BIT_REGISTER, *PT3_64BIT_REGISTER;
+
+typedef T3_64BIT_REGISTER T3_64BIT_HOST_ADDR, *PT3_64BIT_HOST_ADDR;
+
+#define T3_NUM_OF_DMA_DESC    256
+#define T3_NUM_OF_MBUF        768
+
+typedef struct {
+       T3_64BIT_REGISTER host_addr;
+       T3_32BIT_REGISTER nic_mbuf;
+       T3_16BIT_REGISTER len;
+       T3_16BIT_REGISTER cqid_sqid;
+       T3_32BIT_REGISTER flags;
+       T3_32BIT_REGISTER opaque1;
+       T3_32BIT_REGISTER opaque2;
+       T3_32BIT_REGISTER opaque3;
+} T3_DMA_DESC, *PT3_DMA_DESC;
+
+/******************************************************************************/
+/* Ring control block. */
+/******************************************************************************/
+
+typedef struct {
+       T3_64BIT_REGISTER HostRingAddr;
+
+       union {
+               struct {
+#ifdef BIG_ENDIAN_HOST
+                       T3_16BIT_REGISTER MaxLen;
+                       T3_16BIT_REGISTER Flags;
+#else                          /* BIG_ENDIAN_HOST */
+                       T3_16BIT_REGISTER Flags;
+                       T3_16BIT_REGISTER MaxLen;
+#endif
+               } s;
+
+               T3_32BIT_REGISTER MaxLen_Flags;
+       } u;
+
+       T3_32BIT_REGISTER NicRingAddr;
+} T3_RCB, *PT3_RCB;
+
+#define T3_RCB_FLAG_USE_EXT_RECV_BD                     BIT_0
+#define T3_RCB_FLAG_RING_DISABLED                       BIT_1
+
+/******************************************************************************/
+/* Status block. */
+/******************************************************************************/
+
+/*
+ * Size of status block is actually 0x50 bytes.  Use 0x80 bytes for
+ * cache line alignment.
+ */
+#define T3_STATUS_BLOCK_SIZE                                    0x80
+
+typedef struct {
+       volatile LM_UINT32 Status;
+#define STATUS_BLOCK_UPDATED                                BIT_0
+#define STATUS_BLOCK_LINK_CHANGED_STATUS                    BIT_1
+#define STATUS_BLOCK_ERROR                                  BIT_2
+
+       volatile LM_UINT32 StatusTag;
+
+#ifdef BIG_ENDIAN_HOST
+       volatile LM_UINT16 RcvStdConIdx;
+       volatile LM_UINT16 RcvJumboConIdx;
+
+       volatile LM_UINT16 Reserved2;
+       volatile LM_UINT16 RcvMiniConIdx;
+
+       struct {
+               volatile LM_UINT16 SendConIdx;  /* Send consumer index. */
+               volatile LM_UINT16 RcvProdIdx;  /* Receive producer index. */
+       } Idx[16];
+#else                          /* BIG_ENDIAN_HOST */
+       volatile LM_UINT16 RcvJumboConIdx;
+       volatile LM_UINT16 RcvStdConIdx;
+
+       volatile LM_UINT16 RcvMiniConIdx;
+       volatile LM_UINT16 Reserved2;
+
+       struct {
+               volatile LM_UINT16 RcvProdIdx;  /* Receive producer index. */
+               volatile LM_UINT16 SendConIdx;  /* Send consumer index. */
+       } Idx[16];
+#endif
+} T3_STATUS_BLOCK, *PT3_STATUS_BLOCK;
+
+/******************************************************************************/
+/* Receive buffer descriptors. */
+/******************************************************************************/
+
+typedef struct {
+       T3_64BIT_HOST_ADDR HostAddr;
+
+#ifdef BIG_ENDIAN_HOST
+       volatile LM_UINT16 Index;
+       volatile LM_UINT16 Len;
+
+       volatile LM_UINT16 Type;
+       volatile LM_UINT16 Flags;
+
+       volatile LM_UINT16 IpCksum;
+       volatile LM_UINT16 TcpUdpCksum;
+
+       volatile LM_UINT16 ErrorFlag;
+       volatile LM_UINT16 VlanTag;
+#else                          /* BIG_ENDIAN_HOST */
+       volatile LM_UINT16 Len;
+       volatile LM_UINT16 Index;
+
+       volatile LM_UINT16 Flags;
+       volatile LM_UINT16 Type;
+
+       volatile LM_UINT16 TcpUdpCksum;
+       volatile LM_UINT16 IpCksum;
+
+       volatile LM_UINT16 VlanTag;
+       volatile LM_UINT16 ErrorFlag;
+#endif
+
+       volatile LM_UINT32 Reserved;
+       volatile LM_UINT32 Opaque;
+} T3_RCV_BD, *PT3_RCV_BD;
+
+typedef struct {
+       T3_64BIT_HOST_ADDR HostAddr[3];
+
+#ifdef BIG_ENDIAN_HOST
+       LM_UINT16 Len1;
+       LM_UINT16 Len2;
+
+       LM_UINT16 Len3;
+       LM_UINT16 Reserved1;
+#else                          /* BIG_ENDIAN_HOST */
+       LM_UINT16 Len2;
+       LM_UINT16 Len1;
+
+       LM_UINT16 Reserved1;
+       LM_UINT16 Len3;
+#endif
+
+       T3_RCV_BD StdRcvBd;
+} T3_EXT_RCV_BD, *PT3_EXT_RCV_BD;
+
+/* Error flags. */
+#define RCV_BD_ERR_BAD_CRC                          0x0001
+#define RCV_BD_ERR_COLL_DETECT                      0x0002
+#define RCV_BD_ERR_LINK_LOST_DURING_PKT             0x0004
+#define RCV_BD_ERR_PHY_DECODE_ERR                   0x0008
+#define RCV_BD_ERR_ODD_NIBBLED_RCVD_MII             0x0010
+#define RCV_BD_ERR_MAC_ABORT                        0x0020
+#define RCV_BD_ERR_LEN_LT_64                        0x0040
+#define RCV_BD_ERR_TRUNC_NO_RESOURCES               0x0080
+#define RCV_BD_ERR_GIANT_FRAME_RCVD                 0x0100
+
+/* Buffer descriptor flags. */
+#define RCV_BD_FLAG_END                             0x0004
+#define RCV_BD_FLAG_JUMBO_RING                      0x0020
+#define RCV_BD_FLAG_VLAN_TAG                        0x0040
+#define RCV_BD_FLAG_FRAME_HAS_ERROR                 0x0400
+#define RCV_BD_FLAG_MINI_RING                       0x0800
+#define RCV_BD_FLAG_IP_CHKSUM_FIELD                 0x1000
+#define RCV_BD_FLAG_TCP_UDP_CHKSUM_FIELD            0x2000
+#define RCV_BD_FLAG_TCP_PACKET                      0x4000
+
+/******************************************************************************/
+/* Send buffer descriptor. */
+/******************************************************************************/
+
+typedef struct {
+       T3_64BIT_HOST_ADDR HostAddr;
+
+       union {
+               struct {
+#ifdef BIG_ENDIAN_HOST
+                       LM_UINT16 Len;
+                       LM_UINT16 Flags;
+#else                          /* BIG_ENDIAN_HOST */
+                       LM_UINT16 Flags;
+                       LM_UINT16 Len;
+#endif
+               } s1;
+
+               LM_UINT32 Len_Flags;
+       } u1;
+
+       union {
+               struct {
+#ifdef BIG_ENDIAN_HOST
+                       LM_UINT16 Reserved;
+                       LM_UINT16 VlanTag;
+#else                          /* BIG_ENDIAN_HOST */
+                       LM_UINT16 VlanTag;
+                       LM_UINT16 Reserved;
+#endif
+               } s2;
+
+               LM_UINT32 VlanTag;
+       } u2;
+} T3_SND_BD, *PT3_SND_BD;
+
+/* Send buffer descriptor flags. */
+#define SND_BD_FLAG_TCP_UDP_CKSUM                   0x0001
+#define SND_BD_FLAG_IP_CKSUM                        0x0002
+#define SND_BD_FLAG_END                             0x0004
+#define SND_BD_FLAG_IP_FRAG                         0x0008
+#define SND_BD_FLAG_IP_FRAG_END                     0x0010
+#define SND_BD_FLAG_VLAN_TAG                        0x0040
+#define SND_BD_FLAG_COAL_NOW                        0x0080
+#define SND_BD_FLAG_CPU_PRE_DMA                     0x0100
+#define SND_BD_FLAG_CPU_POST_DMA                    0x0200
+#define SND_BD_FLAG_INSERT_SRC_ADDR                 0x1000
+#define SND_BD_FLAG_CHOOSE_SRC_ADDR                 0x6000
+#define SND_BD_FLAG_DONT_GEN_CRC                    0x8000
+
+/* MBUFs */
+typedef struct T3_MBUF_FRAME_DESC {
+#ifdef BIG_ENDIAN_HOST
+       LM_UINT32 status_control;
+       union {
+               struct {
+                       LM_UINT8 cqid;
+                       LM_UINT8 reserved1;
+                       LM_UINT16 length;
+               } s1;
+               LM_UINT32 word;
+       } u1;
+       union {
+               struct {
+                       LM_UINT16 ip_hdr_start;
+                       LM_UINT16 tcp_udp_hdr_start;
+               } s2;
+
+               LM_UINT32 word;
+       } u2;
+
+       union {
+               struct {
+                       LM_UINT16 data_start;
+                       LM_UINT16 vlan_id;
+               } s3;
+
+               LM_UINT32 word;
+       } u3;
+
+       union {
+               struct {
+                       LM_UINT16 ip_checksum;
+                       LM_UINT16 tcp_udp_checksum;
+               } s4;
+
+               LM_UINT32 word;
+       } u4;
+
+       union {
+               struct {
+                       LM_UINT16 pseudo_checksum;
+                       LM_UINT16 checksum_status;
+               } s5;
+
+               LM_UINT32 word;
+       } u5;
+
+       union {
+               struct {
+                       LM_UINT16 rule_match;
+                       LM_UINT8 class;
+                       LM_UINT8 rupt;
+               } s6;
+
+               LM_UINT32 word;
+       } u6;
+
+       union {
+               struct {
+                       LM_UINT16 reserved2;
+                       LM_UINT16 mbuf_num;
+               } s7;
+
+               LM_UINT32 word;
+       } u7;
+
+       LM_UINT32 reserved3;
+       LM_UINT32 reserved4;
+#else
+       LM_UINT32 status_control;
+       union {
+               struct {
+                       LM_UINT16 length;
+                       LM_UINT8 reserved1;
+                       LM_UINT8 cqid;
+               } s1;
+               LM_UINT32 word;
+       } u1;
+       union {
+               struct {
+                       LM_UINT16 tcp_udp_hdr_start;
+                       LM_UINT16 ip_hdr_start;
+               } s2;
+
+               LM_UINT32 word;
+       } u2;
+
+       union {
+               struct {
+                       LM_UINT16 vlan_id;
+                       LM_UINT16 data_start;
+               } s3;
+
+               LM_UINT32 word;
+       } u3;
+
+       union {
+               struct {
+                       LM_UINT16 tcp_udp_checksum;
+                       LM_UINT16 ip_checksum;
+               } s4;
+
+               LM_UINT32 word;
+       } u4;
+
+       union {
+               struct {
+                       LM_UINT16 checksum_status;
+                       LM_UINT16 pseudo_checksum;
+               } s5;
+
+               LM_UINT32 word;
+       } u5;
+
+       union {
+               struct {
+                       LM_UINT8 rupt;
+                       LM_UINT8 class;
+                       LM_UINT16 rule_match;
+               } s6;
+
+               LM_UINT32 word;
+       } u6;
+
+       union {
+               struct {
+                       LM_UINT16 mbuf_num;
+                       LM_UINT16 reserved2;
+               } s7;
+
+               LM_UINT32 word;
+       } u7;
+
+       LM_UINT32 reserved3;
+       LM_UINT32 reserved4;
+#endif
+} T3_MBUF_FRAME_DESC, *PT3_MBUF_FRAME_DESC;
+
+typedef struct T3_MBUF_HDR {
+       union {
+               struct {
+                       unsigned int C:1;
+                       unsigned int F:1;
+                       unsigned int reserved1:7;
+                       unsigned int next_mbuf:16;
+                       unsigned int length:7;
+               } s1;
+
+               LM_UINT32 word;
+       } u1;
+
+       LM_UINT32 next_frame_ptr;
+} T3_MBUF_HDR, *PT3_MBUF_HDR;
+
+typedef struct T3_MBUF {
+       T3_MBUF_HDR hdr;
+       union {
+               struct {
+                       T3_MBUF_FRAME_DESC frame_hdr;
+                       LM_UINT32 data[20];
+               } s1;
+
+               struct {
+                       LM_UINT32 data[30];
+               } s2;
+       } body;
+} T3_MBUF, *PT3_MBUF;
+
+#define T3_MBUF_BASE   (T3_NIC_MBUF_POOL_ADDR >> 7)
+#define T3_MBUF_END    ((T3_NIC_MBUF_POOL_ADDR + T3_NIC_MBUF_POOL_SIZE) >> 7)
+
+/******************************************************************************/
+/* Statistics block. */
+/******************************************************************************/
+
+typedef struct {
+       LM_UINT8 Reserved0[0x400 - 0x300];
+
+       /* Statistics maintained by Receive MAC. */
+       T3_64BIT_REGISTER ifHCInOctets;
+       T3_64BIT_REGISTER Reserved1;
+       T3_64BIT_REGISTER etherStatsFragments;
+       T3_64BIT_REGISTER ifHCInUcastPkts;
+       T3_64BIT_REGISTER ifHCInMulticastPkts;
+       T3_64BIT_REGISTER ifHCInBroadcastPkts;
+       T3_64BIT_REGISTER dot3StatsFCSErrors;
+       T3_64BIT_REGISTER dot3StatsAlignmentErrors;
+       T3_64BIT_REGISTER xonPauseFramesReceived;
+       T3_64BIT_REGISTER xoffPauseFramesReceived;
+       T3_64BIT_REGISTER macControlFramesReceived;
+       T3_64BIT_REGISTER xoffStateEntered;
+       T3_64BIT_REGISTER dot3StatsFramesTooLong;
+       T3_64BIT_REGISTER etherStatsJabbers;
+       T3_64BIT_REGISTER etherStatsUndersizePkts;
+       T3_64BIT_REGISTER inRangeLengthError;
+       T3_64BIT_REGISTER outRangeLengthError;
+       T3_64BIT_REGISTER etherStatsPkts64Octets;
+       T3_64BIT_REGISTER etherStatsPkts65Octetsto127Octets;
+       T3_64BIT_REGISTER etherStatsPkts128Octetsto255Octets;
+       T3_64BIT_REGISTER etherStatsPkts256Octetsto511Octets;
+       T3_64BIT_REGISTER etherStatsPkts512Octetsto1023Octets;
+       T3_64BIT_REGISTER etherStatsPkts1024Octetsto1522Octets;
+       T3_64BIT_REGISTER etherStatsPkts1523Octetsto2047Octets;
+       T3_64BIT_REGISTER etherStatsPkts2048Octetsto4095Octets;
+       T3_64BIT_REGISTER etherStatsPkts4096Octetsto8191Octets;
+       T3_64BIT_REGISTER etherStatsPkts8192Octetsto9022Octets;
+
+       T3_64BIT_REGISTER Unused1[37];
+
+       /* Statistics maintained by Transmit MAC. */
+       T3_64BIT_REGISTER ifHCOutOctets;
+       T3_64BIT_REGISTER Reserved2;
+       T3_64BIT_REGISTER etherStatsCollisions;
+       T3_64BIT_REGISTER outXonSent;
+       T3_64BIT_REGISTER outXoffSent;
+       T3_64BIT_REGISTER flowControlDone;
+       T3_64BIT_REGISTER dot3StatsInternalMacTransmitErrors;
+       T3_64BIT_REGISTER dot3StatsSingleCollisionFrames;
+       T3_64BIT_REGISTER dot3StatsMultipleCollisionFrames;
+       T3_64BIT_REGISTER dot3StatsDeferredTransmissions;
+       T3_64BIT_REGISTER Reserved3;
+       T3_64BIT_REGISTER dot3StatsExcessiveCollisions;
+       T3_64BIT_REGISTER dot3StatsLateCollisions;
+       T3_64BIT_REGISTER dot3Collided2Times;
+       T3_64BIT_REGISTER dot3Collided3Times;
+       T3_64BIT_REGISTER dot3Collided4Times;
+       T3_64BIT_REGISTER dot3Collided5Times;
+       T3_64BIT_REGISTER dot3Collided6Times;
+       T3_64BIT_REGISTER dot3Collided7Times;
+       T3_64BIT_REGISTER dot3Collided8Times;
+       T3_64BIT_REGISTER dot3Collided9Times;
+       T3_64BIT_REGISTER dot3Collided10Times;
+       T3_64BIT_REGISTER dot3Collided11Times;
+       T3_64BIT_REGISTER dot3Collided12Times;
+       T3_64BIT_REGISTER dot3Collided13Times;
+       T3_64BIT_REGISTER dot3Collided14Times;
+       T3_64BIT_REGISTER dot3Collided15Times;
+       T3_64BIT_REGISTER ifHCOutUcastPkts;
+       T3_64BIT_REGISTER ifHCOutMulticastPkts;
+       T3_64BIT_REGISTER ifHCOutBroadcastPkts;
+       T3_64BIT_REGISTER dot3StatsCarrierSenseErrors;
+       T3_64BIT_REGISTER ifOutDiscards;
+       T3_64BIT_REGISTER ifOutErrors;
+
+       T3_64BIT_REGISTER Unused2[31];
+
+       /* Statistics maintained by Receive List Placement. */
+       T3_64BIT_REGISTER COSIfHCInPkts[16];
+       T3_64BIT_REGISTER COSFramesDroppedDueToFilters;
+       T3_64BIT_REGISTER nicDmaWriteQueueFull;
+       T3_64BIT_REGISTER nicDmaWriteHighPriQueueFull;
+       T3_64BIT_REGISTER nicNoMoreRxBDs;
+       T3_64BIT_REGISTER ifInDiscards;
+       T3_64BIT_REGISTER ifInErrors;
+       T3_64BIT_REGISTER nicRecvThresholdHit;
+
+       T3_64BIT_REGISTER Unused3[9];
+
+       /* Statistics maintained by Send Data Initiator. */
+       T3_64BIT_REGISTER COSIfHCOutPkts[16];
+       T3_64BIT_REGISTER nicDmaReadQueueFull;
+       T3_64BIT_REGISTER nicDmaReadHighPriQueueFull;
+       T3_64BIT_REGISTER nicSendDataCompQueueFull;
+
+       /* Statistics maintained by Host Coalescing. */
+       T3_64BIT_REGISTER nicRingSetSendProdIndex;
+       T3_64BIT_REGISTER nicRingStatusUpdate;
+       T3_64BIT_REGISTER nicInterrupts;
+       T3_64BIT_REGISTER nicAvoidedInterrupts;
+       T3_64BIT_REGISTER nicSendThresholdHit;
+
+       LM_UINT8 Reserved4[0xb00 - 0x9c0];
+} T3_STATS_BLOCK, *PT3_STATS_BLOCK;
+
+/******************************************************************************/
+/* PCI configuration registers. */
+/******************************************************************************/
+
+typedef struct {
+       T3_16BIT_REGISTER VendorId;
+       T3_16BIT_REGISTER DeviceId;
+
+       T3_16BIT_REGISTER Command;
+       T3_16BIT_REGISTER Status;
+
+       T3_32BIT_REGISTER ClassCodeRevId;
+
+       T3_8BIT_REGISTER CacheLineSize;
+       T3_8BIT_REGISTER LatencyTimer;
+       T3_8BIT_REGISTER HeaderType;
+       T3_8BIT_REGISTER Bist;
+
+       T3_32BIT_REGISTER MemBaseAddrLow;
+       T3_32BIT_REGISTER MemBaseAddrHigh;
+
+       LM_UINT8 Unused1[20];
+
+       T3_16BIT_REGISTER SubsystemVendorId;
+       T3_16BIT_REGISTER SubsystemId;
+
+       T3_32BIT_REGISTER RomBaseAddr;
+
+       T3_8BIT_REGISTER PciXCapiblityPtr;
+       LM_UINT8 Unused2[7];
+
+       T3_8BIT_REGISTER IntLine;
+       T3_8BIT_REGISTER IntPin;
+       T3_8BIT_REGISTER MinGnt;
+       T3_8BIT_REGISTER MaxLat;
+
+       T3_8BIT_REGISTER PciXCapabilities;
+       T3_8BIT_REGISTER PmCapabilityPtr;
+       T3_16BIT_REGISTER PciXCommand;
+
+       T3_32BIT_REGISTER PciXStatus;
+
+       T3_8BIT_REGISTER PmCapabilityId;
+       T3_8BIT_REGISTER VpdCapabilityPtr;
+       T3_16BIT_REGISTER PmCapabilities;
+
+       T3_16BIT_REGISTER PmCtrlStatus;
+#define PM_CTRL_PME_STATUS            BIT_15
+#define PM_CTRL_PME_ENABLE            BIT_8
+#define PM_CTRL_PME_POWER_STATE_D0    0
+#define PM_CTRL_PME_POWER_STATE_D1    1
+#define PM_CTRL_PME_POWER_STATE_D2    2
+#define PM_CTRL_PME_POWER_STATE_D3H   3
+
+       T3_8BIT_REGISTER BridgeSupportExt;
+       T3_8BIT_REGISTER PmData;
+
+       T3_8BIT_REGISTER VpdCapabilityId;
+       T3_8BIT_REGISTER MsiCapabilityPtr;
+       T3_16BIT_REGISTER VpdAddrFlag;
+#define VPD_FLAG_WRITE      (1 << 15)
+#define VPD_FLAG_RW_MASK    (1 << 15)
+#define VPD_FLAG_READ       0
+
+       T3_32BIT_REGISTER VpdData;
+
+       T3_8BIT_REGISTER MsiCapabilityId;
+       T3_8BIT_REGISTER NextCapabilityPtr;
+       T3_16BIT_REGISTER MsiCtrl;
+#define MSI_CTRL_64BIT_CAP     (1 << 7)
+#define MSI_CTRL_MSG_ENABLE(x) (x << 4)
+#define MSI_CTRL_MSG_CAP(x)    (x << 1)
+#define MSI_CTRL_ENABLE        (1 << 0)
+
+       T3_32BIT_REGISTER MsiAddrLow;
+       T3_32BIT_REGISTER MsiAddrHigh;
+
+       T3_16BIT_REGISTER MsiData;
+       T3_16BIT_REGISTER Unused3;
+
+       T3_32BIT_REGISTER MiscHostCtrl;
+#define MISC_HOST_CTRL_CLEAR_INT                        BIT_0
+#define MISC_HOST_CTRL_MASK_PCI_INT                     BIT_1
+#define MISC_HOST_CTRL_ENABLE_ENDIAN_BYTE_SWAP          BIT_2
+#define MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP          BIT_3
+#define MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW          BIT_4
+#define MISC_HOST_CTRL_ENABLE_CLK_REG_RW                BIT_5
+#define MISC_HOST_CTRL_ENABLE_REG_WORD_SWAP             BIT_6
+#define MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS           BIT_7
+#define MISC_HOST_CTRL_ENABLE_INT_MASK_MODE             BIT_8
+#define MISC_HOST_CTRL_ENABLE_TAGGED_STATUS_MODE        BIT_9
+
+       T3_32BIT_REGISTER DmaReadWriteCtrl;
+#define DMA_CTRL_WRITE_BOUNDARY_MASK            (BIT_11 | BIT_12 | BIT_13)
+#define DMA_CTRL_WRITE_BOUNDARY_DISABLE         0
+#define DMA_CTRL_WRITE_BOUNDARY_16              BIT_11
+#define DMA_CTRL_WRITE_BOUNDARY_32              BIT_12
+#define DMA_CTRL_WRITE_BOUNDARY_64              (BIT_12 | BIT_11)
+#define DMA_CTRL_WRITE_BOUNDARY_128             BIT_13
+#define DMA_CTRL_WRITE_BOUNDARY_256             (BIT_13 | BIT_11)
+#define DMA_CTRL_WRITE_BOUNDARY_512             (BIT_13 | BIT_12)
+#define DMA_CTRL_WRITE_BOUNDARY_1024            (BIT_13 | BIT_12 | BIT_11)
+#define DMA_CTRL_WRITE_ONE_DMA_AT_ONCE          BIT_14
+
+       T3_32BIT_REGISTER PciState;
+#define T3_PCI_STATE_FORCE_PCI_RESET                    BIT_0
+#define T3_PCI_STATE_INTERRUPT_NOT_ACTIVE               BIT_1
+#define T3_PCI_STATE_NOT_PCI_X_BUS                      BIT_2
+#define T3_PCI_STATE_HIGH_BUS_SPEED                     BIT_3
+#define T3_PCI_STATE_32BIT_PCI_BUS                      BIT_4
+#define T3_PCI_STATE_PCI_ROM_ENABLE                     BIT_5
+#define T3_PCI_STATE_PCI_ROM_RETRY_ENABLE               BIT_6
+#define T3_PCI_STATE_FLAT_VIEW                          BIT_8
+#define T3_PCI_STATE_RETRY_SAME_DMA                     BIT_13
+
+       T3_32BIT_REGISTER ClockCtrl;
+#define T3_PCI_CLKCTRL_TXCPU_CLK_DISABLE                BIT_11
+#define T3_PCI_CLKCTRL_RXCPU_CLK_DISABLE                BIT_10
+#define T3_PCI_CLKCTRL_CORE_CLK_DISABLE                 BIT_9
+
+       T3_32BIT_REGISTER RegBaseAddr;
+
+       T3_32BIT_REGISTER MemWindowBaseAddr;
+
+#ifdef NIC_CPU_VIEW
+       /* These registers are ONLY visible to NIC CPU */
+       T3_32BIT_REGISTER PowerConsumed;
+       T3_32BIT_REGISTER PowerDissipated;
+#else                          /* NIC_CPU_VIEW */
+       T3_32BIT_REGISTER RegData;
+       T3_32BIT_REGISTER MemWindowData;
+#endif                         /* !NIC_CPU_VIEW */
+
+       T3_32BIT_REGISTER ModeCtrl;
+
+       T3_32BIT_REGISTER MiscCfg;
+
+       T3_32BIT_REGISTER MiscLocalCtrl;
+
+       T3_32BIT_REGISTER Unused4;
+
+       /* NOTE: Big/Little-endian clarification needed.  Are these register */
+       /* in big or little endian formate. */
+       T3_64BIT_REGISTER StdRingProdIdx;
+       T3_64BIT_REGISTER RcvRetRingConIdx;
+       T3_64BIT_REGISTER SndProdIdx;
+
+       LM_UINT8 Unused5[80];
+} T3_PCI_CONFIGURATION, *PT3_PCI_CONFIGURATION;
+
+#define PCIX_CMD_MAX_SPLIT_MASK                         0x0070
+#define PCIX_CMD_MAX_SPLIT_SHL                          4
+#define PCIX_CMD_MAX_BURST_MASK                         0x000c
+#define PCIX_CMD_MAX_BURST_SHL                          2
+#define PCIX_CMD_MAX_BURST_CPIOB                        2
+
+/******************************************************************************/
+/* Mac control registers. */
+/******************************************************************************/
+
+typedef struct {
+       /* MAC mode control. */
+       T3_32BIT_REGISTER Mode;
+#define MAC_MODE_GLOBAL_RESET                       BIT_0
+#define MAC_MODE_HALF_DUPLEX                        BIT_1
+#define MAC_MODE_PORT_MODE_MASK                     (BIT_2 | BIT_3)
+#define MAC_MODE_PORT_MODE_TBI                      (BIT_2 | BIT_3)
+#define MAC_MODE_PORT_MODE_GMII                     BIT_3
+#define MAC_MODE_PORT_MODE_MII                      BIT_2
+#define MAC_MODE_PORT_MODE_NONE                     BIT_NONE
+#define MAC_MODE_PORT_INTERNAL_LOOPBACK             BIT_4
+#define MAC_MODE_TAGGED_MAC_CONTROL                 BIT_7
+#define MAC_MODE_TX_BURSTING                        BIT_8
+#define MAC_MODE_MAX_DEFER                          BIT_9
+#define MAC_MODE_LINK_POLARITY                      BIT_10
+#define MAC_MODE_ENABLE_RX_STATISTICS               BIT_11
+#define MAC_MODE_CLEAR_RX_STATISTICS                BIT_12
+#define MAC_MODE_FLUSH_RX_STATISTICS                BIT_13
+#define MAC_MODE_ENABLE_TX_STATISTICS               BIT_14
+#define MAC_MODE_CLEAR_TX_STATISTICS                BIT_15
+#define MAC_MODE_FLUSH_TX_STATISTICS                BIT_16
+#define MAC_MODE_SEND_CONFIGS                       BIT_17
+#define MAC_MODE_DETECT_MAGIC_PACKET_ENABLE         BIT_18
+#define MAC_MODE_ACPI_POWER_ON_ENABLE               BIT_19
+#define MAC_MODE_ENABLE_MIP                         BIT_20
+#define MAC_MODE_ENABLE_TDE                         BIT_21
+#define MAC_MODE_ENABLE_RDE                         BIT_22
+#define MAC_MODE_ENABLE_FHDE                        BIT_23
+
+       /* MAC status */
+       T3_32BIT_REGISTER Status;
+#define MAC_STATUS_PCS_SYNCED                       BIT_0
+#define MAC_STATUS_SIGNAL_DETECTED                  BIT_1
+#define MAC_STATUS_RECEIVING_CFG                    BIT_2
+#define MAC_STATUS_CFG_CHANGED                      BIT_3
+#define MAC_STATUS_SYNC_CHANGED                     BIT_4
+#define MAC_STATUS_PORT_DECODE_ERROR                BIT_10
+#define MAC_STATUS_LINK_STATE_CHANGED               BIT_12
+#define MAC_STATUS_MI_COMPLETION                    BIT_22
+#define MAC_STATUS_MI_INTERRUPT                     BIT_23
+#define MAC_STATUS_AP_ERROR                         BIT_24
+#define MAC_STATUS_ODI_ERROR                        BIT_25
+#define MAC_STATUS_RX_STATS_OVERRUN                 BIT_26
+#define MAC_STATUS_TX_STATS_OVERRUN                 BIT_27
+
+       /* Event Enable */
+       T3_32BIT_REGISTER MacEvent;
+#define MAC_EVENT_ENABLE_PORT_DECODE_ERR            BIT_10
+#define MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN    BIT_12
+#define MAC_EVENT_ENABLE_MI_COMPLETION              BIT_22
+#define MAC_EVENT_ENABLE_MI_INTERRUPT               BIT_23
+#define MAC_EVENT_ENABLE_AP_ERROR                   BIT_24
+#define MAC_EVENT_ENABLE_ODI_ERROR                  BIT_25
+#define MAC_EVENT_ENABLE_RX_STATS_OVERRUN           BIT_26
+#define MAC_EVENT_ENABLE_TX_STATS_OVERRUN           BIT_27
+
+       /* Led control. */
+       T3_32BIT_REGISTER LedCtrl;
+#define LED_CTRL_OVERRIDE_LINK_LED                  BIT_0
+#define LED_CTRL_1000MBPS_LED_ON                    BIT_1
+#define LED_CTRL_100MBPS_LED_ON                     BIT_2
+#define LED_CTRL_10MBPS_LED_ON                      BIT_3
+#define LED_CTRL_OVERRIDE_TRAFFIC_LED               BIT_4
+#define LED_CTRL_BLINK_TRAFFIC_LED                  BIT_5
+#define LED_CTRL_TRAFFIC_LED                        BIT_6
+#define LED_CTRL_1000MBPS_LED_STATUS                BIT_7
+#define LED_CTRL_100MBPS_LED_STATUS                 BIT_8
+#define LED_CTRL_10MBPS_LED_STATUS                  BIT_9
+#define LED_CTRL_TRAFFIC_LED_STATUS                 BIT_10
+#define LED_CTRL_MAC_MODE                           BIT_NONE
+#define LED_CTRL_PHY_MODE_1                         BIT_11
+#define LED_CTRL_PHY_MODE_2                         BIT_12
+#define LED_CTRL_BLINK_RATE_MASK                    0x7ff80000
+#define LED_CTRL_OVERRIDE_BLINK_PERIOD              BIT_19
+#define LED_CTRL_OVERRIDE_BLINK_RATE                BIT_31
+
+       /* MAC addresses. */
+       struct {
+               T3_32BIT_REGISTER High; /* Upper 2 bytes. */
+               T3_32BIT_REGISTER Low;  /* Lower 4 bytes. */
+       } MacAddr[4];
+
+       /* ACPI Mbuf pointer. */
+       T3_32BIT_REGISTER AcpiMbufPtr;
+
+       /* ACPI Length and Offset. */
+       T3_32BIT_REGISTER AcpiLengthOffset;
+#define ACPI_LENGTH_MASK                            0xffff
+#define ACPI_OFFSET_MASK                            0x0fff0000
+#define ACPI_LENGTH(x)                              x
+#define ACPI_OFFSET(x)                              ((x) << 16)
+
+       /* Transmit random backoff. */
+       T3_32BIT_REGISTER TxBackoffSeed;
+#define MAC_TX_BACKOFF_SEED_MASK                    0x3ff
+
+       /* Receive MTU */
+       T3_32BIT_REGISTER MtuSize;
+#define MAC_RX_MTU_MASK                             0xffff
+
+       /* Gigabit PCS Test. */
+       T3_32BIT_REGISTER PcsTest;
+#define MAC_PCS_TEST_DATA_PATTERN_MASK              0x0fffff
+#define MAC_PCS_TEST_ENABLE                         BIT_20
+
+       /* Transmit Gigabit Auto-Negotiation. */
+       T3_32BIT_REGISTER TxAutoNeg;
+#define MAC_AN_TX_AN_DATA_MASK                      0xffff
+
+       /* Receive Gigabit Auto-Negotiation. */
+       T3_32BIT_REGISTER RxAutoNeg;
+#define MAC_AN_RX_AN_DATA_MASK                      0xffff
+
+       /* MI Communication. */
+       T3_32BIT_REGISTER MiCom;
+#define MI_COM_CMD_MASK                             (BIT_26 | BIT_27)
+#define MI_COM_CMD_WRITE                            BIT_26
+#define MI_COM_CMD_READ                             BIT_27
+#define MI_COM_READ_FAILED                          BIT_28
+#define MI_COM_START                                BIT_29
+#define MI_COM_BUSY                                 BIT_29
+
+#define MI_COM_PHY_ADDR_MASK                        0x1f
+#define MI_COM_FIRST_PHY_ADDR_BIT                   21
+
+#define MI_COM_PHY_REG_ADDR_MASK                    0x1f
+#define MI_COM_FIRST_PHY_REG_ADDR_BIT               16
+
+#define MI_COM_PHY_DATA_MASK                        0xffff
+
+       /* MI Status. */
+       T3_32BIT_REGISTER MiStatus;
+#define MI_STATUS_ENABLE_LINK_STATUS_ATTN           BIT_0
+
+       /* MI Mode. */
+       T3_32BIT_REGISTER MiMode;
+#define MI_MODE_CLOCK_SPEED_10MHZ                   BIT_0
+#define MI_MODE_USE_SHORT_PREAMBLE                  BIT_1
+#define MI_MODE_AUTO_POLLING_ENABLE                 BIT_4
+#define MI_MODE_CORE_CLOCK_SPEED_62MHZ              BIT_15
+
+       /* Auto-polling status. */
+       T3_32BIT_REGISTER AutoPollStatus;
+#define AUTO_POLL_ERROR                             BIT_0
+
+       /* Transmit MAC mode. */
+       T3_32BIT_REGISTER TxMode;
+#define TX_MODE_RESET                               BIT_0
+#define TX_MODE_ENABLE                              BIT_1
+#define TX_MODE_ENABLE_FLOW_CONTROL                 BIT_4
+#define TX_MODE_ENABLE_BIG_BACKOFF                  BIT_5
+#define TX_MODE_ENABLE_LONG_PAUSE                   BIT_6
+
+       /* Transmit MAC status. */
+       T3_32BIT_REGISTER TxStatus;
+#define TX_STATUS_RX_CURRENTLY_XOFFED               BIT_0
+#define TX_STATUS_SENT_XOFF                         BIT_1
+#define TX_STATUS_SENT_XON                          BIT_2
+#define TX_STATUS_LINK_UP                           BIT_3
+#define TX_STATUS_ODI_UNDERRUN                      BIT_4
+#define TX_STATUS_ODI_OVERRUN                       BIT_5
+
+       /* Transmit MAC length. */
+       T3_32BIT_REGISTER TxLengths;
+#define TX_LEN_SLOT_TIME_MASK                       0xff
+#define TX_LEN_IPG_MASK                             0x0f00
+#define TX_LEN_IPG_CRS_MASK                         (BIT_12 | BIT_13)
+
+       /* Receive MAC mode. */
+       T3_32BIT_REGISTER RxMode;
+#define RX_MODE_RESET                               BIT_0
+#define RX_MODE_ENABLE                              BIT_1
+#define RX_MODE_ENABLE_FLOW_CONTROL                 BIT_2
+#define RX_MODE_KEEP_MAC_CONTROL                    BIT_3
+#define RX_MODE_KEEP_PAUSE                          BIT_4
+#define RX_MODE_ACCEPT_OVERSIZED                    BIT_5
+#define RX_MODE_ACCEPT_RUNTS                        BIT_6
+#define RX_MODE_LENGTH_CHECK                        BIT_7
+#define RX_MODE_PROMISCUOUS_MODE                    BIT_8
+#define RX_MODE_NO_CRC_CHECK                        BIT_9
+#define RX_MODE_KEEP_VLAN_TAG                       BIT_10
+
+       /* Receive MAC status. */
+       T3_32BIT_REGISTER RxStatus;
+#define RX_STATUS_REMOTE_TRANSMITTER_XOFFED         BIT_0
+#define RX_STATUS_XOFF_RECEIVED                     BIT_1
+#define RX_STATUS_XON_RECEIVED                      BIT_2
+
+       /* Hash registers. */
+       T3_32BIT_REGISTER HashReg[4];
+
+       /* Receive placement rules registers. */
+       struct {
+               T3_32BIT_REGISTER Rule;
+               T3_32BIT_REGISTER Value;
+       } RcvRules[16];
+
+#define RCV_DISABLE_RULE_MASK                       0x7fffffff
+
+#define RCV_RULE1_REJECT_BROADCAST_IDX              0x00
+#define REJECT_BROADCAST_RULE1_RULE                 0xc2000000
+#define REJECT_BROADCAST_RULE1_VALUE                0xffffffff
+
+#define RCV_RULE2_REJECT_BROADCAST_IDX              0x01
+#define REJECT_BROADCAST_RULE2_RULE                 0x86000004
+#define REJECT_BROADCAST_RULE2_VALUE                0xffffffff
+
+#if INCLUDE_5701_AX_FIX
+#define RCV_LAST_RULE_IDX                           0x04
+#else
+#define RCV_LAST_RULE_IDX                           0x02
+#endif
+
+       T3_32BIT_REGISTER RcvRuleCfg;
+#define RX_RULE_DEFAULT_CLASS                       (1 << 3)
+
+       LM_UINT8 Reserved1[140];
+
+       T3_32BIT_REGISTER SerdesCfg;
+       T3_32BIT_REGISTER SerdesStatus;
+
+       LM_UINT8 Reserved2[104];
+
+       volatile LM_UINT8 TxMacState[16];
+       volatile LM_UINT8 RxMacState[20];
+
+       LM_UINT8 Reserved3[476];
+
+       T3_32BIT_REGISTER RxStats[26];
+
+       LM_UINT8 Reserved4[24];
+
+       T3_32BIT_REGISTER TxStats[28];
+
+       LM_UINT8 Reserved5[784];
+} T3_MAC_CONTROL, *PT3_MAC_CONTROL;
+
+/******************************************************************************/
+/* Send data initiator control registers. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Mode;
+#define T3_SND_DATA_IN_MODE_RESET                       BIT_0
+#define T3_SND_DATA_IN_MODE_ENABLE                      BIT_1
+#define T3_SND_DATA_IN_MODE_STATS_OFLW_ATTN_ENABLE      BIT_2
+
+       T3_32BIT_REGISTER Status;
+#define T3_SND_DATA_IN_STATUS_STATS_OFLW_ATTN           BIT_2
+
+       T3_32BIT_REGISTER StatsCtrl;
+#define T3_SND_DATA_IN_STATS_CTRL_ENABLE                BIT_0
+#define T3_SND_DATA_IN_STATS_CTRL_FASTER_UPDATE         BIT_1
+#define T3_SND_DATA_IN_STATS_CTRL_CLEAR                 BIT_2
+#define T3_SND_DATA_IN_STATS_CTRL_FLUSH                 BIT_3
+#define T3_SND_DATA_IN_STATS_CTRL_FORCE_ZERO            BIT_4
+
+       T3_32BIT_REGISTER StatsEnableMask;
+       T3_32BIT_REGISTER StatsIncMask;
+
+       LM_UINT8 Reserved[108];
+
+       T3_32BIT_REGISTER ClassOfServCnt[16];
+       T3_32BIT_REGISTER DmaReadQFullCnt;
+       T3_32BIT_REGISTER DmaPriorityReadQFullCnt;
+       T3_32BIT_REGISTER SdcQFullCnt;
+
+       T3_32BIT_REGISTER NicRingSetSendProdIdxCnt;
+       T3_32BIT_REGISTER StatusUpdatedCnt;
+       T3_32BIT_REGISTER InterruptsCnt;
+       T3_32BIT_REGISTER AvoidInterruptsCnt;
+       T3_32BIT_REGISTER SendThresholdHitCnt;
+
+       /* Unused space. */
+       LM_UINT8 Unused[800];
+} T3_SEND_DATA_INITIATOR, *PT3_SEND_DATA_INITIATOR;
+
+/******************************************************************************/
+/* Send data completion control registers. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Mode;
+#define SND_DATA_COMP_MODE_RESET                        BIT_0
+#define SND_DATA_COMP_MODE_ENABLE                       BIT_1
+
+       /* Unused space. */
+       LM_UINT8 Unused[1020];
+} T3_SEND_DATA_COMPLETION, *PT3_SEND_DATA_COMPLETION;
+
+/******************************************************************************/
+/* Send BD Ring Selector Control Registers. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Mode;
+#define SND_BD_SEL_MODE_RESET                           BIT_0
+#define SND_BD_SEL_MODE_ENABLE                          BIT_1
+#define SND_BD_SEL_MODE_ATTN_ENABLE                     BIT_2
+
+       T3_32BIT_REGISTER Status;
+#define SND_BD_SEL_STATUS_ERROR_ATTN                    BIT_2
+
+       T3_32BIT_REGISTER HwDiag;
+
+       /* Unused space. */
+       LM_UINT8 Unused1[52];
+
+       /* Send BD Ring Selector Local NIC Send BD Consumer Index. */
+       T3_32BIT_REGISTER NicSendBdSelConIdx[16];
+
+       /* Unused space. */
+       LM_UINT8 Unused2[896];
+} T3_SEND_BD_SELECTOR, *PT3_SEND_BD_SELECTOR;
+
+/******************************************************************************/
+/* Send BD initiator control registers. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Mode;
+#define SND_BD_IN_MODE_RESET                            BIT_0
+#define SND_BD_IN_MODE_ENABLE                           BIT_1
+#define SND_BD_IN_MODE_ATTN_ENABLE                      BIT_2
+
+       T3_32BIT_REGISTER Status;
+#define SND_BD_IN_STATUS_ERROR_ATTN                     BIT_2
+
+       /* Send BD initiator local NIC send BD producer index. */
+       T3_32BIT_REGISTER NicSendBdInProdIdx[16];
+
+       /* Unused space. */
+       LM_UINT8 Unused2[952];
+} T3_SEND_BD_INITIATOR, *PT3_SEND_BD_INITIATOR;
+
+/******************************************************************************/
+/* Send BD Completion Control. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Mode;
+#define SND_BD_COMP_MODE_RESET                          BIT_0
+#define SND_BD_COMP_MODE_ENABLE                         BIT_1
+#define SND_BD_COMP_MODE_ATTN_ENABLE                    BIT_2
+
+       /* Unused space. */
+       LM_UINT8 Unused2[1020];
+} T3_SEND_BD_COMPLETION, *PT3_SEND_BD_COMPLETION;
+
+/******************************************************************************/
+/* Receive list placement control registers. */
+/******************************************************************************/
+
+typedef struct {
+       /* Mode. */
+       T3_32BIT_REGISTER Mode;
+#define RCV_LIST_PLMT_MODE_RESET                        BIT_0
+#define RCV_LIST_PLMT_MODE_ENABLE                       BIT_1
+#define RCV_LIST_PLMT_MODE_CLASS0_ATTN_ENABLE           BIT_2
+#define RCV_LIST_PLMT_MODE_MAPPING_OOR_ATTN_ENABLE      BIT_3
+#define RCV_LIST_PLMT_MODE_STATS_OFLOW_ATTN_ENABLE      BIT_4
+
+       /* Status. */
+       T3_32BIT_REGISTER Status;
+#define RCV_LIST_PLMT_STATUS_CLASS0_ATTN                BIT_2
+#define RCV_LIST_PLMT_STATUS_MAPPING_ATTN               BIT_3
+#define RCV_LIST_PLMT_STATUS_STATS_OFLOW_ATTN           BIT_4
+
+       /* Receive selector list lock register. */
+       T3_32BIT_REGISTER Lock;
+#define RCV_LIST_SEL_LOCK_REQUEST_MASK                  0xffff
+#define RCV_LIST_SEL_LOCK_GRANT_MASK                    0xffff0000
+
+       /* Selector non-empty bits. */
+       T3_32BIT_REGISTER NonEmptyBits;
+#define RCV_LIST_SEL_NON_EMPTY_MASK                     0xffff
+
+       /* Receive list placement configuration register. */
+       T3_32BIT_REGISTER Config;
+
+       /* Receive List Placement statistics Control. */
+       T3_32BIT_REGISTER StatsCtrl;
+#define RCV_LIST_STATS_ENABLE                               BIT_0
+#define RCV_LIST_STATS_FAST_UPDATE                          BIT_1
+
+       /* Receive List Placement statistics Enable Mask. */
+       T3_32BIT_REGISTER StatsEnableMask;
+
+       /* Receive List Placement statistics Increment Mask. */
+       T3_32BIT_REGISTER StatsIncMask;
+
+       /* Unused space. */
+       LM_UINT8 Unused1[224];
+
+       struct {
+               T3_32BIT_REGISTER Head;
+               T3_32BIT_REGISTER Tail;
+               T3_32BIT_REGISTER Count;
+
+               /* Unused space. */
+               LM_UINT8 Unused[4];
+       } RcvSelectorList[16];
+
+       /* Local statistics counter. */
+       T3_32BIT_REGISTER ClassOfServCnt[16];
+
+       T3_32BIT_REGISTER DropDueToFilterCnt;
+       T3_32BIT_REGISTER DmaWriteQFullCnt;
+       T3_32BIT_REGISTER DmaHighPriorityWriteQFullCnt;
+       T3_32BIT_REGISTER NoMoreReceiveBdCnt;
+       T3_32BIT_REGISTER IfInDiscardsCnt;
+       T3_32BIT_REGISTER IfInErrorsCnt;
+       T3_32BIT_REGISTER RcvThresholdHitCnt;
+
+       /* Another unused space. */
+       LM_UINT8 Unused2[420];
+} T3_RCV_LIST_PLACEMENT, *PT3_RCV_LIST_PLACEMENT;
+
+/******************************************************************************/
+/* Receive Data and Receive BD Initiator Control. */
+/******************************************************************************/
+
+typedef struct {
+       /* Mode. */
+       T3_32BIT_REGISTER Mode;
+#define RCV_DATA_BD_IN_MODE_RESET                   BIT_0
+#define RCV_DATA_BD_IN_MODE_ENABLE                  BIT_1
+#define RCV_DATA_BD_IN_MODE_JUMBO_BD_NEEDED         BIT_2
+#define RCV_DATA_BD_IN_MODE_FRAME_TOO_BIG           BIT_3
+#define RCV_DATA_BD_IN_MODE_INVALID_RING_SIZE       BIT_4
+
+       /* Status. */
+       T3_32BIT_REGISTER Status;
+#define RCV_DATA_BD_IN_STATUS_JUMBO_BD_NEEDED       BIT_2
+#define RCV_DATA_BD_IN_STATUS_FRAME_TOO_BIG         BIT_3
+#define RCV_DATA_BD_IN_STATUS_INVALID_RING_SIZE     BIT_4
+
+       /* Split frame minium size. */
+       T3_32BIT_REGISTER SplitFrameMinSize;
+
+       /* Unused space. */
+       LM_UINT8 Unused1[0x2440 - 0x240c];
+
+       /* Receive RCBs. */
+       T3_RCB JumboRcvRcb;
+       T3_RCB StdRcvRcb;
+       T3_RCB MiniRcvRcb;
+
+       /* Receive Data and Receive BD Ring Initiator Local NIC Receive */
+       /* BD Consumber Index. */
+       T3_32BIT_REGISTER NicJumboConIdx;
+       T3_32BIT_REGISTER NicStdConIdx;
+       T3_32BIT_REGISTER NicMiniConIdx;
+
+       /* Unused space. */
+       LM_UINT8 Unused2[4];
+
+       /* Receive Data and Receive BD Initiator Local Receive Return ProdIdx. */
+       T3_32BIT_REGISTER RcvDataBdProdIdx[16];
+
+       /* Receive Data and Receive BD Initiator Hardware Diagnostic. */
+       T3_32BIT_REGISTER HwDiag;
+
+       /* Unused space. */
+       LM_UINT8 Unused3[828];
+} T3_RCV_DATA_BD_INITIATOR, *PT3_RCV_DATA_BD_INITIATOR;
+
+/******************************************************************************/
+/* Receive Data Completion Control Registes. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Mode;
+#define RCV_DATA_COMP_MODE_RESET                        BIT_0
+#define RCV_DATA_COMP_MODE_ENABLE                       BIT_1
+#define RCV_DATA_COMP_MODE_ATTN_ENABLE                  BIT_2
+
+       /* Unused spaced. */
+       LM_UINT8 Unused[1020];
+} T3_RCV_DATA_COMPLETION, *PT3_RCV_DATA_COMPLETION;
+
+/******************************************************************************/
+/* Receive BD Initiator Control. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Mode;
+#define RCV_BD_IN_MODE_RESET                            BIT_0
+#define RCV_BD_IN_MODE_ENABLE                           BIT_1
+#define RCV_BD_IN_MODE_BD_IN_DIABLED_RCB_ATTN_ENABLE    BIT_2
+
+       T3_32BIT_REGISTER Status;
+#define RCV_BD_IN_STATUS_BD_IN_DIABLED_RCB_ATTN         BIT_2
+
+       T3_32BIT_REGISTER NicJumboRcvProdIdx;
+       T3_32BIT_REGISTER NicStdRcvProdIdx;
+       T3_32BIT_REGISTER NicMiniRcvProdIdx;
+
+       T3_32BIT_REGISTER MiniRcvThreshold;
+       T3_32BIT_REGISTER StdRcvThreshold;
+       T3_32BIT_REGISTER JumboRcvThreshold;
+
+       /* Unused space. */
+       LM_UINT8 Unused[992];
+} T3_RCV_BD_INITIATOR, *PT3_RCV_BD_INITIATOR;
+
+/******************************************************************************/
+/* Receive BD Completion Control Registers. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Mode;
+#define RCV_BD_COMP_MODE_RESET                          BIT_0
+#define RCV_BD_COMP_MODE_ENABLE                         BIT_1
+#define RCV_BD_COMP_MODE_ATTN_ENABLE                    BIT_2
+
+       T3_32BIT_REGISTER Status;
+#define RCV_BD_COMP_STATUS_ERROR_ATTN                   BIT_2
+
+       T3_32BIT_REGISTER NicJumboRcvBdProdIdx;
+       T3_32BIT_REGISTER NicStdRcvBdProdIdx;
+       T3_32BIT_REGISTER NicMiniRcvBdProdIdx;
+
+       /* Unused space. */
+       LM_UINT8 Unused[1004];
+} T3_RCV_BD_COMPLETION, *PT3_RCV_BD_COMPLETION;
+
+/******************************************************************************/
+/* Receive list selector control register. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Mode;
+#define RCV_LIST_SEL_MODE_RESET                         BIT_0
+#define RCV_LIST_SEL_MODE_ENABLE                        BIT_1
+#define RCV_LIST_SEL_MODE_ATTN_ENABLE                   BIT_2
+
+       T3_32BIT_REGISTER Status;
+#define RCV_LIST_SEL_STATUS_ERROR_ATTN                  BIT_2
+
+       /* Unused space. */
+       LM_UINT8 Unused[1016];
+} T3_RCV_LIST_SELECTOR, *PT3_RCV_LIST_SELECTOR;
+
+/******************************************************************************/
+/* Mbuf cluster free registers. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Mode;
+#define MBUF_CLUSTER_FREE_MODE_RESET    BIT_0
+#define MBUF_CLUSTER_FREE_MODE_ENABLE   BIT_1
+
+       T3_32BIT_REGISTER Status;
+
+       /* Unused space. */
+       LM_UINT8 Unused[1016];
+} T3_MBUF_CLUSTER_FREE, *PT3_MBUF_CLUSTER_FREE;
+
+/******************************************************************************/
+/* Host coalescing control registers. */
+/******************************************************************************/
+
+typedef struct {
+       /* Mode. */
+       T3_32BIT_REGISTER Mode;
+#define HOST_COALESCE_RESET                         BIT_0
+#define HOST_COALESCE_ENABLE                        BIT_1
+#define HOST_COALESCE_ATTN                          BIT_2
+#define HOST_COALESCE_NOW                           BIT_3
+#define HOST_COALESCE_FULL_STATUS_MODE              BIT_NONE
+#define HOST_COALESCE_64_BYTE_STATUS_MODE           BIT_7
+#define HOST_COALESCE_32_BYTE_STATUS_MODE           BIT_8
+#define HOST_COALESCE_CLEAR_TICKS_ON_RX_BD_EVENT    BIT_9
+#define HOST_COALESCE_CLEAR_TICKS_ON_TX_BD_EVENT    BIT_10
+#define HOST_COALESCE_NO_INT_ON_COALESCE_NOW_MODE   BIT_11
+#define HOST_COALESCE_NO_INT_ON_FORCE_DMAD_MODE     BIT_12
+
+       /* Status. */
+       T3_32BIT_REGISTER Status;
+#define HOST_COALESCE_ERROR_ATTN                    BIT_2
+
+       /* Receive coalescing ticks. */
+       T3_32BIT_REGISTER RxCoalescingTicks;
+
+       /* Send coalescing ticks. */
+       T3_32BIT_REGISTER TxCoalescingTicks;
+
+       /* Receive max coalesced frames. */
+       T3_32BIT_REGISTER RxMaxCoalescedFrames;
+
+       /* Send max coalesced frames. */
+       T3_32BIT_REGISTER TxMaxCoalescedFrames;
+
+       /* Receive coalescing ticks during interrupt. */
+       T3_32BIT_REGISTER RxCoalescedTickDuringInt;
+
+       /* Send coalescing ticks during interrupt. */
+       T3_32BIT_REGISTER TxCoalescedTickDuringInt;
+
+       /* Receive max coalesced frames during interrupt. */
+       T3_32BIT_REGISTER RxMaxCoalescedFramesDuringInt;
+
+       /* Send max coalesced frames during interrupt. */
+       T3_32BIT_REGISTER TxMaxCoalescedFramesDuringInt;
+
+       /* Statistics tick. */
+       T3_32BIT_REGISTER StatsCoalescingTicks;
+
+       /* Unused space. */
+       LM_UINT8 Unused2[4];
+
+       /* Statistics host address. */
+       T3_64BIT_REGISTER StatsBlkHostAddr;
+
+       /* Status block host address. */
+       T3_64BIT_REGISTER StatusBlkHostAddr;
+
+       /* Statistics NIC address. */
+       T3_32BIT_REGISTER StatsBlkNicAddr;
+
+       /* Statust block NIC address. */
+       T3_32BIT_REGISTER StatusBlkNicAddr;
+
+       /* Flow attention registers. */
+       T3_32BIT_REGISTER FlowAttn;
+
+       /* Unused space. */
+       LM_UINT8 Unused3[4];
+
+       T3_32BIT_REGISTER NicJumboRcvBdConIdx;
+       T3_32BIT_REGISTER NicStdRcvBdConIdx;
+       T3_32BIT_REGISTER NicMiniRcvBdConIdx;
+
+       /* Unused space. */
+       LM_UINT8 Unused4[36];
+
+       T3_32BIT_REGISTER NicRetProdIdx[16];
+       T3_32BIT_REGISTER NicSndBdConIdx[16];
+
+       /* Unused space. */
+       LM_UINT8 Unused5[768];
+} T3_HOST_COALESCING, *PT3_HOST_COALESCING;
+
+/******************************************************************************/
+/* Memory arbiter registers. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Mode;
+#define T3_MEM_ARBITER_MODE_RESET       BIT_0
+#define T3_MEM_ARBITER_MODE_ENABLE      BIT_1
+
+       T3_32BIT_REGISTER Status;
+
+       T3_32BIT_REGISTER ArbTrapAddrLow;
+       T3_32BIT_REGISTER ArbTrapAddrHigh;
+
+       /* Unused space. */
+       LM_UINT8 Unused[1008];
+} T3_MEM_ARBITER, *PT3_MEM_ARBITER;
+
+/******************************************************************************/
+/* Buffer manager control register. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Mode;
+#define BUFMGR_MODE_RESET                           BIT_0
+#define BUFMGR_MODE_ENABLE                          BIT_1
+#define BUFMGR_MODE_ATTN_ENABLE                     BIT_2
+#define BUFMGR_MODE_BM_TEST                         BIT_3
+#define BUFMGR_MODE_MBUF_LOW_ATTN_ENABLE            BIT_4
+
+       T3_32BIT_REGISTER Status;
+#define BUFMGR_STATUS_ERROR                         BIT_2
+#define BUFMGR_STATUS_MBUF_LOW                      BIT_4
+
+       T3_32BIT_REGISTER MbufPoolAddr;
+       T3_32BIT_REGISTER MbufPoolSize;
+       T3_32BIT_REGISTER MbufReadDmaLowWaterMark;
+       T3_32BIT_REGISTER MbufMacRxLowWaterMark;
+       T3_32BIT_REGISTER MbufHighWaterMark;
+
+       T3_32BIT_REGISTER RxCpuMbufAllocReq;
+#define BUFMGR_MBUF_ALLOC_BIT                     BIT_31
+       T3_32BIT_REGISTER RxCpuMbufAllocResp;
+       T3_32BIT_REGISTER TxCpuMbufAllocReq;
+       T3_32BIT_REGISTER TxCpuMbufAllocResp;
+
+       T3_32BIT_REGISTER DmaDescPoolAddr;
+       T3_32BIT_REGISTER DmaDescPoolSize;
+       T3_32BIT_REGISTER DmaLowWaterMark;
+       T3_32BIT_REGISTER DmaHighWaterMark;
+
+       T3_32BIT_REGISTER RxCpuDmaAllocReq;
+       T3_32BIT_REGISTER RxCpuDmaAllocResp;
+       T3_32BIT_REGISTER TxCpuDmaAllocReq;
+       T3_32BIT_REGISTER TxCpuDmaAllocResp;
+
+       T3_32BIT_REGISTER Hwdiag[3];
+
+       /* Unused space. */
+       LM_UINT8 Unused[936];
+} T3_BUFFER_MANAGER, *PT3_BUFFER_MANAGER;
+
+/******************************************************************************/
+/* Read DMA control registers. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Mode;
+#define DMA_READ_MODE_RESET                         BIT_0
+#define DMA_READ_MODE_ENABLE                        BIT_1
+#define DMA_READ_MODE_TARGET_ABORT_ATTN_ENABLE      BIT_2
+#define DMA_READ_MODE_MASTER_ABORT_ATTN_ENABLE      BIT_3
+#define DMA_READ_MODE_PARITY_ERROR_ATTN_ENABLE      BIT_4
+#define DMA_READ_MODE_ADDR_OVERFLOW_ATTN_ENABLE     BIT_5
+#define DMA_READ_MODE_FIFO_OVERRUN_ATTN_ENABLE      BIT_6
+#define DMA_READ_MODE_FIFO_UNDERRUN_ATTN_ENABLE     BIT_7
+#define DMA_READ_MODE_FIFO_OVERREAD_ATTN_ENABLE     BIT_8
+#define DMA_READ_MODE_LONG_READ_ATTN_ENABLE         BIT_9
+#define DMA_READ_MODE_SPLIT_ENABLE                  BIT_11
+#define DMA_READ_MODE_SPLIT_RESET                   BIT_12
+
+       T3_32BIT_REGISTER Status;
+#define DMA_READ_STATUS_TARGET_ABORT_ATTN           BIT_2
+#define DMA_READ_STATUS_MASTER_ABORT_ATTN           BIT_3
+#define DMA_READ_STATUS_PARITY_ERROR_ATTN           BIT_4
+#define DMA_READ_STATUS_ADDR_OVERFLOW_ATTN          BIT_5
+#define DMA_READ_STATUS_FIFO_OVERRUN_ATTN           BIT_6
+#define DMA_READ_STATUS_FIFO_UNDERRUN_ATTN          BIT_7
+#define DMA_READ_STATUS_FIFO_OVERREAD_ATTN          BIT_8
+#define DMA_READ_STATUS_LONG_READ_ATTN              BIT_9
+
+       /* Unused space. */
+       LM_UINT8 Unused[1016];
+} T3_DMA_READ, *PT3_DMA_READ;
+
+typedef union T3_CPU {
+       struct {
+               T3_32BIT_REGISTER mode;
+#define CPU_MODE_HALT   BIT_10
+#define CPU_MODE_RESET  BIT_0
+               T3_32BIT_REGISTER state;
+               T3_32BIT_REGISTER EventMask;
+               T3_32BIT_REGISTER reserved1[4];
+               T3_32BIT_REGISTER PC;
+               T3_32BIT_REGISTER Instruction;
+               T3_32BIT_REGISTER SpadUnderflow;
+               T3_32BIT_REGISTER WatchdogClear;
+               T3_32BIT_REGISTER WatchdogVector;
+               T3_32BIT_REGISTER WatchdogSavedPC;
+               T3_32BIT_REGISTER HardwareBp;
+               T3_32BIT_REGISTER reserved2[3];
+               T3_32BIT_REGISTER WatchdogSavedState;
+               T3_32BIT_REGISTER LastBrchAddr;
+               T3_32BIT_REGISTER SpadUnderflowSet;
+               T3_32BIT_REGISTER reserved3[(0x200 - 0x50) / 4];
+               T3_32BIT_REGISTER Regs[32];
+               T3_32BIT_REGISTER reserved4[(0x400 - 0x280) / 4];
+       } reg;
+} T3_CPU, *PT3_CPU;
+
+/******************************************************************************/
+/* Write DMA control registers. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Mode;
+#define DMA_WRITE_MODE_RESET                        BIT_0
+#define DMA_WRITE_MODE_ENABLE                       BIT_1
+#define DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE     BIT_2
+#define DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE     BIT_3
+#define DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE     BIT_4
+#define DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE    BIT_5
+#define DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE     BIT_6
+#define DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE    BIT_7
+#define DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE    BIT_8
+#define DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE        BIT_9
+
+       T3_32BIT_REGISTER Status;
+#define DMA_WRITE_STATUS_TARGET_ABORT_ATTN          BIT_2
+#define DMA_WRITE_STATUS_MASTER_ABORT_ATTN          BIT_3
+#define DMA_WRITE_STATUS_PARITY_ERROR_ATTN          BIT_4
+#define DMA_WRITE_STATUS_ADDR_OVERFLOW_ATTN         BIT_5
+#define DMA_WRITE_STATUS_FIFO_OVERRUN_ATTN          BIT_6
+#define DMA_WRITE_STATUS_FIFO_UNDERRUN_ATTN         BIT_7
+#define DMA_WRITE_STATUS_FIFO_OVERREAD_ATTN         BIT_8
+#define DMA_WRITE_STATUS_LONG_READ_ATTN             BIT_9
+
+       /* Unused space. */
+       LM_UINT8 Unused[1016];
+} T3_DMA_WRITE, *PT3_DMA_WRITE;
+
+/******************************************************************************/
+/* Mailbox registers. */
+/******************************************************************************/
+
+typedef struct {
+       /* Interrupt mailbox registers. */
+       T3_64BIT_REGISTER Interrupt[4];
+
+       /* General mailbox registers. */
+       T3_64BIT_REGISTER General[8];
+
+       /* Reload statistics mailbox. */
+       T3_64BIT_REGISTER ReloadStat;
+
+       /* Receive BD ring producer index registers. */
+       T3_64BIT_REGISTER RcvStdProdIdx;
+       T3_64BIT_REGISTER RcvJumboProdIdx;
+       T3_64BIT_REGISTER RcvMiniProdIdx;
+
+       /* Receive return ring consumer index registers. */
+       T3_64BIT_REGISTER RcvRetConIdx[16];
+
+       /* Send BD ring host producer index registers. */
+       T3_64BIT_REGISTER SendHostProdIdx[16];
+
+       /* Send BD ring nic producer index registers. */
+       T3_64BIT_REGISTER SendNicProdIdx[16];
+} T3_MAILBOX, *PT3_MAILBOX;
+
+typedef struct {
+       T3_MAILBOX Mailbox;
+
+       /* Priority mailbox registers. */
+       T3_32BIT_REGISTER HighPriorityEventVector;
+       T3_32BIT_REGISTER HighPriorityEventMask;
+       T3_32BIT_REGISTER LowPriorityEventVector;
+       T3_32BIT_REGISTER LowPriorityEventMask;
+
+       /* Unused space. */
+       LM_UINT8 Unused[496];
+} T3_GRC_MAILBOX, *PT3_GRC_MAILBOX;
+
+/******************************************************************************/
+/* Flow through queues. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Reset;
+
+       LM_UINT8 Unused[12];
+
+       T3_32BIT_REGISTER DmaNormalReadFtqCtrl;
+       T3_32BIT_REGISTER DmaNormalReadFtqFullCnt;
+       T3_32BIT_REGISTER DmaNormalReadFtqFifoEnqueueDequeue;
+       T3_32BIT_REGISTER DmaNormalReadFtqFifoWritePeek;
+
+       T3_32BIT_REGISTER DmaHighReadFtqCtrl;
+       T3_32BIT_REGISTER DmaHighReadFtqFullCnt;
+       T3_32BIT_REGISTER DmaHighReadFtqFifoEnqueueDequeue;
+       T3_32BIT_REGISTER DmaHighReadFtqFifoWritePeek;
+
+       T3_32BIT_REGISTER DmaCompDiscardFtqCtrl;
+       T3_32BIT_REGISTER DmaCompDiscardFtqFullCnt;
+       T3_32BIT_REGISTER DmaCompDiscardFtqFifoEnqueueDequeue;
+       T3_32BIT_REGISTER DmaCompDiscardFtqFifoWritePeek;
+
+       T3_32BIT_REGISTER SendBdCompFtqCtrl;
+       T3_32BIT_REGISTER SendBdCompFtqFullCnt;
+       T3_32BIT_REGISTER SendBdCompFtqFifoEnqueueDequeue;
+       T3_32BIT_REGISTER SendBdCompFtqFifoWritePeek;
+
+       T3_32BIT_REGISTER SendDataInitiatorFtqCtrl;
+       T3_32BIT_REGISTER SendDataInitiatorFtqFullCnt;
+       T3_32BIT_REGISTER SendDataInitiatorFtqFifoEnqueueDequeue;
+       T3_32BIT_REGISTER SendDataInitiatorFtqFifoWritePeek;
+
+       T3_32BIT_REGISTER DmaNormalWriteFtqCtrl;
+       T3_32BIT_REGISTER DmaNormalWriteFtqFullCnt;
+       T3_32BIT_REGISTER DmaNormalWriteFtqFifoEnqueueDequeue;
+       T3_32BIT_REGISTER DmaNormalWriteFtqFifoWritePeek;
+
+       T3_32BIT_REGISTER DmaHighWriteFtqCtrl;
+       T3_32BIT_REGISTER DmaHighWriteFtqFullCnt;
+       T3_32BIT_REGISTER DmaHighWriteFtqFifoEnqueueDequeue;
+       T3_32BIT_REGISTER DmaHighWriteFtqFifoWritePeek;
+
+       T3_32BIT_REGISTER SwType1FtqCtrl;
+       T3_32BIT_REGISTER SwType1FtqFullCnt;
+       T3_32BIT_REGISTER SwType1FtqFifoEnqueueDequeue;
+       T3_32BIT_REGISTER SwType1FtqFifoWritePeek;
+
+       T3_32BIT_REGISTER SendDataCompFtqCtrl;
+       T3_32BIT_REGISTER SendDataCompFtqFullCnt;
+       T3_32BIT_REGISTER SendDataCompFtqFifoEnqueueDequeue;
+       T3_32BIT_REGISTER SendDataCompFtqFifoWritePeek;
+
+       T3_32BIT_REGISTER HostCoalesceFtqCtrl;
+       T3_32BIT_REGISTER HostCoalesceFtqFullCnt;
+       T3_32BIT_REGISTER HostCoalesceFtqFifoEnqueueDequeue;
+       T3_32BIT_REGISTER HostCoalesceFtqFifoWritePeek;
+
+       T3_32BIT_REGISTER MacTxFtqCtrl;
+       T3_32BIT_REGISTER MacTxFtqFullCnt;
+       T3_32BIT_REGISTER MacTxFtqFifoEnqueueDequeue;
+       T3_32BIT_REGISTER MacTxFtqFifoWritePeek;
+
+       T3_32BIT_REGISTER MbufClustFreeFtqCtrl;
+       T3_32BIT_REGISTER MbufClustFreeFtqFullCnt;
+       T3_32BIT_REGISTER MbufClustFreeFtqFifoEnqueueDequeue;
+       T3_32BIT_REGISTER MbufClustFreeFtqFifoWritePeek;
+
+       T3_32BIT_REGISTER RcvBdCompFtqCtrl;
+       T3_32BIT_REGISTER RcvBdCompFtqFullCnt;
+       T3_32BIT_REGISTER RcvBdCompFtqFifoEnqueueDequeue;
+       T3_32BIT_REGISTER RcvBdCompFtqFifoWritePeek;
+
+       T3_32BIT_REGISTER RcvListPlmtFtqCtrl;
+       T3_32BIT_REGISTER RcvListPlmtFtqFullCnt;
+       T3_32BIT_REGISTER RcvListPlmtFtqFifoEnqueueDequeue;
+       T3_32BIT_REGISTER RcvListPlmtFtqFifoWritePeek;
+
+       T3_32BIT_REGISTER RcvDataBdInitiatorFtqCtrl;
+       T3_32BIT_REGISTER RcvDataBdInitiatorFtqFullCnt;
+       T3_32BIT_REGISTER RcvDataBdInitiatorFtqFifoEnqueueDequeue;
+       T3_32BIT_REGISTER RcvDataBdInitiatorFtqFifoWritePeek;
+
+       T3_32BIT_REGISTER RcvDataCompFtqCtrl;
+       T3_32BIT_REGISTER RcvDataCompFtqFullCnt;
+       T3_32BIT_REGISTER RcvDataCompFtqFifoEnqueueDequeue;
+       T3_32BIT_REGISTER RcvDataCompFtqFifoWritePeek;
+
+       T3_32BIT_REGISTER SwType2FtqCtrl;
+       T3_32BIT_REGISTER SwType2FtqFullCnt;
+       T3_32BIT_REGISTER SwType2FtqFifoEnqueueDequeue;
+       T3_32BIT_REGISTER SwType2FtqFifoWritePeek;
+
+       /* Unused space. */
+       LM_UINT8 Unused2[736];
+} T3_FTQ, *PT3_FTQ;
+
+/******************************************************************************/
+/* Message signaled interrupt registers. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Mode;
+#define MSI_MODE_RESET       BIT_0
+#define MSI_MODE_ENABLE      BIT_1
+       T3_32BIT_REGISTER Status;
+
+       T3_32BIT_REGISTER MsiFifoAccess;
+
+       /* Unused space. */
+       LM_UINT8 Unused[1012];
+} T3_MSG_SIGNALED_INT, *PT3_MSG_SIGNALED_INT;
+
+/******************************************************************************/
+/* DMA Completion registes. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Mode;
+#define DMA_COMP_MODE_RESET                         BIT_0
+#define DMA_COMP_MODE_ENABLE                        BIT_1
+
+       /* Unused space. */
+       LM_UINT8 Unused[1020];
+} T3_DMA_COMPLETION, *PT3_DMA_COMPLETION;
+
+/******************************************************************************/
+/* GRC registers. */
+/******************************************************************************/
+
+typedef struct {
+       /* Mode control register. */
+       T3_32BIT_REGISTER Mode;
+#define GRC_MODE_UPDATE_ON_COALESCING               BIT_0
+#define GRC_MODE_BYTE_SWAP_NON_FRAME_DATA           BIT_1
+#define GRC_MODE_WORD_SWAP_NON_FRAME_DATA           BIT_2
+#define GRC_MODE_BYTE_SWAP_DATA                     BIT_4
+#define GRC_MODE_WORD_SWAP_DATA                     BIT_5
+#define GRC_MODE_SPLIT_HEADER_MODE                  BIT_8
+#define GRC_MODE_NO_FRAME_CRACKING                  BIT_9
+#define GRC_MODE_INCLUDE_CRC                        BIT_10
+#define GRC_MODE_ALLOW_BAD_FRAMES                   BIT_11
+#define GRC_MODE_NO_INTERRUPT_ON_SENDS              BIT_13
+#define GRC_MODE_NO_INTERRUPT_ON_RECEIVE            BIT_14
+#define GRC_MODE_FORCE_32BIT_PCI_BUS_MODE           BIT_15
+#define GRC_MODE_HOST_STACK_UP                      BIT_16
+#define GRC_MODE_HOST_SEND_BDS                      BIT_17
+#define GRC_MODE_TX_NO_PSEUDO_HEADER_CHKSUM         BIT_20
+#define GRC_MODE_RX_NO_PSEUDO_HEADER_CHKSUM         BIT_23
+#define GRC_MODE_INT_ON_TX_CPU_ATTN                 BIT_24
+#define GRC_MODE_INT_ON_RX_CPU_ATTN                 BIT_25
+#define GRC_MODE_INT_ON_MAC_ATTN                    BIT_26
+#define GRC_MODE_INT_ON_DMA_ATTN                    BIT_27
+#define GRC_MODE_INT_ON_FLOW_ATTN                   BIT_28
+#define GRC_MODE_4X_NIC_BASED_SEND_RINGS            BIT_29
+#define GRC_MODE_MULTICAST_FRAME_ENABLE             BIT_30
+
+       /* Misc configuration register. */
+       T3_32BIT_REGISTER MiscCfg;
+#define GRC_MISC_CFG_CORE_CLOCK_RESET               BIT_0
+#define GRC_MISC_PRESCALAR_TIMER_MASK               0xfe
+#define GRC_MISC_BD_ID_MASK                         0x0001e000
+#define GRC_MISC_BD_ID_5700                         0x0001e000
+#define GRC_MISC_BD_ID_5701                         0x00000000
+#define GRC_MISC_BD_ID_5703                         0x00000000
+#define GRC_MISC_BD_ID_5703S                        0x00002000
+#define GRC_MISC_BD_ID_5702FE                       0x00004000
+#define GRC_MISC_BD_ID_5704                         0x00000000
+#define GRC_MISC_BD_ID_5704CIOBE                    0x00004000
+
+       /* Miscellaneous local control register. */
+       T3_32BIT_REGISTER LocalCtrl;
+#define GRC_MISC_LOCAL_CTRL_INT_ACTIVE              BIT_0
+#define GRC_MISC_LOCAL_CTRL_CLEAR_INT               BIT_1
+#define GRC_MISC_LOCAL_CTRL_SET_INT                 BIT_2
+#define GRC_MISC_LOCAL_CTRL_INT_ON_ATTN             BIT_3
+#define GRC_MISC_LOCAL_CTRL_GPIO_INPUT0             BIT_8
+#define GRC_MISC_LOCAL_CTRL_GPIO_INPUT1             BIT_9
+#define GRC_MISC_LOCAL_CTRL_GPIO_INPUT2             BIT_10
+#define GRC_MISC_LOCAL_CTRL_GPIO_OE0                BIT_11
+#define GRC_MISC_LOCAL_CTRL_GPIO_OE1                BIT_12
+#define GRC_MISC_LOCAL_CTRL_GPIO_OE2                BIT_13
+#define GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0            BIT_14
+#define GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1            BIT_15
+#define GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2            BIT_16
+#define GRC_MISC_LOCAL_CTRL_ENABLE_EXT_MEMORY       BIT_17
+#define GRC_MISC_LOCAL_CTRL_BANK_SELECT             BIT_21
+#define GRC_MISC_LOCAL_CTRL_SSRAM_TYPE              BIT_22
+
+#define GRC_MISC_MEMSIZE_256K     0
+#define GRC_MISC_MEMSIZE_512K     (1 << 18)
+#define GRC_MISC_MEMSIZE_1024K    (2 << 18)
+#define GRC_MISC_MEMSIZE_2048K    (3 << 18)
+#define GRC_MISC_MEMSIZE_4096K    (4 << 18)
+#define GRC_MISC_MEMSIZE_8192K    (5 << 18)
+#define GRC_MISC_MEMSIZE_16M      (6 << 18)
+#define GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM            BIT_24
+
+       T3_32BIT_REGISTER Timer;
+
+       T3_32BIT_REGISTER RxCpuEvent;
+       T3_32BIT_REGISTER RxTimerRef;
+       T3_32BIT_REGISTER RxCpuSemaphore;
+       T3_32BIT_REGISTER RemoteRxCpuAttn;
+
+       T3_32BIT_REGISTER TxCpuEvent;
+       T3_32BIT_REGISTER TxTimerRef;
+       T3_32BIT_REGISTER TxCpuSemaphore;
+       T3_32BIT_REGISTER RemoteTxCpuAttn;
+
+       T3_64BIT_REGISTER MemoryPowerUp;
+
+       T3_32BIT_REGISTER EepromAddr;
+#define SEEPROM_ADDR_WRITE       0
+#define SEEPROM_ADDR_READ        (1 << 31)
+#define SEEPROM_ADDR_RW_MASK     0x80000000
+#define SEEPROM_ADDR_COMPLETE    (1 << 30)
+#define SEEPROM_ADDR_FSM_RESET   (1 << 29)
+#define SEEPROM_ADDR_DEV_ID(x)   (x << 26)
+#define SEEPROM_ADDR_DEV_ID_MASK 0x1c000000
+#define SEEPROM_ADDR_START       (1 << 25)
+#define SEEPROM_ADDR_CLK_PERD(x) (x << 16)
+#define SEEPROM_ADDR_ADDRESS(x)  (x & 0xfffc)
+#define SEEPROM_ADDR_ADDRESS_MASK 0x0000ffff
+
+#define SEEPROM_CLOCK_PERIOD        60
+#define SEEPROM_CHIP_SIZE           (64 * 1024)
+
+       T3_32BIT_REGISTER EepromData;
+       T3_32BIT_REGISTER EepromCtrl;
+
+       T3_32BIT_REGISTER MdiCtrl;
+       T3_32BIT_REGISTER SepromDelay;
+
+       /* Unused space. */
+       LM_UINT8 Unused[948];
+} T3_GRC, *PT3_GRC;
+
+/******************************************************************************/
+/* NVRAM control registers. */
+/******************************************************************************/
+
+typedef struct {
+       T3_32BIT_REGISTER Cmd;
+#define NVRAM_CMD_RESET                             BIT_0
+#define NVRAM_CMD_DONE                              BIT_3
+#define NVRAM_CMD_DO_IT                             BIT_4
+#define NVRAM_CMD_WR                                BIT_5
+#define NVRAM_CMD_RD                                BIT_NONE
+#define NVRAM_CMD_ERASE                             BIT_6
+#define NVRAM_CMD_FIRST                             BIT_7
+#define NVRAM_CMD_LAST                              BIT_8
+
+       T3_32BIT_REGISTER Status;
+       T3_32BIT_REGISTER WriteData;
+
+       T3_32BIT_REGISTER Addr;
+#define NVRAM_ADDRESS_MASK                          0xffffff
+
+       T3_32BIT_REGISTER ReadData;
+
+       /* Flash config 1 register. */
+       T3_32BIT_REGISTER Config1;
+#define FLASH_INTERFACE_ENABLE                      BIT_0
+#define FLASH_SSRAM_BUFFERRED_MODE                  BIT_1
+#define FLASH_PASS_THRU_MODE                        BIT_2
+#define FLASH_BIT_BANG_MODE                         BIT_3
+#define FLASH_COMPAT_BYPASS                         BIT_31
+
+       /* Buffered flash (Atmel: AT45DB011B) specific information */
+#define BUFFERED_FLASH_PAGE_POS         9
+#define BUFFERED_FLASH_BYTE_ADDR_MASK   ((1<<BUFFERED_FLASH_PAGE_POS) - 1)
+#define BUFFERED_FLASH_PAGE_SIZE        264
+#define BUFFERED_FLASH_PHY_PAGE_SIZE    512
+
+       T3_32BIT_REGISTER Config2;
+       T3_32BIT_REGISTER Config3;
+       T3_32BIT_REGISTER SwArb;
+#define SW_ARB_REQ_SET0                             BIT_0
+#define SW_ARB_REQ_SET1                             BIT_1
+#define SW_ARB_REQ_SET2                             BIT_2
+#define SW_ARB_REQ_SET3                             BIT_3
+#define SW_ARB_REQ_CLR0                             BIT_4
+#define SW_ARB_REQ_CLR1                             BIT_5
+#define SW_ARB_REQ_CLR2                             BIT_6
+#define SW_ARB_REQ_CLR3                             BIT_7
+#define SW_ARB_GNT0                                 BIT_8
+#define SW_ARB_GNT1                                 BIT_9
+#define SW_ARB_GNT2                                 BIT_10
+#define SW_ARB_GNT3                                 BIT_11
+#define SW_ARB_REQ0                                 BIT_12
+#define SW_ARB_REQ1                                 BIT_13
+#define SW_ARB_REQ2                                 BIT_14
+#define SW_ARB_REQ3                                 BIT_15
+
+       /* Unused space. */
+       LM_UINT8 Unused[988];
+} T3_NVRAM, *PT3_NVRAM;
+
+/******************************************************************************/
+/* NIC's internal memory. */
+/******************************************************************************/
+
+typedef struct {
+       /* Page zero for the internal CPUs. */
+       LM_UINT8 PageZero[0x100];       /* 0x0000 */
+
+       /* Send RCBs. */
+       T3_RCB SendRcb[16];     /* 0x0100 */
+
+       /* Receive Return RCBs. */
+       T3_RCB RcvRetRcb[16];   /* 0x0200 */
+
+       /* Statistics block. */
+       T3_STATS_BLOCK StatsBlk;        /* 0x0300 */
+
+       /* Status block. */
+       T3_STATUS_BLOCK StatusBlk;      /* 0x0b00 */
+
+       /* Reserved for software. */
+       LM_UINT8 Reserved[1200];        /* 0x0b50 */
+
+       /* Unmapped region. */
+       LM_UINT8 Unmapped[4096];        /* 0x1000 */
+
+       /* DMA descriptors. */
+       LM_UINT8 DmaDesc[8192]; /* 0x2000 */
+
+       /* Buffer descriptors. */
+       LM_UINT8 BufferDesc[16384];     /* 0x4000 */
+} T3_FIRST_32K_SRAM, *PT3_FIRST_32K_SRAM;
+
+/******************************************************************************/
+/* Memory layout. */
+/******************************************************************************/
+
+typedef struct {
+       /* PCI configuration registers. */
+       T3_PCI_CONFIGURATION PciCfg;
+
+       /* Unused. */
+       LM_UINT8 Unused1[0x100];        /* 0x0100 */
+
+       /* Mailbox . */
+       T3_MAILBOX Mailbox;     /* 0x0200 */
+
+       /* MAC control registers. */
+       T3_MAC_CONTROL MacCtrl; /* 0x0400 */
+
+       /* Send data initiator control registers. */
+       T3_SEND_DATA_INITIATOR SndDataIn;       /* 0x0c00 */
+
+       /* Send data completion Control registers. */
+       T3_SEND_DATA_COMPLETION SndDataComp;    /* 0x1000 */
+
+       /* Send BD ring selector. */
+       T3_SEND_BD_SELECTOR SndBdSel;   /* 0x1400 */
+
+       /* Send BD initiator control registers. */
+       T3_SEND_BD_INITIATOR SndBdIn;   /* 0x1800 */
+
+       /* Send BD completion control registers. */
+       T3_SEND_BD_COMPLETION SndBdComp;        /* 0x1c00 */
+
+       /* Receive list placement control registers. */
+       T3_RCV_LIST_PLACEMENT RcvListPlmt;      /* 0x2000 */
+
+       /* Receive Data and Receive BD Initiator Control. */
+       T3_RCV_DATA_BD_INITIATOR RcvDataBdIn;   /* 0x2400 */
+
+       /* Receive Data Completion Control */
+       T3_RCV_DATA_COMPLETION RcvDataComp;     /* 0x2800 */
+
+       /* Receive BD Initiator Control Registers. */
+       T3_RCV_BD_INITIATOR RcvBdIn;    /* 0x2c00 */
+
+       /* Receive BD Completion Control Registers. */
+       T3_RCV_BD_COMPLETION RcvBdComp; /* 0x3000 */
+
+       /* Receive list selector control registers. */
+       T3_RCV_LIST_SELECTOR RcvListSel;        /* 0x3400 */
+
+       /* Mbuf cluster free registers. */
+       T3_MBUF_CLUSTER_FREE MbufClusterFree;   /* 0x3800 */
+
+       /* Host coalescing control registers. */
+       T3_HOST_COALESCING HostCoalesce;        /* 0x3c00 */
+
+       /* Memory arbiter control registers. */
+       T3_MEM_ARBITER MemArbiter;      /* 0x4000 */
+
+       /* Buffer manger control registers. */
+       T3_BUFFER_MANAGER BufMgr;       /* 0x4400 */
+
+       /* Read DMA control registers. */
+       T3_DMA_READ DmaRead;    /* 0x4800 */
+
+       /* Write DMA control registers. */
+       T3_DMA_WRITE DmaWrite;  /* 0x4c00 */
+
+       T3_CPU rxCpu;           /* 0x5000 */
+       T3_CPU txCpu;           /* 0x5400 */
+
+       /* Mailboxes. */
+       T3_GRC_MAILBOX GrcMailbox;      /* 0x5800 */
+
+       /* Flow Through queues. */
+       T3_FTQ Ftq;             /* 0x5c00 */
+
+       /* Message signaled interrupt registes. */
+       T3_MSG_SIGNALED_INT Msi;        /* 0x6000 */
+
+       /* DMA completion registers. */
+       T3_DMA_COMPLETION DmaComp;      /* 0x6400 */
+
+       /* GRC registers. */
+       T3_GRC Grc;             /* 0x6800 */
+
+       /* Unused space. */
+       LM_UINT8 Unused2[1024]; /* 0x6c00 */
+
+       /* NVRAM registers. */
+       T3_NVRAM Nvram;         /* 0x7000 */
+
+       /* Unused space. */
+       LM_UINT8 Unused3[3072]; /* 0x7400 */
+
+       /* The 32k memory window into the NIC's */
+       /* internal memory.  The memory window is */
+       /* controlled by the Memory Window Base */
+       /* Address register.  This register is located */
+       /* in the PCI configuration space. */
+       union {                 /* 0x8000 */
+               T3_FIRST_32K_SRAM First32k;
+
+               /* Use the memory window base address register to determine the */
+               /* MBUF segment. */
+               LM_UINT32 Mbuf[32768 / 4];
+               LM_UINT32 MemBlock32K[32768 / 4];
+       } uIntMem;
+} T3_STD_MEM_MAP, *PT3_STD_MEM_MAP;
+
+/******************************************************************************/
+/* Adapter info. */
+/******************************************************************************/
+
+typedef struct {
+       LM_UINT16 Svid;
+       LM_UINT16 Ssid;
+       LM_UINT32 PhyId;
+       LM_UINT32 Serdes;       /* 0 = copper PHY, 1 = Serdes */
+} LM_ADAPTER_INFO, *PLM_ADAPTER_INFO;
+
+/******************************************************************************/
+/* Packet queues. */
+/******************************************************************************/
+
+DECLARE_QUEUE_TYPE (LM_RX_PACKET_Q, MAX_RX_PACKET_DESC_COUNT);
+DECLARE_QUEUE_TYPE (LM_TX_PACKET_Q, MAX_TX_PACKET_DESC_COUNT);
+
+/******************************************************************************/
+/* Tx counters. */
+/******************************************************************************/
+
+typedef struct {
+       LM_COUNTER TxPacketGoodCnt;
+       LM_COUNTER TxBytesGoodCnt;
+       LM_COUNTER TxPacketAbortedCnt;
+       LM_COUNTER NoSendBdLeftCnt;
+       LM_COUNTER NoMapRegisterLeftCnt;
+       LM_COUNTER TooManyFragmentsCnt;
+       LM_COUNTER NoTxPacketDescCnt;
+} LM_TX_COUNTERS, *PLM_TX_COUNTERS;
+
+/******************************************************************************/
+/* Rx counters. */
+/******************************************************************************/
+
+typedef struct {
+       LM_COUNTER RxPacketGoodCnt;
+       LM_COUNTER RxBytesGoodCnt;
+       LM_COUNTER RxPacketErrCnt;
+       LM_COUNTER RxErrCrcCnt;
+       LM_COUNTER RxErrCollCnt;
+       LM_COUNTER RxErrLinkLostCnt;
+       LM_COUNTER RxErrPhyDecodeCnt;
+       LM_COUNTER RxErrOddNibbleCnt;
+       LM_COUNTER RxErrMacAbortCnt;
+       LM_COUNTER RxErrShortPacketCnt;
+       LM_COUNTER RxErrNoResourceCnt;
+       LM_COUNTER RxErrLargePacketCnt;
+} LM_RX_COUNTERS, *PLM_RX_COUNTERS;
+
+/******************************************************************************/
+/* Receive producer rings. */
+/******************************************************************************/
+
+typedef enum {
+       T3_UNKNOWN_RCV_PROD_RING = 0,
+       T3_STD_RCV_PROD_RING = 1,
+       T3_MINI_RCV_PROD_RING = 2,
+       T3_JUMBO_RCV_PROD_RING = 3
+} T3_RCV_PROD_RING, *PT3_RCV_PROD_RING;
+
+/******************************************************************************/
+/* Packet descriptor. */
+/******************************************************************************/
+
+#define LM_PACKET_SIGNATURE_TX              0x6861766b
+#define LM_PACKET_SIGNATURE_RX              0x6b766168
+
+typedef struct _LM_PACKET {
+       /* Set in LM. */
+       LM_STATUS PacketStatus;
+
+       /* Set in LM for Rx, in UM for Tx. */
+       LM_UINT32 PacketSize;
+
+       LM_UINT16 Flags;
+
+       LM_UINT16 VlanTag;
+
+       union {
+               /* Send info. */
+               struct {
+                       /* Set up by UM. */
+                       LM_UINT32 FragCount;
+
+               } Tx;
+
+               /* Receive info. */
+               struct {
+                       /* This descriptor belongs to either Std, Mini, or Jumbo ring. */
+                       T3_RCV_PROD_RING RcvProdRing;
+
+                       /* Receive buffer size */
+                       LM_UINT32 RxBufferSize;
+
+                       /* Checksum information. */
+                       LM_UINT16 IpChecksum;
+                       LM_UINT16 TcpUdpChecksum;
+
+               } Rx;
+       } u;
+} LM_PACKET;
+
+/******************************************************************************/
+/* Tigon3 device block. */
+/******************************************************************************/
+
+typedef struct _LM_DEVICE_BLOCK {
+       int index;              /* Device ID */
+       /* Memory view. */
+       PT3_STD_MEM_MAP pMemView;
+
+       /* Base address of the block of memory in which the LM_PACKET descriptors */
+       /* are allocated from. */
+       PLM_VOID pPacketDescBase;
+
+       LM_UINT32 MiscHostCtrl;
+       LM_UINT32 GrcLocalCtrl;
+       LM_UINT32 DmaReadWriteCtrl;
+       LM_UINT32 PciState;
+
+       /* Rx info */
+       LM_UINT32 RxStdDescCnt;
+       LM_UINT32 RxStdQueuedCnt;
+       LM_UINT32 RxStdProdIdx;
+
+       PT3_RCV_BD pRxStdBdVirt;
+       LM_PHYSICAL_ADDRESS RxStdBdPhy;
+
+       LM_UINT32 RxPacketDescCnt;
+       LM_RX_PACKET_Q RxPacketFreeQ;
+       LM_RX_PACKET_Q RxPacketReceivedQ;
+
+       /* Receive info. */
+       PT3_RCV_BD pRcvRetBdVirt;
+       LM_PHYSICAL_ADDRESS RcvRetBdPhy;
+       LM_UINT32 RcvRetConIdx;
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+       LM_UINT32 RxJumboDescCnt;
+       LM_UINT32 RxJumboBufferSize;
+       LM_UINT32 RxJumboQueuedCnt;
+
+       LM_UINT32 RxJumboProdIdx;
+
+       PT3_RCV_BD pRxJumboBdVirt;
+       LM_PHYSICAL_ADDRESS RxJumboBdPhy;
+#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
+
+       /* These values are used by the upper module to inform the protocol */
+       /* of the maximum transmit/receive packet size. */
+       LM_UINT32 TxMtu;        /* Does not include CRC. */
+       LM_UINT32 RxMtu;        /* Does not include CRC. */
+
+       /* We need to shadow the EMAC, Rx, Tx mode registers.  With B0 silicon, */
+       /* we may have problems reading any MAC registers in 10mb mode. */
+       LM_UINT32 MacMode;
+       LM_UINT32 RxMode;
+       LM_UINT32 TxMode;
+
+       /* MiMode register. */
+       LM_UINT32 MiMode;
+
+       /* Host coalesce mode register. */
+       LM_UINT32 CoalesceMode;
+
+       /* Send info. */
+       LM_UINT32 TxPacketDescCnt;
+
+       /* Tx info. */
+       LM_TX_PACKET_Q TxPacketFreeQ;
+       LM_TX_PACKET_Q TxPacketActiveQ;
+       LM_TX_PACKET_Q TxPacketXmittedQ;
+
+       /* Pointers to SendBd. */
+       PT3_SND_BD pSendBdVirt;
+       LM_PHYSICAL_ADDRESS SendBdPhy;  /* Only valid for Host based Send BD. */
+
+       /* Send producer and consumer indices. */
+       LM_UINT32 SendProdIdx;
+       LM_UINT32 SendConIdx;
+
+       /* Number of BD left. */
+       atomic_t SendBdLeft;
+
+       T3_SND_BD ShadowSendBd[T3_SEND_RCB_ENTRY_COUNT];
+
+       /* Counters. */
+       LM_RX_COUNTERS RxCounters;
+       LM_TX_COUNTERS TxCounters;
+
+       /* Host coalescing parameters. */
+       LM_UINT32 RxCoalescingTicks;
+       LM_UINT32 TxCoalescingTicks;
+       LM_UINT32 RxMaxCoalescedFrames;
+       LM_UINT32 TxMaxCoalescedFrames;
+       LM_UINT32 StatsCoalescingTicks;
+       LM_UINT32 RxCoalescingTicksDuringInt;
+       LM_UINT32 TxCoalescingTicksDuringInt;
+       LM_UINT32 RxMaxCoalescedFramesDuringInt;
+       LM_UINT32 TxMaxCoalescedFramesDuringInt;
+
+       /* DMA water marks. */
+       LM_UINT32 DmaMbufLowMark;
+       LM_UINT32 RxMacMbufLowMark;
+       LM_UINT32 MbufHighMark;
+
+       /* Status block. */
+       PT3_STATUS_BLOCK pStatusBlkVirt;
+       LM_PHYSICAL_ADDRESS StatusBlkPhy;
+
+       /* Statistics block. */
+       PT3_STATS_BLOCK pStatsBlkVirt;
+       LM_PHYSICAL_ADDRESS StatsBlkPhy;
+
+       /* Current receive mask. */
+       LM_UINT32 ReceiveMask;
+
+       /* Task offload capabilities. */
+       LM_TASK_OFFLOAD TaskOffloadCap;
+
+       /* Task offload selected. */
+       LM_TASK_OFFLOAD TaskToOffload;
+
+       /* Wake up capability. */
+       LM_WAKE_UP_MODE WakeUpModeCap;
+
+       /* Wake up capability. */
+       LM_WAKE_UP_MODE WakeUpMode;
+
+       /* Flow control. */
+       LM_FLOW_CONTROL FlowControlCap;
+       LM_FLOW_CONTROL FlowControl;
+
+       /* Enable or disable PCI MWI. */
+       LM_UINT32 EnableMWI;
+
+       /* Enable 5701 tagged status mode. */
+       LM_UINT32 UseTaggedStatus;
+
+       /* NIC will not compute the pseudo header checksum.  The driver or OS */
+       /* must seed the checksum field with the pseudo checksum. */
+       LM_UINT32 NoTxPseudoHdrChksum;
+
+       /* The receive checksum in the BD does not include the pseudo checksum. */
+       /* The OS or the driver must calculate the pseudo checksum and add it to */
+       /* the checksum in the BD. */
+       LM_UINT32 NoRxPseudoHdrChksum;
+
+       /* Current node address. */
+       LM_UINT8 NodeAddress[8];
+
+       /* The adapter's node address. */
+       LM_UINT8 PermanentNodeAddress[8];
+
+       /* Adapter info. */
+       LM_UINT16 BusNum;
+       LM_UINT8 DevNum;
+       LM_UINT8 FunctNum;
+       LM_UINT16 PciVendorId;
+       LM_UINT16 PciDeviceId;
+       LM_UINT32 BondId;
+       LM_UINT8 Irq;
+       LM_UINT8 IntPin;
+       LM_UINT8 CacheLineSize;
+       LM_UINT8 PciRevId;
+#if PCIX_TARGET_WORKAROUND
+       LM_UINT32 EnablePciXFix;
+#endif
+       LM_UINT32 UndiFix;      /* new, jimmy */
+       LM_UINT32 PciCommandStatusWords;
+       LM_UINT32 ChipRevId;
+       LM_UINT16 SubsystemVendorId;
+       LM_UINT16 SubsystemId;
+#if 0                          /* Jimmy, deleted in new driver */
+       LM_UINT32 MemBaseLow;
+       LM_UINT32 MemBaseHigh;
+       LM_UINT32 MemBaseSize;
+#endif
+       PLM_UINT8 pMappedMemBase;
+
+       /* Saved PCI configuration registers for restoring after a reset. */
+       LM_UINT32 SavedCacheLineReg;
+
+       /* Phy info. */
+       LM_UINT32 PhyAddr;
+       LM_UINT32 PhyId;
+
+       /* Requested phy settings. */
+       LM_REQUESTED_MEDIA_TYPE RequestedMediaType;
+
+       /* Disable auto-negotiation. */
+       LM_UINT32 DisableAutoNeg;
+
+       /* Ways for the MAC to get link change interrupt. */
+       LM_UINT32 PhyIntMode;
+#define T3_PHY_INT_MODE_AUTO                        0
+#define T3_PHY_INT_MODE_MI_INTERRUPT                1
+#define T3_PHY_INT_MODE_LINK_READY                  2
+#define T3_PHY_INT_MODE_AUTO_POLLING                3
+
+       /* Ways to determine link change status. */
+       LM_UINT32 LinkChngMode;
+#define T3_LINK_CHNG_MODE_AUTO                      0
+#define T3_LINK_CHNG_MODE_USE_STATUS_REG            1
+#define T3_LINK_CHNG_MODE_USE_STATUS_BLOCK          2
+
+       /* LED mode. */
+       LM_UINT32 LedMode;
+
+#define LED_MODE_AUTO                               0
+
+       /* 5700/01 LED mode. */
+#define LED_MODE_THREE_LINK                         1
+#define LED_MODE_LINK10                             2
+
+       /* 5703/02/04 LED mode. */
+#define LED_MODE_OPEN_DRAIN                         1
+#define LED_MODE_OUTPUT                             2
+
+       /* WOL Speed */
+       LM_UINT32 WolSpeed;
+#define WOL_SPEED_10MB                              1
+#define WOL_SPEED_100MB                             2
+
+       /* Reset the PHY on initialization. */
+       LM_UINT32 ResetPhyOnInit;
+
+       LM_UINT32 RestoreOnWakeUp;
+       LM_REQUESTED_MEDIA_TYPE WakeUpRequestedMediaType;
+       LM_UINT32 WakeUpDisableAutoNeg;
+
+       /* Current phy settings. */
+       LM_MEDIA_TYPE MediaType;
+       LM_LINE_SPEED LineSpeed;
+       LM_LINE_SPEED OldLineSpeed;
+       LM_DUPLEX_MODE DuplexMode;
+       LM_STATUS LinkStatus;
+       LM_UINT32 advertising;  /* Jimmy, new! */
+       LM_UINT32 advertising1000;      /* Jimmy, new! */
+
+       /* Multicast address list. */
+       LM_UINT32 McEntryCount;
+       LM_UINT8 McTable[LM_MAX_MC_TABLE_SIZE][LM_MC_ENTRY_SIZE];
+
+       /* Use NIC or Host based send BD. */
+       LM_UINT32 NicSendBd;
+
+       /* Athlon fix. */
+       LM_UINT32 DelayPciGrant;
+
+       /* Enable OneDmaAtOnce */
+       LM_UINT32 OneDmaAtOnce;
+
+       /* Split Mode flags, Jimmy new */
+       LM_UINT32 SplitModeEnable;
+       LM_UINT32 SplitModeMaxReq;
+
+       /* Init flag. */
+       LM_BOOL InitDone;
+
+       /* Shutdown flag.  Set by the upper module. */
+       LM_BOOL ShuttingDown;
+
+       /* Flag to determine whether to call LM_QueueRxPackets or not in */
+       /* LM_ResetAdapter routine. */
+       LM_BOOL QueueRxPackets;
+
+       LM_UINT32 MbufBase;
+       LM_UINT32 MbufSize;
+
+       /* TRUE if we have a SERDES PHY. */
+       LM_UINT32 EnableTbi;
+
+       /* Ethernet@WireSpeed. */
+       LM_UINT32 EnableWireSpeed;
+
+       LM_UINT32 EepromWp;
+
+#if INCLUDE_TBI_SUPPORT
+       /* Autoneg state info. */
+       AN_STATE_INFO AnInfo;
+       LM_UINT32 PollTbiLink;
+       LM_UINT32 IgnoreTbiLinkChange;
+#endif
+       char PartNo[24];
+       char BootCodeVer[16];
+       char BusSpeedStr[24];   /* Jimmy, new! */
+       LM_UINT32 PhyCrcCount;
+} LM_DEVICE_BLOCK;
+
+#define T3_REG_CPU_VIEW               0xc0000000
+
+#define T3_BLOCK_DMA_RD               (1 << 0)
+#define T3_BLOCK_DMA_COMP             (1 << 1)
+#define T3_BLOCK_RX_BD_INITIATOR      (1 << 2)
+#define T3_BLOCK_RX_BD_COMP           (1 << 3)
+#define T3_BLOCK_DMA_WR               (1 << 4)
+#define T3_BLOCK_MSI_HANDLER          (1 << 5)
+#define T3_BLOCK_RX_LIST_PLMT         (1 << 6)
+#define T3_BLOCK_RX_LIST_SELECTOR     (1 << 7)
+#define T3_BLOCK_RX_DATA_INITIATOR    (1 << 8)
+#define T3_BLOCK_RX_DATA_COMP         (1 << 9)
+#define T3_BLOCK_HOST_COALESING       (1 << 10)
+#define T3_BLOCK_MAC_RX_ENGINE        (1 << 11)
+#define T3_BLOCK_MBUF_CLUSTER_FREE    (1 << 12)
+#define T3_BLOCK_SEND_BD_INITIATOR    (1 << 13)
+#define T3_BLOCK_SEND_BD_COMP         (1 << 14)
+#define T3_BLOCK_SEND_BD_SELECTOR     (1 << 15)
+#define T3_BLOCK_SEND_DATA_INITIATOR  (1 << 16)
+#define T3_BLOCK_SEND_DATA_COMP       (1 << 17)
+#define T3_BLOCK_MAC_TX_ENGINE        (1 << 18)
+#define T3_BLOCK_MEM_ARBITOR          (1 << 19)
+#define T3_BLOCK_MBUF_MANAGER         (1 << 20)
+#define T3_BLOCK_MAC_GLOBAL           (1 << 21)
+
+#define LM_ENABLE               1
+#define LM_DISABLE              2
+
+#define RX_CPU_EVT_SW0              0
+#define RX_CPU_EVT_SW1              1
+#define RX_CPU_EVT_RLP              2
+#define RX_CPU_EVT_SW3              3
+#define RX_CPU_EVT_RLS              4
+#define RX_CPU_EVT_SW4              5
+#define RX_CPU_EVT_RX_BD_COMP       6
+#define RX_CPU_EVT_SW5              7
+#define RX_CPU_EVT_RDI              8
+#define RX_CPU_EVT_DMA_WR           9
+#define RX_CPU_EVT_DMA_RD           10
+#define RX_CPU_EVT_SWQ              11
+#define RX_CPU_EVT_SW6              12
+#define RX_CPU_EVT_RDC              13
+#define RX_CPU_EVT_SW7              14
+#define RX_CPU_EVT_HOST_COALES      15
+#define RX_CPU_EVT_SW8              16
+#define RX_CPU_EVT_HIGH_DMA_WR      17
+#define RX_CPU_EVT_HIGH_DMA_RD      18
+#define RX_CPU_EVT_SW9              19
+#define RX_CPU_EVT_DMA_ATTN         20
+#define RX_CPU_EVT_LOW_P_MBOX       21
+#define RX_CPU_EVT_HIGH_P_MBOX      22
+#define RX_CPU_EVT_SW10             23
+#define RX_CPU_EVT_TX_CPU_ATTN      24
+#define RX_CPU_EVT_MAC_ATTN         25
+#define RX_CPU_EVT_RX_CPU_ATTN      26
+#define RX_CPU_EVT_FLOW_ATTN        27
+#define RX_CPU_EVT_SW11             28
+#define RX_CPU_EVT_TIMER            29
+#define RX_CPU_EVT_SW12             30
+#define RX_CPU_EVT_SW13             31
+
+/* RX-CPU event */
+#define RX_CPU_EVENT_SW_EVENT0      (1 << RX_CPU_EVT_SW0)
+#define RX_CPU_EVENT_SW_EVENT1      (1 << RX_CPU_EVT_SW1)
+#define RX_CPU_EVENT_RLP            (1 << RX_CPU_EVT_RLP)
+#define RX_CPU_EVENT_SW_EVENT3      (1 << RX_CPU_EVT_SW3)
+#define RX_CPU_EVENT_RLS            (1 << RX_CPU_EVT_RLS)
+#define RX_CPU_EVENT_SW_EVENT4      (1 << RX_CPU_EVT_SW4)
+#define RX_CPU_EVENT_RX_BD_COMP     (1 << RX_CPU_EVT_RX_BD_COMP)
+#define RX_CPU_EVENT_SW_EVENT5      (1 << RX_CPU_EVT_SW5)
+#define RX_CPU_EVENT_RDI            (1 << RX_CPU_EVT_RDI)
+#define RX_CPU_EVENT_DMA_WR         (1 << RX_CPU_EVT_DMA_WR)
+#define RX_CPU_EVENT_DMA_RD         (1 << RX_CPU_EVT_DMA_RD)
+#define RX_CPU_EVENT_SWQ            (1 << RX_CPU_EVT_SWQ)
+#define RX_CPU_EVENT_SW_EVENT6      (1 << RX_CPU_EVT_SW6)
+#define RX_CPU_EVENT_RDC            (1 << RX_CPU_EVT_RDC)
+#define RX_CPU_EVENT_SW_EVENT7      (1 << RX_CPU_EVT_SW7)
+#define RX_CPU_EVENT_HOST_COALES    (1 << RX_CPU_EVT_HOST_COALES)
+#define RX_CPU_EVENT_SW_EVENT8      (1 << RX_CPU_EVT_SW8)
+#define RX_CPU_EVENT_HIGH_DMA_WR    (1 << RX_CPU_EVT_HIGH_DMA_WR)
+#define RX_CPU_EVENT_HIGH_DMA_RD    (1 << RX_CPU_EVT_HIGH_DMA_RD)
+#define RX_CPU_EVENT_SW_EVENT9      (1 << RX_CPU_EVT_SW9)
+#define RX_CPU_EVENT_DMA_ATTN       (1 << RX_CPU_EVT_DMA_ATTN)
+#define RX_CPU_EVENT_LOW_P_MBOX     (1 << RX_CPU_EVT_LOW_P_MBOX)
+#define RX_CPU_EVENT_HIGH_P_MBOX    (1 << RX_CPU_EVT_HIGH_P_MBOX)
+#define RX_CPU_EVENT_SW_EVENT10     (1 << RX_CPU_EVT_SW10)
+#define RX_CPU_EVENT_TX_CPU_ATTN    (1 << RX_CPU_EVT_TX_CPU_ATTN)
+#define RX_CPU_EVENT_MAC_ATTN       (1 << RX_CPU_EVT_MAC_ATTN)
+#define RX_CPU_EVENT_RX_CPU_ATTN    (1 << RX_CPU_EVT_RX_CPU_ATTN)
+#define RX_CPU_EVENT_FLOW_ATTN      (1 << RX_CPU_EVT_FLOW_ATTN)
+#define RX_CPU_EVENT_SW_EVENT11     (1 << RX_CPU_EVT_SW11)
+#define RX_CPU_EVENT_TIMER          (1 << RX_CPU_EVT_TIMER)
+#define RX_CPU_EVENT_SW_EVENT12     (1 << RX_CPU_EVT_SW12)
+#define RX_CPU_EVENT_SW_EVENT13     (1 << RX_CPU_EVT_SW13)
+
+#define RX_CPU_MASK (RX_CPU_EVENT_SW_EVENT0 | \
+                    RX_CPU_EVENT_RLP | \
+                    RX_CPU_EVENT_RDI | \
+                    RX_CPU_EVENT_RDC)
+
+#define TX_CPU_EVT_SW0              0
+#define TX_CPU_EVT_SW1              1
+#define TX_CPU_EVT_SW2              2
+#define TX_CPU_EVT_SW3              3
+#define TX_CPU_EVT_TX_MAC           4
+#define TX_CPU_EVT_SW4              5
+#define TX_CPU_EVT_SBDC             6
+#define TX_CPU_EVT_SW5              7
+#define TX_CPU_EVT_SDI              8
+#define TX_CPU_EVT_DMA_WR           9
+#define TX_CPU_EVT_DMA_RD           10
+#define TX_CPU_EVT_SWQ              11
+#define TX_CPU_EVT_SW6              12
+#define TX_CPU_EVT_SDC              13
+#define TX_CPU_EVT_SW7              14
+#define TX_CPU_EVT_HOST_COALES      15
+#define TX_CPU_EVT_SW8              16
+#define TX_CPU_EVT_HIGH_DMA_WR      17
+#define TX_CPU_EVT_HIGH_DMA_RD      18
+#define TX_CPU_EVT_SW9              19
+#define TX_CPU_EVT_DMA_ATTN         20
+#define TX_CPU_EVT_LOW_P_MBOX       21
+#define TX_CPU_EVT_HIGH_P_MBOX      22
+#define TX_CPU_EVT_SW10             23
+#define TX_CPU_EVT_RX_CPU_ATTN      24
+#define TX_CPU_EVT_MAC_ATTN         25
+#define TX_CPU_EVT_TX_CPU_ATTN      26
+#define TX_CPU_EVT_FLOW_ATTN        27
+#define TX_CPU_EVT_SW11             28
+#define TX_CPU_EVT_TIMER            29
+#define TX_CPU_EVT_SW12             30
+#define TX_CPU_EVT_SW13             31
+
+/* TX-CPU event */
+#define TX_CPU_EVENT_SW_EVENT0      (1 << TX_CPU_EVT_SW0)
+#define TX_CPU_EVENT_SW_EVENT1      (1 << TX_CPU_EVT_SW1)
+#define TX_CPU_EVENT_SW_EVENT2      (1 << TX_CPU_EVT_SW2)
+#define TX_CPU_EVENT_SW_EVENT3      (1 << TX_CPU_EVT_SW3)
+#define TX_CPU_EVENT_TX_MAC         (1 << TX_CPU_EVT_TX_MAC)
+#define TX_CPU_EVENT_SW_EVENT4      (1 << TX_CPU_EVT_SW4)
+#define TX_CPU_EVENT_SBDC           (1 << TX_CPU_EVT_SBDC)
+#define TX_CPU_EVENT_SW_EVENT5      (1 << TX_CPU_EVT_SW5)
+#define TX_CPU_EVENT_SDI            (1 << TX_CPU_EVT_SDI)
+#define TX_CPU_EVENT_DMA_WR         (1 << TX_CPU_EVT_DMA_WR)
+#define TX_CPU_EVENT_DMA_RD         (1 << TX_CPU_EVT_DMA_RD)
+#define TX_CPU_EVENT_SWQ            (1 << TX_CPU_EVT_SWQ)
+#define TX_CPU_EVENT_SW_EVENT6      (1 << TX_CPU_EVT_SW6)
+#define TX_CPU_EVENT_SDC            (1 << TX_CPU_EVT_SDC)
+#define TX_CPU_EVENT_SW_EVENT7      (1 << TX_CPU_EVT_SW7)
+#define TX_CPU_EVENT_HOST_COALES    (1 << TX_CPU_EVT_HOST_COALES)
+#define TX_CPU_EVENT_SW_EVENT8      (1 << TX_CPU_EVT_SW8)
+#define TX_CPU_EVENT_HIGH_DMA_WR    (1 << TX_CPU_EVT_HIGH_DMA_WR)
+#define TX_CPU_EVENT_HIGH_DMA_RD    (1 << TX_CPU_EVT_HIGH_DMA_RD)
+#define TX_CPU_EVENT_SW_EVENT9      (1 << TX_CPU_EVT_SW9)
+#define TX_CPU_EVENT_DMA_ATTN       (1 << TX_CPU_EVT_DMA_ATTN)
+#define TX_CPU_EVENT_LOW_P_MBOX     (1 << TX_CPU_EVT_LOW_P_MBOX)
+#define TX_CPU_EVENT_HIGH_P_MBOX    (1 << TX_CPU_EVT_HIGH_P_MBOX)
+#define TX_CPU_EVENT_SW_EVENT10     (1 << TX_CPU_EVT_SW10)
+#define TX_CPU_EVENT_RX_CPU_ATTN    (1 << TX_CPU_EVT_RX_CPU_ATTN)
+#define TX_CPU_EVENT_MAC_ATTN       (1 << TX_CPU_EVT_MAC_ATTN)
+#define TX_CPU_EVENT_TX_CPU_ATTN    (1 << TX_CPU_EVT_TX_CPU_ATTN)
+#define TX_CPU_EVENT_FLOW_ATTN      (1 << TX_CPU_EVT_FLOW_ATTN)
+#define TX_CPU_EVENT_SW_EVENT11     (1 << TX_CPU_EVT_SW11)
+#define TX_CPU_EVENT_TIMER          (1 << TX_CPU_EVT_TIMER)
+#define TX_CPU_EVENT_SW_EVENT12     (1 << TX_CPU_EVT_SW12)
+#define TX_CPU_EVENT_SW_EVENT13     (1 << TX_CPU_EVT_SW13)
+
+#define TX_CPU_MASK (TX_CPU_EVENT_SW_EVENT0 | \
+                    TX_CPU_EVENT_SDI  | \
+                    TX_CPU_EVENT_SDC)
+
+#define T3_FTQ_TYPE1_UNDERFLOW_BIT   (1 << 29)
+#define T3_FTQ_TYPE1_PASS_BIT        (1 << 30)
+#define T3_FTQ_TYPE1_SKIP_BIT        (1 << 31)
+
+#define T3_FTQ_TYPE2_UNDERFLOW_BIT   (1 << 13)
+#define T3_FTQ_TYPE2_PASS_BIT        (1 << 14)
+#define T3_FTQ_TYPE2_SKIP_BIT        (1 << 15)
+
+#define T3_QID_DMA_READ               1
+#define T3_QID_DMA_HIGH_PRI_READ      2
+#define T3_QID_DMA_COMP_DX            3
+#define T3_QID_SEND_BD_COMP           4
+#define T3_QID_SEND_DATA_INITIATOR    5
+#define T3_QID_DMA_WRITE              6
+#define T3_QID_DMA_HIGH_PRI_WRITE     7
+#define T3_QID_SW_TYPE_1              8
+#define T3_QID_SEND_DATA_COMP         9
+#define T3_QID_HOST_COALESCING        10
+#define T3_QID_MAC_TX                 11
+#define T3_QID_MBUF_CLUSTER_FREE      12
+#define T3_QID_RX_BD_COMP             13
+#define T3_QID_RX_LIST_PLM            14
+#define T3_QID_RX_DATA_BD_INITIATOR   15
+#define T3_QID_RX_DATA_COMP           16
+#define T3_QID_SW_TYPE2               17
+
+LM_STATUS LM_LoadFirmware (PLM_DEVICE_BLOCK pDevice,
+                          PT3_FWIMG_INFO pFwImg,
+                          LM_UINT32 LoadCpu, LM_UINT32 StartCpu);
+
+/******************************************************************************/
+/* NIC register read/write macros. */
+/******************************************************************************/
+
+#if 0                          /* Jimmy */
+/* MAC register access. */
+LM_UINT32 LM_RegRdInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register);
+LM_VOID LM_RegWrInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register,
+                    LM_UINT32 Value32);
+
+/* MAC memory access. */
+LM_UINT32 LM_MemRdInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr);
+LM_VOID LM_MemWrInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr,
+                    LM_UINT32 Value32);
+
+#if PCIX_TARGET_WORKAROUND
+
+/* use memory-mapped accesses for mailboxes and reads, UNDI accesses
+   for writes to all other registers */
+#define REG_RD(pDevice, OffsetName)                              \
+    readl(&((pDevice)->pMemView->OffsetName))
+
+#define REG_WR(pDevice, OffsetName, Value32)                     \
+    (((OFFSETOF(T3_STD_MEM_MAP, OffsetName) >=0x200 ) &&         \
+      (OFFSETOF(T3_STD_MEM_MAP, OffsetName) <0x400)) ||                 \
+        ((pDevice)->EnablePciXFix == FALSE)) ?                  \
+    (void) writel(Value32, &((pDevice)->pMemView->OffsetName)) : \
+    LM_RegWrInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName), Value32)
+
+#define MB_REG_RD(pDevice, OffsetName)                           \
+    readl(&((pDevice)->pMemView->OffsetName))
+
+#define MB_REG_WR(pDevice, OffsetName, Value32)                  \
+    writel(Value32, &((pDevice)->pMemView->OffsetName))
+
+#define REG_RD_OFFSET(pDevice, Offset)                           \
+    readl(&((LM_UINT8 *) (pDevice)->pMemView + Offset))
+
+#define REG_WR_OFFSET(pDevice, Offset, Value32)                  \
+       (((Offset >=0x200 ) && (Offset < 0x400)) ||              \
+        ((pDevice)->EnablePciXFix == FALSE)) ?                  \
+    (void) writel(Value32, ((LM_UINT8 *) (pDevice)->pMemView + Offset)) : \
+    LM_RegWrInd(pDevice, Offset, Value32)
+
+#define MEM_RD(pDevice, AddrName)                                \
+    LM_MemRdInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName))
+#define MEM_WR(pDevice, AddrName, Value32)                       \
+    LM_MemWrInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName), Value32)
+
+#define MEM_RD_OFFSET(pDevice, Offset)                           \
+    LM_MemRdInd(pDevice, Offset)
+#define MEM_WR_OFFSET(pDevice, Offset, Value32)                  \
+    LM_MemWrInd(pDevice, Offset, Value32)
+
+#else                          /* normal target access path below */
+
+/* Register access. */
+#define REG_RD(pDevice, OffsetName)                                         \
+    readl(&((pDevice)->pMemView->OffsetName))
+#define REG_WR(pDevice, OffsetName, Value32)                                \
+    writel(Value32, &((pDevice)->pMemView->OffsetName))
+
+#define REG_RD_OFFSET(pDevice, Offset)                                      \
+    readl(((LM_UINT8 *) (pDevice)->pMemView + Offset))
+#define REG_WR_OFFSET(pDevice, Offset, Value32)                             \
+    writel(Value32, ((LM_UINT8 *) (pDevice)->pMemView + Offset))
+
+/* There could be problem access the memory window directly.  For now, */
+/* we have to go through the PCI configuration register. */
+#define MEM_RD(pDevice, AddrName)                                           \
+    LM_MemRdInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName))
+#define MEM_WR(pDevice, AddrName, Value32)                                  \
+    LM_MemWrInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName), Value32)
+
+#define MEM_RD_OFFSET(pDevice, Offset)                                      \
+    LM_MemRdInd(pDevice, Offset)
+#define MEM_WR_OFFSET(pDevice, Offset, Value32)                             \
+    LM_MemWrInd(pDevice, Offset, Value32)
+
+#endif                         /* PCIX_TARGET_WORKAROUND */
+
+#endif                         /* Jimmy, merging */
+
+  /* Jimmy...rest of file is new stuff! */
+/******************************************************************************/
+/* NIC register read/write macros. */
+/******************************************************************************/
+
+/* MAC register access. */
+LM_UINT32 LM_RegRdInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register);
+LM_VOID LM_RegWrInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register,
+                    LM_UINT32 Value32);
+
+/* MAC memory access. */
+LM_UINT32 LM_MemRdInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr);
+LM_VOID LM_MemWrInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr,
+                    LM_UINT32 Value32);
+
+#define MB_REG_WR(pDevice, OffsetName, Value32)                               \
+    ((pDevice)->UndiFix) ?                                                    \
+       LM_RegWrInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName)+0x5600,     \
+           Value32) :                                                        \
+       (void) __raw_writel(Value32, &((pDevice)->pMemView->OffsetName))
+
+#define MB_REG_RD(pDevice, OffsetName)                                        \
+    (((pDevice)->UndiFix) ?                                                   \
+       LM_RegRdInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName)+0x5600) :   \
+       __raw_readl(&((pDevice)->pMemView->OffsetName)))
+
+#define REG_RD(pDevice, OffsetName)                                           \
+    (((pDevice)->UndiFix) ?                                                   \
+       LM_RegRdInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName)) :          \
+       __raw_readl(&((pDevice)->pMemView->OffsetName)))
+
+#if PCIX_TARGET_WORKAROUND
+
+#define REG_WR(pDevice, OffsetName, Value32)                                \
+        ((pDevice)->EnablePciXFix == FALSE) ?                              \
+    (void) __raw_writel(Value32, &((pDevice)->pMemView->OffsetName)) :      \
+    LM_RegWrInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName), Value32)
+
+#else
+
+#define REG_WR(pDevice, OffsetName, Value32)                                \
+    __raw_writel(Value32, &((pDevice)->pMemView->OffsetName))
+
+#endif
+
+#define MEM_RD(pDevice, AddrName)                                           \
+    LM_MemRdInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName))
+#define MEM_WR(pDevice, AddrName, Value32)                                  \
+    LM_MemWrInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName), Value32)
+
+#define MEM_RD_OFFSET(pDevice, Offset)                                      \
+    LM_MemRdInd(pDevice, Offset)
+#define MEM_WR_OFFSET(pDevice, Offset, Value32)                             \
+    LM_MemWrInd(pDevice, Offset, Value32)
+
+#endif                         /* TIGON3_H */
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
new file mode 100644 (file)
index 0000000..ca6284b
--- /dev/null
@@ -0,0 +1,1590 @@
+/*
+ * Freescale Three Speed Ethernet Controller driver
+ *
+ * This software may be used and distributed according to the
+ * terms of the GNU Public License, Version 2, incorporated
+ * herein by reference.
+ *
+ * Copyright 2004, 2007 Freescale Semiconductor, Inc.
+ * (C) Copyright 2003, Motorola, Inc.
+ * author Andy Fleming
+ *
+ */
+
+#include <config.h>
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <command.h>
+
+#if defined(CONFIG_TSEC_ENET)
+#include "tsec.h"
+#include "miiphy.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define TX_BUF_CNT             2
+
+static uint rxIdx;             /* index of the current RX buffer */
+static uint txIdx;             /* index of the current TX buffer */
+
+typedef volatile struct rtxbd {
+       txbd8_t txbd[TX_BUF_CNT];
+       rxbd8_t rxbd[PKTBUFSRX];
+} RTXBD;
+
+struct tsec_info_struct {
+       unsigned int phyaddr;
+       u32 flags;
+       unsigned int phyregidx;
+};
+
+/* The tsec_info structure contains 3 values which the
+ * driver uses to determine how to operate a given ethernet
+ * device. The information needed is:
+ *  phyaddr - The address of the PHY which is attached to
+ *     the given device.
+ *
+ *  flags - This variable indicates whether the device
+ *     supports gigabit speed ethernet, and whether it should be
+ *     in reduced mode.
+ *
+ *  phyregidx - This variable specifies which ethernet device
+ *     controls the MII Management registers which are connected
+ *     to the PHY.  For now, only TSEC1 (index 0) has
+ *     access to the PHYs, so all of the entries have "0".
+ *
+ * The values specified in the table are taken from the board's
+ * config file in include/configs/.  When implementing a new
+ * board with ethernet capability, it is necessary to define:
+ *   TSECn_PHY_ADDR
+ *   TSECn_PHYIDX
+ *
+ * for n = 1,2,3, etc.  And for FEC:
+ *   FEC_PHY_ADDR
+ *   FEC_PHYIDX
+ */
+static struct tsec_info_struct tsec_info[] = {
+#ifdef CONFIG_TSEC1
+       {TSEC1_PHY_ADDR, TSEC1_FLAGS, TSEC1_PHYIDX},
+#else
+       {0, 0, 0},
+#endif
+#ifdef CONFIG_TSEC2
+       {TSEC2_PHY_ADDR, TSEC2_FLAGS, TSEC2_PHYIDX},
+#else
+       {0, 0, 0},
+#endif
+#ifdef CONFIG_MPC85XX_FEC
+       {FEC_PHY_ADDR, FEC_FLAGS, FEC_PHYIDX},
+#else
+#ifdef CONFIG_TSEC3
+       {TSEC3_PHY_ADDR, TSEC3_FLAGS, TSEC3_PHYIDX},
+#else
+       {0, 0, 0},
+#endif
+#ifdef CONFIG_TSEC4
+       {TSEC4_PHY_ADDR, TSEC4_FLAGS, TSEC4_PHYIDX},
+#else
+       {0, 0, 0},
+#endif /* CONFIG_TSEC4 */
+#endif /* CONFIG_MPC85XX_FEC */
+};
+
+#define MAXCONTROLLERS (4)
+
+static int relocated = 0;
+
+static struct tsec_private *privlist[MAXCONTROLLERS];
+
+#ifdef __GNUC__
+static RTXBD rtx __attribute__ ((aligned(8)));
+#else
+#error "rtx must be 64-bit aligned"
+#endif
+
+static int tsec_send(struct eth_device *dev,
+                    volatile void *packet, int length);
+static int tsec_recv(struct eth_device *dev);
+static int tsec_init(struct eth_device *dev, bd_t * bd);
+static void tsec_halt(struct eth_device *dev);
+static void init_registers(volatile tsec_t * regs);
+static void startup_tsec(struct eth_device *dev);
+static int init_phy(struct eth_device *dev);
+void write_phy_reg(struct tsec_private *priv, uint regnum, uint value);
+uint read_phy_reg(struct tsec_private *priv, uint regnum);
+struct phy_info *get_phy_info(struct eth_device *dev);
+void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd);
+static void adjust_link(struct eth_device *dev);
+static void relocate_cmds(void);
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
+       && !defined(BITBANGMII)
+static int tsec_miiphy_write(char *devname, unsigned char addr,
+                            unsigned char reg, unsigned short value);
+static int tsec_miiphy_read(char *devname, unsigned char addr,
+                           unsigned char reg, unsigned short *value);
+#endif
+#ifdef CONFIG_MCAST_TFTP
+static int tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set);
+#endif
+
+/* Initialize device structure. Returns success if PHY
+ * initialization succeeded (i.e. if it recognizes the PHY)
+ */
+int tsec_initialize(bd_t * bis, int index, char *devname)
+{
+       struct eth_device *dev;
+       int i;
+       struct tsec_private *priv;
+
+       dev = (struct eth_device *)malloc(sizeof *dev);
+
+       if (NULL == dev)
+               return 0;
+
+       memset(dev, 0, sizeof *dev);
+
+       priv = (struct tsec_private *)malloc(sizeof(*priv));
+
+       if (NULL == priv)
+               return 0;
+
+       privlist[index] = priv;
+       priv->regs = (volatile tsec_t *)(TSEC_BASE_ADDR + index * TSEC_SIZE);
+       priv->phyregs = (volatile tsec_t *)(TSEC_BASE_ADDR +
+                                           tsec_info[index].phyregidx *
+                                           TSEC_SIZE);
+
+       priv->phyaddr = tsec_info[index].phyaddr;
+       priv->flags = tsec_info[index].flags;
+
+       sprintf(dev->name, devname);
+       dev->iobase = 0;
+       dev->priv = priv;
+       dev->init = tsec_init;
+       dev->halt = tsec_halt;
+       dev->send = tsec_send;
+       dev->recv = tsec_recv;
+#ifdef CONFIG_MCAST_TFTP
+       dev->mcast = tsec_mcast_addr;
+#endif
+
+       /* Tell u-boot to get the addr from the env */
+       for (i = 0; i < 6; i++)
+               dev->enetaddr[i] = 0;
+
+       eth_register(dev);
+
+       /* Reset the MAC */
+       priv->regs->maccfg1 |= MACCFG1_SOFT_RESET;
+       priv->regs->maccfg1 &= ~(MACCFG1_SOFT_RESET);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
+       && !defined(BITBANGMII)
+       miiphy_register(dev->name, tsec_miiphy_read, tsec_miiphy_write);
+#endif
+
+       /* Try to initialize PHY here, and return */
+       return init_phy(dev);
+}
+
+/* Initializes data structures and registers for the controller,
+ * and brings the interface up.         Returns the link status, meaning
+ * that it returns success if the link is up, failure otherwise.
+ * This allows u-boot to find the first active controller.
+ */
+int tsec_init(struct eth_device *dev, bd_t * bd)
+{
+       uint tempval;
+       char tmpbuf[MAC_ADDR_LEN];
+       int i;
+       struct tsec_private *priv = (struct tsec_private *)dev->priv;
+       volatile tsec_t *regs = priv->regs;
+
+       /* Make sure the controller is stopped */
+       tsec_halt(dev);
+
+       /* Init MACCFG2.  Defaults to GMII */
+       regs->maccfg2 = MACCFG2_INIT_SETTINGS;
+
+       /* Init ECNTRL */
+       regs->ecntrl = ECNTRL_INIT_SETTINGS;
+
+       /* Copy the station address into the address registers.
+        * Backwards, because little endian MACS are dumb */
+       for (i = 0; i < MAC_ADDR_LEN; i++) {
+               tmpbuf[MAC_ADDR_LEN - 1 - i] = dev->enetaddr[i];
+       }
+       regs->macstnaddr1 = *((uint *) (tmpbuf));
+
+       tempval = *((uint *) (tmpbuf + 4));
+
+       regs->macstnaddr2 = tempval;
+
+       /* reset the indices to zero */
+       rxIdx = 0;
+       txIdx = 0;
+
+       /* Clear out (for the most part) the other registers */
+       init_registers(regs);
+
+       /* Ready the device for tx/rx */
+       startup_tsec(dev);
+
+       /* If there's no link, fail */
+       return priv->link;
+
+}
+
+/* Write value to the device's PHY through the registers
+ * specified in priv, modifying the register specified in regnum.
+ * It will wait for the write to be done (or for a timeout to
+ * expire) before exiting
+ */
+void write_phy_reg(struct tsec_private *priv, uint regnum, uint value)
+{
+       volatile tsec_t *regbase = priv->phyregs;
+       uint phyid = priv->phyaddr;
+       int timeout = 1000000;
+
+       regbase->miimadd = (phyid << 8) | regnum;
+       regbase->miimcon = value;
+       asm("sync");
+
+       timeout = 1000000;
+       while ((regbase->miimind & MIIMIND_BUSY) && timeout--) ;
+}
+
+/* Reads register regnum on the device's PHY through the
+ * registers specified in priv.         It lowers and raises the read
+ * command, and waits for the data to become valid (miimind
+ * notvalid bit cleared), and the bus to cease activity (miimind
+ * busy bit cleared), and then returns the value
+ */
+uint read_phy_reg(struct tsec_private *priv, uint regnum)
+{
+       uint value;
+       volatile tsec_t *regbase = priv->phyregs;
+       uint phyid = priv->phyaddr;
+
+       /* Put the address of the phy, and the register
+        * number into MIIMADD */
+       regbase->miimadd = (phyid << 8) | regnum;
+
+       /* Clear the command register, and wait */
+       regbase->miimcom = 0;
+       asm("sync");
+
+       /* Initiate a read command, and wait */
+       regbase->miimcom = MIIM_READ_COMMAND;
+       asm("sync");
+
+       /* Wait for the the indication that the read is done */
+       while ((regbase->miimind & (MIIMIND_NOTVALID | MIIMIND_BUSY))) ;
+
+       /* Grab the value read from the PHY */
+       value = regbase->miimstat;
+
+       return value;
+}
+
+/* Discover which PHY is attached to the device, and configure it
+ * properly.  If the PHY is not recognized, then return 0
+ * (failure).  Otherwise, return 1
+ */
+static int init_phy(struct eth_device *dev)
+{
+       struct tsec_private *priv = (struct tsec_private *)dev->priv;
+       struct phy_info *curphy;
+       volatile tsec_t *regs = (volatile tsec_t *)(TSEC_BASE_ADDR);
+
+       /* Assign a Physical address to the TBI */
+       regs->tbipa = CFG_TBIPA_VALUE;
+       regs = (volatile tsec_t *)(TSEC_BASE_ADDR + TSEC_SIZE);
+       regs->tbipa = CFG_TBIPA_VALUE;
+       asm("sync");
+
+       /* Reset MII (due to new addresses) */
+       priv->phyregs->miimcfg = MIIMCFG_RESET;
+       asm("sync");
+       priv->phyregs->miimcfg = MIIMCFG_INIT_VALUE;
+       asm("sync");
+       while (priv->phyregs->miimind & MIIMIND_BUSY) ;
+
+       if (0 == relocated)
+               relocate_cmds();
+
+       /* Get the cmd structure corresponding to the attached
+        * PHY */
+       curphy = get_phy_info(dev);
+
+       if (curphy == NULL) {
+               priv->phyinfo = NULL;
+               printf("%s: No PHY found\n", dev->name);
+
+               return 0;
+       }
+
+       priv->phyinfo = curphy;
+
+       phy_run_commands(priv, priv->phyinfo->config);
+
+       return 1;
+}
+
+/*
+ * Returns which value to write to the control register.
+ * For 10/100, the value is slightly different
+ */
+uint mii_cr_init(uint mii_reg, struct tsec_private * priv)
+{
+       if (priv->flags & TSEC_GIGABIT)
+               return MIIM_CONTROL_INIT;
+       else
+               return MIIM_CR_INIT;
+}
+
+/* Parse the status register for link, and then do
+ * auto-negotiation
+ */
+uint mii_parse_sr(uint mii_reg, struct tsec_private * priv)
+{
+       /*
+        * Wait if the link is up, and autonegotiation is in progress
+        * (ie - we're capable and it's not done)
+        */
+       mii_reg = read_phy_reg(priv, MIIM_STATUS);
+       if ((mii_reg & MIIM_STATUS_LINK) && (mii_reg & PHY_BMSR_AUTN_ABLE)
+           && !(mii_reg & PHY_BMSR_AUTN_COMP)) {
+               int i = 0;
+
+               puts("Waiting for PHY auto negotiation to complete");
+               while (!(mii_reg & PHY_BMSR_AUTN_COMP)) {
+                       /*
+                        * Timeout reached ?
+                        */
+                       if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
+                               puts(" TIMEOUT !\n");
+                               priv->link = 0;
+                               return 0;
+                       }
+
+                       if ((i++ % 1000) == 0) {
+                               putc('.');
+                       }
+                       udelay(1000);   /* 1 ms */
+                       mii_reg = read_phy_reg(priv, MIIM_STATUS);
+               }
+               puts(" done\n");
+               priv->link = 1;
+               udelay(500000); /* another 500 ms (results in faster booting) */
+       } else {
+               if (mii_reg & MIIM_STATUS_LINK)
+                       priv->link = 1;
+               else
+                       priv->link = 0;
+       }
+
+       return 0;
+}
+
+/* Generic function which updates the speed and duplex.  If
+ * autonegotiation is enabled, it uses the AND of the link
+ * partner's advertised capabilities and our advertised
+ * capabilities.  If autonegotiation is disabled, we use the
+ * appropriate bits in the control register.
+ *
+ * Stolen from Linux's mii.c and phy_device.c
+ */
+uint mii_parse_link(uint mii_reg, struct tsec_private *priv)
+{
+       /* We're using autonegotiation */
+       if (mii_reg & PHY_BMSR_AUTN_ABLE) {
+               uint lpa = 0;
+               uint gblpa = 0;
+
+               /* Check for gigabit capability */
+               if (mii_reg & PHY_BMSR_EXT) {
+                       /* We want a list of states supported by
+                        * both PHYs in the link
+                        */
+                       gblpa = read_phy_reg(priv, PHY_1000BTSR);
+                       gblpa &= read_phy_reg(priv, PHY_1000BTCR) << 2;
+               }
+
+               /* Set the baseline so we only have to set them
+                * if they're different
+                */
+               priv->speed = 10;
+               priv->duplexity = 0;
+
+               /* Check the gigabit fields */
+               if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
+                       priv->speed = 1000;
+
+                       if (gblpa & PHY_1000BTSR_1000FD)
+                               priv->duplexity = 1;
+
+                       /* We're done! */
+                       return 0;
+               }
+
+               lpa = read_phy_reg(priv, PHY_ANAR);
+               lpa &= read_phy_reg(priv, PHY_ANLPAR);
+
+               if (lpa & (PHY_ANLPAR_TXFD | PHY_ANLPAR_TX)) {
+                       priv->speed = 100;
+
+                       if (lpa & PHY_ANLPAR_TXFD)
+                               priv->duplexity = 1;
+
+               } else if (lpa & PHY_ANLPAR_10FD)
+                       priv->duplexity = 1;
+       } else {
+               uint bmcr = read_phy_reg(priv, PHY_BMCR);
+
+               priv->speed = 10;
+               priv->duplexity = 0;
+
+               if (bmcr & PHY_BMCR_DPLX)
+                       priv->duplexity = 1;
+
+               if (bmcr & PHY_BMCR_1000_MBPS)
+                       priv->speed = 1000;
+               else if (bmcr & PHY_BMCR_100_MBPS)
+                       priv->speed = 100;
+       }
+
+       return 0;
+}
+
+/*
+ * Parse the BCM54xx status register for speed and duplex information.
+ * The linux sungem_phy has this information, but in a table format.
+ */
+uint mii_parse_BCM54xx_sr(uint mii_reg, struct tsec_private *priv)
+{
+
+       switch((mii_reg & MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK) >> MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT){
+
+               case 1:
+                       printf("Enet starting in 10BT/HD\n");
+                       priv->duplexity = 0;
+                       priv->speed = 10;
+                       break;
+
+               case 2:
+                       printf("Enet starting in 10BT/FD\n");
+                       priv->duplexity = 1;
+                       priv->speed = 10;
+                       break;
+
+               case 3:
+                       printf("Enet starting in 100BT/HD\n");
+                       priv->duplexity = 0;
+                       priv->speed = 100;
+                       break;
+
+               case 5:
+                       printf("Enet starting in 100BT/FD\n");
+                       priv->duplexity = 1;
+                       priv->speed = 100;
+                       break;
+
+               case 6:
+                       printf("Enet starting in 1000BT/HD\n");
+                       priv->duplexity = 0;
+                       priv->speed = 1000;
+                       break;
+
+               case 7:
+                       printf("Enet starting in 1000BT/FD\n");
+                       priv->duplexity = 1;
+                       priv->speed = 1000;
+                       break;
+
+               default:
+                       printf("Auto-neg error, defaulting to 10BT/HD\n");
+                       priv->duplexity = 0;
+                       priv->speed = 10;
+                       break;
+       }
+
+       return 0;
+
+}
+/* Parse the 88E1011's status register for speed and duplex
+ * information
+ */
+uint mii_parse_88E1011_psr(uint mii_reg, struct tsec_private * priv)
+{
+       uint speed;
+
+       mii_reg = read_phy_reg(priv, MIIM_88E1011_PHY_STATUS);
+
+       if ((mii_reg & MIIM_88E1011_PHYSTAT_LINK) &&
+               !(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) {
+               int i = 0;
+
+               puts("Waiting for PHY realtime link");
+               while (!(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) {
+                       /* Timeout reached ? */
+                       if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
+                               puts(" TIMEOUT !\n");
+                               priv->link = 0;
+                               break;
+                       }
+
+                       if ((i++ % 1000) == 0) {
+                               putc('.');
+                       }
+                       udelay(1000);   /* 1 ms */
+                       mii_reg = read_phy_reg(priv, MIIM_88E1011_PHY_STATUS);
+               }
+               puts(" done\n");
+               udelay(500000); /* another 500 ms (results in faster booting) */
+       } else {
+               if (mii_reg & MIIM_88E1011_PHYSTAT_LINK)
+                       priv->link = 1;
+               else
+                       priv->link = 0;
+       }
+
+       if (mii_reg & MIIM_88E1011_PHYSTAT_DUPLEX)
+               priv->duplexity = 1;
+       else
+               priv->duplexity = 0;
+
+       speed = (mii_reg & MIIM_88E1011_PHYSTAT_SPEED);
+
+       switch (speed) {
+       case MIIM_88E1011_PHYSTAT_GBIT:
+               priv->speed = 1000;
+               break;
+       case MIIM_88E1011_PHYSTAT_100:
+               priv->speed = 100;
+               break;
+       default:
+               priv->speed = 10;
+       }
+
+       return 0;
+}
+
+/* Parse the cis8201's status register for speed and duplex
+ * information
+ */
+uint mii_parse_cis8201(uint mii_reg, struct tsec_private * priv)
+{
+       uint speed;
+
+       if (mii_reg & MIIM_CIS8201_AUXCONSTAT_DUPLEX)
+               priv->duplexity = 1;
+       else
+               priv->duplexity = 0;
+
+       speed = mii_reg & MIIM_CIS8201_AUXCONSTAT_SPEED;
+       switch (speed) {
+       case MIIM_CIS8201_AUXCONSTAT_GBIT:
+               priv->speed = 1000;
+               break;
+       case MIIM_CIS8201_AUXCONSTAT_100:
+               priv->speed = 100;
+               break;
+       default:
+               priv->speed = 10;
+               break;
+       }
+
+       return 0;
+}
+
+/* Parse the vsc8244's status register for speed and duplex
+ * information
+ */
+uint mii_parse_vsc8244(uint mii_reg, struct tsec_private * priv)
+{
+       uint speed;
+
+       if (mii_reg & MIIM_VSC8244_AUXCONSTAT_DUPLEX)
+               priv->duplexity = 1;
+       else
+               priv->duplexity = 0;
+
+       speed = mii_reg & MIIM_VSC8244_AUXCONSTAT_SPEED;
+       switch (speed) {
+       case MIIM_VSC8244_AUXCONSTAT_GBIT:
+               priv->speed = 1000;
+               break;
+       case MIIM_VSC8244_AUXCONSTAT_100:
+               priv->speed = 100;
+               break;
+       default:
+               priv->speed = 10;
+               break;
+       }
+
+       return 0;
+}
+
+/* Parse the DM9161's status register for speed and duplex
+ * information
+ */
+uint mii_parse_dm9161_scsr(uint mii_reg, struct tsec_private * priv)
+{
+       if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_100H))
+               priv->speed = 100;
+       else
+               priv->speed = 10;
+
+       if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_10F))
+               priv->duplexity = 1;
+       else
+               priv->duplexity = 0;
+
+       return 0;
+}
+
+/*
+ * Hack to write all 4 PHYs with the LED values
+ */
+uint mii_cis8204_fixled(uint mii_reg, struct tsec_private * priv)
+{
+       uint phyid;
+       volatile tsec_t *regbase = priv->phyregs;
+       int timeout = 1000000;
+
+       for (phyid = 0; phyid < 4; phyid++) {
+               regbase->miimadd = (phyid << 8) | mii_reg;
+               regbase->miimcon = MIIM_CIS8204_SLEDCON_INIT;
+               asm("sync");
+
+               timeout = 1000000;
+               while ((regbase->miimind & MIIMIND_BUSY) && timeout--) ;
+       }
+
+       return MIIM_CIS8204_SLEDCON_INIT;
+}
+
+uint mii_cis8204_setmode(uint mii_reg, struct tsec_private * priv)
+{
+       if (priv->flags & TSEC_REDUCED)
+               return MIIM_CIS8204_EPHYCON_INIT | MIIM_CIS8204_EPHYCON_RGMII;
+       else
+               return MIIM_CIS8204_EPHYCON_INIT;
+}
+
+/* Initialized required registers to appropriate values, zeroing
+ * those we don't care about (unless zero is bad, in which case,
+ * choose a more appropriate value)
+ */
+static void init_registers(volatile tsec_t * regs)
+{
+       /* Clear IEVENT */
+       regs->ievent = IEVENT_INIT_CLEAR;
+
+       regs->imask = IMASK_INIT_CLEAR;
+
+       regs->hash.iaddr0 = 0;
+       regs->hash.iaddr1 = 0;
+       regs->hash.iaddr2 = 0;
+       regs->hash.iaddr3 = 0;
+       regs->hash.iaddr4 = 0;
+       regs->hash.iaddr5 = 0;
+       regs->hash.iaddr6 = 0;
+       regs->hash.iaddr7 = 0;
+
+       regs->hash.gaddr0 = 0;
+       regs->hash.gaddr1 = 0;
+       regs->hash.gaddr2 = 0;
+       regs->hash.gaddr3 = 0;
+       regs->hash.gaddr4 = 0;
+       regs->hash.gaddr5 = 0;
+       regs->hash.gaddr6 = 0;
+       regs->hash.gaddr7 = 0;
+
+       regs->rctrl = 0x00000000;
+
+       /* Init RMON mib registers */
+       memset((void *)&(regs->rmon), 0, sizeof(rmon_mib_t));
+
+       regs->rmon.cam1 = 0xffffffff;
+       regs->rmon.cam2 = 0xffffffff;
+
+       regs->mrblr = MRBLR_INIT_SETTINGS;
+
+       regs->minflr = MINFLR_INIT_SETTINGS;
+
+       regs->attr = ATTR_INIT_SETTINGS;
+       regs->attreli = ATTRELI_INIT_SETTINGS;
+
+}
+
+/* Configure maccfg2 based on negotiated speed and duplex
+ * reported by PHY handling code
+ */
+static void adjust_link(struct eth_device *dev)
+{
+       struct tsec_private *priv = (struct tsec_private *)dev->priv;
+       volatile tsec_t *regs = priv->regs;
+
+       if (priv->link) {
+               if (priv->duplexity != 0)
+                       regs->maccfg2 |= MACCFG2_FULL_DUPLEX;
+               else
+                       regs->maccfg2 &= ~(MACCFG2_FULL_DUPLEX);
+
+               switch (priv->speed) {
+               case 1000:
+                       regs->maccfg2 = ((regs->maccfg2 & ~(MACCFG2_IF))
+                                        | MACCFG2_GMII);
+                       break;
+               case 100:
+               case 10:
+                       regs->maccfg2 = ((regs->maccfg2 & ~(MACCFG2_IF))
+                                        | MACCFG2_MII);
+
+                       /* Set R100 bit in all modes although
+                        * it is only used in RGMII mode
+                        */
+                       if (priv->speed == 100)
+                               regs->ecntrl |= ECNTRL_R100;
+                       else
+                               regs->ecntrl &= ~(ECNTRL_R100);
+                       break;
+               default:
+                       printf("%s: Speed was bad\n", dev->name);
+                       break;
+               }
+
+               printf("Speed: %d, %s duplex\n", priv->speed,
+                      (priv->duplexity) ? "full" : "half");
+
+       } else {
+               printf("%s: No link.\n", dev->name);
+       }
+}
+
+/* Set up the buffers and their descriptors, and bring up the
+ * interface
+ */
+static void startup_tsec(struct eth_device *dev)
+{
+       int i;
+       struct tsec_private *priv = (struct tsec_private *)dev->priv;
+       volatile tsec_t *regs = priv->regs;
+
+       /* Point to the buffer descriptors */
+       regs->tbase = (unsigned int)(&rtx.txbd[txIdx]);
+       regs->rbase = (unsigned int)(&rtx.rxbd[rxIdx]);
+
+       /* Initialize the Rx Buffer descriptors */
+       for (i = 0; i < PKTBUFSRX; i++) {
+               rtx.rxbd[i].status = RXBD_EMPTY;
+               rtx.rxbd[i].length = 0;
+               rtx.rxbd[i].bufPtr = (uint) NetRxPackets[i];
+       }
+       rtx.rxbd[PKTBUFSRX - 1].status |= RXBD_WRAP;
+
+       /* Initialize the TX Buffer Descriptors */
+       for (i = 0; i < TX_BUF_CNT; i++) {
+               rtx.txbd[i].status = 0;
+               rtx.txbd[i].length = 0;
+               rtx.txbd[i].bufPtr = 0;
+       }
+       rtx.txbd[TX_BUF_CNT - 1].status |= TXBD_WRAP;
+
+       /* Start up the PHY */
+       if(priv->phyinfo)
+               phy_run_commands(priv, priv->phyinfo->startup);
+
+       adjust_link(dev);
+
+       /* Enable Transmit and Receive */
+       regs->maccfg1 |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
+
+       /* Tell the DMA it is clear to go */
+       regs->dmactrl |= DMACTRL_INIT_SETTINGS;
+       regs->tstat = TSTAT_CLEAR_THALT;
+       regs->rstat = RSTAT_CLEAR_RHALT;
+       regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
+}
+
+/* This returns the status bits of the device. The return value
+ * is never checked, and this is what the 8260 driver did, so we
+ * do the same.         Presumably, this would be zero if there were no
+ * errors
+ */
+static int tsec_send(struct eth_device *dev, volatile void *packet, int length)
+{
+       int i;
+       int result = 0;
+       struct tsec_private *priv = (struct tsec_private *)dev->priv;
+       volatile tsec_t *regs = priv->regs;
+
+       /* Find an empty buffer descriptor */
+       for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
+               if (i >= TOUT_LOOP) {
+                       debug("%s: tsec: tx buffers full\n", dev->name);
+                       return result;
+               }
+       }
+
+       rtx.txbd[txIdx].bufPtr = (uint) packet;
+       rtx.txbd[txIdx].length = length;
+       rtx.txbd[txIdx].status |=
+           (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT);
+
+       /* Tell the DMA to go */
+       regs->tstat = TSTAT_CLEAR_THALT;
+
+       /* Wait for buffer to be transmitted */
+       for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
+               if (i >= TOUT_LOOP) {
+                       debug("%s: tsec: tx error\n", dev->name);
+                       return result;
+               }
+       }
+
+       txIdx = (txIdx + 1) % TX_BUF_CNT;
+       result = rtx.txbd[txIdx].status & TXBD_STATS;
+
+       return result;
+}
+
+static int tsec_recv(struct eth_device *dev)
+{
+       int length;
+       struct tsec_private *priv = (struct tsec_private *)dev->priv;
+       volatile tsec_t *regs = priv->regs;
+
+       while (!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) {
+
+               length = rtx.rxbd[rxIdx].length;
+
+               /* Send the packet up if there were no errors */
+               if (!(rtx.rxbd[rxIdx].status & RXBD_STATS)) {
+                       NetReceive(NetRxPackets[rxIdx], length - 4);
+               } else {
+                       printf("Got error %x\n",
+                              (rtx.rxbd[rxIdx].status & RXBD_STATS));
+               }
+
+               rtx.rxbd[rxIdx].length = 0;
+
+               /* Set the wrap bit if this is the last element in the list */
+               rtx.rxbd[rxIdx].status =
+                   RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0);
+
+               rxIdx = (rxIdx + 1) % PKTBUFSRX;
+       }
+
+       if (regs->ievent & IEVENT_BSY) {
+               regs->ievent = IEVENT_BSY;
+               regs->rstat = RSTAT_CLEAR_RHALT;
+       }
+
+       return -1;
+
+}
+
+/* Stop the interface */
+static void tsec_halt(struct eth_device *dev)
+{
+       struct tsec_private *priv = (struct tsec_private *)dev->priv;
+       volatile tsec_t *regs = priv->regs;
+
+       regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
+       regs->dmactrl |= (DMACTRL_GRS | DMACTRL_GTS);
+
+       while (!(regs->ievent & (IEVENT_GRSC | IEVENT_GTSC))) ;
+
+       regs->maccfg1 &= ~(MACCFG1_TX_EN | MACCFG1_RX_EN);
+
+       /* Shut down the PHY, as needed */
+       if(priv->phyinfo)
+               phy_run_commands(priv, priv->phyinfo->shutdown);
+}
+
+struct phy_info phy_info_M88E1149S = {
+       0x1410ca,
+       "Marvell 88E1149S",
+       4,
+       (struct phy_cmd[]){     /* config */
+               /* Reset and configure the PHY */
+               {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+               {0x1d, 0x1f, NULL},
+               {0x1e, 0x200c, NULL},
+               {0x1d, 0x5, NULL},
+               {0x1e, 0x0, NULL},
+               {0x1e, 0x100, NULL},
+               {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
+               {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
+               {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+               {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+               {miim_end,}
+       },
+       (struct phy_cmd[]){     /* startup */
+               /* Status is read once to clear old link state */
+               {MIIM_STATUS, miim_read, NULL},
+               /* Auto-negotiate */
+               {MIIM_STATUS, miim_read, &mii_parse_sr},
+               /* Read the status */
+               {MIIM_88E1011_PHY_STATUS, miim_read,
+                &mii_parse_88E1011_psr},
+               {miim_end,}
+       },
+       (struct phy_cmd[]){     /* shutdown */
+               {miim_end,}
+       },
+};
+
+/* The 5411 id is 0x206070, the 5421 is 0x2060e0 */
+struct phy_info phy_info_BCM5461S = {
+       0x02060c1,      /* 5461 ID */
+       "Broadcom BCM5461S",
+       0, /* not clear to me what minor revisions we can shift away */
+       (struct phy_cmd[]) { /* config */
+               /* Reset and configure the PHY */
+               {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+               {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
+               {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
+               {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+               {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+               {miim_end,}
+       },
+       (struct phy_cmd[]) { /* startup */
+               /* Status is read once to clear old link state */
+               {MIIM_STATUS, miim_read, NULL},
+               /* Auto-negotiate */
+               {MIIM_STATUS, miim_read, &mii_parse_sr},
+               /* Read the status */
+               {MIIM_BCM54xx_AUXSTATUS, miim_read, &mii_parse_BCM54xx_sr},
+               {miim_end,}
+       },
+       (struct phy_cmd[]) { /* shutdown */
+               {miim_end,}
+       },
+};
+
+struct phy_info phy_info_BCM5464S = {
+       0x02060b1,      /* 5464 ID */
+       "Broadcom BCM5464S",
+       0, /* not clear to me what minor revisions we can shift away */
+       (struct phy_cmd[]) { /* config */
+               /* Reset and configure the PHY */
+               {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+               {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
+               {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
+               {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+               {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+               {miim_end,}
+       },
+       (struct phy_cmd[]) { /* startup */
+               /* Status is read once to clear old link state */
+               {MIIM_STATUS, miim_read, NULL},
+               /* Auto-negotiate */
+               {MIIM_STATUS, miim_read, &mii_parse_sr},
+               /* Read the status */
+               {MIIM_BCM54xx_AUXSTATUS, miim_read, &mii_parse_BCM54xx_sr},
+               {miim_end,}
+       },
+       (struct phy_cmd[]) { /* shutdown */
+               {miim_end,}
+       },
+};
+
+struct phy_info phy_info_M88E1011S = {
+       0x01410c6,
+       "Marvell 88E1011S",
+       4,
+       (struct phy_cmd[]){     /* config */
+                          /* Reset and configure the PHY */
+                          {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+                          {0x1d, 0x1f, NULL},
+                          {0x1e, 0x200c, NULL},
+                          {0x1d, 0x5, NULL},
+                          {0x1e, 0x0, NULL},
+                          {0x1e, 0x100, NULL},
+                          {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
+                          {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
+                          {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+                          {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* startup */
+                          /* Status is read once to clear old link state */
+                          {MIIM_STATUS, miim_read, NULL},
+                          /* Auto-negotiate */
+                          {MIIM_STATUS, miim_read, &mii_parse_sr},
+                          /* Read the status */
+                          {MIIM_88E1011_PHY_STATUS, miim_read,
+                           &mii_parse_88E1011_psr},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* shutdown */
+                          {miim_end,}
+                          },
+};
+
+struct phy_info phy_info_M88E1111S = {
+       0x01410cc,
+       "Marvell 88E1111S",
+       4,
+       (struct phy_cmd[]){     /* config */
+                          /* Reset and configure the PHY */
+                          {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+                          {0x14, 0x0cd2, NULL}, /* Delay RGMII TX and RX */
+                          {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
+                          {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
+                          {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+                          {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* startup */
+                          /* Status is read once to clear old link state */
+                          {MIIM_STATUS, miim_read, NULL},
+                          /* Auto-negotiate */
+                          {MIIM_STATUS, miim_read, &mii_parse_sr},
+                          /* Read the status */
+                          {MIIM_88E1011_PHY_STATUS, miim_read,
+                           &mii_parse_88E1011_psr},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* shutdown */
+                          {miim_end,}
+                          },
+};
+
+static unsigned int m88e1145_setmode(uint mii_reg, struct tsec_private *priv)
+{
+       uint mii_data = read_phy_reg(priv, mii_reg);
+
+       /* Setting MIIM_88E1145_PHY_EXT_CR */
+       if (priv->flags & TSEC_REDUCED)
+               return mii_data |
+                   MIIM_M88E1145_RGMII_RX_DELAY | MIIM_M88E1145_RGMII_TX_DELAY;
+       else
+               return mii_data;
+}
+
+static struct phy_info phy_info_M88E1145 = {
+       0x01410cd,
+       "Marvell 88E1145",
+       4,
+       (struct phy_cmd[]){     /* config */
+                          /* Reset the PHY */
+                          {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+
+                          /* Errata E0, E1 */
+                          {29, 0x001b, NULL},
+                          {30, 0x418f, NULL},
+                          {29, 0x0016, NULL},
+                          {30, 0xa2da, NULL},
+
+                          /* Configure the PHY */
+                          {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
+                          {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
+                          {MIIM_88E1011_PHY_SCR, MIIM_88E1011_PHY_MDI_X_AUTO,
+                           NULL},
+                          {MIIM_88E1145_PHY_EXT_CR, 0, &m88e1145_setmode},
+                          {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+                          {MIIM_CONTROL, MIIM_CONTROL_INIT, NULL},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* startup */
+                          /* Status is read once to clear old link state */
+                          {MIIM_STATUS, miim_read, NULL},
+                          /* Auto-negotiate */
+                          {MIIM_STATUS, miim_read, &mii_parse_sr},
+                          {MIIM_88E1111_PHY_LED_CONTROL,
+                           MIIM_88E1111_PHY_LED_DIRECT, NULL},
+                          /* Read the Status */
+                          {MIIM_88E1011_PHY_STATUS, miim_read,
+                           &mii_parse_88E1011_psr},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* shutdown */
+                          {miim_end,}
+                          },
+};
+
+struct phy_info phy_info_cis8204 = {
+       0x3f11,
+       "Cicada Cis8204",
+       6,
+       (struct phy_cmd[]){     /* config */
+                          /* Override PHY config settings */
+                          {MIIM_CIS8201_AUX_CONSTAT,
+                           MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
+                          /* Configure some basic stuff */
+                          {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+                          {MIIM_CIS8204_SLED_CON, MIIM_CIS8204_SLEDCON_INIT,
+                           &mii_cis8204_fixled},
+                          {MIIM_CIS8204_EPHY_CON, MIIM_CIS8204_EPHYCON_INIT,
+                           &mii_cis8204_setmode},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* startup */
+                          /* Read the Status (2x to make sure link is right) */
+                          {MIIM_STATUS, miim_read, NULL},
+                          /* Auto-negotiate */
+                          {MIIM_STATUS, miim_read, &mii_parse_sr},
+                          /* Read the status */
+                          {MIIM_CIS8201_AUX_CONSTAT, miim_read,
+                           &mii_parse_cis8201},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* shutdown */
+                          {miim_end,}
+                          },
+};
+
+/* Cicada 8201 */
+struct phy_info phy_info_cis8201 = {
+       0xfc41,
+       "CIS8201",
+       4,
+       (struct phy_cmd[]){     /* config */
+                          /* Override PHY config settings */
+                          {MIIM_CIS8201_AUX_CONSTAT,
+                           MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
+                          /* Set up the interface mode */
+                          {MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT,
+                           NULL},
+                          /* Configure some basic stuff */
+                          {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* startup */
+                          /* Read the Status (2x to make sure link is right) */
+                          {MIIM_STATUS, miim_read, NULL},
+                          /* Auto-negotiate */
+                          {MIIM_STATUS, miim_read, &mii_parse_sr},
+                          /* Read the status */
+                          {MIIM_CIS8201_AUX_CONSTAT, miim_read,
+                           &mii_parse_cis8201},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* shutdown */
+                          {miim_end,}
+                          },
+};
+struct phy_info phy_info_VSC8244 = {
+       0x3f1b,
+       "Vitesse VSC8244",
+       6,
+       (struct phy_cmd[]){     /* config */
+                          /* Override PHY config settings */
+                          /* Configure some basic stuff */
+                          {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* startup */
+                          /* Read the Status (2x to make sure link is right) */
+                          {MIIM_STATUS, miim_read, NULL},
+                          /* Auto-negotiate */
+                          {MIIM_STATUS, miim_read, &mii_parse_sr},
+                          /* Read the status */
+                          {MIIM_VSC8244_AUX_CONSTAT, miim_read,
+                           &mii_parse_vsc8244},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* shutdown */
+                          {miim_end,}
+                          },
+};
+
+struct phy_info phy_info_dm9161 = {
+       0x0181b88,
+       "Davicom DM9161E",
+       4,
+       (struct phy_cmd[]){     /* config */
+                          {MIIM_CONTROL, MIIM_DM9161_CR_STOP, NULL},
+                          /* Do not bypass the scrambler/descrambler */
+                          {MIIM_DM9161_SCR, MIIM_DM9161_SCR_INIT, NULL},
+                          /* Clear 10BTCSR to default */
+                          {MIIM_DM9161_10BTCSR, MIIM_DM9161_10BTCSR_INIT,
+                           NULL},
+                          /* Configure some basic stuff */
+                          {MIIM_CONTROL, MIIM_CR_INIT, NULL},
+                          /* Restart Auto Negotiation */
+                          {MIIM_CONTROL, MIIM_DM9161_CR_RSTAN, NULL},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* startup */
+                          /* Status is read once to clear old link state */
+                          {MIIM_STATUS, miim_read, NULL},
+                          /* Auto-negotiate */
+                          {MIIM_STATUS, miim_read, &mii_parse_sr},
+                          /* Read the status */
+                          {MIIM_DM9161_SCSR, miim_read,
+                           &mii_parse_dm9161_scsr},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* shutdown */
+                          {miim_end,}
+                          },
+};
+/* a generic flavor.  */
+struct phy_info phy_info_generic =  {
+       0,
+       "Unknown/Generic PHY",
+       32,
+       (struct phy_cmd[]) { /* config */
+               {PHY_BMCR, PHY_BMCR_RESET, NULL},
+               {PHY_BMCR, PHY_BMCR_AUTON|PHY_BMCR_RST_NEG, NULL},
+               {miim_end,}
+       },
+       (struct phy_cmd[]) { /* startup */
+               {PHY_BMSR, miim_read, NULL},
+               {PHY_BMSR, miim_read, &mii_parse_sr},
+               {PHY_BMSR, miim_read, &mii_parse_link},
+               {miim_end,}
+       },
+       (struct phy_cmd[]) { /* shutdown */
+               {miim_end,}
+       }
+};
+
+
+uint mii_parse_lxt971_sr2(uint mii_reg, struct tsec_private *priv)
+{
+       unsigned int speed;
+       if (priv->link) {
+               speed = mii_reg & MIIM_LXT971_SR2_SPEED_MASK;
+
+               switch (speed) {
+               case MIIM_LXT971_SR2_10HDX:
+                       priv->speed = 10;
+                       priv->duplexity = 0;
+                       break;
+               case MIIM_LXT971_SR2_10FDX:
+                       priv->speed = 10;
+                       priv->duplexity = 1;
+                       break;
+               case MIIM_LXT971_SR2_100HDX:
+                       priv->speed = 100;
+                       priv->duplexity = 0;
+                       break;
+               default:
+                       priv->speed = 100;
+                       priv->duplexity = 1;
+               }
+       } else {
+               priv->speed = 0;
+               priv->duplexity = 0;
+       }
+
+       return 0;
+}
+
+static struct phy_info phy_info_lxt971 = {
+       0x0001378e,
+       "LXT971",
+       4,
+       (struct phy_cmd[]){     /* config */
+                          {MIIM_CR, MIIM_CR_INIT, mii_cr_init},        /* autonegotiate */
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* startup - enable interrupts */
+                          /* { 0x12, 0x00f2, NULL }, */
+                          {MIIM_STATUS, miim_read, NULL},
+                          {MIIM_STATUS, miim_read, &mii_parse_sr},
+                          {MIIM_LXT971_SR2, miim_read, &mii_parse_lxt971_sr2},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* shutdown - disable interrupts */
+                          {miim_end,}
+                          },
+};
+
+/* Parse the DP83865's link and auto-neg status register for speed and duplex
+ * information
+ */
+uint mii_parse_dp83865_lanr(uint mii_reg, struct tsec_private *priv)
+{
+       switch (mii_reg & MIIM_DP83865_SPD_MASK) {
+
+       case MIIM_DP83865_SPD_1000:
+               priv->speed = 1000;
+               break;
+
+       case MIIM_DP83865_SPD_100:
+               priv->speed = 100;
+               break;
+
+       default:
+               priv->speed = 10;
+               break;
+
+       }
+
+       if (mii_reg & MIIM_DP83865_DPX_FULL)
+               priv->duplexity = 1;
+       else
+               priv->duplexity = 0;
+
+       return 0;
+}
+
+struct phy_info phy_info_dp83865 = {
+       0x20005c7,
+       "NatSemi DP83865",
+       4,
+       (struct phy_cmd[]){     /* config */
+                          {MIIM_CONTROL, MIIM_DP83865_CR_INIT, NULL},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* startup */
+                          /* Status is read once to clear old link state */
+                          {MIIM_STATUS, miim_read, NULL},
+                          /* Auto-negotiate */
+                          {MIIM_STATUS, miim_read, &mii_parse_sr},
+                          /* Read the link and auto-neg status */
+                          {MIIM_DP83865_LANR, miim_read,
+                           &mii_parse_dp83865_lanr},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]){     /* shutdown */
+                          {miim_end,}
+                          },
+};
+
+struct phy_info *phy_info[] = {
+       &phy_info_cis8204,
+       &phy_info_cis8201,
+       &phy_info_BCM5461S,
+       &phy_info_BCM5464S,
+       &phy_info_M88E1011S,
+       &phy_info_M88E1111S,
+       &phy_info_M88E1145,
+       &phy_info_M88E1149S,
+       &phy_info_dm9161,
+       &phy_info_lxt971,
+       &phy_info_VSC8244,
+       &phy_info_dp83865,
+       &phy_info_generic,
+       NULL
+};
+
+/* Grab the identifier of the device's PHY, and search through
+ * all of the known PHYs to see if one matches.         If so, return
+ * it, if not, return NULL
+ */
+struct phy_info *get_phy_info(struct eth_device *dev)
+{
+       struct tsec_private *priv = (struct tsec_private *)dev->priv;
+       uint phy_reg, phy_ID;
+       int i;
+       struct phy_info *theInfo = NULL;
+
+       /* Grab the bits from PHYIR1, and put them in the upper half */
+       phy_reg = read_phy_reg(priv, MIIM_PHYIR1);
+       phy_ID = (phy_reg & 0xffff) << 16;
+
+       /* Grab the bits from PHYIR2, and put them in the lower half */
+       phy_reg = read_phy_reg(priv, MIIM_PHYIR2);
+       phy_ID |= (phy_reg & 0xffff);
+
+       /* loop through all the known PHY types, and find one that */
+       /* matches the ID we read from the PHY. */
+       for (i = 0; phy_info[i]; i++) {
+               if (phy_info[i]->id == (phy_ID >> phy_info[i]->shift)) {
+                       theInfo = phy_info[i];
+                       break;
+               }
+       }
+
+       if (theInfo == NULL) {
+               printf("%s: PHY id %x is not supported!\n", dev->name, phy_ID);
+               return NULL;
+       } else {
+               debug("%s: PHY is %s (%x)\n", dev->name, theInfo->name, phy_ID);
+       }
+
+       return theInfo;
+}
+
+/* Execute the given series of commands on the given device's
+ * PHY, running functions as necessary
+ */
+void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd)
+{
+       int i;
+       uint result;
+       volatile tsec_t *phyregs = priv->phyregs;
+
+       phyregs->miimcfg = MIIMCFG_RESET;
+
+       phyregs->miimcfg = MIIMCFG_INIT_VALUE;
+
+       while (phyregs->miimind & MIIMIND_BUSY) ;
+
+       for (i = 0; cmd->mii_reg != miim_end; i++) {
+               if (cmd->mii_data == miim_read) {
+                       result = read_phy_reg(priv, cmd->mii_reg);
+
+                       if (cmd->funct != NULL)
+                               (*(cmd->funct)) (result, priv);
+
+               } else {
+                       if (cmd->funct != NULL)
+                               result = (*(cmd->funct)) (cmd->mii_reg, priv);
+                       else
+                               result = cmd->mii_data;
+
+                       write_phy_reg(priv, cmd->mii_reg, result);
+
+               }
+               cmd++;
+       }
+}
+
+/* Relocate the function pointers in the phy cmd lists */
+static void relocate_cmds(void)
+{
+       struct phy_cmd **cmdlistptr;
+       struct phy_cmd *cmd;
+       int i, j, k;
+
+       for (i = 0; phy_info[i]; i++) {
+               /* First thing's first: relocate the pointers to the
+                * PHY command structures (the structs were done) */
+               phy_info[i] = (struct phy_info *)((uint) phy_info[i]
+                                                 + gd->reloc_off);
+               phy_info[i]->name += gd->reloc_off;
+               phy_info[i]->config =
+                   (struct phy_cmd *)((uint) phy_info[i]->config
+                                      + gd->reloc_off);
+               phy_info[i]->startup =
+                   (struct phy_cmd *)((uint) phy_info[i]->startup
+                                      + gd->reloc_off);
+               phy_info[i]->shutdown =
+                   (struct phy_cmd *)((uint) phy_info[i]->shutdown
+                                      + gd->reloc_off);
+
+               cmdlistptr = &phy_info[i]->config;
+               j = 0;
+               for (; cmdlistptr <= &phy_info[i]->shutdown; cmdlistptr++) {
+                       k = 0;
+                       for (cmd = *cmdlistptr;
+                            cmd->mii_reg != miim_end;
+                            cmd++) {
+                               /* Only relocate non-NULL pointers */
+                               if (cmd->funct)
+                                       cmd->funct += gd->reloc_off;
+
+                               k++;
+                       }
+                       j++;
+               }
+       }
+
+       relocated = 1;
+}
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
+       && !defined(BITBANGMII)
+
+struct tsec_private *get_priv_for_phy(unsigned char phyaddr)
+{
+       int i;
+
+       for (i = 0; i < MAXCONTROLLERS; i++) {
+               if (privlist[i]->phyaddr == phyaddr)
+                       return privlist[i];
+       }
+
+       return NULL;
+}
+
+/*
+ * Read a MII PHY register.
+ *
+ * Returns:
+ *  0 on success
+ */
+static int tsec_miiphy_read(char *devname, unsigned char addr,
+                           unsigned char reg, unsigned short *value)
+{
+       unsigned short ret;
+       struct tsec_private *priv = get_priv_for_phy(addr);
+
+       if (NULL == priv) {
+               printf("Can't read PHY at address %d\n", addr);
+               return -1;
+       }
+
+       ret = (unsigned short)read_phy_reg(priv, reg);
+       *value = ret;
+
+       return 0;
+}
+
+/*
+ * Write a MII PHY register.
+ *
+ * Returns:
+ *  0 on success
+ */
+static int tsec_miiphy_write(char *devname, unsigned char addr,
+                            unsigned char reg, unsigned short value)
+{
+       struct tsec_private *priv = get_priv_for_phy(addr);
+
+       if (NULL == priv) {
+               printf("Can't write PHY at address %d\n", addr);
+               return -1;
+       }
+
+       write_phy_reg(priv, reg, value);
+
+       return 0;
+}
+
+#endif
+
+#ifdef CONFIG_MCAST_TFTP
+
+/* CREDITS: linux gianfar driver, slightly adjusted... thanx. */
+
+/* Set the appropriate hash bit for the given addr */
+
+/* The algorithm works like so:
+ * 1) Take the Destination Address (ie the multicast address), and
+ * do a CRC on it (little endian), and reverse the bits of the
+ * result.
+ * 2) Use the 8 most significant bits as a hash into a 256-entry
+ * table.  The table is controlled through 8 32-bit registers:
+ * gaddr0-7.  gaddr0's MSB is entry 0, and gaddr7's LSB is
+ * gaddr7.  This means that the 3 most significant bits in the
+ * hash index which gaddr register to use, and the 5 other bits
+ * indicate which bit (assuming an IBM numbering scheme, which
+ * for PowerPC (tm) is usually the case) in the tregister holds
+ * the entry. */
+static int
+tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set)
+{
+ struct tsec_private *priv = privlist[1];
+ volatile tsec_t *regs = priv->regs;
+ volatile u32  *reg_array, value;
+ u8 result, whichbit, whichreg;
+
+       result = (u8)((ether_crc(MAC_ADDR_LEN,mcast_mac) >> 24) & 0xff);
+       whichbit = result & 0x1f;       /* the 5 LSB = which bit to set */
+       whichreg = result >> 5;         /* the 3 MSB = which reg to set it in */
+       value = (1 << (31-whichbit));
+
+       reg_array = &(regs->hash.gaddr0);
+
+       if (set) {
+               reg_array[whichreg] |= value;
+       } else {
+               reg_array[whichreg] &= ~value;
+       }
+       return 0;
+}
+#endif /* Multicast TFTP ? */
+
+#endif /* CONFIG_TSEC_ENET */
diff --git a/drivers/net/tsec.h b/drivers/net/tsec.h
new file mode 100644 (file)
index 0000000..2f0092a
--- /dev/null
@@ -0,0 +1,563 @@
+/*
+ *  tsec.h
+ *
+ *  Driver for the Motorola Triple Speed Ethernet Controller
+ *
+ *  This software may be used and distributed according to the
+ *  terms of the GNU Public License, Version 2, incorporated
+ *  herein by reference.
+ *
+ * Copyright 2004, 2007 Freescale Semiconductor, Inc.
+ * (C) Copyright 2003, Motorola, Inc.
+ * maintained by Xianghua Xiao (x.xiao@motorola.com)
+ * author Andy Fleming
+ *
+ */
+
+#ifndef __TSEC_H
+#define __TSEC_H
+
+#include <net.h>
+#include <config.h>
+
+#ifndef CFG_TSEC1_OFFSET
+    #define CFG_TSEC1_OFFSET   (0x24000)
+#endif
+
+#define TSEC_SIZE      0x01000
+
+/* FIXME:  Should these be pushed back to 83xx and 85xx config files? */
+#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
+    #define TSEC_BASE_ADDR     (CFG_IMMR + CFG_TSEC1_OFFSET)
+#elif defined(CONFIG_MPC83XX)
+    #define TSEC_BASE_ADDR     (CFG_IMMR + CFG_TSEC1_OFFSET)
+#endif
+
+
+#define MAC_ADDR_LEN 6
+
+/* #define TSEC_TIMEOUT        1000000 */
+#define TSEC_TIMEOUT 1000
+#define TOUT_LOOP      1000000
+
+#define PHY_AUTONEGOTIATE_TIMEOUT      5000 /* in ms */
+
+/* MAC register bits */
+#define MACCFG1_SOFT_RESET     0x80000000
+#define MACCFG1_RESET_RX_MC    0x00080000
+#define MACCFG1_RESET_TX_MC    0x00040000
+#define MACCFG1_RESET_RX_FUN   0x00020000
+#define        MACCFG1_RESET_TX_FUN    0x00010000
+#define MACCFG1_LOOPBACK       0x00000100
+#define MACCFG1_RX_FLOW                0x00000020
+#define MACCFG1_TX_FLOW                0x00000010
+#define MACCFG1_SYNCD_RX_EN    0x00000008
+#define MACCFG1_RX_EN          0x00000004
+#define MACCFG1_SYNCD_TX_EN    0x00000002
+#define MACCFG1_TX_EN          0x00000001
+
+#define MACCFG2_INIT_SETTINGS  0x00007205
+#define MACCFG2_FULL_DUPLEX    0x00000001
+#define MACCFG2_IF              0x00000300
+#define MACCFG2_GMII           0x00000200
+#define MACCFG2_MII             0x00000100
+
+#define ECNTRL_INIT_SETTINGS   0x00001000
+#define ECNTRL_TBI_MODE         0x00000020
+#define ECNTRL_R100            0x00000008
+#define ECNTRL_SGMII_MODE      0x00000002
+
+#define miim_end -2
+#define miim_read -1
+
+#ifndef CFG_TBIPA_VALUE
+    #define CFG_TBIPA_VALUE    0x1f
+#endif
+#define MIIMCFG_INIT_VALUE     0x00000003
+#define MIIMCFG_RESET          0x80000000
+
+#define MIIMIND_BUSY            0x00000001
+#define MIIMIND_NOTVALID        0x00000004
+
+#define MIIM_CONTROL            0x00
+#define MIIM_CONTROL_RESET     0x00009140
+#define MIIM_CONTROL_INIT       0x00001140
+#define MIIM_CONTROL_RESTART    0x00001340
+#define MIIM_ANEN               0x00001000
+
+#define MIIM_CR                 0x00
+#define MIIM_CR_RST            0x00008000
+#define MIIM_CR_INIT           0x00001000
+
+#define MIIM_STATUS            0x1
+#define MIIM_STATUS_AN_DONE    0x00000020
+#define MIIM_STATUS_LINK       0x0004
+#define PHY_BMSR_AUTN_ABLE     0x0008
+#define PHY_BMSR_AUTN_COMP     0x0020
+
+#define MIIM_PHYIR1            0x2
+#define MIIM_PHYIR2            0x3
+
+#define MIIM_ANAR              0x4
+#define MIIM_ANAR_INIT         0x1e1
+
+#define MIIM_TBI_ANLPBPA       0x5
+#define MIIM_TBI_ANLPBPA_HALF  0x00000040
+#define MIIM_TBI_ANLPBPA_FULL  0x00000020
+
+#define MIIM_TBI_ANEX          0x6
+#define MIIM_TBI_ANEX_NP       0x00000004
+#define MIIM_TBI_ANEX_PRX      0x00000002
+
+#define MIIM_GBIT_CONTROL      0x9
+#define MIIM_GBIT_CONTROL_INIT 0xe00
+
+/* Broadcom BCM54xx -- taken from linux sungem_phy */
+#define MIIM_BCM54xx_AUXSTATUS                 0x19
+#define MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK   0x0700
+#define MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT  8
+
+/* Cicada Auxiliary Control/Status Register */
+#define MIIM_CIS8201_AUX_CONSTAT        0x1c
+#define MIIM_CIS8201_AUXCONSTAT_INIT    0x0004
+#define MIIM_CIS8201_AUXCONSTAT_DUPLEX  0x0020
+#define MIIM_CIS8201_AUXCONSTAT_SPEED   0x0018
+#define MIIM_CIS8201_AUXCONSTAT_GBIT    0x0010
+#define MIIM_CIS8201_AUXCONSTAT_100     0x0008
+
+/* Cicada Extended Control Register 1 */
+#define MIIM_CIS8201_EXT_CON1           0x17
+#define MIIM_CIS8201_EXTCON1_INIT       0x0000
+
+/* Cicada 8204 Extended PHY Control Register 1 */
+#define MIIM_CIS8204_EPHY_CON          0x17
+#define MIIM_CIS8204_EPHYCON_INIT      0x0006
+#define MIIM_CIS8204_EPHYCON_RGMII     0x1100
+
+/* Cicada 8204 Serial LED Control Register */
+#define MIIM_CIS8204_SLED_CON          0x1b
+#define MIIM_CIS8204_SLEDCON_INIT      0x1115
+
+#define MIIM_GBIT_CON          0x09
+#define MIIM_GBIT_CON_ADVERT   0x0e00
+
+/* Entry for Vitesse VSC8244 regs starts here */
+/* Vitesse VSC8244 Auxiliary Control/Status Register */
+#define MIIM_VSC8244_AUX_CONSTAT        0x1c
+#define MIIM_VSC8244_AUXCONSTAT_INIT    0x0000
+#define MIIM_VSC8244_AUXCONSTAT_DUPLEX  0x0020
+#define MIIM_VSC8244_AUXCONSTAT_SPEED   0x0018
+#define MIIM_VSC8244_AUXCONSTAT_GBIT    0x0010
+#define MIIM_VSC8244_AUXCONSTAT_100     0x0008
+#define MIIM_CONTROL_INIT_LOOPBACK      0x4000
+
+/* Vitesse VSC8244 Extended PHY Control Register 1 */
+#define MIIM_VSC8244_EPHY_CON           0x17
+#define MIIM_VSC8244_EPHYCON_INIT       0x0006
+
+/* Vitesse VSC8244 Serial LED Control Register */
+#define MIIM_VSC8244_LED_CON            0x1b
+#define MIIM_VSC8244_LEDCON_INIT        0xF011
+
+/* 88E1011 PHY Status Register */
+#define MIIM_88E1011_PHY_STATUS         0x11
+#define MIIM_88E1011_PHYSTAT_SPEED      0xc000
+#define MIIM_88E1011_PHYSTAT_GBIT       0x8000
+#define MIIM_88E1011_PHYSTAT_100        0x4000
+#define MIIM_88E1011_PHYSTAT_DUPLEX     0x2000
+#define MIIM_88E1011_PHYSTAT_SPDDONE   0x0800
+#define MIIM_88E1011_PHYSTAT_LINK      0x0400
+
+#define MIIM_88E1011_PHY_SCR           0x10
+#define MIIM_88E1011_PHY_MDI_X_AUTO    0x0060
+
+/* 88E1111 PHY LED Control Register */
+#define MIIM_88E1111_PHY_LED_CONTROL   24
+#define MIIM_88E1111_PHY_LED_DIRECT    0x4100
+#define MIIM_88E1111_PHY_LED_COMBINE   0x411C
+
+/* 88E1145 Extended PHY Specific Control Register */
+#define MIIM_88E1145_PHY_EXT_CR 20
+#define MIIM_M88E1145_RGMII_RX_DELAY   0x0080
+#define MIIM_M88E1145_RGMII_TX_DELAY   0x0002
+
+#define MIIM_88E1145_PHY_PAGE   29
+#define MIIM_88E1145_PHY_CAL_OV 30
+
+
+/* DM9161 Control register values */
+#define MIIM_DM9161_CR_STOP    0x0400
+#define MIIM_DM9161_CR_RSTAN   0x1200
+
+#define MIIM_DM9161_SCR                0x10
+#define MIIM_DM9161_SCR_INIT   0x0610
+
+/* DM9161 Specified Configuration and Status Register */
+#define MIIM_DM9161_SCSR       0x11
+#define MIIM_DM9161_SCSR_100F  0x8000
+#define MIIM_DM9161_SCSR_100H  0x4000
+#define MIIM_DM9161_SCSR_10F   0x2000
+#define MIIM_DM9161_SCSR_10H   0x1000
+
+/* DM9161 10BT Configuration/Status */
+#define MIIM_DM9161_10BTCSR    0x12
+#define MIIM_DM9161_10BTCSR_INIT       0x7800
+
+/* LXT971 Status 2 registers */
+#define MIIM_LXT971_SR2              0x11  /* Status Register 2  */
+#define MIIM_LXT971_SR2_SPEED_MASK 0x4200
+#define MIIM_LXT971_SR2_10HDX      0x0000  /*  10 Mbit half duplex selected */
+#define MIIM_LXT971_SR2_10FDX      0x0200  /*  10 Mbit full duplex selected */
+#define MIIM_LXT971_SR2_100HDX     0x4000  /* 100 Mbit half duplex selected */
+#define MIIM_LXT971_SR2_100FDX     0x4200  /* 100 Mbit full duplex selected */
+
+/* DP83865 Control register values */
+#define MIIM_DP83865_CR_INIT   0x9200
+
+/* DP83865 Link and Auto-Neg Status Register */
+#define MIIM_DP83865_LANR      0x11
+#define MIIM_DP83865_SPD_MASK  0x0018
+#define MIIM_DP83865_SPD_1000  0x0010
+#define MIIM_DP83865_SPD_100   0x0008
+#define MIIM_DP83865_DPX_FULL  0x0002
+
+#define MIIM_READ_COMMAND       0x00000001
+
+#define MRBLR_INIT_SETTINGS    PKTSIZE_ALIGN
+
+#define MINFLR_INIT_SETTINGS   0x00000040
+
+#define DMACTRL_INIT_SETTINGS   0x000000c3
+#define DMACTRL_GRS             0x00000010
+#define DMACTRL_GTS             0x00000008
+
+#define TSTAT_CLEAR_THALT       0x80000000
+#define RSTAT_CLEAR_RHALT       0x00800000
+
+
+#define IEVENT_INIT_CLEAR      0xffffffff
+#define IEVENT_BABR            0x80000000
+#define IEVENT_RXC             0x40000000
+#define IEVENT_BSY             0x20000000
+#define IEVENT_EBERR           0x10000000
+#define IEVENT_MSRO            0x04000000
+#define IEVENT_GTSC            0x02000000
+#define IEVENT_BABT            0x01000000
+#define IEVENT_TXC             0x00800000
+#define IEVENT_TXE             0x00400000
+#define IEVENT_TXB             0x00200000
+#define IEVENT_TXF             0x00100000
+#define IEVENT_IE              0x00080000
+#define IEVENT_LC              0x00040000
+#define IEVENT_CRL             0x00020000
+#define IEVENT_XFUN            0x00010000
+#define IEVENT_RXB0            0x00008000
+#define IEVENT_GRSC            0x00000100
+#define IEVENT_RXF0            0x00000080
+
+#define IMASK_INIT_CLEAR       0x00000000
+#define IMASK_TXEEN            0x00400000
+#define IMASK_TXBEN            0x00200000
+#define IMASK_TXFEN             0x00100000
+#define IMASK_RXFEN0           0x00000080
+
+
+/* Default Attribute fields */
+#define ATTR_INIT_SETTINGS     0x000000c0
+#define ATTRELI_INIT_SETTINGS  0x00000000
+
+
+/* TxBD status field bits */
+#define TXBD_READY             0x8000
+#define TXBD_PADCRC            0x4000
+#define TXBD_WRAP              0x2000
+#define TXBD_INTERRUPT         0x1000
+#define TXBD_LAST              0x0800
+#define TXBD_CRC               0x0400
+#define TXBD_DEF               0x0200
+#define TXBD_HUGEFRAME         0x0080
+#define TXBD_LATECOLLISION     0x0080
+#define TXBD_RETRYLIMIT                0x0040
+#define        TXBD_RETRYCOUNTMASK     0x003c
+#define TXBD_UNDERRUN          0x0002
+#define TXBD_STATS              0x03ff
+
+/* RxBD status field bits */
+#define RXBD_EMPTY             0x8000
+#define RXBD_RO1               0x4000
+#define RXBD_WRAP              0x2000
+#define RXBD_INTERRUPT         0x1000
+#define RXBD_LAST              0x0800
+#define RXBD_FIRST             0x0400
+#define RXBD_MISS              0x0100
+#define RXBD_BROADCAST         0x0080
+#define RXBD_MULTICAST         0x0040
+#define RXBD_LARGE             0x0020
+#define RXBD_NONOCTET          0x0010
+#define RXBD_SHORT             0x0008
+#define RXBD_CRCERR            0x0004
+#define RXBD_OVERRUN           0x0002
+#define RXBD_TRUNCATED         0x0001
+#define RXBD_STATS             0x003f
+
+typedef struct txbd8
+{
+       ushort       status;         /* Status Fields */
+       ushort       length;         /* Buffer length */
+       uint         bufPtr;         /* Buffer Pointer */
+} txbd8_t;
+
+typedef struct rxbd8
+{
+       ushort       status;         /* Status Fields */
+       ushort       length;         /* Buffer Length */
+       uint         bufPtr;         /* Buffer Pointer */
+} rxbd8_t;
+
+typedef struct rmon_mib
+{
+       /* Transmit and Receive Counters */
+       uint    tr64;           /* Transmit and Receive 64-byte Frame Counter */
+       uint    tr127;          /* Transmit and Receive 65-127 byte Frame Counter */
+       uint    tr255;          /* Transmit and Receive 128-255 byte Frame Counter */
+       uint    tr511;          /* Transmit and Receive 256-511 byte Frame Counter */
+       uint    tr1k;           /* Transmit and Receive 512-1023 byte Frame Counter */
+       uint    trmax;          /* Transmit and Receive 1024-1518 byte Frame Counter */
+       uint    trmgv;          /* Transmit and Receive 1519-1522 byte Good VLAN Frame */
+       /* Receive Counters */
+       uint    rbyt;           /* Receive Byte Counter */
+       uint    rpkt;           /* Receive Packet Counter */
+       uint    rfcs;           /* Receive FCS Error Counter */
+       uint    rmca;           /* Receive Multicast Packet (Counter) */
+       uint    rbca;           /* Receive Broadcast Packet */
+       uint    rxcf;           /* Receive Control Frame Packet */
+       uint    rxpf;           /* Receive Pause Frame Packet */
+       uint    rxuo;           /* Receive Unknown OP Code */
+       uint    raln;           /* Receive Alignment Error */
+       uint    rflr;           /* Receive Frame Length Error */
+       uint    rcde;           /* Receive Code Error */
+       uint    rcse;           /* Receive Carrier Sense Error */
+       uint    rund;           /* Receive Undersize Packet */
+       uint    rovr;           /* Receive Oversize Packet */
+       uint    rfrg;           /* Receive Fragments */
+       uint    rjbr;           /* Receive Jabber */
+       uint    rdrp;           /* Receive Drop */
+       /* Transmit Counters */
+       uint    tbyt;           /* Transmit Byte Counter */
+       uint    tpkt;           /* Transmit Packet */
+       uint    tmca;           /* Transmit Multicast Packet */
+       uint    tbca;           /* Transmit Broadcast Packet */
+       uint    txpf;           /* Transmit Pause Control Frame */
+       uint    tdfr;           /* Transmit Deferral Packet */
+       uint    tedf;           /* Transmit Excessive Deferral Packet */
+       uint    tscl;           /* Transmit Single Collision Packet */
+       /* (0x2_n700) */
+       uint    tmcl;           /* Transmit Multiple Collision Packet */
+       uint    tlcl;           /* Transmit Late Collision Packet */
+       uint    txcl;           /* Transmit Excessive Collision Packet */
+       uint    tncl;           /* Transmit Total Collision */
+
+       uint    res2;
+
+       uint    tdrp;           /* Transmit Drop Frame */
+       uint    tjbr;           /* Transmit Jabber Frame */
+       uint    tfcs;           /* Transmit FCS Error */
+       uint    txcf;           /* Transmit Control Frame */
+       uint    tovr;           /* Transmit Oversize Frame */
+       uint    tund;           /* Transmit Undersize Frame */
+       uint    tfrg;           /* Transmit Fragments Frame */
+       /* General Registers */
+       uint    car1;           /* Carry Register One */
+       uint    car2;           /* Carry Register Two */
+       uint    cam1;           /* Carry Register One Mask */
+       uint    cam2;           /* Carry Register Two Mask */
+} rmon_mib_t;
+
+typedef struct tsec_hash_regs
+{
+       uint    iaddr0;         /* Individual Address Register 0 */
+       uint    iaddr1;         /* Individual Address Register 1 */
+       uint    iaddr2;         /* Individual Address Register 2 */
+       uint    iaddr3;         /* Individual Address Register 3 */
+       uint    iaddr4;         /* Individual Address Register 4 */
+       uint    iaddr5;         /* Individual Address Register 5 */
+       uint    iaddr6;         /* Individual Address Register 6 */
+       uint    iaddr7;         /* Individual Address Register 7 */
+       uint    res1[24];
+       uint    gaddr0;         /* Group Address Register 0 */
+       uint    gaddr1;         /* Group Address Register 1 */
+       uint    gaddr2;         /* Group Address Register 2 */
+       uint    gaddr3;         /* Group Address Register 3 */
+       uint    gaddr4;         /* Group Address Register 4 */
+       uint    gaddr5;         /* Group Address Register 5 */
+       uint    gaddr6;         /* Group Address Register 6 */
+       uint    gaddr7;         /* Group Address Register 7 */
+       uint    res2[24];
+} tsec_hash_t;
+
+typedef struct tsec
+{
+       /* General Control and Status Registers (0x2_n000) */
+       uint    res000[4];
+
+       uint    ievent;         /* Interrupt Event */
+       uint    imask;          /* Interrupt Mask */
+       uint    edis;           /* Error Disabled */
+       uint    res01c;
+       uint    ecntrl;         /* Ethernet Control */
+       uint    minflr;         /* Minimum Frame Length */
+       uint    ptv;            /* Pause Time Value */
+       uint    dmactrl;        /* DMA Control */
+       uint    tbipa;          /* TBI PHY Address */
+
+       uint    res034[3];
+       uint    res040[48];
+
+       /* Transmit Control and Status Registers (0x2_n100) */
+       uint    tctrl;          /* Transmit Control */
+       uint    tstat;          /* Transmit Status */
+       uint    res108;
+       uint    tbdlen;         /* Tx BD Data Length */
+       uint    res110[5];
+       uint    ctbptr;         /* Current TxBD Pointer */
+       uint    res128[23];
+       uint    tbptr;          /* TxBD Pointer */
+       uint    res188[30];
+       /* (0x2_n200) */
+       uint        res200;
+       uint    tbase;          /* TxBD Base Address */
+       uint    res208[42];
+       uint    ostbd;          /* Out of Sequence TxBD */
+       uint    ostbdp;         /* Out of Sequence Tx Data Buffer Pointer */
+       uint        res2b8[18];
+
+       /* Receive Control and Status Registers (0x2_n300) */
+       uint    rctrl;          /* Receive Control */
+       uint    rstat;          /* Receive Status */
+       uint    res308;
+       uint    rbdlen;         /* RxBD Data Length */
+       uint    res310[4];
+       uint        res320;
+       uint    crbptr;         /* Current Receive Buffer Pointer */
+       uint    res328[6];
+       uint    mrblr;          /* Maximum Receive Buffer Length */
+       uint    res344[16];
+       uint    rbptr;          /* RxBD Pointer */
+       uint        res388[30];
+       /* (0x2_n400) */
+       uint        res400;
+       uint    rbase;          /* RxBD Base Address */
+       uint        res408[62];
+
+       /* MAC Registers (0x2_n500) */
+       uint    maccfg1;        /* MAC Configuration #1 */
+       uint    maccfg2;        /* MAC Configuration #2 */
+       uint    ipgifg;         /* Inter Packet Gap/Inter Frame Gap */
+       uint    hafdup;         /* Half-duplex */
+       uint    maxfrm;         /* Maximum Frame */
+       uint    res514;
+       uint    res518;
+
+       uint    res51c;
+
+       uint    miimcfg;        /* MII Management: Configuration */
+       uint    miimcom;        /* MII Management: Command */
+       uint    miimadd;        /* MII Management: Address */
+       uint    miimcon;        /* MII Management: Control */
+       uint    miimstat;       /* MII Management: Status */
+       uint    miimind;        /* MII Management: Indicators */
+
+       uint    res538;
+
+       uint    ifstat;         /* Interface Status */
+       uint    macstnaddr1;    /* Station Address, part 1 */
+       uint    macstnaddr2;    /* Station Address, part 2 */
+       uint    res548[46];
+
+       /* (0x2_n600) */
+       uint    res600[32];
+
+       /* RMON MIB Registers (0x2_n680-0x2_n73c) */
+       rmon_mib_t      rmon;
+       uint    res740[48];
+
+       /* Hash Function Registers (0x2_n800) */
+       tsec_hash_t     hash;
+
+       uint        res900[128];
+
+       /* Pattern Registers (0x2_nb00) */
+       uint        resb00[62];
+       uint        attr;          /* Default Attribute Register */
+       uint        attreli;       /* Default Attribute Extract Length and Index */
+
+       /* TSEC Future Expansion Space (0x2_nc00-0x2_nffc) */
+       uint    resc00[256];
+} tsec_t;
+
+#define TSEC_GIGABIT (1)
+
+/* This flag currently only has
+ * meaning if we're using the eTSEC */
+#define TSEC_REDUCED (1 << 1)
+
+struct tsec_private {
+       volatile tsec_t *regs;
+       volatile tsec_t *phyregs;
+       struct phy_info *phyinfo;
+       uint phyaddr;
+       u32 flags;
+       uint link;
+       uint duplexity;
+       uint speed;
+};
+
+
+/*
+ * struct phy_cmd:  A command for reading or writing a PHY register
+ *
+ * mii_reg:  The register to read or write
+ *
+ * mii_data:  For writes, the value to put in the register.
+ *     A value of -1 indicates this is a read.
+ *
+ * funct: A function pointer which is invoked for each command.
+ *     For reads, this function will be passed the value read
+ *     from the PHY, and process it.
+ *     For writes, the result of this function will be written
+ *     to the PHY register
+ */
+struct phy_cmd {
+    uint mii_reg;
+    uint mii_data;
+    uint (*funct) (uint mii_reg, struct tsec_private* priv);
+};
+
+/* struct phy_info: a structure which defines attributes for a PHY
+ *
+ * id will contain a number which represents the PHY.  During
+ * startup, the driver will poll the PHY to find out what its
+ * UID--as defined by registers 2 and 3--is.  The 32-bit result
+ * gotten from the PHY will be shifted right by "shift" bits to
+ * discard any bits which may change based on revision numbers
+ * unimportant to functionality
+ *
+ * The struct phy_cmd entries represent pointers to an arrays of
+ * commands which tell the driver what to do to the PHY.
+ */
+struct phy_info {
+    uint id;
+    char *name;
+    uint shift;
+    /* Called to configure the PHY, and modify the controller
+     * based on the results */
+    struct phy_cmd *config;
+
+    /* Called when starting up the controller */
+    struct phy_cmd *startup;
+
+    /* Called when bringing down the controller */
+    struct phy_cmd *shutdown;
+};
+
+#endif /* __TSEC_H */
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
new file mode 100644 (file)
index 0000000..524e9da
--- /dev/null
@@ -0,0 +1,1036 @@
+/***********************************************************************
+ *
+ * Copyright (c) 2005 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Description:
+ *   Ethernet interface for Tundra TSI108 bridge chip
+ *
+ ***********************************************************************/
+
+#include <config.h>
+
+#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) \
+       && defined(CONFIG_TSI108_ETH)
+
+#if !defined(CONFIG_TSI108_ETH_NUM_PORTS) || (CONFIG_TSI108_ETH_NUM_PORTS > 2)
+#error "CONFIG_TSI108_ETH_NUM_PORTS must be defined as 1 or 2"
+#endif
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/cache.h>
+
+#ifdef DEBUG
+#define TSI108_ETH_DEBUG 7
+#else
+#define TSI108_ETH_DEBUG 0
+#endif
+
+#if TSI108_ETH_DEBUG > 0
+#define debug_lev(lev, fmt, args...) \
+if (lev <= TSI108_ETH_DEBUG) \
+printf ("%s %d: " fmt, __FUNCTION__, __LINE__, ##args)
+#else
+#define debug_lev(lev, fmt, args...) do{}while(0)
+#endif
+
+#define RX_PRINT_ERRORS
+#define TX_PRINT_ERRORS
+
+#define ETH_BASE       (CFG_TSI108_CSR_BASE + 0x6000)
+
+#define ETH_PORT_OFFSET        0x400
+
+#define __REG32(base, offset) (*((volatile u32 *)((char *)(base) + (offset))))
+
+#define reg_MAC_CONFIG_1(base)         __REG32(base, 0x00000000)
+#define MAC_CONFIG_1_TX_ENABLE         (0x00000001)
+#define MAC_CONFIG_1_SYNC_TX_ENABLE    (0x00000002)
+#define MAC_CONFIG_1_RX_ENABLE         (0x00000004)
+#define MAC_CONFIG_1_SYNC_RX_ENABLE    (0x00000008)
+#define MAC_CONFIG_1_TX_FLOW_CONTROL   (0x00000010)
+#define MAC_CONFIG_1_RX_FLOW_CONTROL   (0x00000020)
+#define MAC_CONFIG_1_LOOP_BACK         (0x00000100)
+#define MAC_CONFIG_1_RESET_TX_FUNCTION (0x00010000)
+#define MAC_CONFIG_1_RESET_RX_FUNCTION (0x00020000)
+#define MAC_CONFIG_1_RESET_TX_MAC      (0x00040000)
+#define MAC_CONFIG_1_RESET_RX_MAC      (0x00080000)
+#define MAC_CONFIG_1_SIM_RESET         (0x40000000)
+#define MAC_CONFIG_1_SOFT_RESET                (0x80000000)
+
+#define reg_MAC_CONFIG_2(base)         __REG32(base, 0x00000004)
+#define MAC_CONFIG_2_FULL_DUPLEX       (0x00000001)
+#define MAC_CONFIG_2_CRC_ENABLE                (0x00000002)
+#define MAC_CONFIG_2_PAD_CRC           (0x00000004)
+#define MAC_CONFIG_2_LENGTH_CHECK      (0x00000010)
+#define MAC_CONFIG_2_HUGE_FRAME                (0x00000020)
+#define MAC_CONFIG_2_INTERFACE_MODE(val)       (((val) & 0x3) << 8)
+#define MAC_CONFIG_2_PREAMBLE_LENGTH(val)      (((val) & 0xf) << 12)
+#define INTERFACE_MODE_NIBBLE          1       /* 10/100 Mb/s MII) */
+#define INTERFACE_MODE_BYTE            2       /* 1000 Mb/s GMII/TBI */
+
+#define reg_MAXIMUM_FRAME_LENGTH(base)         __REG32(base, 0x00000010)
+
+#define reg_MII_MGMT_CONFIG(base)              __REG32(base, 0x00000020)
+#define MII_MGMT_CONFIG_MGMT_CLOCK_SELECT(val) ((val) & 0x7)
+#define MII_MGMT_CONFIG_NO_PREAMBLE            (0x00000010)
+#define MII_MGMT_CONFIG_SCAN_INCREMENT         (0x00000020)
+#define MII_MGMT_CONFIG_RESET_MGMT             (0x80000000)
+
+#define reg_MII_MGMT_COMMAND(base)             __REG32(base, 0x00000024)
+#define MII_MGMT_COMMAND_READ_CYCLE            (0x00000001)
+#define MII_MGMT_COMMAND_SCAN_CYCLE            (0x00000002)
+
+#define reg_MII_MGMT_ADDRESS(base)             __REG32(base, 0x00000028)
+#define reg_MII_MGMT_CONTROL(base)             __REG32(base, 0x0000002c)
+#define reg_MII_MGMT_STATUS(base)              __REG32(base, 0x00000030)
+
+#define reg_MII_MGMT_INDICATORS(base)          __REG32(base, 0x00000034)
+#define MII_MGMT_INDICATORS_BUSY               (0x00000001)
+#define MII_MGMT_INDICATORS_SCAN               (0x00000002)
+#define MII_MGMT_INDICATORS_NOT_VALID          (0x00000004)
+
+#define reg_INTERFACE_STATUS(base)             __REG32(base, 0x0000003c)
+#define INTERFACE_STATUS_LINK_FAIL             (0x00000008)
+#define INTERFACE_STATUS_EXCESS_DEFER          (0x00000200)
+
+#define reg_STATION_ADDRESS_1(base)            __REG32(base, 0x00000040)
+#define reg_STATION_ADDRESS_2(base)            __REG32(base, 0x00000044)
+
+#define reg_PORT_CONTROL(base)                 __REG32(base, 0x00000200)
+#define PORT_CONTROL_PRI               (0x00000001)
+#define PORT_CONTROL_BPT               (0x00010000)
+#define PORT_CONTROL_SPD               (0x00040000)
+#define PORT_CONTROL_RBC               (0x00080000)
+#define PORT_CONTROL_PRB               (0x00200000)
+#define PORT_CONTROL_DIS               (0x00400000)
+#define PORT_CONTROL_TBI               (0x00800000)
+#define PORT_CONTROL_STE               (0x10000000)
+#define PORT_CONTROL_ZOR               (0x20000000)
+#define PORT_CONTROL_CLR               (0x40000000)
+#define PORT_CONTROL_SRT               (0x80000000)
+
+#define reg_TX_CONFIG(base)            __REG32(base, 0x00000220)
+#define TX_CONFIG_START_Q              (0x00000003)
+#define TX_CONFIG_EHP                  (0x00400000)
+#define TX_CONFIG_CHP                  (0x00800000)
+#define TX_CONFIG_RST                  (0x80000000)
+
+#define reg_TX_CONTROL(base)           __REG32(base, 0x00000224)
+#define TX_CONTROL_GO                  (0x00008000)
+#define TX_CONTROL_MP                  (0x01000000)
+#define TX_CONTROL_EAI                 (0x20000000)
+#define TX_CONTROL_ABT                 (0x40000000)
+#define TX_CONTROL_EII                 (0x80000000)
+
+#define reg_TX_STATUS(base)            __REG32(base, 0x00000228)
+#define TX_STATUS_QUEUE_USABLE         (0x0000000f)
+#define TX_STATUS_CURR_Q               (0x00000300)
+#define TX_STATUS_ACT                  (0x00008000)
+#define TX_STATUS_QUEUE_IDLE           (0x000f0000)
+#define TX_STATUS_EOQ_PENDING          (0x0f000000)
+
+#define reg_TX_EXTENDED_STATUS(base)           __REG32(base, 0x0000022c)
+#define TX_EXTENDED_STATUS_END_OF_QUEUE_CONDITION              (0x0000000f)
+#define TX_EXTENDED_STATUS_END_OF_FRAME_CONDITION              (0x00000f00)
+#define TX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION      (0x000f0000)
+#define TX_EXTENDED_STATUS_ERROR_FLAG                          (0x0f000000)
+
+#define reg_TX_THRESHOLDS(base)                        __REG32(base, 0x00000230)
+
+#define reg_TX_DIAGNOSTIC_ADDR(base)           __REG32(base, 0x00000270)
+#define TX_DIAGNOSTIC_ADDR_INDEX               (0x0000007f)
+#define TX_DIAGNOSTIC_ADDR_DFR                 (0x40000000)
+#define TX_DIAGNOSTIC_ADDR_AI                  (0x80000000)
+
+#define reg_TX_DIAGNOSTIC_DATA(base)           __REG32(base, 0x00000274)
+
+#define reg_TX_ERROR_STATUS(base)              __REG32(base, 0x00000278)
+#define TX_ERROR_STATUS                                (0x00000278)
+#define TX_ERROR_STATUS_QUEUE_0_ERROR_RESPONSE (0x0000000f)
+#define TX_ERROR_STATUS_TEA_ON_QUEUE_0         (0x00000010)
+#define TX_ERROR_STATUS_RER_ON_QUEUE_0         (0x00000020)
+#define TX_ERROR_STATUS_TER_ON_QUEUE_0         (0x00000040)
+#define TX_ERROR_STATUS_DER_ON_QUEUE_0         (0x00000080)
+#define TX_ERROR_STATUS_QUEUE_1_ERROR_RESPONSE (0x00000f00)
+#define TX_ERROR_STATUS_TEA_ON_QUEUE_1         (0x00001000)
+#define TX_ERROR_STATUS_RER_ON_QUEUE_1         (0x00002000)
+#define TX_ERROR_STATUS_TER_ON_QUEUE_1         (0x00004000)
+#define TX_ERROR_STATUS_DER_ON_QUEUE_1         (0x00008000)
+#define TX_ERROR_STATUS_QUEUE_2_ERROR_RESPONSE (0x000f0000)
+#define TX_ERROR_STATUS_TEA_ON_QUEUE_2         (0x00100000)
+#define TX_ERROR_STATUS_RER_ON_QUEUE_2         (0x00200000)
+#define TX_ERROR_STATUS_TER_ON_QUEUE_2         (0x00400000)
+#define TX_ERROR_STATUS_DER_ON_QUEUE_2         (0x00800000)
+#define TX_ERROR_STATUS_QUEUE_3_ERROR_RESPONSE (0x0f000000)
+#define TX_ERROR_STATUS_TEA_ON_QUEUE_3         (0x10000000)
+#define TX_ERROR_STATUS_RER_ON_QUEUE_3         (0x20000000)
+#define TX_ERROR_STATUS_TER_ON_QUEUE_3         (0x40000000)
+#define TX_ERROR_STATUS_DER_ON_QUEUE_3         (0x80000000)
+
+#define reg_TX_QUEUE_0_CONFIG(base)            __REG32(base, 0x00000280)
+#define TX_QUEUE_0_CONFIG_OCN_PORT             (0x0000003f)
+#define TX_QUEUE_0_CONFIG_BSWP                 (0x00000400)
+#define TX_QUEUE_0_CONFIG_WSWP                 (0x00000800)
+#define TX_QUEUE_0_CONFIG_AM                   (0x00004000)
+#define TX_QUEUE_0_CONFIG_GVI                  (0x00008000)
+#define TX_QUEUE_0_CONFIG_EEI                  (0x00010000)
+#define TX_QUEUE_0_CONFIG_ELI                  (0x00020000)
+#define TX_QUEUE_0_CONFIG_ENI                  (0x00040000)
+#define TX_QUEUE_0_CONFIG_ESI                  (0x00080000)
+#define TX_QUEUE_0_CONFIG_EDI                  (0x00100000)
+
+#define reg_TX_QUEUE_0_BUF_CONFIG(base)                __REG32(base, 0x00000284)
+#define TX_QUEUE_0_BUF_CONFIG_OCN_PORT         (0x0000003f)
+#define TX_QUEUE_0_BUF_CONFIG_BURST            (0x00000300)
+#define TX_QUEUE_0_BUF_CONFIG_BSWP             (0x00000400)
+#define TX_QUEUE_0_BUF_CONFIG_WSWP             (0x00000800)
+
+#define OCN_PORT_HLP                   0       /* HLP Interface */
+#define OCN_PORT_PCI_X                 1       /* PCI-X Interface */
+#define OCN_PORT_PROCESSOR_MASTER      2       /* Processor Interface (master) */
+#define OCN_PORT_PROCESSOR_SLAVE       3       /* Processor Interface (slave) */
+#define OCN_PORT_MEMORY                        4       /* Memory Controller */
+#define OCN_PORT_DMA                   5       /* DMA Controller */
+#define OCN_PORT_ETHERNET              6       /* Ethernet Controller */
+#define OCN_PORT_PRINT                 7       /* Print Engine Interface */
+
+#define reg_TX_QUEUE_0_PTR_LOW(base)           __REG32(base, 0x00000288)
+
+#define reg_TX_QUEUE_0_PTR_HIGH(base)          __REG32(base, 0x0000028c)
+#define TX_QUEUE_0_PTR_HIGH_VALID              (0x80000000)
+
+#define reg_RX_CONFIG(base)                    __REG32(base, 0x00000320)
+#define RX_CONFIG_DEF_Q                                (0x00000003)
+#define RX_CONFIG_EMF                          (0x00000100)
+#define RX_CONFIG_EUF                          (0x00000200)
+#define RX_CONFIG_BFE                          (0x00000400)
+#define RX_CONFIG_MFE                          (0x00000800)
+#define RX_CONFIG_UFE                          (0x00001000)
+#define RX_CONFIG_SE                           (0x00002000)
+#define RX_CONFIG_ABF                          (0x00200000)
+#define RX_CONFIG_APE                          (0x00400000)
+#define RX_CONFIG_CHP                          (0x00800000)
+#define RX_CONFIG_RST                          (0x80000000)
+
+#define reg_RX_CONTROL(base)                   __REG32(base, 0x00000324)
+#define GE_E0_RX_CONTROL_QUEUE_ENABLES         (0x0000000f)
+#define GE_E0_RX_CONTROL_GO                    (0x00008000)
+#define GE_E0_RX_CONTROL_EAI                   (0x20000000)
+#define GE_E0_RX_CONTROL_ABT                   (0x40000000)
+#define GE_E0_RX_CONTROL_EII                   (0x80000000)
+
+#define reg_RX_EXTENDED_STATUS(base)           __REG32(base, 0x0000032c)
+#define RX_EXTENDED_STATUS                     (0x0000032c)
+#define RX_EXTENDED_STATUS_EOQ                 (0x0000000f)
+#define RX_EXTENDED_STATUS_EOQ_0               (0x00000001)
+#define RX_EXTENDED_STATUS_EOF                 (0x00000f00)
+#define RX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION      (0x000f0000)
+#define RX_EXTENDED_STATUS_ERROR_FLAG                          (0x0f000000)
+
+#define reg_RX_THRESHOLDS(base)                        __REG32(base, 0x00000330)
+
+#define reg_RX_DIAGNOSTIC_ADDR(base)           __REG32(base, 0x00000370)
+#define RX_DIAGNOSTIC_ADDR_INDEX               (0x0000007f)
+#define RX_DIAGNOSTIC_ADDR_DFR                 (0x40000000)
+#define RX_DIAGNOSTIC_ADDR_AI                  (0x80000000)
+
+#define reg_RX_DIAGNOSTIC_DATA(base)           __REG32(base, 0x00000374)
+
+#define reg_RX_QUEUE_0_CONFIG(base)            __REG32(base, 0x00000380)
+#define RX_QUEUE_0_CONFIG_OCN_PORT             (0x0000003f)
+#define RX_QUEUE_0_CONFIG_BSWP                 (0x00000400)
+#define RX_QUEUE_0_CONFIG_WSWP                 (0x00000800)
+#define RX_QUEUE_0_CONFIG_AM                   (0x00004000)
+#define RX_QUEUE_0_CONFIG_EEI                  (0x00010000)
+#define RX_QUEUE_0_CONFIG_ELI                  (0x00020000)
+#define RX_QUEUE_0_CONFIG_ENI                  (0x00040000)
+#define RX_QUEUE_0_CONFIG_ESI                  (0x00080000)
+#define RX_QUEUE_0_CONFIG_EDI                  (0x00100000)
+
+#define reg_RX_QUEUE_0_BUF_CONFIG(base)                __REG32(base, 0x00000384)
+#define RX_QUEUE_0_BUF_CONFIG_OCN_PORT         (0x0000003f)
+#define RX_QUEUE_0_BUF_CONFIG_BURST            (0x00000300)
+#define RX_QUEUE_0_BUF_CONFIG_BSWP             (0x00000400)
+#define RX_QUEUE_0_BUF_CONFIG_WSWP             (0x00000800)
+
+#define reg_RX_QUEUE_0_PTR_LOW(base)           __REG32(base, 0x00000388)
+
+#define reg_RX_QUEUE_0_PTR_HIGH(base)          __REG32(base, 0x0000038c)
+#define RX_QUEUE_0_PTR_HIGH_VALID              (0x80000000)
+
+/*
+ *  PHY register definitions
+ */
+/* the first 15 PHY registers are standard. */
+#define PHY_CTRL_REG           0       /* Control Register */
+#define PHY_STATUS_REG         1       /* Status Regiser */
+#define PHY_ID1_REG            2       /* Phy Id Reg (word 1) */
+#define PHY_ID2_REG            3       /* Phy Id Reg (word 2) */
+#define PHY_AN_ADV_REG         4       /* Autoneg Advertisement */
+#define PHY_LP_ABILITY_REG     5       /* Link Partner Ability (Base Page) */
+#define PHY_AUTONEG_EXP_REG    6       /* Autoneg Expansion Reg */
+#define PHY_NEXT_PAGE_TX_REG   7       /* Next Page TX */
+#define PHY_LP_NEXT_PAGE_REG   8       /* Link Partner Next Page */
+#define PHY_1000T_CTRL_REG     9       /* 1000Base-T Control Reg */
+#define PHY_1000T_STATUS_REG   10      /* 1000Base-T Status Reg */
+#define PHY_EXT_STATUS_REG     11      /* Extended Status Reg */
+
+/*
+ * PHY Register bit masks.
+ */
+#define PHY_CTRL_RESET         (1 << 15)
+#define PHY_CTRL_LOOPBACK      (1 << 14)
+#define PHY_CTRL_SPEED0                (1 << 13)
+#define PHY_CTRL_AN_EN         (1 << 12)
+#define PHY_CTRL_PWR_DN                (1 << 11)
+#define PHY_CTRL_ISOLATE       (1 << 10)
+#define PHY_CTRL_RESTART_AN    (1 << 9)
+#define PHY_CTRL_FULL_DUPLEX   (1 << 8)
+#define PHY_CTRL_CT_EN         (1 << 7)
+#define PHY_CTRL_SPEED1                (1 << 6)
+
+#define PHY_STAT_100BASE_T4    (1 << 15)
+#define PHY_STAT_100BASE_X_FD  (1 << 14)
+#define PHY_STAT_100BASE_X_HD  (1 << 13)
+#define PHY_STAT_10BASE_T_FD   (1 << 12)
+#define PHY_STAT_10BASE_T_HD   (1 << 11)
+#define PHY_STAT_100BASE_T2_FD (1 << 10)
+#define PHY_STAT_100BASE_T2_HD (1 << 9)
+#define PHY_STAT_EXT_STAT      (1 << 8)
+#define PHY_STAT_RESERVED      (1 << 7)
+#define PHY_STAT_MFPS          (1 << 6)        /* Management Frames Preamble Suppression */
+#define PHY_STAT_AN_COMPLETE   (1 << 5)
+#define PHY_STAT_REM_FAULT     (1 << 4)
+#define PHY_STAT_AN_CAP                (1 << 3)
+#define PHY_STAT_LINK_UP       (1 << 2)
+#define PHY_STAT_JABBER                (1 << 1)
+#define PHY_STAT_EXT_CAP       (1 << 0)
+
+#define TBI_CONTROL_2                                  0x11
+#define TBI_CONTROL_2_ENABLE_COMMA_DETECT              0x0001
+#define TBI_CONTROL_2_ENABLE_WRAP                      0x0002
+#define TBI_CONTROL_2_G_MII_MODE                       0x0010
+#define TBI_CONTROL_2_RECEIVE_CLOCK_SELECT             0x0020
+#define TBI_CONTROL_2_AUTO_NEGOTIATION_SENSE           0x0100
+#define TBI_CONTROL_2_DISABLE_TRANSMIT_RUNNING_DISPARITY       0x1000
+#define TBI_CONTROL_2_DISABLE_RECEIVE_RUNNING_DISPARITY                0x2000
+#define TBI_CONTROL_2_SHORTCUT_LINK_TIMER                      0x4000
+#define TBI_CONTROL_2_SOFT_RESET                               0x8000
+
+/* marvel specific */
+#define MV1111_EXT_CTRL1_REG   16      /* PHY Specific Control Reg */
+#define MV1111_SPEC_STAT_REG   17      /* PHY Specific Status Reg */
+#define MV1111_EXT_CTRL2_REG   20      /* Extended PHY Specific Control Reg */
+
+/*
+ * MARVELL 88E1111 PHY register bit masks
+ */
+/* PHY Specific Status Register (MV1111_EXT_CTRL1_REG) */
+
+#define SPEC_STAT_SPEED_MASK   (3 << 14)
+#define SPEC_STAT_FULL_DUP     (1 << 13)
+#define SPEC_STAT_PAGE_RCVD    (1 << 12)
+#define SPEC_STAT_RESOLVED     (1 << 11)       /* Speed and Duplex Resolved */
+#define SPEC_STAT_LINK_UP      (1 << 10)
+#define SPEC_STAT_CABLE_LEN_MASK       (7 << 7)/* Cable Length (100/1000 modes only) */
+#define SPEC_STAT_MDIX         (1 << 6)
+#define SPEC_STAT_POLARITY     (1 << 1)
+#define SPEC_STAT_JABBER       (1 << 0)
+
+#define SPEED_1000             (2 << 14)
+#define SPEED_100              (1 << 14)
+#define SPEED_10               (0 << 14)
+
+#define TBI_ADDR       0x1E    /* Ten Bit Interface address */
+
+/* negotiated link parameters */
+#define LINK_SPEED_UNKNOWN     0
+#define LINK_SPEED_10          1
+#define LINK_SPEED_100         2
+#define LINK_SPEED_1000                3
+
+#define LINK_DUPLEX_UNKNOWN    0
+#define LINK_DUPLEX_HALF       1
+#define LINK_DUPLEX_FULL       2
+
+static unsigned int phy_address[] = { 8, 9 };
+
+#define vuint32 volatile u32
+
+/* TX/RX buffer descriptors. MUST be cache line aligned in memory. (32 byte)
+ * This structure is accessed by the ethernet DMA engine which means it
+ * MUST be in LITTLE ENDIAN format */
+struct dma_descriptor {
+       vuint32 start_addr0;    /* buffer address, least significant bytes. */
+       vuint32 start_addr1;    /* buffer address, most significant bytes. */
+       vuint32 next_descr_addr0;/* next descriptor address, least significant bytes.  Must be 64-bit aligned. */
+       vuint32 next_descr_addr1;/* next descriptor address, most significant bytes. */
+       vuint32 vlan_byte_count;/* VLAN tag(top 2 bytes) and byte countt (bottom 2 bytes). */
+       vuint32 config_status;  /* Configuration/Status. */
+       vuint32 reserved1;      /* reserved to make the descriptor cache line aligned. */
+       vuint32 reserved2;      /* reserved to make the descriptor cache line aligned. */
+};
+
+/* last next descriptor address flag */
+#define DMA_DESCR_LAST         (1 << 31)
+
+/* TX DMA descriptor config status bits */
+#define DMA_DESCR_TX_EOF       (1 <<  0)       /* end of frame */
+#define DMA_DESCR_TX_SOF       (1 <<  1)       /* start of frame */
+#define DMA_DESCR_TX_PFVLAN    (1 <<  2)
+#define DMA_DESCR_TX_HUGE      (1 <<  3)
+#define DMA_DESCR_TX_PAD       (1 <<  4)
+#define DMA_DESCR_TX_CRC       (1 <<  5)
+#define DMA_DESCR_TX_DESCR_INT (1 << 14)
+#define DMA_DESCR_TX_RETRY_COUNT       0x000F0000
+#define DMA_DESCR_TX_ONE_COLLISION     (1 << 20)
+#define DMA_DESCR_TX_LATE_COLLISION    (1 << 24)
+#define DMA_DESCR_TX_UNDERRUN          (1 << 25)
+#define DMA_DESCR_TX_RETRY_LIMIT       (1 << 26)
+#define DMA_DESCR_TX_OK                        (1 << 30)
+#define DMA_DESCR_TX_OWNER             (1 << 31)
+
+/* RX DMA descriptor status bits */
+#define DMA_DESCR_RX_EOF               (1 <<  0)
+#define DMA_DESCR_RX_SOF               (1 <<  1)
+#define DMA_DESCR_RX_VTF               (1 <<  2)
+#define DMA_DESCR_RX_FRAME_IS_TYPE     (1 <<  3)
+#define DMA_DESCR_RX_SHORT_FRAME       (1 <<  4)
+#define DMA_DESCR_RX_HASH_MATCH                (1 <<  7)
+#define DMA_DESCR_RX_BAD_FRAME         (1 <<  8)
+#define DMA_DESCR_RX_OVERRUN           (1 <<  9)
+#define DMA_DESCR_RX_MAX_FRAME_LEN     (1 << 11)
+#define DMA_DESCR_RX_CRC_ERROR         (1 << 12)
+#define DMA_DESCR_RX_DESCR_INT         (1 << 13)
+#define DMA_DESCR_RX_OWNER             (1 << 15)
+
+#define RX_BUFFER_SIZE PKTSIZE
+#define NUM_RX_DESC    PKTBUFSRX
+
+static struct dma_descriptor tx_descriptor __attribute__ ((aligned(32)));
+
+static struct dma_descriptor rx_descr_array[NUM_RX_DESC]
+       __attribute__ ((aligned(32)));
+
+static struct dma_descriptor *rx_descr_current;
+
+static int tsi108_eth_probe (struct eth_device *dev, bd_t * bis);
+static int tsi108_eth_send (struct eth_device *dev,
+                          volatile void *packet, int length);
+static int tsi108_eth_recv (struct eth_device *dev);
+static void tsi108_eth_halt (struct eth_device *dev);
+static unsigned int read_phy (unsigned int base,
+                            unsigned int phy_addr, unsigned int phy_reg);
+static void write_phy (unsigned int base,
+                     unsigned int phy_addr,
+                     unsigned int phy_reg, unsigned int phy_data);
+
+#if TSI108_ETH_DEBUG > 100
+/*
+ * print phy debug infomation
+ */
+static void dump_phy_regs (unsigned int phy_addr)
+{
+       int i;
+
+       printf ("PHY %d registers\n", phy_addr);
+       for (i = 0; i <= 30; i++) {
+               printf ("%2d  0x%04x\n", i, read_phy (ETH_BASE, phy_addr, i));
+       }
+       printf ("\n");
+
+}
+#else
+#define dump_phy_regs(base) do{}while(0)
+#endif
+
+#if TSI108_ETH_DEBUG > 100
+/*
+ * print debug infomation
+ */
+static void tx_diag_regs (unsigned int base)
+{
+       int i;
+       unsigned long dummy;
+
+       printf ("TX diagnostics registers\n");
+       reg_TX_DIAGNOSTIC_ADDR(base) = 0x00 | TX_DIAGNOSTIC_ADDR_AI;
+       udelay (1000);
+       dummy = reg_TX_DIAGNOSTIC_DATA(base);
+       for (i = 0x00; i <= 0x05; i++) {
+               udelay (1000);
+               printf ("0x%02x  0x%08x\n", i, reg_TX_DIAGNOSTIC_DATA(base));
+       }
+       reg_TX_DIAGNOSTIC_ADDR(base) = 0x40 | TX_DIAGNOSTIC_ADDR_AI;
+       udelay (1000);
+       dummy = reg_TX_DIAGNOSTIC_DATA(base);
+       for (i = 0x40; i <= 0x47; i++) {
+               udelay (1000);
+               printf ("0x%02x  0x%08x\n", i, reg_TX_DIAGNOSTIC_DATA(base));
+       }
+       printf ("\n");
+
+}
+#else
+#define tx_diag_regs(base) do{}while(0)
+#endif
+
+#if TSI108_ETH_DEBUG > 100
+/*
+ * print debug infomation
+ */
+static void rx_diag_regs (unsigned int base)
+{
+       int i;
+       unsigned long dummy;
+
+       printf ("RX diagnostics registers\n");
+       reg_RX_DIAGNOSTIC_ADDR(base) = 0x00 | RX_DIAGNOSTIC_ADDR_AI;
+       udelay (1000);
+       dummy = reg_RX_DIAGNOSTIC_DATA(base);
+       for (i = 0x00; i <= 0x05; i++) {
+               udelay (1000);
+               printf ("0x%02x  0x%08x\n", i, reg_RX_DIAGNOSTIC_DATA(base));
+       }
+       reg_RX_DIAGNOSTIC_ADDR(base) = 0x40 | RX_DIAGNOSTIC_ADDR_AI;
+       udelay (1000);
+       dummy = reg_RX_DIAGNOSTIC_DATA(base);
+       for (i = 0x08; i <= 0x0a; i++) {
+               udelay (1000);
+               printf ("0x%02x  0x%08x\n", i, reg_RX_DIAGNOSTIC_DATA(base));
+       }
+       printf ("\n");
+
+}
+#else
+#define rx_diag_regs(base) do{}while(0)
+#endif
+
+#if TSI108_ETH_DEBUG > 100
+/*
+ * print debug infomation
+ */
+static void debug_mii_regs (unsigned int base)
+{
+       printf ("MII_MGMT_CONFIG     0x%08x\n", reg_MII_MGMT_CONFIG(base));
+       printf ("MII_MGMT_COMMAND    0x%08x\n", reg_MII_MGMT_COMMAND(base));
+       printf ("MII_MGMT_ADDRESS    0x%08x\n", reg_MII_MGMT_ADDRESS(base));
+       printf ("MII_MGMT_CONTROL    0x%08x\n", reg_MII_MGMT_CONTROL(base));
+       printf ("MII_MGMT_STATUS     0x%08x\n", reg_MII_MGMT_STATUS(base));
+       printf ("MII_MGMT_INDICATORS 0x%08x\n", reg_MII_MGMT_INDICATORS(base));
+       printf ("\n");
+
+}
+#else
+#define debug_mii_regs(base) do{}while(0)
+#endif
+
+/*
+ * Wait until the phy bus is non-busy
+ */
+static void phy_wait (unsigned int base, unsigned int condition)
+{
+       int timeout;
+
+       timeout = 0;
+       while (reg_MII_MGMT_INDICATORS(base) & condition) {
+               udelay (10);
+               if (++timeout > 10000) {
+                       printf ("ERROR: timeout waiting for phy bus (%d)\n",
+                              condition);
+                       break;
+               }
+       }
+}
+
+/*
+ * read phy register
+ */
+static unsigned int read_phy (unsigned int base,
+                            unsigned int phy_addr, unsigned int phy_reg)
+{
+       unsigned int value;
+
+       phy_wait (base, MII_MGMT_INDICATORS_BUSY);
+
+       reg_MII_MGMT_ADDRESS(base) = (phy_addr << 8) | phy_reg;
+
+       /* Ensure that the Read Cycle bit is cleared prior to next read cycle */
+       reg_MII_MGMT_COMMAND(base) = 0;
+
+       /* start the read */
+       reg_MII_MGMT_COMMAND(base) = MII_MGMT_COMMAND_READ_CYCLE;
+
+       /* wait for the read to complete */
+       phy_wait (base,
+                MII_MGMT_INDICATORS_NOT_VALID | MII_MGMT_INDICATORS_BUSY);
+
+       value = reg_MII_MGMT_STATUS(base);
+
+       reg_MII_MGMT_COMMAND(base) = 0;
+
+       return value;
+}
+
+/*
+ * write phy register
+ */
+static void write_phy (unsigned int base,
+                     unsigned int phy_addr,
+                     unsigned int phy_reg, unsigned int phy_data)
+{
+       phy_wait (base, MII_MGMT_INDICATORS_BUSY);
+
+       reg_MII_MGMT_ADDRESS(base) = (phy_addr << 8) | phy_reg;
+
+       /* Ensure that the Read Cycle bit is cleared prior to next cycle */
+       reg_MII_MGMT_COMMAND(base) = 0;
+
+       /* start the write */
+       reg_MII_MGMT_CONTROL(base) = phy_data;
+}
+
+/*
+ * configure the marvell 88e1111 phy
+ */
+static int marvell_88e_phy_config (struct eth_device *dev, int *speed,
+                                 int *duplex)
+{
+       unsigned long base;
+       unsigned long phy_addr;
+       unsigned int phy_status;
+       unsigned int phy_spec_status;
+       int timeout;
+       int phy_speed;
+       int phy_duplex;
+       unsigned int value;
+
+       phy_speed = LINK_SPEED_UNKNOWN;
+       phy_duplex = LINK_DUPLEX_UNKNOWN;
+
+       base = dev->iobase;
+       phy_addr = (unsigned long)dev->priv;
+
+       /* Take the PHY out of reset. */
+       write_phy (ETH_BASE, phy_addr, PHY_CTRL_REG, PHY_CTRL_RESET);
+
+       /* Wait for the reset process to complete. */
+       udelay (10);
+       timeout = 0;
+       while ((phy_status =
+               read_phy (ETH_BASE, phy_addr, PHY_CTRL_REG)) & PHY_CTRL_RESET) {
+               udelay (10);
+               if (++timeout > 10000) {
+                       printf ("ERROR: timeout waiting for phy reset\n");
+                       break;
+               }
+       }
+
+       /* TBI Configuration. */
+       write_phy (base, TBI_ADDR, TBI_CONTROL_2, TBI_CONTROL_2_G_MII_MODE |
+                 TBI_CONTROL_2_RECEIVE_CLOCK_SELECT);
+       /* Wait for the link to be established. */
+       timeout = 0;
+       do {
+               udelay (20000);
+               phy_status = read_phy (ETH_BASE, phy_addr, PHY_STATUS_REG);
+               if (++timeout > 100) {
+                       debug_lev(1, "ERROR: unable to establish link!!!\n");
+                       break;
+               }
+       } while ((phy_status & PHY_STAT_LINK_UP) == 0);
+
+       if ((phy_status & PHY_STAT_LINK_UP) == 0)
+               return 0;
+
+       value = 0;
+       phy_spec_status = read_phy (ETH_BASE, phy_addr, MV1111_SPEC_STAT_REG);
+       if (phy_spec_status & SPEC_STAT_RESOLVED) {
+               switch (phy_spec_status & SPEC_STAT_SPEED_MASK) {
+               case SPEED_1000:
+                       phy_speed = LINK_SPEED_1000;
+                       value |= PHY_CTRL_SPEED1;
+                       break;
+               case SPEED_100:
+                       phy_speed = LINK_SPEED_100;
+                       value |= PHY_CTRL_SPEED0;
+                       break;
+               case SPEED_10:
+                       phy_speed = LINK_SPEED_10;
+                       break;
+               }
+               if (phy_spec_status & SPEC_STAT_FULL_DUP) {
+                       phy_duplex = LINK_DUPLEX_FULL;
+                       value |= PHY_CTRL_FULL_DUPLEX;
+               } else
+                       phy_duplex = LINK_DUPLEX_HALF;
+       }
+       /* set TBI speed */
+       write_phy (base, TBI_ADDR, PHY_CTRL_REG, value);
+       write_phy (base, TBI_ADDR, PHY_AN_ADV_REG, 0x0060);
+
+#if TSI108_ETH_DEBUG > 0
+       printf ("%s link is up", dev->name);
+       phy_spec_status = read_phy (ETH_BASE, phy_addr, MV1111_SPEC_STAT_REG);
+       if (phy_spec_status & SPEC_STAT_RESOLVED) {
+               switch (phy_speed) {
+               case LINK_SPEED_1000:
+                       printf (", 1000 Mbps");
+                       break;
+               case LINK_SPEED_100:
+                       printf (", 100 Mbps");
+                       break;
+               case LINK_SPEED_10:
+                       printf (", 10 Mbps");
+                       break;
+               }
+               if (phy_duplex == LINK_DUPLEX_FULL)
+                       printf (", Full duplex");
+               else
+                       printf (", Half duplex");
+       }
+       printf ("\n");
+#endif
+
+       dump_phy_regs (TBI_ADDR);
+       if (speed)
+               *speed = phy_speed;
+       if (duplex)
+               *duplex = phy_duplex;
+
+       return 1;
+}
+
+/*
+ * External interface
+ *
+ * register the tsi108 ethernet controllers with the multi-ethernet system
+ */
+int tsi108_eth_initialize (bd_t * bis)
+{
+       struct eth_device *dev;
+       int index;
+
+       for (index = 0; index < CONFIG_TSI108_ETH_NUM_PORTS; index++) {
+               dev = (struct eth_device *)malloc(sizeof(struct eth_device));
+
+               sprintf (dev->name, "TSI108_eth%d", index);
+
+               dev->iobase = ETH_BASE + (index * ETH_PORT_OFFSET);
+               dev->priv = (void *)(phy_address[index]);
+               dev->init = tsi108_eth_probe;
+               dev->halt = tsi108_eth_halt;
+               dev->send = tsi108_eth_send;
+               dev->recv = tsi108_eth_recv;
+
+               eth_register(dev);
+       }
+       return index;
+}
+
+/*
+ * probe for and initialize a single ethernet interface
+ */
+static int tsi108_eth_probe (struct eth_device *dev, bd_t * bis)
+{
+       unsigned long base;
+       unsigned long value;
+       int index;
+       struct dma_descriptor *tx_descr;
+       struct dma_descriptor *rx_descr;
+       int speed;
+       int duplex;
+
+       base = dev->iobase;
+
+       reg_PORT_CONTROL(base) = PORT_CONTROL_STE | PORT_CONTROL_BPT;
+
+       /* Bring DMA/FIFO out of reset. */
+       reg_TX_CONFIG(base) = 0x00000000;
+       reg_RX_CONFIG(base) = 0x00000000;
+
+       reg_TX_THRESHOLDS(base) = (192 << 16) | 192;
+       reg_RX_THRESHOLDS(base) = (192 << 16) | 112;
+
+       /* Bring MAC out of reset. */
+       reg_MAC_CONFIG_1(base) = 0x00000000;
+
+       /* DMA MAC configuration. */
+       reg_MAC_CONFIG_1(base) =
+           MAC_CONFIG_1_RX_ENABLE | MAC_CONFIG_1_TX_ENABLE;
+
+       reg_MII_MGMT_CONFIG(base) = MII_MGMT_CONFIG_NO_PREAMBLE;
+       reg_MAXIMUM_FRAME_LENGTH(base) = RX_BUFFER_SIZE;
+
+       /* Note: Early tsi108 manual did not have correct byte order
+        * for the station address.*/
+       reg_STATION_ADDRESS_1(base) = (dev->enetaddr[5] << 24) |
+           (dev->enetaddr[4] << 16) |
+           (dev->enetaddr[3] << 8) | (dev->enetaddr[2] << 0);
+
+       reg_STATION_ADDRESS_2(base) = (dev->enetaddr[1] << 24) |
+           (dev->enetaddr[0] << 16);
+
+       if (marvell_88e_phy_config(dev, &speed, &duplex) == 0)
+               return 0;
+
+       value =
+           MAC_CONFIG_2_PREAMBLE_LENGTH(7) | MAC_CONFIG_2_PAD_CRC |
+           MAC_CONFIG_2_CRC_ENABLE;
+       if (speed == LINK_SPEED_1000)
+               value |= MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_BYTE);
+       else {
+               value |= MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_NIBBLE);
+               reg_PORT_CONTROL(base) |= PORT_CONTROL_SPD;
+       }
+       if (duplex == LINK_DUPLEX_FULL) {
+               value |= MAC_CONFIG_2_FULL_DUPLEX;
+               reg_PORT_CONTROL(base) &= ~PORT_CONTROL_BPT;
+       } else
+               reg_PORT_CONTROL(base) |= PORT_CONTROL_BPT;
+       reg_MAC_CONFIG_2(base) = value;
+
+       reg_RX_CONFIG(base) = RX_CONFIG_SE;
+       reg_RX_QUEUE_0_CONFIG(base) = OCN_PORT_MEMORY;
+       reg_RX_QUEUE_0_BUF_CONFIG(base) = OCN_PORT_MEMORY;
+
+       /* initialize the RX DMA descriptors */
+       rx_descr = &rx_descr_array[0];
+       rx_descr_current = rx_descr;
+       for (index = 0; index < NUM_RX_DESC; index++) {
+               /* make sure the receive buffers are not in cache */
+               invalidate_dcache_range((unsigned long)NetRxPackets[index],
+                                       (unsigned long)NetRxPackets[index] +
+                                       RX_BUFFER_SIZE);
+               rx_descr->start_addr0 =
+                   cpu_to_le32((vuint32) NetRxPackets[index]);
+               rx_descr->start_addr1 = 0;
+               rx_descr->next_descr_addr0 =
+                   cpu_to_le32((vuint32) (rx_descr + 1));
+               rx_descr->next_descr_addr1 = 0;
+               rx_descr->vlan_byte_count = 0;
+               rx_descr->config_status = cpu_to_le32((RX_BUFFER_SIZE << 16) |
+                                                     DMA_DESCR_RX_OWNER);
+               rx_descr++;
+       }
+       rx_descr--;
+       rx_descr->next_descr_addr0 = 0;
+       rx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);
+       /* Push the descriptors to RAM so the ethernet DMA can see them */
+       invalidate_dcache_range((unsigned long)rx_descr_array,
+                               (unsigned long)rx_descr_array +
+                               sizeof(rx_descr_array));
+
+       /* enable RX queue */
+       reg_RX_CONTROL(base) = TX_CONTROL_GO | 0x01;
+       reg_RX_QUEUE_0_PTR_LOW(base) = (u32) rx_descr_current;
+       /* enable receive DMA */
+       reg_RX_QUEUE_0_PTR_HIGH(base) = RX_QUEUE_0_PTR_HIGH_VALID;
+
+       reg_TX_QUEUE_0_CONFIG(base) = OCN_PORT_MEMORY;
+       reg_TX_QUEUE_0_BUF_CONFIG(base) = OCN_PORT_MEMORY;
+
+       /* initialize the TX DMA descriptor */
+       tx_descr = &tx_descriptor;
+
+       tx_descr->start_addr0 = 0;
+       tx_descr->start_addr1 = 0;
+       tx_descr->next_descr_addr0 = 0;
+       tx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);
+       tx_descr->vlan_byte_count = 0;
+       tx_descr->config_status = cpu_to_le32(DMA_DESCR_TX_OK |
+                                             DMA_DESCR_TX_SOF |
+                                             DMA_DESCR_TX_EOF);
+       /* enable TX queue */
+       reg_TX_CONTROL(base) = TX_CONTROL_GO | 0x01;
+
+       return 1;
+}
+
+/*
+ * send a packet
+ */
+static int tsi108_eth_send (struct eth_device *dev,
+                          volatile void *packet, int length)
+{
+       unsigned long base;
+       int timeout;
+       struct dma_descriptor *tx_descr;
+       unsigned long status;
+
+       base = dev->iobase;
+       tx_descr = &tx_descriptor;
+
+       /* Wait until the last packet has been transmitted. */
+       timeout = 0;
+       do {
+               /* make sure we see the changes made by the DMA engine */
+               invalidate_dcache_range((unsigned long)tx_descr,
+                                       (unsigned long)tx_descr +
+                                       sizeof(struct dma_descriptor));
+
+               if (timeout != 0)
+                       udelay (15);
+               if (++timeout > 10000) {
+                       tx_diag_regs(base);
+                       debug_lev(1,
+                                 "ERROR: timeout waiting for last transmit packet to be sent\n");
+                       return 0;
+               }
+       } while (tx_descr->config_status & cpu_to_le32(DMA_DESCR_TX_OWNER));
+
+       status = le32_to_cpu(tx_descr->config_status);
+       if ((status & DMA_DESCR_TX_OK) == 0) {
+#ifdef TX_PRINT_ERRORS
+               printf ("TX packet error: 0x%08x\n    %s%s%s%s\n", status,
+                      status & DMA_DESCR_TX_OK ? "tx error, " : "",
+                      status & DMA_DESCR_TX_RETRY_LIMIT ?
+                      "retry limit reached, " : "",
+                      status & DMA_DESCR_TX_UNDERRUN ? "underrun, " : "",
+                      status & DMA_DESCR_TX_LATE_COLLISION ? "late collision, "
+                      : "");
+#endif
+       }
+
+       debug_lev (9, "sending packet %d\n", length);
+       tx_descr->start_addr0 = cpu_to_le32((vuint32) packet);
+       tx_descr->start_addr1 = 0;
+       tx_descr->next_descr_addr0 = 0;
+       tx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);
+       tx_descr->vlan_byte_count = cpu_to_le32(length);
+       tx_descr->config_status = cpu_to_le32(DMA_DESCR_TX_OWNER |
+                                             DMA_DESCR_TX_CRC |
+                                             DMA_DESCR_TX_PAD |
+                                             DMA_DESCR_TX_SOF |
+                                             DMA_DESCR_TX_EOF);
+
+       invalidate_dcache_range((unsigned long)tx_descr,
+                               (unsigned long)tx_descr +
+                               sizeof(struct dma_descriptor));
+
+       invalidate_dcache_range((unsigned long)packet,
+                               (unsigned long)packet + length);
+
+       reg_TX_QUEUE_0_PTR_LOW(base) = (u32) tx_descr;
+       reg_TX_QUEUE_0_PTR_HIGH(base) = TX_QUEUE_0_PTR_HIGH_VALID;
+
+       return length;
+}
+
+/*
+ * Check for received packets and send them up the protocal stack
+ */
+static int tsi108_eth_recv (struct eth_device *dev)
+{
+       struct dma_descriptor *rx_descr;
+       unsigned long base;
+       int length = 0;
+       unsigned long status;
+       volatile uchar *buffer;
+
+       base = dev->iobase;
+
+       /* make sure we see the changes made by the DMA engine */
+       invalidate_dcache_range ((unsigned long)rx_descr_array,
+                               (unsigned long)rx_descr_array +
+                               sizeof(rx_descr_array));
+
+       /* process all of the received packets */
+       rx_descr = rx_descr_current;
+       while ((rx_descr->config_status & cpu_to_le32(DMA_DESCR_RX_OWNER)) == 0) {
+               /* check for error */
+               status = le32_to_cpu(rx_descr->config_status);
+               if (status & DMA_DESCR_RX_BAD_FRAME) {
+#ifdef RX_PRINT_ERRORS
+                       printf ("RX packet error: 0x%08x\n    %s%s%s%s%s%s\n",
+                              status,
+                              status & DMA_DESCR_RX_FRAME_IS_TYPE ? "too big, "
+                              : "",
+                              status & DMA_DESCR_RX_SHORT_FRAME ? "too short, "
+                              : "",
+                              status & DMA_DESCR_RX_BAD_FRAME ? "bad frame, " :
+                              "",
+                              status & DMA_DESCR_RX_OVERRUN ? "overrun, " : "",
+                              status & DMA_DESCR_RX_MAX_FRAME_LEN ?
+                              "max length, " : "",
+                              status & DMA_DESCR_RX_CRC_ERROR ? "CRC error, " :
+                              "");
+#endif
+               } else {
+                       length =
+                           le32_to_cpu(rx_descr->vlan_byte_count) & 0xFFFF;
+
+                       /*** process packet ***/
+                       buffer =
+                           (volatile uchar
+                            *)(le32_to_cpu (rx_descr->start_addr0));
+                       NetReceive (buffer, length);
+
+                       invalidate_dcache_range ((unsigned long)buffer,
+                                               (unsigned long)buffer +
+                                               RX_BUFFER_SIZE);
+               }
+               /* Give this buffer back to the DMA engine */
+               rx_descr->vlan_byte_count = 0;
+               rx_descr->config_status = cpu_to_le32 ((RX_BUFFER_SIZE << 16) |
+                                                     DMA_DESCR_RX_OWNER);
+               /* move descriptor pointer forward */
+               rx_descr =
+                   (struct dma_descriptor
+                    *)(le32_to_cpu (rx_descr->next_descr_addr0));
+               if (rx_descr == 0)
+                       rx_descr = &rx_descr_array[0];
+       }
+       /* remember where we are for next time */
+       rx_descr_current = rx_descr;
+
+       /* If the DMA engine has reached the end of the queue
+        * start over at the begining */
+       if (reg_RX_EXTENDED_STATUS(base) & RX_EXTENDED_STATUS_EOQ_0) {
+
+               reg_RX_EXTENDED_STATUS(base) = RX_EXTENDED_STATUS_EOQ_0;
+               reg_RX_QUEUE_0_PTR_LOW(base) = (u32) & rx_descr_array[0];
+               reg_RX_QUEUE_0_PTR_HIGH(base) = RX_QUEUE_0_PTR_HIGH_VALID;
+       }
+
+       return length;
+}
+
+/*
+ * disable an ethernet interface
+ */
+static void tsi108_eth_halt (struct eth_device *dev)
+{
+       unsigned long base;
+
+       base = dev->iobase;
+
+       /* Put DMA/FIFO into reset state. */
+       reg_TX_CONFIG(base) = TX_CONFIG_RST;
+       reg_RX_CONFIG(base) = RX_CONFIG_RST;
+
+       /* Put MAC into reset state. */
+       reg_MAC_CONFIG_1(base) = MAC_CONFIG_1_SOFT_RESET;
+}
+
+#endif
diff --git a/drivers/net/uli526x.c b/drivers/net/uli526x.c
new file mode 100644 (file)
index 0000000..1267c57
--- /dev/null
@@ -0,0 +1,996 @@
+/*
+ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Roy Zang <tie-fei.zang@freescale.com>, Sep, 2007
+ *
+ * Description:
+ * ULI 526x Ethernet port driver.
+ * Based on the Linux driver: drivers/net/tulip/uli526x.c
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of  the GNU General  Public License as published by
+ * the Free Software Foundation;  either version 2 of the  License, or
+ * (at your option) any later version.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <pci.h>
+#include <miiphy.h>
+
+/* some kernel function compatible define */
+
+#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
+       defined(CONFIG_ULI526X)
+
+#undef DEBUG
+
+/* Board/System/Debug information/definition */
+#define ULI_VENDOR_ID          0x10B9
+#define ULI5261_DEVICE_ID      0x5261
+#define ULI5263_DEVICE_ID      0x5263
+/* ULi M5261 ID*/
+#define PCI_ULI5261_ID         ULI5261_DEVICE_ID << 16 | ULI_VENDOR_ID
+/* ULi M5263 ID*/
+#define PCI_ULI5263_ID         ULI5263_DEVICE_ID << 16 | ULI_VENDOR_ID
+
+#define ULI526X_IO_SIZE        0x100
+#define TX_DESC_CNT    0x10            /* Allocated Tx descriptors */
+#define RX_DESC_CNT    PKTBUFSRX       /* Allocated Rx descriptors */
+#define TX_FREE_DESC_CNT       (TX_DESC_CNT - 2) /* Max TX packet count */
+#define TX_WAKE_DESC_CNT       (TX_DESC_CNT - 3) /* TX wakeup count */
+#define DESC_ALL_CNT           (TX_DESC_CNT + RX_DESC_CNT)
+#define TX_BUF_ALLOC           0x300
+#define RX_ALLOC_SIZE          PKTSIZE
+#define ULI526X_RESET          1
+#define CR0_DEFAULT            0
+#define CR6_DEFAULT            0x22200000
+#define CR7_DEFAULT            0x180c1
+#define CR15_DEFAULT           0x06            /* TxJabber RxWatchdog */
+#define TDES0_ERR_MASK         0x4302          /* TXJT, LC, EC, FUE */
+#define MAX_PACKET_SIZE                1514
+#define ULI5261_MAX_MULTICAST  14
+#define RX_COPY_SIZE           100
+#define MAX_CHECK_PACKET       0x8000
+
+#define ULI526X_10MHF          0
+#define ULI526X_100MHF         1
+#define ULI526X_10MFD          4
+#define ULI526X_100MFD         5
+#define ULI526X_AUTO           8
+
+#define ULI526X_TXTH_72                0x400000        /* TX TH 72 byte */
+#define ULI526X_TXTH_96                0x404000        /* TX TH 96 byte */
+#define ULI526X_TXTH_128       0x0000          /* TX TH 128 byte */
+#define ULI526X_TXTH_256       0x4000          /* TX TH 256 byte */
+#define ULI526X_TXTH_512       0x8000          /* TX TH 512 byte */
+#define ULI526X_TXTH_1K                0xC000          /* TX TH 1K  byte */
+
+/* CR9 definition: SROM/MII */
+#define CR9_SROM_READ          0x4800
+#define CR9_SRCS               0x1
+#define CR9_SRCLK              0x2
+#define CR9_CRDOUT             0x8
+#define SROM_DATA_0            0x0
+#define SROM_DATA_1            0x4
+#define PHY_DATA_1             0x20000
+#define PHY_DATA_0             0x00000
+#define MDCLKH                 0x10000
+
+#define PHY_POWER_DOWN 0x800
+
+#define SROM_V41_CODE          0x14
+
+#define SROM_CLK_WRITE(data, ioaddr) do {                      \
+       outl(data|CR9_SROM_READ|CR9_SRCS, ioaddr);              \
+       udelay(5);                                              \
+       outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK, ioaddr);    \
+       udelay(5);                                              \
+       outl(data|CR9_SROM_READ|CR9_SRCS, ioaddr);              \
+       udelay(5);                                              \
+       } while (0)
+
+/* Structure/enum declaration */
+
+struct tx_desc {
+       u32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */
+       char *tx_buf_ptr;               /* Data for us */
+       struct tx_desc *next_tx_desc;
+};
+
+struct rx_desc {
+       u32 rdes0, rdes1, rdes2, rdes3; /* Data for the card */
+       char *rx_buf_ptr;               /* Data for us */
+       struct rx_desc *next_rx_desc;
+};
+
+struct uli526x_board_info {
+       u32 chip_id;    /* Chip vendor/Device ID */
+       pci_dev_t pdev;
+
+       long ioaddr;                    /* I/O base address */
+       u32 cr0_data;
+       u32 cr5_data;
+       u32 cr6_data;
+       u32 cr7_data;
+       u32 cr15_data;
+
+       /* pointer for memory physical address */
+       dma_addr_t buf_pool_dma_ptr;    /* Tx buffer pool memory */
+       dma_addr_t buf_pool_dma_start;  /* Tx buffer pool align dword */
+       dma_addr_t desc_pool_dma_ptr;   /* descriptor pool memory */
+       dma_addr_t first_tx_desc_dma;
+       dma_addr_t first_rx_desc_dma;
+
+       /* descriptor pointer */
+       unsigned char *buf_pool_ptr;    /* Tx buffer pool memory */
+       unsigned char *buf_pool_start;  /* Tx buffer pool align dword */
+       unsigned char *desc_pool_ptr;   /* descriptor pool memory */
+       struct tx_desc *first_tx_desc;
+       struct tx_desc *tx_insert_ptr;
+       struct tx_desc *tx_remove_ptr;
+       struct rx_desc *first_rx_desc;
+       struct rx_desc *rx_ready_ptr;   /* packet come pointer */
+       unsigned long tx_packet_cnt;    /* transmitted packet count */
+
+       u16 PHY_reg4;                   /* Saved Phyxcer register 4 value */
+
+       u8 media_mode;                  /* user specify media mode */
+       u8 op_mode;                     /* real work dedia mode */
+       u8 phy_addr;
+
+       /* NIC SROM data */
+       unsigned char srom[128];
+};
+
+enum uli526x_offsets {
+       DCR0 = 0x00, DCR1 = 0x08, DCR2 = 0x10, DCR3 = 0x18, DCR4 = 0x20,
+       DCR5 = 0x28, DCR6 = 0x30, DCR7 = 0x38, DCR8 = 0x40, DCR9 = 0x48,
+       DCR10 = 0x50, DCR11 = 0x58, DCR12 = 0x60, DCR13 = 0x68, DCR14 = 0x70,
+       DCR15 = 0x78
+};
+
+enum uli526x_CR6_bits {
+       CR6_RXSC = 0x2, CR6_PBF = 0x8, CR6_PM = 0x40, CR6_PAM = 0x80,
+       CR6_FDM = 0x200, CR6_TXSC = 0x2000, CR6_STI = 0x100000,
+       CR6_SFT = 0x200000, CR6_RXA = 0x40000000, CR6_NO_PURGE = 0x20000000
+};
+
+/* Global variable declaration -- */
+
+static unsigned char uli526x_media_mode = ULI526X_AUTO;
+
+static struct tx_desc desc_pool_array[DESC_ALL_CNT + 0x20]
+       __attribute__ ((aligned(32)));
+static char buf_pool[TX_BUF_ALLOC * TX_DESC_CNT + 4];
+
+/* For module input parameter */
+static int mode = 8;
+
+/* function declaration -- */
+static int uli526x_start_xmit(struct eth_device *dev,
+                               volatile void *packet, int length);
+static const struct ethtool_ops netdev_ethtool_ops;
+static u16 read_srom_word(long, int);
+static void uli526x_descriptor_init(struct uli526x_board_info *, unsigned long);
+static void allocate_rx_buffer(struct uli526x_board_info *);
+static void update_cr6(u32, unsigned long);
+static u16 phy_read(unsigned long, u8, u8, u32);
+static u16 phy_readby_cr10(unsigned long, u8, u8);
+static void phy_write(unsigned long, u8, u8, u16, u32);
+static void phy_writeby_cr10(unsigned long, u8, u8, u16);
+static void phy_write_1bit(unsigned long, u32, u32);
+static u16 phy_read_1bit(unsigned long, u32);
+static int uli526x_rx_packet(struct eth_device *);
+static void uli526x_free_tx_pkt(struct eth_device *,
+               struct uli526x_board_info *);
+static void uli526x_reuse_buf(struct rx_desc *);
+static void uli526x_init(struct eth_device *);
+static void uli526x_set_phyxcer(struct uli526x_board_info *);
+
+
+static int uli526x_init_one(struct eth_device *, bd_t *);
+static void uli526x_disable(struct eth_device *);
+static void set_mac_addr(struct eth_device *);
+
+static struct pci_device_id uli526x_pci_tbl[] = {
+       { ULI_VENDOR_ID, ULI5261_DEVICE_ID}, /* 5261 device */
+       { ULI_VENDOR_ID, ULI5263_DEVICE_ID}, /* 5263 device */
+       {}
+};
+
+/* ULI526X network board routine */
+
+/*
+ *     Search ULI526X board, register it
+ */
+
+int uli526x_initialize(bd_t *bis)
+{
+       pci_dev_t devno;
+       int card_number = 0;
+       struct eth_device *dev;
+       struct uli526x_board_info *db;  /* board information structure */
+
+       u32 iobase;
+       int idx = 0;
+
+       while (1) {
+               /* Find PCI device */
+               devno = pci_find_devices(uli526x_pci_tbl, idx++);
+               if (devno < 0)
+                       break;
+
+               pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase);
+               iobase &= ~0xf;
+
+               dev = (struct eth_device *)malloc(sizeof *dev);
+               sprintf(dev->name, "uli526x#%d\n", card_number);
+               db = (struct uli526x_board_info *)
+                       malloc(sizeof(struct uli526x_board_info));
+
+               dev->priv = db;
+               db->pdev = devno;
+               dev->iobase = iobase;
+
+               dev->init = uli526x_init_one;
+               dev->halt = uli526x_disable;
+               dev->send = uli526x_start_xmit;
+               dev->recv = uli526x_rx_packet;
+
+               /* init db */
+               db->ioaddr = dev->iobase;
+               /* get chip id */
+
+               pci_read_config_dword(devno, PCI_VENDOR_ID, &db->chip_id);
+#ifdef DEBUG
+               printf("uli526x: uli526x @0x%x\n", iobase);
+               printf("uli526x: chip_id%x\n", db->chip_id);
+#endif
+               eth_register(dev);
+               card_number++;
+               pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20);
+               udelay(10 * 1000);
+       }
+       return card_number;
+}
+
+static int uli526x_init_one(struct eth_device *dev, bd_t *bis)
+{
+
+       struct uli526x_board_info *db = dev->priv;
+       int i;
+
+       switch (mode) {
+       case ULI526X_10MHF:
+       case ULI526X_100MHF:
+       case ULI526X_10MFD:
+       case ULI526X_100MFD:
+               uli526x_media_mode = mode;
+               break;
+       default:
+               uli526x_media_mode = ULI526X_AUTO;
+               break;
+       }
+
+       /* Allocate Tx/Rx descriptor memory */
+       db->desc_pool_ptr = (uchar *)&desc_pool_array[0];
+       db->desc_pool_dma_ptr = (dma_addr_t)&desc_pool_array[0];
+       if (db->desc_pool_ptr == NULL)
+               return 0;
+
+       db->buf_pool_ptr = &buf_pool[0];
+       db->buf_pool_dma_ptr = (dma_addr_t)&buf_pool[0];
+       if (db->buf_pool_ptr == NULL)
+               return 0;
+
+       db->first_tx_desc = (struct tx_desc *) db->desc_pool_ptr;
+       db->first_tx_desc_dma = db->desc_pool_dma_ptr;
+
+       db->buf_pool_start = db->buf_pool_ptr;
+       db->buf_pool_dma_start = db->buf_pool_dma_ptr;
+
+#ifdef DEBUG
+       printf("%s(): db->ioaddr= 0x%x\n",
+               __FUNCTION__, db->ioaddr);
+       printf("%s(): media_mode= 0x%x\n",
+               __FUNCTION__, uli526x_media_mode);
+       printf("%s(): db->desc_pool_ptr= 0x%x\n",
+               __FUNCTION__, db->desc_pool_ptr);
+       printf("%s(): db->desc_pool_dma_ptr= 0x%x\n",
+               __FUNCTION__, db->desc_pool_dma_ptr);
+       printf("%s(): db->buf_pool_ptr= 0x%x\n",
+               __FUNCTION__, db->buf_pool_ptr);
+       printf("%s(): db->buf_pool_dma_ptr= 0x%x\n",
+               __FUNCTION__, db->buf_pool_dma_ptr);
+#endif
+
+       /* read 64 word srom data */
+       for (i = 0; i < 64; i++)
+               ((u16 *) db->srom)[i] = cpu_to_le16(read_srom_word(db->ioaddr,
+                       i));
+
+       /* Set Node address */
+       if (((u16 *) db->srom)[0] == 0xffff || ((u16 *) db->srom)[0] == 0)
+       /* SROM absent, so write MAC address to ID Table */
+               set_mac_addr(dev);
+       else {          /*Exist SROM*/
+               for (i = 0; i < 6; i++)
+                       dev->enetaddr[i] = db->srom[20 + i];
+       }
+#ifdef DEBUG
+       for (i = 0; i < 6; i++)
+               printf("%c%02x", i ? ':' : ' ', dev->enetaddr[i]);
+#endif
+       db->PHY_reg4 = 0x1e0;
+
+       /* system variable init */
+       db->cr6_data = CR6_DEFAULT ;
+       db->cr6_data |= ULI526X_TXTH_256;
+       db->cr0_data = CR0_DEFAULT;
+       uli526x_init(dev);
+       return 1;
+}
+
+static void uli526x_disable(struct eth_device *dev)
+{
+#ifdef DEBUG
+       printf("uli526x_disable\n");
+#endif
+       struct uli526x_board_info *db = dev->priv;
+
+       if (!((inl(db->ioaddr + DCR12)) & 0x8)) {
+               /* Reset & stop ULI526X board */
+               outl(ULI526X_RESET, db->ioaddr + DCR0);
+               udelay(5);
+               phy_write(db->ioaddr, db->phy_addr, 0, 0x8000, db->chip_id);
+
+               /* reset the board */
+               db->cr6_data &= ~(CR6_RXSC | CR6_TXSC); /* Disable Tx/Rx */
+               update_cr6(db->cr6_data, dev->iobase);
+               outl(0, dev->iobase + DCR7);            /* Disable Interrupt */
+               outl(inl(dev->iobase + DCR5), dev->iobase + DCR5);
+       }
+}
+
+/*     Initialize ULI526X board
+ *     Reset ULI526X board
+ *     Initialize TX/Rx descriptor chain structure
+ *     Send the set-up frame
+ *     Enable Tx/Rx machine
+ */
+
+static void uli526x_init(struct eth_device *dev)
+{
+
+       struct uli526x_board_info *db = dev->priv;
+       u8      phy_tmp;
+       u16     phy_value;
+       u16 phy_reg_reset;
+
+       /* Reset M526x MAC controller */
+       outl(ULI526X_RESET, db->ioaddr + DCR0); /* RESET MAC */
+       udelay(100);
+       outl(db->cr0_data, db->ioaddr + DCR0);
+       udelay(5);
+
+       /* Phy addr : In some boards,M5261/M5263 phy address != 1 */
+       db->phy_addr = 1;
+       db->tx_packet_cnt = 0;
+       for (phy_tmp = 0; phy_tmp < 32; phy_tmp++) {
+               /* peer add */
+               phy_value = phy_read(db->ioaddr, phy_tmp, 3, db->chip_id);
+               if (phy_value != 0xffff && phy_value != 0) {
+                       db->phy_addr = phy_tmp;
+                       break;
+               }
+       }
+
+#ifdef DEBUG
+       printf("%s(): db->ioaddr= 0x%x\n", __FUNCTION__, db->ioaddr);
+       printf("%s(): db->phy_addr= 0x%x\n", __FUNCTION__, db->phy_addr);
+#endif
+       if (phy_tmp == 32)
+               printf("Can not find the phy address!!!");
+
+       /* Parser SROM and media mode */
+       db->media_mode = uli526x_media_mode;
+
+       if (!(inl(db->ioaddr + DCR12) & 0x8)) {
+               /* Phyxcer capability setting */
+               phy_reg_reset = phy_read(db->ioaddr,
+                       db->phy_addr, 0, db->chip_id);
+               phy_reg_reset = (phy_reg_reset | 0x8000);
+               phy_write(db->ioaddr, db->phy_addr, 0,
+                       phy_reg_reset, db->chip_id);
+               udelay(500);
+
+               /* Process Phyxcer Media Mode */
+               uli526x_set_phyxcer(db);
+       }
+       /* Media Mode Process */
+       if (!(db->media_mode & ULI526X_AUTO))
+               db->op_mode = db->media_mode;   /* Force Mode */
+
+       /* Initialize Transmit/Receive decriptor and CR3/4 */
+       uli526x_descriptor_init(db, db->ioaddr);
+
+       /* Init CR6 to program M526X operation */
+       update_cr6(db->cr6_data, db->ioaddr);
+
+       /* Init CR7, interrupt active bit */
+       db->cr7_data = CR7_DEFAULT;
+       outl(db->cr7_data, db->ioaddr + DCR7);
+
+       /* Init CR15, Tx jabber and Rx watchdog timer */
+       outl(db->cr15_data, db->ioaddr + DCR15);
+
+       /* Enable ULI526X Tx/Rx function */
+       db->cr6_data |= CR6_RXSC | CR6_TXSC;
+       update_cr6(db->cr6_data, db->ioaddr);
+       while (!(inl(db->ioaddr + DCR12) & 0x8))
+               udelay(10);
+}
+
+/*
+ *     Hardware start transmission.
+ *     Send a packet to media from the upper layer.
+ */
+
+static int uli526x_start_xmit(struct eth_device *dev,
+                               volatile void *packet, int length)
+{
+       struct uli526x_board_info *db = dev->priv;
+       struct tx_desc *txptr;
+       unsigned int len = length;
+       /* Too large packet check */
+       if (len > MAX_PACKET_SIZE) {
+               printf(": big packet = %d\n", len);
+               return 0;
+       }
+
+       /* No Tx resource check, it never happen nromally */
+       if (db->tx_packet_cnt >= TX_FREE_DESC_CNT) {
+               printf("No Tx resource %ld\n", db->tx_packet_cnt);
+               return 0;
+       }
+
+       /* Disable NIC interrupt */
+       outl(0, dev->iobase + DCR7);
+
+       /* transmit this packet */
+       txptr = db->tx_insert_ptr;
+       memcpy((char *)txptr->tx_buf_ptr, (char *)packet, (int)length);
+       txptr->tdes1 = cpu_to_le32(0xe1000000 | length);
+
+       /* Point to next transmit free descriptor */
+       db->tx_insert_ptr = txptr->next_tx_desc;
+
+       /* Transmit Packet Process */
+       if ((db->tx_packet_cnt < TX_DESC_CNT)) {
+               txptr->tdes0 = cpu_to_le32(0x80000000); /* Set owner bit */
+               db->tx_packet_cnt++;                    /* Ready to send */
+               outl(0x1, dev->iobase + DCR1);  /* Issue Tx polling */
+       }
+
+       /* Got ULI526X status */
+       db->cr5_data = inl(db->ioaddr + DCR5);
+       outl(db->cr5_data, db->ioaddr + DCR5);
+
+#ifdef TX_DEBUG
+       printf("%s(): length = 0x%x\n", __FUNCTION__, length);
+       printf("%s(): cr5_data=%x\n", __FUNCTION__, db->cr5_data);
+#endif
+
+       outl(db->cr7_data, dev->iobase + DCR7);
+       uli526x_free_tx_pkt(dev, db);
+
+       return length;
+}
+
+/*
+ *     Free TX resource after TX complete
+ */
+
+static void uli526x_free_tx_pkt(struct eth_device *dev,
+       struct uli526x_board_info *db)
+{
+       struct tx_desc *txptr;
+       u32 tdes0;
+
+       txptr = db->tx_remove_ptr;
+       while (db->tx_packet_cnt) {
+               tdes0 = le32_to_cpu(txptr->tdes0);
+               /* printf(DRV_NAME ": tdes0=%x\n", tdes0); */
+               if (tdes0 & 0x80000000)
+                       break;
+
+               /* A packet sent completed */
+               db->tx_packet_cnt--;
+
+               if (tdes0 != 0x7fffffff) {
+#ifdef TX_DEBUG
+                       printf("%s()tdes0=%x\n", __FUNCTION__, tdes0);
+#endif
+                       if (tdes0 & TDES0_ERR_MASK) {
+                               if (tdes0 & 0x0002) {   /* UnderRun */
+                                       if (!(db->cr6_data & CR6_SFT)) {
+                                               db->cr6_data = db->cr6_data |
+                                                       CR6_SFT;
+                                               update_cr6(db->cr6_data,
+                                                       db->ioaddr);
+                                       }
+                               }
+                       }
+               }
+
+               txptr = txptr->next_tx_desc;
+       }/* End of while */
+
+       /* Update TX remove pointer to next */
+       db->tx_remove_ptr = txptr;
+}
+
+
+/*
+ *     Receive the come packet and pass to upper layer
+ */
+
+static int uli526x_rx_packet(struct eth_device *dev)
+{
+       struct uli526x_board_info *db = dev->priv;
+       struct rx_desc *rxptr;
+       int rxlen = 0;
+       u32 rdes0;
+
+       rxptr = db->rx_ready_ptr;
+
+       rdes0 = le32_to_cpu(rxptr->rdes0);
+#ifdef RX_DEBUG
+       printf("%s(): rxptr->rdes0=%x:%x\n", __FUNCTION__, rxptr->rdes0);
+#endif
+       if (!(rdes0 & 0x80000000)) {    /* packet owner check */
+               if ((rdes0 & 0x300) != 0x300) {
+                       /* A packet without First/Last flag */
+                       /* reuse this buf */
+                       printf("A packet without First/Last flag");
+                       uli526x_reuse_buf(rxptr);
+               } else {
+                       /* A packet with First/Last flag */
+                       rxlen = ((rdes0 >> 16) & 0x3fff) - 4;
+#ifdef RX_DEBUG
+                       printf("%s(): rxlen =%x\n", __FUNCTION__, rxlen);
+#endif
+                       /* error summary bit check */
+                       if (rdes0 & 0x8000) {
+                               /* This is a error packet */
+                               printf("Eroor: rdes0: %lx\n", rdes0);
+                       }
+
+                       if (!(rdes0 & 0x8000) ||
+                               ((db->cr6_data & CR6_PM) && (rxlen > 6))) {
+
+#ifdef RX_DEBUG
+                               printf("%s(): rx_skb_ptr =%x\n",
+                                       __FUNCTION__, rxptr->rx_buf_ptr);
+                               printf("%s(): rxlen =%x\n",
+                                       __FUNCTION__, rxlen);
+
+                               printf("%s(): buf addr =%x\n",
+                                       __FUNCTION__, rxptr->rx_buf_ptr);
+                               printf("%s(): rxlen =%x\n",
+                                       __FUNCTION__, rxlen);
+                               int i;
+                               for (i = 0; i < 0x20; i++)
+                                       printf("%s(): data[%x] =%x\n",
+                                       __FUNCTION__, i, rxptr->rx_buf_ptr[i]);
+#endif
+
+                               NetReceive(rxptr->rx_buf_ptr, rxlen);
+                               uli526x_reuse_buf(rxptr);
+
+                       } else {
+                               /* Reuse SKB buffer when the packet is error */
+                               printf("Reuse buffer, rdes0");
+                               uli526x_reuse_buf(rxptr);
+                       }
+               }
+
+               rxptr = rxptr->next_rx_desc;
+       }
+
+       db->rx_ready_ptr = rxptr;
+       return rxlen;
+}
+
+/*
+ *     Reuse the RX buffer
+ */
+
+static void uli526x_reuse_buf(struct rx_desc *rxptr)
+{
+
+       if (!(rxptr->rdes0 & cpu_to_le32(0x80000000)))
+               rxptr->rdes0 = cpu_to_le32(0x80000000);
+       else
+               printf("Buffer reuse method error");
+}
+/*
+ *     Initialize transmit/Receive descriptor
+ *     Using Chain structure, and allocate Tx/Rx buffer
+ */
+
+static void uli526x_descriptor_init(struct uli526x_board_info *db,
+       unsigned long ioaddr)
+{
+       struct tx_desc *tmp_tx;
+       struct rx_desc *tmp_rx;
+       unsigned char *tmp_buf;
+       dma_addr_t tmp_tx_dma, tmp_rx_dma;
+       dma_addr_t tmp_buf_dma;
+       int i;
+       /* tx descriptor start pointer */
+       db->tx_insert_ptr = db->first_tx_desc;
+       db->tx_remove_ptr = db->first_tx_desc;
+
+       outl(db->first_tx_desc_dma, ioaddr + DCR4);     /* TX DESC address */
+
+       /* rx descriptor start pointer */
+       db->first_rx_desc = (void *)db->first_tx_desc +
+               sizeof(struct tx_desc) * TX_DESC_CNT;
+       db->first_rx_desc_dma =  db->first_tx_desc_dma +
+               sizeof(struct tx_desc) * TX_DESC_CNT;
+       db->rx_ready_ptr = db->first_rx_desc;
+       outl(db->first_rx_desc_dma, ioaddr + DCR3);     /* RX DESC address */
+#ifdef DEBUG
+       printf("%s(): db->first_tx_desc= 0x%x\n",
+               __FUNCTION__, db->first_tx_desc);
+       printf("%s(): db->first_rx_desc_dma= 0x%x\n",
+               __FUNCTION__, db->first_rx_desc_dma);
+#endif
+       /* Init Transmit chain */
+       tmp_buf = db->buf_pool_start;
+       tmp_buf_dma = db->buf_pool_dma_start;
+       tmp_tx_dma = db->first_tx_desc_dma;
+       for (tmp_tx = db->first_tx_desc, i = 0;
+                       i < TX_DESC_CNT; i++, tmp_tx++) {
+               tmp_tx->tx_buf_ptr = tmp_buf;
+               tmp_tx->tdes0 = cpu_to_le32(0);
+               tmp_tx->tdes1 = cpu_to_le32(0x81000000);        /* IC, chain */
+               tmp_tx->tdes2 = cpu_to_le32(tmp_buf_dma);
+               tmp_tx_dma += sizeof(struct tx_desc);
+               tmp_tx->tdes3 = cpu_to_le32(tmp_tx_dma);
+               tmp_tx->next_tx_desc = tmp_tx + 1;
+               tmp_buf = tmp_buf + TX_BUF_ALLOC;
+               tmp_buf_dma = tmp_buf_dma + TX_BUF_ALLOC;
+       }
+       (--tmp_tx)->tdes3 = cpu_to_le32(db->first_tx_desc_dma);
+       tmp_tx->next_tx_desc = db->first_tx_desc;
+
+        /* Init Receive descriptor chain */
+       tmp_rx_dma = db->first_rx_desc_dma;
+       for (tmp_rx = db->first_rx_desc, i = 0; i < RX_DESC_CNT;
+                       i++, tmp_rx++) {
+               tmp_rx->rdes0 = cpu_to_le32(0);
+               tmp_rx->rdes1 = cpu_to_le32(0x01000600);
+               tmp_rx_dma += sizeof(struct rx_desc);
+               tmp_rx->rdes3 = cpu_to_le32(tmp_rx_dma);
+               tmp_rx->next_rx_desc = tmp_rx + 1;
+       }
+       (--tmp_rx)->rdes3 = cpu_to_le32(db->first_rx_desc_dma);
+       tmp_rx->next_rx_desc = db->first_rx_desc;
+
+       /* pre-allocate Rx buffer */
+       allocate_rx_buffer(db);
+}
+
+/*
+ *     Update CR6 value
+ *     Firstly stop ULI526X, then written value and start
+ */
+
+static void update_cr6(u32 cr6_data, unsigned long ioaddr)
+{
+
+       outl(cr6_data, ioaddr + DCR6);
+       udelay(5);
+}
+
+/*
+ *     Allocate rx buffer,
+ */
+
+static void allocate_rx_buffer(struct uli526x_board_info *db)
+{
+       int index;
+       struct rx_desc *rxptr;
+       rxptr = db->first_rx_desc;
+       u32 addr;
+
+       for (index = 0; index < RX_DESC_CNT; index++) {
+               addr = (u32)NetRxPackets[index];
+               addr += (16 - (addr & 15));
+               rxptr->rx_buf_ptr = (char *) addr;
+               rxptr->rdes2 = cpu_to_le32(addr);
+               rxptr->rdes0 = cpu_to_le32(0x80000000);
+#ifdef DEBUG
+               printf("%s(): Number 0x%x:\n", __FUNCTION__, index);
+               printf("%s(): addr 0x%x:\n", __FUNCTION__, addr);
+               printf("%s(): rxptr address = 0x%x\n", __FUNCTION__, rxptr);
+               printf("%s(): rxptr buf address = 0x%x\n", \
+                       __FUNCTION__, rxptr->rx_buf_ptr);
+               printf("%s(): rdes2  = 0x%x\n", __FUNCTION__, rxptr->rdes2);
+#endif
+               rxptr = rxptr->next_rx_desc;
+       }
+}
+
+/*
+ *     Read one word data from the serial ROM
+ */
+
+static u16 read_srom_word(long ioaddr, int offset)
+{
+       int i;
+       u16 srom_data = 0;
+       long cr9_ioaddr = ioaddr + DCR9;
+
+       outl(CR9_SROM_READ, cr9_ioaddr);
+       outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
+
+       /* Send the Read Command 110b */
+       SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);
+       SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);
+       SROM_CLK_WRITE(SROM_DATA_0, cr9_ioaddr);
+
+       /* Send the offset */
+       for (i = 5; i >= 0; i--) {
+               srom_data = (offset & (1 << i)) ? SROM_DATA_1 : SROM_DATA_0;
+               SROM_CLK_WRITE(srom_data, cr9_ioaddr);
+       }
+
+       outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
+
+       for (i = 16; i > 0; i--) {
+               outl(CR9_SROM_READ | CR9_SRCS | CR9_SRCLK, cr9_ioaddr);
+               udelay(5);
+               srom_data = (srom_data << 1) | ((inl(cr9_ioaddr) & CR9_CRDOUT)
+                       ? 1 : 0);
+               outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
+               udelay(5);
+       }
+
+       outl(CR9_SROM_READ, cr9_ioaddr);
+       return srom_data;
+}
+
+/*
+ *     Set 10/100 phyxcer capability
+ *     AUTO mode : phyxcer register4 is NIC capability
+ *     Force mode: phyxcer register4 is the force media
+ */
+
+static void uli526x_set_phyxcer(struct uli526x_board_info *db)
+{
+       u16 phy_reg;
+
+       /* Phyxcer capability setting */
+       phy_reg = phy_read(db->ioaddr, db->phy_addr, 4, db->chip_id) & ~0x01e0;
+
+       if (db->media_mode & ULI526X_AUTO) {
+               /* AUTO Mode */
+               phy_reg |= db->PHY_reg4;
+       } else {
+               /* Force Mode */
+               switch (db->media_mode) {
+               case ULI526X_10MHF: phy_reg |= 0x20; break;
+               case ULI526X_10MFD: phy_reg |= 0x40; break;
+               case ULI526X_100MHF: phy_reg |= 0x80; break;
+               case ULI526X_100MFD: phy_reg |= 0x100; break;
+               }
+
+       }
+
+       /* Write new capability to Phyxcer Reg4 */
+       if (!(phy_reg & 0x01e0)) {
+               phy_reg |= db->PHY_reg4;
+               db->media_mode |= ULI526X_AUTO;
+       }
+       phy_write(db->ioaddr, db->phy_addr, 4, phy_reg, db->chip_id);
+
+       /* Restart Auto-Negotiation */
+       phy_write(db->ioaddr, db->phy_addr, 0, 0x1200, db->chip_id);
+       udelay(50);
+}
+
+/*
+ *     Write a word to Phy register
+ */
+
+static void phy_write(unsigned long iobase, u8 phy_addr, u8 offset,
+       u16 phy_data, u32 chip_id)
+{
+       u16 i;
+       unsigned long ioaddr;
+
+       if (chip_id == PCI_ULI5263_ID) {
+               phy_writeby_cr10(iobase, phy_addr, offset, phy_data);
+               return;
+       }
+       /* M5261/M5263 Chip */
+       ioaddr = iobase + DCR9;
+
+       /* Send 33 synchronization clock to Phy controller */
+       for (i = 0; i < 35; i++)
+               phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+
+       /* Send start command(01) to Phy */
+       phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
+       phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+
+       /* Send write command(01) to Phy */
+       phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
+       phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+
+       /* Send Phy address */
+       for (i = 0x10; i > 0; i = i >> 1)
+               phy_write_1bit(ioaddr, phy_addr & i ?
+                       PHY_DATA_1 : PHY_DATA_0, chip_id);
+
+       /* Send register address */
+       for (i = 0x10; i > 0; i = i >> 1)
+               phy_write_1bit(ioaddr, offset & i ?
+                       PHY_DATA_1 : PHY_DATA_0, chip_id);
+
+       /* written trasnition */
+       phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+       phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
+
+       /* Write a word data to PHY controller */
+       for (i = 0x8000; i > 0; i >>= 1)
+               phy_write_1bit(ioaddr, phy_data & i ?
+                       PHY_DATA_1 : PHY_DATA_0, chip_id);
+}
+
+/*
+ *     Read a word data from phy register
+ */
+
+static u16 phy_read(unsigned long iobase, u8 phy_addr, u8 offset, u32 chip_id)
+{
+       int i;
+       u16 phy_data;
+       unsigned long ioaddr;
+
+       if (chip_id == PCI_ULI5263_ID)
+               return phy_readby_cr10(iobase, phy_addr, offset);
+       /* M5261/M5263 Chip */
+       ioaddr = iobase + DCR9;
+
+       /* Send 33 synchronization clock to Phy controller */
+       for (i = 0; i < 35; i++)
+               phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+
+       /* Send start command(01) to Phy */
+       phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
+       phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+
+       /* Send read command(10) to Phy */
+       phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+       phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
+
+       /* Send Phy address */
+       for (i = 0x10; i > 0; i = i >> 1)
+               phy_write_1bit(ioaddr, phy_addr & i ?
+                       PHY_DATA_1 : PHY_DATA_0, chip_id);
+
+       /* Send register address */
+       for (i = 0x10; i > 0; i = i >> 1)
+               phy_write_1bit(ioaddr, offset & i ?
+                       PHY_DATA_1 : PHY_DATA_0, chip_id);
+
+       /* Skip transition state */
+       phy_read_1bit(ioaddr, chip_id);
+
+       /* read 16bit data */
+       for (phy_data = 0, i = 0; i < 16; i++) {
+               phy_data <<= 1;
+               phy_data |= phy_read_1bit(ioaddr, chip_id);
+       }
+
+       return phy_data;
+}
+
+static u16 phy_readby_cr10(unsigned long iobase, u8 phy_addr, u8 offset)
+{
+       unsigned long ioaddr, cr10_value;
+
+       ioaddr = iobase + DCR10;
+       cr10_value = phy_addr;
+       cr10_value = (cr10_value<<5) + offset;
+       cr10_value = (cr10_value<<16) + 0x08000000;
+       outl(cr10_value, ioaddr);
+       udelay(1);
+       while (1) {
+               cr10_value = inl(ioaddr);
+               if (cr10_value & 0x10000000)
+                       break;
+       }
+       return (cr10_value&0x0ffff);
+}
+
+static void phy_writeby_cr10(unsigned long iobase, u8 phy_addr,
+       u8 offset, u16 phy_data)
+{
+       unsigned long ioaddr, cr10_value;
+
+       ioaddr = iobase + DCR10;
+       cr10_value = phy_addr;
+       cr10_value = (cr10_value<<5) + offset;
+       cr10_value = (cr10_value<<16) + 0x04000000 + phy_data;
+       outl(cr10_value, ioaddr);
+       udelay(1);
+}
+/*
+ *     Write one bit data to Phy Controller
+ */
+
+static void phy_write_1bit(unsigned long ioaddr, u32 phy_data, u32 chip_id)
+{
+       outl(phy_data , ioaddr);                        /* MII Clock Low */
+       udelay(1);
+       outl(phy_data  | MDCLKH, ioaddr);       /* MII Clock High */
+       udelay(1);
+       outl(phy_data , ioaddr);                        /* MII Clock Low */
+       udelay(1);
+}
+
+/*
+ *     Read one bit phy data from PHY controller
+ */
+
+static u16 phy_read_1bit(unsigned long ioaddr, u32 chip_id)
+{
+       u16 phy_data;
+
+       outl(0x50000 , ioaddr);
+       udelay(1);
+       phy_data = (inl(ioaddr) >> 19) & 0x1;
+       outl(0x40000 , ioaddr);
+       udelay(1);
+
+       return phy_data;
+}
+
+/*
+ * Set MAC address to ID Table
+ */
+
+static void set_mac_addr(struct eth_device *dev)
+{
+       int i;
+       u16 addr;
+       struct uli526x_board_info *db = dev->priv;
+       outl(0x10000, db->ioaddr + DCR0);       /* Diagnosis mode */
+       /* Reset dianostic pointer port */
+       outl(0x1c0, db->ioaddr + DCR13);
+       outl(0, db->ioaddr + DCR14);    /* Clear reset port */
+       outl(0x10, db->ioaddr + DCR14); /* Reset ID Table pointer */
+       outl(0, db->ioaddr + DCR14);    /* Clear reset port */
+       outl(0, db->ioaddr + DCR13);    /* Clear CR13 */
+       /* Select ID Table access port */
+       outl(0x1b0, db->ioaddr + DCR13);
+       /* Read MAC address from CR14 */
+       for (i = 0; i < 3; i++) {
+               addr = dev->enetaddr[2 * i] | (dev->enetaddr[2 * i + 1] << 8);
+               outl(addr, db->ioaddr + DCR14);
+       }
+       /* write end */
+       outl(0, db->ioaddr + DCR13);    /* Clear CR13 */
+       outl(0, db->ioaddr + DCR0);     /* Clear CR0 */
+       udelay(10);
+       return;
+}
+#endif
diff --git a/drivers/netarm_eth.c b/drivers/netarm_eth.c
deleted file mode 100644 (file)
index a99ee5d..0000000
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (C) 2004 IMMS gGmbH <www.imms.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * author(s): Thomas Elste, <info@elste.org>
- *            (some parts derived from uCLinux Netarm Ethernet Driver)
- */
-
-
-#include <common.h>
-
-#ifdef CONFIG_DRIVER_NETARMETH
-#include <command.h>
-#include <net.h>
-#include "netarm_eth.h"
-#include <asm/arch/netarm_registers.h>
-
-
-#if defined(CONFIG_CMD_NET)
-
-static int na_mii_poll_busy (void);
-
-static void na_get_mac_addr (void)
-{
-       unsigned short p[3];
-       char *m_addr;
-       char ethaddr[20];
-
-       m_addr = (char *) p;
-
-       p[0] = (unsigned short) GET_EADDR (NETARM_ETH_SAL_STATION_ADDR_1);
-       p[1] = (unsigned short) GET_EADDR (NETARM_ETH_SAL_STATION_ADDR_2);
-       p[2] = (unsigned short) GET_EADDR (NETARM_ETH_SAL_STATION_ADDR_3);
-
-       sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
-                m_addr[0], m_addr[1],
-                m_addr[2], m_addr[3], m_addr[4], m_addr[5]);
-
-       printf ("HW-MAC Address:  %s\n", ethaddr);
-
-       /* set env, todo: check if already an adress is set */
-       setenv ("ethaddr", ethaddr);
-}
-
-
-static void na_mii_write (int reg, int value)
-{
-       int mii_addr;
-
-       /* Select register */
-       mii_addr = CFG_ETH_PHY_ADDR + reg;
-       SET_EADDR (NETARM_ETH_MII_ADDR, mii_addr);
-       /* Write value */
-       SET_EADDR (NETARM_ETH_MII_WRITE, value);
-       na_mii_poll_busy ();
-}
-
-static unsigned int na_mii_read (int reg)
-{
-       int mii_addr, val;
-
-       /* Select register */
-       mii_addr = CFG_ETH_PHY_ADDR + reg;
-       SET_EADDR (NETARM_ETH_MII_ADDR, mii_addr);
-       /* do one management cycle */
-       SET_EADDR (NETARM_ETH_MII_CMD,
-                  GET_EADDR (NETARM_ETH_MII_CMD) | NETARM_ETH_MIIC_RSTAT);
-       na_mii_poll_busy ();
-       /* Return read value */
-       val = GET_EADDR (NETARM_ETH_MII_READ);
-       return val;
-}
-
-static int na_mii_poll_busy (void)
-{
-       /* arm simple, non interrupt dependent timer */
-       reset_timer_masked ();
-       while (get_timer_masked () < NA_MII_POLL_BUSY_DELAY) {
-               if (!(GET_EADDR (NETARM_ETH_MII_IND) & NETARM_ETH_MIII_BUSY)) {
-                       return 1;
-               }
-       }
-       printf ("na_mii_busy timeout\n");
-       return (0);
-}
-
-static int na_mii_identify_phy (void)
-{
-       int id_reg_a = 0;
-
-       /* get phy id register */
-       id_reg_a = na_mii_read (MII_PHY_ID);
-
-       if (id_reg_a == 0x0043) {
-               /* This must be an Enable or a Lucent LU3X31 PHY chip */
-               return 1;
-       } else if (id_reg_a == 0x0013) {
-               /* it is an Intel LXT971A */
-               return 1;
-       }
-       return (0);
-}
-
-static int na_mii_negotiate (void)
-{
-       int i = 0;
-
-       /* Enable auto-negotiation */
-       na_mii_write (MII_PHY_AUTONEGADV, 0x01e1);
-       /* FIXME: 0x01E1 is 100Mb half and full duplex, 0x0061 is 10Mb only */
-       /* Restart auto-negotiation */
-       na_mii_write (MII_PHY_CONTROL, 0x1200);
-
-       /* status register is 0xffff after setting the autoneg restart bit */
-       while (na_mii_read (MII_PHY_STATUS) == 0xffff) {
-               i++;
-       }
-
-       /* na_mii_read uses the timer already, so we can't use it again for
-          timeout checking.
-          Instead we just try some times.
-        */
-       for (i = 0; i < 40000; i++) {
-               if ((na_mii_read (MII_PHY_STATUS) & 0x0024) == 0x0024) {
-                       return 0;
-               }
-       }
-       /*
-          printf("*Warning* autonegotiation timeout, status: 0x%x\n",na_mii_read(MII_PHY_STATUS));
-        */
-       return (1);
-}
-
-static unsigned int na_mii_check_speed (void)
-{
-       unsigned int status;
-
-       /* Read Status register */
-       status = na_mii_read (MII_PHY_STATUS);
-       /* Check link status.  If 0, default to 100 Mbps. */
-       if ((status & 0x0004) == 0) {
-               printf ("*Warning* no link detected, set default speed to 100Mbs\n");
-               return 1;
-       } else {
-               if ((na_mii_read (17) & 0x4000) != 0) {
-                       printf ("100Mbs link detected\n");
-                       return 1;
-               } else {
-                       printf ("10Mbs link detected\n");
-                       return 0;
-               }
-       }
-       return 0;
-}
-
-static int reset_eth (void)
-{
-       int pt;
-
-       na_get_mac_addr ();
-       pt = na_mii_identify_phy ();
-
-       /* reset the phy */
-       na_mii_write (MII_PHY_CONTROL, 0x8000);
-       reset_timer_masked ();
-       while (get_timer_masked () < NA_MII_NEGOTIATE_DELAY) {
-               if ((na_mii_read (MII_PHY_STATUS) & 0x8000) == 0) {
-                       break;
-               }
-       }
-       if (get_timer_masked () >= NA_MII_NEGOTIATE_DELAY)
-               printf ("phy reset timeout\n");
-
-       /* set the PCS reg */
-       SET_EADDR (NETARM_ETH_PCS_CFG, NETARM_ETH_PCSC_CLKS_25M |
-                  NETARM_ETH_PCSC_ENJAB | NETARM_ETH_PCSC_NOCFR);
-
-       na_mii_negotiate ();
-       na_mii_check_speed ();
-
-       /* Delay 10 millisecond.  (Maybe this should be 1 second.) */
-       udelay (10000);
-
-       /* Turn receive on.
-          Enable statistics register autozero on read.
-          Do not insert MAC address on transmit.
-          Do not enable special test modes.  */
-       SET_EADDR (NETARM_ETH_STL_CFG,
-                  (NETARM_ETH_STLC_AUTOZ | NETARM_ETH_STLC_RXEN));
-
-       /* Set the inter-packet gap delay to 0.96us for MII.
-          The NET+ARM H/W Reference Guide indicates that the Back-to-back IPG
-          Gap Timer Register should be set to 0x15 and the Non Back-to-back IPG
-          Gap Timer Register should be set to 0x00000C12 for the MII PHY. */
-       SET_EADDR (NETARM_ETH_B2B_IPG_GAP_TMR, 0x15);
-       SET_EADDR (NETARM_ETH_NB2B_IPG_GAP_TMR, 0x00000C12);
-
-       /* Add CRC to end of packets.
-          Pad packets to minimum length of 64 bytes.
-          Allow unlimited length transmit packets.
-          Receive all broadcast packets.
-          NOTE:  Multicast addressing is NOT enabled here currently. */
-       SET_EADDR (NETARM_ETH_MAC_CFG,
-                  (NETARM_ETH_MACC_CRCEN |
-                   NETARM_ETH_MACC_PADEN | NETARM_ETH_MACC_HUGEN));
-       SET_EADDR (NETARM_ETH_SAL_FILTER, NETARM_ETH_SALF_BROAD);
-
-       /* enable fifos */
-       SET_EADDR (NETARM_ETH_GEN_CTRL,
-                  (NETARM_ETH_GCR_ERX | NETARM_ETH_GCR_ETX));
-
-       return (0);
-}
-
-
-extern int eth_init (bd_t * bd)
-{
-       reset_eth ();
-       return 0;
-}
-
-extern void eth_halt (void)
-{
-       SET_EADDR (NETARM_ETH_GEN_CTRL, 0);
-}
-
-/* Get a data block via Ethernet */
-extern int eth_rx (void)
-{
-       int i;
-       unsigned short rxlen;
-       unsigned int *addr;
-       unsigned int rxstatus, lastrxlen;
-       char *pa;
-
-       /* RXBR is 1, data block was received */
-       if ((GET_EADDR (NETARM_ETH_GEN_STAT) & NETARM_ETH_GST_RXBR) == 0)
-               return 0;
-
-       /* get status register and the length of received block */
-       rxstatus = GET_EADDR (NETARM_ETH_RX_STAT);
-       rxlen = (rxstatus & NETARM_ETH_RXSTAT_SIZE) >> 16;
-
-       if (rxlen == 0)
-               return 0;
-
-       /* clear RXBR to make fifo available */
-       SET_EADDR (NETARM_ETH_GEN_STAT,
-                  GET_EADDR (NETARM_ETH_GEN_STAT) & ~NETARM_ETH_GST_RXBR);
-
-       /* clear TXBC to make fifo available */
-       /* According to NETARM50 data manual you just have to clear
-          RXBR but that has no effect. Only after clearing TXBC the
-          Fifo becomes readable. */
-       SET_EADDR (NETARM_ETH_GEN_STAT,
-                  GET_EADDR (NETARM_ETH_GEN_STAT) & ~NETARM_ETH_GST_TXBC);
-
-       addr = (unsigned int *) NetRxPackets[0];
-       pa = (char *) NetRxPackets[0];
-
-       /* read the fifo */
-       for (i = 0; i < rxlen / 4; i++) {
-               *addr = GET_EADDR (NETARM_ETH_FIFO_DAT1);
-               addr++;
-       }
-
-       if (GET_EADDR (NETARM_ETH_GEN_STAT) & NETARM_ETH_GST_RXREGR) {
-               /* RXFDB indicates wether the last word is 1,2,3 or 4 bytes long */
-               lastrxlen =
-                       (GET_EADDR (NETARM_ETH_GEN_STAT) &
-                        NETARM_ETH_GST_RXFDB) >> 28;
-               *addr = GET_EADDR (NETARM_ETH_FIFO_DAT1);
-               switch (lastrxlen) {
-               case 1:
-                       *addr &= 0xff000000;
-                       break;
-               case 2:
-                       *addr &= 0xffff0000;
-                       break;
-               case 3:
-                       *addr &= 0xffffff00;
-                       break;
-               }
-       }
-
-       /* Pass the packet up to the protocol layers. */
-       NetReceive (NetRxPackets[0], rxlen);
-
-       return rxlen;
-}
-
-/* Send a data block via Ethernet. */
-extern int eth_send (volatile void *packet, int length)
-{
-       int i, length32;
-       char *pa;
-       unsigned int *pa32, lastp = 0, rest;
-
-       pa = (char *) packet;
-       pa32 = (unsigned int *) packet;
-       length32 = length / 4;
-       rest = length % 4;
-
-       /* make sure there's no garbage in the last word */
-       switch (rest) {
-       case 0:
-               lastp = pa32[length32];
-               length32--;
-               break;
-       case 1:
-               lastp = pa32[length32] & 0x000000ff;
-               break;
-       case 2:
-               lastp = pa32[length32] & 0x0000ffff;
-               break;
-       case 3:
-               lastp = pa32[length32] & 0x00ffffff;
-               break;
-       }
-
-       /* write to the fifo */
-       for (i = 0; i < length32; i++)
-               SET_EADDR (NETARM_ETH_FIFO_DAT1, pa32[i]);
-
-       /* the last word is written to an extra register, this
-          starts the transmission */
-       SET_EADDR (NETARM_ETH_FIFO_DAT2, lastp);
-
-       /* NETARM_ETH_TXSTAT_TXOK should be checked, to know if the transmission
-          went fine. But we can't use the timer for a timeout loop because
-          of it is used already in upper layers. So we just try some times. */
-       i = 0;
-       while (i < 50000) {
-               if ((GET_EADDR (NETARM_ETH_TX_STAT) & NETARM_ETH_TXSTAT_TXOK)
-                   == NETARM_ETH_TXSTAT_TXOK)
-                       return 0;
-               i++;
-       }
-
-       printf ("eth_send timeout\n");
-       return 1;
-}
-
-#endif /* COMMANDS & CFG_NET */
-
-#endif /* CONFIG_DRIVER_NETARMETH */
diff --git a/drivers/netarm_eth.h b/drivers/netarm_eth.h
deleted file mode 100644 (file)
index 8edab82..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2003 IMMS gGmbH <www.imms.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * author(s): Thomas Elste, <info@elste.org>
- */
-
-#include <asm/types.h>
-#include <config.h>
-
-#ifdef CONFIG_DRIVER_NETARMETH
-
-#define SET_EADDR(ad,val) *(volatile unsigned int*)(ad + NETARM_ETH_MODULE_BASE) = val
-#define GET_EADDR(ad) (*(volatile unsigned int*)(ad + NETARM_ETH_MODULE_BASE))
-
-#define NA_MII_POLL_BUSY_DELAY 900
-
-/* MII negotiation timeout value
-   500 jiffies = 5 seconds */
-#define NA_MII_NEGOTIATE_DELAY 30
-
-/* Registers in the physical layer chip */
-#define MII_PHY_CONTROL                0
-#define MII_PHY_STATUS         1
-#define MII_PHY_ID              2
-#define MII_PHY_AUTONEGADV     4
-
-#endif /* CONFIG_DRIVER_NETARMETH */
diff --git a/drivers/netconsole.c b/drivers/netconsole.c
deleted file mode 100644 (file)
index 69089f9..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * (C) Copyright 2004
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-
-#ifdef CONFIG_NETCONSOLE
-
-#include <command.h>
-#include <devices.h>
-#include <net.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-static char input_buffer[512];
-static int input_size = 0;             /* char count in input buffer */
-static int input_offset = 0;           /* offset to valid chars in input buffer */
-static int input_recursion = 0;
-static int output_recursion = 0;
-static int net_timeout;
-static uchar nc_ether[6];              /* server enet address */
-static IPaddr_t nc_ip;                 /* server ip */
-static short nc_port;                  /* source/target port */
-static const char *output_packet;      /* used by first send udp */
-static int output_packet_len = 0;
-
-static void nc_wait_arp_handler (uchar * pkt, unsigned dest, unsigned src,
-                                unsigned len)
-{
-       NetState = NETLOOP_SUCCESS;     /* got arp reply - quit net loop */
-}
-
-static void nc_handler (uchar * pkt, unsigned dest, unsigned src,
-                       unsigned len)
-{
-       if (input_size)
-               NetState = NETLOOP_SUCCESS;     /* got input - quit net loop */
-}
-
-static void nc_timeout (void)
-{
-       NetState = NETLOOP_SUCCESS;
-}
-
-void NcStart (void)
-{
-       if (!output_packet_len || memcmp (nc_ether, NetEtherNullAddr, 6)) {
-               /* going to check for input packet */
-               NetSetHandler (nc_handler);
-               NetSetTimeout (net_timeout, nc_timeout);
-       } else {
-               /* send arp request */
-               uchar *pkt;
-               NetSetHandler (nc_wait_arp_handler);
-               pkt = (uchar *) NetTxPacket + NetEthHdrSize () + IP_HDR_SIZE;
-               memcpy (pkt, output_packet, output_packet_len);
-               NetSendUDPPacket (nc_ether, nc_ip, nc_port, nc_port, output_packet_len);
-       }
-}
-
-int nc_input_packet (uchar * pkt, unsigned dest, unsigned src, unsigned len)
-{
-       int end, chunk;
-
-       if (dest != nc_port || !len)
-               return 0;               /* not for us */
-
-       if (input_size == sizeof input_buffer)
-               return 1;               /* no space */
-       if (len > sizeof input_buffer - input_size)
-               len = sizeof input_buffer - input_size;
-
-       end = input_offset + input_size;
-       if (end > sizeof input_buffer)
-               end -= sizeof input_buffer;
-
-       chunk = len;
-       if (end + len > sizeof input_buffer) {
-               chunk = sizeof input_buffer - end;
-               memcpy(input_buffer, pkt + chunk, len - chunk);
-       }
-       memcpy (input_buffer + end, pkt, chunk);
-
-       input_size += len;
-
-       return 1;
-}
-
-static void nc_send_packet (const char *buf, int len)
-{
-       struct eth_device *eth;
-       int inited = 0;
-       uchar *pkt;
-       uchar *ether;
-       IPaddr_t ip;
-
-       if ((eth = eth_get_dev ()) == NULL) {
-               return;
-       }
-
-       if (!memcmp (nc_ether, NetEtherNullAddr, 6)) {
-               if (eth->state == ETH_STATE_ACTIVE)
-                       return; /* inside net loop */
-               output_packet = buf;
-               output_packet_len = len;
-               NetLoop (NETCONS);      /* wait for arp reply and send packet */
-               output_packet_len = 0;
-               return;
-       }
-
-       if (eth->state != ETH_STATE_ACTIVE) {
-               if (eth_init (gd->bd) < 0)
-                       return;
-               inited = 1;
-       }
-       pkt = (uchar *) NetTxPacket + NetEthHdrSize () + IP_HDR_SIZE;
-       memcpy (pkt, buf, len);
-       ether = nc_ether;
-       ip = nc_ip;
-       NetSendUDPPacket (ether, ip, nc_port, nc_port, len);
-
-       if (inited)
-               eth_halt ();
-}
-
-int nc_start (void)
-{
-       int netmask, our_ip;
-
-       nc_port = 6666;         /* default port */
-
-       if (getenv ("ncip")) {
-               char *p;
-
-               nc_ip = getenv_IPaddr ("ncip");
-               if (!nc_ip)
-                       return -1;      /* ncip is 0.0.0.0 */
-               if ((p = strchr (getenv ("ncip"), ':')) != NULL)
-                       nc_port = simple_strtoul (p + 1, NULL, 10);
-       } else
-               nc_ip = ~0;             /* ncip is not set */
-
-       our_ip = getenv_IPaddr ("ipaddr");
-       netmask = getenv_IPaddr ("netmask");
-
-       if (nc_ip == ~0 ||                              /* 255.255.255.255 */
-           ((netmask & our_ip) == (netmask & nc_ip) && /* on the same net */
-           (netmask | nc_ip) == ~0))                   /* broadcast to our net */
-               memset (nc_ether, 0xff, sizeof nc_ether);
-       else
-               memset (nc_ether, 0, sizeof nc_ether);  /* force arp request */
-
-       return 0;
-}
-
-void nc_putc (char c)
-{
-       if (output_recursion)
-               return;
-       output_recursion = 1;
-
-       nc_send_packet (&c, 1);
-
-       output_recursion = 0;
-}
-
-void nc_puts (const char *s)
-{
-       int len;
-
-       if (output_recursion)
-               return;
-       output_recursion = 1;
-
-       if ((len = strlen (s)) > 512)
-               len = 512;
-
-       nc_send_packet (s, len);
-
-       output_recursion = 0;
-}
-
-int nc_getc (void)
-{
-       uchar c;
-
-       input_recursion = 1;
-
-       net_timeout = 0;        /* no timeout */
-       while (!input_size)
-               NetLoop (NETCONS);
-
-       input_recursion = 0;
-
-       c = input_buffer[input_offset++];
-
-       if (input_offset >= sizeof input_buffer)
-               input_offset -= sizeof input_buffer;
-       input_size--;
-
-       return c;
-}
-
-int nc_tstc (void)
-{
-       struct eth_device *eth;
-
-       if (input_recursion)
-               return 0;
-
-       if (input_size)
-               return 1;
-
-       eth = eth_get_dev ();
-       if (eth && eth->state == ETH_STATE_ACTIVE)
-               return 0;       /* inside net loop */
-
-       input_recursion = 1;
-
-       net_timeout = 1;
-       NetLoop (NETCONS);      /* kind of poll */
-
-       input_recursion = 0;
-
-       return input_size != 0;
-}
-
-int drv_nc_init (void)
-{
-       device_t dev;
-       int rc;
-
-       memset (&dev, 0, sizeof (dev));
-
-       strcpy (dev.name, "nc");
-       dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
-       dev.start = nc_start;
-       dev.putc = nc_putc;
-       dev.puts = nc_puts;
-       dev.getc = nc_getc;
-       dev.tstc = nc_tstc;
-
-       rc = device_register (&dev);
-
-       return (rc == 0) ? 1 : rc;
-}
-
-#endif /* CONFIG_NETCONSOLE */
diff --git a/drivers/nicext.h b/drivers/nicext.h
deleted file mode 100644 (file)
index 4074972..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/****************************************************************************
- * Copyright(c) 2000-2001 Broadcom Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- *
- * Name:        nicext.h
- *
- * Description: Broadcom Network Interface Card Extension (NICE) is an
- *              extension to Linux NET device kernel mode drivers.
- *              NICE is designed to provide additional functionalities,
- *              such as receive packet intercept. To support Broadcom NICE,
- *              the network device driver can be modified by adding an
- *              device ioctl handler and by indicating receiving packets
- *              to the NICE receive handler. Broadcom NICE will only be
- *              enabled by a NICE-aware intermediate driver, such as
- *              Broadcom Advanced Server Program Driver (BASP). When NICE
- *              is not enabled, the modified network device drivers
- *              functions exactly as other non-NICE aware drivers.
- *
- * Author:      Frankie Fan
- *
- * Created:     September 17, 2000
- *
- ****************************************************************************/
-#ifndef _nicext_h_
-#define _nicext_h_
-
-/*
- * ioctl for NICE
- */
-#define SIOCNICE                       SIOCDEVPRIVATE+7
-
-/*
- * SIOCNICE:
- *
- * The following structure needs to be less than IFNAMSIZ (16 bytes) because
- * we're overloading ifreq.ifr_ifru.
- *
- * If 16 bytes is not enough, we should consider relaxing this because
- * this is no field after ifr_ifru in the ifreq structure. But we may
- * run into future compatiability problem in case of changing struct ifreq.
- */
-struct nice_req
-{
-    __u32 cmd;
-
-    union
-    {
-#ifdef __KERNEL__
-       /* cmd = NICE_CMD_SET_RX or NICE_CMD_GET_RX */
-       struct
-       {
-           void (*nrqus1_rx)( struct sk_buff*, void* );
-           void* nrqus1_ctx;
-       } nrqu_nrqus1;
-
-       /* cmd = NICE_CMD_QUERY_SUPPORT */
-       struct
-       {
-           __u32 nrqus2_magic;
-           __u32 nrqus2_support_rx:1;
-           __u32 nrqus2_support_vlan:1;
-           __u32 nrqus2_support_get_speed:1;
-       } nrqu_nrqus2;
-#endif
-
-       /* cmd = NICE_CMD_GET_SPEED */
-       struct
-       {
-           unsigned int nrqus3_speed; /* 0 if link is down, */
-                                      /* otherwise speed in Mbps */
-       } nrqu_nrqus3;
-
-       /* cmd = NICE_CMD_BLINK_LED */
-       struct
-       {
-           unsigned int nrqus4_blink_time; /* blink duration in seconds */
-       } nrqu_nrqus4;
-
-    } nrq_nrqu;
-};
-
-#define nrq_rx           nrq_nrqu.nrqu_nrqus1.nrqus1_rx
-#define nrq_ctx          nrq_nrqu.nrqu_nrqus1.nrqus1_ctx
-#define nrq_support_rx   nrq_nrqu.nrqu_nrqus2.nrqus2_support_rx
-#define nrq_magic        nrq_nrqu.nrqu_nrqus2.nrqus2_magic
-#define nrq_support_vlan nrq_nrqu.nrqu_nrqus2.nrqus2_support_vlan
-#define nrq_support_get_speed nrq_nrqu.nrqu_nrqus2.nrqus2_support_get_speed
-#define nrq_speed        nrq_nrqu.nrqu_nrqus3.nrqus3_speed
-#define nrq_blink_time   nrq_nrqu.nrqu_nrqus4.nrqus4_blink_time
-
-/*
- * magic constants
- */
-#define NICE_REQUESTOR_MAGIC            0x4543494E /* NICE in ascii */
-#define NICE_DEVICE_MAGIC               0x4E494345 /* ECIN in ascii */
-
-/*
- * command field
- */
-#define NICE_CMD_QUERY_SUPPORT          0x00000001
-#define NICE_CMD_SET_RX                 0x00000002
-#define NICE_CMD_GET_RX                 0x00000003
-#define NICE_CMD_GET_SPEED              0x00000004
-#define NICE_CMD_BLINK_LED              0x00000005
-
-#endif  /* _nicext_h_ */
diff --git a/drivers/ns16550.c b/drivers/ns16550.c
deleted file mode 100644 (file)
index 2429464..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * COM1 NS16550 support
- * originally from linux source (arch/ppc/boot/ns16550.c)
- * modified to use CFG_ISA_MEM and new defines
- */
-
-#include <config.h>
-
-#ifdef CFG_NS16550
-
-#include <ns16550.h>
-
-#define LCRVAL LCR_8N1                                 /* 8 data, 1 stop, no parity */
-#define MCRVAL (MCR_DTR | MCR_RTS)                     /* RTS/DTR */
-#define FCRVAL (FCR_FIFO_EN | FCR_RXSR | FCR_TXSR)     /* Clear & enable FIFOs */
-
-void NS16550_init (NS16550_t com_port, int baud_divisor)
-{
-       com_port->ier = 0x00;
-#ifdef CONFIG_OMAP
-       com_port->mdr1 = 0x7;   /* mode select reset TL16C750*/
-#endif
-       com_port->lcr = LCR_BKSE | LCRVAL;
-       com_port->dll = baud_divisor & 0xff;
-       com_port->dlm = (baud_divisor >> 8) & 0xff;
-       com_port->lcr = LCRVAL;
-       com_port->mcr = MCRVAL;
-       com_port->fcr = FCRVAL;
-#if defined(CONFIG_OMAP)
-#if defined(CONFIG_APTIX)
-       com_port->mdr1 = 3;     /* /13 mode so Aptix 6MHz can hit 115200 */
-#else
-       com_port->mdr1 = 0;     /* /16 is proper to hit 115200 with 48MHz */
-#endif
-#endif
-}
-
-void NS16550_reinit (NS16550_t com_port, int baud_divisor)
-{
-       com_port->ier = 0x00;
-       com_port->lcr = LCR_BKSE;
-       com_port->dll = baud_divisor & 0xff;
-       com_port->dlm = (baud_divisor >> 8) & 0xff;
-       com_port->lcr = LCRVAL;
-       com_port->mcr = MCRVAL;
-       com_port->fcr = FCRVAL;
-}
-
-void NS16550_putc (NS16550_t com_port, char c)
-{
-       while ((com_port->lsr & LSR_THRE) == 0);
-       com_port->thr = c;
-}
-
-char NS16550_getc (NS16550_t com_port)
-{
-       while ((com_port->lsr & LSR_DR) == 0) {
-#ifdef CONFIG_USB_TTY
-               extern void usbtty_poll(void);
-               usbtty_poll();
-#endif
-       }
-       return (com_port->rbr);
-}
-
-int NS16550_tstc (NS16550_t com_port)
-{
-       return ((com_port->lsr & LSR_DR) != 0);
-}
-
-#endif
diff --git a/drivers/ns7520_eth.c b/drivers/ns7520_eth.c
deleted file mode 100644 (file)
index a5a20df..0000000
+++ /dev/null
@@ -1,859 +0,0 @@
-/***********************************************************************
- *
- * Copyright (C) 2005 by Videon Central, Inc.
- *
- * $Id$
- * @Author: Arthur Shipkowski
- * @Descr: Ethernet driver for the NS7520. Uses polled Ethernet, like
- *     the older netarmeth driver.  Note that attempting to filter
- *     broadcast and multicast out in the SAFR register will cause
- *     bad things due to released errata.
- * @References: [1] NS7520 Hardware Reference, December 2003
- *             [2] Intel LXT971 Datasheet #249414 Rev. 02
- *
- ***********************************************************************/
-
-#include <common.h>
-
-#if defined(CONFIG_DRIVER_NS7520_ETHERNET)
-
-#include <net.h>               /* NetSendPacket */
-#include <asm/arch/netarm_registers.h>
-#include <asm/arch/netarm_dma_module.h>
-
-#include "ns7520_eth.h"                /* for Ethernet and PHY */
-
-/**
- * Send an error message to the terminal.
- */
-#define ERROR(x) \
-do { \
-       char *__foo = strrchr(__FILE__, '/'); \
-       \
-       printf("%s: %d: %s(): ", (__foo == NULL ? __FILE__ : (__foo + 1)), \
-                       __LINE__, __FUNCTION__); \
-       printf x; printf("\n"); \
-} while (0);
-
-/* some definition to make transistion to linux easier */
-
-#define NS7520_DRIVER_NAME     "eth"
-#define KERN_WARNING           "Warning:"
-#define KERN_ERR               "Error:"
-#define KERN_INFO              "Info:"
-
-#if 1
-# define DEBUG
-#endif
-
-#ifdef DEBUG
-# define printk                        printf
-
-# define DEBUG_INIT            0x0001
-# define DEBUG_MINOR           0x0002
-# define DEBUG_RX              0x0004
-# define DEBUG_TX              0x0008
-# define DEBUG_INT             0x0010
-# define DEBUG_POLL            0x0020
-# define DEBUG_LINK            0x0040
-# define DEBUG_MII             0x0100
-# define DEBUG_MII_LOW         0x0200
-# define DEBUG_MEM             0x0400
-# define DEBUG_ERROR           0x4000
-# define DEBUG_ERROR_CRIT      0x8000
-
-static int nDebugLvl = DEBUG_ERROR_CRIT;
-
-# define DEBUG_ARGS0( FLG, a0 ) if( ( nDebugLvl & (FLG) ) == (FLG) ) \
-               printf("%s: " a0, __FUNCTION__, 0, 0, 0, 0, 0, 0 )
-# define DEBUG_ARGS1( FLG, a0, a1 ) if( ( nDebugLvl & (FLG) ) == (FLG)) \
-               printf("%s: " a0, __FUNCTION__, (int)(a1), 0, 0, 0, 0, 0 )
-# define DEBUG_ARGS2( FLG, a0, a1, a2 ) if( (nDebugLvl & (FLG)) ==(FLG))\
-               printf("%s: " a0, __FUNCTION__, (int)(a1), (int)(a2), 0, 0,0,0 )
-# define DEBUG_ARGS3( FLG, a0, a1, a2, a3 ) if((nDebugLvl &(FLG))==(FLG))\
-               printf("%s: "a0,__FUNCTION__,(int)(a1),(int)(a2),(int)(a3),0,0,0)
-# define DEBUG_FN( FLG ) if( (nDebugLvl & (FLG)) == (FLG) ) \
-               printf("\r%s:line %d\n", (int)__FUNCTION__, __LINE__, 0,0,0,0);
-# define ASSERT( expr, func ) if( !( expr ) ) { \
-               printf( "Assertion failed! %s:line %d %s\n", \
-               (int)__FUNCTION__,__LINE__,(int)(#expr),0,0,0); \
-               func }
-#else                          /* DEBUG */
-# define printk(...)
-# define DEBUG_ARGS0( FLG, a0 )
-# define DEBUG_ARGS1( FLG, a0, a1 )
-# define DEBUG_ARGS2( FLG, a0, a1, a2 )
-# define DEBUG_ARGS3( FLG, a0, a1, a2, a3 )
-# define DEBUG_FN( n )
-# define ASSERT(expr, func)
-#endif                         /* DEBUG */
-
-#define NS7520_MII_NEG_DELAY           (5*CFG_HZ)      /* in s */
-#define TX_TIMEOUT                     (5*CFG_HZ)      /* in s */
-#define RX_STALL_WORKAROUND_CNT 100
-
-static int ns7520_eth_reset(void);
-
-static void ns7520_link_auto_negotiate(void);
-static void ns7520_link_update_egcr(void);
-static void ns7520_link_print_changed(void);
-
-/* the PHY stuff */
-
-static char ns7520_mii_identify_phy(void);
-static unsigned short ns7520_mii_read(unsigned short uiRegister);
-static void ns7520_mii_write(unsigned short uiRegister,
-                            unsigned short uiData);
-static unsigned int ns7520_mii_get_clock_divisor(unsigned int
-                                                unMaxMDIOClk);
-static unsigned int ns7520_mii_poll_busy(void);
-
-static unsigned int nPhyMaxMdioClock = PHY_MDIO_MAX_CLK;
-static unsigned int uiLastLinkStatus;
-static PhyType phyDetected = PHY_NONE;
-
-/***********************************************************************
- * @Function: eth_init
- * @Return: -1 on failure otherwise 0
- * @Descr: Initializes the ethernet engine and uses either FS Forth's default
- *        MAC addr or the one in environment
- ***********************************************************************/
-
-int eth_init(bd_t * pbis)
-{
-       unsigned char aucMACAddr[6];
-       char *pcTmp = getenv("ethaddr");
-       char *pcEnd;
-       int i;
-
-       DEBUG_FN(DEBUG_INIT);
-
-       /* no need to check for hardware */
-
-       if (!ns7520_eth_reset())
-               return -1;
-
-       if (NULL == pcTmp)
-               return -1;
-
-       for (i = 0; i < 6; i++) {
-               aucMACAddr[i] =
-                   pcTmp ? simple_strtoul(pcTmp, &pcEnd, 16) : 0;
-               pcTmp = (*pcTmp) ? pcEnd + 1 : pcEnd;
-       }
-
-       /* configure ethernet address */
-
-       *get_eth_reg_addr(NS7520_ETH_SA1) =
-           aucMACAddr[5] << 8 | aucMACAddr[4];
-       *get_eth_reg_addr(NS7520_ETH_SA2) =
-           aucMACAddr[3] << 8 | aucMACAddr[2];
-       *get_eth_reg_addr(NS7520_ETH_SA3) =
-           aucMACAddr[1] << 8 | aucMACAddr[0];
-
-       /* enable hardware */
-
-       *get_eth_reg_addr(NS7520_ETH_MAC1) = NS7520_ETH_MAC1_RXEN;
-       *get_eth_reg_addr(NS7520_ETH_SUPP) = NS7520_ETH_SUPP_JABBER;
-       *get_eth_reg_addr(NS7520_ETH_MAC1) = NS7520_ETH_MAC1_RXEN;
-
-       /* the linux kernel may give packets < 60 bytes, for example arp */
-       *get_eth_reg_addr(NS7520_ETH_MAC2) = NS7520_ETH_MAC2_CRCEN |
-           NS7520_ETH_MAC2_PADEN | NS7520_ETH_MAC2_HUGE;
-
-       /* Broadcast/multicast allowed; if you don't set this even unicast chokes */
-       /* Based on NS7520 errata documentation */
-       *get_eth_reg_addr(NS7520_ETH_SAFR) =
-           NS7520_ETH_SAFR_BROAD | NS7520_ETH_SAFR_PRM;
-
-       /* enable receive and transmit FIFO, use 10/100 Mbps MII */
-       *get_eth_reg_addr(NS7520_ETH_EGCR) |=
-           NS7520_ETH_EGCR_ETXWM_75 |
-           NS7520_ETH_EGCR_ERX |
-           NS7520_ETH_EGCR_ERXREG |
-           NS7520_ETH_EGCR_ERXBR | NS7520_ETH_EGCR_ETX;
-
-       return 0;
-}
-
-/***********************************************************************
- * @Function: eth_send
- * @Return: -1 on timeout otherwise 1
- * @Descr: sends one frame by DMA
- ***********************************************************************/
-
-int eth_send(volatile void *pPacket, int nLen)
-{
-       int i, length32, retval = 1;
-       char *pa;
-       unsigned int *pa32, lastp = 0, rest;
-       unsigned int status;
-
-       pa = (char *) pPacket;
-       pa32 = (unsigned int *) pPacket;
-       length32 = nLen / 4;
-       rest = nLen % 4;
-
-       /* make sure there's no garbage in the last word */
-       switch (rest) {
-       case 0:
-               lastp = pa32[length32 - 1];
-               length32--;
-               break;
-       case 1:
-               lastp = pa32[length32] & 0x000000ff;
-               break;
-       case 2:
-               lastp = pa32[length32] & 0x0000ffff;
-               break;
-       case 3:
-               lastp = pa32[length32] & 0x00ffffff;
-               break;
-       }
-
-       while (((*get_eth_reg_addr(NS7520_ETH_EGSR)) &
-               NS7520_ETH_EGSR_TXREGE)
-              == 0) {
-       }
-
-       /* write to the fifo */
-       for (i = 0; i < length32; i++)
-               *get_eth_reg_addr(NS7520_ETH_FIFO) = pa32[i];
-
-       /* the last word is written to an extra register, this
-          starts the transmission */
-       *get_eth_reg_addr(NS7520_ETH_FIFOL) = lastp;
-
-       /* Wait for it to be done */
-       while ((*get_eth_reg_addr(NS7520_ETH_EGSR) & NS7520_ETH_EGSR_TXBC)
-              == 0) {
-       }
-       status = (*get_eth_reg_addr(NS7520_ETH_ETSR));
-       *get_eth_reg_addr(NS7520_ETH_EGSR) = NS7520_ETH_EGSR_TXBC;      /* Clear it now */
-
-       if (status & NS7520_ETH_ETSR_TXOK) {
-               retval = 0;     /* We're OK! */
-       } else if (status & NS7520_ETH_ETSR_TXDEF) {
-               printf("Deferred, we'll see.\n");
-               retval = 0;
-       } else if (status & NS7520_ETH_ETSR_TXAL) {
-               printf("Late collision error, %d collisions.\n",
-                      (*get_eth_reg_addr(NS7520_ETH_ETSR)) &
-                      NS7520_ETH_ETSR_TXCOLC);
-       } else if (status & NS7520_ETH_ETSR_TXAEC) {
-               printf("Excessive collisions: %d\n",
-                      (*get_eth_reg_addr(NS7520_ETH_ETSR)) &
-                      NS7520_ETH_ETSR_TXCOLC);
-       } else if (status & NS7520_ETH_ETSR_TXAED) {
-               printf("Excessive deferral on xmit.\n");
-       } else if (status & NS7520_ETH_ETSR_TXAUR) {
-               printf("Packet underrun.\n");
-       } else if (status & NS7520_ETH_ETSR_TXAJ) {
-               printf("Jumbo packet error.\n");
-       } else {
-               printf("Error: Should never get here.\n");
-       }
-
-       return (retval);
-}
-
-/***********************************************************************
- * @Function: eth_rx
- * @Return: size of last frame in bytes or 0 if no frame available
- * @Descr: gives one frame to U-Boot which has been copied by DMA engine already
- *        to NetRxPackets[ 0 ].
- ***********************************************************************/
-
-int eth_rx(void)
-{
-       int i;
-       unsigned short rxlen;
-       unsigned short totrxlen = 0;
-       unsigned int *addr;
-       unsigned int rxstatus, lastrxlen;
-       char *pa;
-
-       /* If RXBR is 1, data block was received */
-       while (((*get_eth_reg_addr(NS7520_ETH_EGSR)) &
-               NS7520_ETH_EGSR_RXBR) == NS7520_ETH_EGSR_RXBR) {
-
-               /* get status register and the length of received block */
-               rxstatus = *get_eth_reg_addr(NS7520_ETH_ERSR);
-               rxlen = (rxstatus & NS7520_ETH_ERSR_RXSIZE) >> 16;
-
-               /* clear RXBR to make fifo available */
-               *get_eth_reg_addr(NS7520_ETH_EGSR) = NS7520_ETH_EGSR_RXBR;
-
-               if (rxstatus & NS7520_ETH_ERSR_ROVER) {
-                       printf("Receive overrun, resetting FIFO.\n");
-                       *get_eth_reg_addr(NS7520_ETH_EGCR) &=
-                           ~NS7520_ETH_EGCR_ERX;
-                       udelay(20);
-                       *get_eth_reg_addr(NS7520_ETH_EGCR) |=
-                           NS7520_ETH_EGCR_ERX;
-               }
-               if (rxlen == 0) {
-                       printf("Nothing.\n");
-                       return 0;
-               }
-
-               addr = (unsigned int *) NetRxPackets[0];
-               pa = (char *) NetRxPackets[0];
-
-               /* read the fifo */
-               for (i = 0; i < rxlen / 4; i++) {
-                       *addr = *get_eth_reg_addr(NS7520_ETH_FIFO);
-                       addr++;
-               }
-
-               if ((*get_eth_reg_addr(NS7520_ETH_EGSR)) &
-                   NS7520_ETH_EGSR_RXREGR) {
-                       /* RXFDB indicates wether the last word is 1,2,3 or 4 bytes long */
-                       lastrxlen =
-                           ((*get_eth_reg_addr(NS7520_ETH_EGSR)) &
-                            NS7520_ETH_EGSR_RXFDB_MA) >> 28;
-                       *addr = *get_eth_reg_addr(NS7520_ETH_FIFO);
-                       switch (lastrxlen) {
-                       case 1:
-                               *addr &= 0xff000000;
-                               break;
-                       case 2:
-                               *addr &= 0xffff0000;
-                               break;
-                       case 3:
-                               *addr &= 0xffffff00;
-                               break;
-                       }
-               }
-
-               /* Pass the packet up to the protocol layers. */
-               NetReceive(NetRxPackets[0], rxlen - 4);
-               totrxlen += rxlen - 4;
-       }
-
-       return totrxlen;
-}
-
-/***********************************************************************
- * @Function: eth_halt
- * @Return: n/a
- * @Descr: stops the ethernet engine
- ***********************************************************************/
-
-void eth_halt(void)
-{
-       DEBUG_FN(DEBUG_INIT);
-
-       *get_eth_reg_addr(NS7520_ETH_MAC1) &= ~NS7520_ETH_MAC1_RXEN;
-       *get_eth_reg_addr(NS7520_ETH_EGCR) &= ~(NS7520_ETH_EGCR_ERX |
-                                               NS7520_ETH_EGCR_ERXDMA |
-                                               NS7520_ETH_EGCR_ERXREG |
-                                               NS7520_ETH_EGCR_ERXBR |
-                                               NS7520_ETH_EGCR_ETX |
-                                               NS7520_ETH_EGCR_ETXDMA);
-}
-
-/***********************************************************************
- * @Function: ns7520_eth_reset
- * @Return: 0 on failure otherwise 1
- * @Descr: resets the ethernet interface and the PHY,
- *        performs auto negotiation or fixed modes
- ***********************************************************************/
-
-static int ns7520_eth_reset(void)
-{
-       DEBUG_FN(DEBUG_MINOR);
-
-       /* Reset important registers */
-       *get_eth_reg_addr(NS7520_ETH_EGCR) = 0; /* Null it out! */
-       *get_eth_reg_addr(NS7520_ETH_MAC1) &= NS7520_ETH_MAC1_SRST;
-       *get_eth_reg_addr(NS7520_ETH_MAC2) = 0;
-       /* Reset MAC */
-       *get_eth_reg_addr(NS7520_ETH_EGCR) |= NS7520_ETH_EGCR_MAC_RES;
-       udelay(5);
-       *get_eth_reg_addr(NS7520_ETH_EGCR) &= ~NS7520_ETH_EGCR_MAC_RES;
-
-       /* reset and initialize PHY */
-
-       *get_eth_reg_addr(NS7520_ETH_MAC1) &= ~NS7520_ETH_MAC1_SRST;
-
-       /* we don't support hot plugging of PHY, therefore we don't reset
-          phyDetected and nPhyMaxMdioClock here. The risk is if the setting is
-          incorrect the first open
-          may detect the PHY correctly but succeding will fail
-          For reseting the PHY and identifying we have to use the standard
-          MDIO CLOCK value 2.5 MHz only after hardware reset
-          After having identified the PHY we will do faster */
-
-       *get_eth_reg_addr(NS7520_ETH_MCFG) =
-           ns7520_mii_get_clock_divisor(nPhyMaxMdioClock);
-
-       /* reset PHY */
-       ns7520_mii_write(PHY_COMMON_CTRL, PHY_COMMON_CTRL_RESET);
-       ns7520_mii_write(PHY_COMMON_CTRL, 0);
-
-       udelay(3000);           /* [2] p.70 says at least 300us reset recovery time. */
-
-       /* MII clock has been setup to default, ns7520_mii_identify_phy should
-          work for all */
-
-       if (!ns7520_mii_identify_phy()) {
-               printk(KERN_ERR NS7520_DRIVER_NAME
-                      ": Unsupported PHY, aborting\n");
-               return 0;
-       }
-
-       /* now take the highest MDIO clock possible after detection */
-       *get_eth_reg_addr(NS7520_ETH_MCFG) =
-           ns7520_mii_get_clock_divisor(nPhyMaxMdioClock);
-
-       /* PHY has been detected, so there can be no abort reason and we can
-          finish initializing ethernet */
-
-       uiLastLinkStatus = 0xff;        /* undefined */
-
-       ns7520_link_auto_negotiate();
-
-       if (phyDetected == PHY_LXT971A)
-               /* set LED2 to link mode */
-               ns7520_mii_write(PHY_LXT971_LED_CFG,
-                                (PHY_LXT971_LED_CFG_LINK_ACT <<
-                                 PHY_LXT971_LED_CFG_SHIFT_LED2) |
-                                (PHY_LXT971_LED_CFG_TRANSMIT <<
-                                 PHY_LXT971_LED_CFG_SHIFT_LED1));
-
-       return 1;
-}
-
-/***********************************************************************
- * @Function: ns7520_link_auto_negotiate
- * @Return: void
- * @Descr: performs auto-negotation of link.
- ***********************************************************************/
-
-static void ns7520_link_auto_negotiate(void)
-{
-       unsigned long ulStartJiffies;
-       unsigned short uiStatus;
-
-       DEBUG_FN(DEBUG_LINK);
-
-       /* run auto-negotation */
-       /* define what we are capable of */
-       ns7520_mii_write(PHY_COMMON_AUTO_ADV,
-                        PHY_COMMON_AUTO_ADV_100BTXFD |
-                        PHY_COMMON_AUTO_ADV_100BTX |
-                        PHY_COMMON_AUTO_ADV_10BTFD |
-                        PHY_COMMON_AUTO_ADV_10BT |
-                        PHY_COMMON_AUTO_ADV_802_3);
-       /* start auto-negotiation */
-       ns7520_mii_write(PHY_COMMON_CTRL,
-                        PHY_COMMON_CTRL_AUTO_NEG |
-                        PHY_COMMON_CTRL_RES_AUTO);
-
-       /* wait for completion */
-
-       ulStartJiffies = get_timer(0);
-       while (get_timer(0) < ulStartJiffies + NS7520_MII_NEG_DELAY) {
-               uiStatus = ns7520_mii_read(PHY_COMMON_STAT);
-               if ((uiStatus &
-                    (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT))
-                   ==
-                   (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT)) {
-                       /* lucky we are, auto-negotiation succeeded */
-                       ns7520_link_print_changed();
-                       ns7520_link_update_egcr();
-                       return;
-               }
-       }
-
-       DEBUG_ARGS0(DEBUG_LINK, "auto-negotiation timed out\n");
-       /* ignore invalid link settings */
-}
-
-/***********************************************************************
- * @Function: ns7520_link_update_egcr
- * @Return: void
- * @Descr: updates the EGCR and MAC2 link status after mode change or
- *        auto-negotation
- ***********************************************************************/
-
-static void ns7520_link_update_egcr(void)
-{
-       unsigned int unEGCR;
-       unsigned int unMAC2;
-       unsigned int unIPGT;
-
-       DEBUG_FN(DEBUG_LINK);
-
-       unEGCR = *get_eth_reg_addr(NS7520_ETH_EGCR);
-       unMAC2 = *get_eth_reg_addr(NS7520_ETH_MAC2);
-       unIPGT =
-           *get_eth_reg_addr(NS7520_ETH_IPGT) & ~NS7520_ETH_IPGT_IPGT;
-
-       unEGCR &= ~NS7520_ETH_EGCR_EFULLD;
-       unMAC2 &= ~NS7520_ETH_MAC2_FULLD;
-       if ((uiLastLinkStatus & PHY_LXT971_STAT2_DUPLEX_MODE)
-           == PHY_LXT971_STAT2_DUPLEX_MODE) {
-               unEGCR |= NS7520_ETH_EGCR_EFULLD;
-               unMAC2 |= NS7520_ETH_MAC2_FULLD;
-               unIPGT |= 0x15; /* see [1] p. 167 */
-       } else
-               unIPGT |= 0x12; /* see [1] p. 167 */
-
-       *get_eth_reg_addr(NS7520_ETH_MAC2) = unMAC2;
-       *get_eth_reg_addr(NS7520_ETH_EGCR) = unEGCR;
-       *get_eth_reg_addr(NS7520_ETH_IPGT) = unIPGT;
-}
-
-/***********************************************************************
- * @Function: ns7520_link_print_changed
- * @Return: void
- * @Descr: checks whether the link status has changed and if so prints
- *        the new mode
- ***********************************************************************/
-
-static void ns7520_link_print_changed(void)
-{
-       unsigned short uiStatus;
-       unsigned short uiControl;
-
-       DEBUG_FN(DEBUG_LINK);
-
-       uiControl = ns7520_mii_read(PHY_COMMON_CTRL);
-
-       if ((uiControl & PHY_COMMON_CTRL_AUTO_NEG) ==
-           PHY_COMMON_CTRL_AUTO_NEG) {
-               /* PHY_COMMON_STAT_LNK_STAT is only set on autonegotiation */
-               uiStatus = ns7520_mii_read(PHY_COMMON_STAT);
-
-               if (!(uiStatus & PHY_COMMON_STAT_LNK_STAT)) {
-                       printk(KERN_WARNING NS7520_DRIVER_NAME
-                              ": link down\n");
-                       /* @TODO Linux: carrier_off */
-               } else {
-                       /* @TODO Linux: carrier_on */
-                       if (phyDetected == PHY_LXT971A) {
-                               uiStatus =
-                                   ns7520_mii_read(PHY_LXT971_STAT2);
-                               uiStatus &=
-                                   (PHY_LXT971_STAT2_100BTX |
-                                    PHY_LXT971_STAT2_DUPLEX_MODE |
-                                    PHY_LXT971_STAT2_AUTO_NEG);
-
-                               /* mask out all uninteresting parts */
-                       }
-                       /* other PHYs must store there link information in
-                          uiStatus as PHY_LXT971 */
-               }
-       } else {
-               /* mode has been forced, so uiStatus should be the same as the
-                  last link status, enforce printing */
-               uiStatus = uiLastLinkStatus;
-               uiLastLinkStatus = 0xff;
-       }
-
-       if (uiStatus != uiLastLinkStatus) {
-               /* save current link status */
-               uiLastLinkStatus = uiStatus;
-
-               /* print new link status */
-
-               printk(KERN_INFO NS7520_DRIVER_NAME
-                      ": link mode %i Mbps %s duplex %s\n",
-                      (uiStatus & PHY_LXT971_STAT2_100BTX) ? 100 : 10,
-                      (uiStatus & PHY_LXT971_STAT2_DUPLEX_MODE) ? "full" :
-                      "half",
-                      (uiStatus & PHY_LXT971_STAT2_AUTO_NEG) ? "(auto)" :
-                      "");
-       }
-}
-
-/***********************************************************************
- * the MII low level stuff
- ***********************************************************************/
-
-/***********************************************************************
- * @Function: ns7520_mii_identify_phy
- * @Return: 1 if supported PHY has been detected otherwise 0
- * @Descr: checks for supported PHY and prints the IDs.
- ***********************************************************************/
-
-static char ns7520_mii_identify_phy(void)
-{
-       unsigned short uiID1;
-       unsigned short uiID2;
-       unsigned char *szName;
-       char cRes = 0;
-
-       DEBUG_FN(DEBUG_MII);
-
-       phyDetected = (PhyType) uiID1 = ns7520_mii_read(PHY_COMMON_ID1);
-
-       switch (phyDetected) {
-       case PHY_LXT971A:
-               szName = "LXT971A";
-               uiID2 = ns7520_mii_read(PHY_COMMON_ID2);
-               nPhyMaxMdioClock = PHY_LXT971_MDIO_MAX_CLK;
-               cRes = 1;
-               break;
-       case PHY_NONE:
-       default:
-               /* in case uiID1 == 0 && uiID2 == 0 we may have the wrong
-                  address or reset sets the wrong NS7520_ETH_MCFG_CLKS */
-
-               uiID2 = 0;
-               szName = "unknown";
-               nPhyMaxMdioClock = PHY_MDIO_MAX_CLK;
-               phyDetected = PHY_NONE;
-       }
-
-       printk(KERN_INFO NS7520_DRIVER_NAME
-              ": PHY (0x%x, 0x%x) = %s detected\n", uiID1, uiID2, szName);
-
-       return cRes;
-}
-
-/***********************************************************************
- * @Function: ns7520_mii_read
- * @Return: the data read from PHY register uiRegister
- * @Descr: the data read may be invalid if timed out. If so, a message
- *        is printed but the invalid data is returned.
- *        The fixed device address is being used.
- ***********************************************************************/
-
-static unsigned short ns7520_mii_read(unsigned short uiRegister)
-{
-       DEBUG_FN(DEBUG_MII_LOW);
-
-       /* write MII register to be read */
-       *get_eth_reg_addr(NS7520_ETH_MADR) =
-           CONFIG_PHY_ADDR << 8 | uiRegister;
-
-       *get_eth_reg_addr(NS7520_ETH_MCMD) = NS7520_ETH_MCMD_READ;
-
-       if (!ns7520_mii_poll_busy())
-               printk(KERN_WARNING NS7520_DRIVER_NAME
-                      ": MII still busy in read\n");
-       /* continue to read */
-
-       *get_eth_reg_addr(NS7520_ETH_MCMD) = 0;
-
-       return (unsigned short) (*get_eth_reg_addr(NS7520_ETH_MRDD));
-}
-
-/***********************************************************************
- * @Function: ns7520_mii_write
- * @Return: nothing
- * @Descr: writes the data to the PHY register. In case of a timeout,
- *        no special handling is performed but a message printed
- *        The fixed device address is being used.
- ***********************************************************************/
-
-static void ns7520_mii_write(unsigned short uiRegister,
-                            unsigned short uiData)
-{
-       DEBUG_FN(DEBUG_MII_LOW);
-
-       /* write MII register to be written */
-       *get_eth_reg_addr(NS7520_ETH_MADR) =
-           CONFIG_PHY_ADDR << 8 | uiRegister;
-
-       *get_eth_reg_addr(NS7520_ETH_MWTD) = uiData;
-
-       if (!ns7520_mii_poll_busy()) {
-               printf(KERN_WARNING NS7520_DRIVER_NAME
-                      ": MII still busy in write\n");
-       }
-}
-
-/***********************************************************************
- * @Function: ns7520_mii_get_clock_divisor
- * @Return: the clock divisor that should be used in NS7520_ETH_MCFG_CLKS
- * @Descr: if no clock divisor can be calculated for the
- *        current SYSCLK and the maximum MDIO Clock, a warning is printed
- *        and the greatest divisor is taken
- ***********************************************************************/
-
-static unsigned int ns7520_mii_get_clock_divisor(unsigned int unMaxMDIOClk)
-{
-       struct {
-               unsigned int unSysClkDivisor;
-               unsigned int unClks;    /* field for NS7520_ETH_MCFG_CLKS */
-       } PHYClockDivisors[] = {
-               {
-               4, NS7520_ETH_MCFG_CLKS_4}, {
-               6, NS7520_ETH_MCFG_CLKS_6}, {
-               8, NS7520_ETH_MCFG_CLKS_8}, {
-               10, NS7520_ETH_MCFG_CLKS_10}, {
-               14, NS7520_ETH_MCFG_CLKS_14}, {
-               20, NS7520_ETH_MCFG_CLKS_20}, {
-               28, NS7520_ETH_MCFG_CLKS_28}
-       };
-
-       int nIndexSysClkDiv;
-       int nArraySize =
-           sizeof(PHYClockDivisors) / sizeof(PHYClockDivisors[0]);
-       unsigned int unClks = NS7520_ETH_MCFG_CLKS_28;  /* defaults to
-                                                          greatest div */
-
-       DEBUG_FN(DEBUG_INIT);
-
-       for (nIndexSysClkDiv = 0; nIndexSysClkDiv < nArraySize;
-            nIndexSysClkDiv++) {
-               /* find first sysclock divisor that isn't higher than 2.5 MHz
-                  clock */
-               if (NETARM_XTAL_FREQ /
-                   PHYClockDivisors[nIndexSysClkDiv].unSysClkDivisor <=
-                   unMaxMDIOClk) {
-                       unClks = PHYClockDivisors[nIndexSysClkDiv].unClks;
-                       break;
-               }
-       }
-
-       DEBUG_ARGS2(DEBUG_INIT,
-                   "Taking MDIO Clock bit mask 0x%0x for max clock %i\n",
-                   unClks, unMaxMDIOClk);
-
-       /* return greatest divisor */
-       return unClks;
-}
-
-/***********************************************************************
- * @Function: ns7520_mii_poll_busy
- * @Return: 0 if timed out otherwise the remaing timeout
- * @Descr: waits until the MII has completed a command or it times out
- *        code may be interrupted by hard interrupts.
- *        It is not checked what happens on multiple actions when
- *        the first is still being busy and we timeout.
- ***********************************************************************/
-
-static unsigned int ns7520_mii_poll_busy(void)
-{
-       unsigned int unTimeout = 1000;
-
-       DEBUG_FN(DEBUG_MII_LOW);
-
-       while (((*get_eth_reg_addr(NS7520_ETH_MIND) & NS7520_ETH_MIND_BUSY)
-               == NS7520_ETH_MIND_BUSY) && unTimeout)
-               unTimeout--;
-
-       return unTimeout;
-}
-
-/* ----------------------------------------------------------------------------
- * Net+ARM ethernet MII functionality.
- */
-#if defined(CONFIG_MII)
-
-/**
- * Maximum MII address we support
- */
-#define MII_ADDRESS_MAX                        (31)
-
-/**
- * Maximum MII register address we support
- */
-#define MII_REGISTER_MAX               (31)
-
-/**
- * Ethernet MII interface return values for public functions.
- */
-enum mii_status {
-       MII_STATUS_SUCCESS = 0,
-       MII_STATUS_FAILURE = 1,
-};
-
-/**
- * Read a 16-bit value from an MII register.
- */
-extern int ns7520_miiphy_read(char *devname, unsigned char const addr,
-               unsigned char const reg, unsigned short *const value)
-{
-       int ret = MII_STATUS_FAILURE;
-
-       /* Parameter checks */
-       if (addr > MII_ADDRESS_MAX) {
-               ERROR(("invalid addr, 0x%02X", addr));
-               goto miiphy_read_failed_0;
-       }
-
-       if (reg > MII_REGISTER_MAX) {
-               ERROR(("invalid reg, 0x%02X", reg));
-               goto miiphy_read_failed_0;
-       }
-
-       if (value == NULL) {
-               ERROR(("NULL value"));
-               goto miiphy_read_failed_0;
-       }
-
-       DEBUG_FN(DEBUG_MII_LOW);
-
-       /* write MII register to be read */
-       *get_eth_reg_addr(NS7520_ETH_MADR) = (addr << 8) | reg;
-
-       *get_eth_reg_addr(NS7520_ETH_MCMD) = NS7520_ETH_MCMD_READ;
-
-       if (!ns7520_mii_poll_busy())
-               printk(KERN_WARNING NS7520_DRIVER_NAME
-                      ": MII still busy in read\n");
-       /* continue to read */
-
-       *get_eth_reg_addr(NS7520_ETH_MCMD) = 0;
-
-       *value = (*get_eth_reg_addr(NS7520_ETH_MRDD));
-       ret = MII_STATUS_SUCCESS;
-       /* Fall through */
-
-      miiphy_read_failed_0:
-       return (ret);
-}
-
-/**
- * Write a 16-bit value to an MII register.
- */
-extern int ns7520_miiphy_write(char *devname, unsigned char const addr,
-               unsigned char const reg, unsigned short const value)
-{
-       int ret = MII_STATUS_FAILURE;
-
-       /* Parameter checks */
-       if (addr > MII_ADDRESS_MAX) {
-               ERROR(("invalid addr, 0x%02X", addr));
-               goto miiphy_write_failed_0;
-       }
-
-       if (reg > MII_REGISTER_MAX) {
-               ERROR(("invalid reg, 0x%02X", reg));
-               goto miiphy_write_failed_0;
-       }
-
-       /* write MII register to be written */
-       *get_eth_reg_addr(NS7520_ETH_MADR) = (addr << 8) | reg;
-
-       *get_eth_reg_addr(NS7520_ETH_MWTD) = value;
-
-       if (!ns7520_mii_poll_busy()) {
-               printf(KERN_WARNING NS7520_DRIVER_NAME
-                      ": MII still busy in write\n");
-       }
-
-       ret = MII_STATUS_SUCCESS;
-       /* Fall through */
-
-      miiphy_write_failed_0:
-       return (ret);
-}
-#endif                         /* defined(CONFIG_MII) */
-#endif                         /* CONFIG_DRIVER_NS7520_ETHERNET */
-
-int ns7520_miiphy_initialize(bd_t *bis)
-{
-#if defined(CONFIG_DRIVER_NS7520_ETHERNET)
-#if defined(CONFIG_MII)
-       miiphy_register("ns7520phy", ns7520_miiphy_read, ns7520_miiphy_write);
-#endif
-#endif
-       return 0;
-}
diff --git a/drivers/ns8382x.c b/drivers/ns8382x.c
deleted file mode 100644 (file)
index f8b143a..0000000
+++ /dev/null
@@ -1,863 +0,0 @@
-/*
-   ns8382x.c: A U-Boot driver for the NatSemi DP8382[01].
-   ported by: Mark A. Rakes (mark_rakes@vivato.net)
-
-   Adapted from:
-   1. an Etherboot driver for DP8381[56] written by:
-          Copyright (C) 2001 Entity Cyber, Inc.
-
-          This development of this Etherboot driver was funded by
-                 Sicom Systems: http://www.sicompos.com/
-
-          Author: Marty Connor (mdc@thinguin.org)
-          Adapted from a Linux driver which was written by Donald Becker
-
-          This software may be used and distributed according to the terms
-          of the GNU Public License (GPL), incorporated herein by reference.
-
-   2. A Linux driver by Donald Becker, ns820.c:
-               Written/copyright 1999-2002 by Donald Becker.
-
-               This software may be used and distributed according to the terms of
-               the GNU General Public License (GPL), incorporated herein by reference.
-               Drivers based on or derived from this code fall under the GPL and must
-               retain the authorship, copyright and license notice.  This file is not
-               a complete program and may only be used when the entire operating
-               system is licensed under the GPL.  License for under other terms may be
-               available.  Contact the original author for details.
-
-               The original author may be reached as becker@scyld.com, or at
-               Scyld Computing Corporation
-               410 Severn Ave., Suite 210
-               Annapolis MD 21403
-
-               Support information and updates available at
-               http://www.scyld.com/network/netsemi.html
-
-   Datasheets available from:
-   http://www.national.com/pf/DP/DP83820.html
-   http://www.national.com/pf/DP/DP83821.html
-*/
-
-/* Revision History
- * October 2002 mar    1.0
- *   Initial U-Boot Release.
- *     Tested with Netgear GA622T (83820)
- *     and SMC9452TX (83821)
- *     NOTE: custom boards with these chips may (likely) require
- *     a programmed EEPROM device (if present) in order to work
- *     correctly.
-*/
-
-/* Includes */
-#include <common.h>
-#include <malloc.h>
-#include <net.h>
-#include <asm/io.h>
-#include <pci.h>
-
-#if defined(CONFIG_CMD_NET) \
-       && defined(CONFIG_NET_MULTI) && defined(CONFIG_NS8382X)
-
-/* defines */
-#define DSIZE     0x00000FFF
-#define ETH_ALEN               6
-#define CRC_SIZE  4
-#define TOUT_LOOP   500000
-#define TX_BUF_SIZE    1536
-#define RX_BUF_SIZE    1536
-#define NUM_RX_DESC    4       /* Number of Rx descriptor registers. */
-
-enum register_offsets {
-       ChipCmd = 0x00,
-       ChipConfig = 0x04,
-       EECtrl = 0x08,
-       IntrMask = 0x14,
-       IntrEnable = 0x18,
-       TxRingPtr = 0x20,
-       TxRingPtrHi = 0x24,
-       TxConfig = 0x28,
-       RxRingPtr = 0x30,
-       RxRingPtrHi = 0x34,
-       RxConfig = 0x38,
-       PriQueue = 0x3C,
-       RxFilterAddr = 0x48,
-       RxFilterData = 0x4C,
-       ClkRun = 0xCC,
-       PCIPM = 0x44,
-};
-
-enum ChipCmdBits {
-       ChipReset = 0x100,
-       RxReset = 0x20,
-       TxReset = 0x10,
-       RxOff = 0x08,
-       RxOn = 0x04,
-       TxOff = 0x02,
-       TxOn = 0x01
-};
-
-enum ChipConfigBits {
-       LinkSts = 0x80000000,
-       GigSpeed = 0x40000000,
-       HundSpeed = 0x20000000,
-       FullDuplex = 0x10000000,
-       TBIEn = 0x01000000,
-       Mode1000 = 0x00400000,
-       T64En = 0x00004000,
-       D64En = 0x00001000,
-       M64En = 0x00000800,
-       PhyRst = 0x00000400,
-       PhyDis = 0x00000200,
-       ExtStEn = 0x00000100,
-       BEMode = 0x00000001,
-};
-#define SpeedStatus_Polarity ( GigSpeed | HundSpeed | FullDuplex)
-
-enum TxConfig_bits {
-       TxDrthMask      = 0x000000ff,
-       TxFlthMask      = 0x0000ff00,
-       TxMxdmaMask     = 0x00700000,
-       TxMxdma_8       = 0x00100000,
-       TxMxdma_16      = 0x00200000,
-       TxMxdma_32      = 0x00300000,
-       TxMxdma_64      = 0x00400000,
-       TxMxdma_128     = 0x00500000,
-       TxMxdma_256     = 0x00600000,
-       TxMxdma_512     = 0x00700000,
-       TxMxdma_1024    = 0x00000000,
-       TxCollRetry     = 0x00800000,
-       TxAutoPad       = 0x10000000,
-       TxMacLoop       = 0x20000000,
-       TxHeartIgn      = 0x40000000,
-       TxCarrierIgn    = 0x80000000
-};
-
-enum RxConfig_bits {
-       RxDrthMask      = 0x0000003e,
-       RxMxdmaMask     = 0x00700000,
-       RxMxdma_8       = 0x00100000,
-       RxMxdma_16      = 0x00200000,
-       RxMxdma_32      = 0x00300000,
-       RxMxdma_64      = 0x00400000,
-       RxMxdma_128     = 0x00500000,
-       RxMxdma_256     = 0x00600000,
-       RxMxdma_512     = 0x00700000,
-       RxMxdma_1024    = 0x00000000,
-       RxAcceptLenErr  = 0x04000000,
-       RxAcceptLong    = 0x08000000,
-       RxAcceptTx      = 0x10000000,
-       RxStripCRC      = 0x20000000,
-       RxAcceptRunt    = 0x40000000,
-       RxAcceptErr     = 0x80000000,
-};
-
-/* Bits in the RxMode register. */
-enum rx_mode_bits {
-       RxFilterEnable          = 0x80000000,
-       AcceptAllBroadcast      = 0x40000000,
-       AcceptAllMulticast      = 0x20000000,
-       AcceptAllUnicast        = 0x10000000,
-       AcceptPerfectMatch      = 0x08000000,
-};
-
-typedef struct _BufferDesc {
-       u32 link;
-       u32 bufptr;
-       vu_long cmdsts;
-       u32 extsts;             /*not used here */
-} BufferDesc;
-
-/* Bits in network_desc.status */
-enum desc_status_bits {
-       DescOwn = 0x80000000, DescMore = 0x40000000, DescIntr = 0x20000000,
-       DescNoCRC = 0x10000000, DescPktOK = 0x08000000,
-       DescSizeMask = 0xfff,
-
-       DescTxAbort = 0x04000000, DescTxFIFO = 0x02000000,
-       DescTxCarrier = 0x01000000, DescTxDefer = 0x00800000,
-       DescTxExcDefer = 0x00400000, DescTxOOWCol = 0x00200000,
-       DescTxExcColl = 0x00100000, DescTxCollCount = 0x000f0000,
-
-       DescRxAbort = 0x04000000, DescRxOver = 0x02000000,
-       DescRxDest = 0x01800000, DescRxLong = 0x00400000,
-       DescRxRunt = 0x00200000, DescRxInvalid = 0x00100000,
-       DescRxCRC = 0x00080000, DescRxAlign = 0x00040000,
-       DescRxLoop = 0x00020000, DesRxColl = 0x00010000,
-};
-
-/* Bits in MEAR */
-enum mii_reg_bits {
-       MDIO_ShiftClk = 0x0040,
-       MDIO_EnbOutput = 0x0020,
-       MDIO_Data = 0x0010,
-};
-
-/* PHY Register offsets.  */
-enum phy_reg_offsets {
-       BMCR = 0x00,
-       BMSR = 0x01,
-       PHYIDR1 = 0x02,
-       PHYIDR2 = 0x03,
-       ANAR = 0x04,
-       KTCR = 0x09,
-};
-
-/* basic mode control register bits */
-enum bmcr_bits {
-       Bmcr_Reset = 0x8000,
-       Bmcr_Loop = 0x4000,
-       Bmcr_Speed0 = 0x2000,
-       Bmcr_AutoNegEn = 0x1000,        /*if set ignores Duplex, Speed[01] */
-       Bmcr_RstAutoNeg = 0x0200,
-       Bmcr_Duplex = 0x0100,
-       Bmcr_Speed1 = 0x0040,
-       Bmcr_Force10H = 0x0000,
-       Bmcr_Force10F = 0x0100,
-       Bmcr_Force100H = 0x2000,
-       Bmcr_Force100F = 0x2100,
-       Bmcr_Force1000H = 0x0040,
-       Bmcr_Force1000F = 0x0140,
-};
-
-/* auto negotiation advertisement register */
-enum anar_bits {
-       anar_adv_100F = 0x0100,
-       anar_adv_100H = 0x0080,
-       anar_adv_10F = 0x0040,
-       anar_adv_10H = 0x0020,
-       anar_ieee_8023 = 0x0001,
-};
-
-/* 1K-base T control register */
-enum ktcr_bits {
-       ktcr_adv_1000H = 0x0100,
-       ktcr_adv_1000F = 0x0200,
-};
-
-/* Globals */
-static u32 SavedClkRun;
-static unsigned int cur_rx;
-static unsigned int rx_config;
-static unsigned int tx_config;
-
-/* Note: transmit and receive buffers and descriptors must be
-   long long word aligned */
-static BufferDesc txd __attribute__ ((aligned(8)));
-static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(8)));
-static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(8)));
-static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE]
-    __attribute__ ((aligned(8)));
-
-/* Function Prototypes */
-static int mdio_read(struct eth_device *dev, int phy_id, int addr);
-static void mdio_write(struct eth_device *dev, int phy_id, int addr, int value);
-static void mdio_sync(struct eth_device *dev, u32 offset);
-static int ns8382x_init(struct eth_device *dev, bd_t * bis);
-static void ns8382x_reset(struct eth_device *dev);
-static void ns8382x_init_rxfilter(struct eth_device *dev);
-static void ns8382x_init_txd(struct eth_device *dev);
-static void ns8382x_init_rxd(struct eth_device *dev);
-static void ns8382x_set_rx_mode(struct eth_device *dev);
-static void ns8382x_check_duplex(struct eth_device *dev);
-static int ns8382x_send(struct eth_device *dev, volatile void *packet,
-                       int length);
-static int ns8382x_poll(struct eth_device *dev);
-static void ns8382x_disable(struct eth_device *dev);
-
-static struct pci_device_id supported[] = {
-       {PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83820},
-       {}
-};
-
-#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a)
-#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
-
-static inline int
-INW(struct eth_device *dev, u_long addr)
-{
-       return le16_to_cpu(*(vu_short *) (addr + dev->iobase));
-}
-
-static int
-INL(struct eth_device *dev, u_long addr)
-{
-       return le32_to_cpu(*(vu_long *) (addr + dev->iobase));
-}
-
-static inline void
-OUTW(struct eth_device *dev, int command, u_long addr)
-{
-       *(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command);
-}
-
-static inline void
-OUTL(struct eth_device *dev, int command, u_long addr)
-{
-       *(vu_long *) ((addr + dev->iobase)) = cpu_to_le32(command);
-}
-
-/* Function: ns8382x_initialize
- * Description: Retrieves the MAC address of the card, and sets up some
- *  globals required by other routines, and initializes the NIC, making it
- *  ready to send and receive packets.
- * Side effects: initializes ns8382xs, ready to recieve packets.
- * Returns:   int:          number of cards found
- */
-
-int
-ns8382x_initialize(bd_t * bis)
-{
-       pci_dev_t devno;
-       int card_number = 0;
-       struct eth_device *dev;
-       u32 iobase, status;
-       int i, idx = 0;
-       u32 phyAddress;
-       u32 tmp;
-       u32 chip_config;
-
-       while (1) {             /* Find PCI device(s) */
-               if ((devno = pci_find_devices(supported, idx++)) < 0)
-                       break;
-
-               pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase);
-               iobase &= ~0x3; /* 1: unused and 0:I/O Space Indicator */
-
-#ifdef NS8382X_DEBUG
-               printf("ns8382x: NatSemi dp8382x @ 0x%x\n", iobase);
-#endif
-
-               pci_write_config_dword(devno, PCI_COMMAND,
-                                      PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
-
-               /* Check if I/O accesses and Bus Mastering are enabled. */
-               pci_read_config_dword(devno, PCI_COMMAND, &status);
-               if (!(status & PCI_COMMAND_MEMORY)) {
-                       printf("Error: Can not enable MEM access.\n");
-                       continue;
-               } else if (!(status & PCI_COMMAND_MASTER)) {
-                       printf("Error: Can not enable Bus Mastering.\n");
-                       continue;
-               }
-
-               dev = (struct eth_device *) malloc(sizeof *dev);
-
-               sprintf(dev->name, "dp8382x#%d", card_number);
-               dev->iobase = bus_to_phys(iobase);
-               dev->priv = (void *) devno;
-               dev->init = ns8382x_init;
-               dev->halt = ns8382x_disable;
-               dev->send = ns8382x_send;
-               dev->recv = ns8382x_poll;
-
-               /* ns8382x has a non-standard PM control register
-                * in PCI config space.  Some boards apparently need
-                * to be brought to D0 in this manner.  */
-               pci_read_config_dword(devno, PCIPM, &tmp);
-               if (tmp & (0x03 | 0x100)) {     /* D0 state, disable PME assertion */
-                       u32 newtmp = tmp & ~(0x03 | 0x100);
-                       pci_write_config_dword(devno, PCIPM, newtmp);
-               }
-
-               /* get MAC address */
-               for (i = 0; i < 3; i++) {
-                       u32 data;
-                       char *mac = (char *)&dev->enetaddr[i * 2];
-
-                       OUTL(dev, i * 2, RxFilterAddr);
-                       data = INL(dev, RxFilterData);
-                       *mac++ = data;
-                       *mac++ = data >> 8;
-               }
-               /* get PHY address, can't be zero */
-               for (phyAddress = 1; phyAddress < 32; phyAddress++) {
-                       u32 rev, phy1;
-
-                       phy1 = mdio_read(dev, phyAddress, PHYIDR1);
-                       if (phy1 == 0x2000) {   /*check for 83861/91 */
-                               rev = mdio_read(dev, phyAddress, PHYIDR2);
-                               if ((rev & ~(0x000f)) == 0x00005c50 ||
-                                   (rev & ~(0x000f)) == 0x00005c60) {
-#ifdef NS8382X_DEBUG
-                                       printf("phy rev is %x\n", rev);
-                                       printf("phy address is %x\n",
-                                              phyAddress);
-#endif
-                                       break;
-                               }
-                       }
-               }
-
-               /* set phy to autonegotiate && advertise everything */
-               mdio_write(dev, phyAddress, KTCR,
-                          (ktcr_adv_1000H | ktcr_adv_1000F));
-               mdio_write(dev, phyAddress, ANAR,
-                          (anar_adv_100F | anar_adv_100H | anar_adv_10H |
-                           anar_adv_10F | anar_ieee_8023));
-               mdio_write(dev, phyAddress, BMCR, 0x0); /*restore */
-               mdio_write(dev, phyAddress, BMCR,
-                          (Bmcr_AutoNegEn | Bmcr_RstAutoNeg));
-               /* Reset the chip to erase any previous misconfiguration. */
-               OUTL(dev, (ChipReset), ChipCmd);
-
-               chip_config = INL(dev, ChipConfig);
-               /* reset the phy */
-               OUTL(dev, (chip_config | PhyRst), ChipConfig);
-               /* power up and initialize transceiver */
-               OUTL(dev, (chip_config & ~(PhyDis)), ChipConfig);
-
-               mdio_sync(dev, EECtrl);
-#ifdef NS8382X_DEBUG
-               {
-                       u32 chpcfg =
-                           INL(dev, ChipConfig) ^ SpeedStatus_Polarity;
-
-                       printf("%s: Transceiver 10%s %s duplex.\n", dev->name,
-                              (chpcfg & GigSpeed) ? "00" : (chpcfg & HundSpeed)
-                              ? "0" : "",
-                              chpcfg & FullDuplex ? "full" : "half");
-                       printf("%s: %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
-                              dev->enetaddr[0], dev->enetaddr[1],
-                              dev->enetaddr[2], dev->enetaddr[3],
-                              dev->enetaddr[4], dev->enetaddr[5]);
-               }
-#endif
-               /* Disable PME:
-                * The PME bit is initialized from the EEPROM contents.
-                * PCI cards probably have PME disabled, but motherboard
-                * implementations may have PME set to enable WakeOnLan.
-                * With PME set the chip will scan incoming packets but
-                * nothing will be written to memory. */
-               SavedClkRun = INL(dev, ClkRun);
-               OUTL(dev, SavedClkRun & ~0x100, ClkRun);
-
-               eth_register(dev);
-
-               card_number++;
-
-               pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x60);
-
-               udelay(10 * 1000);
-       }
-       return card_number;
-}
-
-/*  MII transceiver control section.
-       Read and write MII registers using software-generated serial MDIO
-       protocol.  See the MII specifications or DP83840A data sheet for details.
-
-       The maximum data clock rate is 2.5 Mhz.  To meet minimum timing we
-       must flush writes to the PCI bus with a PCI read. */
-#define mdio_delay(mdio_addr) INL(dev, mdio_addr)
-
-#define MDIO_EnbIn  (0)
-#define MDIO_WRITE0 (MDIO_EnbOutput)
-#define MDIO_WRITE1 (MDIO_Data | MDIO_EnbOutput)
-
-/* Generate the preamble required for initial synchronization and
-   a few older transceivers. */
-static void
-mdio_sync(struct eth_device *dev, u32 offset)
-{
-       int bits = 32;
-
-       /* Establish sync by sending at least 32 logic ones. */
-       while (--bits >= 0) {
-               OUTL(dev, MDIO_WRITE1, offset);
-               mdio_delay(offset);
-               OUTL(dev, MDIO_WRITE1 | MDIO_ShiftClk, offset);
-               mdio_delay(offset);
-       }
-}
-
-static int
-mdio_read(struct eth_device *dev, int phy_id, int addr)
-{
-       int mii_cmd = (0xf6 << 10) | (phy_id << 5) | addr;
-       int i, retval = 0;
-
-       /* Shift the read command bits out. */
-       for (i = 15; i >= 0; i--) {
-               int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
-
-               OUTL(dev, dataval, EECtrl);
-               mdio_delay(EECtrl);
-               OUTL(dev, dataval | MDIO_ShiftClk, EECtrl);
-               mdio_delay(EECtrl);
-       }
-       /* Read the two transition, 16 data, and wire-idle bits. */
-       for (i = 19; i > 0; i--) {
-               OUTL(dev, MDIO_EnbIn, EECtrl);
-               mdio_delay(EECtrl);
-               retval =
-                   (retval << 1) | ((INL(dev, EECtrl) & MDIO_Data) ? 1 : 0);
-               OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl);
-               mdio_delay(EECtrl);
-       }
-       return (retval >> 1) & 0xffff;
-}
-
-static void
-mdio_write(struct eth_device *dev, int phy_id, int addr, int value)
-{
-       int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (addr << 18) | value;
-       int i;
-
-       /* Shift the command bits out. */
-       for (i = 31; i >= 0; i--) {
-               int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
-
-               OUTL(dev, dataval, EECtrl);
-               mdio_delay(EECtrl);
-               OUTL(dev, dataval | MDIO_ShiftClk, EECtrl);
-               mdio_delay(EECtrl);
-       }
-       /* Clear out extra bits. */
-       for (i = 2; i > 0; i--) {
-               OUTL(dev, MDIO_EnbIn, EECtrl);
-               mdio_delay(EECtrl);
-               OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl);
-               mdio_delay(EECtrl);
-       }
-       return;
-}
-
-/* Function: ns8382x_init
- * Description: resets the ethernet controller chip and configures
- *    registers and data structures required for sending and receiving packets.
- * Arguments: struct eth_device *dev:       NIC data structure
- * returns:    int.
- */
-
-static int
-ns8382x_init(struct eth_device *dev, bd_t * bis)
-{
-       u32 config;
-
-       ns8382x_reset(dev);
-
-       /* Disable PME:
-        * The PME bit is initialized from the EEPROM contents.
-        * PCI cards probably have PME disabled, but motherboard
-        * implementations may have PME set to enable WakeOnLan.
-        * With PME set the chip will scan incoming packets but
-        * nothing will be written to memory. */
-       OUTL(dev, SavedClkRun & ~0x100, ClkRun);
-
-       ns8382x_init_rxfilter(dev);
-       ns8382x_init_txd(dev);
-       ns8382x_init_rxd(dev);
-
-       /*set up ChipConfig */
-       config = INL(dev, ChipConfig);
-       /*turn off 64 bit ops && Ten-bit interface
-        * && big-endian mode && extended status */
-       config &= ~(TBIEn | Mode1000 | T64En | D64En | M64En | BEMode | PhyDis | ExtStEn);
-       OUTL(dev, config, ChipConfig);
-
-       /* Configure the PCI bus bursts and FIFO thresholds. */
-       tx_config = TxCarrierIgn | TxHeartIgn | TxAutoPad
-           | TxCollRetry | TxMxdma_1024 | (0x1002);
-       rx_config = RxMxdma_1024 | 0x20;
-#ifdef NS8382X_DEBUG
-       printf("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config);
-       printf("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config);
-#endif
-       OUTL(dev, tx_config, TxConfig);
-       OUTL(dev, rx_config, RxConfig);
-
-       /*turn off priority queueing */
-       OUTL(dev, 0x0, PriQueue);
-
-       ns8382x_check_duplex(dev);
-       ns8382x_set_rx_mode(dev);
-
-       OUTL(dev, (RxOn | TxOn), ChipCmd);
-       return 1;
-}
-
-/* Function: ns8382x_reset
- * Description: soft resets the controller chip
- * Arguments: struct eth_device *dev:          NIC data structure
- * Returns:   void.
- */
-static void
-ns8382x_reset(struct eth_device *dev)
-{
-       OUTL(dev, ChipReset, ChipCmd);
-       while (INL(dev, ChipCmd))
-               /*wait until done */ ;
-       OUTL(dev, 0, IntrMask);
-       OUTL(dev, 0, IntrEnable);
-}
-
-/* Function: ns8382x_init_rxfilter
- * Description: sets receive filter address to our MAC address
- * Arguments: struct eth_device *dev:          NIC data structure
- * returns:   void.
- */
-
-static void
-ns8382x_init_rxfilter(struct eth_device *dev)
-{
-       int i;
-
-       for (i = 0; i < ETH_ALEN; i += 2) {
-               OUTL(dev, i, RxFilterAddr);
-               OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8),
-                    RxFilterData);
-       }
-}
-
-/* Function: ns8382x_init_txd
- * Description: initializes the Tx descriptor
- * Arguments: struct eth_device *dev:          NIC data structure
- * returns:   void.
- */
-
-static void
-ns8382x_init_txd(struct eth_device *dev)
-{
-       txd.link = (u32) 0;
-       txd.bufptr = cpu_to_le32((u32) & txb[0]);
-       txd.cmdsts = (u32) 0;
-       txd.extsts = (u32) 0;
-
-       OUTL(dev, 0x0, TxRingPtrHi);
-       OUTL(dev, phys_to_bus((u32)&txd), TxRingPtr);
-#ifdef NS8382X_DEBUG
-       printf("ns8382x_init_txd: TX descriptor register loaded with: %#08X (&txd: %p)\n",
-              INL(dev, TxRingPtr), &txd);
-#endif
-}
-
-/* Function: ns8382x_init_rxd
- * Description: initializes the Rx descriptor ring
- * Arguments: struct eth_device *dev:          NIC data structure
- * Returns:   void.
- */
-
-static void
-ns8382x_init_rxd(struct eth_device *dev)
-{
-       int i;
-
-       OUTL(dev, 0x0, RxRingPtrHi);
-
-       cur_rx = 0;
-       for (i = 0; i < NUM_RX_DESC; i++) {
-               rxd[i].link =
-                   cpu_to_le32((i + 1 <
-                                NUM_RX_DESC) ? (u32) & rxd[i +
-                                                           1] : (u32) &
-                               rxd[0]);
-               rxd[i].extsts = cpu_to_le32((u32) 0x0);
-               rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE);
-               rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]);
-#ifdef NS8382X_DEBUG
-               printf
-                   ("ns8382x_init_rxd: rxd[%d]=%p link=%X cmdsts=%X bufptr=%X\n",
-                    i, &rxd[i], le32_to_cpu(rxd[i].link),
-                    le32_to_cpu(rxd[i].cmdsts), le32_to_cpu(rxd[i].bufptr));
-#endif
-       }
-       OUTL(dev, phys_to_bus((u32) & rxd), RxRingPtr);
-
-#ifdef NS8382X_DEBUG
-       printf("ns8382x_init_rxd: RX descriptor register loaded with: %X\n",
-              INL(dev, RxRingPtr));
-#endif
-}
-
-/* Function: ns8382x_set_rx_mode
- * Description:
- *    sets the receive mode to accept all broadcast packets and packets
- *    with our MAC address, and reject all multicast packets.
- * Arguments: struct eth_device *dev:          NIC data structure
- * Returns:   void.
- */
-
-static void
-ns8382x_set_rx_mode(struct eth_device *dev)
-{
-       u32 rx_mode = 0x0;
-       /*spec says RxFilterEnable has to be 0 for rest of
-        * this stuff to be properly configured. Linux driver
-        * seems to support this*/
-/*     OUTL(dev, rx_mode, RxFilterAddr);*/
-       rx_mode = (RxFilterEnable | AcceptAllBroadcast | AcceptPerfectMatch);
-       OUTL(dev, rx_mode, RxFilterAddr);
-       printf("ns8382x_set_rx_mode: set to %X\n", rx_mode);
-       /*now we turn RxFilterEnable back on */
-       /*rx_mode |= RxFilterEnable;
-       OUTL(dev, rx_mode, RxFilterAddr);*/
-}
-
-static void
-ns8382x_check_duplex(struct eth_device *dev)
-{
-       int gig = 0;
-       int hun = 0;
-       int duplex = 0;
-       int config = (INL(dev, ChipConfig) ^ SpeedStatus_Polarity);
-
-       duplex = (config & FullDuplex) ? 1 : 0;
-       gig = (config & GigSpeed) ? 1 : 0;
-       hun = (config & HundSpeed) ? 1 : 0;
-#ifdef NS8382X_DEBUG
-       printf("%s: Setting 10%s %s-duplex based on negotiated link"
-              " capability.\n", dev->name, (gig) ? "00" : (hun) ? "0" : "",
-              duplex ? "full" : "half");
-#endif
-       if (duplex) {
-               rx_config |= RxAcceptTx;
-               tx_config |= (TxCarrierIgn | TxHeartIgn);
-       } else {
-               rx_config &= ~RxAcceptTx;
-               tx_config &= ~(TxCarrierIgn | TxHeartIgn);
-       }
-#ifdef NS8382X_DEBUG
-       printf("%s: Resetting TxConfig Register %#08X\n", dev->name, tx_config);
-       printf("%s: Resetting RxConfig Register %#08X\n", dev->name, rx_config);
-#endif
-       OUTL(dev, tx_config, TxConfig);
-       OUTL(dev, rx_config, RxConfig);
-
-       /*if speed is 10 or 100, remove MODE1000,
-        * if it's 1000, then set it */
-       config = INL(dev, ChipConfig);
-       if (gig)
-               config |= Mode1000;
-       else
-               config &= ~Mode1000;
-
-#ifdef NS8382X_DEBUG
-       printf("%s: %setting Mode1000\n", dev->name, (gig) ? "S" : "Uns");
-#endif
-       OUTL(dev, config, ChipConfig);
-}
-
-/* Function: ns8382x_send
- * Description: transmits a packet and waits for completion or timeout.
- * Returns:   void.  */
-static int
-ns8382x_send(struct eth_device *dev, volatile void *packet, int length)
-{
-       u32 i, status = 0;
-       vu_long tx_stat = 0;
-
-       /* Stop the transmitter */
-       OUTL(dev, TxOff, ChipCmd);
-#ifdef NS8382X_DEBUG
-       printf("ns8382x_send: sending %d bytes\n", (int)length);
-#endif
-
-       /* set the transmit buffer descriptor and enable Transmit State Machine */
-       txd.link = cpu_to_le32(0x0);
-       txd.bufptr = cpu_to_le32(phys_to_bus((u32)packet));
-       txd.extsts = cpu_to_le32(0x0);
-       txd.cmdsts = cpu_to_le32(DescOwn | length);
-
-       /* load Transmit Descriptor Register */
-       OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr);
-#ifdef NS8382X_DEBUG
-       printf("ns8382x_send: TX descriptor register loaded with: %#08X\n",
-              INL(dev, TxRingPtr));
-       printf("\ttxd.link:%X\tbufp:%X\texsts:%X\tcmdsts:%X\n",
-              le32_to_cpu(txd.link), le32_to_cpu(txd.bufptr),
-              le32_to_cpu(txd.extsts), le32_to_cpu(txd.cmdsts));
-#endif
-       /* restart the transmitter */
-       OUTL(dev, TxOn, ChipCmd);
-
-       for (i = 0; (tx_stat = le32_to_cpu(txd.cmdsts)) & DescOwn; i++) {
-               if (i >= TOUT_LOOP) {
-                       printf ("%s: tx error buffer not ready: txd.cmdsts %#X\n",
-                            dev->name, tx_stat);
-                       goto Done;
-               }
-       }
-
-       if (!(tx_stat & DescPktOK)) {
-               printf("ns8382x_send: Transmit error, Tx status %X.\n", tx_stat);
-               goto Done;
-       }
-#ifdef NS8382X_DEBUG
-       printf("ns8382x_send: tx_stat: %#08X\n", tx_stat);
-#endif
-
-       status = 1;
-      Done:
-       return status;
-}
-
-/* Function: ns8382x_poll
- * Description: checks for a received packet and returns it if found.
- * Arguments: struct eth_device *dev:          NIC data structure
- * Returns:   1 if    packet was received.
- *            0 if no packet was received.
- * Side effects:
- *            Returns (copies) the packet to the array dev->packet.
- *            Returns the length of the packet.
- */
-
-static int
-ns8382x_poll(struct eth_device *dev)
-{
-       int retstat = 0;
-       int length = 0;
-       vu_long rx_status = le32_to_cpu(rxd[cur_rx].cmdsts);
-
-       if (!(rx_status & (u32) DescOwn))
-               return retstat;
-#ifdef NS8382X_DEBUG
-       printf("ns8382x_poll: got a packet: cur_rx:%u, status:%lx\n",
-              cur_rx, rx_status);
-#endif
-       length = (rx_status & DSIZE) - CRC_SIZE;
-
-       if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) {
-               /* corrupted packet received */
-               printf("ns8382x_poll: Corrupted packet, status:%lx\n", rx_status);
-               retstat = 0;
-       } else {
-               /* give packet to higher level routine */
-               NetReceive((rxb + cur_rx * RX_BUF_SIZE), length);
-               retstat = 1;
-       }
-
-       /* return the descriptor and buffer to receive ring */
-       rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE);
-       rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]);
-
-       if (++cur_rx == NUM_RX_DESC)
-               cur_rx = 0;
-
-       /* re-enable the potentially idle receive state machine */
-       OUTL(dev, RxOn, ChipCmd);
-
-       return retstat;
-}
-
-/* Function: ns8382x_disable
- * Description: Turns off interrupts and stops Tx and Rx engines
- * Arguments: struct eth_device *dev:          NIC data structure
- * Returns:   void.
- */
-
-static void
-ns8382x_disable(struct eth_device *dev)
-{
-       /* Disable interrupts using the mask. */
-       OUTL(dev, 0, IntrMask);
-       OUTL(dev, 0, IntrEnable);
-
-       /* Stop the chip's Tx and Rx processes. */
-       OUTL(dev, (RxOff | TxOff), ChipCmd);
-
-       /* Restore PME enable bit */
-       OUTL(dev, SavedClkRun, ClkRun);
-}
-
-#endif
diff --git a/drivers/ns87308.c b/drivers/ns87308.c
deleted file mode 100644 (file)
index cf4d359..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * (C) Copyright 2000
- * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <config.h>
-
-#ifdef CFG_NS87308
-
-#include <ns87308.h>
-
-void initialise_ns87308 (void)
-{
-#ifdef CFG_NS87308_PS2MOD
-       unsigned char data;
-
-       /*
-        * Switch floppy drive to PS/2 mode.
-        */
-       read_pnp_config(SUPOERIO_CONF1, &data);
-       data &= 0xFB;
-       write_pnp_config(SUPOERIO_CONF1, data);
-#endif
-
-#if (CFG_NS87308_DEVS & CFG_NS87308_KBC1)
-       PNP_SET_DEVICE_BASE(LDEV_KBC1, CFG_NS87308_KBC1_BASE);
-       write_pnp_config(LUN_CONFIG_REG, 0);
-       write_pnp_config(CBASE_HIGH, 0x00);
-       write_pnp_config(CBASE_LOW, 0x64);
-#endif
-
-#if (CFG_NS87308_DEVS & CFG_NS87308_MOUSE)
-       PNP_ACTIVATE_DEVICE(LDEV_MOUSE);
-#endif
-
-#if (CFG_NS87308_DEVS & CFG_NS87308_RTC_APC)
-       PNP_SET_DEVICE_BASE(LDEV_RTC_APC, CFG_NS87308_RTC_BASE);
-#endif
-
-#if (CFG_NS87308_DEVS & CFG_NS87308_FDC)
-       PNP_SET_DEVICE_BASE(LDEV_FDC, CFG_NS87308_FDC_BASE);
-       write_pnp_config(LUN_CONFIG_REG, 0x40);
-#endif
-
-#if (CFG_NS87308_DEVS & CFG_NS87308_RARP)
-       PNP_SET_DEVICE_BASE(LDEV_PARP, CFG_NS87308_LPT_BASE);
-#endif
-
-#if (CFG_NS87308_DEVS & CFG_NS87308_UART1)
-       PNP_SET_DEVICE_BASE(LDEV_UART1, CFG_NS87308_UART1_BASE);
-#endif
-
-#if (CFG_NS87308_DEVS & CFG_NS87308_UART2)
-       PNP_SET_DEVICE_BASE(LDEV_UART2, CFG_NS87308_UART2_BASE);
-#endif
-
-#if (CFG_NS87308_DEVS & CFG_NS87308_GPIO)
-       PNP_SET_DEVICE_BASE(LDEV_GPIO, CFG_NS87308_GPIO_BASE);
-#endif
-
-#if (CFG_NS87308_DEVS & CFG_NS87308_POWRMAN)
-#ifndef CFG_NS87308_PWMAN_BASE
-       PNP_ACTIVATE_DEVICE(LDEV_POWRMAN);
-#else
-       PNP_SET_DEVICE_BASE(LDEV_POWRMAN, CFG_NS87308_PWMAN_BASE);
-
-       /*
-        * Enable all units
-        */
-       write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_FER1, 0x7d);
-       write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_FER2, 0x87);
-
-#ifdef CFG_NS87308_PMC1
-       write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_PMC1, CFG_NS87308_PMC1);
-#endif
-
-#ifdef CFG_NS87308_PMC2
-       write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_PMC2, CFG_NS87308_PMC2);
-#endif
-
-#ifdef CFG_NS87308_PMC3
-       write_pm_reg(CFG_NS87308_PWMAN_BASE, PWM_PMC3, CFG_NS87308_PMC3);
-#endif
-#endif
-#endif
-
-#ifdef CFG_NS87308_CS0_BASE
-       PNP_PGCS_CSLINE_BASE(0, CFG_NS87308_CS0_BASE);
-       PNP_PGCS_CSLINE_CONF(0, CFG_NS87308_CS0_CONF);
-#endif
-
-#ifdef CFG_NS87308_CS1_BASE
-       PNP_PGCS_CSLINE_BASE(1, CFG_NS87308_CS1_BASE);
-       PNP_PGCS_CSLINE_CONF(1, CFG_NS87308_CS1_CONF);
-#endif
-
-#ifdef CFG_NS87308_CS2_BASE
-       PNP_PGCS_CSLINE_BASE(2, CFG_NS87308_CS2_BASE);
-       PNP_PGCS_CSLINE_CONF(2, CFG_NS87308_CS2_CONF);
-#endif
-}
-
-#endif
diff --git a/drivers/ns9750_eth.c b/drivers/ns9750_eth.c
deleted file mode 100644 (file)
index 067ff8e..0000000
+++ /dev/null
@@ -1,797 +0,0 @@
-/***********************************************************************
- *
- * Copyright (C) 2004 by FS Forth-Systeme GmbH.
- * All rights reserved.
- *
- * $Id: ns9750_eth.c,v 1.2 2004/02/24 14:09:39 mpietrek Exp $
- * @Author: Markus Pietrek
- * @Descr: Ethernet driver for the NS9750. Uses DMA Engine with polling
- *        interrupt status. But interrupts are not enabled.
- *        Only one tx buffer descriptor and the RXA buffer descriptor are used
- *        Currently no transmit lockup handling is included. eth_send has a 5s
- *        timeout for sending frames. No retransmits are performed when an
- *        error occurs.
- * @References: [1] NS9750 Hardware Reference, December 2003
- *             [2] Intel LXT971 Datasheet #249414 Rev. 02
- *             [3] NS7520 Linux Ethernet Driver
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- ***********************************************************************/
-
-#include <common.h>
-#include <net.h>               /* NetSendPacket */
-
-#include "ns9750_eth.h"                /* for Ethernet and PHY */
-
-#ifdef CONFIG_DRIVER_NS9750_ETHERNET
-
-/* some definition to make transistion to linux easier */
-
-#define NS9750_DRIVER_NAME     "eth"
-#define KERN_WARNING           "Warning:"
-#define KERN_ERR               "Error:"
-#define KERN_INFO              "Info:"
-
-#if 0
-# define DEBUG
-#endif
-
-#ifdef DEBUG
-# define printk                        printf
-
-# define DEBUG_INIT            0x0001
-# define DEBUG_MINOR           0x0002
-# define DEBUG_RX              0x0004
-# define DEBUG_TX              0x0008
-# define DEBUG_INT             0x0010
-# define DEBUG_POLL            0x0020
-# define DEBUG_LINK            0x0040
-# define DEBUG_MII             0x0100
-# define DEBUG_MII_LOW         0x0200
-# define DEBUG_MEM             0x0400
-# define DEBUG_ERROR           0x4000
-# define DEBUG_ERROR_CRIT      0x8000
-
-static int nDebugLvl = DEBUG_ERROR_CRIT;
-
-# define DEBUG_ARGS0( FLG, a0 ) if( ( nDebugLvl & (FLG) ) == (FLG) ) \
-               printf("%s: " a0, __FUNCTION__, 0, 0, 0, 0, 0, 0 )
-# define DEBUG_ARGS1( FLG, a0, a1 ) if( ( nDebugLvl & (FLG) ) == (FLG)) \
-               printf("%s: " a0, __FUNCTION__, (int)(a1), 0, 0, 0, 0, 0 )
-# define DEBUG_ARGS2( FLG, a0, a1, a2 ) if( (nDebugLvl & (FLG)) ==(FLG))\
-               printf("%s: " a0, __FUNCTION__, (int)(a1), (int)(a2), 0, 0,0,0 )
-# define DEBUG_ARGS3( FLG, a0, a1, a2, a3 ) if((nDebugLvl &(FLG))==(FLG))\
-               printf("%s: "a0,__FUNCTION__,(int)(a1),(int)(a2),(int)(a3),0,0,0)
-# define DEBUG_FN( FLG ) if( (nDebugLvl & (FLG)) == (FLG) ) \
-               printf("\r%s:line %d\n", (int)__FUNCTION__, __LINE__, 0,0,0,0);
-# define ASSERT( expr, func ) if( !( expr ) ) { \
-               printf( "Assertion failed! %s:line %d %s\n", \
-               (int)__FUNCTION__,__LINE__,(int)(#expr),0,0,0); \
-               func }
-#else /* DEBUG */
-# define printk(...)
-# define DEBUG_ARGS0( FLG, a0 )
-# define DEBUG_ARGS1( FLG, a0, a1 )
-# define DEBUG_ARGS2( FLG, a0, a1, a2 )
-# define DEBUG_ARGS3( FLG, a0, a1, a2, a3 )
-# define DEBUG_FN( n )
-# define ASSERT(expr, func)
-#endif /* DEBUG */
-
-#define NS9750_MII_NEG_DELAY           (5*CFG_HZ) /* in s */
-#define TX_TIMEOUT                     (5*CFG_HZ) /* in s */
-
-/* @TODO move it to eeprom.h */
-#define FS_EEPROM_AUTONEG_MASK         0x7
-#define FS_EEPROM_AUTONEG_SPEED_MASK   0x1
-#define FS_EEPROM_AUTONEG_SPEED_10     0x0
-#define FS_EEPROM_AUTONEG_SPEED_100    0x1
-#define FS_EEPROM_AUTONEG_DUPLEX_MASK  0x2
-#define FS_EEPROM_AUTONEG_DUPLEX_HALF  0x0
-#define FS_EEPROM_AUTONEG_DUPLEX_FULL  0x2
-#define FS_EEPROM_AUTONEG_ENABLE_MASK  0x4
-#define FS_EEPROM_AUTONEG_DISABLE      0x0
-#define FS_EEPROM_AUTONEG_ENABLE       0x4
-
-/* buffer descriptors taken from [1] p.306 */
-typedef struct
-{
-       unsigned int* punSrc;
-       unsigned int unLen;     /* 11 bits */
-       unsigned int* punDest;  /* unused */
-       union {
-               unsigned int unReg;
-               struct {
-                       unsigned uStatus : 16;
-                       unsigned uRes : 12;
-                       unsigned uFull : 1;
-                       unsigned uEnable : 1;
-                       unsigned uInt : 1;
-                       unsigned uWrap : 1;
-               } bits;
-       } s;
-} rx_buffer_desc_t;
-
-typedef struct
-{
-       unsigned int* punSrc;
-       unsigned int unLen;     /* 10 bits */
-       unsigned int* punDest;  /* unused */
-       union {
-               unsigned int unReg; /* only 32bit accesses may done to NS9750
-                                    * eth engine */
-               struct {
-                       unsigned uStatus : 16;
-                       unsigned uRes : 12;
-                       unsigned uFull : 1;
-                       unsigned uLast : 1;
-                       unsigned uInt : 1;
-                       unsigned uWrap : 1;
-               } bits;
-       } s;
-} tx_buffer_desc_t;
-
-static int ns9750_eth_reset( void );
-
-static void ns9750_link_force( void );
-static void ns9750_link_auto_negotiate( void );
-static void ns9750_link_update_egcr( void );
-static void ns9750_link_print_changed( void );
-
-/* the PHY stuff */
-
-static char ns9750_mii_identify_phy( void );
-static unsigned short ns9750_mii_read( unsigned short uiRegister );
-static void ns9750_mii_write( unsigned short uiRegister, unsigned short uiData );
-static unsigned int ns9750_mii_get_clock_divisor( unsigned int unMaxMDIOClk );
-static unsigned int ns9750_mii_poll_busy( void );
-
-static unsigned int nPhyMaxMdioClock = PHY_MDIO_MAX_CLK;
-static unsigned char ucLinkMode =      FS_EEPROM_AUTONEG_ENABLE;
-static unsigned int uiLastLinkStatus;
-static PhyType phyDetected = PHY_NONE;
-
-/* we use only one tx buffer descriptor */
-static tx_buffer_desc_t* pTxBufferDesc =
-       (tx_buffer_desc_t*) get_eth_reg_addr( NS9750_ETH_TXBD );
-
-/* we use only one rx buffer descriptor of the 4 */
-static rx_buffer_desc_t aRxBufferDesc[ 4 ];
-
-/***********************************************************************
- * @Function: eth_init
- * @Return: -1 on failure otherwise 0
- * @Descr: Initializes the ethernet engine and uses either FS Forth's default
- *        MAC addr or the one in environment
- ***********************************************************************/
-
-int eth_init (bd_t * pbis)
-{
-       /* This default MAC Addr is reserved by FS Forth-Systeme for the case of
-          EEPROM failures */
-       unsigned char aucMACAddr[6] = { 0x00, 0x04, 0xf3, 0x00, 0x06, 0x35 };
-       char *pcTmp = getenv ("ethaddr");
-       char *pcEnd;
-       int i;
-
-       DEBUG_FN (DEBUG_INIT);
-
-       /* no need to check for hardware */
-
-       if (!ns9750_eth_reset ())
-               return -1;
-
-       if (pcTmp != NULL)
-               for (i = 0; i < 6; i++) {
-                       aucMACAddr[i] =
-                               pcTmp ? simple_strtoul (pcTmp, &pcEnd,
-                                                       16) : 0;
-                       pcTmp = (*pcTmp) ? pcEnd + 1 : pcEnd;
-               }
-
-       /* configure ethernet address */
-
-       *get_eth_reg_addr (NS9750_ETH_SA1) =
-               aucMACAddr[5] << 8 | aucMACAddr[4];
-       *get_eth_reg_addr (NS9750_ETH_SA2) =
-               aucMACAddr[3] << 8 | aucMACAddr[2];
-       *get_eth_reg_addr (NS9750_ETH_SA3) =
-               aucMACAddr[1] << 8 | aucMACAddr[0];
-
-       /* enable hardware */
-
-       *get_eth_reg_addr (NS9750_ETH_MAC1) = NS9750_ETH_MAC1_RXEN;
-
-       /* the linux kernel may give packets < 60 bytes, for example arp */
-       *get_eth_reg_addr (NS9750_ETH_MAC2) = NS9750_ETH_MAC2_CRCEN |
-               NS9750_ETH_MAC2_PADEN | NS9750_ETH_MAC2_HUGE;
-
-       /* enable receive and transmit FIFO, use 10/100 Mbps MII */
-       *get_eth_reg_addr (NS9750_ETH_EGCR1) =
-               NS9750_ETH_EGCR1_ETXWM |
-               NS9750_ETH_EGCR1_ERX |
-               NS9750_ETH_EGCR1_ERXDMA |
-               NS9750_ETH_EGCR1_ETX |
-               NS9750_ETH_EGCR1_ETXDMA | NS9750_ETH_EGCR1_ITXA;
-
-       /* prepare DMA descriptors */
-       for (i = 0; i < 4; i++) {
-               aRxBufferDesc[i].punSrc = 0;
-               aRxBufferDesc[i].unLen = 0;
-               aRxBufferDesc[i].s.bits.uWrap = 1;
-               aRxBufferDesc[i].s.bits.uInt = 1;
-               aRxBufferDesc[i].s.bits.uEnable = 0;
-               aRxBufferDesc[i].s.bits.uFull = 0;
-       }
-
-       /* NetRxPackets[ 0 ] is initialized before eth_init is called and never
-          changes. NetRxPackets is 32bit aligned */
-       aRxBufferDesc[0].punSrc = (unsigned int *) NetRxPackets[0];
-       aRxBufferDesc[0].s.bits.uEnable = 1;
-       aRxBufferDesc[0].unLen = 1522;  /* as stated in [1] p.307 */
-
-       *get_eth_reg_addr (NS9750_ETH_RXAPTR) =
-               (unsigned int) &aRxBufferDesc[0];
-
-       /* [1] Tab. 221 states less than 5us */
-       *get_eth_reg_addr (NS9750_ETH_EGCR1) |= NS9750_ETH_EGCR1_ERXINIT;
-       while (!
-              (*get_eth_reg_addr (NS9750_ETH_EGSR) & NS9750_ETH_EGSR_RXINIT))
-               /* wait for finish */
-               udelay (1);
-
-       /* @TODO do we need to clear RXINIT? */
-       *get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~NS9750_ETH_EGCR1_ERXINIT;
-
-       *get_eth_reg_addr (NS9750_ETH_RXFREE) = 0x1;
-
-       return 0;
-}
-
-/***********************************************************************
- * @Function: eth_send
- * @Return: -1 on timeout otherwise 1
- * @Descr: sends one frame by DMA
- ***********************************************************************/
-
-int eth_send (volatile void *pPacket, int nLen)
-{
-       ulong ulTimeout;
-
-       DEBUG_FN (DEBUG_TX);
-
-       /* clear old status values */
-       *get_eth_reg_addr (NS9750_ETH_EINTR) &=
-               *get_eth_reg_addr (NS9750_ETH_EINTR) & NS9750_ETH_EINTR_TX_MA;
-
-       /* prepare Tx Descriptors */
-
-       pTxBufferDesc->punSrc = (unsigned int *) pPacket;       /* pPacket is 32bit
-                                                                * aligned */
-       pTxBufferDesc->unLen = nLen;
-       /* only 32bit accesses allowed. wrap, full, interrupt and enabled to 1 */
-       pTxBufferDesc->s.unReg = 0xf0000000;
-       /* pTxBufferDesc is the first possible buffer descriptor */
-       *get_eth_reg_addr (NS9750_ETH_TXPTR) = 0x0;
-
-       /* enable processor for next frame */
-
-       *get_eth_reg_addr (NS9750_ETH_EGCR2) &= ~NS9750_ETH_EGCR2_TCLER;
-       *get_eth_reg_addr (NS9750_ETH_EGCR2) |= NS9750_ETH_EGCR2_TCLER;
-
-       ulTimeout = get_timer (0);
-
-       DEBUG_ARGS0 (DEBUG_TX | DEBUG_MINOR,
-                    "Waiting for transmission to finish\n");
-       while (!
-              (*get_eth_reg_addr (NS9750_ETH_EINTR) &
-               (NS9750_ETH_EINTR_TXDONE | NS9750_ETH_EINTR_TXERR))) {
-               /* do nothing, wait for completion */
-               if (get_timer (0) - ulTimeout > TX_TIMEOUT) {
-                       DEBUG_ARGS0 (DEBUG_TX, "Transmit Timed out\n");
-                       return -1;
-               }
-       }
-       DEBUG_ARGS0 (DEBUG_TX | DEBUG_MINOR, "transmitted...\n");
-
-       return 0;
-}
-
-/***********************************************************************
- * @Function: eth_rx
- * @Return: size of last frame in bytes or 0 if no frame available
- * @Descr: gives one frame to U-Boot which has been copied by DMA engine already
- *        to NetRxPackets[ 0 ].
- ***********************************************************************/
-
-int eth_rx (void)
-{
-       int nLen = 0;
-       unsigned int unStatus;
-
-       unStatus =
-               *get_eth_reg_addr (NS9750_ETH_EINTR) & NS9750_ETH_EINTR_RX_MA;
-
-       if (!unStatus)
-               /* no packet available, return immediately */
-               return 0;
-
-       DEBUG_FN (DEBUG_RX);
-
-       /* unLen always < max(nLen) and discard checksum */
-       nLen = (int) aRxBufferDesc[0].unLen - 4;
-
-       /* acknowledge status register */
-       *get_eth_reg_addr (NS9750_ETH_EINTR) = unStatus;
-
-       aRxBufferDesc[0].unLen = 1522;
-       aRxBufferDesc[0].s.bits.uFull = 0;
-
-       /* Buffer A descriptor available again */
-       *get_eth_reg_addr (NS9750_ETH_RXFREE) |= 0x1;
-
-       /* NetReceive may call eth_send. Due to a possible bug of the NS9750 we
-        * have to acknowledge the received frame before sending a new one */
-       if (unStatus & NS9750_ETH_EINTR_RXDONEA)
-               NetReceive (NetRxPackets[0], nLen);
-
-       return nLen;
-}
-
-/***********************************************************************
- * @Function: eth_halt
- * @Return: n/a
- * @Descr: stops the ethernet engine
- ***********************************************************************/
-
-void eth_halt (void)
-{
-       DEBUG_FN (DEBUG_INIT);
-
-       *get_eth_reg_addr (NS9750_ETH_MAC1) &= ~NS9750_ETH_MAC1_RXEN;
-       *get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~(NS9750_ETH_EGCR1_ERX |
-                                                 NS9750_ETH_EGCR1_ERXDMA |
-                                                 NS9750_ETH_EGCR1_ETX |
-                                                 NS9750_ETH_EGCR1_ETXDMA);
-}
-
-/***********************************************************************
- * @Function: ns9750_eth_reset
- * @Return: 0 on failure otherwise 1
- * @Descr: resets the ethernet interface and the PHY,
- *        performs auto negotiation or fixed modes
- ***********************************************************************/
-
-static int ns9750_eth_reset (void)
-{
-       DEBUG_FN (DEBUG_MINOR);
-
-       /* Reset MAC */
-       *get_eth_reg_addr (NS9750_ETH_EGCR1) |= NS9750_ETH_EGCR1_MAC_HRST;
-       udelay (5);             /* according to [1], p.322 */
-       *get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~NS9750_ETH_EGCR1_MAC_HRST;
-
-       /* reset and initialize PHY */
-
-       *get_eth_reg_addr (NS9750_ETH_MAC1) &= ~NS9750_ETH_MAC1_SRST;
-
-       /* we don't support hot plugging of PHY, therefore we don't reset
-          phyDetected and nPhyMaxMdioClock here. The risk is if the setting is
-          incorrect the first open
-          may detect the PHY correctly but succeding will fail
-          For reseting the PHY and identifying we have to use the standard
-          MDIO CLOCK value 2.5 MHz only after hardware reset
-          After having identified the PHY we will do faster */
-
-       *get_eth_reg_addr (NS9750_ETH_MCFG) =
-               ns9750_mii_get_clock_divisor (nPhyMaxMdioClock);
-
-       /* reset PHY */
-       ns9750_mii_write (PHY_COMMON_CTRL, PHY_COMMON_CTRL_RESET);
-       ns9750_mii_write (PHY_COMMON_CTRL, 0);
-
-       /* @TODO check time */
-       udelay (3000);          /* [2] p.70 says at least 300us reset recovery time. But
-                                  go sure, it didn't worked stable at higher timer
-                                  frequencies under LxNETES-2.x */
-
-       /* MII clock has been setup to default, ns9750_mii_identify_phy should
-          work for all */
-
-       if (!ns9750_mii_identify_phy ()) {
-               printk (KERN_ERR NS9750_DRIVER_NAME
-                       ": Unsupported PHY, aborting\n");
-               return 0;
-       }
-
-       /* now take the highest MDIO clock possible after detection */
-       *get_eth_reg_addr (NS9750_ETH_MCFG) =
-               ns9750_mii_get_clock_divisor (nPhyMaxMdioClock);
-
-
-       /* PHY has been detected, so there can be no abort reason and we can
-          finish initializing ethernet */
-
-       uiLastLinkStatus = 0xff;        /* undefined */
-
-       if ((ucLinkMode & FS_EEPROM_AUTONEG_ENABLE_MASK) ==
-           FS_EEPROM_AUTONEG_DISABLE)
-               /* use parameters defined */
-               ns9750_link_force ();
-       else
-               ns9750_link_auto_negotiate ();
-
-       if (phyDetected == PHY_LXT971A)
-               /* set LED2 to link mode */
-               ns9750_mii_write (PHY_LXT971_LED_CFG,
-                                 PHY_LXT971_LED_CFG_LINK_ACT <<
-                                 PHY_LXT971_LED_CFG_SHIFT_LED2);
-
-       return 1;
-}
-
-/***********************************************************************
- * @Function: ns9750_link_force
- * @Return: void
- * @Descr: configures eth and MII to use the link mode defined in
- *        ucLinkMode
- ***********************************************************************/
-
-static void ns9750_link_force (void)
-{
-       unsigned short uiControl;
-
-       DEBUG_FN (DEBUG_LINK);
-
-       uiControl = ns9750_mii_read (PHY_COMMON_CTRL);
-       uiControl &= ~(PHY_COMMON_CTRL_SPD_MA |
-                      PHY_COMMON_CTRL_AUTO_NEG | PHY_COMMON_CTRL_DUPLEX);
-
-       uiLastLinkStatus = 0;
-
-       if ((ucLinkMode & FS_EEPROM_AUTONEG_SPEED_MASK) ==
-           FS_EEPROM_AUTONEG_SPEED_100) {
-               uiControl |= PHY_COMMON_CTRL_SPD_100;
-               uiLastLinkStatus |= PHY_LXT971_STAT2_100BTX;
-       } else
-               uiControl |= PHY_COMMON_CTRL_SPD_10;
-
-       if ((ucLinkMode & FS_EEPROM_AUTONEG_DUPLEX_MASK) ==
-           FS_EEPROM_AUTONEG_DUPLEX_FULL) {
-               uiControl |= PHY_COMMON_CTRL_DUPLEX;
-               uiLastLinkStatus |= PHY_LXT971_STAT2_DUPLEX_MODE;
-       }
-
-       ns9750_mii_write (PHY_COMMON_CTRL, uiControl);
-
-       ns9750_link_print_changed ();
-       ns9750_link_update_egcr ();
-}
-
-/***********************************************************************
- * @Function: ns9750_link_auto_negotiate
- * @Return: void
- * @Descr: performs auto-negotation of link.
- ***********************************************************************/
-
-static void ns9750_link_auto_negotiate (void)
-{
-       unsigned long ulStartJiffies;
-       unsigned short uiStatus;
-
-       DEBUG_FN (DEBUG_LINK);
-
-       /* run auto-negotation */
-       /* define what we are capable of */
-       ns9750_mii_write (PHY_COMMON_AUTO_ADV,
-                         PHY_COMMON_AUTO_ADV_100BTXFD |
-                         PHY_COMMON_AUTO_ADV_100BTX |
-                         PHY_COMMON_AUTO_ADV_10BTFD |
-                         PHY_COMMON_AUTO_ADV_10BT |
-                         PHY_COMMON_AUTO_ADV_802_3);
-       /* start auto-negotiation */
-       ns9750_mii_write (PHY_COMMON_CTRL,
-                         PHY_COMMON_CTRL_AUTO_NEG |
-                         PHY_COMMON_CTRL_RES_AUTO);
-
-       /* wait for completion */
-
-       ulStartJiffies = get_ticks ();
-       while (get_ticks () < ulStartJiffies + NS9750_MII_NEG_DELAY) {
-               uiStatus = ns9750_mii_read (PHY_COMMON_STAT);
-               if ((uiStatus &
-                    (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT)) ==
-                   (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT)) {
-                       /* lucky we are, auto-negotiation succeeded */
-                       ns9750_link_print_changed ();
-                       ns9750_link_update_egcr ();
-                       return;
-               }
-       }
-
-       DEBUG_ARGS0 (DEBUG_LINK, "auto-negotiation timed out\n");
-       /* ignore invalid link settings */
-}
-
-/***********************************************************************
- * @Function: ns9750_link_update_egcr
- * @Return: void
- * @Descr: updates the EGCR and MAC2 link status after mode change or
- *        auto-negotation
- ***********************************************************************/
-
-static void ns9750_link_update_egcr (void)
-{
-       unsigned int unEGCR;
-       unsigned int unMAC2;
-       unsigned int unIPGT;
-
-       DEBUG_FN (DEBUG_LINK);
-
-       unEGCR = *get_eth_reg_addr (NS9750_ETH_EGCR1);
-       unMAC2 = *get_eth_reg_addr (NS9750_ETH_MAC2);
-       unIPGT = *get_eth_reg_addr (NS9750_ETH_IPGT) & ~NS9750_ETH_IPGT_MA;
-
-       unMAC2 &= ~NS9750_ETH_MAC2_FULLD;
-       if ((uiLastLinkStatus & PHY_LXT971_STAT2_DUPLEX_MODE)
-           == PHY_LXT971_STAT2_DUPLEX_MODE) {
-               unMAC2 |= NS9750_ETH_MAC2_FULLD;
-               unIPGT |= 0x15; /* see [1] p. 339 */
-       } else
-               unIPGT |= 0x12; /* see [1] p. 339 */
-
-       *get_eth_reg_addr (NS9750_ETH_MAC2) = unMAC2;
-       *get_eth_reg_addr (NS9750_ETH_EGCR1) = unEGCR;
-       *get_eth_reg_addr (NS9750_ETH_IPGT) = unIPGT;
-}
-
-/***********************************************************************
- * @Function: ns9750_link_print_changed
- * @Return: void
- * @Descr: checks whether the link status has changed and if so prints
- *        the new mode
- ***********************************************************************/
-
-static void ns9750_link_print_changed (void)
-{
-       unsigned short uiStatus;
-       unsigned short uiControl;
-
-       DEBUG_FN (DEBUG_LINK);
-
-       uiControl = ns9750_mii_read (PHY_COMMON_CTRL);
-
-       if ((uiControl & PHY_COMMON_CTRL_AUTO_NEG) ==
-           PHY_COMMON_CTRL_AUTO_NEG) {
-               /* PHY_COMMON_STAT_LNK_STAT is only set on autonegotiation */
-               uiStatus = ns9750_mii_read (PHY_COMMON_STAT);
-
-               if (!(uiStatus & PHY_COMMON_STAT_LNK_STAT)) {
-                       printk (KERN_WARNING NS9750_DRIVER_NAME
-                               ": link down\n");
-                       /* @TODO Linux: carrier_off */
-               } else {
-                       /* @TODO Linux: carrier_on */
-                       if (phyDetected == PHY_LXT971A) {
-                               uiStatus = ns9750_mii_read (PHY_LXT971_STAT2);
-                               uiStatus &= (PHY_LXT971_STAT2_100BTX |
-                                            PHY_LXT971_STAT2_DUPLEX_MODE |
-                                            PHY_LXT971_STAT2_AUTO_NEG);
-
-                               /* mask out all uninteresting parts */
-                       }
-                       /* other PHYs must store there link information in
-                          uiStatus as PHY_LXT971 */
-               }
-       } else {
-               /* mode has been forced, so uiStatus should be the same as the
-                  last link status, enforce printing */
-               uiStatus = uiLastLinkStatus;
-               uiLastLinkStatus = 0xff;
-       }
-
-       if (uiStatus != uiLastLinkStatus) {
-               /* save current link status */
-               uiLastLinkStatus = uiStatus;
-
-               /* print new link status */
-
-               printk (KERN_INFO NS9750_DRIVER_NAME
-                       ": link mode %i Mbps %s duplex %s\n",
-                       (uiStatus & PHY_LXT971_STAT2_100BTX) ? 100 : 10,
-                       (uiStatus & PHY_LXT971_STAT2_DUPLEX_MODE) ? "full" :
-                       "half",
-                       (uiStatus & PHY_LXT971_STAT2_AUTO_NEG) ? "(auto)" :
-                       "");
-       }
-}
-
-/***********************************************************************
- * the MII low level stuff
- ***********************************************************************/
-
-/***********************************************************************
- * @Function: ns9750_mii_identify_phy
- * @Return: 1 if supported PHY has been detected otherwise 0
- * @Descr: checks for supported PHY and prints the IDs.
- ***********************************************************************/
-
-static char ns9750_mii_identify_phy (void)
-{
-       unsigned short uiID1;
-       unsigned short uiID2;
-       unsigned char *szName;
-       char cRes = 0;
-
-       DEBUG_FN (DEBUG_MII);
-
-       phyDetected = (PhyType) uiID1 = ns9750_mii_read (PHY_COMMON_ID1);
-
-       switch (phyDetected) {
-       case PHY_LXT971A:
-               szName = "LXT971A";
-               uiID2 = ns9750_mii_read (PHY_COMMON_ID2);
-               nPhyMaxMdioClock = PHY_LXT971_MDIO_MAX_CLK;
-               cRes = 1;
-               break;
-       case PHY_NONE:
-       default:
-               /* in case uiID1 == 0 && uiID2 == 0 we may have the wrong
-                  address or reset sets the wrong NS9750_ETH_MCFG_CLKS */
-
-               uiID2 = 0;
-               szName = "unknown";
-               nPhyMaxMdioClock = PHY_MDIO_MAX_CLK;
-               phyDetected = PHY_NONE;
-       }
-
-       printk (KERN_INFO NS9750_DRIVER_NAME
-               ": PHY (0x%x, 0x%x) = %s detected\n", uiID1, uiID2, szName);
-
-       return cRes;
-}
-
-/***********************************************************************
- * @Function: ns9750_mii_read
- * @Return: the data read from PHY register uiRegister
- * @Descr: the data read may be invalid if timed out. If so, a message
- *        is printed but the invalid data is returned.
- *        The fixed device address is being used.
- ***********************************************************************/
-
-static unsigned short ns9750_mii_read (unsigned short uiRegister)
-{
-       DEBUG_FN (DEBUG_MII_LOW);
-
-       /* write MII register to be read */
-       *get_eth_reg_addr (NS9750_ETH_MADR) =
-               NS9750_ETH_PHY_ADDRESS << 8 | uiRegister;
-
-       *get_eth_reg_addr (NS9750_ETH_MCMD) = NS9750_ETH_MCMD_READ;
-
-       if (!ns9750_mii_poll_busy ())
-               printk (KERN_WARNING NS9750_DRIVER_NAME
-                       ": MII still busy in read\n");
-       /* continue to read */
-
-       *get_eth_reg_addr (NS9750_ETH_MCMD) = 0;
-
-       return (unsigned short) (*get_eth_reg_addr (NS9750_ETH_MRDD));
-}
-
-
-/***********************************************************************
- * @Function: ns9750_mii_write
- * @Return: nothing
- * @Descr: writes the data to the PHY register. In case of a timeout,
- *        no special handling is performed but a message printed
- *        The fixed device address is being used.
- ***********************************************************************/
-
-static void ns9750_mii_write (unsigned short uiRegister,
-                             unsigned short uiData)
-{
-       DEBUG_FN (DEBUG_MII_LOW);
-
-       /* write MII register to be written */
-       *get_eth_reg_addr (NS9750_ETH_MADR) =
-               NS9750_ETH_PHY_ADDRESS << 8 | uiRegister;
-
-       *get_eth_reg_addr (NS9750_ETH_MWTD) = uiData;
-
-       if (!ns9750_mii_poll_busy ()) {
-               printf (KERN_WARNING NS9750_DRIVER_NAME
-                       ": MII still busy in write\n");
-       }
-}
-
-
-/***********************************************************************
- * @Function: ns9750_mii_get_clock_divisor
- * @Return: the clock divisor that should be used in NS9750_ETH_MCFG_CLKS
- * @Descr: if no clock divisor can be calculated for the
- *        current SYSCLK and the maximum MDIO Clock, a warning is printed
- *        and the greatest divisor is taken
- ***********************************************************************/
-
-static unsigned int ns9750_mii_get_clock_divisor (unsigned int unMaxMDIOClk)
-{
-       struct {
-               unsigned int unSysClkDivisor;
-               unsigned int unClks;    /* field for NS9750_ETH_MCFG_CLKS */
-       } PHYClockDivisors[] = {
-               {
-               4, NS9750_ETH_MCFG_CLKS_4}, {
-               6, NS9750_ETH_MCFG_CLKS_6}, {
-               8, NS9750_ETH_MCFG_CLKS_8}, {
-               10, NS9750_ETH_MCFG_CLKS_10}, {
-               20, NS9750_ETH_MCFG_CLKS_20}, {
-               30, NS9750_ETH_MCFG_CLKS_30}, {
-               40, NS9750_ETH_MCFG_CLKS_40}
-       };
-
-       int nIndexSysClkDiv;
-       int nArraySize =
-               sizeof (PHYClockDivisors) / sizeof (PHYClockDivisors[0]);
-       unsigned int unClks = NS9750_ETH_MCFG_CLKS_40;  /* defaults to
-                                                          greatest div */
-
-       DEBUG_FN (DEBUG_INIT);
-
-       for (nIndexSysClkDiv = 0; nIndexSysClkDiv < nArraySize;
-            nIndexSysClkDiv++) {
-               /* find first sysclock divisor that isn't higher than 2.5 MHz
-                  clock */
-               if (AHB_CLK_FREQ /
-                   PHYClockDivisors[nIndexSysClkDiv].unSysClkDivisor <=
-                   unMaxMDIOClk) {
-                       unClks = PHYClockDivisors[nIndexSysClkDiv].unClks;
-                       break;
-               }
-       }
-
-       DEBUG_ARGS2 (DEBUG_INIT,
-                    "Taking MDIO Clock bit mask 0x%0x for max clock %i\n",
-                    unClks, unMaxMDIOClk);
-
-       /* return greatest divisor */
-       return unClks;
-}
-
-/***********************************************************************
- * @Function: ns9750_mii_poll_busy
- * @Return: 0 if timed out otherwise the remaing timeout
- * @Descr: waits until the MII has completed a command or it times out
- *        code may be interrupted by hard interrupts.
- *        It is not checked what happens on multiple actions when
- *        the first is still being busy and we timeout.
- ***********************************************************************/
-
-static unsigned int ns9750_mii_poll_busy (void)
-{
-       unsigned int unTimeout = 10000;
-
-       DEBUG_FN (DEBUG_MII_LOW);
-
-       while (((*get_eth_reg_addr (NS9750_ETH_MIND) & NS9750_ETH_MIND_BUSY)
-               == NS9750_ETH_MIND_BUSY) && unTimeout)
-               unTimeout--;
-
-       return unTimeout;
-}
-
-#endif /* CONFIG_DRIVER_NS9750_ETHERNET */
diff --git a/drivers/ns9750_serial.c b/drivers/ns9750_serial.c
deleted file mode 100644 (file)
index 02c0d39..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/***********************************************************************
- *
- * Copyright (C) 2004 by FS Forth-Systeme GmbH.
- * All rights reserved.
- *
- * $Id: ns9750_serial.c,v 1.1 2004/02/16 10:37:20 mpietrek Exp $
- * @Author: Markus Pietrek
- * @Descr: Serial driver for the NS9750. Only one UART is supported yet.
- * @References: [1] NS9750 Hardware Reference/December 2003
- * @TODO: Implement Character GAP Timer when chip is fixed for PLL bypass
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- ***********************************************************************/
-
-#include <common.h>
-
-#ifdef CFG_NS9750_UART
-
-#include "ns9750_bbus.h"       /* for GPIOs */
-#include "ns9750_ser.h"                /* for serial configuration */
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#if !defined(CONFIG_CONS_INDEX)
-#error "No console index specified."
-#endif
-
-#define CONSOLE CONFIG_CONS_INDEX
-
-static unsigned int calcBitrateRegister( void );
-static unsigned int calcRxCharGapRegister( void );
-
-static char cCharsAvailable; /* Numbers of chars in unCharCache */
-static unsigned int unCharCache; /* unCharCache is only valid if
-                                 * cCharsAvailable > 0 */
-
-/***********************************************************************
- * @Function: serial_init
- * @Return: 0
- * @Descr: configures GPIOs and UART. Requires BBUS Master Reset turned off
- ***********************************************************************/
-
-int serial_init( void )
-{
-       unsigned int aunGPIOTxD[] = { 0, 8, 40, 44 };
-       unsigned int aunGPIORxD[] = { 1, 9, 41, 45 };
-
-       cCharsAvailable = 0;
-
-       /* configure TxD and RxD pins for their special function */
-       set_gpio_cfg_reg_val( aunGPIOTxD[ CONSOLE ],
-                             NS9750_GPIO_CFG_FUNC_0 | NS9750_GPIO_CFG_OUTPUT );
-       set_gpio_cfg_reg_val( aunGPIORxD[ CONSOLE ],
-                             NS9750_GPIO_CFG_FUNC_0 | NS9750_GPIO_CFG_INPUT );
-
-       /* configure serial engine */
-       *get_ser_reg_addr_channel( NS9750_SER_CTRL_A, CONSOLE ) =
-               NS9750_SER_CTRL_A_CE |
-               NS9750_SER_CTRL_A_STOP |
-               NS9750_SER_CTRL_A_WLS_8;
-
-       serial_setbrg();
-
-       *get_ser_reg_addr_channel( NS9750_SER_CTRL_B, CONSOLE ) =
-               NS9750_SER_CTRL_B_RCGT;
-
-       return 0;
-}
-
-/***********************************************************************
- * @Function: serial_putc
- * @Return: n/a
- * @Descr: writes one character to the FIFO. Blocks until FIFO is not full
- ***********************************************************************/
-
-void serial_putc( const char c )
-{
-       if (c == '\n')
-               serial_putc( '\r' );
-
-       while (!(*get_ser_reg_addr_channel( NS9750_SER_STAT_A, CONSOLE) &
-                NS9750_SER_STAT_A_TRDY ) ) {
-               /* do nothing, wait for characters in FIFO sent */
-       }
-
-       *(volatile char*) get_ser_reg_addr_channel( NS9750_SER_FIFO,
-                                                   CONSOLE) = c;
-}
-
-/***********************************************************************
- * @Function: serial_puts
- * @Return: n/a
- * @Descr: writes non-zero string to the FIFO.
- ***********************************************************************/
-
-void serial_puts( const char *s )
-{
-       while (*s) {
-               serial_putc( *s++ );
-       }
-}
-
-/***********************************************************************
- * @Function: serial_getc
- * @Return: the character read
- * @Descr: performs only 8bit accesses to the FIFO. No error handling
- ***********************************************************************/
-
-int serial_getc( void )
-{
-       int i;
-
-       while (!serial_tstc() ) {
-               /* do nothing, wait for incoming characters */
-       }
-
-       /*  at least one character in unCharCache */
-       i = (int) (unCharCache & 0xff);
-
-       unCharCache >>= 8;
-       cCharsAvailable--;
-
-       return i;
-}
-
-/***********************************************************************
- * @Function: serial_tstc
- * @Return: 0 if no input available, otherwise != 0
- * @Descr: checks for incoming FIFO not empty. Stores the incoming chars in
- *        unCharCache and the numbers of characters in cCharsAvailable
- ***********************************************************************/
-
-int serial_tstc( void )
-{
-       unsigned int unRegCache;
-
-       if ( cCharsAvailable )
-               return 1;
-
-       unRegCache = *get_ser_reg_addr_channel( NS9750_SER_STAT_A,CONSOLE );
-       if( unRegCache & NS9750_SER_STAT_A_RBC ) {
-               *get_ser_reg_addr_channel( NS9750_SER_STAT_A, CONSOLE ) =
-                       NS9750_SER_STAT_A_RBC;
-               unRegCache = *get_ser_reg_addr_channel( NS9750_SER_STAT_A,
-                                                       CONSOLE );
-       }
-
-       if ( unRegCache & NS9750_SER_STAT_A_RRDY ) {
-               cCharsAvailable = (unRegCache & NS9750_SER_STAT_A_RXFDB_MA)>>20;
-               if ( !cCharsAvailable )
-                       cCharsAvailable = 4;
-
-               unCharCache = *get_ser_reg_addr_channel( NS9750_SER_FIFO,
-                                                        CONSOLE );
-               return 1;
-       }
-
-       /* no chars available */
-       return 0;
-}
-
-void serial_setbrg( void )
-{
-       *get_ser_reg_addr_channel( NS9750_SER_BITRATE, CONSOLE ) =
-               calcBitrateRegister();
-       *get_ser_reg_addr_channel( NS9750_SER_RX_CHAR_TIMER, CONSOLE ) =
-               calcRxCharGapRegister();
-}
-
-/***********************************************************************
- * @Function: calcBitrateRegister
- * @Return: value for the serial bitrate register
- * @Descr: register value depends on clock frequency and baudrate
- ***********************************************************************/
-
-static unsigned int calcBitrateRegister( void )
-{
-       return ( NS9750_SER_BITRATE_EBIT |
-                NS9750_SER_BITRATE_CLKMUX_BCLK |
-                NS9750_SER_BITRATE_TMODE |
-                NS9750_SER_BITRATE_TCDR_16 |
-                NS9750_SER_BITRATE_RCDR_16 |
-                ( ( ( ( CONFIG_SYS_CLK_FREQ / 8 ) / /* BBUS clock,[1] Fig. 38 */
-                      ( gd->baudrate * 16 ) ) - 1 ) &
-                  NS9750_SER_BITRATE_N_MA ) );
-}
-
-/***********************************************************************
- * @Function: calcRxCharGapRegister
- * @Return: value for the character gap timer register
- * @Descr: register value depends on clock frequency and baudrate. Currently 0
- *        is used as there is a bug with the gap timer in PLL bypass mode.
- ***********************************************************************/
-
-static unsigned int calcRxCharGapRegister( void )
-{
-       return NS9750_SER_RX_CHAR_TIMER_TRUN;
-}
-
-#endif /* CFG_NS9750_UART */
diff --git a/drivers/omap1510_i2c.c b/drivers/omap1510_i2c.c
deleted file mode 100644 (file)
index 04400fb..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Basic I2C functions
- *
- * Copyright (c) 2003 Texas Instruments
- *
- * This package is free software;  you can redistribute it and/or
- * modify it under the terms of the license found in the file
- * named COPYING that should have accompanied this file.
- *
- * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Author: Jian Zhang jzhang@ti.com, Texas Instruments
- *
- * Copyright (c) 2003 Wolfgang Denk, wd@denx.de
- * Rewritten to fit into the current U-Boot framework
- *
- */
-
-#include <common.h>
-
-#ifdef CONFIG_DRIVER_OMAP1510_I2C
-
-static void wait_for_bb (void);
-static u16 wait_for_pin (void);
-
-void i2c_init (int speed, int slaveadd)
-{
-       u16 scl;
-
-       if (inw (I2C_CON) & I2C_CON_EN) {
-               outw (0, I2C_CON);
-               udelay (5000);
-       }
-
-       /* 12Mhz I2C module clock */
-       outw (0, I2C_PSC);
-       outw (I2C_CON_EN, I2C_CON);
-       outw (0, I2C_SYSTEST);
-       /* have to enable intrrupts or OMAP i2c module doesn't work */
-       outw (I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
-             I2C_IE_NACK_IE | I2C_IE_AL_IE, I2C_IE);
-       scl = (12000000 / 2) / speed - 6;
-       outw (scl, I2C_SCLL);
-       outw (scl, I2C_SCLH);
-       /* own address */
-       outw (slaveadd, I2C_OA);
-       outw (0, I2C_CNT);
-       udelay (1000);
-}
-
-static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
-{
-       int i2c_error = 0;
-       u16 status;
-
-       /* wait until bus not busy */
-       wait_for_bb ();
-
-       /* one byte only */
-       outw (1, I2C_CNT);
-       /* set slave address */
-       outw (devaddr, I2C_SA);
-       /* no stop bit needed here */
-       outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON);
-
-       status = wait_for_pin ();
-
-       if (status & I2C_STAT_XRDY) {
-               /* Important: have to use byte access */
-               *(volatile u8 *) (I2C_DATA) = regoffset;
-               udelay (20000);
-               if (inw (I2C_STAT) & I2C_STAT_NACK) {
-                       i2c_error = 1;
-               }
-       } else {
-               i2c_error = 1;
-       }
-
-       if (!i2c_error) {
-               /* free bus, otherwise we can't use a combined transction */
-               outw (0, I2C_CON);
-               while (inw (I2C_STAT) || (inw (I2C_CON) & I2C_CON_MST)) {
-                       udelay (10000);
-                       /* Have to clear pending interrupt to clear I2C_STAT */
-                       inw (I2C_IV);
-               }
-
-               wait_for_bb ();
-               /* set slave address */
-               outw (devaddr, I2C_SA);
-               /* read one byte from slave */
-               outw (1, I2C_CNT);
-               /* need stop bit here */
-               outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP,
-                     I2C_CON);
-
-               status = wait_for_pin ();
-               if (status & I2C_STAT_RRDY) {
-                       *value = inw (I2C_DATA);
-                       udelay (20000);
-               } else {
-                       i2c_error = 1;
-               }
-
-               if (!i2c_error) {
-                       outw (I2C_CON_EN, I2C_CON);
-                       while (inw (I2C_STAT)
-                              || (inw (I2C_CON) & I2C_CON_MST)) {
-                               udelay (10000);
-                               inw (I2C_IV);
-                       }
-               }
-       }
-
-       return i2c_error;
-}
-
-static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value)
-{
-       int i2c_error = 0;
-       u16 status;
-
-       /* wait until bus not busy */
-       wait_for_bb ();
-
-       /* two bytes */
-       outw (2, I2C_CNT);
-       /* set slave address */
-       outw (devaddr, I2C_SA);
-       /* stop bit needed here */
-       outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
-             I2C_CON_STP, I2C_CON);
-
-       /* wait until state change */
-       status = wait_for_pin ();
-
-       if (status & I2C_STAT_XRDY) {
-               /* send out two bytes */
-               outw ((value << 8) + regoffset, I2C_DATA);
-               /* must have enough delay to allow BB bit to go low */
-               udelay (30000);
-               if (inw (I2C_STAT) & I2C_STAT_NACK) {
-                       i2c_error = 1;
-               }
-       } else {
-               i2c_error = 1;
-       }
-
-       if (!i2c_error) {
-               outw (I2C_CON_EN, I2C_CON);
-               while (inw (I2C_STAT) || (inw (I2C_CON) & I2C_CON_MST)) {
-                       udelay (1000);
-                       /* have to read to clear intrrupt */
-                       inw (I2C_IV);
-               }
-       }
-
-       return i2c_error;
-}
-
-int i2c_probe (uchar chip)
-{
-       int res = 1;
-
-       if (chip == inw (I2C_OA)) {
-               return res;
-       }
-
-       /* wait until bus not busy */
-       wait_for_bb ();
-
-       /* try to read one byte */
-       outw (1, I2C_CNT);
-       /* set slave address */
-       outw (chip, I2C_SA);
-       /* stop bit needed here */
-       outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON);
-       /* enough delay for the NACK bit set */
-       udelay (2000);
-       if (!(inw (I2C_STAT) & I2C_STAT_NACK)) {
-               res = 0;
-       } else {
-               outw (inw (I2C_CON) | I2C_CON_STP, I2C_CON);
-               udelay (20);
-               wait_for_bb ();
-       }
-
-       return res;
-}
-
-int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
-{
-       int i;
-
-       if (alen > 1) {
-               printf ("I2C read: addr len %d not supported\n", alen);
-               return 1;
-       }
-
-       if (addr + len > 256) {
-               printf ("I2C read: address out of range\n");
-               return 1;
-       }
-
-       for (i = 0; i < len; i++) {
-               if (i2c_read_byte (chip, addr + i, &buffer[i])) {
-                       printf ("I2C read: I/O error\n");
-                       i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
-int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
-{
-       int i;
-
-       if (alen > 1) {
-               printf ("I2C read: addr len %d not supported\n", alen);
-               return 1;
-       }
-
-       if (addr + len > 256) {
-               printf ("I2C read: address out of range\n");
-               return 1;
-       }
-
-       for (i = 0; i < len; i++) {
-               if (i2c_write_byte (chip, addr + i, buffer[i])) {
-                       printf ("I2C read: I/O error\n");
-                       i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
-static void wait_for_bb (void)
-{
-       int timeout = 10;
-
-       while ((inw (I2C_STAT) & I2C_STAT_BB) && timeout--) {
-               inw (I2C_IV);
-               udelay (1000);
-       }
-
-       if (timeout <= 0) {
-               printf ("timed out in wait_for_bb: I2C_STAT=%x\n",
-                       inw (I2C_STAT));
-       }
-}
-
-static u16 wait_for_pin (void)
-{
-       u16 status, iv;
-       int timeout = 10;
-
-       do {
-               udelay (1000);
-               status = inw (I2C_STAT);
-               iv = inw (I2C_IV);
-       } while (!iv &&
-                !(status &
-                  (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
-                   I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
-                   I2C_STAT_AL)) && timeout--);
-
-       if (timeout <= 0) {
-               printf ("timed out in wait_for_pin: I2C_STAT=%x\n",
-                       inw (I2C_STAT));
-       }
-
-       return status;
-}
-
-#endif /* CONFIG_DRIVER_OMAP1510_I2C */
diff --git a/drivers/omap24xx_i2c.c b/drivers/omap24xx_i2c.c
deleted file mode 100644 (file)
index 7dab786..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Basic I2C functions
- *
- * Copyright (c) 2004 Texas Instruments
- *
- * This package is free software;  you can redistribute it and/or
- * modify it under the terms of the license found in the file
- * named COPYING that should have accompanied this file.
- *
- * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Author: Jian Zhang jzhang@ti.com, Texas Instruments
- *
- * Copyright (c) 2003 Wolfgang Denk, wd@denx.de
- * Rewritten to fit into the current U-Boot framework
- *
- * Adapted for OMAP2420 I2C, r-woodruff2@ti.com
- *
- */
-
-#include <common.h>
-
-#ifdef CONFIG_DRIVER_OMAP24XX_I2C
-
-#include <asm/arch/i2c.h>
-#include <asm/io.h>
-
-#define inw(a) __raw_readw(a)
-#define outw(a,v) __raw_writew(a,v)
-
-static void wait_for_bb (void);
-static u16 wait_for_pin (void);
-static void flush_fifo(void);
-
-void i2c_init (int speed, int slaveadd)
-{
-       u16 scl;
-
-       outw(0x2, I2C_SYSC); /* for ES2 after soft reset */
-       udelay(1000);
-       outw(0x0, I2C_SYSC); /* will probably self clear but */
-
-       if (inw (I2C_CON) & I2C_CON_EN) {
-               outw (0, I2C_CON);
-               udelay (50000);
-       }
-
-       /* 12Mhz I2C module clock */
-       outw (0, I2C_PSC);
-       speed = speed/1000;                 /* 100 or 400 */
-       scl = ((12000/(speed*2)) - 7);  /* use 7 when PSC = 0 */
-       outw (scl, I2C_SCLL);
-       outw (scl, I2C_SCLH);
-       /* own address */
-       outw (slaveadd, I2C_OA);
-       outw (I2C_CON_EN, I2C_CON);
-
-       /* have to enable intrrupts or OMAP i2c module doesn't work */
-       outw (I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
-             I2C_IE_NACK_IE | I2C_IE_AL_IE, I2C_IE);
-       udelay (1000);
-       flush_fifo();
-       outw (0xFFFF, I2C_STAT);
-       outw (0, I2C_CNT);
-}
-
-static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
-{
-       int i2c_error = 0;
-       u16 status;
-
-       /* wait until bus not busy */
-       wait_for_bb ();
-
-       /* one byte only */
-       outw (1, I2C_CNT);
-       /* set slave address */
-       outw (devaddr, I2C_SA);
-       /* no stop bit needed here */
-       outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON);
-
-       status = wait_for_pin ();
-
-       if (status & I2C_STAT_XRDY) {
-               /* Important: have to use byte access */
-               *(volatile u8 *) (I2C_DATA) = regoffset;
-               udelay (20000);
-               if (inw (I2C_STAT) & I2C_STAT_NACK) {
-                       i2c_error = 1;
-               }
-       } else {
-               i2c_error = 1;
-       }
-
-       if (!i2c_error) {
-               /* free bus, otherwise we can't use a combined transction */
-               outw (0, I2C_CON);
-               while (inw (I2C_STAT) || (inw (I2C_CON) & I2C_CON_MST)) {
-                       udelay (10000);
-                       /* Have to clear pending interrupt to clear I2C_STAT */
-                       outw (0xFFFF, I2C_STAT);
-               }
-
-               wait_for_bb ();
-               /* set slave address */
-               outw (devaddr, I2C_SA);
-               /* read one byte from slave */
-               outw (1, I2C_CNT);
-               /* need stop bit here */
-               outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP,
-                     I2C_CON);
-
-               status = wait_for_pin ();
-               if (status & I2C_STAT_RRDY) {
-                       *value = inw (I2C_DATA);
-                       udelay (20000);
-               } else {
-                       i2c_error = 1;
-               }
-
-               if (!i2c_error) {
-                       outw (I2C_CON_EN, I2C_CON);
-                       while (inw (I2C_STAT)
-                              || (inw (I2C_CON) & I2C_CON_MST)) {
-                               udelay (10000);
-                               outw (0xFFFF, I2C_STAT);
-                       }
-               }
-       }
-       flush_fifo();
-       outw (0xFFFF, I2C_STAT);
-       outw (0, I2C_CNT);
-       return i2c_error;
-}
-
-static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value)
-{
-       int i2c_error = 0;
-       u16 status, stat;
-
-       /* wait until bus not busy */
-       wait_for_bb ();
-
-       /* two bytes */
-       outw (2, I2C_CNT);
-       /* set slave address */
-       outw (devaddr, I2C_SA);
-       /* stop bit needed here */
-       outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
-             I2C_CON_STP, I2C_CON);
-
-       /* wait until state change */
-       status = wait_for_pin ();
-
-       if (status & I2C_STAT_XRDY) {
-               /* send out two bytes */
-               outw ((value << 8) + regoffset, I2C_DATA);
-               /* must have enough delay to allow BB bit to go low */
-               udelay (50000);
-               if (inw (I2C_STAT) & I2C_STAT_NACK) {
-                       i2c_error = 1;
-               }
-       } else {
-               i2c_error = 1;
-       }
-
-       if (!i2c_error) {
-               int eout = 200;
-
-               outw (I2C_CON_EN, I2C_CON);
-               while ((stat = inw (I2C_STAT)) || (inw (I2C_CON) & I2C_CON_MST)) {
-                       udelay (1000);
-                       /* have to read to clear intrrupt */
-                       outw (0xFFFF, I2C_STAT);
-                       if(--eout == 0) /* better leave with error than hang */
-                               break;
-               }
-       }
-       flush_fifo();
-       outw (0xFFFF, I2C_STAT);
-       outw (0, I2C_CNT);
-       return i2c_error;
-}
-
-static void flush_fifo(void)
-{      u16 stat;
-
-       /* note: if you try and read data when its not there or ready
-        * you get a bus error
-        */
-       while(1){
-               stat = inw(I2C_STAT);
-               if(stat == I2C_STAT_RRDY){
-                       inw(I2C_DATA);
-                       outw(I2C_STAT_RRDY,I2C_STAT);
-                       udelay(1000);
-               }else
-                       break;
-       }
-}
-
-int i2c_probe (uchar chip)
-{
-       int res = 1; /* default = fail */
-
-       if (chip == inw (I2C_OA)) {
-               return res;
-       }
-
-       /* wait until bus not busy */
-       wait_for_bb ();
-
-       /* try to read one byte */
-       outw (1, I2C_CNT);
-       /* set slave address */
-       outw (chip, I2C_SA);
-       /* stop bit needed here */
-       outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON);
-       /* enough delay for the NACK bit set */
-       udelay (50000);
-
-       if (!(inw (I2C_STAT) & I2C_STAT_NACK)) {
-               res = 0;      /* success case */
-               flush_fifo();
-               outw(0xFFFF, I2C_STAT);
-       } else {
-               outw(0xFFFF, I2C_STAT);  /* failue, clear sources*/
-               outw (inw (I2C_CON) | I2C_CON_STP, I2C_CON); /* finish up xfer */
-               udelay(20000);
-               wait_for_bb ();
-       }
-       flush_fifo();
-       outw (0, I2C_CNT); /* don't allow any more data in...we don't want it.*/
-       outw(0xFFFF, I2C_STAT);
-       return res;
-}
-
-int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
-{
-       int i;
-
-       if (alen > 1) {
-               printf ("I2C read: addr len %d not supported\n", alen);
-               return 1;
-       }
-
-       if (addr + len > 256) {
-               printf ("I2C read: address out of range\n");
-               return 1;
-       }
-
-       for (i = 0; i < len; i++) {
-               if (i2c_read_byte (chip, addr + i, &buffer[i])) {
-                       printf ("I2C read: I/O error\n");
-                       i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
-int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
-{
-       int i;
-
-       if (alen > 1) {
-               printf ("I2C read: addr len %d not supported\n", alen);
-               return 1;
-       }
-
-       if (addr + len > 256) {
-               printf ("I2C read: address out of range\n");
-               return 1;
-       }
-
-       for (i = 0; i < len; i++) {
-               if (i2c_write_byte (chip, addr + i, buffer[i])) {
-                       printf ("I2C read: I/O error\n");
-                       i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
-static void wait_for_bb (void)
-{
-       int timeout = 10;
-       u16 stat;
-
-       outw(0xFFFF, I2C_STAT);  /* clear current interruts...*/
-       while ((stat = inw (I2C_STAT) & I2C_STAT_BB) && timeout--) {
-               outw (stat, I2C_STAT);
-               udelay (50000);
-       }
-
-       if (timeout <= 0) {
-               printf ("timed out in wait_for_bb: I2C_STAT=%x\n",
-                       inw (I2C_STAT));
-       }
-       outw(0xFFFF, I2C_STAT);  /* clear delayed stuff*/
-}
-
-static u16 wait_for_pin (void)
-{
-       u16 status;
-       int timeout = 10;
-
-       do {
-               udelay (1000);
-               status = inw (I2C_STAT);
-       } while (  !(status &
-                  (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
-                   I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
-                   I2C_STAT_AL)) && timeout--);
-
-       if (timeout <= 0) {
-               printf ("timed out in wait_for_pin: I2C_STAT=%x\n",
-                       inw (I2C_STAT));
-                       outw(0xFFFF, I2C_STAT);
-}
-       return status;
-}
-
-#endif /* CONFIG_DRIVER_OMAP24XX_I2C */
diff --git a/drivers/onenand/Makefile b/drivers/onenand/Makefile
deleted file mode 100644 (file)
index 2049413..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# Copyright (C) 2005-2007 Samsung Electronics.
-# Kyungmin Park <kyungmin.park@samsung.com>
-#
-# See file CREDITS for list of people who contributed to this
-# project.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-# MA 02111-1307 USA
-#
-
-include $(TOPDIR)/config.mk
-
-LIB    := $(obj)libonenand.a
-
-COBJS  := onenand_base.o onenand_bbt.o
-
-SRCS   := $(COBJS:.o=.c)
-OBJS   := $(addprefix $(obj),$(COBJS))
-
-all:   $(LIB)
-
-$(LIB): $(obj).depend $(OBJS)
-       $(AR) $(ARFLAGS) $@ $(OBJS)
-
-#########################################################################
-
-include $(SRCTREE)/rules.mk
-
-sinclude $(obj).depend
-
-#########################################################################
diff --git a/drivers/onenand/onenand_base.c b/drivers/onenand/onenand_base.c
deleted file mode 100644 (file)
index 7983a4a..0000000
+++ /dev/null
@@ -1,1294 +0,0 @@
-/*
- *  linux/drivers/mtd/onenand/onenand_base.c
- *
- *  Copyright (C) 2005-2007 Samsung Electronics
- *  Kyungmin Park <kyungmin.park@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <common.h>
-
-#ifdef CONFIG_CMD_ONENAND
-
-#include <linux/mtd/compat.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/onenand.h>
-
-#include <asm/io.h>
-#include <asm/errno.h>
-
-static const unsigned char ffchars[] = {
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 */
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 32 */
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */
-};
-
-/**
- * onenand_readw - [OneNAND Interface] Read OneNAND register
- * @param addr         address to read
- *
- * Read OneNAND register
- */
-static unsigned short onenand_readw(void __iomem * addr)
-{
-       return readw(addr);
-}
-
-/**
- * onenand_writew - [OneNAND Interface] Write OneNAND register with value
- * @param value                value to write
- * @param addr         address to write
- *
- * Write OneNAND register with value
- */
-static void onenand_writew(unsigned short value, void __iomem * addr)
-{
-       writew(value, addr);
-}
-
-/**
- * onenand_block_address - [DEFAULT] Get block address
- * @param device       the device id
- * @param block                the block
- * @return             translated block address if DDP, otherwise same
- *
- * Setup Start Address 1 Register (F100h)
- */
-static int onenand_block_address(int device, int block)
-{
-       if (device & ONENAND_DEVICE_IS_DDP) {
-               /* Device Flash Core select, NAND Flash Block Address */
-               int dfs = 0, density, mask;
-
-               density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
-               mask = (1 << (density + 6));
-
-               if (block & mask)
-                       dfs = 1;
-
-               return (dfs << ONENAND_DDP_SHIFT) | (block & (mask - 1));
-       }
-
-       return block;
-}
-
-/**
- * onenand_bufferram_address - [DEFAULT] Get bufferram address
- * @param device       the device id
- * @param block                the block
- * @return             set DBS value if DDP, otherwise 0
- *
- * Setup Start Address 2 Register (F101h) for DDP
- */
-static int onenand_bufferram_address(int device, int block)
-{
-       if (device & ONENAND_DEVICE_IS_DDP) {
-               /* Device BufferRAM Select */
-               int dbs = 0, density, mask;
-
-               density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
-               mask = (1 << (density + 6));
-
-               if (block & mask)
-                       dbs = 1;
-
-               return (dbs << ONENAND_DDP_SHIFT);
-       }
-
-       return 0;
-}
-
-/**
- * onenand_page_address - [DEFAULT] Get page address
- * @param page         the page address
- * @param sector       the sector address
- * @return             combined page and sector address
- *
- * Setup Start Address 8 Register (F107h)
- */
-static int onenand_page_address(int page, int sector)
-{
-       /* Flash Page Address, Flash Sector Address */
-       int fpa, fsa;
-
-       fpa = page & ONENAND_FPA_MASK;
-       fsa = sector & ONENAND_FSA_MASK;
-
-       return ((fpa << ONENAND_FPA_SHIFT) | fsa);
-}
-
-/**
- * onenand_buffer_address - [DEFAULT] Get buffer address
- * @param dataram1     DataRAM index
- * @param sectors      the sector address
- * @param count                the number of sectors
- * @return             the start buffer value
- *
- * Setup Start Buffer Register (F200h)
- */
-static int onenand_buffer_address(int dataram1, int sectors, int count)
-{
-       int bsa, bsc;
-
-       /* BufferRAM Sector Address */
-       bsa = sectors & ONENAND_BSA_MASK;
-
-       if (dataram1)
-               bsa |= ONENAND_BSA_DATARAM1;    /* DataRAM1 */
-       else
-               bsa |= ONENAND_BSA_DATARAM0;    /* DataRAM0 */
-
-       /* BufferRAM Sector Count */
-       bsc = count & ONENAND_BSC_MASK;
-
-       return ((bsa << ONENAND_BSA_SHIFT) | bsc);
-}
-
-/**
- * onenand_command - [DEFAULT] Send command to OneNAND device
- * @param mtd          MTD device structure
- * @param cmd          the command to be sent
- * @param addr         offset to read from or write to
- * @param len          number of bytes to read or write
- *
- * Send command to OneNAND device. This function is used for middle/large page
- * devices (1KB/2KB Bytes per page)
- */
-static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr,
-                          size_t len)
-{
-       struct onenand_chip *this = mtd->priv;
-       int value, readcmd = 0;
-       int block, page;
-       /* Now we use page size operation */
-       int sectors = 4, count = 4;
-
-       /* Address translation */
-       switch (cmd) {
-       case ONENAND_CMD_UNLOCK:
-       case ONENAND_CMD_LOCK:
-       case ONENAND_CMD_LOCK_TIGHT:
-               block = -1;
-               page = -1;
-               break;
-
-       case ONENAND_CMD_ERASE:
-       case ONENAND_CMD_BUFFERRAM:
-               block = (int)(addr >> this->erase_shift);
-               page = -1;
-               break;
-
-       default:
-               block = (int)(addr >> this->erase_shift);
-               page = (int)(addr >> this->page_shift);
-               page &= this->page_mask;
-               break;
-       }
-
-       /* NOTE: The setting order of the registers is very important! */
-       if (cmd == ONENAND_CMD_BUFFERRAM) {
-               /* Select DataRAM for DDP */
-               value = onenand_bufferram_address(this->device_id, block);
-               this->write_word(value,
-                                this->base + ONENAND_REG_START_ADDRESS2);
-
-               /* Switch to the next data buffer */
-               ONENAND_SET_NEXT_BUFFERRAM(this);
-
-               return 0;
-       }
-
-       if (block != -1) {
-               /* Write 'DFS, FBA' of Flash */
-               value = onenand_block_address(this->device_id, block);
-               this->write_word(value,
-                                this->base + ONENAND_REG_START_ADDRESS1);
-       }
-
-       if (page != -1) {
-               int dataram;
-
-               switch (cmd) {
-               case ONENAND_CMD_READ:
-               case ONENAND_CMD_READOOB:
-                       dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
-                       readcmd = 1;
-                       break;
-
-               default:
-                       dataram = ONENAND_CURRENT_BUFFERRAM(this);
-                       break;
-               }
-
-               /* Write 'FPA, FSA' of Flash */
-               value = onenand_page_address(page, sectors);
-               this->write_word(value,
-                                this->base + ONENAND_REG_START_ADDRESS8);
-
-               /* Write 'BSA, BSC' of DataRAM */
-               value = onenand_buffer_address(dataram, sectors, count);
-               this->write_word(value, this->base + ONENAND_REG_START_BUFFER);
-
-               if (readcmd) {
-                       /* Select DataRAM for DDP */
-                       value =
-                           onenand_bufferram_address(this->device_id, block);
-                       this->write_word(value,
-                                        this->base +
-                                        ONENAND_REG_START_ADDRESS2);
-               }
-       }
-
-       /* Interrupt clear */
-       this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT);
-       /* Write command */
-       this->write_word(cmd, this->base + ONENAND_REG_COMMAND);
-
-       return 0;
-}
-
-/**
- * onenand_wait - [DEFAULT] wait until the command is done
- * @param mtd          MTD device structure
- * @param state                state to select the max. timeout value
- *
- * Wait for command done. This applies to all OneNAND command
- * Read can take up to 30us, erase up to 2ms and program up to 350us
- * according to general OneNAND specs
- */
-static int onenand_wait(struct mtd_info *mtd, int state)
-{
-       struct onenand_chip *this = mtd->priv;
-       unsigned int flags = ONENAND_INT_MASTER;
-       unsigned int interrupt = 0;
-       unsigned int ctrl, ecc;
-
-       while (1) {
-               interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
-               if (interrupt & flags)
-                       break;
-       }
-
-       ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
-
-       if (ctrl & ONENAND_CTRL_ERROR) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_wait: controller error = 0x%04x\n", ctrl);
-               return -EAGAIN;
-       }
-
-       if (ctrl & ONENAND_CTRL_LOCK) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_wait: it's locked error = 0x%04x\n", ctrl);
-               return -EIO;
-       }
-
-       if (interrupt & ONENAND_INT_READ) {
-               ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
-               if (ecc & ONENAND_ECC_2BIT_ALL) {
-                       DEBUG(MTD_DEBUG_LEVEL0,
-                             "onenand_wait: ECC error = 0x%04x\n", ecc);
-                       return -EBADMSG;
-               }
-       }
-
-       return 0;
-}
-
-/**
- * onenand_bufferram_offset - [DEFAULT] BufferRAM offset
- * @param mtd          MTD data structure
- * @param area         BufferRAM area
- * @return             offset given area
- *
- * Return BufferRAM offset given area
- */
-static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
-{
-       struct onenand_chip *this = mtd->priv;
-
-       if (ONENAND_CURRENT_BUFFERRAM(this)) {
-               if (area == ONENAND_DATARAM)
-                       return mtd->oobblock;
-               if (area == ONENAND_SPARERAM)
-                       return mtd->oobsize;
-       }
-
-       return 0;
-}
-
-/**
- * onenand_read_bufferram - [OneNAND Interface] Read the bufferram area
- * @param mtd          MTD data structure
- * @param area         BufferRAM area
- * @param buffer       the databuffer to put/get data
- * @param offset       offset to read from or write to
- * @param count                number of bytes to read/write
- *
- * Read the BufferRAM area
- */
-static int onenand_read_bufferram(struct mtd_info *mtd, int area,
-                                 unsigned char *buffer, int offset,
-                                 size_t count)
-{
-       struct onenand_chip *this = mtd->priv;
-       void __iomem *bufferram;
-
-       bufferram = this->base + area;
-       bufferram += onenand_bufferram_offset(mtd, area);
-
-       memcpy(buffer, bufferram + offset, count);
-
-       return 0;
-}
-
-/**
- * onenand_sync_read_bufferram - [OneNAND Interface] Read the bufferram area with Sync. Burst mode
- * @param mtd          MTD data structure
- * @param area         BufferRAM area
- * @param buffer       the databuffer to put/get data
- * @param offset       offset to read from or write to
- * @param count                number of bytes to read/write
- *
- * Read the BufferRAM area with Sync. Burst Mode
- */
-static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area,
-                                      unsigned char *buffer, int offset,
-                                      size_t count)
-{
-       struct onenand_chip *this = mtd->priv;
-       void __iomem *bufferram;
-
-       bufferram = this->base + area;
-       bufferram += onenand_bufferram_offset(mtd, area);
-
-       this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
-
-       memcpy(buffer, bufferram + offset, count);
-
-       this->mmcontrol(mtd, 0);
-
-       return 0;
-}
-
-/**
- * onenand_write_bufferram - [OneNAND Interface] Write the bufferram area
- * @param mtd          MTD data structure
- * @param area         BufferRAM area
- * @param buffer       the databuffer to put/get data
- * @param offset       offset to read from or write to
- * @param count                number of bytes to read/write
- *
- * Write the BufferRAM area
- */
-static int onenand_write_bufferram(struct mtd_info *mtd, int area,
-                                  const unsigned char *buffer, int offset,
-                                  size_t count)
-{
-       struct onenand_chip *this = mtd->priv;
-       void __iomem *bufferram;
-
-       bufferram = this->base + area;
-       bufferram += onenand_bufferram_offset(mtd, area);
-
-       memcpy(bufferram + offset, buffer, count);
-
-       return 0;
-}
-
-/**
- * onenand_check_bufferram - [GENERIC] Check BufferRAM information
- * @param mtd          MTD data structure
- * @param addr         address to check
- * @return             1 if there are valid data, otherwise 0
- *
- * Check bufferram if there is data we required
- */
-static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
-{
-       struct onenand_chip *this = mtd->priv;
-       int block, page;
-       int i;
-
-       block = (int)(addr >> this->erase_shift);
-       page = (int)(addr >> this->page_shift);
-       page &= this->page_mask;
-
-       i = ONENAND_CURRENT_BUFFERRAM(this);
-
-       /* Is there valid data? */
-       if (this->bufferram[i].block == block &&
-           this->bufferram[i].page == page && this->bufferram[i].valid)
-               return 1;
-
-       return 0;
-}
-
-/**
- * onenand_update_bufferram - [GENERIC] Update BufferRAM information
- * @param mtd          MTD data structure
- * @param addr         address to update
- * @param valid                valid flag
- *
- * Update BufferRAM information
- */
-static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
-                                   int valid)
-{
-       struct onenand_chip *this = mtd->priv;
-       int block, page;
-       int i;
-
-       block = (int)(addr >> this->erase_shift);
-       page = (int)(addr >> this->page_shift);
-       page &= this->page_mask;
-
-       /* Invalidate BufferRAM */
-       for (i = 0; i < MAX_BUFFERRAM; i++) {
-               if (this->bufferram[i].block == block &&
-                   this->bufferram[i].page == page)
-                       this->bufferram[i].valid = 0;
-       }
-
-       /* Update BufferRAM */
-       i = ONENAND_CURRENT_BUFFERRAM(this);
-       this->bufferram[i].block = block;
-       this->bufferram[i].page = page;
-       this->bufferram[i].valid = valid;
-
-       return 0;
-}
-
-/**
- * onenand_get_device - [GENERIC] Get chip for selected access
- * @param mtd          MTD device structure
- * @param new_state    the state which is requested
- *
- * Get the device and lock it for exclusive access
- */
-static void onenand_get_device(struct mtd_info *mtd, int new_state)
-{
-       /* Do nothing */
-}
-
-/**
- * onenand_release_device - [GENERIC] release chip
- * @param mtd          MTD device structure
- *
- * Deselect, release chip lock and wake up anyone waiting on the device
- */
-static void onenand_release_device(struct mtd_info *mtd)
-{
-       /* Do nothing */
-}
-
-/**
- * onenand_read_ecc - [MTD Interface] Read data with ECC
- * @param mtd          MTD device structure
- * @param from         offset to read from
- * @param len          number of bytes to read
- * @param retlen       pointer to variable to store the number of read bytes
- * @param buf          the databuffer to put data
- * @param oob_buf      filesystem supplied oob data buffer
- * @param oobsel       oob selection structure
- *
- * OneNAND read with ECC
- */
-static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
-                           size_t * retlen, u_char * buf,
-                           u_char * oob_buf, struct nand_oobinfo *oobsel)
-{
-       struct onenand_chip *this = mtd->priv;
-       int read = 0, column;
-       int thislen;
-       int ret = 0;
-
-       DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ecc: from = 0x%08x, len = %i\n",
-             (unsigned int)from, (int)len);
-
-       /* Do not allow reads past end of device */
-       if ((from + len) > mtd->size) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_read_ecc: Attempt read beyond end of device\n");
-               *retlen = 0;
-               return -EINVAL;
-       }
-
-       /* Grab the lock and see if the device is available */
-       onenand_get_device(mtd, FL_READING);
-
-       while (read < len) {
-               thislen = min_t(int, mtd->oobblock, len - read);
-
-               column = from & (mtd->oobblock - 1);
-               if (column + thislen > mtd->oobblock)
-                       thislen = mtd->oobblock - column;
-
-               if (!onenand_check_bufferram(mtd, from)) {
-                       this->command(mtd, ONENAND_CMD_READ, from,
-                                     mtd->oobblock);
-                       ret = this->wait(mtd, FL_READING);
-                       /* First copy data and check return value for ECC handling */
-                       onenand_update_bufferram(mtd, from, 1);
-               }
-
-               this->read_bufferram(mtd, ONENAND_DATARAM, buf, column,
-                                    thislen);
-
-               read += thislen;
-               if (read == len)
-                       break;
-
-               if (ret) {
-                       DEBUG(MTD_DEBUG_LEVEL0,
-                             "onenand_read_ecc: read failed = %d\n", ret);
-                       break;
-               }
-
-               from += thislen;
-               buf += thislen;
-       }
-
-       /* Deselect and wake up anyone waiting on the device */
-       onenand_release_device(mtd);
-
-       /*
-        * Return success, if no ECC failures, else -EBADMSG
-        * fs driver will take care of that, because
-        * retlen == desired len and result == -EBADMSG
-        */
-       *retlen = read;
-       return ret;
-}
-
-/**
- * onenand_read - [MTD Interface] MTD compability function for onenand_read_ecc
- * @param mtd          MTD device structure
- * @param from         offset to read from
- * @param len          number of bytes to read
- * @param retlen       pointer to variable to store the number of read bytes
- * @param buf          the databuffer to put data
- *
- * This function simply calls onenand_read_ecc with oob buffer and oobsel = NULL
-*/
-int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
-                size_t * retlen, u_char * buf)
-{
-       return onenand_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
-}
-
-/**
- * onenand_read_oob - [MTD Interface] OneNAND read out-of-band
- * @param mtd          MTD device structure
- * @param from         offset to read from
- * @param len          number of bytes to read
- * @param retlen       pointer to variable to store the number of read bytes
- * @param buf          the databuffer to put data
- *
- * OneNAND read out-of-band data from the spare area
- */
-int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
-                    size_t * retlen, u_char * buf)
-{
-       struct onenand_chip *this = mtd->priv;
-       int read = 0, thislen, column;
-       int ret = 0;
-
-       DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n",
-             (unsigned int)from, (int)len);
-
-       /* Initialize return length value */
-       *retlen = 0;
-
-       /* Do not allow reads past end of device */
-       if (unlikely((from + len) > mtd->size)) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_read_oob: Attempt read beyond end of device\n");
-               return -EINVAL;
-       }
-
-       /* Grab the lock and see if the device is available */
-       onenand_get_device(mtd, FL_READING);
-
-       column = from & (mtd->oobsize - 1);
-
-       while (read < len) {
-               thislen = mtd->oobsize - column;
-               thislen = min_t(int, thislen, len);
-
-               this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
-
-               onenand_update_bufferram(mtd, from, 0);
-
-               ret = this->wait(mtd, FL_READING);
-               /* First copy data and check return value for ECC handling */
-
-               this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column,
-                                    thislen);
-
-               read += thislen;
-               if (read == len)
-                       break;
-
-               if (ret) {
-                       DEBUG(MTD_DEBUG_LEVEL0,
-                             "onenand_read_oob: read failed = %d\n", ret);
-                       break;
-               }
-
-               buf += thislen;
-               /* Read more? */
-               if (read < len) {
-                       /* Page size */
-                       from += mtd->oobblock;
-                       column = 0;
-               }
-       }
-
-       /* Deselect and wake up anyone waiting on the device */
-       onenand_release_device(mtd);
-
-       *retlen = read;
-       return ret;
-}
-
-#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
-/**
- * onenand_verify_page - [GENERIC] verify the chip contents after a write
- * @param mtd          MTD device structure
- * @param buf          the databuffer to verify
- * @param block                block address
- * @param page         page address
- *
- * Check DataRAM area directly
- */
-static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
-                              loff_t addr, int block, int page)
-{
-       struct onenand_chip *this = mtd->priv;
-       void __iomem *dataram0, *dataram1;
-       int ret = 0;
-
-       this->command(mtd, ONENAND_CMD_READ, addr, mtd->oobblock);
-
-       ret = this->wait(mtd, FL_READING);
-       if (ret)
-               return ret;
-
-       onenand_update_bufferram(mtd, addr, 1);
-
-       /* Check, if the two dataram areas are same */
-       dataram0 = this->base + ONENAND_DATARAM;
-       dataram1 = dataram0 + mtd->oobblock;
-
-       if (memcmp(dataram0, dataram1, mtd->oobblock))
-               return -EBADMSG;
-
-       return 0;
-}
-#else
-#define onenand_verify_page(...)       (0)
-#endif
-
-#define NOTALIGNED(x)  ((x & (mtd->oobblock - 1)) != 0)
-
-/**
- * onenand_write_ecc - [MTD Interface] OneNAND write with ECC
- * @param mtd          MTD device structure
- * @param to           offset to write to
- * @param len          number of bytes to write
- * @param retlen       pointer to variable to store the number of written bytes
- * @param buf          the data to write
- * @param eccbuf       filesystem supplied oob data buffer
- * @param oobsel       oob selection structure
- *
- * OneNAND write with ECC
- */
-static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
-                            size_t * retlen, const u_char * buf,
-                            u_char * eccbuf, struct nand_oobinfo *oobsel)
-{
-       struct onenand_chip *this = mtd->priv;
-       int written = 0;
-       int ret = 0;
-
-       DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ecc: to = 0x%08x, len = %i\n",
-             (unsigned int)to, (int)len);
-
-       /* Initialize retlen, in case of early exit */
-       *retlen = 0;
-
-       /* Do not allow writes past end of device */
-       if (unlikely((to + len) > mtd->size)) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_write_ecc: Attempt write to past end of device\n");
-               return -EINVAL;
-       }
-
-       /* Reject writes, which are not page aligned */
-       if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_write_ecc: Attempt to write not page aligned data\n");
-               return -EINVAL;
-       }
-
-       /* Grab the lock and see if the device is available */
-       onenand_get_device(mtd, FL_WRITING);
-
-       /* Loop until all data write */
-       while (written < len) {
-               int thislen = min_t(int, mtd->oobblock, len - written);
-
-               this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
-
-               this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);
-               this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0,
-                                     mtd->oobsize);
-
-               this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
-
-               onenand_update_bufferram(mtd, to, 1);
-
-               ret = this->wait(mtd, FL_WRITING);
-               if (ret) {
-                       DEBUG(MTD_DEBUG_LEVEL0,
-                             "onenand_write_ecc: write filaed %d\n", ret);
-                       break;
-               }
-
-               written += thislen;
-
-               /* Only check verify write turn on */
-               ret = onenand_verify_page(mtd, (u_char *) buf, to, block, page);
-               if (ret) {
-                       DEBUG(MTD_DEBUG_LEVEL0,
-                             "onenand_write_ecc: verify failed %d\n", ret);
-                       break;
-               }
-
-               if (written == len)
-                       break;
-
-               to += thislen;
-               buf += thislen;
-       }
-
-       /* Deselect and wake up anyone waiting on the device */
-       onenand_release_device(mtd);
-
-       *retlen = written;
-
-       return ret;
-}
-
-/**
- * onenand_write - [MTD Interface] compability function for onenand_write_ecc
- * @param mtd          MTD device structure
- * @param to           offset to write to
- * @param len          number of bytes to write
- * @param retlen       pointer to variable to store the number of written bytes
- * @param buf          the data to write
- *
- * This function simply calls onenand_write_ecc
- * with oob buffer and oobsel = NULL
- */
-int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
-                 size_t * retlen, const u_char * buf)
-{
-       return onenand_write_ecc(mtd, to, len, retlen, buf, NULL, NULL);
-}
-
-/**
- * onenand_write_oob - [MTD Interface] OneNAND write out-of-band
- * @param mtd          MTD device structure
- * @param to           offset to write to
- * @param len          number of bytes to write
- * @param retlen       pointer to variable to store the number of written bytes
- * @param buf          the data to write
- *
- * OneNAND write out-of-band
- */
-int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
-                     size_t * retlen, const u_char * buf)
-{
-       struct onenand_chip *this = mtd->priv;
-       int column, status;
-       int written = 0;
-
-       DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n",
-             (unsigned int)to, (int)len);
-
-       /* Initialize retlen, in case of early exit */
-       *retlen = 0;
-
-       /* Do not allow writes past end of device */
-       if (unlikely((to + len) > mtd->size)) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_write_oob: Attempt write to past end of device\n");
-               return -EINVAL;
-       }
-
-       /* Grab the lock and see if the device is available */
-       onenand_get_device(mtd, FL_WRITING);
-
-       /* Loop until all data write */
-       while (written < len) {
-               int thislen = min_t(int, mtd->oobsize, len - written);
-
-               column = to & (mtd->oobsize - 1);
-
-               this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
-
-               this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0,
-                                     mtd->oobsize);
-               this->write_bufferram(mtd, ONENAND_SPARERAM, buf, column,
-                                     thislen);
-
-               this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
-
-               onenand_update_bufferram(mtd, to, 0);
-
-               status = this->wait(mtd, FL_WRITING);
-               if (status)
-                       break;
-
-               written += thislen;
-               if (written == len)
-                       break;
-
-               to += thislen;
-               buf += thislen;
-       }
-
-       /* Deselect and wake up anyone waiting on the device */
-       onenand_release_device(mtd);
-
-       *retlen = written;
-
-       return 0;
-}
-
-/**
- * onenand_erase - [MTD Interface] erase block(s)
- * @param mtd          MTD device structure
- * @param instr                erase instruction
- *
- * Erase one ore more blocks
- */
-int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
-{
-       struct onenand_chip *this = mtd->priv;
-       unsigned int block_size;
-       loff_t addr;
-       int len;
-       int ret = 0;
-
-       DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%08x, len = %i\n",
-             (unsigned int)instr->addr, (unsigned int)instr->len);
-
-       block_size = (1 << this->erase_shift);
-
-       /* Start address must align on block boundary */
-       if (unlikely(instr->addr & (block_size - 1))) {
-               DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Unaligned address\n");
-               return -EINVAL;
-       }
-
-       /* Length must align on block boundary */
-       if (unlikely(instr->len & (block_size - 1))) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_erase: Length not block aligned\n");
-               return -EINVAL;
-       }
-
-       /* Do not allow erase past end of device */
-       if (unlikely((instr->len + instr->addr) > mtd->size)) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_erase: Erase past end of device\n");
-               return -EINVAL;
-       }
-
-       instr->fail_addr = 0xffffffff;
-
-       /* Grab the lock and see if the device is available */
-       onenand_get_device(mtd, FL_ERASING);
-
-       /* Loop throught the pages */
-       len = instr->len;
-       addr = instr->addr;
-
-       instr->state = MTD_ERASING;
-
-       while (len) {
-
-               /* TODO Check badblock */
-
-               this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
-
-               ret = this->wait(mtd, FL_ERASING);
-               /* Check, if it is write protected */
-               if (ret) {
-                       if (ret == -EPERM)
-                               DEBUG(MTD_DEBUG_LEVEL0,
-                                     "onenand_erase: Device is write protected!!!\n");
-                       else
-                               DEBUG(MTD_DEBUG_LEVEL0,
-                                     "onenand_erase: Failed erase, block %d\n",
-                                     (unsigned)(addr >> this->erase_shift));
-                       instr->state = MTD_ERASE_FAILED;
-                       instr->fail_addr = addr;
-                       goto erase_exit;
-               }
-
-               len -= block_size;
-               addr += block_size;
-       }
-
-       instr->state = MTD_ERASE_DONE;
-
-      erase_exit:
-
-       ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
-       /* Do call back function */
-       if (!ret)
-               mtd_erase_callback(instr);
-
-       /* Deselect and wake up anyone waiting on the device */
-       onenand_release_device(mtd);
-
-       return ret;
-}
-
-/**
- * onenand_sync - [MTD Interface] sync
- * @param mtd          MTD device structure
- *
- * Sync is actually a wait for chip ready function
- */
-void onenand_sync(struct mtd_info *mtd)
-{
-       DEBUG(MTD_DEBUG_LEVEL3, "onenand_sync: called\n");
-
-       /* Grab the lock and see if the device is available */
-       onenand_get_device(mtd, FL_SYNCING);
-
-       /* Release it and go back */
-       onenand_release_device(mtd);
-}
-
-/**
- * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
- * @param mtd          MTD device structure
- * @param ofs          offset relative to mtd start
- */
-int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
-{
-       /*
-        * TODO
-        * 1. Bad block table (BBT)
-        *   -> using NAND BBT to support JFFS2
-        * 2. Bad block management (BBM)
-        *   -> bad block replace scheme
-        *
-        * Currently we do nothing
-        */
-       return 0;
-}
-
-/**
- * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
- * @param mtd          MTD device structure
- * @param ofs          offset relative to mtd start
- */
-int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
-{
-       /* see above */
-       return 0;
-}
-
-/**
- * onenand_unlock - [MTD Interface] Unlock block(s)
- * @param mtd          MTD device structure
- * @param ofs          offset relative to mtd start
- * @param len          number of bytes to unlock
- *
- * Unlock one or more blocks
- */
-int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
-{
-       struct onenand_chip *this = mtd->priv;
-       int start, end, block, value, status;
-
-       start = ofs >> this->erase_shift;
-       end = len >> this->erase_shift;
-
-       /* Continuous lock scheme */
-       if (this->options & ONENAND_CONT_LOCK) {
-               /* Set start block address */
-               this->write_word(start,
-                                this->base + ONENAND_REG_START_BLOCK_ADDRESS);
-               /* Set end block address */
-               this->write_word(end - 1,
-                                this->base + ONENAND_REG_END_BLOCK_ADDRESS);
-               /* Write unlock command */
-               this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
-
-               /* There's no return value */
-               this->wait(mtd, FL_UNLOCKING);
-
-               /* Sanity check */
-               while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
-                      & ONENAND_CTRL_ONGO)
-                       continue;
-
-               /* Check lock status */
-               status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
-               if (!(status & ONENAND_WP_US))
-                       printk(KERN_ERR "wp status = 0x%x\n", status);
-
-               return 0;
-       }
-
-       /* Block lock scheme */
-       for (block = start; block < end; block++) {
-               /* Set start block address */
-               this->write_word(block,
-                                this->base + ONENAND_REG_START_BLOCK_ADDRESS);
-               /* Write unlock command */
-               this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
-
-               /* There's no return value */
-               this->wait(mtd, FL_UNLOCKING);
-
-               /* Sanity check */
-               while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
-                      & ONENAND_CTRL_ONGO)
-                       continue;
-
-               /* Set block address for read block status */
-               value = onenand_block_address(this->device_id, block);
-               this->write_word(value,
-                                this->base + ONENAND_REG_START_ADDRESS1);
-
-               /* Check lock status */
-               status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
-               if (!(status & ONENAND_WP_US))
-                       printk(KERN_ERR "block = %d, wp status = 0x%x\n",
-                              block, status);
-       }
-
-       return 0;
-}
-
-/**
- * onenand_print_device_info - Print device ID
- * @param device        device ID
- *
- * Print device ID
- */
-void onenand_print_device_info(int device, int verbose)
-{
-       int vcc, demuxed, ddp, density;
-
-       if (!verbose)
-               return;
-
-       vcc = device & ONENAND_DEVICE_VCC_MASK;
-       demuxed = device & ONENAND_DEVICE_IS_DEMUX;
-       ddp = device & ONENAND_DEVICE_IS_DDP;
-       density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
-       printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n",
-              demuxed ? "" : "Muxed ",
-              ddp ? "(DDP)" : "",
-              (16 << density), vcc ? "2.65/3.3" : "1.8", device);
-}
-
-static const struct onenand_manufacturers onenand_manuf_ids[] = {
-       {ONENAND_MFR_SAMSUNG, "Samsung"},
-       {ONENAND_MFR_UNKNOWN, "Unknown"}
-};
-
-/**
- * onenand_check_maf - Check manufacturer ID
- * @param manuf         manufacturer ID
- *
- * Check manufacturer ID
- */
-static int onenand_check_maf(int manuf)
-{
-       int i;
-
-       for (i = 0; onenand_manuf_ids[i].id; i++) {
-               if (manuf == onenand_manuf_ids[i].id)
-                       break;
-       }
-
-#ifdef ONENAND_DEBUG
-       printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n",
-              onenand_manuf_ids[i].name, manuf);
-#endif
-
-       return (i != ONENAND_MFR_UNKNOWN);
-}
-
-/**
- * onenand_probe - [OneNAND Interface] Probe the OneNAND device
- * @param mtd          MTD device structure
- *
- * OneNAND detection method:
- *   Compare the the values from command with ones from register
- */
-static int onenand_probe(struct mtd_info *mtd)
-{
-       struct onenand_chip *this = mtd->priv;
-       int bram_maf_id, bram_dev_id, maf_id, dev_id;
-       int version_id;
-       int density;
-
-       /* Send the command for reading device ID from BootRAM */
-       this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
-
-       /* Read manufacturer and device IDs from BootRAM */
-       bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
-       bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
-
-       /* Check manufacturer ID */
-       if (onenand_check_maf(bram_maf_id))
-               return -ENXIO;
-
-       /* Reset OneNAND to read default register values */
-       this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
-
-       {
-               int i;
-               for (i = 0; i < 10000; i++) ;
-       }
-
-       /* Read manufacturer and device IDs from Register */
-       maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
-       dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
-
-       /* Check OneNAND device */
-       if (maf_id != bram_maf_id || dev_id != bram_dev_id)
-               return -ENXIO;
-
-       /* Flash device information */
-       onenand_print_device_info(dev_id, 0);
-       this->device_id = dev_id;
-
-       density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
-       this->chipsize = (16 << density) << 20;
-
-       /* OneNAND page size & block size */
-       /* The data buffer size is equal to page size */
-       mtd->oobblock =
-           this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
-       mtd->oobsize = mtd->oobblock >> 5;
-       /* Pagers per block is always 64 in OneNAND */
-       mtd->erasesize = mtd->oobblock << 6;
-
-       this->erase_shift = ffs(mtd->erasesize) - 1;
-       this->page_shift = ffs(mtd->oobblock) - 1;
-       this->ppb_shift = (this->erase_shift - this->page_shift);
-       this->page_mask = (mtd->erasesize / mtd->oobblock) - 1;
-
-       /* REVIST: Multichip handling */
-
-       mtd->size = this->chipsize;
-
-       /* Version ID */
-       version_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
-#ifdef ONENAND_DEBUG
-       printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version_id);
-#endif
-
-       /* Lock scheme */
-       if (density <= ONENAND_DEVICE_DENSITY_512Mb &&
-           !(version_id >> ONENAND_VERSION_PROCESS_SHIFT)) {
-               printk(KERN_INFO "Lock scheme is Continues Lock\n");
-               this->options |= ONENAND_CONT_LOCK;
-       }
-
-       return 0;
-}
-
-/**
- * onenand_scan - [OneNAND Interface] Scan for the OneNAND device
- * @param mtd          MTD device structure
- * @param maxchips     Number of chips to scan for
- *
- * This fills out all the not initialized function pointers
- * with the defaults.
- * The flash ID is read and the mtd/chip structures are
- * filled with the appropriate values.
- */
-int onenand_scan(struct mtd_info *mtd, int maxchips)
-{
-       struct onenand_chip *this = mtd->priv;
-
-       if (!this->read_word)
-               this->read_word = onenand_readw;
-       if (!this->write_word)
-               this->write_word = onenand_writew;
-
-       if (!this->command)
-               this->command = onenand_command;
-       if (!this->wait)
-               this->wait = onenand_wait;
-
-       if (!this->read_bufferram)
-               this->read_bufferram = onenand_read_bufferram;
-       if (!this->write_bufferram)
-               this->write_bufferram = onenand_write_bufferram;
-
-       if (onenand_probe(mtd))
-               return -ENXIO;
-
-       /* Set Sync. Burst Read after probing */
-       if (this->mmcontrol) {
-               printk(KERN_INFO "OneNAND Sync. Burst Read support\n");
-               this->read_bufferram = onenand_sync_read_bufferram;
-       }
-
-       onenand_unlock(mtd, 0, mtd->size);
-
-       return onenand_default_bbt(mtd);
-}
-
-/**
- * onenand_release - [OneNAND Interface] Free resources held by the OneNAND device
- * @param mtd          MTD device structure
- */
-void onenand_release(struct mtd_info *mtd)
-{
-}
-
-/*
- * OneNAND initialization at U-Boot
- */
-struct mtd_info onenand_mtd;
-struct onenand_chip onenand_chip;
-
-void onenand_init(void)
-{
-       memset(&onenand_mtd, 0, sizeof(struct mtd_info));
-       memset(&onenand_chip, 0, sizeof(struct onenand_chip));
-
-       onenand_chip.base = (void *)CFG_ONENAND_BASE;
-       onenand_mtd.priv = &onenand_chip;
-
-       onenand_scan(&onenand_mtd, 1);
-
-       puts("OneNAND: ");
-       print_size(onenand_mtd.size, "\n");
-}
-
-#endif /* CONFIG_CMD_ONENAND */
diff --git a/drivers/onenand/onenand_bbt.c b/drivers/onenand/onenand_bbt.c
deleted file mode 100644 (file)
index 5a610ee..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- *  linux/drivers/mtd/onenand/onenand_bbt.c
- *
- *  Bad Block Table support for the OneNAND driver
- *
- *  Copyright(c) 2005-2007 Samsung Electronics
- *  Kyungmin Park <kyungmin.park@samsung.com>
- *
- *  TODO:
- *    Split BBT core and chip specific BBT.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <common.h>
-
-#ifdef CONFIG_CMD_ONENAND
-
-#include <linux/mtd/compat.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/onenand.h>
-#include <malloc.h>
-
-#include <asm/errno.h>
-
-/**
- * check_short_pattern - [GENERIC] check if a pattern is in the buffer
- * @param buf          the buffer to search
- * @param len          the length of buffer to search
- * @param paglen       the pagelength
- * @param td           search pattern descriptor
- *
- * Check for a pattern at the given place. Used to search bad block
- * tables and good / bad block identifiers. Same as check_pattern, but
- * no optional empty check and the pattern is expected to start
- * at offset 0.
- */
-static int check_short_pattern(uint8_t * buf, int len, int paglen,
-                              struct nand_bbt_descr *td)
-{
-       int i;
-       uint8_t *p = buf;
-
-       /* Compare the pattern */
-       for (i = 0; i < td->len; i++) {
-               if (p[i] != td->pattern[i])
-                       return -1;
-       }
-       return 0;
-}
-
-/**
- * create_bbt - [GENERIC] Create a bad block table by scanning the device
- * @param mtd          MTD device structure
- * @param buf          temporary buffer
- * @param bd           descriptor for the good/bad block search pattern
- * @param chip         create the table for a specific chip, -1 read all chips.
- *              Applies only if NAND_BBT_PERCHIP option is set
- *
- * Create a bad block table by scanning the device
- * for the given good/bad block identify pattern
- */
-static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
-                     struct nand_bbt_descr *bd, int chip)
-{
-       struct onenand_chip *this = mtd->priv;
-       struct bbm_info *bbm = this->bbm;
-       int i, j, numblocks, len, scanlen;
-       int startblock;
-       loff_t from;
-       size_t readlen, ooblen;
-
-       printk(KERN_INFO "Scanning device for bad blocks\n");
-
-       len = 1;
-
-       /* We need only read few bytes from the OOB area */
-       scanlen = ooblen = 0;
-       readlen = bd->len;
-
-       /* chip == -1 case only */
-       /* Note that numblocks is 2 * (real numblocks) here;
-        * see i += 2 below as it makses shifting and masking less painful
-        */
-       numblocks = mtd->size >> (bbm->bbt_erase_shift - 1);
-       startblock = 0;
-       from = 0;
-
-       for (i = startblock; i < numblocks;) {
-               int ret;
-
-               for (j = 0; j < len; j++) {
-                       size_t retlen;
-
-                       /* No need to read pages fully,
-                        * just read required OOB bytes */
-                       ret = onenand_read_oob(mtd,
-                                            from + j * mtd->oobblock +
-                                            bd->offs, readlen, &retlen,
-                                            &buf[0]);
-
-                       if (ret && ret != -EAGAIN) {
-                               printk("ret = %d\n", ret);
-                               return ret;
-                       }
-
-                       if (check_short_pattern
-                           (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
-                               bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
-                               printk(KERN_WARNING
-                                      "Bad eraseblock %d at 0x%08x\n", i >> 1,
-                                      (unsigned int)from);
-                               break;
-                       }
-               }
-               i += 2;
-               from += (1 << bbm->bbt_erase_shift);
-       }
-
-       return 0;
-}
-
-/**
- * onenand_memory_bbt - [GENERIC] create a memory based bad block table
- * @param mtd          MTD device structure
- * @param bd           descriptor for the good/bad block search pattern
- *
- * The function creates a memory based bbt by scanning the device
- * for manufacturer / software marked good / bad blocks
- */
-static inline int onenand_memory_bbt(struct mtd_info *mtd,
-                                    struct nand_bbt_descr *bd)
-{
-       unsigned char data_buf[MAX_ONENAND_PAGESIZE];
-
-       bd->options &= ~NAND_BBT_SCANEMPTY;
-       return create_bbt(mtd, data_buf, bd, -1);
-}
-
-/**
- * onenand_isbad_bbt - [OneNAND Interface] Check if a block is bad
- * @param mtd          MTD device structure
- * @param offs         offset in the device
- * @param allowbbt     allow access to bad block table region
- */
-static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
-{
-       struct onenand_chip *this = mtd->priv;
-       struct bbm_info *bbm = this->bbm;
-       int block;
-       uint8_t res;
-
-       /* Get block number * 2 */
-       block = (int)(offs >> (bbm->bbt_erase_shift - 1));
-       res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
-
-       DEBUG(MTD_DEBUG_LEVEL2,
-             "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n",
-             (unsigned int)offs, block >> 1, res);
-
-       switch ((int)res) {
-       case 0x00:
-               return 0;
-       case 0x01:
-               return 1;
-       case 0x02:
-               return allowbbt ? 0 : 1;
-       }
-
-       return 1;
-}
-
-/**
- * onenand_scan_bbt - [OneNAND Interface] scan, find, read and maybe create bad block table(s)
- * @param mtd          MTD device structure
- * @param bd           descriptor for the good/bad block search pattern
- *
- * The function checks, if a bad block table(s) is/are already
- * available. If not it scans the device for manufacturer
- * marked good / bad blocks and writes the bad block table(s) to
- * the selected place.
- *
- * The bad block table memory is allocated here. It must be freed
- * by calling the onenand_free_bbt function.
- *
- */
-int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
-{
-       struct onenand_chip *this = mtd->priv;
-       struct bbm_info *bbm = this->bbm;
-       int len, ret = 0;
-
-       len = mtd->size >> (this->erase_shift + 2);
-       /* Allocate memory (2bit per block) */
-       bbm->bbt = malloc(len);
-       if (!bbm->bbt) {
-               printk(KERN_ERR "onenand_scan_bbt: Out of memory\n");
-               return -ENOMEM;
-       }
-       /* Clear the memory bad block table */
-       memset(bbm->bbt, 0x00, len);
-
-       /* Set the bad block position */
-       bbm->badblockpos = ONENAND_BADBLOCK_POS;
-
-       /* Set erase shift */
-       bbm->bbt_erase_shift = this->erase_shift;
-
-       if (!bbm->isbad_bbt)
-               bbm->isbad_bbt = onenand_isbad_bbt;
-
-       /* Scan the device to build a memory based bad block table */
-       if ((ret = onenand_memory_bbt(mtd, bd))) {
-               printk(KERN_ERR
-                      "onenand_scan_bbt: Can't scan flash and build the RAM-based BBT\n");
-               free(bbm->bbt);
-               bbm->bbt = NULL;
-       }
-
-       return ret;
-}
-
-/*
- * Define some generic bad / good block scan pattern which are used
- * while scanning a device for factory marked good / bad blocks.
- */
-static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
-
-static struct nand_bbt_descr largepage_memorybased = {
-       .options = 0,
-       .offs = 0,
-       .len = 2,
-       .pattern = scan_ff_pattern,
-};
-
-/**
- * onenand_default_bbt - [OneNAND Interface] Select a default bad block table for the device
- * @param mtd          MTD device structure
- *
- * This function selects the default bad block table
- * support for the device and calls the onenand_scan_bbt function
- */
-int onenand_default_bbt(struct mtd_info *mtd)
-{
-       struct onenand_chip *this = mtd->priv;
-       struct bbm_info *bbm;
-
-       this->bbm = malloc(sizeof(struct bbm_info));
-       if (!this->bbm)
-               return -ENOMEM;
-
-       bbm = this->bbm;
-
-       memset(bbm, 0, sizeof(struct bbm_info));
-
-       /* 1KB page has same configuration as 2KB page */
-       if (!bbm->badblock_pattern)
-               bbm->badblock_pattern = &largepage_memorybased;
-
-       return onenand_scan_bbt(mtd, bbm->badblock_pattern);
-}
-
-#endif /* CFG_CMD_ONENAND */
diff --git a/drivers/pc_keyb.c b/drivers/pc_keyb.c
deleted file mode 100644 (file)
index 81d3e98..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/***********************************************************************
- *
- * (C) Copyright 2004
- * DENX Software Engineering
- * Wolfgang Denk, wd@denx.de
- * All rights reserved.
- *
- * PS/2 keyboard driver
- *
- * Originally from linux source (drivers/char/pc_keyb.c)
- *
- ***********************************************************************/
-
-#include <common.h>
-
-#ifdef CONFIG_PS2KBD
-
-#include <keyboard.h>
-#include <pc_keyb.h>
-
-#undef KBG_DEBUG
-
-#ifdef KBG_DEBUG
-#define        PRINTF(fmt,args...)     printf (fmt ,##args)
-#else
-#define PRINTF(fmt,args...)
-#endif
-
-
-/*
- * This reads the keyboard status port, and does the
- * appropriate action.
- *
- */
-static unsigned char handle_kbd_event(void)
-{
-       unsigned char status = kbd_read_status();
-       unsigned int work = 10000;
-
-       while ((--work > 0) && (status & KBD_STAT_OBF)) {
-               unsigned char scancode;
-
-               scancode = kbd_read_input();
-
-               /* Error bytes must be ignored to make the
-                  Synaptics touchpads compaq use work */
-               /* Ignore error bytes */
-               if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR))) {
-                       if (status & KBD_STAT_MOUSE_OBF)
-                               ; /* not supported: handle_mouse_event(scancode); */
-                       else
-                               handle_scancode(scancode);
-               }
-               status = kbd_read_status();
-       }
-       if (!work)
-               PRINTF("pc_keyb: controller jammed (0x%02X).\n", status);
-       return status;
-}
-
-
-static int kbd_read_data(void)
-{
-       int val;
-       unsigned char status;
-
-       val=-1;
-       status = kbd_read_status();
-       if (status & KBD_STAT_OBF) {
-               val = kbd_read_input();
-               if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
-                       val = -2;
-       }
-       return val;
-}
-
-static int kbd_wait_for_input(void)
-{
-       unsigned long timeout;
-       int val;
-
-       timeout = KBD_TIMEOUT;
-       val=kbd_read_data();
-       while(val < 0) {
-               if(timeout--==0)
-                       return -1;
-               udelay(1000);
-               val=kbd_read_data();
-       }
-       return val;
-}
-
-
-static int kb_wait(void)
-{
-       unsigned long timeout = KBC_TIMEOUT * 10;
-
-       do {
-               unsigned char status = handle_kbd_event();
-               if (!(status & KBD_STAT_IBF))
-                       return 0; /* ok */
-               udelay(1000);
-               timeout--;
-       } while (timeout);
-       return 1;
-}
-
-static void kbd_write_command_w(int data)
-{
-       if(kb_wait())
-               PRINTF("timeout in kbd_write_command_w\n");
-       kbd_write_command(data);
-}
-
-static void kbd_write_output_w(int data)
-{
-       if(kb_wait())
-               PRINTF("timeout in kbd_write_output_w\n");
-       kbd_write_output(data);
-}
-
-static void kbd_send_data(unsigned char data)
-{
-       kbd_write_output_w(data);
-       kbd_wait_for_input();
-}
-
-
-static char * kbd_initialize(void)
-{
-       int status;
-
-       /*
-        * Test the keyboard interface.
-        * This seems to be the only way to get it going.
-        * If the test is successful a x55 is placed in the input buffer.
-        */
-       kbd_write_command_w(KBD_CCMD_SELF_TEST);
-       if (kbd_wait_for_input() != 0x55)
-               return "Kbd:   failed self test";
-       /*
-        * Perform a keyboard interface test.  This causes the controller
-        * to test the keyboard clock and data lines.  The results of the
-        * test are placed in the input buffer.
-        */
-       kbd_write_command_w(KBD_CCMD_KBD_TEST);
-       if (kbd_wait_for_input() != 0x00)
-               return "Kbd:   interface failed self test";
-       /*
-        * Enable the keyboard by allowing the keyboard clock to run.
-        */
-       kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
-
-       /*
-        * Reset keyboard. If the read times out
-        * then the assumption is that no keyboard is
-        * plugged into the machine.
-        * This defaults the keyboard to scan-code set 2.
-        *
-        * Set up to try again if the keyboard asks for RESEND.
-        */
-       do {
-               kbd_write_output_w(KBD_CMD_RESET);
-               status = kbd_wait_for_input();
-               if (status == KBD_REPLY_ACK)
-                       break;
-               if (status != KBD_REPLY_RESEND) {
-                       PRINTF("status: %X\n",status);
-                       return "Kbd:   reset failed, no ACK";
-               }
-       } while (1);
-       if (kbd_wait_for_input() != KBD_REPLY_POR)
-               return "Kbd:   reset failed, no POR";
-
-       /*
-        * Set keyboard controller mode. During this, the keyboard should be
-        * in the disabled state.
-        *
-        * Set up to try again if the keyboard asks for RESEND.
-        */
-       do {
-               kbd_write_output_w(KBD_CMD_DISABLE);
-               status = kbd_wait_for_input();
-               if (status == KBD_REPLY_ACK)
-                       break;
-               if (status != KBD_REPLY_RESEND)
-                       return "Kbd:   disable keyboard: no ACK";
-       } while (1);
-
-       kbd_write_command_w(KBD_CCMD_WRITE_MODE);
-       kbd_write_output_w(KBD_MODE_KBD_INT
-                             | KBD_MODE_SYS
-                             | KBD_MODE_DISABLE_MOUSE
-                             | KBD_MODE_KCC);
-
-       /* AMCC powerpc portables need this to use scan-code set 1 -- Cort */
-       kbd_write_command_w(KBD_CCMD_READ_MODE);
-       if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
-               /*
-                * If the controller does not support conversion,
-                * Set the keyboard to scan-code set 1.
-                */
-               kbd_write_output_w(0xF0);
-               kbd_wait_for_input();
-               kbd_write_output_w(0x01);
-               kbd_wait_for_input();
-       }
-       kbd_write_output_w(KBD_CMD_ENABLE);
-       if (kbd_wait_for_input() != KBD_REPLY_ACK)
-               return "Kbd:   enable keyboard: no ACK";
-
-       /*
-        * Finally, set the typematic rate to maximum.
-        */
-       kbd_write_output_w(KBD_CMD_SET_RATE);
-       if (kbd_wait_for_input() != KBD_REPLY_ACK)
-               return "Kbd:   Set rate: no ACK";
-       kbd_write_output_w(0x00);
-       if (kbd_wait_for_input() != KBD_REPLY_ACK)
-               return "Kbd:   Set rate: no ACK";
-       return NULL;
-}
-
-static void kbd_interrupt(void *dev_id)
-{
-       handle_kbd_event();
-}
-
-/******************************************************************
- * Init
- ******************************************************************/
-
-int kbd_init_hw(void)
-{
-       char* result;
-
-       kbd_request_region();
-
-       result=kbd_initialize();
-       if (result==NULL) {
-               PRINTF("AT Keyboard initialized\n");
-               kbd_request_irq(kbd_interrupt);
-               return (1);
-       } else {
-               printf("%s\n",result);
-               return (-1);
-       }
-}
-
-void pckbd_leds(unsigned char leds)
-{
-       kbd_send_data(KBD_CMD_SET_LEDS);
-       kbd_send_data(leds);
-}
-
-#endif /* CONFIG_PS2KBD */
diff --git a/drivers/pci.c b/drivers/pci.c
deleted file mode 100644 (file)
index 50ca6b0..0000000
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Andreas Heppel <aheppel@sysgo.de>
- *
- * (C) Copyright 2002, 2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * PCI routines
- */
-
-#include <common.h>
-
-#ifdef CONFIG_PCI
-
-#include <command.h>
-#include <asm/processor.h>
-#include <asm/io.h>
-#include <pci.h>
-
-#define PCI_HOSE_OP(rw, size, type)                                    \
-int pci_hose_##rw##_config_##size(struct pci_controller *hose,                 \
-                                 pci_dev_t dev,                        \
-                                 int offset, type value)               \
-{                                                                      \
-       return hose->rw##_##size(hose, dev, offset, value);             \
-}
-
-PCI_HOSE_OP(read, byte, u8 *)
-PCI_HOSE_OP(read, word, u16 *)
-PCI_HOSE_OP(read, dword, u32 *)
-PCI_HOSE_OP(write, byte, u8)
-PCI_HOSE_OP(write, word, u16)
-PCI_HOSE_OP(write, dword, u32)
-
-#ifndef CONFIG_IXP425
-#define PCI_OP(rw, size, type, error_code)                             \
-int pci_##rw##_config_##size(pci_dev_t dev, int offset, type value)    \
-{                                                                      \
-       struct pci_controller *hose = pci_bus_to_hose(PCI_BUS(dev));    \
-                                                                       \
-       if (!hose)                                                      \
-       {                                                               \
-               error_code;                                             \
-               return -1;                                              \
-       }                                                               \
-                                                                       \
-       return pci_hose_##rw##_config_##size(hose, dev, offset, value); \
-}
-
-PCI_OP(read, byte, u8 *, *value = 0xff)
-PCI_OP(read, word, u16 *, *value = 0xffff)
-PCI_OP(read, dword, u32 *, *value = 0xffffffff)
-PCI_OP(write, byte, u8, )
-PCI_OP(write, word, u16, )
-PCI_OP(write, dword, u32, )
-#endif /* CONFIG_IXP425 */
-
-#define PCI_READ_VIA_DWORD_OP(size, type, off_mask)                    \
-int pci_hose_read_config_##size##_via_dword(struct pci_controller *hose,\
-                                       pci_dev_t dev,                  \
-                                       int offset, type val)           \
-{                                                                      \
-       u32 val32;                                                      \
-                                                                       \
-       if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0) { \
-               *val = -1;                                              \
-               return -1;                                              \
-       }                                                               \
-                                                                       \
-       *val = (val32 >> ((offset & (int)off_mask) * 8));               \
-                                                                       \
-       return 0;                                                       \
-}
-
-#define PCI_WRITE_VIA_DWORD_OP(size, type, off_mask, val_mask)         \
-int pci_hose_write_config_##size##_via_dword(struct pci_controller *hose,\
-                                            pci_dev_t dev,             \
-                                            int offset, type val)      \
-{                                                                      \
-       u32 val32, mask, ldata, shift;                                  \
-                                                                       \
-       if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0)\
-               return -1;                                              \
-                                                                       \
-       shift = ((offset & (int)off_mask) * 8);                         \
-       ldata = (((unsigned long)val) & val_mask) << shift;             \
-       mask = val_mask << shift;                                       \
-       val32 = (val32 & ~mask) | ldata;                                \
-                                                                       \
-       if (pci_hose_write_config_dword(hose, dev, offset & 0xfc, val32) < 0)\
-               return -1;                                              \
-                                                                       \
-       return 0;                                                       \
-}
-
-PCI_READ_VIA_DWORD_OP(byte, u8 *, 0x03)
-PCI_READ_VIA_DWORD_OP(word, u16 *, 0x02)
-PCI_WRITE_VIA_DWORD_OP(byte, u8, 0x03, 0x000000ff)
-PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff)
-
-/*
- *
- */
-
-static struct pci_controller* hose_head = NULL;
-
-void pci_register_hose(struct pci_controller* hose)
-{
-       struct pci_controller **phose = &hose_head;
-
-       while(*phose)
-               phose = &(*phose)->next;
-
-       hose->next = NULL;
-
-       *phose = hose;
-}
-
-struct pci_controller *pci_bus_to_hose (int bus)
-{
-       struct pci_controller *hose;
-
-       for (hose = hose_head; hose; hose = hose->next)
-               if (bus >= hose->first_busno && bus <= hose->last_busno)
-                       return hose;
-
-       printf("pci_bus_to_hose() failed\n");
-       return NULL;
-}
-
-#ifndef CONFIG_IXP425
-pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
-{
-       struct pci_controller * hose;
-       u16 vendor, device;
-       u8 header_type;
-       pci_dev_t bdf;
-       int i, bus, found_multi = 0;
-
-       for (hose = hose_head; hose; hose = hose->next)
-       {
-#ifdef CFG_SCSI_SCAN_BUS_REVERSE
-               for (bus = hose->last_busno; bus >= hose->first_busno; bus--)
-#else
-               for (bus = hose->first_busno; bus <= hose->last_busno; bus++)
-#endif
-                       for (bdf = PCI_BDF(bus,0,0);
-#if defined(CONFIG_ELPPC) || defined(CONFIG_PPMC7XX)
-                            bdf < PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1);
-#else
-                            bdf < PCI_BDF(bus+1,0,0);
-#endif
-                            bdf += PCI_BDF(0,0,1))
-                       {
-                               if (!PCI_FUNC(bdf)) {
-                                       pci_read_config_byte(bdf,
-                                                            PCI_HEADER_TYPE,
-                                                            &header_type);
-
-                                       found_multi = header_type & 0x80;
-                               } else {
-                                       if (!found_multi)
-                                               continue;
-                               }
-
-                               pci_read_config_word(bdf,
-                                                    PCI_VENDOR_ID,
-                                                    &vendor);
-                               pci_read_config_word(bdf,
-                                                    PCI_DEVICE_ID,
-                                                    &device);
-
-                               for (i=0; ids[i].vendor != 0; i++)
-                                       if (vendor == ids[i].vendor &&
-                                           device == ids[i].device)
-                                       {
-                                               if (index <= 0)
-                                                       return bdf;
-
-                                               index--;
-                                       }
-                       }
-       }
-
-       return (-1);
-}
-#endif /* CONFIG_IXP425 */
-
-pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
-{
-       static struct pci_device_id ids[2] = {{}, {0, 0}};
-
-       ids[0].vendor = vendor;
-       ids[0].device = device;
-
-       return pci_find_devices(ids, index);
-}
-
-/*
- *
- */
-
-unsigned long pci_hose_phys_to_bus (struct pci_controller *hose,
-                                   unsigned long phys_addr,
-                                   unsigned long flags)
-{
-       struct pci_region *res;
-       unsigned long bus_addr;
-       int i;
-
-       if (!hose) {
-               printf ("pci_hose_phys_to_bus: %s\n", "invalid hose");
-               goto Done;
-       }
-
-       for (i = 0; i < hose->region_count; i++) {
-               res = &hose->regions[i];
-
-               if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
-                       continue;
-
-               bus_addr = phys_addr - res->phys_start + res->bus_start;
-
-               if (bus_addr >= res->bus_start &&
-                       bus_addr < res->bus_start + res->size) {
-                       return bus_addr;
-               }
-       }
-
-       printf ("pci_hose_phys_to_bus: %s\n", "invalid physical address");
-
-Done:
-       return 0;
-}
-
-unsigned long pci_hose_bus_to_phys(struct pci_controller* hose,
-                                  unsigned long bus_addr,
-                                  unsigned long flags)
-{
-       struct pci_region *res;
-       int i;
-
-       if (!hose) {
-               printf ("pci_hose_bus_to_phys: %s\n", "invalid hose");
-               goto Done;
-       }
-
-       for (i = 0; i < hose->region_count; i++) {
-               res = &hose->regions[i];
-
-               if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
-                       continue;
-
-               if (bus_addr >= res->bus_start &&
-                       bus_addr < res->bus_start + res->size) {
-                       return bus_addr - res->bus_start + res->phys_start;
-               }
-       }
-
-       printf ("pci_hose_bus_to_phys: %s\n", "invalid physical address");
-
-Done:
-       return 0;
-}
-
-/*
- *
- */
-
-int pci_hose_config_device(struct pci_controller *hose,
-                          pci_dev_t dev,
-                          unsigned long io,
-                          unsigned long mem,
-                          unsigned long command)
-{
-       unsigned int bar_response, bar_size, bar_value, old_command;
-       unsigned char pin;
-       int bar, found_mem64;
-
-       debug ("PCI Config: I/O=0x%lx, Memory=0x%lx, Command=0x%lx\n",
-               io, mem, command);
-
-       pci_hose_write_config_dword (hose, dev, PCI_COMMAND, 0);
-
-       for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_5; bar += 4) {
-               pci_hose_write_config_dword (hose, dev, bar, 0xffffffff);
-               pci_hose_read_config_dword (hose, dev, bar, &bar_response);
-
-               if (!bar_response)
-                       continue;
-
-               found_mem64 = 0;
-
-               /* Check the BAR type and set our address mask */
-               if (bar_response & PCI_BASE_ADDRESS_SPACE) {
-                       bar_size = ~(bar_response & PCI_BASE_ADDRESS_IO_MASK) + 1;
-                       /* round up region base address to a multiple of size */
-                       io = ((io - 1) | (bar_size - 1)) + 1;
-                       bar_value = io;
-                       /* compute new region base address */
-                       io = io + bar_size;
-               } else {
-                       if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
-                               PCI_BASE_ADDRESS_MEM_TYPE_64)
-                               found_mem64 = 1;
-
-                       bar_size = ~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1;
-
-                       /* round up region base address to multiple of size */
-                       mem = ((mem - 1) | (bar_size - 1)) + 1;
-                       bar_value = mem;
-                       /* compute new region base address */
-                       mem = mem + bar_size;
-               }
-
-               /* Write it out and update our limit */
-               pci_hose_write_config_dword (hose, dev, bar, bar_value);
-
-               if (found_mem64) {
-                       bar += 4;
-                       pci_hose_write_config_dword (hose, dev, bar, 0x00000000);
-               }
-       }
-
-       /* Configure Cache Line Size Register */
-       pci_hose_write_config_byte (hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
-
-       /* Configure Latency Timer */
-       pci_hose_write_config_byte (hose, dev, PCI_LATENCY_TIMER, 0x80);
-
-       /* Disable interrupt line, if device says it wants to use interrupts */
-       pci_hose_read_config_byte (hose, dev, PCI_INTERRUPT_PIN, &pin);
-       if (pin != 0) {
-               pci_hose_write_config_byte (hose, dev, PCI_INTERRUPT_LINE, 0xff);
-       }
-
-       pci_hose_read_config_dword (hose, dev, PCI_COMMAND, &old_command);
-       pci_hose_write_config_dword (hose, dev, PCI_COMMAND,
-                                    (old_command & 0xffff0000) | command);
-
-       return 0;
-}
-
-/*
- *
- */
-
-struct pci_config_table *pci_find_config(struct pci_controller *hose,
-                                        unsigned short class,
-                                        unsigned int vendor,
-                                        unsigned int device,
-                                        unsigned int bus,
-                                        unsigned int dev,
-                                        unsigned int func)
-{
-       struct pci_config_table *table;
-
-       for (table = hose->config_table; table && table->vendor; table++) {
-               if ((table->vendor == PCI_ANY_ID || table->vendor == vendor) &&
-                   (table->device == PCI_ANY_ID || table->device == device) &&
-                   (table->class  == PCI_ANY_ID || table->class  == class)  &&
-                   (table->bus    == PCI_ANY_ID || table->bus    == bus)    &&
-                   (table->dev    == PCI_ANY_ID || table->dev    == dev)    &&
-                   (table->func   == PCI_ANY_ID || table->func   == func)) {
-                       return table;
-               }
-       }
-
-       return NULL;
-}
-
-void pci_cfgfunc_config_device(struct pci_controller *hose,
-                              pci_dev_t dev,
-                              struct pci_config_table *entry)
-{
-       pci_hose_config_device(hose, dev, entry->priv[0], entry->priv[1], entry->priv[2]);
-}
-
-void pci_cfgfunc_do_nothing(struct pci_controller *hose,
-                           pci_dev_t dev, struct pci_config_table *entry)
-{
-}
-
-/*
- *
- */
-
-/* HJF: Changed this to return int. I think this is required
- * to get the correct result when scanning bridges
- */
-extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
-extern void pciauto_config_init(struct pci_controller *hose);
-
-int pci_hose_scan_bus(struct pci_controller *hose, int bus)
-{
-       unsigned int sub_bus, found_multi=0;
-       unsigned short vendor, device, class;
-       unsigned char header_type;
-       struct pci_config_table *cfg;
-       pci_dev_t dev;
-
-       sub_bus = bus;
-
-       for (dev =  PCI_BDF(bus,0,0);
-            dev <  PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1);
-            dev += PCI_BDF(0,0,1))
-       {
-               /* Skip our host bridge */
-               if ( dev == PCI_BDF(hose->first_busno,0,0) ) {
-#if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE)              /* don't skip host bridge */
-                       /*
-                        * Only skip hostbridge configuration if "pciconfighost" is not set
-                        */
-                       if (getenv("pciconfighost") == NULL) {
-                               continue; /* Skip our host bridge */
-                       }
-#else
-                       continue; /* Skip our host bridge */
-#endif
-               }
-
-               if (PCI_FUNC(dev) && !found_multi)
-                       continue;
-
-               pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);
-
-               pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor);
-
-               if (vendor != 0xffff && vendor != 0x0000) {
-
-                       if (!PCI_FUNC(dev))
-                               found_multi = header_type & 0x80;
-
-                       debug ("PCI Scan: Found Bus %d, Device %d, Function %d\n",
-                               PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev) );
-
-                       pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device);
-                       pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
-
-                       cfg = pci_find_config(hose, class, vendor, device,
-                                             PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));
-                       if (cfg) {
-                               cfg->config_device(hose, dev, cfg);
-                               sub_bus = max(sub_bus, hose->current_busno);
-#ifdef CONFIG_PCI_PNP
-                       } else {
-                               int n = pciauto_config_device(hose, dev);
-
-                               sub_bus = max(sub_bus, n);
-#endif
-                       }
-                       if (hose->fixup_irq)
-                               hose->fixup_irq(hose, dev);
-
-#ifdef CONFIG_PCI_SCAN_SHOW
-                       /* Skip our host bridge */
-                       if ( dev != PCI_BDF(hose->first_busno,0,0) ) {
-                           unsigned char int_line;
-
-                           pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_LINE,
-                                                     &int_line);
-                           printf("        %02x  %02x  %04x  %04x  %04x  %02x\n",
-                                  PCI_BUS(dev), PCI_DEV(dev), vendor, device, class,
-                                  int_line);
-                       }
-#endif
-               }
-       }
-
-       return sub_bus;
-}
-
-int pci_hose_scan(struct pci_controller *hose)
-{
-       /* Start scan at current_busno.
-        * PCIe will start scan at first_busno+1.
-        */
-       /* For legacy support, ensure current>=first */
-       if (hose->first_busno > hose->current_busno)
-               hose->current_busno = hose->first_busno;
-#ifdef CONFIG_PCI_PNP
-       pciauto_config_init(hose);
-#endif
-       return pci_hose_scan_bus(hose, hose->current_busno);
-}
-
-void pci_init(void)
-{
-#if defined(CONFIG_PCI_BOOTDELAY)
-       char *s;
-       int i;
-
-       /* wait "pcidelay" ms (if defined)... */
-       s = getenv ("pcidelay");
-       if (s) {
-               int val = simple_strtoul (s, NULL, 10);
-               for (i=0; i<val; i++)
-                       udelay (1000);
-       }
-#endif /* CONFIG_PCI_BOOTDELAY */
-
-       /* now call board specific pci_init()... */
-       pci_init_board();
-}
-
-#endif /* CONFIG_PCI */
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
new file mode 100644 (file)
index 0000000..fe45839
--- /dev/null
@@ -0,0 +1,51 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libpci.a
+
+COBJS-y += fsl_pci_init.o
+COBJS-y += pci.o
+COBJS-y += pci_auto.o
+COBJS-y += pci_indirect.o
+COBJS-y += tsi108_pci.o
+COBJS-y += w83c553f.o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c
new file mode 100644 (file)
index 0000000..1e77884
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2007 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * Version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_FSL_PCI_INIT
+
+/*
+ * PCI/PCIE Controller initialization for mpc85xx/mpc86xx soc's
+ *
+ * Initialize controller and call the common driver/pci pci_hose_scan to
+ * scan for bridges and devices.
+ *
+ * Hose fields which need to be pre-initialized by board specific code:
+ *   regions[]
+ *   first_busno
+ *
+ * Fields updated:
+ *   last_busno
+ */
+
+#include <pci.h>
+#include <asm/immap_fsl_pci.h>
+
+void pciauto_prescan_setup_bridge(struct pci_controller *hose,
+                               pci_dev_t dev, int sub_bus);
+void pciauto_postscan_setup_bridge(struct pci_controller *hose,
+                               pci_dev_t dev, int sub_bus);
+
+void pciauto_config_init(struct pci_controller *hose);
+void
+fsl_pci_init(struct pci_controller *hose)
+{
+       u16 temp16;
+       u32 temp32;
+       int busno = hose->first_busno;
+       int enabled;
+       u16 ltssm;
+       u8 temp8;
+       int r;
+       int bridge;
+       int inbound = 0;
+       volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) hose->cfg_addr;
+       pci_dev_t dev = PCI_BDF(busno,0,0);
+
+       /* Initialize ATMU registers based on hose regions and flags */
+       volatile pot_t *po=&pci->pot[1];        /* skip 0 */
+       volatile pit_t *pi=&pci->pit[0];        /* ranges from: 3 to 1 */
+
+#ifdef DEBUG
+       int neg_link_w;
+#endif
+
+       for (r=0; r<hose->region_count; r++) {
+               if (hose->regions[r].flags & PCI_REGION_MEMORY) { /* inbound */
+                       pi->pitar = (hose->regions[r].bus_start >> 12) & 0x000fffff;
+                       pi->piwbar = (hose->regions[r].phys_start >> 12) & 0x000fffff;
+                       pi->piwbear = 0;
+                       pi->piwar = PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
+                               PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP |
+                               (__ilog2(hose->regions[r].size) - 1);
+                       pi++;
+                       inbound = hose->regions[r].size > 0;
+               } else { /* Outbound */
+                       po->powbar = (hose->regions[r].phys_start >> 12) & 0x000fffff;
+                       po->potar = (hose->regions[r].bus_start >> 12) & 0x000fffff;
+                       po->potear = 0;
+                       if (hose->regions[r].flags & PCI_REGION_IO)
+                               po->powar = POWAR_EN | POWAR_IO_READ | POWAR_IO_WRITE |
+                                       (__ilog2(hose->regions[r].size) - 1);
+                       else
+                               po->powar = POWAR_EN | POWAR_MEM_READ | POWAR_MEM_WRITE |
+                                       (__ilog2(hose->regions[r].size) - 1);
+                       po++;
+               }
+       }
+
+       pci_register_hose(hose);
+       pciauto_config_init(hose);      /* grab pci_{mem,prefetch,io} */
+       hose->current_busno = hose->first_busno;
+
+       pci->pedr = 0xffffffff;         /* Clear any errors */
+       pci->peer = ~0x20140;           /* Enable All Error Interupts except
+                                        * - Master abort (pci)
+                                        * - Master PERR (pci)
+                                        * - ICCA (PCIe)
+                                        */
+       pci_hose_read_config_dword (hose, dev, PCI_DCR, &temp32);
+       temp32 |= 0xf000e;              /* set URR, FER, NFER (but not CER) */
+       pci_hose_write_config_dword(hose, dev, PCI_DCR, temp32);
+
+       pci_hose_read_config_byte (hose, dev, PCI_HEADER_TYPE, &temp8);
+       bridge = temp8 & PCI_HEADER_TYPE_BRIDGE; /* Bridge, such as pcie */
+
+       if ( bridge ) {
+
+               pci_hose_read_config_word(hose, dev, PCI_LTSSM, &ltssm);
+               enabled = ltssm >= PCI_LTSSM_L0;
+
+               if (!enabled) {
+                       debug("....PCIE link error.  Skipping scan."
+                             "LTSSM=0x%02x\n", ltssm);
+                       hose->last_busno = hose->first_busno;
+                       return;
+               }
+
+               pci->pme_msg_det = 0xffffffff;
+               pci->pme_msg_int_en = 0xffffffff;
+#ifdef DEBUG
+               pci_hose_read_config_word(hose, dev, PCI_LSR, &temp16);
+               neg_link_w = (temp16 & 0x3f0 ) >> 4;
+               printf("...PCIE LTSSM=0x%x, Negotiated link width=%d\n",
+                     ltssm, neg_link_w);
+#endif
+               hose->current_busno++; /* Start scan with secondary */
+               pciauto_prescan_setup_bridge(hose, dev, hose->current_busno);
+
+       }
+
+       /* Use generic setup_device to initialize standard pci regs,
+        * but do not allocate any windows since any BAR found (such
+        * as PCSRBAR) is not in this cpu's memory space.
+        */
+
+       pciauto_setup_device(hose, dev, 0, hose->pci_mem,
+                            hose->pci_prefetch, hose->pci_io);
+
+       if (inbound) {
+               pci_hose_read_config_word(hose, dev, PCI_COMMAND, &temp16);
+               pci_hose_write_config_word(hose, dev, PCI_COMMAND,
+                                          temp16 | PCI_COMMAND_MEMORY);
+       }
+
+#ifndef CONFIG_PCI_NOSCAN
+       printf ("               Scanning PCI bus %02x\n", hose->current_busno);
+       hose->last_busno = pci_hose_scan_bus(hose,hose->current_busno);
+
+       if ( bridge ) { /* update limit regs and subordinate busno */
+               pciauto_postscan_setup_bridge(hose, dev, hose->last_busno);
+       }
+#else
+       hose->last_busno = hose->current_busno;
+#endif
+
+       /* Clear all error indications */
+
+       pci->pme_msg_det = 0xffffffff;
+       pci->pedr = 0xffffffff;
+
+       pci_hose_read_config_word (hose, dev, PCI_DSR, &temp16);
+       if (temp16) {
+               pci_hose_write_config_word(hose, dev,
+                                       PCI_DSR, 0xffff);
+       }
+
+       pci_hose_read_config_word (hose, dev, PCI_SEC_STATUS, &temp16);
+       if (temp16) {
+               pci_hose_write_config_word(hose, dev, PCI_SEC_STATUS, 0xffff);
+       }
+}
+
+#endif /* CONFIG_FSL_PCI */
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
new file mode 100644 (file)
index 0000000..50ca6b0
--- /dev/null
@@ -0,0 +1,526 @@
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.de>
+ *
+ * (C) Copyright 2002, 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * PCI routines
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_PCI
+
+#include <command.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#define PCI_HOSE_OP(rw, size, type)                                    \
+int pci_hose_##rw##_config_##size(struct pci_controller *hose,                 \
+                                 pci_dev_t dev,                        \
+                                 int offset, type value)               \
+{                                                                      \
+       return hose->rw##_##size(hose, dev, offset, value);             \
+}
+
+PCI_HOSE_OP(read, byte, u8 *)
+PCI_HOSE_OP(read, word, u16 *)
+PCI_HOSE_OP(read, dword, u32 *)
+PCI_HOSE_OP(write, byte, u8)
+PCI_HOSE_OP(write, word, u16)
+PCI_HOSE_OP(write, dword, u32)
+
+#ifndef CONFIG_IXP425
+#define PCI_OP(rw, size, type, error_code)                             \
+int pci_##rw##_config_##size(pci_dev_t dev, int offset, type value)    \
+{                                                                      \
+       struct pci_controller *hose = pci_bus_to_hose(PCI_BUS(dev));    \
+                                                                       \
+       if (!hose)                                                      \
+       {                                                               \
+               error_code;                                             \
+               return -1;                                              \
+       }                                                               \
+                                                                       \
+       return pci_hose_##rw##_config_##size(hose, dev, offset, value); \
+}
+
+PCI_OP(read, byte, u8 *, *value = 0xff)
+PCI_OP(read, word, u16 *, *value = 0xffff)
+PCI_OP(read, dword, u32 *, *value = 0xffffffff)
+PCI_OP(write, byte, u8, )
+PCI_OP(write, word, u16, )
+PCI_OP(write, dword, u32, )
+#endif /* CONFIG_IXP425 */
+
+#define PCI_READ_VIA_DWORD_OP(size, type, off_mask)                    \
+int pci_hose_read_config_##size##_via_dword(struct pci_controller *hose,\
+                                       pci_dev_t dev,                  \
+                                       int offset, type val)           \
+{                                                                      \
+       u32 val32;                                                      \
+                                                                       \
+       if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0) { \
+               *val = -1;                                              \
+               return -1;                                              \
+       }                                                               \
+                                                                       \
+       *val = (val32 >> ((offset & (int)off_mask) * 8));               \
+                                                                       \
+       return 0;                                                       \
+}
+
+#define PCI_WRITE_VIA_DWORD_OP(size, type, off_mask, val_mask)         \
+int pci_hose_write_config_##size##_via_dword(struct pci_controller *hose,\
+                                            pci_dev_t dev,             \
+                                            int offset, type val)      \
+{                                                                      \
+       u32 val32, mask, ldata, shift;                                  \
+                                                                       \
+       if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0)\
+               return -1;                                              \
+                                                                       \
+       shift = ((offset & (int)off_mask) * 8);                         \
+       ldata = (((unsigned long)val) & val_mask) << shift;             \
+       mask = val_mask << shift;                                       \
+       val32 = (val32 & ~mask) | ldata;                                \
+                                                                       \
+       if (pci_hose_write_config_dword(hose, dev, offset & 0xfc, val32) < 0)\
+               return -1;                                              \
+                                                                       \
+       return 0;                                                       \
+}
+
+PCI_READ_VIA_DWORD_OP(byte, u8 *, 0x03)
+PCI_READ_VIA_DWORD_OP(word, u16 *, 0x02)
+PCI_WRITE_VIA_DWORD_OP(byte, u8, 0x03, 0x000000ff)
+PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff)
+
+/*
+ *
+ */
+
+static struct pci_controller* hose_head = NULL;
+
+void pci_register_hose(struct pci_controller* hose)
+{
+       struct pci_controller **phose = &hose_head;
+
+       while(*phose)
+               phose = &(*phose)->next;
+
+       hose->next = NULL;
+
+       *phose = hose;
+}
+
+struct pci_controller *pci_bus_to_hose (int bus)
+{
+       struct pci_controller *hose;
+
+       for (hose = hose_head; hose; hose = hose->next)
+               if (bus >= hose->first_busno && bus <= hose->last_busno)
+                       return hose;
+
+       printf("pci_bus_to_hose() failed\n");
+       return NULL;
+}
+
+#ifndef CONFIG_IXP425
+pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
+{
+       struct pci_controller * hose;
+       u16 vendor, device;
+       u8 header_type;
+       pci_dev_t bdf;
+       int i, bus, found_multi = 0;
+
+       for (hose = hose_head; hose; hose = hose->next)
+       {
+#ifdef CFG_SCSI_SCAN_BUS_REVERSE
+               for (bus = hose->last_busno; bus >= hose->first_busno; bus--)
+#else
+               for (bus = hose->first_busno; bus <= hose->last_busno; bus++)
+#endif
+                       for (bdf = PCI_BDF(bus,0,0);
+#if defined(CONFIG_ELPPC) || defined(CONFIG_PPMC7XX)
+                            bdf < PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1);
+#else
+                            bdf < PCI_BDF(bus+1,0,0);
+#endif
+                            bdf += PCI_BDF(0,0,1))
+                       {
+                               if (!PCI_FUNC(bdf)) {
+                                       pci_read_config_byte(bdf,
+                                                            PCI_HEADER_TYPE,
+                                                            &header_type);
+
+                                       found_multi = header_type & 0x80;
+                               } else {
+                                       if (!found_multi)
+                                               continue;
+                               }
+
+                               pci_read_config_word(bdf,
+                                                    PCI_VENDOR_ID,
+                                                    &vendor);
+                               pci_read_config_word(bdf,
+                                                    PCI_DEVICE_ID,
+                                                    &device);
+
+                               for (i=0; ids[i].vendor != 0; i++)
+                                       if (vendor == ids[i].vendor &&
+                                           device == ids[i].device)
+                                       {
+                                               if (index <= 0)
+                                                       return bdf;
+
+                                               index--;
+                                       }
+                       }
+       }
+
+       return (-1);
+}
+#endif /* CONFIG_IXP425 */
+
+pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
+{
+       static struct pci_device_id ids[2] = {{}, {0, 0}};
+
+       ids[0].vendor = vendor;
+       ids[0].device = device;
+
+       return pci_find_devices(ids, index);
+}
+
+/*
+ *
+ */
+
+unsigned long pci_hose_phys_to_bus (struct pci_controller *hose,
+                                   unsigned long phys_addr,
+                                   unsigned long flags)
+{
+       struct pci_region *res;
+       unsigned long bus_addr;
+       int i;
+
+       if (!hose) {
+               printf ("pci_hose_phys_to_bus: %s\n", "invalid hose");
+               goto Done;
+       }
+
+       for (i = 0; i < hose->region_count; i++) {
+               res = &hose->regions[i];
+
+               if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
+                       continue;
+
+               bus_addr = phys_addr - res->phys_start + res->bus_start;
+
+               if (bus_addr >= res->bus_start &&
+                       bus_addr < res->bus_start + res->size) {
+                       return bus_addr;
+               }
+       }
+
+       printf ("pci_hose_phys_to_bus: %s\n", "invalid physical address");
+
+Done:
+       return 0;
+}
+
+unsigned long pci_hose_bus_to_phys(struct pci_controller* hose,
+                                  unsigned long bus_addr,
+                                  unsigned long flags)
+{
+       struct pci_region *res;
+       int i;
+
+       if (!hose) {
+               printf ("pci_hose_bus_to_phys: %s\n", "invalid hose");
+               goto Done;
+       }
+
+       for (i = 0; i < hose->region_count; i++) {
+               res = &hose->regions[i];
+
+               if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
+                       continue;
+
+               if (bus_addr >= res->bus_start &&
+                       bus_addr < res->bus_start + res->size) {
+                       return bus_addr - res->bus_start + res->phys_start;
+               }
+       }
+
+       printf ("pci_hose_bus_to_phys: %s\n", "invalid physical address");
+
+Done:
+       return 0;
+}
+
+/*
+ *
+ */
+
+int pci_hose_config_device(struct pci_controller *hose,
+                          pci_dev_t dev,
+                          unsigned long io,
+                          unsigned long mem,
+                          unsigned long command)
+{
+       unsigned int bar_response, bar_size, bar_value, old_command;
+       unsigned char pin;
+       int bar, found_mem64;
+
+       debug ("PCI Config: I/O=0x%lx, Memory=0x%lx, Command=0x%lx\n",
+               io, mem, command);
+
+       pci_hose_write_config_dword (hose, dev, PCI_COMMAND, 0);
+
+       for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_5; bar += 4) {
+               pci_hose_write_config_dword (hose, dev, bar, 0xffffffff);
+               pci_hose_read_config_dword (hose, dev, bar, &bar_response);
+
+               if (!bar_response)
+                       continue;
+
+               found_mem64 = 0;
+
+               /* Check the BAR type and set our address mask */
+               if (bar_response & PCI_BASE_ADDRESS_SPACE) {
+                       bar_size = ~(bar_response & PCI_BASE_ADDRESS_IO_MASK) + 1;
+                       /* round up region base address to a multiple of size */
+                       io = ((io - 1) | (bar_size - 1)) + 1;
+                       bar_value = io;
+                       /* compute new region base address */
+                       io = io + bar_size;
+               } else {
+                       if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+                               PCI_BASE_ADDRESS_MEM_TYPE_64)
+                               found_mem64 = 1;
+
+                       bar_size = ~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1;
+
+                       /* round up region base address to multiple of size */
+                       mem = ((mem - 1) | (bar_size - 1)) + 1;
+                       bar_value = mem;
+                       /* compute new region base address */
+                       mem = mem + bar_size;
+               }
+
+               /* Write it out and update our limit */
+               pci_hose_write_config_dword (hose, dev, bar, bar_value);
+
+               if (found_mem64) {
+                       bar += 4;
+                       pci_hose_write_config_dword (hose, dev, bar, 0x00000000);
+               }
+       }
+
+       /* Configure Cache Line Size Register */
+       pci_hose_write_config_byte (hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
+
+       /* Configure Latency Timer */
+       pci_hose_write_config_byte (hose, dev, PCI_LATENCY_TIMER, 0x80);
+
+       /* Disable interrupt line, if device says it wants to use interrupts */
+       pci_hose_read_config_byte (hose, dev, PCI_INTERRUPT_PIN, &pin);
+       if (pin != 0) {
+               pci_hose_write_config_byte (hose, dev, PCI_INTERRUPT_LINE, 0xff);
+       }
+
+       pci_hose_read_config_dword (hose, dev, PCI_COMMAND, &old_command);
+       pci_hose_write_config_dword (hose, dev, PCI_COMMAND,
+                                    (old_command & 0xffff0000) | command);
+
+       return 0;
+}
+
+/*
+ *
+ */
+
+struct pci_config_table *pci_find_config(struct pci_controller *hose,
+                                        unsigned short class,
+                                        unsigned int vendor,
+                                        unsigned int device,
+                                        unsigned int bus,
+                                        unsigned int dev,
+                                        unsigned int func)
+{
+       struct pci_config_table *table;
+
+       for (table = hose->config_table; table && table->vendor; table++) {
+               if ((table->vendor == PCI_ANY_ID || table->vendor == vendor) &&
+                   (table->device == PCI_ANY_ID || table->device == device) &&
+                   (table->class  == PCI_ANY_ID || table->class  == class)  &&
+                   (table->bus    == PCI_ANY_ID || table->bus    == bus)    &&
+                   (table->dev    == PCI_ANY_ID || table->dev    == dev)    &&
+                   (table->func   == PCI_ANY_ID || table->func   == func)) {
+                       return table;
+               }
+       }
+
+       return NULL;
+}
+
+void pci_cfgfunc_config_device(struct pci_controller *hose,
+                              pci_dev_t dev,
+                              struct pci_config_table *entry)
+{
+       pci_hose_config_device(hose, dev, entry->priv[0], entry->priv[1], entry->priv[2]);
+}
+
+void pci_cfgfunc_do_nothing(struct pci_controller *hose,
+                           pci_dev_t dev, struct pci_config_table *entry)
+{
+}
+
+/*
+ *
+ */
+
+/* HJF: Changed this to return int. I think this is required
+ * to get the correct result when scanning bridges
+ */
+extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
+extern void pciauto_config_init(struct pci_controller *hose);
+
+int pci_hose_scan_bus(struct pci_controller *hose, int bus)
+{
+       unsigned int sub_bus, found_multi=0;
+       unsigned short vendor, device, class;
+       unsigned char header_type;
+       struct pci_config_table *cfg;
+       pci_dev_t dev;
+
+       sub_bus = bus;
+
+       for (dev =  PCI_BDF(bus,0,0);
+            dev <  PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1);
+            dev += PCI_BDF(0,0,1))
+       {
+               /* Skip our host bridge */
+               if ( dev == PCI_BDF(hose->first_busno,0,0) ) {
+#if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE)              /* don't skip host bridge */
+                       /*
+                        * Only skip hostbridge configuration if "pciconfighost" is not set
+                        */
+                       if (getenv("pciconfighost") == NULL) {
+                               continue; /* Skip our host bridge */
+                       }
+#else
+                       continue; /* Skip our host bridge */
+#endif
+               }
+
+               if (PCI_FUNC(dev) && !found_multi)
+                       continue;
+
+               pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);
+
+               pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor);
+
+               if (vendor != 0xffff && vendor != 0x0000) {
+
+                       if (!PCI_FUNC(dev))
+                               found_multi = header_type & 0x80;
+
+                       debug ("PCI Scan: Found Bus %d, Device %d, Function %d\n",
+                               PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev) );
+
+                       pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device);
+                       pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
+
+                       cfg = pci_find_config(hose, class, vendor, device,
+                                             PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));
+                       if (cfg) {
+                               cfg->config_device(hose, dev, cfg);
+                               sub_bus = max(sub_bus, hose->current_busno);
+#ifdef CONFIG_PCI_PNP
+                       } else {
+                               int n = pciauto_config_device(hose, dev);
+
+                               sub_bus = max(sub_bus, n);
+#endif
+                       }
+                       if (hose->fixup_irq)
+                               hose->fixup_irq(hose, dev);
+
+#ifdef CONFIG_PCI_SCAN_SHOW
+                       /* Skip our host bridge */
+                       if ( dev != PCI_BDF(hose->first_busno,0,0) ) {
+                           unsigned char int_line;
+
+                           pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_LINE,
+                                                     &int_line);
+                           printf("        %02x  %02x  %04x  %04x  %04x  %02x\n",
+                                  PCI_BUS(dev), PCI_DEV(dev), vendor, device, class,
+                                  int_line);
+                       }
+#endif
+               }
+       }
+
+       return sub_bus;
+}
+
+int pci_hose_scan(struct pci_controller *hose)
+{
+       /* Start scan at current_busno.
+        * PCIe will start scan at first_busno+1.
+        */
+       /* For legacy support, ensure current>=first */
+       if (hose->first_busno > hose->current_busno)
+               hose->current_busno = hose->first_busno;
+#ifdef CONFIG_PCI_PNP
+       pciauto_config_init(hose);
+#endif
+       return pci_hose_scan_bus(hose, hose->current_busno);
+}
+
+void pci_init(void)
+{
+#if defined(CONFIG_PCI_BOOTDELAY)
+       char *s;
+       int i;
+
+       /* wait "pcidelay" ms (if defined)... */
+       s = getenv ("pcidelay");
+       if (s) {
+               int val = simple_strtoul (s, NULL, 10);
+               for (i=0; i<val; i++)
+                       udelay (1000);
+       }
+#endif /* CONFIG_PCI_BOOTDELAY */
+
+       /* now call board specific pci_init()... */
+       pci_init_board();
+}
+
+#endif /* CONFIG_PCI */
diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c
new file mode 100644 (file)
index 0000000..acfda83
--- /dev/null
@@ -0,0 +1,412 @@
+/*
+ * arch/ppc/kernel/pci_auto.c
+ *
+ * PCI autoconfiguration library
+ *
+ * Author: Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_PCI
+
+#include <pci.h>
+
+#undef DEBUG
+#ifdef DEBUG
+#define DEBUGF(x...) printf(x)
+#else
+#define DEBUGF(x...)
+#endif /* DEBUG */
+
+#define        PCIAUTO_IDE_MODE_MASK           0x05
+
+/* the user can define CFG_PCI_CACHE_LINE_SIZE to avoid problems */
+#ifndef CFG_PCI_CACHE_LINE_SIZE
+#define CFG_PCI_CACHE_LINE_SIZE        8
+#endif
+
+/*
+ *
+ */
+
+void pciauto_region_init(struct pci_region* res)
+{
+       /*
+        * Avoid allocating PCI resources from address 0 -- this is illegal
+        * according to PCI 2.1 and moreover, this is known to cause Linux IDE
+        * drivers to fail. Use a reasonable starting value of 0x1000 instead.
+        */
+       res->bus_lower = res->bus_start ? res->bus_start : 0x1000;
+}
+
+void pciauto_region_align(struct pci_region *res, unsigned long size)
+{
+       res->bus_lower = ((res->bus_lower - 1) | (size - 1)) + 1;
+}
+
+int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned int *bar)
+{
+       unsigned long addr;
+
+       if (!res) {
+               DEBUGF("No resource");
+               goto error;
+       }
+
+       addr = ((res->bus_lower - 1) | (size - 1)) + 1;
+
+       if (addr - res->bus_start + size > res->size) {
+               DEBUGF("No room in resource");
+               goto error;
+       }
+
+       res->bus_lower = addr + size;
+
+       DEBUGF("address=0x%lx bus_lower=%x", addr, res->bus_lower);
+
+       *bar = addr;
+       return 0;
+
+ error:
+       *bar = 0xffffffff;
+       return -1;
+}
+
+/*
+ *
+ */
+
+void pciauto_setup_device(struct pci_controller *hose,
+                         pci_dev_t dev, int bars_num,
+                         struct pci_region *mem,
+                         struct pci_region *prefetch,
+                         struct pci_region *io)
+{
+       unsigned int bar_value, bar_response, bar_size;
+       unsigned int cmdstat = 0;
+       struct pci_region *bar_res;
+       int bar, bar_nr = 0;
+       int found_mem64 = 0;
+
+       pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
+       cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | PCI_COMMAND_MASTER;
+
+       for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_0 + (bars_num*4); bar += 4) {
+               /* Tickle the BAR and get the response */
+               pci_hose_write_config_dword(hose, dev, bar, 0xffffffff);
+               pci_hose_read_config_dword(hose, dev, bar, &bar_response);
+
+               /* If BAR is not implemented go to the next BAR */
+               if (!bar_response)
+                       continue;
+
+               found_mem64 = 0;
+
+               /* Check the BAR type and set our address mask */
+               if (bar_response & PCI_BASE_ADDRESS_SPACE) {
+                       bar_size = ((~(bar_response & PCI_BASE_ADDRESS_IO_MASK))
+                                  & 0xffff) + 1;
+                       bar_res = io;
+
+                       DEBUGF("PCI Autoconfig: BAR %d, I/O, size=0x%x, ", bar_nr, bar_size);
+               } else {
+                       if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+                            PCI_BASE_ADDRESS_MEM_TYPE_64)
+                               found_mem64 = 1;
+
+                       bar_size = ~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1;
+                       if (prefetch && (bar_response & PCI_BASE_ADDRESS_MEM_PREFETCH))
+                               bar_res = prefetch;
+                       else
+                               bar_res = mem;
+
+                       DEBUGF("PCI Autoconfig: BAR %d, Mem, size=0x%x, ", bar_nr, bar_size);
+               }
+
+               if (pciauto_region_allocate(bar_res, bar_size, &bar_value) == 0) {
+                       /* Write it out and update our limit */
+                       pci_hose_write_config_dword(hose, dev, bar, bar_value);
+
+                       /*
+                        * If we are a 64-bit decoder then increment to the
+                        * upper 32 bits of the bar and force it to locate
+                        * in the lower 4GB of memory.
+                        */
+                       if (found_mem64) {
+                               bar += 4;
+                               pci_hose_write_config_dword(hose, dev, bar, 0x00000000);
+                       }
+
+                       cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ?
+                               PCI_COMMAND_IO : PCI_COMMAND_MEMORY;
+               }
+
+               DEBUGF("\n");
+
+               bar_nr++;
+       }
+
+       pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat);
+       pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE,
+               CFG_PCI_CACHE_LINE_SIZE);
+       pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
+}
+
+void pciauto_prescan_setup_bridge(struct pci_controller *hose,
+                                        pci_dev_t dev, int sub_bus)
+{
+       struct pci_region *pci_mem = hose->pci_mem;
+       struct pci_region *pci_prefetch = hose->pci_prefetch;
+       struct pci_region *pci_io = hose->pci_io;
+       unsigned int cmdstat;
+
+       pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
+
+       /* Configure bus number registers */
+       pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS,
+                                  PCI_BUS(dev) - hose->first_busno);
+       pci_hose_write_config_byte(hose, dev, PCI_SECONDARY_BUS,
+                                  sub_bus - hose->first_busno);
+       pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, 0xff);
+
+       if (pci_mem) {
+               /* Round memory allocator to 1MB boundary */
+               pciauto_region_align(pci_mem, 0x100000);
+
+               /* Set up memory and I/O filter limits, assume 32-bit I/O space */
+               pci_hose_write_config_word(hose, dev, PCI_MEMORY_BASE,
+                                       (pci_mem->bus_lower & 0xfff00000) >> 16);
+
+               cmdstat |= PCI_COMMAND_MEMORY;
+       }
+
+       if (pci_prefetch) {
+               /* Round memory allocator to 1MB boundary */
+               pciauto_region_align(pci_prefetch, 0x100000);
+
+               /* Set up memory and I/O filter limits, assume 32-bit I/O space */
+               pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE,
+                                       (pci_prefetch->bus_lower & 0xfff00000) >> 16);
+
+               cmdstat |= PCI_COMMAND_MEMORY;
+       } else {
+               /* We don't support prefetchable memory for now, so disable */
+               pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, 0x1000);
+               pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, 0x0);
+       }
+
+       if (pci_io) {
+               /* Round I/O allocator to 4KB boundary */
+               pciauto_region_align(pci_io, 0x1000);
+
+               pci_hose_write_config_byte(hose, dev, PCI_IO_BASE,
+                                       (pci_io->bus_lower & 0x0000f000) >> 8);
+               pci_hose_write_config_word(hose, dev, PCI_IO_BASE_UPPER16,
+                                       (pci_io->bus_lower & 0xffff0000) >> 16);
+
+               cmdstat |= PCI_COMMAND_IO;
+       }
+
+       /* Enable memory and I/O accesses, enable bus master */
+       pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat | PCI_COMMAND_MASTER);
+}
+
+void pciauto_postscan_setup_bridge(struct pci_controller *hose,
+                                         pci_dev_t dev, int sub_bus)
+{
+       struct pci_region *pci_mem = hose->pci_mem;
+       struct pci_region *pci_prefetch = hose->pci_prefetch;
+       struct pci_region *pci_io = hose->pci_io;
+
+       /* Configure bus number registers */
+       pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS,
+                                  sub_bus - hose->first_busno);
+
+       if (pci_mem) {
+               /* Round memory allocator to 1MB boundary */
+               pciauto_region_align(pci_mem, 0x100000);
+
+               pci_hose_write_config_word(hose, dev, PCI_MEMORY_LIMIT,
+                                       (pci_mem->bus_lower-1) >> 16);
+       }
+
+       if (pci_prefetch) {
+               /* Round memory allocator to 1MB boundary */
+               pciauto_region_align(pci_prefetch, 0x100000);
+
+               pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT,
+                                       (pci_prefetch->bus_lower-1) >> 16);
+       }
+
+       if (pci_io) {
+               /* Round I/O allocator to 4KB boundary */
+               pciauto_region_align(pci_io, 0x1000);
+
+               pci_hose_write_config_byte(hose, dev, PCI_IO_LIMIT,
+                                       ((pci_io->bus_lower-1) & 0x0000f000) >> 8);
+               pci_hose_write_config_word(hose, dev, PCI_IO_LIMIT_UPPER16,
+                                       ((pci_io->bus_lower-1) & 0xffff0000) >> 16);
+       }
+}
+
+/*
+ *
+ */
+
+void pciauto_config_init(struct pci_controller *hose)
+{
+       int i;
+
+       hose->pci_io = hose->pci_mem = NULL;
+
+       for (i=0; i<hose->region_count; i++) {
+               switch(hose->regions[i].flags) {
+               case PCI_REGION_IO:
+                       if (!hose->pci_io ||
+                           hose->pci_io->size < hose->regions[i].size)
+                               hose->pci_io = hose->regions + i;
+                       break;
+               case PCI_REGION_MEM:
+                       if (!hose->pci_mem ||
+                           hose->pci_mem->size < hose->regions[i].size)
+                               hose->pci_mem = hose->regions + i;
+                       break;
+               case (PCI_REGION_MEM | PCI_REGION_PREFETCH):
+                       if (!hose->pci_prefetch ||
+                           hose->pci_prefetch->size < hose->regions[i].size)
+                               hose->pci_prefetch = hose->regions + i;
+                       break;
+               }
+       }
+
+
+       if (hose->pci_mem) {
+               pciauto_region_init(hose->pci_mem);
+
+               DEBUGF("PCI Autoconfig: Bus Memory region: [%lx-%lx],\n"
+                      "\t\tPhysical Memory [%x-%x]\n",
+                   hose->pci_mem->bus_start,
+                   hose->pci_mem->bus_start + hose->pci_mem->size - 1,
+                   hose->pci_mem->phys_start,
+                   hose->pci_mem->phys_start + hose->pci_mem->size - 1);
+       }
+
+       if (hose->pci_prefetch) {
+               pciauto_region_init(hose->pci_prefetch);
+
+               DEBUGF("PCI Autoconfig: Bus Prefetchable Mem: [%lx-%lx],\n"
+                      "\t\tPhysical Memory [%x-%x]\n",
+                   hose->pci_prefetch->bus_start,
+                   hose->pci_prefetch->bus_start + hose->pci_prefetch->size - 1,
+                   hose->pci_prefetch->phys_start,
+                   hose->pci_prefetch->phys_start +
+                               hose->pci_prefetch->size - 1);
+       }
+
+       if (hose->pci_io) {
+               pciauto_region_init(hose->pci_io);
+
+               DEBUGF("PCI Autoconfig: Bus I/O region: [%lx-%lx],\n"
+                      "\t\tPhysical Memory: [%x-%x]\n",
+                   hose->pci_io->bus_start,
+                   hose->pci_io->bus_start + hose->pci_io->size - 1,
+                   hose->pci_io->phys_start,
+                   hose->pci_io->phys_start + hose->pci_io->size - 1);
+
+       }
+}
+
+/* HJF: Changed this to return int. I think this is required
+ * to get the correct result when scanning bridges
+ */
+int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
+{
+       unsigned int sub_bus = PCI_BUS(dev);
+       unsigned short class;
+       unsigned char prg_iface;
+       int n;
+
+       pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
+
+       switch(class) {
+       case PCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */
+               DEBUGF("PCI AutoConfig: Found PowerPC device\n");
+               pciauto_setup_device(hose, dev, 6, hose->pci_mem,
+                                    hose->pci_prefetch, hose->pci_io);
+               break;
+
+       case PCI_CLASS_BRIDGE_PCI:
+               hose->current_busno++;
+               pciauto_setup_device(hose, dev, 2, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
+
+               DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_DEV(dev));
+
+               /* Passing in current_busno allows for sibling P2P bridges */
+               pciauto_prescan_setup_bridge(hose, dev, hose->current_busno);
+               /*
+                * need to figure out if this is a subordinate bridge on the bus
+                * to be able to properly set the pri/sec/sub bridge registers.
+                */
+               n = pci_hose_scan_bus(hose, hose->current_busno);
+
+               /* figure out the deepest we've gone for this leg */
+               sub_bus = max(n, sub_bus);
+               pciauto_postscan_setup_bridge(hose, dev, sub_bus);
+
+               sub_bus = hose->current_busno;
+               break;
+
+       case PCI_CLASS_STORAGE_IDE:
+               pci_hose_read_config_byte(hose, dev, PCI_CLASS_PROG, &prg_iface);
+               if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) {
+                       DEBUGF("PCI Autoconfig: Skipping legacy mode IDE controller\n");
+                       return sub_bus;
+               }
+
+               pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
+               break;
+
+       case PCI_CLASS_BRIDGE_CARDBUS:
+               /* just do a minimal setup of the bridge, let the OS take care of the rest */
+               pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
+
+               DEBUGF("PCI Autoconfig: Found P2CardBus bridge, device %d\n", PCI_DEV(dev));
+
+               hose->current_busno++;
+               break;
+
+#ifdef CONFIG_MPC5200
+       case PCI_CLASS_BRIDGE_OTHER:
+               DEBUGF("PCI Autoconfig: Skipping bridge device %d\n",
+                      PCI_DEV(dev));
+               break;
+#endif
+#ifdef CONFIG_MPC834X
+       case PCI_CLASS_BRIDGE_OTHER:
+               /*
+                * The host/PCI bridge 1 seems broken in 8349 - it presents
+                * itself as 'PCI_CLASS_BRIDGE_OTHER' and appears as an _agent_
+                * device claiming resources io/mem/irq.. we only allow for
+                * the PIMMR window to be allocated (BAR0 - 1MB size)
+                */
+               DEBUGF("PCI Autoconfig: Broken bridge found, only minimal config\n");
+               pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
+               break;
+#endif
+       default:
+               pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
+               break;
+       }
+
+       return sub_bus;
+}
+
+#endif /* CONFIG_PCI */
diff --git a/drivers/pci/pci_indirect.c b/drivers/pci/pci_indirect.c
new file mode 100644 (file)
index 0000000..a8220fb
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Support for indirect PCI bridges.
+ *
+ * Copyright (C) 1998 Gabriel Paubert.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_PCI
+#if (!defined(__I386__) && !defined(CONFIG_IXDP425))
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#define cfg_read(val, addr, type, op)  *val = op((type)(addr))
+#define cfg_write(val, addr, type, op) op((type *)(addr), (val))
+
+#ifdef CONFIG_IXP425
+extern unsigned char   in_8 (volatile unsigned *addr);
+extern unsigned short  in_le16 (volatile unsigned *addr);
+extern unsigned                in_le32 (volatile unsigned *addr);
+extern void            out_8 (volatile unsigned *addr, char val);
+extern void            out_le16 (volatile unsigned *addr, unsigned short val);
+extern void            out_le32 (volatile unsigned *addr, unsigned int val);
+#endif /* CONFIG_IXP425 */
+
+#if defined(CONFIG_MPC8260)
+#define INDIRECT_PCI_OP(rw, size, type, op, mask)                       \
+static int                                                              \
+indirect_##rw##_config_##size(struct pci_controller *hose,              \
+                             pci_dev_t dev, int offset, type val)       \
+{                                                                       \
+       u32 b, d,f;                                                      \
+       b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev);           \
+       b = b - hose->first_busno;                                       \
+       dev = PCI_BDF(b, d, f);                                          \
+       out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000000);    \
+       sync();                                                          \
+       cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);       \
+       return 0;                                                        \
+}
+#elif defined(CONFIG_E500) || defined(CONFIG_MPC86xx)
+#define INDIRECT_PCI_OP(rw, size, type, op, mask)                        \
+static int                                                               \
+indirect_##rw##_config_##size(struct pci_controller *hose,               \
+                             pci_dev_t dev, int offset, type val)       \
+{                                                                        \
+       u32 b, d,f;                                                      \
+       b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev);           \
+       b = b - hose->first_busno;                                       \
+       dev = PCI_BDF(b, d, f);                                          \
+       *(hose->cfg_addr) = dev | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000; \
+       sync();                                                          \
+       cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);       \
+       return 0;                                                        \
+}
+#elif defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SPE)
+#define INDIRECT_PCI_OP(rw, size, type, op, mask)                       \
+static int                                                              \
+indirect_##rw##_config_##size(struct pci_controller *hose,              \
+                             pci_dev_t dev, int offset, type val)       \
+{                                                                       \
+       u32 b, d,f;                                                      \
+       b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev);           \
+       b = b - hose->first_busno;                                       \
+       dev = PCI_BDF(b, d, f);                                          \
+       if (PCI_BUS(dev) > 0)                                            \
+               out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000001); \
+       else                                                             \
+               out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000000); \
+       cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);       \
+       return 0;                                                        \
+}
+#else
+#define INDIRECT_PCI_OP(rw, size, type, op, mask)                       \
+static int                                                              \
+indirect_##rw##_config_##size(struct pci_controller *hose,              \
+                             pci_dev_t dev, int offset, type val)       \
+{                                                                       \
+       u32 b, d,f;                                                      \
+       b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev);           \
+       b = b - hose->first_busno;                                       \
+       dev = PCI_BDF(b, d, f);                                          \
+       out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000000);    \
+       cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);       \
+       return 0;                                                        \
+}
+#endif
+
+#define INDIRECT_PCI_OP_ERRATA6(rw, size, type, op, mask)               \
+static int                                                              \
+indirect_##rw##_config_##size(struct pci_controller *hose,              \
+                             pci_dev_t dev, int offset, type val)       \
+{                                                                       \
+       unsigned int msr = mfmsr();                                      \
+       mtmsr(msr & ~(MSR_EE | MSR_CE));                                 \
+       out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000000);    \
+       cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);       \
+       out_le32(hose->cfg_addr, 0x00000000);                            \
+       mtmsr(msr);                                                      \
+       return 0;                                                        \
+}
+
+INDIRECT_PCI_OP(read, byte, u8 *, in_8, 3)
+INDIRECT_PCI_OP(read, word, u16 *, in_le16, 2)
+INDIRECT_PCI_OP(read, dword, u32 *, in_le32, 0)
+#ifdef CONFIG_405GP
+INDIRECT_PCI_OP_ERRATA6(write, byte, u8, out_8, 3)
+INDIRECT_PCI_OP_ERRATA6(write, word, u16, out_le16, 2)
+INDIRECT_PCI_OP_ERRATA6(write, dword, u32, out_le32, 0)
+#else
+INDIRECT_PCI_OP(write, byte, u8, out_8, 3)
+INDIRECT_PCI_OP(write, word, u16, out_le16, 2)
+INDIRECT_PCI_OP(write, dword, u32, out_le32, 0)
+#endif
+
+void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
+{
+       pci_set_ops(hose,
+                   indirect_read_config_byte,
+                   indirect_read_config_word,
+                   indirect_read_config_dword,
+                   indirect_write_config_byte,
+                   indirect_write_config_word,
+                   indirect_write_config_dword);
+
+       hose->cfg_addr = (unsigned int *) cfg_addr;
+       hose->cfg_data = (unsigned char *) cfg_data;
+}
+
+#endif /* !__I386__ && !CONFIG_IXDP425 */
+#endif /* CONFIG_PCI */
diff --git a/drivers/pci/tsi108_pci.c b/drivers/pci/tsi108_pci.c
new file mode 100644 (file)
index 0000000..d5f11e4
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * (C) Copyright 2004 Tundra Semiconductor Corp.
+ * Alex Bounine <alexandreb@tundra.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * PCI initialisation for the Tsi108 EMU board.
+ */
+
+#include <config.h>
+
+#ifdef CONFIG_TSI108_PCI
+
+#include <common.h>
+#include <pci.h>
+#include <asm/io.h>
+#include <tsi108.h>
+#ifdef CONFIG_OF_FLAT_TREE
+#include <ft_build.h>
+#endif
+
+struct pci_controller local_hose;
+
+void tsi108_clear_pci_error (void)
+{
+       u32 err_stat, err_addr, pci_stat;
+
+       /*
+        * Quietly clear errors signalled as result of PCI/X configuration read
+        * requests.
+        */
+       /* Read PB Error Log Registers */
+       err_stat = *(volatile u32 *)(CFG_TSI108_CSR_BASE +
+                                    TSI108_PB_REG_OFFSET + PB_ERRCS);
+       err_addr = *(volatile u32 *)(CFG_TSI108_CSR_BASE +
+                                    TSI108_PB_REG_OFFSET + PB_AERR);
+       if (err_stat & PB_ERRCS_ES) {
+               /* Clear PCI/X bus errors if applicable */
+               if ((err_addr & 0xFF000000) == CFG_PCI_CFG_BASE) {
+                       /* Clear error flag */
+                       *(u32 *) (CFG_TSI108_CSR_BASE +
+                                 TSI108_PB_REG_OFFSET + PB_ERRCS) =
+                           PB_ERRCS_ES;
+
+                       /* Clear read error reported in PB_ISR */
+                       *(u32 *) (CFG_TSI108_CSR_BASE +
+                                 TSI108_PB_REG_OFFSET + PB_ISR) =
+                           PB_ISR_PBS_RD_ERR;
+
+               /* Clear errors reported by PCI CSR (Normally Master Abort) */
+                       pci_stat = *(volatile u32 *)(CFG_TSI108_CSR_BASE +
+                                                    TSI108_PCI_REG_OFFSET +
+                                                    PCI_CSR);
+                       *(volatile u32 *)(CFG_TSI108_CSR_BASE +
+                                         TSI108_PCI_REG_OFFSET + PCI_CSR) =
+                           pci_stat;
+
+                       *(volatile u32 *)(CFG_TSI108_CSR_BASE +
+                                         TSI108_PCI_REG_OFFSET +
+                                         PCI_IRP_STAT) = PCI_IRP_STAT_P_CSR;
+               }
+       }
+
+       return;
+}
+
+unsigned int __get_pci_config_dword (u32 addr)
+{
+       unsigned int retval;
+
+       __asm__ __volatile__ ("       lwbrx %0,0,%1\n"
+                            "1:     eieio\n"
+                            "2:\n"
+                            ".section .fixup,\"ax\"\n"
+                            "3:     li %0,-1\n"
+                            "       b 2b\n"
+                            ".section __ex_table,\"a\"\n"
+                            "       .align 2\n"
+                            "       .long 1b,3b\n"
+                            ".text":"=r"(retval):"r"(addr));
+
+       return (retval);
+}
+
+static int tsi108_read_config_dword (struct pci_controller *hose,
+                                   pci_dev_t dev, int offset, u32 * value)
+{
+       dev &= (CFG_PCI_CFG_SIZE - 1);
+       dev |= (CFG_PCI_CFG_BASE | (offset & 0xfc));
+       *value = __get_pci_config_dword(dev);
+       if (0xFFFFFFFF == *value)
+               tsi108_clear_pci_error ();
+       return 0;
+}
+
+static int tsi108_write_config_dword (struct pci_controller *hose,
+                                    pci_dev_t dev, int offset, u32 value)
+{
+       dev &= (CFG_PCI_CFG_SIZE - 1);
+       dev |= (CFG_PCI_CFG_BASE | (offset & 0xfc));
+
+       out_le32 ((volatile unsigned *)dev, value);
+
+       return 0;
+}
+
+void pci_init_board (void)
+{
+       struct pci_controller *hose = (struct pci_controller *)&local_hose;
+
+       hose->first_busno = 0;
+       hose->last_busno = 0xff;
+
+       pci_set_region (hose->regions + 0,
+                      CFG_PCI_MEMORY_BUS,
+                      CFG_PCI_MEMORY_PHYS,
+                      CFG_PCI_MEMORY_SIZE, PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+       /* PCI memory space */
+       pci_set_region (hose->regions + 1,
+                      CFG_PCI_MEM_BUS,
+                      CFG_PCI_MEM_PHYS, CFG_PCI_MEM_SIZE, PCI_REGION_MEM);
+
+       /* PCI I/O space */
+       pci_set_region (hose->regions + 2,
+                      CFG_PCI_IO_BUS,
+                      CFG_PCI_IO_PHYS, CFG_PCI_IO_SIZE, PCI_REGION_IO);
+
+       hose->region_count = 3;
+
+       pci_set_ops (hose,
+                   pci_hose_read_config_byte_via_dword,
+                   pci_hose_read_config_word_via_dword,
+                   tsi108_read_config_dword,
+                   pci_hose_write_config_byte_via_dword,
+                   pci_hose_write_config_word_via_dword,
+                   tsi108_write_config_dword);
+
+       pci_register_hose (hose);
+
+       hose->last_busno = pci_hose_scan (hose);
+
+       debug ("Done PCI initialization\n");
+       return;
+}
+
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_pci_setup (void *blob, bd_t *bd)
+{
+       u32 *p;
+       int len;
+
+       p = (u32 *)ft_get_prop (blob, "/" OF_TSI "/pci@1000/bus-range", &len);
+       if (p != NULL) {
+               p[0] = local_hose.first_busno;
+               p[1] = local_hose.last_busno;
+       }
+
+}
+#endif
+
+#endif /* CONFIG_TSI108_PCI */
diff --git a/drivers/pci/w83c553f.c b/drivers/pci/w83c553f.c
new file mode 100644 (file)
index 0000000..5d82ed4
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Initialisation of the PCI-to-ISA bridge and disabling the BIOS
+ * write protection (for flash) in function 0 of the chip.
+ * Enabling function 1 (IDE controller of the chip.
+ */
+
+#include <common.h>
+#include <config.h>
+
+#ifdef CFG_WINBOND_83C553
+
+#include <asm/io.h>
+#include <pci.h>
+
+#include <w83c553f.h>
+
+#define out8(addr,val) do { \
+                       out_8((u8*) (addr),(val)); udelay(1); \
+                       } while (0)
+#define out16(addr,val)        do { \
+                       out_be16((u16*) (addr),(val)); udelay(1); \
+                       } while (0)
+
+extern uint ide_bus_offset[CFG_IDE_MAXBUS];
+
+void initialise_pic(void);
+void initialise_dma(void);
+
+void initialise_w83c553f(void)
+{
+       pci_dev_t devbusfn;
+       unsigned char reg8;
+       unsigned short reg16;
+       unsigned int reg32;
+
+       devbusfn = pci_find_device(W83C553F_VID, W83C553F_DID, 0);
+       if (devbusfn == -1)
+       {
+               printf("Error: Cannot find W83C553F controller on any PCI bus.");
+               return;
+       }
+
+       pci_read_config_word(devbusfn, PCI_COMMAND, &reg16);
+       reg16 |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+       pci_write_config_word(devbusfn, PCI_COMMAND, reg16);
+
+       pci_read_config_byte(devbusfn, WINBOND_IPADCR, &reg8);
+       /* 16 MB ISA memory space */
+       reg8 |= (IPADCR_IPATOM4 | IPADCR_IPATOM5 | IPADCR_IPATOM6 | IPADCR_IPATOM7);
+       reg8 &= ~IPADCR_MBE512;
+       pci_write_config_byte(devbusfn, WINBOND_IPADCR, reg8);
+
+       pci_read_config_byte(devbusfn, WINBOND_CSCR, &reg8);
+       /* switch off BIOS write protection */
+       reg8 |= CSCR_UBIOSCSE;
+       reg8 &= ~CSCR_BIOSWP;
+       pci_write_config_byte(devbusfn, WINBOND_CSCR, reg8);
+
+       /*
+        * Interrupt routing:
+        *  - IDE  -> IRQ 9/0
+        *  - INTA -> IRQ 10
+        *  - INTB -> IRQ 11
+        *  - INTC -> IRQ 14
+        *  - INTD -> IRQ 15
+        */
+       pci_write_config_byte(devbusfn, WINBOND_IDEIRCR, 0x90);
+       pci_write_config_word(devbusfn, WINBOND_PCIIRCR, 0xABEF);
+
+       /*
+        * Read IDE bus offsets from function 1 device.
+        * We must unmask the LSB indicating that ist is an IO address.
+        */
+       devbusfn |= PCI_BDF(0,0,1);
+
+       /*
+        * Switch off legacy IRQ for IDE and IDE port 1.
+        */
+       pci_write_config_byte(devbusfn, 0x09, 0x8F);
+
+       pci_read_config_dword(devbusfn, WINDOND_IDECSR, &reg32);
+       reg32 &= ~(IDECSR_LEGIRQ | IDECSR_P1EN | IDECSR_P1F16);
+       pci_write_config_dword(devbusfn, WINDOND_IDECSR, reg32);
+
+       pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &ide_bus_offset[0]);
+       ide_bus_offset[0] &= ~1;
+#if CFG_IDE_MAXBUS > 1
+       pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_2, &ide_bus_offset[1]);
+       ide_bus_offset[1] &= ~1;
+#endif
+
+       /*
+        * Enable function 1, IDE -> busmastering and IO space access
+        */
+       pci_read_config_word(devbusfn, PCI_COMMAND, &reg16);
+       reg16 |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+       pci_write_config_word(devbusfn, PCI_COMMAND, reg16);
+
+       /*
+        * Initialise ISA interrupt controller
+        */
+       initialise_pic();
+
+       /*
+        * Initialise DMA controller
+        */
+       initialise_dma();
+}
+
+void initialise_pic(void)
+{
+       out8(W83C553F_PIC1_ICW1, 0x11);
+       out8(W83C553F_PIC1_ICW2, 0x08);
+       out8(W83C553F_PIC1_ICW3, 0x04);
+       out8(W83C553F_PIC1_ICW4, 0x01);
+       out8(W83C553F_PIC1_OCW1, 0xfb);
+       out8(W83C553F_PIC1_ELC, 0x20);
+
+       out8(W83C553F_PIC2_ICW1, 0x11);
+       out8(W83C553F_PIC2_ICW2, 0x08);
+       out8(W83C553F_PIC2_ICW3, 0x02);
+       out8(W83C553F_PIC2_ICW4, 0x01);
+       out8(W83C553F_PIC2_OCW1, 0xff);
+       out8(W83C553F_PIC2_ELC, 0xce);
+
+       out8(W83C553F_TMR1_CMOD, 0x74);
+
+       out8(W83C553F_PIC2_OCW1, 0x20);
+       out8(W83C553F_PIC1_OCW1, 0x20);
+
+       out8(W83C553F_PIC2_OCW1, 0x2b);
+       out8(W83C553F_PIC1_OCW1, 0x2b);
+}
+
+void initialise_dma(void)
+{
+       unsigned int channel;
+       unsigned int rvalue1, rvalue2;
+
+       /* perform a H/W reset of the devices */
+
+       out8(W83C553F_DMA1 + W83C553F_DMA1_MC, 0x00);
+       out16(W83C553F_DMA2 + W83C553F_DMA2_MC, 0x0000);
+
+       /* initialise all channels to a sane state */
+
+       for (channel = 0; channel < 4; channel++) {
+               /*
+                * dependent upon the channel, setup the specifics:
+                *
+                * demand
+                * address-increment
+                * autoinitialize-disable
+                * verify-transfer
+                */
+
+               switch (channel) {
+               case 0:
+                       rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH0SEL|W83C553F_MODE_TT_VERIFY);
+                       rvalue2 = (W83C553F_MODE_TM_CASCADE|W83C553F_MODE_CH0SEL);
+                       break;
+               case 1:
+                       rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH1SEL|W83C553F_MODE_TT_VERIFY);
+                       rvalue2 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH1SEL|W83C553F_MODE_TT_VERIFY);
+                       break;
+               case 2:
+                       rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH2SEL|W83C553F_MODE_TT_VERIFY);
+                       rvalue2 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH2SEL|W83C553F_MODE_TT_VERIFY);
+                       break;
+               case 3:
+                       rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH3SEL|W83C553F_MODE_TT_VERIFY);
+                       rvalue2 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH3SEL|W83C553F_MODE_TT_VERIFY);
+                       break;
+               default:
+                       rvalue1 = 0x00;
+                       rvalue2 = 0x00;
+                       break;
+               }
+
+               /* write to write mode registers */
+
+               out8(W83C553F_DMA1 + W83C553F_DMA1_WM, rvalue1 & 0xFF);
+               out16(W83C553F_DMA2 + W83C553F_DMA2_WM, rvalue2 & 0x00FF);
+       }
+
+       /* enable all channels */
+
+       out8(W83C553F_DMA1 + W83C553F_DMA1_CM, 0x00);
+       out16(W83C553F_DMA2 + W83C553F_DMA2_CM, 0x0000);
+       /*
+        * initialize the global DMA configuration
+        *
+        * DACK# active low
+        * DREQ active high
+        * fixed priority
+        * channel group enable
+        */
+
+       out8(W83C553F_DMA1 + W83C553F_DMA1_CS, 0x00);
+       out16(W83C553F_DMA2 + W83C553F_DMA2_CS, 0x0000);
+}
+
+#endif /* CFG_WINBOND_83C553 */
diff --git a/drivers/pci_auto.c b/drivers/pci_auto.c
deleted file mode 100644 (file)
index acfda83..0000000
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * arch/ppc/kernel/pci_auto.c
- *
- * PCI autoconfiguration library
- *
- * Author: Matt Porter <mporter@mvista.com>
- *
- * Copyright 2000 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#include <common.h>
-
-#ifdef CONFIG_PCI
-
-#include <pci.h>
-
-#undef DEBUG
-#ifdef DEBUG
-#define DEBUGF(x...) printf(x)
-#else
-#define DEBUGF(x...)
-#endif /* DEBUG */
-
-#define        PCIAUTO_IDE_MODE_MASK           0x05
-
-/* the user can define CFG_PCI_CACHE_LINE_SIZE to avoid problems */
-#ifndef CFG_PCI_CACHE_LINE_SIZE
-#define CFG_PCI_CACHE_LINE_SIZE        8
-#endif
-
-/*
- *
- */
-
-void pciauto_region_init(struct pci_region* res)
-{
-       /*
-        * Avoid allocating PCI resources from address 0 -- this is illegal
-        * according to PCI 2.1 and moreover, this is known to cause Linux IDE
-        * drivers to fail. Use a reasonable starting value of 0x1000 instead.
-        */
-       res->bus_lower = res->bus_start ? res->bus_start : 0x1000;
-}
-
-void pciauto_region_align(struct pci_region *res, unsigned long size)
-{
-       res->bus_lower = ((res->bus_lower - 1) | (size - 1)) + 1;
-}
-
-int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned int *bar)
-{
-       unsigned long addr;
-
-       if (!res) {
-               DEBUGF("No resource");
-               goto error;
-       }
-
-       addr = ((res->bus_lower - 1) | (size - 1)) + 1;
-
-       if (addr - res->bus_start + size > res->size) {
-               DEBUGF("No room in resource");
-               goto error;
-       }
-
-       res->bus_lower = addr + size;
-
-       DEBUGF("address=0x%lx bus_lower=%x", addr, res->bus_lower);
-
-       *bar = addr;
-       return 0;
-
- error:
-       *bar = 0xffffffff;
-       return -1;
-}
-
-/*
- *
- */
-
-void pciauto_setup_device(struct pci_controller *hose,
-                         pci_dev_t dev, int bars_num,
-                         struct pci_region *mem,
-                         struct pci_region *prefetch,
-                         struct pci_region *io)
-{
-       unsigned int bar_value, bar_response, bar_size;
-       unsigned int cmdstat = 0;
-       struct pci_region *bar_res;
-       int bar, bar_nr = 0;
-       int found_mem64 = 0;
-
-       pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
-       cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | PCI_COMMAND_MASTER;
-
-       for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_0 + (bars_num*4); bar += 4) {
-               /* Tickle the BAR and get the response */
-               pci_hose_write_config_dword(hose, dev, bar, 0xffffffff);
-               pci_hose_read_config_dword(hose, dev, bar, &bar_response);
-
-               /* If BAR is not implemented go to the next BAR */
-               if (!bar_response)
-                       continue;
-
-               found_mem64 = 0;
-
-               /* Check the BAR type and set our address mask */
-               if (bar_response & PCI_BASE_ADDRESS_SPACE) {
-                       bar_size = ((~(bar_response & PCI_BASE_ADDRESS_IO_MASK))
-                                  & 0xffff) + 1;
-                       bar_res = io;
-
-                       DEBUGF("PCI Autoconfig: BAR %d, I/O, size=0x%x, ", bar_nr, bar_size);
-               } else {
-                       if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
-                            PCI_BASE_ADDRESS_MEM_TYPE_64)
-                               found_mem64 = 1;
-
-                       bar_size = ~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1;
-                       if (prefetch && (bar_response & PCI_BASE_ADDRESS_MEM_PREFETCH))
-                               bar_res = prefetch;
-                       else
-                               bar_res = mem;
-
-                       DEBUGF("PCI Autoconfig: BAR %d, Mem, size=0x%x, ", bar_nr, bar_size);
-               }
-
-               if (pciauto_region_allocate(bar_res, bar_size, &bar_value) == 0) {
-                       /* Write it out and update our limit */
-                       pci_hose_write_config_dword(hose, dev, bar, bar_value);
-
-                       /*
-                        * If we are a 64-bit decoder then increment to the
-                        * upper 32 bits of the bar and force it to locate
-                        * in the lower 4GB of memory.
-                        */
-                       if (found_mem64) {
-                               bar += 4;
-                               pci_hose_write_config_dword(hose, dev, bar, 0x00000000);
-                       }
-
-                       cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ?
-                               PCI_COMMAND_IO : PCI_COMMAND_MEMORY;
-               }
-
-               DEBUGF("\n");
-
-               bar_nr++;
-       }
-
-       pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat);
-       pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE,
-               CFG_PCI_CACHE_LINE_SIZE);
-       pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
-}
-
-void pciauto_prescan_setup_bridge(struct pci_controller *hose,
-                                        pci_dev_t dev, int sub_bus)
-{
-       struct pci_region *pci_mem = hose->pci_mem;
-       struct pci_region *pci_prefetch = hose->pci_prefetch;
-       struct pci_region *pci_io = hose->pci_io;
-       unsigned int cmdstat;
-
-       pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
-
-       /* Configure bus number registers */
-       pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS,
-                                  PCI_BUS(dev) - hose->first_busno);
-       pci_hose_write_config_byte(hose, dev, PCI_SECONDARY_BUS,
-                                  sub_bus - hose->first_busno);
-       pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, 0xff);
-
-       if (pci_mem) {
-               /* Round memory allocator to 1MB boundary */
-               pciauto_region_align(pci_mem, 0x100000);
-
-               /* Set up memory and I/O filter limits, assume 32-bit I/O space */
-               pci_hose_write_config_word(hose, dev, PCI_MEMORY_BASE,
-                                       (pci_mem->bus_lower & 0xfff00000) >> 16);
-
-               cmdstat |= PCI_COMMAND_MEMORY;
-       }
-
-       if (pci_prefetch) {
-               /* Round memory allocator to 1MB boundary */
-               pciauto_region_align(pci_prefetch, 0x100000);
-
-               /* Set up memory and I/O filter limits, assume 32-bit I/O space */
-               pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE,
-                                       (pci_prefetch->bus_lower & 0xfff00000) >> 16);
-
-               cmdstat |= PCI_COMMAND_MEMORY;
-       } else {
-               /* We don't support prefetchable memory for now, so disable */
-               pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, 0x1000);
-               pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, 0x0);
-       }
-
-       if (pci_io) {
-               /* Round I/O allocator to 4KB boundary */
-               pciauto_region_align(pci_io, 0x1000);
-
-               pci_hose_write_config_byte(hose, dev, PCI_IO_BASE,
-                                       (pci_io->bus_lower & 0x0000f000) >> 8);
-               pci_hose_write_config_word(hose, dev, PCI_IO_BASE_UPPER16,
-                                       (pci_io->bus_lower & 0xffff0000) >> 16);
-
-               cmdstat |= PCI_COMMAND_IO;
-       }
-
-       /* Enable memory and I/O accesses, enable bus master */
-       pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat | PCI_COMMAND_MASTER);
-}
-
-void pciauto_postscan_setup_bridge(struct pci_controller *hose,
-                                         pci_dev_t dev, int sub_bus)
-{
-       struct pci_region *pci_mem = hose->pci_mem;
-       struct pci_region *pci_prefetch = hose->pci_prefetch;
-       struct pci_region *pci_io = hose->pci_io;
-
-       /* Configure bus number registers */
-       pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS,
-                                  sub_bus - hose->first_busno);
-
-       if (pci_mem) {
-               /* Round memory allocator to 1MB boundary */
-               pciauto_region_align(pci_mem, 0x100000);
-
-               pci_hose_write_config_word(hose, dev, PCI_MEMORY_LIMIT,
-                                       (pci_mem->bus_lower-1) >> 16);
-       }
-
-       if (pci_prefetch) {
-               /* Round memory allocator to 1MB boundary */
-               pciauto_region_align(pci_prefetch, 0x100000);
-
-               pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT,
-                                       (pci_prefetch->bus_lower-1) >> 16);
-       }
-
-       if (pci_io) {
-               /* Round I/O allocator to 4KB boundary */
-               pciauto_region_align(pci_io, 0x1000);
-
-               pci_hose_write_config_byte(hose, dev, PCI_IO_LIMIT,
-                                       ((pci_io->bus_lower-1) & 0x0000f000) >> 8);
-               pci_hose_write_config_word(hose, dev, PCI_IO_LIMIT_UPPER16,
-                                       ((pci_io->bus_lower-1) & 0xffff0000) >> 16);
-       }
-}
-
-/*
- *
- */
-
-void pciauto_config_init(struct pci_controller *hose)
-{
-       int i;
-
-       hose->pci_io = hose->pci_mem = NULL;
-
-       for (i=0; i<hose->region_count; i++) {
-               switch(hose->regions[i].flags) {
-               case PCI_REGION_IO:
-                       if (!hose->pci_io ||
-                           hose->pci_io->size < hose->regions[i].size)
-                               hose->pci_io = hose->regions + i;
-                       break;
-               case PCI_REGION_MEM:
-                       if (!hose->pci_mem ||
-                           hose->pci_mem->size < hose->regions[i].size)
-                               hose->pci_mem = hose->regions + i;
-                       break;
-               case (PCI_REGION_MEM | PCI_REGION_PREFETCH):
-                       if (!hose->pci_prefetch ||
-                           hose->pci_prefetch->size < hose->regions[i].size)
-                               hose->pci_prefetch = hose->regions + i;
-                       break;
-               }
-       }
-
-
-       if (hose->pci_mem) {
-               pciauto_region_init(hose->pci_mem);
-
-               DEBUGF("PCI Autoconfig: Bus Memory region: [%lx-%lx],\n"
-                      "\t\tPhysical Memory [%x-%x]\n",
-                   hose->pci_mem->bus_start,
-                   hose->pci_mem->bus_start + hose->pci_mem->size - 1,
-                   hose->pci_mem->phys_start,
-                   hose->pci_mem->phys_start + hose->pci_mem->size - 1);
-       }
-
-       if (hose->pci_prefetch) {
-               pciauto_region_init(hose->pci_prefetch);
-
-               DEBUGF("PCI Autoconfig: Bus Prefetchable Mem: [%lx-%lx],\n"
-                      "\t\tPhysical Memory [%x-%x]\n",
-                   hose->pci_prefetch->bus_start,
-                   hose->pci_prefetch->bus_start + hose->pci_prefetch->size - 1,
-                   hose->pci_prefetch->phys_start,
-                   hose->pci_prefetch->phys_start +
-                               hose->pci_prefetch->size - 1);
-       }
-
-       if (hose->pci_io) {
-               pciauto_region_init(hose->pci_io);
-
-               DEBUGF("PCI Autoconfig: Bus I/O region: [%lx-%lx],\n"
-                      "\t\tPhysical Memory: [%x-%x]\n",
-                   hose->pci_io->bus_start,
-                   hose->pci_io->bus_start + hose->pci_io->size - 1,
-                   hose->pci_io->phys_start,
-                   hose->pci_io->phys_start + hose->pci_io->size - 1);
-
-       }
-}
-
-/* HJF: Changed this to return int. I think this is required
- * to get the correct result when scanning bridges
- */
-int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
-{
-       unsigned int sub_bus = PCI_BUS(dev);
-       unsigned short class;
-       unsigned char prg_iface;
-       int n;
-
-       pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
-
-       switch(class) {
-       case PCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */
-               DEBUGF("PCI AutoConfig: Found PowerPC device\n");
-               pciauto_setup_device(hose, dev, 6, hose->pci_mem,
-                                    hose->pci_prefetch, hose->pci_io);
-               break;
-
-       case PCI_CLASS_BRIDGE_PCI:
-               hose->current_busno++;
-               pciauto_setup_device(hose, dev, 2, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
-
-               DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_DEV(dev));
-
-               /* Passing in current_busno allows for sibling P2P bridges */
-               pciauto_prescan_setup_bridge(hose, dev, hose->current_busno);
-               /*
-                * need to figure out if this is a subordinate bridge on the bus
-                * to be able to properly set the pri/sec/sub bridge registers.
-                */
-               n = pci_hose_scan_bus(hose, hose->current_busno);
-
-               /* figure out the deepest we've gone for this leg */
-               sub_bus = max(n, sub_bus);
-               pciauto_postscan_setup_bridge(hose, dev, sub_bus);
-
-               sub_bus = hose->current_busno;
-               break;
-
-       case PCI_CLASS_STORAGE_IDE:
-               pci_hose_read_config_byte(hose, dev, PCI_CLASS_PROG, &prg_iface);
-               if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) {
-                       DEBUGF("PCI Autoconfig: Skipping legacy mode IDE controller\n");
-                       return sub_bus;
-               }
-
-               pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
-               break;
-
-       case PCI_CLASS_BRIDGE_CARDBUS:
-               /* just do a minimal setup of the bridge, let the OS take care of the rest */
-               pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
-
-               DEBUGF("PCI Autoconfig: Found P2CardBus bridge, device %d\n", PCI_DEV(dev));
-
-               hose->current_busno++;
-               break;
-
-#ifdef CONFIG_MPC5200
-       case PCI_CLASS_BRIDGE_OTHER:
-               DEBUGF("PCI Autoconfig: Skipping bridge device %d\n",
-                      PCI_DEV(dev));
-               break;
-#endif
-#ifdef CONFIG_MPC834X
-       case PCI_CLASS_BRIDGE_OTHER:
-               /*
-                * The host/PCI bridge 1 seems broken in 8349 - it presents
-                * itself as 'PCI_CLASS_BRIDGE_OTHER' and appears as an _agent_
-                * device claiming resources io/mem/irq.. we only allow for
-                * the PIMMR window to be allocated (BAR0 - 1MB size)
-                */
-               DEBUGF("PCI Autoconfig: Broken bridge found, only minimal config\n");
-               pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
-               break;
-#endif
-       default:
-               pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
-               break;
-       }
-
-       return sub_bus;
-}
-
-#endif /* CONFIG_PCI */
diff --git a/drivers/pci_indirect.c b/drivers/pci_indirect.c
deleted file mode 100644 (file)
index a8220fb..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Support for indirect PCI bridges.
- *
- * Copyright (C) 1998 Gabriel Paubert.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <common.h>
-
-#ifdef CONFIG_PCI
-#if (!defined(__I386__) && !defined(CONFIG_IXDP425))
-
-#include <asm/processor.h>
-#include <asm/io.h>
-#include <pci.h>
-
-#define cfg_read(val, addr, type, op)  *val = op((type)(addr))
-#define cfg_write(val, addr, type, op) op((type *)(addr), (val))
-
-#ifdef CONFIG_IXP425
-extern unsigned char   in_8 (volatile unsigned *addr);
-extern unsigned short  in_le16 (volatile unsigned *addr);
-extern unsigned                in_le32 (volatile unsigned *addr);
-extern void            out_8 (volatile unsigned *addr, char val);
-extern void            out_le16 (volatile unsigned *addr, unsigned short val);
-extern void            out_le32 (volatile unsigned *addr, unsigned int val);
-#endif /* CONFIG_IXP425 */
-
-#if defined(CONFIG_MPC8260)
-#define INDIRECT_PCI_OP(rw, size, type, op, mask)                       \
-static int                                                              \
-indirect_##rw##_config_##size(struct pci_controller *hose,              \
-                             pci_dev_t dev, int offset, type val)       \
-{                                                                       \
-       u32 b, d,f;                                                      \
-       b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev);           \
-       b = b - hose->first_busno;                                       \
-       dev = PCI_BDF(b, d, f);                                          \
-       out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000000);    \
-       sync();                                                          \
-       cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);       \
-       return 0;                                                        \
-}
-#elif defined(CONFIG_E500) || defined(CONFIG_MPC86xx)
-#define INDIRECT_PCI_OP(rw, size, type, op, mask)                        \
-static int                                                               \
-indirect_##rw##_config_##size(struct pci_controller *hose,               \
-                             pci_dev_t dev, int offset, type val)       \
-{                                                                        \
-       u32 b, d,f;                                                      \
-       b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev);           \
-       b = b - hose->first_busno;                                       \
-       dev = PCI_BDF(b, d, f);                                          \
-       *(hose->cfg_addr) = dev | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000; \
-       sync();                                                          \
-       cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);       \
-       return 0;                                                        \
-}
-#elif defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SPE)
-#define INDIRECT_PCI_OP(rw, size, type, op, mask)                       \
-static int                                                              \
-indirect_##rw##_config_##size(struct pci_controller *hose,              \
-                             pci_dev_t dev, int offset, type val)       \
-{                                                                       \
-       u32 b, d,f;                                                      \
-       b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev);           \
-       b = b - hose->first_busno;                                       \
-       dev = PCI_BDF(b, d, f);                                          \
-       if (PCI_BUS(dev) > 0)                                            \
-               out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000001); \
-       else                                                             \
-               out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000000); \
-       cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);       \
-       return 0;                                                        \
-}
-#else
-#define INDIRECT_PCI_OP(rw, size, type, op, mask)                       \
-static int                                                              \
-indirect_##rw##_config_##size(struct pci_controller *hose,              \
-                             pci_dev_t dev, int offset, type val)       \
-{                                                                       \
-       u32 b, d,f;                                                      \
-       b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev);           \
-       b = b - hose->first_busno;                                       \
-       dev = PCI_BDF(b, d, f);                                          \
-       out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000000);    \
-       cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);       \
-       return 0;                                                        \
-}
-#endif
-
-#define INDIRECT_PCI_OP_ERRATA6(rw, size, type, op, mask)               \
-static int                                                              \
-indirect_##rw##_config_##size(struct pci_controller *hose,              \
-                             pci_dev_t dev, int offset, type val)       \
-{                                                                       \
-       unsigned int msr = mfmsr();                                      \
-       mtmsr(msr & ~(MSR_EE | MSR_CE));                                 \
-       out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000000);    \
-       cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);       \
-       out_le32(hose->cfg_addr, 0x00000000);                            \
-       mtmsr(msr);                                                      \
-       return 0;                                                        \
-}
-
-INDIRECT_PCI_OP(read, byte, u8 *, in_8, 3)
-INDIRECT_PCI_OP(read, word, u16 *, in_le16, 2)
-INDIRECT_PCI_OP(read, dword, u32 *, in_le32, 0)
-#ifdef CONFIG_405GP
-INDIRECT_PCI_OP_ERRATA6(write, byte, u8, out_8, 3)
-INDIRECT_PCI_OP_ERRATA6(write, word, u16, out_le16, 2)
-INDIRECT_PCI_OP_ERRATA6(write, dword, u32, out_le32, 0)
-#else
-INDIRECT_PCI_OP(write, byte, u8, out_8, 3)
-INDIRECT_PCI_OP(write, word, u16, out_le16, 2)
-INDIRECT_PCI_OP(write, dword, u32, out_le32, 0)
-#endif
-
-void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
-{
-       pci_set_ops(hose,
-                   indirect_read_config_byte,
-                   indirect_read_config_word,
-                   indirect_read_config_dword,
-                   indirect_write_config_byte,
-                   indirect_write_config_word,
-                   indirect_write_config_dword);
-
-       hose->cfg_addr = (unsigned int *) cfg_addr;
-       hose->cfg_data = (unsigned char *) cfg_data;
-}
-
-#endif /* !__I386__ && !CONFIG_IXDP425 */
-#endif /* CONFIG_PCI */
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
new file mode 100644 (file)
index 0000000..55528c8
--- /dev/null
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libpcmcia.a
+
+COBJS-y += mpc8xx_pcmcia.o
+COBJS-y += pxa_pcmcia.o
+COBJS-y += rpx_pcmcia.o
+COBJS-y += ti_pci1410a.o
+COBJS-y += tqm8xx_pcmcia.o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
new file mode 100644 (file)
index 0000000..a40fcf4
--- /dev/null
@@ -0,0 +1,1014 @@
+/*
+ * (C) Copyright 2003-2005
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ********************************************************************
+ *
+ * Lots of code copied from:
+ *
+ * i82365.c 1.352 - Linux driver for Intel 82365 and compatible
+ * PC Card controllers, and Yenta-compatible PCI-to-CardBus controllers.
+ * (C) 1999 David A. Hinds <dahinds@users.sourceforge.net>
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_I82365
+
+#include <command.h>
+#include <pci.h>
+#include <pcmcia.h>
+#include <asm/io.h>
+
+#include <pcmcia/ss.h>
+#include <pcmcia/i82365.h>
+#include <pcmcia/yenta.h>
+#ifdef CONFIG_CPC45
+#include <pcmcia/cirrus.h>
+#else
+#include <pcmcia/ti113x.h>
+#endif
+
+static struct pci_device_id supported[] = {
+#ifdef CONFIG_CPC45
+       {PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6729},
+#else
+       {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1510},
+#endif
+       {0, 0}
+};
+
+#define CYCLE_TIME     120
+
+#ifdef CONFIG_CPC45
+extern int SPD67290Init (void);
+#endif
+
+#ifdef DEBUG
+static void i82365_dump_regions (pci_dev_t dev);
+#endif
+
+typedef struct socket_info_t {
+       pci_dev_t       dev;
+       u_short         bcr;
+       u_char          pci_lat, cb_lat, sub_bus, cache;
+       u_int           cb_phys;
+
+       socket_cap_t    cap;
+       u_short         type;
+       u_int           flags;
+#ifdef CONFIG_CPC45
+       cirrus_state_t  c_state;
+#else
+       ti113x_state_t  state;
+#endif
+} socket_info_t;
+
+#ifdef CONFIG_CPC45
+/* These definitions must match the pcic table! */
+typedef enum pcic_id {
+       IS_PD6710, IS_PD672X, IS_VT83C469
+} pcic_id;
+
+typedef struct pcic_t {
+       char *name;
+} pcic_t;
+
+static pcic_t pcic[] = {
+       {" Cirrus PD6710: "},
+       {" Cirrus PD672x: "},
+       {" VIA VT83C469: "},
+};
+#endif
+
+static socket_info_t socket;
+static socket_state_t state;
+static struct pccard_mem_map mem;
+static struct pccard_io_map io;
+
+/*====================================================================*/
+
+/* Some PCI shortcuts */
+
+static int pci_readb (socket_info_t * s, int r, u_char * v)
+{
+       return pci_read_config_byte (s->dev, r, v);
+}
+static int pci_writeb (socket_info_t * s, int r, u_char v)
+{
+       return pci_write_config_byte (s->dev, r, v);
+}
+static int pci_readw (socket_info_t * s, int r, u_short * v)
+{
+       return pci_read_config_word (s->dev, r, v);
+}
+static int pci_writew (socket_info_t * s, int r, u_short v)
+{
+       return pci_write_config_word (s->dev, r, v);
+}
+#ifndef CONFIG_CPC45
+static int pci_readl (socket_info_t * s, int r, u_int * v)
+{
+       return pci_read_config_dword (s->dev, r, v);
+}
+static int pci_writel (socket_info_t * s, int r, u_int v)
+{
+       return pci_write_config_dword (s->dev, r, v);
+}
+#endif /* !CONFIG_CPC45 */
+
+/*====================================================================*/
+
+#ifdef CONFIG_CPC45
+
+#define cb_readb(s)            readb((s)->cb_phys + 1)
+#define cb_writeb(s, v)                writeb(v, (s)->cb_phys)
+#define cb_writeb2(s, v)       writeb(v, (s)->cb_phys + 1)
+#define cb_readl(s, r)         readl((s)->cb_phys + (r))
+#define cb_writel(s, r, v)     writel(v, (s)->cb_phys + (r))
+
+
+static u_char i365_get (socket_info_t * s, u_short reg)
+{
+       u_char val;
+#ifdef CONFIG_PCMCIA_SLOT_A
+       int slot = 0;
+#else
+       int slot = 1;
+#endif
+
+       val = I365_REG (slot, reg);
+
+       cb_writeb (s, val);
+       val = cb_readb (s);
+
+       debug ("i365_get slot:%x reg: %x val: %x\n", slot, reg, val);
+       return val;
+}
+
+static void i365_set (socket_info_t * s, u_short reg, u_char data)
+{
+#ifdef CONFIG_PCMCIA_SLOT_A
+       int slot = 0;
+#else
+       int slot = 1;
+#endif
+       u_char val;
+
+       val = I365_REG (slot, reg);
+
+       cb_writeb (s, val);
+       cb_writeb2 (s, data);
+
+       debug ("i365_set slot:%x reg: %x data:%x\n", slot, reg, data);
+}
+
+#else  /* ! CONFIG_CPC45 */
+
+#define cb_readb(s, r)         readb((s)->cb_phys + (r))
+#define cb_readl(s, r)         readl((s)->cb_phys + (r))
+#define cb_writeb(s, r, v)     writeb(v, (s)->cb_phys + (r))
+#define cb_writel(s, r, v)     writel(v, (s)->cb_phys + (r))
+
+static u_char i365_get (socket_info_t * s, u_short reg)
+{
+       return cb_readb (s, 0x0800 + reg);
+}
+
+static void i365_set (socket_info_t * s, u_short reg, u_char data)
+{
+       cb_writeb (s, 0x0800 + reg, data);
+}
+#endif /* CONFIG_CPC45 */
+
+static void i365_bset (socket_info_t * s, u_short reg, u_char mask)
+{
+       i365_set (s, reg, i365_get (s, reg) | mask);
+}
+
+static void i365_bclr (socket_info_t * s, u_short reg, u_char mask)
+{
+       i365_set (s, reg, i365_get (s, reg) & ~mask);
+}
+
+#if 0  /* not used */
+static void i365_bflip (socket_info_t * s, u_short reg, u_char mask, int b)
+{
+       u_char d = i365_get (s, reg);
+
+       i365_set (s, reg, (b) ? (d | mask) : (d & ~mask));
+}
+
+static u_short i365_get_pair (socket_info_t * s, u_short reg)
+{
+       return (i365_get (s, reg) + (i365_get (s, reg + 1) << 8));
+}
+#endif /* not used */
+
+static void i365_set_pair (socket_info_t * s, u_short reg, u_short data)
+{
+       i365_set (s, reg, data & 0xff);
+       i365_set (s, reg + 1, data >> 8);
+}
+
+#ifdef CONFIG_CPC45
+/*======================================================================
+
+    Code to save and restore global state information for Cirrus
+    PD67xx controllers, and to set and report global configuration
+    options.
+
+======================================================================*/
+
+#define flip(v,b,f) (v = ((f)<0) ? v : ((f) ? ((v)|(b)) : ((v)&(~b))))
+
+static void cirrus_get_state (socket_info_t * s)
+{
+       int i;
+       cirrus_state_t *p = &s->c_state;
+
+       p->misc1 = i365_get (s, PD67_MISC_CTL_1);
+       p->misc1 &= (PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
+       p->misc2 = i365_get (s, PD67_MISC_CTL_2);
+       for (i = 0; i < 6; i++)
+               p->timer[i] = i365_get (s, PD67_TIME_SETUP (0) + i);
+
+}
+
+static void cirrus_set_state (socket_info_t * s)
+{
+       int i;
+       u_char misc;
+       cirrus_state_t *p = &s->c_state;
+
+       misc = i365_get (s, PD67_MISC_CTL_2);
+       i365_set (s, PD67_MISC_CTL_2, p->misc2);
+       if (misc & PD67_MC2_SUSPEND)
+               udelay (50000);
+       misc = i365_get (s, PD67_MISC_CTL_1);
+       misc &= ~(PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
+       i365_set (s, PD67_MISC_CTL_1, misc | p->misc1);
+       for (i = 0; i < 6; i++)
+               i365_set (s, PD67_TIME_SETUP (0) + i, p->timer[i]);
+}
+
+static u_int cirrus_set_opts (socket_info_t * s)
+{
+       cirrus_state_t *p = &s->c_state;
+       u_int mask = 0xffff;
+#if DEBUG
+       char buf[200];
+
+       memset (buf, 0, 200);
+#endif
+
+       if (has_ring == -1)
+               has_ring = 1;
+       flip (p->misc2, PD67_MC2_IRQ15_RI, has_ring);
+       flip (p->misc2, PD67_MC2_DYNAMIC_MODE, dynamic_mode);
+#if DEBUG
+       if (p->misc2 & PD67_MC2_IRQ15_RI)
+               strcat (buf, " [ring]");
+       if (p->misc2 & PD67_MC2_DYNAMIC_MODE)
+               strcat (buf, " [dyn mode]");
+       if (p->misc1 & PD67_MC1_INPACK_ENA)
+               strcat (buf, " [inpack]");
+#endif
+
+       if (p->misc2 & PD67_MC2_IRQ15_RI)
+               mask &= ~0x8000;
+       if (has_led > 0) {
+#if DEBUG
+               strcat (buf, " [led]");
+#endif
+               mask &= ~0x1000;
+       }
+       if (has_dma > 0) {
+#if DEBUG
+               strcat (buf, " [dma]");
+#endif
+               mask &= ~0x0600;
+               flip (p->misc2, PD67_MC2_FREQ_BYPASS, freq_bypass);
+#if DEBUG
+               if (p->misc2 & PD67_MC2_FREQ_BYPASS)
+                       strcat (buf, " [freq bypass]");
+#endif
+       }
+
+       if (setup_time >= 0)
+               p->timer[0] = p->timer[3] = setup_time;
+       if (cmd_time > 0) {
+               p->timer[1] = cmd_time;
+               p->timer[4] = cmd_time * 2 + 4;
+       }
+       if (p->timer[1] == 0) {
+               p->timer[1] = 6;
+               p->timer[4] = 16;
+               if (p->timer[0] == 0)
+                       p->timer[0] = p->timer[3] = 1;
+       }
+       if (recov_time >= 0)
+               p->timer[2] = p->timer[5] = recov_time;
+
+       debug ("i82365 Opt: %s [%d/%d/%d] [%d/%d/%d]\n",
+               buf,
+               p->timer[0], p->timer[1], p->timer[2],
+               p->timer[3], p->timer[4], p->timer[5]);
+
+       return mask;
+}
+
+#else  /* !CONFIG_CPC45 */
+
+/*======================================================================
+
+    Code to save and restore global state information for TI 1130 and
+    TI 1131 controllers, and to set and report global configuration
+    options.
+
+======================================================================*/
+
+static void ti113x_get_state (socket_info_t * s)
+{
+       ti113x_state_t *p = &s->state;
+
+       pci_readl (s, TI113X_SYSTEM_CONTROL, &p->sysctl);
+       pci_readb (s, TI113X_CARD_CONTROL, &p->cardctl);
+       pci_readb (s, TI113X_DEVICE_CONTROL, &p->devctl);
+       pci_readb (s, TI1250_DIAGNOSTIC, &p->diag);
+       pci_readl (s, TI12XX_IRQMUX, &p->irqmux);
+}
+
+static void ti113x_set_state (socket_info_t * s)
+{
+       ti113x_state_t *p = &s->state;
+
+       pci_writel (s, TI113X_SYSTEM_CONTROL, p->sysctl);
+       pci_writeb (s, TI113X_CARD_CONTROL, p->cardctl);
+       pci_writeb (s, TI113X_DEVICE_CONTROL, p->devctl);
+       pci_writeb (s, TI1250_MULTIMEDIA_CTL, 0);
+       pci_writeb (s, TI1250_DIAGNOSTIC, p->diag);
+       pci_writel (s, TI12XX_IRQMUX, p->irqmux);
+       i365_set_pair (s, TI113X_IO_OFFSET (0), 0);
+       i365_set_pair (s, TI113X_IO_OFFSET (1), 0);
+}
+
+static u_int ti113x_set_opts (socket_info_t * s)
+{
+       ti113x_state_t *p = &s->state;
+       u_int mask = 0xffff;
+
+       p->cardctl &= ~TI113X_CCR_ZVENABLE;
+       p->cardctl |= TI113X_CCR_SPKROUTEN;
+
+       return mask;
+}
+#endif /* CONFIG_CPC45 */
+
+/*======================================================================
+
+    Routines to handle common CardBus options
+
+======================================================================*/
+
+/* Default settings for PCI command configuration register */
+#define CMD_DFLT (PCI_COMMAND_IO|PCI_COMMAND_MEMORY| \
+                 PCI_COMMAND_MASTER|PCI_COMMAND_WAIT)
+
+static void cb_get_state (socket_info_t * s)
+{
+       pci_readb (s, PCI_CACHE_LINE_SIZE, &s->cache);
+       pci_readb (s, PCI_LATENCY_TIMER, &s->pci_lat);
+       pci_readb (s, CB_LATENCY_TIMER, &s->cb_lat);
+       pci_readb (s, CB_CARDBUS_BUS, &s->cap.cardbus);
+       pci_readb (s, CB_SUBORD_BUS, &s->sub_bus);
+       pci_readw (s, CB_BRIDGE_CONTROL, &s->bcr);
+}
+
+static void cb_set_state (socket_info_t * s)
+{
+#ifndef CONFIG_CPC45
+       pci_writel (s, CB_LEGACY_MODE_BASE, 0);
+       pci_writel (s, PCI_BASE_ADDRESS_0, s->cb_phys);
+#endif
+       pci_writew (s, PCI_COMMAND, CMD_DFLT);
+       pci_writeb (s, PCI_CACHE_LINE_SIZE, s->cache);
+       pci_writeb (s, PCI_LATENCY_TIMER, s->pci_lat);
+       pci_writeb (s, CB_LATENCY_TIMER, s->cb_lat);
+       pci_writeb (s, CB_CARDBUS_BUS, s->cap.cardbus);
+       pci_writeb (s, CB_SUBORD_BUS, s->sub_bus);
+       pci_writew (s, CB_BRIDGE_CONTROL, s->bcr);
+}
+
+static void cb_set_opts (socket_info_t * s)
+{
+#ifndef CONFIG_CPC45
+       if (s->cache == 0)
+               s->cache = 8;
+       if (s->pci_lat == 0)
+               s->pci_lat = 0xa8;
+       if (s->cb_lat == 0)
+               s->cb_lat = 0xb0;
+#endif
+}
+
+/*======================================================================
+
+    Power control for Cardbus controllers: used both for 16-bit and
+    Cardbus cards.
+
+======================================================================*/
+
+static int cb_set_power (socket_info_t * s, socket_state_t * state)
+{
+       u_int reg = 0;
+
+#ifdef CONFIG_CPC45
+
+       reg = I365_PWR_NORESET;
+       if (state->flags & SS_PWR_AUTO)
+               reg |= I365_PWR_AUTO;
+       if (state->flags & SS_OUTPUT_ENA)
+               reg |= I365_PWR_OUT;
+       if (state->Vpp != 0) {
+               if (state->Vpp == 120) {
+                       reg |= I365_VPP1_12V;
+                       puts (" 12V card found: ");
+               } else if (state->Vpp == state->Vcc) {
+                       reg |= I365_VPP1_5V;
+               } else {
+                       puts (" power not found: ");
+                       return -1;
+               }
+       }
+       if (state->Vcc != 0) {
+               reg |= I365_VCC_5V;
+               if (state->Vcc == 33) {
+                       puts (" 3.3V card found: ");
+                       i365_bset (s, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
+               } else if (state->Vcc == 50) {
+                       puts (" 5V card found: ");
+                       i365_bclr (s, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
+               } else {
+                       puts (" power not found: ");
+                       return -1;
+               }
+       }
+
+       if (reg != i365_get (s, I365_POWER)) {
+               reg = (I365_PWR_OUT | I365_PWR_NORESET | I365_VCC_5V | I365_VPP1_5V);
+               i365_set (s, I365_POWER, reg);
+       }
+
+#else  /* ! CONFIG_CPC45 */
+
+       /* restart card voltage detection if it seems appropriate */
+       if ((state->Vcc == 0) && (state->Vpp == 0) &&
+          !(cb_readl (s, CB_SOCKET_STATE) & CB_SS_VSENSE))
+               cb_writel (s, CB_SOCKET_FORCE, CB_SF_CVSTEST);
+       switch (state->Vcc) {
+       case 0:
+               reg = 0;
+               break;
+       case 33:
+               reg = CB_SC_VCC_3V;
+               break;
+       case 50:
+               reg = CB_SC_VCC_5V;
+               break;
+       default:
+               return -1;
+       }
+       switch (state->Vpp) {
+       case 0:
+               break;
+       case 33:
+               reg |= CB_SC_VPP_3V;
+               break;
+       case 50:
+               reg |= CB_SC_VPP_5V;
+               break;
+       case 120:
+               reg |= CB_SC_VPP_12V;
+               break;
+       default:
+               return -1;
+       }
+       if (reg != cb_readl (s, CB_SOCKET_CONTROL))
+               cb_writel (s, CB_SOCKET_CONTROL, reg);
+#endif /* CONFIG_CPC45 */
+       return 0;
+}
+
+/*======================================================================
+
+    Generic routines to get and set controller options
+
+======================================================================*/
+
+static void get_bridge_state (socket_info_t * s)
+{
+#ifdef CONFIG_CPC45
+       cirrus_get_state (s);
+#else
+       ti113x_get_state (s);
+#endif
+       cb_get_state (s);
+}
+
+static void set_bridge_state (socket_info_t * s)
+{
+       cb_set_state (s);
+       i365_set (s, I365_GBLCTL, 0x00);
+       i365_set (s, I365_GENCTL, 0x00);
+#ifdef CONFIG_CPC45
+       cirrus_set_state (s);
+#else
+       ti113x_set_state (s);
+#endif
+}
+
+static void set_bridge_opts (socket_info_t * s)
+{
+#ifdef CONFIG_CPC45
+       cirrus_set_opts (s);
+#else
+       ti113x_set_opts (s);
+#endif
+       cb_set_opts (s);
+}
+
+/*====================================================================*/
+#define PD67_EXT_INDEX         0x2e    /* Extension index */
+#define PD67_EXT_DATA          0x2f    /* Extension data */
+#define PD67_EXD_VS1(s)                (0x01 << ((s)<<1))
+
+#define pd67_ext_get(s, r) \
+    (i365_set(s, PD67_EXT_INDEX, r), i365_get(s, PD67_EXT_DATA))
+
+static int i365_get_status (socket_info_t * s, u_int * value)
+{
+       u_int status;
+#ifdef CONFIG_CPC45
+       u_char val;
+       u_char power, vcc, vpp;
+       u_int powerstate;
+#endif
+
+       status = i365_get (s, I365_IDENT);
+       status = i365_get (s, I365_STATUS);
+       *value = ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0;
+       if (i365_get (s, I365_INTCTL) & I365_PC_IOCARD) {
+               *value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
+       } else {
+               *value |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;
+               *value |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;
+       }
+       *value |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;
+       *value |= (status & I365_CS_READY) ? SS_READY : 0;
+       *value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
+
+#ifdef CONFIG_CPC45
+       /* Check for Cirrus CL-PD67xx chips */
+       i365_set (s, PD67_CHIP_INFO, 0);
+       val = i365_get (s, PD67_CHIP_INFO);
+       s->type = -1;
+       if ((val & PD67_INFO_CHIP_ID) == PD67_INFO_CHIP_ID) {
+               val = i365_get (s, PD67_CHIP_INFO);
+               if ((val & PD67_INFO_CHIP_ID) == 0) {
+                       s->type = (val & PD67_INFO_SLOTS) ? IS_PD672X : IS_PD6710;
+                       i365_set (s, PD67_EXT_INDEX, 0xe5);
+                       if (i365_get (s, PD67_EXT_INDEX) != 0xe5)
+                               s->type = IS_VT83C469;
+               }
+       } else {
+               printf ("no Cirrus Chip found\n");
+               *value = 0;
+               return -1;
+       }
+
+       power = i365_get (s, I365_POWER);
+       state.flags |= (power & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
+       state.flags |= (power & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
+       vcc = power & I365_VCC_MASK;
+       vpp = power & I365_VPP1_MASK;
+       state.Vcc = state.Vpp = 0;
+       if((vcc== 0) || (vpp == 0)) {
+               /*
+                * On the Cirrus we get the info which card voltage
+                * we have in EXTERN DATA and write it to MISC_CTL1
+                */
+               powerstate = pd67_ext_get(s, PD67_EXTERN_DATA);
+               if (powerstate & PD67_EXD_VS1(0)) {
+                       /* 5V Card */
+                       i365_bclr (s, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
+               } else {
+                       /* 3.3V Card */
+                       i365_bset (s, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
+               }
+               i365_set (s, I365_POWER, (I365_PWR_OUT | I365_PWR_NORESET | I365_VCC_5V | I365_VPP1_5V));
+               power = i365_get (s, I365_POWER);
+       }
+       if (power & I365_VCC_5V) {
+               state.Vcc = (i365_get(s, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) ? 33 : 50;
+       }
+
+       if (power == I365_VPP1_12V)
+               state.Vpp = 120;
+
+       /* IO card, RESET flags, IO interrupt */
+       power = i365_get (s, I365_INTCTL);
+       state.flags |= (power & I365_PC_RESET) ? 0 : SS_RESET;
+       if (power & I365_PC_IOCARD)
+               state.flags |= SS_IOCARD;
+       state.io_irq = power & I365_IRQ_MASK;
+
+       /* Card status change mask */
+       power = i365_get (s, I365_CSCINT);
+       state.csc_mask = (power & I365_CSC_DETECT) ? SS_DETECT : 0;
+       if (state.flags & SS_IOCARD)
+               state.csc_mask |= (power & I365_CSC_STSCHG) ? SS_STSCHG : 0;
+       else {
+               state.csc_mask |= (power & I365_CSC_BVD1) ? SS_BATDEAD : 0;
+               state.csc_mask |= (power & I365_CSC_BVD2) ? SS_BATWARN : 0;
+               state.csc_mask |= (power & I365_CSC_READY) ? SS_READY : 0;
+       }
+       debug ("i82365: GetStatus(0) = flags %#3.3x, Vcc %d, Vpp %d, "
+               "io_irq %d, csc_mask %#2.2x\n", state.flags,
+               state.Vcc, state.Vpp, state.io_irq, state.csc_mask);
+
+#else  /* !CONFIG_CPC45 */
+
+       status = cb_readl (s, CB_SOCKET_STATE);
+       *value |= (status & CB_SS_32BIT) ? SS_CARDBUS : 0;
+       *value |= (status & CB_SS_3VCARD) ? SS_3VCARD : 0;
+       *value |= (status & CB_SS_XVCARD) ? SS_XVCARD : 0;
+       *value |= (status & CB_SS_VSENSE) ? 0 : SS_PENDING;
+       /* For now, ignore cards with unsupported voltage keys */
+       if (*value & SS_XVCARD)
+               *value &= ~(SS_DETECT | SS_3VCARD | SS_XVCARD);
+#endif /* CONFIG_CPC45 */
+       return 0;
+}      /* i365_get_status */
+
+static int i365_set_socket (socket_info_t * s, socket_state_t * state)
+{
+       u_char reg;
+
+       set_bridge_state (s);
+
+       /* IO card, RESET flag */
+       reg = 0;
+       reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
+       reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
+       i365_set (s, I365_INTCTL, reg);
+
+#ifdef CONFIG_CPC45
+       cb_set_power (s, state);
+
+#if 0
+       /* Card status change interrupt mask */
+       reg = s->cs_irq << 4;
+       if (state->csc_mask & SS_DETECT)
+               reg |= I365_CSC_DETECT;
+       if (state->flags & SS_IOCARD) {
+               if (state->csc_mask & SS_STSCHG)
+                       reg |= I365_CSC_STSCHG;
+       } else {
+               if (state->csc_mask & SS_BATDEAD)
+                       reg |= I365_CSC_BVD1;
+               if (state->csc_mask & SS_BATWARN)
+                       reg |= I365_CSC_BVD2;
+               if (state->csc_mask & SS_READY)
+                       reg |= I365_CSC_READY;
+       }
+       i365_set (s, I365_CSCINT, reg);
+       i365_get (s, I365_CSC);
+#endif /* 0 */
+
+#else  /* !CONFIG_CPC45 */
+
+       reg = I365_PWR_NORESET;
+       if (state->flags & SS_PWR_AUTO)
+               reg |= I365_PWR_AUTO;
+       if (state->flags & SS_OUTPUT_ENA)
+               reg |= I365_PWR_OUT;
+
+       cb_set_power (s, state);
+       reg |= i365_get (s, I365_POWER) & (I365_VCC_MASK | I365_VPP1_MASK);
+
+       if (reg != i365_get (s, I365_POWER))
+               i365_set (s, I365_POWER, reg);
+#endif /* CONFIG_CPC45 */
+
+       return 0;
+}      /* i365_set_socket */
+
+/*====================================================================*/
+
+static int i365_set_mem_map (socket_info_t * s, struct pccard_mem_map *mem)
+{
+       u_short base, i;
+       u_char map;
+
+       debug ("i82365: SetMemMap(%d, %#2.2x, %d ns, %#5.5lx-%#5.5lx, %#5.5x)\n",
+               mem->map, mem->flags, mem->speed,
+               mem->sys_start, mem->sys_stop, mem->card_start);
+
+       map = mem->map;
+       if ((map > 4) ||
+           (mem->card_start > 0x3ffffff) ||
+           (mem->sys_start > mem->sys_stop) ||
+           (mem->speed > 1000)) {
+               return -1;
+       }
+
+       /* Turn off the window before changing anything */
+       if (i365_get (s, I365_ADDRWIN) & I365_ENA_MEM (map))
+               i365_bclr (s, I365_ADDRWIN, I365_ENA_MEM (map));
+
+       /* Take care of high byte, for PCI controllers */
+       i365_set (s, CB_MEM_PAGE (map), mem->sys_start >> 24);
+
+       base = I365_MEM (map);
+       i = (mem->sys_start >> 12) & 0x0fff;
+       if (mem->flags & MAP_16BIT)
+               i |= I365_MEM_16BIT;
+       if (mem->flags & MAP_0WS)
+               i |= I365_MEM_0WS;
+       i365_set_pair (s, base + I365_W_START, i);
+
+       i = (mem->sys_stop >> 12) & 0x0fff;
+       switch (mem->speed / CYCLE_TIME) {
+       case 0:
+               break;
+       case 1:
+               i |= I365_MEM_WS0;
+               break;
+       case 2:
+               i |= I365_MEM_WS1;
+               break;
+       default:
+               i |= I365_MEM_WS1 | I365_MEM_WS0;
+               break;
+       }
+       i365_set_pair (s, base + I365_W_STOP, i);
+
+#ifdef CONFIG_CPC45
+       i = 0;
+#else
+       i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff;
+#endif
+       if (mem->flags & MAP_WRPROT)
+               i |= I365_MEM_WRPROT;
+       if (mem->flags & MAP_ATTRIB)
+               i |= I365_MEM_REG;
+       i365_set_pair (s, base + I365_W_OFF, i);
+
+#ifdef CONFIG_CPC45
+       /* set System Memory map Upper Adress */
+       i365_set(s, PD67_EXT_INDEX, PD67_MEM_PAGE(map));
+       i365_set(s, PD67_EXT_DATA, ((mem->sys_start >> 24) & 0xff));
+#endif
+
+       /* Turn on the window if necessary */
+       if (mem->flags & MAP_ACTIVE)
+               i365_bset (s, I365_ADDRWIN, I365_ENA_MEM (map));
+       return 0;
+}      /* i365_set_mem_map */
+
+static int i365_set_io_map (socket_info_t * s, struct pccard_io_map *io)
+{
+       u_char map, ioctl;
+
+       map = io->map;
+       /* comment out: comparison is always false due to limited range of data type */
+       if ((map > 1) || /* (io->start > 0xffff) || (io->stop > 0xffff) || */
+           (io->stop < io->start))
+               return -1;
+       /* Turn off the window before changing anything */
+       if (i365_get (s, I365_ADDRWIN) & I365_ENA_IO (map))
+               i365_bclr (s, I365_ADDRWIN, I365_ENA_IO (map));
+       i365_set_pair (s, I365_IO (map) + I365_W_START, io->start);
+       i365_set_pair (s, I365_IO (map) + I365_W_STOP, io->stop);
+       ioctl = i365_get (s, I365_IOCTL) & ~I365_IOCTL_MASK (map);
+       if (io->speed)
+               ioctl |= I365_IOCTL_WAIT (map);
+       if (io->flags & MAP_0WS)
+               ioctl |= I365_IOCTL_0WS (map);
+       if (io->flags & MAP_16BIT)
+               ioctl |= I365_IOCTL_16BIT (map);
+       if (io->flags & MAP_AUTOSZ)
+               ioctl |= I365_IOCTL_IOCS16 (map);
+       i365_set (s, I365_IOCTL, ioctl);
+       /* Turn on the window if necessary */
+       if (io->flags & MAP_ACTIVE)
+               i365_bset (s, I365_ADDRWIN, I365_ENA_IO (map));
+       return 0;
+}      /* i365_set_io_map */
+
+/*====================================================================*/
+
+int i82365_init (void)
+{
+       u_int val;
+       int i;
+
+#ifdef CONFIG_CPC45
+       if (SPD67290Init () != 0)
+               return 1;
+#endif
+       if ((socket.dev = pci_find_devices (supported, 0)) < 0) {
+               /* Controller not found */
+               return 1;
+       }
+       debug ("i82365 Device Found!\n");
+
+       pci_read_config_dword (socket.dev, PCI_BASE_ADDRESS_0, &socket.cb_phys);
+       socket.cb_phys &= ~0xf;
+
+#ifdef CONFIG_CPC45
+       /* + 0xfe000000 see MPC 8245 Users Manual Adress Map B */
+       socket.cb_phys += 0xfe000000;
+#endif
+
+       get_bridge_state (&socket);
+       set_bridge_opts (&socket);
+
+       i = i365_get_status (&socket, &val);
+
+#ifdef CONFIG_CPC45
+       if (i > -1) {
+               puts (pcic[socket.type].name);
+       } else {
+               printf ("i82365: Controller not found.\n");
+               return 1;
+       }
+       if((val & SS_DETECT) != SS_DETECT){
+               puts ("No card\n");
+               return 1;
+       }
+#else  /* !CONFIG_CPC45 */
+       if (val & SS_DETECT) {
+               if (val & SS_3VCARD) {
+                       state.Vcc = state.Vpp = 33;
+                       puts (" 3.3V card found: ");
+               } else if (!(val & SS_XVCARD)) {
+                       state.Vcc = state.Vpp = 50;
+                       puts (" 5.0V card found: ");
+               } else {
+                       puts ("i82365: unsupported voltage key\n");
+                       state.Vcc = state.Vpp = 0;
+               }
+       } else {
+               /* No card inserted */
+               puts ("No card\n");
+               return 1;
+       }
+#endif /* CONFIG_CPC45 */
+
+#ifdef CONFIG_CPC45
+       state.flags |= SS_OUTPUT_ENA;
+#else
+       state.flags = SS_IOCARD | SS_OUTPUT_ENA;
+       state.csc_mask = 0;
+       state.io_irq = 0;
+#endif
+
+       i365_set_socket (&socket, &state);
+
+       for (i = 500; i; i--) {
+               if ((i365_get (&socket, I365_STATUS) & I365_CS_READY))
+                       break;
+               udelay (1000);
+       }
+
+       if (i == 0) {
+               /* PC Card not ready for data transfer */
+               puts ("i82365 PC Card not ready for data transfer\n");
+               return 1;
+       }
+       debug (" PC Card ready for data transfer: ");
+
+       mem.map = 0;
+       mem.flags = MAP_ATTRIB | MAP_ACTIVE;
+       mem.speed = 300;
+       mem.sys_start = CFG_PCMCIA_MEM_ADDR;
+       mem.sys_stop = CFG_PCMCIA_MEM_ADDR + CFG_PCMCIA_MEM_SIZE - 1;
+       mem.card_start = 0;
+       i365_set_mem_map (&socket, &mem);
+
+#ifdef CONFIG_CPC45
+       mem.map = 1;
+       mem.flags = MAP_ACTIVE;
+       mem.speed = 300;
+       mem.sys_start = CFG_PCMCIA_MEM_ADDR + CFG_PCMCIA_MEM_SIZE;
+       mem.sys_stop = CFG_PCMCIA_MEM_ADDR + (2 * CFG_PCMCIA_MEM_SIZE) - 1;
+       mem.card_start = 0;
+       i365_set_mem_map (&socket, &mem);
+
+#else  /* !CONFIG_CPC45 */
+
+       io.map = 0;
+       io.flags = MAP_AUTOSZ | MAP_ACTIVE;
+       io.speed = 0;
+       io.start = 0x0100;
+       io.stop = 0x010F;
+       i365_set_io_map (&socket, &io);
+
+#endif /* CONFIG_CPC45 */
+
+#ifdef DEBUG
+       i82365_dump_regions (socket.dev);
+#endif
+
+       return 0;
+}
+
+void i82365_exit (void)
+{
+       io.map = 0;
+       io.flags = 0;
+       io.speed = 0;
+       io.start = 0;
+       io.stop = 0x1;
+
+       i365_set_io_map (&socket, &io);
+
+       mem.map = 0;
+       mem.flags = 0;
+       mem.speed = 0;
+       mem.sys_start = 0;
+       mem.sys_stop = 0x1000;
+       mem.card_start = 0;
+
+       i365_set_mem_map (&socket, &mem);
+
+#ifdef CONFIG_CPC45
+       mem.map = 1;
+       mem.flags = 0;
+       mem.speed = 0;
+       mem.sys_start = 0;
+       mem.sys_stop = 0x1000;
+       mem.card_start = 0;
+
+       i365_set_mem_map (&socket, &mem);
+#else  /* !CONFIG_CPC45 */
+       socket.state.sysctl &= 0xFFFF00FF;
+#endif
+       state.Vcc = state.Vpp = 0;
+
+       i365_set_socket (&socket, &state);
+}
+
+/*======================================================================
+
+    Debug stuff
+
+======================================================================*/
+
+#ifdef DEBUG
+static void i82365_dump_regions (pci_dev_t dev)
+{
+       u_int tmp[2];
+       u_int *mem = (void *) socket.cb_phys;
+       u_char *cis = (void *) CFG_PCMCIA_MEM_ADDR;
+       u_char *ide = (void *) (CFG_ATA_BASE_ADDR + CFG_ATA_REG_OFFSET);
+
+       pci_read_config_dword (dev, 0x00, tmp + 0);
+       pci_read_config_dword (dev, 0x80, tmp + 1);
+
+       printf ("PCI CONF: %08X ... %08X\n",
+               tmp[0], tmp[1]);
+       printf ("PCI MEM:  ... %08X ... %08X\n",
+               mem[0x8 / 4], mem[0x800 / 4]);
+       printf ("CIS:      ...%c%c%c%c%c%c%c%c...\n",
+               cis[0x38], cis[0x3a], cis[0x3c], cis[0x3e],
+               cis[0x40], cis[0x42], cis[0x44], cis[0x48]);
+       printf ("CIS CONF: %02X %02X %02X ...\n",
+               cis[0x200], cis[0x202], cis[0x204]);
+       printf ("IDE:      %02X %02X %02X %02X %02X %02X %02X %02X\n",
+               ide[0], ide[1], ide[2], ide[3],
+               ide[4], ide[5], ide[6], ide[7]);
+}
+#endif /* DEBUG */
+
+#endif /* CONFIG_I82365 */
diff --git a/drivers/pcmcia/mpc8xx_pcmcia.c b/drivers/pcmcia/mpc8xx_pcmcia.c
new file mode 100644 (file)
index 0000000..8a34cd3
--- /dev/null
@@ -0,0 +1,304 @@
+#include <common.h>
+#if defined(CONFIG_8xx)
+#include <mpc8xx.h>
+#endif
+#include <pcmcia.h>
+
+#undef CONFIG_PCMCIA
+
+#if defined(CONFIG_CMD_PCMCIA)
+#define        CONFIG_PCMCIA
+#endif
+
+#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
+#define        CONFIG_PCMCIA
+#endif
+
+#if defined(CONFIG_8xx)        && defined(CONFIG_PCMCIA)
+
+#if    defined(CONFIG_IDE_8xx_PCCARD)
+extern int check_ide_device (int slot);
+#endif
+
+extern int pcmcia_hardware_enable (int slot);
+extern int pcmcia_voltage_set(int slot, int vcc, int vpp);
+
+#if defined(CONFIG_CMD_PCMCIA)
+extern int pcmcia_hardware_disable(int slot);
+#endif
+
+static u_int m8xx_get_graycode(u_int size);
+#if 0 /* Disabled */
+static u_int m8xx_get_speed(u_int ns, u_int is_io);
+#endif
+
+/* look up table for pgcrx registers */
+u_int *pcmcia_pgcrx[2] = {
+       &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
+       &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
+};
+
+/*
+ * Search this table to see if the windowsize is
+ * supported...
+ */
+
+#define M8XX_SIZES_NO 32
+
+static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
+{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
+  0x00000080, 0x00000040, 0x00000010, 0x00000020,
+  0x00008000, 0x00004000, 0x00001000, 0x00002000,
+  0x00000100, 0x00000200, 0x00000800, 0x00000400,
+
+  0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x01000000, 0x02000000, 0xffffffff, 0x04000000,
+  0x00010000, 0x00020000, 0x00080000, 0x00040000,
+  0x00800000, 0x00400000, 0x00100000, 0x00200000 };
+
+
+/* -------------------------------------------------------------------- */
+
+#ifdef CONFIG_HMI10
+#define        HMI10_FRAM_TIMING       (       PCMCIA_SHT(2)   \
+                               |       PCMCIA_SST(2)   \
+                               |       PCMCIA_SL(4))
+#endif
+
+#if    defined(CONFIG_LWMON) || defined(CONFIG_NSCU)
+#define        CFG_PCMCIA_TIMING       (       PCMCIA_SHT(9)   \
+                               |       PCMCIA_SST(3)   \
+                               |       PCMCIA_SL(12))
+#else
+#define        CFG_PCMCIA_TIMING       (       PCMCIA_SHT(2)   \
+                               |       PCMCIA_SST(4)   \
+                               |       PCMCIA_SL(9))
+#endif
+
+/* -------------------------------------------------------------------- */
+
+int pcmcia_on (void)
+{
+       u_long reg, base;
+       pcmcia_win_t *win;
+       u_int slotbit;
+       u_int rc, slot;
+       int i;
+
+       debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
+
+       /* intialize the fixed memory windows */
+       win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
+       base = CFG_PCMCIA_MEM_ADDR;
+
+       if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
+               printf ("Cannot set window size to 0x%08x\n",
+                       CFG_PCMCIA_MEM_SIZE);
+               return (1);
+       }
+
+       slotbit = PCMCIA_SLOT_x;
+       for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
+               win->br = base;
+
+#if    (PCMCIA_SOCKETS_NO == 2)
+               if (i == 4) /* Another slot starting from win 4 */
+                       slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
+#endif
+               switch (i) {
+#ifdef CONFIG_IDE_8xx_PCCARD
+               case 4:
+#ifdef CONFIG_HMI10
+               {       /* map FRAM area */
+                       win->or = (     PCMCIA_BSIZE_256K
+                               |       PCMCIA_PPS_8
+                               |       PCMCIA_PRS_ATTR
+                               |       slotbit
+                               |       PCMCIA_PV
+                               |       HMI10_FRAM_TIMING );
+                       break;
+               }
+#endif
+               case 0: {       /* map attribute memory */
+                       win->or = (     PCMCIA_BSIZE_64M
+                               |       PCMCIA_PPS_8
+                               |       PCMCIA_PRS_ATTR
+                               |       slotbit
+                               |       PCMCIA_PV
+                               |       CFG_PCMCIA_TIMING );
+                       break;
+               }
+               case 5:
+               case 1: {       /* map I/O window for data reg */
+                       win->or = (     PCMCIA_BSIZE_1K
+                               |       PCMCIA_PPS_16
+                               |       PCMCIA_PRS_IO
+                               |       slotbit
+                               |       PCMCIA_PV
+                               |       CFG_PCMCIA_TIMING );
+                       break;
+               }
+               case 6:
+               case 2: {       /* map I/O window for cmd/ctrl reg block */
+                       win->or = (     PCMCIA_BSIZE_1K
+                               |       PCMCIA_PPS_8
+                               |       PCMCIA_PRS_IO
+                               |       slotbit
+                               |       PCMCIA_PV
+                               |       CFG_PCMCIA_TIMING );
+                       break;
+               }
+#endif /* CONFIG_IDE_8xx_PCCARD */
+#ifdef CONFIG_HMI10
+               case 3: {       /* map I/O window for 4xUART data/ctrl */
+                       win->br += 0x40000;
+                       win->or = (     PCMCIA_BSIZE_256K
+                               |       PCMCIA_PPS_8
+                               |       PCMCIA_PRS_IO
+                               |       slotbit
+                               |       PCMCIA_PV
+                               |       CFG_PCMCIA_TIMING );
+                       break;
+               }
+#endif /* CONFIG_HMI10 */
+               default:        /* set to not valid */
+                       win->or = 0;
+                       break;
+               }
+
+               debug ("MemWin %d: PBR 0x%08lX  POR %08lX\n",
+                      i, win->br, win->or);
+               base += CFG_PCMCIA_MEM_SIZE;
+               ++win;
+       }
+
+       for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
+               /* turn off voltage */
+               if ((rc = pcmcia_voltage_set(slot, 0, 0)))
+                       continue;
+
+               /* Enable external hardware */
+               if ((rc = pcmcia_hardware_enable(slot)))
+                       continue;
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+               if ((rc = check_ide_device(i)))
+                       continue;
+#endif
+       }
+       return rc;
+}
+
+#if defined(CONFIG_CMD_PCMCIA)
+int pcmcia_off (void)
+{
+       int i;
+       pcmcia_win_t *win;
+
+       printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
+
+       /* clear interrupt state, and disable interrupts */
+       ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr =  PCMCIA_MASK(_slot_);
+       ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
+
+       /* turn off interrupt and disable CxOE */
+       PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
+
+       /* turn off memory windows */
+       win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
+
+       for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
+               /* disable memory window */
+               win->or = 0;
+               ++win;
+       }
+
+       /* turn off voltage */
+       pcmcia_voltage_set(_slot_, 0, 0);
+
+       /* disable external hardware */
+       printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
+       pcmcia_hardware_disable(_slot_);
+       return 0;
+}
+#endif
+
+
+static u_int m8xx_get_graycode(u_int size)
+{
+       u_int k;
+
+       for (k = 0; k < M8XX_SIZES_NO; k++) {
+               if(m8xx_size_to_gray[k] == size)
+                       break;
+       }
+
+       if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
+               k = -1;
+
+       return k;
+}
+
+#if    0
+
+#if    defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
+
+/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
+ * SYPCR is write once only, therefore must the slowest memory be faster
+ * than the bus monitor or we will get a machine check due to the bus timeout.
+ */
+#undef PCMCIA_BMT_LIMIT
+#define        PCMCIA_BMT_LIMIT (6*8)
+#endif
+
+static u_int m8xx_get_speed(u_int ns, u_int is_io)
+{
+       u_int reg, clocks, psst, psl, psht;
+
+       if(!ns) {
+
+               /*
+               * We get called with IO maps setup to 0ns
+               * if not specified by the user.
+               * They should be 255ns.
+               */
+
+               if(is_io)
+                       ns = 255;
+               else
+                       ns = 100;  /* fast memory if 0 */
+       }
+
+       /*
+       * In PSST, PSL, PSHT fields we tell the controller
+       * timing parameters in CLKOUT clock cycles.
+       * CLKOUT is the same as GCLK2_50.
+       */
+
+       /* how we want to adjust the timing - in percent */
+
+#define ADJ 180 /* 80 % longer accesstime - to be sure */
+
+       clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
+       clocks = (clocks * ADJ) / (100*1000);
+
+       if(clocks >= PCMCIA_BMT_LIMIT) {
+               DEBUG(0, "Max access time limit reached\n");
+               clocks = PCMCIA_BMT_LIMIT-1;
+       }
+
+       psst = clocks / 7;          /* setup time */
+       psht = clocks / 7;          /* hold time */
+       psl  = (clocks * 5) / 7;    /* strobe length */
+
+       psst += clocks - (psst + psht + psl);
+
+       reg =  psst << 12;
+       reg |= psl  << 7;
+       reg |= psht << 16;
+
+       return reg;
+}
+#endif /* 0 */
+
+#endif /* CONFIG_8xx && CONFIG_PCMCIA */
diff --git a/drivers/pcmcia/pxa_pcmcia.c b/drivers/pcmcia/pxa_pcmcia.c
new file mode 100644 (file)
index 0000000..6020e46
--- /dev/null
@@ -0,0 +1,95 @@
+#include <common.h>
+#include <config.h>
+
+#ifdef CONFIG_PXA_PCMCIA
+
+#include <pcmcia.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/io.h>
+
+static inline void msWait(unsigned msVal)
+{
+       udelay(msVal*1000);
+}
+
+int pcmcia_on (void)
+{
+       unsigned int reg_arr[] = {
+               0x48000028, CFG_MCMEM0_VAL,
+               0x4800002c, CFG_MCMEM1_VAL,
+               0x48000030, CFG_MCATT0_VAL,
+               0x48000034, CFG_MCATT1_VAL,
+               0x48000038, CFG_MCIO0_VAL,
+               0x4800003c, CFG_MCIO1_VAL,
+
+               0, 0
+       };
+       int i, rc;
+
+#ifdef CONFIG_EXADRON1
+       int cardDetect;
+       volatile unsigned int *v_pBCRReg =
+                       (volatile unsigned int *) 0x08000000;
+#endif
+
+       debug ("%s\n", __FUNCTION__);
+
+       i = 0;
+       while (reg_arr[i])
+               *((volatile unsigned int *) reg_arr[i++]) |= reg_arr[i++];
+       udelay (1000);
+
+       debug ("%s: programmed mem controller \n", __FUNCTION__);
+
+#ifdef CONFIG_EXADRON1
+
+/*define useful BCR masks */
+#define BCR_CF_INIT_VAL                    0x00007230
+#define BCR_CF_PWRON_BUSOFF_RESETOFF_VAL    0x00007231
+#define BCR_CF_PWRON_BUSOFF_RESETON_VAL     0x00007233
+#define BCR_CF_PWRON_BUSON_RESETON_VAL      0x00007213
+#define BCR_CF_PWRON_BUSON_RESETOFF_VAL     0x00007211
+
+       /* we see from the GPIO bit if the card is present */
+       cardDetect = !(GPLR0 & GPIO_bit (14));
+
+       if (cardDetect) {
+               printf ("No PCMCIA card found!\n");
+       }
+
+       /* reset the card via the BCR line */
+       *v_pBCRReg = (unsigned) BCR_CF_INIT_VAL;
+       msWait (500);
+
+       *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETOFF_VAL;
+       msWait (500);
+
+       *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETON_VAL;
+       msWait (500);
+
+       *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETON_VAL;
+       msWait (500);
+
+       *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETOFF_VAL;
+       msWait (1500);
+
+       /* enable address bus */
+       GPCR1 = 0x01;
+       /* and the first CF slot */
+       MECR = 0x00000002;
+
+#endif /* EXADRON 1 */
+
+       rc = check_ide_device (0);      /* use just slot 0 */
+
+       return rc;
+}
+
+#if defined(CONFIG_CMD_PCMCIA)
+int pcmcia_off (void)
+{
+       return 0;
+}
+#endif
+
+#endif /* CONFIG_PXA_PCMCIA */
diff --git a/drivers/pcmcia/rpx_pcmcia.c b/drivers/pcmcia/rpx_pcmcia.c
new file mode 100644 (file)
index 0000000..c7c425b
--- /dev/null
@@ -0,0 +1,73 @@
+/* -------------------------------------------------------------------- */
+/* RPX Boards from Embedded Planet                                     */
+/* -------------------------------------------------------------------- */
+#include <common.h>
+#ifdef CONFIG_8xx
+#include <mpc8xx.h>
+#endif
+#include <pcmcia.h>
+
+#undef CONFIG_PCMCIA
+
+#if defined(CONFIG_CMD_PCMCIA)
+#define        CONFIG_PCMCIA
+#endif
+
+#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
+#define        CONFIG_PCMCIA
+#endif
+
+#if    defined(CONFIG_PCMCIA)  \
+       && (defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE))
+
+#define        PCMCIA_BOARD_MSG        "RPX CLASSIC or RPX LITE"
+
+int pcmcia_voltage_set(int slot, int vcc, int vpp)
+{
+       u_long reg = 0;
+
+       switch(vcc) {
+               case 0: break;
+               case 33: reg |= BCSR1_PCVCTL4; break;
+               case 50: reg |= BCSR1_PCVCTL5; break;
+               default: return 1;
+       }
+
+       switch(vpp) {
+               case 0: break;
+               case 33:
+               case 50:
+                       if(vcc == vpp)
+                               reg |= BCSR1_PCVCTL6;
+                       else
+                               return 1;
+                       break;
+               case 120:
+                       reg |= BCSR1_PCVCTL7;
+                       default: return 1;
+       }
+
+       /* first, turn off all power */
+       *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
+                       | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
+
+       /* enable new powersettings */
+       *((uint *)RPX_CSR_ADDR) |= reg;
+
+       return 0;
+}
+
+int pcmcia_hardware_enable (int slot)
+{
+       return 0;       /* No hardware to enable */
+}
+
+#if defined(CONFIG_CMD_PCMCIA)
+static int pcmcia_hardware_disable(int slot)
+{
+       return 0;       /* No hardware to disable */
+}
+#endif
+
+
+#endif /* CONFIG_PCMCIA && (CONFIG_RPXCLASSIC || CONFIG_RPXLITE) */
diff --git a/drivers/pcmcia/ti_pci1410a.c b/drivers/pcmcia/ti_pci1410a.c
new file mode 100644 (file)
index 0000000..208ca50
--- /dev/null
@@ -0,0 +1,665 @@
+/*
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ********************************************************************
+ *
+ * Lots of code copied from:
+ *
+ * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
+ * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
+ *
+ * "The ExCA standard specifies that socket controllers should provide
+ * two IO and five memory windows per socket, which can be independently
+ * configured and positioned in the host address space and mapped to
+ * arbitrary segments of card address space. " - David A Hinds. 1999
+ *
+ * This controller does _not_ meet the ExCA standard.
+ *
+ * m8xx pcmcia controller brief info:
+ * + 8 windows (attrib, mem, i/o)
+ * + up to two slots (SLOT_A and SLOT_B)
+ * + inputpins, outputpins, event and mask registers.
+ * - no offset register. sigh.
+ *
+ * Because of the lacking offset register we must map the whole card.
+ * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
+ * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
+ * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
+ * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
+ * They are maximum 64KByte each...
+ */
+
+
+#undef DEBUG           /**/
+
+/*
+ * PCMCIA support
+ */
+#include <common.h>
+#include <command.h>
+#include <config.h>
+#include <pci.h>
+#include <asm/io.h>
+
+#include <pcmcia.h>
+
+#if defined(CONFIG_CMD_PCMCIA) && defined(CONFIG_IDE_TI_CARDBUS)
+
+int pcmcia_on(int ide_base_bus);
+
+static int  pcmcia_off(void);
+static int  hardware_disable(int slot);
+static int  hardware_enable(int slot);
+static int  voltage_set(int slot, int vcc, int vpp);
+static void print_funcid(int func);
+static void print_fixed(volatile uchar *p);
+static int  identify(volatile uchar *p);
+static int  check_ide_device(int slot, int ide_base_bus);
+
+
+/* ------------------------------------------------------------------------- */
+
+
+const char *indent = "\t   ";
+
+/* ------------------------------------------------------------------------- */
+
+
+int do_pinit(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+#ifndef CFG_FIRST_PCMCIA_BUS
+# define CFG_FIRST_PCMCIA_BUS 0
+#endif
+
+       int rcode = 0;
+
+       if (argc != 2) {
+               printf ("Usage: pinit {on | off}\n");
+               return 1;
+       }
+       if (strcmp(argv[1],"on") == 0) {
+               rcode = pcmcia_on(CFG_FIRST_PCMCIA_BUS);
+       } else if (strcmp(argv[1],"off") == 0) {
+               rcode = pcmcia_off();
+       } else {
+               printf ("Usage: pinit {on | off}\n");
+               return 1;
+       }
+
+       return rcode;
+}
+
+/* ------------------------------------------------------------------------- */
+
+
+static struct pci_device_id supported[] = {
+       { PCI_VENDOR_ID_TI, 0xac50 }, /* Ti PCI1410A */
+       { PCI_VENDOR_ID_TI, 0xac56 }, /* Ti PCI1510 */
+       { }
+};
+
+static pci_dev_t devbusfn;
+static u32 socket_base;
+static u32 pcmcia_cis_ptr;
+
+int pcmcia_on(int ide_base_bus)
+{
+       u16 dev_id;
+       u32 socket_status;
+       int slot = 0;
+       int cis_len;
+       u16 io_base;
+       u16 io_len;
+
+       /*
+        * Find the CardBus PCI device(s).
+        */
+       if ((devbusfn = pci_find_devices(supported, 0)) < 0) {
+               printf("Ti CardBus: not found\n");
+               return 1;
+       }
+
+       pci_read_config_word(devbusfn, PCI_DEVICE_ID, &dev_id);
+
+       if (dev_id == 0xac56) {
+               debug("Enable PCMCIA Ti PCI1510\n");
+       } else {
+               debug("Enable PCMCIA Ti PCI1410A\n");
+       }
+
+       pcmcia_cis_ptr = CFG_PCMCIA_CIS_WIN;
+       cis_len = CFG_PCMCIA_CIS_WIN_SIZE;
+
+       io_base = CFG_PCMCIA_IO_WIN;
+       io_len = CFG_PCMCIA_IO_WIN_SIZE;
+
+       /*
+        * Setup the PCI device.
+        */
+       pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &socket_base);
+       socket_base &= ~0xf;
+
+       socket_status = readl(socket_base+8);
+       if ((socket_status & 6) == 0) {
+               printf("Card Present: ");
+
+               switch (socket_status & 0x3c00) {
+
+               case 0x400:
+                       printf("5V ");
+                       break;
+               case 0x800:
+                       printf("3.3V ");
+                       break;
+               case 0xc00:
+                       printf("3.3/5V ");
+                       break;
+               default:
+                       printf("unsupported Vcc ");
+                       break;
+               }
+               switch (socket_status & 0x30) {
+               case 0x10:
+                       printf("16bit PC-Card\n");
+                       break;
+               case 0x20:
+                       printf("32bit CardBus Card\n");
+                       break;
+               default:
+                       printf("8bit PC-Card\n");
+                       break;
+               }
+       }
+
+
+       writeb(0x41, socket_base + 0x806); /* Enable I/O window 0 and memory window 0 */
+       writeb(0x0e, socket_base + 0x807); /* Reset I/O window options */
+
+       /* Careful: the linux yenta driver do not seem to reset the offset
+        * in the i/o windows, so leaving them non-zero is a problem */
+
+       writeb(io_base & 0xff, socket_base + 0x808); /* I/O window 0 base address */
+       writeb(io_base>>8, socket_base + 0x809);
+       writeb((io_base + io_len - 1) & 0xff, socket_base + 0x80a); /* I/O window 0 end address */
+       writeb((io_base + io_len - 1)>>8, socket_base + 0x80b);
+       writeb(0x00, socket_base + 0x836);      /* I/O window 0 offset address 0x000 */
+       writeb(0x00, socket_base + 0x837);
+
+
+       writeb((pcmcia_cis_ptr&0x000ff000) >> 12,
+              socket_base + 0x810); /* Memory window 0 start address bits 19-12 */
+       writeb((pcmcia_cis_ptr&0x00f00000) >> 20,
+              socket_base + 0x811);  /* Memory window 0 start address bits 23-20 */
+       writeb(((pcmcia_cis_ptr+cis_len-1) & 0x000ff000) >> 12,
+               socket_base + 0x812); /* Memory window 0 end address bits 19-12*/
+       writeb(((pcmcia_cis_ptr+cis_len-1) & 0x00f00000) >> 20,
+               socket_base + 0x813); /* Memory window 0 end address bits 23-20*/
+       writeb(0x00, socket_base + 0x814); /* Memory window 0 offset bits 19-12 */
+       writeb(0x40, socket_base + 0x815); /* Memory window 0 offset bits 23-20 and
+                                           * options (read/write, attribute access) */
+       writeb(0x00, socket_base + 0x816); /* ExCA card-detect and general control  */
+       writeb(0x00, socket_base + 0x81e); /* ExCA global control (interrupt modes) */
+
+       writeb((pcmcia_cis_ptr & 0xff000000) >> 24,
+              socket_base + 0x840); /* Memory window address bits 31-24 */
+
+
+       /* turn off voltage */
+       if (voltage_set(slot, 0, 0)) {
+               return 1;
+       }
+
+       /* Enable external hardware */
+       if (hardware_enable(slot)) {
+               return 1;
+       }
+
+       if (check_ide_device(slot, ide_base_bus)) {
+               return 1;
+       }
+
+       return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+
+static int pcmcia_off (void)
+{
+       int slot = 0;
+
+       writeb(0x00, socket_base + 0x806); /* disable all I/O and memory windows */
+
+       writeb(0x00, socket_base + 0x808); /* I/O window 0 base address */
+       writeb(0x00, socket_base + 0x809);
+       writeb(0x00, socket_base + 0x80a); /* I/O window 0 end address */
+       writeb(0x00, socket_base + 0x80b);
+       writeb(0x00, socket_base + 0x836); /* I/O window 0 offset address  */
+       writeb(0x00, socket_base + 0x837);
+
+       writeb(0x00, socket_base + 0x80c); /* I/O window 1 base address  */
+       writeb(0x00, socket_base + 0x80d);
+       writeb(0x00, socket_base + 0x80e); /* I/O window 1 end address  */
+       writeb(0x00, socket_base + 0x80f);
+       writeb(0x00, socket_base + 0x838); /* I/O window 1 offset address  */
+       writeb(0x00, socket_base + 0x839);
+
+       writeb(0x00, socket_base + 0x810); /* Memory window 0 start address */
+       writeb(0x00, socket_base + 0x811);
+       writeb(0x00, socket_base + 0x812); /* Memory window 0 end address  */
+       writeb(0x00, socket_base + 0x813);
+       writeb(0x00, socket_base + 0x814); /* Memory window 0 offset */
+       writeb(0x00, socket_base + 0x815);
+
+       writeb(0xc0, socket_base + 0x840); /* Memory window 0 page address */
+
+
+       /* turn off voltage */
+       voltage_set(slot, 0, 0);
+
+       /* disable external hardware */
+       printf ("Shutdown and Poweroff Ti PCI1410A\n");
+       hardware_disable(slot);
+
+       return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+
+#define        MAX_TUPEL_SZ    512
+#define MAX_FEATURES   4
+int ide_devices_found;
+static int check_ide_device(int slot, int ide_base_bus)
+{
+       volatile uchar *ident = NULL;
+       volatile uchar *feature_p[MAX_FEATURES];
+       volatile uchar *p, *start;
+       int n_features = 0;
+       uchar func_id = ~0;
+       uchar code, len;
+       ushort config_base = 0;
+       int found = 0;
+       int i;
+       u32 socket_status;
+
+       debug ("PCMCIA MEM: %08X\n", pcmcia_cis_ptr);
+
+       socket_status = readl(socket_base+8);
+
+       if ((socket_status & 6) != 0 || (socket_status & 0x20) != 0) {
+               printf("no card or CardBus card\n");
+               return 1;
+       }
+
+       start = p = (volatile uchar *) pcmcia_cis_ptr;
+
+       while ((p - start) < MAX_TUPEL_SZ) {
+
+               code = *p; p += 2;
+
+               if (code == 0xFF) { /* End of chain */
+                       break;
+               }
+
+               len = *p; p += 2;
+#if defined(DEBUG) && (DEBUG > 1)
+               {
+                       volatile uchar *q = p;
+                       printf ("\nTuple code %02x  length %d\n\tData:",
+                               code, len);
+
+                       for (i = 0; i < len; ++i) {
+                               printf (" %02x", *q);
+                               q+= 2;
+                       }
+               }
+#endif /* DEBUG */
+               switch (code) {
+               case CISTPL_VERS_1:
+                       ident = p + 4;
+                       break;
+               case CISTPL_FUNCID:
+                       /* Fix for broken SanDisk which may have 0x80 bit set */
+                       func_id = *p & 0x7F;
+                       break;
+               case CISTPL_FUNCE:
+                       if (n_features < MAX_FEATURES)
+                               feature_p[n_features++] = p;
+                       break;
+               case CISTPL_CONFIG:
+                       config_base = (*(p+6) << 8) + (*(p+4));
+                       debug ("\n## Config_base = %04x ###\n", config_base);
+               default:
+                       break;
+               }
+               p += 2 * len;
+       }
+
+       found = identify(ident);
+
+       if (func_id != ((uchar)~0)) {
+               print_funcid (func_id);
+
+               if (func_id == CISTPL_FUNCID_FIXED)
+                       found = 1;
+               else
+                       return 1;       /* no disk drive */
+       }
+
+       for (i=0; i<n_features; ++i) {
+               print_fixed(feature_p[i]);
+       }
+
+       if (!found) {
+               printf("unknown card type\n");
+               return 1;
+       }
+
+       /* select config index 1 */
+       writeb(1, pcmcia_cis_ptr + config_base);
+
+#if 0
+       printf("Confiuration Option Register: %02x\n", readb(pcmcia_cis_ptr + config_base));
+       printf("Card Confiuration and Status Register: %02x\n", readb(pcmcia_cis_ptr + config_base + 2));
+       printf("Pin Replacement Register Register: %02x\n", readb(pcmcia_cis_ptr + config_base + 4));
+       printf("Socket and Copy Register: %02x\n", readb(pcmcia_cis_ptr + config_base + 6));
+#endif
+       ide_devices_found |= (1 << (slot+ide_base_bus));
+
+       return 0;
+}
+
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+       u32 socket_control;
+       int reg=0;
+
+       switch (slot) {
+       case 0:
+               reg = socket_base + 0x10;
+               break;
+       default:
+               return 1;
+       }
+
+       socket_control = 0;
+
+
+       switch (vcc) {
+       case 50:
+               socket_control |= 0x20;
+               break;
+       case 33:
+               socket_control |= 0x30;
+               break;
+       case 0:
+       default:
+       }
+
+       switch (vpp) {
+       case 120:
+               socket_control |= 0x1;
+               break;
+       case 50:
+               socket_control |= 0x2;
+               break;
+       case 33:
+               socket_control |= 0x3;
+               break;
+       case 0:
+       default:
+       }
+
+       writel(socket_control, reg);
+
+       debug ("voltage_set: Ti PCI1410A Slot %d, Vcc=%d.%d, Vpp=%d.%d\n",
+               slot, vcc/10, vcc%10, vpp/10, vpp%10);
+
+       udelay(500);
+       return 0;
+}
+
+
+static int hardware_enable(int slot)
+{
+       u32 socket_status;
+       u16 brg_ctrl;
+       int is_82365sl;
+
+       socket_status = readl(socket_base+8);
+
+       if ((socket_status & 6) == 0) {
+
+               switch (socket_status & 0x3c00) {
+
+               case 0x400:
+                       printf("5V ");
+                       voltage_set(slot, 50, 0);
+                       break;
+               case 0x800:
+                       voltage_set(slot, 33, 0);
+                       break;
+               case 0xc00:
+                       voltage_set(slot, 33, 0);
+                       break;
+               default:
+                       voltage_set(slot, 0, 0);
+                       break;
+               }
+       } else {
+               voltage_set(slot, 0, 0);
+       }
+
+       pci_read_config_word(devbusfn, PCI_BRIDGE_CONTROL, &brg_ctrl);
+       brg_ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
+       pci_write_config_word(devbusfn, PCI_BRIDGE_CONTROL, brg_ctrl);
+       is_82365sl = ((readb(socket_base+0x800) & 0x0f) == 2);
+       writeb(is_82365sl?0x90:0x98, socket_base+0x802);
+       writeb(0x67, socket_base+0x803);
+       udelay(100000);
+#if 0
+       printf("ExCA Id %02x, Card Status %02x, Power config %02x, Interrupt Config %02x, bridge control %04x %d\n",
+              readb(socket_base+0x800), readb(socket_base+0x801),
+              readb(socket_base+0x802), readb(socket_base+0x803), brg_ctrl, is_82365sl);
+#endif
+
+       return ((readb(socket_base+0x801)&0x6c)==0x6c)?0:1;
+}
+
+
+static int hardware_disable(int slot)
+{
+       voltage_set(slot, 0, 0);
+       return 0;
+}
+
+static void print_funcid(int func)
+{
+       puts(indent);
+       switch (func) {
+       case CISTPL_FUNCID_MULTI:
+               puts(" Multi-Function");
+               break;
+       case CISTPL_FUNCID_MEMORY:
+               puts(" Memory");
+               break;
+       case CISTPL_FUNCID_SERIAL:
+               puts(" Serial Port");
+               break;
+       case CISTPL_FUNCID_PARALLEL:
+               puts(" Parallel Port");
+               break;
+       case CISTPL_FUNCID_FIXED:
+               puts(" Fixed Disk");
+               break;
+       case CISTPL_FUNCID_VIDEO:
+               puts(" Video Adapter");
+               break;
+       case CISTPL_FUNCID_NETWORK:
+               puts(" Network Adapter");
+               break;
+       case CISTPL_FUNCID_AIMS:
+               puts(" AIMS Card");
+               break;
+       case CISTPL_FUNCID_SCSI:
+               puts(" SCSI Adapter");
+               break;
+       default:
+               puts(" Unknown");
+               break;
+       }
+       puts(" Card\n");
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void print_fixed(volatile uchar *p)
+{
+       if (p == NULL)
+               return;
+
+       puts(indent);
+
+       switch (*p) {
+       case CISTPL_FUNCE_IDE_IFACE:
+               {   uchar iface = *(p+2);
+
+                       puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
+                       puts (" interface ");
+                       break;
+               }
+       case CISTPL_FUNCE_IDE_MASTER:
+       case CISTPL_FUNCE_IDE_SLAVE:
+               {
+                       uchar f1 = *(p+2);
+                       uchar f2 = *(p+4);
+
+                       puts((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
+
+                       if (f1 & CISTPL_IDE_UNIQUE) {
+                               puts(" [unique]");
+                       }
+
+                       puts((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
+
+                       if (f2 & CISTPL_IDE_HAS_SLEEP) {
+                               puts(" [sleep]");
+                       }
+
+                       if (f2 & CISTPL_IDE_HAS_STANDBY) {
+                               puts(" [standby]");
+                       }
+
+                       if (f2 & CISTPL_IDE_HAS_IDLE) {
+                               puts(" [idle]");
+                       }
+
+                       if (f2 & CISTPL_IDE_LOW_POWER) {
+                               puts(" [low power]");
+                       }
+
+                       if (f2 & CISTPL_IDE_REG_INHIBIT) {
+                               puts(" [reg inhibit]");
+                       }
+
+                       if (f2 & CISTPL_IDE_HAS_INDEX) {
+                               puts(" [index]");
+                       }
+
+                       if (f2 & CISTPL_IDE_IOIS16) {
+                               puts(" [IOis16]");
+                       }
+
+                       break;
+               }
+       }
+       putc('\n');
+}
+
+/* ------------------------------------------------------------------------- */
+
+#define MAX_IDENT_CHARS                64
+#define        MAX_IDENT_FIELDS        4
+
+static uchar *known_cards[] = {
+       "ARGOSY PnPIDE D5",
+       NULL
+};
+
+static int identify(volatile uchar *p)
+{
+       uchar id_str[MAX_IDENT_CHARS];
+       uchar data;
+       uchar *t;
+       uchar **card;
+       int i, done;
+
+       if (p == NULL)
+               return (0);     /* Don't know */
+
+       t = id_str;
+       done =0;
+
+       for (i=0; i<=4 && !done; ++i, p+=2) {
+               while ((data = *p) != '\0') {
+                       if (data == 0xFF) {
+                               done = 1;
+                               break;
+                       }
+                       *t++ = data;
+                       if (t == &id_str[MAX_IDENT_CHARS-1]) {
+                               done = 1;
+                               break;
+                       }
+                       p += 2;
+               }
+               if (!done)
+                       *t++ = ' ';
+       }
+       *t = '\0';
+       while (--t > id_str) {
+               if (*t == ' ') {
+                       *t = '\0';
+               } else {
+                       break;
+               }
+       }
+       puts(id_str);
+       putc('\n');
+
+       for (card=known_cards; *card; ++card) {
+               debug ("## Compare against \"%s\"\n", *card);
+               if (strcmp(*card, id_str) == 0) {       /* found! */
+                       debug ("## CARD FOUND ##\n");
+                       return 1;
+               }
+       }
+
+       return 0;       /* don't know */
+}
+
+#endif /* CONFIG_IDE_TI_CARDBUS */
diff --git a/drivers/pcmcia/tqm8xx_pcmcia.c b/drivers/pcmcia/tqm8xx_pcmcia.c
new file mode 100644 (file)
index 0000000..132c7a5
--- /dev/null
@@ -0,0 +1,330 @@
+/* -------------------------------------------------------------------- */
+/* TQM8xxL Boards by TQ Components                                     */
+/* SC8xx   Boards by SinoVee Microsystems                              */
+/* -------------------------------------------------------------------- */
+#include <common.h>
+#ifdef CONFIG_8xx
+#include <mpc8xx.h>
+#endif
+#include <pcmcia.h>
+
+#undef CONFIG_PCMCIA
+
+#if defined(CONFIG_CMD_PCMCIA)
+#define        CONFIG_PCMCIA
+#endif
+
+#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
+#define        CONFIG_PCMCIA
+#endif
+
+#if    defined(CONFIG_PCMCIA)  \
+       && (defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx))
+
+#if    defined(CONFIG_VIRTLAB2)
+#define        PCMCIA_BOARD_MSG        "Virtlab2"
+#elif  defined(CONFIG_TQM8xxL)
+#define        PCMCIA_BOARD_MSG        "TQM8xxL"
+#elif  defined(CONFIG_SVM_SC8xx)
+#define        PCMCIA_BOARD_MSG        "SC8xx"
+#endif
+
+#if    defined(CONFIG_NSCU)
+
+#define        power_config(slot)      do {} while (0)
+#define        power_off(slot)         do {} while (0)
+#define        power_on_5_0(slot)      do {} while (0)
+#define        power_on_3_3(slot)      do {} while (0)
+
+#elif  defined(CONFIG_HMI10)
+
+static inline void power_config(int slot)
+{
+       volatile immap_t *immap = (immap_t *)CFG_IMMR;
+       /*
+        * Configure Port B  pins for
+        * 5 Volts Enable and 3 Volts enable
+       */
+       immap->im_cpm.cp_pbpar &= ~(0x00000300);
+}
+
+static inline void power_off(int slot)
+{
+       volatile immap_t *immap = (immap_t *)CFG_IMMR;
+       /* remove all power */
+       immap->im_cpm.cp_pbdat |= 0x00000300;
+}
+
+static inline void power_on_5_0(int slot)
+{
+       volatile immap_t *immap = (immap_t *)CFG_IMMR;
+       immap->im_cpm.cp_pbdat &= ~(0x0000100);
+       immap->im_cpm.cp_pbdir |= 0x00000300;
+}
+
+static inline void power_on_3_3(int slot)
+{
+       volatile immap_t *immap = (immap_t *)CFG_IMMR;
+       immap->im_cpm.cp_pbdat &= ~(0x0000200);
+       immap->im_cpm.cp_pbdir |= 0x00000300;
+}
+
+#elif  defined(CONFIG_VIRTLAB2)
+
+#define        power_config(slot)      do {} while (0)
+static inline void power_off(int slot)
+{
+       volatile unsigned char  *powerctl =
+                       (volatile unsigned char *)PCMCIA_CTRL;
+       *powerctl = 0;
+}
+
+static inline void power_on_5_0(int slot)
+{
+       volatile unsigned char  *powerctl =
+                       (volatile unsigned char *)PCMCIA_CTRL;
+                       *powerctl = 2;  /* Enable 5V Vccout */
+}
+
+static inline void power_on_3_3(int slot)
+{
+       volatile unsigned char  *powerctl =
+                       (volatile unsigned char *)PCMCIA_CTRL;
+                       *powerctl = 1;  /* Enable 3.3V Vccout */
+}
+
+#else
+
+static inline void power_config(int slot)
+{
+       volatile immap_t *immap = (immap_t *)CFG_IMMR;
+       /*
+       * Configure Port C pins for
+       * 5 Volts Enable and 3 Volts enable
+       */
+       immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
+       immap->im_ioport.iop_pcso  &= ~(0x0002 | 0x0004);
+}
+
+static inline void power_off(int slot)
+{
+       volatile immap_t *immap = (immap_t *)CFG_IMMR;
+       immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
+}
+
+static inline void power_on_5_0(int slot)
+{
+       volatile immap_t *immap = (immap_t *)CFG_IMMR;
+       immap->im_ioport.iop_pcdat |= 0x0004;
+       immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
+}
+
+static inline void power_on_3_3(int slot)
+{
+       volatile immap_t *immap = (immap_t *)CFG_IMMR;
+       immap->im_ioport.iop_pcdat |= 0x0002;
+       immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
+}
+
+#endif
+
+#ifdef CONFIG_HMI10
+static inline int check_card_is_absent(int slot)
+{
+       volatile pcmconf8xx_t *pcmp =
+               (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+       return pcmp->pcmc_pipr & (0x10000000 >> (slot << 4));
+}
+#else
+static inline int check_card_is_absent(int slot)
+{
+       volatile pcmconf8xx_t *pcmp =
+               (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+       return pcmp->pcmc_pipr & (0x18000000 >> (slot << 4));
+}
+#endif
+
+#ifdef NSCU_OE_INV
+#define        NSCU_GCRX_CXOE  0
+#else
+#define        NSCU_GCRX_CXOE  __MY_PCMCIA_GCRX_CXOE
+#endif
+
+int pcmcia_hardware_enable(int slot)
+{
+       volatile pcmconf8xx_t *pcmp =
+               (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+       volatile sysconf8xx_t *sysp =
+               (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
+       uint reg, mask;
+
+       debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+       udelay(10000);
+
+       /*
+       * Configure SIUMCR to enable PCMCIA port B
+       * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
+       */
+       sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
+
+       /* clear interrupt state, and disable interrupts */
+       pcmp->pcmc_pscr =  PCMCIA_MASK(slot);
+       pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
+
+       /*
+       * Disable interrupts, DMA, and PCMCIA buffers
+       * (isolate the interface) and assert RESET signal
+       */
+       debug ("Disable PCMCIA buffers and assert RESET\n");
+       reg  = 0;
+       reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
+       reg |= NSCU_GCRX_CXOE;
+
+       PCMCIA_PGCRX(slot) = reg;
+       udelay(500);
+
+       power_config(slot);
+       power_off(slot);
+
+       /*
+        * Make sure there is a card in the slot, then configure the interface.
+       */
+       udelay(10000);
+       debug ("[%d] %s: PIPR(%p)=0x%x\n", __LINE__,__FUNCTION__,
+              &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
+
+       if (check_card_is_absent(slot)) {
+               printf ("   No Card found\n");
+               return (1);
+       }
+
+       /*
+       * Power On.
+       */
+       mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
+       reg  = pcmp->pcmc_pipr;
+       debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
+              reg,
+              (reg&PCMCIA_VS1(slot))?"n":"ff",
+              (reg&PCMCIA_VS2(slot))?"n":"ff");
+
+       if ((reg & mask) == mask) {
+               power_on_5_0(slot);
+               puts (" 5.0V card found: ");
+       } else {
+               power_on_3_3(slot);
+               puts (" 3.3V card found: ");
+       }
+
+#if 0
+       /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
+       cp->cp_pbdir &= ~(0x0020 | 0x0010);
+       cp->cp_pbpar &= ~(0x0020 | 0x0010);
+       udelay(500000);
+#endif
+
+       udelay(1000);
+       debug ("Enable PCMCIA buffers and stop RESET\n");
+       reg  =  PCMCIA_PGCRX(slot);
+       reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
+       reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
+       reg &= ~NSCU_GCRX_CXOE;
+
+       PCMCIA_PGCRX(slot) = reg;
+
+       udelay(250000); /* some cards need >150 ms to come up :-( */
+
+       debug ("# hardware_enable done\n");
+
+       return (0);
+}
+
+
+#if defined(CONFIG_CMD_PCMCIA)
+int pcmcia_hardware_disable(int slot)
+{
+       u_long reg;
+
+       debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+
+       /* remove all power */
+       power_off(slot);
+
+       debug ("Disable PCMCIA buffers and assert RESET\n");
+       reg  = 0;
+       reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
+       reg |= NSCU_GCRX_CXOE;                  /* active low  */
+
+       PCMCIA_PGCRX(slot) = reg;
+
+       udelay(10000);
+
+       return (0);
+}
+#endif
+
+int pcmcia_voltage_set(int slot, int vcc, int vpp)
+{
+#ifndef CONFIG_NSCU
+       u_long reg;
+# ifdef DEBUG
+       volatile pcmconf8xx_t *pcmp =
+               (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+# endif
+
+       debug ("voltage_set: " PCMCIA_BOARD_MSG
+               " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
+               'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
+
+       /*
+       * Disable PCMCIA buffers (isolate the interface)
+       * and assert RESET signal
+       */
+       debug ("Disable PCMCIA buffers and assert RESET\n");
+       reg  = PCMCIA_PGCRX(slot);
+       reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
+       reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
+       reg |= NSCU_GCRX_CXOE;                  /* active low  */
+
+       PCMCIA_PGCRX(slot) = reg;
+       udelay(500);
+
+       debug ("PCMCIA power OFF\n");
+       power_config(slot);
+       power_off(slot);
+
+       switch(vcc) {
+               case  0:                        break;
+               case 33: power_on_3_3(slot);    break;
+               case 50: power_on_5_0(slot);    break;
+               default:                        goto done;
+       }
+
+       /* Checking supported voltages */
+
+       debug("PIPR: 0x%x --> %s\n", pcmp->pcmc_pipr,
+              (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
+
+       if (vcc)
+               debug("PCMCIA powered at %sV\n", (vcc == 50) ? "5.0" : "3.3");
+       else
+               debug("PCMCIA powered down\n");
+
+done:
+       debug("Enable PCMCIA buffers and stop RESET\n");
+       reg  =  PCMCIA_PGCRX(slot);
+       reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
+       reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
+       reg &= ~NSCU_GCRX_CXOE;                 /* active low  */
+
+       PCMCIA_PGCRX(slot) = reg;
+       udelay(500);
+
+       debug("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n", slot+'A');
+#endif /* CONFIG_NSCU */
+       return (0);
+}
+
+#endif /* CONFIG_PCMCIA && (CONFIG_TQM8xxL || CONFIG_SVM_SC8xx) */
diff --git a/drivers/pcnet.c b/drivers/pcnet.c
deleted file mode 100644 (file)
index 2af0e8f..0000000
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- * (C) Copyright 2002 Wolfgang Grandegger, wg@denx.de.
- *
- * This driver for AMD PCnet network controllers is derived from the
- * Linux driver pcnet32.c written 1996-1999 by Thomas Bogendoerfer.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <malloc.h>
-#include <net.h>
-#include <asm/io.h>
-#include <pci.h>
-
-#if 0
-#define        PCNET_DEBUG_LEVEL       0 /* 0=off, 1=init, 2=rx/tx */
-#endif
-
-#if PCNET_DEBUG_LEVEL > 0
-#define        PCNET_DEBUG1(fmt,args...)       printf (fmt ,##args)
-#if PCNET_DEBUG_LEVEL > 1
-#define        PCNET_DEBUG2(fmt,args...)       printf (fmt ,##args)
-#else
-#define PCNET_DEBUG2(fmt,args...)
-#endif
-#else
-#define PCNET_DEBUG1(fmt,args...)
-#define PCNET_DEBUG2(fmt,args...)
-#endif
-
-#if defined(CONFIG_CMD_NET) \
-       && defined(CONFIG_NET_MULTI) && defined(CONFIG_PCNET)
-
-#if !defined(CONF_PCNET_79C973) && defined(CONF_PCNET_79C975)
-#error "Macro for PCnet chip version is not defined!"
-#endif
-
-/*
- * Set the number of Tx and Rx buffers, using Log_2(# buffers).
- * Reasonable default values are 4 Tx buffers, and 16 Rx buffers.
- * That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4).
- */
-#define PCNET_LOG_TX_BUFFERS   0
-#define PCNET_LOG_RX_BUFFERS   2
-
-#define TX_RING_SIZE           (1 << (PCNET_LOG_TX_BUFFERS))
-#define TX_RING_LEN_BITS       ((PCNET_LOG_TX_BUFFERS) << 12)
-
-#define RX_RING_SIZE           (1 << (PCNET_LOG_RX_BUFFERS))
-#define RX_RING_LEN_BITS       ((PCNET_LOG_RX_BUFFERS) << 4)
-
-#define PKT_BUF_SZ             1544
-
-/* The PCNET Rx and Tx ring descriptors. */
-struct pcnet_rx_head {
-    u32 base;
-    s16 buf_length;
-    s16 status;
-    u32 msg_length;
-    u32 reserved;
-};
-
-struct pcnet_tx_head {
-    u32 base;
-    s16 length;
-    s16 status;
-    u32 misc;
-    u32 reserved;
-};
-
-/* The PCNET 32-Bit initialization block, described in databook. */
-struct pcnet_init_block {
-    u16 mode;
-    u16 tlen_rlen;
-    u8 phys_addr[6];
-    u16 reserved;
-    u32 filter[2];
-    /* Receive and transmit ring base, along with extra bits. */
-    u32 rx_ring;
-    u32 tx_ring;
-    u32 reserved2;
-};
-
-typedef struct pcnet_priv {
-    struct pcnet_rx_head    rx_ring[RX_RING_SIZE];
-    struct pcnet_tx_head    tx_ring[TX_RING_SIZE];
-    struct pcnet_init_block init_block;
-    /* Receive Buffer space */
-    unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4];
-    int cur_rx;
-    int cur_tx;
-} pcnet_priv_t;
-
-static pcnet_priv_t *lp;
-
-/* Offsets from base I/O address for WIO mode */
-#define PCNET_RDP              0x10
-#define PCNET_RAP              0x12
-#define PCNET_RESET            0x14
-#define PCNET_BDP              0x16
-
-static u16 pcnet_read_csr (struct eth_device *dev, int index)
-{
-    outw (index, dev->iobase+PCNET_RAP);
-    return inw (dev->iobase+PCNET_RDP);
-}
-
-static void pcnet_write_csr (struct eth_device *dev, int index, u16 val)
-{
-    outw (index, dev->iobase+PCNET_RAP);
-    outw (val, dev->iobase+PCNET_RDP);
-}
-
-static u16 pcnet_read_bcr (struct eth_device *dev, int index)
-{
-    outw (index, dev->iobase+PCNET_RAP);
-    return inw (dev->iobase+PCNET_BDP);
-}
-
-static void pcnet_write_bcr (struct eth_device *dev, int index, u16 val)
-{
-    outw (index, dev->iobase+PCNET_RAP);
-    outw (val, dev->iobase+PCNET_BDP);
-}
-
-static void pcnet_reset (struct eth_device *dev)
-{
-    inw (dev->iobase+PCNET_RESET);
-}
-
-static int pcnet_check (struct eth_device *dev)
-{
-    outw (88, dev->iobase+PCNET_RAP);
-    return (inw (dev->iobase+PCNET_RAP) == 88);
-}
-
-static int  pcnet_init( struct eth_device* dev, bd_t *bis);
-static int  pcnet_send (struct eth_device* dev, volatile void *packet,
-                       int length);
-static int  pcnet_recv (struct eth_device* dev);
-static void pcnet_halt (struct eth_device* dev);
-static int  pcnet_probe(struct eth_device* dev, bd_t *bis, int dev_num);
-
-#define PCI_TO_MEM(d,a) pci_phys_to_mem((pci_dev_t)d->priv, (u_long)(a))
-#define PCI_TO_MEM_LE(d,a) (u32)(cpu_to_le32(PCI_TO_MEM(d,a)))
-
-static struct pci_device_id supported[] = {
-       { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE },
-       { }
-};
-
-
-int pcnet_initialize(bd_t *bis)
-{
-    pci_dev_t devbusfn;
-    struct eth_device* dev;
-    u16 command, status;
-    int dev_nr = 0;
-
-    PCNET_DEBUG1("\npcnet_initialize...\n");
-
-    for (dev_nr = 0; ; dev_nr++) {
-
-       /*
-        * Find the PCnet PCI device(s).
-        */
-       if ((devbusfn = pci_find_devices(supported, dev_nr)) < 0) {
-           break;
-       }
-
-       /*
-        * Allocate and pre-fill the device structure.
-        */
-       dev = (struct eth_device*) malloc(sizeof *dev);
-       dev->priv = (void *)devbusfn;
-       sprintf(dev->name, "pcnet#%d", dev_nr);
-
-       /*
-        * Setup the PCI device.
-        */
-       pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, (unsigned int *)&dev->iobase);
-       dev->iobase &= ~0xf;
-
-       PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%x: ",
-              dev->name, devbusfn, dev->iobase);
-
-       command = PCI_COMMAND_IO | PCI_COMMAND_MASTER;
-       pci_write_config_word(devbusfn, PCI_COMMAND, command);
-       pci_read_config_word(devbusfn, PCI_COMMAND, &status);
-       if ((status & command) != command) {
-           printf("%s: Couldn't enable IO access or Bus Mastering\n",
-                  dev->name);
-           free(dev);
-           continue;
-       }
-
-       pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x40);
-
-       /*
-        * Probe the PCnet chip.
-        */
-       if (pcnet_probe(dev, bis, dev_nr) < 0) {
-           free(dev);
-           continue;
-       }
-
-       /*
-        * Setup device structure and register the driver.
-        */
-       dev->init   = pcnet_init;
-       dev->halt   = pcnet_halt;
-       dev->send   = pcnet_send;
-       dev->recv   = pcnet_recv;
-
-       eth_register(dev);
-    }
-
-    udelay(10 * 1000);
-
-    return dev_nr;
-}
-
-static int pcnet_probe(struct eth_device* dev, bd_t *bis, int dev_nr)
-{
-    int chip_version;
-    char *chipname;
-#ifdef PCNET_HAS_PROM
-    int i;
-#endif
-
-    /* Reset the PCnet controller */
-    pcnet_reset(dev);
-
-    /* Check if register access is working */
-    if (pcnet_read_csr(dev, 0) != 4 || !pcnet_check(dev)) {
-       printf("%s: CSR register access check failed\n", dev->name);
-       return -1;
-    }
-
-    /* Identify the chip */
-    chip_version = pcnet_read_csr(dev, 88) | (pcnet_read_csr(dev,89) << 16);
-    if ((chip_version & 0xfff) != 0x003)
-       return -1;
-    chip_version = (chip_version >> 12) & 0xffff;
-    switch (chip_version) {
-#ifdef CONFIG_PCNET_79C973
-    case 0x2625:
-       chipname = "PCnet/FAST III 79C973"; /* PCI */
-       break;
-#endif
-#ifdef CONFIG_PCNET_79C975
-    case 0x2627:
-       chipname = "PCnet/FAST III 79C975"; /* PCI */
-       break;
-#endif
-    default:
-       printf("%s: PCnet version %#x not supported\n",
-              dev->name, chip_version);
-       return -1;
-    }
-
-    PCNET_DEBUG1("AMD %s\n", chipname);
-
-#ifdef PCNET_HAS_PROM
-    /*
-     * In most chips, after a chip reset, the ethernet address is read from
-     * the station address PROM at the base address and programmed into the
-     * "Physical Address Registers" CSR12-14.
-     */
-    for (i = 0; i < 3; i++) {
-       unsigned int val;
-       val = pcnet_read_csr(dev, i+12) & 0x0ffff;
-       /* There may be endianness issues here. */
-       dev->enetaddr[2*i  ] =  val       & 0x0ff;
-       dev->enetaddr[2*i+1] = (val >> 8) & 0x0ff;
-    }
-#endif /* PCNET_HAS_PROM */
-
-    return 0;
-}
-
-static int pcnet_init(struct eth_device* dev, bd_t *bis)
-{
-    int i, val;
-    u32 addr;
-
-    PCNET_DEBUG1("%s: pcnet_init...\n", dev->name);
-
-    /* Switch pcnet to 32bit mode */
-    pcnet_write_bcr (dev, 20, 2);
-
-#ifdef CONFIG_PN62
-    /* Setup LED registers */
-    val = pcnet_read_bcr (dev, 2) | 0x1000;
-    pcnet_write_bcr (dev, 2, val);    /* enable LEDPE */
-    pcnet_write_bcr (dev, 4, 0x5080); /* 100MBit */
-    pcnet_write_bcr (dev, 5, 0x40c0); /* LNKSE */
-    pcnet_write_bcr (dev, 6, 0x4090); /* TX Activity */
-    pcnet_write_bcr (dev, 7, 0x4084); /* RX Activity */
-#endif
-
-    /* Set/reset autoselect bit */
-    val = pcnet_read_bcr (dev, 2) & ~2;
-    val |= 2;
-    pcnet_write_bcr (dev, 2, val);
-
-    /* Enable auto negotiate, setup, disable fd */
-    val = pcnet_read_bcr(dev, 32) & ~0x98;
-    val |= 0x20;
-    pcnet_write_bcr(dev, 32, val);
-
-    /*
-     * We only maintain one structure because the drivers will never
-     * be used concurrently. In 32bit mode the RX and TX ring entries
-     * must be aligned on 16-byte boundaries.
-     */
-    if (lp == NULL) {
-       addr = (u32)malloc(sizeof(pcnet_priv_t) + 0x10);
-       addr = (addr + 0xf) & ~0xf;
-       lp = (pcnet_priv_t *)addr;
-    }
-
-    lp->init_block.mode = cpu_to_le16(0x0000);
-    lp->init_block.filter[0] = 0x00000000;
-    lp->init_block.filter[1] = 0x00000000;
-
-    /*
-     * Initialize the Rx ring.
-     */
-    lp->cur_rx = 0;
-    for (i = 0; i < RX_RING_SIZE; i++) {
-       lp->rx_ring[i].base = PCI_TO_MEM_LE(dev, lp->rx_buf[i]);
-       lp->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ);
-       lp->rx_ring[i].status = cpu_to_le16(0x8000);
-       PCNET_DEBUG1("Rx%d: base=0x%x buf_length=0x%hx status=0x%hx\n",
-              i, lp->rx_ring[i].base, lp->rx_ring[i].buf_length,
-              lp->rx_ring[i].status);
-    }
-
-    /*
-     * Initialize the Tx ring. The Tx buffer address is filled in as
-     * needed, but we do need to clear the upper ownership bit.
-     */
-    lp->cur_tx = 0;
-    for (i = 0; i < TX_RING_SIZE; i++) {
-       lp->tx_ring[i].base = 0;
-       lp->tx_ring[i].status = 0;
-    }
-
-    /*
-     * Setup Init Block.
-     */
-    PCNET_DEBUG1("Init block at 0x%p: MAC", &lp->init_block);
-
-    for (i = 0; i < 6; i++) {
-       lp->init_block.phys_addr[i] = dev->enetaddr[i];
-       PCNET_DEBUG1(" %02x", lp->init_block.phys_addr[i]);
-    }
-
-    lp->init_block.tlen_rlen = cpu_to_le16(TX_RING_LEN_BITS |
-                                          RX_RING_LEN_BITS);
-    lp->init_block.rx_ring = PCI_TO_MEM_LE(dev, lp->rx_ring);
-    lp->init_block.tx_ring = PCI_TO_MEM_LE(dev, lp->tx_ring);
-
-    PCNET_DEBUG1("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n",
-          lp->init_block.tlen_rlen,
-          lp->init_block.rx_ring, lp->init_block.tx_ring);
-
-    /*
-     * Tell the controller where the Init Block is located.
-     */
-    addr = PCI_TO_MEM(dev, &lp->init_block);
-    pcnet_write_csr(dev, 1, addr & 0xffff);
-    pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff);
-
-    pcnet_write_csr (dev, 4, 0x0915);
-    pcnet_write_csr (dev, 0, 0x0001); /* start */
-
-    /* Wait for Init Done bit */
-    for (i = 10000; i > 0; i--) {
-       if (pcnet_read_csr (dev, 0) & 0x0100)
-           break;
-       udelay(10);
-    }
-    if (i <= 0) {
-       printf("%s: TIMEOUT: controller init failed\n", dev->name);
-       pcnet_reset (dev);
-       return 0;
-    }
-
-    /*
-     * Finally start network controller operation.
-     */
-    pcnet_write_csr (dev, 0, 0x0002);
-
-    return 1;
-}
-
-static int pcnet_send(struct eth_device* dev, volatile void *packet, int pkt_len)
-{
-    int i, status;
-    struct pcnet_tx_head *entry = &lp->tx_ring[lp->cur_tx];
-
-    PCNET_DEBUG2("Tx%d: %d bytes from 0x%p ", lp->cur_tx, pkt_len, packet);
-
-    /* Wait for completion by testing the OWN bit */
-    for (i = 1000; i > 0; i--) {
-       status = le16_to_cpu(entry->status);
-       if ((status & 0x8000) == 0)
-           break;
-       udelay(100);
-       PCNET_DEBUG2(".");
-    }
-    if (i <= 0) {
-       printf("%s: TIMEOUT: Tx%d failed (status = 0x%x)\n",
-              dev->name, lp->cur_tx, status);
-       pkt_len = 0;
-       goto failure;
-    }
-
-    /*
-     * Setup Tx ring. Caution: the write order is important here,
-     * set the status with the "ownership" bits last.
-     */
-    status = 0x8300;
-    entry->length = le16_to_cpu(-pkt_len);
-    entry->misc   = 0x00000000;
-    entry->base   = PCI_TO_MEM_LE(dev, packet);
-    entry->status = le16_to_cpu(status);
-
-    /* Trigger an immediate send poll. */
-    pcnet_write_csr (dev, 0, 0x0008);
-
- failure:
-    if (++lp->cur_tx >= TX_RING_SIZE)
-       lp->cur_tx = 0;
-
-    PCNET_DEBUG2("done\n");
-    return pkt_len;
-}
-
-static int pcnet_recv(struct eth_device* dev)
-{
-    struct pcnet_rx_head *entry;
-    int pkt_len = 0;
-    u16 status;
-
-    while (1) {
-       entry = &lp->rx_ring[lp->cur_rx];
-       /*
-        * If we own the next entry, it's a new packet. Send it up.
-        */
-       if (((status = le16_to_cpu(entry->status)) & 0x8000) != 0) {
-           break;
-       }
-       status >>= 8;
-
-       if (status != 0x03) {   /* There was an error. */
-
-           printf("%s: Rx%d", dev->name, lp->cur_rx);
-           PCNET_DEBUG1(" (status=0x%x)", status);
-           if (status & 0x20) printf(" Frame");
-           if (status & 0x10) printf(" Overflow");
-           if (status & 0x08) printf(" CRC");
-           if (status & 0x04) printf(" Fifo");
-           printf(" Error\n");
-           entry->status &= le16_to_cpu(0x03ff);
-
-       } else {
-
-           pkt_len = (le32_to_cpu(entry->msg_length) & 0xfff) - 4;
-           if (pkt_len < 60) {
-               printf("%s: Rx%d: invalid packet length %d\n",
-                      dev->name, lp->cur_rx, pkt_len);
-           } else {
-               NetReceive(lp->rx_buf[lp->cur_rx], pkt_len);
-               PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n",
-                      lp->cur_rx, pkt_len, lp->rx_buf[lp->cur_rx]);
-           }
-       }
-       entry->status |= cpu_to_le16(0x8000);
-
-       if (++lp->cur_rx >= RX_RING_SIZE)
-           lp->cur_rx = 0;
-    }
-    return pkt_len;
-}
-
-static void pcnet_halt(struct eth_device* dev)
-{
-    int i;
-
-    PCNET_DEBUG1("%s: pcnet_halt...\n", dev->name);
-
-    /* Reset the PCnet controller */
-    pcnet_reset (dev);
-
-    /* Wait for Stop bit */
-    for (i = 1000; i > 0; i--) {
-       if (pcnet_read_csr (dev, 0) & 0x4)
-           break;
-       udelay(10);
-    }
-    if (i <= 0) {
-       printf("%s: TIMEOUT: controller reset failed\n", dev->name);
-    }
-}
-
-#endif
diff --git a/drivers/plb2800_eth.c b/drivers/plb2800_eth.c
deleted file mode 100644 (file)
index 0ae5d80..0000000
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * PLB2800 internal switch ethernet driver.
- *
- * (C) Copyright 2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-
-#if defined(CONFIG_CMD_NET) \
-       && defined(CONFIG_NET_MULTI) && defined(CONFIG_PLB2800_ETHER)
-
-#include <malloc.h>
-#include <net.h>
-#include <asm/addrspace.h>
-
-
-#define NUM_RX_DESC    PKTBUFSRX
-#define TOUT_LOOP      1000000
-
-#define LONG_REF(addr) (*((volatile unsigned long*)addr))
-
-#define CMAC_CRX_CTRL  LONG_REF(0xb800c870)
-#define CMAC_CTX_CTRL  LONG_REF(0xb800c874)
-#define SYS_MAC_ADDR_0 LONG_REF(0xb800c878)
-#define SYS_MAC_ADDR_1 LONG_REF(0xb800c87c)
-#define MIPS_H_MASK    LONG_REF(0xB800C810)
-
-#define MA_LEARN       LONG_REF(0xb8008004)
-#define DA_LOOKUP      LONG_REF(0xb8008008)
-
-#define CMAC_CRX_CTRL_PD       0x00000001
-#define CMAC_CRX_CTRL_CG       0x00000002
-#define CMAC_CRX_CTRL_PL_SHIFT 2
-#define CMAC_CRIT              0x0
-#define CMAC_NON_CRIT          0x1
-#define MBOX_STAT_ID_SHF       28
-#define MBOX_STAT_CP           0x80000000
-#define MBOX_STAT_MB           0x00000001
-#define EN_MA_LEARN            0x02000000
-#define EN_DA_LKUP             0x01000000
-#define MA_DEST_SHF            11
-#define DA_DEST_SHF            11
-#define DA_STATE_SHF           19
-#define TSTAMP_MS              0x00000000
-#define SW_H_MBOX4_MASK                0x08000000
-#define SW_H_MBOX3_MASK                0x04000000
-#define SW_H_MBOX2_MASK                0x02000000
-#define SW_H_MBOX1_MASK                0x01000000
-
-typedef volatile struct {
-  unsigned int stat;
-  unsigned int cmd;
-  unsigned int cnt;
-  unsigned int adr;
-} mailbox_t;
-
-#define MBOX_REG(mb) ((mailbox_t*)(0xb800c830+(mb<<4)))
-
-typedef volatile struct {
-  unsigned int word0;
-  unsigned int word1;
-  unsigned int word2;
-} mbhdr_t;
-
-#define MBOX_MEM(mb) ((void*)(0xb800a000+((3-mb)<<11)))
-
-
-static int plb2800_eth_init(struct eth_device *dev, bd_t * bis);
-static int plb2800_eth_send(struct eth_device *dev, volatile void *packet,
-                                                 int length);
-static int plb2800_eth_recv(struct eth_device *dev);
-static void plb2800_eth_halt(struct eth_device *dev);
-
-static void plb2800_set_mac_addr(struct eth_device *dev, unsigned char * addr);
-static unsigned char * plb2800_get_mac_addr(void);
-
-static int rx_new;
-static int mac_addr_set = 0;
-
-
-int plb2800_eth_initialize(bd_t * bis)
-{
-       struct eth_device *dev;
-       ulong temp;
-
-#ifdef DEBUG
-       printf("Entered plb2800_eth_initialize()\n");
-#endif
-
-       if (!(dev = (struct eth_device *) malloc (sizeof *dev)))
-       {
-               printf("Failed to allocate memory\n");
-               return 0;
-       }
-       memset(dev, 0, sizeof(*dev));
-
-       sprintf(dev->name, "PLB2800 Switch");
-       dev->init = plb2800_eth_init;
-       dev->halt = plb2800_eth_halt;
-       dev->send = plb2800_eth_send;
-       dev->recv = plb2800_eth_recv;
-
-       eth_register(dev);
-
-       /* bug fix */
-       *(ulong *)0xb800e800 = 0x838;
-
-       /* Set MBOX ownership */
-       temp = CMAC_CRIT << MBOX_STAT_ID_SHF;
-       MBOX_REG(0)->stat = temp;
-       MBOX_REG(1)->stat = temp;
-
-       temp = CMAC_NON_CRIT << MBOX_STAT_ID_SHF;
-       MBOX_REG(2)->stat = temp;
-       MBOX_REG(3)->stat = temp;
-
-       plb2800_set_mac_addr(dev, plb2800_get_mac_addr());
-
-       /* Disable all Mbox interrupt */
-       temp = MIPS_H_MASK;
-       temp &= ~ (SW_H_MBOX1_MASK | SW_H_MBOX2_MASK | SW_H_MBOX3_MASK | SW_H_MBOX4_MASK) ;
-       MIPS_H_MASK = temp;
-
-#ifdef DEBUG
-       printf("Leaving plb2800_eth_initialize()\n");
-#endif
-
-       return 1;
-}
-
-static int plb2800_eth_init(struct eth_device *dev, bd_t * bis)
-{
-#ifdef DEBUG
-       printf("Entering plb2800_eth_init()\n");
-#endif
-
-       plb2800_set_mac_addr(dev, dev->enetaddr);
-
-       rx_new = 0;
-
-#ifdef DEBUG
-       printf("Leaving plb2800_eth_init()\n");
-#endif
-
-       return 0;
-}
-
-
-static int plb2800_eth_send(struct eth_device *dev, volatile void *packet,
-                                                 int length)
-{
-       int                    i;
-       int                    res         = -1;
-       u32                    temp;
-       mailbox_t *            mb          = MBOX_REG(0);
-       char      *            mem         = MBOX_MEM(0);
-
-#ifdef DEBUG
-       printf("Entered plb2800_eth_send()\n");
-#endif
-
-       if (length <= 0)
-       {
-               printf ("%s: bad packet size: %d\n", dev->name, length);
-               goto Done;
-       }
-
-       if (length < 64)
-       {
-               length = 64;
-       }
-
-       temp = CMAC_CRX_CTRL_CG | ((length + 4) << CMAC_CRX_CTRL_PL_SHIFT);
-
-#ifdef DEBUG
-       printf("0 mb->stat = 0x%x\n",  mb->stat);
-#endif
-
-       for(i = 0; mb->stat & (MBOX_STAT_CP | MBOX_STAT_MB); i++)
-       {
-               if (i >= TOUT_LOOP)
-               {
-                       printf("%s: tx buffer not ready\n", dev->name);
-                       printf("1 mb->stat = 0x%x\n",  mb->stat);
-                       goto Done;
-               }
-       }
-
-               /* For some strange reason, memcpy doesn't work, here!
-                */
-       do
-       {
-               int words = (length >> 2) + 1;
-               unsigned int* dst = (unsigned int*)(mem);
-               unsigned int* src = (unsigned int*)(packet);
-               for (i = 0; i < words; i++)
-               {
-                       *dst = *src;
-                       dst++;
-                       src++;
-               };
-       } while(0);
-
-       CMAC_CRX_CTRL = temp;
-       mb->cmd = MBOX_STAT_CP;
-
-#ifdef DEBUG
-       printf("2 mb->stat = 0x%x\n",  mb->stat);
-#endif
-
-       res = length;
-Done:
-
-#ifdef DEBUG
-       printf("Leaving plb2800_eth_send()\n");
-#endif
-
-       return res;
-}
-
-
-static int plb2800_eth_recv(struct eth_device *dev)
-{
-       int                    length  = 0;
-       mailbox_t            * mbox    = MBOX_REG(3);
-       unsigned char        * hdr     = MBOX_MEM(3);
-       unsigned int           stat;
-
-#ifdef DEBUG
-       printf("Entered plb2800_eth_recv()\n");
-#endif
-
-       for (;;)
-       {
-               stat = mbox->stat;
-
-               if (!(stat & MBOX_STAT_CP))
-               {
-                       break;
-               }
-
-               length = ((*(hdr + 6) & 0x3f) << 8) + *(hdr + 7);
-               memcpy((void *)NetRxPackets[rx_new], hdr + 12, length);
-
-               stat &= ~MBOX_STAT_CP;
-               mbox->stat = stat;
-#ifdef DEBUG
-               {
-                       int i;
-                       for (i=0;i<length - 4;i++)
-                       {
-                               if (i % 16 == 0) printf("\n%04x: ", i);
-                               printf("%02X ", NetRxPackets[rx_new][i]);
-                       }
-                       printf("\n");
-               }
-#endif
-
-               if (length)
-               {
-#ifdef DEBUG
-                       printf("Received %d bytes\n", length);
-#endif
-                       NetReceive((void*)(NetRxPackets[rx_new]),
-                                   length - 4);
-               }
-               else
-               {
-#if 1
-                       printf("Zero length!!!\n");
-#endif
-               }
-
-               rx_new = (rx_new + 1) % NUM_RX_DESC;
-       }
-
-#ifdef DEBUG
-       printf("Leaving plb2800_eth_recv()\n");
-#endif
-
-       return length;
-}
-
-
-static void plb2800_eth_halt(struct eth_device *dev)
-{
-#ifdef DEBUG
-       printf("Entered plb2800_eth_halt()\n");
-#endif
-
-#ifdef DEBUG
-       printf("Leaving plb2800_eth_halt()\n");
-#endif
-}
-
-static void plb2800_set_mac_addr(struct eth_device *dev, unsigned char * addr)
-{
-       char packet[60];
-       ulong temp;
-       int ix;
-
-       if (mac_addr_set ||
-           NULL == addr || memcmp(addr, "\0\0\0\0\0\0", 6) == 0)
-       {
-               return;
-       }
-
-       /* send one packet through CPU port
-        * in order to learn system MAC address
-        */
-
-       /* Set DA_LOOKUP register */
-       temp = EN_MA_LEARN | (0 << DA_STATE_SHF) | (63 << DA_DEST_SHF);
-       DA_LOOKUP = temp;
-
-       /* Set MA_LEARN register */
-       temp = 50 << MA_DEST_SHF;       /* static entry */
-       MA_LEARN = temp;
-
-       /* set destination address */
-       for (ix=0;ix<6;ix++)
-               packet[ix] = 0xff;
-
-       /* set source address = system MAC address */
-       for (ix=0;ix<6;ix++)
-               packet[6+ix] = addr[ix];
-
-       /* set type field */
-       packet[12]=0xaa;
-       packet[13]=0x55;
-
-       /* set data field */
-       for(ix=14;ix<60;ix++)
-               packet[ix] = 0x00;
-
-#ifdef DEBUG
-       for (ix=0;ix<6;ix++)
-               printf("mac_addr[%d]=%02X\n", ix, (unsigned char)packet[6+ix]);
-#endif
-
-       /* set one packet */
-       plb2800_eth_send(dev, packet, sizeof(packet));
-
-       /* delay for a while */
-       for(ix=0;ix<65535;ix++)
-               temp = ~temp;
-
-       /* Set CMAC_CTX_CTRL register */
-       temp = TSTAMP_MS;       /* no autocast */
-       CMAC_CTX_CTRL = temp;
-
-       /* Set DA_LOOKUP register */
-       temp = EN_DA_LKUP;
-       DA_LOOKUP = temp;
-
-       mac_addr_set = 1;
-}
-
-static unsigned char * plb2800_get_mac_addr(void)
-{
-       static unsigned char addr[6];
-       char *tmp, *end;
-       int i;
-
-       tmp = getenv ("ethaddr");
-       if (NULL == tmp) return NULL;
-
-       for (i=0; i<6; i++) {
-               addr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
-               if (tmp)
-                       tmp = (*end) ? end+1 : end;
-       }
-
-       return addr;
-}
-
-#endif /* CONFIG_PLB2800_ETHER */
diff --git a/drivers/ps2mult.c b/drivers/ps2mult.c
deleted file mode 100644 (file)
index 9515a0f..0000000
+++ /dev/null
@@ -1,466 +0,0 @@
-/***********************************************************************
- *
- * (C) Copyright 2004
- * DENX Software Engineering
- * Wolfgang Denk, wd@denx.de
- * All rights reserved.
- *
- * PS/2 multiplexer driver
- *
- * Originally from linux source (drivers/char/ps2mult.c)
- *
- * Uses simple serial driver (ps2ser.c) to access the multiplexer
- * Used by PS/2 keyboard driver (pc_keyb.c)
- *
- ***********************************************************************/
-
-#include <common.h>
-
-#ifdef CONFIG_PS2MULT
-
-#include <pc_keyb.h>
-#include <asm/atomic.h>
-#include <ps2mult.h>
-
-/* #define DEBUG_MULT */
-/* #define DEBUG_KEYB */
-
-#define KBD_STAT_DEFAULT               (KBD_STAT_SELFTEST | KBD_STAT_UNLOCKED)
-
-#define PRINTF(format, args...)                printf("ps2mult.c: " format, ## args)
-
-#ifdef DEBUG_MULT
-#define PRINTF_MULT(format, args...)   printf("PS2MULT: " format, ## args)
-#else
-#define PRINTF_MULT(format, args...)
-#endif
-
-#ifdef DEBUG_KEYB
-#define PRINTF_KEYB(format, args...)   printf("KEYB: " format, ## args)
-#else
-#define PRINTF_KEYB(format, args...)
-#endif
-
-
-static ulong start_time;
-static int init_done = 0;
-
-static int received_escape = 0;
-static int received_bsync = 0;
-static int received_selector = 0;
-
-static int kbd_command_active = 0;
-static int mouse_command_active = 0;
-static int ctl_command_active = 0;
-
-static u_char command_byte = 0;
-
-static void (*keyb_handler)(void *dev_id);
-
-static u_char ps2mult_buf [PS2BUF_SIZE];
-static atomic_t ps2mult_buf_cnt;
-static int ps2mult_buf_in_idx;
-static int ps2mult_buf_out_idx;
-
-static u_char ps2mult_buf_status [PS2BUF_SIZE];
-
-#ifndef CONFIG_BOARD_EARLY_INIT_R
-#error #define CONFIG_BOARD_EARLY_INIT_R and call ps2mult_early_init() in board_early_init_r()
-#endif
-void ps2mult_early_init (void)
-{
-       start_time = get_timer(0);
-}
-
-static void ps2mult_send_byte(u_char byte, u_char sel)
-{
-       ps2ser_putc(sel);
-
-       if (sel == PS2MULT_KB_SELECTOR) {
-               PRINTF_MULT("0x%02x send KEYBOARD\n", byte);
-               kbd_command_active = 1;
-       } else {
-               PRINTF_MULT("0x%02x send MOUSE\n", byte);
-               mouse_command_active = 1;
-       }
-
-       switch (byte) {
-       case PS2MULT_ESCAPE:
-       case PS2MULT_BSYNC:
-       case PS2MULT_KB_SELECTOR:
-       case PS2MULT_MS_SELECTOR:
-       case PS2MULT_SESSION_START:
-       case PS2MULT_SESSION_END:
-               ps2ser_putc(PS2MULT_ESCAPE);
-               break;
-       default:
-               break;
-       }
-
-       ps2ser_putc(byte);
-}
-
-static void ps2mult_receive_byte(u_char byte, u_char sel)
-{
-       u_char status = KBD_STAT_DEFAULT;
-
-#if 1 /* Ignore mouse in U-Boot */
-       if (sel == PS2MULT_MS_SELECTOR) return;
-#endif
-
-       if (sel == PS2MULT_KB_SELECTOR) {
-               if (kbd_command_active) {
-                       if (!received_bsync) {
-                               PRINTF_MULT("0x%02x lost KEYBOARD !!!\n", byte);
-                               return;
-                       } else {
-                               kbd_command_active = 0;
-                               received_bsync = 0;
-                       }
-               }
-               PRINTF_MULT("0x%02x receive KEYBOARD\n", byte);
-               status |= KBD_STAT_IBF | KBD_STAT_OBF;
-       } else {
-               if (mouse_command_active) {
-                       if (!received_bsync) {
-                               PRINTF_MULT("0x%02x lost MOUSE !!!\n", byte);
-                               return;
-                       } else {
-                               mouse_command_active = 0;
-                               received_bsync = 0;
-                       }
-               }
-               PRINTF_MULT("0x%02x receive MOUSE\n", byte);
-               status |= KBD_STAT_IBF | KBD_STAT_OBF | KBD_STAT_MOUSE_OBF;
-       }
-
-       if (atomic_read(&ps2mult_buf_cnt) < PS2BUF_SIZE) {
-               ps2mult_buf_status[ps2mult_buf_in_idx] = status;
-               ps2mult_buf[ps2mult_buf_in_idx++] = byte;
-               ps2mult_buf_in_idx &= (PS2BUF_SIZE - 1);
-               atomic_inc(&ps2mult_buf_cnt);
-       } else {
-               PRINTF("buffer overflow\n");
-       }
-
-       if (received_bsync) {
-               PRINTF("unexpected BSYNC\n");
-               received_bsync = 0;
-       }
-}
-
-void ps2mult_callback (int in_cnt)
-{
-       int i;
-       u_char byte;
-       static int keyb_handler_active = 0;
-
-       if (!init_done) {
-               return;
-       }
-
-       for (i = 0; i < in_cnt; i ++) {
-               byte = ps2ser_getc();
-
-               if (received_escape) {
-                       ps2mult_receive_byte(byte, received_selector);
-                       received_escape = 0;
-               } else switch (byte) {
-               case PS2MULT_ESCAPE:
-                       PRINTF_MULT("ESCAPE receive\n");
-                       received_escape = 1;
-                       break;
-
-               case PS2MULT_BSYNC:
-                       PRINTF_MULT("BSYNC receive\n");
-                       received_bsync = 1;
-                       break;
-
-               case PS2MULT_KB_SELECTOR:
-               case PS2MULT_MS_SELECTOR:
-                       PRINTF_MULT("%s receive\n",
-                           byte == PS2MULT_KB_SELECTOR ? "KB_SEL" : "MS_SEL");
-                       received_selector = byte;
-                       break;
-
-               case PS2MULT_SESSION_START:
-               case PS2MULT_SESSION_END:
-                       PRINTF_MULT("%s receive\n",
-                           byte == PS2MULT_SESSION_START ?
-                           "SESSION_START" : "SESSION_END");
-                       break;
-
-               default:
-                       ps2mult_receive_byte(byte, received_selector);
-               }
-       }
-
-       if (keyb_handler && !keyb_handler_active &&
-           atomic_read(&ps2mult_buf_cnt)) {
-               keyb_handler_active = 1;
-               keyb_handler(NULL);
-               keyb_handler_active = 0;
-       }
-}
-
-u_char ps2mult_read_status(void)
-{
-       u_char byte;
-
-       if (atomic_read(&ps2mult_buf_cnt) == 0) {
-               ps2ser_check();
-       }
-
-       if (atomic_read(&ps2mult_buf_cnt)) {
-               byte = ps2mult_buf_status[ps2mult_buf_out_idx];
-       } else {
-               byte = KBD_STAT_DEFAULT;
-       }
-       PRINTF_KEYB("read_status()=0x%02x\n", byte);
-       return byte;
-}
-
-u_char ps2mult_read_input(void)
-{
-       u_char byte = 0;
-
-       if (atomic_read(&ps2mult_buf_cnt) == 0) {
-               ps2ser_check();
-       }
-
-       if (atomic_read(&ps2mult_buf_cnt)) {
-               byte = ps2mult_buf[ps2mult_buf_out_idx++];
-               ps2mult_buf_out_idx &= (PS2BUF_SIZE - 1);
-               atomic_dec(&ps2mult_buf_cnt);
-       }
-       PRINTF_KEYB("read_input()=0x%02x\n", byte);
-       return byte;
-}
-
-void ps2mult_write_output(u_char val)
-{
-       int i;
-
-       PRINTF_KEYB("write_output(0x%02x)\n", val);
-
-       for (i = 0; i < KBD_TIMEOUT; i++) {
-               if (!kbd_command_active && !mouse_command_active) {
-                       break;
-               }
-               udelay(1000);
-               ps2ser_check();
-       }
-
-       if (kbd_command_active) {
-               PRINTF("keyboard command not acknoledged\n");
-               kbd_command_active = 0;
-       }
-
-       if (mouse_command_active) {
-               PRINTF("mouse command not acknoledged\n");
-               mouse_command_active = 0;
-       }
-
-       if (ctl_command_active) {
-               switch (ctl_command_active) {
-               case KBD_CCMD_WRITE_MODE:
-                         /* Scan code conversion not supported */
-                       command_byte = val & ~KBD_MODE_KCC;
-                       break;
-
-               case KBD_CCMD_WRITE_AUX_OBUF:
-                       ps2mult_receive_byte(val, PS2MULT_MS_SELECTOR);
-                       break;
-
-               case KBD_CCMD_WRITE_MOUSE:
-                       ps2mult_send_byte(val, PS2MULT_MS_SELECTOR);
-                       break;
-
-               default:
-                       PRINTF("invalid controller command\n");
-                       break;
-               }
-
-               ctl_command_active = 0;
-               return;
-       }
-
-       ps2mult_send_byte(val, PS2MULT_KB_SELECTOR);
-}
-
-void ps2mult_write_command(u_char val)
-{
-       ctl_command_active = 0;
-
-       PRINTF_KEYB("write_command(0x%02x)\n", val);
-
-       switch (val) {
-       case KBD_CCMD_READ_MODE:
-               ps2mult_receive_byte(command_byte, PS2MULT_KB_SELECTOR);
-               break;
-
-       case KBD_CCMD_WRITE_MODE:
-               ctl_command_active = val;
-               break;
-
-       case KBD_CCMD_MOUSE_DISABLE:
-               break;
-
-       case KBD_CCMD_MOUSE_ENABLE:
-               break;
-
-       case KBD_CCMD_SELF_TEST:
-               ps2mult_receive_byte(0x55, PS2MULT_KB_SELECTOR);
-               break;
-
-       case KBD_CCMD_KBD_TEST:
-               ps2mult_receive_byte(0x00, PS2MULT_KB_SELECTOR);
-               break;
-
-       case KBD_CCMD_KBD_DISABLE:
-               break;
-
-       case KBD_CCMD_KBD_ENABLE:
-               break;
-
-       case KBD_CCMD_WRITE_AUX_OBUF:
-               ctl_command_active = val;
-               break;
-
-       case KBD_CCMD_WRITE_MOUSE:
-               ctl_command_active = val;
-               break;
-
-       default:
-               PRINTF("invalid controller command\n");
-               break;
-       }
-}
-
-static int ps2mult_getc_w (void)
-{
-       int res = -1;
-       int i;
-
-       for (i = 0; i < KBD_TIMEOUT; i++) {
-               if (ps2ser_check()) {
-                       res = ps2ser_getc();
-                       break;
-               }
-               udelay(1000);
-       }
-
-       switch (res) {
-       case PS2MULT_KB_SELECTOR:
-       case PS2MULT_MS_SELECTOR:
-               received_selector = res;
-               break;
-       default:
-               break;
-       }
-
-       return res;
-}
-
-int ps2mult_init (void)
-{
-       int byte;
-       int kbd_found = 0;
-       int mouse_found = 0;
-
-       while (get_timer(start_time) < CONFIG_PS2MULT_DELAY);
-
-       ps2ser_init();
-
-       ps2ser_putc(PS2MULT_SESSION_START);
-
-       ps2ser_putc(PS2MULT_KB_SELECTOR);
-       ps2ser_putc(KBD_CMD_RESET);
-
-       do {
-               byte = ps2mult_getc_w();
-       } while (byte >= 0 && byte != KBD_REPLY_ACK);
-
-       if (byte == KBD_REPLY_ACK) {
-               byte = ps2mult_getc_w();
-               if (byte == 0xaa) {
-                       kbd_found = 1;
-                       puts("keyboard");
-               }
-       }
-
-       if (!kbd_found) {
-               while (byte >= 0) {
-                       byte = ps2mult_getc_w();
-               }
-       }
-
-#if 1 /* detect mouse */
-       ps2ser_putc(PS2MULT_MS_SELECTOR);
-       ps2ser_putc(AUX_RESET);
-
-       do {
-               byte = ps2mult_getc_w();
-       } while (byte >= 0 && byte != AUX_ACK);
-
-       if (byte == AUX_ACK) {
-               byte = ps2mult_getc_w();
-               if (byte == 0xaa) {
-                       byte = ps2mult_getc_w();
-                       if (byte == 0x00) {
-                               mouse_found = 1;
-                               puts(", mouse");
-                       }
-               }
-       }
-
-       if (!mouse_found) {
-               while (byte >= 0) {
-                       byte = ps2mult_getc_w();
-               }
-       }
-#endif
-
-       if (mouse_found || kbd_found) {
-               if (!received_selector) {
-                       if (mouse_found) {
-                               received_selector = PS2MULT_MS_SELECTOR;
-                       } else {
-                               received_selector = PS2MULT_KB_SELECTOR;
-                       }
-               }
-
-               init_done = 1;
-       } else {
-               puts("No device found");
-       }
-
-       puts("\n");
-
-#if 0 /* for testing */
-       {
-               int i;
-               u_char key[] = {
-                       0x1f, 0x12, 0x14, 0x12, 0x31, 0x2f, 0x39,       /* setenv */
-                       0x1f, 0x14, 0x20, 0x17, 0x31, 0x39,             /* stdin */
-                       0x1f, 0x12, 0x13, 0x17, 0x1e, 0x26, 0x1c,       /* serial */
-               };
-
-               for (i = 0; i < sizeof (key); i++) {
-                       ps2mult_receive_byte (key[i],        PS2MULT_KB_SELECTOR);
-                       ps2mult_receive_byte (key[i] | 0x80, PS2MULT_KB_SELECTOR);
-               }
-       }
-#endif
-
-       return init_done ? 0 : -1;
-}
-
-int ps2mult_request_irq(void (*handler)(void *))
-{
-       keyb_handler = handler;
-
-       return 0;
-}
-
-#endif /* CONFIG_PS2MULT */
diff --git a/drivers/ps2ser.c b/drivers/ps2ser.c
deleted file mode 100644 (file)
index 4e304f7..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-/***********************************************************************
- *
- * (C) Copyright 2004
- * DENX Software Engineering
- * Wolfgang Denk, wd@denx.de
- * All rights reserved.
- *
- * Simple 16550A serial driver
- *
- * Originally from linux source (drivers/char/ps2ser.c)
- *
- * Used by the PS/2 multiplexer driver (ps2mult.c)
- *
- ***********************************************************************/
-
-#include <common.h>
-
-#ifdef CONFIG_PS2SERIAL
-
-#include <asm/io.h>
-#include <asm/atomic.h>
-#include <ps2mult.h>
-#if defined(CFG_NS16550) || defined(CONFIG_MPC85xx)
-#include <ns16550.h>
-#endif
-
-DECLARE_GLOBAL_DATA_PTR;
-
-/* #define     DEBUG */
-
-#define PS2SER_BAUD    57600
-
-#ifdef CONFIG_MPC5xxx
-#if CONFIG_PS2SERIAL == 1
-#define PSC_BASE MPC5XXX_PSC1
-#elif CONFIG_PS2SERIAL == 2
-#define PSC_BASE MPC5XXX_PSC2
-#elif CONFIG_PS2SERIAL == 3
-#define PSC_BASE MPC5XXX_PSC3
-#elif defined(CONFIG_MGT5100)
-#error CONFIG_PS2SERIAL must be in 1, 2 or 3
-#elif CONFIG_PS2SERIAL == 4
-#define PSC_BASE MPC5XXX_PSC4
-#elif CONFIG_PS2SERIAL == 5
-#define PSC_BASE MPC5XXX_PSC5
-#elif CONFIG_PS2SERIAL == 6
-#define PSC_BASE MPC5XXX_PSC6
-#else
-#error CONFIG_PS2SERIAL must be in 1 ... 6
-#endif
-
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
-
-#if CONFIG_PS2SERIAL == 1
-#define COM_BASE (CFG_CCSRBAR+0x4500)
-#elif CONFIG_PS2SERIAL == 2
-#define COM_BASE (CFG_CCSRBAR+0x4600)
-#else
-#error CONFIG_PS2SERIAL must be in 1 ... 2
-#endif
-
-#endif /* CONFIG_MPC5xxx / CONFIG_MPC8540 / other */
-
-static int     ps2ser_getc_hw(void);
-static void    ps2ser_interrupt(void *dev_id);
-
-extern struct  serial_state rs_table[]; /* in serial.c */
-#if !defined(CONFIG_MPC5xxx) && !defined(CONFIG_MPC8540) && !defined(CONFIG_MPC8541) && !defined(CONFIG_MPC8555)
-static struct  serial_state *state;
-#endif
-
-static u_char  ps2buf[PS2BUF_SIZE];
-static atomic_t        ps2buf_cnt;
-static int     ps2buf_in_idx;
-static int     ps2buf_out_idx;
-
-#ifdef CONFIG_MPC5xxx
-int ps2ser_init(void)
-{
-       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
-       unsigned long baseclk;
-       int div;
-
-       /* reset PSC */
-       psc->command = PSC_SEL_MODE_REG_1;
-
-       /* select clock sources */
-#if defined(CONFIG_MGT5100)
-       psc->psc_clock_select = 0xdd00;
-       baseclk = (CFG_MPC5XXX_CLKIN + 16) / 32;
-#elif defined(CONFIG_MPC5200)
-       psc->psc_clock_select = 0;
-       baseclk = (gd->ipb_clk + 16) / 32;
-#endif
-
-       /* switch to UART mode */
-       psc->sicr = 0;
-
-       /* configure parity, bit length and so on */
-#if defined(CONFIG_MGT5100)
-       psc->mode = PSC_MODE_ERR | PSC_MODE_8_BITS | PSC_MODE_PARNONE;
-#elif defined(CONFIG_MPC5200)
-       psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE;
-#endif
-       psc->mode = PSC_MODE_ONE_STOP;
-
-       /* set up UART divisor */
-       div = (baseclk + (PS2SER_BAUD/2)) / PS2SER_BAUD;
-       psc->ctur = (div >> 8) & 0xff;
-       psc->ctlr = div & 0xff;
-
-       /* disable all interrupts */
-       psc->psc_imr = 0;
-
-       /* reset and enable Rx/Tx */
-       psc->command = PSC_RST_RX;
-       psc->command = PSC_RST_TX;
-       psc->command = PSC_RX_ENABLE | PSC_TX_ENABLE;
-
-       return (0);
-}
-
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
-int ps2ser_init(void)
-{
-       NS16550_t com_port = (NS16550_t)COM_BASE;
-
-       com_port->ier = 0x00;
-       com_port->lcr = LCR_BKSE | LCR_8N1;
-       com_port->dll = (CFG_NS16550_CLK / 16 / PS2SER_BAUD) & 0xff;
-       com_port->dlm = ((CFG_NS16550_CLK / 16 / PS2SER_BAUD) >> 8) & 0xff;
-       com_port->lcr = LCR_8N1;
-       com_port->mcr = (MCR_DTR | MCR_RTS);
-       com_port->fcr = (FCR_FIFO_EN | FCR_RXSR | FCR_TXSR);
-
-       return (0);
-}
-
-#else /* !CONFIG_MPC5xxx && !CONFIG_MPC8540 / other */
-
-static inline unsigned int ps2ser_in(int offset)
-{
-       return readb((unsigned long) state->iomem_base + offset);
-}
-
-static inline void ps2ser_out(int offset, int value)
-{
-       writeb(value, (unsigned long) state->iomem_base + offset);
-}
-
-int ps2ser_init(void)
-{
-       int quot;
-       unsigned cval;
-
-       state = rs_table + CONFIG_PS2SERIAL;
-
-       quot = state->baud_base / PS2SER_BAUD;
-       cval = 0x3; /* 8N1 - 8 data bits, no parity bits, 1 stop bit */
-
-         /* Set speed, enable interrupts, enable FIFO
-          */
-       ps2ser_out(UART_LCR, cval | UART_LCR_DLAB);
-       ps2ser_out(UART_DLL, quot & 0xff);
-       ps2ser_out(UART_DLM, quot >> 8);
-       ps2ser_out(UART_LCR, cval);
-       ps2ser_out(UART_IER, UART_IER_RDI);
-       ps2ser_out(UART_MCR, UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS);
-       ps2ser_out(UART_FCR,
-           UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
-
-       /* If we read 0xff from the LSR, there is no UART here
-        */
-       if (ps2ser_in(UART_LSR) == 0xff) {
-               printf ("ps2ser.c: no UART found\n");
-               return -1;
-       }
-
-       irq_install_handler(state->irq, ps2ser_interrupt, NULL);
-
-       return 0;
-}
-#endif /* CONFIG_MPC5xxx / CONFIG_MPC8540 / other */
-
-void ps2ser_putc(int chr)
-{
-#ifdef CONFIG_MPC5xxx
-       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
-       NS16550_t com_port = (NS16550_t)COM_BASE;
-#endif
-#ifdef DEBUG
-       printf(">>>> 0x%02x\n", chr);
-#endif
-
-#ifdef CONFIG_MPC5xxx
-       while (!(psc->psc_status & PSC_SR_TXRDY));
-
-       psc->psc_buffer_8 = chr;
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
-       while ((com_port->lsr & LSR_THRE) == 0);
-       com_port->thr = chr;
-#else
-       while (!(ps2ser_in(UART_LSR) & UART_LSR_THRE));
-
-       ps2ser_out(UART_TX, chr);
-#endif
-}
-
-static int ps2ser_getc_hw(void)
-{
-#ifdef CONFIG_MPC5xxx
-       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
-       NS16550_t com_port = (NS16550_t)COM_BASE;
-#endif
-       int res = -1;
-
-#ifdef CONFIG_MPC5xxx
-       if (psc->psc_status & PSC_SR_RXRDY) {
-               res = (psc->psc_buffer_8);
-       }
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
-       if (com_port->lsr & LSR_DR) {
-               res = com_port->rbr;
-       }
-#else
-       if (ps2ser_in(UART_LSR) & UART_LSR_DR) {
-               res = (ps2ser_in(UART_RX));
-       }
-#endif
-
-       return res;
-}
-
-int ps2ser_getc(void)
-{
-       volatile int chr;
-       int flags;
-
-#ifdef DEBUG
-       printf("<< ");
-#endif
-
-       flags = disable_interrupts();
-
-       do {
-               if (atomic_read(&ps2buf_cnt) != 0) {
-                       chr = ps2buf[ps2buf_out_idx++];
-                       ps2buf_out_idx &= (PS2BUF_SIZE - 1);
-                       atomic_dec(&ps2buf_cnt);
-               } else {
-                       chr = ps2ser_getc_hw();
-               }
-       }
-       while (chr < 0);
-
-       if (flags) enable_interrupts();
-
-#ifdef DEBUG
-       printf("0x%02x\n", chr);
-#endif
-
-       return chr;
-}
-
-int ps2ser_check(void)
-{
-       int flags;
-
-       flags = disable_interrupts();
-       ps2ser_interrupt(NULL);
-       if (flags) enable_interrupts();
-
-       return atomic_read(&ps2buf_cnt);
-}
-
-static void ps2ser_interrupt(void *dev_id)
-{
-#ifdef CONFIG_MPC5xxx
-       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
-       NS16550_t com_port = (NS16550_t)COM_BASE;
-#endif
-       int chr;
-       int status;
-
-       do {
-               chr = ps2ser_getc_hw();
-#ifdef CONFIG_MPC5xxx
-               status = psc->psc_status;
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
-               status = com_port->lsr;
-#else
-               status = ps2ser_in(UART_IIR);
-#endif
-               if (chr < 0) continue;
-
-               if (atomic_read(&ps2buf_cnt) < PS2BUF_SIZE) {
-                       ps2buf[ps2buf_in_idx++] = chr;
-                       ps2buf_in_idx &= (PS2BUF_SIZE - 1);
-                       atomic_inc(&ps2buf_cnt);
-               } else {
-                       printf ("ps2ser.c: buffer overflow\n");
-               }
-#ifdef CONFIG_MPC5xxx
-       } while (status & PSC_SR_RXRDY);
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
-       } while (status & LSR_DR);
-#else
-       } while (status & UART_IIR_RDI);
-#endif
-
-       if (atomic_read(&ps2buf_cnt)) {
-               ps2mult_callback(atomic_read(&ps2buf_cnt));
-       }
-}
-
-#endif /* CONFIG_PS2SERIAL */
diff --git a/drivers/pxa_pcmcia.c b/drivers/pxa_pcmcia.c
deleted file mode 100644 (file)
index 6020e46..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-#include <common.h>
-#include <config.h>
-
-#ifdef CONFIG_PXA_PCMCIA
-
-#include <pcmcia.h>
-#include <asm/arch/pxa-regs.h>
-#include <asm/io.h>
-
-static inline void msWait(unsigned msVal)
-{
-       udelay(msVal*1000);
-}
-
-int pcmcia_on (void)
-{
-       unsigned int reg_arr[] = {
-               0x48000028, CFG_MCMEM0_VAL,
-               0x4800002c, CFG_MCMEM1_VAL,
-               0x48000030, CFG_MCATT0_VAL,
-               0x48000034, CFG_MCATT1_VAL,
-               0x48000038, CFG_MCIO0_VAL,
-               0x4800003c, CFG_MCIO1_VAL,
-
-               0, 0
-       };
-       int i, rc;
-
-#ifdef CONFIG_EXADRON1
-       int cardDetect;
-       volatile unsigned int *v_pBCRReg =
-                       (volatile unsigned int *) 0x08000000;
-#endif
-
-       debug ("%s\n", __FUNCTION__);
-
-       i = 0;
-       while (reg_arr[i])
-               *((volatile unsigned int *) reg_arr[i++]) |= reg_arr[i++];
-       udelay (1000);
-
-       debug ("%s: programmed mem controller \n", __FUNCTION__);
-
-#ifdef CONFIG_EXADRON1
-
-/*define useful BCR masks */
-#define BCR_CF_INIT_VAL                    0x00007230
-#define BCR_CF_PWRON_BUSOFF_RESETOFF_VAL    0x00007231
-#define BCR_CF_PWRON_BUSOFF_RESETON_VAL     0x00007233
-#define BCR_CF_PWRON_BUSON_RESETON_VAL      0x00007213
-#define BCR_CF_PWRON_BUSON_RESETOFF_VAL     0x00007211
-
-       /* we see from the GPIO bit if the card is present */
-       cardDetect = !(GPLR0 & GPIO_bit (14));
-
-       if (cardDetect) {
-               printf ("No PCMCIA card found!\n");
-       }
-
-       /* reset the card via the BCR line */
-       *v_pBCRReg = (unsigned) BCR_CF_INIT_VAL;
-       msWait (500);
-
-       *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETOFF_VAL;
-       msWait (500);
-
-       *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETON_VAL;
-       msWait (500);
-
-       *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETON_VAL;
-       msWait (500);
-
-       *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETOFF_VAL;
-       msWait (1500);
-
-       /* enable address bus */
-       GPCR1 = 0x01;
-       /* and the first CF slot */
-       MECR = 0x00000002;
-
-#endif /* EXADRON 1 */
-
-       rc = check_ide_device (0);      /* use just slot 0 */
-
-       return rc;
-}
-
-#if defined(CONFIG_CMD_PCMCIA)
-int pcmcia_off (void)
-{
-       return 0;
-}
-#endif
-
-#endif /* CONFIG_PXA_PCMCIA */
diff --git a/drivers/rpx_pcmcia.c b/drivers/rpx_pcmcia.c
deleted file mode 100644 (file)
index c7c425b..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -------------------------------------------------------------------- */
-/* RPX Boards from Embedded Planet                                     */
-/* -------------------------------------------------------------------- */
-#include <common.h>
-#ifdef CONFIG_8xx
-#include <mpc8xx.h>
-#endif
-#include <pcmcia.h>
-
-#undef CONFIG_PCMCIA
-
-#if defined(CONFIG_CMD_PCMCIA)
-#define        CONFIG_PCMCIA
-#endif
-
-#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
-#define        CONFIG_PCMCIA
-#endif
-
-#if    defined(CONFIG_PCMCIA)  \
-       && (defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE))
-
-#define        PCMCIA_BOARD_MSG        "RPX CLASSIC or RPX LITE"
-
-int pcmcia_voltage_set(int slot, int vcc, int vpp)
-{
-       u_long reg = 0;
-
-       switch(vcc) {
-               case 0: break;
-               case 33: reg |= BCSR1_PCVCTL4; break;
-               case 50: reg |= BCSR1_PCVCTL5; break;
-               default: return 1;
-       }
-
-       switch(vpp) {
-               case 0: break;
-               case 33:
-               case 50:
-                       if(vcc == vpp)
-                               reg |= BCSR1_PCVCTL6;
-                       else
-                               return 1;
-                       break;
-               case 120:
-                       reg |= BCSR1_PCVCTL7;
-                       default: return 1;
-       }
-
-       /* first, turn off all power */
-       *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
-                       | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
-
-       /* enable new powersettings */
-       *((uint *)RPX_CSR_ADDR) |= reg;
-
-       return 0;
-}
-
-int pcmcia_hardware_enable (int slot)
-{
-       return 0;       /* No hardware to enable */
-}
-
-#if defined(CONFIG_CMD_PCMCIA)
-static int pcmcia_hardware_disable(int slot)
-{
-       return 0;       /* No hardware to disable */
-}
-#endif
-
-
-#endif /* CONFIG_PCMCIA && (CONFIG_RPXCLASSIC || CONFIG_RPXLITE) */
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
new file mode 100644 (file)
index 0000000..1d6016e
--- /dev/null
@@ -0,0 +1,71 @@
+#
+# (C) Copyright 2001-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+#CFLAGS += -DDEBUG
+
+LIB    = $(obj)librtc.a
+
+COBJS-y += date.o
+COBJS-y += bf5xx_rtc.o
+COBJS-y += ds12887.o
+COBJS-y += ds1302.o
+COBJS-y += ds1306.o
+COBJS-y += ds1307.o
+COBJS-y += ds1337.o
+COBJS-y += ds1374.o
+COBJS-y += ds1556.o
+COBJS-y += ds164x.o
+COBJS-y += ds174x.o
+COBJS-y += ds3231.o
+COBJS-y += m41t11.o
+COBJS-y += max6900.o
+COBJS-y += m48t35ax.o
+COBJS-y += mc146818.o
+COBJS-y += mk48t59.o
+COBJS-y += mpc5xxx.o
+COBJS-y += mpc8xx.o
+COBJS-y += pcf8563.o
+COBJS-y += s3c24x0_rtc.o
+COBJS-y += rs5c372.o
+COBJS-y += mcfrtc.o
+COBJS-y += x1205.o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/rtc/bf5xx_rtc.c b/drivers/rtc/bf5xx_rtc.c
new file mode 100644 (file)
index 0000000..8856bb9
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ * Real Time Clock interface of ADI21535 (Blackfin) for uCLinux
+ *
+ * Copyright (C) 2003 Motorola Corporation.  All rights reserved.
+ *                             Richard Xiao (A2590C@email.mot.com)
+ *
+ * Copyright (C) 1996 Paul Gortmaker
+ *
+ *
+ *     Based on other minimal char device drivers, like Alan's
+ *     watchdog, Ted's random, etc. etc.
+ *
+ *     1.07    Paul Gortmaker.
+ *     1.08    Miquel van Smoorenburg: disallow certain things on the
+ *             DEC Alpha as the CMOS clock is also used for other things.
+ *     1.09    Nikita Schmidt: epoch support and some Alpha cleanup.
+ *     1.09a   Pete Zaitcev: Sun SPARC
+ *     1.09b   Jeff Garzik: Modularize, init cleanup
+ *     1.09c   Jeff Garzik: SMP cleanup
+ *     1.10    Paul Barton-Davis: add support for async I/O
+ *     1.10a   Andrea Arcangeli: Alpha updates
+ *     1.10b   Andrew Morton: SMP lock fix
+ *     1.10c   Cesar Barros: SMP locking fixes and cleanup
+ *     1.10d   Paul Gortmaker: delete paranoia check in rtc_exit
+ *     1.10e   LG Soft India: Register access is different in BF533.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_RTC_BFIN) && defined(CONFIG_CMD_DATE)
+
+#include <asm/blackfin.h>
+#include <asm/arch/bf5xx_rtc.h>
+
+void rtc_reset(void)
+{
+       return;                 /* nothing to do */
+}
+
+/* Wait for pending writes to complete */
+void wait_for_complete(void)
+{
+       while (!(*(volatile unsigned short *)RTC_ISTAT & 0x8000)) {
+               printf("");
+       }
+       *(volatile unsigned short *)RTC_ISTAT = 0x8000;
+}
+
+/* Enable the RTC prescaler enable register */
+void rtc_init()
+{
+       *(volatile unsigned short *)RTC_PREN = 0x1;
+       wait_for_complete();
+}
+
+/* Set the time. Get the time_in_secs which is the number of seconds since Jan 1970 and set the RTC registers
+ * based on this value.
+ */
+void rtc_set(struct rtc_time *tmp)
+{
+       unsigned long n_days_1970 = 0;
+       unsigned long n_secs_rem = 0;
+       unsigned long n_hrs = 0;
+       unsigned long n_mins = 0;
+       unsigned long n_secs = 0;
+       unsigned long time_in_secs;
+
+       if (tmp == NULL) {
+               printf("Error setting the date/time \n");
+               return;
+       }
+
+       time_in_secs =
+           mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_hour,
+                  tmp->tm_min, tmp->tm_sec);
+
+       /* Compute no. of days since 1970 */
+       n_days_1970 = (unsigned long)(time_in_secs / (NUM_SECS_IN_DAY));
+
+       /* From the remining secs, compute the hrs(0-23), mins(0-59) and secs(0-59) */
+       n_secs_rem = (unsigned long)(time_in_secs % (NUM_SECS_IN_DAY));
+       n_hrs = n_secs_rem / (NUM_SECS_IN_HOUR);
+       n_secs_rem = n_secs_rem % (NUM_SECS_IN_HOUR);
+       n_mins = n_secs_rem / (NUM_SECS_IN_MIN);
+       n_secs = n_secs_rem % (NUM_SECS_IN_MIN);
+
+       /* Store the new time in the RTC_STAT register */
+       *(volatile unsigned long *)RTC_STAT =
+           ((n_days_1970 << DAY_BITS_OFF) | (n_hrs << HOUR_BITS_OFF) |
+            (n_mins << MIN_BITS_OFF) | (n_secs << SEC_BITS_OFF));
+
+       wait_for_complete();
+}
+
+/* Read the time from the RTC_STAT. time_in_seconds is seconds since Jan 1970 */
+void rtc_get(struct rtc_time *tmp)
+{
+       unsigned long cur_rtc_stat = 0;
+       unsigned long time_in_sec;
+       unsigned long tm_sec = 0, tm_min = 0, tm_hour = 0, tm_day = 0;
+
+       if (tmp == NULL) {
+               printf("Error getting the date/time \n");
+               return;
+       }
+
+       /* Read the RTC_STAT register */
+       cur_rtc_stat = *(volatile unsigned long *)RTC_STAT;
+
+       /* Get the secs (0-59), mins (0-59), hrs (0-23) and the days since Jan 1970 */
+       tm_sec = (cur_rtc_stat >> SEC_BITS_OFF) & 0x3f;
+       tm_min = (cur_rtc_stat >> MIN_BITS_OFF) & 0x3f;
+       tm_hour = (cur_rtc_stat >> HOUR_BITS_OFF) & 0x1f;
+       tm_day = (cur_rtc_stat >> DAY_BITS_OFF) & 0x7fff;
+
+       /* Calculate the total number of seconds since Jan 1970 */
+       time_in_sec = (tm_sec) +
+           MIN_TO_SECS(tm_min) + HRS_TO_SECS(tm_hour) + DAYS_TO_SECS(tm_day);
+       to_tm(time_in_sec, tmp);
+}
+#endif
diff --git a/drivers/rtc/date.c b/drivers/rtc/date.c
new file mode 100644 (file)
index 0000000..a83a723
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support for Philips PCF8563 RTC
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_CMD_DATE) || defined(CONFIG_TIMESTAMP)
+
+#define FEBRUARY               2
+#define        STARTOFTIME             1970
+#define SECDAY                 86400L
+#define SECYR                  (SECDAY * 365)
+#define        leapyear(year)          ((year) % 4 == 0)
+#define        days_in_year(a)         (leapyear(a) ? 366 : 365)
+#define        days_in_month(a)        (month_days[(a) - 1])
+
+static int month_days[12] = {
+       31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+/*
+ * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
+ */
+void GregorianDay(struct rtc_time * tm)
+{
+       int leapsToDate;
+       int lastYear;
+       int day;
+       int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };
+
+       lastYear=tm->tm_year-1;
+
+       /*
+        * Number of leap corrections to apply up to end of last year
+        */
+       leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
+
+       /*
+        * This year is a leap year if it is divisible by 4 except when it is
+        * divisible by 100 unless it is divisible by 400
+        *
+        * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
+        */
+       if((tm->tm_year%4==0) &&
+          ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
+          (tm->tm_mon>2)) {
+               /*
+                * We are past Feb. 29 in a leap year
+                */
+               day=1;
+       } else {
+               day=0;
+       }
+
+       day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + tm->tm_mday;
+
+       tm->tm_wday=day%7;
+}
+
+void to_tm(int tim, struct rtc_time * tm)
+{
+       register int    i;
+       register long   hms, day;
+
+       day = tim / SECDAY;
+       hms = tim % SECDAY;
+
+       /* Hours, minutes, seconds are easy */
+       tm->tm_hour = hms / 3600;
+       tm->tm_min = (hms % 3600) / 60;
+       tm->tm_sec = (hms % 3600) % 60;
+
+       /* Number of years in days */
+       for (i = STARTOFTIME; day >= days_in_year(i); i++) {
+               day -= days_in_year(i);
+       }
+       tm->tm_year = i;
+
+       /* Number of months in days left */
+       if (leapyear(tm->tm_year)) {
+               days_in_month(FEBRUARY) = 29;
+       }
+       for (i = 1; day >= days_in_month(i); i++) {
+               day -= days_in_month(i);
+       }
+       days_in_month(FEBRUARY) = 28;
+       tm->tm_mon = i;
+
+       /* Days are what is left over (+1) from all that. */
+       tm->tm_mday = day + 1;
+
+       /*
+        * Determine the day of week
+        */
+       GregorianDay(tm);
+}
+
+/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+ * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
+ * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
+ *
+ * [For the Julian calendar (which was used in Russia before 1917,
+ * Britain & colonies before 1752, anywhere else before 1582,
+ * and is still in use by some communities) leave out the
+ * -year/100+year/400 terms, and add 10.]
+ *
+ * This algorithm was first published by Gauss (I think).
+ *
+ * WARNING: this function will overflow on 2106-02-07 06:28:16 on
+ * machines were long is 32-bit! (However, as time_t is signed, we
+ * will already get problems at other places on 2038-01-19 03:14:08)
+ */
+unsigned long
+mktime (unsigned int year, unsigned int mon,
+       unsigned int day, unsigned int hour,
+       unsigned int min, unsigned int sec)
+{
+       if (0 >= (int) (mon -= 2)) {    /* 1..12 -> 11,12,1..10 */
+               mon += 12;              /* Puts Feb last since it has leap day */
+               year -= 1;
+       }
+
+       return (((
+               (unsigned long) (year/4 - year/100 + year/400 + 367*mon/12 + day) +
+                       year*365 - 719499
+           )*24 + hour /* now have hours */
+         )*60 + min /* now have minutes */
+       )*60 + sec; /* finally seconds */
+}
+
+#endif
diff --git a/drivers/rtc/ds12887.c b/drivers/rtc/ds12887.c
new file mode 100644 (file)
index 0000000..84fecf0
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * (C) Copyright 2003
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support for the DS12887 RTC
+ */
+
+#undef RTC_DEBUG
+
+#include <common.h>
+#include <command.h>
+#include <config.h>
+#include <rtc.h>
+
+#if defined(CONFIG_RTC_DS12887) && defined(CONFIG_CMD_DATE)
+
+#define RTC_SECONDS                    0x00
+#define RTC_SECONDS_ALARM              0x01
+#define RTC_MINUTES                    0x02
+#define RTC_MINUTES_ALARM              0x03
+#define RTC_HOURS                      0x04
+#define RTC_HOURS_ALARM                0x05
+#define RTC_DAY_OF_WEEK                0x06
+#define RTC_DATE_OF_MONTH              0x07
+#define RTC_MONTH                      0x08
+#define RTC_YEAR                       0x09
+#define RTC_CONTROL_A                  0x0A
+#define RTC_CONTROL_B                  0x0B
+#define RTC_CONTROL_C                  0x0C
+#define RTC_CONTROL_D                  0x0D
+
+#define RTC_CA_UIP                     0x80
+#define RTC_CB_DM                      0x04
+#define RTC_CB_24_12                   0x02
+#define RTC_CB_SET                     0x80
+
+#if defined(CONFIG_ATC)
+
+static uchar rtc_read (uchar reg)
+{
+       uchar val;
+
+       *(volatile unsigned char*)(RTC_PORT_ADDR) = reg;
+       __asm__ __volatile__ ("sync");
+
+       val = *(volatile unsigned char*)(RTC_PORT_DATA);
+       return (val);
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+       *(volatile unsigned char*)(RTC_PORT_ADDR) = reg;
+       __asm__ __volatile__ ("sync");
+
+       *(volatile unsigned char*)(RTC_PORT_DATA) = val;
+       __asm__ __volatile__ ("sync");
+}
+
+#else
+# error Board specific rtc access functions should be supplied
+#endif
+
+static unsigned bcd2bin (uchar n)
+{
+       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+       return (((n / 10) << 4) | (n % 10));
+}
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+       uchar sec, min, hour, mday, wday, mon, year;
+
+       /* check if rtc is available for access */
+       while( rtc_read(RTC_CONTROL_A) & RTC_CA_UIP)
+               ;
+
+       sec  = rtc_read(RTC_SECONDS);
+       min  = rtc_read(RTC_MINUTES);
+       hour = rtc_read(RTC_HOURS);
+       mday = rtc_read(RTC_DATE_OF_MONTH);
+       wday = rtc_read(RTC_DAY_OF_WEEK);
+       mon  = rtc_read(RTC_MONTH);
+       year = rtc_read(RTC_YEAR);
+
+#ifdef RTC_DEBUG
+       printf( "Get RTC year: %d; mon: %d; mday: %d; wday: %d; "
+               "hr: %d; min: %d; sec: %d\n",
+               year, mon, mday, wday, hour, min, sec );
+
+       printf ( "Alarms: hour: %02x min: %02x sec: %02x\n",
+                rtc_read (RTC_HOURS_ALARM),
+                rtc_read (RTC_MINUTES_ALARM),
+                rtc_read (RTC_SECONDS_ALARM) );
+#endif
+
+       if( !(rtc_read(RTC_CONTROL_B) & RTC_CB_DM))
+       {           /* Information is in BCD format */
+printf(" Get: Convert BSD to BIN\n");
+               tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+               tmp->tm_min  = bcd2bin (min  & 0x7F);
+               tmp->tm_hour = bcd2bin (hour & 0x3F);
+               tmp->tm_mday = bcd2bin (mday & 0x3F);
+               tmp->tm_mon  = bcd2bin (mon & 0x1F);
+               tmp->tm_year = bcd2bin (year);
+               tmp->tm_wday = bcd2bin (wday & 0x07);
+       }
+else
+       {
+               tmp->tm_sec  = sec  & 0x7F;
+               tmp->tm_min  = min  & 0x7F;
+               tmp->tm_hour = hour & 0x3F;
+               tmp->tm_mday = mday & 0x3F;
+               tmp->tm_mon  = mon & 0x1F;
+               tmp->tm_year = year;
+               tmp->tm_wday = wday & 0x07;
+       }
+
+
+       if(tmp->tm_year<70)
+               tmp->tm_year+=2000;
+       else
+               tmp->tm_year+=1900;
+
+       tmp->tm_yday = 0;
+       tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+       printf ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+       uchar save_ctrl_b;
+       uchar sec, min, hour, mday, wday, mon, year;
+
+#ifdef RTC_DEBUG
+       printf ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+
+       if( !(rtc_read(RTC_CONTROL_B) & RTC_CB_DM))
+       {           /* Information is in BCD format */
+               year = bin2bcd(tmp->tm_year % 100);
+               mon  = bin2bcd(tmp->tm_mon);
+               wday = bin2bcd(tmp->tm_wday);
+               mday = bin2bcd(tmp->tm_mday);
+               hour = bin2bcd(tmp->tm_hour);
+               min  = bin2bcd(tmp->tm_min);
+               sec  = bin2bcd(tmp->tm_sec);
+       }
+       else
+       {
+               year = tmp->tm_year % 100;
+               mon  = tmp->tm_mon;
+               wday = tmp->tm_wday;
+               mday = tmp->tm_mday;
+               hour = tmp->tm_hour;
+               min  = tmp->tm_min;
+               sec  = tmp->tm_sec;
+       }
+
+       /* disables the RTC to update the regs */
+       save_ctrl_b = rtc_read(RTC_CONTROL_B);
+       save_ctrl_b |= RTC_CB_SET;
+       rtc_write(RTC_CONTROL_B, save_ctrl_b);
+
+       rtc_write (RTC_YEAR, year);
+       rtc_write (RTC_MONTH, mon);
+       rtc_write (RTC_DAY_OF_WEEK, wday);
+       rtc_write (RTC_DATE_OF_MONTH, mday);
+       rtc_write (RTC_HOURS, hour);
+       rtc_write (RTC_MINUTES, min);
+       rtc_write (RTC_SECONDS, sec);
+
+       /* enables the RTC to update the regs */
+       save_ctrl_b &= ~RTC_CB_SET;
+       rtc_write(RTC_CONTROL_B, save_ctrl_b);
+}
+
+void rtc_reset (void)
+{
+       struct rtc_time tmp;
+       uchar ctrl_rg;
+
+       ctrl_rg = RTC_CB_SET;
+       rtc_write(RTC_CONTROL_B,ctrl_rg);
+
+       tmp.tm_year = 1970 % 100;
+       tmp.tm_mon = 1;
+       tmp.tm_mday= 1;
+       tmp.tm_hour = 0;
+       tmp.tm_min = 0;
+       tmp.tm_sec = 0;
+
+#ifdef RTC_DEBUG
+       printf ( "RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC\n",
+                   tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
+                   tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
+#endif
+
+       ctrl_rg = RTC_CB_SET | RTC_CB_24_12 | RTC_CB_DM;
+       rtc_write(RTC_CONTROL_B,ctrl_rg);
+       rtc_set(&tmp);
+
+       rtc_write(RTC_HOURS_ALARM, 0),
+       rtc_write(RTC_MINUTES_ALARM, 0),
+       rtc_write(RTC_SECONDS_ALARM, 0);
+
+       ctrl_rg = RTC_CB_24_12 | RTC_CB_DM;
+       rtc_write(RTC_CONTROL_B,ctrl_rg);
+}
+
+#endif
diff --git a/drivers/rtc/ds1302.c b/drivers/rtc/ds1302.c
new file mode 100644 (file)
index 0000000..55af130
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * ds1302.c - Support for the Dallas Semiconductor DS1302 Timekeeping Chip
+ *
+ * Rex G. Feany <rfeany@zumanetworks.com>
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_RTC_DS1302) && defined(CONFIG_CMD_DATE)
+
+/* GPP Pins */
+#define DATA           0x200
+#define SCLK           0x400
+#define RST            0x800
+
+/* Happy Fun Defines(tm) */
+#define RESET          rtc_go_low(RST), rtc_go_low(SCLK)
+#define N_RESET                rtc_go_high(RST), rtc_go_low(SCLK)
+
+#define CLOCK_HIGH     rtc_go_high(SCLK)
+#define CLOCK_LOW      rtc_go_low(SCLK)
+
+#define DATA_HIGH      rtc_go_high(DATA)
+#define DATA_LOW       rtc_go_low(DATA)
+#define DATA_READ      (GTREGREAD(GPP_VALUE) & DATA)
+
+#undef RTC_DEBUG
+
+#ifdef RTC_DEBUG
+#  define DPRINTF(x,args...)   printf("ds1302: " x , ##args)
+static inline void DUMP(const char *ptr, int num)
+{
+       while (num--) printf("%x ", *ptr++);
+       printf("]\n");
+}
+#else
+#  define DPRINTF(x,args...)
+#  define DUMP(ptr, num)
+#endif
+
+/* time data format for DS1302 */
+struct ds1302_st
+{
+       unsigned char CH:1;             /* clock halt 1=stop 0=start */
+       unsigned char sec10:3;
+       unsigned char sec:4;
+
+       unsigned char zero0:1;
+       unsigned char min10:3;
+       unsigned char min:4;
+
+       unsigned char fmt:1;            /* 1=12 hour 0=24 hour */
+       unsigned char zero1:1;
+       unsigned char hr10:2;   /* 10 (0-2) or am/pm (am/pm, 0-1) */
+       unsigned char hr:4;
+
+       unsigned char zero2:2;
+       unsigned char date10:2;
+       unsigned char date:4;
+
+       unsigned char zero3:3;
+       unsigned char month10:1;
+       unsigned char month:4;
+
+       unsigned char zero4:5;
+       unsigned char day:3;            /* day of week */
+
+       unsigned char year10:4;
+       unsigned char year:4;
+
+       unsigned char WP:1;             /* write protect 1=protect 0=unprot */
+       unsigned char zero5:7;
+};
+
+static int ds1302_initted=0;
+
+/* Pin control */
+static inline void
+rtc_go_high(unsigned int mask)
+{
+       unsigned int f = GTREGREAD(GPP_VALUE) | mask;
+
+       GT_REG_WRITE(GPP_VALUE, f);
+}
+
+static inline void
+rtc_go_low(unsigned int mask)
+{
+       unsigned int f = GTREGREAD(GPP_VALUE) & ~mask;
+
+       GT_REG_WRITE(GPP_VALUE, f);
+}
+
+static inline void
+rtc_go_input(unsigned int mask)
+{
+       unsigned int f = GTREGREAD(GPP_IO_CONTROL) & ~mask;
+
+       GT_REG_WRITE(GPP_IO_CONTROL, f);
+}
+
+static inline void
+rtc_go_output(unsigned int mask)
+{
+       unsigned int f = GTREGREAD(GPP_IO_CONTROL) | mask;
+
+       GT_REG_WRITE(GPP_IO_CONTROL, f);
+}
+
+/* Access data in RTC */
+
+static void
+write_byte(unsigned char b)
+{
+       int i;
+       unsigned char mask=1;
+
+       for(i=0;i<8;i++) {
+               CLOCK_LOW;                      /* Lower clock */
+               (b&mask)?DATA_HIGH:DATA_LOW;    /* set data */
+               udelay(1);
+               CLOCK_HIGH;             /* latch data with rising clock */
+               udelay(1);
+               mask=mask<<1;
+       }
+}
+
+static unsigned char
+read_byte(void)
+{
+       int i;
+       unsigned char mask=1;
+       unsigned char b=0;
+
+       for(i=0;i<8;i++) {
+               CLOCK_LOW;
+               udelay(1);
+               if (DATA_READ) b|=mask; /* if this bit is high, set in b */
+               CLOCK_HIGH;             /* clock out next bit */
+               udelay(1);
+               mask=mask<<1;
+       }
+       return b;
+}
+
+static void
+read_ser_drv(unsigned char addr, unsigned char *buf, int count)
+{
+       int i;
+#ifdef RTC_DEBUG
+       char *foo = buf;
+#endif
+
+       DPRINTF("READ 0x%x bytes @ 0x%x [ ", count, addr);
+
+       addr|=1;        /* READ */
+       N_RESET;
+       udelay(4);
+       write_byte(addr);
+       rtc_go_input(DATA); /* Put gpp pin into input mode */
+       udelay(1);
+       for(i=0;i<count;i++) *(buf++)=read_byte();
+       RESET;
+       rtc_go_output(DATA);/* Reset gpp for output */
+       udelay(4);
+
+       DUMP(foo, count);
+}
+
+static void
+write_ser_drv(unsigned char addr, unsigned char *buf, int count)
+{
+       int i;
+
+       DPRINTF("WRITE 0x%x bytes @ 0x%x [ ", count, addr);
+       DUMP(buf, count);
+
+       addr&=~1;       /* WRITE */
+       N_RESET;
+       udelay(4);
+       write_byte(addr);
+       for(i=0;i<count;i++) write_byte(*(buf++));
+       RESET;
+       udelay(4);
+
+}
+
+void
+rtc_init(void)
+{
+       struct ds1302_st bbclk;
+       unsigned char b;
+       int mod;
+
+       DPRINTF("init\n");
+
+       rtc_go_output(DATA|SCLK|RST);
+
+       /* disable write protect */
+       b = 0;
+       write_ser_drv(0x8e,&b,1);
+
+       /* enable trickle */
+       b = 0xa5;       /* 1010.0101 */
+       write_ser_drv(0x90,&b,1);
+
+       /* read burst */
+       read_ser_drv(0xbe, (unsigned char *)&bbclk, 8);
+
+       /* Sanity checks */
+       mod = 0;
+       if (bbclk.CH) {
+               printf("ds1302: Clock was halted, starting clock\n");
+               bbclk.CH=0;
+               mod=1;
+       }
+
+       if (bbclk.fmt) {
+               printf("ds1302: Clock was in 12 hour mode, fixing\n");
+               bbclk.fmt=0;
+               mod=1;
+       }
+
+       if (bbclk.year>9) {
+               printf("ds1302: Year was corrupted, fixing\n");
+               bbclk.year10=100/10;    /* 2000 - why not? ;) */
+               bbclk.year=0;
+               mod=1;
+       }
+
+       /* Write out the changes if needed */
+       if (mod) {
+               /* enable write protect */
+               bbclk.WP = 1;
+               write_ser_drv(0xbe,(unsigned char *)&bbclk,8);
+       } else {
+               /* Else just turn write protect on */
+               b = 0x80;
+               write_ser_drv(0x8e,&b,1);
+       }
+       DPRINTF("init done\n");
+
+       ds1302_initted=1;
+}
+
+void
+rtc_reset(void)
+{
+       if(!ds1302_initted) rtc_init();
+       /* TODO */
+}
+
+void
+rtc_get(struct rtc_time *tmp)
+{
+       struct ds1302_st bbclk;
+
+       if(!ds1302_initted) rtc_init();
+
+       read_ser_drv(0xbe,(unsigned char *)&bbclk, 8);      /* read burst */
+
+       if (bbclk.CH) {
+               printf("ds1302: rtc_get: Clock was halted, clock probably "
+                       "corrupt\n");
+       }
+
+       tmp->tm_sec=10*bbclk.sec10+bbclk.sec;
+       tmp->tm_min=10*bbclk.min10+bbclk.min;
+       tmp->tm_hour=10*bbclk.hr10+bbclk.hr;
+       tmp->tm_wday=bbclk.day;
+       tmp->tm_mday=10*bbclk.date10+bbclk.date;
+       tmp->tm_mon=10*bbclk.month10+bbclk.month;
+       tmp->tm_year=10*bbclk.year10+bbclk.year + 1900;
+
+       tmp->tm_yday = 0;
+       tmp->tm_isdst= 0;
+
+       DPRINTF("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
+}
+
+void
+rtc_set(struct rtc_time *tmp)
+{
+       struct ds1302_st bbclk;
+       unsigned char b=0;
+
+       if(!ds1302_initted) rtc_init();
+
+       DPRINTF("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+       memset(&bbclk,0,sizeof(bbclk));
+       bbclk.CH=0; /* dont halt */
+       bbclk.WP=1; /* write protect when we're done */
+
+       bbclk.sec10=tmp->tm_sec/10;
+       bbclk.sec=tmp->tm_sec%10;
+
+       bbclk.min10=tmp->tm_min/10;
+       bbclk.min=tmp->tm_min%10;
+
+       bbclk.hr10=tmp->tm_hour/10;
+       bbclk.hr=tmp->tm_hour%10;
+
+       bbclk.day=tmp->tm_wday;
+
+       bbclk.date10=tmp->tm_mday/10;
+       bbclk.date=tmp->tm_mday%10;
+
+       bbclk.month10=tmp->tm_mon/10;
+       bbclk.month=tmp->tm_mon%10;
+
+       tmp->tm_year -= 1900;
+       bbclk.year10=tmp->tm_year/10;
+       bbclk.year=tmp->tm_year%10;
+
+       write_ser_drv(0x8e,&b,1);           /* disable write protect */
+       write_ser_drv(0xbe,(unsigned char *)&bbclk, 8);     /* write burst */
+}
+
+#endif
diff --git a/drivers/rtc/ds1306.c b/drivers/rtc/ds1306.c
new file mode 100644 (file)
index 0000000..89e433d
--- /dev/null
@@ -0,0 +1,438 @@
+/*
+ * (C) Copyright 2002 SIXNET, dge@sixnetio.com.
+ *
+ * (C) Copyright 2004, Li-Pro.Net <www.li-pro.net>
+ * Stephan Linz <linz@li-pro.net>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support for DS1306 RTC using SPI:
+ *
+ *    - SXNI855T:    it uses its own soft SPI here in this file
+ *    - all other:   use the external spi_xfer() function
+ *                   (see include/spi.h)
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <spi.h>
+
+#if defined(CONFIG_RTC_DS1306) && defined(CONFIG_CMD_DATE)
+
+#define        RTC_SECONDS             0x00
+#define        RTC_MINUTES             0x01
+#define        RTC_HOURS               0x02
+#define        RTC_DAY_OF_WEEK         0x03
+#define        RTC_DATE_OF_MONTH       0x04
+#define        RTC_MONTH               0x05
+#define        RTC_YEAR                0x06
+
+#define        RTC_SECONDS_ALARM0      0x07
+#define        RTC_MINUTES_ALARM0      0x08
+#define        RTC_HOURS_ALARM0        0x09
+#define        RTC_DAY_OF_WEEK_ALARM0  0x0a
+
+#define        RTC_SECONDS_ALARM1      0x0b
+#define        RTC_MINUTES_ALARM1      0x0c
+#define        RTC_HOURS_ALARM1        0x0d
+#define        RTC_DAY_OF_WEEK_ALARM1  0x0e
+
+#define        RTC_CONTROL             0x0f
+#define        RTC_STATUS              0x10
+#define        RTC_TRICKLE_CHARGER     0x11
+
+#define        RTC_USER_RAM_BASE       0x20
+
+/*
+ * External table of chip select functions (see the appropriate board
+ * support for the actual definition of the table).
+ */
+extern spi_chipsel_type spi_chipsel[];
+extern int spi_chipsel_cnt;
+
+static unsigned int bin2bcd (unsigned int n);
+static unsigned char bcd2bin (unsigned char c);
+
+/* ************************************************************************* */
+#ifdef CONFIG_SXNI855T         /* !!! SHOULD BE CHANGED TO NEW CODE !!! */
+
+static void soft_spi_send (unsigned char n);
+static unsigned char soft_spi_read (void);
+static void init_spi (void);
+
+/*-----------------------------------------------------------------------
+ * Definitions
+ */
+
+#define        PB_SPISCK       0x00000002      /* PB 30 */
+#define PB_SPIMOSI     0x00000004      /* PB 29 */
+#define PB_SPIMISO     0x00000008      /* PB 28 */
+#define PB_SPI_CE      0x00010000      /* PB 15 */
+
+/* ------------------------------------------------------------------------- */
+
+/* read clock time from DS1306 and return it in *tmp */
+void rtc_get (struct rtc_time *tmp)
+{
+       volatile immap_t *immap = (immap_t *) CFG_IMMR;
+       unsigned char spi_byte; /* Data Byte */
+
+       init_spi ();            /* set port B for software SPI */
+
+       /* Now we can enable the DS1306 RTC */
+       immap->im_cpm.cp_pbdat |= PB_SPI_CE;
+       udelay (10);
+
+       /* Shift out the address (0) of the time in the Clock Chip */
+       soft_spi_send (0);
+
+       /* Put the clock readings into the rtc_time structure */
+       tmp->tm_sec = bcd2bin (soft_spi_read ());       /* Read seconds */
+       tmp->tm_min = bcd2bin (soft_spi_read ());       /* Read minutes */
+
+       /* Hours are trickier */
+       spi_byte = soft_spi_read ();    /* Read Hours into temporary value */
+       if (spi_byte & 0x40) {
+               /* 12 hour mode bit is set (time is in 1-12 format) */
+               if (spi_byte & 0x20) {
+                       /* since PM we add 11 to get 0-23 for hours */
+                       tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) + 11;
+               } else {
+                       /* since AM we subtract 1 to get 0-23 for hours */
+                       tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) - 1;
+               }
+       } else {
+               /* Otherwise, 0-23 hour format */
+               tmp->tm_hour = (bcd2bin (spi_byte & 0x3F));
+       }
+
+       soft_spi_read ();       /* Read and discard Day of week */
+       tmp->tm_mday = bcd2bin (soft_spi_read ());      /* Read Day of the Month */
+       tmp->tm_mon = bcd2bin (soft_spi_read ());       /* Read Month */
+
+       /* Read Year and convert to this century */
+       tmp->tm_year = bcd2bin (soft_spi_read ()) + 2000;
+
+       /* Now we can disable the DS1306 RTC */
+       immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;   /* Disable DS1306 Chip */
+       udelay (10);
+
+       GregorianDay (tmp);     /* Determine the day of week */
+
+       debug ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+              tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+              tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* set clock time in DS1306 RTC and in MPC8xx RTC */
+void rtc_set (struct rtc_time *tmp)
+{
+       volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+       init_spi ();            /* set port B for software SPI */
+
+       /* Now we can enable the DS1306 RTC */
+       immap->im_cpm.cp_pbdat |= PB_SPI_CE;    /* Enable DS1306 Chip */
+       udelay (10);
+
+       /* First disable write protect in the clock chip control register */
+       soft_spi_send (0x8F);   /* send address of the control register */
+       soft_spi_send (0x00);   /* send control register contents */
+
+       /* Now disable the DS1306 to terminate the write */
+       immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;
+       udelay (10);
+
+       /* Now enable the DS1306 to initiate a new write */
+       immap->im_cpm.cp_pbdat |= PB_SPI_CE;
+       udelay (10);
+
+       /* Next, send the address of the clock time write registers */
+       soft_spi_send (0x80);   /* send address of the first time register */
+
+       /* Use Burst Mode to send all of the time data to the clock */
+       bin2bcd (tmp->tm_sec);
+       soft_spi_send (bin2bcd (tmp->tm_sec));  /* Send Seconds */
+       soft_spi_send (bin2bcd (tmp->tm_min));  /* Send Minutes */
+       soft_spi_send (bin2bcd (tmp->tm_hour)); /* Send Hour */
+       soft_spi_send (bin2bcd (tmp->tm_wday)); /* Send Day of the Week */
+       soft_spi_send (bin2bcd (tmp->tm_mday)); /* Send Day of Month */
+       soft_spi_send (bin2bcd (tmp->tm_mon));  /* Send Month */
+       soft_spi_send (bin2bcd (tmp->tm_year - 2000));  /* Send Year */
+
+       /* Now we can disable the Clock chip to terminate the burst write */
+       immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;   /* Disable DS1306 Chip */
+       udelay (10);
+
+       /* Now we can enable the Clock chip to initiate a new write */
+       immap->im_cpm.cp_pbdat |= PB_SPI_CE;    /* Enable DS1306 Chip */
+       udelay (10);
+
+       /* First we Enable write protect in the clock chip control register */
+       soft_spi_send (0x8F);   /* send address of the control register */
+       soft_spi_send (0x40);   /* send out Control Register contents */
+
+       /* Now disable the DS1306 */
+       immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;   /*  Disable DS1306 Chip */
+       udelay (10);
+
+       /* Set standard MPC8xx clock to the same time so Linux will
+        * see the time even if it doesn't have a DS1306 clock driver.
+        * This helps with experimenting with standard kernels.
+        */
+       {
+               ulong tim;
+
+               tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
+                             tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+               immap->im_sitk.sitk_rtck = KAPWR_KEY;
+               immap->im_sit.sit_rtc = tim;
+       }
+
+       debug ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+              tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+              tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Initialize Port B for software SPI */
+static void init_spi (void)
+{
+       volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+       /* Force output pins to begin at logic 0 */
+       immap->im_cpm.cp_pbdat &= ~(PB_SPI_CE | PB_SPIMOSI | PB_SPISCK);
+
+       /* Set these 3 signals as outputs */
+       immap->im_cpm.cp_pbdir |= (PB_SPIMOSI | PB_SPI_CE | PB_SPISCK);
+
+       immap->im_cpm.cp_pbdir &= ~PB_SPIMISO;  /* Make MISO pin an input */
+       udelay (10);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* NOTE: soft_spi_send() assumes that the I/O lines are configured already */
+static void soft_spi_send (unsigned char n)
+{
+       volatile immap_t *immap = (immap_t *) CFG_IMMR;
+       unsigned char bitpos;   /* bit position to receive */
+       unsigned char i;        /* Loop Control */
+
+       /* bit position to send, start with most significant bit */
+       bitpos = 0x80;
+
+       /* Send 8 bits to software SPI */
+       for (i = 0; i < 8; i++) {       /* Loop for 8 bits */
+               immap->im_cpm.cp_pbdat |= PB_SPISCK;    /* Raise SCK */
+
+               if (n & bitpos)
+                       immap->im_cpm.cp_pbdat |= PB_SPIMOSI;   /* Set MOSI to 1 */
+               else
+                       immap->im_cpm.cp_pbdat &= ~PB_SPIMOSI;  /* Set MOSI to 0 */
+               udelay (10);
+
+               immap->im_cpm.cp_pbdat &= ~PB_SPISCK;   /* Lower SCK */
+               udelay (10);
+
+               bitpos >>= 1;   /* Shift for next bit position */
+       }
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* NOTE: soft_spi_read() assumes that the I/O lines are configured already */
+static unsigned char soft_spi_read (void)
+{
+       volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+       unsigned char spi_byte = 0;     /* Return value, assume success */
+       unsigned char bitpos;   /* bit position to receive */
+       unsigned char i;        /* Loop Control */
+
+       /* bit position to receive, start with most significant bit */
+       bitpos = 0x80;
+
+       /* Read 8 bits here */
+       for (i = 0; i < 8; i++) {       /* Do 8 bits in loop */
+               immap->im_cpm.cp_pbdat |= PB_SPISCK;    /* Raise SCK */
+               udelay (10);
+               if (immap->im_cpm.cp_pbdat & PB_SPIMISO)        /* Get a bit of data */
+                       spi_byte |= bitpos;     /* Set data accordingly */
+               immap->im_cpm.cp_pbdat &= ~PB_SPISCK;   /* Lower SCK */
+               udelay (10);
+               bitpos >>= 1;   /* Shift for next bit position */
+       }
+
+       return spi_byte;        /* Return the byte read */
+}
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_reset (void)
+{
+       return;                 /* nothing to do */
+}
+
+#else  /* not CONFIG_SXNI855T */
+/* ************************************************************************* */
+
+static unsigned char rtc_read (unsigned char reg);
+static void rtc_write (unsigned char reg, unsigned char val);
+
+/* read clock time from DS1306 and return it in *tmp */
+void rtc_get (struct rtc_time *tmp)
+{
+       unsigned char sec, min, hour, mday, wday, mon, year;
+
+       sec = rtc_read (RTC_SECONDS);
+       min = rtc_read (RTC_MINUTES);
+       hour = rtc_read (RTC_HOURS);
+       mday = rtc_read (RTC_DATE_OF_MONTH);
+       wday = rtc_read (RTC_DAY_OF_WEEK);
+       mon = rtc_read (RTC_MONTH);
+       year = rtc_read (RTC_YEAR);
+
+       debug ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
+              "hr: %02x min: %02x sec: %02x\n",
+              year, mon, mday, wday, hour, min, sec);
+       debug ("Alarms[0]: wday: %02x hour: %02x min: %02x sec: %02x\n",
+              rtc_read (RTC_DAY_OF_WEEK_ALARM0),
+              rtc_read (RTC_HOURS_ALARM0),
+              rtc_read (RTC_MINUTES_ALARM0), rtc_read (RTC_SECONDS_ALARM0));
+       debug ("Alarms[1]: wday: %02x hour: %02x min: %02x sec: %02x\n",
+              rtc_read (RTC_DAY_OF_WEEK_ALARM1),
+              rtc_read (RTC_HOURS_ALARM1),
+              rtc_read (RTC_MINUTES_ALARM1), rtc_read (RTC_SECONDS_ALARM1));
+
+       tmp->tm_sec = bcd2bin (sec & 0x7F);     /* convert Seconds */
+       tmp->tm_min = bcd2bin (min & 0x7F);     /* convert Minutes */
+
+       /* convert Hours */
+       tmp->tm_hour = (hour & 0x40)
+               ? ((hour & 0x20)        /* 12 hour mode */
+                  ? bcd2bin (hour & 0x1F) + 11 /* PM */
+                  : bcd2bin (hour & 0x1F) - 1  /* AM */
+               )
+               : bcd2bin (hour & 0x3F);        /* 24 hour mode */
+
+       tmp->tm_mday = bcd2bin (mday & 0x3F);   /* convert Day of the Month */
+       tmp->tm_mon = bcd2bin (mon & 0x1F);     /* convert Month */
+       tmp->tm_year = bcd2bin (year) + 2000;   /* convert Year */
+       tmp->tm_wday = bcd2bin (wday & 0x07) - 1;       /* convert Day of the Week */
+       tmp->tm_yday = 0;
+       tmp->tm_isdst = 0;
+
+       debug ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+              tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+              tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* set clock time from *tmp in DS1306 RTC */
+void rtc_set (struct rtc_time *tmp)
+{
+       debug ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+              tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+              tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+       rtc_write (RTC_SECONDS, bin2bcd (tmp->tm_sec));
+       rtc_write (RTC_MINUTES, bin2bcd (tmp->tm_min));
+       rtc_write (RTC_HOURS, bin2bcd (tmp->tm_hour));
+       rtc_write (RTC_DAY_OF_WEEK, bin2bcd (tmp->tm_wday + 1));
+       rtc_write (RTC_DATE_OF_MONTH, bin2bcd (tmp->tm_mday));
+       rtc_write (RTC_MONTH, bin2bcd (tmp->tm_mon));
+       rtc_write (RTC_YEAR, bin2bcd (tmp->tm_year - 2000));
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* reset the DS1306 */
+void rtc_reset (void)
+{
+       /* clear the control register */
+       rtc_write (RTC_CONTROL, 0x00);  /* 1st step: reset WP */
+       rtc_write (RTC_CONTROL, 0x00);  /* 2nd step: reset 1Hz, AIE1, AIE0 */
+
+       /* reset all alarms */
+       rtc_write (RTC_SECONDS_ALARM0, 0x00);
+       rtc_write (RTC_SECONDS_ALARM1, 0x00);
+       rtc_write (RTC_MINUTES_ALARM0, 0x00);
+       rtc_write (RTC_MINUTES_ALARM1, 0x00);
+       rtc_write (RTC_HOURS_ALARM0, 0x00);
+       rtc_write (RTC_HOURS_ALARM1, 0x00);
+       rtc_write (RTC_DAY_OF_WEEK_ALARM0, 0x00);
+       rtc_write (RTC_DAY_OF_WEEK_ALARM1, 0x00);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static unsigned char rtc_read (unsigned char reg)
+{
+       unsigned char dout[2];  /* SPI Output Data Bytes */
+       unsigned char din[2];   /* SPI Input Data Bytes */
+
+       dout[0] = reg;
+
+       if (spi_xfer (spi_chipsel[CFG_SPI_RTC_DEVID], 16, dout, din) != 0) {
+               return 0;
+       } else {
+               return din[1];
+       }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void rtc_write (unsigned char reg, unsigned char val)
+{
+       unsigned char dout[2];  /* SPI Output Data Bytes */
+       unsigned char din[2];   /* SPI Input Data Bytes */
+
+       dout[0] = 0x80 | reg;
+       dout[1] = val;
+
+       spi_xfer (spi_chipsel[CFG_SPI_RTC_DEVID], 16, dout, din);
+}
+
+#endif /* end of code exclusion (see #ifdef CONFIG_SXNI855T above) */
+
+/* ------------------------------------------------------------------------- */
+
+static unsigned char bcd2bin (unsigned char n)
+{
+       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+/* ------------------------------------------------------------------------- */
+
+static unsigned int bin2bcd (unsigned int n)
+{
+       return (((n / 10) << 4) | (n % 10));
+}
+/* ------------------------------------------------------------------------- */
+
+#endif
diff --git a/drivers/rtc/ds1307.c b/drivers/rtc/ds1307.c
new file mode 100644 (file)
index 0000000..c882d79
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * (C) Copyright 2001, 2002, 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.com`
+ * Steven Scholz, steven.scholz@imc-berlin.de
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
+ * DS1307 and DS1338 Real Time Clock (RTC).
+ *
+ * based on ds1337.c
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if (defined(CONFIG_RTC_DS1307) || defined(CONFIG_RTC_DS1338) ) && \
+    defined(CONFIG_CMD_DATE)
+
+/*---------------------------------------------------------------------*/
+#undef DEBUG_RTC
+
+#ifdef DEBUG_RTC
+#define DEBUGR(fmt,args...) printf(fmt ,##args)
+#else
+#define DEBUGR(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+#ifndef CFG_I2C_RTC_ADDR
+# define CFG_I2C_RTC_ADDR      0x68
+#endif
+
+#if defined(CONFIG_RTC_DS1307) && (CFG_I2C_SPEED > 100000)
+# error The DS1307 is specified only up to 100kHz!
+#endif
+
+/*
+ * RTC register addresses
+ */
+#define RTC_SEC_REG_ADDR       0x00
+#define RTC_MIN_REG_ADDR       0x01
+#define RTC_HR_REG_ADDR                0x02
+#define RTC_DAY_REG_ADDR       0x03
+#define RTC_DATE_REG_ADDR      0x04
+#define RTC_MON_REG_ADDR       0x05
+#define RTC_YR_REG_ADDR                0x06
+#define RTC_CTL_REG_ADDR       0x07
+
+#define RTC_SEC_BIT_CH         0x80    /* Clock Halt (in Register 0)   */
+
+#define RTC_CTL_BIT_RS0                0x01    /* Rate select 0                */
+#define RTC_CTL_BIT_RS1                0x02    /* Rate select 1                */
+#define RTC_CTL_BIT_SQWE       0x10    /* Square Wave Enable           */
+#define RTC_CTL_BIT_OUT                0x80    /* Output Control               */
+
+static uchar rtc_read (uchar reg);
+static void rtc_write (uchar reg, uchar val);
+static uchar bin2bcd (unsigned int n);
+static unsigned bcd2bin (uchar c);
+
+/*
+ * Get the current time from the RTC
+ */
+void rtc_get (struct rtc_time *tmp)
+{
+       uchar sec, min, hour, mday, wday, mon, year;
+
+       sec = rtc_read (RTC_SEC_REG_ADDR);
+       min = rtc_read (RTC_MIN_REG_ADDR);
+       hour = rtc_read (RTC_HR_REG_ADDR);
+       wday = rtc_read (RTC_DAY_REG_ADDR);
+       mday = rtc_read (RTC_DATE_REG_ADDR);
+       mon = rtc_read (RTC_MON_REG_ADDR);
+       year = rtc_read (RTC_YR_REG_ADDR);
+
+       DEBUGR ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
+               "hr: %02x min: %02x sec: %02x\n",
+               year, mon, mday, wday, hour, min, sec);
+
+       if (sec & RTC_SEC_BIT_CH) {
+               printf ("### Warning: RTC oscillator has stopped\n");
+               /* clear the CH flag */
+               rtc_write (RTC_SEC_REG_ADDR,
+                          rtc_read (RTC_SEC_REG_ADDR) & ~RTC_SEC_BIT_CH);
+       }
+
+       tmp->tm_sec  = bcd2bin (sec & 0x7F);
+       tmp->tm_min  = bcd2bin (min & 0x7F);
+       tmp->tm_hour = bcd2bin (hour & 0x3F);
+       tmp->tm_mday = bcd2bin (mday & 0x3F);
+       tmp->tm_mon  = bcd2bin (mon & 0x1F);
+       tmp->tm_year = bcd2bin (year) + ( bcd2bin (year) >= 70 ? 1900 : 2000);
+       tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
+       tmp->tm_yday = 0;
+       tmp->tm_isdst= 0;
+
+       DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+
+/*
+ * Set the RTC
+ */
+void rtc_set (struct rtc_time *tmp)
+{
+       DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+       if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
+               printf("WARNING: year should be between 1970 and 2069!\n");
+
+       rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
+       rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon));
+       rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
+       rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
+       rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
+       rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
+       rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
+}
+
+
+/*
+ * Reset the RTC. We setting the date back to 1970-01-01.
+ * We also enable the oscillator output on the SQW/OUT pin and program
+ * it for 32,768 Hz output. Note that according to the datasheet, turning
+ * on the square wave output increases the current drain on the backup
+ * battery to something between 480nA and 800nA.
+ */
+void rtc_reset (void)
+{
+       struct rtc_time tmp;
+
+       rtc_write (RTC_SEC_REG_ADDR, 0x00);     /* clearing Clock Halt  */
+       rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_SQWE | RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS0);
+
+       tmp.tm_year = 1970;
+       tmp.tm_mon = 1;
+       tmp.tm_mday= 1;
+       tmp.tm_hour = 0;
+       tmp.tm_min = 0;
+       tmp.tm_sec = 0;
+
+       rtc_set(&tmp);
+
+       printf ( "RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC\n",
+               tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
+               tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
+
+       return;
+}
+
+
+/*
+ * Helper functions
+ */
+
+static
+uchar rtc_read (uchar reg)
+{
+       return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
+}
+
+
+static void rtc_write (uchar reg, uchar val)
+{
+       i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+}
+
+static unsigned bcd2bin (uchar n)
+{
+       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+       return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/ds1337.c b/drivers/rtc/ds1337.c
new file mode 100644 (file)
index 0000000..c636ac5
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * (C) Copyright 2001, 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.com`
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
+ * DS1337 Real Time Clock (RTC).
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_RTC_DS1337) && defined(CONFIG_CMD_DATE)
+
+/*---------------------------------------------------------------------*/
+#undef DEBUG_RTC
+
+#ifdef DEBUG_RTC
+#define DEBUGR(fmt,args...) printf(fmt ,##args)
+#else
+#define DEBUGR(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+/*
+ * RTC register addresses
+ */
+#define RTC_SEC_REG_ADDR       0x0
+#define RTC_MIN_REG_ADDR       0x1
+#define RTC_HR_REG_ADDR                0x2
+#define RTC_DAY_REG_ADDR       0x3
+#define RTC_DATE_REG_ADDR      0x4
+#define RTC_MON_REG_ADDR       0x5
+#define RTC_YR_REG_ADDR                0x6
+#define RTC_CTL_REG_ADDR       0x0e
+#define RTC_STAT_REG_ADDR      0x0f
+
+/*
+ * RTC control register bits
+ */
+#define RTC_CTL_BIT_A1IE       0x1     /* Alarm 1 interrupt enable     */
+#define RTC_CTL_BIT_A2IE       0x2     /* Alarm 2 interrupt enable     */
+#define RTC_CTL_BIT_INTCN      0x4     /* Interrupt control            */
+#define RTC_CTL_BIT_RS1                0x8     /* Rate select 1                */
+#define RTC_CTL_BIT_RS2                0x10    /* Rate select 2                */
+#define RTC_CTL_BIT_DOSC       0x80    /* Disable Oscillator           */
+
+/*
+ * RTC status register bits
+ */
+#define RTC_STAT_BIT_A1F       0x1     /* Alarm 1 flag                 */
+#define RTC_STAT_BIT_A2F       0x2     /* Alarm 2 flag                 */
+#define RTC_STAT_BIT_OSF       0x80    /* Oscillator stop flag         */
+
+
+static uchar rtc_read (uchar reg);
+static void rtc_write (uchar reg, uchar val);
+static uchar bin2bcd (unsigned int n);
+static unsigned bcd2bin (uchar c);
+
+
+/*
+ * Get the current time from the RTC
+ */
+void rtc_get (struct rtc_time *tmp)
+{
+       uchar sec, min, hour, mday, wday, mon_cent, year, control, status;
+
+       control = rtc_read (RTC_CTL_REG_ADDR);
+       status = rtc_read (RTC_STAT_REG_ADDR);
+       sec = rtc_read (RTC_SEC_REG_ADDR);
+       min = rtc_read (RTC_MIN_REG_ADDR);
+       hour = rtc_read (RTC_HR_REG_ADDR);
+       wday = rtc_read (RTC_DAY_REG_ADDR);
+       mday = rtc_read (RTC_DATE_REG_ADDR);
+       mon_cent = rtc_read (RTC_MON_REG_ADDR);
+       year = rtc_read (RTC_YR_REG_ADDR);
+
+       DEBUGR ("Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+               "hr: %02x min: %02x sec: %02x control: %02x status: %02x\n",
+               year, mon_cent, mday, wday, hour, min, sec, control, status);
+
+       if (status & RTC_STAT_BIT_OSF) {
+               printf ("### Warning: RTC oscillator has stopped\n");
+               /* clear the OSF flag */
+               rtc_write (RTC_STAT_REG_ADDR,
+                          rtc_read (RTC_STAT_REG_ADDR) & ~RTC_STAT_BIT_OSF);
+       }
+
+       tmp->tm_sec  = bcd2bin (sec & 0x7F);
+       tmp->tm_min  = bcd2bin (min & 0x7F);
+       tmp->tm_hour = bcd2bin (hour & 0x3F);
+       tmp->tm_mday = bcd2bin (mday & 0x3F);
+       tmp->tm_mon  = bcd2bin (mon_cent & 0x1F);
+       tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900);
+       tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
+       tmp->tm_yday = 0;
+       tmp->tm_isdst= 0;
+
+       DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+
+/*
+ * Set the RTC
+ */
+void rtc_set (struct rtc_time *tmp)
+{
+       uchar century;
+
+       DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+       rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
+
+       century = (tmp->tm_year >= 2000) ? 0x80 : 0;
+       rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon) | century);
+
+       rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
+       rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
+       rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
+       rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
+       rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
+}
+
+
+/*
+ * Reset the RTC.  We also enable the oscillator output on the
+ * SQW/INTB* pin and program it for 32,768 Hz output. Note that
+ * according to the datasheet, turning on the square wave output
+ * increases the current drain on the backup battery from about
+ * 600 nA to 2uA.
+ */
+void rtc_reset (void)
+{
+       rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2);
+}
+
+
+/*
+ * Helper functions
+ */
+
+static
+uchar rtc_read (uchar reg)
+{
+       return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
+}
+
+
+static void rtc_write (uchar reg, uchar val)
+{
+       i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+}
+
+static unsigned bcd2bin (uchar n)
+{
+       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+       return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/ds1374.c b/drivers/rtc/ds1374.c
new file mode 100644 (file)
index 0000000..e773dd9
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * (C) Copyright 2001, 2002, 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.com`
+ * Steven Scholz, steven.scholz@imc-berlin.de
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
+ * DS1374 Real Time Clock (RTC).
+ *
+ * based on ds1337.c
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if (defined(CONFIG_RTC_DS1374)) && defined(CONFIG_CMD_DATE)
+
+/*---------------------------------------------------------------------*/
+#undef DEBUG_RTC
+#define DEBUG_RTC
+
+#ifdef DEBUG_RTC
+#define DEBUGR(fmt,args...) printf(fmt ,##args)
+#else
+#define DEBUGR(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+#ifndef CFG_I2C_RTC_ADDR
+# define CFG_I2C_RTC_ADDR      0x68
+#endif
+
+#if defined(CONFIG_RTC_DS1374) && (CFG_I2C_SPEED > 400000)
+# error The DS1374 is specified up to 400kHz in fast mode!
+#endif
+
+/*
+ * RTC register addresses
+ */
+#define RTC_TOD_CNT_BYTE0_ADDR         0x00 /* TimeOfDay */
+#define RTC_TOD_CNT_BYTE1_ADDR         0x01
+#define RTC_TOD_CNT_BYTE2_ADDR         0x02
+#define RTC_TOD_CNT_BYTE3_ADDR         0x03
+
+#define RTC_WD_ALM_CNT_BYTE0_ADDR      0x04
+#define RTC_WD_ALM_CNT_BYTE1_ADDR      0x05
+#define RTC_WD_ALM_CNT_BYTE2_ADDR      0x06
+
+#define RTC_CTL_ADDR                   0x07 /* RTC-CoNTrol-register */
+#define RTC_SR_ADDR                    0x08 /* RTC-StatusRegister */
+#define RTC_TCS_DS_ADDR                        0x09 /* RTC-TrickleChargeSelect DiodeSelect-register */
+
+#define RTC_CTL_BIT_AIE                        (1<<0) /* Bit 0 - Alarm Interrupt enable */
+#define RTC_CTL_BIT_RS1                        (1<<1) /* Bit 1/2 - Rate Select square wave output */
+#define RTC_CTL_BIT_RS2                        (1<<2) /* Bit 2/2 - Rate Select square wave output */
+#define RTC_CTL_BIT_WDSTR              (1<<3) /* Bit 3 - Watchdog Reset Steering */
+#define RTC_CTL_BIT_BBSQW              (1<<4) /* Bit 4 - Battery-Backed Square-Wave */
+#define RTC_CTL_BIT_WD_ALM             (1<<5) /* Bit 5 - Watchdoc/Alarm Counter Select */
+#define RTC_CTL_BIT_WACE               (1<<6) /* Bit 6 - Watchdog/Alarm Counter Enable WACE*/
+#define RTC_CTL_BIT_EN_OSC             (1<<7) /* Bit 7 - Enable Oscilator */
+
+#define RTC_SR_BIT_AF                  0x01 /* Bit 0 = Alarm Flag */
+#define RTC_SR_BIT_OSF                 0x80 /* Bit 7 - Osc Stop Flag */
+
+typedef unsigned char boolean_t;
+
+#ifndef TRUE
+#define TRUE ((boolean_t)(0==0))
+#endif
+#ifndef FALSE
+#define FALSE (!TRUE)
+#endif
+
+const char RtcTodAddr[] = {
+       RTC_TOD_CNT_BYTE0_ADDR,
+       RTC_TOD_CNT_BYTE1_ADDR,
+       RTC_TOD_CNT_BYTE2_ADDR,
+       RTC_TOD_CNT_BYTE3_ADDR
+};
+
+static uchar rtc_read (uchar reg);
+static void rtc_write (uchar reg, uchar val, boolean_t set);
+static void rtc_write_raw (uchar reg, uchar val);
+
+/*
+ * Get the current time from the RTC
+ */
+void rtc_get (struct rtc_time *tm){
+
+       unsigned long time1, time2;
+       unsigned int limit;
+       unsigned char tmp;
+       unsigned int i;
+
+       /*
+        * Since the reads are being performed one byte at a time,
+        * there is a chance that a carry will occur during the read.
+        * To detect this, 2 reads are performed and compared.
+        */
+       limit = 10;
+       do {
+               i = 4;
+               time1 = 0;
+               while (i--) {
+                       tmp = rtc_read(RtcTodAddr[i]);
+                       time1 = (time1 << 8) | (tmp & 0xff);
+               }
+
+               i = 4;
+               time2 = 0;
+               while (i--) {
+                       tmp = rtc_read(RtcTodAddr[i]);
+                       time2 = (time2 << 8) | (tmp & 0xff);
+               }
+       } while ((time1 != time2) && limit--);
+
+       if (time1 != time2) {
+               printf("can't get consistent time from rtc chip\n");
+       }
+
+       DEBUGR ("Get RTC s since 1.1.1970: %d\n", time1);
+
+       to_tm(time1, tm); /* To Gregorian Date */
+
+       if (rtc_read(RTC_SR_ADDR) & RTC_SR_BIT_OSF)
+               printf ("### Warning: RTC oscillator has stopped\n");
+
+       DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
+               tm->tm_hour, tm->tm_min, tm->tm_sec);
+}
+
+/*
+ * Set the RTC
+ */
+void rtc_set (struct rtc_time *tmp){
+
+       unsigned long time;
+       unsigned i;
+
+       DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+       if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
+               printf("WARNING: year should be between 1970 and 2069!\n");
+
+       time = mktime(tmp->tm_year, tmp->tm_mon,
+                       tmp->tm_mday, tmp->tm_hour,
+                       tmp->tm_min, tmp->tm_sec);
+
+       DEBUGR ("Set RTC s since 1.1.1970: %d (0x%02x)\n", time, time);
+
+       /* write to RTC_TOD_CNT_BYTEn_ADDR */
+       for (i = 0; i <= 3; i++) {
+               rtc_write_raw(RtcTodAddr[i], (unsigned char)(time & 0xff));
+               time = time >> 8;
+       }
+
+       /* Start clock */
+       rtc_write(RTC_CTL_ADDR, RTC_CTL_BIT_EN_OSC, FALSE);
+}
+
+/*
+ * Reset the RTC. We setting the date back to 1970-01-01.
+ * We also enable the oscillator output on the SQW/OUT pin and program
+ * it for 32,768 Hz output. Note that according to the datasheet, turning
+ * on the square wave output increases the current drain on the backup
+ * battery to something between 480nA and 800nA.
+ */
+void rtc_reset (void){
+
+       struct rtc_time tmp;
+
+       /* clear status flags */
+       rtc_write (RTC_SR_ADDR, (RTC_SR_BIT_AF|RTC_SR_BIT_OSF), FALSE); /* clearing OSF and AF */
+
+       /* Initialise DS1374 oriented to MPC8349E-ADS */
+       rtc_write (RTC_CTL_ADDR, (RTC_CTL_BIT_EN_OSC
+                                |RTC_CTL_BIT_WACE
+                                |RTC_CTL_BIT_AIE), FALSE);/* start osc, disable WACE, clear AIE
+                                                             - set to 0 */
+       rtc_write (RTC_CTL_ADDR, (RTC_CTL_BIT_WD_ALM
+                               |RTC_CTL_BIT_WDSTR
+                               |RTC_CTL_BIT_RS1
+                               |RTC_CTL_BIT_RS2
+                               |RTC_CTL_BIT_BBSQW), TRUE);/* disable WD/ALM, WDSTR set to INT-pin,
+                                                             set BBSQW and SQW to 32k
+                                                             - set to 1 */
+       tmp.tm_year = 1970;
+       tmp.tm_mon = 1;
+       tmp.tm_mday= 1;
+       tmp.tm_hour = 0;
+       tmp.tm_min = 0;
+       tmp.tm_sec = 0;
+
+       rtc_set(&tmp);
+
+       printf("RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC\n",
+               tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
+               tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
+
+       rtc_write(RTC_WD_ALM_CNT_BYTE2_ADDR,0xAC, TRUE);
+       rtc_write(RTC_WD_ALM_CNT_BYTE1_ADDR,0xDE, TRUE);
+       rtc_write(RTC_WD_ALM_CNT_BYTE2_ADDR,0xAD, TRUE);
+}
+
+/*
+ * Helper functions
+ */
+static uchar rtc_read (uchar reg)
+{
+       return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
+}
+
+static void rtc_write (uchar reg, uchar val, boolean_t set)
+{
+       if (set == TRUE) {
+               val |= i2c_reg_read (CFG_I2C_RTC_ADDR, reg);
+               i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+       } else {
+               val = i2c_reg_read (CFG_I2C_RTC_ADDR, reg) & ~val;
+               i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+       }
+}
+
+static void rtc_write_raw (uchar reg, uchar val)
+{
+               i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+}
+#endif
diff --git a/drivers/rtc/ds1556.c b/drivers/rtc/ds1556.c
new file mode 100644 (file)
index 0000000..4365cfb
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * (C) Copyright 2002
+ * ARIO Data Networks, Inc. dchiu@ariodata.com
+ *
+ * modified for DS1556:
+ * Frank Panno <fpanno@delphintech.com>, Delphin Technology AG
+ *
+ * Based on MontaVista DS1743 code and U-Boot mc146818 code
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support for the DS1556 RTC
+ */
+
+/*#define      RTC_DEBUG */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+
+#if defined(CONFIG_RTC_DS1556) && defined(CONFIG_CMD_DATE)
+
+static uchar rtc_read( unsigned int addr );
+static void  rtc_write( unsigned int addr, uchar val);
+static uchar bin2bcd   (unsigned int n);
+static unsigned bcd2bin(uchar c);
+
+#define RTC_BASE               ( CFG_NVRAM_SIZE + CFG_NVRAM_BASE_ADDR )
+
+#define RTC_YEAR               ( RTC_BASE + 0xf )
+#define RTC_MONTH              ( RTC_BASE + 0xe )
+#define RTC_DAY_OF_MONTH       ( RTC_BASE + 0xd )
+#define RTC_DAY_OF_WEEK                ( RTC_BASE + 0xc )
+#define RTC_HOURS              ( RTC_BASE + 0xb )
+#define RTC_MINUTES            ( RTC_BASE + 0xa )
+#define RTC_SECONDS            ( RTC_BASE + 0x9 )
+#define RTC_CENTURY            ( RTC_BASE + 0x8 )
+
+#define RTC_CONTROLA           RTC_CENTURY
+#define RTC_CONTROLB           RTC_SECONDS
+#define RTC_CONTROLC           RTC_BASE
+
+#define RTC_CA_WRITE           0x80
+#define RTC_CA_READ            0x40
+
+#define RTC_CB_OSC_DISABLE     0x80
+
+#define RTC_CC_BATTERY_FLAG    0x10
+#define RTC_CC_FREQ_TEST       0x40
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get( struct rtc_time *tmp )
+{
+       uchar sec, min, hour;
+       uchar mday, wday, mon, year;
+
+       int century;
+
+       uchar reg_a;
+
+       reg_a = rtc_read( RTC_CONTROLA );
+       /* lock clock registers for read */
+       rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
+
+       sec     = rtc_read( RTC_SECONDS );
+       min     = rtc_read( RTC_MINUTES );
+       hour    = rtc_read( RTC_HOURS );
+       mday    = rtc_read( RTC_DAY_OF_MONTH );
+       wday    = rtc_read( RTC_DAY_OF_WEEK );
+       mon     = rtc_read( RTC_MONTH );
+       year    = rtc_read( RTC_YEAR );
+       century = rtc_read( RTC_CENTURY );
+
+       /* unlock clock registers after read */
+       rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
+
+#ifdef RTC_DEBUG
+       printf( "Get RTC year: %02x mon/cent: %02x mon: %02x mday: %02x wday: %02x "
+               "hr: %02x min: %02x sec: %02x\n",
+               year, century, mon, mday, wday,
+               hour, min, sec );
+#endif
+       tmp->tm_sec  = bcd2bin( sec  & 0x7F );
+       tmp->tm_min  = bcd2bin( min  & 0x7F );
+       tmp->tm_hour = bcd2bin( hour & 0x3F );
+       tmp->tm_mday = bcd2bin( mday & 0x3F );
+       tmp->tm_mon  = bcd2bin( mon & 0x1F );
+       tmp->tm_wday = bcd2bin( wday & 0x07 );
+
+       /* glue year from century and year in century */
+       tmp->tm_year = bcd2bin( year ) +
+               ( bcd2bin( century & 0x3F ) * 100 );
+
+       tmp->tm_yday = 0;
+       tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+       printf( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
+#endif
+}
+
+void rtc_set( struct rtc_time *tmp )
+{
+       uchar reg_a;
+#ifdef RTC_DEBUG
+       printf( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+       /* lock clock registers for write */
+       reg_a = rtc_read( RTC_CONTROLA );
+       rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
+
+       rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
+
+       rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
+       rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
+       rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
+       rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
+       rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
+
+       /* break year up into century and year in century */
+       rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
+       rtc_write( RTC_CENTURY, bin2bcd( tmp->tm_year / 100 ));
+
+       /* unlock clock registers after read */
+       rtc_write( RTC_CONTROLA, ( reg_a  & ~RTC_CA_WRITE ));
+}
+
+void rtc_reset (void)
+{
+       uchar reg_a, reg_b, reg_c;
+
+       reg_a = rtc_read( RTC_CONTROLA );
+       reg_b = rtc_read( RTC_CONTROLB );
+
+       if ( reg_b & RTC_CB_OSC_DISABLE )
+       {
+               printf( "real-time-clock was stopped. Now starting...\n" );
+               reg_a |= RTC_CA_WRITE;
+               reg_b &= ~RTC_CB_OSC_DISABLE;
+
+               rtc_write( RTC_CONTROLA, reg_a );
+               rtc_write( RTC_CONTROLB, reg_b );
+       }
+
+       /* make sure read/write clock register bits are cleared */
+       reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
+       rtc_write( RTC_CONTROLA, reg_a );
+
+       reg_c = rtc_read( RTC_CONTROLC );
+       if (( reg_c & RTC_CC_BATTERY_FLAG ) == 0 )
+               printf( "RTC battery low. Clock setting may not be reliable.\n" );
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read( unsigned int addr )
+{
+       uchar val = *(volatile unsigned char*)(addr);
+#ifdef RTC_DEBUG
+       printf( "rtc_read: %x:%x\n", addr, val );
+#endif
+       return( val );
+}
+
+static void rtc_write( unsigned int addr, uchar val )
+{
+#ifdef RTC_DEBUG
+       printf( "rtc_write: %x:%x\n", addr, val );
+#endif
+       *(volatile unsigned char*)(addr) = val;
+}
+
+static unsigned bcd2bin (uchar n)
+{
+       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+       return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/ds164x.c b/drivers/rtc/ds164x.c
new file mode 100644 (file)
index 0000000..bff22b9
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * (C) Copyright 2002
+ * ARIO Data Networks, Inc. dchiu@ariodata.com
+ *
+ * modified for DS164x:
+ * The LEOX team <team@leox.org>, http://www.leox.org
+ *
+ * Based on MontaVista DS1743 code and U-Boot mc146818 code
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support for the DS164x RTC
+ */
+
+/* #define     RTC_DEBUG */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+
+#if defined(CONFIG_RTC_DS164x) && defined(CONFIG_CMD_DATE)
+
+static uchar    rtc_read(unsigned int addr );
+static void     rtc_write(unsigned int addr, uchar val);
+static uchar    bin2bcd(unsigned int n);
+static unsigned bcd2bin(uchar c);
+
+#define RTC_EPOCH                 2000 /* century */
+
+/*
+ * DS164x registers layout
+ */
+#define RTC_BASE               ( CFG_NVRAM_BASE_ADDR + CFG_NVRAM_SIZE )
+
+#define RTC_YEAR               ( RTC_BASE + 0x07 )
+#define RTC_MONTH              ( RTC_BASE + 0x06 )
+#define RTC_DAY_OF_MONTH       ( RTC_BASE + 0x05 )
+#define RTC_DAY_OF_WEEK                ( RTC_BASE + 0x04 )
+#define RTC_HOURS              ( RTC_BASE + 0x03 )
+#define RTC_MINUTES            ( RTC_BASE + 0x02 )
+#define RTC_SECONDS            ( RTC_BASE + 0x01 )
+#define RTC_CONTROL            ( RTC_BASE + 0x00 )
+
+#define RTC_CONTROLA           RTC_CONTROL     /* W=bit6, R=bit5 */
+#define   RTC_CA_WRITE           0x80
+#define   RTC_CA_READ            0x40
+#define RTC_CONTROLB           RTC_SECONDS     /* OSC=bit7       */
+#define   RTC_CB_OSC_DISABLE     0x80
+#define RTC_CONTROLC           RTC_DAY_OF_WEEK /* FT=bit6        */
+#define   RTC_CC_FREQ_TEST       0x40
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get( struct rtc_time *tmp )
+{
+       uchar sec, min, hour;
+       uchar mday, wday, mon, year;
+
+       uchar reg_a;
+
+       reg_a = rtc_read( RTC_CONTROLA );
+       /* lock clock registers for read */
+       rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
+
+       sec     = rtc_read( RTC_SECONDS );
+       min     = rtc_read( RTC_MINUTES );
+       hour    = rtc_read( RTC_HOURS );
+       mday    = rtc_read( RTC_DAY_OF_MONTH );
+       wday    = rtc_read( RTC_DAY_OF_WEEK );
+       mon     = rtc_read( RTC_MONTH );
+       year    = rtc_read( RTC_YEAR );
+
+       /* unlock clock registers after read */
+       rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
+
+#ifdef RTC_DEBUG
+       printf( "Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
+               "hr: %02x min: %02x sec: %02x\n",
+               year, mon, mday, wday,
+               hour, min, sec );
+#endif
+       tmp->tm_sec  = bcd2bin( sec  & 0x7F );
+       tmp->tm_min  = bcd2bin( min  & 0x7F );
+       tmp->tm_hour = bcd2bin( hour & 0x3F );
+       tmp->tm_mday = bcd2bin( mday & 0x3F );
+       tmp->tm_mon  = bcd2bin( mon  & 0x1F );
+       tmp->tm_wday = bcd2bin( wday & 0x07 );
+
+       /* glue year in century (2000) */
+       tmp->tm_year = bcd2bin( year ) + RTC_EPOCH;
+
+       tmp->tm_yday = 0;
+       tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+       printf( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
+#endif
+}
+
+void rtc_set( struct rtc_time *tmp )
+{
+       uchar reg_a;
+
+#ifdef RTC_DEBUG
+       printf( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+       /* lock clock registers for write */
+       reg_a = rtc_read( RTC_CONTROLA );
+       rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
+
+       rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
+
+       rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
+       rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
+       rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
+       rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
+       rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
+
+       /* break year in century */
+       rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
+
+       /* unlock clock registers after read */
+       rtc_write( RTC_CONTROLA, ( reg_a  & ~RTC_CA_WRITE ));
+}
+
+void rtc_reset (void)
+{
+       uchar reg_a, reg_b;
+
+       reg_a = rtc_read( RTC_CONTROLA );
+       reg_b = rtc_read( RTC_CONTROLB );
+
+       if ( reg_b & RTC_CB_OSC_DISABLE )
+       {
+               printf( "real-time-clock was stopped. Now starting...\n" );
+               reg_a |= RTC_CA_WRITE;
+               reg_b &= ~RTC_CB_OSC_DISABLE;
+
+               rtc_write( RTC_CONTROLA, reg_a );
+               rtc_write( RTC_CONTROLB, reg_b );
+       }
+
+       /* make sure read/write clock register bits are cleared */
+       reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
+       rtc_write( RTC_CONTROLA, reg_a );
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read( unsigned int addr )
+{
+       uchar val = *(volatile unsigned char*)(addr);
+
+#ifdef RTC_DEBUG
+       printf( "rtc_read: %x:%x\n", addr, val );
+#endif
+       return( val );
+}
+
+static void rtc_write( unsigned int addr, uchar val )
+{
+#ifdef RTC_DEBUG
+       printf( "rtc_write: %x:%x\n", addr, val );
+#endif
+       *(volatile unsigned char*)(addr) = val;
+}
+
+static unsigned bcd2bin (uchar n)
+{
+       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+       return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/ds174x.c b/drivers/rtc/ds174x.c
new file mode 100644 (file)
index 0000000..5f85a68
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * (C) Copyright 2001
+ * ARIO Data Networks, Inc. dchiu@ariodata.com
+ *
+ * Based on MontaVista DS1743 code and U-Boot mc146818 code
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support for the DS174x RTC
+ */
+
+/*#define      DEBUG*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_RTC_DS174x) && defined(CONFIG_CMD_DATE)
+
+static uchar rtc_read( unsigned int addr );
+static void  rtc_write( unsigned int addr, uchar val);
+static uchar bin2bcd   (unsigned int n);
+static unsigned bcd2bin(uchar c);
+
+#define RTC_BASE               ( CFG_NVRAM_SIZE + CFG_NVRAM_BASE_ADDR )
+
+#define RTC_YEAR               ( RTC_BASE + 7 )
+#define RTC_MONTH              ( RTC_BASE + 6 )
+#define RTC_DAY_OF_MONTH       ( RTC_BASE + 5 )
+#define RTC_DAY_OF_WEEK                ( RTC_BASE + 4 )
+#define RTC_HOURS              ( RTC_BASE + 3 )
+#define RTC_MINUTES            ( RTC_BASE + 2 )
+#define RTC_SECONDS            ( RTC_BASE + 1 )
+#define RTC_CENTURY            ( RTC_BASE + 0 )
+
+#define RTC_CONTROLA           RTC_CENTURY
+#define RTC_CONTROLB           RTC_SECONDS
+#define RTC_CONTROLC           RTC_DAY_OF_WEEK
+
+#define RTC_CA_WRITE           0x80
+#define RTC_CA_READ            0x40
+
+#define RTC_CB_OSC_DISABLE     0x80
+
+#define RTC_CC_BATTERY_FLAG    0x80
+#define RTC_CC_FREQ_TEST       0x40
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get( struct rtc_time *tmp )
+{
+       uchar sec, min, hour;
+       uchar mday, wday, mon, year;
+
+       int century;
+
+       uchar reg_a;
+
+       reg_a = rtc_read( RTC_CONTROLA );
+       /* lock clock registers for read */
+       rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
+
+       sec     = rtc_read( RTC_SECONDS );
+       min     = rtc_read( RTC_MINUTES );
+       hour    = rtc_read( RTC_HOURS );
+       mday    = rtc_read( RTC_DAY_OF_MONTH );
+       wday    = rtc_read( RTC_DAY_OF_WEEK );
+       mon     = rtc_read( RTC_MONTH );
+       year    = rtc_read( RTC_YEAR );
+       century = rtc_read( RTC_CENTURY );
+
+       /* unlock clock registers after read */
+       rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
+
+#ifdef RTC_DEBUG
+       printf( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+               "hr: %02x min: %02x sec: %02x\n",
+               year, mon_cent, mday, wday,
+               hour, min, sec );
+#endif
+       tmp->tm_sec  = bcd2bin( sec  & 0x7F );
+       tmp->tm_min  = bcd2bin( min  & 0x7F );
+       tmp->tm_hour = bcd2bin( hour & 0x3F );
+       tmp->tm_mday = bcd2bin( mday & 0x3F );
+       tmp->tm_mon  = bcd2bin( mon & 0x1F );
+       tmp->tm_wday = bcd2bin( wday & 0x07 );
+
+       /* glue year from century and year in century */
+       tmp->tm_year = bcd2bin( year ) +
+               ( bcd2bin( century & 0x3F ) * 100 );
+
+       tmp->tm_yday = 0;
+       tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+       printf( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
+#endif
+}
+
+void rtc_set( struct rtc_time *tmp )
+{
+       uchar reg_a;
+#ifdef RTC_DEBUG
+       printf( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+       /* lock clock registers for write */
+       reg_a = rtc_read( RTC_CONTROLA );
+       rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
+
+       rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
+
+       rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
+       rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
+       rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
+       rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
+       rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
+
+       /* break year up into century and year in century */
+       rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
+       rtc_write( RTC_CENTURY, bin2bcd( tmp->tm_year / 100 ));
+
+       /* unlock clock registers after read */
+       rtc_write( RTC_CONTROLA, ( reg_a  & ~RTC_CA_WRITE ));
+}
+
+void rtc_reset (void)
+{
+       uchar reg_a, reg_b, reg_c;
+
+       reg_a = rtc_read( RTC_CONTROLA );
+       reg_b = rtc_read( RTC_CONTROLB );
+
+       if ( reg_b & RTC_CB_OSC_DISABLE )
+       {
+               printf( "real-time-clock was stopped. Now starting...\n" );
+               reg_a |= RTC_CA_WRITE;
+               reg_b &= ~RTC_CB_OSC_DISABLE;
+
+               rtc_write( RTC_CONTROLA, reg_a );
+               rtc_write( RTC_CONTROLB, reg_b );
+       }
+
+       /* make sure read/write clock register bits are cleared */
+       reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
+       rtc_write( RTC_CONTROLA, reg_a );
+
+       reg_c = rtc_read( RTC_CONTROLC );
+       if (( reg_c & RTC_CC_BATTERY_FLAG ) == 0 )
+               printf( "RTC battery low. Clock setting may not be reliable.\n" );
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read( unsigned int addr )
+{
+       uchar val = in8( addr );
+#ifdef RTC_DEBUG
+       printf( "rtc_read: %x:%x\n", addr, val );
+#endif
+       return( val );
+}
+
+static void rtc_write( unsigned int addr, uchar val )
+{
+#ifdef RTC_DEBUG
+       printf( "rtc_write: %x:%x\n", addr, val );
+#endif
+       out8( addr, val );
+}
+
+static unsigned bcd2bin (uchar n)
+{
+       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+       return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/ds3231.c b/drivers/rtc/ds3231.c
new file mode 100644 (file)
index 0000000..fe11b86
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * (C) Copyright 2006
+ * Markus Klotzbuecher, mk@denx.de
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
+ * Extremly Accurate DS3231 Real Time Clock (RTC).
+ *
+ * copied from ds1337.c
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_RTC_DS3231) && defined(CONFIG_CMD_DATE)
+
+/*---------------------------------------------------------------------*/
+#undef DEBUG_RTC
+
+#ifdef DEBUG_RTC
+#define DEBUGR(fmt,args...) printf(fmt ,##args)
+#else
+#define DEBUGR(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+/*
+ * RTC register addresses
+ */
+#define RTC_SEC_REG_ADDR       0x0
+#define RTC_MIN_REG_ADDR       0x1
+#define RTC_HR_REG_ADDR                0x2
+#define RTC_DAY_REG_ADDR       0x3
+#define RTC_DATE_REG_ADDR      0x4
+#define RTC_MON_REG_ADDR       0x5
+#define RTC_YR_REG_ADDR                0x6
+#define RTC_CTL_REG_ADDR       0x0e
+#define RTC_STAT_REG_ADDR      0x0f
+
+
+/*
+ * RTC control register bits
+ */
+#define RTC_CTL_BIT_A1IE       0x1     /* Alarm 1 interrupt enable     */
+#define RTC_CTL_BIT_A2IE       0x2     /* Alarm 2 interrupt enable     */
+#define RTC_CTL_BIT_INTCN      0x4     /* Interrupt control            */
+#define RTC_CTL_BIT_RS1                0x8     /* Rate select 1                */
+#define RTC_CTL_BIT_RS2                0x10    /* Rate select 2                */
+#define RTC_CTL_BIT_DOSC       0x80    /* Disable Oscillator           */
+
+/*
+ * RTC status register bits
+ */
+#define RTC_STAT_BIT_A1F       0x1     /* Alarm 1 flag                 */
+#define RTC_STAT_BIT_A2F       0x2     /* Alarm 2 flag                 */
+#define RTC_STAT_BIT_OSF       0x80    /* Oscillator stop flag         */
+
+
+static uchar rtc_read (uchar reg);
+static void rtc_write (uchar reg, uchar val);
+static uchar bin2bcd (unsigned int n);
+static unsigned bcd2bin (uchar c);
+
+
+/*
+ * Get the current time from the RTC
+ */
+void rtc_get (struct rtc_time *tmp)
+{
+       uchar sec, min, hour, mday, wday, mon_cent, year, control, status;
+
+       control = rtc_read (RTC_CTL_REG_ADDR);
+       status = rtc_read (RTC_STAT_REG_ADDR);
+       sec = rtc_read (RTC_SEC_REG_ADDR);
+       min = rtc_read (RTC_MIN_REG_ADDR);
+       hour = rtc_read (RTC_HR_REG_ADDR);
+       wday = rtc_read (RTC_DAY_REG_ADDR);
+       mday = rtc_read (RTC_DATE_REG_ADDR);
+       mon_cent = rtc_read (RTC_MON_REG_ADDR);
+       year = rtc_read (RTC_YR_REG_ADDR);
+
+       DEBUGR ("Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+               "hr: %02x min: %02x sec: %02x control: %02x status: %02x\n",
+               year, mon_cent, mday, wday, hour, min, sec, control, status);
+
+       if (status & RTC_STAT_BIT_OSF) {
+               printf ("### Warning: RTC oscillator has stopped\n");
+               /* clear the OSF flag */
+               rtc_write (RTC_STAT_REG_ADDR,
+                          rtc_read (RTC_STAT_REG_ADDR) & ~RTC_STAT_BIT_OSF);
+       }
+
+       tmp->tm_sec  = bcd2bin (sec & 0x7F);
+       tmp->tm_min  = bcd2bin (min & 0x7F);
+       tmp->tm_hour = bcd2bin (hour & 0x3F);
+       tmp->tm_mday = bcd2bin (mday & 0x3F);
+       tmp->tm_mon  = bcd2bin (mon_cent & 0x1F);
+       tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900);
+       tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
+       tmp->tm_yday = 0;
+       tmp->tm_isdst= 0;
+
+       DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+
+/*
+ * Set the RTC
+ */
+void rtc_set (struct rtc_time *tmp)
+{
+       uchar century;
+
+       DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+       rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
+
+       century = (tmp->tm_year >= 2000) ? 0x80 : 0;
+       rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon) | century);
+
+       rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
+       rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
+       rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
+       rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
+       rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
+}
+
+
+/*
+ * Reset the RTC.  We also enable the oscillator output on the
+ * SQW/INTB* pin and program it for 32,768 Hz output. Note that
+ * according to the datasheet, turning on the square wave output
+ * increases the current drain on the backup battery from about
+ * 600 nA to 2uA.
+ */
+void rtc_reset (void)
+{
+       rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2);
+}
+
+
+/*
+ * Helper functions
+ */
+
+static
+uchar rtc_read (uchar reg)
+{
+       return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
+}
+
+
+static void rtc_write (uchar reg, uchar val)
+{
+       i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+}
+
+static unsigned bcd2bin (uchar n)
+{
+       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+       return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/m41t11.c b/drivers/rtc/m41t11.c
new file mode 100644 (file)
index 0000000..81da33a
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * (C) Copyright 2002
+ * Andrew May, Viasat Inc, amay@viasat.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * M41T11 Serial Access Timekeeper(R) SRAM
+ * can you believe a trademark on that?
+ */
+
+/* #define DEBUG 1 */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+/*
+       I Don't have an example config file but this
+       is what should be done.
+
+#define CONFIG_RTC_M41T11 1
+#define CFG_I2C_RTC_ADDR 0x68
+#if 0
+#define CFG_M41T11_EXT_CENTURY_DATA
+#else
+#define CFG_M41T11_BASE_YEAR 2000
+#endif
+*/
+
+#if defined(CONFIG_RTC_M41T11) && defined(CFG_I2C_RTC_ADDR) && defined(CONFIG_CMD_DATE)
+
+static unsigned bcd2bin (uchar n)
+{
+       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+       return (((n / 10) << 4) | (n % 10));
+}
+
+
+/* ------------------------------------------------------------------------- */
+/*
+  these are simple defines for the chip local to here so they aren't too
+  verbose
+  DAY/DATE aren't nice but that is how they are on the data sheet
+*/
+#define RTC_SEC_ADDR       0x0
+#define RTC_MIN_ADDR       0x1
+#define RTC_HOUR_ADDR      0x2
+#define RTC_DAY_ADDR       0x3
+#define RTC_DATE_ADDR      0x4
+#define RTC_MONTH_ADDR     0x5
+#define RTC_YEARS_ADDR     0x6
+
+#define RTC_REG_CNT        7
+
+#define RTC_CONTROL_ADDR   0x7
+
+
+#ifndef CFG_M41T11_EXT_CENTURY_DATA
+
+#define REG_CNT            (RTC_REG_CNT+1)
+
+/*
+  you only get 00-99 for the year we will asume you
+  want from the year 2000 if you don't set the config
+*/
+#ifndef CFG_M41T11_BASE_YEAR
+#define CFG_M41T11_BASE_YEAR 2000
+#endif
+
+#else
+/* we will store extra year info in byte 9*/
+#define M41T11_YEAR_DATA   0x8
+#define M41T11_YEAR_SIZE   1
+#define REG_CNT            (RTC_REG_CNT+1+M41T11_YEAR_SIZE)
+#endif
+
+#define M41T11_STORAGE_SZ  (64-REG_CNT)
+
+void rtc_get (struct rtc_time *tmp)
+{
+       uchar data[RTC_REG_CNT];
+
+       i2c_read(CFG_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, data, RTC_REG_CNT);
+
+       if( data[RTC_SEC_ADDR] & 0x80 ){
+               printf( "m41t11 RTC Clock stopped!!!\n" );
+       }
+       tmp->tm_sec  = bcd2bin (data[RTC_SEC_ADDR]  & 0x7F);
+       tmp->tm_min  = bcd2bin (data[RTC_MIN_ADDR]  & 0x7F);
+       tmp->tm_hour = bcd2bin (data[RTC_HOUR_ADDR] & 0x3F);
+       tmp->tm_mday = bcd2bin (data[RTC_DATE_ADDR] & 0x3F);
+       tmp->tm_mon  = bcd2bin (data[RTC_MONTH_ADDR]& 0x1F);
+#ifndef CFG_M41T11_EXT_CENTURY_DATA
+       tmp->tm_year = CFG_M41T11_BASE_YEAR
+               + bcd2bin(data[RTC_YEARS_ADDR])
+               + ((data[RTC_HOUR_ADDR]&0x40) ? 100 : 0);
+#else
+       {
+               unsigned char cent;
+               i2c_read(CFG_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, &cent, M41T11_YEAR_SIZE);
+               if( !(data[RTC_HOUR_ADDR] & 0x80) ){
+                       printf( "m41t11 RTC: cann't keep track of years without CEB set\n" );
+               }
+               if( (cent & 0x1) != ((data[RTC_HOUR_ADDR]&0x40)>>7) ){
+                       /*century flip store off new year*/
+                       cent += 1;
+                       i2c_write(CFG_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, &cent, M41T11_YEAR_SIZE);
+               }
+               tmp->tm_year =((int)cent*100)+bcd2bin(data[RTC_YEARS_ADDR]);
+       }
+#endif
+       tmp->tm_wday = bcd2bin (data[RTC_DAY_ADDR]  & 0x07);
+       tmp->tm_yday = 0;
+       tmp->tm_isdst= 0;
+
+       debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+       uchar data[RTC_REG_CNT];
+
+       debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+       data[RTC_SEC_ADDR]    = bin2bcd(tmp->tm_sec) &  0x7F;/*just in case*/
+       data[RTC_MIN_ADDR]    = bin2bcd(tmp->tm_min);
+       data[RTC_HOUR_ADDR]   = bin2bcd(tmp->tm_hour) & 0x3F;/*handle cent stuff later*/
+       data[RTC_DATE_ADDR]   = bin2bcd(tmp->tm_mday) & 0x3F;
+       data[RTC_MONTH_ADDR]  = bin2bcd(tmp->tm_mon);
+       data[RTC_DAY_ADDR]    = bin2bcd(tmp->tm_wday) & 0x07;
+
+       data[RTC_HOUR_ADDR]   |= 0x80;/*we will always use CEB*/
+
+       data[RTC_YEARS_ADDR]  = bin2bcd(tmp->tm_year%100);/*same thing either way*/
+#ifndef CFG_M41T11_EXT_CENTURY_DATA
+       if( ((tmp->tm_year - CFG_M41T11_BASE_YEAR) > 200) ||
+           (tmp->tm_year < CFG_M41T11_BASE_YEAR) ){
+               printf( "m41t11 RTC setting year out of range!!need recompile\n" );
+       }
+       data[RTC_HOUR_ADDR] |= (tmp->tm_year - CFG_M41T11_BASE_YEAR) > 100 ? 0x40 : 0;
+#else
+       {
+               unsigned char cent;
+               cent = tmp->tm_year ? tmp->tm_year / 100 : 0;
+               data[RTC_HOUR_ADDR] |= (cent & 0x1) ? 0x40 : 0;
+               i2c_write(CFG_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, &cent, M41T11_YEAR_SIZE);
+       }
+#endif
+       i2c_write(CFG_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, data, RTC_REG_CNT);
+}
+
+void rtc_reset (void)
+{
+       unsigned char val;
+       /* clear all control & status registers */
+       i2c_read(CFG_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, &val, 1);
+       val = val & 0x7F;/*make sure we are running*/
+       i2c_write(CFG_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, &val, RTC_REG_CNT);
+
+       i2c_read(CFG_I2C_RTC_ADDR, RTC_CONTROL_ADDR, 1, &val, 1);
+       val = val & 0x3F;/*turn off freq test keep calibration*/
+       i2c_write(CFG_I2C_RTC_ADDR, RTC_CONTROL_ADDR, 1, &val, 1);
+}
+
+int rtc_store(int addr, unsigned char* data, int size)
+{
+       /*don't let things wrap onto the time on a write*/
+       if( (addr+size) >= M41T11_STORAGE_SZ )
+               return 1;
+       return i2c_write( CFG_I2C_RTC_ADDR, REG_CNT+addr, 1, data, size );
+}
+
+int rtc_recall(int addr, unsigned char* data, int size)
+{
+       return i2c_read( CFG_I2C_RTC_ADDR, REG_CNT+addr, 1, data, size );
+}
+
+#endif
diff --git a/drivers/rtc/m48t35ax.c b/drivers/rtc/m48t35ax.c
new file mode 100644 (file)
index 0000000..0a0ffa8
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen,  Wave 7 Optics, etheisen@mindspring.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support for ST Electronics M48T35Ax RTC
+ */
+
+/*#define       DEBUG */
+
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <config.h>
+
+#if defined(CONFIG_RTC_M48T35A) && defined(CONFIG_CMD_DATE)
+
+static uchar rtc_read  (uchar reg);
+static void  rtc_write (uchar reg, uchar val);
+static uchar bin2bcd   (unsigned int n);
+static unsigned bcd2bin(uchar c);
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+       uchar sec, min, hour, cent_day, date, month, year;
+       uchar ccr;                      /* Clock control register */
+
+       /* Lock RTC for read using clock control register */
+       ccr = rtc_read(0);
+       ccr = ccr | 0x40;
+       rtc_write(0, ccr);
+
+       sec     = rtc_read (0x1);
+       min     = rtc_read (0x2);
+       hour    = rtc_read (0x3);
+       cent_day= rtc_read (0x4);
+       date    = rtc_read (0x5);
+       month   = rtc_read (0x6);
+       year    = rtc_read (0x7);
+
+       /* UNLock RTC */
+       ccr = rtc_read(0);
+       ccr = ccr & 0xBF;
+       rtc_write(0, ccr);
+
+       debug ( "Get RTC year: %02x month: %02x date: %02x cent_day: %02x "
+               "hr: %02x min: %02x sec: %02x\n",
+               year, month, date, cent_day,
+               hour, min, sec );
+
+       tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+       tmp->tm_min  = bcd2bin (min  & 0x7F);
+       tmp->tm_hour = bcd2bin (hour & 0x3F);
+       tmp->tm_mday = bcd2bin (date & 0x3F);
+       tmp->tm_mon  = bcd2bin (month & 0x1F);
+       tmp->tm_year = bcd2bin (year) + ((cent_day & 0x10) ? 2000 : 1900);
+       tmp->tm_wday = bcd2bin (cent_day & 0x07);
+       tmp->tm_yday = 0;
+       tmp->tm_isdst= 0;
+
+       debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+       uchar ccr;                      /* Clock control register */
+       uchar century;
+
+       debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+       /* Lock RTC for write using clock control register */
+       ccr = rtc_read(0);
+       ccr = ccr | 0x80;
+       rtc_write(0, ccr);
+
+       rtc_write (0x07, bin2bcd(tmp->tm_year % 100));
+       rtc_write (0x06, bin2bcd(tmp->tm_mon));
+       rtc_write (0x05, bin2bcd(tmp->tm_mday));
+
+       century = ((tmp->tm_year >= 2000) ? 0x10 : 0) | 0x20;
+       rtc_write (0x04, bin2bcd(tmp->tm_wday) | century);
+
+       rtc_write (0x03, bin2bcd(tmp->tm_hour));
+       rtc_write (0x02, bin2bcd(tmp->tm_min ));
+       rtc_write (0x01, bin2bcd(tmp->tm_sec ));
+
+       /* UNLock RTC */
+       ccr = rtc_read(0);
+       ccr = ccr & 0x7F;
+       rtc_write(0, ccr);
+}
+
+void rtc_reset (void)
+{
+       uchar val;
+
+       /* Clear all clock control registers */
+       rtc_write (0x0, 0x80);          /* No Read Lock or calibration */
+
+       /* Clear stop bit */
+       val = rtc_read (0x1);
+       val &= 0x7f;
+       rtc_write(0x1, val);
+
+       /* Enable century / disable frequency test */
+       val = rtc_read (0x4);
+       val = (val & 0xBF) | 0x20;
+       rtc_write(0x4, val);
+
+       /* Clear write lock */
+       rtc_write(0x0, 0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read (uchar reg)
+{
+       uchar val;
+       val = *(unsigned char *)
+               ((CFG_NVRAM_BASE_ADDR + CFG_NVRAM_SIZE - 8) + reg);
+       return val;
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+       *(unsigned char *)
+               ((CFG_NVRAM_BASE_ADDR + CFG_NVRAM_SIZE - 8) + reg) = val;
+}
+
+static unsigned bcd2bin (uchar n)
+{
+       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+       return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/max6900.c b/drivers/rtc/max6900.c
new file mode 100644 (file)
index 0000000..c75a8e0
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * (C) Copyright 2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support for MAXIM MAX6900 RTC
+ */
+
+/* #define     DEBUG   */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_RTC_MAX6900) && defined(CONFIG_CMD_DATE)
+
+#ifndef        CFG_I2C_RTC_ADDR
+#define        CFG_I2C_RTC_ADDR        0x50
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read (uchar reg)
+{
+       return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+       i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+       udelay(2500);
+}
+
+static unsigned bcd2bin (uchar n)
+{
+       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+       return (((n / 10) << 4) | (n % 10));
+}
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+       uchar sec, min, hour, mday, wday, mon, cent, year;
+       int retry = 1;
+
+       do {
+               sec     = rtc_read (0x80);
+               min     = rtc_read (0x82);
+               hour    = rtc_read (0x84);
+               mday    = rtc_read (0x86);
+               mon     = rtc_read (0x88);
+               wday    = rtc_read (0x8a);
+               year    = rtc_read (0x8c);
+               cent    = rtc_read (0x92);
+               /*
+                * Check for seconds rollover
+                */
+               if ((sec != 59) || (rtc_read(0x80) == sec)){
+                       retry = 0;
+               }
+       } while (retry);
+
+       debug ( "Get RTC year: %02x mon: %02x cent: %02x mday: %02x wday: %02x "
+               "hr: %02x min: %02x sec: %02x\n",
+               year, mon, cent, mday, wday,
+               hour, min, sec );
+
+       tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+       tmp->tm_min  = bcd2bin (min  & 0x7F);
+       tmp->tm_hour = bcd2bin (hour & 0x3F);
+       tmp->tm_mday = bcd2bin (mday & 0x3F);
+       tmp->tm_mon  = bcd2bin (mon & 0x1F);
+       tmp->tm_year = bcd2bin (year) + bcd2bin(cent) * 100;
+       tmp->tm_wday = bcd2bin (wday & 0x07);
+       tmp->tm_yday = 0;
+       tmp->tm_isdst= 0;
+
+       debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+
+       debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+       rtc_write (0x9E, 0x00);
+       rtc_write (0x80, 0);    /* Clear seconds to ensure no rollover */
+       rtc_write (0x92, bin2bcd(tmp->tm_year / 100));
+       rtc_write (0x8c, bin2bcd(tmp->tm_year % 100));
+       rtc_write (0x8a, bin2bcd(tmp->tm_wday));
+       rtc_write (0x88, bin2bcd(tmp->tm_mon));
+       rtc_write (0x86, bin2bcd(tmp->tm_mday));
+       rtc_write (0x84, bin2bcd(tmp->tm_hour));
+       rtc_write (0x82, bin2bcd(tmp->tm_min ));
+       rtc_write (0x80, bin2bcd(tmp->tm_sec ));
+}
+
+void rtc_reset (void)
+{
+}
+
+#endif
diff --git a/drivers/rtc/mc146818.c b/drivers/rtc/mc146818.c
new file mode 100644 (file)
index 0000000..ab377ed
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter MPL AG Switzerland. d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support for the MC146818 (PIXX4) RTC
+ */
+
+/*#define      DEBUG*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_RTC_MC146818) && defined(CONFIG_CMD_DATE)
+
+static uchar rtc_read  (uchar reg);
+static void  rtc_write (uchar reg, uchar val);
+static uchar bin2bcd   (unsigned int n);
+static unsigned bcd2bin(uchar c);
+
+#define RTC_PORT_MC146818              CFG_ISA_IO_BASE_ADDRESS +  0x70
+#define RTC_SECONDS            0x00
+#define RTC_SECONDS_ALARM      0x01
+#define RTC_MINUTES                            0x02
+#define RTC_MINUTES_ALARM      0x03
+#define RTC_HOURS                                      0x04
+#define RTC_HOURS_ALARM                0x05
+#define RTC_DAY_OF_WEEK                0x06
+#define RTC_DATE_OF_MONTH      0x07
+#define RTC_MONTH                                      0x08
+#define RTC_YEAR                                               0x09
+#define RTC_CONFIG_A                           0x0A
+#define RTC_CONFIG_B                           0x0B
+#define RTC_CONFIG_C                           0x0C
+#define RTC_CONFIG_D                           0x0D
+
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+       uchar sec, min, hour, mday, wday, mon, year;
+  /* here check if rtc can be accessed */
+       while((rtc_read(RTC_CONFIG_A)&0x80)==0x80);
+       sec             = rtc_read (RTC_SECONDS);
+       min             = rtc_read (RTC_MINUTES);
+       hour    = rtc_read (RTC_HOURS);
+       mday    = rtc_read (RTC_DATE_OF_MONTH);
+       wday    = rtc_read (RTC_DAY_OF_WEEK);
+       mon             = rtc_read (RTC_MONTH);
+       year    = rtc_read (RTC_YEAR);
+#ifdef CONFIG_AMIGAONEG3SE
+       wday -= 1; /* VIA 686 stores Sunday = 1, Monday = 2, ... */
+#endif
+#ifdef RTC_DEBUG
+       printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+               "hr: %02x min: %02x sec: %02x\n",
+               year, mon, mday, wday,
+               hour, min, sec );
+       printf ( "Alarms: month: %02x hour: %02x min: %02x sec: %02x\n",
+               rtc_read (RTC_CONFIG_D) & 0x3F,
+               rtc_read (RTC_HOURS_ALARM),
+               rtc_read (RTC_MINUTES_ALARM),
+               rtc_read (RTC_SECONDS_ALARM) );
+#endif
+       tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+       tmp->tm_min  = bcd2bin (min  & 0x7F);
+       tmp->tm_hour = bcd2bin (hour & 0x3F);
+       tmp->tm_mday = bcd2bin (mday & 0x3F);
+       tmp->tm_mon  = bcd2bin (mon & 0x1F);
+       tmp->tm_year = bcd2bin (year);
+       tmp->tm_wday = bcd2bin (wday & 0x07);
+       if(tmp->tm_year<70)
+               tmp->tm_year+=2000;
+       else
+               tmp->tm_year+=1900;
+       tmp->tm_yday = 0;
+       tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+       printf ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+#ifdef RTC_DEBUG
+       printf ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+       rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */
+
+       rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100));
+       rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon));
+#ifdef CONFIG_AMIGAONEG3SE
+       rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday)+1);
+#else
+       rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday));
+#endif
+       rtc_write (RTC_DATE_OF_MONTH, bin2bcd(tmp->tm_mday));
+       rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour));
+       rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min ));
+       rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec ));
+       rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */
+
+}
+
+void rtc_reset (void)
+{
+       rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */
+       rtc_write(RTC_CONFIG_A,0x20); /* Normal OP */
+       rtc_write(RTC_CONFIG_B,0x00);
+       rtc_write(RTC_CONFIG_B,0x00);
+       rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */
+}
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CFG_RTC_REG_BASE_ADDR
+/*
+ * use direct memory access
+ */
+static uchar rtc_read (uchar reg)
+{
+       return(in8(CFG_RTC_REG_BASE_ADDR+reg));
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+       out8(CFG_RTC_REG_BASE_ADDR+reg, val);
+}
+#else
+static uchar rtc_read (uchar reg)
+{
+       out8(RTC_PORT_MC146818,reg);
+       return(in8(RTC_PORT_MC146818+1));
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+       out8(RTC_PORT_MC146818,reg);
+       out8(RTC_PORT_MC146818+1,val);
+}
+#endif
+
+static unsigned bcd2bin (uchar n)
+{
+       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+       return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/mcfrtc.c b/drivers/rtc/mcfrtc.c
new file mode 100644 (file)
index 0000000..27386e5
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
+ * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_MCFRTC) && defined(CONFIG_CMD_DATE)
+
+#include <command.h>
+#include <rtc.h>
+#include <asm/immap.h>
+#include <asm/rtc.h>
+
+#undef RTC_DEBUG
+
+#ifndef CFG_MCFRTC_BASE
+#error RTC_BASE is not defined!
+#endif
+
+#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
+#define        STARTOFTIME             1970
+
+void rtc_get(struct rtc_time *tmp)
+{
+       volatile rtc_t *rtc = (rtc_t *) (CFG_MCFRTC_BASE);
+
+       int rtc_days, rtc_hrs, rtc_mins;
+       int tim;
+
+       rtc_days = rtc->days;
+       rtc_hrs = rtc->hourmin >> 8;
+       rtc_mins = RTC_HOURMIN_MINUTES(rtc->hourmin);
+
+       tim = (rtc_days * 24) + rtc_hrs;
+       tim = (tim * 60) + rtc_mins;
+       tim = (tim * 60) + rtc->seconds;
+
+       to_tm(tim, tmp);
+
+       tmp->tm_yday = 0;
+       tmp->tm_isdst = 0;
+
+#ifdef RTC_DEBUG
+       printf("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+              tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+              tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+}
+
+void rtc_set(struct rtc_time *tmp)
+{
+       volatile rtc_t *rtc = (rtc_t *) (CFG_MCFRTC_BASE);
+
+       static int month_days[12] = {
+               31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+       };
+       int days, i, months;
+
+       if (tmp->tm_year > 2037) {
+               printf("Unable to handle. Exceeding integer limitation!\n");
+               tmp->tm_year = 2027;
+       }
+#ifdef RTC_DEBUG
+       printf("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+              tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+              tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+
+       /* calculate days by years */
+       for (i = STARTOFTIME, days = 0; i < tmp->tm_year; i++) {
+               days += 365 + isleap(i);
+       }
+
+       /* calculate days by months */
+       months = tmp->tm_mon - 1;
+       for (i = 0; i < months; i++) {
+               days += month_days[i];
+
+               if (i == 1)
+                       days += isleap(i);
+       }
+
+       days += tmp->tm_mday - 1;
+
+       rtc->days = days;
+       rtc->hourmin = (tmp->tm_hour << 8) | tmp->tm_min;
+       rtc->seconds = tmp->tm_sec;
+}
+
+void rtc_reset(void)
+{
+       volatile rtc_t *rtc = (rtc_t *) (CFG_MCFRTC_BASE);
+
+       if ((rtc->cr & RTC_CR_EN) == 0) {
+               printf("real-time-clock was stopped. Now starting...\n");
+               rtc->cr |= RTC_CR_EN;
+       }
+
+       rtc->cr |= RTC_CR_SWR;
+}
+
+#endif                         /* CONFIG_MCFRTC && CONFIG_CMD_DATE */
diff --git a/drivers/rtc/mk48t59.c b/drivers/rtc/mk48t59.c
new file mode 100644 (file)
index 0000000..bacdb5b
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support for the MK48T59 RTC
+ */
+
+#undef RTC_DEBUG
+
+#include <common.h>
+#include <command.h>
+#include <config.h>
+#include <rtc.h>
+#include <mk48t59.h>
+
+#if defined(CONFIG_RTC_MK48T59)
+
+#if defined(CONFIG_BAB7xx)
+
+static uchar rtc_read (short reg)
+{
+       out8(RTC_PORT_ADDR0, reg & 0xFF);
+       out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF);
+       return in8(RTC_PORT_DATA);
+}
+
+static void rtc_write (short reg, uchar val)
+{
+       out8(RTC_PORT_ADDR0, reg & 0xFF);
+       out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF);
+       out8(RTC_PORT_DATA, val);
+}
+
+#elif defined(CONFIG_PCIPPC2)
+
+#include "../board/pcippc2/pcippc2.h"
+
+static uchar rtc_read (short reg)
+{
+       return in8(RTC(reg));
+}
+
+static void rtc_write (short reg, uchar val)
+{
+       out8(RTC(reg),val);
+}
+
+#elif defined(CONFIG_AMIGAONEG3SE)
+
+#include "../board/MAI/AmigaOneG3SE/via686.h"
+#include "../board/MAI/AmigaOneG3SE/memio.h"
+
+
+static uchar rtc_read (short reg)
+{
+    out_byte(CMOS_ADDR, (uint8)reg);
+    return in_byte(CMOS_DATA);
+}
+
+static void rtc_write (short reg, uchar val)
+{
+    out_byte(CMOS_ADDR, (uint8)reg);
+    out_byte(CMOS_DATA, (uint8)val);
+}
+
+#elif defined(CONFIG_EVAL5200)
+
+static uchar rtc_read (short reg)
+{
+       return in8(RTC(reg));
+}
+
+static void rtc_write (short reg, uchar val)
+{
+       out8(RTC(reg),val);
+}
+
+#else
+# error Board specific rtc access functions should be supplied
+#endif
+
+static unsigned bcd2bin (uchar n)
+{
+       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+       return (((n / 10) << 4) | (n % 10));
+}
+
+/* ------------------------------------------------------------------------- */
+
+void *nvram_read(void *dest, const short src, size_t count)
+{
+       uchar *d = (uchar *) dest;
+       short s = src;
+
+       while (count--)
+               *d++ = rtc_read(s++);
+
+       return dest;
+}
+
+void nvram_write(short dest, const void *src, size_t count)
+{
+       short d = dest;
+       uchar *s = (uchar *) src;
+
+       while (count--)
+               rtc_write(d++, *s++);
+}
+
+#if defined(CONFIG_CMD_DATE)
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+       uchar save_ctrl_a;
+       uchar sec, min, hour, mday, wday, mon, year;
+
+       /* Simple: freeze the clock, read it and allow updates again */
+       save_ctrl_a = rtc_read(RTC_CONTROLA);
+
+       /* Set the register to read the value. */
+       save_ctrl_a |= RTC_CA_READ;
+       rtc_write(RTC_CONTROLA, save_ctrl_a);
+
+       sec             = rtc_read (RTC_SECONDS);
+       min             = rtc_read (RTC_MINUTES);
+       hour    = rtc_read (RTC_HOURS);
+       mday    = rtc_read (RTC_DAY_OF_MONTH);
+       wday    = rtc_read (RTC_DAY_OF_WEEK);
+       mon             = rtc_read (RTC_MONTH);
+       year    = rtc_read (RTC_YEAR);
+
+       /* re-enable update */
+       save_ctrl_a &= ~RTC_CA_READ;
+       rtc_write(RTC_CONTROLA, save_ctrl_a);
+
+#ifdef RTC_DEBUG
+       printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+               "hr: %02x min: %02x sec: %02x\n",
+               year, mon, mday, wday,
+               hour, min, sec );
+#endif
+       tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+       tmp->tm_min  = bcd2bin (min  & 0x7F);
+       tmp->tm_hour = bcd2bin (hour & 0x3F);
+       tmp->tm_mday = bcd2bin (mday & 0x3F);
+       tmp->tm_mon  = bcd2bin (mon & 0x1F);
+       tmp->tm_year = bcd2bin (year);
+       tmp->tm_wday = bcd2bin (wday & 0x07);
+       if(tmp->tm_year<70)
+               tmp->tm_year+=2000;
+       else
+               tmp->tm_year+=1900;
+       tmp->tm_yday = 0;
+       tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+       printf ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+       uchar save_ctrl_a;
+
+#ifdef RTC_DEBUG
+       printf ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+       save_ctrl_a = rtc_read(RTC_CONTROLA);
+
+       save_ctrl_a |= RTC_CA_WRITE;
+       rtc_write(RTC_CONTROLA, save_ctrl_a); /* disables the RTC to update the regs */
+
+       rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100));
+       rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon));
+
+       rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday));
+       rtc_write (RTC_DAY_OF_MONTH, bin2bcd(tmp->tm_mday));
+       rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour));
+       rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min ));
+       rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec ));
+
+       save_ctrl_a &= ~RTC_CA_WRITE;
+       rtc_write(RTC_CONTROLA, save_ctrl_a); /* enables the RTC to update the regs */
+}
+
+void rtc_reset (void)
+{
+       uchar control_b;
+
+       /*
+        * Start oscillator here.
+        */
+       control_b = rtc_read(RTC_CONTROLB);
+
+       control_b &= ~RTC_CB_STOP;
+       rtc_write(RTC_CONTROLB, control_b);
+}
+
+void rtc_set_watchdog(short multi, short res)
+{
+       uchar wd_value;
+
+       wd_value = RTC_WDS | ((multi & 0x1F) << 2) | (res & 0x3);
+       rtc_write(RTC_WATCHDOG, wd_value);
+}
+
+#endif
+#endif /* CONFIG_RTC_MK48T59 */
diff --git a/drivers/rtc/mpc5xxx.c b/drivers/rtc/mpc5xxx.c
new file mode 100644 (file)
index 0000000..216386a
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * (C) Copyright 2004
+ * Reinhard Meyer, EMK Elektronik GmbH
+ * r.meyer@emk-elektronik.de
+ * www.emk-elektronik.de
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*****************************************************************************
+ * Date & Time support for internal RTC of MPC52xx
+ *****************************************************************************/
+/*#define      DEBUG*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_RTC_MPC5200) && defined(CONFIG_CMD_DATE)
+
+/*****************************************************************************
+ * this structure should be defined in mpc5200.h ...
+ *****************************************************************************/
+typedef struct rtc5200 {
+       volatile ulong  tsr;    /* MBAR+0x800: time set register */
+       volatile ulong  dsr;    /* MBAR+0x804: data set register */
+       volatile ulong  nysr;   /* MBAR+0x808: new year and stopwatch register */
+       volatile ulong  aier;   /* MBAR+0x80C: alarm and interrupt enable register */
+       volatile ulong  ctr;    /* MBAR+0x810: current time register */
+       volatile ulong  cdr;    /* MBAR+0x814: current data register */
+       volatile ulong  asir;   /* MBAR+0x818: alarm and stopwatch interupt register */
+       volatile ulong  piber;  /* MBAR+0x81C: periodic interrupt and bus error register */
+       volatile ulong  trdr;   /* MBAR+0x820: test register/divides register */
+} RTC5200;
+
+#define        RTC_SET         0x02000000
+#define        RTC_PAUSE       0x01000000
+
+/*****************************************************************************
+ * get time
+ *****************************************************************************/
+void rtc_get (struct rtc_time *tmp)
+{
+       RTC5200 *rtc = (RTC5200 *) (CFG_MBAR+0x800);
+       ulong time, date, time2;
+
+       /* read twice to avoid getting a funny time when the second is just changing */
+       do {
+               time = rtc->ctr;
+               date = rtc->cdr;
+               time2 = rtc->ctr;
+       } while (time != time2);
+
+       tmp->tm_year    = date & 0xfff;
+       tmp->tm_mon             = (date >> 24) & 0xf;
+       tmp->tm_mday    = (date >> 16) & 0x1f;
+       tmp->tm_wday    = (date >> 21) & 7;
+       /* sunday is 7 in 5200 but 0 in rtc_time */
+       if (tmp->tm_wday == 7)
+               tmp->tm_wday = 0;
+       tmp->tm_hour    = (time >> 16) & 0x1f;
+       tmp->tm_min             = (time >> 8) & 0x3f;
+       tmp->tm_sec             = time & 0x3f;
+
+       debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+/*****************************************************************************
+ * set time
+ *****************************************************************************/
+void rtc_set (struct rtc_time *tmp)
+{
+       RTC5200 *rtc = (RTC5200 *) (CFG_MBAR+0x800);
+       ulong time, date, year;
+
+       debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+       time = (tmp->tm_hour << 16) | (tmp->tm_min << 8) | tmp->tm_sec;
+       date = (tmp->tm_mon << 16) | tmp->tm_mday;
+       if (tmp->tm_wday == 0)
+               date |= (7 << 8);
+       else
+               date |= (tmp->tm_wday << 8);
+       year = tmp->tm_year;
+
+       /* mask unwanted bits that might show up when rtc_time is corrupt */
+       time &= 0x001f3f3f;
+       date &= 0x001f071f;
+       year &= 0x00000fff;
+
+       /* pause and set the RTC */
+       rtc->nysr = year;
+       rtc->dsr = date | RTC_PAUSE;
+       udelay (1000);
+       rtc->dsr = date | RTC_PAUSE | RTC_SET;
+       udelay (1000);
+       rtc->dsr = date | RTC_PAUSE;
+       udelay (1000);
+       rtc->dsr = date;
+       udelay (1000);
+
+       rtc->tsr = time | RTC_PAUSE;
+       udelay (1000);
+       rtc->tsr = time | RTC_PAUSE | RTC_SET;
+       udelay (1000);
+       rtc->tsr = time | RTC_PAUSE;
+       udelay (1000);
+       rtc->tsr = time;
+       udelay (1000);
+}
+
+/*****************************************************************************
+ * reset rtc circuit
+ *****************************************************************************/
+void rtc_reset (void)
+{
+       return; /* nothing to do */
+}
+
+#endif
diff --git a/drivers/rtc/mpc8xx.c b/drivers/rtc/mpc8xx.c
new file mode 100644 (file)
index 0000000..8d10c0e
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support for internal RTC of MPC8xx
+ */
+
+/*#define      DEBUG*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_RTC_MPC8xx) && defined(CONFIG_CMD_DATE)
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+       volatile immap_t *immr = (immap_t *)CFG_IMMR;
+       ulong tim;
+
+       tim = immr->im_sit.sit_rtc;
+
+       to_tm (tim, tmp);
+
+       debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+       volatile immap_t *immr = (immap_t *)CFG_IMMR;
+       ulong tim;
+
+       debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+       tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
+                     tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+       immr->im_sitk.sitk_rtck = KAPWR_KEY;
+       immr->im_sit.sit_rtc = tim;
+}
+
+void rtc_reset (void)
+{
+       return; /* nothing to do */
+}
+
+#endif
diff --git a/drivers/rtc/pcf8563.c b/drivers/rtc/pcf8563.c
new file mode 100644 (file)
index 0000000..2d73d5d
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support for Philips PCF8563 RTC
+ */
+
+/* #define     DEBUG   */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_RTC_PCF8563) && defined(CONFIG_CMD_DATE)
+
+static uchar rtc_read  (uchar reg);
+static void  rtc_write (uchar reg, uchar val);
+static uchar bin2bcd   (unsigned int n);
+static unsigned bcd2bin(uchar c);
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+       uchar sec, min, hour, mday, wday, mon_cent, year;
+
+       sec     = rtc_read (0x02);
+       min     = rtc_read (0x03);
+       hour    = rtc_read (0x04);
+       mday    = rtc_read (0x05);
+       wday    = rtc_read (0x06);
+       mon_cent= rtc_read (0x07);
+       year    = rtc_read (0x08);
+
+       debug ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+               "hr: %02x min: %02x sec: %02x\n",
+               year, mon_cent, mday, wday,
+               hour, min, sec );
+       debug ( "Alarms: wday: %02x day: %02x hour: %02x min: %02x\n",
+               rtc_read (0x0C),
+               rtc_read (0x0B),
+               rtc_read (0x0A),
+               rtc_read (0x09) );
+
+       if (sec & 0x80) {
+               puts ("### Warning: RTC Low Voltage - date/time not reliable\n");
+       }
+
+       tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+       tmp->tm_min  = bcd2bin (min  & 0x7F);
+       tmp->tm_hour = bcd2bin (hour & 0x3F);
+       tmp->tm_mday = bcd2bin (mday & 0x3F);
+       tmp->tm_mon  = bcd2bin (mon_cent & 0x1F);
+       tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900);
+       tmp->tm_wday = bcd2bin (wday & 0x07);
+       tmp->tm_yday = 0;
+       tmp->tm_isdst= 0;
+
+       debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+       uchar century;
+
+       debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+       rtc_write (0x08, bin2bcd(tmp->tm_year % 100));
+
+       century = (tmp->tm_year >= 2000) ? 0x80 : 0;
+       rtc_write (0x07, bin2bcd(tmp->tm_mon) | century);
+
+       rtc_write (0x06, bin2bcd(tmp->tm_wday));
+       rtc_write (0x05, bin2bcd(tmp->tm_mday));
+       rtc_write (0x04, bin2bcd(tmp->tm_hour));
+       rtc_write (0x03, bin2bcd(tmp->tm_min ));
+       rtc_write (0x02, bin2bcd(tmp->tm_sec ));
+}
+
+void rtc_reset (void)
+{
+       /* clear all control & status registers */
+       rtc_write (0x00, 0x00);
+       rtc_write (0x01, 0x00);
+       rtc_write (0x0D, 0x00);
+
+       /* clear Voltage Low bit */
+       rtc_write (0x02, rtc_read (0x02) & 0x7F);
+
+       /* reset all alarms */
+       rtc_write (0x09, 0x00);
+       rtc_write (0x0A, 0x00);
+       rtc_write (0x0B, 0x00);
+       rtc_write (0x0C, 0x00);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read (uchar reg)
+{
+       return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+       i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+}
+
+static unsigned bcd2bin (uchar n)
+{
+       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+       return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/rs5c372.c b/drivers/rtc/rs5c372.c
new file mode 100644 (file)
index 0000000..3d1346e
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * rs5c372.c
+ *
+ * Device driver for Ricoh's Real Time Controller RS5C372A.
+ *
+ * Copyright (C) 2004 Gary Jennejohn garyj@denx.de
+ *
+ * Based in part in ds1307.c -
+ * (C) Copyright 2001, 2002, 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.com`
+ * Steven Scholz, steven.scholz@imc-berlin.de
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_RTC_RS5C372A) && defined(CONFIG_CMD_DATE)
+/*
+ * Reads are always done starting with register 15, which requires some
+ * jumping-through-hoops to access the data correctly.
+ *
+ * Writes are always done starting with register 0.
+ */
+
+#define DEBUG 0
+
+#if DEBUG
+static unsigned int rtc_debug = DEBUG;
+#else
+#define rtc_debug 0    /* gcc will remove all the debug code for us */
+#endif
+
+#ifndef CFG_I2C_RTC_ADDR
+#define CFG_I2C_RTC_ADDR 0x32
+#endif
+
+#define RS5C372_RAM_SIZE 0x10
+#define RATE_32000HZ   0x80    /* Rate Select 32.000KHz */
+#define RATE_32768HZ   0x00    /* Rate Select 32.768KHz */
+
+#define STATUS_XPT  0x10    /* data invalid because voltage was 0 */
+
+#define USE_24HOUR_MODE 0x20
+#define TWELVE_HOUR_MODE(n) ((((n) >> 5) & 1) == 0)
+#define HOURS_AP(n)    (((n) >> 5) & 1)
+#define HOURS_12(n)    bcd2bin((n) & 0x1F)
+#define HOURS_24(n)    bcd2bin((n) & 0x3F)
+
+
+static uchar bin2bcd (unsigned int n);
+static unsigned bcd2bin (uchar c);
+
+static int setup_done = 0;
+
+static int
+rs5c372_readram(unsigned char *buf, int len)
+{
+       int ret;
+
+       ret = i2c_read(CFG_I2C_RTC_ADDR, 0, 0, buf, len);
+       if (ret != 0) {
+               printf("%s: failed to read\n", __FUNCTION__);
+               return ret;
+       }
+
+       if (buf[0] & STATUS_XPT)
+               printf("### Warning: RTC lost power\n");
+
+       return ret;
+}
+
+static void
+rs5c372_enable(void)
+{
+       unsigned char buf[RS5C372_RAM_SIZE + 1];
+       int ret;
+
+       /* note that this returns reg. 15 in buf[1] */
+       ret = rs5c372_readram(&buf[1], RS5C372_RAM_SIZE);
+       if (ret != 0) {
+               printf("%s: failed\n", __FUNCTION__);
+               return;
+       }
+
+       buf[0] = 0;
+       /* we want to start writing at register 0 so we have to copy the */
+       /* register contents up one slot */
+       for (ret = 2; ret < 9; ret++)
+               buf[ret - 1] = buf[ret];
+       /* registers 0 to 6 (time values) are not touched */
+       buf[8] = RATE_32768HZ; /* reg. 7 */
+       buf[9] = 0; /* reg. 8 */
+       buf[10] = 0; /* reg. 9 */
+       buf[11] = 0; /* reg. 10 */
+       buf[12] = 0; /* reg. 11 */
+       buf[13] = 0; /* reg. 12 */
+       buf[14] = 0; /* reg. 13 */
+       buf[15] = 0; /* reg. 14 */
+       buf[16] = USE_24HOUR_MODE; /* reg. 15 */
+       ret = i2c_write(CFG_I2C_RTC_ADDR, 0, 0, buf, RS5C372_RAM_SIZE+1);
+       if (ret != 0) {
+               printf("%s: failed\n", __FUNCTION__);
+               return;
+       }
+       setup_done = 1;
+
+       return;
+}
+
+static void
+rs5c372_convert_to_time(struct rtc_time *dt, unsigned char *buf)
+{
+       /* buf[0] is register 15 */
+       dt->tm_sec = bcd2bin(buf[1]);
+       dt->tm_min = bcd2bin(buf[2]);
+
+       if (TWELVE_HOUR_MODE(buf[0])) {
+               dt->tm_hour = HOURS_12(buf[3]);
+               if (HOURS_AP(buf[3])) /* PM */
+                       dt->tm_hour += 12;
+       } else /* 24-hour-mode */
+               dt->tm_hour = HOURS_24(buf[3]);
+
+       dt->tm_mday = bcd2bin(buf[5]);
+       dt->tm_mon = bcd2bin(buf[6]);
+       dt->tm_year = bcd2bin(buf[7]);
+       if (dt->tm_year >= 70)
+               dt->tm_year += 1900;
+       else
+               dt->tm_year += 2000;
+       /* 0 is Sunday */
+       dt->tm_wday = bcd2bin(buf[4] & 0x07);
+       dt->tm_yday = 0;
+       dt->tm_isdst= 0;
+
+       if(rtc_debug > 2) {
+               printf("rs5c372_convert_to_time: year = %d\n", dt->tm_year);
+               printf("rs5c372_convert_to_time: mon  = %d\n", dt->tm_mon);
+               printf("rs5c372_convert_to_time: mday = %d\n", dt->tm_mday);
+               printf("rs5c372_convert_to_time: hour = %d\n", dt->tm_hour);
+               printf("rs5c372_convert_to_time: min  = %d\n", dt->tm_min);
+               printf("rs5c372_convert_to_time: sec  = %d\n", dt->tm_sec);
+       }
+}
+
+/*
+ * Get the current time from the RTC
+ */
+void
+rtc_get (struct rtc_time *tmp)
+{
+       unsigned char buf[RS5C372_RAM_SIZE];
+       int ret;
+
+       if (!setup_done)
+               rs5c372_enable();
+
+       if (!setup_done)
+               return;
+
+       memset(buf, 0, sizeof(buf));
+
+       /* note that this returns reg. 15 in buf[0] */
+       ret = rs5c372_readram(buf, RS5C372_RAM_SIZE);
+       if (ret != 0) {
+               printf("%s: failed\n", __FUNCTION__);
+               return;
+       }
+
+       rs5c372_convert_to_time(tmp, buf);
+
+       return;
+}
+
+/*
+ * Set the RTC
+ */
+void
+rtc_set (struct rtc_time *tmp)
+{
+       unsigned char buf[8], reg15;
+       int ret;
+
+       if (!setup_done)
+               rs5c372_enable();
+
+       if (!setup_done)
+               return;
+
+       if(rtc_debug > 2) {
+               printf("rtc_set: tm_year = %d\n", tmp->tm_year);
+               printf("rtc_set: tm_mon  = %d\n", tmp->tm_mon);
+               printf("rtc_set: tm_mday = %d\n", tmp->tm_mday);
+               printf("rtc_set: tm_hour = %d\n", tmp->tm_hour);
+               printf("rtc_set: tm_min  = %d\n", tmp->tm_min);
+               printf("rtc_set: tm_sec  = %d\n", tmp->tm_sec);
+       }
+
+       memset(buf, 0, sizeof(buf));
+
+       /* only read register 15 */
+       ret = i2c_read(CFG_I2C_RTC_ADDR, 0, 0, buf, 1);
+
+       if (ret == 0) {
+               /* need to save register 15 */
+               reg15 = buf[0];
+               buf[0] = 0;     /* register address on RS5C372 */
+               buf[1] = bin2bcd(tmp->tm_sec);
+               buf[2] = bin2bcd(tmp->tm_min);
+               /* need to handle 12 hour mode */
+               if (TWELVE_HOUR_MODE(reg15)) {
+                       if (tmp->tm_hour >= 12) { /* PM */
+                               /* 12 PM is a special case */
+                               if (tmp->tm_hour == 12)
+                                       buf[3] = bin2bcd(tmp->tm_hour);
+                               else
+                                       buf[3] = bin2bcd(tmp->tm_hour - 12);
+                               buf[3] |= 0x20;
+                       }
+               } else {
+                       buf[3] = bin2bcd(tmp->tm_hour);
+               }
+
+               buf[4] = bin2bcd(tmp->tm_wday);
+               buf[5] = bin2bcd(tmp->tm_mday);
+               buf[6] = bin2bcd(tmp->tm_mon);
+               if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
+                       printf("WARNING: year should be between 1970 and 2069!\n");
+               buf[7] = bin2bcd(tmp->tm_year % 100);
+
+               ret = i2c_write(CFG_I2C_RTC_ADDR, 0, 0, buf, 8);
+               if (ret != 0)
+                       printf("rs5c372_set_datetime(), i2c_master_send() returned %d\n",ret);
+       }
+
+       return;
+}
+
+/*
+ * Reset the RTC. We set the date back to 1970-01-01.
+ */
+void
+rtc_reset (void)
+{
+       struct rtc_time tmp;
+
+       if (!setup_done)
+               rs5c372_enable();
+
+       if (!setup_done)
+               return;
+
+       tmp.tm_year = 1970;
+       tmp.tm_mon = 1;
+       /* Jan. 1, 1970 was a Thursday */
+       tmp.tm_wday= 4;
+       tmp.tm_mday= 1;
+       tmp.tm_hour = 0;
+       tmp.tm_min = 0;
+       tmp.tm_sec = 0;
+
+       rtc_set(&tmp);
+
+       printf ("RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC\n",
+               tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
+               tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
+
+       return;
+}
+
+static unsigned int
+bcd2bin (unsigned char n)
+{
+       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char
+bin2bcd (unsigned int n)
+{
+       return (((n / 10) << 4) | (n % 10));
+}
+#endif
diff --git a/drivers/rtc/s3c24x0_rtc.c b/drivers/rtc/s3c24x0_rtc.c
new file mode 100644 (file)
index 0000000..7f8b4fa
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * (C) Copyright 2003
+ * David Müller ELSOFT AG Switzerland. d.mueller@elsoft.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support for the built-in Samsung S3C24X0 RTC
+ */
+
+#include <common.h>
+#include <command.h>
+
+#if defined(CONFIG_RTC_S3C24X0) && (defined(CONFIG_CMD_DATE))
+
+#if defined(CONFIG_S3C2400)
+#include <s3c2400.h>
+#elif defined(CONFIG_S3C2410)
+#include <s3c2410.h>
+#endif
+
+#include <rtc.h>
+
+/*#define      DEBUG*/
+
+typedef enum {
+       RTC_ENABLE,
+       RTC_DISABLE
+} RTC_ACCESS;
+
+
+static inline void SetRTC_Access(RTC_ACCESS a)
+{
+       S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
+       switch (a) {
+               case RTC_ENABLE:
+                       rtc->RTCCON |= 0x01; break;
+
+               case RTC_DISABLE:
+                       rtc->RTCCON &= ~0x01; break;
+       }
+}
+
+static unsigned bcd2bin (uchar n)
+{
+       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+       return (((n / 10) << 4) | (n % 10));
+}
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+       S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
+       uchar sec, min, hour, mday, wday, mon, year;
+       uchar a_sec,a_min, a_hour, a_date, a_mon, a_year, a_armed;
+
+       /* enable access to RTC registers */
+       SetRTC_Access(RTC_ENABLE);
+
+       /* read RTC registers */
+       do {
+               sec     = rtc->BCDSEC;
+               min     = rtc->BCDMIN;
+               hour    = rtc->BCDHOUR;
+               mday    = rtc->BCDDATE;
+               wday    = rtc->BCDDAY;
+               mon     = rtc->BCDMON;
+               year    = rtc->BCDYEAR;
+       } while (sec != rtc->BCDSEC);
+
+       /* read ALARM registers */
+       a_sec   = rtc->ALMSEC;
+       a_min   = rtc->ALMMIN;
+       a_hour  = rtc->ALMHOUR;
+       a_date  = rtc->ALMDATE;
+       a_mon   = rtc->ALMMON;
+       a_year  = rtc->ALMYEAR;
+       a_armed = rtc->RTCALM;
+
+       /* disable access to RTC registers */
+       SetRTC_Access(RTC_DISABLE);
+
+#ifdef RTC_DEBUG
+       printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+               "hr: %02x min: %02x sec: %02x\n",
+               year, mon, mday, wday,
+               hour, min, sec);
+       printf ( "Alarms: %02x: year: %02x month: %02x date: %02x hour: %02x min: %02x sec: %02x\n",
+               a_armed,
+               a_year, a_mon, a_date,
+               a_hour, a_min, a_sec);
+#endif
+
+       tmp->tm_sec  = bcd2bin(sec  & 0x7F);
+       tmp->tm_min  = bcd2bin(min  & 0x7F);
+       tmp->tm_hour = bcd2bin(hour & 0x3F);
+       tmp->tm_mday = bcd2bin(mday & 0x3F);
+       tmp->tm_mon  = bcd2bin(mon & 0x1F);
+       tmp->tm_year = bcd2bin(year);
+       tmp->tm_wday = bcd2bin(wday & 0x07);
+       if(tmp->tm_year<70)
+               tmp->tm_year+=2000;
+       else
+               tmp->tm_year+=1900;
+       tmp->tm_yday = 0;
+       tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+       printf ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+       S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
+       uchar sec, min, hour, mday, wday, mon, year;
+
+#ifdef RTC_DEBUG
+       printf ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+       year    = bin2bcd(tmp->tm_year % 100);
+       mon     = bin2bcd(tmp->tm_mon);
+       wday    = bin2bcd(tmp->tm_wday);
+       mday    = bin2bcd(tmp->tm_mday);
+       hour    = bin2bcd(tmp->tm_hour);
+       min     = bin2bcd(tmp->tm_min);
+       sec     = bin2bcd(tmp->tm_sec);
+
+       /* enable access to RTC registers */
+       SetRTC_Access(RTC_ENABLE);
+
+       /* write RTC registers */
+       rtc->BCDSEC     = sec;
+       rtc->BCDMIN     = min;
+       rtc->BCDHOUR    = hour;
+       rtc->BCDDATE    = mday;
+       rtc->BCDDAY     = wday;
+       rtc->BCDMON     = mon;
+       rtc->BCDYEAR    = year;
+
+       /* disable access to RTC registers */
+       SetRTC_Access(RTC_DISABLE);
+}
+
+void rtc_reset (void)
+{
+       S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
+
+       rtc->RTCCON = (rtc->RTCCON & ~0x06) | 0x08;
+       rtc->RTCCON &= ~(0x08|0x01);
+}
+
+#endif
diff --git a/drivers/rtl8019.c b/drivers/rtl8019.c
deleted file mode 100644 (file)
index 409a69f..0000000
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Realtek 8019AS Ethernet
- * (C) Copyright 2002-2003
- * Xue Ligong(lgxue@hotmail.com),Wang Kehao, ESLAB, whut.edu.cn
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * This code works in 8bit mode.
- * If you need to work in 16bit mode, PLS change it!
- */
-
-#include <common.h>
-#include <command.h>
-#include "rtl8019.h"
-#include <net.h>
-
-#ifdef CONFIG_DRIVER_RTL8019
-
-#if defined(CONFIG_CMD_NET)
-
-
-/* packet page register access functions */
-
-
-static unsigned char get_reg (unsigned int regno)
-{
-       return (*(unsigned char *) regno);
-}
-
-
-static void put_reg (unsigned int regno, unsigned char val)
-{
-       *(volatile unsigned char *) regno = val;
-}
-
-static void eth_reset (void)
-{
-       unsigned char ucTemp;
-
-       /* reset NIC */
-       ucTemp = get_reg (RTL8019_RESET);
-       put_reg (RTL8019_RESET, ucTemp);
-       put_reg (RTL8019_INTERRUPTSTATUS, 0xff);
-       udelay (2000);          /* wait for 2ms */
-}
-
-void rtl8019_get_enetaddr (uchar * addr)
-{
-       unsigned char i;
-       unsigned char temp;
-
-       eth_reset ();
-
-       put_reg (RTL8019_COMMAND, RTL8019_REMOTEDMARD);
-       put_reg (RTL8019_DATACONFIGURATION, 0x48);
-       put_reg (RTL8019_REMOTESTARTADDRESS0, 0x00);
-       put_reg (RTL8019_REMOTESTARTADDRESS1, 0x00);
-       put_reg (RTL8019_REMOTEBYTECOUNT0, 12);
-       put_reg (RTL8019_REMOTEBYTECOUNT1, 0x00);
-       put_reg (RTL8019_COMMAND, RTL8019_REMOTEDMARD);
-       printf ("MAC: ");
-       for (i = 0; i < 6; i++) {
-               temp = get_reg (RTL8019_DMA_DATA);
-               *addr++ = temp;
-               temp = get_reg (RTL8019_DMA_DATA);
-               printf ("%x:", temp);
-       }
-
-       while ((!get_reg (RTL8019_INTERRUPTSTATUS) & 0x40));
-       printf ("\b \n");
-       put_reg (RTL8019_REMOTEBYTECOUNT0, 0x00);
-       put_reg (RTL8019_REMOTEBYTECOUNT1, 0x00);
-       put_reg (RTL8019_COMMAND, RTL8019_PAGE0);
-}
-
-
-void eth_halt (void)
-{
-       put_reg (RTL8019_COMMAND, 0x01);
-}
-
-int eth_init (bd_t * bd)
-{
-       eth_reset ();
-       put_reg (RTL8019_COMMAND, RTL8019_PAGE0STOP);
-       put_reg (RTL8019_DATACONFIGURATION, 0x48);
-       put_reg (RTL8019_REMOTEBYTECOUNT0, 0x00);
-       put_reg (RTL8019_REMOTEBYTECOUNT1, 0x00);
-       put_reg (RTL8019_RECEIVECONFIGURATION, 0x00);   /*00; */
-       put_reg (RTL8019_TRANSMITPAGE, RTL8019_TPSTART);
-       put_reg (RTL8019_TRANSMITCONFIGURATION, 0x02);
-       put_reg (RTL8019_PAGESTART, RTL8019_PSTART);
-       put_reg (RTL8019_BOUNDARY, RTL8019_PSTART);
-       put_reg (RTL8019_PAGESTOP, RTL8019_PSTOP);
-       put_reg (RTL8019_INTERRUPTSTATUS, 0xff);
-       put_reg (RTL8019_INTERRUPTMASK, 0x11);  /*b; */
-       put_reg (RTL8019_COMMAND, RTL8019_PAGE1STOP);
-       put_reg (RTL8019_PHYSICALADDRESS0, bd->bi_enetaddr[0]);
-       put_reg (RTL8019_PHYSICALADDRESS1, bd->bi_enetaddr[1]);
-       put_reg (RTL8019_PHYSICALADDRESS2, bd->bi_enetaddr[2]);
-       put_reg (RTL8019_PHYSICALADDRESS3, bd->bi_enetaddr[3]);
-       put_reg (RTL8019_PHYSICALADDRESS4, bd->bi_enetaddr[4]);
-       put_reg (RTL8019_PHYSICALADDRESS5, bd->bi_enetaddr[5]);
-       put_reg (RTL8019_MULTIADDRESS0, 0x00);
-       put_reg (RTL8019_MULTIADDRESS1, 0x00);
-       put_reg (RTL8019_MULTIADDRESS2, 0x00);
-       put_reg (RTL8019_MULTIADDRESS3, 0x00);
-       put_reg (RTL8019_MULTIADDRESS4, 0x00);
-       put_reg (RTL8019_MULTIADDRESS5, 0x00);
-       put_reg (RTL8019_MULTIADDRESS6, 0x00);
-       put_reg (RTL8019_MULTIADDRESS7, 0x00);
-       put_reg (RTL8019_CURRENT, RTL8019_PSTART);
-       put_reg (RTL8019_COMMAND, RTL8019_PAGE0);
-       put_reg (RTL8019_TRANSMITCONFIGURATION, 0xe0);  /*58; */
-
-       return 0;
-}
-
-
-static unsigned char nic_to_pc (void)
-{
-       unsigned char rec_head_status;
-       unsigned char next_packet_pointer;
-       unsigned char packet_length0;
-       unsigned char packet_length1;
-       unsigned short rxlen = 0;
-       unsigned int i = 4;
-       unsigned char current_point;
-       unsigned char *addr;
-
-       /*
-        * The RTL8019's first 4B is packet status,page of next packet
-        * and packet length(2B).So we receive the fist 4B.
-        */
-       put_reg (RTL8019_REMOTESTARTADDRESS1, get_reg (RTL8019_BOUNDARY));
-       put_reg (RTL8019_REMOTESTARTADDRESS0, 0x00);
-       put_reg (RTL8019_REMOTEBYTECOUNT1, 0x00);
-       put_reg (RTL8019_REMOTEBYTECOUNT0, 0x04);
-
-       put_reg (RTL8019_COMMAND, RTL8019_REMOTEDMARD);
-
-       rec_head_status = get_reg (RTL8019_DMA_DATA);
-       next_packet_pointer = get_reg (RTL8019_DMA_DATA);
-       packet_length0 = get_reg (RTL8019_DMA_DATA);
-       packet_length1 = get_reg (RTL8019_DMA_DATA);
-
-       put_reg (RTL8019_COMMAND, RTL8019_PAGE0);
-       /*Packet length is in two 8bit registers */
-       rxlen = packet_length1;
-       rxlen = (((rxlen << 8) & 0xff00) + packet_length0);
-       rxlen -= 4;
-
-       if (rxlen > PKTSIZE_ALIGN + PKTALIGN)
-               printf ("packet too big!\n");
-
-       /*Receive the packet */
-       put_reg (RTL8019_REMOTESTARTADDRESS0, 0x04);
-       put_reg (RTL8019_REMOTESTARTADDRESS1, get_reg (RTL8019_BOUNDARY));
-
-       put_reg (RTL8019_REMOTEBYTECOUNT0, (rxlen & 0xff));
-       put_reg (RTL8019_REMOTEBYTECOUNT1, ((rxlen >> 8) & 0xff));
-
-
-       put_reg (RTL8019_COMMAND, RTL8019_REMOTEDMARD);
-
-       for (addr = (unsigned char *) NetRxPackets[0], i = rxlen; i > 0; i--)
-               *addr++ = get_reg (RTL8019_DMA_DATA);
-       /* Pass the packet up to the protocol layers. */
-       NetReceive (NetRxPackets[0], rxlen);
-
-       while (!(get_reg (RTL8019_INTERRUPTSTATUS)) & 0x40);    /* wait for the op. */
-
-       /*
-        * To test whether the packets are all received,get the
-        * location of current point
-        */
-       put_reg (RTL8019_COMMAND, RTL8019_PAGE1);
-       current_point = get_reg (RTL8019_CURRENT);
-       put_reg (RTL8019_COMMAND, RTL8019_PAGE0);
-       put_reg (RTL8019_BOUNDARY, next_packet_pointer);
-       return current_point;
-}
-
-/* Get a data block via Ethernet */
-extern int eth_rx (void)
-{
-       unsigned char temp, current_point;
-
-       put_reg (RTL8019_COMMAND, RTL8019_PAGE0);
-
-       while (1) {
-               temp = get_reg (RTL8019_INTERRUPTSTATUS);
-
-               if (temp & 0x90) {
-                       /*overflow */
-                       put_reg (RTL8019_COMMAND, RTL8019_PAGE0STOP);
-                       udelay (2000);
-                       put_reg (RTL8019_REMOTEBYTECOUNT0, 0);
-                       put_reg (RTL8019_REMOTEBYTECOUNT1, 0);
-                       put_reg (RTL8019_TRANSMITCONFIGURATION, 2);
-                       do {
-                               current_point = nic_to_pc ();
-                       } while (get_reg (RTL8019_BOUNDARY) != current_point);
-
-                       put_reg (RTL8019_TRANSMITCONFIGURATION, 0xe0);
-               }
-
-               if (temp & 0x1) {
-                       /*packet received */
-                       do {
-                               put_reg (RTL8019_INTERRUPTSTATUS, 0x01);
-                               current_point = nic_to_pc ();
-                       } while (get_reg (RTL8019_BOUNDARY) != current_point);
-               }
-
-               if (!(temp & 0x1))
-                       return 0;
-               /* done and exit. */
-       }
-}
-
-/* Send a data block via Ethernet. */
-extern int eth_send (volatile void *packet, int length)
-{
-       volatile unsigned char *p;
-       unsigned int pn;
-
-       pn = length;
-       p = (volatile unsigned char *) packet;
-
-       while (get_reg (RTL8019_COMMAND) == RTL8019_TRANSMIT);
-
-       put_reg (RTL8019_REMOTESTARTADDRESS0, 0);
-       put_reg (RTL8019_REMOTESTARTADDRESS1, RTL8019_TPSTART);
-       put_reg (RTL8019_REMOTEBYTECOUNT0, (pn & 0xff));
-       put_reg (RTL8019_REMOTEBYTECOUNT1, ((pn >> 8) & 0xff));
-
-       put_reg (RTL8019_COMMAND, RTL8019_REMOTEDMAWR);
-       while (pn > 0) {
-               put_reg (RTL8019_DMA_DATA, *p++);
-               pn--;
-       }
-
-       pn = length;
-
-       while (pn < 60) {       /*Padding */
-               put_reg (RTL8019_DMA_DATA, 0);
-               pn++;
-       }
-
-       while (!(get_reg (RTL8019_INTERRUPTSTATUS)) & 0x40);
-
-       put_reg (RTL8019_INTERRUPTSTATUS, 0x40);
-       put_reg (RTL8019_TRANSMITPAGE, RTL8019_TPSTART);
-       put_reg (RTL8019_TRANSMITBYTECOUNT0, (pn & 0xff));
-       put_reg (RTL8019_TRANSMITBYTECOUNT1, ((pn >> 8 & 0xff)));
-       put_reg (RTL8019_COMMAND, RTL8019_TRANSMIT);
-
-       return 0;
-}
-
-#endif /* COMMANDS & CFG_NET */
-
-#endif /* CONFIG_DRIVER_RTL8019 */
diff --git a/drivers/rtl8019.h b/drivers/rtl8019.h
deleted file mode 100644 (file)
index 38116ad..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Realtek 8019AS Ethernet
- * (C) Copyright 2002-2003
- * Xue Ligong(lgxue@hotmail.com),Wang Kehao, ESLAB, whut.edu.cn
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * This code works in 8bit mode.
- * If you need to work in 16bit mode, PLS change it!
- */
-
-#include <asm/types.h>
-#include <config.h>
-
-
-#ifdef CONFIG_DRIVER_RTL8019
-
-#define                RTL8019_REG_00                  (RTL8019_BASE + 0x00)
-#define        RTL8019_REG_01                  (RTL8019_BASE + 0x01)
-#define        RTL8019_REG_02                  (RTL8019_BASE + 0x02)
-#define        RTL8019_REG_03                  (RTL8019_BASE + 0x03)
-#define        RTL8019_REG_04                  (RTL8019_BASE + 0x04)
-#define        RTL8019_REG_05                  (RTL8019_BASE + 0x05)
-#define        RTL8019_REG_06                  (RTL8019_BASE + 0x06)
-#define        RTL8019_REG_07                  (RTL8019_BASE + 0x07)
-#define        RTL8019_REG_08                  (RTL8019_BASE + 0x08)
-#define        RTL8019_REG_09                  (RTL8019_BASE + 0x09)
-#define        RTL8019_REG_0a                  (RTL8019_BASE + 0x0a)
-#define        RTL8019_REG_0b                  (RTL8019_BASE + 0x0b)
-#define        RTL8019_REG_0c                  (RTL8019_BASE + 0x0c)
-#define        RTL8019_REG_0d                  (RTL8019_BASE + 0x0d)
-#define        RTL8019_REG_0e                  (RTL8019_BASE + 0x0e)
-#define        RTL8019_REG_0f                  (RTL8019_BASE + 0x0f)
-#define        RTL8019_REG_10                  (RTL8019_BASE + 0x10)
-#define        RTL8019_REG_1f                  (RTL8019_BASE + 0x1f)
-
-#define                RTL8019_COMMAND                 RTL8019_REG_00
-#define                RTL8019_PAGESTART               RTL8019_REG_01
-#define                RTL8019_PAGESTOP                RTL8019_REG_02
-#define                RTL8019_BOUNDARY                RTL8019_REG_03
-#define                RTL8019_TRANSMITSTATUS          RTL8019_REG_04
-#define                RTL8019_TRANSMITPAGE            RTL8019_REG_04
-#define                RTL8019_TRANSMITBYTECOUNT0      RTL8019_REG_05
-#define                RTL8019_NCR                     RTL8019_REG_05
-#define                RTL8019_TRANSMITBYTECOUNT1      RTL8019_REG_06
-#define                RTL8019_INTERRUPTSTATUS         RTL8019_REG_07
-#define                RTL8019_CURRENT                 RTL8019_REG_07
-#define                RTL8019_REMOTESTARTADDRESS0     RTL8019_REG_08
-#define                RTL8019_CRDMA0                  RTL8019_REG_08
-#define                RTL8019_REMOTESTARTADDRESS1     RTL8019_REG_09
-#define                RTL8019_CRDMA1                  RTL8019_REG_09
-#define                RTL8019_REMOTEBYTECOUNT0        RTL8019_REG_0a
-#define                RTL8019_REMOTEBYTECOUNT1        RTL8019_REG_0b
-#define                RTL8019_RECEIVESTATUS           RTL8019_REG_0c
-#define                RTL8019_RECEIVECONFIGURATION    RTL8019_REG_0c
-#define                RTL8019_TRANSMITCONFIGURATION   RTL8019_REG_0d
-#define                RTL8019_FAE_TALLY               RTL8019_REG_0d
-#define                RTL8019_DATACONFIGURATION       RTL8019_REG_0e
-#define                RTL8019_CRC_TALLY               RTL8019_REG_0e
-#define                RTL8019_INTERRUPTMASK           RTL8019_REG_0f
-#define                RTL8019_MISS_PKT_TALLY          RTL8019_REG_0f
-#define                RTL8019_PHYSICALADDRESS0        RTL8019_REG_01
-#define        RTL8019_PHYSICALADDRESS1        RTL8019_REG_02
-#define                RTL8019_PHYSICALADDRESS2        RTL8019_REG_03
-#define                RTL8019_PHYSICALADDRESS3        RTL8019_REG_04
-#define                RTL8019_PHYSICALADDRESS4        RTL8019_REG_05
-#define                RTL8019_PHYSICALADDRESS5        RTL8019_REG_06
-#define                RTL8019_MULTIADDRESS0           RTL8019_REG_08
-#define                RTL8019_MULTIADDRESS1           RTL8019_REG_09
-#define                RTL8019_MULTIADDRESS2           RTL8019_REG_0a
-#define                RTL8019_MULTIADDRESS3           RTL8019_REG_0b
-#define                RTL8019_MULTIADDRESS4           RTL8019_REG_0c
-#define                RTL8019_MULTIADDRESS5           RTL8019_REG_0d
-#define                RTL8019_MULTIADDRESS6           RTL8019_REG_0e
-#define                RTL8019_MULTIADDRESS7           RTL8019_REG_0f
-#define                RTL8019_DMA_DATA                RTL8019_REG_10
-#define                RTL8019_RESET                   RTL8019_REG_1f
-
-
-#define        RTL8019_PAGE0                   0x22
-#define        RTL8019_PAGE1                   0x62
-#define        RTL8019_PAGE0DMAWRITE           0x12
-#define        RTL8019_PAGE2DMAWRITE           0x92
-#define        RTL8019_REMOTEDMAWR             0x12
-#define        RTL8019_REMOTEDMARD             0x0A
-#define        RTL8019_ABORTDMAWR              0x32
-#define        RTL8019_ABORTDMARD              0x2A
-#define        RTL8019_PAGE0STOP               0x21
-#define        RTL8019_PAGE1STOP               0x61
-#define        RTL8019_TRANSMIT                0x26
-#define        RTL8019_TXINPROGRESS            0x04
-#define        RTL8019_SEND                    0x1A
-
-#define                RTL8019_PSTART                  0x4c
-#define                RTL8019_PSTOP                   0x80
-#define                RTL8019_TPSTART                 0x40
-
-
-#endif /*end of CONFIG_DRIVER_RTL8019*/
diff --git a/drivers/rtl8139.c b/drivers/rtl8139.c
deleted file mode 100644 (file)
index 2367180..0000000
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * rtl8139.c : U-Boot driver for the RealTek RTL8139
- *
- * Masami Komiya (mkomiya@sonare.it)
- *
- * Most part is taken from rtl8139.c of etherboot
- *
- */
-
-/* rtl8139.c - etherboot driver for the Realtek 8139 chipset
-
-  ported from the linux driver written by Donald Becker
-  by Rainer Bawidamann (Rainer.Bawidamann@informatik.uni-ulm.de) 1999
-
-  This software may be used and distributed according to the terms
-  of the GNU Public License, incorporated herein by reference.
-
-  changes to the original driver:
-  - removed support for interrupts, switching to polling mode (yuck!)
-  - removed support for the 8129 chip (external MII)
-
-*/
-
-/*********************************************************************/
-/* Revision History                                                 */
-/*********************************************************************/
-
-/*
-  28 Dec 2002  ken_yap@users.sourceforge.net (Ken Yap)
-     Put in virt_to_bus calls to allow Etherboot relocation.
-
-  06 Apr 2001  ken_yap@users.sourceforge.net (Ken Yap)
-     Following email from Hyun-Joon Cha, added a disable routine, otherwise
-     NIC remains live and can crash the kernel later.
-
-  4 Feb 2000   espenlaub@informatik.uni-ulm.de (Klaus Espenlaub)
-     Shuffled things around, removed the leftovers from the 8129 support
-     that was in the Linux driver and added a bit more 8139 definitions.
-     Moved the 8K receive buffer to a fixed, available address outside the
-     0x98000-0x9ffff range.  This is a bit of a hack, but currently the only
-     way to make room for the Etherboot features that need substantial amounts
-     of code like the ANSI console support.  Currently the buffer is just below
-     0x10000, so this even conforms to the tagged boot image specification,
-     which reserves the ranges 0x00000-0x10000 and 0x98000-0xA0000.  My
-     interpretation of this "reserved" is that Etherboot may do whatever it
-     likes, as long as its environment is kept intact (like the BIOS
-     variables).  Hopefully fixed rtl_poll() once and for all. The symptoms
-     were that if Etherboot was left at the boot menu for several minutes, the
-     first eth_poll failed.  Seems like I am the only person who does this.
-     First of all I fixed the debugging code and then set out for a long bug
-     hunting session.  It took me about a week full time work - poking around
-     various places in the driver, reading Don Becker's and Jeff Garzik's Linux
-     driver and even the FreeBSD driver (what a piece of crap!) - and
-     eventually spotted the nasty thing: the transmit routine was acknowledging
-     each and every interrupt pending, including the RxOverrun and RxFIFIOver
-     interrupts.  This confused the RTL8139 thoroughly.         It destroyed the
-     Rx ring contents by dumping the 2K FIFO contents right where we wanted to
-     get the next packet.  Oh well, what fun.
-
-  18 Jan 2000  mdc@thinguin.org (Marty Connor)
-     Drastically simplified error handling.  Basically, if any error
-     in transmission or reception occurs, the card is reset.
-     Also, pointed all transmit descriptors to the same buffer to
-     save buffer space.         This should decrease driver size and avoid
-     corruption because of exceeding 32K during runtime.
-
-  28 Jul 1999  (Matthias Meixner - meixner@rbg.informatik.tu-darmstadt.de)
-     rtl_poll was quite broken: it used the RxOK interrupt flag instead
-     of the RxBufferEmpty flag which often resulted in very bad
-     transmission performace - below 1kBytes/s.
-
-*/
-
-#include <common.h>
-#include <malloc.h>
-#include <net.h>
-#include <asm/io.h>
-#include <pci.h>
-
-#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
-       defined(CONFIG_RTL8139)
-
-#define TICKS_PER_SEC  CFG_HZ
-#define TICKS_PER_MS   (TICKS_PER_SEC/1000)
-
-#define RTL_TIMEOUT    (1*TICKS_PER_SEC)
-
-#define ETH_FRAME_LEN          1514
-#define ETH_ALEN               6
-#define ETH_ZLEN               60
-
-/* PCI Tuning Parameters
-   Threshold is bytes transferred to chip before transmission starts. */
-#define TX_FIFO_THRESH 256     /* In bytes, rounded down to 32 byte units. */
-#define RX_FIFO_THRESH 4       /* Rx buffer level before first PCI xfer.  */
-#define RX_DMA_BURST   4       /* Maximum PCI burst, '4' is 256 bytes */
-#define TX_DMA_BURST   4       /* Calculate as 16<<val. */
-#define NUM_TX_DESC    4       /* Number of Tx descriptor registers. */
-#define TX_BUF_SIZE    ETH_FRAME_LEN   /* FCS is added by the chip */
-#define RX_BUF_LEN_IDX 0       /* 0, 1, 2 is allowed - 8,16,32K rx buffer */
-#define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX)
-
-#undef DEBUG_TX
-#undef DEBUG_RX
-
-#define currticks()    get_timer(0)
-#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a)
-#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
-
-/* Symbolic offsets to registers. */
-enum RTL8139_registers {
-       MAC0=0,                 /* Ethernet hardware address. */
-       MAR0=8,                 /* Multicast filter. */
-       TxStatus0=0x10,         /* Transmit status (four 32bit registers). */
-       TxAddr0=0x20,           /* Tx descriptors (also four 32bit). */
-       RxBuf=0x30, RxEarlyCnt=0x34, RxEarlyStatus=0x36,
-       ChipCmd=0x37, RxBufPtr=0x38, RxBufAddr=0x3A,
-       IntrMask=0x3C, IntrStatus=0x3E,
-       TxConfig=0x40, RxConfig=0x44,
-       Timer=0x48,             /* general-purpose counter. */
-       RxMissed=0x4C,          /* 24 bits valid, write clears. */
-       Cfg9346=0x50, Config0=0x51, Config1=0x52,
-       TimerIntrReg=0x54,      /* intr if gp counter reaches this value */
-       MediaStatus=0x58,
-       Config3=0x59,
-       MultiIntr=0x5C,
-       RevisionID=0x5E,        /* revision of the RTL8139 chip */
-       TxSummary=0x60,
-       MII_BMCR=0x62, MII_BMSR=0x64, NWayAdvert=0x66, NWayLPAR=0x68,
-       NWayExpansion=0x6A,
-       DisconnectCnt=0x6C, FalseCarrierCnt=0x6E,
-       NWayTestReg=0x70,
-       RxCnt=0x72,             /* packet received counter */
-       CSCR=0x74,              /* chip status and configuration register */
-       PhyParm1=0x78,TwisterParm=0x7c,PhyParm2=0x80,   /* undocumented */
-       /* from 0x84 onwards are a number of power management/wakeup frame
-        * definitions we will probably never need to know about.  */
-};
-
-enum ChipCmdBits {
-       CmdReset=0x10, CmdRxEnb=0x08, CmdTxEnb=0x04, RxBufEmpty=0x01, };
-
-/* Interrupt register bits, using my own meaningful names. */
-enum IntrStatusBits {
-       PCIErr=0x8000, PCSTimeout=0x4000, CableLenChange= 0x2000,
-       RxFIFOOver=0x40, RxUnderrun=0x20, RxOverflow=0x10,
-       TxErr=0x08, TxOK=0x04, RxErr=0x02, RxOK=0x01,
-};
-enum TxStatusBits {
-       TxHostOwns=0x2000, TxUnderrun=0x4000, TxStatOK=0x8000,
-       TxOutOfWindow=0x20000000, TxAborted=0x40000000,
-       TxCarrierLost=0x80000000,
-};
-enum RxStatusBits {
-       RxMulticast=0x8000, RxPhysical=0x4000, RxBroadcast=0x2000,
-       RxBadSymbol=0x0020, RxRunt=0x0010, RxTooLong=0x0008, RxCRCErr=0x0004,
-       RxBadAlign=0x0002, RxStatusOK=0x0001,
-};
-
-enum MediaStatusBits {
-       MSRTxFlowEnable=0x80, MSRRxFlowEnable=0x40, MSRSpeed10=0x08,
-       MSRLinkFail=0x04, MSRRxPauseFlag=0x02, MSRTxPauseFlag=0x01,
-};
-
-enum MIIBMCRBits {
-       BMCRReset=0x8000, BMCRSpeed100=0x2000, BMCRNWayEnable=0x1000,
-       BMCRRestartNWay=0x0200, BMCRDuplex=0x0100,
-};
-
-enum CSCRBits {
-       CSCR_LinkOKBit=0x0400, CSCR_LinkChangeBit=0x0800,
-       CSCR_LinkStatusBits=0x0f000, CSCR_LinkDownOffCmd=0x003c0,
-       CSCR_LinkDownCmd=0x0f3c0,
-};
-
-/* Bits in RxConfig. */
-enum rx_mode_bits {
-       RxCfgWrap=0x80,
-       AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0x08,
-       AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01,
-};
-
-static int ioaddr;
-static unsigned int cur_rx,cur_tx;
-
-/* The RTL8139 can only transmit from a contiguous, aligned memory block.  */
-static unsigned char tx_buffer[TX_BUF_SIZE] __attribute__((aligned(4)));
-static unsigned char rx_ring[RX_BUF_LEN+16] __attribute__((aligned(4)));
-
-static int rtl8139_probe(struct eth_device *dev, bd_t *bis);
-static int read_eeprom(int location, int addr_len);
-static void rtl_reset(struct eth_device *dev);
-static int rtl_transmit(struct eth_device *dev, volatile void *packet, int length);
-static int rtl_poll(struct eth_device *dev);
-static void rtl_disable(struct eth_device *dev);
-#ifdef CONFIG_MCAST_TFTP/*  This driver already accepts all b/mcast */
-static int rtl_bcast_addr (struct eth_device *dev, u8 bcast_mac, u8 set)
-{
-       return (0);
-}
-#endif
-
-static struct pci_device_id supported[] = {
-       {PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139},
-       {PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_8139},
-       {}
-};
-
-int rtl8139_initialize(bd_t *bis)
-{
-       pci_dev_t devno;
-       int card_number = 0;
-       struct eth_device *dev;
-       u32 iobase;
-       int idx=0;
-
-       while(1){
-               /* Find RTL8139 */
-               if ((devno = pci_find_devices(supported, idx++)) < 0)
-                       break;
-
-               pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase);
-               iobase &= ~0xf;
-
-               debug ("rtl8139: REALTEK RTL8139 @0x%x\n", iobase);
-
-               dev = (struct eth_device *)malloc(sizeof *dev);
-
-               sprintf (dev->name, "RTL8139#%d", card_number);
-
-               dev->priv = (void *) devno;
-               dev->iobase = (int)bus_to_phys(iobase);
-               dev->init = rtl8139_probe;
-               dev->halt = rtl_disable;
-               dev->send = rtl_transmit;
-               dev->recv = rtl_poll;
-#ifdef CONFIG_MCAST_TFTP
-               dev->mcast = rtl_bcast_addr;
-#endif
-
-               eth_register (dev);
-
-               card_number++;
-
-               pci_write_config_byte (devno, PCI_LATENCY_TIMER, 0x20);
-
-               udelay (10 * 1000);
-       }
-
-       return card_number;
-}
-
-static int rtl8139_probe(struct eth_device *dev, bd_t *bis)
-{
-       int i;
-       int speed10, fullduplex;
-       int addr_len;
-       unsigned short *ap = (unsigned short *)dev->enetaddr;
-
-       ioaddr = dev->iobase;
-
-       /* Bring the chip out of low-power mode. */
-       outb(0x00, ioaddr + Config1);
-
-       addr_len = read_eeprom(0,8) == 0x8129 ? 8 : 6;
-       for (i = 0; i < 3; i++)
-               *ap++ = le16_to_cpu (read_eeprom(i + 7, addr_len));
-
-       speed10 = inb(ioaddr + MediaStatus) & MSRSpeed10;
-       fullduplex = inw(ioaddr + MII_BMCR) & BMCRDuplex;
-
-       rtl_reset(dev);
-
-       if (inb(ioaddr + MediaStatus) & MSRLinkFail) {
-               printf("Cable not connected or other link failure\n");
-               return(0);
-       }
-
-       return 1;
-}
-
-/* Serial EEPROM section. */
-
-/*  EEPROM_Ctrl bits. */
-#define EE_SHIFT_CLK   0x04    /* EEPROM shift clock. */
-#define EE_CS          0x08    /* EEPROM chip select. */
-#define EE_DATA_WRITE  0x02    /* EEPROM chip data in. */
-#define EE_WRITE_0     0x00
-#define EE_WRITE_1     0x02
-#define EE_DATA_READ   0x01    /* EEPROM chip data out. */
-#define EE_ENB         (0x80 | EE_CS)
-
-/*
-       Delay between EEPROM clock transitions.
-       No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
-*/
-
-#define eeprom_delay() inl(ee_addr)
-
-/* The EEPROM commands include the alway-set leading bit. */
-#define EE_WRITE_CMD   (5)
-#define EE_READ_CMD    (6)
-#define EE_ERASE_CMD   (7)
-
-static int read_eeprom(int location, int addr_len)
-{
-       int i;
-       unsigned int retval = 0;
-       long ee_addr = ioaddr + Cfg9346;
-       int read_cmd = location | (EE_READ_CMD << addr_len);
-
-       outb(EE_ENB & ~EE_CS, ee_addr);
-       outb(EE_ENB, ee_addr);
-       eeprom_delay();
-
-       /* Shift the read command bits out. */
-       for (i = 4 + addr_len; i >= 0; i--) {
-               int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
-               outb(EE_ENB | dataval, ee_addr);
-               eeprom_delay();
-               outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
-               eeprom_delay();
-       }
-       outb(EE_ENB, ee_addr);
-       eeprom_delay();
-
-       for (i = 16; i > 0; i--) {
-               outb(EE_ENB | EE_SHIFT_CLK, ee_addr);
-               eeprom_delay();
-               retval = (retval << 1) | ((inb(ee_addr) & EE_DATA_READ) ? 1 : 0);
-               outb(EE_ENB, ee_addr);
-               eeprom_delay();
-       }
-
-       /* Terminate the EEPROM access. */
-       outb(~EE_CS, ee_addr);
-       eeprom_delay();
-       return retval;
-}
-
-static const unsigned int rtl8139_rx_config =
-       (RX_BUF_LEN_IDX << 11) |
-       (RX_FIFO_THRESH << 13) |
-       (RX_DMA_BURST << 8);
-
-static void set_rx_mode(struct eth_device *dev) {
-       unsigned int mc_filter[2];
-       int rx_mode;
-       /* !IFF_PROMISC */
-       rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
-       mc_filter[1] = mc_filter[0] = 0xffffffff;
-
-       outl(rtl8139_rx_config | rx_mode, ioaddr + RxConfig);
-
-       outl(mc_filter[0], ioaddr + MAR0 + 0);
-       outl(mc_filter[1], ioaddr + MAR0 + 4);
-}
-
-static void rtl_reset(struct eth_device *dev)
-{
-       int i;
-
-       outb(CmdReset, ioaddr + ChipCmd);
-
-       cur_rx = 0;
-       cur_tx = 0;
-
-       /* Give the chip 10ms to finish the reset. */
-       for (i=0; i<100; ++i){
-               if ((inb(ioaddr + ChipCmd) & CmdReset) == 0) break;
-               udelay (100); /* wait 100us */
-       }
-
-
-       for (i = 0; i < ETH_ALEN; i++)
-               outb(dev->enetaddr[i], ioaddr + MAC0 + i);
-
-       /* Must enable Tx/Rx before setting transfer thresholds! */
-       outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
-       outl((RX_FIFO_THRESH<<13) | (RX_BUF_LEN_IDX<<11) | (RX_DMA_BURST<<8),
-               ioaddr + RxConfig);             /* accept no frames yet!  */
-       outl((TX_DMA_BURST<<8)|0x03000000, ioaddr + TxConfig);
-
-       /* The Linux driver changes Config1 here to use a different LED pattern
-        * for half duplex or full/autodetect duplex (for full/autodetect, the
-        * outputs are TX/RX, Link10/100, FULL, while for half duplex it uses
-        * TX/RX, Link100, Link10).  This is messy, because it doesn't match
-        * the inscription on the mounting bracket.  It should not be changed
-        * from the configuration EEPROM default, because the card manufacturer
-        * should have set that to match the card.  */
-
-#ifdef DEBUG_RX
-       printf("rx ring address is %X\n",(unsigned long)rx_ring);
-#endif
-       outl(phys_to_bus((int)rx_ring), ioaddr + RxBuf);
-
-       /* If we add multicast support, the MAR0 register would have to be
-        * initialized to 0xffffffffffffffff (two 32 bit accesses).  Etherboot
-        * only needs broadcast (for ARP/RARP/BOOTP/DHCP) and unicast.  */
-
-       outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
-
-       outl(rtl8139_rx_config, ioaddr + RxConfig);
-
-       /* Start the chip's Tx and Rx process. */
-       outl(0, ioaddr + RxMissed);
-
-       /* set_rx_mode */
-       set_rx_mode(dev);
-
-       /* Disable all known interrupts by setting the interrupt mask. */
-       outw(0, ioaddr + IntrMask);
-}
-
-static int rtl_transmit(struct eth_device *dev, volatile void *packet, int length)
-{
-       unsigned int status, to;
-       unsigned long txstatus;
-       unsigned int len = length;
-
-       ioaddr = dev->iobase;
-
-       memcpy((char *)tx_buffer, (char *)packet, (int)length);
-
-#ifdef DEBUG_TX
-       printf("sending %d bytes\n", len);
-#endif
-
-       /* Note: RTL8139 doesn't auto-pad, send minimum payload (another 4
-        * bytes are sent automatically for the FCS, totalling to 64 bytes). */
-       while (len < ETH_ZLEN) {
-               tx_buffer[len++] = '\0';
-       }
-
-       outl(phys_to_bus((int)tx_buffer), ioaddr + TxAddr0 + cur_tx*4);
-       outl(((TX_FIFO_THRESH<<11) & 0x003f0000) | len,
-               ioaddr + TxStatus0 + cur_tx*4);
-
-       to = currticks() + RTL_TIMEOUT;
-
-       do {
-               status = inw(ioaddr + IntrStatus);
-               /* Only acknlowledge interrupt sources we can properly handle
-                * here - the RxOverflow/RxFIFOOver MUST be handled in the
-                * rtl_poll() function.  */
-               outw(status & (TxOK | TxErr | PCIErr), ioaddr + IntrStatus);
-               if ((status & (TxOK | TxErr | PCIErr)) != 0) break;
-       } while (currticks() < to);
-
-       txstatus = inl(ioaddr + TxStatus0 + cur_tx*4);
-
-       if (status & TxOK) {
-               cur_tx = (cur_tx + 1) % NUM_TX_DESC;
-#ifdef DEBUG_TX
-               printf("tx done (%d ticks), status %hX txstatus %X\n",
-                       to-currticks(), status, txstatus);
-#endif
-               return length;
-       } else {
-#ifdef DEBUG_TX
-               printf("tx timeout/error (%d ticks), status %hX txstatus %X\n",
-                       currticks()-to, status, txstatus);
-#endif
-               rtl_reset(dev);
-
-               return 0;
-       }
-}
-
-static int rtl_poll(struct eth_device *dev)
-{
-       unsigned int status;
-       unsigned int ring_offs;
-       unsigned int rx_size, rx_status;
-       int length=0;
-
-       ioaddr = dev->iobase;
-
-       if (inb(ioaddr + ChipCmd) & RxBufEmpty) {
-               return 0;
-       }
-
-       status = inw(ioaddr + IntrStatus);
-       /* See below for the rest of the interrupt acknowledges.  */
-       outw(status & ~(RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus);
-
-#ifdef DEBUG_RX
-       printf("rtl_poll: int %hX ", status);
-#endif
-
-       ring_offs = cur_rx % RX_BUF_LEN;
-       rx_status = *(unsigned int*)KSEG1ADDR((rx_ring + ring_offs));
-       rx_size = rx_status >> 16;
-       rx_status &= 0xffff;
-
-       if ((rx_status & (RxBadSymbol|RxRunt|RxTooLong|RxCRCErr|RxBadAlign)) ||
-           (rx_size < ETH_ZLEN) || (rx_size > ETH_FRAME_LEN + 4)) {
-               printf("rx error %hX\n", rx_status);
-               rtl_reset(dev); /* this clears all interrupts still pending */
-               return 0;
-       }
-
-       /* Received a good packet */
-       length = rx_size - 4;   /* no one cares about the FCS */
-       if (ring_offs+4+rx_size-4 > RX_BUF_LEN) {
-               int semi_count = RX_BUF_LEN - ring_offs - 4;
-               unsigned char rxdata[RX_BUF_LEN];
-
-               memcpy(rxdata, rx_ring + ring_offs + 4, semi_count);
-               memcpy(&(rxdata[semi_count]), rx_ring, rx_size-4-semi_count);
-
-               NetReceive(rxdata, length);
-#ifdef DEBUG_RX
-               printf("rx packet %d+%d bytes", semi_count,rx_size-4-semi_count);
-#endif
-       } else {
-               NetReceive(rx_ring + ring_offs + 4, length);
-#ifdef DEBUG_RX
-               printf("rx packet %d bytes", rx_size-4);
-#endif
-       }
-
-       cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
-       outw(cur_rx - 16, ioaddr + RxBufPtr);
-       /* See RTL8139 Programming Guide V0.1 for the official handling of
-        * Rx overflow situations.  The document itself contains basically no
-        * usable information, except for a few exception handling rules.  */
-       outw(status & (RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus);
-       return length;
-}
-
-static void rtl_disable(struct eth_device *dev)
-{
-       int i;
-
-       ioaddr = dev->iobase;
-
-       /* reset the chip */
-       outb(CmdReset, ioaddr + ChipCmd);
-
-       /* Give the chip 10ms to finish the reset. */
-       for (i=0; i<100; ++i){
-               if ((inb(ioaddr + ChipCmd) & CmdReset) == 0) break;
-               udelay (100); /* wait 100us */
-       }
-}
-#endif
diff --git a/drivers/rtl8169.c b/drivers/rtl8169.c
deleted file mode 100644 (file)
index 63ea2cc..0000000
+++ /dev/null
@@ -1,888 +0,0 @@
-/*
- * rtl8169.c : U-Boot driver for the RealTek RTL8169
- *
- * Masami Komiya (mkomiya@sonare.it)
- *
- * Most part is taken from r8169.c of etherboot
- *
- */
-
-/**************************************************************************
-*    r8169.c: Etherboot device driver for the RealTek RTL-8169 Gigabit
-*    Written 2003 by Timothy Legge <tlegge@rogers.com>
-*
-*    This program is free software; you can redistribute it and/or modify
-*    it under the terms of the GNU General Public License as published by
-*    the Free Software Foundation; either version 2 of the License, or
-*    (at your option) any later version.
-*
-*    This program is distributed in the hope that it will be useful,
-*    but WITHOUT ANY WARRANTY; without even the implied warranty of
-*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*    GNU General Public License for more details.
-*
-*    You should have received a copy of the GNU General Public License
-*    along with this program; if not, write to the Free Software
-*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-*    Portions of this code based on:
-*      r8169.c: A RealTek RTL-8169 Gigabit Ethernet driver
-*              for Linux kernel 2.4.x.
-*
-*    Written 2002 ShuChen <shuchen@realtek.com.tw>
-*        See Linux Driver for full information
-*
-*    Linux Driver Version 1.27a, 10.02.2002
-*
-*    Thanks to:
-*      Jean Chen of RealTek Semiconductor Corp. for
-*      providing the evaluation NIC used to develop
-*      this driver.  RealTek's support for Etherboot
-*      is appreciated.
-*
-*    REVISION HISTORY:
-*    ================
-*
-*    v1.0      11-26-2003      timlegge        Initial port of Linux driver
-*    v1.5      01-17-2004      timlegge        Initial driver output cleanup
-*
-*    Indent Options: indent -kr -i8
-***************************************************************************/
-
-#include <common.h>
-#include <malloc.h>
-#include <net.h>
-#include <asm/io.h>
-#include <pci.h>
-
-#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
-       defined(CONFIG_RTL8169)
-
-#undef DEBUG_RTL8169
-#undef DEBUG_RTL8169_TX
-#undef DEBUG_RTL8169_RX
-
-#define drv_version "v1.5"
-#define drv_date "01-17-2004"
-
-static u32 ioaddr;
-
-/* Condensed operations for readability. */
-#define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
-#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
-
-#define currticks()    get_timer(0)
-#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a)
-#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
-
-/* media options */
-#define MAX_UNITS 8
-static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
-
-/* MAC address length*/
-#define MAC_ADDR_LEN   6
-
-/* max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4).*/
-#define MAX_ETH_FRAME_SIZE     1536
-
-#define TX_FIFO_THRESH 256     /* In bytes */
-
-#define RX_FIFO_THRESH 7       /* 7 means NO threshold, Rx buffer level before first PCI xfer.  */
-#define RX_DMA_BURST   6       /* Maximum PCI burst, '6' is 1024 */
-#define TX_DMA_BURST   6       /* Maximum PCI burst, '6' is 1024 */
-#define EarlyTxThld    0x3F    /* 0x3F means NO early transmit */
-#define RxPacketMaxSize 0x0800 /* Maximum size supported is 16K-1 */
-#define InterFrameGap  0x03    /* 3 means InterFrameGap = the shortest one */
-
-#define NUM_TX_DESC    1       /* Number of Tx descriptor registers */
-#define NUM_RX_DESC    4       /* Number of Rx descriptor registers */
-#define RX_BUF_SIZE    1536    /* Rx Buffer size */
-#define RX_BUF_LEN     8192
-
-#define RTL_MIN_IO_SIZE 0x80
-#define TX_TIMEOUT  (6*HZ)
-
-/* write/read MMIO register */
-#define RTL_W8(reg, val8)      writeb ((val8), ioaddr + (reg))
-#define RTL_W16(reg, val16)    writew ((val16), ioaddr + (reg))
-#define RTL_W32(reg, val32)    writel ((val32), ioaddr + (reg))
-#define RTL_R8(reg)            readb (ioaddr + (reg))
-#define RTL_R16(reg)           readw (ioaddr + (reg))
-#define RTL_R32(reg)           ((unsigned long) readl (ioaddr + (reg)))
-
-#define ETH_FRAME_LEN  MAX_ETH_FRAME_SIZE
-#define ETH_ALEN       MAC_ADDR_LEN
-#define ETH_ZLEN       60
-
-enum RTL8169_registers {
-       MAC0 = 0,               /* Ethernet hardware address. */
-       MAR0 = 8,               /* Multicast filter. */
-       TxDescStartAddr = 0x20,
-       TxHDescStartAddr = 0x28,
-       FLASH = 0x30,
-       ERSR = 0x36,
-       ChipCmd = 0x37,
-       TxPoll = 0x38,
-       IntrMask = 0x3C,
-       IntrStatus = 0x3E,
-       TxConfig = 0x40,
-       RxConfig = 0x44,
-       RxMissed = 0x4C,
-       Cfg9346 = 0x50,
-       Config0 = 0x51,
-       Config1 = 0x52,
-       Config2 = 0x53,
-       Config3 = 0x54,
-       Config4 = 0x55,
-       Config5 = 0x56,
-       MultiIntr = 0x5C,
-       PHYAR = 0x60,
-       TBICSR = 0x64,
-       TBI_ANAR = 0x68,
-       TBI_LPAR = 0x6A,
-       PHYstatus = 0x6C,
-       RxMaxSize = 0xDA,
-       CPlusCmd = 0xE0,
-       RxDescStartAddr = 0xE4,
-       EarlyTxThres = 0xEC,
-       FuncEvent = 0xF0,
-       FuncEventMask = 0xF4,
-       FuncPresetState = 0xF8,
-       FuncForceEvent = 0xFC,
-};
-
-enum RTL8169_register_content {
-       /*InterruptStatusBits */
-       SYSErr = 0x8000,
-       PCSTimeout = 0x4000,
-       SWInt = 0x0100,
-       TxDescUnavail = 0x80,
-       RxFIFOOver = 0x40,
-       RxUnderrun = 0x20,
-       RxOverflow = 0x10,
-       TxErr = 0x08,
-       TxOK = 0x04,
-       RxErr = 0x02,
-       RxOK = 0x01,
-
-       /*RxStatusDesc */
-       RxRES = 0x00200000,
-       RxCRC = 0x00080000,
-       RxRUNT = 0x00100000,
-       RxRWT = 0x00400000,
-
-       /*ChipCmdBits */
-       CmdReset = 0x10,
-       CmdRxEnb = 0x08,
-       CmdTxEnb = 0x04,
-       RxBufEmpty = 0x01,
-
-       /*Cfg9346Bits */
-       Cfg9346_Lock = 0x00,
-       Cfg9346_Unlock = 0xC0,
-
-       /*rx_mode_bits */
-       AcceptErr = 0x20,
-       AcceptRunt = 0x10,
-       AcceptBroadcast = 0x08,
-       AcceptMulticast = 0x04,
-       AcceptMyPhys = 0x02,
-       AcceptAllPhys = 0x01,
-
-       /*RxConfigBits */
-       RxCfgFIFOShift = 13,
-       RxCfgDMAShift = 8,
-
-       /*TxConfigBits */
-       TxInterFrameGapShift = 24,
-       TxDMAShift = 8,         /* DMA burst value (0-7) is shift this many bits */
-
-       /*rtl8169_PHYstatus */
-       TBI_Enable = 0x80,
-       TxFlowCtrl = 0x40,
-       RxFlowCtrl = 0x20,
-       _1000bpsF = 0x10,
-       _100bps = 0x08,
-       _10bps = 0x04,
-       LinkStatus = 0x02,
-       FullDup = 0x01,
-
-       /*GIGABIT_PHY_registers */
-       PHY_CTRL_REG = 0,
-       PHY_STAT_REG = 1,
-       PHY_AUTO_NEGO_REG = 4,
-       PHY_1000_CTRL_REG = 9,
-
-       /*GIGABIT_PHY_REG_BIT */
-       PHY_Restart_Auto_Nego = 0x0200,
-       PHY_Enable_Auto_Nego = 0x1000,
-
-       /* PHY_STAT_REG = 1; */
-       PHY_Auto_Neco_Comp = 0x0020,
-
-       /* PHY_AUTO_NEGO_REG = 4; */
-       PHY_Cap_10_Half = 0x0020,
-       PHY_Cap_10_Full = 0x0040,
-       PHY_Cap_100_Half = 0x0080,
-       PHY_Cap_100_Full = 0x0100,
-
-       /* PHY_1000_CTRL_REG = 9; */
-       PHY_Cap_1000_Full = 0x0200,
-
-       PHY_Cap_Null = 0x0,
-
-       /*_MediaType*/
-       _10_Half = 0x01,
-       _10_Full = 0x02,
-       _100_Half = 0x04,
-       _100_Full = 0x08,
-       _1000_Full = 0x10,
-
-       /*_TBICSRBit*/
-       TBILinkOK = 0x02000000,
-};
-
-static struct {
-       const char *name;
-       u8 version;             /* depend on RTL8169 docs */
-       u32 RxConfigMask;       /* should clear the bits supported by this chip */
-} rtl_chip_info[] = {
-       {"RTL-8169", 0x00, 0xff7e1880,},
-       {"RTL-8169", 0x04, 0xff7e1880,},
-};
-
-enum _DescStatusBit {
-       OWNbit = 0x80000000,
-       EORbit = 0x40000000,
-       FSbit = 0x20000000,
-       LSbit = 0x10000000,
-};
-
-struct TxDesc {
-       u32 status;
-       u32 vlan_tag;
-       u32 buf_addr;
-       u32 buf_Haddr;
-};
-
-struct RxDesc {
-       u32 status;
-       u32 vlan_tag;
-       u32 buf_addr;
-       u32 buf_Haddr;
-};
-
-/* Define the TX Descriptor */
-static u8 tx_ring[NUM_TX_DESC * sizeof(struct TxDesc) + 256];
-/*     __attribute__ ((aligned(256))); */
-
-/* Create a static buffer of size RX_BUF_SZ for each
-TX Descriptor. All descriptors point to a
-part of this buffer */
-static unsigned char txb[NUM_TX_DESC * RX_BUF_SIZE];
-
-/* Define the RX Descriptor */
-static u8 rx_ring[NUM_RX_DESC * sizeof(struct TxDesc) + 256];
-  /*  __attribute__ ((aligned(256))); */
-
-/* Create a static buffer of size RX_BUF_SZ for each
-RX Descriptor  All descriptors point to a
-part of this buffer */
-static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE];
-
-struct rtl8169_private {
-       void *mmio_addr;        /* memory map physical address */
-       int chipset;
-       unsigned long cur_rx;   /* Index into the Rx descriptor buffer of next Rx pkt. */
-       unsigned long cur_tx;   /* Index into the Tx descriptor buffer of next Rx pkt. */
-       unsigned long dirty_tx;
-       unsigned char *TxDescArrays;    /* Index of Tx Descriptor buffer */
-       unsigned char *RxDescArrays;    /* Index of Rx Descriptor buffer */
-       struct TxDesc *TxDescArray;     /* Index of 256-alignment Tx Descriptor buffer */
-       struct RxDesc *RxDescArray;     /* Index of 256-alignment Rx Descriptor buffer */
-       unsigned char *RxBufferRings;   /* Index of Rx Buffer  */
-       unsigned char *RxBufferRing[NUM_RX_DESC];       /* Index of Rx Buffer array */
-       unsigned char *Tx_skbuff[NUM_TX_DESC];
-} tpx;
-
-static struct rtl8169_private *tpc;
-
-static const u16 rtl8169_intr_mask =
-    SYSErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver | TxErr |
-    TxOK | RxErr | RxOK;
-static const unsigned int rtl8169_rx_config =
-    (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
-
-static struct pci_device_id supported[] = {
-       {PCI_VENDOR_ID_REALTEK, 0x8169},
-       {}
-};
-
-void mdio_write(int RegAddr, int value)
-{
-       int i;
-
-       RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value);
-       udelay(1000);
-
-       for (i = 2000; i > 0; i--) {
-               /* Check if the RTL8169 has completed writing to the specified MII register */
-               if (!(RTL_R32(PHYAR) & 0x80000000)) {
-                       break;
-               } else {
-                       udelay(100);
-               }
-       }
-}
-
-int mdio_read(int RegAddr)
-{
-       int i, value = -1;
-
-       RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16);
-       udelay(1000);
-
-       for (i = 2000; i > 0; i--) {
-               /* Check if the RTL8169 has completed retrieving data from the specified MII register */
-               if (RTL_R32(PHYAR) & 0x80000000) {
-                       value = (int) (RTL_R32(PHYAR) & 0xFFFF);
-                       break;
-               } else {
-                       udelay(100);
-               }
-       }
-       return value;
-}
-
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-static int rtl8169_init_board(struct eth_device *dev)
-{
-       int i;
-       u32 tmp;
-
-#ifdef DEBUG_RTL8169
-       printf ("%s\n", __FUNCTION__);
-#endif
-       ioaddr = dev->iobase;
-
-       /* Soft reset the chip. */
-       RTL_W8(ChipCmd, CmdReset);
-
-       /* Check that the chip has finished the reset. */
-       for (i = 1000; i > 0; i--)
-               if ((RTL_R8(ChipCmd) & CmdReset) == 0)
-                       break;
-               else
-                       udelay(10);
-
-       /* identify chip attached to board */
-       tmp = RTL_R32(TxConfig);
-       tmp = ((tmp & 0x7c000000) + ((tmp & 0x00800000) << 2)) >> 24;
-
-       for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--){
-               if (tmp == rtl_chip_info[i].version) {
-                       tpc->chipset = i;
-                       goto match;
-               }
-       }
-
-       /* if unknown chip, assume array element #0, original RTL-8169 in this case */
-       printf("PCI device %s: unknown chip version, assuming RTL-8169\n", dev->name);
-       printf("PCI device: TxConfig = 0x%hX\n", (unsigned long) RTL_R32(TxConfig));
-       tpc->chipset = 0;
-
-match:
-       return 0;
-}
-
-/**************************************************************************
-RECV - Receive a frame
-***************************************************************************/
-static int rtl_recv(struct eth_device *dev)
-{
-       /* return true if there's an ethernet packet ready to read */
-       /* nic->packet should contain data on return */
-       /* nic->packetlen should contain length of data */
-       int cur_rx;
-       int length = 0;
-
-#ifdef DEBUG_RTL8169_RX
-       printf ("%s\n", __FUNCTION__);
-#endif
-       ioaddr = dev->iobase;
-
-       cur_rx = tpc->cur_rx;
-       if ((tpc->RxDescArray[cur_rx].status & OWNbit) == 0) {
-               if (!(tpc->RxDescArray[cur_rx].status & RxRES)) {
-                       unsigned char rxdata[RX_BUF_LEN];
-                       length = (int) (tpc->RxDescArray[cur_rx].
-                                               status & 0x00001FFF) - 4;
-
-                       memcpy(rxdata, tpc->RxBufferRing[cur_rx], length);
-                       NetReceive(rxdata, length);
-
-                       if (cur_rx == NUM_RX_DESC - 1)
-                               tpc->RxDescArray[cur_rx].status =
-                                   (OWNbit | EORbit) + RX_BUF_SIZE;
-                       else
-                               tpc->RxDescArray[cur_rx].status =
-                                   OWNbit + RX_BUF_SIZE;
-                       tpc->RxDescArray[cur_rx].buf_addr =
-                           virt_to_bus(tpc->RxBufferRing[cur_rx]);
-               } else {
-                       puts("Error Rx");
-               }
-               cur_rx = (cur_rx + 1) % NUM_RX_DESC;
-               tpc->cur_rx = cur_rx;
-               return 1;
-
-       }
-       tpc->cur_rx = cur_rx;
-       return (0);             /* initially as this is called to flush the input */
-}
-
-#define HZ 1000
-/**************************************************************************
-SEND - Transmit a frame
-***************************************************************************/
-static int rtl_send(struct eth_device *dev, volatile void *packet, int length)
-{
-       /* send the packet to destination */
-
-       u32 to;
-       u8 *ptxb;
-       int entry = tpc->cur_tx % NUM_TX_DESC;
-       u32 len = length;
-
-#ifdef DEBUG_RTL8169_TX
-       int stime = currticks();
-       printf ("%s\n", __FUNCTION__);
-       printf("sending %d bytes\n", len);
-#endif
-
-       ioaddr = dev->iobase;
-
-       /* point to the current txb incase multiple tx_rings are used */
-       ptxb = tpc->Tx_skbuff[entry * MAX_ETH_FRAME_SIZE];
-       memcpy(ptxb, (char *)packet, (int)length);
-
-       while (len < ETH_ZLEN)
-               ptxb[len++] = '\0';
-
-       tpc->TxDescArray[entry].buf_addr = virt_to_bus(ptxb);
-       if (entry != (NUM_TX_DESC - 1)) {
-               tpc->TxDescArray[entry].status =
-                   (OWNbit | FSbit | LSbit) | ((len > ETH_ZLEN) ?
-                                               len : ETH_ZLEN);
-       } else {
-               tpc->TxDescArray[entry].status =
-                   (OWNbit | EORbit | FSbit | LSbit) |
-                   ((len > ETH_ZLEN) ? length : ETH_ZLEN);
-       }
-       RTL_W8(TxPoll, 0x40);   /* set polling bit */
-
-       tpc->cur_tx++;
-       to = currticks() + TX_TIMEOUT;
-       while ((tpc->TxDescArray[entry].status & OWNbit) && (currticks() < to));        /* wait */
-
-       if (currticks() >= to) {
-#ifdef DEBUG_RTL8169_TX
-               puts ("tx timeout/error\n");
-               printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime);
-#endif
-               return 0;
-       } else {
-#ifdef DEBUG_RTL8169_TX
-               puts("tx done\n");
-#endif
-               return length;
-       }
-}
-
-static void rtl8169_set_rx_mode(struct eth_device *dev)
-{
-       u32 mc_filter[2];       /* Multicast hash filter */
-       int rx_mode;
-       u32 tmp = 0;
-
-#ifdef DEBUG_RTL8169
-       printf ("%s\n", __FUNCTION__);
-#endif
-
-       /* IFF_ALLMULTI */
-       /* Too many to filter perfectly -- accept all multicasts. */
-       rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
-       mc_filter[1] = mc_filter[0] = 0xffffffff;
-
-       tmp = rtl8169_rx_config | rx_mode | (RTL_R32(RxConfig) &
-                                  rtl_chip_info[tpc->chipset].RxConfigMask);
-
-       RTL_W32(RxConfig, tmp);
-       RTL_W32(MAR0 + 0, mc_filter[0]);
-       RTL_W32(MAR0 + 4, mc_filter[1]);
-}
-
-static void rtl8169_hw_start(struct eth_device *dev)
-{
-       u32 i;
-
-#ifdef DEBUG_RTL8169
-       int stime = currticks();
-       printf ("%s\n", __FUNCTION__);
-#endif
-
-#if 0
-       /* Soft reset the chip. */
-       RTL_W8(ChipCmd, CmdReset);
-
-       /* Check that the chip has finished the reset. */
-       for (i = 1000; i > 0; i--) {
-               if ((RTL_R8(ChipCmd) & CmdReset) == 0)
-                       break;
-               else
-                       udelay(10);
-       }
-#endif
-
-       RTL_W8(Cfg9346, Cfg9346_Unlock);
-       RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
-       RTL_W8(EarlyTxThres, EarlyTxThld);
-
-       /* For gigabit rtl8169 */
-       RTL_W16(RxMaxSize, RxPacketMaxSize);
-
-       /* Set Rx Config register */
-       i = rtl8169_rx_config | (RTL_R32(RxConfig) &
-                                rtl_chip_info[tpc->chipset].RxConfigMask);
-       RTL_W32(RxConfig, i);
-
-       /* Set DMA burst size and Interframe Gap Time */
-       RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) |
-                               (InterFrameGap << TxInterFrameGapShift));
-
-
-       tpc->cur_rx = 0;
-
-       RTL_W32(TxDescStartAddr, virt_to_le32desc(tpc->TxDescArray));
-       RTL_W32(RxDescStartAddr, virt_to_le32desc(tpc->RxDescArray));
-       RTL_W8(Cfg9346, Cfg9346_Lock);
-       udelay(10);
-
-       RTL_W32(RxMissed, 0);
-
-       rtl8169_set_rx_mode(dev);
-
-       /* no early-rx interrupts */
-       RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
-
-#ifdef DEBUG_RTL8169
-       printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime);
-#endif
-}
-
-static void rtl8169_init_ring(struct eth_device *dev)
-{
-       int i;
-
-#ifdef DEBUG_RTL8169
-       int stime = currticks();
-       printf ("%s\n", __FUNCTION__);
-#endif
-
-       tpc->cur_rx = 0;
-       tpc->cur_tx = 0;
-       tpc->dirty_tx = 0;
-       memset(tpc->TxDescArray, 0x0, NUM_TX_DESC * sizeof(struct TxDesc));
-       memset(tpc->RxDescArray, 0x0, NUM_RX_DESC * sizeof(struct RxDesc));
-
-       for (i = 0; i < NUM_TX_DESC; i++) {
-               tpc->Tx_skbuff[i] = &txb[i];
-       }
-
-       for (i = 0; i < NUM_RX_DESC; i++) {
-               if (i == (NUM_RX_DESC - 1))
-                       tpc->RxDescArray[i].status =
-                           (OWNbit | EORbit) + RX_BUF_SIZE;
-               else
-                       tpc->RxDescArray[i].status = OWNbit + RX_BUF_SIZE;
-
-               tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE];
-               tpc->RxDescArray[i].buf_addr =
-                   virt_to_bus(tpc->RxBufferRing[i]);
-       }
-
-#ifdef DEBUG_RTL8169
-       printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime);
-#endif
-}
-
-/**************************************************************************
-RESET - Finish setting up the ethernet interface
-***************************************************************************/
-static void rtl_reset(struct eth_device *dev, bd_t *bis)
-{
-       int i;
-       u8 diff;
-       u32 TxPhyAddr, RxPhyAddr;
-
-#ifdef DEBUG_RTL8169
-       int stime = currticks();
-       printf ("%s\n", __FUNCTION__);
-#endif
-
-       tpc->TxDescArrays = tx_ring;
-       if (tpc->TxDescArrays == 0)
-               puts("Allot Error");
-       /* Tx Desscriptor needs 256 bytes alignment; */
-       TxPhyAddr = virt_to_bus(tpc->TxDescArrays);
-       diff = 256 - (TxPhyAddr - ((TxPhyAddr >> 8) << 8));
-       TxPhyAddr += diff;
-       tpc->TxDescArray = (struct TxDesc *) (tpc->TxDescArrays + diff);
-
-       tpc->RxDescArrays = rx_ring;
-       /* Rx Desscriptor needs 256 bytes alignment; */
-       RxPhyAddr = virt_to_bus(tpc->RxDescArrays);
-       diff = 256 - (RxPhyAddr - ((RxPhyAddr >> 8) << 8));
-       RxPhyAddr += diff;
-       tpc->RxDescArray = (struct RxDesc *) (tpc->RxDescArrays + diff);
-
-       if (tpc->TxDescArrays == NULL || tpc->RxDescArrays == NULL) {
-               puts("Allocate RxDescArray or TxDescArray failed\n");
-               return;
-       }
-
-       rtl8169_init_ring(dev);
-       rtl8169_hw_start(dev);
-       /* Construct a perfect filter frame with the mac address as first match
-        * and broadcast for all others */
-       for (i = 0; i < 192; i++)
-               txb[i] = 0xFF;
-
-       txb[0] = dev->enetaddr[0];
-       txb[1] = dev->enetaddr[1];
-       txb[2] = dev->enetaddr[2];
-       txb[3] = dev->enetaddr[3];
-       txb[4] = dev->enetaddr[4];
-       txb[5] = dev->enetaddr[5];
-
-#ifdef DEBUG_RTL8169
-       printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime);
-#endif
-}
-
-/**************************************************************************
-HALT - Turn off ethernet interface
-***************************************************************************/
-static void rtl_halt(struct eth_device *dev)
-{
-       int i;
-
-#ifdef DEBUG_RTL8169
-       printf ("%s\n", __FUNCTION__);
-#endif
-
-       ioaddr = dev->iobase;
-
-       /* Stop the chip's Tx and Rx DMA processes. */
-       RTL_W8(ChipCmd, 0x00);
-
-       /* Disable interrupts by clearing the interrupt mask. */
-       RTL_W16(IntrMask, 0x0000);
-
-       RTL_W32(RxMissed, 0);
-
-       tpc->TxDescArrays = NULL;
-       tpc->RxDescArrays = NULL;
-       tpc->TxDescArray = NULL;
-       tpc->RxDescArray = NULL;
-       for (i = 0; i < NUM_RX_DESC; i++) {
-               tpc->RxBufferRing[i] = NULL;
-       }
-}
-
-/**************************************************************************
-INIT - Look for an adapter, this routine's visible to the outside
-***************************************************************************/
-
-#define board_found 1
-#define valid_link 0
-static int rtl_init(struct eth_device *dev, bd_t *bis)
-{
-       static int board_idx = -1;
-       static int printed_version = 0;
-       int i, rc;
-       int option = -1, Cap10_100 = 0, Cap1000 = 0;
-
-#ifdef DEBUG_RTL8169
-       printf ("%s\n", __FUNCTION__);
-#endif
-
-       ioaddr = dev->iobase;
-
-       board_idx++;
-
-       printed_version = 1;
-
-       /* point to private storage */
-       tpc = &tpx;
-
-       rc = rtl8169_init_board(dev);
-       if (rc)
-               return rc;
-
-       /* Get MAC address.  FIXME: read EEPROM */
-       for (i = 0; i < MAC_ADDR_LEN; i++)
-               dev->enetaddr[i] = RTL_R8(MAC0 + i);
-
-#ifdef DEBUG_RTL8169
-       printf("MAC Address");
-       for (i = 0; i < MAC_ADDR_LEN; i++)
-               printf(":%02x", dev->enetaddr[i]);
-       putc('\n');
-#endif
-
-#ifdef DEBUG_RTL8169
-       /* Print out some hardware info */
-       printf("%s: at ioaddr 0x%x\n", dev->name, ioaddr);
-#endif
-
-       /* if TBI is not endbled */
-       if (!(RTL_R8(PHYstatus) & TBI_Enable)) {
-               int val = mdio_read(PHY_AUTO_NEGO_REG);
-
-               option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx];
-               /* Force RTL8169 in 10/100/1000 Full/Half mode. */
-               if (option > 0) {
-#ifdef DEBUG_RTL8169
-                       printf("%s: Force-mode Enabled.\n", dev->name);
-#endif
-                       Cap10_100 = 0, Cap1000 = 0;
-                       switch (option) {
-                       case _10_Half:
-                               Cap10_100 = PHY_Cap_10_Half;
-                               Cap1000 = PHY_Cap_Null;
-                               break;
-                       case _10_Full:
-                               Cap10_100 = PHY_Cap_10_Full;
-                               Cap1000 = PHY_Cap_Null;
-                               break;
-                       case _100_Half:
-                               Cap10_100 = PHY_Cap_100_Half;
-                               Cap1000 = PHY_Cap_Null;
-                               break;
-                       case _100_Full:
-                               Cap10_100 = PHY_Cap_100_Full;
-                               Cap1000 = PHY_Cap_Null;
-                               break;
-                       case _1000_Full:
-                               Cap10_100 = PHY_Cap_Null;
-                               Cap1000 = PHY_Cap_1000_Full;
-                               break;
-                       default:
-                               break;
-                       }
-                       mdio_write(PHY_AUTO_NEGO_REG, Cap10_100 | (val & 0x1F));        /* leave PHY_AUTO_NEGO_REG bit4:0 unchanged */
-                       mdio_write(PHY_1000_CTRL_REG, Cap1000);
-               } else {
-#ifdef DEBUG_RTL8169
-                       printf("%s: Auto-negotiation Enabled.\n",
-                              dev->name);
-#endif
-                       /* enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged */
-                       mdio_write(PHY_AUTO_NEGO_REG,
-                                  PHY_Cap_10_Half | PHY_Cap_10_Full |
-                                  PHY_Cap_100_Half | PHY_Cap_100_Full |
-                                  (val & 0x1F));
-
-                       /* enable 1000 Full Mode */
-                       mdio_write(PHY_1000_CTRL_REG, PHY_Cap_1000_Full);
-
-               }
-
-               /* Enable auto-negotiation and restart auto-nigotiation */
-               mdio_write(PHY_CTRL_REG,
-                          PHY_Enable_Auto_Nego | PHY_Restart_Auto_Nego);
-               udelay(100);
-
-               /* wait for auto-negotiation process */
-               for (i = 10000; i > 0; i--) {
-                       /* check if auto-negotiation complete */
-                       if (mdio_read(PHY_STAT_REG) & PHY_Auto_Neco_Comp) {
-                               udelay(100);
-                               option = RTL_R8(PHYstatus);
-                               if (option & _1000bpsF) {
-#ifdef DEBUG_RTL8169
-                                       printf("%s: 1000Mbps Full-duplex operation.\n",
-                                            dev->name);
-#endif
-                               } else {
-#ifdef DEBUG_RTL8169
-                                       printf
-                                           ("%s: %sMbps %s-duplex operation.\n",
-                                            dev->name,
-                                            (option & _100bps) ? "100" :
-                                            "10",
-                                            (option & FullDup) ? "Full" :
-                                            "Half");
-#endif
-                               }
-                               break;
-                       } else {
-                               udelay(100);
-                       }
-               }               /* end for-loop to wait for auto-negotiation process */
-
-       } else {
-               udelay(100);
-#ifdef DEBUG_RTL8169
-               printf
-                   ("%s: 1000Mbps Full-duplex operation, TBI Link %s!\n",
-                    dev->name,
-                    (RTL_R32(TBICSR) & TBILinkOK) ? "OK" : "Failed");
-#endif
-       }
-
-       return 1;
-}
-
-int rtl8169_initialize(bd_t *bis)
-{
-       pci_dev_t devno;
-       int card_number = 0;
-       struct eth_device *dev;
-       u32 iobase;
-       int idx=0;
-
-       while(1){
-               /* Find RTL8169 */
-               if ((devno = pci_find_devices(supported, idx++)) < 0)
-                       break;
-
-               pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase);
-               iobase &= ~0xf;
-
-               debug ("rtl8169: REALTEK RTL8169 @0x%x\n", iobase);
-
-               dev = (struct eth_device *)malloc(sizeof *dev);
-
-               sprintf (dev->name, "RTL8169#%d", card_number);
-
-               dev->priv = (void *) devno;
-               dev->iobase = (int)bus_to_phys(iobase);
-
-               dev->init = rtl_reset;
-               dev->halt = rtl_halt;
-               dev->send = rtl_send;
-               dev->recv = rtl_recv;
-
-               eth_register (dev);
-
-               rtl_init(dev, bis);
-
-               card_number++;
-       }
-       return card_number;
-}
-
-#endif
diff --git a/drivers/s3c4510b_eth.c b/drivers/s3c4510b_eth.c
deleted file mode 100644 (file)
index 48901aa..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-/***********************************************************************
- *
- * Copyright (c) 2004  Cucy Systems (http://www.cucy.com)
- * Curt Brune <curt@cucy.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * Description:   Ethernet interface for Samsung S3C4510B SoC
- */
-
-#include <common.h>
-
-#ifdef CONFIG_DRIVER_S3C4510_ETH
-
-#include <command.h>
-#include <net.h>
-#include <asm/hardware.h>
-#include "s3c4510b_eth.h"
-
-static TX_FrameDescriptor    txFDbase[ETH_MaxTxFrames];
-static MACFrame           txFrameBase[ETH_MaxTxFrames];
-static RX_FrameDescriptor    rxFDbase[PKTBUFSRX];
-static ETH                      m_eth;
-
-static s32 TxFDinit( ETH *eth) {
-
-       s32 i;
-       MACFrame *txFrmBase;
-
-       /* disable cache for access to the TX buffers */
-       txFrmBase = (MACFrame *)( (u32)txFrameBase | CACHE_DISABLE_MASK);
-
-       /* store start of Tx descriptors and set current */
-       eth->m_curTX_FD  =  (TX_FrameDescriptor *) ((u32)txFDbase | CACHE_DISABLE_MASK);
-       eth->m_baseTX_FD = eth->m_curTX_FD;
-
-       for ( i = 0; i < ETH_MaxTxFrames; i++) {
-               eth->m_baseTX_FD[i].m_frameDataPtr.bf.dataPtr = (u32)&txFrmBase[i];
-               eth->m_baseTX_FD[i].m_frameDataPtr.bf.owner   = 0x0; /* CPU owner */
-               eth->m_baseTX_FD[i].m_opt.ui                  = 0x0;
-               eth->m_baseTX_FD[i].m_status.ui               = 0x0;
-               eth->m_baseTX_FD[i].m_nextFD                  = &eth->m_baseTX_FD[i+1];
-       }
-
-       /* make the list circular */
-       eth->m_baseTX_FD[i-1].m_nextFD          = &eth->m_baseTX_FD[0];
-
-       PUT_REG( REG_BDMATXPTR, (u32)eth->m_curTX_FD);
-
-       return 0;
-}
-
-static s32 RxFDinit( ETH *eth) {
-
-       s32 i;
-       /*  MACFrame *rxFrmBase; */
-
-       /* disable cache for access to the RX buffers */
-       /*  rxFrmBase = (MACFrame *)( (u32)rxFrameBase | CACHE_DISABLE_MASK); */
-
-       /* store start of Rx descriptors and set current */
-       eth->m_curRX_FD = (RX_FrameDescriptor *)((u32)rxFDbase | CACHE_DISABLE_MASK);
-       eth->m_baseRX_FD = eth->m_curRX_FD;
-       for ( i = 0; i < PKTBUFSRX; i++) {
-               eth->m_baseRX_FD[i].m_frameDataPtr.bf.dataPtr = (u32)NetRxPackets[i] | CACHE_DISABLE_MASK;
-               eth->m_baseRX_FD[i].m_frameDataPtr.bf.owner   = 0x1; /* BDMA owner */
-               eth->m_baseRX_FD[i].m_reserved                = 0x0;
-               eth->m_baseRX_FD[i].m_status.ui               = 0x0;
-               eth->m_baseRX_FD[i].m_nextFD                  = &eth->m_baseRX_FD[i+1];
-       }
-
-       /* make the list circular */
-       eth->m_baseRX_FD[i-1].m_nextFD                  = &eth->m_baseRX_FD[0];
-
-       PUT_REG( REG_BDMARXPTR, (u32)eth->m_curRX_FD);
-
-       return 0;
-}
-
-/*
- * Public u-boot interface functions below
- */
-
-int eth_init(bd_t *bis)
-{
-
-       ETH *eth = &m_eth;
-
-       /* store our MAC address */
-       eth->m_mac = bis->bi_enetaddr;
-
-       /* setup DBMA and MAC */
-       PUT_REG( REG_BDMARXCON, ETH_BRxRS);   /* reset BDMA RX machine */
-       PUT_REG( REG_BDMATXCON, ETH_BTxRS);   /* reset BDMA TX machine */
-       PUT_REG( REG_MACCON   , ETH_SwReset); /* reset MAC machine */
-       PUT_REG( REG_BDMARXLSZ, sizeof(MACFrame));
-       PUT_REG( REG_MACCON   , 0);           /* reset MAC machine */
-
-       /* init frame descriptors */
-       TxFDinit( eth);
-       RxFDinit( eth);
-
-       /* init the CAM with our MAC address */
-       PUT_REG( REG_CAM_BASE,       (eth->m_mac[0] << 24) |
-               (eth->m_mac[1] << 16) |
-               (eth->m_mac[2] <<  8) |
-               (eth->m_mac[3]));
-       PUT_REG( REG_CAM_BASE + 0x4, (eth->m_mac[4] << 24) |
-               (eth->m_mac[5] << 16));
-
-       /* enable CAM address 1 -- the MAC we just loaded */
-       PUT_REG( REG_CAMEN, 0x1);
-
-       PUT_REG( REG_CAMCON,
-               ETH_BroadAcc |  /* accept broadcast packetes */
-               ETH_CompEn); /* enable compare mode (check against the CAM) */
-
-       /* configure the BDMA Transmitter control */
-       PUT_REG( REG_BDMATXCON,
-               ETH_BTxBRST   | /* BDMA Tx burst size 16 words  */
-               ETH_BTxMSL110 | /* BDMA Tx wait to fill 6/8 of the BDMA */
-               ETH_BTxSTSKO  | /* BDMA Tx interrupt(Stop) on non-owner TX FD */
-               ETH_BTxEn);     /* BDMA Tx Enable  */
-
-       /* configure the MAC Transmitter control */
-       PUT_REG( REG_MACTXCON,
-               ETH_EnComp | /* interrupt when the MAC transmits or discards packet */
-               ETH_TxEn);      /* MAC transmit enable */
-
-       /* configure the BDMA Receiver control */
-       PUT_REG( REG_BDMARXCON,
-               ETH_BRxBRST   | /* BDMA Rx Burst Size 16 words */
-               ETH_BRxSTSKO  | /* BDMA Rx interrupt(Stop) on non-owner RX FD */
-               ETH_BRxMAINC  | /* BDMA Rx Memory Address increment */
-               ETH_BRxDIE    | /* BDMA Rx Every Received Frame Interrupt Enable */
-               ETH_BRxNLIE   | /* BDMA Rx NULL List Interrupt Enable */
-               ETH_BRxNOIE   | /* BDMA Rx Not Owner Interrupt Enable */
-               ETH_BRxLittle | /* BDMA Rx Little endian */
-               ETH_BRxEn);     /* BDMA Rx Enable */
-
-       /* configure the MAC Receiver control */
-       PUT_REG( REG_MACRXCON,
-               ETH_RxEn);      /* MAC ETH_RxEn */
-
-       return 0;
-
-}
-
-/* Send a packet       */
-s32 eth_send(volatile void *packet, s32 length)
-{
-
-       u32 i;
-       ETH *eth = &m_eth;
-
-       if ( eth->m_curTX_FD->m_frameDataPtr.bf.owner) {
-               printf("eth_send(): TX Frame.  CPU not owner.\n");
-               return -1;
-       }
-
-       /* copy user data into frame data pointer */
-       memcpy((void *)(eth->m_curTX_FD->m_frameDataPtr.bf.dataPtr),
-              (void *)packet,
-              length);
-
-       /* Set TX Frame flags */
-       eth->m_curTX_FD->m_opt.bf.widgetAlign  = 0;
-       eth->m_curTX_FD->m_opt.bf.frameDataDir = 1;
-       eth->m_curTX_FD->m_opt.bf.littleEndian = 1;
-       eth->m_curTX_FD->m_opt.bf.macTxIrqEnbl = 1;
-       eth->m_curTX_FD->m_opt.bf.no_crc       = 0;
-       eth->m_curTX_FD->m_opt.bf.no_padding   = 0;
-
-       /* Set TX Frame length */
-       eth->m_curTX_FD->m_status.bf.len       = length;
-
-       /* Change ownership to BDMA */
-       eth->m_curTX_FD->m_frameDataPtr.bf.owner = 1;
-
-       /* Enable MAC and BDMA Tx control register */
-       SET_REG( REG_BDMATXCON, ETH_BTxEn);
-       SET_REG( REG_MACTXCON,  ETH_TxEn);
-
-       /* poll on TX completion status */
-       while ( !eth->m_curTX_FD->m_status.bf.complete) {
-               /* sleep  */
-               for ( i = 0; i < 0x10000; i ++);
-       }
-
-       /* Change the Tx frame descriptor for next use */
-       eth->m_curTX_FD = eth->m_curTX_FD->m_nextFD;
-
-       return 0;
-}
-
-/* Check for received packets  */
-s32 eth_rx (void)
-{
-       s32 nLen = 0;
-       ETH *eth = &m_eth;
-
-       /* check if packet ready */
-       if ( (GET_REG( REG_BDMASTAT)) & ETH_S_BRxRDF) {
-               /* process all waiting packets */
-               while ( !eth->m_curRX_FD->m_frameDataPtr.bf.owner) {
-                       nLen = eth->m_curRX_FD->m_status.bf.len;
-                       /* call back u-boot -- may call eth_send() */
-                       NetReceive ((u8 *)eth->m_curRX_FD->m_frameDataPtr.ui, nLen);
-                       /* set owner back to CPU */
-                       eth->m_curRX_FD->m_frameDataPtr.bf.owner = 1;
-                       /* clear status */
-                       eth->m_curRX_FD->m_status.ui = 0x0;
-                       /* advance to next descriptor */
-                       eth->m_curRX_FD = eth->m_curRX_FD->m_nextFD;
-                       /* clear received frame bit */
-                       PUT_REG( REG_BDMASTAT, ETH_S_BRxRDF);
-               }
-       }
-
-       return nLen;
-}
-
-/* Halt ethernet engine */
-void eth_halt(void)
-{
-       /* disable MAC */
-       PUT_REG( REG_MACCON, ETH_HaltReg);
-}
-
-#endif
diff --git a/drivers/s3c4510b_eth.h b/drivers/s3c4510b_eth.h
deleted file mode 100644 (file)
index cbddba7..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-#ifndef __S3C4510B_ETH_H
-#define __S3C4510B_ETH_H
-/*
- * Copyright (c) 2004  Cucy Systems (http://www.cucy.com)
- * Curt Brune <curt@cucy.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * MODULE:        $Id:$
- * Description:   Ethernet interface
- * Runtime Env:   ARM7TDMI
- * Change History:
- *     03-02-04    Create (Curt Brune) curt@cucy.com
- *
- */
-
-#define __packed    __attribute__ ((packed))
-
-#define ETH_MAC_ADDR_SIZE           (6)    /*  dst,src addr is 6bytes each */
-#define ETH_MaxTxFrames             (16)   /*  Max number of Tx Frames */
-
-/*  Buffered DMA Receiver Control Register  */
-#define ETH_BRxBRST     0x0000F  /*  BDMA Rx Burst Size * BRxBRST  */
-                                /*  = Burst Data Size 16 */
-#define ETH_BRxSTSKO    0x00020  /*  BDMA Rx Stop/Skip  Frame or Interrupt(=1)  */
-                                /*  case of not OWNER the current Frame  */
-#define ETH_BRxMAINC    0x00040  /*  BDMA Rx Memory Address Inc/Dec  */
-#define ETH_BRxDIE      0x00080  /*  BDMA Rx Every Received Frame Interrupt Enable */
-#define ETH_BRxNLIE     0x00100  /*  BDMA Rx NULL List Interrupt Enable  */
-#define ETH_BRxNOIE     0x00200  /*  BDMA Rx Not Owner Interrupt Enable */
-#define ETH_BRxMSOIE    0x00400  /*  BDMA Rx Maximum Size over Interrupr Enable  */
-#define ETH_BRxLittle   0x00800  /*  BDMA Rx Big/Little Endian  */
-#define ETH_BRxBig      0x00000  /*  BDMA Rx Big/Little Endian */
-#define ETH_BRxWA01     0x01000  /*  BDMA Rx Word Alignment- one invalid byte  */
-#define ETH_BRxWA10     0x02000  /*  BDMA Rx Word Alignment- two invalid byte */
-#define ETH_BRxWA11     0x03000  /*  BDMA Rx Word Alignment- three invalid byte  */
-#define ETH_BRxEn       0x04000  /*  BDMA Rx Enable */
-#define ETH_BRxRS       0x08000  /*  BDMA Rx Reset */
-#define ETH_RxEmpty     0x10000  /*  BDMA Rx Buffer empty interrupt  */
-#define ETH_BRxEarly    0x20000  /*  BDMA Rx Early notify Interrupt */
-
-/*  Buffered DMA Trasmit Control Register(BDMATXCON)  */
-#define ETH_BTxBRST     0x0000F  /*  BDMA Tx Burst Size = 16  */
-#define ETH_BTxSTSKO    0x00020  /*  BDMA Tx Stop/Skip Frame or Interrupt in case */
-                                /*  of not Owner the current frame  */
-#define ETH_BTxCPIE     0x00080  /*  BDMA Tx Complete to send control  */
-                                /*  packet Enable */
-#define ETH_BTxNOIE     0x00200  /*  BDMA Tx Buffer Not Owner */
-#define ETH_BTxEmpty    0x00400  /*  BDMA Tx Buffer Empty Interrupt  */
-
-/*  BDMA Tx buffer can be moved to the MAC Tx IO when the new frame comes in.  */
-#define ETH_BTxMSL000   0x00000  /*  No wait to fill the BDMA  */
-#define ETH_BTxMSL001   0x00800  /*  wait to fill 1/8 of the BDMA  */
-#define ETH_BTxMSL010   0x01000  /*  wait to fill 2/8 of the BDMA */
-#define ETH_BTxMSL011   0x01800  /*  wait to fill 3/8 of the BDMA */
-#define ETH_BTxMSL100   0x02000  /*  wait to fill 4/8 of the BDMA */
-#define ETH_BTxMSL101   0x02800  /*  wait to fill 5/8 of the BDMA */
-#define ETH_BTxMSL110   0x03000  /*  wait to fill 6/8 of the BDMA */
-#define ETH_BTxMSL111   0x03800  /*  wait to fill 7/8 of the BDMA */
-#define ETH_BTxEn       0x04000  /*  BDMA Tx Enable  */
-#define ETH_BTxRS       0x08000  /*  BDMA Tx Reset  */
-
-/*  BDMA Status Register  */
-#define ETH_S_BRxRDF    0x00001  /*  BDMA Rx Done Every Received Frame  */
-#define ETH_S_BRxNL     0x00002  /*  BDMA Rx NULL List  */
-#define ETH_S_BRxNO     0x00004  /*  BDMA Rx Not Owner  */
-#define ETH_S_BRxMSO    0x00008  /*  BDMA Rx Maximum Size Over  */
-#define ETH_S_BRxEmpty  0x00010  /*  BDMA Rx Buffer Empty  */
-#define ETH_S_BRxSEarly 0x00020  /*  Early Notify  */
-#define ETH_S_BRxFRF    0x00080  /*  One more frame data in BDMA receive buffer  */
-#define ETH_S_BTxCCP    0x10000  /*  BDMA Tx Complete to send Control Packet  */
-#define ETH_S_BTxNL     0x20000  /*  BDMA Tx Null List  */
-#define ETH_S_BTxNO     0x40000  /*  BDMA Tx Not Owner */
-#define ETH_S_BTxEmpty  0x100000 /*  BDMA Tx Buffer Empty  */
-
-/*  MAC Control Register  */
-#define ETH_HaltReg     0x0001   /*  stop transmission and reception  */
-                                /*  after completion of any current packets  */
-#define ETH_HaltImm     0x0002   /*  Stop transmission and reception immediately  */
-#define ETH_SwReset     0x0004   /*  reset all Ethernet controller state machines */
-                                /*  and FIFOs  */
-#define ETH_FullDup     0x0008   /*  allow transmission to begin while reception */
-                                /*  is occurring  */
-#define ETH_MACLoop     0x0010   /*  MAC loopback */
-#define ETH_ConnM00     0x0000   /*  Automatic-default  */
-#define ETH_ConnM01     0x0020   /*  Force 10Mbits endec */
-#define ETH_ConnM10     0x0040   /*  Force MII (rate determined by MII clock  */
-#define ETH_MIIOFF      0x0040   /*  Force MII (rate determined by MII clock  */
-#define ETH_Loop10      0x0080   /*  Loop 10Mbps  */
-#define ETH_MissRoll    0x0400   /*  Missed error counter rolled over  */
-#define ETH_MDCOFF      0x1000   /*  MII Station Management Clock Off */
-#define ETH_EnMissRoll  0x2000   /*  Interrupt when missed error counter rolls  */
-                                /*  over  */
-#define ETH_Link10      0x8000   /*  Link status 10Mbps  */
-
-/*  CAM control register(CAMCON)  */
-#define ETH_StationAcc  0x0001   /*  Accept any packet with a unicast station  */
-                                /*  address  */
-#define ETH_GroupAcc    0x0002   /*  Accept any packet with multicast-group  */
-                                /*  station address   */
-#define ETH_BroadAcc    0x0004   /*  Accept any packet with a broadcast station */
-                                /*  address  */
-#define ETH_NegCAM      0x0008   /*  0: Accept packets CAM recognizes,  */
-                                /*     reject others */
-                                /*  1: reject packets CAM recognizes,  */
-                                /*     accept others  */
-#define ETH_CompEn      0x0010   /*  Compare Enable mode */
-
-/*  Transmit Control Register(MACTXCON) */
-#define ETH_TxEn        0x0001   /*  transmit Enable  */
-#define ETH_TxHalt      0x0002   /*  Transmit Halt Request  */
-#define ETH_NoPad       0x0004   /*  suppress Padding  */
-#define ETH_NoCRC       0x0008   /*  Suppress CRC  */
-#define ETH_FBack       0x0010   /*  Fast Back-off */
-#define ETH_NoDef       0x0020   /*  Disable the defer counter */
-#define ETH_SdPause     0x0040   /*  Send Pause */
-#define ETH_MII10En     0x0080   /*  MII 10Mbps mode enable */
-#define ETH_EnUnder     0x0100   /*  Enable Underrun */
-#define ETH_EnDefer     0x0200   /*  Enable Deferral */
-#define ETH_EnNCarr     0x0400   /*  Enable No Carrier  */
-#define ETH_EnExColl    0x0800   /*  interrupt if 16 collision occur  */
-                                /*  in the same packet  */
-#define ETH_EnLateColl  0x1000   /*  interrupt if collision occurs after  */
-                                /*  512 bit times(64 bytes times)  */
-#define ETH_EnTxPar     0x2000   /*  interrupt if the MAC transmit FIFO  */
-                                /*  has a parity error  */
-#define ETH_EnComp      0x4000   /*  interrupt when the MAC transmits or  */
-                                /*  discards one packet  */
-
-/*  Transmit Status Register(MACTXSTAT) */
-#define ETH_ExColl      0x0010   /*  Excessive collision  */
-#define ETH_TxDeffered  0x0020   /*  set if 16 collisions occur for same packet */
-#define ETH_Paused      0x0040   /*  packet waited because of pause during  */
-                                /*  transmission  */
-#define ETH_IntTx       0x0080   /*  set if transmission of packet causes an  */
-                                /*  interrupt condiftion  */
-#define ETH_Under       0x0100   /*  MAC transmit FIFO becomes empty during  */
-                                /*  transmission  */
-#define ETH_Defer       0x0200   /*  MAC defers for MAC deferral  */
-#define ETH_NCarr       0x0400   /*  No carrier sense detected during the  */
-                                /*  transmission of a packet  */
-#define ETH_SQE         0x0800   /*  Signal Quality Error */
-#define ETH_LateColl    0x1000   /*  a collision occures after 512 bit times  */
-#define ETH_TxPar       0x2000   /*  MAC transmit FIFO has detected a parity error */
-#define ETH_Comp        0x4000   /*  MAC transmit or discards one packet  */
-#define ETH_TxHalted    0x8000   /*  Transmission was halted by clearing  */
-                                /*  TxEn or Halt immedite  */
-
-/*  Receive Control Register (MACRXCON)  */
-#define ETH_RxEn        0x0001
-#define ETH_RxHalt      0x0002
-#define ETH_LongEn      0x0004
-#define ETH_ShortEn     0x0008
-#define ETH_StripCRC    0x0010
-#define ETH_PassCtl     0x0020
-#define ETH_IgnoreCRC   0x0040
-#define ETH_EnAlign     0x0100
-#define ETH_EnCRCErr    0x0200
-#define ETH_EnOver      0x0400
-#define ETH_EnLongErr   0x0800
-#define ETH_EnRxPar     0x2000
-#define ETH_EnGood      0x4000
-
-/*  Receive Status Register(MACRXSTAT) */
-#define ETH_MCtlRecd    0x0020
-#define ETH_MIntRx      0x0040
-#define ETH_MRx10Stat   0x0080
-#define ETH_MAllignErr  0x0100
-#define ETH_MCRCErr     0x0200
-#define ETH_MOverflow   0x0400
-#define ETH_MLongErr    0x0800
-#define ETH_MRxPar      0x2000
-#define ETH_MRxGood     0x4000
-#define ETH_MRxHalted   0x8000
-
-/*  type of ethernet packets */
-#define ETH_TYPE_ARP  (0x0806)
-#define ETH_TYPE_IP   (0x0800)
-
-#define ETH_HDR_SIZE  (14)
-
-/*  bit field for frame data pointer word */
-typedef struct __BF_FrameDataPtr {
-       u32 dataPtr:31;
-       u32   owner: 1;
-} BF_FrameDataPtr;
-
-typedef union _FrameDataPtr {
-       u32             ui;
-       BF_FrameDataPtr bf;
-} FrameDataPtr;
-
-typedef struct __BF_TX_Options {
-       u32    no_padding: 1;
-       u32        no_crc: 1;
-       u32  macTxIrqEnbl: 1;
-       u32  littleEndian: 1;
-       u32  frameDataDir: 1;
-       u32   widgetAlign: 2;
-       u32      reserved:25;
-} BF_TX_Options;
-
-typedef union _TX_Options {
-       u32    ui;
-       BF_TX_Options   bf;
-} TX_Options;
-
-typedef struct __BF_RX_Status {
-       u32           len:16;   /*  frame length */
-       u32     reserved1: 3;
-       u32       overMax: 1;
-       u32     reserved2: 1;
-       u32       ctrlRcv: 1;
-       u32         intRx: 1;
-       u32      rx10stat: 1;
-       u32      alignErr: 1;
-       u32        crcErr: 1;
-       u32      overFlow: 1;
-       u32       longErr: 1;
-       u32     reserved3: 1;
-       u32     parityErr: 1;
-       u32          good: 1;
-       u32        halted: 1;
-} BF_RX_Status;
-
-typedef union _RX_Status {
-       u32             ui;
-       BF_RX_Status    bf;
-} RX_Status;
-
-typedef struct __BF_TX_Status {
-       u32           len:16;   /*  frame length */
-       u32     txCollCnt: 4;
-       u32        exColl: 1;
-       u32       txDefer: 1;
-       u32        paused: 1;
-       u32         intTx: 1;
-       u32      underRun: 1;
-       u32         defer: 1;
-       u32     noCarrier: 1;
-       u32         SQErr: 1;
-       u32      lateColl: 1;
-       u32     parityErr: 1;
-       u32      complete: 1;
-       u32        halted: 1;
-} BF_TX_Status;
-
-typedef union _TX_Status {
-       u32    ui;
-       BF_TX_Status    bf;
-} TX_Status;
-
-/*  TX descriptor structure  */
-typedef struct __TX_FrameDescriptor {
-       volatile FrameDataPtr  m_frameDataPtr;
-       TX_Options                      m_opt;
-       volatile TX_Status           m_status;
-       struct __TX_FrameDescriptor *m_nextFD;
-} TX_FrameDescriptor;
-
-/*  RX descriptor structure  */
-typedef struct __RX_FrameDescriptor {
-       volatile FrameDataPtr  m_frameDataPtr;
-       u32                        m_reserved;
-       volatile RX_Status           m_status;
-       struct __RX_FrameDescriptor *m_nextFD;
-} RX_FrameDescriptor;
-
-/*  MAC Frame Structure */
-typedef struct __MACFrame {
-       u8     m_dstAddr[6] __packed;
-       u8     m_srcAddr[6] __packed;
-       u16  m_lengthOrType __packed;
-       u8  m_payload[1506] __packed;
-} MACFrame;
-
-/* Ethernet Control block */
-typedef struct __ETH {
-       TX_FrameDescriptor   *m_curTX_FD; /*  pointer to current TX frame descriptor */
-       TX_FrameDescriptor  *m_baseTX_FD; /*  pointer to base TX frame descriptor    */
-       RX_FrameDescriptor   *m_curRX_FD; /*  pointer to current RX frame descriptor */
-       RX_FrameDescriptor  *m_baseRX_FD; /*  pointer to base RX frame descriptor    */
-       u8                        *m_mac; /*  pointer to our MAC address             */
-} ETH;
-
-#endif
diff --git a/drivers/s3c4510b_uart.c b/drivers/s3c4510b_uart.c
deleted file mode 100644 (file)
index ddcd591..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (c) 2004  Cucy Systems (http://www.cucy.com)
- * Curt Brune <curt@cucy.com>
- *
- * (C) Copyright 2004
- * DAVE Srl
- * http://www.dave-tech.it
- * http://www.wawnet.biz
- * mailto:info@wawnet.biz
- *
- * (C) Copyright 2002-2004
- * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
- *
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
- *
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Alex Zuepke <azu@sysgo.de>
- *
- * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * MODULE:        $Id:$
- * Description:   UART/Serial interface for Samsung S3C4510B SoC
- * Runtime Env:   ARM7TDMI
- * Change History:
- *     03-02-04    Create (Curt Brune) curt@cucy.com
- *
- */
-
-#include <common.h>
-
-#ifdef CONFIG_DRIVER_S3C4510_UART
-
-#include <asm/hardware.h>
-#include "s3c4510b_uart.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-static UART    *uart;
-
-/* flush serial input queue. returns 0 on success or negative error
- * number otherwise
- */
-static int serial_flush_input(void)
-{
-       volatile u32 tmp;
-
-       /* keep on reading as long as the receiver is not empty */
-       while( uart->m_stat.bf.rxReady) {
-               tmp = uart->m_rx;
-       }
-
-       return 0;
-}
-
-
-/* flush output queue. returns 0 on success or negative error number
- * otherwise
- */
-static int serial_flush_output(void)
-{
-       /* wait until the transmitter is no longer busy */
-       while( !uart->m_stat.bf.txBufEmpty);
-
-       return 0;
-}
-
-
-void serial_setbrg (void)
-{
-       UART_LINE_CTRL ulctrl;
-       UART_CTRL      uctrl;
-       UART_BAUD_DIV  ubd;
-
-       serial_flush_output();
-       serial_flush_input();
-
-       /* control register */
-       uctrl.ui = 0x0;
-       uctrl.bf.rxMode = 0x1;
-       uctrl.bf.rxIrq = 0x0;
-       uctrl.bf.txMode = 0x1;
-       uctrl.bf.DSR = 0x0;
-       uctrl.bf.sendBreak = 0x0;
-       uctrl.bf.loopBack = 0x0;
-       uart->m_ctrl.ui = uctrl.ui;
-
-       /* line control register */
-       ulctrl.ui  = 0x0;
-       ulctrl.bf.wordLen   = 0x3; /* 8 bit data */
-       ulctrl.bf.nStop     = 0x0; /* 1 stop bit */
-       ulctrl.bf.parity    = 0x0; /* no parity */
-       ulctrl.bf.clk       = 0x0; /* internal clock */
-       ulctrl.bf.infra_red = 0x0; /* no infra_red */
-       uart->m_lineCtrl.ui = ulctrl.ui;
-
-       ubd.ui = 0x0;
-
-       /* see table on page 10-15 in SAMSUNG S3C4510B manual */
-       /* get correct divisor */
-       switch(gd->baudrate) {
-       case   1200:    ubd.bf.cnt0 = 1301;     break;
-       case   2400:    ubd.bf.cnt0 =  650;     break;
-       case   4800:    ubd.bf.cnt0 =  324;     break;
-       case   9600:    ubd.bf.cnt0 =  162;     break;
-       case  19200:    ubd.bf.cnt0 =   80;     break;
-       case  38400:    ubd.bf.cnt0 =   40;     break;
-       case  57600:    ubd.bf.cnt0 =   26;     break;
-       case 115200:    ubd.bf.cnt0 =   13;     break;
-       }
-
-       uart->m_baudDiv.ui = ubd.ui;
-       uart->m_baudCnt = 0x0;
-       uart->m_baudClk = 0x0;
-
-}
-
-
-/*
- * Initialise the serial port with the given baudrate. The settings
- * are always 8 data bits, no parity, 1 stop bit, no start bits.
- *
- */
-int serial_init (void)
-{
-
-#if   CONFIG_SERIAL1 == 1
-       uart = (UART *)UART0_BASE;
-#elif CONFIG_SERIAL1 == 2
-       uart = (UART *)UART1_BASE;
-#else
-#error CONFIG_SERIAL1 not equal to 1 or 2
-#endif
-
-       serial_setbrg ();
-
-       return (0);
-}
-
-
-/*
- * Output a single byte to the serial port.
- */
-void serial_putc (const char c)
-{
-       /* wait for room in the transmit FIFO */
-       while( !uart->m_stat.bf.txBufEmpty);
-
-       uart->m_tx = c;
-
-       /*
-               to be polite with serial console add a line feed
-               to the carriage return character
-       */
-       if (c=='\n')
-               serial_putc('\r');
-}
-
-/*
- * Test if an input byte is ready from the serial port. Returns non-zero on
- * success, 0 otherwise.
- */
-int serial_tstc (void)
-{
-       return uart->m_stat.bf.rxReady;
-}
-
-/*
- * Read a single byte from the serial port. Returns 1 on success, 0
- * otherwise. When the function is succesfull, the character read is
- * written into its argument c.
- */
-int serial_getc (void)
-{
-       int rv;
-
-       for(;;) {
-               rv = serial_tstc();
-
-               if (rv) {
-                       return uart->m_rx & 0xFF;
-               }
-       }
-}
-
-void serial_puts (const char *s)
-{
-       while (*s) {
-               serial_putc (*s++);
-       }
-
-       /* busy wait for tx complete */
-       while ( !uart->m_stat.bf.txComplete);
-
-       /* clear break */
-       uart->m_ctrl.bf.sendBreak = 0;
-
-}
-
-#endif
diff --git a/drivers/s3c4510b_uart.h b/drivers/s3c4510b_uart.h
deleted file mode 100644 (file)
index b06c76d..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-#ifndef __UART_H
-#define __UART_H
-
-/*
- * Copyright (c) 2004  Cucy Systems (http://www.cucy.com)
- * Curt Brune <curt@cucy.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * Description:   S3C4510B UART register layout
- */
-
-/* UART LINE CONTROL register */
-typedef struct __BF_UART_LINE_CTRL {
-       u32    wordLen: 2;
-       u32      nStop: 1;
-       u32     parity: 3;
-       u32        clk: 1;
-       u32  infra_red: 1;
-       u32     unused:24;
-} BF_UART_LINE_CTRL;
-
-typedef union _UART_LINE_CTRL {
-       u32               ui;
-       BF_UART_LINE_CTRL bf;
-} UART_LINE_CTRL;
-
-/* UART CONTROL register */
-typedef struct __BF_UART_CTRL {
-       u32     rxMode: 2;
-       u32      rxIrq: 1;
-       u32     txMode: 2;
-       u32        DSR: 1;
-       u32  sendBreak: 1;
-       u32   loopBack: 1;
-       u32     unused:24;
-} BF_UART_CTRL;
-
-typedef union _UART_CTRL {
-       u32            ui;
-       BF_UART_CTRL   bf;
-} UART_CTRL;
-
-/* UART STATUS register */
-typedef struct __BF_UART_STAT {
-       u32      overrun: 1;
-       u32       parity: 1;
-       u32        frame: 1;
-       u32     breakIrq: 1;
-       u32          DTR: 1;
-       u32      rxReady: 1;
-       u32   txBufEmpty: 1;
-       u32   txComplete: 1;
-       u32       unused:24;
-} BF_UART_STAT;
-
-typedef union _UART_STAT {
-       u32            ui;
-       BF_UART_STAT   bf;
-} UART_STAT;
-
-/* UART BAUD_DIV register */
-typedef struct __BF_UART_BAUD_DIV {
-       u32      cnt1: 4;
-       u32      cnt0:12;
-       u32    unused:16;
-} BF_UART_BAUD_DIV;
-
-typedef union _UART_BAUD_DIV {
-       u32                ui;
-       BF_UART_BAUD_DIV   bf;
-} UART_BAUD_DIV;
-
-/* UART register block */
-typedef struct __UART {
-       volatile UART_LINE_CTRL  m_lineCtrl;
-       volatile UART_CTRL           m_ctrl;
-       volatile UART_STAT           m_stat;
-       volatile u32                   m_tx;
-       volatile u32                   m_rx;
-       volatile UART_BAUD_DIV    m_baudDiv;
-       volatile u32              m_baudCnt;
-       volatile u32              m_baudClk;
-} UART;
-
-#define NL          0x0A
-#define CR          0x0D
-#define BSP         0x08
-#define ESC         0x1B
-#define CTRLZ       0x1A
-#define RUBOUT      0x7F
-
-#endif
diff --git a/drivers/sed13806.c b/drivers/sed13806.c
deleted file mode 100644 (file)
index 6996ca8..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * (C) Copyright 2002
- * Stäubli Faverges - <www.staubli.com>
- * Pierre AUBERT  p.aubert@staubli.com
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-/* Video support for Epson SED13806 chipset                                  */
-
-#include <common.h>
-
-#ifdef CONFIG_VIDEO_SED13806
-
-#include <video_fb.h>
-#include <sed13806.h>
-
-#define readByte(ptrReg)                \
-    *(volatile unsigned char *)(sed13806.isaBase + ptrReg)
-
-#define writeByte(ptrReg,value) \
-    *(volatile unsigned char *)(sed13806.isaBase + ptrReg) = value
-
-#ifdef CONFIG_TOTAL5200
-#define writeWord(ptrReg,value) \
-    (*(volatile unsigned short *)(sed13806.isaBase + ptrReg) = value)
-#else
-#define writeWord(ptrReg,value) \
-    (*(volatile unsigned short *)(sed13806.isaBase + ptrReg) = ((value >> 8 ) & 0xff) | ((value << 8) & 0xff00))
-#endif
-
-GraphicDevice sed13806;
-
-/*-----------------------------------------------------------------------------
- * EpsonSetRegs --
- *-----------------------------------------------------------------------------
- */
-static void EpsonSetRegs (void)
-{
-    /* the content of the chipset register depends on the board (clocks, ...)*/
-    const S1D_REGS *preg = board_get_regs ();
-    while (preg -> Index) {
-       writeByte (preg -> Index, preg -> Value);
-       preg ++;
-    }
-}
-
-/*-----------------------------------------------------------------------------
- * video_hw_init --
- *-----------------------------------------------------------------------------
- */
-void *video_hw_init (void)
-{
-    unsigned int *vm, i;
-
-    memset (&sed13806, 0, sizeof (GraphicDevice));
-
-    /* Initialization of the access to the graphic chipset
-       Retreive base address of the chipset
-       (see board/RPXClassic/eccx.c)                                         */
-    if ((sed13806.isaBase = board_video_init ()) == 0) {
-       return (NULL);
-    }
-
-    sed13806.frameAdrs = sed13806.isaBase + FRAME_BUFFER_OFFSET;
-    sed13806.winSizeX = board_get_width ();
-    sed13806.winSizeY = board_get_height ();
-
-#if defined(CONFIG_VIDEO_SED13806_8BPP)
-    sed13806.gdfIndex = GDF__8BIT_INDEX;
-    sed13806.gdfBytesPP = 1;
-
-#elif defined(CONFIG_VIDEO_SED13806_16BPP)
-    sed13806.gdfIndex = GDF_16BIT_565RGB;
-    sed13806.gdfBytesPP = 2;
-
-#else
-#error Unsupported SED13806 BPP
-#endif
-
-    sed13806.memSize = sed13806.winSizeX * sed13806.winSizeY * sed13806.gdfBytesPP;
-
-    /* Load SED registers                                                    */
-    EpsonSetRegs ();
-
-    /* (see board/RPXClassic/RPXClassic.c)                                   */
-    board_validate_screen (sed13806.isaBase);
-
-    /* Clear video memory */
-    i = sed13806.memSize/4;
-    vm = (unsigned int *)sed13806.frameAdrs;
-    while(i--)
-       *vm++ = 0;
-
-
-    return (&sed13806);
-}
-/*-----------------------------------------------------------------------------
- * Epson_wait_idle -- Wait for hardware to become idle
- *-----------------------------------------------------------------------------
- */
-static void Epson_wait_idle (void)
-{
-    while (readByte (BLT_CTRL0) & 0x80);
-
-    /* Read a word in the BitBLT memory area to shutdown the BitBLT engine   */
-    *(volatile unsigned short *)(sed13806.isaBase + BLT_REG);
-}
-
-/*-----------------------------------------------------------------------------
- * video_hw_bitblt --
- *-----------------------------------------------------------------------------
- */
-void video_hw_bitblt (
-    unsigned int bpp,             /* bytes per pixel */
-    unsigned int src_x,           /* source pos x */
-    unsigned int src_y,           /* source pos y */
-    unsigned int dst_x,           /* dest pos x */
-    unsigned int dst_y,           /* dest pos y */
-    unsigned int dim_x,           /* frame width */
-    unsigned int dim_y            /* frame height */
-    )
-{
-    register GraphicDevice *pGD = (GraphicDevice *)&sed13806;
-    unsigned long      srcAddr, dstAddr;
-    unsigned int stride = bpp * pGD -> winSizeX;
-
-    srcAddr = (src_y * stride) + (src_x * bpp);
-    dstAddr = (dst_y * stride) + (dst_x * bpp);
-
-    Epson_wait_idle ();
-
-    writeByte(BLT_ROP,0x0C);   /* source */
-    writeByte(BLT_OP,0x02);/* move blit in positive direction with ROP */
-    writeWord(BLT_MEM_OFF0, stride / 2);
-    if (pGD -> gdfIndex == GDF__8BIT_INDEX) {
-       writeByte(BLT_CTRL1,0x00);
-    }
-    else {
-       writeByte(BLT_CTRL1,0x01);
-    }
-
-    writeWord(BLT_WIDTH0,(dim_x - 1));
-    writeWord(BLT_HEIGHT0,(dim_y - 1));
-
-    /* set up blit registers                                                 */
-    writeByte(BLT_SRC_ADDR0,srcAddr);
-    writeByte(BLT_SRC_ADDR1,srcAddr>>8);
-    writeByte(BLT_SRC_ADDR2,srcAddr>>16);
-
-    writeByte(BLT_DST_ADDR0,dstAddr);
-    writeByte(BLT_DST_ADDR1,dstAddr>>8);
-    writeByte(BLT_DST_ADDR2,dstAddr>>16);
-
-    /* Engage the blt engine                                                 */
-    /* rectangular region for src and dst                                    */
-    writeByte(BLT_CTRL0,0x80);
-
-    /* wait untill current blits finished                                    */
-    Epson_wait_idle ();
-}
-/*-----------------------------------------------------------------------------
- * video_hw_rectfill --
- *-----------------------------------------------------------------------------
- */
-void video_hw_rectfill (
-    unsigned int bpp,             /* bytes per pixel */
-    unsigned int dst_x,           /* dest pos x */
-    unsigned int dst_y,           /* dest pos y */
-    unsigned int dim_x,           /* frame width */
-    unsigned int dim_y,           /* frame height */
-    unsigned int color            /* fill color */
-     )
-{
-    register GraphicDevice *pGD = (GraphicDevice *)&sed13806;
-    unsigned long      dstAddr;
-    unsigned int stride = bpp * pGD -> winSizeX;
-
-    dstAddr = (dst_y * stride) + (dst_x * bpp);
-
-    Epson_wait_idle ();
-
-    /* set up blit registers                                                 */
-    writeByte(BLT_DST_ADDR0,dstAddr);
-    writeByte(BLT_DST_ADDR1,dstAddr>>8);
-    writeByte(BLT_DST_ADDR2,dstAddr>>16);
-
-    writeWord(BLT_WIDTH0,(dim_x - 1));
-    writeWord(BLT_HEIGHT0,(dim_y - 1));
-    writeWord(BLT_FGCOLOR0,color);
-
-    writeByte(BLT_OP,0x0C);  /* solid fill                                   */
-    writeWord(BLT_MEM_OFF0,stride / 2);
-
-    if (pGD -> gdfIndex == GDF__8BIT_INDEX) {
-       writeByte(BLT_CTRL1,0x00);
-    }
-    else {
-       writeByte(BLT_CTRL1,0x01);
-    }
-
-    /* Engage the blt engine                                                 */
-    /* rectangular region for src and dst                                    */
-    writeByte(BLT_CTRL0,0x80);
-
-    /* wait untill current blits finished                                    */
-    Epson_wait_idle ();
-}
-
-/*-----------------------------------------------------------------------------
- * video_set_lut --
- *-----------------------------------------------------------------------------
- */
-void video_set_lut (
-    unsigned int index,           /* color number */
-    unsigned char r,              /* red */
-    unsigned char g,              /* green */
-    unsigned char b               /* blue */
-    )
-{
-    writeByte(REG_LUT_ADDR, index );
-    writeByte(REG_LUT_DATA, r);
-    writeByte(REG_LUT_DATA, g);
-    writeByte(REG_LUT_DATA, b);
-}
-#ifdef CONFIG_VIDEO_HW_CURSOR
-/*-----------------------------------------------------------------------------
- * video_set_hw_cursor --
- *-----------------------------------------------------------------------------
- */
-void video_set_hw_cursor (int x, int y)
-{
-    writeByte (LCD_CURSOR_XL, (x & 0xff));
-    writeByte (LCD_CURSOR_XM, (x >> 8));
-    writeByte (LCD_CURSOR_YL, (y & 0xff));
-    writeByte (LCD_CURSOR_YM, (y >> 8));
-}
-
-/*-----------------------------------------------------------------------------
- * video_init_hw_cursor --
- *-----------------------------------------------------------------------------
- */
-void video_init_hw_cursor (int font_width, int font_height)
-{
-    volatile unsigned char *ptr;
-    unsigned char pattern;
-    int i;
-
-
-    /* Init cursor content
-       Cursor size is 64x64 pixels
-       Start of the cursor memory depends on panel type (dual panel ...)     */
-    if ((i = readByte (LCD_CURSOR_START)) == 0) {
-       ptr = (unsigned char *)(sed13806.frameAdrs + DEFAULT_VIDEO_MEMORY_SIZE - HWCURSORSIZE);
-    }
-    else {
-       ptr = (unsigned char *)(sed13806.frameAdrs + DEFAULT_VIDEO_MEMORY_SIZE - (i * 8192));
-    }
-
-    /* Fill the first line and the first empty line after cursor             */
-    for (i = 0, pattern = 0; i < 64; i++) {
-       if (i < font_width) {
-           /* Invert background                                             */
-           pattern |= 0x3;
-
-       }
-       else {
-           /* Background                                                    */
-           pattern |= 0x2;
-       }
-       if ((i & 3) == 3) {
-           *ptr = pattern;
-           *(ptr + font_height * 16) = 0xaa;
-           ptr ++;
-           pattern = 0;
-       }
-       pattern <<= 2;
-    }
-
-    /* Duplicate this line                                                   */
-    for (i = 1; i < font_height; i++) {
-       memcpy ((void *)ptr, (void *)(ptr - 16), 16);
-       ptr += 16;
-    }
-
-    for (; i < 64; i++) {
-       memcpy ((void *)(ptr + 16), (void *)ptr, 16);
-       ptr += 16;
-    }
-
-    /* Select cursor mode                                                    */
-    writeByte (LCD_CURSOR_CNTL, 1);
-}
-#endif
-#endif
diff --git a/drivers/sed156x.c b/drivers/sed156x.c
deleted file mode 100644 (file)
index e9d5ed4..0000000
+++ /dev/null
@@ -1,566 +0,0 @@
-/*
- * (C) Copyright 2003
- *
- * Pantelis Antoniou <panto@intracom.gr>
- * Intracom S.A.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <watchdog.h>
-
-#include <sed156x.h>
-
-#ifdef CONFIG_SED156X
-
-/* configure according to the selected display */
-#if defined(CONFIG_SED156X_PG12864Q)
-#define LCD_WIDTH      128
-#define LCD_HEIGHT     64
-#define LCD_LINES      64
-#define LCD_PAGES      9
-#define LCD_COLUMNS    132
-#else
-#error Unsupported SED156x configuration
-#endif
-
-/* include the font data */
-#include <video_font.h>
-
-#if VIDEO_FONT_WIDTH != 8 || VIDEO_FONT_HEIGHT != 16
-#error Expecting VIDEO_FONT_WIDTH == 8 && VIDEO_FONT_HEIGHT == 16
-#endif
-
-#define LCD_BYTE_WIDTH         (LCD_WIDTH / 8)
-#define VIDEO_FONT_BYTE_WIDTH  (VIDEO_FONT_WIDTH / 8)
-
-#define LCD_TEXT_WIDTH (LCD_WIDTH / VIDEO_FONT_WIDTH)
-#define LCD_TEXT_HEIGHT (LCD_HEIGHT / VIDEO_FONT_HEIGHT)
-
-#define LCD_BYTE_LINESZ                (LCD_BYTE_WIDTH * VIDEO_FONT_HEIGHT)
-
-const int sed156x_text_width = LCD_TEXT_WIDTH;
-const int sed156x_text_height = LCD_TEXT_HEIGHT;
-
-/**************************************************************************************/
-
-#define SED156X_SPI_RXD() (SED156X_SPI_RXD_PORT & SED156X_SPI_RXD_MASK)
-
-#define SED156X_SPI_TXD(x) \
-       do { \
-               if (x) \
-                       SED156X_SPI_TXD_PORT |=  SED156X_SPI_TXD_MASK; \
-               else \
-                       SED156X_SPI_TXD_PORT &= ~SED156X_SPI_TXD_MASK; \
-       } while(0)
-
-#define SED156X_SPI_CLK(x) \
-       do { \
-               if (x) \
-                       SED156X_SPI_CLK_PORT |=  SED156X_SPI_CLK_MASK; \
-               else \
-                       SED156X_SPI_CLK_PORT &= ~SED156X_SPI_CLK_MASK; \
-       } while(0)
-
-#define SED156X_SPI_CLK_TOGGLE() (SED156X_SPI_CLK_PORT ^= SED156X_SPI_CLK_MASK)
-
-#define SED156X_SPI_BIT_DELAY() /* no delay */
-
-#define SED156X_CS(x) \
-       do { \
-               if (x) \
-                       SED156X_CS_PORT |=  SED156X_CS_MASK; \
-               else \
-                       SED156X_CS_PORT &= ~SED156X_CS_MASK; \
-       } while(0)
-
-#define SED156X_A0(x) \
-       do { \
-               if (x) \
-                       SED156X_A0_PORT |=  SED156X_A0_MASK; \
-               else \
-                       SED156X_A0_PORT &= ~SED156X_A0_MASK; \
-       } while(0)
-
-/**************************************************************************************/
-
-/*** LCD Commands ***/
-
-#define LCD_ON         0xAF    /* Display ON                                         */
-#define LCD_OFF                0xAE    /* Display OFF                                        */
-#define LCD_LADDR      0x40    /* Display start line set + (6-bit) address           */
-#define LCD_PADDR      0xB0    /* Page address set + (4-bit) page                    */
-#define LCD_CADRH      0x10    /* Column address set upper + (4-bit) column hi       */
-#define LCD_CADRL      0x00    /* Column address set lower + (4-bit) column lo       */
-#define LCD_ADC_NRM    0xA0    /* ADC select Normal                                  */
-#define LCD_ADC_REV    0xA1    /* ADC select Reverse                                 */
-#define LCD_DSP_NRM    0xA6    /* LCD display Normal                                 */
-#define LCD_DSP_REV    0xA7    /* LCD display Reverse                                */
-#define LCD_DPT_NRM    0xA4    /* Display all points Normal                          */
-#define LCD_DPT_ALL    0xA5    /* Display all points ON                              */
-#define LCD_BIAS9      0xA2    /* LCD bias set 1/9                                   */
-#define LCD_BIAS7      0xA3    /* LCD bias set 1/7                                   */
-#define LCD_CAINC      0xE0    /* Read/modify/write                                  */
-#define LCD_CAEND      0xEE    /* End                                                */
-#define LCD_RESET      0xE2    /* Reset                                              */
-#define LCD_C_NRM      0xC0    /* Common output mode select Normal direction         */
-#define LCD_C_RVS      0xC8    /* Common output mode select Reverse direction        */
-#define LCD_PWRMD      0x28    /* Power control set + (3-bit) mode                   */
-#define LCD_RESRT      0x20    /* V5 v. reg. int. resistor ratio set + (3-bit) ratio */
-#define LCD_EVSET      0x81    /* Electronic volume mode set + byte = (6-bit) volume */
-#define LCD_SIOFF      0xAC    /* Static indicator OFF                               */
-#define LCD_SION       0xAD    /* Static indicator ON + byte = (2-bit) mode          */
-#define LCD_NOP                0xE3    /* NOP                                                */
-#define LCD_TEST       0xF0    /* Test/Test mode reset (Note: *DO NOT USE*)          */
-
-/*-------------------------------------------------------------------------------
-  Compound commands
-  -------------------------------------------------------------------------------
-  Command      Description                     Commands
-  ----------   ------------------------        -------------------------------------
-  POWS_ON      POWER SAVER ON command          LCD_OFF, LCD_D_ALL
-  POWS_OFF     POWER SAVER OFF command         LCD_D_NRM
-  SLEEPON      SLEEP mode                      LCD_SIOFF, POWS_ON
-  SLEEPOFF     SLEEP mode cancel               LCD_D_NRM, LCD_SION, LCD_SIS_???
-  STDBYON      STAND BY mode                   LCD_SION, POWS_ON
-  STDBYOFF     STAND BY mode cancel            LCD_D_NRM
-  -------------------------------------------------------------------------------*/
-
-/*** LCD various parameters ***/
-#define LCD_PPB                8       /* Pixels per byte (display is B/W, 1 bit per pixel) */
-
-/*** LCD Status byte masks ***/
-#define LCD_S_BUSY     0x80    /* Status Read - BUSY mask   */
-#define LCD_S_ADC      0x40    /* Status Read - ADC mask    */
-#define LCD_S_ONOFF    0x20    /* Status Read - ON/OFF mask */
-#define LCD_S_RESET    0x10    /* Status Read - RESET mask  */
-
-/*** LCD commands parameter masks ***/
-#define LCD_M_LADDR    0x3F    /* Display start line (6-bit) address mask           */
-#define LCD_M_PADDR    0x0F    /* Page address (4-bit) page mask                    */
-#define LCD_M_CADRH    0x0F    /* Column address upper (4-bit) column hi mask       */
-#define LCD_M_CADRL    0x0F    /* Column address lower (4-bit) column lo mask       */
-#define LCD_M_PWRMD    0x07    /* Power control (3-bit) mode mask                   */
-#define LCD_M_RESRT    0x07    /* V5 v. reg. int. resistor ratio (3-bit) ratio mask */
-#define LCD_M_EVSET    0x3F    /* Electronic volume mode byte (6-bit) volume mask   */
-#define LCD_M_SION     0x03    /* Static indicator ON (2-bit) mode mask             */
-
-/*** LCD Power control cirquits control masks ***/
-#define LCD_PWRBSTR    0x04    /* Power control mode - Booster cirquit ON           */
-#define LCD_PWRVREG    0x02    /* Power control mode - Voltage regulator cirquit ON */
-#define LCD_PWRVFOL    0x01    /* Power control mode - Voltage follower cirquit ON  */
-
-/*** LCD Static indicator states ***/
-#define LCD_SIS_OFF    0x00    /* Static indicator register set - OFF state             */
-#define LCD_SIS_BL     0x01    /* Static indicator register set - 1s blink state        */
-#define LCD_SIS_RBL    0x02    /* Static indicator register set - .5s rapid blink state */
-#define LCD_SIS_ON     0x03    /* Static indicator register set - constantly on state   */
-
-/*** LCD functions special parameters (commands) ***/
-#define LCD_PREVP      0x80    /* Page number for moving to previous */
-#define LCD_NEXTP      0x81    /* or next page */
-#define LCD_ERR_P      0xFF    /* Error in page number */
-
-/*** LCD initialization settings ***/
-#define LCD_BIAS       LCD_BIAS9       /* Bias: 1/9                  */
-#define LCD_ADCMODE    LCD_ADC_NRM     /* ADC mode: normal           */
-#define LCD_COMDIR     LCD_C_NRM       /* Common output mode: normal */
-#define LCD_RRATIO     0               /* Resistor ratio: 0          */
-#define LCD_CNTRST     0x1C            /* electronic volume: 1Ch     */
-#define LCD_POWERM     (LCD_PWRBSTR | LCD_PWRVREG | LCD_PWRVFOL)       /* Power mode: All on */
-
-/**************************************************************************************/
-
-static inline unsigned int sed156x_transfer(unsigned int val)
-{
-       unsigned int rx;
-       int b;
-
-       rx = 0; b = 8;
-       while (--b >= 0) {
-               SED156X_SPI_TXD(val & 0x80);
-               val <<= 1;
-               SED156X_SPI_CLK_TOGGLE();
-               SED156X_SPI_BIT_DELAY();
-               rx <<= 1;
-               if (SED156X_SPI_RXD())
-                       rx |= 1;
-               SED156X_SPI_CLK_TOGGLE();
-               SED156X_SPI_BIT_DELAY();
-       }
-
-       return rx;
-}
-
-unsigned int sed156x_data_transfer(unsigned int val)
-{
-       unsigned int rx;
-
-       SED156X_SPI_CLK(1);
-       SED156X_CS(0);
-       SED156X_A0(1);
-
-       rx = sed156x_transfer(val);
-
-       SED156X_CS(1);
-
-       return rx;
-}
-
-void sed156x_data_block_transfer(const u8 *p, int size)
-{
-       SED156X_SPI_CLK(1);
-       SED156X_CS(0);
-       SED156X_A0(1);
-
-       while (--size >= 0)
-               sed156x_transfer(*p++);
-
-       SED156X_CS(1);
-}
-
-unsigned int sed156x_cmd_transfer(unsigned int val)
-{
-       unsigned int rx;
-
-       SED156X_SPI_CLK(1);
-       SED156X_CS(0);
-       SED156X_A0(0);
-
-       rx = sed156x_transfer(val);
-
-       SED156X_CS(1);
-       SED156X_A0(1);
-
-       return rx;
-}
-
-/******************************************************************************/
-
-static u8 hw_screen[LCD_PAGES][LCD_COLUMNS];
-static u8 last_hw_screen[LCD_PAGES][LCD_COLUMNS];
-static u8 sw_screen[LCD_BYTE_WIDTH * LCD_HEIGHT];
-
-void sed156x_sync(void)
-{
-       int i, j, last_page;
-       u8 *d;
-       const u8 *s, *e, *b, *r;
-       u8 v0, v1, v2, v3, v4, v5, v6, v7;
-
-       /* copy and rotate sw_screen to hw_screen */
-       for (i = 0; i < LCD_HEIGHT / 8; i++) {
-
-               d = &hw_screen[i][0];
-               s = &sw_screen[LCD_BYTE_WIDTH * 8 * i + LCD_BYTE_WIDTH - 1];
-
-               for (j = 0; j < LCD_WIDTH / 8; j++) {
-
-                       v0 = s[0 * LCD_BYTE_WIDTH];
-                       v1 = s[1 * LCD_BYTE_WIDTH];
-                       v2 = s[2 * LCD_BYTE_WIDTH];
-                       v3 = s[3 * LCD_BYTE_WIDTH];
-                       v4 = s[4 * LCD_BYTE_WIDTH];
-                       v5 = s[5 * LCD_BYTE_WIDTH];
-                       v6 = s[6 * LCD_BYTE_WIDTH];
-                       v7 = s[7 * LCD_BYTE_WIDTH];
-
-                       d[0] =  ((v7 & 0x01) << 7) |
-                               ((v6 & 0x01) << 6) |
-                               ((v5 & 0x01) << 5) |
-                               ((v4 & 0x01) << 4) |
-                               ((v3 & 0x01) << 3) |
-                               ((v2 & 0x01) << 2) |
-                               ((v1 & 0x01) << 1) |
-                                (v0 & 0x01)       ;
-
-                       d[1] =  ((v7 & 0x02) << 6) |
-                               ((v6 & 0x02) << 5) |
-                               ((v5 & 0x02) << 4) |
-                               ((v4 & 0x02) << 3) |
-                               ((v3 & 0x02) << 2) |
-                               ((v2 & 0x02) << 1) |
-                               ((v1 & 0x02) << 0) |
-                               ((v0 & 0x02) >> 1) ;
-
-                       d[2] =  ((v7 & 0x04) << 5) |
-                               ((v6 & 0x04) << 4) |
-                               ((v5 & 0x04) << 3) |
-                               ((v4 & 0x04) << 2) |
-                               ((v3 & 0x04) << 1) |
-                                (v2 & 0x04)       |
-                               ((v1 & 0x04) >> 1) |
-                               ((v0 & 0x04) >> 2) ;
-
-                       d[3] =  ((v7 & 0x08) << 4) |
-                               ((v6 & 0x08) << 3) |
-                               ((v5 & 0x08) << 2) |
-                               ((v4 & 0x08) << 1) |
-                                (v3 & 0x08)       |
-                               ((v2 & 0x08) >> 1) |
-                               ((v1 & 0x08) >> 2) |
-                               ((v0 & 0x08) >> 3) ;
-
-                       d[4] =  ((v7 & 0x10) << 3) |
-                               ((v6 & 0x10) << 2) |
-                               ((v5 & 0x10) << 1) |
-                                (v4 & 0x10)       |
-                               ((v3 & 0x10) >> 1) |
-                               ((v2 & 0x10) >> 2) |
-                               ((v1 & 0x10) >> 3) |
-                               ((v0 & 0x10) >> 4) ;
-
-                       d[5] =  ((v7 & 0x20) << 2) |
-                               ((v6 & 0x20) << 1) |
-                                (v5 & 0x20)       |
-                               ((v4 & 0x20) >> 1) |
-                               ((v3 & 0x20) >> 2) |
-                               ((v2 & 0x20) >> 3) |
-                               ((v1 & 0x20) >> 4) |
-                               ((v0 & 0x20) >> 5) ;
-
-                       d[6] =  ((v7 & 0x40) << 1) |
-                                (v6 & 0x40)       |
-                               ((v5 & 0x40) >> 1) |
-                               ((v4 & 0x40) >> 2) |
-                               ((v3 & 0x40) >> 3) |
-                               ((v2 & 0x40) >> 4) |
-                               ((v1 & 0x40) >> 5) |
-                               ((v0 & 0x40) >> 6) ;
-
-                       d[7] =   (v7 & 0x80)       |
-                               ((v6 & 0x80) >> 1) |
-                               ((v5 & 0x80) >> 2) |
-                               ((v4 & 0x80) >> 3) |
-                               ((v3 & 0x80) >> 4) |
-                               ((v2 & 0x80) >> 5) |
-                               ((v1 & 0x80) >> 6) |
-                               ((v0 & 0x80) >> 7) ;
-
-                       d += 8;
-                       s--;
-               }
-       }
-
-       /* and now output only the differences */
-       for (i = 0; i < LCD_PAGES; i++) {
-
-               b = &hw_screen[i][0];
-               e = &hw_screen[i][LCD_COLUMNS];
-
-               d = &last_hw_screen[i][0];
-               s = b;
-
-               last_page = -1;
-
-               /* update only the differences */
-               do {
-                       while (s < e && *s == *d) {
-                               s++;
-                               d++;
-                       }
-                       if (s == e)
-                               break;
-                       r = s;
-                       while (s < e && *s != *d)
-                               *d++ = *s++;
-
-                       j = r - b;
-
-                       if (i != last_page) {
-                               sed156x_cmd_transfer(LCD_PADDR | i);
-                               last_page = i;
-                       }
-
-                       sed156x_cmd_transfer(LCD_CADRH | ((j >> 4) & 0x0F));
-                       sed156x_cmd_transfer(LCD_CADRL | (j & 0x0F));
-                       sed156x_data_block_transfer(r, s - r);
-
-               } while (s < e);
-       }
-
-/********
-       for (i = 0; i < LCD_PAGES; i++) {
-               sed156x_cmd_transfer(LCD_PADDR | i);
-               sed156x_cmd_transfer(LCD_CADRH | 0);
-               sed156x_cmd_transfer(LCD_CADRL | 0);
-               sed156x_data_block_transfer(&hw_screen[i][0], LCD_COLUMNS);
-       }
-       memcpy(last_hw_screen, hw_screen, sizeof(last_hw_screen));
-********/
-}
-
-void sed156x_clear(void)
-{
-       memset(sw_screen, 0, sizeof(sw_screen));
-}
-
-void sed156x_output_at(int x, int y, const char *str, int size)
-{
-       int i, j;
-       u8 *p;
-       const u8 *s;
-
-       if ((unsigned int)y >= LCD_TEXT_HEIGHT || (unsigned int)x >= LCD_TEXT_WIDTH)
-               return;
-
-       p = &sw_screen[y * VIDEO_FONT_HEIGHT * LCD_BYTE_WIDTH + x * VIDEO_FONT_BYTE_WIDTH];
-
-       while (--size >= 0) {
-
-               s = &video_fontdata[((int)*str++ & 0xff) * VIDEO_FONT_BYTE_WIDTH * VIDEO_FONT_HEIGHT];
-               for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
-                       for (j = 0; j < VIDEO_FONT_BYTE_WIDTH; j++)
-                               *p++ = *s++;
-                       p += LCD_BYTE_WIDTH - VIDEO_FONT_BYTE_WIDTH;
-               }
-               p -= (LCD_BYTE_LINESZ - VIDEO_FONT_BYTE_WIDTH);
-
-               if (x >= LCD_TEXT_WIDTH)
-                       break;
-               x++;
-       }
-}
-
-void sed156x_reverse_at(int x, int y, int size)
-{
-       int i, j;
-       u8 *p;
-
-       if ((unsigned int)y >= LCD_TEXT_HEIGHT || (unsigned int)x >= LCD_TEXT_WIDTH)
-               return;
-
-       p = &sw_screen[y * VIDEO_FONT_HEIGHT * LCD_BYTE_WIDTH + x * VIDEO_FONT_BYTE_WIDTH];
-
-       while (--size >= 0) {
-
-               for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
-                       for (j = 0; j < VIDEO_FONT_BYTE_WIDTH; j++, p++)
-                               *p = ~*p;
-                       p += LCD_BYTE_WIDTH - VIDEO_FONT_BYTE_WIDTH;
-               }
-               p -= (LCD_BYTE_LINESZ - VIDEO_FONT_BYTE_WIDTH);
-
-               if (x >= LCD_TEXT_WIDTH)
-                       break;
-               x++;
-       }
-}
-
-void sed156x_scroll_line(void)
-{
-       memmove(&sw_screen[0],
-                       &sw_screen[LCD_BYTE_LINESZ],
-                       LCD_BYTE_WIDTH * (LCD_HEIGHT - VIDEO_FONT_HEIGHT));
-}
-
-void sed156x_scroll(int dx, int dy)
-{
-       u8 *p1 = NULL, *p2 = NULL, *p3 = NULL;  /* pacify gcc */
-       int adx, ady, i, sz;
-
-       adx = dx > 0 ? dx : -dx;
-       ady = dy > 0 ? dy : -dy;
-
-       /* overscroll? erase everything */
-       if (adx >= LCD_TEXT_WIDTH || ady >= LCD_TEXT_HEIGHT) {
-               memset(sw_screen, 0, sizeof(sw_screen));
-               return;
-       }
-
-       sz = LCD_BYTE_LINESZ * ady;
-       if (dy > 0) {
-               p1 = &sw_screen[0];
-               p2 = &sw_screen[sz];
-               p3 = &sw_screen[LCD_BYTE_WIDTH * LCD_HEIGHT - sz];
-       } else if (dy < 0) {
-               p1 = &sw_screen[sz];
-               p2 = &sw_screen[0];
-               p3 = &sw_screen[0];
-       }
-
-       if (ady > 0) {
-               memmove(p1, p2, LCD_BYTE_WIDTH * LCD_HEIGHT - sz);
-               memset(p3, 0, sz);
-       }
-
-       sz = VIDEO_FONT_BYTE_WIDTH * adx;
-       if (dx > 0) {
-               p1 = &sw_screen[0];
-               p2 = &sw_screen[0] + sz;
-               p3 = &sw_screen[0] + LCD_BYTE_WIDTH - sz;
-       } else if (dx < 0) {
-               p1 = &sw_screen[0] + sz;
-               p2 = &sw_screen[0];
-               p3 = &sw_screen[0];
-       }
-
-       /* xscroll */
-       if (adx > 0) {
-               for (i = 0; i < LCD_HEIGHT; i++) {
-                       memmove(p1, p2, LCD_BYTE_WIDTH - sz);
-                       memset(p3, 0, sz);
-                       p1 += LCD_BYTE_WIDTH;
-                       p2 += LCD_BYTE_WIDTH;
-                       p3 += LCD_BYTE_WIDTH;
-               }
-       }
-}
-
-void sed156x_init(void)
-{
-       int i;
-
-       SED156X_CS(1);
-       SED156X_A0(1);
-
-       /* Send initialization commands to the LCD */
-       sed156x_cmd_transfer(LCD_OFF);                  /* Turn display OFF       */
-       sed156x_cmd_transfer(LCD_BIAS);                 /* set the LCD Bias,      */
-       sed156x_cmd_transfer(LCD_ADCMODE);              /* ADC mode,              */
-       sed156x_cmd_transfer(LCD_COMDIR);               /* common output mode,    */
-       sed156x_cmd_transfer(LCD_RESRT | LCD_RRATIO);   /* resistor ratio,        */
-       sed156x_cmd_transfer(LCD_EVSET);                /* electronic volume,     */
-       sed156x_cmd_transfer(LCD_CNTRST);
-       sed156x_cmd_transfer(LCD_PWRMD | LCD_POWERM);   /* and power mode         */
-       sed156x_cmd_transfer(LCD_PADDR | 0);            /* cursor home            */
-       sed156x_cmd_transfer(LCD_CADRH | 0);
-       sed156x_cmd_transfer(LCD_CADRL | 0);
-       sed156x_cmd_transfer(LCD_LADDR | 0);            /* and display start line */
-       sed156x_cmd_transfer(LCD_DSP_NRM);              /* LCD display Normal     */
-
-       /* clear everything */
-       memset(sw_screen, 0, sizeof(sw_screen));
-       memset(hw_screen, 0, sizeof(hw_screen));
-       memset(last_hw_screen, 0, sizeof(last_hw_screen));
-
-       for (i = 0; i < LCD_PAGES; i++) {
-               sed156x_cmd_transfer(LCD_PADDR | i);
-               sed156x_cmd_transfer(LCD_CADRH | 0);
-               sed156x_cmd_transfer(LCD_CADRL | 0);
-               sed156x_data_block_transfer(&hw_screen[i][0], LCD_COLUMNS);
-       }
-
-       sed156x_clear();
-       sed156x_sync();
-       sed156x_cmd_transfer(LCD_ON);                   /* Turn display ON        */
-}
-
-#endif /* CONFIG_SED156X */
diff --git a/drivers/serial.c b/drivers/serial.c
deleted file mode 100644 (file)
index 76425d8..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * (C) Copyright 2000
- * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-
-#ifdef CFG_NS16550_SERIAL
-
-#include <ns16550.h>
-#ifdef CFG_NS87308
-#include <ns87308.h>
-#endif
-
-#if defined (CONFIG_SERIAL_MULTI)
-#include <serial.h>
-#endif
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#if !defined(CONFIG_CONS_INDEX)
-#if defined (CONFIG_SERIAL_MULTI)
-/*   with CONFIG_SERIAL_MULTI we might have no console
- *  on these devices
- */
-#else
-#error "No console index specified."
-#endif /* CONFIG_SERIAL_MULTI */
-#elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 4)
-#error "Invalid console index value."
-#endif
-
-#if CONFIG_CONS_INDEX == 1 && !defined(CFG_NS16550_COM1)
-#error "Console port 1 defined but not configured."
-#elif CONFIG_CONS_INDEX == 2 && !defined(CFG_NS16550_COM2)
-#error "Console port 2 defined but not configured."
-#elif CONFIG_CONS_INDEX == 3 && !defined(CFG_NS16550_COM3)
-#error "Console port 3 defined but not configured."
-#elif CONFIG_CONS_INDEX == 4 && !defined(CFG_NS16550_COM4)
-#error "Console port 4 defined but not configured."
-#endif
-
-/* Note: The port number specified in the functions is 1 based.
- *      the array is 0 based.
- */
-static NS16550_t serial_ports[4] = {
-#ifdef CFG_NS16550_COM1
-       (NS16550_t)CFG_NS16550_COM1,
-#else
-       NULL,
-#endif
-#ifdef CFG_NS16550_COM2
-       (NS16550_t)CFG_NS16550_COM2,
-#else
-       NULL,
-#endif
-#ifdef CFG_NS16550_COM3
-       (NS16550_t)CFG_NS16550_COM3,
-#else
-       NULL,
-#endif
-#ifdef CFG_NS16550_COM4
-       (NS16550_t)CFG_NS16550_COM4
-#else
-       NULL
-#endif
-};
-
-#define PORT   serial_ports[port-1]
-#if defined(CONFIG_CONS_INDEX)
-#define CONSOLE        (serial_ports[CONFIG_CONS_INDEX-1])
-#endif
-
-#if defined(CONFIG_SERIAL_MULTI)
-
-/* Multi serial device functions */
-#define DECLARE_ESERIAL_FUNCTIONS(port) \
-    int  eserial##port##_init (void) {\
-       int clock_divisor; \
-       clock_divisor = calc_divisor(serial_ports[port-1]); \
-       NS16550_init(serial_ports[port-1], clock_divisor); \
-       return(0);}\
-    void eserial##port##_setbrg (void) {\
-       serial_setbrg_dev(port);}\
-    int  eserial##port##_getc (void) {\
-       return serial_getc_dev(port);}\
-    int  eserial##port##_tstc (void) {\
-       return serial_tstc_dev(port);}\
-    void eserial##port##_putc (const char c) {\
-       serial_putc_dev(port, c);}\
-    void eserial##port##_puts (const char *s) {\
-       serial_puts_dev(port, s);}
-
-/* Serial device descriptor */
-#define INIT_ESERIAL_STRUCTURE(port,name,bus) {\
-       name,\
-       bus,\
-       eserial##port##_init,\
-       eserial##port##_setbrg,\
-       eserial##port##_getc,\
-       eserial##port##_tstc,\
-       eserial##port##_putc,\
-       eserial##port##_puts, }
-
-#endif /* CONFIG_SERIAL_MULTI */
-
-static int calc_divisor (NS16550_t port)
-{
-#ifdef CONFIG_OMAP1510
-       /* If can't cleanly clock 115200 set div to 1 */
-       if ((CFG_NS16550_CLK == 12000000) && (gd->baudrate == 115200)) {
-               port->osc_12m_sel = OSC_12M_SEL;        /* enable 6.5 * divisor */
-               return (1);                             /* return 1 for base divisor */
-       }
-       port->osc_12m_sel = 0;                  /* clear if previsouly set */
-#endif
-#ifdef CONFIG_OMAP1610
-       /* If can't cleanly clock 115200 set div to 1 */
-       if ((CFG_NS16550_CLK == 48000000) && (gd->baudrate == 115200)) {
-               return (26);            /* return 26 for base divisor */
-       }
-#endif
-
-#ifdef CONFIG_APTIX
-#define MODE_X_DIV 13
-#else
-#define MODE_X_DIV 16
-#endif
-       return (CFG_NS16550_CLK / MODE_X_DIV / gd->baudrate);
-
-}
-
-#if !defined(CONFIG_SERIAL_MULTI)
-int serial_init (void)
-{
-       int clock_divisor;
-
-#ifdef CFG_NS87308
-       initialise_ns87308();
-#endif
-
-#ifdef CFG_NS16550_COM1
-       clock_divisor = calc_divisor(serial_ports[0]);
-       NS16550_init(serial_ports[0], clock_divisor);
-#endif
-#ifdef CFG_NS16550_COM2
-       clock_divisor = calc_divisor(serial_ports[1]);
-       NS16550_init(serial_ports[1], clock_divisor);
-#endif
-#ifdef CFG_NS16550_COM3
-       clock_divisor = calc_divisor(serial_ports[2]);
-       NS16550_init(serial_ports[2], clock_divisor);
-#endif
-#ifdef CFG_NS16550_COM4
-       clock_divisor = calc_divisor(serial_ports[3]);
-       NS16550_init(serial_ports[3], clock_divisor);
-#endif
-
-       return (0);
-}
-#endif
-
-void
-_serial_putc(const char c,const int port)
-{
-       if (c == '\n')
-               NS16550_putc(PORT, '\r');
-
-       NS16550_putc(PORT, c);
-}
-
-void
-_serial_putc_raw(const char c,const int port)
-{
-       NS16550_putc(PORT, c);
-}
-
-void
-_serial_puts (const char *s,const int port)
-{
-       while (*s) {
-               _serial_putc (*s++,port);
-       }
-}
-
-
-int
-_serial_getc(const int port)
-{
-       return NS16550_getc(PORT);
-}
-
-int
-_serial_tstc(const int port)
-{
-       return NS16550_tstc(PORT);
-}
-
-void
-_serial_setbrg (const int port)
-{
-       int clock_divisor;
-
-       clock_divisor = calc_divisor(PORT);
-       NS16550_reinit(PORT, clock_divisor);
-}
-
-#if defined(CONFIG_SERIAL_MULTI)
-static inline void
-serial_putc_dev(unsigned int dev_index,const char c)
-{
-       _serial_putc(c,dev_index);
-}
-#else
-void
-serial_putc(const char c)
-{
-       _serial_putc(c,CONFIG_CONS_INDEX);
-}
-#endif
-
-#if defined(CONFIG_SERIAL_MULTI)
-static inline void
-serial_putc_raw_dev(unsigned int dev_index,const char c)
-{
-       _serial_putc_raw(c,dev_index);
-}
-#else
-void
-serial_putc_raw(const char c)
-{
-       _serial_putc_raw(c,CONFIG_CONS_INDEX);
-}
-#endif
-
-#if defined(CONFIG_SERIAL_MULTI)
-static inline void
-serial_puts_dev(unsigned int dev_index,const char *s)
-{
-       _serial_puts(s,dev_index);
-}
-#else
-void
-serial_puts(const char *s)
-{
-       _serial_puts(s,CONFIG_CONS_INDEX);
-}
-#endif
-
-#if defined(CONFIG_SERIAL_MULTI)
-static inline int
-serial_getc_dev(unsigned int dev_index)
-{
-       return _serial_getc(dev_index);
-}
-#else
-int
-serial_getc(void)
-{
-       return _serial_getc(CONFIG_CONS_INDEX);
-}
-#endif
-
-#if defined(CONFIG_SERIAL_MULTI)
-static inline int
-serial_tstc_dev(unsigned int dev_index)
-{
-       return _serial_tstc(dev_index);
-}
-#else
-int
-serial_tstc(void)
-{
-       return _serial_tstc(CONFIG_CONS_INDEX);
-}
-#endif
-
-#if defined(CONFIG_SERIAL_MULTI)
-static inline void
-serial_setbrg_dev(unsigned int dev_index)
-{
-       _serial_setbrg(dev_index);
-}
-#else
-void
-serial_setbrg(void)
-{
-       _serial_setbrg(CONFIG_CONS_INDEX);
-}
-#endif
-
-#if defined(CONFIG_SERIAL_MULTI)
-
-DECLARE_ESERIAL_FUNCTIONS(1);
-struct serial_device eserial1_device =
-       INIT_ESERIAL_STRUCTURE(1,"eserial0","EUART1");
-DECLARE_ESERIAL_FUNCTIONS(2);
-struct serial_device eserial2_device =
-       INIT_ESERIAL_STRUCTURE(2,"eserial1","EUART2");
-DECLARE_ESERIAL_FUNCTIONS(3);
-struct serial_device eserial3_device =
-       INIT_ESERIAL_STRUCTURE(3,"eserial2","EUART3");
-DECLARE_ESERIAL_FUNCTIONS(4);
-struct serial_device eserial4_device =
-       INIT_ESERIAL_STRUCTURE(4,"eserial3","EUART4");
-#endif /* CONFIG_SERIAL_MULTI */
-
-#endif
index 93c68dd2e08e7e9f5a12198d841b107f035da128..735c630006bd4751561cbc043ed5a1355a595523 100644 (file)
@@ -25,8 +25,19 @@ include $(TOPDIR)/config.mk
 
 LIB    := $(obj)libserial.a
 
-COBJS  := mcfuart.o
-
+COBJS-y += atmel_usart.o
+COBJS-y += mcfuart.o
+COBJS-y += ns9750_serial.o
+COBJS-y += ns16550.o
+COBJS-y += s3c4510b_uart.o
+COBJS-y += serial.o
+COBJS-y += serial_max3100.o
+COBJS-y += serial_pl010.o
+COBJS-y += serial_pl011.o
+COBJS-y += serial_xuartlite.o
+COBJS-y += usbtty.o
+
+COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS))
 
diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c
new file mode 100644 (file)
index 0000000..f35b997
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <common.h>
+
+#ifdef CONFIG_ATMEL_USART
+#include <asm/io.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/memory-map.h>
+
+#if defined(CONFIG_USART0)
+# define USART_ID      0
+# define USART_BASE    USART0_BASE
+#elif defined(CONFIG_USART1)
+# define USART_ID      1
+# define USART_BASE    USART1_BASE
+#elif defined(CONFIG_USART2)
+# define USART_ID      2
+# define USART_BASE    USART2_BASE
+#elif defined(CONFIG_USART3)
+# define USART_ID      3
+# define USART_BASE    USART3_BASE
+#endif
+
+#include "atmel_usart.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void serial_setbrg(void)
+{
+       unsigned long divisor;
+       unsigned long usart_hz;
+
+       /*
+        *              Master Clock
+        * Baud Rate = --------------
+        *                16 * CD
+        */
+       usart_hz = get_usart_clk_rate(USART_ID);
+       divisor = (usart_hz / 16 + gd->baudrate / 2) / gd->baudrate;
+       usart3_writel(BRGR, USART3_BF(CD, divisor));
+}
+
+int serial_init(void)
+{
+       usart3_writel(CR, USART3_BIT(RSTRX) | USART3_BIT(RSTTX));
+
+       serial_setbrg();
+
+       usart3_writel(CR, USART3_BIT(RXEN) | USART3_BIT(TXEN));
+       usart3_writel(MR, (USART3_BF(USART_MODE, USART3_USART_MODE_NORMAL)
+                          | USART3_BF(USCLKS, USART3_USCLKS_MCK)
+                          | USART3_BF(CHRL, USART3_CHRL_8)
+                          | USART3_BF(PAR, USART3_PAR_NONE)
+                          | USART3_BF(NBSTOP, USART3_NBSTOP_1)));
+
+       return 0;
+}
+
+void serial_putc(char c)
+{
+       if (c == '\n')
+               serial_putc('\r');
+
+       while (!(usart3_readl(CSR) & USART3_BIT(TXRDY))) ;
+       usart3_writel(THR, c);
+}
+
+void serial_puts(const char *s)
+{
+       while (*s)
+               serial_putc(*s++);
+}
+
+int serial_getc(void)
+{
+       while (!(usart3_readl(CSR) & USART3_BIT(RXRDY))) ;
+       return usart3_readl(RHR);
+}
+
+int serial_tstc(void)
+{
+       return (usart3_readl(CSR) & USART3_BIT(RXRDY)) != 0;
+}
+
+#endif /* CONFIG_ATMEL_USART */
diff --git a/drivers/serial/atmel_usart.h b/drivers/serial/atmel_usart.h
new file mode 100644 (file)
index 0000000..af3773a
--- /dev/null
@@ -0,0 +1,314 @@
+/*
+ * Register definitions for the Atmel USART3 module.
+ *
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __DRIVERS_ATMEL_USART_H__
+#define __DRIVERS_ATMEL_USART_H__
+
+/* USART3 register offsets */
+#define USART3_CR                              0x0000
+#define USART3_MR                              0x0004
+#define USART3_IER                             0x0008
+#define USART3_IDR                             0x000c
+#define USART3_IMR                             0x0010
+#define USART3_CSR                             0x0014
+#define USART3_RHR                             0x0018
+#define USART3_THR                             0x001c
+#define USART3_BRGR                            0x0020
+#define USART3_RTOR                            0x0024
+#define USART3_TTGR                            0x0028
+#define USART3_FIDI                            0x0040
+#define USART3_NER                             0x0044
+#define USART3_XXR                             0x0048
+#define USART3_IFR                             0x004c
+#define USART3_RPR                             0x0100
+#define USART3_RCR                             0x0104
+#define USART3_TPR                             0x0108
+#define USART3_TCR                             0x010c
+#define USART3_RNPR                            0x0110
+#define USART3_RNCR                            0x0114
+#define USART3_TNPR                            0x0118
+#define USART3_TNCR                            0x011c
+#define USART3_PTCR                            0x0120
+#define USART3_PTSR                            0x0124
+
+/* Bitfields in CR */
+#define USART3_RSTRX_OFFSET                    2
+#define USART3_RSTRX_SIZE                      1
+#define USART3_RSTTX_OFFSET                    3
+#define USART3_RSTTX_SIZE                      1
+#define USART3_RXEN_OFFSET                     4
+#define USART3_RXEN_SIZE                       1
+#define USART3_RXDIS_OFFSET                    5
+#define USART3_RXDIS_SIZE                      1
+#define USART3_TXEN_OFFSET                     6
+#define USART3_TXEN_SIZE                       1
+#define USART3_TXDIS_OFFSET                    7
+#define USART3_TXDIS_SIZE                      1
+#define USART3_RSTSTA_OFFSET                   8
+#define USART3_RSTSTA_SIZE                     1
+#define USART3_STTBRK_OFFSET                   9
+#define USART3_STTBRK_SIZE                     1
+#define USART3_STPBRK_OFFSET                   10
+#define USART3_STPBRK_SIZE                     1
+#define USART3_STTTO_OFFSET                    11
+#define USART3_STTTO_SIZE                      1
+#define USART3_SENDA_OFFSET                    12
+#define USART3_SENDA_SIZE                      1
+#define USART3_RSTIT_OFFSET                    13
+#define USART3_RSTIT_SIZE                      1
+#define USART3_RSTNACK_OFFSET                  14
+#define USART3_RSTNACK_SIZE                    1
+#define USART3_RETTO_OFFSET                    15
+#define USART3_RETTO_SIZE                      1
+#define USART3_DTREN_OFFSET                    16
+#define USART3_DTREN_SIZE                      1
+#define USART3_DTRDIS_OFFSET                   17
+#define USART3_DTRDIS_SIZE                     1
+#define USART3_RTSEN_OFFSET                    18
+#define USART3_RTSEN_SIZE                      1
+#define USART3_RTSDIS_OFFSET                   19
+#define USART3_RTSDIS_SIZE                     1
+#define USART3_COMM_TX_OFFSET                  30
+#define USART3_COMM_TX_SIZE                    1
+#define USART3_COMM_RX_OFFSET                  31
+#define USART3_COMM_RX_SIZE                    1
+
+/* Bitfields in MR */
+#define USART3_USART_MODE_OFFSET               0
+#define USART3_USART_MODE_SIZE                 4
+#define USART3_USCLKS_OFFSET                   4
+#define USART3_USCLKS_SIZE                     2
+#define USART3_CHRL_OFFSET                     6
+#define USART3_CHRL_SIZE                       2
+#define USART3_SYNC_OFFSET                     8
+#define USART3_SYNC_SIZE                       1
+#define USART3_PAR_OFFSET                      9
+#define USART3_PAR_SIZE                                3
+#define USART3_NBSTOP_OFFSET                   12
+#define USART3_NBSTOP_SIZE                     2
+#define USART3_CHMODE_OFFSET                   14
+#define USART3_CHMODE_SIZE                     2
+#define USART3_MSBF_OFFSET                     16
+#define USART3_MSBF_SIZE                       1
+#define USART3_MODE9_OFFSET                    17
+#define USART3_MODE9_SIZE                      1
+#define USART3_CLKO_OFFSET                     18
+#define USART3_CLKO_SIZE                       1
+#define USART3_OVER_OFFSET                     19
+#define USART3_OVER_SIZE                       1
+#define USART3_INACK_OFFSET                    20
+#define USART3_INACK_SIZE                      1
+#define USART3_DSNACK_OFFSET                   21
+#define USART3_DSNACK_SIZE                     1
+#define USART3_MAX_ITERATION_OFFSET            24
+#define USART3_MAX_ITERATION_SIZE              3
+#define USART3_FILTER_OFFSET                   28
+#define USART3_FILTER_SIZE                     1
+
+/* Bitfields in CSR */
+#define USART3_RXRDY_OFFSET                    0
+#define USART3_RXRDY_SIZE                      1
+#define USART3_TXRDY_OFFSET                    1
+#define USART3_TXRDY_SIZE                      1
+#define USART3_RXBRK_OFFSET                    2
+#define USART3_RXBRK_SIZE                      1
+#define USART3_ENDRX_OFFSET                    3
+#define USART3_ENDRX_SIZE                      1
+#define USART3_ENDTX_OFFSET                    4
+#define USART3_ENDTX_SIZE                      1
+#define USART3_OVRE_OFFSET                     5
+#define USART3_OVRE_SIZE                       1
+#define USART3_FRAME_OFFSET                    6
+#define USART3_FRAME_SIZE                      1
+#define USART3_PARE_OFFSET                     7
+#define USART3_PARE_SIZE                       1
+#define USART3_TIMEOUT_OFFSET                  8
+#define USART3_TIMEOUT_SIZE                    1
+#define USART3_TXEMPTY_OFFSET                  9
+#define USART3_TXEMPTY_SIZE                    1
+#define USART3_ITERATION_OFFSET                        10
+#define USART3_ITERATION_SIZE                  1
+#define USART3_TXBUFE_OFFSET                   11
+#define USART3_TXBUFE_SIZE                     1
+#define USART3_RXBUFF_OFFSET                   12
+#define USART3_RXBUFF_SIZE                     1
+#define USART3_NACK_OFFSET                     13
+#define USART3_NACK_SIZE                       1
+#define USART3_RIIC_OFFSET                     16
+#define USART3_RIIC_SIZE                       1
+#define USART3_DSRIC_OFFSET                    17
+#define USART3_DSRIC_SIZE                      1
+#define USART3_DCDIC_OFFSET                    18
+#define USART3_DCDIC_SIZE                      1
+#define USART3_CTSIC_OFFSET                    19
+#define USART3_CTSIC_SIZE                      1
+#define USART3_RI_OFFSET                       20
+#define USART3_RI_SIZE                         1
+#define USART3_DSR_OFFSET                      21
+#define USART3_DSR_SIZE                                1
+#define USART3_DCD_OFFSET                      22
+#define USART3_DCD_SIZE                                1
+#define USART3_CTS_OFFSET                      23
+#define USART3_CTS_SIZE                                1
+
+/* Bitfields in RHR */
+#define USART3_RXCHR_OFFSET                    0
+#define USART3_RXCHR_SIZE                      9
+
+/* Bitfields in THR */
+#define USART3_TXCHR_OFFSET                    0
+#define USART3_TXCHR_SIZE                      9
+
+/* Bitfields in BRGR */
+#define USART3_CD_OFFSET                       0
+#define USART3_CD_SIZE                         16
+
+/* Bitfields in RTOR */
+#define USART3_TO_OFFSET                       0
+#define USART3_TO_SIZE                         16
+
+/* Bitfields in TTGR */
+#define USART3_TG_OFFSET                       0
+#define USART3_TG_SIZE                         8
+
+/* Bitfields in FIDI */
+#define USART3_FI_DI_RATIO_OFFSET              0
+#define USART3_FI_DI_RATIO_SIZE                        11
+
+/* Bitfields in NER */
+#define USART3_NB_ERRORS_OFFSET                        0
+#define USART3_NB_ERRORS_SIZE                  8
+
+/* Bitfields in XXR */
+#define USART3_XOFF_OFFSET                     0
+#define USART3_XOFF_SIZE                       8
+#define USART3_XON_OFFSET                      8
+#define USART3_XON_SIZE                                8
+
+/* Bitfields in IFR */
+#define USART3_IRDA_FILTER_OFFSET              0
+#define USART3_IRDA_FILTER_SIZE                        8
+
+/* Bitfields in RCR */
+#define USART3_RXCTR_OFFSET                    0
+#define USART3_RXCTR_SIZE                      16
+
+/* Bitfields in TCR */
+#define USART3_TXCTR_OFFSET                    0
+#define USART3_TXCTR_SIZE                      16
+
+/* Bitfields in RNCR */
+#define USART3_RXNCR_OFFSET                    0
+#define USART3_RXNCR_SIZE                      16
+
+/* Bitfields in TNCR */
+#define USART3_TXNCR_OFFSET                    0
+#define USART3_TXNCR_SIZE                      16
+
+/* Bitfields in PTCR */
+#define USART3_RXTEN_OFFSET                    0
+#define USART3_RXTEN_SIZE                      1
+#define USART3_RXTDIS_OFFSET                   1
+#define USART3_RXTDIS_SIZE                     1
+#define USART3_TXTEN_OFFSET                    8
+#define USART3_TXTEN_SIZE                      1
+#define USART3_TXTDIS_OFFSET                   9
+#define USART3_TXTDIS_SIZE                     1
+
+/* Constants for USART_MODE */
+#define USART3_USART_MODE_NORMAL               0
+#define USART3_USART_MODE_RS485                        1
+#define USART3_USART_MODE_HARDWARE             2
+#define USART3_USART_MODE_MODEM                        3
+#define USART3_USART_MODE_ISO7816_T0           4
+#define USART3_USART_MODE_ISO7816_T1           6
+#define USART3_USART_MODE_IRDA                 8
+
+/* Constants for USCLKS */
+#define USART3_USCLKS_MCK                      0
+#define USART3_USCLKS_MCK_DIV                  1
+#define USART3_USCLKS_SCK                      3
+
+/* Constants for CHRL */
+#define USART3_CHRL_5                          0
+#define USART3_CHRL_6                          1
+#define USART3_CHRL_7                          2
+#define USART3_CHRL_8                          3
+
+/* Constants for PAR */
+#define USART3_PAR_EVEN                                0
+#define USART3_PAR_ODD                         1
+#define USART3_PAR_SPACE                       2
+#define USART3_PAR_MARK                                3
+#define USART3_PAR_NONE                                4
+#define USART3_PAR_MULTI                       6
+
+/* Constants for NBSTOP */
+#define USART3_NBSTOP_1                                0
+#define USART3_NBSTOP_1_5                      1
+#define USART3_NBSTOP_2                                2
+
+/* Constants for CHMODE */
+#define USART3_CHMODE_NORMAL                   0
+#define USART3_CHMODE_ECHO                     1
+#define USART3_CHMODE_LOCAL_LOOP               2
+#define USART3_CHMODE_REMOTE_LOOP              3
+
+/* Constants for MSBF */
+#define USART3_MSBF_LSBF                       0
+#define USART3_MSBF_MSBF                       1
+
+/* Constants for OVER */
+#define USART3_OVER_X16                                0
+#define USART3_OVER_X8                         1
+
+/* Constants for CD */
+#define USART3_CD_DISABLE                      0
+#define USART3_CD_BYPASS                       1
+
+/* Constants for TO */
+#define USART3_TO_DISABLE                      0
+
+/* Constants for TG */
+#define USART3_TG_DISABLE                      0
+
+/* Constants for FI_DI_RATIO */
+#define USART3_FI_DI_RATIO_DISABLE             0
+
+/* Bit manipulation macros */
+#define USART3_BIT(name)                               \
+       (1 << USART3_##name##_OFFSET)
+#define USART3_BF(name,value)                          \
+       (((value) & ((1 << USART3_##name##_SIZE) - 1))  \
+        << USART3_##name##_OFFSET)
+#define USART3_BFEXT(name,value)                       \
+       (((value) >> USART3_##name##_OFFSET)            \
+        & ((1 << USART3_##name##_SIZE) - 1))
+#define USART3_BFINS(name,value,old)                   \
+       (((old) & ~(((1 << USART3_##name##_SIZE) - 1)   \
+                   << USART3_##name##_OFFSET))         \
+        | USART3_BF(name,value))
+
+/* Register access macros */
+#define usart3_readl(reg)                              \
+       readl((void *)USART_BASE + USART3_##reg)
+#define usart3_writel(reg,value)                       \
+       writel((value), (void *)USART_BASE + USART3_##reg)
+
+#endif /* __DRIVERS_ATMEL_USART_H__ */
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
new file mode 100644 (file)
index 0000000..2429464
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * COM1 NS16550 support
+ * originally from linux source (arch/ppc/boot/ns16550.c)
+ * modified to use CFG_ISA_MEM and new defines
+ */
+
+#include <config.h>
+
+#ifdef CFG_NS16550
+
+#include <ns16550.h>
+
+#define LCRVAL LCR_8N1                                 /* 8 data, 1 stop, no parity */
+#define MCRVAL (MCR_DTR | MCR_RTS)                     /* RTS/DTR */
+#define FCRVAL (FCR_FIFO_EN | FCR_RXSR | FCR_TXSR)     /* Clear & enable FIFOs */
+
+void NS16550_init (NS16550_t com_port, int baud_divisor)
+{
+       com_port->ier = 0x00;
+#ifdef CONFIG_OMAP
+       com_port->mdr1 = 0x7;   /* mode select reset TL16C750*/
+#endif
+       com_port->lcr = LCR_BKSE | LCRVAL;
+       com_port->dll = baud_divisor & 0xff;
+       com_port->dlm = (baud_divisor >> 8) & 0xff;
+       com_port->lcr = LCRVAL;
+       com_port->mcr = MCRVAL;
+       com_port->fcr = FCRVAL;
+#if defined(CONFIG_OMAP)
+#if defined(CONFIG_APTIX)
+       com_port->mdr1 = 3;     /* /13 mode so Aptix 6MHz can hit 115200 */
+#else
+       com_port->mdr1 = 0;     /* /16 is proper to hit 115200 with 48MHz */
+#endif
+#endif
+}
+
+void NS16550_reinit (NS16550_t com_port, int baud_divisor)
+{
+       com_port->ier = 0x00;
+       com_port->lcr = LCR_BKSE;
+       com_port->dll = baud_divisor & 0xff;
+       com_port->dlm = (baud_divisor >> 8) & 0xff;
+       com_port->lcr = LCRVAL;
+       com_port->mcr = MCRVAL;
+       com_port->fcr = FCRVAL;
+}
+
+void NS16550_putc (NS16550_t com_port, char c)
+{
+       while ((com_port->lsr & LSR_THRE) == 0);
+       com_port->thr = c;
+}
+
+char NS16550_getc (NS16550_t com_port)
+{
+       while ((com_port->lsr & LSR_DR) == 0) {
+#ifdef CONFIG_USB_TTY
+               extern void usbtty_poll(void);
+               usbtty_poll();
+#endif
+       }
+       return (com_port->rbr);
+}
+
+int NS16550_tstc (NS16550_t com_port)
+{
+       return ((com_port->lsr & LSR_DR) != 0);
+}
+
+#endif
diff --git a/drivers/serial/ns9750_serial.c b/drivers/serial/ns9750_serial.c
new file mode 100644 (file)
index 0000000..02c0d39
--- /dev/null
@@ -0,0 +1,214 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2004 by FS Forth-Systeme GmbH.
+ * All rights reserved.
+ *
+ * $Id: ns9750_serial.c,v 1.1 2004/02/16 10:37:20 mpietrek Exp $
+ * @Author: Markus Pietrek
+ * @Descr: Serial driver for the NS9750. Only one UART is supported yet.
+ * @References: [1] NS9750 Hardware Reference/December 2003
+ * @TODO: Implement Character GAP Timer when chip is fixed for PLL bypass
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ***********************************************************************/
+
+#include <common.h>
+
+#ifdef CFG_NS9750_UART
+
+#include "ns9750_bbus.h"       /* for GPIOs */
+#include "ns9750_ser.h"                /* for serial configuration */
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if !defined(CONFIG_CONS_INDEX)
+#error "No console index specified."
+#endif
+
+#define CONSOLE CONFIG_CONS_INDEX
+
+static unsigned int calcBitrateRegister( void );
+static unsigned int calcRxCharGapRegister( void );
+
+static char cCharsAvailable; /* Numbers of chars in unCharCache */
+static unsigned int unCharCache; /* unCharCache is only valid if
+                                 * cCharsAvailable > 0 */
+
+/***********************************************************************
+ * @Function: serial_init
+ * @Return: 0
+ * @Descr: configures GPIOs and UART. Requires BBUS Master Reset turned off
+ ***********************************************************************/
+
+int serial_init( void )
+{
+       unsigned int aunGPIOTxD[] = { 0, 8, 40, 44 };
+       unsigned int aunGPIORxD[] = { 1, 9, 41, 45 };
+
+       cCharsAvailable = 0;
+
+       /* configure TxD and RxD pins for their special function */
+       set_gpio_cfg_reg_val( aunGPIOTxD[ CONSOLE ],
+                             NS9750_GPIO_CFG_FUNC_0 | NS9750_GPIO_CFG_OUTPUT );
+       set_gpio_cfg_reg_val( aunGPIORxD[ CONSOLE ],
+                             NS9750_GPIO_CFG_FUNC_0 | NS9750_GPIO_CFG_INPUT );
+
+       /* configure serial engine */
+       *get_ser_reg_addr_channel( NS9750_SER_CTRL_A, CONSOLE ) =
+               NS9750_SER_CTRL_A_CE |
+               NS9750_SER_CTRL_A_STOP |
+               NS9750_SER_CTRL_A_WLS_8;
+
+       serial_setbrg();
+
+       *get_ser_reg_addr_channel( NS9750_SER_CTRL_B, CONSOLE ) =
+               NS9750_SER_CTRL_B_RCGT;
+
+       return 0;
+}
+
+/***********************************************************************
+ * @Function: serial_putc
+ * @Return: n/a
+ * @Descr: writes one character to the FIFO. Blocks until FIFO is not full
+ ***********************************************************************/
+
+void serial_putc( const char c )
+{
+       if (c == '\n')
+               serial_putc( '\r' );
+
+       while (!(*get_ser_reg_addr_channel( NS9750_SER_STAT_A, CONSOLE) &
+                NS9750_SER_STAT_A_TRDY ) ) {
+               /* do nothing, wait for characters in FIFO sent */
+       }
+
+       *(volatile char*) get_ser_reg_addr_channel( NS9750_SER_FIFO,
+                                                   CONSOLE) = c;
+}
+
+/***********************************************************************
+ * @Function: serial_puts
+ * @Return: n/a
+ * @Descr: writes non-zero string to the FIFO.
+ ***********************************************************************/
+
+void serial_puts( const char *s )
+{
+       while (*s) {
+               serial_putc( *s++ );
+       }
+}
+
+/***********************************************************************
+ * @Function: serial_getc
+ * @Return: the character read
+ * @Descr: performs only 8bit accesses to the FIFO. No error handling
+ ***********************************************************************/
+
+int serial_getc( void )
+{
+       int i;
+
+       while (!serial_tstc() ) {
+               /* do nothing, wait for incoming characters */
+       }
+
+       /*  at least one character in unCharCache */
+       i = (int) (unCharCache & 0xff);
+
+       unCharCache >>= 8;
+       cCharsAvailable--;
+
+       return i;
+}
+
+/***********************************************************************
+ * @Function: serial_tstc
+ * @Return: 0 if no input available, otherwise != 0
+ * @Descr: checks for incoming FIFO not empty. Stores the incoming chars in
+ *        unCharCache and the numbers of characters in cCharsAvailable
+ ***********************************************************************/
+
+int serial_tstc( void )
+{
+       unsigned int unRegCache;
+
+       if ( cCharsAvailable )
+               return 1;
+
+       unRegCache = *get_ser_reg_addr_channel( NS9750_SER_STAT_A,CONSOLE );
+       if( unRegCache & NS9750_SER_STAT_A_RBC ) {
+               *get_ser_reg_addr_channel( NS9750_SER_STAT_A, CONSOLE ) =
+                       NS9750_SER_STAT_A_RBC;
+               unRegCache = *get_ser_reg_addr_channel( NS9750_SER_STAT_A,
+                                                       CONSOLE );
+       }
+
+       if ( unRegCache & NS9750_SER_STAT_A_RRDY ) {
+               cCharsAvailable = (unRegCache & NS9750_SER_STAT_A_RXFDB_MA)>>20;
+               if ( !cCharsAvailable )
+                       cCharsAvailable = 4;
+
+               unCharCache = *get_ser_reg_addr_channel( NS9750_SER_FIFO,
+                                                        CONSOLE );
+               return 1;
+       }
+
+       /* no chars available */
+       return 0;
+}
+
+void serial_setbrg( void )
+{
+       *get_ser_reg_addr_channel( NS9750_SER_BITRATE, CONSOLE ) =
+               calcBitrateRegister();
+       *get_ser_reg_addr_channel( NS9750_SER_RX_CHAR_TIMER, CONSOLE ) =
+               calcRxCharGapRegister();
+}
+
+/***********************************************************************
+ * @Function: calcBitrateRegister
+ * @Return: value for the serial bitrate register
+ * @Descr: register value depends on clock frequency and baudrate
+ ***********************************************************************/
+
+static unsigned int calcBitrateRegister( void )
+{
+       return ( NS9750_SER_BITRATE_EBIT |
+                NS9750_SER_BITRATE_CLKMUX_BCLK |
+                NS9750_SER_BITRATE_TMODE |
+                NS9750_SER_BITRATE_TCDR_16 |
+                NS9750_SER_BITRATE_RCDR_16 |
+                ( ( ( ( CONFIG_SYS_CLK_FREQ / 8 ) / /* BBUS clock,[1] Fig. 38 */
+                      ( gd->baudrate * 16 ) ) - 1 ) &
+                  NS9750_SER_BITRATE_N_MA ) );
+}
+
+/***********************************************************************
+ * @Function: calcRxCharGapRegister
+ * @Return: value for the character gap timer register
+ * @Descr: register value depends on clock frequency and baudrate. Currently 0
+ *        is used as there is a bug with the gap timer in PLL bypass mode.
+ ***********************************************************************/
+
+static unsigned int calcRxCharGapRegister( void )
+{
+       return NS9750_SER_RX_CHAR_TIMER_TRUN;
+}
+
+#endif /* CFG_NS9750_UART */
diff --git a/drivers/serial/s3c4510b_uart.c b/drivers/serial/s3c4510b_uart.c
new file mode 100644 (file)
index 0000000..ddcd591
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2004  Cucy Systems (http://www.cucy.com)
+ * Curt Brune <curt@cucy.com>
+ *
+ * (C) Copyright 2004
+ * DAVE Srl
+ * http://www.dave-tech.it
+ * http://www.wawnet.biz
+ * mailto:info@wawnet.biz
+ *
+ * (C) Copyright 2002-2004
+ * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * MODULE:        $Id:$
+ * Description:   UART/Serial interface for Samsung S3C4510B SoC
+ * Runtime Env:   ARM7TDMI
+ * Change History:
+ *     03-02-04    Create (Curt Brune) curt@cucy.com
+ *
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DRIVER_S3C4510_UART
+
+#include <asm/hardware.h>
+#include "s3c4510b_uart.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static UART    *uart;
+
+/* flush serial input queue. returns 0 on success or negative error
+ * number otherwise
+ */
+static int serial_flush_input(void)
+{
+       volatile u32 tmp;
+
+       /* keep on reading as long as the receiver is not empty */
+       while( uart->m_stat.bf.rxReady) {
+               tmp = uart->m_rx;
+       }
+
+       return 0;
+}
+
+
+/* flush output queue. returns 0 on success or negative error number
+ * otherwise
+ */
+static int serial_flush_output(void)
+{
+       /* wait until the transmitter is no longer busy */
+       while( !uart->m_stat.bf.txBufEmpty);
+
+       return 0;
+}
+
+
+void serial_setbrg (void)
+{
+       UART_LINE_CTRL ulctrl;
+       UART_CTRL      uctrl;
+       UART_BAUD_DIV  ubd;
+
+       serial_flush_output();
+       serial_flush_input();
+
+       /* control register */
+       uctrl.ui = 0x0;
+       uctrl.bf.rxMode = 0x1;
+       uctrl.bf.rxIrq = 0x0;
+       uctrl.bf.txMode = 0x1;
+       uctrl.bf.DSR = 0x0;
+       uctrl.bf.sendBreak = 0x0;
+       uctrl.bf.loopBack = 0x0;
+       uart->m_ctrl.ui = uctrl.ui;
+
+       /* line control register */
+       ulctrl.ui  = 0x0;
+       ulctrl.bf.wordLen   = 0x3; /* 8 bit data */
+       ulctrl.bf.nStop     = 0x0; /* 1 stop bit */
+       ulctrl.bf.parity    = 0x0; /* no parity */
+       ulctrl.bf.clk       = 0x0; /* internal clock */
+       ulctrl.bf.infra_red = 0x0; /* no infra_red */
+       uart->m_lineCtrl.ui = ulctrl.ui;
+
+       ubd.ui = 0x0;
+
+       /* see table on page 10-15 in SAMSUNG S3C4510B manual */
+       /* get correct divisor */
+       switch(gd->baudrate) {
+       case   1200:    ubd.bf.cnt0 = 1301;     break;
+       case   2400:    ubd.bf.cnt0 =  650;     break;
+       case   4800:    ubd.bf.cnt0 =  324;     break;
+       case   9600:    ubd.bf.cnt0 =  162;     break;
+       case  19200:    ubd.bf.cnt0 =   80;     break;
+       case  38400:    ubd.bf.cnt0 =   40;     break;
+       case  57600:    ubd.bf.cnt0 =   26;     break;
+       case 115200:    ubd.bf.cnt0 =   13;     break;
+       }
+
+       uart->m_baudDiv.ui = ubd.ui;
+       uart->m_baudCnt = 0x0;
+       uart->m_baudClk = 0x0;
+
+}
+
+
+/*
+ * Initialise the serial port with the given baudrate. The settings
+ * are always 8 data bits, no parity, 1 stop bit, no start bits.
+ *
+ */
+int serial_init (void)
+{
+
+#if   CONFIG_SERIAL1 == 1
+       uart = (UART *)UART0_BASE;
+#elif CONFIG_SERIAL1 == 2
+       uart = (UART *)UART1_BASE;
+#else
+#error CONFIG_SERIAL1 not equal to 1 or 2
+#endif
+
+       serial_setbrg ();
+
+       return (0);
+}
+
+
+/*
+ * Output a single byte to the serial port.
+ */
+void serial_putc (const char c)
+{
+       /* wait for room in the transmit FIFO */
+       while( !uart->m_stat.bf.txBufEmpty);
+
+       uart->m_tx = c;
+
+       /*
+               to be polite with serial console add a line feed
+               to the carriage return character
+       */
+       if (c=='\n')
+               serial_putc('\r');
+}
+
+/*
+ * Test if an input byte is ready from the serial port. Returns non-zero on
+ * success, 0 otherwise.
+ */
+int serial_tstc (void)
+{
+       return uart->m_stat.bf.rxReady;
+}
+
+/*
+ * Read a single byte from the serial port. Returns 1 on success, 0
+ * otherwise. When the function is succesfull, the character read is
+ * written into its argument c.
+ */
+int serial_getc (void)
+{
+       int rv;
+
+       for(;;) {
+               rv = serial_tstc();
+
+               if (rv) {
+                       return uart->m_rx & 0xFF;
+               }
+       }
+}
+
+void serial_puts (const char *s)
+{
+       while (*s) {
+               serial_putc (*s++);
+       }
+
+       /* busy wait for tx complete */
+       while ( !uart->m_stat.bf.txComplete);
+
+       /* clear break */
+       uart->m_ctrl.bf.sendBreak = 0;
+
+}
+
+#endif
diff --git a/drivers/serial/s3c4510b_uart.h b/drivers/serial/s3c4510b_uart.h
new file mode 100644 (file)
index 0000000..b06c76d
--- /dev/null
@@ -0,0 +1,109 @@
+#ifndef __UART_H
+#define __UART_H
+
+/*
+ * Copyright (c) 2004  Cucy Systems (http://www.cucy.com)
+ * Curt Brune <curt@cucy.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Description:   S3C4510B UART register layout
+ */
+
+/* UART LINE CONTROL register */
+typedef struct __BF_UART_LINE_CTRL {
+       u32    wordLen: 2;
+       u32      nStop: 1;
+       u32     parity: 3;
+       u32        clk: 1;
+       u32  infra_red: 1;
+       u32     unused:24;
+} BF_UART_LINE_CTRL;
+
+typedef union _UART_LINE_CTRL {
+       u32               ui;
+       BF_UART_LINE_CTRL bf;
+} UART_LINE_CTRL;
+
+/* UART CONTROL register */
+typedef struct __BF_UART_CTRL {
+       u32     rxMode: 2;
+       u32      rxIrq: 1;
+       u32     txMode: 2;
+       u32        DSR: 1;
+       u32  sendBreak: 1;
+       u32   loopBack: 1;
+       u32     unused:24;
+} BF_UART_CTRL;
+
+typedef union _UART_CTRL {
+       u32            ui;
+       BF_UART_CTRL   bf;
+} UART_CTRL;
+
+/* UART STATUS register */
+typedef struct __BF_UART_STAT {
+       u32      overrun: 1;
+       u32       parity: 1;
+       u32        frame: 1;
+       u32     breakIrq: 1;
+       u32          DTR: 1;
+       u32      rxReady: 1;
+       u32   txBufEmpty: 1;
+       u32   txComplete: 1;
+       u32       unused:24;
+} BF_UART_STAT;
+
+typedef union _UART_STAT {
+       u32            ui;
+       BF_UART_STAT   bf;
+} UART_STAT;
+
+/* UART BAUD_DIV register */
+typedef struct __BF_UART_BAUD_DIV {
+       u32      cnt1: 4;
+       u32      cnt0:12;
+       u32    unused:16;
+} BF_UART_BAUD_DIV;
+
+typedef union _UART_BAUD_DIV {
+       u32                ui;
+       BF_UART_BAUD_DIV   bf;
+} UART_BAUD_DIV;
+
+/* UART register block */
+typedef struct __UART {
+       volatile UART_LINE_CTRL  m_lineCtrl;
+       volatile UART_CTRL           m_ctrl;
+       volatile UART_STAT           m_stat;
+       volatile u32                   m_tx;
+       volatile u32                   m_rx;
+       volatile UART_BAUD_DIV    m_baudDiv;
+       volatile u32              m_baudCnt;
+       volatile u32              m_baudClk;
+} UART;
+
+#define NL          0x0A
+#define CR          0x0D
+#define BSP         0x08
+#define ESC         0x1B
+#define CTRLZ       0x1A
+#define RUBOUT      0x7F
+
+#endif
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
new file mode 100644 (file)
index 0000000..76425d8
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#ifdef CFG_NS16550_SERIAL
+
+#include <ns16550.h>
+#ifdef CFG_NS87308
+#include <ns87308.h>
+#endif
+
+#if defined (CONFIG_SERIAL_MULTI)
+#include <serial.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if !defined(CONFIG_CONS_INDEX)
+#if defined (CONFIG_SERIAL_MULTI)
+/*   with CONFIG_SERIAL_MULTI we might have no console
+ *  on these devices
+ */
+#else
+#error "No console index specified."
+#endif /* CONFIG_SERIAL_MULTI */
+#elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 4)
+#error "Invalid console index value."
+#endif
+
+#if CONFIG_CONS_INDEX == 1 && !defined(CFG_NS16550_COM1)
+#error "Console port 1 defined but not configured."
+#elif CONFIG_CONS_INDEX == 2 && !defined(CFG_NS16550_COM2)
+#error "Console port 2 defined but not configured."
+#elif CONFIG_CONS_INDEX == 3 && !defined(CFG_NS16550_COM3)
+#error "Console port 3 defined but not configured."
+#elif CONFIG_CONS_INDEX == 4 && !defined(CFG_NS16550_COM4)
+#error "Console port 4 defined but not configured."
+#endif
+
+/* Note: The port number specified in the functions is 1 based.
+ *      the array is 0 based.
+ */
+static NS16550_t serial_ports[4] = {
+#ifdef CFG_NS16550_COM1
+       (NS16550_t)CFG_NS16550_COM1,
+#else
+       NULL,
+#endif
+#ifdef CFG_NS16550_COM2
+       (NS16550_t)CFG_NS16550_COM2,
+#else
+       NULL,
+#endif
+#ifdef CFG_NS16550_COM3
+       (NS16550_t)CFG_NS16550_COM3,
+#else
+       NULL,
+#endif
+#ifdef CFG_NS16550_COM4
+       (NS16550_t)CFG_NS16550_COM4
+#else
+       NULL
+#endif
+};
+
+#define PORT   serial_ports[port-1]
+#if defined(CONFIG_CONS_INDEX)
+#define CONSOLE        (serial_ports[CONFIG_CONS_INDEX-1])
+#endif
+
+#if defined(CONFIG_SERIAL_MULTI)
+
+/* Multi serial device functions */
+#define DECLARE_ESERIAL_FUNCTIONS(port) \
+    int  eserial##port##_init (void) {\
+       int clock_divisor; \
+       clock_divisor = calc_divisor(serial_ports[port-1]); \
+       NS16550_init(serial_ports[port-1], clock_divisor); \
+       return(0);}\
+    void eserial##port##_setbrg (void) {\
+       serial_setbrg_dev(port);}\
+    int  eserial##port##_getc (void) {\
+       return serial_getc_dev(port);}\
+    int  eserial##port##_tstc (void) {\
+       return serial_tstc_dev(port);}\
+    void eserial##port##_putc (const char c) {\
+       serial_putc_dev(port, c);}\
+    void eserial##port##_puts (const char *s) {\
+       serial_puts_dev(port, s);}
+
+/* Serial device descriptor */
+#define INIT_ESERIAL_STRUCTURE(port,name,bus) {\
+       name,\
+       bus,\
+       eserial##port##_init,\
+       eserial##port##_setbrg,\
+       eserial##port##_getc,\
+       eserial##port##_tstc,\
+       eserial##port##_putc,\
+       eserial##port##_puts, }
+
+#endif /* CONFIG_SERIAL_MULTI */
+
+static int calc_divisor (NS16550_t port)
+{
+#ifdef CONFIG_OMAP1510
+       /* If can't cleanly clock 115200 set div to 1 */
+       if ((CFG_NS16550_CLK == 12000000) && (gd->baudrate == 115200)) {
+               port->osc_12m_sel = OSC_12M_SEL;        /* enable 6.5 * divisor */
+               return (1);                             /* return 1 for base divisor */
+       }
+       port->osc_12m_sel = 0;                  /* clear if previsouly set */
+#endif
+#ifdef CONFIG_OMAP1610
+       /* If can't cleanly clock 115200 set div to 1 */
+       if ((CFG_NS16550_CLK == 48000000) && (gd->baudrate == 115200)) {
+               return (26);            /* return 26 for base divisor */
+       }
+#endif
+
+#ifdef CONFIG_APTIX
+#define MODE_X_DIV 13
+#else
+#define MODE_X_DIV 16
+#endif
+       return (CFG_NS16550_CLK / MODE_X_DIV / gd->baudrate);
+
+}
+
+#if !defined(CONFIG_SERIAL_MULTI)
+int serial_init (void)
+{
+       int clock_divisor;
+
+#ifdef CFG_NS87308
+       initialise_ns87308();
+#endif
+
+#ifdef CFG_NS16550_COM1
+       clock_divisor = calc_divisor(serial_ports[0]);
+       NS16550_init(serial_ports[0], clock_divisor);
+#endif
+#ifdef CFG_NS16550_COM2
+       clock_divisor = calc_divisor(serial_ports[1]);
+       NS16550_init(serial_ports[1], clock_divisor);
+#endif
+#ifdef CFG_NS16550_COM3
+       clock_divisor = calc_divisor(serial_ports[2]);
+       NS16550_init(serial_ports[2], clock_divisor);
+#endif
+#ifdef CFG_NS16550_COM4
+       clock_divisor = calc_divisor(serial_ports[3]);
+       NS16550_init(serial_ports[3], clock_divisor);
+#endif
+
+       return (0);
+}
+#endif
+
+void
+_serial_putc(const char c,const int port)
+{
+       if (c == '\n')
+               NS16550_putc(PORT, '\r');
+
+       NS16550_putc(PORT, c);
+}
+
+void
+_serial_putc_raw(const char c,const int port)
+{
+       NS16550_putc(PORT, c);
+}
+
+void
+_serial_puts (const char *s,const int port)
+{
+       while (*s) {
+               _serial_putc (*s++,port);
+       }
+}
+
+
+int
+_serial_getc(const int port)
+{
+       return NS16550_getc(PORT);
+}
+
+int
+_serial_tstc(const int port)
+{
+       return NS16550_tstc(PORT);
+}
+
+void
+_serial_setbrg (const int port)
+{
+       int clock_divisor;
+
+       clock_divisor = calc_divisor(PORT);
+       NS16550_reinit(PORT, clock_divisor);
+}
+
+#if defined(CONFIG_SERIAL_MULTI)
+static inline void
+serial_putc_dev(unsigned int dev_index,const char c)
+{
+       _serial_putc(c,dev_index);
+}
+#else
+void
+serial_putc(const char c)
+{
+       _serial_putc(c,CONFIG_CONS_INDEX);
+}
+#endif
+
+#if defined(CONFIG_SERIAL_MULTI)
+static inline void
+serial_putc_raw_dev(unsigned int dev_index,const char c)
+{
+       _serial_putc_raw(c,dev_index);
+}
+#else
+void
+serial_putc_raw(const char c)
+{
+       _serial_putc_raw(c,CONFIG_CONS_INDEX);
+}
+#endif
+
+#if defined(CONFIG_SERIAL_MULTI)
+static inline void
+serial_puts_dev(unsigned int dev_index,const char *s)
+{
+       _serial_puts(s,dev_index);
+}
+#else
+void
+serial_puts(const char *s)
+{
+       _serial_puts(s,CONFIG_CONS_INDEX);
+}
+#endif
+
+#if defined(CONFIG_SERIAL_MULTI)
+static inline int
+serial_getc_dev(unsigned int dev_index)
+{
+       return _serial_getc(dev_index);
+}
+#else
+int
+serial_getc(void)
+{
+       return _serial_getc(CONFIG_CONS_INDEX);
+}
+#endif
+
+#if defined(CONFIG_SERIAL_MULTI)
+static inline int
+serial_tstc_dev(unsigned int dev_index)
+{
+       return _serial_tstc(dev_index);
+}
+#else
+int
+serial_tstc(void)
+{
+       return _serial_tstc(CONFIG_CONS_INDEX);
+}
+#endif
+
+#if defined(CONFIG_SERIAL_MULTI)
+static inline void
+serial_setbrg_dev(unsigned int dev_index)
+{
+       _serial_setbrg(dev_index);
+}
+#else
+void
+serial_setbrg(void)
+{
+       _serial_setbrg(CONFIG_CONS_INDEX);
+}
+#endif
+
+#if defined(CONFIG_SERIAL_MULTI)
+
+DECLARE_ESERIAL_FUNCTIONS(1);
+struct serial_device eserial1_device =
+       INIT_ESERIAL_STRUCTURE(1,"eserial0","EUART1");
+DECLARE_ESERIAL_FUNCTIONS(2);
+struct serial_device eserial2_device =
+       INIT_ESERIAL_STRUCTURE(2,"eserial1","EUART2");
+DECLARE_ESERIAL_FUNCTIONS(3);
+struct serial_device eserial3_device =
+       INIT_ESERIAL_STRUCTURE(3,"eserial2","EUART3");
+DECLARE_ESERIAL_FUNCTIONS(4);
+struct serial_device eserial4_device =
+       INIT_ESERIAL_STRUCTURE(4,"eserial3","EUART4");
+#endif /* CONFIG_SERIAL_MULTI */
+
+#endif
diff --git a/drivers/serial/serial_max3100.c b/drivers/serial/serial_max3100.c
new file mode 100644 (file)
index 0000000..35c5596
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * (C) Copyright 2003
+ *
+ * Pantelis Antoniou <panto@intracom.gr>
+ * Intracom S.A.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <watchdog.h>
+
+#ifdef CONFIG_MAX3100_SERIAL
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**************************************************************/
+
+/* convienient macros */
+#define MAX3100_SPI_RXD() (MAX3100_SPI_RXD_PORT & MAX3100_SPI_RXD_BIT)
+
+#define MAX3100_SPI_TXD(x) \
+       do { \
+               if (x) \
+                       MAX3100_SPI_TXD_PORT |=  MAX3100_SPI_TXD_BIT; \
+               else \
+                       MAX3100_SPI_TXD_PORT &= ~MAX3100_SPI_TXD_BIT; \
+       } while(0)
+
+#define MAX3100_SPI_CLK(x) \
+       do { \
+               if (x) \
+                       MAX3100_SPI_CLK_PORT |=  MAX3100_SPI_CLK_BIT; \
+               else \
+                       MAX3100_SPI_CLK_PORT &= ~MAX3100_SPI_CLK_BIT; \
+       } while(0)
+
+#define MAX3100_SPI_CLK_TOGGLE() (MAX3100_SPI_CLK_PORT ^= MAX3100_SPI_CLK_BIT)
+
+#define MAX3100_CS(x) \
+       do { \
+               if (x) \
+                       MAX3100_CS_PORT |=  MAX3100_CS_BIT; \
+               else \
+                       MAX3100_CS_PORT &= ~MAX3100_CS_BIT; \
+       } while(0)
+
+/**************************************************************/
+
+/* MAX3100 definitions */
+
+#define MAX3100_WC     (3 << 14)               /* write configuration */
+#define MAX3100_RC     (1 << 14)               /* read  configuration */
+#define MAX3100_WD     (2 << 14)               /* write data          */
+#define MAX3100_RD     (0 << 14)               /* read  data          */
+
+/* configuration register bits */
+#define MAX3100_FEN    (1 << 13)               /* FIFO enable           */
+#define MAX3100_SHDN    (1 << 12)              /* shutdown bit          */
+#define MAX3100_TM     (1 << 11)               /* T bit irq mask        */
+#define MAX3100_RM     (1 << 10)               /* R bit irq mask        */
+#define MAX3100_PM     (1 <<  9)               /* P bit irq mask        */
+#define MAX3100_RAM    (1 <<  8)               /* mask for RA/FE bit    */
+#define MAX3100_IR     (1 <<  7)               /* IRDA timing mode      */
+#define MAX3100_ST     (1 <<  6)               /* transmit stop bit     */
+#define MAX3100_PE     (1 <<  5)               /* parity enable bit     */
+#define MAX3100_L      (1 <<  4)               /* Length bit            */
+#define MAX3100_B_MASK (0x000F)                /* baud rate bits mask   */
+#define MAX3100_B(x)   ((x) & 0x000F)  /* baud rate select bits */
+
+/* data register bits (write) */
+#define MAX3100_TE     (1 << 10)               /* transmit enable bit (active low)        */
+#define MAX3100_RTS    (1 <<  9)               /* request-to-send bit (inverted ~RTS pin) */
+
+/* data register bits (read) */
+#define MAX3100_RA     (1 << 10)               /* receiver activity when in shutdown mode */
+#define MAX3100_FE     (1 << 10)               /* framing error when in normal mode       */
+#define MAX3100_CTS    (1 <<  9)               /* clear-to-send bit (inverted ~CTS pin)   */
+
+/* data register bits (both directions) */
+#define MAX3100_R      (1 << 15)               /* receive bit    */
+#define MAX3100_T      (1 << 14)               /* transmit bit   */
+#define MAX3100_P      (1 <<  8)               /* parity bit     */
+#define MAX3100_D_MASK 0x00FF                  /* data bits mask */
+#define MAX3100_D(x)   ((x) & 0x00FF)          /* data bits      */
+
+/* these definitions are valid only for fOSC = 3.6864MHz */
+#define MAX3100_B_230400        MAX3100_B(0)
+#define MAX3100_B_115200        MAX3100_B(1)
+#define MAX3100_B_57600         MAX3100_B(2)
+#define MAX3100_B_38400         MAX3100_B(9)
+#define MAX3100_B_19200         MAX3100_B(10)
+#define MAX3100_B_9600          MAX3100_B(11)
+#define MAX3100_B_4800          MAX3100_B(12)
+#define MAX3100_B_2400          MAX3100_B(13)
+#define MAX3100_B_1200          MAX3100_B(14)
+#define MAX3100_B_600           MAX3100_B(15)
+
+/**************************************************************/
+
+static inline unsigned int max3100_transfer(unsigned int val)
+{
+       unsigned int rx;
+       int b;
+
+       MAX3100_SPI_CLK(0);
+       MAX3100_CS(0);
+
+       rx = 0; b = 16;
+       while (--b >= 0) {
+               MAX3100_SPI_TXD(val & 0x8000);
+               val <<= 1;
+               MAX3100_SPI_CLK_TOGGLE();
+               udelay(1);
+               rx <<= 1;
+               if (MAX3100_SPI_RXD())
+                       rx |= 1;
+               MAX3100_SPI_CLK_TOGGLE();
+               udelay(1);
+       }
+
+       MAX3100_SPI_CLK(1);
+       MAX3100_CS(1);
+
+       return rx;
+}
+
+/**************************************************************/
+
+/* must be power of 2 */
+#define RXFIFO_SZ      16
+
+static int rxfifo_cnt;
+static int rxfifo_in;
+static int rxfifo_out;
+static unsigned char rxfifo_buf[16];
+
+static void max3100_putc(int c)
+{
+       unsigned int rx;
+
+       while (((rx = max3100_transfer(MAX3100_RC)) & MAX3100_T) == 0)
+               WATCHDOG_RESET();
+
+       rx = max3100_transfer(MAX3100_WD | (c & 0xff));
+       if ((rx & MAX3100_RD) != 0 && rxfifo_cnt < RXFIFO_SZ) {
+               rxfifo_cnt++;
+               rxfifo_buf[rxfifo_in++] = rx & 0xff;
+               rxfifo_in &= RXFIFO_SZ - 1;
+       }
+}
+
+static int max3100_getc(void)
+{
+       int c;
+       unsigned int rx;
+
+       while (rxfifo_cnt == 0) {
+               rx = max3100_transfer(MAX3100_RD);
+               if ((rx & MAX3100_R) != 0) {
+                       do {
+                               rxfifo_cnt++;
+                               rxfifo_buf[rxfifo_in++] = rx & 0xff;
+                               rxfifo_in &= RXFIFO_SZ - 1;
+
+                               if (rxfifo_cnt >= RXFIFO_SZ)
+                                       break;
+                       } while (((rx = max3100_transfer(MAX3100_RD)) & MAX3100_R) != 0);
+               }
+               WATCHDOG_RESET();
+       }
+
+       rxfifo_cnt--;
+       c = rxfifo_buf[rxfifo_out++];
+       rxfifo_out &= RXFIFO_SZ - 1;
+       return c;
+}
+
+static int max3100_tstc(void)
+{
+       unsigned int rx;
+
+       if (rxfifo_cnt > 0)
+               return 1;
+
+       rx = max3100_transfer(MAX3100_RD);
+       if ((rx & MAX3100_R) == 0)
+               return 0;
+
+       do {
+               rxfifo_cnt++;
+               rxfifo_buf[rxfifo_in++] = rx & 0xff;
+               rxfifo_in &= RXFIFO_SZ - 1;
+
+               if (rxfifo_cnt >= RXFIFO_SZ)
+                       break;
+       } while (((rx = max3100_transfer(MAX3100_RD)) & MAX3100_R) != 0);
+
+       return 1;
+}
+
+int serial_init(void)
+{
+       unsigned int wconf, rconf;
+       int i;
+
+       wconf = 0;
+
+       /* Set baud rate */
+       switch (gd->baudrate) {
+               case 1200:
+                       wconf = MAX3100_B_1200;
+                       break;
+               case 2400:
+                       wconf = MAX3100_B_2400;
+                       break;
+               case 4800:
+                       wconf = MAX3100_B_4800;
+                       break;
+               case 9600:
+                       wconf = MAX3100_B_9600;
+                       break;
+               case 19200:
+                       wconf = MAX3100_B_19200;
+                       break;
+               case 38400:
+                       wconf = MAX3100_B_38400;
+                       break;
+               case 57600:
+                       wconf = MAX3100_B_57600;
+                       break;
+               default:
+               case 115200:
+                       wconf = MAX3100_B_115200;
+                       break;
+               case 230400:
+                       wconf = MAX3100_B_230400;
+                       break;
+       }
+
+       /* try for 10ms, with a 100us gap */
+       for (i = 0; i < 10000; i += 100) {
+
+               max3100_transfer(MAX3100_WC | wconf);
+               rconf = max3100_transfer(MAX3100_RC) & 0x3fff;
+
+               if (rconf == wconf)
+                       break;
+               udelay(100);
+       }
+
+       rxfifo_in = rxfifo_out = rxfifo_cnt = 0;
+
+       return (0);
+}
+
+void serial_putc(const char c)
+{
+       if (c == '\n')
+               max3100_putc('\r');
+
+       max3100_putc(c);
+}
+
+void serial_puts(const char *s)
+{
+       while (*s)
+               serial_putc (*s++);
+}
+
+int serial_getc(void)
+{
+       return max3100_getc();
+}
+
+int serial_tstc(void)
+{
+       return max3100_tstc();
+}
+
+/* XXX WTF? */
+void serial_setbrg(void)
+{
+}
+
+#endif
diff --git a/drivers/serial/serial_pl010.c b/drivers/serial/serial_pl010.c
new file mode 100644 (file)
index 0000000..417b6ae
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * (C) Copyright 2004
+ * ARM Ltd.
+ * Philippe Robin, <philippe.robin@arm.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* Simple U-Boot driver for the PrimeCell PL011 UARTs on the IntegratorCP */
+/* Should be fairly simple to make it work with the PL010 as well */
+
+#include <common.h>
+
+#ifdef CFG_PL010_SERIAL
+
+#include "serial_pl011.h"
+
+#define IO_WRITE(addr, val) (*(volatile unsigned int *)(addr) = (val))
+#define IO_READ(addr) (*(volatile unsigned int *)(addr))
+
+/* Integrator AP has two UARTs, we use the first one, at 38400-8-N-1 */
+#define CONSOLE_PORT CONFIG_CONS_INDEX
+#define baudRate CONFIG_BAUDRATE
+static volatile unsigned char *const port[] = CONFIG_PL01x_PORTS;
+#define NUM_PORTS (sizeof(port)/sizeof(port[0]))
+
+
+static void pl010_putc (int portnum, char c);
+static int pl010_getc (int portnum);
+static int pl010_tstc (int portnum);
+
+
+int serial_init (void)
+{
+       unsigned int divisor;
+
+       /*
+        ** First, disable everything.
+        */
+       IO_WRITE (port[CONSOLE_PORT] + UART_PL010_CR, 0x0);
+
+       /*
+        ** Set baud rate
+        **
+        */
+       switch (baudRate) {
+       case 9600:
+               divisor = UART_PL010_BAUD_9600;
+               break;
+
+       case 19200:
+               divisor = UART_PL010_BAUD_9600;
+               break;
+
+       case 38400:
+               divisor = UART_PL010_BAUD_38400;
+               break;
+
+       case 57600:
+               divisor = UART_PL010_BAUD_57600;
+               break;
+
+       case 115200:
+               divisor = UART_PL010_BAUD_115200;
+               break;
+
+       default:
+               divisor = UART_PL010_BAUD_38400;
+       }
+
+       IO_WRITE (port[CONSOLE_PORT] + UART_PL010_LCRM,
+                 ((divisor & 0xf00) >> 8));
+       IO_WRITE (port[CONSOLE_PORT] + UART_PL010_LCRL, (divisor & 0xff));
+
+       /*
+        ** Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled.
+        */
+       IO_WRITE (port[CONSOLE_PORT] + UART_PL010_LCRH,
+                 (UART_PL010_LCRH_WLEN_8 | UART_PL010_LCRH_FEN));
+
+       /*
+        ** Finally, enable the UART
+        */
+       IO_WRITE (port[CONSOLE_PORT] + UART_PL010_CR, (UART_PL010_CR_UARTEN));
+
+       return (0);
+}
+
+void serial_putc (const char c)
+{
+       if (c == '\n')
+               pl010_putc (CONSOLE_PORT, '\r');
+
+       pl010_putc (CONSOLE_PORT, c);
+}
+
+void serial_puts (const char *s)
+{
+       while (*s) {
+               serial_putc (*s++);
+       }
+}
+
+int serial_getc (void)
+{
+       return pl010_getc (CONSOLE_PORT);
+}
+
+int serial_tstc (void)
+{
+       return pl010_tstc (CONSOLE_PORT);
+}
+
+void serial_setbrg (void)
+{
+}
+
+static void pl010_putc (int portnum, char c)
+{
+       /* Wait until there is space in the FIFO */
+       while (IO_READ (port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_TXFF);
+
+       /* Send the character */
+       IO_WRITE (port[portnum] + UART_PL01x_DR, c);
+}
+
+static int pl010_getc (int portnum)
+{
+       unsigned int data;
+
+       /* Wait until there is data in the FIFO */
+       while (IO_READ (port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_RXFE);
+
+       data = IO_READ (port[portnum] + UART_PL01x_DR);
+
+       /* Check for an error flag */
+       if (data & 0xFFFFFF00) {
+               /* Clear the error */
+               IO_WRITE (port[portnum] + UART_PL01x_ECR, 0xFFFFFFFF);
+               return -1;
+       }
+
+       return (int) data;
+}
+
+static int pl010_tstc (int portnum)
+{
+       return !(IO_READ (port[portnum] + UART_PL01x_FR) &
+                UART_PL01x_FR_RXFE);
+}
+
+#endif
diff --git a/drivers/serial/serial_pl011.c b/drivers/serial/serial_pl011.c
new file mode 100644 (file)
index 0000000..4d35fe5
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * (C) Copyright 2004
+ * ARM Ltd.
+ * Philippe Robin, <philippe.robin@arm.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* Simple U-Boot driver for the PrimeCell PL011 UARTs on the IntegratorCP */
+/* Should be fairly simple to make it work with the PL010 as well */
+
+#include <common.h>
+
+#ifdef CFG_PL011_SERIAL
+
+#include "serial_pl011.h"
+
+#define IO_WRITE(addr, val) (*(volatile unsigned int *)(addr) = (val))
+#define IO_READ(addr) (*(volatile unsigned int *)(addr))
+
+/*
+ * IntegratorCP has two UARTs, use the first one, at 38400-8-N-1
+ * Versatile PB has four UARTs.
+ */
+
+#define CONSOLE_PORT CONFIG_CONS_INDEX
+#define baudRate CONFIG_BAUDRATE
+static volatile unsigned char *const port[] = CONFIG_PL01x_PORTS;
+#define NUM_PORTS (sizeof(port)/sizeof(port[0]))
+
+static void pl011_putc (int portnum, char c);
+static int pl011_getc (int portnum);
+static int pl011_tstc (int portnum);
+
+
+int serial_init (void)
+{
+       unsigned int temp;
+       unsigned int divider;
+       unsigned int remainder;
+       unsigned int fraction;
+
+       /*
+        ** First, disable everything.
+        */
+       IO_WRITE (port[CONSOLE_PORT] + UART_PL011_CR, 0x0);
+
+       /*
+        ** Set baud rate
+        **
+        ** IBRD = UART_CLK / (16 * BAUD_RATE)
+        ** FBRD = ROUND((64 * MOD(UART_CLK,(16 * BAUD_RATE))) / (16 * BAUD_RATE))
+        */
+       temp = 16 * baudRate;
+       divider = CONFIG_PL011_CLOCK / temp;
+       remainder = CONFIG_PL011_CLOCK % temp;
+       temp = (8 * remainder) / baudRate;
+       fraction = (temp >> 1) + (temp & 1);
+
+       IO_WRITE (port[CONSOLE_PORT] + UART_PL011_IBRD, divider);
+       IO_WRITE (port[CONSOLE_PORT] + UART_PL011_FBRD, fraction);
+
+       /*
+        ** Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled.
+        */
+       IO_WRITE (port[CONSOLE_PORT] + UART_PL011_LCRH,
+                 (UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN));
+
+       /*
+        ** Finally, enable the UART
+        */
+       IO_WRITE (port[CONSOLE_PORT] + UART_PL011_CR,
+                 (UART_PL011_CR_UARTEN | UART_PL011_CR_TXE |
+                  UART_PL011_CR_RXE));
+
+       return 0;
+}
+
+void serial_putc (const char c)
+{
+       if (c == '\n')
+               pl011_putc (CONSOLE_PORT, '\r');
+
+       pl011_putc (CONSOLE_PORT, c);
+}
+
+void serial_puts (const char *s)
+{
+       while (*s) {
+               serial_putc (*s++);
+       }
+}
+
+int serial_getc (void)
+{
+       return pl011_getc (CONSOLE_PORT);
+}
+
+int serial_tstc (void)
+{
+       return pl011_tstc (CONSOLE_PORT);
+}
+
+void serial_setbrg (void)
+{
+}
+
+static void pl011_putc (int portnum, char c)
+{
+       /* Wait until there is space in the FIFO */
+       while (IO_READ (port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_TXFF);
+
+       /* Send the character */
+       IO_WRITE (port[portnum] + UART_PL01x_DR, c);
+}
+
+static int pl011_getc (int portnum)
+{
+       unsigned int data;
+
+       /* Wait until there is data in the FIFO */
+       while (IO_READ (port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_RXFE);
+
+       data = IO_READ (port[portnum] + UART_PL01x_DR);
+
+       /* Check for an error flag */
+       if (data & 0xFFFFFF00) {
+               /* Clear the error */
+               IO_WRITE (port[portnum] + UART_PL01x_ECR, 0xFFFFFFFF);
+               return -1;
+       }
+
+       return (int) data;
+}
+
+static int pl011_tstc (int portnum)
+{
+       return !(IO_READ (port[portnum] + UART_PL01x_FR) &
+                UART_PL01x_FR_RXFE);
+}
+
+#endif
diff --git a/drivers/serial/serial_pl011.h b/drivers/serial/serial_pl011.h
new file mode 100644 (file)
index 0000000..5f20fdd
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * (C) Copyright 2003, 2004
+ * ARM Ltd.
+ * Philippe Robin, <philippe.robin@arm.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * ARM PrimeCell UART's (PL010 & PL011)
+ * ------------------------------------
+ *
+ *  Definitions common to both PL010 & PL011
+ *
+ */
+#define UART_PL01x_DR                   0x00    /*  Data read or written from the interface. */
+#define UART_PL01x_RSR                  0x04    /*  Receive status register (Read). */
+#define UART_PL01x_ECR                  0x04    /*  Error clear register (Write). */
+#define UART_PL01x_FR                   0x18    /*  Flag register (Read only). */
+
+#define UART_PL01x_RSR_OE               0x08
+#define UART_PL01x_RSR_BE               0x04
+#define UART_PL01x_RSR_PE               0x02
+#define UART_PL01x_RSR_FE               0x01
+
+#define UART_PL01x_FR_TXFE              0x80
+#define UART_PL01x_FR_RXFF              0x40
+#define UART_PL01x_FR_TXFF              0x20
+#define UART_PL01x_FR_RXFE              0x10
+#define UART_PL01x_FR_BUSY              0x08
+#define UART_PL01x_FR_TMSK              (UART_PL01x_FR_TXFF + UART_PL01x_FR_BUSY)
+
+/*
+ *  PL010 definitions
+ *
+ */
+#define UART_PL010_LCRH                 0x08    /*  Line control register, high byte. */
+#define UART_PL010_LCRM                 0x0C    /*  Line control register, middle byte. */
+#define UART_PL010_LCRL                 0x10    /*  Line control register, low byte. */
+#define UART_PL010_CR                   0x14    /*  Control register. */
+#define UART_PL010_IIR                  0x1C    /*  Interrupt indentification register (Read). */
+#define UART_PL010_ICR                  0x1C    /*  Interrupt clear register (Write). */
+#define UART_PL010_ILPR                 0x20    /*  IrDA low power counter register. */
+
+#define UART_PL010_CR_LPE               (1 << 7)
+#define UART_PL010_CR_RTIE              (1 << 6)
+#define UART_PL010_CR_TIE               (1 << 5)
+#define UART_PL010_CR_RIE               (1 << 4)
+#define UART_PL010_CR_MSIE              (1 << 3)
+#define UART_PL010_CR_IIRLP             (1 << 2)
+#define UART_PL010_CR_SIREN             (1 << 1)
+#define UART_PL010_CR_UARTEN            (1 << 0)
+
+#define UART_PL010_LCRH_WLEN_8          (3 << 5)
+#define UART_PL010_LCRH_WLEN_7          (2 << 5)
+#define UART_PL010_LCRH_WLEN_6          (1 << 5)
+#define UART_PL010_LCRH_WLEN_5          (0 << 5)
+#define UART_PL010_LCRH_FEN             (1 << 4)
+#define UART_PL010_LCRH_STP2            (1 << 3)
+#define UART_PL010_LCRH_EPS             (1 << 2)
+#define UART_PL010_LCRH_PEN             (1 << 1)
+#define UART_PL010_LCRH_BRK             (1 << 0)
+
+
+#define UART_PL010_BAUD_460800            1
+#define UART_PL010_BAUD_230400            3
+#define UART_PL010_BAUD_115200            7
+#define UART_PL010_BAUD_57600             15
+#define UART_PL010_BAUD_38400             23
+#define UART_PL010_BAUD_19200             47
+#define UART_PL010_BAUD_14400             63
+#define UART_PL010_BAUD_9600              95
+#define UART_PL010_BAUD_4800              191
+#define UART_PL010_BAUD_2400              383
+#define UART_PL010_BAUD_1200              767
+/*
+ *  PL011 definitions
+ *
+ */
+#define UART_PL011_IBRD                 0x24
+#define UART_PL011_FBRD                 0x28
+#define UART_PL011_LCRH                 0x2C
+#define UART_PL011_CR                   0x30
+#define UART_PL011_IMSC                 0x38
+#define UART_PL011_PERIPH_ID0           0xFE0
+
+#define UART_PL011_LCRH_SPS             (1 << 7)
+#define UART_PL011_LCRH_WLEN_8          (3 << 5)
+#define UART_PL011_LCRH_WLEN_7          (2 << 5)
+#define UART_PL011_LCRH_WLEN_6          (1 << 5)
+#define UART_PL011_LCRH_WLEN_5          (0 << 5)
+#define UART_PL011_LCRH_FEN             (1 << 4)
+#define UART_PL011_LCRH_STP2            (1 << 3)
+#define UART_PL011_LCRH_EPS             (1 << 2)
+#define UART_PL011_LCRH_PEN             (1 << 1)
+#define UART_PL011_LCRH_BRK             (1 << 0)
+
+#define UART_PL011_CR_CTSEN             (1 << 15)
+#define UART_PL011_CR_RTSEN             (1 << 14)
+#define UART_PL011_CR_OUT2              (1 << 13)
+#define UART_PL011_CR_OUT1              (1 << 12)
+#define UART_PL011_CR_RTS               (1 << 11)
+#define UART_PL011_CR_DTR               (1 << 10)
+#define UART_PL011_CR_RXE               (1 << 9)
+#define UART_PL011_CR_TXE               (1 << 8)
+#define UART_PL011_CR_LPE               (1 << 7)
+#define UART_PL011_CR_IIRLP             (1 << 2)
+#define UART_PL011_CR_SIREN             (1 << 1)
+#define UART_PL011_CR_UARTEN            (1 << 0)
+
+#define UART_PL011_IMSC_OEIM            (1 << 10)
+#define UART_PL011_IMSC_BEIM            (1 << 9)
+#define UART_PL011_IMSC_PEIM            (1 << 8)
+#define UART_PL011_IMSC_FEIM            (1 << 7)
+#define UART_PL011_IMSC_RTIM            (1 << 6)
+#define UART_PL011_IMSC_TXIM            (1 << 5)
+#define UART_PL011_IMSC_RXIM            (1 << 4)
+#define UART_PL011_IMSC_DSRMIM          (1 << 3)
+#define UART_PL011_IMSC_DCDMIM          (1 << 2)
+#define UART_PL011_IMSC_CTSMIM          (1 << 1)
+#define UART_PL011_IMSC_RIMIM           (1 << 0)
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c
new file mode 100644 (file)
index 0000000..d678ab6
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * (C) Copyright 2004 Atmark Techno, Inc.
+ *
+ * Yasushi SHOJI <yashi@atmark-techno.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+
+#ifdef CONFIG_XILINX_UARTLITE
+
+#include <asm/serial_xuartlite.h>
+
+/* FIXME: we should convert these to in32 and out32 */
+#define IO_WORD(offset)             (*(volatile unsigned long *)(offset))
+#define IO_SERIAL(offset)    IO_WORD(CONFIG_SERIAL_BASE + (offset))
+
+#define IO_SERIAL_RX_FIFO   IO_SERIAL(XUL_RX_FIFO_OFFSET)
+#define IO_SERIAL_TX_FIFO   IO_SERIAL(XUL_TX_FIFO_OFFSET)
+#define IO_SERIAL_STATUS    IO_SERIAL(XUL_STATUS_REG_OFFSET)
+#define IO_SERIAL_CONTROL   IO_SERIAL(XUL_CONTROL_REG_OFFSET)
+
+int serial_init(void)
+{
+       /* FIXME: Nothing for now. We should initialize fifo, etc */
+       return 0;
+}
+
+void serial_setbrg(void)
+{
+       /* FIXME: what's this for? */
+}
+
+void serial_putc(const char c)
+{
+       if (c == '\n') serial_putc('\r');
+       while (IO_SERIAL_STATUS & XUL_SR_TX_FIFO_FULL);
+       IO_SERIAL_TX_FIFO = (unsigned char) (c & 0xff);
+}
+
+void serial_puts(const char * s)
+{
+       while (*s) {
+               serial_putc(*s++);
+       }
+}
+
+int serial_getc(void)
+{
+       while (!(IO_SERIAL_STATUS & XUL_SR_RX_FIFO_VALID_DATA));
+       return IO_SERIAL_RX_FIFO & 0xff;
+}
+
+int serial_tstc(void)
+{
+       return (IO_SERIAL_STATUS & XUL_SR_RX_FIFO_VALID_DATA);
+}
+
+#endif /* CONFIG_MICROBLZE */
diff --git a/drivers/serial/usbtty.c b/drivers/serial/usbtty.c
new file mode 100644 (file)
index 0000000..a3b5013
--- /dev/null
@@ -0,0 +1,1012 @@
+/*
+ * (C) Copyright 2003
+ * Gerry Hamel, geh@ti.com, Texas Instruments
+ *
+ * (C) Copyright 2006
+ * Bryan O'Donoghue, bodonoghue@codehermit.ie
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307         USA
+ *
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_USB_TTY
+
+#include <circbuf.h>
+#include <devices.h>
+#include "usbtty.h"
+#include "usb_cdc_acm.h"
+#include "usbdescriptors.h"
+#include <config.h>            /* If defined, override Linux identifiers with
+                                * vendor specific ones */
+
+#if 0
+#define TTYDBG(fmt,args...)\
+       serial_printf("[%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args)
+#else
+#define TTYDBG(fmt,args...) do{}while(0)
+#endif
+
+#if 1
+#define TTYERR(fmt,args...)\
+       serial_printf("ERROR![%s] %s %d: "fmt, __FILE__,__FUNCTION__,\
+       __LINE__,##args)
+#else
+#define TTYERR(fmt,args...) do{}while(0)
+#endif
+
+/*
+ * Defines
+ */
+#define NUM_CONFIGS    1
+#define MAX_INTERFACES 2
+#define NUM_ENDPOINTS  3
+#define ACM_TX_ENDPOINT 3
+#define ACM_RX_ENDPOINT 2
+#define GSERIAL_TX_ENDPOINT 2
+#define GSERIAL_RX_ENDPOINT 1
+#define NUM_ACM_INTERFACES 2
+#define NUM_GSERIAL_INTERFACES 1
+#define CONFIG_USBD_DATA_INTERFACE_STR "Bulk Data Interface"
+#define CONFIG_USBD_CTRL_INTERFACE_STR "Control Interface"
+
+/*
+ * Buffers to hold input and output data
+ */
+#define USBTTY_BUFFER_SIZE 256
+static circbuf_t usbtty_input;
+static circbuf_t usbtty_output;
+
+
+/*
+ * Instance variables
+ */
+static device_t usbttydev;
+static struct usb_device_instance device_instance[1];
+static struct usb_bus_instance bus_instance[1];
+static struct usb_configuration_instance config_instance[NUM_CONFIGS];
+static struct usb_interface_instance interface_instance[MAX_INTERFACES];
+static struct usb_alternate_instance alternate_instance[MAX_INTERFACES];
+/* one extra for control endpoint */
+static struct usb_endpoint_instance endpoint_instance[NUM_ENDPOINTS+1];
+
+/*
+ * Global flag
+ */
+int usbtty_configured_flag = 0;
+
+/*
+ * Serial number
+ */
+static char serial_number[16];
+
+
+/*
+ * Descriptors, Strings, Local variables.
+ */
+
+/* defined and used by usbdcore_ep0.c */
+extern struct usb_string_descriptor **usb_strings;
+
+/* Indicies, References */
+static unsigned short rx_endpoint = 0;
+static unsigned short tx_endpoint = 0;
+static unsigned short interface_count = 0;
+static struct usb_string_descriptor *usbtty_string_table[STR_COUNT];
+
+/* USB Descriptor Strings */
+static u8 wstrLang[4] = {4,USB_DT_STRING,0x9,0x4};
+static u8 wstrManufacturer[2 + 2*(sizeof(CONFIG_USBD_MANUFACTURER)-1)];
+static u8 wstrProduct[2 + 2*(sizeof(CONFIG_USBD_PRODUCT_NAME)-1)];
+static u8 wstrSerial[2 + 2*(sizeof(serial_number) - 1)];
+static u8 wstrConfiguration[2 + 2*(sizeof(CONFIG_USBD_CONFIGURATION_STR)-1)];
+static u8 wstrDataInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)];
+static u8 wstrCtrlInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)];
+
+/* Standard USB Data Structures */
+static struct usb_interface_descriptor interface_descriptors[MAX_INTERFACES];
+static struct usb_endpoint_descriptor *ep_descriptor_ptrs[NUM_ENDPOINTS];
+static struct usb_configuration_descriptor     *configuration_descriptor = 0;
+static struct usb_device_descriptor device_descriptor = {
+       .bLength = sizeof(struct usb_device_descriptor),
+       .bDescriptorType =      USB_DT_DEVICE,
+       .bcdUSB =               cpu_to_le16(USB_BCD_VERSION),
+       .bDeviceSubClass =      0x00,
+       .bDeviceProtocol =      0x00,
+       .bMaxPacketSize0 =      EP0_MAX_PACKET_SIZE,
+       .idVendor =             cpu_to_le16(CONFIG_USBD_VENDORID),
+       .bcdDevice =            cpu_to_le16(USBTTY_BCD_DEVICE),
+       .iManufacturer =        STR_MANUFACTURER,
+       .iProduct =             STR_PRODUCT,
+       .iSerialNumber =        STR_SERIAL,
+       .bNumConfigurations =   NUM_CONFIGS
+};
+
+
+/*
+ * Static CDC ACM specific descriptors
+ */
+
+struct acm_config_desc {
+       struct usb_configuration_descriptor configuration_desc;
+
+       /* Master Interface */
+       struct usb_interface_descriptor interface_desc;
+
+       struct usb_class_header_function_descriptor usb_class_header;
+       struct usb_class_call_management_descriptor usb_class_call_mgt;
+       struct usb_class_abstract_control_descriptor usb_class_acm;
+       struct usb_class_union_function_descriptor usb_class_union;
+       struct usb_endpoint_descriptor notification_endpoint;
+
+       /* Slave Interface */
+       struct usb_interface_descriptor data_class_interface;
+       struct usb_endpoint_descriptor
+               data_endpoints[NUM_ENDPOINTS-1] __attribute__((packed));
+} __attribute__((packed));
+
+static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = {
+       {
+               .configuration_desc ={
+                       .bLength =
+                               sizeof(struct usb_configuration_descriptor),
+                       .bDescriptorType = USB_DT_CONFIG,
+                       .wTotalLength =
+                               cpu_to_le16(sizeof(struct acm_config_desc)),
+                       .bNumInterfaces = NUM_ACM_INTERFACES,
+                       .bConfigurationValue = 1,
+                       .iConfiguration = STR_CONFIG,
+                       .bmAttributes =
+                               BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
+                       .bMaxPower = USBTTY_MAXPOWER
+               },
+               /* Interface 1 */
+               .interface_desc = {
+                       .bLength  = sizeof(struct usb_interface_descriptor),
+                       .bDescriptorType = USB_DT_INTERFACE,
+                       .bInterfaceNumber = 0,
+                       .bAlternateSetting = 0,
+                       .bNumEndpoints = 0x01,
+                       .bInterfaceClass =
+                               COMMUNICATIONS_INTERFACE_CLASS_CONTROL,
+                       .bInterfaceSubClass = COMMUNICATIONS_ACM_SUBCLASS,
+                       .bInterfaceProtocol = COMMUNICATIONS_V25TER_PROTOCOL,
+                       .iInterface = STR_CTRL_INTERFACE,
+               },
+               .usb_class_header = {
+                       .bFunctionLength        =
+                               sizeof(struct usb_class_header_function_descriptor),
+                       .bDescriptorType        = CS_INTERFACE,
+                       .bDescriptorSubtype     = USB_ST_HEADER,
+                       .bcdCDC = cpu_to_le16(110),
+               },
+               .usb_class_call_mgt = {
+                       .bFunctionLength        =
+                               sizeof(struct usb_class_call_management_descriptor),
+                       .bDescriptorType        = CS_INTERFACE,
+                       .bDescriptorSubtype     = USB_ST_CMF,
+                       .bmCapabilities         = 0x00,
+                       .bDataInterface         = 0x01,
+               },
+               .usb_class_acm = {
+                       .bFunctionLength        =
+                               sizeof(struct usb_class_abstract_control_descriptor),
+                       .bDescriptorType        = CS_INTERFACE,
+                       .bDescriptorSubtype     = USB_ST_ACMF,
+                       .bmCapabilities         = 0x00,
+               },
+               .usb_class_union = {
+                       .bFunctionLength        =
+                               sizeof(struct usb_class_union_function_descriptor),
+                       .bDescriptorType        = CS_INTERFACE,
+                       .bDescriptorSubtype     = USB_ST_UF,
+                       .bMasterInterface       = 0x00,
+                       .bSlaveInterface0       = 0x01,
+               },
+               .notification_endpoint = {
+                       .bLength =
+                               sizeof(struct usb_endpoint_descriptor),
+                       .bDescriptorType        = USB_DT_ENDPOINT,
+                       .bEndpointAddress       = 0x01 | USB_DIR_IN,
+                       .bmAttributes           = USB_ENDPOINT_XFER_INT,
+                       .wMaxPacketSize
+                               = cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
+                       .bInterval              = 0xFF,
+               },
+
+               /* Interface 2 */
+               .data_class_interface = {
+                       .bLength                =
+                               sizeof(struct usb_interface_descriptor),
+                       .bDescriptorType        = USB_DT_INTERFACE,
+                       .bInterfaceNumber       = 0x01,
+                       .bAlternateSetting      = 0x00,
+                       .bNumEndpoints          = 0x02,
+                       .bInterfaceClass        =
+                               COMMUNICATIONS_INTERFACE_CLASS_DATA,
+                       .bInterfaceSubClass     = DATA_INTERFACE_SUBCLASS_NONE,
+                       .bInterfaceProtocol     = DATA_INTERFACE_PROTOCOL_NONE,
+                       .iInterface             = STR_DATA_INTERFACE,
+               },
+               .data_endpoints = {
+                       {
+                               .bLength                =
+                                       sizeof(struct usb_endpoint_descriptor),
+                               .bDescriptorType        = USB_DT_ENDPOINT,
+                               .bEndpointAddress       = 0x02 | USB_DIR_OUT,
+                               .bmAttributes           =
+                                       USB_ENDPOINT_XFER_BULK,
+                               .wMaxPacketSize         =
+                                       cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),
+                               .bInterval              = 0xFF,
+                       },
+                       {
+                               .bLength                =
+                                       sizeof(struct usb_endpoint_descriptor),
+                               .bDescriptorType        = USB_DT_ENDPOINT,
+                               .bEndpointAddress       = 0x03 | USB_DIR_IN,
+                               .bmAttributes           =
+                                       USB_ENDPOINT_XFER_BULK,
+                               .wMaxPacketSize         =
+                                       cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),
+                               .bInterval              = 0xFF,
+                       },
+               },
+       },
+};
+
+static struct rs232_emu rs232_desc={
+               .dter           =       115200,
+               .stop_bits      =       0x00,
+               .parity         =       0x00,
+               .data_bits      =       0x08
+};
+
+
+/*
+ * Static Generic Serial specific data
+ */
+
+
+struct gserial_config_desc {
+
+       struct usb_configuration_descriptor configuration_desc;
+       struct usb_interface_descriptor
+               interface_desc[NUM_GSERIAL_INTERFACES] __attribute__((packed));
+       struct usb_endpoint_descriptor
+               data_endpoints[NUM_ENDPOINTS] __attribute__((packed));
+
+} __attribute__((packed));
+
+static struct gserial_config_desc
+gserial_configuration_descriptors[NUM_CONFIGS] ={
+       {
+               .configuration_desc ={
+                       .bLength = sizeof(struct usb_configuration_descriptor),
+                       .bDescriptorType = USB_DT_CONFIG,
+                       .wTotalLength =
+                               cpu_to_le16(sizeof(struct gserial_config_desc)),
+                       .bNumInterfaces = NUM_GSERIAL_INTERFACES,
+                       .bConfigurationValue = 1,
+                       .iConfiguration = STR_CONFIG,
+                       .bmAttributes =
+                               BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
+                       .bMaxPower = USBTTY_MAXPOWER
+               },
+               .interface_desc = {
+                       {
+                               .bLength  =
+                                       sizeof(struct usb_interface_descriptor),
+                               .bDescriptorType = USB_DT_INTERFACE,
+                               .bInterfaceNumber = 0,
+                               .bAlternateSetting = 0,
+                               .bNumEndpoints = NUM_ENDPOINTS,
+                               .bInterfaceClass =
+                                       COMMUNICATIONS_INTERFACE_CLASS_VENDOR,
+                               .bInterfaceSubClass =
+                                       COMMUNICATIONS_NO_SUBCLASS,
+                               .bInterfaceProtocol =
+                                       COMMUNICATIONS_NO_PROTOCOL,
+                               .iInterface = STR_DATA_INTERFACE
+                       },
+               },
+               .data_endpoints  = {
+                       {
+                               .bLength =
+                                       sizeof(struct usb_endpoint_descriptor),
+                               .bDescriptorType =      USB_DT_ENDPOINT,
+                               .bEndpointAddress =     0x01 | USB_DIR_OUT,
+                               .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+                               .wMaxPacketSize =
+                                       cpu_to_le16(CONFIG_USBD_SERIAL_OUT_PKTSIZE),
+                               .bInterval=             0xFF,
+                       },
+                       {
+                               .bLength =
+                                       sizeof(struct usb_endpoint_descriptor),
+                               .bDescriptorType =      USB_DT_ENDPOINT,
+                               .bEndpointAddress =     0x02 | USB_DIR_IN,
+                               .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+                               .wMaxPacketSize =
+                                       cpu_to_le16(CONFIG_USBD_SERIAL_IN_PKTSIZE),
+                               .bInterval =            0xFF,
+                       },
+                       {
+                               .bLength =
+                                       sizeof(struct usb_endpoint_descriptor),
+                               .bDescriptorType =      USB_DT_ENDPOINT,
+                               .bEndpointAddress =     0x03 | USB_DIR_IN,
+                               .bmAttributes =         USB_ENDPOINT_XFER_INT,
+                               .wMaxPacketSize =
+                                       cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
+                               .bInterval =            0xFF,
+                       },
+               },
+       },
+};
+
+/*
+ * Static Function Prototypes
+ */
+
+static void usbtty_init_strings (void);
+static void usbtty_init_instances (void);
+static void usbtty_init_endpoints (void);
+static void usbtty_init_terminal_type(short type);
+static void usbtty_event_handler (struct usb_device_instance *device,
+                               usb_device_event_t event, int data);
+static int usbtty_cdc_setup(struct usb_device_request *request,
+                               struct urb *urb);
+static int usbtty_configured (void);
+static int write_buffer (circbuf_t * buf);
+static int fill_buffer (circbuf_t * buf);
+
+void usbtty_poll (void);
+
+/* utility function for converting char* to wide string used by USB */
+static void str2wide (char *str, u16 * wide)
+{
+       int i;
+       for (i = 0; i < strlen (str) && str[i]; i++){
+               #if defined(__LITTLE_ENDIAN)
+                       wide[i] = (u16) str[i];
+               #elif defined(__BIG_ENDIAN)
+                       wide[i] = ((u16)(str[i])<<8);
+               #else
+                       #error "__LITTLE_ENDIAN or __BIG_ENDIAN undefined"
+               #endif
+       }
+}
+
+/*
+ * Test whether a character is in the RX buffer
+ */
+
+int usbtty_tstc (void)
+{
+       struct usb_endpoint_instance *endpoint =
+               &endpoint_instance[rx_endpoint];
+
+       /* If no input data exists, allow more RX to be accepted */
+       if(usbtty_input.size <= 0){
+               udc_unset_nak(endpoint->endpoint_address&0x03);
+       }
+
+       usbtty_poll ();
+       return (usbtty_input.size > 0);
+}
+
+/*
+ * Read a single byte from the usb client port. Returns 1 on success, 0
+ * otherwise. When the function is succesfull, the character read is
+ * written into its argument c.
+ */
+
+int usbtty_getc (void)
+{
+       char c;
+       struct usb_endpoint_instance *endpoint =
+               &endpoint_instance[rx_endpoint];
+
+       while (usbtty_input.size <= 0) {
+               udc_unset_nak(endpoint->endpoint_address&0x03);
+               usbtty_poll ();
+       }
+
+       buf_pop (&usbtty_input, &c, 1);
+       udc_set_nak(endpoint->endpoint_address&0x03);
+
+       return c;
+}
+
+/*
+ * Output a single byte to the usb client port.
+ */
+void usbtty_putc (const char c)
+{
+       buf_push (&usbtty_output, &c, 1);
+       /* If \n, also do \r */
+       if (c == '\n')
+               buf_push (&usbtty_output, "\r", 1);
+
+       /* Poll at end to handle new data... */
+       if ((usbtty_output.size + 2) >= usbtty_output.totalsize) {
+               usbtty_poll ();
+       }
+}
+
+/* usbtty_puts() helper function for finding the next '\n' in a string */
+static int next_nl_pos (const char *s)
+{
+       int i;
+
+       for (i = 0; s[i] != '\0'; i++) {
+               if (s[i] == '\n')
+                       return i;
+       }
+       return i;
+}
+
+/*
+ * Output a string to the usb client port - implementing flow control
+ */
+
+static void __usbtty_puts (const char *str, int len)
+{
+       int maxlen = usbtty_output.totalsize;
+       int space, n;
+
+       /* break str into chunks < buffer size, if needed */
+       while (len > 0) {
+               usbtty_poll ();
+
+               space = maxlen - usbtty_output.size;
+               /* Empty buffer here, if needed, to ensure space... */
+               if (space) {
+                       write_buffer (&usbtty_output);
+
+                       n = MIN (space, MIN (len, maxlen));
+                       buf_push (&usbtty_output, str, n);
+
+                       str += n;
+                       len -= n;
+               }
+       }
+}
+
+void usbtty_puts (const char *str)
+{
+       int n;
+       int len = strlen (str);
+
+       /* add '\r' for each '\n' */
+       while (len > 0) {
+               n = next_nl_pos (str);
+
+               if (str[n] == '\n') {
+                       __usbtty_puts (str, n + 1);
+                       __usbtty_puts ("\r", 1);
+                       str += (n + 1);
+                       len -= (n + 1);
+               } else {
+                       /* No \n found.  All done. */
+                       __usbtty_puts (str, n);
+                       break;
+               }
+       }
+
+       /* Poll at end to handle new data... */
+       usbtty_poll ();
+}
+
+/*
+ * Initialize the usb client port.
+ *
+ */
+int drv_usbtty_init (void)
+{
+       int rc;
+       char * sn;
+       char * tt;
+       int snlen;
+
+       /* Ger seiral number */
+       if (!(sn = getenv("serial#"))) {
+               sn = "000000000000";
+       }
+       snlen = strlen(sn);
+       if (snlen > sizeof(serial_number) - 1) {
+               printf ("Warning: serial number %s is too long (%d > %d)\n",
+                       sn, snlen, sizeof(serial_number) - 1);
+               snlen = sizeof(serial_number) - 1;
+       }
+       memcpy (serial_number, sn, snlen);
+       serial_number[snlen] = '\0';
+
+       /* Decide on which type of UDC device to be.
+        */
+
+       if(!(tt = getenv("usbtty"))) {
+               tt = "generic";
+       }
+       usbtty_init_terminal_type(strcmp(tt,"cdc_acm"));
+
+       /* prepare buffers... */
+       buf_init (&usbtty_input, USBTTY_BUFFER_SIZE);
+       buf_init (&usbtty_output, USBTTY_BUFFER_SIZE);
+
+       /* Now, set up USB controller and infrastructure */
+       udc_init ();            /* Basic USB initialization */
+
+       usbtty_init_strings ();
+       usbtty_init_instances ();
+
+       udc_startup_events (device_instance);/* Enable dev, init udc pointers */
+       udc_connect ();         /* Enable pullup for host detection */
+
+       usbtty_init_endpoints ();
+
+       /* Device initialization */
+       memset (&usbttydev, 0, sizeof (usbttydev));
+
+       strcpy (usbttydev.name, "usbtty");
+       usbttydev.ext = 0;      /* No extensions */
+       usbttydev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_OUTPUT;
+       usbttydev.tstc = usbtty_tstc;   /* 'tstc' function */
+       usbttydev.getc = usbtty_getc;   /* 'getc' function */
+       usbttydev.putc = usbtty_putc;   /* 'putc' function */
+       usbttydev.puts = usbtty_puts;   /* 'puts' function */
+
+       rc = device_register (&usbttydev);
+
+       return (rc == 0) ? 1 : rc;
+}
+
+static void usbtty_init_strings (void)
+{
+       struct usb_string_descriptor *string;
+
+       usbtty_string_table[STR_LANG] =
+               (struct usb_string_descriptor*)wstrLang;
+
+       string = (struct usb_string_descriptor *) wstrManufacturer;
+       string->bLength = sizeof(wstrManufacturer);
+       string->bDescriptorType = USB_DT_STRING;
+       str2wide (CONFIG_USBD_MANUFACTURER, string->wData);
+       usbtty_string_table[STR_MANUFACTURER]=string;
+
+
+       string = (struct usb_string_descriptor *) wstrProduct;
+       string->bLength = sizeof(wstrProduct);
+       string->bDescriptorType = USB_DT_STRING;
+       str2wide (CONFIG_USBD_PRODUCT_NAME, string->wData);
+       usbtty_string_table[STR_PRODUCT]=string;
+
+
+       string = (struct usb_string_descriptor *) wstrSerial;
+       string->bLength = sizeof(serial_number);
+       string->bDescriptorType = USB_DT_STRING;
+       str2wide (serial_number, string->wData);
+       usbtty_string_table[STR_SERIAL]=string;
+
+
+       string = (struct usb_string_descriptor *) wstrConfiguration;
+       string->bLength = sizeof(wstrConfiguration);
+       string->bDescriptorType = USB_DT_STRING;
+       str2wide (CONFIG_USBD_CONFIGURATION_STR, string->wData);
+       usbtty_string_table[STR_CONFIG]=string;
+
+
+       string = (struct usb_string_descriptor *) wstrDataInterface;
+       string->bLength = sizeof(wstrDataInterface);
+       string->bDescriptorType = USB_DT_STRING;
+       str2wide (CONFIG_USBD_DATA_INTERFACE_STR, string->wData);
+       usbtty_string_table[STR_DATA_INTERFACE]=string;
+
+       string = (struct usb_string_descriptor *) wstrCtrlInterface;
+       string->bLength = sizeof(wstrCtrlInterface);
+       string->bDescriptorType = USB_DT_STRING;
+       str2wide (CONFIG_USBD_CTRL_INTERFACE_STR, string->wData);
+       usbtty_string_table[STR_CTRL_INTERFACE]=string;
+
+       /* Now, initialize the string table for ep0 handling */
+       usb_strings = usbtty_string_table;
+}
+
+static void usbtty_init_instances (void)
+{
+       int i;
+
+       /* initialize device instance */
+       memset (device_instance, 0, sizeof (struct usb_device_instance));
+       device_instance->device_state = STATE_INIT;
+       device_instance->device_descriptor = &device_descriptor;
+       device_instance->event = usbtty_event_handler;
+       device_instance->cdc_recv_setup = usbtty_cdc_setup;
+       device_instance->bus = bus_instance;
+       device_instance->configurations = NUM_CONFIGS;
+       device_instance->configuration_instance_array = config_instance;
+
+       /* initialize bus instance */
+       memset (bus_instance, 0, sizeof (struct usb_bus_instance));
+       bus_instance->device = device_instance;
+       bus_instance->endpoint_array = endpoint_instance;
+       bus_instance->max_endpoints = 1;
+       bus_instance->maxpacketsize = 64;
+       bus_instance->serial_number_str = serial_number;
+
+       /* configuration instance */
+       memset (config_instance, 0,
+               sizeof (struct usb_configuration_instance));
+       config_instance->interfaces = interface_count;
+       config_instance->configuration_descriptor = configuration_descriptor;
+       config_instance->interface_instance_array = interface_instance;
+
+       /* interface instance */
+       memset (interface_instance, 0,
+               sizeof (struct usb_interface_instance));
+       interface_instance->alternates = 1;
+       interface_instance->alternates_instance_array = alternate_instance;
+
+       /* alternates instance */
+       memset (alternate_instance, 0,
+               sizeof (struct usb_alternate_instance));
+       alternate_instance->interface_descriptor = interface_descriptors;
+       alternate_instance->endpoints = NUM_ENDPOINTS;
+       alternate_instance->endpoints_descriptor_array = ep_descriptor_ptrs;
+
+       /* endpoint instances */
+       memset (&endpoint_instance[0], 0,
+               sizeof (struct usb_endpoint_instance));
+       endpoint_instance[0].endpoint_address = 0;
+       endpoint_instance[0].rcv_packetSize = EP0_MAX_PACKET_SIZE;
+       endpoint_instance[0].rcv_attributes = USB_ENDPOINT_XFER_CONTROL;
+       endpoint_instance[0].tx_packetSize = EP0_MAX_PACKET_SIZE;
+       endpoint_instance[0].tx_attributes = USB_ENDPOINT_XFER_CONTROL;
+       udc_setup_ep (device_instance, 0, &endpoint_instance[0]);
+
+       for (i = 1; i <= NUM_ENDPOINTS; i++) {
+               memset (&endpoint_instance[i], 0,
+                       sizeof (struct usb_endpoint_instance));
+
+               endpoint_instance[i].endpoint_address =
+                       ep_descriptor_ptrs[i - 1]->bEndpointAddress;
+
+               endpoint_instance[i].rcv_attributes =
+                       ep_descriptor_ptrs[i - 1]->bmAttributes;
+
+               endpoint_instance[i].rcv_packetSize =
+                       le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize);
+
+               endpoint_instance[i].tx_attributes =
+                       ep_descriptor_ptrs[i - 1]->bmAttributes;
+
+               endpoint_instance[i].tx_packetSize =
+                       le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize);
+
+               endpoint_instance[i].tx_attributes =
+                       ep_descriptor_ptrs[i - 1]->bmAttributes;
+
+               urb_link_init (&endpoint_instance[i].rcv);
+               urb_link_init (&endpoint_instance[i].rdy);
+               urb_link_init (&endpoint_instance[i].tx);
+               urb_link_init (&endpoint_instance[i].done);
+
+               if (endpoint_instance[i].endpoint_address & USB_DIR_IN)
+                       endpoint_instance[i].tx_urb =
+                               usbd_alloc_urb (device_instance,
+                                               &endpoint_instance[i]);
+               else
+                       endpoint_instance[i].rcv_urb =
+                               usbd_alloc_urb (device_instance,
+                                               &endpoint_instance[i]);
+       }
+}
+
+static void usbtty_init_endpoints (void)
+{
+       int i;
+
+       bus_instance->max_endpoints = NUM_ENDPOINTS + 1;
+       for (i = 1; i <= NUM_ENDPOINTS; i++) {
+               udc_setup_ep (device_instance, i, &endpoint_instance[i]);
+       }
+}
+
+/* usbtty_init_terminal_type
+ *
+ * Do some late binding for our device type.
+ */
+static void usbtty_init_terminal_type(short type)
+{
+       switch(type){
+               /* CDC ACM */
+               case 0:
+                       /* Assign endpoint descriptors */
+                       ep_descriptor_ptrs[0] =
+                               &acm_configuration_descriptors[0].notification_endpoint;
+                       ep_descriptor_ptrs[1] =
+                               &acm_configuration_descriptors[0].data_endpoints[0];
+                       ep_descriptor_ptrs[2] =
+                               &acm_configuration_descriptors[0].data_endpoints[1];
+
+                       /* Enumerate Device Descriptor */
+                       device_descriptor.bDeviceClass =
+                               COMMUNICATIONS_DEVICE_CLASS;
+                       device_descriptor.idProduct =
+                               cpu_to_le16(CONFIG_USBD_PRODUCTID_CDCACM);
+
+                       /* Assign endpoint indices */
+                       tx_endpoint = ACM_TX_ENDPOINT;
+                       rx_endpoint = ACM_RX_ENDPOINT;
+
+                       /* Configuration Descriptor */
+                       configuration_descriptor =
+                               (struct usb_configuration_descriptor*)
+                               &acm_configuration_descriptors;
+
+                       /* Interface count */
+                       interface_count = NUM_ACM_INTERFACES;
+               break;
+
+               /* BULK IN/OUT & Default */
+               case 1:
+               default:
+                       /* Assign endpoint descriptors */
+                       ep_descriptor_ptrs[0] =
+                               &gserial_configuration_descriptors[0].data_endpoints[0];
+                       ep_descriptor_ptrs[1] =
+                               &gserial_configuration_descriptors[0].data_endpoints[1];
+                       ep_descriptor_ptrs[2] =
+                               &gserial_configuration_descriptors[0].data_endpoints[2];
+
+                       /* Enumerate Device Descriptor */
+                       device_descriptor.bDeviceClass = 0xFF;
+                       device_descriptor.idProduct =
+                               cpu_to_le16(CONFIG_USBD_PRODUCTID_GSERIAL);
+
+                       /* Assign endpoint indices */
+                       tx_endpoint = GSERIAL_TX_ENDPOINT;
+                       rx_endpoint = GSERIAL_RX_ENDPOINT;
+
+                       /* Configuration Descriptor */
+                       configuration_descriptor =
+                               (struct usb_configuration_descriptor*)
+                               &gserial_configuration_descriptors;
+
+                       /* Interface count */
+                       interface_count = NUM_GSERIAL_INTERFACES;
+               break;
+       }
+}
+
+/******************************************************************************/
+
+static struct urb *next_urb (struct usb_device_instance *device,
+                            struct usb_endpoint_instance *endpoint)
+{
+       struct urb *current_urb = NULL;
+       int space;
+
+       /* If there's a queue, then we should add to the last urb */
+       if (!endpoint->tx_queue) {
+               current_urb = endpoint->tx_urb;
+       } else {
+               /* Last urb from tx chain */
+               current_urb =
+                       p2surround (struct urb, link, endpoint->tx.prev);
+       }
+
+       /* Make sure this one has enough room */
+       space = current_urb->buffer_length - current_urb->actual_length;
+       if (space > 0) {
+               return current_urb;
+       } else {                /* No space here */
+               /* First look at done list */
+               current_urb = first_urb_detached (&endpoint->done);
+               if (!current_urb) {
+                       current_urb = usbd_alloc_urb (device, endpoint);
+               }
+
+               urb_append (&endpoint->tx, current_urb);
+               endpoint->tx_queue++;
+       }
+       return current_urb;
+}
+
+static int write_buffer (circbuf_t * buf)
+{
+       if (!usbtty_configured ()) {
+               return 0;
+       }
+
+       struct usb_endpoint_instance *endpoint =
+                       &endpoint_instance[tx_endpoint];
+       struct urb *current_urb = NULL;
+
+       current_urb = next_urb (device_instance, endpoint);
+       /* TX data still exists - send it now
+        */
+       if(endpoint->sent < current_urb->actual_length){
+               if(udc_endpoint_write (endpoint)){
+                       /* Write pre-empted by RX */
+                       return -1;
+               }
+       }
+
+       if (buf->size) {
+               char *dest;
+
+               int space_avail;
+               int popnum, popped;
+               int total = 0;
+
+               /* Break buffer into urb sized pieces,
+                * and link each to the endpoint
+                */
+               while (buf->size > 0) {
+
+                       if (!current_urb) {
+                               TTYERR ("current_urb is NULL, buf->size %d\n",
+                                       buf->size);
+                               return total;
+                       }
+
+                       dest = (char*)current_urb->buffer +
+                               current_urb->actual_length;
+
+                       space_avail =
+                               current_urb->buffer_length -
+                               current_urb->actual_length;
+                       popnum = MIN (space_avail, buf->size);
+                       if (popnum == 0)
+                               break;
+
+                       popped = buf_pop (buf, dest, popnum);
+                       if (popped == 0)
+                               break;
+                       current_urb->actual_length += popped;
+                       total += popped;
+
+                       /* If endpoint->last == 0, then transfers have
+                        * not started on this endpoint
+                        */
+                       if (endpoint->last == 0) {
+                               if(udc_endpoint_write (endpoint)){
+                                       /* Write pre-empted by RX */
+                                       return -1;
+                               }
+                       }
+
+               }/* end while */
+               return total;
+       }
+
+       return 0;
+}
+
+static int fill_buffer (circbuf_t * buf)
+{
+       struct usb_endpoint_instance *endpoint =
+               &endpoint_instance[rx_endpoint];
+
+       if (endpoint->rcv_urb && endpoint->rcv_urb->actual_length) {
+               unsigned int nb = 0;
+               char *src = (char *) endpoint->rcv_urb->buffer;
+               unsigned int rx_avail = buf->totalsize - buf->size;
+
+               if(rx_avail >= endpoint->rcv_urb->actual_length){
+
+                       nb = endpoint->rcv_urb->actual_length;
+                       buf_push (buf, src, nb);
+                       endpoint->rcv_urb->actual_length = 0;
+
+               }
+               return nb;
+       }
+       return 0;
+}
+
+static int usbtty_configured (void)
+{
+       return usbtty_configured_flag;
+}
+
+/******************************************************************************/
+
+static void usbtty_event_handler (struct usb_device_instance *device,
+                                 usb_device_event_t event, int data)
+{
+       switch (event) {
+       case DEVICE_RESET:
+       case DEVICE_BUS_INACTIVE:
+               usbtty_configured_flag = 0;
+               break;
+       case DEVICE_CONFIGURED:
+               usbtty_configured_flag = 1;
+               break;
+
+       case DEVICE_ADDRESS_ASSIGNED:
+               usbtty_init_endpoints ();
+
+       default:
+               break;
+       }
+}
+
+/******************************************************************************/
+
+int usbtty_cdc_setup(struct usb_device_request *request, struct urb *urb)
+{
+       switch (request->bRequest){
+
+               case ACM_SET_CONTROL_LINE_STATE:        /* Implies DTE ready */
+                       break;
+               case ACM_SEND_ENCAPSULATED_COMMAND :    /* Required */
+                       break;
+               case ACM_SET_LINE_ENCODING :            /* DTE stop/parity bits
+                                                        * per character */
+                       break;
+               case ACM_GET_ENCAPSULATED_RESPONSE :    /* request response */
+                       break;
+               case ACM_GET_LINE_ENCODING :            /* request DTE rate,
+                                                        * stop/parity bits */
+                       memcpy (urb->buffer , &rs232_desc, sizeof(rs232_desc));
+                       urb->actual_length = sizeof(rs232_desc);
+
+                       break;
+               default:
+                       return 1;
+       }
+       return 0;
+}
+
+/******************************************************************************/
+
+/*
+ * Since interrupt handling has not yet been implemented, we use this function
+ * to handle polling.  This is called by the tstc,getc,putc,puts routines to
+ * update the USB state.
+ */
+void usbtty_poll (void)
+{
+       /* New interrupts? */
+       udc_irq();
+
+       /* Write any output data to host buffer
+        * (do this before checking interrupts to avoid missing one)
+        */
+       if (usbtty_configured ()) {
+               write_buffer (&usbtty_output);
+       }
+
+       /* New interrupts? */
+       udc_irq();
+
+       /* Check for new data from host..
+        * (do this after checking interrupts to get latest data)
+        */
+       if (usbtty_configured ()) {
+               fill_buffer (&usbtty_input);
+       }
+
+       /* New interrupts? */
+       udc_irq();
+
+}
+
+
+#endif
diff --git a/drivers/serial/usbtty.h b/drivers/serial/usbtty.h
new file mode 100644 (file)
index 0000000..8154e30
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * (C) Copyright 2003
+ * Gerry Hamel, geh@ti.com, Texas Instruments
+ *
+ * (C) Copyright 2006
+ * Bryan O'Donoghue, bodonoghue@codehermit.ie, CodeHermit
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307         USA
+ *
+ */
+
+#ifndef __USB_TTY_H__
+#define __USB_TTY_H__
+
+#include "usbdcore.h"
+#if defined(CONFIG_PPC)
+#include "usbdcore_mpc8xx.h"
+#elif defined(CONFIG_ARM)
+#include "usbdcore_omap1510.h"
+#endif
+
+#include <version_autogenerated.h>
+
+/* If no VendorID/ProductID is defined in config.h, pretend to be Linux
+ * DO NOT Reuse this Vendor/Product setup with protocol incompatible devices */
+
+#define CONFIG_USBD_VENDORID 0x0525    /* Linux/NetChip */
+#define CONFIG_USBD_PRODUCTID_GSERIAL 0xa4a6   /* gserial */
+#define CONFIG_USBD_PRODUCTID_CDCACM  0xa4a7   /* CDC ACM */
+#define CONFIG_USBD_MANUFACTURER "Das U-Boot"
+#define CONFIG_USBD_PRODUCT_NAME U_BOOT_VERSION
+
+
+#define CONFIG_USBD_CONFIGURATION_STR "TTY via USB"
+
+#define CONFIG_USBD_SERIAL_OUT_ENDPOINT UDC_OUT_ENDPOINT
+#define CONFIG_USBD_SERIAL_OUT_PKTSIZE UDC_OUT_PACKET_SIZE
+#define CONFIG_USBD_SERIAL_IN_ENDPOINT UDC_IN_ENDPOINT
+#define CONFIG_USBD_SERIAL_IN_PKTSIZE  UDC_IN_PACKET_SIZE
+#define CONFIG_USBD_SERIAL_INT_ENDPOINT UDC_INT_ENDPOINT
+#define CONFIG_USBD_SERIAL_INT_PKTSIZE UDC_INT_PACKET_SIZE
+#define CONFIG_USBD_SERIAL_BULK_PKTSIZE        UDC_BULK_PACKET_SIZE
+
+#define USBTTY_DEVICE_CLASS    COMMUNICATIONS_DEVICE_CLASS
+
+#define USBTTY_BCD_DEVICE      0x00
+#define USBTTY_MAXPOWER                0x00
+
+#define STR_LANG               0x00
+#define STR_MANUFACTURER       0x01
+#define STR_PRODUCT            0x02
+#define STR_SERIAL             0x03
+#define STR_CONFIG             0x04
+#define STR_DATA_INTERFACE     0x05
+#define STR_CTRL_INTERFACE     0x06
+#define STR_COUNT              0x07
+
+#endif
diff --git a/drivers/serial_max3100.c b/drivers/serial_max3100.c
deleted file mode 100644 (file)
index 35c5596..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * (C) Copyright 2003
- *
- * Pantelis Antoniou <panto@intracom.gr>
- * Intracom S.A.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <watchdog.h>
-
-#ifdef CONFIG_MAX3100_SERIAL
-
-DECLARE_GLOBAL_DATA_PTR;
-
-/**************************************************************/
-
-/* convienient macros */
-#define MAX3100_SPI_RXD() (MAX3100_SPI_RXD_PORT & MAX3100_SPI_RXD_BIT)
-
-#define MAX3100_SPI_TXD(x) \
-       do { \
-               if (x) \
-                       MAX3100_SPI_TXD_PORT |=  MAX3100_SPI_TXD_BIT; \
-               else \
-                       MAX3100_SPI_TXD_PORT &= ~MAX3100_SPI_TXD_BIT; \
-       } while(0)
-
-#define MAX3100_SPI_CLK(x) \
-       do { \
-               if (x) \
-                       MAX3100_SPI_CLK_PORT |=  MAX3100_SPI_CLK_BIT; \
-               else \
-                       MAX3100_SPI_CLK_PORT &= ~MAX3100_SPI_CLK_BIT; \
-       } while(0)
-
-#define MAX3100_SPI_CLK_TOGGLE() (MAX3100_SPI_CLK_PORT ^= MAX3100_SPI_CLK_BIT)
-
-#define MAX3100_CS(x) \
-       do { \
-               if (x) \
-                       MAX3100_CS_PORT |=  MAX3100_CS_BIT; \
-               else \
-                       MAX3100_CS_PORT &= ~MAX3100_CS_BIT; \
-       } while(0)
-
-/**************************************************************/
-
-/* MAX3100 definitions */
-
-#define MAX3100_WC     (3 << 14)               /* write configuration */
-#define MAX3100_RC     (1 << 14)               /* read  configuration */
-#define MAX3100_WD     (2 << 14)               /* write data          */
-#define MAX3100_RD     (0 << 14)               /* read  data          */
-
-/* configuration register bits */
-#define MAX3100_FEN    (1 << 13)               /* FIFO enable           */
-#define MAX3100_SHDN    (1 << 12)              /* shutdown bit          */
-#define MAX3100_TM     (1 << 11)               /* T bit irq mask        */
-#define MAX3100_RM     (1 << 10)               /* R bit irq mask        */
-#define MAX3100_PM     (1 <<  9)               /* P bit irq mask        */
-#define MAX3100_RAM    (1 <<  8)               /* mask for RA/FE bit    */
-#define MAX3100_IR     (1 <<  7)               /* IRDA timing mode      */
-#define MAX3100_ST     (1 <<  6)               /* transmit stop bit     */
-#define MAX3100_PE     (1 <<  5)               /* parity enable bit     */
-#define MAX3100_L      (1 <<  4)               /* Length bit            */
-#define MAX3100_B_MASK (0x000F)                /* baud rate bits mask   */
-#define MAX3100_B(x)   ((x) & 0x000F)  /* baud rate select bits */
-
-/* data register bits (write) */
-#define MAX3100_TE     (1 << 10)               /* transmit enable bit (active low)        */
-#define MAX3100_RTS    (1 <<  9)               /* request-to-send bit (inverted ~RTS pin) */
-
-/* data register bits (read) */
-#define MAX3100_RA     (1 << 10)               /* receiver activity when in shutdown mode */
-#define MAX3100_FE     (1 << 10)               /* framing error when in normal mode       */
-#define MAX3100_CTS    (1 <<  9)               /* clear-to-send bit (inverted ~CTS pin)   */
-
-/* data register bits (both directions) */
-#define MAX3100_R      (1 << 15)               /* receive bit    */
-#define MAX3100_T      (1 << 14)               /* transmit bit   */
-#define MAX3100_P      (1 <<  8)               /* parity bit     */
-#define MAX3100_D_MASK 0x00FF                  /* data bits mask */
-#define MAX3100_D(x)   ((x) & 0x00FF)          /* data bits      */
-
-/* these definitions are valid only for fOSC = 3.6864MHz */
-#define MAX3100_B_230400        MAX3100_B(0)
-#define MAX3100_B_115200        MAX3100_B(1)
-#define MAX3100_B_57600         MAX3100_B(2)
-#define MAX3100_B_38400         MAX3100_B(9)
-#define MAX3100_B_19200         MAX3100_B(10)
-#define MAX3100_B_9600          MAX3100_B(11)
-#define MAX3100_B_4800          MAX3100_B(12)
-#define MAX3100_B_2400          MAX3100_B(13)
-#define MAX3100_B_1200          MAX3100_B(14)
-#define MAX3100_B_600           MAX3100_B(15)
-
-/**************************************************************/
-
-static inline unsigned int max3100_transfer(unsigned int val)
-{
-       unsigned int rx;
-       int b;
-
-       MAX3100_SPI_CLK(0);
-       MAX3100_CS(0);
-
-       rx = 0; b = 16;
-       while (--b >= 0) {
-               MAX3100_SPI_TXD(val & 0x8000);
-               val <<= 1;
-               MAX3100_SPI_CLK_TOGGLE();
-               udelay(1);
-               rx <<= 1;
-               if (MAX3100_SPI_RXD())
-                       rx |= 1;
-               MAX3100_SPI_CLK_TOGGLE();
-               udelay(1);
-       }
-
-       MAX3100_SPI_CLK(1);
-       MAX3100_CS(1);
-
-       return rx;
-}
-
-/**************************************************************/
-
-/* must be power of 2 */
-#define RXFIFO_SZ      16
-
-static int rxfifo_cnt;
-static int rxfifo_in;
-static int rxfifo_out;
-static unsigned char rxfifo_buf[16];
-
-static void max3100_putc(int c)
-{
-       unsigned int rx;
-
-       while (((rx = max3100_transfer(MAX3100_RC)) & MAX3100_T) == 0)
-               WATCHDOG_RESET();
-
-       rx = max3100_transfer(MAX3100_WD | (c & 0xff));
-       if ((rx & MAX3100_RD) != 0 && rxfifo_cnt < RXFIFO_SZ) {
-               rxfifo_cnt++;
-               rxfifo_buf[rxfifo_in++] = rx & 0xff;
-               rxfifo_in &= RXFIFO_SZ - 1;
-       }
-}
-
-static int max3100_getc(void)
-{
-       int c;
-       unsigned int rx;
-
-       while (rxfifo_cnt == 0) {
-               rx = max3100_transfer(MAX3100_RD);
-               if ((rx & MAX3100_R) != 0) {
-                       do {
-                               rxfifo_cnt++;
-                               rxfifo_buf[rxfifo_in++] = rx & 0xff;
-                               rxfifo_in &= RXFIFO_SZ - 1;
-
-                               if (rxfifo_cnt >= RXFIFO_SZ)
-                                       break;
-                       } while (((rx = max3100_transfer(MAX3100_RD)) & MAX3100_R) != 0);
-               }
-               WATCHDOG_RESET();
-       }
-
-       rxfifo_cnt--;
-       c = rxfifo_buf[rxfifo_out++];
-       rxfifo_out &= RXFIFO_SZ - 1;
-       return c;
-}
-
-static int max3100_tstc(void)
-{
-       unsigned int rx;
-
-       if (rxfifo_cnt > 0)
-               return 1;
-
-       rx = max3100_transfer(MAX3100_RD);
-       if ((rx & MAX3100_R) == 0)
-               return 0;
-
-       do {
-               rxfifo_cnt++;
-               rxfifo_buf[rxfifo_in++] = rx & 0xff;
-               rxfifo_in &= RXFIFO_SZ - 1;
-
-               if (rxfifo_cnt >= RXFIFO_SZ)
-                       break;
-       } while (((rx = max3100_transfer(MAX3100_RD)) & MAX3100_R) != 0);
-
-       return 1;
-}
-
-int serial_init(void)
-{
-       unsigned int wconf, rconf;
-       int i;
-
-       wconf = 0;
-
-       /* Set baud rate */
-       switch (gd->baudrate) {
-               case 1200:
-                       wconf = MAX3100_B_1200;
-                       break;
-               case 2400:
-                       wconf = MAX3100_B_2400;
-                       break;
-               case 4800:
-                       wconf = MAX3100_B_4800;
-                       break;
-               case 9600:
-                       wconf = MAX3100_B_9600;
-                       break;
-               case 19200:
-                       wconf = MAX3100_B_19200;
-                       break;
-               case 38400:
-                       wconf = MAX3100_B_38400;
-                       break;
-               case 57600:
-                       wconf = MAX3100_B_57600;
-                       break;
-               default:
-               case 115200:
-                       wconf = MAX3100_B_115200;
-                       break;
-               case 230400:
-                       wconf = MAX3100_B_230400;
-                       break;
-       }
-
-       /* try for 10ms, with a 100us gap */
-       for (i = 0; i < 10000; i += 100) {
-
-               max3100_transfer(MAX3100_WC | wconf);
-               rconf = max3100_transfer(MAX3100_RC) & 0x3fff;
-
-               if (rconf == wconf)
-                       break;
-               udelay(100);
-       }
-
-       rxfifo_in = rxfifo_out = rxfifo_cnt = 0;
-
-       return (0);
-}
-
-void serial_putc(const char c)
-{
-       if (c == '\n')
-               max3100_putc('\r');
-
-       max3100_putc(c);
-}
-
-void serial_puts(const char *s)
-{
-       while (*s)
-               serial_putc (*s++);
-}
-
-int serial_getc(void)
-{
-       return max3100_getc();
-}
-
-int serial_tstc(void)
-{
-       return max3100_tstc();
-}
-
-/* XXX WTF? */
-void serial_setbrg(void)
-{
-}
-
-#endif
diff --git a/drivers/serial_pl010.c b/drivers/serial_pl010.c
deleted file mode 100644 (file)
index 417b6ae..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * (C) Copyright 2000
- * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
- *
- * (C) Copyright 2004
- * ARM Ltd.
- * Philippe Robin, <philippe.robin@arm.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/* Simple U-Boot driver for the PrimeCell PL011 UARTs on the IntegratorCP */
-/* Should be fairly simple to make it work with the PL010 as well */
-
-#include <common.h>
-
-#ifdef CFG_PL010_SERIAL
-
-#include "serial_pl011.h"
-
-#define IO_WRITE(addr, val) (*(volatile unsigned int *)(addr) = (val))
-#define IO_READ(addr) (*(volatile unsigned int *)(addr))
-
-/* Integrator AP has two UARTs, we use the first one, at 38400-8-N-1 */
-#define CONSOLE_PORT CONFIG_CONS_INDEX
-#define baudRate CONFIG_BAUDRATE
-static volatile unsigned char *const port[] = CONFIG_PL01x_PORTS;
-#define NUM_PORTS (sizeof(port)/sizeof(port[0]))
-
-
-static void pl010_putc (int portnum, char c);
-static int pl010_getc (int portnum);
-static int pl010_tstc (int portnum);
-
-
-int serial_init (void)
-{
-       unsigned int divisor;
-
-       /*
-        ** First, disable everything.
-        */
-       IO_WRITE (port[CONSOLE_PORT] + UART_PL010_CR, 0x0);
-
-       /*
-        ** Set baud rate
-        **
-        */
-       switch (baudRate) {
-       case 9600:
-               divisor = UART_PL010_BAUD_9600;
-               break;
-
-       case 19200:
-               divisor = UART_PL010_BAUD_9600;
-               break;
-
-       case 38400:
-               divisor = UART_PL010_BAUD_38400;
-               break;
-
-       case 57600:
-               divisor = UART_PL010_BAUD_57600;
-               break;
-
-       case 115200:
-               divisor = UART_PL010_BAUD_115200;
-               break;
-
-       default:
-               divisor = UART_PL010_BAUD_38400;
-       }
-
-       IO_WRITE (port[CONSOLE_PORT] + UART_PL010_LCRM,
-                 ((divisor & 0xf00) >> 8));
-       IO_WRITE (port[CONSOLE_PORT] + UART_PL010_LCRL, (divisor & 0xff));
-
-       /*
-        ** Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled.
-        */
-       IO_WRITE (port[CONSOLE_PORT] + UART_PL010_LCRH,
-                 (UART_PL010_LCRH_WLEN_8 | UART_PL010_LCRH_FEN));
-
-       /*
-        ** Finally, enable the UART
-        */
-       IO_WRITE (port[CONSOLE_PORT] + UART_PL010_CR, (UART_PL010_CR_UARTEN));
-
-       return (0);
-}
-
-void serial_putc (const char c)
-{
-       if (c == '\n')
-               pl010_putc (CONSOLE_PORT, '\r');
-
-       pl010_putc (CONSOLE_PORT, c);
-}
-
-void serial_puts (const char *s)
-{
-       while (*s) {
-               serial_putc (*s++);
-       }
-}
-
-int serial_getc (void)
-{
-       return pl010_getc (CONSOLE_PORT);
-}
-
-int serial_tstc (void)
-{
-       return pl010_tstc (CONSOLE_PORT);
-}
-
-void serial_setbrg (void)
-{
-}
-
-static void pl010_putc (int portnum, char c)
-{
-       /* Wait until there is space in the FIFO */
-       while (IO_READ (port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_TXFF);
-
-       /* Send the character */
-       IO_WRITE (port[portnum] + UART_PL01x_DR, c);
-}
-
-static int pl010_getc (int portnum)
-{
-       unsigned int data;
-
-       /* Wait until there is data in the FIFO */
-       while (IO_READ (port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_RXFE);
-
-       data = IO_READ (port[portnum] + UART_PL01x_DR);
-
-       /* Check for an error flag */
-       if (data & 0xFFFFFF00) {
-               /* Clear the error */
-               IO_WRITE (port[portnum] + UART_PL01x_ECR, 0xFFFFFFFF);
-               return -1;
-       }
-
-       return (int) data;
-}
-
-static int pl010_tstc (int portnum)
-{
-       return !(IO_READ (port[portnum] + UART_PL01x_FR) &
-                UART_PL01x_FR_RXFE);
-}
-
-#endif
diff --git a/drivers/serial_pl011.c b/drivers/serial_pl011.c
deleted file mode 100644 (file)
index 4d35fe5..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * (C) Copyright 2000
- * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
- *
- * (C) Copyright 2004
- * ARM Ltd.
- * Philippe Robin, <philippe.robin@arm.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/* Simple U-Boot driver for the PrimeCell PL011 UARTs on the IntegratorCP */
-/* Should be fairly simple to make it work with the PL010 as well */
-
-#include <common.h>
-
-#ifdef CFG_PL011_SERIAL
-
-#include "serial_pl011.h"
-
-#define IO_WRITE(addr, val) (*(volatile unsigned int *)(addr) = (val))
-#define IO_READ(addr) (*(volatile unsigned int *)(addr))
-
-/*
- * IntegratorCP has two UARTs, use the first one, at 38400-8-N-1
- * Versatile PB has four UARTs.
- */
-
-#define CONSOLE_PORT CONFIG_CONS_INDEX
-#define baudRate CONFIG_BAUDRATE
-static volatile unsigned char *const port[] = CONFIG_PL01x_PORTS;
-#define NUM_PORTS (sizeof(port)/sizeof(port[0]))
-
-static void pl011_putc (int portnum, char c);
-static int pl011_getc (int portnum);
-static int pl011_tstc (int portnum);
-
-
-int serial_init (void)
-{
-       unsigned int temp;
-       unsigned int divider;
-       unsigned int remainder;
-       unsigned int fraction;
-
-       /*
-        ** First, disable everything.
-        */
-       IO_WRITE (port[CONSOLE_PORT] + UART_PL011_CR, 0x0);
-
-       /*
-        ** Set baud rate
-        **
-        ** IBRD = UART_CLK / (16 * BAUD_RATE)
-        ** FBRD = ROUND((64 * MOD(UART_CLK,(16 * BAUD_RATE))) / (16 * BAUD_RATE))
-        */
-       temp = 16 * baudRate;
-       divider = CONFIG_PL011_CLOCK / temp;
-       remainder = CONFIG_PL011_CLOCK % temp;
-       temp = (8 * remainder) / baudRate;
-       fraction = (temp >> 1) + (temp & 1);
-
-       IO_WRITE (port[CONSOLE_PORT] + UART_PL011_IBRD, divider);
-       IO_WRITE (port[CONSOLE_PORT] + UART_PL011_FBRD, fraction);
-
-       /*
-        ** Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled.
-        */
-       IO_WRITE (port[CONSOLE_PORT] + UART_PL011_LCRH,
-                 (UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN));
-
-       /*
-        ** Finally, enable the UART
-        */
-       IO_WRITE (port[CONSOLE_PORT] + UART_PL011_CR,
-                 (UART_PL011_CR_UARTEN | UART_PL011_CR_TXE |
-                  UART_PL011_CR_RXE));
-
-       return 0;
-}
-
-void serial_putc (const char c)
-{
-       if (c == '\n')
-               pl011_putc (CONSOLE_PORT, '\r');
-
-       pl011_putc (CONSOLE_PORT, c);
-}
-
-void serial_puts (const char *s)
-{
-       while (*s) {
-               serial_putc (*s++);
-       }
-}
-
-int serial_getc (void)
-{
-       return pl011_getc (CONSOLE_PORT);
-}
-
-int serial_tstc (void)
-{
-       return pl011_tstc (CONSOLE_PORT);
-}
-
-void serial_setbrg (void)
-{
-}
-
-static void pl011_putc (int portnum, char c)
-{
-       /* Wait until there is space in the FIFO */
-       while (IO_READ (port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_TXFF);
-
-       /* Send the character */
-       IO_WRITE (port[portnum] + UART_PL01x_DR, c);
-}
-
-static int pl011_getc (int portnum)
-{
-       unsigned int data;
-
-       /* Wait until there is data in the FIFO */
-       while (IO_READ (port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_RXFE);
-
-       data = IO_READ (port[portnum] + UART_PL01x_DR);
-
-       /* Check for an error flag */
-       if (data & 0xFFFFFF00) {
-               /* Clear the error */
-               IO_WRITE (port[portnum] + UART_PL01x_ECR, 0xFFFFFFFF);
-               return -1;
-       }
-
-       return (int) data;
-}
-
-static int pl011_tstc (int portnum)
-{
-       return !(IO_READ (port[portnum] + UART_PL01x_FR) &
-                UART_PL01x_FR_RXFE);
-}
-
-#endif
diff --git a/drivers/serial_pl011.h b/drivers/serial_pl011.h
deleted file mode 100644 (file)
index 5f20fdd..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * (C) Copyright 2003, 2004
- * ARM Ltd.
- * Philippe Robin, <philippe.robin@arm.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * ARM PrimeCell UART's (PL010 & PL011)
- * ------------------------------------
- *
- *  Definitions common to both PL010 & PL011
- *
- */
-#define UART_PL01x_DR                   0x00    /*  Data read or written from the interface. */
-#define UART_PL01x_RSR                  0x04    /*  Receive status register (Read). */
-#define UART_PL01x_ECR                  0x04    /*  Error clear register (Write). */
-#define UART_PL01x_FR                   0x18    /*  Flag register (Read only). */
-
-#define UART_PL01x_RSR_OE               0x08
-#define UART_PL01x_RSR_BE               0x04
-#define UART_PL01x_RSR_PE               0x02
-#define UART_PL01x_RSR_FE               0x01
-
-#define UART_PL01x_FR_TXFE              0x80
-#define UART_PL01x_FR_RXFF              0x40
-#define UART_PL01x_FR_TXFF              0x20
-#define UART_PL01x_FR_RXFE              0x10
-#define UART_PL01x_FR_BUSY              0x08
-#define UART_PL01x_FR_TMSK              (UART_PL01x_FR_TXFF + UART_PL01x_FR_BUSY)
-
-/*
- *  PL010 definitions
- *
- */
-#define UART_PL010_LCRH                 0x08    /*  Line control register, high byte. */
-#define UART_PL010_LCRM                 0x0C    /*  Line control register, middle byte. */
-#define UART_PL010_LCRL                 0x10    /*  Line control register, low byte. */
-#define UART_PL010_CR                   0x14    /*  Control register. */
-#define UART_PL010_IIR                  0x1C    /*  Interrupt indentification register (Read). */
-#define UART_PL010_ICR                  0x1C    /*  Interrupt clear register (Write). */
-#define UART_PL010_ILPR                 0x20    /*  IrDA low power counter register. */
-
-#define UART_PL010_CR_LPE               (1 << 7)
-#define UART_PL010_CR_RTIE              (1 << 6)
-#define UART_PL010_CR_TIE               (1 << 5)
-#define UART_PL010_CR_RIE               (1 << 4)
-#define UART_PL010_CR_MSIE              (1 << 3)
-#define UART_PL010_CR_IIRLP             (1 << 2)
-#define UART_PL010_CR_SIREN             (1 << 1)
-#define UART_PL010_CR_UARTEN            (1 << 0)
-
-#define UART_PL010_LCRH_WLEN_8          (3 << 5)
-#define UART_PL010_LCRH_WLEN_7          (2 << 5)
-#define UART_PL010_LCRH_WLEN_6          (1 << 5)
-#define UART_PL010_LCRH_WLEN_5          (0 << 5)
-#define UART_PL010_LCRH_FEN             (1 << 4)
-#define UART_PL010_LCRH_STP2            (1 << 3)
-#define UART_PL010_LCRH_EPS             (1 << 2)
-#define UART_PL010_LCRH_PEN             (1 << 1)
-#define UART_PL010_LCRH_BRK             (1 << 0)
-
-
-#define UART_PL010_BAUD_460800            1
-#define UART_PL010_BAUD_230400            3
-#define UART_PL010_BAUD_115200            7
-#define UART_PL010_BAUD_57600             15
-#define UART_PL010_BAUD_38400             23
-#define UART_PL010_BAUD_19200             47
-#define UART_PL010_BAUD_14400             63
-#define UART_PL010_BAUD_9600              95
-#define UART_PL010_BAUD_4800              191
-#define UART_PL010_BAUD_2400              383
-#define UART_PL010_BAUD_1200              767
-/*
- *  PL011 definitions
- *
- */
-#define UART_PL011_IBRD                 0x24
-#define UART_PL011_FBRD                 0x28
-#define UART_PL011_LCRH                 0x2C
-#define UART_PL011_CR                   0x30
-#define UART_PL011_IMSC                 0x38
-#define UART_PL011_PERIPH_ID0           0xFE0
-
-#define UART_PL011_LCRH_SPS             (1 << 7)
-#define UART_PL011_LCRH_WLEN_8          (3 << 5)
-#define UART_PL011_LCRH_WLEN_7          (2 << 5)
-#define UART_PL011_LCRH_WLEN_6          (1 << 5)
-#define UART_PL011_LCRH_WLEN_5          (0 << 5)
-#define UART_PL011_LCRH_FEN             (1 << 4)
-#define UART_PL011_LCRH_STP2            (1 << 3)
-#define UART_PL011_LCRH_EPS             (1 << 2)
-#define UART_PL011_LCRH_PEN             (1 << 1)
-#define UART_PL011_LCRH_BRK             (1 << 0)
-
-#define UART_PL011_CR_CTSEN             (1 << 15)
-#define UART_PL011_CR_RTSEN             (1 << 14)
-#define UART_PL011_CR_OUT2              (1 << 13)
-#define UART_PL011_CR_OUT1              (1 << 12)
-#define UART_PL011_CR_RTS               (1 << 11)
-#define UART_PL011_CR_DTR               (1 << 10)
-#define UART_PL011_CR_RXE               (1 << 9)
-#define UART_PL011_CR_TXE               (1 << 8)
-#define UART_PL011_CR_LPE               (1 << 7)
-#define UART_PL011_CR_IIRLP             (1 << 2)
-#define UART_PL011_CR_SIREN             (1 << 1)
-#define UART_PL011_CR_UARTEN            (1 << 0)
-
-#define UART_PL011_IMSC_OEIM            (1 << 10)
-#define UART_PL011_IMSC_BEIM            (1 << 9)
-#define UART_PL011_IMSC_PEIM            (1 << 8)
-#define UART_PL011_IMSC_FEIM            (1 << 7)
-#define UART_PL011_IMSC_RTIM            (1 << 6)
-#define UART_PL011_IMSC_TXIM            (1 << 5)
-#define UART_PL011_IMSC_RXIM            (1 << 4)
-#define UART_PL011_IMSC_DSRMIM          (1 << 3)
-#define UART_PL011_IMSC_DCDMIM          (1 << 2)
-#define UART_PL011_IMSC_CTSMIM          (1 << 1)
-#define UART_PL011_IMSC_RIMIM           (1 << 0)
diff --git a/drivers/serial_xuartlite.c b/drivers/serial_xuartlite.c
deleted file mode 100644 (file)
index d678ab6..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * (C) Copyright 2004 Atmark Techno, Inc.
- *
- * Yasushi SHOJI <yashi@atmark-techno.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <config.h>
-
-#ifdef CONFIG_XILINX_UARTLITE
-
-#include <asm/serial_xuartlite.h>
-
-/* FIXME: we should convert these to in32 and out32 */
-#define IO_WORD(offset)             (*(volatile unsigned long *)(offset))
-#define IO_SERIAL(offset)    IO_WORD(CONFIG_SERIAL_BASE + (offset))
-
-#define IO_SERIAL_RX_FIFO   IO_SERIAL(XUL_RX_FIFO_OFFSET)
-#define IO_SERIAL_TX_FIFO   IO_SERIAL(XUL_TX_FIFO_OFFSET)
-#define IO_SERIAL_STATUS    IO_SERIAL(XUL_STATUS_REG_OFFSET)
-#define IO_SERIAL_CONTROL   IO_SERIAL(XUL_CONTROL_REG_OFFSET)
-
-int serial_init(void)
-{
-       /* FIXME: Nothing for now. We should initialize fifo, etc */
-       return 0;
-}
-
-void serial_setbrg(void)
-{
-       /* FIXME: what's this for? */
-}
-
-void serial_putc(const char c)
-{
-       if (c == '\n') serial_putc('\r');
-       while (IO_SERIAL_STATUS & XUL_SR_TX_FIFO_FULL);
-       IO_SERIAL_TX_FIFO = (unsigned char) (c & 0xff);
-}
-
-void serial_puts(const char * s)
-{
-       while (*s) {
-               serial_putc(*s++);
-       }
-}
-
-int serial_getc(void)
-{
-       while (!(IO_SERIAL_STATUS & XUL_SR_RX_FIFO_VALID_DATA));
-       return IO_SERIAL_RX_FIFO & 0xff;
-}
-
-int serial_tstc(void)
-{
-       return (IO_SERIAL_STATUS & XUL_SR_RX_FIFO_VALID_DATA);
-}
-
-#endif /* CONFIG_MICROBLZE */
diff --git a/drivers/sil680.c b/drivers/sil680.c
deleted file mode 100644 (file)
index a6143df..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * (C) Copyright 2007
- * Gary Jennejohn, DENX Software Engineering, garyj@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- */
-/* sil680.c - ide support functions for the Sil0680A controller */
-
-/*
- * The following parameters must be defined in the configuration file
- * of the target board:
- *
- * #define CFG_IDE_SIL680
- *
- * #define CONFIG_PCI_PNP
- * NOTE it may also be necessary to define this if the default of 8 is
- * incorrect for the target board (e.g. the sequoia board requires 0).
- * #define CFG_PCI_CACHE_LINE_SIZE     0
- *
- * #define CONFIG_CMD_IDE
- * #undef  CONFIG_IDE_8xx_DIRECT
- * #undef  CONFIG_IDE_LED
- * #undef  CONFIG_IDE_RESET
- * #define CONFIG_IDE_PREINIT
- * #define CFG_IDE_MAXBUS              2 - modify to suit
- * #define CFG_IDE_MAXDEVICE   (CFG_IDE_MAXBUS*2) - modify to suit
- * #define CFG_ATA_BASE_ADDR   0
- * #define CFG_ATA_IDE0_OFFSET 0
- * #define CFG_ATA_IDE1_OFFSET 0
- * #define CFG_ATA_DATA_OFFSET 0
- * #define CFG_ATA_REG_OFFSET  0
- * #define CFG_ATA_ALT_OFFSET  0x0004
- *
- * The mapping for PCI IO-space.
- * NOTE this is the value for the sequoia board. Modify to suit.
- * #define CFG_PCI0_IO_SPACE   0xE8000000
- */
-
-#include <common.h>
-#if defined(CFG_IDE_SIL680)
-#include <ata.h>
-#include <ide.h>
-#include <pci.h>
-
-extern ulong ide_bus_offset[CFG_IDE_MAXBUS];
-
-int ide_preinit (void)
-{
-       int status;
-       pci_dev_t devbusfn;
-       int l;
-
-       status = 1;
-       for (l = 0; l < CFG_IDE_MAXBUS; l++) {
-               ide_bus_offset[l] = -ATA_STATUS;
-       }
-       devbusfn = pci_find_device (0x1095, 0x0680, 0);
-       if (devbusfn != -1) {
-               status = 0;
-
-               pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0,
-                                      (u32 *) &ide_bus_offset[0]);
-               ide_bus_offset[0] &= 0xfffffff8;
-               ide_bus_offset[0] += CFG_PCI0_IO_SPACE;
-               pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_2,
-                                      (u32 *) &ide_bus_offset[1]);
-               ide_bus_offset[1] &= 0xfffffff8;
-               ide_bus_offset[1] += CFG_PCI0_IO_SPACE;
-               /* init various things - taken from the Linux driver */
-               /* set PIO mode */
-               pci_write_config_byte(devbusfn, 0x80, 0x00);
-               pci_write_config_byte(devbusfn, 0x84, 0x00);
-               /* IDE0 */
-               pci_write_config_byte(devbusfn,  0xA1, 0x02);
-               pci_write_config_word(devbusfn,  0xA2, 0x328A);
-               pci_write_config_dword(devbusfn, 0xA4, 0x62DD62DD);
-               pci_write_config_dword(devbusfn, 0xA8, 0x43924392);
-               pci_write_config_dword(devbusfn, 0xAC, 0x40094009);
-               /* IDE1 */
-               pci_write_config_byte(devbusfn,  0xB1, 0x02);
-               pci_write_config_word(devbusfn,  0xB2, 0x328A);
-               pci_write_config_dword(devbusfn, 0xB4, 0x62DD62DD);
-               pci_write_config_dword(devbusfn, 0xB8, 0x43924392);
-               pci_write_config_dword(devbusfn, 0xBC, 0x40094009);
-       }
-       return (status);
-}
-
-void ide_set_reset (int flag) {
-       return;
-}
-
-#endif /* CFG_IDE_SIL680 */
diff --git a/drivers/sk98lin/Makefile b/drivers/sk98lin/Makefile
deleted file mode 100644 (file)
index 7e50b1d..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-#
-# (C) Copyright 2003-2006
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-#
-# See file CREDITS for list of people who contributed to this
-# project.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-# MA 02111-1307 USA
-#
-# File: drivers/sk98lin/Makefile
-#
-# Makefile for the SysKonnect SK-98xx device driver.
-#
-
-include $(TOPDIR)/config.mk
-
-LIB    := $(obj)libsk98lin.a
-
-COBJS  := skge.o skaddr.o skgehwt.o skgeinit.o skgepnmi.o skgesirq.o \
-               ski2c.o sklm80.o skqueue.o skrlmt.o sktimer.o skvpd.o \
-               skxmac2.o skcsum.o #skproc.o
-
-COBJS  += uboot_skb.o uboot_drv.o
-
-SRCS   := $(COBJS:.o=.c)
-OBJS   := $(addprefix $(obj),$(COBJS))
-
-# DBGDEF =  \
-# -DDEBUG
-
-ifdef DEBUG
-DBGDEF +=  \
--DSK_DEBUG_CHKMOD=0x00000000L \
--DSK_DEBUG_CHKCAT=0x00000000L
-endif
-
-
-# **** possible debug modules for SK_DEBUG_CHKMOD *****************
-# SK_DBGMOD_MERR        0x00000001L     /* general module error indication */
-# SK_DBGMOD_HWM         0x00000002L     /* Hardware init module */
-# SK_DBGMOD_RLMT        0x00000004L     /* RLMT module */
-# SK_DBGMOD_VPD         0x00000008L     /* VPD module */
-# SK_DBGMOD_I2C         0x00000010L     /* I2C module */
-# SK_DBGMOD_PNMI        0x00000020L     /* PNMI module */
-# SK_DBGMOD_CSUM        0x00000040L     /* CSUM module */
-# SK_DBGMOD_ADDR        0x00000080L     /* ADDR module */
-# SK_DBGMOD_DRV         0x00010000L     /* DRV module */
-
-# **** possible debug categories for SK_DEBUG_CHKCAT **************
-# *** common modules ***
-# SK_DBGCAT_INIT        0x00000001L     module/driver initialization
-# SK_DBGCAT_CTRL        0x00000002L     controlling: add/rmv MCA/MAC and other controls (IOCTL)
-# SK_DBGCAT_ERR         0x00000004L     error handling paths
-# SK_DBGCAT_TX          0x00000008L     transmit path
-# SK_DBGCAT_RX          0x00000010L     receive path
-# SK_DBGCAT_IRQ         0x00000020L     general IRQ handling
-# SK_DBGCAT_QUEUE       0x00000040L     any queue management
-# SK_DBGCAT_DUMP        0x00000080L     large data output e.g. hex dump
-# SK_DBGCAT_FATAL       0x00000100L     large data output e.g. hex dump
-
-# *** driver (file skge.c) ***
-# SK_DBGCAT_DRV_ENTRY           0x00010000      entry points
-# SK_DBGCAT_DRV_???             0x00020000      not used
-# SK_DBGCAT_DRV_MCA             0x00040000      multicast
-# SK_DBGCAT_DRV_TX_PROGRESS     0x00080000      tx path
-# SK_DBGCAT_DRV_RX_PROGRESS     0x00100000      rx path
-# SK_DBGCAT_DRV_PROGRESS        0x00200000      general runtime
-# SK_DBGCAT_DRV_???             0x00400000      not used
-# SK_DBGCAT_DRV_PROM            0x00800000      promiscuous mode
-# SK_DBGCAT_DRV_TX_FRAME        0x01000000      display tx frames
-# SK_DBGCAT_DRV_ERROR           0x02000000      error conditions
-# SK_DBGCAT_DRV_INT_SRC         0x04000000      interrupts sources
-# SK_DBGCAT_DRV_EVENT           0x08000000      driver events
-
-EXTRA_CFLAGS += -I. -DSK_USE_CSUM $(DBGDEF)
-
-CFLAGS += $(EXTRA_CFLAGS)
-HOST_CFLAGS += $(EXTRA_CFLAGS)
-
-
-all:   $(LIB)
-
-$(LIB):        $(obj).depend $(OBJS)
-       $(AR) $(ARFLAGS) $@ $(OBJS)
-
-#########################################################################
-
-# defines $(obj).depend target
-include $(SRCTREE)/rules.mk
-
-sinclude $(obj).depend
-
-#########################################################################
diff --git a/drivers/sk98lin/h/lm80.h b/drivers/sk98lin/h/lm80.h
deleted file mode 100644 (file)
index 981a4ca..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/******************************************************************************
- *
- * Name:       lm80.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.4 $
- * Date:       $Date: 2002/04/25 11:04:10 $
- * Purpose:    Contains all defines for the LM80 Chip
- *             (National Semiconductor).
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *     $Log: lm80.h,v $
- *     Revision 1.4  2002/04/25 11:04:10  rschmidt
- *     Editorial changes
- *
- *     Revision 1.3  1999/11/22 13:41:19  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.2  1999/03/12 13:26:51  malthoff
- *     remove __STDC__.
- *
- *     Revision 1.1  1998/06/19 09:28:31  malthoff
- *     created.
- *
- *
- ******************************************************************************/
-
-#ifndef __INC_LM80_H
-#define __INC_LM80_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* defines ********************************************************************/
-
-/*
- * LM80 register definition
- *
- * All registers are 8 bit wide
- */
-#define        LM80_CFG                        0x00    /* Configuration Register */
-#define        LM80_ISRC_1                     0x01    /* Interrupt Status Register 1 */
-#define LM80_ISRC_2                    0x02    /* Interrupt Status Register 2 */
-#define LM80_IMSK_1                    0x03    /* Interrupt Mask Register 1 */
-#define LM80_IMSK_2                    0x04    /* Interrupt Mask Register 2 */
-#define LM80_FAN_CTRL          0x05    /* Fan Devisor/RST#/OS# Register */
-#define LM80_TEMP_CTRL         0x06    /* OS# Config, Temp Res. Reg */
-       /* 0x07 - 0x1f reserved */
-       /* current values */
-#define LM80_VT0_IN                    0x20    /* current Voltage 0 value */
-#define LM80_VT1_IN                    0x21    /* current Voltage 1 value */
-#define LM80_VT2_IN                    0x22    /* current Voltage 2 value */
-#define LM80_VT3_IN                    0x23    /* current Voltage 3 value */
-#define LM80_VT4_IN                    0x24    /* current Voltage 4 value */
-#define LM80_VT5_IN                    0x25    /* current Voltage 5 value */
-#define LM80_VT6_IN                    0x26    /* current Voltage 6 value */
-#define LM80_TEMP_IN           0x27    /* current Temperature value */
-#define LM80_FAN1_IN           0x28    /* current Fan 1 count */
-#define LM80_FAN2_IN           0x29    /* current Fan 2 count */
-       /* limit values */
-#define LM80_VT0_HIGH_LIM      0x2a    /* high limit val for Voltage 0 */
-#define LM80_VT0_LOW_LIM       0x2b    /* low limit val for Voltage 0 */
-#define LM80_VT1_HIGH_LIM      0x2c    /* high limit val for Voltage 1 */
-#define LM80_VT1_LOW_LIM       0x2d    /* low limit val for Voltage 1 */
-#define LM80_VT2_HIGH_LIM      0x2e    /* high limit val for Voltage 2 */
-#define LM80_VT2_LOW_LIM       0x2f    /* low limit val for Voltage 2 */
-#define LM80_VT3_HIGH_LIM      0x30    /* high limit val for Voltage 3 */
-#define LM80_VT3_LOW_LIM       0x31    /* low limit val for Voltage 3 */
-#define LM80_VT4_HIGH_LIM      0x32    /* high limit val for Voltage 4 */
-#define LM80_VT4_LOW_LIM       0x33    /* low limit val for Voltage 4 */
-#define LM80_VT5_HIGH_LIM      0x34    /* high limit val for Voltage 5 */
-#define LM80_VT5_LOW_LIM       0x35    /* low limit val for Voltage 5 */
-#define LM80_VT6_HIGH_LIM      0x36    /* high limit val for Voltage 6 */
-#define LM80_VT6_LOW_LIM       0x37    /* low limit val for Voltage 6 */
-#define LM80_THOT_LIM_UP       0x38    /* hot temperature limit (high) */
-#define LM80_THOT_LIM_LO       0x39    /* hot temperature limit (low) */
-#define LM80_TOS_LIM_UP                0x3a    /* OS temperature limit (high) */
-#define LM80_TOS_LIM_LO                0x3b    /* OS temperature limit (low) */
-#define        LM80_FAN1_COUNT_LIM     0x3c    /* Fan 1 count limit (high) */
-#define        LM80_FAN2_COUNT_LIM     0x3d    /* Fan 2 count limit (low) */
-       /* 0x3e - 0x3f reserved */
-
-/*
- * LM80 bit definitions
- */
-
-/*     LM80_CFG                Configuration Register */
-#define LM80_CFG_START         (1<<0)  /* start monitoring operation */
-#define LM80_CFG_INT_ENA       (1<<1)  /* enables the INT# Interrupt output */
-#define LM80_CFG_INT_POL       (1<<2)  /* INT# pol: 0 act low, 1 act high */
-#define LM80_CFG_INT_CLR       (1<<3)  /* disables INT#/RST_OUT#/OS# outputs */
-#define LM80_CFG_RESET         (1<<4)  /* signals a reset */
-#define LM80_CFG_CHASS_CLR     (1<<5)  /* clears Chassis Intrusion (CI) pin */
-#define LM80_CFG_GPO           (1<<6)  /* drives the GPO# pin */
-#define LM80_CFG_INIT          (1<<7)  /* restore power on defaults */
-
-/*     LM80_ISRC_1             Interrupt Status Register 1 */
-/*     LM80_IMSK_1             Interrupt Mask Register 1 */
-#define LM80_IS_VT0                    (1<<0)  /* limit exceeded for Voltage 0 */
-#define LM80_IS_VT1                    (1<<1)  /* limit exceeded for Voltage 1 */
-#define LM80_IS_VT2                    (1<<2)  /* limit exceeded for Voltage 2 */
-#define LM80_IS_VT3                    (1<<3)  /* limit exceeded for Voltage 3 */
-#define LM80_IS_VT4                    (1<<4)  /* limit exceeded for Voltage 4 */
-#define LM80_IS_VT5                    (1<<5)  /* limit exceeded for Voltage 5 */
-#define LM80_IS_VT6                    (1<<6)  /* limit exceeded for Voltage 6 */
-#define LM80_IS_INT_IN         (1<<7)  /* state of INT_IN# */
-
-/*     LM80_ISRC_2             Interrupt Status Register 2 */
-/*     LM80_IMSK_2             Interrupt Mask Register 2 */
-#define        LM80_IS_TEMP            (1<<0)  /* HOT temperature limit exceeded */
-#define LM80_IS_BTI                    (1<<1)  /* state of BTI# pin */
-#define LM80_IS_FAN1           (1<<2)  /* count limit exceeded for Fan 1 */
-#define LM80_IS_FAN2           (1<<3)  /* count limit exceeded for Fan 2 */
-#define LM80_IS_CI                     (1<<4)  /* Chassis Intrusion occured */
-#define LM80_IS_OS                     (1<<5)  /* OS temperature limit exceeded */
-       /* bit 6 and 7 are reserved in LM80_ISRC_2 */
-#define LM80_IS_HT_IRQ_MD      (1<<6)  /* Hot temperature interrupt mode */
-#define LM80_IS_OT_IRQ_MD      (1<<7)  /* OS temperature interrupt mode */
-
-/*     LM80_FAN_CTRL           Fan Devisor/RST#/OS# Register */
-#define LM80_FAN1_MD_SEL       (1<<0)  /* Fan 1 mode select */
-#define LM80_FAN2_MD_SEL       (1<<1)  /* Fan 2 mode select */
-#define LM80_FAN1_PRM_CTL      (3<<2)  /* Fan 1 speed control */
-#define LM80_FAN2_PRM_CTL      (3<<4)  /* Fan 2 speed control */
-#define LM80_FAN_OS_ENA                (1<<6)  /* enable OS mode on RST_OUT#/OS# pins*/
-#define LM80_FAN_RST_ENA       (1<<7)  /* sets RST_OUT#/OS# pins in RST mode */
-
-/*     LM80_TEMP_CTRL          OS# Config, Temp Res. Reg */
-#define        LM80_TEMP_OS_STAT       (1<<0)  /* mirrors the state of RST_OUT#/OS# */
-#define LM80_TEMP_OS_POL       (1<<1)  /* select OS# polarity */
-#define LM80_TEMP_OS_MODE      (1<<2)  /* selects Interrupt mode */
-#define LM80_TEMP_RES          (1<<3)  /* selects 9 or 11 bit temp resulution*/
-#define LM80_TEMP_LSB          (0xf<<4)/* 4 LSBs of 11 bit temp data */
-#define LM80_TEMP_LSB_9                (1<<7)  /* LSB of 9 bit temperature data */
-
-       /* 0x07 - 0x1f reserved */
-/*     LM80_VT0_IN             current Voltage 0 value */
-/*     LM80_VT1_IN             current Voltage 1 value */
-/*     LM80_VT2_IN             current Voltage 2 value */
-/*     LM80_VT3_IN             current Voltage 3 value */
-/*     LM80_VT4_IN             current Voltage 4 value */
-/*     LM80_VT5_IN             current Voltage 5 value */
-/*     LM80_VT6_IN             current Voltage 6 value */
-/*     LM80_TEMP_IN            current temperature value */
-/*     LM80_FAN1_IN            current Fan 1 count */
-/*     LM80_FAN2_IN            current Fan 2 count */
-/*     LM80_VT0_HIGH_LIM       high limit val for Voltage 0 */
-/*     LM80_VT0_LOW_LIM        low limit val for Voltage 0 */
-/*     LM80_VT1_HIGH_LIM       high limit val for Voltage 1 */
-/*     LM80_VT1_LOW_LIM        low limit val for Voltage 1 */
-/*     LM80_VT2_HIGH_LIM       high limit val for Voltage 2 */
-/*     LM80_VT2_LOW_LIM        low limit val for Voltage 2 */
-/*     LM80_VT3_HIGH_LIM       high limit val for Voltage 3 */
-/*     LM80_VT3_LOW_LIM        low limit val for Voltage 3 */
-/*     LM80_VT4_HIGH_LIM       high limit val for Voltage 4 */
-/*     LM80_VT4_LOW_LIM        low limit val for Voltage 4 */
-/*     LM80_VT5_HIGH_LIM       high limit val for Voltage 5 */
-/*     LM80_VT5_LOW_LIM        low limit val for Voltage 5 */
-/*     LM80_VT6_HIGH_LIM       high limit val for Voltage 6 */
-/*     LM80_VT6_LOW_LIM        low limit val for Voltage 6 */
-/*     LM80_THOT_LIM_UP        hot temperature limit (high) */
-/*     LM80_THOT_LIM_LO        hot temperature limit (low) */
-/*     LM80_TOS_LIM_UP         OS temperature limit (high) */
-/*     LM80_TOS_LIM_LO         OS temperature limit (low) */
-/*     LM80_FAN1_COUNT_LIM     Fan 1 count limit (high) */
-/*     LM80_FAN2_COUNT_LIM     Fan 2 count limit (low) */
-       /* 0x3e - 0x3f reserved */
-
-#define LM80_ADDR              0x28    /* LM80 default addr */
-
-/* typedefs *******************************************************************/
-
-
-/* function prototypes ********************************************************/
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_LM80_H */
diff --git a/drivers/sk98lin/h/skaddr.h b/drivers/sk98lin/h/skaddr.h
deleted file mode 100644 (file)
index 711f873..0000000
+++ /dev/null
@@ -1,425 +0,0 @@
-/******************************************************************************
- *
- * Name:       skaddr.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.26 $
- * Date:       $Date: 2002/11/15 07:24:42 $
- * Purpose:    Header file for Address Management (MC, UC, Prom).
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2001 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skaddr.h,v $
- *     Revision 1.26  2002/11/15 07:24:42  tschilli
- *     SK_ADDR_EQUAL macro fixed.
- *
- *     Revision 1.25  2002/06/10 13:55:18  tschilli
- *     Changes for handling YUKON.
- *     All changes are internally and not visible to the programmer
- *     using this module.
- *
- *     Revision 1.24  2001/01/22 13:41:34  rassmann
- *     Supporting two nets on dual-port adapters.
- *
- *     Revision 1.23  2000/08/10 11:27:50  rassmann
- *     Editorial changes.
- *     Preserving 32-bit alignment in structs for the adapter context.
- *
- *     Revision 1.22  2000/08/07 11:10:40  rassmann
- *     Editorial changes.
- *
- *     Revision 1.21  2000/05/04 09:39:59  rassmann
- *     Editorial changes.
- *     Corrected multicast address hashing.
- *
- *     Revision 1.20  1999/11/22 13:46:14  cgoos
- *     Changed license header to GPL.
- *     Allowing overwrite for SK_ADDR_EQUAL.
- *
- *     Revision 1.19  1999/05/28 10:56:07  rassmann
- *     Editorial changes.
- *
- *     Revision 1.18  1999/04/06 17:22:04  rassmann
- *     Added private "ActivePort".
- *
- *     Revision 1.17  1999/01/14 16:18:19  rassmann
- *     Corrected multicast initialization.
- *
- *     Revision 1.16  1999/01/04 10:30:36  rassmann
- *     SkAddrOverride only possible after SK_INIT_IO phase.
- *
- *     Revision 1.15  1998/12/29 13:13:11  rassmann
- *     An address override is now preserved in the SK_INIT_IO phase.
- *     All functions return an int now.
- *     Extended parameter checking.
- *
- *     Revision 1.14  1998/11/24 12:39:45  rassmann
- *     Reserved multicast entry for BPDU address.
- *     13 multicast entries left for protocol.
- *
- *     Revision 1.13  1998/11/13 17:24:32  rassmann
- *     Changed return value of SkAddrOverride to int.
- *
- *     Revision 1.12  1998/11/13 16:56:19  rassmann
- *     Added macro SK_ADDR_COMPARE.
- *     Changed return type of SkAddrOverride to SK_BOOL.
- *
- *     Revision 1.11  1998/10/28 18:16:35  rassmann
- *     Avoiding I/Os before SK_INIT_RUN level.
- *     Aligning InexactFilter.
- *
- *     Revision 1.10  1998/10/22 11:39:10  rassmann
- *     Corrected signed/unsigned mismatches.
- *
- *     Revision 1.9  1998/10/15 15:15:49  rassmann
- *     Changed Flags Parameters from SK_U8 to int.
- *     Checked with lint.
- *
- *     Revision 1.8  1998/09/24 19:15:12  rassmann
- *     Code cleanup.
- *
- *     Revision 1.7  1998/09/18 20:22:13  rassmann
- *     Added HW access.
- *
- *     Revision 1.6  1998/09/04 19:40:20  rassmann
- *     Interface enhancements.
- *
- *     Revision 1.5  1998/09/04 12:40:57  rassmann
- *     Interface cleanup.
- *
- *     Revision 1.4  1998/09/04 12:14:13  rassmann
- *     Interface cleanup.
- *
- *     Revision 1.3  1998/09/02 16:56:40  rassmann
- *     Updated interface.
- *
- *     Revision 1.2  1998/08/27 14:26:09  rassmann
- *     Updated interface.
- *
- *     Revision 1.1  1998/08/21 08:31:08  rassmann
- *     First public version.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This module is intended to manage multicast addresses and promiscuous mode
- * on GEnesis adapters.
- *
- * Include File Hierarchy:
- *
- *     "skdrv1st.h"
- *     ...
- *     "sktypes.h"
- *     "skqueue.h"
- *     "skaddr.h"
- *     ...
- *     "skdrv2nd.h"
- *
- ******************************************************************************/
-
-#ifndef __INC_SKADDR_H
-#define __INC_SKADDR_H
-
-#ifdef __cplusplus
-#error C++ is not yet supported.
-extern "C" {
-#endif /* cplusplus */
-
-/* defines ********************************************************************/
-
-#define SK_MAC_ADDR_LEN                                6       /* Length of MAC address. */
-#define        SK_MAX_ADDRS                            14      /* #Addrs for exact match. */
-
-/* ----- Common return values ----- */
-
-#define SK_ADDR_SUCCESS                                0       /* Function returned successfully. */
-#define SK_ADDR_ILLEGAL_PORT                   100     /* Port number too high. */
-#define SK_ADDR_TOO_EARLY                      101     /* Function called too early. */
-
-/* ----- Clear/Add flag bits ----- */
-
-#define SK_ADDR_PERMANENT                      1       /* RLMT Address */
-
-/* ----- Additional Clear flag bits ----- */
-
-#define SK_MC_SW_ONLY                          2       /* Do not update HW when clearing. */
-
-/* ----- Override flag bits ----- */
-
-#define SK_ADDR_LOGICAL_ADDRESS                0
-#define SK_ADDR_VIRTUAL_ADDRESS                (SK_ADDR_LOGICAL_ADDRESS)       /* old */
-#define SK_ADDR_PHYSICAL_ADDRESS       1
-#define SK_ADDR_CLEAR_LOGICAL          2
-#define SK_ADDR_SET_LOGICAL                    4
-
-/* ----- Override return values ----- */
-
-#define SK_ADDR_OVERRIDE_SUCCESS       (SK_ADDR_SUCCESS)
-#define SK_ADDR_DUPLICATE_ADDRESS      1
-#define SK_ADDR_MULTICAST_ADDRESS      2
-
-/* ----- Partitioning of excact match table ----- */
-
-#define SK_ADDR_EXACT_MATCHES          16      /* #Exact match entries. */
-
-#define SK_ADDR_FIRST_MATCH_RLMT       1
-#define SK_ADDR_LAST_MATCH_RLMT                2
-#define SK_ADDR_FIRST_MATCH_DRV                3
-#define SK_ADDR_LAST_MATCH_DRV         (SK_ADDR_EXACT_MATCHES - 1)
-
-/* ----- SkAddrMcAdd/SkAddrMcUpdate return values ----- */
-
-#define SK_MC_FILTERING_EXACT          0       /* Exact filtering. */
-#define SK_MC_FILTERING_INEXACT                1       /* Inexact filtering. */
-
-/* ----- Additional SkAddrMcAdd return values ----- */
-
-#define SK_MC_ILLEGAL_ADDRESS          2       /* Illegal address. */
-#define SK_MC_ILLEGAL_PORT                     3       /* Illegal port (not the active one). */
-#define SK_MC_RLMT_OVERFLOW                    4       /* Too many RLMT mc addresses. */
-
-/* Promiscuous mode bits ----- */
-
-#define SK_PROM_MODE_NONE                      0       /* Normal receive. */
-#define SK_PROM_MODE_LLC                       1       /* Receive all LLC frames. */
-#define SK_PROM_MODE_ALL_MC                    2       /* Receive all multicast frames. */
-/* #define SK_PROM_MODE_NON_LLC                4 */    /* Receive all non-LLC frames. */
-
-/* Macros */
-
-#if 0
-#ifndef SK_ADDR_EQUAL
-/*
- * "&" instead of "&&" allows better optimization on IA-64.
- * The replacement is safe here, as all bytes exist.
- */
-#ifndef SK_ADDR_DWORD_COMPARE
-#define SK_ADDR_EQUAL(A1,A2)   ( \
-       (((SK_U8 *)(A1))[5] == ((SK_U8 *)(A2))[5]) & \
-       (((SK_U8 *)(A1))[4] == ((SK_U8 *)(A2))[4]) & \
-       (((SK_U8 *)(A1))[3] == ((SK_U8 *)(A2))[3]) & \
-       (((SK_U8 *)(A1))[2] == ((SK_U8 *)(A2))[2]) & \
-       (((SK_U8 *)(A1))[1] == ((SK_U8 *)(A2))[1]) & \
-       (((SK_U8 *)(A1))[0] == ((SK_U8 *)(A2))[0]))
-#else  /* SK_ADDR_DWORD_COMPARE */
-#define SK_ADDR_EQUAL(A1,A2)   ( \
-       (*(SK_U32 *)&(((SK_U8 *)(A1))[2]) == *(SK_U32 *)&(((SK_U8 *)(A2))[2])) & \
-       (*(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0])))
-#endif /* SK_ADDR_DWORD_COMPARE */
-#endif /* SK_ADDR_EQUAL */
-#endif /* 0 */
-
-#ifndef SK_ADDR_EQUAL
-#ifndef SK_ADDR_DWORD_COMPARE
-#define SK_ADDR_EQUAL(A1,A2)   ( \
-       (((SK_U8 *)(A1))[5] == ((SK_U8 *)(A2))[5]) & \
-       (((SK_U8 *)(A1))[4] == ((SK_U8 *)(A2))[4]) & \
-       (((SK_U8 *)(A1))[3] == ((SK_U8 *)(A2))[3]) & \
-       (((SK_U8 *)(A1))[2] == ((SK_U8 *)(A2))[2]) & \
-       (((SK_U8 *)(A1))[1] == ((SK_U8 *)(A2))[1]) & \
-       (((SK_U8 *)(A1))[0] == ((SK_U8 *)(A2))[0]))
-#else  /* SK_ADDR_DWORD_COMPARE */
-#define SK_ADDR_EQUAL(A1,A2)   ( \
-       (*(SK_U16 *)&(((SK_U8 *)(A1))[4]) == *(SK_U16 *)&(((SK_U8 *)(A2))[4])) && \
-       (*(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0])))
-#endif /* SK_ADDR_DWORD_COMPARE */
-#endif /* SK_ADDR_EQUAL */
-
-/* typedefs *******************************************************************/
-
-typedef struct s_MacAddr {
-       SK_U8   a[SK_MAC_ADDR_LEN];
-} SK_MAC_ADDR;
-
-
-/* SK_FILTER is used to ensure alignment of the filter. */
-typedef union s_InexactFilter {
-       SK_U8   Bytes[8];
-       SK_U64  Val;    /* Dummy entry for alignment only. */
-} SK_FILTER64;
-
-
-typedef struct s_AddrNet SK_ADDR_NET;
-
-
-typedef struct s_AddrPort {
-
-/* ----- Public part (read-only) ----- */
-
-       SK_MAC_ADDR     CurrentMacAddress;      /* Current physical MAC Address. */
-       SK_MAC_ADDR     PermanentMacAddress;    /* Permanent physical MAC Address. */
-       int             PromMode;               /* Promiscuous Mode. */
-
-/* ----- Private part ----- */
-
-       SK_MAC_ADDR     PreviousMacAddress;     /* Prev. phys. MAC Address. */
-       SK_BOOL         CurrentMacAddressSet;   /* CurrentMacAddress is set. */
-       SK_U8           Align01;
-
-       SK_U32          FirstExactMatchRlmt;
-       SK_U32          NextExactMatchRlmt;
-       SK_U32          FirstExactMatchDrv;
-       SK_U32          NextExactMatchDrv;
-       SK_MAC_ADDR     Exact[SK_ADDR_EXACT_MATCHES];
-       SK_FILTER64     InexactFilter;                  /* For 64-bit hash register. */
-       SK_FILTER64     InexactRlmtFilter;              /* For 64-bit hash register. */
-       SK_FILTER64     InexactDrvFilter;               /* For 64-bit hash register. */
-} SK_ADDR_PORT;
-
-
-struct s_AddrNet {
-/* ----- Public part (read-only) ----- */
-
-       SK_MAC_ADDR             CurrentMacAddress;      /* Logical MAC Address. */
-       SK_MAC_ADDR             PermanentMacAddress;    /* Logical MAC Address. */
-
-/* ----- Private part ----- */
-
-       SK_U32                  ActivePort;             /* View of module ADDR. */
-       SK_BOOL                 CurrentMacAddressSet;   /* CurrentMacAddress is set. */
-       SK_U8                   Align01;
-       SK_U16                  Align02;
-};
-
-
-typedef struct s_Addr {
-
-/* ----- Public part (read-only) ----- */
-
-       SK_ADDR_NET             Net[SK_MAX_NETS];
-       SK_ADDR_PORT    Port[SK_MAX_MACS];
-
-/* ----- Private part ----- */
-} SK_ADDR;
-
-/* function prototypes ********************************************************/
-
-#ifndef SK_KR_PROTO
-
-/* Functions provided by SkAddr */
-
-/* ANSI/C++ compliant function prototypes */
-
-extern int     SkAddrInit(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int     Level);
-
-extern int     SkAddrMcClear(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  PortNumber,
-       int     Flags);
-
-extern int     SkAddrXmacMcClear(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  PortNumber,
-       int     Flags);
-
-extern int     SkAddrGmacMcClear(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  PortNumber,
-       int     Flags);
-
-extern int     SkAddrMcAdd(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       SK_U32          PortNumber,
-       SK_MAC_ADDR     *pMc,
-       int             Flags);
-
-extern int     SkAddrXmacMcAdd(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       SK_U32          PortNumber,
-       SK_MAC_ADDR     *pMc,
-       int             Flags);
-
-extern int     SkAddrGmacMcAdd(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       SK_U32          PortNumber,
-       SK_MAC_ADDR     *pMc,
-       int             Flags);
-
-extern int     SkAddrMcUpdate(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  PortNumber);
-
-extern int     SkAddrXmacMcUpdate(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  PortNumber);
-
-extern int     SkAddrGmacMcUpdate(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  PortNumber);
-
-extern int     SkAddrOverride(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       SK_U32          PortNumber,
-       SK_MAC_ADDR     *pNewAddr,
-       int             Flags);
-
-extern int     SkAddrPromiscuousChange(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  PortNumber,
-       int     NewPromMode);
-
-extern int     SkAddrXmacPromiscuousChange(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  PortNumber,
-       int     NewPromMode);
-
-extern int     SkAddrGmacPromiscuousChange(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  PortNumber,
-       int     NewPromMode);
-
-extern int     SkAddrSwap(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  FromPortNumber,
-       SK_U32  ToPortNumber);
-
-#else  /* defined(SK_KR_PROTO)) */
-
-/* Non-ANSI/C++ compliant function prototypes */
-
-#error KR-style prototypes are not yet provided.
-
-#endif /* defined(SK_KR_PROTO)) */
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_SKADDR_H */
diff --git a/drivers/sk98lin/h/skcsum.h b/drivers/sk98lin/h/skcsum.h
deleted file mode 100644 (file)
index 2acae32..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-/******************************************************************************
- *
- * Name:       skcsum.h
- * Project:    GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx)
- * Version:    $Revision: 1.9 $
- * Date:       $Date: 2001/02/06 11:21:39 $
- * Purpose:    Store/verify Internet checksum in send/receive packets.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2001 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skcsum.h,v $
- *     Revision 1.9  2001/02/06 11:21:39  rassmann
- *     Editorial changes.
- *
- *     Revision 1.8  2001/02/06 11:15:36  rassmann
- *     Supporting two nets on dual-port adapters.
- *
- *     Revision 1.7  2000/06/29 13:17:05  rassmann
- *     Corrected reception of a packet with UDP checksum == 0 (which means there
- *     is no UDP checksum).
- *
- *     Revision 1.6  2000/02/28 12:33:44  cgoos
- *     Changed C++ style comments to C style.
- *
- *     Revision 1.5  2000/02/21 12:10:05  cgoos
- *     Fixed license comment.
- *
- *     Revision 1.4  2000/02/21 11:08:37  cgoos
- *     Merged changes back into common source.
- *
- *     Revision 1.1  1999/07/26 14:47:49  mkarl
- *     changed from common source to windows specific source
- *     added return SKCS_STATUS_IP_CSUM_ERROR_UDP and
- *     SKCS_STATUS_IP_CSUM_ERROR_TCP to pass the NidsTester
- *     changes for Tx csum offload
- *
- *     Revision 1.2  1998/09/04 12:16:34  mhaveman
- *     Checked in for Stephan to allow compilation.
- *     -Added definition SK_CSUM_EVENT_CLEAR_PROTO_STATS to clear statistic
- *     -Added prototype for SkCsEvent()
- *
- *     Revision 1.1  1998/09/01 15:36:53  swolf
- *     initial revision
- *
- *     01-Sep-1998 sw  Created.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * Public header file for the "GEnesis" common module "CSUM".
- *
- * "GEnesis" is an abbreviation of "Gigabit Ethernet Network System in Silicon"
- * and is the code name of this SysKonnect project.
- *
- * Compilation Options:
- *
- *     SK_USE_CSUM - Define if CSUM is to be used. Otherwise, CSUM will be an
- *     empty module.
- *
- *     SKCS_OVERWRITE_PROTO - Define to overwrite the default protocol id
- *     definitions. In this case, all SKCS_PROTO_xxx definitions must be made
- *     external.
- *
- *     SKCS_OVERWRITE_STATUS - Define to overwrite the default return status
- *     definitions. In this case, all SKCS_STATUS_xxx definitions must be made
- *     external.
- *
- * Include File Hierarchy:
- *
- *     "h/skcsum.h"
- *      "h/sktypes.h"
- *      "h/skqueue.h"
- *
- ******************************************************************************/
-
-#ifndef __INC_SKCSUM_H
-#define __INC_SKCSUM_H
-
-#include "h/sktypes.h"
-#include "h/skqueue.h"
-
-/* defines ********************************************************************/
-
-/*
- * Define the default bit flags for 'SKCS_PACKET_INFO.ProtocolFlags'  if no user
- * overwrite.
- */
-#ifndef SKCS_OVERWRITE_PROTO   /* User overwrite? */
-#define SKCS_PROTO_IP  0x1     /* IP (Internet Protocol version 4) */
-#define SKCS_PROTO_TCP 0x2     /* TCP (Transmission Control Protocol) */
-#define SKCS_PROTO_UDP 0x4     /* UDP (User Datagram Protocol) */
-
-/* Indices for protocol statistics. */
-#define SKCS_PROTO_STATS_IP    0
-#define SKCS_PROTO_STATS_UDP   1
-#define SKCS_PROTO_STATS_TCP   2
-#define SKCS_NUM_PROTOCOLS     3       /* Number of supported protocols. */
-#endif /* !SKCS_OVERWRITE_PROTO */
-
-/*
- * Define the default SKCS_STATUS type and values if no user overwrite.
- *
- *     SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.
- *     SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.
- *     SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.
- *     SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame
- *     SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).
- *     SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).
- *     SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).
- *     SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).
- *     SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.
- *     SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.
- *     SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum.
- */
-#ifndef SKCS_OVERWRITE_STATUS  /* User overwrite? */
-#define SKCS_STATUS    int     /* Define status type. */
-
-#define SKCS_STATUS_UNKNOWN_IP_VERSION 1
-#define SKCS_STATUS_IP_CSUM_ERROR              2
-#define SKCS_STATUS_IP_FRAGMENT                        3
-#define SKCS_STATUS_IP_CSUM_OK                 4
-#define SKCS_STATUS_TCP_CSUM_ERROR             5
-#define SKCS_STATUS_UDP_CSUM_ERROR             6
-#define SKCS_STATUS_TCP_CSUM_OK                        7
-#define SKCS_STATUS_UDP_CSUM_OK                        8
-/* needed for Microsoft */
-#define SKCS_STATUS_IP_CSUM_ERROR_UDP  9
-#define SKCS_STATUS_IP_CSUM_ERROR_TCP  10
-/* UDP checksum may be omitted */
-#define SKCS_STATUS_IP_CSUM_OK_NO_UDP  11
-#endif /* !SKCS_OVERWRITE_STATUS */
-
-/* Clear protocol statistics event. */
-#define SK_CSUM_EVENT_CLEAR_PROTO_STATS        1
-
-/*
- * Add two values in one's complement.
- *
- * Note: One of the two input values may be "longer" than 16-bit, but then the
- * resulting sum may be 17 bits long. In this case, add zero to the result using
- * SKCS_OC_ADD() again.
- *
- *     Result = Value1 + Value2
- */
-#define SKCS_OC_ADD(Result, Value1, Value2) {                          \
-       unsigned long Sum;                                              \
-                                                                       \
-       Sum = (unsigned long) (Value1) + (unsigned long) (Value2);      \
-       /* Add-in any carry. */                                         \
-       (Result) = (Sum & 0xffff) + (Sum >> 16);                        \
-}
-
-/*
- * Subtract two values in one's complement.
- *
- *     Result = Value1 - Value2
- */
-#define SKCS_OC_SUB(Result, Value1, Value2)    \
-       SKCS_OC_ADD((Result), (Value1), ~(Value2) & 0xffff)
-
-/* typedefs *******************************************************************/
-
-/*
- * SKCS_PROTO_STATS - The CSUM protocol statistics structure.
- *
- * There is one instance of this structure for each protocol supported.
- */
-typedef struct s_CsProtocolStatistics {
-       SK_U64 RxOkCts;         /* Receive checksum ok. */
-       SK_U64 RxUnableCts;     /* Unable to verify receive checksum. */
-       SK_U64 RxErrCts;        /* Receive checksum error. */
-       SK_U64 TxOkCts;         /* Transmit checksum ok. */
-       SK_U64 TxUnableCts;     /* Unable to calculate checksum in hw. */
-} SKCS_PROTO_STATS;
-
-/*
- * s_Csum - The CSUM module context structure.
- */
-typedef struct s_Csum {
-       /* Enabled receive SK_PROTO_XXX bit flags. */
-       unsigned ReceiveFlags[SK_MAX_NETS];
-#ifdef TX_CSUM
-       unsigned TransmitFlags[SK_MAX_NETS];
-#endif /* TX_CSUM */
-
-       /* The protocol statistics structure; one per supported protocol. */
-       SKCS_PROTO_STATS ProtoStats[SK_MAX_NETS][SKCS_NUM_PROTOCOLS];
-} SK_CSUM;
-
-/*
- * SKCS_PACKET_INFO - The packet information structure.
- */
-typedef struct s_CsPacketInfo {
-       /* Bit field specifiying the desired/found protocols. */
-       unsigned ProtocolFlags;
-
-       /* Length of complete IP header, including any option fields. */
-       unsigned IpHeaderLength;
-
-       /* IP header checksum. */
-       unsigned IpHeaderChecksum;
-
-       /* TCP/UDP pseudo header checksum. */
-       unsigned PseudoHeaderChecksum;
-} SKCS_PACKET_INFO;
-
-/* function prototypes ********************************************************/
-
-#ifndef SkCsCalculateChecksum
-extern unsigned SkCsCalculateChecksum(
-       void            *pData,
-       unsigned        Length);
-#endif
-
-extern int SkCsEvent(
-       SK_AC           *pAc,
-       SK_IOC          Ioc,
-       SK_U32          Event,
-       SK_EVPARA       Param);
-
-extern SKCS_STATUS SkCsGetReceiveInfo(
-       SK_AC           *pAc,
-       void            *pIpHeader,
-       unsigned        Checksum1,
-       unsigned        Checksum2,
-       int                     NetNumber);
-
-extern void SkCsGetSendInfo(
-       SK_AC                           *pAc,
-       void                            *pIpHeader,
-       SKCS_PACKET_INFO        *pPacketInfo,
-       int                                     NetNumber);
-
-extern void SkCsSetReceiveFlags(
-       SK_AC           *pAc,
-       unsigned        ReceiveFlags,
-       unsigned        *pChecksum1Offset,
-       unsigned        *pChecksum2Offset,
-       int                     NetNumber);
-
-#endif /* __INC_SKCSUM_H */
diff --git a/drivers/sk98lin/h/skdebug.h b/drivers/sk98lin/h/skdebug.h
deleted file mode 100644 (file)
index cf5b5ad..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/******************************************************************************
- *
- * Name:       skdebug.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.12 $
- * Date:       $Date: 2002/07/15 15:37:13 $
- * Purpose:    SK specific DEBUG support
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *     $Log: skdebug.h,v $
- *     Revision 1.12  2002/07/15 15:37:13  rschmidt
- *     Power Management support
- *     Editorial changes
- *
- *     Revision 1.11  2002/04/25 11:04:39  rschmidt
- *     Editorial changes
- *
- *     Revision 1.10  1999/11/22 13:47:40  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.9  1999/09/14 14:02:43  rwahl
- *     Added SK_DBGMOD_PECP.
- *
- *     Revision 1.8  1998/11/25 08:31:54  gklug
- *     fix: no C++ comments allowed in common sources
- *
- *     Revision 1.7  1998/11/24 16:47:24  swolf
- *     Driver may now define its own SK_DBG_MSG() (eg. in "h/skdrv1st.h").
- *
- *     Revision 1.6  1998/10/28 10:23:55  rassmann
- *     ADDED SK_DBGMOD_ADDR.
- *
- *     Revision 1.5  1998/10/22 09:43:55  gklug
- *     add: CSUM module
- *
- *     Revision 1.4  1998/10/01 07:54:44  gklug
- *     add: PNMI debug module
- *
- *     Revision 1.3  1998/09/18 08:32:34  afischer
- *     Macros changed according ssr-spec.:
- *             SK_DBG_MODCHK -> SK_DBG_CHKMOD
- *             SK_DBG_CATCHK -> SK_DBG_CHKCAT
- *
- *     Revision 1.2  1998/07/03 14:38:25  malthoff
- *     Add category SK_DBGCAT_FATAL.
- *
- *     Revision 1.1  1998/06/19 13:39:01  malthoff
- *     created.
- *
- *
- ******************************************************************************/
-
-#ifndef __INC_SKDEBUG_H
-#define __INC_SKDEBUG_H
-
-#ifdef DEBUG
-#ifndef SK_DBG_MSG
-#define SK_DBG_MSG(pAC,comp,cat,arg) \
-               if ( ((comp) & SK_DBG_CHKMOD(pAC)) &&   \
-                     ((cat) & SK_DBG_CHKCAT(pAC)) ) {  \
-                       SK_DBG_PRINTF arg ;             \
-               }
-#endif
-#else
-#define SK_DBG_MSG(pAC,comp,lev,arg)
-#endif
-
-/* PLS NOTE:
- * =========
- * Due to any restrictions of kernel printf routines do not use other
- * format identifiers as: %x %d %c %s .
- * Never use any combined format identifiers such as: %lx %ld in your
- * printf - argument (arg) because some OS specific kernel printfs may
- * only support some basic identifiers.
- */
-
-/* Debug modules */
-
-#define SK_DBGMOD_MERR 0x00000001L     /* general module error indication */
-#define SK_DBGMOD_HWM  0x00000002L     /* Hardware init module */
-#define SK_DBGMOD_RLMT 0x00000004L     /* RLMT module */
-#define SK_DBGMOD_VPD  0x00000008L     /* VPD module */
-#define SK_DBGMOD_I2C  0x00000010L     /* I2C module */
-#define SK_DBGMOD_PNMI 0x00000020L     /* PNMI module */
-#define SK_DBGMOD_CSUM 0x00000040L     /* CSUM module */
-#define SK_DBGMOD_ADDR 0x00000080L     /* ADDR module */
-#define SK_DBGMOD_PECP 0x00000100L     /* PECP module */
-#define SK_DBGMOD_POWM 0x00000200L     /* Power Management module */
-
-/* Debug events */
-
-#define SK_DBGCAT_INIT 0x00000001L     /* module/driver initialization */
-#define SK_DBGCAT_CTRL 0x00000002L     /* controlling devices */
-#define SK_DBGCAT_ERR  0x00000004L     /* error handling paths */
-#define SK_DBGCAT_TX   0x00000008L     /* transmit path */
-#define SK_DBGCAT_RX   0x00000010L     /* receive path */
-#define SK_DBGCAT_IRQ  0x00000020L     /* general IRQ handling */
-#define SK_DBGCAT_QUEUE        0x00000040L     /* any queue management */
-#define SK_DBGCAT_DUMP 0x00000080L     /* large data output e.g. hex dump */
-#define SK_DBGCAT_FATAL        0x00000100L     /* fatal error */
-
-#endif /* __INC_SKDEBUG_H */
diff --git a/drivers/sk98lin/h/skdrv1st.h b/drivers/sk98lin/h/skdrv1st.h
deleted file mode 100644 (file)
index af34d7b..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/******************************************************************************
- *
- * Name:       skdrv1st.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.11 $
- * Date:       $Date: 2003/02/25 14:16:40 $
- * Purpose:    First header file for driver and all other modules
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skdrv1st.h,v $
- *     Revision 1.11  2003/02/25 14:16:40  mlindner
- *     Fix: Copyright statement
- *
- *     Revision 1.10  2002/10/02 12:46:02  mlindner
- *     Add: Support for Yukon
- *
- *     Revision 1.9.2.2  2001/12/07 12:06:42  mlindner
- *     Fix: malloc -> slab changes
- *
- *     Revision 1.9.2.1  2001/03/12 16:50:59  mlindner
- *     chg: kernel 2.4 adaption
- *
- *     Revision 1.9  2001/01/22 14:16:04  mlindner
- *     added ProcFs functionality
- *     Dual Net functionality integrated
- *     Rlmt networks added
- *
- *     Revision 1.8  2000/02/21 12:19:18  cgoos
- *     Added default for SK_DEBUG_CHKMOD/_CHKCAT
- *
- *     Revision 1.7  1999/11/22 13:50:00  cgoos
- *     Changed license header to GPL.
- *     Added overwrite for several functions.
- *     Removed linux 2.0.x definitions.
- *     Removed PCI vendor ID definition (now in kernel).
- *
- *     Revision 1.6  1999/07/27 08:03:33  cgoos
- *     Changed SK_IN/OUT macros to readX/writeX instead of memory
- *     accesses (necessary for ALPHA).
- *
- *     Revision 1.5  1999/07/23 12:10:21  cgoos
- *     Removed SK_RLMT_SLOW_LOOKAHEAD define.
- *
- *     Revision 1.4  1999/07/14 12:31:13  cgoos
- *     Added SK_RLMT_SLOW_LOOKAHEAD define.
- *
- *     Revision 1.3  1999/04/07 10:12:54  cgoos
- *     Added check for KERNEL and OPTIMIZATION defines.
- *
- *     Revision 1.2  1999/03/01 08:51:47  cgoos
- *     Fixed pcibios_read/write definitions.
- *
- *     Revision 1.1  1999/02/16 07:40:49  cgoos
- *     First version.
- *
- *
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This is the first include file of the driver, which includes all
- * neccessary system header files and some of the GEnesis header files.
- * It also defines some basic items.
- *
- * Include File Hierarchy:
- *
- *     see skge.c
- *
- ******************************************************************************/
-
-#ifndef __INC_SKDRV1ST_H
-#define __INC_SKDRV1ST_H
-
-#if 0
-/* Check kernel version */
-#include <linux/version.h>
-#if (LINUX_VERSION_CODE > 0x020300)
-#endif
-#endif
-
-typedef struct s_AC    SK_AC;
-
-/* override some default functions with optimized linux functions */
-
-#define SK_PNMI_STORE_U16(p,v)         memcpy((char*)(p),(char*)&(v),2)
-#define SK_PNMI_STORE_U32(p,v)         memcpy((char*)(p),(char*)&(v),4)
-#define SK_PNMI_STORE_U64(p,v)         memcpy((char*)(p),(char*)&(v),8)
-#define SK_PNMI_READ_U16(p,v)          memcpy((char*)&(v),(char*)(p),2)
-#define SK_PNMI_READ_U32(p,v)          memcpy((char*)&(v),(char*)(p),2)
-#define SK_PNMI_READ_U64(p,v)          memcpy((char*)&(v),(char*)(p),2)
-
-#define SkCsCalculateChecksum(p,l)     ((~ip_compute_csum(p, l)) & 0xffff)
-
-#define SK_ADDR_EQUAL(a1,a2)           (!memcmp(a1,a2,6))
-
-
-#if !defined(__OPTIMIZE__)  ||  !defined(__KERNEL__)
-#warning  You must compile this file with the correct options!
-#warning  See the last lines of the source file.
-#error You must compile this driver with "-O".
-#endif
-
-#if 0
-#include <linux/version.h>
-#endif
-#include <linux/types.h>
-#if 0
-#include <linux/kernel.h>
-#endif
-#include <linux/string.h>
-#if 0
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#endif
-#include <asm/byteorder.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#if 0
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <net/checksum.h>
-#endif
-
-#include       "h/sktypes.h"
-#include       "h/skerror.h"
-#include       "h/skdebug.h"
-#include       "h/lm80.h"
-#include       "h/xmac_ii.h"
-
-#include "u-boot_compat.h"
-
-#ifdef __LITTLE_ENDIAN
-#define SK_LITTLE_ENDIAN
-#else
-#define SK_BIG_ENDIAN
-#endif
-
-#if 0
-#define SK_NET_DEVICE  net_device
-#else
-#define SK_NET_DEVICE  eth_device
-#endif
-
-
-/* we use gethrtime(), return unit: nanoseconds */
-#if 0
-#define SK_TICKS_PER_SEC       HZ
-#else
-#define SK_TICKS_PER_SEC       CFG_HZ
-#endif
-
-#define        SK_MEM_MAPPED_IO
-
-/* #define SK_RLMT_SLOW_LOOKAHEAD */
-
-#define SK_MAX_MACS            2
-#define SK_MAX_NETS            2
-
-#define SK_IOC                 char*
-
-typedef struct s_DrvRlmtMbuf SK_MBUF;
-
-#define        SK_CONST64      INT64_C
-#define        SK_CONSTU64     UINT64_C
-
-#define SK_MEMCPY(dest,src,size)       memcpy(dest,src,size)
-#define SK_MEMCMP(s1,s2,size)          memcmp(s1,s2,size)
-#define SK_MEMSET(dest,val,size)       memset(dest,val,size)
-#define SK_STRLEN(pStr)                        strlen((char*)(pStr))
-#define SK_STRNCPY(pDest,pSrc,size)    strncpy((char*)(pDest),(char*)(pSrc),size)
-#define SK_STRCMP(pStr1,pStr2)         strcmp((char*)(pStr1),(char*)(pStr2))
-
-/* macros to access the adapter */
-#define SK_OUT8(b,a,v)         writeb((v), ((b)+(a)))
-#define SK_OUT16(b,a,v)                writew((v), ((b)+(a)))
-#define SK_OUT32(b,a,v)                writel((v), ((b)+(a)))
-#define SK_IN8(b,a,pv)         (*(pv) = readb((b)+(a)))
-#define SK_IN16(b,a,pv)                (*(pv) = readw((b)+(a)))
-#define SK_IN32(b,a,pv)                (*(pv) = readl((b)+(a)))
-
-#define int8_t         char
-#define int16_t                short
-#define int32_t                long
-#define int64_t                long long
-#define uint8_t                u_char
-#define uint16_t       u_short
-#define uint32_t       u_long
-#define uint64_t       unsigned long long
-#define t_scalar_t     int
-#define t_uscalar_t    unsigned int
-#define uintptr_t      unsigned long
-
-#define __CONCAT__(A,B) A##B
-
-#define INT32_C(a)             __CONCAT__(a,L)
-#define INT64_C(a)             __CONCAT__(a,LL)
-#define UINT32_C(a)            __CONCAT__(a,UL)
-#define UINT64_C(a)            __CONCAT__(a,ULL)
-
-#ifdef DEBUG
-#define SK_DBG_PRINTF          printk
-#ifndef SK_DEBUG_CHKMOD
-#define SK_DEBUG_CHKMOD                0
-#endif
-#ifndef SK_DEBUG_CHKCAT
-#define SK_DEBUG_CHKCAT                0
-#endif
-/* those come from the makefile */
-#define SK_DBG_CHKMOD(pAC)     (SK_DEBUG_CHKMOD)
-#define SK_DBG_CHKCAT(pAC)     (SK_DEBUG_CHKCAT)
-
-extern void SkDbgPrintf(const char *format,...);
-
-#define SK_DBGMOD_DRV                  0x00010000
-
-/**** possible driver debug categories ********************************/
-#define SK_DBGCAT_DRV_ENTRY            0x00010000
-#define SK_DBGCAT_DRV_SAP              0x00020000
-#define SK_DBGCAT_DRV_MCA              0x00040000
-#define SK_DBGCAT_DRV_TX_PROGRESS      0x00080000
-#define SK_DBGCAT_DRV_RX_PROGRESS      0x00100000
-#define SK_DBGCAT_DRV_PROGRESS         0x00200000
-#define SK_DBGCAT_DRV_MSG              0x00400000
-#define SK_DBGCAT_DRV_PROM             0x00800000
-#define SK_DBGCAT_DRV_TX_FRAME         0x01000000
-#define SK_DBGCAT_DRV_ERROR            0x02000000
-#define SK_DBGCAT_DRV_INT_SRC          0x04000000
-#define SK_DBGCAT_DRV_EVENT            0x08000000
-
-#endif
-
-#define SK_ERR_LOG             SkErrorLog
-
-extern void SkErrorLog(SK_AC*, int, int, char*);
-
-#endif
diff --git a/drivers/sk98lin/h/skdrv2nd.h b/drivers/sk98lin/h/skdrv2nd.h
deleted file mode 100644 (file)
index a311827..0000000
+++ /dev/null
@@ -1,561 +0,0 @@
-/******************************************************************************
- *
- * Name:       skdrv2nd.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.15 $
- * Date:       $Date: 2003/02/25 14:16:40 $
- * Purpose:    Second header file for driver and all other modules
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skdrv2nd.h,v $
- *     Revision 1.15  2003/02/25 14:16:40  mlindner
- *     Fix: Copyright statement
- *
- *     Revision 1.14  2003/02/25 13:26:26  mlindner
- *     Add: Support for various vendors
- *
- *     Revision 1.13  2002/10/02 12:46:02  mlindner
- *     Add: Support for Yukon
- *
- *     Revision 1.12.2.2  2001/09/05 12:14:50  mlindner
- *     add: New hardware revision int
- *
- *     Revision 1.12.2.1  2001/03/12 16:50:59  mlindner
- *     chg: kernel 2.4 adaption
- *
- *     Revision 1.12  2001/03/01 12:52:15  mlindner
- *     Fixed ring size
- *
- *     Revision 1.11  2001/02/19 13:28:02  mlindner
- *     Changed PNMI parameter values
- *
- *     Revision 1.10  2001/01/22 14:16:04  mlindner
- *     added ProcFs functionality
- *     Dual Net functionality integrated
- *     Rlmt networks added
- *
- *     Revision 1.1  2000/10/05 19:46:50  phargrov
- *     Add directory src/vipk_devs_nonlbl/vipk_sk98lin/
- *     This is the SysKonnect SK-98xx Gigabit Ethernet driver,
- *     contributed by SysKonnect.
- *
- *     Revision 1.9  2000/02/21 10:39:55  cgoos
- *     Added flag for jumbo support usage.
- *
- *     Revision 1.8  1999/11/22 13:50:44  cgoos
- *     Changed license header to GPL.
- *     Fixed two comments.
- *
- *     Revision 1.7  1999/09/28 12:38:21  cgoos
- *     Added CheckQueue to SK_AC.
- *
- *     Revision 1.6  1999/07/27 08:04:05  cgoos
- *     Added checksumming variables to SK_AC.
- *
- *     Revision 1.5  1999/03/29 12:33:26  cgoos
- *     Rreversed to fine lock granularity.
- *
- *     Revision 1.4  1999/03/15 12:14:02  cgoos
- *     Added DriverLock to SK_AC.
- *     Removed other locks.
- *
- *     Revision 1.3  1999/03/01 08:52:27  cgoos
- *     Changed pAC->PciDev declaration.
- *
- *     Revision 1.2  1999/02/18 10:57:14  cgoos
- *     Removed SkDrvTimeStamp prototype.
- *     Fixed SkGeOsGetTime prototype.
- *
- *     Revision 1.1  1999/02/16 07:41:01  cgoos
- *     First version.
- *
- *
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This is the second include file of the driver, which includes all other
- * neccessary files and defines all structures and constants used by the
- * driver and the common modules.
- *
- * Include File Hierarchy:
- *
- *     see skge.c
- *
- ******************************************************************************/
-
-#ifndef __INC_SKDRV2ND_H
-#define __INC_SKDRV2ND_H
-
-#include "h/skqueue.h"
-#include "h/skgehwt.h"
-#include "h/sktimer.h"
-#include "h/ski2c.h"
-#include "h/skgepnmi.h"
-#include "h/skvpd.h"
-#include "h/skgehw.h"
-#include "h/skgeinit.h"
-#include "h/skaddr.h"
-#include "h/skgesirq.h"
-#include "h/skcsum.h"
-#include "h/skrlmt.h"
-#include "h/skgedrv.h"
-
-#define SK_PCI_ISCOMPLIANT(result, pdev) {     \
-    result = SK_FALSE; /* default */     \
-    /* 3Com (0x10b7) */     \
-    if (pdev->vendor == 0x10b7) {     \
-       /* Gigabit Ethernet Adapter (0x1700) */     \
-       if ((pdev->device == 0x1700)) { \
-           result = SK_TRUE;     \
-       }     \
-    /* SysKonnect (0x1148) */     \
-    } else if (pdev->vendor == 0x1148) {     \
-       /* SK-98xx Gigabit Ethernet Server Adapter (0x4300) */     \
-       /* SK-98xx V2 Gigabit Ethernet Adapter (0x4320) */     \
-       if ((pdev->device == 0x4300) || \
-           (pdev->device == 0x4320)) { \
-           result = SK_TRUE;     \
-       }     \
-    /* D-Link (0x1186) */     \
-    } else if (pdev->vendor == 0x1186) {     \
-       /* Gigabit Ethernet Adapter (0x4c00) */     \
-       if ((pdev->device == 0x4c00)) { \
-           result = SK_TRUE;     \
-       }     \
-    /* CNet (0x1371) */     \
-    } else if (pdev->vendor == 0x1371) {     \
-       /* GigaCard Network Adapter (0x434e) */     \
-       if ((pdev->device == 0x434e)) { \
-           result = SK_TRUE;     \
-       }     \
-    /* Linksys (0x1737) */     \
-    } else if (pdev->vendor == 0x1737) {     \
-       /* Gigabit Network Adapter (0x1032) */     \
-       /* Gigabit Network Adapter (0x1064) */     \
-       if ((pdev->device == 0x1032) || \
-           (pdev->device == 0x1064)) { \
-           result = SK_TRUE;     \
-       }     \
-    } else {     \
-       result = SK_FALSE;     \
-    }     \
-}
-
-
-extern SK_MBUF         *SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned);
-extern void            SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*);
-extern SK_U64          SkOsGetTime(SK_AC*);
-extern int             SkPciReadCfgDWord(SK_AC*, int, SK_U32*);
-extern int             SkPciReadCfgWord(SK_AC*, int, SK_U16*);
-extern int             SkPciReadCfgByte(SK_AC*, int, SK_U8*);
-extern int             SkPciWriteCfgDWord(SK_AC*, int, SK_U32);
-extern int             SkPciWriteCfgWord(SK_AC*, int, SK_U16);
-extern int             SkPciWriteCfgByte(SK_AC*, int, SK_U8);
-extern int             SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
-
-struct s_DrvRlmtMbuf {
-       SK_MBUF         *pNext;         /* Pointer to next RLMT Mbuf. */
-       SK_U8           *pData;         /* Data buffer (virtually contig.). */
-       unsigned        Size;           /* Data buffer size. */
-       unsigned        Length;         /* Length of packet (<= Size). */
-       SK_U32          PortIdx;        /* Receiving/transmitting port. */
-#ifdef SK_RLMT_MBUF_PRIVATE
-       SK_RLMT_MBUF    Rlmt;           /* Private part for RLMT. */
-#endif  /* SK_RLMT_MBUF_PRIVATE */
-       struct sk_buff  *pOs;           /* Pointer to message block */
-};
-
-
-/*
- * ioctl definitions
- */
-#define                SK_IOCTL_BASE           (SIOCDEVPRIVATE)
-#define                SK_IOCTL_GETMIB         (SK_IOCTL_BASE + 0)
-#define                SK_IOCTL_SETMIB         (SK_IOCTL_BASE + 1)
-#define                SK_IOCTL_PRESETMIB      (SK_IOCTL_BASE + 2)
-
-typedef struct s_IOCTL SK_GE_IOCTL;
-
-struct s_IOCTL {
-       char*           pData;
-       unsigned int    Len;
-};
-
-
-/*
- * define sizes of descriptor rings in bytes
- */
-
-#if 0
-#define                TX_RING_SIZE    (8*1024)
-#define                RX_RING_SIZE    (24*1024)
-#else
-#define                TX_RING_SIZE    (10 * 40)
-#define                RX_RING_SIZE    (10 * 40)
-#endif
-
-/*
- * Buffer size for ethernet packets
- */
-#define        ETH_BUF_SIZE    1540
-#define        ETH_MAX_MTU     1514
-#define ETH_MIN_MTU    60
-#define ETH_MULTICAST_BIT      0x01
-#define SK_JUMBO_MTU   9000
-
-/*
- * transmit priority selects the queue: LOW=asynchron, HIGH=synchron
- */
-#define TX_PRIO_LOW    0
-#define TX_PRIO_HIGH   1
-
-/*
- * alignment of rx/tx descriptors
- */
-#define DESCR_ALIGN    8
-
-/*
- * definitions for pnmi. TODO
- */
-#define SK_DRIVER_RESET(pAC, IoC)      0
-#define SK_DRIVER_SENDEVENT(pAC, IoC)  0
-#define SK_DRIVER_SELFTEST(pAC, IoC)   0
-/* For get mtu you must add an own function */
-#define SK_DRIVER_GET_MTU(pAc,IoC,i)   0
-#define SK_DRIVER_SET_MTU(pAc,IoC,i,v) 0
-#define SK_DRIVER_PRESET_MTU(pAc,IoC,i,v)      0
-
-
-/* TX and RX descriptors *****************************************************/
-
-typedef struct s_RxD RXD; /* the receive descriptor */
-
-struct s_RxD {
-       volatile SK_U32 RBControl;      /* Receive Buffer Control */
-       SK_U32          VNextRxd;       /* Next receive descriptor,low dword */
-       SK_U32          VDataLow;       /* Receive buffer Addr, low dword */
-       SK_U32          VDataHigh;      /* Receive buffer Addr, high dword */
-       SK_U32          FrameStat;      /* Receive Frame Status word */
-       SK_U32          TimeStamp;      /* Time stamp from XMAC */
-       SK_U32          TcpSums;        /* TCP Sum 2 / TCP Sum 1 */
-       SK_U32          TcpSumStarts;   /* TCP Sum Start 2 / TCP Sum Start 1 */
-       RXD             *pNextRxd;      /* Pointer to next Rxd */
-       struct sk_buff  *pMBuf;         /* Pointer to Linux' socket buffer */
-};
-
-typedef struct s_TxD TXD; /* the transmit descriptor */
-
-struct s_TxD {
-       volatile SK_U32 TBControl;      /* Transmit Buffer Control */
-       SK_U32          VNextTxd;       /* Next transmit descriptor,low dword */
-       SK_U32          VDataLow;       /* Transmit Buffer Addr, low dword */
-       SK_U32          VDataHigh;      /* Transmit Buffer Addr, high dword */
-       SK_U32          FrameStat;      /* Transmit Frame Status Word */
-       SK_U32          TcpSumOfs;      /* Reserved / TCP Sum Offset */
-       SK_U16          TcpSumSt;       /* TCP Sum Start */
-       SK_U16          TcpSumWr;       /* TCP Sum Write */
-       SK_U32          TcpReserved;    /* not used */
-       TXD             *pNextTxd;      /* Pointer to next Txd */
-       struct sk_buff  *pMBuf;         /* Pointer to Linux' socket buffer */
-};
-
-
-/* definition of flags in descriptor control field */
-#define        RX_CTRL_OWN_BMU         UINT32_C(0x80000000)
-#define        RX_CTRL_STF             UINT32_C(0x40000000)
-#define        RX_CTRL_EOF             UINT32_C(0x20000000)
-#define        RX_CTRL_EOB_IRQ         UINT32_C(0x10000000)
-#define        RX_CTRL_EOF_IRQ         UINT32_C(0x08000000)
-#define RX_CTRL_DEV_NULL       UINT32_C(0x04000000)
-#define RX_CTRL_STAT_VALID     UINT32_C(0x02000000)
-#define RX_CTRL_TIME_VALID     UINT32_C(0x01000000)
-#define RX_CTRL_CHECK_DEFAULT  UINT32_C(0x00550000)
-#define RX_CTRL_CHECK_CSUM     UINT32_C(0x00560000)
-#define        RX_CTRL_LEN_MASK        UINT32_C(0x0000FFFF)
-
-#define        TX_CTRL_OWN_BMU         UINT32_C(0x80000000)
-#define        TX_CTRL_STF             UINT32_C(0x40000000)
-#define        TX_CTRL_EOF             UINT32_C(0x20000000)
-#define        TX_CTRL_EOB_IRQ         UINT32_C(0x10000000)
-#define        TX_CTRL_EOF_IRQ         UINT32_C(0x08000000)
-#define TX_CTRL_ST_FWD         UINT32_C(0x04000000)
-#define TX_CTRL_DISAB_CRC      UINT32_C(0x02000000)
-#define TX_CTRL_SOFTWARE       UINT32_C(0x01000000)
-#define TX_CTRL_CHECK_DEFAULT  UINT32_C(0x00550000)
-#define TX_CTRL_CHECK_CSUM     UINT32_C(0x00560000)
-#define        TX_CTRL_LEN_MASK        UINT32_C(0x0000FFFF)
-
-
-/* The offsets of registers in the TX and RX queue control io area ***********/
-
-#define RX_Q_BUF_CTRL_CNT      0x00
-#define RX_Q_NEXT_DESCR_LOW    0x04
-#define RX_Q_BUF_ADDR_LOW      0x08
-#define RX_Q_BUF_ADDR_HIGH     0x0c
-#define RX_Q_FRAME_STAT                0x10
-#define RX_Q_TIME_STAMP                0x14
-#define RX_Q_CSUM_1_2          0x18
-#define RX_Q_CSUM_START_1_2    0x1c
-#define RX_Q_CUR_DESCR_LOW     0x20
-#define RX_Q_DESCR_HIGH                0x24
-#define RX_Q_CUR_ADDR_LOW      0x28
-#define RX_Q_CUR_ADDR_HIGH     0x2c
-#define RX_Q_CUR_BYTE_CNT      0x30
-#define RX_Q_CTRL              0x34
-#define RX_Q_FLAG              0x38
-#define RX_Q_TEST1             0x3c
-#define RX_Q_TEST2             0x40
-#define RX_Q_TEST3             0x44
-
-#define TX_Q_BUF_CTRL_CNT      0x00
-#define TX_Q_NEXT_DESCR_LOW    0x04
-#define TX_Q_BUF_ADDR_LOW      0x08
-#define TX_Q_BUF_ADDR_HIGH     0x0c
-#define TX_Q_FRAME_STAT                0x10
-#define TX_Q_CSUM_START                0x14
-#define TX_Q_CSUM_START_POS    0x18
-#define TX_Q_RESERVED          0x1c
-#define TX_Q_CUR_DESCR_LOW     0x20
-#define TX_Q_DESCR_HIGH                0x24
-#define TX_Q_CUR_ADDR_LOW      0x28
-#define TX_Q_CUR_ADDR_HIGH     0x2c
-#define TX_Q_CUR_BYTE_CNT      0x30
-#define TX_Q_CTRL              0x34
-#define TX_Q_FLAG              0x38
-#define TX_Q_TEST1             0x3c
-#define TX_Q_TEST2             0x40
-#define TX_Q_TEST3             0x44
-
-/* definition of flags in the queue control field */
-#define RX_Q_CTRL_POLL_ON      0x00000080
-#define RX_Q_CTRL_POLL_OFF     0x00000040
-#define RX_Q_CTRL_STOP         0x00000020
-#define RX_Q_CTRL_START                0x00000010
-#define RX_Q_CTRL_CLR_I_PAR    0x00000008
-#define RX_Q_CTRL_CLR_I_EOB    0x00000004
-#define RX_Q_CTRL_CLR_I_EOF    0x00000002
-#define RX_Q_CTRL_CLR_I_ERR    0x00000001
-
-#define TX_Q_CTRL_POLL_ON      0x00000080
-#define TX_Q_CTRL_POLL_OFF     0x00000040
-#define TX_Q_CTRL_STOP         0x00000020
-#define TX_Q_CTRL_START                0x00000010
-#define TX_Q_CTRL_CLR_I_EOB    0x00000004
-#define TX_Q_CTRL_CLR_I_EOF    0x00000002
-#define TX_Q_CTRL_CLR_I_ERR    0x00000001
-
-
-/* Interrupt bits in the interrupts source register **************************/
-#define IRQ_HW_ERROR           0x80000000
-#define IRQ_RESERVED           0x40000000
-#define IRQ_PKT_TOUT_RX1       0x20000000
-#define IRQ_PKT_TOUT_RX2       0x10000000
-#define IRQ_PKT_TOUT_TX1       0x08000000
-#define IRQ_PKT_TOUT_TX2       0x04000000
-#define IRQ_I2C_READY          0x02000000
-#define IRQ_SW                 0x01000000
-#define IRQ_EXTERNAL_REG       0x00800000
-#define IRQ_TIMER              0x00400000
-#define IRQ_MAC1               0x00200000
-#define IRQ_LINK_SYNC_C_M1     0x00100000
-#define IRQ_MAC2               0x00080000
-#define IRQ_LINK_SYNC_C_M2     0x00040000
-#define IRQ_EOB_RX1            0x00020000
-#define IRQ_EOF_RX1            0x00010000
-#define IRQ_CHK_RX1            0x00008000
-#define IRQ_EOB_RX2            0x00004000
-#define IRQ_EOF_RX2            0x00002000
-#define IRQ_CHK_RX2            0x00001000
-#define IRQ_EOB_SY_TX1         0x00000800
-#define IRQ_EOF_SY_TX1         0x00000400
-#define IRQ_CHK_SY_TX1         0x00000200
-#define IRQ_EOB_AS_TX1         0x00000100
-#define IRQ_EOF_AS_TX1         0x00000080
-#define IRQ_CHK_AS_TX1         0x00000040
-#define IRQ_EOB_SY_TX2         0x00000020
-#define IRQ_EOF_SY_TX2         0x00000010
-#define IRQ_CHK_SY_TX2         0x00000008
-#define IRQ_EOB_AS_TX2         0x00000004
-#define IRQ_EOF_AS_TX2         0x00000002
-#define IRQ_CHK_AS_TX2         0x00000001
-
-#define DRIVER_IRQS    (IRQ_SW | IRQ_EOF_RX1 | IRQ_EOF_RX2 | \
-                       IRQ_EOF_SY_TX1 | IRQ_EOF_AS_TX1 | \
-                       IRQ_EOF_SY_TX2 | IRQ_EOF_AS_TX2)
-
-#define SPECIAL_IRQS   (IRQ_HW_ERROR | IRQ_PKT_TOUT_RX1 | IRQ_PKT_TOUT_RX2 | \
-                       IRQ_PKT_TOUT_TX1 | IRQ_PKT_TOUT_TX2 | \
-                       IRQ_I2C_READY | IRQ_EXTERNAL_REG | IRQ_TIMER | \
-                       IRQ_MAC1 | IRQ_LINK_SYNC_C_M1 | \
-                       IRQ_MAC2 | IRQ_LINK_SYNC_C_M2 | \
-                       IRQ_CHK_RX1 | IRQ_CHK_RX2 | \
-                       IRQ_CHK_SY_TX1 | IRQ_CHK_AS_TX1 | \
-                       IRQ_CHK_SY_TX2 | IRQ_CHK_AS_TX2)
-
-#define IRQ_MASK       (IRQ_SW | IRQ_EOB_RX1 | IRQ_EOF_RX1 | \
-                       IRQ_EOB_RX2 | IRQ_EOF_RX2 | \
-                       IRQ_EOB_SY_TX1 | IRQ_EOF_SY_TX1 | \
-                       IRQ_EOB_AS_TX1 | IRQ_EOF_AS_TX1 | \
-                       IRQ_EOB_SY_TX2 | IRQ_EOF_SY_TX2 | \
-                       IRQ_EOB_AS_TX2 | IRQ_EOF_AS_TX2 | \
-                       IRQ_HW_ERROR | IRQ_PKT_TOUT_RX1 | IRQ_PKT_TOUT_RX2 | \
-                       IRQ_PKT_TOUT_TX1 | IRQ_PKT_TOUT_TX2 | \
-                       IRQ_I2C_READY | IRQ_EXTERNAL_REG | IRQ_TIMER | \
-                       IRQ_MAC1 | \
-                       IRQ_MAC2 | \
-                       IRQ_CHK_RX1 | IRQ_CHK_RX2 | \
-                       IRQ_CHK_SY_TX1 | IRQ_CHK_AS_TX1 | \
-                       IRQ_CHK_SY_TX2 | IRQ_CHK_AS_TX2)
-
-#define IRQ_HWE_MASK   0x00000FFF /* enable all HW irqs */
-
-typedef struct s_DevNet DEV_NET;
-
-struct s_DevNet {
-       int             PortNr;
-       int             NetNr;
-       int             Mtu;
-       int             Up;
-       SK_AC   *pAC;
-};
-
-typedef struct s_TxPort                TX_PORT;
-
-struct s_TxPort {
-       /* the transmit descriptor rings */
-       caddr_t         pTxDescrRing;   /* descriptor area memory */
-       SK_U64          VTxDescrRing;   /* descr. area bus virt. addr. */
-       TXD             *pTxdRingHead;  /* Head of Tx rings */
-       TXD             *pTxdRingTail;  /* Tail of Tx rings */
-       TXD             *pTxdRingPrev;  /* descriptor sent previously */
-       int             TxdRingFree;    /* # of free entrys */
-#if 0
-       spinlock_t      TxDesRingLock;  /* serialize descriptor accesses */
-#endif
-       caddr_t         HwAddr;         /* bmu registers address */
-       int             PortIndex;      /* index number of port (0 or 1) */
-};
-
-typedef struct s_RxPort                RX_PORT;
-
-struct s_RxPort {
-       /* the receive descriptor rings */
-       caddr_t         pRxDescrRing;   /* descriptor area memory */
-       SK_U64          VRxDescrRing;   /* descr. area bus virt. addr. */
-       RXD             *pRxdRingHead;  /* Head of Rx rings */
-       RXD             *pRxdRingTail;  /* Tail of Rx rings */
-       RXD             *pRxdRingPrev;  /* descriptor given to BMU previously */
-       int             RxdRingFree;    /* # of free entrys */
-#if 0
-       spinlock_t      RxDesRingLock;  /* serialize descriptor accesses */
-#endif
-       int             RxFillLimit;    /* limit for buffers in ring */
-       caddr_t         HwAddr;         /* bmu registers address */
-       int             PortIndex;      /* index number of port (0 or 1) */
-};
-
-typedef struct s_PerStrm       PER_STRM;
-
-#define SK_ALLOC_IRQ   0x00000001
-
-/****************************************************************************
- * Per board structure / Adapter Context structure:
- *     Allocated within attach(9e) and freed within detach(9e).
- *     Contains all 'per device' necessary handles, flags, locks etc.:
- */
-struct s_AC  {
-       SK_GEINIT       GIni;           /* GE init struct */
-       SK_PNMI         Pnmi;           /* PNMI data struct */
-       SK_VPD          vpd;            /* vpd data struct */
-       SK_QUEUE        Event;          /* Event queue */
-       SK_HWT          Hwt;            /* Hardware Timer control struct */
-       SK_TIMCTRL      Tim;            /* Software Timer control struct */
-       SK_I2C          I2c;            /* I2C relevant data structure */
-       SK_ADDR         Addr;           /* for Address module */
-       SK_CSUM         Csum;           /* for checksum module */
-       SK_RLMT         Rlmt;           /* for rlmt module */
-#if 0
-       spinlock_t      SlowPathLock;   /* Normal IRQ lock */
-#endif
-       SK_PNMI_STRUCT_DATA PnmiStruct; /* structure to get all Pnmi-Data */
-       int                     RlmtMode;       /* link check mode to set */
-       int                     RlmtNets;       /* Number of nets */
-
-       SK_IOC          IoBase;         /* register set of adapter */
-       int             BoardLevel;     /* level of active hw init (0-2) */
-       char            DeviceStr[80];  /* adapter string from vpd */
-       SK_U32          AllocFlag;      /* flag allocation of resources */
-#if 0
-       struct pci_dev  *PciDev;        /* for access to pci config space */
-       SK_U32          PciDevId;       /* pci device id */
-#else
-       int             PciDev;
-#endif
-       struct SK_NET_DEVICE    *dev[2];        /* pointer to device struct */
-       char            Name[30];       /* driver name */
-       struct SK_NET_DEVICE    *Next;          /* link all devices (for clearing) */
-       int             RxBufSize;      /* length of receive buffers */
-#if 0
-       struct net_device_stats stats;  /* linux 'netstat -i' statistics */
-#endif
-       int             Index;          /* internal board index number */
-
-       /* adapter RAM sizes for queues of active port */
-       int             RxQueueSize;    /* memory used for receive queue */
-       int             TxSQueueSize;   /* memory used for sync. tx queue */
-       int             TxAQueueSize;   /* memory used for async. tx queue */
-
-       int             PromiscCount;   /* promiscuous mode counter  */
-       int             AllMultiCount;  /* allmulticast mode counter */
-       int             MulticCount;    /* number of different MC    */
-                                       /*  addresses for this board */
-                                       /*  (may be more than HW can)*/
-
-       int             HWRevision;     /* Hardware revision */
-       int             ActivePort;     /* the active XMAC port */
-       int             MaxPorts;               /* number of activated ports */
-       int             TxDescrPerRing; /* # of descriptors per tx ring */
-       int             RxDescrPerRing; /* # of descriptors per rx ring */
-
-       caddr_t         pDescrMem;      /* Pointer to the descriptor area */
-       dma_addr_t      pDescrMemDMA;   /* PCI DMA address of area */
-
-       /* the port structures with descriptor rings */
-       TX_PORT         TxPort[SK_MAX_MACS][2];
-       RX_PORT         RxPort[SK_MAX_MACS];
-
-       unsigned int    CsOfs1;         /* for checksum calculation */
-       unsigned int    CsOfs2;         /* for checksum calculation */
-       SK_U32          CsOfs;          /* for checksum calculation */
-
-       SK_BOOL         CheckQueue;     /* check event queue soon */
-
-       /* Only for tests */
-       int             PortUp;
-       int             PortDown;
-
-};
-
-#endif /* __INC_SKDRV2ND_H */
diff --git a/drivers/sk98lin/h/skerror.h b/drivers/sk98lin/h/skerror.h
deleted file mode 100644 (file)
index a454d9d..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/******************************************************************************
- *
- * Name:       skerror.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.5 $
- * Date:       $Date: 2002/04/25 11:05:10 $
- * Purpose:    SK specific Error log support
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *     $Log: skerror.h,v $
- *     Revision 1.5  2002/04/25 11:05:10  rschmidt
- *     Editorial changes
- *
- *     Revision 1.4  1999/11/22 13:51:59  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.3  1999/09/14 14:04:42  rwahl
- *     Added error base SK_ERRBASE_PECP.
- *     Changed error base for driver.
- *
- *     Revision 1.2  1998/08/11 11:15:41  gklug
- *     chg: comments
- *
- *     Revision 1.1  1998/08/11 11:09:38  gklug
- *     add: error bases
- *     add: error Classes
- *     first version
- *
- *
- *
- ******************************************************************************/
-
-#ifndef _INC_SKERROR_H_
-#define _INC_SKERROR_H_
-
-/*
- * Define Error Classes
- */
-#define        SK_ERRCL_OTHER          (0)             /* Other error */
-#define        SK_ERRCL_CONFIG         (1L<<0) /* Configuration error */
-#define        SK_ERRCL_INIT           (1L<<1) /* Initialization error */
-#define        SK_ERRCL_NORES          (1L<<2) /* Out of Resources error */
-#define        SK_ERRCL_SW                     (1L<<3) /* Internal Software error */
-#define        SK_ERRCL_HW                     (1L<<4) /* Hardware Failure */
-#define        SK_ERRCL_COMM           (1L<<5) /* Communication error */
-
-
-/*
- * Define Error Code Bases
- */
-#define        SK_ERRBASE_RLMT          100    /* Base Error number for RLMT */
-#define        SK_ERRBASE_HWINIT        200    /* Base Error number for HWInit */
-#define        SK_ERRBASE_VPD           300    /* Base Error number for VPD */
-#define        SK_ERRBASE_PNMI          400    /* Base Error number for PNMI */
-#define        SK_ERRBASE_CSUM          500    /* Base Error number for Checksum */
-#define        SK_ERRBASE_SIRQ          600    /* Base Error number for Special IRQ */
-#define        SK_ERRBASE_I2C           700    /* Base Error number for I2C module */
-#define        SK_ERRBASE_QUEUE         800    /* Base Error number for Scheduler */
-#define        SK_ERRBASE_ADDR          900    /* Base Error number for Address module */
-#define SK_ERRBASE_PECP                1000    /* Base Error number for PECP */
-#define        SK_ERRBASE_DRV          1100    /* Base Error number for Driver */
-
-#endif /* _INC_SKERROR_H_ */
diff --git a/drivers/sk98lin/h/skgedrv.h b/drivers/sk98lin/h/skgedrv.h
deleted file mode 100644 (file)
index 72ba9ce..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/******************************************************************************
- *
- * Name:       skgedrv.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.6 $
- * Date:       $Date: 2002/07/15 15:38:01 $
- * Purpose:    Interface with the driver
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skgedrv.h,v $
- *     Revision 1.6  2002/07/15 15:38:01  rschmidt
- *     Power Management support
- *     Editorial changes
- *
- *     Revision 1.5  2002/04/25 11:05:47  rschmidt
- *     Editorial changes
- *
- *     Revision 1.4  1999/11/22 13:52:46  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.3  1998/12/01 13:31:39  cgoos
- *     SWITCH INTERN Event added.
- *
- *     Revision 1.2  1998/11/25 08:28:38  gklug
- *     rmv: PORT SWITCH Event
- *
- *     Revision 1.1  1998/09/29 06:14:07  gklug
- *     add: driver events (initial version)
- *
- *
- ******************************************************************************/
-
-#ifndef __INC_SKGEDRV_H_
-#define __INC_SKGEDRV_H_
-
-/* defines ********************************************************************/
-
-/*
- * Define the driver events.
- * Usually the events are defined by the destination module.
- * In case of the driver we put the definition of the events here.
- */
-#define SK_DRV_PORT_RESET               1      /* The port needs to be reset */
-#define SK_DRV_NET_UP                   2      /* The net is operational */
-#define SK_DRV_NET_DOWN                         3      /* The net is down */
-#define SK_DRV_SWITCH_SOFT              4      /* Ports switch with both links connected */
-#define SK_DRV_SWITCH_HARD              5      /* Port switch due to link failure */
-#define SK_DRV_RLMT_SEND                6      /* Send a RLMT packet */
-#define SK_DRV_ADAP_FAIL                7      /* The whole adapter fails */
-#define SK_DRV_PORT_FAIL                8      /* One port fails */
-#define SK_DRV_SWITCH_INTERN    9      /* Port switch by the driver itself */
-#define SK_DRV_POWER_DOWN              10      /* Power down mode */
-
-#endif /* __INC_SKGEDRV_H_ */
diff --git a/drivers/sk98lin/h/skgehw.h b/drivers/sk98lin/h/skgehw.h
deleted file mode 100644 (file)
index 2c98427..0000000
+++ /dev/null
@@ -1,2336 +0,0 @@
-/******************************************************************************
- *
- * Name:       skgehw.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.49 $
- * Date:       $Date: 2003/01/28 09:43:49 $
- * Purpose:    Defines and Macros for the Gigabit Ethernet Adapter Product Family
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- * $Log: skgehw.h,v $
- * Revision 1.49  2003/01/28 09:43:49  rschmidt
- * Added defines for PCI-Spec. 2.3 IRQ
- * Added defines for CLK_RUN (YUKON-Lite)
- * Editorial changes
- *
- * Revision 1.48  2002/12/05 10:25:11  rschmidt
- * Added defines for Half Duplex Burst Mode On/Off
- * Added defines for Rx GMAC FIFO Flush feature
- * Editorial changes
- *
- * Revision 1.47  2002/11/12 17:01:31  rschmidt
- * Added defines for WOL_CTL_DEFAULT
- * Editorial changes
- *
- * Revision 1.46  2002/10/14 14:47:57  rschmidt
- * Corrected bit mask for HW self test results
- * Added defines for WOL Registers
- * Editorial changes
- *
- * Revision 1.45  2002/10/11 09:25:22  mkarl
- * Added bit mask for HW self test results.
- *
- * Revision 1.44  2002/08/16 14:44:36  rschmidt
- * Added define GPC_HWCFG_GMII_FIB for YUKON Fiber
- *
- * Revision 1.43  2002/08/12 13:31:50  rschmidt
- * Corrected macros for GMAC Address Registers: GM_INADDR(),
- * GM_OUTADDR(), GM_INHASH, GM_OUTHASH.
- * Editorial changes
- *
- * Revision 1.42  2002/08/08 15:37:56  rschmidt
- * Added defines for Power Management Capabilities
- * Editorial changes
- *
- * Revision 1.41  2002/07/23 16:02:25  rschmidt
- * Added macro WOL_REG() to access WOL reg. (HW-Bug in YUKON 1st rev.)
- *
- * Revision 1.40  2002/07/15 15:41:37  rschmidt
- * Added new defines for Power Management Cap. & Control
- * Editorial changes
- *
- * Revision 1.39  2002/06/10 09:37:07  rschmidt
- * Added macros for the ADDR-Modul
- *
- * Revision 1.38  2002/06/05 08:15:19  rschmidt
- * Added defines for WOL Registers
- * Editorial changes
- *
- * Revision 1.37  2002/04/25 11:39:23  rschmidt
- * Added new defines for PCI Our Register 1
- * Added new registers and defines for YUKON (Rx FIFO, Tx FIFO,
- * Time Stamp Timer, GMAC Control, GPHY Control,Link Control,
- * GMAC IRQ Source and Mask, Wake-up Frame Pattern Match);
- * Added new defines for Control/Status (VAUX available)
- * Added Chip ID for YUKON
- * Added define for descriptors with UDP ext. for YUKON
- * Added macros to access the GMAC
- * Added new Phy Type for Marvell 88E1011S (GPHY)
- * Editorial changes
- *
- * Revision 1.36  2000/11/09 12:32:49  rassmann
- * Renamed variables.
- *
- * Revision 1.35  2000/05/19 10:17:13  cgoos
- * Added inactivity check in PHY_READ (in DEBUG mode only).
- *
- * Revision 1.34  1999/11/22 13:53:40  cgoos
- * Changed license header to GPL.
- *
- * Revision 1.33  1999/08/27 11:17:10  malthoff
- * It's more savely to put brackets around macro parameters.
- * Brackets added for PHY_READ and PHY_WRITE.
- *
- * Revision 1.32  1999/05/19 07:31:01  cgoos
- * Changes for 1000Base-T.
- * Added HWAC_LINK_LED macro.
- *
- * Revision 1.31  1999/03/12 13:27:40  malthoff
- * Remove __STDC__.
- *
- * Revision 1.30  1999/02/09 09:28:20  malthoff
- * Add PCI_ERRBITS.
- *
- * Revision 1.29  1999/01/26 08:55:48  malthoff
- * Bugfix: The 16 bit field relations inside the descriptor are
- *     endianess dependend if the descriptor reversal feature
- *     (PCI_REV_DESC bit in PCI_OUR_REG_2) is enabled.
- *     Drivers which use this feature has to set the define
- *     SK_USE_REV_DESC.
- *
- * Revision 1.28  1998/12/10 11:10:22  malthoff
- * bug fix: IS_IRQ_STAT and IS_IRQ_MST_ERR has been twisted.
- *
- * Revision 1.27  1998/11/13 14:19:21  malthoff
- * Bug Fix: The bit definition of B3_PA_CTRL has completely
- * changed from HW Spec v1.3 to v1.5.
- *
- * Revision 1.26  1998/11/04 08:31:48  cgoos
- * Fixed byte ordering in XM_OUTADDR/XM_OUTHASH macros.
- *
- * Revision 1.25  1998/11/04 07:16:25  cgoos
- * Changed byte ordering in XM_INADDR/XM_INHASH again.
- *
- * Revision 1.24  1998/11/02 11:08:43  malthoff
- * RxCtrl and TxCtrl must be volatile.
- *
- * Revision 1.23  1998/10/28 13:50:45  malthoff
- * Fix: Endian support missing in XM_IN/OUT-ADDR/HASH macros.
- *
- * Revision 1.22  1998/10/26 08:01:36  malthoff
- * RX_MFF_CTRL1 is split up into RX_MFF_CTRL1,
- * RX_MFF_STAT_TO, and RX_MFF_TIST_TO.
- * TX_MFF_CTRL1 is split up TX_MFF_CTRL1 and TX_MFF_WAF.
- *
- * Revision 1.21  1998/10/20 07:43:10  malthoff
- * Fix: XM_IN/OUT/ADDR/HASH macros:
- * The pointer must be casted.
- *
- * Revision 1.20  1998/10/19 15:53:59  malthoff
- * Remove ML proto definitions.
- *
- * Revision 1.19  1998/10/16 14:40:17  gklug
- * fix: typo B0_XM_IMSK regs
- *
- * Revision 1.18  1998/10/16 09:46:54  malthoff
- * Remove temp defines for ML diag prototype.
- * Fix register definition for B0_XM1_PHY_DATA, B0_XM1_PHY_DATA
- * B0_XM2_PHY_DATA, B0_XM2_PHY_ADDR, B0_XA1_CSR, B0_XS1_CSR,
- * B0_XS2_CSR, and B0_XA2_CSR.
- *
- * Revision 1.17  1998/10/14 06:03:14  cgoos
- * Changed shifted constant to ULONG.
- *
- * Revision 1.16  1998/10/09 07:05:41  malthoff
- * Rename ALL_PA_ENA_TO to PA_ENA_TO_ALL.
- *
- * Revision 1.15  1998/10/05 07:54:23  malthoff
- * Split up RB_CTRL and it's bit definition into
- * RB_CTRL, RB_TST1, and RB_TST2.
- * Rename RB_RX_HTPP to RB_RX_LTPP.
- * Add ALL_PA_ENA_TO. Modify F_WATER_MARK
- * according to HW Spec. v1.5.
- * Add MFF_TX_CTRL_DEF.
- *
- * Revision 1.14  1998/09/28 13:31:16  malthoff
- * bug fix: B2_MAC_3 is 0x110 not 0x114
- *
- * Revision 1.13  1998/09/24 14:42:56  malthoff
- * Split the RX_MFF_TST into RX_MFF_CTRL2,
- * RX_MFF_TST1, and RX_MFF_TST2.
- * Rename RX_MFF_CTRL to RX_MFF_CTRL1.
- * Add BMU bit CSR_SV_IDLE.
- * Add macros PHY_READ() and PHY_WRITE().
- * Rename macro SK_ADDR() to SK_HW_ADDR()
- * because of conflicts with the Address Module.
- *
- * Revision 1.12  1998/09/16 07:25:33  malthoff
- * Change the parameter order in the XM_INxx and XM_OUTxx macros,
- * to have the IoC as first parameter.
- *
- * Revision 1.11  1998/09/03 09:58:41  malthoff
- * Rework the XM_xxx macros. Use {} instead of () to
- * be compatible with SK_xxx macros which are defined
- * with {}.
- *
- * Revision 1.10  1998/09/02 11:16:39  malthoff
- * Temporary modify B2_I2C_SW to make tests with
- * the GE/ML prototype.
- *
- * Revision 1.9  1998/08/19 09:11:49  gklug
- * fix: struct are removed from c-source (see CCC)
- * add: typedefs for all structs
- *
- * Revision 1.8  1998/08/18 08:27:27  malthoff
- * Add some temporary workarounds to test GE
- * sources with the ML.
- *
- * Revision 1.7  1998/07/03 14:42:26  malthoff
- * bug fix: Correct macro XMA().
- * Add temporary workaround to access the PCI config space over I/O
- *
- * Revision 1.6  1998/06/23 11:30:36  malthoff
- * Remove ';' with ',' in macors.
- *
- * Revision 1.5  1998/06/22 14:20:57  malthoff
- * Add macro SK_ADDR(Base,Addr).
- *
- * Revision 1.4  1998/06/19 13:35:43  malthoff
- * change 'pGec' with 'pAC'
- *
- * Revision 1.3  1998/06/17 14:58:16  cvs
- * Lost keywords reinserted.
- *
- * Revision 1.1  1998/06/17 14:16:36  cvs
- * created
- *
- *
- ******************************************************************************/
-
-#ifndef __INC_SKGEHW_H
-#define __INC_SKGEHW_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* defines ********************************************************************/
-
-#define BIT_31         (1UL << 31)
-#define BIT_30         (1L << 30)
-#define BIT_29         (1L << 29)
-#define BIT_28         (1L << 28)
-#define BIT_27         (1L << 27)
-#define BIT_26         (1L << 26)
-#define BIT_25         (1L << 25)
-#define BIT_24         (1L << 24)
-#define BIT_23         (1L << 23)
-#define BIT_22         (1L << 22)
-#define BIT_21         (1L << 21)
-#define BIT_20         (1L << 20)
-#define BIT_19         (1L << 19)
-#define BIT_18         (1L << 18)
-#define BIT_17         (1L << 17)
-#define BIT_16         (1L << 16)
-#define BIT_15         (1L << 15)
-#define BIT_14         (1L << 14)
-#define BIT_13         (1L << 13)
-#define BIT_12         (1L << 12)
-#define BIT_11         (1L << 11)
-#define BIT_10         (1L << 10)
-#define BIT_9          (1L << 9)
-#define BIT_8          (1L << 8)
-#define BIT_7          (1L << 7)
-#define BIT_6          (1L << 6)
-#define BIT_5          (1L << 5)
-#define BIT_4          (1L << 4)
-#define BIT_3          (1L << 3)
-#define BIT_2          (1L << 2)
-#define BIT_1          (1L << 1)
-#define BIT_0          1L
-
-#define BIT_15S                (1U << 15)
-#define BIT_14S                (1 << 14)
-#define BIT_13S                (1 << 13)
-#define BIT_12S                (1 << 12)
-#define BIT_11S                (1 << 11)
-#define BIT_10S                (1 << 10)
-#define BIT_9S         (1 << 9)
-#define BIT_8S         (1 << 8)
-#define BIT_7S                 (1 << 7)
-#define BIT_6S         (1 << 6)
-#define BIT_5S         (1 << 5)
-#define BIT_4S         (1 << 4)
-#define BIT_3S         (1 << 3)
-#define BIT_2S         (1 << 2)
-#define BIT_1S         (1 << 1)
-#define BIT_0S         1
-
-#define SHIFT31(x)     ((x) << 31)
-#define SHIFT30(x)     ((x) << 30)
-#define SHIFT29(x)     ((x) << 29)
-#define SHIFT28(x)     ((x) << 28)
-#define SHIFT27(x)     ((x) << 27)
-#define SHIFT26(x)     ((x) << 26)
-#define SHIFT25(x)     ((x) << 25)
-#define SHIFT24(x)     ((x) << 24)
-#define SHIFT23(x)     ((x) << 23)
-#define SHIFT22(x)     ((x) << 22)
-#define SHIFT21(x)     ((x) << 21)
-#define SHIFT20(x)     ((x) << 20)
-#define SHIFT19(x)     ((x) << 19)
-#define SHIFT18(x)     ((x) << 18)
-#define SHIFT17(x)     ((x) << 17)
-#define SHIFT16(x)     ((x) << 16)
-#define SHIFT15(x)     ((x) << 15)
-#define SHIFT14(x)     ((x) << 14)
-#define SHIFT13(x)     ((x) << 13)
-#define SHIFT12(x)     ((x) << 12)
-#define SHIFT11(x)     ((x) << 11)
-#define SHIFT10(x)     ((x) << 10)
-#define SHIFT9(x)      ((x) << 9)
-#define SHIFT8(x)      ((x) << 8)
-#define SHIFT7(x)      ((x) << 7)
-#define SHIFT6(x)      ((x) << 6)
-#define SHIFT5(x)      ((x) << 5)
-#define SHIFT4(x)      ((x) << 4)
-#define SHIFT3(x)      ((x) << 3)
-#define SHIFT2(x)      ((x) << 2)
-#define SHIFT1(x)      ((x) << 1)
-#define SHIFT0(x)      ((x) << 0)
-
-/*
- * Configuration Space header
- * Since this module is used for different OS', those may be
- * duplicate on some of them (e.g. Linux). But to keep the
- * common source, we have to live with this...
- */
-#define PCI_VENDOR_ID  0x00    /* 16 bit       Vendor ID */
-#define PCI_DEVICE_ID  0x02    /* 16 bit       Device ID */
-#define PCI_COMMAND            0x04    /* 16 bit       Command */
-#define PCI_STATUS             0x06    /* 16 bit       Status */
-#define PCI_REV_ID             0x08    /*  8 bit       Revision ID */
-#if 0
-#define PCI_CLASS_CODE 0x09    /* 24 bit       Class Code */
-#endif
-#define PCI_CACHE_LSZ  0x0c    /*  8 bit       Cache Line Size */
-#define PCI_LAT_TIM            0x0d    /*  8 bit       Latency Timer */
-#define PCI_HEADER_T   0x0e    /*  8 bit       Header Type */
-#define PCI_BIST               0x0f    /*  8 bit       Built-in selftest */
-#define PCI_BASE_1ST   0x10    /* 32 bit       1st Base address */
-#define PCI_BASE_2ND   0x14    /* 32 bit       2nd Base address */
-       /* Byte 0x18..0x2b:     reserved */
-#define PCI_SUB_VID            0x2c    /* 16 bit       Subsystem Vendor ID */
-#define PCI_SUB_ID             0x2e    /* 16 bit       Subsystem ID */
-#define PCI_BASE_ROM   0x30    /* 32 bit       Expansion ROM Base Address */
-#define PCI_CAP_PTR            0x34    /*  8 bit       Capabilities Ptr */
-       /* Byte 35..3b: reserved */
-#define PCI_IRQ_LINE   0x3c    /*  8 bit       Interrupt Line */
-#define PCI_IRQ_PIN            0x3d    /*  8 bit       Interrupt Pin */
-#define PCI_MIN_GNT            0x3e    /*  8 bit       Min_Gnt */
-#define PCI_MAX_LAT            0x3f    /*  8 bit       Max_Lat */
-       /* Device Dependent Region */
-#define PCI_OUR_REG_1  0x40    /* 32 bit       Our Register 1 */
-#define PCI_OUR_REG_2  0x44    /* 32 bit       Our Register 2 */
-       /* Power Management Region */
-#define PCI_PM_CAP_ID  0x48    /*  8 bit       Power Management Cap. ID */
-#define PCI_PM_NITEM   0x49    /*  8 bit       Next Item Ptr */
-#define PCI_PM_CAP_REG 0x4a    /* 16 bit       Power Management Capabilities */
-#define PCI_PM_CTL_STS 0x4c    /* 16 bit       Power Manag. Control/Status */
-       /* Byte 0x4e:   reserved */
-#define PCI_PM_DAT_REG 0x4f    /*  8 bit       Power Manag. Data Register */
-       /* VPD Region */
-#define PCI_VPD_CAP_ID 0x50    /*  8 bit       VPD Cap. ID */
-#define PCI_VPD_NITEM  0x51    /*  8 bit       Next Item Ptr */
-#define PCI_VPD_ADR_REG        0x52    /* 16 bit       VPD Address Register */
-#define PCI_VPD_DAT_REG        0x54    /* 32 bit       VPD Data Register */
-       /* Byte 0x58..0xff:     reserved */
-
-/*
- * I2C Address (PCI Config)
- *
- * Note: The temperature and voltage sensors are relocated on a different
- *      I2C bus.
- */
-#define I2C_ADDR_VPD   0xA0    /* I2C address for the VPD EEPROM */
-
-/*
- * Define Bits and Values of the registers
- */
-/*     PCI_COMMAND     16 bit  Command */
-                                                               /* Bit 15..11:  reserved */
-#define PCI_INT_DIS            BIT_10S         /* Interrupt INTx# disable (PCI 2.3) */
-#define PCI_FBTEN              BIT_9S          /* Fast Back-To-Back enable */
-#define PCI_SERREN             BIT_8S          /* SERR enable */
-#define PCI_ADSTEP             BIT_7S          /* Address Stepping */
-#define PCI_PERREN             BIT_6S          /* Parity Report Response enable */
-#define PCI_VGA_SNOOP  BIT_5S          /* VGA palette snoop */
-#define PCI_MWIEN              BIT_4S          /* Memory write an inv cycl ena */
-#define PCI_SCYCEN             BIT_3S          /* Special Cycle enable */
-#define PCI_BMEN               BIT_2S          /* Bus Master enable */
-#define PCI_MEMEN              BIT_1S          /* Memory Space Access enable */
-#define PCI_IOEN               BIT_0S          /* I/O Space Access enable */
-
-#define PCI_COMMAND_VAL        (PCI_FBTEN | PCI_SERREN | PCI_PERREN | PCI_MWIEN |\
-                                                PCI_BMEN | PCI_MEMEN | PCI_IOEN)
-
-/*     PCI_STATUS      16 bit  Status */
-#define PCI_PERR               BIT_15S         /* Parity Error */
-#define PCI_SERR               BIT_14S         /* Signaled SERR */
-#define PCI_RMABORT            BIT_13S         /* Received Master Abort */
-#define PCI_RTABORT            BIT_12S         /* Received Target Abort */
-                                                               /* Bit 11:      reserved */
-#define PCI_DEVSEL             (3<<9)          /* Bit 10.. 9:  DEVSEL Timing */
-#define PCI_DEV_FAST   (0<<9)          /*              fast */
-#define PCI_DEV_MEDIUM (1<<9)          /*              medium */
-#define PCI_DEV_SLOW   (2<<9)          /*              slow */
-#define PCI_DATAPERR   BIT_8S          /* DATA Parity error detected */
-#define PCI_FB2BCAP            BIT_7S          /* Fast Back-to-Back Capability */
-#define PCI_UDF                        BIT_6S          /* User Defined Features */
-#define PCI_66MHZCAP   BIT_5S          /* 66 MHz PCI bus clock capable */
-#define PCI_NEWCAP             BIT_4S          /* New cap. list implemented */
-#define PCI_INT_STAT   BIT_3S          /* Interrupt INTx# Status (PCI 2.3) */
-                                                               /* Bit  2.. 0:  reserved */
-
-#define PCI_ERRBITS    (PCI_PERR | PCI_SERR | PCI_RMABORT | PCI_RTABORT |\
-                       PCI_DATAPERR)
-
-/*     PCI_CLASS_CODE  24 bit  Class Code */
-/*     Byte 2:         Base Class              (02) */
-/*     Byte 1:         SubClass                (00) */
-/*     Byte 0:         Programming Interface   (00) */
-
-/*     PCI_CACHE_LSZ   8 bit   Cache Line Size */
-/*     Possible values: 0,2,4,8,16,32,64,128   */
-
-/*     PCI_HEADER_T    8 bit   Header Type */
-#define PCI_HD_MF_DEV  BIT_7S  /* 0= single, 1= multi-func dev */
-#define PCI_HD_TYPE            0x7f    /* Bit 6..0:    Header Layout 0= normal */
-
-/*     PCI_BIST        8 bit   Built-in selftest */
-/*     Built-in Self test not supported (optional) */
-
-/*     PCI_BASE_1ST    32 bit  1st Base address */
-#define PCI_MEMSIZE            0x4000L         /* use 16 kB Memory Base */
-#define PCI_MEMBASE_MSK 0xffffc000L    /* Bit 31..14:  Memory Base Address */
-#define PCI_MEMSIZE_MSK 0x00003ff0L    /* Bit 13.. 4:  Memory Size Req. */
-#define PCI_PREFEN             BIT_3           /* Prefetchable */
-#define PCI_MEM_TYP            (3L<<2)         /* Bit  2.. 1:  Memory Type */
-#define PCI_MEM32BIT   (0L<<1)         /* Base addr anywhere in 32 Bit range */
-#define PCI_MEM1M              (1L<<1)         /* Base addr below 1 MegaByte */
-#define PCI_MEM64BIT   (2L<<1)         /* Base addr anywhere in 64 Bit range */
-#define PCI_MEMSPACE   BIT_0           /* Memory Space Indic. */
-
-/*     PCI_BASE_2ND    32 bit  2nd Base address */
-#define PCI_IOBASE             0xffffff00L     /* Bit 31.. 8:  I/O Base address */
-#define PCI_IOSIZE             0x000000fcL     /* Bit  7.. 2:  I/O Size Requirements */
-                                                                       /* Bit  1:      reserved */
-#define PCI_IOSPACE            BIT_0           /* I/O Space Indicator */
-
-/*     PCI_BASE_ROM    32 bit  Expansion ROM Base Address */
-#define PCI_ROMBASE            0xfffe0000L     /* Bit 31..17:  ROM BASE address (1st)*/
-#define PCI_ROMBASZ            (0x1cL<<14)     /* Bit 16..14:  Treat as BASE or SIZE */
-#define PCI_ROMSIZE            (0x38L<<11)     /* Bit 13..11:  ROM Size Requirements */
-                                                                       /* Bit 10.. 1:  reserved */
-#define PCI_ROMEN              BIT_0           /* Address Decode enable */
-
-/* Device Dependent Region */
-/*     PCI_OUR_REG_1           32 bit  Our Register 1 */
-                                                                       /* Bit 31..29:  reserved */
-#define PCI_PHY_COMA   BIT_28          /* Set PHY to Coma Mode */
-#define PCI_EN_CAL             BIT_27          /* Enable  PCI buffer strength calibr. */
-#define PCI_DIS_CAL            BIT_26          /* Disable PCI buffer strength calibr. */
-#define PCI_VIO                        BIT_25          /* PCI I/O Voltage, 0 = 3.3V, 1 = 5V */
-#define PCI_DIS_BOOT   BIT_24          /* Disable BOOT via ROM */
-#define PCI_EN_IO              BIT_23          /* Mapping to I/O space */
-#define PCI_EN_FPROM   BIT_22          /* Enable FLASH mapping to memory */
-                                                                       /*              1 = Map Flash to memory */
-                                                                       /*              0 = Disable addr. dec */
-#define PCI_PAGESIZE   (3L<<20)        /* Bit 21..20:  FLASH Page Size */
-#define PCI_PAGE_16            (0L<<20)        /*              16 k pages      */
-#define PCI_PAGE_32K   (1L<<20)        /*              32 k pages      */
-#define PCI_PAGE_64K   (2L<<20)        /*              64 k pages      */
-#define PCI_PAGE_128K  (3L<<20)        /*              128 k pages     */
-                                                                       /* Bit 19:      reserved        */
-#define PCI_PAGEREG            (7L<<16)        /* Bit 18..16:  Page Register   */
-#define PCI_NOTAR              BIT_15          /* No turnaround cycle */
-#define PCI_FORCE_BE   BIT_14          /* Assert all BEs on MR */
-#define PCI_DIS_MRL            BIT_13          /* Disable Mem Read Line */
-#define PCI_DIS_MRM            BIT_12          /* Disable Mem Read Multiple */
-#define PCI_DIS_MWI            BIT_11          /* Disable Mem Write & Invalidate */
-#define PCI_DISC_CLS   BIT_10          /* Disc: cacheLsz bound */
-#define PCI_BURST_DIS  BIT_9           /* Burst Disable */
-#define PCI_DIS_PCI_CLK        BIT_8           /* Disable PCI clock driving */
-#define PCI_SKEW_DAS   (0xfL<<4)       /* Bit  7.. 4:  Skew Ctrl, DAS Ext */
-#define PCI_SKEW_BASE  0xfL            /* Bit  3.. 0:  Skew Ctrl, Base */
-
-
-/*     PCI_OUR_REG_2           32 bit  Our Register 2 */
-#define PCI_VPD_WR_THR (0xffL<<24)     /* Bit 31..24:  VPD Write Threshold */
-#define PCI_DEV_SEL            (0x7fL<<17)     /* Bit 23..17:  EEPROM Device Select */
-#define PCI_VPD_ROM_SZ (7L<<14)        /* Bit 16..14:  VPD ROM Size    */
-                                                                       /* Bit 13..12:  reserved        */
-#define PCI_PATCH_DIR  (0xfL<<8)       /* Bit 11.. 8:  Ext Patches dir 3..0 */
-#define PCI_PATCH_DIR_3        BIT_11
-#define PCI_PATCH_DIR_2        BIT_10
-#define PCI_PATCH_DIR_1        BIT_9
-#define PCI_PATCH_DIR_0        BIT_8
-#define PCI_EXT_PATCHS (0xfL<<4)       /* Bit  7.. 4:  Extended Patches 3..0 */
-#define PCI_EXT_PATCH_3        BIT_7
-#define PCI_EXT_PATCH_2        BIT_6
-#define PCI_EXT_PATCH_1        BIT_5
-#define PCI_EXT_PATCH_0        BIT_4
-#define PCI_EN_DUMMY_RD        BIT_3           /* Enable Dummy Read */
-#define PCI_REV_DESC   BIT_2           /* Reverse Desc. Bytes */
-                                                                       /* Bit  1:      reserved */
-#define PCI_USEDATA64  BIT_0           /* Use 64Bit Data bus ext */
-
-
-/* Power Management Region */
-/*     PCI_PM_CAP_REG          16 bit  Power Management Capabilities */
-#define PCI_PME_SUP_MSK        (0x1f<<11)      /* Bit 15..11:  PM Event Support Mask */
-#define PCI_PME_D3C_SUP        BIT_15S         /* PME from D3cold Support (if Vaux) */
-#define PCI_PME_D3H_SUP        BIT_14S         /* PME from D3hot Support */
-#define PCI_PME_D2_SUP BIT_13S         /* PME from D2 Support */
-#define PCI_PME_D1_SUP BIT_12S         /* PME from D1 Support */
-#define PCI_PME_D0_SUP BIT_11S         /* PME from D0 Support */
-#define PCI_PM_D2_SUP  BIT_10S         /* D2 Support in 33 MHz mode */
-#define PCI_PM_D1_SUP  BIT_9S          /* D1 Support */
-                                                                       /* Bit  8.. 6:  reserved */
-#define PCI_PM_DSI             BIT_5S          /* Device Specific Initialization */
-#define PCI_PM_APS             BIT_4S          /* Auxialiary Power Source */
-#define PCI_PME_CLOCK  BIT_3S          /* PM Event Clock */
-#define PCI_PM_VER_MSK         7               /* Bit  2.. 0:  PM PCI Spec. version */
-
-/*     PCI_PM_CTL_STS          16 bit  Power Management Control/Status */
-#define PCI_PME_STATUS BIT_15S         /* PME Status (YUKON only) */
-#define PCI_PM_DAT_SCL (3<<13)         /* Bit 14..13:  Data Reg. scaling factor */
-#define PCI_PM_DAT_SEL (0xf<<9)        /* Bit 12.. 9:  PM data selector field */
-#define PCI_PME_EN             BIT_8S          /* Enable PME# generation (YUKON only) */
-                                                                       /* Bit  7.. 2:  reserved */
-#define PCI_PM_STATE_MSK       3               /* Bit  1.. 0:  Power Management State */
-
-#define PCI_PM_STATE_D0                0               /* D0:  Operational (default) */
-#define PCI_PM_STATE_D1                1               /* D1:  (YUKON only) */
-#define PCI_PM_STATE_D2                2               /* D2:  (YUKON only) */
-#define PCI_PM_STATE_D3        3               /* D3:  HOT, Power Down and Reset */
-
-/* VPD Region */
-/*     PCI_VPD_ADR_REG         16 bit  VPD Address Register */
-#define PCI_VPD_FLAG   BIT_15S         /* starts VPD rd/wr cycle */
-#define PCI_VPD_ADR_MSK        0x7fffL         /* Bit 14.. 0:  VPD address mask */
-
-/*     Control Register File (Address Map) */
-
-/*
- *     Bank 0
- */
-#define B0_RAP                 0x0000  /*  8 bit       Register Address Port */
-       /* 0x0001 - 0x0003:     reserved */
-#define B0_CTST                        0x0004  /* 16 bit       Control/Status register */
-#define B0_LED                 0x0006  /*  8 Bit       LED register */
-#define B0_POWER_CTRL  0x0007  /*  8 Bit       Power Control reg (YUKON only) */
-#define B0_ISRC                        0x0008  /* 32 bit       Interrupt Source Register */
-#define B0_IMSK                        0x000c  /* 32 bit       Interrupt Mask Register */
-#define B0_HWE_ISRC            0x0010  /* 32 bit       HW Error Interrupt Src Reg */
-#define B0_HWE_IMSK            0x0014  /* 32 bit       HW Error Interrupt Mask Reg */
-#define B0_SP_ISRC             0x0018  /* 32 bit       Special Interrupt Source Reg */
-       /* 0x001c:              reserved */
-
-/* B0 XMAC 1 registers (GENESIS only) */
-#define B0_XM1_IMSK            0x0020  /* 16 bit r/w   XMAC 1 Interrupt Mask Register*/
-       /* 0x0022 - 0x0027:     reserved */
-#define B0_XM1_ISRC            0x0028  /* 16 bit ro    XMAC 1 Interrupt Status Reg */
-       /* 0x002a - 0x002f:     reserved */
-#define B0_XM1_PHY_ADDR 0x0030 /* 16 bit r/w   XMAC 1 PHY Address Register */
-       /* 0x0032 - 0x0033:     reserved */
-#define B0_XM1_PHY_DATA 0x0034 /* 16 bit r/w   XMAC 1 PHY Data Register */
-       /* 0x0036 - 0x003f:     reserved */
-
-/* B0 XMAC 2 registers (GENESIS only) */
-#define B0_XM2_IMSK            0x0040  /* 16 bit r/w   XMAC 2 Interrupt Mask Register*/
-       /* 0x0042 - 0x0047:     reserved */
-#define B0_XM2_ISRC            0x0048  /* 16 bit ro    XMAC 2 Interrupt Status Reg */
-       /* 0x004a - 0x004f:     reserved */
-#define B0_XM2_PHY_ADDR 0x0050 /* 16 bit r/w   XMAC 2 PHY Address Register */
-       /* 0x0052 - 0x0053:     reserved */
-#define B0_XM2_PHY_DATA 0x0054 /* 16 bit r/w   XMAC 2 PHY Data Register */
-       /* 0x0056 - 0x005f:     reserved */
-
-/* BMU Control Status Registers */
-#define B0_R1_CSR              0x0060  /* 32 bit       BMU Ctrl/Stat Rx Queue 1 */
-#define B0_R2_CSR              0x0064  /* 32 bit       BMU Ctrl/Stat Rx Queue 2 */
-#define B0_XS1_CSR             0x0068  /* 32 bit       BMU Ctrl/Stat Sync Tx Queue 1 */
-#define B0_XA1_CSR             0x006c  /* 32 bit       BMU Ctrl/Stat Async Tx Queue 1*/
-#define B0_XS2_CSR             0x0070  /* 32 bit       BMU Ctrl/Stat Sync Tx Queue 2 */
-#define B0_XA2_CSR             0x0074  /* 32 bit       BMU Ctrl/Stat Async Tx Queue 2*/
-       /* 0x0078 - 0x007f:     reserved */
-
-/*
- *     Bank 1
- *     - completely empty (this is the RAP Block window)
- *     Note: if RAP = 1 this page is reserved
- */
-
-/*
- *     Bank 2
- */
-/* NA reg = 48 bit Network Address Register, 3x16 or 8x8 bit readable */
-#define B2_MAC_1               0x0100  /* NA reg        MAC Address 1 */
-       /* 0x0106 - 0x0107:     reserved */
-#define B2_MAC_2               0x0108  /* NA reg        MAC Address 2 */
-       /* 0x010e - 0x010f:     reserved */
-#define B2_MAC_3               0x0110  /* NA reg        MAC Address 3 */
-       /* 0x0116 - 0x0117:     reserved */
-#define B2_CONN_TYP            0x0118  /*  8 bit       Connector type */
-#define B2_PMD_TYP             0x0119  /*  8 bit       PMD type */
-#define B2_MAC_CFG             0x011a  /*  8 bit       MAC Configuration / Chip Revision */
-#define B2_CHIP_ID             0x011b  /*  8 bit       Chip Identification Number */
-       /* Eprom registers are currently of no use */
-#define B2_E_0                 0x011c  /*  8 bit       EPROM Byte 0 (ext. SRAM size */
-#define B2_E_1                 0x011d  /*  8 bit       EPROM Byte 1 (PHY type) */
-#define B2_E_2                 0x011e  /*  8 bit       EPROM Byte 2 */
-#define B2_E_3                 0x011f  /*  8 bit       EPROM Byte 3 */
-#define B2_FAR                 0x0120  /* 32 bit       Flash-Prom Addr Reg/Cnt */
-#define B2_FDP                 0x0124  /*  8 bit       Flash-Prom Data Port */
-       /* 0x0125 - 0x0127:     reserved */
-#define B2_LD_CRTL             0x0128  /*  8 bit       EPROM loader control register */
-#define B2_LD_TEST             0x0129  /*  8 bit       EPROM loader test register */
-       /* 0x012a - 0x012f:     reserved */
-#define B2_TI_INI              0x0130  /* 32 bit       Timer Init Value */
-#define B2_TI_VAL              0x0134  /* 32 bit       Timer Value */
-#define B2_TI_CRTL             0x0138  /*  8 bit       Timer Control */
-#define B2_TI_TEST             0x0139  /*  8 Bit       Timer Test */
-       /* 0x013a - 0x013f:     reserved */
-#define B2_IRQM_INI            0x0140  /* 32 bit       IRQ Moderation Timer Init Reg.*/
-#define B2_IRQM_VAL            0x0144  /* 32 bit       IRQ Moderation Timer Value */
-#define B2_IRQM_CTRL   0x0148  /*  8 bit       IRQ Moderation Timer Control */
-#define B2_IRQM_TEST   0x0149  /*  8 bit       IRQ Moderation Timer Test */
-#define B2_IRQM_MSK    0x014c  /* 32 bit       IRQ Moderation Mask */
-#define B2_IRQM_HWE_MSK 0x0150 /* 32 bit       IRQ Moderation HW Error Mask */
-       /* 0x0154 - 0x0157:     reserved */
-#define B2_TST_CTRL1   0x0158  /*  8 bit       Test Control Register 1 */
-#define B2_TST_CTRL2   0x0159  /*  8 bit       Test Control Register 2 */
-       /* 0x015a - 0x015b:     reserved */
-#define B2_GP_IO               0x015c  /* 32 bit       General Purpose I/O Register */
-#define B2_I2C_CTRL            0x0160  /* 32 bit       I2C HW Control Register */
-#define B2_I2C_DATA            0x0164  /* 32 bit       I2C HW Data Register */
-#define B2_I2C_IRQ             0x0168  /* 32 bit       I2C HW IRQ Register */
-#define B2_I2C_SW              0x016c  /* 32 bit       I2C SW Port Register */
-
-/* Blink Source Counter (GENESIS only) */
-#define B2_BSC_INI             0x0170  /* 32 bit       Blink Source Counter Init Val */
-#define B2_BSC_VAL             0x0174  /* 32 bit       Blink Source Counter Value */
-#define B2_BSC_CTRL            0x0178  /*  8 bit       Blink Source Counter Control */
-#define B2_BSC_STAT            0x0179  /*  8 bit       Blink Source Counter Status */
-#define B2_BSC_TST             0x017a  /* 16 bit       Blink Source Counter Test Reg */
-       /* 0x017c - 0x017f:     reserved */
-
-/*
- *     Bank 3
- */
-/* RAM Random Registers */
-#define B3_RAM_ADDR            0x0180  /* 32 bit       RAM Address, to read or write */
-#define B3_RAM_DATA_LO 0x0184  /* 32 bit       RAM Data Word (low dWord) */
-#define B3_RAM_DATA_HI 0x0188  /* 32 bit       RAM Data Word (high dWord) */
-       /* 0x018c - 0x018f:     reserved */
-
-/* RAM Interface Registers */
-/*
- * The HW-Spec. calls this registers Timeout Value 0..11. But this names are
- * not usable in SW. Please notice these are NOT real timeouts, these are
- * the number of qWords transferred continuously.
- */
-#define B3_RI_WTO_R1   0x0190  /*  8 bit       WR Timeout Queue R1             (TO0) */
-#define B3_RI_WTO_XA1  0x0191  /*  8 bit       WR Timeout Queue XA1    (TO1) */
-#define B3_RI_WTO_XS1  0x0192  /*  8 bit       WR Timeout Queue XS1    (TO2) */
-#define B3_RI_RTO_R1   0x0193  /*  8 bit       RD Timeout Queue R1             (TO3) */
-#define B3_RI_RTO_XA1  0x0194  /*  8 bit       RD Timeout Queue XA1    (TO4) */
-#define B3_RI_RTO_XS1  0x0195  /*  8 bit       RD Timeout Queue XS1    (TO5) */
-#define B3_RI_WTO_R2   0x0196  /*  8 bit       WR Timeout Queue R2             (TO6) */
-#define B3_RI_WTO_XA2  0x0197  /*  8 bit       WR Timeout Queue XA2    (TO7) */
-#define B3_RI_WTO_XS2  0x0198  /*  8 bit       WR Timeout Queue XS2    (TO8) */
-#define B3_RI_RTO_R2   0x0199  /*  8 bit       RD Timeout Queue R2             (TO9) */
-#define B3_RI_RTO_XA2  0x019a  /*  8 bit       RD Timeout Queue XA2    (TO10)*/
-#define B3_RI_RTO_XS2  0x019b  /*  8 bit       RD Timeout Queue XS2    (TO11)*/
-#define B3_RI_TO_VAL   0x019c  /*  8 bit       Current Timeout Count Val */
-       /* 0x019d - 0x019f:     reserved */
-#define B3_RI_CTRL             0x01a0  /* 16 bit       RAM Interface Control Register */
-#define B3_RI_TEST             0x01a2  /*  8 bit       RAM Interface Test Register */
-       /* 0x01a3 - 0x01af:     reserved */
-
-/* MAC Arbiter Registers (GENESIS only) */
-/* these are the no. of qWord transferred continuously and NOT real timeouts */
-#define B3_MA_TOINI_RX1        0x01b0  /*  8 bit       Timeout Init Val Rx Path MAC 1 */
-#define B3_MA_TOINI_RX2        0x01b1  /*  8 bit       Timeout Init Val Rx Path MAC 2 */
-#define B3_MA_TOINI_TX1        0x01b2  /*  8 bit       Timeout Init Val Tx Path MAC 1 */
-#define B3_MA_TOINI_TX2        0x01b3  /*  8 bit       Timeout Init Val Tx Path MAC 2 */
-#define B3_MA_TOVAL_RX1        0x01b4  /*  8 bit       Timeout Value Rx Path MAC 1 */
-#define B3_MA_TOVAL_RX2        0x01b5  /*  8 bit       Timeout Value Rx Path MAC 1 */
-#define B3_MA_TOVAL_TX1        0x01b6  /*  8 bit       Timeout Value Tx Path MAC 2 */
-#define B3_MA_TOVAL_TX2        0x01b7  /*  8 bit       Timeout Value Tx Path MAC 2 */
-#define B3_MA_TO_CTRL  0x01b8  /* 16 bit       MAC Arbiter Timeout Ctrl Reg */
-#define B3_MA_TO_TEST  0x01ba  /* 16 bit       MAC Arbiter Timeout Test Reg */
-       /* 0x01bc - 0x01bf:     reserved */
-#define B3_MA_RCINI_RX1        0x01c0  /*  8 bit       Recovery Init Val Rx Path MAC 1 */
-#define B3_MA_RCINI_RX2        0x01c1  /*  8 bit       Recovery Init Val Rx Path MAC 2 */
-#define B3_MA_RCINI_TX1        0x01c2  /*  8 bit       Recovery Init Val Tx Path MAC 1 */
-#define B3_MA_RCINI_TX2        0x01c3  /*  8 bit       Recovery Init Val Tx Path MAC 2 */
-#define B3_MA_RCVAL_RX1        0x01c4  /*  8 bit       Recovery Value Rx Path MAC 1 */
-#define B3_MA_RCVAL_RX2        0x01c5  /*  8 bit       Recovery Value Rx Path MAC 1 */
-#define B3_MA_RCVAL_TX1        0x01c6  /*  8 bit       Recovery Value Tx Path MAC 2 */
-#define B3_MA_RCVAL_TX2        0x01c7  /*  8 bit       Recovery Value Tx Path MAC 2 */
-#define B3_MA_RC_CTRL  0x01c8  /* 16 bit       MAC Arbiter Recovery Ctrl Reg */
-#define B3_MA_RC_TEST  0x01ca  /* 16 bit       MAC Arbiter Recovery Test Reg */
-       /* 0x01cc - 0x01cf:     reserved */
-
-/* Packet Arbiter Registers (GENESIS only) */
-/* these are real timeouts */
-#define B3_PA_TOINI_RX1        0x01d0  /* 16 bit       Timeout Init Val Rx Path MAC 1 */
-       /* 0x01d2 - 0x01d3:     reserved */
-#define B3_PA_TOINI_RX2        0x01d4  /* 16 bit       Timeout Init Val Rx Path MAC 2 */
-       /* 0x01d6 - 0x01d7:     reserved */
-#define B3_PA_TOINI_TX1        0x01d8  /* 16 bit       Timeout Init Val Tx Path MAC 1 */
-       /* 0x01da - 0x01db:     reserved */
-#define B3_PA_TOINI_TX2        0x01dc  /* 16 bit       Timeout Init Val Tx Path MAC 2 */
-       /* 0x01de - 0x01df:     reserved */
-#define B3_PA_TOVAL_RX1        0x01e0  /* 16 bit       Timeout Val Rx Path MAC 1 */
-       /* 0x01e2 - 0x01e3:     reserved */
-#define B3_PA_TOVAL_RX2        0x01e4  /* 16 bit       Timeout Val Rx Path MAC 2 */
-       /* 0x01e6 - 0x01e7:     reserved */
-#define B3_PA_TOVAL_TX1        0x01e8  /* 16 bit       Timeout Val Tx Path MAC 1 */
-       /* 0x01ea - 0x01eb:     reserved */
-#define B3_PA_TOVAL_TX2        0x01ec  /* 16 bit       Timeout Val Tx Path MAC 2 */
-       /* 0x01ee - 0x01ef:     reserved */
-#define B3_PA_CTRL     0x01f0  /* 16 bit       Packet Arbiter Ctrl Register */
-#define B3_PA_TEST     0x01f2  /* 16 bit       Packet Arbiter Test Register */
-       /* 0x01f4 - 0x01ff:     reserved */
-
-/*
- *     Bank 4 - 5
- */
-/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
-#define TXA_ITI_INI            0x0200  /* 32 bit       Tx Arb Interval Timer Init Val*/
-#define TXA_ITI_VAL            0x0204  /* 32 bit       Tx Arb Interval Timer Value */
-#define TXA_LIM_INI            0x0208  /* 32 bit       Tx Arb Limit Counter Init Val */
-#define TXA_LIM_VAL            0x020c  /* 32 bit       Tx Arb Limit Counter Value */
-#define TXA_CTRL               0x0210  /*  8 bit       Tx Arbiter Control Register */
-#define TXA_TEST               0x0211  /*  8 bit       Tx Arbiter Test Register */
-#define TXA_STAT               0x0212  /*  8 bit       Tx Arbiter Status Register */
-       /* 0x0213 - 0x027f:     reserved */
-       /* 0x0280 - 0x0292:     MAC 2 */
-       /* 0x0213 - 0x027f:     reserved */
-
-/*
- *     Bank 6
- */
-/* External registers (GENESIS only) */
-#define B6_EXT_REG             0x0300
-
-/*
- *     Bank 7
- */
-/* This is a copy of the Configuration register file (lower half) */
-#define B7_CFG_SPC             0x0380
-
-/*
- *     Bank 8 - 15
- */
-/* Receive and Transmit Queue Registers, use Q_ADDR() to access */
-#define B8_Q_REGS              0x0400
-
-/* Queue Register Offsets, use Q_ADDR() to access */
-#define Q_D            0x00    /* 8*32 bit     Current Descriptor */
-#define Q_DA_L 0x20    /* 32 bit       Current Descriptor Address Low dWord */
-#define Q_DA_H 0x24    /* 32 bit       Current Descriptor Address High dWord */
-#define Q_AC_L 0x28    /* 32 bit       Current Address Counter Low dWord */
-#define Q_AC_H 0x2c    /* 32 bit       Current Address Counter High dWord */
-#define Q_BC   0x30    /* 32 bit       Current Byte Counter */
-#define Q_CSR  0x34    /* 32 bit       BMU Control/Status Register */
-#define Q_F            0x38    /* 32 bit       Flag Register */
-#define Q_T1   0x3c    /* 32 bit       Test Register 1 */
-#define Q_T1_TR        0x3c    /*  8 bit       Test Register 1 Transfer SM */
-#define Q_T1_WR        0x3d    /*  8 bit       Test Register 1 Write Descriptor SM */
-#define Q_T1_RD        0x3e    /*  8 bit       Test Register 1 Read Descriptor SM */
-#define Q_T1_SV        0x3f    /*  8 bit       Test Register 1 Supervisor SM */
-#define Q_T2   0x40    /* 32 bit       Test Register 2 */
-#define Q_T3   0x44    /* 32 bit       Test Register 3 */
-       /* 0x48 - 0x7f: reserved */
-
-/*
- *     Bank 16 - 23
- */
-/* RAM Buffer Registers */
-#define B16_RAM_REGS   0x0800
-
-/* RAM Buffer Register Offsets, use RB_ADDR() to access */
-#define RB_START               0x00    /* 32 bit       RAM Buffer Start Address */
-#define RB_END                 0x04    /* 32 bit       RAM Buffer End Address */
-#define RB_WP                  0x08    /* 32 bit       RAM Buffer Write Pointer */
-#define RB_RP                  0x0c    /* 32 bit       RAM Buffer Read Pointer */
-#define RB_RX_UTPP             0x10    /* 32 bit       Rx Upper Threshold, Pause Pack */
-#define RB_RX_LTPP             0x14    /* 32 bit       Rx Lower Threshold, Pause Pack */
-#define RB_RX_UTHP             0x18    /* 32 bit       Rx Upper Threshold, High Prio */
-#define RB_RX_LTHP             0x1c    /* 32 bit       Rx Lower Threshold, High Prio */
-       /* 0x10 - 0x1f: reserved at Tx RAM Buffer Registers */
-#define RB_PC                  0x20    /* 32 bit       RAM Buffer Packet Counter */
-#define RB_LEV                 0x24    /* 32 bit       RAM Buffer Level Register */
-#define RB_CTRL                        0x28    /*  8 bit       RAM Buffer Control Register */
-#define RB_TST1                        0x29    /*  8 bit       RAM Buffer Test Register 1 */
-#define RB_TST2                        0x2A    /*  8 bit       RAM Buffer Test Register 2 */
-       /* 0x2c - 0x7f: reserved */
-
-/*
- *     Bank 24
- */
-/*
- * Receive MAC FIFO, Receive LED, and Link_Sync regs (GENESIS only)
- * use MR_ADDR() to access
- */
-#define RX_MFF_EA              0x0c00  /* 32 bit       Receive MAC FIFO End Address */
-#define RX_MFF_WP              0x0c04  /* 32 bit       Receive MAC FIFO Write Pointer */
-       /* 0x0c08 - 0x0c0b:     reserved */
-#define RX_MFF_RP              0x0c0c  /* 32 bit       Receive MAC FIFO Read Pointer */
-#define RX_MFF_PC              0x0c10  /* 32 bit       Receive MAC FIFO Packet Cnt */
-#define RX_MFF_LEV             0x0c14  /* 32 bit       Receive MAC FIFO Level */
-#define RX_MFF_CTRL1   0x0c18  /* 16 bit       Receive MAC FIFO Control Reg 1*/
-#define RX_MFF_STAT_TO 0x0c1a  /*  8 bit       Receive MAC Status Timeout */
-#define RX_MFF_TIST_TO 0x0c1b  /*  8 bit       Receive MAC Time Stamp Timeout */
-#define RX_MFF_CTRL2   0x0c1c  /*  8 bit       Receive MAC FIFO Control Reg 2*/
-#define RX_MFF_TST1            0x0c1d  /*  8 bit       Receive MAC FIFO Test Reg 1 */
-#define RX_MFF_TST2            0x0c1e  /*  8 bit       Receive MAC FIFO Test Reg 2 */
-       /* 0x0c1f:      reserved */
-#define RX_LED_INI             0x0c20  /* 32 bit       Receive LED Cnt Init Value */
-#define RX_LED_VAL             0x0c24  /* 32 bit       Receive LED Cnt Current Value */
-#define RX_LED_CTRL            0x0c28  /*  8 bit       Receive LED Cnt Control Reg */
-#define RX_LED_TST             0x0c29  /*  8 bit       Receive LED Cnt Test Register */
-       /* 0x0c2a - 0x0c2f:     reserved */
-#define LNK_SYNC_INI   0x0c30  /* 32 bit       Link Sync Cnt Init Value */
-#define LNK_SYNC_VAL   0x0c34  /* 32 bit       Link Sync Cnt Current Value */
-#define LNK_SYNC_CTRL  0x0c38  /*  8 bit       Link Sync Cnt Control Register */
-#define LNK_SYNC_TST   0x0c39  /*  8 bit       Link Sync Cnt Test Register */
-       /* 0x0c3a - 0x0c3b:     reserved */
-#define LNK_LED_REG            0x0c3c  /*  8 bit       Link LED Register */
-       /* 0x0c3d - 0x0c3f:     reserved */
-
-/* Receive GMAC FIFO (YUKON only), use MR_ADDR() to access */
-#define RX_GMF_EA              0x0c40  /* 32 bit       Rx GMAC FIFO End Address */
-#define RX_GMF_AF_THR  0x0c44  /* 32 bit       Rx GMAC FIFO Almost Full Thresh. */
-#define RX_GMF_CTRL_T  0x0c48  /* 32 bit       Rx GMAC FIFO Control/Test */
-#define RX_GMF_FL_MSK  0x0c4c  /* 32 bit       Rx GMAC FIFO Flush Mask */
-#define RX_GMF_FL_THR  0x0c50  /* 32 bit       Rx GMAC FIFO Flush Threshold */
-       /* 0x0c54 - 0x0c5f:     reserved */
-#define RX_GMF_WP              0x0c60  /* 32 bit       Rx GMAC FIFO Write Pointer */
-       /* 0x0c64 - 0x0c67:     reserved */
-#define RX_GMF_WLEV            0x0c68  /* 32 bit       Rx GMAC FIFO Write Level */
-       /* 0x0c6c - 0x0c6f:     reserved */
-#define RX_GMF_RP              0x0c70  /* 32 bit       Rx GMAC FIFO Read Pointer */
-       /* 0x0c74 - 0x0c77:     reserved */
-#define RX_GMF_RLEV            0x0c78  /* 32 bit       Rx GMAC FIFO Read Level */
-       /* 0x0c7c - 0x0c7f:     reserved */
-
-/*
- *     Bank 25
- */
-       /* 0x0c80 - 0x0cbf:     MAC 2 */
-       /* 0x0cc0 - 0x0cff:     reserved */
-
-/*
- *     Bank 26
- */
-/*
- * Transmit MAC FIFO and Transmit LED Registers (GENESIS only),
- * use MR_ADDR() to access
- */
-#define TX_MFF_EA              0x0d00  /* 32 bit       Transmit MAC FIFO End Address */
-#define TX_MFF_WP              0x0d04  /* 32 bit       Transmit MAC FIFO WR Pointer */
-#define TX_MFF_WSP             0x0d08  /* 32 bit       Transmit MAC FIFO WR Shadow Ptr */
-#define TX_MFF_RP              0x0d0c  /* 32 bit       Transmit MAC FIFO RD Pointer */
-#define TX_MFF_PC              0x0d10  /* 32 bit       Transmit MAC FIFO Packet Cnt */
-#define TX_MFF_LEV             0x0d14  /* 32 bit       Transmit MAC FIFO Level */
-#define TX_MFF_CTRL1   0x0d18  /* 16 bit       Transmit MAC FIFO Ctrl Reg 1 */
-#define TX_MFF_WAF             0x0d1a  /*  8 bit       Transmit MAC Wait after flush */
-       /* 0x0c1b:      reserved */
-#define TX_MFF_CTRL2   0x0d1c  /*  8 bit       Transmit MAC FIFO Ctrl Reg 2 */
-#define TX_MFF_TST1            0x0d1d  /*  8 bit       Transmit MAC FIFO Test Reg 1 */
-#define TX_MFF_TST2            0x0d1e  /*  8 bit       Transmit MAC FIFO Test Reg 2 */
-       /* 0x0d1f:      reserved */
-#define TX_LED_INI             0x0d20  /* 32 bit       Transmit LED Cnt Init Value */
-#define TX_LED_VAL             0x0d24  /* 32 bit       Transmit LED Cnt Current Val */
-#define TX_LED_CTRL            0x0d28  /*  8 bit       Transmit LED Cnt Control Reg */
-#define TX_LED_TST             0x0d29  /*  8 bit       Transmit LED Cnt Test Reg */
-       /* 0x0d2a - 0x0d3f:     reserved */
-
-/* Transmit GMAC FIFO (YUKON only), use MR_ADDR() to access */
-#define TX_GMF_EA              0x0d40  /* 32 bit       Tx GMAC FIFO End Address */
-#define TX_GMF_AE_THR  0x0d44  /* 32 bit       Tx GMAC FIFO Almost Empty Thresh.*/
-#define TX_GMF_CTRL_T  0x0d48  /* 32 bit       Tx GMAC FIFO Control/Test */
-       /* 0x0d4c - 0x0d5f:     reserved */
-#define TX_GMF_WP              0x0d60  /* 32 bit       Tx GMAC FIFO Write Pointer */
-#define TX_GMF_WSP             0x0d64  /* 32 bit       Tx GMAC FIFO Write Shadow Ptr. */
-#define TX_GMF_WLEV            0x0d68  /* 32 bit       Tx GMAC FIFO Write Level */
-       /* 0x0d6c - 0x0d6f:     reserved */
-#define TX_GMF_RP              0x0d70  /* 32 bit       Tx GMAC FIFO Read Pointer */
-#define TX_GMF_RSTP            0x0d74  /* 32 bit       Tx GMAC FIFO Restart Pointer */
-#define TX_GMF_RLEV            0x0d78  /* 32 bit       Tx GMAC FIFO Read Level */
-       /* 0x0d7c - 0x0d7f:     reserved */
-
-/*
- *     Bank 27
- */
-       /* 0x0d80 - 0x0dbf:     MAC 2 */
-       /* 0x0daa - 0x0dff:     reserved */
-
-/*
- *     Bank 28
- */
-/* Descriptor Poll Timer Registers */
-#define B28_DPT_INI            0x0e00  /* 24 bit       Descriptor Poll Timer Init Val */
-#define B28_DPT_VAL            0x0e04  /* 24 bit       Descriptor Poll Timer Curr Val */
-#define B28_DPT_CTRL   0x0e08  /*  8 bit       Descriptor Poll Timer Ctrl Reg */
-       /* 0x0e09:      reserved */
-#define B28_DPT_TST            0x0e0a  /*  8 bit       Descriptor Poll Timer Test Reg */
-       /* 0x0e0b:      reserved */
-
-/* Time Stamp Timer Registers (YUKON only) */
-       /* 0x0e10:      reserved */
-#define GMAC_TI_ST_VAL 0x0e14  /* 32 bit       Time Stamp Timer Curr Val */
-#define GMAC_TI_ST_CTRL        0x0e18  /*  8 bit       Time Stamp Timer Ctrl Reg */
-       /* 0x0e19:      reserved */
-#define GMAC_TI_ST_TST 0x0e1a  /*  8 bit       Time Stamp Timer Test Reg */
-       /* 0x0e1b - 0x0e7f:     reserved */
-
-/*
- *     Bank 29
- */
-       /* 0x0e80 - 0x0efc:     reserved */
-
-/*
- *     Bank 30
- */
-/* GMAC and GPHY Control Registers (YUKON only) */
-#define GMAC_CTRL              0x0f00  /* 32 bit       GMAC Control Reg */
-#define GPHY_CTRL              0x0f04  /* 32 bit       GPHY Control Reg */
-#define GMAC_IRQ_SRC   0x0f08  /*  8 bit       GMAC Interrupt Source Reg */
-       /* 0x0f09 - 0x0f0b:     reserved */
-#define GMAC_IRQ_MSK   0x0f0c  /*  8 bit       GMAC Interrupt Mask Reg */
-       /* 0x0f0d - 0x0f0f:     reserved */
-#define GMAC_LINK_CTRL 0x0f10  /* 16 bit       Link Control Reg */
-       /* 0x0f14 - 0x0f1f:     reserved */
-
-/* Wake-up Frame Pattern Match Control Registers (YUKON only) */
-
-#define WOL_REG_OFFS   0x20    /* HW-Bug: Address is + 0x20 against spec. */
-
-#define WOL_CTRL_STAT  0x0f20  /* 16 bit       WOL Control/Status Reg */
-#define WOL_MATCH_CTL  0x0f22  /*  8 bit       WOL Match Control Reg */
-#define WOL_MATCH_RES  0x0f23  /*  8 bit       WOL Match Result Reg */
-#define WOL_MAC_ADDR_LO        0x0f24  /* 32 bit       WOL MAC Address Low */
-#define WOL_MAC_ADDR_HI        0x0f28  /* 16 bit       WOL MAC Address High */
-#define WOL_PATT_RPTR  0x0f2c  /*  8 bit       WOL Pattern Read Ptr */
-
-/* use this macro to access above registers */
-#define WOL_REG(Reg)   ((Reg) + (pAC->GIni.GIWolOffs))
-
-
-/* WOL Pattern Length Registers (YUKON only) */
-
-#define WOL_PATT_LEN_LO        0x0f30          /* 32 bit       WOL Pattern Length 3..0 */
-#define WOL_PATT_LEN_HI        0x0f34          /* 24 bit       WOL Pattern Length 6..4 */
-
-/* WOL Pattern Counter Registers (YUKON only) */
-
-#define WOL_PATT_CNT_0 0x0f38          /* 32 bit       WOL Pattern Counter 3..0 */
-#define WOL_PATT_CNT_4 0x0f3c          /* 24 bit       WOL Pattern Counter 6..4 */
-       /* 0x0f40 - 0x0f7f:     reserved */
-
-/*
- *     Bank 31
- */
-/* 0x0f80 - 0x0fff:    reserved */
-
-/*
- *     Bank 32 - 33
- */
-#define WOL_PATT_RAM_1 0x1000  /*  WOL Pattern RAM Link 1 */
-
-/*
- *     Bank 0x22 - 0x3f
- */
-/* 0x1100 - 0x1fff:    reserved */
-
-/*
- *     Bank 0x40 - 0x4f
- */
-#define BASE_XMAC_1            0x2000  /* XMAC 1 registers */
-
-/*
- *     Bank 0x50 - 0x5f
- */
-
-#define BASE_GMAC_1            0x2800  /* GMAC 1 registers */
-
-/*
- *     Bank 0x60 - 0x6f
- */
-#define BASE_XMAC_2            0x3000  /* XMAC 2 registers */
-
-/*
- *     Bank 0x70 - 0x7f
- */
-#define BASE_GMAC_2            0x3800  /* GMAC 2 registers */
-
-/*
- *     Control Register Bit Definitions:
- */
-/*     B0_RAP          8 bit   Register Address Port */
-                                                               /* Bit 7:       reserved */
-#define RAP_RAP                        0x3f    /* Bit 6..0:    0 = block 0,..,6f = block 6f */
-
-/*     B0_CTST         16 bit  Control/Status register */
-                                                               /* Bit 15..14:  reserved */
-#define CS_CLK_RUN_HOT BIT_13S         /* CLK_RUN hot m. (YUKON-Lite only) */
-#define CS_CLK_RUN_RST BIT_12S         /* CLK_RUN reset  (YUKON-Lite only) */
-#define CS_CLK_RUN_ENA BIT_11S         /* CLK_RUN enable (YUKON-Lite only) */
-#define CS_VAUX_AVAIL  BIT_10S         /* VAUX available (YUKON only) */
-#define CS_BUS_CLOCK   BIT_9S          /* Bus Clock 0/1 = 33/66 MHz */
-#define CS_BUS_SLOT_SZ BIT_8S          /* Slot Size 0/1 = 32/64 bit slot */
-#define CS_ST_SW_IRQ   BIT_7S          /* Set IRQ SW Request */
-#define CS_CL_SW_IRQ   BIT_6S          /* Clear IRQ SW Request */
-#define CS_STOP_DONE   BIT_5S          /* Stop Master is finished */
-#define CS_STOP_MAST   BIT_4S          /* Command Bit to stop the master */
-#define CS_MRST_CLR            BIT_3S          /* Clear Master reset   */
-#define CS_MRST_SET            BIT_2S          /* Set Master reset     */
-#define CS_RST_CLR             BIT_1S          /* Clear Software reset */
-#define CS_RST_SET             BIT_0S          /* Set   Software reset */
-
-/*     B0_LED           8 Bit  LED register */
-                                                               /* Bit  7.. 2:  reserved */
-#define LED_STAT_ON            BIT_1S          /* Status LED on        */
-#define LED_STAT_OFF   BIT_0S          /* Status LED off       */
-
-/*     B0_POWER_CTRL    8 Bit  Power Control reg (YUKON only) */
-#define PC_VAUX_ENA            BIT_7           /* Switch VAUX Enable  */
-#define PC_VAUX_DIS            BIT_6       /* Switch VAUX Disable */
-#define PC_VCC_ENA             BIT_5       /* Switch VCC Enable  */
-#define PC_VCC_DIS             BIT_4       /* Switch VCC Disable */
-#define PC_VAUX_ON             BIT_3       /* Switch VAUX On  */
-#define PC_VAUX_OFF            BIT_2       /* Switch VAUX Off */
-#define PC_VCC_ON              BIT_1       /* Switch VCC On  */
-#define PC_VCC_OFF             BIT_0       /* Switch VCC Off */
-
-/*     B0_ISRC         32 bit  Interrupt Source Register */
-/*     B0_IMSK         32 bit  Interrupt Mask Register */
-/*     B0_SP_ISRC      32 bit  Special Interrupt Source Reg */
-/*     B2_IRQM_MSK     32 bit  IRQ Moderation Mask */
-#define IS_ALL_MSK             0xbfffffffL     /*              All Interrupt bits */
-#define IS_HW_ERR              BIT_31          /* Interrupt HW Error */
-                                                               /* Bit 30:      reserved */
-#define IS_PA_TO_RX1   BIT_29          /* Packet Arb Timeout Rx1 */
-#define IS_PA_TO_RX2   BIT_28          /* Packet Arb Timeout Rx2 */
-#define IS_PA_TO_TX1   BIT_27          /* Packet Arb Timeout Tx1 */
-#define IS_PA_TO_TX2   BIT_26          /* Packet Arb Timeout Tx2 */
-#define IS_I2C_READY   BIT_25          /* IRQ on end of I2C Tx */
-#define IS_IRQ_SW              BIT_24          /* SW forced IRQ        */
-#define IS_EXT_REG             BIT_23          /* IRQ from LM80 or PHY (GENESIS only) */
-                                                                       /* IRQ from PHY (YUKON only) */
-#define IS_TIMINT              BIT_22          /* IRQ from Timer       */
-#define IS_MAC1                        BIT_21          /* IRQ from MAC 1       */
-#define IS_LNK_SYNC_M1 BIT_20          /* Link Sync Cnt wrap MAC 1 */
-#define IS_MAC2                        BIT_19          /* IRQ from MAC 2       */
-#define IS_LNK_SYNC_M2 BIT_18          /* Link Sync Cnt wrap MAC 2 */
-/* Receive Queue 1 */
-#define IS_R1_B                        BIT_17          /* Q_R1 End of Buffer */
-#define IS_R1_F                        BIT_16          /* Q_R1 End of Frame */
-#define IS_R1_C                        BIT_15          /* Q_R1 Encoding Error */
-/* Receive Queue 2 */
-#define IS_R2_B                        BIT_14          /* Q_R2 End of Buffer */
-#define IS_R2_F                        BIT_13          /* Q_R2 End of Frame */
-#define IS_R2_C                        BIT_12          /* Q_R2 Encoding Error */
-/* Synchronous Transmit Queue 1 */
-#define IS_XS1_B               BIT_11          /* Q_XS1 End of Buffer */
-#define IS_XS1_F               BIT_10          /* Q_XS1 End of Frame */
-#define IS_XS1_C               BIT_9           /* Q_XS1 Encoding Error */
-/* Asynchronous Transmit Queue 1 */
-#define IS_XA1_B               BIT_8           /* Q_XA1 End of Buffer */
-#define IS_XA1_F               BIT_7           /* Q_XA1 End of Frame */
-#define IS_XA1_C               BIT_6           /* Q_XA1 Encoding Error */
-/* Synchronous Transmit Queue 2 */
-#define IS_XS2_B               BIT_5           /* Q_XS2 End of Buffer */
-#define IS_XS2_F               BIT_4           /* Q_XS2 End of Frame */
-#define IS_XS2_C               BIT_3           /* Q_XS2 Encoding Error */
-/* Asynchronous Transmit Queue 2 */
-#define IS_XA2_B               BIT_2           /* Q_XA2 End of Buffer */
-#define IS_XA2_F               BIT_1           /* Q_XA2 End of Frame */
-#define IS_XA2_C               BIT_0           /* Q_XA2 Encoding Error */
-
-
-/*     B0_HWE_ISRC     32 bit  HW Error Interrupt Src Reg */
-/*     B0_HWE_IMSK     32 bit  HW Error Interrupt Mask Reg */
-/*     B2_IRQM_HWE_MSK 32 bit  IRQ Moderation HW Error Mask */
-#define IS_ERR_MSK             0x00000fffL     /*              All Error bits */
-                                                               /* Bit 31..14:  reserved */
-#define IS_IRQ_TIST_OV BIT_13  /* Time Stamp Timer Overflow (YUKON only) */
-#define IS_IRQ_SENSOR  BIT_12  /* IRQ from Sensor (YUKON only) */
-#define IS_IRQ_MST_ERR BIT_11  /* IRQ master error detected */
-#define IS_IRQ_STAT            BIT_10  /* IRQ status exception */
-#define IS_NO_STAT_M1  BIT_9   /* No Rx Status from MAC 1 */
-#define IS_NO_STAT_M2  BIT_8   /* No Rx Status from MAC 2 */
-#define IS_NO_TIST_M1  BIT_7   /* No Time Stamp from MAC 1 */
-#define IS_NO_TIST_M2  BIT_6   /* No Time Stamp from MAC 2 */
-#define IS_RAM_RD_PAR  BIT_5   /* RAM Read  Parity Error */
-#define IS_RAM_WR_PAR  BIT_4   /* RAM Write Parity Error */
-#define IS_M1_PAR_ERR  BIT_3   /* MAC 1 Parity Error */
-#define IS_M2_PAR_ERR  BIT_2   /* MAC 2 Parity Error */
-#define IS_R1_PAR_ERR  BIT_1   /* Queue R1 Parity Error */
-#define IS_R2_PAR_ERR  BIT_0   /* Queue R2 Parity Error */
-
-/*     B2_CONN_TYP      8 bit  Connector type */
-/*     B2_PMD_TYP       8 bit  PMD type */
-/*     Values of connector and PMD type comply to SysKonnect internal std */
-
-/*     B2_MAC_CFG       8 bit  MAC Configuration / Chip Revision */
-#define CFG_CHIP_R_MSK (0xf<<4)        /* Bit 7.. 4: Chip Revision */
-                                                                       /* Bit 3.. 2:   reserved */
-#define CFG_DIS_M2_CLK BIT_1S          /* Disable Clock for 2nd MAC */
-#define CFG_SNG_MAC            BIT_0S          /* MAC Config: 0=2 MACs / 1=1 MAC*/
-
-/*     B2_CHIP_ID       8 bit  Chip Identification Number */
-#define CHIP_ID_GENESIS        0x0a            /* Chip ID for GENESIS */
-#define CHIP_ID_YUKON  0xb0            /* Chip ID for YUKON */
-
-/*     B2_FAR          32 bit  Flash-Prom Addr Reg/Cnt */
-#define FAR_ADDR               0x1ffffL        /* Bit 16.. 0:  FPROM Address mask */
-
-/*     B2_LD_CRTL       8 bit  EPROM loader control register */
-/*     Bits are currently reserved */
-
-/*     B2_LD_TEST       8 bit  EPROM loader test register */
-                                                               /* Bit 7.. 4:   reserved */
-#define LD_T_ON                        BIT_3S  /* Loader Test mode on */
-#define LD_T_OFF               BIT_2S  /* Loader Test mode off */
-#define LD_T_STEP              BIT_1S  /* Decrement FPROM addr. Counter */
-#define LD_START               BIT_0S  /* Start loading FPROM */
-
-/*
- *     Timer Section
- */
-/*     B2_TI_CRTL       8 bit  Timer control */
-/*     B2_IRQM_CTRL     8 bit  IRQ Moderation Timer Control */
-                                                               /* Bit 7.. 3:   reserved */
-#define TIM_START              BIT_2S  /* Start Timer */
-#define TIM_STOP               BIT_1S  /* Stop  Timer */
-#define TIM_CLR_IRQ            BIT_0S  /* Clear Timer IRQ (!IRQM) */
-
-/*     B2_TI_TEST       8 Bit  Timer Test */
-/*     B2_IRQM_TEST     8 bit  IRQ Moderation Timer Test */
-/*     B28_DPT_TST      8 bit  Descriptor Poll Timer Test Reg */
-                                                               /* Bit 7.. 3:   reserved */
-#define TIM_T_ON               BIT_2S  /* Test mode on */
-#define TIM_T_OFF              BIT_1S  /* Test mode off */
-#define TIM_T_STEP             BIT_0S  /* Test step */
-
-/*     B28_DPT_INI     32 bit  Descriptor Poll Timer Init Val */
-/*     B28_DPT_VAL     32 bit  Descriptor Poll Timer Curr Val */
-                                                               /* Bit 31..24:  reserved */
-#define DPT_MSK                0x00ffffffL     /* Bit 23.. 0:  Desc Poll Timer Bits */
-
-/*     B28_DPT_CTRL     8 bit  Descriptor Poll Timer Ctrl Reg */
-                                                               /* Bit  7.. 2:  reserved */
-#define DPT_START              BIT_1S  /* Start Descriptor Poll Timer */
-#define DPT_STOP               BIT_0S  /* Stop  Descriptor Poll Timer */
-
-/*     B2_E_3                   8 bit  lower 4 bits used for HW self test result */
-#define B2_E3_RES_MASK 0x0f
-
-/*     B2_TST_CTRL1     8 bit  Test Control Register 1 */
-#define TST_FRC_DPERR_MR       BIT_7S  /* force DATAPERR on MST RD */
-#define TST_FRC_DPERR_MW       BIT_6S  /* force DATAPERR on MST WR */
-#define TST_FRC_DPERR_TR       BIT_5S  /* force DATAPERR on TRG RD */
-#define TST_FRC_DPERR_TW       BIT_4S  /* force DATAPERR on TRG WR */
-#define TST_FRC_APERR_M                BIT_3S  /* force ADDRPERR on MST */
-#define TST_FRC_APERR_T                BIT_2S  /* force ADDRPERR on TRG */
-#define TST_CFG_WRITE_ON       BIT_1S  /* Enable  Config Reg WR */
-#define TST_CFG_WRITE_OFF      BIT_0S  /* Disable Config Reg WR */
-
-/*     B2_TST_CTRL2     8 bit  Test Control Register 2 */
-                                                                       /* Bit 7.. 4:   reserved */
-                       /* force the following error on the next master read/write      */
-#define TST_FRC_DPERR_MR64     BIT_3S  /* DataPERR RD 64       */
-#define TST_FRC_DPERR_MW64     BIT_2S  /* DataPERR WR 64       */
-#define TST_FRC_APERR_1M64     BIT_1S  /* AddrPERR on 1. phase */
-#define TST_FRC_APERR_2M64     BIT_0S  /* AddrPERR on 2. phase */
-
-/*     B2_GP_IO        32 bit  General Purpose I/O Register */
-                                                       /* Bit 31..26:  reserved */
-#define GP_DIR_9       BIT_25  /* IO_9 direct, 0=I/1=O */
-#define GP_DIR_8       BIT_24  /* IO_8 direct, 0=I/1=O */
-#define GP_DIR_7       BIT_23  /* IO_7 direct, 0=I/1=O */
-#define GP_DIR_6       BIT_22  /* IO_6 direct, 0=I/1=O */
-#define GP_DIR_5       BIT_21  /* IO_5 direct, 0=I/1=O */
-#define GP_DIR_4       BIT_20  /* IO_4 direct, 0=I/1=O */
-#define GP_DIR_3       BIT_19  /* IO_3 direct, 0=I/1=O */
-#define GP_DIR_2       BIT_18  /* IO_2 direct, 0=I/1=O */
-#define GP_DIR_1       BIT_17  /* IO_1 direct, 0=I/1=O */
-#define GP_DIR_0       BIT_16  /* IO_0 direct, 0=I/1=O */
-                                               /* Bit 15..10:  reserved */
-#define GP_IO_9                BIT_9   /* IO_9 pin */
-#define GP_IO_8                BIT_8   /* IO_8 pin */
-#define GP_IO_7                BIT_7   /* IO_7 pin */
-#define GP_IO_6                BIT_6   /* IO_6 pin */
-#define GP_IO_5                BIT_5   /* IO_5 pin */
-#define GP_IO_4                BIT_4   /* IO_4 pin */
-#define GP_IO_3                BIT_3   /* IO_3 pin */
-#define GP_IO_2                BIT_2   /* IO_2 pin */
-#define GP_IO_1                BIT_1   /* IO_1 pin */
-#define GP_IO_0                BIT_0   /* IO_0 pin */
-
-/*     B2_I2C_CTRL     32 bit  I2C HW Control Register */
-#define I2C_FLAG               BIT_31          /* Start read/write if WR */
-#define I2C_ADDR               (0x7fffL<<16)   /* Bit 30..16:  Addr to be RD/WR */
-#define I2C_DEV_SEL            (0x7fL<<9)              /* Bit 15.. 9:  I2C Device Select */
-                                                               /* Bit  8.. 5:  reserved        */
-#define I2C_BURST_LEN  BIT_4           /* Burst Len, 1/4 bytes */
-#define I2C_DEV_SIZE   (7L<<1)         /* Bit  3.. 1:  I2C Device Size */
-#define I2C_025K_DEV   (0L<<1)         /*              0: 256 Bytes or smal. */
-#define I2C_05K_DEV            (1L<<1)         /*              1: 512  Bytes   */
-#define I2C_1K_DEV             (2L<<1)         /*              2: 1024 Bytes   */
-#define I2C_2K_DEV             (3L<<1)         /*              3: 2048 Bytes   */
-#define I2C_4K_DEV             (4L<<1)         /*              4: 4096 Bytes   */
-#define I2C_8K_DEV             (5L<<1)         /*              5: 8192 Bytes   */
-#define I2C_16K_DEV            (6L<<1)         /*              6: 16384 Bytes  */
-#define I2C_32K_DEV            (7L<<1)         /*              7: 32768 Bytes  */
-#define I2C_STOP               BIT_0           /* Interrupt I2C transfer */
-
-/*     B2_I2C_IRQ      32 bit  I2C HW IRQ Register */
-                                                               /* Bit 31.. 1   reserved */
-#define I2C_CLR_IRQ            BIT_0   /* Clear I2C IRQ */
-
-/*     B2_I2C_SW       32 bit (8 bit access)   I2C HW SW Port Register */
-                                                               /* Bit  7.. 3:  reserved */
-#define I2C_DATA_DIR   BIT_2S          /* direction of I2C_DATA */
-#define I2C_DATA               BIT_1S          /* I2C Data Port        */
-#define I2C_CLK                        BIT_0S          /* I2C Clock Port       */
-
-/*
- * I2C Address
- */
-#define I2C_SENS_ADDR  LM80_ADDR       /* I2C Sensor Address, (Volt and Temp)*/
-
-
-/*     B2_BSC_CTRL      8 bit  Blink Source Counter Control */
-                                                       /* Bit  7.. 2:  reserved */
-#define BSC_START      BIT_1S          /* Start Blink Source Counter */
-#define BSC_STOP       BIT_0S          /* Stop  Blink Source Counter */
-
-/*     B2_BSC_STAT      8 bit  Blink Source Counter Status */
-                                                       /* Bit  7.. 1:  reserved */
-#define BSC_SRC                BIT_0S          /* Blink Source, 0=Off / 1=On */
-
-/*     B2_BSC_TST      16 bit  Blink Source Counter Test Reg */
-#define BSC_T_ON       BIT_2S          /* Test mode on */
-#define BSC_T_OFF      BIT_1S          /* Test mode off */
-#define BSC_T_STEP     BIT_0S          /* Test step */
-
-
-/*     B3_RAM_ADDR     32 bit  RAM Address, to read or write */
-                                       /* Bit 31..19:  reserved */
-#define RAM_ADR_RAN    0x0007ffffL     /* Bit 18.. 0:  RAM Address Range */
-
-/* RAM Interface Registers */
-/*     B3_RI_CTRL      16 bit  RAM Iface Control Register */
-                                                               /* Bit 15..10:  reserved */
-#define RI_CLR_RD_PERR BIT_9S  /* Clear IRQ RAM Read Parity Err */
-#define RI_CLR_WR_PERR BIT_8S  /* Clear IRQ RAM Write Parity Err*/
-                                                               /* Bit  7.. 2:  reserved */
-#define RI_RST_CLR             BIT_1S  /* Clear RAM Interface Reset */
-#define RI_RST_SET             BIT_0S  /* Set   RAM Interface Reset */
-
-/*     B3_RI_TEST       8 bit  RAM Iface Test Register */
-                                                               /* Bit 15.. 4:  reserved */
-#define RI_T_EV                        BIT_3S  /* Timeout Event occured */
-#define RI_T_ON                        BIT_2S  /* Timeout Timer Test On */
-#define RI_T_OFF               BIT_1S  /* Timeout Timer Test Off */
-#define RI_T_STEP              BIT_0S  /* Timeout Timer Step */
-
-/* MAC Arbiter Registers */
-/*     B3_MA_TO_CTRL   16 bit  MAC Arbiter Timeout Ctrl Reg */
-                                                               /* Bit 15.. 4:  reserved */
-#define MA_FOE_ON              BIT_3S  /* XMAC Fast Output Enable ON */
-#define MA_FOE_OFF             BIT_2S  /* XMAC Fast Output Enable OFF */
-#define MA_RST_CLR             BIT_1S  /* Clear MAC Arbiter Reset */
-#define MA_RST_SET             BIT_0S  /* Set   MAC Arbiter Reset */
-
-/*     B3_MA_RC_CTRL   16 bit  MAC Arbiter Recovery Ctrl Reg */
-                                                               /* Bit 15.. 8:  reserved */
-#define MA_ENA_REC_TX2 BIT_7S  /* Enable  Recovery Timer TX2 */
-#define MA_DIS_REC_TX2 BIT_6S  /* Disable Recovery Timer TX2 */
-#define MA_ENA_REC_TX1 BIT_5S  /* Enable  Recovery Timer TX1 */
-#define MA_DIS_REC_TX1 BIT_4S  /* Disable Recovery Timer TX1 */
-#define MA_ENA_REC_RX2 BIT_3S  /* Enable  Recovery Timer RX2 */
-#define MA_DIS_REC_RX2 BIT_2S  /* Disable Recovery Timer RX2 */
-#define MA_ENA_REC_RX1 BIT_1S  /* Enable  Recovery Timer RX1 */
-#define MA_DIS_REC_RX1 BIT_0S  /* Disable Recovery Timer RX1 */
-
-/* Packet Arbiter Registers */
-/*     B3_PA_CTRL      16 bit  Packet Arbiter Ctrl Register */
-                                                               /* Bit 15..14:  reserved */
-#define PA_CLR_TO_TX2  BIT_13S /* Clear IRQ Packet Timeout TX2 */
-#define PA_CLR_TO_TX1  BIT_12S /* Clear IRQ Packet Timeout TX1 */
-#define PA_CLR_TO_RX2  BIT_11S /* Clear IRQ Packet Timeout RX2 */
-#define PA_CLR_TO_RX1  BIT_10S /* Clear IRQ Packet Timeout RX1 */
-#define PA_ENA_TO_TX2  BIT_9S  /* Enable  Timeout Timer TX2 */
-#define PA_DIS_TO_TX2  BIT_8S  /* Disable Timeout Timer TX2 */
-#define PA_ENA_TO_TX1  BIT_7S  /* Enable  Timeout Timer TX1 */
-#define PA_DIS_TO_TX1  BIT_6S  /* Disable Timeout Timer TX1 */
-#define PA_ENA_TO_RX2  BIT_5S  /* Enable  Timeout Timer RX2 */
-#define PA_DIS_TO_RX2  BIT_4S  /* Disable Timeout Timer RX2 */
-#define PA_ENA_TO_RX1  BIT_3S  /* Enable  Timeout Timer RX1 */
-#define PA_DIS_TO_RX1  BIT_2S  /* Disable Timeout Timer RX1 */
-#define PA_RST_CLR             BIT_1S  /* Clear MAC Arbiter Reset */
-#define PA_RST_SET             BIT_0S  /* Set   MAC Arbiter Reset */
-
-#define PA_ENA_TO_ALL  (PA_ENA_TO_RX1 | PA_ENA_TO_RX2 |\
-                                               PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
-
-/* Rx/Tx Path related Arbiter Test Registers */
-/*     B3_MA_TO_TEST   16 bit  MAC Arbiter Timeout Test Reg */
-/*     B3_MA_RC_TEST   16 bit  MAC Arbiter Recovery Test Reg */
-/*     B3_PA_TEST      16 bit  Packet Arbiter Test Register */
-/*                     Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */
-#define TX2_T_EV       BIT_15S         /* TX2 Timeout/Recv Event occured */
-#define TX2_T_ON       BIT_14S         /* TX2 Timeout/Recv Timer Test On */
-#define TX2_T_OFF      BIT_13S         /* TX2 Timeout/Recv Timer Tst Off */
-#define TX2_T_STEP     BIT_12S         /* TX2 Timeout/Recv Timer Step */
-#define TX1_T_EV       BIT_11S         /* TX1 Timeout/Recv Event occured */
-#define TX1_T_ON       BIT_10S         /* TX1 Timeout/Recv Timer Test On */
-#define TX1_T_OFF      BIT_9S          /* TX1 Timeout/Recv Timer Tst Off */
-#define TX1_T_STEP     BIT_8S          /* TX1 Timeout/Recv Timer Step */
-#define RX2_T_EV       BIT_7S          /* RX2 Timeout/Recv Event occured */
-#define RX2_T_ON       BIT_6S          /* RX2 Timeout/Recv Timer Test On */
-#define RX2_T_OFF      BIT_5S          /* RX2 Timeout/Recv Timer Tst Off */
-#define RX2_T_STEP     BIT_4S          /* RX2 Timeout/Recv Timer Step */
-#define RX1_T_EV       BIT_3S          /* RX1 Timeout/Recv Event occured */
-#define RX1_T_ON       BIT_2S          /* RX1 Timeout/Recv Timer Test On */
-#define RX1_T_OFF      BIT_1S          /* RX1 Timeout/Recv Timer Tst Off */
-#define RX1_T_STEP     BIT_0S          /* RX1 Timeout/Recv Timer Step */
-
-
-/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
-/*     TXA_ITI_INI     32 bit  Tx Arb Interval Timer Init Val */
-/*     TXA_ITI_VAL     32 bit  Tx Arb Interval Timer Value */
-/*     TXA_LIM_INI     32 bit  Tx Arb Limit Counter Init Val */
-/*     TXA_LIM_VAL     32 bit  Tx Arb Limit Counter Value */
-                                                               /* Bit 31..24:  reserved */
-#define TXA_MAX_VAL    0x00ffffffL     /* Bit 23.. 0:  Max TXA Timer/Cnt Val */
-
-/*     TXA_CTRL         8 bit  Tx Arbiter Control Register */
-#define TXA_ENA_FSYNC  BIT_7S  /* Enable  force of sync Tx queue */
-#define TXA_DIS_FSYNC  BIT_6S  /* Disable force of sync Tx queue */
-#define TXA_ENA_ALLOC  BIT_5S  /* Enable  alloc of free bandwidth */
-#define TXA_DIS_ALLOC  BIT_4S  /* Disable alloc of free bandwidth */
-#define TXA_START_RC   BIT_3S  /* Start sync Rate Control */
-#define TXA_STOP_RC            BIT_2S  /* Stop  sync Rate Control */
-#define TXA_ENA_ARB            BIT_1S  /* Enable  Tx Arbiter */
-#define TXA_DIS_ARB            BIT_0S  /* Disable Tx Arbiter */
-
-/*     TXA_TEST         8 bit  Tx Arbiter Test Register */
-                                                               /* Bit 7.. 6:   reserved */
-#define TXA_INT_T_ON   BIT_5S  /* Tx Arb Interval Timer Test On */
-#define TXA_INT_T_OFF  BIT_4S  /* Tx Arb Interval Timer Test Off */
-#define TXA_INT_T_STEP BIT_3S  /* Tx Arb Interval Timer Step */
-#define TXA_LIM_T_ON   BIT_2S  /* Tx Arb Limit Timer Test On */
-#define TXA_LIM_T_OFF  BIT_1S  /* Tx Arb Limit Timer Test Off */
-#define TXA_LIM_T_STEP BIT_0S  /* Tx Arb Limit Timer Step */
-
-/*     TXA_STAT         8 bit  Tx Arbiter Status Register */
-                                                               /* Bit 7.. 1:   reserved */
-#define TXA_PRIO_XS            BIT_0S  /* sync queue has prio to send */
-
-/*     Q_BC    32 bit  Current Byte Counter */
-                                                               /* Bit 31..16:  reserved */
-#define BC_MAX                 0xffff  /* Bit 15.. 0:  Byte counter */
-
-/* BMU Control Status Registers */
-/*     B0_R1_CSR       32 bit  BMU Ctrl/Stat Rx Queue 1 */
-/*     B0_R2_CSR       32 bit  BMU Ctrl/Stat Rx Queue 2 */
-/*     B0_XA1_CSR      32 bit  BMU Ctrl/Stat Sync Tx Queue 1 */
-/*     B0_XS1_CSR      32 bit  BMU Ctrl/Stat Async Tx Queue 1 */
-/*     B0_XA2_CSR      32 bit  BMU Ctrl/Stat Sync Tx Queue 2 */
-/*     B0_XS2_CSR      32 bit  BMU Ctrl/Stat Async Tx Queue 2 */
-/*     Q_CSR           32 bit  BMU Control/Status Register */
-                                                               /* Bit 31..25:  reserved */
-#define CSR_SV_IDLE            BIT_24          /* BMU SM Idle */
-                                                               /* Bit 23..22:  reserved */
-#define CSR_DESC_CLR   BIT_21          /* Clear Reset for Descr */
-#define CSR_DESC_SET   BIT_20          /* Set   Reset for Descr */
-#define CSR_FIFO_CLR   BIT_19          /* Clear Reset for FIFO */
-#define CSR_FIFO_SET   BIT_18          /* Set   Reset for FIFO */
-#define CSR_HPI_RUN            BIT_17          /* Release HPI SM */
-#define CSR_HPI_RST            BIT_16          /* Reset   HPI SM to Idle */
-#define CSR_SV_RUN             BIT_15          /* Release Supervisor SM */
-#define CSR_SV_RST             BIT_14          /* Reset   Supervisor SM */
-#define CSR_DREAD_RUN  BIT_13          /* Release Descr Read SM */
-#define CSR_DREAD_RST  BIT_12          /* Reset   Descr Read SM */
-#define CSR_DWRITE_RUN BIT_11          /* Release Descr Write SM */
-#define CSR_DWRITE_RST BIT_10          /* Reset   Descr Write SM */
-#define CSR_TRANS_RUN  BIT_9           /* Release Transfer SM */
-#define CSR_TRANS_RST  BIT_8           /* Reset   Transfer SM */
-#define CSR_ENA_POL            BIT_7           /* Enable  Descr Polling */
-#define CSR_DIS_POL            BIT_6           /* Disable Descr Polling */
-#define CSR_STOP               BIT_5           /* Stop  Rx/Tx Queue */
-#define CSR_START              BIT_4           /* Start Rx/Tx Queue */
-#define CSR_IRQ_CL_P   BIT_3           /* (Rx) Clear Parity IRQ */
-#define CSR_IRQ_CL_B   BIT_2           /* Clear EOB IRQ */
-#define CSR_IRQ_CL_F   BIT_1           /* Clear EOF IRQ */
-#define CSR_IRQ_CL_C   BIT_0           /* Clear ERR IRQ */
-
-#define CSR_SET_RESET  (CSR_DESC_SET | CSR_FIFO_SET | CSR_HPI_RST |\
-                                               CSR_SV_RST | CSR_DREAD_RST | CSR_DWRITE_RST |\
-                                               CSR_TRANS_RST)
-#define CSR_CLR_RESET  (CSR_DESC_CLR | CSR_FIFO_CLR | CSR_HPI_RUN |\
-                                               CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\
-                                               CSR_TRANS_RUN)
-
-/*     Q_F     32 bit  Flag Register */
-                                                                       /* Bit 31..28:  reserved */
-#define F_ALM_FULL             BIT_27          /* Rx FIFO: almost full */
-#define F_EMPTY                        BIT_27          /* Tx FIFO: empty flag */
-#define F_FIFO_EOF             BIT_26          /* Tag (EOF Flag) bit in FIFO */
-#define F_WM_REACHED   BIT_25          /* Watermark reached */
-                                                                       /* reserved */
-#define F_FIFO_LEVEL   (0x1fL<<16)     /* Bit 23..16:  # of Qwords in FIFO */
-                                                                       /* Bit 15..11:  reserved */
-#define F_WATER_MARK   0x0007ffL       /* Bit 10.. 0:  Watermark */
-
-/*     Q_T1    32 bit  Test Register 1 */
-/*             Holds four State Machine control Bytes */
-#define SM_CRTL_SV_MSK (0xffL<<24)     /* Bit 31..24:  Control Supervisor SM */
-#define SM_CRTL_RD_MSK (0xffL<<16)     /* Bit 23..16:  Control Read Desc SM */
-#define SM_CRTL_WR_MSK (0xffL<<8)      /* Bit 15.. 8:  Control Write Desc SM */
-#define SM_CRTL_TR_MSK 0xffL           /* Bit  7.. 0:  Control Transfer SM */
-
-/*     Q_T1_TR  8 bit  Test Register 1 Transfer SM */
-/*     Q_T1_WR  8 bit  Test Register 1 Write Descriptor SM */
-/*     Q_T1_RD  8 bit  Test Register 1 Read Descriptor SM */
-/*     Q_T1_SV  8 bit  Test Register 1 Supervisor SM */
-
-/* The control status byte of each machine looks like ... */
-#define SM_STATE               0xf0    /* Bit 7.. 4:   State which shall be loaded */
-#define SM_LOAD                        BIT_3S  /* Load the SM with SM_STATE */
-#define SM_TEST_ON             BIT_2S  /* Switch on SM Test Mode */
-#define SM_TEST_OFF            BIT_1S  /* Go off the Test Mode */
-#define SM_STEP                        BIT_0S  /* Step the State Machine */
-/* The encoding of the states is not supported by the Diagnostics Tool */
-
-/*     Q_T2    32 bit  Test Register 2 */
-                                                               /* Bit 31.. 8:  reserved */
-#define T2_AC_T_ON             BIT_7   /* Address Counter Test Mode on */
-#define T2_AC_T_OFF            BIT_6   /* Address Counter Test Mode off */
-#define T2_BC_T_ON             BIT_5   /* Byte Counter Test Mode on */
-#define T2_BC_T_OFF            BIT_4   /* Byte Counter Test Mode off */
-#define T2_STEP04              BIT_3   /* Inc AC/Dec BC by 4 */
-#define T2_STEP03              BIT_2   /* Inc AC/Dec BC by 3 */
-#define T2_STEP02              BIT_1   /* Inc AC/Dec BC by 2 */
-#define T2_STEP01              BIT_0   /* Inc AC/Dec BC by 1 */
-
-/*     Q_T3    32 bit  Test Register 3 */
-                                                               /* Bit 31.. 7:  reserved */
-#define T3_MUX_MSK             (7<<4)  /* Bit  6.. 4:  Mux Position */
-                                                               /* Bit  3:      reserved */
-#define T3_VRAM_MSK            7               /* Bit  2.. 0:  Virtual RAM Buffer Address */
-
-/* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */
-/*     RB_START        32 bit  RAM Buffer Start Address */
-/*     RB_END          32 bit  RAM Buffer End Address */
-/*     RB_WP           32 bit  RAM Buffer Write Pointer */
-/*     RB_RP           32 bit  RAM Buffer Read Pointer */
-/*     RB_RX_UTPP      32 bit  Rx Upper Threshold, Pause Pack */
-/*     RB_RX_LTPP      32 bit  Rx Lower Threshold, Pause Pack */
-/*     RB_RX_UTHP      32 bit  Rx Upper Threshold, High Prio */
-/*     RB_RX_LTHP      32 bit  Rx Lower Threshold, High Prio */
-/*     RB_PC           32 bit  RAM Buffer Packet Counter */
-/*     RB_LEV          32 bit  RAM Buffer Level Register */
-                               /* Bit 31..19:  reserved */
-#define RB_MSK 0x0007ffff      /* Bit 18.. 0:  RAM Buffer Pointer Bits */
-
-/*     RB_TST2                  8 bit  RAM Buffer Test Register 2 */
-                                                               /* Bit 7.. 4:   reserved */
-#define RB_PC_DEC              BIT_3S  /* Packet Counter Decrem */
-#define RB_PC_T_ON             BIT_2S  /* Packet Counter Test On */
-#define RB_PC_T_OFF            BIT_1S  /* Packet Counter Tst Off */
-#define RB_PC_INC              BIT_0S  /* Packet Counter Increm */
-
-/*     RB_TST1                  8 bit  RAM Buffer Test Register 1 */
-                                                       /* Bit 7:       reserved */
-#define RB_WP_T_ON             BIT_6S  /* Write Pointer Test On */
-#define RB_WP_T_OFF            BIT_5S  /* Write Pointer Test Off */
-#define RB_WP_INC              BIT_4S  /* Write Pointer Increm */
-                                                               /* Bit 3:       reserved */
-#define RB_RP_T_ON             BIT_2S  /* Read Pointer Test On */
-#define RB_RP_T_OFF            BIT_1S  /* Read Pointer Test Off */
-#define RB_RP_DEC              BIT_0S  /* Read Pointer Decrement */
-
-/*     RB_CTRL                  8 bit  RAM Buffer Control Register */
-                                                               /* Bit 7.. 6:   reserved */
-#define RB_ENA_STFWD   BIT_5S  /* Enable  Store & Forward */
-#define RB_DIS_STFWD   BIT_4S  /* Disable Store & Forward */
-#define RB_ENA_OP_MD   BIT_3S  /* Enable  Operation Mode */
-#define RB_DIS_OP_MD   BIT_2S  /* Disable Operation Mode */
-#define RB_RST_CLR             BIT_1S  /* Clear RAM Buf STM Reset */
-#define RB_RST_SET             BIT_0S  /* Set   RAM Buf STM Reset */
-
-
-/* Receive and Transmit MAC FIFO Registers (GENESIS only) */
-
-/*     RX_MFF_EA       32 bit  Receive MAC FIFO End Address */
-/*     RX_MFF_WP       32 bit  Receive MAC FIFO Write Pointer */
-/*     RX_MFF_RP       32 bit  Receive MAC FIFO Read Pointer */
-/*     RX_MFF_PC       32 bit  Receive MAC FIFO Packet Counter */
-/*     RX_MFF_LEV      32 bit  Receive MAC FIFO Level */
-/*     TX_MFF_EA       32 bit  Transmit MAC FIFO End Address */
-/*     TX_MFF_WP       32 bit  Transmit MAC FIFO Write Pointer */
-/*     TX_MFF_WSP      32 bit  Transmit MAC FIFO WR Shadow Pointer */
-/*     TX_MFF_RP       32 bit  Transmit MAC FIFO Read Pointer */
-/*     TX_MFF_PC       32 bit  Transmit MAC FIFO Packet Cnt */
-/*     TX_MFF_LEV      32 bit  Transmit MAC FIFO Level */
-                                                               /* Bit 31.. 6:  reserved */
-#define MFF_MSK                        0x007fL /* Bit  5.. 0:  MAC FIFO Address/Ptr Bits */
-
-/*     RX_MFF_CTRL1    16 bit  Receive MAC FIFO Control Reg 1 */
-                                                               /* Bit 15..14:  reserved */
-#define MFF_ENA_RDY_PAT        BIT_13S         /* Enable  Ready Patch */
-#define MFF_DIS_RDY_PAT        BIT_12S         /* Disable Ready Patch */
-#define MFF_ENA_TIM_PAT        BIT_11S         /* Enable  Timing Patch */
-#define MFF_DIS_TIM_PAT        BIT_10S         /* Disable Timing Patch */
-#define MFF_ENA_ALM_FUL        BIT_9S          /* Enable  AlmostFull Sign */
-#define MFF_DIS_ALM_FUL        BIT_8S          /* Disable AlmostFull Sign */
-#define MFF_ENA_PAUSE  BIT_7S          /* Enable  Pause Signaling */
-#define MFF_DIS_PAUSE  BIT_6S          /* Disable Pause Signaling */
-#define MFF_ENA_FLUSH  BIT_5S          /* Enable  Frame Flushing */
-#define MFF_DIS_FLUSH  BIT_4S          /* Disable Frame Flushing */
-#define MFF_ENA_TIST   BIT_3S          /* Enable  Time Stamp Gener */
-#define MFF_DIS_TIST   BIT_2S          /* Disable Time Stamp Gener */
-#define MFF_CLR_INTIST BIT_1S          /* Clear IRQ No Time Stamp */
-#define MFF_CLR_INSTAT BIT_0S          /* Clear IRQ No Status */
-
-#define MFF_RX_CTRL_DEF MFF_ENA_TIM_PAT
-
-/*     TX_MFF_CTRL1    16 bit  Transmit MAC FIFO Control Reg 1 */
-#define MFF_CLR_PERR   BIT_15S         /* Clear Parity Error IRQ */
-                                                               /* Bit 14:      reserved */
-#define MFF_ENA_PKT_REC        BIT_13S         /* Enable  Packet Recovery */
-#define MFF_DIS_PKT_REC BIT_12S                /* Disable Packet Recovery */
-/*     MFF_ENA_TIM_PAT  (see RX_MFF_CTRL1) Bit 11:     Enable  Timing Patch */
-/*     MFF_DIS_TIM_PAT  (see RX_MFF_CTRL1) Bit 10:     Disable Timing Patch */
-/*     MFF_ENA_ALM_FUL  (see RX_MFF_CTRL1) Bit  9:     Enable  Almost Full Sign */
-/*     MFF_DIS_ALM_FUL  (see RX_MFF_CTRL1) Bit  8:     Disable Almost Full Sign */
-#define MFF_ENA_W4E            BIT_7S          /* Enable  Wait for Empty */
-#define MFF_DIS_W4E            BIT_6S          /* Disable Wait for Empty */
-/*     MFF_ENA_FLUSH    (see RX_MFF_CTRL1) Bit  5:     Enable  Frame Flushing */
-/*     MFF_DIS_FLUSH    (see RX_MFF_CTRL1) Bit  4:     Disable Frame Flushing */
-#define MFF_ENA_LOOPB  BIT_3S          /* Enable  Loopback */
-#define MFF_DIS_LOOPB  BIT_2S          /* Disable Loopback */
-#define MFF_CLR_MAC_RST        BIT_1S          /* Clear XMAC Reset */
-#define MFF_SET_MAC_RST        BIT_0S          /* Set   XMAC Reset */
-
-#define MFF_TX_CTRL_DEF        (MFF_ENA_PKT_REC | MFF_ENA_TIM_PAT | MFF_ENA_FLUSH)
-
-/*     RX_MFF_TST2              8 bit  Receive MAC FIFO Test Register 2 */
-/*     TX_MFF_TST2              8 bit  Transmit MAC FIFO Test Register 2 */
-                                                               /* Bit 7:       reserved */
-#define MFF_WSP_T_ON   BIT_6S  /* Tx: Write Shadow Ptr TestOn */
-#define MFF_WSP_T_OFF  BIT_5S  /* Tx: Write Shadow Ptr TstOff */
-#define MFF_WSP_INC            BIT_4S  /* Tx: Write Shadow Ptr Increment */
-#define MFF_PC_DEC             BIT_3S  /* Packet Counter Decrement */
-#define MFF_PC_T_ON            BIT_2S  /* Packet Counter Test On */
-#define MFF_PC_T_OFF   BIT_1S  /* Packet Counter Test Off */
-#define MFF_PC_INC             BIT_0S  /* Packet Counter Increment */
-
-/*     RX_MFF_TST1              8 bit  Receive MAC FIFO Test Register 1 */
-/*     TX_MFF_TST1              8 bit  Transmit MAC FIFO Test Register 1 */
-                                       /* Bit 7:       reserved */
-#define MFF_WP_T_ON            BIT_6S  /* Write Pointer Test On */
-#define MFF_WP_T_OFF   BIT_5S  /* Write Pointer Test Off */
-#define MFF_WP_INC             BIT_4S  /* Write Pointer Increm */
-                                                       /* Bit 3:       reserved */
-#define MFF_RP_T_ON            BIT_2S  /* Read Pointer Test On */
-#define MFF_RP_T_OFF   BIT_1S  /* Read Pointer Test Off */
-#define MFF_RP_DEC             BIT_0S  /* Read Pointer Decrement */
-
-/*     RX_MFF_CTRL2     8 bit  Receive MAC FIFO Control Reg 2 */
-/*     TX_MFF_CTRL2     8 bit  Transmit MAC FIFO Control Reg 2 */
-                                                               /* Bit 7..4:    reserved */
-#define MFF_ENA_OP_MD  BIT_3S  /* Enable  Operation Mode */
-#define MFF_DIS_OP_MD  BIT_2S  /* Disable Operation Mode */
-#define MFF_RST_CLR            BIT_1S  /* Clear MAC FIFO Reset */
-#define MFF_RST_SET            BIT_0S  /* Set   MAC FIFO Reset */
-
-
-/*     Link LED Counter Registers (GENESIS only) */
-
-/*     RX_LED_CTRL              8 bit  Receive LED Cnt Control Reg */
-/*     TX_LED_CTRL              8 bit  Transmit LED Cnt Control Reg */
-/*     LNK_SYNC_CTRL    8 bit  Link Sync Cnt Control Register */
-                                                       /* Bit 7.. 3:   reserved */
-#define LED_START              BIT_2S  /* Start Timer */
-#define LED_STOP               BIT_1S  /* Stop Timer */
-#define LED_STATE              BIT_0S  /* Rx/Tx: LED State, 1=LED on */
-#define LED_CLR_IRQ            BIT_0S  /* Lnk:         Clear Link IRQ */
-
-/*     RX_LED_TST               8 bit  Receive LED Cnt Test Register */
-/*     TX_LED_TST               8 bit  Transmit LED Cnt Test Register */
-/*     LNK_SYNC_TST     8 bit  Link Sync Cnt Test Register */
-                                                       /* Bit 7.. 3:   reserved */
-#define LED_T_ON               BIT_2S  /* LED Counter Test mode On */
-#define LED_T_OFF              BIT_1S  /* LED Counter Test mode Off */
-#define LED_T_STEP             BIT_0S  /* LED Counter Step */
-
-/*     LNK_LED_REG              8 bit  Link LED Register */
-                                                               /* Bit 7.. 6:   reserved */
-#define LED_BLK_ON             BIT_5S  /* Link LED Blinking On */
-#define LED_BLK_OFF            BIT_4S  /* Link LED Blinking Off */
-#define LED_SYNC_ON            BIT_3S  /* Use Sync Wire to switch LED */
-#define LED_SYNC_OFF   BIT_2S  /* Disable Sync Wire Input */
-#define LED_ON                 BIT_1S  /* switch LED on */
-#define LED_OFF                        BIT_0S  /* switch LED off */
-
-/*     Receive and Transmit GMAC FIFO Registers (YUKON only) */
-
-/*     RX_GMF_EA               32 bit  Rx GMAC FIFO End Address */
-/*     RX_GMF_AF_THR   32 bit  Rx GMAC FIFO Almost Full Thresh. */
-/*     RX_GMF_WP               32 bit  Rx GMAC FIFO Write Pointer */
-/*     RX_GMF_WLEV             32 bit  Rx GMAC FIFO Write Level */
-/*     RX_GMF_RP               32 bit  Rx GMAC FIFO Read Pointer */
-/*     RX_GMF_RLEV             32 bit  Rx GMAC FIFO Read Level */
-/*     TX_GMF_EA               32 bit  Tx GMAC FIFO End Address */
-/*     TX_GMF_AE_THR   32 bit  Tx GMAC FIFO Almost Empty Thresh.*/
-/*     TX_GMF_WP               32 bit  Tx GMAC FIFO Write Pointer */
-/*     TX_GMF_WSP              32 bit  Tx GMAC FIFO Write Shadow Ptr. */
-/*     TX_GMF_WLEV             32 bit  Tx GMAC FIFO Write Level */
-/*     TX_GMF_RP               32 bit  Tx GMAC FIFO Read Pointer */
-/*     TX_GMF_RSTP             32 bit  Tx GMAC FIFO Restart Pointer */
-/*     TX_GMF_RLEV             32 bit  Tx GMAC FIFO Read Level */
-
-/*     RX_GMF_CTRL_T   32 bit  Rx GMAC FIFO Control/Test */
-                                               /* Bits 31..15: reserved */
-#define GMF_WP_TST_ON  BIT_14          /* Write Pointer Test On */
-#define GMF_WP_TST_OFF BIT_13          /* Write Pointer Test Off */
-#define GMF_WP_STEP            BIT_12          /* Write Pointer Step/Increment */
-                                               /* Bit 11:      reserved */
-#define GMF_RP_TST_ON  BIT_10          /* Read Pointer Test On */
-#define GMF_RP_TST_OFF BIT_9           /* Read Pointer Test Off */
-#define GMF_RP_STEP            BIT_8           /* Read Pointer Step/Increment */
-#define GMF_RX_F_FL_ON BIT_7           /* Rx FIFO Flush Mode On */
-#define GMF_RX_F_FL_OFF        BIT_6           /* Rx FIFO Flush Mode Off */
-#define GMF_CLI_RX_FO  BIT_5           /* Clear IRQ Rx FIFO Overrun */
-#define GMF_CLI_RX_FC  BIT_4           /* Clear IRQ Rx Frame Complete */
-#define GMF_OPER_ON            BIT_3           /* Operational Mode On */
-#define GMF_OPER_OFF   BIT_2           /* Operational Mode Off */
-#define GMF_RST_CLR            BIT_1           /* Clear GMAC FIFO Reset */
-#define GMF_RST_SET            BIT_0           /* Set   GMAC FIFO Reset */
-
-/*     TX_GMF_CTRL_T   32 bit  Tx GMAC FIFO Control/Test */
-                                               /* Bits 31..19: reserved */
-#define GMF_WSP_TST_ON BIT_18          /* Write Shadow Pointer Test On */
-#define GMF_WSP_TST_OFF        BIT_17          /* Write Shadow Pointer Test Off */
-#define GMF_WSP_STEP   BIT_16          /* Write Shadow Pointer Step/Increment */
-                                               /* Bits 15..7: same as for RX_GMF_CTRL_T */
-#define GMF_CLI_TX_FU  BIT_6           /* Clear IRQ Tx FIFO Underrun */
-#define GMF_CLI_TX_FC  BIT_5           /* Clear IRQ Tx Frame Complete */
-#define GMF_CLI_TX_PE  BIT_4           /* Clear IRQ Tx Parity Error */
-                                               /* Bits 3..0: same as for RX_GMF_CTRL_T */
-
-#define GMF_RX_CTRL_DEF                (GMF_OPER_ON | GMF_RX_F_FL_ON)
-#define GMF_TX_CTRL_DEF                GMF_OPER_ON
-
-#define RX_GMF_FL_THR_DEF      0x0a    /* Rx GMAC FIFO Flush Threshold default */
-
-/*     GMAC_TI_ST_CTRL           8 bit Time Stamp Timer Ctrl Reg (YUKON only) */
-                                                               /* Bit 7.. 3:   reserved */
-#define GMT_ST_START   BIT_2S          /* Start Time Stamp Timer */
-#define GMT_ST_STOP            BIT_1S          /* Stop  Time Stamp Timer */
-#define GMT_ST_CLR_IRQ BIT_0S          /* Clear Time Stamp Timer IRQ */
-
-/*     GMAC_CTRL               32 bit  GMAC Control Reg (YUKON only) */
-                                               /* Bits 31.. 8: reserved */
-#define GMC_H_BURST_ON BIT_7           /* Half Duplex Burst Mode On */
-#define GMC_H_BURST_OFF        BIT_6           /* Half Duplex Burst Mode Off */
-#define GMC_F_LOOPB_ON BIT_5           /* FIFO Loopback On */
-#define GMC_F_LOOPB_OFF        BIT_4           /* FIFO Loopback Off */
-#define GMC_PAUSE_ON   BIT_3           /* Pause On */
-#define GMC_PAUSE_OFF  BIT_2           /* Pause Off */
-#define GMC_RST_CLR            BIT_1           /* Clear GMAC Reset */
-#define GMC_RST_SET            BIT_0           /* Set   GMAC Reset */
-
-/*     GPHY_CTRL               32 bit  GPHY Control Reg (YUKON only) */
-                                               /* Bits 31..29: reserved */
-#define GPC_SEL_BDT            BIT_28  /* Select Bi-Dir. Transfer for MDC/MDIO */
-#define GPC_INT_POL_HI BIT_27  /* IRQ Polarity is Active HIGH */
-#define GPC_75_OHM             BIT_26  /* Use 75 Ohm Termination instead of 50 */
-#define GPC_DIS_FC             BIT_25  /* Disable Automatic Fiber/Copper Detection */
-#define GPC_DIS_SLEEP  BIT_24  /* Disable Energy Detect */
-#define GPC_HWCFG_M_3  BIT_23  /* HWCFG_MODE[3] */
-#define GPC_HWCFG_M_2  BIT_22  /* HWCFG_MODE[2] */
-#define GPC_HWCFG_M_1  BIT_21  /* HWCFG_MODE[1] */
-#define GPC_HWCFG_M_0  BIT_20  /* HWCFG_MODE[0] */
-#define GPC_ANEG_0             BIT_19  /* ANEG[0] */
-#define GPC_ENA_XC             BIT_18  /* Enable MDI crossover */
-#define GPC_DIS_125            BIT_17  /* Disable 125 MHz clock */
-#define GPC_ANEG_3             BIT_16  /* ANEG[3] */
-#define GPC_ANEG_2             BIT_15  /* ANEG[2] */
-#define GPC_ANEG_1             BIT_14  /* ANEG[1] */
-#define GPC_ENA_PAUSE  BIT_13  /* Enable Pause (SYM_OR_REM) */
-#define GPC_PHYADDR_4  BIT_12  /* Bit 4 of Phy Addr */
-#define GPC_PHYADDR_3  BIT_11  /* Bit 3 of Phy Addr */
-#define GPC_PHYADDR_2  BIT_10  /* Bit 2 of Phy Addr */
-#define GPC_PHYADDR_1  BIT_9   /* Bit 1 of Phy Addr */
-#define GPC_PHYADDR_0  BIT_8   /* Bit 0 of Phy Addr */
-                                               /* Bits  7..2:  reserved */
-#define GPC_RST_CLR            BIT_1   /* Clear GPHY Reset */
-#define GPC_RST_SET            BIT_0   /* Set   GPHY Reset */
-
-#define GPC_HWCFG_GMII_COP     (GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | \
-                                                        GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
-
-#define GPC_HWCFG_GMII_FIB     (                                GPC_HWCFG_M_2 | \
-                                                        GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
-
-#define GPC_ANEG_ADV_ALL_M     (GPC_ANEG_3 | GPC_ANEG_2 | \
-                                                        GPC_ANEG_1 | GPC_ANEG_0)
-
-/* forced speed and duplex mode (don't mix with other ANEG bits) */
-#define GPC_FRC10MBIT_HALF     0
-#define GPC_FRC10MBIT_FULL     GPC_ANEG_0
-#define GPC_FRC100MBIT_HALF    GPC_ANEG_1
-#define GPC_FRC100MBIT_FULL    (GPC_ANEG_0 | GPC_ANEG_1)
-
-/* auto-negotiation with limited advertised speeds */
-/* mix only with master/slave settings (for copper) */
-#define GPC_ADV_1000_HALF      GPC_ANEG_2
-#define GPC_ADV_1000_FULL      GPC_ANEG_3
-#define GPC_ADV_ALL                    (GPC_ANEG_2 | GPC_ANEG_3)
-
-/* master/slave settings */
-/* only for copper with 1000 Mbps */
-#define GPC_FORCE_MASTER       0
-#define GPC_FORCE_SLAVE                GPC_ANEG_0
-#define GPC_PREF_MASTER                GPC_ANEG_1
-#define GPC_PREF_SLAVE         (GPC_ANEG_1 | GPC_ANEG_0)
-
-/*     GMAC_IRQ_SRC     8 bit  GMAC Interrupt Source Reg (YUKON only) */
-/*     GMAC_IRQ_MSK     8 bit  GMAC Interrupt Mask   Reg (YUKON only) */
-#define GM_IS_TX_CO_OV BIT_5           /* Transmit Counter Overflow IRQ */
-#define GM_IS_RX_CO_OV BIT_4           /* Receive Counter Overflow IRQ */
-#define GM_IS_TX_FF_UR BIT_3           /* Transmit FIFO Underrun */
-#define GM_IS_TX_COMPL BIT_2           /* Frame Transmission Complete */
-#define GM_IS_RX_FF_OR BIT_1           /* Receive FIFO Overrun */
-#define GM_IS_RX_COMPL BIT_0           /* Frame Reception Complete */
-
-#define GMAC_DEF_MSK   (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \
-                                               GM_IS_TX_FF_UR)
-
-/*     GMAC_LINK_CTRL          16 bit  GMAC Link Control Reg (YUKON only) */
-                                               /* Bits 15.. 2: reserved */
-#define GMLC_RST_CLR   BIT_1S          /* Clear GMAC Link Reset */
-#define GMLC_RST_SET   BIT_0S          /* Set   GMAC Link Reset */
-
-
-/*     WOL_CTRL_STAT           16 bit  WOL Control/Status Reg */
-#define WOL_CTL_LINK_CHG_OCC                   BIT_15S
-#define WOL_CTL_MAGIC_PKT_OCC                  BIT_14S
-#define WOL_CTL_PATTERN_OCC                            BIT_13S
-
-#define WOL_CTL_CLEAR_RESULT                   BIT_12S
-
-#define WOL_CTL_ENA_PME_ON_LINK_CHG            BIT_11S
-#define WOL_CTL_DIS_PME_ON_LINK_CHG            BIT_10S
-#define WOL_CTL_ENA_PME_ON_MAGIC_PKT   BIT_9S
-#define WOL_CTL_DIS_PME_ON_MAGIC_PKT   BIT_8S
-#define WOL_CTL_ENA_PME_ON_PATTERN             BIT_7S
-#define WOL_CTL_DIS_PME_ON_PATTERN             BIT_6S
-
-#define WOL_CTL_ENA_LINK_CHG_UNIT              BIT_5S
-#define WOL_CTL_DIS_LINK_CHG_UNIT              BIT_4S
-#define WOL_CTL_ENA_MAGIC_PKT_UNIT             BIT_3S
-#define WOL_CTL_DIS_MAGIC_PKT_UNIT             BIT_2S
-#define WOL_CTL_ENA_PATTERN_UNIT               BIT_1S
-#define WOL_CTL_DIS_PATTERN_UNIT               BIT_0S
-
-#define WOL_CTL_DEFAULT                                \
-       (WOL_CTL_DIS_PME_ON_LINK_CHG |  \
-       WOL_CTL_DIS_PME_ON_PATTERN |    \
-       WOL_CTL_DIS_PME_ON_MAGIC_PKT |  \
-       WOL_CTL_DIS_LINK_CHG_UNIT |             \
-       WOL_CTL_DIS_PATTERN_UNIT |              \
-       WOL_CTL_DIS_MAGIC_PKT_UNIT)
-
-/*     WOL_MATCH_CTL            8 bit  WOL Match Control Reg */
-#define WOL_CTL_PATT_ENA(x)                            (BIT_0 << (x))
-
-#define SK_NUM_WOL_PATTERN             7
-#define SK_PATTERN_PER_WORD            4
-#define SK_BITMASK_PATTERN             7
-#define SK_POW_PATTERN_LENGTH  128
-
-#define WOL_LENGTH_MSK         0x7f
-#define WOL_LENGTH_SHIFT       8
-
-
-/* Receive and Transmit Descriptors ******************************************/
-
-/* Transmit Descriptor struct */
-typedef        struct s_HwTxd {
-       SK_U32 volatile TxCtrl; /* Transmit Buffer Control Field */
-       SK_U32  TxNext;                 /* Physical Address Pointer to the next TxD */
-       SK_U32  TxAdrLo;                /* Physical Tx Buffer Address lower dword */
-       SK_U32  TxAdrHi;                /* Physical Tx Buffer Address upper dword */
-       SK_U32  TxStat;                 /* Transmit Frame Status Word */
-#ifndef        SK_USE_REV_DESC
-       SK_U16  TxTcpOffs;              /* TCP Checksum Calculation Start Value */
-       SK_U16  TxRes1;                 /* 16 bit reserved field */
-       SK_U16  TxTcpWp;                /* TCP Checksum Write Position */
-       SK_U16  TxTcpSp;                /* TCP Checksum Calculation Start Position */
-#else  /* SK_USE_REV_DESC */
-       SK_U16  TxRes1;                 /* 16 bit reserved field */
-       SK_U16  TxTcpOffs;              /* TCP Checksum Calculation Start Value */
-       SK_U16  TxTcpSp;                /* TCP Checksum Calculation Start Position */
-       SK_U16  TxTcpWp;                /* TCP Checksum Write Position */
-#endif /* SK_USE_REV_DESC */
-       SK_U32  TxRes2;                 /* 32 bit reserved field */
-} SK_HWTXD;
-
-/* Receive Descriptor struct */
-typedef        struct s_HwRxd {
-       SK_U32 volatile RxCtrl; /* Receive Buffer Control Field */
-       SK_U32  RxNext;                 /* Physical Address Pointer to the next RxD */
-       SK_U32  RxAdrLo;                /* Physical Rx Buffer Address lower dword */
-       SK_U32  RxAdrHi;                /* Physical Rx Buffer Address upper dword */
-       SK_U32  RxStat;                 /* Receive Frame Status Word */
-       SK_U32  RxTiSt;                 /* Receive Time Stamp (from XMAC on GENESIS) */
-#ifndef        SK_USE_REV_DESC
-       SK_U16  RxTcpSum1;              /* TCP Checksum 1 */
-       SK_U16  RxTcpSum2;              /* TCP Checksum 2 */
-       SK_U16  RxTcpSp1;               /* TCP Checksum Calculation Start Position 1 */
-       SK_U16  RxTcpSp2;               /* TCP Checksum Calculation Start Position 2 */
-#else  /* SK_USE_REV_DESC */
-       SK_U16  RxTcpSum2;              /* TCP Checksum 2 */
-       SK_U16  RxTcpSum1;              /* TCP Checksum 1 */
-       SK_U16  RxTcpSp2;               /* TCP Checksum Calculation Start Position 2 */
-       SK_U16  RxTcpSp1;               /* TCP Checksum Calculation Start Position 1 */
-#endif /* SK_USE_REV_DESC */
-} SK_HWRXD;
-
-/*
- * Drivers which use the reverse descriptor feature (PCI_OUR_REG_2)
- * should set the define SK_USE_REV_DESC.
- * Structures are 'normaly' not endianess dependent. But in
- * this case the SK_U16 fields are bound to bit positions inside the
- * descriptor. RxTcpSum1 e.g. must start at bit 0 within the 6.th DWord.
- * The bit positions inside a DWord are of course endianess dependent and
- * swaps if the DWord is swapped by the hardware.
- */
-
-
-/* Descriptor Bit Definition */
-/*     TxCtrl          Transmit Buffer Control Field */
-/*     RxCtrl          Receive  Buffer Control Field */
-#define BMU_OWN                        BIT_31  /* OWN bit: 0=host/1=BMU */
-#define BMU_STF                        BIT_30  /* Start of Frame */
-#define BMU_EOF                        BIT_29  /* End of Frame */
-#define BMU_IRQ_EOB            BIT_28  /* Req "End of Buffer" IRQ */
-#define BMU_IRQ_EOF            BIT_27  /* Req "End of Frame" IRQ */
-/* TxCtrl specific bits */
-#define BMU_STFWD              BIT_26  /* (Tx) Store & Forward Frame */
-#define BMU_NO_FCS             BIT_25  /* (Tx) Disable MAC FCS (CRC) generation */
-#define BMU_SW                 BIT_24  /* (Tx) 1 bit res. for SW use */
-/* RxCtrl specific bits */
-#define BMU_DEV_0              BIT_26  /* (Rx) Transfer data to Dev0 */
-#define BMU_STAT_VAL   BIT_25  /* (Rx) Rx Status Valid */
-#define BMU_TIST_VAL   BIT_24  /* (Rx) Rx TimeStamp Valid */
-                                                               /* Bit 23..16:  BMU Check Opcodes */
-#define BMU_CHECK              (0x55L<<16)     /* Default BMU check */
-#define BMU_TCP_CHECK  (0x56L<<16)     /* Descr with TCP ext */
-#define BMU_UDP_CHECK  (0x57L<<16)     /* Descr with UDP ext (YUKON only) */
-#define BMU_BBC                        0xFFFFL /* Bit 15.. 0:  Buffer Byte Counter */
-
-/*     TxStat          Transmit Frame Status Word */
-/*     RxStat          Receive Frame Status Word */
-/*
- *Note: TxStat is reserved for ASIC loopback mode only
- *
- *     The Bits of the Status words are defined in xmac_ii.h
- *     (see XMR_FS bits)
- */
-
-/* other defines *************************************************************/
-
-/*
- * FlashProm specification
- */
-#define MAX_PAGES      0x20000L        /* Every byte has a single page */
-#define MAX_FADDR      1                       /* 1 byte per page */
-#define SKFDDI_PSZ     8                       /* address PROM size */
-
-/* macros ********************************************************************/
-
-/*
- * Receive and Transmit Queues
- */
-#define Q_R1   0x0000          /* Receive Queue 1 */
-#define Q_R2   0x0080          /* Receive Queue 2 */
-#define Q_XS1  0x0200          /* Synchronous Transmit Queue 1 */
-#define Q_XA1  0x0280          /* Asynchronous Transmit Queue 1 */
-#define Q_XS2  0x0300          /* Synchronous Transmit Queue 2 */
-#define Q_XA2  0x0380          /* Asynchronous Transmit Queue 2 */
-
-/*
- *     Macro Q_ADDR()
- *
- *     Use this macro to access the Receive and Transmit Queue Registers.
- *
- * para:
- *     Queue   Queue to access.
- *                             Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2
- *     Offs    Queue register offset.
- *                             Values: Q_D, Q_DA_L ... Q_T2, Q_T3
- *
- * usage       SK_IN32(pAC, Q_ADDR(Q_R2, Q_BC), pVal)
- */
-#define Q_ADDR(Queue, Offs)    (B8_Q_REGS + (Queue) + (Offs))
-
-/*
- *     Macro RB_ADDR()
- *
- *     Use this macro to access the RAM Buffer Registers.
- *
- * para:
- *     Queue   Queue to access.
- *                             Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2
- *     Offs    Queue register offset.
- *                             Values: RB_START, RB_END ... RB_LEV, RB_CTRL
- *
- * usage       SK_IN32(pAC, RB_ADDR(Q_R2, RB_RP), pVal)
- */
-#define RB_ADDR(Queue, Offs)   (B16_RAM_REGS + (Queue) + (Offs))
-
-
-/*
- * MAC Related Registers
- */
-#define MAC_1          0       /* belongs to the port near the slot */
-#define MAC_2          1       /* belongs to the port far away from the slot */
-
-/*
- *     Macro MR_ADDR()
- *
- *     Use this macro to access a MAC Related Registers inside the ASIC.
- *
- * para:
- *     Mac             MAC to access.
- *                             Values: MAC_1, MAC_2
- *     Offs    MAC register offset.
- *                             Values: RX_MFF_EA, RX_MFF_WP ... LNK_LED_REG,
- *                                             TX_MFF_EA, TX_MFF_WP ... TX_LED_TST
- *
- * usage       SK_IN32(pAC, MR_ADDR(MAC_1, TX_MFF_EA), pVal)
- */
-#define MR_ADDR(Mac, Offs)     (((Mac) << 7) + (Offs))
-
-#ifdef SK_LITTLE_ENDIAN
-#define XM_WORD_LO     0
-#define XM_WORD_HI     1
-#else  /* !SK_LITTLE_ENDIAN */
-#define XM_WORD_LO     1
-#define XM_WORD_HI     0
-#endif /* !SK_LITTLE_ENDIAN */
-
-
-/*
- * macros to access the XMAC (GENESIS only)
- *
- * XM_IN16(),          to read a 16 bit register (e.g. XM_MMU_CMD)
- * XM_OUT16(),         to write a 16 bit register (e.g. XM_MMU_CMD)
- * XM_IN32(),          to read a 32 bit register (e.g. XM_TX_EV_CNT)
- * XM_OUT32(),         to write a 32 bit register (e.g. XM_TX_EV_CNT)
- * XM_INADDR(),                to read a network address register (e.g. XM_SRC_CHK)
- * XM_OUTADDR(),       to write a network address register (e.g. XM_SRC_CHK)
- * XM_INHASH(),                to read the XM_HSM_CHK register
- * XM_OUTHASH()                to write the XM_HSM_CHK register
- *
- * para:
- *     Mac             XMAC to access          values: MAC_1 or MAC_2
- *     IoC             I/O context needed for SK I/O macros
- *     Reg             XMAC Register to read or write
- *     (p)Val  Value or pointer to the value which should be read or written
- *
- * usage:      XM_OUT16(IoC, MAC_1, XM_MMU_CMD, Value);
- */
-
-#define XMA(Mac, Reg)                                                                  \
-       ((BASE_XMAC_1 + (Mac) * (BASE_XMAC_2 - BASE_XMAC_1)) | ((Reg) << 1))
-
-#define XM_IN16(IoC, Mac, Reg, pVal)                                   \
-       SK_IN16((IoC), XMA((Mac), (Reg)), (pVal))
-
-#define XM_OUT16(IoC, Mac, Reg, Val)                                   \
-       SK_OUT16((IoC), XMA((Mac), (Reg)), (Val))
-
-#define XM_IN32(IoC, Mac, Reg, pVal) {                                 \
-       SK_IN16((IoC), XMA((Mac), (Reg)),                                       \
-               (SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_LO]);             \
-       SK_IN16((IoC), XMA((Mac), (Reg+2)),                                     \
-               (SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_HI]);             \
-}
-
-#define XM_OUT32(IoC, Mac, Reg, Val) {                                                                         \
-       SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL));                  \
-       SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)(((Val) >> 16) & 0xffffL));\
-}
-
-/* Remember: we are always writing to / reading from LITTLE ENDIAN memory */
-
-#define XM_INADDR(IoC, Mac, Reg, pVal) {                               \
-       SK_U16  Word;                                                                           \
-       SK_U8   *pByte;                                                                         \
-       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
-       SK_IN16((IoC), XMA((Mac), (Reg)), &Word);                       \
-       pByte[0] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word);                     \
-       pByte[2] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word);                     \
-       pByte[4] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-}
-
-#define XM_OUTADDR(IoC, Mac, Reg, pVal) {                              \
-       SK_U8   *pByte;                                                                         \
-       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
-       SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)                     \
-               (((SK_U16)(pByte[0]) & 0x00ff) |                                \
-               (((SK_U16)(pByte[1]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)           \
-               (((SK_U16)(pByte[2]) & 0x00ff) |                                \
-               (((SK_U16)(pByte[3]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16)           \
-               (((SK_U16)(pByte[4]) & 0x00ff) |                                \
-               (((SK_U16)(pByte[5]) << 8) & 0xff00)));                 \
-}
-
-#define XM_INHASH(IoC, Mac, Reg, pVal) {                               \
-       SK_U16  Word;                                                                           \
-       SK_U8   *pByte;                                                                         \
-       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
-       SK_IN16((IoC), XMA((Mac), (Reg)), &Word);                       \
-       pByte[0] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word);                     \
-       pByte[2] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word);                     \
-       pByte[4] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), XMA((Mac), (Reg+6)), &Word);                     \
-       pByte[6] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[7] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-}
-
-#define XM_OUTHASH(IoC, Mac, Reg, pVal) {                              \
-       SK_U8   *pByte;                                                                         \
-       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
-       SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)                     \
-               (((SK_U16)(pByte[0]) & 0x00ff)|                                 \
-               (((SK_U16)(pByte[1]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)           \
-               (((SK_U16)(pByte[2]) & 0x00ff)|                                 \
-               (((SK_U16)(pByte[3]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16)           \
-               (((SK_U16)(pByte[4]) & 0x00ff)|                                 \
-               (((SK_U16)(pByte[5]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), XMA((Mac), (Reg+6)), (SK_U16)           \
-               (((SK_U16)(pByte[6]) & 0x00ff)|                                 \
-               (((SK_U16)(pByte[7]) << 8) & 0xff00)));                 \
-}
-
-/*
- * macros to access the GMAC (YUKON only)
- *
- * GM_IN16(),          to read  a 16 bit register (e.g. GM_GP_STAT)
- * GM_OUT16(),         to write a 16 bit register (e.g. GM_GP_CTRL)
- * GM_IN32(),          to read  a 32 bit register (e.g. GM_)
- * GM_OUT32(),         to write a 32 bit register (e.g. GM_)
- * GM_INADDR(),                to read  a network address register (e.g. GM_SRC_ADDR_1L)
- * GM_OUTADDR(),       to write a network address register (e.g. GM_SRC_ADDR_2L)
- * GM_INHASH(),                to read  the GM_MC_ADDR_H1 register
- * GM_OUTHASH()                to write the GM_MC_ADDR_H1 register
- *
- * para:
- *     Mac             GMAC to access          values: MAC_1 or MAC_2
- *     IoC             I/O context needed for SK I/O macros
- *     Reg             GMAC Register to read or write
- *     (p)Val  Value or pointer to the value which should be read or written
- *
- * usage:      GM_OUT16(IoC, MAC_1, GM_GP_CTRL, Value);
- */
-
-#define GMA(Mac, Reg)                                                                  \
-       ((BASE_GMAC_1 + (Mac) * (BASE_GMAC_2 - BASE_GMAC_1)) | (Reg))
-
-#define GM_IN16(IoC, Mac, Reg, pVal)                                   \
-       SK_IN16((IoC), GMA((Mac), (Reg)), (pVal))
-
-#define GM_OUT16(IoC, Mac, Reg, Val)                                   \
-       SK_OUT16((IoC), GMA((Mac), (Reg)), (Val))
-
-#define GM_IN32(IoC, Mac, Reg, pVal) {                                 \
-       SK_IN16((IoC), GMA((Mac), (Reg)),                                       \
-               (SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_LO]);             \
-       SK_IN16((IoC), GMA((Mac), (Reg+4)),                                     \
-               (SK_U16 *)&((SK_U16 *)(pVal))[XM_WORD_HI]);             \
-}
-
-#define GM_OUT32(IoC, Mac, Reg, Val) {                                                                         \
-       SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL));                  \
-       SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)(((Val) >> 16) & 0xffffL));\
-}
-
-#define GM_INADDR(IoC, Mac, Reg, pVal) {                               \
-       SK_U16  Word;                                                                           \
-       SK_U8   *pByte;                                                                         \
-       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
-       SK_IN16((IoC), GMA((Mac), (Reg)), &Word);                       \
-       pByte[0] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word);                     \
-       pByte[2] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word);                     \
-       pByte[4] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-}
-
-#define GM_OUTADDR(IoC, Mac, Reg, pVal) {                              \
-       SK_U8   *pByte;                                                                         \
-       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
-       SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)                     \
-               (((SK_U16)(pByte[0]) & 0x00ff) |                                \
-               (((SK_U16)(pByte[1]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)           \
-               (((SK_U16)(pByte[2]) & 0x00ff) |                                \
-               (((SK_U16)(pByte[3]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16)           \
-               (((SK_U16)(pByte[4]) & 0x00ff) |                                \
-               (((SK_U16)(pByte[5]) << 8) & 0xff00)));                 \
-}
-
-#define GM_INHASH(IoC, Mac, Reg, pVal) {                               \
-       SK_U16  Word;                                                                           \
-       SK_U8   *pByte;                                                                         \
-       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
-       SK_IN16((IoC), GMA((Mac), (Reg)), &Word);                       \
-       pByte[0] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word);                     \
-       pByte[2] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word);                     \
-       pByte[4] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), GMA((Mac), (Reg+12)), &Word);            \
-       pByte[6] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[7] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-}
-
-#define GM_OUTHASH(IoC, Mac, Reg, pVal) {                              \
-       SK_U8   *pByte;                                                                         \
-       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
-       SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)                     \
-               (((SK_U16)(pByte[0]) & 0x00ff)|                                 \
-               (((SK_U16)(pByte[1]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)           \
-               (((SK_U16)(pByte[2]) & 0x00ff)|                                 \
-               (((SK_U16)(pByte[3]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16)           \
-               (((SK_U16)(pByte[4]) & 0x00ff)|                                 \
-               (((SK_U16)(pByte[5]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), GMA((Mac), (Reg+12)), (SK_U16)          \
-               (((SK_U16)(pByte[6]) & 0x00ff)|                                 \
-               (((SK_U16)(pByte[7]) << 8) & 0xff00)));                 \
-}
-
-/*
- * Different MAC Types
- */
-#define SK_MAC_XMAC            0       /* Xaqti XMAC II */
-#define SK_MAC_GMAC            1       /* Marvell GMAC */
-
-/*
- * Different PHY Types
- */
-#define SK_PHY_XMAC                    0       /* integrated in XMAC II */
-#define SK_PHY_BCOM                    1       /* Broadcom BCM5400 */
-#define SK_PHY_LONE                    2       /* Level One LXT1000 */
-#define SK_PHY_NAT                     3       /* National DP83891 */
-#define SK_PHY_MARV_COPPER     4       /* Marvell 88E1011S */
-#define SK_PHY_MARV_FIBER      5       /* Marvell 88E1011S working on fiber */
-
-/*
- * PHY addresses (bits 12..8 of PHY address reg)
- */
-#define PHY_ADDR_XMAC  (0<<8)
-#define PHY_ADDR_BCOM  (1<<8)
-#define PHY_ADDR_LONE  (3<<8)
-#define PHY_ADDR_NAT   (0<<8)
-
-/* GPHY address (bits 15..11 of SMI control reg) */
-#define PHY_ADDR_MARV  0
-
-/*
- * macros to access the PHY
- *
- * PHY_READ()          read a 16 bit value from the PHY
- * PHY_WRITE()         write a 16 bit value to the PHY
- *
- * para:
- *     IoC             I/O context needed for SK I/O macros
- *     pPort   Pointer to port struct for PhyAddr
- *     Mac             XMAC to access          values: MAC_1 or MAC_2
- *     PhyReg  PHY Register to read or write
- *     (p)Val  Value or pointer to the value which should be read or
- *                     written.
- *
- * usage:      PHY_READ(IoC, pPort, MAC_1, PHY_CTRL, Value);
- * Warning: a PHY_READ on an uninitialized PHY (PHY still in reset) never
- *          comes back. This is checked in DEBUG mode.
- */
-#ifndef DEBUG
-#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) {                                              \
-       SK_U16 Mmu;                                                                                                             \
-                                                                                                                                               \
-       XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr);       \
-       XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));                                                     \
-       if ((pPort)->PhyType != SK_PHY_XMAC) {                                                          \
-               do {                                                                                                                    \
-                       XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);                                        \
-               } while ((Mmu & XM_MMU_PHY_RDY) == 0);                                                  \
-               XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));                                             \
-       }                                                                                                                                       \
-}
-#else
-#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) {                                              \
-       SK_U16 Mmu;                                                                                                             \
-       int __i = 0;                                                                                                            \
-                                                                                                                                               \
-       XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr);       \
-       XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));                                                     \
-       if ((pPort)->PhyType != SK_PHY_XMAC) {                                                          \
-               do {                                                                                                                    \
-                       XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);                                        \
-                       __i++;                                                                                                          \
-                       if (__i > 100000) {                                                                                     \
-                               SK_DBG_PRINTF("*****************************\n");               \
-                               SK_DBG_PRINTF("PHY_READ on uninitialized PHY\n");               \
-                               SK_DBG_PRINTF("*****************************\n");               \
-                               break;                                                                                                  \
-                       }                                                                                                                       \
-               } while ((Mmu & XM_MMU_PHY_RDY) == 0);                                                  \
-               XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));                                             \
-       }                                                                                                                                       \
-}
-#endif /* DEBUG */
-
-#define PHY_WRITE(IoC, pPort, Mac, PhyReg, Val) {                                              \
-       SK_U16 Mmu;                                                                                                                     \
-                                                                                                                                               \
-       if ((pPort)->PhyType != SK_PHY_XMAC) {                                                          \
-               do {                                                                                                                    \
-                       XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);                                        \
-               } while ((Mmu & XM_MMU_PHY_BUSY) != 0);                                                 \
-       }                                                                                                                                       \
-       XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr);       \
-       XM_OUT16((IoC), (Mac), XM_PHY_DATA, (Val));                                                     \
-       if ((pPort)->PhyType != SK_PHY_XMAC) {                                                          \
-               do {                                                                                                                    \
-                       XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);                                        \
-               } while ((Mmu & XM_MMU_PHY_BUSY) != 0);                                                 \
-       }                                                                                                                                       \
-}
-
-/*
- *     Macro PCI_C()
- *
- *     Use this macro to access PCI config register from the I/O space.
- *
- * para:
- *     Addr    PCI configuration register to access.
- *                     Values: PCI_VENDOR_ID ... PCI_VPD_ADR_REG,
- *
- * usage       SK_IN16(pAC, PCI_C(PCI_VENDOR_ID), pVal);
- */
-#define PCI_C(Addr)    (B7_CFG_SPC + (Addr))   /* PCI Config Space */
-
-/*
- *     Macro SK_HW_ADDR(Base, Addr)
- *
- *     Calculates the effective HW address
- *
- * para:
- *     Base    I/O or memory base address
- *     Addr    Address offset
- *
- * usage:      May be used in SK_INxx and SK_OUTxx macros
- *             #define SK_IN8(pAC, Addr, pVal) ...\
- *                     *pVal = (SK_U8)inp(SK_HW_ADDR(pAC->Hw.Iop, Addr)))
- */
-#ifdef SK_MEM_MAPPED_IO
-#define SK_HW_ADDR(Base, Addr) ((Base) + (Addr))
-#else  /* SK_MEM_MAPPED_IO */
-#define SK_HW_ADDR(Base, Addr) \
-                       ((Base) + (((Addr) & 0x7f) | (((Addr) >> 7 > 0) ? 0x80 : 0)))
-#endif /* SK_MEM_MAPPED_IO */
-
-#define SZ_LONG        (sizeof(SK_U32))
-
-/*
- *     Macro SK_HWAC_LINK_LED()
- *
- *     Use this macro to set the link LED mode.
- * para:
- *     pAC             Pointer to adapter context struct
- *     IoC             I/O context needed for SK I/O macros
- *  Port       Port number
- *     Mode    Mode to set for this LED
- */
-#define SK_HWAC_LINK_LED(pAC, IoC, Port, Mode) \
-       SK_OUT8(IoC, MR_ADDR(Port, LNK_LED_REG), Mode);
-
-
-/* typedefs *******************************************************************/
-
-
-/* function prototypes ********************************************************/
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_SKGEHW_H */
diff --git a/drivers/sk98lin/h/skgehwt.h b/drivers/sk98lin/h/skgehwt.h
deleted file mode 100644 (file)
index 8aa9edd..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/******************************************************************************
- *
- * Name:       skhwt.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.5 $
- * Date:       $Date: 1999/11/22 13:54:24 $
- * Purpose:    Defines for the hardware timer functions
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998,1999 SysKonnect,
- *     a business unit of Schneider & Koch & Co. Datensysteme GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skgehwt.h,v $
- *     Revision 1.5  1999/11/22 13:54:24  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.4  1998/08/19 09:50:58  gklug
- *     fix: remove struct keyword from c-code (see CCC) add typedefs
- *
- *     Revision 1.3  1998/08/14 07:09:29  gklug
- *     fix: chg pAc -> pAC
- *
- *     Revision 1.2  1998/08/07 12:54:21  gklug
- *     fix: first compiled version
- *
- *     Revision 1.1  1998/08/07 09:32:58  gklug
- *     first version
- *
- *
- *
- *
- *
- ******************************************************************************/
-
-/*
- * SKGEHWT.H   contains all defines and types for the timer functions
- */
-
-#ifndef        _SKGEHWT_H_
-#define _SKGEHWT_H_
-
-/*
- * SK Hardware Timer
- * - needed wherever the HWT module is used
- * - use in Adapters context name pAC->Hwt
- */
-typedef        struct s_Hwt {
-       SK_U32          TStart ;        /* HWT start */
-       SK_U32          TStop ;         /* HWT stop */
-       int             TActive ;       /* HWT: flag : active/inactive */
-} SK_HWT;
-
-extern void SkHwtInit(SK_AC *pAC, SK_IOC Ioc);
-extern void SkHwtStart(SK_AC *pAC, SK_IOC Ioc, SK_U32 Time);
-extern void SkHwtStop(SK_AC *pAC, SK_IOC Ioc);
-extern SK_U32 SkHwtRead(SK_AC *pAC,SK_IOC Ioc);
-extern void SkHwtIsr(SK_AC *pAC, SK_IOC Ioc);
-#endif /* _SKGEHWT_H_ */
diff --git a/drivers/sk98lin/h/skgei2c.h b/drivers/sk98lin/h/skgei2c.h
deleted file mode 100644 (file)
index e639f73..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-/******************************************************************************
- *
- * Name:       skgei2c.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.23 $
- * Date:       $Date: 2002/12/19 14:34:27 $
- * Purpose:    Special GEnesis defines for TWSI
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skgei2c.h,v $
- *     Revision 1.23  2002/12/19 14:34:27  rschmidt
- *     Added cast in macros SK_I2C_SET_BIT() and SK_I2C_CLR_BIT()
- *     Editorial changes (TWSI)
- *
- *     Revision 1.22  2002/10/14 16:45:56  rschmidt
- *     Editorial changes (TWSI)
- *
- *     Revision 1.21  2002/08/13 08:42:24  rschmidt
- *     Changed define for SK_MIN_SENSORS back to 5
- *     Merged defines for PHY PLL 3V3 voltage (A and B)
- *     Editorial changes
- *
- *     Revision 1.20  2002/08/06 09:43:56  jschmalz
- *     Extensions and changes for Yukon
- *
- *     Revision 1.19  2002/08/02 12:00:08  rschmidt
- *     Added defines for YUKON sensors
- *     Editorial changes
- *
- *     Revision 1.18  2001/08/16 12:44:33  afischer
- *     LM80 sensor init values corrected
- *
- *     Revision 1.17  1999/11/22 13:55:25  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.16  1999/11/12 08:24:10  malthoff
- *     Change voltage warning and error limits
- *     (warning +-5%, error +-10%).
- *
- *     Revision 1.15  1999/09/14 14:14:43  malthoff
- *     The 1000BT Dual Link adapter has got only one Fan.
- *     The second Fan has been removed.
- *
- *     Revision 1.14  1999/05/27 13:40:50  malthoff
- *     Fan Divisor = 1. Assuming fan with 6500 rpm.
- *
- *     Revision 1.13  1999/05/20 14:56:55  malthoff
- *     Bug Fix: Missing brace in SK_LM80_FAN_FAKTOR.
- *
- *     Revision 1.12  1999/05/20 09:22:00  cgoos
- *     Changes for 1000Base-T (Fan sensors).
- *
- *     Revision 1.11  1998/10/14 05:57:22  cgoos
- *     Fixed compilation warnings.
- *
- *     Revision 1.10  1998/09/04 08:37:00  malthoff
- *     bugfix: correct the SK_I2C_GET_CTL() macro.
- *
- *     Revision 1.9  1998/08/25 06:10:03  gklug
- *     add: thresholds for all sensors
- *
- *     Revision 1.8  1998/08/20 11:37:42  gklug
- *     chg: change Ioc to IoC
- *
- *     Revision 1.7  1998/08/20 08:53:11  gklug
- *     fix: compiler errors
- *     add: Threshold values
- *
- *     Revision 1.6  1998/08/17 11:37:09  malthoff
- *     Bugfix in SK_I2C_CTL macro. The parameter 'dev'
- *     has to be shifted 9 bits.
- *
- *     Revision 1.5  1998/08/17 06:52:21  malthoff
- *     Remove unrequired macros.
- *     Add macros for accessing TWSI SW register.
- *
- *     Revision 1.4  1998/08/13 08:30:18  gklug
- *     add: conversion factors for read values
- *     add: new state SEN_VALEXT to read extension value of temperature sensor
- *
- *     Revision 1.3  1998/08/12 13:37:56  gklug
- *     rmv: error numbers and messages
- *
- *     Revision 1.2  1998/08/11 07:54:38  gklug
- *     add: sensor states for GE sensors
- *     add: Macro to access TWSI hardware register
- *     chg: Error messages for TWSI errors
- *
- *     Revision 1.1  1998/07/17 11:27:56  gklug
- *     Created.
- *
- *
- *
- ******************************************************************************/
-
-/*
- * SKGEI2C.H   contains all SK-98xx specific defines for the TWSI handling
- */
-
-#ifndef _INC_SKGEI2C_H_
-#define _INC_SKGEI2C_H_
-
-/*
- * Macros to access the B2_I2C_CTRL
- */
-#define SK_I2C_CTL(IoC, flag, dev, reg, burst) \
-       SK_OUT32(IoC, B2_I2C_CTRL,\
-               (flag ? 0x80000000UL : 0x0L) | \
-               (((SK_U32) reg << 16) & I2C_ADDR) | \
-               (((SK_U32) dev << 9) & I2C_DEV_SEL) | \
-               (( burst << 4) & I2C_BURST_LEN))
-
-#define SK_I2C_STOP(IoC) {                             \
-       SK_U32  I2cCtrl;                                \
-       SK_IN32(IoC, B2_I2C_CTRL, &I2cCtrl);            \
-       SK_OUT32(IoC, B2_I2C_CTRL, I2cCtrl | I2C_STOP); \
-}
-
-#define SK_I2C_GET_CTL(IoC, pI2cCtrl)  SK_IN32(IoC, B2_I2C_CTRL, pI2cCtrl)
-
-/*
- * Macros to access the TWSI SW Registers
- */
-#define SK_I2C_SET_BIT(IoC, SetBits) {                 \
-       SK_U8   OrgBits;                                \
-       SK_IN8(IoC, B2_I2C_SW, &OrgBits);               \
-       SK_OUT8(IoC, B2_I2C_SW, OrgBits | (SK_U8)(SetBits));    \
-}
-
-#define SK_I2C_CLR_BIT(IoC, ClrBits) {                 \
-       SK_U8   OrgBits;                                \
-       SK_IN8(IoC, B2_I2C_SW, &OrgBits);               \
-       SK_OUT8(IoC, B2_I2C_SW, OrgBits & ~((SK_U8)(ClrBits))); \
-}
-
-#define SK_I2C_GET_SW(IoC, pI2cSw)     SK_IN8(IoC, B2_I2C_SW, pI2cSw)
-
-/*
- * define the possible sensor states
- */
-#define        SK_SEN_IDLE             0       /* Idle: sensor not read */
-#define        SK_SEN_VALUE    1       /* Value Read cycle */
-#define        SK_SEN_VALEXT   2       /* Extended Value Read cycle */
-
-/*
- * Conversion factor to convert read Voltage sensor to milli Volt
- * Conversion factor to convert read Temperature sensor to 10th degree Celsius
- */
-#define        SK_LM80_VT_LSB          22      /* 22mV LSB resolution */
-#define        SK_LM80_TEMP_LSB        10      /* 1 degree LSB resolution */
-#define        SK_LM80_TEMPEXT_LSB     5       /* 0.5 degree LSB resolution for the
-                                        * extension value
-                                        */
-#define SK_LM80_FAN_FAKTOR     ((22500L*60)/(1*2))
-/* formula: counter = (22500*60)/(rpm * divisor * pulses/2)
- * assuming: 6500rpm, 4 pulses, divisor 1
- */
-
-/*
- * Define sensor management data
- * Maximum is reached on copperfield with dual Broadcom.
- * Board specific maximum is in pAC->I2c.MaxSens
- */
-#define        SK_MAX_SENSORS  8       /* maximal no. of installed sensors */
-#define        SK_MIN_SENSORS  5       /* minimal no. of installed sensors */
-
-/*
- * To watch the statemachine (JS) use the timer in two ways instead of one as hitherto
- */
-#define        SK_TIMER_WATCH_STATEMACHINE     0       /* Watch the statemachine to finish in a specific time */
-#define        SK_TIMER_NEW_GAUGING            1       /* Start a new gauging when timer expires */
-
-
-/*
- * Defines for the individual Thresholds
- */
-
-/* Temperature sensor */
-#define        SK_SEN_TEMP_HIGH_ERR    800     /* Temperature High Err  Threshold */
-#define        SK_SEN_TEMP_HIGH_WARN   700     /* Temperature High Warn Threshold */
-#define        SK_SEN_TEMP_LOW_WARN    100     /* Temperature Low  Warn Threshold */
-#define        SK_SEN_TEMP_LOW_ERR       0     /* Temperature Low  Err  Threshold */
-
-/* VCC which should be 5 V */
-#define        SK_SEN_PCI_5V_HIGH_ERR          5588    /* Voltage PCI High Err  Threshold */
-#define        SK_SEN_PCI_5V_HIGH_WARN     5346        /* Voltage PCI High Warn Threshold */
-#define        SK_SEN_PCI_5V_LOW_WARN          4664    /* Voltage PCI Low  Warn Threshold */
-#define        SK_SEN_PCI_5V_LOW_ERR           4422    /* Voltage PCI Low  Err  Threshold */
-
-/*
- * VIO may be 5 V or 3.3 V. Initialization takes two parts:
- * 1. Initialize lowest lower limit and highest higher limit.
- * 2. After the first value is read correct the upper or the lower limit to
- *    the appropriate C constant.
- *
- * Warning limits are +-5% of the exepected voltage.
- * Error limits are +-10% of the expected voltage.
- */
-
-/* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */
-
-#define        SK_SEN_PCI_IO_5V_HIGH_ERR       5566    /* + 10% V PCI-IO High Err Threshold */
-#define        SK_SEN_PCI_IO_5V_HIGH_WARN      5324    /* +  5% V PCI-IO High Warn Threshold */
-                                       /*              5000    mVolt */
-#define        SK_SEN_PCI_IO_5V_LOW_WARN       4686    /* -  5% V PCI-IO Low Warn Threshold */
-#define        SK_SEN_PCI_IO_5V_LOW_ERR        4444    /* - 10% V PCI-IO Low Err Threshold */
-
-#define        SK_SEN_PCI_IO_RANGE_LIMITER     4000    /* 4000 mV range delimiter */
-
-/* correction values for the second pass */
-#define        SK_SEN_PCI_IO_3V3_HIGH_ERR      3850    /* + 15% V PCI-IO High Err Threshold */
-#define        SK_SEN_PCI_IO_3V3_HIGH_WARN     3674    /* + 10% V PCI-IO High Warn Threshold */
-                                       /*              3300    mVolt */
-#define        SK_SEN_PCI_IO_3V3_LOW_WARN  2926        /* - 10% V PCI-IO Low Warn Threshold */
-#define        SK_SEN_PCI_IO_3V3_LOW_ERR   2772        /* - 15% V PCI-IO Low Err  Threshold */
-
-
-/*
- * VDD voltage
- */
-#define        SK_SEN_VDD_HIGH_ERR         3630        /* Voltage ASIC High Err  Threshold */
-#define        SK_SEN_VDD_HIGH_WARN    3476    /* Voltage ASIC High Warn Threshold */
-#define        SK_SEN_VDD_LOW_WARN     3146    /* Voltage ASIC Low  Warn Threshold */
-#define        SK_SEN_VDD_LOW_ERR      2970    /* Voltage ASIC Low  Err  Threshold */
-
-/*
- * PHY PLL 3V3 voltage
- */
-#define        SK_SEN_PLL_3V3_HIGH_ERR         3630    /* Voltage PMA High Err  Threshold */
-#define        SK_SEN_PLL_3V3_HIGH_WARN        3476    /* Voltage PMA High Warn Threshold */
-#define        SK_SEN_PLL_3V3_LOW_WARN         3146    /* Voltage PMA Low  Warn Threshold */
-#define        SK_SEN_PLL_3V3_LOW_ERR          2970    /* Voltage PMA Low  Err  Threshold */
-
-/*
- * VAUX (YUKON only)
- */
-#define        SK_SEN_VAUX_3V3_HIGH_ERR        3630    /* Voltage VAUX High Err Threshold */
-#define        SK_SEN_VAUX_3V3_HIGH_WARN       3476    /* Voltage VAUX High Warn Threshold */
-#define        SK_SEN_VAUX_3V3_LOW_WARN        3146    /* Voltage VAUX Low Warn Threshold */
-#define        SK_SEN_VAUX_3V3_LOW_ERR     2970        /* Voltage VAUX Low Err Threshold */
-#define        SK_SEN_VAUX_0V_WARN_ERR        0        /* if VAUX not present */
-#define        SK_SEN_VAUX_RANGE_LIMITER       1000    /* 1000 mV range delimiter */
-
-/*
- * PHY 2V5 voltage
- */
-#define        SK_SEN_PHY_2V5_HIGH_ERR         2750    /* Voltage PHY High Err Threshold */
-#define        SK_SEN_PHY_2V5_HIGH_WARN        2640    /* Voltage PHY High Warn Threshold */
-#define        SK_SEN_PHY_2V5_LOW_WARN         2376    /* Voltage PHY Low Warn Threshold */
-#define        SK_SEN_PHY_2V5_LOW_ERR          2222    /* Voltage PHY Low Err Threshold */
-
-/*
- * ASIC Core 1V5 voltage (YUKON only)
- */
-#define        SK_SEN_CORE_1V5_HIGH_ERR    1650        /* Voltage ASIC Core High Err Threshold */
-#define        SK_SEN_CORE_1V5_HIGH_WARN       1575    /* Voltage ASIC Core High Warn Threshold */
-#define        SK_SEN_CORE_1V5_LOW_WARN        1425    /* Voltage ASIC Core Low Warn Threshold */
-#define        SK_SEN_CORE_1V5_LOW_ERR         1350    /* Voltage ASIC Core Low Err Threshold */
-
-/*
- * FAN 1 speed
- */
-/* assuming: 6500rpm +-15%, 4 pulses,
- * warning at: 80 %
- * error at:   70 %
- * no upper limit
- */
-#define        SK_SEN_FAN_HIGH_ERR             20000   /* FAN Speed High Err Threshold */
-#define        SK_SEN_FAN_HIGH_WARN    20000   /* FAN Speed High Warn Threshold */
-#define        SK_SEN_FAN_LOW_WARN     5200    /* FAN Speed Low Warn Threshold */
-#define        SK_SEN_FAN_LOW_ERR              4550    /* FAN Speed Low Err Threshold */
-
-/*
- * Some Voltages need dynamic thresholds
- */
-#define        SK_SEN_DYN_INIT_NONE             0  /* No dynamic init of thresholds */
-#define        SK_SEN_DYN_INIT_PCI_IO          10  /* Init PCI-IO with new thresholds */
-#define        SK_SEN_DYN_INIT_VAUX            11  /* Init VAUX with new thresholds */
-
-extern int SkLm80ReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
-#endif /* n_INC_SKGEI2C_H */
diff --git a/drivers/sk98lin/h/skgeinit.h b/drivers/sk98lin/h/skgeinit.h
deleted file mode 100644 (file)
index cdddef9..0000000
+++ /dev/null
@@ -1,1113 +0,0 @@
-/******************************************************************************
- *
- * Name:       skgeinit.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.75 $
- * Date:       $Date: 2003/02/05 13:36:39 $
- * Purpose:    Structures and prototypes for the GE Init Module
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skgeinit.h,v $
- *     Revision 1.75  2003/02/05 13:36:39  rschmidt
- *     Added define SK_FACT_78 for YUKON's Host Clock of 78.12 MHz
- *     Editorial changes
- *
- *     Revision 1.74  2003/01/28 09:39:16  rschmidt
- *     Added entry GIYukonLite in s_GeInit structure
- *     Editorial changes
- *
- *     Revision 1.73  2002/11/15 12:47:25  rschmidt
- *     Replaced error message SKERR_HWI_E024 for Cable Diagnostic with
- *     Rx queue error in SkGeStopPort().
- *
- *     Revision 1.72  2002/11/12 17:08:35  rschmidt
- *     Added entries for Cable Diagnostic to Port structure
- *     Added entries GIPciSlot64 and GIPciClock66 in s_GeInit structure
- *     Added error message for Cable Diagnostic
- *     Added prototypes for SkGmCableDiagStatus()
- *     Editorial changes
- *
- *     Revision 1.71  2002/10/21 11:26:10  mkarl
- *     Changed interface of SkGeInitAssignRamToQueues().
- *
- *     Revision 1.70  2002/10/14 08:21:32  rschmidt
- *     Changed type of GICopperType, GIVauxAvail to SK_BOOL
- *     Added entry PRxOverCnt to Port structure
- *     Added entry GIYukon32Bit in s_GeInit structure
- *     Editorial changes
- *
- *     Revision 1.69  2002/10/09 16:57:15  mkarl
- *     Added some constants and macros for SkGeInitAssignRamToQueues().
- *
- *     Revision 1.68  2002/09/12 08:58:51  rwahl
- *     Retrieve counters needed for XMAC errata workarounds directly because
- *     PNMI returns corrected counter values (e.g. #10620).
- *
- *     Revision 1.67  2002/08/16 14:40:30  rschmidt
- *     Added entries GIGenesis and GICopperType in s_GeInit structure
- *     Added prototypes for SkMacHashing()
- *     Editorial changes
- *
- *     Revision 1.66  2002/08/12 13:27:21  rschmidt
- *     Added defines for Link speed capabilities
- *     Added entry PLinkSpeedCap to Port structure
- *     Added entry GIVauxAvail in s_GeInit structure
- *     Added prototypes for SkMacPromiscMode()
- *     Editorial changes
- *
- *     Revision 1.65  2002/08/08 15:46:18  rschmidt
- *     Added define SK_PHY_ACC_TO for PHY access timeout
- *     Added define SK_XM_RX_HI_WM for XMAC Rx High Watermark
- *     Added define SK_MIN_TXQ_SIZE for Min RAM Buffer Tx Queue Size
- *     Added entry PhyId1 to Port structure
- *
- *     Revision 1.64  2002/07/23 16:02:56  rschmidt
- *     Added entry GIWolOffs in s_GeInit struct (HW-Bug in YUKON 1st rev.)
- *     Added prototypes for: SkGePhyRead(), SkGePhyWrite()
- *
- *     Revision 1.63  2002/07/18 08:17:38  rwahl
- *     Corrected definitions for SK_LSPEED_xxx & SK_LSPEED_STAT_xxx.
- *
- *     Revision 1.62  2002/07/17 18:21:55  rwahl
- *     Added SK_LSPEED_INDETERMINATED define.
- *
- *     Revision 1.61  2002/07/17 17:16:03  rwahl
- *     - MacType now member of GIni struct.
- *     - Struct alignment to 32bit.
- *     - Editorial change.
- *
- *     Revision 1.60  2002/07/15 18:23:39  rwahl
- *     Added GeMacFunc to GE Init structure.
- *     Added prototypes for SkXmUpdateStats(), SkGmUpdateStats(),
- *       SkXmMacStatistic(), SkGmMacStatistic(), SkXmResetCounter(),
- *       SkGmResetCounter(), SkXmOverflowStatus(), SkGmOverflowStatus().
- *     Added defines for current link speed state.
- *     Added ERRMSG defintions for MacUpdateStat() & MacStatistics().
- *
- *     Revision 1.59  2002/07/15 15:40:22  rschmidt
- *     Added entry PLinkSpeedUsed to Port structure
- *     Editorial changes
- *
- *     Revision 1.58  2002/06/10 09:36:30  rschmidt
- *     Editorial changes.
- *
- *     Revision 1.57  2002/06/05 08:18:00  rschmidt
- *     Corrected alignment in Port Structure
- *     Added new prototypes for GMAC
- *     Editorial changes
- *
- *     Revision 1.56  2002/04/25 11:38:12  rschmidt
- *     Added defines for Link speed values
- *     Added defines for Loopback parameters for MAC and PHY
- *     Removed entry PRxCmd from Port structure
- *     Added entry PLinkSpeed to Port structure
- *     Added entries GIChipId and GIChipRev to GE Init structure
- *     Removed entry GIAnyPortAct from GE Init structure
- *     Added prototypes for: SkMacInit(), SkMacInitPhy(),
- *     SkMacRxTxDisable(), SkMacSoftRst(), SkMacHardRst(), SkMacIrq(),
- *     SkMacIrqDisable(), SkMacFlushTxFifo(), SkMacFlushRxFifo(),
- *     SkMacAutoNegDone(), SkMacAutoNegLipaPhy(), SkMacSetRxTxEn(),
- *     SkXmPhyRead(), SkXmPhyRead(), SkGmPhyWrite(), SkGmPhyWrite();
- *     Removed prototypes for static functions in SkXmac2.c
- *     Editorial changes
- *
- *     Revision 1.55  2002/02/26 15:24:53  rwahl
- *     Fix: no link with manual configuration (#10673). The previous fix for
- *     #10639 was removed. So for RLMT mode = CLS the RLMT may switch to
- *     misconfigured port. It should not occur for the other RLMT modes.
- *
- *     Revision 1.54  2002/01/18 16:52:52  rwahl
- *     Editorial corrections.
- *
- *     Revision 1.53  2001/11/20 09:19:58  rwahl
- *     Reworked bugfix #10639 (no dependency to RLMT mode).
- *
- *     Revision 1.52  2001/10/26 07:52:23  afischer
- *     Port switching bug in `check local link` mode
- *
- *     Revision 1.51  2001/02/09 12:26:38  cgoos
- *     Inserted #ifdef DIAG for half duplex workaround timer.
- *
- *     Revision 1.50  2001/02/07 07:56:40  rassmann
- *     Corrected copyright.
- *
- *     Revision 1.49  2001/01/31 15:32:18  gklug
- *     fix: problem with autosensing an SR8800 switch
- *     add: counter for autoneg timeouts
- *
- *     Revision 1.48  2000/11/09 11:30:10  rassmann
- *     WA: Waiting after releasing reset until BCom chip is accessible.
- *
- *     Revision 1.47  2000/10/18 12:22:40  cgoos
- *     Added workaround for half duplex hangup.
- *
- *     Revision 1.46  2000/08/10 11:28:00  rassmann
- *     Editorial changes.
- *     Preserving 32-bit alignment in structs for the adapter context.
- *
- *     Revision 1.45  1999/11/22 13:56:19  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.44  1999/10/26 07:34:15  malthoff
- *     The define SK_LNK_ON has been lost in v1.41.
- *
- *     Revision 1.43  1999/10/06 09:30:16  cgoos
- *     Changed SK_XM_THR_JUMBO.
- *
- *     Revision 1.42  1999/09/16 12:58:26  cgoos
- *     Changed SK_LED_STANDY macro to be independent of HW link sync.
- *
- *     Revision 1.41  1999/07/30 06:56:14  malthoff
- *     Correct comment for SK_MS_STAT_UNSET.
- *
- *     Revision 1.40  1999/05/27 13:38:46  cgoos
- *     Added SK_BMU_TX_WM.
- *     Made SK_BMU_TX_WM and SK_BMU_RX_WM user-definable.
- *     Changed XMAC Tx treshold to max. values.
- *
- *     Revision 1.39  1999/05/20 14:35:26  malthoff
- *     Remove prototypes for SkGeLinkLED().
- *
- *     Revision 1.38  1999/05/19 11:59:12  cgoos
- *     Added SK_MS_CAP_INDETERMINATED define.
- *
- *     Revision 1.37  1999/05/19 07:32:33  cgoos
- *     Changes for 1000Base-T.
- *     LED-defines for HWAC_LINK_LED macro.
- *
- *     Revision 1.36  1999/04/08 14:00:24  gklug
- *     add:Port struct field PLinkResCt
- *
- *     Revision 1.35  1999/03/25 07:43:07  malthoff
- *     Add error string for SKERR_HWI_E018MSG.
- *
- *     Revision 1.34  1999/03/12 16:25:57  malthoff
- *     Remove PPollRxD and PPollTxD.
- *     Add SKERR_HWI_E017MSG. and SK_DPOLL_MAX.
- *
- *     Revision 1.33  1999/03/12 13:34:41  malthoff
- *     Add Autonegotiation error codes.
- *     Change defines for parameter Mode in SkXmSetRxCmd().
- *     Replace __STDC__ by SK_KR_PROTO.
- *
- *     Revision 1.32  1999/01/25 14:40:20  mhaveman
- *     Added new return states for the virtual management port if multiple
- *     ports are active but differently configured.
- *
- *     Revision 1.31  1998/12/11 15:17:02  gklug
- *     add: Link partnet autoneg states : Unknown Manual and Auto-negotiation
- *
- *     Revision 1.30  1998/12/07 12:17:04  gklug
- *     add: Link Partner auto-negotiation flag
- *
- *     Revision 1.29  1998/12/01 10:54:42  gklug
- *     add: variables for XMAC Errata
- *
- *     Revision 1.28  1998/12/01 10:14:15  gklug
- *     add: PIsave saves the Interrupt status word
- *
- *     Revision 1.27  1998/11/26 15:24:52  mhaveman
- *     Added link status states SK_LMODE_STAT_AUTOHALF and
- *     SK_LMODE_STAT_AUTOFULL which are used by PNMI.
- *
- *     Revision 1.26  1998/11/26 14:53:01  gklug
- *     add:autoNeg Timeout variable
- *
- *     Revision 1.25  1998/11/26 08:58:50  gklug
- *     add: Link Mode configuration (AUTO Sense mode)
- *
- *     Revision 1.24  1998/11/24 13:30:27  gklug
- *     add: PCheckPar to port struct
- *
- *     Revision 1.23  1998/11/18 13:23:26  malthoff
- *     Add SK_PKT_TO_MAX.
- *
- *     Revision 1.22  1998/11/18 13:19:54  gklug
- *     add: PPrevShorts and PLinkBroken to port struct for WA XMAC Errata #C1
- *
- *     Revision 1.21  1998/10/26 08:02:57  malthoff
- *     Add GIRamOffs.
- *
- *     Revision 1.20  1998/10/19 07:28:37  malthoff
- *     Add prototype for SkGeInitRamIface().
- *
- *     Revision 1.19  1998/10/14 14:47:48  malthoff
- *     SK_TIMER should not be defined for Diagnostics.
- *     Add SKERR_HWI_E015MSG and SKERR_HWI_E016MSG.
- *
- *     Revision 1.18  1998/10/14 14:00:03  gklug
- *     add: timer to port struct for workaround of Errata #2
- *
- *     Revision 1.17  1998/10/14 11:23:09  malthoff
- *     Add prototype for SkXmAutoNegDone().
- *     Fix SkXmSetRxCmd() prototype statement.
- *
- *     Revision 1.16  1998/10/14 05:42:29  gklug
- *     add: HWLinkUp flag to Port struct
- *
- *     Revision 1.15  1998/10/09 08:26:33  malthoff
- *     Rename SK_RB_ULPP_B to SK_RB_LLPP_B.
- *
- *     Revision 1.14  1998/10/09 07:11:13  malthoff
- *     bug fix: SK_FACT_53 is 85 not 117.
- *     Rework time out init values.
- *     Add GIPortUsage and corresponding defines.
- *     Add some error log messages.
- *
- *     Revision 1.13  1998/10/06 14:13:14  malthoff
- *     Add prototype for SkGeLoadLnkSyncCnt().
- *
- *     Revision 1.12  1998/10/05 11:29:53  malthoff
- *     bug fix: A comment was not closed.
- *
- *     Revision 1.11  1998/10/05 08:01:59  malthoff
- *     Add default Timeout- Threshold- and
- *     Watermark constants. Add QRam start and end
- *     variables. Also add vars to store the polling
- *     mode and receive command. Add new Error Log
- *     Messages and function prototypes.
- *
- *     Revision 1.10  1998/09/28 13:34:48  malthoff
- *     Add mode bits for LED functions.
- *     Move Autoneg and Flow Ctrl bits from shgesirq.h
- *     Add the required Error Log Entries
- *     and Function Prototypes.
- *
- *     Revision 1.9  1998/09/16 14:38:41  malthoff
- *     Rework the SK_LNK_xxx defines.
- *     Add error log message defines.
- *     Add prototypes for skxmac2.c
- *
- *     Revision 1.8  1998/09/11 05:29:18  gklug
- *     add: init state of a port
- *
- *     Revision 1.7  1998/09/08 08:35:52  gklug
- *     add: defines of the Init Levels
- *
- *     Revision 1.6  1998/09/03 13:48:42  gklug
- *     add: Link strati, capabilities to Port struct
- *
- *     Revision 1.5  1998/09/03 13:30:59  malthoff
- *     Add SK_LNK_BLINK and SK_LNK_PERM.
- *
- *     Revision 1.4  1998/09/03 09:55:31  malthoff
- *     Add constants for parameters Dir and RstMode
- *     when calling SkGeStopPort().
- *     Rework the prototype section.
- *     Add Queue Address offsets PRxQOff, PXsQOff, and PXaQOff.
- *     Remove Ioc with IoC.
- *
- *     Revision 1.3  1998/08/19 09:11:54  gklug
- *     fix: struct are removed from c-source (see CCC)
- *     add: typedefs for all structs
- *
- *     Revision 1.2  1998/07/28 12:38:26  malthoff
- *     The prototypes got the parameter 'IoC'.
- *
- *     Revision 1.1  1998/07/23 09:50:24  malthoff
- *     Created.
- *
- ******************************************************************************/
-
-#ifndef __INC_SKGEINIT_H_
-#define __INC_SKGEINIT_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* defines ********************************************************************/
-
-/* modifying Link LED behaviour (used with SkGeLinkLED()) */
-#define SK_LNK_OFF             LED_OFF
-#define SK_LNK_ON              (LED_ON | LED_BLK_OFF | LED_SYNC_OFF)
-#define SK_LNK_BLINK   (LED_ON | LED_BLK_ON  | LED_SYNC_ON)
-#define SK_LNK_PERM            (LED_ON | LED_BLK_OFF | LED_SYNC_ON)
-#define SK_LNK_TST             (LED_ON | LED_BLK_ON  | LED_SYNC_OFF)
-
-/* parameter 'Mode' when calling SK_HWAC_LINK_LED() */
-#define SK_LED_OFF             LED_OFF
-#define SK_LED_ACTIVE  (LED_ON | LED_BLK_OFF | LED_SYNC_OFF)
-#define SK_LED_STANDBY (LED_ON | LED_BLK_ON  | LED_SYNC_OFF)
-
-/* addressing LED Registers in SkGeXmitLED() */
-#define XMIT_LED_INI   0
-#define XMIT_LED_CNT   (RX_LED_VAL - RX_LED_INI)
-#define XMIT_LED_CTRL  (RX_LED_CTRL- RX_LED_INI)
-#define XMIT_LED_TST   (RX_LED_TST - RX_LED_INI)
-
-/* parameter 'Mode' when calling SkGeXmitLED() */
-#define SK_LED_DIS     0
-#define SK_LED_ENA     1
-#define SK_LED_TST     2
-
-/* Counter and Timer constants, for a host clock of 62.5 MHz */
-#define SK_XMIT_DUR            0x002faf08L             /*  50 ms */
-#define SK_BLK_DUR             0x01dcd650L             /* 500 ms */
-
-#define SK_DPOLL_DEF   0x00ee6b28L             /* 250 ms at 62.5 MHz */
-
-#define SK_DPOLL_MAX   0x00ffffffL             /* 268 ms at 62.5 MHz */
-                                                                               /* 215 ms at 78.12 MHz */
-
-#define SK_FACT_62             100                     /* is given in percent */
-#define SK_FACT_53              85         /* on GENESIS:      53.12 MHz */
-#define SK_FACT_78             125                     /* on YUKON:    78.12 MHz */
-
-/* Timeout values */
-#define SK_MAC_TO_53   72                      /* MAC arbiter timeout */
-#define SK_PKT_TO_53   0x2000          /* Packet arbiter timeout */
-#define SK_PKT_TO_MAX  0xffff          /* Maximum value */
-#define SK_RI_TO_53            36                      /* RAM interface timeout */
-
-#define SK_PHY_ACC_TO  600000          /* PHY access timeout */
-
-/* RAM Buffer High Pause Threshold values */
-#define SK_RB_ULPP             ( 8 * 1024)     /* Upper Level in kB/8 */
-#define SK_RB_LLPP_S   (10 * 1024)     /* Lower Level for small Queues */
-#define SK_RB_LLPP_B   (16 * 1024)     /* Lower Level for big Queues */
-
-#ifndef SK_BMU_RX_WM
-#define SK_BMU_RX_WM   0x600           /* BMU Rx Watermark */
-#endif
-#ifndef SK_BMU_TX_WM
-#define SK_BMU_TX_WM   0x600           /* BMU Tx Watermark */
-#endif
-
-/* XMAC II Rx High Watermark */
-#define SK_XM_RX_HI_WM 0x05aa          /* 1450 */
-
-/* XMAC II Tx Threshold */
-#define SK_XM_THR_REDL 0x01fb          /* .. for redundant link usage */
-#define SK_XM_THR_SL   0x01fb          /* .. for single link adapters */
-#define SK_XM_THR_MULL 0x01fb          /* .. for multiple link usage */
-#define SK_XM_THR_JUMBO        0x03fc          /* .. for jumbo frame usage */
-
-/* values for GIPortUsage */
-#define SK_RED_LINK            1               /* redundant link usage */
-#define SK_MUL_LINK            2               /* multiple link usage */
-#define SK_JUMBO_LINK  3               /* driver uses jumbo frames */
-
-/* Minimum RAM Buffer Rx Queue Size */
-#define SK_MIN_RXQ_SIZE        16              /* 16 kB */
-
-/* Minimum RAM Buffer Tx Queue Size */
-#define SK_MIN_TXQ_SIZE        16              /* 16 kB */
-
-/* Queue Size units */
-#define QZ_UNITS               0x7
-#define QZ_STEP                        8
-
-/* Percentage of queue size from whole memory */
-/* 80 % for receive */
-#define RAM_QUOTA_RX   80L
-/* 0% for sync transfer */
-#define        RAM_QUOTA_SYNC  0L
-/* the rest (20%) is taken for async transfer */
-
-/* Get the rounded queue size in Bytes in 8k steps */
-#define ROUND_QUEUE_SIZE(SizeInBytes)                                  \
-       ((((unsigned long) (SizeInBytes) + (QZ_STEP*1024L)-1) / 1024) & \
-       ~(QZ_STEP-1))
-
-/* Get the rounded queue size in KBytes in 8k steps */
-#define ROUND_QUEUE_SIZE_KB(Kilobytes) \
-       ROUND_QUEUE_SIZE((Kilobytes) * 1024L)
-
-/* Types of RAM Buffer Queues */
-#define SK_RX_SRAM_Q   1       /* small receive queue */
-#define SK_RX_BRAM_Q   2       /* big receive queue */
-#define SK_TX_RAM_Q            3       /* small or big transmit queue */
-
-/* parameter 'Dir' when calling SkGeStopPort() */
-#define SK_STOP_TX     1       /* Stops the transmit path, resets the XMAC */
-#define SK_STOP_RX     2       /* Stops the receive path */
-#define SK_STOP_ALL    3       /* Stops Rx and Tx path, resets the XMAC */
-
-/* parameter 'RstMode' when calling SkGeStopPort() */
-#define SK_SOFT_RST    1       /* perform a software reset */
-#define SK_HARD_RST    2       /* perform a hardware reset */
-
-/* Init Levels */
-#define SK_INIT_DATA   0       /* Init level 0: init data structures */
-#define SK_INIT_IO             1       /* Init level 1: init with IOs */
-#define SK_INIT_RUN            2       /* Init level 2: init for run time */
-
-/* Link Mode Parameter */
-#define SK_LMODE_HALF          1       /* Half Duplex Mode */
-#define SK_LMODE_FULL          2       /* Full Duplex Mode */
-#define SK_LMODE_AUTOHALF      3       /* AutoHalf Duplex Mode */
-#define SK_LMODE_AUTOFULL      4       /* AutoFull Duplex Mode */
-#define SK_LMODE_AUTOBOTH      5       /* AutoBoth Duplex Mode */
-#define SK_LMODE_AUTOSENSE     6       /* configured mode auto sensing */
-#define SK_LMODE_INDETERMINATED        7       /* indeterminated */
-
-/* Auto-negotiation timeout in 100ms granularity */
-#define SK_AND_MAX_TO          6       /* Wait 600 msec before link comes up */
-
-/* Auto-negotiation error codes */
-#define SK_AND_OK                      0       /* no error */
-#define SK_AND_OTHER           1       /* other error than below */
-#define SK_AND_DUP_CAP         2       /* Duplex capabilities error */
-
-
-/* Link Speed Capabilities */
-#define SK_LSPEED_CAP_AUTO                     (1<<0)  /* Automatic resolution */
-#define SK_LSPEED_CAP_10MBPS           (1<<1)  /* 10 Mbps */
-#define SK_LSPEED_CAP_100MBPS          (1<<2)  /* 100 Mbps */
-#define SK_LSPEED_CAP_1000MBPS         (1<<3)  /* 1000 Mbps */
-#define SK_LSPEED_CAP_INDETERMINATED (1<<4) /* indeterminated */
-
-/* Link Speed Parameter */
-#define SK_LSPEED_AUTO                         1       /* Automatic resolution */
-#define SK_LSPEED_10MBPS                       2       /* 10 Mbps */
-#define SK_LSPEED_100MBPS                      3       /* 100 Mbps */
-#define SK_LSPEED_1000MBPS                     4       /* 1000 Mbps */
-#define SK_LSPEED_INDETERMINATED       5       /* indeterminated */
-
-/* Link Speed Current State */
-#define SK_LSPEED_STAT_UNKNOWN         1
-#define SK_LSPEED_STAT_10MBPS          2
-#define SK_LSPEED_STAT_100MBPS                 3
-#define SK_LSPEED_STAT_1000MBPS                4
-#define SK_LSPEED_STAT_INDETERMINATED 5
-
-
-/* Link Capability Parameter */
-#define SK_LMODE_CAP_HALF              (1<<0)  /* Half Duplex Mode */
-#define SK_LMODE_CAP_FULL              (1<<1)  /* Full Duplex Mode */
-#define SK_LMODE_CAP_AUTOHALF  (1<<2)  /* AutoHalf Duplex Mode */
-#define SK_LMODE_CAP_AUTOFULL  (1<<3)  /* AutoFull Duplex Mode */
-#define SK_LMODE_CAP_INDETERMINATED (1<<4) /* indeterminated */
-
-/* Link Mode Current State */
-#define SK_LMODE_STAT_UNKNOWN  1       /* Unknown Duplex Mode */
-#define SK_LMODE_STAT_HALF             2       /* Half Duplex Mode */
-#define SK_LMODE_STAT_FULL             3       /* Full Duplex Mode */
-#define SK_LMODE_STAT_AUTOHALF 4       /* Half Duplex Mode obtained by Auto-Neg */
-#define SK_LMODE_STAT_AUTOFULL 5       /* Full Duplex Mode obtained by Auto-Neg */
-#define SK_LMODE_STAT_INDETERMINATED 6 /* indeterminated */
-
-/* Flow Control Mode Parameter (and capabilities) */
-#define SK_FLOW_MODE_NONE              1       /* No Flow-Control */
-#define SK_FLOW_MODE_LOC_SEND  2       /* Local station sends PAUSE */
-#define SK_FLOW_MODE_SYMMETRIC 3       /* Both stations may send PAUSE */
-#define SK_FLOW_MODE_SYM_OR_REM        4       /* Both stations may send PAUSE or
-                                        * just the remote station may send PAUSE
-                                        */
-#define SK_FLOW_MODE_INDETERMINATED 5  /* indeterminated */
-
-/* Flow Control Status Parameter */
-#define SK_FLOW_STAT_NONE              1       /* No Flow Control */
-#define SK_FLOW_STAT_REM_SEND  2       /* Remote Station sends PAUSE */
-#define SK_FLOW_STAT_LOC_SEND  3       /* Local station sends PAUSE */
-#define SK_FLOW_STAT_SYMMETRIC 4       /* Both station may send PAUSE */
-#define SK_FLOW_STAT_INDETERMINATED 5  /* indeterminated */
-
-/* Master/Slave Mode Capabilities */
-#define SK_MS_CAP_AUTO         (1<<0)  /* Automatic resolution */
-#define SK_MS_CAP_MASTER       (1<<1)  /* This station is master */
-#define SK_MS_CAP_SLAVE                (1<<2)  /* This station is slave */
-#define SK_MS_CAP_INDETERMINATED (1<<3)        /* indeterminated */
-
-/* Set Master/Slave Mode Parameter (and capabilities) */
-#define SK_MS_MODE_AUTO                1       /* Automatic resolution */
-#define SK_MS_MODE_MASTER      2       /* This station is master */
-#define SK_MS_MODE_SLAVE       3       /* This station is slave */
-#define SK_MS_MODE_INDETERMINATED 4    /* indeterminated */
-
-/* Master/Slave Status Parameter */
-#define SK_MS_STAT_UNSET       1       /* The M/S status is not set */
-#define SK_MS_STAT_MASTER      2       /* This station is Master */
-#define SK_MS_STAT_SLAVE       3       /* This station is Dlave */
-#define SK_MS_STAT_FAULT       4       /* M/S resolution failed */
-#define SK_MS_STAT_INDETERMINATED 5    /* indeterminated */
-
-/* parameter 'Mode' when calling SkXmSetRxCmd() */
-#define SK_STRIP_FCS_ON                (1<<0)  /* Enable  FCS stripping of Rx frames */
-#define SK_STRIP_FCS_OFF       (1<<1)  /* Disable FCS stripping of Rx frames */
-#define SK_STRIP_PAD_ON                (1<<2)  /* Enable  pad byte stripping of Rx fr */
-#define SK_STRIP_PAD_OFF       (1<<3)  /* Disable pad byte stripping of Rx fr */
-#define SK_LENERR_OK_ON                (1<<4)  /* Don't chk fr for in range len error */
-#define SK_LENERR_OK_OFF       (1<<5)  /* Check frames for in range len error */
-#define SK_BIG_PK_OK_ON                (1<<6)  /* Don't set Rx Error bit for big frames */
-#define SK_BIG_PK_OK_OFF       (1<<7)  /* Set Rx Error bit for big frames */
-#define SK_SELF_RX_ON          (1<<8)  /* Enable  Rx of own packets */
-#define SK_SELF_RX_OFF         (1<<9)  /* Disable Rx of own packets */
-
-/* parameter 'Para' when calling SkMacSetRxTxEn() */
-#define SK_MAC_LOOPB_ON                (1<<0)  /* Enable  MAC Loopback Mode */
-#define SK_MAC_LOOPB_OFF       (1<<1)  /* Disable MAC Loopback Mode */
-#define SK_PHY_LOOPB_ON                (1<<2)  /* Enable  PHY Loopback Mode */
-#define SK_PHY_LOOPB_OFF       (1<<3)  /* Disable PHY Loopback Mode */
-#define SK_PHY_FULLD_ON                (1<<4)  /* Enable  GMII Full Duplex */
-#define SK_PHY_FULLD_OFF       (1<<5)  /* Disable GMII Full Duplex */
-
-/* States of PState */
-#define SK_PRT_RESET   0       /* the port is reset */
-#define SK_PRT_STOP            1       /* the port is stopped (similar to SW reset) */
-#define SK_PRT_INIT            2       /* the port is initialized */
-#define SK_PRT_RUN             3       /* the port has an active link */
-
-/* Default receive frame limit for Workaround of XMAC Errata */
-#define SK_DEF_RX_WA_LIM       SK_CONSTU64(100)
-
-/* Link Partner Status */
-#define SK_LIPA_UNKNOWN        0       /* Link partner is in unknown state */
-#define SK_LIPA_MANUAL 1       /* Link partner is in detected manual state */
-#define SK_LIPA_AUTO   2       /* Link partner is in auto-negotiation state */
-
-/* Maximum Restarts before restart is ignored (3Com WA) */
-#define SK_MAX_LRESTART        3       /* Max. 3 times the link is restarted */
-
-/* Max. Auto-neg. timeouts before link detection in sense mode is reset */
-#define SK_MAX_ANEG_TO 10      /* Max. 10 times the sense mode is reset */
-
-/* structures *****************************************************************/
-
-/*
- * MAC specific functions
- */
-typedef struct s_GeMacFunc {
-       int  (*pFnMacUpdateStats)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
-       int  (*pFnMacStatistic)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
-                                                       SK_U16 StatAddr, SK_U32 *pVal);
-       int  (*pFnMacResetCounter)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
-       int  (*pFnMacOverflow)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
-                                                  SK_U16 IStatus, SK_U64 *pVal);
-} SK_GEMACFUNC;
-
-/*
- * Port Structure
- */
-typedef        struct s_GePort {
-#ifndef SK_DIAG
-       SK_TIMER        PWaTimer;       /* Workaround Timer */
-       SK_TIMER        HalfDupChkTimer;
-#endif /* SK_DIAG */
-       SK_U32  PPrevShorts;    /* Previous short Counter checking */
-       SK_U32  PPrevFcs;               /* Previous FCS Error Counter checking */
-       SK_U64  PPrevRx;                /* Previous RxOk Counter checking */
-       SK_U64  PRxLim;                 /* Previous RxOk Counter checking */
-       SK_U64  LastOctets;             /* For half duplex hang check */
-       int             PLinkResCt;             /* Link Restart Counter */
-       int             PAutoNegTimeOut;/* Auto-negotiation timeout current value */
-       int             PAutoNegTOCt;   /* Auto-negotiation Timeout Counter */
-       int             PRxQSize;               /* Port Rx Queue Size in kB */
-       int             PXSQSize;               /* Port Synchronous  Transmit Queue Size in kB */
-       int             PXAQSize;               /* Port Asynchronous Transmit Queue Size in kB */
-       SK_U32  PRxQRamStart;   /* Receive Queue RAM Buffer Start Address */
-       SK_U32  PRxQRamEnd;             /* Receive Queue RAM Buffer End Address */
-       SK_U32  PXsQRamStart;   /* Sync Tx Queue RAM Buffer Start Address */
-       SK_U32  PXsQRamEnd;             /* Sync Tx Queue RAM Buffer End Address */
-       SK_U32  PXaQRamStart;   /* Async Tx Queue RAM Buffer Start Address */
-       SK_U32  PXaQRamEnd;             /* Async Tx Queue RAM Buffer End Address */
-       SK_U32  PRxOverCnt;             /* Receive Overflow Counter */
-       int             PRxQOff;                /* Rx Queue Address Offset */
-       int             PXsQOff;                /* Synchronous Tx Queue Address Offset */
-       int             PXaQOff;                /* Asynchronous Tx Queue Address Offset */
-       int             PhyType;                /* PHY used on this port */
-       SK_U16  PhyId1;                 /* PHY Id1 on this port */
-       SK_U16  PhyAddr;                /* MDIO/MDC PHY address */
-       SK_U16  PIsave;                 /* Saved Interrupt status word */
-       SK_U16  PSsave;                 /* Saved PHY status word */
-       SK_BOOL PHWLinkUp;              /* The hardware Link is up (wiring) */
-       SK_BOOL PState;                 /* Is port initialized ? */
-       SK_BOOL PLinkBroken;    /* Is Link broken ? */
-       SK_BOOL PCheckPar;              /* Do we check for parity errors ? */
-       SK_BOOL HalfDupTimerActive;
-       SK_U8   PLinkCap;               /* Link Capabilities */
-       SK_U8   PLinkModeConf;  /* Link Mode configured */
-       SK_U8   PLinkMode;              /* Link Mode currently used */
-       SK_U8   PLinkModeStatus;/* Link Mode Status */
-       SK_U8   PLinkSpeedCap;  /* Link Speed Capabilities(10/100/1000 Mbps) */
-       SK_U8   PLinkSpeed;             /* configured Link Speed (10/100/1000 Mbps) */
-       SK_U8   PLinkSpeedUsed; /* current Link Speed (10/100/1000 Mbps) */
-       SK_U8   PFlowCtrlCap;   /* Flow Control Capabilities */
-       SK_U8   PFlowCtrlMode;  /* Flow Control Mode */
-       SK_U8   PFlowCtrlStatus;/* Flow Control Status */
-       SK_U8   PMSCap;                 /* Master/Slave Capabilities */
-       SK_U8   PMSMode;                /* Master/Slave Mode */
-       SK_U8   PMSStatus;              /* Master/Slave Status */
-       SK_U8   PAutoNegFail;   /* Auto-negotiation fail flag */
-       SK_U8   PLipaAutoNeg;   /* Auto-negotiation possible with Link Partner */
-       SK_U8   PCableLen;              /* Cable Length */
-       SK_U8   PMdiPairLen[4]; /* MDI[0..3] Pair Length */
-       SK_U8   PMdiPairSts[4]; /* MDI[0..3] Pair Diagnostic Status */
-} SK_GEPORT;
-
-/*
- * Gigabit Ethernet Initialization Struct
- * (has to be included in the adapter context)
- */
-typedef        struct s_GeInit {
-       SK_U8           GIPciHwRev;             /* PCI HW Revision Number */
-       SK_U8           GIChipId;               /* Chip Identification Number */
-       SK_U8           GIChipRev;              /* Chip Revision Number */
-       SK_BOOL         GIGenesis;              /* Genesis adapter ? */
-       SK_BOOL         GICopperType;   /* Copper Type adapter ? */
-       SK_BOOL         GIPciSlot64;    /* 64-bit PCI Slot */
-       SK_BOOL         GIPciClock66;   /* 66 MHz PCI Clock */
-       SK_BOOL         GIVauxAvail;    /* VAUX available (YUKON) */
-       SK_BOOL         GIYukon32Bit;   /* 32-Bit YUKON adapter */
-       SK_BOOL         GIYukonLite;    /* YUKON-Lite chip */
-       int                     GIMacsFound;    /* Number of MACs found on this adapter */
-       int                     GIMacType;              /* MAC Type used on this adapter */
-       int                     GIHstClkFact;   /* Host Clock Factor (62.5 / HstClk * 100) */
-       int                     GIPortUsage;    /* Driver Port Usage */
-       int                     GILevel;                /* Initialization Level completed */
-       int                     GIRamSize;              /* The RAM size of the adapter in kB */
-       int                     GIWolOffs;              /* WOL Register Offset (HW-Bug in Rev. A) */
-       SK_U32          GIRamOffs;              /* RAM Address Offset for addr calculation */
-       SK_U32          GIPollTimerVal; /* Descr. Poll Timer Init Val (HstClk ticks) */
-       SK_GEPORT       GP[SK_MAX_MACS];/* Port Dependent Information */
-       SK_GEMACFUNC GIFunc;            /* MAC depedent functions */
-} SK_GEINIT;
-
-/*
- * Error numbers and messages for skxmac2.c and skgeinit.c
- */
-#define SKERR_HWI_E001         (SK_ERRBASE_HWINIT)
-#define SKERR_HWI_E001MSG      "SkXmClrExactAddr() has got illegal parameters"
-#define SKERR_HWI_E002         (SKERR_HWI_E001+1)
-#define SKERR_HWI_E002MSG      "SkGeInit(): Level 1 call missing"
-#define SKERR_HWI_E003         (SKERR_HWI_E002+1)
-#define SKERR_HWI_E003MSG      "SkGeInit() called with illegal init Level"
-#define SKERR_HWI_E004         (SKERR_HWI_E003+1)
-#define SKERR_HWI_E004MSG      "SkGeInitPort(): Queue Size illegal configured"
-#define SKERR_HWI_E005         (SKERR_HWI_E004+1)
-#define SKERR_HWI_E005MSG      "SkGeInitPort(): cannot init running ports"
-#define SKERR_HWI_E006         (SKERR_HWI_E005+1)
-#define SKERR_HWI_E006MSG      "SkGeMacInit(): PState does not match HW state"
-#define SKERR_HWI_E007         (SKERR_HWI_E006+1)
-#define SKERR_HWI_E007MSG      "SkXmInitDupMd() called with invalid Dup Mode"
-#define SKERR_HWI_E008         (SKERR_HWI_E007+1)
-#define SKERR_HWI_E008MSG      "SkXmSetRxCmd() called with invalid Mode"
-#define SKERR_HWI_E009         (SKERR_HWI_E008+1)
-#define SKERR_HWI_E009MSG      "SkGeCfgSync() called although PXSQSize zero"
-#define SKERR_HWI_E010         (SKERR_HWI_E009+1)
-#define SKERR_HWI_E010MSG      "SkGeCfgSync() called with invalid parameters"
-#define SKERR_HWI_E011         (SKERR_HWI_E010+1)
-#define SKERR_HWI_E011MSG      "SkGeInitPort(): Receive Queue Size too small"
-#define SKERR_HWI_E012         (SKERR_HWI_E011+1)
-#define SKERR_HWI_E012MSG      "SkGeInitPort(): invalid Queue Size specified"
-#define SKERR_HWI_E013         (SKERR_HWI_E012+1)
-#define SKERR_HWI_E013MSG      "SkGeInitPort(): cfg changed for running queue"
-#define SKERR_HWI_E014         (SKERR_HWI_E013+1)
-#define SKERR_HWI_E014MSG      "SkGeInitPort(): unknown GIPortUsage specified"
-#define SKERR_HWI_E015         (SKERR_HWI_E014+1)
-#define SKERR_HWI_E015MSG      "Illegal Link mode parameter"
-#define SKERR_HWI_E016         (SKERR_HWI_E015+1)
-#define SKERR_HWI_E016MSG      "Illegal Flow control mode parameter"
-#define SKERR_HWI_E017         (SKERR_HWI_E016+1)
-#define SKERR_HWI_E017MSG      "Illegal value specified for GIPollTimerVal"
-#define SKERR_HWI_E018         (SKERR_HWI_E017+1)
-#define SKERR_HWI_E018MSG      "FATAL: SkGeStopPort() does not terminate (Tx)"
-#define SKERR_HWI_E019         (SKERR_HWI_E018+1)
-#define SKERR_HWI_E019MSG      "Illegal Speed parameter"
-#define SKERR_HWI_E020         (SKERR_HWI_E019+1)
-#define SKERR_HWI_E020MSG      "Illegal Master/Slave parameter"
-#define SKERR_HWI_E021         (SKERR_HWI_E020+1)
-#define        SKERR_HWI_E021MSG       "MacUpdateStats(): cannot update statistic counter"
-#define        SKERR_HWI_E022          (SKERR_HWI_E021+1)
-#define        SKERR_HWI_E022MSG       "MacStatistic(): illegal statistic base address"
-#define SKERR_HWI_E023         (SKERR_HWI_E022+1)
-#define SKERR_HWI_E023MSG      "SkGeInitPort(): Transmit Queue Size too small"
-#define SKERR_HWI_E024         (SKERR_HWI_E023+1)
-#define SKERR_HWI_E024MSG      "FATAL: SkGeStopPort() does not terminate (Rx)"
-#define SKERR_HWI_E025         (SKERR_HWI_E024+1)
-#define SKERR_HWI_E025MSG      ""
-
-/* function prototypes ********************************************************/
-
-#ifndef        SK_KR_PROTO
-
-/*
- * public functions in skgeinit.c
- */
-extern void    SkGePollRxD(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_BOOL PollRxD);
-
-extern void    SkGePollTxD(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_BOOL PollTxD);
-
-extern void    SkGeYellowLED(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             State);
-
-extern int     SkGeCfgSync(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_U32  IntTime,
-       SK_U32  LimCount,
-       int             SyncMode);
-
-extern void    SkGeLoadLnkSyncCnt(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_U32  CntVal);
-
-extern void    SkGeStopPort(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             Dir,
-       int             RstMode);
-
-extern int     SkGeInit(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Level);
-
-extern void    SkGeDeInit(
-       SK_AC   *pAC,
-       SK_IOC  IoC);
-
-extern int     SkGeInitPort(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkGeXmitLED(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Led,
-       int             Mode);
-
-extern void    SkGeInitRamIface(
-       SK_AC   *pAC,
-       SK_IOC  IoC);
-
-extern int     SkGeInitAssignRamToQueues(
-       SK_AC   *pAC,
-       int             ActivePort,
-       SK_BOOL DualNet);
-
-/*
- * public functions in skxmac2.c
- */
-extern void SkMacRxTxDisable(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkMacSoftRst(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkMacHardRst(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkXmInitMac(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkGmInitMac(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void SkMacInitPhy(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_BOOL DoLoop);
-
-extern void SkMacIrqDisable(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkMacFlushTxFifo(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkMacFlushRxFifo(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkMacIrq(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern int     SkMacAutoNegDone(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkMacAutoNegLipaPhy(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_U16  IStatus);
-
-extern void  SkMacSetRxTxEn(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             Para);
-
-extern int  SkMacRxTxEnable(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkMacPromiscMode(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_BOOL Enable);
-
-extern void    SkMacHashing(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_BOOL Enable);
-
-extern void    SkXmPhyRead(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             Addr,
-       SK_U16  *pVal);
-
-extern void    SkXmPhyWrite(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             Addr,
-       SK_U16  Val);
-
-extern void    SkGmPhyRead(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             Addr,
-       SK_U16  *pVal);
-
-extern void    SkGmPhyWrite(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             Addr,
-       SK_U16  Val);
-
-extern void    SkGePhyRead(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             Addr,
-       SK_U16  *pVal);
-
-extern void    SkGePhyWrite(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             Addr,
-       SK_U16  Val);
-
-extern void    SkXmClrExactAddr(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             StartNum,
-       int             StopNum);
-
-extern void    SkXmInitDupMd(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkXmInitPauseMd(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkXmAutoNegLipaXmac(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_U16  IStatus);
-
-extern int SkXmUpdateStats(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       unsigned int Port);
-
-extern int SkGmUpdateStats(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       unsigned int Port);
-
-extern int SkXmMacStatistic(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       unsigned int Port,
-       SK_U16  StatAddr,
-       SK_U32  *pVal);
-
-extern int SkGmMacStatistic(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       unsigned int Port,
-       SK_U16  StatAddr,
-       SK_U32  *pVal);
-
-extern int SkXmResetCounter(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       unsigned int Port);
-
-extern int SkGmResetCounter(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       unsigned int Port);
-
-extern int SkXmOverflowStatus(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       unsigned int Port,
-       SK_U16  IStatus,
-       SK_U64  *pStatus);
-
-extern int SkGmOverflowStatus(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       unsigned int Port,
-       SK_U16  MacStatus,
-       SK_U64  *pStatus);
-
-extern int SkGmCableDiagStatus(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_BOOL StartTest);
-
-#ifdef SK_DIAG
-extern void    SkMacSetRxCmd(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             Mode);
-extern void    SkMacCrcGener(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_BOOL Enable);
-extern void    SkMacTimeStamp(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_BOOL Enable);
-extern void    SkXmSendCont(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_BOOL Enable);
-#endif /* SK_DIAG */
-
-#else  /* SK_KR_PROTO */
-
-/*
- * public functions in skgeinit.c
- */
-extern void    SkGePollRxD();
-extern void    SkGePollTxD();
-extern void    SkGeYellowLED();
-extern int     SkGeCfgSync();
-extern void    SkGeLoadLnkSyncCnt();
-extern void    SkGeStopPort();
-extern int     SkGeInit();
-extern void    SkGeDeInit();
-extern int     SkGeInitPort();
-extern void    SkGeXmitLED();
-extern void    SkGeInitRamIface();
-extern int     SkGeInitAssignRamToQueues();
-
-/*
- * public functions in skxmac2.c
- */
-extern void SkMacRxTxDisable();
-extern void    SkMacSoftRst();
-extern void    SkMacHardRst();
-extern void SkMacInitPhy();
-extern int  SkMacRxTxEnable();
-extern void SkMacPromiscMode();
-extern void SkMacHashing();
-extern void SkMacIrqDisable();
-extern void    SkMacFlushTxFifo();
-extern void    SkMacFlushRxFifo();
-extern void    SkMacIrq();
-extern int     SkMacAutoNegDone();
-extern void    SkMacAutoNegLipaPhy();
-extern void SkMacSetRxTxEn();
-extern void    SkGePhyRead();
-extern void    SkGePhyWrite();
-extern void    SkXmInitMac();
-extern void    SkXmPhyRead();
-extern void    SkXmPhyWrite();
-extern void    SkGmInitMac();
-extern void    SkGmPhyRead();
-extern void    SkGmPhyWrite();
-extern void    SkXmClrExactAddr();
-extern void    SkXmInitDupMd();
-extern void    SkXmInitPauseMd();
-extern void    SkXmAutoNegLipaXmac();
-extern int     SkXmUpdateStats();
-extern int     SkGmUpdateStats();
-extern int     SkXmMacStatistic();
-extern int     SkGmMacStatistic();
-extern int     SkXmResetCounter();
-extern int     SkGmResetCounter();
-extern int     SkXmOverflowStatus();
-extern int     SkGmOverflowStatus();
-extern int     SkGmCableDiagStatus();
-
-#ifdef SK_DIAG
-extern void    SkMacSetRxCmd();
-extern void    SkMacCrcGener();
-extern void    SkMacTimeStamp();
-extern void    SkXmSendCont();
-#endif /* SK_DIAG */
-
-#endif /* SK_KR_PROTO */
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_SKGEINIT_H_ */
diff --git a/drivers/sk98lin/h/skgepnm2.h b/drivers/sk98lin/h/skgepnm2.h
deleted file mode 100644 (file)
index 5c44f47..0000000
+++ /dev/null
@@ -1,462 +0,0 @@
-/*****************************************************************************
- *
- * Name:       skgepnm2.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.34 $
- * Date:       $Date: 2002/12/16 09:05:18 $
- * Purpose:    Defines for Private Network Management Interface
- *
- ****************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2001 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*****************************************************************************
- *
- * History:
- *
- *     $Log: skgepnm2.h,v $
- *     Revision 1.34  2002/12/16 09:05:18  tschilli
- *     Code for VCT handling added.
- *
- *     Revision 1.33  2002/09/10 09:00:03  rwahl
- *     Adapted boolean definitions according sktypes.
- *
- *     Revision 1.32  2002/08/09 09:47:01  rwahl
- *     Added write-only flag to oid access defines.
- *     Editorial changes.
- *
- *     Revision 1.31  2002/07/17 19:23:18  rwahl
- *     - Replaced MAC counter definitions by enumeration.
- *     - Added definition SK_PNMI_MAC_TYPES.
- *     - Added chipset defnition for Yukon.
- *
- *     Revision 1.30  2001/02/06 10:03:41  mkunz
- *     - Pnmi V4 dual net support added. Interface functions and macros extended
- *     - Vpd bug fixed
- *     - OID_SKGE_MTU added
- *
- *     Revision 1.29  2001/01/22 13:41:37  rassmann
- *     Supporting two nets on dual-port adapters.
- *
- *     Revision 1.28  2000/08/03 15:12:48  rwahl
- *     - Additional comment for MAC statistic data structure.
- *
- *     Revision 1.27  2000/08/01 16:10:18  rwahl
- *     - Added mac statistic data structure for StatRxLongFrame counter.
- *
- *     Revision 1.26  2000/03/31 13:51:34  rwahl
- *     Added SK_UPTR cast to offset calculation for PNMI struct fields;
- *     missing cast caused compiler warnings by Win64 compiler.
- *
- *     Revision 1.25  1999/11/22 13:57:41  cgoos
- *     Changed license header to GPL.
- *     Allowing overwrite for SK_PNMI_STORE/_READ defines.
- *
- *     Revision 1.24  1999/04/13 15:11:11  mhaveman
- *     Changed copyright.
- *
- *     Revision 1.23  1999/01/28 15:07:12  mhaveman
- *     Changed default threshold for port switches per hour from 10
- *     to 240 which means 4 switches per minute. This fits better
- *     the granularity of 32 for the port switch estimate
- *     counter.
- *
- *     Revision 1.22  1999/01/05 12:52:30  mhaveman
- *     Removed macro SK_PNMI_MICRO_SEC.
- *
- *     Revision 1.21  1999/01/05 12:50:34  mhaveman
- *     Enlarged macro definition SK_PNMI_HUNDREDS_SEC() so that no 64-bit
- *     arithmetic is necessary if SK_TICKS_PER_SEC is 100.
- *
- *     Revision 1.20  1998/12/09 14:02:53  mhaveman
- *     Defined macro SK_PNMI_DEF_RLMT_CHG_THRES for default port switch
- *     threshold.
- *
- *     Revision 1.19  1998/12/03 11:28:41  mhaveman
- *     Removed SK_PNMI_CHECKPTR macro.
- *
- *     Revision 1.18  1998/12/03 11:21:00  mhaveman
- *     -Added pointer check macro SK_PNMI_CHECKPTR
- *     -Added macros SK_PNMI_VPD_ARR_SIZE and SK_PNMI_VPD_STR_SIZE for
- *      VPD key evaluation.
- *
- *     Revision 1.17  1998/11/20 13:20:33  mhaveman
- *     Fixed bug in SK_PNMI_SET_STAT macro. ErrorStatus was not correctly set.
- *
- *     Revision 1.16  1998/11/20 08:08:49  mhaveman
- *     Macro SK_PNMI_CHECKFLAGS has got a if clause.
- *
- *     Revision 1.15  1998/11/03 13:53:40  mhaveman
- *     Fixed alignment problem in macor SK_PNMI_SET_STAT macro.
- *
- *     Revision 1.14  1998/10/30 15:50:13  mhaveman
- *     Added macro SK_PNMI_MICRO_SEC()
- *
- *     Revision 1.13  1998/10/30 12:32:20  mhaveman
- *     Added forgotten cast in SK_PNMI_READ_U32 macro.
- *
- *     Revision 1.12  1998/10/29 15:40:26  mhaveman
- *     -Changed SK_PNMI_TRAP_SENSOR_LEN because SensorDescr has now
- *      variable string length.
- *     -Defined SK_PNMI_CHECKFLAGS macro
- *
- *     Revision 1.11  1998/10/29 08:53:34  mhaveman
- *     Removed SK_PNMI_RLM_XXX table indexed because these counters need
- *     not been saved over XMAC resets.
- *
- *     Revision 1.10  1998/10/28 08:48:20  mhaveman
- *     -Added macros for storage according to alignment
- *     -Changed type of Instance to SK_U32 because of VPD
- *     -Removed trap structures. Not needed because of alignment problem
- *     -Changed type of Action form SK_U8 to int
- *
- *     Revision 1.9  1998/10/21 13:34:45  mhaveman
- *     Shit, mismatched calculation of SK_PNMI_HUNDREDS_SEC. Corrected.
- *
- *     Revision 1.8  1998/10/21 13:24:58  mhaveman
- *     Changed calculation of hundreds of seconds.
- *
- *     Revision 1.7  1998/10/20 07:31:41  mhaveman
- *     Made type changes to unsigned int where possible.
- *
- *     Revision 1.6  1998/09/04 17:04:05  mhaveman
- *     Added Sync counters to offset storage to provided settled values on
- *     port switch.
- *
- *     Revision 1.5  1998/09/04 12:45:35  mhaveman
- *     Removed dummies for SK_DRIVER_ macros. They should be added by driver
- *     writer in skdrv2nd.h.
- *
- *     Revision 1.4  1998/09/04 11:59:50  mhaveman
- *     Everything compiles now. Driver Macros for counting still missing.
- *
- *     Revision 1.3  1998/08/24 12:01:35  mhaveman
- *     Intermediate state.
- *
- *     Revision 1.2  1998/08/17 07:51:40  mhaveman
- *     Intermediate state.
- *
- *     Revision 1.1  1998/08/11 09:08:40  mhaveman
- *     Intermediate state.
- *
- ****************************************************************************/
-
-#ifndef _SKGEPNM2_H_
-#define _SKGEPNM2_H_
-
-/*
- * General definitions
- */
-#define SK_PNMI_CHIPSET_XMAC   1       /* XMAC11800FP */
-#define SK_PNMI_CHIPSET_YUKON  2       /* YUKON */
-
-#define        SK_PNMI_BUS_PCI         1       /* PCI bus*/
-
-/*
- * Actions
- */
-#define SK_PNMI_ACT_IDLE               1
-#define SK_PNMI_ACT_RESET              2
-#define SK_PNMI_ACT_SELFTEST   3
-#define SK_PNMI_ACT_RESETCNT   4
-
-/*
- * VPD releated defines
- */
-
-#define SK_PNMI_VPD_RW         1
-#define SK_PNMI_VPD_RO         2
-
-#define SK_PNMI_VPD_OK                 0
-#define SK_PNMI_VPD_NOTFOUND   1
-#define SK_PNMI_VPD_CUT                        2
-#define SK_PNMI_VPD_TIMEOUT            3
-#define SK_PNMI_VPD_FULL               4
-#define SK_PNMI_VPD_NOWRITE            5
-#define SK_PNMI_VPD_FATAL              6
-
-#define SK_PNMI_VPD_IGNORE     0
-#define SK_PNMI_VPD_CREATE     1
-#define SK_PNMI_VPD_DELETE     2
-
-
-/*
- * RLMT related defines
- */
-#define SK_PNMI_DEF_RLMT_CHG_THRES     240     /* 4 changes per minute */
-
-
-/*
- * VCT internal status values
- */
-#define SK_PNMI_VCT_PENDING    32
-#define SK_PNMI_VCT_TEST_DONE  64
-#define SK_PNMI_VCT_LINK       128
-
-/*
- * Internal table definitions
- */
-#define SK_PNMI_GET            0
-#define SK_PNMI_PRESET 1
-#define SK_PNMI_SET            2
-
-#define SK_PNMI_RO             0
-#define SK_PNMI_RW             1
-#define SK_PNMI_WO             2
-
-typedef struct s_OidTabEntry {
-       SK_U32                  Id;
-       SK_U32                  InstanceNo;
-       unsigned int    StructSize;
-       unsigned int    Offset;
-       int                             Access;
-       int                             (* Func)(SK_AC *pAc, SK_IOC pIo, int action,
-                                                        SK_U32 Id, char* pBuf, unsigned int* pLen,
-                                                        SK_U32 Instance, unsigned int TableIndex,
-                                                        SK_U32 NetNumber);
-       SK_U16                  Param;
-} SK_PNMI_TAB_ENTRY;
-
-
-/*
- * Trap lengths
- */
-#define SK_PNMI_TRAP_SIMPLE_LEN                        17
-#define SK_PNMI_TRAP_SENSOR_LEN_BASE   46
-#define SK_PNMI_TRAP_RLMT_CHANGE_LEN   23
-#define SK_PNMI_TRAP_RLMT_PORT_LEN             23
-
-/*
- * Number of MAC types supported
- */
-#define SK_PNMI_MAC_TYPES      (SK_MAC_GMAC + 1)
-
-/*
- * MAC statistic data list (overall set for MAC types used)
- */
-enum SK_MACSTATS {
-       SK_PNMI_HTX                             = 0,
-       SK_PNMI_HTX_OCTET,
-       SK_PNMI_HTX_OCTETHIGH   = SK_PNMI_HTX_OCTET,
-       SK_PNMI_HTX_OCTETLOW,
-       SK_PNMI_HTX_BROADCAST,
-       SK_PNMI_HTX_MULTICAST,
-       SK_PNMI_HTX_UNICAST,
-       SK_PNMI_HTX_BURST,
-       SK_PNMI_HTX_PMACC,
-       SK_PNMI_HTX_MACC,
-       SK_PNMI_HTX_COL,
-       SK_PNMI_HTX_SINGLE_COL,
-       SK_PNMI_HTX_MULTI_COL,
-       SK_PNMI_HTX_EXCESS_COL,
-       SK_PNMI_HTX_LATE_COL,
-       SK_PNMI_HTX_DEFFERAL,
-       SK_PNMI_HTX_EXCESS_DEF,
-       SK_PNMI_HTX_UNDERRUN,
-       SK_PNMI_HTX_CARRIER,
-       SK_PNMI_HTX_UTILUNDER,
-       SK_PNMI_HTX_UTILOVER,
-       SK_PNMI_HTX_64,
-       SK_PNMI_HTX_127,
-       SK_PNMI_HTX_255,
-       SK_PNMI_HTX_511,
-       SK_PNMI_HTX_1023,
-       SK_PNMI_HTX_MAX,
-       SK_PNMI_HTX_LONGFRAMES,
-       SK_PNMI_HTX_SYNC,
-       SK_PNMI_HTX_SYNC_OCTET,
-       SK_PNMI_HTX_RESERVED,
-
-       SK_PNMI_HRX,
-       SK_PNMI_HRX_OCTET,
-       SK_PNMI_HRX_OCTETHIGH   = SK_PNMI_HRX_OCTET,
-       SK_PNMI_HRX_OCTETLOW,
-       SK_PNMI_HRX_BADOCTET,
-       SK_PNMI_HRX_BADOCTETHIGH = SK_PNMI_HRX_BADOCTET,
-       SK_PNMI_HRX_BADOCTETLOW,
-       SK_PNMI_HRX_BROADCAST,
-       SK_PNMI_HRX_MULTICAST,
-       SK_PNMI_HRX_UNICAST,
-       SK_PNMI_HRX_PMACC,
-       SK_PNMI_HRX_MACC,
-       SK_PNMI_HRX_PMACC_ERR,
-       SK_PNMI_HRX_MACC_UNKWN,
-       SK_PNMI_HRX_BURST,
-       SK_PNMI_HRX_MISSED,
-       SK_PNMI_HRX_FRAMING,
-       SK_PNMI_HRX_UNDERSIZE,
-       SK_PNMI_HRX_OVERFLOW,
-       SK_PNMI_HRX_JABBER,
-       SK_PNMI_HRX_CARRIER,
-       SK_PNMI_HRX_IRLENGTH,
-       SK_PNMI_HRX_SYMBOL,
-       SK_PNMI_HRX_SHORTS,
-       SK_PNMI_HRX_RUNT,
-       SK_PNMI_HRX_TOO_LONG,
-       SK_PNMI_HRX_FCS,
-       SK_PNMI_HRX_CEXT,
-       SK_PNMI_HRX_UTILUNDER,
-       SK_PNMI_HRX_UTILOVER,
-       SK_PNMI_HRX_64,
-       SK_PNMI_HRX_127,
-       SK_PNMI_HRX_255,
-       SK_PNMI_HRX_511,
-       SK_PNMI_HRX_1023,
-       SK_PNMI_HRX_MAX,
-       SK_PNMI_HRX_LONGFRAMES,
-
-       SK_PNMI_HRX_RESERVED,
-
-       SK_PNMI_MAX_IDX         /* NOTE: Ensure SK_PNMI_CNT_NO is set to this value */
-};
-
-/*
- * MAC specific data
- */
-typedef struct s_PnmiStatAddr {
-       SK_U16          Reg;            /* MAC register containing the value */
-       SK_BOOL         GetOffset;      /* TRUE: Offset managed by PNMI (call GetStatVal())*/
-} SK_PNMI_STATADDR;
-
-
-/*
- * SK_PNMI_STRUCT_DATA copy offset evaluation macros
- */
-#define SK_PNMI_OFF(e)         ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
-#define SK_PNMI_MAI_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
-#define SK_PNMI_VPD_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_VPD *)0)->e))
-#define SK_PNMI_SEN_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_SENSOR *)0)->e))
-#define SK_PNMI_CHK_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_CHECKSUM *)0)->e))
-#define SK_PNMI_STA_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_STAT *)0)->e))
-#define SK_PNMI_CNF_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_CONF *)0)->e))
-#define SK_PNMI_RLM_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT *)0)->e))
-#define SK_PNMI_MON_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT_MONITOR *)0)->e))
-#define SK_PNMI_TRP_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_TRAP *)0)->e))
-
-#define SK_PNMI_SET_STAT(b,s,o)        {SK_U32 Val32; char *pVal; \
-                                       Val32 = (s); \
-                                       pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
-                                               &(((SK_PNMI_STRUCT_DATA *)0)-> \
-                                               ReturnStatus.ErrorStatus)); \
-                                       SK_PNMI_STORE_U32(pVal, Val32); \
-                                       Val32 = (o); \
-                                       pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
-                                               &(((SK_PNMI_STRUCT_DATA *)0)-> \
-                                               ReturnStatus.ErrorOffset)); \
-                                       SK_PNMI_STORE_U32(pVal, Val32);}
-
-/*
- * Time macros
- */
-#if SK_TICKS_PER_SEC == 100
-#define SK_PNMI_HUNDREDS_SEC(t)        (t)
-#else
-#define SK_PNMI_HUNDREDS_SEC(t)        (((t) * 100) / (SK_TICKS_PER_SEC))
-#endif
-
-/*
- * Macros to work around alignment problems
- */
-#ifndef SK_PNMI_STORE_U16
-#define SK_PNMI_STORE_U16(p,v) {*(char *)(p) = *((char *)&(v)); \
-                                       *((char *)(p) + 1) = \
-                                               *(((char *)&(v)) + 1);}
-#endif
-
-#ifndef SK_PNMI_STORE_U32
-#define SK_PNMI_STORE_U32(p,v) {*(char *)(p) = *((char *)&(v)); \
-                                       *((char *)(p) + 1) = \
-                                               *(((char *)&(v)) + 1); \
-                                       *((char *)(p) + 2) = \
-                                               *(((char *)&(v)) + 2); \
-                                       *((char *)(p) + 3) = \
-                                               *(((char *)&(v)) + 3);}
-#endif
-
-#ifndef SK_PNMI_STORE_U64
-#define SK_PNMI_STORE_U64(p,v) {*(char *)(p) = *((char *)&(v)); \
-                                       *((char *)(p) + 1) = \
-                                               *(((char *)&(v)) + 1); \
-                                       *((char *)(p) + 2) = \
-                                               *(((char *)&(v)) + 2); \
-                                       *((char *)(p) + 3) = \
-                                               *(((char *)&(v)) + 3); \
-                                       *((char *)(p) + 4) = \
-                                               *(((char *)&(v)) + 4); \
-                                       *((char *)(p) + 5) = \
-                                               *(((char *)&(v)) + 5); \
-                                       *((char *)(p) + 6) = \
-                                               *(((char *)&(v)) + 6); \
-                                       *((char *)(p) + 7) = \
-                                               *(((char *)&(v)) + 7);}
-#endif
-
-#ifndef SK_PNMI_READ_U16
-#define SK_PNMI_READ_U16(p,v)  {*((char *)&(v)) = *(char *)(p); \
-                                       *(((char *)&(v)) + 1) = \
-                                               *((char *)(p) + 1);}
-#endif
-
-#ifndef SK_PNMI_READ_U32
-#define SK_PNMI_READ_U32(p,v)  {*((char *)&(v)) = *(char *)(p); \
-                                       *(((char *)&(v)) + 1) = \
-                                               *((char *)(p) + 1); \
-                                       *(((char *)&(v)) + 2) = \
-                                               *((char *)(p) + 2); \
-                                       *(((char *)&(v)) + 3) = \
-                                               *((char *)(p) + 3);}
-#endif
-
-#ifndef SK_PNMI_READ_U64
-#define SK_PNMI_READ_U64(p,v)  {*((char *)&(v)) = *(char *)(p); \
-                                       *(((char *)&(v)) + 1) = \
-                                               *((char *)(p) + 1); \
-                                       *(((char *)&(v)) + 2) = \
-                                               *((char *)(p) + 2); \
-                                       *(((char *)&(v)) + 3) = \
-                                               *((char *)(p) + 3); \
-                                       *(((char *)&(v)) + 4) = \
-                                               *((char *)(p) + 4); \
-                                       *(((char *)&(v)) + 5) = \
-                                               *((char *)(p) + 5); \
-                                       *(((char *)&(v)) + 6) = \
-                                               *((char *)(p) + 6); \
-                                       *(((char *)&(v)) + 7) = \
-                                               *((char *)(p) + 7);}
-#endif
-
-/*
- * Macros for Debug
- */
-#ifdef DEBUG
-
-#define SK_PNMI_CHECKFLAGS(vSt)        {if (pAC->Pnmi.MacUpdatedFlag > 0 || \
-                                       pAC->Pnmi.RlmtUpdatedFlag > 0 || \
-                                       pAC->Pnmi.SirqUpdatedFlag > 0) { \
-                                               SK_DBG_MSG(pAC, \
-                                               SK_DBGMOD_PNMI, \
-                                               SK_DBGCAT_CTRL, \
-                                               ("PNMI: ERR: %s MacUFlag=%d, RlmtUFlag=%d, SirqUFlag=%d\n", \
-                                               vSt, \
-                                               pAC->Pnmi.MacUpdatedFlag, \
-                                               pAC->Pnmi.RlmtUpdatedFlag, \
-                                               pAC->Pnmi.SirqUpdatedFlag))}}
-
-#else  /* !DEBUG */
-
-#define SK_PNMI_CHECKFLAGS(vSt)        /* Nothing */
-
-#endif /* !DEBUG */
-
-#endif /* _SKGEPNM2_H_ */
diff --git a/drivers/sk98lin/h/skgepnmi.h b/drivers/sk98lin/h/skgepnmi.h
deleted file mode 100644 (file)
index 7532313..0000000
+++ /dev/null
@@ -1,1114 +0,0 @@
-/*****************************************************************************
- *
- * Name:       skgepnmi.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.59 $
- * Date:       $Date: 2002/12/16 14:03:50 $
- * Purpose:    Defines for Private Network Management Interface
- *
- ****************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2001 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*****************************************************************************
- *
- * History:
- *
- *     $Log: skgepnmi.h,v $
- *     Revision 1.59  2002/12/16 14:03:50  tschilli
- *     New defines for VCT added.
- *
- *     Revision 1.58  2002/12/16 09:04:59  tschilli
- *     Code for VCT handling added.
- *
- *     Revision 1.57  2002/09/26 12:41:05  tschilli
- *     SK_PNMI_PORT BufPort entry in struct SK_PNMI added.
- *
- *     Revision 1.56  2002/08/16 11:10:41  rwahl
- *     - Replaced c++ comment.
- *
- *     Revision 1.55  2002/08/09 15:40:21  rwahl
- *     Editorial change (renamed ConfSpeedCap).
- *
- *     Revision 1.54  2002/08/09 11:06:07  rwahl
- *     Added OID_SKGE_SPEED_CAP.
- *
- *     Revision 1.53  2002/08/09 09:45:28  rwahl
- *     Added support for NDIS OID_PNP_xxx.
- *     Editorial changes.
- *
- *     Revision 1.52  2002/08/06 17:54:07  rwahl
- *     - Added speed cap to PNMI config struct.
- *
- *     Revision 1.51  2002/07/17 19:19:26  rwahl
- *     - Added OID_SKGE_SPEED_MODE and OID_SKGE_SPEED_STATUS.
- *     - Added SK_PNMI_CNT_RX_PMACC_ERR() & SK_PNMI_CNT_RX_LONGFRAMES().
- *     - Added speed mode & status to PNMI config struct.
- *     - Editorial changes.
- *
- *     Revision 1.50  2002/05/22 08:59:37  rwahl
- *     Added string definitions for error msgs.
- *
- *     Revision 1.49  2001/11/20 09:23:50  rwahl
- *     - pnmi struct: reordered and aligned to 32bit.
- *
- *     Revision 1.48  2001/02/23 14:34:24  mkunz
- *     Changed macro PHYS2INST. Added pAC to Interface
- *
- *     Revision 1.47  2001/02/07 08:28:23  mkunz
- *     - Added Oids:   OID_SKGE_DIAG_ACTION
- *                                     OID_SKGE_DIAG_RESULT
- *                                     OID_SKGE_MULTICAST_LIST
- *                                     OID_SKGE_CURRENT_PACKET_FILTER
- *                                     OID_SKGE_INTERMEDIATE_SUPPORT
- *     - Changed value of OID_SKGE_MTU
- *
- *     Revision 1.46  2001/02/06 10:01:41  mkunz
- *     - Pnmi V4 dual net support added. Interface functions and macros extended
- *     - Vpd bug fixed
- *     - OID_SKGE_MTU added
- *
- *     Revision 1.45  2001/01/22 13:41:37  rassmann
- *     Supporting two nets on dual-port adapters.
- *
- *     Revision 1.44  2000/09/07 07:35:27  rwahl
- *     - removed NDIS counter specific data type.
- *     - fixed spelling for OID_SKGE_RLMT_PORT_PREFERRED.
- *
- *     Revision 1.43  2000/08/04 11:41:08  rwahl
- *     - Fixed compiler warning (port is always >= 0) for macros
- *       SK_PNMI_CNT_RX_LONGFRAMES & SK_PNMI_CNT_SYNC_OCTETS
- *
- *     Revision 1.42  2000/08/03 15:14:07  rwahl
- *     - Corrected error in driver macros addressing a physical port.
- *
- *     Revision 1.41  2000/08/01 16:22:29  rwahl
- *     - Changed MDB version to 3.1.
- *     - Added definitions for StatRxLongFrames counter.
- *     - Added macro to be used by driver to count long frames received.
- *     - Added directive to control width (default = 32bit) of NDIS statistic
- *       counters (SK_NDIS_64BIT_CTR).
- *
- *     Revision 1.40  2000/03/31 13:51:34  rwahl
- *     Added SK_UPTR cast to offset calculation for PNMI struct fields;
- *     missing cast caused compiler warnings by Win64 compiler.
- *
- *     Revision 1.39  1999/12/06 10:09:47  rwahl
- *     Added new error log message.
- *
- *     Revision 1.38  1999/11/22 13:57:55  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.37  1999/09/14 14:25:32  rwahl
- *     Set MDB version for 1000Base-T (sensors, Master/Slave) changes.
- *
- *     Revision 1.36  1999/05/20 09:24:56  cgoos
- *     Changes for 1000Base-T (sensors, Master/Slave).
- *
- *     Revision 1.35  1999/04/13 15:10:51  mhaveman
- *     Replaced RLMT macros SK_RLMT_CHECK_xxx again by those of PNMI to
- *     grant unified interface. But PNMI macros will store the same
- *     value as RLMT macros.
- *
- *     Revision 1.34  1999/04/13 15:03:49  mhaveman
- *     -Changed copyright
- *     -Removed SK_PNMI_RLMT_MODE_CHK_xxx macros. Those of RLMT should be
- *      used.
- *
- *     Revision 1.33  1999/03/23 10:41:02  mhaveman
- *     Changed comments.
- *
- *     Revision 1.32  1999/01/25 15:01:33  mhaveman
- *     Added support for multiple simultaniously active ports.
- *
- *     Revision 1.31  1999/01/19 10:06:26  mhaveman
- *     Added new error log message.
- *
- *     Revision 1.30  1999/01/05 10:34:49  mhaveman
- *     Fixed little error in RlmtChangeEstimate calculation.
- *
- *     Revision 1.29  1999/01/05 09:59:41  mhaveman
- *     Redesigned port switch average calculation to avoid 64bit
- *     arithmetic.
- *
- *     Revision 1.28  1998/12/08 10:05:48  mhaveman
- *     Defined macro SK_PNMI_MIN_STRUCT_SIZE.
- *
- *     Revision 1.27  1998/12/03 14:39:35  mhaveman
- *     Fixed problem that LSTAT was enumerated wrong.
- *
- *     Revision 1.26  1998/12/03 11:19:51  mhaveman
- *     Changed contents of errlog message SK_PNMI_ERR016MSG
- *
- *     Revision 1.25  1998/12/01 10:40:04  mhaveman
- *     Changed size of SensorNumber, ChecksumNumber and RlmtPortNumber in
- *     SK_PNMI_STRUCT_DATA to be conform with OID definition.
- *
- *     Revision 1.24  1998/11/20 08:09:27  mhaveman
- *     Added macros to convert between logical, physical port indexes and
- *     instances.
- *
- *     Revision 1.23  1998/11/10 13:41:13  mhaveman
- *     Needed to change interface, because NT driver needs a return value
- *     of needed buffer space on TOO_SHORT errors. Therefore all
- *     SkPnmiGet/Preset/Set functions now have a pointer to the length
- *     parameter, where the needed space on error is returned.
- *
- *     Revision 1.22  1998/11/03 12:05:51  mhaveman
- *     Added pAC parameter to counter macors.
- *
- *     Revision 1.21  1998/11/02 10:47:36  mhaveman
- *     Added syslog messages for internal errors.
- *
- *     Revision 1.20  1998/10/30 15:49:36  mhaveman
- *     -Removed unused SK_PNMI_UTILIZATION_BASE and EstOldCnt.
- *     -Redefined SK_PNMI_CHG_EST_BASE to hundreds of seconds.
- *
- *     Revision 1.19  1998/10/29 15:38:44  mhaveman
- *     Changed string lengths of PNMI_STRUCT_DATA structure because
- *     string OIDs are now encoded with leading length ocetet.
- *
- *     Revision 1.18  1998/10/29 08:52:27  mhaveman
- *     -Added byte to strings in PNMI_STRUCT_DATA structure.
- *     -Shortened SK_PNMI_RLMT structure to SK_MAX_MACS elements.
- *
- *     Revision 1.17  1998/10/28 08:49:50  mhaveman
- *     -Changed type of Instance back to SK_U32 because of VPD
- *     -Changed type from SK_U8 to char of PciBusSpeed, PciBusWidth, PMD,
- *      and Connector.
- *
- *     Revision 1.16  1998/10/22 10:42:31  mhaveman
- *     -Removed (SK_U32) casts for OIDs
- *     -excluded NDIS OIDs when they are already defined with ifndef _NDIS_
- *
- *     Revision 1.15  1998/10/20 13:56:28  mhaveman
- *     Headerfile includes now directly other header files to comile correctly.
- *
- *     Revision 1.14  1998/10/20 07:31:09  mhaveman
- *     Made type changes to unsigned int where possible.
- *
- *     Revision 1.13  1998/10/19 10:53:13  mhaveman
- *     -Casted OID definitions to SK_U32
- *     -Renamed RlmtMAC... to RlmtPort...
- *     -Changed wrong type of VpdEntriesList from SK_U32 to char *
- *
- *     Revision 1.12  1998/10/13 07:42:27  mhaveman
- *     -Added OIDs OID_SKGE_TRAP_NUMBER and OID_SKGE_ALL_DATA
- *     -Removed old cvs history entries
- *     -Renamed MacNumber to PortNumber
- *
- *     Revision 1.11  1998/10/07 10:55:24  mhaveman
- *     -Added OID_MDB_VERSION. Therefore was a renumbering of the VPD OIDs
- *      necessary.
- *     -Added OID_GEN_ Ids to support the windows driver.
- *
- *     Revision 1.10  1998/09/30 13:41:10  mhaveman
- *     Renamed some OIDs to reduce usage of 'MAC' which is replaced by 'PORT'.
- *
- *     Revision 1.9  1998/09/04 17:06:17  mhaveman
- *     -Added SyncCounter as macro.
- *     -Renamed OID_SKGE_.._NO_DESCR_CTS to OID_SKGE_.._NO_BUF_CTS.
- *     -Added macros for driver description and version strings.
- *
- *     Revision 1.8  1998/09/04 14:36:52  mhaveman
- *     Added OIDs and Structure to access value of macro counters which are
- *     counted by the driver.
- *
- *     Revision 1.7  1998/09/04 11:59:36  mhaveman
- *     Everything compiles now. Driver Macros for counting still missing.
- *
- ****************************************************************************/
-
-#ifndef _SKGEPNMI_H_
-#define _SKGEPNMI_H_
-
-/*
- * Include dependencies
- */
-#include "h/sktypes.h"
-#include "h/skerror.h"
-#include "h/sktimer.h"
-#include "h/ski2c.h"
-#include "h/skaddr.h"
-#include "h/skrlmt.h"
-#include "h/skvpd.h"
-
-/*
- * Management Database Version
- */
-#define SK_PNMI_MDB_VERSION            0x00030001      /* 3.1 */
-
-
-/*
- * Event definitions
- */
-#define SK_PNMI_EVT_SIRQ_OVERFLOW              1       /* Counter overflow */
-#define SK_PNMI_EVT_SEN_WAR_LOW                        2       /* Lower war thres exceeded */
-#define SK_PNMI_EVT_SEN_WAR_UPP                        3       /* Upper war thres exceeded */
-#define SK_PNMI_EVT_SEN_ERR_LOW                        4       /* Lower err thres exceeded */
-#define SK_PNMI_EVT_SEN_ERR_UPP                        5       /* Upper err thres exceeded */
-#define SK_PNMI_EVT_CHG_EST_TIMER              6       /* Timer event for RLMT Chg */
-#define SK_PNMI_EVT_UTILIZATION_TIMER  7       /* Timer event for Utiliza. */
-#define SK_PNMI_EVT_CLEAR_COUNTER              8       /* Clear statistic counters */
-#define SK_PNMI_EVT_XMAC_RESET                 9       /* XMAC will be reset */
-
-#define SK_PNMI_EVT_RLMT_PORT_UP               10      /* Port came logically up */
-#define SK_PNMI_EVT_RLMT_PORT_DOWN             11      /* Port went logically down */
-#define SK_PNMI_EVT_RLMT_SEGMENTATION  13      /* Two SP root bridges found */
-#define SK_PNMI_EVT_RLMT_ACTIVE_DOWN   14      /* Port went logically down */
-#define SK_PNMI_EVT_RLMT_ACTIVE_UP             15      /* Port came logically up */
-#define SK_PNMI_EVT_RLMT_SET_NETS              16      /* 1. Parameter is number of nets
-                                                                                               1 = single net; 2 = dual net */
-#define SK_PNMI_EVT_VCT_RESET          17      /* VCT port reset timer event started with SET. */
-
-
-/*
- * Return values
- */
-#define SK_PNMI_ERR_OK                         0
-#define SK_PNMI_ERR_GENERAL                    1
-#define SK_PNMI_ERR_TOO_SHORT          2
-#define SK_PNMI_ERR_BAD_VALUE          3
-#define SK_PNMI_ERR_READ_ONLY          4
-#define SK_PNMI_ERR_UNKNOWN_OID                5
-#define SK_PNMI_ERR_UNKNOWN_INST       6
-#define SK_PNMI_ERR_UNKNOWN_NET        7
-
-
-/*
- * Return values of driver reset function SK_DRIVER_RESET() and
- * driver event function SK_DRIVER_EVENT()
- */
-#define SK_PNMI_ERR_OK                 0
-#define SK_PNMI_ERR_FAIL               1
-
-
-/*
- * Return values of driver test function SK_DRIVER_SELFTEST()
- */
-#define SK_PNMI_TST_UNKNOWN            (1 << 0)
-#define SK_PNMI_TST_TRANCEIVER         (1 << 1)
-#define SK_PNMI_TST_ASIC               (1 << 2)
-#define SK_PNMI_TST_SENSOR             (1 << 3)
-#define SK_PNMI_TST_POWERMGMT          (1 << 4)
-#define SK_PNMI_TST_PCI                        (1 << 5)
-#define SK_PNMI_TST_MAC                        (1 << 6)
-
-
-/*
- * RLMT specific definitions
- */
-#define SK_PNMI_RLMT_STATUS_STANDBY    1
-#define SK_PNMI_RLMT_STATUS_ACTIVE     2
-#define SK_PNMI_RLMT_STATUS_ERROR      3
-
-#define SK_PNMI_RLMT_LSTAT_PHY_DOWN    1
-#define SK_PNMI_RLMT_LSTAT_AUTONEG     2
-#define SK_PNMI_RLMT_LSTAT_LOG_DOWN    3
-#define SK_PNMI_RLMT_LSTAT_LOG_UP      4
-#define SK_PNMI_RLMT_LSTAT_INDETERMINATED 5
-
-#define SK_PNMI_RLMT_MODE_CHK_LINK     (SK_RLMT_CHECK_LINK)
-#define SK_PNMI_RLMT_MODE_CHK_RX       (SK_RLMT_CHECK_LOC_LINK)
-#define SK_PNMI_RLMT_MODE_CHK_SPT      (SK_RLMT_CHECK_SEG)
-/* #define SK_PNMI_RLMT_MODE_CHK_EX */
-
-/*
- * OID definition
- */
-#ifndef _NDIS_ /* Check, whether NDIS already included OIDs */
-
-#define OID_GEN_XMIT_OK                                        0x00020101
-#define OID_GEN_RCV_OK                                 0x00020102
-#define OID_GEN_XMIT_ERROR                             0x00020103
-#define OID_GEN_RCV_ERROR                              0x00020104
-#define OID_GEN_RCV_NO_BUFFER                  0x00020105
-
-/* #define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 */
-#define OID_GEN_DIRECTED_FRAMES_XMIT   0x00020202
-/* #define OID_GEN_MULTICAST_BYTES_XMIT        0x00020203 */
-#define OID_GEN_MULTICAST_FRAMES_XMIT  0x00020204
-/* #define OID_GEN_BROADCAST_BYTES_XMIT        0x00020205 */
-#define OID_GEN_BROADCAST_FRAMES_XMIT  0x00020206
-/* #define OID_GEN_DIRECTED_BYTES_RCV  0x00020207 */
-#define OID_GEN_DIRECTED_FRAMES_RCV            0x00020208
-/* #define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 */
-#define OID_GEN_MULTICAST_FRAMES_RCV   0x0002020A
-/* #define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B */
-#define OID_GEN_BROADCAST_FRAMES_RCV   0x0002020C
-#define OID_GEN_RCV_CRC_ERROR                  0x0002020D
-#define OID_GEN_TRANSMIT_QUEUE_LENGTH  0x0002020E
-
-#define OID_802_3_PERMANENT_ADDRESS            0x01010101
-#define OID_802_3_CURRENT_ADDRESS              0x01010102
-/* #define OID_802_3_MULTICAST_LIST            0x01010103 */
-/* #define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 */
-/* #define OID_802_3_MAC_OPTIONS               0x01010105 */
-
-#define OID_802_3_RCV_ERROR_ALIGNMENT  0x01020101
-#define OID_802_3_XMIT_ONE_COLLISION   0x01020102
-#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103
-#define OID_802_3_XMIT_DEFERRED                        0x01020201
-#define OID_802_3_XMIT_MAX_COLLISIONS  0x01020202
-#define OID_802_3_RCV_OVERRUN                  0x01020203
-#define OID_802_3_XMIT_UNDERRUN                        0x01020204
-#define OID_802_3_XMIT_TIMES_CRS_LOST  0x01020206
-#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
-
-/*
- * PnP and PM OIDs
- */
-#ifdef SK_POWER_MGMT
-#define OID_PNP_CAPABILITIES                   0xFD010100
-#define OID_PNP_SET_POWER                              0xFD010101
-#define OID_PNP_QUERY_POWER                            0xFD010102
-#define OID_PNP_ADD_WAKE_UP_PATTERN            0xFD010103
-#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104
-#define OID_PNP_ENABLE_WAKE_UP                 0xFD010106
-#endif /* SK_POWER_MGMT */
-
-#endif /* _NDIS_ */
-
-#define OID_SKGE_MDB_VERSION                   0xFF010100
-#define OID_SKGE_SUPPORTED_LIST                        0xFF010101
-#define OID_SKGE_VPD_FREE_BYTES                        0xFF010102
-#define OID_SKGE_VPD_ENTRIES_LIST              0xFF010103
-#define OID_SKGE_VPD_ENTRIES_NUMBER            0xFF010104
-#define OID_SKGE_VPD_KEY                               0xFF010105
-#define OID_SKGE_VPD_VALUE                             0xFF010106
-#define OID_SKGE_VPD_ACCESS                            0xFF010107
-#define OID_SKGE_VPD_ACTION                            0xFF010108
-
-#define OID_SKGE_PORT_NUMBER                   0xFF010110
-#define OID_SKGE_DEVICE_TYPE                   0xFF010111
-#define OID_SKGE_DRIVER_DESCR                  0xFF010112
-#define OID_SKGE_DRIVER_VERSION                        0xFF010113
-#define OID_SKGE_HW_DESCR                              0xFF010114
-#define OID_SKGE_HW_VERSION                            0xFF010115
-#define OID_SKGE_CHIPSET                               0xFF010116
-#define OID_SKGE_ACTION                                        0xFF010117
-#define OID_SKGE_RESULT                                        0xFF010118
-#define OID_SKGE_BUS_TYPE                              0xFF010119
-#define OID_SKGE_BUS_SPEED                             0xFF01011A
-#define OID_SKGE_BUS_WIDTH                             0xFF01011B
-/* 0xFF01011C unused */
-#define OID_SKGE_DIAG_ACTION                   0xFF01011D
-#define OID_SKGE_DIAG_RESULT                   0xFF01011E
-#define OID_SKGE_MTU                                   0xFF01011F
-#define OID_SKGE_PHYS_CUR_ADDR                 0xFF010120
-#define OID_SKGE_PHYS_FAC_ADDR                 0xFF010121
-#define OID_SKGE_PMD                                   0xFF010122
-#define OID_SKGE_CONNECTOR                             0xFF010123
-#define OID_SKGE_LINK_CAP                              0xFF010124
-#define OID_SKGE_LINK_MODE                             0xFF010125
-#define OID_SKGE_LINK_MODE_STATUS              0xFF010126
-#define OID_SKGE_LINK_STATUS                   0xFF010127
-#define OID_SKGE_FLOWCTRL_CAP                  0xFF010128
-#define OID_SKGE_FLOWCTRL_MODE                 0xFF010129
-#define OID_SKGE_FLOWCTRL_STATUS               0xFF01012A
-#define OID_SKGE_PHY_OPERATION_CAP             0xFF01012B
-#define OID_SKGE_PHY_OPERATION_MODE            0xFF01012C
-#define OID_SKGE_PHY_OPERATION_STATUS  0xFF01012D
-#define OID_SKGE_MULTICAST_LIST                        0xFF01012E
-#define OID_SKGE_CURRENT_PACKET_FILTER 0xFF01012F
-
-#define OID_SKGE_TRAP                                  0xFF010130
-#define OID_SKGE_TRAP_NUMBER                   0xFF010131
-
-#define OID_SKGE_RLMT_MODE                             0xFF010140
-#define OID_SKGE_RLMT_PORT_NUMBER              0xFF010141
-#define OID_SKGE_RLMT_PORT_ACTIVE              0xFF010142
-#define OID_SKGE_RLMT_PORT_PREFERRED   0xFF010143
-#define OID_SKGE_INTERMEDIATE_SUPPORT  0xFF010160
-
-#define OID_SKGE_SPEED_CAP                             0xFF010170
-#define OID_SKGE_SPEED_MODE                            0xFF010171
-#define OID_SKGE_SPEED_STATUS                  0xFF010172
-
-#define OID_SKGE_SENSOR_NUMBER                 0xFF020100
-#define OID_SKGE_SENSOR_INDEX                  0xFF020101
-#define OID_SKGE_SENSOR_DESCR                  0xFF020102
-#define OID_SKGE_SENSOR_TYPE                   0xFF020103
-#define OID_SKGE_SENSOR_VALUE                  0xFF020104
-#define OID_SKGE_SENSOR_WAR_THRES_LOW  0xFF020105
-#define OID_SKGE_SENSOR_WAR_THRES_UPP  0xFF020106
-#define OID_SKGE_SENSOR_ERR_THRES_LOW  0xFF020107
-#define OID_SKGE_SENSOR_ERR_THRES_UPP  0xFF020108
-#define OID_SKGE_SENSOR_STATUS                 0xFF020109
-#define OID_SKGE_SENSOR_WAR_CTS                        0xFF02010A
-#define OID_SKGE_SENSOR_ERR_CTS                        0xFF02010B
-#define OID_SKGE_SENSOR_WAR_TIME               0xFF02010C
-#define OID_SKGE_SENSOR_ERR_TIME               0xFF02010D
-
-#define OID_SKGE_CHKSM_NUMBER                  0xFF020110
-#define OID_SKGE_CHKSM_RX_OK_CTS               0xFF020111
-#define OID_SKGE_CHKSM_RX_UNABLE_CTS   0xFF020112
-#define OID_SKGE_CHKSM_RX_ERR_CTS              0xFF020113
-#define OID_SKGE_CHKSM_TX_OK_CTS               0xFF020114
-#define OID_SKGE_CHKSM_TX_UNABLE_CTS   0xFF020115
-
-#define OID_SKGE_STAT_TX                               0xFF020120
-#define OID_SKGE_STAT_TX_OCTETS                        0xFF020121
-#define OID_SKGE_STAT_TX_BROADCAST             0xFF020122
-#define OID_SKGE_STAT_TX_MULTICAST             0xFF020123
-#define OID_SKGE_STAT_TX_UNICAST               0xFF020124
-#define OID_SKGE_STAT_TX_LONGFRAMES            0xFF020125
-#define OID_SKGE_STAT_TX_BURST                 0xFF020126
-#define OID_SKGE_STAT_TX_PFLOWC                        0xFF020127
-#define OID_SKGE_STAT_TX_FLOWC                 0xFF020128
-#define OID_SKGE_STAT_TX_SINGLE_COL            0xFF020129
-#define OID_SKGE_STAT_TX_MULTI_COL             0xFF02012A
-#define OID_SKGE_STAT_TX_EXCESS_COL            0xFF02012B
-#define OID_SKGE_STAT_TX_LATE_COL              0xFF02012C
-#define OID_SKGE_STAT_TX_DEFFERAL              0xFF02012D
-#define OID_SKGE_STAT_TX_EXCESS_DEF            0xFF02012E
-#define OID_SKGE_STAT_TX_UNDERRUN              0xFF02012F
-#define OID_SKGE_STAT_TX_CARRIER               0xFF020130
-/* #define OID_SKGE_STAT_TX_UTIL               0xFF020131 */
-#define OID_SKGE_STAT_TX_64                            0xFF020132
-#define OID_SKGE_STAT_TX_127                   0xFF020133
-#define OID_SKGE_STAT_TX_255                   0xFF020134
-#define OID_SKGE_STAT_TX_511                   0xFF020135
-#define OID_SKGE_STAT_TX_1023                  0xFF020136
-#define OID_SKGE_STAT_TX_MAX                   0xFF020137
-#define OID_SKGE_STAT_TX_SYNC                  0xFF020138
-#define OID_SKGE_STAT_TX_SYNC_OCTETS   0xFF020139
-#define OID_SKGE_STAT_RX                               0xFF02013A
-#define OID_SKGE_STAT_RX_OCTETS                        0xFF02013B
-#define OID_SKGE_STAT_RX_BROADCAST             0xFF02013C
-#define OID_SKGE_STAT_RX_MULTICAST             0xFF02013D
-#define OID_SKGE_STAT_RX_UNICAST               0xFF02013E
-#define OID_SKGE_STAT_RX_PFLOWC                        0xFF02013F
-#define OID_SKGE_STAT_RX_FLOWC                 0xFF020140
-#define OID_SKGE_STAT_RX_PFLOWC_ERR            0xFF020141
-#define OID_SKGE_STAT_RX_FLOWC_UNKWN   0xFF020142
-#define OID_SKGE_STAT_RX_BURST                 0xFF020143
-#define OID_SKGE_STAT_RX_MISSED                        0xFF020144
-#define OID_SKGE_STAT_RX_FRAMING               0xFF020145
-#define OID_SKGE_STAT_RX_OVERFLOW              0xFF020146
-#define OID_SKGE_STAT_RX_JABBER                        0xFF020147
-#define OID_SKGE_STAT_RX_CARRIER               0xFF020148
-#define OID_SKGE_STAT_RX_IR_LENGTH             0xFF020149
-#define OID_SKGE_STAT_RX_SYMBOL                        0xFF02014A
-#define OID_SKGE_STAT_RX_SHORTS                        0xFF02014B
-#define OID_SKGE_STAT_RX_RUNT                  0xFF02014C
-#define OID_SKGE_STAT_RX_CEXT                  0xFF02014D
-#define OID_SKGE_STAT_RX_TOO_LONG              0xFF02014E
-#define OID_SKGE_STAT_RX_FCS                   0xFF02014F
-/* #define OID_SKGE_STAT_RX_UTIL               0xFF020150 */
-#define OID_SKGE_STAT_RX_64                            0xFF020151
-#define OID_SKGE_STAT_RX_127                   0xFF020152
-#define OID_SKGE_STAT_RX_255                   0xFF020153
-#define OID_SKGE_STAT_RX_511                   0xFF020154
-#define OID_SKGE_STAT_RX_1023                  0xFF020155
-#define OID_SKGE_STAT_RX_MAX                   0xFF020156
-#define OID_SKGE_STAT_RX_LONGFRAMES            0xFF020157
-
-#define OID_SKGE_RLMT_CHANGE_CTS               0xFF020160
-#define OID_SKGE_RLMT_CHANGE_TIME              0xFF020161
-#define OID_SKGE_RLMT_CHANGE_ESTIM             0xFF020162
-#define OID_SKGE_RLMT_CHANGE_THRES             0xFF020163
-
-#define OID_SKGE_RLMT_PORT_INDEX               0xFF020164
-#define OID_SKGE_RLMT_STATUS                   0xFF020165
-#define OID_SKGE_RLMT_TX_HELLO_CTS             0xFF020166
-#define OID_SKGE_RLMT_RX_HELLO_CTS             0xFF020167
-#define OID_SKGE_RLMT_TX_SP_REQ_CTS            0xFF020168
-#define OID_SKGE_RLMT_RX_SP_CTS                        0xFF020169
-
-#define OID_SKGE_RLMT_MONITOR_NUMBER   0xFF010150
-#define OID_SKGE_RLMT_MONITOR_INDEX            0xFF010151
-#define OID_SKGE_RLMT_MONITOR_ADDR             0xFF010152
-#define OID_SKGE_RLMT_MONITOR_ERRS             0xFF010153
-#define OID_SKGE_RLMT_MONITOR_TIMESTAMP        0xFF010154
-#define OID_SKGE_RLMT_MONITOR_ADMIN            0xFF010155
-
-#define OID_SKGE_TX_SW_QUEUE_LEN               0xFF020170
-#define OID_SKGE_TX_SW_QUEUE_MAX               0xFF020171
-#define OID_SKGE_TX_RETRY                              0xFF020172
-#define OID_SKGE_RX_INTR_CTS                   0xFF020173
-#define OID_SKGE_TX_INTR_CTS                   0xFF020174
-#define OID_SKGE_RX_NO_BUF_CTS                 0xFF020175
-#define OID_SKGE_TX_NO_BUF_CTS                 0xFF020176
-#define OID_SKGE_TX_USED_DESCR_NO              0xFF020177
-#define OID_SKGE_RX_DELIVERED_CTS              0xFF020178
-#define OID_SKGE_RX_OCTETS_DELIV_CTS   0xFF020179
-#define OID_SKGE_RX_HW_ERROR_CTS               0xFF02017A
-#define OID_SKGE_TX_HW_ERROR_CTS               0xFF02017B
-#define OID_SKGE_IN_ERRORS_CTS                 0xFF02017C
-#define OID_SKGE_OUT_ERROR_CTS                 0xFF02017D
-#define OID_SKGE_ERR_RECOVERY_CTS              0xFF02017E
-#define OID_SKGE_SYSUPTIME                             0xFF02017F
-
-#define OID_SKGE_ALL_DATA                              0xFF020190
-
-/* Defines for VCT. */
-#define OID_SKGE_VCT_GET                       0xFF020200
-#define OID_SKGE_VCT_SET                       0xFF020201
-#define OID_SKGE_VCT_STATUS                    0xFF020202
-
-
-/* VCT struct to store a backup copy of VCT data after a port reset. */
-typedef struct s_PnmiVct {
-       SK_U8                   VctStatus;
-       SK_U8                   PCableLen;
-       SK_U32                  PMdiPairLen[4];
-       SK_U8                   PMdiPairSts[4];
-} SK_PNMI_VCT;
-
-
-/* VCT status values (to be given to CPA via OID_SKGE_VCT_STATUS). */
-#define SK_PNMI_VCT_NONE               0
-#define SK_PNMI_VCT_OLD_VCT_DATA       1
-#define SK_PNMI_VCT_NEW_VCT_DATA       2
-#define SK_PNMI_VCT_OLD_DSP_DATA       4
-#define SK_PNMI_VCT_NEW_DSP_DATA       8
-#define SK_PNMI_VCT_RUNNING            16
-
-
-/* VCT cable test status. */
-#define SK_PNMI_VCT_NORMAL_CABLE               0
-#define SK_PNMI_VCT_SHORT_CABLE                        1
-#define SK_PNMI_VCT_OPEN_CABLE                 2
-#define SK_PNMI_VCT_TEST_FAIL                  3
-#define SK_PNMI_VCT_IMPEDANCE_MISMATCH         4
-
-#define        OID_SKGE_TRAP_SEN_WAR_LOW               500
-#define OID_SKGE_TRAP_SEN_WAR_UPP              501
-#define        OID_SKGE_TRAP_SEN_ERR_LOW               502
-#define OID_SKGE_TRAP_SEN_ERR_UPP              503
-#define OID_SKGE_TRAP_RLMT_CHANGE_THRES        520
-#define OID_SKGE_TRAP_RLMT_CHANGE_PORT 521
-#define OID_SKGE_TRAP_RLMT_PORT_DOWN   522
-#define OID_SKGE_TRAP_RLMT_PORT_UP             523
-#define OID_SKGE_TRAP_RLMT_SEGMENTATION        524
-
-
-/*
- * Define error numbers and messages for syslog
- */
-#define SK_PNMI_ERR001         (SK_ERRBASE_PNMI + 1)
-#define SK_PNMI_ERR001MSG      "SkPnmiGetStruct: Unknown OID"
-#define SK_PNMI_ERR002         (SK_ERRBASE_PNMI + 2)
-#define SK_PNMI_ERR002MSG      "SkPnmiGetStruct: Cannot read VPD keys"
-#define SK_PNMI_ERR003         (SK_ERRBASE_PNMI + 3)
-#define SK_PNMI_ERR003MSG      "OidStruct: Called with wrong OID"
-#define SK_PNMI_ERR004         (SK_ERRBASE_PNMI + 4)
-#define SK_PNMI_ERR004MSG      "OidStruct: Called with wrong action"
-#define SK_PNMI_ERR005         (SK_ERRBASE_PNMI + 5)
-#define SK_PNMI_ERR005MSG      "Perform: Cannot reset driver"
-#define SK_PNMI_ERR006         (SK_ERRBASE_PNMI + 6)
-#define SK_PNMI_ERR006MSG      "Perform: Unknown OID action command"
-#define SK_PNMI_ERR007         (SK_ERRBASE_PNMI + 7)
-#define SK_PNMI_ERR007MSG      "General: Driver description not initialized"
-#define SK_PNMI_ERR008         (SK_ERRBASE_PNMI + 8)
-#define SK_PNMI_ERR008MSG      "Addr: Tried to get unknown OID"
-#define SK_PNMI_ERR009         (SK_ERRBASE_PNMI + 9)
-#define SK_PNMI_ERR009MSG      "Addr: Unknown OID"
-#define SK_PNMI_ERR010         (SK_ERRBASE_PNMI + 10)
-#define SK_PNMI_ERR010MSG      "CsumStat: Unknown OID"
-#define SK_PNMI_ERR011         (SK_ERRBASE_PNMI + 11)
-#define SK_PNMI_ERR011MSG      "SensorStat: Sensor descr string too long"
-#define SK_PNMI_ERR012         (SK_ERRBASE_PNMI + 12)
-#define SK_PNMI_ERR012MSG      "SensorStat: Unknown OID"
-#define SK_PNMI_ERR013         (SK_ERRBASE_PNMI + 13)
-#define SK_PNMI_ERR013MSG      ""
-#define SK_PNMI_ERR014         (SK_ERRBASE_PNMI + 14)
-#define SK_PNMI_ERR014MSG      "Vpd: Cannot read VPD keys"
-#define SK_PNMI_ERR015         (SK_ERRBASE_PNMI + 15)
-#define SK_PNMI_ERR015MSG      "Vpd: Internal array for VPD keys to small"
-#define SK_PNMI_ERR016         (SK_ERRBASE_PNMI + 16)
-#define SK_PNMI_ERR016MSG      "Vpd: Key string too long"
-#define SK_PNMI_ERR017         (SK_ERRBASE_PNMI + 17)
-#define SK_PNMI_ERR017MSG      "Vpd: Invalid VPD status pointer"
-#define SK_PNMI_ERR018         (SK_ERRBASE_PNMI + 18)
-#define SK_PNMI_ERR018MSG      "Vpd: VPD data not valid"
-#define SK_PNMI_ERR019         (SK_ERRBASE_PNMI + 19)
-#define SK_PNMI_ERR019MSG      "Vpd: VPD entries list string too long"
-#define SK_PNMI_ERR021         (SK_ERRBASE_PNMI + 21)
-#define SK_PNMI_ERR021MSG      "Vpd: VPD data string too long"
-#define SK_PNMI_ERR022         (SK_ERRBASE_PNMI + 22)
-#define SK_PNMI_ERR022MSG      "Vpd: VPD data string too long should be errored before"
-#define SK_PNMI_ERR023         (SK_ERRBASE_PNMI + 23)
-#define SK_PNMI_ERR023MSG      "Vpd: Unknown OID in get action"
-#define SK_PNMI_ERR024         (SK_ERRBASE_PNMI + 24)
-#define SK_PNMI_ERR024MSG      "Vpd: Unknown OID in preset/set action"
-#define SK_PNMI_ERR025         (SK_ERRBASE_PNMI + 25)
-#define SK_PNMI_ERR025MSG      "Vpd: Cannot write VPD after modify entry"
-#define SK_PNMI_ERR026         (SK_ERRBASE_PNMI + 26)
-#define SK_PNMI_ERR026MSG      "Vpd: Cannot update VPD"
-#define SK_PNMI_ERR027         (SK_ERRBASE_PNMI + 27)
-#define SK_PNMI_ERR027MSG      "Vpd: Cannot delete VPD entry"
-#define SK_PNMI_ERR028         (SK_ERRBASE_PNMI + 28)
-#define SK_PNMI_ERR028MSG      "Vpd: Cannot update VPD after delete entry"
-#define SK_PNMI_ERR029         (SK_ERRBASE_PNMI + 29)
-#define SK_PNMI_ERR029MSG      "General: Driver description string too long"
-#define SK_PNMI_ERR030         (SK_ERRBASE_PNMI + 30)
-#define SK_PNMI_ERR030MSG      "General: Driver version not initialized"
-#define SK_PNMI_ERR031         (SK_ERRBASE_PNMI + 31)
-#define SK_PNMI_ERR031MSG      "General: Driver version string too long"
-#define SK_PNMI_ERR032         (SK_ERRBASE_PNMI + 32)
-#define SK_PNMI_ERR032MSG      "General: Cannot read VPD Name for HW descr"
-#define SK_PNMI_ERR033         (SK_ERRBASE_PNMI + 33)
-#define SK_PNMI_ERR033MSG      "General: HW description string too long"
-#define SK_PNMI_ERR034         (SK_ERRBASE_PNMI + 34)
-#define SK_PNMI_ERR034MSG      "General: Unknown OID"
-#define SK_PNMI_ERR035         (SK_ERRBASE_PNMI + 35)
-#define SK_PNMI_ERR035MSG      "Rlmt: Unknown OID"
-#define SK_PNMI_ERR036         (SK_ERRBASE_PNMI + 36)
-#define SK_PNMI_ERR036MSG      ""
-#define SK_PNMI_ERR037         (SK_ERRBASE_PNMI + 37)
-#define SK_PNMI_ERR037MSG      "Rlmt: SK_RLMT_MODE_CHANGE event return not 0"
-#define SK_PNMI_ERR038         (SK_ERRBASE_PNMI + 38)
-#define SK_PNMI_ERR038MSG      "Rlmt: SK_RLMT_PREFPORT_CHANGE event return not 0"
-#define SK_PNMI_ERR039         (SK_ERRBASE_PNMI + 39)
-#define SK_PNMI_ERR039MSG      "RlmtStat: Unknown OID"
-#define SK_PNMI_ERR040         (SK_ERRBASE_PNMI + 40)
-#define SK_PNMI_ERR040MSG      "PowerManagement: Unknown OID"
-#define SK_PNMI_ERR041         (SK_ERRBASE_PNMI + 41)
-#define SK_PNMI_ERR041MSG      "MacPrivateConf: Unknown OID"
-#define SK_PNMI_ERR042         (SK_ERRBASE_PNMI + 42)
-#define SK_PNMI_ERR042MSG      "MacPrivateConf: SK_HWEV_SET_ROLE returned not 0"
-#define SK_PNMI_ERR043         (SK_ERRBASE_PNMI + 43)
-#define SK_PNMI_ERR043MSG      "MacPrivateConf: SK_HWEV_SET_LMODE returned not 0"
-#define SK_PNMI_ERR044         (SK_ERRBASE_PNMI + 44)
-#define SK_PNMI_ERR044MSG      "MacPrivateConf: SK_HWEV_SET_FLOWMODE returned not 0"
-#define SK_PNMI_ERR045         (SK_ERRBASE_PNMI + 45)
-#define SK_PNMI_ERR045MSG      "MacPrivateConf: SK_HWEV_SET_SPEED returned not 0"
-#define SK_PNMI_ERR046         (SK_ERRBASE_PNMI + 46)
-#define SK_PNMI_ERR046MSG      "Monitor: Unknown OID"
-#define SK_PNMI_ERR047         (SK_ERRBASE_PNMI + 47)
-#define SK_PNMI_ERR047MSG      "SirqUpdate: Event function returns not 0"
-#define SK_PNMI_ERR048         (SK_ERRBASE_PNMI + 48)
-#define SK_PNMI_ERR048MSG      "RlmtUpdate: Event function returns not 0"
-#define SK_PNMI_ERR049         (SK_ERRBASE_PNMI + 49)
-#define SK_PNMI_ERR049MSG      "SkPnmiInit: Invalid size of 'CounterOffset' struct!!"
-#define SK_PNMI_ERR050         (SK_ERRBASE_PNMI + 50)
-#define SK_PNMI_ERR050MSG      "SkPnmiInit: Invalid size of 'StatAddr' table!!"
-#define SK_PNMI_ERR051         (SK_ERRBASE_PNMI + 51)
-#define SK_PNMI_ERR051MSG      "SkPnmiEvent: Port switch suspicious"
-#define SK_PNMI_ERR052         (SK_ERRBASE_PNMI + 52)
-#define SK_PNMI_ERR052MSG      ""
-
-/*
- * Management counter macros called by the driver
- */
-#define SK_PNMI_SET_DRIVER_DESCR(pAC,v)        ((pAC)->Pnmi.pDriverDescription = \
-       (char *)(v))
-
-#define SK_PNMI_SET_DRIVER_VER(pAC,v)  ((pAC)->Pnmi.pDriverVersion = \
-       (char *)(v))
-
-
-#define SK_PNMI_CNT_TX_QUEUE_LEN(pAC,v,p) \
-       { \
-               (pAC)->Pnmi.Port[p].TxSwQueueLen = (SK_U64)(v); \
-               if ((pAC)->Pnmi.Port[p].TxSwQueueLen > (pAC)->Pnmi.Port[p].TxSwQueueMax) { \
-                       (pAC)->Pnmi.Port[p].TxSwQueueMax = (pAC)->Pnmi.Port[p].TxSwQueueLen; \
-               } \
-       }
-#define SK_PNMI_CNT_TX_RETRY(pAC,p)    (((pAC)->Pnmi.Port[p].TxRetryCts)++)
-#define SK_PNMI_CNT_RX_INTR(pAC,p)     (((pAC)->Pnmi.Port[p].RxIntrCts)++)
-#define SK_PNMI_CNT_TX_INTR(pAC,p)     (((pAC)->Pnmi.Port[p].TxIntrCts)++)
-#define SK_PNMI_CNT_NO_RX_BUF(pAC,p)   (((pAC)->Pnmi.Port[p].RxNoBufCts)++)
-#define SK_PNMI_CNT_NO_TX_BUF(pAC,p)   (((pAC)->Pnmi.Port[p].TxNoBufCts)++)
-#define SK_PNMI_CNT_USED_TX_DESCR(pAC,v,p) \
-       ((pAC)->Pnmi.Port[p].TxUsedDescrNo=(SK_U64)(v));
-#define SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,v,p) \
-       { \
-               ((pAC)->Pnmi.Port[p].RxDeliveredCts)++; \
-               (pAC)->Pnmi.Port[p].RxOctetsDeliveredCts += (SK_U64)(v); \
-       }
-#define SK_PNMI_CNT_ERR_RECOVERY(pAC,p)        (((pAC)->Pnmi.Port[p].ErrRecoveryCts)++);
-
-#define SK_PNMI_CNT_SYNC_OCTETS(pAC,p,v) \
-       { \
-               if ((p) < SK_MAX_MACS) { \
-                       ((pAC)->Pnmi.Port[p].StatSyncCts)++; \
-                       (pAC)->Pnmi.Port[p].StatSyncOctetsCts += (SK_U64)(v); \
-               } \
-       }
-
-#define SK_PNMI_CNT_RX_LONGFRAMES(pAC,p) \
-       { \
-               if ((p) < SK_MAX_MACS) { \
-                       ((pAC)->Pnmi.Port[p].StatRxLongFrameCts++); \
-               } \
-       }
-
-#define SK_PNMI_CNT_RX_FRAMETOOLONG(pAC,p) \
-       { \
-               if ((p) < SK_MAX_MACS) { \
-                       ((pAC)->Pnmi.Port[p].StatRxFrameTooLongCts++); \
-               } \
-       }
-
-#define SK_PNMI_CNT_RX_PMACC_ERR(pAC,p) \
-       { \
-               if ((p) < SK_MAX_MACS) { \
-                       ((pAC)->Pnmi.Port[p].StatRxPMaccErr++); \
-               } \
-       }
-
-/*
- * Conversion Macros
- */
-#define SK_PNMI_PORT_INST2LOG(i)       ((unsigned int)(i) - 1)
-#define SK_PNMI_PORT_LOG2INST(l)       ((unsigned int)(l) + 1)
-#define SK_PNMI_PORT_PHYS2LOG(p)       ((unsigned int)(p) + 1)
-#define SK_PNMI_PORT_LOG2PHYS(pAC,l)   ((unsigned int)(l) - 1)
-#define SK_PNMI_PORT_PHYS2INST(pAC,p)  \
-       (pAC->Pnmi.DualNetActiveFlag ? 2 : ((unsigned int)(p) + 2))
-#define SK_PNMI_PORT_INST2PHYS(pAC,i)  ((unsigned int)(i) - 2)
-
-/*
- * Structure definition for SkPnmiGetStruct and SkPnmiSetStruct
- */
-#define SK_PNMI_VPD_KEY_SIZE   5
-#define SK_PNMI_VPD_BUFSIZE            (VPD_SIZE)
-#define SK_PNMI_VPD_ENTRIES            (VPD_SIZE / 4)
-#define SK_PNMI_VPD_DATALEN            128 /*  Number of data bytes */
-
-#define SK_PNMI_MULTICAST_LISTLEN      64
-#define SK_PNMI_SENSOR_ENTRIES         (SK_MAX_SENSORS)
-#define SK_PNMI_CHECKSUM_ENTRIES       3
-#define SK_PNMI_MAC_ENTRIES                    (SK_MAX_MACS + 1)
-#define SK_PNMI_MONITOR_ENTRIES                20
-#define SK_PNMI_TRAP_ENTRIES           10
-#define SK_PNMI_TRAPLEN                                128
-#define SK_PNMI_STRINGLEN1                     80
-#define SK_PNMI_STRINGLEN2                     25
-#define SK_PNMI_TRAP_QUEUE_LEN         512
-
-typedef struct s_PnmiVpd {
-       char                    VpdKey[SK_PNMI_VPD_KEY_SIZE];
-       char                    VpdValue[SK_PNMI_VPD_DATALEN];
-       SK_U8                   VpdAccess;
-       SK_U8                   VpdAction;
-} SK_PNMI_VPD;
-
-typedef struct s_PnmiSensor {
-       SK_U8                   SensorIndex;
-       char                    SensorDescr[SK_PNMI_STRINGLEN2];
-       SK_U8                   SensorType;
-       SK_U32                  SensorValue;
-       SK_U32                  SensorWarningThresholdLow;
-       SK_U32                  SensorWarningThresholdHigh;
-       SK_U32                  SensorErrorThresholdLow;
-       SK_U32                  SensorErrorThresholdHigh;
-       SK_U8                   SensorStatus;
-       SK_U64                  SensorWarningCts;
-       SK_U64                  SensorErrorCts;
-       SK_U64                  SensorWarningTimestamp;
-       SK_U64                  SensorErrorTimestamp;
-} SK_PNMI_SENSOR;
-
-typedef struct s_PnmiChecksum {
-       SK_U64                  ChecksumRxOkCts;
-       SK_U64                  ChecksumRxUnableCts;
-       SK_U64                  ChecksumRxErrCts;
-       SK_U64                  ChecksumTxOkCts;
-       SK_U64                  ChecksumTxUnableCts;
-} SK_PNMI_CHECKSUM;
-
-typedef struct s_PnmiStat {
-       SK_U64                  StatTxOkCts;
-       SK_U64                  StatTxOctetsOkCts;
-       SK_U64                  StatTxBroadcastOkCts;
-       SK_U64                  StatTxMulticastOkCts;
-       SK_U64                  StatTxUnicastOkCts;
-       SK_U64                  StatTxLongFramesCts;
-       SK_U64                  StatTxBurstCts;
-       SK_U64                  StatTxPauseMacCtrlCts;
-       SK_U64                  StatTxMacCtrlCts;
-       SK_U64                  StatTxSingleCollisionCts;
-       SK_U64                  StatTxMultipleCollisionCts;
-       SK_U64                  StatTxExcessiveCollisionCts;
-       SK_U64                  StatTxLateCollisionCts;
-       SK_U64                  StatTxDeferralCts;
-       SK_U64                  StatTxExcessiveDeferralCts;
-       SK_U64                  StatTxFifoUnderrunCts;
-       SK_U64                  StatTxCarrierCts;
-       SK_U64                  Dummy1; /* StatTxUtilization */
-       SK_U64                  StatTx64Cts;
-       SK_U64                  StatTx127Cts;
-       SK_U64                  StatTx255Cts;
-       SK_U64                  StatTx511Cts;
-       SK_U64                  StatTx1023Cts;
-       SK_U64                  StatTxMaxCts;
-       SK_U64                  StatTxSyncCts;
-       SK_U64                  StatTxSyncOctetsCts;
-       SK_U64                  StatRxOkCts;
-       SK_U64                  StatRxOctetsOkCts;
-       SK_U64                  StatRxBroadcastOkCts;
-       SK_U64                  StatRxMulticastOkCts;
-       SK_U64                  StatRxUnicastOkCts;
-       SK_U64                  StatRxLongFramesCts;
-       SK_U64                  StatRxPauseMacCtrlCts;
-       SK_U64                  StatRxMacCtrlCts;
-       SK_U64                  StatRxPauseMacCtrlErrorCts;
-       SK_U64                  StatRxMacCtrlUnknownCts;
-       SK_U64                  StatRxBurstCts;
-       SK_U64                  StatRxMissedCts;
-       SK_U64                  StatRxFramingCts;
-       SK_U64                  StatRxFifoOverflowCts;
-       SK_U64                  StatRxJabberCts;
-       SK_U64                  StatRxCarrierCts;
-       SK_U64                  StatRxIRLengthCts;
-       SK_U64                  StatRxSymbolCts;
-       SK_U64                  StatRxShortsCts;
-       SK_U64                  StatRxRuntCts;
-       SK_U64                  StatRxCextCts;
-       SK_U64                  StatRxTooLongCts;
-       SK_U64                  StatRxFcsCts;
-       SK_U64                  Dummy2; /* StatRxUtilization */
-       SK_U64                  StatRx64Cts;
-       SK_U64                  StatRx127Cts;
-       SK_U64                  StatRx255Cts;
-       SK_U64                  StatRx511Cts;
-       SK_U64                  StatRx1023Cts;
-       SK_U64                  StatRxMaxCts;
-} SK_PNMI_STAT;
-
-typedef struct s_PnmiConf {
-       char                    ConfMacCurrentAddr[6];
-       char                    ConfMacFactoryAddr[6];
-       SK_U8                   ConfPMD;
-       SK_U8                   ConfConnector;
-       SK_U8                   ConfLinkCapability;
-       SK_U8                   ConfLinkMode;
-       SK_U8                   ConfLinkModeStatus;
-       SK_U8                   ConfLinkStatus;
-       SK_U8                   ConfFlowCtrlCapability;
-       SK_U8                   ConfFlowCtrlMode;
-       SK_U8                   ConfFlowCtrlStatus;
-       SK_U8                   ConfPhyOperationCapability;
-       SK_U8                   ConfPhyOperationMode;
-       SK_U8                   ConfPhyOperationStatus;
-       SK_U8                   ConfSpeedCapability;
-       SK_U8                   ConfSpeedMode;
-       SK_U8                   ConfSpeedStatus;
-} SK_PNMI_CONF;
-
-typedef struct s_PnmiRlmt {
-       SK_U32                  RlmtIndex;
-       SK_U32                  RlmtStatus;
-       SK_U64                  RlmtTxHelloCts;
-       SK_U64                  RlmtRxHelloCts;
-       SK_U64                  RlmtTxSpHelloReqCts;
-       SK_U64                  RlmtRxSpHelloCts;
-} SK_PNMI_RLMT;
-
-typedef struct s_PnmiRlmtMonitor {
-       SK_U32                  RlmtMonitorIndex;
-       char                    RlmtMonitorAddr[6];
-       SK_U64                  RlmtMonitorErrorCts;
-       SK_U64                  RlmtMonitorTimestamp;
-       SK_U8                   RlmtMonitorAdmin;
-} SK_PNMI_RLMT_MONITOR;
-
-typedef struct s_PnmiRequestStatus {
-       SK_U32                  ErrorStatus;
-       SK_U32                  ErrorOffset;
-} SK_PNMI_REQUEST_STATUS;
-
-typedef struct s_PnmiStrucData {
-       SK_U32                  MgmtDBVersion;
-       SK_PNMI_REQUEST_STATUS  ReturnStatus;
-       SK_U32                  VpdFreeBytes;
-       char                    VpdEntriesList[SK_PNMI_VPD_ENTRIES * SK_PNMI_VPD_KEY_SIZE];
-       SK_U32                  VpdEntriesNumber;
-       SK_PNMI_VPD             Vpd[SK_PNMI_VPD_ENTRIES];
-       SK_U32                  PortNumber;
-       SK_U32                  DeviceType;
-       char                    DriverDescr[SK_PNMI_STRINGLEN1];
-       char                    DriverVersion[SK_PNMI_STRINGLEN2];
-       char                    HwDescr[SK_PNMI_STRINGLEN1];
-       char                    HwVersion[SK_PNMI_STRINGLEN2];
-       SK_U16                  Chipset;
-       SK_U32                  MtuSize;
-       SK_U32                  Action;
-       SK_U32                  TestResult;
-       SK_U8                   BusType;
-       SK_U8                   BusSpeed;
-       SK_U8                   BusWidth;
-       SK_U8                   SensorNumber;
-       SK_PNMI_SENSOR  Sensor[SK_PNMI_SENSOR_ENTRIES];
-       SK_U8                   ChecksumNumber;
-       SK_PNMI_CHECKSUM        Checksum[SK_PNMI_CHECKSUM_ENTRIES];
-       SK_PNMI_STAT    Stat[SK_PNMI_MAC_ENTRIES];
-       SK_PNMI_CONF    Conf[SK_PNMI_MAC_ENTRIES];
-       SK_U8                   RlmtMode;
-       SK_U32                  RlmtPortNumber;
-       SK_U8                   RlmtPortActive;
-       SK_U8                   RlmtPortPreferred;
-       SK_U64                  RlmtChangeCts;
-       SK_U64                  RlmtChangeTime;
-       SK_U64                  RlmtChangeEstimate;
-       SK_U64                  RlmtChangeThreshold;
-       SK_PNMI_RLMT    Rlmt[SK_MAX_MACS];
-       SK_U32                  RlmtMonitorNumber;
-       SK_PNMI_RLMT_MONITOR    RlmtMonitor[SK_PNMI_MONITOR_ENTRIES];
-       SK_U32                  TrapNumber;
-       SK_U8                   Trap[SK_PNMI_TRAP_QUEUE_LEN];
-       SK_U64                  TxSwQueueLen;
-       SK_U64                  TxSwQueueMax;
-       SK_U64                  TxRetryCts;
-       SK_U64                  RxIntrCts;
-       SK_U64                  TxIntrCts;
-       SK_U64                  RxNoBufCts;
-       SK_U64                  TxNoBufCts;
-       SK_U64                  TxUsedDescrNo;
-       SK_U64                  RxDeliveredCts;
-       SK_U64                  RxOctetsDeliveredCts;
-       SK_U64                  RxHwErrorsCts;
-       SK_U64                  TxHwErrorsCts;
-       SK_U64                  InErrorsCts;
-       SK_U64                  OutErrorsCts;
-       SK_U64                  ErrRecoveryCts;
-       SK_U64                  SysUpTime;
-} SK_PNMI_STRUCT_DATA;
-
-#define SK_PNMI_STRUCT_SIZE    (sizeof(SK_PNMI_STRUCT_DATA))
-#define SK_PNMI_MIN_STRUCT_SIZE        ((unsigned int)(SK_UPTR)\
-                                &(((SK_PNMI_STRUCT_DATA *)0)->VpdFreeBytes))
-                                                                                                               /*
-                                                                                                                * ReturnStatus field
-                                                                                                                * must be located
-                                                                                                                * before VpdFreeBytes
-                                                                                                                */
-
-/*
- * Various definitions
- */
-#define SK_PNMI_MAX_PROTOS             3
-
-#define SK_PNMI_CNT_NO                 66      /* Must have the value of the enum
-                                                                        * SK_PNMI_MAX_IDX. Define SK_PNMI_CHECK
-                                                                        * for check while init phase 1
-                                                                        */
-
-/*
- * Estimate data structure
- */
-typedef struct s_PnmiEstimate {
-       unsigned int    EstValueIndex;
-       SK_U64                  EstValue[7];
-       SK_U64                  Estimate;
-       SK_TIMER                EstTimer;
-} SK_PNMI_ESTIMATE;
-
-
-/*
- * VCT timer data structure
- */
-typedef struct s_VctTimer {
-       SK_TIMER                VctTimer;
-} SK_PNMI_VCT_TIMER;
-
-
-/*
- * PNMI specific adapter context structure
- */
-typedef struct s_PnmiPort {
-       SK_U64                  StatSyncCts;
-       SK_U64                  StatSyncOctetsCts;
-       SK_U64                  StatRxLongFrameCts;
-       SK_U64                  StatRxFrameTooLongCts;
-       SK_U64                  StatRxPMaccErr;
-       SK_U64                  TxSwQueueLen;
-       SK_U64                  TxSwQueueMax;
-       SK_U64                  TxRetryCts;
-       SK_U64                  RxIntrCts;
-       SK_U64                  TxIntrCts;
-       SK_U64                  RxNoBufCts;
-       SK_U64                  TxNoBufCts;
-       SK_U64                  TxUsedDescrNo;
-       SK_U64                  RxDeliveredCts;
-       SK_U64                  RxOctetsDeliveredCts;
-       SK_U64                  RxHwErrorsCts;
-       SK_U64                  TxHwErrorsCts;
-       SK_U64                  InErrorsCts;
-       SK_U64                  OutErrorsCts;
-       SK_U64                  ErrRecoveryCts;
-       SK_U64                  RxShortZeroMark;
-       SK_U64                  CounterOffset[SK_PNMI_CNT_NO];
-       SK_U32                  CounterHigh[SK_PNMI_CNT_NO];
-       SK_BOOL                 ActiveFlag;
-       SK_U8                   Align[3];
-} SK_PNMI_PORT;
-
-
-typedef struct s_PnmiData {
-       SK_PNMI_PORT    Port    [SK_MAX_MACS];
-       SK_PNMI_PORT    BufPort [SK_MAX_MACS]; /* 2002-09-13 pweber  */
-       SK_U64                  VirtualCounterOffset[SK_PNMI_CNT_NO];
-       SK_U32                  TestResult;
-       char                    HwVersion[10];
-       SK_U16                  Align01;
-
-       char                    *pDriverDescription;
-       char                    *pDriverVersion;
-
-       int                             MacUpdatedFlag;
-       int                             RlmtUpdatedFlag;
-       int                             SirqUpdatedFlag;
-
-       SK_U64                  RlmtChangeCts;
-       SK_U64                  RlmtChangeTime;
-       SK_PNMI_ESTIMATE        RlmtChangeEstimate;
-       SK_U64                  RlmtChangeThreshold;
-
-       SK_U64                  StartUpTime;
-       SK_U32                  DeviceType;
-       char                    PciBusSpeed;
-       char                    PciBusWidth;
-       char                    Chipset;
-       char                    PMD;
-       char                    Connector;
-       SK_BOOL                 DualNetActiveFlag;
-       SK_U16                  Align02;
-
-       char                    TrapBuf[SK_PNMI_TRAP_QUEUE_LEN];
-       unsigned int    TrapBufFree;
-       unsigned int    TrapQueueBeg;
-       unsigned int    TrapQueueEnd;
-       unsigned int    TrapBufPad;
-       unsigned int    TrapUnique;
-       SK_U8           VctStatus[SK_MAX_MACS];
-       SK_PNMI_VCT     VctBackup[SK_MAX_MACS];
-       SK_PNMI_VCT_TIMER VctTimeout[SK_MAX_MACS];
-} SK_PNMI;
-
-
-/*
- * Function prototypes
- */
-extern int SkPnmiInit(SK_AC *pAc, SK_IOC IoC, int level);
-extern int SkPnmiGetVar(SK_AC *pAc, SK_IOC IoC, SK_U32 Id, void* pBuf,
-       unsigned int* pLen, SK_U32 Instance, SK_U32 NetIndex);
-extern int SkPnmiPreSetVar(SK_AC *pAc, SK_IOC IoC, SK_U32 Id,
-       void* pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
-extern int SkPnmiSetVar(SK_AC *pAc, SK_IOC IoC, SK_U32 Id, void* pBuf,
-       unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
-extern int SkPnmiGetStruct(SK_AC *pAc, SK_IOC IoC, void* pBuf,
-       unsigned int *pLen, SK_U32 NetIndex);
-extern int SkPnmiPreSetStruct(SK_AC *pAc, SK_IOC IoC, void* pBuf,
-       unsigned int *pLen, SK_U32 NetIndex);
-extern int SkPnmiSetStruct(SK_AC *pAc, SK_IOC IoC, void* pBuf,
-       unsigned int *pLen, SK_U32 NetIndex);
-extern int SkPnmiEvent(SK_AC *pAc, SK_IOC IoC, SK_U32 Event,
-       SK_EVPARA Param);
-
-#endif
diff --git a/drivers/sk98lin/h/skgesirq.h b/drivers/sk98lin/h/skgesirq.h
deleted file mode 100644 (file)
index fc001b2..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/******************************************************************************
- *
- * Name:       skgesirq.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.26 $
- * Date:       $Date: 2002/10/14 09:52:36 $
- * Purpose:    SK specific Gigabit Ethernet special IRQ functions
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *     $Log: skgesirq.h,v $
- *     Revision 1.26  2002/10/14 09:52:36  rschmidt
- *     Added SKERR_SIRQ_E023 and SKERR_SIRQ_E023 for GPHY (Yukon)
- *     Editorial changes
- *
- *     Revision 1.25  2002/07/15 18:15:52  rwahl
- *     Editorial changes.
- *
- *     Revision 1.24  2002/07/15 15:39:21  rschmidt
- *     Corrected define for SKERR_SIRQ_E022
- *     Editorial changes
- *
- *     Revision 1.23  2002/04/25 11:09:45  rschmidt
- *     Removed declarations for SkXmInitPhy(), SkXmRxTxEnable()
- *     Editorial changes
- *
- *     Revision 1.22  2000/11/09 11:30:10  rassmann
- *     WA: Waiting after releasing reset until BCom chip is accessible.
- *
- *     Revision 1.21  2000/10/18 12:22:40  cgoos
- *     Added workaround for half duplex hangup.
- *
- *     Revision 1.20  1999/12/06 10:00:44  cgoos
- *     Added SET event for role.
- *
- *     Revision 1.19  1999/11/22 13:58:26  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.18  1999/05/19 07:32:59  cgoos
- *     Changes for 1000Base-T.
- *
- *     Revision 1.17  1999/03/12 13:29:31  malthoff
- *     Move Autonegotiation Error Codes to skgeinit.h.
- *
- *     Revision 1.16  1999/03/08 10:11:28  gklug
- *     add: AutoNegDone return codes
- *
- *     Revision 1.15  1998/11/18 13:20:53  gklug
- *     add: different timeouts for active and non-active links
- *
- *     Revision 1.14  1998/11/04 07:18:14  cgoos
- *     Added prototype for SkXmRxTxEnable.
- *
- *     Revision 1.13  1998/10/21 05:52:23  gklug
- *     add: parameter DoLoop to InitPhy function
- *
- *     Revision 1.12  1998/10/19 06:45:03  cgoos
- *     Added prototype for SkXmInitPhy.
- *
- *     Revision 1.11  1998/10/15 14:34:10  gklug
- *     add: WA_TIME is 500 msec
- *
- *     Revision 1.10  1998/10/14 14:49:41  malthoff
- *     Remove err log defines E021 and E022. They are
- *     defined in skgeinit.h now.
- *
- *     Revision 1.9  1998/10/14 14:00:39  gklug
- *     add: error logs for init phys
- *
- *     Revision 1.8  1998/10/14 05:44:05  gklug
- *     add: E020
- *
- *     Revision 1.7  1998/10/02 06:24:58  gklug
- *     add: error messages
- *
- *     Revision 1.6  1998/10/01 07:54:45  gklug
- *     add: PNMI debug module
- *
- *     Revision 1.5  1998/09/28 13:36:31  malthoff
- *     Move the bit definitions for Autonegotiation
- *     and Flow Control to skgeinit.h.
- *
- *     Revision 1.4  1998/09/15 12:29:34  gklug
- *     add: error logs
- *
- *     Revision 1.3  1998/09/03 13:54:02  gklug
- *     add: function prototypes
- *
- *     Revision 1.2  1998/09/03 10:24:36  gklug
- *     add: Events send by PNMI
- *     add: parameter definition for Flow Control etc.
- *
- *     Revision 1.1  1998/08/27 11:50:27  gklug
- *     initial revision
- *
- *
- ******************************************************************************/
-
-#ifndef _INC_SKGESIRQ_H_
-#define _INC_SKGESIRQ_H_
-
-/*
- * Define the Event the special IRQ/INI module can handle
- */
-#define SK_HWEV_WATIM                  1       /* Timeout for WA errata #2 XMAC */
-#define SK_HWEV_PORT_START             2       /* Port Start Event by RLMT */
-#define SK_HWEV_PORT_STOP              3       /* Port Stop Event by RLMT */
-#define SK_HWEV_CLEAR_STAT             4       /* Clear Statistics by PNMI */
-#define SK_HWEV_UPDATE_STAT            5       /* Update Statistics by PNMI */
-#define SK_HWEV_SET_LMODE              6       /* Set Link Mode by PNMI */
-#define SK_HWEV_SET_FLOWMODE   7       /* Set Flow Control Mode by PNMI */
-#define SK_HWEV_SET_ROLE               8       /* Set Master/Slave (Role) by PNMI */
-#define SK_HWEV_SET_SPEED              9       /* Set Link Speed by PNMI */
-#define SK_HWEV_HALFDUP_CHK            10      /* Half Duplex Hangup Workaround */
-
-#define SK_WA_ACT_TIME         (5000000L)      /* 5 sec */
-#define SK_WA_INA_TIME         (100000L)       /* 100 msec */
-
-#define SK_HALFDUP_CHK_TIME    (10000L)        /* 10 msec */
-
-/*
- * Define the error numbers and messages
- */
-#define SKERR_SIRQ_E001                (SK_ERRBASE_SIRQ+0)
-#define SKERR_SIRQ_E001MSG     "Unknown event"
-#define SKERR_SIRQ_E002                (SKERR_SIRQ_E001+1)
-#define SKERR_SIRQ_E002MSG     "Packet timeout RX1"
-#define SKERR_SIRQ_E003                (SKERR_SIRQ_E002+1)
-#define SKERR_SIRQ_E003MSG     "Packet timeout RX2"
-#define SKERR_SIRQ_E004                (SKERR_SIRQ_E003+1)
-#define SKERR_SIRQ_E004MSG     "MAC 1 not correctly initialized"
-#define SKERR_SIRQ_E005                (SKERR_SIRQ_E004+1)
-#define SKERR_SIRQ_E005MSG     "MAC 2 not correctly initialized"
-#define SKERR_SIRQ_E006                (SKERR_SIRQ_E005+1)
-#define SKERR_SIRQ_E006MSG     "CHECK failure R1"
-#define SKERR_SIRQ_E007                (SKERR_SIRQ_E006+1)
-#define SKERR_SIRQ_E007MSG     "CHECK failure R2"
-#define SKERR_SIRQ_E008                (SKERR_SIRQ_E007+1)
-#define SKERR_SIRQ_E008MSG     "CHECK failure XS1"
-#define SKERR_SIRQ_E009                (SKERR_SIRQ_E008+1)
-#define SKERR_SIRQ_E009MSG     "CHECK failure XA1"
-#define SKERR_SIRQ_E010                (SKERR_SIRQ_E009+1)
-#define SKERR_SIRQ_E010MSG     "CHECK failure XS2"
-#define SKERR_SIRQ_E011                (SKERR_SIRQ_E010+1)
-#define SKERR_SIRQ_E011MSG     "CHECK failure XA2"
-#define SKERR_SIRQ_E012                (SKERR_SIRQ_E011+1)
-#define SKERR_SIRQ_E012MSG     "unexpected IRQ Master error"
-#define SKERR_SIRQ_E013                (SKERR_SIRQ_E012+1)
-#define SKERR_SIRQ_E013MSG     "unexpected IRQ Status error"
-#define SKERR_SIRQ_E014                (SKERR_SIRQ_E013+1)
-#define SKERR_SIRQ_E014MSG     "Parity error on RAM (read)"
-#define SKERR_SIRQ_E015                (SKERR_SIRQ_E014+1)
-#define SKERR_SIRQ_E015MSG     "Parity error on RAM (write)"
-#define SKERR_SIRQ_E016                (SKERR_SIRQ_E015+1)
-#define SKERR_SIRQ_E016MSG     "Parity error MAC 1"
-#define SKERR_SIRQ_E017                (SKERR_SIRQ_E016+1)
-#define SKERR_SIRQ_E017MSG     "Parity error MAC 2"
-#define SKERR_SIRQ_E018                (SKERR_SIRQ_E017+1)
-#define SKERR_SIRQ_E018MSG     "Parity error RX 1"
-#define SKERR_SIRQ_E019                (SKERR_SIRQ_E018+1)
-#define SKERR_SIRQ_E019MSG     "Parity error RX 2"
-#define SKERR_SIRQ_E020                (SKERR_SIRQ_E019+1)
-#define SKERR_SIRQ_E020MSG     "MAC transmit FIFO underrun"
-#define SKERR_SIRQ_E021                (SKERR_SIRQ_E020+1)
-#define SKERR_SIRQ_E021MSG     "Spurious TWSI interrupt"
-#define SKERR_SIRQ_E022                (SKERR_SIRQ_E021+1)
-#define SKERR_SIRQ_E022MSG     "Cable pair swap error"
-#define SKERR_SIRQ_E023                (SKERR_SIRQ_E022+1)
-#define SKERR_SIRQ_E023MSG     "Auto-negotiation error"
-#define SKERR_SIRQ_E024                (SKERR_SIRQ_E023+1)
-#define SKERR_SIRQ_E024MSG     "FIFO overflow error"
-
-extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus);
-extern int  SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
-extern void SkHWLinkUp(SK_AC *pAC, SK_IOC IoC, int Port);
-extern void SkHWLinkDown(SK_AC *pAC, SK_IOC IoC, int Port);
-
-#endif /* _INC_SKGESIRQ_H_ */
diff --git a/drivers/sk98lin/h/ski2c.h b/drivers/sk98lin/h/ski2c.h
deleted file mode 100644 (file)
index 5ffaf6e..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-/******************************************************************************
- *
- * Name:       ski2c.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.34 $
- * Date:       $Date: 2003/01/28 09:11:21 $
- * Purpose:    Defines to access Voltage and Temperature Sensor
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: ski2c.h,v $
- *     Revision 1.34  2003/01/28 09:11:21  rschmidt
- *     Editorial changes
- *
- *     Revision 1.33  2002/10/14 16:40:50  rschmidt
- *     Editorial changes (TWSI)
- *
- *     Revision 1.32  2002/08/13 08:55:07  rschmidt
- *     Editorial changes
- *
- *     Revision 1.31  2002/08/06 09:44:22  jschmalz
- *     Extensions and changes for Yukon
- *
- *     Revision 1.30  2001/04/05 11:38:09  rassmann
- *     Set SenState to idle in SkI2cWaitIrq().
- *     Changed error message in SkI2cWaitIrq().
- *
- *     Revision 1.29  2000/08/03 14:28:17  rassmann
- *     - Added function to wait for I2C being ready before resetting the board.
- *     - Replaced one duplicate "out of range" message with correct one.
- *
- *     Revision 1.28  1999/11/22 13:55:46  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.27  1999/05/20 09:23:10  cgoos
- *     Changes for 1000Base-T (Fan sensors).
- *
- *     Revision 1.26  1998/12/01 13:45:47  gklug
- *     add: InitLevel to I2c struct
- *
- *     Revision 1.25  1998/11/03 06:55:16  gklug
- *     add: Dummy Reads to I2c struct
- *
- *     Revision 1.24  1998/10/02 14:28:59  cgoos
- *     Added prototype for SkI2cIsr.
- *
- *     Revision 1.23  1998/09/08 12:20:11  gklug
- *     add: prototypes for init and read functions
- *
- *     Revision 1.22  1998/09/08 07:37:56  gklug
- *     add: log error if PCI_IO voltage sensor could not be initialized
- *
- *     Revision 1.21  1998/09/04 08:38:05  malthoff
- *     Change the values for I2C_READ and I2C_WRITE
- *
- *     Revision 1.20  1998/08/25 07:52:22  gklug
- *     chg: Timestamps (last) added for logging
- *
- *     Revision 1.19  1998/08/25 06:09:00  gklug
- *     rmv: warning and error levels of the individual sensors.
- *     add: timing definitions for sending traps and logging errors
- *
- *     Revision 1.18  1998/08/20 11:41:15  gklug
- *     chg: omit STRCPY macro by using char * as Sensor Description
- *
- *     Revision 1.17  1998/08/20 11:37:43  gklug
- *     chg: change Ioc to IoC
- *
- *     Revision 1.16  1998/08/20 11:30:38  gklug
- *     fix: SenRead declaration
- *
- *     Revision 1.15  1998/08/20 11:27:53  gklug
- *     fix: Compile bugs with new awrning constants
- *
- *     Revision 1.14  1998/08/20 08:53:12  gklug
- *     fix: compiler errors
- *     add: Threshold values
- *
- *     Revision 1.13  1998/08/19 12:21:16  gklug
- *     fix: remove struct from C files (see CCC)
- *     add: typedefs for all structs
- *
- *     Revision 1.12  1998/08/19 10:57:41  gklug
- *     add: Warning levels
- *
- *     Revision 1.11  1998/08/18 08:37:02  malthoff
- *     Prototypes not required for SK_DIAG.
- *
- *     Revision 1.10  1998/08/17 13:54:00  gklug
- *     fix: declaration of event function
- *
- *     Revision 1.9  1998/08/17 06:48:39  malthoff
- *     Remove some unrequired macros.
- *     Fix the compiler errors.
- *
- *     Revision 1.8  1998/08/14 06:47:19  gklug
- *     fix: Values are intergers
- *
- *     Revision 1.7  1998/08/14 06:26:05  gklug
- *     add: Init error message
- *
- *     Revision 1.6  1998/08/13 08:31:08  gklug
- *     add: Error message
- *
- *     Revision 1.5  1998/08/12 14:32:04  gklug
- *     add: new error code/message
- *
- *     Revision 1.4  1998/08/12 13:39:08  gklug
- *     chg: names of error messages
- *     add: defines for Sensor type and thresholds
- *
- *     Revision 1.3  1998/08/11 07:57:16  gklug
- *     add: sensor struct
- *     add: Timeout defines
- *     add: I2C control struct for pAC
- *
- *     Revision 1.2  1998/07/17 11:29:02  gklug
- *     rmv: Microwire and SMTPANIC
- *
- *     Revision 1.1  1998/06/19 14:30:10  malthoff
- *     Created. Sources taken from ML Project.
- *
- *
- ******************************************************************************/
-
-/*
- * SKI2C.H     contains all I2C specific defines
- */
-
-#ifndef _SKI2C_H_
-#define _SKI2C_H_
-
-typedef struct  s_Sensor SK_SENSOR;
-
-#include "h/skgei2c.h"
-
-/*
- * Define the I2C events.
- */
-#define SK_I2CEV_IRQ   1       /* IRQ happened Event */
-#define SK_I2CEV_TIM   2       /* Timeout event */
-#define SK_I2CEV_CLEAR 3       /* Clear MIB Values */
-
-/*
- * Define READ and WRITE Constants.
- */
-#undef I2C_READ                /* just in case */
-#undef I2C_WRITE               /* just in case */
-#define I2C_READ       0
-#define I2C_WRITE      1
-#define I2C_BURST      1
-#define I2C_SINGLE     0
-
-#define SKERR_I2C_E001         (SK_ERRBASE_I2C+0)
-#define SKERR_I2C_E001MSG      "Sensor index unknown"
-#define SKERR_I2C_E002         (SKERR_I2C_E001+1)
-#define SKERR_I2C_E002MSG      "TWSI: transfer does not complete"
-#define SKERR_I2C_E003         (SKERR_I2C_E002+1)
-#define SKERR_I2C_E003MSG      "LM80: NAK on device send"
-#define SKERR_I2C_E004         (SKERR_I2C_E003+1)
-#define SKERR_I2C_E004MSG      "LM80: NAK on register send"
-#define SKERR_I2C_E005         (SKERR_I2C_E004+1)
-#define SKERR_I2C_E005MSG      "LM80: NAK on device (2) send"
-#define SKERR_I2C_E006         (SKERR_I2C_E005+1)
-#define SKERR_I2C_E006MSG      "Unknown event"
-#define SKERR_I2C_E007         (SKERR_I2C_E006+1)
-#define SKERR_I2C_E007MSG      "LM80 read out of state"
-#define SKERR_I2C_E008         (SKERR_I2C_E007+1)
-#define SKERR_I2C_E008MSG      "Unexpected sensor read completed"
-#define SKERR_I2C_E009         (SKERR_I2C_E008+1)
-#define SKERR_I2C_E009MSG      "WARNING: temperature sensor out of range"
-#define SKERR_I2C_E010         (SKERR_I2C_E009+1)
-#define SKERR_I2C_E010MSG      "WARNING: voltage sensor out of range"
-#define SKERR_I2C_E011         (SKERR_I2C_E010+1)
-#define SKERR_I2C_E011MSG      "ERROR: temperature sensor out of range"
-#define SKERR_I2C_E012         (SKERR_I2C_E011+1)
-#define SKERR_I2C_E012MSG      "ERROR: voltage sensor out of range"
-#define SKERR_I2C_E013         (SKERR_I2C_E012+1)
-#define SKERR_I2C_E013MSG      "ERROR: couldn't init sensor"
-#define SKERR_I2C_E014         (SKERR_I2C_E013+1)
-#define SKERR_I2C_E014MSG      "WARNING: fan sensor out of range"
-#define SKERR_I2C_E015         (SKERR_I2C_E014+1)
-#define SKERR_I2C_E015MSG      "ERROR: fan sensor out of range"
-#define SKERR_I2C_E016         (SKERR_I2C_E015+1)
-#define SKERR_I2C_E016MSG      "TWSI: active transfer does not complete"
-
-/*
- * Define Timeout values
- */
-#define SK_I2C_TIM_LONG                2000000L        /* 2 seconds */
-#define SK_I2C_TIM_SHORT        100000L        /* 100 milliseconds */
-#define SK_I2C_TIM_WATCH       1000000L        /* 1 second */
-
-/*
- * Define trap and error log hold times
- */
-#ifndef        SK_SEN_ERR_TR_HOLD
-#define SK_SEN_ERR_TR_HOLD             (4*SK_TICKS_PER_SEC)
-#endif
-#ifndef        SK_SEN_ERR_LOG_HOLD
-#define SK_SEN_ERR_LOG_HOLD            (60*SK_TICKS_PER_SEC)
-#endif
-#ifndef        SK_SEN_WARN_TR_HOLD
-#define SK_SEN_WARN_TR_HOLD            (15*SK_TICKS_PER_SEC)
-#endif
-#ifndef        SK_SEN_WARN_LOG_HOLD
-#define SK_SEN_WARN_LOG_HOLD   (15*60*SK_TICKS_PER_SEC)
-#endif
-
-/*
- * Defines for SenType
- */
-#define SK_SEN_UNKNOWN 0
-#define SK_SEN_TEMP            1
-#define SK_SEN_VOLT            2
-#define SK_SEN_FAN             3
-
-/*
- * Define for the SenErrorFlag
- */
-#define SK_SEN_ERR_NOT_PRESENT 0       /* Error Flag: Sensor not present */
-#define SK_SEN_ERR_OK                  1       /* Error Flag: O.K. */
-#define SK_SEN_ERR_WARN                        2       /* Error Flag: Warning */
-#define SK_SEN_ERR_ERR                 3       /* Error Flag: Error */
-#define SK_SEN_ERR_FAULTY              4       /* Error Flag: Faulty */
-
-/*
- * Define the Sensor struct
- */
-struct s_Sensor {
-       char    *SenDesc;                       /* Description */
-       int             SenType;                        /* Voltage or Temperature */
-       SK_I32  SenValue;                       /* Current value of the sensor */
-       SK_I32  SenThreErrHigh;         /* High error Threshhold of this sensor */
-       SK_I32  SenThreWarnHigh;        /* High warning Threshhold of this sensor */
-       SK_I32  SenThreErrLow;          /* Lower error Threshold of the sensor */
-       SK_I32  SenThreWarnLow;         /* Lower warning Threshold of the sensor */
-       int             SenErrFlag;                     /* Sensor indicated an error */
-       SK_BOOL SenInit;                        /* Is sensor initialized ? */
-       SK_U64  SenErrCts;                      /* Error  trap counter */
-       SK_U64  SenWarnCts;                     /* Warning trap counter */
-       SK_U64  SenBegErrTS;            /* Begin error timestamp */
-       SK_U64  SenBegWarnTS;           /* Begin warning timestamp */
-       SK_U64  SenLastErrTrapTS;       /* Last error trap timestamp */
-       SK_U64  SenLastErrLogTS;        /* Last error log timestamp */
-       SK_U64  SenLastWarnTrapTS;      /* Last warning trap timestamp */
-       SK_U64  SenLastWarnLogTS;       /* Last warning log timestamp */
-       int             SenState;                       /* Sensor State (see HW specific include) */
-       int             (*SenRead)(SK_AC *pAC, SK_IOC IoC, struct s_Sensor *pSen);
-                                                               /* Sensors read function */
-       SK_U16  SenReg;                         /* Register Address for this sensor */
-       SK_U8   SenDev;                         /* Device Selection for this sensor */
-};
-
-typedef        struct  s_I2c {
-       SK_SENSOR       SenTable[SK_MAX_SENSORS];       /* Sensor Table */
-       int                     CurrSens;       /* Which sensor is currently queried */
-       int                     MaxSens;        /* Max. number of sensors */
-       int                     TimerMode;      /* Use the timer also to watch the state machine */
-       int                     InitLevel;      /* Initialized Level */
-#ifndef SK_DIAG
-       int                     DummyReads;     /* Number of non-checked dummy reads */
-       SK_TIMER        SenTimer;       /* Sensors timer */
-#endif /* !SK_DIAG */
-} SK_I2C;
-
-extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
-#ifndef SK_DIAG
-extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
-extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level);
-extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC);
-extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC);
-
-#endif
-#endif /* n_SKI2C_H */
diff --git a/drivers/sk98lin/h/skqueue.h b/drivers/sk98lin/h/skqueue.h
deleted file mode 100644 (file)
index bce20a7..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/******************************************************************************
- *
- * Name:       skqueue.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.14 $
- * Date:       $Date: 2002/03/15 10:52:13 $
- * Purpose:    Defines for the Event queue
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998,1999 SysKonnect,
- *     a business unit of Schneider & Koch & Co. Datensysteme GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skqueue.h,v $
- *     Revision 1.14  2002/03/15 10:52:13  mkunz
- *     Added event classes for link aggregation
- *
- *     Revision 1.13  1999/11/22 13:59:05  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.12  1998/09/08 08:48:01  gklug
- *     add: init level handling
- *
- *     Revision 1.11  1998/09/03 14:15:11  gklug
- *     add: CSUM and HWAC Eventclass and function.
- *     fix: pParaPtr according to CCC
- *
- *     Revision 1.10  1998/08/20 12:43:03  gklug
- *     add: typedef SK_QUEUE
- *
- *     Revision 1.9  1998/08/19 09:50:59  gklug
- *     fix: remove struct keyword from c-code (see CCC) add typedefs
- *
- *     Revision 1.8  1998/08/18 07:00:01  gklug
- *     fix: SK_PTR not defined use void * instead.
- *
- *     Revision 1.7  1998/08/17 13:43:19  gklug
- *     chg: Parameter will be union of 64bit para, 2 times SK_U32 or SK_PTR
- *
- *     Revision 1.6  1998/08/14 07:09:30  gklug
- *     fix: chg pAc -> pAC
- *
- *     Revision 1.5  1998/08/11 14:26:44  gklug
- *     chg: Event Dispatcher returns now int.
- *
- *     Revision 1.4  1998/08/11 12:15:21  gklug
- *     add: Error numbers of skqueue module
- *
- *     Revision 1.3  1998/08/07 12:54:23  gklug
- *     fix: first compiled version
- *
- *     Revision 1.2  1998/08/07 09:34:00  gklug
- *     adapt structure defs to CCC
- *     add: prototypes for functions
- *
- *     Revision 1.1  1998/07/30 14:52:12  gklug
- *     Initial version.
- *     Defines Event Classes, Event structs and queue management variables.
- *
- *
- *
- ******************************************************************************/
-
-/*
- * SKQUEUE.H   contains all defines and types for the event queue
- */
-
-#ifndef _SKQUEUE_H_
-#define _SKQUEUE_H_
-
-
-/*
- * define the event classes to be served
- */
-#define        SKGE_DRV        1       /* Driver Event Class */
-#define        SKGE_RLMT       2       /* RLMT Event Class */
-#define        SKGE_I2C        3       /* i2C Event Class */
-#define        SKGE_PNMI       4       /* PNMI Event Class */
-#define        SKGE_CSUM       5       /* Checksum Event Class */
-#define        SKGE_HWAC       6       /* Hardware Access Event Class */
-
-#define        SKGE_SWT        9       /* Software Timer Event Class */
-#define        SKGE_LACP       10      /* LACP Aggregation Event Class */
-#define        SKGE_RSF        11      /* RSF Aggregation Event Class */
-#define        SKGE_MARKER     12      /* MARKER Aggregation Event Class */
-#define        SKGE_FD         13      /* FD Distributor Event Class */
-
-/*
- * define event queue as circular buffer
- */
-#define SK_MAX_EVENT   64
-
-/*
- * Parameter union for the Para stuff
- */
-typedef        union u_EvPara {
-       void    *pParaPtr;      /* Parameter Pointer */
-       SK_U64  Para64;         /* Parameter 64bit version */
-       SK_U32  Para32[2];      /* Parameter Array of 32bit parameters */
-} SK_EVPARA;
-
-/*
- * Event Queue
- *     skqueue.c
- * events are class/value pairs
- *     class   is addressee, e.g. RMT, PCM etc.
- *     value   is command, e.g. line state change, ring op change etc.
- */
-typedef        struct s_EventElem {
-       SK_U32          Class ;                 /* Event class */
-       SK_U32          Event ;                 /* Event value */
-       SK_EVPARA       Para ;                  /* Event parameter */
-} SK_EVENTELEM;
-
-typedef        struct s_Queue {
-       SK_EVENTELEM    EvQueue[SK_MAX_EVENT];
-       SK_EVENTELEM    *EvPut ;
-       SK_EVENTELEM    *EvGet ;
-} SK_QUEUE;
-
-extern void SkEventInit(SK_AC *pAC, SK_IOC Ioc, int Level);
-extern void SkEventQueue(SK_AC *pAC, SK_U32 Class, SK_U32 Event,
-       SK_EVPARA Para);
-extern int SkEventDispatcher(SK_AC *pAC,SK_IOC Ioc);
-
-
-/* Define Error Numbers and messages */
-#define        SKERR_Q_E001    (SK_ERRBASE_QUEUE+0)
-#define        SKERR_Q_E001MSG "Event queue overflow"
-#define        SKERR_Q_E002    (SKERR_Q_E001+1)
-#define        SKERR_Q_E002MSG "Undefined event class"
-#endif /* _SKQUEUE_H_ */
diff --git a/drivers/sk98lin/h/skrlmt.h b/drivers/sk98lin/h/skrlmt.h
deleted file mode 100644 (file)
index 04d025b..0000000
+++ /dev/null
@@ -1,563 +0,0 @@
-/******************************************************************************
- *
- * Name:       skrlmt.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.35 $
- * Date:       $Date: 2003/01/31 14:12:41 $
- * Purpose:    Header file for Redundant Link ManagemenT.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2001 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skrlmt.h,v $
- *     Revision 1.35  2003/01/31 14:12:41  mkunz
- *     single port adapter runs now with two identical MAC addresses
- *
- *     Revision 1.34  2002/09/23 15:13:41  rwahl
- *     Editorial changes.
- *
- *     Revision 1.33  2001/07/03 12:16:48  mkunz
- *     New Flag ChgBcPrio (Change priority of last broadcast received)
- *
- *     Revision 1.32  2001/02/14 14:06:31  rassmann
- *     Editorial changes.
- *
- *     Revision 1.31  2001/02/05 14:25:26  rassmann
- *     Prepared RLMT for transparent operation.
- *
- *     Revision 1.30  2001/01/22 13:41:39  rassmann
- *     Supporting two nets on dual-port adapters.
- *
- *     Revision 1.29  2000/11/17 08:58:00  rassmann
- *     Moved CheckSwitch from SK_RLMT_PACKET_RECEIVED to SK_RLMT_TIM event.
- *
- *     Revision 1.28  2000/11/09 12:24:34  rassmann
- *     Editorial changes.
- *
- *     Revision 1.27  1999/11/22 13:59:56  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.26  1999/10/04 14:01:19  rassmann
- *     Corrected reaction to reception of BPDU frames (#10441).
- *
- *     Revision 1.25  1999/07/20 12:53:39  rassmann
- *     Fixed documentation errors for lookahead macros.
- *
- *     Revision 1.24  1999/05/28 11:15:56  rassmann
- *     Changed behaviour to reflect Design Spec v1.2.
- *     Controlling Link LED(s).
- *     Introduced RLMT Packet Version field in RLMT Packet.
- *     Newstyle lookahead macros (checking meta-information before looking at
- *       the packet).
- *
- *     Revision 1.23  1999/01/28 12:50:42  rassmann
- *     Not using broadcast time stamps in CheckLinkState mode.
- *
- *     Revision 1.22  1999/01/27 14:13:04  rassmann
- *     Monitoring broadcast traffic.
- *     Switching more reliably and not too early if switch is
- *      configured for spanning tree.
- *
- *     Revision 1.21  1998/12/08 13:11:25  rassmann
- *     Stopping SegTimer at RlmtStop.
- *
- *     Revision 1.20  1998/11/24 12:37:33  rassmann
- *     Implemented segmentation check.
- *
- *     Revision 1.19  1998/11/17 13:43:06  rassmann
- *     Handling (logical) tx failure.
- *     Sending packet on logical address after PORT_SWITCH.
- *
- *     Revision 1.18  1998/11/13 16:56:56  rassmann
- *     Added macro version of SkRlmtLookaheadPacket.
- *
- *     Revision 1.17  1998/11/06 18:06:05  rassmann
- *     Corrected timing when RLMT checks fail.
- *     Clearing tx counter earlier in periodical checks.
- *
- *     Revision 1.16  1998/11/03 13:53:50  rassmann
- *     RLMT should switch now (at least in mode 3).
- *
- *     Revision 1.15  1998/10/22 11:39:52  rassmann
- *     Corrected signed/unsigned mismatches.
- *     Corrected receive list handling and address recognition.
- *
- *     Revision 1.14  1998/10/15 15:16:36  rassmann
- *     Finished Spanning Tree checking.
- *     Checked with lint.
- *
- *     Revision 1.13  1998/09/24 19:16:08  rassmann
- *     Code cleanup.
- *     Introduced Timer for PORT_DOWN due to no RX.
- *
- *     Revision 1.12  1998/09/16 11:09:52  rassmann
- *     Syntax corrections.
- *
- *     Revision 1.11  1998/09/15 11:28:50  rassmann
- *     Syntax corrections.
- *
- *     Revision 1.10  1998/09/14 17:07:38  rassmann
- *     Added code for port checking via LAN.
- *     Changed Mbuf definition.
- *
- *     Revision 1.9  1998/09/07 11:14:15  rassmann
- *     Syntax corrections.
- *
- *     Revision 1.8  1998/09/07 09:06:08  rassmann
- *     Syntax corrections.
- *
- *     Revision 1.7  1998/09/04 19:41:34  rassmann
- *     Syntax corrections.
- *     Started entering code for checking local links.
- *
- *     Revision 1.6  1998/09/04 12:14:28  rassmann
- *     Interface cleanup.
- *
- *     Revision 1.5  1998/09/02 16:55:29  rassmann
- *     Updated to reflect new DRV/HWAC/RLMT interface.
- *
- *     Revision 1.4  1998/09/02 07:26:02  afischer
- *     typedef for SK_RLMT_PORT
- *
- *     Revision 1.3  1998/08/27 14:29:03  rassmann
- *     Code cleanup.
- *
- *     Revision 1.2  1998/08/27 14:26:25  rassmann
- *     Updated interface.
- *
- *     Revision 1.1  1998/08/21 08:29:10  rassmann
- *     First public version.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This is the header file for Redundant Link ManagemenT.
- *
- * Include File Hierarchy:
- *
- *     "skdrv1st.h"
- *     ...
- *     "sktypes.h"
- *     "skqueue.h"
- *     "skaddr.h"
- *     "skrlmt.h"
- *     ...
- *     "skdrv2nd.h"
- *
- ******************************************************************************/
-
-#ifndef __INC_SKRLMT_H
-#define __INC_SKRLMT_H
-
-#ifdef __cplusplus
-#error C++ is not yet supported.
-extern "C" {
-#endif /* cplusplus */
-
-/* defines ********************************************************************/
-
-#define        SK_RLMT_NET_DOWN_TEMP   1       /* NET_DOWN due to last port down. */
-#define        SK_RLMT_NET_DOWN_FINAL  2       /* NET_DOWN due to RLMT_STOP. */
-
-/* ----- Default queue sizes - must be multiples of 8 KB ----- */
-
-/* Less than 8 KB free in RX queue => pause frames. */
-#define SK_RLMT_STANDBY_QRXSIZE        128     /* Size of rx standby queue in KB. */
-#define SK_RLMT_STANDBY_QXASIZE        32      /* Size of async standby queue in KB. */
-#define SK_RLMT_STANDBY_QXSSIZE        0       /* Size of sync standby queue in KB. */
-
-#define SK_RLMT_MAX_TX_BUF_SIZE        60      /* Maximum RLMT transmit size. */
-
-/* ----- PORT states ----- */
-
-#define SK_RLMT_PS_INIT                        0       /* Port state: Init. */
-#define SK_RLMT_PS_LINK_DOWN   1       /* Port state: Link down. */
-#define SK_RLMT_PS_DOWN                        2       /* Port state: Port down. */
-#define SK_RLMT_PS_GOING_UP            3       /* Port state: Going up. */
-#define SK_RLMT_PS_UP                  4       /* Port state: Up. */
-
-/* ----- RLMT states ----- */
-
-#define SK_RLMT_RS_INIT                        0       /* RLMT state: Init. */
-#define SK_RLMT_RS_NET_DOWN            1       /* RLMT state: Net down. */
-#define SK_RLMT_RS_NET_UP              2       /* RLMT state: Net up. */
-
-/* ----- PORT events ----- */
-
-#define SK_RLMT_LINK_UP                        1001    /* Link came up. */
-#define SK_RLMT_LINK_DOWN              1002    /* Link went down. */
-#define SK_RLMT_PORT_ADDR              1003    /* Port address changed. */
-
-/* ----- RLMT events ----- */
-
-#define SK_RLMT_START                  2001    /* Start RLMT. */
-#define SK_RLMT_STOP                   2002    /* Stop RLMT. */
-#define SK_RLMT_PACKET_RECEIVED        2003    /* Packet was received for RLMT. */
-#define SK_RLMT_STATS_CLEAR            2004    /* Clear statistics. */
-#define SK_RLMT_STATS_UPDATE   2005    /* Update statistics. */
-#define SK_RLMT_PREFPORT_CHANGE        2006    /* Change preferred port. */
-#define SK_RLMT_MODE_CHANGE            2007    /* New RlmtMode. */
-#define SK_RLMT_SET_NETS               2008    /* Number of Nets (1 or 2). */
-
-/* ----- RLMT mode bits ----- */
-
-/*
- * CAUTION:    These defines are private to RLMT.
- *                     Please use the RLMT mode defines below.
- */
-
-#define SK_RLMT_CHECK_LINK               1             /* Check Link. */
-#define SK_RLMT_CHECK_LOC_LINK   2             /* Check other link on same adapter. */
-#define SK_RLMT_CHECK_SEG                4             /* Check segmentation. */
-
-#ifndef RLMT_CHECK_REMOTE
-#define SK_RLMT_CHECK_OTHERS   SK_RLMT_CHECK_LOC_LINK
-#else  /* RLMT_CHECK_REMOTE */
-#define SK_RLMT_CHECK_REM_LINK   8             /* Check link(s) on other adapter(s). */
-#define SK_RLMT_MAX_REMOTE_PORTS_CHECKED       3
-#define SK_RLMT_CHECK_OTHERS   \
-               (SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
-#endif /* RLMT_CHECK_REMOTE */
-
-#ifndef SK_RLMT_ENABLE_TRANSPARENT
-#define SK_RLMT_TRANSPARENT              0             /* RLMT transparent - inactive. */
-#else  /* SK_RLMT_ENABLE_TRANSPARENT */
-#define SK_RLMT_TRANSPARENT            128             /* RLMT transparent. */
-#endif /* SK_RLMT_ENABLE_TRANSPARENT */
-
-/* ----- RLMT modes ----- */
-
-/* Check Link State. */
-#define SK_RLMT_MODE_CLS       (SK_RLMT_CHECK_LINK)
-
-/* Check Local Ports: check other links on the same adapter. */
-#define SK_RLMT_MODE_CLP       (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK)
-
-/* Check Local Ports and Segmentation Status. */
-#define SK_RLMT_MODE_CLPSS     \
-               (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_SEG)
-
-#ifdef RLMT_CHECK_REMOTE
-/* Check Local and Remote Ports: check links (local or remote). */
-       Name of define TBD!
-#define SK_RLMT_MODE_CRP       \
-               (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
-
-/* Check Local and Remote Ports and Segmentation Status. */
-       Name of define TBD!
-#define SK_RLMT_MODE_CRPSS     \
-               (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | \
-               SK_RLMT_CHECK_REM_LINK | SK_RLMT_CHECK_SEG)
-#endif /* RLMT_CHECK_REMOTE */
-
-/* ----- RLMT lookahead result bits ----- */
-
-#define SK_RLMT_RX_RLMT                        1       /* Give packet to RLMT. */
-#define SK_RLMT_RX_PROTOCOL            2       /* Give packet to protocol. */
-
-/* Macros */
-
-#if 0
-SK_AC          *pAC            /* adapter context */
-SK_U32         PortNum         /* receiving port */
-unsigned       PktLen          /* received packet's length */
-SK_BOOL                IsBc            /* Flag: packet is broadcast */
-unsigned       *pOffset        /* offs. of bytes to present to SK_RLMT_LOOKAHEAD */
-unsigned       *pNumBytes      /* #Bytes to present to SK_RLMT_LOOKAHEAD */
-#endif /* 0 */
-
-#define SK_RLMT_PRE_LOOKAHEAD(pAC,PortNum,PktLen,IsBc,pOffset,pNumBytes) { \
-       SK_AC   *_pAC; \
-       SK_U32  _PortNum; \
-       _pAC = (pAC); \
-       _PortNum = (SK_U32)(PortNum); \
-       /* _pAC->Rlmt.Port[_PortNum].PacketsRx++; */ \
-       _pAC->Rlmt.Port[_PortNum].PacketsPerTimeSlot++; \
-    if (_pAC->Rlmt.RlmtOff) { \
-               *(pNumBytes) = 0; \
-    } \
-    else {\
-       if ((_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_TRANSPARENT) != 0) { \
-               *(pNumBytes) = 0; \
-       } \
-       else if (IsBc) { \
-               if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode != SK_RLMT_MODE_CLS) { \
-                       *(pNumBytes) = 6; \
-                       *(pOffset) = 6; \
-               } \
-               else { \
-                       *(pNumBytes) = 0; \
-               } \
-       } \
-       else { \
-               if ((PktLen) > SK_RLMT_MAX_TX_BUF_SIZE) { \
-                       /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
-                       *(pNumBytes) = 0; \
-               } \
-               else { \
-                       *(pNumBytes) = 6; \
-                       *(pOffset) = 0; \
-               } \
-       } \
-    } \
-}
-
-#if 0
-SK_AC          *pAC            /* adapter context */
-SK_U32         PortNum         /* receiving port */
-SK_U8          *pLaPacket,     /* received packet's data (points to pOffset) */
-SK_BOOL                IsBc            /* Flag: packet is broadcast */
-SK_BOOL                IsMc            /* Flag: packet is multicast */
-unsigned       *pForRlmt       /* Result: bits SK_RLMT_RX_RLMT, SK_RLMT_RX_PROTOCOL */
-SK_RLMT_LOOKAHEAD() expects *pNumBytes from
-packet offset *pOffset (s.a.) at *pLaPacket.
-
-If you use SK_RLMT_LOOKAHEAD in a path where you already know if the packet is
-BC, MC, or UC, you should use constants for IsBc and IsMc, so that your compiler
-can trash unneeded parts of the if construction.
-#endif /* 0 */
-
-#define SK_RLMT_LOOKAHEAD(pAC,PortNum,pLaPacket,IsBc,IsMc,pForRlmt) { \
-       SK_AC   *_pAC; \
-       SK_U32  _PortNum; \
-       SK_U8   *_pLaPacket; \
-       _pAC = (pAC); \
-       _PortNum = (SK_U32)(PortNum); \
-       _pLaPacket = (SK_U8 *)(pLaPacket); \
-       if (IsBc) {\
-               if (!SK_ADDR_EQUAL(_pLaPacket, _pAC->Addr.Net[_pAC->Rlmt.Port[ \
-                       _PortNum].Net->NetNumber].CurrentMacAddress.a)) { \
-                       _pAC->Rlmt.Port[_PortNum].BcTimeStamp = SkOsGetTime(_pAC); \
-                       _pAC->Rlmt.CheckSwitch = SK_TRUE; \
-               } \
-               /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
-               *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
-       } \
-       else if (IsMc) { \
-               if (SK_ADDR_EQUAL(_pLaPacket, BridgeMcAddr.a)) { \
-                       _pAC->Rlmt.Port[_PortNum].BpduPacketsPerTimeSlot++; \
-                       if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_CHECK_SEG) { \
-                               *(pForRlmt) = SK_RLMT_RX_RLMT | SK_RLMT_RX_PROTOCOL; \
-                       } \
-                       else { \
-                               *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
-                       } \
-               } \
-               else if (SK_ADDR_EQUAL(_pLaPacket, SkRlmtMcAddr.a)) { \
-                       *(pForRlmt) = SK_RLMT_RX_RLMT; \
-               } \
-               else { \
-                       /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
-                       *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
-               } \
-       } \
-       else { \
-               if (SK_ADDR_EQUAL( \
-                       _pLaPacket, \
-                       _pAC->Addr.Port[_PortNum].CurrentMacAddress.a)) { \
-                       *(pForRlmt) = SK_RLMT_RX_RLMT; \
-               } \
-               else { \
-                       /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
-                       *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
-               } \
-       } \
-}
-
-#ifdef SK_RLMT_FAST_LOOKAHEAD
-Error: SK_RLMT_FAST_LOOKAHEAD no longer used. Use new macros for lookahead.
-#endif /* SK_RLMT_FAST_LOOKAHEAD */
-#ifdef SK_RLMT_SLOW_LOOKAHEAD
-Error: SK_RLMT_SLOW_LOOKAHEAD no longer used. Use new macros for lookahead.
-#endif /* SK_RLMT_SLOW_LOOKAHEAD */
-
-/* typedefs *******************************************************************/
-
-#ifdef SK_RLMT_MBUF_PRIVATE
-typedef struct s_RlmtMbuf {
-       some content
-} SK_RLMT_MBUF;
-#endif /* SK_RLMT_MBUF_PRIVATE */
-
-
-#ifdef SK_LA_INFO
-typedef struct s_Rlmt_PacketInfo {
-       unsigned        PacketLength;                   /* Length of packet. */
-       unsigned        PacketType;                             /* Directed/Multicast/Broadcast. */
-} SK_RLMT_PINFO;
-#endif /* SK_LA_INFO */
-
-
-typedef struct s_RootId {
-       SK_U8           Id[8];                                  /* Root Bridge Id. */
-} SK_RLMT_ROOT_ID;
-
-
-typedef struct s_port {
-       SK_MAC_ADDR     CheckAddr;
-       SK_BOOL         SuspectTx;
-} SK_PORT_CHECK;
-
-
-typedef struct s_RlmtNet SK_RLMT_NET;
-
-
-typedef struct s_RlmtPort {
-
-/* ----- Public part (read-only) ----- */
-
-       SK_U8                   PortState;                              /* Current state of this port. */
-
-       /* For PNMI */
-       SK_BOOL                 LinkDown;
-       SK_BOOL                 PortDown;
-       SK_U8                   Align01;
-
-       SK_U32                  PortNumber;                             /* Number of port on adapter. */
-       SK_RLMT_NET *   Net;                                    /* Net port belongs to. */
-
-       SK_U64                  TxHelloCts;
-       SK_U64                  RxHelloCts;
-       SK_U64                  TxSpHelloReqCts;
-       SK_U64                  RxSpHelloCts;
-
-/* ----- Private part ----- */
-
-/*     SK_U64                  PacketsRx; */                           /* Total packets received. */
-       SK_U32                  PacketsPerTimeSlot;             /* Packets rxed between TOs. */
-/*     SK_U32                  DataPacketsPerTimeSlot; */      /* Data packets ... */
-       SK_U32                  BpduPacketsPerTimeSlot; /* BPDU packets rxed in TS. */
-       SK_U64                  BcTimeStamp;                    /* Time of last BC receive. */
-       SK_U64                  GuTimeStamp;                    /* Time of entering GOING_UP. */
-
-       SK_TIMER                UpTimer;                                /* Timer struct Link/Port up. */
-       SK_TIMER                DownRxTimer;                    /* Timer struct down rx. */
-       SK_TIMER                DownTxTimer;                    /* Timer struct down tx. */
-
-       SK_U32                  CheckingState;                  /* Checking State. */
-
-       SK_ADDR_PORT *  AddrPort;
-
-       SK_U8                   Random[4];                              /* Random value. */
-       unsigned                PortsChecked;                   /* #ports checked. */
-       unsigned                PortsSuspect;                   /* #ports checked that are s. */
-       SK_PORT_CHECK   PortCheck[1];
-/*     SK_PORT_CHECK   PortCheck[SK_MAX_MACS - 1]; */
-
-       SK_BOOL                 PortStarted;                    /* Port is started. */
-       SK_BOOL                 PortNoRx;                               /* NoRx for >= 1 time slot. */
-       SK_BOOL                 RootIdSet;
-       SK_RLMT_ROOT_ID Root;                                   /* Root Bridge Id. */
-} SK_RLMT_PORT;
-
-
-struct s_RlmtNet {
-
-/* ----- Public part (read-only) ----- */
-
-       SK_U32                  NetNumber;                      /* Number of net. */
-
-       SK_RLMT_PORT *  Port[SK_MAX_MACS];      /* Ports that belong to this net. */
-       SK_U32                  NumPorts;                       /* Number of ports. */
-       SK_U32                  PrefPort;                       /* Preferred port. */
-
-       /* For PNMI */
-
-       SK_U32                  ChgBcPrio;                      /* Change Priority of last broadcast received */
-       SK_U32                  RlmtMode;                       /* Check ... */
-       SK_U32                  ActivePort;                     /* Active port. */
-       SK_U32                  Preference;             /* 0xFFFFFFFF: Automatic. */
-
-       SK_U8                   RlmtState;                      /* Current RLMT state. */
-
-/* ----- Private part ----- */
-       SK_BOOL                 RootIdSet;
-       SK_U16                  Align01;
-
-       int                             LinksUp;                        /* #Links up. */
-       int                             PortsUp;                        /* #Ports up. */
-       SK_U32                  TimeoutValue;           /* RLMT timeout value. */
-
-       SK_U32                  CheckingState;          /* Checking State. */
-       SK_RLMT_ROOT_ID Root;                           /* Root Bridge Id. */
-
-       SK_TIMER                LocTimer;                       /* Timer struct. */
-       SK_TIMER                SegTimer;                       /* Timer struct. */
-};
-
-
-typedef struct s_Rlmt {
-
-/* ----- Public part (read-only) ----- */
-
-       SK_U32                  NumNets;                        /* Number of nets. */
-       SK_U32                  NetsStarted;            /* Number of nets started. */
-       SK_RLMT_NET             Net[SK_MAX_NETS];       /* Array of available nets. */
-       SK_RLMT_PORT    Port[SK_MAX_MACS];      /* Array of available ports. */
-
-/* ----- Private part ----- */
-       SK_BOOL                 CheckSwitch;
-       SK_BOOL                 RlmtOff;            /* set to zero if the Mac addresses
-                                          are equal or the second one
-                                          is zero */
-       SK_U16                  Align01;
-
-} SK_RLMT;
-
-
-extern SK_MAC_ADDR     BridgeMcAddr;
-extern SK_MAC_ADDR     SkRlmtMcAddr;
-
-/* function prototypes ********************************************************/
-
-
-#ifndef SK_KR_PROTO
-
-/* Functions provided by SkRlmt */
-
-/* ANSI/C++ compliant function prototypes */
-
-extern void    SkRlmtInit(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Level);
-
-extern int     SkRlmtEvent(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       SK_U32          Event,
-       SK_EVPARA       Para);
-
-#else  /* defined(SK_KR_PROTO) */
-
-/* Non-ANSI/C++ compliant function prototypes */
-
-#error KR-style function prototypes are not yet provided.
-
-#endif /* defined(SK_KR_PROTO)) */
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_SKRLMT_H */
diff --git a/drivers/sk98lin/h/sktimer.h b/drivers/sk98lin/h/sktimer.h
deleted file mode 100644 (file)
index 36f8ccb..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/******************************************************************************
- *
- * Name:       sktimer.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.9 $
- * Date:       $Date: 1999/11/22 14:00:29 $
- * Purpose:    Defines for the timer functions
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998,1999 SysKonnect,
- *     a business unit of Schneider & Koch & Co. Datensysteme GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: sktimer.h,v $
- *     Revision 1.9  1999/11/22 14:00:29  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.8  1998/09/08 08:48:02  gklug
- *     add: init level handling
- *
- *     Revision 1.7  1998/08/20 12:31:29  gklug
- *     fix: SK_TIMCTRL needs to be defined
- *
- *     Revision 1.6  1998/08/19 09:51:00  gklug
- *     fix: remove struct keyword from c-code (see CCC) add typedefs
- *
- *     Revision 1.5  1998/08/17 13:43:21  gklug
- *     chg: Parameter will be union of 64bit para, 2 times SK_U32 or SK_PTR
- *
- *     Revision 1.4  1998/08/14 07:09:31  gklug
- *     fix: chg pAc -> pAC
- *
- *     Revision 1.3  1998/08/07 12:54:24  gklug
- *     fix: first compiled version
- *
- *     Revision 1.2  1998/08/07 09:35:29  gklug
- *     add: Timer control struct for Adapters context
- *     add: function prototypes
- *
- *     Revision 1.1  1998/08/05 11:27:01  gklug
- *     First version: adapted from SMT
- *
- *
- ******************************************************************************/
-
-/*
- * SKTIMER.H   contains all defines and types for the timer functions
- */
-
-#ifndef        _SKTIMER_H_
-#define _SKTIMER_H_
-
-#include "h/skqueue.h"
-
-/*
- * SK timer
- * - needed wherever a timer is used. Put this in your data structure
- *   wherever you want.
- */
-typedef        struct s_Timer SK_TIMER;
-
-struct s_Timer {
-       SK_TIMER        *TmNext ;       /* linked list */
-       SK_U32          TmClass ;       /* Timer Event class */
-       SK_U32          TmEvent ;       /* Timer Event value */
-       SK_EVPARA       TmPara ;        /* Timer Event parameter */
-       SK_U32          TmDelta ;       /* delta time */
-       int             TmActive ;      /* flag : active/inactive */
-} ;
-
-/*
- * Timer control struct.
- * - use in Adapters context name pAC->Tim
- */
-typedef        struct s_TimCtrl {
-       SK_TIMER        *StQueue ;      /* Head of Timer queue */
-} SK_TIMCTRL ;
-
-extern void SkTimerInit(SK_AC *pAC,SK_IOC Ioc, int Level);
-extern void SkTimerStop(SK_AC *pAC,SK_IOC Ioc,SK_TIMER *pTimer);
-extern void SkTimerStart(SK_AC *pAC,SK_IOC Ioc,SK_TIMER *pTimer,
-       SK_U32 Time,SK_U32 Class,SK_U32 Event,SK_EVPARA Para);
-extern void SkTimerDone(SK_AC *pAC,SK_IOC Ioc);
-#endif /* _SKTIMER_H_ */
diff --git a/drivers/sk98lin/h/sktypes.h b/drivers/sk98lin/h/sktypes.h
deleted file mode 100644 (file)
index e657016..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/******************************************************************************
- *
- * Name:       sktypes.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.3 $
- * Date:       $Date: 2003/02/25 14:16:40 $
- * Purpose:    Define data types for Linux
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
- /*****************************************************************************
- *
- * History:
- *
- *     $Log: sktypes.h,v $
- *     Revision 1.3  2003/02/25 14:16:40  mlindner
- *     Fix: Copyright statement
- *
- *     Revision 1.2  1999/11/22 14:01:58  cgoos
- *     Changed license header to GPL.
- *     Now using Linux' fixed size types instead of standard types.
- *
- *     Revision 1.1  1999/02/16 07:41:40  cgoos
- *     First version.
- *
- *
- *
- *****************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * In this file, all data types that are needed by the common modules
- * are mapped to Linux data types.
- *
- *
- * Include File Hierarchy:
- *
- *
- ******************************************************************************/
-
-#ifndef __INC_SKTYPES_H
-#define __INC_SKTYPES_H
-
-
-/* defines *******************************************************************/
-
-/*
- * Data types with a specific size. 'I' = signed, 'U' = unsigned.
- */
-#define SK_I8  s8
-#define SK_U8  u8
-#define SK_I16 s16
-#define SK_U16 u16
-#define SK_I32 s32
-#define SK_U32 u32
-#define SK_I64 s64
-#define SK_U64 u64
-
-#define SK_UPTR        ulong           /* casting pointer <-> integral */
-
-/*
-* Boolean type.
-*/
-#define SK_BOOL                SK_U8
-#define SK_FALSE       0
-#define SK_TRUE                (!SK_FALSE)
-
-/* typedefs *******************************************************************/
-
-/* function prototypes ********************************************************/
-
-#endif /* __INC_SKTYPES_H */
diff --git a/drivers/sk98lin/h/skversion.h b/drivers/sk98lin/h/skversion.h
deleted file mode 100644 (file)
index ef46685..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/******************************************************************************
- *
- * Name:       version.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.4 $
- * Date:       $Date: 2003/02/25 14:16:40 $
- * Purpose:    SK specific Error log support
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *     $Log: skversion.h,v $
- *     Revision 1.4  2003/02/25 14:16:40  mlindner
- *     Fix: Copyright statement
- *
- *     Revision 1.3  2003/02/25 13:30:18  mlindner
- *     Add: Support for various vendors
- *
- *     Revision 1.1.2.1  2001/09/05 13:38:30  mlindner
- *     Removed FILE description
- *
- *     Revision 1.1  2001/03/06 09:25:00  mlindner
- *     first version
- *
- *
- *
- ******************************************************************************/
-
-
-static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH.";
-static const char SysKonnectBuildNumber[] =
-       "@(#)SK-BUILD: 6.05 PL: 01";
-
-#define BOOT_STRING    "sk98lin: Network Device Driver v6.05\n" \
-                       "(C)Copyright 1999-2003 Marvell(R)."
-
-#define VER_STRING     "6.05"
diff --git a/drivers/sk98lin/h/skvpd.h b/drivers/sk98lin/h/skvpd.h
deleted file mode 100644 (file)
index 1be34c5..0000000
+++ /dev/null
@@ -1,335 +0,0 @@
-/******************************************************************************
- *
- * Name:       skvpd.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.15 $
- * Date:       $Date: 2003/01/13 10:39:38 $
- * Purpose:    Defines and Macros for VPD handling
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skvpd.h,v $
- *     Revision 1.15  2003/01/13 10:39:38  rschmidt
- *     Replaced define for PCI device Id for YUKON with GENESIS
- *     Editorial changes
- *
- *     Revision 1.14  2002/11/14 15:18:10  gheinig
- *     Added const specifier to key and buf parameters for VpdPara,VpdRead
- *     and VpdWrite. This is necessary for the Diag 7 GUI API
- *
- *     Revision 1.13  2002/10/14 15:58:18  rschmidt
- *     Added entry in rom_size struct s_vpd
- *     Editorial changes
- *
- *     Revision 1.12  2002/09/09 14:43:51  mkarl
- *     added PCI Id of Yukon for reading VPD in diag before the adapter has
- *     been initialized
- *     editorial changes
- *
- *     Revision 1.11  2002/07/26 13:19:16  mkarl
- *     added support for Yukon
- *     added vpd_size to VPD struct
- *
- *     Revision 1.10  2000/08/10 11:29:07  rassmann
- *     Editorial changes.
- *     Preserving 32-bit alignment in structs for the adapter context.
- *     Removed unused function VpdWriteDword() (#if 0).
- *     Made VpdReadKeyword() available for SKDIAG only.
- *
- *     Revision 1.9  1999/11/22 14:02:27  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.8  1999/03/11 14:26:40  malthoff
- *     Replace __STDC__ with SK_KR_PROTO.
- *
- *     Revision 1.7  1998/10/28 07:27:17  gklug
- *     rmv: SWAP macros
- *     add: VPD_IN/OUT8 macros
- *     chg: interface definition
- *
- *     Revision 1.6  1998/10/22 10:03:44  gklug
- *     fix: use SK_OUT16 instead of SK_OUTW
- *
- *     Revision 1.5  1998/10/14 07:05:31  cgoos
- *     Changed constants in SK_SWAP_32 to UL.
- *
- *     Revision 1.4  1998/08/19 08:14:09  gklug
- *     fix: remove struct keyword as much as possible from the C-code (see CCC)
- *
- *     Revision 1.3  1998/08/18 08:18:56  malthoff
- *     Modify VPD in and out macros for SK_DIAG
- *
- *     Revision 1.2  1998/07/03 14:49:08  malthoff
- *     Add VPD_INxx() and VPD_OUTxx() macros for the Diagnostics tool.
- *
- *     Revision 1.1  1998/06/19 14:08:03  malthoff
- *     Created.
- *
- *
- ******************************************************************************/
-
-/*
- * skvpd.h     contains Diagnostic specific defines for VPD handling
- */
-
-#ifndef __INC_SKVPD_H_
-#define __INC_SKVPD_H_
-
-/*
- * Define Resource Type Identifiers and VPD keywords
- */
-#define        RES_ID          0x82    /* Resource Type ID String (Product Name) */
-#define RES_VPD_R      0x90    /* start of VPD read only area */
-#define RES_VPD_W      0x91    /* start of VPD read/write area */
-#define RES_END                0x78    /* Resource Type End Tag */
-
-#ifndef VPD_NAME
-#define VPD_NAME       "Name"  /* Product Name, VPD name of RES_ID */
-#endif /* VPD_NAME */
-#define VPD_PN         "PN"    /* Adapter Part Number */
-#define        VPD_EC          "EC"    /* Adapter Engineering Level */
-#define VPD_MN         "MN"    /* Manufacture ID */
-#define VPD_SN         "SN"    /* Serial Number */
-#define VPD_CP         "CP"    /* Extended Capability */
-#define VPD_RV         "RV"    /* Checksum and Reserved */
-#define        VPD_YA          "YA"    /* Asset Tag Identifier */
-#define VPD_VL         "VL"    /* First Error Log Message (SK specific) */
-#define VPD_VF         "VF"    /* Second Error Log Message (SK specific) */
-#define VPD_RW         "RW"    /* Remaining Read / Write Area */
-
-/* 'type' values for vpd_setup_para() */
-#define VPD_RO_KEY     1       /* RO keys are "PN", "EC", "MN", "SN", "RV" */
-#define VPD_RW_KEY     2       /* RW keys are "Yx", "Vx", and "RW" */
-
-/* 'op' values for vpd_setup_para() */
-#define        ADD_KEY         1       /* add the key at the pos "RV" or "RW" */
-#define OWR_KEY                2       /* overwrite key if already exists */
-
-/*
- * Define READ and WRITE Constants.
- */
-
-#define VPD_DEV_ID_GENESIS     0x4300
-
-#define        VPD_SIZE_YUKON          256
-#define        VPD_SIZE_GENESIS        512
-#define        VPD_SIZE                        512
-#define VPD_READ       0x0000
-#define VPD_WRITE      0x8000
-
-#define VPD_STOP(pAC,IoC)      VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG,VPD_WRITE)
-
-#define VPD_GET_RES_LEN(p)     ((unsigned int) \
-                                       (* (SK_U8 *)&(p)[1]) |\
-                                       ((* (SK_U8 *)&(p)[2]) << 8))
-#define VPD_GET_VPD_LEN(p)     ((unsigned int)(* (SK_U8 *)&(p)[2]))
-#define VPD_GET_VAL(p)         ((char *)&(p)[3])
-
-#define VPD_MAX_LEN    50
-
-/* VPD status */
-       /* bit 7..1 reserved */
-#define VPD_VALID      (1<<0)  /* VPD data buffer, vpd_free_ro, */
-                                                       /* and vpd_free_rw valid         */
-
-/*
- * VPD structs
- */
-typedef        struct s_vpd_status {
-       unsigned short  Align01;                        /* Alignment */
-       unsigned short  vpd_status;                     /* VPD status, description see above */
-       int                             vpd_free_ro;            /* unused bytes in read only area */
-       int                             vpd_free_rw;            /* bytes available in read/write area */
-} SK_VPD_STATUS;
-
-typedef        struct s_vpd {
-       SK_VPD_STATUS   v;                                      /* VPD status structure */
-       char                    vpd_buf[VPD_SIZE];      /* VPD buffer */
-       int                             rom_size;                       /* VPD ROM Size from PCI_OUR_REG_2 */
-       int                             vpd_size;                       /* saved VPD-size */
-} SK_VPD;
-
-typedef        struct s_vpd_para {
-       unsigned int    p_len;  /* parameter length */
-       char                    *p_val; /* points to the value */
-} SK_VPD_PARA;
-
-/*
- * structure of Large Resource Type Identifiers
- */
-
-/* was removed because of alignment problems */
-
-/*
- * structure of VPD keywords
- */
-typedef        struct s_vpd_key {
-       char                    p_key[2];       /* 2 bytes ID string */
-       unsigned char   p_len;          /* 1 byte length */
-       char                    p_val;          /* start of the value string */
-} SK_VPD_KEY;
-
-
-/*
- * System specific VPD macros
- */
-#ifndef SKDIAG
-#ifndef VPD_DO_IO
-#define VPD_OUT8(pAC,IoC,Addr,Val)     (void)SkPciWriteCfgByte(pAC,Addr,Val)
-#define VPD_OUT16(pAC,IoC,Addr,Val)    (void)SkPciWriteCfgWord(pAC,Addr,Val)
-#define VPD_OUT32(pAC,IoC,Addr,Val)    (void)SkPciWriteCfgDWord(pAC,Addr,Val)
-#define VPD_IN8(pAC,IoC,Addr,pVal)     (void)SkPciReadCfgByte(pAC,Addr,pVal)
-#define VPD_IN16(pAC,IoC,Addr,pVal)    (void)SkPciReadCfgWord(pAC,Addr,pVal)
-#define VPD_IN32(pAC,IoC,Addr,pVal)    (void)SkPciReadCfgDWord(pAC,Addr,pVal)
-#else  /* VPD_DO_IO */
-#define VPD_OUT8(pAC,IoC,Addr,Val)     SK_OUT8(IoC,PCI_C(Addr),Val)
-#define VPD_OUT16(pAC,IoC,Addr,Val)    SK_OUT16(IoC,PCI_C(Addr),Val)
-#define VPD_OUT32(pAC,IoC,Addr,Val)    SK_OUT32(IoC,PCI_C(Addr),Val)
-#define VPD_IN8(pAC,IoC,Addr,pVal)     SK_IN8(IoC,PCI_C(Addr),pVal)
-#define VPD_IN16(pAC,IoC,Addr,pVal)    SK_IN16(IoC,PCI_C(Addr),pVal)
-#define VPD_IN32(pAC,IoC,Addr,pVal)    SK_IN32(IoC,PCI_C(Addr),pVal)
-#endif /* VPD_DO_IO */
-#else  /* SKDIAG */
-#define VPD_OUT8(pAC,Ioc,Addr,Val) {                   \
-               if ((pAC)->DgT.DgUseCfgCycle)                   \
-                       SkPciWriteCfgByte(pAC,Addr,Val);        \
-               else                                                                    \
-                       SK_OUT8(pAC,PCI_C(Addr),Val);           \
-               }
-#define VPD_OUT16(pAC,Ioc,Addr,Val) {                  \
-               if ((pAC)->DgT.DgUseCfgCycle)                   \
-                       SkPciWriteCfgWord(pAC,Addr,Val);        \
-               else                                            \
-                       SK_OUT16(pAC,PCI_C(Addr),Val);          \
-               }
-#define VPD_OUT32(pAC,Ioc,Addr,Val) {                  \
-               if ((pAC)->DgT.DgUseCfgCycle)                   \
-                       SkPciWriteCfgDWord(pAC,Addr,Val);       \
-               else                                            \
-                       SK_OUT32(pAC,PCI_C(Addr),Val);          \
-               }
-#define VPD_IN8(pAC,Ioc,Addr,pVal) {                   \
-               if ((pAC)->DgT.DgUseCfgCycle)                   \
-                       SkPciReadCfgByte(pAC,Addr,pVal);        \
-               else                                            \
-                       SK_IN8(pAC,PCI_C(Addr),pVal);           \
-               }
-#define VPD_IN16(pAC,Ioc,Addr,pVal) {                  \
-               if ((pAC)->DgT.DgUseCfgCycle)                   \
-                       SkPciReadCfgWord(pAC,Addr,pVal);        \
-               else                                            \
-                       SK_IN16(pAC,PCI_C(Addr),pVal);          \
-               }
-#define VPD_IN32(pAC,Ioc,Addr,pVal) {                  \
-               if ((pAC)->DgT.DgUseCfgCycle)                   \
-                       SkPciReadCfgDWord(pAC,Addr,pVal);       \
-               else                                            \
-                       SK_IN32(pAC,PCI_C(Addr),pVal);          \
-               }
-#endif /* nSKDIAG */
-
-/* function prototypes ********************************************************/
-
-#ifndef        SK_KR_PROTO
-#ifdef SKDIAG
-extern SK_U32  VpdReadDWord(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       int                     addr);
-#endif /* SKDIAG */
-
-extern int     VpdSetupPara(
-       SK_AC           *pAC,
-       const char      *key,
-       const char      *buf,
-       int                     len,
-       int                     type,
-       int                     op);
-
-extern SK_VPD_STATUS   *VpdStat(
-       SK_AC           *pAC,
-       SK_IOC          IoC);
-
-extern int     VpdKeys(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       char            *buf,
-       int                     *len,
-       int                     *elements);
-
-extern int     VpdRead(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       const char      *key,
-       char            *buf,
-       int                     *len);
-
-extern SK_BOOL VpdMayWrite(
-       char            *key);
-
-extern int     VpdWrite(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       const char      *key,
-       const char      *buf);
-
-extern int     VpdDelete(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       char            *key);
-
-extern int     VpdUpdate(
-       SK_AC           *pAC,
-       SK_IOC          IoC);
-
-extern void    VpdErrLog(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       char            *msg);
-
-#ifdef SKDIAG
-extern int     VpdReadBlock(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       char            *buf,
-       int                     addr,
-       int                     len);
-
-extern int     VpdWriteBlock(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       char            *buf,
-       int                     addr,
-       int                     len);
-#endif /* SKDIAG */
-#else  /* SK_KR_PROTO */
-extern SK_U32  VpdReadDWord();
-extern int     VpdSetupPara();
-extern SK_VPD_STATUS   *VpdStat();
-extern int     VpdKeys();
-extern int     VpdRead();
-extern SK_BOOL VpdMayWrite();
-extern int     VpdWrite();
-extern int     VpdDelete();
-extern int     VpdUpdate();
-extern void    VpdErrLog();
-#endif /* SK_KR_PROTO */
-
-#endif /* __INC_SKVPD_H_ */
diff --git a/drivers/sk98lin/h/xmac_ii.h b/drivers/sk98lin/h/xmac_ii.h
deleted file mode 100644 (file)
index 2ef903a..0000000
+++ /dev/null
@@ -1,1738 +0,0 @@
-/******************************************************************************
- *
- * Name:       xmac_ii.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.46 $
- * Date:       $Date: 2003/01/28 09:47:45 $
- * Purpose:    Defines and Macros for Gigabit Ethernet Controller
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: xmac_ii.h,v $
- *     Revision 1.46  2003/01/28 09:47:45  rschmidt
- *     Added defines for copper MDI/MDIX configuration
- *     Added defines for LED Control Register
- *     Editorial changes
- *
- *     Revision 1.45  2002/12/10 14:35:13  rschmidt
- *     Corrected defines for Extended PHY Specific Control
- *     Added defines for Ext. PHY Specific Ctrl 2 Reg. (Fiber specific)
- *
- *     Revision 1.44  2002/12/09 14:58:41  rschmidt
- *     Added defines for Ext. PHY Specific Ctrl Reg. (downshift feature)
- *     Added 'GMR_FS_UN_SIZE'-Bit to Rx GMAC FIFO Flush Mask
- *
- *     Revision 1.43  2002/12/05 10:14:45  rschmidt
- *     Added define for GMAC's Half Duplex Burst Mode
- *     Added define for Rx GMAC FIFO Flush Mask (default)
- *
- *     Revision 1.42  2002/11/12 16:48:19  rschmidt
- *     Added defines for Cable Diagnostic Register (GPHY)
- *     Editorial changes
- *
- *     Revision 1.41  2002/10/21 11:20:22  rschmidt
- *     Added bit GMR_FS_GOOD_FC to GMR_FS_ANY_ERR
- *     Editorial changes
- *
- *     Revision 1.40  2002/10/14 14:54:14  rschmidt
- *     Added defines for GPHY Specific Status and GPHY Interrupt Status
- *     Added bits PHY_M_IS_AN_ERROR and PHY_M_IS_FIFO_ERROR to PHY_M_DEF_MSK
- *     Editorial changes
- *
- *     Revision 1.39  2002/10/10 15:53:44  mkarl
- *     added some bit definitions for link speed status and LED's
- *
- *     Revision 1.38  2002/08/21 16:23:46  rschmidt
- *     Added defines for PHY Specific Ctrl Reg
- *     Editorial changes
- *
- *     Revision 1.37  2002/08/16 14:50:33  rschmidt
- *     Added defines for Auto-Neg. Advertisement YUKON Fiber (88E1011S only)
- *     Changed define PHY_M_DEF_MSK for GPHY IRQ Mask
- *     Editorial changes
- *
- *     Revision 1.36  2002/08/12 13:21:10  rschmidt
- *     Added defines for different Broadcom PHY Ids
- *
- *     Revision 1.35  2002/08/08 15:58:01  rschmidt
- *     Added defines for Manual LED Override register (YUKON)
- *     Editorial changes
- *
- *     Revision 1.34  2002/07/31 17:23:36  rwahl
- *     Added define GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR).
- *
- *     Revision 1.33  2002/07/23 16:03:37  rschmidt
- *     Added defines for GPHY registers
- *     Editorial changes
- *
- *     Revision 1.32  2002/07/15 18:14:37  rwahl
- *     Added GMAC MIB counters definitions.
- *     Editorial changes.
- *
- *     Revision 1.31  2002/07/15 15:42:50  rschmidt
- *     Removed defines from PHY specific reg. which are
- *     common to all PHYs
- *     Added defines for GMAC MIB Counters
- *     Editorial changes
- *
- *     Revision 1.30  2002/06/05 08:22:12  rschmidt
- *     Changed defines for GMAC Rx Control Register and Rx Status
- *     Editorial changes
- *
- *     Revision 1.29  2002/04/25 11:43:56  rschmidt
- *     Added define PHY_B_AS_PAUSE_MSK for BCom Pause Res.
- *     Added new registers and defines for YUKON (GMAC, GPHY)
- *     Added Receive Frame Status Encoding for YUKON
- *     Editorial changes
- *
- *     Revision 1.28  2000/11/09 12:32:49  rassmann
- *     Renamed variables.
- *
- *     Revision 1.27  2000/05/17 11:00:46  malthoff
- *     Add bit for enable/disable power management in BCOM chip.
- *
- *     Revision 1.26  1999/11/22 14:03:00  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.25  1999/08/12 19:19:38  malthoff
- *     Add PHY_B_AC_TX_TST bit according to BCOM A1 errata sheet.
- *
- *     Revision 1.24  1999/07/30 11:27:21  cgoos
- *     Fixed a missing end-of-comment.
- *
- *     Revision 1.23  1999/07/30 07:03:31  malthoff
- *     Cut some long comments.
- *     Correct the XMAC PHY ID definitions.
- *
- *     Revision 1.22  1999/05/19 07:33:18  cgoos
- *     Changes for 1000Base-T.
- *
- *     Revision 1.21  1999/03/25 07:46:11  malthoff
- *     Add XM_HW_CFG, XM_TS_READ, and XM_TS_LOAD registers.
- *
- *     Revision 1.20  1999/03/12 13:36:09  malthoff
- *     Remove __STDC__.
- *
- *     Revision 1.19  1998/12/10 12:22:54  gklug
- *     fix: RX_PAGE must be in interrupt mask
- *
- *     Revision 1.18  1998/12/10 10:36:36  gklug
- *     fix: swap of pause bits
- *
- *     Revision 1.17  1998/11/18 13:21:45  gklug
- *     fix: Default interrupt mask
- *
- *     Revision 1.16  1998/10/29 15:53:21  gklug
- *     fix: Default mask uses ASS (GP0) signal
- *
- *     Revision 1.15  1998/10/28 13:52:52  malthoff
- *     Add new bits in RX_CMD register.
- *
- *     Revision 1.14  1998/10/19 15:34:53  gklug
- *     fix: typos
- *
- *     Revision 1.13  1998/10/14 07:19:03  malthoff
- *     bug fix: Every define which describes bit 31
- *     must be declared as unsigned long 'UL'.
- *     fix bit definitions of PHY_AN_RFB and PHY_AN_PAUSE.
- *     Remove ANP defines. Rework the RFB defines.
- *
- *     Revision 1.12  1998/10/14 06:22:44  cgoos
- *     Changed shifted constant to ULONG.
- *
- *     Revision 1.11  1998/10/14 05:43:26  gklug
- *     add: shift pause coding
- *     fix: PAUSE bits definition
- *
- *     Revision 1.10  1998/10/13 09:19:21  malthoff
- *     Again change XMR_FS_ANY_ERR because of new info from XaQti.
- *
- *     Revision 1.9  1998/10/09 07:58:30  malthoff
- *     Add XMR_FS_FCS_ERR to XMR_FS_ANY_ERR.
- *
- *     Revision 1.8  1998/10/09 07:18:17  malthoff
- *     bug fix of a bug fix: XM_PAUSE_MODE and XM_DEF_MODE
- *     are not inverted! Bug XM_DEF_MSK is inverted.
- *
- *     Revision 1.7  1998/10/05 08:04:32  malthoff
- *     bug fix: XM_PAUSE_MODE and XM_DEF_MODE
- *     must be inverted declarations.
- *
- *     Revision 1.6  1998/09/28 13:38:18  malthoff
- *     Add default modes and masks XM_DEF_MSK,
- *     XM_PAUSE_MODE and XM_DEF_MODE
- *
- *     Revision 1.5  1998/09/16 14:42:04  malthoff
- *     Bug Fix: XM_GP_PORT is a 32 bit (not a 16 bit) register.
- *
- *     Revision 1.4  1998/08/20 14:59:47  malthoff
- *     Rework this file after reading the XaQti data sheet
- *     "Differences between Rev. B2 & Rev. C XMAC II".
- *     This file is now 100% XMAC II Rev. C complained.
- *
- *     Revision 1.3  1998/06/29 12:18:23  malthoff
- *     Correct XMR_FS_ANY_ERR definition.
- *
- *     Revision 1.2  1998/06/29 12:10:56  malthoff
- *     Add define XMR_FS_ANY_ERR.
- *
- *     Revision 1.1  1998/06/19 13:37:17  malthoff
- *     created.
- *
- *
- ******************************************************************************/
-
-#ifndef __INC_XMAC_H
-#define __INC_XMAC_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* defines ********************************************************************/
-
-/*
- * XMAC II registers
- *
- * The XMAC registers are 16 or 32 bits wide.
- * The XMACs host processor interface is set to 16 bit mode,
- * therefore ALL registers will be addressed with 16 bit accesses.
- *
- * The following macros are provided to access the XMAC registers
- * XM_IN16(), XM_OUT16, XM_IN32(), XM_OUT32(), XM_INADR(), XM_OUTADR(),
- * XM_INHASH(), and XM_OUTHASH().
- * The macros are defined in SkGeHw.h.
- *
- * Note:       NA reg  = Network Address e.g DA, SA etc.
- *
- */
-#define XM_MMU_CMD             0x0000  /* 16 bit r/w   MMU Command Register */
-       /* 0x0004:              reserved */
-#define XM_POFF                        0x0008  /* 32 bit r/w   Packet Offset Register */
-#define XM_BURST               0x000c  /* 32 bit r/w   Burst Register for half duplex*/
-#define XM_1L_VLAN_TAG 0x0010  /* 16 bit r/w   One Level VLAN Tag ID */
-#define XM_2L_VLAN_TAG 0x0014  /* 16 bit r/w   Two Level VLAN Tag ID */
-       /* 0x0018 - 0x001e:     reserved */
-#define XM_TX_CMD              0x0020  /* 16 bit r/w   Transmit Command Register */
-#define XM_TX_RT_LIM   0x0024  /* 16 bit r/w   Transmit Retry Limit Register */
-#define XM_TX_STIME            0x0028  /* 16 bit r/w   Transmit Slottime Register */
-#define XM_TX_IPG              0x002c  /* 16 bit r/w   Transmit Inter Packet Gap */
-#define XM_RX_CMD              0x0030  /* 16 bit r/w   Receive Command Register */
-#define XM_PHY_ADDR            0x0034  /* 16 bit r/w   PHY Address Register */
-#define XM_PHY_DATA            0x0038  /* 16 bit r/w   PHY Data Register */
-       /* 0x003c:              reserved */
-#define XM_GP_PORT             0x0040  /* 32 bit r/w   General Purpose Port Register */
-#define XM_IMSK                        0x0044  /* 16 bit r/w   Interrupt Mask Register */
-#define XM_ISRC                        0x0048  /* 16 bit r/o   Interrupt Status Register */
-#define XM_HW_CFG              0x004c  /* 16 bit r/w   Hardware Config Register */
-       /* 0x0050 - 0x005e:     reserved */
-#define XM_TX_LO_WM            0x0060  /* 16 bit r/w   Tx FIFO Low Water Mark */
-#define XM_TX_HI_WM            0x0062  /* 16 bit r/w   Tx FIFO High Water Mark */
-#define XM_TX_THR              0x0064  /* 16 bit r/w   Tx Request Threshold */
-#define XM_HT_THR              0x0066  /* 16 bit r/w   Host Request Threshold */
-#define XM_PAUSE_DA            0x0068  /* NA reg r/w   Pause Destination Address */
-       /* 0x006e:              reserved */
-#define XM_CTL_PARA            0x0070  /* 32 bit r/w   Control Parameter Register */
-#define XM_MAC_OPCODE  0x0074  /* 16 bit r/w   Opcode for MAC control frames */
-#define XM_MAC_PTIME   0x0076  /* 16 bit r/w   Pause time for MAC ctrl frames*/
-#define XM_TX_STAT             0x0078  /* 32 bit r/o   Tx Status LIFO Register */
-
-       /* 0x0080 - 0x00fc:     16 NA reg r/w   Exact Match Address Registers */
-       /*                              use the XM_EXM() macro to address */
-#define XM_EXM_START   0x0080  /* r/w  Start Address of the EXM Regs */
-
-       /*
-        * XM_EXM(Reg)
-        *
-        * returns the XMAC address offset of specified Exact Match Addr Reg
-        *
-        * para:        Reg     EXM register to addr    (0 .. 15)
-        *
-        * usage:       XM_INADDR(IoC, MAC_1, XM_EXM(i), &val[i]);
-        */
-#define XM_EXM(Reg)    (XM_EXM_START + ((Reg) << 3))
-
-#define XM_SRC_CHK             0x0100  /* NA reg r/w   Source Check Address Register */
-#define XM_SA                  0x0108  /* NA reg r/w   Station Address Register */
-#define XM_HSM                 0x0110  /* 64 bit r/w   Hash Match Address Registers */
-#define XM_RX_LO_WM            0x0118  /* 16 bit r/w   Receive Low Water Mark */
-#define XM_RX_HI_WM            0x011a  /* 16 bit r/w   Receive High Water Mark */
-#define XM_RX_THR              0x011c  /* 32 bit r/w   Receive Request Threshold */
-#define XM_DEV_ID              0x0120  /* 32 bit r/o   Device ID Register */
-#define XM_MODE                        0x0124  /* 32 bit r/w   Mode Register */
-#define XM_LSA                 0x0128  /* NA reg r/o   Last Source Register */
-       /* 0x012e:              reserved */
-#define XM_TS_READ             0x0130  /* 32 bit r/o   Time Stamp Read Register */
-#define XM_TS_LOAD             0x0134  /* 32 bit r/o   Time Stamp Load Value */
-       /* 0x0138 - 0x01fe:     reserved */
-#define XM_STAT_CMD    0x0200  /* 16 bit r/w   Statistics Command Register */
-#define XM_RX_CNT_EV   0x0204  /* 32 bit r/o   Rx Counter Event Register */
-#define XM_TX_CNT_EV   0x0208  /* 32 bit r/o   Tx Counter Event Register */
-#define XM_RX_EV_MSK   0x020c  /* 32 bit r/w   Rx Counter Event Mask */
-#define XM_TX_EV_MSK   0x0210  /* 32 bit r/w   Tx Counter Event Mask */
-       /* 0x0204 - 0x027e:     reserved */
-#define XM_TXF_OK              0x0280  /* 32 bit r/o   Frames Transmitted OK Conuter */
-#define XM_TXO_OK_HI   0x0284  /* 32 bit r/o   Octets Transmitted OK High Cnt*/
-#define XM_TXO_OK_LO   0x0288  /* 32 bit r/o   Octets Transmitted OK Low Cnt */
-#define XM_TXF_BC_OK   0x028c  /* 32 bit r/o   Broadcast Frames Xmitted OK */
-#define XM_TXF_MC_OK   0x0290  /* 32 bit r/o   Multicast Frames Xmitted OK */
-#define XM_TXF_UC_OK   0x0294  /* 32 bit r/o   Unicast Frames Xmitted OK */
-#define XM_TXF_LONG            0x0298  /* 32 bit r/o   Tx Long Frame Counter */
-#define XM_TXE_BURST   0x029c  /* 32 bit r/o   Tx Burst Event Counter */
-#define XM_TXF_MPAUSE  0x02a0  /* 32 bit r/o   Tx Pause MAC Ctrl Frame Cnt */
-#define XM_TXF_MCTRL   0x02a4  /* 32 bit r/o   Tx MAC Ctrl Frame Counter */
-#define XM_TXF_SNG_COL 0x02a8  /* 32 bit r/o   Tx Single Collision Counter */
-#define XM_TXF_MUL_COL 0x02ac  /* 32 bit r/o   Tx Multiple Collision Counter */
-#define XM_TXF_ABO_COL 0x02b0  /* 32 bit r/o   Tx aborted due to Exces. Col. */
-#define XM_TXF_LAT_COL 0x02b4  /* 32 bit r/o   Tx Late Collision Counter */
-#define XM_TXF_DEF             0x02b8  /* 32 bit r/o   Tx Deferred Frame Counter */
-#define XM_TXF_EX_DEF  0x02bc  /* 32 bit r/o   Tx Excessive Deferall Counter */
-#define XM_TXE_FIFO_UR 0x02c0  /* 32 bit r/o   Tx FIFO Underrun Event Cnt */
-#define XM_TXE_CS_ERR  0x02c4  /* 32 bit r/o   Tx Carrier Sense Error Cnt */
-#define XM_TXP_UTIL            0x02c8  /* 32 bit r/o   Tx Utilization in % */
-       /* 0x02cc - 0x02ce:     reserved */
-#define XM_TXF_64B             0x02d0  /* 32 bit r/o   64 Byte Tx Frame Counter */
-#define XM_TXF_127B            0x02d4  /* 32 bit r/o   65-127 Byte Tx Frame Counter */
-#define XM_TXF_255B            0x02d8  /* 32 bit r/o   128-255 Byte Tx Frame Counter */
-#define XM_TXF_511B            0x02dc  /* 32 bit r/o   256-511 Byte Tx Frame Counter */
-#define XM_TXF_1023B   0x02e0  /* 32 bit r/o   512-1023 Byte Tx Frame Counter*/
-#define XM_TXF_MAX_SZ  0x02e4  /* 32 bit r/o   1024-MaxSize Byte Tx Frame Cnt*/
-       /* 0x02e8 - 0x02fe:     reserved */
-#define XM_RXF_OK              0x0300  /* 32 bit r/o   Frames Received OK */
-#define XM_RXO_OK_HI   0x0304  /* 32 bit r/o   Octets Received OK High Cnt */
-#define XM_RXO_OK_LO   0x0308  /* 32 bit r/o   Octets Received OK Low Counter*/
-#define XM_RXF_BC_OK   0x030c  /* 32 bit r/o   Broadcast Frames Received OK */
-#define XM_RXF_MC_OK   0x0310  /* 32 bit r/o   Multicast Frames Received OK */
-#define XM_RXF_UC_OK   0x0314  /* 32 bit r/o   Unicast Frames Received OK */
-#define XM_RXF_MPAUSE  0x0318  /* 32 bit r/o   Rx Pause MAC Ctrl Frame Cnt */
-#define XM_RXF_MCTRL   0x031c  /* 32 bit r/o   Rx MAC Ctrl Frame Counter */
-#define XM_RXF_INV_MP  0x0320  /* 32 bit r/o   Rx invalid Pause Frame Cnt */
-#define XM_RXF_INV_MOC 0x0324  /* 32 bit r/o   Rx Frames with inv. MAC Opcode*/
-#define XM_RXE_BURST   0x0328  /* 32 bit r/o   Rx Burst Event Counter */
-#define XM_RXE_FMISS   0x032c  /* 32 bit r/o   Rx Missed Frames Event Cnt */
-#define XM_RXF_FRA_ERR 0x0330  /* 32 bit r/o   Rx Framing Error Counter */
-#define XM_RXE_FIFO_OV 0x0334  /* 32 bit r/o   Rx FIFO overflow Event Cnt */
-#define XM_RXF_JAB_PKT 0x0338  /* 32 bit r/o   Rx Jabber Packet Frame Cnt */
-#define XM_RXE_CAR_ERR 0x033c  /* 32 bit r/o   Rx Carrier Event Error Cnt */
-#define XM_RXF_LEN_ERR 0x0340  /* 32 bit r/o   Rx in Range Length Error */
-#define XM_RXE_SYM_ERR 0x0344  /* 32 bit r/o   Rx Symbol Error Counter */
-#define XM_RXE_SHT_ERR 0x0348  /* 32 bit r/o   Rx Short Event Error Cnt */
-#define XM_RXE_RUNT            0x034c  /* 32 bit r/o   Rx Runt Event Counter */
-#define XM_RXF_LNG_ERR 0x0350  /* 32 bit r/o   Rx Frame too Long Error Cnt */
-#define XM_RXF_FCS_ERR 0x0354  /* 32 bit r/o   Rx Frame Check Seq. Error Cnt */
-       /* 0x0358 - 0x035a:     reserved */
-#define XM_RXF_CEX_ERR 0x035c  /* 32 bit r/o   Rx Carrier Ext Error Frame Cnt*/
-#define XM_RXP_UTIL            0x0360  /* 32 bit r/o   Rx Utilization in % */
-       /* 0x0364 - 0x0366:     reserved */
-#define XM_RXF_64B             0x0368  /* 32 bit r/o   64 Byte Rx Frame Counter */
-#define XM_RXF_127B            0x036c  /* 32 bit r/o   65-127 Byte Rx Frame Counter */
-#define XM_RXF_255B            0x0370  /* 32 bit r/o   128-255 Byte Rx Frame Counter */
-#define XM_RXF_511B            0x0374  /* 32 bit r/o   256-511 Byte Rx Frame Counter */
-#define XM_RXF_1023B   0x0378  /* 32 bit r/o   512-1023 Byte Rx Frame Counter*/
-#define XM_RXF_MAX_SZ  0x037c  /* 32 bit r/o   1024-MaxSize Byte Rx Frame Cnt*/
-       /* 0x02e8 - 0x02fe:     reserved */
-
-
-/*----------------------------------------------------------------------------*/
-/*
- * XMAC Bit Definitions
- *
- * If the bit access behaviour differs from the register access behaviour
- * (r/w, r/o) this is documented after the bit number.
- * The following bit access behaviours are used:
- *     (sc)    self clearing
- *     (ro)    read only
- */
-
-/*     XM_MMU_CMD      16 bit r/w      MMU Command Register */
-                                                               /* Bit 15..13:  reserved */
-#define XM_MMU_PHY_RDY (1<<12) /* Bit 12:      PHY Read Ready */
-#define XM_MMU_PHY_BUSY        (1<<11) /* Bit 11:      PHY Busy */
-#define XM_MMU_IGN_PF  (1<<10) /* Bit 10:      Ignore Pause Frame */
-#define XM_MMU_MAC_LB  (1<<9)  /* Bit  9:      Enable MAC Loopback */
-                                                               /* Bit  8:      reserved */
-#define XM_MMU_FRC_COL (1<<7)  /* Bit  7:      Force Collision */
-#define XM_MMU_SIM_COL (1<<6)  /* Bit  6:      Simulate Collision */
-#define XM_MMU_NO_PRE  (1<<5)  /* Bit  5:      No MDIO Preamble */
-#define XM_MMU_GMII_FD (1<<4)  /* Bit  4:      GMII uses Full Duplex */
-#define XM_MMU_RAT_CTRL        (1<<3)  /* Bit  3:      Enable Rate Control */
-#define XM_MMU_GMII_LOOP (1<<2)        /* Bit  2:      PHY is in Loopback Mode */
-#define XM_MMU_ENA_RX  (1<<1)  /* Bit  1:      Enable Receiver */
-#define XM_MMU_ENA_TX  (1<<0)  /* Bit  0:      Enable Transmitter */
-
-
-/*     XM_TX_CMD       16 bit r/w      Transmit Command Register */
-                                                               /* Bit 15..7:   reserved */
-#define XM_TX_BK2BK            (1<<6)  /* Bit  6:      Ignor Carrier Sense (Tx Bk2Bk)*/
-#define XM_TX_ENC_BYP  (1<<5)  /* Bit  5:      Set Encoder in Bypass Mode */
-#define XM_TX_SAM_LINE (1<<4)  /* Bit  4: (sc) Start utilization calculation */
-#define XM_TX_NO_GIG_MD        (1<<3)  /* Bit  3:      Disable Carrier Extension */
-#define XM_TX_NO_PRE   (1<<2)  /* Bit  2:      Disable Preamble Generation */
-#define XM_TX_NO_CRC   (1<<1)  /* Bit  1:      Disable CRC Generation */
-#define XM_TX_AUTO_PAD (1<<0)  /* Bit  0:      Enable Automatic Padding */
-
-
-/*     XM_TX_RT_LIM    16 bit r/w      Transmit Retry Limit Register */
-                                                               /* Bit 15..5:   reserved */
-#define XM_RT_LIM_MSK  0x1f    /* Bit  4..0:   Tx Retry Limit */
-
-
-/*     XM_TX_STIME     16 bit r/w      Transmit Slottime Register */
-                                                               /* Bit 15..7:   reserved */
-#define XM_STIME_MSK   0x7f    /* Bit  6..0:   Tx Slottime bits */
-
-
-/*     XM_TX_IPG       16 bit r/w      Transmit Inter Packet Gap */
-                                                               /* Bit 15..8:   reserved */
-#define XM_IPG_MSK             0xff    /* Bit  7..0:   IPG value bits */
-
-
-/*     XM_RX_CMD       16 bit r/w      Receive Command Register */
-                                                               /* Bit 15..9:   reserved */
-#define XM_RX_LENERR_OK (1<<8) /* Bit  8       don't set Rx Err bit for */
-                                                               /*              inrange error packets */
-#define XM_RX_BIG_PK_OK        (1<<7)  /* Bit  7       don't set Rx Err bit for */
-                                                               /*              jumbo packets */
-#define XM_RX_IPG_CAP  (1<<6)  /* Bit  6       repl. type field with IPG */
-#define XM_RX_TP_MD            (1<<5)  /* Bit  5:      Enable transparent Mode */
-#define XM_RX_STRIP_FCS        (1<<4)  /* Bit  4:      Enable FCS Stripping */
-#define XM_RX_SELF_RX  (1<<3)  /* Bit  3:      Enable Rx of own packets */
-#define XM_RX_SAM_LINE (1<<2)  /* Bit  2: (sc) Start utilization calculation */
-#define XM_RX_STRIP_PAD        (1<<1)  /* Bit  1:      Strip pad bytes of Rx frames */
-#define XM_RX_DIS_CEXT (1<<0)  /* Bit  0:      Disable carrier ext. check */
-
-
-/*     XM_PHY_ADDR     16 bit r/w      PHY Address Register */
-                                                               /* Bit 15..5:   reserved */
-#define XM_PHY_ADDR_SZ 0x1f    /* Bit  4..0:   PHY Address bits */
-
-
-/*     XM_GP_PORT      32 bit r/w      General Purpose Port Register */
-                                                               /* Bit 31..7:   reserved */
-#define XM_GP_ANIP             (1L<<6) /* Bit  6: (ro) Auto-Neg. in progress */
-#define XM_GP_FRC_INT  (1L<<5) /* Bit  5: (sc) Force Interrupt */
-                                                               /* Bit  4:      reserved */
-#define XM_GP_RES_MAC  (1L<<3) /* Bit  3: (sc) Reset MAC and FIFOs */
-#define XM_GP_RES_STAT (1L<<2) /* Bit  2: (sc) Reset the statistics module */
-                                                               /* Bit  1:      reserved */
-#define XM_GP_INP_ASS  (1L<<0) /* Bit  0: (ro) GP Input Pin asserted */
-
-
-/*     XM_IMSK         16 bit r/w      Interrupt Mask Register */
-/*     XM_ISRC         16 bit r/o      Interrupt Status Register */
-                                                               /* Bit 15:      reserved */
-#define XM_IS_LNK_AE   (1<<14) /* Bit 14:      Link Asynchronous Event */
-#define XM_IS_TX_ABORT (1<<13) /* Bit 13:      Transmit Abort, late Col. etc */
-#define XM_IS_FRC_INT  (1<<12) /* Bit 12:      Force INT bit set in GP */
-#define XM_IS_INP_ASS  (1<<11) /* Bit 11:      Input Asserted, GP bit 0 set */
-#define XM_IS_LIPA_RC  (1<<10) /* Bit 10:      Link Partner requests config */
-#define XM_IS_RX_PAGE  (1<<9)  /* Bit  9:      Page Received */
-#define XM_IS_TX_PAGE  (1<<8)  /* Bit  8:      Next Page Loaded for Transmit */
-#define XM_IS_AND              (1<<7)  /* Bit  7:      Auto-Negotiation Done */
-#define XM_IS_TSC_OV   (1<<6)  /* Bit  6:      Time Stamp Counter Overflow */
-#define XM_IS_RXC_OV   (1<<5)  /* Bit  5:      Rx Counter Event Overflow */
-#define XM_IS_TXC_OV   (1<<4)  /* Bit  4:      Tx Counter Event Overflow */
-#define XM_IS_RXF_OV   (1<<3)  /* Bit  3:      Receive FIFO Overflow */
-#define XM_IS_TXF_UR   (1<<2)  /* Bit  2:      Transmit FIFO Underrun */
-#define XM_IS_TX_COMP  (1<<1)  /* Bit  1:      Frame Tx Complete */
-#define XM_IS_RX_COMP  (1<<0)  /* Bit  0:      Frame Rx Complete */
-
-#define XM_DEF_MSK     (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE |\
-                       XM_IS_AND | XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_TXF_UR))
-
-
-/*     XM_HW_CFG       16 bit r/w      Hardware Config Register */
-                                                               /* Bit 15.. 4:  reserved */
-#define XM_HW_GEN_EOP  (1<<3)  /* Bit  3:      generate End of Packet pulse */
-#define XM_HW_COM4SIG  (1<<2)  /* Bit  2:      use Comma Detect for Sig. Det.*/
-                                                               /* Bit  1:      reserved */
-#define XM_HW_GMII_MD  (1<<0)  /* Bit  0:      GMII Interface selected */
-
-
-/*     XM_TX_LO_WM     16 bit r/w      Tx FIFO Low Water Mark */
-/*     XM_TX_HI_WM     16 bit r/w      Tx FIFO High Water Mark */
-                                                               /* Bit 15..10   reserved */
-#define XM_TX_WM_MSK   0x01ff  /* Bit  9.. 0   Tx FIFO Watermark bits */
-
-/*     XM_TX_THR       16 bit r/w      Tx Request Threshold */
-/*     XM_HT_THR       16 bit r/w      Host Request Threshold */
-/*     XM_RX_THR       16 bit r/w      Rx Request Threshold */
-                                                               /* Bit 15..11   reserved */
-#define XM_THR_MSK             0x03ff  /* Bit 10.. 0   Rx/Tx Request Threshold bits */
-
-
-/*     XM_TX_STAT      32 bit r/o      Tx Status LIFO Register */
-#define XM_ST_VALID            (1UL<<31)       /* Bit 31:      Status Valid */
-#define XM_ST_BYTE_CNT (0x3fffL<<17)   /* Bit 30..17:  Tx frame Length */
-#define XM_ST_RETRY_CNT        (0x1fL<<12)     /* Bit 16..12:  Retry Count */
-#define XM_ST_EX_COL   (1L<<11)        /* Bit 11:      Excessive Collisions */
-#define XM_ST_EX_DEF   (1L<<10)        /* Bit 10:      Excessive Deferral */
-#define XM_ST_BURST            (1L<<9)         /* Bit  9:      p. xmitted in burst md*/
-#define XM_ST_DEFER            (1L<<8)         /* Bit  8:      packet was defered */
-#define XM_ST_BC               (1L<<7)         /* Bit  7:      Broadcast packet */
-#define XM_ST_MC               (1L<<6)         /* Bit  6:      Multicast packet */
-#define XM_ST_UC               (1L<<5)         /* Bit  5:      Unicast packet */
-#define XM_ST_TX_UR            (1L<<4)         /* Bit  4:      FIFO Underrun occured */
-#define XM_ST_CS_ERR   (1L<<3)         /* Bit  3:      Carrier Sense Error */
-#define XM_ST_LAT_COL  (1L<<2)         /* Bit  2:      Late Collision Error */
-#define XM_ST_MUL_COL  (1L<<1)         /* Bit  1:      Multiple Collisions */
-#define XM_ST_SGN_COL  (1L<<0)         /* Bit  0:      Single Collision */
-
-/*     XM_RX_LO_WM     16 bit r/w      Receive Low Water Mark */
-/*     XM_RX_HI_WM     16 bit r/w      Receive High Water Mark */
-                                                                       /* Bit 15..11:  reserved */
-#define XM_RX_WM_MSK   0x03ff          /* Bit 11.. 0:  Rx FIFO Watermark bits */
-
-
-/*     XM_DEV_ID       32 bit r/o      Device ID Register */
-#define XM_DEV_OUI     (0x00ffffffUL<<8)       /* Bit 31..8:   Device OUI */
-#define XM_DEV_REV     (0x07L << 5)            /* Bit  7..5:   Chip Rev Num */
-
-
-/*     XM_MODE         32 bit r/w      Mode Register */
-                                                                       /* Bit 31..27:  reserved */
-#define XM_MD_ENA_REJ  (1L<<26)        /* Bit 26:      Enable Frame Reject */
-#define XM_MD_SPOE_E   (1L<<25)        /* Bit 25:      Send Pause on Edge */
-                                                                       /*              extern generated */
-#define XM_MD_TX_REP   (1L<<24)        /* Bit 24:      Transmit Repeater Mode */
-#define XM_MD_SPOFF_I  (1L<<23)        /* Bit 23:      Send Pause on FIFO full */
-                                                                       /*              intern generated */
-#define XM_MD_LE_STW   (1L<<22)        /* Bit 22:      Rx Stat Word in Little Endian */
-#define XM_MD_TX_CONT  (1L<<21)        /* Bit 21:      Send Continuous */
-#define XM_MD_TX_PAUSE (1L<<20)        /* Bit 20: (sc) Send Pause Frame */
-#define XM_MD_ATS              (1L<<19)        /* Bit 19:      Append Time Stamp */
-#define XM_MD_SPOL_I   (1L<<18)        /* Bit 18:      Send Pause on Low */
-                                                                       /*              intern generated */
-#define XM_MD_SPOH_I   (1L<<17)        /* Bit 17:      Send Pause on High */
-                                                                       /*              intern generated */
-#define XM_MD_CAP              (1L<<16)        /* Bit 16:      Check Address Pair */
-#define XM_MD_ENA_HASH (1L<<15)        /* Bit 15:      Enable Hashing */
-#define XM_MD_CSA              (1L<<14)        /* Bit 14:      Check Station Address */
-#define XM_MD_CAA              (1L<<13)        /* Bit 13:      Check Address Array */
-#define XM_MD_RX_MCTRL (1L<<12)        /* Bit 12:      Rx MAC Control Frame */
-#define XM_MD_RX_RUNT  (1L<<11)        /* Bit 11:      Rx Runt Frames */
-#define XM_MD_RX_IRLE  (1L<<10)        /* Bit 10:      Rx in Range Len Err Frame */
-#define XM_MD_RX_LONG  (1L<<9)         /* Bit  9:      Rx Long Frame */
-#define XM_MD_RX_CRCE  (1L<<8)         /* Bit  8:      Rx CRC Error Frame */
-#define XM_MD_RX_ERR   (1L<<7)         /* Bit  7:      Rx Error Frame */
-#define XM_MD_DIS_UC   (1L<<6)         /* Bit  6:      Disable Rx Unicast */
-#define XM_MD_DIS_MC   (1L<<5)         /* Bit  5:      Disable Rx Multicast */
-#define XM_MD_DIS_BC   (1L<<4)         /* Bit  4:      Disable Rx Broadcast */
-#define XM_MD_ENA_PROM (1L<<3)         /* Bit  3:      Enable Promiscuous */
-#define XM_MD_ENA_BE   (1L<<2)         /* Bit  2:      Enable Big Endian */
-#define XM_MD_FTF              (1L<<1)         /* Bit  1: (sc) Flush Tx FIFO */
-#define XM_MD_FRF              (1L<<0)         /* Bit  0: (sc) Flush Rx FIFO */
-
-#define XM_PAUSE_MODE  (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I)
-#define XM_DEF_MODE            (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
-                               XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA)
-
-/*     XM_STAT_CMD     16 bit r/w      Statistics Command Register */
-                                                               /* Bit 16..6:   reserved */
-#define XM_SC_SNP_RXC  (1<<5)  /* Bit  5: (sc) Snap Rx Counters */
-#define XM_SC_SNP_TXC  (1<<4)  /* Bit  4: (sc) Snap Tx Counters */
-#define XM_SC_CP_RXC   (1<<3)  /* Bit  3:      Copy Rx Counters Continuously */
-#define XM_SC_CP_TXC   (1<<2)  /* Bit  2:      Copy Tx Counters Continuously */
-#define XM_SC_CLR_RXC  (1<<1)  /* Bit  1: (sc) Clear Rx Counters */
-#define XM_SC_CLR_TXC  (1<<0)  /* Bit  0: (sc) Clear Tx Counters */
-
-
-/*     XM_RX_CNT_EV    32 bit r/o      Rx Counter Event Register */
-/*     XM_RX_EV_MSK    32 bit r/w      Rx Counter Event Mask */
-#define XMR_MAX_SZ_OV  (1UL<<31)       /* Bit 31:      1024-MaxSize Rx Cnt Ov*/
-#define XMR_1023B_OV   (1L<<30)        /* Bit 30:      512-1023Byte Rx Cnt Ov*/
-#define XMR_511B_OV            (1L<<29)        /* Bit 29:      256-511 Byte Rx Cnt Ov*/
-#define XMR_255B_OV            (1L<<28)        /* Bit 28:      128-255 Byte Rx Cnt Ov*/
-#define XMR_127B_OV            (1L<<27)        /* Bit 27:      65-127 Byte Rx Cnt Ov */
-#define XMR_64B_OV             (1L<<26)        /* Bit 26:      64 Byte Rx Cnt Ov */
-#define XMR_UTIL_OV            (1L<<25)        /* Bit 25:      Rx Util Cnt Overflow */
-#define XMR_UTIL_UR            (1L<<24)        /* Bit 24:      Rx Util Cnt Underrun */
-#define XMR_CEX_ERR_OV (1L<<23)        /* Bit 23:      CEXT Err Cnt Ov */
-                                                                       /* Bit 22:      reserved */
-#define XMR_FCS_ERR_OV (1L<<21)        /* Bit 21:      Rx FCS Error Cnt Ov */
-#define XMR_LNG_ERR_OV (1L<<20)        /* Bit 20:      Rx too Long Err Cnt Ov*/
-#define XMR_RUNT_OV            (1L<<19)        /* Bit 19:      Runt Event Cnt Ov */
-#define XMR_SHT_ERR_OV (1L<<18)        /* Bit 18:      Rx Short Ev Err Cnt Ov*/
-#define XMR_SYM_ERR_OV (1L<<17)        /* Bit 17:      Rx Sym Err Cnt Ov */
-                                                                       /* Bit 16:      reserved */
-#define XMR_CAR_ERR_OV (1L<<15)        /* Bit 15:      Rx Carr Ev Err Cnt Ov */
-#define XMR_JAB_PKT_OV (1L<<14)        /* Bit 14:      Rx Jabb Packet Cnt Ov */
-#define XMR_FIFO_OV            (1L<<13)        /* Bit 13:      Rx FIFO Ov Ev Cnt Ov */
-#define XMR_FRA_ERR_OV (1L<<12)        /* Bit 12:      Rx Framing Err Cnt Ov */
-#define XMR_FMISS_OV   (1L<<11)        /* Bit 11:      Rx Missed Ev Cnt Ov */
-#define XMR_BURST              (1L<<10)        /* Bit 10:      Rx Burst Event Cnt Ov */
-#define XMR_INV_MOC            (1L<<9)         /* Bit  9:      Rx with inv. MAC OC Ov*/
-#define XMR_INV_MP             (1L<<8)         /* Bit  8:      Rx inv Pause Frame Ov */
-#define XMR_MCTRL_OV   (1L<<7)         /* Bit  7:      Rx MAC Ctrl-F Cnt Ov */
-#define XMR_MPAUSE_OV  (1L<<6)         /* Bit  6:      Rx Pause MAC Ctrl-F Ov*/
-#define XMR_UC_OK_OV   (1L<<5)         /* Bit  5:      Rx Unicast Frame CntOv*/
-#define XMR_MC_OK_OV   (1L<<4)         /* Bit  4:      Rx Multicast Cnt Ov */
-#define XMR_BC_OK_OV   (1L<<3)         /* Bit  3:      Rx Broadcast Cnt Ov */
-#define XMR_OK_LO_OV   (1L<<2)         /* Bit  2:      Octets Rx OK Low CntOv*/
-#define XMR_OK_HI_OV   (1L<<1)         /* Bit  1:      Octets Rx OK Hi Cnt Ov*/
-#define XMR_OK_OV              (1L<<0)         /* Bit  0:      Frames Received Ok Ov */
-
-#define XMR_DEF_MSK            (XMR_OK_LO_OV | XMR_OK_HI_OV)
-
-/*     XM_TX_CNT_EV    32 bit r/o      Tx Counter Event Register */
-/*     XM_TX_EV_MSK    32 bit r/w      Tx Counter Event Mask */
-                                                                       /* Bit 31..26:  reserved */
-#define XMT_MAX_SZ_OV  (1L<<25)        /* Bit 25:      1024-MaxSize Tx Cnt Ov*/
-#define XMT_1023B_OV   (1L<<24)        /* Bit 24:      512-1023Byte Tx Cnt Ov*/
-#define XMT_511B_OV            (1L<<23)        /* Bit 23:      256-511 Byte Tx Cnt Ov*/
-#define XMT_255B_OV            (1L<<22)        /* Bit 22:      128-255 Byte Tx Cnt Ov*/
-#define XMT_127B_OV            (1L<<21)        /* Bit 21:      65-127 Byte Tx Cnt Ov */
-#define XMT_64B_OV             (1L<<20)        /* Bit 20:      64 Byte Tx Cnt Ov */
-#define XMT_UTIL_OV            (1L<<19)        /* Bit 19:      Tx Util Cnt Overflow */
-#define XMT_UTIL_UR            (1L<<18)        /* Bit 18:      Tx Util Cnt Underrun */
-#define XMT_CS_ERR_OV  (1L<<17)        /* Bit 17:      Tx Carr Sen Err Cnt Ov*/
-#define XMT_FIFO_UR_OV (1L<<16)        /* Bit 16:      Tx FIFO Ur Ev Cnt Ov */
-#define XMT_EX_DEF_OV  (1L<<15)        /* Bit 15:      Tx Ex Deferall Cnt Ov */
-#define XMT_DEF                        (1L<<14)        /* Bit 14:      Tx Deferred Cnt Ov */
-#define XMT_LAT_COL_OV (1L<<13)        /* Bit 13:      Tx Late Col Cnt Ov */
-#define XMT_ABO_COL_OV (1L<<12)        /* Bit 12:      Tx abo dueto Ex Col Ov*/
-#define XMT_MUL_COL_OV (1L<<11)        /* Bit 11:      Tx Mult Col Cnt Ov */
-#define XMT_SNG_COL            (1L<<10)        /* Bit 10:      Tx Single Col Cnt Ov */
-#define XMT_MCTRL_OV   (1L<<9)         /* Bit  9:      Tx MAC Ctrl Counter Ov*/
-#define XMT_MPAUSE             (1L<<8)         /* Bit  8:      Tx Pause MAC Ctrl-F Ov*/
-#define XMT_BURST              (1L<<7)         /* Bit  7:      Tx Burst Event Cnt Ov */
-#define XMT_LONG               (1L<<6)         /* Bit  6:      Tx Long Frame Cnt Ov */
-#define XMT_UC_OK_OV   (1L<<5)         /* Bit  5:      Tx Unicast Cnt Ov */
-#define XMT_MC_OK_OV   (1L<<4)         /* Bit  4:      Tx Multicast Cnt Ov */
-#define XMT_BC_OK_OV   (1L<<3)         /* Bit  3:      Tx Broadcast Cnt Ov */
-#define XMT_OK_LO_OV   (1L<<2)         /* Bit  2:      Octets Tx OK Low CntOv*/
-#define XMT_OK_HI_OV   (1L<<1)         /* Bit  1:      Octets Tx OK Hi Cnt Ov*/
-#define XMT_OK_OV              (1L<<0)         /* Bit  0:      Frames Tx Ok Ov */
-
-#define XMT_DEF_MSK            (XMT_OK_LO_OV | XMT_OK_HI_OV)
-
-/*
- * Receive Frame Status Encoding
- */
-#define XMR_FS_LEN     (0x3fffUL<<18)  /* Bit 31..18:  Rx Frame Length */
-#define XMR_FS_2L_VLAN (1L<<17)        /* Bit 17:      tagged wh 2Lev VLAN ID*/
-#define XMR_FS_1L_VLAN (1L<<16)        /* Bit 16:      tagged wh 1Lev VLAN ID*/
-#define XMR_FS_BC              (1L<<15)        /* Bit 15:      Broadcast Frame */
-#define XMR_FS_MC              (1L<<14)        /* Bit 14:      Multicast Frame */
-#define XMR_FS_UC              (1L<<13)        /* Bit 13:      Unicast Frame */
-                                                                       /* Bit 12:      reserved */
-#define XMR_FS_BURST   (1L<<11)        /* Bit 11:      Burst Mode */
-#define XMR_FS_CEX_ERR (1L<<10)        /* Bit 10:      Carrier Ext. Error */
-#define XMR_FS_802_3   (1L<<9)         /* Bit  9:      802.3 Frame */
-#define XMR_FS_COL_ERR (1L<<8)         /* Bit  8:      Collision Error */
-#define XMR_FS_CAR_ERR (1L<<7)         /* Bit  7:      Carrier Event Error */
-#define XMR_FS_LEN_ERR (1L<<6)         /* Bit  6:      In-Range Length Error */
-#define XMR_FS_FRA_ERR (1L<<5)         /* Bit  5:      Framing Error */
-#define XMR_FS_RUNT            (1L<<4)         /* Bit  4:      Runt Frame */
-#define XMR_FS_LNG_ERR (1L<<3)         /* Bit  3:      Giant (Jumbo) Frame */
-#define XMR_FS_FCS_ERR (1L<<2)         /* Bit  2:      Frame Check Sequ Err */
-#define XMR_FS_ERR             (1L<<1)         /* Bit  1:      Frame Error */
-#define XMR_FS_MCTRL   (1L<<0)         /* Bit  0:      MAC Control Packet */
-
-/*
- * XMR_FS_ERR will be set if
- *     XMR_FS_FCS_ERR, XMR_FS_LNG_ERR, XMR_FS_RUNT,
- *     XMR_FS_FRA_ERR, XMR_FS_LEN_ERR, or XMR_FS_CEX_ERR
- * is set. XMR_FS_LNG_ERR and XMR_FS_LEN_ERR will issue
- * XMR_FS_ERR unless the corresponding bit in the Receive Command
- * Register is set.
- */
-#define XMR_FS_ANY_ERR XMR_FS_ERR
-
-/*----------------------------------------------------------------------------*/
-/*
- * XMAC-PHY Registers, indirect addressed over the XMAC
- */
-#define PHY_XMAC_CTRL          0x00    /* 16 bit r/w   PHY Control Register */
-#define PHY_XMAC_STAT          0x01    /* 16 bit r/w   PHY Status Register */
-#define PHY_XMAC_ID0           0x02    /* 16 bit r/o   PHY ID0 Register */
-#define PHY_XMAC_ID1           0x03    /* 16 bit r/o   PHY ID1 Register */
-#define PHY_XMAC_AUNE_ADV      0x04    /* 16 bit r/w   Auto-Neg. Advertisement */
-#define PHY_XMAC_AUNE_LP       0x05    /* 16 bit r/o   Link Partner Abi Reg */
-#define PHY_XMAC_AUNE_EXP      0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
-#define PHY_XMAC_NEPG          0x07    /* 16 bit r/w   Next Page Register */
-#define PHY_XMAC_NEPG_LP       0x08    /* 16 bit r/o   Next Page Link P Reg */
-       /* 0x09 - 0x0e:         reserved */
-#define PHY_XMAC_EXT_STAT      0x0f    /* 16 bit r/o   Ext Status Register */
-#define PHY_XMAC_RES_ABI       0x10    /* 16 bit r/o   PHY Resolved Ability */
-
-/*----------------------------------------------------------------------------*/
-/*
- * Broadcom-PHY Registers, indirect addressed over XMAC
- */
-#define PHY_BCOM_CTRL          0x00    /* 16 bit r/w   PHY Control Register */
-#define PHY_BCOM_STAT          0x01    /* 16 bit r/o   PHY Status Register */
-#define PHY_BCOM_ID0           0x02    /* 16 bit r/o   PHY ID0 Register */
-#define PHY_BCOM_ID1           0x03    /* 16 bit r/o   PHY ID1 Register */
-#define PHY_BCOM_AUNE_ADV      0x04    /* 16 bit r/w   Auto-Neg. Advertisement */
-#define PHY_BCOM_AUNE_LP       0x05    /* 16 bit r/o   Link Part Ability Reg */
-#define PHY_BCOM_AUNE_EXP      0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
-#define PHY_BCOM_NEPG          0x07    /* 16 bit r/w   Next Page Register */
-#define PHY_BCOM_NEPG_LP       0x08    /* 16 bit r/o   Next Page Link P Reg */
-       /* Broadcom-specific registers */
-#define PHY_BCOM_1000T_CTRL    0x09    /* 16 bit r/w   1000Base-T Ctrl Reg */
-#define PHY_BCOM_1000T_STAT    0x0a    /* 16 bit r/o   1000Base-T Status Reg */
-       /* 0x0b - 0x0e:         reserved */
-#define PHY_BCOM_EXT_STAT      0x0f    /* 16 bit r/o   Extended Status Reg */
-#define PHY_BCOM_P_EXT_CTRL    0x10    /* 16 bit r/w   PHY Extended Ctrl Reg */
-#define PHY_BCOM_P_EXT_STAT    0x11    /* 16 bit r/o   PHY Extended Stat Reg */
-#define PHY_BCOM_RE_CTR                0x12    /* 16 bit r/w   Receive Error Counter */
-#define PHY_BCOM_FC_CTR                0x13    /* 16 bit r/w   False Carr Sense Cnt */
-#define PHY_BCOM_RNO_CTR       0x14    /* 16 bit r/w   Receiver NOT_OK Cnt */
-       /* 0x15 - 0x17:         reserved */
-#define PHY_BCOM_AUX_CTRL      0x18    /* 16 bit r/w   Auxiliary Control Reg */
-#define PHY_BCOM_AUX_STAT      0x19    /* 16 bit r/o   Auxiliary Stat Summary */
-#define PHY_BCOM_INT_STAT      0x1a    /* 16 bit r/o   Interrupt Status Reg */
-#define PHY_BCOM_INT_MASK      0x1b    /* 16 bit r/w   Interrupt Mask Reg */
-       /* 0x1c:                reserved */
-       /* 0x1d - 0x1f:         test registers */
-
-/*----------------------------------------------------------------------------*/
-/*
- * Marvel-PHY Registers, indirect addressed over GMAC
- */
-#define PHY_MARV_CTRL          0x00    /* 16 bit r/w   PHY Control Register */
-#define PHY_MARV_STAT          0x01    /* 16 bit r/o   PHY Status Register */
-#define PHY_MARV_ID0           0x02    /* 16 bit r/o   PHY ID0 Register */
-#define PHY_MARV_ID1           0x03    /* 16 bit r/o   PHY ID1 Register */
-#define PHY_MARV_AUNE_ADV      0x04    /* 16 bit r/w   Auto-Neg. Advertisement */
-#define PHY_MARV_AUNE_LP       0x05    /* 16 bit r/o   Link Part Ability Reg */
-#define PHY_MARV_AUNE_EXP      0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
-#define PHY_MARV_NEPG          0x07    /* 16 bit r/w   Next Page Register */
-#define PHY_MARV_NEPG_LP       0x08    /* 16 bit r/o   Next Page Link P Reg */
-       /* Marvel-specific registers */
-#define PHY_MARV_1000T_CTRL    0x09    /* 16 bit r/w   1000Base-T Ctrl Reg */
-#define PHY_MARV_1000T_STAT    0x0a    /* 16 bit r/o   1000Base-T Status Reg */
-       /* 0x0b - 0x0e:         reserved */
-#define PHY_MARV_EXT_STAT      0x0f    /* 16 bit r/o   Extended Status Reg */
-#define PHY_MARV_PHY_CTRL      0x10    /* 16 bit r/w   PHY Specific Ctrl Reg */
-#define PHY_MARV_PHY_STAT      0x11    /* 16 bit r/o   PHY Specific Stat Reg */
-#define PHY_MARV_INT_MASK      0x12    /* 16 bit r/w   Interrupt Mask Reg */
-#define PHY_MARV_INT_STAT      0x13    /* 16 bit r/o   Interrupt Status Reg */
-#define PHY_MARV_EXT_CTRL      0x14    /* 16 bit r/w   Ext. PHY Specific Ctrl */
-#define PHY_MARV_RXE_CNT       0x15    /* 16 bit r/w   Receive Error Counter */
-#define PHY_MARV_EXT_ADR       0x16    /* 16 bit r/w   Ext. Ad. for Cable Diag. */
-       /* 0x17:                reserved */
-#define PHY_MARV_LED_CTRL      0x18    /* 16 bit r/w   LED Control Reg */
-#define PHY_MARV_LED_OVER      0x19    /* 16 bit r/w   Manual LED Override Reg */
-#define PHY_MARV_EXT_CTRL_2    0x1a    /* 16 bit r/w   Ext. PHY Specific Ctrl 2 */
-#define PHY_MARV_EXT_P_STAT    0x1b    /* 16 bit r/w   Ext. PHY Spec. Stat Reg */
-#define PHY_MARV_CABLE_DIAG    0x1c    /* 16 bit r/o   Cable Diagnostic Reg */
-       /* 0x1d - 0x1f:         reserved */
-
-/*----------------------------------------------------------------------------*/
-/*
- * Level One-PHY Registers, indirect addressed over XMAC
- */
-#define PHY_LONE_CTRL          0x00    /* 16 bit r/w   PHY Control Register */
-#define PHY_LONE_STAT          0x01    /* 16 bit r/o   PHY Status Register */
-#define PHY_LONE_ID0           0x02    /* 16 bit r/o   PHY ID0 Register */
-#define PHY_LONE_ID1           0x03    /* 16 bit r/o   PHY ID1 Register */
-#define PHY_LONE_AUNE_ADV      0x04    /* 16 bit r/w   Auto-Neg. Advertisement */
-#define PHY_LONE_AUNE_LP       0x05    /* 16 bit r/o   Link Part Ability Reg */
-#define PHY_LONE_AUNE_EXP      0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
-#define PHY_LONE_NEPG          0x07    /* 16 bit r/w   Next Page Register */
-#define PHY_LONE_NEPG_LP       0x08    /* 16 bit r/o   Next Page Link Partner*/
-       /* Level One-specific registers */
-#define PHY_LONE_1000T_CTRL    0x09    /* 16 bit r/w   1000Base-T Control Reg*/
-#define PHY_LONE_1000T_STAT    0x0a    /* 16 bit r/o   1000Base-T Status Reg */
-       /* 0x0b -0x0e:          reserved */
-#define PHY_LONE_EXT_STAT      0x0f    /* 16 bit r/o   Extended Status Reg */
-#define PHY_LONE_PORT_CFG      0x10    /* 16 bit r/w   Port Configuration Reg*/
-#define PHY_LONE_Q_STAT                0x11    /* 16 bit r/o   Quick Status Reg */
-#define PHY_LONE_INT_ENAB      0x12    /* 16 bit r/w   Interrupt Enable Reg */
-#define PHY_LONE_INT_STAT      0x13    /* 16 bit r/o   Interrupt Status Reg */
-#define PHY_LONE_LED_CFG       0x14    /* 16 bit r/w   LED Configuration Reg */
-#define PHY_LONE_PORT_CTRL     0x15    /* 16 bit r/w   Port Control Reg */
-#define PHY_LONE_CIM           0x16    /* 16 bit r/o   CIM Reg */
-       /* 0x17 -0x1c:          reserved */
-
-/*----------------------------------------------------------------------------*/
-/*
- * National-PHY Registers, indirect addressed over XMAC
- */
-#define PHY_NAT_CTRL           0x00    /* 16 bit r/w   PHY Control Register */
-#define PHY_NAT_STAT           0x01    /* 16 bit r/w   PHY Status Register */
-#define PHY_NAT_ID0                    0x02    /* 16 bit r/o   PHY ID0 Register */
-#define PHY_NAT_ID1                    0x03    /* 16 bit r/o   PHY ID1 Register */
-#define PHY_NAT_AUNE_ADV       0x04    /* 16 bit r/w   Auto-Neg. Advertisement */
-#define PHY_NAT_AUNE_LP                0x05    /* 16 bit r/o   Link Partner Ability Reg */
-#define PHY_NAT_AUNE_EXP       0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
-#define PHY_NAT_NEPG           0x07    /* 16 bit r/w   Next Page Register */
-#define PHY_NAT_NEPG_LP                0x08    /* 16 bit r/o   Next Page Link Partner Reg */
-       /* National-specific registers */
-#define PHY_NAT_1000T_CTRL     0x09    /* 16 bit r/w   1000Base-T Control Reg */
-#define PHY_NAT_1000T_STAT     0x0a    /* 16 bit r/o   1000Base-T Status Reg */
-       /* 0x0b -0x0e:          reserved */
-#define PHY_NAT_EXT_STAT       0x0f    /* 16 bit r/o   Extended Status Register */
-#define PHY_NAT_EXT_CTRL1      0x10    /* 16 bit r/o   Extended Control Reg1 */
-#define PHY_NAT_Q_STAT1                0x11    /* 16 bit r/o   Quick Status Reg1 */
-#define PHY_NAT_10B_OP         0x12    /* 16 bit r/o   10Base-T Operations Reg */
-#define PHY_NAT_EXT_CTRL2      0x13    /* 16 bit r/o   Extended Control Reg1 */
-#define PHY_NAT_Q_STAT2                0x14    /* 16 bit r/o   Quick Status Reg2 */
-       /* 0x15 -0x18:          reserved */
-#define PHY_NAT_PHY_ADDR       0x19    /* 16 bit r/o   PHY Address Register */
-
-
-/*----------------------------------------------------------------------------*/
-
-/*
- * PHY bit definitions
- * Bits defined as PHY_X_..., PHY_B_..., PHY_L_... or PHY_N_... are
- * Xmac/Broadcom/LevelOne/National-specific.
- * All other are general.
- */
-
-/*****  PHY_XMAC_CTRL  16 bit r/w      PHY Control Register *****/
-/*****  PHY_BCOM_CTRL  16 bit r/w      PHY Control Register *****/
-/*****  PHY_LONE_CTRL  16 bit r/w      PHY Control Register *****/
-#define PHY_CT_RESET   (1<<15) /* Bit 15: (sc) clear all PHY related regs */
-#define PHY_CT_LOOP            (1<<14) /* Bit 14:      enable Loopback over PHY */
-#define PHY_CT_SPS_LSB (1<<13) /* Bit 13: (BC,L1) Speed select, lower bit */
-#define PHY_CT_ANE             (1<<12) /* Bit 12:      Auto-Negotiation Enabled */
-#define PHY_CT_PDOWN   (1<<11) /* Bit 11: (BC,L1) Power Down Mode */
-#define PHY_CT_ISOL            (1<<10) /* Bit 10: (BC,L1) Isolate Mode */
-#define PHY_CT_RE_CFG  (1<<9)  /* Bit  9: (sc) Restart Auto-Negotiation */
-#define PHY_CT_DUP_MD  (1<<8)  /* Bit  8:      Duplex Mode */
-#define PHY_CT_COL_TST (1<<7)  /* Bit  7: (BC,L1) Collision Test enabled */
-#define PHY_CT_SPS_MSB (1<<6)  /* Bit  6: (BC,L1) Speed select, upper bit */
-                                                               /* Bit  5..0:   reserved */
-
-#define PHY_CT_SP1000  PHY_CT_SPS_MSB  /* enable speed of 1000 Mbps */
-#define PHY_CT_SP100   PHY_CT_SPS_LSB  /* enable speed of  100 Mbps */
-#define PHY_CT_SP10            (0)                             /* enable speed of   10 Mbps */
-
-
-/*****  PHY_XMAC_STAT  16 bit r/w      PHY Status Register *****/
-/*****  PHY_BCOM_STAT  16 bit r/w      PHY Status Register *****/
-/*****  PHY_MARV_STAT  16 bit r/w      PHY Status Register *****/
-/*****  PHY_LONE_STAT  16 bit r/w      PHY Status Register *****/
-                                                               /* Bit 15..9:   reserved */
-                               /*      (BC/L1) 100/10 Mbps cap bits ignored*/
-#define PHY_ST_EXT_ST  (1<<8)  /* Bit  8:      Extended Status Present */
-                                                               /* Bit  7:      reserved */
-#define PHY_ST_PRE_SUP (1<<6)  /* Bit  6: (BC/L1) preamble suppression */
-#define PHY_ST_AN_OVER (1<<5)  /* Bit  5:      Auto-Negotiation Over */
-#define PHY_ST_REM_FLT (1<<4)  /* Bit  4:      Remote Fault Condition Occured */
-#define PHY_ST_AN_CAP  (1<<3)  /* Bit  3:      Auto-Negotiation Capability */
-#define PHY_ST_LSYNC   (1<<2)  /* Bit  2:      Link Synchronized */
-#define PHY_ST_JAB_DET (1<<1)  /* Bit  1: (BC/L1) Jabber Detected */
-#define PHY_ST_EXT_REG (1<<0)  /* Bit  0:      Extended Register available */
-
-
-/***** PHY_XMAC_ID1            16 bit r/o      PHY ID1 Register */
-/***** PHY_BCOM_ID1            16 bit r/o      PHY ID1 Register */
-/***** PHY_MARV_ID1            16 bit r/o      PHY ID1 Register */
-/***** PHY_LONE_ID1            16 bit r/o      PHY ID1 Register */
-#define PHY_I1_OUI_MSK (0x3f<<10)      /* Bit 15..10:  Organization Unique ID */
-#define PHY_I1_MOD_NUM (0x3f<<4)       /* Bit  9.. 4:  Model Number */
-#define PHY_I1_REV_MSK 0x0f            /* Bit  3.. 0:  Revision Number */
-
-/* different Broadcom PHY Ids */
-#define PHY_BCOM_ID1_A1                0x6041
-#define PHY_BCOM_ID1_B2                0x6043
-#define PHY_BCOM_ID1_C0                0x6044
-#define PHY_BCOM_ID1_C5                0x6047
-
-
-/*****  PHY_XMAC_AUNE_ADV      16 bit r/w      Auto-Negotiation Advertisement *****/
-/*****  PHY_XMAC_AUNE_LP       16 bit r/o      Link Partner Ability Reg *****/
-#define PHY_AN_NXT_PG  (1<<15) /* Bit 15:      Request Next Page */
-#define PHY_X_AN_ACK   (1<<14) /* Bit 14: (ro) Acknowledge Received */
-#define PHY_X_AN_RFB   (3<<12) /* Bit 13..12:  Remote Fault Bits */
-                                                               /* Bit 11.. 9:  reserved */
-#define PHY_X_AN_PAUSE (3<<7)  /* Bit  8.. 7:  Pause Bits */
-#define PHY_X_AN_HD            (1<<6)  /* Bit  6:      Half Duplex */
-#define PHY_X_AN_FD            (1<<5)  /* Bit  5:      Full Duplex */
-                                                               /* Bit  4.. 0:  reserved */
-
-/*****  PHY_BCOM_AUNE_ADV      16 bit r/w      Auto-Negotiation Advertisement *****/
-/*****  PHY_BCOM_AUNE_LP       16 bit r/o      Link Partner Ability Reg *****/
-/*     PHY_AN_NXT_PG           (see XMAC) Bit 15:      Request Next Page */
-                                                               /* Bit 14:      reserved */
-#define PHY_B_AN_RF            (1<<13) /* Bit 13:      Remote Fault */
-                                                               /* Bit 12:      reserved */
-#define PHY_B_AN_ASP   (1<<11) /* Bit 11:      Asymmetric Pause */
-#define PHY_B_AN_PC            (1<<10) /* Bit 10:      Pause Capable */
-                                                               /* Bit  9..5:   100/10 BT cap bits ingnored */
-#define PHY_B_AN_SEL   0x1f    /* Bit 4..0:    Selector Field, 00001=Ethernet*/
-
-/*****  PHY_LONE_AUNE_ADV      16 bit r/w      Auto-Negotiation Advertisement *****/
-/*****  PHY_LONE_AUNE_LP       16 bit r/o      Link Partner Ability Reg *****/
-/*     PHY_AN_NXT_PG           (see XMAC) Bit 15:      Request Next Page */
-                                                               /* Bit 14:      reserved */
-#define PHY_L_AN_RF            (1<<13) /* Bit 13:      Remote Fault */
-                                                               /* Bit 12:      reserved */
-#define PHY_L_AN_ASP   (1<<11) /* Bit 11:      Asymmetric Pause */
-#define PHY_L_AN_PC            (1<<10) /* Bit 10:      Pause Capable */
-                                                               /* Bit  9..5:   100/10 BT cap bits ingnored */
-#define PHY_L_AN_SEL   0x1f    /* Bit 4..0:    Selector Field, 00001=Ethernet*/
-
-/*****  PHY_NAT_AUNE_ADV       16 bit r/w      Auto-Negotiation Advertisement *****/
-/*****  PHY_NAT_AUNE_LP                16 bit r/o      Link Partner Ability Reg *****/
-/*     PHY_AN_NXT_PG           (see XMAC) Bit 15:      Request Next Page */
-                                                               /* Bit 14:      reserved */
-#define PHY_N_AN_RF            (1<<13) /* Bit 13:      Remote Fault */
-                                                               /* Bit 12:      reserved */
-#define PHY_N_AN_100F  (1<<11) /* Bit 11:      100Base-T2 FD Support */
-#define PHY_N_AN_100H  (1<<10) /* Bit 10:      100Base-T2 HD Support */
-                                                               /* Bit  9..5:   100/10 BT cap bits ingnored */
-#define PHY_N_AN_SEL   0x1f    /* Bit 4..0:    Selector Field, 00001=Ethernet*/
-
-/* field type definition for PHY_x_AN_SEL */
-#define PHY_SEL_TYPE   0x01    /* 00001 = Ethernet */
-
-/*****  PHY_XMAC_AUNE_EXP      16 bit r/o      Auto-Negotiation Expansion Reg *****/
-                                                               /* Bit 15..4:   reserved */
-#define PHY_AN_LP_NP   (1<<3)  /* Bit  3:      Link Partner can Next Page */
-#define PHY_AN_LOC_NP  (1<<2)  /* Bit  2:      Local PHY can Next Page */
-#define PHY_AN_RX_PG   (1<<1)  /* Bit  1:      Page Received */
-                                                               /* Bit  0:      reserved */
-
-/*****  PHY_BCOM_AUNE_EXP      16 bit r/o      Auto-Negotiation Expansion Reg *****/
-                                                               /* Bit 15..5:   reserved */
-#define PHY_B_AN_PDF   (1<<4)  /* Bit  4:      Parallel Detection Fault */
-/*     PHY_AN_LP_NP            (see XMAC) Bit  3:      Link Partner can Next Page */
-/*     PHY_AN_LOC_NP           (see XMAC) Bit  2:      Local PHY can Next Page */
-/*     PHY_AN_RX_PG            (see XMAC) Bit  1:      Page Received */
-#define PHY_B_AN_LP_CAP        (1<<0)  /* Bit  0:      Link Partner Auto-Neg. Cap. */
-
-/*****  PHY_LONE_AUNE_EXP      16 bit r/o      Auto-Negotiation Expansion Reg *****/
-#define PHY_L_AN_BP            (1<<5)  /* Bit  5:      Base Page Indication */
-#define PHY_L_AN_PDF   (1<<4)  /* Bit  4:      Parallel Detection Fault */
-/*     PHY_AN_LP_NP            (see XMAC) Bit  3:      Link Partner can Next Page */
-/*     PHY_AN_LOC_NP           (see XMAC) Bit  2:      Local PHY can Next Page */
-/*     PHY_AN_RX_PG            (see XMAC) Bit  1:      Page Received */
-#define PHY_B_AN_LP_CAP        (1<<0)  /* Bit  0:      Link Partner Auto-Neg. Cap. */
-
-
-/*****  PHY_XMAC_NEPG          16 bit r/w      Next Page Register *****/
-/*****  PHY_BCOM_NEPG          16 bit r/w      Next Page Register *****/
-/*****  PHY_LONE_NEPG          16 bit r/w      Next Page Register *****/
-/*****  PHY_XMAC_NEPG_LP       16 bit r/o      Next Page Link Partner *****/
-/*****  PHY_BCOM_NEPG_LP       16 bit r/o      Next Page Link Partner *****/
-/*****  PHY_LONE_NEPG_LP       16 bit r/o      Next Page Link Partner *****/
-#define PHY_NP_MORE            (1<<15) /* Bit 15:      More, Next Pages to follow */
-#define PHY_NP_ACK1            (1<<14) /* Bit 14: (ro) Ack 1, for receiving a message*/
-#define PHY_NP_MSG_VAL (1<<13) /* Bit 13:      Message Page valid */
-#define PHY_NP_ACK2            (1<<12) /* Bit 12:      Ack 2, comply with msg content*/
-#define PHY_NP_TOG             (1<<11) /* Bit 11:      Toggle Bit, ensure sync */
-#define PHY_NP_MSG             0x07ff  /* Bit 10..0:   Message from/to Link Partner */
-
-/*
- * XMAC-Specific
- */
-/*****  PHY_XMAC_EXT_STAT      16 bit r/w      Extended Status Register *****/
-#define PHY_X_EX_FD            (1<<15) /* Bit 15:      Device Supports Full Duplex */
-#define PHY_X_EX_HD            (1<<14) /* Bit 14:      Device Supports Half Duplex */
-                                                               /* Bit 13..0:   reserved */
-
-/*****  PHY_XMAC_RES_ABI       16 bit r/o      PHY Resolved Ability *****/
-                                                               /* Bit 15..9:   reserved */
-#define PHY_X_RS_PAUSE (3<<7)  /* Bit  8..7:   selected Pause Mode */
-#define PHY_X_RS_HD            (1<<6)  /* Bit  6:      Half Duplex Mode selected */
-#define PHY_X_RS_FD            (1<<5)  /* Bit  5:      Full Duplex Mode selected */
-#define PHY_X_RS_ABLMIS (1<<4) /* Bit  4:      duplex or pause cap mismatch */
-#define PHY_X_RS_PAUMIS (1<<3) /* Bit  3:      pause capability missmatch */
-                                                               /* Bit  2..0:   reserved */
-/*
- * Remote Fault Bits (PHY_X_AN_RFB) encoding
- */
-#define X_RFB_OK               (0<<12) /* Bit 13..12   No errors, Link OK */
-#define X_RFB_LF               (1<<12) /* Bit 13..12   Link Failure */
-#define X_RFB_OFF              (2<<12) /* Bit 13..12   Offline */
-#define X_RFB_AN_ERR   (3<<12) /* Bit 13..12   Auto-Negotiation Error */
-
-/*
- * Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding
- */
-#define PHY_X_P_NO_PAUSE       (0<<7)  /* Bit  8..7:   no Pause Mode */
-#define PHY_X_P_SYM_MD         (1<<7)  /* Bit  8..7:   symmetric Pause Mode */
-#define PHY_X_P_ASYM_MD                (2<<7)  /* Bit  8..7:   asymmetric Pause Mode */
-#define PHY_X_P_BOTH_MD                (3<<7)  /* Bit  8..7:   both Pause Mode */
-
-
-/*
- * Broadcom-Specific
- */
-/*****  PHY_BCOM_1000T_CTRL    16 bit r/w      1000Base-T Control Reg *****/
-#define PHY_B_1000C_TEST       (7<<13) /* Bit 15..13:  Test Modes */
-#define PHY_B_1000C_MSE                (1<<12) /* Bit 12:      Master/Slave Enable */
-#define PHY_B_1000C_MSC                (1<<11) /* Bit 11:      M/S Configuration */
-#define PHY_B_1000C_RD         (1<<10) /* Bit 10:      Repeater/DTE */
-#define PHY_B_1000C_AFD                (1<<9)  /* Bit  9:      Advertise Full Duplex */
-#define PHY_B_1000C_AHD                (1<<8)  /* Bit  8:      Advertise Half Duplex */
-                                                                       /* Bit  7..0:   reserved */
-
-/*****  PHY_BCOM_1000T_STAT    16 bit r/o      1000Base-T Status Reg *****/
-#define PHY_B_1000S_MSF                (1<<15) /* Bit 15:      Master/Slave Fault */
-#define PHY_B_1000S_MSR                (1<<14) /* Bit 14:      Master/Slave Result */
-#define PHY_B_1000S_LRS                (1<<13) /* Bit 13:      Local Receiver Status */
-#define PHY_B_1000S_RRS                (1<<12) /* Bit 12:      Remote Receiver Status */
-#define PHY_B_1000S_LP_FD      (1<<11) /* Bit 11:      Link Partner can FD */
-#define PHY_B_1000S_LP_HD      (1<<10) /* Bit 10:      Link Partner can HD */
-                                                                       /* Bit  9..8:   reserved */
-#define PHY_B_1000S_IEC                0xff    /* Bit  7..0:   Idle Error Count */
-
-/*****  PHY_BCOM_EXT_STAT      16 bit r/o      Extended Status Register *****/
-#define PHY_B_ES_X_FD_CAP      (1<<15) /* Bit 15:      1000Base-X FD capable */
-#define PHY_B_ES_X_HD_CAP      (1<<14) /* Bit 14:      1000Base-X HD capable */
-#define PHY_B_ES_T_FD_CAP      (1<<13) /* Bit 13:      1000Base-T FD capable */
-#define PHY_B_ES_T_HD_CAP      (1<<12) /* Bit 12:      1000Base-T HD capable */
-                                                                       /* Bit 11..0:   reserved */
-
-/*****  PHY_BCOM_P_EXT_CTRL    16 bit r/w      PHY Extended Control Reg *****/
-#define PHY_B_PEC_MAC_PHY      (1<<15) /* Bit 15:      10BIT/GMI-Interface */
-#define PHY_B_PEC_DIS_CROSS    (1<<14) /* Bit 14:      Disable MDI Crossover */
-#define PHY_B_PEC_TX_DIS       (1<<13) /* Bit 13:      Tx output Disabled */
-#define PHY_B_PEC_INT_DIS      (1<<12) /* Bit 12:      Interrupts Disabled */
-#define PHY_B_PEC_F_INT                (1<<11) /* Bit 11:      Force Interrupt */
-#define PHY_B_PEC_BY_45                (1<<10) /* Bit 10:      Bypass 4B5B-Decoder */
-#define PHY_B_PEC_BY_SCR       (1<<9)  /* Bit  9:      Bypass Scrambler */
-#define PHY_B_PEC_BY_MLT3      (1<<8)  /* Bit  8:      Bypass MLT3 Encoder */
-#define PHY_B_PEC_BY_RXA       (1<<7)  /* Bit  7:      Bypass Rx Alignm. */
-#define PHY_B_PEC_RES_SCR      (1<<6)  /* Bit  6:      Reset Scrambler */
-#define PHY_B_PEC_EN_LTR       (1<<5)  /* Bit  5:      Ena LED Traffic Mode */
-#define PHY_B_PEC_LED_ON       (1<<4)  /* Bit  4:      Force LED's on */
-#define PHY_B_PEC_LED_OFF      (1<<3)  /* Bit  3:      Force LED's off */
-#define PHY_B_PEC_EX_IPG       (1<<2)  /* Bit  2:      Extend Tx IPG Mode */
-#define PHY_B_PEC_3_LED                (1<<1)  /* Bit  1:      Three Link LED mode */
-#define PHY_B_PEC_HIGH_LA      (1<<0)  /* Bit  0:      GMII FIFO Elasticy */
-
-/*****  PHY_BCOM_P_EXT_STAT    16 bit r/o      PHY Extended Status Reg *****/
-                                                                       /* Bit 15..14:  reserved */
-#define PHY_B_PES_CROSS_STAT   (1<<13) /* Bit 13:      MDI Crossover Status */
-#define PHY_B_PES_INT_STAT     (1<<12) /* Bit 12:      Interrupt Status */
-#define PHY_B_PES_RRS          (1<<11) /* Bit 11:      Remote Receiver Stat. */
-#define PHY_B_PES_LRS          (1<<10) /* Bit 10:      Local Receiver Stat. */
-#define PHY_B_PES_LOCKED       (1<<9)  /* Bit  9:      Locked */
-#define PHY_B_PES_LS           (1<<8)  /* Bit  8:      Link Status */
-#define PHY_B_PES_RF           (1<<7)  /* Bit  7:      Remote Fault */
-#define PHY_B_PES_CE_ER                (1<<6)  /* Bit  6:      Carrier Ext Error */
-#define PHY_B_PES_BAD_SSD      (1<<5)  /* Bit  5:      Bad SSD */
-#define PHY_B_PES_BAD_ESD      (1<<4)  /* Bit  4:      Bad ESD */
-#define PHY_B_PES_RX_ER                (1<<3)  /* Bit  3:      Receive Error */
-#define PHY_B_PES_TX_ER                (1<<2)  /* Bit  2:      Transmit Error */
-#define PHY_B_PES_LOCK_ER      (1<<1)  /* Bit  1:      Lock Error */
-#define PHY_B_PES_MLT3_ER      (1<<0)  /* Bit  0:      MLT3 code Error */
-
-/*****  PHY_BCOM_FC_CTR                16 bit r/w      False Carrier Counter *****/
-                                                                       /* Bit 15..8:   reserved */
-#define PHY_B_FC_CTR           0xff    /* Bit  7..0:   False Carrier Counter */
-
-/*****  PHY_BCOM_RNO_CTR       16 bit r/w      Receive NOT_OK Counter *****/
-#define PHY_B_RC_LOC_MSK       0xff00  /* Bit 15..8:   Local Rx NOT_OK cnt */
-#define PHY_B_RC_REM_MSK       0x00ff  /* Bit  7..0:   Remote Rx NOT_OK cnt */
-
-/*****  PHY_BCOM_AUX_CTRL      16 bit r/w      Auxiliary Control Reg *****/
-#define PHY_B_AC_L_SQE         (1<<15) /* Bit 15:      Low Squelch */
-#define PHY_B_AC_LONG_PACK     (1<<14) /* Bit 14:      Rx Long Packets */
-#define PHY_B_AC_ER_CTRL       (3<<12) /* Bit 13..12:  Edgerate Control */
-                                                                       /* Bit 11:      reserved */
-#define PHY_B_AC_TX_TST                (1<<10) /* Bit 10:      Tx test bit, always 1 */
-                                                                       /* Bit  9.. 8:  reserved */
-#define PHY_B_AC_DIS_PRF       (1<<7)  /* Bit  7:      dis part resp filter */
-                                                                       /* Bit  6:      reserved */
-#define PHY_B_AC_DIS_PM                (1<<5)  /* Bit  5:      dis power management */
-                                                                       /* Bit  4:      reserved */
-#define PHY_B_AC_DIAG          (1<<3)  /* Bit  3:      Diagnostic Mode */
-                                                                       /* Bit  2.. 0:  reserved */
-
-/*****  PHY_BCOM_AUX_STAT      16 bit r/o      Auxiliary Status Reg *****/
-#define PHY_B_AS_AN_C          (1<<15) /* Bit 15:      AutoNeg complete */
-#define PHY_B_AS_AN_CA         (1<<14) /* Bit 14:      AN Complete Ack */
-#define PHY_B_AS_ANACK_D       (1<<13) /* Bit 13:      AN Ack Detect */
-#define PHY_B_AS_ANAB_D                (1<<12) /* Bit 12:      AN Ability Detect */
-#define PHY_B_AS_NPW           (1<<11) /* Bit 11:      AN Next Page Wait */
-#define PHY_B_AS_AN_RES_MSK    (7<<8)  /* Bit 10..8:   AN HDC */
-#define PHY_B_AS_PDF           (1<<7)  /* Bit  7:      Parallel Detect. Fault */
-#define PHY_B_AS_RF                    (1<<6)  /* Bit  6:      Remote Fault */
-#define PHY_B_AS_ANP_R         (1<<5)  /* Bit  5:      AN Page Received */
-#define PHY_B_AS_LP_ANAB       (1<<4)  /* Bit  4:      LP AN Ability */
-#define PHY_B_AS_LP_NPAB       (1<<3)  /* Bit  3:      LP Next Page Ability */
-#define PHY_B_AS_LS                    (1<<2)  /* Bit  2:      Link Status */
-#define PHY_B_AS_PRR           (1<<1)  /* Bit  1:      Pause Resolution-Rx */
-#define PHY_B_AS_PRT           (1<<0)  /* Bit  0:      Pause Resolution-Tx */
-
-#define PHY_B_AS_PAUSE_MSK     (PHY_B_AS_PRR | PHY_B_AS_PRT)
-
-/*****  PHY_BCOM_INT_STAT      16 bit r/o      Interrupt Status Reg *****/
-/*****  PHY_BCOM_INT_MASK      16 bit r/w      Interrupt Mask Reg *****/
-                                                                       /* Bit 15:      reserved */
-#define PHY_B_IS_PSE           (1<<14) /* Bit 14:      Pair Swap Error */
-#define PHY_B_IS_MDXI_SC       (1<<13) /* Bit 13:      MDIX Status Change */
-#define PHY_B_IS_HCT           (1<<12) /* Bit 12:      counter above 32k */
-#define PHY_B_IS_LCT           (1<<11) /* Bit 11:      counter above 128 */
-#define PHY_B_IS_AN_PR         (1<<10) /* Bit 10:      Page Received */
-#define PHY_B_IS_NO_HDCL       (1<<9)  /* Bit  9:      No HCD Link */
-#define PHY_B_IS_NO_HDC                (1<<8)  /* Bit  8:      No HCD */
-#define PHY_B_IS_NEG_USHDC     (1<<7)  /* Bit  7:      Negotiated Unsup. HCD */
-#define PHY_B_IS_SCR_S_ER      (1<<6)  /* Bit  6:      Scrambler Sync Error */
-#define PHY_B_IS_RRS_CHANGE    (1<<5)  /* Bit  5:      Remote Rx Stat Change */
-#define PHY_B_IS_LRS_CHANGE    (1<<4)  /* Bit  4:      Local Rx Stat Change */
-#define PHY_B_IS_DUP_CHANGE    (1<<3)  /* Bit  3:      Duplex Mode Change */
-#define PHY_B_IS_LSP_CHANGE    (1<<2)  /* Bit  2:      Link Speed Change */
-#define PHY_B_IS_LST_CHANGE    (1<<1)  /* Bit  1:      Link Status Changed */
-#define PHY_B_IS_CRC_ER                (1<<0)  /* Bit  0:      CRC Error */
-
-#define PHY_B_DEF_MSK  (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
-
-/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */
-#define PHY_B_P_NO_PAUSE       (0<<10) /* Bit 11..10:  no Pause Mode */
-#define PHY_B_P_SYM_MD         (1<<10) /* Bit 11..10:  symmetric Pause Mode */
-#define PHY_B_P_ASYM_MD                (2<<10) /* Bit 11..10:  asymmetric Pause Mode */
-#define PHY_B_P_BOTH_MD                (3<<10) /* Bit 11..10:  both Pause Mode */
-
-/*
- * Resolved Duplex mode and Capabilities (Aux Status Summary Reg)
- */
-#define PHY_B_RES_1000FD       (7<<8)  /* Bit 10..8:   1000Base-T Full Dup. */
-#define PHY_B_RES_1000HD       (6<<8)  /* Bit 10..8:   1000Base-T Half Dup. */
-/* others: 100/10: invalid for us */
-
-/*
- * Level One-Specific
- */
-/*****  PHY_LONE_1000T_CTRL    16 bit r/w      1000Base-T Control Reg *****/
-#define PHY_L_1000C_TEST       (7<<13) /* Bit 15..13:  Test Modes */
-#define PHY_L_1000C_MSE                (1<<12) /* Bit 12:      Master/Slave Enable */
-#define PHY_L_1000C_MSC                (1<<11) /* Bit 11:      M/S Configuration */
-#define PHY_L_1000C_RD         (1<<10) /* Bit 10:      Repeater/DTE */
-#define PHY_L_1000C_AFD                (1<<9)  /* Bit  9:      Advertise Full Duplex */
-#define PHY_L_1000C_AHD                (1<<8)  /* Bit  8:      Advertise Half Duplex */
-                                                                       /* Bit  7..0:   reserved */
-
-/*****  PHY_LONE_1000T_STAT    16 bit r/o      1000Base-T Status Reg *****/
-#define PHY_L_1000S_MSF                (1<<15) /* Bit 15:      Master/Slave Fault */
-#define PHY_L_1000S_MSR                (1<<14) /* Bit 14:      Master/Slave Result */
-#define PHY_L_1000S_LRS                (1<<13) /* Bit 13:      Local Receiver Status */
-#define PHY_L_1000S_RRS                (1<<12) /* Bit 12:      Remote Receiver Status*/
-#define PHY_L_1000S_LP_FD      (1<<11) /* Bit 11:      Link Partner can FD */
-#define PHY_L_1000S_LP_HD      (1<<10) /* Bit 10:      Link Partner can HD */
-                                                                       /* Bit  9..8:   reserved */
-#define PHY_B_1000S_IEC                0xff    /* Bit  7..0:   Idle Error Count */
-
-/*****  PHY_LONE_EXT_STAT      16 bit r/o      Extended Status Register *****/
-#define PHY_L_ES_X_FD_CAP      (1<<15) /* Bit 15:      1000Base-X FD capable */
-#define PHY_L_ES_X_HD_CAP      (1<<14) /* Bit 14:      1000Base-X HD capable */
-#define PHY_L_ES_T_FD_CAP      (1<<13) /* Bit 13:      1000Base-T FD capable */
-#define PHY_L_ES_T_HD_CAP      (1<<12) /* Bit 12:      1000Base-T HD capable */
-                                                                       /* Bit 11..0:   reserved */
-
-/*****  PHY_LONE_PORT_CFG      16 bit r/w      Port Configuration Reg *****/
-#define PHY_L_PC_REP_MODE      (1<<15) /* Bit 15:      Repeater Mode */
-                                                                       /* Bit 14:      reserved */
-#define PHY_L_PC_TX_DIS                (1<<13) /* Bit 13:      Tx output Disabled */
-#define PHY_L_PC_BY_SCR                (1<<12) /* Bit 12:      Bypass Scrambler */
-#define PHY_L_PC_BY_45         (1<<11) /* Bit 11:      Bypass 4B5B-Decoder */
-#define PHY_L_PC_JAB_DIS       (1<<10) /* Bit 10:      Jabber Disabled */
-#define PHY_L_PC_SQE           (1<<9)  /* Bit  9:      Enable Heartbeat */
-#define PHY_L_PC_TP_LOOP       (1<<8)  /* Bit  8:      TP Loopback */
-#define PHY_L_PC_SSS           (1<<7)  /* Bit  7:      Smart Speed Selection */
-#define PHY_L_PC_FIFO_SIZE     (1<<6)  /* Bit  6:      FIFO Size */
-#define PHY_L_PC_PRE_EN                (1<<5)  /* Bit  5:      Preamble Enable */
-#define PHY_L_PC_CIM           (1<<4)  /* Bit  4:      Carrier Integrity Mon */
-#define PHY_L_PC_10_SER                (1<<3)  /* Bit  3:      Use Serial Output */
-#define PHY_L_PC_ANISOL                (1<<2)  /* Bit  2:      Unisolate Port */
-#define PHY_L_PC_TEN_BIT       (1<<1)  /* Bit  1:      10bit iface mode on */
-#define PHY_L_PC_ALTCLOCK      (1<<0)  /* Bit  0: (ro) ALTCLOCK Mode on */
-
-/*****  PHY_LONE_Q_STAT                16 bit r/o      Quick Status Reg *****/
-#define PHY_L_QS_D_RATE                (3<<14) /* Bit 15..14:  Data Rate */
-#define PHY_L_QS_TX_STAT       (1<<13) /* Bit 13:      Transmitting */
-#define PHY_L_QS_RX_STAT       (1<<12) /* Bit 12:      Receiving */
-#define PHY_L_QS_COL_STAT      (1<<11) /* Bit 11:      Collision */
-#define PHY_L_QS_L_STAT                (1<<10) /* Bit 10:      Link is up */
-#define PHY_L_QS_DUP_MOD       (1<<9)  /* Bit  9:      Full/Half Duplex */
-#define PHY_L_QS_AN                    (1<<8)  /* Bit  8:      AutoNeg is On */
-#define PHY_L_QS_AN_C          (1<<7)  /* Bit  7:      AN is Complete */
-#define PHY_L_QS_LLE           (7<<4)  /* Bit  6:      Line Length Estim. */
-#define PHY_L_QS_PAUSE         (1<<3)  /* Bit  3:      LP advertised Pause */
-#define PHY_L_QS_AS_PAUSE      (1<<2)  /* Bit  2:      LP adv. asym. Pause */
-#define PHY_L_QS_ISOLATE       (1<<1)  /* Bit  1:      CIM Isolated */
-#define PHY_L_QS_EVENT         (1<<0)  /* Bit  0:      Event has occurred */
-
-/*****  PHY_LONE_INT_ENAB      16 bit r/w      Interrupt Enable Reg *****/
-/*****  PHY_LONE_INT_STAT      16 bit r/o      Interrupt Status Reg *****/
-                                                                       /* Bit 15..14:  reserved */
-#define PHY_L_IS_AN_F          (1<<13) /* Bit 13:      Auto-Negotiation fault */
-                                                                       /* Bit 12:      not described */
-#define PHY_L_IS_CROSS         (1<<11) /* Bit 11:      Crossover used */
-#define PHY_L_IS_POL           (1<<10) /* Bit 10:      Polarity correct. used*/
-#define PHY_L_IS_SS                    (1<<9)  /* Bit  9:      Smart Speed Downgrade*/
-#define PHY_L_IS_CFULL         (1<<8)  /* Bit  8:      Counter Full */
-#define PHY_L_IS_AN_C          (1<<7)  /* Bit  7:      AutoNeg Complete */
-#define PHY_L_IS_SPEED         (1<<6)  /* Bit  6:      Speed Changed */
-#define PHY_L_IS_DUP           (1<<5)  /* Bit  5:      Duplex Changed */
-#define PHY_L_IS_LS                    (1<<4)  /* Bit  4:      Link Status Changed */
-#define PHY_L_IS_ISOL          (1<<3)  /* Bit  3:      Isolate Occured */
-#define PHY_L_IS_MDINT         (1<<2)  /* Bit  2: (ro) STAT: MII Int Pending */
-#define PHY_L_IS_INTEN         (1<<1)  /* Bit  1:      ENAB: Enable IRQs */
-#define PHY_L_IS_FORCE         (1<<0)  /* Bit  0:      ENAB: Force Interrupt */
-
-/* int. mask */
-#define PHY_L_DEF_MSK          (PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN)
-
-/*****  PHY_LONE_LED_CFG       16 bit r/w      LED Configuration Reg *****/
-#define PHY_L_LC_LEDC          (3<<14) /* Bit 15..14:  Col/Blink/On/Off */
-#define PHY_L_LC_LEDR          (3<<12) /* Bit 13..12:  Rx/Blink/On/Off */
-#define PHY_L_LC_LEDT          (3<<10) /* Bit 11..10:  Tx/Blink/On/Off */
-#define PHY_L_LC_LEDG          (3<<8)  /* Bit  9..8:   Giga/Blink/On/Off */
-#define PHY_L_LC_LEDS          (3<<6)  /* Bit  7..6:   10-100/Blink/On/Off */
-#define PHY_L_LC_LEDL          (3<<4)  /* Bit  5..4:   Link/Blink/On/Off */
-#define PHY_L_LC_LEDF          (3<<2)  /* Bit  3..2:   Duplex/Blink/On/Off */
-#define PHY_L_LC_PSTRECH       (1<<1)  /* Bit  1:      Strech LED Pulses */
-#define PHY_L_LC_FREQ          (1<<0)  /* Bit  0:      30/100 ms */
-
-/*****  PHY_LONE_PORT_CTRL     16 bit r/w      Port Control Reg *****/
-#define PHY_L_PC_TX_TCLK       (1<<15) /* Bit 15:      Enable TX_TCLK */
-                                                                       /* Bit 14:      reserved */
-#define PHY_L_PC_ALT_NP                (1<<13) /* Bit 14:      Alternate Next Page */
-#define PHY_L_PC_GMII_ALT      (1<<12) /* Bit 13:      Alternate GMII driver */
-                                                                       /* Bit 11:      reserved */
-#define PHY_L_PC_TEN_CRS       (1<<10) /* Bit 10:      Extend CRS*/
-                                                                       /* Bit  9..0:   not described */
-
-/*****  PHY_LONE_CIM           16 bit r/o      CIM Reg *****/
-#define PHY_L_CIM_ISOL         (255<<8)/* Bit 15..8:   Isolate Count */
-#define PHY_L_CIM_FALSE_CAR    (255<<0)/* Bit  7..0:   False Carrier Count */
-
-
-/*
- * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding
- */
-#define PHY_L_P_NO_PAUSE       (0<<10) /* Bit 11..10:  no Pause Mode */
-#define PHY_L_P_SYM_MD         (1<<10) /* Bit 11..10:  symmetric Pause Mode */
-#define PHY_L_P_ASYM_MD                (2<<10) /* Bit 11..10:  asymmetric Pause Mode */
-#define PHY_L_P_BOTH_MD                (3<<10) /* Bit 11..10:  both Pause Mode */
-
-
-/*
- * National-Specific
- */
-/*****  PHY_NAT_1000T_CTRL     16 bit r/w      1000Base-T Control Reg *****/
-#define PHY_N_1000C_TEST       (7<<13) /* Bit 15..13:  Test Modes */
-#define PHY_N_1000C_MSE                (1<<12) /* Bit 12:      Master/Slave Enable */
-#define PHY_N_1000C_MSC                (1<<11) /* Bit 11:      M/S Configuration */
-#define PHY_N_1000C_RD         (1<<10) /* Bit 10:      Repeater/DTE */
-#define PHY_N_1000C_AFD                (1<<9)  /* Bit  9:      Advertise Full Duplex */
-#define PHY_N_1000C_AHD                (1<<8)  /* Bit  8:      Advertise Half Duplex */
-#define PHY_N_1000C_APC                (1<<7)  /* Bit  7:      Asymmetric Pause Cap. */
-                                                                       /* Bit  6..0:   reserved */
-
-/*****  PHY_NAT_1000T_STAT     16 bit r/o      1000Base-T Status Reg *****/
-#define PHY_N_1000S_MSF                (1<<15) /* Bit 15:      Master/Slave Fault */
-#define PHY_N_1000S_MSR                (1<<14) /* Bit 14:      Master/Slave Result */
-#define PHY_N_1000S_LRS                (1<<13) /* Bit 13:      Local Receiver Status */
-#define PHY_N_1000S_RRS                (1<<12) /* Bit 12:      Remote Receiver Status*/
-#define PHY_N_1000S_LP_FD      (1<<11) /* Bit 11:      Link Partner can FD */
-#define PHY_N_1000S_LP_HD      (1<<10) /* Bit 10:      Link Partner can HD */
-#define PHY_N_1000C_LP_APC     (1<<9)  /* Bit  9:      LP Asym. Pause Cap. */
-                                                                       /* Bit  8:      reserved */
-#define PHY_N_1000S_IEC                0xff    /* Bit  7..0:   Idle Error Count */
-
-/*****  PHY_NAT_EXT_STAT       16 bit r/o      Extended Status Register *****/
-#define PHY_N_ES_X_FD_CAP      (1<<15) /* Bit 15:      1000Base-X FD capable */
-#define PHY_N_ES_X_HD_CAP      (1<<14) /* Bit 14:      1000Base-X HD capable */
-#define PHY_N_ES_T_FD_CAP      (1<<13) /* Bit 13:      1000Base-T FD capable */
-#define PHY_N_ES_T_HD_CAP      (1<<12) /* Bit 12:      1000Base-T HD capable */
-                                                                       /* Bit 11..0:   reserved */
-
-/* todo: those are still missing */
-/*****  PHY_NAT_EXT_CTRL1      16 bit r/o      Extended Control Reg1 *****/
-/*****  PHY_NAT_Q_STAT1                16 bit r/o      Quick Status Reg1 *****/
-/*****  PHY_NAT_10B_OP         16 bit r/o      10Base-T Operations Reg *****/
-/*****  PHY_NAT_EXT_CTRL2      16 bit r/o      Extended Control Reg1 *****/
-/*****  PHY_NAT_Q_STAT2                16 bit r/o      Quick Status Reg2 *****/
-/*****  PHY_NAT_PHY_ADDR       16 bit r/o      PHY Address Register *****/
-
-/*
- * Marvell-Specific
- */
-/*****  PHY_MARV_AUNE_ADV      16 bit r/w      Auto-Negotiation Advertisement *****/
-/*****  PHY_MARV_AUNE_LP       16 bit r/w      Link Part Ability Reg *****/
-#define PHY_M_AN_NXT_PG                BIT_15  /* Request Next Page */
-#define PHY_M_AN_ACK           BIT_14  /* (ro) Acknowledge Received */
-#define PHY_M_AN_RF                    BIT_13  /* Remote Fault */
-                                                                       /* Bit 12:      reserved */
-#define PHY_M_AN_ASP           BIT_11  /* Asymmetric Pause */
-#define PHY_M_AN_PC                    BIT_10  /* MAC Pause implemented */
-#define PHY_M_AN_100_FD                BIT_8   /* Advertise 100Base-TX Full Duplex */
-#define PHY_M_AN_100_HD                BIT_7   /* Advertise 100Base-TX Half Duplex */
-#define PHY_M_AN_10_FD         BIT_6   /* Advertise 10Base-TX Full Duplex */
-#define PHY_M_AN_10_HD         BIT_5   /* Advertise 10Base-TX Half Duplex */
-
-/* special defines for FIBER (88E1011S only) */
-#define PHY_M_AN_ASP_X         BIT_8   /* Asymmetric Pause */
-#define PHY_M_AN_PC_X          BIT_7   /* MAC Pause implemented */
-#define PHY_M_AN_1000X_AHD     BIT_6   /* Advertise 10000Base-X Half Duplex */
-#define PHY_M_AN_1000X_AFD     BIT_5   /* Advertise 10000Base-X Full Duplex */
-
-/* Pause Bits (PHY_M_AN_ASP_X and PHY_M_AN_PC_X) encoding */
-#define PHY_M_P_NO_PAUSE_X     (0<<7)  /* Bit  8.. 7:  no Pause Mode */
-#define PHY_M_P_SYM_MD_X       (1<<7)  /* Bit  8.. 7:  symmetric Pause Mode */
-#define PHY_M_P_ASYM_MD_X      (2<<7)  /* Bit  8.. 7:  asymmetric Pause Mode */
-#define PHY_M_P_BOTH_MD_X      (3<<7)  /* Bit  8.. 7:  both Pause Mode */
-
-/*****  PHY_MARV_1000T_CTRL    16 bit r/w      1000Base-T Control Reg *****/
-#define PHY_M_1000C_TEST       (7<<13) /* Bit 15..13:  Test Modes */
-#define PHY_M_1000C_MSE                (1<<12) /* Bit 12:      Manual Master/Slave Enable */
-#define PHY_M_1000C_MSC                (1<<11) /* Bit 11:      M/S Configuration (1=Master) */
-#define PHY_M_1000C_MPD                (1<<10) /* Bit 10:      Multi-Port Device */
-#define PHY_M_1000C_AFD                (1<<9)  /* Bit  9:      Advertise Full Duplex */
-#define PHY_M_1000C_AHD                (1<<8)  /* Bit  8:      Advertise Half Duplex */
-                                                                       /* Bit  7..0:   reserved */
-
-/*****  PHY_MARV_PHY_CTRL      16 bit r/w      PHY Specific Ctrl Reg *****/
-
-#define PHY_M_PC_TX_FFD_MSK    (3<<14) /* Bit 15..14:  Tx FIFO Depth Mask */
-#define PHY_M_PC_RX_FFD_MSK    (3<<12) /* Bit 13..12:  Rx FIFO Depth Mask */
-#define PHY_M_PC_ASS_CRS_TX    (1<<11) /* Bit 11:      Assert CRS on Transmit */
-#define PHY_M_PC_FL_GOOD       (1<<10) /* Bit 10:      Force Link Good */
-#define PHY_M_PC_EN_DET_MSK    (3<<8)  /* Bit  9.. 8:  Energy Detect Mask */
-#define PHY_M_PC_ENA_EXT_D     (1<<7)  /* Bit  7:      Enable Ext. Distance (10BT) */
-#define PHY_M_PC_MDIX_MSK      (3<<5)  /* Bit  6.. 5:  MDI/MDIX Config. Mask */
-#define PHY_M_PC_DIS_125CLK    (1<<4)  /* Bit  4:      Disable 125 CLK */
-#define PHY_M_PC_MAC_POW_UP    (1<<3)  /* Bit  3:      MAC Power up */
-#define PHY_M_PC_SQE_T_ENA     (1<<2)  /* Bit  2:      SQE Test Enabled */
-#define PHY_M_PC_POL_R_DIS     (1<<1)  /* Bit  1:      Polarity Reversal Disabled */
-#define PHY_M_PC_DIS_JABBER    (1<<0)  /* Bit  0:      Disable Jabber */
-
-#define PHY_M_PC_MDI_XMODE(x)  SHIFT5(x)
-#define PHY_M_PC_MAN_MDI       0       /* 00 = Manual MDI configuration */
-#define PHY_M_PC_MAN_MDIX      1               /* 01 = Manual MDIX configuration */
-#define PHY_M_PC_ENA_AUTO      3               /* 11 = Enable Automatic Crossover */
-
-/*****  PHY_MARV_PHY_STAT      16 bit r/o      PHY Specific Status Reg *****/
-#define PHY_M_PS_SPEED_MSK     (3<<14) /* Bit 15..14:  Speed Mask */
-#define PHY_M_PS_SPEED_1000    (1<<15) /*       10 = 1000 Mbps */
-#define PHY_M_PS_SPEED_100     (1<<14) /*       01 =  100 Mbps */
-#define PHY_M_PS_SPEED_10      0               /*       00 =   10 Mbps */
-#define PHY_M_PS_FULL_DUP      (1<<13) /* Bit 13:      Full Duplex */
-#define PHY_M_PS_PAGE_REC      (1<<12) /* Bit 12:      Page Received */
-#define PHY_M_PS_SPDUP_RES     (1<<11) /* Bit 11:      Speed & Duplex Resolved */
-#define PHY_M_PS_LINK_UP       (1<<10) /* Bit 10:      Link Up */
-#define PHY_M_PS_CABLE_MSK     (3<<7)  /* Bit  9.. 7:  Cable Length Mask */
-#define PHY_M_PS_MDI_X_STAT    (1<<6)  /* Bit  6:      MDI Crossover Stat (1=MDIX) */
-#define PHY_M_PS_DOWNS_STAT    (1<<5)  /* Bit  5:      Downshift Status (1=downsh.) */
-#define PHY_M_PS_ENDET_STAT    (1<<4)  /* Bit  4:      Energy Detect Status (1=act) */
-#define PHY_M_PS_TX_P_EN       (1<<3)  /* Bit  3:      Tx Pause Enabled */
-#define PHY_M_PS_RX_P_EN       (1<<2)  /* Bit  2:      Rx Pause Enabled */
-#define PHY_M_PS_POL_REV       (1<<1)  /* Bit  1:      Polarity Reversed */
-#define PHY_M_PC_JABBER                (1<<0)  /* Bit  0:      Jabber */
-
-#define PHY_M_PS_PAUSE_MSK     (PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN)
-
-/*****  PHY_MARV_INT_MASK      16 bit r/w      Interrupt Mask Reg *****/
-/*****  PHY_MARV_INT_STAT      16 bit r/o      Interrupt Status Reg *****/
-#define PHY_M_IS_AN_ERROR      (1<<15) /* Bit 15:      Auto-Negotiation Error */
-#define PHY_M_IS_LSP_CHANGE    (1<<14) /* Bit 14:      Link Speed Changed */
-#define PHY_M_IS_DUP_CHANGE    (1<<13) /* Bit 13:      Duplex Mode Changed */
-#define PHY_M_IS_AN_PR         (1<<12) /* Bit 12:      Page Received */
-#define PHY_M_IS_AN_COMPL      (1<<11) /* Bit 11:      Auto-Negotiation Completed */
-#define PHY_M_IS_LST_CHANGE    (1<<10) /* Bit 10:      Link Status Changed */
-#define PHY_M_IS_SYMB_ERROR    (1<<9)  /* Bit  9:      Symbol Error */
-#define PHY_M_IS_FALSE_CARR    (1<<8)  /* Bit  8:      False Carrier */
-#define PHY_M_IS_FIFO_ERROR    (1<<7)  /* Bit  7:      FIFO Overflow/Underrun Error */
-#define PHY_M_IS_MDI_CHANGE    (1<<6)  /* Bit  6:      MDI Crossover Changed */
-#define PHY_M_IS_DOWNSH_DET    (1<<5)  /* Bit  5:      Downshift Detected */
-#define PHY_M_IS_END_CHANGE    (1<<4)  /* Bit  4:      Energy Detect Changed */
-                                                                       /* Bit  3..2:   reserved */
-#define PHY_M_IS_POL_CHANGE    (1<<1)  /* Bit  1:      Polarity Changed */
-#define PHY_M_IS_JABBER                (1<<0)  /* Bit  0:      Jabber */
-
-#define PHY_M_DEF_MSK          (PHY_M_IS_AN_ERROR | PHY_M_IS_AN_PR | \
-                                                       PHY_M_IS_LST_CHANGE | PHY_M_IS_FIFO_ERROR)
-
-/*****  PHY_MARV_EXT_CTRL      16 bit r/w      Ext. PHY Specific Ctrl *****/
-#define PHY_M_EC_M_DSC_MSK     (3<<10) /* Bit 11..10:  Master downshift counter */
-#define PHY_M_EC_S_DSC_MSK     (3<<8)  /* Bit  9.. 8:  Slave  downshift counter */
-#define PHY_M_EC_MAC_S_MSK     (7<<4)  /* Bit  6.. 4:  Def. MAC interface speed */
-
-#define PHY_M_EC_M_DSC(x)              SHIFT10(x)      /* 00=1x; 01=2x; 10=3x; 11=4x */
-#define PHY_M_EC_S_DSC(x)              SHIFT8(x)       /* 00=dis; 01=1x; 10=2x; 11=3x */
-#define PHY_M_EC_MAC_S(x)              SHIFT4(x)       /* 01X=0; 110=2.5; 111=25 (MHz) */
-
-#define MAC_TX_CLK_0_MHZ       2
-#define MAC_TX_CLK_2_5_MHZ     6
-#define MAC_TX_CLK_25_MHZ      7
-
-/*****  PHY_MARV_LED_CTRL      16 bit r/w      LED Control Reg *****/
-#define PHY_M_LEDC_DIS_LED     (1<<15) /* Bit 15:      Disable LED */
-#define PHY_M_LEDC_PULS_MSK    (7<<12) /* Bit 14..12:  Pulse Stretch Mask */
-#define PHY_M_LEDC_F_INT       (1<<11) /* Bit 11:      Force Interrupt */
-#define PHY_M_LEDC_BL_R_MSK    (7<<8)  /* Bit 10.. 8:  Blink Rate Mask */
-                                                                       /* Bit  7.. 5:  reserved */
-#define PHY_M_LEDC_LINK_MSK    (3<<3)  /* Bit  4.. 3:  Link Control Mask */
-#define PHY_M_LEDC_DP_CTRL     (1<<2)  /* Bit  2:      Duplex Control */
-#define PHY_M_LEDC_RX_CTRL     (1<<1)  /* Bit  1:      Rx activity / Link */
-#define PHY_M_LEDC_TX_CTRL     (1<<0)  /* Bit  0:      Tx activity / Link */
-
-#define PHY_M_LED_PULS_DUR(x)  SHIFT12(x)      /* Pulse Stretch Duration */
-
-#define        PULS_NO_STR             0               /* no pulse stretching */
-#define        PULS_21MS               1               /* 21 ms to 42 ms */
-#define PULS_42MS              2               /* 42 ms to 84 ms */
-#define PULS_84MS              3               /* 84 ms to 170 ms */
-#define PULS_170MS             4               /* 170 ms to 340 ms */
-#define PULS_340MS             5               /* 340 ms to 670 ms */
-#define PULS_670MS             6               /* 670 ms to 1.3 s */
-#define PULS_1300MS            7               /* 1.3 s to 2.7 s */
-
-#define PHY_M_LED_BLINK_RT(x)  SHIFT8(x)       /* Blink Rate */
-
-#define BLINK_42MS             0               /* 42 ms */
-#define BLINK_84MS             1               /* 84 ms */
-#define BLINK_170MS            2               /* 170 ms */
-#define BLINK_340MS            3               /* 340 ms */
-#define BLINK_670MS            4               /* 670 ms */
-                                                               /* values 5 - 7: reserved */
-
-/*****  PHY_MARV_LED_OVER      16 bit r/w      Manual LED Override Reg *****/
-#define PHY_M_LED_MO_DUP(x)            SHIFT10(x)      /* Bit 11..10:  Duplex */
-#define PHY_M_LED_MO_10(x)             SHIFT8(x)       /* Bit  9.. 8:  Link 10 */
-#define PHY_M_LED_MO_100(x)            SHIFT6(x)       /* Bit  7.. 6:  Link 100 */
-#define PHY_M_LED_MO_1000(x)   SHIFT4(x)       /* Bit  5.. 4:  Link 1000 */
-#define PHY_M_LED_MO_RX(x)             SHIFT2(x)       /* Bit  3.. 2:  Rx */
-#define PHY_M_LED_MO_TX(x)             SHIFT0(x)       /* Bit  1.. 0:  Tx */
-
-#define MO_LED_NORM                    0
-#define MO_LED_BLINK           1
-#define MO_LED_OFF                     2
-#define MO_LED_ON                      3
-
-/*****  PHY_MARV_EXT_CTRL_2    16 bit r/w      Ext. PHY Specific Ctrl 2 *****/
-                                                                       /* Bit 15.. 7:  reserved */
-#define PHY_M_EC2_FI_IMPED     (1<<6)  /* Bit  6:      Fiber Input  Impedance */
-#define PHY_M_EC2_FO_IMPED     (1<<5)  /* Bit  5:      Fiber Output Impedance */
-#define PHY_M_EC2_FO_M_CLK     (1<<4)  /* Bit  4:      Fiber Mode Clock Enable */
-#define PHY_M_EC2_FO_BOOST     (1<<3)  /* Bit  3:      Fiber Output Boost */
-#define PHY_M_EC2_FO_AM_MSK    7               /* Bit  2.. 0:  Fiber Output Amplitude */
-
-/*****  PHY_MARV_CABLE_DIAG    16 bit r/o      Cable Diagnostic Reg *****/
-#define PHY_M_CABD_ENA_TEST    (1<<15) /* Bit 15:      Enable Test */
-#define PHY_M_CABD_STAT_MSK    (3<<13) /* Bit 14..13:  Status */
-                                                                       /* Bit 12.. 8:  reserved */
-#define PHY_M_CABD_DIST_MSK    0xff    /* Bit  7.. 0:  Distance */
-
-/* values for Cable Diagnostic Status (11=fail; 00=OK; 10=open; 01=short) */
-#define CABD_STAT_NORMAL       0
-#define CABD_STAT_SHORT                1
-#define CABD_STAT_OPEN         2
-#define CABD_STAT_FAIL         3
-
-
-/*
- * GMAC registers
- *
- * The GMAC registers are 16 or 32 bits wide.
- * The GMACs host processor interface is 16 bits wide,
- * therefore ALL registers will be addressed with 16 bit accesses.
- *
- * The following macros are provided to access the GMAC registers
- * GM_IN16(), GM_OUT16, GM_IN32(), GM_OUT32(), GM_INADR(), GM_OUTADR(),
- * GM_INHASH(), and GM_OUTHASH().
- * The macros are defined in SkGeHw.h.
- *
- * Note:       NA reg  = Network Address e.g DA, SA etc.
- *
- */
-
-/* Port Registers */
-#define GM_GP_STAT             0x0000          /* 16 bit r/o   General Purpose Status */
-#define GM_GP_CTRL             0x0004          /* 16 bit r/w   General Purpose Control */
-#define GM_TX_CTRL             0x0008          /* 16 bit r/w   Transmit Control Reg. */
-#define GM_RX_CTRL             0x000c          /* 16 bit r/w   Receive Control Reg. */
-#define GM_TX_FLOW_CTRL        0x0010          /* 16 bit r/w   Transmit Flow Control */
-#define GM_TX_PARAM            0x0014          /* 16 bit r/w   Transmit Parameter Reg. */
-#define GM_SERIAL_MODE 0x0018          /* 16 bit r/w   Serial Mode Register */
-
-/* Source Address Registers */
-#define GM_SRC_ADDR_1L 0x001c          /* 16 bit r/w   Source Address 1 (low) */
-#define GM_SRC_ADDR_1M 0x0020          /* 16 bit r/w   Source Address 1 (middle) */
-#define GM_SRC_ADDR_1H 0x0024          /* 16 bit r/w   Source Address 1 (high) */
-#define GM_SRC_ADDR_2L 0x0028          /* 16 bit r/w   Source Address 2 (low) */
-#define GM_SRC_ADDR_2M 0x002c          /* 16 bit r/w   Source Address 2 (middle) */
-#define GM_SRC_ADDR_2H 0x0030          /* 16 bit r/w   Source Address 2 (high) */
-
-/* Multicast Address Hash Registers */
-#define GM_MC_ADDR_H1  0x0034          /* 16 bit r/w   Multicast Address Hash 1 */
-#define GM_MC_ADDR_H2  0x0038          /* 16 bit r/w   Multicast Address Hash 2 */
-#define GM_MC_ADDR_H3  0x003c          /* 16 bit r/w   Multicast Address Hash 3 */
-#define GM_MC_ADDR_H4  0x0040          /* 16 bit r/w   Multicast Address Hash 4 */
-
-/* Interrupt Source Registers */
-#define GM_TX_IRQ_SRC  0x0044          /* 16 bit r/o   Tx Overflow IRQ Source */
-#define GM_RX_IRQ_SRC  0x0048          /* 16 bit r/o   Rx Overflow IRQ Source */
-#define GM_TR_IRQ_SRC  0x004c          /* 16 bit r/o   Tx/Rx Over. IRQ Source */
-
-/* Interrupt Mask Registers */
-#define GM_TX_IRQ_MSK  0x0050          /* 16 bit r/w   Tx Overflow IRQ Mask */
-#define GM_RX_IRQ_MSK  0x0054          /* 16 bit r/w   Rx Overflow IRQ Mask */
-#define GM_TR_IRQ_MSK  0x0058          /* 16 bit r/w   Tx/Rx Over. IRQ Mask */
-
-/* Serial Management Interface (SMI) Registers */
-#define GM_SMI_CTRL            0x0080          /* 16 bit r/w   SMI Control Register */
-#define GM_SMI_DATA            0x0084          /* 16 bit r/w   SMI Data Register */
-#define GM_PHY_ADDR            0x0088          /* 16 bit r/w   GPHY Address Register */
-
-/* MIB Counters */
-#define GM_MIB_CNT_BASE        0x0100          /* Base Address of MIB Counters */
-#define GM_MIB_CNT_SIZE        44                      /* Number of MIB Counters */
-
-/*
- * MIB Counters base address definitions (low word) -
- * use offset 4 for access to high word        (32 bit r/o)
- */
-#define GM_RXF_UC_OK \
-                       (GM_MIB_CNT_BASE + 0)   /* Unicast Frames Received OK */
-#define GM_RXF_BC_OK \
-                       (GM_MIB_CNT_BASE + 8)   /* Broadcast Frames Received OK */
-#define GM_RXF_MPAUSE \
-                       (GM_MIB_CNT_BASE + 16)  /* Pause MAC Ctrl Frames Received */
-#define GM_RXF_MC_OK \
-                       (GM_MIB_CNT_BASE + 24)  /* Multicast Frames Received OK */
-#define GM_RXF_FCS_ERR \
-                       (GM_MIB_CNT_BASE + 32)  /* Rx Frame Check Seq. Error */
-       /* GM_MIB_CNT_BASE + 40:        reserved */
-#define GM_RXO_OK_LO \
-                       (GM_MIB_CNT_BASE + 48)  /* Octets Received OK Low */
-#define GM_RXO_OK_HI \
-                       (GM_MIB_CNT_BASE + 56)  /* Octets Received OK High */
-#define GM_RXO_ERR_LO \
-                       (GM_MIB_CNT_BASE + 64)  /* Octets Received Invalid Low */
-#define GM_RXO_ERR_HI \
-                       (GM_MIB_CNT_BASE + 72)  /* Octets Received Invalid High */
-#define GM_RXF_SHT \
-                       (GM_MIB_CNT_BASE + 80)  /* Frames <64 Byte Received OK */
-#define GM_RXE_FRAG \
-                       (GM_MIB_CNT_BASE + 88)  /* Frames <64 Byte Receeived with FCS Err */
-#define GM_RXF_64B \
-                       (GM_MIB_CNT_BASE + 96)  /* 64 Byte Rx Frame */
-#define GM_RXF_127B \
-                       (GM_MIB_CNT_BASE + 104) /* 65-127 Byte Rx Frame */
-#define GM_RXF_255B \
-                       (GM_MIB_CNT_BASE + 112) /* 128-255 Byte Rx Frame */
-#define GM_RXF_511B \
-                       (GM_MIB_CNT_BASE + 120) /* 256-511 Byte Rx Frame */
-#define GM_RXF_1023B \
-                       (GM_MIB_CNT_BASE + 128) /* 512-1023 Byte Rx Frame */
-#define GM_RXF_1518B \
-                       (GM_MIB_CNT_BASE + 136) /* 1024-1518 Byte Rx Frame */
-#define GM_RXF_MAX_SZ \
-                       (GM_MIB_CNT_BASE + 144) /* 1519-MaxSize Byte Rx Frame */
-#define GM_RXF_LNG_ERR \
-                       (GM_MIB_CNT_BASE + 152) /* Rx Frame too Long Error */
-#define GM_RXF_JAB_PKT \
-                       (GM_MIB_CNT_BASE + 160) /* Rx Jabber Packet Frame */
-       /* GM_MIB_CNT_BASE + 168:       reserved */
-#define GM_RXE_FIFO_OV \
-                       (GM_MIB_CNT_BASE + 176) /* Rx FIFO overflow Event */
-       /* GM_MIB_CNT_BASE + 184:       reserved */
-#define GM_TXF_UC_OK \
-                       (GM_MIB_CNT_BASE + 192) /* Unicast Frames Xmitted OK */
-#define GM_TXF_BC_OK \
-                       (GM_MIB_CNT_BASE + 200) /* Broadcast Frames Xmitted OK */
-#define GM_TXF_MPAUSE \
-                       (GM_MIB_CNT_BASE + 208) /* Pause MAC Ctrl Frames Xmitted */
-#define GM_TXF_MC_OK \
-                       (GM_MIB_CNT_BASE + 216) /* Multicast Frames Xmitted OK */
-#define GM_TXO_OK_LO \
-                       (GM_MIB_CNT_BASE + 224) /* Octets Transmitted OK Low */
-#define GM_TXO_OK_HI \
-                       (GM_MIB_CNT_BASE + 232) /* Octets Transmitted OK High */
-#define GM_TXF_64B \
-                       (GM_MIB_CNT_BASE + 240) /* 64 Byte Tx Frame */
-#define GM_TXF_127B \
-                       (GM_MIB_CNT_BASE + 248) /* 65-127 Byte Tx Frame */
-#define GM_TXF_255B \
-                       (GM_MIB_CNT_BASE + 256) /* 128-255 Byte Tx Frame */
-#define GM_TXF_511B \
-                       (GM_MIB_CNT_BASE + 264) /* 256-511 Byte Tx Frame */
-#define GM_TXF_1023B \
-                       (GM_MIB_CNT_BASE + 272) /* 512-1023 Byte Tx Frame */
-#define GM_TXF_1518B \
-                       (GM_MIB_CNT_BASE + 280) /* 1024-1518 Byte Tx Frame */
-#define GM_TXF_MAX_SZ \
-                       (GM_MIB_CNT_BASE + 288) /* 1519-MaxSize Byte Tx Frame */
-       /* GM_MIB_CNT_BASE + 296:       reserved */
-#define GM_TXF_COL \
-                       (GM_MIB_CNT_BASE + 304) /* Tx Collision */
-#define GM_TXF_LAT_COL \
-                       (GM_MIB_CNT_BASE + 312) /* Tx Late Collision */
-#define GM_TXF_ABO_COL \
-                       (GM_MIB_CNT_BASE + 320) /* Tx aborted due to Exces. Col. */
-#define GM_TXF_MUL_COL \
-                       (GM_MIB_CNT_BASE + 328) /* Tx Multiple Collision */
-#define GM_TXF_SNG_COL \
-                       (GM_MIB_CNT_BASE + 336) /* Tx Single Collision */
-#define GM_TXE_FIFO_UR \
-                       (GM_MIB_CNT_BASE + 344) /* Tx FIFO Underrun Event */
-
-/*----------------------------------------------------------------------------*/
-/*
- * GMAC Bit Definitions
- *
- * If the bit access behaviour differs from the register access behaviour
- * (r/w, r/o) this is documented after the bit number.
- * The following bit access behaviours are used:
- *     (sc)    self clearing
- *     (r/o)   read only
- */
-
-/*     GM_GP_STAT      16 bit r/o      General Purpose Status Register */
-
-#define GM_GPSR_SPEED          (1<<15) /* Bit 15:      Port Speed (1 = 100 Mbps) */
-#define GM_GPSR_DUPLEX         (1<<14) /* Bit 14:      Duplex Mode (1 = Full) */
-#define GM_GPSR_FC_TX_DIS      (1<<13) /* Bit 13:      Tx Flow Control Mode Disabled */
-#define GM_GPSR_LINK_UP                (1<<12) /* Bit 12:      Link Up Status */
-#define GM_GPSR_PAUSE          (1<<11) /* Bit 11:      Pause State */
-#define GM_GPSR_TX_ACTIVE      (1<<10) /* Bit 10:      Tx in Progress */
-#define GM_GPSR_EXC_COL                (1<<9)  /* Bit  9:      Excessive Collisions Occured */
-#define GM_GPSR_LAT_COL                (1<<8)  /* Bit  8:      Late Collisions Occured */
-                                                               /* Bit  7..6:   reserved */
-#define GM_GPSR_PHY_ST_CH      (1<<5)  /* Bit  5:      PHY Status Change */
-#define GM_GPSR_GIG_SPEED      (1<<4)  /* Bit  4:      Gigabit Speed (1 = 1000 Mbps) */
-#define GM_GPSR_PART_MODE      (1<<3)  /* Bit  3:      Partition mode */
-#define GM_GPSR_FC_RX_DIS      (1<<2)  /* Bit  2:      Rx Flow Control Mode Disabled */
-#define GM_GPSR_PROM_EN                (1<<1)  /* Bit  1:      Promiscuous Mode Enabled */
-                                                               /* Bit  0:      reserved */
-
-/*     GM_GP_CTRL      16 bit r/w      General Purpose Control Register */
-                                                               /* Bit 15:      reserved */
-#define GM_GPCR_PROM_ENA       (1<<14) /* Bit 14:      Enable Promiscuous Mode */
-#define GM_GPCR_FC_TX_DIS      (1<<13) /* Bit 13:      Disable Tx Flow Control Mode */
-#define GM_GPCR_TX_ENA         (1<<12) /* Bit 12:      Enable Transmit */
-#define GM_GPCR_RX_ENA         (1<<11) /* Bit 11:      Enable Receive */
-#define GM_GPCR_BURST_ENA      (1<<10) /* Bit 10:      Enable Burst Mode */
-#define GM_GPCR_LOOP_ENA       (1<<9)  /* Bit  9:      Enable MAC Loopback Mode */
-#define GM_GPCR_PART_ENA       (1<<8)  /* Bit  8:      Enable Partition Mode */
-#define GM_GPCR_GIGS_ENA       (1<<7)  /* Bit  7:      Gigabit Speed (1000 Mbps) */
-#define GM_GPCR_FL_PASS                (1<<6)  /* Bit  6:      Force Link Pass */
-#define GM_GPCR_DUP_FULL       (1<<5)  /* Bit  5:      Full Duplex Mode */
-#define GM_GPCR_FC_RX_DIS      (1<<4)  /* Bit  4:      Disable Rx Flow Control Mode */
-#define GM_GPCR_SPEED_100      (1<<3)  /* Bit  3:      Port Speed 100 Mbps */
-#define GM_GPCR_AU_DUP_DIS     (1<<2)  /* Bit  2:      Disable Auto-Update for Duplex */
-#define GM_GPCR_AU_FCT_DIS     (1<<1)  /* Bit  1:      Disable Auto-Update for Flow-c. */
-#define GM_GPCR_AU_SPD_DIS     (1<<0)  /* Bit  0:      Disable Auto-Update for Speed */
-
-#define GM_GPCR_SPEED_1000     (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
-#define GM_GPCR_AU_ALL_DIS     (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |\
-                                                        GM_GPCR_AU_SPD_DIS)
-
-/*     GM_TX_CTRL                              16 bit r/w      Transmit Control Register */
-
-#define GM_TXCR_FORCE_JAM      (1<<15) /* Bit 15:      Force Jam / Flow-Control */
-#define GM_TXCR_CRC_DIS                (1<<14) /* Bit 14:      Disable insertion of CRC */
-#define GM_TXCR_PAD_DIS                (1<<13) /* Bit 13:      Disable padding of packets */
-#define GM_TXCR_COL_THR                (4<<10) /* Bit 12..10:  Collision Threshold */
-
-/*     GM_RX_CTRL                              16 bit r/w      Receive Control Register */
-#define GM_RXCR_UCF_ENA                (1<<15) /* Bit 15:      Enable Unicast filtering */
-#define GM_RXCR_MCF_ENA                (1<<14) /* Bit 14:      Enable Multicast filtering */
-#define GM_RXCR_CRC_DIS                (1<<13) /* Bit 13:      Remove 4-byte CRC */
-#define GM_RXCR_PASS_FC                (1<<12) /* Bit 12:      Pass FC packets to FIFO */
-
-/*     GM_TX_PARAM                             16 bit r/w      Transmit Parameter Register */
-#define GM_TXPA_JAMLEN_MSK     (0x03<<14)      /* Bit 15..14:  Jam Length */
-#define GM_TXPA_JAMIPG_MSK     (0x1f<<9)       /* Bit 13..9:   Jam IPG */
-#define GM_TXPA_JAMDAT_MSK     (0x1f<<4)       /* Bit  8..4:   IPG Jam to Data */
-                                                               /* Bit  3..0:   reserved */
-#define JAM_LEN_VAL(x)         SHIFT14(x)
-#define JAM_IPG_VAL(x)         SHIFT9(x)
-#define IPG_JAM_DATA(x)                SHIFT4(x)
-
-/*     GM_SERIAL_MODE                  16 bit r/w      Serial Mode Register */
-#define GM_SMOD_DATABL_MSK     (0x1f<<11)      /* Bit 15..11:  Data Blinder */
-#define GM_SMOD_LIMIT_4                (1<<10) /* Bit 10:      4 consecutive transmit trials */
-#define GM_SMOD_VLAN_ENA       (1<<9)  /* Bit  9:      Enable VLAN  (Max. Frame Length) */
-#define GM_SMOD_JUMBO_ENA      (1<<8)  /* Bit  8:      Enable Jumbo (Max. Frame Length) */
-                                                               /* Bit  7..5:   reserved */
-#define GM_SMOD_IPG_MSK                0x1f    /* Bit 4..0:    Inter-Packet Gap (IPG) */
-
-#define DATA_BLIND_VAL(x)      SHIFT11(x)
-#define DATA_BLIND_FAST_ETH    0x1c
-#define DATA_BLIND_GIGABIT     4
-
-#define IPG_VAL_FAST_ETH       0x1e
-#define IPG_VAL_GIGABIT                6
-
-/*     GM_SMI_CTRL                             16 bit r/w      SMI Control Register */
-
-#define GM_SMI_CT_PHY_AD(x)    SHIFT11(x)
-#define GM_SMI_CT_REG_AD(x)    SHIFT6(x)
-#define GM_SMI_CT_OP_RD                (1<<5)  /* Bit  5:      OpCode Read (0=Write)*/
-#define GM_SMI_CT_RD_VAL       (1<<4)  /* Bit  4:      Read Valid (Read completed) */
-#define GM_SMI_CT_BUSY         (1<<3)  /* Bit  3:      Busy (Operation in progress) */
-                                                               /* Bit   2..0:  reserved */
-
-/*     GM_PHY_ADDR                             16 bit r/w      GPHY Address Register */
-                                                               /* Bit  15..6:  reserved */
-#define GM_PAR_MIB_CLR         (1<<5)  /* Bit  5:      Set MIB Clear Counter Mode */
-#define GM_PAR_MIB_TST         (1<<4)  /* Bit  4:      MIB Load Counter (Test Mode) */
-                                                               /* Bit   3..0:  reserved */
-
-/* Receive Frame Status Encoding */
-#define GMR_FS_LEN     (0xffffUL<<16)  /* Bit 31..16:  Rx Frame Length */
-                                                               /* Bit  15..14: reserved */
-#define GMR_FS_VLAN            (1L<<13)        /* Bit 13:      VLAN Packet */
-#define GMR_FS_JABBER  (1L<<12)        /* Bit 12:      Jabber Packet */
-#define GMR_FS_UN_SIZE (1L<<11)        /* Bit 11:      Undersize Packet */
-#define GMR_FS_MC              (1L<<10)        /* Bit 10:      Multicast Packet */
-#define GMR_FS_BC              (1L<<9)         /* Bit  9:      Broadcast Packet */
-#define GMR_FS_RX_OK   (1L<<8)         /* Bit  8:      Receive OK (Good Packet) */
-#define GMR_FS_GOOD_FC (1L<<7)         /* Bit  7:      Good Flow-Control Packet */
-#define GMR_FS_BAD_FC  (1L<<6)         /* Bit  6:      Bad  Flow-Control Packet */
-#define GMR_FS_MII_ERR (1L<<5)         /* Bit  5:      MII Error */
-#define GMR_FS_LONG_ERR        (1L<<4)         /* Bit  4:      Too Long Packet */
-#define GMR_FS_FRAGMENT        (1L<<3)         /* Bit  3:      Fragment */
-                                                               /* Bit  2:      reserved */
-#define GMR_FS_CRC_ERR (1L<<1)         /* Bit  1:      CRC Error */
-#define GMR_FS_RX_FF_OV        (1L<<0)         /* Bit  0:      Rx FIFO Overflow */
-
-/*
- * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR)
- */
-#define GMR_FS_ANY_ERR (GMR_FS_CRC_ERR | \
-                       GMR_FS_LONG_ERR | \
-                       GMR_FS_MII_ERR | \
-                       GMR_FS_BAD_FC | \
-                       GMR_FS_GOOD_FC | \
-                       GMR_FS_JABBER)
-
-/* Rx GMAC FIFO Flush Mask (default) */
-#define RX_FF_FL_DEF_MSK       (GMR_FS_CRC_ERR | \
-                       GMR_FS_RX_FF_OV | \
-                       GMR_FS_MII_ERR | \
-                       GMR_FS_BAD_FC | \
-                       GMR_FS_GOOD_FC | \
-                       GMR_FS_UN_SIZE | \
-                       GMR_FS_JABBER)
-
-/* typedefs *******************************************************************/
-
-
-/* function prototypes ********************************************************/
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_XMAC_H */
diff --git a/drivers/sk98lin/skaddr.c b/drivers/sk98lin/skaddr.c
deleted file mode 100644 (file)
index ed79c04..0000000
+++ /dev/null
@@ -1,1879 +0,0 @@
-/******************************************************************************
- *
- * Name:       skaddr.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.48 $
- * Date:       $Date: 2003/02/12 17:09:37 $
- * Purpose:    Manage Addresses (Multicast and Unicast) and Promiscuous Mode.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skaddr.c,v $
- *     Revision 1.48  2003/02/12 17:09:37  tschilli
- *     Fix in SkAddrOverride() to set both (physical and logical) MAC addresses
- *     in case that both addresses are identical.
- *
- *     Revision 1.47  2002/09/17 06:31:10  tschilli
- *     Handling of SK_PROM_MODE_ALL_MC flag in SkAddrGmacMcUpdate()
- *     and SkAddrGmacPromiscuousChange() fixed.
- *     Editorial changes.
- *
- *     Revision 1.46  2002/08/22 07:55:41  tschilli
- *     New function SkGmacMcHash() for GMAC multicast hashing algorithm added.
- *     Editorial changes.
- *
- *     Revision 1.45  2002/08/15 12:29:35  tschilli
- *     SkAddrGmacMcUpdate() and SkAddrGmacPromiscuousChange() changed.
- *
- *     Revision 1.44  2002/08/14 12:18:03  rschmidt
- *     Replaced direct handling of MAC Hashing (XMAC and GMAC)
- *     with routine SkMacHashing().
- *     Replaced wrong 3rd para 'i' with 'PortNumber' in SkMacPromiscMode().
- *
- *     Revision 1.43  2002/08/13 09:37:43  rschmidt
- *     Corrected some SK_DBG_MSG outputs.
- *     Replaced wrong 2nd para pAC with IoC in SkMacPromiscMode().
- *     Editorial changes.
- *
- *     Revision 1.42  2002/08/12 11:24:36  rschmidt
- *     Remove setting of logical MAC address GM_SRC_ADDR_2 in SkAddrInit().
- *     Replaced direct handling of MAC Promiscuous Mode (XMAC and GMAC)
- *     with routine SkMacPromiscMode().
- *     Editorial changes.
- *
- *     Revision 1.41  2002/06/10 13:52:18  tschilli
- *     Changes for handling YUKON.
- *     All changes are internally and not visible to the programmer
- *     using this module.
- *
- *     Revision 1.40  2001/02/14 14:04:59  rassmann
- *     Editorial changes.
- *
- *     Revision 1.39  2001/01/30 10:30:04  rassmann
- *     Editorial changes.
- *
- *     Revision 1.38  2001/01/25 16:26:52  rassmann
- *     Ensured that logical address overrides are done on net's active port.
- *
- *     Revision 1.37  2001/01/22 13:41:34  rassmann
- *     Supporting two nets on dual-port adapters.
- *
- *     Revision 1.36  2000/08/07 11:10:39  rassmann
- *     Editorial changes.
- *
- *     Revision 1.35  2000/05/04 09:38:41  rassmann
- *     Editorial changes.
- *     Corrected multicast address hashing.
- *
- *     Revision 1.34  1999/11/22 13:23:44  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.33  1999/05/28 10:56:06  rassmann
- *     Editorial changes.
- *
- *     Revision 1.32  1999/03/31 10:59:20  rassmann
- *     Returning Success instead of DupAddr if address shall be overridden
- *     with same value.
- *
- *     Revision 1.31  1999/01/14 16:18:17  rassmann
- *     Corrected multicast initialization.
- *
- *     Revision 1.30  1999/01/04 10:30:35  rassmann
- *     SkAddrOverride only possible after SK_INIT_IO phase.
- *
- *     Revision 1.29  1998/12/29 13:13:10  rassmann
- *     An address override is now preserved in the SK_INIT_IO phase.
- *     All functions return an int now.
- *     Extended parameter checking.
- *
- *     Revision 1.28  1998/12/01 11:45:53  rassmann
- *     Code cleanup.
- *
- *     Revision 1.27  1998/12/01 09:22:49  rassmann
- *     SkAddrMcAdd and SkAddrMcUpdate returned SK_MC_FILTERING_INEXACT
- *     too often.
- *
- *     Revision 1.26  1998/11/24 12:39:44  rassmann
- *     Reserved multicast entry for BPDU address.
- *     13 multicast entries left for protocol.
- *
- *     Revision 1.25  1998/11/17 16:54:23  rassmann
- *     Using exact match for up to 14 multicast addresses.
- *     Still receiving all multicasts if more addresses are added.
- *
- *     Revision 1.24  1998/11/13 17:24:31  rassmann
- *     Changed return value of SkAddrOverride to int.
- *
- *     Revision 1.23  1998/11/13 16:56:18  rassmann
- *     Added macro SK_ADDR_COMPARE.
- *     Changed return type of SkAddrOverride to SK_BOOL.
- *
- *     Revision 1.22  1998/11/04 17:06:17  rassmann
- *     Corrected McUpdate and PromiscuousChange functions.
- *
- *     Revision 1.21  1998/10/29 14:34:04  rassmann
- *     Clearing SK_ADDR struct at startup.
- *
- *     Revision 1.20  1998/10/28 18:16:34  rassmann
- *     Avoiding I/Os before SK_INIT_RUN level.
- *     Aligning InexactFilter.
- *
- *     Revision 1.19  1998/10/28 11:29:28  rassmann
- *     Programming physical address in SkAddrMcUpdate.
- *     Corrected programming of exact match entries.
- *
- *     Revision 1.18  1998/10/28 10:34:48  rassmann
- *     Corrected reading of physical addresses.
- *
- *     Revision 1.17  1998/10/28 10:26:13  rassmann
- *     Getting ports' current MAC addresses from EPROM now.
- *     Added debug output.
- *
- *     Revision 1.16  1998/10/27 16:20:12  rassmann
- *     Reading MAC address byte by byte.
- *
- *     Revision 1.15  1998/10/22 11:39:09  rassmann
- *     Corrected signed/unsigned mismatches.
- *
- *     Revision 1.14  1998/10/19 17:12:35  rassmann
- *     Syntax corrections.
- *
- *     Revision 1.13  1998/10/19 17:02:19  rassmann
- *     Now reading permanent MAC addresses from CRF.
- *
- *     Revision 1.12  1998/10/15 15:15:48  rassmann
- *     Changed Flags Parameters from SK_U8 to int.
- *     Checked with lint.
- *
- *     Revision 1.11  1998/09/24 19:15:12  rassmann
- *     Code cleanup.
- *
- *     Revision 1.10  1998/09/18 20:18:54  rassmann
- *     Added HW access.
- *     Implemented swapping.
- *
- *     Revision 1.9  1998/09/16 11:32:00  rassmann
- *     Including skdrv1st.h again. :(
- *
- *     Revision 1.8  1998/09/16 11:09:34  rassmann
- *     Syntax corrections.
- *
- *     Revision 1.7  1998/09/14 17:06:34  rassmann
- *     Minor changes.
- *
- *     Revision 1.6  1998/09/07 08:45:41  rassmann
- *     Syntax corrections.
- *
- *     Revision 1.5  1998/09/04 19:40:19  rassmann
- *     Interface enhancements.
- *
- *     Revision 1.4  1998/09/04 12:14:12  rassmann
- *     Interface cleanup.
- *
- *     Revision 1.3  1998/09/02 16:56:40  rassmann
- *     Updated interface.
- *
- *     Revision 1.2  1998/08/27 14:26:09  rassmann
- *     Updated interface.
- *
- *     Revision 1.1  1998/08/21 08:30:22  rassmann
- *     First public version.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This module is intended to manage multicast addresses, address override,
- * and promiscuous mode on GEnesis and Yukon adapters.
- *
- * Address Layout:
- *     port address:           physical MAC address
- *     1st exact match:        logical MAC address (GEnesis only)
- *     2nd exact match:        RLMT multicast (GEnesis only)
- *     exact match 3-13:       OS-specific multicasts (GEnesis only)
- *
- * Include File Hierarchy:
- *
- *     "skdrv1st.h"
- *     "skdrv2nd.h"
- *
- ******************************************************************************/
-
-#include <config.h>
-
-#ifdef CONFIG_SK98
-
-#ifndef        lint
-static const char SysKonnectFileId[] =
-       "@(#) $Id: skaddr.c,v 1.48 2003/02/12 17:09:37 tschilli Exp $ (C) SysKonnect.";
-#endif /* !defined(lint) */
-
-#define __SKADDR_C
-
-#ifdef __cplusplus
-#error C++ is not yet supported.
-extern "C" {
-#endif /* cplusplus */
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-
-/* defines ********************************************************************/
-
-
-#define XMAC_POLY      0xEDB88320UL    /* CRC32-Poly - XMAC: Little Endian */
-#define GMAC_POLY      0x04C11DB7L     /* CRC16-Poly - GMAC: Little Endian */
-#define HASH_BITS      6                               /* #bits in hash */
-#define        SK_MC_BIT       0x01
-
-/* Error numbers and messages. */
-
-#define SKERR_ADDR_E001                (SK_ERRBASE_ADDR + 0)
-#define SKERR_ADDR_E001MSG     "Bad Flags."
-#define SKERR_ADDR_E002                (SKERR_ADDR_E001 + 1)
-#define SKERR_ADDR_E002MSG     "New Error."
-
-/* typedefs *******************************************************************/
-
-/* None. */
-
-/* global variables ***********************************************************/
-
-/* 64-bit hash values with all bits set. */
-
-SK_U16 OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
-
-/* local variables ************************************************************/
-
-#ifdef DEBUG
-static int     Next0[SK_MAX_MACS] = {0, 0};
-#endif /* DEBUG */
-
-/* functions ******************************************************************/
-
-/******************************************************************************
- *
- *     SkAddrInit - initialize data, set state to init
- *
- * Description:
- *
- *     SK_INIT_DATA
- *     ============
- *
- *     This routine clears the multicast tables and resets promiscuous mode.
- *     Some entries are reserved for the "logical MAC address", the
- *     SK-RLMT multicast address, and the BPDU multicast address.
- *
- *
- *     SK_INIT_IO
- *     ==========
- *
- *     All permanent MAC addresses are read from EPROM.
- *     If the current MAC addresses are not already set in software,
- *     they are set to the values of the permanent addresses.
- *     The current addresses are written to the corresponding MAC.
- *
- *
- *     SK_INIT_RUN
- *     ===========
- *
- *     Nothing.
- *
- * Context:
- *     init, pageable
- *
- * Returns:
- *     SK_ADDR_SUCCESS
- */
-int    SkAddrInit(
-SK_AC  *pAC,   /* the adapter context */
-SK_IOC IoC,    /* I/O context */
-int            Level)  /* initialization level */
-{
-       int                     j;
-       SK_U32          i;
-       SK_U8           *InAddr;
-       SK_U16          *OutAddr;
-       SK_ADDR_PORT    *pAPort;
-
-       switch (Level) {
-       case SK_INIT_DATA:
-               SK_MEMSET((char *) &pAC->Addr, 0, sizeof(SK_ADDR));
-
-               for (i = 0; i < SK_MAX_MACS; i++) {
-                       pAPort = &pAC->Addr.Port[i];
-                       pAPort->PromMode = SK_PROM_MODE_NONE;
-
-                       pAPort->FirstExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
-                       pAPort->FirstExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
-                       pAPort->NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
-                       pAPort->NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
-               }
-#ifdef xDEBUG
-               for (i = 0; i < SK_MAX_MACS; i++) {
-                       if (pAC->Addr.Port[i].NextExactMatchRlmt <
-                               SK_ADDR_FIRST_MATCH_RLMT) {
-                               Next0[i] |= 4;
-                       }
-               }
-#endif /* DEBUG */
-               /* pAC->Addr.InitDone = SK_INIT_DATA; */
-               break;
-
-       case SK_INIT_IO:
-               for (i = 0; i < SK_MAX_NETS; i++) {
-                       pAC->Addr.Net[i].ActivePort = pAC->Rlmt.Net[i].ActivePort;
-               }
-#ifdef xDEBUG
-               for (i = 0; i < SK_MAX_MACS; i++) {
-                       if (pAC->Addr.Port[i].NextExactMatchRlmt <
-                               SK_ADDR_FIRST_MATCH_RLMT) {
-                               Next0[i] |= 8;
-                       }
-               }
-#endif /* DEBUG */
-
-               /* Read permanent logical MAC address from Control Register File. */
-               for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
-                       InAddr = (SK_U8 *) &pAC->Addr.Net[0].PermanentMacAddress.a[j];
-                       SK_IN8(IoC, B2_MAC_1 + j, InAddr);
-               }
-
-               if (!pAC->Addr.Net[0].CurrentMacAddressSet) {
-                       /* Set the current logical MAC address to the permanent one. */
-                       pAC->Addr.Net[0].CurrentMacAddress =
-                               pAC->Addr.Net[0].PermanentMacAddress;
-                       pAC->Addr.Net[0].CurrentMacAddressSet = SK_TRUE;
-               }
-
-               /* Set the current logical MAC address. */
-               pAC->Addr.Port[pAC->Addr.Net[0].ActivePort].Exact[0] =
-                       pAC->Addr.Net[0].CurrentMacAddress;
-#if SK_MAX_NETS > 1
-               /* Set logical MAC address for net 2 to (log | 3). */
-               if (!pAC->Addr.Net[1].CurrentMacAddressSet) {
-                       pAC->Addr.Net[1].PermanentMacAddress =
-                               pAC->Addr.Net[0].PermanentMacAddress;
-                       pAC->Addr.Net[1].PermanentMacAddress.a[5] |= 3;
-                       /* Set the current logical MAC address to the permanent one. */
-                       pAC->Addr.Net[1].CurrentMacAddress =
-                               pAC->Addr.Net[1].PermanentMacAddress;
-                       pAC->Addr.Net[1].CurrentMacAddressSet = SK_TRUE;
-               }
-#endif /* SK_MAX_NETS > 1 */
-
-#ifdef DEBUG
-               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
-                               ("Permanent MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
-                                       i,
-                                       pAC->Addr.Net[i].PermanentMacAddress.a[0],
-                                       pAC->Addr.Net[i].PermanentMacAddress.a[1],
-                                       pAC->Addr.Net[i].PermanentMacAddress.a[2],
-                                       pAC->Addr.Net[i].PermanentMacAddress.a[3],
-                                       pAC->Addr.Net[i].PermanentMacAddress.a[4],
-                                       pAC->Addr.Net[i].PermanentMacAddress.a[5]))
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
-                               ("Logical MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
-                                       i,
-                                       pAC->Addr.Net[i].CurrentMacAddress.a[0],
-                                       pAC->Addr.Net[i].CurrentMacAddress.a[1],
-                                       pAC->Addr.Net[i].CurrentMacAddress.a[2],
-                                       pAC->Addr.Net[i].CurrentMacAddress.a[3],
-                                       pAC->Addr.Net[i].CurrentMacAddress.a[4],
-                                       pAC->Addr.Net[i].CurrentMacAddress.a[5]))
-               }
-#endif /* DEBUG */
-
-               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
-                       pAPort = &pAC->Addr.Port[i];
-
-                       /* Read permanent port addresses from Control Register File. */
-                       for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
-                               InAddr = (SK_U8 *) &pAPort->PermanentMacAddress.a[j];
-                               SK_IN8(IoC, B2_MAC_2 + 8 * i + j, InAddr);
-                       }
-
-                       if (!pAPort->CurrentMacAddressSet) {
-                               /*
-                                * Set the current and previous physical MAC address
-                                * of this port to its permanent MAC address.
-                                */
-                               pAPort->CurrentMacAddress = pAPort->PermanentMacAddress;
-                               pAPort->PreviousMacAddress = pAPort->PermanentMacAddress;
-                               pAPort->CurrentMacAddressSet = SK_TRUE;
-                       }
-
-                       /* Set port's current physical MAC address. */
-                       OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
-
-                       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-                               XM_OUTADDR(IoC, i, XM_SA, OutAddr);
-                       }
-                       else {
-                               GM_OUTADDR(IoC, i, GM_SRC_ADDR_1L, OutAddr);
-                       }
-#ifdef DEBUG
-                       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
-                               ("SkAddrInit: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
-                                       pAPort->PermanentMacAddress.a[0],
-                                       pAPort->PermanentMacAddress.a[1],
-                                       pAPort->PermanentMacAddress.a[2],
-                                       pAPort->PermanentMacAddress.a[3],
-                                       pAPort->PermanentMacAddress.a[4],
-                                       pAPort->PermanentMacAddress.a[5]))
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
-                               ("SkAddrInit: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
-                                       pAPort->CurrentMacAddress.a[0],
-                                       pAPort->CurrentMacAddress.a[1],
-                                       pAPort->CurrentMacAddress.a[2],
-                                       pAPort->CurrentMacAddress.a[3],
-                                       pAPort->CurrentMacAddress.a[4],
-                                       pAPort->CurrentMacAddress.a[5]))
-#endif /* DEBUG */
-               }
-               /* pAC->Addr.InitDone = SK_INIT_IO; */
-               break;
-
-       case SK_INIT_RUN:
-#ifdef xDEBUG
-               for (i = 0; i < SK_MAX_MACS; i++) {
-                       if (pAC->Addr.Port[i].NextExactMatchRlmt <
-                               SK_ADDR_FIRST_MATCH_RLMT) {
-                               Next0[i] |= 16;
-                       }
-               }
-#endif /* DEBUG */
-
-               /* pAC->Addr.InitDone = SK_INIT_RUN; */
-               break;
-
-       default:        /* error */
-               break;
-       }
-
-       return (SK_ADDR_SUCCESS);
-
-}      /* SkAddrInit */
-
-
-/******************************************************************************
- *
- *     SkAddrMcClear - clear the multicast table
- *
- * Description:
- *     This routine clears the multicast table.
- *
- *     If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
- *     immediately.
- *
- *     It calls either SkAddrXmacMcClear or SkAddrGmacMcClear, according
- *     to the adapter in use. The real work is done there.
- *
- * Context:
- *     runtime, pageable
- *     may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
- *     may be called after SK_INIT_IO without limitation
- *
- * Returns:
- *     SK_ADDR_SUCCESS
- *     SK_ADDR_ILLEGAL_PORT
- */
-int    SkAddrMcClear(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* I/O context */
-SK_U32 PortNumber,     /* Index of affected port */
-int            Flags)          /* permanent/non-perm, sw-only */
-{
-       int ReturnCode;
-
-       if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
-               return (SK_ADDR_ILLEGAL_PORT);
-       }
-
-       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-               ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags);
-       }
-       else {
-               ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags);
-       }
-
-       return (ReturnCode);
-
-}      /* SkAddrMcClear */
-
-
-/******************************************************************************
- *
- *     SkAddrXmacMcClear - clear the multicast table
- *
- * Description:
- *     This routine clears the multicast table
- *     (either entry 2 or entries 3-16 and InexactFilter) of the given port.
- *     If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
- *     immediately.
- *
- * Context:
- *     runtime, pageable
- *     may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
- *     may be called after SK_INIT_IO without limitation
- *
- * Returns:
- *     SK_ADDR_SUCCESS
- *     SK_ADDR_ILLEGAL_PORT
- */
-int    SkAddrXmacMcClear(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* I/O context */
-SK_U32 PortNumber,     /* Index of affected port */
-int            Flags)          /* permanent/non-perm, sw-only */
-{
-       int i;
-
-       if (Flags & SK_ADDR_PERMANENT) {        /* permanent => RLMT */
-
-               /* Clear RLMT multicast addresses. */
-               pAC->Addr.Port[PortNumber].NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
-       }
-       else {  /* not permanent => DRV */
-
-               /* Clear InexactFilter */
-               for (i = 0; i < 8; i++) {
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
-               }
-
-               /* Clear DRV multicast addresses. */
-
-               pAC->Addr.Port[PortNumber].NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
-       }
-
-       if (!(Flags & SK_MC_SW_ONLY)) {
-               (void) SkAddrXmacMcUpdate(pAC, IoC, PortNumber);
-       }
-
-       return (SK_ADDR_SUCCESS);
-
-}      /* SkAddrXmacMcClear */
-
-
-/******************************************************************************
- *
- *     SkAddrGmacMcClear - clear the multicast table
- *
- * Description:
- *     This routine clears the multicast hashing table (InexactFilter)
- *     (either the RLMT or the driver bits) of the given port.
- *
- *     If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
- *     immediately.
- *
- * Context:
- *     runtime, pageable
- *     may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
- *     may be called after SK_INIT_IO without limitation
- *
- * Returns:
- *     SK_ADDR_SUCCESS
- *     SK_ADDR_ILLEGAL_PORT
- */
-int    SkAddrGmacMcClear(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* I/O context */
-SK_U32 PortNumber,     /* Index of affected port */
-int            Flags)          /* permanent/non-perm, sw-only */
-{
-       int i;
-
-#ifdef DEBUG
-       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("GMAC InexactFilter (not cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n",
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
-#endif /* DEBUG */
-
-       /* Clear InexactFilter */
-       for (i = 0; i < 8; i++) {
-               pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
-       }
-
-       if (Flags & SK_ADDR_PERMANENT) {        /* permanent => RLMT */
-
-               /* Copy DRV bits to InexactFilter. */
-               for (i = 0; i < 8; i++) {
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
-                               pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i];
-
-                       /* Clear InexactRlmtFilter. */
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i] = 0;
-
-               }
-       }
-       else {  /* not permanent => DRV */
-
-               /* Copy RLMT bits to InexactFilter. */
-               for (i = 0; i < 8; i++) {
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
-                               pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i];
-
-                       /* Clear InexactDrvFilter. */
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i] = 0;
-               }
-       }
-
-#ifdef DEBUG
-       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("GMAC InexactFilter (cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n",
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
-#endif /* DEBUG */
-
-       if (!(Flags & SK_MC_SW_ONLY)) {
-               (void) SkAddrGmacMcUpdate(pAC, IoC, PortNumber);
-       }
-
-       return (SK_ADDR_SUCCESS);
-
-}      /* SkAddrGmacMcClear */
-
-#ifndef SK_ADDR_CHEAT
-
-/******************************************************************************
- *
- *     SkXmacMcHash - hash multicast address
- *
- * Description:
- *     This routine computes the hash value for a multicast address.
- *     A CRC32 algorithm is used.
- *
- * Notes:
- *     The code was adapted from the XaQti data sheet.
- *
- * Context:
- *     runtime, pageable
- *
- * Returns:
- *     Hash value of multicast address.
- */
-SK_U32 SkXmacMcHash(
-unsigned char *pMc)    /* Multicast address */
-{
-       SK_U32 Idx;
-       SK_U32 Bit;
-       SK_U32 Data;
-       SK_U32 Crc;
-
-       Crc = 0xFFFFFFFFUL;
-       for (Idx = 0; Idx < SK_MAC_ADDR_LEN; Idx++) {
-               Data = *pMc++;
-               for (Bit = 0; Bit < 8; Bit++, Data >>= 1) {
-                       Crc = (Crc >> 1) ^ (((Crc ^ Data) & 1) ? XMAC_POLY : 0);
-               }
-       }
-
-       return (Crc & ((1 << HASH_BITS) - 1));
-
-}      /* SkXmacMcHash */
-
-
-/******************************************************************************
- *
- *     SkGmacMcHash - hash multicast address
- *
- * Description:
- *     This routine computes the hash value for a multicast address.
- *     A CRC16 algorithm is used.
- *
- * Notes:
- *
- *
- * Context:
- *     runtime, pageable
- *
- * Returns:
- *     Hash value of multicast address.
- */
-SK_U32 SkGmacMcHash(
-unsigned char *pMc)    /* Multicast address */
-{
-       SK_U32 Data;
-       SK_U32 TmpData;
-       SK_U32 Crc;
-       int Byte;
-       int Bit;
-
-       Crc = 0xFFFFFFFFUL;
-       for (Byte = 0; Byte < 6; Byte++) {
-               /* Get next byte. */
-               Data = (SK_U32) pMc[Byte];
-
-               /* Change bit order in byte. */
-               TmpData = Data;
-               for (Bit = 0; Bit < 8; Bit++) {
-                       if (TmpData & 1L) {
-                               Data |=  1L << (7 - Bit);
-                       }
-                       else {
-                               Data &= ~(1L << (7 - Bit));
-                       }
-                       TmpData >>= 1;
-               }
-
-               Crc ^= (Data << 24);
-               for (Bit = 0; Bit < 8; Bit++) {
-                       if (Crc & 0x80000000) {
-                               Crc = (Crc << 1) ^ GMAC_POLY;
-                       }
-                       else {
-                               Crc <<= 1;
-                       }
-               }
-       }
-
-       return (Crc & ((1 << HASH_BITS) - 1));
-
-}      /* SkGmacMcHash */
-
-#endif /* not SK_ADDR_CHEAT */
-
-/******************************************************************************
- *
- *     SkAddrMcAdd - add a multicast address to a port
- *
- * Description:
- *     This routine enables reception for a given address on the given port.
- *
- *     It calls either SkAddrXmacMcAdd or SkAddrGmacMcAdd, according to the
- *     adapter in use. The real work is done there.
- *
- * Notes:
- *     The return code is only valid for SK_PROM_MODE_NONE.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_DATA
- *
- * Returns:
- *     SK_MC_FILTERING_EXACT
- *     SK_MC_FILTERING_INEXACT
- *     SK_MC_ILLEGAL_ADDRESS
- *     SK_MC_ILLEGAL_PORT
- *     SK_MC_RLMT_OVERFLOW
- */
-int    SkAddrMcAdd(
-SK_AC          *pAC,           /* adapter context */
-SK_IOC         IoC,            /* I/O context */
-SK_U32         PortNumber,     /* Port Number */
-SK_MAC_ADDR    *pMc,           /* multicast address to be added */
-int                    Flags)          /* permanent/non-permanent */
-{
-       int ReturnCode;
-
-       if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
-               return (SK_ADDR_ILLEGAL_PORT);
-       }
-
-       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-               ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
-       }
-       else {
-               ReturnCode = SkAddrGmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
-       }
-
-       return (ReturnCode);
-
-}      /* SkAddrMcAdd */
-
-
-/******************************************************************************
- *
- *     SkAddrXmacMcAdd - add a multicast address to a port
- *
- * Description:
- *     This routine enables reception for a given address on the given port.
- *
- * Notes:
- *     The return code is only valid for SK_PROM_MODE_NONE.
- *
- *     The multicast bit is only checked if there are no free exact match
- *     entries.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_DATA
- *
- * Returns:
- *     SK_MC_FILTERING_EXACT
- *     SK_MC_FILTERING_INEXACT
- *     SK_MC_ILLEGAL_ADDRESS
- *     SK_MC_RLMT_OVERFLOW
- */
-int    SkAddrXmacMcAdd(
-SK_AC          *pAC,           /* adapter context */
-SK_IOC         IoC,            /* I/O context */
-SK_U32         PortNumber,     /* Port Number */
-SK_MAC_ADDR    *pMc,           /* multicast address to be added */
-int            Flags)          /* permanent/non-permanent */
-{
-       int     i;
-       SK_U8   Inexact;
-#ifndef SK_ADDR_CHEAT
-       SK_U32 HashBit;
-#endif /* !defined(SK_ADDR_CHEAT) */
-
-       if (Flags & SK_ADDR_PERMANENT) {        /* permanent => RLMT */
-#ifdef xDEBUG
-               if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt <
-                       SK_ADDR_FIRST_MATCH_RLMT) {
-                       Next0[PortNumber] |= 1;
-                       return (SK_MC_RLMT_OVERFLOW);
-               }
-#endif /* DEBUG */
-
-               if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt >
-                       SK_ADDR_LAST_MATCH_RLMT) {
-                       return (SK_MC_RLMT_OVERFLOW);
-               }
-
-               /* Set a RLMT multicast address. */
-
-               pAC->Addr.Port[PortNumber].Exact[
-                       pAC->Addr.Port[PortNumber].NextExactMatchRlmt++] = *pMc;
-
-               return (SK_MC_FILTERING_EXACT);
-       }
-
-#ifdef xDEBUG
-       if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <
-               SK_ADDR_FIRST_MATCH_DRV) {
-                       Next0[PortNumber] |= 2;
-               return (SK_MC_RLMT_OVERFLOW);
-       }
-#endif /* DEBUG */
-
-       if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
-
-               /* Set exact match entry. */
-               pAC->Addr.Port[PortNumber].Exact[
-                       pAC->Addr.Port[PortNumber].NextExactMatchDrv++] = *pMc;
-
-               /* Clear InexactFilter */
-               for (i = 0; i < 8; i++) {
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
-               }
-       }
-       else {
-               if (!(pMc->a[0] & SK_MC_BIT)) {
-                       /* Hashing only possible with multicast addresses. */
-                       return (SK_MC_ILLEGAL_ADDRESS);
-               }
-#ifndef SK_ADDR_CHEAT
-               /* Compute hash value of address. */
-               HashBit = 63 - SkXmacMcHash(&pMc->a[0]);
-
-               /* Add bit to InexactFilter. */
-               pAC->Addr.Port[PortNumber].InexactFilter.Bytes[HashBit / 8] |=
-                       1 << (HashBit % 8);
-#else  /* SK_ADDR_CHEAT */
-               /* Set all bits in InexactFilter. */
-               for (i = 0; i < 8; i++) {
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
-               }
-#endif /* SK_ADDR_CHEAT */
-       }
-
-       for (Inexact = 0, i = 0; i < 8; i++) {
-               Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
-       }
-
-       if (Inexact == 0 && pAC->Addr.Port[PortNumber].PromMode == 0) {
-               return (SK_MC_FILTERING_EXACT);
-       }
-       else {
-               return (SK_MC_FILTERING_INEXACT);
-       }
-
-}      /* SkAddrXmacMcAdd */
-
-
-/******************************************************************************
- *
- *     SkAddrGmacMcAdd - add a multicast address to a port
- *
- * Description:
- *     This routine enables reception for a given address on the given port.
- *
- * Notes:
- *     The return code is only valid for SK_PROM_MODE_NONE.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_DATA
- *
- * Returns:
- *     SK_MC_FILTERING_INEXACT
- *     SK_MC_ILLEGAL_ADDRESS
- */
-int    SkAddrGmacMcAdd(
-SK_AC          *pAC,           /* adapter context */
-SK_IOC         IoC,            /* I/O context */
-SK_U32         PortNumber,     /* Port Number */
-SK_MAC_ADDR    *pMc,           /* multicast address to be added */
-int            Flags)          /* permanent/non-permanent */
-{
-       int     i;
-#ifndef SK_ADDR_CHEAT
-       SK_U32 HashBit;
-#endif /* !defined(SK_ADDR_CHEAT) */
-
-       if (!(pMc->a[0] & SK_MC_BIT)) {
-               /* Hashing only possible with multicast addresses. */
-               return (SK_MC_ILLEGAL_ADDRESS);
-       }
-
-#ifndef SK_ADDR_CHEAT
-
-       /* Compute hash value of address. */
-       HashBit = SkGmacMcHash(&pMc->a[0]);
-
-       if (Flags & SK_ADDR_PERMANENT) {        /* permanent => RLMT */
-
-               /* Add bit to InexactRlmtFilter. */
-               pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[HashBit / 8] |=
-                       1 << (HashBit % 8);
-
-               /* Copy bit to InexactFilter. */
-               for (i = 0; i < 8; i++) {
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
-                               pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i];
-               }
-#ifdef DEBUG
-               SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("GMAC InexactRlmtFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n",
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[0],
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[1],
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[2],
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[3],
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[4],
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[5],
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[6],
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7]))
-#endif /* DEBUG */
-       }
-       else {  /* not permanent => DRV */
-
-               /* Add bit to InexactDrvFilter. */
-               pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[HashBit / 8] |=
-                       1 << (HashBit % 8);
-
-               /* Copy bit to InexactFilter. */
-               for (i = 0; i < 8; i++) {
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
-                               pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i];
-               }
-#ifdef DEBUG
-               SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("GMAC InexactDrvFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n",
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[0],
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[1],
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[2],
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[3],
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[4],
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[5],
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[6],
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7]))
-#endif /* DEBUG */
-       }
-
-#else  /* SK_ADDR_CHEAT */
-
-       /* Set all bits in InexactFilter. */
-       for (i = 0; i < 8; i++) {
-               pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
-       }
-#endif /* SK_ADDR_CHEAT */
-
-       return (SK_MC_FILTERING_INEXACT);
-
-}      /* SkAddrGmacMcAdd */
-
-
-/******************************************************************************
- *
- *     SkAddrMcUpdate - update the HW MC address table and set the MAC address
- *
- * Description:
- *     This routine enables reception of the addresses contained in a local
- *     table for a given port.
- *     It also programs the port's current physical MAC address.
- *
- *     It calls either SkAddrXmacMcUpdate or SkAddrGmacMcUpdate, according
- *     to the adapter in use. The real work is done there.
- *
- * Notes:
- *     The return code is only valid for SK_PROM_MODE_NONE.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     SK_MC_FILTERING_EXACT
- *     SK_MC_FILTERING_INEXACT
- *     SK_ADDR_ILLEGAL_PORT
- */
-int    SkAddrMcUpdate(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* I/O context */
-SK_U32 PortNumber)     /* Port Number */
-{
-       int ReturnCode;
-
-       if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
-               return (SK_ADDR_ILLEGAL_PORT);
-       }
-
-       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-               ReturnCode = SkAddrXmacMcUpdate(pAC, IoC, PortNumber);
-       }
-       else {
-               ReturnCode = SkAddrGmacMcUpdate(pAC, IoC, PortNumber);
-       }
-
-       return (ReturnCode);
-
-}      /* SkAddrMcUpdate */
-
-
-/******************************************************************************
- *
- *     SkAddrXmacMcUpdate - update the HW MC address table and set the MAC address
- *
- * Description:
- *     This routine enables reception of the addresses contained in a local
- *     table for a given port.
- *     It also programs the port's current physical MAC address.
- *
- * Notes:
- *     The return code is only valid for SK_PROM_MODE_NONE.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     SK_MC_FILTERING_EXACT
- *     SK_MC_FILTERING_INEXACT
- *     SK_ADDR_ILLEGAL_PORT
- */
-int    SkAddrXmacMcUpdate(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* I/O context */
-SK_U32 PortNumber)     /* Port Number */
-{
-       SK_U32          i;
-       SK_U8           Inexact;
-       SK_U16          *OutAddr;
-       SK_ADDR_PORT    *pAPort;
-
-       SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("SkAddrXmacMcUpdate on Port %u.\n", PortNumber))
-
-       pAPort = &pAC->Addr.Port[PortNumber];
-
-#ifdef DEBUG
-       SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
-#endif /* DEBUG */
-
-       /* Start with 0 to also program the logical MAC address. */
-       for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
-               /* Set exact match address i on XMAC */
-               OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0];
-               XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
-       }
-
-       /* Clear other permanent exact match addresses on XMAC */
-       if (pAPort->NextExactMatchRlmt <= SK_ADDR_LAST_MATCH_RLMT) {
-
-               SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchRlmt,
-                       SK_ADDR_LAST_MATCH_RLMT);
-       }
-
-       for (i = pAPort->FirstExactMatchDrv; i < pAPort->NextExactMatchDrv; i++) {
-               OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0];
-               XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
-       }
-
-       /* Clear other non-permanent exact match addresses on XMAC */
-       if (pAPort->NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
-
-               SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchDrv,
-                       SK_ADDR_LAST_MATCH_DRV);
-       }
-
-       for (Inexact = 0, i = 0; i < 8; i++) {
-               Inexact |= pAPort->InexactFilter.Bytes[i];
-       }
-
-       if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
-
-               /* Set all bits in 64-bit hash register. */
-               XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
-
-               /* Enable Hashing */
-               SkMacHashing(pAC, IoC, PortNumber, SK_TRUE);
-       }
-       else if (Inexact != 0) {
-
-               /* Set 64-bit hash register to InexactFilter. */
-               XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAPort->InexactFilter.Bytes[0]);
-
-               /* Enable Hashing */
-               SkMacHashing(pAC, IoC, PortNumber, SK_TRUE);
-       }
-       else {
-               /* Disable Hashing */
-               SkMacHashing(pAC, IoC, PortNumber, SK_FALSE);
-       }
-
-       if (pAPort->PromMode != SK_PROM_MODE_NONE) {
-               (void) SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
-       }
-
-       /* Set port's current physical MAC address. */
-       OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
-
-       XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
-
-#ifdef xDEBUG
-       for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
-               SK_U8           InAddr8[6];
-               SK_U16          *InAddr;
-
-               /* Get exact match address i from port PortNumber. */
-               InAddr = (SK_U16 *) &InAddr8[0];
-
-               XM_INADDR(IoC, PortNumber, XM_EXM(i), InAddr);
-
-               SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-                       ("SkAddrXmacMcUpdate: MC address %d on Port %u: ",
-                        "%02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x\n",
-                               i,
-                               PortNumber,
-                               InAddr8[0],
-                               InAddr8[1],
-                               InAddr8[2],
-                               InAddr8[3],
-                               InAddr8[4],
-                               InAddr8[5],
-                               pAPort->Exact[i].a[0],
-                               pAPort->Exact[i].a[1],
-                               pAPort->Exact[i].a[2],
-                               pAPort->Exact[i].a[3],
-                               pAPort->Exact[i].a[4],
-                               pAPort->Exact[i].a[5]))
-       }
-#endif /* DEBUG */
-
-       /* Determine return value. */
-       if (Inexact == 0 && pAPort->PromMode == 0) {
-               return (SK_MC_FILTERING_EXACT);
-       }
-       else {
-               return (SK_MC_FILTERING_INEXACT);
-       }
-
-}      /* SkAddrXmacMcUpdate */
-
-
-/******************************************************************************
- *
- *     SkAddrGmacMcUpdate - update the HW MC address table and set the MAC address
- *
- * Description:
- *     This routine enables reception of the addresses contained in a local
- *     table for a given port.
- *     It also programs the port's current physical MAC address.
- *
- * Notes:
- *     The return code is only valid for SK_PROM_MODE_NONE.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     SK_MC_FILTERING_EXACT
- *     SK_MC_FILTERING_INEXACT
- *     SK_ADDR_ILLEGAL_PORT
- */
-int    SkAddrGmacMcUpdate(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* I/O context */
-SK_U32 PortNumber)     /* Port Number */
-{
-       SK_U32          i;
-       SK_U8           Inexact;
-       SK_U16          *OutAddr;
-       SK_ADDR_PORT    *pAPort;
-
-       SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("SkAddrGmacMcUpdate on Port %u.\n", PortNumber))
-
-       pAPort = &pAC->Addr.Port[PortNumber];
-
-#ifdef DEBUG
-       SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
-#endif /* DEBUG */
-
-       for (Inexact = 0, i = 0; i < 8; i++) {
-               Inexact |= pAPort->InexactFilter.Bytes[i];
-       }
-
-       /* Set 64-bit hash register to InexactFilter. */
-       GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1,
-               &pAPort->InexactFilter.Bytes[0]);
-
-       if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
-
-               /* Set all bits in 64-bit hash register. */
-               GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
-
-               /* Enable Hashing */
-               SkMacHashing(pAC, IoC, PortNumber, SK_TRUE);
-       }
-       else {
-               /* Enable Hashing. */
-               SkMacHashing(pAC, IoC, PortNumber, SK_TRUE);
-       }
-
-       if (pAPort->PromMode != SK_PROM_MODE_NONE) {
-               (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
-       }
-
-       /* Set port's current physical MAC address. */
-       OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
-       GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr);
-
-       /* Set port's current logical MAC address. */
-       OutAddr = (SK_U16 *) &pAPort->Exact[0].a[0];
-       GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_2L, OutAddr);
-
-#ifdef DEBUG
-       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("SkAddrGmacMcUpdate: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
-                       pAPort->Exact[0].a[0],
-                       pAPort->Exact[0].a[1],
-                       pAPort->Exact[0].a[2],
-                       pAPort->Exact[0].a[3],
-                       pAPort->Exact[0].a[4],
-                       pAPort->Exact[0].a[5]))
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("SkAddrGmacMcUpdate: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
-                       pAPort->CurrentMacAddress.a[0],
-                       pAPort->CurrentMacAddress.a[1],
-                       pAPort->CurrentMacAddress.a[2],
-                       pAPort->CurrentMacAddress.a[3],
-                       pAPort->CurrentMacAddress.a[4],
-                       pAPort->CurrentMacAddress.a[5]))
-#endif /* DEBUG */
-
-       /* Determine return value. */
-       if (Inexact == 0 && pAPort->PromMode == 0) {
-               return (SK_MC_FILTERING_EXACT);
-       }
-       else {
-               return (SK_MC_FILTERING_INEXACT);
-       }
-
-}      /* SkAddrGmacMcUpdate */
-
-
-/******************************************************************************
- *
- *     SkAddrOverride - override a port's MAC address
- *
- * Description:
- *     This routine overrides the MAC address of one port.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     SK_ADDR_SUCCESS if successful.
- *     SK_ADDR_DUPLICATE_ADDRESS if duplicate MAC address.
- *     SK_ADDR_MULTICAST_ADDRESS if multicast or broadcast address.
- *     SK_ADDR_TOO_EARLY if SK_INIT_IO was not executed before.
- */
-int    SkAddrOverride(
-SK_AC          *pAC,           /* adapter context */
-SK_IOC         IoC,            /* I/O context */
-SK_U32         PortNumber,     /* Port Number */
-SK_MAC_ADDR    *pNewAddr,      /* new MAC address */
-int                    Flags)          /* logical/physical MAC address */
-{
-       SK_EVPARA       Para;
-       SK_U32          NetNumber;
-       SK_U32          i;
-       SK_U16          *OutAddr;
-
-       NetNumber = pAC->Rlmt.Port[PortNumber].Net->NetNumber;
-
-       if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
-               return (SK_ADDR_ILLEGAL_PORT);
-       }
-
-       if (pNewAddr != NULL && (pNewAddr->a[0] & SK_MC_BIT) != 0) {
-               return (SK_ADDR_MULTICAST_ADDRESS);
-       }
-
-       if (!pAC->Addr.Net[NetNumber].CurrentMacAddressSet) {
-               return (SK_ADDR_TOO_EARLY);
-       }
-
-       if (Flags & SK_ADDR_SET_LOGICAL) {      /* Activate logical MAC address. */
-               /* Parameter *pNewAddr is ignored. */
-               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
-                       if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
-                               return (SK_ADDR_TOO_EARLY);
-                       }
-               }
-
-               /* Set PortNumber to number of net's active port. */
-               PortNumber = pAC->Rlmt.Net[NetNumber].
-                       Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
-
-               pAC->Addr.Port[PortNumber].Exact[0] =
-                       pAC->Addr.Net[NetNumber].CurrentMacAddress;
-
-               /* Write address to first exact match entry of active port. */
-               (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
-       }
-       else if (Flags & SK_ADDR_CLEAR_LOGICAL) {
-               /* Deactivate logical MAC address. */
-               /* Parameter *pNewAddr is ignored. */
-               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
-                       if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
-                               return (SK_ADDR_TOO_EARLY);
-                       }
-               }
-
-               /* Set PortNumber to number of net's active port. */
-               PortNumber = pAC->Rlmt.Net[NetNumber].
-                       Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
-
-               for (i = 0; i < SK_MAC_ADDR_LEN; i++ ) {
-                       pAC->Addr.Port[PortNumber].Exact[0].a[i] = 0;
-               }
-
-               /* Write address to first exact match entry of active port. */
-               (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
-       }
-       else if (Flags & SK_ADDR_PHYSICAL_ADDRESS) {    /* Physical MAC address. */
-               if (SK_ADDR_EQUAL(pNewAddr->a,
-                       pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
-                       return (SK_ADDR_DUPLICATE_ADDRESS);
-               }
-
-               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
-                       if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
-                               return (SK_ADDR_TOO_EARLY);
-                       }
-
-                       if (SK_ADDR_EQUAL(pNewAddr->a,
-                               pAC->Addr.Port[i].CurrentMacAddress.a)) {
-                               if (i == PortNumber) {
-                                       return (SK_ADDR_SUCCESS);
-                               }
-                               else {
-                                       return (SK_ADDR_DUPLICATE_ADDRESS);
-                               }
-                       }
-               }
-
-               pAC->Addr.Port[PortNumber].PreviousMacAddress =
-                       pAC->Addr.Port[PortNumber].CurrentMacAddress;
-               pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;
-
-               /* Change port's physical MAC address. */
-               OutAddr = (SK_U16 *) pNewAddr;
-
-               if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-                       XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
-               }
-               else {
-                       GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr);
-               }
-
-               /* Report address change to RLMT. */
-               Para.Para32[0] = PortNumber;
-               Para.Para32[0] = -1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
-       }
-       else {  /* Logical MAC address. */
-               if (SK_ADDR_EQUAL(pNewAddr->a,
-                       pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
-                       return (SK_ADDR_SUCCESS);
-               }
-
-               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
-                       if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
-                               return (SK_ADDR_TOO_EARLY);
-                       }
-
-                       if (SK_ADDR_EQUAL(pNewAddr->a,
-                               pAC->Addr.Port[i].CurrentMacAddress.a)) {
-                               return (SK_ADDR_DUPLICATE_ADDRESS);
-                       }
-               }
-
-               /*
-                * In case that the physical and the logical MAC addresses are equal
-                * we must also change the physical MAC address here.
-                * In this case we have an adapter which initially was programmed with
-                * two identical MAC addresses.
-                */
-               if (SK_ADDR_EQUAL(pAC->Addr.Port[PortNumber].CurrentMacAddress.a,
-                               pAC->Addr.Port[PortNumber].Exact[0].a)) {
-
-                       pAC->Addr.Port[PortNumber].PreviousMacAddress =
-                               pAC->Addr.Port[PortNumber].CurrentMacAddress;
-                       pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;
-
-                       /* Report address change to RLMT. */
-                       Para.Para32[0] = PortNumber;
-                       Para.Para32[0] = -1;
-                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
-               }
-
-               /* Set PortNumber to number of net's active port. */
-               PortNumber = pAC->Rlmt.Net[NetNumber].
-                       Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
-
-               pAC->Addr.Net[NetNumber].CurrentMacAddress = *pNewAddr;
-               pAC->Addr.Port[PortNumber].Exact[0] = *pNewAddr;
-#ifdef DEBUG
-               SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-                       ("SkAddrOverride: Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n",
-                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[0],
-                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[1],
-                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[2],
-                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[3],
-                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[4],
-                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5]))
-
-               SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-                       ("SkAddrOverride: New logical MAC Address: %02X %02X %02X %02X %02X %02X\n",
-                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[0],
-                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[1],
-                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[2],
-                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[3],
-                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[4],
-                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5]))
-#endif /* DEBUG */
-
-       /* Write address to first exact match entry of active port. */
-               (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
-       }
-
-       return (SK_ADDR_SUCCESS);
-
-}      /* SkAddrOverride */
-
-
-/******************************************************************************
- *
- *     SkAddrPromiscuousChange - set promiscuous mode for given port
- *
- * Description:
- *     This routine manages promiscuous mode:
- *     - none
- *     - all LLC frames
- *     - all MC frames
- *
- *     It calls either SkAddrXmacPromiscuousChange or
- *     SkAddrGmacPromiscuousChange, according to the adapter in use.
- *     The real work is done there.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     SK_ADDR_SUCCESS
- *     SK_ADDR_ILLEGAL_PORT
- */
-int    SkAddrPromiscuousChange(
-SK_AC  *pAC,                   /* adapter context */
-SK_IOC IoC,                    /* I/O context */
-SK_U32 PortNumber,             /* port whose promiscuous mode changes */
-int            NewPromMode)    /* new promiscuous mode */
-{
-       int ReturnCode;
-
-       if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
-               return (SK_ADDR_ILLEGAL_PORT);
-       }
-
-       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-               ReturnCode = SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode);
-       }
-       else {
-               ReturnCode = SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode);
-       }
-
-       return (ReturnCode);
-
-}      /* SkAddrPromiscuousChange */
-
-
-/******************************************************************************
- *
- *     SkAddrXmacPromiscuousChange - set promiscuous mode for given port
- *
- * Description:
- *     This routine manages promiscuous mode:
- *     - none
- *     - all LLC frames
- *     - all MC frames
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     SK_ADDR_SUCCESS
- *     SK_ADDR_ILLEGAL_PORT
- */
-int    SkAddrXmacPromiscuousChange(
-SK_AC  *pAC,                   /* adapter context */
-SK_IOC IoC,                    /* I/O context */
-SK_U32 PortNumber,             /* port whose promiscuous mode changes */
-int            NewPromMode)    /* new promiscuous mode */
-{
-       int                     i;
-       SK_BOOL         InexactModeBit;
-       SK_U8           Inexact;
-       SK_U8           HwInexact;
-       SK_FILTER64     HwInexactFilter;
-       SK_U16          LoMode;         /* Lower 16 bits of XMAC Mode Register. */
-       int                     CurPromMode = SK_PROM_MODE_NONE;
-
-       /* Read CurPromMode from Hardware. */
-       XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
-
-       if ((LoMode & XM_MD_ENA_PROM) != 0) {
-               /* Promiscuous mode! */
-               CurPromMode |= SK_PROM_MODE_LLC;
-       }
-
-       for (Inexact = 0xFF, i = 0; i < 8; i++) {
-               Inexact &= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
-       }
-       if (Inexact == 0xFF) {
-               CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
-       }
-       else {
-               /* Get InexactModeBit (bit XM_MD_ENA_HASH in mode register) */
-               XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
-
-               InexactModeBit = (LoMode & XM_MD_ENA_HASH) != 0;
-
-               /* Read 64-bit hash register from XMAC */
-               XM_INHASH(IoC, PortNumber, XM_HSM, &HwInexactFilter.Bytes[0]);
-
-               for (HwInexact = 0xFF, i = 0; i < 8; i++) {
-                       HwInexact &= HwInexactFilter.Bytes[i];
-               }
-
-               if (InexactModeBit && (HwInexact == 0xFF)) {
-                       CurPromMode |= SK_PROM_MODE_ALL_MC;
-               }
-       }
-
-       pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
-
-       if (NewPromMode == CurPromMode) {
-               return (SK_ADDR_SUCCESS);
-       }
-
-       if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
-               !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC. */
-
-               /* Set all bits in 64-bit hash register. */
-               XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
-
-               /* Enable Hashing */
-               SkMacHashing(pAC, IoC, PortNumber, SK_TRUE);
-       }
-       else if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
-               !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm MC. */
-               for (Inexact = 0, i = 0; i < 8; i++) {
-                       Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
-               }
-               if (Inexact == 0) {
-                       /* Disable Hashing */
-                       SkMacHashing(pAC, IoC, PortNumber, SK_FALSE);
-               }
-               else {
-                       /* Set 64-bit hash register to InexactFilter. */
-                       XM_OUTHASH(IoC, PortNumber, XM_HSM,
-                               &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
-
-                       /* Enable Hashing */
-                       SkMacHashing(pAC, IoC, PortNumber, SK_TRUE);
-               }
-       }
-
-       if ((NewPromMode & SK_PROM_MODE_LLC) &&
-               !(CurPromMode & SK_PROM_MODE_LLC)) {    /* Prom. LLC */
-               /* Set the MAC in Promiscuous Mode */
-               SkMacPromiscMode(pAC, IoC, PortNumber, SK_TRUE);
-       }
-       else if ((CurPromMode & SK_PROM_MODE_LLC) &&
-               !(NewPromMode & SK_PROM_MODE_LLC)) {    /* Norm. LLC. */
-               /* Clear Promiscuous Mode */
-               SkMacPromiscMode(pAC, IoC, PortNumber, SK_FALSE);
-       }
-
-       return (SK_ADDR_SUCCESS);
-
-}      /* SkAddrXmacPromiscuousChange */
-
-
-/******************************************************************************
- *
- *     SkAddrGmacPromiscuousChange - set promiscuous mode for given port
- *
- * Description:
- *     This routine manages promiscuous mode:
- *     - none
- *     - all LLC frames
- *     - all MC frames
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     SK_ADDR_SUCCESS
- *     SK_ADDR_ILLEGAL_PORT
- */
-int    SkAddrGmacPromiscuousChange(
-SK_AC  *pAC,                   /* adapter context */
-SK_IOC IoC,                    /* I/O context */
-SK_U32 PortNumber,             /* port whose promiscuous mode changes */
-int            NewPromMode)    /* new promiscuous mode */
-{
-       SK_U16          ReceiveControl; /* GMAC Receive Control Register */
-       int             CurPromMode = SK_PROM_MODE_NONE;
-
-       /* Read CurPromMode from Hardware. */
-       GM_IN16(IoC, PortNumber, GM_RX_CTRL, &ReceiveControl);
-
-       if ((ReceiveControl & (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA)) == 0) {
-               /* Promiscuous mode! */
-               CurPromMode |= SK_PROM_MODE_LLC;
-       }
-
-       if ((ReceiveControl & GM_RXCR_MCF_ENA) == 0) {
-               /* All Multicast mode! */
-               CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
-       }
-
-       pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
-
-       if (NewPromMode == CurPromMode) {
-               return (SK_ADDR_SUCCESS);
-       }
-
-       if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
-               !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC */
-
-               /* Set all bits in 64-bit hash register. */
-               GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
-
-               /* Enable Hashing */
-               SkMacHashing(pAC, IoC, PortNumber, SK_TRUE);
-       }
-
-       if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
-               !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm. MC */
-
-               /* Set 64-bit hash register to InexactFilter. */
-               GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1,
-                       &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
-
-               /* Enable Hashing. */
-               SkMacHashing(pAC, IoC, PortNumber, SK_TRUE);
-       }
-
-       if ((NewPromMode & SK_PROM_MODE_LLC) &&
-               !(CurPromMode & SK_PROM_MODE_LLC)) {    /* Prom. LLC */
-
-               /* Set the MAC to Promiscuous Mode. */
-               SkMacPromiscMode(pAC, IoC, PortNumber, SK_TRUE);
-       }
-       else if ((CurPromMode & SK_PROM_MODE_LLC) &&
-               !(NewPromMode & SK_PROM_MODE_LLC)) {    /* Norm. LLC */
-
-               /* Clear Promiscuous Mode. */
-               SkMacPromiscMode(pAC, IoC, PortNumber, SK_FALSE);
-       }
-
-       return (SK_ADDR_SUCCESS);
-
-}      /* SkAddrGmacPromiscuousChange */
-
-
-/******************************************************************************
- *
- *     SkAddrSwap - swap address info
- *
- * Description:
- *     This routine swaps address info of two ports.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     SK_ADDR_SUCCESS
- *     SK_ADDR_ILLEGAL_PORT
- */
-int    SkAddrSwap(
-SK_AC  *pAC,                   /* adapter context */
-SK_IOC IoC,                    /* I/O context */
-SK_U32 FromPortNumber,         /* Port1 Index */
-SK_U32 ToPortNumber)           /* Port2 Index */
-{
-       int                     i;
-       SK_U8           Byte;
-       SK_MAC_ADDR     MacAddr;
-       SK_U32          DWord;
-
-       if (FromPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
-               return (SK_ADDR_ILLEGAL_PORT);
-       }
-
-       if (ToPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
-               return (SK_ADDR_ILLEGAL_PORT);
-       }
-
-       if (pAC->Rlmt.Port[FromPortNumber].Net != pAC->Rlmt.Port[ToPortNumber].Net) {
-               return (SK_ADDR_ILLEGAL_PORT);
-       }
-
-       /*
-        * Swap:
-        * - Exact Match Entries (GEnesis and Yukon)
-        *   Yukon uses first entry for the logical MAC
-        *   address (stored in the second GMAC register).
-        * - FirstExactMatchRlmt (GEnesis only)
-        * - NextExactMatchRlmt (GEnesis only)
-        * - FirstExactMatchDrv (GEnesis only)
-        * - NextExactMatchDrv (GEnesis only)
-        * - 64-bit filter (InexactFilter)
-        * - Promiscuous Mode
-        * of ports.
-        */
-
-       for (i = 0; i < SK_ADDR_EXACT_MATCHES; i++) {
-               MacAddr = pAC->Addr.Port[FromPortNumber].Exact[i];
-               pAC->Addr.Port[FromPortNumber].Exact[i] =
-                       pAC->Addr.Port[ToPortNumber].Exact[i];
-               pAC->Addr.Port[ToPortNumber].Exact[i] = MacAddr;
-       }
-
-       for (i = 0; i < 8; i++) {
-               Byte = pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i];
-               pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i] =
-                       pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i];
-               pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i] = Byte;
-       }
-
-       i = pAC->Addr.Port[FromPortNumber].PromMode;
-       pAC->Addr.Port[FromPortNumber].PromMode = pAC->Addr.Port[ToPortNumber].PromMode;
-       pAC->Addr.Port[ToPortNumber].PromMode = i;
-
-       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-               DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt;
-               pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt =
-                       pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt;
-               pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt = DWord;
-
-               DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt;
-               pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt =
-                       pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt;
-               pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt = DWord;
-
-               DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv;
-               pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv =
-                       pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv;
-               pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv = DWord;
-
-               DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchDrv;
-               pAC->Addr.Port[FromPortNumber].NextExactMatchDrv =
-                       pAC->Addr.Port[ToPortNumber].NextExactMatchDrv;
-               pAC->Addr.Port[ToPortNumber].NextExactMatchDrv = DWord;
-       }
-
-       /* CAUTION: Solution works if only ports of one adapter are in use. */
-       for (i = 0; (SK_U32) i < pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].
-               Net->NetNumber].NumPorts; i++) {
-               if (pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
-                       Port[i]->PortNumber == ToPortNumber) {
-                       pAC->Addr.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
-                               ActivePort = i;
-                       /* 20001207 RA: Was "ToPortNumber;". */
-               }
-       }
-
-       (void) SkAddrMcUpdate(pAC, IoC, FromPortNumber);
-       (void) SkAddrMcUpdate(pAC, IoC, ToPortNumber);
-
-       return (SK_ADDR_SUCCESS);
-
-}      /* SkAddrSwap */
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CONFIG_SK98 */
diff --git a/drivers/sk98lin/skcsum.c b/drivers/sk98lin/skcsum.c
deleted file mode 100644 (file)
index a5dc572..0000000
+++ /dev/null
@@ -1,929 +0,0 @@
-/******************************************************************************
- *
- * Name:       skcsum.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.10 $
- * Date:       $Date: 2002/04/11 10:02:04 $
- * Purpose:    Store/verify Internet checksum in send/receive packets.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2001 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skcsum.c,v $
- *     Revision 1.10  2002/04/11 10:02:04  rwahl
- *     Fix in SkCsGetSendInfo():
- *     - function did not return ProtocolFlags in every case.
- *     - pseudo header csum calculated wrong for big endian.
- *
- *     Revision 1.9  2001/06/13 07:42:08  gklug
- *     fix: NetNumber was wrong in CLEAR_STAT event
- *     add: check for good NetNumber in Clear STAT
- *
- *     Revision 1.8  2001/02/06 11:15:36  rassmann
- *     Supporting two nets on dual-port adapters.
- *
- *     Revision 1.7  2000/06/29 13:17:05  rassmann
- *     Corrected reception of a packet with UDP checksum == 0 (which means there
- *     is no UDP checksum).
- *
- *     Revision 1.6  2000/02/21 12:35:10  cgoos
- *     Fixed license header comment.
- *
- *     Revision 1.5  2000/02/21 11:05:19  cgoos
- *     Merged changes back to common source.
- *     Fixed rx path for BIG ENDIAN architecture.
- *
- *     Revision 1.1  1999/07/26 15:28:12  mkarl
- *     added return SKCS_STATUS_IP_CSUM_ERROR_UDP and
- *     SKCS_STATUS_IP_CSUM_ERROR_TCP to pass the NidsTester
- *     changed from common source to windows specific source
- *     therefore restarting with v1.0
- *
- *     Revision 1.3  1999/05/10 08:39:33  mkarl
- *     prevent overflows in SKCS_HTON16
- *     fixed a bug in pseudo header checksum calculation
- *     added some comments
- *
- *     Revision 1.2  1998/10/22 11:53:28  swolf
- *     Now using SK_DBG_MSG.
- *
- *     Revision 1.1  1998/09/01 15:35:41  swolf
- *     initial revision
- *
- *     13-May-1998 sw  Created.
- *
- ******************************************************************************/
-
-#include <config.h>
-
-#ifdef CONFIG_SK98
-
-#ifdef SK_USE_CSUM     /* Check if CSUM is to be used. */
-
-#ifndef lint
-static const char SysKonnectFileId[] = "@(#)"
-       "$Id: skcsum.c,v 1.10 2002/04/11 10:02:04 rwahl Exp $"
-       " (C) SysKonnect.";
-#endif /* !lint */
-
-/******************************************************************************
- *
- * Description:
- *
- * This is the "GEnesis" common module "CSUM".
- *
- * This module contains the code necessary to calculate, store, and verify the
- * Internet Checksum of IP, TCP, and UDP frames.
- *
- * "GEnesis" is an abbreviation of "Gigabit Ethernet Network System in Silicon"
- * and is the code name of this SysKonnect project.
- *
- * Compilation Options:
- *
- *     SK_USE_CSUM - Define if CSUM is to be used. Otherwise, CSUM will be an
- *     empty module.
- *
- *     SKCS_OVERWRITE_PROTO - Define to overwrite the default protocol id
- *     definitions. In this case, all SKCS_PROTO_xxx definitions must be made
- *     external.
- *
- *     SKCS_OVERWRITE_STATUS - Define to overwrite the default return status
- *     definitions. In this case, all SKCS_STATUS_xxx definitions must be made
- *     external.
- *
- * Include File Hierarchy:
- *
- *     "h/skdrv1st.h"
- *     "h/skcsum.h"
- *      "h/sktypes.h"
- *      "h/skqueue.h"
- *     "h/skdrv2nd.h"
- *
- ******************************************************************************/
-
-#include "h/skdrv1st.h"
-#include "h/skcsum.h"
-#include "h/skdrv2nd.h"
-
-/* defines ********************************************************************/
-
-/* The size of an Ethernet MAC header. */
-#define SKCS_ETHERNET_MAC_HEADER_SIZE                  (6+6+2)
-
-/* The size of the used topology's MAC header. */
-#define        SKCS_MAC_HEADER_SIZE    SKCS_ETHERNET_MAC_HEADER_SIZE
-
-/* The size of the IP header without any option fields. */
-#define SKCS_IP_HEADER_SIZE                                            20
-
-/*
- * Field offsets within the IP header.
- */
-
-/* "Internet Header Version" and "Length". */
-#define SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH  0
-
-/* "Total Length". */
-#define SKCS_OFS_IP_TOTAL_LENGTH                               2
-
-/* "Flags" "Fragment Offset". */
-#define SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET  6
-
-/* "Next Level Protocol" identifier. */
-#define SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL                        9
-
-/* Source IP address. */
-#define SKCS_OFS_IP_SOURCE_ADDRESS                             12
-
-/* Destination IP address. */
-#define SKCS_OFS_IP_DESTINATION_ADDRESS                        16
-
-
-/*
- * Field offsets within the UDP header.
- */
-
-/* UDP checksum. */
-#define SKCS_OFS_UDP_CHECKSUM                                  6
-
-/* IP "Next Level Protocol" identifiers (see RFC 790). */
-#define SKCS_PROTO_ID_TCP              6       /* Transport Control Protocol */
-#define SKCS_PROTO_ID_UDP              17      /* User Datagram Protocol */
-
-/* IP "Don't Fragment" bit. */
-#define SKCS_IP_DONT_FRAGMENT  SKCS_HTON16(0x4000)
-
-/* Add a byte offset to a pointer. */
-#define SKCS_IDX(pPtr, Ofs)    ((void *) ((char *) (pPtr) + (Ofs)))
-
-/*
- * Macros that convert host to network representation and vice versa, i.e.
- * little/big endian conversion on little endian machines only.
- */
-#ifdef SK_LITTLE_ENDIAN
-#define SKCS_HTON16(Val16)     (((unsigned) (Val16) >> 8) | (((Val16) & 0xFF) << 8))
-#endif /* SK_LITTLE_ENDIAN */
-#ifdef SK_BIG_ENDIAN
-#define SKCS_HTON16(Val16)     (Val16)
-#endif /* SK_BIG_ENDIAN */
-#define SKCS_NTOH16(Val16)     SKCS_HTON16(Val16)
-
-/* typedefs *******************************************************************/
-
-/* function prototypes ********************************************************/
-
-/******************************************************************************
- *
- *     SkCsGetSendInfo - get checksum information for a send packet
- *
- * Description:
- *     Get all checksum information necessary to send a TCP or UDP packet. The
- *     function checks the IP header passed to it. If the high-level protocol
- *     is either TCP or UDP the pseudo header checksum is calculated and
- *     returned.
- *
- *     The function returns the total length of the IP header (including any
- *     IP option fields), which is the same as the start offset of the IP data
- *     which in turn is the start offset of the TCP or UDP header.
- *
- *     The function also returns the TCP or UDP pseudo header checksum, which
- *     should be used as the start value for the hardware checksum calculation.
- *     (Note that any actual pseudo header checksum can never calculate to
- *     zero.)
- *
- * Note:
- *     There is a bug in the ASIC which may lead to wrong checksums.
- *
- * Arguments:
- *     pAc - A pointer to the adapter context struct.
- *
- *     pIpHeader - Pointer to IP header. Must be at least the IP header *not*
- *     including any option fields, i.e. at least 20 bytes.
- *
- *     Note: This pointer will be used to address 8-, 16-, and 32-bit
- *     variables with the respective alignment offsets relative to the pointer.
- *     Thus, the pointer should point to a 32-bit aligned address. If the
- *     target system cannot address 32-bit variables on non 32-bit aligned
- *     addresses, then the pointer *must* point to a 32-bit aligned address.
- *
- *     pPacketInfo - A pointer to the packet information structure for this
- *     packet. Before calling this SkCsGetSendInfo(), the following field must
- *     be initialized:
- *
- *             ProtocolFlags - Initialize with any combination of
- *             SKCS_PROTO_XXX bit flags. SkCsGetSendInfo() will only work on
- *             the protocols specified here. Any protocol(s) not specified
- *             here will be ignored.
- *
- *             Note: Only one checksum can be calculated in hardware. Thus, if
- *             SKCS_PROTO_IP is specified in the 'ProtocolFlags',
- *             SkCsGetSendInfo() must calculate the IP header checksum in
- *             software. It might be a better idea to have the calling
- *             protocol stack calculate the IP header checksum.
- *
- * Returns: N/A
- *     On return, the following fields in 'pPacketInfo' may or may not have
- *     been filled with information, depending on the protocol(s) found in the
- *     packet:
- *
- *     ProtocolFlags - Returns the SKCS_PROTO_XXX bit flags of the protocol(s)
- *     that were both requested by the caller and actually found in the packet.
- *     Protocol(s) not specified by the caller and/or not found in the packet
- *     will have their respective SKCS_PROTO_XXX bit flags reset.
- *
- *     Note: For IP fragments, TCP and UDP packet information is ignored.
- *
- *     IpHeaderLength - The total length in bytes of the complete IP header
- *     including any option fields is returned here. This is the start offset
- *     of the IP data, i.e. the TCP or UDP header if present.
- *
- *     IpHeaderChecksum - If IP has been specified in the 'ProtocolFlags', the
- *     16-bit Internet Checksum of the IP header is returned here. This value
- *     is to be stored into the packet's 'IP Header Checksum' field.
- *
- *     PseudoHeaderChecksum - If this is a TCP or UDP packet and if TCP or UDP
- *     has been specified in the 'ProtocolFlags', the 16-bit Internet Checksum
- *     of the TCP or UDP pseudo header is returned here.
- */
-#if 0
-void SkCsGetSendInfo(
-SK_AC                          *pAc,                   /* Adapter context struct. */
-void                           *pIpHeader,             /* IP header. */
-SKCS_PACKET_INFO       *pPacketInfo,   /* Packet information struct. */
-int                                    NetNumber)              /* Net number */
-{
-       /* Internet Header Version found in IP header. */
-       unsigned InternetHeaderVersion;
-
-       /* Length of the IP header as found in IP header. */
-       unsigned IpHeaderLength;
-
-       /* Bit field specifiying the desired/found protocols. */
-       unsigned ProtocolFlags;
-
-       /* Next level protocol identifier found in IP header. */
-       unsigned NextLevelProtocol;
-
-       /* Length of IP data portion. */
-       unsigned IpDataLength;
-
-       /* TCP/UDP pseudo header checksum. */
-       unsigned long PseudoHeaderChecksum;
-
-       /* Pointer to next level protocol statistics structure. */
-       SKCS_PROTO_STATS *NextLevelProtoStats;
-
-       /* Temporary variable. */
-       unsigned Tmp;
-
-       Tmp = *(SK_U8 *)
-               SKCS_IDX(pIpHeader, SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH);
-
-       /* Get the Internet Header Version (IHV). */
-       /* Note: The IHV is stored in the upper four bits. */
-
-       InternetHeaderVersion = Tmp >> 4;
-
-       /* Check the Internet Header Version. */
-       /* Note: We currently only support IP version 4. */
-
-       if (InternetHeaderVersion != 4) {       /* IPv4? */
-               SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_TX,
-                       ("Tx: Unknown Internet Header Version %u.\n",
-                       InternetHeaderVersion));
-               pPacketInfo->ProtocolFlags = 0;
-               pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxUnableCts++;
-               return;
-       }
-
-       /* Get the IP header length (IHL). */
-       /*
-        * Note: The IHL is stored in the lower four bits as the number of
-        * 4-byte words.
-        */
-
-       IpHeaderLength = (Tmp & 0xf) * 4;
-       pPacketInfo->IpHeaderLength = IpHeaderLength;
-
-       /* Check the IP header length. */
-
-       /* 04-Aug-1998 sw - Really check the IHL? Necessary? */
-
-       if (IpHeaderLength < 5*4) {
-               SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_TX,
-                       ("Tx: Invalid IP Header Length %u.\n", IpHeaderLength));
-               pPacketInfo->ProtocolFlags = 0;
-               pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxUnableCts++;
-               return;
-       }
-
-       /* This is an IPv4 frame with a header of valid length. */
-
-       pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxOkCts++;
-
-       /* Check if we should calculate the IP header checksum. */
-
-       ProtocolFlags = pPacketInfo->ProtocolFlags;
-
-       if (ProtocolFlags & SKCS_PROTO_IP) {
-               pPacketInfo->IpHeaderChecksum =
-                       SkCsCalculateChecksum(pIpHeader, IpHeaderLength);
-       }
-
-       /* Get the next level protocol identifier. */
-
-       NextLevelProtocol =
-               *(SK_U8 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL);
-
-       /*
-        * Check if this is a TCP or UDP frame and if we should calculate the
-        * TCP/UDP pseudo header checksum.
-        *
-        * Also clear all protocol bit flags of protocols not present in the
-        * frame.
-        */
-
-       if ((ProtocolFlags & SKCS_PROTO_TCP) != 0 &&
-               NextLevelProtocol == SKCS_PROTO_ID_TCP) {
-               /* TCP/IP frame. */
-               ProtocolFlags &= SKCS_PROTO_TCP | SKCS_PROTO_IP;
-               NextLevelProtoStats =
-                       &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_TCP];
-       }
-       else if ((ProtocolFlags & SKCS_PROTO_UDP) != 0 &&
-               NextLevelProtocol == SKCS_PROTO_ID_UDP) {
-               /* UDP/IP frame. */
-               ProtocolFlags &= SKCS_PROTO_UDP | SKCS_PROTO_IP;
-               NextLevelProtoStats =
-                       &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_UDP];
-       }
-       else {
-               /*
-                * Either not a TCP or UDP frame and/or TCP/UDP processing not
-                * specified.
-                */
-               pPacketInfo->ProtocolFlags = ProtocolFlags & SKCS_PROTO_IP;
-               return;
-       }
-
-       /* Check if this is an IP fragment. */
-
-       /*
-        * Note: An IP fragment has a non-zero "Fragment Offset" field and/or
-        * the "More Fragments" bit set. Thus, if both the "Fragment Offset"
-        * and the "More Fragments" are zero, it is *not* a fragment. We can
-        * easily check both at the same time since they are in the same 16-bit
-        * word.
-        */
-
-       if ((*(SK_U16 *)
-               SKCS_IDX(pIpHeader, SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET) &
-               ~SKCS_IP_DONT_FRAGMENT) != 0) {
-               /* IP fragment; ignore all other protocols. */
-               pPacketInfo->ProtocolFlags = ProtocolFlags & SKCS_PROTO_IP;
-               NextLevelProtoStats->TxUnableCts++;
-               return;
-       }
-
-       /*
-        * Calculate the TCP/UDP pseudo header checksum.
-        */
-
-       /* Get total length of IP header and data. */
-
-       IpDataLength =
-               *(SK_U16 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_TOTAL_LENGTH);
-
-       /* Get length of IP data portion. */
-
-       IpDataLength = SKCS_NTOH16(IpDataLength) - IpHeaderLength;
-
-       /* Calculate the sum of all pseudo header fields (16-bit). */
-
-       PseudoHeaderChecksum =
-               (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-                       SKCS_OFS_IP_SOURCE_ADDRESS + 0) +
-               (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-                       SKCS_OFS_IP_SOURCE_ADDRESS + 2) +
-               (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-                       SKCS_OFS_IP_DESTINATION_ADDRESS + 0) +
-               (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-                       SKCS_OFS_IP_DESTINATION_ADDRESS + 2) +
-               (unsigned long) SKCS_HTON16(NextLevelProtocol) +
-               (unsigned long) SKCS_HTON16(IpDataLength);
-
-       /* Add-in any carries. */
-
-       SKCS_OC_ADD(PseudoHeaderChecksum, PseudoHeaderChecksum, 0);
-
-       /* Add-in any new carry. */
-
-       SKCS_OC_ADD(pPacketInfo->PseudoHeaderChecksum, PseudoHeaderChecksum, 0);
-
-       pPacketInfo->ProtocolFlags = ProtocolFlags;
-       NextLevelProtoStats->TxOkCts++; /* Success. */
-}      /* SkCsGetSendInfo */
-
-
-/******************************************************************************
- *
- *     SkCsGetReceiveInfo - verify checksum information for a received packet
- *
- * Description:
- *     Verify a received frame's checksum. The function returns a status code
- *     reflecting the result of the verification.
- *
- * Note:
- *     Before calling this function you have to verify that the frame is
- *     not padded and Checksum1 and Checksum2 are bigger than 1.
- *
- * Arguments:
- *     pAc - Pointer to adapter context struct.
- *
- *     pIpHeader - Pointer to IP header. Must be at least the length in bytes
- *     of the received IP header including any option fields. For UDP packets,
- *     8 additional bytes are needed to access the UDP checksum.
- *
- *     Note: The actual length of the IP header is stored in the lower four
- *     bits of the first octet of the IP header as the number of 4-byte words,
- *     so it must be multiplied by four to get the length in bytes. Thus, the
- *     maximum IP header length is 15 * 4 = 60 bytes.
- *
- *     Checksum1 - The first 16-bit Internet Checksum calculated by the
- *     hardware starting at the offset returned by SkCsSetReceiveFlags().
- *
- *     Checksum2 - The second 16-bit Internet Checksum calculated by the
- *     hardware starting at the offset returned by SkCsSetReceiveFlags().
- *
- * Returns:
- *     SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.
- *     SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.
- *     SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.
- *     SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame
- *     SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).
- *     SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).
- *     SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).
- *     SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).
- *     SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.
- *     SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.
- *     SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum.
- *
- *     Note: If SKCS_OVERWRITE_STATUS is defined, the SKCS_STATUS_XXX values
- *     returned here can be defined in some header file by the module using CSUM.
- *     In this way, the calling module can assign return values for its own needs,
- *     e.g. by assigning bit flags to the individual protocols.
- */
-SKCS_STATUS SkCsGetReceiveInfo(
-SK_AC          *pAc,           /* Adapter context struct. */
-void           *pIpHeader,     /* IP header. */
-unsigned       Checksum1,      /* Hardware checksum 1. */
-unsigned       Checksum2,      /* Hardware checksum 2. */
-int                    NetNumber)      /* Net number */
-{
-       /* Internet Header Version found in IP header. */
-       unsigned InternetHeaderVersion;
-
-       /* Length of the IP header as found in IP header. */
-       unsigned IpHeaderLength;
-
-       /* Length of IP data portion. */
-       unsigned IpDataLength;
-
-       /* IP header checksum. */
-       unsigned IpHeaderChecksum;
-
-       /* IP header options checksum, if any. */
-       unsigned IpOptionsChecksum;
-
-       /* IP data checksum, i.e. TCP/UDP checksum. */
-       unsigned IpDataChecksum;
-
-       /* Next level protocol identifier found in IP header. */
-       unsigned NextLevelProtocol;
-
-       /* The checksum of the "next level protocol", i.e. TCP or UDP. */
-       unsigned long NextLevelProtocolChecksum;
-
-       /* Pointer to next level protocol statistics structure. */
-       SKCS_PROTO_STATS *NextLevelProtoStats;
-
-       /* Temporary variable. */
-       unsigned Tmp;
-
-       Tmp = *(SK_U8 *)
-               SKCS_IDX(pIpHeader, SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH);
-
-       /* Get the Internet Header Version (IHV). */
-       /* Note: The IHV is stored in the upper four bits. */
-
-       InternetHeaderVersion = Tmp >> 4;
-
-       /* Check the Internet Header Version. */
-       /* Note: We currently only support IP version 4. */
-
-       if (InternetHeaderVersion != 4) {       /* IPv4? */
-               SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_RX,
-                       ("Rx: Unknown Internet Header Version %u.\n",
-                       InternetHeaderVersion));
-               pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxUnableCts++;
-               return (SKCS_STATUS_UNKNOWN_IP_VERSION);
-       }
-
-       /* Get the IP header length (IHL). */
-       /*
-        * Note: The IHL is stored in the lower four bits as the number of
-        * 4-byte words.
-        */
-
-       IpHeaderLength = (Tmp & 0xf) * 4;
-
-       /* Check the IP header length. */
-
-       /* 04-Aug-1998 sw - Really check the IHL? Necessary? */
-
-       if (IpHeaderLength < 5*4) {
-               SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_RX,
-                       ("Rx: Invalid IP Header Length %u.\n", IpHeaderLength));
-               pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxErrCts++;
-               return (SKCS_STATUS_IP_CSUM_ERROR);
-       }
-
-       /* This is an IPv4 frame with a header of valid length. */
-
-       /* Get the IP header and data checksum. */
-
-       IpDataChecksum = Checksum2;
-
-       /*
-        * The IP header checksum is calculated as follows:
-        *
-        *      IpHeaderChecksum = Checksum1 - Checksum2
-        */
-
-       SKCS_OC_SUB(IpHeaderChecksum, Checksum1, Checksum2);
-
-       /* Check if any IP header options. */
-
-       if (IpHeaderLength > SKCS_IP_HEADER_SIZE) {
-
-               /* Get the IP options checksum. */
-
-               IpOptionsChecksum = SkCsCalculateChecksum(
-                       SKCS_IDX(pIpHeader, SKCS_IP_HEADER_SIZE),
-                       IpHeaderLength - SKCS_IP_HEADER_SIZE);
-
-               /* Adjust the IP header and IP data checksums. */
-
-               SKCS_OC_ADD(IpHeaderChecksum, IpHeaderChecksum, IpOptionsChecksum);
-
-               SKCS_OC_SUB(IpDataChecksum, IpDataChecksum, IpOptionsChecksum);
-       }
-
-       /*
-        * Check if the IP header checksum is ok.
-        *
-        * NOTE: We must check the IP header checksum even if the caller just wants
-        * us to check upper-layer checksums, because we cannot do any further
-        * processing of the packet without a valid IP checksum.
-        */
-
-       /* Get the next level protocol identifier. */
-
-       NextLevelProtocol = *(SK_U8 *)
-               SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL);
-
-       if (IpHeaderChecksum != 0xFFFF) {
-               pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxErrCts++;
-               /* the NDIS tester wants to know the upper level protocol too */
-               if (NextLevelProtocol == SKCS_PROTO_ID_TCP) {
-                       return(SKCS_STATUS_IP_CSUM_ERROR_TCP);
-               }
-               else if (NextLevelProtocol == SKCS_PROTO_ID_UDP) {
-                       return(SKCS_STATUS_IP_CSUM_ERROR_UDP);
-               }
-               return (SKCS_STATUS_IP_CSUM_ERROR);
-       }
-
-       /*
-        * Check if this is a TCP or UDP frame and if we should calculate the
-        * TCP/UDP pseudo header checksum.
-        *
-        * Also clear all protocol bit flags of protocols not present in the
-        * frame.
-        */
-
-       if ((pAc->Csum.ReceiveFlags[NetNumber] & SKCS_PROTO_TCP) != 0 &&
-               NextLevelProtocol == SKCS_PROTO_ID_TCP) {
-               /* TCP/IP frame. */
-               NextLevelProtoStats =
-                       &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_TCP];
-       }
-       else if ((pAc->Csum.ReceiveFlags[NetNumber] & SKCS_PROTO_UDP) != 0 &&
-               NextLevelProtocol == SKCS_PROTO_ID_UDP) {
-               /* UDP/IP frame. */
-               NextLevelProtoStats =
-                       &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_UDP];
-       }
-       else {
-               /*
-                * Either not a TCP or UDP frame and/or TCP/UDP processing not
-                * specified.
-                */
-               return (SKCS_STATUS_IP_CSUM_OK);
-       }
-
-       /* Check if this is an IP fragment. */
-
-       /*
-        * Note: An IP fragment has a non-zero "Fragment Offset" field and/or
-        * the "More Fragments" bit set. Thus, if both the "Fragment Offset"
-        * and the "More Fragments" are zero, it is *not* a fragment. We can
-        * easily check both at the same time since they are in the same 16-bit
-        * word.
-        */
-
-       if ((*(SK_U16 *)
-               SKCS_IDX(pIpHeader, SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET) &
-               ~SKCS_IP_DONT_FRAGMENT) != 0) {
-               /* IP fragment; ignore all other protocols. */
-               NextLevelProtoStats->RxUnableCts++;
-               return (SKCS_STATUS_IP_FRAGMENT);
-       }
-
-       /*
-        * 08-May-2000 ra
-        *
-        * From RFC 768 (UDP)
-        * If the computed checksum is zero, it is transmitted as all ones (the
-        * equivalent in one's complement arithmetic).  An all zero transmitted
-        * checksum value means that the transmitter generated no checksum (for
-        * debugging or for higher level protocols that don't care).
-        */
-
-       if (NextLevelProtocol == SKCS_PROTO_ID_UDP &&
-               *(SK_U16*)SKCS_IDX(pIpHeader, IpHeaderLength + 6) == 0x0000) {
-
-               NextLevelProtoStats->RxOkCts++;
-
-               return (SKCS_STATUS_IP_CSUM_OK_NO_UDP);
-       }
-
-       /*
-        * Calculate the TCP/UDP checksum.
-        */
-
-       /* Get total length of IP header and data. */
-
-       IpDataLength =
-               *(SK_U16 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_TOTAL_LENGTH);
-
-       /* Get length of IP data portion. */
-
-       IpDataLength = SKCS_NTOH16(IpDataLength) - IpHeaderLength;
-
-       NextLevelProtocolChecksum =
-
-               /* Calculate the pseudo header checksum. */
-
-               (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-                       SKCS_OFS_IP_SOURCE_ADDRESS + 0) +
-               (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-                       SKCS_OFS_IP_SOURCE_ADDRESS + 2) +
-               (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-                       SKCS_OFS_IP_DESTINATION_ADDRESS + 0) +
-               (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-                       SKCS_OFS_IP_DESTINATION_ADDRESS + 2) +
-               (unsigned long) SKCS_HTON16(NextLevelProtocol) +
-               (unsigned long) SKCS_HTON16(IpDataLength) +
-
-               /* Add the TCP/UDP header checksum. */
-
-               (unsigned long) IpDataChecksum;
-
-       /* Add-in any carries. */
-
-       SKCS_OC_ADD(NextLevelProtocolChecksum, NextLevelProtocolChecksum, 0);
-
-       /* Add-in any new carry. */
-
-       SKCS_OC_ADD(NextLevelProtocolChecksum, NextLevelProtocolChecksum, 0);
-
-       /* Check if the TCP/UDP checksum is ok. */
-
-       if ((unsigned) NextLevelProtocolChecksum == 0xFFFF) {
-
-               /* TCP/UDP checksum ok. */
-
-               NextLevelProtoStats->RxOkCts++;
-
-               return (NextLevelProtocol == SKCS_PROTO_ID_TCP ?
-                       SKCS_STATUS_TCP_CSUM_OK : SKCS_STATUS_UDP_CSUM_OK);
-       }
-
-       /* TCP/UDP checksum error. */
-
-       NextLevelProtoStats->RxErrCts++;
-
-       return (NextLevelProtocol == SKCS_PROTO_ID_TCP ?
-               SKCS_STATUS_TCP_CSUM_ERROR : SKCS_STATUS_UDP_CSUM_ERROR);
-}      /* SkCsGetReceiveInfo */
-#endif
-
-
-/******************************************************************************
- *
- *     SkCsSetReceiveFlags - set checksum receive flags
- *
- * Description:
- *     Use this function to set the various receive flags. According to the
- *     protocol flags set by the caller, the start offsets within received
- *     packets of the two hardware checksums are returned. These offsets must
- *     be stored in all receive descriptors.
- *
- * Arguments:
- *     pAc - Pointer to adapter context struct.
- *
- *     ReceiveFlags - Any combination of SK_PROTO_XXX flags of the protocols
- *     for which the caller wants checksum information on received frames.
- *
- *     pChecksum1Offset - The start offset of the first receive descriptor
- *     hardware checksum to be calculated for received frames is returned
- *     here.
- *
- *     pChecksum2Offset - The start offset of the second receive descriptor
- *     hardware checksum to be calculated for received frames is returned
- *     here.
- *
- * Returns: N/A
- *     Returns the two hardware checksum start offsets.
- */
-void SkCsSetReceiveFlags(
-SK_AC          *pAc,                           /* Adapter context struct. */
-unsigned       ReceiveFlags,           /* New receive flags. */
-unsigned       *pChecksum1Offset,      /* Offset for hardware checksum 1. */
-unsigned       *pChecksum2Offset,      /* Offset for hardware checksum 2. */
-int                    NetNumber)
-{
-       /* Save the receive flags. */
-
-       pAc->Csum.ReceiveFlags[NetNumber] = ReceiveFlags;
-
-       /* First checksum start offset is the IP header. */
-       *pChecksum1Offset = SKCS_MAC_HEADER_SIZE;
-
-       /*
-        * Second checksum start offset is the IP data. Note that this may vary
-        * if there are any IP header options in the actual packet.
-        */
-       *pChecksum2Offset = SKCS_MAC_HEADER_SIZE + SKCS_IP_HEADER_SIZE;
-}      /* SkCsSetReceiveFlags */
-
-#ifndef SkCsCalculateChecksum
-
-/******************************************************************************
- *
- *     SkCsCalculateChecksum - calculate checksum for specified data
- *
- * Description:
- *     Calculate and return the 16-bit Internet Checksum for the specified
- *     data.
- *
- * Arguments:
- *     pData - Pointer to data for which the checksum shall be calculated.
- *     Note: The pointer should be aligned on a 16-bit boundary.
- *
- *     Length - Length in bytes of data to checksum.
- *
- * Returns:
- *     The 16-bit Internet Checksum for the specified data.
- *
- *     Note: The checksum is calculated in the machine's natural byte order,
- *     i.e. little vs. big endian. Thus, the resulting checksum is different
- *     for the same input data on little and big endian machines.
- *
- *     However, when written back to the network packet, the byte order is
- *     always in correct network order.
- */
-unsigned SkCsCalculateChecksum(
-void           *pData,         /* Data to checksum. */
-unsigned       Length)         /* Length of data. */
-{
-       SK_U16 *pU16;           /* Pointer to the data as 16-bit words. */
-       unsigned long Checksum; /* Checksum; must be at least 32 bits. */
-
-       /* Sum up all 16-bit words. */
-
-       pU16 = (SK_U16 *) pData;
-       for (Checksum = 0; Length > 1; Length -= 2) {
-               Checksum += *pU16++;
-       }
-
-       /* If this is an odd number of bytes, add-in the last byte. */
-
-       if (Length > 0) {
-#ifdef SK_BIG_ENDIAN
-               /* Add the last byte as the high byte. */
-               Checksum += ((unsigned) *(SK_U8 *) pU16) << 8;
-#else  /* !SK_BIG_ENDIAN */
-               /* Add the last byte as the low byte. */
-               Checksum += *(SK_U8 *) pU16;
-#endif /* !SK_BIG_ENDIAN */
-       }
-
-       /* Add-in any carries. */
-
-       SKCS_OC_ADD(Checksum, Checksum, 0);
-
-       /* Add-in any new carry. */
-
-       SKCS_OC_ADD(Checksum, Checksum, 0);
-
-       /* Note: All bits beyond the 16-bit limit are now zero. */
-
-       return ((unsigned) Checksum);
-}      /* SkCsCalculateChecksum */
-
-#endif /* SkCsCalculateChecksum */
-
-/******************************************************************************
- *
- *     SkCsEvent - the CSUM event dispatcher
- *
- * Description:
- *     This is the event handler for the CSUM module.
- *
- * Arguments:
- *     pAc - Pointer to adapter context.
- *
- *     Ioc - I/O context.
- *
- *     Event -  Event id.
- *
- *     Param - Event dependent parameter.
- *
- * Returns:
- *     The 16-bit Internet Checksum for the specified data.
- *
- *     Note: The checksum is calculated in the machine's natural byte order,
- *     i.e. little vs. big endian. Thus, the resulting checksum is different
- *     for the same input data on little and big endian machines.
- *
- *     However, when written back to the network packet, the byte order is
- *     always in correct network order.
- */
-int SkCsEvent(
-SK_AC          *pAc,   /* Pointer to adapter context. */
-SK_IOC         Ioc,    /* I/O context. */
-SK_U32         Event,  /* Event id. */
-SK_EVPARA      Param)  /* Event dependent parameter. */
-{
-       int ProtoIndex;
-       int     NetNumber;
-
-       switch (Event) {
-       /*
-        * Clear protocol statistics.
-        *
-        * Param - Protocol index, or -1 for all protocols.
-        *               - Net number.
-        */
-       case SK_CSUM_EVENT_CLEAR_PROTO_STATS:
-
-               ProtoIndex = (int)Param.Para32[1];
-               NetNumber = (int)Param.Para32[0];
-               if (ProtoIndex < 0) {   /* Clear for all protocols. */
-                       if (NetNumber >= 0) {
-                               memset(&pAc->Csum.ProtoStats[NetNumber][0], 0,
-                                       sizeof(pAc->Csum.ProtoStats[NetNumber]));
-                       }
-               }
-               else {                                  /* Clear for individual protocol. */
-                       memset(&pAc->Csum.ProtoStats[NetNumber][ProtoIndex], 0,
-                               sizeof(pAc->Csum.ProtoStats[NetNumber][ProtoIndex]));
-               }
-               break;
-       default:
-               break;
-       }
-       return (0);     /* Success. */
-}      /* SkCsEvent */
-
-#endif /* SK_USE_CSUM */
-
-#endif /* CONFIG_SK98 */
diff --git a/drivers/sk98lin/skge.c b/drivers/sk98lin/skge.c
deleted file mode 100644 (file)
index 61a6094..0000000
+++ /dev/null
@@ -1,4864 +0,0 @@
-/******************************************************************************
- *
- * Name:    skge.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.46 $
- * Date:               $Date: 2003/02/25 14:16:36 $
- * Purpose:    The main driver source module
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     Driver for SysKonnect Gigabit Ethernet Server Adapters:
- *
- *     SK-9871 (single link 1000Base-ZX)
- *     SK-9872 (dual link   1000Base-ZX)
- *     SK-9861 (single link 1000Base-SX, VF45 Volition Plug)
- *     SK-9862 (dual link   1000Base-SX, VF45 Volition Plug)
- *     SK-9841 (single link 1000Base-LX)
- *     SK-9842 (dual link   1000Base-LX)
- *     SK-9843 (single link 1000Base-SX)
- *     SK-9844 (dual link   1000Base-SX)
- *     SK-9821 (single link 1000Base-T)
- *     SK-9822 (dual link   1000Base-T)
- *     SK-9881 (single link 1000Base-SX V2 LC)
- *     SK-9871 (single link 1000Base-ZX V2)
- *     SK-9861 (single link 1000Base-SX V2, VF45 Volition Plug)
- *     SK-9841 (single link 1000Base-LX V2)
- *     SK-9843 (single link 1000Base-SX V2)
- *     SK-9821 (single link 1000Base-T V2)
- *
- *     Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and
- *     SysKonnects GEnesis Solaris driver
- *     Author: Christoph Goos (cgoos@syskonnect.de)
- *             Mirko Lindner (mlindner@syskonnect.de)
- *
- *     Address all question to: linux@syskonnect.de
- *
- *     The technical manual for the adapters is available from SysKonnect's
- *     web pages: www.syskonnect.com
- *     Goto "Support" and search Knowledge Base for "manual".
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skge.c,v $
- *     Revision 1.46  2003/02/25 14:16:36  mlindner
- *     Fix: Copyright statement
- *
- *     Revision 1.45  2003/02/25 13:25:55  mlindner
- *     Add: Performance improvements
- *     Add: Support for various vendors
- *     Fix: Init function
- *
- *     Revision 1.44  2003/01/09 09:25:26  mlindner
- *     Fix: Remove useless init_module/cleanup_module forward declarations
- *
- *     Revision 1.43  2002/11/29 08:42:41  mlindner
- *     Fix: Boot message
- *
- *     Revision 1.42  2002/11/28 13:30:23  mlindner
- *     Add: New frame check
- *
- *     Revision 1.41  2002/11/27 13:55:18  mlindner
- *     Fix: Drop wrong csum packets
- *     Fix: Initialize proc_entry after hw check
- *
- *     Revision 1.40  2002/10/31 07:50:37  tschilli
- *     Function SkGeInitAssignRamToQueues() from common module inserted.
- *     Autonegotiation is set to ON for all adapters.
- *     LinkSpeedUsed is used in link up status report.
- *     Role parameter will show up for 1000 Mbps links only.
- *     GetConfiguration() inserted after init level 1 in SkGeChangeMtu().
- *     All return values of SkGeInit() and SkGeInitPort() are checked.
- *
- *     Revision 1.39  2002/10/02 12:56:05  mlindner
- *     Add: Support for Yukon
- *     Add: Support for ZEROCOPY, scatter-gather and hw checksum
- *     Add: New transmit ring function (use SG and TCP/UDP hardware checksumming)
- *     Add: New init function
- *     Add: Speed check and setup
- *     Add: Merge source for kernel 2.2.x and 2.4.x
- *     Add: Opcode check for tcp
- *     Add: Frame length check
- *     Fix: Transmit complete interrupt
- *     Fix: Interrupt moderation
- *
- *     Revision 1.29.2.13  2002/01/14 12:44:52  mlindner
- *     Fix: Rlmt modes
- *
- *     Revision 1.29.2.12  2001/12/07 12:06:18  mlindner
- *     Fix: malloc -> slab changes
- *
- *     Revision 1.29.2.11  2001/12/06 15:19:20  mlindner
- *     Add: DMA attributes
- *     Fix: Module initialisation
- *     Fix: pci_map_single and pci_unmap_single replaced
- *
- *     Revision 1.29.2.10  2001/12/06 09:56:50  mlindner
- *     Corrected some printk's
- *
- *     Revision 1.29.2.9  2001/09/05 12:15:34  mlindner
- *     Add: LBFO Changes
- *     Fix: Counter Errors (Jumbo == to long errors)
- *     Fix: Changed pAC->PciDev declaration
- *     Fix: too short counters
- *
- *     Revision 1.29.2.8  2001/06/25 12:10:44  mlindner
- *     fix: ReceiveIrq() changed.
- *
- *     Revision 1.29.2.7  2001/06/25 08:07:05  mlindner
- *     fix: RLMT locking in ReceiveIrq() changed.
- *
- *     Revision 1.29.2.6  2001/05/21 07:59:29  mlindner
- *     fix: MTU init problems
- *
- *     Revision 1.29.2.5  2001/05/08 11:25:08  mlindner
- *     fix: removed VLAN error message
- *
- *     Revision 1.29.2.4  2001/05/04 13:31:43  gklug
- *     fix: do not handle eth_copy on bad fragments received.
- *
- *     Revision 1.29.2.3  2001/04/23 08:06:43  mlindner
- *     Fix: error handling
- *
- *     Revision 1.29.2.2  2001/03/15 12:04:54  mlindner
- *     Fixed memory problem
- *
- *     Revision 1.29.2.1  2001/03/12 16:41:44  mlindner
- *     add: procfs function
- *     add: dual-net function
- *     add: RLMT networks
- *     add: extended PNMI features
- *
- *     Kernel 2.4.x specific:
- *     Revision 1.xx  2000/09/12 13:31:56  cgoos
- *     Fixed missign "dev=NULL in skge_probe.
- *     Added counting for jumbo frames (corrects error statistic).
- *     Removed VLAN tag check (enables VLAN support).
- *
- *     Kernel 2.2.x specific:
- *     Revision 1.29  2000/02/21 13:31:56  cgoos
- *     Fixed "unused" warning for UltraSPARC change.
- *
- *     Partially kernel 2.2.x specific:
- *     Revision 1.28  2000/02/21 10:32:36  cgoos
- *     Added fixes for UltraSPARC.
- *     Now printing RlmtMode and PrefPort setting at startup.
- *     Changed XmitFrame return value.
- *     Fixed rx checksum calculation for BIG ENDIAN systems.
- *     Fixed rx jumbo frames counted as ierrors.
- *
- *
- *     Revision 1.27  1999/11/25 09:06:28  cgoos
- *     Changed base_addr to unsigned long.
- *
- *     Revision 1.26  1999/11/22 13:29:16  cgoos
- *     Changed license header to GPL.
- *     Changes for inclusion in linux kernel (2.2.13).
- *     Removed 2.0.x defines.
- *     Changed SkGeProbe to skge_probe.
- *     Added checks in SkGeIoctl.
- *
- *     Revision 1.25  1999/10/07 14:47:52  cgoos
- *     Changed 984x to 98xx.
- *
- *     Revision 1.24  1999/09/30 07:21:01  cgoos
- *     Removed SK_RLMT_SLOW_LOOKAHEAD option.
- *     Giving spanning tree packets also to OS now.
- *
- *     Revision 1.23  1999/09/29 07:36:50  cgoos
- *     Changed assignment for IsBc/IsMc.
- *
- *     Revision 1.22  1999/09/28 12:57:09  cgoos
- *     Added CheckQueue also to Single-Port-ISR.
- *
- *     Revision 1.21  1999/09/28 12:42:41  cgoos
- *     Changed parameter strings for RlmtMode.
- *
- *     Revision 1.20  1999/09/28 12:37:57  cgoos
- *     Added CheckQueue for fast delivery of RLMT frames.
- *
- *     Revision 1.19  1999/09/16 07:57:25  cgoos
- *     Copperfield changes.
- *
- *     Revision 1.18  1999/09/03 13:06:30  cgoos
- *     Fixed RlmtMode=CheckSeg bug: wrong DEV_KFREE_SKB in RLMT_SEND caused
- *     double allocated skb's.
- *     FrameStat in ReceiveIrq was accessed via wrong Rxd.
- *     Queue size for async. standby Tx queue was zero.
- *     FillRxLimit of 0 could cause problems with ReQueue, changed to 1.
- *     Removed debug output of checksum statistic.
- *
- *     Revision 1.17  1999/08/11 13:55:27  cgoos
- *     Transmit descriptor polling was not reenabled after SkGePortInit.
- *
- *     Revision 1.16  1999/07/27 15:17:29  cgoos
- *     Added some "\n" in output strings (removed while debuging...).
- *
- *     Revision 1.15  1999/07/23 12:09:30  cgoos
- *     Performance optimization, rx checksumming, large frame support.
- *
- *     Revision 1.14  1999/07/14 11:26:27  cgoos
- *     Removed Link LED settings (now in RLMT).
- *     Added status output at NET UP.
- *     Fixed SMP problems with Tx and SWITCH running in parallel.
- *     Fixed return code problem at RLMT_SEND event.
- *
- *     Revision 1.13  1999/04/07 10:11:42  cgoos
- *     Fixed Single Port problems.
- *     Fixed Multi-Adapter problems.
- *     Always display startup string.
- *
- *     Revision 1.12  1999/03/29 12:26:37  cgoos
- *     Reversed locking to fine granularity.
- *     Fixed skb double alloc problem (caused by incorrect xmit return code).
- *     Enhanced function descriptions.
- *
- *     Revision 1.11  1999/03/15 13:10:51  cgoos
- *     Changed device identifier in output string to ethX.
- *
- *     Revision 1.10  1999/03/15 12:12:34  cgoos
- *     Changed copyright notice.
- *
- *     Revision 1.9  1999/03/15 12:10:17  cgoos
- *     Changed locking to one driver lock.
- *     Added check of SK_AC-size (for consistency with library).
- *
- *     Revision 1.8  1999/03/08 11:44:02  cgoos
- *     Fixed missing dev->tbusy in SkGeXmit.
- *     Changed large frame (jumbo) buffer number.
- *     Added copying of short frames.
- *
- *     Revision 1.7  1999/03/04 13:26:57  cgoos
- *     Fixed spinlock calls for SMP.
- *
- *     Revision 1.6  1999/03/02 09:53:51  cgoos
- *     Added descriptor revertion for big endian machines.
- *
- *     Revision 1.5  1999/03/01 08:50:59  cgoos
- *     Fixed SkGeChangeMtu.
- *     Fixed pci config space accesses.
- *
- *     Revision 1.4  1999/02/18 15:48:44  cgoos
- *     Corrected some printk's.
- *
- *     Revision 1.3  1999/02/18 12:45:55  cgoos
- *     Changed SK_MAX_CARD_PARAM to default 16
- *
- *     Revision 1.2  1999/02/18 10:55:32  cgoos
- *     Removed SkGeDrvTimeStamp function.
- *     Printing "ethX:" before adapter type at adapter init.
- *
- *
- *     10-Feb-1999 cg  Created, based on Linux' acenic.c, 3c59x.c and
- *                     SysKonnects GEnesis Solaris driver
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Possible compiler options (#define xxx / -Dxxx):
- *
- *     debugging can be enable by changing SK_DEBUG_CHKMOD and
- *     SK_DEBUG_CHKCAT in makefile (described there).
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- *     This is the main module of the Linux GE driver.
- *
- *     All source files except skge.c, skdrv1st.h, skdrv2nd.h and sktypes.h
- *     are part of SysKonnect's COMMON MODULES for the SK-98xx adapters.
- *     Those are used for drivers on multiple OS', so some thing may seem
- *     unnecessary complicated on Linux. Please do not try to 'clean up'
- *     them without VERY good reasons, because this will make it more
- *     difficult to keep the Linux driver in synchronisation with the
- *     other versions.
- *
- * Include file hierarchy:
- *
- *     <linux/module.h>
- *
- *     "h/skdrv1st.h"
- *             <linux/version.h>
- *             <linux/types.h>
- *             <linux/kernel.h>
- *             <linux/string.h>
- *             <linux/errno.h>
- *             <linux/ioport.h>
- *             <linux/slab.h>
- *             <linux/interrupt.h>
- *             <linux/pci.h>
- *             <asm/byteorder.h>
- *             <asm/bitops.h>
- *             <asm/io.h>
- *             <linux/netdevice.h>
- *             <linux/etherdevice.h>
- *             <linux/skbuff.h>
- *         those three depending on kernel version used:
- *             <linux/bios32.h>
- *             <linux/init.h>
- *             <asm/uaccess.h>
- *             <net/checksum.h>
- *
- *             "h/skerror.h"
- *             "h/skdebug.h"
- *             "h/sktypes.h"
- *             "h/lm80.h"
- *             "h/xmac_ii.h"
- *
- *      "h/skdrv2nd.h"
- *             "h/skqueue.h"
- *             "h/skgehwt.h"
- *             "h/sktimer.h"
- *             "h/ski2c.h"
- *             "h/skgepnmi.h"
- *             "h/skvpd.h"
- *             "h/skgehw.h"
- *             "h/skgeinit.h"
- *             "h/skaddr.h"
- *             "h/skgesirq.h"
- *             "h/skcsum.h"
- *             "h/skrlmt.h"
- *
- ******************************************************************************/
-
-#include <config.h>
-
-#ifdef CONFIG_SK98
-
-#include       "h/skversion.h"
-#if 0
-#include       <linux/module.h>
-#include       <linux/init.h>
-#include       <linux/proc_fs.h>
-#endif
-#include       "h/skdrv1st.h"
-#include       "h/skdrv2nd.h"
-
-
-/* defines ******************************************************************/
-/* for debuging on x86 only */
-/* #define BREAKPOINT() asm(" int $3"); */
-
-/* use the scatter-gather functionality with sendfile() */
-#if 0
-#define SK_ZEROCOPY
-#endif
-
-/* use of a transmit complete interrupt */
-#define USE_TX_COMPLETE
-
-/* use interrupt moderation (for tx complete only) */
-#define USE_INT_MOD
-#define INTS_PER_SEC   1000
-
-/*
- * threshold for copying small receive frames
- * set to 0 to avoid copying, set to 9001 to copy all frames
- */
-#define SK_COPY_THRESHOLD      50
-
-/* number of adapters that can be configured via command line params */
-#define SK_MAX_CARD_PARAM      16
-
-
-/*
- * use those defines for a compile-in version of the driver instead
- * of command line parameters
- */
-/* #define LINK_SPEED_A        {"Auto", }              */
-/* #define LINK_SPEED_B        {"Auto", }              */
-/* #define AUTO_NEG_A  {"Sense", }             */
-/* #define AUTO_NEG_B  {"Sense", }             */
-/* #define DUP_CAP_A   {"Both", }              */
-/* #define DUP_CAP_B   {"Both", }              */
-/* #define FLOW_CTRL_A {"SymOrRem", }          */
-/* #define FLOW_CTRL_B {"SymOrRem", }          */
-/* #define ROLE_A      {"Auto", }              */
-/* #define ROLE_B      {"Auto", }              */
-/* #define PREF_PORT   {"A", }                 */
-/* #define RLMT_MODE   {"CheckLinkState", }    */
-
-#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
-#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb)
-#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb)
-
-/* function prototypes ******************************************************/
-static void    FreeResources(struct SK_NET_DEVICE *dev);
-static int     SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC);
-static SK_BOOL BoardAllocMem(SK_AC *pAC);
-static void    BoardFreeMem(SK_AC *pAC);
-static void    BoardInitMem(SK_AC *pAC);
-static void    SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**,
-                       int*, SK_BOOL);
-
-#if 0
-static void    SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs);
-static void    SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs);
-static int     SkGeOpen(struct SK_NET_DEVICE *dev);
-static int     SkGeClose(struct SK_NET_DEVICE *dev);
-static int     SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev);
-static int     SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p);
-static void    SkGeSetRxMode(struct SK_NET_DEVICE *dev);
-static struct  net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev);
-static int     SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd);
-#else
-void   SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs);
-void   SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs);
-int    SkGeOpen(struct SK_NET_DEVICE *dev);
-int    SkGeClose(struct SK_NET_DEVICE *dev);
-int    SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev);
-#endif
-static void    GetConfiguration(SK_AC*);
-static void    ProductStr(SK_AC*);
-static int     XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*);
-static void    FreeTxDescriptors(SK_AC*pAC, TX_PORT*);
-static void    FillRxRing(SK_AC*, RX_PORT*);
-static SK_BOOL FillRxDescriptor(SK_AC*, RX_PORT*);
-#if 0
-static void    ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL);
-#else
-void   ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL);
-#endif
-static void ClearAndStartRx(SK_AC*, int);
-static void    ClearTxIrq(SK_AC*, int, int);
-static void    ClearRxRing(SK_AC*, RX_PORT*);
-static void    ClearTxRing(SK_AC*, TX_PORT*);
-#if 0
-static void    SetQueueSizes(SK_AC     *pAC);
-
-static int     SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu);
-#endif
-static void    PortReInitBmu(SK_AC*, int);
-#if 0
-static int     SkGeIocMib(DEV_NET*, unsigned int, int);
-static int     XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*);
-#endif
-
-/*Extern */
-
-/* external Proc function */
-extern int proc_read(
-       char    *buffer,
-       char    **buffer_location,
-       off_t   offset,
-       int             buffer_length,
-       int             *eof,
-       void    *data);
-
-#ifdef DEBUG
-static void    DumpMsg(struct sk_buff*, char*);
-static void    DumpData(char*, int);
-static void    DumpLong(char*, int);
-#endif
-void dump_frag( SK_U8 *data, int length);
-
-/* global variables *********************************************************/
-#if 0
-static const char *BootString = BOOT_STRING;
-#endif
-struct SK_NET_DEVICE *SkGeRootDev = NULL;
-static int probed __initdata = 0;
-
-/* local variables **********************************************************/
-static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
-static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
-
-
-/* local variables **********************************************************/
-const char SK_Root_Dir_entry[8];
-
-#if 0
-static struct proc_dir_entry   *pSkRootDir;
-#endif
-
-
-static struct pci_device_id supported[] = {
-       {PCI_VENDOR_ID_3COM, 0x1700},
-       {PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE},
-       {PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU},
-       {}
-};
-
-
-/*****************************************************************************
- *
- *     skge_probe - find all SK-98xx adapters
- *
- * Description:
- *     This function scans the PCI bus for SK-98xx adapters. Resources for
- *     each adapter are allocated and the adapter is brought into Init 1
- *     state.
- *
- * Returns:
- *     0, if everything is ok
- *     !=0, on error
- */
-#if 0
-static int __init skge_probe (void)
-#else
-int skge_probe (struct eth_device ** ret_dev)
-#endif
-{
-#if 0
-       int                     proc_root_initialized = 0;
-#endif
-       int                     boards_found = 0;
-#if 0
-       int                     vendor_flag = SK_FALSE;
-#endif
-       SK_AC                   *pAC;
-       DEV_NET                 *pNet = NULL;
-#if 0
-       struct proc_dir_entry   *pProcFile;
-       struct pci_dev  *pdev = NULL;
-       unsigned long           base_address;
-#else
-       u32                     base_address;
-#endif
-       struct SK_NET_DEVICE *dev = NULL;
-#if 0
-       SK_BOOL DeviceFound = SK_FALSE;
-#endif
-       SK_BOOL BootStringCount = SK_FALSE;
-#if 1
-       pci_dev_t devno;
-#endif
-
-       if (probed)
-               return -ENODEV;
-       probed++;
-
-       if (!pci_present())             /* is PCI support present? */
-               return -ENODEV;
-
-#if 0
-               while((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, pdev)))
-#else
-               while((devno = pci_find_devices (supported, boards_found)) >= 0)
-#endif
-               {
-
-               dev = NULL;
-               pNet = NULL;
-
-
-#if 0
-               SK_PCI_ISCOMPLIANT(vendor_flag, pdev);
-               if (!vendor_flag)
-                       continue;
-#endif
-
-/*             if ((pdev->vendor != PCI_VENDOR_ID_SYSKONNECT) &&
-                       ((pdev->device != PCI_DEVICE_ID_SYSKONNECT_GE) ||
-                       (pdev->device != PCI_DEVICE_ID_SYSKONNECT_YU))){
-                       continue;
-               }
-*/
-#if 0
-               /* Configure DMA attributes. */
-               if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff) &&
-                       pci_set_dma_mask(pdev, (u64) 0xffffffff))
-                       continue;
-#endif
-
-
-#if 0
-               if ((dev = init_etherdev(dev, sizeof(DEV_NET))) == NULL) {
-                       printk(KERN_ERR "Unable to allocate etherdev "
-                              "structure!\n");
-                       break;
-               }
-#else
-               dev = malloc (sizeof *dev);
-               memset(dev, 0, sizeof(*dev));
-               dev->priv = malloc(sizeof(DEV_NET));
-#endif
-
-               if (dev->priv == NULL) {
-                       printk(KERN_ERR "Unable to allocate adapter "
-                              "structure!\n");
-                       break;
-               }
-
-               pNet = dev->priv;
-               pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
-               if (pNet->pAC == NULL){
-                       kfree(dev->priv);
-                       printk(KERN_ERR "Unable to allocate adapter "
-                              "structure!\n");
-                       break;
-               }
-
-               /* Print message */
-               if (!BootStringCount) {
-                       /* set display flag to TRUE so that */
-                       /* we only display this string ONCE */
-                       BootStringCount = SK_TRUE;
-#ifdef SK98_INFO
-                       printk("%s\n", BootString);
-#endif
-               }
-
-               memset(pNet->pAC, 0, sizeof(SK_AC));
-               pAC = pNet->pAC;
-#if 0
-               pAC->PciDev = pdev;
-               pAC->PciDevId = pdev->device;
-               pAC->dev[0] = dev;
-               pAC->dev[1] = dev;
-#else
-               pAC->PciDev = devno;
-               ret_dev[0] = pAC->dev[0] = dev;
-               ret_dev[1] = pAC->dev[1] = dev;
-#endif
-               sprintf(pAC->Name, "SysKonnect SK-98xx");
-               pAC->CheckQueue = SK_FALSE;
-
-               pNet->Mtu = 1500;
-               pNet->Up = 0;
-#if 0
-               dev->irq = pdev->irq;
-
-               dev->open =             &SkGeOpen;
-               dev->stop =             &SkGeClose;
-               dev->hard_start_xmit =  &SkGeXmit;
-               dev->get_stats =        &SkGeStats;
-               dev->set_multicast_list = &SkGeSetRxMode;
-               dev->set_mac_address =  &SkGeSetMacAddr;
-               dev->do_ioctl =         &SkGeIoctl;
-               dev->change_mtu =       &SkGeChangeMtu;
-               dev->flags &=           ~IFF_RUNNING;
-#endif
-
-#ifdef SK_ZEROCOPY
-               if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
-                       /* Use only if yukon hardware */
-                       /* SK and ZEROCOPY - fly baby... */
-                       dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-               }
-#endif
-
-#if 0
-               /*
-                * Dummy value.
-                */
-               dev->base_addr = 42;
-               pci_set_master(pdev);
-
-               pci_set_master(pdev);
-               base_address = pci_resource_start (pdev, 0);
-#else
-               pci_write_config_dword(devno,
-                                      PCI_COMMAND,
-                                      PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
-               pci_read_config_dword (devno, PCI_BASE_ADDRESS_0,
-                                      &base_address);
-#endif
-
-#ifdef SK_BIG_ENDIAN
-               /*
-                * On big endian machines, we use the adapter's aibility of
-                * reading the descriptors as big endian.
-                */
-               {
-               SK_U32          our2;
-                       SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2);
-                       our2 |= PCI_REV_DESC;
-                       SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2);
-               }
-#endif
-
-               /*
-                * Remap the regs into kernel space.
-                */
-#if 0
-               pAC->IoBase = (char*)ioremap(base_address, 0x4000);
-#else
-               pAC->IoBase = (char*)pci_mem_to_phys(devno, base_address);
-#endif
-
-               if (!pAC->IoBase){
-                       printk(KERN_ERR "%s:  Unable to map I/O register, "
-                              "SK 98xx No. %i will be disabled.\n",
-                              dev->name, boards_found);
-                       kfree(dev);
-                       break;
-               }
-
-               pAC->Index = boards_found;
-               if (SkGeBoardInit(dev, pAC)) {
-                       FreeResources(dev);
-                       kfree(dev);
-                       continue;
-               }
-
-#if 0
-               memcpy((caddr_t) &dev->dev_addr,
-                       (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
-#else
-               memcpy((caddr_t) &dev->enetaddr,
-                       (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
-#endif
-
-#if 0
-               /* First adapter... Create proc and print message */
-               if (!DeviceFound) {
-                       DeviceFound = SK_TRUE;
-                       SK_MEMCPY(&SK_Root_Dir_entry, BootString,
-                               sizeof(SK_Root_Dir_entry) - 1);
-
-                       /*Create proc (directory)*/
-                       if(!proc_root_initialized) {
-                               pSkRootDir = create_proc_entry(SK_Root_Dir_entry,
-                                       S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net);
-                               proc_root_initialized = 1;
-                       }
-
-                       pSkRootDir->owner = THIS_MODULE;
-               }
-
-
-               /* Create proc file */
-               pProcFile = create_proc_entry(dev->name,
-                       S_IFREG | S_IXUSR | S_IWGRP | S_IROTH,
-                       pSkRootDir);
-
-
-               pProcFile->read_proc = proc_read;
-               pProcFile->write_proc = NULL;
-               pProcFile->nlink = 1;
-               pProcFile->size = sizeof(dev->name + 1);
-               pProcFile->data = (void *)pProcFile;
-#endif
-
-               pNet->PortNr = 0;
-               pNet->NetNr = 0;
-
-#ifdef SK_ZEROCOPY
-                       if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
-                               /* SG and ZEROCOPY - fly baby... */
-                               dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-                       }
-#endif
-
-               boards_found++;
-
-               /* More then one port found */
-               if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
-#if 0
-                       if ((dev = init_etherdev(NULL, sizeof(DEV_NET))) == 0) {
-                               printk(KERN_ERR "Unable to allocate etherdev "
-                                       "structure!\n");
-                               break;
-                       }
-#else
-                       dev = malloc (sizeof *dev);
-                       memset(dev, 0, sizeof(*dev));
-                       dev->priv = malloc(sizeof(DEV_NET));
-#endif
-
-                       pAC->dev[1] = dev;
-                       pNet = dev->priv;
-                       pNet->PortNr = 1;
-                       pNet->NetNr = 1;
-                       pNet->pAC = pAC;
-                       pNet->Mtu = 1500;
-                       pNet->Up = 0;
-
-#if 0
-                       dev->open =             &SkGeOpen;
-                       dev->stop =             &SkGeClose;
-                       dev->hard_start_xmit =  &SkGeXmit;
-                       dev->get_stats =        &SkGeStats;
-                       dev->set_multicast_list = &SkGeSetRxMode;
-                       dev->set_mac_address =  &SkGeSetMacAddr;
-                       dev->do_ioctl =         &SkGeIoctl;
-                       dev->change_mtu =       &SkGeChangeMtu;
-                       dev->flags &=           ~IFF_RUNNING;
-#endif
-
-#ifdef SK_ZEROCOPY
-                       if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
-                               /* SG and ZEROCOPY - fly baby... */
-                               dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-                       }
-#endif
-
-#if 0
-                       pProcFile = create_proc_entry(dev->name,
-                               S_IFREG | S_IXUSR | S_IWGRP | S_IROTH,
-                               pSkRootDir);
-
-
-                       pProcFile->read_proc = proc_read;
-                       pProcFile->write_proc = NULL;
-                       pProcFile->nlink = 1;
-                       pProcFile->size = sizeof(dev->name + 1);
-                       pProcFile->data = (void *)pProcFile;
-#endif
-
-#if 0
-                       memcpy((caddr_t) &dev->dev_addr,
-                       (caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6);
-#else
-                       memcpy((caddr_t) &dev->enetaddr,
-                       (caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6);
-#endif
-
-                       printk("%s: %s\n", dev->name, pAC->DeviceStr);
-                       printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");
-
-               }
-
-
-               /* Save the hardware revision */
-               pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
-                       (pAC->GIni.GIPciHwRev & 0x0F);
-
-               /*
-                * This is bollocks, but we need to tell the net-init
-                * code that it shall go for the next device.
-                */
-#if 0
-#ifndef MODULE
-               dev->base_addr = 0;
-#endif
-#endif
-       }
-
-       /*
-        * If we're at this point we're going through skge_probe() for
-        * the first time.  Return success (0) if we've initialized 1
-        * or more boards. Otherwise, return failure (-ENODEV).
-        */
-
-       return boards_found;
-} /* skge_probe */
-
-
-/*****************************************************************************
- *
- *     FreeResources - release resources allocated for adapter
- *
- * Description:
- *     This function releases the IRQ, unmaps the IO and
- *     frees the desriptor ring.
- *
- * Returns: N/A
- *
- */
-static void FreeResources(struct SK_NET_DEVICE *dev)
-{
-SK_U32 AllocFlag;
-DEV_NET                *pNet;
-SK_AC          *pAC;
-
-       if (dev->priv) {
-               pNet = (DEV_NET*) dev->priv;
-               pAC = pNet->pAC;
-               AllocFlag = pAC->AllocFlag;
-#if 0
-               if (AllocFlag & SK_ALLOC_IRQ) {
-                       free_irq(dev->irq, dev);
-               }
-               if (pAC->IoBase) {
-                       iounmap(pAC->IoBase);
-               }
-#endif
-               if (pAC->pDescrMem) {
-                       BoardFreeMem(pAC);
-               }
-       }
-
-} /* FreeResources */
-
-#if 0
-MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
-MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");
-MODULE_LICENSE("GPL");
-MODULE_PARM(Speed_A,    "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(Speed_B,    "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(AutoNeg_A,  "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(AutoNeg_B,  "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(DupCap_A,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(DupCap_B,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(FlowCtrl_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(FlowCtrl_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(Role_A,        "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(Role_B,        "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(PrefPort,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(RlmtMode,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-/* not used, just there because every driver should have them: */
-MODULE_PARM(options,    "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i");
-MODULE_PARM(debug,      "i");
-#endif
-
-
-#ifdef LINK_SPEED_A
-static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED_A;
-#else
-static char *Speed_A[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef LINK_SPEED_B
-static char *Speed_B[SK_MAX_CARD_PARAM] = LINK_SPEED_B;
-#else
-static char *Speed_B[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef AUTO_NEG_A
-static char *AutoNeg_A[SK_MAX_CARD_PARAM] = AUTO_NEG_A;
-#else
-static char *AutoNeg_A[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef DUP_CAP_A
-static char *DupCap_A[SK_MAX_CARD_PARAM] = DUP_CAP_A;
-#else
-static char *DupCap_A[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef FLOW_CTRL_A
-static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = FLOW_CTRL_A;
-#else
-static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef ROLE_A
-static char *Role_A[SK_MAX_CARD_PARAM] = ROLE_A;
-#else
-static char *Role_A[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef AUTO_NEG_B
-static char *AutoNeg_B[SK_MAX_CARD_PARAM] = AUTO_NEG_B;
-#else
-static char *AutoNeg_B[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef DUP_CAP_B
-static char *DupCap_B[SK_MAX_CARD_PARAM] = DUP_CAP_B;
-#else
-static char *DupCap_B[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef FLOW_CTRL_B
-static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = FLOW_CTRL_B;
-#else
-static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef ROLE_B
-static char *Role_B[SK_MAX_CARD_PARAM] = ROLE_B;
-#else
-static char *Role_B[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef PREF_PORT
-static char *PrefPort[SK_MAX_CARD_PARAM] = PREF_PORT;
-#else
-static char *PrefPort[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef RLMT_MODE
-static char *RlmtMode[SK_MAX_CARD_PARAM] = RLMT_MODE;
-#else
-static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#if 0
-static int debug = 0; /* not used */
-static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */
-
-
-/*****************************************************************************
- *
- *     skge_init_module - module initialization function
- *
- * Description:
- *     Very simple, only call skge_probe and return approriate result.
- *
- * Returns:
- *     0, if everything is ok
- *     !=0, on error
- */
-static int __init skge_init_module(void)
-{
-       int cards;
-       SkGeRootDev = NULL;
-
-       /* just to avoid warnings ... */
-       debug = 0;
-       options[0] = 0;
-
-       cards = skge_probe();
-       if (cards == 0) {
-               printk("sk98lin: No adapter found.\n");
-       }
-       return cards ? 0 : -ENODEV;
-} /* skge_init_module */
-
-
-/*****************************************************************************
- *
- *     skge_cleanup_module - module unload function
- *
- * Description:
- *     Disable adapter if it is still running, free resources,
- *     free device struct.
- *
- * Returns: N/A
- */
-static void __exit skge_cleanup_module(void)
-{
-DEV_NET                *pNet;
-SK_AC          *pAC;
-struct SK_NET_DEVICE *next;
-unsigned long Flags;
-SK_EVPARA EvPara;
-
-       while (SkGeRootDev) {
-               pNet = (DEV_NET*) SkGeRootDev->priv;
-               pAC = pNet->pAC;
-               next = pAC->Next;
-
-               netif_stop_queue(SkGeRootDev);
-               SkGeYellowLED(pAC, pAC->IoBase, 0);
-
-               if(pAC->BoardLevel == 2) {
-                       /* board is still alive */
-                       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-                       EvPara.Para32[0] = 0;
-                       EvPara.Para32[1] = -1;
-                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
-                       EvPara.Para32[0] = 1;
-                       EvPara.Para32[1] = -1;
-                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
-                       SkEventDispatcher(pAC, pAC->IoBase);
-                       /* disable interrupts */
-                       SK_OUT32(pAC->IoBase, B0_IMSK, 0);
-                       SkGeDeInit(pAC, pAC->IoBase);
-                       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-                       pAC->BoardLevel = 0;
-                       /* We do NOT check here, if IRQ was pending, of course*/
-               }
-
-               if(pAC->BoardLevel == 1) {
-                       /* board is still alive */
-                       SkGeDeInit(pAC, pAC->IoBase);
-                       pAC->BoardLevel = 0;
-               }
-
-               if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){
-                       unregister_netdev(pAC->dev[1]);
-                       kfree(pAC->dev[1]);
-               }
-
-               FreeResources(SkGeRootDev);
-
-               SkGeRootDev->get_stats = NULL;
-               /*
-                * otherwise unregister_netdev calls get_stats with
-                * invalid IO ...  :-(
-                */
-               unregister_netdev(SkGeRootDev);
-               kfree(SkGeRootDev);
-               kfree(pAC);
-               SkGeRootDev = next;
-       }
-
-       /* clear proc-dir */
-       remove_proc_entry(pSkRootDir->name, proc_net);
-
-} /* skge_cleanup_module */
-
-module_init(skge_init_module);
-module_exit(skge_cleanup_module);
-#endif
-
-
-/*****************************************************************************
- *
- *     SkGeBoardInit - do level 0 and 1 initialization
- *
- * Description:
- *     This function prepares the board hardware for running. The desriptor
- *     ring is set up, the IRQ is allocated and the configuration settings
- *     are examined.
- *
- * Returns:
- *     0, if everything is ok
- *     !=0, on error
- */
-static int __init SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC)
-{
-short  i;
-unsigned long Flags;
-char   *DescrString = "sk98lin: Driver for Linux"; /* this is given to PNMI */
-char   *VerStr = VER_STRING;
-#if 0
-int    Ret;                    /* return code of request_irq */
-#endif
-SK_BOOL        DualNet;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("IoBase: %08lX\n", (unsigned long)pAC->IoBase));
-       for (i=0; i<SK_MAX_MACS; i++) {
-               pAC->TxPort[i][0].HwAddr = pAC->IoBase + TxQueueAddr[i][0];
-               pAC->TxPort[i][0].PortIndex = i;
-               pAC->RxPort[i].HwAddr = pAC->IoBase + RxQueueAddr[i];
-               pAC->RxPort[i].PortIndex = i;
-       }
-
-       /* Initialize the mutexes */
-       for (i=0; i<SK_MAX_MACS; i++) {
-               spin_lock_init(&pAC->TxPort[i][0].TxDesRingLock);
-               spin_lock_init(&pAC->RxPort[i].RxDesRingLock);
-       }
-       spin_lock_init(&pAC->SlowPathLock);
-
-       /* level 0 init common modules here */
-
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-       /* Does a RESET on board ...*/
-       if (SkGeInit(pAC, pAC->IoBase, 0) != 0) {
-               printk("HWInit (0) failed.\n");
-               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-               return(-EAGAIN);
-       }
-       SkI2cInit(  pAC, pAC->IoBase, 0);
-       SkEventInit(pAC, pAC->IoBase, 0);
-       SkPnmiInit( pAC, pAC->IoBase, 0);
-       SkAddrInit( pAC, pAC->IoBase, 0);
-       SkRlmtInit( pAC, pAC->IoBase, 0);
-       SkTimerInit(pAC, pAC->IoBase, 0);
-
-       pAC->BoardLevel = 0;
-       pAC->RxBufSize = ETH_BUF_SIZE;
-
-       SK_PNMI_SET_DRIVER_DESCR(pAC, DescrString);
-       SK_PNMI_SET_DRIVER_VER(pAC, VerStr);
-
-       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
-       /* level 1 init common modules here (HW init) */
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-       if (SkGeInit(pAC, pAC->IoBase, 1) != 0) {
-               printk("HWInit (1) failed.\n");
-               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-               return(-EAGAIN);
-       }
-       SkI2cInit(  pAC, pAC->IoBase, 1);
-       SkEventInit(pAC, pAC->IoBase, 1);
-       SkPnmiInit( pAC, pAC->IoBase, 1);
-       SkAddrInit( pAC, pAC->IoBase, 1);
-       SkRlmtInit( pAC, pAC->IoBase, 1);
-       SkTimerInit(pAC, pAC->IoBase, 1);
-
-       GetConfiguration(pAC);
-       if (pAC->RlmtNets == 2) {
-               pAC->GIni.GIPortUsage = SK_MUL_LINK;
-       }
-
-       pAC->BoardLevel = 1;
-       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
-#if 0
-       if (pAC->GIni.GIMacsFound == 2) {
-                Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
-       } else if (pAC->GIni.GIMacsFound == 1) {
-               Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ,
-                       pAC->Name, dev);
-       } else {
-               printk(KERN_WARNING "%s: Illegal number of ports: %d\n",
-                      dev->name, pAC->GIni.GIMacsFound);
-               return -EAGAIN;
-       }
-
-       if (Ret) {
-               printk(KERN_WARNING "%s: Requested IRQ %d is busy.\n",
-                      dev->name, dev->irq);
-               return -EAGAIN;
-       }
-#endif
-       pAC->AllocFlag |= SK_ALLOC_IRQ;
-
-       /* Alloc memory for this board (Mem for RxD/TxD) : */
-       if(!BoardAllocMem(pAC)) {
-               printk("No memory for descriptor rings.\n");
-               return(-EAGAIN);
-       }
-
-       SkCsSetReceiveFlags(pAC,
-               SKCS_PROTO_IP | SKCS_PROTO_TCP | SKCS_PROTO_UDP,
-               &pAC->CsOfs1, &pAC->CsOfs2, 0);
-       pAC->CsOfs = (pAC->CsOfs2 << 16) | pAC->CsOfs1;
-
-       BoardInitMem(pAC);
-#if 0
-       SetQueueSizes(pAC);
-#else
-       /* tschilling: New common function with minimum size check. */
-       DualNet = SK_FALSE;
-       if (pAC->RlmtNets == 2) {
-               DualNet = SK_TRUE;
-       }
-
-       if (SkGeInitAssignRamToQueues(
-               pAC,
-               pAC->ActivePort,
-               DualNet)) {
-               BoardFreeMem(pAC);
-               printk("SkGeInitAssignRamToQueues failed.\n");
-               return(-EAGAIN);
-       }
-#endif
-
-       /* Print adapter specific string from vpd */
-       ProductStr(pAC);
-#ifdef SK98_INFO
-       printk("%s: %s\n", dev->name, pAC->DeviceStr);
-
-       /* Print configuration settings */
-       printk("      PrefPort:%c  RlmtMode:%s\n",
-               'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
-               (pAC->RlmtMode==0)  ? "Check Link State" :
-               ((pAC->RlmtMode==1) ? "Check Link State" :
-               ((pAC->RlmtMode==3) ? "Check Local Port" :
-               ((pAC->RlmtMode==7) ? "Check Segmentation" :
-               ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
-#endif
-
-       SkGeYellowLED(pAC, pAC->IoBase, 1);
-
-       /*
-        * Register the device here
-        */
-       pAC->Next = SkGeRootDev;
-       SkGeRootDev = dev;
-
-       return (0);
-} /* SkGeBoardInit */
-
-
-/*****************************************************************************
- *
- *     BoardAllocMem - allocate the memory for the descriptor rings
- *
- * Description:
- *     This function allocates the memory for all descriptor rings.
- *     Each ring is aligned for the desriptor alignment and no ring
- *     has a 4 GByte boundary in it (because the upper 32 bit must
- *     be constant for all descriptiors in one rings).
- *
- * Returns:
- *     SK_TRUE, if all memory could be allocated
- *     SK_FALSE, if not
- */
-static SK_BOOL BoardAllocMem(
-SK_AC  *pAC)
-{
-caddr_t                pDescrMem;      /* pointer to descriptor memory area */
-size_t         AllocLength;    /* length of complete descriptor area */
-int            i;              /* loop counter */
-unsigned long  BusAddr;
-
-
-       /* rings plus one for alignment (do not cross 4 GB boundary) */
-       /* RX_RING_SIZE is assumed bigger than TX_RING_SIZE */
-#if (BITS_PER_LONG == 32)
-       AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
-#else
-       AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
-               + RX_RING_SIZE + 8;
-#endif
-
-       pDescrMem = pci_alloc_consistent(pAC->PciDev, AllocLength,
-                                        &pAC->pDescrMemDMA);
-
-       if (pDescrMem == NULL) {
-               return (SK_FALSE);
-       }
-       pAC->pDescrMem = pDescrMem;
-       BusAddr = (unsigned long) pAC->pDescrMemDMA;
-
-       /* Descriptors need 8 byte alignment, and this is ensured
-        * by pci_alloc_consistent.
-        */
-       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
-                       ("TX%d/A: pDescrMem: %lX,   PhysDescrMem: %lX\n",
-                       i, (unsigned long) pDescrMem,
-                       BusAddr));
-               pAC->TxPort[i][0].pTxDescrRing = pDescrMem;
-               pAC->TxPort[i][0].VTxDescrRing = BusAddr;
-               pDescrMem += TX_RING_SIZE;
-               BusAddr += TX_RING_SIZE;
-
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
-                       ("RX%d: pDescrMem: %lX,   PhysDescrMem: %lX\n",
-                       i, (unsigned long) pDescrMem,
-                       (unsigned long)BusAddr));
-               pAC->RxPort[i].pRxDescrRing = pDescrMem;
-               pAC->RxPort[i].VRxDescrRing = BusAddr;
-               pDescrMem += RX_RING_SIZE;
-               BusAddr += RX_RING_SIZE;
-       } /* for */
-
-       return (SK_TRUE);
-} /* BoardAllocMem */
-
-
-/****************************************************************************
- *
- *     BoardFreeMem - reverse of BoardAllocMem
- *
- * Description:
- *     Free all memory allocated in BoardAllocMem: adapter context,
- *     descriptor rings, locks.
- *
- * Returns:    N/A
- */
-static void BoardFreeMem(
-SK_AC          *pAC)
-{
-size_t         AllocLength;    /* length of complete descriptor area */
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("BoardFreeMem\n"));
-#if (BITS_PER_LONG == 32)
-       AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
-#else
-       AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
-               + RX_RING_SIZE + 8;
-#endif
-
-       pci_free_consistent(pAC->PciDev, AllocLength,
-                           pAC->pDescrMem, pAC->pDescrMemDMA);
-       pAC->pDescrMem = NULL;
-} /* BoardFreeMem */
-
-
-/*****************************************************************************
- *
- *     BoardInitMem - initiate the descriptor rings
- *
- * Description:
- *     This function sets the descriptor rings up in memory.
- *     The adapter is initialized with the descriptor start addresses.
- *
- * Returns:    N/A
- */
-static void BoardInitMem(
-SK_AC  *pAC)   /* pointer to adapter context */
-{
-int    i;              /* loop counter */
-int    RxDescrSize;    /* the size of a rx descriptor rounded up to alignment*/
-int    TxDescrSize;    /* the size of a tx descriptor rounded up to alignment*/
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("BoardInitMem\n"));
-
-       RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
-       pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize;
-       TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
-       pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize;
-
-       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-               SetupRing(
-                       pAC,
-                       pAC->TxPort[i][0].pTxDescrRing,
-                       pAC->TxPort[i][0].VTxDescrRing,
-                       (RXD**)&pAC->TxPort[i][0].pTxdRingHead,
-                       (RXD**)&pAC->TxPort[i][0].pTxdRingTail,
-                       (RXD**)&pAC->TxPort[i][0].pTxdRingPrev,
-                       &pAC->TxPort[i][0].TxdRingFree,
-                       SK_TRUE);
-               SetupRing(
-                       pAC,
-                       pAC->RxPort[i].pRxDescrRing,
-                       pAC->RxPort[i].VRxDescrRing,
-                       &pAC->RxPort[i].pRxdRingHead,
-                       &pAC->RxPort[i].pRxdRingTail,
-                       &pAC->RxPort[i].pRxdRingPrev,
-                       &pAC->RxPort[i].RxdRingFree,
-                       SK_FALSE);
-       }
-} /* BoardInitMem */
-
-
-/*****************************************************************************
- *
- *     SetupRing - create one descriptor ring
- *
- * Description:
- *     This function creates one descriptor ring in the given memory area.
- *     The head, tail and number of free descriptors in the ring are set.
- *
- * Returns:
- *     none
- */
-static void SetupRing(
-SK_AC          *pAC,
-void           *pMemArea,      /* a pointer to the memory area for the ring */
-uintptr_t      VMemArea,       /* the virtual bus address of the memory area */
-RXD            **ppRingHead,   /* address where the head should be written */
-RXD            **ppRingTail,   /* address where the tail should be written */
-RXD            **ppRingPrev,   /* address where the tail should be written */
-int            *pRingFree,     /* address where the # of free descr. goes */
-SK_BOOL                IsTx)           /* flag: is this a tx ring */
-{
-int    i;              /* loop counter */
-int    DescrSize;      /* the size of a descriptor rounded up to alignment*/
-int    DescrNum;       /* number of descriptors per ring */
-RXD    *pDescr;        /* pointer to a descriptor (receive or transmit) */
-RXD    *pNextDescr;    /* pointer to the next descriptor */
-RXD    *pPrevDescr;    /* pointer to the previous descriptor */
-uintptr_t VNextDescr;  /* the virtual bus address of the next descriptor */
-
-       if (IsTx == SK_TRUE) {
-               DescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) *
-                       DESCR_ALIGN;
-               DescrNum = TX_RING_SIZE / DescrSize;
-       } else {
-               DescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) *
-                       DESCR_ALIGN;
-               DescrNum = RX_RING_SIZE / DescrSize;
-       }
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
-               ("Descriptor size: %d   Descriptor Number: %d\n",
-               DescrSize,DescrNum));
-
-       pDescr = (RXD*) pMemArea;
-       pPrevDescr = NULL;
-       pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
-       VNextDescr = VMemArea + DescrSize;
-       for(i=0; i<DescrNum; i++) {
-               /* set the pointers right */
-               pDescr->VNextRxd = VNextDescr & 0xffffffffULL;
-               pDescr->pNextRxd = pNextDescr;
-               pDescr->TcpSumStarts = pAC->CsOfs;
-
-               /* advance one step */
-               pPrevDescr = pDescr;
-               pDescr = pNextDescr;
-               pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
-               VNextDescr += DescrSize;
-       }
-       pPrevDescr->pNextRxd = (RXD*) pMemArea;
-       pPrevDescr->VNextRxd = VMemArea;
-       pDescr = (RXD*) pMemArea;
-       *ppRingHead = (RXD*) pMemArea;
-       *ppRingTail = *ppRingHead;
-       *ppRingPrev = pPrevDescr;
-       *pRingFree = DescrNum;
-} /* SetupRing */
-
-
-/*****************************************************************************
- *
- *     PortReInitBmu - re-initiate the descriptor rings for one port
- *
- * Description:
- *     This function reinitializes the descriptor rings of one port
- *     in memory. The port must be stopped before.
- *     The HW is initialized with the descriptor start addresses.
- *
- * Returns:
- *     none
- */
-static void PortReInitBmu(
-SK_AC  *pAC,           /* pointer to adapter context */
-int    PortIndex)      /* index of the port for which to re-init */
-{
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("PortReInitBmu "));
-
-       /* set address of first descriptor of ring in BMU */
-       SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+
-               TX_Q_CUR_DESCR_LOW,
-               (uint32_t)(((caddr_t)
-               (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
-               pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
-               pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) &
-               0xFFFFFFFF));
-       SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+
-               TX_Q_DESCR_HIGH,
-               (uint32_t)(((caddr_t)
-               (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
-               pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
-               pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) >> 32));
-       SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+RX_Q_CUR_DESCR_LOW,
-               (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
-               pAC->RxPort[PortIndex].pRxDescrRing +
-               pAC->RxPort[PortIndex].VRxDescrRing) & 0xFFFFFFFF));
-       SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+RX_Q_DESCR_HIGH,
-               (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
-               pAC->RxPort[PortIndex].pRxDescrRing +
-               pAC->RxPort[PortIndex].VRxDescrRing) >> 32));
-} /* PortReInitBmu */
-
-
-/****************************************************************************
- *
- *     SkGeIsr - handle adapter interrupts
- *
- * Description:
- *     The interrupt routine is called when the network adapter
- *     generates an interrupt. It may also be called if another device
- *     shares this interrupt vector with the driver.
- *
- * Returns: N/A
- *
- */
-#if 0
-static void SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs)
-#else
-void SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs)
-#endif
-{
-struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
-DEV_NET                *pNet;
-SK_AC          *pAC;
-SK_U32         IntSrc;         /* interrupts source register contents */
-
-       pNet = (DEV_NET*) dev->priv;
-       pAC = pNet->pAC;
-
-       /*
-        * Check and process if its our interrupt
-        */
-       SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
-       if (IntSrc == 0) {
-               return;
-       }
-
-       while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
-#if 0 /* software irq currently not used */
-               if (IntSrc & IRQ_SW) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("Software IRQ\n"));
-               }
-#endif
-               if (IntSrc & IRQ_EOF_RX1) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF RX1 IRQ\n"));
-                       ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
-                       SK_PNMI_CNT_RX_INTR(pAC, 0);
-               }
-               if (IntSrc & IRQ_EOF_RX2) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF RX2 IRQ\n"));
-                       ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
-                       SK_PNMI_CNT_RX_INTR(pAC, 1);
-               }
-#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
-               if (IntSrc & IRQ_EOF_AS_TX1) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF AS TX1 IRQ\n"));
-                       SK_PNMI_CNT_TX_INTR(pAC, 0);
-                       spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
-                       FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
-                       spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
-               }
-               if (IntSrc & IRQ_EOF_AS_TX2) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF AS TX2 IRQ\n"));
-                       SK_PNMI_CNT_TX_INTR(pAC, 1);
-                       spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
-                       FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]);
-                       spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
-               }
-#if 0 /* only if sync. queues used */
-               if (IntSrc & IRQ_EOF_SY_TX1) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF SY TX1 IRQ\n"));
-                       SK_PNMI_CNT_TX_INTR(pAC, 1);
-                       spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
-                       FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
-                       spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
-                       ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
-               }
-               if (IntSrc & IRQ_EOF_SY_TX2) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF SY TX2 IRQ\n"));
-                       SK_PNMI_CNT_TX_INTR(pAC, 1);
-                       spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
-                       FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH);
-                       spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
-                       ClearTxIrq(pAC, 1, TX_PRIO_HIGH);
-               }
-#endif
-#endif
-
-               /* do all IO at once */
-               if (IntSrc & IRQ_EOF_RX1)
-                       ClearAndStartRx(pAC, 0);
-               if (IntSrc & IRQ_EOF_RX2)
-                       ClearAndStartRx(pAC, 1);
-#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
-               if (IntSrc & IRQ_EOF_AS_TX1)
-                       ClearTxIrq(pAC, 0, TX_PRIO_LOW);
-               if (IntSrc & IRQ_EOF_AS_TX2)
-                       ClearTxIrq(pAC, 1, TX_PRIO_LOW);
-#endif
-               SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
-       } /* while (IntSrc & IRQ_MASK != 0) */
-
-       if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
-                       ("SPECIAL IRQ DP-Cards => %x\n", IntSrc));
-               pAC->CheckQueue = SK_FALSE;
-               spin_lock(&pAC->SlowPathLock);
-               if (IntSrc & SPECIAL_IRQS)
-                       SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
-
-               SkEventDispatcher(pAC, pAC->IoBase);
-               spin_unlock(&pAC->SlowPathLock);
-       }
-       /*
-        * do it all again is case we cleared an interrupt that
-        * came in after handling the ring (OUTs may be delayed
-        * in hardware buffers, but are through after IN)
-        */
-
-       ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
-       ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
-
-       if (pAC->CheckQueue) {
-               pAC->CheckQueue = SK_FALSE;
-               spin_lock(&pAC->SlowPathLock);
-               SkEventDispatcher(pAC, pAC->IoBase);
-               spin_unlock(&pAC->SlowPathLock);
-       }
-
-
-       /* IRQ is processed - Enable IRQs again*/
-       SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK);
-
-       return;
-} /* SkGeIsr */
-
-
-/****************************************************************************
- *
- *     SkGeIsrOnePort - handle adapter interrupts for single port adapter
- *
- * Description:
- *     The interrupt routine is called when the network adapter
- *     generates an interrupt. It may also be called if another device
- *     shares this interrupt vector with the driver.
- *     This is the same as above, but handles only one port.
- *
- * Returns: N/A
- *
- */
-#if 0
-static void SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs)
-#else
-void SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs)
-#endif
-{
-struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
-DEV_NET                *pNet;
-SK_AC          *pAC;
-SK_U32         IntSrc;         /* interrupts source register contents */
-
-       pNet = (DEV_NET*) dev->priv;
-       pAC = pNet->pAC;
-
-       /*
-        * Check and process if its our interrupt
-        */
-       SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
-       if (IntSrc == 0) {
-               return;
-       }
-
-       while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
-#if 0 /* software irq currently not used */
-               if (IntSrc & IRQ_SW) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("Software IRQ\n"));
-               }
-#endif
-               if (IntSrc & IRQ_EOF_RX1) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF RX1 IRQ\n"));
-                       ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
-                       SK_PNMI_CNT_RX_INTR(pAC, 0);
-               }
-#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
-               if (IntSrc & IRQ_EOF_AS_TX1) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF AS TX1 IRQ\n"));
-                       SK_PNMI_CNT_TX_INTR(pAC, 0);
-                       spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
-                       FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
-                       spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
-               }
-#if 0 /* only if sync. queues used */
-               if (IntSrc & IRQ_EOF_SY_TX1) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF SY TX1 IRQ\n"));
-                       SK_PNMI_CNT_TX_INTR(pAC, 0);
-                       spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
-                       FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
-                       spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
-                       ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
-               }
-#endif
-#endif
-
-               /* do all IO at once */
-               if (IntSrc & IRQ_EOF_RX1)
-                       ClearAndStartRx(pAC, 0);
-#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
-               if (IntSrc & IRQ_EOF_AS_TX1)
-                       ClearTxIrq(pAC, 0, TX_PRIO_LOW);
-#endif
-               SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
-       } /* while (IntSrc & IRQ_MASK != 0) */
-
-       if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
-                       ("SPECIAL IRQ SP-Cards => %x\n", IntSrc));
-               pAC->CheckQueue = SK_FALSE;
-               spin_lock(&pAC->SlowPathLock);
-               if (IntSrc & SPECIAL_IRQS)
-                       SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
-
-               SkEventDispatcher(pAC, pAC->IoBase);
-               spin_unlock(&pAC->SlowPathLock);
-       }
-       /*
-        * do it all again is case we cleared an interrupt that
-        * came in after handling the ring (OUTs may be delayed
-        * in hardware buffers, but are through after IN)
-        */
-       ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
-
-       /* IRQ is processed - Enable IRQs again*/
-       SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK);
-
-       return;
-} /* SkGeIsrOnePort */
-
-
-/****************************************************************************
- *
- *     SkGeOpen - handle start of initialized adapter
- *
- * Description:
- *     This function starts the initialized adapter.
- *     The board level variable is set and the adapter is
- *     brought to full functionality.
- *     The device flags are set for operation.
- *     Do all necessary level 2 initialization, enable interrupts and
- *     give start command to RLMT.
- *
- * Returns:
- *     0 on success
- *     != 0 on error
- */
-#if 0
-static int SkGeOpen(
-#else
-int SkGeOpen(
-#endif
-struct SK_NET_DEVICE   *dev)
-{
-       DEV_NET                 *pNet;
-       SK_AC                   *pAC;
-       unsigned long   Flags;          /* for spin lock */
-       int                             i;
-       SK_EVPARA               EvPara;         /* an event parameter union */
-
-       pNet = (DEV_NET*) dev->priv;
-       pAC = pNet->pAC;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC));
-
-       if (pAC->BoardLevel == 0) {
-               /* level 1 init common modules here */
-               if (SkGeInit(pAC, pAC->IoBase, 1) != 0) {
-                       printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name);
-                       return (-1);
-               }
-               SkI2cInit       (pAC, pAC->IoBase, 1);
-               SkEventInit     (pAC, pAC->IoBase, 1);
-               SkPnmiInit      (pAC, pAC->IoBase, 1);
-               SkAddrInit      (pAC, pAC->IoBase, 1);
-               SkRlmtInit      (pAC, pAC->IoBase, 1);
-               SkTimerInit     (pAC, pAC->IoBase, 1);
-               pAC->BoardLevel = 1;
-       }
-
-       if (pAC->BoardLevel != 2) {
-               /* tschilling: Level 2 init modules here, check return value. */
-               if (SkGeInit(pAC, pAC->IoBase, 2) != 0) {
-                       printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name);
-                       return (-1);
-               }
-               SkI2cInit       (pAC, pAC->IoBase, 2);
-               SkEventInit     (pAC, pAC->IoBase, 2);
-               SkPnmiInit      (pAC, pAC->IoBase, 2);
-               SkAddrInit      (pAC, pAC->IoBase, 2);
-               SkRlmtInit      (pAC, pAC->IoBase, 2);
-               SkTimerInit     (pAC, pAC->IoBase, 2);
-               pAC->BoardLevel = 2;
-       }
-
-       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-               /* Enable transmit descriptor polling. */
-               SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
-               FillRxRing(pAC, &pAC->RxPort[i]);
-       }
-       SkGeYellowLED(pAC, pAC->IoBase, 1);
-
-#ifdef USE_INT_MOD
-/* moderate only TX complete interrupts (these are not time critical) */
-#define IRQ_MOD_MASK (IRQ_EOF_AS_TX1 | IRQ_EOF_AS_TX2)
-       {
-               unsigned long ModBase;
-               ModBase = 53125000 / INTS_PER_SEC;
-               SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
-               SK_OUT32(pAC->IoBase, B2_IRQM_MSK, IRQ_MOD_MASK);
-               SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
-       }
-#endif
-
-       /* enable Interrupts */
-       SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK);
-       SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
-
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-
-       if ((pAC->RlmtMode != 0) && (pAC->MaxPorts == 0)) {
-               EvPara.Para32[0] = pAC->RlmtNets;
-               EvPara.Para32[1] = -1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
-                       EvPara);
-               EvPara.Para32[0] = pAC->RlmtMode;
-               EvPara.Para32[1] = 0;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE,
-                       EvPara);
-       }
-
-       EvPara.Para32[0] = pNet->NetNr;
-       EvPara.Para32[1] = -1;
-       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
-       SkEventDispatcher(pAC, pAC->IoBase);
-       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
-       pAC->MaxPorts++;
-       pNet->Up = 1;
-
-       MOD_INC_USE_COUNT;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeOpen suceeded\n"));
-
-       return (0);
-} /* SkGeOpen */
-
-
-/****************************************************************************
- *
- *     SkGeClose - Stop initialized adapter
- *
- * Description:
- *     Close initialized adapter.
- *
- * Returns:
- *     0 - on success
- *     error code - on error
- */
-#if 0
-static int SkGeClose(
-#else
-int SkGeClose(
-#endif
-struct SK_NET_DEVICE   *dev)
-{
-       DEV_NET                 *pNet;
-       SK_AC                   *pAC;
-
-       unsigned long   Flags;          /* for spin lock */
-       int                             i;
-       int                             PortIdx;
-       SK_EVPARA               EvPara;
-
-       netif_stop_queue(dev);
-       pNet = (DEV_NET*) dev->priv;
-       pAC = pNet->pAC;
-
-       if (pAC->RlmtNets == 1)
-               PortIdx = pAC->ActivePort;
-       else
-               PortIdx = pNet->NetNr;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
-
-       /*
-        * Clear multicast table, promiscuous mode ....
-        */
-       SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
-       SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
-               SK_PROM_MODE_NONE);
-
-       if (pAC->MaxPorts == 1) {
-               spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-               /* disable interrupts */
-               SK_OUT32(pAC->IoBase, B0_IMSK, 0);
-               EvPara.Para32[0] = pNet->NetNr;
-               EvPara.Para32[1] = -1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
-               SkEventDispatcher(pAC, pAC->IoBase);
-               SK_OUT32(pAC->IoBase, B0_IMSK, 0);
-               /* stop the hardware */
-               SkGeDeInit(pAC, pAC->IoBase);
-               pAC->BoardLevel = 0;
-               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-       } else {
-
-               spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-               EvPara.Para32[0] = pNet->NetNr;
-               EvPara.Para32[1] = -1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
-               SkEventDispatcher(pAC, pAC->IoBase);
-               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
-               /* Stop port */
-               spin_lock_irqsave(&pAC->TxPort[pNet->PortNr]
-                       [TX_PRIO_LOW].TxDesRingLock, Flags);
-               SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr,
-                       SK_STOP_ALL, SK_HARD_RST);
-               spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr]
-                       [TX_PRIO_LOW].TxDesRingLock, Flags);
-       }
-
-       if (pAC->RlmtNets == 1) {
-               /* clear all descriptor rings */
-               for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-                       ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
-                       ClearRxRing(pAC, &pAC->RxPort[i]);
-                       ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]);
-               }
-       } else {
-               /* clear port descriptor rings */
-               ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE);
-               ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
-               ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]);
-       }
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeClose: done "));
-
-       pAC->MaxPorts--;
-       pNet->Up = 0;
-       MOD_DEC_USE_COUNT;
-
-       return (0);
-} /* SkGeClose */
-
-
-/*****************************************************************************
- *
- *     SkGeXmit - Linux frame transmit function
- *
- * Description:
- *     The system calls this function to send frames onto the wire.
- *     It puts the frame in the tx descriptor ring. If the ring is
- *     full then, the 'tbusy' flag is set.
- *
- * Returns:
- *     0, if everything is ok
- *     !=0, on error
- * WARNING: returning 1 in 'tbusy' case caused system crashes (double
- *     allocated skb's) !!!
- */
-#if 0
-static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev)
-#else
-int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev)
-#endif
-{
-DEV_NET                *pNet;
-SK_AC          *pAC;
-int                    Rc;     /* return code of XmitFrame */
-
-       pNet = (DEV_NET*) dev->priv;
-       pAC = pNet->pAC;
-
-#if 0
-       if ((!skb_shinfo(skb)->nr_frags) ||
-#else
-       if (1 ||
-#endif
-               (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) {
-               /* Don't activate scatter-gather and hardware checksum */
-
-               if (pAC->RlmtNets == 2)
-                       Rc = XmitFrame(
-                               pAC,
-                               &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
-                               skb);
-               else
-                       Rc = XmitFrame(
-                               pAC,
-                               &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
-                               skb);
-       } else {
-#if 0
-               /* scatter-gather and hardware TCP checksumming anabled*/
-               if (pAC->RlmtNets == 2)
-                       Rc = XmitFrameSG(
-                               pAC,
-                               &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
-                               skb);
-               else
-                       Rc = XmitFrameSG(
-                               pAC,
-                               &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
-                               skb);
-#endif
-       }
-
-       /* Transmitter out of resources? */
-       if (Rc <= 0) {
-               netif_stop_queue(dev);
-       }
-
-       /* If not taken, give buffer ownership back to the
-        * queueing layer.
-        */
-       if (Rc < 0)
-               return (1);
-
-#if 0
-       dev->trans_start = jiffies;
-#endif
-       return (0);
-} /* SkGeXmit */
-
-
-/*****************************************************************************
- *
- *     XmitFrame - fill one socket buffer into the transmit ring
- *
- * Description:
- *     This function puts a message into the transmit descriptor ring
- *     if there is a descriptors left.
- *     Linux skb's consist of only one continuous buffer.
- *     The first step locks the ring. It is held locked
- *     all time to avoid problems with SWITCH_../PORT_RESET.
- *     Then the descriptoris allocated.
- *     The second part is linking the buffer to the descriptor.
- *     At the very last, the Control field of the descriptor
- *     is made valid for the BMU and a start TX command is given
- *     if necessary.
- *
- * Returns:
- *     > 0 - on succes: the number of bytes in the message
- *     = 0 - on resource shortage: this frame sent or dropped, now
- *             the ring is full ( -> set tbusy)
- *     < 0 - on failure: other problems ( -> return failure to upper layers)
- */
-static int XmitFrame(
-SK_AC          *pAC,           /* pointer to adapter context */
-TX_PORT                *pTxPort,       /* pointer to struct of port to send to */
-struct sk_buff *pMessage)      /* pointer to send-message */
-{
-TXD            *pTxd;          /* the rxd to fill */
-unsigned long  Flags;
-SK_U64         PhysAddr;
-int            BytesSend;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
-               ("X"));
-
-       spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
-#ifndef USE_TX_COMPLETE
-       FreeTxDescriptors(pAC, pTxPort);
-#endif
-       if (pTxPort->TxdRingFree == 0) {
-               /* no enough free descriptors in ring at the moment */
-               FreeTxDescriptors(pAC, pTxPort);
-               if (pTxPort->TxdRingFree == 0) {
-                       spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
-                       SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_TX_PROGRESS,
-                               ("XmitFrame failed\n"));
-                       /* this message can not be sent now */
-                       /* Because tbusy seems to be set, the message should not be freed here */
-                       /* It will be used by the scheduler of the ethernet handler */
-                       return (-1);
-               }
-       }
-       /* advance head counter behind descriptor needed for this frame */
-       pTxd = pTxPort->pTxdRingHead;
-       pTxPort->pTxdRingHead = pTxd->pNextTxd;
-       pTxPort->TxdRingFree--;
-       /* the needed descriptor is reserved now */
-
-       /*
-        * everything allocated ok, so add buffer to descriptor
-        */
-
-#ifdef SK_DUMP_TX
-       DumpMsg(pMessage, "XmitFrame");
-#endif
-
-       /* set up descriptor and CONTROL dword */
-#if 0
-       PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
-               virt_to_page(pMessage->data),
-               ((unsigned long) pMessage->data &
-               ~PAGE_MASK),
-               pMessage->len,
-               PCI_DMA_TODEVICE);
-#else
-       PhysAddr = (SK_U64) pci_phys_to_mem(pAC->PciDev, (u32) pMessage->data);
-#endif
-       pTxd->VDataLow = (SK_U32)  (PhysAddr & 0xffffffff);
-       pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
-       pTxd->pMBuf = pMessage;
-       pTxd->TBControl = TX_CTRL_OWN_BMU | TX_CTRL_STF |
-               TX_CTRL_CHECK_DEFAULT | TX_CTRL_SOFTWARE |
-#ifdef USE_TX_COMPLETE
-               TX_CTRL_EOF | TX_CTRL_EOF_IRQ | pMessage->len;
-#else
-               TX_CTRL_EOF | pMessage->len;
-#endif
-
-       if ((pTxPort->pTxdRingPrev->TBControl & TX_CTRL_OWN_BMU) == 0) {
-               /* previous descriptor already done, so give tx start cmd */
-               /* StartTx(pAC, pTxPort->HwAddr); */
-               SK_OUT8(pTxPort->HwAddr, TX_Q_CTRL, TX_Q_CTRL_START);
-       }
-       pTxPort->pTxdRingPrev = pTxd;
-
-
-       BytesSend = pMessage->len;
-       spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
-       /* after releasing the lock, the skb may be immidiately freed */
-       if (pTxPort->TxdRingFree != 0)
-               return (BytesSend);
-       else
-               return (0);
-
-} /* XmitFrame */
-
-/*****************************************************************************
- *
- *     XmitFrameSG - fill one socket buffer into the transmit ring
- *                (use SG and TCP/UDP hardware checksumming)
- *
- * Description:
- *     This function puts a message into the transmit descriptor ring
- *     if there is a descriptors left.
- *
- * Returns:
- *     > 0 - on succes: the number of bytes in the message
- *     = 0 - on resource shortage: this frame sent or dropped, now
- *             the ring is full ( -> set tbusy)
- *     < 0 - on failure: other problems ( -> return failure to upper layers)
- */
-#if 0
-static int XmitFrameSG(
-SK_AC          *pAC,                   /* pointer to adapter context */
-TX_PORT                *pTxPort,               /* pointer to struct of port to send to */
-struct sk_buff *pMessage)      /* pointer to send-message */
-{
-
-       int             i;
-       int                     BytesSend;
-       int                     hlength;
-       int                     protocol;
-       skb_frag_t              *sk_frag;
-       TXD                     *pTxd;
-       TXD                     *pTxdFst;
-       TXD                     *pTxdLst;
-       SK_U64          PhysAddr;
-       unsigned long   Flags;
-
-       spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
-#ifndef USE_TX_COMPLETE
-       FreeTxDescriptors(pAC, pTxPort);
-#endif
-       if ((skb_shinfo(pMessage)->nr_frags +1) > pTxPort->TxdRingFree) {
-               FreeTxDescriptors(pAC, pTxPort);
-               if ((skb_shinfo(pMessage)->nr_frags + 1) > pTxPort->TxdRingFree) {
-                       spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
-                       SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_TX_PROGRESS,
-                               ("XmitFrameSG failed - Ring full\n"));
-                               /* this message can not be sent now */
-                       return(-1);
-               }
-       }
-
-
-       pTxd = pTxPort->pTxdRingHead;
-       pTxdFst = pTxd;
-       pTxdLst = pTxd;
-       BytesSend = 0;
-       protocol = 0;
-
-       /* map first fragment (header) */
-       PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
-                       virt_to_page(pMessage->data),
-                       ((unsigned long) pMessage->data & ~PAGE_MASK),
-                       skb_headlen(pMessage),
-                       PCI_DMA_TODEVICE);
-
-       pTxd->VDataLow = (SK_U32)  (PhysAddr & 0xffffffff);
-       pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
-
-       /* HW checksum? */
-       if (pMessage->ip_summed == CHECKSUM_HW) {
-               pTxd->TBControl = TX_CTRL_STF |
-                                 TX_CTRL_ST_FWD |
-                                 skb_headlen(pMessage);
-
-               /* We have to use the opcode for tcp here because the opcode for
-               udp is not working in the hardware yet (revision 2.0)*/
-               protocol = ((SK_U8)pMessage->data[23] & 0xf);
-               if ((protocol == 17) && (pAC->GIni.GIChipRev != 0))
-                       pTxd->TBControl |=  BMU_UDP_CHECK;
-               else
-                       pTxd->TBControl |= BMU_TCP_CHECK ;
-
-               hlength = ((SK_U8)pMessage->data[14] & 0xf) * 4;
-               pTxd->TcpSumOfs = 0; /* PH-Checksum already claculated */
-               pTxd->TcpSumSt = 14+hlength+16;
-               pTxd->TcpSumWr = 14+hlength;
-
-       } else {
-               pTxd->TBControl = TX_CTRL_CHECK_DEFAULT |
-                                 TX_CTRL_SOFTWARE |
-                                 TX_CTRL_STF |
-                                 skb_headlen(pMessage);
-       }
-
-       pTxd = pTxd->pNextTxd;
-       pTxPort->TxdRingFree--;
-       BytesSend += skb_headlen(pMessage);
-
-
-       /* Map SG fragments */
-       for (i = 0; i < skb_shinfo(pMessage)->nr_frags; i++) {
-               sk_frag = &skb_shinfo(pMessage)->frags[i];
-
-               /* we already have the proper value in entry */
-               PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
-                                                sk_frag->page,
-                                                sk_frag->page_offset,
-                                                sk_frag->size,
-                                                PCI_DMA_TODEVICE);
-
-               pTxd->VDataLow = (SK_U32)  (PhysAddr & 0xffffffff);
-               pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
-               pTxd->pMBuf = pMessage;
-
-               /* HW checksum */
-               if (pMessage->ip_summed == CHECKSUM_HW) {
-                       pTxd->TBControl = TX_CTRL_OWN_BMU |
-                                         TX_CTRL_SOFTWARE |
-                                         TX_CTRL_ST_FWD;
-
-                       /* We have to use the opcode for tcp here because the opcode for
-                       udp is not working in the hardware yet (revision 2.0)*/
-                       if ((protocol == 17) && (pAC->GIni.GIChipRev != 0))
-                               pTxd->TBControl |= BMU_UDP_CHECK ;
-                       else
-                               pTxd->TBControl |= BMU_TCP_CHECK ;
-
-               } else {
-                       pTxd->TBControl = TX_CTRL_CHECK_DEFAULT |
-                                         TX_CTRL_SOFTWARE |
-                                         TX_CTRL_OWN_BMU;
-               }
-
-               /* Last fragment  */
-               if( (i+1) == skb_shinfo(pMessage)->nr_frags )  {
-#ifdef USE_TX_COMPLETE
-                       pTxd->TBControl |= TX_CTRL_EOF |
-                                          TX_CTRL_EOF_IRQ |
-                                          sk_frag->size;
-#else
-                       pTxd->TBControl |= TX_CTRL_EOF |
-                                          sk_frag->size;
-#endif
-                       pTxdFst->TBControl |= TX_CTRL_OWN_BMU |
-                                             TX_CTRL_SOFTWARE;
-
-               } else {
-                       pTxd->TBControl |= sk_frag->size;
-               }
-               pTxdLst = pTxd;
-               pTxd = pTxd->pNextTxd;
-               pTxPort->TxdRingFree--;
-               BytesSend += sk_frag->size;
-       }
-
-       if ((pTxPort->pTxdRingPrev->TBControl & TX_CTRL_OWN_BMU) == 0) {
-               /* previous descriptor already done, so give tx start cmd */
-               /* StartTx(pAC, pTxPort->HwAddr); */
-               SK_OUT8(pTxPort->HwAddr, TX_Q_CTRL, TX_Q_CTRL_START);
-       }
-
-       pTxPort->pTxdRingPrev = pTxdLst;
-       pTxPort->pTxdRingHead = pTxd;
-
-       spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
-
-       if (pTxPort->TxdRingFree > 0)
-               return (BytesSend);
-       else
-               return (0);
-}
-#endif
-
-
-void dump_frag( SK_U8 *data, int length)
-{
-       int i;
-
-       printk("Length: %d\n", length);
-       for( i=0; i < length; i++ ) {
-               printk(" %02x", (SK_U8)*(data + i) );
-               if( !((i+1) % 20) )
-                 printk("\n");
-       }
-       printk("\n\n");
-
-}
-
-
-/*****************************************************************************
- *
- *     FreeTxDescriptors - release descriptors from the descriptor ring
- *
- * Description:
- *     This function releases descriptors from a transmit ring if they
- *     have been sent by the BMU.
- *     If a descriptors is sent, it can be freed and the message can
- *     be freed, too.
- *     The SOFTWARE controllable bit is used to prevent running around a
- *     completely free ring for ever. If this bit is no set in the
- *     frame (by XmitFrame), this frame has never been sent or is
- *     already freed.
- *     The Tx descriptor ring lock must be held while calling this function !!!
- *
- * Returns:
- *     none
- */
-static void FreeTxDescriptors(
-SK_AC  *pAC,           /* pointer to the adapter context */
-TX_PORT        *pTxPort)       /* pointer to destination port structure */
-{
-TXD    *pTxd;          /* pointer to the checked descriptor */
-TXD    *pNewTail;      /* pointer to 'end' of the ring */
-SK_U32 Control;        /* TBControl field of descriptor */
-SK_U64 PhysAddr;       /* address of DMA mapping */
-
-       pNewTail = pTxPort->pTxdRingTail;
-       pTxd = pNewTail;
-       /*
-        * loop forever; exits if TX_CTRL_SOFTWARE bit not set in start frame
-        * or TX_CTRL_OWN_BMU bit set in any frame
-        */
-       while (1) {
-               Control = pTxd->TBControl;
-               if ((Control & TX_CTRL_SOFTWARE) == 0) {
-                       /*
-                        * software controllable bit is set in first
-                        * fragment when given to BMU. Not set means that
-                        * this fragment was never sent or is already
-                        * freed ( -> ring completely free now).
-                        */
-                       pTxPort->pTxdRingTail = pTxd;
-                       netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
-                       return;
-               }
-               if (Control & TX_CTRL_OWN_BMU) {
-                       pTxPort->pTxdRingTail = pTxd;
-                       if (pTxPort->TxdRingFree > 0) {
-                               netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
-                       }
-                       return;
-               }
-
-               /* release the DMA mapping */
-               PhysAddr = ((SK_U64) pTxd->VDataHigh) << (SK_U64) 32;
-               PhysAddr |= (SK_U64) pTxd->VDataLow;
-               pci_unmap_page(pAC->PciDev, PhysAddr,
-                                pTxd->pMBuf->len,
-                                PCI_DMA_TODEVICE);
-
-               if (Control & TX_CTRL_EOF)
-                       DEV_KFREE_SKB_ANY(pTxd->pMBuf); /* free message */
-
-               pTxPort->TxdRingFree++;
-               pTxd->TBControl &= ~TX_CTRL_SOFTWARE;
-               pTxd = pTxd->pNextTxd; /* point behind fragment with EOF */
-       } /* while(forever) */
-} /* FreeTxDescriptors */
-
-/*****************************************************************************
- *
- *     FillRxRing - fill the receive ring with valid descriptors
- *
- * Description:
- *     This function fills the receive ring descriptors with data
- *     segments and makes them valid for the BMU.
- *     The active ring is filled completely, if possible.
- *     The non-active ring is filled only partial to save memory.
- *
- * Description of rx ring structure:
- *     head - points to the descriptor which will be used next by the BMU
- *     tail - points to the next descriptor to give to the BMU
- *
- * Returns:    N/A
- */
-static void FillRxRing(
-SK_AC          *pAC,           /* pointer to the adapter context */
-RX_PORT                *pRxPort)       /* ptr to port struct for which the ring
-                                  should be filled */
-{
-unsigned long  Flags;
-
-       spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
-       while (pRxPort->RxdRingFree > pRxPort->RxFillLimit) {
-               if(!FillRxDescriptor(pAC, pRxPort))
-                       break;
-       }
-       spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
-} /* FillRxRing */
-
-
-/*****************************************************************************
- *
- *     FillRxDescriptor - fill one buffer into the receive ring
- *
- * Description:
- *     The function allocates a new receive buffer and
- *     puts it into the next descriptor.
- *
- * Returns:
- *     SK_TRUE - a buffer was added to the ring
- *     SK_FALSE - a buffer could not be added
- */
-static SK_BOOL FillRxDescriptor(
-SK_AC          *pAC,           /* pointer to the adapter context struct */
-RX_PORT                *pRxPort)       /* ptr to port struct of ring to fill */
-{
-struct sk_buff *pMsgBlock;     /* pointer to a new message block */
-RXD            *pRxd;          /* the rxd to fill */
-SK_U16         Length;         /* data fragment length */
-SK_U64         PhysAddr;       /* physical address of a rx buffer */
-
-       pMsgBlock = alloc_skb(pAC->RxBufSize, GFP_ATOMIC);
-       if (pMsgBlock == NULL) {
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                       SK_DBGCAT_DRV_ENTRY,
-                       ("%s: Allocation of rx buffer failed !\n",
-                       pAC->dev[pRxPort->PortIndex]->name));
-               SK_PNMI_CNT_NO_RX_BUF(pAC, pRxPort->PortIndex);
-               return(SK_FALSE);
-       }
-       skb_reserve(pMsgBlock, 2); /* to align IP frames */
-       /* skb allocated ok, so add buffer */
-       pRxd = pRxPort->pRxdRingTail;
-       pRxPort->pRxdRingTail = pRxd->pNextRxd;
-       pRxPort->RxdRingFree--;
-       Length = pAC->RxBufSize;
-#if 0
-       PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
-               virt_to_page(pMsgBlock->data),
-               ((unsigned long) pMsgBlock->data &
-               ~PAGE_MASK),
-               pAC->RxBufSize - 2,
-               PCI_DMA_FROMDEVICE);
-#else
-       PhysAddr = (SK_U64) pci_phys_to_mem(pAC->PciDev, (u32)pMsgBlock->data);
-#endif
-       pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
-       pRxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
-       pRxd->pMBuf = pMsgBlock;
-       pRxd->RBControl = RX_CTRL_OWN_BMU | RX_CTRL_STF |
-               RX_CTRL_EOF_IRQ | RX_CTRL_CHECK_CSUM | Length;
-       return (SK_TRUE);
-
-} /* FillRxDescriptor */
-
-
-/*****************************************************************************
- *
- *     ReQueueRxBuffer - fill one buffer back into the receive ring
- *
- * Description:
- *     Fill a given buffer back into the rx ring. The buffer
- *     has been previously allocated and aligned, and its phys.
- *     address calculated, so this is no more necessary.
- *
- * Returns: N/A
- */
-static void ReQueueRxBuffer(
-SK_AC          *pAC,           /* pointer to the adapter context struct */
-RX_PORT                *pRxPort,       /* ptr to port struct of ring to fill */
-struct sk_buff *pMsg,          /* pointer to the buffer */
-SK_U32         PhysHigh,       /* phys address high dword */
-SK_U32         PhysLow)        /* phys address low dword */
-{
-RXD            *pRxd;          /* the rxd to fill */
-SK_U16         Length;         /* data fragment length */
-
-       pRxd = pRxPort->pRxdRingTail;
-       pRxPort->pRxdRingTail = pRxd->pNextRxd;
-       pRxPort->RxdRingFree--;
-       Length = pAC->RxBufSize;
-       pRxd->VDataLow = PhysLow;
-       pRxd->VDataHigh = PhysHigh;
-       pRxd->pMBuf = pMsg;
-       pRxd->RBControl = RX_CTRL_OWN_BMU | RX_CTRL_STF |
-               RX_CTRL_EOF_IRQ | RX_CTRL_CHECK_CSUM | Length;
-       return;
-} /* ReQueueRxBuffer */
-
-
-/*****************************************************************************
- *
- *     ReceiveIrq - handle a receive IRQ
- *
- * Description:
- *     This function is called when a receive IRQ is set.
- *     It walks the receive descriptor ring and sends up all
- *     frames that are complete.
- *
- * Returns:    N/A
- */
-#if 0
-static void ReceiveIrq(
-#else
-void ReceiveIrq(
-#endif
-       SK_AC           *pAC,                   /* pointer to adapter context */
-       RX_PORT         *pRxPort,               /* pointer to receive port struct */
-       SK_BOOL         SlowPathLock)   /* indicates if SlowPathLock is needed */
-{
-RXD                            *pRxd;                  /* pointer to receive descriptors */
-SK_U32                 Control;                /* control field of descriptor */
-struct sk_buff *pMsg;                  /* pointer to message holding frame */
-struct sk_buff *pNewMsg;               /* pointer to a new message for copying frame */
-int                            FrameLength;    /* total length of received frame */
-SK_MBUF                        *pRlmtMbuf;             /* ptr to a buffer for giving a frame to rlmt */
-SK_EVPARA              EvPara;                 /* an event parameter union */
-unsigned long  Flags;                  /* for spin lock */
-int                            PortIndex = pRxPort->PortIndex;
-unsigned int   Offset;
-unsigned int   NumBytes;
-unsigned int   ForRlmt;
-SK_BOOL                        IsBc;
-SK_BOOL                        IsMc;
-SK_BOOL  IsBadFrame;                   /* Bad frame */
-
-SK_U32                 FrameStat;
-unsigned short Csum1;
-unsigned short Csum2;
-unsigned short Type;
-#if 0
-int                            Result;
-#endif
-SK_U64                 PhysAddr;
-
-rx_start:
-       /* do forever; exit if RX_CTRL_OWN_BMU found */
-       for ( pRxd = pRxPort->pRxdRingHead ;
-                 pRxPort->RxdRingFree < pAC->RxDescrPerRing ;
-                 pRxd = pRxd->pNextRxd,
-                 pRxPort->pRxdRingHead = pRxd,
-                 pRxPort->RxdRingFree ++) {
-
-               /*
-                * For a better understanding of this loop
-                * Go through every descriptor beginning at the head
-                * Please note: the ring might be completely received so the OWN bit
-                * set is not a good crirteria to leave that loop.
-                * Therefore the RingFree counter is used.
-                * On entry of this loop pRxd is a pointer to the Rxd that needs
-                * to be checked next.
-                */
-
-               Control = pRxd->RBControl;
-
-               /* check if this descriptor is ready */
-               if ((Control & RX_CTRL_OWN_BMU) != 0) {
-                       /* this descriptor is not yet ready */
-                       /* This is the usual end of the loop */
-                       /* We don't need to start the ring again */
-                       FillRxRing(pAC, pRxPort);
-                       return;
-               }
-
-               /* get length of frame and check it */
-               FrameLength = Control & RX_CTRL_LEN_MASK;
-               if (FrameLength > pAC->RxBufSize) {
-                       goto rx_failed;
-               }
-
-               /* check for STF and EOF */
-               if ((Control & (RX_CTRL_STF | RX_CTRL_EOF)) !=
-                       (RX_CTRL_STF | RX_CTRL_EOF)) {
-                       goto rx_failed;
-               }
-
-               /* here we have a complete frame in the ring */
-               pMsg = pRxd->pMBuf;
-
-               FrameStat = pRxd->FrameStat;
-
-               /* check for frame length mismatch */
-#define XMR_FS_LEN_SHIFT        18
-#define GMR_FS_LEN_SHIFT        16
-               if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-                       if (FrameLength != (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)) {
-                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                                       SK_DBGCAT_DRV_RX_PROGRESS,
-                                       ("skge: Frame length mismatch (%u/%u).\n",
-                                       FrameLength,
-                                       (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
-                               goto rx_failed;
-                       }
-               }
-               else {
-                       if (FrameLength != (SK_U32) (FrameStat >> GMR_FS_LEN_SHIFT)) {
-                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                                       SK_DBGCAT_DRV_RX_PROGRESS,
-                                       ("skge: Frame length mismatch (%u/%u).\n",
-                                       FrameLength,
-                                       (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
-                               goto rx_failed;
-                       }
-               }
-
-               /* Set Rx Status */
-               if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-                       IsBc = (FrameStat & XMR_FS_BC) != 0;
-                       IsMc = (FrameStat & XMR_FS_MC) != 0;
-                       IsBadFrame = (FrameStat &
-                               (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0;
-               } else {
-                       IsBc = (FrameStat & GMR_FS_BC) != 0;
-                       IsMc = (FrameStat & GMR_FS_MC) != 0;
-                       IsBadFrame = (((FrameStat & GMR_FS_ANY_ERR) != 0) ||
-                                                       ((FrameStat & GMR_FS_RX_OK) == 0));
-               }
-
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
-                       ("Received frame of length %d on port %d\n",
-                       FrameLength, PortIndex));
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
-                       ("Number of free rx descriptors: %d\n",
-                       pRxPort->RxdRingFree));
-/* DumpMsg(pMsg, "Rx");        */
-
-               if ((Control & RX_CTRL_STAT_VALID) != RX_CTRL_STAT_VALID ||
-                       (IsBadFrame)) {
-#if 0
-                       (FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) {
-#endif
-                       /* there is a receive error in this frame */
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_RX_PROGRESS,
-                               ("skge: Error in received frame, dropped!\n"
-                               "Control: %x\nRxStat: %x\n",
-                               Control, FrameStat));
-
-                       PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
-                       PhysAddr |= (SK_U64) pRxd->VDataLow;
-                       pci_dma_sync_single(pAC->PciDev,
-                                               (dma_addr_t) PhysAddr,
-                                               FrameLength,
-                                               PCI_DMA_FROMDEVICE);
-                       ReQueueRxBuffer(pAC, pRxPort, pMsg,
-                               pRxd->VDataHigh, pRxd->VDataLow);
-
-                       continue;
-               }
-
-               /*
-                * if short frame then copy data to reduce memory waste
-                */
-               if ((FrameLength < SK_COPY_THRESHOLD) &&
-                       ((pNewMsg = alloc_skb(FrameLength+2, GFP_ATOMIC)) != NULL)) {
-                       /*
-                        * Short frame detected and allocation successfull
-                        */
-                       /* use new skb and copy data */
-                       skb_reserve(pNewMsg, 2);
-                       skb_put(pNewMsg, FrameLength);
-                       PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
-                       PhysAddr |= (SK_U64) pRxd->VDataLow;
-
-                       pci_dma_sync_single(pAC->PciDev,
-                                               (dma_addr_t) PhysAddr,
-                                               FrameLength,
-                                               PCI_DMA_FROMDEVICE);
-                       eth_copy_and_sum(pNewMsg, pMsg->data,
-                               FrameLength, 0);
-                       ReQueueRxBuffer(pAC, pRxPort, pMsg,
-                               pRxd->VDataHigh, pRxd->VDataLow);
-                       pMsg = pNewMsg;
-
-               }
-               else {
-                       /*
-                        * if large frame, or SKB allocation failed, pass
-                        * the SKB directly to the networking
-                        */
-
-                       PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
-                       PhysAddr |= (SK_U64) pRxd->VDataLow;
-
-                       /* release the DMA mapping */
-                       pci_unmap_single(pAC->PciDev,
-                                        PhysAddr,
-                                        pAC->RxBufSize - 2,
-                                        PCI_DMA_FROMDEVICE);
-
-                       /* set length in message */
-                       skb_put(pMsg, FrameLength);
-                       /* hardware checksum */
-                       Type = ntohs(*((short*)&pMsg->data[12]));
-                       if (Type == 0x800) {
-                               Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff);
-                               Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff);
-#if 0
-                               if ((((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) &&
-                                       (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) ||
-                                       (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
-                                       Result = SkCsGetReceiveInfo(pAC,
-                                               &pMsg->data[14],
-                                               Csum1, Csum2, pRxPort->PortIndex);
-                                       if (Result ==
-                                               SKCS_STATUS_IP_FRAGMENT ||
-                                               Result ==
-                                               SKCS_STATUS_IP_CSUM_OK ||
-                                               Result ==
-                                               SKCS_STATUS_TCP_CSUM_OK ||
-                                               Result ==
-                                               SKCS_STATUS_UDP_CSUM_OK) {
-                                                       pMsg->ip_summed =
-                                                       CHECKSUM_UNNECESSARY;
-                                       } else {
-                                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                                               SK_DBGCAT_DRV_RX_PROGRESS,
-                                               ("skge: CRC error. Frame dropped!\n"));
-                                               goto rx_failed;
-                                       }
-                               }/* checksumControl calculation valid */
-#endif
-                       } /* IP frame */
-               } /* frame > SK_COPY_TRESHOLD */
-
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V"));
-               ForRlmt = SK_RLMT_RX_PROTOCOL;
-#if 0
-               IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC;
-#endif
-               SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength,
-                       IsBc, &Offset, &NumBytes);
-               if (NumBytes != 0) {
-#if 0
-                       IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC;
-#endif
-                       SK_RLMT_LOOKAHEAD(pAC, PortIndex,
-                               &pMsg->data[Offset],
-                               IsBc, IsMc, &ForRlmt);
-               }
-               if (ForRlmt == SK_RLMT_RX_PROTOCOL) {
-                                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("W"));
-                       /* send up only frames from active port */
-                       if ((PortIndex == pAC->ActivePort) ||
-                               (pAC->RlmtNets == 2)) {
-                               /* frame for upper layer */
-                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("U"));
-#ifdef xDEBUG
-                               DumpMsg(pMsg, "Rx");
-#endif
-                               SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
-                                       FrameLength, pRxPort->PortIndex);
-
-#if 0
-                               pMsg->dev = pAC->dev[pRxPort->PortIndex];
-                               pMsg->protocol = eth_type_trans(pMsg,
-                                       pAC->dev[pRxPort->PortIndex]);
-                               netif_rx(pMsg);
-                               pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
-#else
-                               NetReceive(pMsg->data, pMsg->len);
-                               dev_kfree_skb_any(pMsg);
-#endif
-                       }
-                       else {
-                               /* drop frame */
-                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                                       SK_DBGCAT_DRV_RX_PROGRESS,
-                                       ("D"));
-                               DEV_KFREE_SKB(pMsg);
-                       }
-
-               } /* if not for rlmt */
-               else {
-                       /* packet for rlmt */
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_RX_PROGRESS, ("R"));
-                       pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
-                               pAC->IoBase, FrameLength);
-                       if (pRlmtMbuf != NULL) {
-                               pRlmtMbuf->pNext = NULL;
-                               pRlmtMbuf->Length = FrameLength;
-                               pRlmtMbuf->PortIdx = PortIndex;
-                               EvPara.pParaPtr = pRlmtMbuf;
-                               memcpy((char*)(pRlmtMbuf->pData),
-                                          (char*)(pMsg->data),
-                                          FrameLength);
-
-                               /* SlowPathLock needed? */
-                               if (SlowPathLock == SK_TRUE) {
-                                       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-                                       SkEventQueue(pAC, SKGE_RLMT,
-                                               SK_RLMT_PACKET_RECEIVED,
-                                               EvPara);
-                                       pAC->CheckQueue = SK_TRUE;
-                                       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-                               } else {
-                                       SkEventQueue(pAC, SKGE_RLMT,
-                                               SK_RLMT_PACKET_RECEIVED,
-                                               EvPara);
-                                       pAC->CheckQueue = SK_TRUE;
-                               }
-
-                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                                       SK_DBGCAT_DRV_RX_PROGRESS,
-                                       ("Q"));
-                       }
-#if 0
-                       if ((pAC->dev[pRxPort->PortIndex]->flags &
-                               (IFF_PROMISC | IFF_ALLMULTI)) != 0 ||
-                               (ForRlmt & SK_RLMT_RX_PROTOCOL) ==
-                               SK_RLMT_RX_PROTOCOL) {
-                               pMsg->dev = pAC->dev[pRxPort->PortIndex];
-                               pMsg->protocol = eth_type_trans(pMsg,
-                                       pAC->dev[pRxPort->PortIndex]);
-                               netif_rx(pMsg);
-                               pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
-                       }
-#else
-                       if (0) {
-                       }
-#endif
-                       else {
-                               DEV_KFREE_SKB(pMsg);
-                       }
-
-               } /* if packet for rlmt */
-       } /* for ... scanning the RXD ring */
-
-       /* RXD ring is empty -> fill and restart */
-       FillRxRing(pAC, pRxPort);
-       /* do not start if called from Close */
-       if (pAC->BoardLevel > 0) {
-               ClearAndStartRx(pAC, PortIndex);
-       }
-       return;
-
-rx_failed:
-       /* remove error frame */
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
-               ("Schrottdescriptor, length: 0x%x\n", FrameLength));
-
-       /* release the DMA mapping */
-
-       PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
-       PhysAddr |= (SK_U64) pRxd->VDataLow;
-       pci_unmap_page(pAC->PciDev,
-                        PhysAddr,
-                        pAC->RxBufSize - 2,
-                        PCI_DMA_FROMDEVICE);
-       DEV_KFREE_SKB_IRQ(pRxd->pMBuf);
-       pRxd->pMBuf = NULL;
-       pRxPort->RxdRingFree++;
-       pRxPort->pRxdRingHead = pRxd->pNextRxd;
-       goto rx_start;
-
-} /* ReceiveIrq */
-
-
-/*****************************************************************************
- *
- *     ClearAndStartRx - give a start receive command to BMU, clear IRQ
- *
- * Description:
- *     This function sends a start command and a clear interrupt
- *     command for one receive queue to the BMU.
- *
- * Returns: N/A
- *     none
- */
-static void ClearAndStartRx(
-SK_AC  *pAC,           /* pointer to the adapter context */
-int    PortIndex)      /* index of the receive port (XMAC) */
-{
-       SK_OUT8(pAC->IoBase, RxQueueAddr[PortIndex]+RX_Q_CTRL,
-               RX_Q_CTRL_START | RX_Q_CTRL_CLR_I_EOF);
-} /* ClearAndStartRx */
-
-
-/*****************************************************************************
- *
- *     ClearTxIrq - give a clear transmit IRQ command to BMU
- *
- * Description:
- *     This function sends a clear tx IRQ command for one
- *     transmit queue to the BMU.
- *
- * Returns: N/A
- */
-static void ClearTxIrq(
-SK_AC  *pAC,           /* pointer to the adapter context */
-int    PortIndex,      /* index of the transmit port (XMAC) */
-int    Prio)           /* priority or normal queue */
-{
-       SK_OUT8(pAC->IoBase, TxQueueAddr[PortIndex][Prio]+TX_Q_CTRL,
-               TX_Q_CTRL_CLR_I_EOF);
-} /* ClearTxIrq */
-
-
-/*****************************************************************************
- *
- *     ClearRxRing - remove all buffers from the receive ring
- *
- * Description:
- *     This function removes all receive buffers from the ring.
- *     The receive BMU must be stopped before calling this function.
- *
- * Returns: N/A
- */
-static void ClearRxRing(
-SK_AC  *pAC,           /* pointer to adapter context */
-RX_PORT        *pRxPort)       /* pointer to rx port struct */
-{
-RXD            *pRxd;  /* pointer to the current descriptor */
-unsigned long  Flags;
-SK_U64         PhysAddr;
-
-       if (pRxPort->RxdRingFree == pAC->RxDescrPerRing) {
-               return;
-       }
-       spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
-       pRxd = pRxPort->pRxdRingHead;
-       do {
-               if (pRxd->pMBuf != NULL) {
-
-                       PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
-                       PhysAddr |= (SK_U64) pRxd->VDataLow;
-                       pci_unmap_page(pAC->PciDev,
-                                        PhysAddr,
-                                        pAC->RxBufSize - 2,
-                                        PCI_DMA_FROMDEVICE);
-                       DEV_KFREE_SKB(pRxd->pMBuf);
-                       pRxd->pMBuf = NULL;
-               }
-               pRxd->RBControl &= RX_CTRL_OWN_BMU;
-               pRxd = pRxd->pNextRxd;
-               pRxPort->RxdRingFree++;
-       } while (pRxd != pRxPort->pRxdRingTail);
-       pRxPort->pRxdRingTail = pRxPort->pRxdRingHead;
-       spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
-} /* ClearRxRing */
-
-
-/*****************************************************************************
- *
- *     ClearTxRing - remove all buffers from the transmit ring
- *
- * Description:
- *     This function removes all transmit buffers from the ring.
- *     The transmit BMU must be stopped before calling this function
- *     and transmitting at the upper level must be disabled.
- *     The BMU own bit of all descriptors is cleared, the rest is
- *     done by calling FreeTxDescriptors.
- *
- * Returns: N/A
- */
-static void ClearTxRing(
-SK_AC  *pAC,           /* pointer to adapter context */
-TX_PORT        *pTxPort)       /* pointer to tx prt struct */
-{
-TXD            *pTxd;          /* pointer to the current descriptor */
-int            i;
-unsigned long  Flags;
-
-       spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
-       pTxd = pTxPort->pTxdRingHead;
-       for (i=0; i<pAC->TxDescrPerRing; i++) {
-               pTxd->TBControl &= ~TX_CTRL_OWN_BMU;
-               pTxd = pTxd->pNextTxd;
-       }
-       FreeTxDescriptors(pAC, pTxPort);
-       spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
-} /* ClearTxRing */
-
-
-#if 0
-/*****************************************************************************
- *
- *     SetQueueSizes - configure the sizes of rx and tx queues
- *
- * Description:
- *     This function assigns the sizes for active and passive port
- *     to the appropriate HWinit structure variables.
- *     The passive port(s) get standard values, all remaining RAM
- *     is given to the active port.
- *     The queue sizes are in kbyte and must be multiple of 8.
- *     The limits for the number of buffers filled into the rx rings
- *     is also set in this routine.
- *
- * Returns:
- *     none
- */
-static void SetQueueSizes(
-SK_AC  *pAC)   /* pointer to the adapter context */
-{
-int    StandbyRam;     /* adapter RAM used for a standby port */
-int    RemainingRam;   /* adapter RAM available for the active port */
-int    RxRam;          /* RAM used for the active port receive queue */
-int    i;              /* loop counter */
-
-if (pAC->RlmtNets == 1) {
-       StandbyRam = SK_RLMT_STANDBY_QRXSIZE + SK_RLMT_STANDBY_QXASIZE +
-               SK_RLMT_STANDBY_QXSSIZE;
-       RemainingRam = pAC->GIni.GIRamSize -
-               (pAC->GIni.GIMacsFound-1) * StandbyRam;
-       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-               pAC->GIni.GP[i].PRxQSize = SK_RLMT_STANDBY_QRXSIZE;
-               pAC->GIni.GP[i].PXSQSize = SK_RLMT_STANDBY_QXSSIZE;
-               pAC->GIni.GP[i].PXAQSize = SK_RLMT_STANDBY_QXASIZE;
-       }
-       RxRam = (RemainingRam * 8 / 10) & ~7;
-       pAC->GIni.GP[pAC->ActivePort].PRxQSize = RxRam;
-       pAC->GIni.GP[pAC->ActivePort].PXSQSize = 0;
-       pAC->GIni.GP[pAC->ActivePort].PXAQSize =
-               (RemainingRam - RxRam) & ~7;
-       pAC->RxQueueSize = RxRam;
-       pAC->TxSQueueSize = 0;
-       pAC->TxAQueueSize = (RemainingRam - RxRam) & ~7;
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("queue sizes settings - rx:%d  txA:%d txS:%d\n",
-               pAC->RxQueueSize,pAC->TxAQueueSize, pAC->TxSQueueSize));
-} else {
-       RemainingRam = pAC->GIni.GIRamSize/pAC->GIni.GIMacsFound;
-       RxRam = (RemainingRam * 8 / 10) & ~7;
-       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-               pAC->GIni.GP[i].PRxQSize = RxRam;
-               pAC->GIni.GP[i].PXSQSize = 0;
-               pAC->GIni.GP[i].PXAQSize = (RemainingRam - RxRam) & ~7;
-       }
-
-       pAC->RxQueueSize = RxRam;
-       pAC->TxSQueueSize = 0;
-       pAC->TxAQueueSize = (RemainingRam - RxRam) & ~7;
-}
-       for (i=0; i<SK_MAX_MACS; i++) {
-               pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing;
-       }
-
-       if (pAC->RlmtNets == 2) {
-               for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-                       pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 100;
-               }
-       } else {
-               for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-                       pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 100;
-               }
-               /*
-                * Do not set the Limit to 0, because this could cause
-                * wrap around with ReQueue'ed buffers (a buffer could
-                * be requeued in the same position, made accessable to
-                * the hardware, and the hardware could change its
-                * contents!
-                */
-               pAC->RxPort[pAC->ActivePort].RxFillLimit = 1;
-       }
-
-#ifdef DEBUG
-       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
-                       ("i: %d,  RxQSize: %d,  PXSQsize: %d, PXAQSize: %d\n",
-                       i,
-                       pAC->GIni.GP[i].PRxQSize,
-                       pAC->GIni.GP[i].PXSQSize,
-                       pAC->GIni.GP[i].PXAQSize));
-       }
-#endif
-} /* SetQueueSizes */
-
-
-/*****************************************************************************
- *
- *     SkGeSetMacAddr - Set the hardware MAC address
- *
- * Description:
- *     This function sets the MAC address used by the adapter.
- *
- * Returns:
- *     0, if everything is ok
- *     !=0, on error
- */
-static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p)
-{
-
-DEV_NET *pNet = (DEV_NET*) dev->priv;
-SK_AC  *pAC = pNet->pAC;
-
-struct sockaddr        *addr = p;
-unsigned long  Flags;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeSetMacAddr starts now...\n"));
-       if(netif_running(dev))
-               return -EBUSY;
-
-       memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
-
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-
-       if (pAC->RlmtNets == 2)
-               SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr,
-                       (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
-       else
-               SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort,
-                       (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
-
-
-       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-       return 0;
-} /* SkGeSetMacAddr */
-#endif
-
-
-/*****************************************************************************
- *
- *     SkGeSetRxMode - set receive mode
- *
- * Description:
- *     This function sets the receive mode of an adapter. The adapter
- *     supports promiscuous mode, allmulticast mode and a number of
- *     multicast addresses. If more multicast addresses the available
- *     are selected, a hash function in the hardware is used.
- *
- * Returns:
- *     0, if everything is ok
- *     !=0, on error
- */
-#if 0
-static void SkGeSetRxMode(struct SK_NET_DEVICE *dev)
-{
-
-DEV_NET                *pNet;
-SK_AC          *pAC;
-
-struct dev_mc_list     *pMcList;
-int                    i;
-int                    PortIdx;
-unsigned long          Flags;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeSetRxMode starts now... "));
-
-       pNet = (DEV_NET*) dev->priv;
-       pAC = pNet->pAC;
-       if (pAC->RlmtNets == 1)
-               PortIdx = pAC->ActivePort;
-       else
-               PortIdx = pNet->NetNr;
-
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-       if (dev->flags & IFF_PROMISC) {
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-                       ("PROMISCUOUS mode\n"));
-               SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
-                       SK_PROM_MODE_LLC);
-       } else if (dev->flags & IFF_ALLMULTI) {
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-                       ("ALLMULTI mode\n"));
-               SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
-                       SK_PROM_MODE_ALL_MC);
-       } else {
-               SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
-                       SK_PROM_MODE_NONE);
-               SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
-
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-                       ("Number of MC entries: %d ", dev->mc_count));
-
-               pMcList = dev->mc_list;
-               for (i=0; i<dev->mc_count; i++, pMcList = pMcList->next) {
-                       SkAddrMcAdd(pAC, pAC->IoBase, PortIdx,
-                               (SK_MAC_ADDR*)pMcList->dmi_addr, 0);
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MCA,
-                               ("%02x:%02x:%02x:%02x:%02x:%02x\n",
-                               pMcList->dmi_addr[0],
-                               pMcList->dmi_addr[1],
-                               pMcList->dmi_addr[2],
-                               pMcList->dmi_addr[3],
-                               pMcList->dmi_addr[4],
-                               pMcList->dmi_addr[5]));
-               }
-               SkAddrMcUpdate(pAC, pAC->IoBase, PortIdx);
-       }
-       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
-       return;
-} /* SkGeSetRxMode */
-
-
-/*****************************************************************************
- *
- *     SkGeChangeMtu - set the MTU to another value
- *
- * Description:
- *     This function sets is called whenever the MTU size is changed
- *     (ifconfig mtu xxx dev ethX). If the MTU is bigger than standard
- *     ethernet MTU size, long frame support is activated.
- *
- * Returns:
- *     0, if everything is ok
- *     !=0, on error
- */
-static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu)
-{
-DEV_NET                *pNet;
-DEV_NET                *pOtherNet;
-SK_AC          *pAC;
-unsigned long  Flags;
-int            i;
-SK_EVPARA      EvPara;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeChangeMtu starts now...\n"));
-
-       pNet = (DEV_NET*) dev->priv;
-       pAC = pNet->pAC;
-
-       if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) {
-               return -EINVAL;
-       }
-
-       if(pAC->BoardLevel != 2) {
-               return -EINVAL;
-       }
-
-       pNet->Mtu = NewMtu;
-       pOtherNet = (DEV_NET*)pAC->dev[1 - pNet->NetNr]->priv;
-       if ((pOtherNet->Mtu > 1500) && (NewMtu <= 1500) && (pOtherNet->Up==1)) {
-               return(0);
-       }
-
-       EvPara.Para32[0] = pNet->NetNr;
-       EvPara.Para32[1] = -1;
-
-       pAC->RxBufSize = NewMtu + 32;
-       dev->mtu = NewMtu;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("New MTU: %d\n", NewMtu));
-
-       /* prevent reconfiguration while changing the MTU */
-
-       /* disable interrupts */
-       SK_OUT32(pAC->IoBase, B0_IMSK, 0);
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-
-       /* Found more than one port */
-       if ((pAC->GIni.GIMacsFound == 2 ) &&
-               (pAC->RlmtNets == 2)) {
-                       /* Stop both ports */
-                       EvPara.Para32[0] = 0;
-                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
-                       EvPara.Para32[0] = 1;
-                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
-       } else {
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
-       }
-
-       SkEventDispatcher(pAC, pAC->IoBase);
-
-       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-               spin_lock_irqsave(
-                       &pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock, Flags);
-               netif_stop_queue(pAC->dev[i]);
-
-       }
-
-       /*
-        * adjust number of rx buffers allocated
-        */
-       if (NewMtu > 1500) {
-               /* use less rx buffers */
-               for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-                       /* Found more than one port */
-                       if ((pAC->GIni.GIMacsFound == 2 ) &&
-                               (pAC->RlmtNets == 2)) {
-                                       pAC->RxPort[i].RxFillLimit =
-                                               pAC->RxDescrPerRing - 100;
-                       } else {
-                               if (i == pAC->ActivePort)
-                                       pAC->RxPort[i].RxFillLimit =
-                                               pAC->RxDescrPerRing - 100;
-                               else
-                                       pAC->RxPort[i].RxFillLimit =
-                                               pAC->RxDescrPerRing - 10;
-                       }
-               }
-       }
-       else {
-               /* use normal amount of rx buffers */
-               for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-                       /* Found more than one port */
-                       if ((pAC->GIni.GIMacsFound == 2 ) &&
-                               (pAC->RlmtNets == 2)) {
-                                       pAC->RxPort[i].RxFillLimit = 1;
-                       } else {
-                               if (i == pAC->ActivePort)
-                                       pAC->RxPort[i].RxFillLimit = 1;
-                               else
-                                       pAC->RxPort[i].RxFillLimit =
-                                               pAC->RxDescrPerRing - 100;
-                       }
-               }
-       }
-
-       SkGeDeInit(pAC, pAC->IoBase);
-
-       /*
-        * enable/disable hardware support for long frames
-        */
-       if (NewMtu > 1500) {
-/*             pAC->JumboActivated = SK_TRUE; /#* is never set back !!! */
-               pAC->GIni.GIPortUsage = SK_JUMBO_LINK;
-       }
-       else {
-               if ((pAC->GIni.GIMacsFound == 2 ) &&
-                       (pAC->RlmtNets == 2)) {
-                       pAC->GIni.GIPortUsage = SK_MUL_LINK;
-               } else {
-                       pAC->GIni.GIPortUsage = SK_RED_LINK;
-               }
-       }
-
-       SkGeInit(   pAC, pAC->IoBase, 1);
-       SkI2cInit(  pAC, pAC->IoBase, 1);
-       SkEventInit(pAC, pAC->IoBase, 1);
-       SkPnmiInit( pAC, pAC->IoBase, 1);
-       SkAddrInit( pAC, pAC->IoBase, 1);
-       SkRlmtInit( pAC, pAC->IoBase, 1);
-       SkTimerInit(pAC, pAC->IoBase, 1);
-
-       /*
-        * tschilling:
-        * Speed and others are set back to default in level 1 init!
-        */
-       GetConfiguration(pAC);
-
-       SkGeInit(   pAC, pAC->IoBase, 2);
-       SkI2cInit(  pAC, pAC->IoBase, 2);
-       SkEventInit(pAC, pAC->IoBase, 2);
-       SkPnmiInit( pAC, pAC->IoBase, 2);
-       SkAddrInit( pAC, pAC->IoBase, 2);
-       SkRlmtInit( pAC, pAC->IoBase, 2);
-       SkTimerInit(pAC, pAC->IoBase, 2);
-
-       /*
-        * clear and reinit the rx rings here
-        */
-       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-               ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
-               ClearRxRing(pAC, &pAC->RxPort[i]);
-               FillRxRing(pAC, &pAC->RxPort[i]);
-
-               /* Enable transmit descriptor polling. */
-               SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
-               FillRxRing(pAC, &pAC->RxPort[i]);
-       };
-
-       SkGeYellowLED(pAC, pAC->IoBase, 1);
-
-#ifdef USE_INT_MOD
-       {
-               unsigned long ModBase;
-               ModBase = 53125000 / INTS_PER_SEC;
-               SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
-               SK_OUT32(pAC->IoBase, B2_IRQM_MSK, IRQ_MOD_MASK);
-               SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
-       }
-#endif
-
-       netif_start_queue(pAC->dev[pNet->PortNr]);
-       for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) {
-               spin_unlock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
-       }
-
-       /* enable Interrupts */
-       SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK);
-       SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
-
-       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
-       SkEventDispatcher(pAC, pAC->IoBase);
-
-       /* Found more than one port */
-       if ((pAC->GIni.GIMacsFound == 2 ) &&
-               (pAC->RlmtNets == 2)) {
-                       /* Start both ports */
-                       EvPara.Para32[0] = pAC->RlmtNets;
-                       EvPara.Para32[1] = -1;
-                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
-                               EvPara);
-
-
-                       EvPara.Para32[1] = -1;
-                       EvPara.Para32[0] = pNet->PortNr;
-                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
-
-                       if (pOtherNet->Up) {
-                               EvPara.Para32[0] = pOtherNet->PortNr;
-                               SkEventQueue(pAC, SKGE_RLMT,
-                                       SK_RLMT_START, EvPara);
-                       }
-       } else {
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
-       }
-
-       SkEventDispatcher(pAC, pAC->IoBase);
-       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
-       return 0;
-} /* SkGeChangeMtu */
-
-
-/*****************************************************************************
- *
- *     SkGeStats - return ethernet device statistics
- *
- * Description:
- *     This function return statistic data about the ethernet device
- *     to the operating system.
- *
- * Returns:
- *     pointer to the statistic structure.
- */
-static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev)
-{
-DEV_NET *pNet = (DEV_NET*) dev->priv;
-SK_AC  *pAC = pNet->pAC;
-SK_PNMI_STRUCT_DATA *pPnmiStruct;       /* structure for all Pnmi-Data */
-SK_PNMI_STAT    *pPnmiStat;             /* pointer to virtual XMAC stat. data */
-SK_PNMI_CONF    *pPnmiConf;             /* pointer to virtual link config. */
-unsigned int    Size;                   /* size of pnmi struct */
-unsigned long  Flags;                  /* for spin lock */
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeStats starts now...\n"));
-       pPnmiStruct = &pAC->PnmiStruct;
-       memset(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-       Size = SK_PNMI_STRUCT_SIZE;
-               SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
-       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-       pPnmiStat = &pPnmiStruct->Stat[0];
-       pPnmiConf = &pPnmiStruct->Conf[0];
-
-       pAC->stats.rx_packets = (SK_U32) pPnmiStruct->RxDeliveredCts & 0xFFFFFFFF;
-       pAC->stats.tx_packets = (SK_U32) pPnmiStat->StatTxOkCts & 0xFFFFFFFF;
-       pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts;
-       pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts;
-
-       if (pNet->Mtu <= 1500) {
-               pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
-       } else {
-               pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts -
-                       pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF);
-       }
-
-
-       if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && pAC->HWRevision < 12)
-               pAC->stats.rx_errors = pAC->stats.rx_errors - pPnmiStat->StatRxShortsCts;
-
-       pAC->stats.tx_errors = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
-       pAC->stats.rx_dropped = (SK_U32) pPnmiStruct->RxNoBufCts & 0xFFFFFFFF;
-       pAC->stats.tx_dropped = (SK_U32) pPnmiStruct->TxNoBufCts & 0xFFFFFFFF;
-       pAC->stats.multicast = (SK_U32) pPnmiStat->StatRxMulticastOkCts & 0xFFFFFFFF;
-       pAC->stats.collisions = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
-
-       /* detailed rx_errors: */
-       pAC->stats.rx_length_errors = (SK_U32) pPnmiStat->StatRxRuntCts & 0xFFFFFFFF;
-       pAC->stats.rx_over_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
-       pAC->stats.rx_crc_errors = (SK_U32) pPnmiStat->StatRxFcsCts & 0xFFFFFFFF;
-       pAC->stats.rx_frame_errors = (SK_U32) pPnmiStat->StatRxFramingCts & 0xFFFFFFFF;
-       pAC->stats.rx_fifo_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
-       pAC->stats.rx_missed_errors = (SK_U32) pPnmiStat->StatRxMissedCts & 0xFFFFFFFF;
-
-       /* detailed tx_errors */
-       pAC->stats.tx_aborted_errors = (SK_U32) 0;
-       pAC->stats.tx_carrier_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
-       pAC->stats.tx_fifo_errors = (SK_U32) pPnmiStat->StatTxFifoUnderrunCts & 0xFFFFFFFF;
-       pAC->stats.tx_heartbeat_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
-       pAC->stats.tx_window_errors = (SK_U32) 0;
-
-       return(&pAC->stats);
-} /* SkGeStats */
-
-
-/*****************************************************************************
- *
- *     SkGeIoctl - IO-control function
- *
- * Description:
- *     This function is called if an ioctl is issued on the device.
- *     There are three subfunction for reading, writing and test-writing
- *     the private MIB data structure (usefull for SysKonnect-internal tools).
- *
- * Returns:
- *     0, if everything is ok
- *     !=0, on error
- */
-static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd)
-{
-DEV_NET                *pNet;
-SK_AC          *pAC;
-
-SK_GE_IOCTL    Ioctl;
-unsigned int   Err = 0;
-int            Size;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeIoctl starts now...\n"));
-
-       pNet = (DEV_NET*) dev->priv;
-       pAC = pNet->pAC;
-
-       if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
-               return -EFAULT;
-       }
-
-       switch(cmd) {
-       case SK_IOCTL_SETMIB:
-       case SK_IOCTL_PRESETMIB:
-               if (!capable(CAP_NET_ADMIN)) return -EPERM;
-       case SK_IOCTL_GETMIB:
-               if(copy_from_user(&pAC->PnmiStruct, Ioctl.pData,
-                       Ioctl.Len<sizeof(pAC->PnmiStruct)?
-                       Ioctl.Len : sizeof(pAC->PnmiStruct))) {
-                       return -EFAULT;
-               }
-               Size = SkGeIocMib(pNet, Ioctl.Len, cmd);
-               if(copy_to_user(Ioctl.pData, &pAC->PnmiStruct,
-                       Ioctl.Len<Size? Ioctl.Len : Size)) {
-                       return -EFAULT;
-               }
-               Ioctl.Len = Size;
-               if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
-                       return -EFAULT;
-               }
-               break;
-       default:
-               Err = -EOPNOTSUPP;
-       }
-       return(Err);
-} /* SkGeIoctl */
-
-
-/*****************************************************************************
- *
- *     SkGeIocMib - handle a GetMib, SetMib- or PresetMib-ioctl message
- *
- * Description:
- *     This function reads/writes the MIB data using PNMI (Private Network
- *     Management Interface).
- *     The destination for the data must be provided with the
- *     ioctl call and is given to the driver in the form of
- *     a user space address.
- *     Copying from the user-provided data area into kernel messages
- *     and back is done by copy_from_user and copy_to_user calls in
- *     SkGeIoctl.
- *
- * Returns:
- *     returned size from PNMI call
- */
-static int SkGeIocMib(
-DEV_NET                *pNet,  /* pointer to the adapter context */
-unsigned int   Size,   /* length of ioctl data */
-int            mode)   /* flag for set/preset */
-{
-unsigned long  Flags;  /* for spin lock */
-SK_AC          *pAC;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeIocMib starts now...\n"));
-       pAC = pNet->pAC;
-       /* access MIB */
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-       switch(mode) {
-       case SK_IOCTL_GETMIB:
-               SkPnmiGetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
-                       pNet->NetNr);
-               break;
-       case SK_IOCTL_PRESETMIB:
-               SkPnmiPreSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
-                       pNet->NetNr);
-               break;
-       case SK_IOCTL_SETMIB:
-               SkPnmiSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
-                       pNet->NetNr);
-               break;
-       default:
-               break;
-       }
-       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("MIB data access succeeded\n"));
-       return (Size);
-} /* SkGeIocMib */
-#endif
-
-
-/*****************************************************************************
- *
- *     GetConfiguration - read configuration information
- *
- * Description:
- *     This function reads per-adapter configuration information from
- *     the options provided on the command line.
- *
- * Returns:
- *     none
- */
-static void GetConfiguration(
-SK_AC  *pAC)   /* pointer to the adapter context structure */
-{
-SK_I32 Port;           /* preferred port */
-int    LinkSpeed;      /* Link speed */
-int    AutoNeg;        /* auto negotiation off (0) or on (1) */
-int    DuplexCap;      /* duplex capabilities (0=both, 1=full, 2=half */
-int    MSMode;         /* master / slave mode selection */
-SK_BOOL        AutoSet;
-SK_BOOL DupSet;
-/*
- *     The two parameters AutoNeg. and DuplexCap. map to one configuration
- *     parameter. The mapping is described by this table:
- *     DuplexCap ->    |       both    |       full    |       half    |
- *     AutoNeg         |               |               |               |
- *     -----------------------------------------------------------------
- *     Off             |    illegal    |       Full    |       Half    |
- *     -----------------------------------------------------------------
- *     On              |   AutoBoth    |   AutoFull    |   AutoHalf    |
- *     -----------------------------------------------------------------
- *     Sense           |   AutoSense   |   AutoSense   |   AutoSense   |
- */
-int    Capabilities[3][3] =
-               { {               -1, SK_LMODE_FULL,     SK_LMODE_HALF},
-                 {SK_LMODE_AUTOBOTH, SK_LMODE_AUTOFULL, SK_LMODE_AUTOHALF},
-                 {SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE} };
-#define DC_BOTH        0
-#define DC_FULL 1
-#define DC_HALF 2
-#define AN_OFF 0
-#define AN_ON  1
-#define AN_SENS        2
-
-       /* settings for port A */
-       /* settings link speed */
-       LinkSpeed = SK_LSPEED_AUTO;     /* default: do auto select */
-       if (Speed_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               Speed_A[pAC->Index] != NULL) {
-               if (strcmp(Speed_A[pAC->Index],"")==0) {
-                       LinkSpeed = SK_LSPEED_AUTO;
-               }
-               else if (strcmp(Speed_A[pAC->Index],"Auto")==0) {
-                       LinkSpeed = SK_LSPEED_AUTO;
-               }
-               else if (strcmp(Speed_A[pAC->Index],"10")==0) {
-                       LinkSpeed = SK_LSPEED_10MBPS;
-               }
-               else if (strcmp(Speed_A[pAC->Index],"100")==0) {
-                       LinkSpeed = SK_LSPEED_100MBPS;
-               }
-               else if (strcmp(Speed_A[pAC->Index],"1000")==0) {
-                       LinkSpeed = SK_LSPEED_1000MBPS;
-               }
-               else printk("%s: Illegal value for Speed_A\n",
-                       pAC->dev[0]->name);
-       }
-
-       /* Check speed parameter */
-       /* Only copper type adapter and GE V2 cards */
-       if (((pAC->GIni.GIChipId != CHIP_ID_YUKON) ||
-               (pAC->GIni.GICopperType != SK_TRUE)) &&
-               ((LinkSpeed != SK_LSPEED_AUTO) &&
-               (LinkSpeed != SK_LSPEED_1000MBPS))) {
-               printk("%s: Illegal value for Speed_A. "
-                       "Not a copper card or GE V2 card\n    Using "
-                       "speed 1000\n", pAC->dev[0]->name);
-               LinkSpeed = SK_LSPEED_1000MBPS;
-       }
-       pAC->GIni.GP[0].PLinkSpeed = LinkSpeed;
-
-       /* Autonegotiation */
-       AutoNeg = AN_ON; /* tschilling: Default: Autonegotiation on! */
-       AutoSet = SK_FALSE;
-       if (AutoNeg_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               AutoNeg_A[pAC->Index] != NULL) {
-               AutoSet = SK_TRUE;
-               if (strcmp(AutoNeg_A[pAC->Index],"")==0) {
-                       AutoSet = SK_FALSE;
-               }
-               else if (strcmp(AutoNeg_A[pAC->Index],"On")==0) {
-                       AutoNeg = AN_ON;
-               }
-               else if (strcmp(AutoNeg_A[pAC->Index],"Off")==0) {
-                       AutoNeg = AN_OFF;
-               }
-               else if (strcmp(AutoNeg_A[pAC->Index],"Sense")==0) {
-                       AutoNeg = AN_SENS;
-               }
-               else printk("%s: Illegal value for AutoNeg_A\n",
-                       pAC->dev[0]->name);
-       }
-
-       DuplexCap = DC_BOTH;
-       DupSet = SK_FALSE;
-       if (DupCap_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               DupCap_A[pAC->Index] != NULL) {
-               DupSet = SK_TRUE;
-               if (strcmp(DupCap_A[pAC->Index],"")==0) {
-                       DupSet = SK_FALSE;
-               }
-               else if (strcmp(DupCap_A[pAC->Index],"Both")==0) {
-                       DuplexCap = DC_BOTH;
-               }
-               else if (strcmp(DupCap_A[pAC->Index],"Full")==0) {
-                       DuplexCap = DC_FULL;
-               }
-               else if (strcmp(DupCap_A[pAC->Index],"Half")==0) {
-                       DuplexCap = DC_HALF;
-               }
-               else printk("%s: Illegal value for DupCap_A\n",
-                       pAC->dev[0]->name);
-       }
-
-       /* check for illegal combinations */
-       if (AutoSet && AutoNeg==AN_SENS && DupSet) {
-               printk("%s, Port A: DuplexCapabilities"
-                       " ignored using Sense mode\n", pAC->dev[0]->name);
-       }
-       if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
-               printk("%s, Port A: Illegal combination"
-                       " of values AutoNeg. and DuplexCap.\n    Using "
-                       "Full Duplex\n", pAC->dev[0]->name);
-
-               DuplexCap = DC_FULL;
-       }
-       if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
-               DuplexCap = DC_FULL;
-       }
-
-       if (!AutoSet && DupSet) {
-               printk("%s, Port A: Duplex setting not"
-                       " possible in\n    default AutoNegotiation mode"
-                       " (Sense).\n    Using AutoNegotiation On\n",
-                       pAC->dev[0]->name);
-               AutoNeg = AN_ON;
-       }
-
-       /* set the desired mode */
-       pAC->GIni.GP[0].PLinkModeConf =
-               Capabilities[AutoNeg][DuplexCap];
-
-       pAC->GIni.GP[0].PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
-       if (FlowCtrl_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               FlowCtrl_A[pAC->Index] != NULL) {
-               if (strcmp(FlowCtrl_A[pAC->Index],"") == 0) {
-               }
-               else if (strcmp(FlowCtrl_A[pAC->Index],"SymOrRem") == 0) {
-                       pAC->GIni.GP[0].PFlowCtrlMode =
-                               SK_FLOW_MODE_SYM_OR_REM;
-               }
-               else if (strcmp(FlowCtrl_A[pAC->Index],"Sym")==0) {
-                       pAC->GIni.GP[0].PFlowCtrlMode =
-                               SK_FLOW_MODE_SYMMETRIC;
-               }
-               else if (strcmp(FlowCtrl_A[pAC->Index],"LocSend")==0) {
-                       pAC->GIni.GP[0].PFlowCtrlMode =
-                               SK_FLOW_MODE_LOC_SEND;
-               }
-               else if (strcmp(FlowCtrl_A[pAC->Index],"None")==0) {
-                       pAC->GIni.GP[0].PFlowCtrlMode =
-                               SK_FLOW_MODE_NONE;
-               }
-               else printk("Illegal value for FlowCtrl_A\n");
-       }
-       if (AutoNeg==AN_OFF && pAC->GIni.GP[0].PFlowCtrlMode!=
-               SK_FLOW_MODE_NONE) {
-               printk("%s, Port A: FlowControl"
-                       " impossible without AutoNegotiation,"
-                       " disabled\n", pAC->dev[0]->name);
-               pAC->GIni.GP[0].PFlowCtrlMode = SK_FLOW_MODE_NONE;
-       }
-
-       MSMode = SK_MS_MODE_AUTO; /* default: do auto select */
-       if (Role_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               Role_A[pAC->Index] != NULL) {
-               if (strcmp(Role_A[pAC->Index],"")==0) {
-               }
-               else if (strcmp(Role_A[pAC->Index],"Auto")==0) {
-                       MSMode = SK_MS_MODE_AUTO;
-               }
-               else if (strcmp(Role_A[pAC->Index],"Master")==0) {
-                       MSMode = SK_MS_MODE_MASTER;
-               }
-               else if (strcmp(Role_A[pAC->Index],"Slave")==0) {
-                       MSMode = SK_MS_MODE_SLAVE;
-               }
-               else printk("%s: Illegal value for Role_A\n",
-                       pAC->dev[0]->name);
-       }
-       pAC->GIni.GP[0].PMSMode = MSMode;
-
-
-       /* settings for port B */
-       /* settings link speed */
-       LinkSpeed = SK_LSPEED_AUTO;     /* default: do auto select */
-       if (Speed_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               Speed_B[pAC->Index] != NULL) {
-               if (strcmp(Speed_B[pAC->Index],"")==0) {
-                       LinkSpeed = SK_LSPEED_AUTO;
-               }
-               else if (strcmp(Speed_B[pAC->Index],"Auto")==0) {
-                       LinkSpeed = SK_LSPEED_AUTO;
-               }
-               else if (strcmp(Speed_B[pAC->Index],"10")==0) {
-                       LinkSpeed = SK_LSPEED_10MBPS;
-               }
-               else if (strcmp(Speed_B[pAC->Index],"100")==0) {
-                       LinkSpeed = SK_LSPEED_100MBPS;
-               }
-               else if (strcmp(Speed_B[pAC->Index],"1000")==0) {
-                       LinkSpeed = SK_LSPEED_1000MBPS;
-               }
-               else printk("%s: Illegal value for Speed_B\n",
-                       pAC->dev[1]->name);
-       }
-
-       /* Check speed parameter */
-       /* Only copper type adapter and GE V2 cards */
-       if (((pAC->GIni.GIChipId != CHIP_ID_YUKON) ||
-               (pAC->GIni.GICopperType != SK_TRUE)) &&
-               ((LinkSpeed != SK_LSPEED_AUTO) &&
-               (LinkSpeed != SK_LSPEED_1000MBPS))) {
-               printk("%s: Illegal value for Speed_B. "
-                       "Not a copper card or GE V2 card\n    Using "
-                       "speed 1000\n", pAC->dev[1]->name);
-               LinkSpeed = SK_LSPEED_1000MBPS;
-       }
-       pAC->GIni.GP[1].PLinkSpeed = LinkSpeed;
-
-       /* Auto negotiation */
-       AutoNeg = AN_SENS; /* default: do auto Sense */
-       AutoSet = SK_FALSE;
-       if (AutoNeg_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               AutoNeg_B[pAC->Index] != NULL) {
-               AutoSet = SK_TRUE;
-               if (strcmp(AutoNeg_B[pAC->Index],"")==0) {
-                       AutoSet = SK_FALSE;
-               }
-               else if (strcmp(AutoNeg_B[pAC->Index],"On")==0) {
-                       AutoNeg = AN_ON;
-               }
-               else if (strcmp(AutoNeg_B[pAC->Index],"Off")==0) {
-                       AutoNeg = AN_OFF;
-               }
-               else if (strcmp(AutoNeg_B[pAC->Index],"Sense")==0) {
-                       AutoNeg = AN_SENS;
-               }
-               else printk("Illegal value for AutoNeg_B\n");
-       }
-
-       DuplexCap = DC_BOTH;
-       DupSet = SK_FALSE;
-       if (DupCap_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               DupCap_B[pAC->Index] != NULL) {
-               DupSet = SK_TRUE;
-               if (strcmp(DupCap_B[pAC->Index],"")==0) {
-                       DupSet = SK_FALSE;
-               }
-               else if (strcmp(DupCap_B[pAC->Index],"Both")==0) {
-                       DuplexCap = DC_BOTH;
-               }
-               else if (strcmp(DupCap_B[pAC->Index],"Full")==0) {
-                       DuplexCap = DC_FULL;
-               }
-               else if (strcmp(DupCap_B[pAC->Index],"Half")==0) {
-                       DuplexCap = DC_HALF;
-               }
-               else printk("Illegal value for DupCap_B\n");
-       }
-
-       /* check for illegal combinations */
-       if (AutoSet && AutoNeg==AN_SENS && DupSet) {
-               printk("%s, Port B: DuplexCapabilities"
-                       " ignored using Sense mode\n", pAC->dev[1]->name);
-       }
-       if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
-               printk("%s, Port B: Illegal combination"
-                       " of values AutoNeg. and DuplexCap.\n    Using "
-                       "Full Duplex\n", pAC->dev[1]->name);
-
-               DuplexCap = DC_FULL;
-       }
-       if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
-               DuplexCap = DC_FULL;
-       }
-
-       if (!AutoSet && DupSet) {
-               printk("%s, Port B: Duplex setting not"
-                       " possible in\n    default AutoNegotiation mode"
-                       " (Sense).\n    Using AutoNegotiation On\n",
-                       pAC->dev[1]->name);
-               AutoNeg = AN_ON;
-       }
-
-       /* set the desired mode */
-       pAC->GIni.GP[1].PLinkModeConf =
-               Capabilities[AutoNeg][DuplexCap];
-
-       pAC->GIni.GP[1].PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
-       if (FlowCtrl_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               FlowCtrl_B[pAC->Index] != NULL) {
-               if (strcmp(FlowCtrl_B[pAC->Index],"") == 0) {
-               }
-               else if (strcmp(FlowCtrl_B[pAC->Index],"SymOrRem") == 0) {
-                       pAC->GIni.GP[1].PFlowCtrlMode =
-                               SK_FLOW_MODE_SYM_OR_REM;
-               }
-               else if (strcmp(FlowCtrl_B[pAC->Index],"Sym")==0) {
-                       pAC->GIni.GP[1].PFlowCtrlMode =
-                               SK_FLOW_MODE_SYMMETRIC;
-               }
-               else if (strcmp(FlowCtrl_B[pAC->Index],"LocSend")==0) {
-                       pAC->GIni.GP[1].PFlowCtrlMode =
-                               SK_FLOW_MODE_LOC_SEND;
-               }
-               else if (strcmp(FlowCtrl_B[pAC->Index],"None")==0) {
-                       pAC->GIni.GP[1].PFlowCtrlMode =
-                               SK_FLOW_MODE_NONE;
-               }
-               else printk("Illegal value for FlowCtrl_B\n");
-       }
-       if (AutoNeg==AN_OFF && pAC->GIni.GP[1].PFlowCtrlMode!=
-               SK_FLOW_MODE_NONE) {
-               printk("%s, Port B: FlowControl"
-                       " impossible without AutoNegotiation,"
-                       " disabled\n", pAC->dev[1]->name);
-               pAC->GIni.GP[1].PFlowCtrlMode = SK_FLOW_MODE_NONE;
-       }
-
-       MSMode = SK_MS_MODE_AUTO; /* default: do auto select */
-       if (Role_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               Role_B[pAC->Index] != NULL) {
-               if (strcmp(Role_B[pAC->Index],"")==0) {
-               }
-               else if (strcmp(Role_B[pAC->Index],"Auto")==0) {
-                       MSMode = SK_MS_MODE_AUTO;
-               }
-               else if (strcmp(Role_B[pAC->Index],"Master")==0) {
-                       MSMode = SK_MS_MODE_MASTER;
-               }
-               else if (strcmp(Role_B[pAC->Index],"Slave")==0) {
-                       MSMode = SK_MS_MODE_SLAVE;
-               }
-               else printk("%s: Illegal value for Role_B\n",
-                       pAC->dev[1]->name);
-       }
-       pAC->GIni.GP[1].PMSMode = MSMode;
-
-
-       /* settings for both ports */
-       pAC->ActivePort = 0;
-       if (PrefPort != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               PrefPort[pAC->Index] != NULL) {
-               if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */
-                       pAC->ActivePort = 0;
-                       pAC->Rlmt.Net[0].Preference = -1; /* auto */
-                       pAC->Rlmt.Net[0].PrefPort = 0;
-               }
-               else if (strcmp(PrefPort[pAC->Index],"A") == 0) {
-                       /*
-                        * do not set ActivePort here, thus a port
-                        * switch is issued after net up.
-                        */
-                       Port = 0;
-                       pAC->Rlmt.Net[0].Preference = Port;
-                       pAC->Rlmt.Net[0].PrefPort = Port;
-               }
-               else if (strcmp(PrefPort[pAC->Index],"B") == 0) {
-                       /*
-                        * do not set ActivePort here, thus a port
-                        * switch is issued after net up.
-                        */
-                       Port = 1;
-                       pAC->Rlmt.Net[0].Preference = Port;
-                       pAC->Rlmt.Net[0].PrefPort = Port;
-               }
-               else printk("%s: Illegal value for PrefPort\n",
-                       pAC->dev[0]->name);
-       }
-
-       pAC->RlmtNets = 1;
-
-       if (RlmtMode != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               RlmtMode[pAC->Index] != NULL) {
-               if (strcmp(RlmtMode[pAC->Index], "") == 0) {
-                       pAC->RlmtMode = 0;
-               }
-               else if (strcmp(RlmtMode[pAC->Index], "CheckLinkState") == 0) {
-                       pAC->RlmtMode = SK_RLMT_CHECK_LINK;
-               }
-               else if (strcmp(RlmtMode[pAC->Index], "CheckLocalPort") == 0) {
-                       pAC->RlmtMode = SK_RLMT_CHECK_LINK |
-                               SK_RLMT_CHECK_LOC_LINK;
-               }
-               else if (strcmp(RlmtMode[pAC->Index], "CheckSeg") == 0) {
-                       pAC->RlmtMode = SK_RLMT_CHECK_LINK |
-                               SK_RLMT_CHECK_LOC_LINK |
-                               SK_RLMT_CHECK_SEG;
-               }
-               else if ((strcmp(RlmtMode[pAC->Index], "DualNet") == 0) &&
-                       (pAC->GIni.GIMacsFound == 2)) {
-                               pAC->RlmtMode = SK_RLMT_CHECK_LINK;
-                               pAC->RlmtNets = 2;
-               }
-               else {
-                       printk("%s: Illegal value for"
-                               " RlmtMode, using default\n", pAC->dev[0]->name);
-                       pAC->RlmtMode = 0;
-               }
-       }
-       else {
-               pAC->RlmtMode = 0;
-       }
-} /* GetConfiguration */
-
-
-/*****************************************************************************
- *
- *     ProductStr - return a adapter identification string from vpd
- *
- * Description:
- *     This function reads the product name string from the vpd area
- *     and puts it the field pAC->DeviceString.
- *
- * Returns: N/A
- */
-static void ProductStr(
-SK_AC  *pAC            /* pointer to adapter context */
-)
-{
-int    StrLen = 80;            /* length of the string, defined in SK_AC */
-char   Keyword[] = VPD_NAME;   /* vpd productname identifier */
-int    ReturnCode;             /* return code from vpd_read */
-unsigned long Flags;
-
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-       ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, pAC->DeviceStr,
-               &StrLen);
-       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-       if (ReturnCode != 0) {
-               /* there was an error reading the vpd data */
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
-                       ("Error reading VPD data: %d\n", ReturnCode));
-               pAC->DeviceStr[0] = '\0';
-       }
-} /* ProductStr */
-
-
-/****************************************************************************/
-/* functions for common modules *********************************************/
-/****************************************************************************/
-
-
-/*****************************************************************************
- *
- *     SkDrvAllocRlmtMbuf - allocate an RLMT mbuf
- *
- * Description:
- *     This routine returns an RLMT mbuf or NULL. The RLMT Mbuf structure
- *     is embedded into a socket buff data area.
- *
- * Context:
- *     runtime
- *
- * Returns:
- *     NULL or pointer to Mbuf.
- */
-SK_MBUF *SkDrvAllocRlmtMbuf(
-SK_AC          *pAC,           /* pointer to adapter context */
-SK_IOC         IoC,            /* the IO-context */
-unsigned       BufferSize)     /* size of the requested buffer */
-{
-SK_MBUF                *pRlmtMbuf;     /* pointer to a new rlmt-mbuf structure */
-struct sk_buff *pMsgBlock;     /* pointer to a new message block */
-
-       pMsgBlock = alloc_skb(BufferSize + sizeof(SK_MBUF), GFP_ATOMIC);
-       if (pMsgBlock == NULL) {
-               return (NULL);
-       }
-       pRlmtMbuf = (SK_MBUF*) pMsgBlock->data;
-       skb_reserve(pMsgBlock, sizeof(SK_MBUF));
-       pRlmtMbuf->pNext = NULL;
-       pRlmtMbuf->pOs = pMsgBlock;
-       pRlmtMbuf->pData = pMsgBlock->data;     /* Data buffer. */
-       pRlmtMbuf->Size = BufferSize;           /* Data buffer size. */
-       pRlmtMbuf->Length = 0;          /* Length of packet (<= Size). */
-       return (pRlmtMbuf);
-
-} /* SkDrvAllocRlmtMbuf */
-
-
-/*****************************************************************************
- *
- *     SkDrvFreeRlmtMbuf - free an RLMT mbuf
- *
- * Description:
- *     This routine frees one or more RLMT mbuf(s).
- *
- * Context:
- *     runtime
- *
- * Returns:
- *     Nothing
- */
-void  SkDrvFreeRlmtMbuf(
-SK_AC          *pAC,           /* pointer to adapter context */
-SK_IOC         IoC,            /* the IO-context */
-SK_MBUF                *pMbuf)         /* size of the requested buffer */
-{
-SK_MBUF                *pFreeMbuf;
-SK_MBUF                *pNextMbuf;
-
-       pFreeMbuf = pMbuf;
-       do {
-               pNextMbuf = pFreeMbuf->pNext;
-               DEV_KFREE_SKB_ANY(pFreeMbuf->pOs);
-               pFreeMbuf = pNextMbuf;
-       } while ( pFreeMbuf != NULL );
-} /* SkDrvFreeRlmtMbuf */
-
-
-/*****************************************************************************
- *
- *     SkOsGetTime - provide a time value
- *
- * Description:
- *     This routine provides a time value. The unit is 1/HZ (defined by Linux).
- *     It is not used for absolute time, but only for time differences.
- *
- *
- * Returns:
- *     Time value
- */
-SK_U64 SkOsGetTime(SK_AC *pAC)
-{
-#if 0
-       return jiffies;
-#else
-       return get_timer(0);
-#endif
-} /* SkOsGetTime */
-
-
-/*****************************************************************************
- *
- *     SkPciReadCfgDWord - read a 32 bit value from pci config space
- *
- * Description:
- *     This routine reads a 32 bit value from the pci configuration
- *     space.
- *
- * Returns:
- *     0 - indicate everything worked ok.
- *     != 0 - error indication
- */
-int SkPciReadCfgDWord(
-SK_AC *pAC,            /* Adapter Control structure pointer */
-int PciAddr,           /* PCI register address */
-SK_U32 *pVal)          /* pointer to store the read value */
-{
-       pci_read_config_dword(pAC->PciDev, PciAddr, pVal);
-       return(0);
-} /* SkPciReadCfgDWord */
-
-
-/*****************************************************************************
- *
- *     SkPciReadCfgWord - read a 16 bit value from pci config space
- *
- * Description:
- *     This routine reads a 16 bit value from the pci configuration
- *     space.
- *
- * Returns:
- *     0 - indicate everything worked ok.
- *     != 0 - error indication
- */
-int SkPciReadCfgWord(
-SK_AC *pAC,    /* Adapter Control structure pointer */
-int PciAddr,           /* PCI register address */
-SK_U16 *pVal)          /* pointer to store the read value */
-{
-       pci_read_config_word(pAC->PciDev, PciAddr, pVal);
-       return(0);
-} /* SkPciReadCfgWord */
-
-
-/*****************************************************************************
- *
- *     SkPciReadCfgByte - read a 8 bit value from pci config space
- *
- * Description:
- *     This routine reads a 8 bit value from the pci configuration
- *     space.
- *
- * Returns:
- *     0 - indicate everything worked ok.
- *     != 0 - error indication
- */
-int SkPciReadCfgByte(
-SK_AC *pAC,    /* Adapter Control structure pointer */
-int PciAddr,           /* PCI register address */
-SK_U8 *pVal)           /* pointer to store the read value */
-{
-       pci_read_config_byte(pAC->PciDev, PciAddr, pVal);
-       return(0);
-} /* SkPciReadCfgByte */
-
-
-/*****************************************************************************
- *
- *     SkPciWriteCfgDWord - write a 32 bit value to pci config space
- *
- * Description:
- *     This routine writes a 32 bit value to the pci configuration
- *     space.
- *
- * Returns:
- *     0 - indicate everything worked ok.
- *     != 0 - error indication
- */
-int SkPciWriteCfgDWord(
-SK_AC *pAC,    /* Adapter Control structure pointer */
-int PciAddr,           /* PCI register address */
-SK_U32 Val)            /* pointer to store the read value */
-{
-       pci_write_config_dword(pAC->PciDev, PciAddr, Val);
-       return(0);
-} /* SkPciWriteCfgDWord */
-
-
-/*****************************************************************************
- *
- *     SkPciWriteCfgWord - write a 16 bit value to pci config space
- *
- * Description:
- *     This routine writes a 16 bit value to the pci configuration
- *     space. The flag PciConfigUp indicates whether the config space
- *     is accesible or must be set up first.
- *
- * Returns:
- *     0 - indicate everything worked ok.
- *     != 0 - error indication
- */
-int SkPciWriteCfgWord(
-SK_AC *pAC,    /* Adapter Control structure pointer */
-int PciAddr,           /* PCI register address */
-SK_U16 Val)            /* pointer to store the read value */
-{
-       pci_write_config_word(pAC->PciDev, PciAddr, Val);
-       return(0);
-} /* SkPciWriteCfgWord */
-
-
-/*****************************************************************************
- *
- *     SkPciWriteCfgWord - write a 8 bit value to pci config space
- *
- * Description:
- *     This routine writes a 8 bit value to the pci configuration
- *     space. The flag PciConfigUp indicates whether the config space
- *     is accesible or must be set up first.
- *
- * Returns:
- *     0 - indicate everything worked ok.
- *     != 0 - error indication
- */
-int SkPciWriteCfgByte(
-SK_AC *pAC,    /* Adapter Control structure pointer */
-int PciAddr,           /* PCI register address */
-SK_U8 Val)             /* pointer to store the read value */
-{
-       pci_write_config_byte(pAC->PciDev, PciAddr, Val);
-       return(0);
-} /* SkPciWriteCfgByte */
-
-
-/*****************************************************************************
- *
- *     SkDrvEvent - handle driver events
- *
- * Description:
- *     This function handles events from all modules directed to the driver
- *
- * Context:
- *     Is called under protection of slow path lock.
- *
- * Returns:
- *     0 if everything ok
- *     < 0  on error
- *
- */
-int SkDrvEvent(
-SK_AC *pAC,            /* pointer to adapter context */
-SK_IOC IoC,            /* io-context */
-SK_U32 Event,          /* event-id */
-SK_EVPARA Param)       /* event-parameter */
-{
-SK_MBUF                *pRlmtMbuf;     /* pointer to a rlmt-mbuf structure */
-struct sk_buff *pMsg;          /* pointer to a message block */
-int            FromPort;       /* the port from which we switch away */
-int            ToPort;         /* the port we switch to */
-SK_EVPARA      NewPara;        /* parameter for further events */
-#if 0
-int            Stat;
-#endif
-unsigned long  Flags;
-SK_BOOL                DualNet;
-
-       switch (Event) {
-       case SK_DRV_ADAP_FAIL:
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-                       ("ADAPTER FAIL EVENT\n"));
-               printk("%s: Adapter failed.\n", pAC->dev[0]->name);
-               /* disable interrupts */
-               SK_OUT32(pAC->IoBase, B0_IMSK, 0);
-               /* cgoos */
-               break;
-       case SK_DRV_PORT_FAIL:
-               FromPort = Param.Para32[0];
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-                       ("PORT FAIL EVENT, Port: %d\n", FromPort));
-               if (FromPort == 0) {
-                       printk("%s: Port A failed.\n", pAC->dev[0]->name);
-               } else {
-                       printk("%s: Port B failed.\n", pAC->dev[1]->name);
-               }
-               /* cgoos */
-               break;
-       case SK_DRV_PORT_RESET:  /* SK_U32 PortIdx */
-               /* action list 4 */
-               FromPort = Param.Para32[0];
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-                       ("PORT RESET EVENT, Port: %d ", FromPort));
-               NewPara.Para64 = FromPort;
-               SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
-               spin_lock_irqsave(
-                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                       Flags);
-               SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
-#if 0
-               pAC->dev[Param.Para32[0]]->flags &= ~IFF_RUNNING;
-#endif
-               spin_unlock_irqrestore(
-                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                       Flags);
-
-               /* clear rx ring from received frames */
-               ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE);
-
-               ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
-               spin_lock_irqsave(
-                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                       Flags);
-
-               /* tschilling: Handling of return value inserted. */
-               if (SkGeInitPort(pAC, IoC, FromPort)) {
-                       if (FromPort == 0) {
-                               printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name);
-                       } else {
-                               printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name);
-                       }
-               }
-               SkAddrMcUpdate(pAC,IoC, FromPort);
-               PortReInitBmu(pAC, FromPort);
-               SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
-               ClearAndStartRx(pAC, FromPort);
-               spin_unlock_irqrestore(
-                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                       Flags);
-               break;
-       case SK_DRV_NET_UP:      /* SK_U32 PortIdx */
-               /* action list 5 */
-               FromPort = Param.Para32[0];
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-                       ("NET UP EVENT, Port: %d ", Param.Para32[0]));
-#ifdef SK98_INFO
-               printk("%s: network connection up using"
-                       " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]);
-
-               /* tschilling: Values changed according to LinkSpeedUsed. */
-               Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed;
-               if (Stat == SK_LSPEED_STAT_10MBPS) {
-                       printk("    speed:           10\n");
-               } else if (Stat == SK_LSPEED_STAT_100MBPS) {
-                       printk("    speed:           100\n");
-               } else if (Stat == SK_LSPEED_STAT_1000MBPS) {
-                       printk("    speed:           1000\n");
-               } else {
-                       printk("    speed:           unknown\n");
-               }
-
-               Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
-               if (Stat == SK_LMODE_STAT_AUTOHALF ||
-                       Stat == SK_LMODE_STAT_AUTOFULL) {
-                       printk("    autonegotiation: yes\n");
-               }
-               else {
-                       printk("    autonegotiation: no\n");
-               }
-               if (Stat == SK_LMODE_STAT_AUTOHALF ||
-                       Stat == SK_LMODE_STAT_HALF) {
-                       printk("    duplex mode:     half\n");
-               }
-               else {
-                       printk("    duplex mode:     full\n");
-               }
-               Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus;
-               if (Stat == SK_FLOW_STAT_REM_SEND ) {
-                       printk("    flowctrl:        remote send\n");
-               }
-               else if (Stat == SK_FLOW_STAT_LOC_SEND ){
-                       printk("    flowctrl:        local send\n");
-               }
-               else if (Stat == SK_FLOW_STAT_SYMMETRIC ){
-                       printk("    flowctrl:        symmetric\n");
-               }
-               else {
-                       printk("    flowctrl:        none\n");
-               }
-
-               /* tschilling: Check against CopperType now. */
-               if ((pAC->GIni.GICopperType == SK_TRUE) &&
-                       (pAC->GIni.GP[FromPort].PLinkSpeedUsed ==
-                       SK_LSPEED_STAT_1000MBPS)) {
-                       Stat = pAC->GIni.GP[FromPort].PMSStatus;
-                       if (Stat == SK_MS_STAT_MASTER ) {
-                               printk("    role:            master\n");
-                       }
-                       else if (Stat == SK_MS_STAT_SLAVE ) {
-                               printk("    role:            slave\n");
-                       }
-                       else {
-                               printk("    role:            ???\n");
-                       }
-               }
-
-#ifdef SK_ZEROCOPY
-               if (pAC->GIni.GIChipId == CHIP_ID_YUKON)
-                       printk("    scatter-gather:  enabled\n");
-               else
-                       printk("    scatter-gather:  disabled\n");
-
-#else
-                       printk("    scatter-gather:  disabled\n");
-#endif
-#endif /* SK98_INFO */
-
-               if ((Param.Para32[0] != pAC->ActivePort) &&
-                       (pAC->RlmtNets == 1)) {
-                       NewPara.Para32[0] = pAC->ActivePort;
-                       NewPara.Para32[1] = Param.Para32[0];
-                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN,
-                               NewPara);
-               }
-
-               /* Inform the world that link protocol is up. */
-#if 0
-               pAC->dev[Param.Para32[0]]->flags |= IFF_RUNNING;
-#endif
-
-               break;
-       case SK_DRV_NET_DOWN:    /* SK_U32 Reason */
-               /* action list 7 */
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-                       ("NET DOWN EVENT "));
-#ifdef SK98_INFO
-               printk("%s: network connection down\n", pAC->dev[Param.Para32[1]]->name);
-#endif
-#if 0
-               pAC->dev[Param.Para32[1]]->flags &= ~IFF_RUNNING;
-#endif
-               break;
-       case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-                       ("PORT SWITCH HARD "));
-       case SK_DRV_SWITCH_SOFT: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
-       /* action list 6 */
-               printk("%s: switching to port %c\n", pAC->dev[0]->name,
-                       'A'+Param.Para32[1]);
-       case SK_DRV_SWITCH_INTERN: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
-               FromPort = Param.Para32[0];
-               ToPort = Param.Para32[1];
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-                       ("PORT SWITCH EVENT, From: %d  To: %d (Pref %d) ",
-                       FromPort, ToPort, pAC->Rlmt.Net[0].PrefPort));
-               NewPara.Para64 = FromPort;
-               SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
-               NewPara.Para64 = ToPort;
-               SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
-               spin_lock_irqsave(
-                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                       Flags);
-               spin_lock_irqsave(
-                       &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
-               SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST);
-               SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST);
-               spin_unlock_irqrestore(
-                       &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
-               spin_unlock_irqrestore(
-                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                       Flags);
-
-               ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */
-               ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */
-
-               ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
-               ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]);
-               spin_lock_irqsave(
-                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                       Flags);
-               spin_lock_irqsave(
-                       &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
-               pAC->ActivePort = ToPort;
-#if 0
-               SetQueueSizes(pAC);
-#else
-               /* tschilling: New common function with minimum size check. */
-               DualNet = SK_FALSE;
-               if (pAC->RlmtNets == 2) {
-                       DualNet = SK_TRUE;
-               }
-
-               if (SkGeInitAssignRamToQueues(
-                       pAC,
-                       pAC->ActivePort,
-                       DualNet)) {
-                       spin_unlock_irqrestore(
-                               &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
-                       spin_unlock_irqrestore(
-                               &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                               Flags);
-                       printk("SkGeInitAssignRamToQueues failed.\n");
-                       break;
-               }
-#endif
-               /* tschilling: Handling of return values inserted. */
-               if (SkGeInitPort(pAC, IoC, FromPort) ||
-                       SkGeInitPort(pAC, IoC, ToPort)) {
-                       printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name);
-               }
-               if (Event == SK_DRV_SWITCH_SOFT) {
-                       SkMacRxTxEnable(pAC, IoC, FromPort);
-               }
-               SkMacRxTxEnable(pAC, IoC, ToPort);
-               SkAddrSwap(pAC, IoC, FromPort, ToPort);
-               SkAddrMcUpdate(pAC, IoC, FromPort);
-               SkAddrMcUpdate(pAC, IoC, ToPort);
-               PortReInitBmu(pAC, FromPort);
-               PortReInitBmu(pAC, ToPort);
-               SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
-               SkGePollTxD(pAC, IoC, ToPort, SK_TRUE);
-               ClearAndStartRx(pAC, FromPort);
-               ClearAndStartRx(pAC, ToPort);
-               spin_unlock_irqrestore(
-                       &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
-               spin_unlock_irqrestore(
-                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                       Flags);
-               break;
-       case SK_DRV_RLMT_SEND:   /* SK_MBUF *pMb */
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-                       ("RLS "));
-               pRlmtMbuf = (SK_MBUF*) Param.pParaPtr;
-               pMsg = (struct sk_buff*) pRlmtMbuf->pOs;
-               skb_put(pMsg, pRlmtMbuf->Length);
-               if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW],
-                       pMsg) < 0)
-
-                       DEV_KFREE_SKB_ANY(pMsg);
-               break;
-       default:
-               break;
-       }
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-               ("END EVENT "));
-
-       return (0);
-} /* SkDrvEvent */
-
-
-/*****************************************************************************
- *
- *     SkErrorLog - log errors
- *
- * Description:
- *     This function logs errors to the system buffer and to the console
- *
- * Returns:
- *     0 if everything ok
- *     < 0  on error
- *
- */
-void SkErrorLog(
-SK_AC  *pAC,
-int    ErrClass,
-int    ErrNum,
-char   *pErrorMsg)
-{
-char   ClassStr[80];
-
-       switch (ErrClass) {
-       case SK_ERRCL_OTHER:
-               strcpy(ClassStr, "Other error");
-               break;
-       case SK_ERRCL_CONFIG:
-               strcpy(ClassStr, "Configuration error");
-               break;
-       case SK_ERRCL_INIT:
-               strcpy(ClassStr, "Initialization error");
-               break;
-       case SK_ERRCL_NORES:
-               strcpy(ClassStr, "Out of resources error");
-               break;
-       case SK_ERRCL_SW:
-               strcpy(ClassStr, "internal Software error");
-               break;
-       case SK_ERRCL_HW:
-               strcpy(ClassStr, "Hardware failure");
-               break;
-       case SK_ERRCL_COMM:
-               strcpy(ClassStr, "Communication error");
-               break;
-       }
-       printk(KERN_INFO "%s: -- ERROR --\n        Class:  %s\n"
-               "        Nr:  0x%x\n        Msg:  %s\n", pAC->dev[0]->name,
-               ClassStr, ErrNum, pErrorMsg);
-
-} /* SkErrorLog */
-
-#ifdef DEBUG
-/****************************************************************************/
-/* "debug only" section *****************************************************/
-/****************************************************************************/
-
-
-/*****************************************************************************
- *
- *     DumpMsg - print a frame
- *
- * Description:
- *     This function prints frames to the system logfile/to the console.
- *
- * Returns: N/A
- *
- */
-static void DumpMsg(struct sk_buff *skb, char *str)
-{
-       int     msglen;
-
-       if (skb == NULL) {
-               printk("DumpMsg(): NULL-Message\n");
-               return;
-       }
-
-       if (skb->data == NULL) {
-               printk("DumpMsg(): Message empty\n");
-               return;
-       }
-
-       msglen = skb->len;
-       if (msglen > 64)
-               msglen = 64;
-
-       printk("--- Begin of message from %s , len %d (from %d) ----\n", str, msglen, skb->len);
-
-       DumpData((char *)skb->data, msglen);
-
-       printk("------- End of message ---------\n");
-} /* DumpMsg */
-
-
-/*****************************************************************************
- *
- *     DumpData - print a data area
- *
- * Description:
- *     This function prints a area of data to the system logfile/to the
- *     console.
- *
- * Returns: N/A
- *
- */
-static void DumpData(char *p, int size)
-{
-register int    i;
-int    haddr, addr;
-char   hex_buffer[180];
-char   asc_buffer[180];
-char   HEXCHAR[] = "0123456789ABCDEF";
-
-       addr = 0;
-       haddr = 0;
-       hex_buffer[0] = 0;
-       asc_buffer[0] = 0;
-       for (i=0; i < size; ) {
-               if (*p >= '0' && *p <='z')
-                       asc_buffer[addr] = *p;
-               else
-                       asc_buffer[addr] = '.';
-               addr++;
-               asc_buffer[addr] = 0;
-               hex_buffer[haddr] = HEXCHAR[(*p & 0xf0) >> 4];
-               haddr++;
-               hex_buffer[haddr] = HEXCHAR[*p & 0x0f];
-               haddr++;
-               hex_buffer[haddr] = ' ';
-               haddr++;
-               hex_buffer[haddr] = 0;
-               p++;
-               i++;
-               if (i%16 == 0) {
-                       printk("%s  %s\n", hex_buffer, asc_buffer);
-                       addr = 0;
-                       haddr = 0;
-               }
-       }
-} /* DumpData */
-
-
-/*****************************************************************************
- *
- *     DumpLong - print a data area as long values
- *
- * Description:
- *     This function prints a area of data to the system logfile/to the
- *     console.
- *
- * Returns: N/A
- *
- */
-static void DumpLong(char *pc, int size)
-{
-register int    i;
-int    haddr, addr;
-char   hex_buffer[180];
-char   asc_buffer[180];
-char   HEXCHAR[] = "0123456789ABCDEF";
-long   *p;
-int    l;
-
-       addr = 0;
-       haddr = 0;
-       hex_buffer[0] = 0;
-       asc_buffer[0] = 0;
-       p = (long*) pc;
-       for (i=0; i < size; ) {
-               l = (long) *p;
-               hex_buffer[haddr] = HEXCHAR[(l >> 28) & 0xf];
-               haddr++;
-               hex_buffer[haddr] = HEXCHAR[(l >> 24) & 0xf];
-               haddr++;
-               hex_buffer[haddr] = HEXCHAR[(l >> 20) & 0xf];
-               haddr++;
-               hex_buffer[haddr] = HEXCHAR[(l >> 16) & 0xf];
-               haddr++;
-               hex_buffer[haddr] = HEXCHAR[(l >> 12) & 0xf];
-               haddr++;
-               hex_buffer[haddr] = HEXCHAR[(l >> 8) & 0xf];
-               haddr++;
-               hex_buffer[haddr] = HEXCHAR[(l >> 4) & 0xf];
-               haddr++;
-               hex_buffer[haddr] = HEXCHAR[l & 0x0f];
-               haddr++;
-               hex_buffer[haddr] = ' ';
-               haddr++;
-               hex_buffer[haddr] = 0;
-               p++;
-               i++;
-               if (i%8 == 0) {
-                       printk("%4x %s\n", (i-8)*4, hex_buffer);
-                       haddr = 0;
-               }
-       }
-       printk("------------------------\n");
-} /* DumpLong */
-
-#endif
-
-#endif /* CONFIG_SK98 */
diff --git a/drivers/sk98lin/skgehwt.c b/drivers/sk98lin/skgehwt.c
deleted file mode 100644 (file)
index f8681a8..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-/******************************************************************************
- *
- * Name:       skgehwt.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.13 $
- * Date:       $Date: 1999/11/22 13:31:12 $
- * Purpose:    Hardware Timer.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998,1999 SysKonnect,
- *     a business unit of Schneider & Koch & Co. Datensysteme GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skgehwt.c,v $
- *     Revision 1.13  1999/11/22 13:31:12  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.12  1998/10/15 15:11:34  gklug
- *     fix: ID_sccs to SysKonnectFileId
- *
- *     Revision 1.11  1998/10/08 15:27:51  gklug
- *     chg: correction factor is host clock dependent
- *
- *     Revision 1.10  1998/09/15 14:18:31  cgoos
- *     Changed more BOOLEANs to SK_xxx
- *
- *     Revision 1.9  1998/09/15 14:16:06  cgoos
- *     Changed line 107: FALSE to SK_FALSE
- *
- *     Revision 1.8  1998/08/24 13:04:44  gklug
- *     fix: typo
- *
- *     Revision 1.7  1998/08/19 09:50:49  gklug
- *     fix: remove struct keyword from c-code (see CCC) add typedefs
- *
- *     Revision 1.6  1998/08/17 09:59:02  gklug
- *     fix: typos
- *
- *     Revision 1.5  1998/08/14 07:09:10  gklug
- *     fix: chg pAc -> pAC
- *
- *     Revision 1.4  1998/08/10 14:14:52  gklug
- *     rmv: unneccessary SK_ADDR macro
- *
- *     Revision 1.3  1998/08/07 12:53:44  gklug
- *     fix: first compiled version
- *
- *     Revision 1.2  1998/08/07 09:19:29  gklug
- *     adapt functions to the C coding conventions
- *     rmv unneccessary functions.
- *
- *     Revision 1.1  1998/08/05 11:28:36  gklug
- *     first version: adapted from SMT/FDDI
- *
- *
- *
- *
- ******************************************************************************/
-
-
-#include <config.h>
-
-#ifdef CONFIG_SK98
-
-/*
-       Event queue and dispatcher
-*/
-static const char SysKonnectFileId[] =
-       "$Header: /usr56/projects/ge/schedule/skgehwt.c,v 1.13 1999/11/22 13:31:12 cgoos Exp $" ;
-
-#include "h/skdrv1st.h"                /* Driver Specific Definitions */
-#include "h/skdrv2nd.h"                /* Adapter Control- and Driver specific Def. */
-
-#ifdef __C2MAN__
-/*
-       Hardware Timer function queue management.
-
-       General Description:
-
- */
-intro()
-{}
-#endif
-
-/*
- * Prototypes of local functions.
- */
-#define        SK_HWT_MAX      (65000)
-
-/* correction factor */
-#define        SK_HWT_FAC      (1000 * (SK_U32)pAC->GIni.GIHstClkFact / 100)
-
-/*
- * Initialize hardware timer.
- *
- * Must be called during init level 1.
- */
-void   SkHwtInit(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC Ioc)    /* IoContext */
-{
-       pAC->Hwt.TStart = 0 ;
-       pAC->Hwt.TStop  = 0 ;
-       pAC->Hwt.TActive = SK_FALSE ;
-
-       SkHwtStop(pAC,Ioc) ;
-}
-
-/*
- *
- * Start hardware timer (clock ticks are 16us).
- *
- */
-void   SkHwtStart(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC Ioc,    /* IoContext */
-SK_U32 Time)   /* Time in units of 16us to load the timer with. */
-{
-       SK_U32  Cnt ;
-
-       if (Time > SK_HWT_MAX)
-               Time = SK_HWT_MAX ;
-
-       pAC->Hwt.TStart = Time ;
-       pAC->Hwt.TStop = 0L ;
-
-       Cnt = Time ;
-
-       /*
-        * if time < 16 us
-        *      time = 16 us
-        */
-       if (!Cnt) {
-               Cnt++ ;
-       }
-
-       SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC) ;
-       SK_OUT16(Ioc, B2_TI_CRTL, TIM_START) ;  /* Start timer. */
-
-       pAC->Hwt.TActive = SK_TRUE ;
-}
-
-/*
- * Stop hardware timer.
- * and clear the timer IRQ
- */
-void   SkHwtStop(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC Ioc)    /* IoContext */
-{
-       SK_OUT16(Ioc, B2_TI_CRTL, TIM_STOP) ;
-       SK_OUT16(Ioc, B2_TI_CRTL, TIM_CLR_IRQ) ;
-
-       pAC->Hwt.TActive = SK_FALSE ;
-}
-
-
-/*
- *     Stop hardware timer and read time elapsed since last start.
- *
- * returns
- *     The elapsed time since last start in units of 16us.
- *
- */
-SK_U32 SkHwtRead(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC Ioc)    /* IoContext */
-{
-       SK_U32  TRead ;
-       SK_U32  IStatus ;
-
-       if (pAC->Hwt.TActive) {
-               SkHwtStop(pAC,Ioc) ;
-
-               SK_IN32(Ioc, B2_TI_VAL, &TRead);
-               TRead /= SK_HWT_FAC;
-
-               SK_IN32(Ioc, B0_ISRC, &IStatus);
-
-               /* Check if timer expired (or wraparound). */
-               if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) {
-                       SkHwtStop(pAC,Ioc) ;
-                       pAC->Hwt.TStop = pAC->Hwt.TStart ;
-               } else {
-                       pAC->Hwt.TStop = pAC->Hwt.TStart - TRead ;
-               }
-       }
-       return (pAC->Hwt.TStop) ;
-}
-
-/*
- * interrupt source= timer
- */
-void   SkHwtIsr(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC Ioc)    /* IoContext */
-{
-       SkHwtStop(pAC,Ioc);
-       pAC->Hwt.TStop = pAC->Hwt.TStart;
-       SkTimerDone(pAC,Ioc) ;
-}
-
-#endif /* CONFIG_SK98 */
-
-/* End of file */
diff --git a/drivers/sk98lin/skgeinit.c b/drivers/sk98lin/skgeinit.c
deleted file mode 100644 (file)
index a18dc0a..0000000
+++ /dev/null
@@ -1,2372 +0,0 @@
-/******************************************************************************
- *
- * Name:       skgeinit.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.85 $
- * Date:       $Date: 2003/02/05 15:30:33 $
- * Purpose:    Contains functions to initialize the GE HW
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skgeinit.c,v $
- *     Revision 1.85  2003/02/05 15:30:33  rschmidt
- *     Corrected setting of GIHstClkFact (Host Clock Factor) and
- *     GIPollTimerVal (Descr. Poll Timer Init Value) for YUKON.
- *     Editorial changes.
- *
- *     Revision 1.84  2003/01/28 09:57:25  rschmidt
- *     Added detection of YUKON-Lite Rev. A0 (stored in GIYukonLite).
- *     Disabled Rx GMAC FIFO Flush for YUKON-Lite Rev. A0.
- *     Added support for CLK_RUN (YUKON-Lite).
- *     Added additional check of PME from D3cold for setting GIVauxAvail.
- *     Editorial changes.
- *
- *     Revision 1.83  2002/12/17 16:15:41  rschmidt
- *     Added default setting of PhyType (Copper) for YUKON.
- *     Added define around check for HW self test results.
- *     Editorial changes.
- *
- *     Revision 1.82  2002/12/05 13:40:21  rschmidt
- *     Added setting of Rx GMAC FIFO Flush Mask register.
- *     Corrected PhyType with new define SK_PHY_MARV_FIBER when
- *     YUKON Fiber board was found.
- *     Editorial changes.
- *
- *     Revision 1.81  2002/11/15 12:48:35  rschmidt
- *     Replaced message SKERR_HWI_E018 with SKERR_HWI_E024 for Rx queue error
- *     in SkGeStopPort().
- *     Added init for pAC->GIni.GIGenesis with SK_FALSE in YUKON-branch.
- *     Editorial changes.
- *
- *     Revision 1.80  2002/11/12 17:28:30  rschmidt
- *     Initialized GIPciSlot64 and GIPciClock66 in SkGeInit1().
- *     Reduced PCI FIFO watermarks for 32bit/33MHz bus in SkGeInitBmu().
- *     Editorial changes.
- *
- *     Revision 1.79  2002/10/21 09:31:02  mkarl
- *     Changed SkGeInitAssignRamToQueues(), removed call to
- *     SkGeInitAssignRamToQueues in SkGeInit1 and fixed compiler warning in
- *     SkGeInit1.
- *
- *     Revision 1.78  2002/10/16 15:55:07  mkarl
- *     Fixed a bug in SkGeInitAssignRamToQueues.
- *
- *     Revision 1.77  2002/10/14 15:07:22  rschmidt
- *     Corrected timeout handling for Rx queue in SkGeStopPort() (#10748)
- *     Editorial changes.
- *
- *     Revision 1.76  2002/10/11 09:24:38  mkarl
- *     Added check for HW self test results.
- *
- *     Revision 1.75  2002/10/09 16:56:44  mkarl
- *     Now call SkGeInitAssignRamToQueues() in Init Level 1 in order to assign
- *     the adapter memory to the queues. This default assignment is not suitable
- *     for dual net mode.
- *
- *     Revision 1.74  2002/09/12 08:45:06  rwahl
- *     Set defaults for PMSCap, PLinkSpeed & PLinkSpeedCap dependent on PHY.
- *
- *     Revision 1.73  2002/08/16 15:19:45  rschmidt
- *     Corrected check for Tx queues in SkGeCheckQSize().
- *     Added init for new entry GIGenesis and GICopperType
- *     Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis.
- *     Replaced wrong 1st para pAC with IoC in SK_IN/OUT macros.
- *
- *     Revision 1.72  2002/08/12 13:38:55  rschmidt
- *     Added check if VAUX is available (stored in GIVauxAvail)
- *     Initialized PLinkSpeedCap in Port struct with SK_LSPEED_CAP_1000MBPS
- *     Editorial changes.
- *
- *     Revision 1.71  2002/08/08 16:32:58  rschmidt
- *     Added check for Tx queues in SkGeCheckQSize().
- *     Added start of Time Stamp Timer (YUKON) in SkGeInit2().
- *     Editorial changes.
- *
- *     Revision 1.70  2002/07/23 16:04:26  rschmidt
- *     Added init for GIWolOffs (HW-Bug in YUKON 1st rev.)
- *     Minor changes
- *
- *     Revision 1.69  2002/07/17 17:07:08  rwahl
- *     - SkGeInit1(): fixed PHY type debug output; corrected init of GIFunc
- *       table & GIMacType.
- *     - Editorial changes.
- *
- *     Revision 1.68  2002/07/15 18:38:31  rwahl
- *     Added initialization for MAC type dependent function table.
- *
- *     Revision 1.67  2002/07/15 15:45:39  rschmidt
- *     Added Tx Store & Forward for YUKON (GMAC Tx FIFO is only 1 kB)
- *     Replaced SK_PHY_MARV by SK_PHY_MARV_COPPER
- *     Editorial changes
- *
- *     Revision 1.66  2002/06/10 09:35:08  rschmidt
- *     Replaced C++ comments (//)
- *     Editorial changes
- *
- *     Revision 1.65  2002/06/05 08:33:37  rschmidt
- *     Changed GIRamSize and Reset sequence for YUKON.
- *     SkMacInit() replaced by SkXmInitMac() resp. SkGmInitMac()
- *
- *     Revision 1.64  2002/04/25 13:03:20  rschmidt
- *     Changes for handling YUKON.
- *     Removed reference to xmac_ii.h (not necessary).
- *     Moved all defines into header file.
- *     Replaced all SkXm...() functions with SkMac...() to handle also
- *     YUKON's GMAC.
- *     Added handling for GMAC FIFO in SkGeInitMacFifo(), SkGeStopPort().
- *     Removed 'goto'-directive from SkGeCfgSync(), SkGeCheckQSize().
- *     Replaced all XMAC-access macros by functions: SkMacRxTxDisable(),
- *     SkMacFlushTxFifo().
- *     Optimized timeout handling in SkGeStopPort().
- *     Initialized PLinkSpeed in Port struct with SK_LSPEED_AUTO.
- *     Release of GMAC Link Control reset in SkGeInit1().
- *     Initialized GIChipId and GIChipRev in GE Init structure.
- *     Added GIRamSize and PhyType values for YUKON.
- *     Removed use of PRxCmd to setup XMAC.
- *     Moved setting of XM_RX_DIS_CEXT to SkXmInitMac().
- *     Use of SkGeXmitLED() only for GENESIS.
- *     Changes for V-CPU support.
- *     Editorial changes.
- *
- *     Revision 1.63  2001/04/05 11:02:09  rassmann
- *     Stop Port check of the STOP bit did not take 2/18 sec as wanted.
- *
- *     Revision 1.62  2001/02/07 07:54:21  rassmann
- *     Corrected copyright.
- *
- *     Revision 1.61  2001/01/31 15:31:40  gklug
- *     fix: problem with autosensing an SR8800 switch
- *
- *     Revision 1.60  2000/10/18 12:22:21  cgoos
- *     Added workaround for half duplex hangup.
- *
- *     Revision 1.59  2000/10/10 11:22:06  gklug
- *     add: in manual half duplex mode ignore carrier extension errors
- *
- *     Revision 1.58  2000/10/02 14:10:27  rassmann
- *     Reading BCOM PHY after releasing reset until it returns a valid value.
- *
- *     Revision 1.57  2000/08/03 14:55:28  rassmann
- *     Waiting for I2C to be ready before de-initializing adapter
- *     (prevents sensors from hanging up).
- *
- *     Revision 1.56  2000/07/27 12:16:48  gklug
- *     fix: Stop Port check of the STOP bit does now take 2/18 sec as wanted
- *
- *     Revision 1.55  1999/11/22 13:32:26  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.54  1999/10/26 07:32:54  malthoff
- *     Initialize PHWLinkUp with SK_FALSE. Required for Diagnostics.
- *
- *     Revision 1.53  1999/08/12 19:13:50  malthoff
- *     Fix for 1000BT. Do not owerwrite XM_MMU_CMD when
- *     disabling receiver and transmitter. Other bits
- *     may be lost.
- *
- *     Revision 1.52  1999/07/01 09:29:54  gklug
- *     fix: DoInitRamQueue needs pAC
- *
- *     Revision 1.51  1999/07/01 08:42:21  gklug
- *     chg: use Store & forward for RAM buffer when Jumbos are used
- *
- *     Revision 1.50  1999/05/27 13:19:38  cgoos
- *     Added Tx PCI watermark initialization.
- *     Removed Tx RAM queue Store & Forward setting.
- *
- *     Revision 1.49  1999/05/20 14:32:45  malthoff
- *     SkGeLinkLED() is completly removed now.
- *
- *     Revision 1.48  1999/05/19 07:28:24  cgoos
- *     SkGeLinkLED no more available for drivers.
- *     Changes for 1000Base-T.
- *
- *     Revision 1.47  1999/04/08 13:57:45  gklug
- *     add: Init of new port struct fiels PLinkResCt
- *     chg: StopPort Timer check
- *
- *     Revision 1.46  1999/03/25 07:42:15  malthoff
- *     SkGeStopPort(): Add workaround for cache incoherency.
- *                     Create error log entry, disable port, and
- *                     exit loop if it does not terminate.
- *     Add XM_RX_LENERR_OK to the default value for the
- *     XMAC receive command register.
- *
- *     Revision 1.45  1999/03/12 16:24:47  malthoff
- *     Remove PPollRxD and PPollTxD.
- *     Add check for GIPollTimerVal.
- *
- *     Revision 1.44  1999/03/12 13:40:23  malthoff
- *     Fix: SkGeXmitLED(), SK_LED_TST mode does not work.
- *     Add: Jumbo frame support.
- *     Chg: Resolution of parameter IntTime in SkGeCfgSync().
- *
- *     Revision 1.43  1999/02/09 10:29:46  malthoff
- *     Bugfix: The previous modification again also for the second location.
- *
- *     Revision 1.42  1999/02/09 09:35:16  malthoff
- *     Bugfix: The bits '66 MHz Capable' and 'NEWCAP are reset while
- *             clearing the error bits in the PCI status register.
- *
- *     Revision 1.41  1999/01/18 13:07:02  malthoff
- *     Bugfix: Do not use CFG cycles after during Init- or Runtime, because
- *             they may not be available after Boottime.
- *
- *     Revision 1.40  1999/01/11 12:40:49  malthoff
- *     Bug fix: PCI_STATUS: clearing error bits sets the UDF bit.
- *
- *     Revision 1.39  1998/12/11 15:17:33  gklug
- *     chg: Init LipaAutoNeg with Unknown
- *
- *     Revision 1.38  1998/12/10 11:02:57  malthoff
- *     Disable Error Log Message when calling SkGeInit(level 2)
- *     more than once.
- *
- *     Revision 1.37  1998/12/07 12:18:25  gklug
- *     add: refinement of autosense mode: take into account the autoneg cap of LiPa
- *
- *     Revision 1.36  1998/12/07 07:10:39  gklug
- *     fix: init values of LinkBroken/ Capabilities for management
- *
- *     Revision 1.35  1998/12/02 10:56:20  gklug
- *     fix: do NOT init LoinkSync Counter.
- *
- *     Revision 1.34  1998/12/01 10:53:21  gklug
- *     add: init of additional Counters for workaround
- *
- *     Revision 1.33  1998/12/01 10:00:49  gklug
- *     add: init PIsave var in Port struct
- *
- *     Revision 1.32  1998/11/26 14:50:40  gklug
- *     chg: Default is autosensing with AUTOFULL mode
- *
- *     Revision 1.31  1998/11/25 15:36:16  gklug
- *     fix: do NOT stop LED Timer when port should be stopped
- *
- *     Revision 1.30  1998/11/24 13:15:28  gklug
- *     add: Init PCkeckPar struct member
- *
- *     Revision 1.29  1998/11/18 13:19:27  malthoff
- *     Disable packet arbiter timeouts on receive side.
- *     Use maximum timeout value for packet arbiter
- *     transmit timeouts.
- *     Add TestStopBit() function to handle stop RX/TX
- *     problem with active descriptor poll timers.
- *     Bug Fix: Descriptor Poll Timer not started, because
- *     GIPollTimerVal was initialized with 0.
- *
- *     Revision 1.28  1998/11/13 14:24:26  malthoff
- *     Bug Fix: SkGeStopPort() may hang if a Packet Arbiter Timout
- *     is pending or occurs while waiting for TX_STOP and RX_STOP.
- *     The PA timeout is cleared now while waiting for TX- or RX_STOP.
- *
- *     Revision 1.27  1998/11/02 11:04:36  malthoff
- *     fix the last fix
- *
- *     Revision 1.26  1998/11/02 10:37:03  malthoff
- *     Fix: SkGePollTxD() enables always the synchronounous poll timer.
- *
- *     Revision 1.25  1998/10/28 07:12:43  cgoos
- *     Fixed "LED_STOP" in SkGeLnkSyncCnt, "== SK_INIT_IO" in SkGeInit.
- *     Removed: Reset of RAM Interface in SkGeStopPort.
- *
- *     Revision 1.24  1998/10/27 08:13:12  malthoff
- *     Remove temporary code.
- *
- *     Revision 1.23  1998/10/26 07:45:03  malthoff
- *     Add Address Calculation Workaround: If the EPROM byte
- *     Id is 3, the address offset is 512 kB.
- *     Initialize default values for PLinkMode and PFlowCtrlMode.
- *
- *     Revision 1.22  1998/10/22 09:46:47  gklug
- *     fix SysKonnectFileId typo
- *
- *     Revision 1.21  1998/10/20 12:11:56  malthoff
- *     Don't dendy the Queue config if the size of the unused
- *     Rx qeueu is zero.
- *
- *     Revision 1.20  1998/10/19 07:27:58  malthoff
- *     SkGeInitRamIface() is public to be called by diagnostics.
- *
- *     Revision 1.19  1998/10/16 13:33:45  malthoff
- *     Fix: enabling descriptor polling is not allowed until
- *     the descriptor addresses are set. Descriptor polling
- *     must be handled by the driver.
- *
- *     Revision 1.18  1998/10/16 10:58:27  malthoff
- *     Remove temp. code for Diag prototype.
- *     Remove lint warning for dummy reads.
- *     Call SkGeLoadLnkSyncCnt() during SkGeInitPort().
- *
- *     Revision 1.17  1998/10/14 09:16:06  malthoff
- *     Change parameter LimCount and programming of
- *     the limit counter in SkGeCfgSync().
- *
- *     Revision 1.16  1998/10/13 09:21:16  malthoff
- *     Don't set XM_RX_SELF_RX in RxCmd Reg, because it's
- *     like a Loopback Mode in half duplex.
- *
- *     Revision 1.15  1998/10/09 06:47:40  malthoff
- *     SkGeInitMacArb(): set recovery counters init value
- *     to zero although this counters are not uesd.
- *     Bug fix in Rx Upper/Lower Pause Threshold calculation.
- *     Add XM_RX_SELF_RX to RxCmd.
- *
- *     Revision 1.14  1998/10/06 15:15:53  malthoff
- *     Make sure no pending IRQ is cleared in SkGeLoadLnkSyncCnt().
- *
- *     Revision 1.13  1998/10/06 14:09:36  malthoff
- *     Add SkGeLoadLnkSyncCnt(). Modify
- *     the 'port stopped' condition according
- *     to the current problem report.
- *
- *     Revision 1.12  1998/10/05 08:17:21  malthoff
- *     Add functions: SkGePollRxD(), SkGePollTxD(),
- *     DoCalcAddr(), SkGeCheckQSize(),
- *     DoInitRamQueue(), and SkGeCfgSync().
- *     Add coding for SkGeInitMacArb(), SkGeInitPktArb(),
- *     SkGeInitMacFifo(), SkGeInitRamBufs(),
- *     SkGeInitRamIface(), and SkGeInitBmu().
- *
- *     Revision 1.11  1998/09/29 08:26:29  malthoff
- *     bug fix: SkGeInit0() 'i' should be increment.
- *
- *     Revision 1.10  1998/09/28 13:19:01  malthoff
- *     Coding time: Save the done work.
- *     Modify SkGeLinkLED(), add SkGeXmitLED(),
- *     define SkGeCheckQSize(), SkGeInitMacArb(),
- *     SkGeInitPktArb(), SkGeInitMacFifo(),
- *     SkGeInitRamBufs(), SkGeInitRamIface(),
- *     and SkGeInitBmu(). Do coding for SkGeStopPort(),
- *     SkGeInit1(), SkGeInit2(), and SkGeInit3().
- *     Do coding for SkGeDinit() and SkGeInitPort().
- *
- *     Revision 1.9  1998/09/16 14:29:05  malthoff
- *     Some minor changes.
- *
- *     Revision 1.8  1998/09/11 05:29:14  gklug
- *     add: init state of a port
- *
- *     Revision 1.7  1998/09/04 09:26:25  malthoff
- *     Short temporary modification.
- *
- *     Revision 1.6  1998/09/04 08:27:59  malthoff
- *     Remark the do-while in StopPort() because it never ends
- *     without a GE adapter.
- *
- *     Revision 1.5  1998/09/03 14:05:45  malthoff
- *     Change comment for SkGeInitPort(). Do not
- *     repair the queue sizes if invalid.
- *
- *     Revision 1.4  1998/09/03 10:03:19  malthoff
- *     Implement the new interface according to the
- *     reviewed interface specification.
- *
- *     Revision 1.3  1998/08/19 09:11:25  gklug
- *     fix: struct are removed from c-source (see CCC)
- *
- *     Revision 1.2  1998/07/28 12:33:58  malthoff
- *     Add 'IoC' parameter in function declaration and SK IO macros.
- *
- *     Revision 1.1  1998/07/23 09:48:57  malthoff
- *     Creation. First dummy 'C' file.
- *     SkGeInit(Level 0) is card_start for GE.
- *     SkGeDeInit() is card_stop for GE.
- *
- *
- ******************************************************************************/
-
-#include <config.h>
-
-#ifdef CONFIG_SK98
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-
-/* global variables ***********************************************************/
-
-/* local variables ************************************************************/
-
-static const char SysKonnectFileId[] =
-       "@(#)$Id: skgeinit.c,v 1.85 2003/02/05 15:30:33 rschmidt Exp $ (C) SK ";
-
-struct s_QOffTab {
-       int     RxQOff;         /* Receive Queue Address Offset */
-       int     XsQOff;         /* Sync Tx Queue Address Offset */
-       int     XaQOff;         /* Async Tx Queue Address Offset */
-};
-static struct s_QOffTab QOffTab[] = {
-       {Q_R1, Q_XS1, Q_XA1}, {Q_R2, Q_XS2, Q_XA2}
-};
-
-
-/******************************************************************************
- *
- *     SkGePollRxD() - Enable / Disable Descriptor Polling of RxD Ring
- *
- * Description:
- *     Enable or disable the descriptor polling of the receive descriptor
- *     ring (RxD) for port 'Port'.
- *     The new configuration is *not* saved over any SkGeStopPort() and
- *     SkGeInitPort() calls.
- *
- * Returns:
- *     nothing
- */
-void SkGePollRxD(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_BOOL PollRxD)       /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */
-{
-       SK_GEPORT *pPrt;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), (PollRxD) ?
-               CSR_ENA_POL : CSR_DIS_POL);
-}      /* SkGePollRxD */
-
-
-/******************************************************************************
- *
- *     SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings
- *
- * Description:
- *     Enable or disable the descriptor polling of the transmit descriptor
- *     ring(s) (TxD) for port 'Port'.
- *     The new configuration is *not* saved over any SkGeStopPort() and
- *     SkGeInitPort() calls.
- *
- * Returns:
- *     nothing
- */
-void SkGePollTxD(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_BOOL PollTxD)       /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */
-{
-       SK_GEPORT *pPrt;
-       SK_U32  DWord;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       DWord = (PollTxD) ? CSR_ENA_POL : CSR_DIS_POL;
-
-       if (pPrt->PXSQSize != 0) {
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord);
-       }
-
-       if (pPrt->PXAQSize != 0) {
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord);
-       }
-}      /* SkGePollTxD */
-
-
-/******************************************************************************
- *
- *     SkGeYellowLED() - Switch the yellow LED on or off.
- *
- * Description:
- *     Switch the yellow LED on or off.
- *
- * Note:
- *     This function may be called any time after SkGeInit(Level 1).
- *
- * Returns:
- *     nothing
- */
-void SkGeYellowLED(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            State)          /* yellow LED state, 0 = OFF, 0 != ON */
-{
-       if (State == 0) {
-               /* Switch yellow LED OFF */
-               SK_OUT8(IoC, B0_LED, LED_STAT_OFF);
-       }
-       else {
-               /* Switch yellow LED ON */
-               SK_OUT8(IoC, B0_LED, LED_STAT_ON);
-       }
-}      /* SkGeYellowLED */
-
-
-/******************************************************************************
- *
- *     SkGeXmitLED() - Modify the Operational Mode of a transmission LED.
- *
- * Description:
- *     The Rx or Tx LED which is specified by 'Led' will be
- *     enabled, disabled or switched on in test mode.
- *
- * Note:
- *     'Led' must contain the address offset of the LEDs INI register.
- *
- * Usage:
- *     SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
- *
- * Returns:
- *     nothing
- */
-void SkGeXmitLED(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Led,            /* offset to the LED Init Value register */
-int            Mode)           /* Mode may be SK_LED_DIS, SK_LED_ENA, SK_LED_TST */
-{
-       SK_U32  LedIni;
-
-       switch (Mode) {
-       case SK_LED_ENA:
-               LedIni = SK_XMIT_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100;
-               SK_OUT32(IoC, Led + XMIT_LED_INI, LedIni);
-               SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
-               break;
-       case SK_LED_TST:
-               SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_ON);
-               SK_OUT32(IoC, Led + XMIT_LED_CNT, 100);
-               SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
-               break;
-       case SK_LED_DIS:
-       default:
-               /*
-                * Do NOT stop the LED Timer here. The LED might be
-                * in on state. But it needs to go off.
-                */
-               SK_OUT32(IoC, Led + XMIT_LED_CNT, 0);
-               SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_OFF);
-               break;
-       }
-
-       /*
-        * 1000BT: The Transmit LED is driven by the PHY.
-        * But the default LED configuration is used for
-        * Level One and Broadcom PHYs.
-        * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set.)
-        * (In this case it has to be added here. But we will see. XXX)
-        */
-}      /* SkGeXmitLED */
-
-
-/******************************************************************************
- *
- *     DoCalcAddr() - Calculates the start and the end address of a queue.
- *
- * Description:
- *     This function calculates the start and the end address of a queue.
- *  Afterwards the 'StartVal' is incremented to the next start position.
- *     If the port is already initialized the calculated values
- *     will be checked against the configured values and an
- *     error will be returned, if they are not equal.
- *     If the port is not initialized the values will be written to
- *     *StartAdr and *EndAddr.
- *
- * Returns:
- *     0:      success
- *     1:      configuration error
- */
-static int DoCalcAddr(
-SK_AC          *pAC,                   /* adapter context */
-SK_GEPORT      *pPrt,                  /* port index */
-int                    QuSize,                 /* size of the queue to configure in kB */
-SK_U32         *StartVal,              /* start value for address calculation */
-SK_U32         *QuStartAddr,   /* start addr to calculate */
-SK_U32         *QuEndAddr)             /* end address to calculate */
-{
-       SK_U32  EndVal;
-       SK_U32  NextStart;
-       int             Rtv;
-
-       Rtv = 0;
-       if (QuSize == 0) {
-               EndVal = *StartVal;
-               NextStart = EndVal;
-       }
-       else {
-               EndVal = *StartVal + ((SK_U32)QuSize * 1024) - 1;
-               NextStart = EndVal + 1;
-       }
-
-       if (pPrt->PState >= SK_PRT_INIT) {
-               if (*StartVal != *QuStartAddr || EndVal != *QuEndAddr) {
-                       Rtv = 1;
-               }
-       }
-       else {
-               *QuStartAddr = *StartVal;
-               *QuEndAddr = EndVal;
-       }
-
-       *StartVal = NextStart;
-       return(Rtv);
-}      /* DoCalcAddr */
-
-/******************************************************************************
- *
- *     SkGeInitAssignRamToQueues() - allocate default queue sizes
- *
- * Description:
- *     This function assigns the memory to the different queues and ports.
- *     When DualNet is set to SK_TRUE all ports get the same amount of memory.
- *  Otherwise the first port gets most of the memory and all the
- *     other ports just the required minimum.
- *     This function can only be called when pAC->GIni.GIRamSize and
- *     pAC->GIni.GIMacsFound have been initialized, usually this happens
- *     at init level 1
- *
- * Returns:
- *     0 - ok
- *     1 - invalid input values
- *     2 - not enough memory
- */
-
-int SkGeInitAssignRamToQueues(
-SK_AC  *pAC,                   /* Adapter context */
-int            ActivePort,             /* Active Port in RLMT mode */
-SK_BOOL        DualNet)                /* adapter context */
-{
-       int     i;
-       int     UsedKilobytes;                  /* memory already assigned */
-       int     ActivePortKilobytes;    /* memory available for active port */
-       SK_GEPORT *pGePort;
-
-       UsedKilobytes = 0;
-
-       if (ActivePort >= pAC->GIni.GIMacsFound) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
-                       ("SkGeInitAssignRamToQueues: ActivePort (%d) invalid\n",
-                       ActivePort));
-               return(1);
-       }
-       if (((pAC->GIni.GIMacsFound * (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE)) +
-               ((RAM_QUOTA_SYNC == 0) ? 0 : SK_MIN_TXQ_SIZE)) > pAC->GIni.GIRamSize) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
-                       ("SkGeInitAssignRamToQueues: Not enough memory (%d)\n",
-                        pAC->GIni.GIRamSize));
-               return(2);
-       }
-
-
-       if (DualNet) {
-               /* every port gets the same amount of memory */
-               ActivePortKilobytes = pAC->GIni.GIRamSize / pAC->GIni.GIMacsFound;
-               for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-
-                       pGePort = &pAC->GIni.GP[i];
-
-                       /* take away the minimum memory for active queues */
-                       ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
-
-                       /* receive queue gets the minimum + 80% of the rest */
-                       pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((
-                               ActivePortKilobytes * (unsigned long) RAM_QUOTA_RX) / 100))
-                               + SK_MIN_RXQ_SIZE;
-
-                       ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
-
-                       /* synchronous transmit queue */
-                       pGePort->PXSQSize = 0;
-
-                       /* asynchronous transmit queue */
-                       pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes +
-                               SK_MIN_TXQ_SIZE);
-               }
-       }
-       else {
-               /* Rlmt Mode or single link adapter */
-
-               /* Set standby queue size defaults for all standby ports */
-               for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-
-                       if (i != ActivePort) {
-                               pGePort = &pAC->GIni.GP[i];
-
-                               pGePort->PRxQSize = SK_MIN_RXQ_SIZE;
-                               pGePort->PXAQSize = SK_MIN_TXQ_SIZE;
-                               pGePort->PXSQSize = 0;
-
-                               /* Count used RAM */
-                               UsedKilobytes += pGePort->PRxQSize + pGePort->PXAQSize;
-                       }
-               }
-               /* what's left? */
-               ActivePortKilobytes = pAC->GIni.GIRamSize - UsedKilobytes;
-
-               /* assign it to the active port */
-               /* first take away the minimum memory */
-               ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
-               pGePort = &pAC->GIni.GP[ActivePort];
-
-               /* receive queue get's the minimum + 80% of the rest */
-               pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((ActivePortKilobytes *
-                       (unsigned long) RAM_QUOTA_RX) / 100)) + SK_MIN_RXQ_SIZE;
-
-               ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
-
-               /* synchronous transmit queue */
-               pGePort->PXSQSize = 0;
-
-               /* asynchronous transmit queue */
-               pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes) +
-                       SK_MIN_TXQ_SIZE;
-       }
-#ifdef VCPU
-       VCPUprintf(0, "PRxQSize=%u, PXSQSize=%u, PXAQSize=%u\n",
-               pGePort->PRxQSize, pGePort->PXSQSize, pGePort->PXAQSize);
-#endif /* VCPU */
-
-       return(0);
-}      /* SkGeInitAssignRamToQueues */
-
-/******************************************************************************
- *
- *     SkGeCheckQSize() - Checks the Adapters Queue Size Configuration
- *
- * Description:
- *     This function verifies the Queue Size Configuration specified
- *     in the variables PRxQSize, PXSQSize, and PXAQSize of all
- *     used ports.
- *     This requirements must be fullfilled to have a valid configuration:
- *             - The size of all queues must not exceed GIRamSize.
- *             - The queue sizes must be specified in units of 8 kB.
- *             - The size of Rx queues of available ports must not be
- *               smaller than 16 kB.
- *             - The size of at least one Tx queue (synch. or asynch.)
- *        of available ports must not be smaller than 16 kB
- *        when Jumbo Frames are used.
- *             - The RAM start and end addresses must not be changed
- *               for ports which are already initialized.
- *     Furthermore SkGeCheckQSize() defines the Start and End Addresses
- *  of all ports and stores them into the HWAC port    structure.
- *
- * Returns:
- *     0:      Queue Size Configuration valid
- *     1:      Queue Size Configuration invalid
- */
-static int SkGeCheckQSize(
-SK_AC   *pAC,          /* adapter context */
-int             Port)          /* port index */
-{
-       SK_GEPORT *pPrt;
-       int     UsedMem;        /* total memory used (max. found ports) */
-       int     i;
-       int     Rtv;
-       int     Rtv2;
-       SK_U32  StartAddr;
-
-       UsedMem = 0;
-       Rtv = 0;
-       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-               pPrt = &pAC->GIni.GP[i];
-
-               if ((pPrt->PRxQSize & QZ_UNITS) != 0 ||
-                       (pPrt->PXSQSize & QZ_UNITS) != 0 ||
-                       (pPrt->PXAQSize & QZ_UNITS) != 0) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
-                       return(1);
-               }
-
-               if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) {
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG);
-                       return(1);
-               }
-
-               /*
-                * the size of at least one Tx queue (synch. or asynch.) has to be > 0.
-                * if Jumbo Frames are used, this size has to be >= 16 kB.
-                */
-               if ((i == Port && pPrt->PXSQSize == 0 && pPrt->PXAQSize == 0) ||
-                       (pAC->GIni.GIPortUsage == SK_JUMBO_LINK &&
-           ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) ||
-                        (pPrt->PXAQSize > 0 && pPrt->PXAQSize < SK_MIN_TXQ_SIZE)))) {
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E023, SKERR_HWI_E023MSG);
-                               return(1);
-               }
-
-               UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize;
-       }
-
-       if (UsedMem > pAC->GIni.GIRamSize) {
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
-               return(1);
-       }
-
-       /* Now start address calculation */
-       StartAddr = pAC->GIni.GIRamOffs;
-       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-               pPrt = &pAC->GIni.GP[i];
-
-               /* Calculate/Check values for the receive queue */
-               Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PRxQSize, &StartAddr,
-                       &pPrt->PRxQRamStart, &pPrt->PRxQRamEnd);
-               Rtv |= Rtv2;
-
-               /* Calculate/Check values for the synchronous Tx queue */
-               Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXSQSize, &StartAddr,
-                       &pPrt->PXsQRamStart, &pPrt->PXsQRamEnd);
-               Rtv |= Rtv2;
-
-               /* Calculate/Check values for the asynchronous Tx queue */
-               Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXAQSize, &StartAddr,
-                       &pPrt->PXaQRamStart, &pPrt->PXaQRamEnd);
-               Rtv |= Rtv2;
-
-               if (Rtv) {
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E013, SKERR_HWI_E013MSG);
-                       return(1);
-               }
-       }
-
-       return(0);
-}      /* SkGeCheckQSize */
-
-
-/******************************************************************************
- *
- *     SkGeInitMacArb() - Initialize the MAC Arbiter
- *
- * Description:
- *     This function initializes the MAC Arbiter.
- *     It must not be called if there is still an
- *     initialized or active port.
- *
- * Returns:
- *     nothing
- */
-static void SkGeInitMacArb(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC)            /* IO context */
-{
-       /* release local reset */
-       SK_OUT16(IoC, B3_MA_TO_CTRL, MA_RST_CLR);
-
-       /* configure timeout values */
-       SK_OUT8(IoC, B3_MA_TOINI_RX1, SK_MAC_TO_53);
-       SK_OUT8(IoC, B3_MA_TOINI_RX2, SK_MAC_TO_53);
-       SK_OUT8(IoC, B3_MA_TOINI_TX1, SK_MAC_TO_53);
-       SK_OUT8(IoC, B3_MA_TOINI_TX2, SK_MAC_TO_53);
-
-       SK_OUT8(IoC, B3_MA_RCINI_RX1, 0);
-       SK_OUT8(IoC, B3_MA_RCINI_RX2, 0);
-       SK_OUT8(IoC, B3_MA_RCINI_TX1, 0);
-       SK_OUT8(IoC, B3_MA_RCINI_TX2, 0);
-
-       /* recovery values are needed for XMAC II Rev. B2 only */
-       /* Fast Output Enable Mode was intended to use with Rev. B2, but now? */
-
-       /*
-        * There is no start or enable button to push, therefore
-        * the MAC arbiter is configured and enabled now.
-        */
-}      /* SkGeInitMacArb */
-
-
-/******************************************************************************
- *
- *     SkGeInitPktArb() - Initialize the Packet Arbiter
- *
- * Description:
- *     This function initializes the Packet Arbiter.
- *     It must not be called if there is still an
- *     initialized or active port.
- *
- * Returns:
- *     nothing
- */
-static void SkGeInitPktArb(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC)            /* IO context */
-{
-       /* release local reset */
-       SK_OUT16(IoC, B3_PA_CTRL, PA_RST_CLR);
-
-       /* configure timeout values */
-       SK_OUT16(IoC, B3_PA_TOINI_RX1, SK_PKT_TO_MAX);
-       SK_OUT16(IoC, B3_PA_TOINI_RX2, SK_PKT_TO_MAX);
-       SK_OUT16(IoC, B3_PA_TOINI_TX1, SK_PKT_TO_MAX);
-       SK_OUT16(IoC, B3_PA_TOINI_TX2, SK_PKT_TO_MAX);
-
-       /*
-        * enable timeout timers if jumbo frames not used
-        * NOTE: the packet arbiter timeout interrupt is needed for
-        * half duplex hangup workaround
-        */
-       if (pAC->GIni.GIPortUsage != SK_JUMBO_LINK) {
-               if (pAC->GIni.GIMacsFound == 1) {
-                       SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1);
-               }
-               else {
-                       SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1 | PA_ENA_TO_TX2);
-               }
-       }
-}      /* SkGeInitPktArb */
-
-
-/******************************************************************************
- *
- *     SkGeInitMacFifo() - Initialize the MAC FIFOs
- *
- * Description:
- *     Initialize all MAC FIFOs of the specified port
- *
- * Returns:
- *     nothing
- */
-static void SkGeInitMacFifo(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_U16  Word;
-#ifdef VCPU
-       SK_U32  DWord;
-#endif /* VCPU */
-       /*
-        * For each FIFO:
-        *      - release local reset
-        *      - use default value for MAC FIFO size
-        *      - setup defaults for the control register
-        *      - enable the FIFO
-        */
-
-       Word = GMF_RX_CTRL_DEF;
-
-       if (pAC->GIni.GIGenesis) {
-               /* Configure Rx MAC FIFO */
-               SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR);
-               SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF);
-               SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD);
-
-               /* Configure Tx MAC FIFO */
-               SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR);
-               SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
-               SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD);
-
-               /* Enable frame flushing if jumbo frames used */
-               if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
-                       SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH);
-               }
-       }
-       else {
-               /* set Rx GMAC FIFO Flush Mask */
-               SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK);
-
-               if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipId == CHIP_ID_YUKON) {
-
-                       Word &= ~GMF_RX_F_FL_ON;
-               }
-
-               /* Configure Rx MAC FIFO */
-               SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
-               SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), Word);
-
-               /* set Rx GMAC FIFO Flush Threshold (default: 0x0a -> 56 bytes) */
-               SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
-
-               /* Configure Tx MAC FIFO */
-               SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
-               SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U16)GMF_TX_CTRL_DEF);
-
-#ifdef VCPU
-               SK_IN32(IoC, MR_ADDR(Port, RX_GMF_AF_THR), &DWord);
-               SK_IN32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), &DWord);
-#endif /* VCPU */
-
-               /* set Tx GMAC FIFO Almost Empty Threshold */
-/*             SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), 0); */
-       }
-}      /* SkGeInitMacFifo */
-
-
-/******************************************************************************
- *
- *     SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting
- *
- * Description:
- *     This function starts the Link Sync Counter of the specified
- *     port and enables the generation of an Link Sync IRQ.
- *     The Link Sync Counter may be used to detect an active link,
- *     if autonegotiation is not used.
- *
- * Note:
- *     o To ensure receiving the Link Sync Event the LinkSyncCounter
- *       should be initialized BEFORE clearing the XMAC's reset!
- *     o Enable IS_LNK_SYNC_M1 and IS_LNK_SYNC_M2 after calling this
- *       function.
- *
- * Returns:
- *     nothing
- */
-void SkGeLoadLnkSyncCnt(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_U32 CntVal)         /* Counter value */
-{
-       SK_U32  OrgIMsk;
-       SK_U32  NewIMsk;
-       SK_U32  ISrc;
-       SK_BOOL IrqPend;
-
-       /* stop counter */
-       SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_STOP);
-
-       /*
-        * ASIC problem:
-        * Each time starting the Link Sync Counter an IRQ is generated
-        * by the adapter. See problem report entry from 21.07.98
-        *
-        * Workaround:  Disable Link Sync IRQ and clear the unexpeced IRQ
-        *              if no IRQ is already pending.
-        */
-       IrqPend = SK_FALSE;
-       SK_IN32(IoC, B0_ISRC, &ISrc);
-       SK_IN32(IoC, B0_IMSK, &OrgIMsk);
-       if (Port == MAC_1) {
-               NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M1;
-               if ((ISrc & IS_LNK_SYNC_M1) != 0) {
-                       IrqPend = SK_TRUE;
-               }
-       }
-       else {
-               NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M2;
-               if ((ISrc & IS_LNK_SYNC_M2) != 0) {
-                       IrqPend = SK_TRUE;
-               }
-       }
-       if (!IrqPend) {
-               SK_OUT32(IoC, B0_IMSK, NewIMsk);
-       }
-
-       /* load counter */
-       SK_OUT32(IoC, MR_ADDR(Port, LNK_SYNC_INI), CntVal);
-
-       /* start counter */
-       SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_START);
-
-       if (!IrqPend) {
-               /* clear the unexpected IRQ, and restore the interrupt mask */
-               SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_CLR_IRQ);
-               SK_OUT32(IoC, B0_IMSK, OrgIMsk);
-       }
-}      /* SkGeLoadLnkSyncCnt*/
-
-
-/******************************************************************************
- *
- *     SkGeCfgSync() - Configure synchronous bandwidth for this port.
- *
- * Description:
- *     This function may be used to configure synchronous bandwidth
- *     to the specified port. This may be done any time after
- *     initializing the port. The configuration values are NOT saved
- *     in the HWAC port structure and will be overwritten any
- *     time when stopping and starting the port.
- *     Any values for the synchronous configuration will be ignored
- *     if the size of the synchronous queue is zero!
- *
- *     The default configuration for the synchronous service is
- *     TXA_ENA_FSYNC. This means if the size of
- *     the synchronous queue is unequal zero but no specific
- *     synchronous bandwidth is configured, the synchronous queue
- *     will always have the 'unlimited' transmit priority!
- *
- *     This mode will be restored if the synchronous bandwidth is
- *     deallocated ('IntTime' = 0 and 'LimCount' = 0).
- *
- * Returns:
- *     0:      success
- *     1:      parameter configuration error
- *     2:      try to configure quality of service although no
- *             synchronous queue is configured
- */
-int SkGeCfgSync(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_U32 IntTime,        /* Interval Timer Value in units of 8ns */
-SK_U32 LimCount,       /* Number of bytes to transfer during IntTime */
-int            SyncMode)       /* Sync Mode: TXA_ENA_ALLOC | TXA_DIS_ALLOC | 0 */
-{
-       int Rtv;
-
-       Rtv = 0;
-
-       /* check the parameters */
-       if (LimCount > IntTime ||
-               (LimCount == 0 && IntTime != 0) ||
-               (LimCount != 0 && IntTime == 0)) {
-
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
-               return(1);
-       }
-
-       if (pAC->GIni.GP[Port].PXSQSize == 0) {
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG);
-               return(2);
-       }
-
-       /* calculate register values */
-       IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100;
-       LimCount = LimCount / 8;
-
-       if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) {
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
-               return(1);
-       }
-
-       /*
-        * - Enable 'Force Sync' to ensure the synchronous queue
-        *   has the priority while configuring the new values.
-        * - Also 'disable alloc' to ensure the settings complies
-        *   to the SyncMode parameter.
-        * - Disable 'Rate Control' to configure the new values.
-        * - write IntTime and LimCount
-        * - start 'Rate Control' and disable 'Force Sync'
-        *   if Interval Timer or Limit Counter not zero.
-        */
-       SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
-               TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
-
-       SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime);
-       SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount);
-
-       SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
-               (SK_U8)(SyncMode & (TXA_ENA_ALLOC | TXA_DIS_ALLOC)));
-
-       if (IntTime != 0 || LimCount != 0) {
-               SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_START_RC);
-       }
-
-       return(0);
-}      /* SkGeCfgSync */
-
-
-/******************************************************************************
- *
- *     DoInitRamQueue() - Initialize the RAM Buffer Address of a single Queue
- *
- * Desccription:
- *     If the queue is used, enable and initialize it.
- *     Make sure the queue is still reset, if it is not used.
- *
- * Returns:
- *     nothing
- */
-static void DoInitRamQueue(
-SK_AC  *pAC,                   /* adapter context */
-SK_IOC IoC,                    /* IO context */
-int            QuIoOffs,               /* Queue IO Address Offset */
-SK_U32 QuStartAddr,    /* Queue Start Address */
-SK_U32 QuEndAddr,              /* Queue End Address */
-int            QuType)                 /* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */
-{
-       SK_U32  RxUpThresVal;
-       SK_U32  RxLoThresVal;
-
-       if (QuStartAddr != QuEndAddr) {
-               /* calculate thresholds, assume we have a big Rx queue */
-               RxUpThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_ULPP) / 8;
-               RxLoThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_LLPP_B)/8;
-
-               /* build HW address format */
-               QuStartAddr = QuStartAddr / 8;
-               QuEndAddr = QuEndAddr / 8;
-
-               /* release local reset */
-               SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_CLR);
-
-               /* configure addresses */
-               SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_START), QuStartAddr);
-               SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_END), QuEndAddr);
-               SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_WP), QuStartAddr);
-               SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RP), QuStartAddr);
-
-               switch (QuType) {
-               case SK_RX_SRAM_Q:
-                       /* configure threshold for small Rx Queue */
-                       RxLoThresVal += (SK_RB_LLPP_B - SK_RB_LLPP_S) / 8;
-
-                       /* continue with SK_RX_BRAM_Q */
-               case SK_RX_BRAM_Q:
-                       /* write threshold for Rx Queue */
-
-                       SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal);
-                       SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_LTPP), RxLoThresVal);
-
-                       /* the high priority threshold not used */
-                       break;
-               case SK_TX_RAM_Q:
-                       /*
-                        * Do NOT use Store & Forward under normal operation due to
-                        * performance optimization (GENESIS only).
-                        * But if Jumbo Frames are configured (XMAC Tx FIFO is only 4 kB)
-                        * or YUKON is used ((GMAC Tx FIFO is only 1 kB)
-                        * we NEED Store & Forward of the RAM buffer.
-                        */
-                       if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK ||
-                               !pAC->GIni.GIGenesis) {
-                               /* enable Store & Forward Mode for the Tx Side */
-                               SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD);
-                       }
-                       break;
-               }
-
-               /* set queue operational */
-               SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_OP_MD);
-       }
-       else {
-               /* ensure the queue is still disabled */
-               SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_SET);
-       }
-}      /* DoInitRamQueue */
-
-
-/******************************************************************************
- *
- *     SkGeInitRamBufs() - Initialize the RAM Buffer Queues
- *
- * Description:
- *     Initialize all RAM Buffer Queues of the specified port
- *
- * Returns:
- *     nothing
- */
-static void SkGeInitRamBufs(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT *pPrt;
-       int RxQType;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PRxQSize == SK_MIN_RXQ_SIZE) {
-               RxQType = SK_RX_SRAM_Q;         /* small Rx Queue */
-       }
-       else {
-               RxQType = SK_RX_BRAM_Q;         /* big Rx Queue */
-       }
-
-       DoInitRamQueue(pAC, IoC, pPrt->PRxQOff, pPrt->PRxQRamStart,
-               pPrt->PRxQRamEnd, RxQType);
-
-       DoInitRamQueue(pAC, IoC, pPrt->PXsQOff, pPrt->PXsQRamStart,
-               pPrt->PXsQRamEnd, SK_TX_RAM_Q);
-
-       DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart,
-               pPrt->PXaQRamEnd, SK_TX_RAM_Q);
-
-}      /* SkGeInitRamBufs */
-
-
-/******************************************************************************
- *
- *     SkGeInitRamIface() - Initialize the RAM Interface
- *
- * Description:
- *     This function initializes the Adapters RAM Interface.
- *
- * Note:
- *     This function is used in the diagnostics.
- *
- * Returns:
- *     nothing
- */
-void SkGeInitRamIface(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC)            /* IO context */
-{
-       /* release local reset */
-       SK_OUT16(IoC, B3_RI_CTRL, RI_RST_CLR);
-
-       /* configure timeout values */
-       SK_OUT8(IoC, B3_RI_WTO_R1, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_WTO_XA1, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_WTO_XS1, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_RTO_R1, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_RTO_XA1, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_RTO_XS1, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_WTO_R2, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_WTO_XA2, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_WTO_XS2, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_RTO_R2, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_RTO_XA2, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_RTO_XS2, SK_RI_TO_53);
-
-}      /* SkGeInitRamIface */
-
-
-/******************************************************************************
- *
- *     SkGeInitBmu() - Initialize the BMU state machines
- *
- * Description:
- *     Initialize all BMU state machines of the specified port
- *
- * Returns:
- *     nothing
- */
-static void SkGeInitBmu(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U32          RxWm;
-       SK_U32          TxWm;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       RxWm = SK_BMU_RX_WM;
-       TxWm = SK_BMU_TX_WM;
-
-       if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) {
-               /* for better performance */
-               RxWm /= 2;
-               TxWm /= 2;
-       }
-
-       /* Rx Queue: Release all local resets and set the watermark */
-       SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET);
-       SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm);
-
-       /*
-        * Tx Queue: Release all local resets if the queue is used !
-        *              set watermark
-        */
-       if (pPrt->PXSQSize != 0) {
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET);
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm);
-       }
-
-       if (pPrt->PXAQSize != 0) {
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET);
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm);
-       }
-       /*
-        * Do NOT enable the descriptor poll timers here, because
-        * the descriptor addresses are not specified yet.
-        */
-}      /* SkGeInitBmu */
-
-
-/******************************************************************************
- *
- *     TestStopBit() - Test the stop bit of the queue
- *
- * Description:
- *     Stopping a queue is not as simple as it seems to be.
- *     If descriptor polling is enabled, it may happen
- *     that RX/TX stop is done and SV idle is NOT set.
- *     In this case we have to issue another stop command.
- *
- * Returns:
- *     The queues control status register
- */
-static SK_U32 TestStopBit(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO Context */
-int            QuIoOffs)       /* Queue IO Address Offset */
-{
-       SK_U32  QuCsr;  /* CSR contents */
-
-       SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
-
-       if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) {
-               /* Stop Descriptor overridden by start command */
-               SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP);
-
-               SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
-       }
-
-       return(QuCsr);
-}      /* TestStopBit */
-
-
-/******************************************************************************
- *
- *     SkGeStopPort() - Stop the Rx/Tx activity of the port 'Port'.
- *
- * Description:
- *     After calling this function the descriptor rings and Rx and Tx
- *     queues of this port may be reconfigured.
- *
- *     It is possible to stop the receive and transmit path separate or
- *     both together.
- *
- *     Dir =   SK_STOP_TX      Stops the transmit path only and resets the MAC.
- *                             The receive queue is still active and
- *                             the pending Rx frames may be still transferred
- *                             into the RxD.
- *             SK_STOP_RX      Stop the receive path. The tansmit path
- *                             has to be stopped once before.
- *             SK_STOP_ALL     SK_STOP_TX + SK_STOP_RX
- *
- *     RstMode = SK_SOFT_RST   Resets the MAC. The PHY is still alive.
- *                     SK_HARD_RST     Resets the MAC and the PHY.
- *
- * Example:
- *     1) A Link Down event was signaled for a port. Therefore the activity
- *     of this port should be stopped and a hardware reset should be issued
- *     to enable the workaround of XMAC errata #2. But the received frames
- *     should not be discarded.
- *             ...
- *             SkGeStopPort(pAC, IoC, Port, SK_STOP_TX, SK_HARD_RST);
- *             (transfer all pending Rx frames)
- *             SkGeStopPort(pAC, IoC, Port, SK_STOP_RX, SK_HARD_RST);
- *             ...
- *
- *     2) An event was issued which request the driver to switch
- *     the 'virtual active' link to an other already active port
- *     as soon as possible. The frames in the receive queue of this
- *     port may be lost. But the PHY must not be reset during this
- *     event.
- *             ...
- *             SkGeStopPort(pAC, IoC, Port, SK_STOP_ALL, SK_SOFT_RST);
- *             ...
- *
- * Extended Description:
- *     If SK_STOP_TX is set,
- *             o disable the MAC's receive and transmitter to prevent
- *               from sending incomplete frames
- *             o stop the port's transmit queues before terminating the
- *               BMUs to prevent from performing incomplete PCI cycles
- *               on the PCI bus
- *             - The network Rx and Tx activity and PCI Tx transfer is
- *               disabled now.
- *             o reset the MAC depending on the RstMode
- *             o Stop Interval Timer and Limit Counter of Tx Arbiter,
- *               also disable Force Sync bit and Enable Alloc bit.
- *             o perform a local reset of the port's Tx path
- *                     - reset the PCI FIFO of the async Tx queue
- *                     - reset the PCI FIFO of the sync Tx queue
- *                     - reset the RAM Buffer async Tx queue
- *                     - reset the RAM Buffer sync Tx queue
- *                     - reset the MAC Tx FIFO
- *             o switch Link and Tx LED off, stop the LED counters
- *
- *     If SK_STOP_RX is set,
- *             o stop the port's receive queue
- *             - The path data transfer activity is fully stopped now.
- *             o perform a local reset of the port's Rx path
- *                     - reset the PCI FIFO of the Rx queue
- *                     - reset the RAM Buffer receive queue
- *                     - reset the MAC Rx FIFO
- *             o switch Rx LED off, stop the LED counter
- *
- *     If all ports are stopped,
- *             o reset the RAM Interface.
- *
- * Notes:
- *     o This function may be called during the driver states RESET_PORT and
- *       SWITCH_PORT.
- */
-void SkGeStopPort(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* I/O context */
-int            Port,   /* port to stop (MAC_1 + n) */
-int            Dir,    /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */
-int            RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */
-{
-#ifndef SK_DIAG
-       SK_EVPARA Para;
-#endif /* !SK_DIAG */
-       SK_GEPORT *pPrt;
-       SK_U32  DWord;
-       SK_U32  XsCsr;
-       SK_U32  XaCsr;
-       SK_U64  ToutStart;
-       int             i;
-       int             ToutCnt;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if ((Dir & SK_STOP_TX) != 0) {
-               /* disable receiver and transmitter */
-               SkMacRxTxDisable(pAC, IoC, Port);
-
-               /* stop both transmit queues */
-               /*
-                * If the BMU is in the reset state CSR_STOP will terminate
-                * immediately.
-                */
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_STOP);
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_STOP);
-
-               ToutStart = SkOsGetTime(pAC);
-               ToutCnt = 0;
-               do {
-                       /*
-                        * Clear packet arbiter timeout to make sure
-                        * this loop will terminate.
-                        */
-                       SK_OUT16(IoC, B3_PA_CTRL, (Port == MAC_1) ? PA_CLR_TO_TX1 :
-                               PA_CLR_TO_TX2);
-
-                       /*
-                        * If the transfer stucks at the MAC the STOP command will not
-                        * terminate if we don't flush the XMAC's transmit FIFO !
-                        */
-                       SkMacFlushTxFifo(pAC, IoC, Port);
-
-                       XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff);
-                       XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff);
-
-                       if (SkOsGetTime(pAC) - ToutStart > (SK_TICKS_PER_SEC / 18)) {
-                               /*
-                                * Timeout of 1/18 second reached.
-                                * This needs to be checked at 1/18 sec only.
-                                */
-                               ToutCnt++;
-                               if (ToutCnt > 1) {
-                                       /* Might be a problem when the driver event handler
-                                        * calls StopPort again. XXX.
-                                        */
-
-                                       /* Fatal Error, Loop aborted */
-                                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E018,
-                                               SKERR_HWI_E018MSG);
-#ifndef SK_DIAG
-                                       Para.Para64 = Port;
-                                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-#endif /* !SK_DIAG */
-                                       return;
-                               }
-                               /*
-                                * Cache incoherency workaround: Assume a start command
-                                * has been lost while sending the frame.
-                                */
-                               ToutStart = SkOsGetTime(pAC);
-
-                               if ((XsCsr & CSR_STOP) != 0) {
-                                       SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START);
-                               }
-                               if ((XaCsr & CSR_STOP) != 0) {
-                                       SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START);
-                               }
-                       }
-
-                       /*
-                        * Because of the ASIC problem report entry from 21.08.1998 it is
-                        * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set.
-                        */
-               } while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE ||
-                                (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
-
-               /* Reset the MAC depending on the RstMode */
-               if (RstMode == SK_SOFT_RST) {
-                       SkMacSoftRst(pAC, IoC, Port);
-               }
-               else {
-                       SkMacHardRst(pAC, IoC, Port);
-               }
-
-               /* Disable Force Sync bit and Enable Alloc bit */
-               SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
-                       TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
-
-               /* Stop Interval Timer and Limit Counter of Tx Arbiter */
-               SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0L);
-               SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0L);
-
-               /* Perform a local reset of the port's Tx path */
-
-               /* Reset the PCI FIFO of the async Tx queue */
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET);
-               /* Reset the PCI FIFO of the sync Tx queue */
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET);
-               /* Reset the RAM Buffer async Tx queue */
-               SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET);
-               /* Reset the RAM Buffer sync Tx queue */
-               SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET);
-
-               /* Reset Tx MAC FIFO */
-               if (pAC->GIni.GIGenesis) {
-                       /* Note: MFF_RST_SET does NOT reset the XMAC ! */
-                       SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_SET);
-
-                       /* switch Link and Tx LED off, stop the LED counters */
-                       /* Link LED is switched off by the RLMT and the Diag itself */
-                       SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS);
-               }
-               else {
-                       /* Reset TX MAC FIFO */
-                       SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
-               }
-       }
-
-       if ((Dir & SK_STOP_RX) != 0) {
-               /*
-                * The RX Stop Command will not terminate if no buffers
-                * are queued in the RxD ring. But it will always reach
-                * the Idle state. Therefore we can use this feature to
-                * stop the transfer of received packets.
-                */
-               /* stop the port's receive queue */
-               SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP);
-
-               i = 100;
-               do {
-                       /*
-                        * Clear packet arbiter timeout to make sure
-                        * this loop will terminate
-                        */
-                       SK_OUT16(IoC, B3_PA_CTRL, (Port == MAC_1) ? PA_CLR_TO_RX1 :
-                               PA_CLR_TO_RX2);
-
-                       DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff);
-
-                       /* timeout if i==0 (bug fix for #10748) */
-                       if (--i == 0) {
-                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024,
-                                       SKERR_HWI_E024MSG);
-                               break;
-                       }
-                       /*
-                        * because of the ASIC problem report entry from 21.08.98
-                        * it is required to wait until CSR_STOP is reset and
-                        * CSR_SV_IDLE is set.
-                        */
-               } while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
-
-               /* The path data transfer activity is fully stopped now */
-
-               /* Perform a local reset of the port's Rx path */
-
-                /*     Reset the PCI FIFO of the Rx queue */
-               SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET);
-               /* Reset the RAM Buffer receive queue */
-               SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET);
-
-               /* Reset Rx MAC FIFO */
-               if (pAC->GIni.GIGenesis) {
-
-                       SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET);
-
-                       /* switch Rx LED off, stop the LED counter */
-                       SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS);
-               }
-               else {
-                       /* Reset Rx MAC FIFO */
-                       SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
-               }
-       }
-}      /* SkGeStopPort */
-
-
-/******************************************************************************
- *
- *     SkGeInit0() - Level 0 Initialization
- *
- * Description:
- *     - Initialize the BMU address offsets
- *
- * Returns:
- *     nothing
- */
-static void SkGeInit0(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC)            /* IO context */
-{
-       int i;
-       SK_GEPORT *pPrt;
-
-       for (i = 0; i < SK_MAX_MACS; i++) {
-               pPrt = &pAC->GIni.GP[i];
-
-               pPrt->PState = SK_PRT_RESET;
-               pPrt->PRxQOff = QOffTab[i].RxQOff;
-               pPrt->PXsQOff = QOffTab[i].XsQOff;
-               pPrt->PXaQOff = QOffTab[i].XaQOff;
-               pPrt->PCheckPar = SK_FALSE;
-               pPrt->PIsave = 0;
-               pPrt->PPrevShorts = 0;
-               pPrt->PLinkResCt = 0;
-               pPrt->PAutoNegTOCt = 0;
-               pPrt->PPrevRx = 0;
-               pPrt->PPrevFcs = 0;
-               pPrt->PRxLim = SK_DEF_RX_WA_LIM;
-               pPrt->PLinkMode = SK_LMODE_AUTOFULL;
-               pPrt->PLinkSpeedCap = SK_LSPEED_CAP_1000MBPS;
-               pPrt->PLinkSpeed = SK_LSPEED_1000MBPS;
-               pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_UNKNOWN;
-               pPrt->PLinkModeConf = SK_LMODE_AUTOSENSE;
-               pPrt->PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
-               pPrt->PLinkBroken = SK_TRUE; /* See WA code */
-               pPrt->PLinkCap = (SK_LMODE_CAP_HALF | SK_LMODE_CAP_FULL |
-                               SK_LMODE_CAP_AUTOHALF | SK_LMODE_CAP_AUTOFULL);
-               pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN;
-               pPrt->PFlowCtrlCap = SK_FLOW_MODE_SYM_OR_REM;
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
-               pPrt->PMSCap = 0;
-               pPrt->PMSMode = SK_MS_MODE_AUTO;
-               pPrt->PMSStatus = SK_MS_STAT_UNSET;
-               pPrt->PAutoNegFail = SK_FALSE;
-               pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
-               pPrt->PHWLinkUp = SK_FALSE;
-       }
-
-       pAC->GIni.GIPortUsage = SK_RED_LINK;
-
-}      /* SkGeInit0*/
-
-#ifdef SK_PCI_RESET
-
-/******************************************************************************
- *
- *     SkGePciReset() - Reset PCI interface
- *
- * Description:
- *     o Read PCI configuration.
- *     o Change power state to 3.
- *     o Change power state to 0.
- *     o Restore PCI configuration.
- *
- * Returns:
- *     0:      Success.
- *     1:      Power state could not be changed to 3.
- */
-static int SkGePciReset(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC)            /* IO context */
-{
-       int             i;
-       SK_U16  PmCtlSts;
-       SK_U32  Bp1;
-       SK_U32  Bp2;
-       SK_U16  PciCmd;
-       SK_U8   Cls;
-       SK_U8   Lat;
-       SK_U8   ConfigSpace[PCI_CFG_SIZE];
-
-       /*
-        * Note: Switching to D3 state is like a software reset.
-        *               Switching from D3 to D0 is a hardware reset.
-        *               We have to save and restore the configuration space.
-        */
-       for (i = 0; i < PCI_CFG_SIZE; i++) {
-               SkPciReadCfgDWord(pAC, i*4, &ConfigSpace[i]);
-       }
-
-       /* We know the RAM Interface Arbiter is enabled. */
-       SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D3);
-       SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts);
-
-       if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D3) {
-               return(1);
-       }
-
-       /* Return to D0 state. */
-       SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D0);
-
-       /* Check for D0 state. */
-       SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts);
-
-       if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D0) {
-               return(1);
-       }
-
-       /* Check PCI Config Registers. */
-       SkPciReadCfgWord(pAC, PCI_COMMAND, &PciCmd);
-       SkPciReadCfgByte(pAC, PCI_CACHE_LSZ, &Cls);
-       SkPciReadCfgDWord(pAC, PCI_BASE_1ST, &Bp1);
-       SkPciReadCfgDWord(pAC, PCI_BASE_2ND, &Bp2);
-       SkPciReadCfgByte(pAC, PCI_LAT_TIM, &Lat);
-
-       if (PciCmd != 0 || Cls != 0 || (Bp1 & 0xfffffff0L) != 0 || Bp2 != 1 ||
-               Lat != 0) {
-               return(1);
-       }
-
-       /* Restore PCI Config Space. */
-       for (i = 0; i < PCI_CFG_SIZE; i++) {
-               SkPciWriteCfgDWord(pAC, i*4, ConfigSpace[i]);
-       }
-
-       return(0);
-}      /* SkGePciReset */
-
-#endif /* SK_PCI_RESET */
-
-/******************************************************************************
- *
- *     SkGeInit1() - Level 1 Initialization
- *
- * Description:
- *     o Do a software reset.
- *     o Clear all reset bits.
- *     o Verify that the detected hardware is present.
- *       Return an error if not.
- *     o Get the hardware configuration
- *             + Read the number of MACs/Ports.
- *             + Read the RAM size.
- *             + Read the PCI Revision Id.
- *             + Find out the adapters host clock speed
- *             + Read and check the PHY type
- *
- * Returns:
- *     0:      success
- *     5:      Unexpected PHY type detected
- *     6:      HW self test failed
- */
-static int SkGeInit1(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC)            /* IO context */
-{
-       SK_U8   Byte;
-       SK_U16  Word;
-       SK_U16  CtrlStat;
-       SK_U32  FlashAddr;
-       int     RetVal;
-       int     i;
-
-       RetVal = 0;
-
-       /* save CLK_RUN bits (YUKON-Lite) */
-       SK_IN16(IoC, B0_CTST, &CtrlStat);
-
-#ifdef SK_PCI_RESET
-       (void)SkGePciReset(pAC, IoC);
-#endif /* SK_PCI_RESET */
-
-       /* do the SW-reset */
-       SK_OUT8(IoC, B0_CTST, CS_RST_SET);
-
-       /* release the SW-reset */
-       SK_OUT8(IoC, B0_CTST, CS_RST_CLR);
-
-       /* reset all error bits in the PCI STATUS register */
-       /*
-        * Note: PCI Cfg cycles cannot be used, because they are not
-        *               available on some platforms after 'boot time'.
-        */
-       SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
-
-       SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-       SK_OUT16(IoC, PCI_C(PCI_STATUS), Word | PCI_ERRBITS);
-       SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-
-       /* release Master Reset */
-       SK_OUT8(IoC, B0_CTST, CS_MRST_CLR);
-
-#ifdef CLK_RUN
-       CtrlStat |= CS_CLK_RUN_ENA;
-#endif /* CLK_RUN */
-
-       /* restore CLK_RUN bits */
-       SK_OUT16(IoC, B0_CTST, CtrlStat &
-               (CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA));
-
-       /* read Chip Identification Number */
-       SK_IN8(IoC, B2_CHIP_ID, &Byte);
-       pAC->GIni.GIChipId = Byte;
-
-       /* read number of MACs */
-       SK_IN8(IoC, B2_MAC_CFG, &Byte);
-       pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2;
-
-       /* get Chip Revision Number */
-       pAC->GIni.GIChipRev = (SK_U8)((Byte & CFG_CHIP_R_MSK) >> 4);
-
-       /* get diff. PCI parameters */
-       SK_IN16(IoC, B0_CTST, &CtrlStat);
-
-       /* read the adapters RAM size */
-       SK_IN8(IoC, B2_E_0, &Byte);
-
-       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-
-               pAC->GIni.GIGenesis = SK_TRUE;
-
-               if (Byte == 3) {
-                       /* special case: 4 x 64k x 36, offset = 0x80000 */
-                       pAC->GIni.GIRamSize = 1024;
-                       pAC->GIni.GIRamOffs = (SK_U32)512 * 1024;
-               }
-               else {
-                       pAC->GIni.GIRamSize = (int)Byte * 512;
-                       pAC->GIni.GIRamOffs = 0;
-               }
-               /* all GE adapters work with 53.125 MHz host clock */
-               pAC->GIni.GIHstClkFact = SK_FACT_53;
-
-               /* set Descr. Poll Timer Init Value to 250 ms */
-               pAC->GIni.GIPollTimerVal =
-                       SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100;
-       }
-       else {
-               pAC->GIni.GIGenesis = SK_FALSE;
-
-#ifndef VCPU
-               pAC->GIni.GIRamSize = (Byte == 0) ? 128 : (int)Byte * 4;
-#else
-               pAC->GIni.GIRamSize = 128;
-#endif
-               pAC->GIni.GIRamOffs = 0;
-
-               /* WA for chip Rev. A */
-               pAC->GIni.GIWolOffs = (pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0;
-
-               /* get PM Capabilities of PCI config space */
-               SK_IN16(IoC, PCI_C(PCI_PM_CAP_REG), &Word);
-
-               /* check if VAUX is available */
-               if (((CtrlStat & CS_VAUX_AVAIL) != 0) &&
-                       /* check also if PME from D3cold is set */
-                       ((Word & PCI_PME_D3C_SUP) != 0)) {
-                       /* set entry in GE init struct */
-                       pAC->GIni.GIVauxAvail = SK_TRUE;
-               }
-
-               /* save Flash-Address Register */
-               SK_IN32(IoC, B2_FAR, &FlashAddr);
-
-               /* test Flash-Address Register */
-               SK_OUT8(IoC, B2_FAR + 3, 0xff);
-               SK_IN8(IoC, B2_FAR + 3, &Byte);
-
-               pAC->GIni.GIYukonLite = (SK_BOOL)(Byte != 0);
-
-               /* restore Flash-Address Register */
-               SK_OUT32(IoC, B2_FAR, FlashAddr);
-
-               for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-                       /* set GMAC Link Control reset */
-                       SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET);
-
-                       /* clear GMAC Link Control reset */
-                       SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
-               }
-               /* all YU chips work with 78.125 MHz host clock */
-               pAC->GIni.GIHstClkFact = SK_FACT_78;
-
-               pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX;        /* 215 ms */
-       }
-
-       /* check if 64-bit PCI Slot is present */
-       pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0);
-
-       /* check if 66 MHz PCI Clock is active */
-       pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0);
-
-       /* read PCI HW Revision Id. */
-       SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte);
-       pAC->GIni.GIPciHwRev = Byte;
-
-       /* read the PMD type */
-       SK_IN8(IoC, B2_PMD_TYP, &Byte);
-       pAC->GIni.GICopperType = (SK_U8)(Byte == 'T');
-
-       /* read the PHY type */
-       SK_IN8(IoC, B2_E_1, &Byte);
-
-       Byte &= 0x0f;   /* the PHY type is stored in the lower nibble */
-       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-
-               if (pAC->GIni.GIGenesis) {
-                       switch (Byte) {
-                       case SK_PHY_XMAC:
-                               pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC;
-                               break;
-                       case SK_PHY_BCOM:
-                               pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM;
-                               pAC->GIni.GP[i].PMSCap =
-                                       SK_MS_CAP_AUTO | SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE;
-                               break;
-#ifdef OTHER_PHY
-                       case SK_PHY_LONE:
-                               pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE;
-                               break;
-                       case SK_PHY_NAT:
-                               pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT;
-                               break;
-#endif /* OTHER_PHY */
-                       default:
-                               /* ERROR: unexpected PHY type detected */
-                               RetVal = 5;
-                               break;
-                       }
-               }
-               else {
-                       if (Byte == 0) {
-                               /* if this field is not initialized */
-                               Byte = SK_PHY_MARV_COPPER;
-                               pAC->GIni.GICopperType = SK_TRUE;
-                       }
-                       pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV;
-
-                       if (pAC->GIni.GICopperType) {
-                               pAC->GIni.GP[i].PLinkSpeedCap = SK_LSPEED_CAP_AUTO |
-                                       SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS |
-                                       SK_LSPEED_CAP_1000MBPS;
-                               pAC->GIni.GP[i].PLinkSpeed = SK_LSPEED_AUTO;
-                               pAC->GIni.GP[i].PMSCap =
-                                       SK_MS_CAP_AUTO | SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE;
-                       }
-                       else {
-                               Byte = SK_PHY_MARV_FIBER;
-                       }
-               }
-
-               pAC->GIni.GP[i].PhyType = Byte;
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
-                       ("PHY type: %d  PHY addr: %04x\n", Byte,
-                       pAC->GIni.GP[i].PhyAddr));
-       }
-
-       /* get Mac Type & set function pointers dependent on */
-       if (pAC->GIni.GIGenesis) {
-               pAC->GIni.GIMacType = SK_MAC_XMAC;
-
-               pAC->GIni.GIFunc.pFnMacUpdateStats      = SkXmUpdateStats;
-               pAC->GIni.GIFunc.pFnMacStatistic        = SkXmMacStatistic;
-               pAC->GIni.GIFunc.pFnMacResetCounter     = SkXmResetCounter;
-               pAC->GIni.GIFunc.pFnMacOverflow         = SkXmOverflowStatus;
-       }
-       else {
-               pAC->GIni.GIMacType = SK_MAC_GMAC;
-
-               pAC->GIni.GIFunc.pFnMacUpdateStats      = SkGmUpdateStats;
-               pAC->GIni.GIFunc.pFnMacStatistic        = SkGmMacStatistic;
-               pAC->GIni.GIFunc.pFnMacResetCounter     = SkGmResetCounter;
-               pAC->GIni.GIFunc.pFnMacOverflow         = SkGmOverflowStatus;
-
-#ifdef SPECIAL_HANDLING
-               if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
-                       /* check HW self test result */
-                       SK_IN8(IoC, B2_E_3, &Byte);
-                       if ((Byte & B2_E3_RES_MASK) != 0) {
-                               RetVal = 6;
-                       }
-               }
-#endif
-       }
-       return(RetVal);
-}      /* SkGeInit1 */
-
-
-/******************************************************************************
- *
- *     SkGeInit2() - Level 2 Initialization
- *
- * Description:
- *     - start the Blink Source Counter
- *     - start the Descriptor Poll Timer
- *     - configure the MAC-Arbiter
- *     - configure the Packet-Arbiter
- *     - enable the Tx Arbiters
- *     - enable the RAM Interface Arbiter
- *
- * Returns:
- *     nothing
- */
-static void SkGeInit2(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC)            /* IO context */
-{
-       SK_U32  DWord;
-       int             i;
-
-       /* start the Descriptor Poll Timer */
-       if (pAC->GIni.GIPollTimerVal != 0) {
-               if (pAC->GIni.GIPollTimerVal > SK_DPOLL_MAX) {
-                       pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX;
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E017, SKERR_HWI_E017MSG);
-               }
-               SK_OUT32(IoC, B28_DPT_INI, pAC->GIni.GIPollTimerVal);
-               SK_OUT8(IoC, B28_DPT_CTRL, DPT_START);
-       }
-
-       if (pAC->GIni.GIGenesis) {
-               /* start the Blink Source Counter */
-               DWord = SK_BLK_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100;
-
-               SK_OUT32(IoC, B2_BSC_INI, DWord);
-               SK_OUT8(IoC, B2_BSC_CTRL, BSC_START);
-
-               /*
-                * Configure the MAC Arbiter and the Packet Arbiter.
-                * They will be started once and never be stopped.
-                */
-               SkGeInitMacArb(pAC, IoC);
-
-               SkGeInitPktArb(pAC, IoC);
-       }
-       else {
-               /* start Time Stamp Timer */
-               SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START);
-       }
-
-       /* enable the Tx Arbiters */
-       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-               SK_OUT8(IoC, MR_ADDR(i, TXA_CTRL), TXA_ENA_ARB);
-       }
-
-       /* enable the RAM Interface Arbiter */
-       SkGeInitRamIface(pAC, IoC);
-
-}      /* SkGeInit2 */
-
-/******************************************************************************
- *
- *     SkGeInit() - Initialize the GE Adapter with the specified level.
- *
- * Description:
- *     Level   0:      Initialize the Module structures.
- *     Level   1:      Generic Hardware Initialization. The IOP/MemBase pointer has
- *                             to be set before calling this level.
- *
- *                     o Do a software reset.
- *                     o Clear all reset bits.
- *                     o Verify that the detected hardware is present.
- *                       Return an error if not.
- *                     o Get the hardware configuration
- *                             + Set GIMacsFound with the number of MACs.
- *                             + Store the RAM size in GIRamSize.
- *                             + Save the PCI Revision ID in GIPciHwRev.
- *                     o return an error
- *                             if Number of MACs > SK_MAX_MACS
- *
- *                     After returning from Level 0 the adapter
- *                     may be accessed with IO operations.
- *
- *     Level   2:      start the Blink Source Counter
- *
- * Returns:
- *     0:      success
- *     1:      Number of MACs exceeds SK_MAX_MACS      (after level 1)
- *     2:      Adapter not present or not accessible
- *     3:      Illegal initialization level
- *     4:      Initialization Level 1 Call missing
- *     5:      Unexpected PHY type detected
- *     6:      HW self test failed
- */
-int    SkGeInit(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Level)          /* initialization level */
-{
-       int             RetVal;         /* return value */
-       SK_U32  DWord;
-
-       RetVal = 0;
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
-               ("SkGeInit(Level %d)\n", Level));
-
-       switch (Level) {
-       case SK_INIT_DATA:
-               /* Initialization Level 0 */
-               SkGeInit0(pAC, IoC);
-               pAC->GIni.GILevel = SK_INIT_DATA;
-               break;
-
-       case SK_INIT_IO:
-               /* Initialization Level 1 */
-               RetVal = SkGeInit1(pAC, IoC);
-               if (RetVal != 0) {
-                       break;
-               }
-
-               /* check if the adapter seems to be accessible */
-               SK_OUT32(IoC, B2_IRQM_INI, 0x11335577L);
-               SK_IN32(IoC, B2_IRQM_INI, &DWord);
-               SK_OUT32(IoC, B2_IRQM_INI, 0L);
-
-               if (DWord != 0x11335577L) {
-                       RetVal = 2;
-                       break;
-               }
-
-               /* check if the number of GIMacsFound matches SK_MAX_MACS */
-               if (pAC->GIni.GIMacsFound > SK_MAX_MACS) {
-                       RetVal = 1;
-                       break;
-               }
-
-               /* Level 1 successfully passed */
-               pAC->GIni.GILevel = SK_INIT_IO;
-               break;
-
-       case SK_INIT_RUN:
-               /* Initialization Level 2 */
-               if (pAC->GIni.GILevel != SK_INIT_IO) {
-#ifndef SK_DIAG
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E002, SKERR_HWI_E002MSG);
-#endif /* !SK_DIAG */
-                       RetVal = 4;
-                       break;
-               }
-               SkGeInit2(pAC, IoC);
-
-               /* Level 2 successfully passed */
-               pAC->GIni.GILevel = SK_INIT_RUN;
-               break;
-
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG);
-               RetVal = 3;
-               break;
-       }
-
-       return(RetVal);
-}      /* SkGeInit */
-
-
-/******************************************************************************
- *
- *     SkGeDeInit() - Deinitialize the adapter
- *
- * Description:
- *     All ports of the adapter will be stopped if not already done.
- *     Do a software reset and switch off all LEDs.
- *
- * Returns:
- *     nothing
- */
-void SkGeDeInit(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC)            /* IO context */
-{
-       int     i;
-       SK_U16  Word;
-
-#ifndef VCPU
-       /* ensure I2C is ready */
-       SkI2cWaitIrq(pAC, IoC);
-#endif
-
-       /* stop all current transfer activity */
-       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-               if (pAC->GIni.GP[i].PState != SK_PRT_STOP &&
-                       pAC->GIni.GP[i].PState != SK_PRT_RESET) {
-
-                       SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST);
-               }
-       }
-
-       /* Reset all bits in the PCI STATUS register */
-       /*
-        * Note: PCI Cfg cycles cannot be used, because they are not
-        *       available on some platforms after 'boot time'.
-        */
-       SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
-
-       SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-       SK_OUT16(IoC, PCI_C(PCI_STATUS), Word | PCI_ERRBITS);
-       SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-
-       /* do the reset, all LEDs are switched off now */
-       SK_OUT8(IoC, B0_CTST, CS_RST_SET);
-}      /* SkGeDeInit */
-
-
-/******************************************************************************
- *
- *     SkGeInitPort()  Initialize the specified port.
- *
- * Description:
- *     PRxQSize, PXSQSize, and PXAQSize has to be
- *     configured for the specified port before calling this function.
- *  The descriptor rings has to be initialized too.
- *
- *     o (Re)configure queues of the specified port.
- *     o configure the MAC of the specified port.
- *     o put ASIC and MAC(s) in operational mode.
- *     o initialize Rx/Tx and Sync LED
- *     o initialize RAM Buffers and MAC FIFOs
- *
- *     The port is ready to connect when returning.
- *
- * Note:
- *     The MAC's Rx and Tx state machine is still disabled when returning.
- *
- * Returns:
- *     0:      success
- *     1:      Queue size initialization error. The configured values
- *             for PRxQSize, PXSQSize, or PXAQSize are invalid for one
- *             or more queues. The specified port was NOT initialized.
- *             An error log entry was generated.
- *     2:      The port has to be stopped before it can be initialized again.
- */
-int SkGeInitPort(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port to configure */
-{
-       SK_GEPORT *pPrt;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (SkGeCheckQSize(pAC, Port) != 0) {
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG);
-               return(1);
-       }
-
-       if (pPrt->PState == SK_PRT_INIT || pPrt->PState == SK_PRT_RUN) {
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E005, SKERR_HWI_E005MSG);
-               return(2);
-       }
-
-       /* configuration ok, initialize the Port now */
-
-       if (pAC->GIni.GIGenesis) {
-               /* initialize Rx, Tx and Link LED */
-               /*
-                * If 1000BT Phy needs LED initialization than swap
-                * LED and XMAC initialization order
-                */
-               SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
-               SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA);
-               /* The Link LED is initialized by RLMT or Diagnostics itself */
-
-               SkXmInitMac(pAC, IoC, Port);
-       }
-       else {
-
-               SkGmInitMac(pAC, IoC, Port);
-       }
-
-       /* do NOT initialize the Link Sync Counter */
-
-       SkGeInitMacFifo(pAC, IoC, Port);
-
-       SkGeInitRamBufs(pAC, IoC, Port);
-
-       if (pPrt->PXSQSize != 0) {
-               /* enable Force Sync bit if synchronous queue available */
-               SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC);
-       }
-
-       SkGeInitBmu(pAC, IoC, Port);
-
-       /* mark port as initialized */
-       pPrt->PState = SK_PRT_INIT;
-
-       return(0);
-}      /* SkGeInitPort */
-
-#endif /* CONFIG_SK98 */
diff --git a/drivers/sk98lin/skgemib.c b/drivers/sk98lin/skgemib.c
deleted file mode 100644 (file)
index 4a9e9e6..0000000
+++ /dev/null
@@ -1,1060 +0,0 @@
-/*****************************************************************************
- *
- * Name:       skgemib.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.7 $
- * Date:       $Date: 2002/12/16 09:04:34 $
- * Purpose:    Private Network Management Interface Management Database
- *
- ****************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 2002 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*****************************************************************************
- *
- * History:
- *
- *     $Log: skgemib.c,v $
- *     Revision 1.7  2002/12/16 09:04:34  tschilli
- *     Code for VCT handling added.
- *
- *     Revision 1.6  2002/08/09 15:40:21  rwahl
- *     Editorial change (renamed ConfSpeedCap).
- *
- *     Revision 1.5  2002/08/09 11:05:34  rwahl
- *     Added oid handling for link speed cap.
- *
- *     Revision 1.4  2002/08/09 09:40:27  rwahl
- *     Added support for NDIS OID_PNP_xxx.
- *
- *     Revision 1.3  2002/07/17 19:39:54  rwahl
- *     Added handler for OID_SKGE_SPEED_MODE & OID_SKGE_SPEED_STATUS.
- *
- *     Revision 1.2  2002/05/22 08:59:00  rwahl
- *     - static functions only for release build.
- *     - Source file must be included.
- *
- *     Revision 1.1  2002/05/22 08:12:42  rwahl
- *     Initial version.
- *
- ****************************************************************************/
-
-#include <config.h>
-
-#ifdef CONFIG_SK98
-
-/*
- * PRIVATE OID handler function prototypes
- */
-PNMI_STATIC int Addr(SK_AC *pAC, SK_IOC IoC, int action,
-       SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int CsumStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int General(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Mac8023Stat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int MacPrivateConf(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int MacPrivateStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Monitor(SK_AC *pAC, SK_IOC IoC, int action,
-       SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int OidStruct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Perform(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int* pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Rlmt(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int RlmtStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int SensorStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Vpd(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-
-#ifdef SK_POWER_MGMT
-PNMI_STATIC int PowerManagement(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-#endif
-
-
-/* defines *******************************************************************/
-#define ID_TABLE_SIZE (sizeof(IdTable)/sizeof(IdTable[0]))
-
-
-/* global variables **********************************************************/
-
-/*
- * Table to correlate OID with handler function and index to
- * hardware register stored in StatAddress if applicable.
- */
-PNMI_STATIC const SK_PNMI_TAB_ENTRY IdTable[] = {
-       {OID_GEN_XMIT_OK,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX},
-       {OID_GEN_RCV_OK,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX},
-       {OID_GEN_XMIT_ERROR,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, General, 0},
-       {OID_GEN_RCV_ERROR,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, General, 0},
-       {OID_GEN_RCV_NO_BUFFER,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, General, 0},
-       {OID_GEN_DIRECTED_FRAMES_XMIT,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNICAST},
-       {OID_GEN_MULTICAST_FRAMES_XMIT,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTICAST},
-       {OID_GEN_BROADCAST_FRAMES_XMIT,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_BROADCAST},
-       {OID_GEN_DIRECTED_FRAMES_RCV,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_UNICAST},
-       {OID_GEN_MULTICAST_FRAMES_RCV,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_MULTICAST},
-       {OID_GEN_BROADCAST_FRAMES_RCV,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_BROADCAST},
-       {OID_GEN_RCV_CRC_ERROR,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FCS},
-       {OID_GEN_TRANSMIT_QUEUE_LENGTH,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, General, 0},
-       {OID_802_3_PERMANENT_ADDRESS,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, 0},
-       {OID_802_3_CURRENT_ADDRESS,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, 0},
-       {OID_802_3_RCV_ERROR_ALIGNMENT,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FRAMING},
-       {OID_802_3_XMIT_ONE_COLLISION,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_SINGLE_COL},
-       {OID_802_3_XMIT_MORE_COLLISIONS,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTI_COL},
-       {OID_802_3_XMIT_DEFERRED,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_DEFFERAL},
-       {OID_802_3_XMIT_MAX_COLLISIONS,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_EXCESS_COL},
-       {OID_802_3_RCV_OVERRUN,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_OVERFLOW},
-       {OID_802_3_XMIT_UNDERRUN,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNDERRUN},
-       {OID_802_3_XMIT_TIMES_CRS_LOST,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_CARRIER},
-       {OID_802_3_XMIT_LATE_COLLISIONS,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_LATE_COL},
-#ifdef SK_POWER_MGMT
-       {OID_PNP_CAPABILITIES,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, PowerManagement, 0},
-       {OID_PNP_SET_POWER,
-               0,
-               0,
-               0,
-               SK_PNMI_WO, PowerManagement, 0},
-       {OID_PNP_QUERY_POWER,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, PowerManagement, 0},
-       {OID_PNP_ADD_WAKE_UP_PATTERN,
-               0,
-               0,
-               0,
-               SK_PNMI_WO, PowerManagement, 0},
-       {OID_PNP_REMOVE_WAKE_UP_PATTERN,
-               0,
-               0,
-               0,
-               SK_PNMI_WO, PowerManagement, 0},
-       {OID_PNP_ENABLE_WAKE_UP,
-               0,
-               0,
-               0,
-               SK_PNMI_RW, PowerManagement, 0},
-#endif /* SK_POWER_MGMT */
-       {OID_SKGE_MDB_VERSION,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(MgmtDBVersion),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_SUPPORTED_LIST,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_ALL_DATA,
-               0,
-               0,
-               0,
-               SK_PNMI_RW, OidStruct, 0},
-       {OID_SKGE_VPD_FREE_BYTES,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(VpdFreeBytes),
-               SK_PNMI_RO, Vpd, 0},
-       {OID_SKGE_VPD_ENTRIES_LIST,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(VpdEntriesList),
-               SK_PNMI_RO, Vpd, 0},
-       {OID_SKGE_VPD_ENTRIES_NUMBER,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(VpdEntriesNumber),
-               SK_PNMI_RO, Vpd, 0},
-       {OID_SKGE_VPD_KEY,
-               SK_PNMI_VPD_ENTRIES,
-               sizeof(SK_PNMI_VPD),
-               SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdKey),
-               SK_PNMI_RO, Vpd, 0},
-       {OID_SKGE_VPD_VALUE,
-               SK_PNMI_VPD_ENTRIES,
-               sizeof(SK_PNMI_VPD),
-               SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdValue),
-               SK_PNMI_RO, Vpd, 0},
-       {OID_SKGE_VPD_ACCESS,
-               SK_PNMI_VPD_ENTRIES,
-               sizeof(SK_PNMI_VPD),
-               SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAccess),
-               SK_PNMI_RO, Vpd, 0},
-       {OID_SKGE_VPD_ACTION,
-               SK_PNMI_VPD_ENTRIES,
-               sizeof(SK_PNMI_VPD),
-               SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAction),
-               SK_PNMI_RW, Vpd, 0},
-       {OID_SKGE_PORT_NUMBER,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(PortNumber),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_DEVICE_TYPE,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(DeviceType),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_DRIVER_DESCR,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(DriverDescr),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_DRIVER_VERSION,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(DriverVersion),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_HW_DESCR,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(HwDescr),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_HW_VERSION,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(HwVersion),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_CHIPSET,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(Chipset),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_ACTION,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(Action),
-               SK_PNMI_RW, Perform, 0},
-       {OID_SKGE_RESULT,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TestResult),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_BUS_TYPE,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(BusType),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_BUS_SPEED,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(BusSpeed),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_BUS_WIDTH,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(BusWidth),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_TX_SW_QUEUE_LEN,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TxSwQueueLen),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_TX_SW_QUEUE_MAX,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TxSwQueueMax),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_TX_RETRY,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TxRetryCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_RX_INTR_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RxIntrCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_TX_INTR_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TxIntrCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_RX_NO_BUF_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RxNoBufCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_TX_NO_BUF_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TxNoBufCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_TX_USED_DESCR_NO,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TxUsedDescrNo),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_RX_DELIVERED_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RxDeliveredCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_RX_OCTETS_DELIV_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RxOctetsDeliveredCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_RX_HW_ERROR_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RxHwErrorsCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_TX_HW_ERROR_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TxHwErrorsCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_IN_ERRORS_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(InErrorsCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_OUT_ERROR_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(OutErrorsCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_ERR_RECOVERY_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(ErrRecoveryCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_SYSUPTIME,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(SysUpTime),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_SENSOR_NUMBER,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(SensorNumber),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_SENSOR_INDEX,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorIndex),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_DESCR,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorDescr),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_TYPE,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorType),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_VALUE,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorValue),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_WAR_THRES_LOW,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdLow),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_WAR_THRES_UPP,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdHigh),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_ERR_THRES_LOW,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdLow),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_ERR_THRES_UPP,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdHigh),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_STATUS,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorStatus),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_WAR_CTS,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningCts),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_ERR_CTS,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorCts),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_WAR_TIME,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningTimestamp),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_ERR_TIME,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorTimestamp),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_CHKSM_NUMBER,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(ChecksumNumber),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_CHKSM_RX_OK_CTS,
-               SKCS_NUM_PROTOCOLS,
-               sizeof(SK_PNMI_CHECKSUM),
-               SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxOkCts),
-               SK_PNMI_RO, CsumStat, 0},
-       {OID_SKGE_CHKSM_RX_UNABLE_CTS,
-               SKCS_NUM_PROTOCOLS,
-               sizeof(SK_PNMI_CHECKSUM),
-               SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxUnableCts),
-               SK_PNMI_RO, CsumStat, 0},
-       {OID_SKGE_CHKSM_RX_ERR_CTS,
-               SKCS_NUM_PROTOCOLS,
-               sizeof(SK_PNMI_CHECKSUM),
-               SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxErrCts),
-               SK_PNMI_RO, CsumStat, 0},
-       {OID_SKGE_CHKSM_TX_OK_CTS,
-               SKCS_NUM_PROTOCOLS,
-               sizeof(SK_PNMI_CHECKSUM),
-               SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxOkCts),
-               SK_PNMI_RO, CsumStat, 0},
-       {OID_SKGE_CHKSM_TX_UNABLE_CTS,
-               SKCS_NUM_PROTOCOLS,
-               sizeof(SK_PNMI_CHECKSUM),
-               SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxUnableCts),
-               SK_PNMI_RO, CsumStat, 0},
-       {OID_SKGE_STAT_TX,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX},
-       {OID_SKGE_STAT_TX_OCTETS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOctetsOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_OCTET},
-       {OID_SKGE_STAT_TX_BROADCAST,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBroadcastOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BROADCAST},
-       {OID_SKGE_STAT_TX_MULTICAST,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMulticastOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTICAST},
-       {OID_SKGE_STAT_TX_UNICAST,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUnicastOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNICAST},
-       {OID_SKGE_STAT_TX_LONGFRAMES,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLongFramesCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LONGFRAMES},
-       {OID_SKGE_STAT_TX_BURST,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBurstCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BURST},
-       {OID_SKGE_STAT_TX_PFLOWC,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxPauseMacCtrlCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_PMACC},
-       {OID_SKGE_STAT_TX_FLOWC,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMacCtrlCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MACC},
-       {OID_SKGE_STAT_TX_SINGLE_COL,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSingleCollisionCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SINGLE_COL},
-       {OID_SKGE_STAT_TX_MULTI_COL,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMultipleCollisionCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTI_COL},
-       {OID_SKGE_STAT_TX_EXCESS_COL,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveCollisionCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_COL},
-       {OID_SKGE_STAT_TX_LATE_COL,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLateCollisionCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LATE_COL},
-       {OID_SKGE_STAT_TX_DEFFERAL,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxDeferralCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_DEFFERAL},
-       {OID_SKGE_STAT_TX_EXCESS_DEF,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveDeferralCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_DEF},
-       {OID_SKGE_STAT_TX_UNDERRUN,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxFifoUnderrunCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNDERRUN},
-       {OID_SKGE_STAT_TX_CARRIER,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxCarrierCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_CARRIER},
-/*     {OID_SKGE_STAT_TX_UTIL,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUtilization),
-               SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */
-       {OID_SKGE_STAT_TX_64,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx64Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_64},
-       {OID_SKGE_STAT_TX_127,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx127Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_127},
-       {OID_SKGE_STAT_TX_255,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx255Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_255},
-       {OID_SKGE_STAT_TX_511,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx511Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_511},
-       {OID_SKGE_STAT_TX_1023,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx1023Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_1023},
-       {OID_SKGE_STAT_TX_MAX,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMaxCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MAX},
-       {OID_SKGE_STAT_TX_SYNC,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC},
-       {OID_SKGE_STAT_TX_SYNC_OCTETS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncOctetsCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC_OCTET},
-       {OID_SKGE_STAT_RX,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX},
-       {OID_SKGE_STAT_RX_OCTETS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOctetsOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OCTET},
-       {OID_SKGE_STAT_RX_BROADCAST,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBroadcastOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BROADCAST},
-       {OID_SKGE_STAT_RX_MULTICAST,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMulticastOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MULTICAST},
-       {OID_SKGE_STAT_RX_UNICAST,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUnicastOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_UNICAST},
-       {OID_SKGE_STAT_RX_LONGFRAMES,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxLongFramesCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_LONGFRAMES},
-       {OID_SKGE_STAT_RX_PFLOWC,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC},
-       {OID_SKGE_STAT_RX_FLOWC,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC},
-       {OID_SKGE_STAT_RX_PFLOWC_ERR,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlErrorCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC_ERR},
-       {OID_SKGE_STAT_RX_FLOWC_UNKWN,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlUnknownCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC_UNKWN},
-       {OID_SKGE_STAT_RX_BURST,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBurstCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BURST},
-       {OID_SKGE_STAT_RX_MISSED,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMissedCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MISSED},
-       {OID_SKGE_STAT_RX_FRAMING,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFramingCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FRAMING},
-       {OID_SKGE_STAT_RX_OVERFLOW,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFifoOverflowCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OVERFLOW},
-       {OID_SKGE_STAT_RX_JABBER,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxJabberCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_JABBER},
-       {OID_SKGE_STAT_RX_CARRIER,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCarrierCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CARRIER},
-       {OID_SKGE_STAT_RX_IR_LENGTH,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxIRLengthCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_IRLENGTH},
-       {OID_SKGE_STAT_RX_SYMBOL,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxSymbolCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SYMBOL},
-       {OID_SKGE_STAT_RX_SHORTS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxShortsCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SHORTS},
-       {OID_SKGE_STAT_RX_RUNT,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxRuntCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_RUNT},
-       {OID_SKGE_STAT_RX_CEXT,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCextCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CEXT},
-       {OID_SKGE_STAT_RX_TOO_LONG,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxTooLongCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_TOO_LONG},
-       {OID_SKGE_STAT_RX_FCS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFcsCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FCS},
-/*     {OID_SKGE_STAT_RX_UTIL,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUtilization),
-               SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */
-       {OID_SKGE_STAT_RX_64,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx64Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_64},
-       {OID_SKGE_STAT_RX_127,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx127Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_127},
-       {OID_SKGE_STAT_RX_255,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx255Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_255},
-       {OID_SKGE_STAT_RX_511,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx511Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_511},
-       {OID_SKGE_STAT_RX_1023,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx1023Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_1023},
-       {OID_SKGE_STAT_RX_MAX,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMaxCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MAX},
-       {OID_SKGE_PHYS_CUR_ADDR,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacCurrentAddr),
-               SK_PNMI_RW, Addr, 0},
-       {OID_SKGE_PHYS_FAC_ADDR,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacFactoryAddr),
-               SK_PNMI_RO, Addr, 0},
-       {OID_SKGE_PMD,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPMD),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_CONNECTOR,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfConnector),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_LINK_CAP,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkCapability),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_LINK_MODE,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkMode),
-               SK_PNMI_RW, MacPrivateConf, 0},
-       {OID_SKGE_LINK_MODE_STATUS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkModeStatus),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_LINK_STATUS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkStatus),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_FLOWCTRL_CAP,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlCapability),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_FLOWCTRL_MODE,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlMode),
-               SK_PNMI_RW, MacPrivateConf, 0},
-       {OID_SKGE_FLOWCTRL_STATUS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlStatus),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_PHY_OPERATION_CAP,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationCapability),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_PHY_OPERATION_MODE,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationMode),
-               SK_PNMI_RW, MacPrivateConf, 0},
-       {OID_SKGE_PHY_OPERATION_STATUS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationStatus),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_SPEED_CAP,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedCapability),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_SPEED_MODE,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedMode),
-               SK_PNMI_RW, MacPrivateConf, 0},
-       {OID_SKGE_SPEED_STATUS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedStatus),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_TRAP,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(Trap),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_TRAP_NUMBER,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TrapNumber),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_RLMT_MODE,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtMode),
-               SK_PNMI_RW, Rlmt, 0},
-       {OID_SKGE_RLMT_PORT_NUMBER,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtPortNumber),
-               SK_PNMI_RO, Rlmt, 0},
-       {OID_SKGE_RLMT_PORT_ACTIVE,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtPortActive),
-               SK_PNMI_RO, Rlmt, 0},
-       {OID_SKGE_RLMT_PORT_PREFERRED,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtPortPreferred),
-               SK_PNMI_RW, Rlmt, 0},
-       {OID_SKGE_RLMT_CHANGE_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtChangeCts),
-               SK_PNMI_RO, Rlmt, 0},
-       {OID_SKGE_RLMT_CHANGE_TIME,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtChangeTime),
-               SK_PNMI_RO, Rlmt, 0},
-       {OID_SKGE_RLMT_CHANGE_ESTIM,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtChangeEstimate),
-               SK_PNMI_RO, Rlmt, 0},
-       {OID_SKGE_RLMT_CHANGE_THRES,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtChangeThreshold),
-               SK_PNMI_RW, Rlmt, 0},
-       {OID_SKGE_RLMT_PORT_INDEX,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_RLMT),
-               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtIndex),
-               SK_PNMI_RO, RlmtStat, 0},
-       {OID_SKGE_RLMT_STATUS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_RLMT),
-               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtStatus),
-               SK_PNMI_RO, RlmtStat, 0},
-       {OID_SKGE_RLMT_TX_HELLO_CTS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_RLMT),
-               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxHelloCts),
-               SK_PNMI_RO, RlmtStat, 0},
-       {OID_SKGE_RLMT_RX_HELLO_CTS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_RLMT),
-               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxHelloCts),
-               SK_PNMI_RO, RlmtStat, 0},
-       {OID_SKGE_RLMT_TX_SP_REQ_CTS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_RLMT),
-               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxSpHelloReqCts),
-               SK_PNMI_RO, RlmtStat, 0},
-       {OID_SKGE_RLMT_RX_SP_CTS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_RLMT),
-               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxSpHelloCts),
-               SK_PNMI_RO, RlmtStat, 0},
-       {OID_SKGE_RLMT_MONITOR_NUMBER,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtMonitorNumber),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_RLMT_MONITOR_INDEX,
-               SK_PNMI_MONITOR_ENTRIES,
-               sizeof(SK_PNMI_RLMT_MONITOR),
-               SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorIndex),
-               SK_PNMI_RO, Monitor, 0},
-       {OID_SKGE_RLMT_MONITOR_ADDR,
-               SK_PNMI_MONITOR_ENTRIES,
-               sizeof(SK_PNMI_RLMT_MONITOR),
-               SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAddr),
-               SK_PNMI_RO, Monitor, 0},
-       {OID_SKGE_RLMT_MONITOR_ERRS,
-               SK_PNMI_MONITOR_ENTRIES,
-               sizeof(SK_PNMI_RLMT_MONITOR),
-               SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorErrorCts),
-               SK_PNMI_RO, Monitor, 0},
-       {OID_SKGE_RLMT_MONITOR_TIMESTAMP,
-               SK_PNMI_MONITOR_ENTRIES,
-               sizeof(SK_PNMI_RLMT_MONITOR),
-               SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorTimestamp),
-               SK_PNMI_RO, Monitor, 0},
-       {OID_SKGE_RLMT_MONITOR_ADMIN,
-               SK_PNMI_MONITOR_ENTRIES,
-               sizeof(SK_PNMI_RLMT_MONITOR),
-               SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAdmin),
-               SK_PNMI_RW, Monitor, 0},
-       {OID_SKGE_MTU,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(MtuSize),
-               SK_PNMI_RW, MacPrivateConf, 0},
-       {OID_SKGE_VCT_GET,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Vct, 0},
-       {OID_SKGE_VCT_SET,
-               0,
-               0,
-               0,
-               SK_PNMI_WO, Vct, 0},
-       {OID_SKGE_VCT_STATUS,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Vct, 0},
-};
-
-#endif /* CONFIG_SK98 */
diff --git a/drivers/sk98lin/skgepnmi.c b/drivers/sk98lin/skgepnmi.c
deleted file mode 100644 (file)
index b5d32b0..0000000
+++ /dev/null
@@ -1,8310 +0,0 @@
-/*****************************************************************************
- *
- * Name:       skgepnmi.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.102 $
- * Date:       $Date: 2002/12/16 14:03:24 $
- * Purpose:    Private Network Management Interface
- *
- ****************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*****************************************************************************
- *
- * History:
- *
- *     $Log: skgepnmi.c,v $
- *     Revision 1.102  2002/12/16 14:03:24  tschilli
- *     VCT code in Vct() changed.
- *
- *     Revision 1.101  2002/12/16 09:04:10  tschilli
- *     Code for VCT handling added.
- *
- *     Revision 1.100  2002/09/26 14:28:13  tschilli
- *     For XMAC the values in the SK_PNMI_PORT Port struct are copied to
- *     the new SK_PNMI_PORT BufPort struct during a MacUpdate() call.
- *     These values are used when GetPhysStatVal() is called. With this
- *     mechanism you get the best results when software corrections for
- *     counters are needed. Example: RX_LONGFRAMES.
- *
- *     Revision 1.99  2002/09/17 12:31:19  tschilli
- *     OID_SKGE_TX_HW_ERROR_CTS, OID_SKGE_OUT_ERROR_CTS, OID_GEN_XMIT_ERROR:
- *     Double count of SK_PNMI_HTX_EXCESS_COL in function General() removed.
- *     OID_PNP_CAPABILITIES: sizeof(SK_PM_WAKE_UP_CAPABILITIES) changed to
- *     sizeof(SK_PNP_CAPABILITIES) in function PowerManagement().
- *
- *     Revision 1.98  2002/09/10 09:00:03  rwahl
- *     Adapted boolean definitions according sktypes.
- *
- *     Revision 1.97  2002/09/05 15:07:03  rwahl
- *     Editorial changes.
- *
- *     Revision 1.96  2002/09/05 11:04:14  rwahl
- *     - Rx/Tx packets statistics of virtual port were zero on link down (#10750)
- *     - For GMAC the overflow IRQ for Rx longframe counter was not counted.
- *     - Incorrect calculation for oids OID_SKGE_RX_HW_ERROR_CTS,
- *       OID_SKGE_IN_ERRORS_CTS,  OID_GEN_RCV_ERROR.
- *     - Moved correction for OID_SKGE_STAT_RX_TOO_LONG to GetPhysStatVal().
- *     - Editorial changes.
- *
- *     Revision 1.95  2002/09/04 08:53:37  rwahl
- *     - Incorrect statistics for Rx_too_long counter with jumbo frame (#10751)
- *     - StatRxFrameTooLong & StatRxPMaccErr counters were not reset.
- *     - Fixed compiler warning for debug msg arg types.
- *
- *     Revision 1.94  2002/08/09 15:42:14  rwahl
- *     - Fixed StatAddr table for GMAC.
- *     - VirtualConf(): returned indeterminated status for speed oids if no
- *       active port.
- *
- *     Revision 1.93  2002/08/09 11:04:59  rwahl
- *     Added handler for link speed caps.
- *
- *     Revision 1.92  2002/08/09 09:43:03  rwahl
- *     - Added handler for NDIS OID_PNP_xxx ids.
- *
- *     Revision 1.91  2002/07/17 19:53:03  rwahl
- *     - Added StatOvrflwBit table for XMAC & GMAC.
- *     - Extended StatAddr table for GMAC. Added check of number of counters
- *       in enumeration and size of StatAddr table on init level.
- *     - Added use of GIFunc table.
- *     - ChipSet is not static anymore,
- *     - Extended SIRQ event handler for both mac types.
- *     - Fixed rx short counter bug (#10620)
- *     - Added handler for oids SKGE_SPEED_MODE & SKGE_SPEED_STATUS.
- *     - Extendet GetPhysStatVal() for GMAC.
- *     - Editorial changes.
- *
- *     Revision 1.90  2002/05/22 08:56:25  rwahl
- *     - Moved OID table to separate source file.
- *     - Fix: TX_DEFFERAL counter incremented in full-duplex mode.
- *     - Use string definitions for error msgs.
- *
- *     Revision 1.89  2001/09/18 10:01:30  mkunz
- *     some OID's fixed for dualnetmode
- *
- *     Revision 1.88  2001/08/02 07:58:08  rwahl
- *     - Fixed NetIndex to csum module at ResetCounter().
- *
- *     Revision 1.87  2001/04/06 13:35:09  mkunz
- *     -Bugs fixed in handling of OID_SKGE_MTU and the VPD OID's
- *
- *     Revision 1.86  2001/03/09 09:18:03  mkunz
- *     Changes in SK_DBG_MSG
- *
- *     Revision 1.85  2001/03/08 09:37:31  mkunz
- *     Bugfix in ResetCounter for Pnmi.Port structure
- *
- *     Revision 1.84  2001/03/06 09:04:55  mkunz
- *     Made some changes in instance calculation
- *
- *     Revision 1.83  2001/02/15 09:15:32  mkunz
- *     Necessary changes for dual net mode added
- *
- *     Revision 1.82  2001/02/07 08:24:19  mkunz
- *     -Made changes in handling of OID_SKGE_MTU
- *
- *     Revision 1.81  2001/02/06 09:58:00  mkunz
- *     -Vpd bug fixed
- *     -OID_SKGE_MTU added
- *     -pnmi support for dual net mode. Interface function and macros extended
- *
- *     Revision 1.80  2001/01/22 13:41:35  rassmann
- *     Supporting two nets on dual-port adapters.
- *
- *     Revision 1.79  2000/12/05 14:57:40  cgoos
- *     SetStruct failed before first Link Up (link mode of virtual
- *     port "INDETERMINATED").
- *
- *     Revision 1.78  2000/09/12 10:44:58  cgoos
- *     Fixed SK_PNMI_STORE_U32 calls with typecasted argument.
- *
- *     Revision 1.77  2000/09/07 08:10:19  rwahl
- *     - Modified algorithm for 64bit NDIS statistic counters;
- *       returns 64bit or 32bit value depending on passed buffer
- *       size. Indicate capability for 64bit NDIS counter, if passed
- *       buffer size is zero. OID_GEN_XMIT_ERROR, OID_GEN_RCV_ERROR,
- *       and OID_GEN_RCV_NO_BUFFER handled as 64bit counter, too.
- *     - corrected OID_SKGE_RLMT_PORT_PREFERRED.
- *
- *     Revision 1.76  2000/08/03 15:23:39  rwahl
- *     - Correction for FrameTooLong counter has to be moved to OID handling
- *       routines (instead of statistic counter routine).
- *     - Fix in XMAC Reset Event handling: Only offset counter for hardware
- *       statistic registers are updated.
- *
- *     Revision 1.75  2000/08/01 16:46:05  rwahl
- *     - Added StatRxLongFrames counter and correction of FrameTooLong counter.
- *     - Added directive to control width (default = 32bit) of NDIS statistic
- *       counters (SK_NDIS_64BIT_CTR).
- *
- *     Revision 1.74  2000/07/04 11:41:53  rwahl
- *     - Added volition connector type.
- *
- *     Revision 1.73  2000/03/15 16:33:10  rwahl
- *     Fixed bug 10510; wrong reset of virtual port statistic counters.
- *
- *     Revision 1.72  1999/12/06 16:15:53  rwahl
- *     Fixed problem of instance range for current and factory MAC address.
- *
- *     Revision 1.71  1999/12/06 10:14:20  rwahl
- *     Fixed bug 10476; set operation for PHY_OPERATION_MODE.
- *
- *     Revision 1.70  1999/11/22 13:33:34  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.69  1999/10/18 11:42:15  rwahl
- *     Added typecasts for checking event dependent param (debug only).
- *
- *     Revision 1.68  1999/10/06 09:35:59  cgoos
- *     Added state check to PHY_READ call (hanged if called during startup).
- *
- *     Revision 1.67  1999/09/22 09:53:20  rwahl
- *     - Read Broadcom register for updating fcs error counter (1000Base-T).
- *
- *     Revision 1.66  1999/08/26 13:47:56  rwahl
- *     Added SK_DRIVER_SENDEVENT when queueing RLMT_CHANGE_THRES trap.
- *
- *     Revision 1.65  1999/07/26 07:49:35  cgoos
- *     Added two typecasts to avoid compiler warnings.
- *
- *     Revision 1.64  1999/05/20 09:24:12  cgoos
- *     Changes for 1000Base-T (sensors, Master/Slave).
- *
- *     Revision 1.63  1999/04/13 15:11:58  mhaveman
- *     Moved include of rlmt.h to header skgepnmi.h because some macros
- *     are needed there.
- *
- *     Revision 1.62  1999/04/13 15:08:07  mhaveman
- *     Replaced again SK_RLMT_CHECK_LINK with SK_PNMI_RLMT_MODE_CHK_LINK
- *     to grant unified interface by only using the PNMI header file.
- *     SK_PNMI_RLMT_MODE_CHK_LINK is defined the same as SK_RLMT_CHECK_LINK.
- *
- *     Revision 1.61  1999/04/13 15:02:48  mhaveman
- *     Changes caused by review:
- *     -Changed some comments
- *     -Removed redundant check for OID_SKGE_PHYS_FAC_ADDR
- *     -Optimized PRESET check.
- *     -Meaning of error SK_ADDR_DUPLICATE_ADDRESS changed. Set of same
- *      address will now not cause this error. Removed corresponding check.
- *
- *     Revision 1.60  1999/03/23 10:41:23  mhaveman
- *     Added comments.
- *
- *     Revision 1.59  1999/02/19 08:01:28  mhaveman
- *     Fixed bug 10372 that after counter reset all ports were displayed
- *     as inactive.
- *
- *     Revision 1.58  1999/02/16 18:04:47  mhaveman
- *     Fixed problem of twisted OIDs SENSOR_WAR_TIME and SENSOR_ERR_TIME.
- *
- *     Revision 1.56  1999/01/27 12:29:11  mhaveman
- *     SkTimerStart was called with time value in milli seconds but needs
- *     micro seconds.
- *
- *     Revision 1.55  1999/01/25 15:00:38  mhaveman
- *     Added support to allow multiple ports to be active. If this feature in
- *     future will be used, the Management Data Base variables PORT_ACTIVE
- *     and PORT_PREFERED should be moved to the port specific part of RLMT.
- *     Currently they return the values of the first active physical port
- *     found. A set to the virtual port will actually change all active
- *     physical ports. A get returns the melted values of all active physical
- *     ports. If the port values differ a return value INDETERMINATED will
- *     be returned. This effects especially the CONF group.
- *
- *     Revision 1.54  1999/01/19 10:10:22  mhaveman
- *     -Fixed bug 10354: Counter values of virtual port were wrong after port
- *      switches
- *     -Added check if a switch to the same port is notified.
- *
- *     Revision 1.53  1999/01/07 09:25:21  mhaveman
- *     Forgot to initialize a variable.
- *
- *     Revision 1.52  1999/01/05 10:34:33  mhaveman
- *     Fixed little error in RlmtChangeEstimate calculation.
- *
- *     Revision 1.51  1999/01/05 09:59:07  mhaveman
- *     -Moved timer start to init level 2
- *     -Redesigned port switch average calculation to avoid 64bit
- *      arithmetic.
- *
- *     Revision 1.50  1998/12/10 15:13:59  mhaveman
- *     -Fixed: PHYS_CUR_ADDR returned wrong addresses
- *     -Fixed: RLMT_PORT_PREFERED and RLMT_CHANGE_THRES preset returned
- *             always BAD_VALUE.
- *     -Fixed: TRAP buffer seemed to sometimes suddenly empty
- *
- *     Revision 1.49  1998/12/09 16:17:07  mhaveman
- *     Fixed: Couldnot delete VPD keys on UNIX.
- *
- *     Revision 1.48  1998/12/09 14:11:10  mhaveman
- *     -Add: Debugmessage for XMAC_RESET supressed to minimize output.
- *     -Fixed: RlmtChangeThreshold will now be initialized.
- *     -Fixed: VPD_ENTRIES_LIST extended value with unnecessary space char.
- *     -Fixed: On VPD key creation an invalid key name could be created
- *             (e.g. A5)
- *     -Some minor changes in comments and code.
- *
- *     Revision 1.47  1998/12/08 16:00:31  mhaveman
- *     -Fixed: For RLMT_PORT_ACTIVE will now be returned a 0 if no port
- *             is active.
- *     -Fixed: For the RLMT statistics group only the last value was
- *             returned and the rest of the buffer was filled with 0xff
- *     -Fixed: Mysteriously the preset on RLMT_MODE still returned
- *             BAD_VALUE.
- *     Revision 1.46  1998/12/08 10:04:56  mhaveman
- *     -Fixed: Preset on RLMT_MODE returned always BAD_VALUE error.
- *     -Fixed: Alignment error in GetStruct
- *     -Fixed: If for Get/Preset/SetStruct the buffer size is equal or
- *             larger than SK_PNMI_MIN_STRUCT_SIZE the return value is stored
- *             to the buffer. In this case the caller should always return
- *             ok to its upper routines. Only if the buffer size is less
- *             than SK_PNMI_MIN_STRUCT_SIZE and the return value is unequal
- *             to 0, an error should be returned by the caller.
- *     -Fixed: Wrong number of instances with RLMT statistic.
- *     -Fixed: Return now SK_LMODE_STAT_UNKNOWN if the LinkModeStatus is 0.
- *
- *     Revision 1.45  1998/12/03 17:17:24  mhaveman
- *     -Removed for VPD create action the buffer size limitation to 4 bytes.
- *     -Pass now physical/active physical port to ADDR for CUR_ADDR set
- *
- *     Revision 1.44  1998/12/03 15:14:35  mhaveman
- *     Another change to Vpd instance evaluation.
- *
- *     Revision 1.43  1998/12/03 14:18:10  mhaveman
- *     -Fixed problem in PnmiSetStruct. It was impossible to set any value.
- *     -Removed VPD key evaluation for VPD_FREE_BYTES and VPD_ACTION.
- *
- *     Revision 1.42  1998/12/03 11:31:47  mhaveman
- *     Inserted cast to satisfy lint.
- *
- *     Revision 1.41  1998/12/03 11:28:16  mhaveman
- *     Removed SK_PNMI_CHECKPTR
- *
- *     Revision 1.40  1998/12/03 11:19:07  mhaveman
- *     Fixed problems
- *     -A set to virtual port will now be ignored. A set with broadcast
- *      address to any port will be ignored.
- *     -GetStruct function made VPD instance calculation wrong.
- *     -Prefered port returned -1 instead of 0.
- *
- *     Revision 1.39  1998/11/26 15:30:29  mhaveman
- *     Added sense mode to link mode.
- *
- *     Revision 1.38  1998/11/23 15:34:00  mhaveman
- *     -Fixed bug for RX counters. On an RX overflow interrupt the high
- *      words of all RX counters were incremented.
- *     -SET operations on FLOWCTRL_MODE and LINK_MODE accept now the
- *      value 0, which has no effect. It is usefull for multiple instance
- *      SETs.
- *
- *     Revision 1.37  1998/11/20 08:02:04  mhaveman
- *     -Fixed: Ports were compared with MAX_SENSORS
- *     -Fixed: Crash in GetTrapEntry with MEMSET macro
- *     -Fixed: Conversions between physical, logical port index and instance
- *
- *     Revision 1.36  1998/11/16 07:48:53  mhaveman
- *     Casted SK_DRIVER_SENDEVENT with (void) to eleminate compiler warnings
- *     on Solaris.
- *
- *     Revision 1.35  1998/11/16 07:45:34  mhaveman
- *     SkAddrOverride now returns value and will be checked.
- *
- *     Revision 1.34  1998/11/10 13:40:37  mhaveman
- *     Needed to change interface, because NT driver needs a return value
- *     of needed buffer space on TOO_SHORT errors. Therefore all
- *     SkPnmiGet/Preset/Set functions now have a pointer to the length
- *     parameter, where the needed space on error is returned.
- *
- *     Revision 1.33  1998/11/03 13:52:46  mhaveman
- *     Made file lint conform.
- *
- *     Revision 1.32  1998/11/03 13:19:07  mhaveman
- *     The events SK_HWEV_SET_LMODE and SK_HWEV_SET_FLOWMODE pass now in
- *     Para32[0] the physical MAC index and in Para32[1] the new mode.
- *
- *     Revision 1.31  1998/11/03 12:30:40  gklug
- *     fix: compiler warning memset
- *
- *     Revision 1.30  1998/11/03 12:04:46  mhaveman
- *     Fixed problem in SENSOR_VALUE, which wrote beyond the buffer end
- *     Fixed alignment problem with CHIPSET.
- *
- *     Revision 1.29  1998/11/02 11:23:54  mhaveman
- *     Corrected SK_ERROR_LOG to SK_ERR_LOG. Sorry.
- *
- *     Revision 1.28  1998/11/02 10:47:16  mhaveman
- *     Added syslog messages for internal errors.
- *
- *     Revision 1.27  1998/10/30 15:48:06  mhaveman
- *     Fixed problems after simulation of SK_PNMI_EVT_CHG_EST_TIMER and
- *     RlmtChangeThreshold calculation.
- *
- *     Revision 1.26  1998/10/29 15:36:55  mhaveman
- *     -Fixed bug in trap buffer handling.
- *     -OID_SKGE_DRIVER_DESCR, OID_SKGE_DRIVER_VERSION, OID_SKGE_HW_DESCR,
- *      OID_SKGE_HW_VERSION, OID_SKGE_VPD_ENTRIES_LIST, OID_SKGE_VPD_KEY,
- *      OID_SKGE_VPD_VALUE, and OID_SKGE_SENSOR_DESCR return values with
- *      a leading octet before each string storing the string length.
- *     -Perform a RlmtUpdate during SK_PNMI_EVT_XMAC_RESET to minimize
- *      RlmtUpdate calls in GetStatVal.
- *     -Inserted SK_PNMI_CHECKFLAGS macro increase readability.
- *
- *     Revision 1.25  1998/10/29 08:50:36  mhaveman
- *     Fixed problems after second event simulation.
- *
- *     Revision 1.24  1998/10/28 08:44:37  mhaveman
- *     -Fixed alignment problem
- *     -Fixed problems during event simulation
- *     -Fixed sequence of error return code (INSTANCE -> ACCESS -> SHORT)
- *     -Changed type of parameter Instance back to SK_U32 because of VPD
- *     -Updated new VPD function calls
- *
- *     Revision 1.23  1998/10/23 10:16:37  mhaveman
- *     Fixed bugs after buffer test simulation.
- *
- *     Revision 1.22  1998/10/21 13:23:52  mhaveman
- *     -Call syntax of SkOsGetTime() changed to SkOsGetTime(pAc).
- *     -Changed calculation of hundrets of seconds.
- *
- *     Revision 1.20  1998/10/20 07:30:45  mhaveman
- *     Made type changes to unsigned integer where possible.
- *
- *     Revision 1.19  1998/10/19 10:51:30  mhaveman
- *     -Made Bug fixes after simulation run
- *     -Renamed RlmtMAC... to RlmtPort...
- *     -Marked workarounds with Errata comments
- *
- *     Revision 1.18  1998/10/14 07:50:08  mhaveman
- *     -For OID_SKGE_LINK_STATUS the link down detection has moved from RLMT
- *      to HWACCESS.
- *     -Provided all MEMCPY/MEMSET macros with (char *) pointers, because
- *      Solaris throwed warnings when mapping to bcopy/bset.
- *
- *     Revision 1.17  1998/10/13 07:42:01  mhaveman
- *     -Added OIDs OID_SKGE_TRAP_NUMBER and OID_SKGE_ALL_DATA
- *     -Removed old cvs history entries
- *     -Renamed MacNumber to PortNumber
- *
- *     Revision 1.16  1998/10/07 10:52:49  mhaveman
- *     -Inserted handling of some OID_GEN_ Ids for windows
- *     -Fixed problem with 803.2 statistic.
- *
- *     Revision 1.15  1998/10/01 09:16:29  mhaveman
- *     Added Debug messages for function call and UpdateFlag tracing.
- *
- *     Revision 1.14  1998/09/30 13:39:09  mhaveman
- *     -Reduced namings of 'MAC' by replacing them with 'PORT'.
- *     -Completed counting of OID_SKGE_RX_HW_ERROR_CTS,
- *       OID_SKGE_TX_HW_ERROR_CTS,
- *      OID_SKGE_IN_ERRORS_CTS, and OID_SKGE_OUT_ERROR_CTS.
- *     -SET check for RlmtMode
- *
- *     Revision 1.13  1998/09/28 13:13:08  mhaveman
- *     Hide strcmp, strlen, and strncpy behind macros SK_STRCMP, SK_STRLEN,
- *     and SK_STRNCPY. (Same reasons as for mem.. and MEM..)
- *
- *     Revision 1.12  1998/09/16 08:18:36  cgoos
- *     Fix: XM_INxx and XM_OUTxx called with different parameter order:
- *      sometimes IoC,Mac,...  sometimes Mac,IoC,... Now always first variant.
- *     Fix: inserted "Pnmi." into some pAC->pDriverDescription / Version.
- *     Change: memset, memcpy to makros SK_MEMSET, SK_MEMCPY
- *
- *     Revision 1.11  1998/09/04 17:01:45  mhaveman
- *     Added SyncCounter as macro and OID_SKGE_.._NO_DESCR_CTS to
- *     OID_SKGE_RX_NO_BUF_CTS.
- *
- *     Revision 1.10  1998/09/04 14:35:35  mhaveman
- *     Added macro counters, that are counted by driver.
- *
- ****************************************************************************/
-
-
-#include <config.h>
-
-#ifdef CONFIG_SK98
-
-static const char SysKonnectFileId[] =
-       "@(#) $Id: skgepnmi.c,v 1.102 2002/12/16 14:03:24 tschilli Exp $"
-       " (C) SysKonnect.";
-
-#include "h/skdrv1st.h"
-#include "h/sktypes.h"
-#include "h/xmac_ii.h"
-#include "h/skdebug.h"
-#include "h/skqueue.h"
-#include "h/skgepnmi.h"
-#include "h/skgesirq.h"
-#include "h/skcsum.h"
-#include "h/skvpd.h"
-#include "h/skgehw.h"
-#include "h/skgeinit.h"
-#include "h/skdrv2nd.h"
-#include "h/skgepnm2.h"
-#ifdef SK_POWER_MGMT
-#include "h/skgepmgt.h"
-#endif
-/* defines *******************************************************************/
-
-#ifndef DEBUG
-#define PNMI_STATIC    static
-#else  /* DEBUG */
-#define PNMI_STATIC
-#endif /* DEBUG */
-
-/*
- * Public Function prototypes
- */
-int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
-int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
-       unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
-int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
-       unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
-int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
-       unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
-int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
-       unsigned int *pLen, SK_U32 NetIndex);
-int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
-       unsigned int *pLen, SK_U32 NetIndex);
-int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
-       unsigned int *pLen, SK_U32 NetIndex);
-int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
-
-
-/*
- * Private Function prototypes
- */
-
-PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
-       PhysPortIndex);
-PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
-       PhysPortIndex);
-PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
-PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
-PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
-       unsigned int PhysPortIndex, unsigned int StatIndex);
-PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
-       unsigned int StatIndex, SK_U32 NetIndex);
-PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
-PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
-       unsigned int *pEntries);
-PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
-       unsigned int KeyArrLen, unsigned int *pKeyNo);
-PNMI_STATIC int LookupId(SK_U32 Id);
-PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
-       unsigned int LastMac);
-PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
-       unsigned int *pLen, SK_U32 NetIndex);
-PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
-PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
-PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
-       unsigned int PortIndex);
-PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
-       unsigned int SensorIndex);
-PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
-PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
-PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
-PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
-PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
-PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
-       unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
-
-/*
- * Table to correlate OID with handler function and index to
- * hardware register stored in StatAddress if applicable.
- */
-#include "skgemib.c"
-
-/* global variables **********************************************************/
-
-/*
- * Overflow status register bit table and corresponding counter
- * dependent on MAC type - the number relates to the size of overflow
- * mask returned by the pFnMacOverflow function
- */
-PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
-/* Bit0  */    { SK_PNMI_HTX,                          SK_PNMI_HTX_UNICAST},
-/* Bit1  */    { SK_PNMI_HTX_OCTETHIGH,        SK_PNMI_HTX_BROADCAST},
-/* Bit2  */    { SK_PNMI_HTX_OCTETLOW,         SK_PNMI_HTX_PMACC},
-/* Bit3  */    { SK_PNMI_HTX_BROADCAST,        SK_PNMI_HTX_MULTICAST},
-/* Bit4  */    { SK_PNMI_HTX_MULTICAST,        SK_PNMI_HTX_OCTETLOW},
-/* Bit5  */    { SK_PNMI_HTX_UNICAST,          SK_PNMI_HTX_OCTETHIGH},
-/* Bit6  */    { SK_PNMI_HTX_LONGFRAMES,       SK_PNMI_HTX_64},
-/* Bit7  */    { SK_PNMI_HTX_BURST,            SK_PNMI_HTX_127},
-/* Bit8  */    { SK_PNMI_HTX_PMACC,            SK_PNMI_HTX_255},
-/* Bit9  */    { SK_PNMI_HTX_MACC,             SK_PNMI_HTX_511},
-/* Bit10 */    { SK_PNMI_HTX_SINGLE_COL,       SK_PNMI_HTX_1023},
-/* Bit11 */    { SK_PNMI_HTX_MULTI_COL,        SK_PNMI_HTX_MAX},
-/* Bit12 */    { SK_PNMI_HTX_EXCESS_COL,       SK_PNMI_HTX_LONGFRAMES},
-/* Bit13 */    { SK_PNMI_HTX_LATE_COL,         SK_PNMI_HTX_RESERVED},
-/* Bit14 */    { SK_PNMI_HTX_DEFFERAL,         SK_PNMI_HTX_COL},
-/* Bit15 */    { SK_PNMI_HTX_EXCESS_DEF,       SK_PNMI_HTX_LATE_COL},
-/* Bit16 */    { SK_PNMI_HTX_UNDERRUN,         SK_PNMI_HTX_EXCESS_COL},
-/* Bit17 */    { SK_PNMI_HTX_CARRIER,          SK_PNMI_HTX_MULTI_COL},
-/* Bit18 */    { SK_PNMI_HTX_UTILUNDER,        SK_PNMI_HTX_SINGLE_COL},
-/* Bit19 */    { SK_PNMI_HTX_UTILOVER,         SK_PNMI_HTX_UNDERRUN},
-/* Bit20 */    { SK_PNMI_HTX_64,                       SK_PNMI_HTX_RESERVED},
-/* Bit21 */    { SK_PNMI_HTX_127,                      SK_PNMI_HTX_RESERVED},
-/* Bit22 */    { SK_PNMI_HTX_255,                      SK_PNMI_HTX_RESERVED},
-/* Bit23 */    { SK_PNMI_HTX_511,                      SK_PNMI_HTX_RESERVED},
-/* Bit24 */    { SK_PNMI_HTX_1023,             SK_PNMI_HTX_RESERVED},
-/* Bit25 */    { SK_PNMI_HTX_MAX,                      SK_PNMI_HTX_RESERVED},
-/* Bit26 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
-/* Bit27 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
-/* Bit28 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
-/* Bit29 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
-/* Bit30 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
-/* Bit31 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
-/* Bit32 */    { SK_PNMI_HRX,                          SK_PNMI_HRX_UNICAST},
-/* Bit33 */    { SK_PNMI_HRX_OCTETHIGH,        SK_PNMI_HRX_BROADCAST},
-/* Bit34 */    { SK_PNMI_HRX_OCTETLOW,         SK_PNMI_HRX_PMACC},
-/* Bit35 */    { SK_PNMI_HRX_BROADCAST,        SK_PNMI_HRX_MULTICAST},
-/* Bit36 */    { SK_PNMI_HRX_MULTICAST,        SK_PNMI_HRX_FCS},
-/* Bit37 */    { SK_PNMI_HRX_UNICAST,          SK_PNMI_HRX_RESERVED},
-/* Bit38 */    { SK_PNMI_HRX_PMACC,            SK_PNMI_HRX_OCTETLOW},
-/* Bit39 */    { SK_PNMI_HRX_MACC,             SK_PNMI_HRX_OCTETHIGH},
-/* Bit40 */    { SK_PNMI_HRX_PMACC_ERR,        SK_PNMI_HRX_BADOCTETLOW},
-/* Bit41 */    { SK_PNMI_HRX_MACC_UNKWN,       SK_PNMI_HRX_BADOCTETHIGH},
-/* Bit42 */    { SK_PNMI_HRX_BURST,            SK_PNMI_HRX_UNDERSIZE},
-/* Bit43 */    { SK_PNMI_HRX_MISSED,           SK_PNMI_HRX_RUNT},
-/* Bit44 */    { SK_PNMI_HRX_FRAMING,          SK_PNMI_HRX_64},
-/* Bit45 */    { SK_PNMI_HRX_OVERFLOW,         SK_PNMI_HRX_127},
-/* Bit46 */    { SK_PNMI_HRX_JABBER,           SK_PNMI_HRX_255},
-/* Bit47 */    { SK_PNMI_HRX_CARRIER,          SK_PNMI_HRX_511},
-/* Bit48 */    { SK_PNMI_HRX_IRLENGTH,         SK_PNMI_HRX_1023},
-/* Bit49 */    { SK_PNMI_HRX_SYMBOL,           SK_PNMI_HRX_MAX},
-/* Bit50 */    { SK_PNMI_HRX_SHORTS,           SK_PNMI_HRX_LONGFRAMES},
-/* Bit51 */    { SK_PNMI_HRX_RUNT,             SK_PNMI_HRX_TOO_LONG},
-/* Bit52 */    { SK_PNMI_HRX_TOO_LONG,         SK_PNMI_HRX_JABBER},
-/* Bit53 */    { SK_PNMI_HRX_FCS,                      SK_PNMI_HRX_RESERVED},
-/* Bit54 */    { SK_PNMI_HRX_RESERVED,         SK_PNMI_HRX_OVERFLOW},
-/* Bit55 */    { SK_PNMI_HRX_CEXT,             SK_PNMI_HRX_RESERVED},
-/* Bit56 */    { SK_PNMI_HRX_UTILUNDER,        SK_PNMI_HRX_RESERVED},
-/* Bit57 */    { SK_PNMI_HRX_UTILOVER,         SK_PNMI_HRX_RESERVED},
-/* Bit58 */    { SK_PNMI_HRX_64,                       SK_PNMI_HRX_RESERVED},
-/* Bit59 */    { SK_PNMI_HRX_127,                      SK_PNMI_HRX_RESERVED},
-/* Bit60 */    { SK_PNMI_HRX_255,                      SK_PNMI_HRX_RESERVED},
-/* Bit61 */    { SK_PNMI_HRX_511,                      SK_PNMI_HRX_RESERVED},
-/* Bit62 */    { SK_PNMI_HRX_1023,             SK_PNMI_HRX_RESERVED},
-/* Bit63 */    { SK_PNMI_HRX_MAX,                      SK_PNMI_HRX_RESERVED}
-};
-
-/*
- * Table for hardware register saving on resets and port switches
- */
-PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
-       /* SK_PNMI_HTX */
-       {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_OCTETHIGH */
-       {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
-       /* SK_PNMI_HTX_OCTETLOW */
-       {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
-       /* SK_PNMI_HTX_BROADCAST */
-       {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
-       /* SK_PNMI_HTX_MULTICAST */
-       {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
-       /* SK_PNMI_HTX_UNICAST */
-       {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
-       /* SK_PNMI_HTX_BURST */
-       {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_PMACC */
-       {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
-       /* SK_PNMI_HTX_MACC */
-       {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_COL */
-       {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
-       /* SK_PNMI_HTX_SINGLE_COL */
-       {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
-       /* SK_PNMI_HTX_MULTI_COL */
-       {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
-       /* SK_PNMI_HTX_EXCESS_COL */
-       {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
-       /* SK_PNMI_HTX_LATE_COL */
-       {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
-       /* SK_PNMI_HTX_DEFFERAL */
-       {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_EXCESS_DEF */
-       {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_UNDERRUN */
-       {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
-       /* SK_PNMI_HTX_CARRIER */
-       {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_UTILUNDER */
-       {{0, SK_FALSE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_UTILOVER */
-       {{0, SK_FALSE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_64 */
-       {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
-       /* SK_PNMI_HTX_127 */
-       {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
-       /* SK_PNMI_HTX_255 */
-       {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
-       /* SK_PNMI_HTX_511 */
-       {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
-       /* SK_PNMI_HTX_1023 */
-       {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
-       /* SK_PNMI_HTX_MAX */
-       {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
-       /* SK_PNMI_HTX_LONGFRAMES  */
-       {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
-       /* SK_PNMI_HTX_SYNC */
-       {{0, SK_FALSE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_SYNC_OCTET */
-       {{0, SK_FALSE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_RESERVED */
-       {{0, SK_FALSE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX */
-       {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_OCTETHIGH */
-       {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
-       /* SK_PNMI_HRX_OCTETLOW */
-       {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
-       /* SK_PNMI_HRX_BADOCTETHIGH */
-       {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
-       /* SK_PNMI_HRX_BADOCTETLOW */
-       {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
-       /* SK_PNMI_HRX_BROADCAST */
-       {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
-       /* SK_PNMI_HRX_MULTICAST */
-       {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
-       /* SK_PNMI_HRX_UNICAST */
-       {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
-       /* SK_PNMI_HRX_PMACC */
-       {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
-       /* SK_PNMI_HRX_MACC */
-       {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_PMACC_ERR */
-       {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_MACC_UNKWN */
-       {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_BURST */
-       {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_MISSED */
-       {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_FRAMING */
-       {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_UNDERSIZE */
-       {{0, SK_FALSE},{GM_RXF_SHT, SK_TRUE}},
-       /* SK_PNMI_HRX_OVERFLOW */
-       {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
-       /* SK_PNMI_HRX_JABBER */
-       {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
-       /* SK_PNMI_HRX_CARRIER */
-       {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_IRLENGTH */
-       {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_SYMBOL */
-       {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_SHORTS */
-       {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_RUNT */
-       {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
-       /* SK_PNMI_HRX_TOO_LONG */
-       {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
-       /* SK_PNMI_HRX_FCS */
-       {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
-       /* SK_PNMI_HRX_CEXT */
-       {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_UTILUNDER */
-       {{0, SK_FALSE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_UTILOVER */
-       {{0, SK_FALSE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_64 */
-       {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
-       /* SK_PNMI_HRX_127 */
-       {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
-       /* SK_PNMI_HRX_255 */
-       {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
-       /* SK_PNMI_HRX_511 */
-       {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
-       /* SK_PNMI_HRX_1023 */
-       {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
-       /* SK_PNMI_HRX_MAX */
-       {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
-       /* SK_PNMI_HRX_LONGFRAMES */
-       {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
-       /* SK_PNMI_HRX_RESERVED */
-       {{0, SK_FALSE}, {0, SK_FALSE}}
-};
-
-
-/*****************************************************************************
- *
- * Public functions
- *
- */
-
-/*****************************************************************************
- *
- * SkPnmiInit - Init function of PNMI
- *
- * Description:
- *     SK_INIT_DATA: Initialises the data structures
- *     SK_INIT_IO:   Resets the XMAC statistics, determines the device and
- *                   connector type.
- *     SK_INIT_RUN:  Starts a timer event for port switch per hour
- *                   calculation.
- *
- * Returns:
- *     Always 0
- */
-int SkPnmiInit(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Level)             /* Initialization level */
-{
-       unsigned int    PortMax;        /* Number of ports */
-       unsigned int    PortIndex;      /* Current port index in loop */
-       SK_U16          Val16;          /* Multiple purpose 16 bit variable */
-       SK_U8           Val8;           /* Mulitple purpose 8 bit variable */
-       SK_EVPARA       EventParam;     /* Event struct for timer event */
-       SK_GEPORT       *pPrt;
-       SK_PNMI_VCT     *pVctBackupData;
-
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-               ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
-
-       switch (Level) {
-
-       case SK_INIT_DATA:
-               SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
-               pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
-               pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
-               pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
-               for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
-
-                       pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
-                       pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
-               }
-
-#ifdef SK_PNMI_CHECK
-               if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
-                                          ("CounterOffset struct size (%d) differs from"
-                                               "SK_PNMI_MAX_IDX (%d)\n",
-                                               SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
-                       BRK;
-               }
-
-               if (SK_PNMI_MAX_IDX !=
-                       (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
-                                          ("StatAddr table size (%d) differs from "
-                                               "SK_PNMI_MAX_IDX (%d)\n",
-                                               (sizeof(StatAddr) /
-                                                (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
-                                                SK_PNMI_MAX_IDX));
-                       BRK;
-               }
-#endif /* SK_PNMI_CHECK */
-               break;
-
-       case SK_INIT_IO:
-               /*
-                * Reset MAC counters
-                */
-               PortMax = pAC->GIni.GIMacsFound;
-
-               for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
-
-                       pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
-               }
-
-               /* Initialize DSP variables for Vct() to 0xff => Never written! */
-               for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
-                       pPrt = &pAC->GIni.GP[PortIndex];
-                       pPrt->PCableLen =0xff;
-                       pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
-                       pVctBackupData->PCableLen = 0xff;
-               }
-
-               /*
-                * Get pci bus speed
-                */
-               SK_IN16(IoC, B0_CTST, &Val16);
-               if ((Val16 & CS_BUS_CLOCK) == 0) {
-
-                       pAC->Pnmi.PciBusSpeed = 33;
-               }
-               else {
-                       pAC->Pnmi.PciBusSpeed = 66;
-               }
-
-               /*
-                * Get pci bus width
-                */
-               SK_IN16(IoC, B0_CTST, &Val16);
-               if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
-
-                       pAC->Pnmi.PciBusWidth = 32;
-               }
-               else {
-                       pAC->Pnmi.PciBusWidth = 64;
-               }
-
-               /*
-                * Get chipset
-                */
-               switch (pAC->GIni.GIChipId) {
-               case CHIP_ID_GENESIS:
-                       pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
-                       break;
-
-               case CHIP_ID_YUKON:
-                       pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
-                       break;
-
-               default:
-                       break;
-               }
-
-               /*
-                * Get PMD and DeviceType
-                */
-               SK_IN8(IoC, B2_PMD_TYP, &Val8);
-               switch (Val8) {
-               case 'S':
-                       pAC->Pnmi.PMD = 3;
-                       if (pAC->GIni.GIMacsFound > 1) {
-
-                               pAC->Pnmi.DeviceType = 0x00020002;
-                       }
-                       else {
-                               pAC->Pnmi.DeviceType = 0x00020001;
-                       }
-                       break;
-
-               case 'L':
-                       pAC->Pnmi.PMD = 2;
-                       if (pAC->GIni.GIMacsFound > 1) {
-
-                               pAC->Pnmi.DeviceType = 0x00020004;
-                       }
-                       else {
-                               pAC->Pnmi.DeviceType = 0x00020003;
-                       }
-                       break;
-
-               case 'C':
-                       pAC->Pnmi.PMD = 4;
-                       if (pAC->GIni.GIMacsFound > 1) {
-
-                               pAC->Pnmi.DeviceType = 0x00020006;
-                       }
-                       else {
-                               pAC->Pnmi.DeviceType = 0x00020005;
-                       }
-                       break;
-
-               case 'T':
-                       pAC->Pnmi.PMD = 5;
-                       if (pAC->GIni.GIMacsFound > 1) {
-
-                               pAC->Pnmi.DeviceType = 0x00020008;
-                       }
-                       else {
-                               pAC->Pnmi.DeviceType = 0x00020007;
-                       }
-                       break;
-
-               default :
-                       pAC->Pnmi.PMD = 1;
-                       pAC->Pnmi.DeviceType = 0;
-                       break;
-               }
-
-               /*
-                * Get connector
-                */
-               SK_IN8(IoC, B2_CONN_TYP, &Val8);
-               switch (Val8) {
-               case 'C':
-                       pAC->Pnmi.Connector = 2;
-                       break;
-
-               case 'D':
-                       pAC->Pnmi.Connector = 3;
-                       break;
-
-               case 'F':
-                       pAC->Pnmi.Connector = 4;
-                       break;
-
-               case 'J':
-                       pAC->Pnmi.Connector = 5;
-                       break;
-
-               case 'V':
-                       pAC->Pnmi.Connector = 6;
-                       break;
-
-               default:
-                       pAC->Pnmi.Connector = 1;
-                       break;
-               }
-               break;
-
-       case SK_INIT_RUN:
-               /*
-                * Start timer for RLMT change counter
-                */
-               SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
-               SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
-                       28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
-                       EventParam);
-               break;
-
-       default:
-               break; /* Nothing todo */
-       }
-
-       return (0);
-}
-
-/*****************************************************************************
- *
- * SkPnmiGetVar - Retrieves the value of a single OID
- *
- * Description:
- *     Calls a general sub-function for all this stuff. If the instance
- *     -1 is passed, the values of all instances are returned in an
- *     array of values.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
- *                              the data.
- *     SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-int SkPnmiGetVar(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-SK_U32 Id,             /* Object ID that is to be processed */
-void *pBuf,            /* Buffer to which to mgmt data will be retrieved */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-               ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
-                       Id, *pLen, Instance, NetIndex));
-
-       return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
-               Instance, NetIndex));
-}
-
-/*****************************************************************************
- *
- * SkPnmiPreSetVar - Presets the value of a single OID
- *
- * Description:
- *     Calls a general sub-function for all this stuff. The preset does
- *     the same as a set, but returns just before finally setting the
- *     new value. This is usefull to check if a set might be successfull.
- *     If as instance a -1 is passed, an array of values is supposed and
- *     all instance of the OID will be set.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-int SkPnmiPreSetVar(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-SK_U32 Id,             /* Object ID that is to be processed */
-void *pBuf,            /* Buffer which stores the mgmt data to be set */
-unsigned int *pLen,    /* Total length of mgmt data */
-SK_U32 Instance,       /* Instance (1..n) that is to be set or -1 */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-               ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
-                       Id, *pLen, Instance, NetIndex));
-
-
-       return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
-               Instance, NetIndex));
-}
-
-/*****************************************************************************
- *
- * SkPnmiSetVar - Sets the value of a single OID
- *
- * Description:
- *     Calls a general sub-function for all this stuff. The preset does
- *     the same as a set, but returns just before finally setting the
- *     new value. This is usefull to check if a set might be successfull.
- *     If as instance a -1 is passed, an array of values is supposed and
- *     all instance of the OID will be set.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-int SkPnmiSetVar(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-SK_U32 Id,             /* Object ID that is to be processed */
-void *pBuf,            /* Buffer which stores the mgmt data to be set */
-unsigned int *pLen,    /* Total length of mgmt data */
-SK_U32 Instance,       /* Instance (1..n) that is to be set or -1 */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-               ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
-                       Id, *pLen, Instance, NetIndex));
-
-       return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
-               Instance, NetIndex));
-}
-
-/*****************************************************************************
- *
- * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
- *
- * Description:
- *     Runs through the IdTable, queries the single OIDs and stores the
- *     returned data into the management database structure
- *     SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
- *     is stored in the IdTable. The return value of the function will also
- *     be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
- *     minimum size of SK_PNMI_MIN_STRUCT_SIZE.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
- *                              the data.
- *     SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
- */
-int SkPnmiGetStruct(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-void *pBuf,            /* Buffer which will store the retrieved data */
-unsigned int *pLen,    /* Length of buffer */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       int             Ret;
-       unsigned int    TableIndex;
-       unsigned int    DstOffset;
-       unsigned int    InstanceNo;
-       unsigned int    InstanceCnt;
-       SK_U32          Instance;
-       unsigned int    TmpLen;
-       char            KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
-
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-               ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
-                       *pLen, NetIndex));
-
-       if (*pLen < SK_PNMI_STRUCT_SIZE) {
-
-               if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
-
-                       SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
-                               (SK_U32)(-1));
-               }
-
-               *pLen = SK_PNMI_STRUCT_SIZE;
-               return (SK_PNMI_ERR_TOO_SHORT);
-       }
-
-    /*
-     * Check NetIndex
-     */
-       if (NetIndex >= pAC->Rlmt.NumNets) {
-               return (SK_PNMI_ERR_UNKNOWN_NET);
-       }
-
-       /* Update statistic */
-       SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
-
-       if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
-               SK_PNMI_ERR_OK) {
-
-               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
-               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-               return (Ret);
-       }
-
-       if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
-
-               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
-               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-               return (Ret);
-       }
-
-       if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
-
-               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
-               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-               return (Ret);
-       }
-
-       /*
-        * Increment semaphores to indicate that an update was
-        * already done
-        */
-       pAC->Pnmi.MacUpdatedFlag ++;
-       pAC->Pnmi.RlmtUpdatedFlag ++;
-       pAC->Pnmi.SirqUpdatedFlag ++;
-
-       /* Get vpd keys for instance calculation */
-       Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
-       if (Ret != SK_PNMI_ERR_OK) {
-
-               pAC->Pnmi.MacUpdatedFlag --;
-               pAC->Pnmi.RlmtUpdatedFlag --;
-               pAC->Pnmi.SirqUpdatedFlag --;
-
-               SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
-               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
-               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-               return (SK_PNMI_ERR_GENERAL);
-       }
-
-       /* Retrieve values */
-       SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
-       for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
-
-               InstanceNo = IdTable[TableIndex].InstanceNo;
-               for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
-                       InstanceCnt ++) {
-
-                       DstOffset = IdTable[TableIndex].Offset +
-                               (InstanceCnt - 1) *
-                               IdTable[TableIndex].StructSize;
-
-                       /*
-                        * For the VPD the instance is not an index number
-                        * but the key itself. Determin with the instance
-                        * counter the VPD key to be used.
-                        */
-                       if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
-                               IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
-                               IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
-                               IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
-
-                               SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
-                       }
-                       else {
-                               Instance = (SK_U32)InstanceCnt;
-                       }
-
-                       TmpLen = *pLen - DstOffset;
-                       Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
-                               IdTable[TableIndex].Id, (char *)pBuf +
-                               DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
-
-                       /*
-                        * An unknown instance error means that we reached
-                        * the last instance of that variable. Proceed with
-                        * the next OID in the table and ignore the return
-                        * code.
-                        */
-                       if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
-
-               break;
-                       }
-
-                       if (Ret != SK_PNMI_ERR_OK) {
-
-                               pAC->Pnmi.MacUpdatedFlag --;
-                               pAC->Pnmi.RlmtUpdatedFlag --;
-                               pAC->Pnmi.SirqUpdatedFlag --;
-
-                               SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
-                               SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
-                               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-                               return (Ret);
-                       }
-               }
-       }
-
-       pAC->Pnmi.MacUpdatedFlag --;
-       pAC->Pnmi.RlmtUpdatedFlag --;
-       pAC->Pnmi.SirqUpdatedFlag --;
-
-       *pLen = SK_PNMI_STRUCT_SIZE;
-       SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
-       SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
- *
- * Description:
- *     Calls a general sub-function for all this set stuff. The preset does
- *     the same as a set, but returns just before finally setting the
- *     new value. This is usefull to check if a set might be successfull.
- *     The sub-function runs through the IdTable, checks which OIDs are able
- *     to set, and calls the handler function of the OID to perform the
- *     preset. The return value of the function will also be stored in
- *     SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
- *     SK_PNMI_MIN_STRUCT_SIZE.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- */
-int SkPnmiPreSetStruct(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-void *pBuf,            /* Buffer which contains the data to be set */
-unsigned int *pLen,    /* Length of buffer */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-               ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
-                       *pLen, NetIndex));
-
-       return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
-                                       pLen, NetIndex));
-}
-
-/*****************************************************************************
- *
- * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
- *
- * Description:
- *     Calls a general sub-function for all this set stuff. The return value
- *     of the function will also be stored in SK_PNMI_STRUCT_DATA if the
- *     passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
- *     The sub-function runs through the IdTable, checks which OIDs are able
- *     to set, and calls the handler function of the OID to perform the
- *     set. The return value of the function will also be stored in
- *     SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
- *     SK_PNMI_MIN_STRUCT_SIZE.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- */
-int SkPnmiSetStruct(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-void *pBuf,            /* Buffer which contains the data to be set */
-unsigned int *pLen,    /* Length of buffer */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-               ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
-                       *pLen, NetIndex));
-
-       return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
-                                       pLen, NetIndex));
-}
-
-/*****************************************************************************
- *
- * SkPnmiEvent - Event handler
- *
- * Description:
- *     Handles the following events:
- *     SK_PNMI_EVT_SIRQ_OVERFLOW     When a hardware counter overflows an
- *                                   interrupt will be generated which is
- *                                   first handled by SIRQ which generates a
- *                                   this event. The event increments the
- *                                   upper 32 bit of the 64 bit counter.
- *     SK_PNMI_EVT_SEN_XXX           The event is generated by the I2C module
- *                                   when a sensor reports a warning or
- *                                   error. The event will store a trap
- *                                   message in the trap buffer.
- *     SK_PNMI_EVT_CHG_EST_TIMER     The timer event was initiated by this
- *                                   module and is used to calculate the
- *                                   port switches per hour.
- *     SK_PNMI_EVT_CLEAR_COUNTER     The event clears all counters and
- *                                   timestamps.
- *     SK_PNMI_EVT_XMAC_RESET        The event is generated by the driver
- *                                   before a hard reset of the XMAC is
- *                                   performed. All counters will be saved
- *                                   and added to the hardware counter
- *                                   values after reset to grant continuous
- *                                   counter values.
- *     SK_PNMI_EVT_RLMT_PORT_UP      Generated by RLMT to notify that a port
- *                                   went logically up. A trap message will
- *                                   be stored to the trap buffer.
- *     SK_PNMI_EVT_RLMT_PORT_DOWN    Generated by RLMT to notify that a port
- *                                   went logically down. A trap message will
- *                                   be stored to the trap buffer.
- *     SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
- *                                   spanning tree root bridges were
- *                                   detected. A trap message will be stored
- *                                   to the trap buffer.
- *     SK_PNMI_EVT_RLMT_ACTIVE_DOWN  Notifies PNMI that an active port went
- *                                   down. PNMI will not further add the
- *                                   statistic values to the virtual port.
- *     SK_PNMI_EVT_RLMT_ACTIVE_UP    Notifies PNMI that a port went up and
- *                                   is now an active port. PNMI will now
- *                                   add the statistic data of this port to
- *                                   the virtual port.
- *     SK_PNMI_EVT_RLMT_SET_NETS     Notifies PNMI about the net mode. The first Parameter
- *                                   contains the number of nets. 1 means single net, 2 means
- *                                   dual net. The second Parameter is -1
- *
- * Returns:
- *     Always 0
- */
-int SkPnmiEvent(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-SK_U32 Event,          /* Event-Id */
-SK_EVPARA Param)       /* Event dependent parameter */
-{
-       unsigned int    PhysPortIndex;
-       unsigned int    MaxNetNumber;
-       int                     CounterIndex;
-       int                     Ret;
-       SK_U16          MacStatus;
-       SK_U64          OverflowStatus;
-       SK_U64          Mask;
-       int                     MacType;
-       SK_U64          Value;
-       SK_U32          Val32;
-       SK_U16          Register;
-       SK_EVPARA       EventParam;
-       SK_U64          NewestValue;
-       SK_U64          OldestValue;
-       SK_U64          Delta;
-       SK_PNMI_ESTIMATE *pEst;
-       SK_U32          NetIndex;
-       SK_GEPORT       *pPrt;
-       SK_PNMI_VCT     *pVctBackupData;
-       SK_U32          RetCode;
-       int             i;
-       SK_U32          CableLength;
-
-
-#ifdef DEBUG
-       if (Event != SK_PNMI_EVT_XMAC_RESET) {
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                       ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
-                       (unsigned int)Event, (unsigned int)Param.Para64));
-       }
-#endif
-       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
-
-       MacType = pAC->GIni.GIMacType;
-
-       switch (Event) {
-
-       case SK_PNMI_EVT_SIRQ_OVERFLOW:
-               PhysPortIndex = (int)Param.Para32[0];
-               MacStatus = (SK_U16)Param.Para32[1];
-#ifdef DEBUG
-               if (PhysPortIndex >= SK_MAX_MACS) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
-                                " wrong, PhysPortIndex=0x%x\n",
-                               PhysPortIndex));
-                       return (0);
-               }
-#endif
-               OverflowStatus = 0;
-
-               /*
-                * Check which source caused an overflow interrupt.
-                */
-               if ((pAC->GIni.GIFunc.pFnMacOverflow(
-                        pAC, IoC, PhysPortIndex, MacStatus, &OverflowStatus) != 0) ||
-                       (OverflowStatus == 0)) {
-
-                       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
-                       return (0);
-               }
-
-               /*
-                * Check the overflow status register and increment
-                * the upper dword of corresponding counter.
-                */
-               for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
-                       CounterIndex ++) {
-
-                       Mask = (SK_U64)1 << CounterIndex;
-                       if ((OverflowStatus & Mask) == 0) {
-
-                               continue;
-                       }
-
-                       switch (StatOvrflwBit[CounterIndex][MacType]) {
-
-                       case SK_PNMI_HTX_UTILUNDER:
-                       case SK_PNMI_HTX_UTILOVER:
-                               XM_IN16(IoC, PhysPortIndex, XM_TX_CMD,
-                                       &Register);
-                               Register |= XM_TX_SAM_LINE;
-                               XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD,
-                                       Register);
-                               break;
-
-                       case SK_PNMI_HRX_UTILUNDER:
-                       case SK_PNMI_HRX_UTILOVER:
-                               XM_IN16(IoC, PhysPortIndex, XM_RX_CMD,
-                                       &Register);
-                               Register |= XM_RX_SAM_LINE;
-                               XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD,
-                                       Register);
-                               break;
-
-                       case SK_PNMI_HTX_OCTETHIGH:
-                       case SK_PNMI_HTX_OCTETLOW:
-                       case SK_PNMI_HTX_RESERVED:
-                       case SK_PNMI_HRX_OCTETHIGH:
-                       case SK_PNMI_HRX_OCTETLOW:
-                       case SK_PNMI_HRX_IRLENGTH:
-                       case SK_PNMI_HRX_RESERVED:
-
-                       /*
-                        * the following counters aren't be handled (id > 63)
-                        */
-                       case SK_PNMI_HTX_SYNC:
-                       case SK_PNMI_HTX_SYNC_OCTET:
-                               break;
-
-                       case SK_PNMI_HRX_LONGFRAMES:
-                               if (MacType == SK_MAC_GMAC) {
-                                       pAC->Pnmi.Port[PhysPortIndex].
-                                               CounterHigh[CounterIndex] ++;
-                               }
-                               break;
-
-                       default:
-                               pAC->Pnmi.Port[PhysPortIndex].
-                                       CounterHigh[CounterIndex] ++;
-                       }
-               }
-               break;
-
-       case SK_PNMI_EVT_SEN_WAR_LOW:
-#ifdef DEBUG
-               if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
-                               (unsigned int)Param.Para64));
-                       return (0);
-               }
-#endif
-               /*
-                * Store a trap message in the trap buffer and generate
-                * an event for user space applications with the
-                * SK_DRIVER_SENDEVENT macro.
-                */
-               QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
-                       (unsigned int)Param.Para64);
-               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-               break;
-
-       case SK_PNMI_EVT_SEN_WAR_UPP:
-#ifdef DEBUG
-               if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR:SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
-                               (unsigned int)Param.Para64));
-                       return (0);
-               }
-#endif
-               /*
-                * Store a trap message in the trap buffer and generate
-                * an event for user space applications with the
-                * SK_DRIVER_SENDEVENT macro.
-                */
-               QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
-                       (unsigned int)Param.Para64);
-               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-               break;
-
-       case SK_PNMI_EVT_SEN_ERR_LOW:
-#ifdef DEBUG
-               if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
-                               (unsigned int)Param.Para64));
-                       return (0);
-               }
-#endif
-               /*
-                * Store a trap message in the trap buffer and generate
-                * an event for user space applications with the
-                * SK_DRIVER_SENDEVENT macro.
-                */
-               QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
-                       (unsigned int)Param.Para64);
-               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-               break;
-
-       case SK_PNMI_EVT_SEN_ERR_UPP:
-#ifdef DEBUG
-               if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
-                               (unsigned int)Param.Para64));
-                       return (0);
-               }
-#endif
-               /*
-                * Store a trap message in the trap buffer and generate
-                * an event for user space applications with the
-                * SK_DRIVER_SENDEVENT macro.
-                */
-               QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
-                       (unsigned int)Param.Para64);
-               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-               break;
-
-       case SK_PNMI_EVT_CHG_EST_TIMER:
-               /*
-                * Calculate port switch average on a per hour basis
-                *   Time interval for check       : 28125 ms
-                *   Number of values for average  : 8
-                *
-                * Be careful in changing these values, on change check
-                *   - typedef of SK_PNMI_ESTIMATE (Size of EstValue
-                *     array one less than value number)
-                *   - Timer initilization SkTimerStart() in SkPnmiInit
-                *   - Delta value below must be multiplicated with
-                *     power of 2
-                *
-                */
-               pEst = &pAC->Pnmi.RlmtChangeEstimate;
-               CounterIndex = pEst->EstValueIndex + 1;
-               if (CounterIndex == 7) {
-
-                       CounterIndex = 0;
-               }
-               pEst->EstValueIndex = CounterIndex;
-
-               NewestValue = pAC->Pnmi.RlmtChangeCts;
-               OldestValue = pEst->EstValue[CounterIndex];
-               pEst->EstValue[CounterIndex] = NewestValue;
-
-               /*
-                * Calculate average. Delta stores the number of
-                * port switches per 28125 * 8 = 225000 ms
-                */
-               if (NewestValue >= OldestValue) {
-
-                       Delta = NewestValue - OldestValue;
-               }
-               else {
-                       /* Overflow situation */
-                       Delta = (SK_U64)(0 - OldestValue) + NewestValue;
-               }
-
-               /*
-                * Extrapolate delta to port switches per hour.
-                *     Estimate = Delta * (3600000 / 225000)
-                *              = Delta * 16
-                *              = Delta << 4
-                */
-               pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
-
-               /*
-                * Check if threshold is exceeded. If the threshold is
-                * permanently exceeded every 28125 ms an event will be
-                * generated to remind the user of this condition.
-                */
-               if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
-                       (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
-                       pAC->Pnmi.RlmtChangeThreshold)) {
-
-                       QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
-                       (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-               }
-
-               SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
-               SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
-                       28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
-                       EventParam);
-               break;
-
-       case SK_PNMI_EVT_CLEAR_COUNTER:
-               /*
-                *  Param.Para32[0] contains the NetIndex (0 ..1).
-                *  Param.Para32[1] is reserved, contains -1.
-                */
-               NetIndex = (SK_U32)Param.Para32[0];
-
-#ifdef DEBUG
-               if (NetIndex >= pAC->Rlmt.NumNets) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
-                               NetIndex));
-
-                       return (0);
-               }
-#endif
-
-               /*
-                * Set all counters and timestamps to zero
-                */
-               ResetCounter(pAC, IoC, NetIndex); /* the according NetIndex is required
-                                                                                               as a Parameter of the Event */
-               break;
-
-       case SK_PNMI_EVT_XMAC_RESET:
-               /*
-                * To grant continuous counter values store the current
-                * XMAC statistic values to the entries 1..n of the
-                * CounterOffset array. XMAC Errata #2
-                */
-#ifdef DEBUG
-               if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
-                               (unsigned int)Param.Para64));
-                       return (0);
-               }
-#endif
-               PhysPortIndex = (unsigned int)Param.Para64;
-
-               /*
-                * Update XMAC statistic to get fresh values
-                */
-               Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
-               if (Ret != SK_PNMI_ERR_OK) {
-
-                       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
-                       return (0);
-               }
-               /*
-                * Increment semaphore to indicate that an update was
-                * already done
-                */
-               pAC->Pnmi.MacUpdatedFlag ++;
-
-               for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
-                       CounterIndex ++) {
-
-                       if (!StatAddr[CounterIndex][MacType].GetOffset) {
-
-                               continue;
-                       }
-
-                       pAC->Pnmi.Port[PhysPortIndex].
-                               CounterOffset[CounterIndex] = GetPhysStatVal(
-                               pAC, IoC, PhysPortIndex, CounterIndex);
-                       pAC->Pnmi.Port[PhysPortIndex].
-                               CounterHigh[CounterIndex] = 0;
-               }
-
-               pAC->Pnmi.MacUpdatedFlag --;
-               break;
-
-       case SK_PNMI_EVT_RLMT_PORT_UP:
-               PhysPortIndex = (unsigned int)Param.Para32[0];
-#ifdef DEBUG
-               if (PhysPortIndex >= SK_MAX_MACS) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
-                " wrong, PhysPortIndex=%d\n", PhysPortIndex));
-
-                       return (0);
-               }
-#endif
-               /*
-                * Store a trap message in the trap buffer and generate an event for
-                * user space applications with the SK_DRIVER_SENDEVENT macro.
-                */
-               QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
-               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-
-               /* Bugfix for XMAC errata (#10620)*/
-               if (pAC->GIni.GIMacType == SK_MAC_XMAC){
-
-                       /* Add incremental difference to offset (#10620)*/
-                       (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                               XM_RXE_SHT_ERR, &Val32);
-
-                       Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
-                                CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
-                       pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
-                               Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
-               }
-
-               /* Tell VctStatus() that a link was up meanwhile. */
-               pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
-               break;
-
-    case SK_PNMI_EVT_RLMT_PORT_DOWN:
-               PhysPortIndex = (unsigned int)Param.Para32[0];
-
-#ifdef DEBUG
-               if (PhysPortIndex >= SK_MAX_MACS) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
-                " wrong, PhysPortIndex=%d\n", PhysPortIndex));
-
-                       return (0);
-               }
-#endif
-               /*
-                * Store a trap message in the trap buffer and generate an event for
-                * user space applications with the SK_DRIVER_SENDEVENT macro.
-                */
-               QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
-               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-
-               /* Bugfix #10620 - get zero level for incremental difference */
-               if ((pAC->GIni.GIMacType == SK_MAC_XMAC)) {
-
-                       (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                               XM_RXE_SHT_ERR, &Val32);
-                       pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
-                               (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
-                                CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
-               }
-               break;
-
-       case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
-               PhysPortIndex = (unsigned int)Param.Para32[0];
-               NetIndex = (SK_U32)Param.Para32[1];
-
-#ifdef DEBUG
-               if (PhysPortIndex >= SK_MAX_MACS) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
-                               PhysPortIndex));
-               }
-
-               if (NetIndex >= pAC->Rlmt.NumNets) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
-                               NetIndex));
-               }
-#endif
-               /*
-                * For now, ignore event if NetIndex != 0.
-                */
-               if (Param.Para32[1] != 0) {
-
-                       return (0);
-               }
-
-               /*
-                * Nothing to do if port is already inactive
-                */
-               if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
-                       return (0);
-               }
-
-               /*
-                * Update statistic counters to calculate new offset for the virtual
-                * port and increment semaphore to indicate that an update was already
-                * done.
-                */
-               if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
-                       SK_PNMI_ERR_OK) {
-
-                       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
-                       return (0);
-               }
-               pAC->Pnmi.MacUpdatedFlag ++;
-
-               /*
-                * Calculate new counter offset for virtual port to grant continous
-                * counting on port switches. The virtual port consists of all currently
-                * active ports. The port down event indicates that a port is removed
-                * from the virtual port. Therefore add the counter value of the removed
-                * port to the CounterOffset for the virtual port to grant the same
-                * counter value.
-                */
-               for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
-                       CounterIndex ++) {
-
-                       if (!StatAddr[CounterIndex][MacType].GetOffset) {
-
-                               continue;
-                       }
-
-                       Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
-
-                       pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
-               }
-
-               /*
-                * Set port to inactive
-                */
-               pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
-
-               pAC->Pnmi.MacUpdatedFlag --;
-               break;
-
-       case SK_PNMI_EVT_RLMT_ACTIVE_UP:
-               PhysPortIndex = (unsigned int)Param.Para32[0];
-               NetIndex = (SK_U32)Param.Para32[1];
-
-#ifdef DEBUG
-               if (PhysPortIndex >= SK_MAX_MACS) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
-                               PhysPortIndex));
-               }
-
-               if (NetIndex >= pAC->Rlmt.NumNets) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
-                               NetIndex));
-               }
-#endif
-               /*
-                * For now, ignore event if NetIndex != 0.
-                */
-               if (Param.Para32[1] != 0) {
-
-                       return (0);
-               }
-
-               /*
-                * Nothing to do if port is already active
-                */
-               if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
-                       return (0);
-               }
-
-               /*
-                * Statistic maintenance
-                */
-               pAC->Pnmi.RlmtChangeCts ++;
-               pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
-
-               /*
-                * Store a trap message in the trap buffer and generate an event for
-                * user space applications with the SK_DRIVER_SENDEVENT macro.
-                */
-               QueueRlmtNewMacTrap(pAC, PhysPortIndex);
-               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-
-               /*
-                * Update statistic counters to calculate new offset for the virtual
-                * port and increment semaphore to indicate that an update was
-                * already done.
-                */
-               if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
-                       SK_PNMI_ERR_OK) {
-
-                       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
-                       return (0);
-               }
-               pAC->Pnmi.MacUpdatedFlag ++;
-
-               /*
-                * Calculate new counter offset for virtual port to grant continous
-                * counting on port switches. A new port is added to the virtual port.
-                * Therefore substract the counter value of the new port from the
-                * CounterOffset for the virtual port to grant the same value.
-                */
-               for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
-                       CounterIndex ++) {
-
-                       if (!StatAddr[CounterIndex][MacType].GetOffset) {
-
-                               continue;
-                       }
-
-                       Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
-
-                       pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
-               }
-
-               /*
-                * Set port to active
-                */
-               pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
-
-               pAC->Pnmi.MacUpdatedFlag --;
-               break;
-
-       case SK_PNMI_EVT_RLMT_SEGMENTATION:
-               /*
-                * Para.Para32[0] contains the NetIndex.
-                */
-
-               /*
-                * Store a trap message in the trap buffer and generate an event for
-                * user space applications with the SK_DRIVER_SENDEVENT macro.
-                */
-               QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
-               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-               break;
-
-    case SK_PNMI_EVT_RLMT_SET_NETS:
-               /*
-                *  Param.Para32[0] contains the number of Nets.
-                *  Param.Para32[1] is reserved, contains -1.
-                */
-           /*
-        * Check number of nets
-                */
-               MaxNetNumber = pAC->GIni.GIMacsFound;
-               if (((unsigned int)Param.Para32[0] < 1)
-                       || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
-                       return (SK_PNMI_ERR_UNKNOWN_NET);
-               }
-
-       if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
-               pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
-       }
-       else { /* dual net mode */
-               pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
-       }
-       break;
-
-    case SK_PNMI_EVT_VCT_RESET:
-       PhysPortIndex = Param.Para32[0];
-       pPrt = &pAC->GIni.GP[PhysPortIndex];
-       pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
-
-       if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
-               RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
-               if (RetCode == 2) {
-                       /*
-                        * VCT test is still running.
-                        * Start VCT timer counter again.
-                        */
-                       SK_MEMSET((char *) &Param, 0, sizeof(Param));
-                       Param.Para32[0] = PhysPortIndex;
-                       Param.Para32[1] = -1;
-                       SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
-                               4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
-                       break;
-               }
-               pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
-               pAC->Pnmi.VctStatus[PhysPortIndex] |=
-                       (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
-
-               /* Copy results for later use to PNMI struct. */
-               for (i = 0; i < 4; i++)  {
-                       if (pPrt->PMdiPairLen[i] > 35) {
-                               CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
-                       }
-                       else {
-                               CableLength = 0;
-                       }
-                       pVctBackupData->PMdiPairLen[i] = CableLength;
-                       pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
-               }
-
-               Param.Para32[0] = PhysPortIndex;
-               Param.Para32[1] = -1;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
-               SkEventDispatcher(pAC, IoC);
-       }
-
-       break;
-
-       default:
-               break;
-       }
-
-       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
-       return (0);
-}
-
-
-/******************************************************************************
- *
- * Private functions
- *
- */
-
-/*****************************************************************************
- *
- * PnmiVar - Gets, presets, and sets single OIDs
- *
- * Description:
- *     Looks up the requested OID, calls the corresponding handler
- *     function, and passes the parameters with the get, preset, or
- *     set command. The function is called by SkGePnmiGetVar,
- *     SkGePnmiPreSetVar, or SkGePnmiSetVar.
- *
- * Returns:
- *     SK_PNMI_ERR_XXX. For details have a look to the description of the
- *     calling functions.
- *     SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
- */
-PNMI_STATIC int PnmiVar(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* Get/PreSet/Set action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer which stores the mgmt data to be set */
-unsigned int *pLen,    /* Total length of mgmt data */
-SK_U32 Instance,       /* Instance (1..n) that is to be set or -1 */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       unsigned int    TableIndex;
-       int             Ret;
-
-
-       if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_UNKNOWN_OID);
-       }
-
-    /*
-     * Check NetIndex
-     */
-       if (NetIndex >= pAC->Rlmt.NumNets) {
-               return (SK_PNMI_ERR_UNKNOWN_NET);
-       }
-
-       SK_PNMI_CHECKFLAGS("PnmiVar: On call");
-
-       Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
-               Instance, TableIndex, NetIndex);
-
-       SK_PNMI_CHECKFLAGS("PnmiVar: On return");
-
-       return (Ret);
-}
-
-/*****************************************************************************
- *
- * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
- *
- * Description:
- *     The return value of the function will also be stored in
- *     SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
- *     SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
- *     checks which OIDs are able to set, and calls the handler function of
- *     the OID to perform the set. The return value of the function will
- *     also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
- *     minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
- *     by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
- *
- * Returns:
- *     SK_PNMI_ERR_XXX. The codes are described in the calling functions.
- *     SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
- */
-PNMI_STATIC int PnmiStruct(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int  Action,           /* Set action to be performed */
-char *pBuf,            /* Buffer which contains the data to be set */
-unsigned int *pLen,    /* Length of buffer */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       int             Ret;
-       unsigned int    TableIndex;
-       unsigned int    DstOffset;
-       unsigned int    Len;
-       unsigned int    InstanceNo;
-       unsigned int    InstanceCnt;
-       SK_U32          Instance;
-       SK_U32          Id;
-
-
-       /* Check if the passed buffer has the right size */
-       if (*pLen < SK_PNMI_STRUCT_SIZE) {
-
-               /* Check if we can return the error within the buffer */
-               if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
-
-                       SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
-                               (SK_U32)(-1));
-               }
-
-               *pLen = SK_PNMI_STRUCT_SIZE;
-               return (SK_PNMI_ERR_TOO_SHORT);
-       }
-
-    /*
-     * Check NetIndex
-     */
-       if (NetIndex >= pAC->Rlmt.NumNets) {
-               return (SK_PNMI_ERR_UNKNOWN_NET);
-       }
-
-       SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
-
-       /*
-        * Update the values of RLMT and SIRQ and increment semaphores to
-        * indicate that an update was already done.
-        */
-       if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
-
-               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
-               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-               return (Ret);
-       }
-
-       if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
-
-               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
-               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-               return (Ret);
-       }
-
-       pAC->Pnmi.RlmtUpdatedFlag ++;
-       pAC->Pnmi.SirqUpdatedFlag ++;
-
-       /* Preset/Set values */
-       for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
-
-               if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
-                       (IdTable[TableIndex].Access != SK_PNMI_WO)) {
-
-                       continue;
-               }
-
-               InstanceNo = IdTable[TableIndex].InstanceNo;
-               Id = IdTable[TableIndex].Id;
-
-               for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
-                       InstanceCnt ++) {
-
-                       DstOffset = IdTable[TableIndex].Offset +
-                               (InstanceCnt - 1) *
-                               IdTable[TableIndex].StructSize;
-
-                       /*
-                        * Because VPD multiple instance variables are
-                        * not setable we do not need to evaluate VPD
-                        * instances. Have a look to VPD instance
-                        * calculation in SkPnmiGetStruct().
-                        */
-                       Instance = (SK_U32)InstanceCnt;
-
-                       /*
-                        * Evaluate needed buffer length
-                        */
-                       Len = 0;
-                       Ret = IdTable[TableIndex].Func(pAC, IoC,
-                               SK_PNMI_GET, IdTable[TableIndex].Id,
-                               NULL, &Len, Instance, TableIndex, NetIndex);
-
-                       if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
-
-                               break;
-                       }
-                       if (Ret != SK_PNMI_ERR_TOO_SHORT) {
-
-                               pAC->Pnmi.RlmtUpdatedFlag --;
-                               pAC->Pnmi.SirqUpdatedFlag --;
-
-                               SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
-                               SK_PNMI_SET_STAT(pBuf,
-                                       SK_PNMI_ERR_GENERAL, DstOffset);
-                               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-                       if (Id == OID_SKGE_VPD_ACTION) {
-
-                               switch (*(pBuf + DstOffset)) {
-
-                               case SK_PNMI_VPD_CREATE:
-                                       Len = 3 + *(pBuf + DstOffset + 3);
-                                       break;
-
-                               case SK_PNMI_VPD_DELETE:
-                                       Len = 3;
-                                       break;
-
-                               default:
-                                       Len = 1;
-                                       break;
-                               }
-                       }
-
-                       /* Call the OID handler function */
-                       Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
-                               IdTable[TableIndex].Id, pBuf + DstOffset,
-                               &Len, Instance, TableIndex, NetIndex);
-
-                       if (Ret != SK_PNMI_ERR_OK) {
-
-                               pAC->Pnmi.RlmtUpdatedFlag --;
-                               pAC->Pnmi.SirqUpdatedFlag --;
-
-                               SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
-                               SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
-                                       DstOffset);
-                               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-               }
-       }
-
-       pAC->Pnmi.RlmtUpdatedFlag --;
-       pAC->Pnmi.SirqUpdatedFlag --;
-
-       SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
-       SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * LookupId - Lookup an OID in the IdTable
- *
- * Description:
- *     Scans the IdTable to find the table entry of an OID.
- *
- * Returns:
- *     The table index or -1 if not found.
- */
-PNMI_STATIC int LookupId(
-SK_U32 Id)             /* Object identifier to be searched */
-{
-       int i;
-
-       for (i = 0; i < ID_TABLE_SIZE; i++) {
-
-               if (IdTable[i].Id == Id) {
-
-                       return i;
-               }
-       }
-
-       return (-1);
-}
-
-/*****************************************************************************
- *
- * OidStruct - Handler of OID_SKGE_ALL_DATA
- *
- * Description:
- *     This OID performs a Get/Preset/SetStruct call and returns all data
- *     in a SK_PNMI_STRUCT_DATA structure.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int OidStruct(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* Get/PreSet/Set action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       if (Id != OID_SKGE_ALL_DATA) {
-
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
-                       SK_PNMI_ERR003MSG);
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_GENERAL);
-       }
-
-       /*
-        * Check instance. We only handle single instance variables
-        */
-       if (Instance != (SK_U32)(-1) && Instance != 1) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_UNKNOWN_INST);
-       }
-
-       switch (Action) {
-
-       case SK_PNMI_GET:
-               return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
-
-       case SK_PNMI_PRESET:
-               return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
-
-       case SK_PNMI_SET:
-               return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
-       }
-
-       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
-
-       *pLen = 0;
-       return (SK_PNMI_ERR_GENERAL);
-}
-
-/*****************************************************************************
- *
- * Perform - OID handler of OID_SKGE_ACTION
- *
- * Description:
- *     None.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int Perform(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* Get/PreSet/Set action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       int     Ret;
-       SK_U32  ActionOp;
-
-
-       /*
-        * Check instance. We only handle single instance variables
-        */
-       if (Instance != (SK_U32)(-1) && Instance != 1) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_UNKNOWN_INST);
-       }
-
-       if (*pLen < sizeof(SK_U32)) {
-
-               *pLen = sizeof(SK_U32);
-               return (SK_PNMI_ERR_TOO_SHORT);
-       }
-
-       /* Check if a get should be performed */
-       if (Action == SK_PNMI_GET) {
-
-               /* A get is easy. We always return the same value */
-               ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
-               SK_PNMI_STORE_U32(pBuf, ActionOp);
-               *pLen = sizeof(SK_U32);
-
-               return (SK_PNMI_ERR_OK);
-       }
-
-       /* Continue with PRESET/SET action */
-       if (*pLen > sizeof(SK_U32)) {
-
-               return (SK_PNMI_ERR_BAD_VALUE);
-       }
-
-       /* Check if the command is a known one */
-       SK_PNMI_READ_U32(pBuf, ActionOp);
-       if (*pLen > sizeof(SK_U32) ||
-               (ActionOp != SK_PNMI_ACT_IDLE &&
-               ActionOp != SK_PNMI_ACT_RESET &&
-               ActionOp != SK_PNMI_ACT_SELFTEST &&
-               ActionOp != SK_PNMI_ACT_RESETCNT)) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_BAD_VALUE);
-       }
-
-       /* A preset ends here */
-       if (Action == SK_PNMI_PRESET) {
-
-               return (SK_PNMI_ERR_OK);
-       }
-
-       switch (ActionOp) {
-
-       case SK_PNMI_ACT_IDLE:
-               /* Nothing to do */
-               break;
-
-       case SK_PNMI_ACT_RESET:
-               /*
-                * Perform a driver reset or something that comes near
-                * to this.
-                */
-               Ret = SK_DRIVER_RESET(pAC, IoC);
-               if (Ret != 0) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
-                               SK_PNMI_ERR005MSG);
-
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-               break;
-
-       case SK_PNMI_ACT_SELFTEST:
-               /*
-                * Perform a driver selftest or something similar to this.
-                * Currently this feature is not used and will probably
-                * implemented in another way.
-                */
-               Ret = SK_DRIVER_SELFTEST(pAC, IoC);
-               pAC->Pnmi.TestResult = Ret;
-               break;
-
-       case SK_PNMI_ACT_RESETCNT:
-               /* Set all counters and timestamps to zero */
-               ResetCounter(pAC, IoC, NetIndex);
-               break;
-
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
-                       SK_PNMI_ERR006MSG);
-
-               return (SK_PNMI_ERR_GENERAL);
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
- *
- * Description:
- *     Retrieves the statistic values of the virtual port (logical
- *     index 0). Only special OIDs of NDIS are handled which consist
- *     of a 32 bit instead of a 64 bit value. The OIDs are public
- *     because perhaps some other platform can use them too.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int Mac8023Stat(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* Get/PreSet/Set action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex,       /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       int     Ret;
-       SK_U64  StatVal;
-       SK_U32  StatVal32;
-       SK_BOOL Is64BitReq = SK_FALSE;
-
-       /*
-        * Only the active Mac is returned
-        */
-       if (Instance != (SK_U32)(-1) && Instance != 1) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_UNKNOWN_INST);
-       }
-
-       /*
-        * Check action type
-        */
-       if (Action != SK_PNMI_GET) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_READ_ONLY);
-       }
-
-       /*
-        * Check length
-        */
-       switch (Id) {
-
-       case OID_802_3_PERMANENT_ADDRESS:
-       case OID_802_3_CURRENT_ADDRESS:
-               if (*pLen < sizeof(SK_MAC_ADDR)) {
-
-                       *pLen = sizeof(SK_MAC_ADDR);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       default:
-#ifndef SK_NDIS_64BIT_CTR
-               if (*pLen < sizeof(SK_U32)) {
-                       *pLen = sizeof(SK_U32);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-
-#else /* SK_NDIS_64BIT_CTR */
-
-               /*
-                * for compatibility, at least 32bit are required for oid
-                */
-               if (*pLen < sizeof(SK_U32)) {
-                       /*
-                       * but indicate handling for 64bit values,
-                       * if insufficient space is provided
-                       */
-                       *pLen = sizeof(SK_U64);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-
-               Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
-#endif /* SK_NDIS_64BIT_CTR */
-               break;
-       }
-
-       /*
-        * Update all statistics, because we retrieve virtual MAC, which
-        * consists of multiple physical statistics and increment semaphore
-        * to indicate that an update was already done.
-        */
-       Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
-       if ( Ret != SK_PNMI_ERR_OK) {
-
-               *pLen = 0;
-               return (Ret);
-       }
-       pAC->Pnmi.MacUpdatedFlag ++;
-
-       /*
-        * Get value (MAC Index 0 identifies the virtual MAC)
-        */
-       switch (Id) {
-
-       case OID_802_3_PERMANENT_ADDRESS:
-               CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
-               *pLen = sizeof(SK_MAC_ADDR);
-               break;
-
-       case OID_802_3_CURRENT_ADDRESS:
-               CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
-               *pLen = sizeof(SK_MAC_ADDR);
-               break;
-
-       default:
-               StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
-
-               /*
-                * by default 32bit values are evaluated
-                */
-               if (!Is64BitReq) {
-                       StatVal32 = (SK_U32)StatVal;
-                       SK_PNMI_STORE_U32(pBuf, StatVal32);
-                       *pLen = sizeof(SK_U32);
-               }
-               else {
-                       SK_PNMI_STORE_U64(pBuf, StatVal);
-                       *pLen = sizeof(SK_U64);
-               }
-               break;
-       }
-
-       pAC->Pnmi.MacUpdatedFlag --;
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
- *
- * Description:
- *     Retrieves the XMAC statistic data.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int MacPrivateStat(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* Get/PreSet/Set action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       unsigned int    LogPortMax;
-       unsigned int    LogPortIndex;
-       unsigned int    PhysPortMax;
-       unsigned int    Limit;
-       unsigned int    Offset;
-       int                             Ret;
-       SK_U64                  StatVal;
-
-
-       /*
-        * Calculate instance if wished. MAC index 0 is the virtual
-        * MAC.
-        */
-       PhysPortMax = pAC->GIni.GIMacsFound;
-       LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
-
-       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
-               LogPortMax--;
-       }
-
-       if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
-               /* Check instance range */
-               if ((Instance < 1) || (Instance > LogPortMax)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-               LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
-               Limit = LogPortIndex + 1;
-       }
-
-       else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
-
-               LogPortIndex = 0;
-               Limit = LogPortMax;
-       }
-
-
-       /*
-        * Check action
-        */
-       if (Action != SK_PNMI_GET) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_READ_ONLY);
-       }
-
-       /*
-        * Check length
-        */
-       if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
-
-               *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
-               return (SK_PNMI_ERR_TOO_SHORT);
-       }
-
-       /*
-        * Update XMAC statistic and increment semaphore to indicate that
-        * an update was already done.
-        */
-       Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
-       if (Ret != SK_PNMI_ERR_OK) {
-
-               *pLen = 0;
-               return (Ret);
-       }
-       pAC->Pnmi.MacUpdatedFlag ++;
-
-       /*
-        * Get value
-        */
-       Offset = 0;
-       for (; LogPortIndex < Limit; LogPortIndex ++) {
-
-               switch (Id) {
-
-/* XXX not yet implemented due to XMAC problems
-               case OID_SKGE_STAT_TX_UTIL:
-                       return (SK_PNMI_ERR_GENERAL);
-*/
-/* XXX not yet implemented due to XMAC problems
-               case OID_SKGE_STAT_RX_UTIL:
-                       return (SK_PNMI_ERR_GENERAL);
-*/
-               case OID_SKGE_STAT_RX:
-               case OID_SKGE_STAT_TX:
-                       switch (pAC->GIni.GIMacType) {
-                       case SK_MAC_XMAC:
-                               StatVal = GetStatVal(pAC, IoC, LogPortIndex,
-                                       IdTable[TableIndex].Param, NetIndex);
-                               break;
-
-                       case SK_MAC_GMAC:
-                               if (Id == OID_SKGE_STAT_TX) {
-
-                                       StatVal =
-                                               GetStatVal(pAC, IoC, LogPortIndex,
-                                                                  SK_PNMI_HTX_BROADCAST, NetIndex) +
-                                               GetStatVal(pAC, IoC, LogPortIndex,
-                                                                  SK_PNMI_HTX_MULTICAST, NetIndex) +
-                                               GetStatVal(pAC, IoC, LogPortIndex,
-                                                                  SK_PNMI_HTX_UNICAST, NetIndex);
-                               }
-                               else {
-                                       StatVal =
-                                               GetStatVal(pAC, IoC, LogPortIndex,
-                                                                  SK_PNMI_HRX_BROADCAST, NetIndex) +
-                                               GetStatVal(pAC, IoC, LogPortIndex,
-                                                                  SK_PNMI_HRX_MULTICAST, NetIndex) +
-                                               GetStatVal(pAC, IoC, LogPortIndex,
-                                                                  SK_PNMI_HRX_UNICAST, NetIndex) +
-                                               GetStatVal(pAC, IoC, LogPortIndex,
-                                                                  SK_PNMI_HRX_UNDERSIZE, NetIndex);
-                               }
-                               break;
-
-                       default:
-                               StatVal = 0;
-                               break;
-                       }
-
-                       SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
-                       break;
-
-               default:
-                       StatVal = GetStatVal(pAC, IoC, LogPortIndex,
-                               IdTable[TableIndex].Param, NetIndex);
-                       SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
-                       break;
-               }
-
-               Offset += sizeof(SK_U64);
-       }
-       *pLen = Offset;
-
-       pAC->Pnmi.MacUpdatedFlag --;
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
- *
- * Description:
- *     Get/Presets/Sets the current and factory MAC address. The MAC
- *     address of the virtual port, which is reported to the OS, may
- *     not be changed, but the physical ones. A set to the virtual port
- *     will be ignored. No error should be reported because otherwise
- *     a multiple instance set (-1) would always fail.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int Addr(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* Get/PreSet/Set action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       int             Ret;
-       unsigned int    LogPortMax;
-       unsigned int    PhysPortMax;
-       unsigned int    LogPortIndex;
-       unsigned int    PhysPortIndex;
-       unsigned int    Limit;
-       unsigned int    Offset = 0;
-
-       /*
-        * Calculate instance if wished. MAC index 0 is the virtual
-        * MAC.
-        */
-       PhysPortMax = pAC->GIni.GIMacsFound;
-       LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
-
-       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
-               LogPortMax--;
-       }
-
-       if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
-               /* Check instance range */
-               if ((Instance < 1) || (Instance > LogPortMax)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-               LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
-               Limit = LogPortIndex + 1;
-       }
-
-       else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
-
-               LogPortIndex = 0;
-               Limit = LogPortMax;
-       }
-
-       /*
-        * Perform Action
-        */
-       if (Action == SK_PNMI_GET) {
-
-               /*
-                * Check length
-               */
-               if (*pLen < (Limit - LogPortIndex) * 6) {
-
-                       *pLen = (Limit - LogPortIndex) * 6;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-
-               /*
-                * Get value
-                */
-               for (; LogPortIndex < Limit; LogPortIndex ++) {
-
-                       switch (Id) {
-
-                       case OID_SKGE_PHYS_CUR_ADDR:
-                               if (LogPortIndex == 0) {
-                                       CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
-                               }
-                               else {
-                                       PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
-
-                                       CopyMac(pBuf + Offset,
-                                               &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
-                               }
-                               Offset += 6;
-                               break;
-
-                       case OID_SKGE_PHYS_FAC_ADDR:
-                               if (LogPortIndex == 0) {
-                                       CopyMac(pBuf + Offset,
-                                               &pAC->Addr.Net[NetIndex].PermanentMacAddress);
-                               }
-                               else {
-                                       PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                               pAC, LogPortIndex);
-
-                                       CopyMac(pBuf + Offset,
-                                               &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
-                               }
-                               Offset += 6;
-                               break;
-
-                       default:
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
-                                       SK_PNMI_ERR008MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-               }
-
-               *pLen = Offset;
-       }
-       else {
-               /*
-                * The logical MAC address may not be changed only
-                * the physical ones
-                */
-               if (Id == OID_SKGE_PHYS_FAC_ADDR) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_READ_ONLY);
-               }
-
-               /*
-                * Only the current address may be changed
-                */
-               if (Id != OID_SKGE_PHYS_CUR_ADDR) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
-                               SK_PNMI_ERR009MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               /*
-                * Check length
-               */
-               if (*pLen < (Limit - LogPortIndex) * 6) {
-
-                       *pLen = (Limit - LogPortIndex) * 6;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               if (*pLen > (Limit - LogPortIndex) * 6) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_BAD_VALUE);
-               }
-
-               /*
-                * Check Action
-                */
-               if (Action == SK_PNMI_PRESET) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_OK);
-               }
-
-               /*
-                * Set OID_SKGE_MAC_CUR_ADDR
-                */
-               for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
-
-                       /*
-                        * A set to virtual port and set of broadcast
-                        * address will be ignored
-                        */
-                       if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
-                               "\xff\xff\xff\xff\xff\xff", 6) == 0) {
-
-                               continue;
-                       }
-
-                       PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
-                               LogPortIndex);
-
-                       Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
-                               (SK_MAC_ADDR *)(pBuf + Offset),
-                               (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
-                               SK_ADDR_PHYSICAL_ADDRESS));
-                       if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
-
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-               }
-               *pLen = Offset;
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
- *
- * Description:
- *     Retrieves the statistic values of the CSUM module. The CSUM data
- *     structure must be available in the SK_AC even if the CSUM module
- *     is not included, because PNMI reads the statistic data from the
- *     CSUM part of SK_AC directly.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int CsumStat(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* Get/PreSet/Set action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       unsigned int    Index;
-       unsigned int    Limit;
-       unsigned int    Offset = 0;
-       SK_U64          StatVal;
-
-
-       /*
-        * Calculate instance if wished
-        */
-       if (Instance != (SK_U32)(-1)) {
-
-               if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-               Index = (unsigned int)Instance - 1;
-               Limit = Index + 1;
-       }
-       else {
-               Index = 0;
-               Limit = SKCS_NUM_PROTOCOLS;
-       }
-
-       /*
-        * Check action
-        */
-       if (Action != SK_PNMI_GET) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_READ_ONLY);
-       }
-
-       /*
-        * Check length
-        */
-       if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
-
-               *pLen = (Limit - Index) * sizeof(SK_U64);
-               return (SK_PNMI_ERR_TOO_SHORT);
-       }
-
-       /*
-        * Get value
-        */
-       for (; Index < Limit; Index ++) {
-
-               switch (Id) {
-
-               case OID_SKGE_CHKSM_RX_OK_CTS:
-                       StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
-                       break;
-
-               case OID_SKGE_CHKSM_RX_UNABLE_CTS:
-                       StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
-                       break;
-
-               case OID_SKGE_CHKSM_RX_ERR_CTS:
-                       StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
-                       break;
-
-               case OID_SKGE_CHKSM_TX_OK_CTS:
-                       StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
-                       break;
-
-               case OID_SKGE_CHKSM_TX_UNABLE_CTS:
-                       StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
-                       break;
-
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
-                               SK_PNMI_ERR010MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
-               Offset += sizeof(SK_U64);
-       }
-
-       /*
-        * Store used buffer space
-        */
-       *pLen = Offset;
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
- *
- * Description:
- *     Retrieves the statistic values of the I2C module, which handles
- *     the temperature and voltage sensors.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int SensorStat(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* Get/PreSet/Set action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       unsigned int    i;
-       unsigned int    Index;
-       unsigned int    Limit;
-       unsigned int    Offset;
-       unsigned int    Len;
-       SK_U32          Val32;
-       SK_U64          Val64;
-
-
-       /*
-        * Calculate instance if wished
-        */
-       if ((Instance != (SK_U32)(-1))) {
-
-               if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-
-               Index = (unsigned int)Instance -1;
-               Limit = (unsigned int)Instance;
-       }
-       else {
-               Index = 0;
-               Limit = (unsigned int) pAC->I2c.MaxSens;
-       }
-
-       /*
-        * Check action
-        */
-       if (Action != SK_PNMI_GET) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_READ_ONLY);
-       }
-
-       /*
-        * Check length
-        */
-       switch (Id) {
-
-       case OID_SKGE_SENSOR_VALUE:
-       case OID_SKGE_SENSOR_WAR_THRES_LOW:
-       case OID_SKGE_SENSOR_WAR_THRES_UPP:
-       case OID_SKGE_SENSOR_ERR_THRES_LOW:
-       case OID_SKGE_SENSOR_ERR_THRES_UPP:
-               if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
-
-                       *pLen = (Limit - Index) * sizeof(SK_U32);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       case OID_SKGE_SENSOR_DESCR:
-               for (Offset = 0, i = Index; i < Limit; i ++) {
-
-                       Len = (unsigned int)
-                               SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
-                       if (Len >= SK_PNMI_STRINGLEN2) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
-                                       SK_PNMI_ERR011MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-                       Offset += Len;
-               }
-               if (*pLen < Offset) {
-
-                       *pLen = Offset;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       case OID_SKGE_SENSOR_INDEX:
-       case OID_SKGE_SENSOR_TYPE:
-       case OID_SKGE_SENSOR_STATUS:
-               if (*pLen < Limit - Index) {
-
-                       *pLen = Limit - Index;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       case OID_SKGE_SENSOR_WAR_CTS:
-       case OID_SKGE_SENSOR_WAR_TIME:
-       case OID_SKGE_SENSOR_ERR_CTS:
-       case OID_SKGE_SENSOR_ERR_TIME:
-               if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
-
-                       *pLen = (Limit - Index) * sizeof(SK_U64);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
-                       SK_PNMI_ERR012MSG);
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_GENERAL);
-
-       }
-
-       /*
-        * Get value
-        */
-       for (Offset = 0; Index < Limit; Index ++) {
-
-               switch (Id) {
-
-               case OID_SKGE_SENSOR_INDEX:
-                       *(pBuf + Offset) = (char)Index;
-                       Offset += sizeof(char);
-                       break;
-
-               case OID_SKGE_SENSOR_DESCR:
-                       Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
-                       SK_MEMCPY(pBuf + Offset + 1,
-                               pAC->I2c.SenTable[Index].SenDesc, Len);
-                       *(pBuf + Offset) = (char)Len;
-                       Offset += Len + 1;
-                       break;
-
-               case OID_SKGE_SENSOR_TYPE:
-                       *(pBuf + Offset) =
-                               (char)pAC->I2c.SenTable[Index].SenType;
-                       Offset += sizeof(char);
-                       break;
-
-               case OID_SKGE_SENSOR_VALUE:
-                       Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
-                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-                       Offset += sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_SENSOR_WAR_THRES_LOW:
-                       Val32 = (SK_U32)pAC->I2c.SenTable[Index].
-                               SenThreWarnLow;
-                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-                       Offset += sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_SENSOR_WAR_THRES_UPP:
-                       Val32 = (SK_U32)pAC->I2c.SenTable[Index].
-                               SenThreWarnHigh;
-                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-                       Offset += sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_SENSOR_ERR_THRES_LOW:
-                       Val32 = (SK_U32)pAC->I2c.SenTable[Index].
-                               SenThreErrLow;
-                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-                       Offset += sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_SENSOR_ERR_THRES_UPP:
-                       Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
-                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-                       Offset += sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_SENSOR_STATUS:
-                       *(pBuf + Offset) =
-                               (char)pAC->I2c.SenTable[Index].SenErrFlag;
-                       Offset += sizeof(char);
-                       break;
-
-               case OID_SKGE_SENSOR_WAR_CTS:
-                       Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
-                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
-                       Offset += sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_SENSOR_ERR_CTS:
-                       Val64 = pAC->I2c.SenTable[Index].SenErrCts;
-                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
-                       Offset += sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_SENSOR_WAR_TIME:
-                       Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
-                               SenBegWarnTS);
-                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
-                       Offset += sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_SENSOR_ERR_TIME:
-                       Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
-                               SenBegErrTS);
-                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
-                       Offset += sizeof(SK_U64);
-                       break;
-
-               default:
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
-                               ("SensorStat: Unknown OID should be handled before"));
-
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-       }
-
-       /*
-        * Store used buffer space
-        */
-       *pLen = Offset;
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * Vpd - OID handler function of OID_SKGE_VPD_XXX
- *
- * Description:
- *     Get/preset/set of VPD data. As instance the name of a VPD key
- *     can be passed. The Instance parameter is a SK_U32 and can be
- *     used as a string buffer for the VPD key, because their maximum
- *     length is 4 byte.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int Vpd(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* Get/PreSet/Set action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       SK_VPD_STATUS   *pVpdStatus;
-       unsigned int    BufLen;
-       char            Buf[256];
-       char            KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
-       char            KeyStr[SK_PNMI_VPD_KEY_SIZE];
-       unsigned int    KeyNo;
-       unsigned int    Offset;
-       unsigned int    Index;
-       unsigned int    FirstIndex;
-       unsigned int    LastIndex;
-       unsigned int    Len;
-       int             Ret;
-       SK_U32          Val32;
-
-       /*
-        * Get array of all currently stored VPD keys
-        */
-       Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr),
-               &KeyNo);
-       if (Ret != SK_PNMI_ERR_OK) {
-               *pLen = 0;
-               return (Ret);
-       }
-
-       /*
-        * If instance is not -1, try to find the requested VPD key for
-        * the multiple instance variables. The other OIDs as for example
-        * OID VPD_ACTION are single instance variables and must be
-        * handled separatly.
-        */
-       FirstIndex = 0;
-       LastIndex = KeyNo;
-
-       if ((Instance != (SK_U32)(-1))) {
-
-               if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
-                       Id == OID_SKGE_VPD_ACCESS) {
-
-                       SK_STRNCPY(KeyStr, (char *)&Instance, 4);
-                       KeyStr[4] = 0;
-
-                       for (Index = 0; Index < KeyNo; Index ++) {
-
-                               if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
-                                       FirstIndex = Index;
-                                       LastIndex = Index+1;
-                                       break;
-                               }
-                       }
-                       if (Index == KeyNo) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_UNKNOWN_INST);
-                       }
-               }
-               else if (Instance != 1) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-       }
-
-       /*
-        * Get value, if a query should be performed
-        */
-       if (Action == SK_PNMI_GET) {
-
-               switch (Id) {
-
-               case OID_SKGE_VPD_FREE_BYTES:
-                       /* Check length of buffer */
-                       if (*pLen < sizeof(SK_U32)) {
-
-                               *pLen = sizeof(SK_U32);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       /* Get number of free bytes */
-                       pVpdStatus = VpdStat(pAC, IoC);
-                       if (pVpdStatus == NULL) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
-                                       SK_PNMI_ERR017MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-                       if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
-                                       SK_PNMI_ERR018MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-
-                       Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
-                       SK_PNMI_STORE_U32(pBuf, Val32);
-                       *pLen = sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_VPD_ENTRIES_LIST:
-                       /* Check length */
-                       for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
-
-                               Len += SK_STRLEN(KeyArr[Index]) + 1;
-                       }
-                       if (*pLen < Len) {
-
-                               *pLen = Len;
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-
-                       /* Get value */
-                       *(pBuf) = (char)Len - 1;
-                       for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
-
-                               Len = SK_STRLEN(KeyArr[Index]);
-                               SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
-
-                               Offset += Len;
-
-                               if (Index < KeyNo - 1) {
-
-                                       *(pBuf + Offset) = ' ';
-                                       Offset ++;
-                               }
-                       }
-                       *pLen = Offset;
-                       break;
-
-               case OID_SKGE_VPD_ENTRIES_NUMBER:
-                       /* Check length */
-                       if (*pLen < sizeof(SK_U32)) {
-
-                               *pLen = sizeof(SK_U32);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-
-                       Val32 = (SK_U32)KeyNo;
-                       SK_PNMI_STORE_U32(pBuf, Val32);
-                       *pLen = sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_VPD_KEY:
-                       /* Check buffer length, if it is large enough */
-                       for (Len = 0, Index = FirstIndex;
-                               Index < LastIndex; Index ++) {
-
-                               Len += SK_STRLEN(KeyArr[Index]) + 1;
-                       }
-                       if (*pLen < Len) {
-
-                               *pLen = Len;
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-
-                       /*
-                        * Get the key to an intermediate buffer, because
-                        * we have to prepend a length byte.
-                        */
-                       for (Offset = 0, Index = FirstIndex;
-                               Index < LastIndex; Index ++) {
-
-                               Len = SK_STRLEN(KeyArr[Index]);
-
-                               *(pBuf + Offset) = (char)Len;
-                               SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
-                                       Len);
-                               Offset += Len + 1;
-                       }
-                       *pLen = Offset;
-                       break;
-
-               case OID_SKGE_VPD_VALUE:
-                       /* Check the buffer length if it is large enough */
-                       for (Offset = 0, Index = FirstIndex;
-                               Index < LastIndex; Index ++) {
-
-                               BufLen = 256;
-                               if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
-                                       (int *)&BufLen) > 0 ||
-                                       BufLen >= SK_PNMI_VPD_DATALEN) {
-
-                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                               SK_PNMI_ERR021,
-                                               SK_PNMI_ERR021MSG);
-
-                                       return (SK_PNMI_ERR_GENERAL);
-                               }
-                               Offset += BufLen + 1;
-                       }
-                       if (*pLen < Offset) {
-
-                               *pLen = Offset;
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-
-                       /*
-                        * Get the value to an intermediate buffer, because
-                        * we have to prepend a length byte.
-                        */
-                       for (Offset = 0, Index = FirstIndex;
-                               Index < LastIndex; Index ++) {
-
-                               BufLen = 256;
-                               if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
-                                       (int *)&BufLen) > 0 ||
-                                       BufLen >= SK_PNMI_VPD_DATALEN) {
-
-                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                               SK_PNMI_ERR022,
-                                               SK_PNMI_ERR022MSG);
-
-                                       *pLen = 0;
-                                       return (SK_PNMI_ERR_GENERAL);
-                               }
-
-                               *(pBuf + Offset) = (char)BufLen;
-                               SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
-                               Offset += BufLen + 1;
-                       }
-                       *pLen = Offset;
-                       break;
-
-               case OID_SKGE_VPD_ACCESS:
-                       if (*pLen < LastIndex - FirstIndex) {
-
-                               *pLen = LastIndex - FirstIndex;
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-
-                       for (Offset = 0, Index = FirstIndex;
-                               Index < LastIndex; Index ++) {
-
-                               if (VpdMayWrite(KeyArr[Index])) {
-
-                                       *(pBuf + Offset) = SK_PNMI_VPD_RW;
-                               }
-                               else {
-                                       *(pBuf + Offset) = SK_PNMI_VPD_RO;
-                               }
-                               Offset ++;
-                       }
-                       *pLen = Offset;
-                       break;
-
-               case OID_SKGE_VPD_ACTION:
-                       Offset = LastIndex - FirstIndex;
-                       if (*pLen < Offset) {
-
-                               *pLen = Offset;
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       SK_MEMSET(pBuf, 0, Offset);
-                       *pLen = Offset;
-                       break;
-
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
-                               SK_PNMI_ERR023MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-       }
-       else {
-               /* The only OID which can be set is VPD_ACTION */
-               if (Id != OID_SKGE_VPD_ACTION) {
-
-                       if (Id == OID_SKGE_VPD_FREE_BYTES ||
-                               Id == OID_SKGE_VPD_ENTRIES_LIST ||
-                               Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
-                               Id == OID_SKGE_VPD_KEY ||
-                               Id == OID_SKGE_VPD_VALUE ||
-                               Id == OID_SKGE_VPD_ACCESS) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_READ_ONLY);
-                       }
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
-                               SK_PNMI_ERR024MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               /*
-                * From this point we handle VPD_ACTION. Check the buffer
-                * length. It should at least have the size of one byte.
-                */
-               if (*pLen < 1) {
-
-                       *pLen = 1;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-
-               /*
-                * The first byte contains the VPD action type we should
-                * perform.
-                */
-               switch (*pBuf) {
-
-               case SK_PNMI_VPD_IGNORE:
-                       /* Nothing to do */
-                       break;
-
-               case SK_PNMI_VPD_CREATE:
-                       /*
-                        * We have to create a new VPD entry or we modify
-                        * an existing one. Check first the buffer length.
-                        */
-                       if (*pLen < 4) {
-
-                               *pLen = 4;
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       KeyStr[0] = pBuf[1];
-                       KeyStr[1] = pBuf[2];
-                       KeyStr[2] = 0;
-
-                       /*
-                        * Is the entry writable or does it belong to the
-                        * read-only area?
-                        */
-                       if (!VpdMayWrite(KeyStr)) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-
-                       Offset = (int)pBuf[3] & 0xFF;
-
-                       SK_MEMCPY(Buf, pBuf + 4, Offset);
-                       Buf[Offset] = 0;
-
-                       /* A preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-
-                               return (SK_PNMI_ERR_OK);
-                       }
-
-                       /* Write the new entry or modify an existing one */
-                       Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
-                       if (Ret == SK_PNMI_VPD_NOWRITE ) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-                       else if (Ret != SK_PNMI_VPD_OK) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
-                                       SK_PNMI_ERR025MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-
-                       /*
-                        * Perform an update of the VPD data. This is
-                        * not mandantory, but just to be sure.
-                        */
-                       Ret = VpdUpdate(pAC, IoC);
-                       if (Ret != SK_PNMI_VPD_OK) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
-                                       SK_PNMI_ERR026MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-                       break;
-
-               case SK_PNMI_VPD_DELETE:
-                       /* Check if the buffer size is plausible */
-                       if (*pLen < 3) {
-
-                               *pLen = 3;
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       if (*pLen > 3) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-                       KeyStr[0] = pBuf[1];
-                       KeyStr[1] = pBuf[2];
-                       KeyStr[2] = 0;
-
-                       /* Find the passed key in the array */
-                       for (Index = 0; Index < KeyNo; Index ++) {
-
-                               if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
-
-                                       break;
-                               }
-                       }
-                       /*
-                        * If we cannot find the key it is wrong, so we
-                        * return an appropriate error value.
-                        */
-                       if (Index == KeyNo) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-
-                       if (Action == SK_PNMI_PRESET) {
-
-                               return (SK_PNMI_ERR_OK);
-                       }
-
-                       /* Ok, you wanted it and you will get it */
-                       Ret = VpdDelete(pAC, IoC, KeyStr);
-                       if (Ret != SK_PNMI_VPD_OK) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
-                                       SK_PNMI_ERR027MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-
-                       /*
-                        * Perform an update of the VPD data. This is
-                        * not mandantory, but just to be sure.
-                        */
-                       Ret = VpdUpdate(pAC, IoC);
-                       if (Ret != SK_PNMI_VPD_OK) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
-                                       SK_PNMI_ERR028MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-                       break;
-
-               default:
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_BAD_VALUE);
-               }
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * General - OID handler function of various single instance OIDs
- *
- * Description:
- *     The code is simple. No description necessary.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int General(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* Get/PreSet/Set action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       int             Ret;
-       unsigned int    Index;
-       unsigned int    Len;
-       unsigned int    Offset;
-       unsigned int    Val;
-       SK_U8           Val8;
-       SK_U16          Val16;
-       SK_U32          Val32;
-       SK_U64          Val64;
-       SK_U64          Val64RxHwErrs = 0;
-       SK_U64          Val64TxHwErrs = 0;
-       SK_BOOL         Is64BitReq = SK_FALSE;
-       char            Buf[256];
-       int                     MacType;
-
-       /*
-        * Check instance. We only handle single instance variables
-        */
-       if (Instance != (SK_U32)(-1) && Instance != 1) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_UNKNOWN_INST);
-       }
-
-       /*
-        * Check action. We only allow get requests.
-        */
-       if (Action != SK_PNMI_GET) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_READ_ONLY);
-       }
-
-       MacType = pAC->GIni.GIMacType;
-
-       /*
-        * Check length for the various supported OIDs
-        */
-       switch (Id) {
-
-       case OID_GEN_XMIT_ERROR:
-       case OID_GEN_RCV_ERROR:
-       case OID_GEN_RCV_NO_BUFFER:
-#ifndef SK_NDIS_64BIT_CTR
-               if (*pLen < sizeof(SK_U32)) {
-                       *pLen = sizeof(SK_U32);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-
-#else /* SK_NDIS_64BIT_CTR */
-
-               /*
-                * for compatibility, at least 32bit are required for oid
-                */
-               if (*pLen < sizeof(SK_U32)) {
-                       /*
-                       * but indicate handling for 64bit values,
-                       * if insufficient space is provided
-                       */
-                       *pLen = sizeof(SK_U64);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-
-               Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
-#endif /* SK_NDIS_64BIT_CTR */
-               break;
-
-       case OID_SKGE_PORT_NUMBER:
-       case OID_SKGE_DEVICE_TYPE:
-       case OID_SKGE_RESULT:
-       case OID_SKGE_RLMT_MONITOR_NUMBER:
-       case OID_GEN_TRANSMIT_QUEUE_LENGTH:
-       case OID_SKGE_TRAP_NUMBER:
-       case OID_SKGE_MDB_VERSION:
-               if (*pLen < sizeof(SK_U32)) {
-
-                       *pLen = sizeof(SK_U32);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       case OID_SKGE_CHIPSET:
-               if (*pLen < sizeof(SK_U16)) {
-
-                       *pLen = sizeof(SK_U16);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       case OID_SKGE_BUS_TYPE:
-       case OID_SKGE_BUS_SPEED:
-       case OID_SKGE_BUS_WIDTH:
-       case OID_SKGE_SENSOR_NUMBER:
-       case OID_SKGE_CHKSM_NUMBER:
-               if (*pLen < sizeof(SK_U8)) {
-
-                       *pLen = sizeof(SK_U8);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       case OID_SKGE_TX_SW_QUEUE_LEN:
-       case OID_SKGE_TX_SW_QUEUE_MAX:
-       case OID_SKGE_TX_RETRY:
-       case OID_SKGE_RX_INTR_CTS:
-       case OID_SKGE_TX_INTR_CTS:
-       case OID_SKGE_RX_NO_BUF_CTS:
-       case OID_SKGE_TX_NO_BUF_CTS:
-       case OID_SKGE_TX_USED_DESCR_NO:
-       case OID_SKGE_RX_DELIVERED_CTS:
-       case OID_SKGE_RX_OCTETS_DELIV_CTS:
-       case OID_SKGE_RX_HW_ERROR_CTS:
-       case OID_SKGE_TX_HW_ERROR_CTS:
-       case OID_SKGE_IN_ERRORS_CTS:
-       case OID_SKGE_OUT_ERROR_CTS:
-       case OID_SKGE_ERR_RECOVERY_CTS:
-       case OID_SKGE_SYSUPTIME:
-               if (*pLen < sizeof(SK_U64)) {
-
-                       *pLen = sizeof(SK_U64);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       default:
-               /* Checked later */
-               break;
-       }
-
-       /* Update statistic */
-       if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
-               Id == OID_SKGE_TX_HW_ERROR_CTS ||
-               Id == OID_SKGE_IN_ERRORS_CTS ||
-               Id == OID_SKGE_OUT_ERROR_CTS ||
-               Id == OID_GEN_XMIT_ERROR ||
-               Id == OID_GEN_RCV_ERROR) {
-
-               /* Force the XMAC to update its statistic counters and
-                * Increment semaphore to indicate that an update was
-                * already done.
-                */
-               Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
-               if (Ret != SK_PNMI_ERR_OK) {
-
-                       *pLen = 0;
-                       return (Ret);
-               }
-               pAC->Pnmi.MacUpdatedFlag ++;
-
-               /*
-                * Some OIDs consist of multiple hardware counters. Those
-                * values which are contained in all of them will be added
-                * now.
-                */
-               switch (Id) {
-
-               case OID_SKGE_RX_HW_ERROR_CTS:
-               case OID_SKGE_IN_ERRORS_CTS:
-               case OID_GEN_RCV_ERROR:
-                       Val64RxHwErrs =
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex)+
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex)+
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
-               break;
-
-               case OID_SKGE_TX_HW_ERROR_CTS:
-               case OID_SKGE_OUT_ERROR_CTS:
-               case OID_GEN_XMIT_ERROR:
-                       Val64TxHwErrs =
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex)+
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex)+
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
-                       break;
-               }
-       }
-
-       /*
-        * Retrieve value
-        */
-       switch (Id) {
-
-       case OID_SKGE_SUPPORTED_LIST:
-               Len = ID_TABLE_SIZE * sizeof(SK_U32);
-               if (*pLen < Len) {
-
-                       *pLen = Len;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               for (Offset = 0, Index = 0; Offset < Len;
-                       Offset += sizeof(SK_U32), Index ++) {
-
-                       Val32 = (SK_U32)IdTable[Index].Id;
-                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-               }
-               *pLen = Len;
-               break;
-
-       case OID_SKGE_PORT_NUMBER:
-               Val32 = (SK_U32)pAC->GIni.GIMacsFound;
-               SK_PNMI_STORE_U32(pBuf, Val32);
-               *pLen = sizeof(SK_U32);
-               break;
-
-       case OID_SKGE_DEVICE_TYPE:
-               Val32 = (SK_U32)pAC->Pnmi.DeviceType;
-               SK_PNMI_STORE_U32(pBuf, Val32);
-               *pLen = sizeof(SK_U32);
-               break;
-
-       case OID_SKGE_DRIVER_DESCR:
-               if (pAC->Pnmi.pDriverDescription == NULL) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
-                               SK_PNMI_ERR007MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
-               if (Len > SK_PNMI_STRINGLEN1) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
-                               SK_PNMI_ERR029MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               if (*pLen < Len) {
-
-                       *pLen = Len;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               *pBuf = (char)(Len - 1);
-               SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
-               *pLen = Len;
-               break;
-
-       case OID_SKGE_DRIVER_VERSION:
-               if (pAC->Pnmi.pDriverVersion == NULL) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
-                               SK_PNMI_ERR030MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
-               if (Len > SK_PNMI_STRINGLEN1) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
-                               SK_PNMI_ERR031MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               if (*pLen < Len) {
-
-                       *pLen = Len;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               *pBuf = (char)(Len - 1);
-               SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
-               *pLen = Len;
-               break;
-
-       case OID_SKGE_HW_DESCR:
-               /*
-                * The hardware description is located in the VPD. This
-                * query may move to the initialisation routine. But
-                * the VPD data is cached and therefore a call here
-                * will not make much difference.
-                */
-               Len = 256;
-               if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
-                               SK_PNMI_ERR032MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-               Len ++;
-               if (Len > SK_PNMI_STRINGLEN1) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
-                               SK_PNMI_ERR033MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-               if (*pLen < Len) {
-
-                       *pLen = Len;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               *pBuf = (char)(Len - 1);
-               SK_MEMCPY(pBuf + 1, Buf, Len - 1);
-               *pLen = Len;
-               break;
-
-       case OID_SKGE_HW_VERSION:
-               /* Oh, I love to do some string manipulation */
-               if (*pLen < 5) {
-
-                       *pLen = 5;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
-               pBuf[0] = 4;
-               pBuf[1] = 'v';
-               pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
-               pBuf[3] = '.';
-               pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
-               *pLen = 5;
-               break;
-
-       case OID_SKGE_CHIPSET:
-               Val16 = pAC->Pnmi.Chipset;
-               SK_PNMI_STORE_U16(pBuf, Val16);
-               *pLen = sizeof(SK_U16);
-               break;
-
-       case OID_SKGE_BUS_TYPE:
-               *pBuf = (char)SK_PNMI_BUS_PCI;
-               *pLen = sizeof(char);
-               break;
-
-       case OID_SKGE_BUS_SPEED:
-               *pBuf = pAC->Pnmi.PciBusSpeed;
-               *pLen = sizeof(char);
-               break;
-
-       case OID_SKGE_BUS_WIDTH:
-               *pBuf = pAC->Pnmi.PciBusWidth;
-               *pLen = sizeof(char);
-               break;
-
-       case OID_SKGE_RESULT:
-               Val32 = pAC->Pnmi.TestResult;
-               SK_PNMI_STORE_U32(pBuf, Val32);
-               *pLen = sizeof(SK_U32);
-               break;
-
-       case OID_SKGE_SENSOR_NUMBER:
-               *pBuf = (char)pAC->I2c.MaxSens;
-               *pLen = sizeof(char);
-               break;
-
-       case OID_SKGE_CHKSM_NUMBER:
-               *pBuf = SKCS_NUM_PROTOCOLS;
-               *pLen = sizeof(char);
-               break;
-
-       case OID_SKGE_TRAP_NUMBER:
-               GetTrapQueueLen(pAC, &Len, &Val);
-               Val32 = (SK_U32)Val;
-               SK_PNMI_STORE_U32(pBuf, Val32);
-               *pLen = sizeof(SK_U32);
-               break;
-
-       case OID_SKGE_TRAP:
-               GetTrapQueueLen(pAC, &Len, &Val);
-               if (*pLen < Len) {
-
-                       *pLen = Len;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               CopyTrapQueue(pAC, pBuf);
-               *pLen = Len;
-               break;
-
-       case OID_SKGE_RLMT_MONITOR_NUMBER:
-/* XXX Not yet implemented by RLMT therefore we return zero elements */
-               Val32 = 0;
-               SK_PNMI_STORE_U32(pBuf, Val32);
-               *pLen = sizeof(SK_U32);
-               break;
-
-       case OID_SKGE_TX_SW_QUEUE_LEN:
-               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
-                                       pAC->Pnmi.BufPort[1].TxSwQueueLen;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
-                                       pAC->Pnmi.Port[1].TxSwQueueLen;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-
-       case OID_SKGE_TX_SW_QUEUE_MAX:
-               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
-                                       pAC->Pnmi.BufPort[1].TxSwQueueMax;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
-                                       pAC->Pnmi.Port[1].TxSwQueueMax;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_TX_RETRY:
-               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
-                                       pAC->Pnmi.BufPort[1].TxRetryCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].TxRetryCts +
-                                       pAC->Pnmi.Port[1].TxRetryCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_RX_INTR_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
-                                       pAC->Pnmi.BufPort[1].RxIntrCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].RxIntrCts +
-                                       pAC->Pnmi.Port[1].RxIntrCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_TX_INTR_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
-                                       pAC->Pnmi.BufPort[1].TxIntrCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].TxIntrCts +
-                                       pAC->Pnmi.Port[1].TxIntrCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_RX_NO_BUF_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
-                                       pAC->Pnmi.BufPort[1].RxNoBufCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
-                                       pAC->Pnmi.Port[1].RxNoBufCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_TX_NO_BUF_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
-                                       pAC->Pnmi.BufPort[1].TxNoBufCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
-                                       pAC->Pnmi.Port[1].TxNoBufCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_TX_USED_DESCR_NO:
-               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
-                                       pAC->Pnmi.BufPort[1].TxUsedDescrNo;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
-                                       pAC->Pnmi.Port[1].TxUsedDescrNo;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_RX_DELIVERED_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
-                                       pAC->Pnmi.BufPort[1].RxDeliveredCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
-                                       pAC->Pnmi.Port[1].RxDeliveredCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_RX_OCTETS_DELIV_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
-                                       pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
-                                       pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_RX_HW_ERROR_CTS:
-               SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_TX_HW_ERROR_CTS:
-               SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_IN_ERRORS_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = Val64RxHwErrs +
-                                       pAC->Pnmi.BufPort[0].RxNoBufCts +
-                                       pAC->Pnmi.BufPort[1].RxNoBufCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = Val64RxHwErrs +
-                                       pAC->Pnmi.Port[0].RxNoBufCts +
-                                       pAC->Pnmi.Port[1].RxNoBufCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_OUT_ERROR_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = Val64TxHwErrs +
-                                       pAC->Pnmi.BufPort[0].TxNoBufCts +
-                                       pAC->Pnmi.BufPort[1].TxNoBufCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = Val64TxHwErrs +
-                                       pAC->Pnmi.Port[0].TxNoBufCts +
-                                       pAC->Pnmi.Port[1].TxNoBufCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_ERR_RECOVERY_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
-                                       pAC->Pnmi.BufPort[1].ErrRecoveryCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
-                                       pAC->Pnmi.Port[1].ErrRecoveryCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_SYSUPTIME:
-               Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
-               Val64 -= pAC->Pnmi.StartUpTime;
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_MDB_VERSION:
-               Val32 = SK_PNMI_MDB_VERSION;
-               SK_PNMI_STORE_U32(pBuf, Val32);
-               *pLen = sizeof(SK_U32);
-               break;
-
-       case OID_GEN_RCV_ERROR:
-               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
-               }
-               else {
-                       Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
-               }
-
-               /*
-                * by default 32bit values are evaluated
-                */
-               if (!Is64BitReq) {
-                       Val32 = (SK_U32)Val64;
-                       SK_PNMI_STORE_U32(pBuf, Val32);
-                       *pLen = sizeof(SK_U32);
-               }
-               else {
-                       SK_PNMI_STORE_U64(pBuf, Val64);
-                       *pLen = sizeof(SK_U64);
-               }
-               break;
-
-       case OID_GEN_XMIT_ERROR:
-               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
-               }
-               else {
-                       Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
-               }
-
-               /*
-                * by default 32bit values are evaluated
-                */
-               if (!Is64BitReq) {
-                       Val32 = (SK_U32)Val64;
-                       SK_PNMI_STORE_U32(pBuf, Val32);
-                       *pLen = sizeof(SK_U32);
-               }
-               else {
-                       SK_PNMI_STORE_U64(pBuf, Val64);
-                       *pLen = sizeof(SK_U64);
-               }
-               break;
-
-       case OID_GEN_RCV_NO_BUFFER:
-               /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
-               }
-               else {
-                       Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
-               }
-
-               /*
-                * by default 32bit values are evaluated
-                */
-               if (!Is64BitReq) {
-                       Val32 = (SK_U32)Val64;
-                       SK_PNMI_STORE_U32(pBuf, Val32);
-                       *pLen = sizeof(SK_U32);
-               }
-               else {
-                       SK_PNMI_STORE_U64(pBuf, Val64);
-                       *pLen = sizeof(SK_U64);
-               }
-               break;
-
-       case OID_GEN_TRANSMIT_QUEUE_LENGTH:
-               Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
-               SK_PNMI_STORE_U32(pBuf, Val32);
-               *pLen = sizeof(SK_U32);
-               break;
-
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
-                       SK_PNMI_ERR034MSG);
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_GENERAL);
-       }
-
-       if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
-               Id == OID_SKGE_TX_HW_ERROR_CTS ||
-               Id == OID_SKGE_IN_ERRORS_CTS ||
-               Id == OID_SKGE_OUT_ERROR_CTS ||
-               Id == OID_GEN_XMIT_ERROR ||
-               Id == OID_GEN_RCV_ERROR) {
-
-               pAC->Pnmi.MacUpdatedFlag --;
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
- *
- * Description:
- *     Get/Presets/Sets the RLMT OIDs.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int Rlmt(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* Get/PreSet/Set action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       int             Ret;
-       unsigned int    PhysPortIndex;
-       unsigned int    PhysPortMax;
-       SK_EVPARA       EventParam;
-       SK_U32          Val32;
-       SK_U64          Val64;
-
-
-       /*
-        * Check instance. Only single instance OIDs are allowed here.
-        */
-       if (Instance != (SK_U32)(-1) && Instance != 1) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_UNKNOWN_INST);
-       }
-
-       /*
-        * Perform the requested action
-        */
-       if (Action == SK_PNMI_GET) {
-
-               /*
-                * Check if the buffer length is large enough.
-                */
-
-               switch (Id) {
-
-               case OID_SKGE_RLMT_MODE:
-               case OID_SKGE_RLMT_PORT_ACTIVE:
-               case OID_SKGE_RLMT_PORT_PREFERRED:
-                       if (*pLen < sizeof(SK_U8)) {
-
-                               *pLen = sizeof(SK_U8);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       break;
-
-               case OID_SKGE_RLMT_PORT_NUMBER:
-                       if (*pLen < sizeof(SK_U32)) {
-
-                               *pLen = sizeof(SK_U32);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       break;
-
-               case OID_SKGE_RLMT_CHANGE_CTS:
-               case OID_SKGE_RLMT_CHANGE_TIME:
-               case OID_SKGE_RLMT_CHANGE_ESTIM:
-               case OID_SKGE_RLMT_CHANGE_THRES:
-                       if (*pLen < sizeof(SK_U64)) {
-
-                               *pLen = sizeof(SK_U64);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       break;
-
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
-                               SK_PNMI_ERR035MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               /*
-                * Update RLMT statistic and increment semaphores to indicate
-                * that an update was already done. Maybe RLMT will hold its
-                * statistic always up to date some time. Then we can
-                * remove this type of call.
-                */
-               if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
-
-                       *pLen = 0;
-                       return (Ret);
-               }
-               pAC->Pnmi.RlmtUpdatedFlag ++;
-
-               /*
-                * Retrieve Value
-               */
-               switch (Id) {
-
-               case OID_SKGE_RLMT_MODE:
-                       *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
-                       *pLen = sizeof(char);
-                       break;
-
-               case OID_SKGE_RLMT_PORT_NUMBER:
-                       Val32 = (SK_U32)pAC->GIni.GIMacsFound;
-                       SK_PNMI_STORE_U32(pBuf, Val32);
-                       *pLen = sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_RLMT_PORT_ACTIVE:
-                       *pBuf = 0;
-                       /*
-                        * If multiple ports may become active this OID
-                        * doesn't make sense any more. A new variable in
-                        * the port structure should be created. However,
-                        * for this variable the first active port is
-                        * returned.
-                        */
-                       PhysPortMax = pAC->GIni.GIMacsFound;
-
-                       for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
-                               PhysPortIndex ++) {
-
-                               if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
-                                       *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
-                                       break;
-                               }
-                       }
-                       *pLen = sizeof(char);
-                       break;
-
-               case OID_SKGE_RLMT_PORT_PREFERRED:
-                       *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
-                       *pLen = sizeof(char);
-                       break;
-
-               case OID_SKGE_RLMT_CHANGE_CTS:
-                       Val64 = pAC->Pnmi.RlmtChangeCts;
-                       SK_PNMI_STORE_U64(pBuf, Val64);
-                       *pLen = sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_RLMT_CHANGE_TIME:
-                       Val64 = pAC->Pnmi.RlmtChangeTime;
-                       SK_PNMI_STORE_U64(pBuf, Val64);
-                       *pLen = sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_RLMT_CHANGE_ESTIM:
-                       Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
-                       SK_PNMI_STORE_U64(pBuf, Val64);
-                       *pLen = sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_RLMT_CHANGE_THRES:
-                       Val64 = pAC->Pnmi.RlmtChangeThreshold;
-                       SK_PNMI_STORE_U64(pBuf, Val64);
-                       *pLen = sizeof(SK_U64);
-                       break;
-
-               default:
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
-                               ("Rlmt: Unknown OID should be handled before"));
-
-                       pAC->Pnmi.RlmtUpdatedFlag --;
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               pAC->Pnmi.RlmtUpdatedFlag --;
-       }
-       else {
-               /* Perform a preset or set */
-               switch (Id) {
-
-               case OID_SKGE_RLMT_MODE:
-                       /* Check if the buffer length is plausible */
-                       if (*pLen < sizeof(char)) {
-
-                               *pLen = sizeof(char);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       /* Check if the value range is correct */
-                       if (*pLen != sizeof(char) ||
-                               (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
-                               *(SK_U8 *)pBuf > 15) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-                       /* The preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_OK);
-                       }
-                       /* Send an event to RLMT to change the mode */
-                       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
-                       EventParam.Para32[0] |= (SK_U32)(*pBuf);
-                       EventParam.Para32[1] = 0;
-                       if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
-                               EventParam) > 0) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
-                                       SK_PNMI_ERR037MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-                       break;
-
-               case OID_SKGE_RLMT_PORT_PREFERRED:
-                       /* Check if the buffer length is plausible */
-                       if (*pLen < sizeof(char)) {
-
-                               *pLen = sizeof(char);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       /* Check if the value range is correct */
-                       if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
-                               (SK_U8)pAC->GIni.GIMacsFound) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-                       /* The preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_OK);
-                       }
-
-                       /*
-                        * Send an event to RLMT change the preferred port.
-                        * A param of -1 means automatic mode. RLMT will
-                        * make the decision which is the preferred port.
-                        */
-                       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
-                       EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
-                       EventParam.Para32[1] = NetIndex;
-                       if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
-                               EventParam) > 0) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
-                                       SK_PNMI_ERR038MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-                       break;
-
-               case OID_SKGE_RLMT_CHANGE_THRES:
-                       /* Check if the buffer length is plausible */
-                       if (*pLen < sizeof(SK_U64)) {
-
-                               *pLen = sizeof(SK_U64);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       /*
-                        * There are not many restrictions to the
-                        * value range.
-                        */
-                       if (*pLen != sizeof(SK_U64)) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-                       /* A preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_OK);
-                       }
-                       /*
-                        * Store the new threshold, which will be taken
-                        * on the next timer event.
-                        */
-                       SK_PNMI_READ_U64(pBuf, Val64);
-                       pAC->Pnmi.RlmtChangeThreshold = Val64;
-                       break;
-
-               default:
-                       /* The other OIDs are not be able for set */
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_READ_ONLY);
-               }
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
- *
- * Description:
- *     Performs get requests on multiple instance variables.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int RlmtStat(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* Get/PreSet/Set action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       unsigned int    PhysPortMax;
-       unsigned int    PhysPortIndex;
-       unsigned int    Limit;
-       unsigned int    Offset;
-       int             Ret;
-       SK_U32          Val32;
-       SK_U64          Val64;
-
-       /*
-        * Calculate the port indexes from the instance
-        */
-       PhysPortMax = pAC->GIni.GIMacsFound;
-
-       if ((Instance != (SK_U32)(-1))) {
-               /* Check instance range */
-               if ((Instance < 1) || (Instance > PhysPortMax)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-
-               /* Single net mode */
-               PhysPortIndex = Instance - 1;
-
-               /* Dual net mode */
-               if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                       PhysPortIndex = NetIndex;
-               }
-
-               /* Both net modes */
-               Limit = PhysPortIndex + 1;
-       }
-       else {
-               /* Single net mode */
-               PhysPortIndex = 0;
-               Limit = PhysPortMax;
-
-               /* Dual net mode */
-               if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                       PhysPortIndex = NetIndex;
-                       Limit = PhysPortIndex + 1;
-               }
-       }
-
-       /*
-        * Currently only get requests are allowed.
-        */
-       if (Action != SK_PNMI_GET) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_READ_ONLY);
-       }
-
-       /*
-        * Check if the buffer length is large enough.
-        */
-       switch (Id) {
-
-       case OID_SKGE_RLMT_PORT_INDEX:
-       case OID_SKGE_RLMT_STATUS:
-               if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
-
-                       *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       case OID_SKGE_RLMT_TX_HELLO_CTS:
-       case OID_SKGE_RLMT_RX_HELLO_CTS:
-       case OID_SKGE_RLMT_TX_SP_REQ_CTS:
-       case OID_SKGE_RLMT_RX_SP_CTS:
-               if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
-
-                       *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
-                       SK_PNMI_ERR039MSG);
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_GENERAL);
-
-       }
-
-       /*
-        * Update statistic and increment semaphores to indicate that
-        * an update was already done.
-        */
-       if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
-
-               *pLen = 0;
-               return (Ret);
-       }
-       pAC->Pnmi.RlmtUpdatedFlag ++;
-
-       /*
-        * Get value
-        */
-       Offset = 0;
-       for (; PhysPortIndex < Limit; PhysPortIndex ++) {
-
-               switch (Id) {
-
-               case OID_SKGE_RLMT_PORT_INDEX:
-                       Val32 = PhysPortIndex;
-                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-                       Offset += sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_RLMT_STATUS:
-                       if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
-                               SK_RLMT_PS_INIT ||
-                               pAC->Rlmt.Port[PhysPortIndex].PortState ==
-                               SK_RLMT_PS_DOWN) {
-
-                               Val32 = SK_PNMI_RLMT_STATUS_ERROR;
-                       }
-                       else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
-                               Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
-                       }
-                       else {
-                               Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
-                       }
-                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-                       Offset += sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_RLMT_TX_HELLO_CTS:
-                       Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
-                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
-                       Offset += sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_RLMT_RX_HELLO_CTS:
-                       Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
-                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
-                       Offset += sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_RLMT_TX_SP_REQ_CTS:
-                       Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
-                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
-                       Offset += sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_RLMT_RX_SP_CTS:
-                       Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
-                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
-                       Offset += sizeof(SK_U64);
-                       break;
-
-               default:
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
-                               ("RlmtStat: Unknown OID should be errored before"));
-
-                       pAC->Pnmi.RlmtUpdatedFlag --;
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-       }
-       *pLen = Offset;
-
-       pAC->Pnmi.RlmtUpdatedFlag --;
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * MacPrivateConf - OID handler function of OIDs concerning the configuration
- *
- * Description:
- *     Get/Presets/Sets the OIDs concerning the configuration.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int MacPrivateConf(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* Get/PreSet/Set action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       unsigned int    PhysPortMax;
-       unsigned int    PhysPortIndex;
-       unsigned int    LogPortMax;
-       unsigned int    LogPortIndex;
-       unsigned int    Limit;
-       unsigned int    Offset;
-       char            Val8;
-       int             Ret;
-       SK_EVPARA       EventParam;
-       SK_U32          Val32;
-
-
-       /*
-        * Calculate instance if wished. MAC index 0 is the virtual
-        * MAC.
-        */
-       PhysPortMax = pAC->GIni.GIMacsFound;
-       LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
-
-       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
-               LogPortMax--;
-       }
-
-       if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
-               /* Check instance range */
-               if ((Instance < 1) || (Instance > LogPortMax)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-               LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
-               Limit = LogPortIndex + 1;
-       }
-
-       else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
-
-               LogPortIndex = 0;
-               Limit = LogPortMax;
-       }
-
-       /*
-        * Perform action
-        */
-       if (Action == SK_PNMI_GET) {
-
-               /*
-                * Check length
-                */
-               switch (Id) {
-
-               case OID_SKGE_PMD:
-               case OID_SKGE_CONNECTOR:
-               case OID_SKGE_LINK_CAP:
-               case OID_SKGE_LINK_MODE:
-               case OID_SKGE_LINK_MODE_STATUS:
-               case OID_SKGE_LINK_STATUS:
-               case OID_SKGE_FLOWCTRL_CAP:
-               case OID_SKGE_FLOWCTRL_MODE:
-               case OID_SKGE_FLOWCTRL_STATUS:
-               case OID_SKGE_PHY_OPERATION_CAP:
-               case OID_SKGE_PHY_OPERATION_MODE:
-               case OID_SKGE_PHY_OPERATION_STATUS:
-               case OID_SKGE_SPEED_CAP:
-               case OID_SKGE_SPEED_MODE:
-               case OID_SKGE_SPEED_STATUS:
-                       if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
-
-                               *pLen = (Limit - LogPortIndex) *
-                                       sizeof(SK_U8);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       break;
-
-       case OID_SKGE_MTU:
-                       if (*pLen < sizeof(SK_U32)) {
-
-                               *pLen = sizeof(SK_U32);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       break;
-
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
-                               SK_PNMI_ERR041MSG);
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               /*
-                * Update statistic and increment semaphore to indicate
-                * that an update was already done.
-                */
-               if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
-
-                       *pLen = 0;
-                       return (Ret);
-               }
-               pAC->Pnmi.SirqUpdatedFlag ++;
-
-               /*
-                * Get value
-                */
-               Offset = 0;
-               for (; LogPortIndex < Limit; LogPortIndex ++) {
-
-                       switch (Id) {
-
-                       case OID_SKGE_PMD:
-                               *(pBuf + Offset) = pAC->Pnmi.PMD;
-                               Offset += sizeof(char);
-                               break;
-
-                       case OID_SKGE_CONNECTOR:
-                               *(pBuf + Offset) = pAC->Pnmi.Connector;
-                               Offset += sizeof(char);
-                               break;
-
-                       case OID_SKGE_LINK_CAP:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBuf +
-                                                       Offset);
-                                       }
-                                       else {
-                                               /* Get value for physical ports */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-
-                                               *(pBuf + Offset) = pAC->GIni.GP[
-                                                       PhysPortIndex].PLinkCap;
-                                       }
-                                       Offset += sizeof(char);
-                               }
-                               else { /* DualNetMode */
-
-                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkCap;
-                                       Offset += sizeof(char);
-                               }
-                               break;
-
-                       case OID_SKGE_LINK_MODE:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBuf +
-                                               Offset);
-                                       }
-                                       else {
-                                               /* Get value for physical ports */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-
-                                               *(pBuf + Offset) = pAC->GIni.GP[
-                                                       PhysPortIndex].PLinkModeConf;
-                                       }
-                                       Offset += sizeof(char);
-                               }
-                               else { /* DualNetMode */
-
-                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkModeConf;
-                                       Offset += sizeof(char);
-                               }
-                               break;
-
-                       case OID_SKGE_LINK_MODE_STATUS:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBuf +
-                                                       Offset);
-                                       }
-                                       else {
-                                               /* Get value for physical port */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-
-                                               *(pBuf + Offset) =
-                                                       CalculateLinkModeStatus(pAC,
-                                                               IoC, PhysPortIndex);
-                                       }
-                                       Offset += sizeof(char);
-                               }
-                               else { /* DualNetMode */
-                                       *(pBuf + Offset) = CalculateLinkModeStatus(pAC, IoC, NetIndex);
-                                       Offset += sizeof(char);
-                               }
-                               break;
-
-                       case OID_SKGE_LINK_STATUS:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBuf +
-                                                       Offset);
-                                       }
-                                       else {
-                                               /* Get value for physical ports */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-
-                                               *(pBuf + Offset) =
-                                                       CalculateLinkStatus(pAC,
-                                                               IoC, PhysPortIndex);
-                                       }
-                                       Offset += sizeof(char);
-                               }
-                               else { /* DualNetMode */
-
-                                       *(pBuf + Offset) = CalculateLinkStatus(pAC, IoC, NetIndex);
-                                       Offset += sizeof(char);
-                               }
-                               break;
-
-                       case OID_SKGE_FLOWCTRL_CAP:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBuf +
-                                                       Offset);
-                                       }
-                                       else {
-                                               /* Get value for physical ports */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-
-                                               *(pBuf + Offset) = pAC->GIni.GP[
-                                                       PhysPortIndex].PFlowCtrlCap;
-                                       }
-                                       Offset += sizeof(char);
-                               }
-                               else { /* DualNetMode */
-
-                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
-                                       Offset += sizeof(char);
-                               }
-                               break;
-
-                       case OID_SKGE_FLOWCTRL_MODE:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBuf +
-                                                       Offset);
-                                       }
-                                       else {
-                                               /* Get value for physical port */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-
-                                               *(pBuf + Offset) = pAC->GIni.GP[
-                                                       PhysPortIndex].PFlowCtrlMode;
-                                       }
-                                       Offset += sizeof(char);
-                               }
-                               else { /* DualNetMode */
-
-                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
-                                       Offset += sizeof(char);
-                               }
-                               break;
-
-                       case OID_SKGE_FLOWCTRL_STATUS:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBuf +
-                                                       Offset);
-                                       }
-                                       else {
-                                               /* Get value for physical port */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-
-                                               *(pBuf + Offset) = pAC->GIni.GP[
-                                                       PhysPortIndex].PFlowCtrlStatus;
-                                       }
-                                       Offset += sizeof(char);
-                               }
-                               else { /* DualNetMode */
-
-                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
-                                       Offset += sizeof(char);
-                               }
-                               break;
-
-                       case OID_SKGE_PHY_OPERATION_CAP:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBuf +
-                                                       Offset);
-                                       }
-                                       else {
-                                               /* Get value for physical ports */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-
-                                               *(pBuf + Offset) = pAC->GIni.GP[
-                                                       PhysPortIndex].PMSCap;
-                                       }
-                                       Offset += sizeof(char);
-                               }
-                               else { /* DualNetMode */
-
-                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSCap;
-                                       Offset += sizeof(char);
-                               }
-                               break;
-
-                       case OID_SKGE_PHY_OPERATION_MODE:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBuf + Offset);
-                                       }
-                                       else {
-                                               /* Get value for physical port */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-
-                                               *(pBuf + Offset) = pAC->GIni.GP[
-                                                       PhysPortIndex].PMSMode;
-                                       }
-                                       Offset += sizeof(char);
-                               }
-                               else { /* DualNetMode */
-
-                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSMode;
-                                       Offset += sizeof(char);
-                               }
-                               break;
-
-                       case OID_SKGE_PHY_OPERATION_STATUS:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBuf + Offset);
-                                       }
-                                       else {
-                                               /* Get value for physical port */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-
-                                               *(pBuf + Offset) = pAC->GIni.GP[
-                                                       PhysPortIndex].PMSStatus;
-                                       }
-                                       Offset += sizeof(char);
-                               }
-                               else {
-
-                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSStatus;
-                                       Offset += sizeof(char);
-                               }
-                               break;
-
-                       case OID_SKGE_SPEED_CAP:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBuf +
-                                                       Offset);
-                                       }
-                                       else {
-                                               /* Get value for physical ports */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-
-                                               *(pBuf + Offset) = pAC->GIni.GP[
-                                                       PhysPortIndex].PLinkSpeedCap;
-                                       }
-                                       Offset += sizeof(char);
-                               }
-                               else { /* DualNetMode */
-
-                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
-                                       Offset += sizeof(char);
-                               }
-                               break;
-
-                       case OID_SKGE_SPEED_MODE:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBuf + Offset);
-                                       }
-                                       else {
-                                               /* Get value for physical port */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-
-                                               *(pBuf + Offset) = pAC->GIni.GP[
-                                                       PhysPortIndex].PLinkSpeed;
-                                       }
-                                       Offset += sizeof(char);
-                               }
-                               else { /* DualNetMode */
-
-                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeed;
-                                       Offset += sizeof(char);
-                               }
-                               break;
-
-                       case OID_SKGE_SPEED_STATUS:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBuf + Offset);
-                                       }
-                                       else {
-                                               /* Get value for physical port */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-
-                                               *(pBuf + Offset) = pAC->GIni.GP[
-                                                       PhysPortIndex].PLinkSpeedUsed;
-                                       }
-                                       Offset += sizeof(char);
-                               }
-                               else { /* DualNetMode */
-
-                                       *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
-                                       Offset += sizeof(char);
-                               }
-                               break;
-
-                       case OID_SKGE_MTU:
-                               Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
-                               SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-                               Offset += sizeof(SK_U32);
-                               break;
-
-                       default:
-                               SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
-                                       ("MacPrivateConf: Unknown OID should be handled before"));
-
-                               pAC->Pnmi.SirqUpdatedFlag --;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-               }
-               *pLen = Offset;
-               pAC->Pnmi.SirqUpdatedFlag --;
-
-               return (SK_PNMI_ERR_OK);
-       }
-
-       /*
-        * From here SET or PRESET action. Check if the passed
-        * buffer length is plausible.
-        */
-       switch (Id) {
-
-       case OID_SKGE_LINK_MODE:
-       case OID_SKGE_FLOWCTRL_MODE:
-       case OID_SKGE_PHY_OPERATION_MODE:
-       case OID_SKGE_SPEED_MODE:
-               if (*pLen < Limit - LogPortIndex) {
-
-                       *pLen = Limit - LogPortIndex;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               if (*pLen != Limit - LogPortIndex) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_BAD_VALUE);
-               }
-               break;
-
-       case OID_SKGE_MTU:
-               if (*pLen < sizeof(SK_U32)) {
-
-                       *pLen = sizeof(SK_U32);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               if (*pLen != sizeof(SK_U32)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_BAD_VALUE);
-               }
-               break;
-
-    default:
-               *pLen = 0;
-               return (SK_PNMI_ERR_READ_ONLY);
-       }
-
-       /*
-        * Perform preset or set
-        */
-       Offset = 0;
-       for (; LogPortIndex < Limit; LogPortIndex ++) {
-
-               switch (Id) {
-
-               case OID_SKGE_LINK_MODE:
-                       /* Check the value range */
-                       Val8 = *(pBuf + Offset);
-                       if (Val8 == 0) {
-
-                               Offset += sizeof(char);
-                               break;
-                       }
-                       if (Val8 < SK_LMODE_HALF ||
-                               (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
-                               (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-
-                       /* The preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-
-                               return (SK_PNMI_ERR_OK);
-                       }
-
-                       if (LogPortIndex == 0) {
-
-                               /*
-                                * The virtual port consists of all currently
-                                * active ports. Find them and send an event
-                                * with the new link mode to SIRQ.
-                                */
-                               for (PhysPortIndex = 0;
-                                       PhysPortIndex < PhysPortMax;
-                                       PhysPortIndex ++) {
-
-                                       if (!pAC->Pnmi.Port[PhysPortIndex].
-                                               ActiveFlag) {
-
-                                               continue;
-                                       }
-
-                                       EventParam.Para32[0] = PhysPortIndex;
-                                       EventParam.Para32[1] = (SK_U32)Val8;
-                                       if (SkGeSirqEvent(pAC, IoC,
-                                               SK_HWEV_SET_LMODE,
-                                               EventParam) > 0) {
-
-                                               SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                                       SK_PNMI_ERR043,
-                                                       SK_PNMI_ERR043MSG);
-
-                                               *pLen = 0;
-                                               return (SK_PNMI_ERR_GENERAL);
-                                       }
-                               }
-                       }
-                       else {
-                               /*
-                                * Send an event with the new link mode to
-                                * the SIRQ module.
-                                */
-                               EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
-                                       pAC, LogPortIndex);
-                               EventParam.Para32[1] = (SK_U32)Val8;
-                               if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
-                                       EventParam) > 0) {
-
-                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                               SK_PNMI_ERR043,
-                                               SK_PNMI_ERR043MSG);
-
-                                       *pLen = 0;
-                                       return (SK_PNMI_ERR_GENERAL);
-                               }
-                       }
-                       Offset += sizeof(char);
-                       break;
-
-               case OID_SKGE_FLOWCTRL_MODE:
-                       /* Check the value range */
-                       Val8 = *(pBuf + Offset);
-                       if (Val8 == 0) {
-
-                               Offset += sizeof(char);
-                               break;
-                       }
-                       if (Val8 < SK_FLOW_MODE_NONE ||
-                               (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
-                               (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-
-                       /* The preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-
-                               return (SK_PNMI_ERR_OK);
-                       }
-
-                       if (LogPortIndex == 0) {
-
-                               /*
-                                * The virtual port consists of all currently
-                                * active ports. Find them and send an event
-                                * with the new flow control mode to SIRQ.
-                                */
-                               for (PhysPortIndex = 0;
-                                       PhysPortIndex < PhysPortMax;
-                                       PhysPortIndex ++) {
-
-                                       if (!pAC->Pnmi.Port[PhysPortIndex].
-                                               ActiveFlag) {
-
-                                               continue;
-                                       }
-
-                                       EventParam.Para32[0] = PhysPortIndex;
-                                       EventParam.Para32[1] = (SK_U32)Val8;
-                                       if (SkGeSirqEvent(pAC, IoC,
-                                               SK_HWEV_SET_FLOWMODE,
-                                               EventParam) > 0) {
-
-                                               SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                                       SK_PNMI_ERR044,
-                                                       SK_PNMI_ERR044MSG);
-
-                                               *pLen = 0;
-                                               return (SK_PNMI_ERR_GENERAL);
-                                       }
-                               }
-                       }
-                       else {
-                               /*
-                                * Send an event with the new flow control
-                                * mode to the SIRQ module.
-                                */
-                               EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
-                                       pAC, LogPortIndex);
-                               EventParam.Para32[1] = (SK_U32)Val8;
-                               if (SkGeSirqEvent(pAC, IoC,
-                                       SK_HWEV_SET_FLOWMODE, EventParam)
-                                       > 0) {
-
-                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                               SK_PNMI_ERR044,
-                                               SK_PNMI_ERR044MSG);
-
-                                       *pLen = 0;
-                                       return (SK_PNMI_ERR_GENERAL);
-                               }
-                       }
-                       Offset += sizeof(char);
-                       break;
-
-               case OID_SKGE_PHY_OPERATION_MODE :
-                       /* Check the value range */
-                       Val8 = *(pBuf + Offset);
-                       if (Val8 == 0) {
-                               /* mode of this port remains unchanged */
-                               Offset += sizeof(char);
-                               break;
-                       }
-                       if (Val8 < SK_MS_MODE_AUTO ||
-                               (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
-                               (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-
-                       /* The preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-
-                               return (SK_PNMI_ERR_OK);
-                       }
-
-                       if (LogPortIndex == 0) {
-
-                               /*
-                                * The virtual port consists of all currently
-                                * active ports. Find them and send an event
-                                * with new master/slave (role) mode to SIRQ.
-                                */
-                               for (PhysPortIndex = 0;
-                                       PhysPortIndex < PhysPortMax;
-                                       PhysPortIndex ++) {
-
-                                       if (!pAC->Pnmi.Port[PhysPortIndex].
-                                               ActiveFlag) {
-
-                                               continue;
-                                       }
-
-                                       EventParam.Para32[0] = PhysPortIndex;
-                                       EventParam.Para32[1] = (SK_U32)Val8;
-                                       if (SkGeSirqEvent(pAC, IoC,
-                                               SK_HWEV_SET_ROLE,
-                                               EventParam) > 0) {
-
-                                               SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                                       SK_PNMI_ERR042,
-                                                       SK_PNMI_ERR042MSG);
-
-                                               *pLen = 0;
-                                               return (SK_PNMI_ERR_GENERAL);
-                                       }
-                               }
-                       }
-                       else {
-                               /*
-                                * Send an event with the new master/slave
-                                * (role) mode to the SIRQ module.
-                                */
-                               EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
-                                       pAC, LogPortIndex);
-                               EventParam.Para32[1] = (SK_U32)Val8;
-                               if (SkGeSirqEvent(pAC, IoC,
-                                       SK_HWEV_SET_ROLE, EventParam) > 0) {
-
-                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                               SK_PNMI_ERR042,
-                                               SK_PNMI_ERR042MSG);
-
-                                       *pLen = 0;
-                                       return (SK_PNMI_ERR_GENERAL);
-                               }
-                       }
-
-                       Offset += sizeof(char);
-                       break;
-
-               case OID_SKGE_SPEED_MODE:
-                       /* Check the value range */
-                       Val8 = *(pBuf + Offset);
-                       if (Val8 == 0) {
-
-                               Offset += sizeof(char);
-                               break;
-                       }
-                       if (Val8 < (SK_LSPEED_AUTO) ||
-                               (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
-                               (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-
-                       /* The preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-
-                               return (SK_PNMI_ERR_OK);
-                       }
-
-                       if (LogPortIndex == 0) {
-
-                               /*
-                                * The virtual port consists of all currently
-                                * active ports. Find them and send an event
-                                * with the new flow control mode to SIRQ.
-                                */
-                               for (PhysPortIndex = 0;
-                                       PhysPortIndex < PhysPortMax;
-                                       PhysPortIndex ++) {
-
-                                       if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
-                                               continue;
-                                       }
-
-                                       EventParam.Para32[0] = PhysPortIndex;
-                                       EventParam.Para32[1] = (SK_U32)Val8;
-                                       if (SkGeSirqEvent(pAC, IoC,
-                                               SK_HWEV_SET_SPEED,
-                                               EventParam) > 0) {
-
-                                               SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                                       SK_PNMI_ERR045,
-                                                       SK_PNMI_ERR045MSG);
-
-                                               *pLen = 0;
-                                               return (SK_PNMI_ERR_GENERAL);
-                                       }
-                               }
-                       }
-                       else {
-                               /*
-                                * Send an event with the new flow control
-                                * mode to the SIRQ module.
-                                */
-                               EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
-                                       pAC, LogPortIndex);
-                               EventParam.Para32[1] = (SK_U32)Val8;
-                               if (SkGeSirqEvent(pAC, IoC,
-                                       SK_HWEV_SET_SPEED,
-                                       EventParam) > 0) {
-
-                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                               SK_PNMI_ERR045,
-                                               SK_PNMI_ERR045MSG);
-
-                                       *pLen = 0;
-                                       return (SK_PNMI_ERR_GENERAL);
-                               }
-                       }
-                       Offset += sizeof(char);
-                       break;
-
-               case OID_SKGE_MTU :
-                       /* Check the value range */
-                       Val32 = *(SK_U32*)(pBuf + Offset);
-                       if (Val32 == 0) {
-                               /* mtu of this port remains unchanged */
-                               Offset += sizeof(SK_U32);
-                               break;
-                       }
-                       if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-
-                       /* The preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-                               return (SK_PNMI_ERR_OK);
-                       }
-
-                       if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-
-                       Offset += sizeof(SK_U32);
-                       break;
-
-               default:
-           SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
-               ("MacPrivateConf: Unknown OID should be handled before set"));
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * Monitor - OID handler function for RLMT_MONITOR_XXX
- *
- * Description:
- *     Because RLMT currently does not support the monitoring of
- *     remote adapter cards, we return always an empty table.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int Monitor(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* Get/PreSet/Set action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       unsigned int    Index;
-       unsigned int    Limit;
-       unsigned int    Offset;
-       unsigned int    Entries;
-
-
-       /*
-        * Calculate instance if wished.
-        */
-/* XXX Not yet implemented. Return always an empty table. */
-       Entries = 0;
-
-       if ((Instance != (SK_U32)(-1))) {
-
-               if ((Instance < 1) || (Instance > Entries)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-
-               Index = (unsigned int)Instance - 1;
-               Limit = (unsigned int)Instance;
-       }
-       else {
-               Index = 0;
-               Limit = Entries;
-       }
-
-       /*
-        * Get/Set value
-       */
-       if (Action == SK_PNMI_GET) {
-
-               for (Offset=0; Index < Limit; Index ++) {
-
-                       switch (Id) {
-
-                       case OID_SKGE_RLMT_MONITOR_INDEX:
-                       case OID_SKGE_RLMT_MONITOR_ADDR:
-                       case OID_SKGE_RLMT_MONITOR_ERRS:
-                       case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
-                       case OID_SKGE_RLMT_MONITOR_ADMIN:
-                               break;
-
-                       default:
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
-                                       SK_PNMI_ERR046MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-               }
-               *pLen = Offset;
-       }
-       else {
-               /* Only MONITOR_ADMIN can be set */
-               if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_READ_ONLY);
-               }
-
-               /* Check if the length is plausible */
-               if (*pLen < (Limit - Index)) {
-
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               /* Okay, we have a wide value range */
-               if (*pLen != (Limit - Index)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_BAD_VALUE);
-               }
-/*
-               for (Offset=0; Index < Limit; Index ++) {
-               }
-*/
-/*
- * XXX Not yet implemented. Return always BAD_VALUE, because the table
- * is empty.
- */
-               *pLen = 0;
-               return (SK_PNMI_ERR_BAD_VALUE);
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * VirtualConf - Calculates the values of configuration OIDs for virtual port
- *
- * Description:
- *     We handle here the get of the configuration group OIDs, which are
- *     a little bit complicated. The virtual port consists of all currently
- *     active physical ports. If multiple ports are active and configured
- *     differently we get in some trouble to return a single value. So we
- *     get the value of the first active port and compare it with that of
- *     the other active ports. If they are not the same, we return a value
- *     that indicates that the state is indeterminated.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void VirtualConf(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf)            /* Buffer to which to mgmt data will be retrieved */
-{
-       unsigned int    PhysPortMax;
-       unsigned int    PhysPortIndex;
-       SK_U8           Val8;
-       SK_BOOL         PortActiveFlag;
-
-
-       *pBuf = 0;
-       PortActiveFlag = SK_FALSE;
-       PhysPortMax = pAC->GIni.GIMacsFound;
-
-       for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
-               PhysPortIndex ++) {
-
-               /* Check if the physical port is active */
-               if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
-                       continue;
-               }
-
-               PortActiveFlag = SK_TRUE;
-
-               switch (Id) {
-
-               case OID_SKGE_LINK_CAP:
-
-                       /*
-                        * Different capabilities should not happen, but
-                        * in the case of the cases OR them all together.
-                        * From a curious point of view the virtual port
-                        * is capable of all found capabilities.
-                        */
-                       *pBuf |= pAC->GIni.GP[PhysPortIndex].PLinkCap;
-                       break;
-
-               case OID_SKGE_LINK_MODE:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different link
-                        * mode than the first one we return a value that
-                        * indicates that the link mode is indeterminated.
-                        */
-                       if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkModeConf
-                               ) {
-
-                               *pBuf = SK_LMODE_INDETERMINATED;
-                       }
-                       break;
-
-               case OID_SKGE_LINK_MODE_STATUS:
-                       /* Get the link mode of the physical port */
-                       Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
-
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = Val8;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different link
-                        * mode status than the first one we return a value
-                        * that indicates that the link mode status is
-                        * indeterminated.
-                        */
-                       if (*pBuf != Val8) {
-
-                               *pBuf = SK_LMODE_STAT_INDETERMINATED;
-                       }
-                       break;
-
-               case OID_SKGE_LINK_STATUS:
-                       /* Get the link status of the physical port */
-                       Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
-
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = Val8;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different link
-                        * status than the first one, we return a value
-                        * that indicates that the link status is
-                        * indeterminated.
-                        */
-                       if (*pBuf != Val8) {
-
-                               *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
-                       }
-                       break;
-
-               case OID_SKGE_FLOWCTRL_CAP:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
-                               continue;
-                       }
-
-                       /*
-                        * From a curious point of view the virtual port
-                        * is capable of all found capabilities.
-                        */
-                       *pBuf |= pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
-                       break;
-
-               case OID_SKGE_FLOWCTRL_MODE:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different flow
-                        * control mode than the first one, we return a value
-                        * that indicates that the mode is indeterminated.
-                        */
-                       if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode) {
-
-                               *pBuf = SK_FLOW_MODE_INDETERMINATED;
-                       }
-                       break;
-
-               case OID_SKGE_FLOWCTRL_STATUS:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different flow
-                        * control status than the first one, we return a
-                        * value that indicates that the status is
-                        * indeterminated.
-                        */
-                       if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus) {
-
-                               *pBuf = SK_FLOW_STAT_INDETERMINATED;
-                       }
-                       break;
-
-               case OID_SKGE_PHY_OPERATION_CAP:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pAC->GIni.GP[PhysPortIndex].PMSCap;
-                               continue;
-                       }
-
-                       /*
-                        * From a curious point of view the virtual port
-                        * is capable of all found capabilities.
-                        */
-                       *pBuf |= pAC->GIni.GP[PhysPortIndex].PMSCap;
-                       break;
-
-               case OID_SKGE_PHY_OPERATION_MODE:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pAC->GIni.GP[PhysPortIndex].PMSMode;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different master/
-                        * slave mode than the first one, we return a value
-                        * that indicates that the mode is indeterminated.
-                        */
-                       if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSMode) {
-
-                               *pBuf = SK_MS_MODE_INDETERMINATED;
-                       }
-                       break;
-
-               case OID_SKGE_PHY_OPERATION_STATUS:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pAC->GIni.GP[PhysPortIndex].PMSStatus;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different master/
-                        * slave status than the first one, we return a
-                        * value that indicates that the status is
-                        * indeterminated.
-                        */
-                       if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSStatus) {
-
-                               *pBuf = SK_MS_STAT_INDETERMINATED;
-                       }
-                       break;
-
-               case OID_SKGE_SPEED_MODE:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different flow
-                        * control mode than the first one, we return a value
-                        * that indicates that the mode is indeterminated.
-                        */
-                       if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeed) {
-
-                               *pBuf = SK_LSPEED_INDETERMINATED;
-                       }
-                       break;
-
-               case OID_SKGE_SPEED_STATUS:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different flow
-                        * control status than the first one, we return a
-                        * value that indicates that the status is
-                        * indeterminated.
-                        */
-                       if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed) {
-
-                               *pBuf = SK_LSPEED_STAT_INDETERMINATED;
-                       }
-                       break;
-               }
-       }
-
-       /*
-        * If no port is active return an indeterminated answer
-        */
-       if (!PortActiveFlag) {
-
-               switch (Id) {
-
-               case OID_SKGE_LINK_CAP:
-                       *pBuf = SK_LMODE_CAP_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_LINK_MODE:
-                       *pBuf = SK_LMODE_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_LINK_MODE_STATUS:
-                       *pBuf = SK_LMODE_STAT_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_LINK_STATUS:
-                       *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_FLOWCTRL_CAP:
-               case OID_SKGE_FLOWCTRL_MODE:
-                       *pBuf = SK_FLOW_MODE_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_FLOWCTRL_STATUS:
-                       *pBuf = SK_FLOW_STAT_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_PHY_OPERATION_CAP:
-                       *pBuf = SK_MS_CAP_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_PHY_OPERATION_MODE:
-                       *pBuf = SK_MS_MODE_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_PHY_OPERATION_STATUS:
-                       *pBuf = SK_MS_STAT_INDETERMINATED;
-                       break;
-               case OID_SKGE_SPEED_CAP:
-                       *pBuf = SK_LSPEED_CAP_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_SPEED_MODE:
-                       *pBuf = SK_LSPEED_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_SPEED_STATUS:
-                       *pBuf = SK_LSPEED_STAT_INDETERMINATED;
-                       break;
-               }
-       }
-}
-
-/*****************************************************************************
- *
- * CalculateLinkStatus - Determins the link status of a physical port
- *
- * Description:
- *     Determins the link status the following way:
- *       LSTAT_PHY_DOWN:  Link is down
- *       LSTAT_AUTONEG:   Auto-negotiation failed
- *       LSTAT_LOG_DOWN:  Link is up but RLMT did not yet put the port
- *                        logically up.
- *       LSTAT_LOG_UP:    RLMT marked the port as up
- *
- * Returns:
- *     Link status of physical port
- */
-PNMI_STATIC SK_U8 CalculateLinkStatus(
-SK_AC *pAC,                    /* Pointer to adapter context */
-SK_IOC IoC,                    /* IO context handle */
-unsigned int PhysPortIndex)    /* Physical port index */
-{
-       SK_U8   Result;
-
-
-       if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
-
-               Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
-       }
-       else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
-
-               Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
-                               }
-       else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
-
-               Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
-       }
-       else {
-               Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
-       }
-
-       return (Result);
-}
-
-/*****************************************************************************
- *
- * CalculateLinkModeStatus - Determins the link mode status of a phys. port
- *
- * Description:
- *     The COMMON module only tells us if the mode is half or full duplex.
- *     But in the decade of auto sensing it is usefull for the user to
- *     know if the mode was negotiated or forced. Therefore we have a
- *     look to the mode, which was last used by the negotiation process.
- *
- * Returns:
- *     The link mode status
- */
-PNMI_STATIC SK_U8 CalculateLinkModeStatus(
-SK_AC *pAC,                    /* Pointer to adapter context */
-SK_IOC IoC,                    /* IO context handle */
-unsigned int PhysPortIndex)    /* Physical port index */
-{
-       SK_U8   Result;
-
-
-       /* Get the current mode, which can be full or half duplex */
-       Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
-
-       /* Check if no valid mode could be found (link is down) */
-       if (Result < SK_LMODE_STAT_HALF) {
-
-               Result = SK_LMODE_STAT_UNKNOWN;
-       }
-       else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
-
-               /*
-                * Auto-negotiation was used to bring up the link. Change
-                * the already found duplex status that it indicates
-                * auto-negotiation was involved.
-                */
-               if (Result == SK_LMODE_STAT_HALF) {
-
-                       Result = SK_LMODE_STAT_AUTOHALF;
-               }
-               else if (Result == SK_LMODE_STAT_FULL) {
-
-                       Result = SK_LMODE_STAT_AUTOFULL;
-               }
-       }
-
-       return (Result);
-}
-
-/*****************************************************************************
- *
- * GetVpdKeyArr - Obtain an array of VPD keys
- *
- * Description:
- *     Read the VPD keys and build an array of VPD keys, which are
- *     easy to access.
- *
- * Returns:
- *     SK_PNMI_ERR_OK       Task successfully performed.
- *     SK_PNMI_ERR_GENERAL  Something went wrong.
- */
-PNMI_STATIC int GetVpdKeyArr(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-char *pKeyArr,         /* Ptr KeyArray */
-unsigned int KeyArrLen,        /* Length of array in bytes */
-unsigned int *pKeyNo)  /* Number of keys */
-{
-       unsigned int            BufKeysLen = SK_PNMI_VPD_BUFSIZE;
-       char                    BufKeys[SK_PNMI_VPD_BUFSIZE];
-       unsigned int            StartOffset;
-       unsigned int            Offset;
-       int                     Index;
-       int                     Ret;
-
-
-       SK_MEMSET(pKeyArr, 0, KeyArrLen);
-
-       /*
-        * Get VPD key list
-        */
-       Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
-               (int *)pKeyNo);
-       if (Ret > 0) {
-
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
-                       SK_PNMI_ERR014MSG);
-
-               return (SK_PNMI_ERR_GENERAL);
-       }
-       /* If no keys are available return now */
-       if (*pKeyNo == 0 || BufKeysLen == 0) {
-
-               return (SK_PNMI_ERR_OK);
-       }
-       /*
-        * If the key list is too long for us trunc it and give a
-        * errorlog notification. This case should not happen because
-        * the maximum number of keys is limited due to RAM limitations
-        */
-       if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
-
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
-                       SK_PNMI_ERR015MSG);
-
-               *pKeyNo = SK_PNMI_VPD_ENTRIES;
-       }
-
-       /*
-        * Now build an array of fixed string length size and copy
-        * the keys together.
-        */
-       for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
-               Offset ++) {
-
-               if (BufKeys[Offset] != 0) {
-
-                       continue;
-               }
-
-               if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
-                               SK_PNMI_ERR016MSG);
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
-                       &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
-
-               Index ++;
-               StartOffset = Offset + 1;
-       }
-
-       /* Last key not zero terminated? Get it anyway */
-       if (StartOffset < Offset) {
-
-               SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
-                       &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * SirqUpdate - Let the SIRQ update its internal values
- *
- * Description:
- *     Just to be sure that the SIRQ module holds its internal data
- *     structures up to date, we send an update event before we make
- *     any access.
- *
- * Returns:
- *     SK_PNMI_ERR_OK       Task successfully performed.
- *     SK_PNMI_ERR_GENERAL  Something went wrong.
- */
-PNMI_STATIC int SirqUpdate(
-SK_AC *pAC,    /* Pointer to adapter context */
-SK_IOC IoC)    /* IO context handle */
-{
-       SK_EVPARA       EventParam;
-
-
-       /* Was the module already updated during the current PNMI call? */
-       if (pAC->Pnmi.SirqUpdatedFlag > 0) {
-
-               return (SK_PNMI_ERR_OK);
-       }
-
-       /* Send an synchronuous update event to the module */
-       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
-       if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
-
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
-                       SK_PNMI_ERR047MSG);
-
-               return (SK_PNMI_ERR_GENERAL);
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * RlmtUpdate - Let the RLMT update its internal values
- *
- * Description:
- *     Just to be sure that the RLMT module holds its internal data
- *     structures up to date, we send an update event before we make
- *     any access.
- *
- * Returns:
- *     SK_PNMI_ERR_OK       Task successfully performed.
- *     SK_PNMI_ERR_GENERAL  Something went wrong.
- */
-PNMI_STATIC int RlmtUpdate(
-SK_AC *pAC,    /* Pointer to adapter context */
-SK_IOC IoC,    /* IO context handle */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       SK_EVPARA       EventParam;
-
-
-       /* Was the module already updated during the current PNMI call? */
-       if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
-
-               return (SK_PNMI_ERR_OK);
-       }
-
-       /* Send an synchronuous update event to the module */
-       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
-       EventParam.Para32[0] = NetIndex;
-       EventParam.Para32[1] = (SK_U32)-1;
-       if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
-
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
-                       SK_PNMI_ERR048MSG);
-
-               return (SK_PNMI_ERR_GENERAL);
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * MacUpdate - Force the XMAC to output the current statistic
- *
- * Description:
- *     The XMAC holds its statistic internally. To obtain the current
- *     values we send a command so that the statistic data will
- *     be written to apredefined memory area on the adapter.
- *
- * Returns:
- *     SK_PNMI_ERR_OK       Task successfully performed.
- *     SK_PNMI_ERR_GENERAL  Something went wrong.
- */
-PNMI_STATIC int MacUpdate(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-unsigned int FirstMac, /* Index of the first Mac to be updated */
-unsigned int LastMac)  /* Index of the last Mac to be updated */
-{
-       unsigned int    MacIndex;
-
-       /*
-        * Were the statistics already updated during the
-        * current PNMI call?
-        */
-       if (pAC->Pnmi.MacUpdatedFlag > 0) {
-
-               return (SK_PNMI_ERR_OK);
-       }
-
-       /* Send an update command to all MACs specified */
-       for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
-
-               /*
-                * 2002-09-13 pweber:   Freeze the current sw counters.
-                *                      (That should be done as close as
-                *                      possible to the update of the
-                *                      hw counters)
-                */
-               if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
-                       pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
-               }
-
-               /* 2002-09-13 pweber:  Update the hw counter  */
-               if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
-
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * GetStatVal - Retrieve an XMAC statistic counter
- *
- * Description:
- *     Retrieves the statistic counter of a virtual or physical port. The
- *     virtual port is identified by the index 0. It consists of all
- *     currently active ports. To obtain the counter value for this port
- *     we must add the statistic counter of all active ports. To grant
- *     continuous counter values for the virtual port even when port
- *     switches occur we must additionally add a delta value, which was
- *     calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
- *
- * Returns:
- *     Requested statistic value
- */
-PNMI_STATIC SK_U64 GetStatVal(
-SK_AC *pAC,                                    /* Pointer to adapter context */
-SK_IOC IoC,                                    /* IO context handle */
-unsigned int LogPortIndex,     /* Index of the logical Port to be processed */
-unsigned int StatIndex,                /* Index to statistic value */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       unsigned int    PhysPortIndex;
-       unsigned int    PhysPortMax;
-       SK_U64                  Val = 0;
-
-
-       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {   /* Dual net mode */
-
-               PhysPortIndex = NetIndex;
-               Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
-       }
-       else {  /* Single Net mode */
-
-               if (LogPortIndex == 0) {
-
-                       PhysPortMax = pAC->GIni.GIMacsFound;
-
-                       /* Add counter of all active ports */
-                       for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
-                               PhysPortIndex ++) {
-
-                               if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
-                                       Val += GetPhysStatVal(pAC, IoC, PhysPortIndex,
-                                               StatIndex);
-                               }
-                       }
-
-                       /* Correct value because of port switches */
-                       Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
-               }
-               else {
-                       /* Get counter value of physical port */
-                       PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
-                       Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
-               }
-       }
-       return (Val);
-}
-
-/*****************************************************************************
- *
- * GetPhysStatVal - Get counter value for physical port
- *
- * Description:
- *     Builds a 64bit counter value. Except for the octet counters
- *     the lower 32bit are counted in hardware and the upper 32bit
- *     in software by monitoring counter overflow interrupts in the
- *     event handler. To grant continous counter values during XMAC
- *     resets (caused by a workaround) we must add a delta value.
- *     The delta was calculated in the event handler when a
- *     SK_PNMI_EVT_XMAC_RESET was received.
- *
- * Returns:
- *     Counter value
- */
-PNMI_STATIC SK_U64 GetPhysStatVal(
-SK_AC *pAC,                                    /* Pointer to adapter context */
-SK_IOC IoC,                                    /* IO context handle */
-unsigned int PhysPortIndex,    /* Index of the logical Port to be processed */
-unsigned int StatIndex)                /* Index to statistic value */
-{
-       SK_U64  Val = 0;
-       SK_U32  LowVal = 0;
-       SK_U32  HighVal = 0;
-       SK_U16  Word;
-       int             MacType;
-
-       SK_PNMI_PORT    *pPnmiPrt;
-       SK_GEMACFUNC    *pFnMac;
-
-       MacType = pAC->GIni.GIMacType;
-
-       /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
-       if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
-               pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
-       }
-       else {
-               pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
-       }
-
-       pFnMac   = &pAC->GIni.GIFunc;
-
-       switch (StatIndex) {
-       case SK_PNMI_HTX:
-       case SK_PNMI_HRX:
-               /* Not supported by GMAC */
-               if (MacType == SK_MAC_GMAC) {
-                       return (Val);
-               }
-
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &LowVal);
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               break;
-
-       case SK_PNMI_HTX_OCTET:
-       case SK_PNMI_HRX_OCTET:
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &HighVal);
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex + 1][MacType].Reg,
-                                                                         &LowVal);
-               break;
-
-       case SK_PNMI_HTX_BURST:
-       case SK_PNMI_HTX_EXCESS_DEF:
-       case SK_PNMI_HTX_CARRIER:
-               /* Not supported by GMAC */
-               if (MacType == SK_MAC_GMAC) {
-                       return (Val);
-               }
-
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &LowVal);
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               break;
-
-       case SK_PNMI_HTX_MACC:
-               /* GMAC only supports PAUSE MAC control frames */
-               if (MacType == SK_MAC_GMAC) {
-                       Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, SK_PNMI_HTX_PMACC);
-
-                       return (Val);
-               }
-
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &LowVal);
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               break;
-
-       case SK_PNMI_HTX_COL:
-       case SK_PNMI_HRX_UNDERSIZE:
-               /* Not supported by XMAC */
-               if (MacType == SK_MAC_XMAC) {
-                       return (Val);
-               }
-
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &LowVal);
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               break;
-
-
-       case SK_PNMI_HTX_DEFFERAL:
-               /* Not supported by GMAC */
-               if (MacType == SK_MAC_GMAC) {
-                       return (Val);
-               }
-
-               /*
-                * XMAC counts frames with deferred transmission
-                * even in full-duplex mode.
-                *
-                * In full-duplex mode the counter remains constant!
-                */
-               if ((pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
-                       (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_FULL)) {
-
-                       LowVal = 0;
-                       HighVal = 0;
-               }
-               else {
-                       /* Otherwise get contents of hardware register. */
-                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                                 StatAddr[SK_PNMI_HTX_DEFFERAL][MacType].Reg,
-                                                                                 &LowVal);
-                       HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               }
-               break;
-
-       case SK_PNMI_HRX_BADOCTET:
-               /* Not supported by XMAC */
-               if (MacType == SK_MAC_XMAC) {
-                       return (Val);
-               }
-
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &HighVal);
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex + 1][MacType].Reg,
-                                     &LowVal);
-               break;
-
-       case SK_PNMI_HTX_OCTETLOW:
-       case SK_PNMI_HRX_OCTETLOW:
-       case SK_PNMI_HRX_BADOCTETLOW:
-               return (Val);
-
-       case SK_PNMI_HRX_LONGFRAMES:
-               /* For XMAC the SW counter is managed by PNMI */
-               if (MacType == SK_MAC_XMAC) {
-                       return (pPnmiPrt->StatRxLongFrameCts);
-               }
-
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &LowVal);
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               break;
-
-       case SK_PNMI_HRX_TOO_LONG:
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                               StatAddr[StatIndex][MacType].Reg,
-                                                               &LowVal);
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-
-               Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
-
-               switch (MacType) {
-               case SK_MAC_GMAC:
-                       /* For GMAC the SW counter is additionally managed by PNMI */
-                       Val += pPnmiPrt->StatRxFrameTooLongCts;
-                       break;
-
-               case SK_MAC_XMAC:
-                       /*
-                        * Frames longer than IEEE 802.3 frame max size are counted
-                        * by XMAC in frame_too_long counter even reception of long
-                        * frames was enabled and the frame was correct.
-                        * So correct the value by subtracting RxLongFrame counter.
-                        */
-                       Val -= pPnmiPrt->StatRxLongFrameCts;
-                       break;
-
-               default:
-                       break;
-               }
-
-               LowVal = (SK_U32)Val;
-               HighVal = (SK_U32)(Val >> 32);
-               break;
-
-       case SK_PNMI_HRX_SHORTS:
-               /* Not supported by GMAC */
-               if (MacType == SK_MAC_GMAC) {
-                       /* GM_RXE_FRAG?? */
-                       return (Val);
-               }
-
-               /*
-                * XMAC counts short frame errors even if link down (#10620)
-                *
-                * If link-down the counter remains constant
-                */
-               if (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
-
-                       /* Otherwise get incremental difference */
-                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                                 StatAddr[StatIndex][MacType].Reg,
-                                                                                 &LowVal);
-                       HighVal = pPnmiPrt->CounterHigh[StatIndex];
-
-                       Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
-                       Val -= pPnmiPrt->RxShortZeroMark;
-
-                       LowVal = (SK_U32)Val;
-                       HighVal = (SK_U32)(Val >> 32);
-               }
-               break;
-
-       case SK_PNMI_HRX_MACC:
-       case SK_PNMI_HRX_MACC_UNKWN:
-       case SK_PNMI_HRX_BURST:
-       case SK_PNMI_HRX_MISSED:
-       case SK_PNMI_HRX_FRAMING:
-       case SK_PNMI_HRX_CARRIER:
-       case SK_PNMI_HRX_IRLENGTH:
-       case SK_PNMI_HRX_SYMBOL:
-       case SK_PNMI_HRX_CEXT:
-               /* Not supported by GMAC */
-               if (MacType == SK_MAC_GMAC) {
-                       /* GM_RXE_FRAG?? */
-                       return (Val);
-               }
-
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &LowVal);
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               break;
-
-       case SK_PNMI_HRX_PMACC_ERR:
-               /* For GMAC the SW counter is managed by PNMI */
-               if (MacType == SK_MAC_GMAC) {
-                       return (pPnmiPrt->StatRxPMaccErr);
-               }
-
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &LowVal);
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               break;
-
-       /* SW counter managed by PNMI */
-       case SK_PNMI_HTX_SYNC:
-               LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
-               HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
-               break;
-
-       /* SW counter managed by PNMI */
-       case SK_PNMI_HTX_SYNC_OCTET:
-               LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
-               HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
-               break;
-
-       case SK_PNMI_HRX_FCS:
-               /*
-                * Broadcom filters fcs errors and counts it in
-                * Receive Error Counter register
-                */
-               if (pAC->GIni.GP[PhysPortIndex].PhyType == SK_PHY_BCOM) {
-                       /* do not read while not initialized (PHY_READ hangs!)*/
-                       if (pAC->GIni.GP[PhysPortIndex].PState) {
-                               PHY_READ(IoC, &pAC->GIni.GP[PhysPortIndex],
-                                                PhysPortIndex, PHY_BCOM_RE_CTR,
-                                                &Word);
-
-                               LowVal = Word;
-                       }
-                       HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               }
-               else {
-                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                                 StatAddr[StatIndex][MacType].Reg,
-                                                                                 &LowVal);
-                       HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               }
-               break;
-
-       default:
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &LowVal);
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               break;
-       }
-
-       Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
-
-       /* Correct value because of possible XMAC reset. XMAC Errata #2 */
-       Val += pPnmiPrt->CounterOffset[StatIndex];
-
-       return (Val);
-}
-
-/*****************************************************************************
- *
- * ResetCounter - Set all counters and timestamps to zero
- *
- * Description:
- *     Notifies other common modules which store statistic data to
- *     reset their counters and finally reset our own counters.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void ResetCounter(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-SK_U32 NetIndex)
-{
-       unsigned int    PhysPortIndex;
-       SK_EVPARA       EventParam;
-
-
-       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
-
-       /* Notify sensor module */
-       SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
-
-       /* Notify RLMT module */
-       EventParam.Para32[0] = NetIndex;
-       EventParam.Para32[1] = (SK_U32)-1;
-       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
-       EventParam.Para32[1] = 0;
-
-       /* Notify SIRQ module */
-       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
-
-       /* Notify CSUM module */
-#ifdef SK_USE_CSUM
-       EventParam.Para32[0] = NetIndex;
-       EventParam.Para32[1] = (SK_U32)-1;
-       SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
-               EventParam);
-#endif
-
-       /* Clear XMAC statistic */
-       for (PhysPortIndex = 0; PhysPortIndex <
-               (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
-
-               (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
-
-               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
-                       0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
-               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
-                       CounterOffset, 0, sizeof(pAC->Pnmi.Port[
-                       PhysPortIndex].CounterOffset));
-               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
-                       0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
-               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
-                       StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
-                       PhysPortIndex].StatSyncOctetsCts));
-               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
-                       StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
-                       PhysPortIndex].StatRxLongFrameCts));
-               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
-                                 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
-                       PhysPortIndex].StatRxFrameTooLongCts));
-               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
-                                 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
-                       PhysPortIndex].StatRxPMaccErr));
-       }
-
-       /*
-        * Clear local statistics
-        */
-       SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
-                 sizeof(pAC->Pnmi.VirtualCounterOffset));
-       pAC->Pnmi.RlmtChangeCts = 0;
-       pAC->Pnmi.RlmtChangeTime = 0;
-       SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
-               sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
-       pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
-       pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
-       pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
-       pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
-       pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
-       pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
-       pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
-       pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
-       pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
-       pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
-       pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
-       pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
-}
-
-/*****************************************************************************
- *
- * GetTrapEntry - Get an entry in the trap buffer
- *
- * Description:
- *     The trap buffer stores various events. A user application somehow
- *     gets notified that an event occured and retrieves the trap buffer
- *     contens (or simply polls the buffer). The buffer is organized as
- *     a ring which stores the newest traps at the beginning. The oldest
- *     traps are overwritten by the newest ones. Each trap entry has a
- *     unique number, so that applications may detect new trap entries.
- *
- * Returns:
- *     A pointer to the trap entry
- */
-PNMI_STATIC char* GetTrapEntry(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_U32 TrapId,         /* SNMP ID of the trap */
-unsigned int Size)     /* Space needed for trap entry */
-{
-       unsigned int            BufPad = pAC->Pnmi.TrapBufPad;
-       unsigned int            BufFree = pAC->Pnmi.TrapBufFree;
-       unsigned int            Beg = pAC->Pnmi.TrapQueueBeg;
-       unsigned int            End = pAC->Pnmi.TrapQueueEnd;
-       char                    *pBuf = &pAC->Pnmi.TrapBuf[0];
-       int                     Wrap;
-       unsigned int            NeededSpace;
-       unsigned int            EntrySize;
-       SK_U32                  Val32;
-       SK_U64                  Val64;
-
-
-       /* Last byte of entry will get a copy of the entry length */
-       Size ++;
-
-       /*
-        * Calculate needed buffer space */
-       if (Beg >= Size) {
-
-               NeededSpace = Size;
-               Wrap = SK_FALSE;
-       }
-       else {
-               NeededSpace = Beg + Size;
-               Wrap = SK_TRUE;
-       }
-
-       /*
-        * Check if enough buffer space is provided. Otherwise
-        * free some entries. Leave one byte space between begin
-        * and end of buffer to make it possible to detect whether
-        * the buffer is full or empty
-        */
-       while (BufFree < NeededSpace + 1) {
-
-               if (End == 0) {
-
-                       End = SK_PNMI_TRAP_QUEUE_LEN;
-               }
-
-               EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
-               BufFree += EntrySize;
-               End -= EntrySize;
-#ifdef DEBUG
-               SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
-#endif
-               if (End == BufPad) {
-#ifdef DEBUG
-                       SK_MEMSET(pBuf, (char)(-1), End);
-#endif
-                       BufFree += End;
-                       End = 0;
-                       BufPad = 0;
-               }
-       }
-
-       /*
-        * Insert new entry as first entry. Newest entries are
-        * stored at the beginning of the queue.
-        */
-       if (Wrap) {
-
-               BufPad = Beg;
-               Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
-       }
-       else {
-               Beg = Beg - Size;
-       }
-       BufFree -= NeededSpace;
-
-       /* Save the current offsets */
-       pAC->Pnmi.TrapQueueBeg = Beg;
-       pAC->Pnmi.TrapQueueEnd = End;
-       pAC->Pnmi.TrapBufPad = BufPad;
-       pAC->Pnmi.TrapBufFree = BufFree;
-
-       /* Initialize the trap entry */
-       *(pBuf + Beg + Size - 1) = (char)Size;
-       *(pBuf + Beg) = (char)Size;
-       Val32 = (pAC->Pnmi.TrapUnique) ++;
-       SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
-       SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
-       Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
-       SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
-
-       return (pBuf + Beg);
-}
-
-/*****************************************************************************
- *
- * CopyTrapQueue - Copies the trap buffer for the TRAP OID
- *
- * Description:
- *     On a query of the TRAP OID the trap buffer contents will be
- *     copied continuously to the request buffer, which must be large
- *     enough. No length check is performed.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void CopyTrapQueue(
-SK_AC *pAC,            /* Pointer to adapter context */
-char *pDstBuf)         /* Buffer to which the queued traps will be copied */
-{
-       unsigned int    BufPad = pAC->Pnmi.TrapBufPad;
-       unsigned int    Trap = pAC->Pnmi.TrapQueueBeg;
-       unsigned int    End = pAC->Pnmi.TrapQueueEnd;
-       char            *pBuf = &pAC->Pnmi.TrapBuf[0];
-       unsigned int    Len;
-       unsigned int    DstOff = 0;
-
-
-       while (Trap != End) {
-
-               Len = (unsigned int)*(pBuf + Trap);
-
-               /*
-                * Last byte containing a copy of the length will
-                * not be copied.
-                */
-               *(pDstBuf + DstOff) = (char)(Len - 1);
-               SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
-               DstOff += Len - 1;
-
-               Trap += Len;
-               if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
-
-                       Trap = BufPad;
-               }
-       }
-}
-
-/*****************************************************************************
- *
- * GetTrapQueueLen - Get the length of the trap buffer
- *
- * Description:
- *     Evaluates the number of currently stored traps and the needed
- *     buffer size to retrieve them.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void GetTrapQueueLen(
-SK_AC *pAC,            /* Pointer to adapter context */
-unsigned int *pLen,    /* Length in Bytes of all queued traps */
-unsigned int *pEntries)        /* Returns number of trapes stored in queue */
-{
-       unsigned int    BufPad = pAC->Pnmi.TrapBufPad;
-       unsigned int    Trap = pAC->Pnmi.TrapQueueBeg;
-       unsigned int    End = pAC->Pnmi.TrapQueueEnd;
-       char            *pBuf = &pAC->Pnmi.TrapBuf[0];
-       unsigned int    Len;
-       unsigned int    Entries = 0;
-       unsigned int    TotalLen = 0;
-
-
-       while (Trap != End) {
-
-               Len = (unsigned int)*(pBuf + Trap);
-               TotalLen += Len - 1;
-               Entries ++;
-
-               Trap += Len;
-               if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
-
-                       Trap = BufPad;
-               }
-       }
-
-       *pEntries = Entries;
-       *pLen = TotalLen;
-}
-
-/*****************************************************************************
- *
- * QueueSimpleTrap - Store a simple trap to the trap buffer
- *
- * Description:
- *     A simple trap is a trap with now additional data. It consists
- *     simply of a trap code.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void QueueSimpleTrap(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_U32 TrapId)         /* Type of sensor trap */
-{
-       GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
-}
-
-/*****************************************************************************
- *
- * QueueSensorTrap - Stores a sensor trap in the trap buffer
- *
- * Description:
- *     Gets an entry in the trap buffer and fills it with sensor related
- *     data.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void QueueSensorTrap(
-SK_AC *pAC,                    /* Pointer to adapter context */
-SK_U32 TrapId,                 /* Type of sensor trap */
-unsigned int SensorIndex)      /* Index of sensor which caused the trap */
-{
-       char            *pBuf;
-       unsigned int    Offset;
-       unsigned int    DescrLen;
-       SK_U32          Val32;
-
-
-       /* Get trap buffer entry */
-       DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
-       pBuf = GetTrapEntry(pAC, TrapId,
-               SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
-       Offset = SK_PNMI_TRAP_SIMPLE_LEN;
-
-       /* Store additionally sensor trap related data */
-       Val32 = OID_SKGE_SENSOR_INDEX;
-       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-       *(pBuf + Offset + 4) = 4;
-       Val32 = (SK_U32)SensorIndex;
-       SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
-       Offset += 9;
-
-       Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
-       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-       *(pBuf + Offset + 4) = (char)DescrLen;
-       SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
-               DescrLen);
-       Offset += DescrLen + 5;
-
-       Val32 = OID_SKGE_SENSOR_TYPE;
-       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-       *(pBuf + Offset + 4) = 1;
-       *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
-       Offset += 6;
-
-       Val32 = OID_SKGE_SENSOR_VALUE;
-       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-       *(pBuf + Offset + 4) = 4;
-       Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
-       SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
-}
-
-/*****************************************************************************
- *
- * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
- *
- * Description:
- *     Nothing further to explain.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void QueueRlmtNewMacTrap(
-SK_AC *pAC,            /* Pointer to adapter context */
-unsigned int ActiveMac)        /* Index (0..n) of the currently active port */
-{
-       char    *pBuf;
-       SK_U32  Val32;
-
-
-       pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
-               SK_PNMI_TRAP_RLMT_CHANGE_LEN);
-
-       Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
-       SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
-       *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
-       *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
-}
-
-/*****************************************************************************
- *
- * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
- *
- * Description:
- *     Nothing further to explain.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void QueueRlmtPortTrap(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_U32 TrapId,         /* Type of RLMT port trap */
-unsigned int PortIndex)        /* Index of the port, which changed its state */
-{
-       char    *pBuf;
-       SK_U32  Val32;
-
-
-       pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
-
-       Val32 = OID_SKGE_RLMT_PORT_INDEX;
-       SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
-       *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
-       *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
-}
-
-/*****************************************************************************
- *
- * CopyMac - Copies a MAC address
- *
- * Description:
- *     Nothing further to explain.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void CopyMac(
-char *pDst,            /* Pointer to destination buffer */
-SK_MAC_ADDR *pMac)     /* Pointer of Source */
-{
-       int     i;
-
-
-       for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
-
-               *(pDst + i) = pMac->a[i];
-       }
-}
-
-
-#ifdef SK_POWER_MGMT
-/*****************************************************************************
- *
- * PowerManagement - OID handler function of PowerManagement OIDs
- *
- * Description:
- *     The code is simple. No description necessary.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-
-PNMI_STATIC int PowerManagement(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* Get/PreSet/Set action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-
-       SK_U32  RetCode = SK_PNMI_ERR_GENERAL;
-
-       /*
-        * Check instance. We only handle single instance variables
-        */
-       if (Instance != (SK_U32)(-1) && Instance != 1) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_UNKNOWN_INST);
-       }
-
-       /*
-        * Perform action
-        */
-       if (Action == SK_PNMI_GET) {
-
-               /*
-                * Check length
-                */
-               switch (Id) {
-
-               case OID_PNP_CAPABILITIES:
-                       if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
-
-                               *pLen = sizeof(SK_PNP_CAPABILITIES);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       break;
-
-               case OID_PNP_QUERY_POWER:
-               case OID_PNP_ENABLE_WAKE_UP:
-                       if (*pLen < sizeof(SK_U32)) {
-
-                               *pLen = sizeof(SK_U32);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       break;
-
-               case OID_PNP_SET_POWER:
-               case OID_PNP_ADD_WAKE_UP_PATTERN:
-               case OID_PNP_REMOVE_WAKE_UP_PATTERN:
-                       break;
-
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040,
-                               SK_PNMI_ERR040MSG);
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               /*
-                * Get value
-                */
-               switch (Id) {
-
-               case OID_PNP_CAPABILITIES:
-                       RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
-                       break;
-
-               case OID_PNP_QUERY_POWER:
-                       /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
-                        the miniport to indicate whether it can transition its NIC
-                        to the low-power state.
-                        A miniport driver must always return NDIS_STATUS_SUCCESS
-                        to a query of OID_PNP_QUERY_POWER. */
-                       RetCode = SK_PNMI_ERR_OK;
-                       break;
-
-                       /* NDIS handles these OIDs as write-only.
-                        * So in case of get action the buffer with written length = 0
-                        * is returned
-                        */
-               case OID_PNP_SET_POWER:
-               case OID_PNP_ADD_WAKE_UP_PATTERN:
-               case OID_PNP_REMOVE_WAKE_UP_PATTERN:
-                       *pLen = 0;
-                       RetCode = SK_PNMI_ERR_OK;
-                       break;
-
-               case OID_PNP_ENABLE_WAKE_UP:
-                       RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
-                       break;
-
-               default:
-                       RetCode = SK_PNMI_ERR_GENERAL;
-                       break;
-               }
-
-               return (RetCode);
-       }
-
-       /*
-        * From here SET or PRESET action. Check if the passed
-        * buffer length is plausible.
-        */
-       switch (Id) {
-       case OID_PNP_SET_POWER:
-       case OID_PNP_ENABLE_WAKE_UP:
-               if (*pLen < sizeof(SK_U32)) {
-
-                       *pLen = sizeof(SK_U32);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               if (*pLen != sizeof(SK_U32)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_BAD_VALUE);
-               }
-               break;
-
-       case OID_PNP_ADD_WAKE_UP_PATTERN:
-       case OID_PNP_REMOVE_WAKE_UP_PATTERN:
-               if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_BAD_VALUE);
-               }
-               break;
-
-    default:
-               *pLen = 0;
-               return (SK_PNMI_ERR_READ_ONLY);
-       }
-
-       /*
-        * Perform preset or set
-        */
-
-       /* POWER module does not support PRESET action */
-       if (Action == SK_PNMI_PRESET) {
-               return (SK_PNMI_ERR_OK);
-       }
-
-       switch (Id) {
-       case OID_PNP_SET_POWER:
-               RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
-               break;
-
-       case OID_PNP_ADD_WAKE_UP_PATTERN:
-               RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
-               break;
-
-       case OID_PNP_REMOVE_WAKE_UP_PATTERN:
-               RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
-               break;
-
-       case OID_PNP_ENABLE_WAKE_UP:
-               RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
-               break;
-
-       default:
-               RetCode = SK_PNMI_ERR_GENERAL;
-       }
-
-       return (RetCode);
-}
-#endif /* SK_POWER_MGMT */
-
-
-/*****************************************************************************
- *
- * Vct - OID handler function of  OIDs
- *
- * Description:
- *     The code is simple. No description necessary.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was performed successfully.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter).
- *     SK_PNMI_ERR_READ_ONLY    Only the Get action is allowed.
- *
- */
-
-PNMI_STATIC int Vct(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* Get/PreSet/Set action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer to which the mgmt data will be copied */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (-1,2..n) that is to be queried */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       SK_GEPORT       *pPrt;
-       SK_PNMI_VCT     *pVctBackupData;
-       SK_U32          LogPortMax;
-       SK_U32          PhysPortMax;
-       SK_U32          PhysPortIndex;
-       SK_U32          Limit;
-       SK_U32          Offset;
-       SK_BOOL         Link;
-       SK_U32          RetCode = SK_PNMI_ERR_GENERAL;
-       int             i;
-       SK_EVPARA       Para;
-       SK_U32          CableLength;
-
-       /*
-        * Calculate the port indexes from the instance.
-        */
-       PhysPortMax = pAC->GIni.GIMacsFound;
-       LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
-
-       /* Dual net mode? */
-       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-               LogPortMax--;
-       }
-
-       if ((Instance != (SK_U32) (-1))) {
-               /* Check instance range. */
-               if ((Instance < 2) || (Instance > LogPortMax)) {
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-
-               if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                       PhysPortIndex = NetIndex;
-               }
-               else {
-                       PhysPortIndex = Instance - 2;
-               }
-               Limit = PhysPortIndex + 1;
-       }
-       else {  /*
-                * Instance == (SK_U32) (-1), get all Instances of that OID.
-                *
-                * Not implemented yet. May be used in future releases.
-                */
-               PhysPortIndex = 0;
-               Limit = PhysPortMax;
-       }
-
-       pPrt = &pAC->GIni.GP[PhysPortIndex];
-       if (pPrt->PHWLinkUp) {
-               Link = SK_TRUE;
-       }
-       else {
-               Link = SK_FALSE;
-       }
-
-       /*
-        * Check MAC type.
-        */
-       if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
-               *pLen = 0;
-               return (SK_PNMI_ERR_GENERAL);
-       }
-
-       /* Initialize backup data pointer. */
-       pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
-
-       /*
-        * Check action type.
-        */
-       if (Action == SK_PNMI_GET) {
-               /*
-                * Check length.
-                */
-               switch (Id) {
-
-               case OID_SKGE_VCT_GET:
-                       if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
-                               *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       break;
-
-               case OID_SKGE_VCT_STATUS:
-                       if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
-                               *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       break;
-
-               default:
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               /*
-                * Get value.
-                */
-               Offset = 0;
-               for (; PhysPortIndex < Limit; PhysPortIndex++) {
-                       switch (Id) {
-
-                       case OID_SKGE_VCT_GET:
-                               if ((Link == SK_FALSE) &&
-                                       (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
-                                       RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
-                                       if (RetCode == 0) {
-                                               pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
-                                               pAC->Pnmi.VctStatus[PhysPortIndex] |=
-                                                       (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
-
-                                               /* Copy results for later use to PNMI struct. */
-                                               for (i = 0; i < 4; i++)  {
-                                                       if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
-                                                               if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
-                                                                       pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
-                                                               }
-                                                       }
-                                                       if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
-                                                               CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
-                                                       }
-                                                       else {
-                                                               CableLength = 0;
-                                                       }
-                                                       pVctBackupData->PMdiPairLen[i] = CableLength;
-                                                       pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
-                                               }
-
-                                               Para.Para32[0] = PhysPortIndex;
-                                               Para.Para32[1] = -1;
-                                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
-                                               SkEventDispatcher(pAC, IoC);
-                                       }
-                                       else {
-                                               ; /* VCT test is running. */
-                                       }
-                               }
-
-                               /* Get all results. */
-                               CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
-                               Offset += sizeof(SK_U8);
-                               *(pBuf + Offset) = pPrt->PCableLen;
-                               Offset += sizeof(SK_U8);
-                               for (i = 0; i < 4; i++)  {
-                                       SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
-                                       Offset += sizeof(SK_U32);
-                               }
-                               for (i = 0; i < 4; i++)  {
-                                       *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
-                                       Offset += sizeof(SK_U8);
-                               }
-
-                               RetCode = SK_PNMI_ERR_OK;
-                               break;
-
-                       case OID_SKGE_VCT_STATUS:
-                               CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
-                               Offset += sizeof(SK_U8);
-                               RetCode = SK_PNMI_ERR_OK;
-                               break;
-
-                       default:
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-               } /* for */
-               *pLen = Offset;
-               return (RetCode);
-
-       } /* if SK_PNMI_GET */
-
-       /*
-        * From here SET or PRESET action. Check if the passed
-        * buffer length is plausible.
-        */
-
-       /*
-        * Check length.
-        */
-       switch (Id) {
-       case OID_SKGE_VCT_SET:
-               if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
-                       *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       default:
-               *pLen = 0;
-               return (SK_PNMI_ERR_GENERAL);
-       }
-
-       /*
-        * Perform preset or set.
-        */
-
-       /* VCT does not support PRESET action. */
-       if (Action == SK_PNMI_PRESET) {
-               return (SK_PNMI_ERR_OK);
-       }
-
-       Offset = 0;
-       for (; PhysPortIndex < Limit; PhysPortIndex++) {
-               switch (Id) {
-               case OID_SKGE_VCT_SET: /* Start VCT test. */
-                       if (Link == SK_FALSE) {
-                               SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
-
-                               RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
-                               if (RetCode == 0) { /* RetCode: 0 => Start! */
-                                       pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
-                                       pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
-                                       pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
-
-                                       /*
-                                        * Start VCT timer counter.
-                                        */
-                                       SK_MEMSET((char *) &Para, 0, sizeof(Para));
-                                       Para.Para32[0] = PhysPortIndex;
-                                       Para.Para32[1] = -1;
-                                       SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
-                                               4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
-                                       SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
-                                       RetCode = SK_PNMI_ERR_OK;
-                               }
-                               else { /* RetCode: 2 => Running! */
-                                       SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
-                                       RetCode = SK_PNMI_ERR_OK;
-                               }
-                       }
-                       else { /* RetCode: 4 => Link! */
-                               RetCode = 4;
-                               SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
-                               RetCode = SK_PNMI_ERR_OK;
-                       }
-                       Offset += sizeof(SK_U32);
-                       break;
-
-               default:
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-       } /* for */
-       *pLen = Offset;
-       return (RetCode);
-
-} /* Vct */
-
-
-PNMI_STATIC void CheckVctStatus(
-SK_AC          *pAC,
-SK_IOC         IoC,
-char           *pBuf,
-SK_U32         Offset,
-SK_U32         PhysPortIndex)
-{
-       SK_GEPORT       *pPrt;
-       SK_PNMI_VCT     *pVctData;
-       SK_U32          RetCode;
-       SK_U8           LinkSpeedUsed;
-
-       pPrt = &pAC->GIni.GP[PhysPortIndex];
-
-       pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
-       pVctData->VctStatus = SK_PNMI_VCT_NONE;
-
-       if (!pPrt->PHWLinkUp) {
-
-               /* Was a VCT test ever made before? */
-               if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
-                       if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
-                               pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
-                       }
-                       else {
-                               pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
-                       }
-               }
-
-               /* Check VCT test status. */
-               RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
-               if (RetCode == 2) { /* VCT test is running. */
-                       pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
-               }
-               else { /* VCT data was copied to pAC here. Check PENDING state. */
-                       if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
-                               pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
-                       }
-               }
-
-               if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
-                       pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
-               }
-       }
-       else {
-
-               /* Was a VCT test ever made before? */
-               if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
-                       pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
-                       pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
-               }
-
-               /* DSP only valid in 100/1000 modes. */
-               LinkSpeedUsed = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
-               if (LinkSpeedUsed != SK_LSPEED_STAT_10MBPS) {
-                       pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
-               }
-       }
-
-} /* CheckVctStatus */
-
-#endif /* CONFIG_SK98 */
diff --git a/drivers/sk98lin/skgesirq.c b/drivers/sk98lin/skgesirq.c
deleted file mode 100644 (file)
index e5a4f7e..0000000
+++ /dev/null
@@ -1,2417 +0,0 @@
-/******************************************************************************
- *
- * Name:       skgesirq.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.83 $
- * Date:       $Date: 2003/02/05 15:10:59 $
- * Purpose:    Special IRQ module
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skgesirq.c,v $
- *     Revision 1.83  2003/02/05 15:10:59  rschmidt
- *     Fixed setting of PLinkSpeedUsed in SkHWLinkUp() when
- *     auto-negotiation is disabled.
- *     Editorial changes.
- *
- *     Revision 1.82  2003/01/29 13:34:33  rschmidt
- *     Added some typecasts to avoid compiler warnings.
- *
- *     Revision 1.81  2002/12/05 10:49:51  rschmidt
- *     Fixed missing Link Down Event for fiber (Bug Id #10768)
- *     Added reading of cable length when link is up
- *     Removed testing of unused error bits in PHY ISR
- *     Editorial changes.
- *
- *     Revision 1.80  2002/11/12 17:15:21  rschmidt
- *     Replaced SkPnmiGetVar() by ...MacStatistic() in SkMacParity().
- *     Editorial changes.
- *
- *     Revision 1.79  2002/10/14 15:14:51  rschmidt
- *     Changed clearing of IS_M1_PAR_ERR (MAC 1 Parity Error) in
- *     SkMacParity() depending on GIChipRev (HW-Bug #8).
- *     Added error messages for GPHY Auto-Negotiation Error and
- *     FIFO Overflow/Underrun in SkPhyIsrGmac().
- *     Editorial changes.
- *
- *     Revision 1.78  2002/10/10 15:54:29  mkarl
- *     changes for PLinkSpeedUsed
- *
- *     Revision 1.77  2002/09/12 08:58:51  rwahl
- *     Retrieve counters needed for XMAC errata workarounds directly because
- *     PNMI returns corrected counter values (e.g. #10620).
- *
- *     Revision 1.76  2002/08/16 15:21:54  rschmidt
- *     Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis.
- *     Replaced wrong 1st para pAC with IoC in SK_IN/OUT macros.
- *     Editorial changes.
- *
- *     Revision 1.75  2002/08/12 13:50:47  rschmidt
- *     Changed clearing of IS_M1_PAR_ERR (MAC 1 Parity Error) in
- *     SkMacParity() by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE (HW-Bug #8).
- *     Added clearing of IS_IRQ_TIST_OV and IS_IRQ_SENSOR in SkGeHwErr().
- *     Corrected handling of Link Up and Auto-Negotiation Over for GPHY.
- *     in SkGePortCheckUpGmac().
- *     Editorial changes.
- *
- *     Revision 1.74  2002/08/08 16:17:04  rschmidt
- *     Added PhyType check for SK_HWEV_SET_ROLE event (copper only)
- *     Changed Link Up check reading PHY Specific Status (YUKON)
- *     Editorial changes
- *
- *     Revision 1.73  2002/07/15 18:36:53  rwahl
- *     Editorial changes.
- *
- *     Revision 1.72  2002/07/15 15:46:26  rschmidt
- *     Added new event: SK_HWEV_SET_SPEED
- *     Editorial changes
- *
- *     Revision 1.71  2002/06/10 09:34:19  rschmidt
- *     Editorial changes
- *
- *     Revision 1.70  2002/06/05 08:29:18  rschmidt
- *     SkXmRxTxEnable() replaced by SkMacRxTxEnable().
- *     Editorial changes.
- *
- *     Revision 1.69  2002/04/25 13:03:49  rschmidt
- *     Changes for handling YUKON.
- *     Use of #ifdef OTHER_PHY to eliminate code for unused Phy types.
- *     Replaced all XMAC-access macros by functions: SkMacRxTxDisable(),
- *     SkMacIrqDisable().
- *     Added handling for GMAC FIFO in SkMacParity().
- *     Replaced all SkXm...() functions with SkMac...() to handle also
- *     YUKON's GMAC.
- *     Macros for XMAC PHY access PHY_READ(), PHY_WRITE() replaced
- *     by functions SkXmPhyRead(), SkXmPhyWrite().
- *     Disabling all PHY interrupts moved to SkMacIrqDisable().
- *     Added handling for GPHY IRQ in SkGeSirqIsr().
- *     Removed status parameter from MAC IRQ handler SkMacIrq().
- *     Added SkGePortCheckUpGmac(), SkPhyIsrGmac() for GMAC.
- *     Editorial changes
- *
- *     Revision 1.68  2002/02/26 15:24:53  rwahl
- *     Fix: no link with manual configuration (#10673). The previous fix for
- *     #10639 was removed. So for RLMT mode = CLS the RLMT may switch to
- *     misconfigured port. It should not occur for the other RLMT modes.
- *
- *     Revision 1.67  2001/11/20 09:19:58  rwahl
- *     Reworked bugfix #10639 (no dependency to RLMT mode).
- *
- *     Revision 1.66  2001/10/26 07:52:53  afischer
- *     Port switching bug in `check local link` mode
- *
- *     Revision 1.65  2001/02/23 13:41:51  gklug
- *     fix: PHYS2INST should be used correctly for Dual Net operation
- *     chg: do no longer work with older PNMI
- *
- *     Revision 1.64  2001/02/15 11:27:04  rassmann
- *     Working with RLMT v1 if SK_MAX_NETS undefined.
- *
- *     Revision 1.63  2001/02/06 10:44:23  mkunz
- *     - NetIndex added to interface functions of pnmi V4 with dual net support
- *
- *     Revision 1.62  2001/01/31 15:31:41  gklug
- *     fix: problem with autosensing an SR8800 switch
- *
- *     Revision 1.61  2000/11/09 11:30:09  rassmann
- *     WA: Waiting after releasing reset until BCom chip is accessible.
- *
- *     Revision 1.60  2000/10/18 12:37:48  cgoos
- *     Reinserted the comment for version 1.56.
- *
- *     Revision 1.59  2000/10/18 12:22:20  cgoos
- *     Added workaround for half duplex hangup.
- *
- *     Revision 1.58  2000/09/28 13:06:04  gklug
- *     fix: BCom may NOT be touched if XMAC is in RESET state
- *
- *     Revision 1.57  2000/09/08 12:38:39  cgoos
- *     Added forgotten variable declaration.
- *
- *     Revision 1.56  2000/09/08 08:12:13  cgoos
- *     Changed handling of parity errors in SkGeHwErr (correct reset of error).
- *
- *     Revision 1.55  2000/06/19 08:36:25  cgoos
- *     Changed comment.
- *
- *     Revision 1.54  2000/05/22 08:45:57  malthoff
- *     Fix: #10523 is valid for all BCom PHYs.
- *
- *     Revision 1.53  2000/05/19 10:20:30  cgoos
- *     Removed Solaris debug output code.
- *
- *     Revision 1.52  2000/05/19 10:19:37  cgoos
- *     Added PHY state check in HWLinkDown.
- *     Move PHY interrupt code to IS_EXT_REG case in SkGeSirqIsr.
- *
- *     Revision 1.51  2000/05/18 05:56:20  cgoos
- *     Fixed typo.
- *
- *     Revision 1.50  2000/05/17 12:49:49  malthoff
- *     Fixes BCom link bugs (#10523).
- *
- *     Revision 1.49  1999/12/17 11:02:50  gklug
- *     fix: read PHY_STAT of Broadcom chip more often to assure good status
- *
- *     Revision 1.48  1999/12/06 10:01:17  cgoos
- *     Added SET function for Role.
- *
- *     Revision 1.47  1999/11/22 13:34:24  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.46  1999/09/16 10:30:07  cgoos
- *     Removed debugging output statement from Linux.
- *
- *     Revision 1.45  1999/09/16 07:32:55  cgoos
- *     Fixed dual-port copperfield bug (PHY_READ from resetted port).
- *     Removed some unused variables.
- *
- *     Revision 1.44  1999/08/03 15:25:04  cgoos
- *     Removed workaround for disabled interrupts in half duplex mode.
- *
- *     Revision 1.43  1999/08/03 14:27:58  cgoos
- *     Removed SENSE mode code from SkGePortCheckUpBcom.
- *
- *     Revision 1.42  1999/07/26 09:16:54  cgoos
- *     Added some typecasts to avoid compiler warnings.
- *
- *     Revision 1.41  1999/05/19 07:28:59  cgoos
- *     Changes for 1000Base-T.
- *
- *     Revision 1.40  1999/04/08 13:59:39  gklug
- *     fix: problem with 3Com switches endless RESTARTs
- *
- *     Revision 1.39  1999/03/08 10:10:52  gklug
- *     fix: AutoSensing did switch to next mode even if LiPa indicated offline
- *
- *     Revision 1.38  1999/03/08 09:49:03  gklug
- *     fix: Bug using pAC instead of IoC, causing AIX problems
- *     fix: change compare for Linux compiler bug workaround
- *
- *     Revision 1.37  1999/01/28 14:51:33  gklug
- *     fix: monitor for autosensing and extra RESETS the RX on wire counters
- *
- *     Revision 1.36  1999/01/22 09:19:55  gklug
- *     fix: Init DupMode and InitPauseMd are now called in RxTxEnable
- *
- *     Revision 1.35  1998/12/11 15:22:59  gklug
- *     chg: autosensing: check for receive if manual mode was guessed
- *     chg: simplified workaround for XMAC errata
- *     chg: wait additional 100 ms before link goes up.
- *     chg: autoneg timeout to 600 ms
- *     chg: restart autoneg even if configured to autonegotiation
- *
- *     Revision 1.34  1998/12/10 10:33:14  gklug
- *     add: more debug messages
- *     fix: do a new InitPhy if link went down (AutoSensing problem)
- *     chg: Check for zero shorts if link is NOT up
- *     chg: reset Port if link goes down
- *     chg: wait additional 100 ms when link comes up to check shorts
- *     fix: dummy read extended autoneg status to prevent link going down immediately
- *
- *     Revision 1.33  1998/12/07 12:18:29  gklug
- *     add: refinement of autosense mode: take into account the autoneg cap of LiPa
- *
- *     Revision 1.32  1998/12/07 07:11:21  gklug
- *     fix: compiler warning
- *
- *     Revision 1.31  1998/12/02 09:29:05  gklug
- *     fix: WA XMAC Errata: FCSCt check was not correct.
- *     fix: WA XMAC Errata: Prec Counter were NOT updated in case of short checks.
- *     fix: Clear Stat : now clears the Prev counters of all known Ports
- *
- *     Revision 1.30  1998/12/01 10:54:15  gklug
- *     dd: workaround for XMAC errata changed. Check RX count and CRC err Count, too.
- *
- *     Revision 1.29  1998/12/01 10:01:53  gklug
- *     fix: if MAC IRQ occurs during port down, this will be handled correctly
- *
- *     Revision 1.28  1998/11/26 16:22:11  gklug
- *     fix: bug in autosense if manual modes are used
- *
- *     Revision 1.27  1998/11/26 15:50:06  gklug
- *     fix: PNMI needs to set PLinkModeConf
- *
- *     Revision 1.26  1998/11/26 14:51:58  gklug
- *     add: AutoSensing functionalty
- *
- *     Revision 1.25  1998/11/26 07:34:37  gklug
- *     fix: Init PrevShorts when restarting port due to Link connection
- *
- *     Revision 1.24  1998/11/25 10:57:32  gklug
- *     fix: remove unreferenced local vars
- *
- *     Revision 1.23  1998/11/25 08:26:40  gklug
- *     fix: don't do a RESET on a starting or stopping port
- *
- *     Revision 1.22  1998/11/24 13:29:44  gklug
- *     add: Workaround for MAC parity errata
- *
- *     Revision 1.21  1998/11/18 15:31:06  gklug
- *     fix: lint bugs
- *
- *     Revision 1.20  1998/11/18 12:58:54  gklug
- *     fix: use PNMI query instead of hardware access
- *
- *     Revision 1.19  1998/11/18 12:54:55  gklug
- *     chg: add new workaround for XMAC Errata
- *     add: short event counter monitoring on active link too
- *
- *     Revision 1.18  1998/11/13 14:27:41  malthoff
- *     Bug Fix: Packet Arbiter Timeout was not cleared correctly
- *     for timeout on TX1 and TX2.
- *
- *     Revision 1.17  1998/11/04 07:01:59  cgoos
- *     Moved HW link poll sequence.
- *     Added call to SkXmRxTxEnable.
- *
- *     Revision 1.16  1998/11/03 13:46:03  gklug
- *     add: functionality of SET_LMODE and SET_FLOW_MODE
- *     fix: send RLMT LinkDown event when Port stop is given with LinkUp
- *
- *     Revision 1.15  1998/11/03 12:56:47  gklug
- *     fix: Needs more events
- *
- *     Revision 1.14  1998/10/30 07:36:35  gklug
- *     rmv: unnecessary code
- *
- *     Revision 1.13  1998/10/29 15:21:57  gklug
- *     add: Poll link feature for activating HW link
- *     fix: Deactivate HWLink when Port STOP is given
- *
- *     Revision 1.12  1998/10/28 07:38:57  cgoos
- *     Checking link status at begin of SkHWLinkUp.
- *
- *     Revision 1.11  1998/10/22 09:46:50  gklug
- *     fix SysKonnectFileId typo
- *
- *     Revision 1.10  1998/10/14 13:57:47  gklug
- *     add: Port start/stop event
- *
- *     Revision 1.9  1998/10/14 05:48:29  cgoos
- *     Added definition for Para.
- *
- *     Revision 1.8  1998/10/14 05:40:09  gklug
- *     add: Hardware Linkup signal used
- *
- *     Revision 1.7  1998/10/09 06:50:20  malthoff
- *     Remove ID_sccs by SysKonnectFileId.
- *
- *     Revision 1.6  1998/10/08 09:11:49  gklug
- *     add: clear IRQ commands
- *
- *     Revision 1.5  1998/10/02 14:27:35  cgoos
- *     Fixed some typos and wrong event names.
- *
- *     Revision 1.4  1998/10/02 06:24:17  gklug
- *     add: HW error function
- *     fix: OUT macros
- *
- *     Revision 1.3  1998/10/01 07:03:00  gklug
- *     add: ISR for the usual interrupt source register
- *
- *     Revision 1.2  1998/09/03 13:50:33  gklug
- *     add: function prototypes
- *
- *     Revision 1.1  1998/08/27 11:50:21  gklug
- *     initial revision
- *
- *
- *
- ******************************************************************************/
-
-#include <config.h>
-
-#ifdef CONFIG_SK98
-
-/*
- *     Special Interrupt handler
- *
- *     The following abstract should show how this module is included
- *     in the driver path:
- *
- *     In the ISR of the driver the bits for frame transmission complete and
- *     for receive complete are checked and handled by the driver itself.
- *     The bits of the slow path mask are checked after that and then the
- *     entry into the so-called "slow path" is prepared. It is an implementors
- *     decision whether this is executed directly or just scheduled by
- *     disabling the mask. In the interrupt service routine some events may be
- *     generated, so it would be a good idea to call the EventDispatcher
- *     right after this ISR.
- *
- *     The Interrupt source register of the adapter is NOT read by this module.
- *  SO if the drivers implementor needs a while loop around the
- *     slow data paths interrupt bits, he needs to call the SkGeSirqIsr() for
- *     each loop entered.
- *
- *     However, the MAC Interrupt status registers are read in a while loop.
- *
- */
-
-static const char SysKonnectFileId[] =
-       "$Id: skgesirq.c,v 1.83 2003/02/05 15:10:59 rschmidt Exp $" ;
-
-#include "h/skdrv1st.h"                /* Driver Specific Definitions */
-#include "h/skgepnmi.h"                /* PNMI Definitions */
-#include "h/skrlmt.h"          /* RLMT Definitions */
-#include "h/skdrv2nd.h"                /* Adapter Control and Driver specific Def. */
-
-/* local function prototypes */
-static int     SkGePortCheckUpXmac(SK_AC*, SK_IOC, int);
-static int     SkGePortCheckUpBcom(SK_AC*, SK_IOC, int);
-static int     SkGePortCheckUpGmac(SK_AC*, SK_IOC, int);
-static void    SkPhyIsrBcom(SK_AC*, SK_IOC, int, SK_U16);
-static void    SkPhyIsrGmac(SK_AC*, SK_IOC, int, SK_U16);
-#ifdef OTHER_PHY
-static int     SkGePortCheckUpLone(SK_AC*, SK_IOC, int);
-static int     SkGePortCheckUpNat(SK_AC*, SK_IOC, int);
-static void    SkPhyIsrLone(SK_AC*, SK_IOC, int, SK_U16);
-#endif /* OTHER_PHY */
-
-/*
- * array of Rx counter from XMAC which are checked
- * in AutoSense mode to check whether a link is not able to auto-negotiate.
- */
-static const SK_U16 SkGeRxRegs[]= {
-       XM_RXF_64B,
-       XM_RXF_127B,
-       XM_RXF_255B,
-       XM_RXF_511B,
-       XM_RXF_1023B,
-       XM_RXF_MAX_SZ
-} ;
-
-#ifdef __C2MAN__
-/*
- *     Special IRQ function
- *
- *     General Description:
- *
- */
-intro()
-{}
-#endif
-
-/* Define return codes of SkGePortCheckUp and CheckShort */
-#define        SK_HW_PS_NONE           0       /* No action needed */
-#define        SK_HW_PS_RESTART        1       /* Restart needed */
-#define        SK_HW_PS_LINK           2       /* Link Up actions needed */
-
-/******************************************************************************
- *
- *     SkHWInitDefSense() - Default Autosensing mode initialization
- *
- * Description: sets the PLinkMode for HWInit
- *
- * Returns: N/A
- */
-static void SkHWInitDefSense(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       pPrt->PAutoNegTimeOut = 0;
-
-       if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
-               pPrt->PLinkMode = pPrt->PLinkModeConf;
-               return;
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-               ("AutoSensing: First mode %d on Port %d\n",
-               (int)SK_LMODE_AUTOFULL, Port));
-
-       pPrt->PLinkMode = SK_LMODE_AUTOFULL;
-
-       return;
-}      /* SkHWInitDefSense */
-
-
-/******************************************************************************
- *
- *     SkHWSenseGetNext() - Get Next Autosensing Mode
- *
- * Description: gets the appropriate next mode
- *
- * Note:
- *
- */
-SK_U8 SkHWSenseGetNext(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       pPrt->PAutoNegTimeOut = 0;
-
-       if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
-               /* Leave all as configured */
-               return(pPrt->PLinkModeConf);
-       }
-
-       if (pPrt->PLinkMode == SK_LMODE_AUTOFULL) {
-               /* Return next mode AUTOBOTH */
-               return(SK_LMODE_AUTOBOTH);
-       }
-
-       /* Return default autofull */
-       return(SK_LMODE_AUTOFULL);
-}      /* SkHWSenseGetNext */
-
-
-/******************************************************************************
- *
- *     SkHWSenseSetNext() - Autosensing Set next mode
- *
- * Description:        sets the appropriate next mode
- *
- * Returns: N/A
- */
-void SkHWSenseSetNext(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_U8  NewMode)        /* New Mode to be written in sense mode */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       pPrt->PAutoNegTimeOut = 0;
-
-       if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
-               return;
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-               ("AutoSensing: next mode %d on Port %d\n",
-               (int)NewMode, Port));
-
-       pPrt->PLinkMode = NewMode;
-
-       return;
-}      /* SkHWSenseSetNext */
-
-
-/******************************************************************************
- *
- *     SkHWLinkDown() - Link Down handling
- *
- * Description: handles the hardware link down signal
- *
- * Returns: N/A
- */
-void SkHWLinkDown(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Disable all MAC interrupts */
-       SkMacIrqDisable(pAC, IoC, Port);
-
-       /* Disable Receiver and Transmitter */
-       SkMacRxTxDisable(pAC, IoC, Port);
-
-       /* Init default sense mode */
-       SkHWInitDefSense(pAC, IoC, Port);
-
-       if (!pPrt->PHWLinkUp) {
-               return;
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-               ("Link down Port %d\n", Port));
-
-       /* Set Link to DOWN */
-       pPrt->PHWLinkUp = SK_FALSE;
-
-       /* Reset Port stati */
-       pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN;
-       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
-       pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_INDETERMINATED;
-
-       /* Re-init Phy especially when the AutoSense default is set now */
-       SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
-
-       /* GP0: used for workaround of Rev. C Errata 2 */
-
-       /* Do NOT signal to RLMT */
-
-       /* Do NOT start the timer here */
-}      /* SkHWLinkDown */
-
-
-/******************************************************************************
- *
- *     SkHWLinkUp() - Link Up handling
- *
- * Description: handles the hardware link up signal
- *
- * Returns: N/A
- */
-void SkHWLinkUp(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PHWLinkUp) {
-               /* We do NOT need to proceed on active link */
-               return;
-       }
-
-       pPrt->PHWLinkUp = SK_TRUE;
-       pPrt->PAutoNegFail = SK_FALSE;
-       pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN;
-
-       if (pPrt->PLinkMode != SK_LMODE_AUTOHALF &&
-           pPrt->PLinkMode != SK_LMODE_AUTOFULL &&
-           pPrt->PLinkMode != SK_LMODE_AUTOBOTH) {
-               /* Link is up and no Auto-negotiation should be done */
-
-               /* Link speed should be the configured one */
-               switch (pPrt->PLinkSpeed) {
-               case SK_LSPEED_AUTO:
-                       /* default is 1000 Mbps */
-               case SK_LSPEED_1000MBPS:
-                       pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
-                       break;
-               case SK_LSPEED_100MBPS:
-                       pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_100MBPS;
-                       break;
-               case SK_LSPEED_10MBPS:
-                       pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_10MBPS;
-                       break;
-               }
-
-               /* Set Link Mode Status */
-               if (pPrt->PLinkMode == SK_LMODE_FULL) {
-                       pPrt->PLinkModeStatus = SK_LMODE_STAT_FULL;
-               }
-               else {
-                       pPrt->PLinkModeStatus = SK_LMODE_STAT_HALF;
-               }
-
-               /* No flow control without auto-negotiation */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
-
-               /* enable Rx/Tx */
-               SkMacRxTxEnable(pAC, IoC, Port);
-       }
-}      /* SkHWLinkUp */
-
-
-/******************************************************************************
- *
- *     SkMacParity() - MAC parity workaround
- *
- * Description: handles MAC parity errors correctly
- *
- * Returns: N/A
- */
-static void SkMacParity(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index of the port failed */
-{
-       SK_EVPARA       Para;
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       SK_U32          TxMax;          /* TxMax Counter */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Clear IRQ Tx Parity Error */
-       if (pAC->GIni.GIGenesis) {
-               SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_PERR);
-       }
-       else {
-               /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */
-               SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T),
-                       (SK_U8)((pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE));
-       }
-
-       if (pPrt->PCheckPar) {
-               if (Port == MAC_1) {
-                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG);
-               }
-               else {
-                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E017, SKERR_SIRQ_E017MSG);
-               }
-               Para.Para64 = Port;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               Para.Para32[0] = Port;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-
-               return;
-       }
-
-       /* Check whether frames with a size of 1k were sent */
-       if (pAC->GIni.GIGenesis) {
-               /* Snap statistic counters */
-               (void)SkXmUpdateStats(pAC, IoC, Port);
-
-               (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax);
-       }
-       else {
-               (void)SkGmMacStatistic(pAC, IoC, Port, GM_TXF_1518B, &TxMax);
-       }
-
-       if (TxMax > 0) {
-               /* From now on check the parity */
-               pPrt->PCheckPar = SK_TRUE;
-       }
-}      /* SkMacParity */
-
-
-/******************************************************************************
- *
- *     SkGeHwErr() - Hardware Error service routine
- *
- * Description: handles all HW Error interrupts
- *
- * Returns: N/A
- */
-static void SkGeHwErr(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-SK_U32 HwStatus)       /* Interrupt status word */
-{
-       SK_EVPARA       Para;
-       SK_U16          Word;
-
-       if ((HwStatus & (IS_IRQ_MST_ERR | IS_IRQ_STAT)) != 0) {
-               /* PCI Errors occured */
-               if ((HwStatus & IS_IRQ_STAT) != 0) {
-                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG);
-               }
-               else {
-                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG);
-               }
-
-               /* Reset all bits in the PCI STATUS register */
-               SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
-
-               SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-               SK_OUT16(IoC, PCI_C(PCI_STATUS), Word | PCI_ERRBITS);
-               SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-
-               Para.Para64 = 0;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
-       }
-
-       if (pAC->GIni.GIGenesis) {
-               if ((HwStatus & IS_NO_STAT_M1) != 0) {
-                       /* Ignore it */
-                       /* This situation is also indicated in the descriptor */
-                       SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INSTAT);
-               }
-
-               if ((HwStatus & IS_NO_STAT_M2) != 0) {
-                       /* Ignore it */
-                       /* This situation is also indicated in the descriptor */
-                       SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INSTAT);
-               }
-
-               if ((HwStatus & IS_NO_TIST_M1) != 0) {
-                       /* Ignore it */
-                       /* This situation is also indicated in the descriptor */
-                       SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INTIST);
-               }
-
-               if ((HwStatus & IS_NO_TIST_M2) != 0) {
-                       /* Ignore it */
-                       /* This situation is also indicated in the descriptor */
-                       SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INTIST);
-               }
-       }
-       else {  /* YUKON */
-               /* This is necessary only for Rx timing measurements */
-               if ((HwStatus & IS_IRQ_TIST_OV) != 0) {
-                       /* Clear Time Stamp Timer IRQ */
-                       SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ);
-               }
-
-               if ((HwStatus & IS_IRQ_SENSOR) != 0) {
-                       /* Clear I2C IRQ */
-                       SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
-               }
-       }
-
-       if ((HwStatus & IS_RAM_RD_PAR) != 0) {
-               SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR);
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG);
-               Para.Para64 = 0;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
-       }
-
-       if ((HwStatus & IS_RAM_WR_PAR) != 0) {
-               SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR);
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG);
-               Para.Para64 = 0;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
-       }
-
-       if ((HwStatus & IS_M1_PAR_ERR) != 0) {
-               SkMacParity(pAC, IoC, MAC_1);
-       }
-
-       if ((HwStatus & IS_M2_PAR_ERR) != 0) {
-               SkMacParity(pAC, IoC, MAC_2);
-       }
-
-       if ((HwStatus & IS_R1_PAR_ERR) != 0) {
-               /* Clear IRQ */
-               SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_P);
-
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG);
-               Para.Para64 = MAC_1;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               Para.Para32[0] = MAC_1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-
-       if ((HwStatus & IS_R2_PAR_ERR) != 0) {
-               /* Clear IRQ */
-               SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_P);
-
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG);
-               Para.Para64 = MAC_2;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               Para.Para32[0] = MAC_2;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-}      /* SkGeHwErr */
-
-
-/******************************************************************************
- *
- *     SkGeSirqIsr() - Special Interrupt Service Routine
- *
- * Description: handles all non data transfer specific interrupts (slow path)
- *
- * Returns: N/A
- */
-void SkGeSirqIsr(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-SK_U32 Istatus)        /* Interrupt status word */
-{
-       SK_EVPARA       Para;
-       SK_U32          RegVal32;       /* Read register value */
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       unsigned        Len;
-       SK_U64          Octets;
-       SK_U16          PhyInt;
-       SK_U16          PhyIMsk;
-       int                     i;
-
-       if ((Istatus & IS_HW_ERR) != 0) {
-               /* read the HW Error Interrupt source */
-               SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
-
-               SkGeHwErr(pAC, IoC, RegVal32);
-       }
-
-       /*
-        * Packet Timeout interrupts
-        */
-       /* Check whether MACs are correctly initialized */
-       if (((Istatus & (IS_PA_TO_RX1 | IS_PA_TO_TX1)) != 0) &&
-               pAC->GIni.GP[MAC_1].PState == SK_PRT_RESET) {
-               /* MAC 1 was not initialized but Packet timeout occured */
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E004,
-                       SKERR_SIRQ_E004MSG);
-       }
-
-       if (((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) != 0) &&
-           pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) {
-               /* MAC 2 was not initialized but Packet timeout occured */
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005,
-                       SKERR_SIRQ_E005MSG);
-       }
-
-       if ((Istatus & IS_PA_TO_RX1) != 0) {
-               /* Means network is filling us up */
-               SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E002,
-                       SKERR_SIRQ_E002MSG);
-               SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX1);
-       }
-
-       if ((Istatus & IS_PA_TO_RX2) != 0) {
-               /* Means network is filling us up */
-               SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E003,
-                       SKERR_SIRQ_E003MSG);
-               SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX2);
-       }
-
-       if ((Istatus & IS_PA_TO_TX1) != 0) {
-
-               pPrt = &pAC->GIni.GP[0];
-
-               /* May be a normal situation in a server with a slow network */
-               SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1);
-
-               /*
-                * workaround: if in half duplex mode, check for Tx hangup.
-                * Read number of TX'ed bytes, wait for 10 ms, then compare
-                * the number with current value. If nothing changed, we assume
-                * that Tx is hanging and do a FIFO flush (see event routine).
-                */
-               if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
-                   pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
-                   !pPrt->HalfDupTimerActive) {
-                       /*
-                        * many more pack. arb. timeouts may come in between,
-                        * we ignore those
-                        */
-                       pPrt->HalfDupTimerActive = SK_TRUE;
-
-                       Len = sizeof(SK_U64);
-                       SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
-                               &Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(pAC, 0),
-                               pAC->Rlmt.Port[0].Net->NetNumber);
-
-                       pPrt->LastOctets = Octets;
-
-                       Para.Para32[0] = 0;
-                       SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
-                               SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
-               }
-       }
-
-       if ((Istatus & IS_PA_TO_TX2) != 0) {
-
-               pPrt = &pAC->GIni.GP[1];
-
-               /* May be a normal situation in a server with a slow network */
-               SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2);
-
-               /* workaround: see above */
-               if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
-                    pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
-                   !pPrt->HalfDupTimerActive) {
-                       pPrt->HalfDupTimerActive = SK_TRUE;
-
-                       Len = sizeof(SK_U64);
-                       SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
-                               &Len, (SK_U32) SK_PNMI_PORT_PHYS2INST(pAC, 1),
-                               pAC->Rlmt.Port[1].Net->NetNumber);
-
-                       pPrt->LastOctets = Octets;
-
-                       Para.Para32[0] = 1;
-                       SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
-                               SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
-               }
-       }
-
-       /* Check interrupts of the particular queues */
-       if ((Istatus & IS_R1_C) != 0) {
-               /* Clear IRQ */
-               SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C);
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006,
-                       SKERR_SIRQ_E006MSG);
-               Para.Para64 = MAC_1;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               Para.Para32[0] = MAC_1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-
-       if ((Istatus & IS_R2_C) != 0) {
-               /* Clear IRQ */
-               SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C);
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007,
-                       SKERR_SIRQ_E007MSG);
-               Para.Para64 = MAC_2;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               Para.Para32[0] = MAC_2;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-
-       if ((Istatus & IS_XS1_C) != 0) {
-               /* Clear IRQ */
-               SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C);
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008,
-                       SKERR_SIRQ_E008MSG);
-               Para.Para64 = MAC_1;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               Para.Para32[0] = MAC_1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-
-       if ((Istatus & IS_XA1_C) != 0) {
-               /* Clear IRQ */
-               SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C);
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009,
-                       SKERR_SIRQ_E009MSG);
-               Para.Para64 = MAC_1;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               Para.Para32[0] = MAC_1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-
-       if ((Istatus & IS_XS2_C) != 0) {
-               /* Clear IRQ */
-               SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C);
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010,
-                       SKERR_SIRQ_E010MSG);
-               Para.Para64 = MAC_2;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               Para.Para32[0] = MAC_2;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-
-       if ((Istatus & IS_XA2_C) != 0) {
-               /* Clear IRQ */
-               SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C);
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011,
-                       SKERR_SIRQ_E011MSG);
-               Para.Para64 = MAC_2;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               Para.Para32[0] = MAC_2;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-
-       /* External reg interrupt */
-       if ((Istatus & IS_EXT_REG) != 0) {
-               /* Test IRQs from PHY */
-               for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-
-                       pPrt = &pAC->GIni.GP[i];
-
-                       if (pPrt->PState == SK_PRT_RESET) {
-                               continue;
-                       }
-
-                       switch (pPrt->PhyType) {
-
-                       case SK_PHY_XMAC:
-                               break;
-
-                       case SK_PHY_BCOM:
-                               SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt);
-                               SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_MASK, &PhyIMsk);
-
-                               if ((PhyInt & ~PhyIMsk) != 0) {
-                                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                                               ("Port %d Bcom Int: 0x%04X Mask: 0x%04X\n",
-                                               i, PhyInt, PhyIMsk));
-                                       SkPhyIsrBcom(pAC, IoC, i, PhyInt);
-                               }
-                               break;
-
-                       case SK_PHY_MARV_COPPER:
-                       case SK_PHY_MARV_FIBER:
-                               SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt);
-                               SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_MASK, &PhyIMsk);
-
-                               if ((PhyInt & PhyIMsk) != 0) {
-                                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                                               ("Port %d Marv Int: 0x%04X Mask: 0x%04X\n",
-                                               i, PhyInt, PhyIMsk));
-                                       SkPhyIsrGmac(pAC, IoC, i, PhyInt);
-                               }
-                               break;
-
-#ifdef OTHER_PHY
-                       case SK_PHY_LONE:
-                               SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt);
-                               SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_ENAB, &PhyIMsk);
-
-                               if ((PhyInt & PhyIMsk) != 0) {
-                                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                                               ("Port %d Lone Int: %x Mask: %x\n",
-                                               i, PhyInt, PhyIMsk));
-                                       SkPhyIsrLone(pAC, IoC, i, PhyInt);
-                               }
-                               break;
-                       case SK_PHY_NAT:
-                               /* todo: National */
-                               break;
-#endif /* OTHER_PHY */
-                       }
-               }
-       }
-
-       /* I2C Ready interrupt */
-       if ((Istatus & IS_I2C_READY) != 0) {
-               SkI2cIsr(pAC, IoC);
-       }
-
-       if ((Istatus & IS_LNK_SYNC_M1) != 0) {
-               /*
-                * We do NOT need the Link Sync interrupt, because it shows
-                * us only a link going down.
-                */
-               /* clear interrupt */
-               SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ);
-       }
-
-       /* Check MAC after link sync counter */
-       if ((Istatus & IS_MAC1) != 0) {
-               /* IRQ from MAC 1 */
-               SkMacIrq(pAC, IoC, MAC_1);
-       }
-
-       if ((Istatus & IS_LNK_SYNC_M2) != 0) {
-               /*
-                * We do NOT need the Link Sync interrupt, because it shows
-                * us only a link going down.
-                */
-               /* clear interrupt */
-               SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ);
-       }
-
-       /* Check MAC after link sync counter */
-       if ((Istatus & IS_MAC2) != 0) {
-               /* IRQ from MAC 2 */
-               SkMacIrq(pAC, IoC, MAC_2);
-       }
-
-       /* Timer interrupt (served last) */
-       if ((Istatus & IS_TIMINT) != 0) {
-               SkHwtIsr(pAC, IoC);
-       }
-}      /* SkGeSirqIsr */
-
-
-/******************************************************************************
- *
- * SkGePortCheckShorts() - Implementing XMAC Workaround Errata # 2
- *
- * return:
- *     0       o.k. nothing needed
- *     1       Restart needed on this port
- */
-static int     SkGePortCheckShorts(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO Context */
-int            Port)           /* Which port should be checked */
-{
-       SK_U32          Shorts;                 /* Short Event Counter */
-       SK_U32          CheckShorts;    /* Check value for Short Event Counter */
-       SK_U64          RxCts;                  /* Rx Counter (packets on network) */
-       SK_U32          RxTmp;                  /* Rx temp. Counter */
-       SK_U32          FcsErrCts;              /* FCS Error Counter */
-       SK_GEPORT       *pPrt;                  /* GIni Port struct pointer */
-       int                     Rtv;                    /* Return value */
-       int                     i;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Default: no action */
-       Rtv = SK_HW_PS_NONE;
-
-       (void)SkXmUpdateStats(pAC, IoC, Port);
-
-       /* Extra precaution: check for short Event counter */
-       (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
-
-       /*
-        * Read Rx counter (packets seen on the network and not necessarily
-        * really received.
-        */
-       RxCts = 0;
-
-       for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) {
-               (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp);
-               RxCts += (SK_U64)RxTmp;
-       }
-
-       /* On default: check shorts against zero */
-       CheckShorts = 0;
-
-       /* Extra precaution on active links */
-       if (pPrt->PHWLinkUp) {
-               /* Reset Link Restart counter */
-               pPrt->PLinkResCt = 0;
-               pPrt->PAutoNegTOCt = 0;
-
-               /* If link is up check for 2 */
-               CheckShorts = 2;
-
-               (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts);
-
-               if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
-                   pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN &&
-                   (pPrt->PLinkMode == SK_LMODE_HALF ||
-                        pPrt->PLinkMode == SK_LMODE_FULL)) {
-                       /*
-                        * This is autosensing and we are in the fallback
-                        * manual full/half duplex mode.
-                        */
-                       if (RxCts == pPrt->PPrevRx) {
-                               /* Nothing received, restart link */
-                               pPrt->PPrevFcs = FcsErrCts;
-                               pPrt->PPrevShorts = Shorts;
-
-                               return(SK_HW_PS_RESTART);
-                       }
-                       else {
-                               pPrt->PLipaAutoNeg = SK_LIPA_MANUAL;
-                       }
-               }
-
-               if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) ||
-                   (!(FcsErrCts - pPrt->PPrevFcs))) {
-                       /*
-                        * Note: The compare with zero above has to be done the way shown,
-                        * otherwise the Linux driver will have a problem.
-                        */
-                       /*
-                        * We received a bunch of frames or no CRC error occured on the
-                        * network -> ok.
-                        */
-                       pPrt->PPrevRx = RxCts;
-                       pPrt->PPrevFcs = FcsErrCts;
-                       pPrt->PPrevShorts = Shorts;
-
-                       return(SK_HW_PS_NONE);
-               }
-
-               pPrt->PPrevFcs = FcsErrCts;
-       }
-
-
-       if ((Shorts - pPrt->PPrevShorts) > CheckShorts) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                       ("Short Event Count Restart Port %d \n", Port));
-               Rtv = SK_HW_PS_RESTART;
-       }
-
-       pPrt->PPrevShorts = Shorts;
-       pPrt->PPrevRx = RxCts;
-
-       return(Rtv);
-}      /* SkGePortCheckShorts */
-
-
-/******************************************************************************
- *
- * SkGePortCheckUp() - Check if the link is up
- *
- * return:
- *     0       o.k. nothing needed
- *     1       Restart needed on this port
- *     2       Link came up
- */
-static int     SkGePortCheckUp(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO Context */
-int            Port)           /* Which port should be checked */
-{
-       switch (pAC->GIni.GP[Port].PhyType) {
-       case SK_PHY_XMAC:
-               return(SkGePortCheckUpXmac(pAC, IoC, Port));
-       case SK_PHY_BCOM:
-               return(SkGePortCheckUpBcom(pAC, IoC, Port));
-       case SK_PHY_MARV_COPPER:
-       case SK_PHY_MARV_FIBER:
-               return(SkGePortCheckUpGmac(pAC, IoC, Port));
-#ifdef OTHER_PHY
-       case SK_PHY_LONE:
-               return(SkGePortCheckUpLone(pAC, IoC, Port));
-       case SK_PHY_NAT:
-               return(SkGePortCheckUpNat(pAC, IoC, Port));
-#endif /* OTHER_PHY */
-       }
-       return(SK_HW_PS_NONE);
-}      /* SkGePortCheckUp */
-
-
-/******************************************************************************
- *
- * SkGePortCheckUpXmac() - Implementing of the Workaround Errata # 2
- *
- * return:
- *     0       o.k. nothing needed
- *     1       Restart needed on this port
- *     2       Link came up
- */
-static int SkGePortCheckUpXmac(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO Context */
-int            Port)           /* Which port should be checked */
-{
-       SK_U32          Shorts;         /* Short Event Counter */
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       int                     Done;
-       SK_U32          GpReg;          /* General Purpose register value */
-       SK_U16          Isrc;           /* Interrupt source register */
-       SK_U16          IsrcSum;        /* Interrupt source register sum */
-       SK_U16          LpAb;           /* Link Partner Ability */
-       SK_U16          ResAb;          /* Resolved Ability */
-       SK_U16          ExtStat;        /* Extended Status Register */
-       SK_BOOL         AutoNeg;        /* Is Auto-negotiation used ? */
-       SK_U8           NextMode;       /* Next AutoSensing Mode */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PHWLinkUp) {
-               if (pPrt->PhyType != SK_PHY_XMAC) {
-                       return(SK_HW_PS_NONE);
-               }
-               else {
-                       return(SkGePortCheckShorts(pAC, IoC, Port));
-               }
-       }
-
-       IsrcSum = pPrt->PIsave;
-       pPrt->PIsave = 0;
-
-       /* Now wait for each port's link */
-       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
-               AutoNeg = SK_FALSE;
-       }
-       else {
-               AutoNeg = SK_TRUE;
-       }
-
-       if (pPrt->PLinkBroken) {
-               /* Link was broken */
-               XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
-
-               if ((GpReg & XM_GP_INP_ASS) == 0) {
-                       /* The Link is in sync */
-                       XM_IN16(IoC, Port, XM_ISRC, &Isrc);
-                       IsrcSum |= Isrc;
-                       SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
-
-                       if ((Isrc & XM_IS_INP_ASS) == 0) {
-                               /* It has been in sync since last time */
-                               /* Restart the PORT */
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                                       ("Link in sync Restart Port %d\n", Port));
-
-                               (void)SkXmUpdateStats(pAC, IoC, Port);
-
-                               /* We now need to reinitialize the PrevShorts counter */
-                               (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
-                               pPrt->PPrevShorts = Shorts;
-
-                               pPrt->PLinkBroken = SK_FALSE;
-
-                               /*
-                                * Link Restart Workaround:
-                                *  it may be possible that the other Link side
-                                *  restarts its link as well an we detect
-                                *  another LinkBroken. To prevent this
-                                *  happening we check for a maximum number
-                                *  of consecutive restart. If those happens,
-                                *  we do NOT restart the active link and
-                                *  check whether the link is now o.k.
-                                */
-                               pPrt->PLinkResCt++;
-
-                               pPrt->PAutoNegTimeOut = 0;
-
-                               if (pPrt->PLinkResCt < SK_MAX_LRESTART) {
-                                       return(SK_HW_PS_RESTART);
-                               }
-
-                               pPrt->PLinkResCt = 0;
-
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                                       ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum));
-                       }
-                       else {
-                               pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
-
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                                       ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum));
-
-                               /* Do nothing more if link is broken */
-                               return(SK_HW_PS_NONE);
-                       }
-               }
-               else {
-                       /* Do nothing more if link is broken */
-                       return(SK_HW_PS_NONE);
-               }
-
-       }
-       else {
-               /* Link was not broken, check if it is */
-               XM_IN16(IoC, Port, XM_ISRC, &Isrc);
-               IsrcSum |= Isrc;
-               if ((Isrc & XM_IS_INP_ASS) != 0) {
-                       XM_IN16(IoC, Port, XM_ISRC, &Isrc);
-                       IsrcSum |= Isrc;
-                       if ((Isrc & XM_IS_INP_ASS) != 0) {
-                               XM_IN16(IoC, Port, XM_ISRC, &Isrc);
-                               IsrcSum |= Isrc;
-                               if ((Isrc & XM_IS_INP_ASS) != 0) {
-                                       pPrt->PLinkBroken = SK_TRUE;
-                                       /* Re-Init Link partner Autoneg flag */
-                                       pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
-                                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                                               ("Link broken Port %d\n", Port));
-
-                                       /* Cable removed-> reinit sense mode */
-                                       SkHWInitDefSense(pAC, IoC, Port);
-
-                                       return(SK_HW_PS_RESTART);
-                               }
-                       }
-               }
-               else {
-                       SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc);
-                       if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) {
-                               return(SK_HW_PS_RESTART);
-                       }
-               }
-       }
-
-       /*
-        * here we usually can check whether the link is in sync and
-        * auto-negotiation is done.
-        */
-       XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
-       XM_IN16(IoC, Port, XM_ISRC, &Isrc);
-       IsrcSum |= Isrc;
-
-       SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
-
-       if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) {
-               if ((GpReg & XM_GP_INP_ASS) == 0) {
-                       /* Save Auto-negotiation Done interrupt only if link is in sync */
-                       pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
-               }
-#ifdef DEBUG
-               if ((pPrt->PIsave & XM_IS_AND) != 0) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                               ("AutoNeg done rescheduled Port %d\n", Port));
-               }
-#endif /* DEBUG */
-               return(SK_HW_PS_NONE);
-       }
-
-       if (AutoNeg) {
-               if ((IsrcSum & XM_IS_AND) != 0) {
-                       SkHWLinkUp(pAC, IoC, Port);
-                       Done = SkMacAutoNegDone(pAC, IoC, Port);
-                       if (Done != SK_AND_OK) {
-                               /* Get PHY parameters, for debugging only */
-                               SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb);
-                               SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                                       ("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n",
-                                        Port, LpAb, ResAb));
-
-                               /* Try next possible mode */
-                               NextMode = SkHWSenseGetNext(pAC, IoC, Port);
-                               SkHWLinkDown(pAC, IoC, Port);
-                               if (Done == SK_AND_DUP_CAP) {
-                                       /* GoTo next mode */
-                                       SkHWSenseSetNext(pAC, IoC, Port, NextMode);
-                               }
-
-                               return(SK_HW_PS_RESTART);
-                       }
-                       /*
-                        * Dummy Read extended status to prevent extra link down/ups
-                        * (clear Page Received bit if set)
-                        */
-                       SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat);
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                               ("AutoNeg done Port %d\n", Port));
-                       return(SK_HW_PS_LINK);
-               }
-
-               /* AutoNeg not done, but HW link is up. Check for timeouts */
-               pPrt->PAutoNegTimeOut++;
-               if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
-                       /* Increase the Timeout counter */
-                       pPrt->PAutoNegTOCt++;
-
-                       /* Timeout occured */
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                               ("AutoNeg timeout Port %d\n", Port));
-                       if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
-                               pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
-                               /* Set Link manually up */
-                               SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                                       ("Set manual full duplex Port %d\n", Port));
-                       }
-
-                       if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
-                               pPrt->PLipaAutoNeg == SK_LIPA_AUTO &&
-                               pPrt->PAutoNegTOCt >= SK_MAX_ANEG_TO) {
-                               /*
-                                * This is rather complicated.
-                                * we need to check here whether the LIPA_AUTO
-                                * we saw before is false alert. We saw at one
-                                * switch ( SR8800) that on boot time it sends
-                                * just one auto-neg packet and does no further
-                                * auto-negotiation.
-                                * Solution: we restart the autosensing after
-                                * a few timeouts.
-                                */
-                               pPrt->PAutoNegTOCt = 0;
-                               pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
-                               SkHWInitDefSense(pAC, IoC, Port);
-                       }
-
-                       /* Do the restart */
-                       return(SK_HW_PS_RESTART);
-               }
-       }
-       else {
-               /* Link is up and we don't need more */
-#ifdef DEBUG
-               if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                               ("ERROR: Lipa auto detected on port %d\n", Port));
-               }
-#endif /* DEBUG */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                       ("Link sync(GP), Port %d\n", Port));
-               SkHWLinkUp(pAC, IoC, Port);
-
-               /*
-                * Link sync (GP) and so assume a good connection. But if not received
-                * a bunch of frames received in a time slot (maybe broken tx cable)
-                * the port is restart.
-                */
-               return(SK_HW_PS_LINK);
-       }
-
-       return(SK_HW_PS_NONE);
-}      /* SkGePortCheckUpXmac */
-
-
-/******************************************************************************
- *
- * SkGePortCheckUpBcom() - Check if the link is up on Bcom PHY
- *
- * return:
- *     0       o.k. nothing needed
- *     1       Restart needed on this port
- *     2       Link came up
- */
-static int SkGePortCheckUpBcom(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC,    /* IO Context */
-int            Port)   /* Which port should be checked */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       int                     Done;
-       SK_U16          Isrc;           /* Interrupt source register */
-       SK_U16          PhyStat;        /* Phy Status Register */
-       SK_U16          ResAb;          /* Master/Slave resolution */
-       SK_U16          Ctrl;           /* Broadcom control flags */
-#ifdef DEBUG
-       SK_U16          LpAb;
-       SK_U16          ExtStat;
-#endif /* DEBUG */
-       SK_BOOL         AutoNeg;        /* Is Auto-negotiation used ? */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Check for No HCD Link events (#10523) */
-       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc);
-
-#ifdef xDEBUG
-       if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT) ==
-               (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) {
-
-               SK_U32  Stat1, Stat2, Stat3;
-
-               Stat1 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "CheckUp1 - Stat: %x, Mask: %x",
-                       (void *)Isrc,
-                       (void *)Stat1);
-
-               Stat1 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2);
-               Stat1 = Stat1 << 16 | Stat2;
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
-               Stat3 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
-               Stat2 = Stat2 << 16 | Stat3;
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "Ctrl/Stat: %x, AN Adv/LP: %x",
-                       (void *)Stat1,
-                       (void *)Stat2);
-
-               Stat1 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
-               Stat1 = Stat1 << 16 | Stat2;
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
-               Stat3 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3);
-               Stat2 = Stat2 << 16 | Stat3;
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
-                       (void *)Stat1,
-                       (void *)Stat2);
-
-               Stat1 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
-               Stat1 = Stat1 << 16 | Stat2;
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
-               Stat3 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
-               Stat2 = Stat2 << 16 | Stat3;
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
-                       (void *)Stat1,
-                       (void *)Stat2);
-       }
-#endif /* DEBUG */
-
-       if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) {
-               /*
-                * Workaround BCom Errata:
-                *      enable and disable loopback mode if "NO HCD" occurs.
-                */
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Ctrl);
-               SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
-                       (SK_U16)(Ctrl | PHY_CT_LOOP));
-               SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
-                       (SK_U16)(Ctrl & ~PHY_CT_LOOP));
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("No HCD Link event, Port %d\n", Port));
-#ifdef xDEBUG
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "No HCD link event, port %d.",
-                       (void *)Port,
-                       (void *)NULL);
-#endif /* DEBUG */
-       }
-
-       /* Not obsolete: link status bit is latched to 0 and autoclearing! */
-       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
-
-       if (pPrt->PHWLinkUp) {
-               return(SK_HW_PS_NONE);
-       }
-
-#ifdef xDEBUG
-       {
-               SK_U32  Stat1, Stat2, Stat3;
-
-               Stat1 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "CheckUp1a - Stat: %x, Mask: %x",
-                       (void *)Isrc,
-                       (void *)Stat1);
-
-               Stat1 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
-               Stat1 = Stat1 << 16 | PhyStat;
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
-               Stat3 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
-               Stat2 = Stat2 << 16 | Stat3;
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "Ctrl/Stat: %x, AN Adv/LP: %x",
-                       (void *)Stat1,
-                       (void *)Stat2);
-
-               Stat1 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
-               Stat1 = Stat1 << 16 | Stat2;
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
-               Stat3 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
-               Stat2 = Stat2 << 16 | ResAb;
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
-                       (void *)Stat1,
-                       (void *)Stat2);
-
-               Stat1 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
-               Stat1 = Stat1 << 16 | Stat2;
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
-               Stat3 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
-               Stat2 = Stat2 << 16 | Stat3;
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
-                       (void *)Stat1,
-                       (void *)Stat2);
-       }
-#endif /* DEBUG */
-
-       /* Now wait for each port's link */
-       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
-               AutoNeg = SK_FALSE;
-       }
-       else {
-               AutoNeg = SK_TRUE;
-       }
-
-       /*
-        * Here we usually can check whether the link is in sync and
-        * auto-negotiation is done.
-        */
-
-       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
-
-       SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat));
-
-       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
-
-       if ((ResAb & PHY_B_1000S_MSF) != 0) {
-               /* Error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("Master/Slave Fault port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               pPrt->PMSStatus = SK_MS_STAT_FAULT;
-
-               return(SK_HW_PS_RESTART);
-       }
-
-       if ((PhyStat & PHY_ST_LSYNC) == 0) {
-               return(SK_HW_PS_NONE);
-       }
-
-       pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
-               SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat));
-
-       if (AutoNeg) {
-               if ((PhyStat & PHY_ST_AN_OVER) != 0) {
-                       SkHWLinkUp(pAC, IoC, Port);
-                       Done = SkMacAutoNegDone(pAC, IoC, Port);
-                       if (Done != SK_AND_OK) {
-#ifdef DEBUG
-                               /* Get PHY parameters, for debugging only */
-                               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb);
-                               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ExtStat);
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                                       ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
-                                       Port, LpAb, ExtStat));
-#endif /* DEBUG */
-                               return(SK_HW_PS_RESTART);
-                       }
-                       else {
-#ifdef xDEBUG
-                               /* Dummy read ISR to prevent extra link downs/ups */
-                               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
-
-                               if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
-                                       CMSMPrintString(
-                                               pAC->pConfigTable,
-                                               MSG_TYPE_RUNTIME_INFO,
-                                               "CheckUp2 - Stat: %x",
-                                               (void *)ExtStat,
-                                               (void *)NULL);
-                               }
-#endif /* DEBUG */
-
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                                       ("AutoNeg done Port %d\n", Port));
-                               return(SK_HW_PS_LINK);
-                       }
-               }
-       }
-       else {  /* !AutoNeg */
-               /* Link is up and we don't need more. */
-#ifdef DEBUG
-               if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                               ("ERROR: Lipa auto detected on port %d\n", Port));
-               }
-#endif /* DEBUG */
-
-#ifdef xDEBUG
-               /* Dummy read ISR to prevent extra link downs/ups */
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
-
-               if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
-                       CMSMPrintString(
-                               pAC->pConfigTable,
-                               MSG_TYPE_RUNTIME_INFO,
-                               "CheckUp3 - Stat: %x",
-                               (void *)ExtStat,
-                               (void *)NULL);
-               }
-#endif /* DEBUG */
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                       ("Link sync(GP), Port %d\n", Port));
-               SkHWLinkUp(pAC, IoC, Port);
-               return(SK_HW_PS_LINK);
-       }
-
-       return(SK_HW_PS_NONE);
-}      /* SkGePortCheckUpBcom */
-
-
-/******************************************************************************
- *
- * SkGePortCheckUpGmac() - Check if the link is up on Marvell PHY
- *
- * return:
- *     0       o.k. nothing needed
- *     1       Restart needed on this port
- *     2       Link came up
- */
-static int SkGePortCheckUpGmac(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC,    /* IO Context */
-int            Port)   /* Which port should be checked */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       int                     Done;
-       SK_U16          Isrc;           /* Interrupt source */
-       SK_U16          PhyStat;        /* Phy Status */
-       SK_U16          PhySpecStat;/* Phy Specific Status */
-       SK_U16          ResAb;          /* Master/Slave resolution */
-       SK_BOOL         AutoNeg;        /* Is Auto-negotiation used ? */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Read PHY Interrupt Status */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &Isrc);
-
-       if ((Isrc & PHY_M_IS_AN_COMPL) != 0) {
-               /* TBD */
-       }
-
-       if ((Isrc & PHY_M_IS_DOWNSH_DET) != 0) {
-               /* TBD */
-       }
-
-       if (pPrt->PHWLinkUp) {
-               return(SK_HW_PS_NONE);
-       }
-
-       /* Now wait for each port's link */
-       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
-               AutoNeg = SK_FALSE;
-       }
-       else {
-               AutoNeg = SK_TRUE;
-       }
-
-       /* Read PHY Status */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("AutoNeg: %d, PhyStat: 0x%04x\n", AutoNeg, PhyStat));
-
-       SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
-
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
-
-       if ((ResAb & PHY_B_1000S_MSF) != 0) {
-               /* Error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("Master/Slave Fault port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               pPrt->PMSStatus = SK_MS_STAT_FAULT;
-
-               return(SK_HW_PS_RESTART);
-       }
-
-       /* Read PHY Specific Status */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("AutoNeg: %d, PhySpecStat: 0x%04x\n", AutoNeg, PhySpecStat));
-
-       if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) {
-               return(SK_HW_PS_NONE);
-       }
-
-       pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
-               SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
-
-       pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7);
-
-       if (AutoNeg) {
-               /* Auto-Negotiation Over ? */
-               if ((PhyStat & PHY_ST_AN_OVER) != 0) {
-
-                       SkHWLinkUp(pAC, IoC, Port);
-
-                       Done = SkMacAutoNegDone(pAC, IoC, Port);
-
-                       if (Done != SK_AND_OK) {
-                               return(SK_HW_PS_RESTART);
-                       }
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                               ("AutoNeg done Port %d\n", Port));
-                       return(SK_HW_PS_LINK);
-               }
-       }
-       else {  /* !AutoNeg */
-               /* Link is up and we don't need more */
-#ifdef DEBUG
-               if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                               ("ERROR: Lipa auto detected on port %d\n", Port));
-               }
-#endif /* DEBUG */
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                       ("Link sync, Port %d\n", Port));
-               SkHWLinkUp(pAC, IoC, Port);
-
-               return(SK_HW_PS_LINK);
-       }
-
-       return(SK_HW_PS_NONE);
-}      /* SkGePortCheckUpGmac */
-
-
-#ifdef OTHER_PHY
-/******************************************************************************
- *
- * SkGePortCheckUpLone() - Check if the link is up on Level One PHY
- *
- * return:
- *     0       o.k. nothing needed
- *     1       Restart needed on this port
- *     2       Link came up
- */
-static int SkGePortCheckUpLone(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO Context */
-int            Port)           /* Which port should be checked */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       int                     Done;
-       SK_U16          Isrc;           /* Interrupt source register */
-       SK_U16          LpAb;           /* Link Partner Ability */
-       SK_U16          ExtStat;        /* Extended Status Register */
-       SK_U16          PhyStat;        /* Phy Status Register */
-       SK_U16          StatSum;
-       SK_BOOL         AutoNeg;        /* Is Auto-negotiation used ? */
-       SK_U8           NextMode;       /* Next AutoSensing Mode */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PHWLinkUp) {
-               return(SK_HW_PS_NONE);
-       }
-
-       StatSum = pPrt->PIsave;
-       pPrt->PIsave = 0;
-
-       /* Now wait for each ports link */
-       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
-               AutoNeg = SK_FALSE;
-       }
-       else {
-               AutoNeg = SK_TRUE;
-       }
-
-       /*
-        * here we usually can check whether the link is in sync and
-        * auto-negotiation is done.
-        */
-       SkXmPhyRead(pAC, IoC, Port, PHY_LONE_STAT, &PhyStat);
-       StatSum |= PhyStat;
-
-       SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
-
-       if ((PhyStat & PHY_ST_LSYNC) == 0) {
-               /* Save Auto-negotiation Done bit */
-               pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER);
-#ifdef DEBUG
-               if ((pPrt->PIsave & PHY_ST_AN_OVER) != 0) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                               ("AutoNeg done rescheduled Port %d\n", Port));
-               }
-#endif /* DEBUG */
-               return(SK_HW_PS_NONE);
-       }
-
-       if (AutoNeg) {
-               if ((StatSum & PHY_ST_AN_OVER) != 0) {
-                       SkHWLinkUp(pAC, IoC, Port);
-                       Done = SkMacAutoNegDone(pAC, IoC, Port);
-                       if (Done != SK_AND_OK) {
-                               /* Get PHY parameters, for debugging only */
-                               SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb);
-                               SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ExtStat);
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                                       ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
-                                        Port, LpAb, ExtStat));
-
-                               /* Try next possible mode */
-                               NextMode = SkHWSenseGetNext(pAC, IoC, Port);
-                               SkHWLinkDown(pAC, IoC, Port);
-                               if (Done == SK_AND_DUP_CAP) {
-                                       /* GoTo next mode */
-                                       SkHWSenseSetNext(pAC, IoC, Port, NextMode);
-                               }
-
-                               return(SK_HW_PS_RESTART);
-
-                       }
-                       else {
-                               /*
-                                * Dummy Read interrupt status to prevent
-                                * extra link down/ups
-                                */
-                               SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                                       ("AutoNeg done Port %d\n", Port));
-                               return(SK_HW_PS_LINK);
-                       }
-               }
-
-               /* AutoNeg not done, but HW link is up. Check for timeouts */
-               pPrt->PAutoNegTimeOut++;
-               if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
-                       /* Timeout occured */
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                               ("AutoNeg timeout Port %d\n", Port));
-                       if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
-                               pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
-                               /* Set Link manually up */
-                               SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                                       ("Set manual full duplex Port %d\n", Port));
-                       }
-
-                       /* Do the restart */
-                       return(SK_HW_PS_RESTART);
-               }
-       }
-       else {
-               /* Link is up and we don't need more */
-#ifdef DEBUG
-               if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                               ("ERROR: Lipa auto detected on port %d\n", Port));
-               }
-#endif /* DEBUG */
-
-               /*
-                * Dummy Read interrupt status to prevent
-                * extra link down/ups
-                */
-               SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                       ("Link sync(GP), Port %d\n", Port));
-               SkHWLinkUp(pAC, IoC, Port);
-               return(SK_HW_PS_LINK);
-       }
-
-       return(SK_HW_PS_NONE);
-}      /* SkGePortCheckUpLone */
-
-
-/******************************************************************************
- *
- * SkGePortCheckUpNat() - Check if the link is up on National PHY
- *
- * return:
- *     0       o.k. nothing needed
- *     1       Restart needed on this port
- *     2       Link came up
- */
-static int SkGePortCheckUpNat(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO Context */
-int            Port)           /* Which port should be checked */
-{
-       /* todo: National */
-       return(SK_HW_PS_NONE);
-}      /* SkGePortCheckUpNat */
-#endif /* OTHER_PHY */
-
-
-/******************************************************************************
- *
- *     SkGeSirqEvent() - Event Service Routine
- *
- * Description:
- *
- * Notes:
- */
-int    SkGeSirqEvent(
-SK_AC          *pAC,           /* Adapter Context */
-SK_IOC         IoC,            /* Io Context */
-SK_U32         Event,          /* Module specific Event */
-SK_EVPARA      Para)           /* Event specific Parameter */
-{
-       SK_U64          Octets;
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       SK_U32          Port;
-       SK_U32          Time;
-       unsigned        Len;
-       int                     PortStat;
-       SK_U8           Val8;
-
-       Port = Para.Para32[0];
-       pPrt = &pAC->GIni.GP[Port];
-
-       switch (Event) {
-       case SK_HWEV_WATIM:
-               /* Check whether port came up */
-               PortStat = SkGePortCheckUp(pAC, IoC, Port);
-
-               switch (PortStat) {
-               case SK_HW_PS_RESTART:
-                       if (pPrt->PHWLinkUp) {
-                               /*
-                                * Set Link to down.
-                                */
-                               SkHWLinkDown(pAC, IoC, Port);
-
-                               /*
-                                * Signal directly to RLMT to ensure correct
-                                * sequence of SWITCH and RESET event.
-                                */
-                               SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
-                       }
-
-                       /* Restart needed */
-                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
-                       break;
-
-               case SK_HW_PS_LINK:
-                       /* Signal to RLMT */
-                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para);
-                       break;
-
-               }
-
-               /* Start again the check Timer */
-               if (pPrt->PHWLinkUp) {
-                       Time = SK_WA_ACT_TIME;
-               }
-               else {
-                       Time = SK_WA_INA_TIME;
-               }
-
-               /* Todo: still needed for non-XMAC PHYs??? */
-               /* Start workaround Errata #2 timer */
-               SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Time,
-                       SKGE_HWAC, SK_HWEV_WATIM, Para);
-               break;
-
-       case SK_HWEV_PORT_START:
-               if (pPrt->PHWLinkUp) {
-                       /*
-                        * Signal directly to RLMT to ensure correct
-                        * sequence of SWITCH and RESET event.
-                        */
-                       SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
-               }
-
-               SkHWLinkDown(pAC, IoC, Port);
-
-               /* Schedule Port RESET */
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
-
-               /* Start workaround Errata #2 timer */
-               SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
-                       SKGE_HWAC, SK_HWEV_WATIM, Para);
-               break;
-
-       case SK_HWEV_PORT_STOP:
-               if (pPrt->PHWLinkUp) {
-                       /*
-                        * Signal directly to RLMT to ensure correct
-                        * sequence of SWITCH and RESET event.
-                        */
-                       SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
-               }
-
-               /* Stop Workaround Timer */
-               SkTimerStop(pAC, IoC, &pPrt->PWaTimer);
-
-               SkHWLinkDown(pAC, IoC, Port);
-               break;
-
-       case SK_HWEV_UPDATE_STAT:
-               /* We do NOT need to update any statistics */
-               break;
-
-       case SK_HWEV_CLEAR_STAT:
-               /* We do NOT need to clear any statistics */
-               for (Port = 0; Port < (SK_U32)pAC->GIni.GIMacsFound; Port++) {
-                       pPrt->PPrevRx = 0;
-                       pPrt->PPrevFcs = 0;
-                       pPrt->PPrevShorts = 0;
-               }
-               break;
-
-       case SK_HWEV_SET_LMODE:
-               Val8 = (SK_U8)Para.Para32[1];
-               if (pPrt->PLinkModeConf != Val8) {
-                       /* Set New link mode */
-                       pPrt->PLinkModeConf = Val8;
-
-                       /* Restart Port */
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
-               }
-               break;
-
-       case SK_HWEV_SET_FLOWMODE:
-               Val8 = (SK_U8)Para.Para32[1];
-               if (pPrt->PFlowCtrlMode != Val8) {
-                       /* Set New Flow Control mode */
-                       pPrt->PFlowCtrlMode = Val8;
-
-                       /* Restart Port */
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
-               }
-               break;
-
-       case SK_HWEV_SET_ROLE:
-               /* not possible for fiber */
-               if (!pAC->GIni.GICopperType) {
-                       break;
-               }
-               Val8 = (SK_U8)Para.Para32[1];
-               if (pPrt->PMSMode != Val8) {
-                       /* Set New link mode */
-                       pPrt->PMSMode = Val8;
-
-                       /* Restart Port */
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
-               }
-               break;
-
-       case SK_HWEV_SET_SPEED:
-               if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
-                       break;
-               }
-               Val8 = (SK_U8)Para.Para32[1];
-               if (pPrt->PLinkSpeed != Val8) {
-                       /* Set New Speed parameter */
-                       pPrt->PLinkSpeed = Val8;
-
-                       /* Restart Port */
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
-               }
-               break;
-
-       case SK_HWEV_HALFDUP_CHK:
-               /*
-                * half duplex hangup workaround.
-                * See packet arbiter timeout interrupt for description
-                */
-               pPrt->HalfDupTimerActive = SK_FALSE;
-               if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
-                   pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) {
-
-                       Len = sizeof(SK_U64);
-                       SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
-                               &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port),
-                               pAC->Rlmt.Port[Port].Net->NetNumber);
-
-                       if (pPrt->LastOctets == Octets) {
-                               /* Tx hanging, a FIFO flush restarts it */
-                               SkMacFlushTxFifo(pAC, IoC, Port);
-                       }
-               }
-               break;
-
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG);
-               break;
-       }
-
-       return(0);
-}      /* SkGeSirqEvent */
-
-
-/******************************************************************************
- *
- *     SkPhyIsrBcom() - PHY interrupt service routine
- *
- * Description: handles all interrupts from BCom PHY
- *
- * Returns: N/A
- */
-static void SkPhyIsrBcom(
-SK_AC          *pAC,           /* Adapter Context */
-SK_IOC         IoC,            /* Io Context */
-int                    Port,           /* Port Num = PHY Num */
-SK_U16         IStatus)        /* Interrupt Status */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       SK_EVPARA       Para;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if ((IStatus & PHY_B_IS_PSE) != 0) {
-               /* Incorrectable pair swap error */
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E022,
-                       SKERR_SIRQ_E022MSG);
-       }
-
-       if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) {
-               Para.Para32[0] = (SK_U32)Port;
-
-               SkHWLinkDown(pAC, IoC, Port);
-
-               /* Signal to RLMT */
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-
-               /* Start workaround Errata #2 timer */
-               SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
-                       SKGE_HWAC, SK_HWEV_WATIM, Para);
-       }
-
-}      /* SkPhyIsrBcom */
-
-
-/******************************************************************************
- *
- *     SkPhyIsrGmac() - PHY interrupt service routine
- *
- * Description: handles all interrupts from Marvell PHY
- *
- * Returns: N/A
- */
-static void SkPhyIsrGmac(
-SK_AC          *pAC,           /* Adapter Context */
-SK_IOC         IoC,            /* Io Context */
-int                    Port,           /* Port Num = PHY Num */
-SK_U16         IStatus)        /* Interrupt Status */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       SK_EVPARA       Para;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) {
-               Para.Para32[0] = (SK_U32)Port;
-
-               SkHWLinkDown(pAC, IoC, Port);
-
-               /* Signal to RLMT */
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-
-       if ((IStatus & PHY_M_IS_AN_ERROR) != 0) {
-               /* Auto-Negotiation Error */
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG);
-       }
-
-       if ((IStatus & PHY_M_IS_LSP_CHANGE) != 0) {
-               /* TBD */
-       }
-
-       if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) {
-               /* FIFO Overflow/Underrun Error */
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG);
-       }
-}      /* SkPhyIsrGmac */
-
-
-#ifdef OTHER_PHY
-/******************************************************************************
- *
- *     SkPhyIsrLone() - PHY interrupt service routine
- *
- * Description: handles all interrupts from LONE PHY
- *
- * Returns: N/A
- */
-static void SkPhyIsrLone(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* Io Context */
-int            Port,           /* Port Num = PHY Num */
-SK_U16 IStatus)        /* Interrupt Status */
-{
-       SK_EVPARA       Para;
-
-       if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) {
-               SkHWLinkDown(pAC, IoC, Port);
-
-               /* Signal to RLMT */
-               Para.Para32[0] = (SK_U32)Port;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-
-}      /* SkPhyIsrLone */
-#endif /* OTHER_PHY */
-
-#endif /* CONFIG_SK98 */
-
-/* End of File */
diff --git a/drivers/sk98lin/ski2c.c b/drivers/sk98lin/ski2c.c
deleted file mode 100644 (file)
index 2ab635a..0000000
+++ /dev/null
@@ -1,1505 +0,0 @@
-/******************************************************************************
- *
- * Name:       ski2c.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.57 $
- * Date:       $Date: 2003/01/28 09:17:38 $
- * Purpose:    Functions to access Voltage and Temperature Sensor
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: ski2c.c,v $
- *     Revision 1.57  2003/01/28 09:17:38  rschmidt
- *     Fixed handling for sensors on YUKON Fiber.
- *     Editorial changes.
- *
- *     Revision 1.56  2002/12/19 14:20:41  rschmidt
- *     Added debugging code in SkI2cWait().
- *     Replaced all I2C-write operations with function SkI2cWrite().
- *     Fixed compiler warning because of uninitialized 'Time' in SkI2cEvent().
- *     Editorial changes.
- *
- *     Revision 1.55  2002/10/15 07:23:55  rschmidt
- *     Added setting of the GIYukon32Bit bool variable to distinguish
- *     32-bit adapters.
- *     Editorial changes (TWSI).
- *
- *     Revision 1.54  2002/08/13 09:05:06  rschmidt
- *     Added new thresholds if VAUX is not available (GIVauxAvail).
- *     Merged defines for PHY PLL 3V3 voltage (A and B).
- *     Editorial changes.
- *
- *     Revision 1.53  2002/08/08 11:04:53  rwahl
- *     Added missing comment for revision 1.51
- *
- *     Revision 1.52  2002/08/08 10:09:02  jschmalz
- *     Sensor init state caused wrong error log entry
- *
- *     Revision 1.51  2002/08/06 09:43:03  jschmalz
- *     Extensions and changes for Yukon
- *
- *     Revision 1.50  2002/08/02 12:09:22  rschmidt
- *     Added support for YUKON sensors.
- *     Editorial changes.
- *
- *     Revision 1.49  2002/07/30 11:07:52  rschmidt
- *     Replaced MaxSens init by update for Copper in SkI2cInit1(),
- *     because it was already initialized in SkI2cInit0().
- *     Editorial changes.
- *
- *     Revision 1.48  2001/08/16 12:44:33  afischer
- *     LM80 sensor init values corrected
- *
- *     Revision 1.47  2001/04/05 11:38:09  rassmann
- *     Set SenState to idle in SkI2cWaitIrq().
- *     Changed error message in SkI2cWaitIrq().
- *
- *     Revision 1.46  2001/04/02 14:03:35  rassmann
- *     Changed pAC to IoC in SK_IN32().
- *
- *     Revision 1.45  2001/03/21 12:12:49  rassmann
- *     Resetting I2C_READY interrupt in SkI2cInit1().
- *
- *     Revision 1.44  2000/08/07 15:49:03  gklug
- *     Fix: SK_INFAST only in NetWare driver.
- *
- *     Revision 1.43  2000/08/03 14:28:17  rassmann
- *     Added function to wait for I2C being ready before resetting the board.
- *     Replaced one duplicate "out of range" message with correct one.
- *
- *     Revision 1.42  1999/11/22 13:35:12  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.41  1999/09/14 14:11:30  malthoff
- *     The 1000BT Dual Link adapter has got only one Fan.
- *     The second Fan has been removed.
- *
- *     Revision 1.40  1999/05/27 13:37:27  malthoff
- *     Set divisor of 1 for fan count calculation.
- *
- *     Revision 1.39  1999/05/20 14:54:43  malthoff
- *     I2c.DummyReads is not used in Diagnostics.
- *
- *     Revision 1.38  1999/05/20 09:20:56  cgoos
- *     Changes for 1000Base-T (up to 9 sensors and fans).
- *
- *     Revision 1.37  1999/03/25 15:11:36  gklug
- *     fix: reset error flag if sensor reads correct value
- *
- *     Revision 1.36  1999/01/07 14:11:16  gklug
- *     fix: break added
- *
- *     Revision 1.35  1999/01/05 15:31:49  gklug
- *     fix: CLEAR STAT command is now added correctly
- *
- *     Revision 1.34  1998/12/01 13:45:16  gklug
- *     fix: introduced Init level, because we don't need reinits
- *
- *     Revision 1.33  1998/11/09 14:54:25  malthoff
- *     Modify I2C Transfer Timeout handling for Diagnostics.
- *
- *     Revision 1.32  1998/11/03 06:54:35  gklug
- *     fix: Need dummy reads at the beginning to init sensors
- *
- *     Revision 1.31  1998/11/03 06:42:42  gklug
- *     fix: select correctVIO range only if between warning levels
- *
- *     Revision 1.30  1998/11/02 07:36:53  gklug
- *     fix: Error should not include WARNING message
- *
- *     Revision 1.29  1998/10/30 15:07:43  malthoff
- *     Disable 'I2C does not compelete' error log for diagnostics.
- *
- *     Revision 1.28  1998/10/22 09:48:11  gklug
- *     fix: SysKonnectFileId typo
- *
- *     Revision 1.27  1998/10/20 09:59:46  gklug
- *     add: parameter to SkOsGetTime
- *
- *     Revision 1.26  1998/10/09 06:10:59  malthoff
- *     Remove ID_sccs by SysKonnectFileId.
- *
- *     Revision 1.25  1998/09/08 12:40:26  gklug
- *     fix: syntax error in if clause
- *
- *     Revision 1.24  1998/09/08 12:19:42  gklug
- *     chg: INIT Level checking
- *
- *     Revision 1.23  1998/09/08 07:37:20  gklug
- *     fix: log error if PCI_IO voltage sensor could not be initialized
- *
- *     Revision 1.22  1998/09/04 08:30:03  malthoff
- *     Bugfixes during SK_DIAG testing:
- *     - correct NS2BCLK() macro
- *     - correct SkI2cSndDev()
- *     - correct SkI2cWait() loop waiting for an event
- *
- *     Revision 1.21  1998/08/27 14:46:01  gklug
- *     chg: if-then-else replaced by switch
- *
- *     Revision 1.20  1998/08/27 14:40:07  gklug
- *     test: integral types
- *
- *     Revision 1.19  1998/08/25 07:51:54  gklug
- *     fix: typos for compiling
- *
- *     Revision 1.18  1998/08/25 06:12:24  gklug
- *     add: count errors and warnings
- *     fix: check not the sensor state but the ErrFlag!
- *
- *     Revision 1.17  1998/08/25 05:56:48  gklug
- *     add: CheckSensor function
- *
- *     Revision 1.16  1998/08/20 11:41:10  gklug
- *     chg: omit STRCPY macro by using char * as Sensor Description
- *
- *     Revision 1.15  1998/08/20 11:37:35  gklug
- *     chg: change Ioc to IoC
- *
- *     Revision 1.14  1998/08/20 11:32:52  gklug
- *     fix: Para compile error
- *
- *     Revision 1.13  1998/08/20 11:27:41  gklug
- *     fix: Compile bugs with new awrning constants
- *
- *     Revision 1.12  1998/08/20 08:53:05  gklug
- *     fix: compiler errors
- *     add: Threshold values
- *
- *     Revision 1.11  1998/08/19 12:39:22  malthoff
- *     Compiler Fix: Some names have changed.
- *
- *     Revision 1.10  1998/08/19 12:20:56  gklug
- *     fix: remove struct from C files (see CCC)
- *
- *     Revision 1.9  1998/08/19 06:28:46  malthoff
- *     SkOsGetTime returns SK_U64 now.
- *
- *     Revision 1.8  1998/08/17 13:53:33  gklug
- *     fix: Parameter of event function and its result
- *
- *     Revision 1.7  1998/08/17 07:02:15  malthoff
- *     Modify the functions for accessing the I2C SW Registers.
- *     Modify SkI2cWait().
- *     Put Lm80RcvReg into sklm80.c
- *     Remove Compiler Errors.
- *
- *     Revision 1.6  1998/08/14 07:13:20  malthoff
- *     remove pAc with pAC
- *     remove smc with pAC
- *     change names to new convention
- *
- *     Revision 1.5  1998/08/14 06:24:49  gklug
- *     add: init level 1 and 2
- *
- *     Revision 1.4  1998/08/12 14:31:12  gklug
- *     add: error log for unknown event
- *
- *     Revision 1.3  1998/08/12 13:37:04  gklug
- *     add: Init 0 function
- *
- *     Revision 1.2  1998/08/11 07:27:15  gklug
- *     add: functions of the interface
- *     adapt rest of source to C coding Conventions
- *     rmv: unnecessary code taken from Mona Lisa
- *
- *     Revision 1.1  1998/06/19 14:28:43  malthoff
- *     Created. Sources taken from ML Projekt.
- *     Sources have to be reworked for GE.
- *
- *
- ******************************************************************************/
-
-
-#include <config.h>
-
-#ifdef CONFIG_SK98
-
-/*
- *     I2C Protocol
- */
-static const char SysKonnectFileId[] =
-       "$Id: ski2c.c,v 1.57 2003/01/28 09:17:38 rschmidt Exp $";
-
-#include "h/skdrv1st.h"                /* Driver Specific Definitions */
-#include "h/lm80.h"
-#include "h/skdrv2nd.h"                /* Adapter Control- and Driver specific Def. */
-
-#ifdef __C2MAN__
-/*
-       I2C protocol implementation.
-
-       General Description:
-
-       The I2C protocol is used for the temperature sensors and for
-       the serial EEPROM which hold the configuration.
-
-       This file covers functions that allow to read write and do
-       some bulk requests a specified I2C address.
-
-       The Genesis has 2 I2C buses. One for the EEPROM which holds
-       the VPD Data and one for temperature and voltage sensor.
-       The following picture shows the I2C buses, I2C devices and
-       their control registers.
-
-       Note: The VPD functions are in skvpd.c
-.
-.      PCI Config I2C Bus for VPD Data:
-.
-.                    +------------+
-.                    | VPD EEPROM |
-.                    +------------+
-.                           |
-.                           | <-- I2C
-.                           |
-.               +-----------+-----------+
-.               |                       |
-.      +-----------------+     +-----------------+
-.      | PCI_VPD_ADR_REG |     | PCI_VPD_DAT_REG |
-.      +-----------------+     +-----------------+
-.
-.
-.      I2C Bus for LM80 sensor:
-.
-.                      +-----------------+
-.                      | Temperature and |
-.                      | Voltage Sensor  |
-.                      |       LM80      |
-.                      +-----------------+
-.                              |
-.                              |
-.                      I2C --> |
-.                              |
-.                           +----+
-.           +-------------->| OR |<--+
-.           |               +----+   |
-.     +------+------+                |
-.     |                    |                 |
-. +--------+   +--------+      +----------+
-. | B2_I2C |   | B2_I2C |      |  B2_I2C  |
-. | _CTRL  |   | _DATA  |      |   _SW    |
-. +--------+   +--------+      +----------+
-.
-       The I2C bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL
-       and B2_I2C_DATA registers.
-       For driver software it is recommended to use the I2C control and
-       data register, because I2C bus timing is done by the ASIC and
-       an interrupt may be received when the I2C request is completed.
-
-       Clock Rate Timing:                      MIN     MAX     generated by
-               VPD EEPROM:                     50 kHz  100 kHz         HW
-               LM80 over I2C Ctrl/Data reg.    50 kHz  100 kHz         HW
-               LM80 over B2_I2C_SW register    0       400 kHz         SW
-
-       Note:   The clock generated by the hardware is dependend on the
-               PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD
-               clock is 50 kHz.
- */
-intro()
-{}
-#endif
-
-#ifdef SK_DIAG
-/*
- * I2C Fast Mode timing values used by the LM80.
- * If new devices are added to the I2C bus the timing values have to be checked.
- */
-#ifndef I2C_SLOW_TIMING
-#define        T_CLK_LOW                       1300L   /* clock low time in ns */
-#define        T_CLK_HIGH                       600L   /* clock high time in ns */
-#define T_DATA_IN_SETUP                 100L   /* data in Set-up Time */
-#define T_START_HOLD            600L   /* start condition hold time */
-#define T_START_SETUP           600L   /* start condition Set-up time */
-#define        T_STOP_SETUP             600L   /* stop condition Set-up time */
-#define T_BUS_IDLE                     1300L   /* time the bus must free after Tx */
-#define        T_CLK_2_DATA_OUT         900L   /* max. clock low to data output valid */
-#else  /* I2C_SLOW_TIMING */
-/* I2C Standard Mode Timing */
-#define        T_CLK_LOW                       4700L   /* clock low time in ns */
-#define        T_CLK_HIGH                      4000L   /* clock high time in ns */
-#define T_DATA_IN_SETUP                 250L   /* data in Set-up Time */
-#define T_START_HOLD           4000L   /* start condition hold time */
-#define T_START_SETUP          4700L   /* start condition Set-up time */
-#define        T_STOP_SETUP            4000L   /* stop condition Set-up time */
-#define T_BUS_IDLE                     4700L   /* time the bus must free after Tx */
-#endif /* !I2C_SLOW_TIMING */
-
-#define NS2BCLK(x)     (((x)*125)/10000)
-
-/*
- * I2C Wire Operations
- *
- * About I2C_CLK_LOW():
- *
- * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting
- * clock to low, to prevent the ASIC and the I2C data client from driving the
- * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client
- * send an 'ACK'). See also Concentrator Bugreport No. 10192.
- */
-#define I2C_DATA_HIGH(IoC)     SK_I2C_SET_BIT(IoC, I2C_DATA)
-#define        I2C_DATA_LOW(IoC)       SK_I2C_CLR_BIT(IoC, I2C_DATA)
-#define        I2C_DATA_OUT(IoC)       SK_I2C_SET_BIT(IoC, I2C_DATA_DIR)
-#define        I2C_DATA_IN(IoC)        SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA)
-#define        I2C_CLK_HIGH(IoC)       SK_I2C_SET_BIT(IoC, I2C_CLK)
-#define        I2C_CLK_LOW(IoC)        SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR)
-#define        I2C_START_COND(IoC)     SK_I2C_CLR_BIT(IoC, I2C_CLK)
-
-#define NS2CLKT(x)     ((x*125L)/10000)
-
-/*--------------- I2C Interface Register Functions --------------- */
-
-/*
- * sending one bit
- */
-void SkI2cSndBit(
-SK_IOC IoC,    /* I/O Context */
-SK_U8  Bit)    /* Bit to send */
-{
-       I2C_DATA_OUT(IoC);
-       if (Bit) {
-               I2C_DATA_HIGH(IoC);
-       }
-       else {
-               I2C_DATA_LOW(IoC);
-       }
-       SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
-       I2C_CLK_HIGH(IoC);
-       SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
-       I2C_CLK_LOW(IoC);
-}      /* SkI2cSndBit*/
-
-
-/*
- * Signal a start to the I2C Bus.
- *
- * A start is signaled when data goes to low in a high clock cycle.
- *
- * Ends with Clock Low.
- *
- * Status: not tested
- */
-void SkI2cStart(
-SK_IOC IoC)    /* I/O Context */
-{
-       /* Init data and Clock to output lines */
-       /* Set Data high */
-       I2C_DATA_OUT(IoC);
-       I2C_DATA_HIGH(IoC);
-       /* Set Clock high */
-       I2C_CLK_HIGH(IoC);
-
-       SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
-
-       /* Set Data Low */
-       I2C_DATA_LOW(IoC);
-
-       SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
-
-       /* Clock low without Data to Input */
-       I2C_START_COND(IoC);
-
-       SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
-}      /* SkI2cStart */
-
-
-void SkI2cStop(
-SK_IOC IoC)    /* I/O Context */
-{
-       /* Init data and Clock to output lines */
-       /* Set Data low */
-       I2C_DATA_OUT(IoC);
-       I2C_DATA_LOW(IoC);
-
-       SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
-
-       /* Set Clock high */
-       I2C_CLK_HIGH(IoC);
-
-       SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
-
-       /*
-        * Set Data High:       Do it by setting the Data Line to Input.
-        *                      Because of a pull up resistor the Data Line
-        *                      floods to high.
-        */
-       I2C_DATA_IN(IoC);
-
-       /*
-        *      When I2C activity is stopped
-        *       o      DATA should be set to input and
-        *       o      CLOCK should be set to high!
-        */
-       SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
-}      /* SkI2cStop */
-
-
-/*
- * Receive just one bit via the I2C bus.
- *
- * Note:       Clock must be set to LOW before calling this function.
- *
- * Returns The received bit.
- */
-int SkI2cRcvBit(
-SK_IOC IoC)    /* I/O Context */
-{
-       int     Bit;
-       SK_U8   I2cSwCtrl;
-
-       /* Init data as input line */
-       I2C_DATA_IN(IoC);
-
-       SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
-
-       I2C_CLK_HIGH(IoC);
-
-       SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
-
-       SK_I2C_GET_SW(IoC, &I2cSwCtrl);
-
-       Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
-
-       I2C_CLK_LOW(IoC);
-       SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
-
-       return(Bit);
-}      /* SkI2cRcvBit */
-
-
-/*
- * Receive an ACK.
- *
- * returns     0 If acknowledged
- *             1 in case of an error
- */
-int SkI2cRcvAck(
-SK_IOC IoC)    /* I/O Context */
-{
-       /*
-        * Received bit must be zero.
-        */
-       return(SkI2cRcvBit(IoC) != 0);
-}      /* SkI2cRcvAck */
-
-
-/*
- * Send an NACK.
- */
-void SkI2cSndNAck(
-SK_IOC IoC)    /* I/O Context */
-{
-       /*
-        * Received bit must be zero.
-        */
-       SkI2cSndBit(IoC, 1);
-}      /* SkI2cSndNAck */
-
-
-/*
- * Send an ACK.
- */
-void SkI2cSndAck(
-SK_IOC IoC)    /* I/O Context */
-{
-       /*
-        * Received bit must be zero.
-        *
-        */
-       SkI2cSndBit(IoC, 0);
-}      /* SkI2cSndAck */
-
-
-/*
- * Send one byte to the I2C device and wait for ACK.
- *
- * Return acknowleged status.
- */
-int SkI2cSndByte(
-SK_IOC IoC,    /* I/O Context */
-int            Byte)   /* byte to send */
-{
-       int     i;
-
-       for (i = 0; i < 8; i++) {
-               if (Byte & (1<<(7-i))) {
-                       SkI2cSndBit(IoC, 1);
-               }
-               else {
-                       SkI2cSndBit(IoC, 0);
-               }
-       }
-
-       return(SkI2cRcvAck(IoC));
-}      /* SkI2cSndByte */
-
-
-/*
- * Receive one byte and ack it.
- *
- * Return byte.
- */
-int SkI2cRcvByte(
-SK_IOC IoC,    /* I/O Context */
-int            Last)   /* Last Byte Flag */
-{
-       int     i;
-       int     Byte = 0;
-
-       for (i = 0; i < 8; i++) {
-               Byte <<= 1;
-               Byte |= SkI2cRcvBit(IoC);
-       }
-
-       if (Last) {
-               SkI2cSndNAck(IoC);
-       }
-       else {
-               SkI2cSndAck(IoC);
-       }
-
-       return(Byte);
-}      /* SkI2cRcvByte */
-
-
-/*
- * Start dialog and send device address
- *
- * Return 0 if acknowleged, 1 in case of an error
- */
-int    SkI2cSndDev(
-SK_IOC IoC,    /* I/O Context */
-int            Addr,   /* Device Address */
-int            Rw)             /* Read / Write Flag */
-{
-       SkI2cStart(IoC);
-       Rw = ~Rw;
-       Rw &= I2C_WRITE;
-       return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
-}      /* SkI2cSndDev */
-
-#endif /* SK_DIAG */
-
-/*----------------- I2C CTRL Register Functions ----------*/
-
-/*
- * waits for a completion of an I2C transfer
- *
- * returns     0:      success, transfer completes
- *                     1:      error,   transfer does not complete, I2C transfer
- *                                              killed, wait loop terminated.
- */
-int    SkI2cWait(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC,    /* I/O Context */
-int            Event)  /* complete event to wait for (I2C_READ or I2C_WRITE) */
-{
-       SK_U64  StartTime;
-       SK_U64  CurrentTime;
-       SK_U32  I2cCtrl;
-
-       StartTime = SkOsGetTime(pAC);
-
-       do {
-               CurrentTime = SkOsGetTime(pAC);
-
-               if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
-
-                       SK_I2C_STOP(IoC);
-#ifndef SK_DIAG
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
-#endif /* !SK_DIAG */
-                       return(1);
-               }
-
-               SK_I2C_GET_CTL(IoC, &I2cCtrl);
-
-#ifdef xYUKON_DBG
-               printf("StartTime=%lu, CurrentTime=%lu\n",
-                       StartTime, CurrentTime);
-               if (kbhit()) {
-                       return(1);
-               }
-#endif /* YUKON_DBG */
-
-       } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
-
-       return(0);
-}      /* SkI2cWait */
-
-
-/*
- * waits for a completion of an I2C transfer
- *
- * Returns
- *     Nothing
- */
-void SkI2cWaitIrq(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC)    /* I/O Context */
-{
-       SK_SENSOR       *pSen;
-       SK_U64          StartTime;
-       SK_U32          IrqSrc;
-
-       pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
-
-       if (pSen->SenState == SK_SEN_IDLE) {
-               return;
-       }
-
-       StartTime = SkOsGetTime(pAC);
-       do {
-               if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
-                       SK_I2C_STOP(IoC);
-#ifndef SK_DIAG
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
-#endif /* !SK_DIAG */
-                       return;
-               }
-               SK_IN32(IoC, B0_ISRC, &IrqSrc);
-       } while ((IrqSrc & IS_I2C_READY) == 0);
-
-       pSen->SenState = SK_SEN_IDLE;
-       return;
-}      /* SkI2cWaitIrq */
-
-/*
- * writes a single byte or 4 bytes into the I2C device
- *
- * returns     0:      success
- *                     1:      error
- */
-int SkI2cWrite(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-SK_U32 I2cData,        /* I2C Data to write */
-int            I2cDev,         /* I2C Device Address */
-int            I2cReg,         /* I2C Device Register Address */
-int            I2cBurst)       /* I2C Burst Flag */
-{
-       SK_OUT32(IoC, B2_I2C_DATA, I2cData);
-       SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cReg, I2cBurst);
-
-       return(SkI2cWait(pAC, IoC, I2C_WRITE));
-}      /* SkI2cWrite*/
-
-
-#ifdef SK_DIAG
-
-/*
- * reads a single byte or 4 bytes from the I2C device
- *
- * returns     the word read
- */
-SK_U32 SkI2cRead(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-int            I2cDev,         /* I2C Device Address */
-int            I2cReg,         /* I2C Device Register Address */
-int            I2cBurst)       /* I2C Burst Flag */
-{
-       SK_U32  Data;
-
-       SK_OUT32(IoC, B2_I2C_DATA, 0);
-       SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cReg, I2cBurst);
-
-       if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
-               w_print("%s\n", SKERR_I2C_E002MSG);
-       }
-
-       SK_IN32(IoC, B2_I2C_DATA, &Data);
-       return(Data);
-}      /* SkI2cRead */
-
-#endif /* SK_DIAG */
-
-
-/*
- * read a sensor's value
- *
- * This function reads a sensor's value from the I2C sensor chip. The sensor
- * is defined by its index into the sensors database in the struct pAC points
- * to.
- * Returns
- *             1 if the read is completed
- *             0 if the read must be continued (I2C Bus still allocated)
- */
-int    SkI2cReadSensor(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_SENSOR      *pSen)  /* Sensor to be read */
-{
-    if (pSen->SenRead != NULL) {
-       return((*pSen->SenRead)(pAC, IoC, pSen));
-    }
-    else
-       return(0); /* no success */
-}      /* SkI2cReadSensor*/
-
-/*
- * Do the Init state 0 initialization
- */
-static int SkI2cInit0(
-SK_AC  *pAC)   /* Adapter Context */
-{
-       int     i;
-
-       /* Begin with first sensor */
-       pAC->I2c.CurrSens = 0;
-
-       /* Begin with timeout control for state machine */
-       pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
-
-       /* Set sensor number to zero */
-       pAC->I2c.MaxSens = 0;
-
-#ifndef        SK_DIAG
-       /* Initialize Number of Dummy Reads */
-       pAC->I2c.DummyReads = SK_MAX_SENSORS;
-#endif
-
-       for (i = 0; i < SK_MAX_SENSORS; i++) {
-               pAC->I2c.SenTable[i].SenDesc = "unknown";
-               pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN;
-               pAC->I2c.SenTable[i].SenThreErrHigh = 0;
-               pAC->I2c.SenTable[i].SenThreErrLow = 0;
-               pAC->I2c.SenTable[i].SenThreWarnHigh = 0;
-               pAC->I2c.SenTable[i].SenThreWarnLow = 0;
-               pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
-               pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE;
-               pAC->I2c.SenTable[i].SenValue = 0;
-               pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT;
-               pAC->I2c.SenTable[i].SenErrCts = 0;
-               pAC->I2c.SenTable[i].SenBegErrTS = 0;
-               pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
-               pAC->I2c.SenTable[i].SenRead = NULL;
-               pAC->I2c.SenTable[i].SenDev = 0;
-       }
-
-       /* Now we are "INIT data"ed */
-       pAC->I2c.InitLevel = SK_INIT_DATA;
-       return(0);
-}      /* SkI2cInit0*/
-
-
-/*
- * Do the init state 1 initialization
- *
- * initialize the following register of the LM80:
- * Configuration register:
- * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
- *
- * Interrupt Mask Register 1:
- * - all interrupts are Disabled (0xff)
- *
- * Interrupt Mask Register 2:
- * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
- *
- * Fan Divisor/RST_OUT register:
- * - Divisors set to 1 (bits 00), all others 0s.
- *
- * OS# Configuration/Temperature resolution Register:
- * - all 0s
- *
- */
-static int SkI2cInit1(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC)    /* I/O Context */
-{
-    int i;
-    SK_U8 I2cSwCtrl;
-       SK_GEPORT *pPrt;        /* GIni Port struct pointer */
-
-       if (pAC->I2c.InitLevel != SK_INIT_DATA) {
-               /* ReInit not needed in I2C module */
-               return(0);
-       }
-
-    /* Set the Direction of I2C-Data Pin to IN */
-    SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA);
-    /* Check for 32-Bit Yukon with Low at I2C-Data Pin */
-       SK_I2C_GET_SW(IoC, &I2cSwCtrl);
-
-       if ((I2cSwCtrl & I2C_DATA) == 0) {
-               /* this is a 32-Bit board */
-               pAC->GIni.GIYukon32Bit = SK_TRUE;
-       return(0);
-    }
-
-       /* Check for 64 Bit Yukon without sensors */
-       if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_CFG, 0) != 0) {
-       return(0);
-    }
-
-       (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_1, 0);
-
-       (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_2, 0);
-
-       (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_FAN_CTRL, 0);
-
-       (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_TEMP_CTRL, 0);
-
-       (void)SkI2cWrite(pAC, IoC, LM80_CFG_START, LM80_ADDR, LM80_CFG, 0);
-
-       /*
-        * MaxSens has to be updated here, because PhyType is not
-        * set when performing Init Level 0
-        */
-    pAC->I2c.MaxSens = 5;
-
-       pPrt = &pAC->GIni.GP[0];
-
-       if (pAC->GIni.GIGenesis) {
-               if (pPrt->PhyType == SK_PHY_BCOM) {
-                       if (pAC->GIni.GIMacsFound == 1) {
-                               pAC->I2c.MaxSens += 1;
-                       }
-                       else {
-                               pAC->I2c.MaxSens += 3;
-                       }
-               }
-       }
-       else {
-               pAC->I2c.MaxSens += 3;
-       }
-
-       for (i = 0; i < pAC->I2c.MaxSens; i++) {
-               switch (i) {
-               case 0:
-                       pAC->I2c.SenTable[i].SenDesc = "Temperature";
-                       pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP;
-                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR;
-                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN;
-                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN;
-                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR;
-                       pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN;
-                       break;
-               case 1:
-                       pAC->I2c.SenTable[i].SenDesc = "Voltage PCI";
-                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
-                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR;
-                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN;
-                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN;
-                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR;
-                       pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN;
-                       break;
-               case 2:
-                       pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO";
-                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
-                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR;
-                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN;
-                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN;
-                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR;
-                       pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN;
-                       pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO;
-                       break;
-               case 3:
-                       pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC";
-                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
-                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR;
-                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN;
-                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN;
-                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR;
-                       pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN;
-                       break;
-               case 4:
-                       if (pAC->GIni.GIGenesis) {
-                               if (pPrt->PhyType == SK_PHY_BCOM) {
-                                       pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL";
-                                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
-                                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
-                                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
-                                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
-                               }
-                               else {
-                                       pAC->I2c.SenTable[i].SenDesc = "Voltage PMA";
-                                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
-                                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
-                                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
-                                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
-                               }
-                       }
-                       else {
-                               pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX";
-                               pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR;
-                               pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN;
-                               if (pAC->GIni.GIVauxAvail) {
-                                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
-                                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
-                               }
-                               else {
-                                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR;
-                                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR;
-                               }
-                       }
-                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
-                       pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN;
-                       break;
-               case 5:
-                       if (pAC->GIni.GIGenesis) {
-                               pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
-                               pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
-                               pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
-                               pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
-                               pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
-                       }
-                       else {
-                               pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC-Co 1V5";
-                               pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
-                               pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
-                               pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
-                               pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
-                       }
-                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
-                       pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN;
-                       break;
-               case 6:
-                       if (pAC->GIni.GIGenesis) {
-                               pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL";
-                       }
-                       else {
-                               pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3";
-                       }
-                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
-                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
-                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
-                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
-                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
-                       pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN;
-                       break;
-               case 7:
-                       if (pAC->GIni.GIGenesis) {
-                               pAC->I2c.SenTable[i].SenDesc = "Speed Fan";
-                               pAC->I2c.SenTable[i].SenType = SK_SEN_FAN;
-                               pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR;
-                               pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN;
-                               pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN;
-                               pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR;
-                               pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
-                       }
-                       else {
-                               pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
-                               pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
-                               pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
-                               pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
-                               pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
-                               pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
-                               pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN;
-                       }
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
-                               SKERR_I2C_E001, SKERR_I2C_E001MSG);
-                       break;
-               }
-
-               pAC->I2c.SenTable[i].SenValue = 0;
-               pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
-               pAC->I2c.SenTable[i].SenErrCts = 0;
-               pAC->I2c.SenTable[i].SenBegErrTS = 0;
-               pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
-               pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor;
-               pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
-       }
-
-#ifndef        SK_DIAG
-       pAC->I2c.DummyReads = pAC->I2c.MaxSens;
-#endif /* !SK_DIAG */
-
-       /* Clear I2C IRQ */
-       SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
-
-       /* Now we are I/O initialized */
-       pAC->I2c.InitLevel = SK_INIT_IO;
-       return(0);
-}      /* SkI2cInit1 */
-
-
-/*
- * Init level 2: Start first sensor read.
- */
-static int SkI2cInit2(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC)    /* I/O Context */
-{
-       int             ReadComplete;
-       SK_SENSOR       *pSen;
-
-       if (pAC->I2c.InitLevel != SK_INIT_IO) {
-               /* ReInit not needed in I2C module */
-               /* Init0 and Init2 not permitted */
-               return(0);
-       }
-
-       pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
-       ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
-
-       if (ReadComplete) {
-               SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
-       }
-
-       /* Now we are correctly initialized */
-       pAC->I2c.InitLevel = SK_INIT_RUN;
-
-       return(0);
-}      /* SkI2cInit2*/
-
-
-/*
- * Initialize I2C devices
- *
- * Get the first voltage value and discard it.
- * Go into temperature read mode. A default pointer is not set.
- *
- * The things to be done depend on the init level in the parameter list:
- * Level 0:
- *     Initialize only the data structures. Do NOT access hardware.
- * Level 1:
- *     Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
- * Level 2:
- *     Everything is possible. Interrupts may be used from now on.
- *
- * return:
- *     0 = success
- *     other = error.
- */
-int    SkI2cInit(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC,    /* I/O Context needed in levels 1 and 2 */
-int            Level)  /* Init Level */
-{
-
-       switch (Level) {
-       case SK_INIT_DATA:
-               return(SkI2cInit0(pAC));
-       case SK_INIT_IO:
-               return(SkI2cInit1(pAC, IoC));
-       case SK_INIT_RUN:
-               return(SkI2cInit2(pAC, IoC));
-       default:
-               break;
-       }
-
-       return(0);
-}      /* SkI2cInit */
-
-
-#ifndef SK_DIAG
-
-/*
- * Interrupt service function for the I2C Interface
- *
- * Clears the Interrupt source
- *
- * Reads the register and check it for sending a trap.
- *
- * Starts the timer if necessary.
- */
-void SkI2cIsr(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC)    /* I/O Context */
-{
-       SK_EVPARA       Para;
-
-       /* Clear I2C IRQ */
-       SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
-
-       Para.Para64 = 0;
-       SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
-}      /* SkI2cIsr */
-
-
-/*
- * Check this sensors Value against the threshold and send events.
- */
-static void SkI2cCheckSensor(
-SK_AC          *pAC,   /* Adapter Context */
-SK_SENSOR      *pSen)
-{
-       SK_EVPARA       ParaLocal;
-       SK_BOOL         TooHigh;        /* Is sensor too high? */
-       SK_BOOL         TooLow;         /* Is sensor too low? */
-       SK_U64          CurrTime;       /* Current Time */
-       SK_BOOL         DoTrapSend;     /* We need to send a trap */
-       SK_BOOL         DoErrLog;       /* We need to log the error */
-       SK_BOOL         IsError;        /* We need to log the error */
-
-       /* Check Dummy Reads first */
-       if (pAC->I2c.DummyReads > 0) {
-               pAC->I2c.DummyReads--;
-               return;
-       }
-
-       /* Get the current time */
-       CurrTime = SkOsGetTime(pAC);
-
-       /* Set para to the most useful setting: The current sensor. */
-       ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
-
-       /* Check the Value against the thresholds. First: Error Thresholds */
-       TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
-       TooLow = (pSen->SenValue < pSen->SenThreErrLow);
-
-       IsError = SK_FALSE;
-       if (TooHigh || TooLow) {
-               /* Error condition is satisfied */
-               DoTrapSend = SK_TRUE;
-               DoErrLog = SK_TRUE;
-
-               /* Now error condition is satisfied */
-               IsError = SK_TRUE;
-
-               if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
-                       /* This state is the former one */
-
-                       /* So check first whether we have to send a trap */
-                       if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD >
-                           CurrTime) {
-                               /*
-                                * Do NOT send the Trap. The hold back time
-                                * has to run out first.
-                                */
-                               DoTrapSend = SK_FALSE;
-                       }
-
-                       /* Check now whether we have to log an Error */
-                       if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD >
-                           CurrTime) {
-                               /*
-                                * Do NOT log the error. The hold back time
-                                * has to run out first.
-                                */
-                               DoErrLog = SK_FALSE;
-                       }
-               }
-               else {
-                       /* We came from a different state -> Set Begin Time Stamp */
-                       pSen->SenBegErrTS = CurrTime;
-                       pSen->SenErrFlag = SK_SEN_ERR_ERR;
-               }
-
-               if (DoTrapSend) {
-                       /* Set current Time */
-                       pSen->SenLastErrTrapTS = CurrTime;
-                       pSen->SenErrCts++;
-
-                       /* Queue PNMI Event */
-                       SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
-                               SK_PNMI_EVT_SEN_ERR_UPP :
-                               SK_PNMI_EVT_SEN_ERR_LOW),
-                               ParaLocal);
-               }
-
-               if (DoErrLog) {
-                       /* Set current Time */
-                       pSen->SenLastErrLogTS = CurrTime;
-
-                       if (pSen->SenType == SK_SEN_TEMP) {
-                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011,
-                                       SKERR_I2C_E011MSG);
-                       } else if (pSen->SenType == SK_SEN_VOLT) {
-                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012,
-                                       SKERR_I2C_E012MSG);
-                       } else
-                       {
-                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015,
-                                       SKERR_I2C_E015MSG);
-                       }
-               }
-       }
-
-       /* Check the Value against the thresholds */
-       /* 2nd: Warning thresholds */
-       TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
-       TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
-
-       if (!IsError && (TooHigh || TooLow)) {
-               /* Error condition is satisfied */
-               DoTrapSend = SK_TRUE;
-               DoErrLog = SK_TRUE;
-
-               if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
-                       /* This state is the former one */
-
-                       /* So check first whether we have to send a trap */
-                       if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD >
-                           CurrTime) {
-                               /*
-                                * Do NOT send the Trap. The hold back time
-                                * has to run out first.
-                                */
-                               DoTrapSend = SK_FALSE;
-                       }
-
-                       /* Check now whether we have to log an Error */
-                       if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD >
-                           CurrTime) {
-                               /*
-                                * Do NOT log the error. The hold back time
-                                * has to run out first.
-                                */
-                               DoErrLog = SK_FALSE;
-                       }
-               }
-               else {
-                       /* We came from a different state -> Set Begin Time Stamp */
-                       pSen->SenBegWarnTS = CurrTime;
-                       pSen->SenErrFlag = SK_SEN_ERR_WARN;
-               }
-
-               if (DoTrapSend) {
-                       /* Set current Time */
-                       pSen->SenLastWarnTrapTS = CurrTime;
-                       pSen->SenWarnCts++;
-
-                       /* Queue PNMI Event */
-                       SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
-                               SK_PNMI_EVT_SEN_WAR_UPP :
-                               SK_PNMI_EVT_SEN_WAR_LOW),
-                               ParaLocal);
-               }
-
-               if (DoErrLog) {
-                       /* Set current Time */
-                       pSen->SenLastWarnLogTS = CurrTime;
-
-                       if (pSen->SenType == SK_SEN_TEMP) {
-                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009,
-                                       SKERR_I2C_E009MSG);
-                       } else if (pSen->SenType == SK_SEN_VOLT) {
-                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010,
-                                       SKERR_I2C_E010MSG);
-                       } else
-                       {
-                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014,
-                                       SKERR_I2C_E014MSG);
-                       }
-               }
-       }
-
-       /* Check for NO error at all */
-       if (!IsError && !TooHigh && !TooLow) {
-               /* Set o.k. Status if no error and no warning condition */
-               pSen->SenErrFlag = SK_SEN_ERR_OK;
-       }
-
-       /* End of check against the thresholds */
-
-       /* Bug fix AF: 16.Aug.2001: Correct the init base
-        * of LM80 sensor.
-        */
-       if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
-
-       pSen->SenInit = SK_SEN_DYN_INIT_NONE;
-
-               if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) {
-                       /* 5V PCI-IO Voltage */
-                       pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN;
-                       pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR;
-               }
-               else {
-                       /* 3.3V PCI-IO Voltage */
-                       pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN;
-                       pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR;
-               }
-       }
-
-#if 0
-    /* Dynamic thresholds also for VAUX of LM80 sensor */
-       if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
-
-       pSen->SenInit = SK_SEN_DYN_INIT_NONE;
-
-               /* 3.3V VAUX Voltage */
-               if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) {
-                       pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
-                       pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
-               }
-               /* 0V VAUX Voltage */
-               else {
-                       pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
-                       pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
-               }
-       }
-
-       /*
-        * Check initialization state:
-        * The VIO Thresholds need adaption
-        */
-       if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
-            pSen->SenValue > SK_SEN_WARNLOW2C &&
-            pSen->SenValue < SK_SEN_WARNHIGH2) {
-               pSen->SenThreErrLow = SK_SEN_ERRLOW2C;
-               pSen->SenThreWarnLow = SK_SEN_WARNLOW2C;
-               pSen->SenInit = SK_TRUE;
-       }
-
-       if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
-            pSen->SenValue > SK_SEN_WARNLOW2 &&
-            pSen->SenValue < SK_SEN_WARNHIGH2C) {
-               pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C;
-               pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C;
-               pSen->SenInit = SK_TRUE;
-       }
-#endif
-
-       if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
-       }
-}      /* SkI2cCheckSensor*/
-
-
-/*
- * The only Event to be served is the timeout event
- *
- */
-int    SkI2cEvent(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_U32         Event,  /* Module specific Event */
-SK_EVPARA      Para)   /* Event specific Parameter */
-{
-       int                     ReadComplete;
-       SK_SENSOR       *pSen;
-       SK_U32          Time;
-       SK_EVPARA       ParaLocal;
-       int                     i;
-
-       /* New case: no sensors */
-       if (pAC->I2c.MaxSens == 0) {
-               return(0);
-       }
-
-       switch (Event) {
-       case SK_I2CEV_IRQ:
-               pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
-               ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
-
-               if (ReadComplete) {
-                       /* Check sensor against defined thresholds */
-                       SkI2cCheckSensor (pAC, pSen);
-
-                       /* Increment Current sensor and set appropriate Timeout */
-                       pAC->I2c.CurrSens++;
-                       if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) {
-                               pAC->I2c.CurrSens = 0;
-                               Time = SK_I2C_TIM_LONG;
-                       }
-                       else {
-                               Time = SK_I2C_TIM_SHORT;
-                       }
-
-                       /* Start Timer */
-                       ParaLocal.Para64 = (SK_U64)0;
-
-                       pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
-
-                       SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
-                               SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
-               }
-       else {
-                       /* Start Timer */
-                       ParaLocal.Para64 = (SK_U64)0;
-
-                       pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
-
-           SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
-                               SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
-               }
-               break;
-       case SK_I2CEV_TIM:
-               if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
-
-                       ParaLocal.Para64 = (SK_U64)0;
-                       SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
-
-                       pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
-                       ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
-
-                       if (ReadComplete) {
-                               /* Check sensor against defined thresholds */
-                               SkI2cCheckSensor (pAC, pSen);
-
-                               /* Increment Current sensor and set appropriate Timeout */
-                               pAC->I2c.CurrSens++;
-                               if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
-                                       pAC->I2c.CurrSens = 0;
-                                       Time = SK_I2C_TIM_LONG;
-                               }
-                               else {
-                                       Time = SK_I2C_TIM_SHORT;
-                               }
-
-                               /* Start Timer */
-                               ParaLocal.Para64 = (SK_U64)0;
-
-                               pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
-
-                               SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
-                                       SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
-                       }
-               }
-               else {
-                       pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
-                       pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
-                       SK_I2C_STOP(IoC);
-
-                       /* Increment Current sensor and set appropriate Timeout */
-                       pAC->I2c.CurrSens++;
-                       if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
-                               pAC->I2c.CurrSens = 0;
-                               Time = SK_I2C_TIM_LONG;
-                       }
-                       else {
-                               Time = SK_I2C_TIM_SHORT;
-                       }
-
-                       /* Start Timer */
-                       ParaLocal.Para64 = (SK_U64)0;
-
-                       pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
-
-                       SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
-                               SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
-               }
-               break;
-       case SK_I2CEV_CLEAR:
-               for (i = 0; i < SK_MAX_SENSORS; i++) {
-                       pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
-                       pAC->I2c.SenTable[i].SenErrCts = 0;
-                       pAC->I2c.SenTable[i].SenWarnCts = 0;
-                       pAC->I2c.SenTable[i].SenBegErrTS = 0;
-                       pAC->I2c.SenTable[i].SenBegWarnTS = 0;
-                       pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0;
-                       pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0;
-                       pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0;
-                       pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0;
-               }
-               break;
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
-       }
-
-       return(0);
-}      /* SkI2cEvent*/
-
-#endif /* !SK_DIAG */
-
-#endif /* CONFIG_SK98 */
diff --git a/drivers/sk98lin/sklm80.c b/drivers/sk98lin/sklm80.c
deleted file mode 100644 (file)
index 687572b..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-/******************************************************************************
- *
- * Name:       sklm80.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.20 $
- * Date:       $Date: 2002/08/13 09:16:27 $
- * Purpose:    Funktions to access Voltage and Temperature Sensor (LM80)
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: sklm80.c,v $
- *     Revision 1.20  2002/08/13 09:16:27  rschmidt
- *     Changed return value for SkLm80ReadSensor() back to 'int'
- *     Editorial changes
- *
- *     Revision 1.19  2002/08/06 09:43:31  jschmalz
- *     Extensions and changes for Yukon
- *
- *     Revision 1.18  2002/08/02 12:26:57  rschmidt
- *     Editorial changes
- *
- *     Revision 1.17  1999/11/22 13:35:51  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.16  1999/05/27 14:05:47  malthoff
- *     Fans: Set SenVal to 0 if the fan value is 0 or 0xff. Both values
- *     are outside the limits (0: div zero error, 0xff: value not in
- *     range, assume 0).
- *
- *     Revision 1.15  1999/05/27 13:38:51  malthoff
- *     Pervent from Division by zero errors.
- *
- *     Revision 1.14  1999/05/20 09:20:01  cgoos
- *     Changes for 1000Base-T (Fan sensors).
- *
- *     Revision 1.13  1998/10/22 09:48:14  gklug
- *     fix: SysKonnectFileId typo
- *
- *     Revision 1.12  1998/10/09 06:12:06  malthoff
- *     Remove ID_sccs by SysKonnectFileId.
- *
- *     Revision 1.11  1998/09/04 08:33:48  malthoff
- *     bug fix: SenState = SK_SEN_IDLE when
- *     leaving SK_SEN_VALEXT state
- *
- *     Revision 1.10  1998/08/20 12:02:10  gklug
- *     fix: compiler warnings type mismatch
- *
- *     Revision 1.9  1998/08/20 11:37:38  gklug
- *     chg: change Ioc to IoC
- *
- *     Revision 1.8  1998/08/19 12:20:58  gklug
- *     fix: remove struct from C files (see CCC)
- *
- *     Revision 1.7  1998/08/17 07:04:57  malthoff
- *     Take SkLm80RcvReg() function from ski2c.c.
- *     Add IoC parameter to BREAK_OR_WAIT() macro.
- *
- *     Revision 1.6  1998/08/14 07:11:28  malthoff
- *     remove pAc with pAC.
- *
- *     Revision 1.5  1998/08/14 06:46:55  gklug
- *     fix: temperature can get negative
- *
- *     Revision 1.4  1998/08/13 08:27:04  gklug
- *     add: temperature reading now o.k.
- *     fix: pSen declaration, SK_ERR_LOG call, ADDR macro
- *
- *     Revision 1.3  1998/08/13 07:28:21  gklug
- *     fix: pSen was wrong initialized
- *     add: correct conversion for voltage readings
- *
- *     Revision 1.2  1998/08/11 07:52:14  gklug
- *     add: Lm80 read sensor function
- *
- *     Revision 1.1  1998/07/17 09:57:12  gklug
- *     initial version
- *
- *
- *
- ******************************************************************************/
-
-
-#include <config.h>
-
-#ifdef CONFIG_SK98
-
-/*
-       LM80 functions
-*/
-static const char SysKonnectFileId[] =
-       "$Id: sklm80.c,v 1.20 2002/08/13 09:16:27 rschmidt Exp $" ;
-
-#include "h/skdrv1st.h"                /* Driver Specific Definitions */
-#include "h/lm80.h"
-#include "h/skdrv2nd.h"                /* Adapter Control- and Driver specific Def. */
-
-#ifdef SK_DIAG
-#define        BREAK_OR_WAIT(pAC,IoC,Event)    SkI2cWait(pAC,IoC,Event)
-#else  /* nSK_DIAG */
-#define        BREAK_OR_WAIT(pAC,IoC,Event)    break
-#endif /* nSK_DIAG */
-
-#ifdef SK_DIAG
-/*
- * read the register 'Reg' from the device 'Dev'
- *
- * return      read error      -1
- *             success         the read value
- */
-int    SkLm80RcvReg(
-SK_IOC IoC,            /* Adapter Context */
-int            Dev,            /* I2C device address */
-int            Reg)            /* register to read */
-{
-       int     Val = 0;
-       int     TempExt;
-
-       /* Signal device number */
-       if (SkI2cSndDev(IoC, Dev, I2C_WRITE)) {
-               return(-1);
-       }
-
-       if (SkI2cSndByte(IoC, Reg)) {
-               return(-1);
-       }
-
-       /* repeat start */
-       if (SkI2cSndDev(IoC, Dev, I2C_READ)) {
-               return(-1);
-       }
-
-       switch (Reg) {
-       case LM80_TEMP_IN:
-               Val = (int)SkI2cRcvByte(IoC, 1);
-
-               /* First: correct the value: it might be negative */
-               if ((Val & 0x80) != 0) {
-                       /* Value is negative */
-                       Val = Val - 256;
-               }
-               Val = Val * SK_LM80_TEMP_LSB;
-               SkI2cStop(IoC);
-
-               TempExt = (int)SkLm80RcvReg(IoC, LM80_ADDR, LM80_TEMP_CTRL);
-
-               if (Val > 0) {
-                       Val += ((TempExt >> 7) * SK_LM80_TEMPEXT_LSB);
-               }
-               else {
-                       Val -= ((TempExt >> 7) * SK_LM80_TEMPEXT_LSB);
-               }
-               return(Val);
-               break;
-       case LM80_VT0_IN:
-       case LM80_VT1_IN:
-       case LM80_VT2_IN:
-       case LM80_VT3_IN:
-               Val = (int)SkI2cRcvByte(IoC, 1) * SK_LM80_VT_LSB;
-               break;
-
-       default:
-               Val = (int)SkI2cRcvByte(IoC, 1);
-               break;
-       }
-
-       SkI2cStop(IoC);
-       return(Val);
-}
-#endif /* SK_DIAG */
-
-/*
- * read a sensors value (LM80 specific)
- *
- * This function reads a sensors value from the I2C sensor chip LM80.
- * The sensor is defined by its index into the sensors database in the struct
- * pAC points to.
- *
- * Returns     1 if the read is completed
- *             0 if the read must be continued (I2C Bus still allocated)
- */
-int SkLm80ReadSensor(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context needed in level 1 and 2 */
-SK_SENSOR      *pSen)  /* Sensor to be read */
-{
-       SK_I32          Value;
-
-       switch (pSen->SenState) {
-       case SK_SEN_IDLE:
-               /* Send address to ADDR register */
-               SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, pSen->SenReg, 0);
-
-               pSen->SenState = SK_SEN_VALUE ;
-               BREAK_OR_WAIT(pAC, IoC, I2C_READ);
-
-       case SK_SEN_VALUE:
-               /* Read value from data register */
-               SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value));
-
-               Value &= 0xff; /* only least significant byte is valid */
-
-               /* Do NOT check the Value against the thresholds */
-               /* Checking is done in the calling instance */
-
-               if (pSen->SenType == SK_SEN_VOLT) {
-                       /* Voltage sensor */
-                       pSen->SenValue = Value * SK_LM80_VT_LSB;
-                       pSen->SenState = SK_SEN_IDLE ;
-                       return(1);
-               }
-
-               if (pSen->SenType == SK_SEN_FAN) {
-                       if (Value != 0 && Value != 0xff) {
-                               /* Fan speed counter */
-                               pSen->SenValue = SK_LM80_FAN_FAKTOR/Value;
-                       }
-                       else {
-                               /* Indicate Fan error */
-                               pSen->SenValue = 0;
-                       }
-                       pSen->SenState = SK_SEN_IDLE ;
-                       return(1);
-               }
-
-               /* First: correct the value: it might be negative */
-               if ((Value & 0x80) != 0) {
-                       /* Value is negative */
-                       Value = Value - 256;
-               }
-
-               /* We have a temperature sensor and need to get the signed extension.
-                * For now we get the extension from the last reading, so in the normal
-                * case we won't see flickering temperatures.
-                */
-               pSen->SenValue = (Value * SK_LM80_TEMP_LSB) +
-                       (pSen->SenValue % SK_LM80_TEMP_LSB);
-
-               /* Send address to ADDR register */
-               SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, LM80_TEMP_CTRL, 0);
-
-               pSen->SenState = SK_SEN_VALEXT ;
-               BREAK_OR_WAIT(pAC, IoC, I2C_READ);
-
-       case SK_SEN_VALEXT:
-               /* Read value from data register */
-               SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value));
-               Value &= LM80_TEMP_LSB_9; /* only bit 7 is valid */
-
-               /* cut the LSB bit */
-               pSen->SenValue = ((pSen->SenValue / SK_LM80_TEMP_LSB) *
-                       SK_LM80_TEMP_LSB);
-
-               if (pSen->SenValue < 0) {
-                       /* Value negative: The bit value must be subtracted */
-                       pSen->SenValue -= ((Value >> 7) * SK_LM80_TEMPEXT_LSB);
-               }
-               else {
-                       /* Value positive: The bit value must be added */
-                       pSen->SenValue += ((Value >> 7) * SK_LM80_TEMPEXT_LSB);
-               }
-
-               pSen->SenState = SK_SEN_IDLE ;
-               return(1);
-
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E007, SKERR_I2C_E007MSG);
-               return(1);
-       }
-
-       /* Not completed */
-       return(0);
-}
-
-#endif /* CONFIG_SK98 */
diff --git a/drivers/sk98lin/skproc.c b/drivers/sk98lin/skproc.c
deleted file mode 100644 (file)
index 4e34073..0000000
+++ /dev/null
@@ -1,515 +0,0 @@
-/******************************************************************************
- *
- * Name:    skproc.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.4 $
- * Date:    $Date: 2003/02/25 14:16:37 $
- * Purpose:    Funktions to display statictic data
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     Created 22-Nov-2000
- *     Author: Mirko Lindner (mlindner@syskonnect.de)
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skproc.c,v $
- *     Revision 1.4  2003/02/25 14:16:37  mlindner
- *     Fix: Copyright statement
- *
- *     Revision 1.3  2002/10/02 12:59:51  mlindner
- *     Add: Support for Yukon
- *     Add: Speed check and setup
- *     Add: Merge source for kernel 2.2.x and 2.4.x
- *     Add: Read sensor names directly from VPD
- *     Fix: Volt values
- *
- *     Revision 1.2.2.7  2002/01/14 12:45:15  mlindner
- *     Fix: Editorial changes
- *
- *     Revision 1.2.2.6  2001/12/06 15:26:07  mlindner
- *     Fix: Return value of proc_read
- *
- *     Revision 1.2.2.5  2001/12/06 09:57:39  mlindner
- *     New ProcFs entries
- *
- *     Revision 1.2.2.4  2001/09/05 12:16:02  mlindner
- *     Add: New ProcFs entries
- *     Fix: Counter Errors (Jumbo == to long errors)
- *     Fix: Kernel error compilation
- *     Fix: too short counters
- *
- *     Revision 1.2.2.3  2001/06/25 07:26:26  mlindner
- *     Add: More error messages
- *
- *     Revision 1.2.2.2  2001/03/15 12:50:13  mlindner
- *     fix: ProcFS owner protection
- *
- *     Revision 1.2.2.1  2001/03/12 16:43:48  mlindner
- *     chg: 2.4 requirements for procfs
- *
- *     Revision 1.1  2001/01/22 14:15:31  mlindner
- *     added ProcFs functionality
- *     Dual Net functionality integrated
- *     Rlmt networks added
- *
- *
- ******************************************************************************/
-
-#include <config.h>
-
-#ifdef CONFIG_SK98
-
-#include <linux/proc_fs.h>
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-#define ZEROPAD                1               /* pad with zero */
-#define SIGN           2               /* unsigned/signed long */
-#define PLUS           4               /* show plus */
-#define SPACE          8               /* space if plus */
-#define LEFT           16              /* left justified */
-#define SPECIALX       32              /* 0x */
-#define LARGE          64
-
-extern SK_AC                           *pACList;
-extern struct net_device       *SkGeRootDev;
-
-extern char * SkNumber(
-       char * str,
-       long long num,
-       int base,
-       int size,
-       int precision,
-       int type);
-
-
-/*****************************************************************************
- *
- *     proc_read - print "summaries" entry
- *
- * Description:
- *  This function fills the proc entry with statistic data about
- *  the ethernet device.
- *
- *
- * Returns: buffer with statistic data
- *
- */
-int proc_read(char *buffer,
-char **buffer_location,
-off_t offset,
-int buffer_length,
-int *eof,
-void *data)
-{
-       int len = 0;
-       int t;
-       int i;
-       DEV_NET                                 *pNet;
-       SK_AC                                   *pAC;
-       char                                    test_buf[100];
-       char                                    sens_msg[50];
-       unsigned long                   Flags;
-       unsigned int                    Size;
-       struct SK_NET_DEVICE            *next;
-       struct SK_NET_DEVICE            *SkgeProcDev = SkGeRootDev;
-
-       SK_PNMI_STRUCT_DATA     *pPnmiStruct;
-       SK_PNMI_STAT            *pPnmiStat;
-       struct proc_dir_entry *file = (struct proc_dir_entry*) data;
-
-       while (SkgeProcDev) {
-               pNet = (DEV_NET*) SkgeProcDev->priv;
-               pAC = pNet->pAC;
-               next = pAC->Next;
-               pPnmiStruct = &pAC->PnmiStruct;
-               /* NetIndex in GetStruct is now required, zero is only dummy */
-
-               for (t=pAC->GIni.GIMacsFound; t > 0; t--) {
-                       if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1)
-                               t--;
-
-                       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-                       Size = SK_PNMI_STRUCT_SIZE;
-                       SkPnmiGetStruct(pAC, pAC->IoBase,
-                               pPnmiStruct, &Size, t-1);
-                       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
-                       if (strcmp(pAC->dev[t-1]->name, file->name) == 0) {
-                               pPnmiStat = &pPnmiStruct->Stat[0];
-                               len = sprintf(buffer,
-                                       "\nDetailed statistic for device %s\n",
-                                       pAC->dev[t-1]->name);
-                               len += sprintf(buffer + len,
-                                       "=======================================\n");
-
-                               /* Board statistics */
-                               len += sprintf(buffer + len,
-                                       "\nBoard statistics\n\n");
-                               len += sprintf(buffer + len,
-                                       "Active Port                    %c\n",
-                                       'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
-                                       Net[t-1].PrefPort]->PortNumber);
-                               len += sprintf(buffer + len,
-                                       "Preferred Port                 %c\n",
-                                       'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
-                                       Net[t-1].PrefPort]->PortNumber);
-
-                               len += sprintf(buffer + len,
-                                       "Bus speed (MHz)                %d\n",
-                                       pPnmiStruct->BusSpeed);
-
-                               len += sprintf(buffer + len,
-                                       "Bus width (Bit)                %d\n",
-                                       pPnmiStruct->BusWidth);
-                               len += sprintf(buffer + len,
-                                       "Hardware revision              v%d.%d\n",
-                                       (pAC->GIni.GIPciHwRev >> 4) & 0x0F,
-                                       pAC->GIni.GIPciHwRev & 0x0F);
-
-                               /* Print sensor informations */
-                               for (i=0; i < pAC->I2c.MaxSens; i ++) {
-                                       /* Check type */
-                                       switch (pAC->I2c.SenTable[i].SenType) {
-                                       case 1:
-                                               strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-                                               strcat(sens_msg, " (C)");
-                                               len += sprintf(buffer + len,
-                                                       "%-25s      %d.%02d\n",
-                                                       sens_msg,
-                                                       pAC->I2c.SenTable[i].SenValue / 10,
-                                                       pAC->I2c.SenTable[i].SenValue % 10);
-
-                                               strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-                                               strcat(sens_msg, " (F)");
-                                               len += sprintf(buffer + len,
-                                                       "%-25s      %d.%02d\n",
-                                                       sens_msg,
-                                                       ((((pAC->I2c.SenTable[i].SenValue)
-                                                       *10)*9)/5 + 3200)/100,
-                                                       ((((pAC->I2c.SenTable[i].SenValue)
-                                                       *10)*9)/5 + 3200) % 10);
-                                               break;
-                                       case 2:
-                                               strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-                                               strcat(sens_msg, " (V)");
-                                               len += sprintf(buffer + len,
-                                                       "%-25s      %d.%03d\n",
-                                                       sens_msg,
-                                                       pAC->I2c.SenTable[i].SenValue / 1000,
-                                                       pAC->I2c.SenTable[i].SenValue % 1000);
-                                               break;
-                                       case 3:
-                                               strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-                                               strcat(sens_msg, " (rpm)");
-                                               len += sprintf(buffer + len,
-                                                       "%-25s      %d\n",
-                                                       sens_msg,
-                                                       pAC->I2c.SenTable[i].SenValue);
-                                               break;
-                                       default:
-                                               break;
-                                       }
-                               }
-
-                               /*Receive statistics */
-                               len += sprintf(buffer + len,
-                               "\nReceive statistics\n\n");
-
-                               len += sprintf(buffer + len,
-                                       "Received bytes                 %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatRxOctetsOkCts,
-                                       10,0,-1,0));
-                               len += sprintf(buffer + len,
-                                       "Received packets               %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatRxOkCts,
-                                       10,0,-1,0));
-#if 0
-                               if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC &&
-                                       pAC->HWRevision < 12) {
-                                       pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
-                                               pPnmiStat->StatRxShortsCts;
-                                       pPnmiStat->StatRxShortsCts = 0;
-                               }
-#endif
-                               if (pNet->Mtu > 1500)
-                                       pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
-                                               pPnmiStat->StatRxTooLongCts;
-
-                               len += sprintf(buffer + len,
-                                       "Receive errors                 %s\n",
-                                       SkNumber(test_buf, pPnmiStruct->InErrorsCts,
-                                       10,0,-1,0));
-                               len += sprintf(buffer + len,
-                                       "Receive drops                  %s\n",
-                                       SkNumber(test_buf, pPnmiStruct->RxNoBufCts,
-                                       10,0,-1,0));
-                               len += sprintf(buffer + len,
-                                       "Received multicast             %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatRxMulticastOkCts,
-                                       10,0,-1,0));
-                               len += sprintf(buffer + len,
-                                       "Receive error types\n");
-                               len += sprintf(buffer + len,
-                                       "   length                      %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatRxRuntCts,
-                                       10, 0, -1, 0));
-                               len += sprintf(buffer + len,
-                                       "   buffer overflow             %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatRxFifoOverflowCts,
-                                       10, 0, -1, 0));
-                               len += sprintf(buffer + len,
-                                       "   bad crc                     %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatRxFcsCts,
-                                       10, 0, -1, 0));
-                               len += sprintf(buffer + len,
-                                       "   framing                     %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatRxFramingCts,
-                                       10, 0, -1, 0));
-                               len += sprintf(buffer + len,
-                                       "   missed frames               %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatRxMissedCts,
-                                       10, 0, -1, 0));
-
-                               if (pNet->Mtu > 1500)
-                                       pPnmiStat->StatRxTooLongCts = 0;
-
-                               len += sprintf(buffer + len,
-                                       "   too long                    %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatRxTooLongCts,
-                                       10, 0, -1, 0));
-                               len += sprintf(buffer + len,
-                                       "   carrier extension           %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatRxCextCts,
-                                       10, 0, -1, 0));
-                               len += sprintf(buffer + len,
-                                       "   too short                   %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatRxShortsCts,
-                                       10, 0, -1, 0));
-                               len += sprintf(buffer + len,
-                                       "   symbol                      %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatRxSymbolCts,
-                                       10, 0, -1, 0));
-                               len += sprintf(buffer + len,
-                                       "   LLC MAC size                %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatRxIRLengthCts,
-                                       10, 0, -1, 0));
-                               len += sprintf(buffer + len,
-                                       "   carrier event               %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatRxCarrierCts,
-                                       10, 0, -1, 0));
-                               len += sprintf(buffer + len,
-                                       "   jabber                      %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatRxJabberCts,
-                                       10, 0, -1, 0));
-
-
-                               /*Transmit statistics */
-                               len += sprintf(buffer + len,
-                               "\nTransmit statistics\n\n");
-
-                               len += sprintf(buffer + len,
-                                       "Transmited bytes               %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatTxOctetsOkCts,
-                                       10,0,-1,0));
-                               len += sprintf(buffer + len,
-                                       "Transmited packets             %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatTxOkCts,
-                                       10,0,-1,0));
-                               len += sprintf(buffer + len,
-                                       "Transmit errors                %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatTxSingleCollisionCts,
-                                       10,0,-1,0));
-                               len += sprintf(buffer + len,
-                                       "Transmit dropped               %s\n",
-                                       SkNumber(test_buf, pPnmiStruct->TxNoBufCts,
-                                       10,0,-1,0));
-                               len += sprintf(buffer + len,
-                                       "Transmit collisions            %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatTxSingleCollisionCts,
-                                       10,0,-1,0));
-                               len += sprintf(buffer + len,
-                                       "Transmit errors types\n");
-                               len += sprintf(buffer + len,
-                                       "   excessive collision         %ld\n",
-                                       pAC->stats.tx_aborted_errors);
-                               len += sprintf(buffer + len,
-                                       "   carrier                     %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatTxCarrierCts,
-                                       10, 0, -1, 0));
-                               len += sprintf(buffer + len,
-                                       "   fifo underrun               %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatTxFifoUnderrunCts,
-                                       10, 0, -1, 0));
-                               len += sprintf(buffer + len,
-                                       "   heartbeat                   %s\n",
-                                       SkNumber(test_buf, pPnmiStat->StatTxCarrierCts,
-                                       10, 0, -1, 0));
-                               len += sprintf(buffer + len,
-                                       "   window                      %ld\n",
-                                       pAC->stats.tx_window_errors);
-
-                       }
-               }
-               SkgeProcDev = next;
-       }
-       if (offset >= len) {
-               *eof = 1;
-               return 0;
-       }
-
-       *buffer_location = buffer + offset;
-       if (buffer_length >= len - offset) {
-               *eof = 1;
-       }
-       return (min_t(int, buffer_length, len - offset));
-}
-
-
-/*****************************************************************************
- *
- * SkDoDiv - convert 64bit number
- *
- * Description:
- *     This function "converts" a long long number.
- *
- * Returns:
- *     remainder of division
- */
-static long SkDoDiv (long long Dividend, int Divisor, long long *pErg)
-{
- long          Rest;
- long long     Ergebnis;
- long          Akku;
-
-
- Akku  = Dividend >> 32;
-
- Ergebnis = ((long long) (Akku / Divisor)) << 32;
- Rest = Akku % Divisor ;
-
- Akku = Rest << 16;
- Akku |= ((Dividend & 0xFFFF0000) >> 16);
-
-
- Ergebnis += ((long long) (Akku / Divisor)) << 16;
- Rest = Akku % Divisor ;
-
- Akku = Rest << 16;
- Akku |= (Dividend & 0xFFFF);
-
- Ergebnis += (Akku / Divisor);
- Rest = Akku % Divisor ;
-
- *pErg = Ergebnis;
- return (Rest);
-}
-
-
-#if 0
-#define do_div(n,base) ({ \
-long long __res; \
-__res = ((unsigned long long) n) % (unsigned) base; \
-n = ((unsigned long long) n) / (unsigned) base; \
-__res; })
-
-#endif
-
-
-/*****************************************************************************
- *
- * SkNumber - Print results
- *
- * Description:
- *     This function converts a long long number into a string.
- *
- * Returns:
- *     number as string
- */
-char * SkNumber(char * str, long long num, int base, int size, int precision
-       ,int type)
-{
-       char c,sign,tmp[66], *strorg = str;
-       const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
-       int i;
-
-       if (type & LARGE)
-               digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-       if (type & LEFT)
-               type &= ~ZEROPAD;
-       if (base < 2 || base > 36)
-               return 0;
-       c = (type & ZEROPAD) ? '0' : ' ';
-       sign = 0;
-       if (type & SIGN) {
-               if (num < 0) {
-                       sign = '-';
-                       num = -num;
-                       size--;
-               } else if (type & PLUS) {
-                       sign = '+';
-                       size--;
-               } else if (type & SPACE) {
-                       sign = ' ';
-                       size--;
-               }
-       }
-       if (type & SPECIALX) {
-               if (base == 16)
-                       size -= 2;
-               else if (base == 8)
-                       size--;
-       }
-       i = 0;
-       if (num == 0)
-               tmp[i++]='0';
-       else while (num != 0)
-               tmp[i++] = digits[SkDoDiv(num,base, &num)];
-
-       if (i > precision)
-               precision = i;
-       size -= precision;
-       if (!(type&(ZEROPAD+LEFT)))
-               while(size-->0)
-                       *str++ = ' ';
-       if (sign)
-               *str++ = sign;
-       if (type & SPECIALX) {
-               if (base==8)
-                       *str++ = '0';
-               else if (base==16) {
-                       *str++ = '0';
-                       *str++ = digits[33];
-               }
-       }
-       if (!(type & LEFT))
-               while (size-- > 0)
-                       *str++ = c;
-       while (i < precision--)
-               *str++ = '0';
-       while (i-- > 0)
-               *str++ = tmp[i];
-       while (size-- > 0)
-               *str++ = ' ';
-
-       str[0] = '\0';
-
-       return strorg;
-}
-
-#endif /* CONFIG_SK98 */
diff --git a/drivers/sk98lin/skqueue.c b/drivers/sk98lin/skqueue.c
deleted file mode 100644 (file)
index c49baed..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-/******************************************************************************
- *
- * Name:       skqueue.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.18 $
- * Date:       $Date: 2002/05/07 14:11:11 $
- * Purpose:    Management of an event queue.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998,1999 SysKonnect,
- *     a business unit of Schneider & Koch & Co. Datensysteme GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skqueue.c,v $
- *     Revision 1.18  2002/05/07 14:11:11  rwahl
- *     Fixed Watcom Precompiler error.
- *
- *     Revision 1.17  2002/03/25 10:06:41  mkunz
- *     SkIgnoreEvent deleted
- *
- *     Revision 1.16  2002/03/15 10:51:59  mkunz
- *     Added event classes for link aggregation
- *
- *     Revision 1.15  1999/11/22 13:36:29  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.14  1998/10/15 15:11:35  gklug
- *     fix: ID_sccs to SysKonnectFileId
- *
- *     Revision 1.13  1998/09/08 08:47:52  gklug
- *     add: init level handling
- *
- *     Revision 1.12  1998/09/08 07:43:20  gklug
- *     fix: Sirq Event function name
- *
- *     Revision 1.11  1998/09/08 05:54:34  gklug
- *     chg: define SK_CSUM is replaced by SK_USE_CSUM
- *
- *     Revision 1.10  1998/09/03 14:14:49  gklug
- *     add: CSUM and HWAC Eventclass and function.
- *
- *     Revision 1.9  1998/08/19 09:50:50  gklug
- *     fix: remove struct keyword from c-code (see CCC) add typedefs
- *
- *     Revision 1.8  1998/08/17 13:43:11  gklug
- *     chg: Parameter will be union of 64bit para, 2 times SK_U32 or SK_PTR
- *
- *     Revision 1.7  1998/08/14 07:09:11  gklug
- *     fix: chg pAc -> pAC
- *
- *     Revision 1.6  1998/08/11 12:13:14  gklug
- *     add: return code feature of Event service routines
- *     add: correct Error log calls
- *
- *     Revision 1.5  1998/08/07 12:53:45  gklug
- *     fix: first compiled version
- *
- *     Revision 1.4  1998/08/07 09:20:48  gklug
- *     adapt functions to C coding conventions.
- *
- *     Revision 1.3  1998/08/05 11:29:32  gklug
- *     rmv: Timer event entry. Timer will queue event directly
- *
- *     Revision 1.2  1998/07/31 11:22:40  gklug
- *     Initial version
- *
- *     Revision 1.1  1998/07/30 15:14:01  gklug
- *     Initial version. Adapted from SMT
- *
- *
- *
- ******************************************************************************/
-
-
-#include <config.h>
-
-#ifdef CONFIG_SK98
-
-/*
-       Event queue and dispatcher
-*/
-static const char SysKonnectFileId[] =
-       "$Header: /usr56/projects/ge/schedule/skqueue.c,v 1.18 2002/05/07 14:11:11 rwahl Exp $" ;
-
-#include "h/skdrv1st.h"                /* Driver Specific Definitions */
-#include "h/skqueue.h"         /* Queue Definitions */
-#include "h/skdrv2nd.h"                /* Adapter Control- and Driver specific Def. */
-
-#ifdef __C2MAN__
-/*
-       Event queue management.
-
-       General Description:
-
- */
-intro()
-{}
-#endif
-
-#define PRINTF(a,b,c)
-
-/*
- * init event queue management
- *
- * Must be called during init level 0.
- */
-void   SkEventInit(
-SK_AC  *pAC,   /* Adapter context */
-SK_IOC Ioc,    /* IO context */
-int    Level)  /* Init level */
-{
-       switch (Level) {
-       case SK_INIT_DATA:
-               pAC->Event.EvPut = pAC->Event.EvGet = pAC->Event.EvQueue ;
-               break;
-       default:
-               break;
-       }
-}
-
-/*
- * add event to queue
- */
-void   SkEventQueue(
-SK_AC          *pAC,   /* Adapters context */
-SK_U32         Class,  /* Event Class */
-SK_U32         Event,  /* Event to be queued */
-SK_EVPARA      Para)   /* Event parameter */
-{
-       pAC->Event.EvPut->Class = Class ;
-       pAC->Event.EvPut->Event = Event ;
-       pAC->Event.EvPut->Para = Para ;
-       if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT])
-               pAC->Event.EvPut = pAC->Event.EvQueue ;
-
-       if (pAC->Event.EvPut == pAC->Event.EvGet) {
-               SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG) ;
-       }
-}
-
-/*
- * event dispatcher
- *     while event queue is not empty
- *             get event from queue
- *             send command to state machine
- *     end
- *     return error reported by individual Event function
- *             0 if no error occured.
- */
-int    SkEventDispatcher(
-SK_AC  *pAC,   /* Adapters Context */
-SK_IOC Ioc)    /* Io context */
-{
-       SK_EVENTELEM    *pEv ;  /* pointer into queue */
-       SK_U32                  Class ;
-       int                     Rtv ;
-
-       pEv = pAC->Event.EvGet ;
-       PRINTF("dispatch get %x put %x\n",pEv,pAC->Event.ev_put) ;
-       while (pEv != pAC->Event.EvPut) {
-               PRINTF("dispatch Class %d Event %d\n",pEv->Class,pEv->Event) ;
-               switch(Class = pEv->Class) {
-#ifndef SK_USE_LAC_EV
-               case SKGE_RLMT :        /* RLMT Event */
-                       Rtv = SkRlmtEvent(pAC,Ioc,pEv->Event,pEv->Para);
-                       break ;
-               case SKGE_I2C :         /* I2C Event */
-                       Rtv = SkI2cEvent(pAC,Ioc,pEv->Event,pEv->Para);
-                       break ;
-               case SKGE_PNMI :
-                       Rtv = SkPnmiEvent(pAC,Ioc,pEv->Event,pEv->Para);
-                       break ;
-#endif /* SK_USE_LAC_EV */
-               case SKGE_DRV :         /* Driver Event */
-                       Rtv = SkDrvEvent(pAC,Ioc,pEv->Event,pEv->Para);
-                       break ;
-#ifndef SK_USE_SW_TIMER
-               case SKGE_HWAC :
-                       Rtv = SkGeSirqEvent(pAC,Ioc,pEv->Event,pEv->Para);
-                       break ;
-#else /* !SK_USE_SW_TIMER */
-       case SKGE_SWT :
-                       Rtv = SkSwtEvent(pAC,Ioc,pEv->Event,pEv->Para);
-                       break ;
-#endif /* !SK_USE_SW_TIMER */
-#ifdef SK_USE_LAC_EV
-               case SKGE_LACP :
-                       Rtv = SkLacpEvent(pAC,Ioc,pEv->Event,pEv->Para);
-                       break ;
-               case SKGE_RSF :
-                       Rtv = SkRsfEvent(pAC,Ioc,pEv->Event,pEv->Para);
-                       break ;
-               case SKGE_MARKER :
-                       Rtv = SkMarkerEvent(pAC,Ioc,pEv->Event,pEv->Para);
-                       break ;
-               case SKGE_FD :
-                       Rtv = SkFdEvent(pAC,Ioc,pEv->Event,pEv->Para);
-                       break ;
-#endif /* SK_USE_LAC_EV */
-#ifdef SK_USE_CSUM
-               case SKGE_CSUM :
-                       Rtv = SkCsEvent(pAC,Ioc,pEv->Event,pEv->Para);
-                       break ;
-#endif /* SK_USE_CSUM */
-               default :
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E002,
-                               SKERR_Q_E002MSG) ;
-                       Rtv = 0;
-               }
-
-               if (Rtv != 0) {
-                       return(Rtv) ;
-               }
-
-               if (++pEv == &pAC->Event.EvQueue[SK_MAX_EVENT])
-                       pEv = pAC->Event.EvQueue ;
-
-               /* Renew get: it is used in queue_events to detect overruns */
-               pAC->Event.EvGet = pEv;
-       }
-
-       return(0) ;
-}
-
-#endif /* CONFIG_SK98 */
-
-/* End of file */
diff --git a/drivers/sk98lin/skrlmt.c b/drivers/sk98lin/skrlmt.c
deleted file mode 100644 (file)
index f8a3b41..0000000
+++ /dev/null
@@ -1,3508 +0,0 @@
-/******************************************************************************
- *
- * Name:       skrlmt.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.68 $
- * Date:       $Date: 2003/01/31 15:26:56 $
- * Purpose:    Manage links on SK-NET Adapters, esp. redundant ones.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2001 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skrlmt.c,v $
- *     Revision 1.68  2003/01/31 15:26:56  rschmidt
- *     Added init for local variables in RlmtInit().
- *
- *     Revision 1.67  2003/01/31 14:12:41  mkunz
- *     single port adapter runs now with two identical MAC addresses
- *
- *     Revision 1.66  2002/09/23 15:14:19  rwahl
- *     - Reset broadcast timestamp on link down.
- *     - Editorial corrections.
- *
- *     Revision 1.65  2002/07/22 14:29:48  rwahl
- *     - Removed BRK statement from debug check.
- *
- *     Revision 1.64  2001/11/28 19:36:14  rwahl
- *     - RLMT Packets sent to an invalid MAC address in CLP/CLPSS mode
- *       (#10650).
- *     - Reworked fix for port switching in CLS mode (#10639)
- *      (no dependency to RLMT module).
- *     - Enabled dbg output for entry/exit of event functions.
- *     - Editorial changes.
- *
- *     Revision 1.63  2001/10/26 07:53:18  afischer
- *     Port switching bug in `check local link` mode
- *
- *     Revision 1.62  2001/07/03 12:16:30  mkunz
- *     New Flag ChgBcPrio (Change priority of last broadcast received)
- *
- *     Revision 1.61  2001/03/14 12:52:08  rassmann
- *     Fixed reporting of active port up/down to PNMI.
- *
- *     Revision 1.60  2001/02/21 16:02:25  gklug
- *     fix: when RLMT starts set Active Port for PNMI
- *
- *     Revision 1.59  2001/02/16 14:38:19  rassmann
- *     Initializing some pointers earlier in the init phase.
- *     Rx Mbufs are freed if the net which they belong to is stopped.
- *
- *     Revision 1.58  2001/02/14 14:06:31  rassmann
- *     Editorial changes.
- *
- *     Revision 1.57  2001/02/05 14:25:26  rassmann
- *     Prepared RLMT for transparent operation.
- *
- *     Revision 1.56  2001/01/30 10:29:09  rassmann
- *     Not checking switching befor RlmtStart.
- *     Editorial changes.
- *
- *     Revision 1.55  2001/01/22 13:41:38  rassmann
- *     Supporting two nets on dual-port adapters.
- *
- *     Revision 1.54  2000/11/30 13:25:07  rassmann
- *     Setting SK_TICK_INCR to 1 by default.
- *
- *     Revision 1.53  2000/11/30 10:48:07  cgoos
- *     Changed definition of SK_RLMT_BC_DELTA.
- *
- *     Revision 1.52  2000/11/27 12:50:03  rassmann
- *     Checking ports after receiving broadcasts.
- *
- *     Revision 1.51  2000/11/17 08:58:00  rassmann
- *     Moved CheckSwitch from SK_RLMT_PACKET_RECEIVED to SK_RLMT_TIM event.
- *
- *     Revision 1.50  2000/11/09 12:24:34  rassmann
- *     Indicating that segmentation check is not running anymore after
- *       SkRlmtCheckSeg().
- *     Restarting segmentation timer after segmentation log.
- *     Editorial changes.
- *
- *     Revision 1.49  1999/11/22 13:38:02  cgoos
- *     Changed license header to GPL.
- *     Added initialization to some variables to avoid compiler warnings.
- *
- *     Revision 1.48  1999/10/04 14:01:17  rassmann
- *     Corrected reaction to reception of BPDU frames (#10441).
- *
- *     Revision 1.47  1999/07/20 12:53:36  rassmann
- *     Fixed documentation errors for lookahead macros.
- *
- *     Revision 1.46  1999/05/28 13:29:16  rassmann
- *     Replaced C++-style comment.
- *
- *     Revision 1.45  1999/05/28 13:28:08  rassmann
- *     Corrected syntax error (xxx).
- *
- *     Revision 1.44  1999/05/28 11:15:54  rassmann
- *     Changed behaviour to reflect Design Spec v1.2.
- *     Controlling Link LED(s).
- *     Introduced RLMT Packet Version field in RLMT Packet.
- *     Newstyle lookahead macros (checking meta-information before looking at
- *       the packet).
- *
- *     Revision 1.43  1999/01/28 13:12:43  rassmann
- *     Corrected Lookahead (bug introduced in previous Rev.).
- *
- *     Revision 1.42  1999/01/28 12:50:41  rassmann
- *     Not using broadcast time stamps in CheckLinkState mode.
- *
- *     Revision 1.41  1999/01/27 14:13:02  rassmann
- *     Monitoring broadcast traffic.
- *     Switching more reliably and not too early if switch is
- *      configured for spanning tree.
- *
- *     Revision 1.40  1999/01/22 13:17:30  rassmann
- *     Informing PNMI of NET_UP.
- *     Clearing RLMT multicast addresses before setting them for the first time.
- *     Reporting segmentation earlier, setting a "quiet time"
- *      after a report.
- *
- *     Revision 1.39  1998/12/10 15:29:53  rassmann
- *     Corrected SuspectStatus in SkRlmtBuildCheckChain().
- *     Corrected CHECK_SEG mode.
- *
- *     Revision 1.38  1998/12/08 13:11:23  rassmann
- *     Stopping SegTimer at RlmtStop.
- *
- *     Revision 1.37  1998/12/07 16:51:42  rassmann
- *     Corrected comments.
- *
- *     Revision 1.36  1998/12/04 10:58:56  rassmann
- *     Setting next pointer to NULL when receiving.
- *
- *     Revision 1.35  1998/12/03 16:12:42  rassmann
- *     Ignoring/correcting illegal PrefPort values.
- *
- *     Revision 1.34  1998/12/01 11:45:35  rassmann
- *     Code cleanup.
- *
- *     Revision 1.33  1998/12/01 10:29:32  rassmann
- *     Starting standby ports before getting the net up.
- *     Checking if a port is started when the link comes up.
- *
- *     Revision 1.32  1998/11/30 16:19:50  rassmann
- *     New default for PortNoRx.
- *
- *     Revision 1.31  1998/11/27 19:17:13  rassmann
- *     Corrected handling of LINK_DOWN coming shortly after LINK_UP.
- *
- *     Revision 1.30  1998/11/24 12:37:31  rassmann
- *     Implemented segmentation check.
- *
- *     Revision 1.29  1998/11/18 13:04:32  rassmann
- *     Secured PortUpTimer event.
- *     Waiting longer before starting standby port(s).
- *
- *     Revision 1.28  1998/11/17 13:43:04  rassmann
- *     Handling (logical) tx failure.
- *     Sending packet on logical address after PORT_SWITCH.
- *
- *     Revision 1.27  1998/11/13 17:09:50  rassmann
- *     Secured some events against being called in wrong state.
- *
- *     Revision 1.26  1998/11/13 16:56:54  rassmann
- *     Added macro version of SkRlmtLookaheadPacket.
- *
- *     Revision 1.25  1998/11/06 18:06:04  rassmann
- *     Corrected timing when RLMT checks fail.
- *     Clearing tx counter earlier in periodical checks.
- *
- *     Revision 1.24  1998/11/05 10:37:27  rassmann
- *     Checking destination address in Lookahead.
- *
- *     Revision 1.23  1998/11/03 13:53:49  rassmann
- *     RLMT should switch now (at least in mode 3).
- *
- *     Revision 1.22  1998/10/29 14:34:49  rassmann
- *     Clearing SK_RLMT struct at startup.
- *     Initializing PortsUp during SK_RLMT_START.
- *
- *     Revision 1.21  1998/10/28 11:30:17  rassmann
- *     Default mode is now SK_RLMT_CHECK_LOC_LINK.
- *
- *     Revision 1.20  1998/10/26 16:02:03  rassmann
- *     Ignoring LINK_DOWN for links that are down.
- *
- *     Revision 1.19  1998/10/22 15:54:01  rassmann
- *     Corrected EtherLen.
- *     Starting Link Check when second port comes up.
- *
- *     Revision 1.18  1998/10/22 11:39:50  rassmann
- *     Corrected signed/unsigned mismatches.
- *     Corrected receive list handling and address recognition.
- *
- *     Revision 1.17  1998/10/19 17:01:20  rassmann
- *     More detailed checking of received packets.
- *
- *     Revision 1.16  1998/10/15 15:16:34  rassmann
- *     Finished Spanning Tree checking.
- *     Checked with lint.
- *
- *     Revision 1.15  1998/09/24 19:16:07  rassmann
- *     Code cleanup.
- *     Introduced Timer for PORT_DOWN due to no RX.
- *
- *     Revision 1.14  1998/09/18 20:27:14  rassmann
- *     Added address override.
- *
- *     Revision 1.13  1998/09/16 11:31:48  rassmann
- *     Including skdrv1st.h again. :(
- *
- *     Revision 1.12  1998/09/16 11:09:50  rassmann
- *     Syntax corrections.
- *
- *     Revision 1.11  1998/09/15 12:32:03  rassmann
- *     Syntax correction.
- *
- *     Revision 1.10  1998/09/15 11:28:49  rassmann
- *     Syntax corrections.
- *
- *     Revision 1.9  1998/09/14 17:07:37  rassmann
- *     Added code for port checking via LAN.
- *     Changed Mbuf definition.
- *
- *     Revision 1.8  1998/09/07 11:14:14  rassmann
- *     Syntax corrections.
- *
- *     Revision 1.7  1998/09/07 09:06:07  rassmann
- *     Syntax corrections.
- *
- *     Revision 1.6  1998/09/04 19:41:33  rassmann
- *     Syntax corrections.
- *     Started entering code for checking local links.
- *
- *     Revision 1.5  1998/09/04 12:14:27  rassmann
- *     Interface cleanup.
- *
- *     Revision 1.4  1998/09/02 16:55:28  rassmann
- *     Updated to reflect new DRV/HWAC/RLMT interface.
- *
- *     Revision 1.3  1998/08/27 14:29:03  rassmann
- *     Code cleanup.
- *
- *     Revision 1.2  1998/08/27 14:26:24  rassmann
- *     Updated interface.
- *
- *     Revision 1.1  1998/08/21 08:26:49  rassmann
- *     First public version.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This module contains code for Link ManagemenT (LMT) of SK-NET Adapters.
- * It is mainly intended for adapters with more than one link.
- * For such adapters, this module realizes Redundant Link ManagemenT (RLMT).
- *
- * Include File Hierarchy:
- *
- *     "skdrv1st.h"
- *     "skdrv2nd.h"
- *
- ******************************************************************************/
-
-#include <config.h>
-
-#ifdef CONFIG_SK98
-
-#ifndef        lint
-static const char SysKonnectFileId[] =
-       "@(#) $Id: skrlmt.c,v 1.68 2003/01/31 15:26:56 rschmidt Exp $ (C) SysKonnect.";
-#endif /* !defined(lint) */
-
-#define __SKRLMT_C
-
-#ifdef __cplusplus
-#error C++ is not yet supported.
-extern "C" {
-#endif /* cplusplus */
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-
-/* defines ********************************************************************/
-
-#ifndef SK_HWAC_LINK_LED
-#define SK_HWAC_LINK_LED(a,b,c,d)
-#endif /* !defined(SK_HWAC_LINK_LED) */
-
-#ifndef DEBUG
-#define RLMT_STATIC    static
-#else  /* DEBUG */
-#define RLMT_STATIC
-
-#ifndef SK_LITTLE_ENDIAN
-/* First 32 bits */
-#define OFFS_LO32      1
-
-/* Second 32 bits */
-#define OFFS_HI32      0
-#else  /* SK_LITTLE_ENDIAN */
-/* First 32 bits */
-#define OFFS_LO32      0
-
-/* Second 32 bits */
-#define OFFS_HI32      1
-#endif /* SK_LITTLE_ENDIAN */
-
-#endif /* DEBUG */
-
-/* ----- Private timeout values ----- */
-
-#define SK_RLMT_MIN_TO_VAL                        125000       /* 1/8 sec. */
-#define SK_RLMT_DEF_TO_VAL                       1000000       /* 1 sec. */
-#define SK_RLMT_PORTDOWN_TIM_VAL          900000       /* another 0.9 sec. */
-#define SK_RLMT_PORTSTART_TIM_VAL         100000       /* 0.1 sec. */
-#define SK_RLMT_PORTUP_TIM_VAL           2500000       /* 2.5 sec. */
-#define SK_RLMT_SEG_TO_VAL                     900000000       /* 15 min. */
-
-/* Assume tick counter increment is 1 - may be set OS-dependent. */
-#ifndef SK_TICK_INCR
-#define SK_TICK_INCR   SK_CONSTU64(1)
-#endif /* !defined(SK_TICK_INCR) */
-
-/*
- * Amount that a time stamp must be later to be recognized as "substantially
- * later". This is about 1/128 sec, but above 1 tick counter increment.
- */
-#define SK_RLMT_BC_DELTA               (1 + ((SK_TICKS_PER_SEC >> 7) > SK_TICK_INCR ? \
-                                                                       (SK_TICKS_PER_SEC >> 7) : SK_TICK_INCR))
-
-/* ----- Private RLMT defaults ----- */
-
-#define SK_RLMT_DEF_PREF_PORT  0                                       /* "Lower" port. */
-#define SK_RLMT_DEF_MODE               SK_RLMT_CHECK_LINK      /* Default RLMT Mode. */
-
-/* ----- Private RLMT checking states ----- */
-
-#define SK_RLMT_RCS_SEG                        1               /* RLMT Check State: check seg. */
-#define SK_RLMT_RCS_START_SEG  2               /* RLMT Check State: start check seg. */
-#define SK_RLMT_RCS_SEND_SEG   4               /* RLMT Check State: send BPDU packet */
-#define SK_RLMT_RCS_REPORT_SEG 8               /* RLMT Check State: report seg. */
-
-/* ----- Private PORT checking states ----- */
-
-#define SK_RLMT_PCS_TX                 1               /* Port Check State: check tx. */
-#define SK_RLMT_PCS_RX                 2               /* Port Check State: check rx. */
-
-/* ----- Private PORT events ----- */
-
-/* Note: Update simulation when changing these. */
-#define SK_RLMT_PORTSTART_TIM  1100    /* Port start timeout. */
-#define SK_RLMT_PORTUP_TIM             1101    /* Port can now go up. */
-#define SK_RLMT_PORTDOWN_RX_TIM        1102    /* Port did not receive once ... */
-#define SK_RLMT_PORTDOWN               1103    /* Port went down. */
-#define SK_RLMT_PORTDOWN_TX_TIM        1104    /* Partner did not receive ... */
-
-/* ----- Private RLMT events ----- */
-
-/* Note: Update simulation when changing these. */
-#define SK_RLMT_TIM                            2100    /* RLMT timeout. */
-#define SK_RLMT_SEG_TIM                        2101    /* RLMT segmentation check timeout. */
-
-#define TO_SHORTEN(tim)        ((tim) / 2)
-
-/* Error numbers and messages. */
-#define SKERR_RLMT_E001                (SK_ERRBASE_RLMT + 0)
-#define SKERR_RLMT_E001_MSG    "No Packet."
-#define SKERR_RLMT_E002                (SKERR_RLMT_E001 + 1)
-#define SKERR_RLMT_E002_MSG    "Short Packet."
-#define SKERR_RLMT_E003                (SKERR_RLMT_E002 + 1)
-#define SKERR_RLMT_E003_MSG    "Unknown RLMT event."
-#define SKERR_RLMT_E004                (SKERR_RLMT_E003 + 1)
-#define SKERR_RLMT_E004_MSG    "PortsUp incorrect."
-#define SKERR_RLMT_E005                (SKERR_RLMT_E004 + 1)
-#define SKERR_RLMT_E005_MSG    \
- "Net seems to be segmented (different root bridges are reported on the ports)."
-#define SKERR_RLMT_E006                (SKERR_RLMT_E005 + 1)
-#define SKERR_RLMT_E006_MSG    "Duplicate MAC Address detected."
-#define SKERR_RLMT_E007                (SKERR_RLMT_E006 + 1)
-#define SKERR_RLMT_E007_MSG    "LinksUp incorrect."
-#define SKERR_RLMT_E008                (SKERR_RLMT_E007 + 1)
-#define SKERR_RLMT_E008_MSG    "Port not started but link came up."
-#define SKERR_RLMT_E009                (SKERR_RLMT_E008 + 1)
-#define SKERR_RLMT_E009_MSG    "Corrected illegal setting of Preferred Port."
-#define SKERR_RLMT_E010                (SKERR_RLMT_E009 + 1)
-#define SKERR_RLMT_E010_MSG    "Ignored illegal Preferred Port."
-
-/* LLC field values. */
-#define LLC_COMMAND_RESPONSE_BIT               1
-#define LLC_TEST_COMMAND                               0xE3
-#define LLC_UI                                                 0x03
-
-/* RLMT Packet fields. */
-#define        SK_RLMT_DSAP                                    0
-#define        SK_RLMT_SSAP                                    0
-#define SK_RLMT_CTRL                                   (LLC_TEST_COMMAND)
-#define SK_RLMT_INDICATOR0                             0x53    /* S */
-#define SK_RLMT_INDICATOR1                             0x4B    /* K */
-#define SK_RLMT_INDICATOR2                             0x2D    /* - */
-#define SK_RLMT_INDICATOR3                             0x52    /* R */
-#define SK_RLMT_INDICATOR4                             0x4C    /* L */
-#define SK_RLMT_INDICATOR5                             0x4D    /* M */
-#define SK_RLMT_INDICATOR6                             0x54    /* T */
-#define SK_RLMT_PACKET_VERSION                 0
-
-/* RLMT SPT Flag values. */
-#define        SK_RLMT_SPT_FLAG_CHANGE                 0x01
-#define        SK_RLMT_SPT_FLAG_CHANGE_ACK             0x80
-
-/* RLMT SPT Packet fields. */
-#define        SK_RLMT_SPT_DSAP                                0x42
-#define        SK_RLMT_SPT_SSAP                                0x42
-#define SK_RLMT_SPT_CTRL                               (LLC_UI)
-#define        SK_RLMT_SPT_PROTOCOL_ID0                0x00
-#define        SK_RLMT_SPT_PROTOCOL_ID1                0x00
-#define        SK_RLMT_SPT_PROTOCOL_VERSION_ID 0x00
-#define        SK_RLMT_SPT_BPDU_TYPE                   0x00
-#define        SK_RLMT_SPT_FLAGS                               0x00    /* ?? */
-#define        SK_RLMT_SPT_ROOT_ID0                    0xFF    /* Lowest possible priority. */
-#define        SK_RLMT_SPT_ROOT_ID1                    0xFF    /* Lowest possible priority. */
-
-/* Remaining 6 bytes will be the current port address. */
-#define        SK_RLMT_SPT_ROOT_PATH_COST0             0x00
-#define        SK_RLMT_SPT_ROOT_PATH_COST1             0x00
-#define        SK_RLMT_SPT_ROOT_PATH_COST2             0x00
-#define        SK_RLMT_SPT_ROOT_PATH_COST3             0x00
-#define        SK_RLMT_SPT_BRIDGE_ID0                  0xFF    /* Lowest possible priority. */
-#define        SK_RLMT_SPT_BRIDGE_ID1                  0xFF    /* Lowest possible priority. */
-
-/* Remaining 6 bytes will be the current port address. */
-#define        SK_RLMT_SPT_PORT_ID0                    0xFF    /* Lowest possible priority. */
-#define        SK_RLMT_SPT_PORT_ID1                    0xFF    /* Lowest possible priority. */
-#define        SK_RLMT_SPT_MSG_AGE0                    0x00
-#define        SK_RLMT_SPT_MSG_AGE1                    0x00
-#define        SK_RLMT_SPT_MAX_AGE0                    0x00
-#define        SK_RLMT_SPT_MAX_AGE1                    0xFF
-#define        SK_RLMT_SPT_HELLO_TIME0                 0x00
-#define        SK_RLMT_SPT_HELLO_TIME1                 0xFF
-#define        SK_RLMT_SPT_FWD_DELAY0                  0x00
-#define        SK_RLMT_SPT_FWD_DELAY1                  0x40
-
-/* Size defines. */
-#define SK_RLMT_MIN_PACKET_SIZE                        34
-#define SK_RLMT_MAX_PACKET_SIZE                        (SK_RLMT_MAX_TX_BUF_SIZE)
-#define SK_PACKET_DATA_LEN                             (SK_RLMT_MAX_PACKET_SIZE - \
-                                                                               SK_RLMT_MIN_PACKET_SIZE)
-
-/* ----- RLMT packet types ----- */
-#define SK_PACKET_ANNOUNCE                             1       /* Port announcement. */
-#define SK_PACKET_ALIVE                                        2       /* Alive packet to port. */
-#define SK_PACKET_ADDR_CHANGED                 3       /* Port address changed. */
-#define SK_PACKET_CHECK_TX                             4       /* Check your tx line. */
-
-#ifdef SK_LITTLE_ENDIAN
-#define SK_U16_TO_NETWORK_ORDER(Val,Addr) { \
-       SK_U8   *_Addr = (SK_U8*)(Addr); \
-       SK_U16  _Val = (SK_U16)(Val); \
-       *_Addr++ = (SK_U8)(_Val >> 8); \
-       *_Addr = (SK_U8)(_Val & 0xFF); \
-}
-#endif /* SK_LITTLE_ENDIAN */
-
-#ifdef SK_BIG_ENDIAN
-#define SK_U16_TO_NETWORK_ORDER(Val,Addr) (*(SK_U16*)(Addr) = (SK_U16)(Val))
-#endif /* SK_BIG_ENDIAN */
-
-#define AUTONEG_FAILED SK_FALSE
-#define AUTONEG_SUCCESS        SK_TRUE
-
-
-/* typedefs *******************************************************************/
-
-/* RLMT packet.  Length: SK_RLMT_MAX_PACKET_SIZE (60) bytes. */
-typedef struct s_RlmtPacket {
-       SK_U8   DstAddr[SK_MAC_ADDR_LEN];
-       SK_U8   SrcAddr[SK_MAC_ADDR_LEN];
-       SK_U8   TypeLen[2];
-       SK_U8   DSap;
-       SK_U8   SSap;
-       SK_U8   Ctrl;
-       SK_U8   Indicator[7];
-       SK_U8   RlmtPacketType[2];
-       SK_U8   Align1[2];
-       SK_U8   Random[4];                              /* Random value of requesting(!) station. */
-       SK_U8   RlmtPacketVersion[2];   /* RLMT Packet version. */
-       SK_U8   Data[SK_PACKET_DATA_LEN];
-} SK_RLMT_PACKET;
-
-typedef struct s_SpTreeRlmtPacket {
-       SK_U8   DstAddr[SK_MAC_ADDR_LEN];
-       SK_U8   SrcAddr[SK_MAC_ADDR_LEN];
-       SK_U8   TypeLen[2];
-       SK_U8   DSap;
-       SK_U8   SSap;
-       SK_U8   Ctrl;
-       SK_U8   ProtocolId[2];
-       SK_U8   ProtocolVersionId;
-       SK_U8   BpduType;
-       SK_U8   Flags;
-       SK_U8   RootId[8];
-       SK_U8   RootPathCost[4];
-       SK_U8   BridgeId[8];
-       SK_U8   PortId[2];
-       SK_U8   MessageAge[2];
-       SK_U8   MaxAge[2];
-       SK_U8   HelloTime[2];
-       SK_U8   ForwardDelay[2];
-} SK_SPTREE_PACKET;
-
-/* global variables ***********************************************************/
-
-SK_MAC_ADDR    SkRlmtMcAddr =  {{0x01,  0x00,  0x5A,  0x52,  0x4C,  0x4D}};
-SK_MAC_ADDR    BridgeMcAddr =  {{0x01,  0x80,  0xC2,  0x00,  0x00,  0x00}};
-SK_MAC_ADDR    BcAddr =                {{0xFF,  0xFF,  0xFF,  0xFF,  0xFF,  0xFF}};
-
-/* local variables ************************************************************/
-
-/* None. */
-
-/* functions ******************************************************************/
-
-RLMT_STATIC void       SkRlmtCheckSwitch(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  NetIdx);
-RLMT_STATIC void       SkRlmtCheckSeg(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  NetIdx);
-RLMT_STATIC void       SkRlmtEvtSetNets(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       SK_EVPARA       Para);
-
-/******************************************************************************
- *
- *     SkRlmtInit - initialize data, set state to init
- *
- * Description:
- *
- *     SK_INIT_DATA
- *     ============
- *
- *     This routine initializes all RLMT-related variables to a known state.
- *     The initial state is SK_RLMT_RS_INIT.
- *     All ports are initialized to SK_RLMT_PS_INIT.
- *
- *
- *     SK_INIT_IO
- *     ==========
- *
- *     Nothing.
- *
- *
- *     SK_INIT_RUN
- *     ===========
- *
- *     Determine the adapter's random value.
- *     Set the hw registers, the "logical MAC address", the
- *     RLMT multicast address, and eventually the BPDU multicast address.
- *
- * Context:
- *     init, pageable
- *
- * Returns:
- *     Nothing.
- */
-void   SkRlmtInit(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC,    /* I/O Context */
-int            Level)  /* Initialization Level */
-{
-       SK_U32          i, j;
-       SK_U64          Random;
-       SK_EVPARA       Para;
-    SK_MAC_ADDR                VirtualMacAddress;
-    SK_MAC_ADDR                PhysicalAMacAddress;
-    SK_BOOL            VirtualMacAddressSet;
-    SK_BOOL            PhysicalAMacAddressSet;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
-               ("RLMT Init level %d.\n", Level))
-
-       switch (Level) {
-       case SK_INIT_DATA:      /* Initialize data structures. */
-               SK_MEMSET((char *)&pAC->Rlmt, 0, sizeof(SK_RLMT));
-
-               for (i = 0; i < SK_MAX_MACS; i++) {
-                       pAC->Rlmt.Port[i].PortState = SK_RLMT_PS_INIT;
-                       pAC->Rlmt.Port[i].LinkDown = SK_TRUE;
-                       pAC->Rlmt.Port[i].PortDown = SK_TRUE;
-                       pAC->Rlmt.Port[i].PortStarted = SK_FALSE;
-                       pAC->Rlmt.Port[i].PortNoRx = SK_FALSE;
-                       pAC->Rlmt.Port[i].RootIdSet = SK_FALSE;
-                       pAC->Rlmt.Port[i].PortNumber = i;
-                       pAC->Rlmt.Port[i].Net = &pAC->Rlmt.Net[0];
-                       pAC->Rlmt.Port[i].AddrPort = &pAC->Addr.Port[i];
-               }
-
-               pAC->Rlmt.NumNets = 1;
-               for (i = 0; i < SK_MAX_NETS; i++) {
-                       pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
-                       pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
-                       pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
-                       pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF;         /* Automatic. */
-                       /* Just assuming. */
-                       pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
-                       pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
-                       pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
-                       pAC->Rlmt.Net[i].NetNumber = i;
-               }
-
-               pAC->Rlmt.Net[0].Port[0] = &pAC->Rlmt.Port[0];
-               pAC->Rlmt.Net[0].Port[1] = &pAC->Rlmt.Port[1];
-#if SK_MAX_NETS > 1
-               pAC->Rlmt.Net[1].Port[0] = &pAC->Rlmt.Port[1];
-#endif /* SK_MAX_NETS > 1 */
-               break;
-
-       case SK_INIT_IO:        /* GIMacsFound first available here. */
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
-                       ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound))
-
-               pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
-
-               /* Initialize HW registers? */
-               if (pAC->GIni.GIMacsFound == 1) {
-                       Para.Para32[0] = SK_RLMT_MODE_CLS;
-                       Para.Para32[1] = 0;
-                       (void)SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, Para);
-               }
-               break;
-
-       case SK_INIT_RUN:
-               /* Ensure RLMT is set to one net. */
-               if (pAC->Rlmt.NumNets > 1) {
-                       Para.Para32[0] = 1;
-                       Para.Para32[1] = -1;
-                       SkRlmtEvtSetNets(pAC, IoC, Para);
-               }
-
-               for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-                       Random = SkOsGetTime(pAC);
-                       *(SK_U32*)&pAC->Rlmt.Port[i].Random = *(SK_U32*)&Random;
-
-                       for (j = 0; j < 4; j++) {
-                               pAC->Rlmt.Port[i].Random[j] ^= pAC->Rlmt.Port[i].AddrPort->
-                                       CurrentMacAddress.a[SK_MAC_ADDR_LEN - 1 - j];
-                       }
-
-                       (void)SkAddrMcClear(pAC, IoC, i, SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
-
-                       /* Add RLMT MC address. */
-                       (void)SkAddrMcAdd(pAC, IoC, i, &SkRlmtMcAddr, SK_ADDR_PERMANENT);
-
-                       if (pAC->Rlmt.Net[0].RlmtMode & SK_RLMT_CHECK_SEG) {
-                               /* Add BPDU MC address. */
-                               (void)SkAddrMcAdd(pAC, IoC, i, &BridgeMcAddr, SK_ADDR_PERMANENT);
-                       }
-
-                       (void)SkAddrMcUpdate(pAC, IoC, i);
-               }
-
-       VirtualMacAddressSet = SK_FALSE;
-               /* Read virtual MAC address from Control Register File. */
-               for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
-
-           SK_IN8(IoC, B2_MAC_1 + j, &VirtualMacAddress.a[j]);
-           VirtualMacAddressSet |= VirtualMacAddress.a[j];
-               }
-
-       PhysicalAMacAddressSet = SK_FALSE;
-               /* Read physical MAC address for MAC A from Control Register File. */
-               for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
-
-           SK_IN8(IoC, B2_MAC_2 + j, &PhysicalAMacAddress.a[j]);
-           PhysicalAMacAddressSet |= PhysicalAMacAddress.a[j];
-               }
-
-       /* check if the two mac addresses contain reasonable values */
-       if (!VirtualMacAddressSet || !PhysicalAMacAddressSet) {
-
-           pAC->Rlmt.RlmtOff = SK_TRUE;
-       }
-
-       /* if the two mac addresses are equal switch off the RLMT_PRE_LOOKAHEAD
-          and the RLMT_LOOKAHEAD macros */
-       else if (SK_ADDR_EQUAL(PhysicalAMacAddress.a, VirtualMacAddress.a)) {
-
-           pAC->Rlmt.RlmtOff = SK_TRUE;
-       }
-               else {
-                       pAC->Rlmt.RlmtOff = SK_FALSE;
-               }
-               break;
-
-       default:        /* error */
-               break;
-       }
-       return;
-}      /* SkRlmtInit */
-
-
-/******************************************************************************
- *
- *     SkRlmtBuildCheckChain - build the check chain
- *
- * Description:
- *     This routine builds the local check chain:
- *     - Each port that is up checks the next port.
- *     - The last port that is up checks the first port that is up.
- *
- * Notes:
- *     - Currently only local ports are considered when building the chain.
- *     - Currently the SuspectState is just reset;
- *       it would be better to save it ...
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtBuildCheckChain(
-SK_AC  *pAC,   /* Adapter Context */
-SK_U32 NetIdx) /* Net Number */
-{
-       SK_U32                  i;
-       SK_U32                  NumMacsUp;
-       SK_RLMT_PORT *  FirstMacUp;
-       SK_RLMT_PORT *  PrevMacUp;
-
-       FirstMacUp      = NULL;
-       PrevMacUp       = NULL;
-
-       if (!(pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
-               for (i = 0; i < pAC->Rlmt.Net[i].NumPorts; i++) {
-                       pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
-               }
-               return; /* Done. */
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SkRlmtBuildCheckChain.\n"))
-
-       NumMacsUp = 0;
-
-       for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
-               pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
-               pAC->Rlmt.Net[NetIdx].Port[i]->PortsSuspect = 0;
-               pAC->Rlmt.Net[NetIdx].Port[i]->CheckingState &=
-                       ~(SK_RLMT_PCS_RX | SK_RLMT_PCS_TX);
-
-               /*
-                * If more than two links are detected we should consider
-                * checking at least two other ports:
-                * 1. the next port that is not LinkDown and
-                * 2. the next port that is not PortDown.
-                */
-               if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
-                       if (NumMacsUp == 0) {
-                               FirstMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
-                       }
-                       else {
-                               PrevMacUp->PortCheck[
-                                       pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked].CheckAddr =
-                                       pAC->Rlmt.Net[NetIdx].Port[i]->AddrPort->CurrentMacAddress;
-                               PrevMacUp->PortCheck[
-                                       PrevMacUp->PortsChecked].SuspectTx = SK_FALSE;
-                               PrevMacUp->PortsChecked++;
-                       }
-                       PrevMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
-                       NumMacsUp++;
-               }
-       }
-
-       if (NumMacsUp > 1) {
-               PrevMacUp->PortCheck[PrevMacUp->PortsChecked].CheckAddr =
-                       FirstMacUp->AddrPort->CurrentMacAddress;
-               PrevMacUp->PortCheck[PrevMacUp->PortsChecked].SuspectTx =
-                       SK_FALSE;
-               PrevMacUp->PortsChecked++;
-       }
-
-#ifdef DEBUG
-       for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Port %d checks %d other ports: %2X.\n", i,
-                               pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked,
-                               pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5]))
-       }
-#endif /* DEBUG */
-
-       return;
-}      /* SkRlmtBuildCheckChain */
-
-
-/******************************************************************************
- *
- *     SkRlmtBuildPacket - build an RLMT packet
- *
- * Description:
- *     This routine sets up an RLMT packet.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     NULL or pointer to RLMT mbuf
- */
-RLMT_STATIC SK_MBUF    *SkRlmtBuildPacket(
-SK_AC          *pAC,           /* Adapter Context */
-SK_IOC         IoC,            /* I/O Context */
-SK_U32         PortNumber,     /* Sending port */
-SK_U16         PacketType,     /* RLMT packet type */
-SK_MAC_ADDR    *SrcAddr,       /* Source address */
-SK_MAC_ADDR    *DestAddr)      /* Destination address */
-{
-       int             i;
-       SK_U16          Length;
-       SK_MBUF         *pMb;
-       SK_RLMT_PACKET  *pPacket;
-
-#ifdef DEBUG
-       SK_U8   CheckSrc  = 0;
-       SK_U8   CheckDest = 0;
-
-       for (i = 0; i < SK_MAC_ADDR_LEN; ++i) {
-               CheckSrc  |= SrcAddr->a[i];
-               CheckDest |= DestAddr->a[i];
-       }
-
-       if ((CheckSrc == 0) || (CheckDest == 0)) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_ERR,
-                       ("SkRlmtBuildPacket: Invalid %s%saddr.\n",
-                        (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : "")))
-       }
-#endif
-
-       if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) != NULL) {
-               pPacket = (SK_RLMT_PACKET*)pMb->pData;
-               for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
-                       pPacket->DstAddr[i] = DestAddr->a[i];
-                       pPacket->SrcAddr[i] = SrcAddr->a[i];
-               }
-               pPacket->DSap = SK_RLMT_DSAP;
-               pPacket->SSap = SK_RLMT_SSAP;
-               pPacket->Ctrl = SK_RLMT_CTRL;
-               pPacket->Indicator[0] = SK_RLMT_INDICATOR0;
-               pPacket->Indicator[1] = SK_RLMT_INDICATOR1;
-               pPacket->Indicator[2] = SK_RLMT_INDICATOR2;
-               pPacket->Indicator[3] = SK_RLMT_INDICATOR3;
-               pPacket->Indicator[4] = SK_RLMT_INDICATOR4;
-               pPacket->Indicator[5] = SK_RLMT_INDICATOR5;
-               pPacket->Indicator[6] = SK_RLMT_INDICATOR6;
-
-               SK_U16_TO_NETWORK_ORDER(PacketType, &pPacket->RlmtPacketType[0]);
-
-               for (i = 0; i < 4; i++) {
-                       pPacket->Random[i] = pAC->Rlmt.Port[PortNumber].Random[i];
-               }
-
-               SK_U16_TO_NETWORK_ORDER(
-                       SK_RLMT_PACKET_VERSION, &pPacket->RlmtPacketVersion[0]);
-
-               for (i = 0; i < SK_PACKET_DATA_LEN; i++) {
-                       pPacket->Data[i] = 0x00;
-               }
-
-               Length = SK_RLMT_MAX_PACKET_SIZE;       /* Or smaller. */
-               pMb->Length = Length;
-               pMb->PortIdx = PortNumber;
-               Length -= 14;
-               SK_U16_TO_NETWORK_ORDER(Length, &pPacket->TypeLen[0]);
-
-               if (PacketType == SK_PACKET_ALIVE) {
-                       pAC->Rlmt.Port[PortNumber].TxHelloCts++;
-               }
-       }
-
-       return (pMb);
-}      /* SkRlmtBuildPacket */
-
-
-/******************************************************************************
- *
- *     SkRlmtBuildSpanningTreePacket - build spanning tree check packet
- *
- * Description:
- *     This routine sets up a BPDU packet for spanning tree check.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     NULL or pointer to RLMT mbuf
- */
-RLMT_STATIC SK_MBUF    *SkRlmtBuildSpanningTreePacket(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-SK_U32 PortNumber)     /* Sending port */
-{
-       unsigned                        i;
-       SK_U16                          Length;
-       SK_MBUF                         *pMb;
-       SK_SPTREE_PACKET        *pSPacket;
-
-       if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) !=
-               NULL) {
-               pSPacket = (SK_SPTREE_PACKET*)pMb->pData;
-               for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
-                       pSPacket->DstAddr[i] = BridgeMcAddr.a[i];
-                       pSPacket->SrcAddr[i] =
-                               pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
-               }
-               pSPacket->DSap = SK_RLMT_SPT_DSAP;
-               pSPacket->SSap = SK_RLMT_SPT_SSAP;
-               pSPacket->Ctrl = SK_RLMT_SPT_CTRL;
-
-               pSPacket->ProtocolId[0] = SK_RLMT_SPT_PROTOCOL_ID0;
-               pSPacket->ProtocolId[1] = SK_RLMT_SPT_PROTOCOL_ID1;
-               pSPacket->ProtocolVersionId = SK_RLMT_SPT_PROTOCOL_VERSION_ID;
-               pSPacket->BpduType = SK_RLMT_SPT_BPDU_TYPE;
-               pSPacket->Flags = SK_RLMT_SPT_FLAGS;
-               pSPacket->RootId[0] = SK_RLMT_SPT_ROOT_ID0;
-               pSPacket->RootId[1] = SK_RLMT_SPT_ROOT_ID1;
-               pSPacket->RootPathCost[0] = SK_RLMT_SPT_ROOT_PATH_COST0;
-               pSPacket->RootPathCost[1] = SK_RLMT_SPT_ROOT_PATH_COST1;
-               pSPacket->RootPathCost[2] = SK_RLMT_SPT_ROOT_PATH_COST2;
-               pSPacket->RootPathCost[3] = SK_RLMT_SPT_ROOT_PATH_COST3;
-               pSPacket->BridgeId[0] = SK_RLMT_SPT_BRIDGE_ID0;
-               pSPacket->BridgeId[1] = SK_RLMT_SPT_BRIDGE_ID1;
-
-               /*
-                * Use logical MAC address as bridge ID and filter these packets
-                * on receive.
-                */
-               for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
-                       pSPacket->BridgeId[i + 2] = pSPacket->RootId[i + 2] =
-                               pAC->Addr.Net[pAC->Rlmt.Port[PortNumber].Net->NetNumber].
-                                       CurrentMacAddress.a[i];
-               }
-               pSPacket->PortId[0] = SK_RLMT_SPT_PORT_ID0;
-               pSPacket->PortId[1] = SK_RLMT_SPT_PORT_ID1;
-               pSPacket->MessageAge[0] = SK_RLMT_SPT_MSG_AGE0;
-               pSPacket->MessageAge[1] = SK_RLMT_SPT_MSG_AGE1;
-               pSPacket->MaxAge[0] = SK_RLMT_SPT_MAX_AGE0;
-               pSPacket->MaxAge[1] = SK_RLMT_SPT_MAX_AGE1;
-               pSPacket->HelloTime[0] = SK_RLMT_SPT_HELLO_TIME0;
-               pSPacket->HelloTime[1] = SK_RLMT_SPT_HELLO_TIME1;
-               pSPacket->ForwardDelay[0] = SK_RLMT_SPT_FWD_DELAY0;
-               pSPacket->ForwardDelay[1] = SK_RLMT_SPT_FWD_DELAY1;
-
-               Length = SK_RLMT_MAX_PACKET_SIZE;       /* Or smaller. */
-               pMb->Length = Length;
-               pMb->PortIdx = PortNumber;
-               Length -= 14;
-               SK_U16_TO_NETWORK_ORDER(Length, &pSPacket->TypeLen[0]);
-
-               pAC->Rlmt.Port[PortNumber].TxSpHelloReqCts++;
-       }
-
-       return (pMb);
-}      /* SkRlmtBuildSpanningTreePacket */
-
-
-/******************************************************************************
- *
- *     SkRlmtSend - build and send check packets
- *
- * Description:
- *     Depending on the RLMT state and the checking state, several packets
- *     are sent through the indicated port.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     Nothing.
- */
-RLMT_STATIC void       SkRlmtSend(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-SK_U32 PortNumber)     /* Sending port */
-{
-       unsigned        j;
-       SK_EVPARA       Para;
-       SK_RLMT_PORT    *pRPort;
-
-       pRPort = &pAC->Rlmt.Port[PortNumber];
-       if (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
-               if (pRPort->CheckingState & (SK_RLMT_PCS_TX | SK_RLMT_PCS_RX)) {
-                       /* Port is suspicious. Send the RLMT packet to the RLMT mc addr. */
-                       if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
-                               SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
-                               &SkRlmtMcAddr)) != NULL) {
-                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
-                       }
-               }
-               else {
-                       /*
-                        * Send a directed RLMT packet to all ports that are
-                        * checked by the indicated port.
-                        */
-                       for (j = 0; j < pRPort->PortsChecked; j++) {
-                               if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
-                                       SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
-                                       &pRPort->PortCheck[j].CheckAddr)) != NULL) {
-                                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
-                               }
-                       }
-               }
-       }
-
-       if ((pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
-               (pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEND_SEG)) {
-               /*
-                * Send a BPDU packet to make a connected switch tell us
-                * the correct root bridge.
-                */
-               if ((Para.pParaPtr =
-                       SkRlmtBuildSpanningTreePacket(pAC, IoC, PortNumber)) != NULL) {
-                       pAC->Rlmt.Port[PortNumber].Net->CheckingState &= ~SK_RLMT_RCS_SEND_SEG;
-                       pRPort->RootIdSet = SK_FALSE;
-
-                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX,
-                               ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber))
-               }
-       }
-       return;
-}      /* SkRlmtSend */
-
-
-/******************************************************************************
- *
- *     SkRlmtPortReceives - check if port is (going) down and bring it up
- *
- * Description:
- *     This routine checks if a port who received a non-BPDU packet
- *     needs to go up or needs to be stopped going down.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     Nothing.
- */
-RLMT_STATIC void       SkRlmtPortReceives(
-SK_AC  *pAC,                   /* Adapter Context */
-SK_IOC IoC,                    /* I/O Context */
-SK_U32 PortNumber)             /* Port to check */
-{
-       SK_RLMT_PORT    *pRPort;
-       SK_EVPARA               Para;
-
-       pRPort = &pAC->Rlmt.Port[PortNumber];
-       pRPort->PortNoRx = SK_FALSE;
-
-       if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
-               !(pRPort->CheckingState & SK_RLMT_PCS_TX)) {
-               /*
-                * Port is marked down (rx), but received a non-BPDU packet.
-                * Bring it up.
-                */
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                       ("SkRlmtPacketReceive: Received on PortDown.\n"))
-
-               pRPort->PortState = SK_RLMT_PS_GOING_UP;
-               pRPort->GuTimeStamp = SkOsGetTime(pAC);
-               Para.Para32[0] = PortNumber;
-               Para.Para32[1] = (SK_U32)-1;
-               SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
-                       SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para);
-               pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
-               /* pAC->Rlmt.CheckSwitch = SK_TRUE; */
-               SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
-       }       /* PortDown && !SuspectTx */
-       else if (pRPort->CheckingState & SK_RLMT_PCS_RX) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                       ("SkRlmtPacketReceive: Stop bringing port down.\n"))
-               SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
-               pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
-               /* pAC->Rlmt.CheckSwitch = SK_TRUE; */
-               SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
-       }       /* PortGoingDown */
-
-       return;
-}      /* SkRlmtPortReceives */
-
-
-/******************************************************************************
- *
- *     SkRlmtPacketReceive - receive a packet for closer examination
- *
- * Description:
- *     This routine examines a packet more closely than SK_RLMT_LOOKAHEAD.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     Nothing.
- */
-RLMT_STATIC void       SkRlmtPacketReceive(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC,    /* I/O Context */
-SK_MBUF        *pMb)   /* Received packet */
-{
-#ifdef xDEBUG
-       extern  void DumpData(char *p, int size);
-#endif /* DEBUG */
-       int                                     i;
-       unsigned                        j;
-       SK_U16                          PacketType;
-       SK_U32                          PortNumber;
-       SK_ADDR_PORT            *pAPort;
-       SK_RLMT_PORT            *pRPort;
-       SK_RLMT_PACKET          *pRPacket;
-       SK_SPTREE_PACKET        *pSPacket;
-       SK_EVPARA                       Para;
-
-       PortNumber      = pMb->PortIdx;
-       pAPort = &pAC->Addr.Port[PortNumber];
-       pRPort = &pAC->Rlmt.Port[PortNumber];
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-               ("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber))
-
-       pRPacket = (SK_RLMT_PACKET*)pMb->pData;
-       pSPacket = (SK_SPTREE_PACKET*)pRPacket;
-
-#ifdef xDEBUG
-       DumpData((char *)pRPacket, 32);
-#endif /* DEBUG */
-
-       if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) != 0) {
-               SkRlmtPortReceives(pAC, IoC, PortNumber);
-       }
-
-       /* Check destination address. */
-
-       if (!SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->DstAddr) &&
-               !SK_ADDR_EQUAL(SkRlmtMcAddr.a, pRPacket->DstAddr) &&
-               !SK_ADDR_EQUAL(BridgeMcAddr.a, pRPacket->DstAddr)) {
-
-               /* Not sent to current MAC or registered MC address => Trash it. */
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                       ("SkRlmtPacketReceive: Not for me.\n"))
-
-               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-               return;
-       }
-       else if (SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->SrcAddr)) {
-
-               /*
-                * Was sent by same port (may happen during port switching
-                * or in case of duplicate MAC addresses).
-                */
-
-               /*
-                * Check for duplicate address here:
-                * If Packet.Random != My.Random => DupAddr.
-                */
-               for (i = 3; i >= 0; i--) {
-                       if (pRPort->Random[i] != pRPacket->Random[i]) {
-                               break;
-                       }
-               }
-
-               /*
-                * CAUTION: Do not check for duplicate MAC address in RLMT Alive Reply
-                * packets (they have the LLC_COMMAND_RESPONSE_BIT set in
-                * pRPacket->SSap).
-                */
-               if (i >= 0 && pRPacket->DSap == SK_RLMT_DSAP &&
-                       pRPacket->Ctrl == SK_RLMT_CTRL &&
-                       pRPacket->SSap == SK_RLMT_SSAP &&
-                       pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&
-                       pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&
-                       pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&
-                       pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&
-                       pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&
-                       pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
-                       pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                               ("SkRlmtPacketReceive: Duplicate MAC Address.\n"))
-
-                       /* Error Log entry. */
-                       SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E006, SKERR_RLMT_E006_MSG);
-               }
-               else {
-                       /* Simply trash it. */
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                               ("SkRlmtPacketReceive: Sent by me.\n"))
-               }
-
-               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-               return;
-       }
-
-       /* Check SuspectTx entries. */
-       if (pRPort->PortsSuspect > 0) {
-               for (j = 0; j < pRPort->PortsChecked; j++) {
-                       if (pRPort->PortCheck[j].SuspectTx &&
-                               SK_ADDR_EQUAL(
-                                       pRPacket->SrcAddr, pRPort->PortCheck[j].CheckAddr.a)) {
-                               pRPort->PortCheck[j].SuspectTx = SK_FALSE;
-                               pRPort->PortsSuspect--;
-                               break;
-                       }
-               }
-       }
-
-       /* Determine type of packet. */
-       if (pRPacket->DSap == SK_RLMT_DSAP &&
-               pRPacket->Ctrl == SK_RLMT_CTRL &&
-               (pRPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SSAP &&
-               pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&
-               pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&
-               pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&
-               pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&
-               pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&
-               pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
-               pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
-
-               /* It's an RLMT packet. */
-               PacketType = (SK_U16)((pRPacket->RlmtPacketType[0] << 8) |
-                       pRPacket->RlmtPacketType[1]);
-
-               switch (PacketType) {
-               case SK_PACKET_ANNOUNCE:        /* Not yet used. */
-#if 0
-                       /* Build the check chain. */
-                       SkRlmtBuildCheckChain(pAC);
-#endif /* 0 */
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                               ("SkRlmtPacketReceive: Announce.\n"))
-
-                       SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-                       break;
-
-               case SK_PACKET_ALIVE:
-                       if (pRPacket->SSap & LLC_COMMAND_RESPONSE_BIT) {
-                               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                                       ("SkRlmtPacketReceive: Alive Reply.\n"))
-
-                               if (!(pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_LLC) ||
-                                       SK_ADDR_EQUAL(
-                                               pRPacket->DstAddr, pAPort->CurrentMacAddress.a)) {
-                                       /* Obviously we could send something. */
-                                       if (pRPort->CheckingState & SK_RLMT_PCS_TX) {
-                                               pRPort->CheckingState &=  ~SK_RLMT_PCS_TX;
-                                               SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
-                                       }
-
-                                       if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
-                                               !(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
-                                               pRPort->PortState = SK_RLMT_PS_GOING_UP;
-                                               pRPort->GuTimeStamp = SkOsGetTime(pAC);
-
-                                               SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
-
-                                               Para.Para32[0] = PortNumber;
-                                               Para.Para32[1] = (SK_U32)-1;
-                                               SkTimerStart(pAC, IoC, &pRPort->UpTimer,
-                                                       SK_RLMT_PORTUP_TIM_VAL, SKGE_RLMT,
-                                                       SK_RLMT_PORTUP_TIM, Para);
-                                       }
-                               }
-
-                               /* Mark sending port as alive? */
-                               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-                       }
-                       else {  /* Alive Request Packet. */
-                               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                                       ("SkRlmtPacketReceive: Alive Request.\n"))
-
-                               pRPort->RxHelloCts++;
-
-                               /* Answer. */
-                               for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
-                                       pRPacket->DstAddr[i] = pRPacket->SrcAddr[i];
-                                       pRPacket->SrcAddr[i] =
-                                               pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
-                               }
-                               pRPacket->SSap |= LLC_COMMAND_RESPONSE_BIT;
-
-                               Para.pParaPtr = pMb;
-                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
-                       }
-                       break;
-
-               case SK_PACKET_CHECK_TX:
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                               ("SkRlmtPacketReceive: Check your tx line.\n"))
-
-                       /* A port checking us requests us to check our tx line. */
-                       pRPort->CheckingState |= SK_RLMT_PCS_TX;
-
-                       /* Start PortDownTx timer. */
-                       Para.Para32[0] = PortNumber;
-                       Para.Para32[1] = (SK_U32)-1;
-                       SkTimerStart(pAC, IoC, &pRPort->DownTxTimer,
-                               SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
-                               SK_RLMT_PORTDOWN_TX_TIM, Para);
-
-                       SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-
-                       if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
-                               SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
-                               &SkRlmtMcAddr)) != NULL) {
-                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
-                       }
-                       break;
-
-               case SK_PACKET_ADDR_CHANGED:
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                               ("SkRlmtPacketReceive: Address Change.\n"))
-
-                       /* Build the check chain. */
-                       SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
-                       SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-                       break;
-
-               default:
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                               ("SkRlmtPacketReceive: Unknown RLMT packet.\n"))
-
-                       /* RA;:;: ??? */
-                       SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-               }
-       }
-       else if (pSPacket->DSap == SK_RLMT_SPT_DSAP &&
-               pSPacket->Ctrl == SK_RLMT_SPT_CTRL &&
-               (pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SPT_SSAP) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                       ("SkRlmtPacketReceive: BPDU Packet.\n"))
-
-               /* Spanning Tree packet. */
-               pRPort->RxSpHelloCts++;
-
-               if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pAC->Addr.Net[pAC->Rlmt.
-                       Port[PortNumber].Net->NetNumber].CurrentMacAddress.a[0])) {
-                       /*
-                        * Check segmentation if a new root bridge is set and
-                        * the segmentation check is not currently running.
-                        */
-                       if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pRPort->Root.Id[2]) &&
-                               (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
-                               (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG)
-                               != 0 && (pAC->Rlmt.Port[PortNumber].Net->CheckingState &
-                               SK_RLMT_RCS_SEG) == 0) {
-                               pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
-                                       SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
-                       }
-
-                       /* Store tree view of this port. */
-                       for (i = 0; i < 8; i++) {
-                               pRPort->Root.Id[i] = pSPacket->RootId[i];
-                       }
-                       pRPort->RootIdSet = SK_TRUE;
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
-                               ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
-                                       PortNumber,
-                                       pRPort->Root.Id[0], pRPort->Root.Id[1],
-                                       pRPort->Root.Id[2], pRPort->Root.Id[3],
-                                       pRPort->Root.Id[4], pRPort->Root.Id[5],
-                                       pRPort->Root.Id[6], pRPort->Root.Id[7]))
-               }
-
-               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-               if ((pAC->Rlmt.Port[PortNumber].Net->CheckingState &
-                       SK_RLMT_RCS_REPORT_SEG) != 0) {
-                       SkRlmtCheckSeg(pAC, IoC, pAC->Rlmt.Port[PortNumber].Net->NetNumber);
-               }
-       }
-       else {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                       ("SkRlmtPacketReceive: Unknown Packet Type.\n"))
-
-               /* Unknown packet. */
-               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-       }
-       return;
-}      /* SkRlmtPacketReceive */
-
-
-/******************************************************************************
- *
- *     SkRlmtCheckPort - check if a port works
- *
- * Description:
- *     This routine checks if a port whose link is up received something
- *     and if it seems to transmit successfully.
- *
- *     # PortState: PsInit, PsLinkDown, PsDown, PsGoingUp, PsUp
- *     # PortCheckingState (Bitfield): ChkTx, ChkRx, ChkSeg
- *     # RlmtCheckingState (Bitfield): ChkSeg, StartChkSeg, ReportSeg
- *
- *     if (Rx - RxBpdu == 0) { # No rx.
- *             if (state == PsUp) {
- *                     PortCheckingState |= ChkRx
- *             }
- *             if (ModeCheckSeg && (Timeout ==
- *                     TO_SHORTEN(RLMT_DEFAULT_TIMEOUT))) {
- *                     RlmtCheckingState |= ChkSeg)
- *                     PortCheckingState |= ChkSeg
- *             }
- *             NewTimeout = TO_SHORTEN(Timeout)
- *             if (NewTimeout < RLMT_MIN_TIMEOUT) {
- *                     NewTimeout = RLMT_MIN_TIMEOUT
- *                     PortState = PsDown
- *                     ...
- *             }
- *     }
- *     else {  # something was received
- *             # Set counter to 0 at LinkDown?
- *             #   No - rx may be reported after LinkDown ???
- *             PortCheckingState &= ~ChkRx
- *             NewTimeout = RLMT_DEFAULT_TIMEOUT
- *             if (RxAck == 0) {
- *                     possible reasons:
- *                     is my tx line bad? --
- *                             send RLMT multicast and report
- *                             back internally? (only possible
- *                             between ports on same adapter)
- *             }
- *             if (RxChk == 0) {
- *                     possible reasons:
- *                     - tx line of port set to check me
- *                       maybe bad
- *                     - no other port/adapter available or set
- *                       to check me
- *                     - adapter checking me has a longer
- *                       timeout
- *                     ??? anything that can be done here?
- *             }
- *     }
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     New timeout value.
- */
-RLMT_STATIC SK_U32     SkRlmtCheckPort(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-SK_U32 PortNumber)     /* Port to check */
-{
-       unsigned                i;
-       SK_U32                  NewTimeout;
-       SK_RLMT_PORT    *pRPort;
-       SK_EVPARA               Para;
-
-       pRPort = &pAC->Rlmt.Port[PortNumber];
-
-       if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) == 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SkRlmtCheckPort %d: No (%d) receives in last time slot.\n",
-                               PortNumber, pRPort->PacketsPerTimeSlot))
-
-               /*
-                * Check segmentation if there was no receive at least twice
-                * in a row (PortNoRx is already set) and the segmentation
-                * check is not currently running.
-                */
-
-               if (pRPort->PortNoRx && (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
-                       (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
-                       !(pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEG)) {
-                       pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
-                               SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
-               }
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SkRlmtCheckPort: PortsSuspect %d, PcsRx %d.\n",
-                               pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX))
-
-               if (pRPort->PortState != SK_RLMT_PS_DOWN) {
-                       NewTimeout = TO_SHORTEN(pAC->Rlmt.Port[PortNumber].Net->TimeoutValue);
-                       if (NewTimeout < SK_RLMT_MIN_TO_VAL) {
-                               NewTimeout = SK_RLMT_MIN_TO_VAL;
-                       }
-
-                       if (!(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
-                               Para.Para32[0] = PortNumber;
-                               pRPort->CheckingState |= SK_RLMT_PCS_RX;
-
-                               /*
-                                * What shall we do if the port checked by this one receives
-                                * our request frames?  What's bad - our rx line or his tx line?
-                                */
-                               Para.Para32[1] = (SK_U32)-1;
-                               SkTimerStart(pAC, IoC, &pRPort->DownRxTimer,
-                                       SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
-                                       SK_RLMT_PORTDOWN_RX_TIM, Para);
-
-                               for (i = 0; i < pRPort->PortsChecked; i++) {
-                                       if (pRPort->PortCheck[i].SuspectTx) {
-                                               continue;
-                                       }
-                                       pRPort->PortCheck[i].SuspectTx = SK_TRUE;
-                                       pRPort->PortsSuspect++;
-                                       if ((Para.pParaPtr =
-                                               SkRlmtBuildPacket(pAC, IoC, PortNumber, SK_PACKET_CHECK_TX,
-                                                       &pAC->Addr.Port[PortNumber].CurrentMacAddress,
-                                                       &pRPort->PortCheck[i].CheckAddr)) != NULL) {
-                                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
-                                       }
-                               }
-                       }
-               }
-               else {  /* PortDown -- or all partners suspect. */
-                       NewTimeout = SK_RLMT_DEF_TO_VAL;
-               }
-               pRPort->PortNoRx = SK_TRUE;
-       }
-       else {  /* A non-BPDU packet was received. */
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SkRlmtCheckPort %d: %d (%d) receives in last time slot.\n",
-                               PortNumber,
-                               pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot,
-                               pRPort->PacketsPerTimeSlot))
-
-               SkRlmtPortReceives(pAC, IoC, PortNumber);
-               if (pAC->Rlmt.CheckSwitch) {
-                       SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
-               }
-
-               NewTimeout = SK_RLMT_DEF_TO_VAL;
-       }
-
-       return (NewTimeout);
-}      /* SkRlmtCheckPort */
-
-
-/******************************************************************************
- *
- *     SkRlmtSelectBcRx - select new active port, criteria 1 (CLP)
- *
- * Description:
- *     This routine selects the port that received a broadcast frame
- *     substantially later than all other ports.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     SK_BOOL
- */
-RLMT_STATIC SK_BOOL    SkRlmtSelectBcRx(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-SK_U32 Active,         /* Active port */
-SK_U32 PrefPort,       /* Preferred port */
-SK_U32 *pSelect)       /* New active port */
-{
-       SK_U64          BcTimeStamp;
-       SK_U32          i;
-       SK_BOOL         PortFound;
-
-       BcTimeStamp = 0;        /* Not totally necessary, but feeling better. */
-       PortFound = SK_FALSE;
-
-       /* Select port with the latest TimeStamp. */
-       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("TimeStamp Port %d (Down: %d, NoRx: %d): %08x %08x.\n",
-                               i,
-                               pAC->Rlmt.Port[i].PortDown, pAC->Rlmt.Port[i].PortNoRx,
-                               *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32),
-                               *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32)))
-
-               if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx) {
-                       if (!PortFound || pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) {
-                               BcTimeStamp = pAC->Rlmt.Port[i].BcTimeStamp;
-                               *pSelect = i;
-                               PortFound = SK_TRUE;
-                       }
-               }
-       }
-
-       if (PortFound) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Port %d received the last broadcast.\n", *pSelect))
-
-               /* Look if another port's time stamp is similar. */
-               for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-                       if (i == *pSelect) {
-                               continue;
-                       }
-                       if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx &&
-                               (pAC->Rlmt.Port[i].BcTimeStamp >
-                                BcTimeStamp - SK_RLMT_BC_DELTA ||
-                               pAC->Rlmt.Port[i].BcTimeStamp +
-                                SK_RLMT_BC_DELTA > BcTimeStamp)) {
-                               PortFound = SK_FALSE;
-
-                               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                                       ("Port %d received a broadcast at a similar time.\n", i))
-                               break;
-                       }
-               }
-       }
-
-#ifdef DEBUG
-       if (PortFound) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_SELECT_BCRX found Port %d receiving the substantially "
-                        "latest broadcast (%u).\n",
-                               *pSelect,
-                               BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp))
-       }
-#endif /* DEBUG */
-
-       return (PortFound);
-}      /* SkRlmtSelectBcRx */
-
-
-/******************************************************************************
- *
- *     SkRlmtSelectNotSuspect - select new active port, criteria 2 (CLP)
- *
- * Description:
- *     This routine selects a good port (it is PortUp && !SuspectRx).
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     SK_BOOL
- */
-RLMT_STATIC SK_BOOL    SkRlmtSelectNotSuspect(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-SK_U32 Active,         /* Active port */
-SK_U32 PrefPort,       /* Preferred port */
-SK_U32 *pSelect)       /* New active port */
-{
-       SK_U32          i;
-       SK_BOOL         PortFound;
-
-       PortFound = SK_FALSE;
-
-       /* Select first port that is PortUp && !SuspectRx. */
-       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-               if (!pAC->Rlmt.Port[i].PortDown &&
-                       !(pAC->Rlmt.Port[i].CheckingState & SK_RLMT_PCS_RX)) {
-                       *pSelect = i;
-                       if (!pAC->Rlmt.Port[Active].PortDown &&
-                               !(pAC->Rlmt.Port[Active].CheckingState & SK_RLMT_PCS_RX)) {
-                               *pSelect = Active;
-                       }
-                       if (!pAC->Rlmt.Port[PrefPort].PortDown &&
-                               !(pAC->Rlmt.Port[PrefPort].CheckingState & SK_RLMT_PCS_RX)) {
-                               *pSelect = PrefPort;
-                       }
-                       PortFound = SK_TRUE;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                               ("SK_RLMT_SELECT_NOTSUSPECT found Port %d up and not check RX.\n",
-                                       *pSelect))
-                       break;
-               }
-       }
-       return (PortFound);
-}      /* SkRlmtSelectNotSuspect */
-
-
-/******************************************************************************
- *
- *     SkRlmtSelectUp - select new active port, criteria 3, 4 (CLP)
- *
- * Description:
- *     This routine selects a port that is up.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     SK_BOOL
- */
-RLMT_STATIC SK_BOOL    SkRlmtSelectUp(
-SK_AC  *pAC,                   /* Adapter Context */
-SK_IOC IoC,                    /* I/O Context */
-SK_U32 Active,                 /* Active port */
-SK_U32 PrefPort,               /* Preferred port */
-SK_U32 *pSelect,               /* New active port */
-SK_BOOL        AutoNegDone)    /* Successfully auto-negotiated? */
-{
-       SK_U32          i;
-       SK_BOOL         PortFound;
-
-       PortFound = SK_FALSE;
-
-       /* Select first port that is PortUp. */
-       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-               if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_UP &&
-                       pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
-                       *pSelect = i;
-                       if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_UP &&
-                               pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
-                               *pSelect = Active;
-                       }
-                       if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_UP &&
-                               pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
-                               *pSelect = PrefPort;
-                       }
-                       PortFound = SK_TRUE;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                               ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect))
-                       break;
-               }
-       }
-       return (PortFound);
-}      /* SkRlmtSelectUp */
-
-
-/******************************************************************************
- *
- *     SkRlmtSelectGoingUp - select new active port, criteria 5, 6 (CLP)
- *
- * Description:
- *     This routine selects the port that is going up for the longest time.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     SK_BOOL
- */
-RLMT_STATIC SK_BOOL    SkRlmtSelectGoingUp(
-SK_AC  *pAC,                   /* Adapter Context */
-SK_IOC IoC,                    /* I/O Context */
-SK_U32 Active,                 /* Active port */
-SK_U32 PrefPort,               /* Preferred port */
-SK_U32 *pSelect,               /* New active port */
-SK_BOOL        AutoNegDone)    /* Successfully auto-negotiated? */
-{
-       SK_U64          GuTimeStamp;
-       SK_U32          i;
-       SK_BOOL         PortFound;
-
-       GuTimeStamp = 0;
-       PortFound = SK_FALSE;
-
-       /* Select port that is PortGoingUp for the longest time. */
-       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-               if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
-                       pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
-                       GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
-                       *pSelect = i;
-                       PortFound = SK_TRUE;
-                       break;
-               }
-       }
-
-       if (!PortFound) {
-               return (SK_FALSE);
-       }
-
-       for (i = *pSelect + 1; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-               if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
-                       pAC->Rlmt.Port[i].GuTimeStamp < GuTimeStamp &&
-                       pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
-                       GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
-                       *pSelect = i;
-               }
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect))
-       return (SK_TRUE);
-}      /* SkRlmtSelectGoingUp */
-
-
-/******************************************************************************
- *
- *     SkRlmtSelectDown - select new active port, criteria 7, 8 (CLP)
- *
- * Description:
- *     This routine selects a port that is down.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     SK_BOOL
- */
-RLMT_STATIC SK_BOOL    SkRlmtSelectDown(
-SK_AC  *pAC,                   /* Adapter Context */
-SK_IOC IoC,                    /* I/O Context */
-SK_U32 Active,                 /* Active port */
-SK_U32 PrefPort,               /* Preferred port */
-SK_U32 *pSelect,               /* New active port */
-SK_BOOL        AutoNegDone)    /* Successfully auto-negotiated? */
-{
-       SK_U32          i;
-       SK_BOOL         PortFound;
-
-       PortFound = SK_FALSE;
-
-       /* Select first port that is PortDown. */
-       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-               if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_DOWN &&
-                       pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
-                       *pSelect = i;
-                       if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_DOWN &&
-                               pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
-                               *pSelect = Active;
-                       }
-                       if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_DOWN &&
-                               pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
-                               *pSelect = PrefPort;
-                       }
-                       PortFound = SK_TRUE;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                               ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect))
-                       break;
-               }
-       }
-       return (PortFound);
-}      /* SkRlmtSelectDown */
-
-
-/******************************************************************************
- *
- *     SkRlmtCheckSwitch - select new active port and switch to it
- *
- * Description:
- *     This routine decides which port should be the active one and queues
- *     port switching if necessary.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     Nothing.
- */
-RLMT_STATIC void       SkRlmtCheckSwitch(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC,    /* I/O Context */
-SK_U32 NetIdx) /* Net index */
-{
-       SK_EVPARA       Para;
-       SK_U32          Active;
-       SK_U32          PrefPort;
-       SK_U32          i;
-       SK_BOOL         PortFound;
-
-       Active = pAC->Rlmt.Net[NetIdx].ActivePort;      /* Index of active port. */
-       PrefPort = pAC->Rlmt.Net[NetIdx].PrefPort;      /* Index of preferred port. */
-       PortFound = SK_FALSE;
-       pAC->Rlmt.CheckSwitch = SK_FALSE;
-
-#if 0  /* RW 2001/10/18 - active port becomes always prefered one */
-       if (pAC->Rlmt.Net[NetIdx].Preference == 0xFFFFFFFF) { /* Automatic */
-               /* disable auto-fail back */
-               PrefPort = Active;
-       }
-#endif
-
-       if (pAC->Rlmt.Net[NetIdx].LinksUp == 0) {
-               /* Last link went down - shut down the net. */
-               pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_DOWN;
-               Para.Para32[0] = SK_RLMT_NET_DOWN_TEMP;
-               Para.Para32[1] = NetIdx;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para);
-
-               Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
-                       Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
-               Para.Para32[1] = NetIdx;
-               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
-               return;
-       }       /* pAC->Rlmt.LinksUp == 0 */
-       else if (pAC->Rlmt.Net[NetIdx].LinksUp == 1 &&
-               pAC->Rlmt.Net[NetIdx].RlmtState == SK_RLMT_RS_NET_DOWN) {
-               /* First link came up - get the net up. */
-               pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_UP;
-
-               /*
-                * If pAC->Rlmt.ActivePort != Para.Para32[0],
-                * the DRV switches to the port that came up.
-                */
-               for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
-                       if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
-                               if (!pAC->Rlmt.Net[NetIdx].Port[Active]->LinkDown) {
-                                       i = Active;
-                               }
-                               if (!pAC->Rlmt.Net[NetIdx].Port[PrefPort]->LinkDown) {
-                                       i = PrefPort;
-                               }
-                               PortFound = SK_TRUE;
-                               break;
-                       }
-               }
-
-               if (PortFound) {
-                       Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
-                       Para.Para32[1] = NetIdx;
-                       SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
-
-                       pAC->Rlmt.Net[NetIdx].ActivePort = i;
-                       Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
-                       Para.Para32[1] = NetIdx;
-                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para);
-
-                       if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
-                               (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC,
-                               pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber,
-                               SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].
-                               CurrentMacAddress, &SkRlmtMcAddr)) != NULL) {
-                               /*
-                                * Send announce packet to RLMT multicast address to force
-                                * switches to learn the new location of the logical MAC address.
-                                */
-                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
-                       }
-               }
-               else {
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E007, SKERR_RLMT_E007_MSG);
-               }
-
-               return;
-       }       /* LinksUp == 1 && RlmtState == SK_RLMT_RS_NET_DOWN */
-       else {  /* Cannot be reached in dual-net mode. */
-               Para.Para32[0] = Active;
-
-               /*
-                * Preselection:
-                *      If RLMT Mode != CheckLinkState
-                *              select port that received a broadcast frame substantially later
-                *              than all other ports
-                *      else select first port that is not SuspectRx
-                *      else select first port that is PortUp
-                *      else select port that is PortGoingUp for the longest time
-                *      else select first port that is PortDown
-                *      else stop.
-                *
-                * For the preselected port:
-                *      If ActivePort is equal in quality, select ActivePort.
-                *
-                *      If PrefPort is equal in quality, select PrefPort.
-                *
-                *      If ActivePort != SelectedPort,
-                *              If old ActivePort is LinkDown,
-                *                      SwitchHard
-                *              else
-                *                      SwitchSoft
-                */
-               /* check of ChgBcPrio flag added */
-               if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) &&
-                       (!pAC->Rlmt.Net[0].ChgBcPrio)) {
-
-                       if (!PortFound) {
-                               PortFound = SkRlmtSelectBcRx(
-                                       pAC, IoC, Active, PrefPort, &Para.Para32[1]);
-                       }
-
-                       if (!PortFound) {
-                               PortFound = SkRlmtSelectNotSuspect(
-                                       pAC, IoC, Active, PrefPort, &Para.Para32[1]);
-                       }
-               }       /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
-
-               /* with changed priority for last broadcast received */
-               if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) &&
-                       (pAC->Rlmt.Net[0].ChgBcPrio)) {
-                       if (!PortFound) {
-                               PortFound = SkRlmtSelectNotSuspect(
-                                       pAC, IoC, Active, PrefPort, &Para.Para32[1]);
-                       }
-
-                       if (!PortFound) {
-                               PortFound = SkRlmtSelectBcRx(
-                                       pAC, IoC, Active, PrefPort, &Para.Para32[1]);
-                       }
-               }       /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
-
-               if (!PortFound) {
-                       PortFound = SkRlmtSelectUp(
-                               pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
-               }
-
-               if (!PortFound) {
-                       PortFound = SkRlmtSelectUp(
-                               pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
-               }
-
-               if (!PortFound) {
-                       PortFound = SkRlmtSelectGoingUp(
-                               pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
-               }
-
-               if (!PortFound) {
-                       PortFound = SkRlmtSelectGoingUp(
-                               pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
-               }
-
-               if (pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) {
-                       if (!PortFound) {
-                               PortFound = SkRlmtSelectDown(pAC, IoC,
-                                       Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
-                       }
-
-                       if (!PortFound) {
-                               PortFound = SkRlmtSelectDown(pAC, IoC,
-                                       Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
-                       }
-               }       /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
-
-               if (PortFound) {
-
-                       if (Para.Para32[1] != Active) {
-                               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                                       ("Active: %d, Para1: %d.\n", Active, Para.Para32[1]))
-                               pAC->Rlmt.Net[NetIdx].ActivePort = Para.Para32[1];
-                               Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
-                                       Port[Para.Para32[0]]->PortNumber;
-                               Para.Para32[1] = pAC->Rlmt.Net[NetIdx].
-                                       Port[Para.Para32[1]]->PortNumber;
-                               SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[1], SK_LED_ACTIVE);
-                               if (pAC->Rlmt.Port[Active].LinkDown) {
-                                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_HARD, Para);
-                               }
-                               else {
-                                       SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
-                                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_SOFT, Para);
-                               }
-                               Para.Para32[1] = NetIdx;
-                               Para.Para32[0] =
-                                       pAC->Rlmt.Net[NetIdx].Port[Para.Para32[0]]->PortNumber;
-                               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
-                               Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
-                                       Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
-                               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
-                               if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
-                                       (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, Para.Para32[0],
-                                       SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].CurrentMacAddress,
-                                       &SkRlmtMcAddr)) != NULL) {
-                                       /*
-                                        * Send announce packet to RLMT multicast address to force
-                                        * switches to learn the new location of the logical
-                                        * MAC address.
-                                        */
-                                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
-                               }       /* (Para.pParaPtr = SkRlmtBuildPacket(...)) != NULL */
-                       }       /* Para.Para32[1] != Active */
-               }       /* PortFound */
-               else {
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E004, SKERR_RLMT_E004_MSG);
-               }
-       }       /* LinksUp > 1 || LinksUp == 1 && RlmtState != SK_RLMT_RS_NET_DOWN */
-       return;
-}      /* SkRlmtCheckSwitch */
-
-
-/******************************************************************************
- *
- *     SkRlmtCheckSeg - Report if segmentation is detected
- *
- * Description:
- *     This routine checks if the ports see different root bridges and reports
- *     segmentation in such a case.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     Nothing.
- */
-RLMT_STATIC void       SkRlmtCheckSeg(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC,    /* I/O Context */
-SK_U32 NetIdx) /* Net number */
-{
-       SK_EVPARA       Para;
-       SK_RLMT_NET     *pNet;
-       SK_U32          i, j;
-       SK_BOOL         Equal;
-
-       pNet = &pAC->Rlmt.Net[NetIdx];
-       pNet->RootIdSet = SK_FALSE;
-       Equal = SK_TRUE;
-
-       for (i = 0; i < pNet->NumPorts; i++) {
-               if (pNet->Port[i]->LinkDown || !pNet->Port[i]->RootIdSet) {
-                       continue;
-               }
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
-                       ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n", i,
-                               pNet->Port[i]->Root.Id[0], pNet->Port[i]->Root.Id[1],
-                               pNet->Port[i]->Root.Id[2], pNet->Port[i]->Root.Id[3],
-                               pNet->Port[i]->Root.Id[4], pNet->Port[i]->Root.Id[5],
-                               pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7]))
-
-               if (!pNet->RootIdSet) {
-                       pNet->Root = pNet->Port[i]->Root;
-                       pNet->RootIdSet = SK_TRUE;
-                       continue;
-               }
-
-               for (j = 0; j < 8; j ++) {
-                       Equal &= pNet->Port[i]->Root.Id[j] == pNet->Root.Id[j];
-                       if (!Equal) {
-                               break;
-                       }
-               }
-
-               if (!Equal) {
-                       SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E005, SKERR_RLMT_E005_MSG);
-                       Para.Para32[0] = NetIdx;
-                       Para.Para32[1] = (SK_U32)-1;
-                       SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SEGMENTATION, Para);
-
-                       pNet->CheckingState &= ~SK_RLMT_RCS_REPORT_SEG;
-
-                       /* 2000-03-06 RA: New. */
-                       Para.Para32[0] = NetIdx;
-                       Para.Para32[1] = (SK_U32)-1;
-                       SkTimerStart(pAC, IoC, &pNet->SegTimer, SK_RLMT_SEG_TO_VAL,
-                               SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
-                       break;
-               }
-       }       /* for (i = 0; i < pNet->NumPorts; i++) */
-
-       /* 2000-03-06 RA: Moved here. */
-       /* Segmentation check not running anymore. */
-       pNet->CheckingState &= ~SK_RLMT_RCS_SEG;
-
-}      /* SkRlmtCheckSeg */
-
-
-/******************************************************************************
- *
- *     SkRlmtPortStart - initialize port variables and start port
- *
- * Description:
- *     This routine initializes a port's variables and issues a PORT_START
- *     to the HWAC module.  This handles retries if the start fails or the
- *     link eventually goes down.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtPortStart(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-SK_U32 PortNumber)     /* Port number */
-{
-       SK_EVPARA       Para;
-
-       pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_LINK_DOWN;
-       pAC->Rlmt.Port[PortNumber].PortStarted = SK_TRUE;
-       pAC->Rlmt.Port[PortNumber].LinkDown = SK_TRUE;
-       pAC->Rlmt.Port[PortNumber].PortDown = SK_TRUE;
-       pAC->Rlmt.Port[PortNumber].CheckingState = 0;
-       pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
-       Para.Para32[0] = PortNumber;
-       Para.Para32[1] = (SK_U32)-1;
-       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
-}      /* SkRlmtPortStart */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtPortStartTim - PORT_START_TIM
- *
- * Description:
- *     This routine handles PORT_START_TIM events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtPortStartTim(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 -1 */
-{
-       SK_U32                  i;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0]))
-
-               if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n"))
-               return;
-       }
-
-       /*
-        * Used to start non-preferred ports if the preferred one
-        * does not come up.
-        * This timeout needs only be set when starting the first
-        * (preferred) port.
-        */
-       if (pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
-               /* PORT_START failed. */
-               for (i = 0; i < pAC->Rlmt.Port[Para.Para32[0]].Net->NumPorts; i++) {
-                       if (!pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortStarted) {
-                               SkRlmtPortStart(pAC, IoC,
-                                       pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortNumber);
-                       }
-               }
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n"))
-}      /* SkRlmtEvtPortStartTim */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtLinkUp - LINK_UP
- *
- * Description:
- *     This routine handles LLINK_UP events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtLinkUp(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 Undefined */
-{
-       SK_U32                  i;
-       SK_RLMT_PORT    *pRPort;
-       SK_EVPARA               Para2;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0]))
-
-       pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
-       if (!pRPort->PortStarted) {
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E008, SKERR_RLMT_E008_MSG);
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                               ("SK_RLMT_LINK_UP Event EMPTY.\n"))
-               return;
-       }
-
-       if (!pRPort->LinkDown) {
-               /* RA;:;: Any better solution? */
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_LINK_UP Event EMPTY.\n"))
-               return;
-       }
-
-       SkTimerStop(pAC, IoC, &pRPort->UpTimer);
-       SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
-       SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
-
-       /* Do something if timer already fired? */
-
-       pRPort->LinkDown = SK_FALSE;
-       pRPort->PortState = SK_RLMT_PS_GOING_UP;
-       pRPort->GuTimeStamp = SkOsGetTime(pAC);
-       pRPort->BcTimeStamp = 0;
-       pRPort->Net->LinksUp++;
-       if (pRPort->Net->LinksUp == 1) {
-               SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_ACTIVE);
-       }
-       else {
-               SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
-       }
-
-       for (i = 0; i < pRPort->Net->NumPorts; i++) {
-               if (!pRPort->Net->Port[i]->PortStarted) {
-                       SkRlmtPortStart(pAC, IoC, pRPort->Net->Port[i]->PortNumber);
-               }
-       }
-
-       SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
-
-       if (pRPort->Net->LinksUp >= 2) {
-               if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
-                       /* Build the check chain. */
-                       SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
-               }
-       }
-
-       /* If the first link comes up, start the periodical RLMT timeout. */
-       if (pRPort->Net->NumPorts > 1 && pRPort->Net->LinksUp == 1 &&
-               (pRPort->Net->RlmtMode & SK_RLMT_CHECK_OTHERS) != 0) {
-               Para2.Para32[0] = pRPort->Net->NetNumber;
-               Para2.Para32[1] = (SK_U32)-1;
-               SkTimerStart(pAC, IoC, &pRPort->Net->LocTimer,
-                       pRPort->Net->TimeoutValue, SKGE_RLMT, SK_RLMT_TIM, Para2);
-       }
-
-       Para2 = Para;
-       Para2.Para32[1] = (SK_U32)-1;
-       SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
-               SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para2);
-
-       /* Later: if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) && */
-       if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
-               (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 &&
-               (Para2.pParaPtr =
-                       SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE,
-                       &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr)
-               ) != NULL) {
-               /* Send "new" packet to RLMT multicast address. */
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
-       }
-
-       if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_SEG) {
-               if ((Para2.pParaPtr =
-                       SkRlmtBuildSpanningTreePacket(pAC, IoC, Para.Para32[0])) != NULL) {
-                       pAC->Rlmt.Port[Para.Para32[0]].RootIdSet = SK_FALSE;
-                       pRPort->Net->CheckingState |=
-                               SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
-
-                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
-
-                       Para.Para32[1] = (SK_U32)-1;
-                       SkTimerStart(pAC, IoC, &pRPort->Net->SegTimer,
-                               SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
-               }
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_LINK_UP Event END.\n"))
-}      /* SkRlmtEvtLinkUp */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtPortUpTim - PORT_UP_TIM
- *
- * Description:
- *     This routine handles PORT_UP_TIM events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtPortUpTim(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 -1 */
-{
-       SK_RLMT_PORT    *pRPort;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0]))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_PORTUP_TIM Event EMPTY.\n"))
-               return;
-       }
-
-       pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
-       if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0]))
-               return;
-       }
-
-       pRPort->PortDown = SK_FALSE;
-       pRPort->PortState = SK_RLMT_PS_UP;
-       pRPort->Net->PortsUp++;
-       if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
-               if (pAC->Rlmt.NumNets <= 1) {
-                       SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
-               }
-               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_UP, Para);
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PORTUP_TIM Event END.\n"))
-}      /* SkRlmtEvtPortUpTim */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtPortDownTim - PORT_DOWN_*
- *
- * Description:
- *     This routine handles PORT_DOWN_* events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtPortDownX(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_U32         Event,  /* Event code */
-SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 -1 */
-{
-       SK_RLMT_PORT    *pRPort;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n",
-                       Para.Para32[0], Event))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_PORTDOWN* Event EMPTY.\n"))
-               return;
-       }
-
-       pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
-       if (!pRPort->PortStarted || (Event == SK_RLMT_PORTDOWN_TX_TIM &&
-               !(pRPort->CheckingState & SK_RLMT_PCS_TX))) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event))
-               return;
-       }
-
-       /* Stop port's timers. */
-       SkTimerStop(pAC, IoC, &pRPort->UpTimer);
-       SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
-       SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
-
-       if (pRPort->PortState != SK_RLMT_PS_LINK_DOWN) {
-               pRPort->PortState = SK_RLMT_PS_DOWN;
-       }
-
-       if (!pRPort->PortDown) {
-               pRPort->Net->PortsUp--;
-               pRPort->PortDown = SK_TRUE;
-               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_DOWN, Para);
-       }
-
-       pRPort->PacketsPerTimeSlot = 0;
-       /* pRPort->DataPacketsPerTimeSlot = 0; */
-       pRPort->BpduPacketsPerTimeSlot = 0;
-       pRPort->BcTimeStamp = 0;
-
-       /*
-        * RA;:;: To be checked:
-        * - actions at RLMT_STOP: We should not switch anymore.
-        */
-       if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
-               if (Para.Para32[0] ==
-                       pRPort->Net->Port[pRPort->Net->ActivePort]->PortNumber) {
-                       /* Active Port went down. */
-                       SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
-               }
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event))
-}      /* SkRlmtEvtPortDownX */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtLinkDown - LINK_DOWN
- *
- * Description:
- *     This routine handles LINK_DOWN events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtLinkDown(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 Undefined */
-{
-       SK_RLMT_PORT    *pRPort;
-
-       pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0]))
-
-       if (!pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
-               pRPort->Net->LinksUp--;
-               pRPort->LinkDown = SK_TRUE;
-               pRPort->PortState = SK_RLMT_PS_LINK_DOWN;
-               SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_OFF);
-
-               if ((pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) != 0) {
-                       /* Build the check chain. */
-                       SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
-               }
-
-               /* Ensure that port is marked down. */
-               Para.Para32[1] = -1;
-               (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PORTDOWN, Para);
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_LINK_DOWN Event END.\n"))
-}      /* SkRlmtEvtLinkDown */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtPortAddr - PORT_ADDR
- *
- * Description:
- *     This routine handles PORT_ADDR events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtPortAddr(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 -1 */
-{
-       SK_U32                  i, j;
-       SK_RLMT_PORT    *pRPort;
-       SK_MAC_ADDR             *pOldMacAddr;
-       SK_MAC_ADDR             *pNewMacAddr;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0]))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_PORT_ADDR Event EMPTY.\n"))
-               return;
-       }
-
-       /* Port's physical MAC address changed. */
-       pOldMacAddr = &pAC->Addr.Port[Para.Para32[0]].PreviousMacAddress;
-       pNewMacAddr = &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress;
-
-       /*
-        * NOTE: This is not scalable for solutions where ports are
-        *       checked remotely.  There, we need to send an RLMT
-        *       address change packet - and how do we ensure delivery?
-        */
-       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-               pRPort = &pAC->Rlmt.Port[i];
-               for (j = 0; j < pRPort->PortsChecked; j++) {
-                       if (SK_ADDR_EQUAL(
-                               pRPort->PortCheck[j].CheckAddr.a, pOldMacAddr->a)) {
-                               pRPort->PortCheck[j].CheckAddr = *pNewMacAddr;
-                       }
-               }
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_PORT_ADDR Event END.\n"))
-}      /* SkRlmtEvtPortAddr */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtStart - START
- *
- * Description:
- *     This routine handles START events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtStart(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
-{
-       SK_EVPARA       Para2;
-       SK_U32          PortIdx;
-       SK_U32          PortNumber;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0]))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_START Event EMPTY.\n"))
-               return;
-       }
-
-       if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad NetNumber %d.\n", Para.Para32[0]))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_START Event EMPTY.\n"))
-               return;
-       }
-
-       if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState != SK_RLMT_RS_INIT) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_START Event EMPTY.\n"))
-               return;
-       }
-
-       if (pAC->Rlmt.NetsStarted >= pAC->Rlmt.NumNets) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("All nets should have been started.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_START Event EMPTY.\n"))
-               return;
-       }
-
-       if (pAC->Rlmt.Net[Para.Para32[0]].PrefPort >=
-               pAC->Rlmt.Net[Para.Para32[0]].NumPorts) {
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E009, SKERR_RLMT_E009_MSG);
-
-               /* Change PrefPort to internal default. */
-               Para2.Para32[0] = 0xFFFFFFFF;
-               Para2.Para32[1] = Para.Para32[0];
-               (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE, Para2);
-       }
-
-       PortIdx = pAC->Rlmt.Net[Para.Para32[0]].PrefPort;
-       PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[PortIdx]->PortNumber;
-
-       pAC->Rlmt.Net[Para.Para32[0]].LinksUp = 0;
-       pAC->Rlmt.Net[Para.Para32[0]].PortsUp = 0;
-       pAC->Rlmt.Net[Para.Para32[0]].CheckingState = 0;
-       pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_NET_DOWN;
-
-       /* Start preferred port. */
-       SkRlmtPortStart(pAC, IoC, PortNumber);
-
-       /* Start Timer (for first port only). */
-       Para2.Para32[0] = PortNumber;
-       Para2.Para32[1] = (SK_U32)-1;
-       SkTimerStart(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer,
-               SK_RLMT_PORTSTART_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTSTART_TIM, Para2);
-
-       pAC->Rlmt.NetsStarted++;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_START Event END.\n"))
-}      /* SkRlmtEvtStart */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtStop - STOP
- *
- * Description:
- *     This routine handles STOP events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtStop(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
-{
-       SK_EVPARA       Para2;
-       SK_U32          PortNumber;
-       SK_U32          i;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0]))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_STOP Event EMPTY.\n"))
-               return;
-       }
-
-       if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad NetNumber %d.\n", Para.Para32[0]))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_STOP Event EMPTY.\n"))
-               return;
-       }
-
-       if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState == SK_RLMT_RS_INIT) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_STOP Event EMPTY.\n"))
-               return;
-       }
-
-       if (pAC->Rlmt.NetsStarted == 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("All nets are stopped.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_STOP Event EMPTY.\n"))
-               return;
-       }
-
-       /* Stop RLMT timers. */
-       SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer);
-       SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer);
-
-       /* Stop net. */
-       pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_INIT;
-       pAC->Rlmt.Net[Para.Para32[0]].RootIdSet = SK_FALSE;
-       Para2.Para32[0] = SK_RLMT_NET_DOWN_FINAL;
-       Para2.Para32[1] = Para.Para32[0];                       /* Net# */
-       SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para2);
-
-       /* Stop ports. */
-       for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
-               PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
-               if (pAC->Rlmt.Port[PortNumber].PortState != SK_RLMT_PS_INIT) {
-                       SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer);
-                       SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownRxTimer);
-                       SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownTxTimer);
-
-                       pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_INIT;
-                       pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
-                       pAC->Rlmt.Port[PortNumber].PortStarted = SK_FALSE;
-                       Para2.Para32[0] = PortNumber;
-                       Para2.Para32[1] = (SK_U32)-1;
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para2);
-               }
-       }
-
-       pAC->Rlmt.NetsStarted--;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_STOP Event END.\n"))
-}      /* SkRlmtEvtStop */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtTim - TIM
- *
- * Description:
- *     This routine handles TIM events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtTim(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
-{
-       SK_RLMT_PORT    *pRPort;
-       SK_U32                  Timeout;
-       SK_U32                  NewTimeout;
-       SK_U32                  PortNumber;
-       SK_U32                  i;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_TIM Event BEGIN.\n"))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_TIM Event EMPTY.\n"))
-               return;
-       }
-
-       if ((pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_OTHERS) == 0 ||
-               pAC->Rlmt.Net[Para.Para32[0]].LinksUp == 0) {
-               /* Mode changed or all links down: No more link checking. */
-               return;
-       }
-
-#if 0
-       pAC->Rlmt.SwitchCheckCounter--;
-       if (pAC->Rlmt.SwitchCheckCounter == 0) {
-               pAC->Rlmt.SwitchCheckCounter;
-       }
-#endif /* 0 */
-
-       NewTimeout = SK_RLMT_DEF_TO_VAL;
-       for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
-               PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
-               pRPort = &pAC->Rlmt.Port[PortNumber];
-               if (!pRPort->LinkDown) {
-                       Timeout = SkRlmtCheckPort(pAC, IoC, PortNumber);
-                       if (Timeout < NewTimeout) {
-                               NewTimeout = Timeout;
-                       }
-
-                       /*
-                        * These counters should be set to 0 for all ports before the
-                        * first frame is sent in the next loop.
-                        */
-                       pRPort->PacketsPerTimeSlot = 0;
-                       /* pRPort->DataPacketsPerTimeSlot = 0; */
-                       pRPort->BpduPacketsPerTimeSlot = 0;
-               }
-       }
-       pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue = NewTimeout;
-
-       if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1) {
-               /*
-                * If checking remote ports, also send packets if
-                *   (LinksUp == 1) &&
-                *   this port checks at least one (remote) port.
-                */
-
-               /*
-                * Must be new loop, as SkRlmtCheckPort can request to
-                * check segmentation when e.g. checking the last port.
-                */
-               for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
-                       if (!pAC->Rlmt.Net[Para.Para32[0]].Port[i]->LinkDown) {
-                               SkRlmtSend(pAC, IoC,
-                                       pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber);
-                       }
-               }
-       }
-
-       SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer,
-               pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue, SKGE_RLMT, SK_RLMT_TIM,
-               Para);
-
-       if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1 &&
-               (pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_SEG) &&
-               (pAC->Rlmt.Net[Para.Para32[0]].CheckingState & SK_RLMT_RCS_START_SEG)) {
-               SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer,
-                       SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
-               pAC->Rlmt.Net[Para.Para32[0]].CheckingState &= ~SK_RLMT_RCS_START_SEG;
-               pAC->Rlmt.Net[Para.Para32[0]].CheckingState |=
-                       SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_TIM Event END.\n"))
-}      /* SkRlmtEvtTim */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtSegTim - SEG_TIM
- *
- * Description:
- *     This routine handles SEG_TIM events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtSegTim(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
-{
-#ifdef xDEBUG
-       int j;
-#endif /* DEBUG */
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_SEG_TIM Event BEGIN.\n"))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_SEG_TIM Event EMPTY.\n"))
-               return;
-       }
-
-#ifdef xDEBUG
-       for (j = 0; j < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; j++) {
-               SK_ADDR_PORT    *pAPort;
-               SK_U32                  k;
-               SK_U16                  *InAddr;
-               SK_U8                   InAddr8[6];
-
-               InAddr = (SK_U16 *)&InAddr8[0];
-               pAPort = pAC->Rlmt.Net[Para.Para32[0]].Port[j]->AddrPort;
-               for (k = 0; k < pAPort->NextExactMatchRlmt; k++) {
-                       /* Get exact match address k from port j. */
-                       XM_INADDR(IoC, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
-                               XM_EXM(k), InAddr);
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                               ("MC address %d on Port %u: %02x %02x %02x %02x %02x %02x --  %02x %02x %02x %02x %02x %02x.\n",
-                                       k, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
-                                       InAddr8[0], InAddr8[1], InAddr8[2],
-                                       InAddr8[3], InAddr8[4], InAddr8[5],
-                                       pAPort->Exact[k].a[0], pAPort->Exact[k].a[1],
-                                       pAPort->Exact[k].a[2], pAPort->Exact[k].a[3],
-                                       pAPort->Exact[k].a[4], pAPort->Exact[k].a[5]))
-               }
-       }
-#endif /* xDEBUG */
-
-       SkRlmtCheckSeg(pAC, IoC, Para.Para32[0]);
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_SEG_TIM Event END.\n"))
-}      /* SkRlmtEvtSegTim */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtPacketRx - PACKET_RECEIVED
- *
- * Description:
- *     This routine handles PACKET_RECEIVED events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtPacketRx(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_MBUF *pMb */
-{
-       SK_MBUF *pMb;
-       SK_MBUF *pNextMb;
-       SK_U32  NetNumber;
-
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n"))
-
-       /* Should we ignore frames during port switching? */
-
-#ifdef DEBUG
-       pMb = Para.pParaPtr;
-       if (pMb == NULL) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n"))
-       }
-       else if (pMb->pNext != NULL) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("More than one mbuf or pMb->pNext not set.\n"))
-       }
-#endif /* DEBUG */
-
-       for (pMb = Para.pParaPtr; pMb != NULL; pMb = pNextMb) {
-               pNextMb = pMb->pNext;
-               pMb->pNext = NULL;
-
-               NetNumber = pAC->Rlmt.Port[pMb->PortIdx].Net->NetNumber;
-               if (pAC->Rlmt.Net[NetNumber].RlmtState == SK_RLMT_RS_INIT) {
-                       SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-               }
-               else {
-                       SkRlmtPacketReceive(pAC, IoC, pMb);
-               }
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PACKET_RECEIVED Event END.\n"))
-}      /* SkRlmtEvtPacketRx */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtStatsClear - STATS_CLEAR
- *
- * Description:
- *     This routine handles STATS_CLEAR events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtStatsClear(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
-{
-       SK_U32                  i;
-       SK_RLMT_PORT    *pRPort;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_STATS_CLEAR Event BEGIN.\n"))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
-               return;
-       }
-
-       if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad NetNumber %d.\n", Para.Para32[0]))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
-               return;
-       }
-
-       /* Clear statistics for logical and physical ports. */
-       for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
-               pRPort =
-                       &pAC->Rlmt.Port[pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber];
-               pRPort->TxHelloCts = 0;
-               pRPort->RxHelloCts = 0;
-               pRPort->TxSpHelloReqCts = 0;
-               pRPort->RxSpHelloCts = 0;
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_STATS_CLEAR Event END.\n"))
-}      /* SkRlmtEvtStatsClear */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtStatsUpdate - STATS_UPDATE
- *
- * Description:
- *     This routine handles STATS_UPDATE events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtStatsUpdate(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
-{
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_STATS_UPDATE Event BEGIN.\n"))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
-               return;
-       }
-
-       if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad NetNumber %d.\n", Para.Para32[0]))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
-               return;
-       }
-
-       /* Update statistics - currently always up-to-date. */
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_STATS_UPDATE Event END.\n"))
-}      /* SkRlmtEvtStatsUpdate */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtPrefportChange - PREFPORT_CHANGE
- *
- * Description:
- *     This routine handles PREFPORT_CHANGE events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtPrefportChange(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 PortIndex; SK_U32 NetNumber */
-{
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0]))
-
-       if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad NetNumber %d.\n", Para.Para32[1]))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
-               return;
-       }
-
-       /* 0xFFFFFFFF == auto-mode. */
-       if (Para.Para32[0] == 0xFFFFFFFF) {
-               pAC->Rlmt.Net[Para.Para32[1]].PrefPort = SK_RLMT_DEF_PREF_PORT;
-       }
-       else {
-               if (Para.Para32[0] >= pAC->Rlmt.Net[Para.Para32[1]].NumPorts) {
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E010, SKERR_RLMT_E010_MSG);
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                               ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
-                       return;
-               }
-
-               pAC->Rlmt.Net[Para.Para32[1]].PrefPort = Para.Para32[0];
-       }
-
-       pAC->Rlmt.Net[Para.Para32[1]].Preference = Para.Para32[0];
-
-       if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
-               SkRlmtCheckSwitch(pAC, IoC, Para.Para32[1]);
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PREFPORT_CHANGE Event END.\n"))
-}      /* SkRlmtEvtPrefportChange */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtSetNets - SET_NETS
- *
- * Description:
- *     This routine handles SET_NETS events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtSetNets(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 NumNets; SK_U32 -1 */
-{
-       int i;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_SET_NETS Event BEGIN.\n"))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_SET_NETS Event EMPTY.\n"))
-               return;
-       }
-
-       if (Para.Para32[0] == 0 || Para.Para32[0] > SK_MAX_NETS ||
-               Para.Para32[0] > (SK_U32)pAC->GIni.GIMacsFound) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad number of nets: %d.\n", Para.Para32[0]))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_SET_NETS Event EMPTY.\n"))
-               return;
-       }
-
-       if (Para.Para32[0] == pAC->Rlmt.NumNets) {      /* No change. */
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_SET_NETS Event EMPTY.\n"))
-               return;
-       }
-
-       /* Entering and leaving dual mode only allowed while nets are stopped. */
-       if (pAC->Rlmt.NetsStarted > 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Changing dual mode only allowed while all nets are stopped.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_SET_NETS Event EMPTY.\n"))
-               return;
-       }
-
-       if (Para.Para32[0] == 1) {
-               if (pAC->Rlmt.NumNets > 1) {
-                       /* Clear logical MAC addr from second net's active port. */
-                       (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
-                               Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_CLEAR_LOGICAL);
-                       pAC->Rlmt.Net[1].NumPorts = 0;
-               }
-
-               pAC->Rlmt.NumNets = Para.Para32[0];
-               for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
-                       pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
-                       pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
-                       pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF;         /* "Automatic" */
-                       pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
-                       /* Just assuming. */
-                       pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
-                       pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
-                       pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
-                       pAC->Rlmt.Net[i].NetNumber = i;
-               }
-
-               pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[0];
-               pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
-
-               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("RLMT: Changed to one net with two ports.\n"))
-       }
-       else if (Para.Para32[0] == 2) {
-               pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[1];
-               pAC->Rlmt.Net[1].NumPorts = pAC->GIni.GIMacsFound - 1;
-               pAC->Rlmt.Net[0].NumPorts =
-                       pAC->GIni.GIMacsFound - pAC->Rlmt.Net[1].NumPorts;
-
-               pAC->Rlmt.NumNets = Para.Para32[0];
-               for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
-                       pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
-                       pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
-                       pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF;         /* "Automatic" */
-                       pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
-                       /* Just assuming. */
-                       pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
-                       pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
-                       pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
-
-                       pAC->Rlmt.Net[i].NetNumber = i;
-               }
-
-               /* Set logical MAC addr on second net's active port. */
-               (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
-                       Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_SET_LOGICAL);
-
-               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("RLMT: Changed to two nets with one port each.\n"))
-       }
-       else {
-               /* Not implemented for more than two nets. */
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SetNets not implemented for more than two nets.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_SET_NETS Event EMPTY.\n"))
-               return;
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_SET_NETS Event END.\n"))
-}      /* SkRlmtSetNets */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtModeChange - MODE_CHANGE
- *
- * Description:
- *     This routine handles MODE_CHANGE events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtModeChange(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 NewMode; SK_U32 NetNumber */
-{
-       SK_EVPARA       Para2;
-       SK_U32          i;
-       SK_U32          PrevRlmtMode;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_MODE_CHANGE Event BEGIN.\n"))
-
-       if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad NetNumber %d.\n", Para.Para32[1]))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
-               return;
-       }
-
-       Para.Para32[0] |= SK_RLMT_CHECK_LINK;
-
-       if ((pAC->Rlmt.Net[Para.Para32[1]].NumPorts == 1) &&
-               Para.Para32[0] != SK_RLMT_MODE_CLS) {
-               pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = SK_RLMT_MODE_CLS;
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Forced RLMT mode to CLS on single port net.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
-               return;
-       }
-
-       /* Update RLMT mode. */
-       PrevRlmtMode = pAC->Rlmt.Net[Para.Para32[1]].RlmtMode;
-       pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = Para.Para32[0];
-
-       if ((PrevRlmtMode & SK_RLMT_CHECK_LOC_LINK) !=
-               (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
-               /* SK_RLMT_CHECK_LOC_LINK bit changed. */
-               if ((PrevRlmtMode & SK_RLMT_CHECK_OTHERS) == 0 &&
-                       pAC->Rlmt.Net[Para.Para32[1]].NumPorts > 1 &&
-                       pAC->Rlmt.Net[Para.Para32[1]].PortsUp >= 1) {
-                       /* 20001207 RA: Was "PortsUp == 1". */
-                       Para2.Para32[0] = Para.Para32[1];
-                       Para2.Para32[1] = (SK_U32)-1;
-                       SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].LocTimer,
-                               pAC->Rlmt.Net[Para.Para32[1]].TimeoutValue,
-                               SKGE_RLMT, SK_RLMT_TIM, Para2);
-               }
-       }
-
-       if ((PrevRlmtMode & SK_RLMT_CHECK_SEG) !=
-               (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG)) {
-               /* SK_RLMT_CHECK_SEG bit changed. */
-               for (i = 0; i < pAC->Rlmt.Net[Para.Para32[1]].NumPorts; i++) {
-                       (void)SkAddrMcClear(pAC, IoC,
-                               pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
-                               SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
-
-                       /* Add RLMT MC address. */
-                       (void)SkAddrMcAdd(pAC, IoC,
-                               pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
-                               &SkRlmtMcAddr, SK_ADDR_PERMANENT);
-
-                       if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode &
-                               SK_RLMT_CHECK_SEG) != 0) {
-                               /* Add BPDU MC address. */
-                               (void)SkAddrMcAdd(pAC, IoC,
-                                       pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
-                                       &BridgeMcAddr, SK_ADDR_PERMANENT);
-
-                               if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
-                                       if (!pAC->Rlmt.Net[Para.Para32[1]].Port[i]->LinkDown &&
-                                               (Para2.pParaPtr = SkRlmtBuildSpanningTreePacket(
-                                               pAC, IoC, i)) != NULL) {
-                                               pAC->Rlmt.Net[Para.Para32[1]].Port[i]->RootIdSet =
-                                                       SK_FALSE;
-                                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
-                                       }
-                               }
-                       }
-                       (void)SkAddrMcUpdate(pAC, IoC,
-                               pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber);
-               }       /* for ... */
-
-               if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG) != 0) {
-                       Para2.Para32[0] = Para.Para32[1];
-                       Para2.Para32[1] = (SK_U32)-1;
-                       SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].SegTimer,
-                               SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para2);
-               }
-       }       /* SK_RLMT_CHECK_SEG bit changed. */
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_MODE_CHANGE Event END.\n"))
-}      /* SkRlmtEvtModeChange */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvent - a PORT- or an RLMT-specific event happened
- *
- * Description:
- *     This routine calls subroutines to handle PORT- and RLMT-specific events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     0
- */
-int    SkRlmtEvent(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_U32         Event,  /* Event code */
-SK_EVPARA      Para)   /* Event-specific parameter */
-{
-       switch (Event) {
-
-       /* ----- PORT events ----- */
-
-       case SK_RLMT_PORTSTART_TIM:     /* From RLMT via TIME. */
-               SkRlmtEvtPortStartTim(pAC, IoC, Para);
-               break;
-       case SK_RLMT_LINK_UP:           /* From SIRQ. */
-               SkRlmtEvtLinkUp(pAC, IoC, Para);
-               break;
-       case SK_RLMT_PORTUP_TIM:        /* From RLMT via TIME. */
-               SkRlmtEvtPortUpTim(pAC, IoC, Para);
-               break;
-       case SK_RLMT_PORTDOWN:                  /* From RLMT. */
-       case SK_RLMT_PORTDOWN_RX_TIM:   /* From RLMT via TIME. */
-       case SK_RLMT_PORTDOWN_TX_TIM:   /* From RLMT via TIME. */
-               SkRlmtEvtPortDownX(pAC, IoC, Event, Para);
-               break;
-       case SK_RLMT_LINK_DOWN:         /* From SIRQ. */
-               SkRlmtEvtLinkDown(pAC, IoC, Para);
-               break;
-       case SK_RLMT_PORT_ADDR:         /* From ADDR. */
-               SkRlmtEvtPortAddr(pAC, IoC, Para);
-               break;
-
-       /* ----- RLMT events ----- */
-
-       case SK_RLMT_START:             /* From DRV. */
-               SkRlmtEvtStart(pAC, IoC, Para);
-               break;
-       case SK_RLMT_STOP:              /* From DRV. */
-               SkRlmtEvtStop(pAC, IoC, Para);
-               break;
-       case SK_RLMT_TIM:               /* From RLMT via TIME. */
-               SkRlmtEvtTim(pAC, IoC, Para);
-               break;
-       case SK_RLMT_SEG_TIM:
-               SkRlmtEvtSegTim(pAC, IoC, Para);
-               break;
-       case SK_RLMT_PACKET_RECEIVED:   /* From DRV. */
-               SkRlmtEvtPacketRx(pAC, IoC, Para);
-               break;
-       case SK_RLMT_STATS_CLEAR:       /* From PNMI. */
-               SkRlmtEvtStatsClear(pAC, IoC, Para);
-               break;
-       case SK_RLMT_STATS_UPDATE:      /* From PNMI. */
-               SkRlmtEvtStatsUpdate(pAC, IoC, Para);
-               break;
-       case SK_RLMT_PREFPORT_CHANGE:   /* From PNMI. */
-               SkRlmtEvtPrefportChange(pAC, IoC, Para);
-               break;
-       case SK_RLMT_MODE_CHANGE:       /* From PNMI. */
-               SkRlmtEvtModeChange(pAC, IoC, Para);
-               break;
-       case SK_RLMT_SET_NETS:  /* From DRV. */
-               SkRlmtEvtSetNets(pAC, IoC, Para);
-               break;
-
-       /* ----- Unknown events ----- */
-
-       default:        /* Create error log entry. */
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Unknown RLMT Event %d.\n", Event))
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E003, SKERR_RLMT_E003_MSG);
-               break;
-       }       /* switch() */
-
-       return (0);
-}      /* SkRlmtEvent */
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CONFIG_SK98 */
diff --git a/drivers/sk98lin/sktimer.c b/drivers/sk98lin/sktimer.c
deleted file mode 100644 (file)
index 37cd4c9..0000000
+++ /dev/null
@@ -1,297 +0,0 @@
-/******************************************************************************
- *
- * Name:       sktimer.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.12 $
- * Date:       $Date: 1999/11/22 13:38:51 $
- * Purpose:    High level timer functions.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998,1999 SysKonnect,
- *     a business unit of Schneider & Koch & Co. Datensysteme GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: sktimer.c,v $
- *     Revision 1.12  1999/11/22 13:38:51  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.11  1998/12/17 13:24:13  gklug
- *     fix: restart problem: do NOT destroy timer queue if init 1 is done
- *
- *     Revision 1.10  1998/10/15 15:11:36  gklug
- *     fix: ID_sccs to SysKonnectFileId
- *
- *     Revision 1.9  1998/09/15 15:15:04  cgoos
- *     Changed TRUE/FALSE to SK_TRUE/SK_FALSE
- *
- *     Revision 1.8  1998/09/08 08:47:55  gklug
- *     add: init level handling
- *
- *     Revision 1.7  1998/08/19 09:50:53  gklug
- *     fix: remove struct keyword from c-code (see CCC) add typedefs
- *
- *     Revision 1.6  1998/08/17 13:43:13  gklug
- *     chg: Parameter will be union of 64bit para, 2 times SK_U32 or SK_PTR
- *
- *     Revision 1.5  1998/08/14 07:09:14  gklug
- *     fix: chg pAc -> pAC
- *
- *     Revision 1.4  1998/08/07 12:53:46  gklug
- *     fix: first compiled version
- *
- *     Revision 1.3  1998/08/07 09:31:53  gklug
- *     fix: delta spelling
- *
- *     Revision 1.2  1998/08/07 09:31:02  gklug
- *     adapt functions to new c coding conventions
- *     rmv: "fast" handling
- *     chg: inserting of new timer in queue.
- *     chg: event queue generation when timer runs out
- *
- *     Revision 1.1  1998/08/05 11:27:55  gklug
- *     first version: adapted from SMT
- *
- *
- *
- *
- ******************************************************************************/
-
-
-#include <config.h>
-
-#ifdef CONFIG_SK98
-
-/*
-       Event queue and dispatcher
-*/
-static const char SysKonnectFileId[] =
-       "$Header: /usr56/projects/ge/schedule/sktimer.c,v 1.12 1999/11/22 13:38:51 cgoos Exp $" ;
-
-#include "h/skdrv1st.h"                /* Driver Specific Definitions */
-#include "h/skdrv2nd.h"                /* Adapter Control- and Driver specific Def. */
-
-#ifdef __C2MAN__
-/*
-       Event queue management.
-
-       General Description:
-
- */
-intro()
-{}
-#endif
-
-
-/* Forward declaration */
-static void timer_done(SK_AC *pAC,SK_IOC Ioc,int Restart);
-
-
-/*
- * Inits the software timer
- *
- * needs to be called during Init level 1.
- */
-void   SkTimerInit(
-SK_AC  *pAC,           /* Adapters context */
-SK_IOC Ioc,            /* IoContext */
-int    Level)          /* Init Level */
-{
-       switch (Level) {
-       case SK_INIT_DATA:
-               pAC->Tim.StQueue = 0 ;
-               break;
-       case SK_INIT_IO:
-               SkHwtInit(pAC,Ioc) ;
-               SkTimerDone(pAC, Ioc);
-               break;
-       default:
-               break;
-       }
-}
-
-/*
- * Stops a high level timer
- * - If a timer is not in the queue the function returns normally, too.
- */
-void   SkTimerStop(
-SK_AC          *pAC,           /* Adapters context */
-SK_IOC         Ioc,            /* IoContext */
-SK_TIMER       *pTimer)        /* Timer Pointer to be started */
-{
-       SK_TIMER        **ppTimPrev ;
-       SK_TIMER        *pTm ;
-
-       /*
-        * remove timer from queue
-        */
-       pTimer->TmActive = SK_FALSE ;
-       if (pAC->Tim.StQueue == pTimer && !pTimer->TmNext) {
-               SkHwtStop(pAC,Ioc) ;
-       }
-       for (ppTimPrev = &pAC->Tim.StQueue ; (pTm = *ppTimPrev) ;
-               ppTimPrev = &pTm->TmNext ) {
-               if (pTm == pTimer) {
-                       /*
-                        * Timer found in queue
-                        * - dequeue it and
-                        * - correct delta of the next timer
-                        */
-                       *ppTimPrev = pTm->TmNext ;
-
-                       if (pTm->TmNext) {
-                               /* correct delta of next timer in queue */
-                               pTm->TmNext->TmDelta += pTm->TmDelta ;
-                       }
-                       return ;
-               }
-       }
-}
-
-/*
- * Start a high level software timer
- */
-void   SkTimerStart(
-SK_AC          *pAC,           /* Adapters context */
-SK_IOC         Ioc,            /* IoContext */
-SK_TIMER       *pTimer,        /* Timer Pointer to be started */
-SK_U32         Time,           /* Time value */
-SK_U32         Class,          /* Event Class for this timer */
-SK_U32         Event,          /* Event Value for this timer */
-SK_EVPARA      Para)           /* Event Parameter for this timer */
-{
-       SK_TIMER        **ppTimPrev ;
-       SK_TIMER        *pTm ;
-       SK_U32          Delta ;
-
-       Time /= 16 ;            /* input is uS, clock ticks are 16uS */
-       if (!Time)
-               Time = 1 ;
-
-       SkTimerStop(pAC,Ioc,pTimer) ;
-
-       pTimer->TmClass = Class ;
-       pTimer->TmEvent = Event ;
-       pTimer->TmPara = Para ;
-       pTimer->TmActive = SK_TRUE ;
-
-       if (!pAC->Tim.StQueue) {
-               /* First Timer to be started */
-               pAC->Tim.StQueue = pTimer ;
-               pTimer->TmNext = 0 ;
-               pTimer->TmDelta = Time ;
-               SkHwtStart(pAC,Ioc,Time) ;
-               return ;
-       }
-
-       /*
-        * timer correction
-        */
-       timer_done(pAC,Ioc,0) ;
-
-       /*
-        * find position in queue
-        */
-       Delta = 0 ;
-       for (ppTimPrev = &pAC->Tim.StQueue ; (pTm = *ppTimPrev) ;
-               ppTimPrev = &pTm->TmNext ) {
-               if (Delta + pTm->TmDelta > Time) {
-                       /* Position found */
-                       /* Here the timer needs to be inserted. */
-                       break ;
-               }
-               Delta += pTm->TmDelta ;
-       }
-
-       /* insert in queue */
-       *ppTimPrev = pTimer ;
-       pTimer->TmNext = pTm ;
-       pTimer->TmDelta = Time - Delta ;
-
-       if (pTm) {
-               /* There is a next timer
-                * -> correct its Delta value.
-                */
-               pTm->TmDelta -= pTimer->TmDelta ;
-       }
-
-       /*
-        * start new with first
-        */
-       SkHwtStart(pAC,Ioc,pAC->Tim.StQueue->TmDelta) ;
-}
-
-
-void   SkTimerDone(
-SK_AC  *pAC,           /* Adapters context */
-SK_IOC Ioc)            /* IoContext */
-{
-       timer_done(pAC,Ioc,1) ;
-}
-
-
-static void    timer_done(
-SK_AC  *pAC,           /* Adapters context */
-SK_IOC Ioc,            /* IoContext */
-int    Restart)        /* Do we need to restart the Hardware timer ? */
-{
-       SK_U32          Delta ;
-       SK_TIMER        *pTm ;
-       SK_TIMER        *pTComp ;       /* Timer completed now now */
-       SK_TIMER        **ppLast ;      /* Next field of Last timer to be deq */
-       int             Done = 0 ;
-
-       Delta = SkHwtRead(pAC,Ioc) ;
-       ppLast = &pAC->Tim.StQueue ;
-       pTm = pAC->Tim.StQueue ;
-       while (pTm && !Done) {
-               if (Delta >= pTm->TmDelta) {
-                       /* Timer ran out */
-                       pTm->TmActive = SK_FALSE ;
-                       Delta -= pTm->TmDelta ;
-                       ppLast = &pTm->TmNext ;
-                       pTm = pTm->TmNext ;
-               } else {
-                       /* We found the first timer that did not run out */
-                       pTm->TmDelta -= Delta ;
-                       Delta = 0 ;
-                       Done = 1 ;
-               }
-       }
-       *ppLast = 0 ;
-       /*
-        * pTm points to the first Timer that did not run out.
-        * StQueue points to the first Timer that run out.
-        */
-
-       for ( pTComp = pAC->Tim.StQueue ; pTComp ; pTComp = pTComp->TmNext) {
-               SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent,
-                       pTComp->TmPara) ;
-       }
-
-       /* Set head of timer queue to the first timer that did not run out */
-       pAC->Tim.StQueue = pTm ;
-
-       if (Restart && pAC->Tim.StQueue) {
-               /* Restart HW timer */
-               SkHwtStart(pAC,Ioc,pAC->Tim.StQueue->TmDelta) ;
-       }
-}
-
-#endif /* CONFIG_SK98 */
-
-/* End of file */
diff --git a/drivers/sk98lin/skvpd.c b/drivers/sk98lin/skvpd.c
deleted file mode 100644 (file)
index 3b81e67..0000000
+++ /dev/null
@@ -1,1329 +0,0 @@
-/******************************************************************************
- *
- * Name:       skvpd.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.37 $
- * Date:       $Date: 2003/01/13 10:42:45 $
- * Purpose:    Shared software to read and write VPD data
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skvpd.c,v $
- *     Revision 1.37  2003/01/13 10:42:45  rschmidt
- *     Replaced check for PCI device Id from YUKON with GENESIS
- *     to set the VPD size in VpdInit()
- *     Editorial changes
- *
- *     Revision 1.36  2002/11/14 15:16:56  gheinig
- *     Added const specifier to key and buf parameters for VpdPara, VpdRead
- *     and VpdWrite for Diag 7 GUI
- *
- *     Revision 1.35  2002/10/21 14:31:59  gheinig
- *     Took out CVS web garbage at head of file
- *
- *     Revision 1.34  2002/10/21 11:47:24  gheinig
- *     Reverted to version 1.32 due to unwanted commit
- *
- *     Revision 1.32  2002/10/14 16:04:29  rschmidt
- *     Added saving of VPD ROM Size from PCI_OUR_REG_2
- *     Avoid reading of PCI_OUR_REG_2 in VpdTransferBlock()
- *     Editorial changes
- *
- *     Revision 1.31  2002/09/10 09:21:32  mkarl
- *     Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis
- *
- *     Revision 1.30  2002/09/09 14:43:03  mkarl
- *     changes for diagnostics in order to read VPD data before the adapter
- *     has been initialized
- *     editorial changes
- *
- *     Revision 1.29  2002/07/26 13:20:43  mkarl
- *     added Yukon support
- *     save size of VPD in pAC->vpd.vpd_size
- *
- *     Revision 1.28  2002/04/02 15:31:47  afischer
- *     Bug fix in VpdWait()
- *
- *     Revision 1.27  2000/08/10 11:29:06  rassmann
- *     Editorial changes.
- *     Preserving 32-bit alignment in structs for the adapter context.
- *     Removed unused function VpdWriteDword() (#if 0).
- *     Made VpdReadKeyword() available for SKDIAG only.
- *
- *     Revision 1.26  2000/06/13 08:00:01  mkarl
- *     additional cast to avoid compile problems in 64 bit environment
- *
- *     Revision 1.25  1999/11/22 13:39:32  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.24  1999/03/11 14:25:49  malthoff
- *     Replace __STDC__ with SK_KR_PROTO.
- *
- *     Revision 1.23  1999/01/11 15:13:11  gklug
- *     fix: syntax error
- *
- *     Revision 1.22  1998/10/30 06:41:15  gklug
- *     rmv: WARNING
- *
- *     Revision 1.21  1998/10/29 07:15:14  gklug
- *     fix: Write Stream function needs verify.
- *
- *     Revision 1.20  1998/10/28 18:05:08  gklug
- *     chg: no DEBUG in VpdMayWrite
- *
- *     Revision 1.19  1998/10/28 15:56:11  gklug
- *     fix: Return len at end of ReadStream
- *     fix: Write even less than 4 bytes correctly
- *
- *     Revision 1.18  1998/10/28 09:00:47  gklug
- *     fix: unreferenced local vars
- *
- *     Revision 1.17  1998/10/28 08:25:45  gklug
- *     fix: WARNING
- *
- *     Revision 1.16  1998/10/28 08:17:30  gklug
- *     fix: typo
- *
- *     Revision 1.15  1998/10/28 07:50:32  gklug
- *     fix: typo
- *
- *     Revision 1.14  1998/10/28 07:20:38  gklug
- *     chg: Interface functions to use IoC as parameter as well
- *     fix: VpdRead/WriteDWord now returns SK_U32
- *     chg: VPD_IN/OUT names conform to SK_IN/OUT
- *     add: usage of VPD_IN/OUT8 macros
- *     add: VpdRead/Write Stream functions to r/w a stream of data
- *     fix: VpdTransferBlock swapped illegal
- *     add: VpdMayWrite
- *
- *     Revision 1.13  1998/10/22 10:02:37  gklug
- *     fix: SysKonnectFileId typo
- *
- *     Revision 1.12  1998/10/20 10:01:01  gklug
- *     fix: parameter to SkOsGetTime
- *
- *     Revision 1.11  1998/10/15 12:51:48  malthoff
- *     Remove unrequired parameter p in vpd_setup_para().
- *
- *     Revision 1.10  1998/10/08 14:52:43  malthoff
- *     Remove CvsId by SysKonnectFileId.
- *
- *     Revision 1.9  1998/09/16 07:33:52  malthoff
- *     replace memcmp() by SK_MEMCMP and
- *     memcpy() by SK_MEMCPY() to be
- *     independent from the 'C' Standard Library.
- *
- *     Revision 1.8  1998/08/19 12:52:35  malthoff
- *     compiler fix: use SK_VPD_KEY instead of S_VPD.
- *
- *     Revision 1.7  1998/08/19 08:14:01  gklug
- *     fix: remove struct keyword as much as possible from the C-code (see CCC)
- *
- *     Revision 1.6  1998/08/18 13:03:58  gklug
- *     SkOsGetTime now returns SK_U64
- *
- *     Revision 1.5  1998/08/18 08:17:29  malthoff
- *     Ensure we issue a VPD read in vpd_read_dword().
- *     Discard all VPD keywords other than Vx or Yx, where
- *     x is '0..9' or 'A..Z'.
- *
- *     Revision 1.4  1998/07/03 14:52:19  malthoff
- *     Add category SK_DBGCAT_FATAL to some debug macros.
- *     bug fix: correct the keyword name check in vpd_write().
- *
- *     Revision 1.3  1998/06/26 11:16:53  malthoff
- *     Correct the modified File Identifier.
- *
- *     Revision 1.2  1998/06/26 11:13:43  malthoff
- *     Modify the File Identifier.
- *
- *     Revision 1.1  1998/06/19 14:11:08  malthoff
- *     Created, Tests with AIX were performed successfully
- *
- *
- ******************************************************************************/
-
-#include <config.h>
-
-#ifdef CONFIG_SK98
-
-/*
-       Please refer skvpd.txt for infomation how to include this module
- */
-static const char SysKonnectFileId[] =
-       "@(#)$Id: skvpd.c,v 1.37 2003/01/13 10:42:45 rschmidt Exp $ (C) SK";
-
-#include "h/skdrv1st.h"
-#include "h/sktypes.h"
-#include "h/skdebug.h"
-#include "h/skdrv2nd.h"
-
-/*
- * Static functions
- */
-#ifndef SK_KR_PROTO
-static SK_VPD_PARA     *vpd_find_para(
-       SK_AC   *pAC,
-       const char      *key,
-       SK_VPD_PARA *p);
-#else  /* SK_KR_PROTO */
-static SK_VPD_PARA     *vpd_find_para();
-#endif /* SK_KR_PROTO */
-
-/*
- * waits for a completion of a VPD transfer
- * The VPD transfer must complete within SK_TICKS_PER_SEC/16
- *
- * returns     0:      success, transfer completes
- *             error   exit(9) with a error message
- */
-static int VpdWait(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC IoC,    /* IO Context */
-int            event)  /* event to wait for (VPD_READ / VPD_write) completion*/
-{
-       SK_U64  start_time;
-       SK_U16  state;
-
-       SK_DBG_MSG(pAC,SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-               ("VPD wait for %s\n", event?"Write":"Read"));
-       start_time = SkOsGetTime(pAC);
-       do {
-               if (SkOsGetTime(pAC) - start_time > SK_TICKS_PER_SEC) {
-
-                       /* Bug fix AF: Thu Mar 28 2002
-                        * Do not call: VPD_STOP(pAC, IoC);
-                        * A pending VPD read cycle can not be aborted by writing
-                        * VPD_WRITE to the PCI_VPD_ADR_REG (VPD address register).
-                        * Although the write threshold in the OUR-register protects
-                        * VPD read only space from being overwritten this does not
-                        * protect a VPD read from being `converted` into a VPD write
-                        * operation (on the fly). As a consequence the VPD_STOP would
-                        * delete VPD read only data. In case of any problems with the
-                        * I2C bus we exit the loop here. The I2C read operation can
-                        * not be aborted except by a reset (->LR).
-                        */
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_FATAL | SK_DBGCAT_ERR,
-                               ("ERROR:VPD wait timeout\n"));
-                       return(1);
-               }
-
-               VPD_IN16(pAC, IoC, PCI_VPD_ADR_REG, &state);
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-                       ("state = %x, event %x\n",state,event));
-       } while((int)(state & PCI_VPD_FLAG) == event);
-
-       return(0);
-}
-
-#ifdef SKDIAG
-
-/*
- * Read the dword at address 'addr' from the VPD EEPROM.
- *
- * Needed Time:        MIN 1,3 ms      MAX 2,6 ms
- *
- * Note: The DWord is returned in the endianess of the machine the routine
- *       is running on.
- *
- * Returns the data read.
- */
-SK_U32 VpdReadDWord(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC IoC,    /* IO Context */
-int            addr)   /* VPD address */
-{
-       SK_U32  Rtv;
-
-       /* start VPD read */
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-               ("VPD read dword at 0x%x\n",addr));
-       addr &= ~VPD_WRITE;             /* ensure the R/W bit is set to read */
-
-       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)addr);
-
-       /* ignore return code here */
-       (void)VpdWait(pAC, IoC, VPD_READ);
-
-       /* Don't swap here, it's a data stream of bytes */
-       Rtv = 0;
-
-       VPD_IN32(pAC, IoC, PCI_VPD_DAT_REG, &Rtv);
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-               ("VPD read dword data = 0x%x\n",Rtv));
-       return(Rtv);
-}
-
-#endif /* SKDIAG */
-
-#if 0
-
-/*
-       Write the dword 'data' at address 'addr' into the VPD EEPROM, and
-       verify that the data is written.
-
- Needed Time:
-
-.                              MIN             MAX
-. -------------------------------------------------------------------
-. write                                1.8 ms          3.6 ms
-. internal write cyles         0.7 ms          7.0 ms
-. -------------------------------------------------------------------
-. over all program time                2.5 ms          10.6 ms
-. read                         1.3 ms          2.6 ms
-. -------------------------------------------------------------------
-. over all                     3.8 ms          13.2 ms
-.
-
-
- Returns       0:      success
-                       1:      error,  I2C transfer does not terminate
-                       2:      error,  data verify error
-
- */
-static int VpdWriteDWord(
-SK_AC  *pAC,   /* pAC pointer */
-SK_IOC IoC,    /* IO Context */
-int            addr,   /* VPD address */
-SK_U32 data)   /* VPD data to write */
-{
-       /* start VPD write */
-       /* Don't swap here, it's a data stream of bytes */
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-               ("VPD write dword at addr 0x%x, data = 0x%x\n",addr,data));
-       VPD_OUT32(pAC, IoC, PCI_VPD_DAT_REG, (SK_U32)data);
-       /* But do it here */
-       addr |= VPD_WRITE;
-
-       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)(addr | VPD_WRITE));
-
-       /* this may take up to 10,6 ms */
-       if (VpdWait(pAC, IoC, VPD_WRITE)) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                       ("Write Timed Out\n"));
-               return(1);
-       };
-
-       /* verify data */
-       if (VpdReadDWord(pAC, IoC, addr) != data) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("Data Verify Error\n"));
-               return(2);
-       }
-       return(0);
-}      /* VpdWriteDWord */
-
-#endif /* 0 */
-
-/*
- *     Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
- *     or to the I2C EEPROM.
- *
- * Returns number of bytes read / written.
- */
-static int VpdWriteStream(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC IoC,    /* IO Context */
-char   *buf,   /* data buffer */
-int            Addr,   /* VPD start address */
-int            Len)    /* number of bytes to read / to write */
-{
-       int             i;
-       int             j;
-       SK_U16  AdrReg;
-       int             Rtv;
-       SK_U8   * pComp;        /* Compare pointer */
-       SK_U8   Data;           /* Input Data for Compare */
-
-       /* Init Compare Pointer */
-       pComp = (SK_U8 *) buf;
-
-       for (i = 0; i < Len; i++, buf++) {
-               if ((i%sizeof(SK_U32)) == 0) {
-                       /*
-                        * At the begin of each cycle read the Data Reg
-                        * So it is initialized even if only a few bytes
-                        * are written.
-                        */
-                       AdrReg = (SK_U16) Addr;
-                       AdrReg &= ~VPD_WRITE;   /* READ operation */
-
-                       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
-
-                       /* Wait for termination */
-                       Rtv = VpdWait(pAC, IoC, VPD_READ);
-                       if (Rtv != 0) {
-                               return(i);
-                       }
-               }
-
-               /* Write current Byte */
-               VPD_OUT8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)),
-                               *(SK_U8*)buf);
-
-               if (((i%sizeof(SK_U32)) == 3) || (i == (Len - 1))) {
-                       /* New Address needs to be written to VPD_ADDR reg */
-                       AdrReg = (SK_U16) Addr;
-                       Addr += sizeof(SK_U32);
-                       AdrReg |= VPD_WRITE;    /* WRITE operation */
-
-                       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
-
-                       /* Wait for termination */
-                       Rtv = VpdWait(pAC, IoC, VPD_WRITE);
-                       if (Rtv != 0) {
-                               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                                       ("Write Timed Out\n"));
-                               return(i - (i%sizeof(SK_U32)));
-                       }
-
-                       /*
-                        * Now re-read to verify
-                        */
-                       AdrReg &= ~VPD_WRITE;   /* READ operation */
-
-                       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
-
-                       /* Wait for termination */
-                       Rtv = VpdWait(pAC, IoC, VPD_READ);
-                       if (Rtv != 0) {
-                               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                                       ("Verify Timed Out\n"));
-                               return(i - (i%sizeof(SK_U32)));
-                       }
-
-                       for (j = 0; j <= (int)(i%sizeof(SK_U32)); j++, pComp++) {
-
-                               VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + j, &Data);
-
-                               if (Data != *pComp) {
-                                       /* Verify Error */
-                                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                                               ("WriteStream Verify Error\n"));
-                                       return(i - (i%sizeof(SK_U32)) + j);
-                               }
-                       }
-               }
-       }
-
-       return(Len);
-}
-
-
-/*
- *     Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
- *     or to the I2C EEPROM.
- *
- * Returns number of bytes read / written.
- */
-static int VpdReadStream(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC IoC,    /* IO Context */
-char   *buf,   /* data buffer */
-int            Addr,   /* VPD start address */
-int            Len)    /* number of bytes to read / to write */
-{
-       int             i;
-       SK_U16  AdrReg;
-       int             Rtv;
-
-       for (i = 0; i < Len; i++, buf++) {
-               if ((i%sizeof(SK_U32)) == 0) {
-                       /* New Address needs to be written to VPD_ADDR reg */
-                       AdrReg = (SK_U16) Addr;
-                       Addr += sizeof(SK_U32);
-                       AdrReg &= ~VPD_WRITE;   /* READ operation */
-
-                       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
-
-                       /* Wait for termination */
-                       Rtv = VpdWait(pAC, IoC, VPD_READ);
-                       if (Rtv != 0) {
-                               return(i);
-                       }
-               }
-               VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)),
-                       (SK_U8 *)buf);
-       }
-
-       return(Len);
-}
-
-/*
- *     Read ore writes 'len' bytes of VPD data, starting at 'addr' from
- *     or to the I2C EEPROM.
- *
- * Returns number of bytes read / written.
- */
-static int VpdTransferBlock(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC IoC,    /* IO Context */
-char   *buf,   /* data buffer */
-int            addr,   /* VPD start address */
-int            len,    /* number of bytes to read / to write */
-int            dir)    /* transfer direction may be VPD_READ or VPD_WRITE */
-{
-       int             Rtv;    /* Return value */
-       int             vpd_rom_size;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-               ("VPD %s block, addr = 0x%x, len = %d\n",
-               dir ? "write" : "read", addr, len));
-
-       if (len == 0)
-               return(0);
-
-       vpd_rom_size = pAC->vpd.rom_size;
-
-       if (addr > vpd_rom_size - 4) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("Address error: 0x%x, exp. < 0x%x\n",
-                       addr, vpd_rom_size - 4));
-               return(0);
-       }
-
-       if (addr + len > vpd_rom_size) {
-               len = vpd_rom_size - addr;
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                       ("Warning: len was cut to %d\n", len));
-       }
-
-       if (dir == VPD_READ) {
-               Rtv = VpdReadStream(pAC, IoC, buf, addr, len);
-       }
-       else {
-               Rtv = VpdWriteStream(pAC, IoC, buf, addr, len);
-       }
-
-       return(Rtv);
-}
-
-#ifdef SKDIAG
-
-/*
- *     Read 'len' bytes of VPD data, starting at 'addr'.
- *
- * Returns number of bytes read.
- */
-int VpdReadBlock(
-SK_AC  *pAC,   /* pAC pointer */
-SK_IOC IoC,    /* IO Context */
-char   *buf,   /* buffer were the data should be stored */
-int            addr,   /* start reading at the VPD address */
-int            len)    /* number of bytes to read */
-{
-       return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ));
-}
-
-/*
- *     Write 'len' bytes of *but to the VPD EEPROM, starting at 'addr'.
- *
- * Returns number of bytes writes.
- */
-int VpdWriteBlock(
-SK_AC  *pAC,   /* pAC pointer */
-SK_IOC IoC,    /* IO Context */
-char   *buf,   /* buffer, holds the data to write */
-int            addr,   /* start writing at the VPD address */
-int            len)    /* number of bytes to write */
-{
-       return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE));
-}
-#endif /* SKDIAG */
-
-/*
- * (re)initialize the VPD buffer
- *
- * Reads the VPD data from the EEPROM into the VPD buffer.
- * Get the remaining read only and read / write space.
- *
- * return      0:      success
- *             1:      fatal VPD error
- */
-static int VpdInit(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC IoC)    /* IO Context */
-{
-       SK_VPD_PARA *r, rp;     /* RW or RV */
-       int             i;
-       unsigned char   x;
-       int             vpd_size;
-       SK_U16  dev_id;
-       SK_U32  our_reg2;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit .. "));
-
-       VPD_IN16(pAC, IoC, PCI_DEVICE_ID, &dev_id);
-
-       VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2);
-
-       pAC->vpd.rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14);
-
-       /*
-        * this function might get used before the hardware is initialized
-        * therefore we cannot always trust in GIChipId
-        */
-       if (((pAC->vpd.v.vpd_status & VPD_VALID) == 0 &&
-               dev_id != VPD_DEV_ID_GENESIS) ||
-               ((pAC->vpd.v.vpd_status & VPD_VALID) != 0 &&
-               !pAC->GIni.GIGenesis)) {
-
-               /* for Yukon the VPD size is always 256 */
-               vpd_size = VPD_SIZE_YUKON;
-       }
-       else {
-               /* Genesis uses the maximum ROM size up to 512 for VPD */
-               if (pAC->vpd.rom_size > VPD_SIZE_GENESIS) {
-                       vpd_size = VPD_SIZE_GENESIS;
-               }
-               else {
-                       vpd_size = pAC->vpd.rom_size;
-               }
-       }
-
-       /* read the VPD data into the VPD buffer */
-       if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf, 0, vpd_size, VPD_READ)
-               != vpd_size) {
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                       ("Block Read Error\n"));
-               return(1);
-       }
-
-       pAC->vpd.vpd_size = vpd_size;
-
-       /* find the end tag of the RO area */
-       if (!(r = vpd_find_para(pAC, VPD_RV, &rp))) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("Encoding Error: RV Tag not found\n"));
-               return(1);
-       }
-
-       if (r->p_val + r->p_len > pAC->vpd.vpd_buf + vpd_size/2) {
-               SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("Encoding Error: Invalid VPD struct size\n"));
-               return(1);
-       }
-       pAC->vpd.v.vpd_free_ro = r->p_len - 1;
-
-       /* test the checksum */
-       for (i = 0, x = 0; (unsigned)i <= (unsigned)vpd_size/2 - r->p_len; i++) {
-               x += pAC->vpd.vpd_buf[i];
-       }
-
-       if (x != 0) {
-               /* checksum error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("VPD Checksum Error\n"));
-               return(1);
-       }
-
-       /* find and check the end tag of the RW area */
-       if (!(r = vpd_find_para(pAC, VPD_RW, &rp))) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("Encoding Error: RV Tag not found\n"));
-               return(1);
-       }
-
-       if (r->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("Encoding Error: Invalid VPD struct size\n"));
-               return(1);
-       }
-       pAC->vpd.v.vpd_free_rw = r->p_len;
-
-       /* everything seems to be ok */
-       if (pAC->GIni.GIChipId != 0) {
-               pAC->vpd.v.vpd_status |= VPD_VALID;
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT,
-               ("done. Free RO = %d, Free RW = %d\n",
-               pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
-
-       return(0);
-}
-
-/*
- *     find the Keyword 'key' in the VPD buffer and fills the
- *     parameter struct 'p' with it's values
- *
- * returns     *p      success
- *             0:      parameter was not found or VPD encoding error
- */
-static SK_VPD_PARA *vpd_find_para(
-SK_AC          *pAC,   /* common data base */
-const char     *key,   /* keyword to find (e.g. "MN") */
-SK_VPD_PARA *p)                /* parameter description struct */
-{
-       char *v ;       /* points to VPD buffer */
-       int max;        /* Maximum Number of Iterations */
-
-       v = pAC->vpd.vpd_buf;
-       max = 128;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-               ("VPD find para %s .. ",key));
-
-       /* check mandatory resource type ID string (Product Name) */
-       if (*v != (char)RES_ID) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("Error: 0x%x missing\n", RES_ID));
-               return(0);
-       }
-
-       if (strcmp(key, VPD_NAME) == 0) {
-               p->p_len = VPD_GET_RES_LEN(v);
-               p->p_val = VPD_GET_VAL(v);
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-                       ("found, len = %d\n", p->p_len));
-               return(p);
-       }
-
-       v += 3 + VPD_GET_RES_LEN(v) + 3;
-       for (;; ) {
-               if (SK_MEMCMP(key,v,2) == 0) {
-                       p->p_len = VPD_GET_VPD_LEN(v);
-                       p->p_val = VPD_GET_VAL(v);
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-                               ("found, len = %d\n",p->p_len));
-                       return(p);
-               }
-
-               /* exit when reaching the "RW" Tag or the maximum of itera. */
-               max--;
-               if (SK_MEMCMP(VPD_RW,v,2) == 0 || max == 0) {
-                       break;
-               }
-
-               if (SK_MEMCMP(VPD_RV,v,2) == 0) {
-                       v += 3 + VPD_GET_VPD_LEN(v) + 3;        /* skip VPD-W */
-               }
-               else {
-                       v += 3 + VPD_GET_VPD_LEN(v);
-               }
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-                       ("scanning '%c%c' len = %d\n",v[0],v[1],v[2]));
-       }
-
-#ifdef DEBUG
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ("not found\n"));
-       if (max == 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("Key/Len Encoding error\n"));
-       }
-#endif /* DEBUG */
-       return(0);
-}
-
-/*
- *     Move 'n' bytes. Begin with the last byte if 'n' is > 0,
- *     Start with the last byte if n is < 0.
- *
- * returns nothing
- */
-static void vpd_move_para(
-char   *start,         /* start of memory block */
-char   *end,           /* end of memory block to move */
-int            n)                      /* number of bytes the memory block has to be moved */
-{
-       char *p;
-       int i;          /* number of byte copied */
-
-       if (n == 0)
-               return;
-
-       i = (int) (end - start + 1);
-       if (n < 0) {
-               p = start + n;
-               while (i != 0) {
-                       *p++ = *start++;
-                       i--;
-               }
-       }
-       else {
-               p = end + n;
-               while (i != 0) {
-                       *p-- = *end--;
-                       i--;
-               }
-       }
-}
-
-/*
- *     setup the VPD keyword 'key' at 'ip'.
- *
- * returns nothing
- */
-static void vpd_insert_key(
-const char     *key,   /* keyword to insert */
-const char     *buf,   /* buffer with the keyword value */
-int            len,            /* length of the value string */
-char   *ip)            /* inseration point */
-{
-       SK_VPD_KEY *p;
-
-       p = (SK_VPD_KEY *) ip;
-       p->p_key[0] = key[0];
-       p->p_key[1] = key[1];
-       p->p_len = (unsigned char) len;
-       SK_MEMCPY(&p->p_val,buf,len);
-}
-
-/*
- *     Setup the VPD end tag "RV" / "RW".
- *     Also correct the remaining space variables vpd_free_ro / vpd_free_rw.
- *
- * returns     0:      success
- *             1:      encoding error
- */
-static int vpd_mod_endtag(
-SK_AC  *pAC,           /* common data base */
-char   *etp)           /* end pointer input position */
-{
-       SK_VPD_KEY *p;
-       unsigned char   x;
-       int     i;
-       int     vpd_size;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-               ("VPD modify endtag at 0x%x = '%c%c'\n",etp,etp[0],etp[1]));
-
-       vpd_size = pAC->vpd.vpd_size;
-
-       p = (SK_VPD_KEY *) etp;
-
-       if (p->p_key[0] != 'R' || (p->p_key[1] != 'V' && p->p_key[1] != 'W')) {
-               /* something wrong here, encoding error */
-               SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("Encoding Error: invalid end tag\n"));
-               return(1);
-       }
-       if (etp > pAC->vpd.vpd_buf + vpd_size/2) {
-               /* create "RW" tag */
-               p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size-etp-3-1);
-               pAC->vpd.v.vpd_free_rw = (int) p->p_len;
-               i = pAC->vpd.v.vpd_free_rw;
-               etp += 3;
-       }
-       else {
-               /* create "RV" tag */
-               p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size/2-etp-3);
-               pAC->vpd.v.vpd_free_ro = (int) p->p_len - 1;
-
-               /* setup checksum */
-               for (i = 0, x = 0; i < vpd_size/2 - p->p_len; i++) {
-                       x += pAC->vpd.vpd_buf[i];
-               }
-               p->p_val = (char) 0 - x;
-               i = pAC->vpd.v.vpd_free_ro;
-               etp += 4;
-       }
-       while (i) {
-               *etp++ = 0x00;
-               i--;
-       }
-
-       return(0);
-}
-
-/*
- *     Insert a VPD keyword into the VPD buffer.
- *
- *     The keyword 'key' is inserted at the position 'ip' in the
- *     VPD buffer.
- *     The keywords behind the input position will
- *     be moved. The VPD end tag "RV" or "RW" is generated again.
- *
- * returns     0:      success
- *             2:      value string was cut
- *             4:      VPD full, keyword was not written
- *             6:      fatal VPD error
- *
- */
-int    VpdSetupPara(
-SK_AC  *pAC,           /* common data base */
-const char     *key,   /* keyword to insert */
-const char     *buf,   /* buffer with the keyword value */
-int            len,            /* length of the keyword value */
-int            type,           /* VPD_RO_KEY or VPD_RW_KEY */
-int            op)                     /* operation to do: ADD_KEY or OWR_KEY */
-{
-       SK_VPD_PARA vp;
-       char    *etp;           /* end tag position */
-       int     free;           /* remaining space in selected area */
-       char    *ip;            /* input position inside the VPD buffer */
-       int     rtv;            /* return code */
-       int     head;           /* additional haeder bytes to move */
-       int     found;          /* additinoal bytes if the keyword was found */
-       int vpd_size;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-               ("VPD setup para key = %s, val = %s\n",key,buf));
-
-       vpd_size = pAC->vpd.vpd_size;
-
-       rtv = 0;
-       ip = 0;
-       if (type == VPD_RW_KEY) {
-               /* end tag is "RW" */
-               free = pAC->vpd.v.vpd_free_rw;
-               etp = pAC->vpd.vpd_buf + (vpd_size - free - 1 - 3);
-       }
-       else {
-               /* end tag is "RV" */
-               free = pAC->vpd.v.vpd_free_ro;
-               etp = pAC->vpd.vpd_buf + (vpd_size/2 - free - 4);
-       }
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-               ("Free RO = %d, Free RW = %d\n",
-               pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
-
-       head = 0;
-       found = 0;
-       if (op == OWR_KEY) {
-               if (vpd_find_para(pAC, key, &vp)) {
-                       found = 3;
-                       ip = vp.p_val - 3;
-                       free += vp.p_len + 3;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-                               ("Overwrite Key\n"));
-               }
-               else {
-                       op = ADD_KEY;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-                               ("Add Key\n"));
-               }
-       }
-       if (op == ADD_KEY) {
-               ip = etp;
-               vp.p_len = 0;
-               head = 3;
-       }
-
-       if (len + 3 > free) {
-               if (free < 7) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("VPD Buffer Overflow, keyword not written\n"));
-                       return(4);
-               }
-               /* cut it again */
-               len = free - 3;
-               rtv = 2;
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                       ("VPD Buffer Full, Keyword was cut\n"));
-       }
-
-       vpd_move_para(ip + vp.p_len + found, etp+2, len-vp.p_len+head);
-       vpd_insert_key(key, buf, len, ip);
-       if (vpd_mod_endtag(pAC, etp + len - vp.p_len + head)) {
-               pAC->vpd.v.vpd_status &= ~VPD_VALID;
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                       ("VPD Encoding Error\n"));
-               return(6);
-       }
-
-       return(rtv);
-}
-
-
-/*
- *     Read the contents of the VPD EEPROM and copy it to the
- *     VPD buffer if not already done.
- *
- * return:     A pointer to the vpd_status structure. The structure contains
- *             this fields.
- */
-SK_VPD_STATUS *VpdStat(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC IoC)    /* IO Context */
-{
-       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
-               (void)VpdInit(pAC, IoC);
-       }
-       return(&pAC->vpd.v);
-}
-
-
-/*
- *     Read the contents of the VPD EEPROM and copy it to the VPD
- *     buffer if not already done.
- *     Scan the VPD buffer for VPD keywords and create the VPD
- *     keyword list by copying the keywords to 'buf', all after
- *     each other and terminated with a '\0'.
- *
- * Exceptions: o The Resource Type ID String (product name) is called "Name"
- *             o The VPD end tags 'RV' and 'RW' are not listed
- *
- *     The number of copied keywords is counted in 'elements'.
- *
- * returns     0:      success
- *             2:      buffer overfull, one or more keywords are missing
- *             6:      fatal VPD error
- *
- *     example values after returning:
- *
- *             buf =   "Name\0PN\0EC\0MN\0SN\0CP\0VF\0VL\0YA\0"
- *             *len =          30
- *             *elements =      9
- */
-int VpdKeys(
-SK_AC  *pAC,           /* common data base */
-SK_IOC IoC,            /* IO Context */
-char   *buf,           /* buffer where to copy the keywords */
-int            *len,           /* buffer length */
-int            *elements)      /* number of keywords returned */
-{
-       char *v;
-       int n;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("list VPD keys .. "));
-       *elements = 0;
-       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
-               if (VpdInit(pAC, IoC) != 0) {
-                       *len = 0;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("VPD Init Error, terminated\n"));
-                       return(6);
-               }
-       }
-
-       if ((signed)strlen(VPD_NAME) + 1 <= *len) {
-               v = pAC->vpd.vpd_buf;
-               strcpy(buf,VPD_NAME);
-               n = strlen(VPD_NAME) + 1;
-               buf += n;
-               *elements = 1;
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
-                       ("'%c%c' ",v[0],v[1]));
-       }
-       else {
-               *len = 0;
-               SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-                       ("buffer overflow\n"));
-               return(2);
-       }
-
-       v += 3 + VPD_GET_RES_LEN(v) + 3;
-       for (;; ) {
-               /* exit when reaching the "RW" Tag */
-               if (SK_MEMCMP(VPD_RW,v,2) == 0) {
-                       break;
-               }
-
-               if (SK_MEMCMP(VPD_RV,v,2) == 0) {
-                       v += 3 + VPD_GET_VPD_LEN(v) + 3;        /* skip VPD-W */
-                       continue;
-               }
-
-               if (n+3 <= *len) {
-                       SK_MEMCPY(buf,v,2);
-                       buf += 2;
-                       *buf++ = '\0';
-                       n += 3;
-                       v += 3 + VPD_GET_VPD_LEN(v);
-                       *elements += 1;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
-                               ("'%c%c' ",v[0],v[1]));
-               }
-               else {
-                       *len = n;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("buffer overflow\n"));
-                       return(2);
-               }
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("\n"));
-       *len = n;
-       return(0);
-}
-
-
-/*
- *     Read the contents of the VPD EEPROM and copy it to the
- *     VPD buffer if not already done. Search for the VPD keyword
- *     'key' and copy its value to 'buf'. Add a terminating '\0'.
- *     If the value does not fit into the buffer cut it after
- *     'len' - 1 bytes.
- *
- * returns     0:      success
- *             1:      keyword not found
- *             2:      value string was cut
- *             3:      VPD transfer timeout
- *             6:      fatal VPD error
- */
-int VpdRead(
-SK_AC          *pAC,   /* common data base */
-SK_IOC         IoC,    /* IO Context */
-const char     *key,   /* keyword to read (e.g. "MN") */
-char           *buf,   /* buffer where to copy the keyword value */
-int                    *len)   /* buffer length */
-{
-       SK_VPD_PARA *p, vp;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("VPD read %s .. ", key));
-       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
-               if (VpdInit(pAC, IoC) != 0) {
-                       *len = 0;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("VPD init error\n"));
-                       return(6);
-               }
-       }
-
-       if ((p = vpd_find_para(pAC, key, &vp)) != NULL) {
-               if (p->p_len > (*(unsigned *)len)-1) {
-                       p->p_len = *len - 1;
-               }
-               SK_MEMCPY(buf, p->p_val, p->p_len);
-               buf[p->p_len] = '\0';
-               *len = p->p_len;
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
-                       ("%c%c%c%c.., len = %d\n",
-                       buf[0],buf[1],buf[2],buf[3],*len));
-       }
-       else {
-               *len = 0;
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("not found\n"));
-               return(1);
-       }
-       return(0);
-}
-
-
-/*
- *     Check whether a given key may be written
- *
- * returns
- *     SK_TRUE         Yes it may be written
- *     SK_FALSE        No it may be written
- */
-SK_BOOL VpdMayWrite(
-char   *key)   /* keyword to write (allowed values "Yx", "Vx") */
-{
-       if ((*key != 'Y' && *key != 'V') ||
-               key[1] < '0' || key[1] > 'Z' ||
-               (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
-
-               return(SK_FALSE);
-       }
-       return(SK_TRUE);
-}
-
-/*
- *     Read the contents of the VPD EEPROM and copy it to the VPD
- *     buffer if not already done. Insert/overwrite the keyword 'key'
- *     in the VPD buffer. Cut the keyword value if it does not fit
- *     into the VPD read / write area.
- *
- * returns     0:      success
- *             2:      value string was cut
- *             3:      VPD transfer timeout
- *             4:      VPD full, keyword was not written
- *             5:      keyword cannot be written
- *             6:      fatal VPD error
- */
-int VpdWrite(
-SK_AC          *pAC,   /* common data base */
-SK_IOC         IoC,    /* IO Context */
-const char     *key,   /* keyword to write (allowed values "Yx", "Vx") */
-const char     *buf)   /* buffer where the keyword value can be read from */
-{
-       int len;                /* length of the keyword to write */
-       int rtv;                /* return code */
-       int rtv2;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX,
-               ("VPD write %s = %s\n",key,buf));
-
-       if ((*key != 'Y' && *key != 'V') ||
-               key[1] < '0' || key[1] > 'Z' ||
-               (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                       ("illegal key tag, keyword not written\n"));
-               return(5);
-       }
-
-       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
-               if (VpdInit(pAC, IoC) != 0) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("VPD init error\n"));
-                       return(6);
-               }
-       }
-
-       rtv = 0;
-       len = strlen(buf);
-       if (len > VPD_MAX_LEN) {
-               /* cut it */
-               len = VPD_MAX_LEN;
-               rtv = 2;
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                       ("keyword too long, cut after %d bytes\n",VPD_MAX_LEN));
-       }
-       if ((rtv2 = VpdSetupPara(pAC, key, buf, len, VPD_RW_KEY, OWR_KEY)) != 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                       ("VPD write error\n"));
-               return(rtv2);
-       }
-
-       return(rtv);
-}
-
-/*
- *     Read the contents of the VPD EEPROM and copy it to the
- *     VPD buffer if not already done. Remove the VPD keyword
- *     'key' from the VPD buffer.
- *     Only the keywords in the read/write area can be deleted.
- *     Keywords in the read only area cannot be deleted.
- *
- * returns     0:      success, keyword was removed
- *             1:      keyword not found
- *             5:      keyword cannot be deleted
- *             6:      fatal VPD error
- */
-int VpdDelete(
-SK_AC  *pAC,   /* common data base */
-SK_IOC IoC,    /* IO Context */
-char   *key)   /* keyword to read (e.g. "MN") */
-{
-       SK_VPD_PARA *p, vp;
-       char *etp;
-       int     vpd_size;
-
-       vpd_size = pAC->vpd.vpd_size;
-
-       SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("VPD delete key %s\n",key));
-       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
-               if (VpdInit(pAC, IoC) != 0) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("VPD init error\n"));
-                       return(6);
-               }
-       }
-
-       if ((p = vpd_find_para(pAC, key, &vp)) != NULL) {
-               if (p->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
-                       /* try to delete read only keyword */
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("cannot delete RO keyword\n"));
-                       return(5);
-               }
-
-               etp = pAC->vpd.vpd_buf + (vpd_size-pAC->vpd.v.vpd_free_rw-1-3);
-
-               vpd_move_para(vp.p_val+vp.p_len, etp+2,
-                       - ((int)(vp.p_len + 3)));
-               if (vpd_mod_endtag(pAC, etp - vp.p_len - 3)) {
-                       pAC->vpd.v.vpd_status &= ~VPD_VALID;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("VPD encoding error\n"));
-                       return(6);
-               }
-       }
-       else {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                       ("keyword not found\n"));
-               return(1);
-       }
-
-       return(0);
-}
-
-/*
- *     If the VPD buffer contains valid data write the VPD
- *     read/write area back to the VPD EEPROM.
- *
- * returns     0:      success
- *             3:      VPD transfer timeout
- */
-int VpdUpdate(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC IoC)    /* IO Context */
-{
-       int vpd_size;
-
-       vpd_size = pAC->vpd.vpd_size;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("VPD update .. "));
-       if ((pAC->vpd.v.vpd_status & VPD_VALID) != 0) {
-               if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf + vpd_size/2,
-                       vpd_size/2, vpd_size/2, VPD_WRITE) != vpd_size/2) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("transfer timed out\n"));
-                       return(3);
-               }
-       }
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("done\n"));
-       return(0);
-}
-
-
-/*
- *     Read the contents of the VPD EEPROM and copy it to the VPD buffer
- *     if not already done. If the keyword "VF" is not present it will be
- *     created and the error log message will be stored to this keyword.
- *     If "VF" is not present the error log message will be stored to the
- *     keyword "VL". "VL" will created or overwritten if "VF" is present.
- *     The VPD read/write area is saved to the VPD EEPROM.
- *
- * returns nothing, errors will be ignored.
- */
-void VpdErrLog(
-SK_AC  *pAC,   /* common data base */
-SK_IOC IoC,    /* IO Context */
-char   *msg)   /* error log message */
-{
-       SK_VPD_PARA *v, vf;     /* VF */
-       int len;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX,
-               ("VPD error log msg %s\n", msg));
-       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
-               if (VpdInit(pAC, IoC) != 0) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("VPD init error\n"));
-                       return;
-               }
-       }
-
-       len = strlen(msg);
-       if (len > VPD_MAX_LEN) {
-               /* cut it */
-               len = VPD_MAX_LEN;
-       }
-       if ((v = vpd_find_para(pAC, VPD_VF, &vf)) != NULL) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("overwrite VL\n"));
-               (void)VpdSetupPara(pAC, VPD_VL, msg, len, VPD_RW_KEY, OWR_KEY);
-       }
-       else {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("write VF\n"));
-               (void)VpdSetupPara(pAC, VPD_VF, msg, len, VPD_RW_KEY, ADD_KEY);
-       }
-
-       (void)VpdUpdate(pAC, IoC);
-}
-
-#endif /* CONFIG_SK98 */
diff --git a/drivers/sk98lin/skxmac2.c b/drivers/sk98lin/skxmac2.c
deleted file mode 100644 (file)
index e6b5a95..0000000
+++ /dev/null
@@ -1,4396 +0,0 @@
-/******************************************************************************
- *
- * Name:       skxmac2.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.91 $
- * Date:       $Date: 2003/02/05 15:09:34 $
- * Purpose:    Contains functions to initialize the MACs and PHYs
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * History:
- *
- *     $Log: skxmac2.c,v $
- *     Revision 1.91  2003/02/05 15:09:34  rschmidt
- *     Removed setting of 'Collision Test'-bit in SkGmInitPhyMarv().
- *     Disabled auto-update for speed, duplex and flow-control when
- *     auto-negotiation is not enabled (Bug Id #10766).
- *     Editorial changes.
- *
- *     Revision 1.90  2003/01/29 13:35:19  rschmidt
- *     Increment Rx FIFO Overflow counter only in DEBUG-mode.
- *     Corrected define for blinking active LED.
- *
- *     Revision 1.89  2003/01/28 16:37:45  rschmidt
- *     Changed init for blinking active LED
- *
- *     Revision 1.88  2003/01/28 10:09:38  rschmidt
- *     Added debug outputs in SkGmInitMac().
- *     Added customized init of LED registers in SkGmInitPhyMarv(),
- *     for blinking active LED (#ifdef ACT_LED_BLINK) and
- *     for normal duplex LED (#ifdef DUP_LED_NORMAL).
- *     Editorial changes.
- *
- *     Revision 1.87  2002/12/10 14:39:05  rschmidt
- *     Improved initialization of GPHY in SkGmInitPhyMarv().
- *     Editorial changes.
- *
- *     Revision 1.86  2002/12/09 15:01:12  rschmidt
- *     Added setup of Ext. PHY Specific Ctrl Reg (downshift feature).
- *
- *     Revision 1.85  2002/12/05 14:09:16  rschmidt
- *     Improved avoiding endless loop in SkGmPhyWrite(), SkGmPhyWrite().
- *     Added additional advertising for 10Base-T when 100Base-T is selected.
- *     Added case SK_PHY_MARV_FIBER for YUKON Fiber adapter.
- *     Editorial changes.
- *
- *     Revision 1.84  2002/11/15 12:50:09  rschmidt
- *     Changed SkGmCableDiagStatus() when getting results.
- *
- *     Revision 1.83  2002/11/13 10:28:29  rschmidt
- *     Added some typecasts to avoid compiler warnings.
- *
- *     Revision 1.82  2002/11/13 09:20:46  rschmidt
- *     Replaced for(..) with do {} while (...) in SkXmUpdateStats().
- *     Replaced 2 macros GM_IN16() with 1 GM_IN32() in SkGmMacStatistic().
- *     Added SkGmCableDiagStatus() for Virtual Cable Test (VCT).
- *     Editorial changes.
- *
- *     Revision 1.81  2002/10/28 14:28:08  rschmidt
- *     Changed MAC address setup for GMAC in SkGmInitMac().
- *     Optimized handling of counter overflow IRQ in SkGmOverflowStatus().
- *     Editorial changes.
- *
- *     Revision 1.80  2002/10/14 15:29:44  rschmidt
- *     Corrected disabling of all PHY IRQs.
- *     Added WA for deviation #16 (address used for pause packets).
- *     Set Pause Mode in SkMacRxTxEnable() only for Genesis.
- *     Added IRQ and counter for Receive FIFO Overflow in DEBUG-mode.
- *     SkXmTimeStamp() replaced by SkMacTimeStamp().
- *     Added clearing of GMAC Tx FIFO Underrun IRQ in SkGmIrq().
- *     Editorial changes.
- *
- *     Revision 1.79  2002/10/10 15:55:36  mkarl
- *     changes for PLinkSpeedUsed
- *
- *     Revision 1.78  2002/09/12 09:39:51  rwahl
- *     Removed deactivate code for SIRQ overflow event separate for TX/RX.
- *
- *     Revision 1.77  2002/09/09 12:26:37  mkarl
- *     added handling for Yukon to SkXmTimeStamp
- *
- *     Revision 1.76  2002/08/21 16:41:16  rschmidt
- *     Added bit GPC_ENA_XC (Enable MDI crossover) in HWCFG_MODE.
- *     Added forced speed settings in SkGmInitPhyMarv().
- *     Added settings of full/half duplex capabilities for YUKON Fiber.
- *     Editorial changes.
- *
- *     Revision 1.75  2002/08/16 15:12:01  rschmidt
- *     Replaced all if(GIChipId == CHIP_ID_GENESIS) with new entry GIGenesis.
- *     Added function SkMacHashing() for ADDR-Module.
- *     Removed functions SkXmClrSrcCheck(), SkXmClrHashAddr() (calls replaced
- *     with macros).
- *     Removed functions SkGmGetMuxConfig().
- *     Added HWCFG_MODE init for YUKON Fiber.
- *     Changed initialization of GPHY in SkGmInitPhyMarv().
- *     Changed check of parameter in SkXmMacStatistic().
- *     Editorial changes.
- *
- *     Revision 1.74  2002/08/12 14:00:17  rschmidt
- *     Replaced usage of Broadcom PHY Ids with defines.
- *     Corrected error messages in SkGmMacStatistic().
- *     Made SkMacPromiscMode() public for ADDR-Modul.
- *     Editorial changes.
- *
- *     Revision 1.73  2002/08/08 16:26:24  rschmidt
- *     Improved reset sequence for YUKON in SkGmHardRst() and SkGmInitMac().
- *     Replaced XMAC Rx High Watermark init value with SK_XM_RX_HI_WM.
- *     Editorial changes.
- *
- *     Revision 1.72  2002/07/24 15:11:19  rschmidt
- *     Fixed wrong placement of parenthesis.
- *     Editorial changes.
- *
- *     Revision 1.71  2002/07/23 16:05:18  rschmidt
- *     Added global functions for PHY: SkGePhyRead(), SkGePhyWrite().
- *     Fixed Tx Counter Overflow IRQ (Bug ID #10730).
- *     Editorial changes.
- *
- *     Revision 1.70  2002/07/18 14:27:27  rwahl
- *     Fixed syntax error.
- *
- *     Revision 1.69  2002/07/17 17:08:47  rwahl
- *     Fixed check in SkXmMacStatistic().
- *
- *     Revision 1.68  2002/07/16 07:35:24  rwahl
- *     Removed check for cleared mib counter in SkGmResetCounter().
- *
- *     Revision 1.67  2002/07/15 18:35:56  rwahl
- *     Added SkXmUpdateStats(), SkGmUpdateStats(), SkXmMacStatistic(),
- *       SkGmMacStatistic(), SkXmResetCounter(), SkGmResetCounter(),
- *       SkXmOverflowStatus(), SkGmOverflowStatus().
- *     Changes to SkXmIrq() & SkGmIrq(): Combined SIRQ Overflow for both
- *       RX & TX.
- *     Changes to SkGmInitMac(): call to SkGmResetCounter().
- *     Editorial changes.
- *
- *     Revision 1.66  2002/07/15 15:59:30  rschmidt
- *     Added PHY Address in SkXmPhyRead(), SkXmPhyWrite().
- *     Added MIB Clear Counter in SkGmInitMac().
- *     Added Duplex and Flow-Control settings.
- *     Reset all Multicast filtering Hash reg. in SkGmInitMac().
- *     Added new function: SkGmGetMuxConfig().
- *     Editorial changes.
- *
- *     Revision 1.65  2002/06/10 09:35:39  rschmidt
- *     Replaced C++ comments (//).
- *     Added #define VCPU around VCPUwaitTime.
- *     Editorial changes.
- *
- *     Revision 1.64  2002/06/05 08:41:10  rschmidt
- *     Added function for XMAC2: SkXmTimeStamp().
- *     Added function for YUKON: SkGmSetRxCmd().
- *     Changed SkGmInitMac() resp. SkGmHardRst().
- *     Fixed wrong variable in SkXmAutoNegLipaXmac() (debug mode).
- *     SkXmRxTxEnable() replaced by SkMacRxTxEnable().
- *     Editorial changes.
- *
- *     Revision 1.63  2002/04/25 13:04:44  rschmidt
- *     Changes for handling YUKON.
- *     Use of #ifdef OTHER_PHY to eliminate code for unused Phy types.
- *     Macros for XMAC PHY access PHY_READ(), PHY_WRITE() replaced
- *     by functions SkXmPhyRead(), SkXmPhyWrite();
- *     Removed use of PRxCmd to setup XMAC.
- *     Added define PHY_B_AS_PAUSE_MSK for BCom Pause Res.
- *     Added setting of XM_RX_DIS_CEXT in SkXmInitMac().
- *     Removed status parameter from MAC IRQ handler SkMacIrq(),
- *     SkXmIrq() and SkGmIrq().
- *     SkXmAutoNegLipa...() for ext. Phy replaced by SkMacAutoNegLipaPhy().
- *     Added SkMac...() functions to handle both XMAC and GMAC.
- *     Added functions for YUKON: SkGmHardRst(), SkGmSoftRst(),
- *     SkGmSetRxTxEn(), SkGmIrq(), SkGmInitMac(), SkGmInitPhyMarv(),
- *     SkGmAutoNegDoneMarv(), SkGmPhyRead(), SkGmPhyWrite().
- *     Changes for V-CPU support.
- *     Editorial changes.
- *
- *     Revision 1.62  2001/08/06 09:50:14  rschmidt
- *     Workaround BCOM Errata #1 for the C5 type.
- *     Editorial changes.
- *
- *     Revision 1.61  2001/02/09 15:40:59  rassmann
- *     Editorial changes.
- *
- *     Revision 1.60  2001/02/07 15:02:01  cgoos
- *     Added workaround for Fujitsu switch link down.
- *
- *     Revision 1.59  2001/01/10 09:38:06  cgoos
- *     Fixed Broadcom C0/A1 Id check for workaround.
- *
- *     Revision 1.58  2000/11/29 11:30:38  cgoos
- *     Changed DEBUG sections with NW output to xDEBUG
- *
- *     Revision 1.57  2000/11/27 12:40:40  rassmann
- *     Suppressing preamble after first access to BCom, not before (#10556).
- *
- *     Revision 1.56  2000/11/09 12:32:48  rassmann
- *     Renamed variables.
- *
- *     Revision 1.55  2000/11/09 11:30:10  rassmann
- *     WA: Waiting after releasing reset until BCom chip is accessible.
- *
- *     Revision 1.54  2000/10/02 14:10:27  rassmann
- *     Reading BCOM PHY after releasing reset until it returns a valid value.
- *
- *     Revision 1.53  2000/07/27 12:22:11  gklug
- *     fix: possible endless loop in XmHardRst.
- *
- *     Revision 1.52  2000/05/22 08:48:31  malthoff
- *     Fix: #10523 errata valid for all BCOM PHYs.
- *
- *     Revision 1.51  2000/05/17 12:52:18  malthoff
- *     Fixes BCom link errata (#10523).
- *
- *     Revision 1.50  1999/11/22 13:40:14  cgoos
- *     Changed license header to GPL.
- *
- *     Revision 1.49  1999/11/22 08:12:13  malthoff
- *     Add workaround for power consumption feature of BCom C0 chip.
- *
- *     Revision 1.48  1999/11/16 08:39:01  malthoff
- *     Fix: MDIO preamble suppression is port dependent.
- *
- *     Revision 1.47  1999/08/27 08:55:35  malthoff
- *     1000BT: Optimizing MDIO transfer by oppressing MDIO preamble.
- *
- *     Revision 1.46  1999/08/13 11:01:12  malthoff
- *     Fix for 1000BT: pFlowCtrlMode was not set correctly.
- *
- *     Revision 1.45  1999/08/12 19:18:28  malthoff
- *     1000BT Fixes: Do not owerwrite XM_MMU_CMD.
- *     Do not execute BCOM A1 workaround for B1 chips.
- *     Fix pause frame setting.
- *     Always set PHY_B_AC_TX_TST in PHY_BCOM_AUX_CTRL.
- *
- *     Revision 1.44  1999/08/03 15:23:48  cgoos
- *     Fixed setting of PHY interrupt mask in half duplex mode.
- *
- *     Revision 1.43  1999/08/03 15:22:17  cgoos
- *     Added some debug output.
- *     Disabled XMac GP0 interrupt for external PHYs.
- *
- *     Revision 1.42  1999/08/02 08:39:23  malthoff
- *     BCOM PHY: TX LED: To get the mono flop behaviour it is required
- *     to set the LED Traffic Mode bit in PHY_BCOM_P_EXT_CTRL.
- *
- *     Revision 1.41  1999/07/30 06:54:31  malthoff
- *     Add temp. workarounds for the BCOM Phy revision A1.
- *
- *     Revision 1.40  1999/06/01 07:43:26  cgoos
- *     Changed Link Mode Status in SkXmAutoNegDone... from FULL/HALF to
- *     AUTOFULL/AUTOHALF.
- *
- *     Revision 1.39  1999/05/19 07:29:51  cgoos
- *     Changes for 1000Base-T.
- *
- *     Revision 1.38  1999/04/08 14:35:10  malthoff
- *     Add code for enabling signal detect. Enabling signal detect is disabled.
- *
- *     Revision 1.37  1999/03/12 13:42:54  malthoff
- *     Add: Jumbo Frame Support.
- *     Add: Receive modes SK_LENERR_OK_ON/OFF and
- *     SK_BIG_PK_OK_ON/OFF in SkXmSetRxCmd().
- *
- *     Revision 1.36  1999/03/08 10:10:55  gklug
- *     fix: AutoSensing did switch to next mode even if LiPa indicated offline
- *
- *     Revision 1.35  1999/02/22 15:16:41  malthoff
- *     Remove some compiler warnings.
- *
- *     Revision 1.34  1999/01/22 09:19:59  gklug
- *     fix: Init DupMode and InitPauseMd are now called in RxTxEnable
- *
- *     Revision 1.33  1998/12/11 15:19:11  gklug
- *     chg: lipa autoneg stati
- *     chg: debug messages
- *     chg: do NOT use spurious XmIrq
- *
- *     Revision 1.32  1998/12/10 11:08:44  malthoff
- *     bug fix: pAC has been used for IOs in SkXmHardRst().
- *     SkXmInitPhy() is also called for the Diag in SkXmInitMac().
- *
- *     Revision 1.31  1998/12/10 10:39:11  gklug
- *     fix: do 4 RESETS of the XMAC at the beginning
- *     fix: dummy read interrupt source register BEFORE initializing the Phy
- *     add: debug messages
- *     fix: Linkpartners autoneg capability cannot be shown by TX_PAGE interrupt
- *
- *     Revision 1.30  1998/12/07 12:18:32  gklug
- *     add: refinement of autosense mode: take into account the autoneg cap of LiPa
- *
- *     Revision 1.29  1998/12/07 07:12:29  gklug
- *     fix: if page is received the link is  down.
- *
- *     Revision 1.28  1998/12/01 10:12:47  gklug
- *     chg: if spurious IRQ from XMAC encountered, save it
- *
- *     Revision 1.27  1998/11/26 07:33:38  gklug
- *     add: InitPhy call is now in XmInit function
- *
- *     Revision 1.26  1998/11/18 13:38:24  malthoff
- *     'Imsk' is also unused in SkXmAutoNegDone.
- *
- *     Revision 1.25  1998/11/18 13:28:01  malthoff
- *     Remove unused variable 'Reg' in SkXmAutoNegDone().
- *
- *     Revision 1.24  1998/11/18 13:18:45  gklug
- *     add: workaround for xmac errata #1
- *     add: detect Link Down also when Link partner requested config
- *     chg: XMIrq is only used when link is up
- *
- *     Revision 1.23  1998/11/04 07:07:04  cgoos
- *     Added function SkXmRxTxEnable.
- *
- *     Revision 1.22  1998/10/30 07:35:54  gklug
- *     fix: serve LinkDown interrupt when link is already down
- *
- *     Revision 1.21  1998/10/29 15:32:03  gklug
- *     fix: Link Down signaling
- *
- *     Revision 1.20  1998/10/29 11:17:27  gklug
- *     fix: AutoNegDone bug
- *
- *     Revision 1.19  1998/10/29 10:14:43  malthoff
- *     Add endainesss comment for reading/writing MAC addresses.
- *
- *     Revision 1.18  1998/10/28 07:48:55  cgoos
- *     Fix: ASS somtimes signaled although link is up.
- *
- *     Revision 1.17  1998/10/26 07:55:39  malthoff
- *     Fix in SkXmInitPauseMd(): Pause Mode
- *     was disabled and not enabled.
- *     Fix in SkXmAutoNegDone(): Checking Mode bits
- *     always failed, becaues of some missing braces.
- *
- *     Revision 1.16  1998/10/22 09:46:52  gklug
- *     fix SysKonnectFileId typo
- *
- *     Revision 1.15  1998/10/21 05:51:37  gklug
- *     add: para DoLoop to InitPhy function for loopback set-up
- *
- *     Revision 1.14  1998/10/16 10:59:23  malthoff
- *     Remove Lint warning for dummy reads.
- *
- *     Revision 1.13  1998/10/15 14:01:20  malthoff
- *     Fix: SkXmAutoNegDone() is (int) but does not return a value.
- *
- *     Revision 1.12  1998/10/14 14:45:04  malthoff
- *     Remove SKERR_SIRQ_E0xx and SKERR_SIRQ_E0xxMSG by
- *     SKERR_HWI_Exx and SKERR_HWI_E0xxMSG to be independent
- *     from the Sirq module.
- *
- *     Revision 1.11  1998/10/14 13:59:01  gklug
- *     add: InitPhy function
- *
- *     Revision 1.10  1998/10/14 11:20:57  malthoff
- *     Make SkXmAutoNegDone() public, because it's
- *     used in diagnostics, too.
- *     The Link Up event to the RLMT is issued in SkXmIrq().
- *  SkXmIrq() is not available in diagnostics.
- *  Use PHY_READ when reading PHY registers.
- *
- *     Revision 1.9  1998/10/14 05:50:10  cgoos
- *     Added definition for Para.
- *
- *     Revision 1.8  1998/10/14 05:41:28  gklug
- *     add: Xmac IRQ
- *     add: auto-negotiation done function
- *
- *     Revision 1.7  1998/10/09 06:55:20  malthoff
- *     The configuration of the XMACs Tx Request Threshold
- *     depends from the drivers port usage now. The port
- *     usage is configured in GIPortUsage.
- *
- *     Revision 1.6  1998/10/05 07:48:00  malthoff
- *     minor changes
- *
- *     Revision 1.5  1998/10/01 07:03:54  gklug
- *     add: dummy function for XMAC ISR
- *
- *     Revision 1.4  1998/09/30 12:37:44  malthoff
- *     Add SkXmSetRxCmd() and related code.
- *
- *     Revision 1.3  1998/09/28 13:26:40  malthoff
- *     Add SkXmInitMac(), SkXmInitDupMd(), and SkXmInitPauseMd()
- *
- *     Revision 1.2  1998/09/16 14:34:21  malthoff
- *     Add SkXmClrExactAddr(), SkXmClrSrcCheck(),
- *     SkXmClrHashAddr(), SkXmFlushTxFifo(),
- *     SkXmFlushRxFifo(), and SkXmHardRst().
- *     Finish Coding of SkXmSoftRst().
- *     The sources may be compiled now.
- *
- *     Revision 1.1  1998/09/04 10:05:56  malthoff
- *     Created.
- *
- *
- ******************************************************************************/
-
-#include <config.h>
-
-#ifdef CONFIG_SK98
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-
-/* typedefs *******************************************************************/
-
-/* BCOM PHY magic pattern list */
-typedef struct s_PhyHack {
-       int             PhyReg;         /* Phy register */
-       SK_U16  PhyVal;         /* Value to write */
-} BCOM_HACK;
-
-/* local variables ************************************************************/
-static const char SysKonnectFileId[] =
-       "@(#)$Id: skxmac2.c,v 1.91 2003/02/05 15:09:34 rschmidt Exp $ (C) SK ";
-
-BCOM_HACK BcomRegA1Hack[] = {
- { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 },
- { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 },
- { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 },
- { 0, 0 }
-};
-BCOM_HACK BcomRegC0Hack[] = {
- { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 }, { 0x17, 0x0013 },
- { 0x15, 0x0A04 }, { 0x18, 0x0420 },
- { 0, 0 }
-};
-
-/* function prototypes ********************************************************/
-static void    SkXmInitPhyXmac(SK_AC*, SK_IOC, int, SK_BOOL);
-static void    SkXmInitPhyBcom(SK_AC*, SK_IOC, int, SK_BOOL);
-static void    SkGmInitPhyMarv(SK_AC*, SK_IOC, int, SK_BOOL);
-static int     SkXmAutoNegDoneXmac(SK_AC*, SK_IOC, int);
-static int     SkXmAutoNegDoneBcom(SK_AC*, SK_IOC, int);
-static int     SkGmAutoNegDoneMarv(SK_AC*, SK_IOC, int);
-#ifdef OTHER_PHY
-static void    SkXmInitPhyLone(SK_AC*, SK_IOC, int, SK_BOOL);
-static void    SkXmInitPhyNat (SK_AC*, SK_IOC, int, SK_BOOL);
-static int     SkXmAutoNegDoneLone(SK_AC*, SK_IOC, int);
-static int     SkXmAutoNegDoneNat (SK_AC*, SK_IOC, int);
-#endif /* OTHER_PHY */
-
-
-/******************************************************************************
- *
- *     SkXmPhyRead() - Read from XMAC PHY register
- *
- * Description:        reads a 16-bit word from XMAC PHY or ext. PHY
- *
- * Returns:
- *     nothing
- */
-void SkXmPhyRead(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            PhyReg,         /* Register Address (Offset) */
-SK_U16 *pVal)          /* Pointer to Value */
-{
-       SK_U16          Mmu;
-       SK_GEPORT       *pPrt;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* write the PHY register's address */
-       XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
-
-       /* get the PHY register's value */
-       XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
-
-       if (pPrt->PhyType != SK_PHY_XMAC) {
-               do {
-                       XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
-                       /* wait until 'Ready' is set */
-               } while ((Mmu & XM_MMU_PHY_RDY) == 0);
-
-               /* get the PHY register's value */
-               XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
-       }
-}      /* SkXmPhyRead */
-
-
-/******************************************************************************
- *
- *     SkXmPhyWrite() - Write to XMAC PHY register
- *
- * Description:        writes a 16-bit word to XMAC PHY or ext. PHY
- *
- * Returns:
- *     nothing
- */
-void SkXmPhyWrite(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            PhyReg,         /* Register Address (Offset) */
-SK_U16 Val)            /* Value */
-{
-       SK_U16          Mmu;
-       SK_GEPORT       *pPrt;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PhyType != SK_PHY_XMAC) {
-               do {
-                       XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
-                       /* wait until 'Busy' is cleared */
-               } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
-       }
-
-       /* write the PHY register's address */
-       XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
-
-       /* write the PHY register's value */
-       XM_OUT16(IoC, Port, XM_PHY_DATA, Val);
-
-       if (pPrt->PhyType != SK_PHY_XMAC) {
-               do {
-                       XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
-                       /* wait until 'Busy' is cleared */
-               } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
-       }
-}      /* SkXmPhyWrite */
-
-
-/******************************************************************************
- *
- *     SkGmPhyRead() - Read from GPHY register
- *
- * Description:        reads a 16-bit word from GPHY through MDIO
- *
- * Returns:
- *     nothing
- */
-void SkGmPhyRead(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            PhyReg,         /* Register Address (Offset) */
-SK_U16 *pVal)          /* Pointer to Value */
-{
-       SK_U16  Ctrl;
-       SK_GEPORT       *pPrt;
-#ifdef VCPU
-       u_long SimCyle;
-       u_long SimLowTime;
-
-       VCPUgetTime(&SimCyle, &SimLowTime);
-       VCPUprintf(0, "SkGmPhyRead(%u), SimCyle=%u, SimLowTime=%u\n",
-               PhyReg, SimCyle, SimLowTime);
-#endif /* VCPU */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* set PHY-Register offset and 'Read' OpCode (= 1) */
-       *pVal = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) |
-               GM_SMI_CT_REG_AD(PhyReg) | GM_SMI_CT_OP_RD);
-
-       GM_OUT16(IoC, Port, GM_SMI_CTRL, *pVal);
-
-       GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
-
-       /* additional check for MDC/MDIO activity */
-       if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
-               *pVal = 0;
-               return;
-       }
-
-       *pVal |= GM_SMI_CT_BUSY;
-
-       do {
-#ifdef VCPU
-               VCPUwaitTime(1000);
-#endif /* VCPU */
-
-               GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
-
-       /* wait until 'ReadValid' is set */
-       } while (Ctrl == *pVal);
-
-       /* get the PHY register's value */
-       GM_IN16(IoC, Port, GM_SMI_DATA, pVal);
-
-#ifdef VCPU
-       VCPUgetTime(&SimCyle, &SimLowTime);
-       VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
-               SimCyle, SimLowTime);
-#endif /* VCPU */
-}      /* SkGmPhyRead */
-
-
-/******************************************************************************
- *
- *     SkGmPhyWrite() - Write to GPHY register
- *
- * Description:        writes a 16-bit word to GPHY through MDIO
- *
- * Returns:
- *     nothing
- */
-void SkGmPhyWrite(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            PhyReg,         /* Register Address (Offset) */
-SK_U16 Val)            /* Value */
-{
-       SK_U16  Ctrl;
-       SK_GEPORT       *pPrt;
-#ifdef VCPU
-       SK_U32  DWord;
-       u_long  SimCyle;
-       u_long  SimLowTime;
-
-       VCPUgetTime(&SimCyle, &SimLowTime);
-       VCPUprintf(0, "SkGmPhyWrite(Reg=%u, Val=0x%04x), SimCyle=%u, SimLowTime=%u\n",
-               PhyReg, Val, SimCyle, SimLowTime);
-#endif /* VCPU */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* write the PHY register's value */
-       GM_OUT16(IoC, Port, GM_SMI_DATA, Val);
-
-       /* set PHY-Register offset and 'Write' OpCode (= 0) */
-       Val = GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg);
-
-       GM_OUT16(IoC, Port, GM_SMI_CTRL, Val);
-
-       GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
-
-       /* additional check for MDC/MDIO activity */
-       if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
-               return;
-       }
-
-       Val |= GM_SMI_CT_BUSY;
-
-       do {
-#ifdef VCPU
-               /* read Timer value */
-               SK_IN32(IoC, B2_TI_VAL, &DWord);
-
-               VCPUwaitTime(1000);
-#endif /* VCPU */
-
-               GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
-
-       /* wait until 'Busy' is cleared */
-       } while (Ctrl == Val);
-
-#ifdef VCPU
-       VCPUgetTime(&SimCyle, &SimLowTime);
-       VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
-               SimCyle, SimLowTime);
-#endif /* VCPU */
-}      /* SkGmPhyWrite */
-
-
-/******************************************************************************
- *
- *     SkGePhyRead() - Read from PHY register
- *
- * Description:        calls a read PHY routine dep. on board type
- *
- * Returns:
- *     nothing
- */
-void SkGePhyRead(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            PhyReg,         /* Register Address (Offset) */
-SK_U16 *pVal)          /* Pointer to Value */
-{
-       void (*r_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 *pVal);
-
-       if (pAC->GIni.GIGenesis) {
-               r_func = SkXmPhyRead;
-       }
-       else {
-               r_func = SkGmPhyRead;
-       }
-
-       r_func(pAC, IoC, Port, PhyReg, pVal);
-}      /* SkGePhyRead */
-
-
-/******************************************************************************
- *
- *     SkGePhyWrite() - Write to PHY register
- *
- * Description:        calls a write PHY routine dep. on board type
- *
- * Returns:
- *     nothing
- */
-void SkGePhyWrite(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            PhyReg,         /* Register Address (Offset) */
-SK_U16 Val)            /* Value */
-{
-       void (*w_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 Val);
-
-       if (pAC->GIni.GIGenesis) {
-               w_func = SkXmPhyWrite;
-       }
-       else {
-               w_func = SkGmPhyWrite;
-       }
-
-       w_func(pAC, IoC, Port, PhyReg, Val);
-}      /* SkGePhyWrite */
-
-
-/******************************************************************************
- *
- *     SkMacPromiscMode() - Enable / Disable Promiscuous Mode
- *
- * Description:
- *   enables / disables promiscuous mode by setting Mode Register (XMAC) or
- *   Receive Control Register (GMAC) dep. on board type
- *
- * Returns:
- *     nothing
- */
-void SkMacPromiscMode(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port,   /* Port Index (MAC_1 + n) */
-SK_BOOL        Enable) /* Enable / Disable */
-{
-       SK_U16  RcReg;
-       SK_U32  MdReg;
-
-       if (pAC->GIni.GIGenesis) {
-
-               XM_IN32(IoC, Port, XM_MODE, &MdReg);
-               /* enable or disable promiscuous mode */
-               if (Enable) {
-                       MdReg |= XM_MD_ENA_PROM;
-               }
-               else {
-                       MdReg &= ~XM_MD_ENA_PROM;
-               }
-               /* setup Mode Register */
-               XM_OUT32(IoC, Port, XM_MODE, MdReg);
-       }
-       else {
-
-               GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
-
-               /* enable or disable unicast and multicast filtering */
-               if (Enable) {
-                       RcReg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
-               }
-               else {
-                       RcReg |= (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
-               }
-               /* setup Receive Control Register */
-               GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);
-       }
-}      /* SkMacPromiscMode*/
-
-
-/******************************************************************************
- *
- *     SkMacHashing() - Enable / Disable Hashing
- *
- * Description:
- *   enables / disables hashing by setting Mode Register (XMAC) or
- *   Receive Control Register (GMAC) dep. on board type
- *
- * Returns:
- *     nothing
- */
-void SkMacHashing(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port,   /* Port Index (MAC_1 + n) */
-SK_BOOL        Enable) /* Enable / Disable */
-{
-       SK_U16  RcReg;
-       SK_U32  MdReg;
-
-       if (pAC->GIni.GIGenesis) {
-
-               XM_IN32(IoC, Port, XM_MODE, &MdReg);
-               /* enable or disable hashing */
-               if (Enable) {
-                       MdReg |= XM_MD_ENA_HASH;
-               }
-               else {
-                       MdReg &= ~XM_MD_ENA_HASH;
-               }
-               /* setup Mode Register */
-               XM_OUT32(IoC, Port, XM_MODE, MdReg);
-       }
-       else {
-
-               GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
-
-               /* enable or disable multicast filtering */
-               if (Enable) {
-                       RcReg |= GM_RXCR_MCF_ENA;
-               }
-               else {
-                       RcReg &= ~GM_RXCR_MCF_ENA;
-               }
-               /* setup Receive Control Register */
-               GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);
-       }
-}      /* SkMacHashing*/
-
-
-#ifdef SK_DIAG
-/******************************************************************************
- *
- *     SkXmSetRxCmd() - Modify the value of the XMAC's Rx Command Register
- *
- * Description:
- *     The features
- *      - FCS stripping,                                       SK_STRIP_FCS_ON/OFF
- *      - pad byte stripping,                          SK_STRIP_PAD_ON/OFF
- *      - don't set XMR_FS_ERR in status       SK_LENERR_OK_ON/OFF
- *        for inrange length error frames
- *      - don't set XMR_FS_ERR in status       SK_BIG_PK_OK_ON/OFF
- *        for frames > 1514 bytes
- *   - enable Rx of own packets         SK_SELF_RX_ON/OFF
- *
- *     for incoming packets may be enabled/disabled by this function.
- *     Additional modes may be added later.
- *     Multiple modes can be enabled/disabled at the same time.
- *     The new configuration is written to the Rx Command register immediately.
- *
- * Returns:
- *     nothing
- */
-static void SkXmSetRxCmd(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            Mode)           /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
-                                          SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
-{
-       SK_U16  OldRxCmd;
-       SK_U16  RxCmd;
-
-       XM_IN16(IoC, Port, XM_RX_CMD, &OldRxCmd);
-
-       RxCmd = OldRxCmd;
-
-       switch (Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) {
-       case SK_STRIP_FCS_ON:
-               RxCmd |= XM_RX_STRIP_FCS;
-               break;
-       case SK_STRIP_FCS_OFF:
-               RxCmd &= ~XM_RX_STRIP_FCS;
-               break;
-       }
-
-       switch (Mode & (SK_STRIP_PAD_ON | SK_STRIP_PAD_OFF)) {
-       case SK_STRIP_PAD_ON:
-               RxCmd |= XM_RX_STRIP_PAD;
-               break;
-       case SK_STRIP_PAD_OFF:
-               RxCmd &= ~XM_RX_STRIP_PAD;
-               break;
-       }
-
-       switch (Mode & (SK_LENERR_OK_ON | SK_LENERR_OK_OFF)) {
-       case SK_LENERR_OK_ON:
-               RxCmd |= XM_RX_LENERR_OK;
-               break;
-       case SK_LENERR_OK_OFF:
-               RxCmd &= ~XM_RX_LENERR_OK;
-               break;
-       }
-
-       switch (Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) {
-       case SK_BIG_PK_OK_ON:
-               RxCmd |= XM_RX_BIG_PK_OK;
-               break;
-       case SK_BIG_PK_OK_OFF:
-               RxCmd &= ~XM_RX_BIG_PK_OK;
-               break;
-       }
-
-       switch (Mode & (SK_SELF_RX_ON | SK_SELF_RX_OFF)) {
-       case SK_SELF_RX_ON:
-               RxCmd |= XM_RX_SELF_RX;
-               break;
-       case SK_SELF_RX_OFF:
-               RxCmd &= ~XM_RX_SELF_RX;
-               break;
-       }
-
-       /* Write the new mode to the Rx command register if required */
-       if (OldRxCmd != RxCmd) {
-               XM_OUT16(IoC, Port, XM_RX_CMD, RxCmd);
-       }
-}      /* SkXmSetRxCmd */
-
-
-/******************************************************************************
- *
- *     SkGmSetRxCmd() - Modify the value of the GMAC's Rx Control Register
- *
- * Description:
- *     The features
- *      - FCS (CRC) stripping,                         SK_STRIP_FCS_ON/OFF
- *      - don't set GMR_FS_LONG_ERR            SK_BIG_PK_OK_ON/OFF
- *        for frames > 1514 bytes
- *   - enable Rx of own packets         SK_SELF_RX_ON/OFF
- *
- *     for incoming packets may be enabled/disabled by this function.
- *     Additional modes may be added later.
- *     Multiple modes can be enabled/disabled at the same time.
- *     The new configuration is written to the Rx Command register immediately.
- *
- * Returns:
- *     nothing
- */
-static void SkGmSetRxCmd(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            Mode)           /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
-                                          SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
-{
-       SK_U16  OldRxCmd;
-       SK_U16  RxCmd;
-
-       if ((Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) != 0) {
-
-               GM_IN16(IoC, Port, GM_RX_CTRL, &OldRxCmd);
-
-               RxCmd = OldRxCmd;
-
-               if ((Mode & SK_STRIP_FCS_ON) != 0) {
-                       RxCmd |= GM_RXCR_CRC_DIS;
-               }
-               else {
-                       RxCmd &= ~GM_RXCR_CRC_DIS;
-               }
-               /* Write the new mode to the Rx control register if required */
-               if (OldRxCmd != RxCmd) {
-                       GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd);
-               }
-       }
-
-       if ((Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) != 0) {
-
-               GM_IN16(IoC, Port, GM_SERIAL_MODE, &OldRxCmd);
-
-               RxCmd = OldRxCmd;
-
-               if ((Mode & SK_BIG_PK_OK_ON) != 0) {
-                       RxCmd |= GM_SMOD_JUMBO_ENA;
-               }
-               else {
-                       RxCmd &= ~GM_SMOD_JUMBO_ENA;
-               }
-               /* Write the new mode to the Rx control register if required */
-               if (OldRxCmd != RxCmd) {
-                       GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd);
-               }
-       }
-}      /* SkGmSetRxCmd */
-
-
-/******************************************************************************
- *
- *     SkMacSetRxCmd() - Modify the value of the MAC's Rx Control Register
- *
- * Description:        modifies the MAC's Rx Control reg. dep. on board type
- *
- * Returns:
- *     nothing
- */
-void SkMacSetRxCmd(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            Mode)           /* Rx Mode */
-{
-       if (pAC->GIni.GIGenesis) {
-
-               SkXmSetRxCmd(pAC, IoC, Port, Mode);
-       }
-       else {
-
-               SkGmSetRxCmd(pAC, IoC, Port, Mode);
-       }
-}      /* SkMacSetRxCmd */
-
-
-/******************************************************************************
- *
- *     SkMacCrcGener() - Enable / Disable CRC Generation
- *
- * Description:        enables / disables CRC generation dep. on board type
- *
- * Returns:
- *     nothing
- */
-void SkMacCrcGener(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port,   /* Port Index (MAC_1 + n) */
-SK_BOOL        Enable) /* Enable / Disable */
-{
-       SK_U16  Word;
-
-       if (pAC->GIni.GIGenesis) {
-
-               XM_IN16(IoC, Port, XM_TX_CMD, &Word);
-
-               if (Enable) {
-                       Word &= ~XM_TX_NO_CRC;
-               }
-               else {
-                       Word |= XM_TX_NO_CRC;
-               }
-               /* setup Tx Command Register */
-               XM_OUT16(pAC, Port, XM_TX_CMD, Word);
-       }
-       else {
-
-               GM_IN16(IoC, Port, GM_TX_CTRL, &Word);
-
-               if (Enable) {
-                       Word &= ~GM_TXCR_CRC_DIS;
-               }
-               else {
-                       Word |= GM_TXCR_CRC_DIS;
-               }
-               /* setup Tx Control Register */
-               GM_OUT16(IoC, Port, GM_TX_CTRL, Word);
-       }
-}      /* SkMacCrcGener*/
-
-#endif /* SK_DIAG */
-
-
-/******************************************************************************
- *
- *     SkXmClrExactAddr() - Clear Exact Match Address Registers
- *
- * Description:
- *     All Exact Match Address registers of the XMAC 'Port' will be
- *     cleared starting with 'StartNum' up to (and including) the
- *     Exact Match address number of 'StopNum'.
- *
- * Returns:
- *     nothing
- */
-void SkXmClrExactAddr(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            StartNum,       /* Begin with this Address Register Index (0..15) */
-int            StopNum)        /* Stop after finished with this Register Idx (0..15) */
-{
-       int             i;
-       SK_U16  ZeroAddr[3] = {0x0000, 0x0000, 0x0000};
-
-       if ((unsigned)StartNum > 15 || (unsigned)StopNum > 15 ||
-               StartNum > StopNum) {
-
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E001, SKERR_HWI_E001MSG);
-               return;
-       }
-
-       for (i = StartNum; i <= StopNum; i++) {
-               XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]);
-       }
-}      /* SkXmClrExactAddr */
-
-
-/******************************************************************************
- *
- *     SkMacFlushTxFifo() - Flush the MAC's transmit FIFO
- *
- * Description:
- *     Flush the transmit FIFO of the MAC specified by the index 'Port'
- *
- * Returns:
- *     nothing
- */
-void SkMacFlushTxFifo(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_U32  MdReg;
-
-       if (pAC->GIni.GIGenesis) {
-
-               XM_IN32(IoC, Port, XM_MODE, &MdReg);
-
-               XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FTF);
-       }
-       else {
-               /* no way to flush the FIFO we have to issue a reset */
-               /* TBD */
-       }
-}      /* SkMacFlushTxFifo */
-
-
-/******************************************************************************
- *
- *     SkMacFlushRxFifo() - Flush the MAC's receive FIFO
- *
- * Description:
- *     Flush the receive FIFO of the MAC specified by the index 'Port'
- *
- * Returns:
- *     nothing
- */
-void SkMacFlushRxFifo(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_U32  MdReg;
-
-       if (pAC->GIni.GIGenesis) {
-
-               XM_IN32(IoC, Port, XM_MODE, &MdReg);
-
-               XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FRF);
-       }
-       else {
-               /* no way to flush the FIFO we have to issue a reset */
-               /* TBD */
-       }
-}      /* SkMacFlushRxFifo */
-
-
-/******************************************************************************
- *
- *     SkXmSoftRst() - Do a XMAC software reset
- *
- * Description:
- *     The PHY registers should not be destroyed during this
- *     kind of software reset. Therefore the XMAC Software Reset
- *     (XM_GP_RES_MAC bit in XM_GP_PORT) must not be used!
- *
- *     The software reset is done by
- *             - disabling the Rx and Tx state machine,
- *             - resetting the statistics module,
- *             - clear all other significant XMAC Mode,
- *               Command, and Control Registers
- *             - clearing the Hash Register and the
- *               Exact Match Address registers, and
- *             - flushing the XMAC's Rx and Tx FIFOs.
- *
- * Note:
- *     Another requirement when stopping the XMAC is to
- *     avoid sending corrupted frames on the network.
- *     Disabling the Tx state machine will NOT interrupt
- *     the currently transmitted frame. But we must take care
- *     that the Tx FIFO is cleared AFTER the current frame
- *     is complete sent to the network.
- *
- *     It takes about 12ns to send a frame with 1538 bytes.
- *     One PCI clock goes at least 15ns (66MHz). Therefore
- *     after reading XM_GP_PORT back, we are sure that the
- *     transmitter is disabled AND idle. And this means
- *     we may flush the transmit FIFO now.
- *
- * Returns:
- *     nothing
- */
-static void SkXmSoftRst(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_U16  ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000};
-
-       /* reset the statistics module */
-       XM_OUT32(IoC, Port, XM_GP_PORT, XM_GP_RES_STAT);
-
-       /* disable all XMAC IRQs */
-       XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
-
-       XM_OUT32(IoC, Port, XM_MODE, 0);                /* clear Mode Reg */
-
-       XM_OUT16(IoC, Port, XM_TX_CMD, 0);              /* reset TX CMD Reg */
-       XM_OUT16(IoC, Port, XM_RX_CMD, 0);              /* reset RX CMD Reg */
-
-       /* disable all PHY IRQs */
-       switch (pAC->GIni.GP[Port].PhyType) {
-       case SK_PHY_BCOM:
-                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff);
-                       break;
-#ifdef OTHER_PHY
-               case SK_PHY_LONE:
-                       SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0);
-                       break;
-               case SK_PHY_NAT:
-                       /* todo: National
-                        SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */
-                       break;
-#endif /* OTHER_PHY */
-       }
-
-       /* clear the Hash Register */
-       XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr);
-
-       /* clear the Exact Match Address registers */
-       SkXmClrExactAddr(pAC, IoC, Port, 0, 15);
-
-       /* clear the Source Check Address registers */
-       XM_OUTHASH(IoC, Port, XM_SRC_CHK, &ZeroAddr);
-
-}      /* SkXmSoftRst */
-
-
-/******************************************************************************
- *
- *     SkXmHardRst() - Do a XMAC hardware reset
- *
- * Description:
- *     The XMAC of the specified 'Port' and all connected devices
- *     (PHY and SERDES) will receive a reset signal on its *Reset pins.
- *     External PHYs must be reset be clearing a bit in the GPIO register
- *  (Timing requirements: Broadcom: 400ns, Level One: none, National: 80ns).
- *
- * ATTENTION:
- *     It is absolutely necessary to reset the SW_RST Bit first
- *     before calling this function.
- *
- * Returns:
- *     nothing
- */
-static void SkXmHardRst(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_U32  Reg;
-       int             i;
-       int             TOut;
-       SK_U16  Word;
-
-       for (i = 0; i < 4; i++) {
-               /* TX_MFF_CTRL1 has 32 bits, but only the lowest 16 bits are used */
-               SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
-
-               TOut = 0;
-               do {
-                       if (TOut++ > 10000) {
-                               /*
-                                * Adapter seems to be in RESET state.
-                                * Registers cannot be written.
-                                */
-                               return;
-                       }
-
-                       SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
-
-                       SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &Word);
-
-               } while ((Word & MFF_SET_MAC_RST) == 0);
-       }
-
-       /* For external PHYs there must be special handling */
-       if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
-               /* reset external PHY */
-               SK_IN32(IoC, B2_GP_IO, &Reg);
-               if (Port == 0) {
-                       Reg |= GP_DIR_0; /* set to output */
-                       Reg &= ~GP_IO_0;
-               }
-               else {
-                       Reg |= GP_DIR_2; /* set to output */
-                       Reg &= ~GP_IO_2;
-               }
-               SK_OUT32(IoC, B2_GP_IO, Reg);
-
-               /* short delay */
-               SK_IN32(IoC, B2_GP_IO, &Reg);
-       }
-
-}      /* SkXmHardRst */
-
-
-/******************************************************************************
- *
- *     SkGmSoftRst() - Do a GMAC software reset
- *
- * Description:
- *     The GPHY registers should not be destroyed during this
- *     kind of software reset.
- *
- * Returns:
- *     nothing
- */
-static void SkGmSoftRst(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_U16  EmptyHash[4] = {0x0000, 0x0000, 0x0000, 0x0000};
-       SK_U16  RxCtrl;
-
-       /* reset the statistics module */
-
-       /* disable all GMAC IRQs */
-       SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
-
-       /* disable all PHY IRQs */
-       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
-
-       /* clear the Hash Register */
-       GM_OUTHASH(IoC, Port, GM_MC_ADDR_H1, EmptyHash);
-
-       /* Enable Unicast and Multicast filtering */
-       GM_IN16(IoC, Port, GM_RX_CTRL, &RxCtrl);
-
-       GM_OUT16(IoC, Port, GM_RX_CTRL,
-               RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
-
-}      /* SkGmSoftRst */
-
-
-/******************************************************************************
- *
- *     SkGmHardRst() - Do a GMAC hardware reset
- *
- * Description:
- *
- * ATTENTION:
- *     It is absolutely necessary to reset the SW_RST Bit first
- *     before calling this function.
- *
- * Returns:
- *     nothing
- */
-static void SkGmHardRst(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       /* set GPHY Control reset */
-       SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
-
-       /* set GMAC Control reset */
-       SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
-
-}      /* SkGmHardRst */
-
-
-/******************************************************************************
- *
- *     SkMacSoftRst() - Do a MAC software reset
- *
- * Description:        calls a MAC software reset routine dep. on board type
- *
- * Returns:
- *     nothing
- */
-void SkMacSoftRst(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* disable receiver and transmitter */
-       SkMacRxTxDisable(pAC, IoC, Port);
-
-       if (pAC->GIni.GIGenesis) {
-
-               SkXmSoftRst(pAC, IoC, Port);
-       }
-       else {
-
-               SkGmSoftRst(pAC, IoC, Port);
-       }
-
-       /* flush the MAC's Rx and Tx FIFOs */
-       SkMacFlushTxFifo(pAC, IoC, Port);
-
-       SkMacFlushRxFifo(pAC, IoC, Port);
-
-       pPrt->PState = SK_PRT_STOP;
-
-}      /* SkMacSoftRst */
-
-
-/******************************************************************************
- *
- *     SkMacHardRst() - Do a MAC hardware reset
- *
- * Description:        calls a MAC hardware reset routine dep. on board type
- *
- * Returns:
- *     nothing
- */
-void SkMacHardRst(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-
-       if (pAC->GIni.GIGenesis) {
-
-               SkXmHardRst(pAC, IoC, Port);
-       }
-       else {
-
-               SkGmHardRst(pAC, IoC, Port);
-       }
-
-       pAC->GIni.GP[Port].PState = SK_PRT_RESET;
-
-}      /* SkMacHardRst */
-
-
-/******************************************************************************
- *
- *     SkXmInitMac() - Initialize the XMAC II
- *
- * Description:
- *     Initialize the XMAC of the specified port.
- *     The XMAC must be reset or stopped before calling this function.
- *
- * Note:
- *     The XMAC's Rx and Tx state machine is still disabled when returning.
- *
- * Returns:
- *     nothing
- */
-void SkXmInitMac(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U32          Reg;
-       int                     i;
-       SK_U16          SWord;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PState == SK_PRT_STOP) {
-               /* Port State: SK_PRT_STOP */
-               /* Verify that the reset bit is cleared */
-               SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
-
-               if ((SWord & MFF_SET_MAC_RST) != 0) {
-                       /* PState does not match HW state */
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
-                       /* Correct it */
-                       pPrt->PState = SK_PRT_RESET;
-               }
-       }
-
-       if (pPrt->PState == SK_PRT_RESET) {
-               /*
-                * clear HW reset
-                * Note: The SW reset is self clearing, therefore there is
-                *       nothing to do here.
-                */
-               SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
-
-               /* Ensure that XMAC reset release is done (errata from LReinbold?) */
-               SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
-
-               /* Clear PHY reset */
-               if (pPrt->PhyType != SK_PHY_XMAC) {
-
-                       SK_IN32(IoC, B2_GP_IO, &Reg);
-
-                       if (Port == 0) {
-                               Reg |= (GP_DIR_0 | GP_IO_0); /* set to output */
-                       }
-                       else {
-                               Reg |= (GP_DIR_2 | GP_IO_2); /* set to output */
-                       }
-                       SK_OUT32(IoC, B2_GP_IO, Reg);
-
-                       /* Enable GMII interface */
-                       XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);
-
-                       /* read Id from external PHY (all have the same address) */
-                       SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_ID1, &pPrt->PhyId1);
-
-                       /*
-                        * Optimize MDIO transfer by suppressing preamble.
-                        * Must be done AFTER first access to BCOM chip.
-                        */
-                       XM_IN16(IoC, Port, XM_MMU_CMD, &SWord);
-
-                       XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE);
-
-                       if (pPrt->PhyId1 == PHY_BCOM_ID1_C0) {
-                               /*
-                                * Workaround BCOM Errata for the C0 type.
-                                * Write magic patterns to reserved registers.
-                                */
-                               i = 0;
-                               while (BcomRegC0Hack[i].PhyReg != 0) {
-                                       SkXmPhyWrite(pAC, IoC, Port, BcomRegC0Hack[i].PhyReg,
-                                               BcomRegC0Hack[i].PhyVal);
-                                       i++;
-                               }
-                       }
-                       else if (pPrt->PhyId1 == PHY_BCOM_ID1_A1) {
-                               /*
-                                * Workaround BCOM Errata for the A1 type.
-                                * Write magic patterns to reserved registers.
-                                */
-                               i = 0;
-                               while (BcomRegA1Hack[i].PhyReg != 0) {
-                                       SkXmPhyWrite(pAC, IoC, Port, BcomRegA1Hack[i].PhyReg,
-                                               BcomRegA1Hack[i].PhyVal);
-                                       i++;
-                               }
-                       }
-
-                       /*
-                        * Workaround BCOM Errata (#10523) for all BCom PHYs.
-                        * Disable Power Management after reset.
-                        */
-                       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
-
-                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
-                               (SK_U16)(SWord | PHY_B_AC_DIS_PM));
-
-                       /* PHY LED initialization is done in SkGeXmitLED() */
-               }
-
-               /* Dummy read the Interrupt source register */
-               XM_IN16(IoC, Port, XM_ISRC, &SWord);
-
-               /*
-                * The auto-negotiation process starts immediately after
-                * clearing the reset. The auto-negotiation process should be
-                * started by the SIRQ, therefore stop it here immediately.
-                */
-               SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
-
-#if 0
-               /* temp. code: enable signal detect */
-               /* WARNING: do not override GMII setting above */
-               XM_OUT16(pAC, Port, XM_HW_CFG, XM_HW_COM4SIG);
-#endif
-       }
-
-       /*
-        * configure the XMACs Station Address
-        * B2_MAC_2 = xx xx xx xx xx x1 is programmed to XMAC A
-        * B2_MAC_3 = xx xx xx xx xx x2 is programmed to XMAC B
-        */
-       for (i = 0; i < 3; i++) {
-               /*
-                * The following 2 statements are together endianess
-                * independent. Remember this when changing.
-                */
-               SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
-
-               XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord);
-       }
-
-       /* Tx Inter Packet Gap (XM_TX_IPG):     use default */
-       /* Tx High Water Mark (XM_TX_HI_WM):    use default */
-       /* Tx Low Water Mark (XM_TX_LO_WM):     use default */
-       /* Host Request Threshold (XM_HT_THR):  use default */
-       /* Rx Request Threshold (XM_RX_THR):    use default */
-       /* Rx Low Water Mark (XM_RX_LO_WM):     use default */
-
-       /* configure Rx High Water Mark (XM_RX_HI_WM) */
-       XM_OUT16(IoC, Port, XM_RX_HI_WM, SK_XM_RX_HI_WM);
-
-       /* Configure Tx Request Threshold */
-       SWord = SK_XM_THR_SL;                           /* for single port */
-
-       if (pAC->GIni.GIMacsFound > 1) {
-               switch (pAC->GIni.GIPortUsage) {
-               case SK_RED_LINK:
-                       SWord = SK_XM_THR_REDL;         /* redundant link */
-                       break;
-               case SK_MUL_LINK:
-                       SWord = SK_XM_THR_MULL;         /* load balancing */
-                       break;
-               case SK_JUMBO_LINK:
-                       SWord = SK_XM_THR_JUMBO;        /* jumbo frames */
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E014, SKERR_HWI_E014MSG);
-                       break;
-               }
-       }
-       XM_OUT16(IoC, Port, XM_TX_THR, SWord);
-
-       /* setup register defaults for the Tx Command Register */
-       XM_OUT16(IoC, Port, XM_TX_CMD, XM_TX_AUTO_PAD);
-
-       /* setup register defaults for the Rx Command Register */
-       SWord = XM_RX_STRIP_FCS | XM_RX_LENERR_OK;
-
-       if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
-               SWord |= XM_RX_BIG_PK_OK;
-       }
-
-       if (pPrt->PLinkModeConf == SK_LMODE_HALF) {
-               /*
-                * If in manual half duplex mode the other side might be in
-                * full duplex mode, so ignore if a carrier extension is not seen
-                * on frames received
-                */
-               SWord |= XM_RX_DIS_CEXT;
-       }
-
-       XM_OUT16(IoC, Port, XM_RX_CMD, SWord);
-
-       /*
-        * setup register defaults for the Mode Register
-        *      - Don't strip error frames to avoid Store & Forward
-        *        on the Rx side.
-        *      - Enable 'Check Station Address' bit
-        *      - Enable 'Check Address Array' bit
-        */
-       XM_OUT32(IoC, Port, XM_MODE, XM_DEF_MODE);
-
-       /*
-        * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)
-        *      - Enable all bits excepting 'Octets Rx OK Low CntOv'
-        *        and 'Octets Rx OK Hi Cnt Ov'.
-        */
-       XM_OUT32(IoC, Port, XM_RX_EV_MSK, XMR_DEF_MSK);
-
-       /*
-        * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)
-        *      - Enable all bits excepting 'Octets Tx OK Low CntOv'
-        *        and 'Octets Tx OK Hi Cnt Ov'.
-        */
-       XM_OUT32(IoC, Port, XM_TX_EV_MSK, XMT_DEF_MSK);
-
-       /*
-        * Do NOT init XMAC interrupt mask here.
-        * All interrupts remain disable until link comes up!
-        */
-
-       /*
-        * Any additional configuration changes may be done now.
-        * The last action is to enable the Rx and Tx state machine.
-        * This should be done after the auto-negotiation process
-        * has been completed successfully.
-        */
-}      /* SkXmInitMac */
-
-/******************************************************************************
- *
- *     SkGmInitMac() - Initialize the GMAC
- *
- * Description:
- *     Initialize the GMAC of the specified port.
- *     The GMAC must be reset or stopped before calling this function.
- *
- * Note:
- *     The GMAC's Rx and Tx state machine is still disabled when returning.
- *
- * Returns:
- *     nothing
- */
-void SkGmInitMac(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       int                     i;
-       SK_U16          SWord;
-       SK_U32          DWord;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PState == SK_PRT_STOP) {
-               /* Port State: SK_PRT_STOP */
-               /* Verify that the reset bit is cleared */
-               SK_IN32(IoC, MR_ADDR(Port, GMAC_CTRL), &DWord);
-
-               if ((DWord & GMC_RST_SET) != 0) {
-                       /* PState does not match HW state */
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
-                       /* Correct it */
-                       pPrt->PState = SK_PRT_RESET;
-               }
-       }
-
-       if (pPrt->PState == SK_PRT_RESET) {
-               /* set GPHY Control reset */
-               SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
-
-               /* set GMAC Control reset */
-               SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
-
-               /* clear GMAC Control reset */
-               SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR);
-
-               /* set GMAC Control reset */
-               SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
-
-               /* set HWCFG_MODE */
-               DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
-                       GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
-                       (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
-                       GPC_HWCFG_GMII_FIB);
-
-               /* set GPHY Control reset */
-               SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
-
-               /* release GPHY Control reset */
-               SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
-
-               /* clear GMAC Control reset */
-               SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
-
-               /* Dummy read the Interrupt source register */
-               SK_IN16(IoC, GMAC_IRQ_SRC, &SWord);
-
-#ifndef VCPU
-               /* read Id from PHY */
-               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1);
-
-               SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
-#endif /* VCPU */
-       }
-
-       (void)SkGmResetCounter(pAC, IoC, Port);
-
-       SWord =  0;
-
-       /* speed settings */
-       switch (pPrt->PLinkSpeed) {
-       case SK_LSPEED_AUTO:
-       case SK_LSPEED_1000MBPS:
-               SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100;
-               break;
-       case SK_LSPEED_100MBPS:
-               SWord |= GM_GPCR_SPEED_100;
-               break;
-       case SK_LSPEED_10MBPS:
-               break;
-       }
-
-       /* duplex settings */
-       if (pPrt->PLinkMode != SK_LMODE_HALF) {
-               /* set full duplex */
-               SWord |= GM_GPCR_DUP_FULL;
-       }
-
-       /* flow control settings */
-       switch (pPrt->PFlowCtrlMode) {
-       case SK_FLOW_MODE_NONE:
-               /* disable auto-negotiation for flow-control */
-               SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS;
-               break;
-       case SK_FLOW_MODE_LOC_SEND:
-               SWord |= GM_GPCR_FC_RX_DIS;
-               break;
-       case SK_FLOW_MODE_SYMMETRIC:
-               /* TBD */
-       case SK_FLOW_MODE_SYM_OR_REM:
-               /* enable auto-negotiation for flow-control and */
-               /* enable Rx and Tx of pause frames */
-               break;
-       }
-
-       /* Auto-negotiation ? */
-       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
-               /* disable auto-update for speed, duplex and flow-control */
-               SWord |= GM_GPCR_AU_ALL_DIS;
-       }
-
-       /* setup General Purpose Control Register */
-       GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
-
-       /* setup Transmit Control Register */
-       GM_OUT16(IoC, Port, GM_TX_CTRL, GM_TXCR_COL_THR);
-
-       /* setup Receive Control Register */
-       GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA |
-               GM_RXCR_CRC_DIS);
-
-       /* setup Transmit Flow Control Register */
-       GM_OUT16(IoC, Port, GM_TX_FLOW_CTRL, 0xffff);
-
-       /* setup Transmit Parameter Register */
-#ifdef VCPU
-       GM_IN16(IoC, Port, GM_TX_PARAM, &SWord);
-#endif /* VCPU */
-
-       SWord = JAM_LEN_VAL(3) | JAM_IPG_VAL(11) | IPG_JAM_DATA(26);
-
-       GM_OUT16(IoC, Port, GM_TX_PARAM, SWord);
-
-       /* configure the Serial Mode Register */
-#ifdef VCPU
-       GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord);
-#endif /* VCPU */
-
-       SWord = GM_SMOD_VLAN_ENA | IPG_VAL_FAST_ETH;
-
-       if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
-               /* enable jumbo mode (Max. Frame Length = 9018) */
-               SWord |= GM_SMOD_JUMBO_ENA;
-       }
-
-       GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord);
-
-       /*
-        * configure the GMACs Station Addresses
-        * in PROM you can find our addresses at:
-        * B2_MAC_1 = xx xx xx xx xx x0 virtual address
-        * B2_MAC_2 = xx xx xx xx xx x1 is programmed to GMAC A
-        * B2_MAC_3 = xx xx xx xx xx x2 is reserved for DualPort
-        */
-
-       for (i = 0; i < 3; i++) {
-               /*
-                * The following 2 statements are together endianess
-                * independent. Remember this when changing.
-                */
-               /* physical address: will be used for pause frames */
-               SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
-
-#ifdef WA_DEV_16
-               /* WA for deviation #16 */
-               if (pAC->GIni.GIChipRev == 0) {
-                       /* swap the address bytes */
-                       SWord = ((SWord & 0xff00) >> 8) | ((SWord & 0x00ff) << 8);
-
-                       /* write to register in reversed order */
-                       GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + (2 - i) * 4), SWord);
-               }
-               else {
-                       GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
-               }
-#else
-               GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
-#endif /* WA_DEV_16 */
-
-               /* virtual address: will be used for data */
-               SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord);
-
-               GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord);
-
-               /* reset Multicast filtering Hash registers 1-3 */
-               GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + 4*i, 0);
-       }
-
-       /* reset Multicast filtering Hash register 4 */
-       GM_OUT16(IoC, Port, GM_MC_ADDR_H4, 0);
-
-       /* enable interrupt mask for counter overflows */
-       GM_OUT16(IoC, Port, GM_TX_IRQ_MSK, 0);
-       GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0);
-       GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0);
-
-       /* read General Purpose Status */
-       GM_IN16(IoC, Port, GM_GP_STAT, &SWord);
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("MAC Stat Reg=0x%04X\n", SWord));
-
-#ifdef SK_DIAG
-       c_print("MAC Stat Reg=0x%04X\n", SWord);
-#endif /* SK_DIAG */
-
-}      /* SkGmInitMac */
-
-
-/******************************************************************************
- *
- *     SkXmInitDupMd() - Initialize the XMACs Duplex Mode
- *
- * Description:
- *     This function initializes the XMACs Duplex Mode.
- *     It should be called after successfully finishing
- *     the Auto-negotiation Process
- *
- * Returns:
- *     nothing
- */
-void SkXmInitDupMd(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       switch (pAC->GIni.GP[Port].PLinkModeStatus) {
-       case SK_LMODE_STAT_AUTOHALF:
-       case SK_LMODE_STAT_HALF:
-               /* Configuration Actions for Half Duplex Mode */
-               /*
-                * XM_BURST = default value. We are probable not quick
-                *      enough at the 'XMAC' bus to burst 8kB.
-                *      The XMAC stops bursting if no transmit frames
-                *      are available or the burst limit is exceeded.
-                */
-               /* XM_TX_RT_LIM = default value (15) */
-               /* XM_TX_STIME = default value (0xff = 4096 bit times) */
-               break;
-       case SK_LMODE_STAT_AUTOFULL:
-       case SK_LMODE_STAT_FULL:
-               /* Configuration Actions for Full Duplex Mode */
-               /*
-                * The duplex mode is configured by the PHY,
-                * therefore it seems to be that there is nothing
-                * to do here.
-                */
-               break;
-       case SK_LMODE_STAT_UNKNOWN:
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E007, SKERR_HWI_E007MSG);
-               break;
-       }
-}      /* SkXmInitDupMd */
-
-
-/******************************************************************************
- *
- *     SkXmInitPauseMd() - initialize the Pause Mode to be used for this port
- *
- * Description:
- *     This function initializes the Pause Mode which should
- *     be used for this port.
- *     It should be called after successfully finishing
- *     the Auto-negotiation Process
- *
- * Returns:
- *     nothing
- */
-void SkXmInitPauseMd(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U32          DWord;
-       SK_U16          Word;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
-
-       if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE ||
-               pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
-
-               /* Disable Pause Frame Reception */
-               Word |= XM_MMU_IGN_PF;
-       }
-       else {
-               /*
-                * enabling pause frame reception is required for 1000BT
-                * because the XMAC is not reset if the link is going down
-                */
-               /* Enable Pause Frame Reception */
-               Word &= ~XM_MMU_IGN_PF;
-       }
-
-       XM_OUT16(IoC, Port, XM_MMU_CMD, Word);
-
-       XM_IN32(IoC, Port, XM_MODE, &DWord);
-
-       if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_SYMMETRIC ||
-               pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
-
-               /*
-                * Configure Pause Frame Generation
-                * Use internal and external Pause Frame Generation.
-                * Sending pause frames is edge triggered.
-                * Send a Pause frame with the maximum pause time if
-                * internal oder external FIFO full condition occurs.
-                * Send a zero pause time frame to re-start transmission.
-                */
-
-               /* XM_PAUSE_DA = '010000C28001' (default) */
-
-               /* XM_MAC_PTIME = 0xffff (maximum) */
-               /* remember this value is defined in big endian (!) */
-               XM_OUT16(IoC, Port, XM_MAC_PTIME, 0xffff);
-
-               /* Set Pause Mode in Mode Register */
-               DWord |= XM_PAUSE_MODE;
-
-               /* Set Pause Mode in MAC Rx FIFO */
-               SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_PAUSE);
-       }
-       else {
-               /*
-                * disable pause frame generation is required for 1000BT
-                * because the XMAC is not reset if the link is going down
-                */
-               /* Disable Pause Mode in Mode Register */
-               DWord &= ~XM_PAUSE_MODE;
-
-               /* Disable Pause Mode in MAC Rx FIFO */
-               SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_DIS_PAUSE);
-       }
-
-       XM_OUT32(IoC, Port, XM_MODE, DWord);
-}      /* SkXmInitPauseMd*/
-
-
-/******************************************************************************
- *
- *     SkXmInitPhyXmac() - Initialize the XMAC Phy registers
- *
- * Description:        initializes all the XMACs Phy registers
- *
- * Note:
- *
- * Returns:
- *     nothing
- */
-static void SkXmInitPhyXmac(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          Ctrl;
-
-       pPrt = &pAC->GIni.GP[Port];
-       Ctrl = 0;
-
-       /* Auto-negotiation ? */
-       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("InitPhyXmac: no auto-negotiation Port %d\n", Port));
-               /* Set DuplexMode in Config register */
-               if (pPrt->PLinkMode == SK_LMODE_FULL) {
-                       Ctrl |= PHY_CT_DUP_MD;
-               }
-
-               /*
-                * Do NOT enable Auto-negotiation here. This would hold
-                * the link down because no IDLEs are transmitted
-                */
-       }
-       else {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("InitPhyXmac: with auto-negotiation Port %d\n", Port));
-               /* Set Auto-negotiation advertisement */
-
-               /* Set Full/half duplex capabilities */
-               switch (pPrt->PLinkMode) {
-               case SK_LMODE_AUTOHALF:
-                       Ctrl |= PHY_X_AN_HD;
-                       break;
-               case SK_LMODE_AUTOFULL:
-                       Ctrl |= PHY_X_AN_FD;
-                       break;
-               case SK_LMODE_AUTOBOTH:
-                       Ctrl |= PHY_X_AN_FD | PHY_X_AN_HD;
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
-                               SKERR_HWI_E015MSG);
-               }
-
-               switch (pPrt->PFlowCtrlMode) {
-               case SK_FLOW_MODE_NONE:
-                       Ctrl |= PHY_X_P_NO_PAUSE;
-                       break;
-               case SK_FLOW_MODE_LOC_SEND:
-                       Ctrl |= PHY_X_P_ASYM_MD;
-                       break;
-               case SK_FLOW_MODE_SYMMETRIC:
-                       Ctrl |= PHY_X_P_SYM_MD;
-                       break;
-               case SK_FLOW_MODE_SYM_OR_REM:
-                       Ctrl |= PHY_X_P_BOTH_MD;
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
-                               SKERR_HWI_E016MSG);
-               }
-
-               /* Write AutoNeg Advertisement Register */
-               SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_AUNE_ADV, Ctrl);
-
-               /* Restart Auto-negotiation */
-               Ctrl = PHY_CT_ANE | PHY_CT_RE_CFG;
-       }
-
-       if (DoLoop) {
-               /* Set the Phy Loopback bit, too */
-               Ctrl |= PHY_CT_LOOP;
-       }
-
-       /* Write to the Phy control register */
-       SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_CTRL, Ctrl);
-}      /* SkXmInitPhyXmac */
-
-
-/******************************************************************************
- *
- *     SkXmInitPhyBcom() - Initialize the Broadcom Phy registers
- *
- * Description:        initializes all the Broadcom Phy registers
- *
- * Note:
- *
- * Returns:
- *     nothing
- */
-static void SkXmInitPhyBcom(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          Ctrl1;
-       SK_U16          Ctrl2;
-       SK_U16          Ctrl3;
-       SK_U16          Ctrl4;
-       SK_U16          Ctrl5;
-
-       Ctrl1 = PHY_CT_SP1000;
-       Ctrl2 = 0;
-       Ctrl3 = PHY_SEL_TYPE;
-       Ctrl4 = PHY_B_PEC_EN_LTR;
-       Ctrl5 = PHY_B_AC_TX_TST;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* manually Master/Slave ? */
-       if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
-               Ctrl2 |= PHY_B_1000C_MSE;
-
-               if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
-                       Ctrl2 |= PHY_B_1000C_MSC;
-               }
-       }
-       /* Auto-negotiation ? */
-       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("InitPhyBcom: no auto-negotiation Port %d\n", Port));
-               /* Set DuplexMode in Config register */
-               Ctrl1 |= (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
-
-               /* Determine Master/Slave manually if not already done */
-               if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
-                       Ctrl2 |= PHY_B_1000C_MSE;       /* set it to Slave */
-               }
-
-               /*
-                * Do NOT enable Auto-negotiation here. This would hold
-                * the link down because no IDLES are transmitted
-                */
-       }
-       else {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("InitPhyBcom: with auto-negotiation Port %d\n", Port));
-               /* Set Auto-negotiation advertisement */
-
-               /*
-                * Workaround BCOM Errata #1 for the C5 type.
-                * 1000Base-T Link Acquisition Failure in Slave Mode
-                * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
-                */
-               Ctrl2 |= PHY_B_1000C_RD;
-
-                /* Set Full/half duplex capabilities */
-               switch (pPrt->PLinkMode) {
-               case SK_LMODE_AUTOHALF:
-                       Ctrl2 |= PHY_B_1000C_AHD;
-                       break;
-               case SK_LMODE_AUTOFULL:
-                       Ctrl2 |= PHY_B_1000C_AFD;
-                       break;
-               case SK_LMODE_AUTOBOTH:
-                       Ctrl2 |= PHY_B_1000C_AFD | PHY_B_1000C_AHD;
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
-                               SKERR_HWI_E015MSG);
-               }
-
-               switch (pPrt->PFlowCtrlMode) {
-               case SK_FLOW_MODE_NONE:
-                       Ctrl3 |= PHY_B_P_NO_PAUSE;
-                       break;
-               case SK_FLOW_MODE_LOC_SEND:
-                       Ctrl3 |= PHY_B_P_ASYM_MD;
-                       break;
-               case SK_FLOW_MODE_SYMMETRIC:
-                       Ctrl3 |= PHY_B_P_SYM_MD;
-                       break;
-               case SK_FLOW_MODE_SYM_OR_REM:
-                       Ctrl3 |= PHY_B_P_BOTH_MD;
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
-                               SKERR_HWI_E016MSG);
-               }
-
-               /* Restart Auto-negotiation */
-               Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG;
-       }
-
-       /* Initialize LED register here? */
-       /* No. Please do it in SkDgXmitLed() (if required) and swap
-          init order of LEDs and XMAC. (MAl) */
-
-       /* Write 1000Base-T Control Register */
-       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
-
-       /* Write AutoNeg Advertisement Register */
-       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("Auto-Neg. Adv. Reg=0x%04X\n", Ctrl3));
-
-       if (DoLoop) {
-               /* Set the Phy Loopback bit, too */
-               Ctrl1 |= PHY_CT_LOOP;
-       }
-
-       if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
-               /* configure FIFO to high latency for transmission of ext. packets */
-               Ctrl4 |= PHY_B_PEC_HIGH_LA;
-
-               /* configure reception of extended packets */
-               Ctrl5 |= PHY_B_AC_LONG_PACK;
-
-               SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, Ctrl5);
-       }
-
-       /* Configure LED Traffic Mode and Jumbo Frame usage if specified */
-       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4);
-
-       /* Write to the Phy control register */
-       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, Ctrl1);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("PHY Control Reg=0x%04X\n", Ctrl1));
-}      /* SkXmInitPhyBcom */
-
-
-/******************************************************************************
- *
- *     SkGmInitPhyMarv() - Initialize the Marvell Phy registers
- *
- * Description:        initializes all the Marvell Phy registers
- *
- * Note:
- *
- * Returns:
- *     nothing
- */
-static void SkGmInitPhyMarv(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          PhyCtrl;
-       SK_U16          C1000BaseT;
-       SK_U16          AutoNegAdv;
-       SK_U16          ExtPhyCtrl;
-       SK_U16          PhyStat;
-       SK_U16          PhyStat1;
-       SK_U16          PhySpecStat;
-       SK_U16          LedCtrl;
-       SK_BOOL         AutoNeg;
-
-#ifdef VCPU
-       VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n",
-               Port, DoLoop);
-#else /* VCPU */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Auto-negotiation ? */
-       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
-               AutoNeg = SK_FALSE;
-       }
-       else {
-               AutoNeg = SK_TRUE;
-       }
-
-       if (!DoLoop) {
-               /* Read Ext. PHY Specific Control */
-               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
-
-               ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
-                       PHY_M_EC_MAC_S_MSK);
-
-               ExtPhyCtrl |= PHY_M_EC_M_DSC(1) | PHY_M_EC_S_DSC(1) |
-                       PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);
-
-               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl);
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("Ext.PHYCtrl=0x%04X\n", ExtPhyCtrl));
-
-               /* Read PHY Control */
-               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
-
-               /* Assert software reset */
-               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL,
-                       (SK_U16)(PhyCtrl | PHY_CT_RESET));
-       }
-#endif /* VCPU */
-
-       PhyCtrl = 0 /* PHY_CT_COL_TST */;
-       C1000BaseT = 0;
-       AutoNegAdv = PHY_SEL_TYPE;
-
-       /* manually Master/Slave ? */
-       if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
-               /* enable Manual Master/Slave */
-               C1000BaseT |= PHY_M_1000C_MSE;
-
-               if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
-                       C1000BaseT |= PHY_M_1000C_MSC;  /* set it to Master */
-               }
-       }
-
-       /* Auto-negotiation ? */
-       if (!AutoNeg) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("InitPhyMarv: no auto-negotiation Port %d\n", Port));
-
-               if (pPrt->PLinkMode == SK_LMODE_FULL) {
-                       /* Set Full Duplex Mode */
-                       PhyCtrl |= PHY_CT_DUP_MD;
-               }
-
-               /* Set Master/Slave manually if not already done */
-               if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
-                       C1000BaseT |= PHY_M_1000C_MSE;  /* set it to Slave */
-               }
-
-               /* Set Speed */
-               switch (pPrt->PLinkSpeed) {
-               case SK_LSPEED_AUTO:
-               case SK_LSPEED_1000MBPS:
-                       PhyCtrl |= PHY_CT_SP1000;
-                       break;
-               case SK_LSPEED_100MBPS:
-                       PhyCtrl |= PHY_CT_SP100;
-                       break;
-               case SK_LSPEED_10MBPS:
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
-                               SKERR_HWI_E019MSG);
-               }
-
-               if (!DoLoop) {
-                       PhyCtrl |= PHY_CT_RESET;
-               }
-               /*
-                * Do NOT enable Auto-negotiation here. This would hold
-                * the link down because no IDLES are transmitted
-                */
-       }
-       else {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("InitPhyMarv: with auto-negotiation Port %d\n", Port));
-
-               PhyCtrl |= PHY_CT_ANE;
-
-               if (pAC->GIni.GICopperType) {
-                       /* Set Speed capabilities */
-                       switch (pPrt->PLinkSpeed) {
-                       case SK_LSPEED_AUTO:
-                               C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
-                               AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
-                                       PHY_M_AN_10_FD | PHY_M_AN_10_HD;
-                               break;
-                       case SK_LSPEED_1000MBPS:
-                               C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
-                               break;
-                       case SK_LSPEED_100MBPS:
-                               AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
-                                       PHY_M_AN_10_FD | PHY_M_AN_10_HD;
-                               break;
-                       case SK_LSPEED_10MBPS:
-                               AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD;
-                               break;
-                       default:
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
-                                       SKERR_HWI_E019MSG);
-                       }
-
-                       /* Set Full/half duplex capabilities */
-                       switch (pPrt->PLinkMode) {
-                       case SK_LMODE_AUTOHALF:
-                               C1000BaseT &= ~PHY_M_1000C_AFD;
-                               AutoNegAdv &= ~(PHY_M_AN_100_FD | PHY_M_AN_10_FD);
-                               break;
-                       case SK_LMODE_AUTOFULL:
-                               C1000BaseT &= ~PHY_M_1000C_AHD;
-                               AutoNegAdv &= ~(PHY_M_AN_100_HD | PHY_M_AN_10_HD);
-                               break;
-                       case SK_LMODE_AUTOBOTH:
-                               break;
-                       default:
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
-                                       SKERR_HWI_E015MSG);
-                       }
-
-                       /* Set Auto-negotiation advertisement */
-                       switch (pPrt->PFlowCtrlMode) {
-                       case SK_FLOW_MODE_NONE:
-                               AutoNegAdv |= PHY_B_P_NO_PAUSE;
-                               break;
-                       case SK_FLOW_MODE_LOC_SEND:
-                               AutoNegAdv |= PHY_B_P_ASYM_MD;
-                               break;
-                       case SK_FLOW_MODE_SYMMETRIC:
-                               AutoNegAdv |= PHY_B_P_SYM_MD;
-                               break;
-                       case SK_FLOW_MODE_SYM_OR_REM:
-                               AutoNegAdv |= PHY_B_P_BOTH_MD;
-                               break;
-                       default:
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
-                                       SKERR_HWI_E016MSG);
-                       }
-               }
-               else {  /* special defines for FIBER (88E1011S only) */
-
-                       /* Set Full/half duplex capabilities */
-                       switch (pPrt->PLinkMode) {
-                       case SK_LMODE_AUTOHALF:
-                               AutoNegAdv |= PHY_M_AN_1000X_AHD;
-                               break;
-                       case SK_LMODE_AUTOFULL:
-                               AutoNegAdv |= PHY_M_AN_1000X_AFD;
-                               break;
-                       case SK_LMODE_AUTOBOTH:
-                               AutoNegAdv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
-                               break;
-                       default:
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
-                                       SKERR_HWI_E015MSG);
-                       }
-
-                       /* Set Auto-negotiation advertisement */
-                       switch (pPrt->PFlowCtrlMode) {
-                       case SK_FLOW_MODE_NONE:
-                               AutoNegAdv |= PHY_M_P_NO_PAUSE_X;
-                               break;
-                       case SK_FLOW_MODE_LOC_SEND:
-                               AutoNegAdv |= PHY_M_P_ASYM_MD_X;
-                               break;
-                       case SK_FLOW_MODE_SYMMETRIC:
-                               AutoNegAdv |= PHY_M_P_SYM_MD_X;
-                               break;
-                       case SK_FLOW_MODE_SYM_OR_REM:
-                               AutoNegAdv |= PHY_M_P_BOTH_MD_X;
-                               break;
-                       default:
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
-                                       SKERR_HWI_E016MSG);
-                       }
-               }
-
-               if (!DoLoop) {
-                       /* Restart Auto-negotiation */
-                       PhyCtrl |= PHY_CT_RE_CFG;
-               }
-       }
-
-#ifdef VCPU
-       /*
-        * E-mail from Gu Lin (08-03-2002):
-        */
-
-       /* Program PHY register 30 as 16'h0708 for simulation speed up */
-       SkGmPhyWrite(pAC, IoC, Port, 30, 0x0708);
-
-       VCpuWait(2000);
-
-#else /* VCPU */
-
-       /* Write 1000Base-T Control Register */
-       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("1000B-T Ctrl=0x%04X\n", C1000BaseT));
-
-       /* Write AutoNeg Advertisement Register */
-       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("Auto-Neg.Ad.=0x%04X\n", AutoNegAdv));
-#endif /* VCPU */
-
-       if (DoLoop) {
-               /* Set the PHY Loopback bit */
-               PhyCtrl |= PHY_CT_LOOP;
-
-               /* Program PHY register 16 as 16'h0400 to force link good */
-               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD);
-
-#if 0
-               if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) {
-                       /* Write Ext. PHY Specific Control */
-                       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL,
-                               (SK_U16)((pPrt->PLinkSpeed + 2) << 4));
-               }
-       }
-       else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) {
-                       /* Write PHY Specific Control */
-                       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_EN_DET_MSK);
-               }
-#endif /* 0 */
-       }
-
-       /* Write to the PHY Control register */
-       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
-
-#ifdef VCPU
-       VCpuWait(2000);
-#else
-
-       LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS) | PHY_M_LED_BLINK_RT(BLINK_84MS);
-
-#ifdef ACT_LED_BLINK
-       LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL;
-#endif /* ACT_LED_BLINK */
-
-#ifdef DUP_LED_NORMAL
-       LedCtrl |= PHY_M_LEDC_DP_CTRL;
-#endif /* DUP_LED_NORMAL */
-
-       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl);
-
-#endif /* VCPU */
-
-#ifdef SK_DIAG
-       c_print("Set PHY Ctrl=0x%04X\n", PhyCtrl);
-       c_print("Set 1000 B-T=0x%04X\n", C1000BaseT);
-       c_print("Set Auto-Neg=0x%04X\n", AutoNegAdv);
-       c_print("Set Ext Ctrl=0x%04X\n", ExtPhyCtrl);
-#endif /* SK_DIAG */
-
-#ifndef xDEBUG
-       /* Read PHY Control */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
-
-       /* Read 1000Base-T Control Register */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("1000B-T Ctrl =0x%04X\n", C1000BaseT));
-
-       /* Read AutoNeg Advertisement Register */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("Auto-Neg. Ad.=0x%04X\n", AutoNegAdv));
-
-       /* Read Ext. PHY Specific Control */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("Ext PHY Ctrl=0x%04X\n", ExtPhyCtrl));
-
-       /* Read PHY Status */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("PHY Stat Reg.=0x%04X\n", PhyStat));
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat1);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("PHY Stat Reg.=0x%04X\n", PhyStat1));
-
-       /* Read PHY Specific Status */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("PHY Spec Stat=0x%04X\n", PhySpecStat));
-#endif /* DEBUG */
-
-#ifdef SK_DIAG
-       c_print("PHY Ctrl Reg=0x%04X\n", PhyCtrl);
-       c_print("PHY 1000 Reg=0x%04X\n", C1000BaseT);
-       c_print("PHY AnAd Reg=0x%04X\n", AutoNegAdv);
-       c_print("Ext Ctrl Reg=0x%04X\n", ExtPhyCtrl);
-       c_print("PHY Stat Reg=0x%04X\n", PhyStat);
-       c_print("PHY Stat Reg=0x%04X\n", PhyStat1);
-       c_print("PHY Spec Reg=0x%04X\n", PhySpecStat);
-#endif /* SK_DIAG */
-
-}      /* SkGmInitPhyMarv */
-
-
-#ifdef OTHER_PHY
-/******************************************************************************
- *
- *     SkXmInitPhyLone() - Initialize the Level One Phy registers
- *
- * Description:        initializes all the Level One Phy registers
- *
- * Note:
- *
- * Returns:
- *     nothing
- */
-static void SkXmInitPhyLone(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          Ctrl1;
-       SK_U16          Ctrl2;
-       SK_U16          Ctrl3;
-
-       Ctrl1 = PHY_CT_SP1000;
-       Ctrl2 = 0;
-       Ctrl3 = PHY_SEL_TYPE;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* manually Master/Slave ? */
-       if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
-               Ctrl2 |= PHY_L_1000C_MSE;
-
-               if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
-                       Ctrl2 |= PHY_L_1000C_MSC;
-               }
-       }
-       /* Auto-negotiation ? */
-       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
-               /*
-                * level one spec say: "1000Mbps: manual mode not allowed"
-                * but lets see what happens...
-                */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("InitPhyLone: no auto-negotiation Port %d\n", Port));
-               /* Set DuplexMode in Config register */
-               Ctrl1 = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
-
-               /* Determine Master/Slave manually if not already done */
-               if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
-                       Ctrl2 |= PHY_L_1000C_MSE;       /* set it to Slave */
-               }
-
-               /*
-                * Do NOT enable Auto-negotiation here. This would hold
-                * the link down because no IDLES are transmitted
-                */
-       }
-       else {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("InitPhyLone: with auto-negotiation Port %d\n", Port));
-               /* Set Auto-negotiation advertisement */
-
-               /* Set Full/half duplex capabilities */
-               switch (pPrt->PLinkMode) {
-               case SK_LMODE_AUTOHALF:
-                       Ctrl2 |= PHY_L_1000C_AHD;
-                       break;
-               case SK_LMODE_AUTOFULL:
-                       Ctrl2 |= PHY_L_1000C_AFD;
-                       break;
-               case SK_LMODE_AUTOBOTH:
-                       Ctrl2 |= PHY_L_1000C_AFD | PHY_L_1000C_AHD;
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
-                               SKERR_HWI_E015MSG);
-               }
-
-               switch (pPrt->PFlowCtrlMode) {
-               case SK_FLOW_MODE_NONE:
-                       Ctrl3 |= PHY_L_P_NO_PAUSE;
-                       break;
-               case SK_FLOW_MODE_LOC_SEND:
-                       Ctrl3 |= PHY_L_P_ASYM_MD;
-                       break;
-               case SK_FLOW_MODE_SYMMETRIC:
-                       Ctrl3 |= PHY_L_P_SYM_MD;
-                       break;
-               case SK_FLOW_MODE_SYM_OR_REM:
-                       Ctrl3 |= PHY_L_P_BOTH_MD;
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
-                               SKERR_HWI_E016MSG);
-               }
-
-               /* Restart Auto-negotiation */
-               Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG;
-
-       }
-
-       /* Initialize LED register here ? */
-       /* No. Please do it in SkDgXmitLed() (if required) and swap
-          init order of LEDs and XMAC. (MAl) */
-
-       /* Write 1000Base-T Control Register */
-       SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
-
-       /* Write AutoNeg Advertisement Register */
-       SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("Auto-Neg. Adv. Reg=0x%04X\n", Ctrl3));
-
-
-       if (DoLoop) {
-               /* Set the Phy Loopback bit, too */
-               Ctrl1 |= PHY_CT_LOOP;
-       }
-
-       /* Write to the Phy control register */
-       SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_CTRL, Ctrl1);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("PHY Control Reg=0x%04X\n", Ctrl1));
-}      /* SkXmInitPhyLone */
-
-
-/******************************************************************************
- *
- *     SkXmInitPhyNat() - Initialize the National Phy registers
- *
- * Description:        initializes all the National Phy registers
- *
- * Note:
- *
- * Returns:
- *     nothing
- */
-static void SkXmInitPhyNat(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
-{
-/* todo: National */
-}      /* SkXmInitPhyNat */
-#endif /* OTHER_PHY */
-
-
-/******************************************************************************
- *
- *     SkMacInitPhy() - Initialize the PHY registers
- *
- * Description:        calls the Init PHY routines dep. on board type
- *
- * Note:
- *
- * Returns:
- *     nothing
- */
-void SkMacInitPhy(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
-{
-       SK_GEPORT       *pPrt;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       switch (pPrt->PhyType) {
-       case SK_PHY_XMAC:
-               SkXmInitPhyXmac(pAC, IoC, Port, DoLoop);
-               break;
-       case SK_PHY_BCOM:
-               SkXmInitPhyBcom(pAC, IoC, Port, DoLoop);
-               break;
-       case SK_PHY_MARV_COPPER:
-       case SK_PHY_MARV_FIBER:
-               SkGmInitPhyMarv(pAC, IoC, Port, DoLoop);
-               break;
-#ifdef OTHER_PHY
-       case SK_PHY_LONE:
-               SkXmInitPhyLone(pAC, IoC, Port, DoLoop);
-               break;
-       case SK_PHY_NAT:
-               SkXmInitPhyNat(pAC, IoC, Port, DoLoop);
-               break;
-#endif /* OTHER_PHY */
-       }
-}      /* SkMacInitPhy */
-
-
-#ifndef SK_DIAG
-/******************************************************************************
- *
- *     SkXmAutoNegLipaXmac() - Decides whether Link Partner could do auto-neg
- *
- *     This function analyses the Interrupt status word. If any of the
- *     Auto-negotiating interrupt bits are set, the PLipaAutoNeg variable
- *     is set true.
- */
-void SkXmAutoNegLipaXmac(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_U16 IStatus)        /* Interrupt Status word to analyse */
-{
-       SK_GEPORT       *pPrt;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
-               (IStatus & (XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND)) != 0) {
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegLipa: AutoNeg detected on Port %d, IStatus=0x%04x\n",
-                       Port, IStatus));
-               pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
-       }
-}      /* SkXmAutoNegLipaXmac */
-
-
-/******************************************************************************
- *
- *     SkMacAutoNegLipaPhy() - Decides whether Link Partner could do auto-neg
- *
- *     This function analyses the PHY status word.
- *  If any of the Auto-negotiating bits are set, the PLipaAutoNeg variable
- *     is set true.
- */
-void SkMacAutoNegLipaPhy(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_U16 PhyStat)        /* PHY Status word to analyse */
-{
-       SK_GEPORT       *pPrt;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
-               (PhyStat & PHY_ST_AN_OVER) != 0) {
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat=0x%04x\n",
-                       Port, PhyStat));
-               pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
-       }
-}      /* SkMacAutoNegLipaPhy */
-#endif /* SK_DIAG */
-
-
-/******************************************************************************
- *
- *     SkXmAutoNegDoneXmac() - Auto-negotiation handling
- *
- * Description:
- *     This function handles the auto-negotiation if the Done bit is set.
- *
- * Returns:
- *     SK_AND_OK       o.k.
- *     SK_AND_DUP_CAP  Duplex capability error happened
- *     SK_AND_OTHER    Other error happened
- */
-static int SkXmAutoNegDoneXmac(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          ResAb;          /* Resolved Ability */
-       SK_U16          LPAb;           /* Link Partner Ability */
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("AutoNegDoneXmac, Port %d\n",Port));
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Get PHY parameters */
-       SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LPAb);
-       SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
-
-       if ((LPAb & PHY_X_AN_RFB) != 0) {
-               /* At least one of the remote fault bit is set */
-               /* Error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegFail: Remote fault bit set Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               return(SK_AND_OTHER);
-       }
-
-       /* Check Duplex mismatch */
-       if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) {
-               pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
-       }
-       else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) {
-               pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
-       }
-       else {
-               /* Error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               return(SK_AND_DUP_CAP);
-       }
-
-       /* Check PAUSE mismatch */
-       /* We are NOT using chapter 4.23 of the Xaqti manual */
-       /* We are using IEEE 802.3z/D5.0 Table 37-4 */
-       if ((pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC ||
-            pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) &&
-           (LPAb & PHY_X_P_SYM_MD) != 0) {
-               /* Symmetric PAUSE */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
-       }
-       else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM &&
-                  (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) {
-               /* Enable PAUSE receive, disable PAUSE transmit */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
-       }
-       else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND &&
-                  (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) {
-               /* Disable PAUSE receive, enable PAUSE transmit */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
-       }
-       else {
-               /* PAUSE mismatch -> no PAUSE */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
-       }
-       pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
-
-       return(SK_AND_OK);
-}      /* SkXmAutoNegDoneXmac */
-
-
-/******************************************************************************
- *
- *     SkXmAutoNegDoneBcom() - Auto-negotiation handling
- *
- * Description:
- *     This function handles the auto-negotiation if the Done bit is set.
- *
- * Returns:
- *     SK_AND_OK       o.k.
- *     SK_AND_DUP_CAP  Duplex capability error happened
- *     SK_AND_OTHER    Other error happened
- */
-static int SkXmAutoNegDoneBcom(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          LPAb;           /* Link Partner Ability */
-       SK_U16          AuxStat;        /* Auxiliary Status */
-
-#if 0
-01-Sep-2000 RA;:;:
-       SK_U16          ResAb;          /* Resolved Ability */
-#endif /* 0 */
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("AutoNegDoneBcom, Port %d\n", Port));
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Get PHY parameters */
-       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LPAb);
-#if 0
-01-Sep-2000 RA;:;:
-       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
-#endif /* 0 */
-
-       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &AuxStat);
-
-       if ((LPAb & PHY_B_AN_RF) != 0) {
-               /* Remote fault bit is set: Error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegFail: Remote fault bit set Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               return(SK_AND_OTHER);
-       }
-
-       /* Check Duplex mismatch */
-       if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000FD) {
-               pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
-       }
-       else if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000HD) {
-               pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
-       }
-       else {
-               /* Error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               return(SK_AND_DUP_CAP);
-       }
-
-#if 0
-01-Sep-2000 RA;:;:
-       /* Check Master/Slave resolution */
-       if ((ResAb & PHY_B_1000S_MSF) != 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("Master/Slave Fault Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               pPrt->PMSStatus = SK_MS_STAT_FAULT;
-               return(SK_AND_OTHER);
-       }
-
-       pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
-               SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
-#endif /* 0 */
-
-       /* Check PAUSE mismatch */
-       /* We are using IEEE 802.3z/D5.0 Table 37-4 */
-       if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PAUSE_MSK) {
-               /* Symmetric PAUSE */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
-       }
-       else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRR) {
-               /* Enable PAUSE receive, disable PAUSE transmit */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
-       }
-       else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRT) {
-               /* Disable PAUSE receive, enable PAUSE transmit */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
-       }
-       else {
-               /* PAUSE mismatch -> no PAUSE */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
-       }
-       pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
-
-       return(SK_AND_OK);
-}      /* SkXmAutoNegDoneBcom */
-
-
-/******************************************************************************
- *
- *     SkGmAutoNegDoneMarv() - Auto-negotiation handling
- *
- * Description:
- *     This function handles the auto-negotiation if the Done bit is set.
- *
- * Returns:
- *     SK_AND_OK       o.k.
- *     SK_AND_DUP_CAP  Duplex capability error happened
- *     SK_AND_OTHER    Other error happened
- */
-static int SkGmAutoNegDoneMarv(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          LPAb;           /* Link Partner Ability */
-       SK_U16          ResAb;          /* Resolved Ability */
-       SK_U16          AuxStat;        /* Auxiliary Status */
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("AutoNegDoneMarv, Port %d\n", Port));
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Get PHY parameters */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb);
-
-       if ((LPAb & PHY_M_AN_RF) != 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegFail: Remote fault bit set Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               return(SK_AND_OTHER);
-       }
-
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
-
-       /* Check Master/Slave resolution */
-       if ((ResAb & PHY_B_1000S_MSF) != 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("Master/Slave Fault Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               pPrt->PMSStatus = SK_MS_STAT_FAULT;
-               return(SK_AND_OTHER);
-       }
-
-       pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
-               (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE;
-
-       /* Read PHY Specific Status */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &AuxStat);
-
-       /* Check Speed & Duplex resolved */
-       if ((AuxStat & PHY_M_PS_SPDUP_RES) == 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegFail: Speed & Duplex not resolved Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN;
-               return(SK_AND_DUP_CAP);
-       }
-
-       if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) {
-               pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
-       }
-       else {
-               pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
-       }
-
-       /* Check PAUSE mismatch */
-       /* We are using IEEE 802.3z/D5.0 Table 37-4 */
-       if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_PAUSE_MSK) {
-               /* Symmetric PAUSE */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
-       }
-       else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_RX_P_EN) {
-               /* Enable PAUSE receive, disable PAUSE transmit */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
-       }
-       else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_TX_P_EN) {
-               /* Disable PAUSE receive, enable PAUSE transmit */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
-       }
-       else {
-               /* PAUSE mismatch -> no PAUSE */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
-       }
-
-       /* set used link speed */
-       switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) {
-       case (unsigned)PHY_M_PS_SPEED_1000:
-               pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
-               break;
-       case PHY_M_PS_SPEED_100:
-               pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_100MBPS;
-               break;
-       default:
-               pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_10MBPS;
-       }
-
-       return(SK_AND_OK);
-}      /* SkGmAutoNegDoneMarv */
-
-
-#ifdef OTHER_PHY
-/******************************************************************************
- *
- *     SkXmAutoNegDoneLone() - Auto-negotiation handling
- *
- * Description:
- *     This function handles the auto-negotiation if the Done bit is set.
- *
- * Returns:
- *     SK_AND_OK       o.k.
- *     SK_AND_DUP_CAP  Duplex capability error happened
- *     SK_AND_OTHER    Other error happened
- */
-static int SkXmAutoNegDoneLone(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          ResAb;          /* Resolved Ability */
-       SK_U16          LPAb;           /* Link Partner Ability */
-       SK_U16          QuickStat;      /* Auxiliary Status */
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("AutoNegDoneLone, Port %d\n",Port));
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Get PHY parameters */
-       SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LPAb);
-       SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ResAb);
-       SkXmPhyRead(pAC, IoC, Port, PHY_LONE_Q_STAT, &QuickStat);
-
-       if ((LPAb & PHY_L_AN_RF) != 0) {
-               /* Remote fault bit is set */
-               /* Error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegFail: Remote fault bit set Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               return(SK_AND_OTHER);
-       }
-
-       /* Check Duplex mismatch */
-       if ((QuickStat & PHY_L_QS_DUP_MOD) != 0) {
-               pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
-       }
-       else {
-               pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
-       }
-
-       /* Check Master/Slave resolution */
-       if ((ResAb & PHY_L_1000S_MSF) != 0) {
-               /* Error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("Master/Slave Fault Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               pPrt->PMSStatus = SK_MS_STAT_FAULT;
-               return(SK_AND_OTHER);
-       }
-       else if (ResAb & PHY_L_1000S_MSR) {
-               pPrt->PMSStatus = SK_MS_STAT_MASTER;
-       }
-       else {
-               pPrt->PMSStatus = SK_MS_STAT_SLAVE;
-       }
-
-       /* Check PAUSE mismatch */
-       /* We are using IEEE 802.3z/D5.0 Table 37-4 */
-       /* we must manually resolve the abilities here */
-       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
-       switch (pPrt->PFlowCtrlMode) {
-       case SK_FLOW_MODE_NONE:
-               /* default */
-               break;
-       case SK_FLOW_MODE_LOC_SEND:
-               if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
-                       (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) {
-                       /* Disable PAUSE receive, enable PAUSE transmit */
-                       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
-               }
-               break;
-       case SK_FLOW_MODE_SYMMETRIC:
-               if ((QuickStat & PHY_L_QS_PAUSE) != 0) {
-                       /* Symmetric PAUSE */
-                       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
-               }
-               break;
-       case SK_FLOW_MODE_SYM_OR_REM:
-               if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
-                       PHY_L_QS_AS_PAUSE) {
-                       /* Enable PAUSE receive, disable PAUSE transmit */
-                       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
-               }
-               else if ((QuickStat & PHY_L_QS_PAUSE) != 0) {
-                       /* Symmetric PAUSE */
-                       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
-               }
-               break;
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
-                       SKERR_HWI_E016MSG);
-       }
-
-       return(SK_AND_OK);
-}      /* SkXmAutoNegDoneLone */
-
-
-/******************************************************************************
- *
- *     SkXmAutoNegDoneNat() - Auto-negotiation handling
- *
- * Description:
- *     This function handles the auto-negotiation if the Done bit is set.
- *
- * Returns:
- *     SK_AND_OK       o.k.
- *     SK_AND_DUP_CAP  Duplex capability error happened
- *     SK_AND_OTHER    Other error happened
- */
-static int SkXmAutoNegDoneNat(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-/* todo: National */
-       return(SK_AND_OK);
-}      /* SkXmAutoNegDoneNat */
-#endif /* OTHER_PHY */
-
-
-/******************************************************************************
- *
- *     SkMacAutoNegDone() - Auto-negotiation handling
- *
- * Description:        calls the auto-negotiation done routines dep. on board type
- *
- * Returns:
- *     SK_AND_OK       o.k.
- *     SK_AND_DUP_CAP  Duplex capability error happened
- *     SK_AND_OTHER    Other error happened
- */
-int    SkMacAutoNegDone(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       int     Rtv;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       switch (pPrt->PhyType) {
-       case SK_PHY_XMAC:
-               Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port);
-               break;
-       case SK_PHY_BCOM:
-               Rtv = SkXmAutoNegDoneBcom(pAC, IoC, Port);
-               break;
-       case SK_PHY_MARV_COPPER:
-       case SK_PHY_MARV_FIBER:
-               Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port);
-               break;
-#ifdef OTHER_PHY
-       case SK_PHY_LONE:
-               Rtv = SkXmAutoNegDoneLone(pAC, IoC, Port);
-               break;
-       case SK_PHY_NAT:
-               Rtv = SkXmAutoNegDoneNat(pAC, IoC, Port);
-               break;
-#endif /* OTHER_PHY */
-       default:
-               return(SK_AND_OTHER);
-       }
-
-       if (Rtv != SK_AND_OK) {
-               return(Rtv);
-       }
-
-       /* We checked everything and may now enable the link */
-       pPrt->PAutoNegFail = SK_FALSE;
-
-       SkMacRxTxEnable(pAC, IoC, Port);
-
-       return(SK_AND_OK);
-}      /* SkMacAutoNegDone */
-
-
-/******************************************************************************
- *
- *     SkXmSetRxTxEn() - Special Set Rx/Tx Enable and some features in XMAC
- *
- * Description:
- *  sets MAC or PHY LoopBack and Duplex Mode in the MMU Command Reg.
- *  enables Rx/Tx
- *
- * Returns: N/A
- */
-static void SkXmSetRxTxEn(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            Para)           /* Parameter to set: MAC or PHY LoopBack, Duplex Mode */
-{
-       SK_U16  Word;
-
-       XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
-
-       switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) {
-       case SK_MAC_LOOPB_ON:
-               Word |= XM_MMU_MAC_LB;
-               break;
-       case SK_MAC_LOOPB_OFF:
-               Word &= ~XM_MMU_MAC_LB;
-               break;
-       }
-
-       switch (Para & (SK_PHY_LOOPB_ON | SK_PHY_LOOPB_OFF)) {
-       case SK_PHY_LOOPB_ON:
-               Word |= XM_MMU_GMII_LOOP;
-               break;
-       case SK_PHY_LOOPB_OFF:
-               Word &= ~XM_MMU_GMII_LOOP;
-               break;
-       }
-
-       switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) {
-       case SK_PHY_FULLD_ON:
-               Word |= XM_MMU_GMII_FD;
-               break;
-       case SK_PHY_FULLD_OFF:
-               Word &= ~XM_MMU_GMII_FD;
-               break;
-       }
-
-       XM_OUT16(IoC, Port, XM_MMU_CMD, Word | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
-
-       /* dummy read to ensure writing */
-       XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
-
-}      /* SkXmSetRxTxEn */
-
-
-/******************************************************************************
- *
- *     SkGmSetRxTxEn() - Special Set Rx/Tx Enable and some features in GMAC
- *
- * Description:
- *  sets MAC LoopBack and Duplex Mode in the General Purpose Control Reg.
- *  enables Rx/Tx
- *
- * Returns: N/A
- */
-static void SkGmSetRxTxEn(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            Para)           /* Parameter to set: MAC LoopBack, Duplex Mode */
-{
-       SK_U16  Ctrl;
-
-       GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl);
-
-       switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) {
-       case SK_MAC_LOOPB_ON:
-               Ctrl |= GM_GPCR_LOOP_ENA;
-               break;
-       case SK_MAC_LOOPB_OFF:
-               Ctrl &= ~GM_GPCR_LOOP_ENA;
-               break;
-       }
-
-       switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) {
-       case SK_PHY_FULLD_ON:
-               Ctrl |= GM_GPCR_DUP_FULL;
-               break;
-       case SK_PHY_FULLD_OFF:
-               Ctrl &= ~GM_GPCR_DUP_FULL;
-               break;
-       }
-
-       GM_OUT16(IoC, Port, GM_GP_CTRL, Ctrl | GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
-
-       /* dummy read to ensure writing */
-       GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl);
-
-}      /* SkGmSetRxTxEn */
-
-
-/******************************************************************************
- *
- *     SkMacSetRxTxEn() - Special Set Rx/Tx Enable and parameters
- *
- * Description:        calls the Special Set Rx/Tx Enable routines dep. on board type
- *
- * Returns: N/A
- */
-void SkMacSetRxTxEn(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            Para)
-{
-       if (pAC->GIni.GIGenesis) {
-
-               SkXmSetRxTxEn(pAC, IoC, Port, Para);
-       }
-       else {
-
-               SkGmSetRxTxEn(pAC, IoC, Port, Para);
-       }
-
-}      /* SkMacSetRxTxEn */
-
-
-/******************************************************************************
- *
- *     SkMacRxTxEnable() - Enable Rx/Tx activity if port is up
- *
- * Description:        enables Rx/Tx dep. on board type
- *
- * Returns:
- *     0       o.k.
- *     != 0    Error happened
- */
-int SkMacRxTxEnable(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          Reg;            /* 16-bit register value */
-       SK_U16          IntMask;        /* MAC interrupt mask */
-       SK_U16          SWord;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (!pPrt->PHWLinkUp) {
-               /* The Hardware link is NOT up */
-               return(0);
-       }
-
-       if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF ||
-            pPrt->PLinkMode == SK_LMODE_AUTOFULL ||
-            pPrt->PLinkMode == SK_LMODE_AUTOBOTH) &&
-            pPrt->PAutoNegFail) {
-               /* Auto-negotiation is not done or failed */
-               return(0);
-       }
-
-       if (pAC->GIni.GIGenesis) {
-               /* set Duplex Mode and Pause Mode */
-               SkXmInitDupMd(pAC, IoC, Port);
-
-               SkXmInitPauseMd(pAC, IoC, Port);
-
-               /*
-                * Initialize the Interrupt Mask Register. Default IRQs are...
-                *      - Link Asynchronous Event
-                *      - Link Partner requests config
-                *      - Auto Negotiation Done
-                *      - Rx Counter Event Overflow
-                *      - Tx Counter Event Overflow
-                *      - Transmit FIFO Underrun
-                */
-               IntMask = XM_DEF_MSK;
-
-#ifdef DEBUG
-               /* add IRQ for Receive FIFO Overflow */
-               IntMask &= ~XM_IS_RXF_OV;
-#endif /* DEBUG */
-
-               if (pPrt->PhyType != SK_PHY_XMAC) {
-                       /* disable GP0 interrupt bit */
-                       IntMask |= XM_IS_INP_ASS;
-               }
-               XM_OUT16(IoC, Port, XM_IMSK, IntMask);
-
-               /* get MMU Command Reg. */
-               XM_IN16(IoC, Port, XM_MMU_CMD, &Reg);
-
-               if (pPrt->PhyType != SK_PHY_XMAC &&
-                       (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
-                        pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) {
-                       /* set to Full Duplex */
-                       Reg |= XM_MMU_GMII_FD;
-               }
-
-               switch (pPrt->PhyType) {
-               case SK_PHY_BCOM:
-                       /*
-                        * Workaround BCOM Errata (#10523) for all BCom Phys
-                        * Enable Power Management after link up
-                        */
-                       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
-                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
-                               (SK_U16)(SWord & ~PHY_B_AC_DIS_PM));
-                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
-                       break;
-#ifdef OTHER_PHY
-               case SK_PHY_LONE:
-                       SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, PHY_L_DEF_MSK);
-                       break;
-               case SK_PHY_NAT:
-                       /* todo National:
-                       SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, PHY_N_DEF_MSK); */
-                       /* no interrupts possible from National ??? */
-                       break;
-#endif /* OTHER_PHY */
-               }
-
-               /* enable Rx/Tx */
-               XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
-       }
-       else {
-               /*
-                * Initialize the Interrupt Mask Register. Default IRQs are...
-                *      - Rx Counter Event Overflow
-                *      - Tx Counter Event Overflow
-                *      - Transmit FIFO Underrun
-                */
-               IntMask = GMAC_DEF_MSK;
-
-#ifdef DEBUG
-               /* add IRQ for Receive FIFO Overrun */
-               IntMask |= GM_IS_RX_FF_OR;
-#endif /* DEBUG */
-
-               SK_OUT8(IoC, GMAC_IRQ_MSK, (SK_U8)IntMask);
-
-               /* get General Purpose Control */
-               GM_IN16(IoC, Port, GM_GP_CTRL, &Reg);
-
-               if (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
-                       pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) {
-                       /* set to Full Duplex */
-                       Reg |= GM_GPCR_DUP_FULL;
-               }
-
-               /* enable Rx/Tx */
-               GM_OUT16(IoC, Port, GM_GP_CTRL, Reg | GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
-
-#ifndef VCPU
-               /* Enable all PHY interrupts */
-               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
-#endif /* VCPU */
-       }
-
-       return(0);
-
-}      /* SkMacRxTxEnable */
-
-
-/******************************************************************************
- *
- *     SkMacRxTxDisable() - Disable Receiver and Transmitter
- *
- * Description:        disables Rx/Tx dep. on board type
- *
- * Returns: N/A
- */
-void SkMacRxTxDisable(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_U16  Word;
-
-       if (pAC->GIni.GIGenesis) {
-
-               XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
-
-               XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
-
-               /* dummy read to ensure writing */
-               XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
-       }
-       else {
-
-               GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
-
-               GM_OUT16(IoC, Port, GM_GP_CTRL, Word & ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA));
-
-               /* dummy read to ensure writing */
-               GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
-       }
-}      /* SkMacRxTxDisable */
-
-
-/******************************************************************************
- *
- *     SkMacIrqDisable() - Disable IRQ from MAC
- *
- * Description:        sets the IRQ-mask to disable IRQ dep. on board type
- *
- * Returns: N/A
- */
-void SkMacIrqDisable(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          Word;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pAC->GIni.GIGenesis) {
-
-               /* disable all XMAC IRQs */
-               XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
-
-               /* Disable all PHY interrupts */
-               switch (pPrt->PhyType) {
-                       case SK_PHY_BCOM:
-                               /* Make sure that PHY is initialized */
-                               if (pPrt->PState != SK_PRT_RESET) {
-                                       /* NOT allowed if BCOM is in RESET state */
-                                       /* Workaround BCOM Errata (#10523) all BCom */
-                                       /* Disable Power Management if link is down */
-                                       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Word);
-                                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
-                                               (SK_U16)(Word | PHY_B_AC_DIS_PM));
-                                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff);
-                               }
-                               break;
-#ifdef OTHER_PHY
-                       case SK_PHY_LONE:
-                               SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0);
-                               break;
-                       case SK_PHY_NAT:
-                               /* todo: National
-                               SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */
-                               break;
-#endif /* OTHER_PHY */
-               }
-       }
-       else {
-               /* disable all GMAC IRQs */
-               SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
-
-#ifndef VCPU
-               /* Disable all PHY interrupts */
-               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
-#endif /* VCPU */
-       }
-}      /* SkMacIrqDisable */
-
-
-#ifdef SK_DIAG
-/******************************************************************************
- *
- *     SkXmSendCont() - Enable / Disable Send Continuous Mode
- *
- * Description:        enable / disable Send Continuous Mode on XMAC
- *
- * Returns:
- *     nothing
- */
-void SkXmSendCont(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port,   /* Port Index (MAC_1 + n) */
-SK_BOOL        Enable) /* Enable / Disable */
-{
-       SK_U32  MdReg;
-
-       XM_IN32(IoC, Port, XM_MODE, &MdReg);
-
-       if (Enable) {
-               MdReg |= XM_MD_TX_CONT;
-       }
-       else {
-               MdReg &= ~XM_MD_TX_CONT;
-       }
-       /* setup Mode Register */
-       XM_OUT32(IoC, Port, XM_MODE, MdReg);
-
-}      /* SkXmSendCont*/
-
-/******************************************************************************
- *
- *     SkMacTimeStamp() - Enable / Disable Time Stamp
- *
- * Description:        enable / disable Time Stamp generation for Rx packets
- *
- * Returns:
- *     nothing
- */
-void SkMacTimeStamp(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port,   /* Port Index (MAC_1 + n) */
-SK_BOOL        Enable) /* Enable / Disable */
-{
-       SK_U32  MdReg;
-       SK_U8   TimeCtrl;
-
-       if (pAC->GIni.GIGenesis) {
-
-               XM_IN32(IoC, Port, XM_MODE, &MdReg);
-
-               if (Enable) {
-                       MdReg |= XM_MD_ATS;
-               }
-               else {
-                       MdReg &= ~XM_MD_ATS;
-               }
-               /* setup Mode Register */
-               XM_OUT32(IoC, Port, XM_MODE, MdReg);
-       }
-       else {
-               if (Enable) {
-                       TimeCtrl = GMT_ST_START | GMT_ST_CLR_IRQ;
-               }
-               else {
-                       TimeCtrl = GMT_ST_STOP | GMT_ST_CLR_IRQ;
-               }
-               /* Start/Stop Time Stamp Timer */
-               SK_OUT8(pAC, GMAC_TI_ST_CTRL, TimeCtrl);
-       }
-}      /* SkMacTimeStamp*/
-
-#else /* SK_DIAG */
-
-/******************************************************************************
- *
- *     SkXmIrq() - Interrupt Service Routine
- *
- * Description:        services an Interrupt Request of the XMAC
- *
- * Note:
- *     With an external PHY, some interrupt bits are not meaningfull any more:
- *     - LinkAsyncEvent (bit #14)              XM_IS_LNK_AE
- *     - LinkPartnerReqConfig (bit #10)        XM_IS_LIPA_RC
- *     - Page Received (bit #9)                XM_IS_RX_PAGE
- *     - NextPageLoadedForXmt (bit #8)         XM_IS_TX_PAGE
- *     - AutoNegDone (bit #7)                  XM_IS_AND
- *     Also probably not valid any more is the GP0 input bit:
- *     - GPRegisterBit0set                     XM_IS_INP_ASS
- *
- * Returns:
- *     nothing
- */
-void SkXmIrq(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_EVPARA       Para;
-       SK_U16          IStatus;        /* Interrupt status read from the XMAC */
-       SK_U16          IStatus2;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       XM_IN16(IoC, Port, XM_ISRC, &IStatus);
-
-       /* LinkPartner Auto-negable? */
-       if (pPrt->PhyType == SK_PHY_XMAC) {
-               SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus);
-       }
-       else {
-               /* mask bits that are not used with ext. PHY */
-               IStatus &= ~(XM_IS_LNK_AE | XM_IS_LIPA_RC |
-                       XM_IS_RX_PAGE | XM_IS_TX_PAGE |
-                       XM_IS_AND | XM_IS_INP_ASS);
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-               ("XmacIrq Port %d Isr 0x%04x\n", Port, IStatus));
-
-       if (!pPrt->PHWLinkUp) {
-               /* Spurious XMAC interrupt */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                       ("SkXmIrq: spurious interrupt on Port %d\n", Port));
-               return;
-       }
-
-       if ((IStatus & XM_IS_INP_ASS) != 0) {
-               /* Reread ISR Register if link is not in sync */
-               XM_IN16(IoC, Port, XM_ISRC, &IStatus2);
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                       ("SkXmIrq: Link async. Double check Port %d 0x%04x 0x%04x\n",
-                        Port, IStatus, IStatus2));
-               IStatus &= ~XM_IS_INP_ASS;
-               IStatus |= IStatus2;
-       }
-
-       if ((IStatus & XM_IS_LNK_AE) != 0) {
-               /* not used, GP0 is used instead */
-       }
-
-       if ((IStatus & XM_IS_TX_ABORT) != 0) {
-               /* not used */
-       }
-
-       if ((IStatus & XM_IS_FRC_INT) != 0) {
-               /* not used, use ASIC IRQ instead if needed */
-       }
-
-       if ((IStatus & (XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE)) != 0) {
-               SkHWLinkDown(pAC, IoC, Port);
-
-               /* Signal to RLMT */
-               Para.Para32[0] = (SK_U32)Port;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-
-               /* Start workaround Errata #2 timer */
-               SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
-                       SKGE_HWAC, SK_HWEV_WATIM, Para);
-       }
-
-       if ((IStatus & XM_IS_RX_PAGE) != 0) {
-               /* not used */
-       }
-
-       if ((IStatus & XM_IS_TX_PAGE) != 0) {
-               /* not used */
-       }
-
-       if ((IStatus & XM_IS_AND) != 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                       ("SkXmIrq: AND on link that is up Port %d\n", Port));
-       }
-
-       if ((IStatus & XM_IS_TSC_OV) != 0) {
-               /* not used */
-       }
-
-       /* Combined Tx & Rx Counter Overflow SIRQ Event */
-       if ((IStatus & (XM_IS_RXC_OV | XM_IS_TXC_OV)) != 0) {
-               Para.Para32[0] = (SK_U32)Port;
-               Para.Para32[1] = (SK_U32)IStatus;
-               SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
-       }
-
-       if ((IStatus & XM_IS_RXF_OV) != 0) {
-               /* normal situation -> no effect */
-#ifdef DEBUG
-               pPrt->PRxOverCnt++;
-#endif /* DEBUG */
-       }
-
-       if ((IStatus & XM_IS_TXF_UR) != 0) {
-               /* may NOT happen -> error log */
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG);
-       }
-
-       if ((IStatus & XM_IS_TX_COMP) != 0) {
-               /* not served here */
-       }
-
-       if ((IStatus & XM_IS_RX_COMP) != 0) {
-               /* not served here */
-       }
-}      /* SkXmIrq */
-
-
-/******************************************************************************
- *
- *     SkGmIrq() - Interrupt Service Routine
- *
- * Description:        services an Interrupt Request of the GMAC
- *
- * Note:
- *
- * Returns:
- *     nothing
- */
-void SkGmIrq(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_EVPARA       Para;
-       SK_U8           IStatus;        /* Interrupt status */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       SK_IN8(IoC, GMAC_IRQ_SRC, &IStatus);
-
-       /* LinkPartner Auto-negable? */
-       SkMacAutoNegLipaPhy(pAC, IoC, Port, IStatus);
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-               ("GmacIrq Port %d Isr 0x%04x\n", Port, IStatus));
-
-       /* Combined Tx & Rx Counter Overflow SIRQ Event */
-       if (IStatus & (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV)) {
-               /* these IRQs will be cleared by reading GMACs register */
-               Para.Para32[0] = (SK_U32)Port;
-               Para.Para32[1] = (SK_U32)IStatus;
-               SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
-       }
-
-       if (IStatus & GM_IS_RX_FF_OR) {
-               /* clear GMAC Rx FIFO Overrun IRQ */
-               SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_CLI_RX_FO);
-#ifdef DEBUG
-               pPrt->PRxOverCnt++;
-#endif /* DEBUG */
-       }
-
-       if (IStatus & GM_IS_TX_FF_UR) {
-               /* clear GMAC Tx FIFO Underrun IRQ */
-               SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_CLI_TX_FU);
-               /* may NOT happen -> error log */
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG);
-       }
-
-       if (IStatus & GM_IS_TX_COMPL) {
-               /* not served here */
-       }
-
-       if (IStatus & GM_IS_RX_COMPL) {
-               /* not served here */
-       }
-}      /* SkGmIrq */
-
-/******************************************************************************
- *
- *     SkMacIrq() - Interrupt Service Routine for MAC
- *
- * Description:        calls the Interrupt Service Routine dep. on board type
- *
- * Returns:
- *     nothing
- */
-void SkMacIrq(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-
-       if (pAC->GIni.GIGenesis) {
-               /* IRQ from XMAC */
-               SkXmIrq(pAC, IoC, Port);
-       }
-       else {
-               /* IRQ from GMAC */
-               SkGmIrq(pAC, IoC, Port);
-       }
-}      /* SkMacIrq */
-
-#endif /* !SK_DIAG */
-
-/******************************************************************************
- *
- *     SkXmUpdateStats() - Force the XMAC to output the current statistic
- *
- * Description:
- *     The XMAC holds its statistic internally. To obtain the current
- *     values a command must be sent so that the statistic data will
- *     be written to a predefined memory area on the adapter.
- *
- * Returns:
- *     0:  success
- *     1:  something went wrong
- */
-int SkXmUpdateStats(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-unsigned int Port)     /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          StatReg;
-       int                     WaitIndex;
-
-       pPrt = &pAC->GIni.GP[Port];
-       WaitIndex = 0;
-
-       /* Send an update command to XMAC specified */
-       XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC);
-
-       /*
-        * It is an auto-clearing register. If the command bits
-        * went to zero again, the statistics are transferred.
-        * Normally the command should be executed immediately.
-        * But just to be sure we execute a loop.
-        */
-       do {
-
-               XM_IN16(IoC, Port, XM_STAT_CMD, &StatReg);
-
-               if (++WaitIndex > 10) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E021, SKERR_HWI_E021MSG);
-
-                       return(1);
-               }
-       } while ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) != 0);
-
-       return(0);
-}      /* SkXmUpdateStats */
-
-/******************************************************************************
- *
- *     SkGmUpdateStats() - Force the GMAC to output the current statistic
- *
- * Description:
- *     Empty function for GMAC. Statistic data is accessible in direct way.
- *
- * Returns:
- *     0:  success
- *     1:  something went wrong
- */
-int SkGmUpdateStats(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-unsigned int Port)     /* Port Index (MAC_1 + n) */
-{
-       return(0);
-}
-
-/******************************************************************************
- *
- *     SkXmMacStatistic() - Get XMAC counter value
- *
- * Description:
- *     Gets the 32bit counter value. Except for the octet counters
- *     the lower 32bit are counted in hardware and the upper 32bit
- *     must be counted in software by monitoring counter overflow interrupts.
- *
- * Returns:
- *     0:  success
- *     1:  something went wrong
- */
-int SkXmMacStatistic(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-unsigned int Port,     /* Port Index (MAC_1 + n) */
-SK_U16 StatAddr,       /* MIB counter base address */
-SK_U32 *pVal)          /* ptr to return statistic value */
-{
-       if ((StatAddr < XM_TXF_OK) || (StatAddr > XM_RXF_MAX_SZ)) {
-
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
-
-               return(1);
-       }
-
-       XM_IN32(IoC, Port, StatAddr, pVal);
-
-       return(0);
-}      /* SkXmMacStatistic */
-
-/******************************************************************************
- *
- *     SkGmMacStatistic() - Get GMAC counter value
- *
- * Description:
- *     Gets the 32bit counter value. Except for the octet counters
- *     the lower 32bit are counted in hardware and the upper 32bit
- *     must be counted in software by monitoring counter overflow interrupts.
- *
- * Returns:
- *     0:  success
- *     1:  something went wrong
- */
-int SkGmMacStatistic(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-unsigned int Port,     /* Port Index (MAC_1 + n) */
-SK_U16 StatAddr,       /* MIB counter base address */
-SK_U32 *pVal)          /* ptr to return statistic value */
-{
-
-       if ((StatAddr < GM_RXF_UC_OK) || (StatAddr > GM_TXE_FIFO_UR)) {
-
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("SkGmMacStat: wrong MIB counter 0x%04X\n", StatAddr));
-               return(1);
-       }
-
-       GM_IN32(IoC, Port, StatAddr, pVal);
-
-       return(0);
-}      /* SkGmMacStatistic */
-
-/******************************************************************************
- *
- *     SkXmResetCounter() - Clear MAC statistic counter
- *
- * Description:
- *     Force the XMAC to clear its statistic counter.
- *
- * Returns:
- *     0:  success
- *     1:  something went wrong
- */
-int SkXmResetCounter(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-unsigned int Port)     /* Port Index (MAC_1 + n) */
-{
-       XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
-       /* Clear two times according to Errata #3 */
-       XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
-
-       return(0);
-}      /* SkXmResetCounter */
-
-/******************************************************************************
- *
- *     SkGmResetCounter() - Clear MAC statistic counter
- *
- * Description:
- *     Force GMAC to clear its statistic counter.
- *
- * Returns:
- *     0:  success
- *     1:  something went wrong
- */
-int SkGmResetCounter(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-unsigned int Port)     /* Port Index (MAC_1 + n) */
-{
-       SK_U16  Reg;    /* Phy Address Register */
-       SK_U16  Word;
-       int             i;
-
-       GM_IN16(IoC, Port, GM_PHY_ADDR, &Reg);
-
-#ifndef VCPU
-       /* set MIB Clear Counter Mode */
-       GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg | GM_PAR_MIB_CLR);
-
-       /* read all MIB Counters with Clear Mode set */
-       for (i = 0; i < GM_MIB_CNT_SIZE; i++) {
-               /* the reset is performed only when the lower 16 bits are read */
-               GM_IN16(IoC, Port, GM_MIB_CNT_BASE + 8*i, &Word);
-       }
-
-       /* clear MIB Clear Counter Mode */
-       GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg);
-#endif /* !VCPU */
-
-       return(0);
-}      /* SkGmResetCounter */
-
-/******************************************************************************
- *
- *     SkXmOverflowStatus() - Gets the status of counter overflow interrupt
- *
- * Description:
- *     Checks the source causing an counter overflow interrupt. On success the
- *     resulting counter overflow status is written to <pStatus>, whereas the
- *     upper dword stores the XMAC ReceiveCounterEvent register and the lower
- *     dword the XMAC TransmitCounterEvent register.
- *
- * Note:
- *     For XMAC the interrupt source is a self-clearing register, so the source
- *     must be checked only once. SIRQ module does another check to be sure
- *     that no interrupt get lost during process time.
- *
- * Returns:
- *     0:  success
- *     1:  something went wrong
- */
-int SkXmOverflowStatus(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-unsigned int Port,     /* Port Index (MAC_1 + n) */
-SK_U16  IStatus,       /* Interupt Status from MAC */
-SK_U64 *pStatus)       /* ptr for return overflow status value */
-{
-       SK_U64  Status; /* Overflow status */
-       SK_U32  RegVal;
-
-       Status = 0;
-
-       if ((IStatus & XM_IS_RXC_OV) != 0) {
-
-               XM_IN32(IoC, Port, XM_RX_CNT_EV, &RegVal);
-               Status |= (SK_U64)RegVal << 32;
-       }
-
-       if ((IStatus & XM_IS_TXC_OV) != 0) {
-
-               XM_IN32(IoC, Port, XM_TX_CNT_EV, &RegVal);
-               Status |= (SK_U64)RegVal;
-       }
-
-       *pStatus = Status;
-
-       return(0);
-}      /* SkXmOverflowStatus */
-
-
-/******************************************************************************
- *
- *     SkGmOverflowStatus() - Gets the status of counter overflow interrupt
- *
- * Description:
- *     Checks the source causing an counter overflow interrupt. On success the
- *     resulting counter overflow status is written to <pStatus>, whereas the
- *     the following bit coding is used:
- *     63:56 - unused
- *     55:48 - TxRx interrupt register bit7:0
- *     32:47 - Rx interrupt register
- *     31:24 - unused
- *     23:16 - TxRx interrupt register bit15:8
- *     15:0  - Tx interrupt register
- *
- * Returns:
- *     0:  success
- *     1:  something went wrong
- */
-int SkGmOverflowStatus(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-unsigned int Port,     /* Port Index (MAC_1 + n) */
-SK_U16  IStatus,       /* Interupt Status from MAC */
-SK_U64 *pStatus)       /* ptr for return overflow status value */
-{
-       SK_U64  Status;         /* Overflow status */
-       SK_U16  RegVal;
-
-       Status = 0;
-
-       if ((IStatus & GM_IS_RX_CO_OV) != 0) {
-               /* this register is self-clearing after read */
-               GM_IN16(IoC, Port, GM_RX_IRQ_SRC, &RegVal);
-               Status |= (SK_U64)RegVal << 32;
-       }
-
-       if ((IStatus & GM_IS_TX_CO_OV) != 0) {
-               /* this register is self-clearing after read */
-               GM_IN16(IoC, Port, GM_TX_IRQ_SRC, &RegVal);
-               Status |= (SK_U64)RegVal;
-       }
-
-       /* this register is self-clearing after read */
-       GM_IN16(IoC, Port, GM_TR_IRQ_SRC, &RegVal);
-       /* Rx overflow interrupt register bits (LoByte)*/
-       Status |= (SK_U64)((SK_U8)RegVal) << 48;
-       /* Tx overflow interrupt register bits (HiByte)*/
-       Status |= (SK_U64)(RegVal >> 8) << 16;
-
-       *pStatus = Status;
-
-       return(0);
-}      /* SkGmOverflowStatus */
-
-/******************************************************************************
- *
- *     SkGmCableDiagStatus() - Starts / Gets status of cable diagnostic test
- *
- * Description:
- *  starts the cable diagnostic test if 'StartTest' is true
- *  gets the results if 'StartTest' is true
- *
- * NOTE:       this test is meaningful only when link is down
- *
- * Returns:
- *     0:  success
- *     1:      no YUKON copper
- *     2:      test in progress
- */
-int SkGmCableDiagStatus(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_BOOL        StartTest)      /* flag for start / get result */
-{
-       int             i;
-       SK_U16  RegVal;
-       SK_GEPORT       *pPrt;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
-
-               return(1);
-       }
-
-       if (StartTest) {
-               /* only start the cable test */
-               if ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4) {
-                       /* apply TDR workaround from Marvell */
-                       SkGmPhyWrite(pAC, IoC, Port, 29, 0x001e);
-
-                       SkGmPhyWrite(pAC, IoC, Port, 30, 0xcc00);
-                       SkGmPhyWrite(pAC, IoC, Port, 30, 0xc800);
-                       SkGmPhyWrite(pAC, IoC, Port, 30, 0xc400);
-                       SkGmPhyWrite(pAC, IoC, Port, 30, 0xc000);
-                       SkGmPhyWrite(pAC, IoC, Port, 30, 0xc100);
-               }
-
-               /* set address to 0 for MDI[0] */
-               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0);
-
-               /* Read Cable Diagnostic Reg */
-               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
-
-               /* start Cable Diagnostic Test */
-               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CABLE_DIAG,
-                       (SK_U16)(RegVal | PHY_M_CABD_ENA_TEST));
-
-               return(0);
-       }
-
-       /* Read Cable Diagnostic Reg */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("PHY Cable Diag.=0x%04X\n", RegVal));
-
-       if ((RegVal & PHY_M_CABD_ENA_TEST) != 0) {
-               /* test is running */
-               return(2);
-       }
-
-       /* get the test results */
-       for (i = 0; i < 4; i++)  {
-               /* set address to i for MDI[i] */
-               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i);
-
-               /* get Cable Diagnostic values */
-               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
-
-               pPrt->PMdiPairLen[i] = (SK_U8)(RegVal & PHY_M_CABD_DIST_MSK);
-
-               pPrt->PMdiPairSts[i] = (SK_U8)((RegVal & PHY_M_CABD_STAT_MSK) >> 13);
-       }
-
-       return(0);
-}      /* SkGmCableDiagStatus */
-
-#endif /* CONFIG_SK98 */
-
-/* End of file */
diff --git a/drivers/sk98lin/u-boot_compat.h b/drivers/sk98lin/u-boot_compat.h
deleted file mode 100644 (file)
index 1e385f8..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * (C) Copyright 2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#ifndef _UBOOT_COMPAT_H__
-#define _UBOOT_COMPAT_H__
-
-
-#include <pci.h>
-#include <pci_ids.h>
-#include <common.h>
-#include <malloc.h>
-#include <net.h>
-
-#define        __initdata
-#define __init
-#define __exit
-
-#define netif_stop_queue(x)
-#define netif_wake_queue(x)
-#define netif_running(x)               0
-#define unregister_netdev(x)
-#define remove_proc_entry(x,y)
-
-#define dev_addr                       enetaddr
-
-#define        spin_lock_irqsave(x,y) y = 0;
-#define spin_lock_init(x)
-#define spin_lock(x)
-#define spin_unlock_irqrestore(x,y)
-#define spin_unlock(x)
-
-
-#define ENODEV                         1
-#define EAGAIN                         2
-#define EBUSY                          3
-
-#define HZ                             CFG_HZ
-
-
-#define printk                         printf
-#define KERN_ERR
-#define KERN_WARNING
-#define KERN_INFO
-
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-
-
-#define kmalloc(x,y)                   malloc(x)
-#define kfree(x)                       free(x)
-#define GFP_ATOMIC                     0
-
-#define pci_alloc_consistent(x,y,z)    (void *)(*(dma_addr_t *)(z) = (dma_addr_t)malloc(y))
-#define pci_free_consistent(x,y,z,d)   free(z)
-#define pci_dma_sync_single(x,y,z,d)
-#define pci_unmap_page(x,y,z,d)
-#define pci_unmap_single(x,y,z,d)
-#define pci_present()                  1
-
-struct sk_buff
-{
-       u8 * data;
-       u32 len;
-       u8 * data_unaligned;
-};
-
-struct sk_buff * alloc_skb(u32 size, int dummy);
-void dev_kfree_skb_any(struct sk_buff *skb);
-void skb_reserve(struct sk_buff *skb, unsigned int len);
-void skb_put(struct sk_buff *skb, unsigned int len);
-
-#define dev_kfree_skb                          dev_kfree_skb_any
-#define dev_kfree_skb_irq                      dev_kfree_skb_any
-
-#define eth_copy_and_sum(dest,src,len,base)    memcpy(dest->data,src,len);
-
-
-#endif /* _UBOOT_COMPAT_H__ */
diff --git a/drivers/sk98lin/uboot_drv.c b/drivers/sk98lin/uboot_drv.c
deleted file mode 100644 (file)
index d02cd1b..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Driver for SysKonnect Gigabit Ethernet Server Adapters.
- *
- * (C) Copyright 2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-
-#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
-       defined(CONFIG_SK98)
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-#include "u-boot_compat.h"
-
-
-#define SKGE_MAX_CARDS 2
-
-
-extern int skge_probe(struct eth_device **);
-extern void SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs);
-extern void SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs);
-extern int SkGeOpen(struct eth_device *);
-extern int SkGeClose(struct eth_device *);
-extern int SkGeXmit(struct sk_buff *skb, struct eth_device *dev);
-extern void ReceiveIrq(SK_AC *pAC, RX_PORT *pRxPort, SK_BOOL SlowPathLock);
-
-static int skge_init(struct eth_device *dev, bd_t * bis);
-static int skge_send(struct eth_device *dev, volatile void *packet, int length);
-static int skge_recv(struct eth_device *dev);
-static void skge_halt(struct eth_device *dev);
-
-int skge_initialize(bd_t * bis)
-{
-       int numdev, i;
-       struct eth_device *dev[SKGE_MAX_CARDS];
-
-       numdev = skge_probe(&dev[0]);
-
-       if (numdev > SKGE_MAX_CARDS)
-       {
-               printf("ERROR: numdev > SKGE_MAX_CARDS\n");
-       }
-
-       for (i = 0; i < numdev; i++)
-       {
-               sprintf (dev[i]->name, "SK98#%d", i);
-
-               dev[i]->init = skge_init;
-               dev[i]->halt = skge_halt;
-               dev[i]->send = skge_send;
-               dev[i]->recv = skge_recv;
-
-               eth_register(dev[i]);
-       }
-
-       return numdev;
-}
-
-
-static int skge_init(struct eth_device *dev, bd_t * bis)
-{
-       int ret;
-       SK_AC * pAC = ((DEV_NET*)dev->priv)->pAC;
-       int i;
-
-       ret = SkGeOpen(dev);
-
-       while (pAC->Rlmt.Port[0].PortState != SK_RLMT_PS_GOING_UP)
-       {
-               SkGeIsrOnePort (0, pAC->dev[0], 0);
-       }
-
-       for (i = 0; i < 100; i ++)
-       {
-               udelay(1000);
-       }
-
-       return ret;
-}
-
-
-static void skge_halt(struct eth_device *dev)
-{
-       SkGeClose(dev);
-}
-
-
-static int skge_send(struct eth_device *dev, volatile void *packet,
-                                                 int length)
-{
-       int ret = -1;
-       struct sk_buff * skb = alloc_skb(length, 0);
-
-       if (! skb)
-       {
-               printf("skge_send: failed to alloc skb\n");
-               goto Done;
-       }
-
-       memcpy(skb->data, (void*)packet, length);
-       ret = SkGeXmit(skb, dev);
-
-Done:
-       return ret;
-}
-
-
-static int skge_recv(struct eth_device *dev)
-{
-       DEV_NET         *pNet;
-       SK_AC           *pAC;
-       int             FromPort = 0;
-
-       pNet = (DEV_NET*) dev->priv;
-       pAC = pNet->pAC;
-
-       ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE);
-
-       return 0;
-}
-
-
-#endif /* CONFIG_SK98 */
diff --git a/drivers/sk98lin/uboot_skb.c b/drivers/sk98lin/uboot_skb.c
deleted file mode 100644 (file)
index 3a487a8..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Definitions for the 'struct sk_buff' memory handlers in U-Boot.
- *
- * (C) Copyright 2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <config.h>
-
-#ifdef CONFIG_SK98
-
-#include <common.h>
-#include "u-boot_compat.h"
-
-#define MAX_SKB                50
-
-static struct sk_buff *sk_table[MAX_SKB];
-
-
-struct sk_buff * alloc_skb(u32 size, int dummy)
-{
-       int i;
-       struct sk_buff * ret = NULL;
-
-       for (i = 0; i < MAX_SKB; i++)
-       {
-               if (sk_table[i])
-               {
-                               /* Already allocated.
-                                */
-                       continue;
-               }
-
-               sk_table[i] = malloc(sizeof(struct sk_buff));
-               if (! sk_table[i])
-               {
-                       printf("alloc_skb: malloc failed\n");
-                       break;
-               }
-
-               memset(sk_table[i], 0, sizeof(struct sk_buff));
-               sk_table[i]->data = sk_table[i]->data_unaligned =
-                                                           malloc(size + 16);
-               if (! sk_table[i]->data)
-               {
-                       printf("alloc_skb: malloc failed\n");
-                       free(sk_table[i]);
-                       sk_table[i] = NULL;
-                       break;
-               }
-
-               sk_table[i]->data += 16 - ((u32)sk_table[i]->data & 15);
-               sk_table[i]->len = size;
-
-               break;
-       }
-
-       if (i < MAX_SKB)
-       {
-               ret = sk_table[i];
-       }
-
-       if (! ret)
-       {
-               printf("Unable to allocate skb!\n");
-       }
-
-       return ret;
-}
-
-void dev_kfree_skb_any(struct sk_buff *skb)
-{
-       int i;
-
-       for (i = 0; i < MAX_SKB; i++)
-       {
-               if (sk_table[i] != skb)
-               {
-                       continue;
-               }
-
-               free(skb->data_unaligned);
-               free(skb);
-               sk_table[i] = NULL;
-               break;
-       }
-
-       if (i == MAX_SKB)
-       {
-               printf("SKB allocation error!\n");
-       }
-}
-
-void skb_reserve(struct sk_buff *skb, unsigned int len)
-{
-       skb->data+=len;
-}
-
-void skb_put(struct sk_buff *skb, unsigned int len)
-{
-       skb->len+=len;
-}
-
-#endif /* CONFIG_SK98 */
diff --git a/drivers/sl811.h b/drivers/sl811.h
deleted file mode 100644 (file)
index c1f9f01..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-#ifndef __UBOOT_SL811_H
-#define __UBOOT_SL811_H
-
-#undef SL811_DEBUG
-
-#ifdef SL811_DEBUG
-       #define PDEBUG(level, fmt, args...) \
-               if (debug >= (level)) printf("[%s:%d] " fmt, \
-               __PRETTY_FUNCTION__, __LINE__ , ## args)
-#else
-       #define PDEBUG(level, fmt, args...) do {} while(0)
-#endif
-
-/* Sl811 host control register */
-#define        SL811_CTRL_A            0x00
-#define        SL811_ADDR_A            0x01
-#define        SL811_LEN_A             0x02
-#define        SL811_STS_A             0x03    /* read */
-#define        SL811_PIDEP_A           0x03    /* write */
-#define        SL811_CNT_A             0x04    /* read */
-#define        SL811_DEV_A             0x04    /* write */
-#define        SL811_CTRL1             0x05
-#define        SL811_INTR              0x06
-#define        SL811_CTRL_B            0x08
-#define        SL811_ADDR_B            0x09
-#define        SL811_LEN_B             0x0A
-#define        SL811_STS_B             0x0B    /* read */
-#define        SL811_PIDEP_B           0x0B    /* write */
-#define        SL811_CNT_B             0x0C    /* read */
-#define        SL811_DEV_B             0x0C    /* write */
-#define        SL811_INTRSTS           0x0D    /* write clears bitwise */
-#define        SL811_HWREV             0x0E    /* read */
-#define        SL811_SOFLOW            0x0E    /* write */
-#define        SL811_SOFCNTDIV         0x0F    /* read */
-#define        SL811_CTRL2             0x0F    /* write */
-
-/* USB control register bits (addr 0x00 and addr 0x08) */
-#define        SL811_USB_CTRL_ARM      0x01
-#define        SL811_USB_CTRL_ENABLE   0x02
-#define        SL811_USB_CTRL_DIR_OUT  0x04
-#define        SL811_USB_CTRL_ISO      0x10
-#define        SL811_USB_CTRL_SOF      0x20
-#define        SL811_USB_CTRL_TOGGLE_1 0x40
-#define        SL811_USB_CTRL_PREAMBLE 0x80
-
-/* USB status register bits (addr 0x03 and addr 0x0B) */
-#define        SL811_USB_STS_ACK       0x01
-#define        SL811_USB_STS_ERROR     0x02
-#define        SL811_USB_STS_TIMEOUT   0x04
-#define        SL811_USB_STS_TOGGLE_1  0x08
-#define        SL811_USB_STS_SETUP     0x10
-#define        SL811_USB_STS_OVERFLOW  0x20
-#define        SL811_USB_STS_NAK       0x40
-#define        SL811_USB_STS_STALL     0x80
-
-/* Control register 1 bits (addr 0x05) */
-#define        SL811_CTRL1_SOF         0x01
-#define        SL811_CTRL1_RESET       0x08
-#define        SL811_CTRL1_JKSTATE     0x10
-#define        SL811_CTRL1_SPEED_LOW   0x20
-#define        SL811_CTRL1_SUSPEND     0x40
-
-/* Interrut enable (addr 0x06) and interrupt status register bits (addr 0x0D) */
-#define        SL811_INTR_DONE_A       0x01
-#define        SL811_INTR_DONE_B       0x02
-#define        SL811_INTR_SOF          0x10
-#define        SL811_INTR_INSRMV       0x20
-#define        SL811_INTR_DETECT       0x40
-#define        SL811_INTR_NOTPRESENT   0x40
-#define        SL811_INTR_SPEED_FULL   0x80    /* only in status reg */
-
-/* HW rev and SOF lo register bits (addr 0x0E) */
-#define        SL811_HWR_HWREV         0xF0
-
-/* SOF counter and control reg 2 (addr 0x0F) */
-#define        SL811_CTL2_SOFHI        0x3F
-#define        SL811_CTL2_DSWAP        0x40
-#define        SL811_CTL2_HOST         0x80
-
-/* Set up for 1-ms SOF time. */
-#define SL811_12M_LOW          0xE0
-#define SL811_12M_HI           0x2E
-
-#define SL811_DATA_START       0x10
-#define SL811_DATA_LIMIT       240
-
-/* Requests: bRequest << 8 | bmRequestType */
-#define RH_GET_STATUS           0x0080
-#define RH_CLEAR_FEATURE        0x0100
-#define RH_SET_FEATURE          0x0300
-#define RH_SET_ADDRESS         0x0500
-#define RH_GET_DESCRIPTOR      0x0680
-#define RH_SET_DESCRIPTOR       0x0700
-#define RH_GET_CONFIGURATION   0x0880
-#define RH_SET_CONFIGURATION   0x0900
-#define RH_GET_STATE            0x0280
-#define RH_GET_INTERFACE        0x0A80
-#define RH_SET_INTERFACE        0x0B00
-#define RH_SYNC_FRAME           0x0C80
-
-
-#define PIDEP(pid, ep) (((pid) & 0x0f) << 4 | (ep))
-
-#endif /* __UBOOT_SL811_H */
diff --git a/drivers/sl811_usb.c b/drivers/sl811_usb.c
deleted file mode 100644 (file)
index b0cdf0b..0000000
+++ /dev/null
@@ -1,737 +0,0 @@
-/*
- * (C) Copyright 2004
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * This code is based on linux driver for sl811hs chip, source at
- * drivers/usb/host/sl811.c:
- *
- * SL811 Host Controller Interface driver for USB.
- *
- * Copyright (c) 2003/06, Courage Co., Ltd.
- *
- * Based on:
- *     1.uhci.c by Linus Torvalds, Johannes Erdfelt, Randy Dunlap,
- *       Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber,
- *       Adam Richter, Gregory P. Smith;
- *     2.Original SL811 driver (hc_sl811.o) by Pei Liu <pbl@cypress.com>
- *     3.Rewrited as sl811.o by Yin Aihua <yinah:couragetech.com.cn>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#ifdef CONFIG_USB_SL811HS
-#include <mpc8xx.h>
-#include <usb.h>
-#include "sl811.h"
-
-#include "../board/kup/common/kup.h"
-
-#ifdef __PPC__
-# define EIEIO         __asm__ volatile ("eieio")
-#else
-# define EIEIO         /* nothing */
-#endif
-
-#define         SL811_ADR (0x50000000)
-#define         SL811_DAT (0x50000001)
-
-#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);})
-
-#ifdef SL811_DEBUG
-static int debug = 9;
-#endif
-
-static int root_hub_devnum = 0;
-static struct usb_port_status rh_status = { 0 };/* root hub port status */
-
-static int sl811_rh_submit_urb(struct usb_device *usb_dev, unsigned long pipe,
-                              void *data, int buf_len, struct devrequest *cmd);
-
-static void sl811_write (__u8 index, __u8 data)
-{
-       *(volatile unsigned char *) (SL811_ADR) = index;
-       EIEIO;
-       *(volatile unsigned char *) (SL811_DAT) = data;
-       EIEIO;
-}
-
-static __u8 sl811_read (__u8 index)
-{
-       __u8 data;
-
-       *(volatile unsigned char *) (SL811_ADR) = index;
-       EIEIO;
-       data = *(volatile unsigned char *) (SL811_DAT);
-       EIEIO;
-       return (data);
-}
-
-/*
- * Read consecutive bytes of data from the SL811H/SL11H buffer
- */
-static void inline sl811_read_buf(__u8 offset, __u8 *buf, __u8 size)
-{
-       *(volatile unsigned char *) (SL811_ADR) = offset;
-       EIEIO;
-       while (size--) {
-               *buf++ = *(volatile unsigned char *) (SL811_DAT);
-               EIEIO;
-       }
-}
-
-/*
- * Write consecutive bytes of data to the SL811H/SL11H buffer
- */
-static void inline sl811_write_buf(__u8 offset, __u8 *buf, __u8 size)
-{
-       *(volatile unsigned char *) (SL811_ADR) = offset;
-       EIEIO;
-       while (size--) {
-               *(volatile unsigned char *) (SL811_DAT) = *buf++;
-               EIEIO;
-       }
-}
-
-int usb_init_kup4x (void)
-{
-       volatile immap_t *immap = (immap_t *) CFG_IMMR;
-       volatile memctl8xx_t *memctl = &immap->im_memctl;
-       int i;
-       unsigned char tmp;
-
-       memctl = &immap->im_memctl;
-       memctl->memc_or7 = 0xFFFF8726;
-       memctl->memc_br7 = 0x50000401;  /* start at 0x50000000 */
-       /* BP 14 low = USB ON */
-       immap->im_cpm.cp_pbdat &= ~(BP_USB_VCC);
-       /* PB 14 nomal port */
-       immap->im_cpm.cp_pbpar &= ~(BP_USB_VCC);
-       /* output */
-       immap->im_cpm.cp_pbdir |= (BP_USB_VCC);
-
-       puts ("USB:   ");
-
-       for (i = 0x10; i < 0xff; i++) {
-               sl811_write(i, i);
-               tmp = (sl811_read(i));
-               if (tmp != i) {
-                       printf ("SL811 compare error index=0x%02x read=0x%02x\n", i, tmp);
-                       return (-1);
-               }
-       }
-       printf ("SL811 ready\n");
-       return (0);
-}
-
-/*
- * This function resets SL811HS controller and detects the speed of
- * the connecting device
- *
- * Return: 0 = no device attached; 1 = USB device attached
- */
-static int sl811_hc_reset(void)
-{
-       int status ;
-
-       sl811_write(SL811_CTRL2, SL811_CTL2_HOST | SL811_12M_HI);
-       sl811_write(SL811_CTRL1, SL811_CTRL1_RESET);
-
-       mdelay(20);
-
-       /* Disable hardware SOF generation, clear all irq status. */
-       sl811_write(SL811_CTRL1, 0);
-       mdelay(2);
-       sl811_write(SL811_INTRSTS, 0xff);
-       status = sl811_read(SL811_INTRSTS);
-
-       if (status & SL811_INTR_NOTPRESENT) {
-               /* Device is not present */
-               PDEBUG(0, "Device not present\n");
-               rh_status.wPortStatus &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE);
-               rh_status.wPortChange |= USB_PORT_STAT_C_CONNECTION;
-               sl811_write(SL811_INTR, SL811_INTR_INSRMV);
-               return 0;
-       }
-
-       /* Send SOF to address 0, endpoint 0. */
-       sl811_write(SL811_LEN_B, 0);
-       sl811_write(SL811_PIDEP_B, PIDEP(USB_PID_SOF, 0));
-       sl811_write(SL811_DEV_B, 0x00);
-       sl811_write(SL811_SOFLOW, SL811_12M_LOW);
-
-       if (status & SL811_INTR_SPEED_FULL) {
-               /* full speed device connect directly to root hub */
-               PDEBUG (0, "Full speed Device attached\n");
-
-               sl811_write(SL811_CTRL1, SL811_CTRL1_RESET);
-               mdelay(20);
-               sl811_write(SL811_CTRL2, SL811_CTL2_HOST | SL811_12M_HI);
-               sl811_write(SL811_CTRL1, SL811_CTRL1_SOF);
-
-               /* start the SOF or EOP */
-               sl811_write(SL811_CTRL_B, SL811_USB_CTRL_ARM);
-               rh_status.wPortStatus |= USB_PORT_STAT_CONNECTION;
-               rh_status.wPortStatus &= ~USB_PORT_STAT_LOW_SPEED;
-               mdelay(2);
-               sl811_write(SL811_INTRSTS, 0xff);
-       } else {
-               /* slow speed device connect directly to root-hub */
-               PDEBUG(0, "Low speed Device attached\n");
-
-               sl811_write(SL811_CTRL1, SL811_CTRL1_RESET);
-               mdelay(20);
-               sl811_write(SL811_CTRL2, SL811_CTL2_HOST | SL811_CTL2_DSWAP | SL811_12M_HI);
-               sl811_write(SL811_CTRL1, SL811_CTRL1_SPEED_LOW | SL811_CTRL1_SOF);
-
-               /* start the SOF or EOP */
-               sl811_write(SL811_CTRL_B, SL811_USB_CTRL_ARM);
-               rh_status.wPortStatus |= USB_PORT_STAT_CONNECTION | USB_PORT_STAT_LOW_SPEED;
-               mdelay(2);
-               sl811_write(SL811_INTRSTS, 0xff);
-       }
-
-       rh_status.wPortChange |= USB_PORT_STAT_C_CONNECTION;
-       sl811_write(SL811_INTR, /*SL811_INTR_INSRMV*/SL811_INTR_DONE_A);
-
-       return 1;
-}
-
-int usb_lowlevel_init(void)
-{
-       root_hub_devnum = 0;
-       sl811_hc_reset();
-       return 0;
-}
-
-int usb_lowlevel_stop(void)
-{
-       sl811_hc_reset();
-       return 0;
-}
-
-static int calc_needed_buswidth(int bytes, int need_preamble)
-{
-       return !need_preamble ? bytes * 8 + 256 : 8 * 8 * bytes + 2048;
-}
-
-static int sl811_send_packet(struct usb_device *dev, unsigned long pipe, __u8 *buffer, int len)
-{
-       __u8 ctrl = SL811_USB_CTRL_ARM | SL811_USB_CTRL_ENABLE;
-       __u16 status = 0;
-       int err = 0, time_start = get_timer(0);
-       int need_preamble = !(rh_status.wPortStatus & USB_PORT_STAT_LOW_SPEED) &&
-               usb_pipeslow(pipe);
-
-       if (len > 239)
-               return -1;
-
-       if (usb_pipeout(pipe))
-               ctrl |= SL811_USB_CTRL_DIR_OUT;
-       if (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)))
-               ctrl |= SL811_USB_CTRL_TOGGLE_1;
-       if (need_preamble)
-               ctrl |= SL811_USB_CTRL_PREAMBLE;
-
-       sl811_write(SL811_INTRSTS, 0xff);
-
-       while (err < 3) {
-               sl811_write(SL811_ADDR_A, 0x10);
-               sl811_write(SL811_LEN_A, len);
-               if (usb_pipeout(pipe) && len)
-                       sl811_write_buf(0x10, buffer, len);
-
-               if (!(rh_status.wPortStatus & USB_PORT_STAT_LOW_SPEED) &&
-                   sl811_read(SL811_SOFCNTDIV)*64 < calc_needed_buswidth(len, need_preamble))
-                       ctrl |= SL811_USB_CTRL_SOF;
-               else
-                       ctrl &= ~SL811_USB_CTRL_SOF;
-
-               sl811_write(SL811_CTRL_A, ctrl);
-               while (!(sl811_read(SL811_INTRSTS) & SL811_INTR_DONE_A)) {
-                       if (5*CFG_HZ < get_timer(time_start)) {
-                               printf("USB transmit timed out\n");
-                               return -USB_ST_CRC_ERR;
-                       }
-               }
-
-               sl811_write(SL811_INTRSTS, 0xff);
-               status = sl811_read(SL811_STS_A);
-
-               if (status & SL811_USB_STS_ACK) {
-                       int remainder = sl811_read(SL811_CNT_A);
-                       if (remainder) {
-                               PDEBUG(0, "usb transfer remainder = %d\n", remainder);
-                               len -= remainder;
-                       }
-                       if (usb_pipein(pipe) && len)
-                               sl811_read_buf(0x10, buffer, len);
-                       return len;
-               }
-
-               if ((status & SL811_USB_STS_NAK) == SL811_USB_STS_NAK)
-                       continue;
-
-               PDEBUG(0, "usb transfer error %#x\n", (int)status);
-               err++;
-       }
-
-       err = 0;
-
-       if (status & SL811_USB_STS_ERROR)
-               err |= USB_ST_BUF_ERR;
-       if (status & SL811_USB_STS_TIMEOUT)
-               err |= USB_ST_CRC_ERR;
-       if (status & SL811_USB_STS_STALL)
-               err |= USB_ST_STALLED;
-
-       return -err;
-}
-
-int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-                   int len)
-{
-       int dir_out = usb_pipeout(pipe);
-       int ep = usb_pipeendpoint(pipe);
-       int max = usb_maxpacket(dev, pipe);
-       int done = 0;
-
-       PDEBUG(7, "dev = %ld pipe = %ld buf = %p size = %d dir_out = %d\n",
-              usb_pipedevice(pipe), usb_pipeendpoint(pipe), buffer, len, dir_out);
-
-       dev->status = 0;
-
-       sl811_write(SL811_DEV_A, usb_pipedevice(pipe));
-       sl811_write(SL811_PIDEP_A, PIDEP(!dir_out ? USB_PID_IN : USB_PID_OUT, ep));
-       while (done < len) {
-               int res = sl811_send_packet(dev, pipe, (__u8*)buffer+done,
-                                           max > len - done ? len - done : max);
-               if (res < 0) {
-                       dev->status = -res;
-                       return res;
-               }
-
-               if (!dir_out && res < max) /* short packet */
-                       break;
-
-               done += res;
-               usb_dotoggle(dev, ep, dir_out);
-       }
-
-       dev->act_len = done;
-
-       return 0;
-}
-
-int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-                      int len,struct devrequest *setup)
-{
-       int done = 0;
-       int devnum = usb_pipedevice(pipe);
-       int ep = usb_pipeendpoint(pipe);
-
-       dev->status = 0;
-
-       if (devnum == root_hub_devnum)
-               return sl811_rh_submit_urb(dev, pipe, buffer, len, setup);
-
-       PDEBUG(7, "dev = %d pipe = %ld buf = %p size = %d rt = %#x req = %#x bus = %i\n",
-              devnum, ep, buffer, len, (int)setup->requesttype,
-              (int)setup->request, sl811_read(SL811_SOFCNTDIV)*64);
-
-       sl811_write(SL811_DEV_A, devnum);
-       sl811_write(SL811_PIDEP_A, PIDEP(USB_PID_SETUP, ep));
-       /* setup phase */
-       usb_settoggle(dev, ep, 1, 0);
-       if (sl811_send_packet(dev, usb_sndctrlpipe(dev, ep),
-                             (__u8*)setup, sizeof(*setup)) == sizeof(*setup)) {
-               int dir_in = usb_pipein(pipe);
-               int max = usb_maxpacket(dev, pipe);
-
-               /* data phase */
-               sl811_write(SL811_PIDEP_A,
-                           PIDEP(dir_in ? USB_PID_IN : USB_PID_OUT, ep));
-               usb_settoggle(dev, ep, usb_pipeout(pipe), 1);
-               while (done < len) {
-                       int res = sl811_send_packet(dev, pipe, (__u8*)buffer+done,
-                                                   max > len - done ? len - done : max);
-                       if (res < 0) {
-                               PDEBUG(0, "status data failed!\n");
-                               dev->status = -res;
-                               return 0;
-                       }
-                       done += res;
-                       usb_dotoggle(dev, ep, usb_pipeout(pipe));
-                       if (dir_in && res < max) /* short packet */
-                               break;
-               }
-
-               /* status phase */
-               sl811_write(SL811_PIDEP_A,
-                           PIDEP(!dir_in ? USB_PID_IN : USB_PID_OUT, ep));
-               usb_settoggle(dev, ep, !usb_pipeout(pipe), 1);
-               if (sl811_send_packet(dev,
-                                     !dir_in ? usb_rcvctrlpipe(dev, ep) :
-                                     usb_sndctrlpipe(dev, ep),
-                                     0, 0) < 0) {
-                       PDEBUG(0, "status phase failed!\n");
-                       dev->status = -1;
-               }
-       } else {
-               PDEBUG(0, "setup phase failed!\n");
-               dev->status = -1;
-       }
-
-       dev->act_len = done;
-
-       return done;
-}
-
-int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-                  int len, int interval)
-{
-       PDEBUG(0, "dev = %p pipe = %#lx buf = %p size = %d int = %d\n", dev, pipe,
-              buffer, len, interval);
-       return -1;
-}
-
-/*
- * SL811 Virtual Root Hub
- */
-
-/* Device descriptor */
-static __u8 sl811_rh_dev_des[] =
-{
-       0x12,       /*  __u8  bLength; */
-       0x01,       /*  __u8  bDescriptorType; Device */
-       0x10,       /*  __u16 bcdUSB; v1.1 */
-       0x01,
-       0x09,       /*  __u8  bDeviceClass; HUB_CLASSCODE */
-       0x00,       /*  __u8  bDeviceSubClass; */
-       0x00,       /*  __u8  bDeviceProtocol; */
-       0x08,       /*  __u8  bMaxPacketSize0; 8 Bytes */
-       0x00,       /*  __u16 idVendor; */
-       0x00,
-       0x00,       /*  __u16 idProduct; */
-       0x00,
-       0x00,       /*  __u16 bcdDevice; */
-       0x00,
-       0x00,       /*  __u8  iManufacturer; */
-       0x02,       /*  __u8  iProduct; */
-       0x01,       /*  __u8  iSerialNumber; */
-       0x01        /*  __u8  bNumConfigurations; */
-};
-
-/* Configuration descriptor */
-static __u8 sl811_rh_config_des[] =
-{
-       0x09,       /*  __u8  bLength; */
-       0x02,       /*  __u8  bDescriptorType; Configuration */
-       0x19,       /*  __u16 wTotalLength; */
-       0x00,
-       0x01,       /*  __u8  bNumInterfaces; */
-       0x01,       /*  __u8  bConfigurationValue; */
-       0x00,       /*  __u8  iConfiguration; */
-       0x40,       /*  __u8  bmAttributes;
-                   Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup,
-                   4..0: resvd */
-       0x00,       /*  __u8  MaxPower; */
-
-       /* interface */
-       0x09,       /*  __u8  if_bLength; */
-       0x04,       /*  __u8  if_bDescriptorType; Interface */
-       0x00,       /*  __u8  if_bInterfaceNumber; */
-       0x00,       /*  __u8  if_bAlternateSetting; */
-       0x01,       /*  __u8  if_bNumEndpoints; */
-       0x09,       /*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
-       0x00,       /*  __u8  if_bInterfaceSubClass; */
-       0x00,       /*  __u8  if_bInterfaceProtocol; */
-       0x00,       /*  __u8  if_iInterface; */
-
-       /* endpoint */
-       0x07,       /*  __u8  ep_bLength; */
-       0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
-       0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
-       0x03,       /*  __u8  ep_bmAttributes; Interrupt */
-       0x08,       /*  __u16 ep_wMaxPacketSize; */
-       0x00,
-       0xff        /*  __u8  ep_bInterval; 255 ms */
-};
-
-/* root hub class descriptor*/
-static __u8 sl811_rh_hub_des[] =
-{
-       0x09,                   /*  __u8  bLength; */
-       0x29,                   /*  __u8  bDescriptorType; Hub-descriptor */
-       0x01,                   /*  __u8  bNbrPorts; */
-       0x00,                   /* __u16  wHubCharacteristics; */
-       0x00,
-       0x50,                   /*  __u8  bPwrOn2pwrGood; 2ms */
-       0x00,                   /*  __u8  bHubContrCurrent; 0 mA */
-       0xfc,                   /*  __u8  DeviceRemovable; *** 7 Ports max *** */
-       0xff                    /*  __u8  PortPwrCtrlMask; *** 7 ports max *** */
-};
-
-/*
- * helper routine for returning string descriptors in UTF-16LE
- * input can actually be ISO-8859-1; ASCII is its 7-bit subset
- */
-static int ascii2utf (char *s, u8 *utf, int utfmax)
-{
-       int retval;
-
-       for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) {
-               *utf++ = *s++;
-               *utf++ = 0;
-       }
-       return retval;
-}
-
-/*
- * root_hub_string is used by each host controller's root hub code,
- * so that they're identified consistently throughout the system.
- */
-static int usb_root_hub_string (int id, int serial, char *type, __u8 *data, int len)
-{
-       char buf [30];
-
-       /* assert (len > (2 * (sizeof (buf) + 1)));
-          assert (strlen (type) <= 8);*/
-
-       /* language ids */
-       if (id == 0) {
-               *data++ = 4; *data++ = 3;       /* 4 bytes data */
-               *data++ = 0; *data++ = 0;       /* some language id */
-               return 4;
-
-       /* serial number */
-       } else if (id == 1) {
-               sprintf (buf, "%#x", serial);
-
-       /* product description */
-       } else if (id == 2) {
-               sprintf (buf, "USB %s Root Hub", type);
-
-       /* id 3 == vendor description */
-
-       /* unsupported IDs --> "stall" */
-       } else
-           return 0;
-
-       ascii2utf (buf, data + 2, len - 2);
-       data [0] = 2 + strlen(buf) * 2;
-       data [1] = 3;
-       return data [0];
-}
-
-/* helper macro */
-#define OK(x)  len = (x); break
-
-/*
- * This function handles all USB request to the the virtual root hub
- */
-static int sl811_rh_submit_urb(struct usb_device *usb_dev, unsigned long pipe,
-                              void *data, int buf_len, struct devrequest *cmd)
-{
-       __u8 data_buf[16];
-       __u8 *bufp = data_buf;
-       int len = 0;
-       int status = 0;
-
-       __u16 bmRType_bReq;
-       __u16 wValue;
-       __u16 wIndex;
-       __u16 wLength;
-
-       if (usb_pipeint(pipe)) {
-               PDEBUG(0, "interrupt transfer unimplemented!\n");
-               return 0;
-       }
-
-       bmRType_bReq  = cmd->requesttype | (cmd->request << 8);
-       wValue        = le16_to_cpu (cmd->value);
-       wIndex        = le16_to_cpu (cmd->index);
-       wLength       = le16_to_cpu (cmd->length);
-
-       PDEBUG(5, "submit rh urb, req = %d(%x) val = %#x index = %#x len=%d\n",
-              bmRType_bReq, bmRType_bReq, wValue, wIndex, wLength);
-
-       /* Request Destination:
-                  without flags: Device,
-                  USB_RECIP_INTERFACE: interface,
-                  USB_RECIP_ENDPOINT: endpoint,
-                  USB_TYPE_CLASS means HUB here,
-                  USB_RECIP_OTHER | USB_TYPE_CLASS  almost ever means HUB_PORT here
-       */
-       switch (bmRType_bReq) {
-       case RH_GET_STATUS:
-               *(__u16 *)bufp = cpu_to_le16(1);
-               OK(2);
-
-       case RH_GET_STATUS | USB_RECIP_INTERFACE:
-               *(__u16 *)bufp = cpu_to_le16(0);
-               OK(2);
-
-       case RH_GET_STATUS | USB_RECIP_ENDPOINT:
-               *(__u16 *)bufp = cpu_to_le16(0);
-               OK(2);
-
-       case RH_GET_STATUS | USB_TYPE_CLASS:
-               *(__u32 *)bufp = cpu_to_le32(0);
-               OK(4);
-
-       case RH_GET_STATUS | USB_RECIP_OTHER | USB_TYPE_CLASS:
-               *(__u32 *)bufp = cpu_to_le32(rh_status.wPortChange<<16 | rh_status.wPortStatus);
-               OK(4);
-
-       case RH_CLEAR_FEATURE | USB_RECIP_ENDPOINT:
-               switch (wValue) {
-               case 1:
-                       OK(0);
-               }
-               break;
-
-       case RH_CLEAR_FEATURE | USB_TYPE_CLASS:
-               switch (wValue) {
-               case C_HUB_LOCAL_POWER:
-                       OK(0);
-
-               case C_HUB_OVER_CURRENT:
-                       OK(0);
-               }
-               break;
-
-       case RH_CLEAR_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS:
-               switch (wValue) {
-               case USB_PORT_FEAT_ENABLE:
-                       rh_status.wPortStatus &= ~USB_PORT_STAT_ENABLE;
-                       OK(0);
-
-               case USB_PORT_FEAT_SUSPEND:
-                       rh_status.wPortStatus &= ~USB_PORT_STAT_SUSPEND;
-                       OK(0);
-
-               case USB_PORT_FEAT_POWER:
-                       rh_status.wPortStatus &= ~USB_PORT_STAT_POWER;
-                       OK(0);
-
-               case USB_PORT_FEAT_C_CONNECTION:
-                       rh_status.wPortChange &= ~USB_PORT_STAT_C_CONNECTION;
-                       OK(0);
-
-               case USB_PORT_FEAT_C_ENABLE:
-                       rh_status.wPortChange &= ~USB_PORT_STAT_C_ENABLE;
-                       OK(0);
-
-               case USB_PORT_FEAT_C_SUSPEND:
-                       rh_status.wPortChange &= ~USB_PORT_STAT_C_SUSPEND;
-                       OK(0);
-
-               case USB_PORT_FEAT_C_OVER_CURRENT:
-                       rh_status.wPortChange &= ~USB_PORT_STAT_C_OVERCURRENT;
-                       OK(0);
-
-               case USB_PORT_FEAT_C_RESET:
-                       rh_status.wPortChange &= ~USB_PORT_STAT_C_RESET;
-                       OK(0);
-               }
-               break;
-
-       case RH_SET_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS:
-               switch (wValue) {
-               case USB_PORT_FEAT_SUSPEND:
-                       rh_status.wPortStatus |= USB_PORT_STAT_SUSPEND;
-                       OK(0);
-
-               case USB_PORT_FEAT_RESET:
-                       rh_status.wPortStatus |= USB_PORT_STAT_RESET;
-                       rh_status.wPortChange = 0;
-                       rh_status.wPortChange |= USB_PORT_STAT_C_RESET;
-                       rh_status.wPortStatus &= ~USB_PORT_STAT_RESET;
-                       rh_status.wPortStatus |= USB_PORT_STAT_ENABLE;
-                       OK(0);
-
-               case USB_PORT_FEAT_POWER:
-                       rh_status.wPortStatus |= USB_PORT_STAT_POWER;
-                       OK(0);
-
-               case USB_PORT_FEAT_ENABLE:
-                       rh_status.wPortStatus |= USB_PORT_STAT_ENABLE;
-                       OK(0);
-               }
-               break;
-
-       case RH_SET_ADDRESS:
-               root_hub_devnum = wValue;
-               OK(0);
-
-       case RH_GET_DESCRIPTOR:
-               switch ((wValue & 0xff00) >> 8) {
-               case USB_DT_DEVICE:
-                       len = sizeof(sl811_rh_dev_des);
-                       bufp = sl811_rh_dev_des;
-                       OK(len);
-
-               case USB_DT_CONFIG:
-                       len = sizeof(sl811_rh_config_des);
-                       bufp = sl811_rh_config_des;
-                       OK(len);
-
-               case USB_DT_STRING:
-                       len = usb_root_hub_string(wValue & 0xff, (int)(long)0,  "SL811HS", data, wLength);
-                       if (len > 0) {
-                               bufp = data;
-                               OK(len);
-                       }
-
-               default:
-                       status = -32;
-               }
-               break;
-
-       case RH_GET_DESCRIPTOR | USB_TYPE_CLASS:
-               len = sizeof(sl811_rh_hub_des);
-               bufp = sl811_rh_hub_des;
-               OK(len);
-
-       case RH_GET_CONFIGURATION:
-               bufp[0] = 0x01;
-               OK(1);
-
-       case RH_SET_CONFIGURATION:
-               OK(0);
-
-       default:
-               PDEBUG(1, "unsupported root hub command\n");
-               status = -32;
-       }
-
-       len = min(len, buf_len);
-       if (data != bufp)
-               memcpy(data, bufp, len);
-
-       PDEBUG(5, "len = %d, status = %d\n", len, status);
-
-       usb_dev->status = status;
-       usb_dev->act_len = len;
-
-       return status == 0 ? len : status;
-}
-
-#endif /* CONFIG_USB_SL811HS */
diff --git a/drivers/sm501.c b/drivers/sm501.c
deleted file mode 100644 (file)
index 23db02c..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * (C) Copyright 2002
- * Stäubli Faverges - <www.staubli.com>
- * Pierre AUBERT  p.aubert@staubli.com
- *
- * (C) Copyright 2005
- * Martin Krause TQ-Systems GmbH martin.krause@tqs.de
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Basic video support for SMI SM501 "Voyager" graphic controller
- */
-
-#include <common.h>
-
-#ifdef CONFIG_VIDEO_SM501
-
-#include <video_fb.h>
-#include <sm501.h>
-
-#define read8(ptrReg)                \
-    *(volatile unsigned char *)(sm501.isaBase + ptrReg)
-
-#define write8(ptrReg,value) \
-    *(volatile unsigned char *)(sm501.isaBase + ptrReg) = value
-
-#define read16(ptrReg) \
-    (*(volatile unsigned short *)(sm501.isaBase + ptrReg))
-
-#define write16(ptrReg,value) \
-    (*(volatile unsigned short *)(sm501.isaBase + ptrReg) = value)
-
-#define read32(ptrReg) \
-    (*(volatile unsigned int *)(sm501.isaBase + ptrReg))
-
-#define write32(ptrReg, value) \
-    (*(volatile unsigned int *)(sm501.isaBase + ptrReg) = value)
-
-GraphicDevice sm501;
-
-/*-----------------------------------------------------------------------------
- * SmiSetRegs --
- *-----------------------------------------------------------------------------
- */
-static void SmiSetRegs (void)
-{
-       /*
-        * The content of the chipset register depends on the board (clocks,
-        * ...)
-        */
-       const SMI_REGS *preg = board_get_regs ();
-       while (preg->Index) {
-               write32 (preg->Index, preg->Value);
-               /*
-                * Insert a delay between
-                */
-               udelay (1000);
-               preg ++;
-       }
-}
-
-/*-----------------------------------------------------------------------------
- * video_hw_init --
- *-----------------------------------------------------------------------------
- */
-void *video_hw_init (void)
-{
-       unsigned int *vm, i;
-
-       memset (&sm501, 0, sizeof (GraphicDevice));
-
-       /*
-        * Initialization of the access to the graphic chipset Retreive base
-        * address of the chipset (see board/RPXClassic/eccx.c)
-        */
-       if ((sm501.isaBase = board_video_init ()) == 0) {
-               return (NULL);
-       }
-
-       if ((sm501.frameAdrs = board_video_get_fb ()) == 0) {
-               return (NULL);
-       }
-
-       sm501.winSizeX = board_get_width ();
-       sm501.winSizeY = board_get_height ();
-
-#if defined(CONFIG_VIDEO_SM501_8BPP)
-       sm501.gdfIndex = GDF__8BIT_INDEX;
-       sm501.gdfBytesPP = 1;
-
-#elif defined(CONFIG_VIDEO_SM501_16BPP)
-       sm501.gdfIndex = GDF_16BIT_565RGB;
-       sm501.gdfBytesPP = 2;
-
-#elif defined(CONFIG_VIDEO_SM501_32BPP)
-       sm501.gdfIndex = GDF_32BIT_X888RGB;
-       sm501.gdfBytesPP = 4;
-#else
-#error Unsupported SM501 BPP
-#endif
-
-       sm501.memSize = sm501.winSizeX * sm501.winSizeY * sm501.gdfBytesPP;
-
-       /* Load Smi registers */
-       SmiSetRegs ();
-
-       /* (see board/RPXClassic/RPXClassic.c) */
-       board_validate_screen (sm501.isaBase);
-
-       /* Clear video memory */
-       i = sm501.memSize/4;
-       vm = (unsigned int *)sm501.frameAdrs;
-       while(i--)
-               *vm++ = 0;
-
-       return (&sm501);
-}
-
-/*-----------------------------------------------------------------------------
- * video_set_lut --
- *-----------------------------------------------------------------------------
- */
-void video_set_lut (
-       unsigned int index,           /* color number */
-       unsigned char r,              /* red */
-       unsigned char g,              /* green */
-       unsigned char b               /* blue */
-       )
-{
-}
-
-#endif /* CONFIG_VIDEO_SM501 */
diff --git a/drivers/smc91111.c b/drivers/smc91111.c
deleted file mode 100644 (file)
index 8061f12..0000000
+++ /dev/null
@@ -1,1623 +0,0 @@
-/*------------------------------------------------------------------------
- . smc91111.c
- . This is a driver for SMSC's 91C111 single-chip Ethernet device.
- .
- . (C) Copyright 2002
- . Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- . Rolf Offermanns <rof@sysgo.de>
- .
- . Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
- .      Developed by Simple Network Magic Corporation (SNMC)
- . Copyright (C) 1996 by Erik Stahlman (ES)
- .
- . This program is free software; you can redistribute it and/or modify
- . it under the terms of the GNU General Public License as published by
- . the Free Software Foundation; either version 2 of the License, or
- . (at your option) any later version.
- .
- . This program is distributed in the hope that it will be useful,
- . but WITHOUT ANY WARRANTY; without even the implied warranty of
- . MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- . GNU General Public License for more details.
- .
- . You should have received a copy of the GNU General Public License
- . along with this program; if not, write to the Free Software
- . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307         USA
- .
- . Information contained in this file was obtained from the LAN91C111
- . manual from SMC.  To get a copy, if you really want one, you can find
- . information under www.smsc.com.
- .
- .
- . "Features" of the SMC chip:
- .   Integrated PHY/MAC for 10/100BaseT Operation
- .   Supports internal and external MII
- .   Integrated 8K packet memory
- .   EEPROM interface for configuration
- .
- . Arguments:
- .     io      = for the base address
- .     irq     = for the IRQ
- .
- . author:
- .     Erik Stahlman                           ( erik@vt.edu )
- .     Daris A Nevil                           ( dnevil@snmc.com )
- .
- .
- . Hardware multicast code from Peter Cammaert ( pc@denkart.be )
- .
- . Sources:
- .    o          SMSC LAN91C111 databook (www.smsc.com)
- .    o          smc9194.c by Erik Stahlman
- .    o          skeleton.c by Donald Becker ( becker@cesdis.gsfc.nasa.gov )
- .
- . History:
- .     06/19/03  Richard Woodruff Made u-boot environment aware and added mac addr checks.
- .     10/17/01  Marco Hasewinkel Modify for DNP/1110
- .     07/25/01  Woojung Huh      Modify for ADS Bitsy
- .     04/25/01  Daris A Nevil    Initial public release through SMSC
- .     03/16/01  Daris A Nevil    Modified smc9194.c for use with LAN91C111
- ----------------------------------------------------------------------------*/
-
-#include <common.h>
-#include <command.h>
-#include <config.h>
-#include "smc91111.h"
-#include <net.h>
-
-#ifdef CONFIG_DRIVER_SMC91111
-
-/* Use power-down feature of the chip */
-#define POWER_DOWN     0
-
-#define NO_AUTOPROBE
-
-#define SMC_DEBUG 0
-
-#if SMC_DEBUG > 1
-static const char version[] =
-       "smc91111.c:v1.0 04/25/01 by Daris A Nevil (dnevil@snmc.com)\n";
-#endif
-
-/* Autonegotiation timeout in seconds */
-#ifndef CONFIG_SMC_AUTONEG_TIMEOUT
-#define CONFIG_SMC_AUTONEG_TIMEOUT 10
-#endif
-
-/*------------------------------------------------------------------------
- .
- . Configuration options, for the experienced user to change.
- .
- -------------------------------------------------------------------------*/
-
-/*
- . Wait time for memory to be free.  This probably shouldn't be
- . tuned that much, as waiting for this means nothing else happens
- . in the system
-*/
-#define MEMORY_WAIT_TIME 16
-
-
-#if (SMC_DEBUG > 2 )
-#define PRINTK3(args...) printf(args)
-#else
-#define PRINTK3(args...)
-#endif
-
-#if SMC_DEBUG > 1
-#define PRINTK2(args...) printf(args)
-#else
-#define PRINTK2(args...)
-#endif
-
-#ifdef SMC_DEBUG
-#define PRINTK(args...) printf(args)
-#else
-#define PRINTK(args...)
-#endif
-
-
-/*------------------------------------------------------------------------
- .
- . The internal workings of the driver.         If you are changing anything
- . here with the SMC stuff, you should have the datasheet and know
- . what you are doing.
- .
- -------------------------------------------------------------------------*/
-#define CARDNAME "LAN91C111"
-
-/* Memory sizing constant */
-#define LAN91C111_MEMORY_MULTIPLIER    (1024*2)
-
-#ifndef CONFIG_SMC91111_BASE
-#define CONFIG_SMC91111_BASE 0x20000300
-#endif
-
-#define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE
-
-#define SMC_DEV_NAME "SMC91111"
-#define SMC_PHY_ADDR 0x0000
-#define SMC_ALLOC_MAX_TRY 5
-#define SMC_TX_TIMEOUT 30
-
-#define SMC_PHY_CLOCK_DELAY 1000
-
-#define ETH_ZLEN 60
-
-#ifdef CONFIG_SMC_USE_32_BIT
-#define USE_32_BIT  1
-#else
-#undef USE_32_BIT
-#endif
-/*-----------------------------------------------------------------
- .
- .  The driver can be entered at any of the following entry points.
- .
- .------------------------------------------------------------------  */
-
-extern int eth_init(bd_t *bd);
-extern void eth_halt(void);
-extern int eth_rx(void);
-extern int eth_send(volatile void *packet, int length);
-
-#ifdef SHARED_RESOURCES
-       extern void swap_to(int device_id);
-#endif
-
-/*
- . This is called by  register_netdev().  It is responsible for
- . checking the portlist for the SMC9000 series chipset.  If it finds
- . one, then it will initialize the device, find the hardware information,
- . and sets up the appropriate device parameters.
- . NOTE: Interrupts are *OFF* when this procedure is called.
- .
- . NB:This shouldn't be static since it is referred to externally.
-*/
-int smc_init(void);
-
-/*
- . This is called by  unregister_netdev().  It is responsible for
- . cleaning up before the driver is finally unregistered and discarded.
-*/
-void smc_destructor(void);
-
-/*
- . The kernel calls this function when someone wants to use the device,
- . typically 'ifconfig ethX up'.
-*/
-static int smc_open(bd_t *bd);
-
-
-/*
- . This is called by the kernel in response to 'ifconfig ethX down'.  It
- . is responsible for cleaning up everything that the open routine
- . does, and maybe putting the card into a powerdown state.
-*/
-static int smc_close(void);
-
-/*
- . Configures the PHY through the MII Management interface
-*/
-#ifndef CONFIG_SMC91111_EXT_PHY
-static void smc_phy_configure(void);
-#endif /* !CONFIG_SMC91111_EXT_PHY */
-
-/*
- . This is a separate procedure to handle the receipt of a packet, to
- . leave the interrupt code looking slightly cleaner
-*/
-static int smc_rcv(void);
-
-/* See if a MAC address is defined in the current environment. If so use it. If not
- . print a warning and set the environment and other globals with the default.
- . If an EEPROM is present it really should be consulted.
-*/
-int smc_get_ethaddr(bd_t *bd);
-int get_rom_mac(uchar *v_rom_mac);
-
-/*
- ------------------------------------------------------------
- .
- . Internal routines
- .
- ------------------------------------------------------------
-*/
-
-#ifdef CONFIG_SMC_USE_IOFUNCS
-/*
- * input and output functions
- *
- * Implemented due to inx,outx macros accessing the device improperly
- * and putting the device into an unkown state.
- *
- * For instance, on Sharp LPD7A400 SDK, affects were chip memory
- * could not be free'd (hence the alloc failures), duplicate packets,
- * packets being corrupt (shifted) on the wire, etc.  Switching to the
- * inx,outx functions fixed this problem.
- */
-static inline word SMC_inw(dword offset);
-static inline void SMC_outw(word value, dword offset);
-static inline byte SMC_inb(dword offset);
-static inline void SMC_outb(byte value, dword offset);
-static inline void SMC_insw(dword offset, volatile uchar* buf, dword len);
-static inline void SMC_outsw(dword offset, uchar* buf, dword len);
-
-#define barrier() __asm__ __volatile__("": : :"memory")
-
-static inline word SMC_inw(dword offset)
-{
-       word v;
-       v = *((volatile word*)(SMC_BASE_ADDRESS+offset));
-       barrier(); *(volatile u32*)(0xc0000000);
-       return v;
-}
-
-static inline void SMC_outw(word value, dword offset)
-{
-       *((volatile word*)(SMC_BASE_ADDRESS+offset)) = value;
-       barrier(); *(volatile u32*)(0xc0000000);
-}
-
-static inline byte SMC_inb(dword offset)
-{
-       word  _w;
-
-       _w = SMC_inw(offset & ~((dword)1));
-       return (offset & 1) ? (byte)(_w >> 8) : (byte)(_w);
-}
-
-static inline void SMC_outb(byte value, dword offset)
-{
-       word  _w;
-
-       _w = SMC_inw(offset & ~((dword)1));
-       if (offset & 1)
-                       *((volatile word*)(SMC_BASE_ADDRESS+(offset & ~((dword)1)))) = (value<<8) | (_w & 0x00ff);
-       else
-                       *((volatile word*)(SMC_BASE_ADDRESS+offset)) = value | (_w & 0xff00);
-}
-
-static inline void SMC_insw(dword offset, volatile uchar* buf, dword len)
-{
-       volatile word *p = (volatile word *)buf;
-
-       while (len-- > 0) {
-               *p++ = SMC_inw(offset);
-               barrier();
-               *((volatile u32*)(0xc0000000));
-       }
-}
-
-static inline void SMC_outsw(dword offset, uchar* buf, dword len)
-{
-       volatile word *p = (volatile word *)buf;
-
-       while (len-- > 0) {
-               SMC_outw(*p++, offset);
-               barrier();
-               *(volatile u32*)(0xc0000000);
-       }
-}
-#endif  /* CONFIG_SMC_USE_IOFUNCS */
-
-static char unsigned smc_mac_addr[6] = {0x02, 0x80, 0xad, 0x20, 0x31, 0xb8};
-
-/*
- * This function must be called before smc_open() if you want to override
- * the default mac address.
- */
-
-void smc_set_mac_addr(const unsigned char *addr) {
-       int i;
-
-       for (i=0; i < sizeof(smc_mac_addr); i++){
-               smc_mac_addr[i] = addr[i];
-       }
-}
-
-/*
- * smc_get_macaddr is no longer used. If you want to override the default
- * mac address, call smc_get_mac_addr as a part of the board initialization.
- */
-
-#if 0
-void smc_get_macaddr( byte *addr ) {
-       /* MAC ADDRESS AT FLASHBLOCK 1 / OFFSET 0x10 */
-       unsigned char *dnp1110_mac = (unsigned char *) (0xE8000000 + 0x20010);
-       int i;
-
-
-       for (i=0; i<6; i++) {
-           addr[0] = *(dnp1110_mac+0);
-           addr[1] = *(dnp1110_mac+1);
-           addr[2] = *(dnp1110_mac+2);
-           addr[3] = *(dnp1110_mac+3);
-           addr[4] = *(dnp1110_mac+4);
-           addr[5] = *(dnp1110_mac+5);
-       }
-}
-#endif /* 0 */
-
-/***********************************************
- * Show available memory                      *
- ***********************************************/
-void dump_memory_info(void)
-{
-       word mem_info;
-       word old_bank;
-
-       old_bank = SMC_inw(BANK_SELECT)&0xF;
-
-       SMC_SELECT_BANK(0);
-       mem_info = SMC_inw( MIR_REG );
-       PRINTK2("Memory: %4d available\n", (mem_info >> 8)*2048);
-
-       SMC_SELECT_BANK(old_bank);
-}
-/*
- . A rather simple routine to print out a packet for debugging purposes.
-*/
-#if SMC_DEBUG > 2
-static void print_packet( byte *, int );
-#endif
-
-#define tx_done(dev) 1
-
-
-/* this does a soft reset on the device */
-static void smc_reset( void );
-
-/* Enable Interrupts, Receive, and Transmit */
-static void smc_enable( void );
-
-/* this puts the device in an inactive state */
-static void smc_shutdown( void );
-
-/* Routines to Read and Write the PHY Registers across the
-   MII Management Interface
-*/
-
-#ifndef CONFIG_SMC91111_EXT_PHY
-static word smc_read_phy_register(byte phyreg);
-static void smc_write_phy_register(byte phyreg, word phydata);
-#endif /* !CONFIG_SMC91111_EXT_PHY */
-
-
-static int poll4int (byte mask, int timeout)
-{
-       int tmo = get_timer (0) + timeout * CFG_HZ;
-       int is_timeout = 0;
-       word old_bank = SMC_inw (BSR_REG);
-
-       PRINTK2 ("Polling...\n");
-       SMC_SELECT_BANK (2);
-       while ((SMC_inw (SMC91111_INT_REG) & mask) == 0) {
-               if (get_timer (0) >= tmo) {
-                       is_timeout = 1;
-                       break;
-               }
-       }
-
-       /* restore old bank selection */
-       SMC_SELECT_BANK (old_bank);
-
-       if (is_timeout)
-               return 1;
-       else
-               return 0;
-}
-
-/* Only one release command at a time, please */
-static inline void smc_wait_mmu_release_complete (void)
-{
-       int count = 0;
-
-       /* assume bank 2 selected */
-       while (SMC_inw (MMU_CMD_REG) & MC_BUSY) {
-               udelay (1);     /* Wait until not busy */
-               if (++count > 200)
-                       break;
-       }
-}
-
-/*
- . Function: smc_reset( void )
- . Purpose:
- .     This sets the SMC91111 chip to its normal state, hopefully from whatever
- .     mess that any other DOS driver has put it in.
- .
- . Maybe I should reset more registers to defaults in here?  SOFTRST  should
- . do that for me.
- .
- . Method:
- .     1.  send a SOFT RESET
- .     2.  wait for it to finish
- .     3.  enable autorelease mode
- .     4.  reset the memory management unit
- .     5.  clear all interrupts
- .
-*/
-static void smc_reset (void)
-{
-       PRINTK2 ("%s: smc_reset\n", SMC_DEV_NAME);
-
-       /* This resets the registers mostly to defaults, but doesn't
-          affect EEPROM.  That seems unnecessary */
-       SMC_SELECT_BANK (0);
-       SMC_outw (RCR_SOFTRST, RCR_REG);
-
-       /* Setup the Configuration Register */
-       /* This is necessary because the CONFIG_REG is not affected */
-       /* by a soft reset */
-
-       SMC_SELECT_BANK (1);
-#if defined(CONFIG_SMC91111_EXT_PHY)
-       SMC_outw (CONFIG_DEFAULT | CONFIG_EXT_PHY, CONFIG_REG);
-#else
-       SMC_outw (CONFIG_DEFAULT, CONFIG_REG);
-#endif
-
-
-       /* Release from possible power-down state */
-       /* Configuration register is not affected by Soft Reset */
-       SMC_outw (SMC_inw (CONFIG_REG) | CONFIG_EPH_POWER_EN, CONFIG_REG);
-
-       SMC_SELECT_BANK (0);
-
-       /* this should pause enough for the chip to be happy */
-       udelay (10);
-
-       /* Disable transmit and receive functionality */
-       SMC_outw (RCR_CLEAR, RCR_REG);
-       SMC_outw (TCR_CLEAR, TCR_REG);
-
-       /* set the control register */
-       SMC_SELECT_BANK (1);
-       SMC_outw (CTL_DEFAULT, CTL_REG);
-
-       /* Reset the MMU */
-       SMC_SELECT_BANK (2);
-       smc_wait_mmu_release_complete ();
-       SMC_outw (MC_RESET, MMU_CMD_REG);
-       while (SMC_inw (MMU_CMD_REG) & MC_BUSY)
-               udelay (1);     /* Wait until not busy */
-
-       /* Note:  It doesn't seem that waiting for the MMU busy is needed here,
-          but this is a place where future chipsets _COULD_ break.  Be wary
-          of issuing another MMU command right after this */
-
-       /* Disable all interrupts */
-       SMC_outb (0, IM_REG);
-}
-
-/*
- . Function: smc_enable
- . Purpose: let the chip talk to the outside work
- . Method:
- .     1.  Enable the transmitter
- .     2.  Enable the receiver
- .     3.  Enable interrupts
-*/
-static void smc_enable()
-{
-       PRINTK2("%s: smc_enable\n", SMC_DEV_NAME);
-       SMC_SELECT_BANK( 0 );
-       /* see the header file for options in TCR/RCR DEFAULT*/
-       SMC_outw( TCR_DEFAULT, TCR_REG );
-       SMC_outw( RCR_DEFAULT, RCR_REG );
-
-       /* clear MII_DIS */
-/*     smc_write_phy_register(PHY_CNTL_REG, 0x0000); */
-}
-
-/*
- . Function: smc_shutdown
- . Purpose:  closes down the SMC91xxx chip.
- . Method:
- .     1. zero the interrupt mask
- .     2. clear the enable receive flag
- .     3. clear the enable xmit flags
- .
- . TODO:
- .   (1) maybe utilize power down mode.
- .     Why not yet?  Because while the chip will go into power down mode,
- .     the manual says that it will wake up in response to any I/O requests
- .     in the register space.   Empirical results do not show this working.
-*/
-static void smc_shutdown()
-{
-       PRINTK2(CARDNAME ": smc_shutdown\n");
-
-       /* no more interrupts for me */
-       SMC_SELECT_BANK( 2 );
-       SMC_outb( 0, IM_REG );
-
-       /* and tell the card to stay away from that nasty outside world */
-       SMC_SELECT_BANK( 0 );
-       SMC_outb( RCR_CLEAR, RCR_REG );
-       SMC_outb( TCR_CLEAR, TCR_REG );
-#ifdef SHARED_RESOURCES
-       swap_to(FLASH);
-#endif
-}
-
-
-/*
- . Function:  smc_hardware_send_packet(struct net_device * )
- . Purpose:
- .     This sends the actual packet to the SMC9xxx chip.
- .
- . Algorithm:
- .     First, see if a saved_skb is available.
- .             ( this should NOT be called if there is no 'saved_skb'
- .     Now, find the packet number that the chip allocated
- .     Point the data pointers at it in memory
- .     Set the length word in the chip's memory
- .     Dump the packet to chip memory
- .     Check if a last byte is needed ( odd length packet )
- .             if so, set the control flag right
- .     Tell the card to send it
- .     Enable the transmit interrupt, so I know if it failed
- .     Free the kernel data if I actually sent it.
-*/
-static int smc_send_packet (volatile void *packet, int packet_length)
-{
-       byte packet_no;
-       unsigned long ioaddr;
-       byte *buf;
-       int length;
-       int numPages;
-       int try = 0;
-       int time_out;
-       byte status;
-       byte saved_pnr;
-       word saved_ptr;
-
-       /* save PTR and PNR registers before manipulation */
-       SMC_SELECT_BANK (2);
-       saved_pnr = SMC_inb( PN_REG );
-       saved_ptr = SMC_inw( PTR_REG );
-
-       PRINTK3 ("%s: smc_hardware_send_packet\n", SMC_DEV_NAME);
-
-       length = ETH_ZLEN < packet_length ? packet_length : ETH_ZLEN;
-
-       /* allocate memory
-        ** The MMU wants the number of pages to be the number of 256 bytes
-        ** 'pages', minus 1 ( since a packet can't ever have 0 pages :) )
-        **
-        ** The 91C111 ignores the size bits, but the code is left intact
-        ** for backwards and future compatibility.
-        **
-        ** Pkt size for allocating is data length +6 (for additional status
-        ** words, length and ctl!)
-        **
-        ** If odd size then last byte is included in this header.
-        */
-       numPages = ((length & 0xfffe) + 6);
-       numPages >>= 8;         /* Divide by 256 */
-
-       if (numPages > 7) {
-               printf ("%s: Far too big packet error. \n", SMC_DEV_NAME);
-               return 0;
-       }
-
-       /* now, try to allocate the memory */
-       SMC_SELECT_BANK (2);
-       SMC_outw (MC_ALLOC | numPages, MMU_CMD_REG);
-
-       /* FIXME: the ALLOC_INT bit never gets set *
-        * so the following will always give a     *
-        * memory allocation error.                *
-        * same code works in armboot though       *
-        * -ro
-        */
-
-again:
-       try++;
-       time_out = MEMORY_WAIT_TIME;
-       do {
-               status = SMC_inb (SMC91111_INT_REG);
-               if (status & IM_ALLOC_INT) {
-                       /* acknowledge the interrupt */
-                       SMC_outb (IM_ALLOC_INT, SMC91111_INT_REG);
-                       break;
-               }
-       } while (--time_out);
-
-       if (!time_out) {
-               PRINTK2 ("%s: memory allocation, try %d failed ...\n",
-                        SMC_DEV_NAME, try);
-               if (try < SMC_ALLOC_MAX_TRY)
-                       goto again;
-               else
-                       return 0;
-       }
-
-       PRINTK2 ("%s: memory allocation, try %d succeeded ...\n",
-                SMC_DEV_NAME, try);
-
-       /* I can send the packet now.. */
-
-       ioaddr = SMC_BASE_ADDRESS;
-
-       buf = (byte *) packet;
-
-       /* If I get here, I _know_ there is a packet slot waiting for me */
-       packet_no = SMC_inb (AR_REG);
-       if (packet_no & AR_FAILED) {
-               /* or isn't there?  BAD CHIP! */
-               printf ("%s: Memory allocation failed. \n", SMC_DEV_NAME);
-               return 0;
-       }
-
-       /* we have a packet address, so tell the card to use it */
-#ifndef CONFIG_XAENIAX
-       SMC_outb (packet_no, PN_REG);
-#else
-       /* On Xaeniax board, we can't use SMC_outb here because that way
-        * the Allocate MMU command will end up written to the command register
-        * as well, which will lead to a problem.
-        */
-       SMC_outl (packet_no << 16, 0);
-#endif
-       /* do not write new ptr value if Write data fifo not empty */
-       while ( saved_ptr & PTR_NOTEMPTY )
-               printf ("Write data fifo not empty!\n");
-
-       /* point to the beginning of the packet */
-       SMC_outw (PTR_AUTOINC, PTR_REG);
-
-       PRINTK3 ("%s: Trying to xmit packet of length %x\n",
-                SMC_DEV_NAME, length);
-
-#if SMC_DEBUG > 2
-       printf ("Transmitting Packet\n");
-       print_packet (buf, length);
-#endif
-
-       /* send the packet length ( +6 for status, length and ctl byte )
-          and the status word ( set to zeros ) */
-#ifdef USE_32_BIT
-       SMC_outl ((length + 6) << 16, SMC91111_DATA_REG);
-#else
-       SMC_outw (0, SMC91111_DATA_REG);
-       /* send the packet length ( +6 for status words, length, and ctl */
-       SMC_outw ((length + 6), SMC91111_DATA_REG);
-#endif
-
-       /* send the actual data
-          . I _think_ it's faster to send the longs first, and then
-          . mop up by sending the last word.  It depends heavily
-          . on alignment, at least on the 486.  Maybe it would be
-          . a good idea to check which is optimal?  But that could take
-          . almost as much time as is saved?
-        */
-#ifdef USE_32_BIT
-       SMC_outsl (SMC91111_DATA_REG, buf, length >> 2);
-#ifndef CONFIG_XAENIAX
-       if (length & 0x2)
-               SMC_outw (*((word *) (buf + (length & 0xFFFFFFFC))),
-                         SMC91111_DATA_REG);
-#else
-       /* On XANEIAX, we can only use 32-bit writes, so we need to handle
-        * unaligned tail part specially. The standard code doesn't work.
-        */
-       if ((length & 3) == 3) {
-               u16 * ptr = (u16*) &buf[length-3];
-               SMC_outl((*ptr) | ((0x2000 | buf[length-1]) << 16),
-                               SMC91111_DATA_REG);
-       } else if ((length & 2) == 2) {
-               u16 * ptr = (u16*) &buf[length-2];
-               SMC_outl(*ptr, SMC91111_DATA_REG);
-       } else if (length & 1) {
-               SMC_outl((0x2000 | buf[length-1]), SMC91111_DATA_REG);
-       } else {
-               SMC_outl(0, SMC91111_DATA_REG);
-       }
-#endif
-#else
-       SMC_outsw (SMC91111_DATA_REG, buf, (length) >> 1);
-#endif /* USE_32_BIT */
-
-#ifndef CONFIG_XAENIAX
-       /* Send the last byte, if there is one.   */
-       if ((length & 1) == 0) {
-               SMC_outw (0, SMC91111_DATA_REG);
-       } else {
-               SMC_outw (buf[length - 1] | 0x2000, SMC91111_DATA_REG);
-       }
-#endif
-
-       /* and let the chipset deal with it */
-       SMC_outw (MC_ENQUEUE, MMU_CMD_REG);
-
-       /* poll for TX INT */
-       /* if (poll4int (IM_TX_INT, SMC_TX_TIMEOUT)) { */
-       /* poll for TX_EMPTY INT - autorelease enabled */
-       if (poll4int(IM_TX_EMPTY_INT, SMC_TX_TIMEOUT)) {
-               /* sending failed */
-               PRINTK2 ("%s: TX timeout, sending failed...\n", SMC_DEV_NAME);
-
-               /* release packet */
-               /* no need to release, MMU does that now */
-#ifdef CONFIG_XAENIAX
-                SMC_outw (MC_FREEPKT, MMU_CMD_REG);
-#endif
-
-               /* wait for MMU getting ready (low) */
-               while (SMC_inw (MMU_CMD_REG) & MC_BUSY) {
-                       udelay (10);
-               }
-
-               PRINTK2 ("MMU ready\n");
-
-
-               return 0;
-       } else {
-               /* ack. int */
-               SMC_outb (IM_TX_EMPTY_INT, SMC91111_INT_REG);
-               /* SMC_outb (IM_TX_INT, SMC91111_INT_REG); */
-               PRINTK2 ("%s: Sent packet of length %d \n", SMC_DEV_NAME,
-                        length);
-
-               /* release packet */
-               /* no need to release, MMU does that now */
-#ifdef CONFIG_XAENIAX
-               SMC_outw (MC_FREEPKT, MMU_CMD_REG);
-#endif
-
-               /* wait for MMU getting ready (low) */
-               while (SMC_inw (MMU_CMD_REG) & MC_BUSY) {
-                       udelay (10);
-               }
-
-               PRINTK2 ("MMU ready\n");
-
-
-       }
-
-       /* restore previously saved registers */
-#ifndef CONFIG_XAENIAX
-       SMC_outb( saved_pnr, PN_REG );
-#else
-       /* On Xaeniax board, we can't use SMC_outb here because that way
-        * the Allocate MMU command will end up written to the command register
-        * as well, which will lead to a problem.
-        */
-       SMC_outl(saved_pnr << 16, 0);
-#endif
-       SMC_outw( saved_ptr, PTR_REG );
-
-       return length;
-}
-
-/*-------------------------------------------------------------------------
- |
- | smc_destructor( struct net_device * dev )
- |   Input parameters:
- |     dev, pointer to the device structure
- |
- |   Output:
- |     None.
- |
- ---------------------------------------------------------------------------
-*/
-void smc_destructor()
-{
-       PRINTK2(CARDNAME ": smc_destructor\n");
-}
-
-
-/*
- * Open and Initialize the board
- *
- * Set up everything, reset the card, etc ..
- *
- */
-static int smc_open (bd_t * bd)
-{
-       int i, err;
-
-       PRINTK2 ("%s: smc_open\n", SMC_DEV_NAME);
-
-       /* reset the hardware */
-       smc_reset ();
-       smc_enable ();
-
-       /* Configure the PHY */
-#ifndef CONFIG_SMC91111_EXT_PHY
-       smc_phy_configure ();
-#endif
-
-       /* conservative setting (10Mbps, HalfDuplex, no AutoNeg.) */
-/*     SMC_SELECT_BANK(0); */
-/*     SMC_outw(0, RPC_REG); */
-       SMC_SELECT_BANK (1);
-
-       err = smc_get_ethaddr (bd);     /* set smc_mac_addr, and sync it with u-boot globals */
-       if (err < 0) {
-               memset (bd->bi_enetaddr, 0, 6); /* hack to make error stick! upper code will abort if not set */
-               return (-1);    /* upper code ignores this, but NOT bi_enetaddr */
-       }
-#ifdef USE_32_BIT
-       for (i = 0; i < 6; i += 2) {
-               word address;
-
-               address = smc_mac_addr[i + 1] << 8;
-               address |= smc_mac_addr[i];
-               SMC_outw (address, (ADDR0_REG + i));
-       }
-#else
-       for (i = 0; i < 6; i++)
-               SMC_outb (smc_mac_addr[i], (ADDR0_REG + i));
-#endif
-
-       return 0;
-}
-
-/*-------------------------------------------------------------
- .
- . smc_rcv -  receive a packet from the card
- .
- . There is ( at least ) a packet waiting to be read from
- . chip-memory.
- .
- . o Read the status
- . o If an error, record it
- . o otherwise, read in the packet
- --------------------------------------------------------------
-*/
-static int smc_rcv()
-{
-       int     packet_number;
-       word    status;
-       word    packet_length;
-       int     is_error = 0;
-#ifdef USE_32_BIT
-       dword stat_len;
-#endif
-       byte saved_pnr;
-       word saved_ptr;
-
-       SMC_SELECT_BANK(2);
-       /* save PTR and PTR registers */
-       saved_pnr = SMC_inb( PN_REG );
-       saved_ptr = SMC_inw( PTR_REG );
-
-       packet_number = SMC_inw( RXFIFO_REG );
-
-       if ( packet_number & RXFIFO_REMPTY ) {
-
-               return 0;
-       }
-
-       PRINTK3("%s: smc_rcv\n", SMC_DEV_NAME);
-       /*  start reading from the start of the packet */
-       SMC_outw( PTR_READ | PTR_RCV | PTR_AUTOINC, PTR_REG );
-
-       /* First two words are status and packet_length */
-#ifdef USE_32_BIT
-       stat_len = SMC_inl(SMC91111_DATA_REG);
-       status = stat_len & 0xffff;
-       packet_length = stat_len >> 16;
-#else
-       status          = SMC_inw( SMC91111_DATA_REG );
-       packet_length   = SMC_inw( SMC91111_DATA_REG );
-#endif
-
-       packet_length &= 0x07ff;  /* mask off top bits */
-
-       PRINTK2("RCV: STATUS %4x LENGTH %4x\n", status, packet_length );
-
-       if ( !(status & RS_ERRORS ) ){
-               /* Adjust for having already read the first two words */
-               packet_length -= 4; /*4; */
-
-
-               /* set odd length for bug in LAN91C111, */
-               /* which never sets RS_ODDFRAME */
-               /* TODO ? */
-
-
-#ifdef USE_32_BIT
-               PRINTK3(" Reading %d dwords (and %d bytes) \n",
-                       packet_length >> 2, packet_length & 3 );
-               /* QUESTION:  Like in the TX routine, do I want
-                  to send the DWORDs or the bytes first, or some
-                  mixture.  A mixture might improve already slow PIO
-                  performance  */
-               SMC_insl( SMC91111_DATA_REG , NetRxPackets[0], packet_length >> 2 );
-               /* read the left over bytes */
-               if (packet_length & 3) {
-                       int i;
-
-                       byte *tail = (byte *)(NetRxPackets[0] + (packet_length & ~3));
-                       dword leftover = SMC_inl(SMC91111_DATA_REG);
-                       for (i=0; i<(packet_length & 3); i++)
-                               *tail++ = (byte) (leftover >> (8*i)) & 0xff;
-               }
-#else
-               PRINTK3(" Reading %d words and %d byte(s) \n",
-                       (packet_length >> 1 ), packet_length & 1 );
-               SMC_insw(SMC91111_DATA_REG , NetRxPackets[0], packet_length >> 1);
-
-#endif /* USE_32_BIT */
-
-#if    SMC_DEBUG > 2
-               printf("Receiving Packet\n");
-               print_packet( NetRxPackets[0], packet_length );
-#endif
-       } else {
-               /* error ... */
-               /* TODO ? */
-               is_error = 1;
-       }
-
-       while ( SMC_inw( MMU_CMD_REG ) & MC_BUSY )
-               udelay(1); /* Wait until not busy */
-
-       /*  error or good, tell the card to get rid of this packet */
-       SMC_outw( MC_RELEASE, MMU_CMD_REG );
-
-       while ( SMC_inw( MMU_CMD_REG ) & MC_BUSY )
-               udelay(1); /* Wait until not busy */
-
-       /* restore saved registers */
-#ifndef CONFIG_XAENIAX
-       SMC_outb( saved_pnr, PN_REG );
-#else
-       /* On Xaeniax board, we can't use SMC_outb here because that way
-        * the Allocate MMU command will end up written to the command register
-        * as well, which will lead to a problem.
-        */
-       SMC_outl( saved_pnr << 16, 0);
-#endif
-       SMC_outw( saved_ptr, PTR_REG );
-
-       if (!is_error) {
-               /* Pass the packet up to the protocol layers. */
-               NetReceive(NetRxPackets[0], packet_length);
-               return packet_length;
-       } else {
-               return 0;
-       }
-
-}
-
-
-/*----------------------------------------------------
- . smc_close
- .
- . this makes the board clean up everything that it can
- . and not talk to the outside world.  Caused by
- . an 'ifconfig ethX down'
- .
- -----------------------------------------------------*/
-static int smc_close()
-{
-       PRINTK2("%s: smc_close\n", SMC_DEV_NAME);
-
-       /* clear everything */
-       smc_shutdown();
-
-       return 0;
-}
-
-
-#if 0
-/*------------------------------------------------------------
- . Modify a bit in the LAN91C111 register set
- .-------------------------------------------------------------*/
-static word smc_modify_regbit(int bank, int ioaddr, int reg,
-       unsigned int bit, int val)
-{
-       word regval;
-
-       SMC_SELECT_BANK( bank );
-
-       regval = SMC_inw( reg );
-       if (val)
-               regval |= bit;
-       else
-               regval &= ~bit;
-
-       SMC_outw( regval, 0 );
-       return(regval);
-}
-
-
-/*------------------------------------------------------------
- . Retrieve a bit in the LAN91C111 register set
- .-------------------------------------------------------------*/
-static int smc_get_regbit(int bank, int ioaddr, int reg, unsigned int bit)
-{
-       SMC_SELECT_BANK( bank );
-       if ( SMC_inw( reg ) & bit)
-               return(1);
-       else
-               return(0);
-}
-
-
-/*------------------------------------------------------------
- . Modify a LAN91C111 register (word access only)
- .-------------------------------------------------------------*/
-static void smc_modify_reg(int bank, int ioaddr, int reg, word val)
-{
-       SMC_SELECT_BANK( bank );
-       SMC_outw( val, reg );
-}
-
-
-/*------------------------------------------------------------
- . Retrieve a LAN91C111 register (word access only)
- .-------------------------------------------------------------*/
-static int smc_get_reg(int bank, int ioaddr, int reg)
-{
-       SMC_SELECT_BANK( bank );
-       return(SMC_inw( reg ));
-}
-
-#endif /* 0 */
-
-/*---PHY CONTROL AND CONFIGURATION----------------------------------------- */
-
-#if (SMC_DEBUG > 2 )
-
-/*------------------------------------------------------------
- . Debugging function for viewing MII Management serial bitstream
- .-------------------------------------------------------------*/
-static void smc_dump_mii_stream (byte * bits, int size)
-{
-       int i;
-
-       printf ("BIT#:");
-       for (i = 0; i < size; ++i) {
-               printf ("%d", i % 10);
-       }
-
-       printf ("\nMDOE:");
-       for (i = 0; i < size; ++i) {
-               if (bits[i] & MII_MDOE)
-                       printf ("1");
-               else
-                       printf ("0");
-       }
-
-       printf ("\nMDO :");
-       for (i = 0; i < size; ++i) {
-               if (bits[i] & MII_MDO)
-                       printf ("1");
-               else
-                       printf ("0");
-       }
-
-       printf ("\nMDI :");
-       for (i = 0; i < size; ++i) {
-               if (bits[i] & MII_MDI)
-                       printf ("1");
-               else
-                       printf ("0");
-       }
-
-       printf ("\n");
-}
-#endif
-
-/*------------------------------------------------------------
- . Reads a register from the MII Management serial interface
- .-------------------------------------------------------------*/
-#ifndef CONFIG_SMC91111_EXT_PHY
-static word smc_read_phy_register (byte phyreg)
-{
-       int oldBank;
-       int i;
-       byte mask;
-       word mii_reg;
-       byte bits[64];
-       int clk_idx = 0;
-       int input_idx;
-       word phydata;
-       byte phyaddr = SMC_PHY_ADDR;
-
-       /* 32 consecutive ones on MDO to establish sync */
-       for (i = 0; i < 32; ++i)
-               bits[clk_idx++] = MII_MDOE | MII_MDO;
-
-       /* Start code <01> */
-       bits[clk_idx++] = MII_MDOE;
-       bits[clk_idx++] = MII_MDOE | MII_MDO;
-
-       /* Read command <10> */
-       bits[clk_idx++] = MII_MDOE | MII_MDO;
-       bits[clk_idx++] = MII_MDOE;
-
-       /* Output the PHY address, msb first */
-       mask = (byte) 0x10;
-       for (i = 0; i < 5; ++i) {
-               if (phyaddr & mask)
-                       bits[clk_idx++] = MII_MDOE | MII_MDO;
-               else
-                       bits[clk_idx++] = MII_MDOE;
-
-               /* Shift to next lowest bit */
-               mask >>= 1;
-       }
-
-       /* Output the phy register number, msb first */
-       mask = (byte) 0x10;
-       for (i = 0; i < 5; ++i) {
-               if (phyreg & mask)
-                       bits[clk_idx++] = MII_MDOE | MII_MDO;
-               else
-                       bits[clk_idx++] = MII_MDOE;
-
-               /* Shift to next lowest bit */
-               mask >>= 1;
-       }
-
-       /* Tristate and turnaround (2 bit times) */
-       bits[clk_idx++] = 0;
-       /*bits[clk_idx++] = 0; */
-
-       /* Input starts at this bit time */
-       input_idx = clk_idx;
-
-       /* Will input 16 bits */
-       for (i = 0; i < 16; ++i)
-               bits[clk_idx++] = 0;
-
-       /* Final clock bit */
-       bits[clk_idx++] = 0;
-
-       /* Save the current bank */
-       oldBank = SMC_inw (BANK_SELECT);
-
-       /* Select bank 3 */
-       SMC_SELECT_BANK (3);
-
-       /* Get the current MII register value */
-       mii_reg = SMC_inw (MII_REG);
-
-       /* Turn off all MII Interface bits */
-       mii_reg &= ~(MII_MDOE | MII_MCLK | MII_MDI | MII_MDO);
-
-       /* Clock all 64 cycles */
-       for (i = 0; i < sizeof bits; ++i) {
-               /* Clock Low - output data */
-               SMC_outw (mii_reg | bits[i], MII_REG);
-               udelay (SMC_PHY_CLOCK_DELAY);
-
-
-               /* Clock Hi - input data */
-               SMC_outw (mii_reg | bits[i] | MII_MCLK, MII_REG);
-               udelay (SMC_PHY_CLOCK_DELAY);
-               bits[i] |= SMC_inw (MII_REG) & MII_MDI;
-       }
-
-       /* Return to idle state */
-       /* Set clock to low, data to low, and output tristated */
-       SMC_outw (mii_reg, MII_REG);
-       udelay (SMC_PHY_CLOCK_DELAY);
-
-       /* Restore original bank select */
-       SMC_SELECT_BANK (oldBank);
-
-       /* Recover input data */
-       phydata = 0;
-       for (i = 0; i < 16; ++i) {
-               phydata <<= 1;
-
-               if (bits[input_idx++] & MII_MDI)
-                       phydata |= 0x0001;
-       }
-
-#if (SMC_DEBUG > 2 )
-       printf ("smc_read_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n",
-               phyaddr, phyreg, phydata);
-       smc_dump_mii_stream (bits, sizeof bits);
-#endif
-
-       return (phydata);
-}
-
-
-/*------------------------------------------------------------
- . Writes a register to the MII Management serial interface
- .-------------------------------------------------------------*/
-static void smc_write_phy_register (byte phyreg, word phydata)
-{
-       int oldBank;
-       int i;
-       word mask;
-       word mii_reg;
-       byte bits[65];
-       int clk_idx = 0;
-       byte phyaddr = SMC_PHY_ADDR;
-
-       /* 32 consecutive ones on MDO to establish sync */
-       for (i = 0; i < 32; ++i)
-               bits[clk_idx++] = MII_MDOE | MII_MDO;
-
-       /* Start code <01> */
-       bits[clk_idx++] = MII_MDOE;
-       bits[clk_idx++] = MII_MDOE | MII_MDO;
-
-       /* Write command <01> */
-       bits[clk_idx++] = MII_MDOE;
-       bits[clk_idx++] = MII_MDOE | MII_MDO;
-
-       /* Output the PHY address, msb first */
-       mask = (byte) 0x10;
-       for (i = 0; i < 5; ++i) {
-               if (phyaddr & mask)
-                       bits[clk_idx++] = MII_MDOE | MII_MDO;
-               else
-                       bits[clk_idx++] = MII_MDOE;
-
-               /* Shift to next lowest bit */
-               mask >>= 1;
-       }
-
-       /* Output the phy register number, msb first */
-       mask = (byte) 0x10;
-       for (i = 0; i < 5; ++i) {
-               if (phyreg & mask)
-                       bits[clk_idx++] = MII_MDOE | MII_MDO;
-               else
-                       bits[clk_idx++] = MII_MDOE;
-
-               /* Shift to next lowest bit */
-               mask >>= 1;
-       }
-
-       /* Tristate and turnaround (2 bit times) */
-       bits[clk_idx++] = 0;
-       bits[clk_idx++] = 0;
-
-       /* Write out 16 bits of data, msb first */
-       mask = 0x8000;
-       for (i = 0; i < 16; ++i) {
-               if (phydata & mask)
-                       bits[clk_idx++] = MII_MDOE | MII_MDO;
-               else
-                       bits[clk_idx++] = MII_MDOE;
-
-               /* Shift to next lowest bit */
-               mask >>= 1;
-       }
-
-       /* Final clock bit (tristate) */
-       bits[clk_idx++] = 0;
-
-       /* Save the current bank */
-       oldBank = SMC_inw (BANK_SELECT);
-
-       /* Select bank 3 */
-       SMC_SELECT_BANK (3);
-
-       /* Get the current MII register value */
-       mii_reg = SMC_inw (MII_REG);
-
-       /* Turn off all MII Interface bits */
-       mii_reg &= ~(MII_MDOE | MII_MCLK | MII_MDI | MII_MDO);
-
-       /* Clock all cycles */
-       for (i = 0; i < sizeof bits; ++i) {
-               /* Clock Low - output data */
-               SMC_outw (mii_reg | bits[i], MII_REG);
-               udelay (SMC_PHY_CLOCK_DELAY);
-
-
-               /* Clock Hi - input data */
-               SMC_outw (mii_reg | bits[i] | MII_MCLK, MII_REG);
-               udelay (SMC_PHY_CLOCK_DELAY);
-               bits[i] |= SMC_inw (MII_REG) & MII_MDI;
-       }
-
-       /* Return to idle state */
-       /* Set clock to low, data to low, and output tristated */
-       SMC_outw (mii_reg, MII_REG);
-       udelay (SMC_PHY_CLOCK_DELAY);
-
-       /* Restore original bank select */
-       SMC_SELECT_BANK (oldBank);
-
-#if (SMC_DEBUG > 2 )
-       printf ("smc_write_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n",
-               phyaddr, phyreg, phydata);
-       smc_dump_mii_stream (bits, sizeof bits);
-#endif
-}
-#endif /* !CONFIG_SMC91111_EXT_PHY */
-
-
-/*------------------------------------------------------------
- . Waits the specified number of milliseconds - kernel friendly
- .-------------------------------------------------------------*/
-#ifndef CONFIG_SMC91111_EXT_PHY
-static void smc_wait_ms(unsigned int ms)
-{
-       udelay(ms*1000);
-}
-#endif /* !CONFIG_SMC91111_EXT_PHY */
-
-
-/*------------------------------------------------------------
- . Configures the specified PHY using Autonegotiation. Calls
- . smc_phy_fixed() if the user has requested a certain config.
- .-------------------------------------------------------------*/
-#ifndef CONFIG_SMC91111_EXT_PHY
-static void smc_phy_configure ()
-{
-       int timeout;
-       byte phyaddr;
-       word my_phy_caps;       /* My PHY capabilities */
-       word my_ad_caps;        /* My Advertised capabilities */
-       word status = 0;        /*;my status = 0 */
-       int failed = 0;
-
-       PRINTK3 ("%s: smc_program_phy()\n", SMC_DEV_NAME);
-
-
-       /* Get the detected phy address */
-       phyaddr = SMC_PHY_ADDR;
-
-       /* Reset the PHY, setting all other bits to zero */
-       smc_write_phy_register (PHY_CNTL_REG, PHY_CNTL_RST);
-
-       /* Wait for the reset to complete, or time out */
-       timeout = 6;            /* Wait up to 3 seconds */
-       while (timeout--) {
-               if (!(smc_read_phy_register (PHY_CNTL_REG)
-                     & PHY_CNTL_RST)) {
-                       /* reset complete */
-                       break;
-               }
-
-               smc_wait_ms (500);      /* wait 500 millisecs */
-       }
-
-       if (timeout < 1) {
-               printf ("%s:PHY reset timed out\n", SMC_DEV_NAME);
-               goto smc_phy_configure_exit;
-       }
-
-       /* Read PHY Register 18, Status Output */
-       /* lp->lastPhy18 = smc_read_phy_register(PHY_INT_REG); */
-
-       /* Enable PHY Interrupts (for register 18) */
-       /* Interrupts listed here are disabled */
-       smc_write_phy_register (PHY_MASK_REG, 0xffff);
-
-       /* Configure the Receive/Phy Control register */
-       SMC_SELECT_BANK (0);
-       SMC_outw (RPC_DEFAULT, RPC_REG);
-
-       /* Copy our capabilities from PHY_STAT_REG to PHY_AD_REG */
-       my_phy_caps = smc_read_phy_register (PHY_STAT_REG);
-       my_ad_caps = PHY_AD_CSMA;       /* I am CSMA capable */
-
-       if (my_phy_caps & PHY_STAT_CAP_T4)
-               my_ad_caps |= PHY_AD_T4;
-
-       if (my_phy_caps & PHY_STAT_CAP_TXF)
-               my_ad_caps |= PHY_AD_TX_FDX;
-
-       if (my_phy_caps & PHY_STAT_CAP_TXH)
-               my_ad_caps |= PHY_AD_TX_HDX;
-
-       if (my_phy_caps & PHY_STAT_CAP_TF)
-               my_ad_caps |= PHY_AD_10_FDX;
-
-       if (my_phy_caps & PHY_STAT_CAP_TH)
-               my_ad_caps |= PHY_AD_10_HDX;
-
-       /* Update our Auto-Neg Advertisement Register */
-       smc_write_phy_register (PHY_AD_REG, my_ad_caps);
-
-       /* Read the register back.  Without this, it appears that when */
-       /* auto-negotiation is restarted, sometimes it isn't ready and */
-       /* the link does not come up. */
-       smc_read_phy_register(PHY_AD_REG);
-
-       PRINTK2 ("%s: phy caps=%x\n", SMC_DEV_NAME, my_phy_caps);
-       PRINTK2 ("%s: phy advertised caps=%x\n", SMC_DEV_NAME, my_ad_caps);
-
-       /* Restart auto-negotiation process in order to advertise my caps */
-       smc_write_phy_register (PHY_CNTL_REG,
-                               PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST);
-
-       /* Wait for the auto-negotiation to complete.  This may take from */
-       /* 2 to 3 seconds. */
-       /* Wait for the reset to complete, or time out */
-       timeout = CONFIG_SMC_AUTONEG_TIMEOUT * 2;
-       while (timeout--) {
-
-               status = smc_read_phy_register (PHY_STAT_REG);
-               if (status & PHY_STAT_ANEG_ACK) {
-                       /* auto-negotiate complete */
-                       break;
-               }
-
-               smc_wait_ms (500);      /* wait 500 millisecs */
-
-               /* Restart auto-negotiation if remote fault */
-               if (status & PHY_STAT_REM_FLT) {
-                       printf ("%s: PHY remote fault detected\n",
-                               SMC_DEV_NAME);
-
-                       /* Restart auto-negotiation */
-                       printf ("%s: PHY restarting auto-negotiation\n",
-                               SMC_DEV_NAME);
-                       smc_write_phy_register (PHY_CNTL_REG,
-                                               PHY_CNTL_ANEG_EN |
-                                               PHY_CNTL_ANEG_RST |
-                                               PHY_CNTL_SPEED |
-                                               PHY_CNTL_DPLX);
-               }
-       }
-
-       if (timeout < 1) {
-               printf ("%s: PHY auto-negotiate timed out\n", SMC_DEV_NAME);
-               failed = 1;
-       }
-
-       /* Fail if we detected an auto-negotiate remote fault */
-       if (status & PHY_STAT_REM_FLT) {
-               printf ("%s: PHY remote fault detected\n", SMC_DEV_NAME);
-               failed = 1;
-       }
-
-       /* Re-Configure the Receive/Phy Control register */
-       SMC_outw (RPC_DEFAULT, RPC_REG);
-
-smc_phy_configure_exit:        ;
-
-}
-#endif /* !CONFIG_SMC91111_EXT_PHY */
-
-
-#if SMC_DEBUG > 2
-static void print_packet( byte * buf, int length )
-{
-       int i;
-       int remainder;
-       int lines;
-
-       printf("Packet of length %d \n", length );
-
-#if SMC_DEBUG > 3
-       lines = length / 16;
-       remainder = length % 16;
-
-       for ( i = 0; i < lines ; i ++ ) {
-               int cur;
-
-               for ( cur = 0; cur < 8; cur ++ ) {
-                       byte a, b;
-
-                       a = *(buf ++ );
-                       b = *(buf ++ );
-                       printf("%02x%02x ", a, b );
-               }
-               printf("\n");
-       }
-       for ( i = 0; i < remainder/2 ; i++ ) {
-               byte a, b;
-
-               a = *(buf ++ );
-               b = *(buf ++ );
-               printf("%02x%02x ", a, b );
-       }
-       printf("\n");
-#endif
-}
-#endif
-
-int eth_init(bd_t *bd) {
-#ifdef SHARED_RESOURCES
-       swap_to(ETHERNET);
-#endif
-       return (smc_open(bd));
-}
-
-void eth_halt() {
-       smc_close();
-}
-
-int eth_rx() {
-       return smc_rcv();
-}
-
-int eth_send(volatile void *packet, int length) {
-       return smc_send_packet(packet, length);
-}
-
-int smc_get_ethaddr (bd_t * bd)
-{
-       int env_size, rom_valid, env_present = 0, reg;
-       char *s = NULL, *e, es[] = "11:22:33:44:55:66";
-       char s_env_mac[64];
-       uchar v_env_mac[6], v_rom_mac[6], *v_mac;
-
-       env_size = getenv_r ("ethaddr", s_env_mac, sizeof (s_env_mac));
-       if ((env_size > 0) && (env_size < sizeof (es))) {       /* exit if env is bad */
-               printf ("\n*** ERROR: ethaddr is not set properly!!\n");
-               return (-1);
-       }
-
-       if (env_size > 0) {
-               env_present = 1;
-               s = s_env_mac;
-       }
-
-       for (reg = 0; reg < 6; ++reg) { /* turn string into mac value */
-               v_env_mac[reg] = s ? simple_strtoul (s, &e, 16) : 0;
-               if (s)
-                       s = (*e) ? e + 1 : e;
-       }
-
-       rom_valid = get_rom_mac (v_rom_mac);    /* get ROM mac value if any */
-
-       if (!env_present) {     /* if NO env */
-               if (rom_valid) {        /* but ROM is valid */
-                       v_mac = v_rom_mac;
-                       sprintf (s_env_mac, "%02X:%02X:%02X:%02X:%02X:%02X",
-                                v_mac[0], v_mac[1], v_mac[2], v_mac[3],
-                                v_mac[4], v_mac[5]);
-                       setenv ("ethaddr", s_env_mac);
-               } else {        /* no env, bad ROM */
-                       printf ("\n*** ERROR: ethaddr is NOT set !!\n");
-                       return (-1);
-               }
-       } else {                /* good env, don't care ROM */
-               v_mac = v_env_mac;      /* always use a good env over a ROM */
-       }
-
-       if (env_present && rom_valid) { /* if both env and ROM are good */
-               if (memcmp (v_env_mac, v_rom_mac, 6) != 0) {
-                       printf ("\nWarning: MAC addresses don't match:\n");
-                       printf ("\tHW MAC address:  "
-                               "%02X:%02X:%02X:%02X:%02X:%02X\n",
-                               v_rom_mac[0], v_rom_mac[1],
-                               v_rom_mac[2], v_rom_mac[3],
-                               v_rom_mac[4], v_rom_mac[5] );
-                       printf ("\t\"ethaddr\" value: "
-                               "%02X:%02X:%02X:%02X:%02X:%02X\n",
-                               v_env_mac[0], v_env_mac[1],
-                               v_env_mac[2], v_env_mac[3],
-                               v_env_mac[4], v_env_mac[5]) ;
-                       debug ("### Set MAC addr from environment\n");
-               }
-       }
-       memcpy (bd->bi_enetaddr, v_mac, 6);     /* update global address to match env (allows env changing) */
-       smc_set_mac_addr ((uchar *)v_mac);      /* use old function to update smc default */
-       PRINTK("Using MAC Address %02X:%02X:%02X:%02X:%02X:%02X\n", v_mac[0], v_mac[1],
-               v_mac[2], v_mac[3], v_mac[4], v_mac[5]);
-       return (0);
-}
-
-int get_rom_mac (uchar *v_rom_mac)
-{
-#ifdef HARDCODE_MAC    /* used for testing or to supress run time warnings */
-       char hw_mac_addr[] = { 0x02, 0x80, 0xad, 0x20, 0x31, 0xb8 };
-
-       memcpy (v_rom_mac, hw_mac_addr, 6);
-       return (1);
-#else
-       int i;
-       int valid_mac = 0;
-
-       SMC_SELECT_BANK (1);
-       for (i=0; i<6; i++)
-       {
-               v_rom_mac[i] = SMC_inb ((ADDR0_REG + i));
-               valid_mac |= v_rom_mac[i];
-       }
-
-       return (valid_mac ? 1 : 0);
-#endif
-}
-#endif /* CONFIG_DRIVER_SMC91111 */
diff --git a/drivers/smc91111.h b/drivers/smc91111.h
deleted file mode 100644 (file)
index d03cbc3..0000000
+++ /dev/null
@@ -1,719 +0,0 @@
-/*------------------------------------------------------------------------
- . smc91111.h - macros for the LAN91C111 Ethernet Driver
- .
- . (C) Copyright 2002
- . Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- . Rolf Offermanns <rof@sysgo.de>
- . Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
- .       Developed by Simple Network Magic Corporation (SNMC)
- . Copyright (C) 1996 by Erik Stahlman (ES)
- .
- . This program is free software; you can redistribute it and/or modify
- . it under the terms of the GNU General Public License as published by
- . the Free Software Foundation; either version 2 of the License, or
- . (at your option) any later version.
- .
- . This program is distributed in the hope that it will be useful,
- . but WITHOUT ANY WARRANTY; without even the implied warranty of
- . MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- . GNU General Public License for more details.
- .
- . You should have received a copy of the GNU General Public License
- . along with this program; if not, write to the Free Software
- . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- .
- . This file contains register information and access macros for
- . the LAN91C111 single chip ethernet controller.  It is a modified
- . version of the smc9194.h file.
- .
- . Information contained in this file was obtained from the LAN91C111
- . manual from SMC.  To get a copy, if you really want one, you can find
- . information under www.smsc.com.
- .
- . Authors
- .     Erik Stahlman                           ( erik@vt.edu )
- .     Daris A Nevil                           ( dnevil@snmc.com )
- .
- . History
- . 03/16/01            Daris A Nevil   Modified for use with LAN91C111 device
- .
- ---------------------------------------------------------------------------*/
-#ifndef _SMC91111_H_
-#define _SMC91111_H_
-
-#include <asm/types.h>
-#include <config.h>
-
-/*
- * This function may be called by the board specific initialisation code
- * in order to override the default mac address.
- */
-
-void smc_set_mac_addr (const unsigned char *addr);
-
-
-/* I want some simple types */
-
-typedef unsigned char                  byte;
-typedef unsigned short                 word;
-typedef unsigned long int              dword;
-
-/*
- . DEBUGGING LEVELS
- .
- . 0 for normal operation
- . 1 for slightly more details
- . >2 for various levels of increasingly useless information
- .    2 for interrupt tracking, status flags
- .    3 for packet info
- .    4 for complete packet dumps
-*/
-/*#define SMC_DEBUG 0 */
-
-/* Because of bank switching, the LAN91xxx uses only 16 I/O ports */
-
-#define        SMC_IO_EXTENT   16
-
-#ifdef CONFIG_PXA250
-
-#ifdef CONFIG_XSENGINE
-#define        SMC_inl(r)      (*((volatile dword *)(SMC_BASE_ADDRESS+(r<<1))))
-#define        SMC_inw(r)      (*((volatile word *)(SMC_BASE_ADDRESS+(r<<1))))
-#define SMC_inb(p)     ({ \
-       unsigned int __p = (unsigned int)(SMC_BASE_ADDRESS + (p<<1)); \
-       unsigned int __v = *(volatile unsigned short *)((__p) & ~2); \
-       if (__p & 2) __v >>= 8; \
-       else __v &= 0xff; \
-       __v; })
-#elif defined(CONFIG_XAENIAX)
-#define SMC_inl(r)     (*((volatile dword *)(SMC_BASE_ADDRESS+(r))))
-#define SMC_inw(z)     ({ \
-       unsigned int __p = (unsigned int)(SMC_BASE_ADDRESS + (z)); \
-       unsigned int __v = *(volatile unsigned int *)((__p) & ~3); \
-       if (__p & 3) __v >>= 16; \
-       else __v &= 0xffff; \
-       __v; })
-#define SMC_inb(p)     ({ \
-       unsigned int ___v = SMC_inw((p) & ~1); \
-       if (p & 1) ___v >>= 8; \
-       else ___v &= 0xff; \
-       ___v; })
-#else
-#define        SMC_inl(r)      (*((volatile dword *)(SMC_BASE_ADDRESS+(r))))
-#define        SMC_inw(r)      (*((volatile word *)(SMC_BASE_ADDRESS+(r))))
-#define SMC_inb(p)     ({ \
-       unsigned int __p = (unsigned int)(SMC_BASE_ADDRESS + (p)); \
-       unsigned int __v = *(volatile unsigned short *)((__p) & ~1); \
-       if (__p & 1) __v >>= 8; \
-       else __v &= 0xff; \
-       __v; })
-#endif
-
-#ifdef CONFIG_XSENGINE
-#define        SMC_outl(d,r)   (*((volatile dword *)(SMC_BASE_ADDRESS+(r<<1))) = d)
-#define        SMC_outw(d,r)   (*((volatile word *)(SMC_BASE_ADDRESS+(r<<1))) = d)
-#elif defined (CONFIG_XAENIAX)
-#define SMC_outl(d,r)  (*((volatile dword *)(SMC_BASE_ADDRESS+(r))) = d)
-#define SMC_outw(d,p)  ({ \
-       dword __dwo = SMC_inl((p) & ~3); \
-       dword __dwn = (word)(d); \
-       __dwo &= ((p) & 3) ? 0x0000ffff : 0xffff0000; \
-       __dwo |= ((p) & 3) ? __dwn << 16 : __dwn; \
-       SMC_outl(__dwo, (p) & ~3); \
-})
-#else
-#define        SMC_outl(d,r)   (*((volatile dword *)(SMC_BASE_ADDRESS+(r))) = d)
-#define        SMC_outw(d,r)   (*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d)
-#endif
-
-#define        SMC_outb(d,r)   ({      word __d = (byte)(d);  \
-                               word __w = SMC_inw((r)&~1);  \
-                               __w &= ((r)&1) ? 0x00FF : 0xFF00;  \
-                               __w |= ((r)&1) ? __d<<8 : __d;  \
-                               SMC_outw(__w,(r)&~1);  \
-                       })
-
-#define SMC_outsl(r,b,l)       ({      int __i; \
-                                       dword *__b2; \
-                                       __b2 = (dword *) b; \
-                                       for (__i = 0; __i < l; __i++) { \
-                                           SMC_outl( *(__b2 + __i), r); \
-                                       } \
-                               })
-
-#define SMC_outsw(r,b,l)       ({      int __i; \
-                                       word *__b2; \
-                                       __b2 = (word *) b; \
-                                       for (__i = 0; __i < l; __i++) { \
-                                           SMC_outw( *(__b2 + __i), r); \
-                                       } \
-                               })
-
-#define SMC_insl(r,b,l)        ({      int __i ;  \
-                                       dword *__b2;  \
-                                       __b2 = (dword *) b;  \
-                                       for (__i = 0; __i < l; __i++) {  \
-                                         *(__b2 + __i) = SMC_inl(r);  \
-                                         SMC_inl(0);  \
-                                       };  \
-                               })
-
-#define SMC_insw(r,b,l)        ({      int __i ;  \
-                                       word *__b2;  \
-                                       __b2 = (word *) b;  \
-                                       for (__i = 0; __i < l; __i++) {  \
-                                         *(__b2 + __i) = SMC_inw(r);  \
-                                         SMC_inw(0);  \
-                                       };  \
-                               })
-
-#define SMC_insb(r,b,l)        ({      int __i ;  \
-                                       byte *__b2;  \
-                                       __b2 = (byte *) b;  \
-                                       for (__i = 0; __i < l; __i++) {  \
-                                         *(__b2 + __i) = SMC_inb(r);  \
-                                         SMC_inb(0);  \
-                                       };  \
-                               })
-
-#else /* if not CONFIG_PXA250 */
-
-#ifndef CONFIG_SMC_USE_IOFUNCS /* these macros don't work on some boards */
-/*
- * We have only 16 Bit PCMCIA access on Socket 0
- */
-
-#ifdef CONFIG_ADNPESC1
-#define        SMC_inw(r)      (*((volatile word *)(SMC_BASE_ADDRESS+((r)<<1))))
-#elif CONFIG_BLACKFIN
-#define        SMC_inw(r)      ({ word __v = (*((volatile word *)(SMC_BASE_ADDRESS+(r)))); asm("ssync;"); __v;})
-#else
-#define        SMC_inw(r)      (*((volatile word *)(SMC_BASE_ADDRESS+(r))))
-#endif
-#define  SMC_inb(r)    (((r)&1) ? SMC_inw((r)&~1)>>8 : SMC_inw(r)&0xFF)
-
-#ifdef CONFIG_ADNPESC1
-#define        SMC_outw(d,r)   (*((volatile word *)(SMC_BASE_ADDRESS+((r)<<1))) = d)
-#elif CONFIG_BLACKFIN
-#define        SMC_outw(d,r)   {(*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d);asm("ssync;");}
-#else
-#define        SMC_outw(d,r)   (*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d)
-#endif
-#define        SMC_outb(d,r)   ({      word __d = (byte)(d);  \
-                               word __w = SMC_inw((r)&~1);  \
-                               __w &= ((r)&1) ? 0x00FF : 0xFF00;  \
-                               __w |= ((r)&1) ? __d<<8 : __d;  \
-                               SMC_outw(__w,(r)&~1);  \
-                       })
-#if 0
-#define        SMC_outsw(r,b,l)        outsw(SMC_BASE_ADDRESS+(r), (b), (l))
-#else
-#define SMC_outsw(r,b,l)       ({      int __i; \
-                                       word *__b2; \
-                                       __b2 = (word *) b; \
-                                       for (__i = 0; __i < l; __i++) { \
-                                           SMC_outw( *(__b2 + __i), r); \
-                                       } \
-                               })
-#endif
-
-#if 0
-#define        SMC_insw(r,b,l)         insw(SMC_BASE_ADDRESS+(r), (b), (l))
-#else
-#define SMC_insw(r,b,l)        ({      int __i ;  \
-                                       word *__b2;  \
-                                       __b2 = (word *) b;  \
-                                       for (__i = 0; __i < l; __i++) {  \
-                                         *(__b2 + __i) = SMC_inw(r);  \
-                                         SMC_inw(0);  \
-                                       };  \
-                               })
-#endif
-
-#endif  /* CONFIG_SMC_USE_IOFUNCS */
-
-#if defined(CONFIG_SMC_USE_32_BIT)
-
-#ifdef CONFIG_XSENGINE
-#define        SMC_inl(r)      (*((volatile dword *)(SMC_BASE_ADDRESS+(r<<1))))
-#else
-#define        SMC_inl(r)      (*((volatile dword *)(SMC_BASE_ADDRESS+(r))))
-#endif
-
-#define SMC_insl(r,b,l)        ({      int __i ;  \
-                                       dword *__b2;  \
-                                       __b2 = (dword *) b;  \
-                                       for (__i = 0; __i < l; __i++) {  \
-                                         *(__b2 + __i) = SMC_inl(r);  \
-                                         SMC_inl(0);  \
-                                       };  \
-                               })
-
-#ifdef CONFIG_XSENGINE
-#define        SMC_outl(d,r)   (*((volatile dword *)(SMC_BASE_ADDRESS+(r<<1))) = d)
-#else
-#define        SMC_outl(d,r)   (*((volatile dword *)(SMC_BASE_ADDRESS+(r))) = d)
-#endif
-#define SMC_outsl(r,b,l)       ({      int __i; \
-                                       dword *__b2; \
-                                       __b2 = (dword *) b; \
-                                       for (__i = 0; __i < l; __i++) { \
-                                           SMC_outl( *(__b2 + __i), r); \
-                                       } \
-                               })
-
-#endif /* CONFIG_SMC_USE_32_BIT */
-
-#endif
-
-/*---------------------------------------------------------------
- .
- . A description of the SMSC registers is probably in order here,
- . although for details, the SMC datasheet is invaluable.
- .
- . Basically, the chip has 4 banks of registers ( 0 to 3 ), which
- . are accessed by writing a number into the BANK_SELECT register
- . ( I also use a SMC_SELECT_BANK macro for this ).
- .
- . The banks are configured so that for most purposes, bank 2 is all
- . that is needed for simple run time tasks.
- -----------------------------------------------------------------------*/
-
-/*
- . Bank Select Register:
- .
- .             yyyy yyyy 0000 00xx
- .             xx              = bank number
- .             yyyy yyyy       = 0x33, for identification purposes.
-*/
-#define        BANK_SELECT             14
-
-/* Transmit Control Register */
-/* BANK 0  */
-#define        TCR_REG         0x0000  /* transmit control register */
-#define TCR_ENABLE     0x0001  /* When 1 we can transmit */
-#define TCR_LOOP       0x0002  /* Controls output pin LBK */
-#define TCR_FORCOL     0x0004  /* When 1 will force a collision */
-#define TCR_PAD_EN     0x0080  /* When 1 will pad tx frames < 64 bytes w/0 */
-#define TCR_NOCRC      0x0100  /* When 1 will not append CRC to tx frames */
-#define TCR_MON_CSN    0x0400  /* When 1 tx monitors carrier */
-#define TCR_FDUPLX     0x0800  /* When 1 enables full duplex operation */
-#define TCR_STP_SQET   0x1000  /* When 1 stops tx if Signal Quality Error */
-#define        TCR_EPH_LOOP    0x2000  /* When 1 enables EPH block loopback */
-#define        TCR_SWFDUP      0x8000  /* When 1 enables Switched Full Duplex mode */
-
-#define        TCR_CLEAR       0       /* do NOTHING */
-/* the default settings for the TCR register : */
-/* QUESTION: do I want to enable padding of short packets ? */
-#define        TCR_DEFAULT     TCR_ENABLE
-
-
-/* EPH Status Register */
-/* BANK 0  */
-#define EPH_STATUS_REG 0x0002
-#define ES_TX_SUC      0x0001  /* Last TX was successful */
-#define ES_SNGL_COL    0x0002  /* Single collision detected for last tx */
-#define ES_MUL_COL     0x0004  /* Multiple collisions detected for last tx */
-#define ES_LTX_MULT    0x0008  /* Last tx was a multicast */
-#define ES_16COL       0x0010  /* 16 Collisions Reached */
-#define ES_SQET                0x0020  /* Signal Quality Error Test */
-#define ES_LTXBRD      0x0040  /* Last tx was a broadcast */
-#define ES_TXDEFR      0x0080  /* Transmit Deferred */
-#define ES_LATCOL      0x0200  /* Late collision detected on last tx */
-#define ES_LOSTCARR    0x0400  /* Lost Carrier Sense */
-#define ES_EXC_DEF     0x0800  /* Excessive Deferral */
-#define ES_CTR_ROL     0x1000  /* Counter Roll Over indication */
-#define ES_LINK_OK     0x4000  /* Driven by inverted value of nLNK pin */
-#define ES_TXUNRN      0x8000  /* Tx Underrun */
-
-
-/* Receive Control Register */
-/* BANK 0  */
-#define        RCR_REG         0x0004
-#define        RCR_RX_ABORT    0x0001  /* Set if a rx frame was aborted */
-#define        RCR_PRMS        0x0002  /* Enable promiscuous mode */
-#define        RCR_ALMUL       0x0004  /* When set accepts all multicast frames */
-#define RCR_RXEN       0x0100  /* IFF this is set, we can receive packets */
-#define        RCR_STRIP_CRC   0x0200  /* When set strips CRC from rx packets */
-#define        RCR_ABORT_ENB   0x0200  /* When set will abort rx on collision */
-#define        RCR_FILT_CAR    0x0400  /* When set filters leading 12 bit s of carrier */
-#define RCR_SOFTRST    0x8000  /* resets the chip */
-
-/* the normal settings for the RCR register : */
-#define        RCR_DEFAULT     (RCR_STRIP_CRC | RCR_RXEN)
-#define RCR_CLEAR      0x0     /* set it to a base state */
-
-/* Counter Register */
-/* BANK 0  */
-#define        COUNTER_REG     0x0006
-
-/* Memory Information Register */
-/* BANK 0  */
-#define        MIR_REG         0x0008
-
-/* Receive/Phy Control Register */
-/* BANK 0  */
-#define        RPC_REG         0x000A
-#define        RPC_SPEED       0x2000  /* When 1 PHY is in 100Mbps mode. */
-#define        RPC_DPLX        0x1000  /* When 1 PHY is in Full-Duplex Mode */
-#define        RPC_ANEG        0x0800  /* When 1 PHY is in Auto-Negotiate Mode */
-#define        RPC_LSXA_SHFT   5       /* Bits to shift LS2A,LS1A,LS0A to lsb */
-#define        RPC_LSXB_SHFT   2       /* Bits to get LS2B,LS1B,LS0B to lsb */
-#define RPC_LED_100_10 (0x00)  /* LED = 100Mbps OR's with 10Mbps link detect */
-#define RPC_LED_RES    (0x01)  /* LED = Reserved */
-#define RPC_LED_10     (0x02)  /* LED = 10Mbps link detect */
-#define RPC_LED_FD     (0x03)  /* LED = Full Duplex Mode */
-#define RPC_LED_TX_RX  (0x04)  /* LED = TX or RX packet occurred */
-#define RPC_LED_100    (0x05)  /* LED = 100Mbps link dectect */
-#define RPC_LED_TX     (0x06)  /* LED = TX packet occurred */
-#define RPC_LED_RX     (0x07)  /* LED = RX packet occurred */
-#if defined(CONFIG_DK1C20) || defined(CONFIG_DK1S10)
-/* buggy schematic: LEDa -> yellow, LEDb --> green */
-#define RPC_DEFAULT    ( RPC_SPEED | RPC_DPLX | RPC_ANEG       \
-                       | (RPC_LED_TX_RX << RPC_LSXA_SHFT)      \
-                       | (RPC_LED_100_10 << RPC_LSXB_SHFT)     )
-#elif defined(CONFIG_ADNPESC1)
-/* SSV ADNP/ESC1 has only one LED: LEDa -> Rx/Tx indicator */
-#define RPC_DEFAULT    ( RPC_SPEED | RPC_DPLX | RPC_ANEG       \
-                       | (RPC_LED_TX_RX << RPC_LSXA_SHFT)      \
-                       | (RPC_LED_100_10 << RPC_LSXB_SHFT)     )
-#else
-/* SMSC reference design: LEDa --> green, LEDb --> yellow */
-#define RPC_DEFAULT    ( RPC_SPEED | RPC_DPLX | RPC_ANEG       \
-                       | (RPC_LED_100_10 << RPC_LSXA_SHFT)     \
-                       | (RPC_LED_TX_RX << RPC_LSXB_SHFT)      )
-#endif
-
-/* Bank 0 0x000C is reserved */
-
-/* Bank Select Register */
-/* All Banks */
-#define BSR_REG        0x000E
-
-
-/* Configuration Reg */
-/* BANK 1 */
-#define CONFIG_REG     0x0000
-#define CONFIG_EXT_PHY 0x0200  /* 1=external MII, 0=internal Phy */
-#define CONFIG_GPCNTRL 0x0400  /* Inverse value drives pin nCNTRL */
-#define CONFIG_NO_WAIT 0x1000  /* When 1 no extra wait states on ISA bus */
-#define CONFIG_EPH_POWER_EN 0x8000 /* When 0 EPH is placed into low power mode. */
-
-/* Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low */
-#define CONFIG_DEFAULT (CONFIG_EPH_POWER_EN)
-
-
-/* Base Address Register */
-/* BANK 1 */
-#define        BASE_REG        0x0002
-
-
-/* Individual Address Registers */
-/* BANK 1 */
-#define        ADDR0_REG       0x0004
-#define        ADDR1_REG       0x0006
-#define        ADDR2_REG       0x0008
-
-
-/* General Purpose Register */
-/* BANK 1 */
-#define        GP_REG          0x000A
-
-
-/* Control Register */
-/* BANK 1 */
-#define        CTL_REG         0x000C
-#define CTL_RCV_BAD    0x4000 /* When 1 bad CRC packets are received */
-#define CTL_AUTO_RELEASE 0x0800 /* When 1 tx pages are released automatically */
-#define        CTL_LE_ENABLE   0x0080 /* When 1 enables Link Error interrupt */
-#define        CTL_CR_ENABLE   0x0040 /* When 1 enables Counter Rollover interrupt */
-#define        CTL_TE_ENABLE   0x0020 /* When 1 enables Transmit Error interrupt */
-#define        CTL_EEPROM_SELECT 0x0004 /* Controls EEPROM reload & store */
-#define        CTL_RELOAD      0x0002 /* When set reads EEPROM into registers */
-#define        CTL_STORE       0x0001 /* When set stores registers into EEPROM */
-#define CTL_DEFAULT     (0x1A10) /* Autorelease enabled*/
-
-/* MMU Command Register */
-/* BANK 2 */
-#define MMU_CMD_REG    0x0000
-#define MC_BUSY                1       /* When 1 the last release has not completed */
-#define MC_NOP         (0<<5)  /* No Op */
-#define        MC_ALLOC        (1<<5)  /* OR with number of 256 byte packets */
-#define        MC_RESET        (2<<5)  /* Reset MMU to initial state */
-#define        MC_REMOVE       (3<<5)  /* Remove the current rx packet */
-#define MC_RELEASE     (4<<5)  /* Remove and release the current rx packet */
-#define MC_FREEPKT     (5<<5)  /* Release packet in PNR register */
-#define MC_ENQUEUE     (6<<5)  /* Enqueue the packet for transmit */
-#define MC_RSTTXFIFO   (7<<5)  /* Reset the TX FIFOs */
-
-
-/* Packet Number Register */
-/* BANK 2 */
-#define        PN_REG          0x0002
-
-
-/* Allocation Result Register */
-/* BANK 2 */
-#define        AR_REG          0x0003
-#define AR_FAILED      0x80    /* Alocation Failed */
-
-
-/* RX FIFO Ports Register */
-/* BANK 2 */
-#define RXFIFO_REG     0x0004  /* Must be read as a word */
-#define RXFIFO_REMPTY  0x8000  /* RX FIFO Empty */
-
-
-/* TX FIFO Ports Register */
-/* BANK 2 */
-#define TXFIFO_REG     RXFIFO_REG      /* Must be read as a word */
-#define TXFIFO_TEMPTY  0x80    /* TX FIFO Empty */
-
-
-/* Pointer Register */
-/* BANK 2 */
-#define PTR_REG                0x0006
-#define        PTR_RCV         0x8000 /* 1=Receive area, 0=Transmit area */
-#define        PTR_AUTOINC     0x4000 /* Auto increment the pointer on each access */
-#define PTR_READ       0x2000 /* When 1 the operation is a read */
-#define PTR_NOTEMPTY   0x0800 /* When 1 _do not_ write fifo DATA REG */
-
-
-/* Data Register */
-/* BANK 2 */
-#define        SMC91111_DATA_REG       0x0008
-
-
-/* Interrupt Status/Acknowledge Register */
-/* BANK 2 */
-#define        SMC91111_INT_REG        0x000C
-
-
-/* Interrupt Mask Register */
-/* BANK 2 */
-#define IM_REG         0x000D
-#define        IM_MDINT        0x80 /* PHY MI Register 18 Interrupt */
-#define        IM_ERCV_INT     0x40 /* Early Receive Interrupt */
-#define        IM_EPH_INT      0x20 /* Set by Etheret Protocol Handler section */
-#define        IM_RX_OVRN_INT  0x10 /* Set by Receiver Overruns */
-#define        IM_ALLOC_INT    0x08 /* Set when allocation request is completed */
-#define        IM_TX_EMPTY_INT 0x04 /* Set if the TX FIFO goes empty */
-#define        IM_TX_INT       0x02 /* Transmit Interrrupt */
-#define IM_RCV_INT     0x01 /* Receive Interrupt */
-
-
-/* Multicast Table Registers */
-/* BANK 3 */
-#define        MCAST_REG1      0x0000
-#define        MCAST_REG2      0x0002
-#define        MCAST_REG3      0x0004
-#define        MCAST_REG4      0x0006
-
-
-/* Management Interface Register (MII) */
-/* BANK 3 */
-#define        MII_REG         0x0008
-#define MII_MSK_CRS100 0x4000 /* Disables CRS100 detection during tx half dup */
-#define MII_MDOE       0x0008 /* MII Output Enable */
-#define MII_MCLK       0x0004 /* MII Clock, pin MDCLK */
-#define MII_MDI                0x0002 /* MII Input, pin MDI */
-#define MII_MDO                0x0001 /* MII Output, pin MDO */
-
-
-/* Revision Register */
-/* BANK 3 */
-#define        REV_REG         0x000A /* ( hi: chip id   low: rev # ) */
-
-
-/* Early RCV Register */
-/* BANK 3 */
-/* this is NOT on SMC9192 */
-#define        ERCV_REG        0x000C
-#define ERCV_RCV_DISCRD        0x0080 /* When 1 discards a packet being received */
-#define ERCV_THRESHOLD 0x001F /* ERCV Threshold Mask */
-
-/* External Register */
-/* BANK 7 */
-#define        EXT_REG         0x0000
-
-
-#define CHIP_9192      3
-#define CHIP_9194      4
-#define CHIP_9195      5
-#define CHIP_9196      6
-#define CHIP_91100     7
-#define CHIP_91100FD   8
-#define CHIP_91111FD   9
-
-#if 0
-static const char * chip_ids[ 15 ] =  {
-       NULL, NULL, NULL,
-       /* 3 */ "SMC91C90/91C92",
-       /* 4 */ "SMC91C94",
-       /* 5 */ "SMC91C95",
-       /* 6 */ "SMC91C96",
-       /* 7 */ "SMC91C100",
-       /* 8 */ "SMC91C100FD",
-       /* 9 */ "SMC91C111",
-       NULL, NULL,
-       NULL, NULL, NULL};
-#endif
-
-/*
- . Transmit status bits
-*/
-#define TS_SUCCESS 0x0001
-#define TS_LOSTCAR 0x0400
-#define TS_LATCOL  0x0200
-#define TS_16COL   0x0010
-
-/*
- . Receive status bits
-*/
-#define RS_ALGNERR     0x8000
-#define RS_BRODCAST    0x4000
-#define RS_BADCRC      0x2000
-#define RS_ODDFRAME    0x1000  /* bug: the LAN91C111 never sets this on receive */
-#define RS_TOOLONG     0x0800
-#define RS_TOOSHORT    0x0400
-#define RS_MULTICAST   0x0001
-#define RS_ERRORS      (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
-
-
-/* PHY Types */
-enum {
-       PHY_LAN83C183 = 1,      /* LAN91C111 Internal PHY */
-       PHY_LAN83C180
-};
-
-
-/* PHY Register Addresses (LAN91C111 Internal PHY) */
-
-/* PHY Control Register */
-#define PHY_CNTL_REG           0x00
-#define PHY_CNTL_RST           0x8000  /* 1=PHY Reset */
-#define PHY_CNTL_LPBK          0x4000  /* 1=PHY Loopback */
-#define PHY_CNTL_SPEED         0x2000  /* 1=100Mbps, 0=10Mpbs */
-#define PHY_CNTL_ANEG_EN       0x1000 /* 1=Enable Auto negotiation */
-#define PHY_CNTL_PDN           0x0800  /* 1=PHY Power Down mode */
-#define PHY_CNTL_MII_DIS       0x0400  /* 1=MII 4 bit interface disabled */
-#define PHY_CNTL_ANEG_RST      0x0200 /* 1=Reset Auto negotiate */
-#define PHY_CNTL_DPLX          0x0100  /* 1=Full Duplex, 0=Half Duplex */
-#define PHY_CNTL_COLTST                0x0080  /* 1= MII Colision Test */
-
-/* PHY Status Register */
-#define PHY_STAT_REG           0x01
-#define PHY_STAT_CAP_T4                0x8000  /* 1=100Base-T4 capable */
-#define PHY_STAT_CAP_TXF       0x4000  /* 1=100Base-X full duplex capable */
-#define PHY_STAT_CAP_TXH       0x2000  /* 1=100Base-X half duplex capable */
-#define PHY_STAT_CAP_TF                0x1000  /* 1=10Mbps full duplex capable */
-#define PHY_STAT_CAP_TH                0x0800  /* 1=10Mbps half duplex capable */
-#define PHY_STAT_CAP_SUPR      0x0040  /* 1=recv mgmt frames with not preamble */
-#define PHY_STAT_ANEG_ACK      0x0020  /* 1=ANEG has completed */
-#define PHY_STAT_REM_FLT       0x0010  /* 1=Remote Fault detected */
-#define PHY_STAT_CAP_ANEG      0x0008  /* 1=Auto negotiate capable */
-#define PHY_STAT_LINK          0x0004  /* 1=valid link */
-#define PHY_STAT_JAB           0x0002  /* 1=10Mbps jabber condition */
-#define PHY_STAT_EXREG         0x0001  /* 1=extended registers implemented */
-
-/* PHY Identifier Registers */
-#define PHY_ID1_REG            0x02    /* PHY Identifier 1 */
-#define PHY_ID2_REG            0x03    /* PHY Identifier 2 */
-
-/* PHY Auto-Negotiation Advertisement Register */
-#define PHY_AD_REG             0x04
-#define PHY_AD_NP              0x8000  /* 1=PHY requests exchange of Next Page */
-#define PHY_AD_ACK             0x4000  /* 1=got link code word from remote */
-#define PHY_AD_RF              0x2000  /* 1=advertise remote fault */
-#define PHY_AD_T4              0x0200  /* 1=PHY is capable of 100Base-T4 */
-#define PHY_AD_TX_FDX          0x0100  /* 1=PHY is capable of 100Base-TX FDPLX */
-#define PHY_AD_TX_HDX          0x0080  /* 1=PHY is capable of 100Base-TX HDPLX */
-#define PHY_AD_10_FDX          0x0040  /* 1=PHY is capable of 10Base-T FDPLX */
-#define PHY_AD_10_HDX          0x0020  /* 1=PHY is capable of 10Base-T HDPLX */
-#define PHY_AD_CSMA            0x0001  /* 1=PHY is capable of 802.3 CMSA */
-
-/* PHY Auto-negotiation Remote End Capability Register */
-#define PHY_RMT_REG            0x05
-/* Uses same bit definitions as PHY_AD_REG */
-
-/* PHY Configuration Register 1 */
-#define PHY_CFG1_REG           0x10
-#define PHY_CFG1_LNKDIS                0x8000  /* 1=Rx Link Detect Function disabled */
-#define PHY_CFG1_XMTDIS                0x4000  /* 1=TP Transmitter Disabled */
-#define PHY_CFG1_XMTPDN                0x2000  /* 1=TP Transmitter Powered Down */
-#define PHY_CFG1_BYPSCR                0x0400  /* 1=Bypass scrambler/descrambler */
-#define PHY_CFG1_UNSCDS                0x0200  /* 1=Unscramble Idle Reception Disable */
-#define PHY_CFG1_EQLZR         0x0100  /* 1=Rx Equalizer Disabled */
-#define PHY_CFG1_CABLE         0x0080  /* 1=STP(150ohm), 0=UTP(100ohm) */
-#define PHY_CFG1_RLVL0         0x0040  /* 1=Rx Squelch level reduced by 4.5db */
-#define PHY_CFG1_TLVL_SHIFT    2       /* Transmit Output Level Adjust */
-#define PHY_CFG1_TLVL_MASK     0x003C
-#define PHY_CFG1_TRF_MASK      0x0003  /* Transmitter Rise/Fall time */
-
-
-/* PHY Configuration Register 2 */
-#define PHY_CFG2_REG           0x11
-#define PHY_CFG2_APOLDIS       0x0020  /* 1=Auto Polarity Correction disabled */
-#define PHY_CFG2_JABDIS                0x0010  /* 1=Jabber disabled */
-#define PHY_CFG2_MREG          0x0008  /* 1=Multiple register access (MII mgt) */
-#define PHY_CFG2_INTMDIO       0x0004  /* 1=Interrupt signaled with MDIO pulseo */
-
-/* PHY Status Output (and Interrupt status) Register */
-#define PHY_INT_REG            0x12    /* Status Output (Interrupt Status) */
-#define PHY_INT_INT            0x8000  /* 1=bits have changed since last read */
-#define        PHY_INT_LNKFAIL         0x4000  /* 1=Link Not detected */
-#define PHY_INT_LOSSSYNC       0x2000  /* 1=Descrambler has lost sync */
-#define PHY_INT_CWRD           0x1000  /* 1=Invalid 4B5B code detected on rx */
-#define PHY_INT_SSD            0x0800  /* 1=No Start Of Stream detected on rx */
-#define PHY_INT_ESD            0x0400  /* 1=No End Of Stream detected on rx */
-#define PHY_INT_RPOL           0x0200  /* 1=Reverse Polarity detected */
-#define PHY_INT_JAB            0x0100  /* 1=Jabber detected */
-#define PHY_INT_SPDDET         0x0080  /* 1=100Base-TX mode, 0=10Base-T mode */
-#define PHY_INT_DPLXDET                0x0040  /* 1=Device in Full Duplex */
-
-/* PHY Interrupt/Status Mask Register */
-#define PHY_MASK_REG           0x13    /* Interrupt Mask */
-/* Uses the same bit definitions as PHY_INT_REG */
-
-
-/*-------------------------------------------------------------------------
- .  I define some macros to make it easier to do somewhat common
- . or slightly complicated, repeated tasks.
- --------------------------------------------------------------------------*/
-
-/* select a register bank, 0 to 3  */
-
-#define SMC_SELECT_BANK(x)  { SMC_outw( x, BANK_SELECT ); }
-
-/* this enables an interrupt in the interrupt mask register */
-#define SMC_ENABLE_INT(x) {\
-               unsigned char mask;\
-               SMC_SELECT_BANK(2);\
-               mask = SMC_inb( IM_REG );\
-               mask |= (x);\
-               SMC_outb( mask, IM_REG ); \
-}
-
-/* this disables an interrupt from the interrupt mask register */
-
-#define SMC_DISABLE_INT(x) {\
-               unsigned char mask;\
-               SMC_SELECT_BANK(2);\
-               mask = SMC_inb( IM_REG );\
-               mask &= ~(x);\
-               SMC_outb( mask, IM_REG ); \
-}
-
-/*----------------------------------------------------------------------
- . Define the interrupts that I want to receive from the card
- .
- . I want:
- .  IM_EPH_INT, for nasty errors
- .  IM_RCV_INT, for happy received packets
- .  IM_RX_OVRN_INT, because I have to kick the receiver
- .  IM_MDINT, for PHY Register 18 Status Changes
- --------------------------------------------------------------------------*/
-#define SMC_INTERRUPT_MASK   (IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT | \
-       IM_MDINT)
-
-#endif  /* _SMC_91111_H_ */
diff --git a/drivers/smiLynxEM.c b/drivers/smiLynxEM.c
deleted file mode 100644 (file)
index 20f9beb..0000000
+++ /dev/null
@@ -1,858 +0,0 @@
-/*
- * (C) Copyright 1997-2002 ELTEC Elektronik AG
- * Frank Gottschling <fgottschling@eltec.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.        See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * smiLynxEM.c
- *
- * Silicon Motion graphic interface for sm810/sm710/sm712 accelerator
- *
- * modification history
- * --------------------
- * 04-18-2002 Rewritten for U-Boot <fgottschling@eltec.de>.
- *
- * 18-03-2004 - Unify videomodes handling with the ct69000
- *            - The video output can be set via the variable "videoout"
- *              in the environment.
- *              videoout=1 output on LCD
- *              videoout=2 output on CRT (default value)
- *                     <p.aubert@staubli.com>
- */
-
-#include <common.h>
-
-#if defined(CONFIG_VIDEO_SMI_LYNXEM)
-
-#include <pci.h>
-#include <video_fb.h>
-#include "videomodes.h"
-/*
- * Export Graphic Device
- */
-GraphicDevice smi;
-
-/*
- * SMI 710/712 have 4MB internal RAM; SMI 810 2MB internal + 2MB external
- */
-#define VIDEO_MEM_SIZE 0x400000
-
-
-/*
- * ISA mapped regs
- */
-#define SMI_INDX_C4            (pGD->isaBase + 0x03c4)    /* index reg */
-#define SMI_DATA_C5            (pGD->isaBase + 0x03c5)    /* data reg */
-#define SMI_INDX_D4            (pGD->isaBase + 0x03d4)    /* index reg */
-#define SMI_DATA_D5            (pGD->isaBase + 0x03d5)    /* data reg */
-#define SMI_ISR1               (pGD->isaBase + 0x03ca)
-#define SMI_INDX_CE            (pGD->isaBase + 0x03ce)    /* index reg */
-#define SMI_DATA_CF            (pGD->isaBase + 0x03cf)    /* data reg */
-#define SMI_LOCK_REG           (pGD->isaBase + 0x03c3)    /* unlock/lock ext crt reg */
-#define SMI_MISC_REG           (pGD->isaBase + 0x03c2)    /* misc reg */
-#define SMI_LUT_MASK           (pGD->isaBase + 0x03c6)    /* lut mask reg */
-#define SMI_LUT_START          (pGD->isaBase + 0x03c8)    /* lut start index */
-#define SMI_LUT_RGB            (pGD->isaBase + 0x03c9)    /* lut colors auto incr.*/
-#define SMI_INDX_ATTR          (pGD->isaBase + 0x03c0)    /* attributes index reg */
-
-/*
- * Video processor control
- */
-typedef struct {
-       unsigned int   control;
-       unsigned int   colorKey;
-       unsigned int   colorKeyMask;
-       unsigned int   start;
-       unsigned short offset;
-       unsigned short width;
-       unsigned int   fifoPrio;
-       unsigned int   fifoERL;
-       unsigned int   YUVtoRGB;
-} SmiVideoProc;
-
-/*
- * Video window control
- */
-typedef struct {
-       unsigned short top;
-       unsigned short left;
-       unsigned short bottom;
-       unsigned short right;
-       unsigned int   srcStart;
-       unsigned short width;
-       unsigned short offset;
-       unsigned char  hStretch;
-       unsigned char  vStretch;
-} SmiVideoWin;
-
-/*
- * Capture port control
- */
-typedef struct {
-       unsigned int   control;
-       unsigned short topClip;
-       unsigned short leftClip;
-       unsigned short srcHeight;
-       unsigned short srcWidth;
-       unsigned int   srcBufStart1;
-       unsigned int   srcBufStart2;
-       unsigned short srcOffset;
-       unsigned short fifoControl;
-} SmiCapturePort;
-
-
-/*
- * Register values for common video modes
- */
-static char SMI_SCR[] = {
-       /* all modes */
-       0x10, 0xff, 0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x15, 0x90,
-       0x17, 0x20, 0x18, 0xb1, 0x19, 0x00,
-};
-static char SMI_EXT_CRT[] = {
-       0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
-       0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00,
-};
-static char SMI_ATTR [] = {
-       0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05,
-       0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b,
-       0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x41, 0x11, 0x00,
-       0x12, 0x0f, 0x13, 0x00, 0x14, 0x00,
-};
-static char SMI_GCR[18] = {
-       0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x40,
-       0x06, 0x05, 0x07, 0x0f, 0x08, 0xff,
-};
-static char SMI_SEQR[] = {
-       0x00, 0x00, 0x01, 0x01, 0x02, 0x0f, 0x03, 0x03, 0x04, 0x0e, 0x00, 0x03,
-};
-static char SMI_PCR [] = {
-       0x20, 0x04, 0x21, 0x30, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00,
-};
-static char SMI_MCR[] = {
-       0x60, 0x01, 0x61, 0x00,
-#ifdef CONFIG_HMI1001
-       0x62, 0x74, /* Memory type is not configured by pins on HMI1001 */
-#endif
-};
-
-static char SMI_HCR[] = {
-       0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
-       0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00,
-};
-
-
-/*******************************************************************************
- *
- * Write SMI ISA register
- */
-static void smiWrite (unsigned short index, char reg, char val)
-{
-       register GraphicDevice *pGD = (GraphicDevice *)&smi;
-
-       out8 ((pGD->isaBase + index), reg);
-       out8 ((pGD->isaBase + index + 1), val);
-}
-
-/*******************************************************************************
- *
- * Write a table of SMI ISA register
- */
-static void smiLoadRegs (
-       unsigned int iReg,
-       unsigned int dReg,
-       char         *regTab,
-       unsigned int tabSize
-       )
-{
-       register GraphicDevice *pGD  = (GraphicDevice *)&smi;
-       register int i;
-
-       for (i=0; i<tabSize; i+=2) {
-               if (iReg == SMI_INDX_ATTR) {
-                       /* Reset the Flip Flop */
-                       in8 (SMI_ISR1);
-                       out8 (iReg, regTab[i]);
-                       out8 (iReg, regTab[i+1]);
-               } else {
-                       out8 (iReg, regTab[i]);
-                       out8 (dReg, regTab[i+1]);
-               }
-       }
-}
-
-/*******************************************************************************
- *
- * Init capture port registers
- */
-static void smiInitCapturePort (void)
-{
-       SmiCapturePort smiCP = { 0x01400600, 0x30, 0x40, 480, 640, 0, 0, 2560, 6 };
-       register GraphicDevice *pGD  = (GraphicDevice *)&smi;
-       register SmiCapturePort *pCP = (SmiCapturePort *)&smiCP;
-
-       out32r ((pGD->cprBase + 0x0004), ((pCP->topClip<<16)   | pCP->leftClip));
-       out32r ((pGD->cprBase + 0x0008), ((pCP->srcHeight<<16) | pCP->srcWidth));
-       out32r ((pGD->cprBase + 0x000c), pCP->srcBufStart1/8);
-       out32r ((pGD->cprBase + 0x0010), pCP->srcBufStart2/8);
-       out32r ((pGD->cprBase + 0x0014), pCP->srcOffset/8);
-       out32r ((pGD->cprBase + 0x0018), pCP->fifoControl);
-       out32r ((pGD->cprBase + 0x0000), pCP->control);
-}
-
-
-/*******************************************************************************
- *
- * Init video processor registers
- */
-static void smiInitVideoProcessor (void)
-{
-       SmiVideoProc smiVP = { 0x100000, 0, 0, 0, 0, 1600, 0x1200543, 4, 0xededed };
-       SmiVideoWin  smiVW = { 0, 0, 599, 799, 0, 1600, 0, 0, 0 };
-       register GraphicDevice *pGD = (GraphicDevice *)&smi;
-       register SmiVideoProc  *pVP = (SmiVideoProc *)&smiVP;
-       register SmiVideoWin *pVWin = (SmiVideoWin *)&smiVW;
-
-       pVP->width    = pGD->plnSizeX * pGD->gdfBytesPP;
-       pVP->control |= pGD->gdfIndex << 16;
-       pVWin->bottom = pGD->winSizeY - 1;
-       pVWin->right  = pGD->winSizeX - 1;
-       pVWin->width  = pVP->width;
-
-       /* color key */
-       out32r ((pGD->vprBase + 0x0004), pVP->colorKey);
-
-       /* color key mask */
-       out32r ((pGD->vprBase + 0x0008), pVP->colorKeyMask);
-
-       /* data src start adrs */
-       out32r ((pGD->vprBase + 0x000c), pVP->start / 8);
-
-       /* data width and offset */
-       out32r ((pGD->vprBase + 0x0010),
-               ((pVP->offset   / 8 * pGD->gdfBytesPP) << 16) |
-               (pGD->plnSizeX / 8 * pGD->gdfBytesPP));
-
-       /* video window 1 */
-       out32r ((pGD->vprBase + 0x0014),
-               ((pVWin->top << 16) | pVWin->left));
-
-       out32r ((pGD->vprBase + 0x0018),
-               ((pVWin->bottom << 16) | pVWin->right));
-
-       out32r ((pGD->vprBase + 0x001c), pVWin->srcStart / 8);
-
-       out32r ((pGD->vprBase + 0x0020),
-               (((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
-
-       out32r ((pGD->vprBase + 0x0024),
-               (((pVWin->hStretch) << 8) | pVWin->vStretch));
-
-       /* video window 2 */
-       out32r ((pGD->vprBase + 0x0028),
-               ((pVWin->top << 16) | pVWin->left));
-
-       out32r ((pGD->vprBase + 0x002c),
-               ((pVWin->bottom << 16) | pVWin->right));
-
-       out32r ((pGD->vprBase + 0x0030),
-               pVWin->srcStart / 8);
-
-       out32r ((pGD->vprBase + 0x0034),
-               (((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
-
-       out32r ((pGD->vprBase + 0x0038),
-               (((pVWin->hStretch) << 8) | pVWin->vStretch));
-
-       /* fifo prio control */
-       out32r ((pGD->vprBase + 0x0054), pVP->fifoPrio);
-
-       /* fifo empty request levell */
-       out32r ((pGD->vprBase + 0x0058), pVP->fifoERL);
-
-       /* conversion constant */
-       out32r ((pGD->vprBase + 0x005c), pVP->YUVtoRGB);
-
-       /* vpr control word */
-       out32r ((pGD->vprBase + 0x0000), pVP->control);
-}
-
-/******************************************************************************
- *
- * Init drawing engine registers
- */
-static void smiInitDrawingEngine (void)
-{
-       GraphicDevice *pGD = (GraphicDevice *)&smi;
-       unsigned int val;
-
-       /* don't start now */
-       out32r ((pGD->dprBase + 0x000c), 0x000f0000);
-
-       /* set rop2 to copypen */
-       val = 0xffff3ff0 & in32r ((pGD->dprBase + 0x000c));
-       out32r ((pGD->dprBase + 0x000c), (val | 0x8000 | 0x0c));
-
-       /* set clip rect */
-       out32r ((pGD->dprBase + 0x002c), 0);
-       out32r ((pGD->dprBase + 0x0030),
-               ((pGD->winSizeY<<16) | pGD->winSizeX * pGD->gdfBytesPP ));
-
-       /* src row pitch */
-       val = 0xffff0000 & (in32r ((pGD->dprBase + 0x0010)));
-       out32r ((pGD->dprBase + 0x0010),
-               (val | pGD->plnSizeX * pGD->gdfBytesPP));
-
-       /* dst row pitch */
-       val = 0x0000ffff & (in32r ((pGD->dprBase + 0x0010)));
-       out32r ((pGD->dprBase + 0x0010),
-               (((pGD->plnSizeX * pGD->gdfBytesPP)<<16) | val));
-
-       /* window width src/dst */
-       out32r ((pGD->dprBase + 0x003c),
-               (((pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)<<16) |
-                (pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)));
-       out16r ((pGD->dprBase + 0x001e), 0x0000);
-
-       /* src base adrs */
-       out32r ((pGD->dprBase + 0x0040),
-               (((pGD->frameAdrs/8) & 0x000fffff)));
-
-       /* dst base adrs */
-       out32r ((pGD->dprBase + 0x0044),
-               (((pGD->frameAdrs/8) & 0x000fffff)));
-
-       /* foreground color */
-       out32r ((pGD->dprBase + 0x0014), pGD->fg);
-
-       /* background color */
-       out32r ((pGD->dprBase + 0x0018), pGD->bg);
-
-       /* xcolor */
-       out32r ((pGD->dprBase + 0x0020), 0x00ffffff);
-
-       /* xcolor mask */
-       out32r ((pGD->dprBase + 0x0024), 0x00ffffff);
-
-       /* bit mask */
-       out32r ((pGD->dprBase + 0x0028), 0x00ffffff);
-
-       /* load mono pattern */
-       out32r ((pGD->dprBase + 0x0034), 0);
-       out32r ((pGD->dprBase + 0x0038), 0);
-}
-
-static struct pci_device_id supported[] = {
-       { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_710 },
-       { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_712 },
-       { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_810 },
-       { }
-};
-
-/*****************************************************************************/
-static void smiLoadMsr (struct ctfb_res_modes *mode)
-{
-       unsigned char h_synch_high, v_synch_high;
-       register GraphicDevice *pGD  = (GraphicDevice *)&smi;
-
-       h_synch_high = (mode->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 0x40;  /* horizontal Synch High active */
-       v_synch_high = (mode->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 0x80; /* vertical Synch High active */
-       out8 (SMI_MISC_REG, (h_synch_high | v_synch_high | 0x29));
-       /* upper64K==0x20, CLC2select==0x08, RAMenable==0x02!(todo), CGA==0x01
-        * Selects the upper 64KB page.Bit5=1
-        * CLK2 (left reserved in standard VGA) Bit3|2=1|0
-        * Disables CPU access to frame buffer. Bit1=0
-        * Sets the I/O address decode for ST01, FCR, and all CR registers
-        * to the 3Dx I/O address range (CGA emulation). Bit0=1
-        */
-}
-/*****************************************************************************/
-static void smiLoadCrt (struct ctfb_res_modes *var, int bits_per_pixel)
-{
-       unsigned char cr[0x7a];
-       int i;
-       unsigned int hd, hs, he, ht, hbs, hbe;  /* Horizontal.  */
-       unsigned int vd, vs, ve, vt, vbs, vbe;  /* vertical */
-       unsigned int bpp, wd, dblscan, interlaced;
-
-       const int LineCompare = 0x3ff;
-       unsigned int TextScanLines = 1; /* this is in fact a vertical zoom factor   */
-       register GraphicDevice *pGD  = (GraphicDevice *)&smi;
-
-       /* Horizontal */
-       hd = (var->xres) / 8;   /* HDisp.  */
-       hs = (var->xres + var->right_margin) / 8;       /* HsStrt  */
-       he = (var->xres + var->right_margin + var->hsync_len) / 8;      /* HsEnd   */
-       ht = (var->left_margin + var->xres + var->right_margin + var->hsync_len) / 8;   /* HTotal  */
-       /* Blank */
-       hbs = hd;
-       hbe = 0; /* Blank end at 0 */
-
-       /* Vertical */
-       vd = var->yres;         /* VDisplay   */
-       vs = var->yres + var->lower_margin;     /* VSyncStart */
-       ve = var->yres + var->lower_margin + var->vsync_len;    /* VSyncEnd */
-       vt = var->upper_margin + var->yres + var->lower_margin + var->vsync_len;        /* VTotal  */
-       vbs = vd;
-       vbe = 0;
-
-       bpp = bits_per_pixel;
-       dblscan = (var->vmode & FB_VMODE_DOUBLE) ? 1 : 0;
-       interlaced = var->vmode & FB_VMODE_INTERLACED;
-
-
-       if (bpp == 15)
-               bpp = 16;
-       wd = var->xres * bpp / 64;      /* double words per line */
-       if (interlaced) {       /* we divide all vertical timings, exept vd */
-               vs >>= 1;
-               vbs >>= 1;
-               ve >>= 1;
-               vt >>= 1;
-       }
-
-       memset (cr, 0, sizeof (cr));
-       cr[0x00] = ht - 5;
-       cr[0x01] = hd - 1;
-       cr[0x02] = hbs - 1;
-       cr[0x03] = (hbe & 0x1F);
-       cr[0x04] = hs;
-       cr[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
-
-       cr[0x06] = (vt - 2) & 0xFF;
-       cr[0x07] = (((vt - 2) & 0x100) >> 8)
-               | (((vd - 1) & 0x100) >> 7)
-               | ((vs & 0x100) >> 6)
-               | (((vbs - 1) & 0x100) >> 5)
-               | ((LineCompare & 0x100) >> 4)
-               | (((vt - 2) & 0x200) >> 4)
-               | (((vd - 1) & 0x200) >> 3)
-               | ((vs & 0x200) >> 2);
-
-       cr[0x30] = ((vt - 2) & 0x400) >> 7
-               | (((vd - 1) & 0x400) >> 8)
-               | (((vbs - 1) & 0x400) >> 9)
-               | ((vs & 0x400) >> 10)
-               | (interlaced) ? 0x80 : 0;
-
-
-       cr[0x08] = 0x00;
-       cr[0x09] = (dblscan << 7)
-               | ((LineCompare & 0x200) >> 3)
-               | (((vbs - 1) & 0x200) >> 4)
-               | (TextScanLines - 1);
-
-       cr[0x10] = vs & 0xff;   /* VSyncPulseStart */
-       cr[0x11] = (ve & 0x0f);
-       cr[0x12] = (vd - 1) & 0xff;     /* LineCount  */
-       cr[0x13] = wd & 0xff;
-       cr[0x14] = 0x40;
-       cr[0x15] = (vbs - 1) & 0xff;
-       cr[0x16] = vbe & 0xff;
-       cr[0x17] = 0xe3;        /* but it does not work */
-       cr[0x18] = 0xff & LineCompare;
-       cr[0x22] = 0x00;        /* todo? */
-
-
-       /* now set the registers */
-       for (i = 0; i <= 0x18; i++) {   /*CR00 .. CR18 */
-               smiWrite (SMI_INDX_D4, i, cr[i]);
-       }
-       i = 0x22;               /*CR22 */
-       smiWrite (SMI_INDX_D4, i, cr[i]);
-       i = 0x30;               /*CR30 */
-       smiWrite (SMI_INDX_D4, i, cr[i]);
-}
-
-/*****************************************************************************/
-#define REF_FREQ       14318180
-#define PMIN           1
-#define PMAX           255
-#define QMIN           1
-#define QMAX           63
-
-static unsigned int FindPQ (unsigned int freq, unsigned int *pp, unsigned int *pq)
-{
-       unsigned int n = QMIN, m = 0;
-       long long int L = 0, P = freq, Q = REF_FREQ, H = P >> 1;
-       long long int D = 0x7ffffffffffffffLL;
-
-       for (n = QMIN; n <= QMAX; n++) {
-               m = PMIN;       /* p/q ~ freq/ref -> p*ref-freq*q ~ 0 */
-               L = P * n - m * Q;
-               while (L > 0 && m < PMAX) {
-                       L -= REF_FREQ;  /* difference is greater as 0 subtract fref */
-                       m++;    /* and increment m */
-               }
-               /* difference is less or equal than 0 or m > maximum */
-               if (m > PMAX)
-                       break;  /* no solution: if we increase n we get the same situation */
-               /* L is <= 0 now */
-               if (-L > H && m > PMIN) {       /* if difference > the half fref */
-                       L += REF_FREQ;  /* we take the situation before */
-                       m--;    /* because its closer to 0 */
-               }
-               L = (L < 0) ? -L : +L;  /* absolute value */
-               if (D < L)      /* if last difference was better take next n */
-                       continue;
-               D = L;
-               *pp = m;
-               *pq = n;        /*  keep improved data */
-               if (D == 0)
-                       break;  /* best result we can get */
-       }
-       return (unsigned int) (0xffffffff & D);
-}
-
-/*****************************************************************************/
-static void smiLoadCcr (struct ctfb_res_modes *var, unsigned short device_id)
-{
-       unsigned int p = 0;
-       unsigned int q = 0;
-       long long freq;
-       register GraphicDevice *pGD  = (GraphicDevice *)&smi;
-
-       smiWrite (SMI_INDX_C4, 0x65, 0);
-       smiWrite (SMI_INDX_C4, 0x66, 0);
-       smiWrite (SMI_INDX_C4, 0x68, 0x50);
-       if (device_id == PCI_DEVICE_ID_SMI_810) {
-               smiWrite (SMI_INDX_C4, 0x69, 0x3);
-       } else {
-               smiWrite (SMI_INDX_C4, 0x69, 0x0);
-       }
-
-       /* Memory clock */
-       switch (device_id) {
-       case PCI_DEVICE_ID_SMI_710 :
-               smiWrite (SMI_INDX_C4, 0x6a, 0x75);
-               break;
-       case PCI_DEVICE_ID_SMI_712 :
-               smiWrite (SMI_INDX_C4, 0x6a, 0x80);
-               break;
-       default :
-               smiWrite (SMI_INDX_C4, 0x6a, 0x53);
-               break;
-       }
-       smiWrite (SMI_INDX_C4, 0x6b, 0x15);
-
-       /* VCLK */
-       freq = 1000000000000LL / var -> pixclock;
-
-       FindPQ ((unsigned int)freq, &p, &q);
-
-       smiWrite (SMI_INDX_C4, 0x6c, p);
-       smiWrite (SMI_INDX_C4, 0x6d, q);
-
-}
-
-/*******************************************************************************
- *
- * Init video chip with common Linux graphic modes (lilo)
- */
-void *video_hw_init (void)
-{
-       GraphicDevice *pGD = (GraphicDevice *)&smi;
-       unsigned short device_id;
-       pci_dev_t devbusfn;
-       int videomode;
-       unsigned long t1, hsynch, vsynch;
-       unsigned int pci_mem_base, *vm;
-       char *penv;
-       int tmp, i, bits_per_pixel;
-       struct ctfb_res_modes *res_mode;
-       struct ctfb_res_modes var_mode;
-       unsigned char videoout;
-
-       /* Search for video chip */
-       printf("Video: ");
-
-       if ((devbusfn = pci_find_devices(supported, 0)) < 0)
-       {
-               printf ("Controller not found !\n");
-               return (NULL);
-       }
-
-       /* PCI setup */
-       pci_write_config_dword (devbusfn, PCI_COMMAND, (PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
-       pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
-       pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
-       pci_mem_base = pci_mem_to_phys (devbusfn, pci_mem_base);
-
-       tmp = 0;
-
-       videomode = CFG_DEFAULT_VIDEO_MODE;
-       /* get video mode via environment */
-       if ((penv = getenv ("videomode")) != NULL) {
-               /* deceide if it is a string */
-               if (penv[0] <= '9') {
-                       videomode = (int) simple_strtoul (penv, NULL, 16);
-                       tmp = 1;
-               }
-       } else {
-               tmp = 1;
-       }
-       if (tmp) {
-               /* parameter are vesa modes */
-               /* search params */
-               for (i = 0; i < VESA_MODES_COUNT; i++) {
-                       if (vesa_modes[i].vesanr == videomode)
-                               break;
-               }
-               if (i == VESA_MODES_COUNT) {
-                       printf ("no VESA Mode found, switching to mode 0x%x ", CFG_DEFAULT_VIDEO_MODE);
-                       i = 0;
-               }
-               res_mode =
-                       (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].
-                                                                resindex];
-               bits_per_pixel = vesa_modes[i].bits_per_pixel;
-       } else {
-
-               res_mode = (struct ctfb_res_modes *) &var_mode;
-               bits_per_pixel = video_get_params (res_mode, penv);
-       }
-
-       /* calculate hsynch and vsynch freq (info only) */
-       t1 = (res_mode->left_margin + res_mode->xres +
-             res_mode->right_margin + res_mode->hsync_len) / 8;
-       t1 *= 8;
-       t1 *= res_mode->pixclock;
-       t1 /= 1000;
-       hsynch = 1000000000L / t1;
-       t1 *=
-               (res_mode->upper_margin + res_mode->yres +
-                res_mode->lower_margin + res_mode->vsync_len);
-       t1 /= 1000;
-       vsynch = 1000000000L / t1;
-
-       /* fill in Graphic device struct */
-       sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
-                res_mode->yres, bits_per_pixel, (hsynch / 1000),
-                (vsynch / 1000));
-       printf ("%s\n", pGD->modeIdent);
-       pGD->winSizeX = res_mode->xres;
-       pGD->winSizeY = res_mode->yres;
-       pGD->plnSizeX = res_mode->xres;
-       pGD->plnSizeY = res_mode->yres;
-       switch (bits_per_pixel) {
-       case 8:
-               pGD->gdfBytesPP = 1;
-               pGD->gdfIndex = GDF__8BIT_INDEX;
-               break;
-       case 15:
-               pGD->gdfBytesPP = 2;
-               pGD->gdfIndex = GDF_15BIT_555RGB;
-               break;
-       case 16:
-               pGD->gdfBytesPP = 2;
-               pGD->gdfIndex = GDF_16BIT_565RGB;
-               break;
-       case 24:
-               pGD->gdfBytesPP = 3;
-               pGD->gdfIndex = GDF_24BIT_888RGB;
-               break;
-       }
-
-       pGD->isaBase = CFG_ISA_IO;
-       pGD->pciBase = pci_mem_base;
-       pGD->dprBase = (pci_mem_base + 0x400000 + 0x8000);
-       pGD->vprBase = (pci_mem_base + 0x400000 + 0xc000);
-       pGD->cprBase = (pci_mem_base + 0x400000 + 0xe000);
-       pGD->frameAdrs = pci_mem_base;
-       pGD->memSize = VIDEO_MEM_SIZE;
-
-       /* Set up hardware : select color mode,
-          set Register base to isa 3dx for 3?x regs*/
-       out8 (SMI_MISC_REG, 0x01);
-
-       /* Turn off display */
-       smiWrite (SMI_INDX_C4, 0x01, 0x20);
-
-       /* Unlock ext. crt regs */
-       out8 (SMI_LOCK_REG, 0x40);
-
-       /* Unlock crt regs 0-7 */
-       smiWrite (SMI_INDX_D4, 0x11, 0x0e);
-
-       /* Sytem Control Register */
-       smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_SCR, sizeof(SMI_SCR));
-
-       /* extented CRT Register */
-       smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5, SMI_EXT_CRT, sizeof(SMI_EXT_CRT));
-
-       /* Attributes controller registers */
-       smiLoadRegs (SMI_INDX_ATTR, SMI_INDX_ATTR, SMI_ATTR, sizeof(SMI_ATTR));
-
-       /* Graphics Controller Register */
-       smiLoadRegs (SMI_INDX_CE, SMI_DATA_CF, SMI_GCR, sizeof(SMI_GCR));
-
-       /* Sequencer Register */
-       smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_SEQR, sizeof(SMI_SEQR));
-
-       /* Power Control Register */
-       smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_PCR, sizeof(SMI_PCR));
-
-       /* Memory Control Register */
-       /* Register MSR62 is a power on configurable register. We don't */
-       /* modify it */
-       smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_MCR, sizeof(SMI_MCR));
-
-       /* Set misc output register */
-       smiLoadMsr (res_mode);
-
-       /* Set CRT and Clock control registers */
-       smiLoadCrt (res_mode, bits_per_pixel);
-
-       smiLoadCcr (res_mode, device_id);
-
-       /* Hardware Cusor Register */
-       smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_HCR, sizeof(SMI_HCR));
-
-       /* Enable  Display  */
-       videoout = 2;       /* Default output is CRT */
-       if ((penv = getenv ("videoout")) != NULL) {
-               /* deceide if it is a string */
-               videoout = (int) simple_strtoul (penv, NULL, 16);
-       }
-       smiWrite (SMI_INDX_C4, 0x31, videoout);
-
-       /* Video processor default setup */
-       smiInitVideoProcessor ();
-
-       /* Capture port default setup */
-       smiInitCapturePort ();
-
-       /* Drawing engine default setup */
-       smiInitDrawingEngine ();
-
-       /* Turn on display */
-       smiWrite (0x3c4, 0x01, 0x01);
-
-       /* Clear video memory */
-       i = pGD->memSize/4;
-       vm = (unsigned int *)pGD->pciBase;
-       while(i--)
-               *vm++ = 0;
-       return ((void*)&smi);
-}
-
-/*******************************************************************************
- *
- * Drawing engine fill on screen region
- */
-void video_hw_rectfill (
-       unsigned int bpp,             /* bytes per pixel */
-       unsigned int dst_x,           /* dest pos x */
-       unsigned int dst_y,           /* dest pos y */
-       unsigned int dim_x,           /* frame width */
-       unsigned int dim_y,           /* frame height */
-       unsigned int color            /* fill color */
-       )
-{
-       register GraphicDevice *pGD = (GraphicDevice *)&smi;
-       register unsigned int control;
-
-       dim_x *= bpp;
-
-       out32r ((pGD->dprBase + 0x0014), color);
-       out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
-       out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
-
-       control = 0x0000ffff &  in32r ((pGD->dprBase + 0x000c));
-
-       control |= 0x80010000;
-
-       out32r ((pGD->dprBase + 0x000c),  control);
-
-       /* Wait for drawing processor */
-       do
-       {
-               out8 ((pGD->isaBase + 0x3c4), 0x16);
-       } while (in8 (pGD->isaBase + 0x3c5) & 0x08);
-}
-
-/*******************************************************************************
- *
- * Drawing engine bitblt with screen region
- */
-void video_hw_bitblt (
-       unsigned int bpp,             /* bytes per pixel */
-       unsigned int src_x,           /* source pos x */
-       unsigned int src_y,           /* source pos y */
-       unsigned int dst_x,           /* dest pos x */
-       unsigned int dst_y,           /* dest pos y */
-       unsigned int dim_x,           /* frame width */
-       unsigned int dim_y            /* frame height */
-       )
-{
-       register GraphicDevice *pGD = (GraphicDevice *)&smi;
-       register unsigned int control;
-
-       dim_x *= bpp;
-
-       if ((src_y<dst_y) || ((src_y==dst_y) && (src_x<dst_x)))
-       {
-               out32r ((pGD->dprBase + 0x0000), (((src_x+dim_x-1)<<16) | (src_y+dim_y-1)));
-               out32r ((pGD->dprBase + 0x0004), (((dst_x+dim_x-1)<<16) | (dst_y+dim_y-1)));
-               control = 0x88000000;
-       } else {
-               out32r ((pGD->dprBase + 0x0000), ((src_x<<16) | src_y));
-               out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
-               control = 0x80000000;
-       }
-
-       out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
-       control |= (0x0000ffff &  in32r ((pGD->dprBase + 0x000c)));
-       out32r ((pGD->dprBase + 0x000c), control);
-
-       /* Wait for drawing processor */
-       do
-       {
-               out8 ((pGD->isaBase + 0x3c4), 0x16);
-       } while (in8 (pGD->isaBase + 0x3c5) & 0x08);
-}
-
-/*******************************************************************************
- *
- * Set a RGB color in the LUT (8 bit index)
- */
-void video_set_lut (
-       unsigned int index,           /* color number */
-       unsigned char r,              /* red */
-       unsigned char g,              /* green */
-       unsigned char b               /* blue */
-       )
-{
-       register GraphicDevice *pGD = (GraphicDevice *)&smi;
-
-       out8 (SMI_LUT_MASK,  0xff);
-
-       out8 (SMI_LUT_START, (char)index);
-
-       out8 (SMI_LUT_RGB, r>>2);    /* red */
-       udelay (10);
-       out8 (SMI_LUT_RGB, g>>2);    /* green */
-       udelay (10);
-       out8 (SMI_LUT_RGB, b>>2);    /* blue */
-       udelay (10);
-}
-
-#endif /* CONFIG_VIDEO_SMI_LYNXEM */
diff --git a/drivers/status_led.c b/drivers/status_led.c
deleted file mode 100644 (file)
index ddb6c22..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * (C) Copyright 2000-2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <status_led.h>
-
-/*
- * The purpose of this code is to signal the operational status of a
- * target which usually boots over the network; while running in
- * U-Boot, a status LED is blinking. As soon as a valid BOOTP reply
- * message has been received, the LED is turned off. The Linux
- * kernel, once it is running, will start blinking the LED again,
- * with another frequency.
- */
-
-/* ------------------------------------------------------------------------- */
-
-#ifdef CONFIG_STATUS_LED
-
-typedef struct {
-       led_id_t mask;
-       int state;
-       int period;
-       int cnt;
-} led_dev_t;
-
-led_dev_t led_dev[] = {
-    {  STATUS_LED_BIT,
-       STATUS_LED_STATE,
-       STATUS_LED_PERIOD,
-       0,
-    },
-#if defined(STATUS_LED_BIT1)
-    {  STATUS_LED_BIT1,
-       STATUS_LED_STATE1,
-       STATUS_LED_PERIOD1,
-       0,
-    },
-#endif
-#if defined(STATUS_LED_BIT2)
-    {  STATUS_LED_BIT2,
-       STATUS_LED_STATE2,
-       STATUS_LED_PERIOD2,
-       0,
-    },
-#endif
-#if defined(STATUS_LED_BIT3)
-    {  STATUS_LED_BIT3,
-       STATUS_LED_STATE3,
-       STATUS_LED_PERIOD3,
-       0,
-    },
-#endif
-};
-
-#define MAX_LED_DEV    (sizeof(led_dev)/sizeof(led_dev_t))
-
-static int status_led_init_done = 0;
-
-static void status_led_init (void)
-{
-       led_dev_t *ld;
-       int i;
-
-       for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++)
-               __led_init (ld->mask, ld->state);
-       status_led_init_done = 1;
-}
-
-void status_led_tick (ulong timestamp)
-{
-       led_dev_t *ld;
-       int i;
-
-       if (!status_led_init_done)
-               status_led_init ();
-
-       for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++) {
-
-               if (ld->state != STATUS_LED_BLINKING)
-                       continue;
-
-               if (++ld->cnt >= ld->period) {
-                       __led_toggle (ld->mask);
-                       ld->cnt -= ld->period;
-               }
-
-       }
-}
-
-void status_led_set (int led, int state)
-{
-       led_dev_t *ld;
-
-       if (led < 0 || led >= MAX_LED_DEV)
-               return;
-
-       if (!status_led_init_done)
-               status_led_init ();
-
-       ld = &led_dev[led];
-
-       ld->state = state;
-       if (state == STATUS_LED_BLINKING) {
-               ld->cnt = 0;            /* always start with full period    */
-               state = STATUS_LED_ON;  /* always start with LED _ON_       */
-       }
-       __led_set (ld->mask, state);
-}
-
-#endif /* CONFIG_STATUS_LED */
diff --git a/drivers/sym53c8xx.c b/drivers/sym53c8xx.c
deleted file mode 100644 (file)
index 29eeccd..0000000
+++ /dev/null
@@ -1,793 +0,0 @@
-/*
- * (C) Copyright 2001
- * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- * partly derived from
- * linux/drivers/scsi/sym53c8xx.c
- *
- */
-
-/*
- * SCSI support based on the chip sym53C810.
- *
- * 09-19-2001 Andreas Heppel, Sysgo RTS GmbH <aheppel@sysgo.de>
- *             The local version of this driver for the BAB750 board does not
- *             use interrupts but polls the chip instead (see the call of
- *             'handle_scsi_int()' in 'scsi_issue()'.
- */
-
-#include <common.h>
-
-#ifdef CONFIG_SCSI_SYM53C8XX
-
-#include <command.h>
-#include <pci.h>
-#include <asm/processor.h>
-#include <sym53c8xx.h>
-#include <scsi.h>
-
-#undef SYM53C8XX_DEBUG
-
-#ifdef SYM53C8XX_DEBUG
-#define        PRINTF(fmt,args...)     printf (fmt ,##args)
-#else
-#define PRINTF(fmt,args...)
-#endif
-
-#if defined(CONFIG_CMD_SCSI) && defined(CONFIG_SCSI_SYM53C8XX)
-
-#undef SCSI_SINGLE_STEP
-/*
- * Single Step is only used for debug purposes
- */
-#ifdef SCSI_SINGLE_STEP
-static unsigned long start_script_select;
-static unsigned long start_script_msgout;
-static unsigned long start_script_msgin;
-static unsigned long start_script_msg_ext;
-static unsigned long start_script_cmd;
-static unsigned long start_script_data_in;
-static unsigned long start_script_data_out;
-static unsigned long start_script_status;
-static unsigned long start_script_complete;
-static unsigned long start_script_error;
-static unsigned long start_script_reselection;
-static unsigned int len_script_select;
-static unsigned int len_script_msgout;
-static unsigned int len_script_msgin;
-static unsigned int len_script_msg_ext;
-static unsigned int len_script_cmd;
-static unsigned int len_script_data_in;
-static unsigned int len_script_data_out;
-static unsigned int len_script_status;
-static unsigned int len_script_complete;
-static unsigned int len_script_error;
-static unsigned int len_script_reselection;
-#endif
-
-
-static unsigned short scsi_int_mask;           /* shadow register for SCSI related interrupts */
-static unsigned char  script_int_mask; /* shadow register for SCRIPT related interrupts */
-static unsigned long script_select[8]; /* script for selection */
-static unsigned long script_msgout[8]; /* script for message out phase (NOT USED) */
-static unsigned long script_msgin[14]; /* script for message in phase */
-static unsigned long script_msg_ext[32]; /* script for message in phase when more than 1 byte message */
-static unsigned long script_cmd[18];    /* script for command phase */
-static unsigned long script_data_in[8]; /* script for data in phase */
-static unsigned long script_data_out[8]; /* script for data out phase */
-static unsigned long script_status[6]; /* script for status phase */
-static unsigned long script_complete[10]; /* script for complete */
-static unsigned long script_reselection[4]; /* script for reselection (NOT USED) */
-static unsigned long script_error[2]; /* script for error handling */
-
-static unsigned long int_stat[3]; /* interrupt status */
-static unsigned long scsi_mem_addr; /* base memory address =SCSI_MEM_ADDRESS; */
-
-#define bus_to_phys(a) pci_mem_to_phys(busdevfunc, (unsigned long) (a))
-#define phys_to_bus(a) pci_phys_to_mem(busdevfunc, (unsigned long) (a))
-
-#define SCSI_MAX_RETRY 3 /* number of retries in scsi_issue() */
-
-#define SCSI_MAX_RETRY_NOT_READY 10 /* number of retries when device is not ready */
-#define SCSI_NOT_READY_TIME_OUT 500 /* timeout per retry when not ready */
-
-/*********************************************************************************
- * forward declerations
- */
-
-void scsi_chip_init(void);
-void handle_scsi_int(void);
-
-
-/********************************************************************************
- * reports SCSI errors to the user
- */
-void scsi_print_error(ccb *pccb)
-{
-       int i;
-       printf("SCSI Error: Target %d LUN %d Command %02X\n",pccb->target, pccb->lun, pccb->cmd[0]);
-       printf("       CCB: ");
-       for(i=0;i<pccb->cmdlen;i++)
-               printf("%02X ",pccb->cmd[i]);
-       printf("(len=%d)\n",pccb->cmdlen);
-       printf("     Cntrl: ");
-       switch(pccb->contr_stat) {
-               case SIR_COMPLETE:                                              printf("Complete (no Error)\n"); break;
-               case SIR_SEL_ATN_NO_MSG_OUT:    printf("Selected with ATN no MSG out phase\n"); break;
-               case SIR_CMD_OUT_ILL_PH:                        printf("Command out illegal phase\n"); break;
-               case SIR_MSG_RECEIVED:                          printf("MSG received Error\n"); break;
-               case SIR_DATA_IN_ERR:                           printf("Data in Error\n"); break;
-               case SIR_DATA_OUT_ERR:                          printf("Data out Error\n"); break;
-               case SIR_SCRIPT_ERROR:                          printf("Script Error\n"); break;
-               case SIR_MSG_OUT_NO_CMD:                        printf("MSG out no Command phase\n"); break;
-               case SIR_MSG_OVER7:                                     printf("MSG in over 7 bytes\n"); break;
-               case INT_ON_FY:                                                         printf("Interrupt on fly\n"); break;
-               case SCSI_SEL_TIME_OUT:                         printf("SCSI Selection Timeout\n"); break;
-               case SCSI_HNS_TIME_OUT:                         printf("SCSI Handshake Timeout\n"); break;
-               case SCSI_MA_TIME_OUT:                          printf("SCSI Phase Error\n"); break;
-               case SCSI_UNEXP_DIS:                                    printf("SCSI unexpected disconnect\n"); break;
-               default:                                                                                        printf("unknown status %lx\n",pccb->contr_stat); break;
-       }
-       printf("     Sense: SK %x (",pccb->sense_buf[2]&0x0f);
-       switch(pccb->sense_buf[2]&0xf) {
-               case SENSE_NO_SENSE: printf("No Sense)"); break;
-               case SENSE_RECOVERED_ERROR: printf("Recovered Error)"); break;
-               case SENSE_NOT_READY:   printf("Not Ready)"); break;
-               case SENSE_MEDIUM_ERROR: printf("Medium Error)"); break;
-               case SENSE_HARDWARE_ERROR: printf("Hardware Error)"); break;
-               case SENSE_ILLEGAL_REQUEST: printf("Illegal request)"); break;
-               case SENSE_UNIT_ATTENTION: printf("Unit Attention)"); break;
-               case SENSE_DATA_PROTECT: printf("Data Protect)"); break;
-               case SENSE_BLANK_CHECK: printf("Blank check)"); break;
-               case SENSE_VENDOR_SPECIFIC: printf("Vendor specific)"); break;
-               case SENSE_COPY_ABORTED: printf("Copy aborted)"); break;
-               case SENSE_ABORTED_COMMAND:     printf("Aborted Command)"); break;
-               case SENSE_VOLUME_OVERFLOW:     printf("Volume overflow)"); break;
-               case SENSE_MISCOMPARE: printf("Misscompare\n"); break;
-               default: printf("Illegal Sensecode\n"); break;
-       }
-       printf(" ASC %x ASCQ %x\n",pccb->sense_buf[12],pccb->sense_buf[13]);
-       printf("    Status: ");
-       switch(pccb->status) {
-               case S_GOOD :   printf("Good\n"); break;
-               case S_CHECK_COND: printf("Check condition\n"); break;
-               case S_COND_MET: printf("Condition Met\n"); break;
-               case S_BUSY: printf("Busy\n"); break;
-               case S_INT: printf("Intermediate\n"); break;
-               case S_INT_COND_MET: printf("Intermediate condition met\n"); break;
-               case S_CONFLICT: printf("Reservation conflict\n"); break;
-               case S_TERMINATED: printf("Command terminated\n"); break;
-               case S_QUEUE_FULL: printf("Task set full\n"); break;
-               default: printf("unknown: %02X\n",pccb->status); break;
-       }
-
-}
-
-
-/******************************************************************************
- * sets-up the SCSI controller
- * the base memory address is retrived via the pci_read_config_dword
- */
-void scsi_low_level_init(int busdevfunc)
-{
-       unsigned int cmd;
-       unsigned int addr;
-       unsigned char vec;
-
-       pci_read_config_byte(busdevfunc, PCI_INTERRUPT_LINE, &vec);
-       pci_read_config_dword(busdevfunc, PCI_BASE_ADDRESS_1, &addr);
-
-       addr = bus_to_phys(addr & ~0xf);
-
-       /*
-        * Enable bus mastering in case this has not been done, yet.
-        */
-       pci_read_config_dword(busdevfunc, PCI_COMMAND, &cmd);
-       cmd |= PCI_COMMAND_MASTER;
-       pci_write_config_dword(busdevfunc, PCI_COMMAND, cmd);
-
-       scsi_mem_addr = addr;
-
-       scsi_chip_init();
-       scsi_bus_reset();
-}
-
-
-/************************************************************************************
- * Low level Part of SCSI Driver
- */
-
-/*
- * big-endian -> little endian conversion for the script
- */
-unsigned long swap_script(unsigned long val)
-{
-       unsigned long tmp;
-       tmp = ((val>>24)&0xff) | ((val>>8)&0xff00) | ((val<<8)&0xff0000) | ((val<<24)&0xff000000);
-       return tmp;
-}
-
-
-void scsi_write_byte(ulong offset,unsigned char val)
-{
-       out8(scsi_mem_addr+offset,val);
-}
-
-
-unsigned char scsi_read_byte(ulong offset)
-{
-       return(in8(scsi_mem_addr+offset));
-}
-
-
-/********************************************************************************
- * interrupt handler
- */
-void handle_scsi_int(void)
-{
-       unsigned char stat,stat1,stat2;
-       unsigned short sstat;
-       int i;
-#ifdef SCSI_SINGLE_STEP
-       unsigned long tt;
-#endif
-       stat=scsi_read_byte(ISTAT);
-       if((stat & DIP)==DIP) { /* DMA Interrupt pending */
-               stat1=scsi_read_byte(DSTAT);
-#ifdef SCSI_SINGLE_STEP
-               if((stat1 & SSI)==SSI)
-               {
-                       tt=in32r(scsi_mem_addr+DSP);
-                       if(((tt)>=start_script_select) && ((tt)<start_script_select+len_script_select)) {
-                               printf("select %d\n",(tt-start_script_select)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_msgout) && ((tt)<start_script_msgout+len_script_msgout)) {
-                               printf("msgout %d\n",(tt-start_script_msgout)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_msgin) && ((tt)<start_script_msgin+len_script_msgin)) {
-                               printf("msgin %d\n",(tt-start_script_msgin)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_msg_ext) && ((tt)<start_script_msg_ext+len_script_msg_ext)) {
-                               printf("msgin_ext %d\n",(tt-start_script_msg_ext)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_cmd) && ((tt)<start_script_cmd+len_script_cmd)) {
-                               printf("cmd %d\n",(tt-start_script_cmd)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_data_in) && ((tt)<start_script_data_in+len_script_data_in)) {
-                               printf("data_in %d\n",(tt-start_script_data_in)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_data_out) && ((tt)<start_script_data_out+len_script_data_out)) {
-                               printf("data_out %d\n",(tt-start_script_data_out)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_status) && ((tt)<start_script_status+len_script_status)) {
-                               printf("status %d\n",(tt-start_script_status)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_complete) && ((tt)<start_script_complete+len_script_complete)) {
-                               printf("complete %d\n",(tt-start_script_complete)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_error) && ((tt)<start_script_error+len_script_error)) {
-                               printf("error %d\n",(tt-start_script_error)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_reselection) && ((tt)<start_script_reselection+len_script_reselection)) {
-                               printf("reselection %d\n",(tt-start_script_reselection)>>2);
-                               goto end_single;
-                       }
-                       printf("sc: %lx\n",tt);
-end_single:
-                       stat2=scsi_read_byte(DCNTL);
-                       stat2|=STD;
-                       scsi_write_byte(DCNTL,stat2);
-               }
-#endif
-               if((stat1 & SIR)==SIR) /* script interrupt */
-               {
-                       int_stat[0]=in32(scsi_mem_addr+DSPS);
-               }
-               if((stat1 & DFE)==0) { /* fifo not epmty */
-                       scsi_write_byte(CTEST3,CLF); /* Clear DMA FIFO */
-                       stat2=scsi_read_byte(STEST3);
-                       scsi_write_byte(STEST3,(stat2 | CSF)); /* Clear SCSI FIFO */
-               }
-       }
-       if((stat & SIP)==SIP) {  /* scsi interrupt */
-               sstat = (unsigned short)scsi_read_byte(SIST+1);
-               sstat <<=8;
-               sstat |= (unsigned short)scsi_read_byte(SIST);
-               for(i=0;i<3;i++) {
-                       if(int_stat[i]==0)
-                               break; /* found an empty int status */
-               }
-               int_stat[i]=SCSI_INT_STATE | sstat;
-               stat1=scsi_read_byte(DSTAT);
-               if((stat1 & DFE)==0) { /* fifo not epmty */
-                       scsi_write_byte(CTEST3,CLF); /* Clear DMA FIFO */
-                       stat2=scsi_read_byte(STEST3);
-                       scsi_write_byte(STEST3,(stat2 | CSF)); /* Clear SCSI FIFO */
-               }
-       }
-       if((stat & INTF)==INTF) { /* interrupt on Fly */
-               scsi_write_byte(ISTAT,stat); /* clear it */
-               for(i=0;i<3;i++) {
-                       if(int_stat[i]==0)
-                               break; /* found an empty int status */
-               }
-               int_stat[i]=INT_ON_FY;
-       }
-}
-
-void scsi_bus_reset(void)
-{
-       unsigned char t;
-       int i;
-       int end = CFG_SCSI_SPIN_UP_TIME*1000;
-
-       t=scsi_read_byte(SCNTL1);
-       scsi_write_byte(SCNTL1,(t | CRST));
-       udelay(50);
-       scsi_write_byte(SCNTL1,t);
-
-       puts("waiting for devices to spin up");
-       for(i=0;i<end;i++) {
-               udelay(1000); /* give the devices time to spin up */
-               if (i % 1000 == 0)
-                       putc('.');
-       }
-       putc('\n');
-       scsi_chip_init(); /* reinit the chip ...*/
-
-}
-
-void scsi_int_enable(void)
-{
-       scsi_write_byte(SIEN,(unsigned char)scsi_int_mask);
-       scsi_write_byte(SIEN+1,(unsigned char)(scsi_int_mask>>8));
-       scsi_write_byte(DIEN,script_int_mask);
-}
-
-void scsi_write_dsp(unsigned long start)
-{
-       unsigned long val;
-#ifdef SCSI_SINGLE_STEP
-       unsigned char t;
-#endif
-       val = start;
-       out32r(scsi_mem_addr + DSP,start);
-#ifdef SCSI_SINGLE_STEP
-       t=scsi_read_byte(DCNTL);
-  t|=STD;
-       scsi_write_byte(DCNTL,t);
-#endif
-}
-
-/* only used for debug purposes */
-void scsi_print_script(void)
-{
-       printf("script_select @         0x%08lX\n",(unsigned long)&script_select[0]);
-       printf("script_msgout @         0x%08lX\n",(unsigned long)&script_msgout[0]);
-       printf("script_msgin @          0x%08lX\n",(unsigned long)&script_msgin[0]);
-       printf("script_msgext @         0x%08lX\n",(unsigned long)&script_msg_ext[0]);
-       printf("script_cmd @            0x%08lX\n",(unsigned long)&script_cmd[0]);
-       printf("script_data_in @        0x%08lX\n",(unsigned long)&script_data_in[0]);
-       printf("script_data_out @       0x%08lX\n",(unsigned long)&script_data_out[0]);
-       printf("script_status @         0x%08lX\n",(unsigned long)&script_status[0]);
-       printf("script_complete @       0x%08lX\n",(unsigned long)&script_complete[0]);
-       printf("script_error @          0x%08lX\n",(unsigned long)&script_error[0]);
-}
-
-
-void scsi_set_script(ccb *pccb)
-{
-       int busdevfunc = pccb->priv;
-       int i;
-       i=0;
-       script_select[i++]=swap_script(SCR_REG_REG(GPREG, SCR_AND, 0xfe));
-       script_select[i++]=0; /* LED ON */
-       script_select[i++]=swap_script(SCR_CLR(SCR_TRG)); /* select initiator mode */
-       script_select[i++]=0;
-       /* script_select[i++]=swap_script(SCR_SEL_ABS_ATN | pccb->target << 16); */
-       script_select[i++]=swap_script(SCR_SEL_ABS | pccb->target << 16);
-       script_select[i++]=swap_script(phys_to_bus(&script_cmd[4])); /* error handling */
-       script_select[i++]=swap_script(SCR_JUMP); /* next section */
-       /*      script_select[i++]=swap_script((unsigned long)&script_msgout[0]); */ /* message out */
-       script_select[i++]=swap_script(phys_to_bus(&script_cmd[0])); /* command out */
-
-#ifdef SCSI_SINGLE_STEP
-       start_script_select=(unsigned long)&script_select[0];
-       len_script_select=i*4;
-#endif
-
-       i=0;
-       script_msgout[i++]=swap_script(SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)));
-       script_msgout[i++]=SIR_SEL_ATN_NO_MSG_OUT;
-       script_msgout[i++]=swap_script( SCR_MOVE_ABS(1) ^ SCR_MSG_OUT);
-       script_msgout[i++]=swap_script(phys_to_bus(&pccb->msgout[0]));
-       script_msgout[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_COMMAND))); /* if Command phase */
-       script_msgout[i++]=swap_script(phys_to_bus(&script_cmd[0])); /* switch to command */
-       script_msgout[i++]=swap_script(SCR_INT); /* interrupt if not */
-       script_msgout[i++]=SIR_MSG_OUT_NO_CMD;
-
-#ifdef SCSI_SINGLE_STEP
-       start_script_msgout=(unsigned long)&script_msgout[0];
-       len_script_msgout=i*4;
-#endif
-       i=0;
-       script_cmd[i++]=swap_script(SCR_MOVE_ABS(pccb->cmdlen) ^ SCR_COMMAND);
-       script_cmd[i++]=swap_script(phys_to_bus(&pccb->cmd[0]));
-       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN))); /* message in ? */
-       script_cmd[i++]=swap_script(phys_to_bus(&script_msgin[0]));
-       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_DATA_OUT))); /* data out ? */
-       script_cmd[i++]=swap_script(phys_to_bus(&script_data_out[0]));
-       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_DATA_IN))); /* data in ? */
-       script_cmd[i++]=swap_script(phys_to_bus(&script_data_in[0]));
-       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_STATUS)));  /* status ? */
-       script_cmd[i++]=swap_script(phys_to_bus(&script_status[0]));
-       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND)));  /* command ? */
-       script_cmd[i++]=swap_script(phys_to_bus(&script_cmd[0]));
-       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)));  /* message out ? */
-       script_cmd[i++]=swap_script(phys_to_bus(&script_msgout[0]));
-       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_MSG_IN))); /* just for error handling message in ? */
-       script_cmd[i++]=swap_script(phys_to_bus(&script_msgin[0]));
-       script_cmd[i++]=swap_script(SCR_INT); /* interrupt if not */
-       script_cmd[i++]=SIR_CMD_OUT_ILL_PH;
-#ifdef SCSI_SINGLE_STEP
-       start_script_cmd=(unsigned long)&script_cmd[0];
-       len_script_cmd=i*4;
-#endif
-       i=0;
-       script_data_out[i++]=swap_script(SCR_MOVE_ABS(pccb->datalen)^ SCR_DATA_OUT); /* move */
-       script_data_out[i++]=swap_script(phys_to_bus(pccb->pdata)); /* pointer to buffer */
-       script_data_out[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)));
-       script_data_out[i++]=swap_script(phys_to_bus(&script_status[0]));
-       script_data_out[i++]=swap_script(SCR_INT);
-       script_data_out[i++]=SIR_DATA_OUT_ERR;
-
-#ifdef SCSI_SINGLE_STEP
-       start_script_data_out=(unsigned long)&script_data_out[0];
-       len_script_data_out=i*4;
-#endif
-       i=0;
-       script_data_in[i++]=swap_script(SCR_MOVE_ABS(pccb->datalen)^ SCR_DATA_IN); /* move  */
-       script_data_in[i++]=swap_script(phys_to_bus(pccb->pdata)); /* pointer to buffer */
-       script_data_in[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)));
-       script_data_in[i++]=swap_script(phys_to_bus(&script_status[0]));
-       script_data_in[i++]=swap_script(SCR_INT);
-       script_data_in[i++]=SIR_DATA_IN_ERR;
-#ifdef SCSI_SINGLE_STEP
-       start_script_data_in=(unsigned long)&script_data_in[0];
-       len_script_data_in=i*4;
-#endif
-       i=0;
-       script_msgin[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN);
-       script_msgin[i++]=swap_script(phys_to_bus(&pccb->msgin[0]));
-       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)));
-       script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0]));
-       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)));
-       script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0]));
-       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)));
-       script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0]));
-       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)));
-       script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0]));
-       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)));
-       script_msgin[i++]=swap_script(phys_to_bus(&script_msg_ext[0]));
-       script_msgin[i++]=swap_script(SCR_INT);
-       script_msgin[i++]=SIR_MSG_RECEIVED;
-#ifdef SCSI_SINGLE_STEP
-       start_script_msgin=(unsigned long)&script_msgin[0];
-       len_script_msgin=i*4;
-#endif
-       i=0;
-       script_msg_ext[i++]=swap_script(SCR_CLR (SCR_ACK)); /* clear ACK */
-       script_msg_ext[i++]=0;
-       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* assuming this is the msg length */
-       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[1]));
-       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
-       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
-       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
-       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[2]));
-       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
-       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
-       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
-       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[3]));
-       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
-       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
-       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
-       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[4]));
-       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
-       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
-       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
-       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[5]));
-       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
-       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
-       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
-       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[6]));
-       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
-       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
-       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
-       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[7]));
-       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
-       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
-       script_msg_ext[i++]=swap_script(SCR_INT);
-       script_msg_ext[i++]=SIR_MSG_OVER7;
-#ifdef SCSI_SINGLE_STEP
-       start_script_msg_ext=(unsigned long)&script_msg_ext[0];
-       len_script_msg_ext=i*4;
-#endif
-       i=0;
-       script_status[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_STATUS);
-       script_status[i++]=swap_script(phys_to_bus(&pccb->status));
-       script_status[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)));
-       script_status[i++]=swap_script(phys_to_bus(&script_msgin[0]));
-       script_status[i++]=swap_script(SCR_INT);
-       script_status[i++]=SIR_STATUS_ILL_PH;
-#ifdef SCSI_SINGLE_STEP
-       start_script_status=(unsigned long)&script_status[0];
-       len_script_status=i*4;
-#endif
-       i=0;
-       script_complete[i++]=swap_script(SCR_REG_REG (SCNTL2, SCR_AND, 0x7f));
-       script_complete[i++]=0;
-       script_complete[i++]=swap_script(SCR_CLR (SCR_ACK|SCR_ATN));
-       script_complete[i++]=0;
-       script_complete[i++]=swap_script(SCR_WAIT_DISC);
-       script_complete[i++]=0;
-       script_complete[i++]=swap_script(SCR_REG_REG(GPREG, SCR_OR, 0x01));
-       script_complete[i++]=0; /* LED OFF */
-       script_complete[i++]=swap_script(SCR_INT);
-       script_complete[i++]=SIR_COMPLETE;
-#ifdef SCSI_SINGLE_STEP
-       start_script_complete=(unsigned long)&script_complete[0];
-       len_script_complete=i*4;
-#endif
-       i=0;
-       script_error[i++]=swap_script(SCR_INT); /* interrupt if error */
-       script_error[i++]=SIR_SCRIPT_ERROR;
-#ifdef SCSI_SINGLE_STEP
-       start_script_error=(unsigned long)&script_error[0];
-       len_script_error=i*4;
-#endif
-       i=0;
-       script_reselection[i++]=swap_script(SCR_CLR (SCR_TRG)); /* target status */
-       script_reselection[i++]=0;
-       script_reselection[i++]=swap_script(SCR_WAIT_RESEL);
-       script_reselection[i++]=swap_script(phys_to_bus(&script_select[0])); /* len = 4 */
-#ifdef SCSI_SINGLE_STEP
-       start_script_reselection=(unsigned long)&script_reselection[0];
-       len_script_reselection=i*4;
-#endif
-}
-
-
-void scsi_issue(ccb *pccb)
-{
-       int busdevfunc = pccb->priv;
-       int i;
-       unsigned short sstat;
-       int retrycnt;  /* retry counter */
-       for(i=0;i<3;i++)
-               int_stat[i]=0; /* delete all int status */
-       /* struct pccb must be set-up correctly */
-       retrycnt=0;
-       PRINTF("ID %d issue cmd %02X\n",pccb->target,pccb->cmd[0]);
-       pccb->trans_bytes=0; /* no bytes transfered yet */
-       scsi_set_script(pccb); /* fill in SCRIPT                */
-       scsi_int_mask=STO | UDC | MA; /* | CMP; / * Interrupts which are enabled */
-       script_int_mask=0xff; /* enable all Ints */
-       scsi_int_enable();
-       scsi_write_dsp(phys_to_bus(&script_select[0])); /* start script */
-       /* now we have to wait for IRQs */
-retry:
-       /*
-        * This version of the driver is _not_ interrupt driven,
-        * but polls the chip's interrupt registers (ISTAT, DSTAT).
-        */
-       while(int_stat[0]==0)
-               handle_scsi_int();
-
-       if(int_stat[0]==SIR_COMPLETE) {
-               if(pccb->msgin[0]==M_DISCONNECT) {
-                       PRINTF("Wait for reselection\n");
-                       for(i=0;i<3;i++)
-                               int_stat[i]=0; /* delete all int status */
-                       scsi_write_dsp(phys_to_bus(&script_reselection[0])); /* start reselection script */
-                       goto retry;
-               }
-               pccb->contr_stat=SIR_COMPLETE;
-               return;
-       }
-       if((int_stat[0] & SCSI_INT_STATE)==SCSI_INT_STATE) { /* scsi interrupt */
-               sstat=(unsigned short)int_stat[0];
-               if((sstat & STO)==STO) { /* selection timeout */
-                       pccb->contr_stat=SCSI_SEL_TIME_OUT;
-                       scsi_write_byte(GPREG,0x01);
-                       PRINTF("ID: %X Selection Timeout\n",pccb->target);
-                       return;
-               }
-               if((sstat & UDC)==UDC) { /* unexpected disconnect */
-                       pccb->contr_stat=SCSI_UNEXP_DIS;
-                       scsi_write_byte(GPREG,0x01);
-                       PRINTF("ID: %X Unexpected Disconnect\n",pccb->target);
-                       return;
-               }
-               if((sstat & RSL)==RSL) { /* reselection */
-                       pccb->contr_stat=SCSI_UNEXP_DIS;
-                       scsi_write_byte(GPREG,0x01);
-                       PRINTF("ID: %X Unexpected Disconnect\n",pccb->target);
-                       return;
-               }
-               if(((sstat & MA)==MA)||((sstat & HTH)==HTH)) { /* phase missmatch */
-                       if(retrycnt<SCSI_MAX_RETRY) {
-                               pccb->trans_bytes=pccb->datalen -
-                                       ((unsigned long)scsi_read_byte(DBC) |
-                                       ((unsigned long)scsi_read_byte(DBC+1)<<8) |
-                                       ((unsigned long)scsi_read_byte(DBC+2)<<16));
-                               for(i=0;i<3;i++)
-                                       int_stat[i]=0; /* delete all int status */
-                               retrycnt++;
-                               PRINTF("ID: %X Phase Missmatch Retry %d Phase %02X transfered %lx\n",
-                                               pccb->target,retrycnt,scsi_read_byte(SBCL),pccb->trans_bytes);
-                               scsi_write_dsp(phys_to_bus(&script_cmd[4])); /* start retry script */
-                               goto retry;
-                       }
-                       if((sstat & MA)==MA)
-                               pccb->contr_stat=SCSI_MA_TIME_OUT;
-                       else
-                               pccb->contr_stat=SCSI_HNS_TIME_OUT;
-                       PRINTF("Phase Missmatch stat %lx\n",pccb->contr_stat);
-                       return;
-               } /* no phase int */
-/*             if((sstat & CMP)==CMP) {
-                       pccb->contr_stat=SIR_COMPLETE;
-                       return;
-               }
-*/
-               PRINTF("SCSI INT %lX\n",int_stat[0]);
-               pccb->contr_stat=int_stat[0];
-               return;
-       } /* end scsi int */
-       PRINTF("SCRIPT INT %lX phase %02X\n",int_stat[0],scsi_read_byte(SBCL));
-       pccb->contr_stat=int_stat[0];
-       return;
-}
-
-int scsi_exec(ccb *pccb)
-{
-       unsigned char tmpcmd[16],tmpstat;
-       int i,retrycnt,t;
-       unsigned long transbytes,datalen;
-       unsigned char *tmpptr;
-       retrycnt=0;
-retry:
-       scsi_issue(pccb);
-       if(pccb->contr_stat!=SIR_COMPLETE)
-               return FALSE;
-       if(pccb->status==S_GOOD)
-               return TRUE;
-       if(pccb->status==S_CHECK_COND) { /* check condition */
-               for(i=0;i<16;i++)
-                       tmpcmd[i]=pccb->cmd[i];
-               pccb->cmd[0]=SCSI_REQ_SENSE;
-               pccb->cmd[1]=pccb->lun<<5;
-               pccb->cmd[2]=0;
-               pccb->cmd[3]=0;
-               pccb->cmd[4]=14;
-               pccb->cmd[5]=0;
-               pccb->cmdlen=6;
-               pccb->msgout[0]=SCSI_IDENTIFY;
-               transbytes=pccb->trans_bytes;
-               tmpptr=pccb->pdata;
-               pccb->pdata=&pccb->sense_buf[0];
-               datalen=pccb->datalen;
-               pccb->datalen=14;
-               tmpstat=pccb->status;
-               scsi_issue(pccb);
-               for(i=0;i<16;i++)
-                       pccb->cmd[i]=tmpcmd[i];
-               pccb->trans_bytes=transbytes;
-               pccb->pdata=tmpptr;
-               pccb->datalen=datalen;
-               pccb->status=tmpstat;
-               PRINTF("Request_sense sense key %x ASC %x ASCQ %x\n",pccb->sense_buf[2]&0x0f,
-                       pccb->sense_buf[12],pccb->sense_buf[13]);
-               switch(pccb->sense_buf[2]&0xf) {
-                       case SENSE_NO_SENSE:
-                       case SENSE_RECOVERED_ERROR:
-                               /* seems to be ok */
-                               return TRUE;
-                               break;
-                       case SENSE_NOT_READY:
-                               if((pccb->sense_buf[12]!=0x04)||(pccb->sense_buf[13]!=0x01)) {
-                                       /* if device is not in process of becoming ready */
-                                       return FALSE;
-                                       break;
-                               } /* else fall through */
-                       case SENSE_UNIT_ATTENTION:
-                               if(retrycnt<SCSI_MAX_RETRY_NOT_READY) {
-                                       PRINTF("Target %d not ready, retry %d\n",pccb->target,retrycnt);
-                                       for(t=0;t<SCSI_NOT_READY_TIME_OUT;t++)
-                                               udelay(1000); /* 1sec wait */
-                                       retrycnt++;
-                                       goto retry;
-                               }
-                               PRINTF("Target %d not ready, %d retried\n",pccb->target,retrycnt);
-                               return FALSE;
-                       default:
-                               return FALSE;
-               }
-       }
-       PRINTF("Status = %X\n",pccb->status);
-       return FALSE;
-}
-
-
-void scsi_chip_init(void)
-{
-       /* first we issue a soft reset */
-       scsi_write_byte(ISTAT,SRST);
-       udelay(1000);
-       scsi_write_byte(ISTAT,0);
-       /* setup chip */
-       scsi_write_byte(SCNTL0,0xC0); /* full arbitration no start, no message, parity disabled, master */
-       scsi_write_byte(SCNTL1,0x00);
-       scsi_write_byte(SCNTL2,0x00);
-#ifndef CFG_SCSI_SYM53C8XX_CCF    /* config value for none 40 mhz clocks */
-       scsi_write_byte(SCNTL3,0x13); /* synchronous clock 40/4=10MHz, asynchronous 40MHz */
-#else
-       scsi_write_byte(SCNTL3,CFG_SCSI_SYM53C8XX_CCF); /* config value for none 40 mhz clocks */
-#endif
-       scsi_write_byte(SCID,0x47); /* ID=7, enable reselection */
-       scsi_write_byte(SXFER,0x00); /* synchronous transfer period 10MHz, asynchronous */
-       scsi_write_byte(SDID,0x00);  /* targed SCSI ID = 0 */
-       scsi_int_mask=0x0000; /* no Interrupt is enabled */
-       script_int_mask=0x00;
-       scsi_int_enable();
-       scsi_write_byte(GPREG,0x01); /* GPIO0 is LED (off) */
-       scsi_write_byte(GPCNTL,0x0E); /* GPIO0 is Output */
-       scsi_write_byte(STIME0,0x08); /* handshake timer disabled, selection timeout 512msec */
-       scsi_write_byte(RESPID,0x80); /* repond only to the own ID (reselection) */
-       scsi_write_byte(STEST1,0x00); /* not isolated, SCLK is used */
-       scsi_write_byte(STEST2,0x00); /* no Lowlevel Mode? */
-       scsi_write_byte(STEST3,0x80); /* enable tolerANT */
-       scsi_write_byte(CTEST3,0x04); /* clear FIFO */
-       scsi_write_byte(CTEST4,0x00);
-       scsi_write_byte(CTEST5,0x00);
-#ifdef SCSI_SINGLE_STEP
-/*     scsi_write_byte(DCNTL,IRQM | SSM);      */
-       scsi_write_byte(DCNTL,IRQD | SSM);
-       scsi_write_byte(DMODE,MAN);
-#else
-/*     scsi_write_byte(DCNTL,IRQM);    */
-       scsi_write_byte(DCNTL,IRQD);
-       scsi_write_byte(DMODE,0x00);
-#endif
-}
-#endif
-
-
-#endif /* CONFIG_SCSI_SYM53C8XX */
diff --git a/drivers/systemace.c b/drivers/systemace.c
deleted file mode 100644 (file)
index 7d82c27..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (c) 2004 Picture Elements, Inc.
- *    Stephen Williams (XXXXXXXXXXXXXXXX)
- *
- *    This source code is free software; you can redistribute it
- *    and/or modify it in source code form under the terms of the GNU
- *    General Public License as published by the Free Software
- *    Foundation; either version 2 of the License, or (at your option)
- *    any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-/*
- * The Xilinx SystemACE chip support is activated by defining
- * CONFIG_SYSTEMACE to turn on support, and CFG_SYSTEMACE_BASE
- * to set the base address of the device. This code currently
- * assumes that the chip is connected via a byte-wide bus.
- *
- * The CONFIG_SYSTEMACE also adds to fat support the device class
- * "ace" that allows the user to execute "fatls ace 0" and the
- * like. This works by making the systemace_get_dev function
- * available to cmd_fat.c:get_dev and filling in a block device
- * description that has all the bits needed for FAT support to
- * read sectors.
- *
- * According to Xilinx technical support, before accessing the
- * SystemACE CF you need to set the following control bits:
- *      FORCECFGMODE : 1
- *      CFGMODE : 0
- *      CFGSTART : 0
- */
-
-#include <common.h>
-#include <command.h>
-#include <systemace.h>
-#include <part.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_SYSTEMACE
-
-/*
- * The ace_readw and writew functions read/write 16bit words, but the
- * offset value is the BYTE offset as most used in the Xilinx
- * datasheet for the SystemACE chip. The CFG_SYSTEMACE_BASE is defined
- * to be the base address for the chip, usually in the local
- * peripheral bus.
- */
-#if (CFG_SYSTEMACE_WIDTH == 8)
-#if !defined(__BIG_ENDIAN)
-#define ace_readw(off) ((readb(CFG_SYSTEMACE_BASE+off)<<8) | \
-                       (readb(CFG_SYSTEMACE_BASE+off+1)))
-#define ace_writew(val, off) {writeb(val>>8, CFG_SYSTEMACE_BASE+off); \
-                             writeb(val, CFG_SYSTEMACE_BASE+off+1);}
-#else
-#define ace_readw(off) ((readb(CFG_SYSTEMACE_BASE+off)) | \
-                       (readb(CFG_SYSTEMACE_BASE+off+1)<<8))
-#define ace_writew(val, off) {writeb(val, CFG_SYSTEMACE_BASE+off); \
-                             writeb(val>>8, CFG_SYSTEMACE_BASE+off+1);}
-#endif
-#else
-#define ace_readw(off) (in16(CFG_SYSTEMACE_BASE+off))
-#define ace_writew(val, off) (out16(CFG_SYSTEMACE_BASE+off,val))
-#endif
-
-/* */
-
-static unsigned long systemace_read(int dev, unsigned long start,
-                                   unsigned long blkcnt, void *buffer);
-
-static block_dev_desc_t systemace_dev = { 0 };
-
-static int get_cf_lock(void)
-{
-       int retry = 10;
-
-       /* CONTROLREG = LOCKREG */
-       unsigned val = ace_readw(0x18);
-       val |= 0x0002;
-       ace_writew((val & 0xffff), 0x18);
-
-       /* Wait for MPULOCK in STATUSREG[15:0] */
-       while (!(ace_readw(0x04) & 0x0002)) {
-
-               if (retry < 0)
-                       return -1;
-
-               udelay(100000);
-               retry -= 1;
-       }
-
-       return 0;
-}
-
-static void release_cf_lock(void)
-{
-       unsigned val = ace_readw(0x18);
-       val &= ~(0x0002);
-       ace_writew((val & 0xffff), 0x18);
-}
-
-block_dev_desc_t *systemace_get_dev(int dev)
-{
-       /* The first time through this, the systemace_dev object is
-          not yet initialized. In that case, fill it in. */
-       if (systemace_dev.blksz == 0) {
-               systemace_dev.if_type = IF_TYPE_UNKNOWN;
-               systemace_dev.dev = 0;
-               systemace_dev.part_type = PART_TYPE_UNKNOWN;
-               systemace_dev.type = DEV_TYPE_HARDDISK;
-               systemace_dev.blksz = 512;
-               systemace_dev.removable = 1;
-               systemace_dev.block_read = systemace_read;
-
-               /*
-                * Ensure the correct bus mode (8/16 bits) gets enabled
-                */
-               ace_writew(CFG_SYSTEMACE_WIDTH == 8 ? 0 : 0x0001, 0);
-
-               init_part(&systemace_dev);
-
-       }
-
-       return &systemace_dev;
-}
-
-/*
- * This function is called (by dereferencing the block_read pointer in
- * the dev_desc) to read blocks of data. The return value is the
- * number of blocks read. A zero return indicates an error.
- */
-static unsigned long systemace_read(int dev, unsigned long start,
-                                   unsigned long blkcnt, void *buffer)
-{
-       int retry;
-       unsigned blk_countdown;
-       unsigned char *dp = buffer;
-       unsigned val;
-
-       if (get_cf_lock() < 0) {
-               unsigned status = ace_readw(0x04);
-
-               /* If CFDETECT is false, card is missing. */
-               if (!(status & 0x0010)) {
-                       printf("** CompactFlash card not present. **\n");
-                       return 0;
-               }
-
-               printf("**** ACE locked away from me (STATUSREG=%04x)\n",
-                      status);
-               return 0;
-       }
-#ifdef DEBUG_SYSTEMACE
-       printf("... systemace read %lu sectors at %lu\n", blkcnt, start);
-#endif
-
-       retry = 2000;
-       for (;;) {
-               val = ace_readw(0x04);
-
-               /* If CFDETECT is false, card is missing. */
-               if (!(val & 0x0010)) {
-                       printf("**** ACE CompactFlash not found.\n");
-                       release_cf_lock();
-                       return 0;
-               }
-
-               /* If RDYFORCMD, then we are ready to go. */
-               if (val & 0x0100)
-                       break;
-
-               if (retry < 0) {
-                       printf("**** SystemACE not ready.\n");
-                       release_cf_lock();
-                       return 0;
-               }
-
-               udelay(1000);
-               retry -= 1;
-       }
-
-       /* The SystemACE can only transfer 256 sectors at a time, so
-          limit the current chunk of sectors. The blk_countdown
-          variable is the number of sectors left to transfer. */
-
-       blk_countdown = blkcnt;
-       while (blk_countdown > 0) {
-               unsigned trans = blk_countdown;
-
-               if (trans > 256)
-                       trans = 256;
-
-#ifdef DEBUG_SYSTEMACE
-               printf("... transfer %lu sector in a chunk\n", trans);
-#endif
-               /* Write LBA block address */
-               ace_writew((start >> 0) & 0xffff, 0x10);
-               ace_writew((start >> 16) & 0x0fff, 0x12);
-
-               /* NOTE: in the Write Sector count below, a count of 0
-                  causes a transfer of 256, so &0xff gives the right
-                  value for whatever transfer count we want. */
-
-               /* Write sector count | ReadMemCardData. */
-               ace_writew((trans & 0xff) | 0x0300, 0x14);
-
-/*
- * For FPGA configuration via SystemACE is reset unacceptable
- * CFGDONE bit in STATUSREG is not set to 1.
- */
-#ifndef SYSTEMACE_CONFIG_FPGA
-               /* Reset the configruation controller */
-               val = ace_readw(0x18);
-               val |= 0x0080;
-               ace_writew(val, 0x18);
-#endif
-
-               retry = trans * 16;
-               while (retry > 0) {
-                       int idx;
-
-                       /* Wait for buffer to become ready. */
-                       while (!(ace_readw(0x04) & 0x0020)) {
-                               udelay(100);
-                       }
-
-                       /* Read 16 words of 2bytes from the sector buffer. */
-                       for (idx = 0; idx < 16; idx += 1) {
-                               unsigned short val = ace_readw(0x40);
-                               *dp++ = val & 0xff;
-                               *dp++ = (val >> 8) & 0xff;
-                       }
-
-                       retry -= 1;
-               }
-
-               /* Clear the configruation controller reset */
-               val = ace_readw(0x18);
-               val &= ~0x0080;
-               ace_writew(val, 0x18);
-
-               /* Count the blocks we transfer this time. */
-               start += trans;
-               blk_countdown -= trans;
-       }
-
-       release_cf_lock();
-
-       return blkcnt;
-}
-#endif /* CONFIG_SYSTEMACE */
diff --git a/drivers/ti_pci1410a.c b/drivers/ti_pci1410a.c
deleted file mode 100644 (file)
index 208ca50..0000000
+++ /dev/null
@@ -1,665 +0,0 @@
-/*
- * (C) Copyright 2000-2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- * (C) Copyright 2002
- * Daniel Engström, Omicron Ceti AB
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- ********************************************************************
- *
- * Lots of code copied from:
- *
- * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
- * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
- *
- * "The ExCA standard specifies that socket controllers should provide
- * two IO and five memory windows per socket, which can be independently
- * configured and positioned in the host address space and mapped to
- * arbitrary segments of card address space. " - David A Hinds. 1999
- *
- * This controller does _not_ meet the ExCA standard.
- *
- * m8xx pcmcia controller brief info:
- * + 8 windows (attrib, mem, i/o)
- * + up to two slots (SLOT_A and SLOT_B)
- * + inputpins, outputpins, event and mask registers.
- * - no offset register. sigh.
- *
- * Because of the lacking offset register we must map the whole card.
- * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
- * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
- * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
- * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
- * They are maximum 64KByte each...
- */
-
-
-#undef DEBUG           /**/
-
-/*
- * PCMCIA support
- */
-#include <common.h>
-#include <command.h>
-#include <config.h>
-#include <pci.h>
-#include <asm/io.h>
-
-#include <pcmcia.h>
-
-#if defined(CONFIG_CMD_PCMCIA) && defined(CONFIG_IDE_TI_CARDBUS)
-
-int pcmcia_on(int ide_base_bus);
-
-static int  pcmcia_off(void);
-static int  hardware_disable(int slot);
-static int  hardware_enable(int slot);
-static int  voltage_set(int slot, int vcc, int vpp);
-static void print_funcid(int func);
-static void print_fixed(volatile uchar *p);
-static int  identify(volatile uchar *p);
-static int  check_ide_device(int slot, int ide_base_bus);
-
-
-/* ------------------------------------------------------------------------- */
-
-
-const char *indent = "\t   ";
-
-/* ------------------------------------------------------------------------- */
-
-
-int do_pinit(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-{
-#ifndef CFG_FIRST_PCMCIA_BUS
-# define CFG_FIRST_PCMCIA_BUS 0
-#endif
-
-       int rcode = 0;
-
-       if (argc != 2) {
-               printf ("Usage: pinit {on | off}\n");
-               return 1;
-       }
-       if (strcmp(argv[1],"on") == 0) {
-               rcode = pcmcia_on(CFG_FIRST_PCMCIA_BUS);
-       } else if (strcmp(argv[1],"off") == 0) {
-               rcode = pcmcia_off();
-       } else {
-               printf ("Usage: pinit {on | off}\n");
-               return 1;
-       }
-
-       return rcode;
-}
-
-/* ------------------------------------------------------------------------- */
-
-
-static struct pci_device_id supported[] = {
-       { PCI_VENDOR_ID_TI, 0xac50 }, /* Ti PCI1410A */
-       { PCI_VENDOR_ID_TI, 0xac56 }, /* Ti PCI1510 */
-       { }
-};
-
-static pci_dev_t devbusfn;
-static u32 socket_base;
-static u32 pcmcia_cis_ptr;
-
-int pcmcia_on(int ide_base_bus)
-{
-       u16 dev_id;
-       u32 socket_status;
-       int slot = 0;
-       int cis_len;
-       u16 io_base;
-       u16 io_len;
-
-       /*
-        * Find the CardBus PCI device(s).
-        */
-       if ((devbusfn = pci_find_devices(supported, 0)) < 0) {
-               printf("Ti CardBus: not found\n");
-               return 1;
-       }
-
-       pci_read_config_word(devbusfn, PCI_DEVICE_ID, &dev_id);
-
-       if (dev_id == 0xac56) {
-               debug("Enable PCMCIA Ti PCI1510\n");
-       } else {
-               debug("Enable PCMCIA Ti PCI1410A\n");
-       }
-
-       pcmcia_cis_ptr = CFG_PCMCIA_CIS_WIN;
-       cis_len = CFG_PCMCIA_CIS_WIN_SIZE;
-
-       io_base = CFG_PCMCIA_IO_WIN;
-       io_len = CFG_PCMCIA_IO_WIN_SIZE;
-
-       /*
-        * Setup the PCI device.
-        */
-       pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &socket_base);
-       socket_base &= ~0xf;
-
-       socket_status = readl(socket_base+8);
-       if ((socket_status & 6) == 0) {
-               printf("Card Present: ");
-
-               switch (socket_status & 0x3c00) {
-
-               case 0x400:
-                       printf("5V ");
-                       break;
-               case 0x800:
-                       printf("3.3V ");
-                       break;
-               case 0xc00:
-                       printf("3.3/5V ");
-                       break;
-               default:
-                       printf("unsupported Vcc ");
-                       break;
-               }
-               switch (socket_status & 0x30) {
-               case 0x10:
-                       printf("16bit PC-Card\n");
-                       break;
-               case 0x20:
-                       printf("32bit CardBus Card\n");
-                       break;
-               default:
-                       printf("8bit PC-Card\n");
-                       break;
-               }
-       }
-
-
-       writeb(0x41, socket_base + 0x806); /* Enable I/O window 0 and memory window 0 */
-       writeb(0x0e, socket_base + 0x807); /* Reset I/O window options */
-
-       /* Careful: the linux yenta driver do not seem to reset the offset
-        * in the i/o windows, so leaving them non-zero is a problem */
-
-       writeb(io_base & 0xff, socket_base + 0x808); /* I/O window 0 base address */
-       writeb(io_base>>8, socket_base + 0x809);
-       writeb((io_base + io_len - 1) & 0xff, socket_base + 0x80a); /* I/O window 0 end address */
-       writeb((io_base + io_len - 1)>>8, socket_base + 0x80b);
-       writeb(0x00, socket_base + 0x836);      /* I/O window 0 offset address 0x000 */
-       writeb(0x00, socket_base + 0x837);
-
-
-       writeb((pcmcia_cis_ptr&0x000ff000) >> 12,
-              socket_base + 0x810); /* Memory window 0 start address bits 19-12 */
-       writeb((pcmcia_cis_ptr&0x00f00000) >> 20,
-              socket_base + 0x811);  /* Memory window 0 start address bits 23-20 */
-       writeb(((pcmcia_cis_ptr+cis_len-1) & 0x000ff000) >> 12,
-               socket_base + 0x812); /* Memory window 0 end address bits 19-12*/
-       writeb(((pcmcia_cis_ptr+cis_len-1) & 0x00f00000) >> 20,
-               socket_base + 0x813); /* Memory window 0 end address bits 23-20*/
-       writeb(0x00, socket_base + 0x814); /* Memory window 0 offset bits 19-12 */
-       writeb(0x40, socket_base + 0x815); /* Memory window 0 offset bits 23-20 and
-                                           * options (read/write, attribute access) */
-       writeb(0x00, socket_base + 0x816); /* ExCA card-detect and general control  */
-       writeb(0x00, socket_base + 0x81e); /* ExCA global control (interrupt modes) */
-
-       writeb((pcmcia_cis_ptr & 0xff000000) >> 24,
-              socket_base + 0x840); /* Memory window address bits 31-24 */
-
-
-       /* turn off voltage */
-       if (voltage_set(slot, 0, 0)) {
-               return 1;
-       }
-
-       /* Enable external hardware */
-       if (hardware_enable(slot)) {
-               return 1;
-       }
-
-       if (check_ide_device(slot, ide_base_bus)) {
-               return 1;
-       }
-
-       return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-
-static int pcmcia_off (void)
-{
-       int slot = 0;
-
-       writeb(0x00, socket_base + 0x806); /* disable all I/O and memory windows */
-
-       writeb(0x00, socket_base + 0x808); /* I/O window 0 base address */
-       writeb(0x00, socket_base + 0x809);
-       writeb(0x00, socket_base + 0x80a); /* I/O window 0 end address */
-       writeb(0x00, socket_base + 0x80b);
-       writeb(0x00, socket_base + 0x836); /* I/O window 0 offset address  */
-       writeb(0x00, socket_base + 0x837);
-
-       writeb(0x00, socket_base + 0x80c); /* I/O window 1 base address  */
-       writeb(0x00, socket_base + 0x80d);
-       writeb(0x00, socket_base + 0x80e); /* I/O window 1 end address  */
-       writeb(0x00, socket_base + 0x80f);
-       writeb(0x00, socket_base + 0x838); /* I/O window 1 offset address  */
-       writeb(0x00, socket_base + 0x839);
-
-       writeb(0x00, socket_base + 0x810); /* Memory window 0 start address */
-       writeb(0x00, socket_base + 0x811);
-       writeb(0x00, socket_base + 0x812); /* Memory window 0 end address  */
-       writeb(0x00, socket_base + 0x813);
-       writeb(0x00, socket_base + 0x814); /* Memory window 0 offset */
-       writeb(0x00, socket_base + 0x815);
-
-       writeb(0xc0, socket_base + 0x840); /* Memory window 0 page address */
-
-
-       /* turn off voltage */
-       voltage_set(slot, 0, 0);
-
-       /* disable external hardware */
-       printf ("Shutdown and Poweroff Ti PCI1410A\n");
-       hardware_disable(slot);
-
-       return 0;
-}
-
-
-/* ------------------------------------------------------------------------- */
-
-
-#define        MAX_TUPEL_SZ    512
-#define MAX_FEATURES   4
-int ide_devices_found;
-static int check_ide_device(int slot, int ide_base_bus)
-{
-       volatile uchar *ident = NULL;
-       volatile uchar *feature_p[MAX_FEATURES];
-       volatile uchar *p, *start;
-       int n_features = 0;
-       uchar func_id = ~0;
-       uchar code, len;
-       ushort config_base = 0;
-       int found = 0;
-       int i;
-       u32 socket_status;
-
-       debug ("PCMCIA MEM: %08X\n", pcmcia_cis_ptr);
-
-       socket_status = readl(socket_base+8);
-
-       if ((socket_status & 6) != 0 || (socket_status & 0x20) != 0) {
-               printf("no card or CardBus card\n");
-               return 1;
-       }
-
-       start = p = (volatile uchar *) pcmcia_cis_ptr;
-
-       while ((p - start) < MAX_TUPEL_SZ) {
-
-               code = *p; p += 2;
-
-               if (code == 0xFF) { /* End of chain */
-                       break;
-               }
-
-               len = *p; p += 2;
-#if defined(DEBUG) && (DEBUG > 1)
-               {
-                       volatile uchar *q = p;
-                       printf ("\nTuple code %02x  length %d\n\tData:",
-                               code, len);
-
-                       for (i = 0; i < len; ++i) {
-                               printf (" %02x", *q);
-                               q+= 2;
-                       }
-               }
-#endif /* DEBUG */
-               switch (code) {
-               case CISTPL_VERS_1:
-                       ident = p + 4;
-                       break;
-               case CISTPL_FUNCID:
-                       /* Fix for broken SanDisk which may have 0x80 bit set */
-                       func_id = *p & 0x7F;
-                       break;
-               case CISTPL_FUNCE:
-                       if (n_features < MAX_FEATURES)
-                               feature_p[n_features++] = p;
-                       break;
-               case CISTPL_CONFIG:
-                       config_base = (*(p+6) << 8) + (*(p+4));
-                       debug ("\n## Config_base = %04x ###\n", config_base);
-               default:
-                       break;
-               }
-               p += 2 * len;
-       }
-
-       found = identify(ident);
-
-       if (func_id != ((uchar)~0)) {
-               print_funcid (func_id);
-
-               if (func_id == CISTPL_FUNCID_FIXED)
-                       found = 1;
-               else
-                       return 1;       /* no disk drive */
-       }
-
-       for (i=0; i<n_features; ++i) {
-               print_fixed(feature_p[i]);
-       }
-
-       if (!found) {
-               printf("unknown card type\n");
-               return 1;
-       }
-
-       /* select config index 1 */
-       writeb(1, pcmcia_cis_ptr + config_base);
-
-#if 0
-       printf("Confiuration Option Register: %02x\n", readb(pcmcia_cis_ptr + config_base));
-       printf("Card Confiuration and Status Register: %02x\n", readb(pcmcia_cis_ptr + config_base + 2));
-       printf("Pin Replacement Register Register: %02x\n", readb(pcmcia_cis_ptr + config_base + 4));
-       printf("Socket and Copy Register: %02x\n", readb(pcmcia_cis_ptr + config_base + 6));
-#endif
-       ide_devices_found |= (1 << (slot+ide_base_bus));
-
-       return 0;
-}
-
-
-static int voltage_set(int slot, int vcc, int vpp)
-{
-       u32 socket_control;
-       int reg=0;
-
-       switch (slot) {
-       case 0:
-               reg = socket_base + 0x10;
-               break;
-       default:
-               return 1;
-       }
-
-       socket_control = 0;
-
-
-       switch (vcc) {
-       case 50:
-               socket_control |= 0x20;
-               break;
-       case 33:
-               socket_control |= 0x30;
-               break;
-       case 0:
-       default:
-       }
-
-       switch (vpp) {
-       case 120:
-               socket_control |= 0x1;
-               break;
-       case 50:
-               socket_control |= 0x2;
-               break;
-       case 33:
-               socket_control |= 0x3;
-               break;
-       case 0:
-       default:
-       }
-
-       writel(socket_control, reg);
-
-       debug ("voltage_set: Ti PCI1410A Slot %d, Vcc=%d.%d, Vpp=%d.%d\n",
-               slot, vcc/10, vcc%10, vpp/10, vpp%10);
-
-       udelay(500);
-       return 0;
-}
-
-
-static int hardware_enable(int slot)
-{
-       u32 socket_status;
-       u16 brg_ctrl;
-       int is_82365sl;
-
-       socket_status = readl(socket_base+8);
-
-       if ((socket_status & 6) == 0) {
-
-               switch (socket_status & 0x3c00) {
-
-               case 0x400:
-                       printf("5V ");
-                       voltage_set(slot, 50, 0);
-                       break;
-               case 0x800:
-                       voltage_set(slot, 33, 0);
-                       break;
-               case 0xc00:
-                       voltage_set(slot, 33, 0);
-                       break;
-               default:
-                       voltage_set(slot, 0, 0);
-                       break;
-               }
-       } else {
-               voltage_set(slot, 0, 0);
-       }
-
-       pci_read_config_word(devbusfn, PCI_BRIDGE_CONTROL, &brg_ctrl);
-       brg_ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
-       pci_write_config_word(devbusfn, PCI_BRIDGE_CONTROL, brg_ctrl);
-       is_82365sl = ((readb(socket_base+0x800) & 0x0f) == 2);
-       writeb(is_82365sl?0x90:0x98, socket_base+0x802);
-       writeb(0x67, socket_base+0x803);
-       udelay(100000);
-#if 0
-       printf("ExCA Id %02x, Card Status %02x, Power config %02x, Interrupt Config %02x, bridge control %04x %d\n",
-              readb(socket_base+0x800), readb(socket_base+0x801),
-              readb(socket_base+0x802), readb(socket_base+0x803), brg_ctrl, is_82365sl);
-#endif
-
-       return ((readb(socket_base+0x801)&0x6c)==0x6c)?0:1;
-}
-
-
-static int hardware_disable(int slot)
-{
-       voltage_set(slot, 0, 0);
-       return 0;
-}
-
-static void print_funcid(int func)
-{
-       puts(indent);
-       switch (func) {
-       case CISTPL_FUNCID_MULTI:
-               puts(" Multi-Function");
-               break;
-       case CISTPL_FUNCID_MEMORY:
-               puts(" Memory");
-               break;
-       case CISTPL_FUNCID_SERIAL:
-               puts(" Serial Port");
-               break;
-       case CISTPL_FUNCID_PARALLEL:
-               puts(" Parallel Port");
-               break;
-       case CISTPL_FUNCID_FIXED:
-               puts(" Fixed Disk");
-               break;
-       case CISTPL_FUNCID_VIDEO:
-               puts(" Video Adapter");
-               break;
-       case CISTPL_FUNCID_NETWORK:
-               puts(" Network Adapter");
-               break;
-       case CISTPL_FUNCID_AIMS:
-               puts(" AIMS Card");
-               break;
-       case CISTPL_FUNCID_SCSI:
-               puts(" SCSI Adapter");
-               break;
-       default:
-               puts(" Unknown");
-               break;
-       }
-       puts(" Card\n");
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void print_fixed(volatile uchar *p)
-{
-       if (p == NULL)
-               return;
-
-       puts(indent);
-
-       switch (*p) {
-       case CISTPL_FUNCE_IDE_IFACE:
-               {   uchar iface = *(p+2);
-
-                       puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
-                       puts (" interface ");
-                       break;
-               }
-       case CISTPL_FUNCE_IDE_MASTER:
-       case CISTPL_FUNCE_IDE_SLAVE:
-               {
-                       uchar f1 = *(p+2);
-                       uchar f2 = *(p+4);
-
-                       puts((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
-
-                       if (f1 & CISTPL_IDE_UNIQUE) {
-                               puts(" [unique]");
-                       }
-
-                       puts((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
-
-                       if (f2 & CISTPL_IDE_HAS_SLEEP) {
-                               puts(" [sleep]");
-                       }
-
-                       if (f2 & CISTPL_IDE_HAS_STANDBY) {
-                               puts(" [standby]");
-                       }
-
-                       if (f2 & CISTPL_IDE_HAS_IDLE) {
-                               puts(" [idle]");
-                       }
-
-                       if (f2 & CISTPL_IDE_LOW_POWER) {
-                               puts(" [low power]");
-                       }
-
-                       if (f2 & CISTPL_IDE_REG_INHIBIT) {
-                               puts(" [reg inhibit]");
-                       }
-
-                       if (f2 & CISTPL_IDE_HAS_INDEX) {
-                               puts(" [index]");
-                       }
-
-                       if (f2 & CISTPL_IDE_IOIS16) {
-                               puts(" [IOis16]");
-                       }
-
-                       break;
-               }
-       }
-       putc('\n');
-}
-
-/* ------------------------------------------------------------------------- */
-
-#define MAX_IDENT_CHARS                64
-#define        MAX_IDENT_FIELDS        4
-
-static uchar *known_cards[] = {
-       "ARGOSY PnPIDE D5",
-       NULL
-};
-
-static int identify(volatile uchar *p)
-{
-       uchar id_str[MAX_IDENT_CHARS];
-       uchar data;
-       uchar *t;
-       uchar **card;
-       int i, done;
-
-       if (p == NULL)
-               return (0);     /* Don't know */
-
-       t = id_str;
-       done =0;
-
-       for (i=0; i<=4 && !done; ++i, p+=2) {
-               while ((data = *p) != '\0') {
-                       if (data == 0xFF) {
-                               done = 1;
-                               break;
-                       }
-                       *t++ = data;
-                       if (t == &id_str[MAX_IDENT_CHARS-1]) {
-                               done = 1;
-                               break;
-                       }
-                       p += 2;
-               }
-               if (!done)
-                       *t++ = ' ';
-       }
-       *t = '\0';
-       while (--t > id_str) {
-               if (*t == ' ') {
-                       *t = '\0';
-               } else {
-                       break;
-               }
-       }
-       puts(id_str);
-       putc('\n');
-
-       for (card=known_cards; *card; ++card) {
-               debug ("## Compare against \"%s\"\n", *card);
-               if (strcmp(*card, id_str) == 0) {       /* found! */
-                       debug ("## CARD FOUND ##\n");
-                       return 1;
-               }
-       }
-
-       return 0;       /* don't know */
-}
-
-#endif /* CONFIG_IDE_TI_CARDBUS */
diff --git a/drivers/tigon3.c b/drivers/tigon3.c
deleted file mode 100644 (file)
index 5f6a4ec..0000000
+++ /dev/null
@@ -1,5699 +0,0 @@
-/******************************************************************************/
-/*                                                                            */
-/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
-/* Corporation.                                                               */
-/* All rights reserved.                                                       */
-/*                                                                            */
-/* This program is free software; you can redistribute it and/or modify       */
-/* it under the terms of the GNU General Public License as published by       */
-/* the Free Software Foundation, located in the file LICENSE.                 */
-/*                                                                            */
-/* History:                                                                   */
-/******************************************************************************/
-#include <common.h>
-#include <asm/types.h>
-#if defined(CONFIG_CMD_NET) && !defined(CONFIG_NET_MULTI) && \
-       defined(CONFIG_TIGON3)
-#ifdef CONFIG_BMW
-#include <mpc824x.h>
-#endif
-#include <malloc.h>
-#include <linux/byteorder/big_endian.h>
-#include "bcm570x_mm.h"
-
-#define EMBEDDED 1
-/******************************************************************************/
-/* Local functions. */
-/******************************************************************************/
-
-LM_STATUS LM_Abort (PLM_DEVICE_BLOCK pDevice);
-LM_STATUS LM_QueueRxPackets (PLM_DEVICE_BLOCK pDevice);
-
-static LM_STATUS LM_TranslateRequestedMediaType (LM_REQUESTED_MEDIA_TYPE
-                                                RequestedMediaType,
-                                                PLM_MEDIA_TYPE pMediaType,
-                                                PLM_LINE_SPEED pLineSpeed,
-                                                PLM_DUPLEX_MODE pDuplexMode);
-
-static LM_STATUS LM_InitBcm540xPhy (PLM_DEVICE_BLOCK pDevice);
-
-__inline static LM_VOID LM_ServiceRxInterrupt (PLM_DEVICE_BLOCK pDevice);
-__inline static LM_VOID LM_ServiceTxInterrupt (PLM_DEVICE_BLOCK pDevice);
-
-static LM_STATUS LM_ForceAutoNegBcm540xPhy (PLM_DEVICE_BLOCK pDevice,
-                                           LM_REQUESTED_MEDIA_TYPE
-                                           RequestedMediaType);
-static LM_STATUS LM_ForceAutoNeg (PLM_DEVICE_BLOCK pDevice,
-                                 LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
-static LM_UINT32 GetPhyAdFlowCntrlSettings (PLM_DEVICE_BLOCK pDevice);
-STATIC LM_STATUS LM_SetFlowControl (PLM_DEVICE_BLOCK pDevice,
-                                   LM_UINT32 LocalPhyAd,
-                                   LM_UINT32 RemotePhyAd);
-#if INCLUDE_TBI_SUPPORT
-STATIC LM_STATUS LM_SetupFiberPhy (PLM_DEVICE_BLOCK pDevice);
-STATIC LM_STATUS LM_InitBcm800xPhy (PLM_DEVICE_BLOCK pDevice);
-#endif
-STATIC LM_STATUS LM_SetupCopperPhy (PLM_DEVICE_BLOCK pDevice);
-STATIC PLM_ADAPTER_INFO LM_GetAdapterInfoBySsid (LM_UINT16 Svid,
-                                                LM_UINT16 Ssid);
-STATIC LM_STATUS LM_DmaTest (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
-                            LM_PHYSICAL_ADDRESS BufferPhy,
-                            LM_UINT32 BufferSize);
-STATIC LM_STATUS LM_HaltCpu (PLM_DEVICE_BLOCK pDevice, LM_UINT32 cpu_number);
-STATIC LM_STATUS LM_ResetChip (PLM_DEVICE_BLOCK pDevice);
-STATIC LM_STATUS LM_Test4GBoundary (PLM_DEVICE_BLOCK pDevice,
-                                   PLM_PACKET pPacket, PT3_SND_BD pSendBd);
-
-/******************************************************************************/
-/* External functions. */
-/******************************************************************************/
-
-LM_STATUS LM_LoadRlsFirmware (PLM_DEVICE_BLOCK pDevice);
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-LM_UINT32 LM_RegRdInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register)
-{
-       LM_UINT32 Value32;
-
-#if PCIX_TARGET_WORKAROUND
-       MM_ACQUIRE_UNDI_LOCK (pDevice);
-#endif
-       MM_WriteConfig32 (pDevice, T3_PCI_REG_ADDR_REG, Register);
-       MM_ReadConfig32 (pDevice, T3_PCI_REG_DATA_REG, &Value32);
-#if PCIX_TARGET_WORKAROUND
-       MM_RELEASE_UNDI_LOCK (pDevice);
-#endif
-
-       return Value32;
-}                              /* LM_RegRdInd */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-LM_VOID
-LM_RegWrInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register, LM_UINT32 Value32)
-{
-
-#if PCIX_TARGET_WORKAROUND
-       MM_ACQUIRE_UNDI_LOCK (pDevice);
-#endif
-       MM_WriteConfig32 (pDevice, T3_PCI_REG_ADDR_REG, Register);
-       MM_WriteConfig32 (pDevice, T3_PCI_REG_DATA_REG, Value32);
-#if PCIX_TARGET_WORKAROUND
-       MM_RELEASE_UNDI_LOCK (pDevice);
-#endif
-}                              /* LM_RegWrInd */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-LM_UINT32 LM_MemRdInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr)
-{
-       LM_UINT32 Value32;
-
-       MM_ACQUIRE_UNDI_LOCK (pDevice);
-#ifdef BIG_ENDIAN_HOST
-       MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
-       Value32 = REG_RD (pDevice, PciCfg.MemWindowData);
-       /*    Value32 = REG_RD(pDevice,uIntMem.Mbuf[(MemAddr & 0x7fff)/4]); */
-#else
-       MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
-       MM_ReadConfig32 (pDevice, T3_PCI_MEM_WIN_DATA_REG, &Value32);
-#endif
-       MM_RELEASE_UNDI_LOCK (pDevice);
-
-       return Value32;
-}                              /* LM_MemRdInd */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-LM_VOID
-LM_MemWrInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr, LM_UINT32 Value32)
-{
-       MM_ACQUIRE_UNDI_LOCK (pDevice);
-#ifdef BIG_ENDIAN_HOST
-       REG_WR (pDevice, PciCfg.MemWindowBaseAddr, MemAddr);
-       REG_WR (pDevice, uIntMem.Mbuf[(MemAddr & 0x7fff) / 4], Value32);
-#else
-       MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
-       MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_DATA_REG, Value32);
-#endif
-       MM_RELEASE_UNDI_LOCK (pDevice);
-}                              /* LM_MemWrInd */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-LM_STATUS LM_QueueRxPackets (PLM_DEVICE_BLOCK pDevice)
-{
-       LM_STATUS Lmstatus;
-       PLM_PACKET pPacket;
-       PT3_RCV_BD pRcvBd;
-       LM_UINT32 StdBdAdded = 0;
-#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
-       LM_UINT32 JumboBdAdded = 0;
-#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
-
-       Lmstatus = LM_STATUS_SUCCESS;
-
-       pPacket = (PLM_PACKET) QQ_PopHead (&pDevice->RxPacketFreeQ.Container);
-       while (pPacket) {
-               switch (pPacket->u.Rx.RcvProdRing) {
-#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
-               case T3_JUMBO_RCV_PROD_RING:    /* Jumbo Receive Ring. */
-                       /* Initialize the buffer descriptor. */
-                       pRcvBd =
-                           &pDevice->pRxJumboBdVirt[pDevice->RxJumboProdIdx];
-                       pRcvBd->Flags =
-                           RCV_BD_FLAG_END | RCV_BD_FLAG_JUMBO_RING;
-                       pRcvBd->Len = (LM_UINT16) pDevice->RxJumboBufferSize;
-
-                       /* Initialize the receive buffer pointer */
-#if 0                          /* Jimmy, deleted in new */
-                       pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low;
-                       pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;
-#endif
-                       MM_MapRxDma (pDevice, pPacket, &pRcvBd->HostAddr);
-
-                       /* The opaque field may point to an offset from a fix addr. */
-                       pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR (pPacket) -
-                                                     MM_UINT_PTR (pDevice->
-                                                                  pPacketDescBase));
-
-                       /* Update the producer index. */
-                       pDevice->RxJumboProdIdx =
-                           (pDevice->RxJumboProdIdx +
-                            1) & T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
-
-                       JumboBdAdded++;
-                       break;
-#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
-
-               case T3_STD_RCV_PROD_RING:      /* Standard Receive Ring. */
-                       /* Initialize the buffer descriptor. */
-                       pRcvBd = &pDevice->pRxStdBdVirt[pDevice->RxStdProdIdx];
-                       pRcvBd->Flags = RCV_BD_FLAG_END;
-                       pRcvBd->Len = MAX_STD_RCV_BUFFER_SIZE;
-
-                       /* Initialize the receive buffer pointer */
-#if 0                          /* Jimmy, deleted in new replaced with MM_MapRxDma */
-                       pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low;
-                       pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;
-#endif
-                       MM_MapRxDma (pDevice, pPacket, &pRcvBd->HostAddr);
-
-                       /* The opaque field may point to an offset from a fix addr. */
-                       pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR (pPacket) -
-                                                     MM_UINT_PTR (pDevice->
-                                                                  pPacketDescBase));
-
-                       /* Update the producer index. */
-                       pDevice->RxStdProdIdx = (pDevice->RxStdProdIdx + 1) &
-                           T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
-
-                       StdBdAdded++;
-                       break;
-
-               case T3_UNKNOWN_RCV_PROD_RING:
-               default:
-                       Lmstatus = LM_STATUS_FAILURE;
-                       break;
-               }               /* switch */
-
-               /* Bail out if there is any error. */
-               if (Lmstatus != LM_STATUS_SUCCESS) {
-                       break;
-               }
-
-               pPacket =
-                   (PLM_PACKET) QQ_PopHead (&pDevice->RxPacketFreeQ.Container);
-       }                       /* while */
-
-       wmb ();
-       /* Update the procedure index. */
-       if (StdBdAdded) {
-               MB_REG_WR (pDevice, Mailbox.RcvStdProdIdx.Low,
-                          pDevice->RxStdProdIdx);
-       }
-#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
-       if (JumboBdAdded) {
-               MB_REG_WR (pDevice, Mailbox.RcvJumboProdIdx.Low,
-                          pDevice->RxJumboProdIdx);
-       }
-#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
-
-       return Lmstatus;
-}                              /* LM_QueueRxPackets */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-STATIC LM_VOID LM_NvramInit (PLM_DEVICE_BLOCK pDevice)
-{
-       LM_UINT32 Value32;
-       LM_UINT32 j;
-
-       /* Intialize clock period and state machine. */
-       Value32 = SEEPROM_ADDR_CLK_PERD (SEEPROM_CLOCK_PERIOD) |
-           SEEPROM_ADDR_FSM_RESET;
-       REG_WR (pDevice, Grc.EepromAddr, Value32);
-
-       for (j = 0; j < 100; j++) {
-               MM_Wait (10);
-       }
-
-       /* Serial eeprom access using the Grc.EepromAddr/EepromData registers. */
-       Value32 = REG_RD (pDevice, Grc.LocalCtrl);
-       REG_WR (pDevice, Grc.LocalCtrl,
-               Value32 | GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM);
-
-       /* Set the 5701 compatibility mode if we are using EEPROM. */
-       if (T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
-           T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5701) {
-               Value32 = REG_RD (pDevice, Nvram.Config1);
-               if ((Value32 & FLASH_INTERFACE_ENABLE) == 0) {
-                       /* Use the new interface to read EEPROM. */
-                       Value32 &= ~FLASH_COMPAT_BYPASS;
-
-                       REG_WR (pDevice, Nvram.Config1, Value32);
-               }
-       }
-}                              /* LM_NvRamInit */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-STATIC LM_STATUS
-LM_EepromRead (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, LM_UINT32 * pData)
-{
-       LM_UINT32 Value32;
-       LM_UINT32 Addr;
-       LM_UINT32 Dev;
-       LM_UINT32 j;
-
-       if (Offset > SEEPROM_CHIP_SIZE) {
-               return LM_STATUS_FAILURE;
-       }
-
-       Dev = Offset / SEEPROM_CHIP_SIZE;
-       Addr = Offset % SEEPROM_CHIP_SIZE;
-
-       Value32 = REG_RD (pDevice, Grc.EepromAddr);
-       Value32 &= ~(SEEPROM_ADDR_ADDRESS_MASK | SEEPROM_ADDR_DEV_ID_MASK |
-                    SEEPROM_ADDR_RW_MASK);
-       REG_WR (pDevice, Grc.EepromAddr, Value32 | SEEPROM_ADDR_DEV_ID (Dev) |
-               SEEPROM_ADDR_ADDRESS (Addr) | SEEPROM_ADDR_START |
-               SEEPROM_ADDR_READ);
-
-       for (j = 0; j < 1000; j++) {
-               Value32 = REG_RD (pDevice, Grc.EepromAddr);
-               if (Value32 & SEEPROM_ADDR_COMPLETE) {
-                       break;
-               }
-               MM_Wait (10);
-       }
-
-       if (Value32 & SEEPROM_ADDR_COMPLETE) {
-               Value32 = REG_RD (pDevice, Grc.EepromData);
-               *pData = Value32;
-
-               return LM_STATUS_SUCCESS;
-       }
-
-       return LM_STATUS_FAILURE;
-}                              /* LM_EepromRead */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-STATIC LM_STATUS
-LM_NvramRead (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, LM_UINT32 * pData)
-{
-       LM_UINT32 Value32;
-       LM_STATUS Status;
-       LM_UINT32 j;
-
-       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
-           T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
-               Status = LM_EepromRead (pDevice, Offset, pData);
-       } else {
-               /* Determine if we have flash or EEPROM. */
-               Value32 = REG_RD (pDevice, Nvram.Config1);
-               if (Value32 & FLASH_INTERFACE_ENABLE) {
-                       if (Value32 & FLASH_SSRAM_BUFFERRED_MODE) {
-                               Offset = ((Offset / BUFFERED_FLASH_PAGE_SIZE) <<
-                                         BUFFERED_FLASH_PAGE_POS) +
-                                   (Offset % BUFFERED_FLASH_PAGE_SIZE);
-                       }
-               }
-
-               REG_WR (pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
-               for (j = 0; j < 1000; j++) {
-                       if (REG_RD (pDevice, Nvram.SwArb) & SW_ARB_GNT1) {
-                               break;
-                       }
-                       MM_Wait (20);
-               }
-               if (j == 1000) {
-                       return LM_STATUS_FAILURE;
-               }
-
-               /* Read from flash or EEPROM with the new 5703/02 interface. */
-               REG_WR (pDevice, Nvram.Addr, Offset & NVRAM_ADDRESS_MASK);
-
-               REG_WR (pDevice, Nvram.Cmd, NVRAM_CMD_RD | NVRAM_CMD_DO_IT |
-                       NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
-
-               /* Wait for the done bit to clear. */
-               for (j = 0; j < 500; j++) {
-                       MM_Wait (10);
-
-                       Value32 = REG_RD (pDevice, Nvram.Cmd);
-                       if (!(Value32 & NVRAM_CMD_DONE)) {
-                               break;
-                       }
-               }
-
-               /* Wait for the done bit. */
-               if (!(Value32 & NVRAM_CMD_DONE)) {
-                       for (j = 0; j < 500; j++) {
-                               MM_Wait (10);
-
-                               Value32 = REG_RD (pDevice, Nvram.Cmd);
-                               if (Value32 & NVRAM_CMD_DONE) {
-                                       MM_Wait (10);
-
-                                       *pData =
-                                           REG_RD (pDevice, Nvram.ReadData);
-
-                                       /* Change the endianess. */
-                                       *pData =
-                                           ((*pData & 0xff) << 24) |
-                                           ((*pData & 0xff00) << 8) |
-                                           ((*pData & 0xff0000) >> 8) |
-                                           ((*pData >> 24) & 0xff);
-
-                                       break;
-                               }
-                       }
-               }
-
-               REG_WR (pDevice, Nvram.SwArb, SW_ARB_REQ_CLR1);
-               if (Value32 & NVRAM_CMD_DONE) {
-                       Status = LM_STATUS_SUCCESS;
-               } else {
-                       Status = LM_STATUS_FAILURE;
-               }
-       }
-
-       return Status;
-}                              /* LM_NvramRead */
-
-STATIC void LM_ReadVPD (PLM_DEVICE_BLOCK pDevice)
-{
-       LM_UINT32 Vpd_arr[256 / 4];
-       LM_UINT8 *Vpd = (LM_UINT8 *) & Vpd_arr[0];
-       LM_UINT32 *Vpd_dptr = &Vpd_arr[0];
-       LM_UINT32 Value32;
-       unsigned int j;
-
-       /* Read PN from VPD */
-       for (j = 0; j < 256; j += 4, Vpd_dptr++) {
-               if (LM_NvramRead (pDevice, 0x100 + j, &Value32) !=
-                   LM_STATUS_SUCCESS) {
-                       printf ("BCM570x: LM_ReadVPD: VPD read failed"
-                               " (no EEPROM onboard)\n");
-                       return;
-               }
-               *Vpd_dptr = cpu_to_le32 (Value32);
-       }
-       for (j = 0; j < 256;) {
-               unsigned int Vpd_r_len;
-               unsigned int Vpd_r_end;
-
-               if ((Vpd[j] == 0x82) || (Vpd[j] == 0x91)) {
-                       j = j + 3 + Vpd[j + 1] + (Vpd[j + 2] << 8);
-               } else if (Vpd[j] == 0x90) {
-                       Vpd_r_len = Vpd[j + 1] + (Vpd[j + 2] << 8);
-                       j += 3;
-                       Vpd_r_end = Vpd_r_len + j;
-                       while (j < Vpd_r_end) {
-                               if ((Vpd[j] == 'P') && (Vpd[j + 1] == 'N')) {
-                                       unsigned int len = Vpd[j + 2];
-
-                                       if (len <= 24) {
-                                               memcpy (pDevice->PartNo,
-                                                       &Vpd[j + 3], len);
-                                       }
-                                       break;
-                               } else {
-                                       if (Vpd[j + 2] == 0) {
-                                               break;
-                                       }
-                                       j = j + Vpd[j + 2];
-                               }
-                       }
-                       break;
-               } else {
-                       break;
-               }
-       }
-}
-
-STATIC void LM_ReadBootCodeVersion (PLM_DEVICE_BLOCK pDevice)
-{
-       LM_UINT32 Value32, offset, ver_offset;
-       int i;
-
-       if (LM_NvramRead (pDevice, 0x0, &Value32) != LM_STATUS_SUCCESS)
-               return;
-       if (Value32 != 0xaa559966)
-               return;
-       if (LM_NvramRead (pDevice, 0xc, &offset) != LM_STATUS_SUCCESS)
-               return;
-
-       offset = ((offset & 0xff) << 24) | ((offset & 0xff00) << 8) |
-           ((offset & 0xff0000) >> 8) | ((offset >> 24) & 0xff);
-       if (LM_NvramRead (pDevice, offset, &Value32) != LM_STATUS_SUCCESS)
-               return;
-       if ((Value32 == 0x0300000e) &&
-           (LM_NvramRead (pDevice, offset + 4, &Value32) == LM_STATUS_SUCCESS)
-           && (Value32 == 0)) {
-
-               if (LM_NvramRead (pDevice, offset + 8, &ver_offset) !=
-                   LM_STATUS_SUCCESS)
-                       return;
-               ver_offset = ((ver_offset & 0xff0000) >> 8) |
-                   ((ver_offset >> 24) & 0xff);
-               for (i = 0; i < 16; i += 4) {
-                       if (LM_NvramRead
-                           (pDevice, offset + ver_offset + i,
-                            &Value32) != LM_STATUS_SUCCESS) {
-                               return;
-                       }
-                       *((LM_UINT32 *) & pDevice->BootCodeVer[i]) =
-                           cpu_to_le32 (Value32);
-               }
-       } else {
-               char c;
-
-               if (LM_NvramRead (pDevice, 0x94, &Value32) != LM_STATUS_SUCCESS)
-                       return;
-
-               i = 0;
-               c = ((Value32 & 0xff0000) >> 16);
-
-               if (c < 10) {
-                       pDevice->BootCodeVer[i++] = c + '0';
-               } else {
-                       pDevice->BootCodeVer[i++] = (c / 10) + '0';
-                       pDevice->BootCodeVer[i++] = (c % 10) + '0';
-               }
-               pDevice->BootCodeVer[i++] = '.';
-               c = (Value32 & 0xff000000) >> 24;
-               if (c < 10) {
-                       pDevice->BootCodeVer[i++] = c + '0';
-               } else {
-                       pDevice->BootCodeVer[i++] = (c / 10) + '0';
-                       pDevice->BootCodeVer[i++] = (c % 10) + '0';
-               }
-               pDevice->BootCodeVer[i] = 0;
-       }
-}
-
-STATIC void LM_GetBusSpeed (PLM_DEVICE_BLOCK pDevice)
-{
-       LM_UINT32 PciState = pDevice->PciState;
-       LM_UINT32 ClockCtrl;
-       char *SpeedStr = "";
-
-       if (PciState & T3_PCI_STATE_32BIT_PCI_BUS) {
-               strcpy (pDevice->BusSpeedStr, "32-bit ");
-       } else {
-               strcpy (pDevice->BusSpeedStr, "64-bit ");
-       }
-       if (PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) {
-               strcat (pDevice->BusSpeedStr, "PCI ");
-               if (PciState & T3_PCI_STATE_HIGH_BUS_SPEED) {
-                       SpeedStr = "66MHz";
-               } else {
-                       SpeedStr = "33MHz";
-               }
-       } else {
-               strcat (pDevice->BusSpeedStr, "PCIX ");
-               if (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE) {
-                       SpeedStr = "133MHz";
-               } else {
-                       ClockCtrl = REG_RD (pDevice, PciCfg.ClockCtrl) & 0x1f;
-                       switch (ClockCtrl) {
-                       case 0:
-                               SpeedStr = "33MHz";
-                               break;
-
-                       case 2:
-                               SpeedStr = "50MHz";
-                               break;
-
-                       case 4:
-                               SpeedStr = "66MHz";
-                               break;
-
-                       case 6:
-                               SpeedStr = "100MHz";
-                               break;
-
-                       case 7:
-                               SpeedStr = "133MHz";
-                               break;
-                       }
-               }
-       }
-       strcat (pDevice->BusSpeedStr, SpeedStr);
-}
-
-/******************************************************************************/
-/* Description:                                                               */
-/*    This routine initializes default parameters and reads the PCI           */
-/*    configurations.                                                         */
-/*                                                                            */
-/* Return:                                                                    */
-/*    LM_STATUS_SUCCESS                                                       */
-/******************************************************************************/
-LM_STATUS LM_GetAdapterInfo (PLM_DEVICE_BLOCK pDevice)
-{
-       PLM_ADAPTER_INFO pAdapterInfo;
-       LM_UINT32 Value32;
-       LM_STATUS Status;
-       LM_UINT32 j;
-       LM_UINT32 EeSigFound;
-       LM_UINT32 EePhyTypeSerdes = 0;
-       LM_UINT32 EePhyLedMode = 0;
-       LM_UINT32 EePhyId = 0;
-
-       /* Get Device Id and Vendor Id */
-       Status = MM_ReadConfig32 (pDevice, PCI_VENDOR_ID_REG, &Value32);
-       if (Status != LM_STATUS_SUCCESS) {
-               return Status;
-       }
-       pDevice->PciVendorId = (LM_UINT16) Value32;
-       pDevice->PciDeviceId = (LM_UINT16) (Value32 >> 16);
-
-       /* If we are not getting the write adapter, exit. */
-       if ((Value32 != T3_PCI_ID_BCM5700) &&
-           (Value32 != T3_PCI_ID_BCM5701) &&
-           (Value32 != T3_PCI_ID_BCM5702) &&
-           (Value32 != T3_PCI_ID_BCM5702x) &&
-           (Value32 != T3_PCI_ID_BCM5702FE) &&
-           (Value32 != T3_PCI_ID_BCM5703) &&
-           (Value32 != T3_PCI_ID_BCM5703x) && (Value32 != T3_PCI_ID_BCM5704)) {
-               return LM_STATUS_FAILURE;
-       }
-
-       Status = MM_ReadConfig32 (pDevice, PCI_REV_ID_REG, &Value32);
-       if (Status != LM_STATUS_SUCCESS) {
-               return Status;
-       }
-       pDevice->PciRevId = (LM_UINT8) Value32;
-
-       /* Get IRQ. */
-       Status = MM_ReadConfig32 (pDevice, PCI_INT_LINE_REG, &Value32);
-       if (Status != LM_STATUS_SUCCESS) {
-               return Status;
-       }
-       pDevice->Irq = (LM_UINT8) Value32;
-
-       /* Get interrupt pin. */
-       pDevice->IntPin = (LM_UINT8) (Value32 >> 8);
-
-       /* Get chip revision id. */
-       Status = MM_ReadConfig32 (pDevice, T3_PCI_MISC_HOST_CTRL_REG, &Value32);
-       pDevice->ChipRevId = Value32 >> 16;
-
-       /* Get subsystem vendor. */
-       Status =
-           MM_ReadConfig32 (pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG, &Value32);
-       if (Status != LM_STATUS_SUCCESS) {
-               return Status;
-       }
-       pDevice->SubsystemVendorId = (LM_UINT16) Value32;
-
-       /* Get PCI subsystem id. */
-       pDevice->SubsystemId = (LM_UINT16) (Value32 >> 16);
-
-       /* Get the cache line size. */
-       MM_ReadConfig32 (pDevice, PCI_CACHE_LINE_SIZE_REG, &Value32);
-       pDevice->CacheLineSize = (LM_UINT8) Value32;
-       pDevice->SavedCacheLineReg = Value32;
-
-       if (pDevice->ChipRevId != T3_CHIP_ID_5703_A1 &&
-           pDevice->ChipRevId != T3_CHIP_ID_5703_A2 &&
-           pDevice->ChipRevId != T3_CHIP_ID_5704_A0) {
-               pDevice->UndiFix = FALSE;
-       }
-#if !PCIX_TARGET_WORKAROUND
-       pDevice->UndiFix = FALSE;
-#endif
-       /* Map the memory base to system address space. */
-       if (!pDevice->UndiFix) {
-               Status = MM_MapMemBase (pDevice);
-               if (Status != LM_STATUS_SUCCESS) {
-                       return Status;
-               }
-               /* Initialize the memory view pointer. */
-               pDevice->pMemView = (PT3_STD_MEM_MAP) pDevice->pMappedMemBase;
-       }
-#if PCIX_TARGET_WORKAROUND
-       /* store whether we are in PCI are PCI-X mode */
-       pDevice->EnablePciXFix = FALSE;
-
-       MM_ReadConfig32 (pDevice, T3_PCI_STATE_REG, &Value32);
-       if ((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0) {
-               /* Enable PCI-X workaround only if we are running on 5700 BX. */
-               if (T3_CHIP_REV (pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) {
-                       pDevice->EnablePciXFix = TRUE;
-               }
-       }
-       if (pDevice->UndiFix) {
-               pDevice->EnablePciXFix = TRUE;
-       }
-#endif
-       /* Bx bug: due to the "byte_enable bug" in PCI-X mode, the power */
-       /* management register may be clobbered which may cause the */
-       /* BCM5700 to go into D3 state.  While in this state, we will */
-       /* not have memory mapped register access.  As a workaround, we */
-       /* need to restore the device to D0 state. */
-       MM_ReadConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, &Value32);
-       Value32 |= T3_PM_PME_ASSERTED;
-       Value32 &= ~T3_PM_POWER_STATE_MASK;
-       Value32 |= T3_PM_POWER_STATE_D0;
-       MM_WriteConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, Value32);
-
-       /* read the current PCI command word */
-       MM_ReadConfig32 (pDevice, PCI_COMMAND_REG, &Value32);
-
-       /* Make sure bus-mastering is enabled. */
-       Value32 |= PCI_BUSMASTER_ENABLE;
-
-#if PCIX_TARGET_WORKAROUND
-       /* if we are in PCI-X mode, also make sure mem-mapping and SERR#/PERR#
-          are enabled */
-       if (pDevice->EnablePciXFix == TRUE) {
-               Value32 |= (PCI_MEM_SPACE_ENABLE | PCI_SYSTEM_ERROR_ENABLE |
-                           PCI_PARITY_ERROR_ENABLE);
-       }
-       if (pDevice->UndiFix) {
-               Value32 &= ~PCI_MEM_SPACE_ENABLE;
-       }
-#endif
-
-       if (pDevice->EnableMWI) {
-               Value32 |= PCI_MEMORY_WRITE_INVALIDATE;
-       } else {
-               Value32 &= (~PCI_MEMORY_WRITE_INVALIDATE);
-       }
-
-       /* Error out if mem-mapping is NOT enabled for PCI systems */
-       if (!(Value32 | PCI_MEM_SPACE_ENABLE)) {
-               return LM_STATUS_FAILURE;
-       }
-
-       /* save the value we are going to write into the PCI command word */
-       pDevice->PciCommandStatusWords = Value32;
-
-       Status = MM_WriteConfig32 (pDevice, PCI_COMMAND_REG, Value32);
-       if (Status != LM_STATUS_SUCCESS) {
-               return Status;
-       }
-
-       /* Set power state to D0. */
-       LM_SetPowerState (pDevice, LM_POWER_STATE_D0);
-
-#ifdef BIG_ENDIAN_PCI
-       pDevice->MiscHostCtrl =
-           MISC_HOST_CTRL_MASK_PCI_INT |
-           MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
-           MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
-           MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
-#else                          /* No CPU Swap modes for PCI IO */
-
-       /* Setup the mode registers. */
-       pDevice->MiscHostCtrl =
-           MISC_HOST_CTRL_MASK_PCI_INT |
-           MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
-#ifdef BIG_ENDIAN_HOST
-           MISC_HOST_CTRL_ENABLE_ENDIAN_BYTE_SWAP |
-#endif                         /* BIG_ENDIAN_HOST */
-           MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
-           MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
-#endif                         /* !BIG_ENDIAN_PCI */
-
-       /* write to PCI misc host ctr first in order to enable indirect accesses */
-       MM_WriteConfig32 (pDevice, T3_PCI_MISC_HOST_CTRL_REG,
-                         pDevice->MiscHostCtrl);
-
-       REG_WR (pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl);
-
-#ifdef BIG_ENDIAN_PCI
-       Value32 = GRC_MODE_WORD_SWAP_DATA | GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
-#else
-/* No CPU Swap modes for PCI IO */
-#ifdef BIG_ENDIAN_HOST
-       Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
-           GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
-#else
-       Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
-#endif
-#endif                         /* !BIG_ENDIAN_PCI */
-
-       REG_WR (pDevice, Grc.Mode, Value32);
-
-       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
-               REG_WR (pDevice, Grc.LocalCtrl,
-                       GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
-                       GRC_MISC_LOCAL_CTRL_GPIO_OE1);
-       }
-       MM_Wait (40);
-
-       /* Enable indirect memory access */
-       REG_WR (pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
-
-       if (REG_RD (pDevice, PciCfg.ClockCtrl) & T3_PCI_44MHZ_CORE_CLOCK) {
-               REG_WR (pDevice, PciCfg.ClockCtrl, T3_PCI_44MHZ_CORE_CLOCK |
-                       T3_PCI_SELECT_ALTERNATE_CLOCK);
-               REG_WR (pDevice, PciCfg.ClockCtrl,
-                       T3_PCI_SELECT_ALTERNATE_CLOCK);
-               MM_Wait (40);   /* required delay is 27usec */
-       }
-       REG_WR (pDevice, PciCfg.ClockCtrl, 0);
-       REG_WR (pDevice, PciCfg.MemWindowBaseAddr, 0);
-
-#if PCIX_TARGET_WORKAROUND
-       MM_ReadConfig32 (pDevice, T3_PCI_STATE_REG, &Value32);
-       if ((pDevice->EnablePciXFix == FALSE) &&
-           ((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0)) {
-               if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
-                   pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
-                   pDevice->ChipRevId == T3_CHIP_ID_5701_B2 ||
-                   pDevice->ChipRevId == T3_CHIP_ID_5701_B5) {
-                       __raw_writel (0,
-                                     &(pDevice->pMemView->uIntMem.
-                                       MemBlock32K[0x300]));
-                       __raw_writel (0,
-                                     &(pDevice->pMemView->uIntMem.
-                                       MemBlock32K[0x301]));
-                       __raw_writel (0xffffffff,
-                                     &(pDevice->pMemView->uIntMem.
-                                       MemBlock32K[0x301]));
-                       if (__raw_readl
-                           (&(pDevice->pMemView->uIntMem.MemBlock32K[0x300])))
-                       {
-                               pDevice->EnablePciXFix = TRUE;
-                       }
-               }
-       }
-#endif
-#if 1
-       /*
-        *  This code was at the beginning of else block below, but that's
-        *  a bug if node address in shared memory.
-        */
-       MM_Wait (50);
-       LM_NvramInit (pDevice);
-#endif
-       /* Get the node address.  First try to get in from the shared memory. */
-       /* If the signature is not present, then get it from the NVRAM. */
-       Value32 = MEM_RD_OFFSET (pDevice, T3_MAC_ADDR_HIGH_MAILBOX);
-       if ((Value32 >> 16) == 0x484b) {
-
-               pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 8);
-               pDevice->NodeAddress[1] = (LM_UINT8) Value32;
-
-               Value32 = MEM_RD_OFFSET (pDevice, T3_MAC_ADDR_LOW_MAILBOX);
-
-               pDevice->NodeAddress[2] = (LM_UINT8) (Value32 >> 24);
-               pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 16);
-               pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 8);
-               pDevice->NodeAddress[5] = (LM_UINT8) Value32;
-
-               Status = LM_STATUS_SUCCESS;
-       } else {
-               Status = LM_NvramRead (pDevice, 0x7c, &Value32);
-               if (Status == LM_STATUS_SUCCESS) {
-                       pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 16);
-                       pDevice->NodeAddress[1] = (LM_UINT8) (Value32 >> 24);
-
-                       Status = LM_NvramRead (pDevice, 0x80, &Value32);
-
-                       pDevice->NodeAddress[2] = (LM_UINT8) Value32;
-                       pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 8);
-                       pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 16);
-                       pDevice->NodeAddress[5] = (LM_UINT8) (Value32 >> 24);
-               }
-       }
-
-       /* Assign a default address. */
-       if (Status != LM_STATUS_SUCCESS) {
-#ifndef EMBEDDED
-               printk (KERN_ERR
-                       "Cannot get MAC addr from NVRAM. Using default.\n");
-#endif
-               pDevice->NodeAddress[0] = 0x00;
-               pDevice->NodeAddress[1] = 0x10;
-               pDevice->NodeAddress[2] = 0x18;
-               pDevice->NodeAddress[3] = 0x68;
-               pDevice->NodeAddress[4] = 0x61;
-               pDevice->NodeAddress[5] = 0x76;
-       }
-
-       pDevice->PermanentNodeAddress[0] = pDevice->NodeAddress[0];
-       pDevice->PermanentNodeAddress[1] = pDevice->NodeAddress[1];
-       pDevice->PermanentNodeAddress[2] = pDevice->NodeAddress[2];
-       pDevice->PermanentNodeAddress[3] = pDevice->NodeAddress[3];
-       pDevice->PermanentNodeAddress[4] = pDevice->NodeAddress[4];
-       pDevice->PermanentNodeAddress[5] = pDevice->NodeAddress[5];
-
-       /* Initialize the default values. */
-       pDevice->NoTxPseudoHdrChksum = FALSE;
-       pDevice->NoRxPseudoHdrChksum = FALSE;
-       pDevice->NicSendBd = FALSE;
-       pDevice->TxPacketDescCnt = DEFAULT_TX_PACKET_DESC_COUNT;
-       pDevice->RxStdDescCnt = DEFAULT_STD_RCV_DESC_COUNT;
-       pDevice->RxCoalescingTicks = DEFAULT_RX_COALESCING_TICKS;
-       pDevice->TxCoalescingTicks = DEFAULT_TX_COALESCING_TICKS;
-       pDevice->RxMaxCoalescedFrames = DEFAULT_RX_MAX_COALESCED_FRAMES;
-       pDevice->TxMaxCoalescedFrames = DEFAULT_TX_MAX_COALESCED_FRAMES;
-       pDevice->RxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
-       pDevice->TxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
-       pDevice->RxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
-       pDevice->TxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
-       pDevice->StatsCoalescingTicks = DEFAULT_STATS_COALESCING_TICKS;
-       pDevice->EnableMWI = FALSE;
-       pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
-       pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
-       pDevice->DisableAutoNeg = FALSE;
-       pDevice->PhyIntMode = T3_PHY_INT_MODE_AUTO;
-       pDevice->LinkChngMode = T3_LINK_CHNG_MODE_AUTO;
-       pDevice->LedMode = LED_MODE_AUTO;
-       pDevice->ResetPhyOnInit = TRUE;
-       pDevice->DelayPciGrant = TRUE;
-       pDevice->UseTaggedStatus = FALSE;
-       pDevice->OneDmaAtOnce = BAD_DEFAULT_VALUE;
-
-       pDevice->DmaMbufLowMark = T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO;
-       pDevice->RxMacMbufLowMark = T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO;
-       pDevice->MbufHighMark = T3_DEF_MBUF_HIGH_WMARK_JUMBO;
-
-       pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_AUTO;
-       pDevice->TaskOffloadCap = LM_TASK_OFFLOAD_NONE;
-       pDevice->FlowControlCap = LM_FLOW_CONTROL_AUTO_PAUSE;
-       pDevice->EnableTbi = FALSE;
-#if INCLUDE_TBI_SUPPORT
-       pDevice->PollTbiLink = BAD_DEFAULT_VALUE;
-#endif
-
-       switch (T3_ASIC_REV (pDevice->ChipRevId)) {
-       case T3_ASIC_REV_5704:
-               pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
-               pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE64;
-               break;
-       default:
-               pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
-               pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE96;
-               break;
-       }
-
-       pDevice->LinkStatus = LM_STATUS_LINK_DOWN;
-       pDevice->QueueRxPackets = TRUE;
-
-       pDevice->EnableWireSpeed = TRUE;
-
-#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
-       pDevice->RxJumboDescCnt = DEFAULT_JUMBO_RCV_DESC_COUNT;
-#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
-
-       /* Make this is a known adapter. */
-       pAdapterInfo = LM_GetAdapterInfoBySsid (pDevice->SubsystemVendorId,
-                                               pDevice->SubsystemId);
-
-       pDevice->BondId = REG_RD (pDevice, Grc.MiscCfg) & GRC_MISC_BD_ID_MASK;
-       if (pDevice->BondId != GRC_MISC_BD_ID_5700 &&
-           pDevice->BondId != GRC_MISC_BD_ID_5701 &&
-           pDevice->BondId != GRC_MISC_BD_ID_5702FE &&
-           pDevice->BondId != GRC_MISC_BD_ID_5703 &&
-           pDevice->BondId != GRC_MISC_BD_ID_5703S &&
-           pDevice->BondId != GRC_MISC_BD_ID_5704 &&
-           pDevice->BondId != GRC_MISC_BD_ID_5704CIOBE) {
-               return LM_STATUS_UNKNOWN_ADAPTER;
-       }
-
-       pDevice->SplitModeEnable = SPLIT_MODE_DISABLE;
-       if ((pDevice->ChipRevId == T3_CHIP_ID_5704_A0) &&
-           (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE)) {
-               pDevice->SplitModeEnable = SPLIT_MODE_ENABLE;
-               pDevice->SplitModeMaxReq = SPLIT_MODE_5704_MAX_REQ;
-       }
-
-       /* Get Eeprom info. */
-       Value32 = MEM_RD_OFFSET (pDevice, T3_NIC_DATA_SIG_ADDR);
-       if (Value32 == T3_NIC_DATA_SIG) {
-               EeSigFound = TRUE;
-               Value32 = MEM_RD_OFFSET (pDevice, T3_NIC_DATA_NIC_CFG_ADDR);
-
-               /* Determine PHY type. */
-               switch (Value32 & T3_NIC_CFG_PHY_TYPE_MASK) {
-               case T3_NIC_CFG_PHY_TYPE_COPPER:
-                       EePhyTypeSerdes = FALSE;
-                       break;
-
-               case T3_NIC_CFG_PHY_TYPE_FIBER:
-                       EePhyTypeSerdes = TRUE;
-                       break;
-
-               default:
-                       EePhyTypeSerdes = FALSE;
-                       break;
-               }
-
-               /* Determine PHY led mode. */
-               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
-                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
-                       switch (Value32 & T3_NIC_CFG_LED_MODE_MASK) {
-                       case T3_NIC_CFG_LED_MODE_TRIPLE_SPEED:
-                               EePhyLedMode = LED_MODE_THREE_LINK;
-                               break;
-
-                       case T3_NIC_CFG_LED_MODE_LINK_SPEED:
-                               EePhyLedMode = LED_MODE_LINK10;
-                               break;
-
-                       default:
-                               EePhyLedMode = LED_MODE_AUTO;
-                               break;
-                       }
-               } else {
-                       switch (Value32 & T3_NIC_CFG_LED_MODE_MASK) {
-                       case T3_NIC_CFG_LED_MODE_OPEN_DRAIN:
-                               EePhyLedMode = LED_MODE_OPEN_DRAIN;
-                               break;
-
-                       case T3_NIC_CFG_LED_MODE_OUTPUT:
-                               EePhyLedMode = LED_MODE_OUTPUT;
-                               break;
-
-                       default:
-                               EePhyLedMode = LED_MODE_AUTO;
-                               break;
-                       }
-               }
-               if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1 ||
-                   pDevice->ChipRevId == T3_CHIP_ID_5703_A2) {
-                       /* Enable EEPROM write protection. */
-                       if (Value32 & T3_NIC_EEPROM_WP) {
-                               pDevice->EepromWp = TRUE;
-                       }
-               }
-
-               /* Get the PHY Id. */
-               Value32 = MEM_RD_OFFSET (pDevice, T3_NIC_DATA_PHY_ID_ADDR);
-               if (Value32) {
-                       EePhyId = (((Value32 & T3_NIC_PHY_ID1_MASK) >> 16) &
-                                  PHY_ID1_OUI_MASK) << 10;
-
-                       Value32 = Value32 & T3_NIC_PHY_ID2_MASK;
-
-                       EePhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
-                           (Value32 & PHY_ID2_MODEL_MASK) | (Value32 &
-                                                             PHY_ID2_REV_MASK);
-               } else {
-                       EePhyId = 0;
-               }
-       } else {
-               EeSigFound = FALSE;
-       }
-
-       /* Set the PHY address. */
-       pDevice->PhyAddr = PHY_DEVICE_ID;
-
-       /* Disable auto polling. */
-       pDevice->MiMode = 0xc0000;
-       REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
-       MM_Wait (40);
-
-       /* Get the PHY id. */
-       LM_ReadPhy (pDevice, PHY_ID1_REG, &Value32);
-       pDevice->PhyId = (Value32 & PHY_ID1_OUI_MASK) << 10;
-
-       LM_ReadPhy (pDevice, PHY_ID2_REG, &Value32);
-       pDevice->PhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
-           (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
-
-       /* Set the EnableTbi flag to false if we have a copper PHY. */
-       switch (pDevice->PhyId & PHY_ID_MASK) {
-       case PHY_BCM5400_PHY_ID:
-               pDevice->EnableTbi = FALSE;
-               break;
-
-       case PHY_BCM5401_PHY_ID:
-               pDevice->EnableTbi = FALSE;
-               break;
-
-       case PHY_BCM5411_PHY_ID:
-               pDevice->EnableTbi = FALSE;
-               break;
-
-       case PHY_BCM5701_PHY_ID:
-               pDevice->EnableTbi = FALSE;
-               break;
-
-       case PHY_BCM5703_PHY_ID:
-               pDevice->EnableTbi = FALSE;
-               break;
-
-       case PHY_BCM5704_PHY_ID:
-               pDevice->EnableTbi = FALSE;
-               break;
-
-       case PHY_BCM8002_PHY_ID:
-               pDevice->EnableTbi = TRUE;
-               break;
-
-       default:
-
-               if (pAdapterInfo) {
-                       pDevice->PhyId = pAdapterInfo->PhyId;
-                       pDevice->EnableTbi = pAdapterInfo->Serdes;
-               } else if (EeSigFound) {
-                       pDevice->PhyId = EePhyId;
-                       pDevice->EnableTbi = EePhyTypeSerdes;
-               }
-               break;
-       }
-
-       /* Bail out if we don't know the copper PHY id. */
-       if (UNKNOWN_PHY_ID (pDevice->PhyId) && !pDevice->EnableTbi) {
-               return LM_STATUS_FAILURE;
-       }
-
-       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5703) {
-               if ((pDevice->SavedCacheLineReg & 0xff00) < 0x4000) {
-                       pDevice->SavedCacheLineReg &= 0xffff00ff;
-                       pDevice->SavedCacheLineReg |= 0x4000;
-               }
-       }
-       /* Change driver parameters. */
-       Status = MM_GetConfig (pDevice);
-       if (Status != LM_STATUS_SUCCESS) {
-               return Status;
-       }
-#if INCLUDE_5701_AX_FIX
-       if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
-           pDevice->ChipRevId == T3_CHIP_ID_5701_B0) {
-               pDevice->ResetPhyOnInit = TRUE;
-       }
-#endif
-
-       /* Save the current phy link status. */
-       if (!pDevice->EnableTbi) {
-               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
-               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
-
-               /* If we don't have link reset the PHY. */
-               if (!(Value32 & PHY_STATUS_LINK_PASS)
-                   || pDevice->ResetPhyOnInit) {
-
-                       LM_WritePhy (pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
-
-                       for (j = 0; j < 100; j++) {
-                               MM_Wait (10);
-
-                               LM_ReadPhy (pDevice, PHY_CTRL_REG, &Value32);
-                               if (Value32 && !(Value32 & PHY_CTRL_PHY_RESET)) {
-                                       MM_Wait (40);
-                                       break;
-                               }
-                       }
-
-#if INCLUDE_5701_AX_FIX
-                       /* 5701_AX_BX bug:  only advertises 10mb speed. */
-                       if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
-                           pDevice->ChipRevId == T3_CHIP_ID_5701_B0) {
-
-                               Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
-                                   PHY_AN_AD_10BASET_HALF |
-                                   PHY_AN_AD_10BASET_FULL |
-                                   PHY_AN_AD_100BASETX_FULL |
-                                   PHY_AN_AD_100BASETX_HALF;
-                               Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
-                               LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
-                               pDevice->advertising = Value32;
-
-                               Value32 = BCM540X_AN_AD_1000BASET_HALF |
-                                   BCM540X_AN_AD_1000BASET_FULL |
-                                   BCM540X_CONFIG_AS_MASTER |
-                                   BCM540X_ENABLE_CONFIG_AS_MASTER;
-                               LM_WritePhy (pDevice,
-                                            BCM540X_1000BASET_CTRL_REG,
-                                            Value32);
-                               pDevice->advertising1000 = Value32;
-
-                               LM_WritePhy (pDevice, PHY_CTRL_REG,
-                                            PHY_CTRL_AUTO_NEG_ENABLE |
-                                            PHY_CTRL_RESTART_AUTO_NEG);
-                       }
-#endif
-                       if (T3_ASIC_REV (pDevice->ChipRevId) ==
-                           T3_ASIC_REV_5703) {
-                               LM_WritePhy (pDevice, 0x18, 0x0c00);
-                               LM_WritePhy (pDevice, 0x17, 0x201f);
-                               LM_WritePhy (pDevice, 0x15, 0x2aaa);
-                       }
-                       if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
-                               LM_WritePhy (pDevice, 0x1c, 0x8d68);
-                               LM_WritePhy (pDevice, 0x1c, 0x8d68);
-                       }
-                       /* Enable Ethernet@WireSpeed. */
-                       if (pDevice->EnableWireSpeed) {
-                               LM_WritePhy (pDevice, 0x18, 0x7007);
-                               LM_ReadPhy (pDevice, 0x18, &Value32);
-                               LM_WritePhy (pDevice, 0x18,
-                                            Value32 | BIT_15 | BIT_4);
-                       }
-               }
-       }
-
-       /* Turn off tap power management. */
-       if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID) {
-               LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x0c20);
-               LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
-               LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x1804);
-               LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
-               LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x1204);
-               LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
-               LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0132);
-               LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
-               LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0232);
-               LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
-               LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
-
-               MM_Wait (40);
-       }
-#if INCLUDE_TBI_SUPPORT
-       pDevice->IgnoreTbiLinkChange = FALSE;
-
-       if (pDevice->EnableTbi) {
-               pDevice->WakeUpModeCap = LM_WAKE_UP_MODE_NONE;
-               pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
-               if ((pDevice->PollTbiLink == BAD_DEFAULT_VALUE) ||
-                   pDevice->DisableAutoNeg) {
-                       pDevice->PollTbiLink = FALSE;
-               }
-       } else {
-               pDevice->PollTbiLink = FALSE;
-       }
-#endif                         /* INCLUDE_TBI_SUPPORT */
-
-       /* UseTaggedStatus is only valid for 5701 and later. */
-       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
-               pDevice->UseTaggedStatus = FALSE;
-
-               pDevice->CoalesceMode = 0;
-       } else {
-               pDevice->CoalesceMode =
-                   HOST_COALESCE_CLEAR_TICKS_ON_RX_BD_EVENT |
-                   HOST_COALESCE_CLEAR_TICKS_ON_TX_BD_EVENT;
-       }
-
-       /* Set the status block size. */
-       if (T3_CHIP_REV (pDevice->ChipRevId) != T3_CHIP_REV_5700_AX &&
-           T3_CHIP_REV (pDevice->ChipRevId) != T3_CHIP_REV_5700_BX) {
-               pDevice->CoalesceMode |= HOST_COALESCE_32_BYTE_STATUS_MODE;
-       }
-
-       /* Check the DURING_INT coalescing ticks parameters. */
-       if (pDevice->UseTaggedStatus) {
-               if (pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE) {
-                       pDevice->RxCoalescingTicksDuringInt =
-                           DEFAULT_RX_COALESCING_TICKS_DURING_INT;
-               }
-
-               if (pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE) {
-                       pDevice->TxCoalescingTicksDuringInt =
-                           DEFAULT_TX_COALESCING_TICKS_DURING_INT;
-               }
-
-               if (pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE) {
-                       pDevice->RxMaxCoalescedFramesDuringInt =
-                           DEFAULT_RX_MAX_COALESCED_FRAMES_DURING_INT;
-               }
-
-               if (pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE) {
-                       pDevice->TxMaxCoalescedFramesDuringInt =
-                           DEFAULT_TX_MAX_COALESCED_FRAMES_DURING_INT;
-               }
-       } else {
-               if (pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE) {
-                       pDevice->RxCoalescingTicksDuringInt = 0;
-               }
-
-               if (pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE) {
-                       pDevice->TxCoalescingTicksDuringInt = 0;
-               }
-
-               if (pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE) {
-                       pDevice->RxMaxCoalescedFramesDuringInt = 0;
-               }
-
-               if (pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE) {
-                       pDevice->TxMaxCoalescedFramesDuringInt = 0;
-               }
-       }
-
-#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
-       if (pDevice->RxMtu <= (MAX_STD_RCV_BUFFER_SIZE - 8 /* CRC */ )) {
-               pDevice->RxJumboDescCnt = 0;
-               if (pDevice->RxMtu <= MAX_ETHERNET_PACKET_SIZE_NO_CRC) {
-                       pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
-               }
-       } else {
-               pDevice->RxJumboBufferSize =
-                   (pDevice->RxMtu + 8 /* CRC + VLAN */  +
-                    COMMON_CACHE_LINE_SIZE - 1) & ~COMMON_CACHE_LINE_MASK;
-
-               if (pDevice->RxJumboBufferSize > MAX_JUMBO_RCV_BUFFER_SIZE) {
-                       pDevice->RxJumboBufferSize =
-                           DEFAULT_JUMBO_RCV_BUFFER_SIZE;
-                       pDevice->RxMtu =
-                           pDevice->RxJumboBufferSize - 8 /* CRC + VLAN */ ;
-               }
-               pDevice->TxMtu = pDevice->RxMtu;
-
-       }
-#else
-       pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
-#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
-
-       pDevice->RxPacketDescCnt =
-#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
-           pDevice->RxJumboDescCnt +
-#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
-           pDevice->RxStdDescCnt;
-
-       if (pDevice->TxMtu < MAX_ETHERNET_PACKET_SIZE_NO_CRC) {
-               pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
-       }
-
-       if (pDevice->TxMtu > MAX_JUMBO_TX_BUFFER_SIZE) {
-               pDevice->TxMtu = MAX_JUMBO_TX_BUFFER_SIZE;
-       }
-
-       /* Configure the proper ways to get link change interrupt. */
-       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO) {
-               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
-                       pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
-               } else {
-                       pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
-               }
-       } else if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
-               /* Auto-polling does not work on 5700_AX and 5700_BX. */
-               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
-                       pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
-               }
-       }
-
-       /* Determine the method to get link change status. */
-       if (pDevice->LinkChngMode == T3_LINK_CHNG_MODE_AUTO) {
-               /* The link status bit in the status block does not work on 5700_AX */
-               /* and 5700_BX chips. */
-               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
-                       pDevice->LinkChngMode =
-                           T3_LINK_CHNG_MODE_USE_STATUS_REG;
-               } else {
-                       pDevice->LinkChngMode =
-                           T3_LINK_CHNG_MODE_USE_STATUS_BLOCK;
-               }
-       }
-
-       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT ||
-           T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
-               pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
-       }
-
-       /* Configure PHY led mode. */
-       if (pDevice->LedMode == LED_MODE_AUTO) {
-               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
-                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
-                       if (pDevice->SubsystemVendorId == T3_SVID_DELL) {
-                               pDevice->LedMode = LED_MODE_LINK10;
-                       } else {
-                               pDevice->LedMode = LED_MODE_THREE_LINK;
-
-                               if (EeSigFound && EePhyLedMode != LED_MODE_AUTO) {
-                                       pDevice->LedMode = EePhyLedMode;
-                               }
-                       }
-
-                       /* bug? 5701 in LINK10 mode does not seem to work when */
-                       /* PhyIntMode is LINK_READY. */
-                       if (T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5700
-                           &&
-#if INCLUDE_TBI_SUPPORT
-                           pDevice->EnableTbi == FALSE &&
-#endif
-                           pDevice->LedMode == LED_MODE_LINK10) {
-                               pDevice->PhyIntMode =
-                                   T3_PHY_INT_MODE_MI_INTERRUPT;
-                               pDevice->LinkChngMode =
-                                   T3_LINK_CHNG_MODE_USE_STATUS_REG;
-                       }
-
-                       if (pDevice->EnableTbi) {
-                               pDevice->LedMode = LED_MODE_THREE_LINK;
-                       }
-               } else {
-                       if (EeSigFound && EePhyLedMode != LED_MODE_AUTO) {
-                               pDevice->LedMode = EePhyLedMode;
-                       } else {
-                               pDevice->LedMode = LED_MODE_OPEN_DRAIN;
-                       }
-               }
-       }
-
-       /* Enable OneDmaAtOnce. */
-       if (pDevice->OneDmaAtOnce == BAD_DEFAULT_VALUE) {
-               pDevice->OneDmaAtOnce = FALSE;
-       }
-
-       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
-           pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
-           pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
-           pDevice->ChipRevId == T3_CHIP_ID_5701_B2) {
-               pDevice->WolSpeed = WOL_SPEED_10MB;
-       } else {
-               pDevice->WolSpeed = WOL_SPEED_100MB;
-       }
-
-       /* Offloadings. */
-       pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;
-
-       /* Turn off task offloading on Ax. */
-       if (pDevice->ChipRevId == T3_CHIP_ID_5700_B0) {
-               pDevice->TaskOffloadCap &= ~(LM_TASK_OFFLOAD_TX_TCP_CHECKSUM |
-                                            LM_TASK_OFFLOAD_TX_UDP_CHECKSUM);
-       }
-       pDevice->PciState = REG_RD (pDevice, PciCfg.PciState);
-       LM_ReadVPD (pDevice);
-       LM_ReadBootCodeVersion (pDevice);
-       LM_GetBusSpeed (pDevice);
-
-       return LM_STATUS_SUCCESS;
-}                              /* LM_GetAdapterInfo */
-
-STATIC PLM_ADAPTER_INFO LM_GetAdapterInfoBySsid (LM_UINT16 Svid, LM_UINT16 Ssid)
-{
-       static LM_ADAPTER_INFO AdapterArr[] = {
-               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A6,
-                PHY_BCM5401_PHY_ID, 0},
-               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A5,
-                PHY_BCM5701_PHY_ID, 0},
-               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700T6,
-                PHY_BCM8002_PHY_ID, 1},
-               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A9, 0, 1},
-               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T1,
-                PHY_BCM5701_PHY_ID, 0},
-               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T8,
-                PHY_BCM5701_PHY_ID, 0},
-               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A7, 0, 1},
-               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A10,
-                PHY_BCM5701_PHY_ID, 0},
-               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A12,
-                PHY_BCM5701_PHY_ID, 0},
-               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax1,
-                PHY_BCM5701_PHY_ID, 0},
-               {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax2,
-                PHY_BCM5701_PHY_ID, 0},
-
-               {T3_SVID_3COM, T3_SSID_3COM_3C996T, PHY_BCM5401_PHY_ID, 0},
-               {T3_SVID_3COM, T3_SSID_3COM_3C996BT, PHY_BCM5701_PHY_ID, 0},
-               {T3_SVID_3COM, T3_SSID_3COM_3C996SX, 0, 1},
-               {T3_SVID_3COM, T3_SSID_3COM_3C1000T, PHY_BCM5701_PHY_ID, 0},
-               {T3_SVID_3COM, T3_SSID_3COM_3C940BR01, PHY_BCM5701_PHY_ID, 0},
-
-               {T3_SVID_DELL, T3_SSID_DELL_VIPER, PHY_BCM5401_PHY_ID, 0},
-               {T3_SVID_DELL, T3_SSID_DELL_JAGUAR, PHY_BCM5401_PHY_ID, 0},
-               {T3_SVID_DELL, T3_SSID_DELL_MERLOT, PHY_BCM5411_PHY_ID, 0},
-               {T3_SVID_DELL, T3_SSID_DELL_SLIM_MERLOT, PHY_BCM5411_PHY_ID, 0},
-
-               {T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE, PHY_BCM5701_PHY_ID, 0},
-               {T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE_2, PHY_BCM5701_PHY_ID,
-                0},
-               {T3_SVID_COMPAQ, T3_SSID_COMPAQ_CHANGELING, 0, 1},
-               {T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780, PHY_BCM5701_PHY_ID, 0},
-               {T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780_2, PHY_BCM5701_PHY_ID,
-                0},
-
-       };
-       LM_UINT32 j;
-
-       for (j = 0; j < sizeof (AdapterArr) / sizeof (LM_ADAPTER_INFO); j++) {
-               if (AdapterArr[j].Svid == Svid && AdapterArr[j].Ssid == Ssid) {
-                       return &AdapterArr[j];
-               }
-       }
-
-       return NULL;
-}
-
-/******************************************************************************/
-/* Description:                                                               */
-/*    This routine sets up receive/transmit buffer descriptions queues.       */
-/*                                                                            */
-/* Return:                                                                    */
-/*    LM_STATUS_SUCCESS                                                       */
-/******************************************************************************/
-LM_STATUS LM_InitializeAdapter (PLM_DEVICE_BLOCK pDevice)
-{
-       LM_PHYSICAL_ADDRESS MemPhy;
-       PLM_UINT8 pMemVirt;
-       PLM_PACKET pPacket;
-       LM_STATUS Status;
-       LM_UINT32 Size;
-       LM_UINT32 j;
-
-       /* Set power state to D0. */
-       LM_SetPowerState (pDevice, LM_POWER_STATE_D0);
-
-       /* Intialize the queues. */
-       QQ_InitQueue (&pDevice->RxPacketReceivedQ.Container,
-                     MAX_RX_PACKET_DESC_COUNT);
-       QQ_InitQueue (&pDevice->RxPacketFreeQ.Container,
-                     MAX_RX_PACKET_DESC_COUNT);
-
-       QQ_InitQueue (&pDevice->TxPacketFreeQ.Container,
-                     MAX_TX_PACKET_DESC_COUNT);
-       QQ_InitQueue (&pDevice->TxPacketActiveQ.Container,
-                     MAX_TX_PACKET_DESC_COUNT);
-       QQ_InitQueue (&pDevice->TxPacketXmittedQ.Container,
-                     MAX_TX_PACKET_DESC_COUNT);
-
-       /* Allocate shared memory for: status block, the buffers for receive */
-       /* rings -- standard, mini, jumbo, and return rings. */
-       Size = T3_STATUS_BLOCK_SIZE + sizeof (T3_STATS_BLOCK) +
-           T3_STD_RCV_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD) +
-#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
-           T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD) +
-#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
-           T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD);
-
-       /* Memory for host based Send BD. */
-       if (pDevice->NicSendBd == FALSE) {
-               Size += sizeof (T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
-       }
-
-       /* Allocate the memory block. */
-       Status =
-           MM_AllocateSharedMemory (pDevice, Size, (PLM_VOID) & pMemVirt,
-                                    &MemPhy, FALSE);
-       if (Status != LM_STATUS_SUCCESS) {
-               return Status;
-       }
-
-       /* Program DMA Read/Write */
-       if (pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS) {
-               pDevice->DmaReadWriteCtrl = 0x763f000f;
-       } else {
-               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5704) {
-                       pDevice->DmaReadWriteCtrl = 0x761f0000;
-               } else {
-                       pDevice->DmaReadWriteCtrl = 0x761b000f;
-               }
-               if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1 ||
-                   pDevice->ChipRevId == T3_CHIP_ID_5703_A2) {
-                       pDevice->OneDmaAtOnce = TRUE;
-               }
-       }
-       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5703) {
-               pDevice->DmaReadWriteCtrl &= 0xfffffff0;
-       }
-
-       if (pDevice->OneDmaAtOnce) {
-               pDevice->DmaReadWriteCtrl |= DMA_CTRL_WRITE_ONE_DMA_AT_ONCE;
-       }
-       REG_WR (pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
-
-       if (LM_DmaTest (pDevice, pMemVirt, MemPhy, 0x400) != LM_STATUS_SUCCESS) {
-               return LM_STATUS_FAILURE;
-       }
-
-       /* Status block. */
-       pDevice->pStatusBlkVirt = (PT3_STATUS_BLOCK) pMemVirt;
-       pDevice->StatusBlkPhy = MemPhy;
-       pMemVirt += T3_STATUS_BLOCK_SIZE;
-       LM_INC_PHYSICAL_ADDRESS (&MemPhy, T3_STATUS_BLOCK_SIZE);
-
-       /* Statistics block. */
-       pDevice->pStatsBlkVirt = (PT3_STATS_BLOCK) pMemVirt;
-       pDevice->StatsBlkPhy = MemPhy;
-       pMemVirt += sizeof (T3_STATS_BLOCK);
-       LM_INC_PHYSICAL_ADDRESS (&MemPhy, sizeof (T3_STATS_BLOCK));
-
-       /* Receive standard BD buffer. */
-       pDevice->pRxStdBdVirt = (PT3_RCV_BD) pMemVirt;
-       pDevice->RxStdBdPhy = MemPhy;
-
-       pMemVirt += T3_STD_RCV_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD);
-       LM_INC_PHYSICAL_ADDRESS (&MemPhy,
-                                T3_STD_RCV_RCB_ENTRY_COUNT *
-                                sizeof (T3_RCV_BD));
-
-#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
-       /* Receive jumbo BD buffer. */
-       pDevice->pRxJumboBdVirt = (PT3_RCV_BD) pMemVirt;
-       pDevice->RxJumboBdPhy = MemPhy;
-
-       pMemVirt += T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD);
-       LM_INC_PHYSICAL_ADDRESS (&MemPhy,
-                                T3_JUMBO_RCV_RCB_ENTRY_COUNT *
-                                sizeof (T3_RCV_BD));
-#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
-
-       /* Receive return BD buffer. */
-       pDevice->pRcvRetBdVirt = (PT3_RCV_BD) pMemVirt;
-       pDevice->RcvRetBdPhy = MemPhy;
-
-       pMemVirt += T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD);
-       LM_INC_PHYSICAL_ADDRESS (&MemPhy,
-                                T3_RCV_RETURN_RCB_ENTRY_COUNT *
-                                sizeof (T3_RCV_BD));
-
-       /* Set up Send BD. */
-       if (pDevice->NicSendBd == FALSE) {
-               pDevice->pSendBdVirt = (PT3_SND_BD) pMemVirt;
-               pDevice->SendBdPhy = MemPhy;
-
-               pMemVirt += sizeof (T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
-               LM_INC_PHYSICAL_ADDRESS (&MemPhy,
-                                        sizeof (T3_SND_BD) *
-                                        T3_SEND_RCB_ENTRY_COUNT);
-       } else {
-               pDevice->pSendBdVirt = (PT3_SND_BD)
-                   pDevice->pMemView->uIntMem.First32k.BufferDesc;
-               pDevice->SendBdPhy.High = 0;
-               pDevice->SendBdPhy.Low = T3_NIC_SND_BUFFER_DESC_ADDR;
-       }
-
-       /* Allocate memory for packet descriptors. */
-       Size = (pDevice->RxPacketDescCnt +
-               pDevice->TxPacketDescCnt) * MM_PACKET_DESC_SIZE;
-       Status = MM_AllocateMemory (pDevice, Size, (PLM_VOID *) & pPacket);
-       if (Status != LM_STATUS_SUCCESS) {
-               return Status;
-       }
-       pDevice->pPacketDescBase = (PLM_VOID) pPacket;
-
-       /* Create transmit packet descriptors from the memory block and add them */
-       /* to the TxPacketFreeQ for each send ring. */
-       for (j = 0; j < pDevice->TxPacketDescCnt; j++) {
-               /* Ring index. */
-               pPacket->Flags = 0;
-
-               /* Queue the descriptor in the TxPacketFreeQ of the 'k' ring. */
-               QQ_PushTail (&pDevice->TxPacketFreeQ.Container, pPacket);
-
-               /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
-               /* is the total size of the packet descriptor including the */
-               /* os-specific extensions in the UM_PACKET structure. */
-               pPacket =
-                   (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
-       }                       /* for(j.. */
-
-       /* Create receive packet descriptors from the memory block and add them */
-       /* to the RxPacketFreeQ.  Create the Standard packet descriptors. */
-       for (j = 0; j < pDevice->RxStdDescCnt; j++) {
-               /* Receive producer ring. */
-               pPacket->u.Rx.RcvProdRing = T3_STD_RCV_PROD_RING;
-
-               /* Receive buffer size. */
-               pPacket->u.Rx.RxBufferSize = MAX_STD_RCV_BUFFER_SIZE;
-
-               /* Add the descriptor to RxPacketFreeQ. */
-               QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
-
-               /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
-               /* is the total size of the packet descriptor including the */
-               /* os-specific extensions in the UM_PACKET structure. */
-               pPacket =
-                   (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
-       }                       /* for */
-
-#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
-       /* Create the Jumbo packet descriptors. */
-       for (j = 0; j < pDevice->RxJumboDescCnt; j++) {
-               /* Receive producer ring. */
-               pPacket->u.Rx.RcvProdRing = T3_JUMBO_RCV_PROD_RING;
-
-               /* Receive buffer size. */
-               pPacket->u.Rx.RxBufferSize = pDevice->RxJumboBufferSize;
-
-               /* Add the descriptor to RxPacketFreeQ. */
-               QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
-
-               /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
-               /* is the total size of the packet descriptor including the */
-               /* os-specific extensions in the UM_PACKET structure. */
-               pPacket =
-                   (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
-       }                       /* for */
-#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
-
-       /* Initialize the rest of the packet descriptors. */
-       Status = MM_InitializeUmPackets (pDevice);
-       if (Status != LM_STATUS_SUCCESS) {
-               return Status;
-       }
-
-       /* if */
-       /* Default receive mask. */
-       pDevice->ReceiveMask = LM_ACCEPT_MULTICAST | LM_ACCEPT_BROADCAST |
-           LM_ACCEPT_UNICAST;
-
-       /* Make sure we are in the first 32k memory window or NicSendBd. */
-       REG_WR (pDevice, PciCfg.MemWindowBaseAddr, 0);
-
-       /* Initialize the hardware. */
-       Status = LM_ResetAdapter (pDevice);
-       if (Status != LM_STATUS_SUCCESS) {
-               return Status;
-       }
-
-       /* We are done with initialization. */
-       pDevice->InitDone = TRUE;
-
-       return LM_STATUS_SUCCESS;
-}                              /* LM_InitializeAdapter */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*    This function Enables/Disables a given block.                          */
-/*                                                                            */
-/* Return:                                                                    */
-/*    LM_STATUS_SUCCESS                                                       */
-/******************************************************************************/
-LM_STATUS
-LM_CntrlBlock (PLM_DEVICE_BLOCK pDevice, LM_UINT32 mask, LM_UINT32 cntrl)
-{
-       LM_UINT32 j, i, data;
-       LM_UINT32 MaxWaitCnt;
-
-       MaxWaitCnt = 2;
-       j = 0;
-
-       for (i = 0; i < 32; i++) {
-               if (!(mask & (1 << i)))
-                       continue;
-
-               switch (1 << i) {
-               case T3_BLOCK_DMA_RD:
-                       data = REG_RD (pDevice, DmaRead.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~DMA_READ_MODE_ENABLE;
-                               REG_WR (pDevice, DmaRead.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, DmaRead.Mode) &
-                                            DMA_READ_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, DmaRead.Mode,
-                                       data | DMA_READ_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_DMA_COMP:
-                       data = REG_RD (pDevice, DmaComp.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~DMA_COMP_MODE_ENABLE;
-                               REG_WR (pDevice, DmaComp.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, DmaComp.Mode) &
-                                            DMA_COMP_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, DmaComp.Mode,
-                                       data | DMA_COMP_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_RX_BD_INITIATOR:
-                       data = REG_RD (pDevice, RcvBdIn.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~RCV_BD_IN_MODE_ENABLE;
-                               REG_WR (pDevice, RcvBdIn.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, RcvBdIn.Mode) &
-                                            RCV_BD_IN_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, RcvBdIn.Mode,
-                                       data | RCV_BD_IN_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_RX_BD_COMP:
-                       data = REG_RD (pDevice, RcvBdComp.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~RCV_BD_COMP_MODE_ENABLE;
-                               REG_WR (pDevice, RcvBdComp.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, RcvBdComp.Mode) &
-                                            RCV_BD_COMP_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, RcvBdComp.Mode,
-                                       data | RCV_BD_COMP_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_DMA_WR:
-                       data = REG_RD (pDevice, DmaWrite.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~DMA_WRITE_MODE_ENABLE;
-                               REG_WR (pDevice, DmaWrite.Mode, data);
-
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, DmaWrite.Mode) &
-                                            DMA_WRITE_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, DmaWrite.Mode,
-                                       data | DMA_WRITE_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_MSI_HANDLER:
-                       data = REG_RD (pDevice, Msi.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~MSI_MODE_ENABLE;
-                               REG_WR (pDevice, Msi.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, Msi.Mode) &
-                                            MSI_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, Msi.Mode,
-                                       data | MSI_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_RX_LIST_PLMT:
-                       data = REG_RD (pDevice, RcvListPlmt.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~RCV_LIST_PLMT_MODE_ENABLE;
-                               REG_WR (pDevice, RcvListPlmt.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, RcvListPlmt.Mode)
-                                            & RCV_LIST_PLMT_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, RcvListPlmt.Mode,
-                                       data | RCV_LIST_PLMT_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_RX_LIST_SELECTOR:
-                       data = REG_RD (pDevice, RcvListSel.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~RCV_LIST_SEL_MODE_ENABLE;
-                               REG_WR (pDevice, RcvListSel.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, RcvListSel.Mode) &
-                                            RCV_LIST_SEL_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, RcvListSel.Mode,
-                                       data | RCV_LIST_SEL_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_RX_DATA_INITIATOR:
-                       data = REG_RD (pDevice, RcvDataBdIn.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~RCV_DATA_BD_IN_MODE_ENABLE;
-                               REG_WR (pDevice, RcvDataBdIn.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, RcvDataBdIn.Mode)
-                                            & RCV_DATA_BD_IN_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, RcvDataBdIn.Mode,
-                                       data | RCV_DATA_BD_IN_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_RX_DATA_COMP:
-                       data = REG_RD (pDevice, RcvDataComp.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~RCV_DATA_COMP_MODE_ENABLE;
-                               REG_WR (pDevice, RcvDataComp.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, RcvDataBdIn.Mode)
-                                            & RCV_DATA_COMP_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, RcvDataComp.Mode,
-                                       data | RCV_DATA_COMP_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_HOST_COALESING:
-                       data = REG_RD (pDevice, HostCoalesce.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~HOST_COALESCE_ENABLE;
-                               REG_WR (pDevice, HostCoalesce.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, SndBdIn.Mode) &
-                                            HOST_COALESCE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, HostCoalesce.Mode,
-                                       data | HOST_COALESCE_ENABLE);
-                       break;
-
-               case T3_BLOCK_MAC_RX_ENGINE:
-                       if (cntrl == LM_DISABLE) {
-                               pDevice->RxMode &= ~RX_MODE_ENABLE;
-                               REG_WR (pDevice, MacCtrl.RxMode,
-                                       pDevice->RxMode);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, MacCtrl.RxMode) &
-                                            RX_MODE_ENABLE)) {
-                                               break;
-                                       }
-                                       MM_Wait (10);
-                               }
-                       } else {
-                               pDevice->RxMode |= RX_MODE_ENABLE;
-                               REG_WR (pDevice, MacCtrl.RxMode,
-                                       pDevice->RxMode);
-                       }
-                       break;
-
-               case T3_BLOCK_MBUF_CLUSTER_FREE:
-                       data = REG_RD (pDevice, MbufClusterFree.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~MBUF_CLUSTER_FREE_MODE_ENABLE;
-                               REG_WR (pDevice, MbufClusterFree.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD
-                                            (pDevice,
-                                             MbufClusterFree.
-                                             Mode) &
-                                            MBUF_CLUSTER_FREE_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, MbufClusterFree.Mode,
-                                       data | MBUF_CLUSTER_FREE_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_SEND_BD_INITIATOR:
-                       data = REG_RD (pDevice, SndBdIn.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~SND_BD_IN_MODE_ENABLE;
-                               REG_WR (pDevice, SndBdIn.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, SndBdIn.Mode) &
-                                            SND_BD_IN_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, SndBdIn.Mode,
-                                       data | SND_BD_IN_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_SEND_BD_COMP:
-                       data = REG_RD (pDevice, SndBdComp.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~SND_BD_COMP_MODE_ENABLE;
-                               REG_WR (pDevice, SndBdComp.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, SndBdComp.Mode) &
-                                            SND_BD_COMP_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, SndBdComp.Mode,
-                                       data | SND_BD_COMP_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_SEND_BD_SELECTOR:
-                       data = REG_RD (pDevice, SndBdSel.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~SND_BD_SEL_MODE_ENABLE;
-                               REG_WR (pDevice, SndBdSel.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, SndBdSel.Mode) &
-                                            SND_BD_SEL_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, SndBdSel.Mode,
-                                       data | SND_BD_SEL_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_SEND_DATA_INITIATOR:
-                       data = REG_RD (pDevice, SndDataIn.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~T3_SND_DATA_IN_MODE_ENABLE;
-                               REG_WR (pDevice, SndDataIn.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, SndDataIn.Mode) &
-                                            T3_SND_DATA_IN_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, SndDataIn.Mode,
-                                       data | T3_SND_DATA_IN_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_SEND_DATA_COMP:
-                       data = REG_RD (pDevice, SndDataComp.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~SND_DATA_COMP_MODE_ENABLE;
-                               REG_WR (pDevice, SndDataComp.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, SndDataComp.Mode)
-                                            & SND_DATA_COMP_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, SndDataComp.Mode,
-                                       data | SND_DATA_COMP_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_MAC_TX_ENGINE:
-                       if (cntrl == LM_DISABLE) {
-                               pDevice->TxMode &= ~TX_MODE_ENABLE;
-                               REG_WR (pDevice, MacCtrl.TxMode,
-                                       pDevice->TxMode);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, MacCtrl.TxMode) &
-                                            TX_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else {
-                               pDevice->TxMode |= TX_MODE_ENABLE;
-                               REG_WR (pDevice, MacCtrl.TxMode,
-                                       pDevice->TxMode);
-                       }
-                       break;
-
-               case T3_BLOCK_MEM_ARBITOR:
-                       data = REG_RD (pDevice, MemArbiter.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~T3_MEM_ARBITER_MODE_ENABLE;
-                               REG_WR (pDevice, MemArbiter.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, MemArbiter.Mode) &
-                                            T3_MEM_ARBITER_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, MemArbiter.Mode,
-                                       data | T3_MEM_ARBITER_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_MBUF_MANAGER:
-                       data = REG_RD (pDevice, BufMgr.Mode);
-                       if (cntrl == LM_DISABLE) {
-                               data &= ~BUFMGR_MODE_ENABLE;
-                               REG_WR (pDevice, BufMgr.Mode, data);
-                               for (j = 0; j < MaxWaitCnt; j++) {
-                                       if (!
-                                           (REG_RD (pDevice, BufMgr.Mode) &
-                                            BUFMGR_MODE_ENABLE))
-                                               break;
-                                       MM_Wait (10);
-                               }
-                       } else
-                               REG_WR (pDevice, BufMgr.Mode,
-                                       data | BUFMGR_MODE_ENABLE);
-                       break;
-
-               case T3_BLOCK_MAC_GLOBAL:
-                       if (cntrl == LM_DISABLE) {
-                               pDevice->MacMode &= ~(MAC_MODE_ENABLE_TDE |
-                                                     MAC_MODE_ENABLE_RDE |
-                                                     MAC_MODE_ENABLE_FHDE);
-                       } else {
-                               pDevice->MacMode |= (MAC_MODE_ENABLE_TDE |
-                                                    MAC_MODE_ENABLE_RDE |
-                                                    MAC_MODE_ENABLE_FHDE);
-                       }
-                       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
-                       break;
-
-               default:
-                       return LM_STATUS_FAILURE;
-               }               /* switch */
-
-               if (j >= MaxWaitCnt) {
-                       return LM_STATUS_FAILURE;
-               }
-       }
-
-       return LM_STATUS_SUCCESS;
-}
-
-/******************************************************************************/
-/* Description:                                                               */
-/*    This function reinitializes the adapter.                                */
-/*                                                                            */
-/* Return:                                                                    */
-/*    LM_STATUS_SUCCESS                                                       */
-/******************************************************************************/
-LM_STATUS LM_ResetAdapter (PLM_DEVICE_BLOCK pDevice)
-{
-       LM_UINT32 Value32;
-       LM_UINT16 Value16;
-       LM_UINT32 j, k;
-
-       /* Disable interrupt. */
-       LM_DisableInterrupt (pDevice);
-
-       /* May get a spurious interrupt */
-       pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED;
-
-       /* Disable transmit and receive DMA engines.  Abort all pending requests. */
-       if (pDevice->InitDone) {
-               LM_Abort (pDevice);
-       }
-
-       pDevice->ShuttingDown = FALSE;
-
-       LM_ResetChip (pDevice);
-
-       /* Bug: Athlon fix for B3 silicon only.  This bit does not do anything */
-       /* in other chip revisions. */
-       if (pDevice->DelayPciGrant) {
-               Value32 = REG_RD (pDevice, PciCfg.ClockCtrl);
-               REG_WR (pDevice, PciCfg.ClockCtrl, Value32 | BIT_31);
-       }
-
-       if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
-               if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)) {
-                       Value32 = REG_RD (pDevice, PciCfg.PciState);
-                       Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
-                       REG_WR (pDevice, PciCfg.PciState, Value32);
-               }
-       }
-
-       /* Enable TaggedStatus mode. */
-       if (pDevice->UseTaggedStatus) {
-               pDevice->MiscHostCtrl |=
-                   MISC_HOST_CTRL_ENABLE_TAGGED_STATUS_MODE;
-       }
-
-       /* Restore PCI configuration registers. */
-       MM_WriteConfig32 (pDevice, PCI_CACHE_LINE_SIZE_REG,
-                         pDevice->SavedCacheLineReg);
-       MM_WriteConfig32 (pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
-                         (pDevice->SubsystemId << 16) | pDevice->
-                         SubsystemVendorId);
-
-       /* Clear the statistics block. */
-       for (j = 0x0300; j < 0x0b00; j++) {
-               MEM_WR_OFFSET (pDevice, j, 0);
-       }
-
-       /* Initialize the statistis Block */
-       pDevice->pStatusBlkVirt->Status = 0;
-       pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
-       pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
-       pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
-
-       for (j = 0; j < 16; j++) {
-               pDevice->pStatusBlkVirt->Idx[j].RcvProdIdx = 0;
-               pDevice->pStatusBlkVirt->Idx[j].SendConIdx = 0;
-       }
-
-       for (k = 0; k < T3_STD_RCV_RCB_ENTRY_COUNT; k++) {
-               pDevice->pRxStdBdVirt[k].HostAddr.High = 0;
-               pDevice->pRxStdBdVirt[k].HostAddr.Low = 0;
-       }
-
-#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
-       /* Receive jumbo BD buffer. */
-       for (k = 0; k < T3_JUMBO_RCV_RCB_ENTRY_COUNT; k++) {
-               pDevice->pRxJumboBdVirt[k].HostAddr.High = 0;
-               pDevice->pRxJumboBdVirt[k].HostAddr.Low = 0;
-       }
-#endif
-
-       REG_WR (pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
-
-       /* GRC mode control register. */
-#ifdef BIG_ENDIAN_PCI          /* Jimmy, this ifdef block deleted in new code! */
-       Value32 =
-           GRC_MODE_WORD_SWAP_DATA |
-           GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
-           GRC_MODE_INT_ON_MAC_ATTN | GRC_MODE_HOST_STACK_UP;
-#else
-       /* No CPU Swap modes for PCI IO */
-       Value32 =
-#ifdef BIG_ENDIAN_HOST
-           GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
-           GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
-           GRC_MODE_BYTE_SWAP_DATA | GRC_MODE_WORD_SWAP_DATA |
-#else
-           GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
-           GRC_MODE_BYTE_SWAP_DATA | GRC_MODE_WORD_SWAP_DATA |
-#endif
-           GRC_MODE_INT_ON_MAC_ATTN | GRC_MODE_HOST_STACK_UP;
-#endif                         /* !BIG_ENDIAN_PCI */
-
-       /* Configure send BD mode. */
-       if (pDevice->NicSendBd == FALSE) {
-               Value32 |= GRC_MODE_HOST_SEND_BDS;
-       } else {
-               Value32 |= GRC_MODE_4X_NIC_BASED_SEND_RINGS;
-       }
-
-       /* Configure pseudo checksum mode. */
-       if (pDevice->NoTxPseudoHdrChksum) {
-               Value32 |= GRC_MODE_TX_NO_PSEUDO_HEADER_CHKSUM;
-       }
-
-       if (pDevice->NoRxPseudoHdrChksum) {
-               Value32 |= GRC_MODE_RX_NO_PSEUDO_HEADER_CHKSUM;
-       }
-
-       REG_WR (pDevice, Grc.Mode, Value32);
-
-       /* Setup the timer prescalar register. */
-       REG_WR (pDevice, Grc.MiscCfg, 65 << 1); /* Clock is alwasy 66Mhz. */
-
-       /* Set up the MBUF pool base address and size. */
-       REG_WR (pDevice, BufMgr.MbufPoolAddr, pDevice->MbufBase);
-       REG_WR (pDevice, BufMgr.MbufPoolSize, pDevice->MbufSize);
-
-       /* Set up the DMA descriptor pool base address and size. */
-       REG_WR (pDevice, BufMgr.DmaDescPoolAddr, T3_NIC_DMA_DESC_POOL_ADDR);
-       REG_WR (pDevice, BufMgr.DmaDescPoolSize, T3_NIC_DMA_DESC_POOL_SIZE);
-
-       /* Configure MBUF and Threshold watermarks */
-       /* Configure the DMA read MBUF low water mark. */
-       if (pDevice->DmaMbufLowMark) {
-               REG_WR (pDevice, BufMgr.MbufReadDmaLowWaterMark,
-                       pDevice->DmaMbufLowMark);
-       } else {
-               if (pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE) {
-                       REG_WR (pDevice, BufMgr.MbufReadDmaLowWaterMark,
-                               T3_DEF_DMA_MBUF_LOW_WMARK);
-               } else {
-                       REG_WR (pDevice, BufMgr.MbufReadDmaLowWaterMark,
-                               T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO);
-               }
-       }
-
-       /* Configure the MAC Rx MBUF low water mark. */
-       if (pDevice->RxMacMbufLowMark) {
-               REG_WR (pDevice, BufMgr.MbufMacRxLowWaterMark,
-                       pDevice->RxMacMbufLowMark);
-       } else {
-               if (pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE) {
-                       REG_WR (pDevice, BufMgr.MbufMacRxLowWaterMark,
-                               T3_DEF_RX_MAC_MBUF_LOW_WMARK);
-               } else {
-                       REG_WR (pDevice, BufMgr.MbufMacRxLowWaterMark,
-                               T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO);
-               }
-       }
-
-       /* Configure the MBUF high water mark. */
-       if (pDevice->MbufHighMark) {
-               REG_WR (pDevice, BufMgr.MbufHighWaterMark,
-                       pDevice->MbufHighMark);
-       } else {
-               if (pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE) {
-                       REG_WR (pDevice, BufMgr.MbufHighWaterMark,
-                               T3_DEF_MBUF_HIGH_WMARK);
-               } else {
-                       REG_WR (pDevice, BufMgr.MbufHighWaterMark,
-                               T3_DEF_MBUF_HIGH_WMARK_JUMBO);
-               }
-       }
-
-       REG_WR (pDevice, BufMgr.DmaLowWaterMark, T3_DEF_DMA_DESC_LOW_WMARK);
-       REG_WR (pDevice, BufMgr.DmaHighWaterMark, T3_DEF_DMA_DESC_HIGH_WMARK);
-
-       /* Enable buffer manager. */
-       REG_WR (pDevice, BufMgr.Mode,
-               BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE);
-
-       for (j = 0; j < 2000; j++) {
-               if (REG_RD (pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE)
-                       break;
-               MM_Wait (10);
-       }
-
-       if (j >= 2000) {
-               return LM_STATUS_FAILURE;
-       }
-
-       /* Enable the FTQs. */
-       REG_WR (pDevice, Ftq.Reset, 0xffffffff);
-       REG_WR (pDevice, Ftq.Reset, 0);
-
-       /* Wait until FTQ is ready */
-       for (j = 0; j < 2000; j++) {
-               if (REG_RD (pDevice, Ftq.Reset) == 0)
-                       break;
-               MM_Wait (10);
-       }
-
-       if (j >= 2000) {
-               return LM_STATUS_FAILURE;
-       }
-
-       /* Initialize the Standard Receive RCB. */
-       REG_WR (pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.High,
-               pDevice->RxStdBdPhy.High);
-       REG_WR (pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.Low,
-               pDevice->RxStdBdPhy.Low);
-       REG_WR (pDevice, RcvDataBdIn.StdRcvRcb.u.MaxLen_Flags,
-               MAX_STD_RCV_BUFFER_SIZE << 16);
-
-       /* Initialize the Jumbo Receive RCB. */
-       REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags,
-               T3_RCB_FLAG_RING_DISABLED);
-#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
-       REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.High,
-               pDevice->RxJumboBdPhy.High);
-       REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.Low,
-               pDevice->RxJumboBdPhy.Low);
-
-       REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags, 0);
-
-#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
-
-       /* Initialize the Mini Receive RCB. */
-       REG_WR (pDevice, RcvDataBdIn.MiniRcvRcb.u.MaxLen_Flags,
-               T3_RCB_FLAG_RING_DISABLED);
-
-       {
-               REG_WR (pDevice, RcvDataBdIn.StdRcvRcb.NicRingAddr,
-                       (LM_UINT32) T3_NIC_STD_RCV_BUFFER_DESC_ADDR);
-               REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.NicRingAddr,
-                       (LM_UINT32) T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR);
-       }
-
-       /* Receive BD Ring replenish threshold. */
-       REG_WR (pDevice, RcvBdIn.StdRcvThreshold, pDevice->RxStdDescCnt / 8);
-#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
-       REG_WR (pDevice, RcvBdIn.JumboRcvThreshold,
-               pDevice->RxJumboDescCnt / 8);
-#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
-
-       /* Disable all the unused rings. */
-       for (j = 0; j < T3_MAX_SEND_RCB_COUNT; j++) {
-               MEM_WR (pDevice, SendRcb[j].u.MaxLen_Flags,
-                       T3_RCB_FLAG_RING_DISABLED);
-       }                       /* for */
-
-       /* Initialize the indices. */
-       pDevice->SendProdIdx = 0;
-       pDevice->SendConIdx = 0;
-
-       MB_REG_WR (pDevice, Mailbox.SendHostProdIdx[0].Low, 0);
-       MB_REG_WR (pDevice, Mailbox.SendNicProdIdx[0].Low, 0);
-
-       /* Set up host or NIC based send RCB. */
-       if (pDevice->NicSendBd == FALSE) {
-               MEM_WR (pDevice, SendRcb[0].HostRingAddr.High,
-                       pDevice->SendBdPhy.High);
-               MEM_WR (pDevice, SendRcb[0].HostRingAddr.Low,
-                       pDevice->SendBdPhy.Low);
-
-               /* Set up the NIC ring address in the RCB. */
-               MEM_WR (pDevice, SendRcb[0].NicRingAddr,
-                       T3_NIC_SND_BUFFER_DESC_ADDR);
-
-               /* Setup the RCB. */
-               MEM_WR (pDevice, SendRcb[0].u.MaxLen_Flags,
-                       T3_SEND_RCB_ENTRY_COUNT << 16);
-
-               for (k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++) {
-                       pDevice->pSendBdVirt[k].HostAddr.High = 0;
-                       pDevice->pSendBdVirt[k].HostAddr.Low = 0;
-               }
-       } else {
-               MEM_WR (pDevice, SendRcb[0].HostRingAddr.High, 0);
-               MEM_WR (pDevice, SendRcb[0].HostRingAddr.Low, 0);
-               MEM_WR (pDevice, SendRcb[0].NicRingAddr,
-                       pDevice->SendBdPhy.Low);
-
-               for (k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++) {
-                       __raw_writel (0,
-                                     &(pDevice->pSendBdVirt[k].HostAddr.High));
-                       __raw_writel (0,
-                                     &(pDevice->pSendBdVirt[k].HostAddr.Low));
-                       __raw_writel (0,
-                                     &(pDevice->pSendBdVirt[k].u1.Len_Flags));
-                       pDevice->ShadowSendBd[k].HostAddr.High = 0;
-                       pDevice->ShadowSendBd[k].u1.Len_Flags = 0;
-               }
-       }
-       atomic_set (&pDevice->SendBdLeft, T3_SEND_RCB_ENTRY_COUNT - 1);
-
-       /* Configure the receive return rings. */
-       for (j = 0; j < T3_MAX_RCV_RETURN_RCB_COUNT; j++) {
-               MEM_WR (pDevice, RcvRetRcb[j].u.MaxLen_Flags,
-                       T3_RCB_FLAG_RING_DISABLED);
-       }
-
-       pDevice->RcvRetConIdx = 0;
-
-       MEM_WR (pDevice, RcvRetRcb[0].HostRingAddr.High,
-               pDevice->RcvRetBdPhy.High);
-       MEM_WR (pDevice, RcvRetRcb[0].HostRingAddr.Low,
-               pDevice->RcvRetBdPhy.Low);
-
-       /* Set up the NIC ring address in the RCB. */
-       /* Not very clear from the spec.  I am guessing that for Receive */
-       /* Return Ring, NicRingAddr is not used. */
-       MEM_WR (pDevice, RcvRetRcb[0].NicRingAddr, 0);
-
-       /* Setup the RCB. */
-       MEM_WR (pDevice, RcvRetRcb[0].u.MaxLen_Flags,
-               T3_RCV_RETURN_RCB_ENTRY_COUNT << 16);
-
-       /* Reinitialize RX ring producer index */
-       MB_REG_WR (pDevice, Mailbox.RcvStdProdIdx.Low, 0);
-       MB_REG_WR (pDevice, Mailbox.RcvJumboProdIdx.Low, 0);
-       MB_REG_WR (pDevice, Mailbox.RcvMiniProdIdx.Low, 0);
-
-#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
-       pDevice->RxJumboProdIdx = 0;
-       pDevice->RxJumboQueuedCnt = 0;
-#endif
-
-       /* Reinitialize our copy of the indices. */
-       pDevice->RxStdProdIdx = 0;
-       pDevice->RxStdQueuedCnt = 0;
-
-#if T3_JUMBO_RCV_ENTRY_COUNT
-       pDevice->RxJumboProdIdx = 0;
-#endif                         /* T3_JUMBO_RCV_ENTRY_COUNT */
-
-       /* Configure the MAC address. */
-       LM_SetMacAddress (pDevice, pDevice->NodeAddress);
-
-       /* Initialize the transmit random backoff seed. */
-       Value32 = (pDevice->NodeAddress[0] + pDevice->NodeAddress[1] +
-                  pDevice->NodeAddress[2] + pDevice->NodeAddress[3] +
-                  pDevice->NodeAddress[4] + pDevice->NodeAddress[5]) &
-           MAC_TX_BACKOFF_SEED_MASK;
-       REG_WR (pDevice, MacCtrl.TxBackoffSeed, Value32);
-
-       /* Receive MTU.  Frames larger than the MTU is marked as oversized. */
-       REG_WR (pDevice, MacCtrl.MtuSize, pDevice->RxMtu + 8);  /* CRC + VLAN. */
-
-       /* Configure Time slot/IPG per 802.3 */
-       REG_WR (pDevice, MacCtrl.TxLengths, 0x2620);
-
-       /*
-        * Configure Receive Rules so that packets don't match
-        * Programmble rule will be queued to Return Ring 1
-        */
-       REG_WR (pDevice, MacCtrl.RcvRuleCfg, RX_RULE_DEFAULT_CLASS);
-
-       /*
-        * Configure to have 16 Classes of Services (COS) and one
-        * queue per class.  Bad frames are queued to RRR#1.
-        * And frames don't match rules are also queued to COS#1.
-        */
-       REG_WR (pDevice, RcvListPlmt.Config, 0x181);
-
-       /* Enable Receive Placement Statistics */
-       REG_WR (pDevice, RcvListPlmt.StatsEnableMask, 0xffffff);
-       REG_WR (pDevice, RcvListPlmt.StatsCtrl, RCV_LIST_STATS_ENABLE);
-
-       /* Enable Send Data Initator Statistics */
-       REG_WR (pDevice, SndDataIn.StatsEnableMask, 0xffffff);
-       REG_WR (pDevice, SndDataIn.StatsCtrl,
-               T3_SND_DATA_IN_STATS_CTRL_ENABLE |
-               T3_SND_DATA_IN_STATS_CTRL_FASTER_UPDATE);
-
-       /* Disable the host coalescing state machine before configuring it's */
-       /* parameters. */
-       REG_WR (pDevice, HostCoalesce.Mode, 0);
-       for (j = 0; j < 2000; j++) {
-               Value32 = REG_RD (pDevice, HostCoalesce.Mode);
-               if (!(Value32 & HOST_COALESCE_ENABLE)) {
-                       break;
-               }
-               MM_Wait (10);
-       }
-
-       /* Host coalescing configurations. */
-       REG_WR (pDevice, HostCoalesce.RxCoalescingTicks,
-               pDevice->RxCoalescingTicks);
-       REG_WR (pDevice, HostCoalesce.TxCoalescingTicks,
-               pDevice->TxCoalescingTicks);
-       REG_WR (pDevice, HostCoalesce.RxMaxCoalescedFrames,
-               pDevice->RxMaxCoalescedFrames);
-       REG_WR (pDevice, HostCoalesce.TxMaxCoalescedFrames,
-               pDevice->TxMaxCoalescedFrames);
-       REG_WR (pDevice, HostCoalesce.RxCoalescedTickDuringInt,
-               pDevice->RxCoalescingTicksDuringInt);
-       REG_WR (pDevice, HostCoalesce.TxCoalescedTickDuringInt,
-               pDevice->TxCoalescingTicksDuringInt);
-       REG_WR (pDevice, HostCoalesce.RxMaxCoalescedFramesDuringInt,
-               pDevice->RxMaxCoalescedFramesDuringInt);
-       REG_WR (pDevice, HostCoalesce.TxMaxCoalescedFramesDuringInt,
-               pDevice->TxMaxCoalescedFramesDuringInt);
-
-       /* Initialize the address of the status block.  The NIC will DMA */
-       /* the status block to this memory which resides on the host. */
-       REG_WR (pDevice, HostCoalesce.StatusBlkHostAddr.High,
-               pDevice->StatusBlkPhy.High);
-       REG_WR (pDevice, HostCoalesce.StatusBlkHostAddr.Low,
-               pDevice->StatusBlkPhy.Low);
-
-       /* Initialize the address of the statistics block.  The NIC will DMA */
-       /* the statistics to this block of memory. */
-       REG_WR (pDevice, HostCoalesce.StatsBlkHostAddr.High,
-               pDevice->StatsBlkPhy.High);
-       REG_WR (pDevice, HostCoalesce.StatsBlkHostAddr.Low,
-               pDevice->StatsBlkPhy.Low);
-
-       REG_WR (pDevice, HostCoalesce.StatsCoalescingTicks,
-               pDevice->StatsCoalescingTicks);
-
-       REG_WR (pDevice, HostCoalesce.StatsBlkNicAddr, 0x300);
-       REG_WR (pDevice, HostCoalesce.StatusBlkNicAddr, 0xb00);
-
-       /* Enable Host Coalesing state machine */
-       REG_WR (pDevice, HostCoalesce.Mode, HOST_COALESCE_ENABLE |
-               pDevice->CoalesceMode);
-
-       /* Enable the Receive BD Completion state machine. */
-       REG_WR (pDevice, RcvBdComp.Mode, RCV_BD_COMP_MODE_ENABLE |
-               RCV_BD_COMP_MODE_ATTN_ENABLE);
-
-       /* Enable the Receive List Placement state machine. */
-       REG_WR (pDevice, RcvListPlmt.Mode, RCV_LIST_PLMT_MODE_ENABLE);
-
-       /* Enable the Receive List Selector state machine. */
-       REG_WR (pDevice, RcvListSel.Mode, RCV_LIST_SEL_MODE_ENABLE |
-               RCV_LIST_SEL_MODE_ATTN_ENABLE);
-
-       /* Enable transmit DMA, clear statistics. */
-       pDevice->MacMode = MAC_MODE_ENABLE_TX_STATISTICS |
-           MAC_MODE_ENABLE_RX_STATISTICS | MAC_MODE_ENABLE_TDE |
-           MAC_MODE_ENABLE_RDE | MAC_MODE_ENABLE_FHDE;
-       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode |
-               MAC_MODE_CLEAR_RX_STATISTICS | MAC_MODE_CLEAR_TX_STATISTICS);
-
-       /* GRC miscellaneous local control register. */
-       pDevice->GrcLocalCtrl = GRC_MISC_LOCAL_CTRL_INT_ON_ATTN |
-           GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM;
-
-       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
-               pDevice->GrcLocalCtrl |= GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
-                   GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1;
-       }
-
-       REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
-       MM_Wait (40);
-
-       /* Reset RX counters. */
-       for (j = 0; j < sizeof (LM_RX_COUNTERS); j++) {
-               ((PLM_UINT8) & pDevice->RxCounters)[j] = 0;
-       }
-
-       /* Reset TX counters. */
-       for (j = 0; j < sizeof (LM_TX_COUNTERS); j++) {
-               ((PLM_UINT8) & pDevice->TxCounters)[j] = 0;
-       }
-
-       MB_REG_WR (pDevice, Mailbox.Interrupt[0].Low, 0);
-
-       /* Enable the DMA Completion state machine. */
-       REG_WR (pDevice, DmaComp.Mode, DMA_COMP_MODE_ENABLE);
-
-       /* Enable the DMA Write state machine. */
-       Value32 = DMA_WRITE_MODE_ENABLE |
-           DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE |
-           DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE |
-           DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE |
-           DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
-           DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE |
-           DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
-           DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE |
-           DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE;
-       REG_WR (pDevice, DmaWrite.Mode, Value32);
-
-       if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)) {
-               if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
-                       Value16 = REG_RD (pDevice, PciCfg.PciXCommand);
-                       Value16 &=
-                           ~(PCIX_CMD_MAX_SPLIT_MASK |
-                             PCIX_CMD_MAX_BURST_MASK);
-                       Value16 |=
-                           ((PCIX_CMD_MAX_BURST_CPIOB <<
-                             PCIX_CMD_MAX_BURST_SHL) &
-                            PCIX_CMD_MAX_BURST_MASK);
-                       if (pDevice->SplitModeEnable == SPLIT_MODE_ENABLE) {
-                               Value16 |=
-                                   (pDevice->
-                                    SplitModeMaxReq << PCIX_CMD_MAX_SPLIT_SHL)
-                                   & PCIX_CMD_MAX_SPLIT_MASK;
-                       }
-                       REG_WR (pDevice, PciCfg.PciXCommand, Value16);
-               }
-       }
-
-       /* Enable the Read DMA state machine. */
-       Value32 = DMA_READ_MODE_ENABLE |
-           DMA_READ_MODE_TARGET_ABORT_ATTN_ENABLE |
-           DMA_READ_MODE_MASTER_ABORT_ATTN_ENABLE |
-           DMA_READ_MODE_PARITY_ERROR_ATTN_ENABLE |
-           DMA_READ_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
-           DMA_READ_MODE_FIFO_OVERRUN_ATTN_ENABLE |
-           DMA_READ_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
-           DMA_READ_MODE_FIFO_OVERREAD_ATTN_ENABLE |
-           DMA_READ_MODE_LONG_READ_ATTN_ENABLE;
-
-       if (pDevice->SplitModeEnable == SPLIT_MODE_ENABLE) {
-               Value32 |= DMA_READ_MODE_SPLIT_ENABLE;
-       }
-       REG_WR (pDevice, DmaRead.Mode, Value32);
-
-       /* Enable the Receive Data Completion state machine. */
-       REG_WR (pDevice, RcvDataComp.Mode, RCV_DATA_COMP_MODE_ENABLE |
-               RCV_DATA_COMP_MODE_ATTN_ENABLE);
-
-       /* Enable the Mbuf Cluster Free state machine. */
-       REG_WR (pDevice, MbufClusterFree.Mode, MBUF_CLUSTER_FREE_MODE_ENABLE);
-
-       /* Enable the Send Data Completion state machine. */
-       REG_WR (pDevice, SndDataComp.Mode, SND_DATA_COMP_MODE_ENABLE);
-
-       /* Enable the Send BD Completion state machine. */
-       REG_WR (pDevice, SndBdComp.Mode, SND_BD_COMP_MODE_ENABLE |
-               SND_BD_COMP_MODE_ATTN_ENABLE);
-
-       /* Enable the Receive BD Initiator state machine. */
-       REG_WR (pDevice, RcvBdIn.Mode, RCV_BD_IN_MODE_ENABLE |
-               RCV_BD_IN_MODE_BD_IN_DIABLED_RCB_ATTN_ENABLE);
-
-       /* Enable the Receive Data and Receive BD Initiator state machine. */
-       REG_WR (pDevice, RcvDataBdIn.Mode, RCV_DATA_BD_IN_MODE_ENABLE |
-               RCV_DATA_BD_IN_MODE_INVALID_RING_SIZE);
-
-       /* Enable the Send Data Initiator state machine. */
-       REG_WR (pDevice, SndDataIn.Mode, T3_SND_DATA_IN_MODE_ENABLE);
-
-       /* Enable the Send BD Initiator state machine. */
-       REG_WR (pDevice, SndBdIn.Mode, SND_BD_IN_MODE_ENABLE |
-               SND_BD_IN_MODE_ATTN_ENABLE);
-
-       /* Enable the Send BD Selector state machine. */
-       REG_WR (pDevice, SndBdSel.Mode, SND_BD_SEL_MODE_ENABLE |
-               SND_BD_SEL_MODE_ATTN_ENABLE);
-
-#if INCLUDE_5701_AX_FIX
-       /* Load the firmware for the 5701_A0 workaround. */
-       if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0) {
-               LM_LoadRlsFirmware (pDevice);
-       }
-#endif
-
-       /* Enable the transmitter. */
-       pDevice->TxMode = TX_MODE_ENABLE;
-       REG_WR (pDevice, MacCtrl.TxMode, pDevice->TxMode);
-
-       /* Enable the receiver. */
-       pDevice->RxMode = RX_MODE_ENABLE;
-       REG_WR (pDevice, MacCtrl.RxMode, pDevice->RxMode);
-
-       if (pDevice->RestoreOnWakeUp) {
-               pDevice->RestoreOnWakeUp = FALSE;
-               pDevice->DisableAutoNeg = pDevice->WakeUpDisableAutoNeg;
-               pDevice->RequestedMediaType = pDevice->WakeUpRequestedMediaType;
-       }
-
-       /* Disable auto polling. */
-       pDevice->MiMode = 0xc0000;
-       REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
-
-       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
-           T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
-               Value32 = LED_CTRL_PHY_MODE_1;
-       } else {
-               if (pDevice->LedMode == LED_MODE_OUTPUT) {
-                       Value32 = LED_CTRL_PHY_MODE_2;
-               } else {
-                       Value32 = LED_CTRL_PHY_MODE_1;
-               }
-       }
-       REG_WR (pDevice, MacCtrl.LedCtrl, Value32);
-
-       /* Activate Link to enable MAC state machine */
-       REG_WR (pDevice, MacCtrl.MiStatus, MI_STATUS_ENABLE_LINK_STATUS_ATTN);
-
-       if (pDevice->EnableTbi) {
-               REG_WR (pDevice, MacCtrl.RxMode, RX_MODE_RESET);
-               MM_Wait (10);
-               REG_WR (pDevice, MacCtrl.RxMode, pDevice->RxMode);
-               if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1) {
-                       REG_WR (pDevice, MacCtrl.SerdesCfg, 0x616000);
-               }
-       }
-       /* Setup the phy chip. */
-       LM_SetupPhy (pDevice);
-
-       if (!pDevice->EnableTbi) {
-               /* Clear CRC stats */
-               LM_ReadPhy (pDevice, 0x1e, &Value32);
-               LM_WritePhy (pDevice, 0x1e, Value32 | 0x8000);
-               LM_ReadPhy (pDevice, 0x14, &Value32);
-       }
-
-       /* Set up the receive mask. */
-       LM_SetReceiveMask (pDevice, pDevice->ReceiveMask);
-
-       /* Queue Rx packet buffers. */
-       if (pDevice->QueueRxPackets) {
-               LM_QueueRxPackets (pDevice);
-       }
-
-       /* Enable interrupt to the host. */
-       if (pDevice->InitDone) {
-               LM_EnableInterrupt (pDevice);
-       }
-
-       return LM_STATUS_SUCCESS;
-}                              /* LM_ResetAdapter */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*    This routine disables the adapter from generating interrupts.           */
-/*                                                                            */
-/* Return:                                                                    */
-/*    LM_STATUS_SUCCESS                                                       */
-/******************************************************************************/
-LM_STATUS LM_DisableInterrupt (PLM_DEVICE_BLOCK pDevice)
-{
-       REG_WR (pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl |
-               MISC_HOST_CTRL_MASK_PCI_INT);
-       MB_REG_WR (pDevice, Mailbox.Interrupt[0].Low, 1);
-
-       return LM_STATUS_SUCCESS;
-}
-
-/******************************************************************************/
-/* Description:                                                               */
-/*    This routine enables the adapter to generate interrupts.                */
-/*                                                                            */
-/* Return:                                                                    */
-/*    LM_STATUS_SUCCESS                                                       */
-/******************************************************************************/
-LM_STATUS LM_EnableInterrupt (PLM_DEVICE_BLOCK pDevice)
-{
-       REG_WR (pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl &
-               ~MISC_HOST_CTRL_MASK_PCI_INT);
-       MB_REG_WR (pDevice, Mailbox.Interrupt[0].Low, 0);
-
-       if (pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_UPDATED) {
-               REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
-                       GRC_MISC_LOCAL_CTRL_SET_INT);
-       }
-
-       return LM_STATUS_SUCCESS;
-}
-
-/******************************************************************************/
-/* Description:                                                               */
-/*    This routine puts a packet on the wire if there is a transmit DMA       */
-/*    descriptor available; otherwise the packet is queued for later          */
-/*    transmission.  If the second argue is NULL, this routine will put       */
-/*    the queued packet on the wire if possible.                              */
-/*                                                                            */
-/* Return:                                                                    */
-/*    LM_STATUS_SUCCESS                                                       */
-/******************************************************************************/
-#if 0
-LM_STATUS LM_SendPacket (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
-{
-       LM_UINT32 FragCount;
-       PT3_SND_BD pSendBd;
-       PT3_SND_BD pShadowSendBd;
-       LM_UINT32 Value32, Len;
-       LM_UINT32 Idx;
-
-       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
-               return LM_5700SendPacket (pDevice, pPacket);
-       }
-
-       /* Update the SendBdLeft count. */
-       atomic_sub (pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
-
-       /* Initalize the send buffer descriptors. */
-       Idx = pDevice->SendProdIdx;
-
-       pSendBd = &pDevice->pSendBdVirt[Idx];
-
-       /* Next producer index. */
-       if (pDevice->NicSendBd == TRUE) {
-               T3_64BIT_HOST_ADDR paddr;
-
-               pShadowSendBd = &pDevice->ShadowSendBd[Idx];
-               for (FragCount = 0;;) {
-                       MM_MapTxDma (pDevice, pPacket, &paddr, &Len, FragCount);
-                       /* Initialize the pointer to the send buffer fragment. */
-                       if (paddr.High != pShadowSendBd->HostAddr.High) {
-                               __raw_writel (paddr.High,
-                                             &(pSendBd->HostAddr.High));
-                               pShadowSendBd->HostAddr.High = paddr.High;
-                       }
-                       __raw_writel (paddr.Low, &(pSendBd->HostAddr.Low));
-
-                       /* Setup the control flags and send buffer size. */
-                       Value32 = (Len << 16) | pPacket->Flags;
-
-                       Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
-
-                       FragCount++;
-                       if (FragCount >= pPacket->u.Tx.FragCount) {
-                               Value32 |= SND_BD_FLAG_END;
-                               if (Value32 != pShadowSendBd->u1.Len_Flags) {
-                                       __raw_writel (Value32,
-                                                     &(pSendBd->u1.Len_Flags));
-                                       pShadowSendBd->u1.Len_Flags = Value32;
-                               }
-                               if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
-                                       __raw_writel (pPacket->VlanTag,
-                                                     &(pSendBd->u2.VlanTag));
-                               }
-                               break;
-                       } else {
-                               if (Value32 != pShadowSendBd->u1.Len_Flags) {
-                                       __raw_writel (Value32,
-                                                     &(pSendBd->u1.Len_Flags));
-                                       pShadowSendBd->u1.Len_Flags = Value32;
-                               }
-                               if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
-                                       __raw_writel (pPacket->VlanTag,
-                                                     &(pSendBd->u2.VlanTag));
-                               }
-                       }
-
-                       pSendBd++;
-                       pShadowSendBd++;
-                       if (Idx == 0) {
-                               pSendBd = &pDevice->pSendBdVirt[0];
-                               pShadowSendBd = &pDevice->ShadowSendBd[0];
-                       }
-               }               /* for */
-
-               /* Put the packet descriptor in the ActiveQ. */
-               QQ_PushTail (&pDevice->TxPacketActiveQ.Container, pPacket);
-
-               wmb ();
-               MB_REG_WR (pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
-
-       } else {
-               for (FragCount = 0;;) {
-                       /* Initialize the pointer to the send buffer fragment. */
-                       MM_MapTxDma (pDevice, pPacket, &pSendBd->HostAddr, &Len,
-                                    FragCount);
-
-                       pSendBd->u2.VlanTag = pPacket->VlanTag;
-
-                       /* Setup the control flags and send buffer size. */
-                       Value32 = (Len << 16) | pPacket->Flags;
-
-                       Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
-
-                       FragCount++;
-                       if (FragCount >= pPacket->u.Tx.FragCount) {
-                               pSendBd->u1.Len_Flags =
-                                   Value32 | SND_BD_FLAG_END;
-                               break;
-                       } else {
-                               pSendBd->u1.Len_Flags = Value32;
-                       }
-                       pSendBd++;
-                       if (Idx == 0) {
-                               pSendBd = &pDevice->pSendBdVirt[0];
-                       }
-               }               /* for */
-
-               /* Put the packet descriptor in the ActiveQ. */
-               QQ_PushTail (&pDevice->TxPacketActiveQ.Container, pPacket);
-
-               wmb ();
-               MB_REG_WR (pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
-
-       }
-
-       /* Update the producer index. */
-       pDevice->SendProdIdx = Idx;
-
-       return LM_STATUS_SUCCESS;
-}
-#endif
-
-LM_STATUS LM_SendPacket (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
-{
-       LM_UINT32 FragCount;
-       PT3_SND_BD pSendBd, pTmpSendBd, pShadowSendBd;
-       T3_SND_BD NicSendBdArr[MAX_FRAGMENT_COUNT];
-       LM_UINT32 StartIdx, Idx;
-
-       while (1) {
-               /* Initalize the send buffer descriptors. */
-               StartIdx = Idx = pDevice->SendProdIdx;
-
-               if (pDevice->NicSendBd) {
-                       pTmpSendBd = pSendBd = &NicSendBdArr[0];
-               } else {
-                       pTmpSendBd = pSendBd = &pDevice->pSendBdVirt[Idx];
-               }
-
-               /* Next producer index. */
-               for (FragCount = 0;;) {
-                       LM_UINT32 Value32, Len;
-
-                       /* Initialize the pointer to the send buffer fragment. */
-                       MM_MapTxDma (pDevice, pPacket, &pSendBd->HostAddr, &Len,
-                                    FragCount);
-
-                       pSendBd->u2.VlanTag = pPacket->VlanTag;
-
-                       /* Setup the control flags and send buffer size. */
-                       Value32 = (Len << 16) | pPacket->Flags;
-
-                       Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
-
-                       FragCount++;
-                       if (FragCount >= pPacket->u.Tx.FragCount) {
-                               pSendBd->u1.Len_Flags =
-                                   Value32 | SND_BD_FLAG_END;
-                               break;
-                       } else {
-                               pSendBd->u1.Len_Flags = Value32;
-                       }
-                       pSendBd++;
-                       if ((Idx == 0) && !pDevice->NicSendBd) {
-                               pSendBd = &pDevice->pSendBdVirt[0];
-                       }
-               }               /* for */
-               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
-                       if (LM_Test4GBoundary (pDevice, pPacket, pTmpSendBd) ==
-                           LM_STATUS_SUCCESS) {
-                               if (MM_CoalesceTxBuffer (pDevice, pPacket) !=
-                                   LM_STATUS_SUCCESS) {
-                                       QQ_PushHead (&pDevice->TxPacketFreeQ.
-                                                    Container, pPacket);
-                                       return LM_STATUS_FAILURE;
-                               }
-                               continue;
-                       }
-               }
-               break;
-       }
-       /* Put the packet descriptor in the ActiveQ. */
-       QQ_PushTail (&pDevice->TxPacketActiveQ.Container, pPacket);
-
-       if (pDevice->NicSendBd) {
-               pSendBd = &pDevice->pSendBdVirt[StartIdx];
-               pShadowSendBd = &pDevice->ShadowSendBd[StartIdx];
-
-               while (StartIdx != Idx) {
-                       LM_UINT32 Value32;
-
-                       if ((Value32 = pTmpSendBd->HostAddr.High) !=
-                           pShadowSendBd->HostAddr.High) {
-                               __raw_writel (Value32,
-                                             &(pSendBd->HostAddr.High));
-                               pShadowSendBd->HostAddr.High = Value32;
-                       }
-
-                       __raw_writel (pTmpSendBd->HostAddr.Low,
-                                     &(pSendBd->HostAddr.Low));
-
-                       if ((Value32 = pTmpSendBd->u1.Len_Flags) !=
-                           pShadowSendBd->u1.Len_Flags) {
-                               __raw_writel (Value32,
-                                             &(pSendBd->u1.Len_Flags));
-                               pShadowSendBd->u1.Len_Flags = Value32;
-                       }
-
-                       if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
-                               __raw_writel (pTmpSendBd->u2.VlanTag,
-                                             &(pSendBd->u2.VlanTag));
-                       }
-
-                       StartIdx =
-                           (StartIdx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
-                       if (StartIdx == 0)
-                               pSendBd = &pDevice->pSendBdVirt[0];
-                       else
-                               pSendBd++;
-                       pTmpSendBd++;
-               }
-               wmb ();
-               MB_REG_WR (pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
-
-               if (T3_CHIP_REV (pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) {
-                       MB_REG_WR (pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
-               }
-       } else {
-               wmb ();
-               MB_REG_WR (pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
-
-               if (T3_CHIP_REV (pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) {
-                       MB_REG_WR (pDevice, Mailbox.SendHostProdIdx[0].Low,
-                                  Idx);
-               }
-       }
-
-       /* Update the SendBdLeft count. */
-       atomic_sub (pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
-
-       /* Update the producer index. */
-       pDevice->SendProdIdx = Idx;
-
-       return LM_STATUS_SUCCESS;
-}
-
-STATIC LM_STATUS
-LM_Test4GBoundary (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
-                  PT3_SND_BD pSendBd)
-{
-       int FragCount;
-       LM_UINT32 Idx, Base, Len;
-
-       Idx = pDevice->SendProdIdx;
-       for (FragCount = 0;;) {
-               Len = pSendBd->u1.Len_Flags >> 16;
-               if (((Base = pSendBd->HostAddr.Low) > 0xffffdcc0) &&
-                   (pSendBd->HostAddr.High == 0) &&
-                   ((Base + 8 + Len) < Base)) {
-                       return LM_STATUS_SUCCESS;
-               }
-               FragCount++;
-               if (FragCount >= pPacket->u.Tx.FragCount) {
-                       break;
-               }
-               pSendBd++;
-               if (!pDevice->NicSendBd) {
-                       Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
-                       if (Idx == 0) {
-                               pSendBd = &pDevice->pSendBdVirt[0];
-                       }
-               }
-       }
-       return LM_STATUS_FAILURE;
-}
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-__inline static unsigned long
-ComputeCrc32 (unsigned char *pBuffer, unsigned long BufferSize)
-{
-       unsigned long Reg;
-       unsigned long Tmp;
-       unsigned long j, k;
-
-       Reg = 0xffffffff;
-
-       for (j = 0; j < BufferSize; j++) {
-               Reg ^= pBuffer[j];
-
-               for (k = 0; k < 8; k++) {
-                       Tmp = Reg & 0x01;
-
-                       Reg >>= 1;
-
-                       if (Tmp) {
-                               Reg ^= 0xedb88320;
-                       }
-               }
-       }
-
-       return ~Reg;
-}                              /* ComputeCrc32 */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*    This routine sets the receive control register according to ReceiveMask */
-/*                                                                            */
-/* Return:                                                                    */
-/*    LM_STATUS_SUCCESS                                                       */
-/******************************************************************************/
-LM_STATUS LM_SetReceiveMask (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Mask)
-{
-       LM_UINT32 ReceiveMask;
-       LM_UINT32 RxMode;
-       LM_UINT32 j, k;
-
-       ReceiveMask = Mask;
-
-       RxMode = pDevice->RxMode;
-
-       if (Mask & LM_ACCEPT_UNICAST) {
-               Mask &= ~LM_ACCEPT_UNICAST;
-       }
-
-       if (Mask & LM_ACCEPT_MULTICAST) {
-               Mask &= ~LM_ACCEPT_MULTICAST;
-       }
-
-       if (Mask & LM_ACCEPT_ALL_MULTICAST) {
-               Mask &= ~LM_ACCEPT_ALL_MULTICAST;
-       }
-
-       if (Mask & LM_ACCEPT_BROADCAST) {
-               Mask &= ~LM_ACCEPT_BROADCAST;
-       }
-
-       RxMode &= ~RX_MODE_PROMISCUOUS_MODE;
-       if (Mask & LM_PROMISCUOUS_MODE) {
-               RxMode |= RX_MODE_PROMISCUOUS_MODE;
-               Mask &= ~LM_PROMISCUOUS_MODE;
-       }
-
-       RxMode &= ~(RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED);
-       if (Mask & LM_ACCEPT_ERROR_PACKET) {
-               RxMode |= RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED;
-               Mask &= ~LM_ACCEPT_ERROR_PACKET;
-       }
-
-       /* Make sure all the bits are valid before committing changes. */
-       if (Mask) {
-               return LM_STATUS_FAILURE;
-       }
-
-       /* Commit the new filter. */
-       pDevice->RxMode = RxMode;
-       REG_WR (pDevice, MacCtrl.RxMode, RxMode);
-
-       pDevice->ReceiveMask = ReceiveMask;
-
-       /* Set up the MC hash table. */
-       if (ReceiveMask & LM_ACCEPT_ALL_MULTICAST) {
-               for (k = 0; k < 4; k++) {
-                       REG_WR (pDevice, MacCtrl.HashReg[k], 0xffffffff);
-               }
-       } else if (ReceiveMask & LM_ACCEPT_MULTICAST) {
-               LM_UINT32 HashReg[4];
-
-               HashReg[0] = 0;
-               HashReg[1] = 0;
-               HashReg[2] = 0;
-               HashReg[3] = 0;
-               for (j = 0; j < pDevice->McEntryCount; j++) {
-                       LM_UINT32 RegIndex;
-                       LM_UINT32 Bitpos;
-                       LM_UINT32 Crc32;
-
-                       Crc32 =
-                           ComputeCrc32 (pDevice->McTable[j],
-                                         ETHERNET_ADDRESS_SIZE);
-
-                       /* The most significant 7 bits of the CRC32 (no inversion), */
-                       /* are used to index into one of the possible 128 bit positions. */
-                       Bitpos = ~Crc32 & 0x7f;
-
-                       /* Hash register index. */
-                       RegIndex = (Bitpos & 0x60) >> 5;
-
-                       /* Bit to turn on within a hash register. */
-                       Bitpos &= 0x1f;
-
-                       /* Enable the multicast bit. */
-                       HashReg[RegIndex] |= (1 << Bitpos);
-               }
-
-               /* REV_AX has problem with multicast filtering where it uses both */
-               /* DA and SA to perform hashing. */
-               for (k = 0; k < 4; k++) {
-                       REG_WR (pDevice, MacCtrl.HashReg[k], HashReg[k]);
-               }
-       } else {
-               /* Reject all multicast frames. */
-               for (j = 0; j < 4; j++) {
-                       REG_WR (pDevice, MacCtrl.HashReg[j], 0);
-               }
-       }
-
-       /* By default, Tigon3 will accept broadcast frames.  We need to setup */
-       if (ReceiveMask & LM_ACCEPT_BROADCAST) {
-               REG_WR (pDevice,
-                       MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
-                       REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
-               REG_WR (pDevice,
-                       MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
-                       REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
-               REG_WR (pDevice,
-                       MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
-                       REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
-               REG_WR (pDevice,
-                       MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
-                       REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
-       } else {
-               REG_WR (pDevice,
-                       MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
-                       REJECT_BROADCAST_RULE1_RULE);
-               REG_WR (pDevice,
-                       MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
-                       REJECT_BROADCAST_RULE1_VALUE);
-               REG_WR (pDevice,
-                       MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
-                       REJECT_BROADCAST_RULE2_RULE);
-               REG_WR (pDevice,
-                       MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
-                       REJECT_BROADCAST_RULE2_VALUE);
-       }
-
-       /* disable the rest of the rules. */
-       for (j = RCV_LAST_RULE_IDX; j < 16; j++) {
-               REG_WR (pDevice, MacCtrl.RcvRules[j].Rule, 0);
-               REG_WR (pDevice, MacCtrl.RcvRules[j].Value, 0);
-       }
-
-       return LM_STATUS_SUCCESS;
-}                              /* LM_SetReceiveMask */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*    Disable the interrupt and put the transmitter and receiver engines in   */
-/*    an idle state.  Also aborts all pending send requests and receive       */
-/*    buffers.                                                                */
-/*                                                                            */
-/* Return:                                                                    */
-/*    LM_STATUS_SUCCESS                                                       */
-/******************************************************************************/
-LM_STATUS LM_Abort (PLM_DEVICE_BLOCK pDevice)
-{
-       PLM_PACKET pPacket;
-       LM_UINT Idx;
-
-       LM_DisableInterrupt (pDevice);
-
-       /* Disable all the state machines. */
-       LM_CntrlBlock (pDevice, T3_BLOCK_MAC_RX_ENGINE, LM_DISABLE);
-       LM_CntrlBlock (pDevice, T3_BLOCK_RX_BD_INITIATOR, LM_DISABLE);
-       LM_CntrlBlock (pDevice, T3_BLOCK_RX_LIST_PLMT, LM_DISABLE);
-       LM_CntrlBlock (pDevice, T3_BLOCK_RX_LIST_SELECTOR, LM_DISABLE);
-       LM_CntrlBlock (pDevice, T3_BLOCK_RX_DATA_INITIATOR, LM_DISABLE);
-       LM_CntrlBlock (pDevice, T3_BLOCK_RX_DATA_COMP, LM_DISABLE);
-       LM_CntrlBlock (pDevice, T3_BLOCK_RX_BD_COMP, LM_DISABLE);
-
-       LM_CntrlBlock (pDevice, T3_BLOCK_SEND_BD_SELECTOR, LM_DISABLE);
-       LM_CntrlBlock (pDevice, T3_BLOCK_SEND_BD_INITIATOR, LM_DISABLE);
-       LM_CntrlBlock (pDevice, T3_BLOCK_SEND_DATA_INITIATOR, LM_DISABLE);
-       LM_CntrlBlock (pDevice, T3_BLOCK_DMA_RD, LM_DISABLE);
-       LM_CntrlBlock (pDevice, T3_BLOCK_SEND_DATA_COMP, LM_DISABLE);
-       LM_CntrlBlock (pDevice, T3_BLOCK_DMA_COMP, LM_DISABLE);
-       LM_CntrlBlock (pDevice, T3_BLOCK_SEND_BD_COMP, LM_DISABLE);
-
-       /* Clear TDE bit */
-       pDevice->MacMode &= ~MAC_MODE_ENABLE_TDE;
-       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
-
-       LM_CntrlBlock (pDevice, T3_BLOCK_MAC_TX_ENGINE, LM_DISABLE);
-       LM_CntrlBlock (pDevice, T3_BLOCK_HOST_COALESING, LM_DISABLE);
-       LM_CntrlBlock (pDevice, T3_BLOCK_DMA_WR, LM_DISABLE);
-       LM_CntrlBlock (pDevice, T3_BLOCK_MBUF_CLUSTER_FREE, LM_DISABLE);
-
-       /* Reset all FTQs */
-       REG_WR (pDevice, Ftq.Reset, 0xffffffff);
-       REG_WR (pDevice, Ftq.Reset, 0x0);
-
-       LM_CntrlBlock (pDevice, T3_BLOCK_MBUF_MANAGER, LM_DISABLE);
-       LM_CntrlBlock (pDevice, T3_BLOCK_MEM_ARBITOR, LM_DISABLE);
-
-       MM_ACQUIRE_INT_LOCK (pDevice);
-
-       /* Abort packets that have already queued to go out. */
-       pPacket = (PLM_PACKET) QQ_PopHead (&pDevice->TxPacketActiveQ.Container);
-       while (pPacket) {
-
-               pPacket->PacketStatus = LM_STATUS_TRANSMIT_ABORTED;
-               pDevice->TxCounters.TxPacketAbortedCnt++;
-
-               atomic_add (pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
-
-               QQ_PushTail (&pDevice->TxPacketXmittedQ.Container, pPacket);
-
-               pPacket = (PLM_PACKET)
-                   QQ_PopHead (&pDevice->TxPacketActiveQ.Container);
-       }
-
-       /* Cleanup the receive return rings. */
-       LM_ServiceRxInterrupt (pDevice);
-
-       /* Don't want to indicate rx packets in Ndis miniport shutdown context. */
-       /* Doing so may cause system crash. */
-       if (!pDevice->ShuttingDown) {
-               /* Indicate packets to the protocol. */
-               MM_IndicateTxPackets (pDevice);
-
-               /* Indicate received packets to the protocols. */
-               MM_IndicateRxPackets (pDevice);
-       } else {
-               /* Move the receive packet descriptors in the ReceivedQ to the */
-               /* free queue. */
-               for (;;) {
-                       pPacket =
-                           (PLM_PACKET) QQ_PopHead (&pDevice->
-                                                    RxPacketReceivedQ.
-                                                    Container);
-                       if (pPacket == NULL) {
-                               break;
-                       }
-                       QQ_PushTail (&pDevice->RxPacketFreeQ.Container,
-                                    pPacket);
-               }
-       }
-
-       /* Clean up the Std Receive Producer ring. */
-       Idx = pDevice->pStatusBlkVirt->RcvStdConIdx;
-
-       while (Idx != pDevice->RxStdProdIdx) {
-               pPacket = (PLM_PACKET) (MM_UINT_PTR (pDevice->pPacketDescBase) +
-                                       MM_UINT_PTR (pDevice->pRxStdBdVirt[Idx].
-                                                    Opaque));
-
-               QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
-
-               Idx = (Idx + 1) & T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
-       }                       /* while */
-
-       /* Reinitialize our copy of the indices. */
-       pDevice->RxStdProdIdx = 0;
-
-#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
-       /* Clean up the Jumbo Receive Producer ring. */
-       Idx = pDevice->pStatusBlkVirt->RcvJumboConIdx;
-
-       while (Idx != pDevice->RxJumboProdIdx) {
-               pPacket = (PLM_PACKET) (MM_UINT_PTR (pDevice->pPacketDescBase) +
-                                       MM_UINT_PTR (pDevice->
-                                                    pRxJumboBdVirt[Idx].
-                                                    Opaque));
-
-               QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
-
-               Idx = (Idx + 1) & T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
-       }                       /* while */
-
-       /* Reinitialize our copy of the indices. */
-       pDevice->RxJumboProdIdx = 0;
-#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
-
-       MM_RELEASE_INT_LOCK (pDevice);
-
-       /* Initialize the statistis Block */
-       pDevice->pStatusBlkVirt->Status = 0;
-       pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
-       pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
-       pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
-
-       return LM_STATUS_SUCCESS;
-}                              /* LM_Abort */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*    Disable the interrupt and put the transmitter and receiver engines in   */
-/*    an idle state.  Aborts all pending send requests and receive buffers.   */
-/*    Also free all the receive buffers.                                      */
-/*                                                                            */
-/* Return:                                                                    */
-/*    LM_STATUS_SUCCESS                                                       */
-/******************************************************************************/
-LM_STATUS LM_Halt (PLM_DEVICE_BLOCK pDevice)
-{
-       PLM_PACKET pPacket;
-       LM_UINT32 EntryCnt;
-
-       LM_Abort (pDevice);
-
-       /* Get the number of entries in the queue. */
-       EntryCnt = QQ_GetEntryCnt (&pDevice->RxPacketFreeQ.Container);
-
-       /* Make sure all the packets have been accounted for. */
-       for (EntryCnt = 0; EntryCnt < pDevice->RxPacketDescCnt; EntryCnt++) {
-               pPacket =
-                   (PLM_PACKET) QQ_PopHead (&pDevice->RxPacketFreeQ.Container);
-               if (pPacket == 0)
-                       break;
-
-               MM_FreeRxBuffer (pDevice, pPacket);
-
-               QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
-       }
-
-       LM_ResetChip (pDevice);
-
-       /* Restore PCI configuration registers. */
-       MM_WriteConfig32 (pDevice, PCI_CACHE_LINE_SIZE_REG,
-                         pDevice->SavedCacheLineReg);
-       LM_RegWrInd (pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
-                    (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
-
-       /* Reprogram the MAC address. */
-       LM_SetMacAddress (pDevice, pDevice->NodeAddress);
-
-       return LM_STATUS_SUCCESS;
-}                              /* LM_Halt */
-
-STATIC LM_STATUS LM_ResetChip (PLM_DEVICE_BLOCK pDevice)
-{
-       LM_UINT32 Value32;
-       LM_UINT32 j;
-
-       /* Wait for access to the nvram interface before resetting.  This is */
-       /* a workaround to prevent EEPROM corruption. */
-       if (T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
-           T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5701) {
-               /* Request access to the flash interface. */
-               REG_WR (pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
-
-               for (j = 0; j < 100000; j++) {
-                       Value32 = REG_RD (pDevice, Nvram.SwArb);
-                       if (Value32 & SW_ARB_GNT1) {
-                               break;
-                       }
-                       MM_Wait (10);
-               }
-       }
-
-       /* Global reset. */
-       REG_WR (pDevice, Grc.MiscCfg, GRC_MISC_CFG_CORE_CLOCK_RESET);
-       MM_Wait (40);
-       MM_Wait (40);
-       MM_Wait (40);
-
-       /* make sure we re-enable indirect accesses */
-       MM_WriteConfig32 (pDevice, T3_PCI_MISC_HOST_CTRL_REG,
-                         pDevice->MiscHostCtrl);
-
-       /* Set MAX PCI retry to zero. */
-       Value32 =
-           T3_PCI_STATE_PCI_ROM_ENABLE | T3_PCI_STATE_PCI_ROM_RETRY_ENABLE;
-       if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
-               if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)) {
-                       Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
-               }
-       }
-       MM_WriteConfig32 (pDevice, T3_PCI_STATE_REG, Value32);
-
-       /* Restore PCI command register. */
-       MM_WriteConfig32 (pDevice, PCI_COMMAND_REG,
-                         pDevice->PciCommandStatusWords);
-
-       /* Disable PCI-X relaxed ordering bit. */
-       MM_ReadConfig32 (pDevice, PCIX_CAP_REG, &Value32);
-       Value32 &= ~PCIX_ENABLE_RELAXED_ORDERING;
-       MM_WriteConfig32 (pDevice, PCIX_CAP_REG, Value32);
-
-       /* Enable memory arbiter. */
-       REG_WR (pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
-
-#ifdef BIG_ENDIAN_PCI          /* This from jfd */
-       Value32 = GRC_MODE_WORD_SWAP_DATA | GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
-#else
-#ifdef BIG_ENDIAN_HOST
-       /* Reconfigure the mode register. */
-       Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
-           GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
-           GRC_MODE_BYTE_SWAP_DATA | GRC_MODE_WORD_SWAP_DATA;
-#else
-       /* Reconfigure the mode register. */
-       Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
-#endif
-#endif
-       REG_WR (pDevice, Grc.Mode, Value32);
-
-       /* Prevent PXE from restarting. */
-       MEM_WR_OFFSET (pDevice, 0x0b50, T3_MAGIC_NUM);
-
-       if (pDevice->EnableTbi) {
-               pDevice->MacMode = MAC_MODE_PORT_MODE_TBI;
-               REG_WR (pDevice, MacCtrl.Mode, MAC_MODE_PORT_MODE_TBI);
-       } else {
-               REG_WR (pDevice, MacCtrl.Mode, 0);
-       }
-
-       /* Wait for the firmware to finish initialization. */
-       for (j = 0; j < 100000; j++) {
-               MM_Wait (10);
-
-               Value32 = MEM_RD_OFFSET (pDevice, 0x0b50);
-               if (Value32 == ~T3_MAGIC_NUM) {
-                       break;
-               }
-       }
-       return LM_STATUS_SUCCESS;
-}
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-__inline static void LM_ServiceTxInterrupt (PLM_DEVICE_BLOCK pDevice)
-{
-       PLM_PACKET pPacket;
-       LM_UINT32 HwConIdx;
-       LM_UINT32 SwConIdx;
-
-       HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
-
-       /* Get our copy of the consumer index.  The buffer descriptors */
-       /* that are in between the consumer indices are freed. */
-       SwConIdx = pDevice->SendConIdx;
-
-       /* Move the packets from the TxPacketActiveQ that are sent out to */
-       /* the TxPacketXmittedQ.  Packets that are sent use the */
-       /* descriptors that are between SwConIdx and HwConIdx. */
-       while (SwConIdx != HwConIdx) {
-               /* Get the packet that was sent from the TxPacketActiveQ. */
-               pPacket =
-                   (PLM_PACKET) QQ_PopHead (&pDevice->TxPacketActiveQ.
-                                            Container);
-
-               /* Set the return status. */
-               pPacket->PacketStatus = LM_STATUS_SUCCESS;
-
-               /* Put the packet in the TxPacketXmittedQ for indication later. */
-               QQ_PushTail (&pDevice->TxPacketXmittedQ.Container, pPacket);
-
-               /* Move to the next packet's BD. */
-               SwConIdx = (SwConIdx + pPacket->u.Tx.FragCount) &
-                   T3_SEND_RCB_ENTRY_COUNT_MASK;
-
-               /* Update the number of unused BDs. */
-               atomic_add (pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
-
-               /* Get the new updated HwConIdx. */
-               HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
-       }                       /* while */
-
-       /* Save the new SwConIdx. */
-       pDevice->SendConIdx = SwConIdx;
-
-}                              /* LM_ServiceTxInterrupt */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-__inline static void LM_ServiceRxInterrupt (PLM_DEVICE_BLOCK pDevice)
-{
-       PLM_PACKET pPacket;
-       PT3_RCV_BD pRcvBd;
-       LM_UINT32 HwRcvRetProdIdx;
-       LM_UINT32 SwRcvRetConIdx;
-
-       /* Loop thru the receive return rings for received packets. */
-       HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
-
-       SwRcvRetConIdx = pDevice->RcvRetConIdx;
-       while (SwRcvRetConIdx != HwRcvRetProdIdx) {
-               pRcvBd = &pDevice->pRcvRetBdVirt[SwRcvRetConIdx];
-
-               /* Get the received packet descriptor. */
-               pPacket = (PLM_PACKET) (MM_UINT_PTR (pDevice->pPacketDescBase) +
-                                       MM_UINT_PTR (pRcvBd->Opaque));
-
-               /* Check the error flag. */
-               if (pRcvBd->ErrorFlag &&
-                   pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII) {
-                       pPacket->PacketStatus = LM_STATUS_FAILURE;
-
-                       pDevice->RxCounters.RxPacketErrCnt++;
-
-                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_BAD_CRC) {
-                               pDevice->RxCounters.RxErrCrcCnt++;
-                       }
-
-                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_COLL_DETECT) {
-                               pDevice->RxCounters.RxErrCollCnt++;
-                       }
-
-                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_LINK_LOST_DURING_PKT) {
-                               pDevice->RxCounters.RxErrLinkLostCnt++;
-                       }
-
-                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_PHY_DECODE_ERR) {
-                               pDevice->RxCounters.RxErrPhyDecodeCnt++;
-                       }
-
-                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_ODD_NIBBLED_RCVD_MII) {
-                               pDevice->RxCounters.RxErrOddNibbleCnt++;
-                       }
-
-                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_MAC_ABORT) {
-                               pDevice->RxCounters.RxErrMacAbortCnt++;
-                       }
-
-                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_LEN_LT_64) {
-                               pDevice->RxCounters.RxErrShortPacketCnt++;
-                       }
-
-                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_TRUNC_NO_RESOURCES) {
-                               pDevice->RxCounters.RxErrNoResourceCnt++;
-                       }
-
-                       if (pRcvBd->ErrorFlag & RCV_BD_ERR_GIANT_FRAME_RCVD) {
-                               pDevice->RxCounters.RxErrLargePacketCnt++;
-                       }
-               } else {
-                       pPacket->PacketStatus = LM_STATUS_SUCCESS;
-                       pPacket->PacketSize = pRcvBd->Len - 4;
-
-                       pPacket->Flags = pRcvBd->Flags;
-                       if (pRcvBd->Flags & RCV_BD_FLAG_VLAN_TAG) {
-                               pPacket->VlanTag = pRcvBd->VlanTag;
-                       }
-
-                       pPacket->u.Rx.TcpUdpChecksum = pRcvBd->TcpUdpCksum;
-               }
-
-               /* Put the packet descriptor containing the received packet */
-               /* buffer in the RxPacketReceivedQ for indication later. */
-               QQ_PushTail (&pDevice->RxPacketReceivedQ.Container, pPacket);
-
-               /* Go to the next buffer descriptor. */
-               SwRcvRetConIdx = (SwRcvRetConIdx + 1) &
-                   T3_RCV_RETURN_RCB_ENTRY_COUNT_MASK;
-
-               /* Get the updated HwRcvRetProdIdx. */
-               HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
-       }                       /* while */
-
-       pDevice->RcvRetConIdx = SwRcvRetConIdx;
-
-       /* Update the receive return ring consumer index. */
-       MB_REG_WR (pDevice, Mailbox.RcvRetConIdx[0].Low, SwRcvRetConIdx);
-}                              /* LM_ServiceRxInterrupt */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*    This is the interrupt event handler routine. It acknowledges all        */
-/*    pending interrupts and process all pending events.                      */
-/*                                                                            */
-/* Return:                                                                    */
-/*    LM_STATUS_SUCCESS                                                       */
-/******************************************************************************/
-LM_STATUS LM_ServiceInterrupts (PLM_DEVICE_BLOCK pDevice)
-{
-       LM_UINT32 Value32;
-       int ServicePhyInt = FALSE;
-
-       /* Setup the phy chip whenever the link status changes. */
-       if (pDevice->LinkChngMode == T3_LINK_CHNG_MODE_USE_STATUS_REG) {
-               Value32 = REG_RD (pDevice, MacCtrl.Status);
-               if (pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT) {
-                       if (Value32 & MAC_STATUS_MI_INTERRUPT) {
-                               ServicePhyInt = TRUE;
-                       }
-               } else if (Value32 & MAC_STATUS_LINK_STATE_CHANGED) {
-                       ServicePhyInt = TRUE;
-               }
-       } else {
-               if (pDevice->pStatusBlkVirt->
-                   Status & STATUS_BLOCK_LINK_CHANGED_STATUS) {
-                       pDevice->pStatusBlkVirt->Status =
-                           STATUS_BLOCK_UPDATED | (pDevice->pStatusBlkVirt->
-                                                   Status &
-                                                   ~STATUS_BLOCK_LINK_CHANGED_STATUS);
-                       ServicePhyInt = TRUE;
-               }
-       }
-#if INCLUDE_TBI_SUPPORT
-       if (pDevice->IgnoreTbiLinkChange == TRUE) {
-               ServicePhyInt = FALSE;
-       }
-#endif
-       if (ServicePhyInt == TRUE) {
-               LM_SetupPhy (pDevice);
-       }
-
-       /* Service receive and transmit interrupts. */
-       LM_ServiceRxInterrupt (pDevice);
-       LM_ServiceTxInterrupt (pDevice);
-
-       /* No spinlock for this queue since this routine is serialized. */
-       if (!QQ_Empty (&pDevice->RxPacketReceivedQ.Container)) {
-               /* Indicate receive packets. */
-               MM_IndicateRxPackets (pDevice);
-               /*       LM_QueueRxPackets(pDevice); */
-       }
-
-       /* No spinlock for this queue since this routine is serialized. */
-       if (!QQ_Empty (&pDevice->TxPacketXmittedQ.Container)) {
-               MM_IndicateTxPackets (pDevice);
-       }
-
-       return LM_STATUS_SUCCESS;
-}                              /* LM_ServiceInterrupts */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-LM_STATUS LM_MulticastAdd (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress)
-{
-       PLM_UINT8 pEntry;
-       LM_UINT32 j;
-
-       pEntry = pDevice->McTable[0];
-       for (j = 0; j < pDevice->McEntryCount; j++) {
-               if (IS_ETH_ADDRESS_EQUAL (pEntry, pMcAddress)) {
-                       /* Found a match, increment the instance count. */
-                       pEntry[LM_MC_INSTANCE_COUNT_INDEX] += 1;
-
-                       return LM_STATUS_SUCCESS;
-               }
-
-               pEntry += LM_MC_ENTRY_SIZE;
-       }
-
-       if (pDevice->McEntryCount >= LM_MAX_MC_TABLE_SIZE) {
-               return LM_STATUS_FAILURE;
-       }
-
-       pEntry = pDevice->McTable[pDevice->McEntryCount];
-
-       COPY_ETH_ADDRESS (pMcAddress, pEntry);
-       pEntry[LM_MC_INSTANCE_COUNT_INDEX] = 1;
-
-       pDevice->McEntryCount++;
-
-       LM_SetReceiveMask (pDevice, pDevice->ReceiveMask | LM_ACCEPT_MULTICAST);
-
-       return LM_STATUS_SUCCESS;
-}                              /* LM_MulticastAdd */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-LM_STATUS LM_MulticastDel (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress)
-{
-       PLM_UINT8 pEntry;
-       LM_UINT32 j;
-
-       pEntry = pDevice->McTable[0];
-       for (j = 0; j < pDevice->McEntryCount; j++) {
-               if (IS_ETH_ADDRESS_EQUAL (pEntry, pMcAddress)) {
-                       /* Found a match, decrement the instance count. */
-                       pEntry[LM_MC_INSTANCE_COUNT_INDEX] -= 1;
-
-                       /* No more instance left, remove the address from the table. */
-                       /* Move the last entry in the table to the delete slot. */
-                       if (pEntry[LM_MC_INSTANCE_COUNT_INDEX] == 0 &&
-                           pDevice->McEntryCount > 1) {
-
-                               COPY_ETH_ADDRESS (pDevice->
-                                                 McTable[pDevice->
-                                                         McEntryCount - 1],
-                                                 pEntry);
-                               pEntry[LM_MC_INSTANCE_COUNT_INDEX] =
-                                   pDevice->McTable[pDevice->McEntryCount - 1]
-                                   [LM_MC_INSTANCE_COUNT_INDEX];
-                       }
-                       pDevice->McEntryCount--;
-
-                       /* Update the receive mask if the table is empty. */
-                       if (pDevice->McEntryCount == 0) {
-                               LM_SetReceiveMask (pDevice,
-                                                  pDevice->
-                                                  ReceiveMask &
-                                                  ~LM_ACCEPT_MULTICAST);
-                       }
-
-                       return LM_STATUS_SUCCESS;
-               }
-
-               pEntry += LM_MC_ENTRY_SIZE;
-       }
-
-       return LM_STATUS_FAILURE;
-}                              /* LM_MulticastDel */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-LM_STATUS LM_MulticastClear (PLM_DEVICE_BLOCK pDevice)
-{
-       pDevice->McEntryCount = 0;
-
-       LM_SetReceiveMask (pDevice,
-                          pDevice->ReceiveMask & ~LM_ACCEPT_MULTICAST);
-
-       return LM_STATUS_SUCCESS;
-}                              /* LM_MulticastClear */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-LM_STATUS LM_SetMacAddress (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMacAddress)
-{
-       LM_UINT32 j;
-
-       for (j = 0; j < 4; j++) {
-               REG_WR (pDevice, MacCtrl.MacAddr[j].High,
-                       (pMacAddress[0] << 8) | pMacAddress[1]);
-               REG_WR (pDevice, MacCtrl.MacAddr[j].Low,
-                       (pMacAddress[2] << 24) | (pMacAddress[3] << 16) |
-                       (pMacAddress[4] << 8) | pMacAddress[5]);
-       }
-
-       return LM_STATUS_SUCCESS;
-}
-
-/******************************************************************************/
-/* Description:                                                               */
-/*    Sets up the default line speed, and duplex modes based on the requested */
-/*    media type.                                                             */
-/*                                                                            */
-/* Return:                                                                    */
-/*    None.                                                                   */
-/******************************************************************************/
-static LM_STATUS
-LM_TranslateRequestedMediaType (LM_REQUESTED_MEDIA_TYPE RequestedMediaType,
-                               PLM_MEDIA_TYPE pMediaType,
-                               PLM_LINE_SPEED pLineSpeed,
-                               PLM_DUPLEX_MODE pDuplexMode)
-{
-       *pMediaType = LM_MEDIA_TYPE_AUTO;
-       *pLineSpeed = LM_LINE_SPEED_UNKNOWN;
-       *pDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
-
-       /* determine media type */
-       switch (RequestedMediaType) {
-       case LM_REQUESTED_MEDIA_TYPE_BNC:
-               *pMediaType = LM_MEDIA_TYPE_BNC;
-               *pLineSpeed = LM_LINE_SPEED_10MBPS;
-               *pDuplexMode = LM_DUPLEX_MODE_HALF;
-               break;
-
-       case LM_REQUESTED_MEDIA_TYPE_UTP_AUTO:
-               *pMediaType = LM_MEDIA_TYPE_UTP;
-               break;
-
-       case LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS:
-               *pMediaType = LM_MEDIA_TYPE_UTP;
-               *pLineSpeed = LM_LINE_SPEED_10MBPS;
-               *pDuplexMode = LM_DUPLEX_MODE_HALF;
-               break;
-
-       case LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS_FULL_DUPLEX:
-               *pMediaType = LM_MEDIA_TYPE_UTP;
-               *pLineSpeed = LM_LINE_SPEED_10MBPS;
-               *pDuplexMode = LM_DUPLEX_MODE_FULL;
-               break;
-
-       case LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS:
-               *pMediaType = LM_MEDIA_TYPE_UTP;
-               *pLineSpeed = LM_LINE_SPEED_100MBPS;
-               *pDuplexMode = LM_DUPLEX_MODE_HALF;
-               break;
-
-       case LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS_FULL_DUPLEX:
-               *pMediaType = LM_MEDIA_TYPE_UTP;
-               *pLineSpeed = LM_LINE_SPEED_100MBPS;
-               *pDuplexMode = LM_DUPLEX_MODE_FULL;
-               break;
-
-       case LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS:
-               *pMediaType = LM_MEDIA_TYPE_UTP;
-               *pLineSpeed = LM_LINE_SPEED_1000MBPS;
-               *pDuplexMode = LM_DUPLEX_MODE_HALF;
-               break;
-
-       case LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS_FULL_DUPLEX:
-               *pMediaType = LM_MEDIA_TYPE_UTP;
-               *pLineSpeed = LM_LINE_SPEED_1000MBPS;
-               *pDuplexMode = LM_DUPLEX_MODE_FULL;
-               break;
-
-       case LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS:
-               *pMediaType = LM_MEDIA_TYPE_FIBER;
-               *pLineSpeed = LM_LINE_SPEED_100MBPS;
-               *pDuplexMode = LM_DUPLEX_MODE_HALF;
-               break;
-
-       case LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS_FULL_DUPLEX:
-               *pMediaType = LM_MEDIA_TYPE_FIBER;
-               *pLineSpeed = LM_LINE_SPEED_100MBPS;
-               *pDuplexMode = LM_DUPLEX_MODE_FULL;
-               break;
-
-       case LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS:
-               *pMediaType = LM_MEDIA_TYPE_FIBER;
-               *pLineSpeed = LM_LINE_SPEED_1000MBPS;
-               *pDuplexMode = LM_DUPLEX_MODE_HALF;
-               break;
-
-       case LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS_FULL_DUPLEX:
-               *pMediaType = LM_MEDIA_TYPE_FIBER;
-               *pLineSpeed = LM_LINE_SPEED_1000MBPS;
-               *pDuplexMode = LM_DUPLEX_MODE_FULL;
-               break;
-
-       default:
-               break;
-       }                       /* switch */
-
-       return LM_STATUS_SUCCESS;
-}                              /* LM_TranslateRequestedMediaType */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/*    LM_STATUS_LINK_ACTIVE                                                   */
-/*    LM_STATUS_LINK_DOWN                                                     */
-/******************************************************************************/
-static LM_STATUS LM_InitBcm540xPhy (PLM_DEVICE_BLOCK pDevice)
-{
-       LM_LINE_SPEED CurrentLineSpeed;
-       LM_DUPLEX_MODE CurrentDuplexMode;
-       LM_STATUS CurrentLinkStatus;
-       LM_UINT32 Value32;
-       LM_UINT32 j;
-
-#if 1                          /* jmb: bugfix -- moved here, out of code that sets initial pwr state */
-       LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x2);
-#endif
-       if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID) {
-               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
-               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
-
-               if (!pDevice->InitDone) {
-                       Value32 = 0;
-               }
-
-               if (!(Value32 & PHY_STATUS_LINK_PASS)) {
-                       LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x0c20);
-
-                       LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
-                       LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x1804);
-
-                       LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
-                       LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x1204);
-
-                       LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
-                       LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0132);
-
-                       LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
-                       LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0232);
-
-                       LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
-                       LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
-
-                       LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
-                       for (j = 0; j < 1000; j++) {
-                               MM_Wait (10);
-
-                               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
-                               if (Value32 & PHY_STATUS_LINK_PASS) {
-                                       MM_Wait (40);
-                                       break;
-                               }
-                       }
-
-                       if ((pDevice->PhyId & PHY_ID_REV_MASK) ==
-                           PHY_BCM5401_B0_REV) {
-                               if (!(Value32 & PHY_STATUS_LINK_PASS)
-                                   && (pDevice->OldLineSpeed ==
-                                       LM_LINE_SPEED_1000MBPS)) {
-                                       LM_WritePhy (pDevice, PHY_CTRL_REG,
-                                                    PHY_CTRL_PHY_RESET);
-                                       for (j = 0; j < 100; j++) {
-                                               MM_Wait (10);
-
-                                               LM_ReadPhy (pDevice,
-                                                           PHY_CTRL_REG,
-                                                           &Value32);
-                                               if (!
-                                                   (Value32 &
-                                                    PHY_CTRL_PHY_RESET)) {
-                                                       MM_Wait (40);
-                                                       break;
-                                               }
-                                       }
-
-                                       LM_WritePhy (pDevice, BCM5401_AUX_CTRL,
-                                                    0x0c20);
-
-                                       LM_WritePhy (pDevice,
-                                                    BCM540X_DSP_ADDRESS_REG,
-                                                    0x0012);
-                                       LM_WritePhy (pDevice,
-                                                    BCM540X_DSP_RW_PORT,
-                                                    0x1804);
-
-                                       LM_WritePhy (pDevice,
-                                                    BCM540X_DSP_ADDRESS_REG,
-                                                    0x0013);
-                                       LM_WritePhy (pDevice,
-                                                    BCM540X_DSP_RW_PORT,
-                                                    0x1204);
-
-                                       LM_WritePhy (pDevice,
-                                                    BCM540X_DSP_ADDRESS_REG,
-                                                    0x8006);
-                                       LM_WritePhy (pDevice,
-                                                    BCM540X_DSP_RW_PORT,
-                                                    0x0132);
-
-                                       LM_WritePhy (pDevice,
-                                                    BCM540X_DSP_ADDRESS_REG,
-                                                    0x8006);
-                                       LM_WritePhy (pDevice,
-                                                    BCM540X_DSP_RW_PORT,
-                                                    0x0232);
-
-                                       LM_WritePhy (pDevice,
-                                                    BCM540X_DSP_ADDRESS_REG,
-                                                    0x201f);
-                                       LM_WritePhy (pDevice,
-                                                    BCM540X_DSP_RW_PORT,
-                                                    0x0a20);
-                               }
-                       }
-               }
-       } else if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
-                  pDevice->ChipRevId == T3_CHIP_ID_5701_B0) {
-               /* Bug: 5701 A0, B0 TX CRC workaround. */
-               LM_WritePhy (pDevice, 0x15, 0x0a75);
-               LM_WritePhy (pDevice, 0x1c, 0x8c68);
-               LM_WritePhy (pDevice, 0x1c, 0x8d68);
-               LM_WritePhy (pDevice, 0x1c, 0x8c68);
-       }
-
-       /* Acknowledge interrupts. */
-       LM_ReadPhy (pDevice, BCM540X_INT_STATUS_REG, &Value32);
-       LM_ReadPhy (pDevice, BCM540X_INT_STATUS_REG, &Value32);
-
-       /* Configure the interrupt mask. */
-       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT) {
-               LM_WritePhy (pDevice, BCM540X_INT_MASK_REG,
-                            ~BCM540X_INT_LINK_CHANGE);
-       }
-
-       /* Configure PHY led mode. */
-       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
-           (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700)) {
-               if (pDevice->LedMode == LED_MODE_THREE_LINK) {
-                       LM_WritePhy (pDevice, BCM540X_EXT_CTRL_REG,
-                                    BCM540X_EXT_CTRL_LINK3_LED_MODE);
-               } else {
-                       LM_WritePhy (pDevice, BCM540X_EXT_CTRL_REG, 0);
-               }
-       }
-
-       CurrentLinkStatus = LM_STATUS_LINK_DOWN;
-
-       /* Get current link and duplex mode. */
-       for (j = 0; j < 100; j++) {
-               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
-               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
-
-               if (Value32 & PHY_STATUS_LINK_PASS) {
-                       break;
-               }
-               MM_Wait (40);
-       }
-
-       if (Value32 & PHY_STATUS_LINK_PASS) {
-
-               /* Determine the current line and duplex settings. */
-               LM_ReadPhy (pDevice, BCM540X_AUX_STATUS_REG, &Value32);
-               for (j = 0; j < 2000; j++) {
-                       MM_Wait (10);
-
-                       LM_ReadPhy (pDevice, BCM540X_AUX_STATUS_REG, &Value32);
-                       if (Value32) {
-                               break;
-                       }
-               }
-
-               switch (Value32 & BCM540X_AUX_SPEED_MASK) {
-               case BCM540X_AUX_10BASET_HD:
-                       CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
-                       CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
-                       break;
-
-               case BCM540X_AUX_10BASET_FD:
-                       CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
-                       CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
-                       break;
-
-               case BCM540X_AUX_100BASETX_HD:
-                       CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
-                       CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
-                       break;
-
-               case BCM540X_AUX_100BASETX_FD:
-                       CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
-                       CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
-                       break;
-
-               case BCM540X_AUX_100BASET_HD:
-                       CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
-                       CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
-                       break;
-
-               case BCM540X_AUX_100BASET_FD:
-                       CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
-                       CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
-                       break;
-
-               default:
-
-                       CurrentLineSpeed = LM_LINE_SPEED_UNKNOWN;
-                       CurrentDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
-                       break;
-               }
-
-               /* Make sure we are in auto-neg mode. */
-               for (j = 0; j < 200; j++) {
-                       LM_ReadPhy (pDevice, PHY_CTRL_REG, &Value32);
-                       if (Value32 && Value32 != 0x7fff) {
-                               break;
-                       }
-
-                       if (Value32 == 0 && pDevice->RequestedMediaType ==
-                           LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS) {
-                               break;
-                       }
-
-                       MM_Wait (10);
-               }
-
-               /* Use the current line settings for "auto" mode. */
-               if (pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO
-                   || pDevice->RequestedMediaType ==
-                   LM_REQUESTED_MEDIA_TYPE_UTP_AUTO) {
-                       if (Value32 & PHY_CTRL_AUTO_NEG_ENABLE) {
-                               CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
-
-                               /* We may be exiting low power mode and the link is in */
-                               /* 10mb.  In this case, we need to restart autoneg. */
-                               LM_ReadPhy (pDevice, BCM540X_1000BASET_CTRL_REG,
-                                           &Value32);
-                               pDevice->advertising1000 = Value32;
-                               /* 5702FE supports 10/100Mb only. */
-                               if (T3_ASIC_REV (pDevice->ChipRevId) !=
-                                   T3_ASIC_REV_5703
-                                   || pDevice->BondId !=
-                                   GRC_MISC_BD_ID_5702FE) {
-                                       if (!
-                                           (Value32 &
-                                            (BCM540X_AN_AD_1000BASET_HALF |
-                                             BCM540X_AN_AD_1000BASET_FULL))) {
-                                               CurrentLinkStatus =
-                                                   LM_STATUS_LINK_SETTING_MISMATCH;
-                                       }
-                               }
-                       } else {
-                               CurrentLinkStatus =
-                                   LM_STATUS_LINK_SETTING_MISMATCH;
-                       }
-               } else {
-                       /* Force line settings. */
-                       /* Use the current setting if it matches the user's requested */
-                       /* setting. */
-                       LM_ReadPhy (pDevice, PHY_CTRL_REG, &Value32);
-                       if ((pDevice->LineSpeed == CurrentLineSpeed) &&
-                           (pDevice->DuplexMode == CurrentDuplexMode)) {
-                               if ((pDevice->DisableAutoNeg &&
-                                    !(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)) ||
-                                   (!pDevice->DisableAutoNeg &&
-                                    (Value32 & PHY_CTRL_AUTO_NEG_ENABLE))) {
-                                       CurrentLinkStatus =
-                                           LM_STATUS_LINK_ACTIVE;
-                               } else {
-                                       CurrentLinkStatus =
-                                           LM_STATUS_LINK_SETTING_MISMATCH;
-                               }
-                       } else {
-                               CurrentLinkStatus =
-                                   LM_STATUS_LINK_SETTING_MISMATCH;
-                       }
-               }
-
-               /* Save line settings. */
-               pDevice->LineSpeed = CurrentLineSpeed;
-               pDevice->DuplexMode = CurrentDuplexMode;
-               pDevice->MediaType = LM_MEDIA_TYPE_UTP;
-       }
-
-       return CurrentLinkStatus;
-}                              /* LM_InitBcm540xPhy */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-LM_STATUS
-LM_SetFlowControl (PLM_DEVICE_BLOCK pDevice,
-                  LM_UINT32 LocalPhyAd, LM_UINT32 RemotePhyAd)
-{
-       LM_FLOW_CONTROL FlowCap;
-
-       /* Resolve flow control. */
-       FlowCap = LM_FLOW_CONTROL_NONE;
-
-       /* See Table 28B-3 of 802.3ab-1999 spec. */
-       if (pDevice->FlowControlCap & LM_FLOW_CONTROL_AUTO_PAUSE) {
-               if (LocalPhyAd & PHY_AN_AD_PAUSE_CAPABLE) {
-                       if (LocalPhyAd & PHY_AN_AD_ASYM_PAUSE) {
-                               if (RemotePhyAd &
-                                   PHY_LINK_PARTNER_PAUSE_CAPABLE) {
-                                       FlowCap =
-                                           LM_FLOW_CONTROL_TRANSMIT_PAUSE |
-                                           LM_FLOW_CONTROL_RECEIVE_PAUSE;
-                               } else if (RemotePhyAd &
-                                          PHY_LINK_PARTNER_ASYM_PAUSE) {
-                                       FlowCap = LM_FLOW_CONTROL_RECEIVE_PAUSE;
-                               }
-                       } else {
-                               if (RemotePhyAd &
-                                   PHY_LINK_PARTNER_PAUSE_CAPABLE) {
-                                       FlowCap =
-                                           LM_FLOW_CONTROL_TRANSMIT_PAUSE |
-                                           LM_FLOW_CONTROL_RECEIVE_PAUSE;
-                               }
-                       }
-               } else if (LocalPhyAd & PHY_AN_AD_ASYM_PAUSE) {
-                       if ((RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE) &&
-                           (RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE)) {
-                               FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE;
-                       }
-               }
-       } else {
-               FlowCap = pDevice->FlowControlCap;
-       }
-
-       /* Enable/disable rx PAUSE. */
-       pDevice->RxMode &= ~RX_MODE_ENABLE_FLOW_CONTROL;
-       if (FlowCap & LM_FLOW_CONTROL_RECEIVE_PAUSE &&
-           (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
-            pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)) {
-               pDevice->FlowControl |= LM_FLOW_CONTROL_RECEIVE_PAUSE;
-               pDevice->RxMode |= RX_MODE_ENABLE_FLOW_CONTROL;
-
-       }
-       REG_WR (pDevice, MacCtrl.RxMode, pDevice->RxMode);
-
-       /* Enable/disable tx PAUSE. */
-       pDevice->TxMode &= ~TX_MODE_ENABLE_FLOW_CONTROL;
-       if (FlowCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE &&
-           (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
-            pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)) {
-               pDevice->FlowControl |= LM_FLOW_CONTROL_TRANSMIT_PAUSE;
-               pDevice->TxMode |= TX_MODE_ENABLE_FLOW_CONTROL;
-
-       }
-       REG_WR (pDevice, MacCtrl.TxMode, pDevice->TxMode);
-
-       return LM_STATUS_SUCCESS;
-}
-
-#if INCLUDE_TBI_SUPPORT
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-STATIC LM_STATUS LM_InitBcm800xPhy (PLM_DEVICE_BLOCK pDevice)
-{
-       LM_UINT32 Value32;
-       LM_UINT32 j;
-
-       Value32 = REG_RD (pDevice, MacCtrl.Status);
-
-       /* Reset the SERDES during init and when we have link. */
-       if (!pDevice->InitDone || Value32 & MAC_STATUS_PCS_SYNCED) {
-               /* Set PLL lock range. */
-               LM_WritePhy (pDevice, 0x16, 0x8007);
-
-               /* Software reset. */
-               LM_WritePhy (pDevice, 0x00, 0x8000);
-
-               /* Wait for reset to complete. */
-               for (j = 0; j < 500; j++) {
-                       MM_Wait (10);
-               }
-
-               /* Config mode; seletct PMA/Ch 1 regs. */
-               LM_WritePhy (pDevice, 0x10, 0x8411);
-
-               /* Enable auto-lock and comdet, select txclk for tx. */
-               LM_WritePhy (pDevice, 0x11, 0x0a10);
-
-               LM_WritePhy (pDevice, 0x18, 0x00a0);
-               LM_WritePhy (pDevice, 0x16, 0x41ff);
-
-               /* Assert and deassert POR. */
-               LM_WritePhy (pDevice, 0x13, 0x0400);
-               MM_Wait (40);
-               LM_WritePhy (pDevice, 0x13, 0x0000);
-
-               LM_WritePhy (pDevice, 0x11, 0x0a50);
-               MM_Wait (40);
-               LM_WritePhy (pDevice, 0x11, 0x0a10);
-
-               /* Delay for signal to stabilize. */
-               for (j = 0; j < 15000; j++) {
-                       MM_Wait (10);
-               }
-
-               /* Deselect the channel register so we can read the PHY id later. */
-               LM_WritePhy (pDevice, 0x10, 0x8011);
-       }
-
-       return LM_STATUS_SUCCESS;
-}
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-STATIC LM_STATUS LM_SetupFiberPhy (PLM_DEVICE_BLOCK pDevice)
-{
-       LM_STATUS CurrentLinkStatus;
-       AUTONEG_STATUS AnStatus = 0;
-       LM_UINT32 Value32;
-       LM_UINT32 Cnt;
-       LM_UINT32 j, k;
-
-       pDevice->MacMode &= ~(MAC_MODE_HALF_DUPLEX | MAC_MODE_PORT_MODE_MASK);
-
-       /* Initialize the send_config register. */
-       REG_WR (pDevice, MacCtrl.TxAutoNeg, 0);
-
-       /* Enable TBI and full duplex mode. */
-       pDevice->MacMode |= MAC_MODE_PORT_MODE_TBI;
-       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
-
-       /* Initialize the BCM8002 SERDES PHY. */
-       switch (pDevice->PhyId & PHY_ID_MASK) {
-       case PHY_BCM8002_PHY_ID:
-               LM_InitBcm800xPhy (pDevice);
-               break;
-
-       default:
-               break;
-       }
-
-       /* Enable link change interrupt. */
-       REG_WR (pDevice, MacCtrl.MacEvent,
-               MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
-
-       /* Default to link down. */
-       CurrentLinkStatus = LM_STATUS_LINK_DOWN;
-
-       /* Get the link status. */
-       Value32 = REG_RD (pDevice, MacCtrl.Status);
-       if (Value32 & MAC_STATUS_PCS_SYNCED) {
-               if ((pDevice->RequestedMediaType ==
-                    LM_REQUESTED_MEDIA_TYPE_AUTO)
-                   || (pDevice->DisableAutoNeg == FALSE)) {
-                       /* auto-negotiation mode. */
-                       /* Initialize the autoneg default capaiblities. */
-                       AutonegInit (&pDevice->AnInfo);
-
-                       /* Set the context pointer to point to the main device structure. */
-                       pDevice->AnInfo.pContext = pDevice;
-
-                       /* Setup flow control advertisement register. */
-                       Value32 = GetPhyAdFlowCntrlSettings (pDevice);
-                       if (Value32 & PHY_AN_AD_PAUSE_CAPABLE) {
-                               pDevice->AnInfo.mr_adv_sym_pause = 1;
-                       } else {
-                               pDevice->AnInfo.mr_adv_sym_pause = 0;
-                       }
-
-                       if (Value32 & PHY_AN_AD_ASYM_PAUSE) {
-                               pDevice->AnInfo.mr_adv_asym_pause = 1;
-                       } else {
-                               pDevice->AnInfo.mr_adv_asym_pause = 0;
-                       }
-
-                       /* Try to autoneg up to six times. */
-                       if (pDevice->IgnoreTbiLinkChange) {
-                               Cnt = 1;
-                       } else {
-                               Cnt = 6;
-                       }
-                       for (j = 0; j < Cnt; j++) {
-                               REG_WR (pDevice, MacCtrl.TxAutoNeg, 0);
-
-                               Value32 =
-                                   pDevice->MacMode & ~MAC_MODE_PORT_MODE_MASK;
-                               REG_WR (pDevice, MacCtrl.Mode, Value32);
-                               MM_Wait (20);
-
-                               REG_WR (pDevice, MacCtrl.Mode,
-                                       pDevice->
-                                       MacMode | MAC_MODE_SEND_CONFIGS);
-
-                               MM_Wait (20);
-
-                               pDevice->AnInfo.State = AN_STATE_UNKNOWN;
-                               pDevice->AnInfo.CurrentTime_us = 0;
-
-                               REG_WR (pDevice, Grc.Timer, 0);
-                               for (k = 0;
-                                    (pDevice->AnInfo.CurrentTime_us < 75000)
-                                    && (k < 75000); k++) {
-                                       AnStatus =
-                                           Autoneg8023z (&pDevice->AnInfo);
-
-                                       if ((AnStatus == AUTONEG_STATUS_DONE) ||
-                                           (AnStatus == AUTONEG_STATUS_FAILED))
-                                       {
-                                               break;
-                                       }
-
-                                       pDevice->AnInfo.CurrentTime_us =
-                                           REG_RD (pDevice, Grc.Timer);
-
-                               }
-                               if ((AnStatus == AUTONEG_STATUS_DONE) ||
-                                   (AnStatus == AUTONEG_STATUS_FAILED)) {
-                                       break;
-                               }
-                               if (j >= 1) {
-                                       if (!(REG_RD (pDevice, MacCtrl.Status) &
-                                             MAC_STATUS_PCS_SYNCED)) {
-                                               break;
-                                       }
-                               }
-                       }
-
-                       /* Stop sending configs. */
-                       MM_AnTxIdle (&pDevice->AnInfo);
-
-                       /* Resolve flow control settings. */
-                       if ((AnStatus == AUTONEG_STATUS_DONE) &&
-                           pDevice->AnInfo.mr_an_complete
-                           && pDevice->AnInfo.mr_link_ok
-                           && pDevice->AnInfo.mr_lp_adv_full_duplex) {
-                               LM_UINT32 RemotePhyAd;
-                               LM_UINT32 LocalPhyAd;
-
-                               LocalPhyAd = 0;
-                               if (pDevice->AnInfo.mr_adv_sym_pause) {
-                                       LocalPhyAd |= PHY_AN_AD_PAUSE_CAPABLE;
-                               }
-
-                               if (pDevice->AnInfo.mr_adv_asym_pause) {
-                                       LocalPhyAd |= PHY_AN_AD_ASYM_PAUSE;
-                               }
-
-                               RemotePhyAd = 0;
-                               if (pDevice->AnInfo.mr_lp_adv_sym_pause) {
-                                       RemotePhyAd |=
-                                           PHY_LINK_PARTNER_PAUSE_CAPABLE;
-                               }
-
-                               if (pDevice->AnInfo.mr_lp_adv_asym_pause) {
-                                       RemotePhyAd |=
-                                           PHY_LINK_PARTNER_ASYM_PAUSE;
-                               }
-
-                               LM_SetFlowControl (pDevice, LocalPhyAd,
-                                                  RemotePhyAd);
-
-                               CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
-                       }
-                       for (j = 0; j < 30; j++) {
-                               MM_Wait (20);
-                               REG_WR (pDevice, MacCtrl.Status,
-                                       MAC_STATUS_SYNC_CHANGED |
-                                       MAC_STATUS_CFG_CHANGED);
-                               MM_Wait (20);
-                               if ((REG_RD (pDevice, MacCtrl.Status) &
-                                    (MAC_STATUS_SYNC_CHANGED |
-                                     MAC_STATUS_CFG_CHANGED)) == 0)
-                                       break;
-                       }
-                       if (pDevice->PollTbiLink) {
-                               Value32 = REG_RD (pDevice, MacCtrl.Status);
-                               if (Value32 & MAC_STATUS_RECEIVING_CFG) {
-                                       pDevice->IgnoreTbiLinkChange = TRUE;
-                               } else {
-                                       pDevice->IgnoreTbiLinkChange = FALSE;
-                               }
-                       }
-                       Value32 = REG_RD (pDevice, MacCtrl.Status);
-                       if (CurrentLinkStatus == LM_STATUS_LINK_DOWN &&
-                           (Value32 & MAC_STATUS_PCS_SYNCED) &&
-                           ((Value32 & MAC_STATUS_RECEIVING_CFG) == 0)) {
-                               CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
-                       }
-               } else {
-                       /* We are forcing line speed. */
-                       pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
-                       LM_SetFlowControl (pDevice, 0, 0);
-
-                       CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
-                       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode |
-                               MAC_MODE_SEND_CONFIGS);
-               }
-       }
-       /* Set the link polarity bit. */
-       pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
-       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
-
-       pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
-           (pDevice->pStatusBlkVirt->
-            Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
-
-       for (j = 0; j < 100; j++) {
-               REG_WR (pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
-                       MAC_STATUS_CFG_CHANGED);
-               MM_Wait (5);
-               if ((REG_RD (pDevice, MacCtrl.Status) &
-                    (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
-                       break;
-       }
-
-       Value32 = REG_RD (pDevice, MacCtrl.Status);
-       if ((Value32 & MAC_STATUS_PCS_SYNCED) == 0) {
-               CurrentLinkStatus = LM_STATUS_LINK_DOWN;
-               if (pDevice->DisableAutoNeg == FALSE) {
-                       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode |
-                               MAC_MODE_SEND_CONFIGS);
-                       MM_Wait (1);
-                       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
-               }
-       }
-
-       /* Initialize the current link status. */
-       if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) {
-               pDevice->LineSpeed = LM_LINE_SPEED_1000MBPS;
-               pDevice->DuplexMode = LM_DUPLEX_MODE_FULL;
-               REG_WR (pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
-                       LED_CTRL_1000MBPS_LED_ON);
-       } else {
-               pDevice->LineSpeed = LM_LINE_SPEED_UNKNOWN;
-               pDevice->DuplexMode = LM_DUPLEX_MODE_UNKNOWN;
-               REG_WR (pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
-                       LED_CTRL_OVERRIDE_TRAFFIC_LED);
-       }
-
-       /* Indicate link status. */
-       if (pDevice->LinkStatus != CurrentLinkStatus) {
-               pDevice->LinkStatus = CurrentLinkStatus;
-               MM_IndicateStatus (pDevice, CurrentLinkStatus);
-       }
-
-       return LM_STATUS_SUCCESS;
-}
-#endif                         /* INCLUDE_TBI_SUPPORT */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-LM_STATUS LM_SetupCopperPhy (PLM_DEVICE_BLOCK pDevice)
-{
-       LM_STATUS CurrentLinkStatus;
-       LM_UINT32 Value32;
-
-       /* Assume there is not link first. */
-       CurrentLinkStatus = LM_STATUS_LINK_DOWN;
-
-       /* Disable phy link change attention. */
-       REG_WR (pDevice, MacCtrl.MacEvent, 0);
-
-       /* Clear link change attention. */
-       REG_WR (pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
-               MAC_STATUS_CFG_CHANGED);
-
-       /* Disable auto-polling for the moment. */
-       pDevice->MiMode = 0xc0000;
-       REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
-       MM_Wait (40);
-
-       /* Determine the requested line speed and duplex. */
-       pDevice->OldLineSpeed = pDevice->LineSpeed;
-       LM_TranslateRequestedMediaType (pDevice->RequestedMediaType,
-                                       &pDevice->MediaType,
-                                       &pDevice->LineSpeed,
-                                       &pDevice->DuplexMode);
-
-       /* Initialize the phy chip. */
-       switch (pDevice->PhyId & PHY_ID_MASK) {
-       case PHY_BCM5400_PHY_ID:
-       case PHY_BCM5401_PHY_ID:
-       case PHY_BCM5411_PHY_ID:
-       case PHY_BCM5701_PHY_ID:
-       case PHY_BCM5703_PHY_ID:
-       case PHY_BCM5704_PHY_ID:
-               CurrentLinkStatus = LM_InitBcm540xPhy (pDevice);
-               break;
-
-       default:
-               break;
-       }
-
-       if (CurrentLinkStatus == LM_STATUS_LINK_SETTING_MISMATCH) {
-               CurrentLinkStatus = LM_STATUS_LINK_DOWN;
-       }
-
-       /* Setup flow control. */
-       pDevice->FlowControl = LM_FLOW_CONTROL_NONE;
-       if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) {
-               LM_FLOW_CONTROL FlowCap;        /* Flow control capability. */
-
-               FlowCap = LM_FLOW_CONTROL_NONE;
-
-               if (pDevice->DuplexMode == LM_DUPLEX_MODE_FULL) {
-                       if (pDevice->DisableAutoNeg == FALSE ||
-                           pDevice->RequestedMediaType ==
-                           LM_REQUESTED_MEDIA_TYPE_AUTO
-                           || pDevice->RequestedMediaType ==
-                           LM_REQUESTED_MEDIA_TYPE_UTP_AUTO) {
-                               LM_UINT32 ExpectedPhyAd;
-                               LM_UINT32 LocalPhyAd;
-                               LM_UINT32 RemotePhyAd;
-
-                               LM_ReadPhy (pDevice, PHY_AN_AD_REG,
-                                           &LocalPhyAd);
-                               pDevice->advertising = LocalPhyAd;
-                               LocalPhyAd &=
-                                   (PHY_AN_AD_ASYM_PAUSE |
-                                    PHY_AN_AD_PAUSE_CAPABLE);
-
-                               ExpectedPhyAd =
-                                   GetPhyAdFlowCntrlSettings (pDevice);
-
-                               if (LocalPhyAd != ExpectedPhyAd) {
-                                       CurrentLinkStatus = LM_STATUS_LINK_DOWN;
-                               } else {
-                                       LM_ReadPhy (pDevice,
-                                                   PHY_LINK_PARTNER_ABILITY_REG,
-                                                   &RemotePhyAd);
-
-                                       LM_SetFlowControl (pDevice, LocalPhyAd,
-                                                          RemotePhyAd);
-                               }
-                       } else {
-                               pDevice->FlowControlCap &=
-                                   ~LM_FLOW_CONTROL_AUTO_PAUSE;
-                               LM_SetFlowControl (pDevice, 0, 0);
-                       }
-               }
-       }
-
-       if (CurrentLinkStatus == LM_STATUS_LINK_DOWN) {
-               LM_ForceAutoNeg (pDevice, pDevice->RequestedMediaType);
-
-               /* If we force line speed, we make get link right away. */
-               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
-               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
-               if (Value32 & PHY_STATUS_LINK_PASS) {
-                       CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
-               }
-       }
-
-       /* GMII interface. */
-       pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
-       if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) {
-               if (pDevice->LineSpeed == LM_LINE_SPEED_100MBPS ||
-                   pDevice->LineSpeed == LM_LINE_SPEED_10MBPS) {
-                       pDevice->MacMode |= MAC_MODE_PORT_MODE_MII;
-               } else {
-                       pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
-               }
-       } else {
-               pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
-       }
-
-       /* Set the MAC to operate in the appropriate duplex mode. */
-       pDevice->MacMode &= ~MAC_MODE_HALF_DUPLEX;
-       if (pDevice->DuplexMode == LM_DUPLEX_MODE_HALF) {
-               pDevice->MacMode |= MAC_MODE_HALF_DUPLEX;
-       }
-
-       /* Set the link polarity bit. */
-       pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
-       if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
-               if ((pDevice->LedMode == LED_MODE_LINK10) ||
-                   (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE &&
-                    pDevice->LineSpeed == LM_LINE_SPEED_10MBPS)) {
-                       pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
-               }
-       } else {
-               if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) {
-                       pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
-               }
-
-               /* Set LED mode. */
-               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
-                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
-                       Value32 = LED_CTRL_PHY_MODE_1;
-               } else {
-                       if (pDevice->LedMode == LED_MODE_OUTPUT) {
-                               Value32 = LED_CTRL_PHY_MODE_2;
-                       } else {
-                               Value32 = LED_CTRL_PHY_MODE_1;
-                       }
-               }
-               REG_WR (pDevice, MacCtrl.LedCtrl, Value32);
-       }
-
-       REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
-
-       /* Enable auto polling. */
-       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
-               pDevice->MiMode |= MI_MODE_AUTO_POLLING_ENABLE;
-               REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
-       }
-
-       /* Enable phy link change attention. */
-       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT) {
-               REG_WR (pDevice, MacCtrl.MacEvent,
-                       MAC_EVENT_ENABLE_MI_INTERRUPT);
-       } else {
-               REG_WR (pDevice, MacCtrl.MacEvent,
-                       MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
-       }
-       if ((T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) &&
-           (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) &&
-           (pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
-           (((pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) &&
-             (pDevice->PciState & T3_PCI_STATE_BUS_SPEED_HIGH)) ||
-            !(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))) {
-               MM_Wait (120);
-               REG_WR (pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
-                       MAC_STATUS_CFG_CHANGED);
-               MEM_WR_OFFSET (pDevice, T3_FIRMWARE_MAILBOX,
-                              T3_MAGIC_NUM_DISABLE_DMAW_ON_LINK_CHANGE);
-       }
-
-       /* Indicate link status. */
-       if (pDevice->LinkStatus != CurrentLinkStatus) {
-               pDevice->LinkStatus = CurrentLinkStatus;
-               MM_IndicateStatus (pDevice, CurrentLinkStatus);
-       }
-
-       return LM_STATUS_SUCCESS;
-}                              /* LM_SetupCopperPhy */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-LM_STATUS LM_SetupPhy (PLM_DEVICE_BLOCK pDevice)
-{
-       LM_STATUS LmStatus;
-       LM_UINT32 Value32;
-
-#if INCLUDE_TBI_SUPPORT
-       if (pDevice->EnableTbi) {
-               LmStatus = LM_SetupFiberPhy (pDevice);
-       } else
-#endif                         /* INCLUDE_TBI_SUPPORT */
-       {
-               LmStatus = LM_SetupCopperPhy (pDevice);
-       }
-       if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
-               if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)) {
-                       Value32 = REG_RD (pDevice, PciCfg.PciState);
-                       REG_WR (pDevice, PciCfg.PciState,
-                               Value32 | T3_PCI_STATE_RETRY_SAME_DMA);
-               }
-       }
-       if ((pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
-           (pDevice->DuplexMode == LM_DUPLEX_MODE_HALF)) {
-               REG_WR (pDevice, MacCtrl.TxLengths, 0x26ff);
-       } else {
-               REG_WR (pDevice, MacCtrl.TxLengths, 0x2620);
-       }
-
-       return LmStatus;
-}
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-LM_VOID
-LM_ReadPhy (PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg, PLM_UINT32 pData32)
-{
-       LM_UINT32 Value32;
-       LM_UINT32 j;
-
-       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
-               REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode &
-                       ~MI_MODE_AUTO_POLLING_ENABLE);
-               MM_Wait (40);
-       }
-
-       Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
-           ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) <<
-            MI_COM_FIRST_PHY_REG_ADDR_BIT) | MI_COM_CMD_READ | MI_COM_START;
-
-       REG_WR (pDevice, MacCtrl.MiCom, Value32);
-
-       for (j = 0; j < 20; j++) {
-               MM_Wait (25);
-
-               Value32 = REG_RD (pDevice, MacCtrl.MiCom);
-
-               if (!(Value32 & MI_COM_BUSY)) {
-                       MM_Wait (5);
-                       Value32 = REG_RD (pDevice, MacCtrl.MiCom);
-                       Value32 &= MI_COM_PHY_DATA_MASK;
-                       break;
-               }
-       }
-
-       if (Value32 & MI_COM_BUSY) {
-               Value32 = 0;
-       }
-
-       *pData32 = Value32;
-
-       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
-               REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
-               MM_Wait (40);
-       }
-}                              /* LM_ReadPhy */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-LM_VOID
-LM_WritePhy (PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg, LM_UINT32 Data32)
-{
-       LM_UINT32 Value32;
-       LM_UINT32 j;
-
-       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
-               REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode &
-                       ~MI_MODE_AUTO_POLLING_ENABLE);
-               MM_Wait (40);
-       }
-
-       Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
-           ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) <<
-            MI_COM_FIRST_PHY_REG_ADDR_BIT) | (Data32 & MI_COM_PHY_DATA_MASK) |
-           MI_COM_CMD_WRITE | MI_COM_START;
-
-       REG_WR (pDevice, MacCtrl.MiCom, Value32);
-
-       for (j = 0; j < 20; j++) {
-               MM_Wait (25);
-
-               Value32 = REG_RD (pDevice, MacCtrl.MiCom);
-
-               if (!(Value32 & MI_COM_BUSY)) {
-                       MM_Wait (5);
-                       break;
-               }
-       }
-
-       if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
-               REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
-               MM_Wait (40);
-       }
-}                              /* LM_WritePhy */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-LM_STATUS LM_SetPowerState (PLM_DEVICE_BLOCK pDevice, LM_POWER_STATE PowerLevel)
-{
-       LM_UINT32 PmeSupport;
-       LM_UINT32 Value32;
-       LM_UINT32 PmCtrl;
-
-       /* make sureindirect accesses are enabled */
-       MM_WriteConfig32 (pDevice, T3_PCI_MISC_HOST_CTRL_REG,
-                         pDevice->MiscHostCtrl);
-
-       /* Clear the PME_ASSERT bit and the power state bits.  Also enable */
-       /* the PME bit. */
-       MM_ReadConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, &PmCtrl);
-
-       PmCtrl |= T3_PM_PME_ASSERTED;
-       PmCtrl &= ~T3_PM_POWER_STATE_MASK;
-
-       /* Set the appropriate power state. */
-       if (PowerLevel == LM_POWER_STATE_D0) {
-
-               /* Bring the card out of low power mode. */
-               PmCtrl |= T3_PM_POWER_STATE_D0;
-               MM_WriteConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
-
-               REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
-               MM_Wait (40);
-#if 0                          /* Bugfix by jmb...can't call WritePhy here because pDevice not fully initialized */
-               LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x02);
-#endif
-
-               return LM_STATUS_SUCCESS;
-       } else if (PowerLevel == LM_POWER_STATE_D1) {
-               PmCtrl |= T3_PM_POWER_STATE_D1;
-       } else if (PowerLevel == LM_POWER_STATE_D2) {
-               PmCtrl |= T3_PM_POWER_STATE_D2;
-       } else if (PowerLevel == LM_POWER_STATE_D3) {
-               PmCtrl |= T3_PM_POWER_STATE_D3;
-       } else {
-               return LM_STATUS_FAILURE;
-       }
-       PmCtrl |= T3_PM_PME_ENABLE;
-
-       /* Mask out all interrupts so LM_SetupPhy won't be called while we are */
-       /* setting new line speed. */
-       Value32 = REG_RD (pDevice, PciCfg.MiscHostCtrl);
-       REG_WR (pDevice, PciCfg.MiscHostCtrl,
-               Value32 | MISC_HOST_CTRL_MASK_PCI_INT);
-
-       if (!pDevice->RestoreOnWakeUp) {
-               pDevice->RestoreOnWakeUp = TRUE;
-               pDevice->WakeUpDisableAutoNeg = pDevice->DisableAutoNeg;
-               pDevice->WakeUpRequestedMediaType = pDevice->RequestedMediaType;
-       }
-
-       /* Force auto-negotiation to 10 line speed. */
-       pDevice->DisableAutoNeg = FALSE;
-       pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS;
-       LM_SetupPhy (pDevice);
-
-       /* Put the driver in the initial state, and go through the power down */
-       /* sequence. */
-       LM_Halt (pDevice);
-
-       MM_ReadConfig32 (pDevice, T3_PCI_PM_CAP_REG, &PmeSupport);
-
-       if (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE) {
-
-               /* Enable WOL. */
-               LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x5a);
-               MM_Wait (40);
-
-               /* Set LED mode. */
-               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
-                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
-                       Value32 = LED_CTRL_PHY_MODE_1;
-               } else {
-                       if (pDevice->LedMode == LED_MODE_OUTPUT) {
-                               Value32 = LED_CTRL_PHY_MODE_2;
-                       } else {
-                               Value32 = LED_CTRL_PHY_MODE_1;
-                       }
-               }
-
-               Value32 = MAC_MODE_PORT_MODE_MII;
-               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
-                       if (pDevice->LedMode == LED_MODE_LINK10 ||
-                           pDevice->WolSpeed == WOL_SPEED_10MB) {
-                               Value32 |= MAC_MODE_LINK_POLARITY;
-                       }
-               } else {
-                       Value32 |= MAC_MODE_LINK_POLARITY;
-               }
-               REG_WR (pDevice, MacCtrl.Mode, Value32);
-               MM_Wait (40);
-               MM_Wait (40);
-               MM_Wait (40);
-
-               /* Always enable magic packet wake-up if we have vaux. */
-               if ((PmeSupport & T3_PCI_PM_CAP_PME_D3COLD) &&
-                   (pDevice->WakeUpModeCap & LM_WAKE_UP_MODE_MAGIC_PACKET)) {
-                       Value32 |= MAC_MODE_DETECT_MAGIC_PACKET_ENABLE;
-               }
-
-               REG_WR (pDevice, MacCtrl.Mode, Value32);
-
-               /* Enable the receiver. */
-               REG_WR (pDevice, MacCtrl.RxMode, RX_MODE_ENABLE);
-       }
-
-       /* Disable tx/rx clocks, and seletect an alternate clock. */
-       if (pDevice->WolSpeed == WOL_SPEED_100MB) {
-               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
-                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
-                       Value32 =
-                           T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
-                           T3_PCI_SELECT_ALTERNATE_CLOCK;
-               } else {
-                       Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK;
-               }
-               REG_WR (pDevice, PciCfg.ClockCtrl, Value32);
-
-               MM_Wait (40);
-
-               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
-                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
-                       Value32 =
-                           T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
-                           T3_PCI_SELECT_ALTERNATE_CLOCK |
-                           T3_PCI_44MHZ_CORE_CLOCK;
-               } else {
-                       Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK |
-                           T3_PCI_44MHZ_CORE_CLOCK;
-               }
-
-               REG_WR (pDevice, PciCfg.ClockCtrl, Value32);
-
-               MM_Wait (40);
-
-               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
-                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
-                       Value32 =
-                           T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
-                           T3_PCI_44MHZ_CORE_CLOCK;
-               } else {
-                       Value32 = T3_PCI_44MHZ_CORE_CLOCK;
-               }
-
-               REG_WR (pDevice, PciCfg.ClockCtrl, Value32);
-       } else {
-               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
-                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
-                       Value32 =
-                           T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
-                           T3_PCI_SELECT_ALTERNATE_CLOCK |
-                           T3_PCI_POWER_DOWN_PCI_PLL133;
-               } else {
-                       Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK |
-                           T3_PCI_POWER_DOWN_PCI_PLL133;
-               }
-
-               REG_WR (pDevice, PciCfg.ClockCtrl, Value32);
-       }
-
-       MM_Wait (40);
-
-       if (!pDevice->EepromWp
-           && (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE)) {
-               /* Switch adapter to auxilliary power. */
-               if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
-                   T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
-                       /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
-                       REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
-                       MM_Wait (40);
-               } else {
-                       /* GPIO0 = 0, GPIO1 = 1, GPIO2 = 1. */
-                       REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
-                       MM_Wait (40);
-
-                       /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 1. */
-                       REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
-                       MM_Wait (40);
-
-                       /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
-                       REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
-                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
-                       MM_Wait (40);
-               }
-       }
-
-       /* Set the phy to low power mode. */
-       /* Put the the hardware in low power mode. */
-       MM_WriteConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
-
-       return LM_STATUS_SUCCESS;
-}                              /* LM_SetPowerState */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-static LM_UINT32 GetPhyAdFlowCntrlSettings (PLM_DEVICE_BLOCK pDevice)
-{
-       LM_UINT32 Value32;
-
-       Value32 = 0;
-
-       /* Auto negotiation flow control only when autonegotiation is enabled. */
-       if (pDevice->DisableAutoNeg == FALSE ||
-           pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO ||
-           pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_UTP_AUTO) {
-               /* Please refer to Table 28B-3 of the 802.3ab-1999 spec. */
-               if ((pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE) ||
-                   ((pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)
-                    && (pDevice->
-                        FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE))) {
-                       Value32 |= PHY_AN_AD_PAUSE_CAPABLE;
-               } else if (pDevice->
-                          FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE) {
-                       Value32 |= PHY_AN_AD_ASYM_PAUSE;
-               } else if (pDevice->
-                          FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE) {
-                       Value32 |=
-                           PHY_AN_AD_PAUSE_CAPABLE | PHY_AN_AD_ASYM_PAUSE;
-               }
-       }
-
-       return Value32;
-}
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/*    LM_STATUS_FAILURE                                                       */
-/*    LM_STATUS_SUCCESS                                                       */
-/*                                                                            */
-/******************************************************************************/
-static LM_STATUS
-LM_ForceAutoNegBcm540xPhy (PLM_DEVICE_BLOCK pDevice,
-                          LM_REQUESTED_MEDIA_TYPE RequestedMediaType)
-{
-       LM_MEDIA_TYPE MediaType;
-       LM_LINE_SPEED LineSpeed;
-       LM_DUPLEX_MODE DuplexMode;
-       LM_UINT32 NewPhyCtrl;
-       LM_UINT32 Value32;
-       LM_UINT32 Cnt;
-
-       /* Get the interface type, line speed, and duplex mode. */
-       LM_TranslateRequestedMediaType (RequestedMediaType, &MediaType,
-                                       &LineSpeed, &DuplexMode);
-
-       if (pDevice->RestoreOnWakeUp) {
-               LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG, 0);
-               pDevice->advertising1000 = 0;
-               Value32 = PHY_AN_AD_10BASET_FULL | PHY_AN_AD_10BASET_HALF;
-               if (pDevice->WolSpeed == WOL_SPEED_100MB) {
-                       Value32 |=
-                           PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
-               }
-               Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
-               Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
-               LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
-               pDevice->advertising = Value32;
-       }
-       /* Setup the auto-negotiation advertisement register. */
-       else if (LineSpeed == LM_LINE_SPEED_UNKNOWN) {
-               /* Setup the 10/100 Mbps auto-negotiation advertisement register. */
-               Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
-                   PHY_AN_AD_10BASET_HALF | PHY_AN_AD_10BASET_FULL |
-                   PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
-               Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
-
-               LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
-               pDevice->advertising = Value32;
-
-               /* Advertise 1000Mbps */
-               Value32 =
-                   BCM540X_AN_AD_1000BASET_HALF | BCM540X_AN_AD_1000BASET_FULL;
-
-#if INCLUDE_5701_AX_FIX
-               /* Bug: workaround for CRC error in gigabit mode when we are in */
-               /* slave mode.  This will force the PHY to operate in */
-               /* master mode. */
-               if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
-                   pDevice->ChipRevId == T3_CHIP_ID_5701_B0) {
-                       Value32 |= BCM540X_CONFIG_AS_MASTER |
-                           BCM540X_ENABLE_CONFIG_AS_MASTER;
-               }
-#endif
-
-               LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
-               pDevice->advertising1000 = Value32;
-       } else {
-               if (LineSpeed == LM_LINE_SPEED_1000MBPS) {
-                       Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
-                       Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
-
-                       LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
-                       pDevice->advertising = Value32;
-
-                       if (DuplexMode != LM_DUPLEX_MODE_FULL) {
-                               Value32 = BCM540X_AN_AD_1000BASET_HALF;
-                       } else {
-                               Value32 = BCM540X_AN_AD_1000BASET_FULL;
-                       }
-
-                       LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG,
-                                    Value32);
-                       pDevice->advertising1000 = Value32;
-               } else if (LineSpeed == LM_LINE_SPEED_100MBPS) {
-                       LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG, 0);
-                       pDevice->advertising1000 = 0;
-
-                       if (DuplexMode != LM_DUPLEX_MODE_FULL) {
-                               Value32 = PHY_AN_AD_100BASETX_HALF;
-                       } else {
-                               Value32 = PHY_AN_AD_100BASETX_FULL;
-                       }
-
-                       Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
-                       Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
-
-                       LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
-                       pDevice->advertising = Value32;
-               } else if (LineSpeed == LM_LINE_SPEED_10MBPS) {
-                       LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG, 0);
-                       pDevice->advertising1000 = 0;
-
-                       if (DuplexMode != LM_DUPLEX_MODE_FULL) {
-                               Value32 = PHY_AN_AD_10BASET_HALF;
-                       } else {
-                               Value32 = PHY_AN_AD_10BASET_FULL;
-                       }
-
-                       Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
-                       Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
-
-                       LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
-                       pDevice->advertising = Value32;
-               }
-       }
-
-       /* Force line speed if auto-negotiation is disabled. */
-       if (pDevice->DisableAutoNeg && LineSpeed != LM_LINE_SPEED_UNKNOWN) {
-               /* This code path is executed only when there is link. */
-               pDevice->MediaType = MediaType;
-               pDevice->LineSpeed = LineSpeed;
-               pDevice->DuplexMode = DuplexMode;
-
-               /* Force line seepd. */
-               NewPhyCtrl = 0;
-               switch (LineSpeed) {
-               case LM_LINE_SPEED_10MBPS:
-                       NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_10MBPS;
-                       break;
-               case LM_LINE_SPEED_100MBPS:
-                       NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_100MBPS;
-                       break;
-               case LM_LINE_SPEED_1000MBPS:
-                       NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
-                       break;
-               default:
-                       NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
-                       break;
-               }
-
-               if (DuplexMode == LM_DUPLEX_MODE_FULL) {
-                       NewPhyCtrl |= PHY_CTRL_FULL_DUPLEX_MODE;
-               }
-
-               /* Don't do anything if the PHY_CTRL is already what we wanted. */
-               LM_ReadPhy (pDevice, PHY_CTRL_REG, &Value32);
-               if (Value32 != NewPhyCtrl) {
-                       /* Temporary bring the link down before forcing line speed. */
-                       LM_WritePhy (pDevice, PHY_CTRL_REG,
-                                    PHY_CTRL_LOOPBACK_MODE);
-
-                       /* Wait for link to go down. */
-                       for (Cnt = 0; Cnt < 15000; Cnt++) {
-                               MM_Wait (10);
-
-                               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
-                               LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
-
-                               if (!(Value32 & PHY_STATUS_LINK_PASS)) {
-                                       MM_Wait (40);
-                                       break;
-                               }
-                       }
-
-                       LM_WritePhy (pDevice, PHY_CTRL_REG, NewPhyCtrl);
-                       MM_Wait (40);
-               }
-       } else {
-               LM_WritePhy (pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
-                            PHY_CTRL_RESTART_AUTO_NEG);
-       }
-
-       return LM_STATUS_SUCCESS;
-}                              /* LM_ForceAutoNegBcm540xPhy */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-static LM_STATUS
-LM_ForceAutoNeg (PLM_DEVICE_BLOCK pDevice,
-                LM_REQUESTED_MEDIA_TYPE RequestedMediaType)
-{
-       LM_STATUS LmStatus;
-
-       /* Initialize the phy chip. */
-       switch (pDevice->PhyId & PHY_ID_MASK) {
-       case PHY_BCM5400_PHY_ID:
-       case PHY_BCM5401_PHY_ID:
-       case PHY_BCM5411_PHY_ID:
-       case PHY_BCM5701_PHY_ID:
-       case PHY_BCM5703_PHY_ID:
-       case PHY_BCM5704_PHY_ID:
-               LmStatus =
-                   LM_ForceAutoNegBcm540xPhy (pDevice, RequestedMediaType);
-               break;
-
-       default:
-               LmStatus = LM_STATUS_FAILURE;
-               break;
-       }
-
-       return LmStatus;
-}                              /* LM_ForceAutoNeg */
-
-/******************************************************************************/
-/* Description:                                                               */
-/*                                                                            */
-/* Return:                                                                    */
-/******************************************************************************/
-LM_STATUS LM_LoadFirmware (PLM_DEVICE_BLOCK pDevice,
-                          PT3_FWIMG_INFO pFwImg,
-                          LM_UINT32 LoadCpu, LM_UINT32 StartCpu)
-{
-       LM_UINT32 i;
-       LM_UINT32 address;
-
-       if (LoadCpu & T3_RX_CPU_ID) {
-               if (LM_HaltCpu (pDevice, T3_RX_CPU_ID) != LM_STATUS_SUCCESS) {
-                       return LM_STATUS_FAILURE;
-               }
-
-               /* First of all clear scrach pad memory */
-               for (i = 0; i < T3_RX_CPU_SPAD_SIZE; i += 4) {
-                       LM_RegWrInd (pDevice, T3_RX_CPU_SPAD_ADDR + i, 0);
-               }
-
-               /* Copy code first */
-               address = T3_RX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
-               for (i = 0; i <= pFwImg->Text.Length; i += 4) {
-                       LM_RegWrInd (pDevice, address + i,
-                                    ((LM_UINT32 *) pFwImg->Text.Buffer)[i /
-                                                                        4]);
-               }
-
-               address =
-                   T3_RX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
-               for (i = 0; i <= pFwImg->ROnlyData.Length; i += 4) {
-                       LM_RegWrInd (pDevice, address + i,
-                                    ((LM_UINT32 *) pFwImg->ROnlyData.
-                                     Buffer)[i / 4]);
-               }
-
-               address = T3_RX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
-               for (i = 0; i <= pFwImg->Data.Length; i += 4) {
-                       LM_RegWrInd (pDevice, address + i,
-                                    ((LM_UINT32 *) pFwImg->Data.Buffer)[i /
-                                                                        4]);
-               }
-       }
-
-       if (LoadCpu & T3_TX_CPU_ID) {
-               if (LM_HaltCpu (pDevice, T3_TX_CPU_ID) != LM_STATUS_SUCCESS) {
-                       return LM_STATUS_FAILURE;
-               }
-
-               /* First of all clear scrach pad memory */
-               for (i = 0; i < T3_TX_CPU_SPAD_SIZE; i += 4) {
-                       LM_RegWrInd (pDevice, T3_TX_CPU_SPAD_ADDR + i, 0);
-               }
-
-               /* Copy code first */
-               address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
-               for (i = 0; i <= pFwImg->Text.Length; i += 4) {
-                       LM_RegWrInd (pDevice, address + i,
-                                    ((LM_UINT32 *) pFwImg->Text.Buffer)[i /
-                                                                        4]);
-               }
-
-               address =
-                   T3_TX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
-               for (i = 0; i <= pFwImg->ROnlyData.Length; i += 4) {
-                       LM_RegWrInd (pDevice, address + i,
-                                    ((LM_UINT32 *) pFwImg->ROnlyData.
-                                     Buffer)[i / 4]);
-               }
-
-               address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
-               for (i = 0; i <= pFwImg->Data.Length; i += 4) {
-                       LM_RegWrInd (pDevice, address + i,
-                                    ((LM_UINT32 *) pFwImg->Data.Buffer)[i /
-                                                                        4]);
-               }
-       }
-
-       if (StartCpu & T3_RX_CPU_ID) {
-               /* Start Rx CPU */
-               REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
-               REG_WR (pDevice, rxCpu.reg.PC, pFwImg->StartAddress);
-               for (i = 0; i < 5; i++) {
-                       if (pFwImg->StartAddress ==
-                           REG_RD (pDevice, rxCpu.reg.PC))
-                               break;
-
-                       REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
-                       REG_WR (pDevice, rxCpu.reg.mode, CPU_MODE_HALT);
-                       REG_WR (pDevice, rxCpu.reg.PC, pFwImg->StartAddress);
-                       MM_Wait (1000);
-               }
-
-               REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
-               REG_WR (pDevice, rxCpu.reg.mode, 0);
-       }
-
-       if (StartCpu & T3_TX_CPU_ID) {
-               /* Start Tx CPU */
-               REG_WR (pDevice, txCpu.reg.state, 0xffffffff);
-               REG_WR (pDevice, txCpu.reg.PC, pFwImg->StartAddress);
-               for (i = 0; i < 5; i++) {
-                       if (pFwImg->StartAddress ==
-                           REG_RD (pDevice, txCpu.reg.PC))
-                               break;
-
-                       REG_WR (pDevice, txCpu.reg.state, 0xffffffff);
-                       REG_WR (pDevice, txCpu.reg.mode, CPU_MODE_HALT);
-                       REG_WR (pDevice, txCpu.reg.PC, pFwImg->StartAddress);
-                       MM_Wait (1000);
-               }
-
-               REG_WR (pDevice, txCpu.reg.state, 0xffffffff);
-               REG_WR (pDevice, txCpu.reg.mode, 0);
-       }
-
-       return LM_STATUS_SUCCESS;
-}
-
-STATIC LM_STATUS LM_HaltCpu (PLM_DEVICE_BLOCK pDevice, LM_UINT32 cpu_number)
-{
-       LM_UINT32 i;
-
-       if (cpu_number == T3_RX_CPU_ID) {
-               for (i = 0; i < 10000; i++) {
-                       REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
-                       REG_WR (pDevice, rxCpu.reg.mode, CPU_MODE_HALT);
-
-                       if (REG_RD (pDevice, rxCpu.reg.mode) & CPU_MODE_HALT)
-                               break;
-               }
-
-               REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
-               REG_WR (pDevice, rxCpu.reg.mode, CPU_MODE_HALT);
-               MM_Wait (10);
-       } else {
-               for (i = 0; i < 10000; i++) {
-                       REG_WR (pDevice, txCpu.reg.state, 0xffffffff);
-                       REG_WR (pDevice, txCpu.reg.mode, CPU_MODE_HALT);
-
-                       if (REG_RD (pDevice, txCpu.reg.mode) & CPU_MODE_HALT)
-                               break;
-               }
-       }
-
-       return ((i == 10000) ? LM_STATUS_FAILURE : LM_STATUS_SUCCESS);
-}
-
-int LM_BlinkLED (PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlinkDurationSec)
-{
-       LM_UINT32 Oldcfg;
-       int j;
-       int ret = 0;
-
-       if (BlinkDurationSec == 0) {
-               return 0;
-       }
-       if (BlinkDurationSec > 120) {
-               BlinkDurationSec = 120;
-       }
-
-       Oldcfg = REG_RD (pDevice, MacCtrl.LedCtrl);
-       for (j = 0; j < BlinkDurationSec * 2; j++) {
-               if (j % 2) {
-                       /* Turn on the LEDs. */
-                       REG_WR (pDevice, MacCtrl.LedCtrl,
-                               LED_CTRL_OVERRIDE_LINK_LED |
-                               LED_CTRL_1000MBPS_LED_ON |
-                               LED_CTRL_100MBPS_LED_ON |
-                               LED_CTRL_10MBPS_LED_ON |
-                               LED_CTRL_OVERRIDE_TRAFFIC_LED |
-                               LED_CTRL_BLINK_TRAFFIC_LED |
-                               LED_CTRL_TRAFFIC_LED);
-               } else {
-                       /* Turn off the LEDs. */
-                       REG_WR (pDevice, MacCtrl.LedCtrl,
-                               LED_CTRL_OVERRIDE_LINK_LED |
-                               LED_CTRL_OVERRIDE_TRAFFIC_LED);
-               }
-
-#ifndef EMBEDDED
-               current->state = TASK_INTERRUPTIBLE;
-               if (schedule_timeout (HZ / 2) != 0) {
-                       ret = -EINTR;
-                       break;
-               }
-#else
-               udelay (100000);        /* 1s sleep */
-#endif
-       }
-       REG_WR (pDevice, MacCtrl.LedCtrl, Oldcfg);
-       return ret;
-}
-
-int t3_do_dma (PLM_DEVICE_BLOCK pDevice,
-              LM_PHYSICAL_ADDRESS host_addr_phy, int length, int dma_read)
-{
-       T3_DMA_DESC dma_desc;
-       int i;
-       LM_UINT32 dma_desc_addr;
-       LM_UINT32 value32;
-
-       REG_WR (pDevice, BufMgr.Mode, 0);
-       REG_WR (pDevice, Ftq.Reset, 0);
-
-       dma_desc.host_addr.High = host_addr_phy.High;
-       dma_desc.host_addr.Low = host_addr_phy.Low;
-       dma_desc.nic_mbuf = 0x2100;
-       dma_desc.len = length;
-       dma_desc.flags = 0x00000004;    /* Generate Rx-CPU event */
-
-       if (dma_read) {
-               dma_desc.cqid_sqid = (T3_QID_RX_BD_COMP << 8) |
-                   T3_QID_DMA_HIGH_PRI_READ;
-               REG_WR (pDevice, DmaRead.Mode, DMA_READ_MODE_ENABLE);
-       } else {
-               dma_desc.cqid_sqid = (T3_QID_RX_DATA_COMP << 8) |
-                   T3_QID_DMA_HIGH_PRI_WRITE;
-               REG_WR (pDevice, DmaWrite.Mode, DMA_WRITE_MODE_ENABLE);
-       }
-
-       dma_desc_addr = T3_NIC_DMA_DESC_POOL_ADDR;
-
-       /* Writing this DMA descriptor to DMA memory */
-       for (i = 0; i < sizeof (T3_DMA_DESC); i += 4) {
-               value32 = *((PLM_UINT32) (((PLM_UINT8) & dma_desc) + i));
-               MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG,
-                                 dma_desc_addr + i);
-               MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_DATA_REG,
-                                 cpu_to_le32 (value32));
-       }
-       MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG, 0);
-
-       if (dma_read)
-               REG_WR (pDevice, Ftq.DmaHighReadFtqFifoEnqueueDequeue,
-                       dma_desc_addr);
-       else
-               REG_WR (pDevice, Ftq.DmaHighWriteFtqFifoEnqueueDequeue,
-                       dma_desc_addr);
-
-       for (i = 0; i < 40; i++) {
-               if (dma_read)
-                       value32 =
-                           REG_RD (pDevice,
-                                   Ftq.RcvBdCompFtqFifoEnqueueDequeue);
-               else
-                       value32 =
-                           REG_RD (pDevice,
-                                   Ftq.RcvDataCompFtqFifoEnqueueDequeue);
-
-               if ((value32 & 0xffff) == dma_desc_addr)
-                       break;
-
-               MM_Wait (10);
-       }
-
-       return LM_STATUS_SUCCESS;
-}
-
-STATIC LM_STATUS
-LM_DmaTest (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
-           LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize)
-{
-       int j;
-       LM_UINT32 *ptr;
-       int dma_success = 0;
-
-       if (T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
-           T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5701) {
-               return LM_STATUS_SUCCESS;
-       }
-       while (!dma_success) {
-               /* Fill data with incremental patterns */
-               ptr = (LM_UINT32 *) pBufferVirt;
-               for (j = 0; j < BufferSize / 4; j++)
-                       *ptr++ = j;
-
-               if (t3_do_dma (pDevice, BufferPhy, BufferSize, 1) ==
-                   LM_STATUS_FAILURE) {
-                       return LM_STATUS_FAILURE;
-               }
-
-               MM_Wait (40);
-               ptr = (LM_UINT32 *) pBufferVirt;
-               /* Fill data with zero */
-               for (j = 0; j < BufferSize / 4; j++)
-                       *ptr++ = 0;
-
-               if (t3_do_dma (pDevice, BufferPhy, BufferSize, 0) ==
-                   LM_STATUS_FAILURE) {
-                       return LM_STATUS_FAILURE;
-               }
-
-               MM_Wait (40);
-               /* Check for data */
-               ptr = (LM_UINT32 *) pBufferVirt;
-               for (j = 0; j < BufferSize / 4; j++) {
-                       if (*ptr++ != j) {
-                               if ((pDevice->
-                                    DmaReadWriteCtrl &
-                                    DMA_CTRL_WRITE_BOUNDARY_MASK)
-                                   == DMA_CTRL_WRITE_BOUNDARY_DISABLE) {
-                                       pDevice->DmaReadWriteCtrl =
-                                           (pDevice->
-                                            DmaReadWriteCtrl &
-                                            ~DMA_CTRL_WRITE_BOUNDARY_MASK) |
-                                           DMA_CTRL_WRITE_BOUNDARY_16;
-                                       REG_WR (pDevice,
-                                               PciCfg.DmaReadWriteCtrl,
-                                               pDevice->DmaReadWriteCtrl);
-                                       break;
-                               } else {
-                                       return LM_STATUS_FAILURE;
-                               }
-                       }
-               }
-               if (j == (BufferSize / 4))
-                       dma_success = 1;
-       }
-       return LM_STATUS_SUCCESS;
-}
-
-#endif
diff --git a/drivers/tigon3.h b/drivers/tigon3.h
deleted file mode 100644 (file)
index c03347f..0000000
+++ /dev/null
@@ -1,3339 +0,0 @@
-
-/******************************************************************************/
-/*                                                                            */
-/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
-/* Corporation.                                                               */
-/* All rights reserved.                                                       */
-/*                                                                            */
-/* This program is free software; you can redistribute it and/or modify       */
-/* it under the terms of the GNU General Public License as published by       */
-/* the Free Software Foundation, located in the file LICENSE.                 */
-/*                                                                            */
-/* History:                                                                   */
-/*                                                                            */
-/******************************************************************************/
-
-#ifndef TIGON3_H
-#define TIGON3_H
-
-#include "bcm570x_lm.h"
-#if INCLUDE_TBI_SUPPORT
-#include "bcm570x_autoneg.h"
-#endif
-
-/* io defines */
-#if !defined(BIG_ENDIAN_HOST)
-#define readl(addr) \
-             (LONGSWAP((*(volatile unsigned int *)(addr))))
-#define writel(b,addr) \
-             ((*(volatile unsigned int *)(addr)) = (LONGSWAP(b)))
-#else
-#if 0                          /* !defined(PPC603) */
-#define readl(addr) (*(volatile unsigned int*)(0xa0000000 + (unsigned long)(addr)))
-#define writel(b,addr) ((*(volatile unsigned int *) ((unsigned long)(addr) + 0xa0000000)) = (b))
-#else
-#if 1
-#define readl(addr) (*(volatile unsigned int*)(addr))
-#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
-#else
-extern int sprintf (char *buf, const char *f, ...);
-static __inline unsigned int readl (void *addr)
-{
-       char buf[128];
-       unsigned int tmp = (*(volatile unsigned int *)(addr));
-       sprintf (buf, "%s:%s: read 0x%x from 0x%x\n", __FILE__, __LINE__, tmp,
-                addr, 0, 0);
-       sysSerialPrintString (buf);
-       return tmp;
-}
-static __inline void writel (unsigned int b, unsigned int addr)
-{
-       char buf[128];
-       ((*(volatile unsigned int *)(addr)) = (b));
-       sprintf (buf, "%s:%s: write 0x%x to 0x%x\n", __FILE__, __LINE__, b,
-                addr, 0, 0);
-       sysSerialPrintString (buf);
-}
-#endif
-#endif                         /* PPC603 */
-#endif
-
-/******************************************************************************/
-/* Constants. */
-/******************************************************************************/
-
-/* Maxim number of packet descriptors used for sending packets. */
-#define MAX_TX_PACKET_DESC_COUNT            600
-#define DEFAULT_TX_PACKET_DESC_COUNT        2
-
-/* Maximum number of packet descriptors used for receiving packets. */
-#if T3_JUMBO_RCB_ENTRY_COUNT
-#define MAX_RX_PACKET_DESC_COUNT                                            \
-    (T3_STD_RCV_RCB_ENTRY_COUNT + T3_JUMBO_RCV_RCB_ENTRY_COUNT)
-#else
-#define MAX_RX_PACKET_DESC_COUNT            800
-#endif
-#define DEFAULT_RX_PACKET_DESC_COUNT        2
-
-/* Threshhold for double copying small tx packets.  0 will disable double */
-/* copying of small Tx packets. */
-#define DEFAULT_TX_COPY_BUFFER_SIZE         0
-#define MIN_TX_COPY_BUFFER_SIZE             64
-#define MAX_TX_COPY_BUFFER_SIZE             512
-
-/* Cache line. */
-#define COMMON_CACHE_LINE_SIZE              0x20
-#define COMMON_CACHE_LINE_MASK              (COMMON_CACHE_LINE_SIZE-1)
-
-/* Maximum number of fragment we can handle. */
-#ifndef MAX_FRAGMENT_COUNT
-#define MAX_FRAGMENT_COUNT                  32
-#endif
-
-/* B0 bug. */
-#define BCM5700_BX_MIN_FRAG_SIZE            10
-#define BCM5700_BX_MIN_FRAG_BUF_SIZE        16 /* nice aligned size. */
-#define BCM5700_BX_MIN_FRAG_BUF_SIZE_MASK   (BCM5700_BX_MIN_FRAG_BUF_SIZE-1)
-#define BCM5700_BX_TX_COPY_BUF_SIZE         (BCM5700_BX_MIN_FRAG_BUF_SIZE * \
-                                           MAX_FRAGMENT_COUNT)
-
-/* MAGIC number. */
-/* #define T3_MAGIC_NUM                        'KevT' */
-#define T3_FIRMWARE_MAILBOX                0x0b50
-#define T3_MAGIC_NUM                       0x4B657654
-#define T3_MAGIC_NUM_DISABLE_DMAW_ON_LINK_CHANGE 0x4861764b
-
-#define T3_NIC_DATA_SIG_ADDR               0x0b54
-#define T3_NIC_DATA_SIG                    0x4b657654
-
-#define T3_NIC_DATA_NIC_CFG_ADDR           0x0b58
-#define T3_NIC_CFG_LED_MODE_UNKNOWN        BIT_NONE
-#define T3_NIC_CFG_LED_MODE_TRIPLE_SPEED   BIT_2
-#define T3_NIC_CFG_LED_MODE_LINK_SPEED     BIT_3
-#define T3_NIC_CFG_LED_MODE_OPEN_DRAIN     BIT_2
-#define T3_NIC_CFG_LED_MODE_OUTPUT         BIT_3
-#define T3_NIC_CFG_LED_MODE_MASK           (BIT_2 | BIT_3)
-#define T3_NIC_CFG_PHY_TYPE_UNKNOWN         BIT_NONE
-#define T3_NIC_CFG_PHY_TYPE_COPPER          BIT_4
-#define T3_NIC_CFG_PHY_TYPE_FIBER           BIT_5
-#define T3_NIC_CFG_PHY_TYPE_MASK            (BIT_4 | BIT_5)
-#define T3_NIC_CFG_ENABLE_WOL               BIT_6
-#define T3_NIC_CFG_ENABLE_ASF               BIT_7
-#define T3_NIC_EEPROM_WP                    BIT_8
-
-#define T3_NIC_DATA_PHY_ID_ADDR            0x0b74
-#define T3_NIC_PHY_ID1_MASK                0xffff0000
-#define T3_NIC_PHY_ID2_MASK                0x0000ffff
-
-#define T3_CMD_MAILBOX                      0x0b78
-#define T3_CMD_NICDRV_ALIVE                 0x01
-#define T3_CMD_NICDRV_PAUSE_FW              0x02
-#define T3_CMD_NICDRV_IPV4ADDR_CHANGE       0x03
-#define T3_CMD_NICDRV_IPV6ADDR_CHANGE       0x04
-#define T3_CMD_5703A0_FIX_DMAFW_DMAR        0x05
-#define T3_CMD_5703A0_FIX_DMAFW_DMAW        0x06
-
-#define T3_CMD_LENGTH_MAILBOX               0x0b7c
-#define T3_CMD_DATA_MAILBOX                 0x0b80
-
-#define T3_ASF_FW_STATUS_MAILBOX            0x0c00
-
-#define T3_DRV_STATE_MAILBOX                0x0c04
-#define T3_DRV_STATE_START                  0x01
-#define T3_DRV_STATE_UNLOAD                 0x02
-#define T3_DRV_STATE_WOL                    0x03
-#define T3_DRV_STATE_SUSPEND                0x04
-
-#define T3_FW_RESET_TYPE_MAILBOX            0x0c08
-
-#define T3_MAC_ADDR_HIGH_MAILBOX            0x0c14
-#define T3_MAC_ADDR_LOW_MAILBOX             0x0c18
-
-/******************************************************************************/
-/* Hardware constants. */
-/******************************************************************************/
-
-/* Number of entries in the send ring:  must be 512. */
-#define T3_SEND_RCB_ENTRY_COUNT             512
-#define T3_SEND_RCB_ENTRY_COUNT_MASK        (T3_SEND_RCB_ENTRY_COUNT-1)
-
-/* Number of send RCBs.  May be 1-16 but for now, only support one. */
-#define T3_MAX_SEND_RCB_COUNT               16
-
-/* Number of entries in the Standard Receive RCB.  Must be 512 entries. */
-#define T3_STD_RCV_RCB_ENTRY_COUNT          512
-#define T3_STD_RCV_RCB_ENTRY_COUNT_MASK     (T3_STD_RCV_RCB_ENTRY_COUNT-1)
-#define DEFAULT_STD_RCV_DESC_COUNT          200        /* Must be < 512. */
-#define MAX_STD_RCV_BUFFER_SIZE             0x600
-
-/* Number of entries in the Mini Receive RCB.  This value can either be */
-/* 0, 1024.  Currently Mini Receive RCB is disabled. */
-#ifndef T3_MINI_RCV_RCB_ENTRY_COUNT
-#define T3_MINI_RCV_RCB_ENTRY_COUNT         0
-#endif                         /* T3_MINI_RCV_RCB_ENTRY_COUNT */
-#define T3_MINI_RCV_RCB_ENTRY_COUNT_MASK    (T3_MINI_RCV_RCB_ENTRY_COUNT-1)
-#define MAX_MINI_RCV_BUFFER_SIZE            512
-#define DEFAULT_MINI_RCV_BUFFER_SIZE        64
-#define DEFAULT_MINI_RCV_DESC_COUNT         100        /* Must be < 1024. */
-
-/* Number of entries in the Jumbo Receive RCB.  This value must 256 or 0. */
-/* Currently, Jumbo Receive RCB is disabled. */
-#ifndef T3_JUMBO_RCV_RCB_ENTRY_COUNT
-#define T3_JUMBO_RCV_RCB_ENTRY_COUNT        0
-#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
-#define T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK   (T3_JUMBO_RCV_RCB_ENTRY_COUNT-1)
-
-#define MAX_JUMBO_RCV_BUFFER_SIZE           (10 * 1024)        /* > 1514 */
-#define DEFAULT_JUMBO_RCV_BUFFER_SIZE       (4 * 1024) /* > 1514 */
-#define DEFAULT_JUMBO_RCV_DESC_COUNT        128        /* Must be < 256. */
-
-#define MAX_JUMBO_TX_BUFFER_SIZE            (8 * 1024) /* > 1514 */
-#define DEFAULT_JUMBO_TX_BUFFER_SIZE        (4 * 1024) /* > 1514 */
-
-/* Number of receive return RCBs.  Maybe 1-16 but for now, only support one. */
-#define T3_MAX_RCV_RETURN_RCB_COUNT         16
-
-/* Number of entries in a Receive Return ring.  This value is either 1024 */
-/* or 2048. */
-#ifndef T3_RCV_RETURN_RCB_ENTRY_COUNT
-#define T3_RCV_RETURN_RCB_ENTRY_COUNT       1024
-#endif                         /* T3_RCV_RETURN_RCB_ENTRY_COUNT */
-#define T3_RCV_RETURN_RCB_ENTRY_COUNT_MASK  (T3_RCV_RETURN_RCB_ENTRY_COUNT-1)
-
-/* Default coalescing parameters. */
-#define DEFAULT_RX_COALESCING_TICKS         100
-#define MAX_RX_COALESCING_TICKS             500
-#define DEFAULT_TX_COALESCING_TICKS         400
-#define MAX_TX_COALESCING_TICKS             500
-#define DEFAULT_RX_MAX_COALESCED_FRAMES     10
-#define MAX_RX_MAX_COALESCED_FRAMES         100
-#define ADAPTIVE_LO_RX_MAX_COALESCED_FRAMES    5
-#define ADAPTIVE_HI_RX_MAX_COALESCED_FRAMES    42
-#define ADAPTIVE_LO_RX_COALESCING_TICKS         50
-#define ADAPTIVE_HI_RX_COALESCING_TICKS         300
-#define ADAPTIVE_LO_PKT_THRESH              30000
-#define ADAPTIVE_HI_PKT_THRESH              74000
-#define DEFAULT_TX_MAX_COALESCED_FRAMES     40
-#define ADAPTIVE_LO_TX_MAX_COALESCED_FRAMES    25
-#define ADAPTIVE_HI_TX_MAX_COALESCED_FRAMES    75
-#define MAX_TX_MAX_COALESCED_FRAMES         100
-
-#define DEFAULT_RX_COALESCING_TICKS_DURING_INT          25
-#define DEFAULT_TX_COALESCING_TICKS_DURING_INT          25
-#define DEFAULT_RX_MAX_COALESCED_FRAMES_DURING_INT      5
-#define DEFAULT_TX_MAX_COALESCED_FRAMES_DURING_INT      5
-
-#define BAD_DEFAULT_VALUE                               0xffffffff
-
-#define DEFAULT_STATS_COALESCING_TICKS      1000000
-#define MAX_STATS_COALESCING_TICKS          3600000000U
-
-/* Receive BD Replenish thresholds. */
-#define DEFAULT_RCV_STD_BD_REPLENISH_THRESHOLD      4
-#define DEFAULT_RCV_JUMBO_BD_REPLENISH_THRESHOLD    4
-
-#define SPLIT_MODE_DISABLE                          0
-#define SPLIT_MODE_ENABLE                           1
-
-#define SPLIT_MODE_5704_MAX_REQ                     3
-
-/* Maximum physical fragment size. */
-#define MAX_FRAGMENT_SIZE                   (64 * 1024)
-
-/* Standard view. */
-#define T3_STD_VIEW_SIZE                    (64 * 1024)
-#define T3_FLAT_VIEW_SIZE                   (32 * 1024 * 1024)
-
-/* Buffer descriptor base address on the NIC's memory. */
-
-#define T3_NIC_SND_BUFFER_DESC_ADDR         0x4000
-#define T3_NIC_STD_RCV_BUFFER_DESC_ADDR     0x6000
-#define T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR   0x7000
-
-#define T3_NIC_STD_RCV_BUFFER_DESC_ADDR_EXT_MEM     0xc000
-#define T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR_EXT_MEM   0xd000
-#define T3_NIC_MINI_RCV_BUFFER_DESC_ADDR_EXT_MEM    0xe000
-
-#define T3_NIC_SND_BUFFER_DESC_SIZE         (T3_SEND_RCB_ENTRY_COUNT * \
-                                           sizeof(T3_SND_BD) / 4)
-
-#define T3_NIC_STD_RCV_BUFFER_DESC_SIZE     (T3_STD_RCV_RCB_ENTRY_COUNT * \
-                                           sizeof(T3_RCV_BD) / 4)
-
-#define T3_NIC_JUMBO_RCV_BUFFER_DESC_SIZE   (T3_JUMBO_RCV_RCB_ENTRY_COUNT * \
-                                           sizeof(T3_EXT_RCV_BD) / 4)
-
-/* MBUF pool. */
-#define T3_NIC_MBUF_POOL_ADDR               0x8000
-/* #define T3_NIC_MBUF_POOL_SIZE               0x18000 */
-#define T3_NIC_MBUF_POOL_SIZE96             0x18000
-#define T3_NIC_MBUF_POOL_SIZE64             0x10000
-
-#define T3_NIC_MBUF_POOL_ADDR_EXT_MEM       0x20000
-
-/* DMA descriptor pool */
-#define T3_NIC_DMA_DESC_POOL_ADDR           0x2000
-#define T3_NIC_DMA_DESC_POOL_SIZE           0x2000     /* 8KB. */
-
-#define T3_DEF_DMA_MBUF_LOW_WMARK           0x40
-#define T3_DEF_RX_MAC_MBUF_LOW_WMARK        0x20
-#define T3_DEF_MBUF_HIGH_WMARK              0x60
-
-#define T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO     304
-#define T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO  152
-#define T3_DEF_MBUF_HIGH_WMARK_JUMBO        380
-
-#define T3_DEF_DMA_DESC_LOW_WMARK           5
-#define T3_DEF_DMA_DESC_HIGH_WMARK          10
-
-/* Maximum size of giant TCP packet can be sent */
-#define T3_TCP_SEG_MAX_OFFLOAD_SIZE         64*1000
-#define T3_TCP_SEG_MIN_NUM_SEG              20
-
-#define T3_RX_CPU_ID    0x1
-#define T3_TX_CPU_ID    0x2
-#define T3_RX_CPU_SPAD_ADDR  0x30000
-#define T3_RX_CPU_SPAD_SIZE  0x4000
-#define T3_TX_CPU_SPAD_ADDR  0x34000
-#define T3_TX_CPU_SPAD_SIZE  0x4000
-
-typedef struct T3_DIR_ENTRY {
-       PLM_UINT8 Buffer;
-       LM_UINT32 Offset;
-       LM_UINT32 Length;
-} T3_DIR_ENTRY, *PT3_DIR_ENTRY;
-
-typedef struct T3_FWIMG_INFO {
-       LM_UINT32 StartAddress;
-       T3_DIR_ENTRY Text;
-       T3_DIR_ENTRY ROnlyData;
-       T3_DIR_ENTRY Data;
-       T3_DIR_ENTRY Sbss;
-       T3_DIR_ENTRY Bss;
-} T3_FWIMG_INFO, *PT3_FWIMG_INFO;
-
-/******************************************************************************/
-/* Tigon3 PCI Registers. */
-/******************************************************************************/
-#define T3_PCI_ID_BCM5700                   0x164414e4
-#define T3_PCI_ID_BCM5701                   0x164514e4
-#define T3_PCI_ID_BCM5702                   0x164614e4
-#define T3_PCI_ID_BCM5702x                  0x16A614e4
-#define T3_PCI_ID_BCM5703                   0x164714e4
-#define T3_PCI_ID_BCM5703x                  0x16A714e4
-#define T3_PCI_ID_BCM5702FE                 0x164D14e4
-#define T3_PCI_ID_BCM5704                   0x164814e4
-
-#define T3_PCI_VENDOR_ID                    (T3_PCI_ID & 0xffff)
-#define T3_PCI_DEVICE_ID                    (T3_PCI_ID >> 16)
-
-#define T3_PCI_MISC_HOST_CTRL_REG           0x68
-
-/* The most significant 16bit of register 0x68. */
-/* ChipId:4, ChipRev:4, MetalRev:8 */
-#define T3_CHIP_ID_5700_A0                  0x7000
-#define T3_CHIP_ID_5700_A1                  0x7001
-#define T3_CHIP_ID_5700_B0                  0x7100
-#define T3_CHIP_ID_5700_B1                  0x7101
-#define T3_CHIP_ID_5700_C0                  0x7200
-
-#define T3_CHIP_ID_5701_A0                  0x0000
-#define T3_CHIP_ID_5701_B0                  0x0100
-#define T3_CHIP_ID_5701_B2                  0x0102
-#define T3_CHIP_ID_5701_B5                  0x0105
-
-#define T3_CHIP_ID_5703_A0                  0x1000
-#define T3_CHIP_ID_5703_A1                  0x1001
-#define T3_CHIP_ID_5703_A2                  0x1002
-
-#define T3_CHIP_ID_5704_A0                  0x2000
-
-/* Chip Id. */
-#define T3_ASIC_REV(_ChipRevId)             ((_ChipRevId) >> 12)
-#define T3_ASIC_REV_5700                    0x07
-#define T3_ASIC_REV_5701                    0x00
-#define T3_ASIC_REV_5703                    0x01
-#define T3_ASIC_REV_5704                    0x02
-
-/* Chip id and revision. */
-#define T3_CHIP_REV(_ChipRevId)             ((_ChipRevId) >> 8)
-#define T3_CHIP_REV_5700_AX                 0x70
-#define T3_CHIP_REV_5700_BX                 0x71
-#define T3_CHIP_REV_5700_CX                 0x72
-#define T3_CHIP_REV_5701_AX                 0x00
-
-/* Metal revision. */
-#define T3_METAL_REV(_ChipRevId)            ((_ChipRevId) & 0xff)
-#define T3_METAL_REV_A0                     0x00
-#define T3_METAL_REV_A1                     0x01
-#define T3_METAL_REV_B0                     0x00
-#define T3_METAL_REV_B1                     0x01
-#define T3_METAL_REV_B2                     0x02
-
-#define T3_PCI_REG_CLOCK_CTRL               0x74
-
-#define T3_PCI_DISABLE_RX_CLOCK             BIT_10
-#define T3_PCI_DISABLE_TX_CLOCK             BIT_11
-#define T3_PCI_SELECT_ALTERNATE_CLOCK       BIT_12
-#define T3_PCI_POWER_DOWN_PCI_PLL133        BIT_15
-#define T3_PCI_44MHZ_CORE_CLOCK             BIT_18
-
-#define T3_PCI_REG_ADDR_REG                 0x78
-#define T3_PCI_REG_DATA_REG                 0x80
-
-#define T3_PCI_MEM_WIN_ADDR_REG             0x7c
-#define T3_PCI_MEM_WIN_DATA_REG             0x84
-
-#define T3_PCI_PM_CAP_REG                   0x48
-
-#define T3_PCI_PM_CAP_PME_D3COLD            BIT_31
-#define T3_PCI_PM_CAP_PME_D3HOT             BIT_30
-
-#define T3_PCI_PM_STATUS_CTRL_REG           0x4c
-
-#define T3_PM_POWER_STATE_MASK              (BIT_0 | BIT_1)
-#define T3_PM_POWER_STATE_D0                BIT_NONE
-#define T3_PM_POWER_STATE_D1                BIT_0
-#define T3_PM_POWER_STATE_D2                BIT_1
-#define T3_PM_POWER_STATE_D3                (BIT_0 | BIT_1)
-
-#define T3_PM_PME_ENABLE                    BIT_8
-#define T3_PM_PME_ASSERTED                  BIT_15
-
-/* PCI state register. */
-#define T3_PCI_STATE_REG                    0x70
-
-#define T3_PCI_STATE_FORCE_RESET            BIT_0
-#define T3_PCI_STATE_INT_NOT_ACTIVE         BIT_1
-#define T3_PCI_STATE_CONVENTIONAL_PCI_MODE  BIT_2
-#define T3_PCI_STATE_BUS_SPEED_HIGH         BIT_3
-#define T3_PCI_STATE_32BIT_PCI_BUS          BIT_4
-
-/* Broadcom subsystem/subvendor IDs. */
-#define T3_SVID_BROADCOM                            0x14e4
-
-#define T3_SSID_BROADCOM_BCM95700A6                 0x1644
-#define T3_SSID_BROADCOM_BCM95701A5                 0x0001
-#define T3_SSID_BROADCOM_BCM95700T6                 0x0002     /* BCM8002 */
-#define T3_SSID_BROADCOM_BCM95700A9                 0x0003     /* Agilent */
-#define T3_SSID_BROADCOM_BCM95701T1                 0x0005
-#define T3_SSID_BROADCOM_BCM95701T8                 0x0006
-#define T3_SSID_BROADCOM_BCM95701A7                 0x0007     /* Agilent */
-#define T3_SSID_BROADCOM_BCM95701A10                0x0008
-#define T3_SSID_BROADCOM_BCM95701A12                0x8008
-#define T3_SSID_BROADCOM_BCM95703Ax1                0x0009
-#define T3_SSID_BROADCOM_BCM95703Ax2                0x8009
-
-/* 3COM subsystem/subvendor IDs. */
-#define T3_SVID_3COM                                0x10b7
-
-#define T3_SSID_3COM_3C996T                         0x1000
-#define T3_SSID_3COM_3C996BT                        0x1006
-#define T3_SSID_3COM_3C996CT                        0x1002
-#define T3_SSID_3COM_3C997T                         0x1003
-#define T3_SSID_3COM_3C1000T                        0x1007
-#define T3_SSID_3COM_3C940BR01                      0x1008
-
-/* Fiber boards. */
-#define T3_SSID_3COM_3C996SX                        0x1004
-#define T3_SSID_3COM_3C997SX                        0x1005
-
-/* Dell subsystem/subvendor IDs. */
-
-#define T3_SVID_DELL                                0x1028
-
-#define T3_SSID_DELL_VIPER                          0x00d1
-#define T3_SSID_DELL_JAGUAR                         0x0106
-#define T3_SSID_DELL_MERLOT                         0x0109
-#define T3_SSID_DELL_SLIM_MERLOT                    0x010a
-
-/* Compaq subsystem/subvendor IDs */
-
-#define T3_SVID_COMPAQ                              0x0e11
-
-#define T3_SSID_COMPAQ_BANSHEE                      0x007c
-#define T3_SSID_COMPAQ_BANSHEE_2                    0x009a
-#define T3_SSID_COMPAQ_CHANGELING                   0x007d
-#define T3_SSID_COMPAQ_NC7780                       0x0085
-#define T3_SSID_COMPAQ_NC7780_2                     0x0099
-
-/******************************************************************************/
-/* MII registers. */
-/******************************************************************************/
-
-/* Control register. */
-#define PHY_CTRL_REG                                0x00
-
-#define PHY_CTRL_SPEED_MASK                         (BIT_6 | BIT_13)
-#define PHY_CTRL_SPEED_SELECT_10MBPS                BIT_NONE
-#define PHY_CTRL_SPEED_SELECT_100MBPS               BIT_13
-#define PHY_CTRL_SPEED_SELECT_1000MBPS              BIT_6
-#define PHY_CTRL_COLLISION_TEST_ENABLE              BIT_7
-#define PHY_CTRL_FULL_DUPLEX_MODE                   BIT_8
-#define PHY_CTRL_RESTART_AUTO_NEG                   BIT_9
-#define PHY_CTRL_ISOLATE_PHY                        BIT_10
-#define PHY_CTRL_LOWER_POWER_MODE                   BIT_11
-#define PHY_CTRL_AUTO_NEG_ENABLE                    BIT_12
-#define PHY_CTRL_LOOPBACK_MODE                      BIT_14
-#define PHY_CTRL_PHY_RESET                          BIT_15
-
-/* Status register. */
-#define PHY_STATUS_REG                              0x01
-
-#define PHY_STATUS_LINK_PASS                        BIT_2
-#define PHY_STATUS_AUTO_NEG_COMPLETE                BIT_5
-
-/* Phy Id registers. */
-#define PHY_ID1_REG                                 0x02
-#define PHY_ID1_OUI_MASK                            0xffff
-
-#define PHY_ID2_REG                                 0x03
-#define PHY_ID2_REV_MASK                            0x000f
-#define PHY_ID2_MODEL_MASK                          0x03f0
-#define PHY_ID2_OUI_MASK                            0xfc00
-
-/* Auto-negotiation advertisement register. */
-#define PHY_AN_AD_REG                               0x04
-
-#define PHY_AN_AD_ASYM_PAUSE                        BIT_11
-#define PHY_AN_AD_PAUSE_CAPABLE                     BIT_10
-#define PHY_AN_AD_10BASET_HALF                      BIT_5
-#define PHY_AN_AD_10BASET_FULL                      BIT_6
-#define PHY_AN_AD_100BASETX_HALF                    BIT_7
-#define PHY_AN_AD_100BASETX_FULL                    BIT_8
-#define PHY_AN_AD_PROTOCOL_802_3_CSMA_CD            0x01
-
-/* Auto-negotiation Link Partner Ability register. */
-#define PHY_LINK_PARTNER_ABILITY_REG                0x05
-
-#define PHY_LINK_PARTNER_ASYM_PAUSE                 BIT_11
-#define PHY_LINK_PARTNER_PAUSE_CAPABLE              BIT_10
-
-/* Auto-negotiation expansion register. */
-#define PHY_AN_EXPANSION_REG                        0x06
-
-/******************************************************************************/
-/* BCM5400 and BCM5401 phy info. */
-/******************************************************************************/
-
-#define PHY_DEVICE_ID           1
-
-/* OUI: bit 31-10;   Model#: bit 9-4;   Rev# bit 3-0. */
-#define PHY_UNKNOWN_PHY                             0x00000000
-#define PHY_BCM5400_PHY_ID                          0x60008040
-#define PHY_BCM5401_PHY_ID                          0x60008050
-#define PHY_BCM5411_PHY_ID                          0x60008070
-#define PHY_BCM5701_PHY_ID                          0x60008110
-#define PHY_BCM5703_PHY_ID                          0x60008160
-#define PHY_BCM5704_PHY_ID                          0x60008190
-#define PHY_BCM8002_PHY_ID                          0x60010140
-
-#define PHY_BCM5401_B0_REV                          0x1
-#define PHY_BCM5401_B2_REV                          0x3
-#define PHY_BCM5401_C0_REV                          0x6
-
-#define PHY_ID_OUI_MASK                             0xfffffc00
-#define PHY_ID_MODEL_MASK                           0x000003f0
-#define PHY_ID_REV_MASK                             0x0000000f
-#define PHY_ID_MASK                                 (PHY_ID_OUI_MASK |      \
-                                                   PHY_ID_MODEL_MASK)
-
-#define UNKNOWN_PHY_ID(x)   ((((x) & PHY_ID_MASK) != PHY_BCM5400_PHY_ID) && \
-                           (((x) & PHY_ID_MASK) != PHY_BCM5401_PHY_ID) && \
-                           (((x) & PHY_ID_MASK) != PHY_BCM5411_PHY_ID) && \
-                           (((x) & PHY_ID_MASK) != PHY_BCM5701_PHY_ID) && \
-                           (((x) & PHY_ID_MASK) != PHY_BCM5703_PHY_ID) && \
-                           (((x) & PHY_ID_MASK) != PHY_BCM5704_PHY_ID) && \
-                           (((x) & PHY_ID_MASK) != PHY_BCM8002_PHY_ID))
-
-/* 1000Base-T control register. */
-#define BCM540X_1000BASET_CTRL_REG                  0x09
-
-#define BCM540X_AN_AD_1000BASET_HALF                BIT_8
-#define BCM540X_AN_AD_1000BASET_FULL                BIT_9
-#define BCM540X_CONFIG_AS_MASTER                    BIT_11
-#define BCM540X_ENABLE_CONFIG_AS_MASTER             BIT_12
-
-/* Extended control register. */
-#define BCM540X_EXT_CTRL_REG                        0x10
-
-#define BCM540X_EXT_CTRL_LINK3_LED_MODE             BIT_1
-#define BCM540X_EXT_CTRL_TBI                        BIT_15
-
-/* PHY extended status register. */
-#define BCM540X_EXT_STATUS_REG                      0x11
-
-#define BCM540X_EXT_STATUS_LINK_PASS                BIT_8
-
-/* DSP Coefficient Read/Write Port. */
-#define BCM540X_DSP_RW_PORT                         0x15
-
-/* DSP Coeficient Address Register. */
-#define BCM540X_DSP_ADDRESS_REG                     0x17
-
-#define BCM540X_DSP_TAP_NUMBER_MASK                 0x00
-#define BCM540X_DSP_AGC_A                           0x00
-#define BCM540X_DSP_AGC_B                           0x01
-#define BCM540X_DSP_MSE_PAIR_STATUS                 0x02
-#define BCM540X_DSP_SOFT_DECISION                   0x03
-#define BCM540X_DSP_PHASE_REG                       0x04
-#define BCM540X_DSP_SKEW                            0x05
-#define BCM540X_DSP_POWER_SAVER_UPPER_BOUND         0x06
-#define BCM540X_DSP_POWER_SAVER_LOWER_BOUND         0x07
-#define BCM540X_DSP_LAST_ECHO                       0x08
-#define BCM540X_DSP_FREQUENCY                       0x09
-#define BCM540X_DSP_PLL_BANDWIDTH                   0x0a
-#define BCM540X_DSP_PLL_PHASE_OFFSET                0x0b
-
-#define BCM540X_DSP_FILTER_DCOFFSET                 (BIT_10 | BIT_11)
-#define BCM540X_DSP_FILTER_FEXT3                    (BIT_8 | BIT_9 | BIT_11)
-#define BCM540X_DSP_FILTER_FEXT2                    (BIT_9 | BIT_11)
-#define BCM540X_DSP_FILTER_FEXT1                    (BIT_8 | BIT_11)
-#define BCM540X_DSP_FILTER_FEXT0                    BIT_11
-#define BCM540X_DSP_FILTER_NEXT3                    (BIT_8 | BIT_9 | BIT_10)
-#define BCM540X_DSP_FILTER_NEXT2                    (BIT_9 | BIT_10)
-#define BCM540X_DSP_FILTER_NEXT1                    (BIT_8 | BIT_10)
-#define BCM540X_DSP_FILTER_NEXT0                    BIT_10
-#define BCM540X_DSP_FILTER_ECHO                     (BIT_8 | BIT_9)
-#define BCM540X_DSP_FILTER_DFE                      BIT_9
-#define BCM540X_DSP_FILTER_FFE                      BIT_8
-
-#define BCM540X_DSP_CONTROL_ALL_FILTERS             BIT_12
-
-#define BCM540X_DSP_SEL_CH_0                        BIT_NONE
-#define BCM540X_DSP_SEL_CH_1                        BIT_13
-#define BCM540X_DSP_SEL_CH_2                        BIT_14
-#define BCM540X_DSP_SEL_CH_3                        (BIT_13 | BIT_14)
-
-#define BCM540X_CONTROL_ALL_CHANNELS                BIT_15
-
-/* Auxilliary Control Register (Shadow Register) */
-#define BCM5401_AUX_CTRL                            0x18
-
-#define BCM5401_SHADOW_SEL_MASK                     0x7
-#define BCM5401_SHADOW_SEL_NORMAL                   0x00
-#define BCM5401_SHADOW_SEL_10BASET                  0x01
-#define BCM5401_SHADOW_SEL_POWER_CONTROL            0x02
-#define BCM5401_SHADOW_SEL_IP_PHONE                 0x03
-#define BCM5401_SHADOW_SEL_MISC_TEST1               0x04
-#define BCM5401_SHADOW_SEL_MISC_TEST2               0x05
-#define BCM5401_SHADOW_SEL_IP_PHONE_SEED            0x06
-
-/* Shadow register selector == '000' */
-#define BCM5401_SHDW_NORMAL_DIAG_MODE               BIT_3
-#define BCM5401_SHDW_NORMAL_DISABLE_MBP             BIT_4
-#define BCM5401_SHDW_NORMAL_DISABLE_LOW_PWR         BIT_5
-#define BCM5401_SHDW_NORMAL_DISABLE_INV_PRF         BIT_6
-#define BCM5401_SHDW_NORMAL_DISABLE_PRF             BIT_7
-#define BCM5401_SHDW_NORMAL_RX_SLICING_NORMAL       BIT_NONE
-#define BCM5401_SHDW_NORMAL_RX_SLICING_4D           BIT_8
-#define BCM5401_SHDW_NORMAL_RX_SLICING_3LVL_1D      BIT_9
-#define BCM5401_SHDW_NORMAL_RX_SLICING_5LVL_1D      (BIT_8 | BIT_9)
-#define BCM5401_SHDW_NORMAL_TX_6DB_CODING           BIT_10
-#define BCM5401_SHDW_NORMAL_ENABLE_SM_DSP_CLOCK     BIT_11
-#define BCM5401_SHDW_NORMAL_EDGERATE_CTRL_4NS       BIT_NONE
-#define BCM5401_SHDW_NORMAL_EDGERATE_CTRL_5NS       BIT_12
-#define BCM5401_SHDW_NORMAL_EDGERATE_CTRL_3NS       BIT_13
-#define BCM5401_SHDW_NORMAL_EDGERATE_CTRL_0NS       (BIT_12 | BIT_13)
-#define BCM5401_SHDW_NORMAL_EXT_PACKET_LENGTH       BIT_14
-#define BCM5401_SHDW_NORMAL_EXTERNAL_LOOPBACK       BIT_15
-
-/* Auxilliary status summary. */
-#define BCM540X_AUX_STATUS_REG                      0x19
-
-#define BCM540X_AUX_LINK_PASS                       BIT_2
-#define BCM540X_AUX_SPEED_MASK                      (BIT_8 | BIT_9 | BIT_10)
-#define BCM540X_AUX_10BASET_HD                      BIT_8
-#define BCM540X_AUX_10BASET_FD                      BIT_9
-#define BCM540X_AUX_100BASETX_HD                    (BIT_8 | BIT_9)
-#define BCM540X_AUX_100BASET4                       BIT_10
-#define BCM540X_AUX_100BASETX_FD                    (BIT_8 | BIT_10)
-#define BCM540X_AUX_100BASET_HD                     (BIT_9 | BIT_10)
-#define BCM540X_AUX_100BASET_FD                     (BIT_8 | BIT_9 | BIT_10)
-
-/* Interrupt status. */
-#define BCM540X_INT_STATUS_REG                      0x1a
-
-#define BCM540X_INT_LINK_CHANGE                     BIT_1
-#define BCM540X_INT_SPEED_CHANGE                    BIT_2
-#define BCM540X_INT_DUPLEX_CHANGE                   BIT_3
-#define BCM540X_INT_AUTO_NEG_PAGE_RX                BIT_10
-
-/* Interrupt mask register. */
-#define BCM540X_INT_MASK_REG                        0x1b
-
-/******************************************************************************/
-/* Register definitions. */
-/******************************************************************************/
-
-typedef volatile LM_UINT8 T3_8BIT_REGISTER, *PT3_8BIT_REGISTER;
-typedef volatile LM_UINT16 T3_16BIT_REGISTER, *PT3_16BIT_REGISTER;
-typedef volatile LM_UINT32 T3_32BIT_REGISTER, *PT3_32BIT_REGISTER;
-
-typedef struct {
-       /* Big endian format. */
-       T3_32BIT_REGISTER High;
-       T3_32BIT_REGISTER Low;
-} T3_64BIT_REGISTER, *PT3_64BIT_REGISTER;
-
-typedef T3_64BIT_REGISTER T3_64BIT_HOST_ADDR, *PT3_64BIT_HOST_ADDR;
-
-#define T3_NUM_OF_DMA_DESC    256
-#define T3_NUM_OF_MBUF        768
-
-typedef struct {
-       T3_64BIT_REGISTER host_addr;
-       T3_32BIT_REGISTER nic_mbuf;
-       T3_16BIT_REGISTER len;
-       T3_16BIT_REGISTER cqid_sqid;
-       T3_32BIT_REGISTER flags;
-       T3_32BIT_REGISTER opaque1;
-       T3_32BIT_REGISTER opaque2;
-       T3_32BIT_REGISTER opaque3;
-} T3_DMA_DESC, *PT3_DMA_DESC;
-
-/******************************************************************************/
-/* Ring control block. */
-/******************************************************************************/
-
-typedef struct {
-       T3_64BIT_REGISTER HostRingAddr;
-
-       union {
-               struct {
-#ifdef BIG_ENDIAN_HOST
-                       T3_16BIT_REGISTER MaxLen;
-                       T3_16BIT_REGISTER Flags;
-#else                          /* BIG_ENDIAN_HOST */
-                       T3_16BIT_REGISTER Flags;
-                       T3_16BIT_REGISTER MaxLen;
-#endif
-               } s;
-
-               T3_32BIT_REGISTER MaxLen_Flags;
-       } u;
-
-       T3_32BIT_REGISTER NicRingAddr;
-} T3_RCB, *PT3_RCB;
-
-#define T3_RCB_FLAG_USE_EXT_RECV_BD                     BIT_0
-#define T3_RCB_FLAG_RING_DISABLED                       BIT_1
-
-/******************************************************************************/
-/* Status block. */
-/******************************************************************************/
-
-/*
- * Size of status block is actually 0x50 bytes.  Use 0x80 bytes for
- * cache line alignment.
- */
-#define T3_STATUS_BLOCK_SIZE                                    0x80
-
-typedef struct {
-       volatile LM_UINT32 Status;
-#define STATUS_BLOCK_UPDATED                                BIT_0
-#define STATUS_BLOCK_LINK_CHANGED_STATUS                    BIT_1
-#define STATUS_BLOCK_ERROR                                  BIT_2
-
-       volatile LM_UINT32 StatusTag;
-
-#ifdef BIG_ENDIAN_HOST
-       volatile LM_UINT16 RcvStdConIdx;
-       volatile LM_UINT16 RcvJumboConIdx;
-
-       volatile LM_UINT16 Reserved2;
-       volatile LM_UINT16 RcvMiniConIdx;
-
-       struct {
-               volatile LM_UINT16 SendConIdx;  /* Send consumer index. */
-               volatile LM_UINT16 RcvProdIdx;  /* Receive producer index. */
-       } Idx[16];
-#else                          /* BIG_ENDIAN_HOST */
-       volatile LM_UINT16 RcvJumboConIdx;
-       volatile LM_UINT16 RcvStdConIdx;
-
-       volatile LM_UINT16 RcvMiniConIdx;
-       volatile LM_UINT16 Reserved2;
-
-       struct {
-               volatile LM_UINT16 RcvProdIdx;  /* Receive producer index. */
-               volatile LM_UINT16 SendConIdx;  /* Send consumer index. */
-       } Idx[16];
-#endif
-} T3_STATUS_BLOCK, *PT3_STATUS_BLOCK;
-
-/******************************************************************************/
-/* Receive buffer descriptors. */
-/******************************************************************************/
-
-typedef struct {
-       T3_64BIT_HOST_ADDR HostAddr;
-
-#ifdef BIG_ENDIAN_HOST
-       volatile LM_UINT16 Index;
-       volatile LM_UINT16 Len;
-
-       volatile LM_UINT16 Type;
-       volatile LM_UINT16 Flags;
-
-       volatile LM_UINT16 IpCksum;
-       volatile LM_UINT16 TcpUdpCksum;
-
-       volatile LM_UINT16 ErrorFlag;
-       volatile LM_UINT16 VlanTag;
-#else                          /* BIG_ENDIAN_HOST */
-       volatile LM_UINT16 Len;
-       volatile LM_UINT16 Index;
-
-       volatile LM_UINT16 Flags;
-       volatile LM_UINT16 Type;
-
-       volatile LM_UINT16 TcpUdpCksum;
-       volatile LM_UINT16 IpCksum;
-
-       volatile LM_UINT16 VlanTag;
-       volatile LM_UINT16 ErrorFlag;
-#endif
-
-       volatile LM_UINT32 Reserved;
-       volatile LM_UINT32 Opaque;
-} T3_RCV_BD, *PT3_RCV_BD;
-
-typedef struct {
-       T3_64BIT_HOST_ADDR HostAddr[3];
-
-#ifdef BIG_ENDIAN_HOST
-       LM_UINT16 Len1;
-       LM_UINT16 Len2;
-
-       LM_UINT16 Len3;
-       LM_UINT16 Reserved1;
-#else                          /* BIG_ENDIAN_HOST */
-       LM_UINT16 Len2;
-       LM_UINT16 Len1;
-
-       LM_UINT16 Reserved1;
-       LM_UINT16 Len3;
-#endif
-
-       T3_RCV_BD StdRcvBd;
-} T3_EXT_RCV_BD, *PT3_EXT_RCV_BD;
-
-/* Error flags. */
-#define RCV_BD_ERR_BAD_CRC                          0x0001
-#define RCV_BD_ERR_COLL_DETECT                      0x0002
-#define RCV_BD_ERR_LINK_LOST_DURING_PKT             0x0004
-#define RCV_BD_ERR_PHY_DECODE_ERR                   0x0008
-#define RCV_BD_ERR_ODD_NIBBLED_RCVD_MII             0x0010
-#define RCV_BD_ERR_MAC_ABORT                        0x0020
-#define RCV_BD_ERR_LEN_LT_64                        0x0040
-#define RCV_BD_ERR_TRUNC_NO_RESOURCES               0x0080
-#define RCV_BD_ERR_GIANT_FRAME_RCVD                 0x0100
-
-/* Buffer descriptor flags. */
-#define RCV_BD_FLAG_END                             0x0004
-#define RCV_BD_FLAG_JUMBO_RING                      0x0020
-#define RCV_BD_FLAG_VLAN_TAG                        0x0040
-#define RCV_BD_FLAG_FRAME_HAS_ERROR                 0x0400
-#define RCV_BD_FLAG_MINI_RING                       0x0800
-#define RCV_BD_FLAG_IP_CHKSUM_FIELD                 0x1000
-#define RCV_BD_FLAG_TCP_UDP_CHKSUM_FIELD            0x2000
-#define RCV_BD_FLAG_TCP_PACKET                      0x4000
-
-/******************************************************************************/
-/* Send buffer descriptor. */
-/******************************************************************************/
-
-typedef struct {
-       T3_64BIT_HOST_ADDR HostAddr;
-
-       union {
-               struct {
-#ifdef BIG_ENDIAN_HOST
-                       LM_UINT16 Len;
-                       LM_UINT16 Flags;
-#else                          /* BIG_ENDIAN_HOST */
-                       LM_UINT16 Flags;
-                       LM_UINT16 Len;
-#endif
-               } s1;
-
-               LM_UINT32 Len_Flags;
-       } u1;
-
-       union {
-               struct {
-#ifdef BIG_ENDIAN_HOST
-                       LM_UINT16 Reserved;
-                       LM_UINT16 VlanTag;
-#else                          /* BIG_ENDIAN_HOST */
-                       LM_UINT16 VlanTag;
-                       LM_UINT16 Reserved;
-#endif
-               } s2;
-
-               LM_UINT32 VlanTag;
-       } u2;
-} T3_SND_BD, *PT3_SND_BD;
-
-/* Send buffer descriptor flags. */
-#define SND_BD_FLAG_TCP_UDP_CKSUM                   0x0001
-#define SND_BD_FLAG_IP_CKSUM                        0x0002
-#define SND_BD_FLAG_END                             0x0004
-#define SND_BD_FLAG_IP_FRAG                         0x0008
-#define SND_BD_FLAG_IP_FRAG_END                     0x0010
-#define SND_BD_FLAG_VLAN_TAG                        0x0040
-#define SND_BD_FLAG_COAL_NOW                        0x0080
-#define SND_BD_FLAG_CPU_PRE_DMA                     0x0100
-#define SND_BD_FLAG_CPU_POST_DMA                    0x0200
-#define SND_BD_FLAG_INSERT_SRC_ADDR                 0x1000
-#define SND_BD_FLAG_CHOOSE_SRC_ADDR                 0x6000
-#define SND_BD_FLAG_DONT_GEN_CRC                    0x8000
-
-/* MBUFs */
-typedef struct T3_MBUF_FRAME_DESC {
-#ifdef BIG_ENDIAN_HOST
-       LM_UINT32 status_control;
-       union {
-               struct {
-                       LM_UINT8 cqid;
-                       LM_UINT8 reserved1;
-                       LM_UINT16 length;
-               } s1;
-               LM_UINT32 word;
-       } u1;
-       union {
-               struct {
-                       LM_UINT16 ip_hdr_start;
-                       LM_UINT16 tcp_udp_hdr_start;
-               } s2;
-
-               LM_UINT32 word;
-       } u2;
-
-       union {
-               struct {
-                       LM_UINT16 data_start;
-                       LM_UINT16 vlan_id;
-               } s3;
-
-               LM_UINT32 word;
-       } u3;
-
-       union {
-               struct {
-                       LM_UINT16 ip_checksum;
-                       LM_UINT16 tcp_udp_checksum;
-               } s4;
-
-               LM_UINT32 word;
-       } u4;
-
-       union {
-               struct {
-                       LM_UINT16 pseudo_checksum;
-                       LM_UINT16 checksum_status;
-               } s5;
-
-               LM_UINT32 word;
-       } u5;
-
-       union {
-               struct {
-                       LM_UINT16 rule_match;
-                       LM_UINT8 class;
-                       LM_UINT8 rupt;
-               } s6;
-
-               LM_UINT32 word;
-       } u6;
-
-       union {
-               struct {
-                       LM_UINT16 reserved2;
-                       LM_UINT16 mbuf_num;
-               } s7;
-
-               LM_UINT32 word;
-       } u7;
-
-       LM_UINT32 reserved3;
-       LM_UINT32 reserved4;
-#else
-       LM_UINT32 status_control;
-       union {
-               struct {
-                       LM_UINT16 length;
-                       LM_UINT8 reserved1;
-                       LM_UINT8 cqid;
-               } s1;
-               LM_UINT32 word;
-       } u1;
-       union {
-               struct {
-                       LM_UINT16 tcp_udp_hdr_start;
-                       LM_UINT16 ip_hdr_start;
-               } s2;
-
-               LM_UINT32 word;
-       } u2;
-
-       union {
-               struct {
-                       LM_UINT16 vlan_id;
-                       LM_UINT16 data_start;
-               } s3;
-
-               LM_UINT32 word;
-       } u3;
-
-       union {
-               struct {
-                       LM_UINT16 tcp_udp_checksum;
-                       LM_UINT16 ip_checksum;
-               } s4;
-
-               LM_UINT32 word;
-       } u4;
-
-       union {
-               struct {
-                       LM_UINT16 checksum_status;
-                       LM_UINT16 pseudo_checksum;
-               } s5;
-
-               LM_UINT32 word;
-       } u5;
-
-       union {
-               struct {
-                       LM_UINT8 rupt;
-                       LM_UINT8 class;
-                       LM_UINT16 rule_match;
-               } s6;
-
-               LM_UINT32 word;
-       } u6;
-
-       union {
-               struct {
-                       LM_UINT16 mbuf_num;
-                       LM_UINT16 reserved2;
-               } s7;
-
-               LM_UINT32 word;
-       } u7;
-
-       LM_UINT32 reserved3;
-       LM_UINT32 reserved4;
-#endif
-} T3_MBUF_FRAME_DESC, *PT3_MBUF_FRAME_DESC;
-
-typedef struct T3_MBUF_HDR {
-       union {
-               struct {
-                       unsigned int C:1;
-                       unsigned int F:1;
-                       unsigned int reserved1:7;
-                       unsigned int next_mbuf:16;
-                       unsigned int length:7;
-               } s1;
-
-               LM_UINT32 word;
-       } u1;
-
-       LM_UINT32 next_frame_ptr;
-} T3_MBUF_HDR, *PT3_MBUF_HDR;
-
-typedef struct T3_MBUF {
-       T3_MBUF_HDR hdr;
-       union {
-               struct {
-                       T3_MBUF_FRAME_DESC frame_hdr;
-                       LM_UINT32 data[20];
-               } s1;
-
-               struct {
-                       LM_UINT32 data[30];
-               } s2;
-       } body;
-} T3_MBUF, *PT3_MBUF;
-
-#define T3_MBUF_BASE   (T3_NIC_MBUF_POOL_ADDR >> 7)
-#define T3_MBUF_END    ((T3_NIC_MBUF_POOL_ADDR + T3_NIC_MBUF_POOL_SIZE) >> 7)
-
-/******************************************************************************/
-/* Statistics block. */
-/******************************************************************************/
-
-typedef struct {
-       LM_UINT8 Reserved0[0x400 - 0x300];
-
-       /* Statistics maintained by Receive MAC. */
-       T3_64BIT_REGISTER ifHCInOctets;
-       T3_64BIT_REGISTER Reserved1;
-       T3_64BIT_REGISTER etherStatsFragments;
-       T3_64BIT_REGISTER ifHCInUcastPkts;
-       T3_64BIT_REGISTER ifHCInMulticastPkts;
-       T3_64BIT_REGISTER ifHCInBroadcastPkts;
-       T3_64BIT_REGISTER dot3StatsFCSErrors;
-       T3_64BIT_REGISTER dot3StatsAlignmentErrors;
-       T3_64BIT_REGISTER xonPauseFramesReceived;
-       T3_64BIT_REGISTER xoffPauseFramesReceived;
-       T3_64BIT_REGISTER macControlFramesReceived;
-       T3_64BIT_REGISTER xoffStateEntered;
-       T3_64BIT_REGISTER dot3StatsFramesTooLong;
-       T3_64BIT_REGISTER etherStatsJabbers;
-       T3_64BIT_REGISTER etherStatsUndersizePkts;
-       T3_64BIT_REGISTER inRangeLengthError;
-       T3_64BIT_REGISTER outRangeLengthError;
-       T3_64BIT_REGISTER etherStatsPkts64Octets;
-       T3_64BIT_REGISTER etherStatsPkts65Octetsto127Octets;
-       T3_64BIT_REGISTER etherStatsPkts128Octetsto255Octets;
-       T3_64BIT_REGISTER etherStatsPkts256Octetsto511Octets;
-       T3_64BIT_REGISTER etherStatsPkts512Octetsto1023Octets;
-       T3_64BIT_REGISTER etherStatsPkts1024Octetsto1522Octets;
-       T3_64BIT_REGISTER etherStatsPkts1523Octetsto2047Octets;
-       T3_64BIT_REGISTER etherStatsPkts2048Octetsto4095Octets;
-       T3_64BIT_REGISTER etherStatsPkts4096Octetsto8191Octets;
-       T3_64BIT_REGISTER etherStatsPkts8192Octetsto9022Octets;
-
-       T3_64BIT_REGISTER Unused1[37];
-
-       /* Statistics maintained by Transmit MAC. */
-       T3_64BIT_REGISTER ifHCOutOctets;
-       T3_64BIT_REGISTER Reserved2;
-       T3_64BIT_REGISTER etherStatsCollisions;
-       T3_64BIT_REGISTER outXonSent;
-       T3_64BIT_REGISTER outXoffSent;
-       T3_64BIT_REGISTER flowControlDone;
-       T3_64BIT_REGISTER dot3StatsInternalMacTransmitErrors;
-       T3_64BIT_REGISTER dot3StatsSingleCollisionFrames;
-       T3_64BIT_REGISTER dot3StatsMultipleCollisionFrames;
-       T3_64BIT_REGISTER dot3StatsDeferredTransmissions;
-       T3_64BIT_REGISTER Reserved3;
-       T3_64BIT_REGISTER dot3StatsExcessiveCollisions;
-       T3_64BIT_REGISTER dot3StatsLateCollisions;
-       T3_64BIT_REGISTER dot3Collided2Times;
-       T3_64BIT_REGISTER dot3Collided3Times;
-       T3_64BIT_REGISTER dot3Collided4Times;
-       T3_64BIT_REGISTER dot3Collided5Times;
-       T3_64BIT_REGISTER dot3Collided6Times;
-       T3_64BIT_REGISTER dot3Collided7Times;
-       T3_64BIT_REGISTER dot3Collided8Times;
-       T3_64BIT_REGISTER dot3Collided9Times;
-       T3_64BIT_REGISTER dot3Collided10Times;
-       T3_64BIT_REGISTER dot3Collided11Times;
-       T3_64BIT_REGISTER dot3Collided12Times;
-       T3_64BIT_REGISTER dot3Collided13Times;
-       T3_64BIT_REGISTER dot3Collided14Times;
-       T3_64BIT_REGISTER dot3Collided15Times;
-       T3_64BIT_REGISTER ifHCOutUcastPkts;
-       T3_64BIT_REGISTER ifHCOutMulticastPkts;
-       T3_64BIT_REGISTER ifHCOutBroadcastPkts;
-       T3_64BIT_REGISTER dot3StatsCarrierSenseErrors;
-       T3_64BIT_REGISTER ifOutDiscards;
-       T3_64BIT_REGISTER ifOutErrors;
-
-       T3_64BIT_REGISTER Unused2[31];
-
-       /* Statistics maintained by Receive List Placement. */
-       T3_64BIT_REGISTER COSIfHCInPkts[16];
-       T3_64BIT_REGISTER COSFramesDroppedDueToFilters;
-       T3_64BIT_REGISTER nicDmaWriteQueueFull;
-       T3_64BIT_REGISTER nicDmaWriteHighPriQueueFull;
-       T3_64BIT_REGISTER nicNoMoreRxBDs;
-       T3_64BIT_REGISTER ifInDiscards;
-       T3_64BIT_REGISTER ifInErrors;
-       T3_64BIT_REGISTER nicRecvThresholdHit;
-
-       T3_64BIT_REGISTER Unused3[9];
-
-       /* Statistics maintained by Send Data Initiator. */
-       T3_64BIT_REGISTER COSIfHCOutPkts[16];
-       T3_64BIT_REGISTER nicDmaReadQueueFull;
-       T3_64BIT_REGISTER nicDmaReadHighPriQueueFull;
-       T3_64BIT_REGISTER nicSendDataCompQueueFull;
-
-       /* Statistics maintained by Host Coalescing. */
-       T3_64BIT_REGISTER nicRingSetSendProdIndex;
-       T3_64BIT_REGISTER nicRingStatusUpdate;
-       T3_64BIT_REGISTER nicInterrupts;
-       T3_64BIT_REGISTER nicAvoidedInterrupts;
-       T3_64BIT_REGISTER nicSendThresholdHit;
-
-       LM_UINT8 Reserved4[0xb00 - 0x9c0];
-} T3_STATS_BLOCK, *PT3_STATS_BLOCK;
-
-/******************************************************************************/
-/* PCI configuration registers. */
-/******************************************************************************/
-
-typedef struct {
-       T3_16BIT_REGISTER VendorId;
-       T3_16BIT_REGISTER DeviceId;
-
-       T3_16BIT_REGISTER Command;
-       T3_16BIT_REGISTER Status;
-
-       T3_32BIT_REGISTER ClassCodeRevId;
-
-       T3_8BIT_REGISTER CacheLineSize;
-       T3_8BIT_REGISTER LatencyTimer;
-       T3_8BIT_REGISTER HeaderType;
-       T3_8BIT_REGISTER Bist;
-
-       T3_32BIT_REGISTER MemBaseAddrLow;
-       T3_32BIT_REGISTER MemBaseAddrHigh;
-
-       LM_UINT8 Unused1[20];
-
-       T3_16BIT_REGISTER SubsystemVendorId;
-       T3_16BIT_REGISTER SubsystemId;
-
-       T3_32BIT_REGISTER RomBaseAddr;
-
-       T3_8BIT_REGISTER PciXCapiblityPtr;
-       LM_UINT8 Unused2[7];
-
-       T3_8BIT_REGISTER IntLine;
-       T3_8BIT_REGISTER IntPin;
-       T3_8BIT_REGISTER MinGnt;
-       T3_8BIT_REGISTER MaxLat;
-
-       T3_8BIT_REGISTER PciXCapabilities;
-       T3_8BIT_REGISTER PmCapabilityPtr;
-       T3_16BIT_REGISTER PciXCommand;
-
-       T3_32BIT_REGISTER PciXStatus;
-
-       T3_8BIT_REGISTER PmCapabilityId;
-       T3_8BIT_REGISTER VpdCapabilityPtr;
-       T3_16BIT_REGISTER PmCapabilities;
-
-       T3_16BIT_REGISTER PmCtrlStatus;
-#define PM_CTRL_PME_STATUS            BIT_15
-#define PM_CTRL_PME_ENABLE            BIT_8
-#define PM_CTRL_PME_POWER_STATE_D0    0
-#define PM_CTRL_PME_POWER_STATE_D1    1
-#define PM_CTRL_PME_POWER_STATE_D2    2
-#define PM_CTRL_PME_POWER_STATE_D3H   3
-
-       T3_8BIT_REGISTER BridgeSupportExt;
-       T3_8BIT_REGISTER PmData;
-
-       T3_8BIT_REGISTER VpdCapabilityId;
-       T3_8BIT_REGISTER MsiCapabilityPtr;
-       T3_16BIT_REGISTER VpdAddrFlag;
-#define VPD_FLAG_WRITE      (1 << 15)
-#define VPD_FLAG_RW_MASK    (1 << 15)
-#define VPD_FLAG_READ       0
-
-       T3_32BIT_REGISTER VpdData;
-
-       T3_8BIT_REGISTER MsiCapabilityId;
-       T3_8BIT_REGISTER NextCapabilityPtr;
-       T3_16BIT_REGISTER MsiCtrl;
-#define MSI_CTRL_64BIT_CAP     (1 << 7)
-#define MSI_CTRL_MSG_ENABLE(x) (x << 4)
-#define MSI_CTRL_MSG_CAP(x)    (x << 1)
-#define MSI_CTRL_ENABLE        (1 << 0)
-
-       T3_32BIT_REGISTER MsiAddrLow;
-       T3_32BIT_REGISTER MsiAddrHigh;
-
-       T3_16BIT_REGISTER MsiData;
-       T3_16BIT_REGISTER Unused3;
-
-       T3_32BIT_REGISTER MiscHostCtrl;
-#define MISC_HOST_CTRL_CLEAR_INT                        BIT_0
-#define MISC_HOST_CTRL_MASK_PCI_INT                     BIT_1
-#define MISC_HOST_CTRL_ENABLE_ENDIAN_BYTE_SWAP          BIT_2
-#define MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP          BIT_3
-#define MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW          BIT_4
-#define MISC_HOST_CTRL_ENABLE_CLK_REG_RW                BIT_5
-#define MISC_HOST_CTRL_ENABLE_REG_WORD_SWAP             BIT_6
-#define MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS           BIT_7
-#define MISC_HOST_CTRL_ENABLE_INT_MASK_MODE             BIT_8
-#define MISC_HOST_CTRL_ENABLE_TAGGED_STATUS_MODE        BIT_9
-
-       T3_32BIT_REGISTER DmaReadWriteCtrl;
-#define DMA_CTRL_WRITE_BOUNDARY_MASK            (BIT_11 | BIT_12 | BIT_13)
-#define DMA_CTRL_WRITE_BOUNDARY_DISABLE         0
-#define DMA_CTRL_WRITE_BOUNDARY_16              BIT_11
-#define DMA_CTRL_WRITE_BOUNDARY_32              BIT_12
-#define DMA_CTRL_WRITE_BOUNDARY_64              (BIT_12 | BIT_11)
-#define DMA_CTRL_WRITE_BOUNDARY_128             BIT_13
-#define DMA_CTRL_WRITE_BOUNDARY_256             (BIT_13 | BIT_11)
-#define DMA_CTRL_WRITE_BOUNDARY_512             (BIT_13 | BIT_12)
-#define DMA_CTRL_WRITE_BOUNDARY_1024            (BIT_13 | BIT_12 | BIT_11)
-#define DMA_CTRL_WRITE_ONE_DMA_AT_ONCE          BIT_14
-
-       T3_32BIT_REGISTER PciState;
-#define T3_PCI_STATE_FORCE_PCI_RESET                    BIT_0
-#define T3_PCI_STATE_INTERRUPT_NOT_ACTIVE               BIT_1
-#define T3_PCI_STATE_NOT_PCI_X_BUS                      BIT_2
-#define T3_PCI_STATE_HIGH_BUS_SPEED                     BIT_3
-#define T3_PCI_STATE_32BIT_PCI_BUS                      BIT_4
-#define T3_PCI_STATE_PCI_ROM_ENABLE                     BIT_5
-#define T3_PCI_STATE_PCI_ROM_RETRY_ENABLE               BIT_6
-#define T3_PCI_STATE_FLAT_VIEW                          BIT_8
-#define T3_PCI_STATE_RETRY_SAME_DMA                     BIT_13
-
-       T3_32BIT_REGISTER ClockCtrl;
-#define T3_PCI_CLKCTRL_TXCPU_CLK_DISABLE                BIT_11
-#define T3_PCI_CLKCTRL_RXCPU_CLK_DISABLE                BIT_10
-#define T3_PCI_CLKCTRL_CORE_CLK_DISABLE                 BIT_9
-
-       T3_32BIT_REGISTER RegBaseAddr;
-
-       T3_32BIT_REGISTER MemWindowBaseAddr;
-
-#ifdef NIC_CPU_VIEW
-       /* These registers are ONLY visible to NIC CPU */
-       T3_32BIT_REGISTER PowerConsumed;
-       T3_32BIT_REGISTER PowerDissipated;
-#else                          /* NIC_CPU_VIEW */
-       T3_32BIT_REGISTER RegData;
-       T3_32BIT_REGISTER MemWindowData;
-#endif                         /* !NIC_CPU_VIEW */
-
-       T3_32BIT_REGISTER ModeCtrl;
-
-       T3_32BIT_REGISTER MiscCfg;
-
-       T3_32BIT_REGISTER MiscLocalCtrl;
-
-       T3_32BIT_REGISTER Unused4;
-
-       /* NOTE: Big/Little-endian clarification needed.  Are these register */
-       /* in big or little endian formate. */
-       T3_64BIT_REGISTER StdRingProdIdx;
-       T3_64BIT_REGISTER RcvRetRingConIdx;
-       T3_64BIT_REGISTER SndProdIdx;
-
-       LM_UINT8 Unused5[80];
-} T3_PCI_CONFIGURATION, *PT3_PCI_CONFIGURATION;
-
-#define PCIX_CMD_MAX_SPLIT_MASK                         0x0070
-#define PCIX_CMD_MAX_SPLIT_SHL                          4
-#define PCIX_CMD_MAX_BURST_MASK                         0x000c
-#define PCIX_CMD_MAX_BURST_SHL                          2
-#define PCIX_CMD_MAX_BURST_CPIOB                        2
-
-/******************************************************************************/
-/* Mac control registers. */
-/******************************************************************************/
-
-typedef struct {
-       /* MAC mode control. */
-       T3_32BIT_REGISTER Mode;
-#define MAC_MODE_GLOBAL_RESET                       BIT_0
-#define MAC_MODE_HALF_DUPLEX                        BIT_1
-#define MAC_MODE_PORT_MODE_MASK                     (BIT_2 | BIT_3)
-#define MAC_MODE_PORT_MODE_TBI                      (BIT_2 | BIT_3)
-#define MAC_MODE_PORT_MODE_GMII                     BIT_3
-#define MAC_MODE_PORT_MODE_MII                      BIT_2
-#define MAC_MODE_PORT_MODE_NONE                     BIT_NONE
-#define MAC_MODE_PORT_INTERNAL_LOOPBACK             BIT_4
-#define MAC_MODE_TAGGED_MAC_CONTROL                 BIT_7
-#define MAC_MODE_TX_BURSTING                        BIT_8
-#define MAC_MODE_MAX_DEFER                          BIT_9
-#define MAC_MODE_LINK_POLARITY                      BIT_10
-#define MAC_MODE_ENABLE_RX_STATISTICS               BIT_11
-#define MAC_MODE_CLEAR_RX_STATISTICS                BIT_12
-#define MAC_MODE_FLUSH_RX_STATISTICS                BIT_13
-#define MAC_MODE_ENABLE_TX_STATISTICS               BIT_14
-#define MAC_MODE_CLEAR_TX_STATISTICS                BIT_15
-#define MAC_MODE_FLUSH_TX_STATISTICS                BIT_16
-#define MAC_MODE_SEND_CONFIGS                       BIT_17
-#define MAC_MODE_DETECT_MAGIC_PACKET_ENABLE         BIT_18
-#define MAC_MODE_ACPI_POWER_ON_ENABLE               BIT_19
-#define MAC_MODE_ENABLE_MIP                         BIT_20
-#define MAC_MODE_ENABLE_TDE                         BIT_21
-#define MAC_MODE_ENABLE_RDE                         BIT_22
-#define MAC_MODE_ENABLE_FHDE                        BIT_23
-
-       /* MAC status */
-       T3_32BIT_REGISTER Status;
-#define MAC_STATUS_PCS_SYNCED                       BIT_0
-#define MAC_STATUS_SIGNAL_DETECTED                  BIT_1
-#define MAC_STATUS_RECEIVING_CFG                    BIT_2
-#define MAC_STATUS_CFG_CHANGED                      BIT_3
-#define MAC_STATUS_SYNC_CHANGED                     BIT_4
-#define MAC_STATUS_PORT_DECODE_ERROR                BIT_10
-#define MAC_STATUS_LINK_STATE_CHANGED               BIT_12
-#define MAC_STATUS_MI_COMPLETION                    BIT_22
-#define MAC_STATUS_MI_INTERRUPT                     BIT_23
-#define MAC_STATUS_AP_ERROR                         BIT_24
-#define MAC_STATUS_ODI_ERROR                        BIT_25
-#define MAC_STATUS_RX_STATS_OVERRUN                 BIT_26
-#define MAC_STATUS_TX_STATS_OVERRUN                 BIT_27
-
-       /* Event Enable */
-       T3_32BIT_REGISTER MacEvent;
-#define MAC_EVENT_ENABLE_PORT_DECODE_ERR            BIT_10
-#define MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN    BIT_12
-#define MAC_EVENT_ENABLE_MI_COMPLETION              BIT_22
-#define MAC_EVENT_ENABLE_MI_INTERRUPT               BIT_23
-#define MAC_EVENT_ENABLE_AP_ERROR                   BIT_24
-#define MAC_EVENT_ENABLE_ODI_ERROR                  BIT_25
-#define MAC_EVENT_ENABLE_RX_STATS_OVERRUN           BIT_26
-#define MAC_EVENT_ENABLE_TX_STATS_OVERRUN           BIT_27
-
-       /* Led control. */
-       T3_32BIT_REGISTER LedCtrl;
-#define LED_CTRL_OVERRIDE_LINK_LED                  BIT_0
-#define LED_CTRL_1000MBPS_LED_ON                    BIT_1
-#define LED_CTRL_100MBPS_LED_ON                     BIT_2
-#define LED_CTRL_10MBPS_LED_ON                      BIT_3
-#define LED_CTRL_OVERRIDE_TRAFFIC_LED               BIT_4
-#define LED_CTRL_BLINK_TRAFFIC_LED                  BIT_5
-#define LED_CTRL_TRAFFIC_LED                        BIT_6
-#define LED_CTRL_1000MBPS_LED_STATUS                BIT_7
-#define LED_CTRL_100MBPS_LED_STATUS                 BIT_8
-#define LED_CTRL_10MBPS_LED_STATUS                  BIT_9
-#define LED_CTRL_TRAFFIC_LED_STATUS                 BIT_10
-#define LED_CTRL_MAC_MODE                           BIT_NONE
-#define LED_CTRL_PHY_MODE_1                         BIT_11
-#define LED_CTRL_PHY_MODE_2                         BIT_12
-#define LED_CTRL_BLINK_RATE_MASK                    0x7ff80000
-#define LED_CTRL_OVERRIDE_BLINK_PERIOD              BIT_19
-#define LED_CTRL_OVERRIDE_BLINK_RATE                BIT_31
-
-       /* MAC addresses. */
-       struct {
-               T3_32BIT_REGISTER High; /* Upper 2 bytes. */
-               T3_32BIT_REGISTER Low;  /* Lower 4 bytes. */
-       } MacAddr[4];
-
-       /* ACPI Mbuf pointer. */
-       T3_32BIT_REGISTER AcpiMbufPtr;
-
-       /* ACPI Length and Offset. */
-       T3_32BIT_REGISTER AcpiLengthOffset;
-#define ACPI_LENGTH_MASK                            0xffff
-#define ACPI_OFFSET_MASK                            0x0fff0000
-#define ACPI_LENGTH(x)                              x
-#define ACPI_OFFSET(x)                              ((x) << 16)
-
-       /* Transmit random backoff. */
-       T3_32BIT_REGISTER TxBackoffSeed;
-#define MAC_TX_BACKOFF_SEED_MASK                    0x3ff
-
-       /* Receive MTU */
-       T3_32BIT_REGISTER MtuSize;
-#define MAC_RX_MTU_MASK                             0xffff
-
-       /* Gigabit PCS Test. */
-       T3_32BIT_REGISTER PcsTest;
-#define MAC_PCS_TEST_DATA_PATTERN_MASK              0x0fffff
-#define MAC_PCS_TEST_ENABLE                         BIT_20
-
-       /* Transmit Gigabit Auto-Negotiation. */
-       T3_32BIT_REGISTER TxAutoNeg;
-#define MAC_AN_TX_AN_DATA_MASK                      0xffff
-
-       /* Receive Gigabit Auto-Negotiation. */
-       T3_32BIT_REGISTER RxAutoNeg;
-#define MAC_AN_RX_AN_DATA_MASK                      0xffff
-
-       /* MI Communication. */
-       T3_32BIT_REGISTER MiCom;
-#define MI_COM_CMD_MASK                             (BIT_26 | BIT_27)
-#define MI_COM_CMD_WRITE                            BIT_26
-#define MI_COM_CMD_READ                             BIT_27
-#define MI_COM_READ_FAILED                          BIT_28
-#define MI_COM_START                                BIT_29
-#define MI_COM_BUSY                                 BIT_29
-
-#define MI_COM_PHY_ADDR_MASK                        0x1f
-#define MI_COM_FIRST_PHY_ADDR_BIT                   21
-
-#define MI_COM_PHY_REG_ADDR_MASK                    0x1f
-#define MI_COM_FIRST_PHY_REG_ADDR_BIT               16
-
-#define MI_COM_PHY_DATA_MASK                        0xffff
-
-       /* MI Status. */
-       T3_32BIT_REGISTER MiStatus;
-#define MI_STATUS_ENABLE_LINK_STATUS_ATTN           BIT_0
-
-       /* MI Mode. */
-       T3_32BIT_REGISTER MiMode;
-#define MI_MODE_CLOCK_SPEED_10MHZ                   BIT_0
-#define MI_MODE_USE_SHORT_PREAMBLE                  BIT_1
-#define MI_MODE_AUTO_POLLING_ENABLE                 BIT_4
-#define MI_MODE_CORE_CLOCK_SPEED_62MHZ              BIT_15
-
-       /* Auto-polling status. */
-       T3_32BIT_REGISTER AutoPollStatus;
-#define AUTO_POLL_ERROR                             BIT_0
-
-       /* Transmit MAC mode. */
-       T3_32BIT_REGISTER TxMode;
-#define TX_MODE_RESET                               BIT_0
-#define TX_MODE_ENABLE                              BIT_1
-#define TX_MODE_ENABLE_FLOW_CONTROL                 BIT_4
-#define TX_MODE_ENABLE_BIG_BACKOFF                  BIT_5
-#define TX_MODE_ENABLE_LONG_PAUSE                   BIT_6
-
-       /* Transmit MAC status. */
-       T3_32BIT_REGISTER TxStatus;
-#define TX_STATUS_RX_CURRENTLY_XOFFED               BIT_0
-#define TX_STATUS_SENT_XOFF                         BIT_1
-#define TX_STATUS_SENT_XON                          BIT_2
-#define TX_STATUS_LINK_UP                           BIT_3
-#define TX_STATUS_ODI_UNDERRUN                      BIT_4
-#define TX_STATUS_ODI_OVERRUN                       BIT_5
-
-       /* Transmit MAC length. */
-       T3_32BIT_REGISTER TxLengths;
-#define TX_LEN_SLOT_TIME_MASK                       0xff
-#define TX_LEN_IPG_MASK                             0x0f00
-#define TX_LEN_IPG_CRS_MASK                         (BIT_12 | BIT_13)
-
-       /* Receive MAC mode. */
-       T3_32BIT_REGISTER RxMode;
-#define RX_MODE_RESET                               BIT_0
-#define RX_MODE_ENABLE                              BIT_1
-#define RX_MODE_ENABLE_FLOW_CONTROL                 BIT_2
-#define RX_MODE_KEEP_MAC_CONTROL                    BIT_3
-#define RX_MODE_KEEP_PAUSE                          BIT_4
-#define RX_MODE_ACCEPT_OVERSIZED                    BIT_5
-#define RX_MODE_ACCEPT_RUNTS                        BIT_6
-#define RX_MODE_LENGTH_CHECK                        BIT_7
-#define RX_MODE_PROMISCUOUS_MODE                    BIT_8
-#define RX_MODE_NO_CRC_CHECK                        BIT_9
-#define RX_MODE_KEEP_VLAN_TAG                       BIT_10
-
-       /* Receive MAC status. */
-       T3_32BIT_REGISTER RxStatus;
-#define RX_STATUS_REMOTE_TRANSMITTER_XOFFED         BIT_0
-#define RX_STATUS_XOFF_RECEIVED                     BIT_1
-#define RX_STATUS_XON_RECEIVED                      BIT_2
-
-       /* Hash registers. */
-       T3_32BIT_REGISTER HashReg[4];
-
-       /* Receive placement rules registers. */
-       struct {
-               T3_32BIT_REGISTER Rule;
-               T3_32BIT_REGISTER Value;
-       } RcvRules[16];
-
-#define RCV_DISABLE_RULE_MASK                       0x7fffffff
-
-#define RCV_RULE1_REJECT_BROADCAST_IDX              0x00
-#define REJECT_BROADCAST_RULE1_RULE                 0xc2000000
-#define REJECT_BROADCAST_RULE1_VALUE                0xffffffff
-
-#define RCV_RULE2_REJECT_BROADCAST_IDX              0x01
-#define REJECT_BROADCAST_RULE2_RULE                 0x86000004
-#define REJECT_BROADCAST_RULE2_VALUE                0xffffffff
-
-#if INCLUDE_5701_AX_FIX
-#define RCV_LAST_RULE_IDX                           0x04
-#else
-#define RCV_LAST_RULE_IDX                           0x02
-#endif
-
-       T3_32BIT_REGISTER RcvRuleCfg;
-#define RX_RULE_DEFAULT_CLASS                       (1 << 3)
-
-       LM_UINT8 Reserved1[140];
-
-       T3_32BIT_REGISTER SerdesCfg;
-       T3_32BIT_REGISTER SerdesStatus;
-
-       LM_UINT8 Reserved2[104];
-
-       volatile LM_UINT8 TxMacState[16];
-       volatile LM_UINT8 RxMacState[20];
-
-       LM_UINT8 Reserved3[476];
-
-       T3_32BIT_REGISTER RxStats[26];
-
-       LM_UINT8 Reserved4[24];
-
-       T3_32BIT_REGISTER TxStats[28];
-
-       LM_UINT8 Reserved5[784];
-} T3_MAC_CONTROL, *PT3_MAC_CONTROL;
-
-/******************************************************************************/
-/* Send data initiator control registers. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Mode;
-#define T3_SND_DATA_IN_MODE_RESET                       BIT_0
-#define T3_SND_DATA_IN_MODE_ENABLE                      BIT_1
-#define T3_SND_DATA_IN_MODE_STATS_OFLW_ATTN_ENABLE      BIT_2
-
-       T3_32BIT_REGISTER Status;
-#define T3_SND_DATA_IN_STATUS_STATS_OFLW_ATTN           BIT_2
-
-       T3_32BIT_REGISTER StatsCtrl;
-#define T3_SND_DATA_IN_STATS_CTRL_ENABLE                BIT_0
-#define T3_SND_DATA_IN_STATS_CTRL_FASTER_UPDATE         BIT_1
-#define T3_SND_DATA_IN_STATS_CTRL_CLEAR                 BIT_2
-#define T3_SND_DATA_IN_STATS_CTRL_FLUSH                 BIT_3
-#define T3_SND_DATA_IN_STATS_CTRL_FORCE_ZERO            BIT_4
-
-       T3_32BIT_REGISTER StatsEnableMask;
-       T3_32BIT_REGISTER StatsIncMask;
-
-       LM_UINT8 Reserved[108];
-
-       T3_32BIT_REGISTER ClassOfServCnt[16];
-       T3_32BIT_REGISTER DmaReadQFullCnt;
-       T3_32BIT_REGISTER DmaPriorityReadQFullCnt;
-       T3_32BIT_REGISTER SdcQFullCnt;
-
-       T3_32BIT_REGISTER NicRingSetSendProdIdxCnt;
-       T3_32BIT_REGISTER StatusUpdatedCnt;
-       T3_32BIT_REGISTER InterruptsCnt;
-       T3_32BIT_REGISTER AvoidInterruptsCnt;
-       T3_32BIT_REGISTER SendThresholdHitCnt;
-
-       /* Unused space. */
-       LM_UINT8 Unused[800];
-} T3_SEND_DATA_INITIATOR, *PT3_SEND_DATA_INITIATOR;
-
-/******************************************************************************/
-/* Send data completion control registers. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Mode;
-#define SND_DATA_COMP_MODE_RESET                        BIT_0
-#define SND_DATA_COMP_MODE_ENABLE                       BIT_1
-
-       /* Unused space. */
-       LM_UINT8 Unused[1020];
-} T3_SEND_DATA_COMPLETION, *PT3_SEND_DATA_COMPLETION;
-
-/******************************************************************************/
-/* Send BD Ring Selector Control Registers. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Mode;
-#define SND_BD_SEL_MODE_RESET                           BIT_0
-#define SND_BD_SEL_MODE_ENABLE                          BIT_1
-#define SND_BD_SEL_MODE_ATTN_ENABLE                     BIT_2
-
-       T3_32BIT_REGISTER Status;
-#define SND_BD_SEL_STATUS_ERROR_ATTN                    BIT_2
-
-       T3_32BIT_REGISTER HwDiag;
-
-       /* Unused space. */
-       LM_UINT8 Unused1[52];
-
-       /* Send BD Ring Selector Local NIC Send BD Consumer Index. */
-       T3_32BIT_REGISTER NicSendBdSelConIdx[16];
-
-       /* Unused space. */
-       LM_UINT8 Unused2[896];
-} T3_SEND_BD_SELECTOR, *PT3_SEND_BD_SELECTOR;
-
-/******************************************************************************/
-/* Send BD initiator control registers. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Mode;
-#define SND_BD_IN_MODE_RESET                            BIT_0
-#define SND_BD_IN_MODE_ENABLE                           BIT_1
-#define SND_BD_IN_MODE_ATTN_ENABLE                      BIT_2
-
-       T3_32BIT_REGISTER Status;
-#define SND_BD_IN_STATUS_ERROR_ATTN                     BIT_2
-
-       /* Send BD initiator local NIC send BD producer index. */
-       T3_32BIT_REGISTER NicSendBdInProdIdx[16];
-
-       /* Unused space. */
-       LM_UINT8 Unused2[952];
-} T3_SEND_BD_INITIATOR, *PT3_SEND_BD_INITIATOR;
-
-/******************************************************************************/
-/* Send BD Completion Control. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Mode;
-#define SND_BD_COMP_MODE_RESET                          BIT_0
-#define SND_BD_COMP_MODE_ENABLE                         BIT_1
-#define SND_BD_COMP_MODE_ATTN_ENABLE                    BIT_2
-
-       /* Unused space. */
-       LM_UINT8 Unused2[1020];
-} T3_SEND_BD_COMPLETION, *PT3_SEND_BD_COMPLETION;
-
-/******************************************************************************/
-/* Receive list placement control registers. */
-/******************************************************************************/
-
-typedef struct {
-       /* Mode. */
-       T3_32BIT_REGISTER Mode;
-#define RCV_LIST_PLMT_MODE_RESET                        BIT_0
-#define RCV_LIST_PLMT_MODE_ENABLE                       BIT_1
-#define RCV_LIST_PLMT_MODE_CLASS0_ATTN_ENABLE           BIT_2
-#define RCV_LIST_PLMT_MODE_MAPPING_OOR_ATTN_ENABLE      BIT_3
-#define RCV_LIST_PLMT_MODE_STATS_OFLOW_ATTN_ENABLE      BIT_4
-
-       /* Status. */
-       T3_32BIT_REGISTER Status;
-#define RCV_LIST_PLMT_STATUS_CLASS0_ATTN                BIT_2
-#define RCV_LIST_PLMT_STATUS_MAPPING_ATTN               BIT_3
-#define RCV_LIST_PLMT_STATUS_STATS_OFLOW_ATTN           BIT_4
-
-       /* Receive selector list lock register. */
-       T3_32BIT_REGISTER Lock;
-#define RCV_LIST_SEL_LOCK_REQUEST_MASK                  0xffff
-#define RCV_LIST_SEL_LOCK_GRANT_MASK                    0xffff0000
-
-       /* Selector non-empty bits. */
-       T3_32BIT_REGISTER NonEmptyBits;
-#define RCV_LIST_SEL_NON_EMPTY_MASK                     0xffff
-
-       /* Receive list placement configuration register. */
-       T3_32BIT_REGISTER Config;
-
-       /* Receive List Placement statistics Control. */
-       T3_32BIT_REGISTER StatsCtrl;
-#define RCV_LIST_STATS_ENABLE                               BIT_0
-#define RCV_LIST_STATS_FAST_UPDATE                          BIT_1
-
-       /* Receive List Placement statistics Enable Mask. */
-       T3_32BIT_REGISTER StatsEnableMask;
-
-       /* Receive List Placement statistics Increment Mask. */
-       T3_32BIT_REGISTER StatsIncMask;
-
-       /* Unused space. */
-       LM_UINT8 Unused1[224];
-
-       struct {
-               T3_32BIT_REGISTER Head;
-               T3_32BIT_REGISTER Tail;
-               T3_32BIT_REGISTER Count;
-
-               /* Unused space. */
-               LM_UINT8 Unused[4];
-       } RcvSelectorList[16];
-
-       /* Local statistics counter. */
-       T3_32BIT_REGISTER ClassOfServCnt[16];
-
-       T3_32BIT_REGISTER DropDueToFilterCnt;
-       T3_32BIT_REGISTER DmaWriteQFullCnt;
-       T3_32BIT_REGISTER DmaHighPriorityWriteQFullCnt;
-       T3_32BIT_REGISTER NoMoreReceiveBdCnt;
-       T3_32BIT_REGISTER IfInDiscardsCnt;
-       T3_32BIT_REGISTER IfInErrorsCnt;
-       T3_32BIT_REGISTER RcvThresholdHitCnt;
-
-       /* Another unused space. */
-       LM_UINT8 Unused2[420];
-} T3_RCV_LIST_PLACEMENT, *PT3_RCV_LIST_PLACEMENT;
-
-/******************************************************************************/
-/* Receive Data and Receive BD Initiator Control. */
-/******************************************************************************/
-
-typedef struct {
-       /* Mode. */
-       T3_32BIT_REGISTER Mode;
-#define RCV_DATA_BD_IN_MODE_RESET                   BIT_0
-#define RCV_DATA_BD_IN_MODE_ENABLE                  BIT_1
-#define RCV_DATA_BD_IN_MODE_JUMBO_BD_NEEDED         BIT_2
-#define RCV_DATA_BD_IN_MODE_FRAME_TOO_BIG           BIT_3
-#define RCV_DATA_BD_IN_MODE_INVALID_RING_SIZE       BIT_4
-
-       /* Status. */
-       T3_32BIT_REGISTER Status;
-#define RCV_DATA_BD_IN_STATUS_JUMBO_BD_NEEDED       BIT_2
-#define RCV_DATA_BD_IN_STATUS_FRAME_TOO_BIG         BIT_3
-#define RCV_DATA_BD_IN_STATUS_INVALID_RING_SIZE     BIT_4
-
-       /* Split frame minium size. */
-       T3_32BIT_REGISTER SplitFrameMinSize;
-
-       /* Unused space. */
-       LM_UINT8 Unused1[0x2440 - 0x240c];
-
-       /* Receive RCBs. */
-       T3_RCB JumboRcvRcb;
-       T3_RCB StdRcvRcb;
-       T3_RCB MiniRcvRcb;
-
-       /* Receive Data and Receive BD Ring Initiator Local NIC Receive */
-       /* BD Consumber Index. */
-       T3_32BIT_REGISTER NicJumboConIdx;
-       T3_32BIT_REGISTER NicStdConIdx;
-       T3_32BIT_REGISTER NicMiniConIdx;
-
-       /* Unused space. */
-       LM_UINT8 Unused2[4];
-
-       /* Receive Data and Receive BD Initiator Local Receive Return ProdIdx. */
-       T3_32BIT_REGISTER RcvDataBdProdIdx[16];
-
-       /* Receive Data and Receive BD Initiator Hardware Diagnostic. */
-       T3_32BIT_REGISTER HwDiag;
-
-       /* Unused space. */
-       LM_UINT8 Unused3[828];
-} T3_RCV_DATA_BD_INITIATOR, *PT3_RCV_DATA_BD_INITIATOR;
-
-/******************************************************************************/
-/* Receive Data Completion Control Registes. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Mode;
-#define RCV_DATA_COMP_MODE_RESET                        BIT_0
-#define RCV_DATA_COMP_MODE_ENABLE                       BIT_1
-#define RCV_DATA_COMP_MODE_ATTN_ENABLE                  BIT_2
-
-       /* Unused spaced. */
-       LM_UINT8 Unused[1020];
-} T3_RCV_DATA_COMPLETION, *PT3_RCV_DATA_COMPLETION;
-
-/******************************************************************************/
-/* Receive BD Initiator Control. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Mode;
-#define RCV_BD_IN_MODE_RESET                            BIT_0
-#define RCV_BD_IN_MODE_ENABLE                           BIT_1
-#define RCV_BD_IN_MODE_BD_IN_DIABLED_RCB_ATTN_ENABLE    BIT_2
-
-       T3_32BIT_REGISTER Status;
-#define RCV_BD_IN_STATUS_BD_IN_DIABLED_RCB_ATTN         BIT_2
-
-       T3_32BIT_REGISTER NicJumboRcvProdIdx;
-       T3_32BIT_REGISTER NicStdRcvProdIdx;
-       T3_32BIT_REGISTER NicMiniRcvProdIdx;
-
-       T3_32BIT_REGISTER MiniRcvThreshold;
-       T3_32BIT_REGISTER StdRcvThreshold;
-       T3_32BIT_REGISTER JumboRcvThreshold;
-
-       /* Unused space. */
-       LM_UINT8 Unused[992];
-} T3_RCV_BD_INITIATOR, *PT3_RCV_BD_INITIATOR;
-
-/******************************************************************************/
-/* Receive BD Completion Control Registers. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Mode;
-#define RCV_BD_COMP_MODE_RESET                          BIT_0
-#define RCV_BD_COMP_MODE_ENABLE                         BIT_1
-#define RCV_BD_COMP_MODE_ATTN_ENABLE                    BIT_2
-
-       T3_32BIT_REGISTER Status;
-#define RCV_BD_COMP_STATUS_ERROR_ATTN                   BIT_2
-
-       T3_32BIT_REGISTER NicJumboRcvBdProdIdx;
-       T3_32BIT_REGISTER NicStdRcvBdProdIdx;
-       T3_32BIT_REGISTER NicMiniRcvBdProdIdx;
-
-       /* Unused space. */
-       LM_UINT8 Unused[1004];
-} T3_RCV_BD_COMPLETION, *PT3_RCV_BD_COMPLETION;
-
-/******************************************************************************/
-/* Receive list selector control register. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Mode;
-#define RCV_LIST_SEL_MODE_RESET                         BIT_0
-#define RCV_LIST_SEL_MODE_ENABLE                        BIT_1
-#define RCV_LIST_SEL_MODE_ATTN_ENABLE                   BIT_2
-
-       T3_32BIT_REGISTER Status;
-#define RCV_LIST_SEL_STATUS_ERROR_ATTN                  BIT_2
-
-       /* Unused space. */
-       LM_UINT8 Unused[1016];
-} T3_RCV_LIST_SELECTOR, *PT3_RCV_LIST_SELECTOR;
-
-/******************************************************************************/
-/* Mbuf cluster free registers. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Mode;
-#define MBUF_CLUSTER_FREE_MODE_RESET    BIT_0
-#define MBUF_CLUSTER_FREE_MODE_ENABLE   BIT_1
-
-       T3_32BIT_REGISTER Status;
-
-       /* Unused space. */
-       LM_UINT8 Unused[1016];
-} T3_MBUF_CLUSTER_FREE, *PT3_MBUF_CLUSTER_FREE;
-
-/******************************************************************************/
-/* Host coalescing control registers. */
-/******************************************************************************/
-
-typedef struct {
-       /* Mode. */
-       T3_32BIT_REGISTER Mode;
-#define HOST_COALESCE_RESET                         BIT_0
-#define HOST_COALESCE_ENABLE                        BIT_1
-#define HOST_COALESCE_ATTN                          BIT_2
-#define HOST_COALESCE_NOW                           BIT_3
-#define HOST_COALESCE_FULL_STATUS_MODE              BIT_NONE
-#define HOST_COALESCE_64_BYTE_STATUS_MODE           BIT_7
-#define HOST_COALESCE_32_BYTE_STATUS_MODE           BIT_8
-#define HOST_COALESCE_CLEAR_TICKS_ON_RX_BD_EVENT    BIT_9
-#define HOST_COALESCE_CLEAR_TICKS_ON_TX_BD_EVENT    BIT_10
-#define HOST_COALESCE_NO_INT_ON_COALESCE_NOW_MODE   BIT_11
-#define HOST_COALESCE_NO_INT_ON_FORCE_DMAD_MODE     BIT_12
-
-       /* Status. */
-       T3_32BIT_REGISTER Status;
-#define HOST_COALESCE_ERROR_ATTN                    BIT_2
-
-       /* Receive coalescing ticks. */
-       T3_32BIT_REGISTER RxCoalescingTicks;
-
-       /* Send coalescing ticks. */
-       T3_32BIT_REGISTER TxCoalescingTicks;
-
-       /* Receive max coalesced frames. */
-       T3_32BIT_REGISTER RxMaxCoalescedFrames;
-
-       /* Send max coalesced frames. */
-       T3_32BIT_REGISTER TxMaxCoalescedFrames;
-
-       /* Receive coalescing ticks during interrupt. */
-       T3_32BIT_REGISTER RxCoalescedTickDuringInt;
-
-       /* Send coalescing ticks during interrupt. */
-       T3_32BIT_REGISTER TxCoalescedTickDuringInt;
-
-       /* Receive max coalesced frames during interrupt. */
-       T3_32BIT_REGISTER RxMaxCoalescedFramesDuringInt;
-
-       /* Send max coalesced frames during interrupt. */
-       T3_32BIT_REGISTER TxMaxCoalescedFramesDuringInt;
-
-       /* Statistics tick. */
-       T3_32BIT_REGISTER StatsCoalescingTicks;
-
-       /* Unused space. */
-       LM_UINT8 Unused2[4];
-
-       /* Statistics host address. */
-       T3_64BIT_REGISTER StatsBlkHostAddr;
-
-       /* Status block host address. */
-       T3_64BIT_REGISTER StatusBlkHostAddr;
-
-       /* Statistics NIC address. */
-       T3_32BIT_REGISTER StatsBlkNicAddr;
-
-       /* Statust block NIC address. */
-       T3_32BIT_REGISTER StatusBlkNicAddr;
-
-       /* Flow attention registers. */
-       T3_32BIT_REGISTER FlowAttn;
-
-       /* Unused space. */
-       LM_UINT8 Unused3[4];
-
-       T3_32BIT_REGISTER NicJumboRcvBdConIdx;
-       T3_32BIT_REGISTER NicStdRcvBdConIdx;
-       T3_32BIT_REGISTER NicMiniRcvBdConIdx;
-
-       /* Unused space. */
-       LM_UINT8 Unused4[36];
-
-       T3_32BIT_REGISTER NicRetProdIdx[16];
-       T3_32BIT_REGISTER NicSndBdConIdx[16];
-
-       /* Unused space. */
-       LM_UINT8 Unused5[768];
-} T3_HOST_COALESCING, *PT3_HOST_COALESCING;
-
-/******************************************************************************/
-/* Memory arbiter registers. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Mode;
-#define T3_MEM_ARBITER_MODE_RESET       BIT_0
-#define T3_MEM_ARBITER_MODE_ENABLE      BIT_1
-
-       T3_32BIT_REGISTER Status;
-
-       T3_32BIT_REGISTER ArbTrapAddrLow;
-       T3_32BIT_REGISTER ArbTrapAddrHigh;
-
-       /* Unused space. */
-       LM_UINT8 Unused[1008];
-} T3_MEM_ARBITER, *PT3_MEM_ARBITER;
-
-/******************************************************************************/
-/* Buffer manager control register. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Mode;
-#define BUFMGR_MODE_RESET                           BIT_0
-#define BUFMGR_MODE_ENABLE                          BIT_1
-#define BUFMGR_MODE_ATTN_ENABLE                     BIT_2
-#define BUFMGR_MODE_BM_TEST                         BIT_3
-#define BUFMGR_MODE_MBUF_LOW_ATTN_ENABLE            BIT_4
-
-       T3_32BIT_REGISTER Status;
-#define BUFMGR_STATUS_ERROR                         BIT_2
-#define BUFMGR_STATUS_MBUF_LOW                      BIT_4
-
-       T3_32BIT_REGISTER MbufPoolAddr;
-       T3_32BIT_REGISTER MbufPoolSize;
-       T3_32BIT_REGISTER MbufReadDmaLowWaterMark;
-       T3_32BIT_REGISTER MbufMacRxLowWaterMark;
-       T3_32BIT_REGISTER MbufHighWaterMark;
-
-       T3_32BIT_REGISTER RxCpuMbufAllocReq;
-#define BUFMGR_MBUF_ALLOC_BIT                     BIT_31
-       T3_32BIT_REGISTER RxCpuMbufAllocResp;
-       T3_32BIT_REGISTER TxCpuMbufAllocReq;
-       T3_32BIT_REGISTER TxCpuMbufAllocResp;
-
-       T3_32BIT_REGISTER DmaDescPoolAddr;
-       T3_32BIT_REGISTER DmaDescPoolSize;
-       T3_32BIT_REGISTER DmaLowWaterMark;
-       T3_32BIT_REGISTER DmaHighWaterMark;
-
-       T3_32BIT_REGISTER RxCpuDmaAllocReq;
-       T3_32BIT_REGISTER RxCpuDmaAllocResp;
-       T3_32BIT_REGISTER TxCpuDmaAllocReq;
-       T3_32BIT_REGISTER TxCpuDmaAllocResp;
-
-       T3_32BIT_REGISTER Hwdiag[3];
-
-       /* Unused space. */
-       LM_UINT8 Unused[936];
-} T3_BUFFER_MANAGER, *PT3_BUFFER_MANAGER;
-
-/******************************************************************************/
-/* Read DMA control registers. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Mode;
-#define DMA_READ_MODE_RESET                         BIT_0
-#define DMA_READ_MODE_ENABLE                        BIT_1
-#define DMA_READ_MODE_TARGET_ABORT_ATTN_ENABLE      BIT_2
-#define DMA_READ_MODE_MASTER_ABORT_ATTN_ENABLE      BIT_3
-#define DMA_READ_MODE_PARITY_ERROR_ATTN_ENABLE      BIT_4
-#define DMA_READ_MODE_ADDR_OVERFLOW_ATTN_ENABLE     BIT_5
-#define DMA_READ_MODE_FIFO_OVERRUN_ATTN_ENABLE      BIT_6
-#define DMA_READ_MODE_FIFO_UNDERRUN_ATTN_ENABLE     BIT_7
-#define DMA_READ_MODE_FIFO_OVERREAD_ATTN_ENABLE     BIT_8
-#define DMA_READ_MODE_LONG_READ_ATTN_ENABLE         BIT_9
-#define DMA_READ_MODE_SPLIT_ENABLE                  BIT_11
-#define DMA_READ_MODE_SPLIT_RESET                   BIT_12
-
-       T3_32BIT_REGISTER Status;
-#define DMA_READ_STATUS_TARGET_ABORT_ATTN           BIT_2
-#define DMA_READ_STATUS_MASTER_ABORT_ATTN           BIT_3
-#define DMA_READ_STATUS_PARITY_ERROR_ATTN           BIT_4
-#define DMA_READ_STATUS_ADDR_OVERFLOW_ATTN          BIT_5
-#define DMA_READ_STATUS_FIFO_OVERRUN_ATTN           BIT_6
-#define DMA_READ_STATUS_FIFO_UNDERRUN_ATTN          BIT_7
-#define DMA_READ_STATUS_FIFO_OVERREAD_ATTN          BIT_8
-#define DMA_READ_STATUS_LONG_READ_ATTN              BIT_9
-
-       /* Unused space. */
-       LM_UINT8 Unused[1016];
-} T3_DMA_READ, *PT3_DMA_READ;
-
-typedef union T3_CPU {
-       struct {
-               T3_32BIT_REGISTER mode;
-#define CPU_MODE_HALT   BIT_10
-#define CPU_MODE_RESET  BIT_0
-               T3_32BIT_REGISTER state;
-               T3_32BIT_REGISTER EventMask;
-               T3_32BIT_REGISTER reserved1[4];
-               T3_32BIT_REGISTER PC;
-               T3_32BIT_REGISTER Instruction;
-               T3_32BIT_REGISTER SpadUnderflow;
-               T3_32BIT_REGISTER WatchdogClear;
-               T3_32BIT_REGISTER WatchdogVector;
-               T3_32BIT_REGISTER WatchdogSavedPC;
-               T3_32BIT_REGISTER HardwareBp;
-               T3_32BIT_REGISTER reserved2[3];
-               T3_32BIT_REGISTER WatchdogSavedState;
-               T3_32BIT_REGISTER LastBrchAddr;
-               T3_32BIT_REGISTER SpadUnderflowSet;
-               T3_32BIT_REGISTER reserved3[(0x200 - 0x50) / 4];
-               T3_32BIT_REGISTER Regs[32];
-               T3_32BIT_REGISTER reserved4[(0x400 - 0x280) / 4];
-       } reg;
-} T3_CPU, *PT3_CPU;
-
-/******************************************************************************/
-/* Write DMA control registers. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Mode;
-#define DMA_WRITE_MODE_RESET                        BIT_0
-#define DMA_WRITE_MODE_ENABLE                       BIT_1
-#define DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE     BIT_2
-#define DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE     BIT_3
-#define DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE     BIT_4
-#define DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE    BIT_5
-#define DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE     BIT_6
-#define DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE    BIT_7
-#define DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE    BIT_8
-#define DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE        BIT_9
-
-       T3_32BIT_REGISTER Status;
-#define DMA_WRITE_STATUS_TARGET_ABORT_ATTN          BIT_2
-#define DMA_WRITE_STATUS_MASTER_ABORT_ATTN          BIT_3
-#define DMA_WRITE_STATUS_PARITY_ERROR_ATTN          BIT_4
-#define DMA_WRITE_STATUS_ADDR_OVERFLOW_ATTN         BIT_5
-#define DMA_WRITE_STATUS_FIFO_OVERRUN_ATTN          BIT_6
-#define DMA_WRITE_STATUS_FIFO_UNDERRUN_ATTN         BIT_7
-#define DMA_WRITE_STATUS_FIFO_OVERREAD_ATTN         BIT_8
-#define DMA_WRITE_STATUS_LONG_READ_ATTN             BIT_9
-
-       /* Unused space. */
-       LM_UINT8 Unused[1016];
-} T3_DMA_WRITE, *PT3_DMA_WRITE;
-
-/******************************************************************************/
-/* Mailbox registers. */
-/******************************************************************************/
-
-typedef struct {
-       /* Interrupt mailbox registers. */
-       T3_64BIT_REGISTER Interrupt[4];
-
-       /* General mailbox registers. */
-       T3_64BIT_REGISTER General[8];
-
-       /* Reload statistics mailbox. */
-       T3_64BIT_REGISTER ReloadStat;
-
-       /* Receive BD ring producer index registers. */
-       T3_64BIT_REGISTER RcvStdProdIdx;
-       T3_64BIT_REGISTER RcvJumboProdIdx;
-       T3_64BIT_REGISTER RcvMiniProdIdx;
-
-       /* Receive return ring consumer index registers. */
-       T3_64BIT_REGISTER RcvRetConIdx[16];
-
-       /* Send BD ring host producer index registers. */
-       T3_64BIT_REGISTER SendHostProdIdx[16];
-
-       /* Send BD ring nic producer index registers. */
-       T3_64BIT_REGISTER SendNicProdIdx[16];
-} T3_MAILBOX, *PT3_MAILBOX;
-
-typedef struct {
-       T3_MAILBOX Mailbox;
-
-       /* Priority mailbox registers. */
-       T3_32BIT_REGISTER HighPriorityEventVector;
-       T3_32BIT_REGISTER HighPriorityEventMask;
-       T3_32BIT_REGISTER LowPriorityEventVector;
-       T3_32BIT_REGISTER LowPriorityEventMask;
-
-       /* Unused space. */
-       LM_UINT8 Unused[496];
-} T3_GRC_MAILBOX, *PT3_GRC_MAILBOX;
-
-/******************************************************************************/
-/* Flow through queues. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Reset;
-
-       LM_UINT8 Unused[12];
-
-       T3_32BIT_REGISTER DmaNormalReadFtqCtrl;
-       T3_32BIT_REGISTER DmaNormalReadFtqFullCnt;
-       T3_32BIT_REGISTER DmaNormalReadFtqFifoEnqueueDequeue;
-       T3_32BIT_REGISTER DmaNormalReadFtqFifoWritePeek;
-
-       T3_32BIT_REGISTER DmaHighReadFtqCtrl;
-       T3_32BIT_REGISTER DmaHighReadFtqFullCnt;
-       T3_32BIT_REGISTER DmaHighReadFtqFifoEnqueueDequeue;
-       T3_32BIT_REGISTER DmaHighReadFtqFifoWritePeek;
-
-       T3_32BIT_REGISTER DmaCompDiscardFtqCtrl;
-       T3_32BIT_REGISTER DmaCompDiscardFtqFullCnt;
-       T3_32BIT_REGISTER DmaCompDiscardFtqFifoEnqueueDequeue;
-       T3_32BIT_REGISTER DmaCompDiscardFtqFifoWritePeek;
-
-       T3_32BIT_REGISTER SendBdCompFtqCtrl;
-       T3_32BIT_REGISTER SendBdCompFtqFullCnt;
-       T3_32BIT_REGISTER SendBdCompFtqFifoEnqueueDequeue;
-       T3_32BIT_REGISTER SendBdCompFtqFifoWritePeek;
-
-       T3_32BIT_REGISTER SendDataInitiatorFtqCtrl;
-       T3_32BIT_REGISTER SendDataInitiatorFtqFullCnt;
-       T3_32BIT_REGISTER SendDataInitiatorFtqFifoEnqueueDequeue;
-       T3_32BIT_REGISTER SendDataInitiatorFtqFifoWritePeek;
-
-       T3_32BIT_REGISTER DmaNormalWriteFtqCtrl;
-       T3_32BIT_REGISTER DmaNormalWriteFtqFullCnt;
-       T3_32BIT_REGISTER DmaNormalWriteFtqFifoEnqueueDequeue;
-       T3_32BIT_REGISTER DmaNormalWriteFtqFifoWritePeek;
-
-       T3_32BIT_REGISTER DmaHighWriteFtqCtrl;
-       T3_32BIT_REGISTER DmaHighWriteFtqFullCnt;
-       T3_32BIT_REGISTER DmaHighWriteFtqFifoEnqueueDequeue;
-       T3_32BIT_REGISTER DmaHighWriteFtqFifoWritePeek;
-
-       T3_32BIT_REGISTER SwType1FtqCtrl;
-       T3_32BIT_REGISTER SwType1FtqFullCnt;
-       T3_32BIT_REGISTER SwType1FtqFifoEnqueueDequeue;
-       T3_32BIT_REGISTER SwType1FtqFifoWritePeek;
-
-       T3_32BIT_REGISTER SendDataCompFtqCtrl;
-       T3_32BIT_REGISTER SendDataCompFtqFullCnt;
-       T3_32BIT_REGISTER SendDataCompFtqFifoEnqueueDequeue;
-       T3_32BIT_REGISTER SendDataCompFtqFifoWritePeek;
-
-       T3_32BIT_REGISTER HostCoalesceFtqCtrl;
-       T3_32BIT_REGISTER HostCoalesceFtqFullCnt;
-       T3_32BIT_REGISTER HostCoalesceFtqFifoEnqueueDequeue;
-       T3_32BIT_REGISTER HostCoalesceFtqFifoWritePeek;
-
-       T3_32BIT_REGISTER MacTxFtqCtrl;
-       T3_32BIT_REGISTER MacTxFtqFullCnt;
-       T3_32BIT_REGISTER MacTxFtqFifoEnqueueDequeue;
-       T3_32BIT_REGISTER MacTxFtqFifoWritePeek;
-
-       T3_32BIT_REGISTER MbufClustFreeFtqCtrl;
-       T3_32BIT_REGISTER MbufClustFreeFtqFullCnt;
-       T3_32BIT_REGISTER MbufClustFreeFtqFifoEnqueueDequeue;
-       T3_32BIT_REGISTER MbufClustFreeFtqFifoWritePeek;
-
-       T3_32BIT_REGISTER RcvBdCompFtqCtrl;
-       T3_32BIT_REGISTER RcvBdCompFtqFullCnt;
-       T3_32BIT_REGISTER RcvBdCompFtqFifoEnqueueDequeue;
-       T3_32BIT_REGISTER RcvBdCompFtqFifoWritePeek;
-
-       T3_32BIT_REGISTER RcvListPlmtFtqCtrl;
-       T3_32BIT_REGISTER RcvListPlmtFtqFullCnt;
-       T3_32BIT_REGISTER RcvListPlmtFtqFifoEnqueueDequeue;
-       T3_32BIT_REGISTER RcvListPlmtFtqFifoWritePeek;
-
-       T3_32BIT_REGISTER RcvDataBdInitiatorFtqCtrl;
-       T3_32BIT_REGISTER RcvDataBdInitiatorFtqFullCnt;
-       T3_32BIT_REGISTER RcvDataBdInitiatorFtqFifoEnqueueDequeue;
-       T3_32BIT_REGISTER RcvDataBdInitiatorFtqFifoWritePeek;
-
-       T3_32BIT_REGISTER RcvDataCompFtqCtrl;
-       T3_32BIT_REGISTER RcvDataCompFtqFullCnt;
-       T3_32BIT_REGISTER RcvDataCompFtqFifoEnqueueDequeue;
-       T3_32BIT_REGISTER RcvDataCompFtqFifoWritePeek;
-
-       T3_32BIT_REGISTER SwType2FtqCtrl;
-       T3_32BIT_REGISTER SwType2FtqFullCnt;
-       T3_32BIT_REGISTER SwType2FtqFifoEnqueueDequeue;
-       T3_32BIT_REGISTER SwType2FtqFifoWritePeek;
-
-       /* Unused space. */
-       LM_UINT8 Unused2[736];
-} T3_FTQ, *PT3_FTQ;
-
-/******************************************************************************/
-/* Message signaled interrupt registers. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Mode;
-#define MSI_MODE_RESET       BIT_0
-#define MSI_MODE_ENABLE      BIT_1
-       T3_32BIT_REGISTER Status;
-
-       T3_32BIT_REGISTER MsiFifoAccess;
-
-       /* Unused space. */
-       LM_UINT8 Unused[1012];
-} T3_MSG_SIGNALED_INT, *PT3_MSG_SIGNALED_INT;
-
-/******************************************************************************/
-/* DMA Completion registes. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Mode;
-#define DMA_COMP_MODE_RESET                         BIT_0
-#define DMA_COMP_MODE_ENABLE                        BIT_1
-
-       /* Unused space. */
-       LM_UINT8 Unused[1020];
-} T3_DMA_COMPLETION, *PT3_DMA_COMPLETION;
-
-/******************************************************************************/
-/* GRC registers. */
-/******************************************************************************/
-
-typedef struct {
-       /* Mode control register. */
-       T3_32BIT_REGISTER Mode;
-#define GRC_MODE_UPDATE_ON_COALESCING               BIT_0
-#define GRC_MODE_BYTE_SWAP_NON_FRAME_DATA           BIT_1
-#define GRC_MODE_WORD_SWAP_NON_FRAME_DATA           BIT_2
-#define GRC_MODE_BYTE_SWAP_DATA                     BIT_4
-#define GRC_MODE_WORD_SWAP_DATA                     BIT_5
-#define GRC_MODE_SPLIT_HEADER_MODE                  BIT_8
-#define GRC_MODE_NO_FRAME_CRACKING                  BIT_9
-#define GRC_MODE_INCLUDE_CRC                        BIT_10
-#define GRC_MODE_ALLOW_BAD_FRAMES                   BIT_11
-#define GRC_MODE_NO_INTERRUPT_ON_SENDS              BIT_13
-#define GRC_MODE_NO_INTERRUPT_ON_RECEIVE            BIT_14
-#define GRC_MODE_FORCE_32BIT_PCI_BUS_MODE           BIT_15
-#define GRC_MODE_HOST_STACK_UP                      BIT_16
-#define GRC_MODE_HOST_SEND_BDS                      BIT_17
-#define GRC_MODE_TX_NO_PSEUDO_HEADER_CHKSUM         BIT_20
-#define GRC_MODE_RX_NO_PSEUDO_HEADER_CHKSUM         BIT_23
-#define GRC_MODE_INT_ON_TX_CPU_ATTN                 BIT_24
-#define GRC_MODE_INT_ON_RX_CPU_ATTN                 BIT_25
-#define GRC_MODE_INT_ON_MAC_ATTN                    BIT_26
-#define GRC_MODE_INT_ON_DMA_ATTN                    BIT_27
-#define GRC_MODE_INT_ON_FLOW_ATTN                   BIT_28
-#define GRC_MODE_4X_NIC_BASED_SEND_RINGS            BIT_29
-#define GRC_MODE_MULTICAST_FRAME_ENABLE             BIT_30
-
-       /* Misc configuration register. */
-       T3_32BIT_REGISTER MiscCfg;
-#define GRC_MISC_CFG_CORE_CLOCK_RESET               BIT_0
-#define GRC_MISC_PRESCALAR_TIMER_MASK               0xfe
-#define GRC_MISC_BD_ID_MASK                         0x0001e000
-#define GRC_MISC_BD_ID_5700                         0x0001e000
-#define GRC_MISC_BD_ID_5701                         0x00000000
-#define GRC_MISC_BD_ID_5703                         0x00000000
-#define GRC_MISC_BD_ID_5703S                        0x00002000
-#define GRC_MISC_BD_ID_5702FE                       0x00004000
-#define GRC_MISC_BD_ID_5704                         0x00000000
-#define GRC_MISC_BD_ID_5704CIOBE                    0x00004000
-
-       /* Miscellaneous local control register. */
-       T3_32BIT_REGISTER LocalCtrl;
-#define GRC_MISC_LOCAL_CTRL_INT_ACTIVE              BIT_0
-#define GRC_MISC_LOCAL_CTRL_CLEAR_INT               BIT_1
-#define GRC_MISC_LOCAL_CTRL_SET_INT                 BIT_2
-#define GRC_MISC_LOCAL_CTRL_INT_ON_ATTN             BIT_3
-#define GRC_MISC_LOCAL_CTRL_GPIO_INPUT0             BIT_8
-#define GRC_MISC_LOCAL_CTRL_GPIO_INPUT1             BIT_9
-#define GRC_MISC_LOCAL_CTRL_GPIO_INPUT2             BIT_10
-#define GRC_MISC_LOCAL_CTRL_GPIO_OE0                BIT_11
-#define GRC_MISC_LOCAL_CTRL_GPIO_OE1                BIT_12
-#define GRC_MISC_LOCAL_CTRL_GPIO_OE2                BIT_13
-#define GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0            BIT_14
-#define GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1            BIT_15
-#define GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2            BIT_16
-#define GRC_MISC_LOCAL_CTRL_ENABLE_EXT_MEMORY       BIT_17
-#define GRC_MISC_LOCAL_CTRL_BANK_SELECT             BIT_21
-#define GRC_MISC_LOCAL_CTRL_SSRAM_TYPE              BIT_22
-
-#define GRC_MISC_MEMSIZE_256K     0
-#define GRC_MISC_MEMSIZE_512K     (1 << 18)
-#define GRC_MISC_MEMSIZE_1024K    (2 << 18)
-#define GRC_MISC_MEMSIZE_2048K    (3 << 18)
-#define GRC_MISC_MEMSIZE_4096K    (4 << 18)
-#define GRC_MISC_MEMSIZE_8192K    (5 << 18)
-#define GRC_MISC_MEMSIZE_16M      (6 << 18)
-#define GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM            BIT_24
-
-       T3_32BIT_REGISTER Timer;
-
-       T3_32BIT_REGISTER RxCpuEvent;
-       T3_32BIT_REGISTER RxTimerRef;
-       T3_32BIT_REGISTER RxCpuSemaphore;
-       T3_32BIT_REGISTER RemoteRxCpuAttn;
-
-       T3_32BIT_REGISTER TxCpuEvent;
-       T3_32BIT_REGISTER TxTimerRef;
-       T3_32BIT_REGISTER TxCpuSemaphore;
-       T3_32BIT_REGISTER RemoteTxCpuAttn;
-
-       T3_64BIT_REGISTER MemoryPowerUp;
-
-       T3_32BIT_REGISTER EepromAddr;
-#define SEEPROM_ADDR_WRITE       0
-#define SEEPROM_ADDR_READ        (1 << 31)
-#define SEEPROM_ADDR_RW_MASK     0x80000000
-#define SEEPROM_ADDR_COMPLETE    (1 << 30)
-#define SEEPROM_ADDR_FSM_RESET   (1 << 29)
-#define SEEPROM_ADDR_DEV_ID(x)   (x << 26)
-#define SEEPROM_ADDR_DEV_ID_MASK 0x1c000000
-#define SEEPROM_ADDR_START       (1 << 25)
-#define SEEPROM_ADDR_CLK_PERD(x) (x << 16)
-#define SEEPROM_ADDR_ADDRESS(x)  (x & 0xfffc)
-#define SEEPROM_ADDR_ADDRESS_MASK 0x0000ffff
-
-#define SEEPROM_CLOCK_PERIOD        60
-#define SEEPROM_CHIP_SIZE           (64 * 1024)
-
-       T3_32BIT_REGISTER EepromData;
-       T3_32BIT_REGISTER EepromCtrl;
-
-       T3_32BIT_REGISTER MdiCtrl;
-       T3_32BIT_REGISTER SepromDelay;
-
-       /* Unused space. */
-       LM_UINT8 Unused[948];
-} T3_GRC, *PT3_GRC;
-
-/******************************************************************************/
-/* NVRAM control registers. */
-/******************************************************************************/
-
-typedef struct {
-       T3_32BIT_REGISTER Cmd;
-#define NVRAM_CMD_RESET                             BIT_0
-#define NVRAM_CMD_DONE                              BIT_3
-#define NVRAM_CMD_DO_IT                             BIT_4
-#define NVRAM_CMD_WR                                BIT_5
-#define NVRAM_CMD_RD                                BIT_NONE
-#define NVRAM_CMD_ERASE                             BIT_6
-#define NVRAM_CMD_FIRST                             BIT_7
-#define NVRAM_CMD_LAST                              BIT_8
-
-       T3_32BIT_REGISTER Status;
-       T3_32BIT_REGISTER WriteData;
-
-       T3_32BIT_REGISTER Addr;
-#define NVRAM_ADDRESS_MASK                          0xffffff
-
-       T3_32BIT_REGISTER ReadData;
-
-       /* Flash config 1 register. */
-       T3_32BIT_REGISTER Config1;
-#define FLASH_INTERFACE_ENABLE                      BIT_0
-#define FLASH_SSRAM_BUFFERRED_MODE                  BIT_1
-#define FLASH_PASS_THRU_MODE                        BIT_2
-#define FLASH_BIT_BANG_MODE                         BIT_3
-#define FLASH_COMPAT_BYPASS                         BIT_31
-
-       /* Buffered flash (Atmel: AT45DB011B) specific information */
-#define BUFFERED_FLASH_PAGE_POS         9
-#define BUFFERED_FLASH_BYTE_ADDR_MASK   ((1<<BUFFERED_FLASH_PAGE_POS) - 1)
-#define BUFFERED_FLASH_PAGE_SIZE        264
-#define BUFFERED_FLASH_PHY_PAGE_SIZE    512
-
-       T3_32BIT_REGISTER Config2;
-       T3_32BIT_REGISTER Config3;
-       T3_32BIT_REGISTER SwArb;
-#define SW_ARB_REQ_SET0                             BIT_0
-#define SW_ARB_REQ_SET1                             BIT_1
-#define SW_ARB_REQ_SET2                             BIT_2
-#define SW_ARB_REQ_SET3                             BIT_3
-#define SW_ARB_REQ_CLR0                             BIT_4
-#define SW_ARB_REQ_CLR1                             BIT_5
-#define SW_ARB_REQ_CLR2                             BIT_6
-#define SW_ARB_REQ_CLR3                             BIT_7
-#define SW_ARB_GNT0                                 BIT_8
-#define SW_ARB_GNT1                                 BIT_9
-#define SW_ARB_GNT2                                 BIT_10
-#define SW_ARB_GNT3                                 BIT_11
-#define SW_ARB_REQ0                                 BIT_12
-#define SW_ARB_REQ1                                 BIT_13
-#define SW_ARB_REQ2                                 BIT_14
-#define SW_ARB_REQ3                                 BIT_15
-
-       /* Unused space. */
-       LM_UINT8 Unused[988];
-} T3_NVRAM, *PT3_NVRAM;
-
-/******************************************************************************/
-/* NIC's internal memory. */
-/******************************************************************************/
-
-typedef struct {
-       /* Page zero for the internal CPUs. */
-       LM_UINT8 PageZero[0x100];       /* 0x0000 */
-
-       /* Send RCBs. */
-       T3_RCB SendRcb[16];     /* 0x0100 */
-
-       /* Receive Return RCBs. */
-       T3_RCB RcvRetRcb[16];   /* 0x0200 */
-
-       /* Statistics block. */
-       T3_STATS_BLOCK StatsBlk;        /* 0x0300 */
-
-       /* Status block. */
-       T3_STATUS_BLOCK StatusBlk;      /* 0x0b00 */
-
-       /* Reserved for software. */
-       LM_UINT8 Reserved[1200];        /* 0x0b50 */
-
-       /* Unmapped region. */
-       LM_UINT8 Unmapped[4096];        /* 0x1000 */
-
-       /* DMA descriptors. */
-       LM_UINT8 DmaDesc[8192]; /* 0x2000 */
-
-       /* Buffer descriptors. */
-       LM_UINT8 BufferDesc[16384];     /* 0x4000 */
-} T3_FIRST_32K_SRAM, *PT3_FIRST_32K_SRAM;
-
-/******************************************************************************/
-/* Memory layout. */
-/******************************************************************************/
-
-typedef struct {
-       /* PCI configuration registers. */
-       T3_PCI_CONFIGURATION PciCfg;
-
-       /* Unused. */
-       LM_UINT8 Unused1[0x100];        /* 0x0100 */
-
-       /* Mailbox . */
-       T3_MAILBOX Mailbox;     /* 0x0200 */
-
-       /* MAC control registers. */
-       T3_MAC_CONTROL MacCtrl; /* 0x0400 */
-
-       /* Send data initiator control registers. */
-       T3_SEND_DATA_INITIATOR SndDataIn;       /* 0x0c00 */
-
-       /* Send data completion Control registers. */
-       T3_SEND_DATA_COMPLETION SndDataComp;    /* 0x1000 */
-
-       /* Send BD ring selector. */
-       T3_SEND_BD_SELECTOR SndBdSel;   /* 0x1400 */
-
-       /* Send BD initiator control registers. */
-       T3_SEND_BD_INITIATOR SndBdIn;   /* 0x1800 */
-
-       /* Send BD completion control registers. */
-       T3_SEND_BD_COMPLETION SndBdComp;        /* 0x1c00 */
-
-       /* Receive list placement control registers. */
-       T3_RCV_LIST_PLACEMENT RcvListPlmt;      /* 0x2000 */
-
-       /* Receive Data and Receive BD Initiator Control. */
-       T3_RCV_DATA_BD_INITIATOR RcvDataBdIn;   /* 0x2400 */
-
-       /* Receive Data Completion Control */
-       T3_RCV_DATA_COMPLETION RcvDataComp;     /* 0x2800 */
-
-       /* Receive BD Initiator Control Registers. */
-       T3_RCV_BD_INITIATOR RcvBdIn;    /* 0x2c00 */
-
-       /* Receive BD Completion Control Registers. */
-       T3_RCV_BD_COMPLETION RcvBdComp; /* 0x3000 */
-
-       /* Receive list selector control registers. */
-       T3_RCV_LIST_SELECTOR RcvListSel;        /* 0x3400 */
-
-       /* Mbuf cluster free registers. */
-       T3_MBUF_CLUSTER_FREE MbufClusterFree;   /* 0x3800 */
-
-       /* Host coalescing control registers. */
-       T3_HOST_COALESCING HostCoalesce;        /* 0x3c00 */
-
-       /* Memory arbiter control registers. */
-       T3_MEM_ARBITER MemArbiter;      /* 0x4000 */
-
-       /* Buffer manger control registers. */
-       T3_BUFFER_MANAGER BufMgr;       /* 0x4400 */
-
-       /* Read DMA control registers. */
-       T3_DMA_READ DmaRead;    /* 0x4800 */
-
-       /* Write DMA control registers. */
-       T3_DMA_WRITE DmaWrite;  /* 0x4c00 */
-
-       T3_CPU rxCpu;           /* 0x5000 */
-       T3_CPU txCpu;           /* 0x5400 */
-
-       /* Mailboxes. */
-       T3_GRC_MAILBOX GrcMailbox;      /* 0x5800 */
-
-       /* Flow Through queues. */
-       T3_FTQ Ftq;             /* 0x5c00 */
-
-       /* Message signaled interrupt registes. */
-       T3_MSG_SIGNALED_INT Msi;        /* 0x6000 */
-
-       /* DMA completion registers. */
-       T3_DMA_COMPLETION DmaComp;      /* 0x6400 */
-
-       /* GRC registers. */
-       T3_GRC Grc;             /* 0x6800 */
-
-       /* Unused space. */
-       LM_UINT8 Unused2[1024]; /* 0x6c00 */
-
-       /* NVRAM registers. */
-       T3_NVRAM Nvram;         /* 0x7000 */
-
-       /* Unused space. */
-       LM_UINT8 Unused3[3072]; /* 0x7400 */
-
-       /* The 32k memory window into the NIC's */
-       /* internal memory.  The memory window is */
-       /* controlled by the Memory Window Base */
-       /* Address register.  This register is located */
-       /* in the PCI configuration space. */
-       union {                 /* 0x8000 */
-               T3_FIRST_32K_SRAM First32k;
-
-               /* Use the memory window base address register to determine the */
-               /* MBUF segment. */
-               LM_UINT32 Mbuf[32768 / 4];
-               LM_UINT32 MemBlock32K[32768 / 4];
-       } uIntMem;
-} T3_STD_MEM_MAP, *PT3_STD_MEM_MAP;
-
-/******************************************************************************/
-/* Adapter info. */
-/******************************************************************************/
-
-typedef struct {
-       LM_UINT16 Svid;
-       LM_UINT16 Ssid;
-       LM_UINT32 PhyId;
-       LM_UINT32 Serdes;       /* 0 = copper PHY, 1 = Serdes */
-} LM_ADAPTER_INFO, *PLM_ADAPTER_INFO;
-
-/******************************************************************************/
-/* Packet queues. */
-/******************************************************************************/
-
-DECLARE_QUEUE_TYPE (LM_RX_PACKET_Q, MAX_RX_PACKET_DESC_COUNT);
-DECLARE_QUEUE_TYPE (LM_TX_PACKET_Q, MAX_TX_PACKET_DESC_COUNT);
-
-/******************************************************************************/
-/* Tx counters. */
-/******************************************************************************/
-
-typedef struct {
-       LM_COUNTER TxPacketGoodCnt;
-       LM_COUNTER TxBytesGoodCnt;
-       LM_COUNTER TxPacketAbortedCnt;
-       LM_COUNTER NoSendBdLeftCnt;
-       LM_COUNTER NoMapRegisterLeftCnt;
-       LM_COUNTER TooManyFragmentsCnt;
-       LM_COUNTER NoTxPacketDescCnt;
-} LM_TX_COUNTERS, *PLM_TX_COUNTERS;
-
-/******************************************************************************/
-/* Rx counters. */
-/******************************************************************************/
-
-typedef struct {
-       LM_COUNTER RxPacketGoodCnt;
-       LM_COUNTER RxBytesGoodCnt;
-       LM_COUNTER RxPacketErrCnt;
-       LM_COUNTER RxErrCrcCnt;
-       LM_COUNTER RxErrCollCnt;
-       LM_COUNTER RxErrLinkLostCnt;
-       LM_COUNTER RxErrPhyDecodeCnt;
-       LM_COUNTER RxErrOddNibbleCnt;
-       LM_COUNTER RxErrMacAbortCnt;
-       LM_COUNTER RxErrShortPacketCnt;
-       LM_COUNTER RxErrNoResourceCnt;
-       LM_COUNTER RxErrLargePacketCnt;
-} LM_RX_COUNTERS, *PLM_RX_COUNTERS;
-
-/******************************************************************************/
-/* Receive producer rings. */
-/******************************************************************************/
-
-typedef enum {
-       T3_UNKNOWN_RCV_PROD_RING = 0,
-       T3_STD_RCV_PROD_RING = 1,
-       T3_MINI_RCV_PROD_RING = 2,
-       T3_JUMBO_RCV_PROD_RING = 3
-} T3_RCV_PROD_RING, *PT3_RCV_PROD_RING;
-
-/******************************************************************************/
-/* Packet descriptor. */
-/******************************************************************************/
-
-#define LM_PACKET_SIGNATURE_TX              0x6861766b
-#define LM_PACKET_SIGNATURE_RX              0x6b766168
-
-typedef struct _LM_PACKET {
-       /* Set in LM. */
-       LM_STATUS PacketStatus;
-
-       /* Set in LM for Rx, in UM for Tx. */
-       LM_UINT32 PacketSize;
-
-       LM_UINT16 Flags;
-
-       LM_UINT16 VlanTag;
-
-       union {
-               /* Send info. */
-               struct {
-                       /* Set up by UM. */
-                       LM_UINT32 FragCount;
-
-               } Tx;
-
-               /* Receive info. */
-               struct {
-                       /* This descriptor belongs to either Std, Mini, or Jumbo ring. */
-                       T3_RCV_PROD_RING RcvProdRing;
-
-                       /* Receive buffer size */
-                       LM_UINT32 RxBufferSize;
-
-                       /* Checksum information. */
-                       LM_UINT16 IpChecksum;
-                       LM_UINT16 TcpUdpChecksum;
-
-               } Rx;
-       } u;
-} LM_PACKET;
-
-/******************************************************************************/
-/* Tigon3 device block. */
-/******************************************************************************/
-
-typedef struct _LM_DEVICE_BLOCK {
-       int index;              /* Device ID */
-       /* Memory view. */
-       PT3_STD_MEM_MAP pMemView;
-
-       /* Base address of the block of memory in which the LM_PACKET descriptors */
-       /* are allocated from. */
-       PLM_VOID pPacketDescBase;
-
-       LM_UINT32 MiscHostCtrl;
-       LM_UINT32 GrcLocalCtrl;
-       LM_UINT32 DmaReadWriteCtrl;
-       LM_UINT32 PciState;
-
-       /* Rx info */
-       LM_UINT32 RxStdDescCnt;
-       LM_UINT32 RxStdQueuedCnt;
-       LM_UINT32 RxStdProdIdx;
-
-       PT3_RCV_BD pRxStdBdVirt;
-       LM_PHYSICAL_ADDRESS RxStdBdPhy;
-
-       LM_UINT32 RxPacketDescCnt;
-       LM_RX_PACKET_Q RxPacketFreeQ;
-       LM_RX_PACKET_Q RxPacketReceivedQ;
-
-       /* Receive info. */
-       PT3_RCV_BD pRcvRetBdVirt;
-       LM_PHYSICAL_ADDRESS RcvRetBdPhy;
-       LM_UINT32 RcvRetConIdx;
-
-#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
-       LM_UINT32 RxJumboDescCnt;
-       LM_UINT32 RxJumboBufferSize;
-       LM_UINT32 RxJumboQueuedCnt;
-
-       LM_UINT32 RxJumboProdIdx;
-
-       PT3_RCV_BD pRxJumboBdVirt;
-       LM_PHYSICAL_ADDRESS RxJumboBdPhy;
-#endif                         /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
-
-       /* These values are used by the upper module to inform the protocol */
-       /* of the maximum transmit/receive packet size. */
-       LM_UINT32 TxMtu;        /* Does not include CRC. */
-       LM_UINT32 RxMtu;        /* Does not include CRC. */
-
-       /* We need to shadow the EMAC, Rx, Tx mode registers.  With B0 silicon, */
-       /* we may have problems reading any MAC registers in 10mb mode. */
-       LM_UINT32 MacMode;
-       LM_UINT32 RxMode;
-       LM_UINT32 TxMode;
-
-       /* MiMode register. */
-       LM_UINT32 MiMode;
-
-       /* Host coalesce mode register. */
-       LM_UINT32 CoalesceMode;
-
-       /* Send info. */
-       LM_UINT32 TxPacketDescCnt;
-
-       /* Tx info. */
-       LM_TX_PACKET_Q TxPacketFreeQ;
-       LM_TX_PACKET_Q TxPacketActiveQ;
-       LM_TX_PACKET_Q TxPacketXmittedQ;
-
-       /* Pointers to SendBd. */
-       PT3_SND_BD pSendBdVirt;
-       LM_PHYSICAL_ADDRESS SendBdPhy;  /* Only valid for Host based Send BD. */
-
-       /* Send producer and consumer indices. */
-       LM_UINT32 SendProdIdx;
-       LM_UINT32 SendConIdx;
-
-       /* Number of BD left. */
-       atomic_t SendBdLeft;
-
-       T3_SND_BD ShadowSendBd[T3_SEND_RCB_ENTRY_COUNT];
-
-       /* Counters. */
-       LM_RX_COUNTERS RxCounters;
-       LM_TX_COUNTERS TxCounters;
-
-       /* Host coalescing parameters. */
-       LM_UINT32 RxCoalescingTicks;
-       LM_UINT32 TxCoalescingTicks;
-       LM_UINT32 RxMaxCoalescedFrames;
-       LM_UINT32 TxMaxCoalescedFrames;
-       LM_UINT32 StatsCoalescingTicks;
-       LM_UINT32 RxCoalescingTicksDuringInt;
-       LM_UINT32 TxCoalescingTicksDuringInt;
-       LM_UINT32 RxMaxCoalescedFramesDuringInt;
-       LM_UINT32 TxMaxCoalescedFramesDuringInt;
-
-       /* DMA water marks. */
-       LM_UINT32 DmaMbufLowMark;
-       LM_UINT32 RxMacMbufLowMark;
-       LM_UINT32 MbufHighMark;
-
-       /* Status block. */
-       PT3_STATUS_BLOCK pStatusBlkVirt;
-       LM_PHYSICAL_ADDRESS StatusBlkPhy;
-
-       /* Statistics block. */
-       PT3_STATS_BLOCK pStatsBlkVirt;
-       LM_PHYSICAL_ADDRESS StatsBlkPhy;
-
-       /* Current receive mask. */
-       LM_UINT32 ReceiveMask;
-
-       /* Task offload capabilities. */
-       LM_TASK_OFFLOAD TaskOffloadCap;
-
-       /* Task offload selected. */
-       LM_TASK_OFFLOAD TaskToOffload;
-
-       /* Wake up capability. */
-       LM_WAKE_UP_MODE WakeUpModeCap;
-
-       /* Wake up capability. */
-       LM_WAKE_UP_MODE WakeUpMode;
-
-       /* Flow control. */
-       LM_FLOW_CONTROL FlowControlCap;
-       LM_FLOW_CONTROL FlowControl;
-
-       /* Enable or disable PCI MWI. */
-       LM_UINT32 EnableMWI;
-
-       /* Enable 5701 tagged status mode. */
-       LM_UINT32 UseTaggedStatus;
-
-       /* NIC will not compute the pseudo header checksum.  The driver or OS */
-       /* must seed the checksum field with the pseudo checksum. */
-       LM_UINT32 NoTxPseudoHdrChksum;
-
-       /* The receive checksum in the BD does not include the pseudo checksum. */
-       /* The OS or the driver must calculate the pseudo checksum and add it to */
-       /* the checksum in the BD. */
-       LM_UINT32 NoRxPseudoHdrChksum;
-
-       /* Current node address. */
-       LM_UINT8 NodeAddress[8];
-
-       /* The adapter's node address. */
-       LM_UINT8 PermanentNodeAddress[8];
-
-       /* Adapter info. */
-       LM_UINT16 BusNum;
-       LM_UINT8 DevNum;
-       LM_UINT8 FunctNum;
-       LM_UINT16 PciVendorId;
-       LM_UINT16 PciDeviceId;
-       LM_UINT32 BondId;
-       LM_UINT8 Irq;
-       LM_UINT8 IntPin;
-       LM_UINT8 CacheLineSize;
-       LM_UINT8 PciRevId;
-#if PCIX_TARGET_WORKAROUND
-       LM_UINT32 EnablePciXFix;
-#endif
-       LM_UINT32 UndiFix;      /* new, jimmy */
-       LM_UINT32 PciCommandStatusWords;
-       LM_UINT32 ChipRevId;
-       LM_UINT16 SubsystemVendorId;
-       LM_UINT16 SubsystemId;
-#if 0                          /* Jimmy, deleted in new driver */
-       LM_UINT32 MemBaseLow;
-       LM_UINT32 MemBaseHigh;
-       LM_UINT32 MemBaseSize;
-#endif
-       PLM_UINT8 pMappedMemBase;
-
-       /* Saved PCI configuration registers for restoring after a reset. */
-       LM_UINT32 SavedCacheLineReg;
-
-       /* Phy info. */
-       LM_UINT32 PhyAddr;
-       LM_UINT32 PhyId;
-
-       /* Requested phy settings. */
-       LM_REQUESTED_MEDIA_TYPE RequestedMediaType;
-
-       /* Disable auto-negotiation. */
-       LM_UINT32 DisableAutoNeg;
-
-       /* Ways for the MAC to get link change interrupt. */
-       LM_UINT32 PhyIntMode;
-#define T3_PHY_INT_MODE_AUTO                        0
-#define T3_PHY_INT_MODE_MI_INTERRUPT                1
-#define T3_PHY_INT_MODE_LINK_READY                  2
-#define T3_PHY_INT_MODE_AUTO_POLLING                3
-
-       /* Ways to determine link change status. */
-       LM_UINT32 LinkChngMode;
-#define T3_LINK_CHNG_MODE_AUTO                      0
-#define T3_LINK_CHNG_MODE_USE_STATUS_REG            1
-#define T3_LINK_CHNG_MODE_USE_STATUS_BLOCK          2
-
-       /* LED mode. */
-       LM_UINT32 LedMode;
-
-#define LED_MODE_AUTO                               0
-
-       /* 5700/01 LED mode. */
-#define LED_MODE_THREE_LINK                         1
-#define LED_MODE_LINK10                             2
-
-       /* 5703/02/04 LED mode. */
-#define LED_MODE_OPEN_DRAIN                         1
-#define LED_MODE_OUTPUT                             2
-
-       /* WOL Speed */
-       LM_UINT32 WolSpeed;
-#define WOL_SPEED_10MB                              1
-#define WOL_SPEED_100MB                             2
-
-       /* Reset the PHY on initialization. */
-       LM_UINT32 ResetPhyOnInit;
-
-       LM_UINT32 RestoreOnWakeUp;
-       LM_REQUESTED_MEDIA_TYPE WakeUpRequestedMediaType;
-       LM_UINT32 WakeUpDisableAutoNeg;
-
-       /* Current phy settings. */
-       LM_MEDIA_TYPE MediaType;
-       LM_LINE_SPEED LineSpeed;
-       LM_LINE_SPEED OldLineSpeed;
-       LM_DUPLEX_MODE DuplexMode;
-       LM_STATUS LinkStatus;
-       LM_UINT32 advertising;  /* Jimmy, new! */
-       LM_UINT32 advertising1000;      /* Jimmy, new! */
-
-       /* Multicast address list. */
-       LM_UINT32 McEntryCount;
-       LM_UINT8 McTable[LM_MAX_MC_TABLE_SIZE][LM_MC_ENTRY_SIZE];
-
-       /* Use NIC or Host based send BD. */
-       LM_UINT32 NicSendBd;
-
-       /* Athlon fix. */
-       LM_UINT32 DelayPciGrant;
-
-       /* Enable OneDmaAtOnce */
-       LM_UINT32 OneDmaAtOnce;
-
-       /* Split Mode flags, Jimmy new */
-       LM_UINT32 SplitModeEnable;
-       LM_UINT32 SplitModeMaxReq;
-
-       /* Init flag. */
-       LM_BOOL InitDone;
-
-       /* Shutdown flag.  Set by the upper module. */
-       LM_BOOL ShuttingDown;
-
-       /* Flag to determine whether to call LM_QueueRxPackets or not in */
-       /* LM_ResetAdapter routine. */
-       LM_BOOL QueueRxPackets;
-
-       LM_UINT32 MbufBase;
-       LM_UINT32 MbufSize;
-
-       /* TRUE if we have a SERDES PHY. */
-       LM_UINT32 EnableTbi;
-
-       /* Ethernet@WireSpeed. */
-       LM_UINT32 EnableWireSpeed;
-
-       LM_UINT32 EepromWp;
-
-#if INCLUDE_TBI_SUPPORT
-       /* Autoneg state info. */
-       AN_STATE_INFO AnInfo;
-       LM_UINT32 PollTbiLink;
-       LM_UINT32 IgnoreTbiLinkChange;
-#endif
-       char PartNo[24];
-       char BootCodeVer[16];
-       char BusSpeedStr[24];   /* Jimmy, new! */
-       LM_UINT32 PhyCrcCount;
-} LM_DEVICE_BLOCK;
-
-#define T3_REG_CPU_VIEW               0xc0000000
-
-#define T3_BLOCK_DMA_RD               (1 << 0)
-#define T3_BLOCK_DMA_COMP             (1 << 1)
-#define T3_BLOCK_RX_BD_INITIATOR      (1 << 2)
-#define T3_BLOCK_RX_BD_COMP           (1 << 3)
-#define T3_BLOCK_DMA_WR               (1 << 4)
-#define T3_BLOCK_MSI_HANDLER          (1 << 5)
-#define T3_BLOCK_RX_LIST_PLMT         (1 << 6)
-#define T3_BLOCK_RX_LIST_SELECTOR     (1 << 7)
-#define T3_BLOCK_RX_DATA_INITIATOR    (1 << 8)
-#define T3_BLOCK_RX_DATA_COMP         (1 << 9)
-#define T3_BLOCK_HOST_COALESING       (1 << 10)
-#define T3_BLOCK_MAC_RX_ENGINE        (1 << 11)
-#define T3_BLOCK_MBUF_CLUSTER_FREE    (1 << 12)
-#define T3_BLOCK_SEND_BD_INITIATOR    (1 << 13)
-#define T3_BLOCK_SEND_BD_COMP         (1 << 14)
-#define T3_BLOCK_SEND_BD_SELECTOR     (1 << 15)
-#define T3_BLOCK_SEND_DATA_INITIATOR  (1 << 16)
-#define T3_BLOCK_SEND_DATA_COMP       (1 << 17)
-#define T3_BLOCK_MAC_TX_ENGINE        (1 << 18)
-#define T3_BLOCK_MEM_ARBITOR          (1 << 19)
-#define T3_BLOCK_MBUF_MANAGER         (1 << 20)
-#define T3_BLOCK_MAC_GLOBAL           (1 << 21)
-
-#define LM_ENABLE               1
-#define LM_DISABLE              2
-
-#define RX_CPU_EVT_SW0              0
-#define RX_CPU_EVT_SW1              1
-#define RX_CPU_EVT_RLP              2
-#define RX_CPU_EVT_SW3              3
-#define RX_CPU_EVT_RLS              4
-#define RX_CPU_EVT_SW4              5
-#define RX_CPU_EVT_RX_BD_COMP       6
-#define RX_CPU_EVT_SW5              7
-#define RX_CPU_EVT_RDI              8
-#define RX_CPU_EVT_DMA_WR           9
-#define RX_CPU_EVT_DMA_RD           10
-#define RX_CPU_EVT_SWQ              11
-#define RX_CPU_EVT_SW6              12
-#define RX_CPU_EVT_RDC              13
-#define RX_CPU_EVT_SW7              14
-#define RX_CPU_EVT_HOST_COALES      15
-#define RX_CPU_EVT_SW8              16
-#define RX_CPU_EVT_HIGH_DMA_WR      17
-#define RX_CPU_EVT_HIGH_DMA_RD      18
-#define RX_CPU_EVT_SW9              19
-#define RX_CPU_EVT_DMA_ATTN         20
-#define RX_CPU_EVT_LOW_P_MBOX       21
-#define RX_CPU_EVT_HIGH_P_MBOX      22
-#define RX_CPU_EVT_SW10             23
-#define RX_CPU_EVT_TX_CPU_ATTN      24
-#define RX_CPU_EVT_MAC_ATTN         25
-#define RX_CPU_EVT_RX_CPU_ATTN      26
-#define RX_CPU_EVT_FLOW_ATTN        27
-#define RX_CPU_EVT_SW11             28
-#define RX_CPU_EVT_TIMER            29
-#define RX_CPU_EVT_SW12             30
-#define RX_CPU_EVT_SW13             31
-
-/* RX-CPU event */
-#define RX_CPU_EVENT_SW_EVENT0      (1 << RX_CPU_EVT_SW0)
-#define RX_CPU_EVENT_SW_EVENT1      (1 << RX_CPU_EVT_SW1)
-#define RX_CPU_EVENT_RLP            (1 << RX_CPU_EVT_RLP)
-#define RX_CPU_EVENT_SW_EVENT3      (1 << RX_CPU_EVT_SW3)
-#define RX_CPU_EVENT_RLS            (1 << RX_CPU_EVT_RLS)
-#define RX_CPU_EVENT_SW_EVENT4      (1 << RX_CPU_EVT_SW4)
-#define RX_CPU_EVENT_RX_BD_COMP     (1 << RX_CPU_EVT_RX_BD_COMP)
-#define RX_CPU_EVENT_SW_EVENT5      (1 << RX_CPU_EVT_SW5)
-#define RX_CPU_EVENT_RDI            (1 << RX_CPU_EVT_RDI)
-#define RX_CPU_EVENT_DMA_WR         (1 << RX_CPU_EVT_DMA_WR)
-#define RX_CPU_EVENT_DMA_RD         (1 << RX_CPU_EVT_DMA_RD)
-#define RX_CPU_EVENT_SWQ            (1 << RX_CPU_EVT_SWQ)
-#define RX_CPU_EVENT_SW_EVENT6      (1 << RX_CPU_EVT_SW6)
-#define RX_CPU_EVENT_RDC            (1 << RX_CPU_EVT_RDC)
-#define RX_CPU_EVENT_SW_EVENT7      (1 << RX_CPU_EVT_SW7)
-#define RX_CPU_EVENT_HOST_COALES    (1 << RX_CPU_EVT_HOST_COALES)
-#define RX_CPU_EVENT_SW_EVENT8      (1 << RX_CPU_EVT_SW8)
-#define RX_CPU_EVENT_HIGH_DMA_WR    (1 << RX_CPU_EVT_HIGH_DMA_WR)
-#define RX_CPU_EVENT_HIGH_DMA_RD    (1 << RX_CPU_EVT_HIGH_DMA_RD)
-#define RX_CPU_EVENT_SW_EVENT9      (1 << RX_CPU_EVT_SW9)
-#define RX_CPU_EVENT_DMA_ATTN       (1 << RX_CPU_EVT_DMA_ATTN)
-#define RX_CPU_EVENT_LOW_P_MBOX     (1 << RX_CPU_EVT_LOW_P_MBOX)
-#define RX_CPU_EVENT_HIGH_P_MBOX    (1 << RX_CPU_EVT_HIGH_P_MBOX)
-#define RX_CPU_EVENT_SW_EVENT10     (1 << RX_CPU_EVT_SW10)
-#define RX_CPU_EVENT_TX_CPU_ATTN    (1 << RX_CPU_EVT_TX_CPU_ATTN)
-#define RX_CPU_EVENT_MAC_ATTN       (1 << RX_CPU_EVT_MAC_ATTN)
-#define RX_CPU_EVENT_RX_CPU_ATTN    (1 << RX_CPU_EVT_RX_CPU_ATTN)
-#define RX_CPU_EVENT_FLOW_ATTN      (1 << RX_CPU_EVT_FLOW_ATTN)
-#define RX_CPU_EVENT_SW_EVENT11     (1 << RX_CPU_EVT_SW11)
-#define RX_CPU_EVENT_TIMER          (1 << RX_CPU_EVT_TIMER)
-#define RX_CPU_EVENT_SW_EVENT12     (1 << RX_CPU_EVT_SW12)
-#define RX_CPU_EVENT_SW_EVENT13     (1 << RX_CPU_EVT_SW13)
-
-#define RX_CPU_MASK (RX_CPU_EVENT_SW_EVENT0 | \
-                    RX_CPU_EVENT_RLP | \
-                    RX_CPU_EVENT_RDI | \
-                    RX_CPU_EVENT_RDC)
-
-#define TX_CPU_EVT_SW0              0
-#define TX_CPU_EVT_SW1              1
-#define TX_CPU_EVT_SW2              2
-#define TX_CPU_EVT_SW3              3
-#define TX_CPU_EVT_TX_MAC           4
-#define TX_CPU_EVT_SW4              5
-#define TX_CPU_EVT_SBDC             6
-#define TX_CPU_EVT_SW5              7
-#define TX_CPU_EVT_SDI              8
-#define TX_CPU_EVT_DMA_WR           9
-#define TX_CPU_EVT_DMA_RD           10
-#define TX_CPU_EVT_SWQ              11
-#define TX_CPU_EVT_SW6              12
-#define TX_CPU_EVT_SDC              13
-#define TX_CPU_EVT_SW7              14
-#define TX_CPU_EVT_HOST_COALES      15
-#define TX_CPU_EVT_SW8              16
-#define TX_CPU_EVT_HIGH_DMA_WR      17
-#define TX_CPU_EVT_HIGH_DMA_RD      18
-#define TX_CPU_EVT_SW9              19
-#define TX_CPU_EVT_DMA_ATTN         20
-#define TX_CPU_EVT_LOW_P_MBOX       21
-#define TX_CPU_EVT_HIGH_P_MBOX      22
-#define TX_CPU_EVT_SW10             23
-#define TX_CPU_EVT_RX_CPU_ATTN      24
-#define TX_CPU_EVT_MAC_ATTN         25
-#define TX_CPU_EVT_TX_CPU_ATTN      26
-#define TX_CPU_EVT_FLOW_ATTN        27
-#define TX_CPU_EVT_SW11             28
-#define TX_CPU_EVT_TIMER            29
-#define TX_CPU_EVT_SW12             30
-#define TX_CPU_EVT_SW13             31
-
-/* TX-CPU event */
-#define TX_CPU_EVENT_SW_EVENT0      (1 << TX_CPU_EVT_SW0)
-#define TX_CPU_EVENT_SW_EVENT1      (1 << TX_CPU_EVT_SW1)
-#define TX_CPU_EVENT_SW_EVENT2      (1 << TX_CPU_EVT_SW2)
-#define TX_CPU_EVENT_SW_EVENT3      (1 << TX_CPU_EVT_SW3)
-#define TX_CPU_EVENT_TX_MAC         (1 << TX_CPU_EVT_TX_MAC)
-#define TX_CPU_EVENT_SW_EVENT4      (1 << TX_CPU_EVT_SW4)
-#define TX_CPU_EVENT_SBDC           (1 << TX_CPU_EVT_SBDC)
-#define TX_CPU_EVENT_SW_EVENT5      (1 << TX_CPU_EVT_SW5)
-#define TX_CPU_EVENT_SDI            (1 << TX_CPU_EVT_SDI)
-#define TX_CPU_EVENT_DMA_WR         (1 << TX_CPU_EVT_DMA_WR)
-#define TX_CPU_EVENT_DMA_RD         (1 << TX_CPU_EVT_DMA_RD)
-#define TX_CPU_EVENT_SWQ            (1 << TX_CPU_EVT_SWQ)
-#define TX_CPU_EVENT_SW_EVENT6      (1 << TX_CPU_EVT_SW6)
-#define TX_CPU_EVENT_SDC            (1 << TX_CPU_EVT_SDC)
-#define TX_CPU_EVENT_SW_EVENT7      (1 << TX_CPU_EVT_SW7)
-#define TX_CPU_EVENT_HOST_COALES    (1 << TX_CPU_EVT_HOST_COALES)
-#define TX_CPU_EVENT_SW_EVENT8      (1 << TX_CPU_EVT_SW8)
-#define TX_CPU_EVENT_HIGH_DMA_WR    (1 << TX_CPU_EVT_HIGH_DMA_WR)
-#define TX_CPU_EVENT_HIGH_DMA_RD    (1 << TX_CPU_EVT_HIGH_DMA_RD)
-#define TX_CPU_EVENT_SW_EVENT9      (1 << TX_CPU_EVT_SW9)
-#define TX_CPU_EVENT_DMA_ATTN       (1 << TX_CPU_EVT_DMA_ATTN)
-#define TX_CPU_EVENT_LOW_P_MBOX     (1 << TX_CPU_EVT_LOW_P_MBOX)
-#define TX_CPU_EVENT_HIGH_P_MBOX    (1 << TX_CPU_EVT_HIGH_P_MBOX)
-#define TX_CPU_EVENT_SW_EVENT10     (1 << TX_CPU_EVT_SW10)
-#define TX_CPU_EVENT_RX_CPU_ATTN    (1 << TX_CPU_EVT_RX_CPU_ATTN)
-#define TX_CPU_EVENT_MAC_ATTN       (1 << TX_CPU_EVT_MAC_ATTN)
-#define TX_CPU_EVENT_TX_CPU_ATTN    (1 << TX_CPU_EVT_TX_CPU_ATTN)
-#define TX_CPU_EVENT_FLOW_ATTN      (1 << TX_CPU_EVT_FLOW_ATTN)
-#define TX_CPU_EVENT_SW_EVENT11     (1 << TX_CPU_EVT_SW11)
-#define TX_CPU_EVENT_TIMER          (1 << TX_CPU_EVT_TIMER)
-#define TX_CPU_EVENT_SW_EVENT12     (1 << TX_CPU_EVT_SW12)
-#define TX_CPU_EVENT_SW_EVENT13     (1 << TX_CPU_EVT_SW13)
-
-#define TX_CPU_MASK (TX_CPU_EVENT_SW_EVENT0 | \
-                    TX_CPU_EVENT_SDI  | \
-                    TX_CPU_EVENT_SDC)
-
-#define T3_FTQ_TYPE1_UNDERFLOW_BIT   (1 << 29)
-#define T3_FTQ_TYPE1_PASS_BIT        (1 << 30)
-#define T3_FTQ_TYPE1_SKIP_BIT        (1 << 31)
-
-#define T3_FTQ_TYPE2_UNDERFLOW_BIT   (1 << 13)
-#define T3_FTQ_TYPE2_PASS_BIT        (1 << 14)
-#define T3_FTQ_TYPE2_SKIP_BIT        (1 << 15)
-
-#define T3_QID_DMA_READ               1
-#define T3_QID_DMA_HIGH_PRI_READ      2
-#define T3_QID_DMA_COMP_DX            3
-#define T3_QID_SEND_BD_COMP           4
-#define T3_QID_SEND_DATA_INITIATOR    5
-#define T3_QID_DMA_WRITE              6
-#define T3_QID_DMA_HIGH_PRI_WRITE     7
-#define T3_QID_SW_TYPE_1              8
-#define T3_QID_SEND_DATA_COMP         9
-#define T3_QID_HOST_COALESCING        10
-#define T3_QID_MAC_TX                 11
-#define T3_QID_MBUF_CLUSTER_FREE      12
-#define T3_QID_RX_BD_COMP             13
-#define T3_QID_RX_LIST_PLM            14
-#define T3_QID_RX_DATA_BD_INITIATOR   15
-#define T3_QID_RX_DATA_COMP           16
-#define T3_QID_SW_TYPE2               17
-
-LM_STATUS LM_LoadFirmware (PLM_DEVICE_BLOCK pDevice,
-                          PT3_FWIMG_INFO pFwImg,
-                          LM_UINT32 LoadCpu, LM_UINT32 StartCpu);
-
-/******************************************************************************/
-/* NIC register read/write macros. */
-/******************************************************************************/
-
-#if 0                          /* Jimmy */
-/* MAC register access. */
-LM_UINT32 LM_RegRdInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register);
-LM_VOID LM_RegWrInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register,
-                    LM_UINT32 Value32);
-
-/* MAC memory access. */
-LM_UINT32 LM_MemRdInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr);
-LM_VOID LM_MemWrInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr,
-                    LM_UINT32 Value32);
-
-#if PCIX_TARGET_WORKAROUND
-
-/* use memory-mapped accesses for mailboxes and reads, UNDI accesses
-   for writes to all other registers */
-#define REG_RD(pDevice, OffsetName)                              \
-    readl(&((pDevice)->pMemView->OffsetName))
-
-#define REG_WR(pDevice, OffsetName, Value32)                     \
-    (((OFFSETOF(T3_STD_MEM_MAP, OffsetName) >=0x200 ) &&         \
-      (OFFSETOF(T3_STD_MEM_MAP, OffsetName) <0x400)) ||                 \
-        ((pDevice)->EnablePciXFix == FALSE)) ?                  \
-    (void) writel(Value32, &((pDevice)->pMemView->OffsetName)) : \
-    LM_RegWrInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName), Value32)
-
-#define MB_REG_RD(pDevice, OffsetName)                           \
-    readl(&((pDevice)->pMemView->OffsetName))
-
-#define MB_REG_WR(pDevice, OffsetName, Value32)                  \
-    writel(Value32, &((pDevice)->pMemView->OffsetName))
-
-#define REG_RD_OFFSET(pDevice, Offset)                           \
-    readl(&((LM_UINT8 *) (pDevice)->pMemView + Offset))
-
-#define REG_WR_OFFSET(pDevice, Offset, Value32)                  \
-       (((Offset >=0x200 ) && (Offset < 0x400)) ||              \
-        ((pDevice)->EnablePciXFix == FALSE)) ?                  \
-    (void) writel(Value32, ((LM_UINT8 *) (pDevice)->pMemView + Offset)) : \
-    LM_RegWrInd(pDevice, Offset, Value32)
-
-#define MEM_RD(pDevice, AddrName)                                \
-    LM_MemRdInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName))
-#define MEM_WR(pDevice, AddrName, Value32)                       \
-    LM_MemWrInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName), Value32)
-
-#define MEM_RD_OFFSET(pDevice, Offset)                           \
-    LM_MemRdInd(pDevice, Offset)
-#define MEM_WR_OFFSET(pDevice, Offset, Value32)                  \
-    LM_MemWrInd(pDevice, Offset, Value32)
-
-#else                          /* normal target access path below */
-
-/* Register access. */
-#define REG_RD(pDevice, OffsetName)                                         \
-    readl(&((pDevice)->pMemView->OffsetName))
-#define REG_WR(pDevice, OffsetName, Value32)                                \
-    writel(Value32, &((pDevice)->pMemView->OffsetName))
-
-#define REG_RD_OFFSET(pDevice, Offset)                                      \
-    readl(((LM_UINT8 *) (pDevice)->pMemView + Offset))
-#define REG_WR_OFFSET(pDevice, Offset, Value32)                             \
-    writel(Value32, ((LM_UINT8 *) (pDevice)->pMemView + Offset))
-
-/* There could be problem access the memory window directly.  For now, */
-/* we have to go through the PCI configuration register. */
-#define MEM_RD(pDevice, AddrName)                                           \
-    LM_MemRdInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName))
-#define MEM_WR(pDevice, AddrName, Value32)                                  \
-    LM_MemWrInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName), Value32)
-
-#define MEM_RD_OFFSET(pDevice, Offset)                                      \
-    LM_MemRdInd(pDevice, Offset)
-#define MEM_WR_OFFSET(pDevice, Offset, Value32)                             \
-    LM_MemWrInd(pDevice, Offset, Value32)
-
-#endif                         /* PCIX_TARGET_WORKAROUND */
-
-#endif                         /* Jimmy, merging */
-
-  /* Jimmy...rest of file is new stuff! */
-/******************************************************************************/
-/* NIC register read/write macros. */
-/******************************************************************************/
-
-/* MAC register access. */
-LM_UINT32 LM_RegRdInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register);
-LM_VOID LM_RegWrInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register,
-                    LM_UINT32 Value32);
-
-/* MAC memory access. */
-LM_UINT32 LM_MemRdInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr);
-LM_VOID LM_MemWrInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr,
-                    LM_UINT32 Value32);
-
-#define MB_REG_WR(pDevice, OffsetName, Value32)                               \
-    ((pDevice)->UndiFix) ?                                                    \
-       LM_RegWrInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName)+0x5600,     \
-           Value32) :                                                        \
-       (void) __raw_writel(Value32, &((pDevice)->pMemView->OffsetName))
-
-#define MB_REG_RD(pDevice, OffsetName)                                        \
-    (((pDevice)->UndiFix) ?                                                   \
-       LM_RegRdInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName)+0x5600) :   \
-       __raw_readl(&((pDevice)->pMemView->OffsetName)))
-
-#define REG_RD(pDevice, OffsetName)                                           \
-    (((pDevice)->UndiFix) ?                                                   \
-       LM_RegRdInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName)) :          \
-       __raw_readl(&((pDevice)->pMemView->OffsetName)))
-
-#if PCIX_TARGET_WORKAROUND
-
-#define REG_WR(pDevice, OffsetName, Value32)                                \
-        ((pDevice)->EnablePciXFix == FALSE) ?                              \
-    (void) __raw_writel(Value32, &((pDevice)->pMemView->OffsetName)) :      \
-    LM_RegWrInd(pDevice, OFFSETOF(T3_STD_MEM_MAP, OffsetName), Value32)
-
-#else
-
-#define REG_WR(pDevice, OffsetName, Value32)                                \
-    __raw_writel(Value32, &((pDevice)->pMemView->OffsetName))
-
-#endif
-
-#define MEM_RD(pDevice, AddrName)                                           \
-    LM_MemRdInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName))
-#define MEM_WR(pDevice, AddrName, Value32)                                  \
-    LM_MemWrInd(pDevice, OFFSETOF(T3_FIRST_32K_SRAM, AddrName), Value32)
-
-#define MEM_RD_OFFSET(pDevice, Offset)                                      \
-    LM_MemRdInd(pDevice, Offset)
-#define MEM_WR_OFFSET(pDevice, Offset, Value32)                             \
-    LM_MemWrInd(pDevice, Offset, Value32)
-
-#endif                         /* TIGON3_H */
diff --git a/drivers/tqm8xx_pcmcia.c b/drivers/tqm8xx_pcmcia.c
deleted file mode 100644 (file)
index 132c7a5..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-/* -------------------------------------------------------------------- */
-/* TQM8xxL Boards by TQ Components                                     */
-/* SC8xx   Boards by SinoVee Microsystems                              */
-/* -------------------------------------------------------------------- */
-#include <common.h>
-#ifdef CONFIG_8xx
-#include <mpc8xx.h>
-#endif
-#include <pcmcia.h>
-
-#undef CONFIG_PCMCIA
-
-#if defined(CONFIG_CMD_PCMCIA)
-#define        CONFIG_PCMCIA
-#endif
-
-#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
-#define        CONFIG_PCMCIA
-#endif
-
-#if    defined(CONFIG_PCMCIA)  \
-       && (defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx))
-
-#if    defined(CONFIG_VIRTLAB2)
-#define        PCMCIA_BOARD_MSG        "Virtlab2"
-#elif  defined(CONFIG_TQM8xxL)
-#define        PCMCIA_BOARD_MSG        "TQM8xxL"
-#elif  defined(CONFIG_SVM_SC8xx)
-#define        PCMCIA_BOARD_MSG        "SC8xx"
-#endif
-
-#if    defined(CONFIG_NSCU)
-
-#define        power_config(slot)      do {} while (0)
-#define        power_off(slot)         do {} while (0)
-#define        power_on_5_0(slot)      do {} while (0)
-#define        power_on_3_3(slot)      do {} while (0)
-
-#elif  defined(CONFIG_HMI10)
-
-static inline void power_config(int slot)
-{
-       volatile immap_t *immap = (immap_t *)CFG_IMMR;
-       /*
-        * Configure Port B  pins for
-        * 5 Volts Enable and 3 Volts enable
-       */
-       immap->im_cpm.cp_pbpar &= ~(0x00000300);
-}
-
-static inline void power_off(int slot)
-{
-       volatile immap_t *immap = (immap_t *)CFG_IMMR;
-       /* remove all power */
-       immap->im_cpm.cp_pbdat |= 0x00000300;
-}
-
-static inline void power_on_5_0(int slot)
-{
-       volatile immap_t *immap = (immap_t *)CFG_IMMR;
-       immap->im_cpm.cp_pbdat &= ~(0x0000100);
-       immap->im_cpm.cp_pbdir |= 0x00000300;
-}
-
-static inline void power_on_3_3(int slot)
-{
-       volatile immap_t *immap = (immap_t *)CFG_IMMR;
-       immap->im_cpm.cp_pbdat &= ~(0x0000200);
-       immap->im_cpm.cp_pbdir |= 0x00000300;
-}
-
-#elif  defined(CONFIG_VIRTLAB2)
-
-#define        power_config(slot)      do {} while (0)
-static inline void power_off(int slot)
-{
-       volatile unsigned char  *powerctl =
-                       (volatile unsigned char *)PCMCIA_CTRL;
-       *powerctl = 0;
-}
-
-static inline void power_on_5_0(int slot)
-{
-       volatile unsigned char  *powerctl =
-                       (volatile unsigned char *)PCMCIA_CTRL;
-                       *powerctl = 2;  /* Enable 5V Vccout */
-}
-
-static inline void power_on_3_3(int slot)
-{
-       volatile unsigned char  *powerctl =
-                       (volatile unsigned char *)PCMCIA_CTRL;
-                       *powerctl = 1;  /* Enable 3.3V Vccout */
-}
-
-#else
-
-static inline void power_config(int slot)
-{
-       volatile immap_t *immap = (immap_t *)CFG_IMMR;
-       /*
-       * Configure Port C pins for
-       * 5 Volts Enable and 3 Volts enable
-       */
-       immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
-       immap->im_ioport.iop_pcso  &= ~(0x0002 | 0x0004);
-}
-
-static inline void power_off(int slot)
-{
-       volatile immap_t *immap = (immap_t *)CFG_IMMR;
-       immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
-}
-
-static inline void power_on_5_0(int slot)
-{
-       volatile immap_t *immap = (immap_t *)CFG_IMMR;
-       immap->im_ioport.iop_pcdat |= 0x0004;
-       immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
-}
-
-static inline void power_on_3_3(int slot)
-{
-       volatile immap_t *immap = (immap_t *)CFG_IMMR;
-       immap->im_ioport.iop_pcdat |= 0x0002;
-       immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
-}
-
-#endif
-
-#ifdef CONFIG_HMI10
-static inline int check_card_is_absent(int slot)
-{
-       volatile pcmconf8xx_t *pcmp =
-               (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
-       return pcmp->pcmc_pipr & (0x10000000 >> (slot << 4));
-}
-#else
-static inline int check_card_is_absent(int slot)
-{
-       volatile pcmconf8xx_t *pcmp =
-               (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
-       return pcmp->pcmc_pipr & (0x18000000 >> (slot << 4));
-}
-#endif
-
-#ifdef NSCU_OE_INV
-#define        NSCU_GCRX_CXOE  0
-#else
-#define        NSCU_GCRX_CXOE  __MY_PCMCIA_GCRX_CXOE
-#endif
-
-int pcmcia_hardware_enable(int slot)
-{
-       volatile pcmconf8xx_t *pcmp =
-               (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
-       volatile sysconf8xx_t *sysp =
-               (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
-       uint reg, mask;
-
-       debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
-       udelay(10000);
-
-       /*
-       * Configure SIUMCR to enable PCMCIA port B
-       * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
-       */
-       sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
-
-       /* clear interrupt state, and disable interrupts */
-       pcmp->pcmc_pscr =  PCMCIA_MASK(slot);
-       pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
-
-       /*
-       * Disable interrupts, DMA, and PCMCIA buffers
-       * (isolate the interface) and assert RESET signal
-       */
-       debug ("Disable PCMCIA buffers and assert RESET\n");
-       reg  = 0;
-       reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
-       reg |= NSCU_GCRX_CXOE;
-
-       PCMCIA_PGCRX(slot) = reg;
-       udelay(500);
-
-       power_config(slot);
-       power_off(slot);
-
-       /*
-        * Make sure there is a card in the slot, then configure the interface.
-       */
-       udelay(10000);
-       debug ("[%d] %s: PIPR(%p)=0x%x\n", __LINE__,__FUNCTION__,
-              &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
-
-       if (check_card_is_absent(slot)) {
-               printf ("   No Card found\n");
-               return (1);
-       }
-
-       /*
-       * Power On.
-       */
-       mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
-       reg  = pcmp->pcmc_pipr;
-       debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
-              reg,
-              (reg&PCMCIA_VS1(slot))?"n":"ff",
-              (reg&PCMCIA_VS2(slot))?"n":"ff");
-
-       if ((reg & mask) == mask) {
-               power_on_5_0(slot);
-               puts (" 5.0V card found: ");
-       } else {
-               power_on_3_3(slot);
-               puts (" 3.3V card found: ");
-       }
-
-#if 0
-       /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
-       cp->cp_pbdir &= ~(0x0020 | 0x0010);
-       cp->cp_pbpar &= ~(0x0020 | 0x0010);
-       udelay(500000);
-#endif
-
-       udelay(1000);
-       debug ("Enable PCMCIA buffers and stop RESET\n");
-       reg  =  PCMCIA_PGCRX(slot);
-       reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
-       reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
-       reg &= ~NSCU_GCRX_CXOE;
-
-       PCMCIA_PGCRX(slot) = reg;
-
-       udelay(250000); /* some cards need >150 ms to come up :-( */
-
-       debug ("# hardware_enable done\n");
-
-       return (0);
-}
-
-
-#if defined(CONFIG_CMD_PCMCIA)
-int pcmcia_hardware_disable(int slot)
-{
-       u_long reg;
-
-       debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
-
-       /* remove all power */
-       power_off(slot);
-
-       debug ("Disable PCMCIA buffers and assert RESET\n");
-       reg  = 0;
-       reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
-       reg |= NSCU_GCRX_CXOE;                  /* active low  */
-
-       PCMCIA_PGCRX(slot) = reg;
-
-       udelay(10000);
-
-       return (0);
-}
-#endif
-
-int pcmcia_voltage_set(int slot, int vcc, int vpp)
-{
-#ifndef CONFIG_NSCU
-       u_long reg;
-# ifdef DEBUG
-       volatile pcmconf8xx_t *pcmp =
-               (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
-# endif
-
-       debug ("voltage_set: " PCMCIA_BOARD_MSG
-               " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
-               'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
-
-       /*
-       * Disable PCMCIA buffers (isolate the interface)
-       * and assert RESET signal
-       */
-       debug ("Disable PCMCIA buffers and assert RESET\n");
-       reg  = PCMCIA_PGCRX(slot);
-       reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
-       reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
-       reg |= NSCU_GCRX_CXOE;                  /* active low  */
-
-       PCMCIA_PGCRX(slot) = reg;
-       udelay(500);
-
-       debug ("PCMCIA power OFF\n");
-       power_config(slot);
-       power_off(slot);
-
-       switch(vcc) {
-               case  0:                        break;
-               case 33: power_on_3_3(slot);    break;
-               case 50: power_on_5_0(slot);    break;
-               default:                        goto done;
-       }
-
-       /* Checking supported voltages */
-
-       debug("PIPR: 0x%x --> %s\n", pcmp->pcmc_pipr,
-              (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
-
-       if (vcc)
-               debug("PCMCIA powered at %sV\n", (vcc == 50) ? "5.0" : "3.3");
-       else
-               debug("PCMCIA powered down\n");
-
-done:
-       debug("Enable PCMCIA buffers and stop RESET\n");
-       reg  =  PCMCIA_PGCRX(slot);
-       reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
-       reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
-       reg &= ~NSCU_GCRX_CXOE;                 /* active low  */
-
-       PCMCIA_PGCRX(slot) = reg;
-       udelay(500);
-
-       debug("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n", slot+'A');
-#endif /* CONFIG_NSCU */
-       return (0);
-}
-
-#endif /* CONFIG_PCMCIA && (CONFIG_TQM8xxL || CONFIG_SVM_SC8xx) */
diff --git a/drivers/tsec.c b/drivers/tsec.c
deleted file mode 100644 (file)
index 4ff3339..0000000
+++ /dev/null
@@ -1,1586 +0,0 @@
-/*
- * Freescale Three Speed Ethernet Controller driver
- *
- * This software may be used and distributed according to the
- * terms of the GNU Public License, Version 2, incorporated
- * herein by reference.
- *
- * Copyright 2004, 2007 Freescale Semiconductor, Inc.
- * (C) Copyright 2003, Motorola, Inc.
- * author Andy Fleming
- *
- */
-
-#include <config.h>
-#include <common.h>
-#include <malloc.h>
-#include <net.h>
-#include <command.h>
-
-#if defined(CONFIG_TSEC_ENET)
-#include "tsec.h"
-#include "miiphy.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#define TX_BUF_CNT             2
-
-static uint rxIdx;             /* index of the current RX buffer */
-static uint txIdx;             /* index of the current TX buffer */
-
-typedef volatile struct rtxbd {
-       txbd8_t txbd[TX_BUF_CNT];
-       rxbd8_t rxbd[PKTBUFSRX];
-} RTXBD;
-
-struct tsec_info_struct {
-       unsigned int phyaddr;
-       u32 flags;
-       unsigned int phyregidx;
-};
-
-/* The tsec_info structure contains 3 values which the
- * driver uses to determine how to operate a given ethernet
- * device. The information needed is:
- *  phyaddr - The address of the PHY which is attached to
- *     the given device.
- *
- *  flags - This variable indicates whether the device
- *     supports gigabit speed ethernet, and whether it should be
- *     in reduced mode.
- *
- *  phyregidx - This variable specifies which ethernet device
- *     controls the MII Management registers which are connected
- *     to the PHY.  For now, only TSEC1 (index 0) has
- *     access to the PHYs, so all of the entries have "0".
- *
- * The values specified in the table are taken from the board's
- * config file in include/configs/.  When implementing a new
- * board with ethernet capability, it is necessary to define:
- *   TSECn_PHY_ADDR
- *   TSECn_PHYIDX
- *
- * for n = 1,2,3, etc.  And for FEC:
- *   FEC_PHY_ADDR
- *   FEC_PHYIDX
- */
-static struct tsec_info_struct tsec_info[] = {
-#ifdef CONFIG_TSEC1
-       {TSEC1_PHY_ADDR, TSEC1_FLAGS, TSEC1_PHYIDX},
-#else
-       {0, 0, 0},
-#endif
-#ifdef CONFIG_TSEC2
-       {TSEC2_PHY_ADDR, TSEC2_FLAGS, TSEC2_PHYIDX},
-#else
-       {0, 0, 0},
-#endif
-#ifdef CONFIG_MPC85XX_FEC
-       {FEC_PHY_ADDR, FEC_FLAGS, FEC_PHYIDX},
-#else
-#ifdef CONFIG_TSEC3
-       {TSEC3_PHY_ADDR, TSEC3_FLAGS, TSEC3_PHYIDX},
-#else
-       {0, 0, 0},
-#endif
-#ifdef CONFIG_TSEC4
-       {TSEC4_PHY_ADDR, TSEC4_FLAGS, TSEC4_PHYIDX},
-#else
-       {0, 0, 0},
-#endif /* CONFIG_TSEC4 */
-#endif /* CONFIG_MPC85XX_FEC */
-};
-
-#define MAXCONTROLLERS (4)
-
-static int relocated = 0;
-
-static struct tsec_private *privlist[MAXCONTROLLERS];
-
-#ifdef __GNUC__
-static RTXBD rtx __attribute__ ((aligned(8)));
-#else
-#error "rtx must be 64-bit aligned"
-#endif
-
-static int tsec_send(struct eth_device *dev,
-                    volatile void *packet, int length);
-static int tsec_recv(struct eth_device *dev);
-static int tsec_init(struct eth_device *dev, bd_t * bd);
-static void tsec_halt(struct eth_device *dev);
-static void init_registers(volatile tsec_t * regs);
-static void startup_tsec(struct eth_device *dev);
-static int init_phy(struct eth_device *dev);
-void write_phy_reg(struct tsec_private *priv, uint regnum, uint value);
-uint read_phy_reg(struct tsec_private *priv, uint regnum);
-struct phy_info *get_phy_info(struct eth_device *dev);
-void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd);
-static void adjust_link(struct eth_device *dev);
-static void relocate_cmds(void);
-static int tsec_miiphy_write(char *devname, unsigned char addr,
-                            unsigned char reg, unsigned short value);
-static int tsec_miiphy_read(char *devname, unsigned char addr,
-                           unsigned char reg, unsigned short *value);
-#ifdef CONFIG_MCAST_TFTP
-static int tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set);
-#endif
-
-/* Initialize device structure. Returns success if PHY
- * initialization succeeded (i.e. if it recognizes the PHY)
- */
-int tsec_initialize(bd_t * bis, int index, char *devname)
-{
-       struct eth_device *dev;
-       int i;
-       struct tsec_private *priv;
-
-       dev = (struct eth_device *)malloc(sizeof *dev);
-
-       if (NULL == dev)
-               return 0;
-
-       memset(dev, 0, sizeof *dev);
-
-       priv = (struct tsec_private *)malloc(sizeof(*priv));
-
-       if (NULL == priv)
-               return 0;
-
-       privlist[index] = priv;
-       priv->regs = (volatile tsec_t *)(TSEC_BASE_ADDR + index * TSEC_SIZE);
-       priv->phyregs = (volatile tsec_t *)(TSEC_BASE_ADDR +
-                                           tsec_info[index].phyregidx *
-                                           TSEC_SIZE);
-
-       priv->phyaddr = tsec_info[index].phyaddr;
-       priv->flags = tsec_info[index].flags;
-
-       sprintf(dev->name, devname);
-       dev->iobase = 0;
-       dev->priv = priv;
-       dev->init = tsec_init;
-       dev->halt = tsec_halt;
-       dev->send = tsec_send;
-       dev->recv = tsec_recv;
-#ifdef CONFIG_MCAST_TFTP
-       dev->mcast = tsec_mcast_addr;
-#endif
-
-       /* Tell u-boot to get the addr from the env */
-       for (i = 0; i < 6; i++)
-               dev->enetaddr[i] = 0;
-
-       eth_register(dev);
-
-       /* Reset the MAC */
-       priv->regs->maccfg1 |= MACCFG1_SOFT_RESET;
-       priv->regs->maccfg1 &= ~(MACCFG1_SOFT_RESET);
-
-#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
-       && !defined(BITBANGMII)
-       miiphy_register(dev->name, tsec_miiphy_read, tsec_miiphy_write);
-#endif
-
-       /* Try to initialize PHY here, and return */
-       return init_phy(dev);
-}
-
-/* Initializes data structures and registers for the controller,
- * and brings the interface up.         Returns the link status, meaning
- * that it returns success if the link is up, failure otherwise.
- * This allows u-boot to find the first active controller.
- */
-int tsec_init(struct eth_device *dev, bd_t * bd)
-{
-       uint tempval;
-       char tmpbuf[MAC_ADDR_LEN];
-       int i;
-       struct tsec_private *priv = (struct tsec_private *)dev->priv;
-       volatile tsec_t *regs = priv->regs;
-
-       /* Make sure the controller is stopped */
-       tsec_halt(dev);
-
-       /* Init MACCFG2.  Defaults to GMII */
-       regs->maccfg2 = MACCFG2_INIT_SETTINGS;
-
-       /* Init ECNTRL */
-       regs->ecntrl = ECNTRL_INIT_SETTINGS;
-
-       /* Copy the station address into the address registers.
-        * Backwards, because little endian MACS are dumb */
-       for (i = 0; i < MAC_ADDR_LEN; i++) {
-               tmpbuf[MAC_ADDR_LEN - 1 - i] = dev->enetaddr[i];
-       }
-       regs->macstnaddr1 = *((uint *) (tmpbuf));
-
-       tempval = *((uint *) (tmpbuf + 4));
-
-       regs->macstnaddr2 = tempval;
-
-       /* reset the indices to zero */
-       rxIdx = 0;
-       txIdx = 0;
-
-       /* Clear out (for the most part) the other registers */
-       init_registers(regs);
-
-       /* Ready the device for tx/rx */
-       startup_tsec(dev);
-
-       /* If there's no link, fail */
-       return priv->link;
-
-}
-
-/* Write value to the device's PHY through the registers
- * specified in priv, modifying the register specified in regnum.
- * It will wait for the write to be done (or for a timeout to
- * expire) before exiting
- */
-void write_phy_reg(struct tsec_private *priv, uint regnum, uint value)
-{
-       volatile tsec_t *regbase = priv->phyregs;
-       uint phyid = priv->phyaddr;
-       int timeout = 1000000;
-
-       regbase->miimadd = (phyid << 8) | regnum;
-       regbase->miimcon = value;
-       asm("sync");
-
-       timeout = 1000000;
-       while ((regbase->miimind & MIIMIND_BUSY) && timeout--) ;
-}
-
-/* Reads register regnum on the device's PHY through the
- * registers specified in priv.         It lowers and raises the read
- * command, and waits for the data to become valid (miimind
- * notvalid bit cleared), and the bus to cease activity (miimind
- * busy bit cleared), and then returns the value
- */
-uint read_phy_reg(struct tsec_private *priv, uint regnum)
-{
-       uint value;
-       volatile tsec_t *regbase = priv->phyregs;
-       uint phyid = priv->phyaddr;
-
-       /* Put the address of the phy, and the register
-        * number into MIIMADD */
-       regbase->miimadd = (phyid << 8) | regnum;
-
-       /* Clear the command register, and wait */
-       regbase->miimcom = 0;
-       asm("sync");
-
-       /* Initiate a read command, and wait */
-       regbase->miimcom = MIIM_READ_COMMAND;
-       asm("sync");
-
-       /* Wait for the the indication that the read is done */
-       while ((regbase->miimind & (MIIMIND_NOTVALID | MIIMIND_BUSY))) ;
-
-       /* Grab the value read from the PHY */
-       value = regbase->miimstat;
-
-       return value;
-}
-
-/* Discover which PHY is attached to the device, and configure it
- * properly.  If the PHY is not recognized, then return 0
- * (failure).  Otherwise, return 1
- */
-static int init_phy(struct eth_device *dev)
-{
-       struct tsec_private *priv = (struct tsec_private *)dev->priv;
-       struct phy_info *curphy;
-       volatile tsec_t *regs = (volatile tsec_t *)(TSEC_BASE_ADDR);
-
-       /* Assign a Physical address to the TBI */
-       regs->tbipa = CFG_TBIPA_VALUE;
-       regs = (volatile tsec_t *)(TSEC_BASE_ADDR + TSEC_SIZE);
-       regs->tbipa = CFG_TBIPA_VALUE;
-       asm("sync");
-
-       /* Reset MII (due to new addresses) */
-       priv->phyregs->miimcfg = MIIMCFG_RESET;
-       asm("sync");
-       priv->phyregs->miimcfg = MIIMCFG_INIT_VALUE;
-       asm("sync");
-       while (priv->phyregs->miimind & MIIMIND_BUSY) ;
-
-       if (0 == relocated)
-               relocate_cmds();
-
-       /* Get the cmd structure corresponding to the attached
-        * PHY */
-       curphy = get_phy_info(dev);
-
-       if (curphy == NULL) {
-               priv->phyinfo = NULL;
-               printf("%s: No PHY found\n", dev->name);
-
-               return 0;
-       }
-
-       priv->phyinfo = curphy;
-
-       phy_run_commands(priv, priv->phyinfo->config);
-
-       return 1;
-}
-
-/*
- * Returns which value to write to the control register.
- * For 10/100, the value is slightly different
- */
-uint mii_cr_init(uint mii_reg, struct tsec_private * priv)
-{
-       if (priv->flags & TSEC_GIGABIT)
-               return MIIM_CONTROL_INIT;
-       else
-               return MIIM_CR_INIT;
-}
-
-/* Parse the status register for link, and then do
- * auto-negotiation
- */
-uint mii_parse_sr(uint mii_reg, struct tsec_private * priv)
-{
-       /*
-        * Wait if the link is up, and autonegotiation is in progress
-        * (ie - we're capable and it's not done)
-        */
-       mii_reg = read_phy_reg(priv, MIIM_STATUS);
-       if ((mii_reg & MIIM_STATUS_LINK) && (mii_reg & PHY_BMSR_AUTN_ABLE)
-           && !(mii_reg & PHY_BMSR_AUTN_COMP)) {
-               int i = 0;
-
-               puts("Waiting for PHY auto negotiation to complete");
-               while (!(mii_reg & PHY_BMSR_AUTN_COMP)) {
-                       /*
-                        * Timeout reached ?
-                        */
-                       if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
-                               puts(" TIMEOUT !\n");
-                               priv->link = 0;
-                               return 0;
-                       }
-
-                       if ((i++ % 1000) == 0) {
-                               putc('.');
-                       }
-                       udelay(1000);   /* 1 ms */
-                       mii_reg = read_phy_reg(priv, MIIM_STATUS);
-               }
-               puts(" done\n");
-               priv->link = 1;
-               udelay(500000); /* another 500 ms (results in faster booting) */
-       } else {
-               if (mii_reg & MIIM_STATUS_LINK)
-                       priv->link = 1;
-               else
-                       priv->link = 0;
-       }
-
-       return 0;
-}
-
-/* Generic function which updates the speed and duplex.  If
- * autonegotiation is enabled, it uses the AND of the link
- * partner's advertised capabilities and our advertised
- * capabilities.  If autonegotiation is disabled, we use the
- * appropriate bits in the control register.
- *
- * Stolen from Linux's mii.c and phy_device.c
- */
-uint mii_parse_link(uint mii_reg, struct tsec_private *priv)
-{
-       /* We're using autonegotiation */
-       if (mii_reg & PHY_BMSR_AUTN_ABLE) {
-               uint lpa = 0;
-               uint gblpa = 0;
-
-               /* Check for gigabit capability */
-               if (mii_reg & PHY_BMSR_EXT) {
-                       /* We want a list of states supported by
-                        * both PHYs in the link
-                        */
-                       gblpa = read_phy_reg(priv, PHY_1000BTSR);
-                       gblpa &= read_phy_reg(priv, PHY_1000BTCR) << 2;
-               }
-
-               /* Set the baseline so we only have to set them
-                * if they're different
-                */
-               priv->speed = 10;
-               priv->duplexity = 0;
-
-               /* Check the gigabit fields */
-               if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
-                       priv->speed = 1000;
-
-                       if (gblpa & PHY_1000BTSR_1000FD)
-                               priv->duplexity = 1;
-
-                       /* We're done! */
-                       return 0;
-               }
-
-               lpa = read_phy_reg(priv, PHY_ANAR);
-               lpa &= read_phy_reg(priv, PHY_ANLPAR);
-
-               if (lpa & (PHY_ANLPAR_TXFD | PHY_ANLPAR_TX)) {
-                       priv->speed = 100;
-
-                       if (lpa & PHY_ANLPAR_TXFD)
-                               priv->duplexity = 1;
-
-               } else if (lpa & PHY_ANLPAR_10FD)
-                       priv->duplexity = 1;
-       } else {
-               uint bmcr = read_phy_reg(priv, PHY_BMCR);
-
-               priv->speed = 10;
-               priv->duplexity = 0;
-
-               if (bmcr & PHY_BMCR_DPLX)
-                       priv->duplexity = 1;
-
-               if (bmcr & PHY_BMCR_1000_MBPS)
-                       priv->speed = 1000;
-               else if (bmcr & PHY_BMCR_100_MBPS)
-                       priv->speed = 100;
-       }
-
-       return 0;
-}
-
-/*
- * Parse the BCM54xx status register for speed and duplex information.
- * The linux sungem_phy has this information, but in a table format.
- */
-uint mii_parse_BCM54xx_sr(uint mii_reg, struct tsec_private *priv)
-{
-
-       switch((mii_reg & MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK) >> MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT){
-
-               case 1:
-                       printf("Enet starting in 10BT/HD\n");
-                       priv->duplexity = 0;
-                       priv->speed = 10;
-                       break;
-
-               case 2:
-                       printf("Enet starting in 10BT/FD\n");
-                       priv->duplexity = 1;
-                       priv->speed = 10;
-                       break;
-
-               case 3:
-                       printf("Enet starting in 100BT/HD\n");
-                       priv->duplexity = 0;
-                       priv->speed = 100;
-                       break;
-
-               case 5:
-                       printf("Enet starting in 100BT/FD\n");
-                       priv->duplexity = 1;
-                       priv->speed = 100;
-                       break;
-
-               case 6:
-                       printf("Enet starting in 1000BT/HD\n");
-                       priv->duplexity = 0;
-                       priv->speed = 1000;
-                       break;
-
-               case 7:
-                       printf("Enet starting in 1000BT/FD\n");
-                       priv->duplexity = 1;
-                       priv->speed = 1000;
-                       break;
-
-               default:
-                       printf("Auto-neg error, defaulting to 10BT/HD\n");
-                       priv->duplexity = 0;
-                       priv->speed = 10;
-                       break;
-       }
-
-       return 0;
-
-}
-/* Parse the 88E1011's status register for speed and duplex
- * information
- */
-uint mii_parse_88E1011_psr(uint mii_reg, struct tsec_private * priv)
-{
-       uint speed;
-
-       mii_reg = read_phy_reg(priv, MIIM_88E1011_PHY_STATUS);
-
-       if ((mii_reg & MIIM_88E1011_PHYSTAT_LINK) &&
-               !(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) {
-               int i = 0;
-
-               puts("Waiting for PHY realtime link");
-               while (!(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) {
-                       /* Timeout reached ? */
-                       if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
-                               puts(" TIMEOUT !\n");
-                               priv->link = 0;
-                               break;
-                       }
-
-                       if ((i++ % 1000) == 0) {
-                               putc('.');
-                       }
-                       udelay(1000);   /* 1 ms */
-                       mii_reg = read_phy_reg(priv, MIIM_88E1011_PHY_STATUS);
-               }
-               puts(" done\n");
-               udelay(500000); /* another 500 ms (results in faster booting) */
-       } else {
-               if (mii_reg & MIIM_88E1011_PHYSTAT_LINK)
-                       priv->link = 1;
-               else
-                       priv->link = 0;
-       }
-
-       if (mii_reg & MIIM_88E1011_PHYSTAT_DUPLEX)
-               priv->duplexity = 1;
-       else
-               priv->duplexity = 0;
-
-       speed = (mii_reg & MIIM_88E1011_PHYSTAT_SPEED);
-
-       switch (speed) {
-       case MIIM_88E1011_PHYSTAT_GBIT:
-               priv->speed = 1000;
-               break;
-       case MIIM_88E1011_PHYSTAT_100:
-               priv->speed = 100;
-               break;
-       default:
-               priv->speed = 10;
-       }
-
-       return 0;
-}
-
-/* Parse the cis8201's status register for speed and duplex
- * information
- */
-uint mii_parse_cis8201(uint mii_reg, struct tsec_private * priv)
-{
-       uint speed;
-
-       if (mii_reg & MIIM_CIS8201_AUXCONSTAT_DUPLEX)
-               priv->duplexity = 1;
-       else
-               priv->duplexity = 0;
-
-       speed = mii_reg & MIIM_CIS8201_AUXCONSTAT_SPEED;
-       switch (speed) {
-       case MIIM_CIS8201_AUXCONSTAT_GBIT:
-               priv->speed = 1000;
-               break;
-       case MIIM_CIS8201_AUXCONSTAT_100:
-               priv->speed = 100;
-               break;
-       default:
-               priv->speed = 10;
-               break;
-       }
-
-       return 0;
-}
-
-/* Parse the vsc8244's status register for speed and duplex
- * information
- */
-uint mii_parse_vsc8244(uint mii_reg, struct tsec_private * priv)
-{
-       uint speed;
-
-       if (mii_reg & MIIM_VSC8244_AUXCONSTAT_DUPLEX)
-               priv->duplexity = 1;
-       else
-               priv->duplexity = 0;
-
-       speed = mii_reg & MIIM_VSC8244_AUXCONSTAT_SPEED;
-       switch (speed) {
-       case MIIM_VSC8244_AUXCONSTAT_GBIT:
-               priv->speed = 1000;
-               break;
-       case MIIM_VSC8244_AUXCONSTAT_100:
-               priv->speed = 100;
-               break;
-       default:
-               priv->speed = 10;
-               break;
-       }
-
-       return 0;
-}
-
-/* Parse the DM9161's status register for speed and duplex
- * information
- */
-uint mii_parse_dm9161_scsr(uint mii_reg, struct tsec_private * priv)
-{
-       if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_100H))
-               priv->speed = 100;
-       else
-               priv->speed = 10;
-
-       if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_10F))
-               priv->duplexity = 1;
-       else
-               priv->duplexity = 0;
-
-       return 0;
-}
-
-/*
- * Hack to write all 4 PHYs with the LED values
- */
-uint mii_cis8204_fixled(uint mii_reg, struct tsec_private * priv)
-{
-       uint phyid;
-       volatile tsec_t *regbase = priv->phyregs;
-       int timeout = 1000000;
-
-       for (phyid = 0; phyid < 4; phyid++) {
-               regbase->miimadd = (phyid << 8) | mii_reg;
-               regbase->miimcon = MIIM_CIS8204_SLEDCON_INIT;
-               asm("sync");
-
-               timeout = 1000000;
-               while ((regbase->miimind & MIIMIND_BUSY) && timeout--) ;
-       }
-
-       return MIIM_CIS8204_SLEDCON_INIT;
-}
-
-uint mii_cis8204_setmode(uint mii_reg, struct tsec_private * priv)
-{
-       if (priv->flags & TSEC_REDUCED)
-               return MIIM_CIS8204_EPHYCON_INIT | MIIM_CIS8204_EPHYCON_RGMII;
-       else
-               return MIIM_CIS8204_EPHYCON_INIT;
-}
-
-/* Initialized required registers to appropriate values, zeroing
- * those we don't care about (unless zero is bad, in which case,
- * choose a more appropriate value)
- */
-static void init_registers(volatile tsec_t * regs)
-{
-       /* Clear IEVENT */
-       regs->ievent = IEVENT_INIT_CLEAR;
-
-       regs->imask = IMASK_INIT_CLEAR;
-
-       regs->hash.iaddr0 = 0;
-       regs->hash.iaddr1 = 0;
-       regs->hash.iaddr2 = 0;
-       regs->hash.iaddr3 = 0;
-       regs->hash.iaddr4 = 0;
-       regs->hash.iaddr5 = 0;
-       regs->hash.iaddr6 = 0;
-       regs->hash.iaddr7 = 0;
-
-       regs->hash.gaddr0 = 0;
-       regs->hash.gaddr1 = 0;
-       regs->hash.gaddr2 = 0;
-       regs->hash.gaddr3 = 0;
-       regs->hash.gaddr4 = 0;
-       regs->hash.gaddr5 = 0;
-       regs->hash.gaddr6 = 0;
-       regs->hash.gaddr7 = 0;
-
-       regs->rctrl = 0x00000000;
-
-       /* Init RMON mib registers */
-       memset((void *)&(regs->rmon), 0, sizeof(rmon_mib_t));
-
-       regs->rmon.cam1 = 0xffffffff;
-       regs->rmon.cam2 = 0xffffffff;
-
-       regs->mrblr = MRBLR_INIT_SETTINGS;
-
-       regs->minflr = MINFLR_INIT_SETTINGS;
-
-       regs->attr = ATTR_INIT_SETTINGS;
-       regs->attreli = ATTRELI_INIT_SETTINGS;
-
-}
-
-/* Configure maccfg2 based on negotiated speed and duplex
- * reported by PHY handling code
- */
-static void adjust_link(struct eth_device *dev)
-{
-       struct tsec_private *priv = (struct tsec_private *)dev->priv;
-       volatile tsec_t *regs = priv->regs;
-
-       if (priv->link) {
-               if (priv->duplexity != 0)
-                       regs->maccfg2 |= MACCFG2_FULL_DUPLEX;
-               else
-                       regs->maccfg2 &= ~(MACCFG2_FULL_DUPLEX);
-
-               switch (priv->speed) {
-               case 1000:
-                       regs->maccfg2 = ((regs->maccfg2 & ~(MACCFG2_IF))
-                                        | MACCFG2_GMII);
-                       break;
-               case 100:
-               case 10:
-                       regs->maccfg2 = ((regs->maccfg2 & ~(MACCFG2_IF))
-                                        | MACCFG2_MII);
-
-                       /* Set R100 bit in all modes although
-                        * it is only used in RGMII mode
-                        */
-                       if (priv->speed == 100)
-                               regs->ecntrl |= ECNTRL_R100;
-                       else
-                               regs->ecntrl &= ~(ECNTRL_R100);
-                       break;
-               default:
-                       printf("%s: Speed was bad\n", dev->name);
-                       break;
-               }
-
-               printf("Speed: %d, %s duplex\n", priv->speed,
-                      (priv->duplexity) ? "full" : "half");
-
-       } else {
-               printf("%s: No link.\n", dev->name);
-       }
-}
-
-/* Set up the buffers and their descriptors, and bring up the
- * interface
- */
-static void startup_tsec(struct eth_device *dev)
-{
-       int i;
-       struct tsec_private *priv = (struct tsec_private *)dev->priv;
-       volatile tsec_t *regs = priv->regs;
-
-       /* Point to the buffer descriptors */
-       regs->tbase = (unsigned int)(&rtx.txbd[txIdx]);
-       regs->rbase = (unsigned int)(&rtx.rxbd[rxIdx]);
-
-       /* Initialize the Rx Buffer descriptors */
-       for (i = 0; i < PKTBUFSRX; i++) {
-               rtx.rxbd[i].status = RXBD_EMPTY;
-               rtx.rxbd[i].length = 0;
-               rtx.rxbd[i].bufPtr = (uint) NetRxPackets[i];
-       }
-       rtx.rxbd[PKTBUFSRX - 1].status |= RXBD_WRAP;
-
-       /* Initialize the TX Buffer Descriptors */
-       for (i = 0; i < TX_BUF_CNT; i++) {
-               rtx.txbd[i].status = 0;
-               rtx.txbd[i].length = 0;
-               rtx.txbd[i].bufPtr = 0;
-       }
-       rtx.txbd[TX_BUF_CNT - 1].status |= TXBD_WRAP;
-
-       /* Start up the PHY */
-       if(priv->phyinfo)
-               phy_run_commands(priv, priv->phyinfo->startup);
-
-       adjust_link(dev);
-
-       /* Enable Transmit and Receive */
-       regs->maccfg1 |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
-
-       /* Tell the DMA it is clear to go */
-       regs->dmactrl |= DMACTRL_INIT_SETTINGS;
-       regs->tstat = TSTAT_CLEAR_THALT;
-       regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
-}
-
-/* This returns the status bits of the device. The return value
- * is never checked, and this is what the 8260 driver did, so we
- * do the same.         Presumably, this would be zero if there were no
- * errors
- */
-static int tsec_send(struct eth_device *dev, volatile void *packet, int length)
-{
-       int i;
-       int result = 0;
-       struct tsec_private *priv = (struct tsec_private *)dev->priv;
-       volatile tsec_t *regs = priv->regs;
-
-       /* Find an empty buffer descriptor */
-       for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
-               if (i >= TOUT_LOOP) {
-                       debug("%s: tsec: tx buffers full\n", dev->name);
-                       return result;
-               }
-       }
-
-       rtx.txbd[txIdx].bufPtr = (uint) packet;
-       rtx.txbd[txIdx].length = length;
-       rtx.txbd[txIdx].status |=
-           (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT);
-
-       /* Tell the DMA to go */
-       regs->tstat = TSTAT_CLEAR_THALT;
-
-       /* Wait for buffer to be transmitted */
-       for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
-               if (i >= TOUT_LOOP) {
-                       debug("%s: tsec: tx error\n", dev->name);
-                       return result;
-               }
-       }
-
-       txIdx = (txIdx + 1) % TX_BUF_CNT;
-       result = rtx.txbd[txIdx].status & TXBD_STATS;
-
-       return result;
-}
-
-static int tsec_recv(struct eth_device *dev)
-{
-       int length;
-       struct tsec_private *priv = (struct tsec_private *)dev->priv;
-       volatile tsec_t *regs = priv->regs;
-
-       while (!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) {
-
-               length = rtx.rxbd[rxIdx].length;
-
-               /* Send the packet up if there were no errors */
-               if (!(rtx.rxbd[rxIdx].status & RXBD_STATS)) {
-                       NetReceive(NetRxPackets[rxIdx], length - 4);
-               } else {
-                       printf("Got error %x\n",
-                              (rtx.rxbd[rxIdx].status & RXBD_STATS));
-               }
-
-               rtx.rxbd[rxIdx].length = 0;
-
-               /* Set the wrap bit if this is the last element in the list */
-               rtx.rxbd[rxIdx].status =
-                   RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0);
-
-               rxIdx = (rxIdx + 1) % PKTBUFSRX;
-       }
-
-       if (regs->ievent & IEVENT_BSY) {
-               regs->ievent = IEVENT_BSY;
-               regs->rstat = RSTAT_CLEAR_RHALT;
-       }
-
-       return -1;
-
-}
-
-/* Stop the interface */
-static void tsec_halt(struct eth_device *dev)
-{
-       struct tsec_private *priv = (struct tsec_private *)dev->priv;
-       volatile tsec_t *regs = priv->regs;
-
-       regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
-       regs->dmactrl |= (DMACTRL_GRS | DMACTRL_GTS);
-
-       while (!(regs->ievent & (IEVENT_GRSC | IEVENT_GTSC))) ;
-
-       regs->maccfg1 &= ~(MACCFG1_TX_EN | MACCFG1_RX_EN);
-
-       /* Shut down the PHY, as needed */
-       if(priv->phyinfo)
-               phy_run_commands(priv, priv->phyinfo->shutdown);
-}
-
-struct phy_info phy_info_M88E1149S = {
-       0x1410ca,
-       "Marvell 88E1149S",
-       4,
-       (struct phy_cmd[]){     /* config */
-               /* Reset and configure the PHY */
-               {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-               {0x1d, 0x1f, NULL},
-               {0x1e, 0x200c, NULL},
-               {0x1d, 0x5, NULL},
-               {0x1e, 0x0, NULL},
-               {0x1e, 0x100, NULL},
-               {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
-               {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
-               {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-               {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
-               {miim_end,}
-       },
-       (struct phy_cmd[]){     /* startup */
-               /* Status is read once to clear old link state */
-               {MIIM_STATUS, miim_read, NULL},
-               /* Auto-negotiate */
-               {MIIM_STATUS, miim_read, &mii_parse_sr},
-               /* Read the status */
-               {MIIM_88E1011_PHY_STATUS, miim_read,
-                &mii_parse_88E1011_psr},
-               {miim_end,}
-       },
-       (struct phy_cmd[]){     /* shutdown */
-               {miim_end,}
-       },
-};
-
-/* The 5411 id is 0x206070, the 5421 is 0x2060e0 */
-struct phy_info phy_info_BCM5461S = {
-       0x02060c1,      /* 5461 ID */
-       "Broadcom BCM5461S",
-       0, /* not clear to me what minor revisions we can shift away */
-       (struct phy_cmd[]) { /* config */
-               /* Reset and configure the PHY */
-               {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-               {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
-               {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
-               {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-               {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
-               {miim_end,}
-       },
-       (struct phy_cmd[]) { /* startup */
-               /* Status is read once to clear old link state */
-               {MIIM_STATUS, miim_read, NULL},
-               /* Auto-negotiate */
-               {MIIM_STATUS, miim_read, &mii_parse_sr},
-               /* Read the status */
-               {MIIM_BCM54xx_AUXSTATUS, miim_read, &mii_parse_BCM54xx_sr},
-               {miim_end,}
-       },
-       (struct phy_cmd[]) { /* shutdown */
-               {miim_end,}
-       },
-};
-
-struct phy_info phy_info_BCM5464S = {
-       0x02060b1,      /* 5464 ID */
-       "Broadcom BCM5464S",
-       0, /* not clear to me what minor revisions we can shift away */
-       (struct phy_cmd[]) { /* config */
-               /* Reset and configure the PHY */
-               {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-               {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
-               {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
-               {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-               {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
-               {miim_end,}
-       },
-       (struct phy_cmd[]) { /* startup */
-               /* Status is read once to clear old link state */
-               {MIIM_STATUS, miim_read, NULL},
-               /* Auto-negotiate */
-               {MIIM_STATUS, miim_read, &mii_parse_sr},
-               /* Read the status */
-               {MIIM_BCM54xx_AUXSTATUS, miim_read, &mii_parse_BCM54xx_sr},
-               {miim_end,}
-       },
-       (struct phy_cmd[]) { /* shutdown */
-               {miim_end,}
-       },
-};
-
-struct phy_info phy_info_M88E1011S = {
-       0x01410c6,
-       "Marvell 88E1011S",
-       4,
-       (struct phy_cmd[]){     /* config */
-                          /* Reset and configure the PHY */
-                          {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-                          {0x1d, 0x1f, NULL},
-                          {0x1e, 0x200c, NULL},
-                          {0x1d, 0x5, NULL},
-                          {0x1e, 0x0, NULL},
-                          {0x1e, 0x100, NULL},
-                          {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
-                          {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
-                          {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-                          {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* startup */
-                          /* Status is read once to clear old link state */
-                          {MIIM_STATUS, miim_read, NULL},
-                          /* Auto-negotiate */
-                          {MIIM_STATUS, miim_read, &mii_parse_sr},
-                          /* Read the status */
-                          {MIIM_88E1011_PHY_STATUS, miim_read,
-                           &mii_parse_88E1011_psr},
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* shutdown */
-                          {miim_end,}
-                          },
-};
-
-struct phy_info phy_info_M88E1111S = {
-       0x01410cc,
-       "Marvell 88E1111S",
-       4,
-       (struct phy_cmd[]){     /* config */
-                          /* Reset and configure the PHY */
-                          {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-                          {0x14, 0x0cd2, NULL}, /* Delay RGMII TX and RX */
-                          {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
-                          {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
-                          {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-                          {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* startup */
-                          /* Status is read once to clear old link state */
-                          {MIIM_STATUS, miim_read, NULL},
-                          /* Auto-negotiate */
-                          {MIIM_STATUS, miim_read, &mii_parse_sr},
-                          /* Read the status */
-                          {MIIM_88E1011_PHY_STATUS, miim_read,
-                           &mii_parse_88E1011_psr},
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* shutdown */
-                          {miim_end,}
-                          },
-};
-
-static unsigned int m88e1145_setmode(uint mii_reg, struct tsec_private *priv)
-{
-       uint mii_data = read_phy_reg(priv, mii_reg);
-
-       /* Setting MIIM_88E1145_PHY_EXT_CR */
-       if (priv->flags & TSEC_REDUCED)
-               return mii_data |
-                   MIIM_M88E1145_RGMII_RX_DELAY | MIIM_M88E1145_RGMII_TX_DELAY;
-       else
-               return mii_data;
-}
-
-static struct phy_info phy_info_M88E1145 = {
-       0x01410cd,
-       "Marvell 88E1145",
-       4,
-       (struct phy_cmd[]){     /* config */
-                          /* Reset the PHY */
-                          {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-
-                          /* Errata E0, E1 */
-                          {29, 0x001b, NULL},
-                          {30, 0x418f, NULL},
-                          {29, 0x0016, NULL},
-                          {30, 0xa2da, NULL},
-
-                          /* Configure the PHY */
-                          {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
-                          {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
-                          {MIIM_88E1011_PHY_SCR, MIIM_88E1011_PHY_MDI_X_AUTO,
-                           NULL},
-                          {MIIM_88E1145_PHY_EXT_CR, 0, &m88e1145_setmode},
-                          {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-                          {MIIM_CONTROL, MIIM_CONTROL_INIT, NULL},
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* startup */
-                          /* Status is read once to clear old link state */
-                          {MIIM_STATUS, miim_read, NULL},
-                          /* Auto-negotiate */
-                          {MIIM_STATUS, miim_read, &mii_parse_sr},
-                          {MIIM_88E1111_PHY_LED_CONTROL,
-                           MIIM_88E1111_PHY_LED_DIRECT, NULL},
-                          /* Read the Status */
-                          {MIIM_88E1011_PHY_STATUS, miim_read,
-                           &mii_parse_88E1011_psr},
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* shutdown */
-                          {miim_end,}
-                          },
-};
-
-struct phy_info phy_info_cis8204 = {
-       0x3f11,
-       "Cicada Cis8204",
-       6,
-       (struct phy_cmd[]){     /* config */
-                          /* Override PHY config settings */
-                          {MIIM_CIS8201_AUX_CONSTAT,
-                           MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
-                          /* Configure some basic stuff */
-                          {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
-                          {MIIM_CIS8204_SLED_CON, MIIM_CIS8204_SLEDCON_INIT,
-                           &mii_cis8204_fixled},
-                          {MIIM_CIS8204_EPHY_CON, MIIM_CIS8204_EPHYCON_INIT,
-                           &mii_cis8204_setmode},
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* startup */
-                          /* Read the Status (2x to make sure link is right) */
-                          {MIIM_STATUS, miim_read, NULL},
-                          /* Auto-negotiate */
-                          {MIIM_STATUS, miim_read, &mii_parse_sr},
-                          /* Read the status */
-                          {MIIM_CIS8201_AUX_CONSTAT, miim_read,
-                           &mii_parse_cis8201},
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* shutdown */
-                          {miim_end,}
-                          },
-};
-
-/* Cicada 8201 */
-struct phy_info phy_info_cis8201 = {
-       0xfc41,
-       "CIS8201",
-       4,
-       (struct phy_cmd[]){     /* config */
-                          /* Override PHY config settings */
-                          {MIIM_CIS8201_AUX_CONSTAT,
-                           MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
-                          /* Set up the interface mode */
-                          {MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT,
-                           NULL},
-                          /* Configure some basic stuff */
-                          {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* startup */
-                          /* Read the Status (2x to make sure link is right) */
-                          {MIIM_STATUS, miim_read, NULL},
-                          /* Auto-negotiate */
-                          {MIIM_STATUS, miim_read, &mii_parse_sr},
-                          /* Read the status */
-                          {MIIM_CIS8201_AUX_CONSTAT, miim_read,
-                           &mii_parse_cis8201},
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* shutdown */
-                          {miim_end,}
-                          },
-};
-struct phy_info phy_info_VSC8244 = {
-       0x3f1b,
-       "Vitesse VSC8244",
-       6,
-       (struct phy_cmd[]){     /* config */
-                          /* Override PHY config settings */
-                          /* Configure some basic stuff */
-                          {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* startup */
-                          /* Read the Status (2x to make sure link is right) */
-                          {MIIM_STATUS, miim_read, NULL},
-                          /* Auto-negotiate */
-                          {MIIM_STATUS, miim_read, &mii_parse_sr},
-                          /* Read the status */
-                          {MIIM_VSC8244_AUX_CONSTAT, miim_read,
-                           &mii_parse_vsc8244},
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* shutdown */
-                          {miim_end,}
-                          },
-};
-
-struct phy_info phy_info_dm9161 = {
-       0x0181b88,
-       "Davicom DM9161E",
-       4,
-       (struct phy_cmd[]){     /* config */
-                          {MIIM_CONTROL, MIIM_DM9161_CR_STOP, NULL},
-                          /* Do not bypass the scrambler/descrambler */
-                          {MIIM_DM9161_SCR, MIIM_DM9161_SCR_INIT, NULL},
-                          /* Clear 10BTCSR to default */
-                          {MIIM_DM9161_10BTCSR, MIIM_DM9161_10BTCSR_INIT,
-                           NULL},
-                          /* Configure some basic stuff */
-                          {MIIM_CONTROL, MIIM_CR_INIT, NULL},
-                          /* Restart Auto Negotiation */
-                          {MIIM_CONTROL, MIIM_DM9161_CR_RSTAN, NULL},
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* startup */
-                          /* Status is read once to clear old link state */
-                          {MIIM_STATUS, miim_read, NULL},
-                          /* Auto-negotiate */
-                          {MIIM_STATUS, miim_read, &mii_parse_sr},
-                          /* Read the status */
-                          {MIIM_DM9161_SCSR, miim_read,
-                           &mii_parse_dm9161_scsr},
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* shutdown */
-                          {miim_end,}
-                          },
-};
-/* a generic flavor.  */
-struct phy_info phy_info_generic =  {
-       0,
-       "Unknown/Generic PHY",
-       32,
-       (struct phy_cmd[]) { /* config */
-               {PHY_BMCR, PHY_BMCR_RESET, NULL},
-               {PHY_BMCR, PHY_BMCR_AUTON|PHY_BMCR_RST_NEG, NULL},
-               {miim_end,}
-       },
-       (struct phy_cmd[]) { /* startup */
-               {PHY_BMSR, miim_read, NULL},
-               {PHY_BMSR, miim_read, &mii_parse_sr},
-               {PHY_BMSR, miim_read, &mii_parse_link},
-               {miim_end,}
-       },
-       (struct phy_cmd[]) { /* shutdown */
-               {miim_end,}
-       }
-};
-
-
-uint mii_parse_lxt971_sr2(uint mii_reg, struct tsec_private *priv)
-{
-       unsigned int speed;
-       if (priv->link) {
-               speed = mii_reg & MIIM_LXT971_SR2_SPEED_MASK;
-
-               switch (speed) {
-               case MIIM_LXT971_SR2_10HDX:
-                       priv->speed = 10;
-                       priv->duplexity = 0;
-                       break;
-               case MIIM_LXT971_SR2_10FDX:
-                       priv->speed = 10;
-                       priv->duplexity = 1;
-                       break;
-               case MIIM_LXT971_SR2_100HDX:
-                       priv->speed = 100;
-                       priv->duplexity = 0;
-                       break;
-               default:
-                       priv->speed = 100;
-                       priv->duplexity = 1;
-               }
-       } else {
-               priv->speed = 0;
-               priv->duplexity = 0;
-       }
-
-       return 0;
-}
-
-static struct phy_info phy_info_lxt971 = {
-       0x0001378e,
-       "LXT971",
-       4,
-       (struct phy_cmd[]){     /* config */
-                          {MIIM_CR, MIIM_CR_INIT, mii_cr_init},        /* autonegotiate */
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* startup - enable interrupts */
-                          /* { 0x12, 0x00f2, NULL }, */
-                          {MIIM_STATUS, miim_read, NULL},
-                          {MIIM_STATUS, miim_read, &mii_parse_sr},
-                          {MIIM_LXT971_SR2, miim_read, &mii_parse_lxt971_sr2},
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* shutdown - disable interrupts */
-                          {miim_end,}
-                          },
-};
-
-/* Parse the DP83865's link and auto-neg status register for speed and duplex
- * information
- */
-uint mii_parse_dp83865_lanr(uint mii_reg, struct tsec_private *priv)
-{
-       switch (mii_reg & MIIM_DP83865_SPD_MASK) {
-
-       case MIIM_DP83865_SPD_1000:
-               priv->speed = 1000;
-               break;
-
-       case MIIM_DP83865_SPD_100:
-               priv->speed = 100;
-               break;
-
-       default:
-               priv->speed = 10;
-               break;
-
-       }
-
-       if (mii_reg & MIIM_DP83865_DPX_FULL)
-               priv->duplexity = 1;
-       else
-               priv->duplexity = 0;
-
-       return 0;
-}
-
-struct phy_info phy_info_dp83865 = {
-       0x20005c7,
-       "NatSemi DP83865",
-       4,
-       (struct phy_cmd[]){     /* config */
-                          {MIIM_CONTROL, MIIM_DP83865_CR_INIT, NULL},
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* startup */
-                          /* Status is read once to clear old link state */
-                          {MIIM_STATUS, miim_read, NULL},
-                          /* Auto-negotiate */
-                          {MIIM_STATUS, miim_read, &mii_parse_sr},
-                          /* Read the link and auto-neg status */
-                          {MIIM_DP83865_LANR, miim_read,
-                           &mii_parse_dp83865_lanr},
-                          {miim_end,}
-                          },
-       (struct phy_cmd[]){     /* shutdown */
-                          {miim_end,}
-                          },
-};
-
-struct phy_info *phy_info[] = {
-       &phy_info_cis8204,
-       &phy_info_cis8201,
-       &phy_info_BCM5461S,
-       &phy_info_BCM5464S,
-       &phy_info_M88E1011S,
-       &phy_info_M88E1111S,
-       &phy_info_M88E1145,
-       &phy_info_M88E1149S,
-       &phy_info_dm9161,
-       &phy_info_lxt971,
-       &phy_info_VSC8244,
-       &phy_info_dp83865,
-       &phy_info_generic,
-       NULL
-};
-
-/* Grab the identifier of the device's PHY, and search through
- * all of the known PHYs to see if one matches.         If so, return
- * it, if not, return NULL
- */
-struct phy_info *get_phy_info(struct eth_device *dev)
-{
-       struct tsec_private *priv = (struct tsec_private *)dev->priv;
-       uint phy_reg, phy_ID;
-       int i;
-       struct phy_info *theInfo = NULL;
-
-       /* Grab the bits from PHYIR1, and put them in the upper half */
-       phy_reg = read_phy_reg(priv, MIIM_PHYIR1);
-       phy_ID = (phy_reg & 0xffff) << 16;
-
-       /* Grab the bits from PHYIR2, and put them in the lower half */
-       phy_reg = read_phy_reg(priv, MIIM_PHYIR2);
-       phy_ID |= (phy_reg & 0xffff);
-
-       /* loop through all the known PHY types, and find one that */
-       /* matches the ID we read from the PHY. */
-       for (i = 0; phy_info[i]; i++) {
-               if (phy_info[i]->id == (phy_ID >> phy_info[i]->shift)) {
-                       theInfo = phy_info[i];
-                       break;
-               }
-       }
-
-       if (theInfo == NULL) {
-               printf("%s: PHY id %x is not supported!\n", dev->name, phy_ID);
-               return NULL;
-       } else {
-               debug("%s: PHY is %s (%x)\n", dev->name, theInfo->name, phy_ID);
-       }
-
-       return theInfo;
-}
-
-/* Execute the given series of commands on the given device's
- * PHY, running functions as necessary
- */
-void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd)
-{
-       int i;
-       uint result;
-       volatile tsec_t *phyregs = priv->phyregs;
-
-       phyregs->miimcfg = MIIMCFG_RESET;
-
-       phyregs->miimcfg = MIIMCFG_INIT_VALUE;
-
-       while (phyregs->miimind & MIIMIND_BUSY) ;
-
-       for (i = 0; cmd->mii_reg != miim_end; i++) {
-               if (cmd->mii_data == miim_read) {
-                       result = read_phy_reg(priv, cmd->mii_reg);
-
-                       if (cmd->funct != NULL)
-                               (*(cmd->funct)) (result, priv);
-
-               } else {
-                       if (cmd->funct != NULL)
-                               result = (*(cmd->funct)) (cmd->mii_reg, priv);
-                       else
-                               result = cmd->mii_data;
-
-                       write_phy_reg(priv, cmd->mii_reg, result);
-
-               }
-               cmd++;
-       }
-}
-
-/* Relocate the function pointers in the phy cmd lists */
-static void relocate_cmds(void)
-{
-       struct phy_cmd **cmdlistptr;
-       struct phy_cmd *cmd;
-       int i, j, k;
-
-       for (i = 0; phy_info[i]; i++) {
-               /* First thing's first: relocate the pointers to the
-                * PHY command structures (the structs were done) */
-               phy_info[i] = (struct phy_info *)((uint) phy_info[i]
-                                                 + gd->reloc_off);
-               phy_info[i]->name += gd->reloc_off;
-               phy_info[i]->config =
-                   (struct phy_cmd *)((uint) phy_info[i]->config
-                                      + gd->reloc_off);
-               phy_info[i]->startup =
-                   (struct phy_cmd *)((uint) phy_info[i]->startup
-                                      + gd->reloc_off);
-               phy_info[i]->shutdown =
-                   (struct phy_cmd *)((uint) phy_info[i]->shutdown
-                                      + gd->reloc_off);
-
-               cmdlistptr = &phy_info[i]->config;
-               j = 0;
-               for (; cmdlistptr <= &phy_info[i]->shutdown; cmdlistptr++) {
-                       k = 0;
-                       for (cmd = *cmdlistptr;
-                            cmd->mii_reg != miim_end;
-                            cmd++) {
-                               /* Only relocate non-NULL pointers */
-                               if (cmd->funct)
-                                       cmd->funct += gd->reloc_off;
-
-                               k++;
-                       }
-                       j++;
-               }
-       }
-
-       relocated = 1;
-}
-
-#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
-       && !defined(BITBANGMII)
-
-struct tsec_private *get_priv_for_phy(unsigned char phyaddr)
-{
-       int i;
-
-       for (i = 0; i < MAXCONTROLLERS; i++) {
-               if (privlist[i]->phyaddr == phyaddr)
-                       return privlist[i];
-       }
-
-       return NULL;
-}
-
-/*
- * Read a MII PHY register.
- *
- * Returns:
- *  0 on success
- */
-static int tsec_miiphy_read(char *devname, unsigned char addr,
-                           unsigned char reg, unsigned short *value)
-{
-       unsigned short ret;
-       struct tsec_private *priv = get_priv_for_phy(addr);
-
-       if (NULL == priv) {
-               printf("Can't read PHY at address %d\n", addr);
-               return -1;
-       }
-
-       ret = (unsigned short)read_phy_reg(priv, reg);
-       *value = ret;
-
-       return 0;
-}
-
-/*
- * Write a MII PHY register.
- *
- * Returns:
- *  0 on success
- */
-static int tsec_miiphy_write(char *devname, unsigned char addr,
-                            unsigned char reg, unsigned short value)
-{
-       struct tsec_private *priv = get_priv_for_phy(addr);
-
-       if (NULL == priv) {
-               printf("Can't write PHY at address %d\n", addr);
-               return -1;
-       }
-
-       write_phy_reg(priv, reg, value);
-
-       return 0;
-}
-
-#endif
-
-#ifdef CONFIG_MCAST_TFTP
-
-/* CREDITS: linux gianfar driver, slightly adjusted... thanx. */
-
-/* Set the appropriate hash bit for the given addr */
-
-/* The algorithm works like so:
- * 1) Take the Destination Address (ie the multicast address), and
- * do a CRC on it (little endian), and reverse the bits of the
- * result.
- * 2) Use the 8 most significant bits as a hash into a 256-entry
- * table.  The table is controlled through 8 32-bit registers:
- * gaddr0-7.  gaddr0's MSB is entry 0, and gaddr7's LSB is
- * gaddr7.  This means that the 3 most significant bits in the
- * hash index which gaddr register to use, and the 5 other bits
- * indicate which bit (assuming an IBM numbering scheme, which
- * for PowerPC (tm) is usually the case) in the tregister holds
- * the entry. */
-static int
-tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set)
-{
- struct tsec_private *priv = privlist[1];
- volatile tsec_t *regs = priv->regs;
- volatile u32  *reg_array, value;
- u8 result, whichbit, whichreg;
-
-       result = (u8)((ether_crc(MAC_ADDR_LEN,mcast_mac) >> 24) & 0xff);
-       whichbit = result & 0x1f;       /* the 5 LSB = which bit to set */
-       whichreg = result >> 5;         /* the 3 MSB = which reg to set it in */
-       value = (1 << (31-whichbit));
-
-       reg_array = &(regs->hash.gaddr0);
-
-       if (set) {
-               reg_array[whichreg] |= value;
-       } else {
-               reg_array[whichreg] &= ~value;
-       }
-       return 0;
-}
-#endif /* Multicast TFTP ? */
-
-#endif /* CONFIG_TSEC_ENET */
diff --git a/drivers/tsec.h b/drivers/tsec.h
deleted file mode 100644 (file)
index 2f0092a..0000000
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- *  tsec.h
- *
- *  Driver for the Motorola Triple Speed Ethernet Controller
- *
- *  This software may be used and distributed according to the
- *  terms of the GNU Public License, Version 2, incorporated
- *  herein by reference.
- *
- * Copyright 2004, 2007 Freescale Semiconductor, Inc.
- * (C) Copyright 2003, Motorola, Inc.
- * maintained by Xianghua Xiao (x.xiao@motorola.com)
- * author Andy Fleming
- *
- */
-
-#ifndef __TSEC_H
-#define __TSEC_H
-
-#include <net.h>
-#include <config.h>
-
-#ifndef CFG_TSEC1_OFFSET
-    #define CFG_TSEC1_OFFSET   (0x24000)
-#endif
-
-#define TSEC_SIZE      0x01000
-
-/* FIXME:  Should these be pushed back to 83xx and 85xx config files? */
-#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
-    #define TSEC_BASE_ADDR     (CFG_IMMR + CFG_TSEC1_OFFSET)
-#elif defined(CONFIG_MPC83XX)
-    #define TSEC_BASE_ADDR     (CFG_IMMR + CFG_TSEC1_OFFSET)
-#endif
-
-
-#define MAC_ADDR_LEN 6
-
-/* #define TSEC_TIMEOUT        1000000 */
-#define TSEC_TIMEOUT 1000
-#define TOUT_LOOP      1000000
-
-#define PHY_AUTONEGOTIATE_TIMEOUT      5000 /* in ms */
-
-/* MAC register bits */
-#define MACCFG1_SOFT_RESET     0x80000000
-#define MACCFG1_RESET_RX_MC    0x00080000
-#define MACCFG1_RESET_TX_MC    0x00040000
-#define MACCFG1_RESET_RX_FUN   0x00020000
-#define        MACCFG1_RESET_TX_FUN    0x00010000
-#define MACCFG1_LOOPBACK       0x00000100
-#define MACCFG1_RX_FLOW                0x00000020
-#define MACCFG1_TX_FLOW                0x00000010
-#define MACCFG1_SYNCD_RX_EN    0x00000008
-#define MACCFG1_RX_EN          0x00000004
-#define MACCFG1_SYNCD_TX_EN    0x00000002
-#define MACCFG1_TX_EN          0x00000001
-
-#define MACCFG2_INIT_SETTINGS  0x00007205
-#define MACCFG2_FULL_DUPLEX    0x00000001
-#define MACCFG2_IF              0x00000300
-#define MACCFG2_GMII           0x00000200
-#define MACCFG2_MII             0x00000100
-
-#define ECNTRL_INIT_SETTINGS   0x00001000
-#define ECNTRL_TBI_MODE         0x00000020
-#define ECNTRL_R100            0x00000008
-#define ECNTRL_SGMII_MODE      0x00000002
-
-#define miim_end -2
-#define miim_read -1
-
-#ifndef CFG_TBIPA_VALUE
-    #define CFG_TBIPA_VALUE    0x1f
-#endif
-#define MIIMCFG_INIT_VALUE     0x00000003
-#define MIIMCFG_RESET          0x80000000
-
-#define MIIMIND_BUSY            0x00000001
-#define MIIMIND_NOTVALID        0x00000004
-
-#define MIIM_CONTROL            0x00
-#define MIIM_CONTROL_RESET     0x00009140
-#define MIIM_CONTROL_INIT       0x00001140
-#define MIIM_CONTROL_RESTART    0x00001340
-#define MIIM_ANEN               0x00001000
-
-#define MIIM_CR                 0x00
-#define MIIM_CR_RST            0x00008000
-#define MIIM_CR_INIT           0x00001000
-
-#define MIIM_STATUS            0x1
-#define MIIM_STATUS_AN_DONE    0x00000020
-#define MIIM_STATUS_LINK       0x0004
-#define PHY_BMSR_AUTN_ABLE     0x0008
-#define PHY_BMSR_AUTN_COMP     0x0020
-
-#define MIIM_PHYIR1            0x2
-#define MIIM_PHYIR2            0x3
-
-#define MIIM_ANAR              0x4
-#define MIIM_ANAR_INIT         0x1e1
-
-#define MIIM_TBI_ANLPBPA       0x5
-#define MIIM_TBI_ANLPBPA_HALF  0x00000040
-#define MIIM_TBI_ANLPBPA_FULL  0x00000020
-
-#define MIIM_TBI_ANEX          0x6
-#define MIIM_TBI_ANEX_NP       0x00000004
-#define MIIM_TBI_ANEX_PRX      0x00000002
-
-#define MIIM_GBIT_CONTROL      0x9
-#define MIIM_GBIT_CONTROL_INIT 0xe00
-
-/* Broadcom BCM54xx -- taken from linux sungem_phy */
-#define MIIM_BCM54xx_AUXSTATUS                 0x19
-#define MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK   0x0700
-#define MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT  8
-
-/* Cicada Auxiliary Control/Status Register */
-#define MIIM_CIS8201_AUX_CONSTAT        0x1c
-#define MIIM_CIS8201_AUXCONSTAT_INIT    0x0004
-#define MIIM_CIS8201_AUXCONSTAT_DUPLEX  0x0020
-#define MIIM_CIS8201_AUXCONSTAT_SPEED   0x0018
-#define MIIM_CIS8201_AUXCONSTAT_GBIT    0x0010
-#define MIIM_CIS8201_AUXCONSTAT_100     0x0008
-
-/* Cicada Extended Control Register 1 */
-#define MIIM_CIS8201_EXT_CON1           0x17
-#define MIIM_CIS8201_EXTCON1_INIT       0x0000
-
-/* Cicada 8204 Extended PHY Control Register 1 */
-#define MIIM_CIS8204_EPHY_CON          0x17
-#define MIIM_CIS8204_EPHYCON_INIT      0x0006
-#define MIIM_CIS8204_EPHYCON_RGMII     0x1100
-
-/* Cicada 8204 Serial LED Control Register */
-#define MIIM_CIS8204_SLED_CON          0x1b
-#define MIIM_CIS8204_SLEDCON_INIT      0x1115
-
-#define MIIM_GBIT_CON          0x09
-#define MIIM_GBIT_CON_ADVERT   0x0e00
-
-/* Entry for Vitesse VSC8244 regs starts here */
-/* Vitesse VSC8244 Auxiliary Control/Status Register */
-#define MIIM_VSC8244_AUX_CONSTAT        0x1c
-#define MIIM_VSC8244_AUXCONSTAT_INIT    0x0000
-#define MIIM_VSC8244_AUXCONSTAT_DUPLEX  0x0020
-#define MIIM_VSC8244_AUXCONSTAT_SPEED   0x0018
-#define MIIM_VSC8244_AUXCONSTAT_GBIT    0x0010
-#define MIIM_VSC8244_AUXCONSTAT_100     0x0008
-#define MIIM_CONTROL_INIT_LOOPBACK      0x4000
-
-/* Vitesse VSC8244 Extended PHY Control Register 1 */
-#define MIIM_VSC8244_EPHY_CON           0x17
-#define MIIM_VSC8244_EPHYCON_INIT       0x0006
-
-/* Vitesse VSC8244 Serial LED Control Register */
-#define MIIM_VSC8244_LED_CON            0x1b
-#define MIIM_VSC8244_LEDCON_INIT        0xF011
-
-/* 88E1011 PHY Status Register */
-#define MIIM_88E1011_PHY_STATUS         0x11
-#define MIIM_88E1011_PHYSTAT_SPEED      0xc000
-#define MIIM_88E1011_PHYSTAT_GBIT       0x8000
-#define MIIM_88E1011_PHYSTAT_100        0x4000
-#define MIIM_88E1011_PHYSTAT_DUPLEX     0x2000
-#define MIIM_88E1011_PHYSTAT_SPDDONE   0x0800
-#define MIIM_88E1011_PHYSTAT_LINK      0x0400
-
-#define MIIM_88E1011_PHY_SCR           0x10
-#define MIIM_88E1011_PHY_MDI_X_AUTO    0x0060
-
-/* 88E1111 PHY LED Control Register */
-#define MIIM_88E1111_PHY_LED_CONTROL   24
-#define MIIM_88E1111_PHY_LED_DIRECT    0x4100
-#define MIIM_88E1111_PHY_LED_COMBINE   0x411C
-
-/* 88E1145 Extended PHY Specific Control Register */
-#define MIIM_88E1145_PHY_EXT_CR 20
-#define MIIM_M88E1145_RGMII_RX_DELAY   0x0080
-#define MIIM_M88E1145_RGMII_TX_DELAY   0x0002
-
-#define MIIM_88E1145_PHY_PAGE   29
-#define MIIM_88E1145_PHY_CAL_OV 30
-
-
-/* DM9161 Control register values */
-#define MIIM_DM9161_CR_STOP    0x0400
-#define MIIM_DM9161_CR_RSTAN   0x1200
-
-#define MIIM_DM9161_SCR                0x10
-#define MIIM_DM9161_SCR_INIT   0x0610
-
-/* DM9161 Specified Configuration and Status Register */
-#define MIIM_DM9161_SCSR       0x11
-#define MIIM_DM9161_SCSR_100F  0x8000
-#define MIIM_DM9161_SCSR_100H  0x4000
-#define MIIM_DM9161_SCSR_10F   0x2000
-#define MIIM_DM9161_SCSR_10H   0x1000
-
-/* DM9161 10BT Configuration/Status */
-#define MIIM_DM9161_10BTCSR    0x12
-#define MIIM_DM9161_10BTCSR_INIT       0x7800
-
-/* LXT971 Status 2 registers */
-#define MIIM_LXT971_SR2              0x11  /* Status Register 2  */
-#define MIIM_LXT971_SR2_SPEED_MASK 0x4200
-#define MIIM_LXT971_SR2_10HDX      0x0000  /*  10 Mbit half duplex selected */
-#define MIIM_LXT971_SR2_10FDX      0x0200  /*  10 Mbit full duplex selected */
-#define MIIM_LXT971_SR2_100HDX     0x4000  /* 100 Mbit half duplex selected */
-#define MIIM_LXT971_SR2_100FDX     0x4200  /* 100 Mbit full duplex selected */
-
-/* DP83865 Control register values */
-#define MIIM_DP83865_CR_INIT   0x9200
-
-/* DP83865 Link and Auto-Neg Status Register */
-#define MIIM_DP83865_LANR      0x11
-#define MIIM_DP83865_SPD_MASK  0x0018
-#define MIIM_DP83865_SPD_1000  0x0010
-#define MIIM_DP83865_SPD_100   0x0008
-#define MIIM_DP83865_DPX_FULL  0x0002
-
-#define MIIM_READ_COMMAND       0x00000001
-
-#define MRBLR_INIT_SETTINGS    PKTSIZE_ALIGN
-
-#define MINFLR_INIT_SETTINGS   0x00000040
-
-#define DMACTRL_INIT_SETTINGS   0x000000c3
-#define DMACTRL_GRS             0x00000010
-#define DMACTRL_GTS             0x00000008
-
-#define TSTAT_CLEAR_THALT       0x80000000
-#define RSTAT_CLEAR_RHALT       0x00800000
-
-
-#define IEVENT_INIT_CLEAR      0xffffffff
-#define IEVENT_BABR            0x80000000
-#define IEVENT_RXC             0x40000000
-#define IEVENT_BSY             0x20000000
-#define IEVENT_EBERR           0x10000000
-#define IEVENT_MSRO            0x04000000
-#define IEVENT_GTSC            0x02000000
-#define IEVENT_BABT            0x01000000
-#define IEVENT_TXC             0x00800000
-#define IEVENT_TXE             0x00400000
-#define IEVENT_TXB             0x00200000
-#define IEVENT_TXF             0x00100000
-#define IEVENT_IE              0x00080000
-#define IEVENT_LC              0x00040000
-#define IEVENT_CRL             0x00020000
-#define IEVENT_XFUN            0x00010000
-#define IEVENT_RXB0            0x00008000
-#define IEVENT_GRSC            0x00000100
-#define IEVENT_RXF0            0x00000080
-
-#define IMASK_INIT_CLEAR       0x00000000
-#define IMASK_TXEEN            0x00400000
-#define IMASK_TXBEN            0x00200000
-#define IMASK_TXFEN             0x00100000
-#define IMASK_RXFEN0           0x00000080
-
-
-/* Default Attribute fields */
-#define ATTR_INIT_SETTINGS     0x000000c0
-#define ATTRELI_INIT_SETTINGS  0x00000000
-
-
-/* TxBD status field bits */
-#define TXBD_READY             0x8000
-#define TXBD_PADCRC            0x4000
-#define TXBD_WRAP              0x2000
-#define TXBD_INTERRUPT         0x1000
-#define TXBD_LAST              0x0800
-#define TXBD_CRC               0x0400
-#define TXBD_DEF               0x0200
-#define TXBD_HUGEFRAME         0x0080
-#define TXBD_LATECOLLISION     0x0080
-#define TXBD_RETRYLIMIT                0x0040
-#define        TXBD_RETRYCOUNTMASK     0x003c
-#define TXBD_UNDERRUN          0x0002
-#define TXBD_STATS              0x03ff
-
-/* RxBD status field bits */
-#define RXBD_EMPTY             0x8000
-#define RXBD_RO1               0x4000
-#define RXBD_WRAP              0x2000
-#define RXBD_INTERRUPT         0x1000
-#define RXBD_LAST              0x0800
-#define RXBD_FIRST             0x0400
-#define RXBD_MISS              0x0100
-#define RXBD_BROADCAST         0x0080
-#define RXBD_MULTICAST         0x0040
-#define RXBD_LARGE             0x0020
-#define RXBD_NONOCTET          0x0010
-#define RXBD_SHORT             0x0008
-#define RXBD_CRCERR            0x0004
-#define RXBD_OVERRUN           0x0002
-#define RXBD_TRUNCATED         0x0001
-#define RXBD_STATS             0x003f
-
-typedef struct txbd8
-{
-       ushort       status;         /* Status Fields */
-       ushort       length;         /* Buffer length */
-       uint         bufPtr;         /* Buffer Pointer */
-} txbd8_t;
-
-typedef struct rxbd8
-{
-       ushort       status;         /* Status Fields */
-       ushort       length;         /* Buffer Length */
-       uint         bufPtr;         /* Buffer Pointer */
-} rxbd8_t;
-
-typedef struct rmon_mib
-{
-       /* Transmit and Receive Counters */
-       uint    tr64;           /* Transmit and Receive 64-byte Frame Counter */
-       uint    tr127;          /* Transmit and Receive 65-127 byte Frame Counter */
-       uint    tr255;          /* Transmit and Receive 128-255 byte Frame Counter */
-       uint    tr511;          /* Transmit and Receive 256-511 byte Frame Counter */
-       uint    tr1k;           /* Transmit and Receive 512-1023 byte Frame Counter */
-       uint    trmax;          /* Transmit and Receive 1024-1518 byte Frame Counter */
-       uint    trmgv;          /* Transmit and Receive 1519-1522 byte Good VLAN Frame */
-       /* Receive Counters */
-       uint    rbyt;           /* Receive Byte Counter */
-       uint    rpkt;           /* Receive Packet Counter */
-       uint    rfcs;           /* Receive FCS Error Counter */
-       uint    rmca;           /* Receive Multicast Packet (Counter) */
-       uint    rbca;           /* Receive Broadcast Packet */
-       uint    rxcf;           /* Receive Control Frame Packet */
-       uint    rxpf;           /* Receive Pause Frame Packet */
-       uint    rxuo;           /* Receive Unknown OP Code */
-       uint    raln;           /* Receive Alignment Error */
-       uint    rflr;           /* Receive Frame Length Error */
-       uint    rcde;           /* Receive Code Error */
-       uint    rcse;           /* Receive Carrier Sense Error */
-       uint    rund;           /* Receive Undersize Packet */
-       uint    rovr;           /* Receive Oversize Packet */
-       uint    rfrg;           /* Receive Fragments */
-       uint    rjbr;           /* Receive Jabber */
-       uint    rdrp;           /* Receive Drop */
-       /* Transmit Counters */
-       uint    tbyt;           /* Transmit Byte Counter */
-       uint    tpkt;           /* Transmit Packet */
-       uint    tmca;           /* Transmit Multicast Packet */
-       uint    tbca;           /* Transmit Broadcast Packet */
-       uint    txpf;           /* Transmit Pause Control Frame */
-       uint    tdfr;           /* Transmit Deferral Packet */
-       uint    tedf;           /* Transmit Excessive Deferral Packet */
-       uint    tscl;           /* Transmit Single Collision Packet */
-       /* (0x2_n700) */
-       uint    tmcl;           /* Transmit Multiple Collision Packet */
-       uint    tlcl;           /* Transmit Late Collision Packet */
-       uint    txcl;           /* Transmit Excessive Collision Packet */
-       uint    tncl;           /* Transmit Total Collision */
-
-       uint    res2;
-
-       uint    tdrp;           /* Transmit Drop Frame */
-       uint    tjbr;           /* Transmit Jabber Frame */
-       uint    tfcs;           /* Transmit FCS Error */
-       uint    txcf;           /* Transmit Control Frame */
-       uint    tovr;           /* Transmit Oversize Frame */
-       uint    tund;           /* Transmit Undersize Frame */
-       uint    tfrg;           /* Transmit Fragments Frame */
-       /* General Registers */
-       uint    car1;           /* Carry Register One */
-       uint    car2;           /* Carry Register Two */
-       uint    cam1;           /* Carry Register One Mask */
-       uint    cam2;           /* Carry Register Two Mask */
-} rmon_mib_t;
-
-typedef struct tsec_hash_regs
-{
-       uint    iaddr0;         /* Individual Address Register 0 */
-       uint    iaddr1;         /* Individual Address Register 1 */
-       uint    iaddr2;         /* Individual Address Register 2 */
-       uint    iaddr3;         /* Individual Address Register 3 */
-       uint    iaddr4;         /* Individual Address Register 4 */
-       uint    iaddr5;         /* Individual Address Register 5 */
-       uint    iaddr6;         /* Individual Address Register 6 */
-       uint    iaddr7;         /* Individual Address Register 7 */
-       uint    res1[24];
-       uint    gaddr0;         /* Group Address Register 0 */
-       uint    gaddr1;         /* Group Address Register 1 */
-       uint    gaddr2;         /* Group Address Register 2 */
-       uint    gaddr3;         /* Group Address Register 3 */
-       uint    gaddr4;         /* Group Address Register 4 */
-       uint    gaddr5;         /* Group Address Register 5 */
-       uint    gaddr6;         /* Group Address Register 6 */
-       uint    gaddr7;         /* Group Address Register 7 */
-       uint    res2[24];
-} tsec_hash_t;
-
-typedef struct tsec
-{
-       /* General Control and Status Registers (0x2_n000) */
-       uint    res000[4];
-
-       uint    ievent;         /* Interrupt Event */
-       uint    imask;          /* Interrupt Mask */
-       uint    edis;           /* Error Disabled */
-       uint    res01c;
-       uint    ecntrl;         /* Ethernet Control */
-       uint    minflr;         /* Minimum Frame Length */
-       uint    ptv;            /* Pause Time Value */
-       uint    dmactrl;        /* DMA Control */
-       uint    tbipa;          /* TBI PHY Address */
-
-       uint    res034[3];
-       uint    res040[48];
-
-       /* Transmit Control and Status Registers (0x2_n100) */
-       uint    tctrl;          /* Transmit Control */
-       uint    tstat;          /* Transmit Status */
-       uint    res108;
-       uint    tbdlen;         /* Tx BD Data Length */
-       uint    res110[5];
-       uint    ctbptr;         /* Current TxBD Pointer */
-       uint    res128[23];
-       uint    tbptr;          /* TxBD Pointer */
-       uint    res188[30];
-       /* (0x2_n200) */
-       uint        res200;
-       uint    tbase;          /* TxBD Base Address */
-       uint    res208[42];
-       uint    ostbd;          /* Out of Sequence TxBD */
-       uint    ostbdp;         /* Out of Sequence Tx Data Buffer Pointer */
-       uint        res2b8[18];
-
-       /* Receive Control and Status Registers (0x2_n300) */
-       uint    rctrl;          /* Receive Control */
-       uint    rstat;          /* Receive Status */
-       uint    res308;
-       uint    rbdlen;         /* RxBD Data Length */
-       uint    res310[4];
-       uint        res320;
-       uint    crbptr;         /* Current Receive Buffer Pointer */
-       uint    res328[6];
-       uint    mrblr;          /* Maximum Receive Buffer Length */
-       uint    res344[16];
-       uint    rbptr;          /* RxBD Pointer */
-       uint        res388[30];
-       /* (0x2_n400) */
-       uint        res400;
-       uint    rbase;          /* RxBD Base Address */
-       uint        res408[62];
-
-       /* MAC Registers (0x2_n500) */
-       uint    maccfg1;        /* MAC Configuration #1 */
-       uint    maccfg2;        /* MAC Configuration #2 */
-       uint    ipgifg;         /* Inter Packet Gap/Inter Frame Gap */
-       uint    hafdup;         /* Half-duplex */
-       uint    maxfrm;         /* Maximum Frame */
-       uint    res514;
-       uint    res518;
-
-       uint    res51c;
-
-       uint    miimcfg;        /* MII Management: Configuration */
-       uint    miimcom;        /* MII Management: Command */
-       uint    miimadd;        /* MII Management: Address */
-       uint    miimcon;        /* MII Management: Control */
-       uint    miimstat;       /* MII Management: Status */
-       uint    miimind;        /* MII Management: Indicators */
-
-       uint    res538;
-
-       uint    ifstat;         /* Interface Status */
-       uint    macstnaddr1;    /* Station Address, part 1 */
-       uint    macstnaddr2;    /* Station Address, part 2 */
-       uint    res548[46];
-
-       /* (0x2_n600) */
-       uint    res600[32];
-
-       /* RMON MIB Registers (0x2_n680-0x2_n73c) */
-       rmon_mib_t      rmon;
-       uint    res740[48];
-
-       /* Hash Function Registers (0x2_n800) */
-       tsec_hash_t     hash;
-
-       uint        res900[128];
-
-       /* Pattern Registers (0x2_nb00) */
-       uint        resb00[62];
-       uint        attr;          /* Default Attribute Register */
-       uint        attreli;       /* Default Attribute Extract Length and Index */
-
-       /* TSEC Future Expansion Space (0x2_nc00-0x2_nffc) */
-       uint    resc00[256];
-} tsec_t;
-
-#define TSEC_GIGABIT (1)
-
-/* This flag currently only has
- * meaning if we're using the eTSEC */
-#define TSEC_REDUCED (1 << 1)
-
-struct tsec_private {
-       volatile tsec_t *regs;
-       volatile tsec_t *phyregs;
-       struct phy_info *phyinfo;
-       uint phyaddr;
-       u32 flags;
-       uint link;
-       uint duplexity;
-       uint speed;
-};
-
-
-/*
- * struct phy_cmd:  A command for reading or writing a PHY register
- *
- * mii_reg:  The register to read or write
- *
- * mii_data:  For writes, the value to put in the register.
- *     A value of -1 indicates this is a read.
- *
- * funct: A function pointer which is invoked for each command.
- *     For reads, this function will be passed the value read
- *     from the PHY, and process it.
- *     For writes, the result of this function will be written
- *     to the PHY register
- */
-struct phy_cmd {
-    uint mii_reg;
-    uint mii_data;
-    uint (*funct) (uint mii_reg, struct tsec_private* priv);
-};
-
-/* struct phy_info: a structure which defines attributes for a PHY
- *
- * id will contain a number which represents the PHY.  During
- * startup, the driver will poll the PHY to find out what its
- * UID--as defined by registers 2 and 3--is.  The 32-bit result
- * gotten from the PHY will be shifted right by "shift" bits to
- * discard any bits which may change based on revision numbers
- * unimportant to functionality
- *
- * The struct phy_cmd entries represent pointers to an arrays of
- * commands which tell the driver what to do to the PHY.
- */
-struct phy_info {
-    uint id;
-    char *name;
-    uint shift;
-    /* Called to configure the PHY, and modify the controller
-     * based on the results */
-    struct phy_cmd *config;
-
-    /* Called when starting up the controller */
-    struct phy_cmd *startup;
-
-    /* Called when bringing down the controller */
-    struct phy_cmd *shutdown;
-};
-
-#endif /* __TSEC_H */
diff --git a/drivers/tsi108_eth.c b/drivers/tsi108_eth.c
deleted file mode 100644 (file)
index 524e9da..0000000
+++ /dev/null
@@ -1,1036 +0,0 @@
-/***********************************************************************
- *
- * Copyright (c) 2005 Freescale Semiconductor, Inc.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * Description:
- *   Ethernet interface for Tundra TSI108 bridge chip
- *
- ***********************************************************************/
-
-#include <config.h>
-
-#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) \
-       && defined(CONFIG_TSI108_ETH)
-
-#if !defined(CONFIG_TSI108_ETH_NUM_PORTS) || (CONFIG_TSI108_ETH_NUM_PORTS > 2)
-#error "CONFIG_TSI108_ETH_NUM_PORTS must be defined as 1 or 2"
-#endif
-
-#include <common.h>
-#include <malloc.h>
-#include <net.h>
-#include <asm/cache.h>
-
-#ifdef DEBUG
-#define TSI108_ETH_DEBUG 7
-#else
-#define TSI108_ETH_DEBUG 0
-#endif
-
-#if TSI108_ETH_DEBUG > 0
-#define debug_lev(lev, fmt, args...) \
-if (lev <= TSI108_ETH_DEBUG) \
-printf ("%s %d: " fmt, __FUNCTION__, __LINE__, ##args)
-#else
-#define debug_lev(lev, fmt, args...) do{}while(0)
-#endif
-
-#define RX_PRINT_ERRORS
-#define TX_PRINT_ERRORS
-
-#define ETH_BASE       (CFG_TSI108_CSR_BASE + 0x6000)
-
-#define ETH_PORT_OFFSET        0x400
-
-#define __REG32(base, offset) (*((volatile u32 *)((char *)(base) + (offset))))
-
-#define reg_MAC_CONFIG_1(base)         __REG32(base, 0x00000000)
-#define MAC_CONFIG_1_TX_ENABLE         (0x00000001)
-#define MAC_CONFIG_1_SYNC_TX_ENABLE    (0x00000002)
-#define MAC_CONFIG_1_RX_ENABLE         (0x00000004)
-#define MAC_CONFIG_1_SYNC_RX_ENABLE    (0x00000008)
-#define MAC_CONFIG_1_TX_FLOW_CONTROL   (0x00000010)
-#define MAC_CONFIG_1_RX_FLOW_CONTROL   (0x00000020)
-#define MAC_CONFIG_1_LOOP_BACK         (0x00000100)
-#define MAC_CONFIG_1_RESET_TX_FUNCTION (0x00010000)
-#define MAC_CONFIG_1_RESET_RX_FUNCTION (0x00020000)
-#define MAC_CONFIG_1_RESET_TX_MAC      (0x00040000)
-#define MAC_CONFIG_1_RESET_RX_MAC      (0x00080000)
-#define MAC_CONFIG_1_SIM_RESET         (0x40000000)
-#define MAC_CONFIG_1_SOFT_RESET                (0x80000000)
-
-#define reg_MAC_CONFIG_2(base)         __REG32(base, 0x00000004)
-#define MAC_CONFIG_2_FULL_DUPLEX       (0x00000001)
-#define MAC_CONFIG_2_CRC_ENABLE                (0x00000002)
-#define MAC_CONFIG_2_PAD_CRC           (0x00000004)
-#define MAC_CONFIG_2_LENGTH_CHECK      (0x00000010)
-#define MAC_CONFIG_2_HUGE_FRAME                (0x00000020)
-#define MAC_CONFIG_2_INTERFACE_MODE(val)       (((val) & 0x3) << 8)
-#define MAC_CONFIG_2_PREAMBLE_LENGTH(val)      (((val) & 0xf) << 12)
-#define INTERFACE_MODE_NIBBLE          1       /* 10/100 Mb/s MII) */
-#define INTERFACE_MODE_BYTE            2       /* 1000 Mb/s GMII/TBI */
-
-#define reg_MAXIMUM_FRAME_LENGTH(base)         __REG32(base, 0x00000010)
-
-#define reg_MII_MGMT_CONFIG(base)              __REG32(base, 0x00000020)
-#define MII_MGMT_CONFIG_MGMT_CLOCK_SELECT(val) ((val) & 0x7)
-#define MII_MGMT_CONFIG_NO_PREAMBLE            (0x00000010)
-#define MII_MGMT_CONFIG_SCAN_INCREMENT         (0x00000020)
-#define MII_MGMT_CONFIG_RESET_MGMT             (0x80000000)
-
-#define reg_MII_MGMT_COMMAND(base)             __REG32(base, 0x00000024)
-#define MII_MGMT_COMMAND_READ_CYCLE            (0x00000001)
-#define MII_MGMT_COMMAND_SCAN_CYCLE            (0x00000002)
-
-#define reg_MII_MGMT_ADDRESS(base)             __REG32(base, 0x00000028)
-#define reg_MII_MGMT_CONTROL(base)             __REG32(base, 0x0000002c)
-#define reg_MII_MGMT_STATUS(base)              __REG32(base, 0x00000030)
-
-#define reg_MII_MGMT_INDICATORS(base)          __REG32(base, 0x00000034)
-#define MII_MGMT_INDICATORS_BUSY               (0x00000001)
-#define MII_MGMT_INDICATORS_SCAN               (0x00000002)
-#define MII_MGMT_INDICATORS_NOT_VALID          (0x00000004)
-
-#define reg_INTERFACE_STATUS(base)             __REG32(base, 0x0000003c)
-#define INTERFACE_STATUS_LINK_FAIL             (0x00000008)
-#define INTERFACE_STATUS_EXCESS_DEFER          (0x00000200)
-
-#define reg_STATION_ADDRESS_1(base)            __REG32(base, 0x00000040)
-#define reg_STATION_ADDRESS_2(base)            __REG32(base, 0x00000044)
-
-#define reg_PORT_CONTROL(base)                 __REG32(base, 0x00000200)
-#define PORT_CONTROL_PRI               (0x00000001)
-#define PORT_CONTROL_BPT               (0x00010000)
-#define PORT_CONTROL_SPD               (0x00040000)
-#define PORT_CONTROL_RBC               (0x00080000)
-#define PORT_CONTROL_PRB               (0x00200000)
-#define PORT_CONTROL_DIS               (0x00400000)
-#define PORT_CONTROL_TBI               (0x00800000)
-#define PORT_CONTROL_STE               (0x10000000)
-#define PORT_CONTROL_ZOR               (0x20000000)
-#define PORT_CONTROL_CLR               (0x40000000)
-#define PORT_CONTROL_SRT               (0x80000000)
-
-#define reg_TX_CONFIG(base)            __REG32(base, 0x00000220)
-#define TX_CONFIG_START_Q              (0x00000003)
-#define TX_CONFIG_EHP                  (0x00400000)
-#define TX_CONFIG_CHP                  (0x00800000)
-#define TX_CONFIG_RST                  (0x80000000)
-
-#define reg_TX_CONTROL(base)           __REG32(base, 0x00000224)
-#define TX_CONTROL_GO                  (0x00008000)
-#define TX_CONTROL_MP                  (0x01000000)
-#define TX_CONTROL_EAI                 (0x20000000)
-#define TX_CONTROL_ABT                 (0x40000000)
-#define TX_CONTROL_EII                 (0x80000000)
-
-#define reg_TX_STATUS(base)            __REG32(base, 0x00000228)
-#define TX_STATUS_QUEUE_USABLE         (0x0000000f)
-#define TX_STATUS_CURR_Q               (0x00000300)
-#define TX_STATUS_ACT                  (0x00008000)
-#define TX_STATUS_QUEUE_IDLE           (0x000f0000)
-#define TX_STATUS_EOQ_PENDING          (0x0f000000)
-
-#define reg_TX_EXTENDED_STATUS(base)           __REG32(base, 0x0000022c)
-#define TX_EXTENDED_STATUS_END_OF_QUEUE_CONDITION              (0x0000000f)
-#define TX_EXTENDED_STATUS_END_OF_FRAME_CONDITION              (0x00000f00)
-#define TX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION      (0x000f0000)
-#define TX_EXTENDED_STATUS_ERROR_FLAG                          (0x0f000000)
-
-#define reg_TX_THRESHOLDS(base)                        __REG32(base, 0x00000230)
-
-#define reg_TX_DIAGNOSTIC_ADDR(base)           __REG32(base, 0x00000270)
-#define TX_DIAGNOSTIC_ADDR_INDEX               (0x0000007f)
-#define TX_DIAGNOSTIC_ADDR_DFR                 (0x40000000)
-#define TX_DIAGNOSTIC_ADDR_AI                  (0x80000000)
-
-#define reg_TX_DIAGNOSTIC_DATA(base)           __REG32(base, 0x00000274)
-
-#define reg_TX_ERROR_STATUS(base)              __REG32(base, 0x00000278)
-#define TX_ERROR_STATUS                                (0x00000278)
-#define TX_ERROR_STATUS_QUEUE_0_ERROR_RESPONSE (0x0000000f)
-#define TX_ERROR_STATUS_TEA_ON_QUEUE_0         (0x00000010)
-#define TX_ERROR_STATUS_RER_ON_QUEUE_0         (0x00000020)
-#define TX_ERROR_STATUS_TER_ON_QUEUE_0         (0x00000040)
-#define TX_ERROR_STATUS_DER_ON_QUEUE_0         (0x00000080)
-#define TX_ERROR_STATUS_QUEUE_1_ERROR_RESPONSE (0x00000f00)
-#define TX_ERROR_STATUS_TEA_ON_QUEUE_1         (0x00001000)
-#define TX_ERROR_STATUS_RER_ON_QUEUE_1         (0x00002000)
-#define TX_ERROR_STATUS_TER_ON_QUEUE_1         (0x00004000)
-#define TX_ERROR_STATUS_DER_ON_QUEUE_1         (0x00008000)
-#define TX_ERROR_STATUS_QUEUE_2_ERROR_RESPONSE (0x000f0000)
-#define TX_ERROR_STATUS_TEA_ON_QUEUE_2         (0x00100000)
-#define TX_ERROR_STATUS_RER_ON_QUEUE_2         (0x00200000)
-#define TX_ERROR_STATUS_TER_ON_QUEUE_2         (0x00400000)
-#define TX_ERROR_STATUS_DER_ON_QUEUE_2         (0x00800000)
-#define TX_ERROR_STATUS_QUEUE_3_ERROR_RESPONSE (0x0f000000)
-#define TX_ERROR_STATUS_TEA_ON_QUEUE_3         (0x10000000)
-#define TX_ERROR_STATUS_RER_ON_QUEUE_3         (0x20000000)
-#define TX_ERROR_STATUS_TER_ON_QUEUE_3         (0x40000000)
-#define TX_ERROR_STATUS_DER_ON_QUEUE_3         (0x80000000)
-
-#define reg_TX_QUEUE_0_CONFIG(base)            __REG32(base, 0x00000280)
-#define TX_QUEUE_0_CONFIG_OCN_PORT             (0x0000003f)
-#define TX_QUEUE_0_CONFIG_BSWP                 (0x00000400)
-#define TX_QUEUE_0_CONFIG_WSWP                 (0x00000800)
-#define TX_QUEUE_0_CONFIG_AM                   (0x00004000)
-#define TX_QUEUE_0_CONFIG_GVI                  (0x00008000)
-#define TX_QUEUE_0_CONFIG_EEI                  (0x00010000)
-#define TX_QUEUE_0_CONFIG_ELI                  (0x00020000)
-#define TX_QUEUE_0_CONFIG_ENI                  (0x00040000)
-#define TX_QUEUE_0_CONFIG_ESI                  (0x00080000)
-#define TX_QUEUE_0_CONFIG_EDI                  (0x00100000)
-
-#define reg_TX_QUEUE_0_BUF_CONFIG(base)                __REG32(base, 0x00000284)
-#define TX_QUEUE_0_BUF_CONFIG_OCN_PORT         (0x0000003f)
-#define TX_QUEUE_0_BUF_CONFIG_BURST            (0x00000300)
-#define TX_QUEUE_0_BUF_CONFIG_BSWP             (0x00000400)
-#define TX_QUEUE_0_BUF_CONFIG_WSWP             (0x00000800)
-
-#define OCN_PORT_HLP                   0       /* HLP Interface */
-#define OCN_PORT_PCI_X                 1       /* PCI-X Interface */
-#define OCN_PORT_PROCESSOR_MASTER      2       /* Processor Interface (master) */
-#define OCN_PORT_PROCESSOR_SLAVE       3       /* Processor Interface (slave) */
-#define OCN_PORT_MEMORY                        4       /* Memory Controller */
-#define OCN_PORT_DMA                   5       /* DMA Controller */
-#define OCN_PORT_ETHERNET              6       /* Ethernet Controller */
-#define OCN_PORT_PRINT                 7       /* Print Engine Interface */
-
-#define reg_TX_QUEUE_0_PTR_LOW(base)           __REG32(base, 0x00000288)
-
-#define reg_TX_QUEUE_0_PTR_HIGH(base)          __REG32(base, 0x0000028c)
-#define TX_QUEUE_0_PTR_HIGH_VALID              (0x80000000)
-
-#define reg_RX_CONFIG(base)                    __REG32(base, 0x00000320)
-#define RX_CONFIG_DEF_Q                                (0x00000003)
-#define RX_CONFIG_EMF                          (0x00000100)
-#define RX_CONFIG_EUF                          (0x00000200)
-#define RX_CONFIG_BFE                          (0x00000400)
-#define RX_CONFIG_MFE                          (0x00000800)
-#define RX_CONFIG_UFE                          (0x00001000)
-#define RX_CONFIG_SE                           (0x00002000)
-#define RX_CONFIG_ABF                          (0x00200000)
-#define RX_CONFIG_APE                          (0x00400000)
-#define RX_CONFIG_CHP                          (0x00800000)
-#define RX_CONFIG_RST                          (0x80000000)
-
-#define reg_RX_CONTROL(base)                   __REG32(base, 0x00000324)
-#define GE_E0_RX_CONTROL_QUEUE_ENABLES         (0x0000000f)
-#define GE_E0_RX_CONTROL_GO                    (0x00008000)
-#define GE_E0_RX_CONTROL_EAI                   (0x20000000)
-#define GE_E0_RX_CONTROL_ABT                   (0x40000000)
-#define GE_E0_RX_CONTROL_EII                   (0x80000000)
-
-#define reg_RX_EXTENDED_STATUS(base)           __REG32(base, 0x0000032c)
-#define RX_EXTENDED_STATUS                     (0x0000032c)
-#define RX_EXTENDED_STATUS_EOQ                 (0x0000000f)
-#define RX_EXTENDED_STATUS_EOQ_0               (0x00000001)
-#define RX_EXTENDED_STATUS_EOF                 (0x00000f00)
-#define RX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION      (0x000f0000)
-#define RX_EXTENDED_STATUS_ERROR_FLAG                          (0x0f000000)
-
-#define reg_RX_THRESHOLDS(base)                        __REG32(base, 0x00000330)
-
-#define reg_RX_DIAGNOSTIC_ADDR(base)           __REG32(base, 0x00000370)
-#define RX_DIAGNOSTIC_ADDR_INDEX               (0x0000007f)
-#define RX_DIAGNOSTIC_ADDR_DFR                 (0x40000000)
-#define RX_DIAGNOSTIC_ADDR_AI                  (0x80000000)
-
-#define reg_RX_DIAGNOSTIC_DATA(base)           __REG32(base, 0x00000374)
-
-#define reg_RX_QUEUE_0_CONFIG(base)            __REG32(base, 0x00000380)
-#define RX_QUEUE_0_CONFIG_OCN_PORT             (0x0000003f)
-#define RX_QUEUE_0_CONFIG_BSWP                 (0x00000400)
-#define RX_QUEUE_0_CONFIG_WSWP                 (0x00000800)
-#define RX_QUEUE_0_CONFIG_AM                   (0x00004000)
-#define RX_QUEUE_0_CONFIG_EEI                  (0x00010000)
-#define RX_QUEUE_0_CONFIG_ELI                  (0x00020000)
-#define RX_QUEUE_0_CONFIG_ENI                  (0x00040000)
-#define RX_QUEUE_0_CONFIG_ESI                  (0x00080000)
-#define RX_QUEUE_0_CONFIG_EDI                  (0x00100000)
-
-#define reg_RX_QUEUE_0_BUF_CONFIG(base)                __REG32(base, 0x00000384)
-#define RX_QUEUE_0_BUF_CONFIG_OCN_PORT         (0x0000003f)
-#define RX_QUEUE_0_BUF_CONFIG_BURST            (0x00000300)
-#define RX_QUEUE_0_BUF_CONFIG_BSWP             (0x00000400)
-#define RX_QUEUE_0_BUF_CONFIG_WSWP             (0x00000800)
-
-#define reg_RX_QUEUE_0_PTR_LOW(base)           __REG32(base, 0x00000388)
-
-#define reg_RX_QUEUE_0_PTR_HIGH(base)          __REG32(base, 0x0000038c)
-#define RX_QUEUE_0_PTR_HIGH_VALID              (0x80000000)
-
-/*
- *  PHY register definitions
- */
-/* the first 15 PHY registers are standard. */
-#define PHY_CTRL_REG           0       /* Control Register */
-#define PHY_STATUS_REG         1       /* Status Regiser */
-#define PHY_ID1_REG            2       /* Phy Id Reg (word 1) */
-#define PHY_ID2_REG            3       /* Phy Id Reg (word 2) */
-#define PHY_AN_ADV_REG         4       /* Autoneg Advertisement */
-#define PHY_LP_ABILITY_REG     5       /* Link Partner Ability (Base Page) */
-#define PHY_AUTONEG_EXP_REG    6       /* Autoneg Expansion Reg */
-#define PHY_NEXT_PAGE_TX_REG   7       /* Next Page TX */
-#define PHY_LP_NEXT_PAGE_REG   8       /* Link Partner Next Page */
-#define PHY_1000T_CTRL_REG     9       /* 1000Base-T Control Reg */
-#define PHY_1000T_STATUS_REG   10      /* 1000Base-T Status Reg */
-#define PHY_EXT_STATUS_REG     11      /* Extended Status Reg */
-
-/*
- * PHY Register bit masks.
- */
-#define PHY_CTRL_RESET         (1 << 15)
-#define PHY_CTRL_LOOPBACK      (1 << 14)
-#define PHY_CTRL_SPEED0                (1 << 13)
-#define PHY_CTRL_AN_EN         (1 << 12)
-#define PHY_CTRL_PWR_DN                (1 << 11)
-#define PHY_CTRL_ISOLATE       (1 << 10)
-#define PHY_CTRL_RESTART_AN    (1 << 9)
-#define PHY_CTRL_FULL_DUPLEX   (1 << 8)
-#define PHY_CTRL_CT_EN         (1 << 7)
-#define PHY_CTRL_SPEED1                (1 << 6)
-
-#define PHY_STAT_100BASE_T4    (1 << 15)
-#define PHY_STAT_100BASE_X_FD  (1 << 14)
-#define PHY_STAT_100BASE_X_HD  (1 << 13)
-#define PHY_STAT_10BASE_T_FD   (1 << 12)
-#define PHY_STAT_10BASE_T_HD   (1 << 11)
-#define PHY_STAT_100BASE_T2_FD (1 << 10)
-#define PHY_STAT_100BASE_T2_HD (1 << 9)
-#define PHY_STAT_EXT_STAT      (1 << 8)
-#define PHY_STAT_RESERVED      (1 << 7)
-#define PHY_STAT_MFPS          (1 << 6)        /* Management Frames Preamble Suppression */
-#define PHY_STAT_AN_COMPLETE   (1 << 5)
-#define PHY_STAT_REM_FAULT     (1 << 4)
-#define PHY_STAT_AN_CAP                (1 << 3)
-#define PHY_STAT_LINK_UP       (1 << 2)
-#define PHY_STAT_JABBER                (1 << 1)
-#define PHY_STAT_EXT_CAP       (1 << 0)
-
-#define TBI_CONTROL_2                                  0x11
-#define TBI_CONTROL_2_ENABLE_COMMA_DETECT              0x0001
-#define TBI_CONTROL_2_ENABLE_WRAP                      0x0002
-#define TBI_CONTROL_2_G_MII_MODE                       0x0010
-#define TBI_CONTROL_2_RECEIVE_CLOCK_SELECT             0x0020
-#define TBI_CONTROL_2_AUTO_NEGOTIATION_SENSE           0x0100
-#define TBI_CONTROL_2_DISABLE_TRANSMIT_RUNNING_DISPARITY       0x1000
-#define TBI_CONTROL_2_DISABLE_RECEIVE_RUNNING_DISPARITY                0x2000
-#define TBI_CONTROL_2_SHORTCUT_LINK_TIMER                      0x4000
-#define TBI_CONTROL_2_SOFT_RESET                               0x8000
-
-/* marvel specific */
-#define MV1111_EXT_CTRL1_REG   16      /* PHY Specific Control Reg */
-#define MV1111_SPEC_STAT_REG   17      /* PHY Specific Status Reg */
-#define MV1111_EXT_CTRL2_REG   20      /* Extended PHY Specific Control Reg */
-
-/*
- * MARVELL 88E1111 PHY register bit masks
- */
-/* PHY Specific Status Register (MV1111_EXT_CTRL1_REG) */
-
-#define SPEC_STAT_SPEED_MASK   (3 << 14)
-#define SPEC_STAT_FULL_DUP     (1 << 13)
-#define SPEC_STAT_PAGE_RCVD    (1 << 12)
-#define SPEC_STAT_RESOLVED     (1 << 11)       /* Speed and Duplex Resolved */
-#define SPEC_STAT_LINK_UP      (1 << 10)
-#define SPEC_STAT_CABLE_LEN_MASK       (7 << 7)/* Cable Length (100/1000 modes only) */
-#define SPEC_STAT_MDIX         (1 << 6)
-#define SPEC_STAT_POLARITY     (1 << 1)
-#define SPEC_STAT_JABBER       (1 << 0)
-
-#define SPEED_1000             (2 << 14)
-#define SPEED_100              (1 << 14)
-#define SPEED_10               (0 << 14)
-
-#define TBI_ADDR       0x1E    /* Ten Bit Interface address */
-
-/* negotiated link parameters */
-#define LINK_SPEED_UNKNOWN     0
-#define LINK_SPEED_10          1
-#define LINK_SPEED_100         2
-#define LINK_SPEED_1000                3
-
-#define LINK_DUPLEX_UNKNOWN    0
-#define LINK_DUPLEX_HALF       1
-#define LINK_DUPLEX_FULL       2
-
-static unsigned int phy_address[] = { 8, 9 };
-
-#define vuint32 volatile u32
-
-/* TX/RX buffer descriptors. MUST be cache line aligned in memory. (32 byte)
- * This structure is accessed by the ethernet DMA engine which means it
- * MUST be in LITTLE ENDIAN format */
-struct dma_descriptor {
-       vuint32 start_addr0;    /* buffer address, least significant bytes. */
-       vuint32 start_addr1;    /* buffer address, most significant bytes. */
-       vuint32 next_descr_addr0;/* next descriptor address, least significant bytes.  Must be 64-bit aligned. */
-       vuint32 next_descr_addr1;/* next descriptor address, most significant bytes. */
-       vuint32 vlan_byte_count;/* VLAN tag(top 2 bytes) and byte countt (bottom 2 bytes). */
-       vuint32 config_status;  /* Configuration/Status. */
-       vuint32 reserved1;      /* reserved to make the descriptor cache line aligned. */
-       vuint32 reserved2;      /* reserved to make the descriptor cache line aligned. */
-};
-
-/* last next descriptor address flag */
-#define DMA_DESCR_LAST         (1 << 31)
-
-/* TX DMA descriptor config status bits */
-#define DMA_DESCR_TX_EOF       (1 <<  0)       /* end of frame */
-#define DMA_DESCR_TX_SOF       (1 <<  1)       /* start of frame */
-#define DMA_DESCR_TX_PFVLAN    (1 <<  2)
-#define DMA_DESCR_TX_HUGE      (1 <<  3)
-#define DMA_DESCR_TX_PAD       (1 <<  4)
-#define DMA_DESCR_TX_CRC       (1 <<  5)
-#define DMA_DESCR_TX_DESCR_INT (1 << 14)
-#define DMA_DESCR_TX_RETRY_COUNT       0x000F0000
-#define DMA_DESCR_TX_ONE_COLLISION     (1 << 20)
-#define DMA_DESCR_TX_LATE_COLLISION    (1 << 24)
-#define DMA_DESCR_TX_UNDERRUN          (1 << 25)
-#define DMA_DESCR_TX_RETRY_LIMIT       (1 << 26)
-#define DMA_DESCR_TX_OK                        (1 << 30)
-#define DMA_DESCR_TX_OWNER             (1 << 31)
-
-/* RX DMA descriptor status bits */
-#define DMA_DESCR_RX_EOF               (1 <<  0)
-#define DMA_DESCR_RX_SOF               (1 <<  1)
-#define DMA_DESCR_RX_VTF               (1 <<  2)
-#define DMA_DESCR_RX_FRAME_IS_TYPE     (1 <<  3)
-#define DMA_DESCR_RX_SHORT_FRAME       (1 <<  4)
-#define DMA_DESCR_RX_HASH_MATCH                (1 <<  7)
-#define DMA_DESCR_RX_BAD_FRAME         (1 <<  8)
-#define DMA_DESCR_RX_OVERRUN           (1 <<  9)
-#define DMA_DESCR_RX_MAX_FRAME_LEN     (1 << 11)
-#define DMA_DESCR_RX_CRC_ERROR         (1 << 12)
-#define DMA_DESCR_RX_DESCR_INT         (1 << 13)
-#define DMA_DESCR_RX_OWNER             (1 << 15)
-
-#define RX_BUFFER_SIZE PKTSIZE
-#define NUM_RX_DESC    PKTBUFSRX
-
-static struct dma_descriptor tx_descriptor __attribute__ ((aligned(32)));
-
-static struct dma_descriptor rx_descr_array[NUM_RX_DESC]
-       __attribute__ ((aligned(32)));
-
-static struct dma_descriptor *rx_descr_current;
-
-static int tsi108_eth_probe (struct eth_device *dev, bd_t * bis);
-static int tsi108_eth_send (struct eth_device *dev,
-                          volatile void *packet, int length);
-static int tsi108_eth_recv (struct eth_device *dev);
-static void tsi108_eth_halt (struct eth_device *dev);
-static unsigned int read_phy (unsigned int base,
-                            unsigned int phy_addr, unsigned int phy_reg);
-static void write_phy (unsigned int base,
-                     unsigned int phy_addr,
-                     unsigned int phy_reg, unsigned int phy_data);
-
-#if TSI108_ETH_DEBUG > 100
-/*
- * print phy debug infomation
- */
-static void dump_phy_regs (unsigned int phy_addr)
-{
-       int i;
-
-       printf ("PHY %d registers\n", phy_addr);
-       for (i = 0; i <= 30; i++) {
-               printf ("%2d  0x%04x\n", i, read_phy (ETH_BASE, phy_addr, i));
-       }
-       printf ("\n");
-
-}
-#else
-#define dump_phy_regs(base) do{}while(0)
-#endif
-
-#if TSI108_ETH_DEBUG > 100
-/*
- * print debug infomation
- */
-static void tx_diag_regs (unsigned int base)
-{
-       int i;
-       unsigned long dummy;
-
-       printf ("TX diagnostics registers\n");
-       reg_TX_DIAGNOSTIC_ADDR(base) = 0x00 | TX_DIAGNOSTIC_ADDR_AI;
-       udelay (1000);
-       dummy = reg_TX_DIAGNOSTIC_DATA(base);
-       for (i = 0x00; i <= 0x05; i++) {
-               udelay (1000);
-               printf ("0x%02x  0x%08x\n", i, reg_TX_DIAGNOSTIC_DATA(base));
-       }
-       reg_TX_DIAGNOSTIC_ADDR(base) = 0x40 | TX_DIAGNOSTIC_ADDR_AI;
-       udelay (1000);
-       dummy = reg_TX_DIAGNOSTIC_DATA(base);
-       for (i = 0x40; i <= 0x47; i++) {
-               udelay (1000);
-               printf ("0x%02x  0x%08x\n", i, reg_TX_DIAGNOSTIC_DATA(base));
-       }
-       printf ("\n");
-
-}
-#else
-#define tx_diag_regs(base) do{}while(0)
-#endif
-
-#if TSI108_ETH_DEBUG > 100
-/*
- * print debug infomation
- */
-static void rx_diag_regs (unsigned int base)
-{
-       int i;
-       unsigned long dummy;
-
-       printf ("RX diagnostics registers\n");
-       reg_RX_DIAGNOSTIC_ADDR(base) = 0x00 | RX_DIAGNOSTIC_ADDR_AI;
-       udelay (1000);
-       dummy = reg_RX_DIAGNOSTIC_DATA(base);
-       for (i = 0x00; i <= 0x05; i++) {
-               udelay (1000);
-               printf ("0x%02x  0x%08x\n", i, reg_RX_DIAGNOSTIC_DATA(base));
-       }
-       reg_RX_DIAGNOSTIC_ADDR(base) = 0x40 | RX_DIAGNOSTIC_ADDR_AI;
-       udelay (1000);
-       dummy = reg_RX_DIAGNOSTIC_DATA(base);
-       for (i = 0x08; i <= 0x0a; i++) {
-               udelay (1000);
-               printf ("0x%02x  0x%08x\n", i, reg_RX_DIAGNOSTIC_DATA(base));
-       }
-       printf ("\n");
-
-}
-#else
-#define rx_diag_regs(base) do{}while(0)
-#endif
-
-#if TSI108_ETH_DEBUG > 100
-/*
- * print debug infomation
- */
-static void debug_mii_regs (unsigned int base)
-{
-       printf ("MII_MGMT_CONFIG     0x%08x\n", reg_MII_MGMT_CONFIG(base));
-       printf ("MII_MGMT_COMMAND    0x%08x\n", reg_MII_MGMT_COMMAND(base));
-       printf ("MII_MGMT_ADDRESS    0x%08x\n", reg_MII_MGMT_ADDRESS(base));
-       printf ("MII_MGMT_CONTROL    0x%08x\n", reg_MII_MGMT_CONTROL(base));
-       printf ("MII_MGMT_STATUS     0x%08x\n", reg_MII_MGMT_STATUS(base));
-       printf ("MII_MGMT_INDICATORS 0x%08x\n", reg_MII_MGMT_INDICATORS(base));
-       printf ("\n");
-
-}
-#else
-#define debug_mii_regs(base) do{}while(0)
-#endif
-
-/*
- * Wait until the phy bus is non-busy
- */
-static void phy_wait (unsigned int base, unsigned int condition)
-{
-       int timeout;
-
-       timeout = 0;
-       while (reg_MII_MGMT_INDICATORS(base) & condition) {
-               udelay (10);
-               if (++timeout > 10000) {
-                       printf ("ERROR: timeout waiting for phy bus (%d)\n",
-                              condition);
-                       break;
-               }
-       }
-}
-
-/*
- * read phy register
- */
-static unsigned int read_phy (unsigned int base,
-                            unsigned int phy_addr, unsigned int phy_reg)
-{
-       unsigned int value;
-
-       phy_wait (base, MII_MGMT_INDICATORS_BUSY);
-
-       reg_MII_MGMT_ADDRESS(base) = (phy_addr << 8) | phy_reg;
-
-       /* Ensure that the Read Cycle bit is cleared prior to next read cycle */
-       reg_MII_MGMT_COMMAND(base) = 0;
-
-       /* start the read */
-       reg_MII_MGMT_COMMAND(base) = MII_MGMT_COMMAND_READ_CYCLE;
-
-       /* wait for the read to complete */
-       phy_wait (base,
-                MII_MGMT_INDICATORS_NOT_VALID | MII_MGMT_INDICATORS_BUSY);
-
-       value = reg_MII_MGMT_STATUS(base);
-
-       reg_MII_MGMT_COMMAND(base) = 0;
-
-       return value;
-}
-
-/*
- * write phy register
- */
-static void write_phy (unsigned int base,
-                     unsigned int phy_addr,
-                     unsigned int phy_reg, unsigned int phy_data)
-{
-       phy_wait (base, MII_MGMT_INDICATORS_BUSY);
-
-       reg_MII_MGMT_ADDRESS(base) = (phy_addr << 8) | phy_reg;
-
-       /* Ensure that the Read Cycle bit is cleared prior to next cycle */
-       reg_MII_MGMT_COMMAND(base) = 0;
-
-       /* start the write */
-       reg_MII_MGMT_CONTROL(base) = phy_data;
-}
-
-/*
- * configure the marvell 88e1111 phy
- */
-static int marvell_88e_phy_config (struct eth_device *dev, int *speed,
-                                 int *duplex)
-{
-       unsigned long base;
-       unsigned long phy_addr;
-       unsigned int phy_status;
-       unsigned int phy_spec_status;
-       int timeout;
-       int phy_speed;
-       int phy_duplex;
-       unsigned int value;
-
-       phy_speed = LINK_SPEED_UNKNOWN;
-       phy_duplex = LINK_DUPLEX_UNKNOWN;
-
-       base = dev->iobase;
-       phy_addr = (unsigned long)dev->priv;
-
-       /* Take the PHY out of reset. */
-       write_phy (ETH_BASE, phy_addr, PHY_CTRL_REG, PHY_CTRL_RESET);
-
-       /* Wait for the reset process to complete. */
-       udelay (10);
-       timeout = 0;
-       while ((phy_status =
-               read_phy (ETH_BASE, phy_addr, PHY_CTRL_REG)) & PHY_CTRL_RESET) {
-               udelay (10);
-               if (++timeout > 10000) {
-                       printf ("ERROR: timeout waiting for phy reset\n");
-                       break;
-               }
-       }
-
-       /* TBI Configuration. */
-       write_phy (base, TBI_ADDR, TBI_CONTROL_2, TBI_CONTROL_2_G_MII_MODE |
-                 TBI_CONTROL_2_RECEIVE_CLOCK_SELECT);
-       /* Wait for the link to be established. */
-       timeout = 0;
-       do {
-               udelay (20000);
-               phy_status = read_phy (ETH_BASE, phy_addr, PHY_STATUS_REG);
-               if (++timeout > 100) {
-                       debug_lev(1, "ERROR: unable to establish link!!!\n");
-                       break;
-               }
-       } while ((phy_status & PHY_STAT_LINK_UP) == 0);
-
-       if ((phy_status & PHY_STAT_LINK_UP) == 0)
-               return 0;
-
-       value = 0;
-       phy_spec_status = read_phy (ETH_BASE, phy_addr, MV1111_SPEC_STAT_REG);
-       if (phy_spec_status & SPEC_STAT_RESOLVED) {
-               switch (phy_spec_status & SPEC_STAT_SPEED_MASK) {
-               case SPEED_1000:
-                       phy_speed = LINK_SPEED_1000;
-                       value |= PHY_CTRL_SPEED1;
-                       break;
-               case SPEED_100:
-                       phy_speed = LINK_SPEED_100;
-                       value |= PHY_CTRL_SPEED0;
-                       break;
-               case SPEED_10:
-                       phy_speed = LINK_SPEED_10;
-                       break;
-               }
-               if (phy_spec_status & SPEC_STAT_FULL_DUP) {
-                       phy_duplex = LINK_DUPLEX_FULL;
-                       value |= PHY_CTRL_FULL_DUPLEX;
-               } else
-                       phy_duplex = LINK_DUPLEX_HALF;
-       }
-       /* set TBI speed */
-       write_phy (base, TBI_ADDR, PHY_CTRL_REG, value);
-       write_phy (base, TBI_ADDR, PHY_AN_ADV_REG, 0x0060);
-
-#if TSI108_ETH_DEBUG > 0
-       printf ("%s link is up", dev->name);
-       phy_spec_status = read_phy (ETH_BASE, phy_addr, MV1111_SPEC_STAT_REG);
-       if (phy_spec_status & SPEC_STAT_RESOLVED) {
-               switch (phy_speed) {
-               case LINK_SPEED_1000:
-                       printf (", 1000 Mbps");
-                       break;
-               case LINK_SPEED_100:
-                       printf (", 100 Mbps");
-                       break;
-               case LINK_SPEED_10:
-                       printf (", 10 Mbps");
-                       break;
-               }
-               if (phy_duplex == LINK_DUPLEX_FULL)
-                       printf (", Full duplex");
-               else
-                       printf (", Half duplex");
-       }
-       printf ("\n");
-#endif
-
-       dump_phy_regs (TBI_ADDR);
-       if (speed)
-               *speed = phy_speed;
-       if (duplex)
-               *duplex = phy_duplex;
-
-       return 1;
-}
-
-/*
- * External interface
- *
- * register the tsi108 ethernet controllers with the multi-ethernet system
- */
-int tsi108_eth_initialize (bd_t * bis)
-{
-       struct eth_device *dev;
-       int index;
-
-       for (index = 0; index < CONFIG_TSI108_ETH_NUM_PORTS; index++) {
-               dev = (struct eth_device *)malloc(sizeof(struct eth_device));
-
-               sprintf (dev->name, "TSI108_eth%d", index);
-
-               dev->iobase = ETH_BASE + (index * ETH_PORT_OFFSET);
-               dev->priv = (void *)(phy_address[index]);
-               dev->init = tsi108_eth_probe;
-               dev->halt = tsi108_eth_halt;
-               dev->send = tsi108_eth_send;
-               dev->recv = tsi108_eth_recv;
-
-               eth_register(dev);
-       }
-       return index;
-}
-
-/*
- * probe for and initialize a single ethernet interface
- */
-static int tsi108_eth_probe (struct eth_device *dev, bd_t * bis)
-{
-       unsigned long base;
-       unsigned long value;
-       int index;
-       struct dma_descriptor *tx_descr;
-       struct dma_descriptor *rx_descr;
-       int speed;
-       int duplex;
-
-       base = dev->iobase;
-
-       reg_PORT_CONTROL(base) = PORT_CONTROL_STE | PORT_CONTROL_BPT;
-
-       /* Bring DMA/FIFO out of reset. */
-       reg_TX_CONFIG(base) = 0x00000000;
-       reg_RX_CONFIG(base) = 0x00000000;
-
-       reg_TX_THRESHOLDS(base) = (192 << 16) | 192;
-       reg_RX_THRESHOLDS(base) = (192 << 16) | 112;
-
-       /* Bring MAC out of reset. */
-       reg_MAC_CONFIG_1(base) = 0x00000000;
-
-       /* DMA MAC configuration. */
-       reg_MAC_CONFIG_1(base) =
-           MAC_CONFIG_1_RX_ENABLE | MAC_CONFIG_1_TX_ENABLE;
-
-       reg_MII_MGMT_CONFIG(base) = MII_MGMT_CONFIG_NO_PREAMBLE;
-       reg_MAXIMUM_FRAME_LENGTH(base) = RX_BUFFER_SIZE;
-
-       /* Note: Early tsi108 manual did not have correct byte order
-        * for the station address.*/
-       reg_STATION_ADDRESS_1(base) = (dev->enetaddr[5] << 24) |
-           (dev->enetaddr[4] << 16) |
-           (dev->enetaddr[3] << 8) | (dev->enetaddr[2] << 0);
-
-       reg_STATION_ADDRESS_2(base) = (dev->enetaddr[1] << 24) |
-           (dev->enetaddr[0] << 16);
-
-       if (marvell_88e_phy_config(dev, &speed, &duplex) == 0)
-               return 0;
-
-       value =
-           MAC_CONFIG_2_PREAMBLE_LENGTH(7) | MAC_CONFIG_2_PAD_CRC |
-           MAC_CONFIG_2_CRC_ENABLE;
-       if (speed == LINK_SPEED_1000)
-               value |= MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_BYTE);
-       else {
-               value |= MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_NIBBLE);
-               reg_PORT_CONTROL(base) |= PORT_CONTROL_SPD;
-       }
-       if (duplex == LINK_DUPLEX_FULL) {
-               value |= MAC_CONFIG_2_FULL_DUPLEX;
-               reg_PORT_CONTROL(base) &= ~PORT_CONTROL_BPT;
-       } else
-               reg_PORT_CONTROL(base) |= PORT_CONTROL_BPT;
-       reg_MAC_CONFIG_2(base) = value;
-
-       reg_RX_CONFIG(base) = RX_CONFIG_SE;
-       reg_RX_QUEUE_0_CONFIG(base) = OCN_PORT_MEMORY;
-       reg_RX_QUEUE_0_BUF_CONFIG(base) = OCN_PORT_MEMORY;
-
-       /* initialize the RX DMA descriptors */
-       rx_descr = &rx_descr_array[0];
-       rx_descr_current = rx_descr;
-       for (index = 0; index < NUM_RX_DESC; index++) {
-               /* make sure the receive buffers are not in cache */
-               invalidate_dcache_range((unsigned long)NetRxPackets[index],
-                                       (unsigned long)NetRxPackets[index] +
-                                       RX_BUFFER_SIZE);
-               rx_descr->start_addr0 =
-                   cpu_to_le32((vuint32) NetRxPackets[index]);
-               rx_descr->start_addr1 = 0;
-               rx_descr->next_descr_addr0 =
-                   cpu_to_le32((vuint32) (rx_descr + 1));
-               rx_descr->next_descr_addr1 = 0;
-               rx_descr->vlan_byte_count = 0;
-               rx_descr->config_status = cpu_to_le32((RX_BUFFER_SIZE << 16) |
-                                                     DMA_DESCR_RX_OWNER);
-               rx_descr++;
-       }
-       rx_descr--;
-       rx_descr->next_descr_addr0 = 0;
-       rx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);
-       /* Push the descriptors to RAM so the ethernet DMA can see them */
-       invalidate_dcache_range((unsigned long)rx_descr_array,
-                               (unsigned long)rx_descr_array +
-                               sizeof(rx_descr_array));
-
-       /* enable RX queue */
-       reg_RX_CONTROL(base) = TX_CONTROL_GO | 0x01;
-       reg_RX_QUEUE_0_PTR_LOW(base) = (u32) rx_descr_current;
-       /* enable receive DMA */
-       reg_RX_QUEUE_0_PTR_HIGH(base) = RX_QUEUE_0_PTR_HIGH_VALID;
-
-       reg_TX_QUEUE_0_CONFIG(base) = OCN_PORT_MEMORY;
-       reg_TX_QUEUE_0_BUF_CONFIG(base) = OCN_PORT_MEMORY;
-
-       /* initialize the TX DMA descriptor */
-       tx_descr = &tx_descriptor;
-
-       tx_descr->start_addr0 = 0;
-       tx_descr->start_addr1 = 0;
-       tx_descr->next_descr_addr0 = 0;
-       tx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);
-       tx_descr->vlan_byte_count = 0;
-       tx_descr->config_status = cpu_to_le32(DMA_DESCR_TX_OK |
-                                             DMA_DESCR_TX_SOF |
-                                             DMA_DESCR_TX_EOF);
-       /* enable TX queue */
-       reg_TX_CONTROL(base) = TX_CONTROL_GO | 0x01;
-
-       return 1;
-}
-
-/*
- * send a packet
- */
-static int tsi108_eth_send (struct eth_device *dev,
-                          volatile void *packet, int length)
-{
-       unsigned long base;
-       int timeout;
-       struct dma_descriptor *tx_descr;
-       unsigned long status;
-
-       base = dev->iobase;
-       tx_descr = &tx_descriptor;
-
-       /* Wait until the last packet has been transmitted. */
-       timeout = 0;
-       do {
-               /* make sure we see the changes made by the DMA engine */
-               invalidate_dcache_range((unsigned long)tx_descr,
-                                       (unsigned long)tx_descr +
-                                       sizeof(struct dma_descriptor));
-
-               if (timeout != 0)
-                       udelay (15);
-               if (++timeout > 10000) {
-                       tx_diag_regs(base);
-                       debug_lev(1,
-                                 "ERROR: timeout waiting for last transmit packet to be sent\n");
-                       return 0;
-               }
-       } while (tx_descr->config_status & cpu_to_le32(DMA_DESCR_TX_OWNER));
-
-       status = le32_to_cpu(tx_descr->config_status);
-       if ((status & DMA_DESCR_TX_OK) == 0) {
-#ifdef TX_PRINT_ERRORS
-               printf ("TX packet error: 0x%08x\n    %s%s%s%s\n", status,
-                      status & DMA_DESCR_TX_OK ? "tx error, " : "",
-                      status & DMA_DESCR_TX_RETRY_LIMIT ?
-                      "retry limit reached, " : "",
-                      status & DMA_DESCR_TX_UNDERRUN ? "underrun, " : "",
-                      status & DMA_DESCR_TX_LATE_COLLISION ? "late collision, "
-                      : "");
-#endif
-       }
-
-       debug_lev (9, "sending packet %d\n", length);
-       tx_descr->start_addr0 = cpu_to_le32((vuint32) packet);
-       tx_descr->start_addr1 = 0;
-       tx_descr->next_descr_addr0 = 0;
-       tx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);
-       tx_descr->vlan_byte_count = cpu_to_le32(length);
-       tx_descr->config_status = cpu_to_le32(DMA_DESCR_TX_OWNER |
-                                             DMA_DESCR_TX_CRC |
-                                             DMA_DESCR_TX_PAD |
-                                             DMA_DESCR_TX_SOF |
-                                             DMA_DESCR_TX_EOF);
-
-       invalidate_dcache_range((unsigned long)tx_descr,
-                               (unsigned long)tx_descr +
-                               sizeof(struct dma_descriptor));
-
-       invalidate_dcache_range((unsigned long)packet,
-                               (unsigned long)packet + length);
-
-       reg_TX_QUEUE_0_PTR_LOW(base) = (u32) tx_descr;
-       reg_TX_QUEUE_0_PTR_HIGH(base) = TX_QUEUE_0_PTR_HIGH_VALID;
-
-       return length;
-}
-
-/*
- * Check for received packets and send them up the protocal stack
- */
-static int tsi108_eth_recv (struct eth_device *dev)
-{
-       struct dma_descriptor *rx_descr;
-       unsigned long base;
-       int length = 0;
-       unsigned long status;
-       volatile uchar *buffer;
-
-       base = dev->iobase;
-
-       /* make sure we see the changes made by the DMA engine */
-       invalidate_dcache_range ((unsigned long)rx_descr_array,
-                               (unsigned long)rx_descr_array +
-                               sizeof(rx_descr_array));
-
-       /* process all of the received packets */
-       rx_descr = rx_descr_current;
-       while ((rx_descr->config_status & cpu_to_le32(DMA_DESCR_RX_OWNER)) == 0) {
-               /* check for error */
-               status = le32_to_cpu(rx_descr->config_status);
-               if (status & DMA_DESCR_RX_BAD_FRAME) {
-#ifdef RX_PRINT_ERRORS
-                       printf ("RX packet error: 0x%08x\n    %s%s%s%s%s%s\n",
-                              status,
-                              status & DMA_DESCR_RX_FRAME_IS_TYPE ? "too big, "
-                              : "",
-                              status & DMA_DESCR_RX_SHORT_FRAME ? "too short, "
-                              : "",
-                              status & DMA_DESCR_RX_BAD_FRAME ? "bad frame, " :
-                              "",
-                              status & DMA_DESCR_RX_OVERRUN ? "overrun, " : "",
-                              status & DMA_DESCR_RX_MAX_FRAME_LEN ?
-                              "max length, " : "",
-                              status & DMA_DESCR_RX_CRC_ERROR ? "CRC error, " :
-                              "");
-#endif
-               } else {
-                       length =
-                           le32_to_cpu(rx_descr->vlan_byte_count) & 0xFFFF;
-
-                       /*** process packet ***/
-                       buffer =
-                           (volatile uchar
-                            *)(le32_to_cpu (rx_descr->start_addr0));
-                       NetReceive (buffer, length);
-
-                       invalidate_dcache_range ((unsigned long)buffer,
-                                               (unsigned long)buffer +
-                                               RX_BUFFER_SIZE);
-               }
-               /* Give this buffer back to the DMA engine */
-               rx_descr->vlan_byte_count = 0;
-               rx_descr->config_status = cpu_to_le32 ((RX_BUFFER_SIZE << 16) |
-                                                     DMA_DESCR_RX_OWNER);
-               /* move descriptor pointer forward */
-               rx_descr =
-                   (struct dma_descriptor
-                    *)(le32_to_cpu (rx_descr->next_descr_addr0));
-               if (rx_descr == 0)
-                       rx_descr = &rx_descr_array[0];
-       }
-       /* remember where we are for next time */
-       rx_descr_current = rx_descr;
-
-       /* If the DMA engine has reached the end of the queue
-        * start over at the begining */
-       if (reg_RX_EXTENDED_STATUS(base) & RX_EXTENDED_STATUS_EOQ_0) {
-
-               reg_RX_EXTENDED_STATUS(base) = RX_EXTENDED_STATUS_EOQ_0;
-               reg_RX_QUEUE_0_PTR_LOW(base) = (u32) & rx_descr_array[0];
-               reg_RX_QUEUE_0_PTR_HIGH(base) = RX_QUEUE_0_PTR_HIGH_VALID;
-       }
-
-       return length;
-}
-
-/*
- * disable an ethernet interface
- */
-static void tsi108_eth_halt (struct eth_device *dev)
-{
-       unsigned long base;
-
-       base = dev->iobase;
-
-       /* Put DMA/FIFO into reset state. */
-       reg_TX_CONFIG(base) = TX_CONFIG_RST;
-       reg_RX_CONFIG(base) = RX_CONFIG_RST;
-
-       /* Put MAC into reset state. */
-       reg_MAC_CONFIG_1(base) = MAC_CONFIG_1_SOFT_RESET;
-}
-
-#endif
diff --git a/drivers/tsi108_i2c.c b/drivers/tsi108_i2c.c
deleted file mode 100644 (file)
index 3a3b75c..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * (C) Copyright 2004 Tundra Semiconductor Corp.
- * Author: Alex Bounine
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- */
-
-#include <config.h>
-#include <common.h>
-
-#ifdef CONFIG_TSI108_I2C
-#include <tsi108.h>
-
-#if defined(CONFIG_CMD_I2C)
-
-#define I2C_DELAY      100000
-#undef  DEBUG_I2C
-
-#ifdef DEBUG_I2C
-#define DPRINT(x) printf (x)
-#else
-#define DPRINT(x)
-#endif
-
-/* All functions assume that Tsi108 I2C block is the only master on the bus */
-/* I2C read helper function */
-
-static int i2c_read_byte (
-               uint i2c_chan,  /* I2C channel number: 0 - main, 1 - SDC SPD */
-               uchar chip_addr,/* I2C device address on the bus */
-               uint byte_addr, /* Byte address within I2C device */
-               uchar * buffer  /* pointer to data buffer */
-               )
-{
-       u32 temp;
-       u32 to_count = I2C_DELAY;
-       u32 op_status = TSI108_I2C_TIMEOUT_ERR;
-       u32 chan_offset = TSI108_I2C_OFFSET;
-
-       DPRINT (("I2C read_byte() %d 0x%02x 0x%02x\n",
-               i2c_chan, chip_addr, byte_addr));
-
-       if (0 != i2c_chan)
-               chan_offset = TSI108_I2C_SDRAM_OFFSET;
-
-       /* Check if I2C operation is in progress */
-       temp = *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + I2C_CNTRL2);
-
-       if (0 == (temp & (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_WR_STATUS |
-                         I2C_CNTRL2_START))) {
-               /* Set device address and operation (read = 0) */
-               temp = (byte_addr << 16) | ((chip_addr & 0x07) << 8) |
-                   ((chip_addr >> 3) & 0x0F);
-               *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + I2C_CNTRL1) =
-                   temp;
-
-               /* Issue the read command
-                * (at this moment all other parameters are 0
-                * (size = 1 byte, lane = 0)
-                */
-
-               *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + I2C_CNTRL2) =
-                   (I2C_CNTRL2_START);
-
-               /* Wait until operation completed */
-               do {
-                       /* Read I2C operation status */
-                       temp = *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + I2C_CNTRL2);
-
-                       if (0 == (temp & (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_START))) {
-                               if (0 == (temp &
-                                    (I2C_CNTRL2_I2C_CFGERR |
-                                     I2C_CNTRL2_I2C_TO_ERR))
-                                   ) {
-                                       op_status = TSI108_I2C_SUCCESS;
-
-                                       temp = *(u32 *) (CFG_TSI108_CSR_BASE +
-                                                        chan_offset +
-                                                        I2C_RD_DATA);
-
-                                       *buffer = (u8) (temp & 0xFF);
-                               } else {
-                                       /* report HW error */
-                                       op_status = TSI108_I2C_IF_ERROR;
-
-                                       DPRINT (("I2C HW error reported: 0x%02x\n", temp));
-                               }
-
-                               break;
-                       }
-               } while (to_count--);
-       } else {
-               op_status = TSI108_I2C_IF_BUSY;
-
-               DPRINT (("I2C Transaction start failed: 0x%02x\n", temp));
-       }
-
-       DPRINT (("I2C read_byte() status: 0x%02x\n", op_status));
-       return op_status;
-}
-
-/*
- * I2C Read interface as defined in "include/i2c.h" :
- *   chip_addr: I2C chip address, range 0..127
- *                  (to read from SPD channel EEPROM use (0xD0 ... 0xD7)
- *              NOTE: The bit 7 in the chip_addr serves as a channel select.
- *              This hack is for enabling "isdram" command on Tsi108 boards
- *              without changes to common code. Used for I2C reads only.
- *   byte_addr: Memory or register address within the chip
- *   alen:      Number of bytes to use for addr (typically 1, 2 for larger
- *              memories, 0 for register type devices with only one
- *              register)
- *   buffer:    Pointer to destination buffer for data to be read
- *   len:       How many bytes to read
- *
- *   Returns: 0 on success, not 0 on failure
- */
-
-int i2c_read (uchar chip_addr, uint byte_addr, int alen,
-               uchar * buffer, int len)
-{
-       u32 op_status = TSI108_I2C_PARAM_ERR;
-       u32 i2c_if = 0;
-
-       /* Hack to support second (SPD) I2C controller (SPD EEPROM read only).*/
-       if (0xD0 == (chip_addr & ~0x07)) {
-               i2c_if = 1;
-               chip_addr &= 0x7F;
-       }
-       /* Check for valid I2C address */
-       if (chip_addr <= 0x7F && (byte_addr + len) <= (0x01 << (alen * 8))) {
-               while (len--) {
-                       op_status = i2c_read_byte(i2c_if, chip_addr, byte_addr++, buffer++);
-
-                       if (TSI108_I2C_SUCCESS != op_status) {
-                               DPRINT (("I2C read_byte() failed: 0x%02x (%d left)\n", op_status, len));
-
-                               break;
-                       }
-               }
-       }
-
-       DPRINT (("I2C read() status: 0x%02x\n", op_status));
-       return op_status;
-}
-
-/* I2C write helper function */
-
-static int i2c_write_byte (uchar chip_addr,/* I2C device address on the bus */
-                         uint byte_addr, /* Byte address within I2C device */
-                         uchar * buffer  /*  pointer to data buffer */
-                         )
-{
-       u32 temp;
-       u32 to_count = I2C_DELAY;
-       u32 op_status = TSI108_I2C_TIMEOUT_ERR;
-
-       /* Check if I2C operation is in progress */
-       temp = *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET + I2C_CNTRL2);
-
-       if (0 == (temp & (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_WR_STATUS | I2C_CNTRL2_START))) {
-               /* Place data into the I2C Tx Register */
-               *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET +
-                         I2C_TX_DATA) = (u32) * buffer;
-
-               /* Set device address and operation  */
-               temp =
-                   I2C_CNTRL1_I2CWRITE | (byte_addr << 16) |
-                   ((chip_addr & 0x07) << 8) | ((chip_addr >> 3) & 0x0F);
-               *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET +
-                         I2C_CNTRL1) = temp;
-
-               /* Issue the write command (at this moment all other parameters
-                * are 0 (size = 1 byte, lane = 0)
-                */
-
-               *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET +
-                         I2C_CNTRL2) = (I2C_CNTRL2_START);
-
-               op_status = TSI108_I2C_TIMEOUT_ERR;
-
-               /* Wait until operation completed */
-               do {
-                       /* Read I2C operation status */
-                       temp = *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET + I2C_CNTRL2);
-
-                       if (0 == (temp & (I2C_CNTRL2_WR_STATUS | I2C_CNTRL2_START))) {
-                               if (0 == (temp &
-                                    (I2C_CNTRL2_I2C_CFGERR |
-                                     I2C_CNTRL2_I2C_TO_ERR))) {
-                                       op_status = TSI108_I2C_SUCCESS;
-                               } else {
-                                       /* report detected HW error */
-                                       op_status = TSI108_I2C_IF_ERROR;
-
-                                       DPRINT (("I2C HW error reported: 0x%02x\n", temp));
-                               }
-
-                               break;
-                       }
-
-               } while (to_count--);
-       } else {
-               op_status = TSI108_I2C_IF_BUSY;
-
-               DPRINT (("I2C Transaction start failed: 0x%02x\n", temp));
-       }
-
-       return op_status;
-}
-
-/*
- * I2C Write interface as defined in "include/i2c.h" :
- *   chip_addr: I2C chip address, range 0..127
- *   byte_addr: Memory or register address within the chip
- *   alen:      Number of bytes to use for addr (typically 1, 2 for larger
- *              memories, 0 for register type devices with only one
- *              register)
- *   buffer:    Pointer to data to be written
- *   len:       How many bytes to write
- *
- *   Returns: 0 on success, not 0 on failure
- */
-
-int i2c_write (uchar chip_addr, uint byte_addr, int alen, uchar * buffer,
-             int len)
-{
-       u32 op_status = TSI108_I2C_PARAM_ERR;
-
-       /* Check for valid I2C address */
-       if (chip_addr <= 0x7F && (byte_addr + len) <= (0x01 << (alen * 8))) {
-               while (len--) {
-                       op_status =
-                           i2c_write_byte (chip_addr, byte_addr++, buffer++);
-
-                       if (TSI108_I2C_SUCCESS != op_status) {
-                               DPRINT (("I2C write_byte() failed: 0x%02x (%d left)\n", op_status, len));
-
-                               break;
-                       }
-               }
-       }
-
-       return op_status;
-}
-
-/*
- * I2C interface function as defined in "include/i2c.h".
- * Probe the given I2C chip address by reading single byte from offset 0.
- * Returns 0 if a chip responded, not 0 on failure.
- */
-
-int i2c_probe (uchar chip)
-{
-       u32 tmp;
-
-       /*
-        * Try to read the first location of the chip.
-        * The Tsi108 HW doesn't support sending just the chip address
-        * and checkong for an <ACK> back.
-        */
-       return i2c_read (chip, 0, 1, (char *)&tmp, 1);
-}
-
-#endif
-#endif /* CONFIG_TSI108_I2C */
diff --git a/drivers/tsi108_pci.c b/drivers/tsi108_pci.c
deleted file mode 100644 (file)
index 9f606df..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * (C) Copyright 2004 Tundra Semiconductor Corp.
- * Alex Bounine <alexandreb@tundra.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * PCI initialisation for the Tsi108 EMU board.
- */
-
-#include <config.h>
-
-#ifdef CONFIG_TSI108_PCI
-
-#include <common.h>
-#include <pci.h>
-#include <asm/io.h>
-#include <tsi108.h>
-
-struct pci_controller local_hose;
-
-void tsi108_clear_pci_error (void)
-{
-       u32 err_stat, err_addr, pci_stat;
-
-       /*
-        * Quietly clear errors signalled as result of PCI/X configuration read
-        * requests.
-        */
-       /* Read PB Error Log Registers */
-       err_stat = *(volatile u32 *)(CFG_TSI108_CSR_BASE +
-                                    TSI108_PB_REG_OFFSET + PB_ERRCS);
-       err_addr = *(volatile u32 *)(CFG_TSI108_CSR_BASE +
-                                    TSI108_PB_REG_OFFSET + PB_AERR);
-       if (err_stat & PB_ERRCS_ES) {
-               /* Clear PCI/X bus errors if applicable */
-               if ((err_addr & 0xFF000000) == CFG_PCI_CFG_BASE) {
-                       /* Clear error flag */
-                       *(u32 *) (CFG_TSI108_CSR_BASE +
-                                 TSI108_PB_REG_OFFSET + PB_ERRCS) =
-                           PB_ERRCS_ES;
-
-                       /* Clear read error reported in PB_ISR */
-                       *(u32 *) (CFG_TSI108_CSR_BASE +
-                                 TSI108_PB_REG_OFFSET + PB_ISR) =
-                           PB_ISR_PBS_RD_ERR;
-
-               /* Clear errors reported by PCI CSR (Normally Master Abort) */
-                       pci_stat = *(volatile u32 *)(CFG_TSI108_CSR_BASE +
-                                                    TSI108_PCI_REG_OFFSET +
-                                                    PCI_CSR);
-                       *(volatile u32 *)(CFG_TSI108_CSR_BASE +
-                                         TSI108_PCI_REG_OFFSET + PCI_CSR) =
-                           pci_stat;
-
-                       *(volatile u32 *)(CFG_TSI108_CSR_BASE +
-                                         TSI108_PCI_REG_OFFSET +
-                                         PCI_IRP_STAT) = PCI_IRP_STAT_P_CSR;
-               }
-       }
-
-       return;
-}
-
-unsigned int __get_pci_config_dword (u32 addr)
-{
-       unsigned int retval;
-
-       __asm__ __volatile__ ("       lwbrx %0,0,%1\n"
-                            "1:     eieio\n"
-                            "2:\n"
-                            ".section .fixup,\"ax\"\n"
-                            "3:     li %0,-1\n"
-                            "       b 2b\n"
-                            ".section __ex_table,\"a\"\n"
-                            "       .align 2\n"
-                            "       .long 1b,3b\n"
-                            ".text":"=r"(retval):"r"(addr));
-
-       return (retval);
-}
-
-static int tsi108_read_config_dword (struct pci_controller *hose,
-                                   pci_dev_t dev, int offset, u32 * value)
-{
-       dev &= (CFG_PCI_CFG_SIZE - 1);
-       dev |= (CFG_PCI_CFG_BASE | (offset & 0xfc));
-       *value = __get_pci_config_dword(dev);
-       if (0xFFFFFFFF == *value)
-               tsi108_clear_pci_error ();
-       return 0;
-}
-
-static int tsi108_write_config_dword (struct pci_controller *hose,
-                                    pci_dev_t dev, int offset, u32 value)
-{
-       dev &= (CFG_PCI_CFG_SIZE - 1);
-       dev |= (CFG_PCI_CFG_BASE | (offset & 0xfc));
-
-       out_le32 ((volatile unsigned *)dev, value);
-
-       return 0;
-}
-
-void pci_init_board (void)
-{
-       struct pci_controller *hose = (struct pci_controller *)&local_hose;
-
-       hose->first_busno = 0;
-       hose->last_busno = 0xff;
-
-       pci_set_region (hose->regions + 0,
-                      CFG_PCI_MEMORY_BUS,
-                      CFG_PCI_MEMORY_PHYS,
-                      CFG_PCI_MEMORY_SIZE, PCI_REGION_MEM | PCI_REGION_MEMORY);
-
-       /* PCI memory space */
-       pci_set_region (hose->regions + 1,
-                      CFG_PCI_MEM_BUS,
-                      CFG_PCI_MEM_PHYS, CFG_PCI_MEM_SIZE, PCI_REGION_MEM);
-
-       /* PCI I/O space */
-       pci_set_region (hose->regions + 2,
-                      CFG_PCI_IO_BUS,
-                      CFG_PCI_IO_PHYS, CFG_PCI_IO_SIZE, PCI_REGION_IO);
-
-       hose->region_count = 3;
-
-       pci_set_ops (hose,
-                   pci_hose_read_config_byte_via_dword,
-                   pci_hose_read_config_word_via_dword,
-                   tsi108_read_config_dword,
-                   pci_hose_write_config_byte_via_dword,
-                   pci_hose_write_config_word_via_dword,
-                   tsi108_write_config_dword);
-
-       pci_register_hose (hose);
-
-       hose->last_busno = pci_hose_scan (hose);
-
-       debug ("Done PCI initialization\n");
-       return;
-}
-
-#ifdef CONFIG_OF_FLAT_TREE
-void
-ft_pci_setup (void *blob, bd_t *bd)
-{
-       u32 *p;
-       int len;
-
-       p = (u32 *)ft_get_prop (blob, "/" OF_TSI "/pci@1000/bus-range", &len);
-       if (p != NULL) {
-               p[0] = local_hose.first_busno;
-               p[1] = local_hose.last_busno;
-       }
-
-}
-#endif
-
-#endif /* CONFIG_TSI108_PCI */
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
new file mode 100644 (file)
index 0000000..f8ea167
--- /dev/null
@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libusb.a
+
+COBJS-y += isp116x-hcd.o
+COBJS-y += sl811_usb.o
+COBJS-y += usb_ohci.o
+COBJS-y += usbdcore.o
+COBJS-y += usbdcore_ep0.o
+COBJS-y += usbdcore_mpc8xx.o
+COBJS-y += usbdcore_omap1510.o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/usb/isp116x-hcd.c b/drivers/usb/isp116x-hcd.c
new file mode 100644 (file)
index 0000000..b21af10
--- /dev/null
@@ -0,0 +1,1445 @@
+/*
+ * ISP116x HCD (Host Controller Driver) for u-boot.
+ *
+ * Copyright (C) 2006-2007 Rodolfo Giometti <giometti@linux.it>
+ * Copyright (C) 2006-2007 Eurotech S.p.A. <info@eurotech.it>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Derived in part from the SL811 HCD driver "u-boot/drivers/sl811_usb.c"
+ * (original copyright message follows):
+ *
+ *    (C) Copyright 2004
+ *    Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ *    This code is based on linux driver for sl811hs chip, source at
+ *    drivers/usb/host/sl811.c:
+ *
+ *    SL811 Host Controller Interface driver for USB.
+ *
+ *    Copyright (c) 2003/06, Courage Co., Ltd.
+ *
+ *    Based on:
+ *         1.uhci.c by Linus Torvalds, Johannes Erdfelt, Randy Dunlap,
+ *           Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber,
+ *           Adam Richter, Gregory P. Smith;
+ *         2.Original SL811 driver (hc_sl811.o) by Pei Liu <pbl@cypress.com>
+ *         3.Rewrited as sl811.o by Yin Aihua <yinah:couragetech.com.cn>
+ *
+ *    [[GNU/GPL disclaimer]]
+ *
+ * and in part from AU1x00 OHCI HCD driver "u-boot/cpu/mips/au1x00_usb_ohci.c"
+ * (original copyright message follows):
+ *
+ *    URB OHCI HCD (Host Controller Driver) for USB on the AU1x00.
+ *
+ *    (C) Copyright 2003
+ *    Gary Jennejohn, DENX Software Engineering <gj@denx.de>
+ *
+ *    [[GNU/GPL disclaimer]]
+ *
+ *    Note: Part of this code has been derived from linux
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_USB_ISP116X_HCD
+#include <asm/io.h>
+#include <usb.h>
+#include <malloc.h>
+#include <linux/list.h>
+
+/*
+ * ISP116x chips require certain delays between accesses to its
+ * registers. The following timing options exist.
+ *
+ * 1. Configure your memory controller (the best)
+ * 2. Use ndelay (easiest, poorest). For that, enable the following macro.
+ *
+ * Value is in microseconds.
+ */
+#ifdef ISP116X_HCD_USE_UDELAY
+#define UDELAY         1
+#endif
+
+/*
+ * On some (slowly?) machines an extra delay after data packing into
+ * controller's FIFOs is required, * otherwise you may get the following
+ * error:
+ *
+ *   uboot> usb start
+ *   (Re)start USB...
+ *   USB:   scanning bus for devices... isp116x: isp116x_submit_job: CTL:TIMEOUT
+ *   isp116x: isp116x_submit_job: ****** FIFO not ready! ******
+ *
+ *         USB device not responding, giving up (status=4)
+ *         isp116x: isp116x_submit_job: ****** FIFO not empty! ******
+ *         isp116x: isp116x_submit_job: ****** FIFO not empty! ******
+ *         isp116x: isp116x_submit_job: ****** FIFO not empty! ******
+ *         3 USB Device(s) found
+ *                scanning bus for storage devices... 0 Storage Device(s) found
+ *
+ * Value is in milliseconds.
+ */
+#ifdef ISP116X_HCD_USE_EXTRA_DELAY
+#define EXTRA_DELAY    2
+#endif
+
+/*
+ * Enable the following defines if you wish enable debugging messages.
+ */
+#undef DEBUG                   /* enable debugging messages */
+#undef TRACE                   /* enable tracing code */
+#undef VERBOSE                 /* verbose debugging messages */
+
+#include "isp116x.h"
+
+#define DRIVER_VERSION "08 Jan 2007"
+static const char hcd_name[] = "isp116x-hcd";
+
+struct isp116x isp116x_dev;
+struct isp116x_platform_data isp116x_board;
+static int got_rhsc;           /* root hub status change */
+struct usb_device *devgone;    /* device which was disconnected */
+static int rh_devnum;          /* address of Root Hub endpoint */
+
+/* ------------------------------------------------------------------------- */
+
+#define ALIGN(x,a)     (((x)+(a)-1UL)&~((a)-1UL))
+#define min_t(type,x,y)        \
+       ({ type __x = (x); type __y = (y); __x < __y ? __x : __y; })
+
+/* ------------------------------------------------------------------------- */
+
+static int isp116x_reset(struct isp116x *isp116x);
+
+/* --- Debugging functions ------------------------------------------------- */
+
+#define isp116x_show_reg(d, r) {                               \
+       if ((r) < 0x20) {                                       \
+               DBG("%-12s[%02x]: %08x", #r,                    \
+                       r, isp116x_read_reg32(d, r));           \
+       } else {                                                \
+               DBG("%-12s[%02x]:     %04x", #r,                \
+                       r, isp116x_read_reg16(d, r));           \
+       }                                                       \
+}
+
+#define isp116x_show_regs(d) {                                 \
+       isp116x_show_reg(d, HCREVISION);                        \
+       isp116x_show_reg(d, HCCONTROL);                         \
+       isp116x_show_reg(d, HCCMDSTAT);                         \
+       isp116x_show_reg(d, HCINTSTAT);                         \
+       isp116x_show_reg(d, HCINTENB);                          \
+       isp116x_show_reg(d, HCFMINTVL);                         \
+       isp116x_show_reg(d, HCFMREM);                           \
+       isp116x_show_reg(d, HCFMNUM);                           \
+       isp116x_show_reg(d, HCLSTHRESH);                        \
+       isp116x_show_reg(d, HCRHDESCA);                         \
+       isp116x_show_reg(d, HCRHDESCB);                         \
+       isp116x_show_reg(d, HCRHSTATUS);                        \
+       isp116x_show_reg(d, HCRHPORT1);                         \
+       isp116x_show_reg(d, HCRHPORT2);                         \
+       isp116x_show_reg(d, HCHWCFG);                           \
+       isp116x_show_reg(d, HCDMACFG);                          \
+       isp116x_show_reg(d, HCXFERCTR);                         \
+       isp116x_show_reg(d, HCuPINT);                           \
+       isp116x_show_reg(d, HCuPINTENB);                        \
+       isp116x_show_reg(d, HCCHIPID);                          \
+       isp116x_show_reg(d, HCSCRATCH);                         \
+       isp116x_show_reg(d, HCITLBUFLEN);                       \
+       isp116x_show_reg(d, HCATLBUFLEN);                       \
+       isp116x_show_reg(d, HCBUFSTAT);                         \
+       isp116x_show_reg(d, HCRDITL0LEN);                       \
+       isp116x_show_reg(d, HCRDITL1LEN);                       \
+}
+
+#if defined(TRACE)
+
+static int isp116x_get_current_frame_number(struct usb_device *usb_dev)
+{
+       struct isp116x *isp116x = &isp116x_dev;
+
+       return isp116x_read_reg32(isp116x, HCFMNUM);
+}
+
+static void dump_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+                    int len, char *str)
+{
+#if defined(VERBOSE)
+       int i;
+#endif
+
+       DBG("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d stat:%#lx",
+           str,
+           isp116x_get_current_frame_number(dev),
+           usb_pipedevice(pipe),
+           usb_pipeendpoint(pipe),
+           usb_pipeout(pipe) ? 'O' : 'I',
+           usb_pipetype(pipe) < 2 ?
+           (usb_pipeint(pipe) ?
+            "INTR" : "ISOC") :
+           (usb_pipecontrol(pipe) ? "CTRL" : "BULK"), len, dev->status);
+#if defined(VERBOSE)
+       if (len > 0 && buffer) {
+               printf(__FILE__ ": data(%d):", len);
+               for (i = 0; i < 16 && i < len; i++)
+                       printf(" %02x", ((__u8 *) buffer)[i]);
+               printf("%s\n", i < len ? "..." : "");
+       }
+#endif
+}
+
+#define PTD_DIR_STR(ptd)  ({char __c;          \
+       switch(PTD_GET_DIR(ptd)){               \
+       case 0:  __c = 's'; break;              \
+       case 1:  __c = 'o'; break;              \
+       default: __c = 'i'; break;              \
+       }; __c;})
+
+/*
+  Dump PTD info. The code documents the format
+  perfectly, right :)
+*/
+static inline void dump_ptd(struct ptd *ptd)
+{
+#if defined(VERBOSE)
+       int k;
+#endif
+
+       DBG("PTD(ext) : cc:%x %d%c%d %d,%d,%d t:%x %x%x%x",
+           PTD_GET_CC(ptd),
+           PTD_GET_FA(ptd), PTD_DIR_STR(ptd), PTD_GET_EP(ptd),
+           PTD_GET_COUNT(ptd), PTD_GET_LEN(ptd), PTD_GET_MPS(ptd),
+           PTD_GET_TOGGLE(ptd),
+           PTD_GET_ACTIVE(ptd), PTD_GET_SPD(ptd), PTD_GET_LAST(ptd));
+#if defined(VERBOSE)
+       printf("isp116x: %s: PTD(byte): ", __FUNCTION__);
+       for (k = 0; k < sizeof(struct ptd); ++k)
+               printf("%02x ", ((u8 *) ptd)[k]);
+       printf("\n");
+#endif
+}
+
+static inline void dump_ptd_data(struct ptd *ptd, u8 * buf, int type)
+{
+#if defined(VERBOSE)
+       int k;
+
+       if (type == 0 /* 0ut data */ ) {
+               printf("isp116x: %s: out data: ", __FUNCTION__);
+               for (k = 0; k < PTD_GET_LEN(ptd); ++k)
+                       printf("%02x ", ((u8 *) buf)[k]);
+               printf("\n");
+       }
+       if (type == 1 /* 1n data */ ) {
+               printf("isp116x: %s: in data: ", __FUNCTION__);
+               for (k = 0; k < PTD_GET_COUNT(ptd); ++k)
+                       printf("%02x ", ((u8 *) buf)[k]);
+               printf("\n");
+       }
+
+       if (PTD_GET_LAST(ptd))
+               DBG("--- last PTD ---");
+#endif
+}
+
+#else
+
+#define dump_msg(dev, pipe, buffer, len, str)                  do { } while (0)
+#define dump_pkt(dev, pipe, buffer, len, setup, str, small)    do {} while (0)
+
+#define dump_ptd(ptd)                  do {} while (0)
+#define dump_ptd_data(ptd, buf, type)  do {} while (0)
+
+#endif
+
+/* --- Virtual Root Hub ---------------------------------------------------- */
+
+/* Device descriptor */
+static __u8 root_hub_dev_des[] = {
+       0x12,                   /*  __u8  bLength; */
+       0x01,                   /*  __u8  bDescriptorType; Device */
+       0x10,                   /*  __u16 bcdUSB; v1.1 */
+       0x01,
+       0x09,                   /*  __u8  bDeviceClass; HUB_CLASSCODE */
+       0x00,                   /*  __u8  bDeviceSubClass; */
+       0x00,                   /*  __u8  bDeviceProtocol; */
+       0x08,                   /*  __u8  bMaxPacketSize0; 8 Bytes */
+       0x00,                   /*  __u16 idVendor; */
+       0x00,
+       0x00,                   /*  __u16 idProduct; */
+       0x00,
+       0x00,                   /*  __u16 bcdDevice; */
+       0x00,
+       0x00,                   /*  __u8  iManufacturer; */
+       0x01,                   /*  __u8  iProduct; */
+       0x00,                   /*  __u8  iSerialNumber; */
+       0x01                    /*  __u8  bNumConfigurations; */
+};
+
+/* Configuration descriptor */
+static __u8 root_hub_config_des[] = {
+       0x09,                   /*  __u8  bLength; */
+       0x02,                   /*  __u8  bDescriptorType; Configuration */
+       0x19,                   /*  __u16 wTotalLength; */
+       0x00,
+       0x01,                   /*  __u8  bNumInterfaces; */
+       0x01,                   /*  __u8  bConfigurationValue; */
+       0x00,                   /*  __u8  iConfiguration; */
+       0x40,                   /*  __u8  bmAttributes;
+                                  Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
+       0x00,                   /*  __u8  MaxPower; */
+
+       /* interface */
+       0x09,                   /*  __u8  if_bLength; */
+       0x04,                   /*  __u8  if_bDescriptorType; Interface */
+       0x00,                   /*  __u8  if_bInterfaceNumber; */
+       0x00,                   /*  __u8  if_bAlternateSetting; */
+       0x01,                   /*  __u8  if_bNumEndpoints; */
+       0x09,                   /*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
+       0x00,                   /*  __u8  if_bInterfaceSubClass; */
+       0x00,                   /*  __u8  if_bInterfaceProtocol; */
+       0x00,                   /*  __u8  if_iInterface; */
+
+       /* endpoint */
+       0x07,                   /*  __u8  ep_bLength; */
+       0x05,                   /*  __u8  ep_bDescriptorType; Endpoint */
+       0x81,                   /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
+       0x03,                   /*  __u8  ep_bmAttributes; Interrupt */
+       0x00,                   /*  __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
+       0x02,
+       0xff                    /*  __u8  ep_bInterval; 255 ms */
+};
+
+static unsigned char root_hub_str_index0[] = {
+       0x04,                   /*  __u8  bLength; */
+       0x03,                   /*  __u8  bDescriptorType; String-descriptor */
+       0x09,                   /*  __u8  lang ID */
+       0x04,                   /*  __u8  lang ID */
+};
+
+static unsigned char root_hub_str_index1[] = {
+       0x22,                   /*  __u8  bLength; */
+       0x03,                   /*  __u8  bDescriptorType; String-descriptor */
+       'I',                    /*  __u8  Unicode */
+       0,                      /*  __u8  Unicode */
+       'S',                    /*  __u8  Unicode */
+       0,                      /*  __u8  Unicode */
+       'P',                    /*  __u8  Unicode */
+       0,                      /*  __u8  Unicode */
+       '1',                    /*  __u8  Unicode */
+       0,                      /*  __u8  Unicode */
+       '1',                    /*  __u8  Unicode */
+       0,                      /*  __u8  Unicode */
+       '6',                    /*  __u8  Unicode */
+       0,                      /*  __u8  Unicode */
+       'x',                    /*  __u8  Unicode */
+       0,                      /*  __u8  Unicode */
+       ' ',                    /*  __u8  Unicode */
+       0,                      /*  __u8  Unicode */
+       'R',                    /*  __u8  Unicode */
+       0,                      /*  __u8  Unicode */
+       'o',                    /*  __u8  Unicode */
+       0,                      /*  __u8  Unicode */
+       'o',                    /*  __u8  Unicode */
+       0,                      /*  __u8  Unicode */
+       't',                    /*  __u8  Unicode */
+       0,                      /*  __u8  Unicode */
+       ' ',                    /*  __u8  Unicode */
+       0,                      /*  __u8  Unicode */
+       'H',                    /*  __u8  Unicode */
+       0,                      /*  __u8  Unicode */
+       'u',                    /*  __u8  Unicode */
+       0,                      /*  __u8  Unicode */
+       'b',                    /*  __u8  Unicode */
+       0,                      /*  __u8  Unicode */
+};
+
+/*
+ * Hub class-specific descriptor is constructed dynamically
+ */
+
+/* --- Virtual root hub management functions ------------------------------- */
+
+static int rh_check_port_status(struct isp116x *isp116x)
+{
+       u32 temp, ndp, i;
+       int res;
+
+       res = -1;
+       temp = isp116x_read_reg32(isp116x, HCRHSTATUS);
+       ndp = (temp & RH_A_NDP);
+       for (i = 0; i < ndp; i++) {
+               temp = isp116x_read_reg32(isp116x, HCRHPORT1 + i);
+               /* check for a device disconnect */
+               if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
+                    (RH_PS_PESC | RH_PS_CSC)) && ((temp & RH_PS_CCS) == 0)) {
+                       res = i;
+                       break;
+               }
+       }
+       return res;
+}
+
+/* --- HC management functions --------------------------------------------- */
+
+/* Write len bytes to fifo, pad till 32-bit boundary
+ */
+static void write_ptddata_to_fifo(struct isp116x *isp116x, void *buf, int len)
+{
+       u8 *dp = (u8 *) buf;
+       u16 *dp2 = (u16 *) buf;
+       u16 w;
+       int quot = len % 4;
+
+       if ((unsigned long)dp2 & 1) {
+               /* not aligned */
+               for (; len > 1; len -= 2) {
+                       w = *dp++;
+                       w |= *dp++ << 8;
+                       isp116x_raw_write_data16(isp116x, w);
+               }
+               if (len)
+                       isp116x_write_data16(isp116x, (u16) * dp);
+       } else {
+               /* aligned */
+               for (; len > 1; len -= 2)
+                       isp116x_raw_write_data16(isp116x, *dp2++);
+               if (len)
+                       isp116x_write_data16(isp116x, 0xff & *((u8 *) dp2));
+       }
+       if (quot == 1 || quot == 2)
+               isp116x_raw_write_data16(isp116x, 0);
+}
+
+/* Read len bytes from fifo and then read till 32-bit boundary
+ */
+static void read_ptddata_from_fifo(struct isp116x *isp116x, void *buf, int len)
+{
+       u8 *dp = (u8 *) buf;
+       u16 *dp2 = (u16 *) buf;
+       u16 w;
+       int quot = len % 4;
+
+       if ((unsigned long)dp2 & 1) {
+               /* not aligned */
+               for (; len > 1; len -= 2) {
+                       w = isp116x_raw_read_data16(isp116x);
+                       *dp++ = w & 0xff;
+                       *dp++ = (w >> 8) & 0xff;
+               }
+               if (len)
+                       *dp = 0xff & isp116x_read_data16(isp116x);
+       } else {
+               /* aligned */
+               for (; len > 1; len -= 2)
+                       *dp2++ = isp116x_raw_read_data16(isp116x);
+               if (len)
+                       *(u8 *) dp2 = 0xff & isp116x_read_data16(isp116x);
+       }
+       if (quot == 1 || quot == 2)
+               isp116x_raw_read_data16(isp116x);
+}
+
+/* Write PTD's and data for scheduled transfers into the fifo ram.
+ * Fifo must be empty and ready */
+static void pack_fifo(struct isp116x *isp116x, struct usb_device *dev,
+                     unsigned long pipe, struct ptd *ptd, int n, void *data,
+                     int len)
+{
+       int buflen = n * sizeof(struct ptd) + len;
+       int i, done;
+
+       DBG("--- pack buffer %p - %d bytes (fifo %d) ---", data, len, buflen);
+
+       isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
+       isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
+       isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET);
+
+       done = 0;
+       for (i = 0; i < n; i++) {
+               DBG("i=%d - done=%d - len=%d", i, done, PTD_GET_LEN(&ptd[i]));
+
+               dump_ptd(&ptd[i]);
+               isp116x_write_data16(isp116x, ptd[i].count);
+               isp116x_write_data16(isp116x, ptd[i].mps);
+               isp116x_write_data16(isp116x, ptd[i].len);
+               isp116x_write_data16(isp116x, ptd[i].faddr);
+
+               dump_ptd_data(&ptd[i], (__u8 *) data + done, 0);
+               write_ptddata_to_fifo(isp116x,
+                                     (__u8 *) data + done,
+                                     PTD_GET_LEN(&ptd[i]));
+
+               done += PTD_GET_LEN(&ptd[i]);
+       }
+}
+
+/* Read the processed PTD's and data from fifo ram back to URBs' buffers.
+ * Fifo must be full and done */
+static int unpack_fifo(struct isp116x *isp116x, struct usb_device *dev,
+                      unsigned long pipe, struct ptd *ptd, int n, void *data,
+                      int len)
+{
+       int buflen = n * sizeof(struct ptd) + len;
+       int i, done, cc, ret;
+
+       isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
+       isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
+       isp116x_write_addr(isp116x, HCATLPORT);
+
+       ret = TD_CC_NOERROR;
+       done = 0;
+       for (i = 0; i < n; i++) {
+               DBG("i=%d - done=%d - len=%d", i, done, PTD_GET_LEN(&ptd[i]));
+
+               ptd[i].count = isp116x_read_data16(isp116x);
+               ptd[i].mps = isp116x_read_data16(isp116x);
+               ptd[i].len = isp116x_read_data16(isp116x);
+               ptd[i].faddr = isp116x_read_data16(isp116x);
+               dump_ptd(&ptd[i]);
+
+               read_ptddata_from_fifo(isp116x,
+                                      (__u8 *) data + done,
+                                      PTD_GET_LEN(&ptd[i]));
+               dump_ptd_data(&ptd[i], (__u8 *) data + done, 1);
+
+               done += PTD_GET_LEN(&ptd[i]);
+
+               cc = PTD_GET_CC(&ptd[i]);
+
+               /* Data underrun means basically that we had more buffer space than
+                * the function had data. It is perfectly normal but upper levels have
+                * to know how much we actually transferred.
+                */
+               if (cc == TD_NOTACCESSED ||
+                               (cc != TD_CC_NOERROR && (ret == TD_CC_NOERROR || ret == TD_DATAUNDERRUN)))
+                       ret = cc;
+       }
+
+       DBG("--- unpack buffer %p - %d bytes (fifo %d) ---", data, len, buflen);
+
+       return ret;
+}
+
+/* Interrupt handling
+ */
+static int isp116x_interrupt(struct isp116x *isp116x)
+{
+       u16 irqstat;
+       u32 intstat;
+       int ret = 0;
+
+       isp116x_write_reg16(isp116x, HCuPINTENB, 0);
+       irqstat = isp116x_read_reg16(isp116x, HCuPINT);
+       isp116x_write_reg16(isp116x, HCuPINT, irqstat);
+       DBG(">>>>>> irqstat %x <<<<<<", irqstat);
+
+       if (irqstat & HCuPINT_ATL) {
+               DBG(">>>>>> HCuPINT_ATL <<<<<<");
+               udelay(500);
+               ret = 1;
+       }
+
+       if (irqstat & HCuPINT_OPR) {
+               intstat = isp116x_read_reg32(isp116x, HCINTSTAT);
+               isp116x_write_reg32(isp116x, HCINTSTAT, intstat);
+               DBG(">>>>>> HCuPINT_OPR %x <<<<<<", intstat);
+
+               if (intstat & HCINT_UE) {
+                       ERR("unrecoverable error, controller disabled");
+
+                       /* FIXME: be optimistic, hope that bug won't repeat
+                        * often. Make some non-interrupt context restart the
+                        * controller. Count and limit the retries though;
+                        * either hardware or software errors can go forever...
+                        */
+                       isp116x_reset(isp116x);
+                       ret = -1;
+                       return -1;
+               }
+
+               if (intstat & HCINT_RHSC) {
+                       got_rhsc = 1;
+                       ret = 1;
+                       /* When root hub or any of its ports is going
+                          to come out of suspend, it may take more
+                          than 10ms for status bits to stabilize. */
+                       wait_ms(20);
+               }
+
+               if (intstat & HCINT_SO) {
+                       ERR("schedule overrun");
+                       ret = -1;
+               }
+
+               irqstat &= ~HCuPINT_OPR;
+       }
+
+       return ret;
+}
+
+/* With one PTD we can transfer almost 1K in one go;
+ * HC does the splitting into endpoint digestible transactions
+ */
+struct ptd ptd[1];
+
+static inline int max_transfer_len(struct usb_device *dev, unsigned long pipe)
+{
+       unsigned mpck = usb_maxpacket(dev, pipe);
+
+       /* One PTD can transfer 1023 bytes but try to always
+        * transfer multiples of endpoint buffer size
+        */
+       return 1023 / mpck * mpck;
+}
+
+/* Do an USB transfer
+ */
+static int isp116x_submit_job(struct usb_device *dev, unsigned long pipe,
+                             int dir, void *buffer, int len)
+{
+       struct isp116x *isp116x = &isp116x_dev;
+       int type = usb_pipetype(pipe);
+       int epnum = usb_pipeendpoint(pipe);
+       int max = usb_maxpacket(dev, pipe);
+       int dir_out = usb_pipeout(pipe);
+       int speed_low = usb_pipeslow(pipe);
+       int i, done = 0, stat, timeout, cc;
+
+       /* 500 frames or 0.5s timeout when function is busy and NAKs transactions for a while */
+       int retries = 500;
+
+       DBG("------------------------------------------------");
+       dump_msg(dev, pipe, buffer, len, "SUBMIT");
+       DBG("------------------------------------------------");
+
+       if (len >= 1024) {
+               ERR("Too big job");
+               dev->status = USB_ST_CRC_ERR;
+               return -1;
+       }
+
+       if (isp116x->disabled) {
+               ERR("EPIPE");
+               dev->status = USB_ST_CRC_ERR;
+               return -1;
+       }
+
+       /* device pulled? Shortcut the action. */
+       if (devgone == dev) {
+               ERR("ENODEV");
+               dev->status = USB_ST_CRC_ERR;
+               return USB_ST_CRC_ERR;
+       }
+
+       if (!max) {
+               ERR("pipesize for pipe %lx is zero", pipe);
+               dev->status = USB_ST_CRC_ERR;
+               return -1;
+       }
+
+       if (type == PIPE_ISOCHRONOUS) {
+               ERR("isochronous transfers not supported");
+               dev->status = USB_ST_CRC_ERR;
+               return -1;
+       }
+
+       /* FIFO not empty? */
+       if (isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_FULL) {
+               ERR("****** FIFO not empty! ******");
+               dev->status = USB_ST_BUF_ERR;
+               return -1;
+       }
+
+      retry:
+       isp116x_write_reg32(isp116x, HCINTSTAT, 0xff);
+
+       /* Prepare the PTD data */
+       ptd->count = PTD_CC_MSK | PTD_ACTIVE_MSK |
+               PTD_TOGGLE(usb_gettoggle(dev, epnum, dir_out));
+       ptd->mps = PTD_MPS(max) | PTD_SPD(speed_low) | PTD_EP(epnum) | PTD_LAST_MSK;
+       ptd->len = PTD_LEN(len) | PTD_DIR(dir);
+       ptd->faddr = PTD_FA(usb_pipedevice(pipe));
+
+retry_same:
+       /* Pack data into FIFO ram */
+       pack_fifo(isp116x, dev, pipe, ptd, 1, buffer, len);
+#ifdef EXTRA_DELAY
+       wait_ms(EXTRA_DELAY);
+#endif
+
+       /* Start the data transfer */
+
+       /* Allow more time for a BULK device to react - some are slow */
+       if (usb_pipetype(pipe) == PIPE_BULK)
+               timeout = 5000;
+       else
+               timeout = 100;
+
+       /* Wait for it to complete */
+       for (;;) {
+               /* Check whether the controller is done */
+               stat = isp116x_interrupt(isp116x);
+
+               if (stat < 0) {
+                       dev->status = USB_ST_CRC_ERR;
+                       break;
+               }
+               if (stat > 0)
+                       break;
+
+               /* Check the timeout */
+               if (--timeout)
+                       udelay(1);
+               else {
+                       ERR("CTL:TIMEOUT ");
+                       stat = USB_ST_CRC_ERR;
+                       break;
+               }
+       }
+
+       /* We got an Root Hub Status Change interrupt */
+       if (got_rhsc) {
+               isp116x_show_regs(isp116x);
+
+               got_rhsc = 0;
+
+               /* Abuse timeout */
+               timeout = rh_check_port_status(isp116x);
+               if (timeout >= 0) {
+                       /*
+                        * FIXME! NOTE! AAAARGH!
+                        * This is potentially dangerous because it assumes
+                        * that only one device is ever plugged in!
+                        */
+                       devgone = dev;
+               }
+       }
+
+       /* Ok, now we can read transfer status */
+
+       /* FIFO not ready? */
+       if (!(isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_DONE)) {
+               ERR("****** FIFO not ready! ******");
+               dev->status = USB_ST_BUF_ERR;
+               return -1;
+       }
+
+       /* Unpack data from FIFO ram */
+       cc = unpack_fifo(isp116x, dev, pipe, ptd, 1, buffer, len);
+
+       i = PTD_GET_COUNT(ptd);
+       done += i;
+       buffer += i;
+       len -= i;
+
+       /* There was some kind of real problem; Prepare the PTD again
+        * and retry from the failed transaction on
+        */
+       if (cc && cc != TD_NOTACCESSED && cc != TD_DATAUNDERRUN) {
+               if (retries >= 100) {
+                       retries -= 100;
+                       /* The chip will have toggled the toggle bit for the failed
+                        * transaction too. We have to toggle it back.
+                        */
+                       usb_settoggle(dev, epnum, dir_out, !PTD_GET_TOGGLE(ptd));
+                       goto retry;
+               }
+       }
+       /* "Normal" errors; TD_NOTACCESSED would mean in effect that the function have NAKed
+        * the transactions from the first on for the whole frame. It may be busy and we retry
+        * with the same PTD. PTD_ACTIVE (and not TD_NOTACCESSED) would mean that some of the
+        * PTD didn't make it because the function was busy or the frame ended before the PTD
+        * finished. We prepare the rest of the data and try again.
+        */
+       else if (cc == TD_NOTACCESSED || PTD_GET_ACTIVE(ptd) || (cc != TD_DATAUNDERRUN && PTD_GET_COUNT(ptd) < PTD_GET_LEN(ptd))) {
+               if (retries) {
+                       --retries;
+                       if (cc == TD_NOTACCESSED && PTD_GET_ACTIVE(ptd) && !PTD_GET_COUNT(ptd)) goto retry_same;
+                       usb_settoggle(dev, epnum, dir_out, PTD_GET_TOGGLE(ptd));
+                       goto retry;
+               }
+       }
+
+       if (cc != TD_CC_NOERROR && cc != TD_DATAUNDERRUN) {
+               DBG("****** completition code error %x ******", cc);
+               switch (cc) {
+               case TD_CC_BITSTUFFING:
+                       dev->status = USB_ST_BIT_ERR;
+                       break;
+               case TD_CC_STALL:
+                       dev->status = USB_ST_STALLED;
+                       break;
+               case TD_BUFFEROVERRUN:
+               case TD_BUFFERUNDERRUN:
+                       dev->status = USB_ST_BUF_ERR;
+                       break;
+               default:
+                       dev->status = USB_ST_CRC_ERR;
+               }
+               return -cc;
+       }
+       else usb_settoggle(dev, epnum, dir_out, PTD_GET_TOGGLE(ptd));
+
+       dump_msg(dev, pipe, buffer, len, "SUBMIT(ret)");
+
+       dev->status = 0;
+       return done;
+}
+
+/* Adapted from au1x00_usb_ohci.c
+ */
+static int isp116x_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
+                                void *buffer, int transfer_len,
+                                struct devrequest *cmd)
+{
+       struct isp116x *isp116x = &isp116x_dev;
+       u32 tmp = 0;
+
+       int leni = transfer_len;
+       int len = 0;
+       int stat = 0;
+       u32 datab[4];
+       u8 *data_buf = (u8 *) datab;
+       u16 bmRType_bReq;
+       u16 wValue;
+       u16 wIndex;
+       u16 wLength;
+
+       if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
+               INFO("Root-Hub submit IRQ: NOT implemented");
+               return 0;
+       }
+
+       bmRType_bReq = cmd->requesttype | (cmd->request << 8);
+       wValue = swap_16(cmd->value);
+       wIndex = swap_16(cmd->index);
+       wLength = swap_16(cmd->length);
+
+       DBG("--- HUB ----------------------------------------");
+       DBG("submit rh urb, req=%x val=%#x index=%#x len=%d",
+           bmRType_bReq, wValue, wIndex, wLength);
+       dump_msg(dev, pipe, buffer, transfer_len, "RH");
+       DBG("------------------------------------------------");
+
+       switch (bmRType_bReq) {
+       case RH_GET_STATUS:
+               DBG("RH_GET_STATUS");
+
+               *(__u16 *) data_buf = swap_16(1);
+               len = 2;
+               break;
+
+       case RH_GET_STATUS | RH_INTERFACE:
+               DBG("RH_GET_STATUS | RH_INTERFACE");
+
+               *(__u16 *) data_buf = swap_16(0);
+               len = 2;
+               break;
+
+       case RH_GET_STATUS | RH_ENDPOINT:
+               DBG("RH_GET_STATUS | RH_ENDPOINT");
+
+               *(__u16 *) data_buf = swap_16(0);
+               len = 2;
+               break;
+
+       case RH_GET_STATUS | RH_CLASS:
+               DBG("RH_GET_STATUS | RH_CLASS");
+
+               tmp = isp116x_read_reg32(isp116x, HCRHSTATUS);
+
+               *(__u32 *) data_buf = swap_32(tmp & ~(RH_HS_CRWE | RH_HS_DRWE));
+               len = 4;
+               break;
+
+       case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+               DBG("RH_GET_STATUS | RH_OTHER | RH_CLASS");
+
+               tmp = isp116x_read_reg32(isp116x, HCRHPORT1 + wIndex - 1);
+               *(__u32 *) data_buf = swap_32(tmp);
+               isp116x_show_regs(isp116x);
+               len = 4;
+               break;
+
+       case RH_CLEAR_FEATURE | RH_ENDPOINT:
+               DBG("RH_CLEAR_FEATURE | RH_ENDPOINT");
+
+               switch (wValue) {
+               case RH_ENDPOINT_STALL:
+                       DBG("C_HUB_ENDPOINT_STALL");
+                       len = 0;
+                       break;
+               }
+               break;
+
+       case RH_CLEAR_FEATURE | RH_CLASS:
+               DBG("RH_CLEAR_FEATURE | RH_CLASS");
+
+               switch (wValue) {
+               case RH_C_HUB_LOCAL_POWER:
+                       DBG("C_HUB_LOCAL_POWER");
+                       len = 0;
+                       break;
+
+               case RH_C_HUB_OVER_CURRENT:
+                       DBG("C_HUB_OVER_CURRENT");
+                       isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_OCIC);
+                       len = 0;
+                       break;
+               }
+               break;
+
+       case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+               DBG("RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS");
+
+               switch (wValue) {
+               case RH_PORT_ENABLE:
+                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+                                           RH_PS_CCS);
+                       len = 0;
+                       break;
+
+               case RH_PORT_SUSPEND:
+                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+                                           RH_PS_POCI);
+                       len = 0;
+                       break;
+
+               case RH_PORT_POWER:
+                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+                                           RH_PS_LSDA);
+                       len = 0;
+                       break;
+
+               case RH_C_PORT_CONNECTION:
+                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+                                           RH_PS_CSC);
+                       len = 0;
+                       break;
+
+               case RH_C_PORT_ENABLE:
+                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+                                           RH_PS_PESC);
+                       len = 0;
+                       break;
+
+               case RH_C_PORT_SUSPEND:
+                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+                                           RH_PS_PSSC);
+                       len = 0;
+                       break;
+
+               case RH_C_PORT_OVER_CURRENT:
+                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+                                           RH_PS_POCI);
+                       len = 0;
+                       break;
+
+               case RH_C_PORT_RESET:
+                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+                                           RH_PS_PRSC);
+                       len = 0;
+                       break;
+
+               default:
+                       ERR("invalid wValue");
+                       stat = USB_ST_STALLED;
+               }
+
+               isp116x_show_regs(isp116x);
+
+               break;
+
+       case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+               DBG("RH_SET_FEATURE | RH_OTHER | RH_CLASS");
+
+               switch (wValue) {
+               case RH_PORT_SUSPEND:
+                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+                                           RH_PS_PSS);
+                       len = 0;
+                       break;
+
+               case RH_PORT_RESET:
+                       /* Spin until any current reset finishes */
+                       while (1) {
+                               tmp =
+                                   isp116x_read_reg32(isp116x,
+                                                      HCRHPORT1 + wIndex - 1);
+                               if (!(tmp & RH_PS_PRS))
+                                       break;
+                               wait_ms(1);
+                       }
+                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+                                           RH_PS_PRS);
+                       wait_ms(10);
+
+                       len = 0;
+                       break;
+
+               case RH_PORT_POWER:
+                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+                                           RH_PS_PPS);
+                       len = 0;
+                       break;
+
+               case RH_PORT_ENABLE:
+                       isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
+                                           RH_PS_PES);
+                       len = 0;
+                       break;
+
+               default:
+                       ERR("invalid wValue");
+                       stat = USB_ST_STALLED;
+               }
+
+               isp116x_show_regs(isp116x);
+
+               break;
+
+       case RH_SET_ADDRESS:
+               DBG("RH_SET_ADDRESS");
+
+               rh_devnum = wValue;
+               len = 0;
+               break;
+
+       case RH_GET_DESCRIPTOR:
+               DBG("RH_GET_DESCRIPTOR: %x, %d", wValue, wLength);
+
+               switch (wValue) {
+               case (USB_DT_DEVICE << 8):      /* device descriptor */
+                       len = min_t(unsigned int,
+                                   leni, min_t(unsigned int,
+                                               sizeof(root_hub_dev_des),
+                                               wLength));
+                       data_buf = root_hub_dev_des;
+                       break;
+
+               case (USB_DT_CONFIG << 8):      /* configuration descriptor */
+                       len = min_t(unsigned int,
+                                   leni, min_t(unsigned int,
+                                               sizeof(root_hub_config_des),
+                                               wLength));
+                       data_buf = root_hub_config_des;
+                       break;
+
+               case ((USB_DT_STRING << 8) | 0x00):     /* string 0 descriptors */
+                       len = min_t(unsigned int,
+                                   leni, min_t(unsigned int,
+                                               sizeof(root_hub_str_index0),
+                                               wLength));
+                       data_buf = root_hub_str_index0;
+                       break;
+
+               case ((USB_DT_STRING << 8) | 0x01):     /* string 1 descriptors */
+                       len = min_t(unsigned int,
+                                   leni, min_t(unsigned int,
+                                               sizeof(root_hub_str_index1),
+                                               wLength));
+                       data_buf = root_hub_str_index1;
+                       break;
+
+               default:
+                       ERR("invalid wValue");
+                       stat = USB_ST_STALLED;
+               }
+
+               break;
+
+       case RH_GET_DESCRIPTOR | RH_CLASS:
+               DBG("RH_GET_DESCRIPTOR | RH_CLASS");
+
+               tmp = isp116x_read_reg32(isp116x, HCRHDESCA);
+
+               data_buf[0] = 0x09;     /* min length; */
+               data_buf[1] = 0x29;
+               data_buf[2] = tmp & RH_A_NDP;
+               data_buf[3] = 0;
+               if (tmp & RH_A_PSM)     /* per-port power switching? */
+                       data_buf[3] |= 0x01;
+               if (tmp & RH_A_NOCP)    /* no overcurrent reporting? */
+                       data_buf[3] |= 0x10;
+               else if (tmp & RH_A_OCPM)       /* per-port overcurrent rep? */
+                       data_buf[3] |= 0x08;
+
+               /* Corresponds to data_buf[4-7] */
+               datab[1] = 0;
+               data_buf[5] = (tmp & RH_A_POTPGT) >> 24;
+
+               tmp = isp116x_read_reg32(isp116x, HCRHDESCB);
+
+               data_buf[7] = tmp & RH_B_DR;
+               if (data_buf[2] < 7)
+                       data_buf[8] = 0xff;
+               else {
+                       data_buf[0] += 2;
+                       data_buf[8] = (tmp & RH_B_DR) >> 8;
+                       data_buf[10] = data_buf[9] = 0xff;
+               }
+
+               len = min_t(unsigned int, leni,
+                           min_t(unsigned int, data_buf[0], wLength));
+               break;
+
+       case RH_GET_CONFIGURATION:
+               DBG("RH_GET_CONFIGURATION");
+
+               *(__u8 *) data_buf = 0x01;
+               len = 1;
+               break;
+
+       case RH_SET_CONFIGURATION:
+               DBG("RH_SET_CONFIGURATION");
+
+               isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPSC);
+               len = 0;
+               break;
+
+       default:
+               ERR("*** *** *** unsupported root hub command *** *** ***");
+               stat = USB_ST_STALLED;
+       }
+
+       len = min_t(int, len, leni);
+       if (buffer != data_buf)
+               memcpy(buffer, data_buf, len);
+
+       dev->act_len = len;
+       dev->status = stat;
+       DBG("dev act_len %d, status %d", dev->act_len, dev->status);
+
+       dump_msg(dev, pipe, buffer, transfer_len, "RH(ret)");
+
+       return stat;
+}
+
+/* --- Transfer functions -------------------------------------------------- */
+
+int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+                  int len, int interval)
+{
+       DBG("dev=%p pipe=%#lx buf=%p size=%d int=%d",
+           dev, pipe, buffer, len, interval);
+
+       return -1;
+}
+
+int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+                      int len, struct devrequest *setup)
+{
+       int devnum = usb_pipedevice(pipe);
+       int epnum = usb_pipeendpoint(pipe);
+       int max = max_transfer_len(dev, pipe);
+       int dir_in = usb_pipein(pipe);
+       int done, ret;
+
+       /* Control message is for the HUB? */
+       if (devnum == rh_devnum)
+               return isp116x_submit_rh_msg(dev, pipe, buffer, len, setup);
+
+       /* Ok, no HUB message so send the message to the device */
+
+       /* Setup phase */
+       DBG("--- SETUP PHASE --------------------------------");
+       usb_settoggle(dev, epnum, 1, 0);
+       ret = isp116x_submit_job(dev, pipe,
+                                PTD_DIR_SETUP,
+                                setup, sizeof(struct devrequest));
+       if (ret < 0) {
+               DBG("control setup phase error (ret = %d", ret);
+               return -1;
+       }
+
+       /* Data phase */
+       DBG("--- DATA PHASE ---------------------------------");
+       done = 0;
+       usb_settoggle(dev, epnum, !dir_in, 1);
+       while (done < len) {
+               ret = isp116x_submit_job(dev, pipe,
+                                        dir_in ? PTD_DIR_IN : PTD_DIR_OUT,
+                                        (__u8 *) buffer + done,
+                                        max > len - done ? len - done : max);
+               if (ret < 0) {
+                       DBG("control data phase error (ret = %d)", ret);
+                       return -1;
+               }
+               done += ret;
+
+               if (dir_in && ret < max)        /* short packet */
+                       break;
+       }
+
+       /* Status phase */
+       DBG("--- STATUS PHASE -------------------------------");
+       usb_settoggle(dev, epnum, !dir_in, 1);
+       ret = isp116x_submit_job(dev, pipe,
+                                !dir_in ? PTD_DIR_IN : PTD_DIR_OUT, NULL, 0);
+       if (ret < 0) {
+               DBG("control status phase error (ret = %d", ret);
+               return -1;
+       }
+
+       dev->act_len = done;
+
+       dump_msg(dev, pipe, buffer, len, "DEV(ret)");
+
+       return done;
+}
+
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+                   int len)
+{
+       int dir_out = usb_pipeout(pipe);
+       int max = max_transfer_len(dev, pipe);
+       int done, ret;
+
+       DBG("--- BULK ---------------------------------------");
+       DBG("dev=%ld pipe=%ld buf=%p size=%d dir_out=%d",
+           usb_pipedevice(pipe), usb_pipeendpoint(pipe), buffer, len, dir_out);
+
+       done = 0;
+       while (done < len) {
+               ret = isp116x_submit_job(dev, pipe,
+                                        !dir_out ? PTD_DIR_IN : PTD_DIR_OUT,
+                                        (__u8 *) buffer + done,
+                                        max > len - done ? len - done : max);
+               if (ret < 0) {
+                       DBG("error on bulk message (ret = %d)", ret);
+                       return -1;
+               }
+
+               done += ret;
+
+               if (!dir_out && ret < max)      /* short packet */
+                       break;
+       }
+
+       dev->act_len = done;
+
+       return 0;
+}
+
+/* --- Basic functions ----------------------------------------------------- */
+
+static int isp116x_sw_reset(struct isp116x *isp116x)
+{
+       int retries = 15;
+       int ret = 0;
+
+       DBG("");
+
+       isp116x->disabled = 1;
+
+       isp116x_write_reg16(isp116x, HCSWRES, HCSWRES_MAGIC);
+       isp116x_write_reg32(isp116x, HCCMDSTAT, HCCMDSTAT_HCR);
+       while (--retries) {
+               /* It usually resets within 1 ms */
+               wait_ms(1);
+               if (!(isp116x_read_reg32(isp116x, HCCMDSTAT) & HCCMDSTAT_HCR))
+                       break;
+       }
+       if (!retries) {
+               ERR("software reset timeout");
+               ret = -1;
+       }
+       return ret;
+}
+
+static int isp116x_reset(struct isp116x *isp116x)
+{
+       unsigned long t;
+       u16 clkrdy = 0;
+       int ret, timeout = 15 /* ms */ ;
+
+       DBG("");
+
+       ret = isp116x_sw_reset(isp116x);
+       if (ret)
+               return ret;
+
+       for (t = 0; t < timeout; t++) {
+               clkrdy = isp116x_read_reg16(isp116x, HCuPINT) & HCuPINT_CLKRDY;
+               if (clkrdy)
+                       break;
+               wait_ms(1);
+       }
+       if (!clkrdy) {
+               ERR("clock not ready after %dms", timeout);
+               /* After sw_reset the clock won't report to be ready, if
+                  H_WAKEUP pin is high. */
+               ERR("please make sure that the H_WAKEUP pin is pulled low!");
+               ret = -1;
+       }
+       return ret;
+}
+
+static void isp116x_stop(struct isp116x *isp116x)
+{
+       u32 val;
+
+       DBG("");
+
+       isp116x_write_reg16(isp116x, HCuPINTENB, 0);
+
+       /* Switch off ports' power, some devices don't come up
+          after next 'start' without this */
+       val = isp116x_read_reg32(isp116x, HCRHDESCA);
+       val &= ~(RH_A_NPS | RH_A_PSM);
+       isp116x_write_reg32(isp116x, HCRHDESCA, val);
+       isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPS);
+
+       isp116x_sw_reset(isp116x);
+}
+
+/*
+ *  Configure the chip. The chip must be successfully reset by now.
+ */
+static int isp116x_start(struct isp116x *isp116x)
+{
+       struct isp116x_platform_data *board = isp116x->board;
+       u32 val;
+
+       DBG("");
+
+       /* Clear interrupt status and disable all interrupt sources */
+       isp116x_write_reg16(isp116x, HCuPINT, 0xff);
+       isp116x_write_reg16(isp116x, HCuPINTENB, 0);
+
+       isp116x_write_reg16(isp116x, HCITLBUFLEN, ISP116x_ITL_BUFSIZE);
+       isp116x_write_reg16(isp116x, HCATLBUFLEN, ISP116x_ATL_BUFSIZE);
+
+       /* Hardware configuration */
+       val = HCHWCFG_DBWIDTH(1);
+       if (board->sel15Kres)
+               val |= HCHWCFG_15KRSEL;
+       /* Remote wakeup won't work without working clock */
+       if (board->remote_wakeup_enable)
+               val |= HCHWCFG_CLKNOTSTOP;
+       if (board->oc_enable)
+               val |= HCHWCFG_ANALOG_OC;
+       isp116x_write_reg16(isp116x, HCHWCFG, val);
+
+       /* --- Root hub configuration */
+       val = (25 << 24) & RH_A_POTPGT;
+       /* AN10003_1.pdf recommends RH_A_NPS (no power switching) to
+          be always set. Yet, instead, we request individual port
+          power switching. */
+       val |= RH_A_PSM;
+       /* Report overcurrent per port */
+       val |= RH_A_OCPM;
+       isp116x_write_reg32(isp116x, HCRHDESCA, val);
+       isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA);
+
+       val = RH_B_PPCM;
+       isp116x_write_reg32(isp116x, HCRHDESCB, val);
+       isp116x->rhdescb = isp116x_read_reg32(isp116x, HCRHDESCB);
+
+       val = 0;
+       if (board->remote_wakeup_enable)
+               val |= RH_HS_DRWE;
+       isp116x_write_reg32(isp116x, HCRHSTATUS, val);
+       isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS);
+
+       isp116x_write_reg32(isp116x, HCFMINTVL, 0x27782edf);
+
+       /* Go operational */
+       val = HCCONTROL_USB_OPER;
+       if (board->remote_wakeup_enable)
+               val |= HCCONTROL_RWE;
+       isp116x_write_reg32(isp116x, HCCONTROL, val);
+
+       /* Disable ports to avoid race in device enumeration */
+       isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS);
+       isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS);
+
+       isp116x_show_regs(isp116x);
+
+       isp116x->disabled = 0;
+
+       return 0;
+}
+
+/* --- Init functions ------------------------------------------------------ */
+
+int isp116x_check_id(struct isp116x *isp116x)
+{
+       int val;
+
+       val = isp116x_read_reg16(isp116x, HCCHIPID);
+       if ((val & HCCHIPID_MASK) != HCCHIPID_MAGIC) {
+               ERR("invalid chip ID %04x", val);
+               return -1;
+       }
+
+       return 0;
+}
+
+int usb_lowlevel_init(void)
+{
+       struct isp116x *isp116x = &isp116x_dev;
+
+       DBG("");
+
+       got_rhsc = rh_devnum = 0;
+
+       /* Init device registers addr */
+       isp116x->addr_reg = (u16 *) ISP116X_HCD_ADDR;
+       isp116x->data_reg = (u16 *) ISP116X_HCD_DATA;
+
+       /* Setup specific board settings */
+#ifdef ISP116X_HCD_SEL15kRES
+       isp116x_board.sel15Kres = 1;
+#endif
+#ifdef ISP116X_HCD_OC_ENABLE
+       isp116x_board.oc_enable = 1;
+#endif
+#ifdef ISP116X_HCD_REMOTE_WAKEUP_ENABLE
+       isp116x_board.remote_wakeup_enable = 1;
+#endif
+       isp116x->board = &isp116x_board;
+
+       /* Try to get ISP116x silicon chip ID */
+       if (isp116x_check_id(isp116x) < 0)
+               return -1;
+
+       isp116x->disabled = 1;
+       isp116x->sleeping = 0;
+
+       isp116x_reset(isp116x);
+       isp116x_start(isp116x);
+
+       return 0;
+}
+
+int usb_lowlevel_stop(void)
+{
+       struct isp116x *isp116x = &isp116x_dev;
+
+       DBG("");
+
+       if (!isp116x->disabled)
+               isp116x_stop(isp116x);
+
+       return 0;
+}
+
+#endif                         /* CONFIG_USB_ISP116X_HCD */
diff --git a/drivers/usb/isp116x.h b/drivers/usb/isp116x.h
new file mode 100644 (file)
index 0000000..a3ce3b5
--- /dev/null
@@ -0,0 +1,489 @@
+/*
+ * ISP116x register declarations and HCD data structures
+ *
+ * Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
+ * Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.it>
+ * Copyright (C) 2005 Olav Kongas <ok@artecdesign.ee>
+ * Portions:
+ * Copyright (C) 2004 Lothar Wassmann
+ * Copyright (C) 2004 Psion Teklogix
+ * Copyright (C) 2004 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifdef DEBUG
+#define DBG(fmt, args...)      \
+               printf("isp116x: %s: " fmt "\n" , __FUNCTION__ , ## args)
+#else
+#define DBG(fmt, args...)      do {} while (0)
+#endif
+
+#ifdef VERBOSE
+#    define VDBG               DBG
+#else
+#    define VDBG(fmt, args...) do {} while (0)
+#endif
+
+#define ERR(fmt, args...)      \
+               printf("isp116x: %s: " fmt "\n" , __FUNCTION__ , ## args)
+#define WARN(fmt, args...)     \
+               printf("isp116x: %s: " fmt "\n" , __FUNCTION__ , ## args)
+#define INFO(fmt, args...)     \
+               printf("isp116x: " fmt "\n" , ## args)
+
+/* ------------------------------------------------------------------------- */
+
+/* us of 1ms frame */
+#define  MAX_LOAD_LIMIT                850
+
+/* Full speed: max # of bytes to transfer for a single urb
+   at a time must be < 1024 && must be multiple of 64.
+   832 allows transfering 4kiB within 5 frames. */
+#define MAX_TRANSFER_SIZE_FULLSPEED    832
+
+/* Low speed: there is no reason to schedule in very big
+   chunks; often the requested long transfers are for
+   string descriptors containing short strings. */
+#define MAX_TRANSFER_SIZE_LOWSPEED     64
+
+/* Bytetime (us), a rough indication of how much time it
+   would take to transfer a byte of useful data over USB */
+#define BYTE_TIME_FULLSPEED    1
+#define BYTE_TIME_LOWSPEED     20
+
+/* Buffer sizes */
+#define ISP116x_BUF_SIZE       4096
+#define ISP116x_ITL_BUFSIZE    0
+#define ISP116x_ATL_BUFSIZE    ((ISP116x_BUF_SIZE) - 2*(ISP116x_ITL_BUFSIZE))
+
+#define ISP116x_WRITE_OFFSET   0x80
+
+/* --- ISP116x registers/bits ---------------------------------------------- */
+
+#define        HCREVISION      0x00
+#define        HCCONTROL       0x01
+#define                HCCONTROL_HCFS  (3 << 6)        /* host controller
+                                                  functional state */
+#define                HCCONTROL_USB_RESET     (0 << 6)
+#define                HCCONTROL_USB_RESUME    (1 << 6)
+#define                HCCONTROL_USB_OPER      (2 << 6)
+#define                HCCONTROL_USB_SUSPEND   (3 << 6)
+#define                HCCONTROL_RWC   (1 << 9)        /* remote wakeup connected */
+#define                HCCONTROL_RWE   (1 << 10)       /* remote wakeup enable */
+#define        HCCMDSTAT       0x02
+#define                HCCMDSTAT_HCR   (1 << 0)        /* host controller reset */
+#define                HCCMDSTAT_SOC   (3 << 16)       /* scheduling overrun count */
+#define        HCINTSTAT       0x03
+#define                HCINT_SO        (1 << 0)        /* scheduling overrun */
+#define                HCINT_WDH       (1 << 1)        /* writeback of done_head */
+#define                HCINT_SF        (1 << 2)        /* start frame */
+#define                HCINT_RD        (1 << 3)        /* resume detect */
+#define                HCINT_UE        (1 << 4)        /* unrecoverable error */
+#define                HCINT_FNO       (1 << 5)        /* frame number overflow */
+#define                HCINT_RHSC      (1 << 6)        /* root hub status change */
+#define                HCINT_OC        (1 << 30)       /* ownership change */
+#define                HCINT_MIE       (1 << 31)       /* master interrupt enable */
+#define        HCINTENB        0x04
+#define        HCINTDIS        0x05
+#define        HCFMINTVL       0x0d
+#define        HCFMREM         0x0e
+#define        HCFMNUM         0x0f
+#define        HCLSTHRESH      0x11
+#define        HCRHDESCA       0x12
+#define                RH_A_NDP        (0x3 << 0)      /* # downstream ports */
+#define                RH_A_PSM        (1 << 8)        /* power switching mode */
+#define                RH_A_NPS        (1 << 9)        /* no power switching */
+#define                RH_A_DT         (1 << 10)       /* device type (mbz) */
+#define                RH_A_OCPM       (1 << 11)       /* overcurrent protection
+                                                  mode */
+#define                RH_A_NOCP       (1 << 12)       /* no overcurrent protection */
+#define                RH_A_POTPGT     (0xff << 24)    /* power on -> power good
+                                                  time */
+#define        HCRHDESCB       0x13
+#define                RH_B_DR         (0xffff << 0)   /* device removable flags */
+#define                RH_B_PPCM       (0xffff << 16)  /* port power control mask */
+#define        HCRHSTATUS      0x14
+#define                RH_HS_LPS       (1 << 0)        /* local power status */
+#define                RH_HS_OCI       (1 << 1)        /* over current indicator */
+#define                RH_HS_DRWE      (1 << 15)       /* device remote wakeup
+                                                  enable */
+#define                RH_HS_LPSC      (1 << 16)       /* local power status change */
+#define                RH_HS_OCIC      (1 << 17)       /* over current indicator
+                                                  change */
+#define                RH_HS_CRWE      (1 << 31)       /* clear remote wakeup
+                                                  enable */
+#define        HCRHPORT1       0x15
+#define                RH_PS_CCS       (1 << 0)        /* current connect status */
+#define                RH_PS_PES       (1 << 1)        /* port enable status */
+#define                RH_PS_PSS       (1 << 2)        /* port suspend status */
+#define                RH_PS_POCI      (1 << 3)        /* port over current
+                                                  indicator */
+#define                RH_PS_PRS       (1 << 4)        /* port reset status */
+#define                RH_PS_PPS       (1 << 8)        /* port power status */
+#define                RH_PS_LSDA      (1 << 9)        /* low speed device attached */
+#define                RH_PS_CSC       (1 << 16)       /* connect status change */
+#define                RH_PS_PESC      (1 << 17)       /* port enable status change */
+#define                RH_PS_PSSC      (1 << 18)       /* port suspend status
+                                                  change */
+#define                RH_PS_OCIC      (1 << 19)       /* over current indicator
+                                                  change */
+#define                RH_PS_PRSC      (1 << 20)       /* port reset status change */
+#define                HCRHPORT_CLRMASK        (0x1f << 16)
+#define        HCRHPORT2       0x16
+#define        HCHWCFG         0x20
+#define                HCHWCFG_15KRSEL         (1 << 12)
+#define                HCHWCFG_CLKNOTSTOP      (1 << 11)
+#define                HCHWCFG_ANALOG_OC       (1 << 10)
+#define                HCHWCFG_DACK_MODE       (1 << 8)
+#define                HCHWCFG_EOT_POL         (1 << 7)
+#define                HCHWCFG_DACK_POL        (1 << 6)
+#define                HCHWCFG_DREQ_POL        (1 << 5)
+#define                HCHWCFG_DBWIDTH_MASK    (0x03 << 3)
+#define                HCHWCFG_DBWIDTH(n)      (((n) << 3) & HCHWCFG_DBWIDTH_MASK)
+#define                HCHWCFG_INT_POL         (1 << 2)
+#define                HCHWCFG_INT_TRIGGER     (1 << 1)
+#define                HCHWCFG_INT_ENABLE      (1 << 0)
+#define        HCDMACFG        0x21
+#define                HCDMACFG_BURST_LEN_MASK (0x03 << 5)
+#define                HCDMACFG_BURST_LEN(n)   (((n) << 5) & HCDMACFG_BURST_LEN_MASK)
+#define                HCDMACFG_BURST_LEN_1    HCDMACFG_BURST_LEN(0)
+#define                HCDMACFG_BURST_LEN_4    HCDMACFG_BURST_LEN(1)
+#define                HCDMACFG_BURST_LEN_8    HCDMACFG_BURST_LEN(2)
+#define                HCDMACFG_DMA_ENABLE     (1 << 4)
+#define                HCDMACFG_BUF_TYPE_MASK  (0x07 << 1)
+#define                HCDMACFG_CTR_SEL        (1 << 2)
+#define                HCDMACFG_ITLATL_SEL     (1 << 1)
+#define                HCDMACFG_DMA_RW_SELECT  (1 << 0)
+#define        HCXFERCTR       0x22
+#define        HCuPINT         0x24
+#define                HCuPINT_SOF             (1 << 0)
+#define                HCuPINT_ATL             (1 << 1)
+#define                HCuPINT_AIIEOT          (1 << 2)
+#define                HCuPINT_OPR             (1 << 4)
+#define                HCuPINT_SUSP            (1 << 5)
+#define                HCuPINT_CLKRDY          (1 << 6)
+#define        HCuPINTENB      0x25
+#define        HCCHIPID        0x27
+#define                HCCHIPID_MASK           0xff00
+#define                HCCHIPID_MAGIC          0x6100
+#define        HCSCRATCH       0x28
+#define        HCSWRES         0x29
+#define                HCSWRES_MAGIC           0x00f6
+#define        HCITLBUFLEN     0x2a
+#define        HCATLBUFLEN     0x2b
+#define        HCBUFSTAT       0x2c
+#define                HCBUFSTAT_ITL0_FULL     (1 << 0)
+#define                HCBUFSTAT_ITL1_FULL     (1 << 1)
+#define                HCBUFSTAT_ATL_FULL      (1 << 2)
+#define                HCBUFSTAT_ITL0_DONE     (1 << 3)
+#define                HCBUFSTAT_ITL1_DONE     (1 << 4)
+#define                HCBUFSTAT_ATL_DONE      (1 << 5)
+#define        HCRDITL0LEN     0x2d
+#define        HCRDITL1LEN     0x2e
+#define        HCITLPORT       0x40
+#define        HCATLPORT       0x41
+
+/* PTD accessor macros. */
+#define PTD_GET_COUNT(p)       (((p)->count & PTD_COUNT_MSK) >> 0)
+#define PTD_COUNT(v)           (((v) << 0) & PTD_COUNT_MSK)
+#define PTD_GET_TOGGLE(p)      (((p)->count & PTD_TOGGLE_MSK) >> 10)
+#define PTD_TOGGLE(v)          (((v) << 10) & PTD_TOGGLE_MSK)
+#define PTD_GET_ACTIVE(p)      (((p)->count & PTD_ACTIVE_MSK) >> 11)
+#define PTD_ACTIVE(v)          (((v) << 11) & PTD_ACTIVE_MSK)
+#define PTD_GET_CC(p)          (((p)->count & PTD_CC_MSK) >> 12)
+#define PTD_CC(v)              (((v) << 12) & PTD_CC_MSK)
+#define PTD_GET_MPS(p)         (((p)->mps & PTD_MPS_MSK) >> 0)
+#define PTD_MPS(v)             (((v) << 0) & PTD_MPS_MSK)
+#define PTD_GET_SPD(p)         (((p)->mps & PTD_SPD_MSK) >> 10)
+#define PTD_SPD(v)             (((v) << 10) & PTD_SPD_MSK)
+#define PTD_GET_LAST(p)                (((p)->mps & PTD_LAST_MSK) >> 11)
+#define PTD_LAST(v)            (((v) << 11) & PTD_LAST_MSK)
+#define PTD_GET_EP(p)          (((p)->mps & PTD_EP_MSK) >> 12)
+#define PTD_EP(v)              (((v) << 12) & PTD_EP_MSK)
+#define PTD_GET_LEN(p)         (((p)->len & PTD_LEN_MSK) >> 0)
+#define PTD_LEN(v)             (((v) << 0) & PTD_LEN_MSK)
+#define PTD_GET_DIR(p)         (((p)->len & PTD_DIR_MSK) >> 10)
+#define PTD_DIR(v)             (((v) << 10) & PTD_DIR_MSK)
+#define PTD_GET_B5_5(p)                (((p)->len & PTD_B5_5_MSK) >> 13)
+#define PTD_B5_5(v)            (((v) << 13) & PTD_B5_5_MSK)
+#define PTD_GET_FA(p)          (((p)->faddr & PTD_FA_MSK) >> 0)
+#define PTD_FA(v)              (((v) << 0) & PTD_FA_MSK)
+#define PTD_GET_FMT(p)         (((p)->faddr & PTD_FMT_MSK) >> 7)
+#define PTD_FMT(v)             (((v) << 7) & PTD_FMT_MSK)
+
+/*  Hardware transfer status codes -- CC from ptd->count */
+#define TD_CC_NOERROR      0x00
+#define TD_CC_CRC          0x01
+#define TD_CC_BITSTUFFING  0x02
+#define TD_CC_DATATOGGLEM  0x03
+#define TD_CC_STALL        0x04
+#define TD_DEVNOTRESP      0x05
+#define TD_PIDCHECKFAIL    0x06
+#define TD_UNEXPECTEDPID   0x07
+#define TD_DATAOVERRUN     0x08
+#define TD_DATAUNDERRUN    0x09
+    /* 0x0A, 0x0B reserved for hardware */
+#define TD_BUFFEROVERRUN   0x0C
+#define TD_BUFFERUNDERRUN  0x0D
+    /* 0x0E, 0x0F reserved for HCD */
+#define TD_NOTACCESSED     0x0F
+
+/* ------------------------------------------------------------------------- */
+
+#define        LOG2_PERIODIC_SIZE      5       /* arbitrary; this matches OHCI */
+#define        PERIODIC_SIZE           (1 << LOG2_PERIODIC_SIZE)
+
+/* Philips transfer descriptor */
+struct ptd {
+       u16 count;
+#define        PTD_COUNT_MSK   (0x3ff << 0)
+#define        PTD_TOGGLE_MSK  (1 << 10)
+#define        PTD_ACTIVE_MSK  (1 << 11)
+#define        PTD_CC_MSK      (0xf << 12)
+       u16 mps;
+#define        PTD_MPS_MSK     (0x3ff << 0)
+#define        PTD_SPD_MSK     (1 << 10)
+#define        PTD_LAST_MSK    (1 << 11)
+#define        PTD_EP_MSK      (0xf << 12)
+       u16 len;
+#define        PTD_LEN_MSK     (0x3ff << 0)
+#define        PTD_DIR_MSK     (3 << 10)
+#define        PTD_DIR_SETUP   (0)
+#define        PTD_DIR_OUT     (1)
+#define        PTD_DIR_IN      (2)
+#define        PTD_B5_5_MSK    (1 << 13)
+       u16 faddr;
+#define        PTD_FA_MSK      (0x7f << 0)
+#define        PTD_FMT_MSK     (1 << 7)
+} __attribute__ ((packed, aligned(2)));
+
+struct isp116x_ep {
+       struct usb_device *udev;
+       struct ptd ptd;
+
+       u8 maxpacket;
+       u8 epnum;
+       u8 nextpid;
+
+       u16 length;             /* of current packet */
+       unsigned char *data;    /* to databuf */
+
+       u16 error_count;
+};
+
+/* URB struct */
+#define N_URB_TD               48
+#define URB_DEL                        1
+typedef struct {
+       struct isp116x_ep *ed;
+       void *transfer_buffer;  /* (in) associated data buffer */
+       int actual_length;      /* (return) actual transfer length */
+       unsigned long pipe;     /* (in) pipe information */
+#if 0
+       int state;
+#endif
+} urb_priv_t;
+
+struct isp116x_platform_data {
+       /* Enable internal resistors on downstream ports */
+       unsigned sel15Kres:1;
+       /* On-chip overcurrent detection */
+       unsigned oc_enable:1;
+       /* Enable wakeup by devices on usb bus (e.g. wakeup
+          by attachment/detachment or by device activity
+          such as moving a mouse). When chosen, this option
+          prevents stopping internal clock, increasing
+          thereby power consumption in suspended state. */
+       unsigned remote_wakeup_enable:1;
+};
+
+struct isp116x {
+       u16 *addr_reg;
+       u16 *data_reg;
+
+       struct isp116x_platform_data *board;
+
+       struct dentry *dentry;
+       unsigned long stat1, stat2, stat4, stat8, stat16;
+
+       /* Status flags */
+       unsigned disabled:1;
+       unsigned sleeping:1;
+
+       /* Root hub registers */
+       u32 rhdesca;
+       u32 rhdescb;
+       u32 rhstatus;
+       u32 rhport[2];
+
+       /* Schedule for the current frame */
+       struct isp116x_ep *atl_active;
+       int atl_buflen;
+       int atl_bufshrt;
+       int atl_last_dir;
+       int atl_finishing;
+};
+
+/* ------------------------------------------------- */
+
+/* Inter-io delay (ns). The chip is picky about access timings; it
+ * expects at least:
+ * 150ns delay between consecutive accesses to DATA_REG,
+ * 300ns delay between access to ADDR_REG and DATA_REG
+ * OE, WE MUST NOT be changed during these intervals
+ */
+#if defined(UDELAY)
+#define        isp116x_delay(h,d)      udelay(d)
+#else
+#define        isp116x_delay(h,d)      do {} while (0)
+#endif
+
+static inline void isp116x_write_addr(struct isp116x *isp116x, unsigned reg)
+{
+       writew(reg & 0xff, isp116x->addr_reg);
+       isp116x_delay(isp116x, UDELAY);
+}
+
+static inline void isp116x_write_data16(struct isp116x *isp116x, u16 val)
+{
+       writew(val, isp116x->data_reg);
+       isp116x_delay(isp116x, UDELAY);
+}
+
+static inline void isp116x_raw_write_data16(struct isp116x *isp116x, u16 val)
+{
+       __raw_writew(val, isp116x->data_reg);
+       isp116x_delay(isp116x, UDELAY);
+}
+
+static inline u16 isp116x_read_data16(struct isp116x *isp116x)
+{
+       u16 val;
+
+       val = readw(isp116x->data_reg);
+       isp116x_delay(isp116x, UDELAY);
+       return val;
+}
+
+static inline u16 isp116x_raw_read_data16(struct isp116x *isp116x)
+{
+       u16 val;
+
+       val = __raw_readw(isp116x->data_reg);
+       isp116x_delay(isp116x, UDELAY);
+       return val;
+}
+
+static inline void isp116x_write_data32(struct isp116x *isp116x, u32 val)
+{
+       writew(val & 0xffff, isp116x->data_reg);
+       isp116x_delay(isp116x, UDELAY);
+       writew(val >> 16, isp116x->data_reg);
+       isp116x_delay(isp116x, UDELAY);
+}
+
+static inline u32 isp116x_read_data32(struct isp116x *isp116x)
+{
+       u32 val;
+
+       val = (u32) readw(isp116x->data_reg);
+       isp116x_delay(isp116x, UDELAY);
+       val |= ((u32) readw(isp116x->data_reg)) << 16;
+       isp116x_delay(isp116x, UDELAY);
+       return val;
+}
+
+/* Let's keep register access functions out of line. Hint:
+   we wait at least 150 ns at every access.
+*/
+static u16 isp116x_read_reg16(struct isp116x *isp116x, unsigned reg)
+{
+       isp116x_write_addr(isp116x, reg);
+       return isp116x_read_data16(isp116x);
+}
+
+static u32 isp116x_read_reg32(struct isp116x *isp116x, unsigned reg)
+{
+       isp116x_write_addr(isp116x, reg);
+       return isp116x_read_data32(isp116x);
+}
+
+static void isp116x_write_reg16(struct isp116x *isp116x, unsigned reg,
+                               unsigned val)
+{
+       isp116x_write_addr(isp116x, reg | ISP116x_WRITE_OFFSET);
+       isp116x_write_data16(isp116x, (u16) (val & 0xffff));
+}
+
+static void isp116x_write_reg32(struct isp116x *isp116x, unsigned reg,
+                               unsigned val)
+{
+       isp116x_write_addr(isp116x, reg | ISP116x_WRITE_OFFSET);
+       isp116x_write_data32(isp116x, (u32) val);
+}
+
+/* --- USB HUB constants (not OHCI-specific; see hub.h) -------------------- */
+
+/* destination of request */
+#define RH_INTERFACE               0x01
+#define RH_ENDPOINT                0x02
+#define RH_OTHER                   0x03
+
+#define RH_CLASS                   0x20
+#define RH_VENDOR                  0x40
+
+/* Requests: bRequest << 8 | bmRequestType */
+#define RH_GET_STATUS           0x0080
+#define RH_CLEAR_FEATURE        0x0100
+#define RH_SET_FEATURE          0x0300
+#define RH_SET_ADDRESS          0x0500
+#define RH_GET_DESCRIPTOR       0x0680
+#define RH_SET_DESCRIPTOR       0x0700
+#define RH_GET_CONFIGURATION    0x0880
+#define RH_SET_CONFIGURATION    0x0900
+#define RH_GET_STATE            0x0280
+#define RH_GET_INTERFACE        0x0A80
+#define RH_SET_INTERFACE        0x0B00
+#define RH_SYNC_FRAME           0x0C80
+/* Our Vendor Specific Request */
+#define RH_SET_EP               0x2000
+
+/* Hub port features */
+#define RH_PORT_CONNECTION         0x00
+#define RH_PORT_ENABLE             0x01
+#define RH_PORT_SUSPEND            0x02
+#define RH_PORT_OVER_CURRENT       0x03
+#define RH_PORT_RESET              0x04
+#define RH_PORT_POWER              0x08
+#define RH_PORT_LOW_SPEED          0x09
+
+#define RH_C_PORT_CONNECTION       0x10
+#define RH_C_PORT_ENABLE           0x11
+#define RH_C_PORT_SUSPEND          0x12
+#define RH_C_PORT_OVER_CURRENT     0x13
+#define RH_C_PORT_RESET            0x14
+
+/* Hub features */
+#define RH_C_HUB_LOCAL_POWER       0x00
+#define RH_C_HUB_OVER_CURRENT      0x01
+
+#define RH_DEVICE_REMOTE_WAKEUP    0x00
+#define RH_ENDPOINT_STALL          0x01
+
+#define RH_ACK                     0x01
+#define RH_REQ_ERR                 -1
+#define RH_NACK                    0x00
diff --git a/drivers/usb/sl811.h b/drivers/usb/sl811.h
new file mode 100644 (file)
index 0000000..c1f9f01
--- /dev/null
@@ -0,0 +1,104 @@
+#ifndef __UBOOT_SL811_H
+#define __UBOOT_SL811_H
+
+#undef SL811_DEBUG
+
+#ifdef SL811_DEBUG
+       #define PDEBUG(level, fmt, args...) \
+               if (debug >= (level)) printf("[%s:%d] " fmt, \
+               __PRETTY_FUNCTION__, __LINE__ , ## args)
+#else
+       #define PDEBUG(level, fmt, args...) do {} while(0)
+#endif
+
+/* Sl811 host control register */
+#define        SL811_CTRL_A            0x00
+#define        SL811_ADDR_A            0x01
+#define        SL811_LEN_A             0x02
+#define        SL811_STS_A             0x03    /* read */
+#define        SL811_PIDEP_A           0x03    /* write */
+#define        SL811_CNT_A             0x04    /* read */
+#define        SL811_DEV_A             0x04    /* write */
+#define        SL811_CTRL1             0x05
+#define        SL811_INTR              0x06
+#define        SL811_CTRL_B            0x08
+#define        SL811_ADDR_B            0x09
+#define        SL811_LEN_B             0x0A
+#define        SL811_STS_B             0x0B    /* read */
+#define        SL811_PIDEP_B           0x0B    /* write */
+#define        SL811_CNT_B             0x0C    /* read */
+#define        SL811_DEV_B             0x0C    /* write */
+#define        SL811_INTRSTS           0x0D    /* write clears bitwise */
+#define        SL811_HWREV             0x0E    /* read */
+#define        SL811_SOFLOW            0x0E    /* write */
+#define        SL811_SOFCNTDIV         0x0F    /* read */
+#define        SL811_CTRL2             0x0F    /* write */
+
+/* USB control register bits (addr 0x00 and addr 0x08) */
+#define        SL811_USB_CTRL_ARM      0x01
+#define        SL811_USB_CTRL_ENABLE   0x02
+#define        SL811_USB_CTRL_DIR_OUT  0x04
+#define        SL811_USB_CTRL_ISO      0x10
+#define        SL811_USB_CTRL_SOF      0x20
+#define        SL811_USB_CTRL_TOGGLE_1 0x40
+#define        SL811_USB_CTRL_PREAMBLE 0x80
+
+/* USB status register bits (addr 0x03 and addr 0x0B) */
+#define        SL811_USB_STS_ACK       0x01
+#define        SL811_USB_STS_ERROR     0x02
+#define        SL811_USB_STS_TIMEOUT   0x04
+#define        SL811_USB_STS_TOGGLE_1  0x08
+#define        SL811_USB_STS_SETUP     0x10
+#define        SL811_USB_STS_OVERFLOW  0x20
+#define        SL811_USB_STS_NAK       0x40
+#define        SL811_USB_STS_STALL     0x80
+
+/* Control register 1 bits (addr 0x05) */
+#define        SL811_CTRL1_SOF         0x01
+#define        SL811_CTRL1_RESET       0x08
+#define        SL811_CTRL1_JKSTATE     0x10
+#define        SL811_CTRL1_SPEED_LOW   0x20
+#define        SL811_CTRL1_SUSPEND     0x40
+
+/* Interrut enable (addr 0x06) and interrupt status register bits (addr 0x0D) */
+#define        SL811_INTR_DONE_A       0x01
+#define        SL811_INTR_DONE_B       0x02
+#define        SL811_INTR_SOF          0x10
+#define        SL811_INTR_INSRMV       0x20
+#define        SL811_INTR_DETECT       0x40
+#define        SL811_INTR_NOTPRESENT   0x40
+#define        SL811_INTR_SPEED_FULL   0x80    /* only in status reg */
+
+/* HW rev and SOF lo register bits (addr 0x0E) */
+#define        SL811_HWR_HWREV         0xF0
+
+/* SOF counter and control reg 2 (addr 0x0F) */
+#define        SL811_CTL2_SOFHI        0x3F
+#define        SL811_CTL2_DSWAP        0x40
+#define        SL811_CTL2_HOST         0x80
+
+/* Set up for 1-ms SOF time. */
+#define SL811_12M_LOW          0xE0
+#define SL811_12M_HI           0x2E
+
+#define SL811_DATA_START       0x10
+#define SL811_DATA_LIMIT       240
+
+/* Requests: bRequest << 8 | bmRequestType */
+#define RH_GET_STATUS           0x0080
+#define RH_CLEAR_FEATURE        0x0100
+#define RH_SET_FEATURE          0x0300
+#define RH_SET_ADDRESS         0x0500
+#define RH_GET_DESCRIPTOR      0x0680
+#define RH_SET_DESCRIPTOR       0x0700
+#define RH_GET_CONFIGURATION   0x0880
+#define RH_SET_CONFIGURATION   0x0900
+#define RH_GET_STATE            0x0280
+#define RH_GET_INTERFACE        0x0A80
+#define RH_SET_INTERFACE        0x0B00
+#define RH_SYNC_FRAME           0x0C80
+
+
+#define PIDEP(pid, ep) (((pid) & 0x0f) << 4 | (ep))
+
+#endif /* __UBOOT_SL811_H */
diff --git a/drivers/usb/sl811_usb.c b/drivers/usb/sl811_usb.c
new file mode 100644 (file)
index 0000000..c1f8427
--- /dev/null
@@ -0,0 +1,737 @@
+/*
+ * (C) Copyright 2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * This code is based on linux driver for sl811hs chip, source at
+ * drivers/usb/host/sl811.c:
+ *
+ * SL811 Host Controller Interface driver for USB.
+ *
+ * Copyright (c) 2003/06, Courage Co., Ltd.
+ *
+ * Based on:
+ *     1.uhci.c by Linus Torvalds, Johannes Erdfelt, Randy Dunlap,
+ *       Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber,
+ *       Adam Richter, Gregory P. Smith;
+ *     2.Original SL811 driver (hc_sl811.o) by Pei Liu <pbl@cypress.com>
+ *     3.Rewrited as sl811.o by Yin Aihua <yinah:couragetech.com.cn>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#ifdef CONFIG_USB_SL811HS
+#include <mpc8xx.h>
+#include <usb.h>
+#include "sl811.h"
+
+#include "../../board/kup/common/kup.h"
+
+#ifdef __PPC__
+# define EIEIO         __asm__ volatile ("eieio")
+#else
+# define EIEIO         /* nothing */
+#endif
+
+#define         SL811_ADR (0x50000000)
+#define         SL811_DAT (0x50000001)
+
+#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);})
+
+#ifdef SL811_DEBUG
+static int debug = 9;
+#endif
+
+static int root_hub_devnum = 0;
+static struct usb_port_status rh_status = { 0 };/* root hub port status */
+
+static int sl811_rh_submit_urb(struct usb_device *usb_dev, unsigned long pipe,
+                              void *data, int buf_len, struct devrequest *cmd);
+
+static void sl811_write (__u8 index, __u8 data)
+{
+       *(volatile unsigned char *) (SL811_ADR) = index;
+       EIEIO;
+       *(volatile unsigned char *) (SL811_DAT) = data;
+       EIEIO;
+}
+
+static __u8 sl811_read (__u8 index)
+{
+       __u8 data;
+
+       *(volatile unsigned char *) (SL811_ADR) = index;
+       EIEIO;
+       data = *(volatile unsigned char *) (SL811_DAT);
+       EIEIO;
+       return (data);
+}
+
+/*
+ * Read consecutive bytes of data from the SL811H/SL11H buffer
+ */
+static void inline sl811_read_buf(__u8 offset, __u8 *buf, __u8 size)
+{
+       *(volatile unsigned char *) (SL811_ADR) = offset;
+       EIEIO;
+       while (size--) {
+               *buf++ = *(volatile unsigned char *) (SL811_DAT);
+               EIEIO;
+       }
+}
+
+/*
+ * Write consecutive bytes of data to the SL811H/SL11H buffer
+ */
+static void inline sl811_write_buf(__u8 offset, __u8 *buf, __u8 size)
+{
+       *(volatile unsigned char *) (SL811_ADR) = offset;
+       EIEIO;
+       while (size--) {
+               *(volatile unsigned char *) (SL811_DAT) = *buf++;
+               EIEIO;
+       }
+}
+
+int usb_init_kup4x (void)
+{
+       volatile immap_t *immap = (immap_t *) CFG_IMMR;
+       volatile memctl8xx_t *memctl = &immap->im_memctl;
+       int i;
+       unsigned char tmp;
+
+       memctl = &immap->im_memctl;
+       memctl->memc_or7 = 0xFFFF8726;
+       memctl->memc_br7 = 0x50000401;  /* start at 0x50000000 */
+       /* BP 14 low = USB ON */
+       immap->im_cpm.cp_pbdat &= ~(BP_USB_VCC);
+       /* PB 14 nomal port */
+       immap->im_cpm.cp_pbpar &= ~(BP_USB_VCC);
+       /* output */
+       immap->im_cpm.cp_pbdir |= (BP_USB_VCC);
+
+       puts ("USB:   ");
+
+       for (i = 0x10; i < 0xff; i++) {
+               sl811_write(i, i);
+               tmp = (sl811_read(i));
+               if (tmp != i) {
+                       printf ("SL811 compare error index=0x%02x read=0x%02x\n", i, tmp);
+                       return (-1);
+               }
+       }
+       printf ("SL811 ready\n");
+       return (0);
+}
+
+/*
+ * This function resets SL811HS controller and detects the speed of
+ * the connecting device
+ *
+ * Return: 0 = no device attached; 1 = USB device attached
+ */
+static int sl811_hc_reset(void)
+{
+       int status ;
+
+       sl811_write(SL811_CTRL2, SL811_CTL2_HOST | SL811_12M_HI);
+       sl811_write(SL811_CTRL1, SL811_CTRL1_RESET);
+
+       mdelay(20);
+
+       /* Disable hardware SOF generation, clear all irq status. */
+       sl811_write(SL811_CTRL1, 0);
+       mdelay(2);
+       sl811_write(SL811_INTRSTS, 0xff);
+       status = sl811_read(SL811_INTRSTS);
+
+       if (status & SL811_INTR_NOTPRESENT) {
+               /* Device is not present */
+               PDEBUG(0, "Device not present\n");
+               rh_status.wPortStatus &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE);
+               rh_status.wPortChange |= USB_PORT_STAT_C_CONNECTION;
+               sl811_write(SL811_INTR, SL811_INTR_INSRMV);
+               return 0;
+       }
+
+       /* Send SOF to address 0, endpoint 0. */
+       sl811_write(SL811_LEN_B, 0);
+       sl811_write(SL811_PIDEP_B, PIDEP(USB_PID_SOF, 0));
+       sl811_write(SL811_DEV_B, 0x00);
+       sl811_write(SL811_SOFLOW, SL811_12M_LOW);
+
+       if (status & SL811_INTR_SPEED_FULL) {
+               /* full speed device connect directly to root hub */
+               PDEBUG (0, "Full speed Device attached\n");
+
+               sl811_write(SL811_CTRL1, SL811_CTRL1_RESET);
+               mdelay(20);
+               sl811_write(SL811_CTRL2, SL811_CTL2_HOST | SL811_12M_HI);
+               sl811_write(SL811_CTRL1, SL811_CTRL1_SOF);
+
+               /* start the SOF or EOP */
+               sl811_write(SL811_CTRL_B, SL811_USB_CTRL_ARM);
+               rh_status.wPortStatus |= USB_PORT_STAT_CONNECTION;
+               rh_status.wPortStatus &= ~USB_PORT_STAT_LOW_SPEED;
+               mdelay(2);
+               sl811_write(SL811_INTRSTS, 0xff);
+       } else {
+               /* slow speed device connect directly to root-hub */
+               PDEBUG(0, "Low speed Device attached\n");
+
+               sl811_write(SL811_CTRL1, SL811_CTRL1_RESET);
+               mdelay(20);
+               sl811_write(SL811_CTRL2, SL811_CTL2_HOST | SL811_CTL2_DSWAP | SL811_12M_HI);
+               sl811_write(SL811_CTRL1, SL811_CTRL1_SPEED_LOW | SL811_CTRL1_SOF);
+
+               /* start the SOF or EOP */
+               sl811_write(SL811_CTRL_B, SL811_USB_CTRL_ARM);
+               rh_status.wPortStatus |= USB_PORT_STAT_CONNECTION | USB_PORT_STAT_LOW_SPEED;
+               mdelay(2);
+               sl811_write(SL811_INTRSTS, 0xff);
+       }
+
+       rh_status.wPortChange |= USB_PORT_STAT_C_CONNECTION;
+       sl811_write(SL811_INTR, /*SL811_INTR_INSRMV*/SL811_INTR_DONE_A);
+
+       return 1;
+}
+
+int usb_lowlevel_init(void)
+{
+       root_hub_devnum = 0;
+       sl811_hc_reset();
+       return 0;
+}
+
+int usb_lowlevel_stop(void)
+{
+       sl811_hc_reset();
+       return 0;
+}
+
+static int calc_needed_buswidth(int bytes, int need_preamble)
+{
+       return !need_preamble ? bytes * 8 + 256 : 8 * 8 * bytes + 2048;
+}
+
+static int sl811_send_packet(struct usb_device *dev, unsigned long pipe, __u8 *buffer, int len)
+{
+       __u8 ctrl = SL811_USB_CTRL_ARM | SL811_USB_CTRL_ENABLE;
+       __u16 status = 0;
+       int err = 0, time_start = get_timer(0);
+       int need_preamble = !(rh_status.wPortStatus & USB_PORT_STAT_LOW_SPEED) &&
+               usb_pipeslow(pipe);
+
+       if (len > 239)
+               return -1;
+
+       if (usb_pipeout(pipe))
+               ctrl |= SL811_USB_CTRL_DIR_OUT;
+       if (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)))
+               ctrl |= SL811_USB_CTRL_TOGGLE_1;
+       if (need_preamble)
+               ctrl |= SL811_USB_CTRL_PREAMBLE;
+
+       sl811_write(SL811_INTRSTS, 0xff);
+
+       while (err < 3) {
+               sl811_write(SL811_ADDR_A, 0x10);
+               sl811_write(SL811_LEN_A, len);
+               if (usb_pipeout(pipe) && len)
+                       sl811_write_buf(0x10, buffer, len);
+
+               if (!(rh_status.wPortStatus & USB_PORT_STAT_LOW_SPEED) &&
+                   sl811_read(SL811_SOFCNTDIV)*64 < calc_needed_buswidth(len, need_preamble))
+                       ctrl |= SL811_USB_CTRL_SOF;
+               else
+                       ctrl &= ~SL811_USB_CTRL_SOF;
+
+               sl811_write(SL811_CTRL_A, ctrl);
+               while (!(sl811_read(SL811_INTRSTS) & SL811_INTR_DONE_A)) {
+                       if (5*CFG_HZ < get_timer(time_start)) {
+                               printf("USB transmit timed out\n");
+                               return -USB_ST_CRC_ERR;
+                       }
+               }
+
+               sl811_write(SL811_INTRSTS, 0xff);
+               status = sl811_read(SL811_STS_A);
+
+               if (status & SL811_USB_STS_ACK) {
+                       int remainder = sl811_read(SL811_CNT_A);
+                       if (remainder) {
+                               PDEBUG(0, "usb transfer remainder = %d\n", remainder);
+                               len -= remainder;
+                       }
+                       if (usb_pipein(pipe) && len)
+                               sl811_read_buf(0x10, buffer, len);
+                       return len;
+               }
+
+               if ((status & SL811_USB_STS_NAK) == SL811_USB_STS_NAK)
+                       continue;
+
+               PDEBUG(0, "usb transfer error %#x\n", (int)status);
+               err++;
+       }
+
+       err = 0;
+
+       if (status & SL811_USB_STS_ERROR)
+               err |= USB_ST_BUF_ERR;
+       if (status & SL811_USB_STS_TIMEOUT)
+               err |= USB_ST_CRC_ERR;
+       if (status & SL811_USB_STS_STALL)
+               err |= USB_ST_STALLED;
+
+       return -err;
+}
+
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+                   int len)
+{
+       int dir_out = usb_pipeout(pipe);
+       int ep = usb_pipeendpoint(pipe);
+       int max = usb_maxpacket(dev, pipe);
+       int done = 0;
+
+       PDEBUG(7, "dev = %ld pipe = %ld buf = %p size = %d dir_out = %d\n",
+              usb_pipedevice(pipe), usb_pipeendpoint(pipe), buffer, len, dir_out);
+
+       dev->status = 0;
+
+       sl811_write(SL811_DEV_A, usb_pipedevice(pipe));
+       sl811_write(SL811_PIDEP_A, PIDEP(!dir_out ? USB_PID_IN : USB_PID_OUT, ep));
+       while (done < len) {
+               int res = sl811_send_packet(dev, pipe, (__u8*)buffer+done,
+                                           max > len - done ? len - done : max);
+               if (res < 0) {
+                       dev->status = -res;
+                       return res;
+               }
+
+               if (!dir_out && res < max) /* short packet */
+                       break;
+
+               done += res;
+               usb_dotoggle(dev, ep, dir_out);
+       }
+
+       dev->act_len = done;
+
+       return 0;
+}
+
+int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+                      int len,struct devrequest *setup)
+{
+       int done = 0;
+       int devnum = usb_pipedevice(pipe);
+       int ep = usb_pipeendpoint(pipe);
+
+       dev->status = 0;
+
+       if (devnum == root_hub_devnum)
+               return sl811_rh_submit_urb(dev, pipe, buffer, len, setup);
+
+       PDEBUG(7, "dev = %d pipe = %ld buf = %p size = %d rt = %#x req = %#x bus = %i\n",
+              devnum, ep, buffer, len, (int)setup->requesttype,
+              (int)setup->request, sl811_read(SL811_SOFCNTDIV)*64);
+
+       sl811_write(SL811_DEV_A, devnum);
+       sl811_write(SL811_PIDEP_A, PIDEP(USB_PID_SETUP, ep));
+       /* setup phase */
+       usb_settoggle(dev, ep, 1, 0);
+       if (sl811_send_packet(dev, usb_sndctrlpipe(dev, ep),
+                             (__u8*)setup, sizeof(*setup)) == sizeof(*setup)) {
+               int dir_in = usb_pipein(pipe);
+               int max = usb_maxpacket(dev, pipe);
+
+               /* data phase */
+               sl811_write(SL811_PIDEP_A,
+                           PIDEP(dir_in ? USB_PID_IN : USB_PID_OUT, ep));
+               usb_settoggle(dev, ep, usb_pipeout(pipe), 1);
+               while (done < len) {
+                       int res = sl811_send_packet(dev, pipe, (__u8*)buffer+done,
+                                                   max > len - done ? len - done : max);
+                       if (res < 0) {
+                               PDEBUG(0, "status data failed!\n");
+                               dev->status = -res;
+                               return 0;
+                       }
+                       done += res;
+                       usb_dotoggle(dev, ep, usb_pipeout(pipe));
+                       if (dir_in && res < max) /* short packet */
+                               break;
+               }
+
+               /* status phase */
+               sl811_write(SL811_PIDEP_A,
+                           PIDEP(!dir_in ? USB_PID_IN : USB_PID_OUT, ep));
+               usb_settoggle(dev, ep, !usb_pipeout(pipe), 1);
+               if (sl811_send_packet(dev,
+                                     !dir_in ? usb_rcvctrlpipe(dev, ep) :
+                                     usb_sndctrlpipe(dev, ep),
+                                     0, 0) < 0) {
+                       PDEBUG(0, "status phase failed!\n");
+                       dev->status = -1;
+               }
+       } else {
+               PDEBUG(0, "setup phase failed!\n");
+               dev->status = -1;
+       }
+
+       dev->act_len = done;
+
+       return done;
+}
+
+int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+                  int len, int interval)
+{
+       PDEBUG(0, "dev = %p pipe = %#lx buf = %p size = %d int = %d\n", dev, pipe,
+              buffer, len, interval);
+       return -1;
+}
+
+/*
+ * SL811 Virtual Root Hub
+ */
+
+/* Device descriptor */
+static __u8 sl811_rh_dev_des[] =
+{
+       0x12,       /*  __u8  bLength; */
+       0x01,       /*  __u8  bDescriptorType; Device */
+       0x10,       /*  __u16 bcdUSB; v1.1 */
+       0x01,
+       0x09,       /*  __u8  bDeviceClass; HUB_CLASSCODE */
+       0x00,       /*  __u8  bDeviceSubClass; */
+       0x00,       /*  __u8  bDeviceProtocol; */
+       0x08,       /*  __u8  bMaxPacketSize0; 8 Bytes */
+       0x00,       /*  __u16 idVendor; */
+       0x00,
+       0x00,       /*  __u16 idProduct; */
+       0x00,
+       0x00,       /*  __u16 bcdDevice; */
+       0x00,
+       0x00,       /*  __u8  iManufacturer; */
+       0x02,       /*  __u8  iProduct; */
+       0x01,       /*  __u8  iSerialNumber; */
+       0x01        /*  __u8  bNumConfigurations; */
+};
+
+/* Configuration descriptor */
+static __u8 sl811_rh_config_des[] =
+{
+       0x09,       /*  __u8  bLength; */
+       0x02,       /*  __u8  bDescriptorType; Configuration */
+       0x19,       /*  __u16 wTotalLength; */
+       0x00,
+       0x01,       /*  __u8  bNumInterfaces; */
+       0x01,       /*  __u8  bConfigurationValue; */
+       0x00,       /*  __u8  iConfiguration; */
+       0x40,       /*  __u8  bmAttributes;
+                   Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup,
+                   4..0: resvd */
+       0x00,       /*  __u8  MaxPower; */
+
+       /* interface */
+       0x09,       /*  __u8  if_bLength; */
+       0x04,       /*  __u8  if_bDescriptorType; Interface */
+       0x00,       /*  __u8  if_bInterfaceNumber; */
+       0x00,       /*  __u8  if_bAlternateSetting; */
+       0x01,       /*  __u8  if_bNumEndpoints; */
+       0x09,       /*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
+       0x00,       /*  __u8  if_bInterfaceSubClass; */
+       0x00,       /*  __u8  if_bInterfaceProtocol; */
+       0x00,       /*  __u8  if_iInterface; */
+
+       /* endpoint */
+       0x07,       /*  __u8  ep_bLength; */
+       0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
+       0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
+       0x03,       /*  __u8  ep_bmAttributes; Interrupt */
+       0x08,       /*  __u16 ep_wMaxPacketSize; */
+       0x00,
+       0xff        /*  __u8  ep_bInterval; 255 ms */
+};
+
+/* root hub class descriptor*/
+static __u8 sl811_rh_hub_des[] =
+{
+       0x09,                   /*  __u8  bLength; */
+       0x29,                   /*  __u8  bDescriptorType; Hub-descriptor */
+       0x01,                   /*  __u8  bNbrPorts; */
+       0x00,                   /* __u16  wHubCharacteristics; */
+       0x00,
+       0x50,                   /*  __u8  bPwrOn2pwrGood; 2ms */
+       0x00,                   /*  __u8  bHubContrCurrent; 0 mA */
+       0xfc,                   /*  __u8  DeviceRemovable; *** 7 Ports max *** */
+       0xff                    /*  __u8  PortPwrCtrlMask; *** 7 ports max *** */
+};
+
+/*
+ * helper routine for returning string descriptors in UTF-16LE
+ * input can actually be ISO-8859-1; ASCII is its 7-bit subset
+ */
+static int ascii2utf (char *s, u8 *utf, int utfmax)
+{
+       int retval;
+
+       for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) {
+               *utf++ = *s++;
+               *utf++ = 0;
+       }
+       return retval;
+}
+
+/*
+ * root_hub_string is used by each host controller's root hub code,
+ * so that they're identified consistently throughout the system.
+ */
+static int usb_root_hub_string (int id, int serial, char *type, __u8 *data, int len)
+{
+       char buf [30];
+
+       /* assert (len > (2 * (sizeof (buf) + 1)));
+          assert (strlen (type) <= 8);*/
+
+       /* language ids */
+       if (id == 0) {
+               *data++ = 4; *data++ = 3;       /* 4 bytes data */
+               *data++ = 0; *data++ = 0;       /* some language id */
+               return 4;
+
+       /* serial number */
+       } else if (id == 1) {
+               sprintf (buf, "%#x", serial);
+
+       /* product description */
+       } else if (id == 2) {
+               sprintf (buf, "USB %s Root Hub", type);
+
+       /* id 3 == vendor description */
+
+       /* unsupported IDs --> "stall" */
+       } else
+           return 0;
+
+       ascii2utf (buf, data + 2, len - 2);
+       data [0] = 2 + strlen(buf) * 2;
+       data [1] = 3;
+       return data [0];
+}
+
+/* helper macro */
+#define OK(x)  len = (x); break
+
+/*
+ * This function handles all USB request to the the virtual root hub
+ */
+static int sl811_rh_submit_urb(struct usb_device *usb_dev, unsigned long pipe,
+                              void *data, int buf_len, struct devrequest *cmd)
+{
+       __u8 data_buf[16];
+       __u8 *bufp = data_buf;
+       int len = 0;
+       int status = 0;
+
+       __u16 bmRType_bReq;
+       __u16 wValue;
+       __u16 wIndex;
+       __u16 wLength;
+
+       if (usb_pipeint(pipe)) {
+               PDEBUG(0, "interrupt transfer unimplemented!\n");
+               return 0;
+       }
+
+       bmRType_bReq  = cmd->requesttype | (cmd->request << 8);
+       wValue        = le16_to_cpu (cmd->value);
+       wIndex        = le16_to_cpu (cmd->index);
+       wLength       = le16_to_cpu (cmd->length);
+
+       PDEBUG(5, "submit rh urb, req = %d(%x) val = %#x index = %#x len=%d\n",
+              bmRType_bReq, bmRType_bReq, wValue, wIndex, wLength);
+
+       /* Request Destination:
+                  without flags: Device,
+                  USB_RECIP_INTERFACE: interface,
+                  USB_RECIP_ENDPOINT: endpoint,
+                  USB_TYPE_CLASS means HUB here,
+                  USB_RECIP_OTHER | USB_TYPE_CLASS  almost ever means HUB_PORT here
+       */
+       switch (bmRType_bReq) {
+       case RH_GET_STATUS:
+               *(__u16 *)bufp = cpu_to_le16(1);
+               OK(2);
+
+       case RH_GET_STATUS | USB_RECIP_INTERFACE:
+               *(__u16 *)bufp = cpu_to_le16(0);
+               OK(2);
+
+       case RH_GET_STATUS | USB_RECIP_ENDPOINT:
+               *(__u16 *)bufp = cpu_to_le16(0);
+               OK(2);
+
+       case RH_GET_STATUS | USB_TYPE_CLASS:
+               *(__u32 *)bufp = cpu_to_le32(0);
+               OK(4);
+
+       case RH_GET_STATUS | USB_RECIP_OTHER | USB_TYPE_CLASS:
+               *(__u32 *)bufp = cpu_to_le32(rh_status.wPortChange<<16 | rh_status.wPortStatus);
+               OK(4);
+
+       case RH_CLEAR_FEATURE | USB_RECIP_ENDPOINT:
+               switch (wValue) {
+               case 1:
+                       OK(0);
+               }
+               break;
+
+       case RH_CLEAR_FEATURE | USB_TYPE_CLASS:
+               switch (wValue) {
+               case C_HUB_LOCAL_POWER:
+                       OK(0);
+
+               case C_HUB_OVER_CURRENT:
+                       OK(0);
+               }
+               break;
+
+       case RH_CLEAR_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS:
+               switch (wValue) {
+               case USB_PORT_FEAT_ENABLE:
+                       rh_status.wPortStatus &= ~USB_PORT_STAT_ENABLE;
+                       OK(0);
+
+               case USB_PORT_FEAT_SUSPEND:
+                       rh_status.wPortStatus &= ~USB_PORT_STAT_SUSPEND;
+                       OK(0);
+
+               case USB_PORT_FEAT_POWER:
+                       rh_status.wPortStatus &= ~USB_PORT_STAT_POWER;
+                       OK(0);
+
+               case USB_PORT_FEAT_C_CONNECTION:
+                       rh_status.wPortChange &= ~USB_PORT_STAT_C_CONNECTION;
+                       OK(0);
+
+               case USB_PORT_FEAT_C_ENABLE:
+                       rh_status.wPortChange &= ~USB_PORT_STAT_C_ENABLE;
+                       OK(0);
+
+               case USB_PORT_FEAT_C_SUSPEND:
+                       rh_status.wPortChange &= ~USB_PORT_STAT_C_SUSPEND;
+                       OK(0);
+
+               case USB_PORT_FEAT_C_OVER_CURRENT:
+                       rh_status.wPortChange &= ~USB_PORT_STAT_C_OVERCURRENT;
+                       OK(0);
+
+               case USB_PORT_FEAT_C_RESET:
+                       rh_status.wPortChange &= ~USB_PORT_STAT_C_RESET;
+                       OK(0);
+               }
+               break;
+
+       case RH_SET_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS:
+               switch (wValue) {
+               case USB_PORT_FEAT_SUSPEND:
+                       rh_status.wPortStatus |= USB_PORT_STAT_SUSPEND;
+                       OK(0);
+
+               case USB_PORT_FEAT_RESET:
+                       rh_status.wPortStatus |= USB_PORT_STAT_RESET;
+                       rh_status.wPortChange = 0;
+                       rh_status.wPortChange |= USB_PORT_STAT_C_RESET;
+                       rh_status.wPortStatus &= ~USB_PORT_STAT_RESET;
+                       rh_status.wPortStatus |= USB_PORT_STAT_ENABLE;
+                       OK(0);
+
+               case USB_PORT_FEAT_POWER:
+                       rh_status.wPortStatus |= USB_PORT_STAT_POWER;
+                       OK(0);
+
+               case USB_PORT_FEAT_ENABLE:
+                       rh_status.wPortStatus |= USB_PORT_STAT_ENABLE;
+                       OK(0);
+               }
+               break;
+
+       case RH_SET_ADDRESS:
+               root_hub_devnum = wValue;
+               OK(0);
+
+       case RH_GET_DESCRIPTOR:
+               switch ((wValue & 0xff00) >> 8) {
+               case USB_DT_DEVICE:
+                       len = sizeof(sl811_rh_dev_des);
+                       bufp = sl811_rh_dev_des;
+                       OK(len);
+
+               case USB_DT_CONFIG:
+                       len = sizeof(sl811_rh_config_des);
+                       bufp = sl811_rh_config_des;
+                       OK(len);
+
+               case USB_DT_STRING:
+                       len = usb_root_hub_string(wValue & 0xff, (int)(long)0,  "SL811HS", data, wLength);
+                       if (len > 0) {
+                               bufp = data;
+                               OK(len);
+                       }
+
+               default:
+                       status = -32;
+               }
+               break;
+
+       case RH_GET_DESCRIPTOR | USB_TYPE_CLASS:
+               len = sizeof(sl811_rh_hub_des);
+               bufp = sl811_rh_hub_des;
+               OK(len);
+
+       case RH_GET_CONFIGURATION:
+               bufp[0] = 0x01;
+               OK(1);
+
+       case RH_SET_CONFIGURATION:
+               OK(0);
+
+       default:
+               PDEBUG(1, "unsupported root hub command\n");
+               status = -32;
+       }
+
+       len = min(len, buf_len);
+       if (data != bufp)
+               memcpy(data, bufp, len);
+
+       PDEBUG(5, "len = %d, status = %d\n", len, status);
+
+       usb_dev->status = status;
+       usb_dev->act_len = len;
+
+       return status == 0 ? len : status;
+}
+
+#endif /* CONFIG_USB_SL811HS */
diff --git a/drivers/usb/usb_ohci.c b/drivers/usb/usb_ohci.c
new file mode 100644 (file)
index 0000000..cfa384e
--- /dev/null
@@ -0,0 +1,1923 @@
+/*
+ * URB OHCI HCD (Host Controller Driver) for USB on the AT91RM9200 and PCI bus.
+ *
+ * Interrupt support is added. Now, it has been tested
+ * on ULI1575 chip and works well with USB keyboard.
+ *
+ * (C) Copyright 2007
+ * Zhang Wei, Freescale Semiconductor, Inc. <wei.zhang@freescale.com>
+ *
+ * (C) Copyright 2003
+ * Gary Jennejohn, DENX Software Engineering <gj@denx.de>
+ *
+ * Note: Much of this code has been derived from Linux 2.4
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ * (C) Copyright 2000-2002 David Brownell
+ *
+ * Modified for the MP2USB by (C) Copyright 2005 Eric Benard
+ * ebenard@eukrea.com - based on s3c24x0's driver
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.        See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+/*
+ * IMPORTANT NOTES
+ * 1 - Read doc/README.generic_usb_ohci
+ * 2 - this driver is intended for use with USB Mass Storage Devices
+ *     (BBB) and USB keyboard. There is NO support for Isochronous pipes!
+ * 2 - when running on a PQFP208 AT91RM9200, define CONFIG_AT91C_PQFP_UHPBUG
+ *     to activate workaround for bug #41 or this driver will NOT work!
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_USB_OHCI_NEW
+
+#include <asm/byteorder.h>
+
+#if defined(CONFIG_PCI_OHCI)
+# include <pci.h>
+#endif
+
+#include <malloc.h>
+#include <usb.h>
+#include "usb_ohci.h"
+
+#ifdef CONFIG_AT91RM9200
+#include <asm/arch/hardware.h> /* needed for AT91_USB_HOST_BASE */
+#endif
+
+#if defined(CONFIG_ARM920T) || \
+    defined(CONFIG_S3C2400) || \
+    defined(CONFIG_S3C2410) || \
+    defined(CONFIG_440EP) || \
+    defined(CONFIG_PCI_OHCI) || \
+    defined(CONFIG_MPC5200)
+# define OHCI_USE_NPS          /* force NoPowerSwitching mode */
+#endif
+
+#undef OHCI_VERBOSE_DEBUG      /* not always helpful */
+#undef DEBUG
+#undef SHOW_INFO
+#undef OHCI_FILL_TRACE
+
+/* For initializing controller (mask in an HCFS mode too) */
+#define OHCI_CONTROL_INIT \
+       (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
+
+/*
+ * e.g. PCI controllers need this
+ */
+#ifdef CFG_OHCI_SWAP_REG_ACCESS
+# define readl(a) __swap_32(*((vu_long *)(a)))
+# define writel(a, b) (*((vu_long *)(b)) = __swap_32((vu_long)a))
+#else
+# define readl(a) (*((vu_long *)(a)))
+# define writel(a, b) (*((vu_long *)(b)) = ((vu_long)a))
+#endif /* CFG_OHCI_SWAP_REG_ACCESS */
+
+#define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
+
+#ifdef CONFIG_PCI_OHCI
+static struct pci_device_id ohci_pci_ids[] = {
+       {0x10b9, 0x5237},       /* ULI1575 PCI OHCI module ids */
+       {0x1033, 0x0035},       /* NEC PCI OHCI module ids */
+       /* Please add supported PCI OHCI controller ids here */
+       {0, 0}
+};
+#endif
+
+#ifdef DEBUG
+#define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg)
+#else
+#define dbg(format, arg...) do {} while(0)
+#endif /* DEBUG */
+#define err(format, arg...) printf("ERROR: " format "\n", ## arg)
+#undef SHOW_INFO
+#ifdef SHOW_INFO
+#define info(format, arg...) printf("INFO: " format "\n", ## arg)
+#else
+#define info(format, arg...) do {} while(0)
+#endif
+
+#ifdef CFG_OHCI_BE_CONTROLLER
+# define m16_swap(x) cpu_to_be16(x)
+# define m32_swap(x) cpu_to_be32(x)
+#else
+# define m16_swap(x) cpu_to_le16(x)
+# define m32_swap(x) cpu_to_le32(x)
+#endif /* CFG_OHCI_BE_CONTROLLER */
+
+/* global ohci_t */
+static ohci_t gohci;
+/* this must be aligned to a 256 byte boundary */
+struct ohci_hcca ghcca[1];
+/* a pointer to the aligned storage */
+struct ohci_hcca *phcca;
+/* this allocates EDs for all possible endpoints */
+struct ohci_device ohci_dev;
+/* RHSC flag */
+int got_rhsc;
+/* device which was disconnected */
+struct usb_device *devgone;
+
+/*-------------------------------------------------------------------------*/
+
+/* AMD-756 (D2 rev) reports corrupt register contents in some cases.
+ * The erratum (#4) description is incorrect.  AMD's workaround waits
+ * till some bits (mostly reserved) are clear; ok for all revs.
+ */
+#define OHCI_QUIRK_AMD756 0xabcd
+#define read_roothub(hc, register, mask) ({ \
+       u32 temp = readl (&hc->regs->roothub.register); \
+       if (hc->flags & OHCI_QUIRK_AMD756) \
+               while (temp & mask) \
+                       temp = readl (&hc->regs->roothub.register); \
+       temp; })
+
+static u32 roothub_a (struct ohci *hc)
+       { return read_roothub (hc, a, 0xfc0fe000); }
+static inline u32 roothub_b (struct ohci *hc)
+       { return readl (&hc->regs->roothub.b); }
+static inline u32 roothub_status (struct ohci *hc)
+       { return readl (&hc->regs->roothub.status); }
+static u32 roothub_portstatus (struct ohci *hc, int i)
+       { return read_roothub (hc, portstatus [i], 0xffe0fce0); }
+
+/* forward declaration */
+static int hc_interrupt (void);
+static void
+td_submit_job (struct usb_device * dev, unsigned long pipe, void * buffer,
+       int transfer_len, struct devrequest * setup, urb_priv_t * urb, int interval);
+
+/*-------------------------------------------------------------------------*
+ * URB support functions
+ *-------------------------------------------------------------------------*/
+
+/* free HCD-private data associated with this URB */
+
+static void urb_free_priv (urb_priv_t * urb)
+{
+       int             i;
+       int             last;
+       struct td       * td;
+
+       last = urb->length - 1;
+       if (last >= 0) {
+               for (i = 0; i <= last; i++) {
+                       td = urb->td[i];
+                       if (td) {
+                               td->usb_dev = NULL;
+                               urb->td[i] = NULL;
+                       }
+               }
+       }
+       free(urb);
+}
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef DEBUG
+static int sohci_get_current_frame_number (struct usb_device * dev);
+
+/* debug| print the main components of an URB
+ * small: 0) header + data packets 1) just header */
+
+static void pkt_print (urb_priv_t *purb, struct usb_device * dev,
+       unsigned long pipe, void * buffer,
+       int transfer_len, struct devrequest * setup, char * str, int small)
+{
+       dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx",
+                       str,
+                       sohci_get_current_frame_number (dev),
+                       usb_pipedevice (pipe),
+                       usb_pipeendpoint (pipe),
+                       usb_pipeout (pipe)? 'O': 'I',
+                       usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"):
+                               (usb_pipecontrol (pipe)? "CTRL": "BULK"),
+                       (purb ? purb->actual_length : 0),
+                       transfer_len, dev->status);
+#ifdef OHCI_VERBOSE_DEBUG
+       if (!small) {
+               int i, len;
+
+               if (usb_pipecontrol (pipe)) {
+                       printf (__FILE__ ": cmd(8):");
+                       for (i = 0; i < 8 ; i++)
+                               printf (" %02x", ((__u8 *) setup) [i]);
+                       printf ("\n");
+               }
+               if (transfer_len > 0 && buffer) {
+                       printf (__FILE__ ": data(%d/%d):",
+                               (purb ? purb->actual_length : 0),
+                               transfer_len);
+                       len = usb_pipeout (pipe)?
+                                       transfer_len:
+                                       (purb ? purb->actual_length : 0);
+                       for (i = 0; i < 16 && i < len; i++)
+                               printf (" %02x", ((__u8 *) buffer) [i]);
+                       printf ("%s\n", i < len? "...": "");
+               }
+       }
+#endif
+}
+
+/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/
+void ep_print_int_eds (ohci_t *ohci, char * str) {
+       int i, j;
+        __u32 * ed_p;
+       for (i= 0; i < 32; i++) {
+               j = 5;
+               ed_p = &(ohci->hcca->int_table [i]);
+               if (*ed_p == 0)
+                   continue;
+               printf (__FILE__ ": %s branch int %2d(%2x):", str, i, i);
+               while (*ed_p != 0 && j--) {
+                       ed_t *ed = (ed_t *)m32_swap(ed_p);
+                       printf (" ed: %4x;", ed->hwINFO);
+                       ed_p = &ed->hwNextED;
+               }
+               printf ("\n");
+       }
+}
+
+static void ohci_dump_intr_mask (char *label, __u32 mask)
+{
+       dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s",
+               label,
+               mask,
+               (mask & OHCI_INTR_MIE) ? " MIE" : "",
+               (mask & OHCI_INTR_OC) ? " OC" : "",
+               (mask & OHCI_INTR_RHSC) ? " RHSC" : "",
+               (mask & OHCI_INTR_FNO) ? " FNO" : "",
+               (mask & OHCI_INTR_UE) ? " UE" : "",
+               (mask & OHCI_INTR_RD) ? " RD" : "",
+               (mask & OHCI_INTR_SF) ? " SF" : "",
+               (mask & OHCI_INTR_WDH) ? " WDH" : "",
+               (mask & OHCI_INTR_SO) ? " SO" : ""
+               );
+}
+
+static void maybe_print_eds (char *label, __u32 value)
+{
+       ed_t *edp = (ed_t *)value;
+
+       if (value) {
+               dbg ("%s %08x", label, value);
+               dbg ("%08x", edp->hwINFO);
+               dbg ("%08x", edp->hwTailP);
+               dbg ("%08x", edp->hwHeadP);
+               dbg ("%08x", edp->hwNextED);
+       }
+}
+
+static char * hcfs2string (int state)
+{
+       switch (state) {
+               case OHCI_USB_RESET:    return "reset";
+               case OHCI_USB_RESUME:   return "resume";
+               case OHCI_USB_OPER:     return "operational";
+               case OHCI_USB_SUSPEND:  return "suspend";
+       }
+       return "?";
+}
+
+/* dump control and status registers */
+static void ohci_dump_status (ohci_t *controller)
+{
+       struct ohci_regs        *regs = controller->regs;
+       __u32                   temp;
+
+       temp = readl (&regs->revision) & 0xff;
+       if (temp != 0x10)
+               dbg ("spec %d.%d", (temp >> 4), (temp & 0x0f));
+
+       temp = readl (&regs->control);
+       dbg ("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp,
+               (temp & OHCI_CTRL_RWE) ? " RWE" : "",
+               (temp & OHCI_CTRL_RWC) ? " RWC" : "",
+               (temp & OHCI_CTRL_IR) ? " IR" : "",
+               hcfs2string (temp & OHCI_CTRL_HCFS),
+               (temp & OHCI_CTRL_BLE) ? " BLE" : "",
+               (temp & OHCI_CTRL_CLE) ? " CLE" : "",
+               (temp & OHCI_CTRL_IE) ? " IE" : "",
+               (temp & OHCI_CTRL_PLE) ? " PLE" : "",
+               temp & OHCI_CTRL_CBSR
+               );
+
+       temp = readl (&regs->cmdstatus);
+       dbg ("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp,
+               (temp & OHCI_SOC) >> 16,
+               (temp & OHCI_OCR) ? " OCR" : "",
+               (temp & OHCI_BLF) ? " BLF" : "",
+               (temp & OHCI_CLF) ? " CLF" : "",
+               (temp & OHCI_HCR) ? " HCR" : ""
+               );
+
+       ohci_dump_intr_mask ("intrstatus", readl (&regs->intrstatus));
+       ohci_dump_intr_mask ("intrenable", readl (&regs->intrenable));
+
+       maybe_print_eds ("ed_periodcurrent", readl (&regs->ed_periodcurrent));
+
+       maybe_print_eds ("ed_controlhead", readl (&regs->ed_controlhead));
+       maybe_print_eds ("ed_controlcurrent", readl (&regs->ed_controlcurrent));
+
+       maybe_print_eds ("ed_bulkhead", readl (&regs->ed_bulkhead));
+       maybe_print_eds ("ed_bulkcurrent", readl (&regs->ed_bulkcurrent));
+
+       maybe_print_eds ("donehead", readl (&regs->donehead));
+}
+
+static void ohci_dump_roothub (ohci_t *controller, int verbose)
+{
+       __u32                   temp, ndp, i;
+
+       temp = roothub_a (controller);
+       ndp = (temp & RH_A_NDP);
+#ifdef CONFIG_AT91C_PQFP_UHPBUG
+       ndp = (ndp == 2) ? 1:0;
+#endif
+       if (verbose) {
+               dbg ("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp,
+                       ((temp & RH_A_POTPGT) >> 24) & 0xff,
+                       (temp & RH_A_NOCP) ? " NOCP" : "",
+                       (temp & RH_A_OCPM) ? " OCPM" : "",
+                       (temp & RH_A_DT) ? " DT" : "",
+                       (temp & RH_A_NPS) ? " NPS" : "",
+                       (temp & RH_A_PSM) ? " PSM" : "",
+                       ndp
+                       );
+               temp = roothub_b (controller);
+               dbg ("roothub.b: %08x PPCM=%04x DR=%04x",
+                       temp,
+                       (temp & RH_B_PPCM) >> 16,
+                       (temp & RH_B_DR)
+                       );
+               temp = roothub_status (controller);
+               dbg ("roothub.status: %08x%s%s%s%s%s%s",
+                       temp,
+                       (temp & RH_HS_CRWE) ? " CRWE" : "",
+                       (temp & RH_HS_OCIC) ? " OCIC" : "",
+                       (temp & RH_HS_LPSC) ? " LPSC" : "",
+                       (temp & RH_HS_DRWE) ? " DRWE" : "",
+                       (temp & RH_HS_OCI) ? " OCI" : "",
+                       (temp & RH_HS_LPS) ? " LPS" : ""
+                       );
+       }
+
+       for (i = 0; i < ndp; i++) {
+               temp = roothub_portstatus (controller, i);
+               dbg ("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s",
+                       i,
+                       temp,
+                       (temp & RH_PS_PRSC) ? " PRSC" : "",
+                       (temp & RH_PS_OCIC) ? " OCIC" : "",
+                       (temp & RH_PS_PSSC) ? " PSSC" : "",
+                       (temp & RH_PS_PESC) ? " PESC" : "",
+                       (temp & RH_PS_CSC) ? " CSC" : "",
+
+                       (temp & RH_PS_LSDA) ? " LSDA" : "",
+                       (temp & RH_PS_PPS) ? " PPS" : "",
+                       (temp & RH_PS_PRS) ? " PRS" : "",
+                       (temp & RH_PS_POCI) ? " POCI" : "",
+                       (temp & RH_PS_PSS) ? " PSS" : "",
+
+                       (temp & RH_PS_PES) ? " PES" : "",
+                       (temp & RH_PS_CCS) ? " CCS" : ""
+                       );
+       }
+}
+
+static void ohci_dump (ohci_t *controller, int verbose)
+{
+       dbg ("OHCI controller usb-%s state", controller->slot_name);
+
+       /* dumps some of the state we know about */
+       ohci_dump_status (controller);
+       if (verbose)
+               ep_print_int_eds (controller, "hcca");
+       dbg ("hcca frame #%04x", controller->hcca->frame_no);
+       ohci_dump_roothub (controller, 1);
+
+#endif /* DEBUG */
+
+/*-------------------------------------------------------------------------*
+ * Interface functions (URB)
+ *-------------------------------------------------------------------------*/
+
+/* get a transfer request */
+
+int sohci_submit_job(urb_priv_t *urb, struct devrequest *setup)
+{
+       ohci_t *ohci;
+       ed_t * ed;
+       urb_priv_t *purb_priv = urb;
+       int i, size = 0;
+       struct usb_device *dev = urb->dev;
+       unsigned long pipe = urb->pipe;
+       void *buffer = urb->transfer_buffer;
+       int transfer_len = urb->transfer_buffer_length;
+       int interval = urb->interval;
+
+       ohci = &gohci;
+
+       /* when controller's hung, permit only roothub cleanup attempts
+        * such as powering down ports */
+       if (ohci->disabled) {
+               err("sohci_submit_job: EPIPE");
+               return -1;
+       }
+
+       /* we're about to begin a new transaction here so mark the URB unfinished */
+       urb->finished = 0;
+
+       /* every endpoint has a ed, locate and fill it */
+       if (!(ed = ep_add_ed (dev, pipe, interval, 1))) {
+               err("sohci_submit_job: ENOMEM");
+               return -1;
+       }
+
+       /* for the private part of the URB we need the number of TDs (size) */
+       switch (usb_pipetype (pipe)) {
+               case PIPE_BULK: /* one TD for every 4096 Byte */
+                       size = (transfer_len - 1) / 4096 + 1;
+                       break;
+               case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */
+                       size = (transfer_len == 0)? 2:
+                                               (transfer_len - 1) / 4096 + 3;
+                       break;
+               case PIPE_INTERRUPT: /* 1 TD */
+                       size = 1;
+                       break;
+       }
+
+       ed->purb = urb;
+
+       if (size >= (N_URB_TD - 1)) {
+               err("need %d TDs, only have %d", size, N_URB_TD);
+               return -1;
+       }
+       purb_priv->pipe = pipe;
+
+       /* fill the private part of the URB */
+       purb_priv->length = size;
+       purb_priv->ed = ed;
+       purb_priv->actual_length = 0;
+
+       /* allocate the TDs */
+       /* note that td[0] was allocated in ep_add_ed */
+       for (i = 0; i < size; i++) {
+               purb_priv->td[i] = td_alloc (dev);
+               if (!purb_priv->td[i]) {
+                       purb_priv->length = i;
+                       urb_free_priv (purb_priv);
+                       err("sohci_submit_job: ENOMEM");
+                       return -1;
+               }
+       }
+
+       if (ed->state == ED_NEW || (ed->state & ED_DEL)) {
+               urb_free_priv (purb_priv);
+               err("sohci_submit_job: EINVAL");
+               return -1;
+       }
+
+       /* link the ed into a chain if is not already */
+       if (ed->state != ED_OPER)
+               ep_link (ohci, ed);
+
+       /* fill the TDs and link it to the ed */
+       td_submit_job(dev, pipe, buffer, transfer_len, setup, purb_priv, interval);
+
+       return 0;
+}
+
+static inline int sohci_return_job(struct ohci *hc, urb_priv_t *urb)
+{
+       struct ohci_regs *regs = hc->regs;
+
+       switch (usb_pipetype (urb->pipe)) {
+       case PIPE_INTERRUPT:
+               /* implicitly requeued */
+               if (urb->dev->irq_handle &&
+                               (urb->dev->irq_act_len = urb->actual_length)) {
+                       writel (OHCI_INTR_WDH, &regs->intrenable);
+                       readl (&regs->intrenable); /* PCI posting flush */
+                       urb->dev->irq_handle(urb->dev);
+                       writel (OHCI_INTR_WDH, &regs->intrdisable);
+                       readl (&regs->intrdisable); /* PCI posting flush */
+               }
+               urb->actual_length = 0;
+               td_submit_job (
+                               urb->dev,
+                               urb->pipe,
+                               urb->transfer_buffer,
+                               urb->transfer_buffer_length,
+                               NULL,
+                               urb,
+                               urb->interval);
+               break;
+       case PIPE_CONTROL:
+       case PIPE_BULK:
+               break;
+       default:
+               return 0;
+       }
+       return 1;
+}
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef DEBUG
+/* tell us the current USB frame number */
+
+static int sohci_get_current_frame_number (struct usb_device *usb_dev)
+{
+       ohci_t *ohci = &gohci;
+
+       return m16_swap (ohci->hcca->frame_no);
+}
+#endif
+
+/*-------------------------------------------------------------------------*
+ * ED handling functions
+ *-------------------------------------------------------------------------*/
+
+/* search for the right branch to insert an interrupt ed into the int tree
+ * do some load ballancing;
+ * returns the branch and
+ * sets the interval to interval = 2^integer (ld (interval)) */
+
+static int ep_int_ballance (ohci_t * ohci, int interval, int load)
+{
+       int i, branch = 0;
+
+       /* search for the least loaded interrupt endpoint
+        * branch of all 32 branches
+        */
+       for (i = 0; i < 32; i++)
+               if (ohci->ohci_int_load [branch] > ohci->ohci_int_load [i])
+                       branch = i;
+
+       branch = branch % interval;
+       for (i = branch; i < 32; i += interval)
+               ohci->ohci_int_load [i] += load;
+
+       return branch;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*  2^int( ld (inter)) */
+
+static int ep_2_n_interval (int inter)
+{
+       int i;
+       for (i = 0; ((inter >> i) > 1 ) && (i < 5); i++);
+       return 1 << i;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* the int tree is a binary tree
+ * in order to process it sequentially the indexes of the branches have to be mapped
+ * the mapping reverses the bits of a word of num_bits length */
+
+static int ep_rev (int num_bits, int word)
+{
+       int i, wout = 0;
+
+       for (i = 0; i < num_bits; i++)
+               wout |= (((word >> i) & 1) << (num_bits - i - 1));
+       return wout;
+}
+
+/*-------------------------------------------------------------------------*
+ * ED handling functions
+ *-------------------------------------------------------------------------*/
+
+/* link an ed into one of the HC chains */
+
+static int ep_link (ohci_t *ohci, ed_t *edi)
+{
+       volatile ed_t *ed = edi;
+       int int_branch;
+       int i;
+       int inter;
+       int interval;
+       int load;
+       __u32 * ed_p;
+
+       ed->state = ED_OPER;
+       ed->int_interval = 0;
+
+       switch (ed->type) {
+       case PIPE_CONTROL:
+               ed->hwNextED = 0;
+               if (ohci->ed_controltail == NULL) {
+                       writel (ed, &ohci->regs->ed_controlhead);
+               } else {
+                       ohci->ed_controltail->hwNextED = m32_swap ((unsigned long)ed);
+               }
+               ed->ed_prev = ohci->ed_controltail;
+               if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&
+                       !ohci->ed_rm_list[1] && !ohci->sleeping) {
+                       ohci->hc_control |= OHCI_CTRL_CLE;
+                       writel (ohci->hc_control, &ohci->regs->control);
+               }
+               ohci->ed_controltail = edi;
+               break;
+
+       case PIPE_BULK:
+               ed->hwNextED = 0;
+               if (ohci->ed_bulktail == NULL) {
+                       writel (ed, &ohci->regs->ed_bulkhead);
+               } else {
+                       ohci->ed_bulktail->hwNextED = m32_swap ((unsigned long)ed);
+               }
+               ed->ed_prev = ohci->ed_bulktail;
+               if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&
+                       !ohci->ed_rm_list[1] && !ohci->sleeping) {
+                       ohci->hc_control |= OHCI_CTRL_BLE;
+                       writel (ohci->hc_control, &ohci->regs->control);
+               }
+               ohci->ed_bulktail = edi;
+               break;
+
+       case PIPE_INTERRUPT:
+               load = ed->int_load;
+               interval = ep_2_n_interval (ed->int_period);
+               ed->int_interval = interval;
+               int_branch = ep_int_ballance (ohci, interval, load);
+               ed->int_branch = int_branch;
+
+               for (i = 0; i < ep_rev (6, interval); i += inter) {
+                       inter = 1;
+                       for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i) + int_branch]);
+                               (*ed_p != 0) && (((ed_t *)ed_p)->int_interval >= interval);
+                               ed_p = &(((ed_t *)ed_p)->hwNextED))
+                                       inter = ep_rev (6, ((ed_t *)ed_p)->int_interval);
+                       ed->hwNextED = *ed_p;
+                       *ed_p = m32_swap((unsigned long)ed);
+               }
+               break;
+       }
+       return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* scan the periodic table to find and unlink this ED */
+static void periodic_unlink ( struct ohci *ohci, volatile struct ed *ed,
+               unsigned index, unsigned period)
+{
+       for (; index < NUM_INTS; index += period) {
+               __u32   *ed_p = &ohci->hcca->int_table [index];
+
+               /* ED might have been unlinked through another path */
+               while (*ed_p != 0) {
+                       if (((struct ed *)m32_swap ((unsigned long)ed_p)) == ed) {
+                               *ed_p = ed->hwNextED;
+                               break;
+                       }
+                       ed_p = & (((struct ed *)m32_swap ((unsigned long)ed_p))->hwNextED);
+               }
+       }
+}
+
+/* unlink an ed from one of the HC chains.
+ * just the link to the ed is unlinked.
+ * the link from the ed still points to another operational ed or 0
+ * so the HC can eventually finish the processing of the unlinked ed */
+
+static int ep_unlink (ohci_t *ohci, ed_t *edi)
+{
+       volatile ed_t *ed = edi;
+       int i;
+
+       ed->hwINFO |= m32_swap (OHCI_ED_SKIP);
+
+       switch (ed->type) {
+       case PIPE_CONTROL:
+               if (ed->ed_prev == NULL) {
+                       if (!ed->hwNextED) {
+                               ohci->hc_control &= ~OHCI_CTRL_CLE;
+                               writel (ohci->hc_control, &ohci->regs->control);
+                       }
+                       writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_controlhead);
+               } else {
+                       ed->ed_prev->hwNextED = ed->hwNextED;
+               }
+               if (ohci->ed_controltail == ed) {
+                       ohci->ed_controltail = ed->ed_prev;
+               } else {
+                       ((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;
+               }
+               break;
+
+       case PIPE_BULK:
+               if (ed->ed_prev == NULL) {
+                       if (!ed->hwNextED) {
+                               ohci->hc_control &= ~OHCI_CTRL_BLE;
+                               writel (ohci->hc_control, &ohci->regs->control);
+                       }
+                       writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_bulkhead);
+               } else {
+                       ed->ed_prev->hwNextED = ed->hwNextED;
+               }
+               if (ohci->ed_bulktail == ed) {
+                       ohci->ed_bulktail = ed->ed_prev;
+               } else {
+                       ((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;
+               }
+               break;
+
+       case PIPE_INTERRUPT:
+               periodic_unlink (ohci, ed, 0, 1);
+               for (i = ed->int_branch; i < 32; i += ed->int_interval)
+                   ohci->ohci_int_load[i] -= ed->int_load;
+               break;
+       }
+       ed->state = ED_UNLINK;
+       return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* add/reinit an endpoint; this should be done once at the
+ * usb_set_configuration command, but the USB stack is a little bit
+ * stateless so we do it at every transaction if the state of the ed
+ * is ED_NEW then a dummy td is added and the state is changed to
+ * ED_UNLINK in all other cases the state is left unchanged the ed
+ * info fields are setted anyway even though most of them should not
+ * change
+ */
+static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe,
+               int interval, int load)
+{
+       td_t *td;
+       ed_t *ed_ret;
+       volatile ed_t *ed;
+
+       ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint (pipe) << 1) |
+                       (usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))];
+
+       if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) {
+               err("ep_add_ed: pending delete");
+               /* pending delete request */
+               return NULL;
+       }
+
+       if (ed->state == ED_NEW) {
+               ed->hwINFO = m32_swap (OHCI_ED_SKIP); /* skip ed */
+               /* dummy td; end of td list for ed */
+               td = td_alloc (usb_dev);
+               ed->hwTailP = m32_swap ((unsigned long)td);
+               ed->hwHeadP = ed->hwTailP;
+               ed->state = ED_UNLINK;
+               ed->type = usb_pipetype (pipe);
+               ohci_dev.ed_cnt++;
+       }
+
+       ed->hwINFO = m32_swap (usb_pipedevice (pipe)
+                       | usb_pipeendpoint (pipe) << 7
+                       | (usb_pipeisoc (pipe)? 0x8000: 0)
+                       | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000))
+                       | usb_pipeslow (pipe) << 13
+                       | usb_maxpacket (usb_dev, pipe) << 16);
+
+       if (ed->type == PIPE_INTERRUPT && ed->state == ED_UNLINK) {
+               ed->int_period = interval;
+               ed->int_load = load;
+       }
+
+       return ed_ret;
+}
+
+/*-------------------------------------------------------------------------*
+ * TD handling functions
+ *-------------------------------------------------------------------------*/
+
+/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */
+
+static void td_fill (ohci_t *ohci, unsigned int info,
+       void *data, int len,
+       struct usb_device *dev, int index, urb_priv_t *urb_priv)
+{
+       volatile td_t  *td, *td_pt;
+#ifdef OHCI_FILL_TRACE
+       int i;
+#endif
+
+       if (index > urb_priv->length) {
+               err("index > length");
+               return;
+       }
+       /* use this td as the next dummy */
+       td_pt = urb_priv->td [index];
+       td_pt->hwNextTD = 0;
+
+       /* fill the old dummy TD */
+       td = urb_priv->td [index] = (td_t *)(m32_swap (urb_priv->ed->hwTailP) & ~0xf);
+
+       td->ed = urb_priv->ed;
+       td->next_dl_td = NULL;
+       td->index = index;
+       td->data = (__u32)data;
+#ifdef OHCI_FILL_TRACE
+       if ((usb_pipetype(urb_priv->pipe) == PIPE_BULK) && usb_pipeout(urb_priv->pipe)) {
+               for (i = 0; i < len; i++)
+               printf("td->data[%d] %#2x ",i, ((unsigned char *)td->data)[i]);
+               printf("\n");
+       }
+#endif
+       if (!len)
+               data = 0;
+
+       td->hwINFO = m32_swap (info);
+       td->hwCBP = m32_swap ((unsigned long)data);
+       if (data)
+               td->hwBE = m32_swap ((unsigned long)(data + len - 1));
+       else
+               td->hwBE = 0;
+       td->hwNextTD = m32_swap ((unsigned long)td_pt);
+
+       /* append to queue */
+       td->ed->hwTailP = td->hwNextTD;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* prepare all TDs of a transfer */
+
+static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buffer,
+       int transfer_len, struct devrequest *setup, urb_priv_t *urb, int interval)
+{
+       ohci_t *ohci = &gohci;
+       int data_len = transfer_len;
+       void *data;
+       int cnt = 0;
+       __u32 info = 0;
+       unsigned int toggle = 0;
+
+       /* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */
+       if(usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) {
+               toggle = TD_T_TOGGLE;
+       } else {
+               toggle = TD_T_DATA0;
+               usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 1);
+       }
+       urb->td_cnt = 0;
+       if (data_len)
+               data = buffer;
+       else
+               data = 0;
+
+       switch (usb_pipetype (pipe)) {
+       case PIPE_BULK:
+               info = usb_pipeout (pipe)?
+                       TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ;
+               while(data_len > 4096) {
+                       td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, dev, cnt, urb);
+                       data += 4096; data_len -= 4096; cnt++;
+               }
+               info = usb_pipeout (pipe)?
+                       TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ;
+               td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, dev, cnt, urb);
+               cnt++;
+
+               if (!ohci->sleeping)
+                       writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
+               break;
+
+       case PIPE_CONTROL:
+               info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
+               td_fill (ohci, info, setup, 8, dev, cnt++, urb);
+               if (data_len > 0) {
+                       info = usb_pipeout (pipe)?
+                               TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1;
+                       /* NOTE:  mishandles transfers >8K, some >4K */
+                       td_fill (ohci, info, data, data_len, dev, cnt++, urb);
+               }
+               info = usb_pipeout (pipe)?
+                       TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1;
+               td_fill (ohci, info, data, 0, dev, cnt++, urb);
+               if (!ohci->sleeping)
+                       writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
+               break;
+
+       case PIPE_INTERRUPT:
+               info = usb_pipeout (urb->pipe)?
+                       TD_CC | TD_DP_OUT | toggle:
+                       TD_CC | TD_R | TD_DP_IN | toggle;
+               td_fill (ohci, info, data, data_len, dev, cnt++, urb);
+               break;
+       }
+       if (urb->length != cnt)
+               dbg("TD LENGTH %d != CNT %d", urb->length, cnt);
+}
+
+/*-------------------------------------------------------------------------*
+ * Done List handling functions
+ *-------------------------------------------------------------------------*/
+
+/* calculate the transfer length and update the urb */
+
+static void dl_transfer_length(td_t * td)
+{
+       __u32 tdINFO, tdBE, tdCBP;
+       urb_priv_t *lurb_priv = td->ed->purb;
+
+       tdINFO = m32_swap (td->hwINFO);
+       tdBE   = m32_swap (td->hwBE);
+       tdCBP  = m32_swap (td->hwCBP);
+
+       if (!(usb_pipetype (lurb_priv->pipe) == PIPE_CONTROL &&
+           ((td->index == 0) || (td->index == lurb_priv->length - 1)))) {
+               if (tdBE != 0) {
+                       if (td->hwCBP == 0)
+                               lurb_priv->actual_length += tdBE - td->data + 1;
+                       else
+                               lurb_priv->actual_length += tdCBP - td->data;
+               }
+       }
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* replies to the request have to be on a FIFO basis so
+ * we reverse the reversed done-list */
+
+static td_t * dl_reverse_done_list (ohci_t *ohci)
+{
+       __u32 td_list_hc;
+       td_t *td_rev = NULL;
+       td_t *td_list = NULL;
+       urb_priv_t *lurb_priv = NULL;
+
+       td_list_hc = m32_swap (ohci->hcca->done_head) & 0xfffffff0;
+       ohci->hcca->done_head = 0;
+
+       while (td_list_hc) {
+               td_list = (td_t *)td_list_hc;
+
+               if (TD_CC_GET (m32_swap (td_list->hwINFO))) {
+                       lurb_priv = td_list->ed->purb;
+                       dbg(" USB-error/status: %x : %p",
+                                       TD_CC_GET (m32_swap (td_list->hwINFO)), td_list);
+                       if (td_list->ed->hwHeadP & m32_swap (0x1)) {
+                               if (lurb_priv && ((td_list->index + 1) < lurb_priv->length)) {
+                                       td_list->ed->hwHeadP =
+                                               (lurb_priv->td[lurb_priv->length - 1]->hwNextTD & m32_swap (0xfffffff0)) |
+                                                                       (td_list->ed->hwHeadP & m32_swap (0x2));
+                                       lurb_priv->td_cnt += lurb_priv->length - td_list->index - 1;
+                               } else
+                                       td_list->ed->hwHeadP &= m32_swap (0xfffffff2);
+                       }
+#ifdef CONFIG_MPC5200
+                       td_list->hwNextTD = 0;
+#endif
+               }
+
+               td_list->next_dl_td = td_rev;
+               td_rev = td_list;
+               td_list_hc = m32_swap (td_list->hwNextTD) & 0xfffffff0;
+       }
+       return td_list;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* td done list */
+static int dl_done_list (ohci_t *ohci, td_t *td_list)
+{
+       td_t *td_list_next = NULL;
+       ed_t *ed;
+       int cc = 0;
+       int stat = 0;
+       /* urb_t *urb; */
+       urb_priv_t *lurb_priv;
+       __u32 tdINFO, edHeadP, edTailP;
+
+       while (td_list) {
+               td_list_next = td_list->next_dl_td;
+
+               tdINFO = m32_swap (td_list->hwINFO);
+
+               ed = td_list->ed;
+               lurb_priv = ed->purb;
+
+               dl_transfer_length(td_list);
+
+               /* error code of transfer */
+               cc = TD_CC_GET (tdINFO);
+               if (cc != 0) {
+                       dbg("ConditionCode %#x", cc);
+                       stat = cc_to_error[cc];
+               }
+
+               /* see if this done list makes for all TD's of current URB,
+                * and mark the URB finished if so */
+               if (++(lurb_priv->td_cnt) == lurb_priv->length) {
+#if 1
+                       if ((ed->state & (ED_OPER | ED_UNLINK)) &&
+                           (lurb_priv->state != URB_DEL))
+#else
+                       if ((ed->state & (ED_OPER | ED_UNLINK)))
+#endif
+                               lurb_priv->finished = sohci_return_job(ohci,
+                                               lurb_priv);
+                       else
+                               dbg("dl_done_list: strange.., ED state %x, ed->state\n");
+               } else
+                       dbg("dl_done_list: processing TD %x, len %x\n", lurb_priv->td_cnt,
+                               lurb_priv->length);
+               if (ed->state != ED_NEW &&
+                         (usb_pipetype (lurb_priv->pipe) != PIPE_INTERRUPT)) {
+                       edHeadP = m32_swap (ed->hwHeadP) & 0xfffffff0;
+                       edTailP = m32_swap (ed->hwTailP);
+
+                       /* unlink eds if they are not busy */
+                       if ((edHeadP == edTailP) && (ed->state == ED_OPER))
+                               ep_unlink (ohci, ed);
+               }
+
+               td_list = td_list_next;
+       }
+       return stat;
+}
+
+/*-------------------------------------------------------------------------*
+ * Virtual Root Hub
+ *-------------------------------------------------------------------------*/
+
+/* Device descriptor */
+static __u8 root_hub_dev_des[] =
+{
+       0x12,       /*  __u8  bLength; */
+       0x01,       /*  __u8  bDescriptorType; Device */
+       0x10,       /*  __u16 bcdUSB; v1.1 */
+       0x01,
+       0x09,       /*  __u8  bDeviceClass; HUB_CLASSCODE */
+       0x00,       /*  __u8  bDeviceSubClass; */
+       0x00,       /*  __u8  bDeviceProtocol; */
+       0x08,       /*  __u8  bMaxPacketSize0; 8 Bytes */
+       0x00,       /*  __u16 idVendor; */
+       0x00,
+       0x00,       /*  __u16 idProduct; */
+       0x00,
+       0x00,       /*  __u16 bcdDevice; */
+       0x00,
+       0x00,       /*  __u8  iManufacturer; */
+       0x01,       /*  __u8  iProduct; */
+       0x00,       /*  __u8  iSerialNumber; */
+       0x01        /*  __u8  bNumConfigurations; */
+};
+
+/* Configuration descriptor */
+static __u8 root_hub_config_des[] =
+{
+       0x09,       /*  __u8  bLength; */
+       0x02,       /*  __u8  bDescriptorType; Configuration */
+       0x19,       /*  __u16 wTotalLength; */
+       0x00,
+       0x01,       /*  __u8  bNumInterfaces; */
+       0x01,       /*  __u8  bConfigurationValue; */
+       0x00,       /*  __u8  iConfiguration; */
+       0x40,       /*  __u8  bmAttributes;
+                Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
+       0x00,       /*  __u8  MaxPower; */
+
+       /* interface */
+       0x09,       /*  __u8  if_bLength; */
+       0x04,       /*  __u8  if_bDescriptorType; Interface */
+       0x00,       /*  __u8  if_bInterfaceNumber; */
+       0x00,       /*  __u8  if_bAlternateSetting; */
+       0x01,       /*  __u8  if_bNumEndpoints; */
+       0x09,       /*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
+       0x00,       /*  __u8  if_bInterfaceSubClass; */
+       0x00,       /*  __u8  if_bInterfaceProtocol; */
+       0x00,       /*  __u8  if_iInterface; */
+
+       /* endpoint */
+       0x07,       /*  __u8  ep_bLength; */
+       0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
+       0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
+       0x03,       /*  __u8  ep_bmAttributes; Interrupt */
+       0x02,       /*  __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
+       0x00,
+       0xff        /*  __u8  ep_bInterval; 255 ms */
+};
+
+static unsigned char root_hub_str_index0[] =
+{
+       0x04,                   /*  __u8  bLength; */
+       0x03,                   /*  __u8  bDescriptorType; String-descriptor */
+       0x09,                   /*  __u8  lang ID */
+       0x04,                   /*  __u8  lang ID */
+};
+
+static unsigned char root_hub_str_index1[] =
+{
+       28,                     /*  __u8  bLength; */
+       0x03,                   /*  __u8  bDescriptorType; String-descriptor */
+       'O',                    /*  __u8  Unicode */
+       0,                              /*  __u8  Unicode */
+       'H',                    /*  __u8  Unicode */
+       0,                              /*  __u8  Unicode */
+       'C',                    /*  __u8  Unicode */
+       0,                              /*  __u8  Unicode */
+       'I',                    /*  __u8  Unicode */
+       0,                              /*  __u8  Unicode */
+       ' ',                    /*  __u8  Unicode */
+       0,                              /*  __u8  Unicode */
+       'R',                    /*  __u8  Unicode */
+       0,                              /*  __u8  Unicode */
+       'o',                    /*  __u8  Unicode */
+       0,                              /*  __u8  Unicode */
+       'o',                    /*  __u8  Unicode */
+       0,                              /*  __u8  Unicode */
+       't',                    /*  __u8  Unicode */
+       0,                              /*  __u8  Unicode */
+       ' ',                    /*  __u8  Unicode */
+       0,                              /*  __u8  Unicode */
+       'H',                    /*  __u8  Unicode */
+       0,                              /*  __u8  Unicode */
+       'u',                    /*  __u8  Unicode */
+       0,                              /*  __u8  Unicode */
+       'b',                    /*  __u8  Unicode */
+       0,                              /*  __u8  Unicode */
+};
+
+/* Hub class-specific descriptor is constructed dynamically */
+
+/*-------------------------------------------------------------------------*/
+
+#define OK(x)                  len = (x); break
+#ifdef DEBUG
+#define WR_RH_STAT(x)          {info("WR:status %#8x", (x));writel((x), &gohci.regs->roothub.status);}
+#define WR_RH_PORTSTAT(x)      {info("WR:portstatus[%d] %#8x", wIndex-1, (x));writel((x), &gohci.regs->roothub.portstatus[wIndex-1]);}
+#else
+#define WR_RH_STAT(x)          writel((x), &gohci.regs->roothub.status)
+#define WR_RH_PORTSTAT(x)      writel((x), &gohci.regs->roothub.portstatus[wIndex-1])
+#endif
+#define RD_RH_STAT             roothub_status(&gohci)
+#define RD_RH_PORTSTAT         roothub_portstatus(&gohci,wIndex-1)
+
+/* request to virtual root hub */
+
+int rh_check_port_status(ohci_t *controller)
+{
+       __u32 temp, ndp, i;
+       int res;
+
+       res = -1;
+       temp = roothub_a (controller);
+       ndp = (temp & RH_A_NDP);
+#ifdef CONFIG_AT91C_PQFP_UHPBUG
+       ndp = (ndp == 2) ? 1:0;
+#endif
+       for (i = 0; i < ndp; i++) {
+               temp = roothub_portstatus (controller, i);
+               /* check for a device disconnect */
+               if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
+                       (RH_PS_PESC | RH_PS_CSC)) &&
+                       ((temp & RH_PS_CCS) == 0)) {
+                       res = i;
+                       break;
+               }
+       }
+       return res;
+}
+
+static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
+               void *buffer, int transfer_len, struct devrequest *cmd)
+{
+       void * data = buffer;
+       int leni = transfer_len;
+       int len = 0;
+       int stat = 0;
+       __u32 datab[4];
+       __u8 *data_buf = (__u8 *)datab;
+       __u16 bmRType_bReq;
+       __u16 wValue;
+       __u16 wIndex;
+       __u16 wLength;
+
+#ifdef DEBUG
+pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
+#else
+       wait_ms(1);
+#endif
+       if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
+               info("Root-Hub submit IRQ: NOT implemented");
+               return 0;
+       }
+
+       bmRType_bReq  = cmd->requesttype | (cmd->request << 8);
+       wValue        = cpu_to_le16 (cmd->value);
+       wIndex        = cpu_to_le16 (cmd->index);
+       wLength       = cpu_to_le16 (cmd->length);
+
+       info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x",
+               dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength);
+
+       switch (bmRType_bReq) {
+       /* Request Destination:
+          without flags: Device,
+          RH_INTERFACE: interface,
+          RH_ENDPOINT: endpoint,
+          RH_CLASS means HUB here,
+          RH_OTHER | RH_CLASS  almost ever means HUB_PORT here
+       */
+
+       case RH_GET_STATUS:
+                       *(__u16 *) data_buf = cpu_to_le16 (1); OK (2);
+       case RH_GET_STATUS | RH_INTERFACE:
+                       *(__u16 *) data_buf = cpu_to_le16 (0); OK (2);
+       case RH_GET_STATUS | RH_ENDPOINT:
+                       *(__u16 *) data_buf = cpu_to_le16 (0); OK (2);
+       case RH_GET_STATUS | RH_CLASS:
+                       *(__u32 *) data_buf = cpu_to_le32 (
+                               RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));
+                       OK (4);
+       case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+                       *(__u32 *) data_buf = cpu_to_le32 (RD_RH_PORTSTAT); OK (4);
+
+       case RH_CLEAR_FEATURE | RH_ENDPOINT:
+               switch (wValue) {
+                       case (RH_ENDPOINT_STALL): OK (0);
+               }
+               break;
+
+       case RH_CLEAR_FEATURE | RH_CLASS:
+               switch (wValue) {
+                       case RH_C_HUB_LOCAL_POWER:
+                               OK(0);
+                       case (RH_C_HUB_OVER_CURRENT):
+                                       WR_RH_STAT(RH_HS_OCIC); OK (0);
+               }
+               break;
+
+       case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+               switch (wValue) {
+                       case (RH_PORT_ENABLE):
+                                       WR_RH_PORTSTAT (RH_PS_CCS ); OK (0);
+                       case (RH_PORT_SUSPEND):
+                                       WR_RH_PORTSTAT (RH_PS_POCI); OK (0);
+                       case (RH_PORT_POWER):
+                                       WR_RH_PORTSTAT (RH_PS_LSDA); OK (0);
+                       case (RH_C_PORT_CONNECTION):
+                                       WR_RH_PORTSTAT (RH_PS_CSC ); OK (0);
+                       case (RH_C_PORT_ENABLE):
+                                       WR_RH_PORTSTAT (RH_PS_PESC); OK (0);
+                       case (RH_C_PORT_SUSPEND):
+                                       WR_RH_PORTSTAT (RH_PS_PSSC); OK (0);
+                       case (RH_C_PORT_OVER_CURRENT):
+                                       WR_RH_PORTSTAT (RH_PS_OCIC); OK (0);
+                       case (RH_C_PORT_RESET):
+                                       WR_RH_PORTSTAT (RH_PS_PRSC); OK (0);
+               }
+               break;
+
+       case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+               switch (wValue) {
+                       case (RH_PORT_SUSPEND):
+                                       WR_RH_PORTSTAT (RH_PS_PSS ); OK (0);
+                       case (RH_PORT_RESET): /* BUG IN HUP CODE *********/
+                                       if (RD_RH_PORTSTAT & RH_PS_CCS)
+                                           WR_RH_PORTSTAT (RH_PS_PRS);
+                                       OK (0);
+                       case (RH_PORT_POWER):
+                                       WR_RH_PORTSTAT (RH_PS_PPS );
+                                       wait_ms(100);
+                                       OK (0);
+                       case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/
+                                       if (RD_RH_PORTSTAT & RH_PS_CCS)
+                                           WR_RH_PORTSTAT (RH_PS_PES );
+                                       OK (0);
+               }
+               break;
+
+       case RH_SET_ADDRESS: gohci.rh.devnum = wValue; OK(0);
+
+       case RH_GET_DESCRIPTOR:
+               switch ((wValue & 0xff00) >> 8) {
+                       case (0x01): /* device descriptor */
+                               len = min_t(unsigned int,
+                                         leni,
+                                         min_t(unsigned int,
+                                             sizeof (root_hub_dev_des),
+                                             wLength));
+                               data_buf = root_hub_dev_des; OK(len);
+                       case (0x02): /* configuration descriptor */
+                               len = min_t(unsigned int,
+                                         leni,
+                                         min_t(unsigned int,
+                                             sizeof (root_hub_config_des),
+                                             wLength));
+                               data_buf = root_hub_config_des; OK(len);
+                       case (0x03): /* string descriptors */
+                               if(wValue==0x0300) {
+                                       len = min_t(unsigned int,
+                                                 leni,
+                                                 min_t(unsigned int,
+                                                     sizeof (root_hub_str_index0),
+                                                     wLength));
+                                       data_buf = root_hub_str_index0;
+                                       OK(len);
+                               }
+                               if(wValue==0x0301) {
+                                       len = min_t(unsigned int,
+                                                 leni,
+                                                 min_t(unsigned int,
+                                                     sizeof (root_hub_str_index1),
+                                                     wLength));
+                                       data_buf = root_hub_str_index1;
+                                       OK(len);
+                       }
+                       default:
+                               stat = USB_ST_STALLED;
+               }
+               break;
+
+       case RH_GET_DESCRIPTOR | RH_CLASS:
+       {
+               __u32 temp = roothub_a (&gohci);
+
+               data_buf [0] = 9;               /* min length; */
+               data_buf [1] = 0x29;
+               data_buf [2] = temp & RH_A_NDP;
+#ifdef CONFIG_AT91C_PQFP_UHPBUG
+               data_buf [2] = (data_buf [2] == 2) ? 1:0;
+#endif
+               data_buf [3] = 0;
+               if (temp & RH_A_PSM)    /* per-port power switching? */
+                       data_buf [3] |= 0x1;
+               if (temp & RH_A_NOCP)   /* no overcurrent reporting? */
+                       data_buf [3] |= 0x10;
+               else if (temp & RH_A_OCPM)      /* per-port overcurrent reporting? */
+                       data_buf [3] |= 0x8;
+
+               /* corresponds to data_buf[4-7] */
+               datab [1] = 0;
+               data_buf [5] = (temp & RH_A_POTPGT) >> 24;
+               temp = roothub_b (&gohci);
+               data_buf [7] = temp & RH_B_DR;
+               if (data_buf [2] < 7) {
+                       data_buf [8] = 0xff;
+               } else {
+                       data_buf [0] += 2;
+                       data_buf [8] = (temp & RH_B_DR) >> 8;
+                       data_buf [10] = data_buf [9] = 0xff;
+               }
+
+               len = min_t(unsigned int, leni,
+                           min_t(unsigned int, data_buf [0], wLength));
+               OK (len);
+       }
+
+       case RH_GET_CONFIGURATION:      *(__u8 *) data_buf = 0x01; OK (1);
+
+       case RH_SET_CONFIGURATION:      WR_RH_STAT (0x10000); OK (0);
+
+       default:
+               dbg ("unsupported root hub command");
+               stat = USB_ST_STALLED;
+       }
+
+#ifdef DEBUG
+       ohci_dump_roothub (&gohci, 1);
+#else
+       wait_ms(1);
+#endif
+
+       len = min_t(int, len, leni);
+       if (data != data_buf)
+           memcpy (data, data_buf, len);
+       dev->act_len = len;
+       dev->status = stat;
+
+#ifdef DEBUG
+       pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/);
+#else
+       wait_ms(1);
+#endif
+
+       return stat;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* common code for handling submit messages - used for all but root hub */
+/* accesses. */
+int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+               int transfer_len, struct devrequest *setup, int interval)
+{
+       int stat = 0;
+       int maxsize = usb_maxpacket(dev, pipe);
+       int timeout;
+       urb_priv_t *urb;
+
+       urb = malloc(sizeof(urb_priv_t));
+       memset(urb, 0, sizeof(urb_priv_t));
+
+       urb->dev = dev;
+       urb->pipe = pipe;
+       urb->transfer_buffer = buffer;
+       urb->transfer_buffer_length = transfer_len;
+       urb->interval = interval;
+
+       /* device pulled? Shortcut the action. */
+       if (devgone == dev) {
+               dev->status = USB_ST_CRC_ERR;
+               return 0;
+       }
+
+#ifdef DEBUG
+       urb->actual_length = 0;
+       pkt_print(urb, dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
+#else
+       wait_ms(1);
+#endif
+       if (!maxsize) {
+               err("submit_common_message: pipesize for pipe %lx is zero",
+                       pipe);
+               return -1;
+       }
+
+       if (sohci_submit_job(urb, setup) < 0) {
+               err("sohci_submit_job failed");
+               return -1;
+       }
+
+#if 0
+       wait_ms(10);
+       /* ohci_dump_status(&gohci); */
+#endif
+
+       /* allow more time for a BULK device to react - some are slow */
+#define BULK_TO         5000   /* timeout in milliseconds */
+       if (usb_pipetype (pipe) == PIPE_BULK)
+               timeout = BULK_TO;
+       else
+               timeout = 100;
+
+       /* wait for it to complete */
+       for (;;) {
+               /* check whether the controller is done */
+               stat = hc_interrupt();
+               if (stat < 0) {
+                       stat = USB_ST_CRC_ERR;
+                       break;
+               }
+
+               /* NOTE: since we are not interrupt driven in U-Boot and always
+                * handle only one URB at a time, we cannot assume the
+                * transaction finished on the first successful return from
+                * hc_interrupt().. unless the flag for current URB is set,
+                * meaning that all TD's to/from device got actually
+                * transferred and processed. If the current URB is not
+                * finished we need to re-iterate this loop so as
+                * hc_interrupt() gets called again as there needs to be some
+                * more TD's to process still */
+               if ((stat >= 0) && (stat != 0xff) && (urb->finished)) {
+                       /* 0xff is returned for an SF-interrupt */
+                       break;
+               }
+
+               if (--timeout) {
+                       wait_ms(1);
+                       if (!urb->finished)
+                               dbg("\%");
+
+               } else {
+                       err("CTL:TIMEOUT ");
+                       dbg("submit_common_msg: TO status %x\n", stat);
+                       urb->finished = 1;
+                       stat = USB_ST_CRC_ERR;
+                       break;
+               }
+       }
+
+       dev->status = stat;
+       dev->act_len = transfer_len;
+
+#ifdef DEBUG
+       pkt_print(urb, dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe));
+#else
+       wait_ms(1);
+#endif
+
+       /* free TDs in urb_priv */
+       if (usb_pipetype (pipe) != PIPE_INTERRUPT)
+               urb_free_priv (urb);
+       return 0;
+}
+
+/* submit routines called from usb.c */
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+               int transfer_len)
+{
+       info("submit_bulk_msg");
+       return submit_common_msg(dev, pipe, buffer, transfer_len, NULL, 0);
+}
+
+int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+               int transfer_len, struct devrequest *setup)
+{
+       int maxsize = usb_maxpacket(dev, pipe);
+
+       info("submit_control_msg");
+#ifdef DEBUG
+       pkt_print(NULL, dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
+#else
+       wait_ms(1);
+#endif
+       if (!maxsize) {
+               err("submit_control_message: pipesize for pipe %lx is zero",
+                       pipe);
+               return -1;
+       }
+       if (((pipe >> 8) & 0x7f) == gohci.rh.devnum) {
+               gohci.rh.dev = dev;
+               /* root hub - redirect */
+               return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len,
+                       setup);
+       }
+
+       return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0);
+}
+
+int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+               int transfer_len, int interval)
+{
+       info("submit_int_msg");
+       return submit_common_msg(dev, pipe, buffer, transfer_len, NULL,
+                       interval);
+}
+
+/*-------------------------------------------------------------------------*
+ * HC functions
+ *-------------------------------------------------------------------------*/
+
+/* reset the HC and BUS */
+
+static int hc_reset (ohci_t *ohci)
+{
+       int timeout = 30;
+       int smm_timeout = 50; /* 0,5 sec */
+
+       dbg("%s\n", __FUNCTION__);
+
+       if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */
+               writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */
+               info("USB HC TakeOver from SMM");
+               while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
+                       wait_ms (10);
+                       if (--smm_timeout == 0) {
+                               err("USB HC TakeOver failed!");
+                               return -1;
+                       }
+               }
+       }
+
+       /* Disable HC interrupts */
+       writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
+
+       dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;\n",
+               ohci->slot_name,
+               readl(&ohci->regs->control));
+
+       /* Reset USB (needed by some controllers) */
+       ohci->hc_control = 0;
+       writel (ohci->hc_control, &ohci->regs->control);
+
+       /* HC Reset requires max 10 us delay */
+       writel (OHCI_HCR,  &ohci->regs->cmdstatus);
+       while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
+               if (--timeout == 0) {
+                       err("USB HC reset timed out!");
+                       return -1;
+               }
+               udelay (1);
+       }
+       return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* Start an OHCI controller, set the BUS operational
+ * enable interrupts
+ * connect the virtual root hub */
+
+static int hc_start (ohci_t * ohci)
+{
+       __u32 mask;
+       unsigned int fminterval;
+
+       ohci->disabled = 1;
+
+       /* Tell the controller where the control and bulk lists are
+        * The lists are empty now. */
+
+       writel (0, &ohci->regs->ed_controlhead);
+       writel (0, &ohci->regs->ed_bulkhead);
+
+       writel ((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */
+
+       fminterval = 0x2edf;
+       writel ((fminterval * 9) / 10, &ohci->regs->periodicstart);
+       fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
+       writel (fminterval, &ohci->regs->fminterval);
+       writel (0x628, &ohci->regs->lsthresh);
+
+       /* start controller operations */
+       ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
+       ohci->disabled = 0;
+       writel (ohci->hc_control, &ohci->regs->control);
+
+       /* disable all interrupts */
+       mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD |
+                       OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC |
+                       OHCI_INTR_OC | OHCI_INTR_MIE);
+       writel (mask, &ohci->regs->intrdisable);
+       /* clear all interrupts */
+       mask &= ~OHCI_INTR_MIE;
+       writel (mask, &ohci->regs->intrstatus);
+       /* Choose the interrupts we care about now  - but w/o MIE */
+       mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO;
+       writel (mask, &ohci->regs->intrenable);
+
+#ifdef OHCI_USE_NPS
+       /* required for AMD-756 and some Mac platforms */
+       writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM,
+               &ohci->regs->roothub.a);
+       writel (RH_HS_LPSC, &ohci->regs->roothub.status);
+#endif /* OHCI_USE_NPS */
+
+#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);})
+       /* POTPGT delay is bits 24-31, in 2 ms units. */
+       mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
+
+       /* connect the virtual root hub */
+       ohci->rh.devnum = 0;
+
+       return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* Poll USB interrupt. */
+void usb_event_poll(void)
+{
+       hc_interrupt();
+}
+
+/* an interrupt happens */
+
+static int hc_interrupt (void)
+{
+       ohci_t *ohci = &gohci;
+       struct ohci_regs *regs = ohci->regs;
+       int ints;
+       int stat = -1;
+
+       if ((ohci->hcca->done_head != 0) &&
+           !(m32_swap (ohci->hcca->done_head) & 0x01)) {
+               ints =  OHCI_INTR_WDH;
+       } else if ((ints = readl (&regs->intrstatus)) == ~(u32)0) {
+               ohci->disabled++;
+               err ("%s device removed!", ohci->slot_name);
+               return -1;
+       } else if ((ints &= readl (&regs->intrenable)) == 0) {
+               dbg("hc_interrupt: returning..\n");
+               return 0xff;
+       }
+
+       /* dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); */
+
+       if (ints & OHCI_INTR_RHSC) {
+               got_rhsc = 1;
+               stat = 0xff;
+       }
+
+       if (ints & OHCI_INTR_UE) {
+               ohci->disabled++;
+               err ("OHCI Unrecoverable Error, controller usb-%s disabled",
+                       ohci->slot_name);
+               /* e.g. due to PCI Master/Target Abort */
+
+#ifdef DEBUG
+               ohci_dump (ohci, 1);
+#else
+       wait_ms(1);
+#endif
+               /* FIXME: be optimistic, hope that bug won't repeat often. */
+               /* Make some non-interrupt context restart the controller. */
+               /* Count and limit the retries though; either hardware or */
+               /* software errors can go forever... */
+               hc_reset (ohci);
+               return -1;
+       }
+
+       if (ints & OHCI_INTR_WDH) {
+               wait_ms(1);
+               writel (OHCI_INTR_WDH, &regs->intrdisable);
+               (void)readl (&regs->intrdisable); /* flush */
+               stat = dl_done_list (&gohci, dl_reverse_done_list (&gohci));
+               writel (OHCI_INTR_WDH, &regs->intrenable);
+               (void)readl (&regs->intrdisable); /* flush */
+       }
+
+       if (ints & OHCI_INTR_SO) {
+               dbg("USB Schedule overrun\n");
+               writel (OHCI_INTR_SO, &regs->intrenable);
+               stat = -1;
+       }
+
+       /* FIXME:  this assumes SOF (1/ms) interrupts don't get lost... */
+       if (ints & OHCI_INTR_SF) {
+               unsigned int frame = m16_swap (ohci->hcca->frame_no) & 1;
+               wait_ms(1);
+               writel (OHCI_INTR_SF, &regs->intrdisable);
+               if (ohci->ed_rm_list[frame] != NULL)
+                       writel (OHCI_INTR_SF, &regs->intrenable);
+               stat = 0xff;
+       }
+
+       writel (ints, &regs->intrstatus);
+       return stat;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------*/
+
+/* De-allocate all resources.. */
+
+static void hc_release_ohci (ohci_t *ohci)
+{
+       dbg ("USB HC release ohci usb-%s", ohci->slot_name);
+
+       if (!ohci->disabled)
+               hc_reset (ohci);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * low level initalisation routine, called from usb.c
+ */
+static char ohci_inited = 0;
+
+int usb_lowlevel_init(void)
+{
+#ifdef CONFIG_PCI_OHCI
+       pci_dev_t pdev;
+#endif
+
+#ifdef CFG_USB_OHCI_CPU_INIT
+       /* cpu dependant init */
+       if(usb_cpu_init())
+               return -1;
+#endif
+
+#ifdef CFG_USB_OHCI_BOARD_INIT
+       /*  board dependant init */
+       if(usb_board_init())
+               return -1;
+#endif
+       memset (&gohci, 0, sizeof (ohci_t));
+
+       /* align the storage */
+       if ((__u32)&ghcca[0] & 0xff) {
+               err("HCCA not aligned!!");
+               return -1;
+       }
+       phcca = &ghcca[0];
+       info("aligned ghcca %p", phcca);
+       memset(&ohci_dev, 0, sizeof(struct ohci_device));
+       if ((__u32)&ohci_dev.ed[0] & 0x7) {
+               err("EDs not aligned!!");
+               return -1;
+       }
+       memset(gtd, 0, sizeof(td_t) * (NUM_TD + 1));
+       if ((__u32)gtd & 0x7) {
+               err("TDs not aligned!!");
+               return -1;
+       }
+       ptd = gtd;
+       gohci.hcca = phcca;
+       memset (phcca, 0, sizeof (struct ohci_hcca));
+
+       gohci.disabled = 1;
+       gohci.sleeping = 0;
+       gohci.irq = -1;
+#ifdef CONFIG_PCI_OHCI
+       pdev = pci_find_devices(ohci_pci_ids, 0);
+
+       if (pdev != -1) {
+               u16 vid, did;
+               u32 base;
+               pci_read_config_word(pdev, PCI_VENDOR_ID, &vid);
+               pci_read_config_word(pdev, PCI_DEVICE_ID, &did);
+               printf("OHCI pci controller (%04x, %04x) found @(%d:%d:%d)\n",
+                               vid, did, (pdev >> 16) & 0xff,
+                               (pdev >> 11) & 0x1f, (pdev >> 8) & 0x7);
+               pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &base);
+               printf("OHCI regs address 0x%08x\n", base);
+               gohci.regs = (struct ohci_regs *)base;
+       } else
+               return -1;
+#else
+       gohci.regs = (struct ohci_regs *)CFG_USB_OHCI_REGS_BASE;
+#endif
+
+       gohci.flags = 0;
+       gohci.slot_name = CFG_USB_OHCI_SLOT_NAME;
+
+       if (hc_reset (&gohci) < 0) {
+               hc_release_ohci (&gohci);
+               err ("can't reset usb-%s", gohci.slot_name);
+#ifdef CFG_USB_OHCI_BOARD_INIT
+               /* board dependant cleanup */
+               usb_board_init_fail();
+#endif
+
+#ifdef CFG_USB_OHCI_CPU_INIT
+               /* cpu dependant cleanup */
+               usb_cpu_init_fail();
+#endif
+               return -1;
+       }
+
+       /* FIXME this is a second HC reset; why?? */
+       /* writel(gohci.hc_control = OHCI_USB_RESET, &gohci.regs->control);
+          wait_ms(10); */
+       if (hc_start (&gohci) < 0) {
+               err ("can't start usb-%s", gohci.slot_name);
+               hc_release_ohci (&gohci);
+               /* Initialization failed */
+#ifdef CFG_USB_OHCI_BOARD_INIT
+               /* board dependant cleanup */
+               usb_board_stop();
+#endif
+
+#ifdef CFG_USB_OHCI_CPU_INIT
+               /* cpu dependant cleanup */
+               usb_cpu_stop();
+#endif
+               return -1;
+       }
+
+#ifdef DEBUG
+       ohci_dump (&gohci, 1);
+#else
+       wait_ms(1);
+#endif
+       ohci_inited = 1;
+       return 0;
+}
+
+int usb_lowlevel_stop(void)
+{
+       /* this gets called really early - before the controller has */
+       /* even been initialized! */
+       if (!ohci_inited)
+               return 0;
+       /* TODO release any interrupts, etc. */
+       /* call hc_release_ohci() here ? */
+       hc_reset (&gohci);
+
+#ifdef CFG_USB_OHCI_BOARD_INIT
+       /* board dependant cleanup */
+       if(usb_board_stop())
+               return -1;
+#endif
+
+#ifdef CFG_USB_OHCI_CPU_INIT
+       /* cpu dependant cleanup */
+       if(usb_cpu_stop())
+               return -1;
+#endif
+
+       return 0;
+}
+#endif /* CONFIG_USB_OHCI_NEW */
diff --git a/drivers/usb/usb_ohci.h b/drivers/usb/usb_ohci.h
new file mode 100644 (file)
index 0000000..380cb4c
--- /dev/null
@@ -0,0 +1,445 @@
+/*
+ * URB OHCI HCD (Host Controller Driver) for USB.
+ *
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ * (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net>
+ *
+ * usb-ohci.h
+ */
+
+/* functions for doing board or CPU specific setup/cleanup */
+extern int usb_board_init(void);
+extern int usb_board_stop(void);
+extern int usb_board_init_fail(void);
+
+extern int usb_cpu_init(void);
+extern int usb_cpu_stop(void);
+extern int usb_cpu_init_fail(void);
+
+
+static int cc_to_error[16] = {
+
+/* mapping of the OHCI CC status to error codes */
+       /* No  Error  */               0,
+       /* CRC Error  */               USB_ST_CRC_ERR,
+       /* Bit Stuff  */               USB_ST_BIT_ERR,
+       /* Data Togg  */               USB_ST_CRC_ERR,
+       /* Stall      */               USB_ST_STALLED,
+       /* DevNotResp */               -1,
+       /* PIDCheck   */               USB_ST_BIT_ERR,
+       /* UnExpPID   */               USB_ST_BIT_ERR,
+       /* DataOver   */               USB_ST_BUF_ERR,
+       /* DataUnder  */               USB_ST_BUF_ERR,
+       /* reservd    */               -1,
+       /* reservd    */               -1,
+       /* BufferOver */               USB_ST_BUF_ERR,
+       /* BuffUnder  */               USB_ST_BUF_ERR,
+       /* Not Access */               -1,
+       /* Not Access */               -1
+};
+
+/* ED States */
+
+#define ED_NEW         0x00
+#define ED_UNLINK      0x01
+#define ED_OPER                0x02
+#define ED_DEL         0x04
+#define ED_URB_DEL     0x08
+
+/* usb_ohci_ed */
+struct ed {
+       __u32 hwINFO;
+       __u32 hwTailP;
+       __u32 hwHeadP;
+       __u32 hwNextED;
+
+       struct ed *ed_prev;
+       __u8 int_period;
+       __u8 int_branch;
+       __u8 int_load;
+       __u8 int_interval;
+       __u8 state;
+       __u8 type;
+       __u16 last_iso;
+       struct ed *ed_rm_list;
+
+       struct usb_device *usb_dev;
+       void *purb;
+       __u32 unused[2];
+} __attribute((aligned(16)));
+typedef struct ed ed_t;
+
+
+/* TD info field */
+#define TD_CC      0xf0000000
+#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f)
+#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)
+#define TD_EC      0x0C000000
+#define TD_T       0x03000000
+#define TD_T_DATA0  0x02000000
+#define TD_T_DATA1  0x03000000
+#define TD_T_TOGGLE 0x00000000
+#define TD_R       0x00040000
+#define TD_DI      0x00E00000
+#define TD_DI_SET(X) (((X) & 0x07)<< 21)
+#define TD_DP      0x00180000
+#define TD_DP_SETUP 0x00000000
+#define TD_DP_IN    0x00100000
+#define TD_DP_OUT   0x00080000
+
+#define TD_ISO     0x00010000
+#define TD_DEL     0x00020000
+
+/* CC Codes */
+#define TD_CC_NOERROR     0x00
+#define TD_CC_CRC         0x01
+#define TD_CC_BITSTUFFING  0x02
+#define TD_CC_DATATOGGLEM  0x03
+#define TD_CC_STALL       0x04
+#define TD_DEVNOTRESP     0x05
+#define TD_PIDCHECKFAIL           0x06
+#define TD_UNEXPECTEDPID   0x07
+#define TD_DATAOVERRUN    0x08
+#define TD_DATAUNDERRUN           0x09
+#define TD_BUFFEROVERRUN   0x0C
+#define TD_BUFFERUNDERRUN  0x0D
+#define TD_NOTACCESSED    0x0F
+
+
+#define MAXPSW 1
+
+struct td {
+       __u32 hwINFO;
+       __u32 hwCBP;            /* Current Buffer Pointer */
+       __u32 hwNextTD;         /* Next TD Pointer */
+       __u32 hwBE;             /* Memory Buffer End Pointer */
+
+/* #ifndef CONFIG_MPC5200 /\* this seems wrong *\/ */
+       __u16 hwPSW[MAXPSW];
+/* #endif */
+       __u8 unused;
+       __u8 index;
+       struct ed *ed;
+       struct td *next_dl_td;
+       struct usb_device *usb_dev;
+       int transfer_len;
+       __u32 data;
+
+       __u32 unused2[2];
+} __attribute((aligned(32)));
+typedef struct td td_t;
+
+#define OHCI_ED_SKIP   (1 << 14)
+
+/*
+ * The HCCA (Host Controller Communications Area) is a 256 byte
+ * structure defined in the OHCI spec. that the host controller is
+ * told the base address of.  It must be 256-byte aligned.
+ */
+
+#define NUM_INTS 32    /* part of the OHCI standard */
+struct ohci_hcca {
+       __u32   int_table[NUM_INTS];    /* Interrupt ED table */
+#if defined(CONFIG_MPC5200)
+       __u16   pad1;                   /* set to 0 on each frame_no change */
+       __u16   frame_no;               /* current frame number */
+#else
+       __u16   frame_no;               /* current frame number */
+       __u16   pad1;                   /* set to 0 on each frame_no change */
+#endif
+       __u32   done_head;              /* info returned for an interrupt */
+       u8              reserved_for_hc[116];
+} __attribute((aligned(256)));
+
+
+/*
+ * Maximum number of root hub ports.
+ */
+#ifndef CFG_USB_OHCI_MAX_ROOT_PORTS
+# error "CFG_USB_OHCI_MAX_ROOT_PORTS undefined!"
+#endif
+
+/*
+ * This is the structure of the OHCI controller's memory mapped I/O
+ * region.  This is Memory Mapped I/O. You must use the readl() and
+ * writel() macros defined in asm/io.h to access these!!
+ */
+struct ohci_regs {
+       /* control and status registers */
+       __u32   revision;
+       __u32   control;
+       __u32   cmdstatus;
+       __u32   intrstatus;
+       __u32   intrenable;
+       __u32   intrdisable;
+       /* memory pointers */
+       __u32   hcca;
+       __u32   ed_periodcurrent;
+       __u32   ed_controlhead;
+       __u32   ed_controlcurrent;
+       __u32   ed_bulkhead;
+       __u32   ed_bulkcurrent;
+       __u32   donehead;
+       /* frame counters */
+       __u32   fminterval;
+       __u32   fmremaining;
+       __u32   fmnumber;
+       __u32   periodicstart;
+       __u32   lsthresh;
+       /* Root hub ports */
+       struct  ohci_roothub_regs {
+               __u32   a;
+               __u32   b;
+               __u32   status;
+               __u32   portstatus[CFG_USB_OHCI_MAX_ROOT_PORTS];
+       } roothub;
+} __attribute((aligned(32)));
+
+
+/* OHCI CONTROL AND STATUS REGISTER MASKS */
+
+/*
+ * HcControl (control) register masks
+ */
+#define OHCI_CTRL_CBSR (3 << 0)        /* control/bulk service ratio */
+#define OHCI_CTRL_PLE  (1 << 2)        /* periodic list enable */
+#define OHCI_CTRL_IE   (1 << 3)        /* isochronous enable */
+#define OHCI_CTRL_CLE  (1 << 4)        /* control list enable */
+#define OHCI_CTRL_BLE  (1 << 5)        /* bulk list enable */
+#define OHCI_CTRL_HCFS (3 << 6)        /* host controller functional state */
+#define OHCI_CTRL_IR   (1 << 8)        /* interrupt routing */
+#define OHCI_CTRL_RWC  (1 << 9)        /* remote wakeup connected */
+#define OHCI_CTRL_RWE  (1 << 10)       /* remote wakeup enable */
+
+/* pre-shifted values for HCFS */
+#      define OHCI_USB_RESET   (0 << 6)
+#      define OHCI_USB_RESUME  (1 << 6)
+#      define OHCI_USB_OPER    (2 << 6)
+#      define OHCI_USB_SUSPEND (3 << 6)
+
+/*
+ * HcCommandStatus (cmdstatus) register masks
+ */
+#define OHCI_HCR       (1 << 0)        /* host controller reset */
+#define OHCI_CLF       (1 << 1)        /* control list filled */
+#define OHCI_BLF       (1 << 2)        /* bulk list filled */
+#define OHCI_OCR       (1 << 3)        /* ownership change request */
+#define OHCI_SOC       (3 << 16)       /* scheduling overrun count */
+
+/*
+ * masks used with interrupt registers:
+ * HcInterruptStatus (intrstatus)
+ * HcInterruptEnable (intrenable)
+ * HcInterruptDisable (intrdisable)
+ */
+#define OHCI_INTR_SO   (1 << 0)        /* scheduling overrun */
+#define OHCI_INTR_WDH  (1 << 1)        /* writeback of done_head */
+#define OHCI_INTR_SF   (1 << 2)        /* start frame */
+#define OHCI_INTR_RD   (1 << 3)        /* resume detect */
+#define OHCI_INTR_UE   (1 << 4)        /* unrecoverable error */
+#define OHCI_INTR_FNO  (1 << 5)        /* frame number overflow */
+#define OHCI_INTR_RHSC (1 << 6)        /* root hub status change */
+#define OHCI_INTR_OC   (1 << 30)       /* ownership change */
+#define OHCI_INTR_MIE  (1 << 31)       /* master interrupt enable */
+
+
+/* Virtual Root HUB */
+struct virt_root_hub {
+       int devnum; /* Address of Root Hub endpoint */
+       void *dev;  /* was urb */
+       void *int_addr;
+       int send;
+       int interval;
+};
+
+/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */
+
+/* destination of request */
+#define RH_INTERFACE              0x01
+#define RH_ENDPOINT               0x02
+#define RH_OTHER                  0x03
+
+#define RH_CLASS                  0x20
+#define RH_VENDOR                 0x40
+
+/* Requests: bRequest << 8 | bmRequestType */
+#define RH_GET_STATUS          0x0080
+#define RH_CLEAR_FEATURE       0x0100
+#define RH_SET_FEATURE         0x0300
+#define RH_SET_ADDRESS         0x0500
+#define RH_GET_DESCRIPTOR      0x0680
+#define RH_SET_DESCRIPTOR      0x0700
+#define RH_GET_CONFIGURATION   0x0880
+#define RH_SET_CONFIGURATION   0x0900
+#define RH_GET_STATE           0x0280
+#define RH_GET_INTERFACE       0x0A80
+#define RH_SET_INTERFACE       0x0B00
+#define RH_SYNC_FRAME          0x0C80
+/* Our Vendor Specific Request */
+#define RH_SET_EP              0x2000
+
+
+/* Hub port features */
+#define RH_PORT_CONNECTION        0x00
+#define RH_PORT_ENABLE            0x01
+#define RH_PORT_SUSPEND                   0x02
+#define RH_PORT_OVER_CURRENT      0x03
+#define RH_PORT_RESET             0x04
+#define RH_PORT_POWER             0x08
+#define RH_PORT_LOW_SPEED         0x09
+
+#define RH_C_PORT_CONNECTION      0x10
+#define RH_C_PORT_ENABLE          0x11
+#define RH_C_PORT_SUSPEND         0x12
+#define RH_C_PORT_OVER_CURRENT    0x13
+#define RH_C_PORT_RESET                   0x14
+
+/* Hub features */
+#define RH_C_HUB_LOCAL_POWER      0x00
+#define RH_C_HUB_OVER_CURRENT     0x01
+
+#define RH_DEVICE_REMOTE_WAKEUP           0x00
+#define RH_ENDPOINT_STALL         0x01
+
+#define RH_ACK                    0x01
+#define RH_REQ_ERR                -1
+#define RH_NACK                           0x00
+
+
+/* OHCI ROOT HUB REGISTER MASKS */
+
+/* roothub.portstatus [i] bits */
+#define RH_PS_CCS           0x00000001         /* current connect status */
+#define RH_PS_PES           0x00000002         /* port enable status*/
+#define RH_PS_PSS           0x00000004         /* port suspend status */
+#define RH_PS_POCI          0x00000008         /* port over current indicator */
+#define RH_PS_PRS           0x00000010         /* port reset status */
+#define RH_PS_PPS           0x00000100         /* port power status */
+#define RH_PS_LSDA          0x00000200         /* low speed device attached */
+#define RH_PS_CSC           0x00010000         /* connect status change */
+#define RH_PS_PESC          0x00020000         /* port enable status change */
+#define RH_PS_PSSC          0x00040000         /* port suspend status change */
+#define RH_PS_OCIC          0x00080000         /* over current indicator change */
+#define RH_PS_PRSC          0x00100000         /* port reset status change */
+
+/* roothub.status bits */
+#define RH_HS_LPS           0x00000001         /* local power status */
+#define RH_HS_OCI           0x00000002         /* over current indicator */
+#define RH_HS_DRWE          0x00008000         /* device remote wakeup enable */
+#define RH_HS_LPSC          0x00010000         /* local power status change */
+#define RH_HS_OCIC          0x00020000         /* over current indicator change */
+#define RH_HS_CRWE          0x80000000         /* clear remote wakeup enable */
+
+/* roothub.b masks */
+#define RH_B_DR                0x0000ffff              /* device removable flags */
+#define RH_B_PPCM      0xffff0000              /* port power control mask */
+
+/* roothub.a masks */
+#define RH_A_NDP       (0xff << 0)             /* number of downstream ports */
+#define RH_A_PSM       (1 << 8)                /* power switching mode */
+#define RH_A_NPS       (1 << 9)                /* no power switching */
+#define RH_A_DT                (1 << 10)               /* device type (mbz) */
+#define RH_A_OCPM      (1 << 11)               /* over current protection mode */
+#define RH_A_NOCP      (1 << 12)               /* no over current protection */
+#define RH_A_POTPGT    (0xff << 24)            /* power on to power good time */
+
+/* urb */
+#define N_URB_TD 48
+typedef struct
+{
+       ed_t *ed;
+       __u16 length;   /* number of tds associated with this request */
+       __u16 td_cnt;   /* number of tds already serviced */
+       struct usb_device *dev;
+       int   state;
+       unsigned long pipe;
+       void *transfer_buffer;
+       int transfer_buffer_length;
+       int interval;
+       int actual_length;
+       int finished;
+       td_t *td[N_URB_TD];     /* list pointer to all corresponding TDs associated with this request */
+} urb_priv_t;
+#define URB_DEL 1
+
+/*
+ * This is the full ohci controller description
+ *
+ * Note how the "proper" USB information is just
+ * a subset of what the full implementation needs. (Linus)
+ */
+
+
+typedef struct ohci {
+       struct ohci_hcca *hcca;         /* hcca */
+       /*dma_addr_t hcca_dma;*/
+
+       int irq;
+       int disabled;                   /* e.g. got a UE, we're hung */
+       int sleeping;
+       unsigned long flags;            /* for HC bugs */
+
+       struct ohci_regs *regs; /* OHCI controller's memory */
+
+       int ohci_int_load[32];   /* load of the 32 Interrupt Chains (for load balancing)*/
+       ed_t *ed_rm_list[2];     /* lists of all endpoints to be removed */
+       ed_t *ed_bulktail;       /* last endpoint of bulk list */
+       ed_t *ed_controltail;    /* last endpoint of control list */
+       int intrstatus;
+       __u32 hc_control;               /* copy of the hc control reg */
+       struct usb_device *dev[32];
+       struct virt_root_hub rh;
+
+       const char      *slot_name;
+} ohci_t;
+
+#define NUM_EDS 8              /* num of preallocated endpoint descriptors */
+
+struct ohci_device {
+       ed_t    ed[NUM_EDS];
+       int ed_cnt;
+};
+
+/* hcd */
+/* endpoint */
+static int ep_link(ohci_t * ohci, ed_t * ed);
+static int ep_unlink(ohci_t * ohci, ed_t * ed);
+static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned long pipe,
+               int interval, int load);
+
+/*-------------------------------------------------------------------------*/
+
+/* we need more TDs than EDs */
+#define NUM_TD 64
+
+/* +1 so we can align the storage */
+td_t gtd[NUM_TD+1];
+/* pointers to aligned storage */
+td_t *ptd;
+
+/* TDs ... */
+static inline struct td *
+td_alloc (struct usb_device *usb_dev)
+{
+       int i;
+       struct td       *td;
+
+       td = NULL;
+       for (i = 0; i < NUM_TD; i++)
+       {
+               if (ptd[i].usb_dev == NULL)
+               {
+                       td = &ptd[i];
+                       td->usb_dev = usb_dev;
+                       break;
+               }
+       }
+
+       return td;
+}
+
+static inline void
+ed_free (struct ed *ed)
+{
+       ed->usb_dev = NULL;
+}
diff --git a/drivers/usb/usbdcore.c b/drivers/usb/usbdcore.c
new file mode 100644 (file)
index 0000000..308c7ce
--- /dev/null
@@ -0,0 +1,684 @@
+/*
+ * (C) Copyright 2003
+ * Gerry Hamel, geh@ti.com, Texas Instruments
+ *
+ * Based on
+ * linux/drivers/usbd/usbd.c.c - USB Device Core Layer
+ *
+ * Copyright (c) 2000, 2001, 2002 Lineo
+ * Copyright (c) 2001 Hewlett Packard
+ *
+ * By:
+ *     Stuart Lynne <sl@lineo.com>,
+ *     Tom Rushworth <tbr@lineo.com>,
+ *     Bruce Balden <balden@lineo.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <malloc.h>
+#include "usbdcore.h"
+
+#define MAX_INTERFACES 2
+
+
+int maxstrings = 20;
+
+/* Global variables ************************************************************************** */
+
+struct usb_string_descriptor **usb_strings;
+
+int usb_devices;
+
+extern struct usb_function_driver ep0_driver;
+
+int registered_functions;
+int registered_devices;
+
+char *usbd_device_events[] = {
+       "DEVICE_UNKNOWN",
+       "DEVICE_INIT",
+       "DEVICE_CREATE",
+       "DEVICE_HUB_CONFIGURED",
+       "DEVICE_RESET",
+       "DEVICE_ADDRESS_ASSIGNED",
+       "DEVICE_CONFIGURED",
+       "DEVICE_SET_INTERFACE",
+       "DEVICE_SET_FEATURE",
+       "DEVICE_CLEAR_FEATURE",
+       "DEVICE_DE_CONFIGURED",
+       "DEVICE_BUS_INACTIVE",
+       "DEVICE_BUS_ACTIVITY",
+       "DEVICE_POWER_INTERRUPTION",
+       "DEVICE_HUB_RESET",
+       "DEVICE_DESTROY",
+       "DEVICE_FUNCTION_PRIVATE",
+};
+
+char *usbd_device_states[] = {
+       "STATE_INIT",
+       "STATE_CREATED",
+       "STATE_ATTACHED",
+       "STATE_POWERED",
+       "STATE_DEFAULT",
+       "STATE_ADDRESSED",
+       "STATE_CONFIGURED",
+       "STATE_UNKNOWN",
+};
+
+char *usbd_device_requests[] = {
+       "GET STATUS",           /* 0 */
+       "CLEAR FEATURE",        /* 1 */
+       "RESERVED",             /* 2 */
+       "SET FEATURE",          /* 3 */
+       "RESERVED",             /* 4 */
+       "SET ADDRESS",          /* 5 */
+       "GET DESCRIPTOR",       /* 6 */
+       "SET DESCRIPTOR",       /* 7 */
+       "GET CONFIGURATION",    /* 8 */
+       "SET CONFIGURATION",    /* 9 */
+       "GET INTERFACE",        /* 10 */
+       "SET INTERFACE",        /* 11 */
+       "SYNC FRAME",           /* 12 */
+};
+
+char *usbd_device_descriptors[] = {
+       "UNKNOWN",              /* 0 */
+       "DEVICE",               /* 1 */
+       "CONFIG",               /* 2 */
+       "STRING",               /* 3 */
+       "INTERFACE",            /* 4 */
+       "ENDPOINT",             /* 5 */
+       "DEVICE QUALIFIER",     /* 6 */
+       "OTHER SPEED",          /* 7 */
+       "INTERFACE POWER",      /* 8 */
+};
+
+char *usbd_device_status[] = {
+       "USBD_OPENING",
+       "USBD_OK",
+       "USBD_SUSPENDED",
+       "USBD_CLOSING",
+};
+
+
+/* Descriptor support functions ************************************************************** */
+
+
+/**
+ * usbd_get_string - find and return a string descriptor
+ * @index: string index to return
+ *
+ * Find an indexed string and return a pointer to a it.
+ */
+struct usb_string_descriptor *usbd_get_string (__u8 index)
+{
+       if (index >= maxstrings) {
+               return NULL;
+       }
+       return usb_strings[index];
+}
+
+
+/* Access to device descriptor functions ***************************************************** */
+
+
+/* *
+ * usbd_device_configuration_instance - find a configuration instance for this device
+ * @device:
+ * @configuration: index to configuration, 0 - N-1
+ *
+ * Get specifed device configuration. Index should be bConfigurationValue-1.
+ */
+static struct usb_configuration_instance *usbd_device_configuration_instance (struct usb_device_instance *device,
+               unsigned int port, unsigned int configuration)
+{
+       /* XXX */
+       configuration = configuration ? configuration - 1 : 0;
+
+       if (configuration >= device->configurations) {
+               return NULL;
+       }
+       return device->configuration_instance_array + configuration;
+}
+
+
+/* *
+ * usbd_device_interface_instance
+ * @device:
+ * @configuration: index to configuration, 0 - N-1
+ * @interface: index to interface
+ *
+ * Return the specified interface descriptor for the specified device.
+ */
+struct usb_interface_instance *usbd_device_interface_instance (struct usb_device_instance *device, int port, int configuration, int interface)
+{
+       struct usb_configuration_instance *configuration_instance;
+
+       if ((configuration_instance = usbd_device_configuration_instance (device, port, configuration)) == NULL) {
+               return NULL;
+       }
+       if (interface >= configuration_instance->interfaces) {
+               return NULL;
+       }
+       return configuration_instance->interface_instance_array + interface;
+}
+
+/* *
+ * usbd_device_alternate_descriptor_list
+ * @device:
+ * @configuration: index to configuration, 0 - N-1
+ * @interface: index to interface
+ * @alternate: alternate setting
+ *
+ * Return the specified alternate descriptor for the specified device.
+ */
+struct usb_alternate_instance *usbd_device_alternate_instance (struct usb_device_instance *device, int port, int configuration, int interface, int alternate)
+{
+       struct usb_interface_instance *interface_instance;
+
+       if ((interface_instance = usbd_device_interface_instance (device, port, configuration, interface)) == NULL) {
+               return NULL;
+       }
+
+       if (alternate >= interface_instance->alternates) {
+               return NULL;
+       }
+
+       return interface_instance->alternates_instance_array + alternate;
+}
+
+
+/* *
+ * usbd_device_device_descriptor
+ * @device: which device
+ * @configuration: index to configuration, 0 - N-1
+ * @port: which port
+ *
+ * Return the specified configuration descriptor for the specified device.
+ */
+struct usb_device_descriptor *usbd_device_device_descriptor (struct usb_device_instance *device, int port)
+{
+       return (device->device_descriptor);
+}
+
+
+/**
+ * usbd_device_configuration_descriptor
+ * @device: which device
+ * @port: which port
+ * @configuration: index to configuration, 0 - N-1
+ *
+ * Return the specified configuration descriptor for the specified device.
+ */
+struct usb_configuration_descriptor *usbd_device_configuration_descriptor (struct
+                                                                          usb_device_instance
+                                                                          *device, int port, int configuration)
+{
+       struct usb_configuration_instance *configuration_instance;
+       if (!(configuration_instance = usbd_device_configuration_instance (device, port, configuration))) {
+               return NULL;
+       }
+       return (configuration_instance->configuration_descriptor);
+}
+
+
+/**
+ * usbd_device_interface_descriptor
+ * @device: which device
+ * @port: which port
+ * @configuration: index to configuration, 0 - N-1
+ * @interface: index to interface
+ * @alternate: alternate setting
+ *
+ * Return the specified interface descriptor for the specified device.
+ */
+struct usb_interface_descriptor *usbd_device_interface_descriptor (struct usb_device_instance
+                                                                  *device, int port, int configuration, int interface, int alternate)
+{
+       struct usb_interface_instance *interface_instance;
+       if (!(interface_instance = usbd_device_interface_instance (device, port, configuration, interface))) {
+               return NULL;
+       }
+       if ((alternate < 0) || (alternate >= interface_instance->alternates)) {
+               return NULL;
+       }
+       return (interface_instance->alternates_instance_array[alternate].interface_descriptor);
+}
+
+/**
+ * usbd_device_endpoint_descriptor_index
+ * @device: which device
+ * @port: which port
+ * @configuration: index to configuration, 0 - N-1
+ * @interface: index to interface
+ * @alternate: index setting
+ * @index: which index
+ *
+ * Return the specified endpoint descriptor for the specified device.
+ */
+struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor_index (struct usb_device_instance
+                                                                      *device, int port, int configuration, int interface, int alternate, int index)
+{
+       struct usb_alternate_instance *alternate_instance;
+
+       if (!(alternate_instance = usbd_device_alternate_instance (device, port, configuration, interface, alternate))) {
+               return NULL;
+       }
+       if (index >= alternate_instance->endpoints) {
+               return NULL;
+       }
+       return *(alternate_instance->endpoints_descriptor_array + index);
+}
+
+
+/**
+ * usbd_device_endpoint_transfersize
+ * @device: which device
+ * @port: which port
+ * @configuration: index to configuration, 0 - N-1
+ * @interface: index to interface
+ * @index: which index
+ *
+ * Return the specified endpoint transfer size;
+ */
+int usbd_device_endpoint_transfersize (struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int index)
+{
+       struct usb_alternate_instance *alternate_instance;
+
+       if (!(alternate_instance = usbd_device_alternate_instance (device, port, configuration, interface, alternate))) {
+               return 0;
+       }
+       if (index >= alternate_instance->endpoints) {
+               return 0;
+       }
+       return *(alternate_instance->endpoint_transfersize_array + index);
+}
+
+
+/**
+ * usbd_device_endpoint_descriptor
+ * @device: which device
+ * @port: which port
+ * @configuration: index to configuration, 0 - N-1
+ * @interface: index to interface
+ * @alternate: alternate setting
+ * @endpoint: which endpoint
+ *
+ * Return the specified endpoint descriptor for the specified device.
+ */
+struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor (struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int endpoint)
+{
+       struct usb_endpoint_descriptor *endpoint_descriptor;
+       int i;
+
+       for (i = 0; !(endpoint_descriptor = usbd_device_endpoint_descriptor_index (device, port, configuration, interface, alternate, i)); i++) {
+               if (endpoint_descriptor->bEndpointAddress == endpoint) {
+                       return endpoint_descriptor;
+               }
+       }
+       return NULL;
+}
+
+/**
+ * usbd_endpoint_halted
+ * @device: point to struct usb_device_instance
+ * @endpoint: endpoint to check
+ *
+ * Return non-zero if endpoint is halted.
+ */
+int usbd_endpoint_halted (struct usb_device_instance *device, int endpoint)
+{
+       return (device->status == USB_STATUS_HALT);
+}
+
+
+/**
+ * usbd_rcv_complete - complete a receive
+ * @endpoint:
+ * @len:
+ * @urb_bad:
+ *
+ * Called from rcv interrupt to complete.
+ */
+void usbd_rcv_complete(struct usb_endpoint_instance *endpoint, int len, int urb_bad)
+{
+       if (endpoint) {
+               struct urb *rcv_urb;
+
+               /*usbdbg("len: %d urb: %p\n", len, endpoint->rcv_urb); */
+
+               /* if we had an urb then update actual_length, dispatch if neccessary */
+               if ((rcv_urb = endpoint->rcv_urb)) {
+
+                       /*usbdbg("actual: %d buffer: %d\n", */
+                       /*rcv_urb->actual_length, rcv_urb->buffer_length); */
+
+                       /* check the urb is ok, are we adding data less than the packetsize */
+                       if (!urb_bad && (len <= endpoint->rcv_packetSize)) {
+                         /*usbdbg("updating actual_length by %d\n",len); */
+
+                               /* increment the received data size */
+                               rcv_urb->actual_length += len;
+
+                       } else {
+                               usberr(" RECV_ERROR actual: %d buffer: %d urb_bad: %d\n",
+                                      rcv_urb->actual_length, rcv_urb->buffer_length, urb_bad);
+
+                               rcv_urb->actual_length = 0;
+                               rcv_urb->status = RECV_ERROR;
+                       }
+               } else {
+                       usberr("no rcv_urb!");
+               }
+       } else {
+               usberr("no endpoint!");
+       }
+
+}
+
+/**
+ * usbd_tx_complete - complete a transmit
+ * @endpoint:
+ * @resetart:
+ *
+ * Called from tx interrupt to complete.
+ */
+void usbd_tx_complete (struct usb_endpoint_instance *endpoint)
+{
+       if (endpoint) {
+               struct urb *tx_urb;
+
+               /* if we have a tx_urb advance or reset, finish if complete */
+               if ((tx_urb = endpoint->tx_urb)) {
+                       int sent = endpoint->last;
+                       endpoint->sent += sent;
+                       endpoint->last -= sent;
+
+                       if( (endpoint->tx_urb->actual_length - endpoint->sent) <= 0 ) {
+                               tx_urb->actual_length = 0;
+                               endpoint->sent = 0;
+                               endpoint->last = 0;
+
+                               /* Remove from active, save for re-use */
+                               urb_detach(tx_urb);
+                               urb_append(&endpoint->done, tx_urb);
+                               /*usbdbg("done->next %p, tx_urb %p, done %p", */
+                               /*       endpoint->done.next, tx_urb, &endpoint->done); */
+
+                               endpoint->tx_urb = first_urb_detached(&endpoint->tx);
+                               if( endpoint->tx_urb ) {
+                                       endpoint->tx_queue--;
+                                       usbdbg("got urb from tx list");
+                               }
+                               if( !endpoint->tx_urb ) {
+                                       /*usbdbg("taking urb from done list"); */
+                                       endpoint->tx_urb = first_urb_detached(&endpoint->done);
+                               }
+                               if( !endpoint->tx_urb ) {
+                                       usbdbg("allocating new urb for tx_urb");
+                                       endpoint->tx_urb = usbd_alloc_urb(tx_urb->device, endpoint);
+                               }
+                       }
+               }
+       }
+}
+
+/* URB linked list functions ***************************************************** */
+
+/*
+ * Initialize an urb_link to be a single element list.
+ * If the urb_link is being used as a distinguished list head
+ * the list is empty when the head is the only link in the list.
+ */
+void urb_link_init (urb_link * ul)
+{
+       if (ul) {
+               ul->prev = ul->next = ul;
+       }
+}
+
+/*
+ * Detach an urb_link from a list, and set it
+ * up as a single element list, so no dangling
+ * pointers can be followed, and so it can be
+ * joined to another list if so desired.
+ */
+void urb_detach (struct urb *urb)
+{
+       if (urb) {
+               urb_link *ul = &urb->link;
+               ul->next->prev = ul->prev;
+               ul->prev->next = ul->next;
+               urb_link_init (ul);
+       }
+}
+
+/*
+ * Return the first urb_link in a list with a distinguished
+ * head "hd", or NULL if the list is empty.  This will also
+ * work as a predicate, returning NULL if empty, and non-NULL
+ * otherwise.
+ */
+urb_link *first_urb_link (urb_link * hd)
+{
+       urb_link *nx;
+       if (NULL != hd && NULL != (nx = hd->next) && nx != hd) {
+               /* There is at least one element in the list */
+               /* (besides the distinguished head). */
+               return (nx);
+       }
+       /* The list is empty */
+       return (NULL);
+}
+
+/*
+ * Return the first urb in a list with a distinguished
+ * head "hd", or NULL if the list is empty.
+ */
+struct urb *first_urb (urb_link * hd)
+{
+       urb_link *nx;
+       if (NULL == (nx = first_urb_link (hd))) {
+               /* The list is empty */
+               return (NULL);
+       }
+       return (p2surround (struct urb, link, nx));
+}
+
+/*
+ * Detach and return the first urb in a list with a distinguished
+ * head "hd", or NULL if the list is empty.
+ *
+ */
+struct urb *first_urb_detached (urb_link * hd)
+{
+       struct urb *urb;
+       if ((urb = first_urb (hd))) {
+               urb_detach (urb);
+       }
+       return urb;
+}
+
+
+/*
+ * Append an urb_link (or a whole list of
+ * urb_links) to the tail of another list
+ * of urb_links.
+ */
+void urb_append (urb_link * hd, struct urb *urb)
+{
+       if (hd && urb) {
+               urb_link *new = &urb->link;
+
+               /* This allows the new urb to be a list of urbs, */
+               /* with new pointing at the first, but the link */
+               /* must be initialized. */
+               /* Order is important here... */
+               urb_link *pul = hd->prev;
+               new->prev->next = hd;
+               hd->prev = new->prev;
+               new->prev = pul;
+               pul->next = new;
+       }
+}
+
+/* URB create/destroy functions ***************************************************** */
+
+/**
+ * usbd_alloc_urb - allocate an URB appropriate for specified endpoint
+ * @device: device instance
+ * @endpoint: endpoint
+ *
+ * Allocate an urb structure. The usb device urb structure is used to
+ * contain all data associated with a transfer, including a setup packet for
+ * control transfers.
+ *
+ * NOTE: endpoint_address MUST contain a direction flag.
+ */
+struct urb *usbd_alloc_urb (struct usb_device_instance *device, struct usb_endpoint_instance *endpoint)
+{
+       struct urb *urb;
+
+       if( !(urb = (struct urb*)malloc(sizeof(struct urb))) ) {
+         usberr(" F A T A L:  malloc(%u) FAILED!!!!", sizeof(struct urb));
+         return NULL;
+       }
+
+       /* Fill in known fields */
+       memset(urb, 0, sizeof(struct urb));
+       urb->endpoint = endpoint;
+       urb->device = device;
+       urb->buffer = (u8*)urb->buffer_data;
+       urb->buffer_length = sizeof(urb->buffer_data);
+
+       urb_link_init (&urb->link);
+
+       return urb;
+}
+
+/**
+ * usbd_dealloc_urb - deallocate an URB and associated buffer
+ * @urb: pointer to an urb structure
+ *
+ * Deallocate an urb structure and associated data.
+ */
+void usbd_dealloc_urb (struct urb *urb)
+{
+       if (urb) {
+               free (urb);
+       }
+}
+
+/* Event signaling functions ***************************************************** */
+
+/**
+ * usbd_device_event - called to respond to various usb events
+ * @device: pointer to struct device
+ * @event: event to respond to
+ *
+ * Used by a Bus driver to indicate an event.
+ */
+void usbd_device_event_irq (struct usb_device_instance *device, usb_device_event_t event, int data)
+{
+       usb_device_state_t state;
+
+       if (!device || !device->bus) {
+               usberr("(%p,%d) NULL device or device->bus", device, event);
+               return;
+       }
+
+       state = device->device_state;
+
+       usbinfo("%s", usbd_device_events[event]);
+
+       switch (event) {
+       case DEVICE_UNKNOWN:
+               break;
+       case DEVICE_INIT:
+               device->device_state = STATE_INIT;
+               break;
+
+       case DEVICE_CREATE:
+               device->device_state = STATE_ATTACHED;
+               break;
+
+       case DEVICE_HUB_CONFIGURED:
+               device->device_state = STATE_POWERED;
+               break;
+
+       case DEVICE_RESET:
+               device->device_state = STATE_DEFAULT;
+               device->address = 0;
+               break;
+
+       case DEVICE_ADDRESS_ASSIGNED:
+               device->device_state = STATE_ADDRESSED;
+               break;
+
+       case DEVICE_CONFIGURED:
+               device->device_state = STATE_CONFIGURED;
+               break;
+
+       case DEVICE_DE_CONFIGURED:
+               device->device_state = STATE_ADDRESSED;
+               break;
+
+       case DEVICE_BUS_INACTIVE:
+               if (device->status != USBD_CLOSING) {
+                       device->status = USBD_SUSPENDED;
+               }
+               break;
+       case DEVICE_BUS_ACTIVITY:
+               if (device->status != USBD_CLOSING) {
+                       device->status = USBD_OK;
+               }
+               break;
+
+       case DEVICE_SET_INTERFACE:
+               break;
+       case DEVICE_SET_FEATURE:
+               break;
+       case DEVICE_CLEAR_FEATURE:
+               break;
+
+       case DEVICE_POWER_INTERRUPTION:
+               device->device_state = STATE_POWERED;
+               break;
+       case DEVICE_HUB_RESET:
+               device->device_state = STATE_ATTACHED;
+               break;
+       case DEVICE_DESTROY:
+               device->device_state = STATE_UNKNOWN;
+               break;
+
+       case DEVICE_FUNCTION_PRIVATE:
+               break;
+
+       default:
+               usbdbg("event %d - not handled",event);
+               break;
+       }
+       /*usbdbg("%s event: %d oldstate: %d newstate: %d status: %d address: %d",
+               device->name, event, state,
+               device->device_state, device->status, device->address); */
+
+       /* tell the bus interface driver */
+       if( device->event ) {
+               /* usbdbg("calling device->event"); */
+               device->event(device, event, data);
+       }
+}
diff --git a/drivers/usb/usbdcore_ep0.c b/drivers/usb/usbdcore_ep0.c
new file mode 100644 (file)
index 0000000..1e44f32
--- /dev/null
@@ -0,0 +1,607 @@
+/*
+ * (C) Copyright 2003
+ * Gerry Hamel, geh@ti.com, Texas Instruments
+ *
+ * (C) Copyright 2006
+ * Bryan O'Donoghue, deckard@CodeHermit.ie
+ *
+ * Based on
+ * linux/drivers/usbd/ep0.c
+ *
+ * Copyright (c) 2000, 2001, 2002 Lineo
+ * Copyright (c) 2001 Hewlett Packard
+ *
+ * By:
+ *     Stuart Lynne <sl@lineo.com>,
+ *     Tom Rushworth <tbr@lineo.com>,
+ *     Bruce Balden <balden@lineo.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * This is the builtin ep0 control function. It implements all required functionality
+ * for responding to control requests (SETUP packets).
+ *
+ * XXX
+ *
+ * Currently we do not pass any SETUP packets (or other) to the configured
+ * function driver. This may need to change.
+ *
+ * XXX
+ *
+ * As alluded to above, a simple callback cdc_recv_setup has been implemented
+ * in the usb_device data structure to facilicate passing
+ * Common Device Class packets to a function driver.
+ *
+ * XXX
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_USB_DEVICE)
+#include "usbdcore.h"
+
+#if 0
+#define dbg_ep0(lvl,fmt,args...) serial_printf("[%s] %s:%d: "fmt"\n",__FILE__,__FUNCTION__,__LINE__,##args)
+#else
+#define dbg_ep0(lvl,fmt,args...)
+#endif
+
+/* EP0 Configuration Set ********************************************************************* */
+
+
+/**
+ * ep0_get_status - fill in URB data with appropriate status
+ * @device:
+ * @urb:
+ * @index:
+ * @requesttype:
+ *
+ */
+static int ep0_get_status (struct usb_device_instance *device,
+                          struct urb *urb, int index, int requesttype)
+{
+       char *cp;
+
+       urb->actual_length = 2;
+       cp = (char*)urb->buffer;
+       cp[0] = cp[1] = 0;
+
+       switch (requesttype) {
+       case USB_REQ_RECIPIENT_DEVICE:
+               cp[0] = USB_STATUS_SELFPOWERED;
+               break;
+       case USB_REQ_RECIPIENT_INTERFACE:
+               break;
+       case USB_REQ_RECIPIENT_ENDPOINT:
+               cp[0] = usbd_endpoint_halted (device, index);
+               break;
+       case USB_REQ_RECIPIENT_OTHER:
+               urb->actual_length = 0;
+       default:
+               break;
+       }
+       dbg_ep0 (2, "%02x %02x", cp[0], cp[1]);
+       return 0;
+}
+
+/**
+ * ep0_get_one
+ * @device:
+ * @urb:
+ * @result:
+ *
+ * Set a single byte value in the urb send buffer. Return non-zero to signal
+ * a request error.
+ */
+static int ep0_get_one (struct usb_device_instance *device, struct urb *urb,
+                       __u8 result)
+{
+       urb->actual_length = 1; /* XXX 2? */
+       ((char *) urb->buffer)[0] = result;
+       return 0;
+}
+
+/**
+ * copy_config
+ * @urb: pointer to urb
+ * @data: pointer to configuration data
+ * @length: length of data
+ *
+ * Copy configuration data to urb transfer buffer if there is room for it.
+ */
+void copy_config (struct urb *urb, void *data, int max_length,
+                        int max_buf)
+{
+       int available;
+       int length;
+
+       /*dbg_ep0(3, "-> actual: %d buf: %d max_buf: %d max_length: %d data: %p", */
+       /*        urb->actual_length, urb->buffer_length, max_buf, max_length, data); */
+
+       if (!data) {
+               dbg_ep0 (1, "data is NULL");
+               return;
+       }
+       length = max_length;
+
+       if (length > max_length) {
+               dbg_ep0 (1, "length: %d >= max_length: %d", length,
+                        max_length);
+               return;
+       }
+       /*dbg_ep0(1, "   actual: %d buf: %d max_buf: %d max_length: %d length: %d", */
+       /*        urb->actual_length, urb->buffer_length, max_buf, max_length, length); */
+
+       if ((available =
+            /*urb->buffer_length */ max_buf - urb->actual_length) <= 0) {
+               return;
+       }
+       /*dbg_ep0(1, "actual: %d buf: %d max_buf: %d length: %d available: %d", */
+       /*        urb->actual_length, urb->buffer_length, max_buf, length, available); */
+
+       if (length > available) {
+               length = available;
+       }
+       /*dbg_ep0(1, "actual: %d buf: %d max_buf: %d length: %d available: %d", */
+       /*        urb->actual_length, urb->buffer_length, max_buf, length, available); */
+
+       memcpy (urb->buffer + urb->actual_length, data, length);
+       urb->actual_length += length;
+
+       dbg_ep0 (3,
+                "copy_config: <- actual: %d buf: %d max_buf: %d max_length: %d available: %d",
+                urb->actual_length, urb->buffer_length, max_buf, max_length,
+                available);
+}
+
+/**
+ * ep0_get_descriptor
+ * @device:
+ * @urb:
+ * @max:
+ * @descriptor_type:
+ * @index:
+ *
+ * Called by ep0_rx_process for a get descriptor device command. Determine what
+ * descriptor is being requested, copy to send buffer. Return zero if ok to send,
+ * return non-zero to signal a request error.
+ */
+static int ep0_get_descriptor (struct usb_device_instance *device,
+                              struct urb *urb, int max, int descriptor_type,
+                              int index)
+{
+       int port = 0;           /* XXX compound device */
+       char *cp;
+
+       /*dbg_ep0(3, "max: %x type: %x index: %x", max, descriptor_type, index); */
+
+       if (!urb || !urb->buffer || !urb->buffer_length
+           || (urb->buffer_length < 255)) {
+               dbg_ep0 (2, "invalid urb %p", urb);
+               return -1L;
+       }
+
+       /* setup tx urb */
+       urb->actual_length = 0;
+       cp = (char*)urb->buffer;
+
+       dbg_ep0 (2, "%s", USBD_DEVICE_DESCRIPTORS (descriptor_type));
+
+       switch (descriptor_type) {
+       case USB_DESCRIPTOR_TYPE_DEVICE:
+               {
+                       struct usb_device_descriptor *device_descriptor;
+                       if (!
+                           (device_descriptor =
+                            usbd_device_device_descriptor (device, port))) {
+                               return -1;
+                       }
+                       /* copy descriptor for this device */
+                       copy_config (urb, device_descriptor,
+                                    sizeof (struct usb_device_descriptor),
+                                    max);
+
+                       /* correct the correct control endpoint 0 max packet size into the descriptor */
+                       device_descriptor =
+                               (struct usb_device_descriptor *) urb->buffer;
+
+               }
+               dbg_ep0(3, "copied device configuration, actual_length: 0x%x", urb->actual_length);
+               break;
+
+       case USB_DESCRIPTOR_TYPE_CONFIGURATION:
+               {
+                       struct usb_configuration_descriptor
+                               *configuration_descriptor;
+                       struct usb_device_descriptor *device_descriptor;
+                       if (!
+                           (device_descriptor =
+                            usbd_device_device_descriptor (device, port))) {
+                               return -1;
+                       }
+                       /*dbg_ep0(2, "%d %d", index, device_descriptor->bNumConfigurations); */
+                       if (index > device_descriptor->bNumConfigurations) {
+                               dbg_ep0 (0, "index too large: %d > %d", index,
+                                        device_descriptor->
+                                        bNumConfigurations);
+                               return -1;
+                       }
+
+                       if (!
+                           (configuration_descriptor =
+                            usbd_device_configuration_descriptor (device,
+                                                                  port,
+                                                                  index))) {
+                               dbg_ep0 (0,
+                                        "usbd_device_configuration_descriptor failed: %d",
+                                        index);
+                               return -1;
+                       }
+                       dbg_ep0(0, "attempt to copy %d bytes to urb\n",cpu_to_le16(configuration_descriptor->wTotalLength));
+                       copy_config (urb, configuration_descriptor,
+
+                                       cpu_to_le16(configuration_descriptor->wTotalLength),
+                                    max);
+               }
+
+               break;
+
+       case USB_DESCRIPTOR_TYPE_STRING:
+               {
+                       struct usb_string_descriptor *string_descriptor;
+                       if (!(string_descriptor = usbd_get_string (index))) {
+                               serial_printf("Invalid string index %d\n", index);
+                               return -1;
+                       }
+                       dbg_ep0(3, "string_descriptor: %p length %d", string_descriptor, string_descriptor->bLength);
+                       copy_config (urb, string_descriptor, string_descriptor->bLength, max);
+               }
+               break;
+       case USB_DESCRIPTOR_TYPE_INTERFACE:
+       serial_printf("USB_DESCRIPTOR_TYPE_INTERFACE - error not implemented\n");
+               return -1;
+       case USB_DESCRIPTOR_TYPE_ENDPOINT:
+               serial_printf("USB_DESCRIPTOR_TYPE_ENDPOINT - error not implemented\n");
+               return -1;
+       case USB_DESCRIPTOR_TYPE_HID:
+               {
+                       serial_printf("USB_DESCRIPTOR_TYPE_HID - error not implemented\n");
+                       return -1;      /* unsupported at this time */
+#if 0
+                       int bNumInterface =
+                               le16_to_cpu (urb->device_request.wIndex);
+                       int bAlternateSetting = 0;
+                       int class = 0;
+                       struct usb_class_descriptor *class_descriptor;
+
+                       if (!(class_descriptor =
+                             usbd_device_class_descriptor_index (device,
+                                                                 port, 0,
+                                                                 bNumInterface,
+                                                                 bAlternateSetting,
+                                                                 class))
+                           || class_descriptor->descriptor.hid.bDescriptorType != USB_DT_HID) {
+                               dbg_ep0 (3, "[%d] interface is not HID",
+                                        bNumInterface);
+                               return -1;
+                       }
+                       /* copy descriptor for this class */
+                       copy_config (urb, class_descriptor,
+                                    class_descriptor->descriptor.hid.bLength,
+                                    max);
+#endif
+               }
+               break;
+       case USB_DESCRIPTOR_TYPE_REPORT:
+               {
+                       serial_printf("USB_DESCRIPTOR_TYPE_REPORT - error not implemented\n");
+                       return -1;      /* unsupported at this time */
+#if 0
+                       int bNumInterface =
+                               le16_to_cpu (urb->device_request.wIndex);
+                       int bAlternateSetting = 0;
+                       int class = 0;
+                       struct usb_class_report_descriptor *report_descriptor;
+
+                       if (!(report_descriptor =
+                             usbd_device_class_report_descriptor_index
+                             (device, port, 0, bNumInterface,
+                              bAlternateSetting, class))
+                           || report_descriptor->bDescriptorType !=
+                           USB_DT_REPORT) {
+                               dbg_ep0 (3, "[%d] descriptor is not REPORT",
+                                        bNumInterface);
+                               return -1;
+                       }
+                       /* copy report descriptor for this class */
+                       /*copy_config(urb, &report_descriptor->bData[0], report_descriptor->wLength, max); */
+                       if (max - urb->actual_length > 0) {
+                               int length =
+                                       MIN (report_descriptor->wLength,
+                                            max - urb->actual_length);
+                               memcpy (urb->buffer + urb->actual_length,
+                                       &report_descriptor->bData[0], length);
+                               urb->actual_length += length;
+                       }
+#endif
+               }
+               break;
+       case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
+               {
+                       /* If a USB device supports both a full speed and low speed operation
+                        * we must send a Device_Qualifier descriptor here
+                        */
+                       return -1;
+               }
+       default:
+               return -1;
+       }
+
+
+       dbg_ep0 (1, "urb: buffer: %p buffer_length: %2d actual_length: %2d tx_packetSize: %2d",
+                urb->buffer, urb->buffer_length, urb->actual_length,
+                device->bus->endpoint_array[0].tx_packetSize);
+/*
+    if ((urb->actual_length < max) && !(urb->actual_length % device->bus->endpoint_array[0].tx_packetSize)) {
+       dbg_ep0(0, "adding null byte");
+       urb->buffer[urb->actual_length++] = 0;
+       dbg_ep0(0, "urb: buffer_length: %2d actual_length: %2d packet size: %2d",
+               urb->buffer_length, urb->actual_length device->bus->endpoint_array[0].tx_packetSize);
+    }
+*/
+       return 0;
+
+}
+
+/**
+ * ep0_recv_setup - called to indicate URB has been received
+ * @urb: pointer to struct urb
+ *
+ * Check if this is a setup packet, process the device request, put results
+ * back into the urb and return zero or non-zero to indicate success (DATA)
+ * or failure (STALL).
+ *
+ */
+int ep0_recv_setup (struct urb *urb)
+{
+       /*struct usb_device_request *request = urb->buffer; */
+       /*struct usb_device_instance *device = urb->device; */
+
+       struct usb_device_request *request;
+       struct usb_device_instance *device;
+       int address;
+
+       dbg_ep0 (0, "entering ep0_recv_setup()");
+       if (!urb || !urb->device) {
+               dbg_ep0 (3, "invalid URB %p", urb);
+               return -1;
+       }
+
+       request = &urb->device_request;
+       device = urb->device;
+
+       dbg_ep0 (3, "urb: %p device: %p", urb, urb->device);
+
+
+       /*dbg_ep0(2, "-       -       -       -       -       -       -       -       -       -"); */
+
+       dbg_ep0 (2,
+                "bmRequestType:%02x bRequest:%02x wValue:%04x wIndex:%04x wLength:%04x %s",
+                request->bmRequestType, request->bRequest,
+                le16_to_cpu (request->wValue), le16_to_cpu (request->wIndex),
+                le16_to_cpu (request->wLength),
+                USBD_DEVICE_REQUESTS (request->bRequest));
+
+       /* handle USB Standard Request (c.f. USB Spec table 9-2) */
+       if ((request->bmRequestType & USB_REQ_TYPE_MASK) != 0) {
+               if(device->device_state <= STATE_CONFIGURED){
+                       /*      Attempt to handle a CDC specific request if we are
+                        *      in the configured state.
+                        */
+                       return device->cdc_recv_setup(request,urb);
+               }
+               dbg_ep0 (1, "non standard request: %x",
+                        request->bmRequestType & USB_REQ_TYPE_MASK);
+               return -1;      /* Stall here */
+       }
+
+       switch (device->device_state) {
+       case STATE_CREATED:
+       case STATE_ATTACHED:
+       case STATE_POWERED:
+               /* It actually is important to allow requests in these states,
+                * Windows will request descriptors before assigning an
+                * address to the client.
+                */
+
+               /*dbg_ep0 (1, "request %s not allowed in this state: %s", */
+               /*                USBD_DEVICE_REQUESTS(request->bRequest), */
+               /*                usbd_device_states[device->device_state]); */
+               /*return -1; */
+               break;
+
+       case STATE_INIT:
+       case STATE_DEFAULT:
+               switch (request->bRequest) {
+               case USB_REQ_GET_STATUS:
+               case USB_REQ_GET_INTERFACE:
+               case USB_REQ_SYNCH_FRAME:       /* XXX should never see this (?) */
+               case USB_REQ_CLEAR_FEATURE:
+               case USB_REQ_SET_FEATURE:
+               case USB_REQ_SET_DESCRIPTOR:
+                       /* case USB_REQ_SET_CONFIGURATION: */
+               case USB_REQ_SET_INTERFACE:
+                       dbg_ep0 (1,
+                                "request %s not allowed in DEFAULT state: %s",
+                                USBD_DEVICE_REQUESTS (request->bRequest),
+                                usbd_device_states[device->device_state]);
+                       return -1;
+
+               case USB_REQ_SET_CONFIGURATION:
+               case USB_REQ_SET_ADDRESS:
+               case USB_REQ_GET_DESCRIPTOR:
+               case USB_REQ_GET_CONFIGURATION:
+                       break;
+               }
+       case STATE_ADDRESSED:
+       case STATE_CONFIGURED:
+               break;
+       case STATE_UNKNOWN:
+               dbg_ep0 (1, "request %s not allowed in UNKNOWN state: %s",
+                        USBD_DEVICE_REQUESTS (request->bRequest),
+                        usbd_device_states[device->device_state]);
+               return -1;
+       }
+
+       /* handle all requests that return data (direction bit set on bm RequestType) */
+       if ((request->bmRequestType & USB_REQ_DIRECTION_MASK)) {
+
+               dbg_ep0 (3, "Device-to-Host");
+
+               switch (request->bRequest) {
+
+               case USB_REQ_GET_STATUS:
+                       return ep0_get_status (device, urb, request->wIndex,
+                                              request->bmRequestType &
+                                              USB_REQ_RECIPIENT_MASK);
+
+               case USB_REQ_GET_DESCRIPTOR:
+                       return ep0_get_descriptor (device, urb,
+                                                  le16_to_cpu (request->wLength),
+                                                  le16_to_cpu (request->wValue) >> 8,
+                                                  le16_to_cpu (request->wValue) & 0xff);
+
+               case USB_REQ_GET_CONFIGURATION:
+                       serial_printf("get config %d\n", device->configuration);
+                       return ep0_get_one (device, urb,
+                                           device->configuration);
+
+               case USB_REQ_GET_INTERFACE:
+                       return ep0_get_one (device, urb, device->alternate);
+
+               case USB_REQ_SYNCH_FRAME:       /* XXX should never see this (?) */
+                       return -1;
+
+               case USB_REQ_CLEAR_FEATURE:
+               case USB_REQ_SET_FEATURE:
+               case USB_REQ_SET_ADDRESS:
+               case USB_REQ_SET_DESCRIPTOR:
+               case USB_REQ_SET_CONFIGURATION:
+               case USB_REQ_SET_INTERFACE:
+                       return -1;
+               }
+       }
+       /* handle the requests that do not return data */
+       else {
+
+
+               /*dbg_ep0(3, "Host-to-Device"); */
+               switch (request->bRequest) {
+
+               case USB_REQ_CLEAR_FEATURE:
+               case USB_REQ_SET_FEATURE:
+                       dbg_ep0 (0, "Host-to-Device");
+                       switch (request->
+                               bmRequestType & USB_REQ_RECIPIENT_MASK) {
+                       case USB_REQ_RECIPIENT_DEVICE:
+                               /* XXX DEVICE_REMOTE_WAKEUP or TEST_MODE would be added here */
+                               /* XXX fall through for now as we do not support either */
+                       case USB_REQ_RECIPIENT_INTERFACE:
+                       case USB_REQ_RECIPIENT_OTHER:
+                               dbg_ep0 (0, "request %s not",
+                                        USBD_DEVICE_REQUESTS (request->bRequest));
+                       default:
+                               return -1;
+
+                       case USB_REQ_RECIPIENT_ENDPOINT:
+                               dbg_ep0 (0, "ENDPOINT: %x", le16_to_cpu (request->wValue));
+                               if (le16_to_cpu (request->wValue) == USB_ENDPOINT_HALT) {
+                                       /*return usbd_device_feature (device, le16_to_cpu (request->wIndex), */
+                                       /*                    request->bRequest == USB_REQ_SET_FEATURE); */
+                                       /* NEED TO IMPLEMENT THIS!!! */
+                                       return -1;
+                               } else {
+                                       dbg_ep0 (1, "request %s bad wValue: %04x",
+                                                USBD_DEVICE_REQUESTS
+                                                (request->bRequest),
+                                                le16_to_cpu (request->wValue));
+                                       return -1;
+                               }
+                       }
+
+               case USB_REQ_SET_ADDRESS:
+                       /* check if this is a re-address, reset first if it is (this shouldn't be possible) */
+                       if (device->device_state != STATE_DEFAULT) {
+                               dbg_ep0 (1, "set_address: %02x state: %s",
+                                        le16_to_cpu (request->wValue),
+                                        usbd_device_states[device->device_state]);
+                               return -1;
+                       }
+                       address = le16_to_cpu (request->wValue);
+                       if ((address & 0x7f) != address) {
+                               dbg_ep0 (1, "invalid address %04x %04x",
+                                        address, address & 0x7f);
+                               return -1;
+                       }
+                       device->address = address;
+
+                       /*dbg_ep0(2, "address: %d %d %d", */
+                       /*        request->wValue, le16_to_cpu(request->wValue), device->address); */
+
+                       return 0;
+
+               case USB_REQ_SET_DESCRIPTOR:    /* XXX should we support this? */
+                       dbg_ep0 (0, "set descriptor: NOT SUPPORTED");
+                       return -1;
+
+               case USB_REQ_SET_CONFIGURATION:
+                       /* c.f. 9.4.7 - the top half of wValue is reserved */
+                       /* */
+                       if ((device->configuration =
+                               le16_to_cpu (request->wValue) & 0xFF80) != 0) {
+                               /* c.f. 9.4.7 - zero is the default or addressed state, in our case this */
+                               /* is the same is configuration zero */
+                               serial_printf("error setting dev->config to zero!\n");
+                               device->configuration = 0;      /* TBR - ?????? */
+                       }
+                       /* reset interface and alternate settings */
+                       device->interface = device->alternate = 0;
+
+                       /*dbg_ep0(2, "set configuration: %d", device->configuration); */
+                       /*serial_printf("DEVICE_CONFIGURED.. event?\n"); */
+                       return 0;
+
+               case USB_REQ_SET_INTERFACE:
+                       device->interface = le16_to_cpu (request->wIndex);
+                       device->alternate = le16_to_cpu (request->wValue);
+                       /*dbg_ep0(2, "set interface: %d alternate: %d", device->interface, device->alternate); */
+                       serial_printf ("DEVICE_SET_INTERFACE.. event?\n");
+                       return 0;
+
+               case USB_REQ_GET_STATUS:
+               case USB_REQ_GET_DESCRIPTOR:
+               case USB_REQ_GET_CONFIGURATION:
+               case USB_REQ_GET_INTERFACE:
+               case USB_REQ_SYNCH_FRAME:       /* XXX should never see this (?) */
+                       return -1;
+               }
+       }
+       return -1;
+}
+
+#endif
diff --git a/drivers/usb/usbdcore_mpc8xx.c b/drivers/usb/usbdcore_mpc8xx.c
new file mode 100644 (file)
index 0000000..d4c4096
--- /dev/null
@@ -0,0 +1,1401 @@
+/*
+ * Copyright (C) 2006 by Bryan O'Donoghue, CodeHermit
+ * bodonoghue@CodeHermit.ie
+ *
+ * References
+ * DasUBoot/drivers/usbdcore_omap1510.c, for design and implementation ideas.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+/*
+ * Notes :
+ * 1.  #define __SIMULATE_ERROR__ to inject a CRC error into every 2nd TX
+ *             packet to force the USB re-transmit protocol.
+ *
+ * 2.  #define __DEBUG_UDC__ to switch on debug tracing to serial console
+ *     be careful that tracing doesn't create Hiesen-bugs with respect to
+ *     response timeouts to control requests.
+ *
+ * 3.  This driver should be able to support any higher level driver that
+ *     that wants to do either of the two standard UDC implementations
+ *     Control-Bulk-Interrupt or  Bulk-IN/Bulk-Out standards. Hence
+ *     gserial and cdc_acm should work with this code.
+ *
+ * 4.  NAK events never actually get raised at all, the documentation
+ *     is just wrong !
+ *
+ * 5.  For some reason, cbd_datlen is *always* +2 the value it should be.
+ *     this means that having an RX cbd of 16 bytes is not possible, since
+ *     the same size is reported for 14 bytes received as 16 bytes received
+ *     until we can find out why this happens, RX cbds must be limited to 8
+ *     bytes. TODO: check errata for this behaviour.
+ *
+ * 6.  Right now this code doesn't support properly powering up with the USB
+ *     cable attached to the USB host my development board the Adder87x doesn't
+ *     have a pull-up fitted to allow this, so it is necessary to power the
+ *     board and *then* attached the USB cable to the host. However somebody
+ *     with a different design in their board may be able to keep the cable
+ *     constantly connected and simply enable/disable a pull-up  re
+ *     figure 31.1 in MPC885RM.pdf instead of having to power up the board and
+ *     then attach the cable !
+ *
+ */
+#include <common.h>
+#include <config.h>
+
+#if defined(CONFIG_MPC885_FAMILY) && defined(CONFIG_USB_DEVICE)
+#include <commproc.h>
+#include "usbdcore.h"
+#include "usbdcore_mpc8xx.h"
+#include "usbdcore_ep0.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define ERR(fmt, args...)\
+       serial_printf("ERROR : [%s] %s:%d: "fmt,\
+                               __FILE__,__FUNCTION__,__LINE__, ##args)
+#ifdef __DEBUG_UDC__
+#define DBG(fmt,args...)\
+               serial_printf("[%s] %s:%d: "fmt,\
+                               __FILE__,__FUNCTION__,__LINE__, ##args)
+#else
+#define DBG(fmt,args...)
+#endif
+
+/* Static Data */
+#ifdef __SIMULATE_ERROR__
+static char err_poison_test = 0;
+#endif
+static struct mpc8xx_ep ep_ref[MAX_ENDPOINTS];
+static u32 address_base = STATE_NOT_READY;
+static mpc8xx_udc_state_t udc_state = 0;
+static struct usb_device_instance *udc_device = 0;
+static volatile usb_epb_t *endpoints[MAX_ENDPOINTS];
+static volatile cbd_t *tx_cbd[TX_RING_SIZE];
+static volatile cbd_t *rx_cbd[RX_RING_SIZE];
+static volatile immap_t *immr = 0;
+static volatile cpm8xx_t *cp = 0;
+static volatile usb_pram_t *usb_paramp = 0;
+static volatile usb_t *usbp = 0;
+static int rx_ct = 0;
+static int tx_ct = 0;
+
+/* Static Function Declarations */
+static void mpc8xx_udc_state_transition_up (usb_device_state_t initial,
+                                           usb_device_state_t final);
+static void mpc8xx_udc_state_transition_down (usb_device_state_t initial,
+                                             usb_device_state_t final);
+static void mpc8xx_udc_stall (unsigned int ep);
+static void mpc8xx_udc_flush_tx_fifo (int epid);
+static void mpc8xx_udc_flush_rx_fifo (void);
+static void mpc8xx_udc_clear_rxbd (volatile cbd_t * rx_cbdp);
+static void mpc8xx_udc_init_tx (struct usb_endpoint_instance *epi,
+                               struct urb *tx_urb);
+static void mpc8xx_udc_dump_request (struct usb_device_request *request);
+static void mpc8xx_udc_clock_init (volatile immap_t * immr,
+                                  volatile cpm8xx_t * cp);
+static int mpc8xx_udc_ep_tx (struct usb_endpoint_instance *epi);
+static int mpc8xx_udc_epn_rx (unsigned int epid, volatile cbd_t * rx_cbdp);
+static void mpc8xx_udc_ep0_rx (volatile cbd_t * rx_cbdp);
+static void mpc8xx_udc_cbd_init (void);
+static void mpc8xx_udc_endpoint_init (void);
+static void mpc8xx_udc_cbd_attach (int ep, uchar tx_size, uchar rx_size);
+static u32 mpc8xx_udc_alloc (u32 data_size, u32 alignment);
+static int mpc8xx_udc_ep0_rx_setup (volatile cbd_t * rx_cbdp);
+static void mpc8xx_udc_set_nak (unsigned int ep);
+static short mpc8xx_udc_handle_txerr (void);
+static void mpc8xx_udc_advance_rx (volatile cbd_t ** rx_cbdp, int epid);
+
+/******************************************************************************
+                              Global Linkage
+ *****************************************************************************/
+
+/* udc_init
+ *
+ * Do initial bus gluing
+ */
+int udc_init (void)
+{
+       /* Init various pointers */
+       immr = (immap_t *) CFG_IMMR;
+       cp = (cpm8xx_t *) & (immr->im_cpm);
+       usb_paramp = (usb_pram_t *) & (cp->cp_dparam[PROFF_USB]);
+       usbp = (usb_t *) & (cp->cp_scc[0]);
+
+       memset (ep_ref, 0x00, (sizeof (struct mpc8xx_ep) * MAX_ENDPOINTS));
+
+       udc_device = 0;
+       udc_state = STATE_NOT_READY;
+
+       usbp->usmod = 0x00;
+       usbp->uscom = 0;
+
+       /* Set USB Frame #0, Respond at Address & Get a clock source  */
+       usbp->usaddr = 0x00;
+       mpc8xx_udc_clock_init (immr, cp);
+
+       /* PA15, PA14 as perhiperal USBRXD and USBOE */
+       immr->im_ioport.iop_padir &= ~0x0003;
+       immr->im_ioport.iop_papar |= 0x0003;
+
+       /* PC11/PC10 as peripheral USBRXP USBRXN */
+       immr->im_ioport.iop_pcso |= 0x0030;
+
+       /* PC7/PC6 as perhiperal USBTXP and USBTXN */
+       immr->im_ioport.iop_pcdir |= 0x0300;
+       immr->im_ioport.iop_pcpar |= 0x0300;
+
+       /* Set the base address */
+       address_base = (u32) (cp->cp_dpmem + CPM_USB_BASE);
+
+       /* Initialise endpoints and circular buffers */
+       mpc8xx_udc_endpoint_init ();
+       mpc8xx_udc_cbd_init ();
+
+       /* Assign allocated Dual Port Endpoint descriptors */
+       usb_paramp->ep0ptr = (u32) endpoints[0];
+       usb_paramp->ep1ptr = (u32) endpoints[1];
+       usb_paramp->ep2ptr = (u32) endpoints[2];
+       usb_paramp->ep3ptr = (u32) endpoints[3];
+       usb_paramp->frame_n = 0;
+
+       DBG ("ep0ptr=0x%08x ep1ptr=0x%08x ep2ptr=0x%08x ep3ptr=0x%08x\n",
+            usb_paramp->ep0ptr, usb_paramp->ep1ptr, usb_paramp->ep2ptr,
+            usb_paramp->ep3ptr);
+
+       return 0;
+}
+
+/* udc_irq
+ *
+ * Poll for whatever events may have occured
+ */
+void udc_irq (void)
+{
+       int epid = 0;
+       volatile cbd_t *rx_cbdp = 0;
+       volatile cbd_t *rx_cbdp_base = 0;
+
+       if (udc_state != STATE_READY) {
+               return;
+       }
+
+       if (usbp->usber & USB_E_BSY) {
+               /* This shouldn't happen. If it does then it's a bug ! */
+               usbp->usber |= USB_E_BSY;
+               mpc8xx_udc_flush_rx_fifo ();
+       }
+
+       /* Scan all RX/Bidirectional Endpoints for RX data. */
+       for (epid = 0; epid < MAX_ENDPOINTS; epid++) {
+               if (!ep_ref[epid].prx) {
+                       continue;
+               }
+               rx_cbdp = rx_cbdp_base = ep_ref[epid].prx;
+
+               do {
+                       if (!(rx_cbdp->cbd_sc & RX_BD_E)) {
+
+                               if (rx_cbdp->cbd_sc & 0x1F) {
+                                       /* Corrupt data discard it.
+                                        * Controller has NAK'd this packet.
+                                        */
+                                       mpc8xx_udc_clear_rxbd (rx_cbdp);
+
+                               } else {
+                                       if (!epid) {
+                                               mpc8xx_udc_ep0_rx (rx_cbdp);
+
+                                       } else {
+                                               /* Process data */
+                                               mpc8xx_udc_set_nak (epid);
+                                               mpc8xx_udc_epn_rx (epid, rx_cbdp);
+                                               mpc8xx_udc_clear_rxbd (rx_cbdp);
+                                       }
+                               }
+
+                               /* Advance RX CBD pointer */
+                               mpc8xx_udc_advance_rx (&rx_cbdp, epid);
+                               ep_ref[epid].prx = rx_cbdp;
+                       } else {
+                               /* Advance RX CBD pointer */
+                               mpc8xx_udc_advance_rx (&rx_cbdp, epid);
+                       }
+
+               } while (rx_cbdp != rx_cbdp_base);
+       }
+
+       /* Handle TX events as appropiate, the correct place to do this is
+        * in a tx routine. Perhaps TX on epn was pre-empted by ep0
+        */
+
+       if (usbp->usber & USB_E_TXB) {
+               usbp->usber |= USB_E_TXB;
+       }
+
+       if (usbp->usber & (USB_TX_ERRMASK)) {
+               mpc8xx_udc_handle_txerr ();
+       }
+
+       /* Switch to the default state, respond at the default address */
+       if (usbp->usber & USB_E_RESET) {
+               usbp->usber |= USB_E_RESET;
+               usbp->usaddr = 0x00;
+               udc_device->device_state = STATE_DEFAULT;
+       }
+
+       /* if(usbp->usber&USB_E_IDLE){
+          We could suspend here !
+          usbp->usber|=USB_E_IDLE;
+          DBG("idle state change\n");
+          }
+          if(usbp->usbs){
+          We could resume here when IDLE is deasserted !
+          Not worth doing, so long as we are self powered though.
+          }
+       */
+
+       return;
+}
+
+/* udc_endpoint_write
+ *
+ * Write some data to an endpoint
+ */
+int udc_endpoint_write (struct usb_endpoint_instance *epi)
+{
+       int ep = 0;
+       short epid = 1, unnak = 0, ret = 0;
+
+       if (udc_state != STATE_READY) {
+               ERR ("invalid udc_state != STATE_READY!\n");
+               return -1;
+       }
+
+       if (!udc_device || !epi) {
+               return -1;
+       }
+
+       if (udc_device->device_state != STATE_CONFIGURED) {
+               return -1;
+       }
+
+       ep = epi->endpoint_address & 0x03;
+       if (ep >= MAX_ENDPOINTS) {
+               return -1;
+       }
+
+       /* Set NAK for all RX endpoints during TX */
+       for (epid = 1; epid < MAX_ENDPOINTS; epid++) {
+
+               /* Don't set NAK on DATA IN/CONTROL endpoints */
+               if (ep_ref[epid].sc & USB_DIR_IN) {
+                       continue;
+               }
+
+               if (!(usbp->usep[epid] & (USEP_THS_NAK | USEP_RHS_NAK))) {
+                       unnak |= 1 << epid;
+               }
+
+               mpc8xx_udc_set_nak (epid);
+       }
+
+       mpc8xx_udc_init_tx (&udc_device->bus->endpoint_array[ep],
+                           epi->tx_urb);
+       ret = mpc8xx_udc_ep_tx (&udc_device->bus->endpoint_array[ep]);
+
+       /* Remove temporary NAK */
+       for (epid = 1; epid < MAX_ENDPOINTS; epid++) {
+               if (unnak & (1 << epid)) {
+                       udc_unset_nak (epid);
+               }
+       }
+
+       return ret;
+}
+
+/* mpc8xx_udc_assign_urb
+ *
+ * Associate a given urb to an endpoint TX or RX transmit/receive buffers
+ */
+static int mpc8xx_udc_assign_urb (int ep, char direction)
+{
+       struct usb_endpoint_instance *epi = 0;
+
+       if (ep >= MAX_ENDPOINTS) {
+               goto err;
+       }
+       epi = &udc_device->bus->endpoint_array[ep];
+       if (!epi) {
+               goto err;
+       }
+
+       if (!ep_ref[ep].urb) {
+               ep_ref[ep].urb = usbd_alloc_urb (udc_device, udc_device->bus->endpoint_array);
+               if (!ep_ref[ep].urb) {
+                       goto err;
+               }
+       } else {
+               ep_ref[ep].urb->actual_length = 0;
+       }
+
+       switch (direction) {
+       case USB_DIR_IN:
+               epi->tx_urb = ep_ref[ep].urb;
+               break;
+       case USB_DIR_OUT:
+               epi->rcv_urb = ep_ref[ep].urb;
+               break;
+       default:
+               goto err;
+       }
+       return 0;
+
+      err:
+       udc_state = STATE_ERROR;
+       return -1;
+}
+
+/* udc_setup_ep
+ *
+ * Associate U-Boot software endpoints to mpc8xx endpoint parameter ram
+ * Isochronous endpoints aren't yet supported!
+ */
+void udc_setup_ep (struct usb_device_instance *device, unsigned int ep,
+                  struct usb_endpoint_instance *epi)
+{
+       uchar direction = 0;
+       int ep_attrib = 0;
+
+       if (epi && (ep < MAX_ENDPOINTS)) {
+
+               if (ep == 0) {
+                       if (epi->rcv_attributes != USB_ENDPOINT_XFER_CONTROL
+                           || epi->tx_attributes !=
+                           USB_ENDPOINT_XFER_CONTROL) {
+
+                               /* ep0 must be a control endpoint */
+                               udc_state = STATE_ERROR;
+                               return;
+
+                       }
+                       if (!(ep_ref[ep].sc & EP_ATTACHED)) {
+                               mpc8xx_udc_cbd_attach (ep, epi->tx_packetSize,
+                                                      epi->rcv_packetSize);
+                       }
+                       usbp->usep[ep] = 0x0000;
+                       return;
+               }
+
+               if ((epi->endpoint_address & USB_ENDPOINT_DIR_MASK)
+                   == USB_DIR_IN) {
+
+                       direction = 1;
+                       ep_attrib = epi->tx_attributes;
+                       epi->rcv_packetSize = 0;
+                       ep_ref[ep].sc |= USB_DIR_IN;
+               } else {
+
+                       direction = 0;
+                       ep_attrib = epi->rcv_attributes;
+                       epi->tx_packetSize = 0;
+                       ep_ref[ep].sc &= ~USB_DIR_IN;
+               }
+
+               if (mpc8xx_udc_assign_urb (ep, epi->endpoint_address
+                                          & USB_ENDPOINT_DIR_MASK)) {
+                       return;
+               }
+
+               switch (ep_attrib) {
+               case USB_ENDPOINT_XFER_CONTROL:
+                       if (!(ep_ref[ep].sc & EP_ATTACHED)) {
+                               mpc8xx_udc_cbd_attach (ep,
+                                                      epi->tx_packetSize,
+                                                      epi->rcv_packetSize);
+                       }
+                       usbp->usep[ep] = ep << 12;
+                       epi->rcv_urb = epi->tx_urb = ep_ref[ep].urb;
+
+                       break;
+               case USB_ENDPOINT_XFER_BULK:
+               case USB_ENDPOINT_XFER_INT:
+                       if (!(ep_ref[ep].sc & EP_ATTACHED)) {
+                               if (direction) {
+                                       mpc8xx_udc_cbd_attach (ep,
+                                                              epi->tx_packetSize,
+                                                              0);
+                               } else {
+                                       mpc8xx_udc_cbd_attach (ep,
+                                                              0,
+                                                              epi->rcv_packetSize);
+                               }
+                       }
+                       usbp->usep[ep] = (ep << 12) | ((ep_attrib) << 8);
+
+                       break;
+               case USB_ENDPOINT_XFER_ISOC:
+               default:
+                       serial_printf ("Error endpoint attrib %d>3\n", ep_attrib);
+                       udc_state = STATE_ERROR;
+                       break;
+               }
+       }
+
+}
+
+/* udc_connect
+ *
+ * Move state, switch on the USB
+ */
+void udc_connect (void)
+{
+       /* Enable pull-up resistor on D+
+        * TODO: fit a pull-up resistor to drive SE0 for > 2.5us
+        */
+
+       if (udc_state != STATE_ERROR) {
+               udc_state = STATE_READY;
+               usbp->usmod |= USMOD_EN;
+       }
+}
+
+/* udc_disconnect
+ *
+ * Disconnect is not used but, is included for completeness
+ */
+void udc_disconnect (void)
+{
+       /* Disable pull-up resistor on D-
+        * TODO: fix a pullup resistor to control this
+        */
+
+       if (udc_state != STATE_ERROR) {
+               udc_state = STATE_NOT_READY;
+       }
+       usbp->usmod &= ~USMOD_EN;
+}
+
+/* udc_enable
+ *
+ * Grab an EP0 URB, register interest in a subset of USB events
+ */
+void udc_enable (struct usb_device_instance *device)
+{
+       if (udc_state == STATE_ERROR) {
+               return;
+       }
+
+       udc_device = device;
+
+       if (!ep_ref[0].urb) {
+               ep_ref[0].urb = usbd_alloc_urb (device, device->bus->endpoint_array);
+       }
+
+       /* Register interest in all events except SOF, enable transceiver */
+       usbp->usber = 0x03FF;
+       usbp->usbmr = 0x02F7;
+
+       return;
+}
+
+/* udc_disable
+ *
+ * disable the currently hooked device
+ */
+void udc_disable (void)
+{
+       int i = 0;
+
+       if (udc_state == STATE_ERROR) {
+               DBG ("Won't disable UDC. udc_state==STATE_ERROR !\n");
+               return;
+       }
+
+       udc_device = 0;
+
+       for (; i < MAX_ENDPOINTS; i++) {
+               if (ep_ref[i].urb) {
+                       usbd_dealloc_urb (ep_ref[i].urb);
+                       ep_ref[i].urb = 0;
+               }
+       }
+
+       usbp->usbmr = 0x00;
+       usbp->usmod = ~USMOD_EN;
+       udc_state = STATE_NOT_READY;
+}
+
+/* udc_startup_events
+ *
+ * Enable the specified device
+ */
+void udc_startup_events (struct usb_device_instance *device)
+{
+       udc_enable (device);
+       if (udc_state == STATE_READY) {
+               usbd_device_event_irq (device, DEVICE_CREATE, 0);
+       }
+}
+
+/* udc_set_nak
+ *
+ * Allow upper layers to signal lower layers should not accept more RX data
+ *
+ */
+void udc_set_nak (int epid)
+{
+       if (epid) {
+               mpc8xx_udc_set_nak (epid);
+       }
+}
+
+/* udc_unset_nak
+ *
+ * Suspend sending of NAK tokens for DATA OUT tokens on a given endpoint.
+ * Switch off NAKing on this endpoint to accept more data output from host.
+ *
+ */
+void udc_unset_nak (int epid)
+{
+       if (epid > MAX_ENDPOINTS) {
+               return;
+       }
+
+       if (usbp->usep[epid] & (USEP_THS_NAK | USEP_RHS_NAK)) {
+               usbp->usep[epid] &= ~(USEP_THS_NAK | USEP_RHS_NAK);
+               __asm__ ("eieio");
+       }
+}
+
+/******************************************************************************
+                             Static Linkage
+******************************************************************************/
+
+/* udc_state_transition_up
+ * udc_state_transition_down
+ *
+ * Helper functions to implement device state changes. The device states and
+ * the events that transition between them are:
+ *
+ *                             STATE_ATTACHED
+ *                             ||      /\
+ *                             \/      ||
+ *     DEVICE_HUB_CONFIGURED                   DEVICE_HUB_RESET
+ *                             ||      /\
+ *                             \/      ||
+ *                             STATE_POWERED
+ *                             ||      /\
+ *                             \/      ||
+ *     DEVICE_RESET                            DEVICE_POWER_INTERRUPTION
+ *                             ||      /\
+ *                             \/      ||
+ *                             STATE_DEFAULT
+ *                             ||      /\
+ *                             \/      ||
+ *     DEVICE_ADDRESS_ASSIGNED                 DEVICE_RESET
+ *                             ||      /\
+ *                             \/      ||
+ *                             STATE_ADDRESSED
+ *                             ||      /\
+ *                             \/      ||
+ *     DEVICE_CONFIGURED                       DEVICE_DE_CONFIGURED
+ *                             ||      /\
+ *                             \/      ||
+ *                             STATE_CONFIGURED
+ *
+ * udc_state_transition_up transitions up (in the direction from STATE_ATTACHED
+ * to STATE_CONFIGURED) from the specified initial state to the specified final
+ * state, passing through each intermediate state on the way.  If the initial
+ * state is at or above (i.e. nearer to STATE_CONFIGURED) the final state, then
+ * no state transitions will take place.
+ *
+ * udc_state_transition_down transitions down (in the direction from
+ * STATE_CONFIGURED to STATE_ATTACHED) from the specified initial state to the
+ * specified final state, passing through each intermediate state on the way.
+ * If the initial state is at or below (i.e. nearer to STATE_ATTACHED) the final
+ * state, then no state transitions will take place.
+ *
+ */
+
+static void mpc8xx_udc_state_transition_up (usb_device_state_t initial,
+                                           usb_device_state_t final)
+{
+       if (initial < final) {
+               switch (initial) {
+               case STATE_ATTACHED:
+                       usbd_device_event_irq (udc_device,
+                                              DEVICE_HUB_CONFIGURED, 0);
+                       if (final == STATE_POWERED)
+                               break;
+               case STATE_POWERED:
+                       usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
+                       if (final == STATE_DEFAULT)
+                               break;
+               case STATE_DEFAULT:
+                       usbd_device_event_irq (udc_device,
+                                              DEVICE_ADDRESS_ASSIGNED, 0);
+                       if (final == STATE_ADDRESSED)
+                               break;
+               case STATE_ADDRESSED:
+                       usbd_device_event_irq (udc_device, DEVICE_CONFIGURED,
+                                              0);
+               case STATE_CONFIGURED:
+                       break;
+               default:
+                       break;
+               }
+       }
+}
+
+static void mpc8xx_udc_state_transition_down (usb_device_state_t initial,
+                                             usb_device_state_t final)
+{
+       if (initial > final) {
+               switch (initial) {
+               case STATE_CONFIGURED:
+                       usbd_device_event_irq (udc_device,
+                                              DEVICE_DE_CONFIGURED, 0);
+                       if (final == STATE_ADDRESSED)
+                               break;
+               case STATE_ADDRESSED:
+                       usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
+                       if (final == STATE_DEFAULT)
+                               break;
+               case STATE_DEFAULT:
+                       usbd_device_event_irq (udc_device,
+                                              DEVICE_POWER_INTERRUPTION, 0);
+                       if (final == STATE_POWERED)
+                               break;
+               case STATE_POWERED:
+                       usbd_device_event_irq (udc_device, DEVICE_HUB_RESET,
+                                              0);
+               case STATE_ATTACHED:
+                       break;
+               default:
+                       break;
+               }
+       }
+}
+
+/* mpc8xx_udc_stall
+ *
+ * Force returning of STALL tokens on the given endpoint. Protocol or function
+ * STALL conditions are permissable here
+ */
+static void mpc8xx_udc_stall (unsigned int ep)
+{
+       usbp->usep[ep] |= STALL_BITMASK;
+}
+
+/* mpc8xx_udc_set_nak
+ *
+ * Force returning of NAK responses for the given endpoint as a kind of very
+ * simple flow control
+ */
+static void mpc8xx_udc_set_nak (unsigned int ep)
+{
+       usbp->usep[ep] |= NAK_BITMASK;
+       __asm__ ("eieio");
+}
+
+/* mpc8xx_udc_handle_txerr
+ *
+ * Handle errors relevant to TX. Return a status code to allow calling
+ * indicative of what if anything happened
+ */
+static short mpc8xx_udc_handle_txerr ()
+{
+       short ep = 0, ret = 0;
+
+       for (; ep < TX_RING_SIZE; ep++) {
+               if (usbp->usber & (0x10 << ep)) {
+
+                       /* Timeout or underrun */
+                       if (tx_cbd[ep]->cbd_sc & 0x06) {
+                               ret = 1;
+                               mpc8xx_udc_flush_tx_fifo (ep);
+
+                       } else {
+                               if (usbp->usep[ep] & STALL_BITMASK) {
+                                       if (!ep) {
+                                               usbp->usep[ep] &= ~STALL_BITMASK;
+                                       }
+                               }       /* else NAK */
+                       }
+                       usbp->usber |= (0x10 << ep);
+               }
+       }
+       return ret;
+}
+
+/* mpc8xx_udc_advance_rx
+ *
+ * Advance cbd rx
+ */
+static void mpc8xx_udc_advance_rx (volatile cbd_t ** rx_cbdp, int epid)
+{
+       if ((*rx_cbdp)->cbd_sc & RX_BD_W) {
+               *rx_cbdp = (volatile cbd_t *) (endpoints[epid]->rbase + CFG_IMMR);
+
+       } else {
+               (*rx_cbdp)++;
+       }
+}
+
+
+/* mpc8xx_udc_flush_tx_fifo
+ *
+ * Flush a given TX fifo. Assumes one tx cbd per endpoint
+ */
+static void mpc8xx_udc_flush_tx_fifo (int epid)
+{
+       volatile cbd_t *tx_cbdp = 0;
+
+       if (epid > MAX_ENDPOINTS) {
+               return;
+       }
+
+       /* TX stop */
+       immr->im_cpm.cp_cpcr = ((epid << 2) | 0x1D01);
+       __asm__ ("eieio");
+       while (immr->im_cpm.cp_cpcr & 0x01);
+
+       usbp->uscom = 0x40 | 0;
+
+       /* reset ring */
+       tx_cbdp = (cbd_t *) (endpoints[epid]->tbptr + CFG_IMMR);
+       tx_cbdp->cbd_sc = (TX_BD_I | TX_BD_W);
+
+
+       endpoints[epid]->tptr = endpoints[epid]->tbase;
+       endpoints[epid]->tstate = 0x00;
+       endpoints[epid]->tbcnt = 0x00;
+
+       /* TX start */
+       immr->im_cpm.cp_cpcr = ((epid << 2) | 0x2D01);
+       __asm__ ("eieio");
+       while (immr->im_cpm.cp_cpcr & 0x01);
+
+       return;
+}
+
+/* mpc8xx_udc_flush_rx_fifo
+ *
+ * For the sake of completeness of the namespace, it seems like
+ * a good-design-decision (tm) to include mpc8xx_udc_flush_rx_fifo();
+ * If RX_BD_E is true => a driver bug either here or in an upper layer
+ * not polling frequently enough. If RX_BD_E is true we have told the host
+ * we have accepted data but, the CPM found it had no-where to put that data
+ * which needless to say would be a bad thing.
+ */
+static void mpc8xx_udc_flush_rx_fifo ()
+{
+       int i = 0;
+
+       for (i = 0; i < RX_RING_SIZE; i++) {
+               if (!(rx_cbd[i]->cbd_sc & RX_BD_E)) {
+                       ERR ("buf %p used rx data len = 0x%x sc=0x%x!\n",
+                            rx_cbd[i], rx_cbd[i]->cbd_datlen,
+                            rx_cbd[i]->cbd_sc);
+
+               }
+       }
+       ERR ("BUG : Input over-run\n");
+}
+
+/* mpc8xx_udc_clear_rxbd
+ *
+ * Release control of RX CBD to CP.
+ */
+static void mpc8xx_udc_clear_rxbd (volatile cbd_t * rx_cbdp)
+{
+       rx_cbdp->cbd_datlen = 0x0000;
+       rx_cbdp->cbd_sc = ((rx_cbdp->cbd_sc & RX_BD_W) | (RX_BD_E | RX_BD_I));
+       __asm__ ("eieio");
+}
+
+/* mpc8xx_udc_tx_irq
+ *
+ * Parse for tx timeout, control RX or USB reset/busy conditions
+ * Return -1 on timeout, -2 on fatal error, else return zero
+ */
+static int mpc8xx_udc_tx_irq (int ep)
+{
+       int i = 0;
+
+       if (usbp->usber & (USB_TX_ERRMASK)) {
+               if (mpc8xx_udc_handle_txerr ()) {
+                       /* Timeout, controlling function must retry send */
+                       return -1;
+               }
+       }
+
+       if (usbp->usber & (USB_E_RESET | USB_E_BSY)) {
+               /* Fatal, abandon TX transaction */
+               return -2;
+       }
+
+       if (usbp->usber & USB_E_RXB) {
+               for (i = 0; i < RX_RING_SIZE; i++) {
+                       if (!(rx_cbd[i]->cbd_sc & RX_BD_E)) {
+                               if ((rx_cbd[i] == ep_ref[0].prx) || ep) {
+                                       return -2;
+                               }
+                       }
+               }
+       }
+
+       return 0;
+}
+
+/* mpc8xx_udc_ep_tx
+ *
+ * Transmit in a re-entrant fashion outbound USB packets.
+ * Implement retry/timeout mechanism described in USB specification
+ * Toggle DATA0/DATA1 pids as necessary
+ * Introduces non-standard tx_retry. The USB standard has no scope for slave
+ * devices to give up TX, however tx_retry stops us getting stuck in an endless
+ * TX loop.
+ */
+static int mpc8xx_udc_ep_tx (struct usb_endpoint_instance *epi)
+{
+       struct urb *urb = epi->tx_urb;
+       volatile cbd_t *tx_cbdp = 0;
+       unsigned int ep = 0, pkt_len = 0, x = 0, tx_retry = 0;
+       int ret = 0;
+
+       if (!epi || (epi->endpoint_address & 0x03) >= MAX_ENDPOINTS || !urb) {
+               return -1;
+       }
+
+       ep = epi->endpoint_address & 0x03;
+       tx_cbdp = (cbd_t *) (endpoints[ep]->tbptr + CFG_IMMR);
+
+       if (tx_cbdp->cbd_sc & TX_BD_R || usbp->usber & USB_E_TXB) {
+               mpc8xx_udc_flush_tx_fifo (ep);
+               usbp->usber |= USB_E_TXB;
+       };
+
+       while (tx_retry++ < 100) {
+               ret = mpc8xx_udc_tx_irq (ep);
+               if (ret == -1) {
+                       /* ignore timeout here */
+               } else if (ret == -2) {
+                       /* Abandon TX */
+                       mpc8xx_udc_flush_tx_fifo (ep);
+                       return -1;
+               }
+
+               tx_cbdp = (cbd_t *) (endpoints[ep]->tbptr + CFG_IMMR);
+               while (tx_cbdp->cbd_sc & TX_BD_R) {
+               };
+               tx_cbdp->cbd_sc = (tx_cbdp->cbd_sc & TX_BD_W);
+
+               pkt_len = urb->actual_length - epi->sent;
+
+               if (pkt_len > epi->tx_packetSize || pkt_len > EP_MAX_PKT) {
+                       pkt_len = MIN (epi->tx_packetSize, EP_MAX_PKT);
+               }
+
+               for (x = 0; x < pkt_len; x++) {
+                       *((unsigned char *) (tx_cbdp->cbd_bufaddr + x)) =
+                               urb->buffer[epi->sent + x];
+               }
+               tx_cbdp->cbd_datlen = pkt_len;
+               tx_cbdp->cbd_sc |= (CBD_TX_BITMASK | ep_ref[ep].pid);
+               __asm__ ("eieio");
+
+#ifdef __SIMULATE_ERROR__
+               if (++err_poison_test == 2) {
+                       err_poison_test = 0;
+                       tx_cbdp->cbd_sc &= ~TX_BD_TC;
+               }
+#endif
+
+               usbp->uscom = (USCOM_STR | ep);
+
+               while (!(usbp->usber & USB_E_TXB)) {
+                       ret = mpc8xx_udc_tx_irq (ep);
+                       if (ret == -1) {
+                               /* TX timeout */
+                               break;
+                       } else if (ret == -2) {
+                               if (usbp->usber & USB_E_TXB) {
+                                       usbp->usber |= USB_E_TXB;
+                               }
+                               mpc8xx_udc_flush_tx_fifo (ep);
+                               return -1;
+                       }
+               };
+
+               if (usbp->usber & USB_E_TXB) {
+                       usbp->usber |= USB_E_TXB;
+               }
+
+               /* ACK must be present <= 18bit times from TX */
+               if (ret == -1) {
+                       continue;
+               }
+
+               /* TX ACK : USB 2.0 8.7.2, Toggle PID, Advance TX */
+               epi->sent += pkt_len;
+               epi->last = MIN (urb->actual_length - epi->sent, epi->tx_packetSize);
+               TOGGLE_TX_PID (ep_ref[ep].pid);
+
+               if (epi->sent >= epi->tx_urb->actual_length) {
+
+                       epi->tx_urb->actual_length = 0;
+                       epi->sent = 0;
+
+                       if (ep_ref[ep].sc & EP_SEND_ZLP) {
+                               ep_ref[ep].sc &= ~EP_SEND_ZLP;
+                       } else {
+                               return 0;
+                       }
+               }
+       }
+
+       ERR ("TX fail, endpoint 0x%x tx bytes 0x%x/0x%x\n", ep, epi->sent,
+            epi->tx_urb->actual_length);
+
+       return -1;
+}
+
+/* mpc8xx_udc_dump_request
+ *
+ * Dump a control request to console
+ */
+static void mpc8xx_udc_dump_request (struct usb_device_request *request)
+{
+       DBG ("bmRequestType:%02x bRequest:%02x wValue:%04x "
+            "wIndex:%04x wLength:%04x ?\n",
+            request->bmRequestType,
+            request->bRequest,
+            request->wValue, request->wIndex, request->wLength);
+
+       return;
+}
+
+/* mpc8xx_udc_ep0_rx_setup
+ *
+ * Decode received ep0 SETUP packet. return non-zero on error
+ */
+static int mpc8xx_udc_ep0_rx_setup (volatile cbd_t * rx_cbdp)
+{
+       unsigned int x = 0;
+       struct urb *purb = ep_ref[0].urb;
+       struct usb_endpoint_instance *epi =
+               &udc_device->bus->endpoint_array[0];
+
+       for (; x < rx_cbdp->cbd_datlen; x++) {
+               *(((unsigned char *) &ep_ref[0].urb->device_request) + x) =
+                       *((unsigned char *) (rx_cbdp->cbd_bufaddr + x));
+       }
+
+       mpc8xx_udc_clear_rxbd (rx_cbdp);
+
+       if (ep0_recv_setup (purb)) {
+               mpc8xx_udc_dump_request (&purb->device_request);
+               return -1;
+       }
+
+       if ((purb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK)
+           == USB_REQ_HOST2DEVICE) {
+
+               switch (purb->device_request.bRequest) {
+               case USB_REQ_SET_ADDRESS:
+                       /* Send the Status OUT ZLP */
+                       ep_ref[0].pid = TX_BD_PID_DATA1;
+                       purb->actual_length = 0;
+                       mpc8xx_udc_init_tx (epi, purb);
+                       mpc8xx_udc_ep_tx (epi);
+
+                       /* Move to the addressed state */
+                       usbp->usaddr = udc_device->address;
+                       mpc8xx_udc_state_transition_up (udc_device->device_state,
+                                                       STATE_ADDRESSED);
+                       return 0;
+
+               case USB_REQ_SET_CONFIGURATION:
+                       if (!purb->device_request.wValue) {
+                               /* Respond at default address */
+                               usbp->usaddr = 0x00;
+                               mpc8xx_udc_state_transition_down (udc_device->device_state,
+                                                                 STATE_ADDRESSED);
+                       } else {
+                               /* TODO: Support multiple configurations */
+                               mpc8xx_udc_state_transition_up (udc_device->device_state,
+                                                               STATE_CONFIGURED);
+                               for (x = 1; x < MAX_ENDPOINTS; x++) {
+                                       if ((udc_device->bus->endpoint_array[x].endpoint_address & USB_ENDPOINT_DIR_MASK)
+                                           == USB_DIR_IN) {
+                                               ep_ref[x].pid = TX_BD_PID_DATA0;
+                                       } else {
+                                               ep_ref[x].pid = RX_BD_PID_DATA0;
+                                       }
+                                       /* Set configuration must unstall endpoints */
+                                       usbp->usep[x] &= ~STALL_BITMASK;
+                               }
+                       }
+                       break;
+               default:
+                       /* CDC/Vendor specific */
+                       break;
+               }
+
+               /* Send ZLP as ACK in Status OUT phase */
+               ep_ref[0].pid = TX_BD_PID_DATA1;
+               purb->actual_length = 0;
+               mpc8xx_udc_init_tx (epi, purb);
+               mpc8xx_udc_ep_tx (epi);
+
+       } else {
+
+               if (purb->actual_length) {
+                       ep_ref[0].pid = TX_BD_PID_DATA1;
+                       mpc8xx_udc_init_tx (epi, purb);
+
+                       if (!(purb->actual_length % EP0_MAX_PACKET_SIZE)) {
+                               ep_ref[0].sc |= EP_SEND_ZLP;
+                       }
+
+                       if (purb->device_request.wValue ==
+                           USB_DESCRIPTOR_TYPE_DEVICE) {
+                               if (le16_to_cpu (purb->device_request.wLength)
+                                   > purb->actual_length) {
+                                       /* Send EP0_MAX_PACKET_SIZE bytes
+                                        * unless correct size requested.
+                                        */
+                                       if (purb->actual_length > epi->tx_packetSize) {
+                                               purb->actual_length = epi->tx_packetSize;
+                                       }
+                               }
+                       }
+                       mpc8xx_udc_ep_tx (epi);
+
+               } else {
+                       /* Corrupt SETUP packet? */
+                       ERR ("Zero length data or SETUP with DATA-IN phase ?\n");
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+/* mpc8xx_udc_init_tx
+ *
+ * Setup some basic parameters for a TX transaction
+ */
+static void mpc8xx_udc_init_tx (struct usb_endpoint_instance *epi,
+                               struct urb *tx_urb)
+{
+       epi->sent = 0;
+       epi->last = 0;
+       epi->tx_urb = tx_urb;
+}
+
+/* mpc8xx_udc_ep0_rx
+ *
+ * Receive ep0/control USB data. Parse and possibly send a response.
+ */
+static void mpc8xx_udc_ep0_rx (volatile cbd_t * rx_cbdp)
+{
+       if (rx_cbdp->cbd_sc & RX_BD_PID_SETUP) {
+
+               /* Unconditionally accept SETUP packets */
+               if (mpc8xx_udc_ep0_rx_setup (rx_cbdp)) {
+                       mpc8xx_udc_stall (0);
+               }
+
+       } else {
+
+               mpc8xx_udc_clear_rxbd (rx_cbdp);
+
+               if ((rx_cbdp->cbd_datlen - 2)) {
+                       /* SETUP with a DATA phase
+                        * outside of SETUP packet.
+                        * Reply with STALL.
+                        */
+                       mpc8xx_udc_stall (0);
+               }
+       }
+}
+
+/* mpc8xx_udc_epn_rx
+ *
+ * Receive some data from cbd into USB system urb data abstraction
+ * Upper layers should NAK if there is insufficient RX data space
+ */
+static int mpc8xx_udc_epn_rx (unsigned int epid, volatile cbd_t * rx_cbdp)
+{
+       struct usb_endpoint_instance *epi = 0;
+       struct urb *urb = 0;
+       unsigned int x = 0;
+
+       if (epid >= MAX_ENDPOINTS || !rx_cbdp->cbd_datlen) {
+               return 0;
+       }
+
+       /* USB 2.0 PDF section 8.6.4
+        * Discard data with invalid PID it is a resend.
+        */
+       if (ep_ref[epid].pid != (rx_cbdp->cbd_sc & 0xC0)) {
+               return 1;
+       }
+       TOGGLE_RX_PID (ep_ref[epid].pid);
+
+       epi = &udc_device->bus->endpoint_array[epid];
+       urb = epi->rcv_urb;
+
+       for (; x < (rx_cbdp->cbd_datlen - 2); x++) {
+               *((unsigned char *) (urb->buffer + urb->actual_length + x)) =
+                       *((unsigned char *) (rx_cbdp->cbd_bufaddr + x));
+       }
+
+       if (x) {
+               usbd_rcv_complete (epi, x, 0);
+               if (ep_ref[epid].urb->status == RECV_ERROR) {
+                       DBG ("RX error unset NAK\n");
+                       udc_unset_nak (epid);
+               }
+       }
+       return x;
+}
+
+/* mpc8xx_udc_clock_init
+ *
+ * Obtain a clock reference for Full Speed Signaling
+ */
+static void mpc8xx_udc_clock_init (volatile immap_t * immr,
+                                  volatile cpm8xx_t * cp)
+{
+
+#if defined(CFG_USB_EXTC_CLK)
+
+       /* This has been tested with a 48MHz crystal on CLK6 */
+       switch (CFG_USB_EXTC_CLK) {
+       case 1:
+               immr->im_ioport.iop_papar |= 0x0100;
+               immr->im_ioport.iop_padir &= ~0x0100;
+               cp->cp_sicr |= 0x24;
+               break;
+       case 2:
+               immr->im_ioport.iop_papar |= 0x0200;
+               immr->im_ioport.iop_padir &= ~0x0200;
+               cp->cp_sicr |= 0x2D;
+               break;
+       case 3:
+               immr->im_ioport.iop_papar |= 0x0400;
+               immr->im_ioport.iop_padir &= ~0x0400;
+               cp->cp_sicr |= 0x36;
+               break;
+       case 4:
+               immr->im_ioport.iop_papar |= 0x0800;
+               immr->im_ioport.iop_padir &= ~0x0800;
+               cp->cp_sicr |= 0x3F;
+               break;
+       default:
+               udc_state = STATE_ERROR;
+               break;
+       }
+
+#elif defined(CFG_USB_BRGCLK)
+
+       /* This has been tested with brgclk == 50MHz */
+       int divisor = 0;
+
+       if (gd->cpu_clk < 48000000L) {
+               ERR ("brgclk is too slow for full-speed USB!\n");
+               udc_state = STATE_ERROR;
+               return;
+       }
+
+       /* Assume the brgclk is 'good enough', we want !(gd->cpu_clk%48Mhz)
+        * but, can /probably/ live with close-ish alternative rates.
+        */
+       divisor = (gd->cpu_clk / 48000000L) - 1;
+       cp->cp_sicr &= ~0x0000003F;
+
+       switch (CFG_USB_BRGCLK) {
+       case 1:
+               cp->cp_brgc1 |= (divisor | CPM_BRG_EN);
+               cp->cp_sicr &= ~0x2F;
+               break;
+       case 2:
+               cp->cp_brgc2 |= (divisor | CPM_BRG_EN);
+               cp->cp_sicr |= 0x00000009;
+               break;
+       case 3:
+               cp->cp_brgc3 |= (divisor | CPM_BRG_EN);
+               cp->cp_sicr |= 0x00000012;
+               break;
+       case 4:
+               cp->cp_brgc4 = (divisor | CPM_BRG_EN);
+               cp->cp_sicr |= 0x0000001B;
+               break;
+       default:
+               udc_state = STATE_ERROR;
+               break;
+       }
+
+#else
+#error "CFG_USB_EXTC_CLK or CFG_USB_BRGCLK must be defined"
+#endif
+
+}
+
+/* mpc8xx_udc_cbd_attach
+ *
+ * attach a cbd to and endpoint
+ */
+static void mpc8xx_udc_cbd_attach (int ep, uchar tx_size, uchar rx_size)
+{
+
+       if (!tx_cbd[ep] || !rx_cbd[ep] || ep >= MAX_ENDPOINTS) {
+               udc_state = STATE_ERROR;
+               return;
+       }
+
+       if (tx_size > USB_MAX_PKT || rx_size > USB_MAX_PKT ||
+           (!tx_size && !rx_size)) {
+               udc_state = STATE_ERROR;
+               return;
+       }
+
+       /* Attach CBD to appropiate Parameter RAM Endpoint data structure */
+       if (rx_size) {
+               endpoints[ep]->rbase = (u32) rx_cbd[rx_ct];
+               endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
+               rx_ct++;
+
+               if (!ep) {
+
+                       endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
+                       rx_cbd[rx_ct]->cbd_sc |= RX_BD_W;
+                       rx_ct++;
+
+               } else {
+                       rx_ct += 2;
+                       endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
+                       rx_cbd[rx_ct]->cbd_sc |= RX_BD_W;
+                       rx_ct++;
+               }
+
+               /* Where we expect to RX data on this endpoint */
+               ep_ref[ep].prx = rx_cbd[rx_ct - 1];
+       } else {
+
+               ep_ref[ep].prx = 0;
+               endpoints[ep]->rbase = 0;
+               endpoints[ep]->rbptr = 0;
+       }
+
+       if (tx_size) {
+               endpoints[ep]->tbase = (u32) tx_cbd[tx_ct];
+               endpoints[ep]->tbptr = (u32) tx_cbd[tx_ct];
+               tx_ct++;
+       } else {
+               endpoints[ep]->tbase = 0;
+               endpoints[ep]->tbptr = 0;
+       }
+
+       endpoints[ep]->tstate = 0;
+       endpoints[ep]->tbcnt = 0;
+       endpoints[ep]->mrblr = EP_MAX_PKT;
+       endpoints[ep]->rfcr = 0x18;
+       endpoints[ep]->tfcr = 0x18;
+       ep_ref[ep].sc |= EP_ATTACHED;
+
+       DBG ("ep %d rbase 0x%08x rbptr 0x%08x tbase 0x%08x tbptr 0x%08x prx = %p\n",
+               ep, endpoints[ep]->rbase, endpoints[ep]->rbptr,
+               endpoints[ep]->tbase, endpoints[ep]->tbptr,
+               ep_ref[ep].prx);
+
+       return;
+}
+
+/* mpc8xx_udc_cbd_init
+ *
+ * Allocate space for a cbd and allocate TX/RX data space
+ */
+static void mpc8xx_udc_cbd_init (void)
+{
+       int i = 0;
+
+       for (; i < TX_RING_SIZE; i++) {
+               tx_cbd[i] = (cbd_t *)
+                       mpc8xx_udc_alloc (sizeof (cbd_t), sizeof (int));
+       }
+
+       for (i = 0; i < RX_RING_SIZE; i++) {
+               rx_cbd[i] = (cbd_t *)
+                       mpc8xx_udc_alloc (sizeof (cbd_t), sizeof (int));
+       }
+
+       for (i = 0; i < TX_RING_SIZE; i++) {
+               tx_cbd[i]->cbd_bufaddr =
+                       mpc8xx_udc_alloc (EP_MAX_PKT, sizeof (int));
+
+               tx_cbd[i]->cbd_sc = (TX_BD_I | TX_BD_W);
+               tx_cbd[i]->cbd_datlen = 0x0000;
+       }
+
+
+       for (i = 0; i < RX_RING_SIZE; i++) {
+               rx_cbd[i]->cbd_bufaddr =
+                       mpc8xx_udc_alloc (EP_MAX_PKT, sizeof (int));
+               rx_cbd[i]->cbd_sc = (RX_BD_I | RX_BD_E);
+               rx_cbd[i]->cbd_datlen = 0x0000;
+
+       }
+
+       return;
+}
+
+/* mpc8xx_udc_endpoint_init
+ *
+ * Attach an endpoint to some dpram
+ */
+static void mpc8xx_udc_endpoint_init (void)
+{
+       int i = 0;
+
+       for (; i < MAX_ENDPOINTS; i++) {
+               endpoints[i] = (usb_epb_t *)
+                       mpc8xx_udc_alloc (sizeof (usb_epb_t), 32);
+       }
+}
+
+/* mpc8xx_udc_alloc
+ *
+ * Grab the address of some dpram
+ */
+static u32 mpc8xx_udc_alloc (u32 data_size, u32 alignment)
+{
+       u32 retaddr = address_base;
+
+       while (retaddr % alignment) {
+               retaddr++;
+       }
+       address_base += data_size;
+
+       return retaddr;
+}
+
+#endif /* CONFIG_MPC885_FAMILY && CONFIG_USB_DEVICE) */
diff --git a/drivers/usb/usbdcore_omap1510.c b/drivers/usb/usbdcore_omap1510.c
new file mode 100644 (file)
index 0000000..84bb936
--- /dev/null
@@ -0,0 +1,1547 @@
+/*
+ * (C) Copyright 2003
+ * Gerry Hamel, geh@ti.com, Texas Instruments
+ *
+ * Based on
+ * linux/drivers/usb/device/bi/omap.c
+ * TI OMAP1510 USB bus interface driver
+ *
+ * Author: MontaVista Software, Inc.
+ *        source@mvista.com
+ *        (C) Copyright 2002
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307         USA
+ *
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_OMAP1510) && defined(CONFIG_USB_DEVICE)
+
+#include <asm/io.h>
+#ifdef CONFIG_OMAP_SX1
+#include <i2c.h>
+#endif
+
+#include "usbdcore.h"
+#include "usbdcore_omap1510.h"
+#include "usbdcore_ep0.h"
+
+
+#define UDC_INIT_MDELAY                     80 /* Device settle delay */
+#define UDC_MAX_ENDPOINTS           31 /* Number of endpoints on this UDC */
+
+/* Some kind of debugging output... */
+#if 1
+#define UDCDBG(str)
+#define UDCDBGA(fmt,args...)
+#else  /* The bugs still exists... */
+#define UDCDBG(str) serial_printf("[%s] %s:%d: " str "\n", __FILE__,__FUNCTION__,__LINE__)
+#define UDCDBGA(fmt,args...) serial_printf("[%s] %s:%d: " fmt "\n", __FILE__,__FUNCTION__,__LINE__, ##args)
+#endif
+
+#if 1
+#define UDCREG(name)
+#define UDCREGL(name)
+#else  /* The bugs still exists... */
+#define UDCREG(name)    serial_printf("%s():%d: %s[%08x]=%.4x\n",__FUNCTION__,__LINE__, (#name), name, inw(name))      /* For 16-bit regs */
+#define UDCREGL(name)   serial_printf("%s():%d: %s[%08x]=%.8x\n",__FUNCTION__,__LINE__, (#name), name, inl(name))      /* For 32-bit regs */
+#endif
+
+
+static struct urb *ep0_urb = NULL;
+
+static struct usb_device_instance *udc_device; /* Used in interrupt handler */
+static u16 udc_devstat = 0;    /* UDC status (DEVSTAT) */
+static u32 udc_interrupts = 0;
+
+static void udc_stall_ep (unsigned int ep_addr);
+
+
+static struct usb_endpoint_instance *omap1510_find_ep (int ep)
+{
+       int i;
+
+       for (i = 0; i < udc_device->bus->max_endpoints; i++) {
+               if (udc_device->bus->endpoint_array[i].endpoint_address == ep)
+                       return &udc_device->bus->endpoint_array[i];
+       }
+       return NULL;
+}
+
+/* ************************************************************************** */
+/* IO
+ */
+
+/*
+ * omap1510_prepare_endpoint_for_rx
+ *
+ * This function implements TRM Figure 14-11.
+ *
+ * The endpoint to prepare for transfer is specified as a physical endpoint
+ * number.  For OUT (rx) endpoints 1 through 15, the corresponding endpoint
+ * configuration register is checked to see if the endpoint is ISO or not.
+ * If the OUT endpoint is valid and is non-ISO then its FIFO is enabled.
+ * No action is taken for endpoint 0 or for IN (tx) endpoints 16 through 30.
+ */
+static void omap1510_prepare_endpoint_for_rx (int ep_addr)
+{
+       int ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;
+
+       UDCDBGA ("omap1510_prepare_endpoint %x", ep_addr);
+       if (((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)) {
+               if ((inw (UDC_EP_RX (ep_num)) &
+                    (UDC_EPn_RX_Valid | UDC_EPn_RX_Iso)) ==
+                   UDC_EPn_RX_Valid) {
+                       /* rx endpoint is valid, non-ISO, so enable its FIFO */
+                       outw (UDC_EP_Sel | ep_num, UDC_EP_NUM);
+                       outw (UDC_Set_FIFO_En, UDC_CTRL);
+                       outw (0, UDC_EP_NUM);
+               }
+       }
+}
+
+/* omap1510_configure_endpoints
+ *
+ * This function implements TRM Figure 14-10.
+ */
+static void omap1510_configure_endpoints (struct usb_device_instance *device)
+{
+       int ep;
+       struct usb_bus_instance *bus;
+       struct usb_endpoint_instance *endpoint;
+       unsigned short ep_ptr;
+       unsigned short ep_size;
+       unsigned short ep_isoc;
+       unsigned short ep_doublebuffer;
+       int ep_addr;
+       int packet_size;
+       int buffer_size;
+       int attributes;
+
+       bus = device->bus;
+
+       /* There is a dedicated 2048 byte buffer for USB packets that may be
+        * arbitrarily partitioned among the endpoints on 8-byte boundaries.
+        * The first 8 bytes are reserved for receiving setup packets on
+        * endpoint 0.
+        */
+       ep_ptr = 8;             /* reserve the first 8 bytes for the setup fifo */
+
+       for (ep = 0; ep < bus->max_endpoints; ep++) {
+               endpoint = bus->endpoint_array + ep;
+               ep_addr = endpoint->endpoint_address;
+               if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
+                       /* IN endpoint */
+                       packet_size = endpoint->tx_packetSize;
+                       attributes = endpoint->tx_attributes;
+               } else {
+                       /* OUT endpoint */
+                       packet_size = endpoint->rcv_packetSize;
+                       attributes = endpoint->rcv_attributes;
+               }
+
+               switch (packet_size) {
+               case 0:
+                       ep_size = 0;
+                       break;
+               case 8:
+                       ep_size = 0;
+                       break;
+               case 16:
+                       ep_size = 1;
+                       break;
+               case 32:
+                       ep_size = 2;
+                       break;
+               case 64:
+                       ep_size = 3;
+                       break;
+               case 128:
+                       ep_size = 4;
+                       break;
+               case 256:
+                       ep_size = 5;
+                       break;
+               case 512:
+                       ep_size = 6;
+                       break;
+               default:
+                       UDCDBGA ("ep 0x%02x has bad packet size %d",
+                                ep_addr, packet_size);
+                       packet_size = 0;
+                       ep_size = 0;
+                       break;
+               }
+
+               switch (attributes & USB_ENDPOINT_XFERTYPE_MASK) {
+               case USB_ENDPOINT_XFER_CONTROL:
+               case USB_ENDPOINT_XFER_BULK:
+               case USB_ENDPOINT_XFER_INT:
+               default:
+                       /* A non-isochronous endpoint may optionally be
+                        * double-buffered. For now we disable
+                        * double-buffering.
+                        */
+                       ep_doublebuffer = 0;
+                       ep_isoc = 0;
+                       if (packet_size > 64)
+                               packet_size = 0;
+                       if (!ep || !ep_doublebuffer)
+                               buffer_size = packet_size;
+                       else
+                               buffer_size = packet_size * 2;
+                       break;
+               case USB_ENDPOINT_XFER_ISOC:
+                       /* Isochronous endpoints are always double-
+                        * buffered, but the double-buffering bit
+                        * in the endpoint configuration register
+                        * becomes the msb of the endpoint size so we
+                        * set the double-buffering flag to zero.
+                        */
+                       ep_doublebuffer = 0;
+                       ep_isoc = 1;
+                       buffer_size = packet_size * 2;
+                       break;
+               }
+
+               /* check to see if our packet buffer RAM is exhausted */
+               if ((ep_ptr + buffer_size) > 2048) {
+                       UDCDBGA ("out of packet RAM for ep 0x%02x buf size %d", ep_addr, buffer_size);
+                       buffer_size = packet_size = 0;
+               }
+
+               /* force a default configuration for endpoint 0 since it is
+                * always enabled
+                */
+               if (!ep && ((packet_size < 8) || (packet_size > 64))) {
+                       buffer_size = packet_size = 64;
+                       ep_size = 3;
+               }
+
+               if (!ep) {
+                       /* configure endpoint 0 */
+                       outw ((ep_size << 12) | (ep_ptr >> 3), UDC_EP0);
+                       /*UDCDBGA("ep 0 buffer offset 0x%03x packet size 0x%03x", */
+                       /*      ep_ptr, packet_size); */
+               } else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
+                       /* IN endpoint */
+                       if (packet_size) {
+                               outw ((1 << 15) | (ep_doublebuffer << 14) |
+                                     (ep_size << 12) | (ep_isoc << 11) |
+                                     (ep_ptr >> 3),
+                                     UDC_EP_TX (ep_addr &
+                                                USB_ENDPOINT_NUMBER_MASK));
+                               UDCDBGA ("IN ep %d buffer offset 0x%03x"
+                                        " packet size 0x%03x",
+                                        ep_addr & USB_ENDPOINT_NUMBER_MASK,
+                                        ep_ptr, packet_size);
+                       } else {
+                               outw (0,
+                                     UDC_EP_TX (ep_addr &
+                                                USB_ENDPOINT_NUMBER_MASK));
+                       }
+               } else {
+                       /* OUT endpoint */
+                       if (packet_size) {
+                               outw ((1 << 15) | (ep_doublebuffer << 14) |
+                                     (ep_size << 12) | (ep_isoc << 11) |
+                                     (ep_ptr >> 3),
+                                     UDC_EP_RX (ep_addr &
+                                                USB_ENDPOINT_NUMBER_MASK));
+                               UDCDBGA ("OUT ep %d buffer offset 0x%03x"
+                                        " packet size 0x%03x",
+                                        ep_addr & USB_ENDPOINT_NUMBER_MASK,
+                                        ep_ptr, packet_size);
+                       } else {
+                               outw (0,
+                                     UDC_EP_RX (ep_addr &
+                                                USB_ENDPOINT_NUMBER_MASK));
+                       }
+               }
+               ep_ptr += buffer_size;
+       }
+}
+
+/* omap1510_deconfigure_device
+ *
+ * This function balances omap1510_configure_device.
+ */
+static void omap1510_deconfigure_device (void)
+{
+       int epnum;
+
+       UDCDBG ("clear Cfg_Lock");
+       outw (inw (UDC_SYSCON1) & ~UDC_Cfg_Lock, UDC_SYSCON1);
+       UDCREG (UDC_SYSCON1);
+
+       /* deconfigure all endpoints */
+       for (epnum = 1; epnum <= 15; epnum++) {
+               outw (0, UDC_EP_RX (epnum));
+               outw (0, UDC_EP_TX (epnum));
+       }
+}
+
+/* omap1510_configure_device
+ *
+ * This function implements TRM Figure 14-9.
+ */
+static void omap1510_configure_device (struct usb_device_instance *device)
+{
+       omap1510_configure_endpoints (device);
+
+
+       /* Figure 14-9 indicates we should enable interrupts here, but we have
+        * other routines (udc_all_interrupts, udc_suspended_interrupts) to
+        * do that.
+        */
+
+       UDCDBG ("set Cfg_Lock");
+       outw (inw (UDC_SYSCON1) | UDC_Cfg_Lock, UDC_SYSCON1);
+       UDCREG (UDC_SYSCON1);
+}
+
+/* omap1510_write_noniso_tx_fifo
+ *
+ * This function implements TRM Figure 14-30.
+ *
+ * If the endpoint has an active tx_urb, then the next packet of data from the
+ * URB is written to the tx FIFO.  The total amount of data in the urb is given
+ * by urb->actual_length.  The maximum amount of data that can be sent in any
+ * one packet is given by endpoint->tx_packetSize.  The number of data bytes
+ * from this URB that have already been transmitted is given by endpoint->sent.
+ * endpoint->last is updated by this routine with the number of data bytes
+ * transmitted in this packet.
+ *
+ * In accordance with Figure 14-30, the EP_NUM register must already have been
+ * written with the value to select the appropriate tx FIFO before this routine
+ * is called.
+ */
+static void omap1510_write_noniso_tx_fifo (struct usb_endpoint_instance
+                                          *endpoint)
+{
+       struct urb *urb = endpoint->tx_urb;
+
+       if (urb) {
+               unsigned int last, i;
+
+               UDCDBGA ("urb->buffer %p, buffer_length %d, actual_length %d",
+                        urb->buffer, urb->buffer_length, urb->actual_length);
+               if ((last =
+                    MIN (urb->actual_length - endpoint->sent,
+                         endpoint->tx_packetSize))) {
+                       u8 *cp = urb->buffer + endpoint->sent;
+
+                       UDCDBGA ("endpoint->sent %d, tx_packetSize %d, last %d", endpoint->sent, endpoint->tx_packetSize, last);
+
+                       if (((u32) cp & 1) == 0) {      /* word aligned? */
+                               outsw (UDC_DATA, cp, last >> 1);
+                       } else {        /* byte aligned. */
+                               for (i = 0; i < (last >> 1); i++) {
+                                       u16 w = ((u16) cp[2 * i + 1] << 8) |
+                                               (u16) cp[2 * i];
+                                       outw (w, UDC_DATA);
+                               }
+                       }
+                       if (last & 1) {
+                               outb (*(cp + last - 1), UDC_DATA);
+                       }
+               }
+               endpoint->last = last;
+       }
+}
+
+/* omap1510_read_noniso_rx_fifo
+ *
+ * This function implements TRM Figure 14-28.
+ *
+ * If the endpoint has an active rcv_urb, then the next packet of data is read
+ * from the rcv FIFO and written to rcv_urb->buffer at offset
+ * rcv_urb->actual_length to append the packet data to the data from any
+ * previous packets for this transfer. We assume that there is sufficient room
+ * left in the buffer to hold an entire packet of data.
+ *
+ * The return value is the number of bytes read from the FIFO for this packet.
+ *
+ * In accordance with Figure 14-28, the EP_NUM register must already have been
+ * written with the value to select the appropriate rcv FIFO before this routine
+ * is called.
+ */
+static int omap1510_read_noniso_rx_fifo (struct usb_endpoint_instance
+                                        *endpoint)
+{
+       struct urb *urb = endpoint->rcv_urb;
+       int len = 0;
+
+       if (urb) {
+               len = inw (UDC_RXFSTAT);
+
+               if (len) {
+                       unsigned char *cp = urb->buffer + urb->actual_length;
+
+                       insw (UDC_DATA, cp, len >> 1);
+                       if (len & 1)
+                               *(cp + len - 1) = inb (UDC_DATA);
+               }
+       }
+       return len;
+}
+
+/* omap1510_prepare_for_control_write_status
+ *
+ * This function implements TRM Figure 14-17.
+ *
+ * We have to deal here with non-autodecoded control writes that haven't already
+ * been dealt with by ep0_recv_setup.  The non-autodecoded standard control
+ * write requests are: set/clear endpoint feature, set configuration, set
+ * interface, and set descriptor.  ep0_recv_setup handles set/clear requests for
+ * ENDPOINT_HALT by halting the endpoint for a set request and resetting the
+ * endpoint for a clear request.  ep0_recv_setup returns an error for
+ * SET_DESCRIPTOR requests which causes them to be terminated with a stall by
+ * the setup handler.  A SET_INTERFACE request is handled by ep0_recv_setup by
+ * generating a DEVICE_SET_INTERFACE event.  This leaves only the
+ * SET_CONFIGURATION event for us to deal with here.
+ *
+ */
+static void omap1510_prepare_for_control_write_status (struct urb *urb)
+{
+       struct usb_device_request *request = &urb->device_request;;
+
+       /* check for a SET_CONFIGURATION request */
+       if (request->bRequest == USB_REQ_SET_CONFIGURATION) {
+               int configuration = le16_to_cpu (request->wValue) & 0xff;
+               unsigned short devstat = inw (UDC_DEVSTAT);
+
+               if ((devstat & (UDC_ADD | UDC_CFG)) == UDC_ADD) {
+                       /* device is currently in ADDRESSED state */
+                       if (configuration) {
+                               /* Assume the specified non-zero configuration
+                                * value is valid and switch to the CONFIGURED
+                                * state.
+                                */
+                               outw (UDC_Dev_Cfg, UDC_SYSCON2);
+                       }
+               } else if ((devstat & UDC_CFG) == UDC_CFG) {
+                       /* device is currently in CONFIGURED state */
+                       if (!configuration) {
+                               /* Switch to ADDRESSED state. */
+                               outw (UDC_Clr_Cfg, UDC_SYSCON2);
+                       }
+               }
+       }
+
+       /* select EP0 tx FIFO */
+       outw (UDC_EP_Dir | UDC_EP_Sel, UDC_EP_NUM);
+       /* clear endpoint (no data bytes in status stage) */
+       outw (UDC_Clr_EP, UDC_CTRL);
+       /* enable the EP0 tx FIFO */
+       outw (UDC_Set_FIFO_En, UDC_CTRL);
+       /* deselect the endpoint */
+       outw (UDC_EP_Dir, UDC_EP_NUM);
+}
+
+/* udc_state_transition_up
+ * udc_state_transition_down
+ *
+ * Helper functions to implement device state changes. The device states and
+ * the events that transition between them are:
+ *
+ *                             STATE_ATTACHED
+ *                             ||      /\
+ *                             \/      ||
+ *     DEVICE_HUB_CONFIGURED                   DEVICE_HUB_RESET
+ *                             ||      /\
+ *                             \/      ||
+ *                             STATE_POWERED
+ *                             ||      /\
+ *                             \/      ||
+ *     DEVICE_RESET                            DEVICE_POWER_INTERRUPTION
+ *                             ||      /\
+ *                             \/      ||
+ *                             STATE_DEFAULT
+ *                             ||      /\
+ *                             \/      ||
+ *     DEVICE_ADDRESS_ASSIGNED                 DEVICE_RESET
+ *                             ||      /\
+ *                             \/      ||
+ *                             STATE_ADDRESSED
+ *                             ||      /\
+ *                             \/      ||
+ *     DEVICE_CONFIGURED                       DEVICE_DE_CONFIGURED
+ *                             ||      /\
+ *                             \/      ||
+ *                             STATE_CONFIGURED
+ *
+ * udc_state_transition_up transitions up (in the direction from STATE_ATTACHED
+ * to STATE_CONFIGURED) from the specified initial state to the specified final
+ * state, passing through each intermediate state on the way.  If the initial
+ * state is at or above (i.e. nearer to STATE_CONFIGURED) the final state, then
+ * no state transitions will take place.
+ *
+ * udc_state_transition_down transitions down (in the direction from
+ * STATE_CONFIGURED to STATE_ATTACHED) from the specified initial state to the
+ * specified final state, passing through each intermediate state on the way.
+ * If the initial state is at or below (i.e. nearer to STATE_ATTACHED) the final
+ * state, then no state transitions will take place.
+ *
+ * These functions must only be called with interrupts disabled.
+ */
+static void udc_state_transition_up (usb_device_state_t initial,
+                                    usb_device_state_t final)
+{
+       if (initial < final) {
+               switch (initial) {
+               case STATE_ATTACHED:
+                       usbd_device_event_irq (udc_device,
+                                              DEVICE_HUB_CONFIGURED, 0);
+                       if (final == STATE_POWERED)
+                               break;
+               case STATE_POWERED:
+                       usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
+                       if (final == STATE_DEFAULT)
+                               break;
+               case STATE_DEFAULT:
+                       usbd_device_event_irq (udc_device,
+                                              DEVICE_ADDRESS_ASSIGNED, 0);
+                       if (final == STATE_ADDRESSED)
+                               break;
+               case STATE_ADDRESSED:
+                       usbd_device_event_irq (udc_device, DEVICE_CONFIGURED,
+                                              0);
+               case STATE_CONFIGURED:
+                       break;
+               default:
+                       break;
+               }
+       }
+}
+
+static void udc_state_transition_down (usb_device_state_t initial,
+                                      usb_device_state_t final)
+{
+       if (initial > final) {
+               switch (initial) {
+               case STATE_CONFIGURED:
+                       usbd_device_event_irq (udc_device, DEVICE_DE_CONFIGURED, 0);
+                       if (final == STATE_ADDRESSED)
+                               break;
+               case STATE_ADDRESSED:
+                       usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
+                       if (final == STATE_DEFAULT)
+                               break;
+               case STATE_DEFAULT:
+                       usbd_device_event_irq (udc_device, DEVICE_POWER_INTERRUPTION, 0);
+                       if (final == STATE_POWERED)
+                               break;
+               case STATE_POWERED:
+                       usbd_device_event_irq (udc_device, DEVICE_HUB_RESET, 0);
+               case STATE_ATTACHED:
+                       break;
+               default:
+                       break;
+               }
+       }
+}
+
+/* Handle all device state changes.
+ * This function implements TRM Figure 14-21.
+ */
+static void omap1510_udc_state_changed (void)
+{
+       u16 bits;
+       u16 devstat = inw (UDC_DEVSTAT);
+
+       UDCDBGA ("state changed, devstat %x, old %x", devstat, udc_devstat);
+
+       bits = devstat ^ udc_devstat;
+       if (bits) {
+               if (bits & UDC_ATT) {
+                       if (devstat & UDC_ATT) {
+                               UDCDBG ("device attached and powered");
+                               udc_state_transition_up (udc_device->device_state, STATE_POWERED);
+                       } else {
+                               UDCDBG ("device detached or unpowered");
+                               udc_state_transition_down (udc_device->device_state, STATE_ATTACHED);
+                       }
+               }
+               if (bits & UDC_USB_Reset) {
+                       if (devstat & UDC_USB_Reset) {
+                               UDCDBG ("device reset in progess");
+                               udc_state_transition_down (udc_device->device_state, STATE_POWERED);
+                       } else {
+                               UDCDBG ("device reset completed");
+                       }
+               }
+               if (bits & UDC_DEF) {
+                       if (devstat & UDC_DEF) {
+                               UDCDBG ("device entering default state");
+                               udc_state_transition_up (udc_device->device_state, STATE_DEFAULT);
+                       } else {
+                               UDCDBG ("device leaving default state");
+                               udc_state_transition_down (udc_device->device_state, STATE_POWERED);
+                       }
+               }
+               if (bits & UDC_SUS) {
+                       if (devstat & UDC_SUS) {
+                               UDCDBG ("entering suspended state");
+                               usbd_device_event_irq (udc_device, DEVICE_BUS_INACTIVE, 0);
+                       } else {
+                               UDCDBG ("leaving suspended state");
+                               usbd_device_event_irq (udc_device, DEVICE_BUS_ACTIVITY, 0);
+                       }
+               }
+               if (bits & UDC_R_WK_OK) {
+                       UDCDBGA ("remote wakeup %s", (devstat & UDC_R_WK_OK)
+                                ? "enabled" : "disabled");
+               }
+               if (bits & UDC_ADD) {
+                       if (devstat & UDC_ADD) {
+                               UDCDBG ("default -> addressed");
+                               udc_state_transition_up (udc_device->device_state, STATE_ADDRESSED);
+                       } else {
+                               UDCDBG ("addressed -> default");
+                               udc_state_transition_down (udc_device->device_state, STATE_DEFAULT);
+                       }
+               }
+               if (bits & UDC_CFG) {
+                       if (devstat & UDC_CFG) {
+                               UDCDBG ("device configured");
+                               /* The ep0_recv_setup function generates the
+                                * DEVICE_CONFIGURED event when a
+                                * USB_REQ_SET_CONFIGURATION setup packet is
+                                * received, so we should already be in the
+                                * state STATE_CONFIGURED.
+                                */
+                               udc_state_transition_up (udc_device->device_state, STATE_CONFIGURED);
+                       } else {
+                               UDCDBG ("device deconfigured");
+                               udc_state_transition_down (udc_device->device_state, STATE_ADDRESSED);
+                       }
+               }
+       }
+
+       /* Clear interrupt source */
+       outw (UDC_DS_Chg, UDC_IRQ_SRC);
+
+       /* Save current DEVSTAT */
+       udc_devstat = devstat;
+}
+
+/* Handle SETUP USB interrupt.
+ * This function implements TRM Figure 14-14.
+ */
+static void omap1510_udc_setup (struct usb_endpoint_instance *endpoint)
+{
+       UDCDBG ("-> Entering device setup");
+
+       do {
+               const int setup_pktsize = 8;
+               unsigned char *datap =
+                       (unsigned char *) &ep0_urb->device_request;
+
+               /* Gain access to EP 0 setup FIFO */
+               outw (UDC_Setup_Sel, UDC_EP_NUM);
+
+               /* Read control request data */
+               insb (UDC_DATA, datap, setup_pktsize);
+
+               UDCDBGA ("EP0 setup read [%x %x %x %x %x %x %x %x]",
+                        *(datap + 0), *(datap + 1), *(datap + 2),
+                        *(datap + 3), *(datap + 4), *(datap + 5),
+                        *(datap + 6), *(datap + 7));
+
+               /* Reset EP0 setup FIFO */
+               outw (0, UDC_EP_NUM);
+       } while (inw (UDC_IRQ_SRC) & UDC_Setup);
+
+       /* Try to process setup packet */
+       if (ep0_recv_setup (ep0_urb)) {
+               /* Not a setup packet, stall next EP0 transaction */
+               udc_stall_ep (0);
+               UDCDBG ("can't parse setup packet, still waiting for setup");
+               return;
+       }
+
+       /* Check direction */
+       if ((ep0_urb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK)
+           == USB_REQ_HOST2DEVICE) {
+               UDCDBG ("control write on EP0");
+               if (le16_to_cpu (ep0_urb->device_request.wLength)) {
+                       /* We don't support control write data stages.
+                        * The only standard control write request with a data
+                        * stage is SET_DESCRIPTOR, and ep0_recv_setup doesn't
+                        * support that so we just stall those requests.  A
+                        * function driver might support a non-standard
+                        * write request with a data stage, but it isn't
+                        * obvious what we would do with the data if we read it
+                        * so we'll just stall it.  It seems like the API isn't
+                        * quite right here.
+                        */
+#if 0
+                       /* Here is what we would do if we did support control
+                        * write data stages.
+                        */
+                       ep0_urb->actual_length = 0;
+                       outw (0, UDC_EP_NUM);
+                       /* enable the EP0 rx FIFO */
+                       outw (UDC_Set_FIFO_En, UDC_CTRL);
+#else
+                       /* Stall this request */
+                       UDCDBG ("Stalling unsupported EP0 control write data "
+                               "stage.");
+                       udc_stall_ep (0);
+#endif
+               } else {
+                       omap1510_prepare_for_control_write_status (ep0_urb);
+               }
+       } else {
+               UDCDBG ("control read on EP0");
+               /* The ep0_recv_setup function has already placed our response
+                * packet data in ep0_urb->buffer and the packet length in
+                * ep0_urb->actual_length.
+                */
+               endpoint->tx_urb = ep0_urb;
+               endpoint->sent = 0;
+               /* select the EP0 tx FIFO */
+               outw (UDC_EP_Dir | UDC_EP_Sel, UDC_EP_NUM);
+               /* Write packet data to the FIFO.  omap1510_write_noniso_tx_fifo
+                * will update endpoint->last with the number of bytes written
+                * to the FIFO.
+                */
+               omap1510_write_noniso_tx_fifo (endpoint);
+               /* enable the FIFO to start the packet transmission */
+               outw (UDC_Set_FIFO_En, UDC_CTRL);
+               /* deselect the EP0 tx FIFO */
+               outw (UDC_EP_Dir, UDC_EP_NUM);
+       }
+
+       UDCDBG ("<- Leaving device setup");
+}
+
+/* Handle endpoint 0 RX interrupt
+ * This routine implements TRM Figure 14-16.
+ */
+static void omap1510_udc_ep0_rx (struct usb_endpoint_instance *endpoint)
+{
+       unsigned short status;
+
+       UDCDBG ("RX on EP0");
+       /* select EP0 rx FIFO */
+       outw (UDC_EP_Sel, UDC_EP_NUM);
+
+       status = inw (UDC_STAT_FLG);
+
+       if (status & UDC_ACK) {
+               /* Check direction */
+               if ((ep0_urb->device_request.bmRequestType
+                    & USB_REQ_DIRECTION_MASK) == USB_REQ_HOST2DEVICE) {
+                       /* This rx interrupt must be for a control write data
+                        * stage packet.
+                        *
+                        * We don't support control write data stages.
+                        * We should never end up here.
+                        */
+
+                       /* clear the EP0 rx FIFO */
+                       outw (UDC_Clr_EP, UDC_CTRL);
+
+                       /* deselect the EP0 rx FIFO */
+                       outw (0, UDC_EP_NUM);
+
+                       UDCDBG ("Stalling unexpected EP0 control write "
+                               "data stage packet");
+                       udc_stall_ep (0);
+               } else {
+                       /* This rx interrupt must be for a control read status
+                        * stage packet.
+                        */
+                       UDCDBG ("ACK on EP0 control read status stage packet");
+                       /* deselect EP0 rx FIFO */
+                       outw (0, UDC_EP_NUM);
+               }
+       } else if (status & UDC_STALL) {
+               UDCDBG ("EP0 stall during RX");
+               /* deselect EP0 rx FIFO */
+               outw (0, UDC_EP_NUM);
+       } else {
+               /* deselect EP0 rx FIFO */
+               outw (0, UDC_EP_NUM);
+       }
+}
+
+/* Handle endpoint 0 TX interrupt
+ * This routine implements TRM Figure 14-18.
+ */
+static void omap1510_udc_ep0_tx (struct usb_endpoint_instance *endpoint)
+{
+       unsigned short status;
+       struct usb_device_request *request = &ep0_urb->device_request;
+
+       UDCDBG ("TX on EP0");
+       /* select EP0 TX FIFO */
+       outw (UDC_EP_Dir | UDC_EP_Sel, UDC_EP_NUM);
+
+       status = inw (UDC_STAT_FLG);
+       if (status & UDC_ACK) {
+               /* Check direction */
+               if ((request->bmRequestType & USB_REQ_DIRECTION_MASK) ==
+                   USB_REQ_HOST2DEVICE) {
+                       /* This tx interrupt must be for a control write status
+                        * stage packet.
+                        */
+                       UDCDBG ("ACK on EP0 control write status stage packet");
+                       /* deselect EP0 TX FIFO */
+                       outw (UDC_EP_Dir, UDC_EP_NUM);
+               } else {
+                       /* This tx interrupt must be for a control read data
+                        * stage packet.
+                        */
+                       int wLength = le16_to_cpu (request->wLength);
+
+                       /* Update our count of bytes sent so far in this
+                        * transfer.
+                        */
+                       endpoint->sent += endpoint->last;
+
+                       /* We are finished with this transfer if we have sent
+                        * all of the bytes in our tx urb (urb->actual_length)
+                        * unless we need a zero-length terminating packet.  We
+                        * need a zero-length terminating packet if we returned
+                        * fewer bytes than were requested (wLength) by the host,
+                        * and the number of bytes we returned is an exact
+                        * multiple of the packet size endpoint->tx_packetSize.
+                        */
+                       if ((endpoint->sent == ep0_urb->actual_length)
+                           && ((ep0_urb->actual_length == wLength)
+                               || (endpoint->last !=
+                                   endpoint->tx_packetSize))) {
+                               /* Done with control read data stage. */
+                               UDCDBG ("control read data stage complete");
+                               /* deselect EP0 TX FIFO */
+                               outw (UDC_EP_Dir, UDC_EP_NUM);
+                               /* select EP0 RX FIFO to prepare for control
+                                * read status stage.
+                                */
+                               outw (UDC_EP_Sel, UDC_EP_NUM);
+                               /* clear the EP0 RX FIFO */
+                               outw (UDC_Clr_EP, UDC_CTRL);
+                               /* enable the EP0 RX FIFO */
+                               outw (UDC_Set_FIFO_En, UDC_CTRL);
+                               /* deselect the EP0 RX FIFO */
+                               outw (0, UDC_EP_NUM);
+                       } else {
+                               /* We still have another packet of data to send
+                                * in this control read data stage or else we
+                                * need a zero-length terminating packet.
+                                */
+                               UDCDBG ("ACK control read data stage packet");
+                               omap1510_write_noniso_tx_fifo (endpoint);
+                               /* enable the EP0 tx FIFO to start transmission */
+                               outw (UDC_Set_FIFO_En, UDC_CTRL);
+                               /* deselect EP0 TX FIFO */
+                               outw (UDC_EP_Dir, UDC_EP_NUM);
+                       }
+               }
+       } else if (status & UDC_STALL) {
+               UDCDBG ("EP0 stall during TX");
+               /* deselect EP0 TX FIFO */
+               outw (UDC_EP_Dir, UDC_EP_NUM);
+       } else {
+               /* deselect EP0 TX FIFO */
+               outw (UDC_EP_Dir, UDC_EP_NUM);
+       }
+}
+
+/* Handle RX transaction on non-ISO endpoint.
+ * This function implements TRM Figure 14-27.
+ * The ep argument is a physical endpoint number for a non-ISO OUT endpoint
+ * in the range 1 to 15.
+ */
+static void omap1510_udc_epn_rx (int ep)
+{
+       unsigned short status;
+
+       /* Check endpoint status */
+       status = inw (UDC_STAT_FLG);
+
+       if (status & UDC_ACK) {
+               int nbytes;
+               struct usb_endpoint_instance *endpoint =
+                       omap1510_find_ep (ep);
+
+               nbytes = omap1510_read_noniso_rx_fifo (endpoint);
+               usbd_rcv_complete (endpoint, nbytes, 0);
+
+               /* enable rx FIFO to prepare for next packet */
+               outw (UDC_Set_FIFO_En, UDC_CTRL);
+       } else if (status & UDC_STALL) {
+               UDCDBGA ("STALL on RX endpoint %d", ep);
+       } else if (status & UDC_NAK) {
+               UDCDBGA ("NAK on RX ep %d", ep);
+       } else {
+               serial_printf ("omap-bi: RX on ep %d with status %x", ep,
+                              status);
+       }
+}
+
+/* Handle TX transaction on non-ISO endpoint.
+ * This function implements TRM Figure 14-29.
+ * The ep argument is a physical endpoint number for a non-ISO IN endpoint
+ * in the range 16 to 30.
+ */
+static void omap1510_udc_epn_tx (int ep)
+{
+       unsigned short status;
+
+       /*serial_printf("omap1510_udc_epn_tx( %x )\n",ep); */
+
+       /* Check endpoint status */
+       status = inw (UDC_STAT_FLG);
+
+       if (status & UDC_ACK) {
+               struct usb_endpoint_instance *endpoint =
+                       omap1510_find_ep (ep);
+
+               /* We need to transmit a terminating zero-length packet now if
+                * we have sent all of the data in this URB and the transfer
+                * size was an exact multiple of the packet size.
+                */
+               if (endpoint->tx_urb
+                   && (endpoint->last == endpoint->tx_packetSize)
+                   && (endpoint->tx_urb->actual_length - endpoint->sent -
+                       endpoint->last == 0)) {
+                       /* Prepare to transmit a zero-length packet. */
+                       endpoint->sent += endpoint->last;
+                       /* write 0 bytes of data to FIFO */
+                       omap1510_write_noniso_tx_fifo (endpoint);
+                       /* enable tx FIFO to start transmission */
+                       outw (UDC_Set_FIFO_En, UDC_CTRL);
+               } else if (endpoint->tx_urb
+                          && endpoint->tx_urb->actual_length) {
+                       /* retire the data that was just sent */
+                       usbd_tx_complete (endpoint);
+                       /* Check to see if we have more data ready to transmit
+                        * now.
+                        */
+                       if (endpoint->tx_urb
+                           && endpoint->tx_urb->actual_length) {
+                               /* write data to FIFO */
+                               omap1510_write_noniso_tx_fifo (endpoint);
+                               /* enable tx FIFO to start transmission */
+                               outw (UDC_Set_FIFO_En, UDC_CTRL);
+                       }
+               }
+       } else if (status & UDC_STALL) {
+               UDCDBGA ("STALL on TX endpoint %d", ep);
+       } else if (status & UDC_NAK) {
+               UDCDBGA ("NAK on TX endpoint %d", ep);
+       } else {
+               /*serial_printf("omap-bi: TX on ep %d with status %x\n", ep, status); */
+       }
+}
+
+
+/*
+-------------------------------------------------------------------------------
+*/
+
+/* Handle general USB interrupts and dispatch according to type.
+ * This function implements TRM Figure 14-13.
+ */
+void omap1510_udc_irq (void)
+{
+       u16 irq_src = inw (UDC_IRQ_SRC);
+       int valid_irq = 0;
+
+       if (!(irq_src & ~UDC_SOF_Flg))  /* ignore SOF interrupts ) */
+               return;
+
+       UDCDBGA ("< IRQ #%d start >- %x", udc_interrupts, irq_src);
+       /*serial_printf("< IRQ #%d start >- %x\n", udc_interrupts, irq_src); */
+
+       if (irq_src & UDC_DS_Chg) {
+               /* Device status changed */
+               omap1510_udc_state_changed ();
+               valid_irq++;
+       }
+       if (irq_src & UDC_EP0_RX) {
+               /* Endpoint 0 receive */
+               outw (UDC_EP0_RX, UDC_IRQ_SRC); /* ack interrupt */
+               omap1510_udc_ep0_rx (udc_device->bus->endpoint_array + 0);
+               valid_irq++;
+       }
+       if (irq_src & UDC_EP0_TX) {
+               /* Endpoint 0 transmit */
+               outw (UDC_EP0_TX, UDC_IRQ_SRC); /* ack interrupt */
+               omap1510_udc_ep0_tx (udc_device->bus->endpoint_array + 0);
+               valid_irq++;
+       }
+       if (irq_src & UDC_Setup) {
+               /* Device setup */
+               omap1510_udc_setup (udc_device->bus->endpoint_array + 0);
+               valid_irq++;
+       }
+       /*if (!valid_irq) */
+       /*      serial_printf("unknown interrupt, IRQ_SRC %.4x\n", irq_src); */
+       UDCDBGA ("< IRQ #%d end >", udc_interrupts);
+       udc_interrupts++;
+}
+
+/* This function implements TRM Figure 14-26. */
+void omap1510_udc_noniso_irq (void)
+{
+       unsigned short epnum;
+       unsigned short irq_src = inw (UDC_IRQ_SRC);
+       int valid_irq = 0;
+
+       if (!(irq_src & (UDC_EPn_RX | UDC_EPn_TX)))
+               return;
+
+       UDCDBGA ("non-ISO IRQ, IRQ_SRC %x", inw (UDC_IRQ_SRC));
+
+       if (irq_src & UDC_EPn_RX) {     /* Endpoint N OUT transaction */
+               /* Determine the endpoint number for this interrupt */
+               epnum = (inw (UDC_EPN_STAT) & 0x0f00) >> 8;
+               UDCDBGA ("RX on ep %x", epnum);
+
+               /* acknowledge interrupt */
+               outw (UDC_EPn_RX, UDC_IRQ_SRC);
+
+               if (epnum) {
+                       /* select the endpoint FIFO */
+                       outw (UDC_EP_Sel | epnum, UDC_EP_NUM);
+
+                       omap1510_udc_epn_rx (epnum);
+
+                       /* deselect the endpoint FIFO */
+                       outw (epnum, UDC_EP_NUM);
+               }
+               valid_irq++;
+       }
+       if (irq_src & UDC_EPn_TX) {     /* Endpoint N IN transaction */
+               /* Determine the endpoint number for this interrupt */
+               epnum = (inw (UDC_EPN_STAT) & 0x000f) | USB_DIR_IN;
+               UDCDBGA ("TX on ep %x", epnum);
+
+               /* acknowledge interrupt */
+               outw (UDC_EPn_TX, UDC_IRQ_SRC);
+
+               if (epnum) {
+                       /* select the endpoint FIFO */
+                       outw (UDC_EP_Sel | UDC_EP_Dir | epnum, UDC_EP_NUM);
+
+                       omap1510_udc_epn_tx (epnum);
+
+                       /* deselect the endpoint FIFO */
+                       outw (UDC_EP_Dir | epnum, UDC_EP_NUM);
+               }
+               valid_irq++;
+       }
+       if (!valid_irq)
+               serial_printf (": unknown non-ISO interrupt, IRQ_SRC %.4x\n",
+                              irq_src);
+}
+
+/*
+-------------------------------------------------------------------------------
+*/
+
+
+/*
+ * Start of public functions.
+ */
+
+/* Called to start packet transmission. */
+void udc_endpoint_write (struct usb_endpoint_instance *endpoint)
+{
+       unsigned short epnum =
+               endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
+
+       UDCDBGA ("Starting transmit on ep %x", epnum);
+
+       if (endpoint->tx_urb) {
+               /* select the endpoint FIFO */
+               outw (UDC_EP_Sel | UDC_EP_Dir | epnum, UDC_EP_NUM);
+               /* write data to FIFO */
+               omap1510_write_noniso_tx_fifo (endpoint);
+               /* enable tx FIFO to start transmission */
+               outw (UDC_Set_FIFO_En, UDC_CTRL);
+               /* deselect the endpoint FIFO */
+               outw (UDC_EP_Dir | epnum, UDC_EP_NUM);
+       }
+}
+
+/* Start to initialize h/w stuff */
+int udc_init (void)
+{
+       u16 udc_rev;
+       uchar value;
+       ulong gpio;
+       int i;
+
+       /* Let the device settle down before we start */
+       for (i = 0; i < UDC_INIT_MDELAY; i++) udelay(1000);
+
+       udc_device = NULL;
+
+       UDCDBG ("starting");
+
+       /* Check peripheral reset. Must be 1 to make sure
+          MPU TIPB peripheral reset is inactive */
+       UDCREG (ARM_RSTCT2);
+
+       /* Set and check clock control.
+        * We might ought to be using the clock control API to do
+        * this instead of fiddling with the clock registers directly
+        * here.
+        */
+       outw ((1 << 4) | (1 << 5), CLOCK_CTRL);
+       UDCREG (CLOCK_CTRL);
+       /* Set and check APLL */
+       outw (0x0008, APLL_CTRL);
+       UDCREG (APLL_CTRL);
+       /* Set and check DPLL */
+       outw (0x2210, DPLL_CTRL);
+       UDCREG (DPLL_CTRL);
+       /* Set and check SOFT */
+       outw ((1 << 4) | (1 << 3) | 1, SOFT_REQ);
+       /* Short delay to wait for DPLL */
+       udelay (1000);
+
+       /* Print banner with device revision */
+       udc_rev = inw (UDC_REV) & 0xff;
+       printf ("USB:   TI OMAP1510 USB function module rev %d.%d\n",
+               udc_rev >> 4, udc_rev & 0xf);
+
+#ifdef CONFIG_OMAP_SX1
+       i2c_read (0x32, 0x04, 1, &value, 1);
+       value |= 0x04;
+       i2c_write (0x32, 0x04, 1, &value, 1);
+
+       i2c_read (0x32, 0x03, 1, &value, 1);
+       value |= 0x01;
+       i2c_write (0x32, 0x03, 1, &value, 1);
+
+       gpio = inl(GPIO_PIN_CONTROL_REG);
+       gpio |=  0x0002; /* A_IRDA_OFF */
+       gpio |=  0x0800; /* A_SWITCH   */
+       gpio |=  0x8000; /* A_USB_ON   */
+       outl (gpio, GPIO_PIN_CONTROL_REG);
+
+       gpio = inl(GPIO_DIR_CONTROL_REG);
+       gpio &= ~0x0002; /* A_IRDA_OFF */
+       gpio &= ~0x0800; /* A_SWITCH   */
+       gpio &= ~0x8000; /* A_USB_ON   */
+       outl (gpio, GPIO_DIR_CONTROL_REG);
+
+       gpio = inl(GPIO_DATA_OUTPUT_REG);
+       gpio |=  0x0002; /* A_IRDA_OFF */
+       gpio &= ~0x0800; /* A_SWITCH   */
+       gpio &= ~0x8000; /* A_USB_ON   */
+       outl (gpio, GPIO_DATA_OUTPUT_REG);
+#endif
+
+       /* The VBUS_MODE bit selects whether VBUS detection is done via
+        * software (1) or hardware (0).  When software detection is
+        * selected, VBUS_CTRL selects whether USB is not connected (0)
+        * or connected (1).
+        */
+       outl (inl (FUNC_MUX_CTRL_0) | UDC_VBUS_MODE, FUNC_MUX_CTRL_0);
+       outl (inl (FUNC_MUX_CTRL_0) & ~UDC_VBUS_CTRL, FUNC_MUX_CTRL_0);
+       UDCREGL (FUNC_MUX_CTRL_0);
+
+       /*
+        * At this point, device is ready for configuration...
+        */
+
+       UDCDBG ("disable USB interrupts");
+       outw (0, UDC_IRQ_EN);
+       UDCREG (UDC_IRQ_EN);
+
+       UDCDBG ("disable USB DMA");
+       outw (0, UDC_DMA_IRQ_EN);
+       UDCREG (UDC_DMA_IRQ_EN);
+
+       UDCDBG ("initialize SYSCON1");
+       outw (UDC_Self_Pwr | UDC_Pullup_En, UDC_SYSCON1);
+       UDCREG (UDC_SYSCON1);
+
+       return 0;
+}
+
+/* Stall endpoint */
+static void udc_stall_ep (unsigned int ep_addr)
+{
+       /*int ep_addr = PHYS_EP_TO_EP_ADDR(ep); */
+       int ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;
+
+       UDCDBGA ("stall ep_addr %d", ep_addr);
+
+       /* REVISIT?
+        * The OMAP TRM section 14.2.4.2 says we must check that the FIFO
+        * is empty before halting the endpoint.  The current implementation
+        * doesn't check that the FIFO is empty.
+        */
+
+       if (!ep_num) {
+               outw (UDC_Stall_Cmd, UDC_SYSCON2);
+       } else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
+               if (inw (UDC_EP_RX (ep_num)) & UDC_EPn_RX_Valid) {
+                       /* we have a valid rx endpoint, so halt it */
+                       outw (UDC_EP_Sel | ep_num, UDC_EP_NUM);
+                       outw (UDC_Set_Halt, UDC_CTRL);
+                       outw (ep_num, UDC_EP_NUM);
+               }
+       } else {
+               if (inw (UDC_EP_TX (ep_num)) & UDC_EPn_TX_Valid) {
+                       /* we have a valid tx endpoint, so halt it */
+                       outw (UDC_EP_Sel | UDC_EP_Dir | ep_num, UDC_EP_NUM);
+                       outw (UDC_Set_Halt, UDC_CTRL);
+                       outw (ep_num, UDC_EP_NUM);
+               }
+       }
+}
+
+/* Reset endpoint */
+#if 0
+static void udc_reset_ep (unsigned int ep_addr)
+{
+       /*int ep_addr = PHYS_EP_TO_EP_ADDR(ep); */
+       int ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;
+
+       UDCDBGA ("reset ep_addr %d", ep_addr);
+
+       if (!ep_num) {
+               /* control endpoint 0 can't be reset */
+       } else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
+               UDCDBGA ("UDC_EP_RX(%d) = 0x%04x", ep_num,
+                        inw (UDC_EP_RX (ep_num)));
+               if (inw (UDC_EP_RX (ep_num)) & UDC_EPn_RX_Valid) {
+                       /* we have a valid rx endpoint, so reset it */
+                       outw (ep_num | UDC_EP_Sel, UDC_EP_NUM);
+                       outw (UDC_Reset_EP, UDC_CTRL);
+                       outw (ep_num, UDC_EP_NUM);
+                       UDCDBGA ("OUT endpoint %d reset", ep_num);
+               }
+       } else {
+               UDCDBGA ("UDC_EP_TX(%d) = 0x%04x", ep_num,
+                        inw (UDC_EP_TX (ep_num)));
+               /* Resetting of tx endpoints seems to be causing the USB function
+                * module to fail, which causes problems when the driver is
+                * uninstalled.  We'll skip resetting tx endpoints for now until
+                * we figure out what the problem is.
+                */
+#if 0
+               if (inw (UDC_EP_TX (ep_num)) & UDC_EPn_TX_Valid) {
+                       /* we have a valid tx endpoint, so reset it */
+                       outw (ep_num | UDC_EP_Dir | UDC_EP_Sel, UDC_EP_NUM);
+                       outw (UDC_Reset_EP, UDC_CTRL);
+                       outw (ep_num | UDC_EP_Dir, UDC_EP_NUM);
+                       UDCDBGA ("IN endpoint %d reset", ep_num);
+               }
+#endif
+       }
+}
+#endif
+
+/* ************************************************************************** */
+
+/**
+ * udc_check_ep - check logical endpoint
+  *
+ * Return physical endpoint number to use for this logical endpoint or zero if not valid.
+ */
+#if 0
+int udc_check_ep (int logical_endpoint, int packetsize)
+{
+       if ((logical_endpoint == 0x80) ||
+           ((logical_endpoint & 0x8f) != logical_endpoint)) {
+               return 0;
+       }
+
+       switch (packetsize) {
+       case 8:
+       case 16:
+       case 32:
+       case 64:
+       case 128:
+       case 256:
+       case 512:
+               break;
+       default:
+               return 0;
+       }
+
+       return EP_ADDR_TO_PHYS_EP (logical_endpoint);
+}
+#endif
+
+/*
+ * udc_setup_ep - setup endpoint
+ *
+ * Associate a physical endpoint with endpoint_instance
+ */
+void udc_setup_ep (struct usb_device_instance *device,
+                  unsigned int ep, struct usb_endpoint_instance *endpoint)
+{
+       UDCDBGA ("setting up endpoint addr %x", endpoint->endpoint_address);
+
+       /* This routine gets called by bi_modinit for endpoint 0 and from
+        * bi_config for all of the other endpoints.  bi_config gets called
+        * during the DEVICE_CREATE, DEVICE_CONFIGURED, and
+        * DEVICE_SET_INTERFACE events.  We need to reconfigure the OMAP packet
+        * RAM after bi_config scans the selected device configuration and
+        * initializes the endpoint structures, but before this routine enables
+        * the OUT endpoint FIFOs.  Since bi_config calls this routine in a
+        * loop for endpoints 1 through UDC_MAX_ENDPOINTS, we reconfigure our
+        * packet RAM here when ep==1.
+        * I really hate to do this here, but it seems like the API exported
+        * by the USB bus interface controller driver to the usbd-bi module
+        * isn't quite right so there is no good place to do this.
+        */
+       if (ep == 1) {
+               omap1510_deconfigure_device ();
+               omap1510_configure_device (device);
+       }
+
+       if (endpoint && (ep < UDC_MAX_ENDPOINTS)) {
+               int ep_addr = endpoint->endpoint_address;
+
+               if (!ep_addr) {
+                       /* nothing to do for endpoint 0 */
+               } else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
+                       /* nothing to do for IN (tx) endpoints */
+               } else {        /* OUT (rx) endpoint */
+                       if (endpoint->rcv_packetSize) {
+                               /*struct urb* urb = &(urb_out_array[ep&0xFF]); */
+                               /*urb->endpoint = endpoint; */
+                               /*urb->device = device; */
+                               /*urb->buffer_length = sizeof(urb->buffer); */
+
+                               /*endpoint->rcv_urb = urb; */
+                               omap1510_prepare_endpoint_for_rx (ep_addr);
+                       }
+               }
+       }
+}
+
+/**
+ * udc_disable_ep - disable endpoint
+ * @ep:
+ *
+ * Disable specified endpoint
+ */
+#if 0
+void udc_disable_ep (unsigned int ep_addr)
+{
+       /*int ep_addr = PHYS_EP_TO_EP_ADDR(ep); */
+       int ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;
+       struct usb_endpoint_instance *endpoint = omap1510_find_ep (ep_addr);    /*udc_device->bus->endpoint_array + ep; */
+
+       UDCDBGA ("disable ep_addr %d", ep_addr);
+
+       if (!ep_num) {
+               /* nothing to do for endpoint 0 */ ;
+       } else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
+               if (endpoint->tx_packetSize) {
+                       /* we have a valid tx endpoint */
+                       /*usbd_flush_tx(endpoint); */
+                       endpoint->tx_urb = NULL;
+               }
+       } else {
+               if (endpoint->rcv_packetSize) {
+                       /* we have a valid rx endpoint */
+                       /*usbd_flush_rcv(endpoint); */
+                       endpoint->rcv_urb = NULL;
+               }
+       }
+}
+#endif
+
+/* ************************************************************************** */
+
+/**
+ * udc_connected - is the USB cable connected
+ *
+ * Return non-zero if cable is connected.
+ */
+#if 0
+int udc_connected (void)
+{
+       return ((inw (UDC_DEVSTAT) & UDC_ATT) == UDC_ATT);
+}
+#endif
+
+/* Turn on the USB connection by enabling the pullup resistor */
+void udc_connect (void)
+{
+       UDCDBG ("connect, enable Pullup");
+       outl (0x00000018, FUNC_MUX_CTRL_D);
+}
+
+/* Turn off the USB connection by disabling the pullup resistor */
+void udc_disconnect (void)
+{
+       UDCDBG ("disconnect, disable Pullup");
+       outl (0x00000000, FUNC_MUX_CTRL_D);
+}
+
+/* ************************************************************************** */
+
+
+/*
+ * udc_disable_interrupts - disable interrupts
+ * switch off interrupts
+ */
+#if 0
+void udc_disable_interrupts (struct usb_device_instance *device)
+{
+       UDCDBG ("disabling all interrupts");
+       outw (0, UDC_IRQ_EN);
+}
+#endif
+
+/* ************************************************************************** */
+
+/**
+ * udc_ep0_packetsize - return ep0 packetsize
+ */
+#if 0
+int udc_ep0_packetsize (void)
+{
+       return EP0_PACKETSIZE;
+}
+#endif
+
+/* Switch on the UDC */
+void udc_enable (struct usb_device_instance *device)
+{
+       UDCDBGA ("enable device %p, status %d", device, device->status);
+
+       /* initialize driver state variables */
+       udc_devstat = 0;
+
+       /* Save the device structure pointer */
+       udc_device = device;
+
+       /* Setup ep0 urb */
+       if (!ep0_urb) {
+               ep0_urb =
+                       usbd_alloc_urb (udc_device,
+                                       udc_device->bus->endpoint_array);
+       } else {
+               serial_printf ("udc_enable: ep0_urb already allocated %p\n",
+                              ep0_urb);
+       }
+
+       UDCDBG ("Check clock status");
+       UDCREG (STATUS_REQ);
+
+       /* The VBUS_MODE bit selects whether VBUS detection is done via
+        * software (1) or hardware (0).  When software detection is
+        * selected, VBUS_CTRL selects whether USB is not connected (0)
+        * or connected (1).
+        */
+       outl (inl (FUNC_MUX_CTRL_0) | UDC_VBUS_CTRL | UDC_VBUS_MODE,
+             FUNC_MUX_CTRL_0);
+       UDCREGL (FUNC_MUX_CTRL_0);
+
+       omap1510_configure_device (device);
+}
+
+/* Switch off the UDC */
+void udc_disable (void)
+{
+       UDCDBG ("disable UDC");
+
+       omap1510_deconfigure_device ();
+
+       /* The VBUS_MODE bit selects whether VBUS detection is done via
+        * software (1) or hardware (0).  When software detection is
+        * selected, VBUS_CTRL selects whether USB is not connected (0)
+        * or connected (1).
+        */
+       outl (inl (FUNC_MUX_CTRL_0) | UDC_VBUS_MODE, FUNC_MUX_CTRL_0);
+       outl (inl (FUNC_MUX_CTRL_0) & ~UDC_VBUS_CTRL, FUNC_MUX_CTRL_0);
+       UDCREGL (FUNC_MUX_CTRL_0);
+
+       /* Free ep0 URB */
+       if (ep0_urb) {
+               /*usbd_dealloc_urb(ep0_urb); */
+               ep0_urb = NULL;
+       }
+
+       /* Reset device pointer.
+        * We ought to do this here to balance the initialization of udc_device
+        * in udc_enable, but some of our other exported functions get called
+        * by the bus interface driver after udc_disable, so we have to hang on
+        * to the device pointer to avoid a null pointer dereference. */
+       /* udc_device = NULL; */
+}
+
+/**
+ * udc_startup - allow udc code to do any additional startup
+ */
+void udc_startup_events (struct usb_device_instance *device)
+{
+       /* The DEVICE_INIT event puts the USB device in the state STATE_INIT. */
+       usbd_device_event_irq (device, DEVICE_INIT, 0);
+
+       /* The DEVICE_CREATE event puts the USB device in the state
+        * STATE_ATTACHED.
+        */
+       usbd_device_event_irq (device, DEVICE_CREATE, 0);
+
+       /* Some USB controller driver implementations signal
+        * DEVICE_HUB_CONFIGURED and DEVICE_RESET events here.
+        * DEVICE_HUB_CONFIGURED causes a transition to the state STATE_POWERED,
+        * and DEVICE_RESET causes a transition to the state STATE_DEFAULT.
+        * The OMAP USB client controller has the capability to detect when the
+        * USB cable is connected to a powered USB bus via the ATT bit in the
+        * DEVSTAT register, so we will defer the DEVICE_HUB_CONFIGURED and
+        * DEVICE_RESET events until later.
+        */
+
+       udc_enable (device);
+}
+
+/**
+ * udc_irq - do pseudo interrupts
+ */
+void udc_irq(void)
+{
+       /* Loop while we have interrupts.
+        * If we don't do this, the input chain
+        * polling delay is likely to miss
+        * host requests.
+        */
+       while (inw (UDC_IRQ_SRC) & ~UDC_SOF_Flg) {
+               /* Handle any new IRQs */
+               omap1510_udc_irq ();
+               omap1510_udc_noniso_irq ();
+       }
+}
+
+/* Flow control */
+void udc_set_nak(int epid)
+{
+       /* TODO: implement this functionality in omap1510 */
+}
+
+void udc_unset_nak (int epid)
+{
+       /* TODO: implement this functionality in omap1510 */
+}
+#endif
diff --git a/drivers/usb_ohci.c b/drivers/usb_ohci.c
deleted file mode 100644 (file)
index 7ddcab6..0000000
+++ /dev/null
@@ -1,1919 +0,0 @@
-/*
- * URB OHCI HCD (Host Controller Driver) for USB on the AT91RM9200 and PCI bus.
- *
- * Interrupt support is added. Now, it has been tested
- * on ULI1575 chip and works well with USB keyboard.
- *
- * (C) Copyright 2007
- * Zhang Wei, Freescale Semiconductor, Inc. <wei.zhang@freescale.com>
- *
- * (C) Copyright 2003
- * Gary Jennejohn, DENX Software Engineering <gj@denx.de>
- *
- * Note: Much of this code has been derived from Linux 2.4
- * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
- * (C) Copyright 2000-2002 David Brownell
- *
- * Modified for the MP2USB by (C) Copyright 2005 Eric Benard
- * ebenard@eukrea.com - based on s3c24x0's driver
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.        See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- */
-/*
- * IMPORTANT NOTES
- * 1 - Read doc/README.generic_usb_ohci
- * 2 - this driver is intended for use with USB Mass Storage Devices
- *     (BBB) and USB keyboard. There is NO support for Isochronous pipes!
- * 2 - when running on a PQFP208 AT91RM9200, define CONFIG_AT91C_PQFP_UHPBUG
- *     to activate workaround for bug #41 or this driver will NOT work!
- */
-
-#include <common.h>
-
-#ifdef CONFIG_USB_OHCI_NEW
-
-#include <asm/byteorder.h>
-
-#if defined(CONFIG_PCI_OHCI)
-# include <pci.h>
-#endif
-
-#include <malloc.h>
-#include <usb.h>
-#include "usb_ohci.h"
-
-#if defined(CONFIG_ARM920T) || \
-    defined(CONFIG_S3C2400) || \
-    defined(CONFIG_S3C2410) || \
-    defined(CONFIG_440EP) || \
-    defined(CONFIG_PCI_OHCI) || \
-    defined(CONFIG_MPC5200)
-# define OHCI_USE_NPS          /* force NoPowerSwitching mode */
-#endif
-
-#undef OHCI_VERBOSE_DEBUG      /* not always helpful */
-#undef DEBUG
-#undef SHOW_INFO
-#undef OHCI_FILL_TRACE
-
-/* For initializing controller (mask in an HCFS mode too) */
-#define OHCI_CONTROL_INIT \
-       (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
-
-/*
- * e.g. PCI controllers need this
- */
-#ifdef CFG_OHCI_SWAP_REG_ACCESS
-# define readl(a) __swap_32(*((vu_long *)(a)))
-# define writel(a, b) (*((vu_long *)(b)) = __swap_32((vu_long)a))
-#else
-# define readl(a) (*((vu_long *)(a)))
-# define writel(a, b) (*((vu_long *)(b)) = ((vu_long)a))
-#endif /* CFG_OHCI_SWAP_REG_ACCESS */
-
-#define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
-
-#ifdef CONFIG_PCI_OHCI
-static struct pci_device_id ohci_pci_ids[] = {
-       {0x10b9, 0x5237},       /* ULI1575 PCI OHCI module ids */
-       {0x1033, 0x0035},       /* NEC PCI OHCI module ids */
-       /* Please add supported PCI OHCI controller ids here */
-       {0, 0}
-};
-#endif
-
-#ifdef DEBUG
-#define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg)
-#else
-#define dbg(format, arg...) do {} while(0)
-#endif /* DEBUG */
-#define err(format, arg...) printf("ERROR: " format "\n", ## arg)
-#undef SHOW_INFO
-#ifdef SHOW_INFO
-#define info(format, arg...) printf("INFO: " format "\n", ## arg)
-#else
-#define info(format, arg...) do {} while(0)
-#endif
-
-#ifdef CFG_OHCI_BE_CONTROLLER
-# define m16_swap(x) cpu_to_be16(x)
-# define m32_swap(x) cpu_to_be32(x)
-#else
-# define m16_swap(x) cpu_to_le16(x)
-# define m32_swap(x) cpu_to_le32(x)
-#endif /* CFG_OHCI_BE_CONTROLLER */
-
-/* global ohci_t */
-static ohci_t gohci;
-/* this must be aligned to a 256 byte boundary */
-struct ohci_hcca ghcca[1];
-/* a pointer to the aligned storage */
-struct ohci_hcca *phcca;
-/* this allocates EDs for all possible endpoints */
-struct ohci_device ohci_dev;
-/* RHSC flag */
-int got_rhsc;
-/* device which was disconnected */
-struct usb_device *devgone;
-
-/*-------------------------------------------------------------------------*/
-
-/* AMD-756 (D2 rev) reports corrupt register contents in some cases.
- * The erratum (#4) description is incorrect.  AMD's workaround waits
- * till some bits (mostly reserved) are clear; ok for all revs.
- */
-#define OHCI_QUIRK_AMD756 0xabcd
-#define read_roothub(hc, register, mask) ({ \
-       u32 temp = readl (&hc->regs->roothub.register); \
-       if (hc->flags & OHCI_QUIRK_AMD756) \
-               while (temp & mask) \
-                       temp = readl (&hc->regs->roothub.register); \
-       temp; })
-
-static u32 roothub_a (struct ohci *hc)
-       { return read_roothub (hc, a, 0xfc0fe000); }
-static inline u32 roothub_b (struct ohci *hc)
-       { return readl (&hc->regs->roothub.b); }
-static inline u32 roothub_status (struct ohci *hc)
-       { return readl (&hc->regs->roothub.status); }
-static u32 roothub_portstatus (struct ohci *hc, int i)
-       { return read_roothub (hc, portstatus [i], 0xffe0fce0); }
-
-/* forward declaration */
-static int hc_interrupt (void);
-static void
-td_submit_job (struct usb_device * dev, unsigned long pipe, void * buffer,
-       int transfer_len, struct devrequest * setup, urb_priv_t * urb, int interval);
-
-/*-------------------------------------------------------------------------*
- * URB support functions
- *-------------------------------------------------------------------------*/
-
-/* free HCD-private data associated with this URB */
-
-static void urb_free_priv (urb_priv_t * urb)
-{
-       int             i;
-       int             last;
-       struct td       * td;
-
-       last = urb->length - 1;
-       if (last >= 0) {
-               for (i = 0; i <= last; i++) {
-                       td = urb->td[i];
-                       if (td) {
-                               td->usb_dev = NULL;
-                               urb->td[i] = NULL;
-                       }
-               }
-       }
-       free(urb);
-}
-
-/*-------------------------------------------------------------------------*/
-
-#ifdef DEBUG
-static int sohci_get_current_frame_number (struct usb_device * dev);
-
-/* debug| print the main components of an URB
- * small: 0) header + data packets 1) just header */
-
-static void pkt_print (urb_priv_t *purb, struct usb_device * dev,
-       unsigned long pipe, void * buffer,
-       int transfer_len, struct devrequest * setup, char * str, int small)
-{
-       dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx",
-                       str,
-                       sohci_get_current_frame_number (dev),
-                       usb_pipedevice (pipe),
-                       usb_pipeendpoint (pipe),
-                       usb_pipeout (pipe)? 'O': 'I',
-                       usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"):
-                               (usb_pipecontrol (pipe)? "CTRL": "BULK"),
-                       (purb ? purb->actual_length : 0),
-                       transfer_len, dev->status);
-#ifdef OHCI_VERBOSE_DEBUG
-       if (!small) {
-               int i, len;
-
-               if (usb_pipecontrol (pipe)) {
-                       printf (__FILE__ ": cmd(8):");
-                       for (i = 0; i < 8 ; i++)
-                               printf (" %02x", ((__u8 *) setup) [i]);
-                       printf ("\n");
-               }
-               if (transfer_len > 0 && buffer) {
-                       printf (__FILE__ ": data(%d/%d):",
-                               (purb ? purb->actual_length : 0),
-                               transfer_len);
-                       len = usb_pipeout (pipe)?
-                                       transfer_len:
-                                       (purb ? purb->actual_length : 0);
-                       for (i = 0; i < 16 && i < len; i++)
-                               printf (" %02x", ((__u8 *) buffer) [i]);
-                       printf ("%s\n", i < len? "...": "");
-               }
-       }
-#endif
-}
-
-/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/
-void ep_print_int_eds (ohci_t *ohci, char * str) {
-       int i, j;
-        __u32 * ed_p;
-       for (i= 0; i < 32; i++) {
-               j = 5;
-               ed_p = &(ohci->hcca->int_table [i]);
-               if (*ed_p == 0)
-                   continue;
-               printf (__FILE__ ": %s branch int %2d(%2x):", str, i, i);
-               while (*ed_p != 0 && j--) {
-                       ed_t *ed = (ed_t *)m32_swap(ed_p);
-                       printf (" ed: %4x;", ed->hwINFO);
-                       ed_p = &ed->hwNextED;
-               }
-               printf ("\n");
-       }
-}
-
-static void ohci_dump_intr_mask (char *label, __u32 mask)
-{
-       dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s",
-               label,
-               mask,
-               (mask & OHCI_INTR_MIE) ? " MIE" : "",
-               (mask & OHCI_INTR_OC) ? " OC" : "",
-               (mask & OHCI_INTR_RHSC) ? " RHSC" : "",
-               (mask & OHCI_INTR_FNO) ? " FNO" : "",
-               (mask & OHCI_INTR_UE) ? " UE" : "",
-               (mask & OHCI_INTR_RD) ? " RD" : "",
-               (mask & OHCI_INTR_SF) ? " SF" : "",
-               (mask & OHCI_INTR_WDH) ? " WDH" : "",
-               (mask & OHCI_INTR_SO) ? " SO" : ""
-               );
-}
-
-static void maybe_print_eds (char *label, __u32 value)
-{
-       ed_t *edp = (ed_t *)value;
-
-       if (value) {
-               dbg ("%s %08x", label, value);
-               dbg ("%08x", edp->hwINFO);
-               dbg ("%08x", edp->hwTailP);
-               dbg ("%08x", edp->hwHeadP);
-               dbg ("%08x", edp->hwNextED);
-       }
-}
-
-static char * hcfs2string (int state)
-{
-       switch (state) {
-               case OHCI_USB_RESET:    return "reset";
-               case OHCI_USB_RESUME:   return "resume";
-               case OHCI_USB_OPER:     return "operational";
-               case OHCI_USB_SUSPEND:  return "suspend";
-       }
-       return "?";
-}
-
-/* dump control and status registers */
-static void ohci_dump_status (ohci_t *controller)
-{
-       struct ohci_regs        *regs = controller->regs;
-       __u32                   temp;
-
-       temp = readl (&regs->revision) & 0xff;
-       if (temp != 0x10)
-               dbg ("spec %d.%d", (temp >> 4), (temp & 0x0f));
-
-       temp = readl (&regs->control);
-       dbg ("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp,
-               (temp & OHCI_CTRL_RWE) ? " RWE" : "",
-               (temp & OHCI_CTRL_RWC) ? " RWC" : "",
-               (temp & OHCI_CTRL_IR) ? " IR" : "",
-               hcfs2string (temp & OHCI_CTRL_HCFS),
-               (temp & OHCI_CTRL_BLE) ? " BLE" : "",
-               (temp & OHCI_CTRL_CLE) ? " CLE" : "",
-               (temp & OHCI_CTRL_IE) ? " IE" : "",
-               (temp & OHCI_CTRL_PLE) ? " PLE" : "",
-               temp & OHCI_CTRL_CBSR
-               );
-
-       temp = readl (&regs->cmdstatus);
-       dbg ("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp,
-               (temp & OHCI_SOC) >> 16,
-               (temp & OHCI_OCR) ? " OCR" : "",
-               (temp & OHCI_BLF) ? " BLF" : "",
-               (temp & OHCI_CLF) ? " CLF" : "",
-               (temp & OHCI_HCR) ? " HCR" : ""
-               );
-
-       ohci_dump_intr_mask ("intrstatus", readl (&regs->intrstatus));
-       ohci_dump_intr_mask ("intrenable", readl (&regs->intrenable));
-
-       maybe_print_eds ("ed_periodcurrent", readl (&regs->ed_periodcurrent));
-
-       maybe_print_eds ("ed_controlhead", readl (&regs->ed_controlhead));
-       maybe_print_eds ("ed_controlcurrent", readl (&regs->ed_controlcurrent));
-
-       maybe_print_eds ("ed_bulkhead", readl (&regs->ed_bulkhead));
-       maybe_print_eds ("ed_bulkcurrent", readl (&regs->ed_bulkcurrent));
-
-       maybe_print_eds ("donehead", readl (&regs->donehead));
-}
-
-static void ohci_dump_roothub (ohci_t *controller, int verbose)
-{
-       __u32                   temp, ndp, i;
-
-       temp = roothub_a (controller);
-       ndp = (temp & RH_A_NDP);
-#ifdef CONFIG_AT91C_PQFP_UHPBUG
-       ndp = (ndp == 2) ? 1:0;
-#endif
-       if (verbose) {
-               dbg ("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp,
-                       ((temp & RH_A_POTPGT) >> 24) & 0xff,
-                       (temp & RH_A_NOCP) ? " NOCP" : "",
-                       (temp & RH_A_OCPM) ? " OCPM" : "",
-                       (temp & RH_A_DT) ? " DT" : "",
-                       (temp & RH_A_NPS) ? " NPS" : "",
-                       (temp & RH_A_PSM) ? " PSM" : "",
-                       ndp
-                       );
-               temp = roothub_b (controller);
-               dbg ("roothub.b: %08x PPCM=%04x DR=%04x",
-                       temp,
-                       (temp & RH_B_PPCM) >> 16,
-                       (temp & RH_B_DR)
-                       );
-               temp = roothub_status (controller);
-               dbg ("roothub.status: %08x%s%s%s%s%s%s",
-                       temp,
-                       (temp & RH_HS_CRWE) ? " CRWE" : "",
-                       (temp & RH_HS_OCIC) ? " OCIC" : "",
-                       (temp & RH_HS_LPSC) ? " LPSC" : "",
-                       (temp & RH_HS_DRWE) ? " DRWE" : "",
-                       (temp & RH_HS_OCI) ? " OCI" : "",
-                       (temp & RH_HS_LPS) ? " LPS" : ""
-                       );
-       }
-
-       for (i = 0; i < ndp; i++) {
-               temp = roothub_portstatus (controller, i);
-               dbg ("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s",
-                       i,
-                       temp,
-                       (temp & RH_PS_PRSC) ? " PRSC" : "",
-                       (temp & RH_PS_OCIC) ? " OCIC" : "",
-                       (temp & RH_PS_PSSC) ? " PSSC" : "",
-                       (temp & RH_PS_PESC) ? " PESC" : "",
-                       (temp & RH_PS_CSC) ? " CSC" : "",
-
-                       (temp & RH_PS_LSDA) ? " LSDA" : "",
-                       (temp & RH_PS_PPS) ? " PPS" : "",
-                       (temp & RH_PS_PRS) ? " PRS" : "",
-                       (temp & RH_PS_POCI) ? " POCI" : "",
-                       (temp & RH_PS_PSS) ? " PSS" : "",
-
-                       (temp & RH_PS_PES) ? " PES" : "",
-                       (temp & RH_PS_CCS) ? " CCS" : ""
-                       );
-       }
-}
-
-static void ohci_dump (ohci_t *controller, int verbose)
-{
-       dbg ("OHCI controller usb-%s state", controller->slot_name);
-
-       /* dumps some of the state we know about */
-       ohci_dump_status (controller);
-       if (verbose)
-               ep_print_int_eds (controller, "hcca");
-       dbg ("hcca frame #%04x", controller->hcca->frame_no);
-       ohci_dump_roothub (controller, 1);
-
-#endif /* DEBUG */
-
-/*-------------------------------------------------------------------------*
- * Interface functions (URB)
- *-------------------------------------------------------------------------*/
-
-/* get a transfer request */
-
-int sohci_submit_job(urb_priv_t *urb, struct devrequest *setup)
-{
-       ohci_t *ohci;
-       ed_t * ed;
-       urb_priv_t *purb_priv = urb;
-       int i, size = 0;
-       struct usb_device *dev = urb->dev;
-       unsigned long pipe = urb->pipe;
-       void *buffer = urb->transfer_buffer;
-       int transfer_len = urb->transfer_buffer_length;
-       int interval = urb->interval;
-
-       ohci = &gohci;
-
-       /* when controller's hung, permit only roothub cleanup attempts
-        * such as powering down ports */
-       if (ohci->disabled) {
-               err("sohci_submit_job: EPIPE");
-               return -1;
-       }
-
-       /* we're about to begin a new transaction here so mark the URB unfinished */
-       urb->finished = 0;
-
-       /* every endpoint has a ed, locate and fill it */
-       if (!(ed = ep_add_ed (dev, pipe, interval, 1))) {
-               err("sohci_submit_job: ENOMEM");
-               return -1;
-       }
-
-       /* for the private part of the URB we need the number of TDs (size) */
-       switch (usb_pipetype (pipe)) {
-               case PIPE_BULK: /* one TD for every 4096 Byte */
-                       size = (transfer_len - 1) / 4096 + 1;
-                       break;
-               case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */
-                       size = (transfer_len == 0)? 2:
-                                               (transfer_len - 1) / 4096 + 3;
-                       break;
-               case PIPE_INTERRUPT: /* 1 TD */
-                       size = 1;
-                       break;
-       }
-
-       ed->purb = urb;
-
-       if (size >= (N_URB_TD - 1)) {
-               err("need %d TDs, only have %d", size, N_URB_TD);
-               return -1;
-       }
-       purb_priv->pipe = pipe;
-
-       /* fill the private part of the URB */
-       purb_priv->length = size;
-       purb_priv->ed = ed;
-       purb_priv->actual_length = 0;
-
-       /* allocate the TDs */
-       /* note that td[0] was allocated in ep_add_ed */
-       for (i = 0; i < size; i++) {
-               purb_priv->td[i] = td_alloc (dev);
-               if (!purb_priv->td[i]) {
-                       purb_priv->length = i;
-                       urb_free_priv (purb_priv);
-                       err("sohci_submit_job: ENOMEM");
-                       return -1;
-               }
-       }
-
-       if (ed->state == ED_NEW || (ed->state & ED_DEL)) {
-               urb_free_priv (purb_priv);
-               err("sohci_submit_job: EINVAL");
-               return -1;
-       }
-
-       /* link the ed into a chain if is not already */
-       if (ed->state != ED_OPER)
-               ep_link (ohci, ed);
-
-       /* fill the TDs and link it to the ed */
-       td_submit_job(dev, pipe, buffer, transfer_len, setup, purb_priv, interval);
-
-       return 0;
-}
-
-static inline int sohci_return_job(struct ohci *hc, urb_priv_t *urb)
-{
-       struct ohci_regs *regs = hc->regs;
-
-       switch (usb_pipetype (urb->pipe)) {
-       case PIPE_INTERRUPT:
-               /* implicitly requeued */
-               if (urb->dev->irq_handle &&
-                               (urb->dev->irq_act_len = urb->actual_length)) {
-                       writel (OHCI_INTR_WDH, &regs->intrenable);
-                       readl (&regs->intrenable); /* PCI posting flush */
-                       urb->dev->irq_handle(urb->dev);
-                       writel (OHCI_INTR_WDH, &regs->intrdisable);
-                       readl (&regs->intrdisable); /* PCI posting flush */
-               }
-               urb->actual_length = 0;
-               td_submit_job (
-                               urb->dev,
-                               urb->pipe,
-                               urb->transfer_buffer,
-                               urb->transfer_buffer_length,
-                               NULL,
-                               urb,
-                               urb->interval);
-               break;
-       case PIPE_CONTROL:
-       case PIPE_BULK:
-               break;
-       default:
-               return 0;
-       }
-       return 1;
-}
-
-/*-------------------------------------------------------------------------*/
-
-#ifdef DEBUG
-/* tell us the current USB frame number */
-
-static int sohci_get_current_frame_number (struct usb_device *usb_dev)
-{
-       ohci_t *ohci = &gohci;
-
-       return m16_swap (ohci->hcca->frame_no);
-}
-#endif
-
-/*-------------------------------------------------------------------------*
- * ED handling functions
- *-------------------------------------------------------------------------*/
-
-/* search for the right branch to insert an interrupt ed into the int tree
- * do some load ballancing;
- * returns the branch and
- * sets the interval to interval = 2^integer (ld (interval)) */
-
-static int ep_int_ballance (ohci_t * ohci, int interval, int load)
-{
-       int i, branch = 0;
-
-       /* search for the least loaded interrupt endpoint
-        * branch of all 32 branches
-        */
-       for (i = 0; i < 32; i++)
-               if (ohci->ohci_int_load [branch] > ohci->ohci_int_load [i])
-                       branch = i;
-
-       branch = branch % interval;
-       for (i = branch; i < 32; i += interval)
-               ohci->ohci_int_load [i] += load;
-
-       return branch;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*  2^int( ld (inter)) */
-
-static int ep_2_n_interval (int inter)
-{
-       int i;
-       for (i = 0; ((inter >> i) > 1 ) && (i < 5); i++);
-       return 1 << i;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* the int tree is a binary tree
- * in order to process it sequentially the indexes of the branches have to be mapped
- * the mapping reverses the bits of a word of num_bits length */
-
-static int ep_rev (int num_bits, int word)
-{
-       int i, wout = 0;
-
-       for (i = 0; i < num_bits; i++)
-               wout |= (((word >> i) & 1) << (num_bits - i - 1));
-       return wout;
-}
-
-/*-------------------------------------------------------------------------*
- * ED handling functions
- *-------------------------------------------------------------------------*/
-
-/* link an ed into one of the HC chains */
-
-static int ep_link (ohci_t *ohci, ed_t *edi)
-{
-       volatile ed_t *ed = edi;
-       int int_branch;
-       int i;
-       int inter;
-       int interval;
-       int load;
-       __u32 * ed_p;
-
-       ed->state = ED_OPER;
-       ed->int_interval = 0;
-
-       switch (ed->type) {
-       case PIPE_CONTROL:
-               ed->hwNextED = 0;
-               if (ohci->ed_controltail == NULL) {
-                       writel (ed, &ohci->regs->ed_controlhead);
-               } else {
-                       ohci->ed_controltail->hwNextED = m32_swap ((unsigned long)ed);
-               }
-               ed->ed_prev = ohci->ed_controltail;
-               if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&
-                       !ohci->ed_rm_list[1] && !ohci->sleeping) {
-                       ohci->hc_control |= OHCI_CTRL_CLE;
-                       writel (ohci->hc_control, &ohci->regs->control);
-               }
-               ohci->ed_controltail = edi;
-               break;
-
-       case PIPE_BULK:
-               ed->hwNextED = 0;
-               if (ohci->ed_bulktail == NULL) {
-                       writel (ed, &ohci->regs->ed_bulkhead);
-               } else {
-                       ohci->ed_bulktail->hwNextED = m32_swap ((unsigned long)ed);
-               }
-               ed->ed_prev = ohci->ed_bulktail;
-               if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&
-                       !ohci->ed_rm_list[1] && !ohci->sleeping) {
-                       ohci->hc_control |= OHCI_CTRL_BLE;
-                       writel (ohci->hc_control, &ohci->regs->control);
-               }
-               ohci->ed_bulktail = edi;
-               break;
-
-       case PIPE_INTERRUPT:
-               load = ed->int_load;
-               interval = ep_2_n_interval (ed->int_period);
-               ed->int_interval = interval;
-               int_branch = ep_int_ballance (ohci, interval, load);
-               ed->int_branch = int_branch;
-
-               for (i = 0; i < ep_rev (6, interval); i += inter) {
-                       inter = 1;
-                       for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i) + int_branch]);
-                               (*ed_p != 0) && (((ed_t *)ed_p)->int_interval >= interval);
-                               ed_p = &(((ed_t *)ed_p)->hwNextED))
-                                       inter = ep_rev (6, ((ed_t *)ed_p)->int_interval);
-                       ed->hwNextED = *ed_p;
-                       *ed_p = m32_swap((unsigned long)ed);
-               }
-               break;
-       }
-       return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* scan the periodic table to find and unlink this ED */
-static void periodic_unlink ( struct ohci *ohci, volatile struct ed *ed,
-               unsigned index, unsigned period)
-{
-       for (; index < NUM_INTS; index += period) {
-               __u32   *ed_p = &ohci->hcca->int_table [index];
-
-               /* ED might have been unlinked through another path */
-               while (*ed_p != 0) {
-                       if (((struct ed *)m32_swap ((unsigned long)ed_p)) == ed) {
-                               *ed_p = ed->hwNextED;
-                               break;
-                       }
-                       ed_p = & (((struct ed *)m32_swap ((unsigned long)ed_p))->hwNextED);
-               }
-       }
-}
-
-/* unlink an ed from one of the HC chains.
- * just the link to the ed is unlinked.
- * the link from the ed still points to another operational ed or 0
- * so the HC can eventually finish the processing of the unlinked ed */
-
-static int ep_unlink (ohci_t *ohci, ed_t *edi)
-{
-       volatile ed_t *ed = edi;
-       int i;
-
-       ed->hwINFO |= m32_swap (OHCI_ED_SKIP);
-
-       switch (ed->type) {
-       case PIPE_CONTROL:
-               if (ed->ed_prev == NULL) {
-                       if (!ed->hwNextED) {
-                               ohci->hc_control &= ~OHCI_CTRL_CLE;
-                               writel (ohci->hc_control, &ohci->regs->control);
-                       }
-                       writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_controlhead);
-               } else {
-                       ed->ed_prev->hwNextED = ed->hwNextED;
-               }
-               if (ohci->ed_controltail == ed) {
-                       ohci->ed_controltail = ed->ed_prev;
-               } else {
-                       ((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;
-               }
-               break;
-
-       case PIPE_BULK:
-               if (ed->ed_prev == NULL) {
-                       if (!ed->hwNextED) {
-                               ohci->hc_control &= ~OHCI_CTRL_BLE;
-                               writel (ohci->hc_control, &ohci->regs->control);
-                       }
-                       writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_bulkhead);
-               } else {
-                       ed->ed_prev->hwNextED = ed->hwNextED;
-               }
-               if (ohci->ed_bulktail == ed) {
-                       ohci->ed_bulktail = ed->ed_prev;
-               } else {
-                       ((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;
-               }
-               break;
-
-       case PIPE_INTERRUPT:
-               periodic_unlink (ohci, ed, 0, 1);
-               for (i = ed->int_branch; i < 32; i += ed->int_interval)
-                   ohci->ohci_int_load[i] -= ed->int_load;
-               break;
-       }
-       ed->state = ED_UNLINK;
-       return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* add/reinit an endpoint; this should be done once at the
- * usb_set_configuration command, but the USB stack is a little bit
- * stateless so we do it at every transaction if the state of the ed
- * is ED_NEW then a dummy td is added and the state is changed to
- * ED_UNLINK in all other cases the state is left unchanged the ed
- * info fields are setted anyway even though most of them should not
- * change
- */
-static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe,
-               int interval, int load)
-{
-       td_t *td;
-       ed_t *ed_ret;
-       volatile ed_t *ed;
-
-       ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint (pipe) << 1) |
-                       (usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))];
-
-       if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) {
-               err("ep_add_ed: pending delete");
-               /* pending delete request */
-               return NULL;
-       }
-
-       if (ed->state == ED_NEW) {
-               ed->hwINFO = m32_swap (OHCI_ED_SKIP); /* skip ed */
-               /* dummy td; end of td list for ed */
-               td = td_alloc (usb_dev);
-               ed->hwTailP = m32_swap ((unsigned long)td);
-               ed->hwHeadP = ed->hwTailP;
-               ed->state = ED_UNLINK;
-               ed->type = usb_pipetype (pipe);
-               ohci_dev.ed_cnt++;
-       }
-
-       ed->hwINFO = m32_swap (usb_pipedevice (pipe)
-                       | usb_pipeendpoint (pipe) << 7
-                       | (usb_pipeisoc (pipe)? 0x8000: 0)
-                       | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000))
-                       | usb_pipeslow (pipe) << 13
-                       | usb_maxpacket (usb_dev, pipe) << 16);
-
-       if (ed->type == PIPE_INTERRUPT && ed->state == ED_UNLINK) {
-               ed->int_period = interval;
-               ed->int_load = load;
-       }
-
-       return ed_ret;
-}
-
-/*-------------------------------------------------------------------------*
- * TD handling functions
- *-------------------------------------------------------------------------*/
-
-/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */
-
-static void td_fill (ohci_t *ohci, unsigned int info,
-       void *data, int len,
-       struct usb_device *dev, int index, urb_priv_t *urb_priv)
-{
-       volatile td_t  *td, *td_pt;
-#ifdef OHCI_FILL_TRACE
-       int i;
-#endif
-
-       if (index > urb_priv->length) {
-               err("index > length");
-               return;
-       }
-       /* use this td as the next dummy */
-       td_pt = urb_priv->td [index];
-       td_pt->hwNextTD = 0;
-
-       /* fill the old dummy TD */
-       td = urb_priv->td [index] = (td_t *)(m32_swap (urb_priv->ed->hwTailP) & ~0xf);
-
-       td->ed = urb_priv->ed;
-       td->next_dl_td = NULL;
-       td->index = index;
-       td->data = (__u32)data;
-#ifdef OHCI_FILL_TRACE
-       if ((usb_pipetype(urb_priv->pipe) == PIPE_BULK) && usb_pipeout(urb_priv->pipe)) {
-               for (i = 0; i < len; i++)
-               printf("td->data[%d] %#2x ",i, ((unsigned char *)td->data)[i]);
-               printf("\n");
-       }
-#endif
-       if (!len)
-               data = 0;
-
-       td->hwINFO = m32_swap (info);
-       td->hwCBP = m32_swap ((unsigned long)data);
-       if (data)
-               td->hwBE = m32_swap ((unsigned long)(data + len - 1));
-       else
-               td->hwBE = 0;
-       td->hwNextTD = m32_swap ((unsigned long)td_pt);
-
-       /* append to queue */
-       td->ed->hwTailP = td->hwNextTD;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* prepare all TDs of a transfer */
-
-static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buffer,
-       int transfer_len, struct devrequest *setup, urb_priv_t *urb, int interval)
-{
-       ohci_t *ohci = &gohci;
-       int data_len = transfer_len;
-       void *data;
-       int cnt = 0;
-       __u32 info = 0;
-       unsigned int toggle = 0;
-
-       /* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */
-       if(usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) {
-               toggle = TD_T_TOGGLE;
-       } else {
-               toggle = TD_T_DATA0;
-               usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 1);
-       }
-       urb->td_cnt = 0;
-       if (data_len)
-               data = buffer;
-       else
-               data = 0;
-
-       switch (usb_pipetype (pipe)) {
-       case PIPE_BULK:
-               info = usb_pipeout (pipe)?
-                       TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ;
-               while(data_len > 4096) {
-                       td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, dev, cnt, urb);
-                       data += 4096; data_len -= 4096; cnt++;
-               }
-               info = usb_pipeout (pipe)?
-                       TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ;
-               td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, dev, cnt, urb);
-               cnt++;
-
-               if (!ohci->sleeping)
-                       writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
-               break;
-
-       case PIPE_CONTROL:
-               info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
-               td_fill (ohci, info, setup, 8, dev, cnt++, urb);
-               if (data_len > 0) {
-                       info = usb_pipeout (pipe)?
-                               TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1;
-                       /* NOTE:  mishandles transfers >8K, some >4K */
-                       td_fill (ohci, info, data, data_len, dev, cnt++, urb);
-               }
-               info = usb_pipeout (pipe)?
-                       TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1;
-               td_fill (ohci, info, data, 0, dev, cnt++, urb);
-               if (!ohci->sleeping)
-                       writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
-               break;
-
-       case PIPE_INTERRUPT:
-               info = usb_pipeout (urb->pipe)?
-                       TD_CC | TD_DP_OUT | toggle:
-                       TD_CC | TD_R | TD_DP_IN | toggle;
-               td_fill (ohci, info, data, data_len, dev, cnt++, urb);
-               break;
-       }
-       if (urb->length != cnt)
-               dbg("TD LENGTH %d != CNT %d", urb->length, cnt);
-}
-
-/*-------------------------------------------------------------------------*
- * Done List handling functions
- *-------------------------------------------------------------------------*/
-
-/* calculate the transfer length and update the urb */
-
-static void dl_transfer_length(td_t * td)
-{
-       __u32 tdINFO, tdBE, tdCBP;
-       urb_priv_t *lurb_priv = td->ed->purb;
-
-       tdINFO = m32_swap (td->hwINFO);
-       tdBE   = m32_swap (td->hwBE);
-       tdCBP  = m32_swap (td->hwCBP);
-
-       if (!(usb_pipetype (lurb_priv->pipe) == PIPE_CONTROL &&
-           ((td->index == 0) || (td->index == lurb_priv->length - 1)))) {
-               if (tdBE != 0) {
-                       if (td->hwCBP == 0)
-                               lurb_priv->actual_length += tdBE - td->data + 1;
-                       else
-                               lurb_priv->actual_length += tdCBP - td->data;
-               }
-       }
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* replies to the request have to be on a FIFO basis so
- * we reverse the reversed done-list */
-
-static td_t * dl_reverse_done_list (ohci_t *ohci)
-{
-       __u32 td_list_hc;
-       td_t *td_rev = NULL;
-       td_t *td_list = NULL;
-       urb_priv_t *lurb_priv = NULL;
-
-       td_list_hc = m32_swap (ohci->hcca->done_head) & 0xfffffff0;
-       ohci->hcca->done_head = 0;
-
-       while (td_list_hc) {
-               td_list = (td_t *)td_list_hc;
-
-               if (TD_CC_GET (m32_swap (td_list->hwINFO))) {
-                       lurb_priv = td_list->ed->purb;
-                       dbg(" USB-error/status: %x : %p",
-                                       TD_CC_GET (m32_swap (td_list->hwINFO)), td_list);
-                       if (td_list->ed->hwHeadP & m32_swap (0x1)) {
-                               if (lurb_priv && ((td_list->index + 1) < lurb_priv->length)) {
-                                       td_list->ed->hwHeadP =
-                                               (lurb_priv->td[lurb_priv->length - 1]->hwNextTD & m32_swap (0xfffffff0)) |
-                                                                       (td_list->ed->hwHeadP & m32_swap (0x2));
-                                       lurb_priv->td_cnt += lurb_priv->length - td_list->index - 1;
-                               } else
-                                       td_list->ed->hwHeadP &= m32_swap (0xfffffff2);
-                       }
-#ifdef CONFIG_MPC5200
-                       td_list->hwNextTD = 0;
-#endif
-               }
-
-               td_list->next_dl_td = td_rev;
-               td_rev = td_list;
-               td_list_hc = m32_swap (td_list->hwNextTD) & 0xfffffff0;
-       }
-       return td_list;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* td done list */
-static int dl_done_list (ohci_t *ohci, td_t *td_list)
-{
-       td_t *td_list_next = NULL;
-       ed_t *ed;
-       int cc = 0;
-       int stat = 0;
-       /* urb_t *urb; */
-       urb_priv_t *lurb_priv;
-       __u32 tdINFO, edHeadP, edTailP;
-
-       while (td_list) {
-               td_list_next = td_list->next_dl_td;
-
-               tdINFO = m32_swap (td_list->hwINFO);
-
-               ed = td_list->ed;
-               lurb_priv = ed->purb;
-
-               dl_transfer_length(td_list);
-
-               /* error code of transfer */
-               cc = TD_CC_GET (tdINFO);
-               if (cc != 0) {
-                       dbg("ConditionCode %#x", cc);
-                       stat = cc_to_error[cc];
-               }
-
-               /* see if this done list makes for all TD's of current URB,
-                * and mark the URB finished if so */
-               if (++(lurb_priv->td_cnt) == lurb_priv->length) {
-#if 1
-                       if ((ed->state & (ED_OPER | ED_UNLINK)) &&
-                           (lurb_priv->state != URB_DEL))
-#else
-                       if ((ed->state & (ED_OPER | ED_UNLINK)))
-#endif
-                               lurb_priv->finished = sohci_return_job(ohci,
-                                               lurb_priv);
-                       else
-                               dbg("dl_done_list: strange.., ED state %x, ed->state\n");
-               } else
-                       dbg("dl_done_list: processing TD %x, len %x\n", lurb_priv->td_cnt,
-                               lurb_priv->length);
-               if (ed->state != ED_NEW &&
-                         (usb_pipetype (lurb_priv->pipe) != PIPE_INTERRUPT)) {
-                       edHeadP = m32_swap (ed->hwHeadP) & 0xfffffff0;
-                       edTailP = m32_swap (ed->hwTailP);
-
-                       /* unlink eds if they are not busy */
-                       if ((edHeadP == edTailP) && (ed->state == ED_OPER))
-                               ep_unlink (ohci, ed);
-               }
-
-               td_list = td_list_next;
-       }
-       return stat;
-}
-
-/*-------------------------------------------------------------------------*
- * Virtual Root Hub
- *-------------------------------------------------------------------------*/
-
-/* Device descriptor */
-static __u8 root_hub_dev_des[] =
-{
-       0x12,       /*  __u8  bLength; */
-       0x01,       /*  __u8  bDescriptorType; Device */
-       0x10,       /*  __u16 bcdUSB; v1.1 */
-       0x01,
-       0x09,       /*  __u8  bDeviceClass; HUB_CLASSCODE */
-       0x00,       /*  __u8  bDeviceSubClass; */
-       0x00,       /*  __u8  bDeviceProtocol; */
-       0x08,       /*  __u8  bMaxPacketSize0; 8 Bytes */
-       0x00,       /*  __u16 idVendor; */
-       0x00,
-       0x00,       /*  __u16 idProduct; */
-       0x00,
-       0x00,       /*  __u16 bcdDevice; */
-       0x00,
-       0x00,       /*  __u8  iManufacturer; */
-       0x01,       /*  __u8  iProduct; */
-       0x00,       /*  __u8  iSerialNumber; */
-       0x01        /*  __u8  bNumConfigurations; */
-};
-
-/* Configuration descriptor */
-static __u8 root_hub_config_des[] =
-{
-       0x09,       /*  __u8  bLength; */
-       0x02,       /*  __u8  bDescriptorType; Configuration */
-       0x19,       /*  __u16 wTotalLength; */
-       0x00,
-       0x01,       /*  __u8  bNumInterfaces; */
-       0x01,       /*  __u8  bConfigurationValue; */
-       0x00,       /*  __u8  iConfiguration; */
-       0x40,       /*  __u8  bmAttributes;
-                Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
-       0x00,       /*  __u8  MaxPower; */
-
-       /* interface */
-       0x09,       /*  __u8  if_bLength; */
-       0x04,       /*  __u8  if_bDescriptorType; Interface */
-       0x00,       /*  __u8  if_bInterfaceNumber; */
-       0x00,       /*  __u8  if_bAlternateSetting; */
-       0x01,       /*  __u8  if_bNumEndpoints; */
-       0x09,       /*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
-       0x00,       /*  __u8  if_bInterfaceSubClass; */
-       0x00,       /*  __u8  if_bInterfaceProtocol; */
-       0x00,       /*  __u8  if_iInterface; */
-
-       /* endpoint */
-       0x07,       /*  __u8  ep_bLength; */
-       0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
-       0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
-       0x03,       /*  __u8  ep_bmAttributes; Interrupt */
-       0x02,       /*  __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
-       0x00,
-       0xff        /*  __u8  ep_bInterval; 255 ms */
-};
-
-static unsigned char root_hub_str_index0[] =
-{
-       0x04,                   /*  __u8  bLength; */
-       0x03,                   /*  __u8  bDescriptorType; String-descriptor */
-       0x09,                   /*  __u8  lang ID */
-       0x04,                   /*  __u8  lang ID */
-};
-
-static unsigned char root_hub_str_index1[] =
-{
-       28,                     /*  __u8  bLength; */
-       0x03,                   /*  __u8  bDescriptorType; String-descriptor */
-       'O',                    /*  __u8  Unicode */
-       0,                              /*  __u8  Unicode */
-       'H',                    /*  __u8  Unicode */
-       0,                              /*  __u8  Unicode */
-       'C',                    /*  __u8  Unicode */
-       0,                              /*  __u8  Unicode */
-       'I',                    /*  __u8  Unicode */
-       0,                              /*  __u8  Unicode */
-       ' ',                    /*  __u8  Unicode */
-       0,                              /*  __u8  Unicode */
-       'R',                    /*  __u8  Unicode */
-       0,                              /*  __u8  Unicode */
-       'o',                    /*  __u8  Unicode */
-       0,                              /*  __u8  Unicode */
-       'o',                    /*  __u8  Unicode */
-       0,                              /*  __u8  Unicode */
-       't',                    /*  __u8  Unicode */
-       0,                              /*  __u8  Unicode */
-       ' ',                    /*  __u8  Unicode */
-       0,                              /*  __u8  Unicode */
-       'H',                    /*  __u8  Unicode */
-       0,                              /*  __u8  Unicode */
-       'u',                    /*  __u8  Unicode */
-       0,                              /*  __u8  Unicode */
-       'b',                    /*  __u8  Unicode */
-       0,                              /*  __u8  Unicode */
-};
-
-/* Hub class-specific descriptor is constructed dynamically */
-
-/*-------------------------------------------------------------------------*/
-
-#define OK(x)                  len = (x); break
-#ifdef DEBUG
-#define WR_RH_STAT(x)          {info("WR:status %#8x", (x));writel((x), &gohci.regs->roothub.status);}
-#define WR_RH_PORTSTAT(x)      {info("WR:portstatus[%d] %#8x", wIndex-1, (x));writel((x), &gohci.regs->roothub.portstatus[wIndex-1]);}
-#else
-#define WR_RH_STAT(x)          writel((x), &gohci.regs->roothub.status)
-#define WR_RH_PORTSTAT(x)      writel((x), &gohci.regs->roothub.portstatus[wIndex-1])
-#endif
-#define RD_RH_STAT             roothub_status(&gohci)
-#define RD_RH_PORTSTAT         roothub_portstatus(&gohci,wIndex-1)
-
-/* request to virtual root hub */
-
-int rh_check_port_status(ohci_t *controller)
-{
-       __u32 temp, ndp, i;
-       int res;
-
-       res = -1;
-       temp = roothub_a (controller);
-       ndp = (temp & RH_A_NDP);
-#ifdef CONFIG_AT91C_PQFP_UHPBUG
-       ndp = (ndp == 2) ? 1:0;
-#endif
-       for (i = 0; i < ndp; i++) {
-               temp = roothub_portstatus (controller, i);
-               /* check for a device disconnect */
-               if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
-                       (RH_PS_PESC | RH_PS_CSC)) &&
-                       ((temp & RH_PS_CCS) == 0)) {
-                       res = i;
-                       break;
-               }
-       }
-       return res;
-}
-
-static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
-               void *buffer, int transfer_len, struct devrequest *cmd)
-{
-       void * data = buffer;
-       int leni = transfer_len;
-       int len = 0;
-       int stat = 0;
-       __u32 datab[4];
-       __u8 *data_buf = (__u8 *)datab;
-       __u16 bmRType_bReq;
-       __u16 wValue;
-       __u16 wIndex;
-       __u16 wLength;
-
-#ifdef DEBUG
-pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
-#else
-       wait_ms(1);
-#endif
-       if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
-               info("Root-Hub submit IRQ: NOT implemented");
-               return 0;
-       }
-
-       bmRType_bReq  = cmd->requesttype | (cmd->request << 8);
-       wValue        = cpu_to_le16 (cmd->value);
-       wIndex        = cpu_to_le16 (cmd->index);
-       wLength       = cpu_to_le16 (cmd->length);
-
-       info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x",
-               dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength);
-
-       switch (bmRType_bReq) {
-       /* Request Destination:
-          without flags: Device,
-          RH_INTERFACE: interface,
-          RH_ENDPOINT: endpoint,
-          RH_CLASS means HUB here,
-          RH_OTHER | RH_CLASS  almost ever means HUB_PORT here
-       */
-
-       case RH_GET_STATUS:
-                       *(__u16 *) data_buf = cpu_to_le16 (1); OK (2);
-       case RH_GET_STATUS | RH_INTERFACE:
-                       *(__u16 *) data_buf = cpu_to_le16 (0); OK (2);
-       case RH_GET_STATUS | RH_ENDPOINT:
-                       *(__u16 *) data_buf = cpu_to_le16 (0); OK (2);
-       case RH_GET_STATUS | RH_CLASS:
-                       *(__u32 *) data_buf = cpu_to_le32 (
-                               RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));
-                       OK (4);
-       case RH_GET_STATUS | RH_OTHER | RH_CLASS:
-                       *(__u32 *) data_buf = cpu_to_le32 (RD_RH_PORTSTAT); OK (4);
-
-       case RH_CLEAR_FEATURE | RH_ENDPOINT:
-               switch (wValue) {
-                       case (RH_ENDPOINT_STALL): OK (0);
-               }
-               break;
-
-       case RH_CLEAR_FEATURE | RH_CLASS:
-               switch (wValue) {
-                       case RH_C_HUB_LOCAL_POWER:
-                               OK(0);
-                       case (RH_C_HUB_OVER_CURRENT):
-                                       WR_RH_STAT(RH_HS_OCIC); OK (0);
-               }
-               break;
-
-       case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
-               switch (wValue) {
-                       case (RH_PORT_ENABLE):
-                                       WR_RH_PORTSTAT (RH_PS_CCS ); OK (0);
-                       case (RH_PORT_SUSPEND):
-                                       WR_RH_PORTSTAT (RH_PS_POCI); OK (0);
-                       case (RH_PORT_POWER):
-                                       WR_RH_PORTSTAT (RH_PS_LSDA); OK (0);
-                       case (RH_C_PORT_CONNECTION):
-                                       WR_RH_PORTSTAT (RH_PS_CSC ); OK (0);
-                       case (RH_C_PORT_ENABLE):
-                                       WR_RH_PORTSTAT (RH_PS_PESC); OK (0);
-                       case (RH_C_PORT_SUSPEND):
-                                       WR_RH_PORTSTAT (RH_PS_PSSC); OK (0);
-                       case (RH_C_PORT_OVER_CURRENT):
-                                       WR_RH_PORTSTAT (RH_PS_OCIC); OK (0);
-                       case (RH_C_PORT_RESET):
-                                       WR_RH_PORTSTAT (RH_PS_PRSC); OK (0);
-               }
-               break;
-
-       case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
-               switch (wValue) {
-                       case (RH_PORT_SUSPEND):
-                                       WR_RH_PORTSTAT (RH_PS_PSS ); OK (0);
-                       case (RH_PORT_RESET): /* BUG IN HUP CODE *********/
-                                       if (RD_RH_PORTSTAT & RH_PS_CCS)
-                                           WR_RH_PORTSTAT (RH_PS_PRS);
-                                       OK (0);
-                       case (RH_PORT_POWER):
-                                       WR_RH_PORTSTAT (RH_PS_PPS );
-                                       wait_ms(100);
-                                       OK (0);
-                       case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/
-                                       if (RD_RH_PORTSTAT & RH_PS_CCS)
-                                           WR_RH_PORTSTAT (RH_PS_PES );
-                                       OK (0);
-               }
-               break;
-
-       case RH_SET_ADDRESS: gohci.rh.devnum = wValue; OK(0);
-
-       case RH_GET_DESCRIPTOR:
-               switch ((wValue & 0xff00) >> 8) {
-                       case (0x01): /* device descriptor */
-                               len = min_t(unsigned int,
-                                         leni,
-                                         min_t(unsigned int,
-                                             sizeof (root_hub_dev_des),
-                                             wLength));
-                               data_buf = root_hub_dev_des; OK(len);
-                       case (0x02): /* configuration descriptor */
-                               len = min_t(unsigned int,
-                                         leni,
-                                         min_t(unsigned int,
-                                             sizeof (root_hub_config_des),
-                                             wLength));
-                               data_buf = root_hub_config_des; OK(len);
-                       case (0x03): /* string descriptors */
-                               if(wValue==0x0300) {
-                                       len = min_t(unsigned int,
-                                                 leni,
-                                                 min_t(unsigned int,
-                                                     sizeof (root_hub_str_index0),
-                                                     wLength));
-                                       data_buf = root_hub_str_index0;
-                                       OK(len);
-                               }
-                               if(wValue==0x0301) {
-                                       len = min_t(unsigned int,
-                                                 leni,
-                                                 min_t(unsigned int,
-                                                     sizeof (root_hub_str_index1),
-                                                     wLength));
-                                       data_buf = root_hub_str_index1;
-                                       OK(len);
-                       }
-                       default:
-                               stat = USB_ST_STALLED;
-               }
-               break;
-
-       case RH_GET_DESCRIPTOR | RH_CLASS:
-       {
-               __u32 temp = roothub_a (&gohci);
-
-               data_buf [0] = 9;               /* min length; */
-               data_buf [1] = 0x29;
-               data_buf [2] = temp & RH_A_NDP;
-#ifdef CONFIG_AT91C_PQFP_UHPBUG
-               data_buf [2] = (data_buf [2] == 2) ? 1:0;
-#endif
-               data_buf [3] = 0;
-               if (temp & RH_A_PSM)    /* per-port power switching? */
-                       data_buf [3] |= 0x1;
-               if (temp & RH_A_NOCP)   /* no overcurrent reporting? */
-                       data_buf [3] |= 0x10;
-               else if (temp & RH_A_OCPM)      /* per-port overcurrent reporting? */
-                       data_buf [3] |= 0x8;
-
-               /* corresponds to data_buf[4-7] */
-               datab [1] = 0;
-               data_buf [5] = (temp & RH_A_POTPGT) >> 24;
-               temp = roothub_b (&gohci);
-               data_buf [7] = temp & RH_B_DR;
-               if (data_buf [2] < 7) {
-                       data_buf [8] = 0xff;
-               } else {
-                       data_buf [0] += 2;
-                       data_buf [8] = (temp & RH_B_DR) >> 8;
-                       data_buf [10] = data_buf [9] = 0xff;
-               }
-
-               len = min_t(unsigned int, leni,
-                           min_t(unsigned int, data_buf [0], wLength));
-               OK (len);
-       }
-
-       case RH_GET_CONFIGURATION:      *(__u8 *) data_buf = 0x01; OK (1);
-
-       case RH_SET_CONFIGURATION:      WR_RH_STAT (0x10000); OK (0);
-
-       default:
-               dbg ("unsupported root hub command");
-               stat = USB_ST_STALLED;
-       }
-
-#ifdef DEBUG
-       ohci_dump_roothub (&gohci, 1);
-#else
-       wait_ms(1);
-#endif
-
-       len = min_t(int, len, leni);
-       if (data != data_buf)
-           memcpy (data, data_buf, len);
-       dev->act_len = len;
-       dev->status = stat;
-
-#ifdef DEBUG
-       pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/);
-#else
-       wait_ms(1);
-#endif
-
-       return stat;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* common code for handling submit messages - used for all but root hub */
-/* accesses. */
-int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-               int transfer_len, struct devrequest *setup, int interval)
-{
-       int stat = 0;
-       int maxsize = usb_maxpacket(dev, pipe);
-       int timeout;
-       urb_priv_t *urb;
-
-       urb = malloc(sizeof(urb_priv_t));
-       memset(urb, 0, sizeof(urb_priv_t));
-
-       urb->dev = dev;
-       urb->pipe = pipe;
-       urb->transfer_buffer = buffer;
-       urb->transfer_buffer_length = transfer_len;
-       urb->interval = interval;
-
-       /* device pulled? Shortcut the action. */
-       if (devgone == dev) {
-               dev->status = USB_ST_CRC_ERR;
-               return 0;
-       }
-
-#ifdef DEBUG
-       urb->actual_length = 0;
-       pkt_print(urb, dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
-#else
-       wait_ms(1);
-#endif
-       if (!maxsize) {
-               err("submit_common_message: pipesize for pipe %lx is zero",
-                       pipe);
-               return -1;
-       }
-
-       if (sohci_submit_job(urb, setup) < 0) {
-               err("sohci_submit_job failed");
-               return -1;
-       }
-
-#if 0
-       wait_ms(10);
-       /* ohci_dump_status(&gohci); */
-#endif
-
-       /* allow more time for a BULK device to react - some are slow */
-#define BULK_TO         5000   /* timeout in milliseconds */
-       if (usb_pipetype (pipe) == PIPE_BULK)
-               timeout = BULK_TO;
-       else
-               timeout = 100;
-
-       /* wait for it to complete */
-       for (;;) {
-               /* check whether the controller is done */
-               stat = hc_interrupt();
-               if (stat < 0) {
-                       stat = USB_ST_CRC_ERR;
-                       break;
-               }
-
-               /* NOTE: since we are not interrupt driven in U-Boot and always
-                * handle only one URB at a time, we cannot assume the
-                * transaction finished on the first successful return from
-                * hc_interrupt().. unless the flag for current URB is set,
-                * meaning that all TD's to/from device got actually
-                * transferred and processed. If the current URB is not
-                * finished we need to re-iterate this loop so as
-                * hc_interrupt() gets called again as there needs to be some
-                * more TD's to process still */
-               if ((stat >= 0) && (stat != 0xff) && (urb->finished)) {
-                       /* 0xff is returned for an SF-interrupt */
-                       break;
-               }
-
-               if (--timeout) {
-                       wait_ms(1);
-                       if (!urb->finished)
-                               dbg("\%");
-
-               } else {
-                       err("CTL:TIMEOUT ");
-                       dbg("submit_common_msg: TO status %x\n", stat);
-                       urb->finished = 1;
-                       stat = USB_ST_CRC_ERR;
-                       break;
-               }
-       }
-
-       dev->status = stat;
-       dev->act_len = transfer_len;
-
-#ifdef DEBUG
-       pkt_print(urb, dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe));
-#else
-       wait_ms(1);
-#endif
-
-       /* free TDs in urb_priv */
-       if (usb_pipetype (pipe) != PIPE_INTERRUPT)
-               urb_free_priv (urb);
-       return 0;
-}
-
-/* submit routines called from usb.c */
-int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-               int transfer_len)
-{
-       info("submit_bulk_msg");
-       return submit_common_msg(dev, pipe, buffer, transfer_len, NULL, 0);
-}
-
-int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-               int transfer_len, struct devrequest *setup)
-{
-       int maxsize = usb_maxpacket(dev, pipe);
-
-       info("submit_control_msg");
-#ifdef DEBUG
-       pkt_print(NULL, dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
-#else
-       wait_ms(1);
-#endif
-       if (!maxsize) {
-               err("submit_control_message: pipesize for pipe %lx is zero",
-                       pipe);
-               return -1;
-       }
-       if (((pipe >> 8) & 0x7f) == gohci.rh.devnum) {
-               gohci.rh.dev = dev;
-               /* root hub - redirect */
-               return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len,
-                       setup);
-       }
-
-       return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0);
-}
-
-int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-               int transfer_len, int interval)
-{
-       info("submit_int_msg");
-       return submit_common_msg(dev, pipe, buffer, transfer_len, NULL,
-                       interval);
-}
-
-/*-------------------------------------------------------------------------*
- * HC functions
- *-------------------------------------------------------------------------*/
-
-/* reset the HC and BUS */
-
-static int hc_reset (ohci_t *ohci)
-{
-       int timeout = 30;
-       int smm_timeout = 50; /* 0,5 sec */
-
-       dbg("%s\n", __FUNCTION__);
-
-       if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */
-               writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */
-               info("USB HC TakeOver from SMM");
-               while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
-                       wait_ms (10);
-                       if (--smm_timeout == 0) {
-                               err("USB HC TakeOver failed!");
-                               return -1;
-                       }
-               }
-       }
-
-       /* Disable HC interrupts */
-       writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
-
-       dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;\n",
-               ohci->slot_name,
-               readl(&ohci->regs->control));
-
-       /* Reset USB (needed by some controllers) */
-       ohci->hc_control = 0;
-       writel (ohci->hc_control, &ohci->regs->control);
-
-       /* HC Reset requires max 10 us delay */
-       writel (OHCI_HCR,  &ohci->regs->cmdstatus);
-       while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
-               if (--timeout == 0) {
-                       err("USB HC reset timed out!");
-                       return -1;
-               }
-               udelay (1);
-       }
-       return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* Start an OHCI controller, set the BUS operational
- * enable interrupts
- * connect the virtual root hub */
-
-static int hc_start (ohci_t * ohci)
-{
-       __u32 mask;
-       unsigned int fminterval;
-
-       ohci->disabled = 1;
-
-       /* Tell the controller where the control and bulk lists are
-        * The lists are empty now. */
-
-       writel (0, &ohci->regs->ed_controlhead);
-       writel (0, &ohci->regs->ed_bulkhead);
-
-       writel ((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */
-
-       fminterval = 0x2edf;
-       writel ((fminterval * 9) / 10, &ohci->regs->periodicstart);
-       fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
-       writel (fminterval, &ohci->regs->fminterval);
-       writel (0x628, &ohci->regs->lsthresh);
-
-       /* start controller operations */
-       ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
-       ohci->disabled = 0;
-       writel (ohci->hc_control, &ohci->regs->control);
-
-       /* disable all interrupts */
-       mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD |
-                       OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC |
-                       OHCI_INTR_OC | OHCI_INTR_MIE);
-       writel (mask, &ohci->regs->intrdisable);
-       /* clear all interrupts */
-       mask &= ~OHCI_INTR_MIE;
-       writel (mask, &ohci->regs->intrstatus);
-       /* Choose the interrupts we care about now  - but w/o MIE */
-       mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO;
-       writel (mask, &ohci->regs->intrenable);
-
-#ifdef OHCI_USE_NPS
-       /* required for AMD-756 and some Mac platforms */
-       writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM,
-               &ohci->regs->roothub.a);
-       writel (RH_HS_LPSC, &ohci->regs->roothub.status);
-#endif /* OHCI_USE_NPS */
-
-#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);})
-       /* POTPGT delay is bits 24-31, in 2 ms units. */
-       mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
-
-       /* connect the virtual root hub */
-       ohci->rh.devnum = 0;
-
-       return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* Poll USB interrupt. */
-void usb_event_poll(void)
-{
-       hc_interrupt();
-}
-
-/* an interrupt happens */
-
-static int hc_interrupt (void)
-{
-       ohci_t *ohci = &gohci;
-       struct ohci_regs *regs = ohci->regs;
-       int ints;
-       int stat = -1;
-
-       if ((ohci->hcca->done_head != 0) &&
-           !(m32_swap (ohci->hcca->done_head) & 0x01)) {
-               ints =  OHCI_INTR_WDH;
-       } else if ((ints = readl (&regs->intrstatus)) == ~(u32)0) {
-               ohci->disabled++;
-               err ("%s device removed!", ohci->slot_name);
-               return -1;
-       } else if ((ints &= readl (&regs->intrenable)) == 0) {
-               dbg("hc_interrupt: returning..\n");
-               return 0xff;
-       }
-
-       /* dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); */
-
-       if (ints & OHCI_INTR_RHSC) {
-               got_rhsc = 1;
-               stat = 0xff;
-       }
-
-       if (ints & OHCI_INTR_UE) {
-               ohci->disabled++;
-               err ("OHCI Unrecoverable Error, controller usb-%s disabled",
-                       ohci->slot_name);
-               /* e.g. due to PCI Master/Target Abort */
-
-#ifdef DEBUG
-               ohci_dump (ohci, 1);
-#else
-       wait_ms(1);
-#endif
-               /* FIXME: be optimistic, hope that bug won't repeat often. */
-               /* Make some non-interrupt context restart the controller. */
-               /* Count and limit the retries though; either hardware or */
-               /* software errors can go forever... */
-               hc_reset (ohci);
-               return -1;
-       }
-
-       if (ints & OHCI_INTR_WDH) {
-               wait_ms(1);
-               writel (OHCI_INTR_WDH, &regs->intrdisable);
-               (void)readl (&regs->intrdisable); /* flush */
-               stat = dl_done_list (&gohci, dl_reverse_done_list (&gohci));
-               writel (OHCI_INTR_WDH, &regs->intrenable);
-               (void)readl (&regs->intrdisable); /* flush */
-       }
-
-       if (ints & OHCI_INTR_SO) {
-               dbg("USB Schedule overrun\n");
-               writel (OHCI_INTR_SO, &regs->intrenable);
-               stat = -1;
-       }
-
-       /* FIXME:  this assumes SOF (1/ms) interrupts don't get lost... */
-       if (ints & OHCI_INTR_SF) {
-               unsigned int frame = m16_swap (ohci->hcca->frame_no) & 1;
-               wait_ms(1);
-               writel (OHCI_INTR_SF, &regs->intrdisable);
-               if (ohci->ed_rm_list[frame] != NULL)
-                       writel (OHCI_INTR_SF, &regs->intrenable);
-               stat = 0xff;
-       }
-
-       writel (ints, &regs->intrstatus);
-       return stat;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*-------------------------------------------------------------------------*/
-
-/* De-allocate all resources.. */
-
-static void hc_release_ohci (ohci_t *ohci)
-{
-       dbg ("USB HC release ohci usb-%s", ohci->slot_name);
-
-       if (!ohci->disabled)
-               hc_reset (ohci);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * low level initalisation routine, called from usb.c
- */
-static char ohci_inited = 0;
-
-int usb_lowlevel_init(void)
-{
-#ifdef CONFIG_PCI_OHCI
-       pci_dev_t pdev;
-#endif
-
-#ifdef CFG_USB_OHCI_CPU_INIT
-       /* cpu dependant init */
-       if(usb_cpu_init())
-               return -1;
-#endif
-
-#ifdef CFG_USB_OHCI_BOARD_INIT
-       /*  board dependant init */
-       if(usb_board_init())
-               return -1;
-#endif
-       memset (&gohci, 0, sizeof (ohci_t));
-
-       /* align the storage */
-       if ((__u32)&ghcca[0] & 0xff) {
-               err("HCCA not aligned!!");
-               return -1;
-       }
-       phcca = &ghcca[0];
-       info("aligned ghcca %p", phcca);
-       memset(&ohci_dev, 0, sizeof(struct ohci_device));
-       if ((__u32)&ohci_dev.ed[0] & 0x7) {
-               err("EDs not aligned!!");
-               return -1;
-       }
-       memset(gtd, 0, sizeof(td_t) * (NUM_TD + 1));
-       if ((__u32)gtd & 0x7) {
-               err("TDs not aligned!!");
-               return -1;
-       }
-       ptd = gtd;
-       gohci.hcca = phcca;
-       memset (phcca, 0, sizeof (struct ohci_hcca));
-
-       gohci.disabled = 1;
-       gohci.sleeping = 0;
-       gohci.irq = -1;
-#ifdef CONFIG_PCI_OHCI
-       pdev = pci_find_devices(ohci_pci_ids, 0);
-
-       if (pdev != -1) {
-               u16 vid, did;
-               u32 base;
-               pci_read_config_word(pdev, PCI_VENDOR_ID, &vid);
-               pci_read_config_word(pdev, PCI_DEVICE_ID, &did);
-               printf("OHCI pci controller (%04x, %04x) found @(%d:%d:%d)\n",
-                               vid, did, (pdev >> 16) & 0xff,
-                               (pdev >> 11) & 0x1f, (pdev >> 8) & 0x7);
-               pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &base);
-               printf("OHCI regs address 0x%08x\n", base);
-               gohci.regs = (struct ohci_regs *)base;
-       } else
-               return -1;
-#else
-       gohci.regs = (struct ohci_regs *)CFG_USB_OHCI_REGS_BASE;
-#endif
-
-       gohci.flags = 0;
-       gohci.slot_name = CFG_USB_OHCI_SLOT_NAME;
-
-       if (hc_reset (&gohci) < 0) {
-               hc_release_ohci (&gohci);
-               err ("can't reset usb-%s", gohci.slot_name);
-#ifdef CFG_USB_OHCI_BOARD_INIT
-               /* board dependant cleanup */
-               usb_board_init_fail();
-#endif
-
-#ifdef CFG_USB_OHCI_CPU_INIT
-               /* cpu dependant cleanup */
-               usb_cpu_init_fail();
-#endif
-               return -1;
-       }
-
-       /* FIXME this is a second HC reset; why?? */
-       /* writel(gohci.hc_control = OHCI_USB_RESET, &gohci.regs->control);
-          wait_ms(10); */
-       if (hc_start (&gohci) < 0) {
-               err ("can't start usb-%s", gohci.slot_name);
-               hc_release_ohci (&gohci);
-               /* Initialization failed */
-#ifdef CFG_USB_OHCI_BOARD_INIT
-               /* board dependant cleanup */
-               usb_board_stop();
-#endif
-
-#ifdef CFG_USB_OHCI_CPU_INIT
-               /* cpu dependant cleanup */
-               usb_cpu_stop();
-#endif
-               return -1;
-       }
-
-#ifdef DEBUG
-       ohci_dump (&gohci, 1);
-#else
-       wait_ms(1);
-#endif
-       ohci_inited = 1;
-       return 0;
-}
-
-int usb_lowlevel_stop(void)
-{
-       /* this gets called really early - before the controller has */
-       /* even been initialized! */
-       if (!ohci_inited)
-               return 0;
-       /* TODO release any interrupts, etc. */
-       /* call hc_release_ohci() here ? */
-       hc_reset (&gohci);
-
-#ifdef CFG_USB_OHCI_BOARD_INIT
-       /* board dependant cleanup */
-       if(usb_board_stop())
-               return -1;
-#endif
-
-#ifdef CFG_USB_OHCI_CPU_INIT
-       /* cpu dependant cleanup */
-       if(usb_cpu_stop())
-               return -1;
-#endif
-
-       return 0;
-}
-#endif /* CONFIG_USB_OHCI_NEW */
diff --git a/drivers/usb_ohci.h b/drivers/usb_ohci.h
deleted file mode 100644 (file)
index 380cb4c..0000000
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * URB OHCI HCD (Host Controller Driver) for USB.
- *
- * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
- * (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net>
- *
- * usb-ohci.h
- */
-
-/* functions for doing board or CPU specific setup/cleanup */
-extern int usb_board_init(void);
-extern int usb_board_stop(void);
-extern int usb_board_init_fail(void);
-
-extern int usb_cpu_init(void);
-extern int usb_cpu_stop(void);
-extern int usb_cpu_init_fail(void);
-
-
-static int cc_to_error[16] = {
-
-/* mapping of the OHCI CC status to error codes */
-       /* No  Error  */               0,
-       /* CRC Error  */               USB_ST_CRC_ERR,
-       /* Bit Stuff  */               USB_ST_BIT_ERR,
-       /* Data Togg  */               USB_ST_CRC_ERR,
-       /* Stall      */               USB_ST_STALLED,
-       /* DevNotResp */               -1,
-       /* PIDCheck   */               USB_ST_BIT_ERR,
-       /* UnExpPID   */               USB_ST_BIT_ERR,
-       /* DataOver   */               USB_ST_BUF_ERR,
-       /* DataUnder  */               USB_ST_BUF_ERR,
-       /* reservd    */               -1,
-       /* reservd    */               -1,
-       /* BufferOver */               USB_ST_BUF_ERR,
-       /* BuffUnder  */               USB_ST_BUF_ERR,
-       /* Not Access */               -1,
-       /* Not Access */               -1
-};
-
-/* ED States */
-
-#define ED_NEW         0x00
-#define ED_UNLINK      0x01
-#define ED_OPER                0x02
-#define ED_DEL         0x04
-#define ED_URB_DEL     0x08
-
-/* usb_ohci_ed */
-struct ed {
-       __u32 hwINFO;
-       __u32 hwTailP;
-       __u32 hwHeadP;
-       __u32 hwNextED;
-
-       struct ed *ed_prev;
-       __u8 int_period;
-       __u8 int_branch;
-       __u8 int_load;
-       __u8 int_interval;
-       __u8 state;
-       __u8 type;
-       __u16 last_iso;
-       struct ed *ed_rm_list;
-
-       struct usb_device *usb_dev;
-       void *purb;
-       __u32 unused[2];
-} __attribute((aligned(16)));
-typedef struct ed ed_t;
-
-
-/* TD info field */
-#define TD_CC      0xf0000000
-#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f)
-#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)
-#define TD_EC      0x0C000000
-#define TD_T       0x03000000
-#define TD_T_DATA0  0x02000000
-#define TD_T_DATA1  0x03000000
-#define TD_T_TOGGLE 0x00000000
-#define TD_R       0x00040000
-#define TD_DI      0x00E00000
-#define TD_DI_SET(X) (((X) & 0x07)<< 21)
-#define TD_DP      0x00180000
-#define TD_DP_SETUP 0x00000000
-#define TD_DP_IN    0x00100000
-#define TD_DP_OUT   0x00080000
-
-#define TD_ISO     0x00010000
-#define TD_DEL     0x00020000
-
-/* CC Codes */
-#define TD_CC_NOERROR     0x00
-#define TD_CC_CRC         0x01
-#define TD_CC_BITSTUFFING  0x02
-#define TD_CC_DATATOGGLEM  0x03
-#define TD_CC_STALL       0x04
-#define TD_DEVNOTRESP     0x05
-#define TD_PIDCHECKFAIL           0x06
-#define TD_UNEXPECTEDPID   0x07
-#define TD_DATAOVERRUN    0x08
-#define TD_DATAUNDERRUN           0x09
-#define TD_BUFFEROVERRUN   0x0C
-#define TD_BUFFERUNDERRUN  0x0D
-#define TD_NOTACCESSED    0x0F
-
-
-#define MAXPSW 1
-
-struct td {
-       __u32 hwINFO;
-       __u32 hwCBP;            /* Current Buffer Pointer */
-       __u32 hwNextTD;         /* Next TD Pointer */
-       __u32 hwBE;             /* Memory Buffer End Pointer */
-
-/* #ifndef CONFIG_MPC5200 /\* this seems wrong *\/ */
-       __u16 hwPSW[MAXPSW];
-/* #endif */
-       __u8 unused;
-       __u8 index;
-       struct ed *ed;
-       struct td *next_dl_td;
-       struct usb_device *usb_dev;
-       int transfer_len;
-       __u32 data;
-
-       __u32 unused2[2];
-} __attribute((aligned(32)));
-typedef struct td td_t;
-
-#define OHCI_ED_SKIP   (1 << 14)
-
-/*
- * The HCCA (Host Controller Communications Area) is a 256 byte
- * structure defined in the OHCI spec. that the host controller is
- * told the base address of.  It must be 256-byte aligned.
- */
-
-#define NUM_INTS 32    /* part of the OHCI standard */
-struct ohci_hcca {
-       __u32   int_table[NUM_INTS];    /* Interrupt ED table */
-#if defined(CONFIG_MPC5200)
-       __u16   pad1;                   /* set to 0 on each frame_no change */
-       __u16   frame_no;               /* current frame number */
-#else
-       __u16   frame_no;               /* current frame number */
-       __u16   pad1;                   /* set to 0 on each frame_no change */
-#endif
-       __u32   done_head;              /* info returned for an interrupt */
-       u8              reserved_for_hc[116];
-} __attribute((aligned(256)));
-
-
-/*
- * Maximum number of root hub ports.
- */
-#ifndef CFG_USB_OHCI_MAX_ROOT_PORTS
-# error "CFG_USB_OHCI_MAX_ROOT_PORTS undefined!"
-#endif
-
-/*
- * This is the structure of the OHCI controller's memory mapped I/O
- * region.  This is Memory Mapped I/O. You must use the readl() and
- * writel() macros defined in asm/io.h to access these!!
- */
-struct ohci_regs {
-       /* control and status registers */
-       __u32   revision;
-       __u32   control;
-       __u32   cmdstatus;
-       __u32   intrstatus;
-       __u32   intrenable;
-       __u32   intrdisable;
-       /* memory pointers */
-       __u32   hcca;
-       __u32   ed_periodcurrent;
-       __u32   ed_controlhead;
-       __u32   ed_controlcurrent;
-       __u32   ed_bulkhead;
-       __u32   ed_bulkcurrent;
-       __u32   donehead;
-       /* frame counters */
-       __u32   fminterval;
-       __u32   fmremaining;
-       __u32   fmnumber;
-       __u32   periodicstart;
-       __u32   lsthresh;
-       /* Root hub ports */
-       struct  ohci_roothub_regs {
-               __u32   a;
-               __u32   b;
-               __u32   status;
-               __u32   portstatus[CFG_USB_OHCI_MAX_ROOT_PORTS];
-       } roothub;
-} __attribute((aligned(32)));
-
-
-/* OHCI CONTROL AND STATUS REGISTER MASKS */
-
-/*
- * HcControl (control) register masks
- */
-#define OHCI_CTRL_CBSR (3 << 0)        /* control/bulk service ratio */
-#define OHCI_CTRL_PLE  (1 << 2)        /* periodic list enable */
-#define OHCI_CTRL_IE   (1 << 3)        /* isochronous enable */
-#define OHCI_CTRL_CLE  (1 << 4)        /* control list enable */
-#define OHCI_CTRL_BLE  (1 << 5)        /* bulk list enable */
-#define OHCI_CTRL_HCFS (3 << 6)        /* host controller functional state */
-#define OHCI_CTRL_IR   (1 << 8)        /* interrupt routing */
-#define OHCI_CTRL_RWC  (1 << 9)        /* remote wakeup connected */
-#define OHCI_CTRL_RWE  (1 << 10)       /* remote wakeup enable */
-
-/* pre-shifted values for HCFS */
-#      define OHCI_USB_RESET   (0 << 6)
-#      define OHCI_USB_RESUME  (1 << 6)
-#      define OHCI_USB_OPER    (2 << 6)
-#      define OHCI_USB_SUSPEND (3 << 6)
-
-/*
- * HcCommandStatus (cmdstatus) register masks
- */
-#define OHCI_HCR       (1 << 0)        /* host controller reset */
-#define OHCI_CLF       (1 << 1)        /* control list filled */
-#define OHCI_BLF       (1 << 2)        /* bulk list filled */
-#define OHCI_OCR       (1 << 3)        /* ownership change request */
-#define OHCI_SOC       (3 << 16)       /* scheduling overrun count */
-
-/*
- * masks used with interrupt registers:
- * HcInterruptStatus (intrstatus)
- * HcInterruptEnable (intrenable)
- * HcInterruptDisable (intrdisable)
- */
-#define OHCI_INTR_SO   (1 << 0)        /* scheduling overrun */
-#define OHCI_INTR_WDH  (1 << 1)        /* writeback of done_head */
-#define OHCI_INTR_SF   (1 << 2)        /* start frame */
-#define OHCI_INTR_RD   (1 << 3)        /* resume detect */
-#define OHCI_INTR_UE   (1 << 4)        /* unrecoverable error */
-#define OHCI_INTR_FNO  (1 << 5)        /* frame number overflow */
-#define OHCI_INTR_RHSC (1 << 6)        /* root hub status change */
-#define OHCI_INTR_OC   (1 << 30)       /* ownership change */
-#define OHCI_INTR_MIE  (1 << 31)       /* master interrupt enable */
-
-
-/* Virtual Root HUB */
-struct virt_root_hub {
-       int devnum; /* Address of Root Hub endpoint */
-       void *dev;  /* was urb */
-       void *int_addr;
-       int send;
-       int interval;
-};
-
-/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */
-
-/* destination of request */
-#define RH_INTERFACE              0x01
-#define RH_ENDPOINT               0x02
-#define RH_OTHER                  0x03
-
-#define RH_CLASS                  0x20
-#define RH_VENDOR                 0x40
-
-/* Requests: bRequest << 8 | bmRequestType */
-#define RH_GET_STATUS          0x0080
-#define RH_CLEAR_FEATURE       0x0100
-#define RH_SET_FEATURE         0x0300
-#define RH_SET_ADDRESS         0x0500
-#define RH_GET_DESCRIPTOR      0x0680
-#define RH_SET_DESCRIPTOR      0x0700
-#define RH_GET_CONFIGURATION   0x0880
-#define RH_SET_CONFIGURATION   0x0900
-#define RH_GET_STATE           0x0280
-#define RH_GET_INTERFACE       0x0A80
-#define RH_SET_INTERFACE       0x0B00
-#define RH_SYNC_FRAME          0x0C80
-/* Our Vendor Specific Request */
-#define RH_SET_EP              0x2000
-
-
-/* Hub port features */
-#define RH_PORT_CONNECTION        0x00
-#define RH_PORT_ENABLE            0x01
-#define RH_PORT_SUSPEND                   0x02
-#define RH_PORT_OVER_CURRENT      0x03
-#define RH_PORT_RESET             0x04
-#define RH_PORT_POWER             0x08
-#define RH_PORT_LOW_SPEED         0x09
-
-#define RH_C_PORT_CONNECTION      0x10
-#define RH_C_PORT_ENABLE          0x11
-#define RH_C_PORT_SUSPEND         0x12
-#define RH_C_PORT_OVER_CURRENT    0x13
-#define RH_C_PORT_RESET                   0x14
-
-/* Hub features */
-#define RH_C_HUB_LOCAL_POWER      0x00
-#define RH_C_HUB_OVER_CURRENT     0x01
-
-#define RH_DEVICE_REMOTE_WAKEUP           0x00
-#define RH_ENDPOINT_STALL         0x01
-
-#define RH_ACK                    0x01
-#define RH_REQ_ERR                -1
-#define RH_NACK                           0x00
-
-
-/* OHCI ROOT HUB REGISTER MASKS */
-
-/* roothub.portstatus [i] bits */
-#define RH_PS_CCS           0x00000001         /* current connect status */
-#define RH_PS_PES           0x00000002         /* port enable status*/
-#define RH_PS_PSS           0x00000004         /* port suspend status */
-#define RH_PS_POCI          0x00000008         /* port over current indicator */
-#define RH_PS_PRS           0x00000010         /* port reset status */
-#define RH_PS_PPS           0x00000100         /* port power status */
-#define RH_PS_LSDA          0x00000200         /* low speed device attached */
-#define RH_PS_CSC           0x00010000         /* connect status change */
-#define RH_PS_PESC          0x00020000         /* port enable status change */
-#define RH_PS_PSSC          0x00040000         /* port suspend status change */
-#define RH_PS_OCIC          0x00080000         /* over current indicator change */
-#define RH_PS_PRSC          0x00100000         /* port reset status change */
-
-/* roothub.status bits */
-#define RH_HS_LPS           0x00000001         /* local power status */
-#define RH_HS_OCI           0x00000002         /* over current indicator */
-#define RH_HS_DRWE          0x00008000         /* device remote wakeup enable */
-#define RH_HS_LPSC          0x00010000         /* local power status change */
-#define RH_HS_OCIC          0x00020000         /* over current indicator change */
-#define RH_HS_CRWE          0x80000000         /* clear remote wakeup enable */
-
-/* roothub.b masks */
-#define RH_B_DR                0x0000ffff              /* device removable flags */
-#define RH_B_PPCM      0xffff0000              /* port power control mask */
-
-/* roothub.a masks */
-#define RH_A_NDP       (0xff << 0)             /* number of downstream ports */
-#define RH_A_PSM       (1 << 8)                /* power switching mode */
-#define RH_A_NPS       (1 << 9)                /* no power switching */
-#define RH_A_DT                (1 << 10)               /* device type (mbz) */
-#define RH_A_OCPM      (1 << 11)               /* over current protection mode */
-#define RH_A_NOCP      (1 << 12)               /* no over current protection */
-#define RH_A_POTPGT    (0xff << 24)            /* power on to power good time */
-
-/* urb */
-#define N_URB_TD 48
-typedef struct
-{
-       ed_t *ed;
-       __u16 length;   /* number of tds associated with this request */
-       __u16 td_cnt;   /* number of tds already serviced */
-       struct usb_device *dev;
-       int   state;
-       unsigned long pipe;
-       void *transfer_buffer;
-       int transfer_buffer_length;
-       int interval;
-       int actual_length;
-       int finished;
-       td_t *td[N_URB_TD];     /* list pointer to all corresponding TDs associated with this request */
-} urb_priv_t;
-#define URB_DEL 1
-
-/*
- * This is the full ohci controller description
- *
- * Note how the "proper" USB information is just
- * a subset of what the full implementation needs. (Linus)
- */
-
-
-typedef struct ohci {
-       struct ohci_hcca *hcca;         /* hcca */
-       /*dma_addr_t hcca_dma;*/
-
-       int irq;
-       int disabled;                   /* e.g. got a UE, we're hung */
-       int sleeping;
-       unsigned long flags;            /* for HC bugs */
-
-       struct ohci_regs *regs; /* OHCI controller's memory */
-
-       int ohci_int_load[32];   /* load of the 32 Interrupt Chains (for load balancing)*/
-       ed_t *ed_rm_list[2];     /* lists of all endpoints to be removed */
-       ed_t *ed_bulktail;       /* last endpoint of bulk list */
-       ed_t *ed_controltail;    /* last endpoint of control list */
-       int intrstatus;
-       __u32 hc_control;               /* copy of the hc control reg */
-       struct usb_device *dev[32];
-       struct virt_root_hub rh;
-
-       const char      *slot_name;
-} ohci_t;
-
-#define NUM_EDS 8              /* num of preallocated endpoint descriptors */
-
-struct ohci_device {
-       ed_t    ed[NUM_EDS];
-       int ed_cnt;
-};
-
-/* hcd */
-/* endpoint */
-static int ep_link(ohci_t * ohci, ed_t * ed);
-static int ep_unlink(ohci_t * ohci, ed_t * ed);
-static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned long pipe,
-               int interval, int load);
-
-/*-------------------------------------------------------------------------*/
-
-/* we need more TDs than EDs */
-#define NUM_TD 64
-
-/* +1 so we can align the storage */
-td_t gtd[NUM_TD+1];
-/* pointers to aligned storage */
-td_t *ptd;
-
-/* TDs ... */
-static inline struct td *
-td_alloc (struct usb_device *usb_dev)
-{
-       int i;
-       struct td       *td;
-
-       td = NULL;
-       for (i = 0; i < NUM_TD; i++)
-       {
-               if (ptd[i].usb_dev == NULL)
-               {
-                       td = &ptd[i];
-                       td->usb_dev = usb_dev;
-                       break;
-               }
-       }
-
-       return td;
-}
-
-static inline void
-ed_free (struct ed *ed)
-{
-       ed->usb_dev = NULL;
-}
diff --git a/drivers/usbdcore.c b/drivers/usbdcore.c
deleted file mode 100644 (file)
index 308c7ce..0000000
+++ /dev/null
@@ -1,684 +0,0 @@
-/*
- * (C) Copyright 2003
- * Gerry Hamel, geh@ti.com, Texas Instruments
- *
- * Based on
- * linux/drivers/usbd/usbd.c.c - USB Device Core Layer
- *
- * Copyright (c) 2000, 2001, 2002 Lineo
- * Copyright (c) 2001 Hewlett Packard
- *
- * By:
- *     Stuart Lynne <sl@lineo.com>,
- *     Tom Rushworth <tbr@lineo.com>,
- *     Bruce Balden <balden@lineo.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <malloc.h>
-#include "usbdcore.h"
-
-#define MAX_INTERFACES 2
-
-
-int maxstrings = 20;
-
-/* Global variables ************************************************************************** */
-
-struct usb_string_descriptor **usb_strings;
-
-int usb_devices;
-
-extern struct usb_function_driver ep0_driver;
-
-int registered_functions;
-int registered_devices;
-
-char *usbd_device_events[] = {
-       "DEVICE_UNKNOWN",
-       "DEVICE_INIT",
-       "DEVICE_CREATE",
-       "DEVICE_HUB_CONFIGURED",
-       "DEVICE_RESET",
-       "DEVICE_ADDRESS_ASSIGNED",
-       "DEVICE_CONFIGURED",
-       "DEVICE_SET_INTERFACE",
-       "DEVICE_SET_FEATURE",
-       "DEVICE_CLEAR_FEATURE",
-       "DEVICE_DE_CONFIGURED",
-       "DEVICE_BUS_INACTIVE",
-       "DEVICE_BUS_ACTIVITY",
-       "DEVICE_POWER_INTERRUPTION",
-       "DEVICE_HUB_RESET",
-       "DEVICE_DESTROY",
-       "DEVICE_FUNCTION_PRIVATE",
-};
-
-char *usbd_device_states[] = {
-       "STATE_INIT",
-       "STATE_CREATED",
-       "STATE_ATTACHED",
-       "STATE_POWERED",
-       "STATE_DEFAULT",
-       "STATE_ADDRESSED",
-       "STATE_CONFIGURED",
-       "STATE_UNKNOWN",
-};
-
-char *usbd_device_requests[] = {
-       "GET STATUS",           /* 0 */
-       "CLEAR FEATURE",        /* 1 */
-       "RESERVED",             /* 2 */
-       "SET FEATURE",          /* 3 */
-       "RESERVED",             /* 4 */
-       "SET ADDRESS",          /* 5 */
-       "GET DESCRIPTOR",       /* 6 */
-       "SET DESCRIPTOR",       /* 7 */
-       "GET CONFIGURATION",    /* 8 */
-       "SET CONFIGURATION",    /* 9 */
-       "GET INTERFACE",        /* 10 */
-       "SET INTERFACE",        /* 11 */
-       "SYNC FRAME",           /* 12 */
-};
-
-char *usbd_device_descriptors[] = {
-       "UNKNOWN",              /* 0 */
-       "DEVICE",               /* 1 */
-       "CONFIG",               /* 2 */
-       "STRING",               /* 3 */
-       "INTERFACE",            /* 4 */
-       "ENDPOINT",             /* 5 */
-       "DEVICE QUALIFIER",     /* 6 */
-       "OTHER SPEED",          /* 7 */
-       "INTERFACE POWER",      /* 8 */
-};
-
-char *usbd_device_status[] = {
-       "USBD_OPENING",
-       "USBD_OK",
-       "USBD_SUSPENDED",
-       "USBD_CLOSING",
-};
-
-
-/* Descriptor support functions ************************************************************** */
-
-
-/**
- * usbd_get_string - find and return a string descriptor
- * @index: string index to return
- *
- * Find an indexed string and return a pointer to a it.
- */
-struct usb_string_descriptor *usbd_get_string (__u8 index)
-{
-       if (index >= maxstrings) {
-               return NULL;
-       }
-       return usb_strings[index];
-}
-
-
-/* Access to device descriptor functions ***************************************************** */
-
-
-/* *
- * usbd_device_configuration_instance - find a configuration instance for this device
- * @device:
- * @configuration: index to configuration, 0 - N-1
- *
- * Get specifed device configuration. Index should be bConfigurationValue-1.
- */
-static struct usb_configuration_instance *usbd_device_configuration_instance (struct usb_device_instance *device,
-               unsigned int port, unsigned int configuration)
-{
-       /* XXX */
-       configuration = configuration ? configuration - 1 : 0;
-
-       if (configuration >= device->configurations) {
-               return NULL;
-       }
-       return device->configuration_instance_array + configuration;
-}
-
-
-/* *
- * usbd_device_interface_instance
- * @device:
- * @configuration: index to configuration, 0 - N-1
- * @interface: index to interface
- *
- * Return the specified interface descriptor for the specified device.
- */
-struct usb_interface_instance *usbd_device_interface_instance (struct usb_device_instance *device, int port, int configuration, int interface)
-{
-       struct usb_configuration_instance *configuration_instance;
-
-       if ((configuration_instance = usbd_device_configuration_instance (device, port, configuration)) == NULL) {
-               return NULL;
-       }
-       if (interface >= configuration_instance->interfaces) {
-               return NULL;
-       }
-       return configuration_instance->interface_instance_array + interface;
-}
-
-/* *
- * usbd_device_alternate_descriptor_list
- * @device:
- * @configuration: index to configuration, 0 - N-1
- * @interface: index to interface
- * @alternate: alternate setting
- *
- * Return the specified alternate descriptor for the specified device.
- */
-struct usb_alternate_instance *usbd_device_alternate_instance (struct usb_device_instance *device, int port, int configuration, int interface, int alternate)
-{
-       struct usb_interface_instance *interface_instance;
-
-       if ((interface_instance = usbd_device_interface_instance (device, port, configuration, interface)) == NULL) {
-               return NULL;
-       }
-
-       if (alternate >= interface_instance->alternates) {
-               return NULL;
-       }
-
-       return interface_instance->alternates_instance_array + alternate;
-}
-
-
-/* *
- * usbd_device_device_descriptor
- * @device: which device
- * @configuration: index to configuration, 0 - N-1
- * @port: which port
- *
- * Return the specified configuration descriptor for the specified device.
- */
-struct usb_device_descriptor *usbd_device_device_descriptor (struct usb_device_instance *device, int port)
-{
-       return (device->device_descriptor);
-}
-
-
-/**
- * usbd_device_configuration_descriptor
- * @device: which device
- * @port: which port
- * @configuration: index to configuration, 0 - N-1
- *
- * Return the specified configuration descriptor for the specified device.
- */
-struct usb_configuration_descriptor *usbd_device_configuration_descriptor (struct
-                                                                          usb_device_instance
-                                                                          *device, int port, int configuration)
-{
-       struct usb_configuration_instance *configuration_instance;
-       if (!(configuration_instance = usbd_device_configuration_instance (device, port, configuration))) {
-               return NULL;
-       }
-       return (configuration_instance->configuration_descriptor);
-}
-
-
-/**
- * usbd_device_interface_descriptor
- * @device: which device
- * @port: which port
- * @configuration: index to configuration, 0 - N-1
- * @interface: index to interface
- * @alternate: alternate setting
- *
- * Return the specified interface descriptor for the specified device.
- */
-struct usb_interface_descriptor *usbd_device_interface_descriptor (struct usb_device_instance
-                                                                  *device, int port, int configuration, int interface, int alternate)
-{
-       struct usb_interface_instance *interface_instance;
-       if (!(interface_instance = usbd_device_interface_instance (device, port, configuration, interface))) {
-               return NULL;
-       }
-       if ((alternate < 0) || (alternate >= interface_instance->alternates)) {
-               return NULL;
-       }
-       return (interface_instance->alternates_instance_array[alternate].interface_descriptor);
-}
-
-/**
- * usbd_device_endpoint_descriptor_index
- * @device: which device
- * @port: which port
- * @configuration: index to configuration, 0 - N-1
- * @interface: index to interface
- * @alternate: index setting
- * @index: which index
- *
- * Return the specified endpoint descriptor for the specified device.
- */
-struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor_index (struct usb_device_instance
-                                                                      *device, int port, int configuration, int interface, int alternate, int index)
-{
-       struct usb_alternate_instance *alternate_instance;
-
-       if (!(alternate_instance = usbd_device_alternate_instance (device, port, configuration, interface, alternate))) {
-               return NULL;
-       }
-       if (index >= alternate_instance->endpoints) {
-               return NULL;
-       }
-       return *(alternate_instance->endpoints_descriptor_array + index);
-}
-
-
-/**
- * usbd_device_endpoint_transfersize
- * @device: which device
- * @port: which port
- * @configuration: index to configuration, 0 - N-1
- * @interface: index to interface
- * @index: which index
- *
- * Return the specified endpoint transfer size;
- */
-int usbd_device_endpoint_transfersize (struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int index)
-{
-       struct usb_alternate_instance *alternate_instance;
-
-       if (!(alternate_instance = usbd_device_alternate_instance (device, port, configuration, interface, alternate))) {
-               return 0;
-       }
-       if (index >= alternate_instance->endpoints) {
-               return 0;
-       }
-       return *(alternate_instance->endpoint_transfersize_array + index);
-}
-
-
-/**
- * usbd_device_endpoint_descriptor
- * @device: which device
- * @port: which port
- * @configuration: index to configuration, 0 - N-1
- * @interface: index to interface
- * @alternate: alternate setting
- * @endpoint: which endpoint
- *
- * Return the specified endpoint descriptor for the specified device.
- */
-struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor (struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int endpoint)
-{
-       struct usb_endpoint_descriptor *endpoint_descriptor;
-       int i;
-
-       for (i = 0; !(endpoint_descriptor = usbd_device_endpoint_descriptor_index (device, port, configuration, interface, alternate, i)); i++) {
-               if (endpoint_descriptor->bEndpointAddress == endpoint) {
-                       return endpoint_descriptor;
-               }
-       }
-       return NULL;
-}
-
-/**
- * usbd_endpoint_halted
- * @device: point to struct usb_device_instance
- * @endpoint: endpoint to check
- *
- * Return non-zero if endpoint is halted.
- */
-int usbd_endpoint_halted (struct usb_device_instance *device, int endpoint)
-{
-       return (device->status == USB_STATUS_HALT);
-}
-
-
-/**
- * usbd_rcv_complete - complete a receive
- * @endpoint:
- * @len:
- * @urb_bad:
- *
- * Called from rcv interrupt to complete.
- */
-void usbd_rcv_complete(struct usb_endpoint_instance *endpoint, int len, int urb_bad)
-{
-       if (endpoint) {
-               struct urb *rcv_urb;
-
-               /*usbdbg("len: %d urb: %p\n", len, endpoint->rcv_urb); */
-
-               /* if we had an urb then update actual_length, dispatch if neccessary */
-               if ((rcv_urb = endpoint->rcv_urb)) {
-
-                       /*usbdbg("actual: %d buffer: %d\n", */
-                       /*rcv_urb->actual_length, rcv_urb->buffer_length); */
-
-                       /* check the urb is ok, are we adding data less than the packetsize */
-                       if (!urb_bad && (len <= endpoint->rcv_packetSize)) {
-                         /*usbdbg("updating actual_length by %d\n",len); */
-
-                               /* increment the received data size */
-                               rcv_urb->actual_length += len;
-
-                       } else {
-                               usberr(" RECV_ERROR actual: %d buffer: %d urb_bad: %d\n",
-                                      rcv_urb->actual_length, rcv_urb->buffer_length, urb_bad);
-
-                               rcv_urb->actual_length = 0;
-                               rcv_urb->status = RECV_ERROR;
-                       }
-               } else {
-                       usberr("no rcv_urb!");
-               }
-       } else {
-               usberr("no endpoint!");
-       }
-
-}
-
-/**
- * usbd_tx_complete - complete a transmit
- * @endpoint:
- * @resetart:
- *
- * Called from tx interrupt to complete.
- */
-void usbd_tx_complete (struct usb_endpoint_instance *endpoint)
-{
-       if (endpoint) {
-               struct urb *tx_urb;
-
-               /* if we have a tx_urb advance or reset, finish if complete */
-               if ((tx_urb = endpoint->tx_urb)) {
-                       int sent = endpoint->last;
-                       endpoint->sent += sent;
-                       endpoint->last -= sent;
-
-                       if( (endpoint->tx_urb->actual_length - endpoint->sent) <= 0 ) {
-                               tx_urb->actual_length = 0;
-                               endpoint->sent = 0;
-                               endpoint->last = 0;
-
-                               /* Remove from active, save for re-use */
-                               urb_detach(tx_urb);
-                               urb_append(&endpoint->done, tx_urb);
-                               /*usbdbg("done->next %p, tx_urb %p, done %p", */
-                               /*       endpoint->done.next, tx_urb, &endpoint->done); */
-
-                               endpoint->tx_urb = first_urb_detached(&endpoint->tx);
-                               if( endpoint->tx_urb ) {
-                                       endpoint->tx_queue--;
-                                       usbdbg("got urb from tx list");
-                               }
-                               if( !endpoint->tx_urb ) {
-                                       /*usbdbg("taking urb from done list"); */
-                                       endpoint->tx_urb = first_urb_detached(&endpoint->done);
-                               }
-                               if( !endpoint->tx_urb ) {
-                                       usbdbg("allocating new urb for tx_urb");
-                                       endpoint->tx_urb = usbd_alloc_urb(tx_urb->device, endpoint);
-                               }
-                       }
-               }
-       }
-}
-
-/* URB linked list functions ***************************************************** */
-
-/*
- * Initialize an urb_link to be a single element list.
- * If the urb_link is being used as a distinguished list head
- * the list is empty when the head is the only link in the list.
- */
-void urb_link_init (urb_link * ul)
-{
-       if (ul) {
-               ul->prev = ul->next = ul;
-       }
-}
-
-/*
- * Detach an urb_link from a list, and set it
- * up as a single element list, so no dangling
- * pointers can be followed, and so it can be
- * joined to another list if so desired.
- */
-void urb_detach (struct urb *urb)
-{
-       if (urb) {
-               urb_link *ul = &urb->link;
-               ul->next->prev = ul->prev;
-               ul->prev->next = ul->next;
-               urb_link_init (ul);
-       }
-}
-
-/*
- * Return the first urb_link in a list with a distinguished
- * head "hd", or NULL if the list is empty.  This will also
- * work as a predicate, returning NULL if empty, and non-NULL
- * otherwise.
- */
-urb_link *first_urb_link (urb_link * hd)
-{
-       urb_link *nx;
-       if (NULL != hd && NULL != (nx = hd->next) && nx != hd) {
-               /* There is at least one element in the list */
-               /* (besides the distinguished head). */
-               return (nx);
-       }
-       /* The list is empty */
-       return (NULL);
-}
-
-/*
- * Return the first urb in a list with a distinguished
- * head "hd", or NULL if the list is empty.
- */
-struct urb *first_urb (urb_link * hd)
-{
-       urb_link *nx;
-       if (NULL == (nx = first_urb_link (hd))) {
-               /* The list is empty */
-               return (NULL);
-       }
-       return (p2surround (struct urb, link, nx));
-}
-
-/*
- * Detach and return the first urb in a list with a distinguished
- * head "hd", or NULL if the list is empty.
- *
- */
-struct urb *first_urb_detached (urb_link * hd)
-{
-       struct urb *urb;
-       if ((urb = first_urb (hd))) {
-               urb_detach (urb);
-       }
-       return urb;
-}
-
-
-/*
- * Append an urb_link (or a whole list of
- * urb_links) to the tail of another list
- * of urb_links.
- */
-void urb_append (urb_link * hd, struct urb *urb)
-{
-       if (hd && urb) {
-               urb_link *new = &urb->link;
-
-               /* This allows the new urb to be a list of urbs, */
-               /* with new pointing at the first, but the link */
-               /* must be initialized. */
-               /* Order is important here... */
-               urb_link *pul = hd->prev;
-               new->prev->next = hd;
-               hd->prev = new->prev;
-               new->prev = pul;
-               pul->next = new;
-       }
-}
-
-/* URB create/destroy functions ***************************************************** */
-
-/**
- * usbd_alloc_urb - allocate an URB appropriate for specified endpoint
- * @device: device instance
- * @endpoint: endpoint
- *
- * Allocate an urb structure. The usb device urb structure is used to
- * contain all data associated with a transfer, including a setup packet for
- * control transfers.
- *
- * NOTE: endpoint_address MUST contain a direction flag.
- */
-struct urb *usbd_alloc_urb (struct usb_device_instance *device, struct usb_endpoint_instance *endpoint)
-{
-       struct urb *urb;
-
-       if( !(urb = (struct urb*)malloc(sizeof(struct urb))) ) {
-         usberr(" F A T A L:  malloc(%u) FAILED!!!!", sizeof(struct urb));
-         return NULL;
-       }
-
-       /* Fill in known fields */
-       memset(urb, 0, sizeof(struct urb));
-       urb->endpoint = endpoint;
-       urb->device = device;
-       urb->buffer = (u8*)urb->buffer_data;
-       urb->buffer_length = sizeof(urb->buffer_data);
-
-       urb_link_init (&urb->link);
-
-       return urb;
-}
-
-/**
- * usbd_dealloc_urb - deallocate an URB and associated buffer
- * @urb: pointer to an urb structure
- *
- * Deallocate an urb structure and associated data.
- */
-void usbd_dealloc_urb (struct urb *urb)
-{
-       if (urb) {
-               free (urb);
-       }
-}
-
-/* Event signaling functions ***************************************************** */
-
-/**
- * usbd_device_event - called to respond to various usb events
- * @device: pointer to struct device
- * @event: event to respond to
- *
- * Used by a Bus driver to indicate an event.
- */
-void usbd_device_event_irq (struct usb_device_instance *device, usb_device_event_t event, int data)
-{
-       usb_device_state_t state;
-
-       if (!device || !device->bus) {
-               usberr("(%p,%d) NULL device or device->bus", device, event);
-               return;
-       }
-
-       state = device->device_state;
-
-       usbinfo("%s", usbd_device_events[event]);
-
-       switch (event) {
-       case DEVICE_UNKNOWN:
-               break;
-       case DEVICE_INIT:
-               device->device_state = STATE_INIT;
-               break;
-
-       case DEVICE_CREATE:
-               device->device_state = STATE_ATTACHED;
-               break;
-
-       case DEVICE_HUB_CONFIGURED:
-               device->device_state = STATE_POWERED;
-               break;
-
-       case DEVICE_RESET:
-               device->device_state = STATE_DEFAULT;
-               device->address = 0;
-               break;
-
-       case DEVICE_ADDRESS_ASSIGNED:
-               device->device_state = STATE_ADDRESSED;
-               break;
-
-       case DEVICE_CONFIGURED:
-               device->device_state = STATE_CONFIGURED;
-               break;
-
-       case DEVICE_DE_CONFIGURED:
-               device->device_state = STATE_ADDRESSED;
-               break;
-
-       case DEVICE_BUS_INACTIVE:
-               if (device->status != USBD_CLOSING) {
-                       device->status = USBD_SUSPENDED;
-               }
-               break;
-       case DEVICE_BUS_ACTIVITY:
-               if (device->status != USBD_CLOSING) {
-                       device->status = USBD_OK;
-               }
-               break;
-
-       case DEVICE_SET_INTERFACE:
-               break;
-       case DEVICE_SET_FEATURE:
-               break;
-       case DEVICE_CLEAR_FEATURE:
-               break;
-
-       case DEVICE_POWER_INTERRUPTION:
-               device->device_state = STATE_POWERED;
-               break;
-       case DEVICE_HUB_RESET:
-               device->device_state = STATE_ATTACHED;
-               break;
-       case DEVICE_DESTROY:
-               device->device_state = STATE_UNKNOWN;
-               break;
-
-       case DEVICE_FUNCTION_PRIVATE:
-               break;
-
-       default:
-               usbdbg("event %d - not handled",event);
-               break;
-       }
-       /*usbdbg("%s event: %d oldstate: %d newstate: %d status: %d address: %d",
-               device->name, event, state,
-               device->device_state, device->status, device->address); */
-
-       /* tell the bus interface driver */
-       if( device->event ) {
-               /* usbdbg("calling device->event"); */
-               device->event(device, event, data);
-       }
-}
diff --git a/drivers/usbdcore_ep0.c b/drivers/usbdcore_ep0.c
deleted file mode 100644 (file)
index 1e44f32..0000000
+++ /dev/null
@@ -1,607 +0,0 @@
-/*
- * (C) Copyright 2003
- * Gerry Hamel, geh@ti.com, Texas Instruments
- *
- * (C) Copyright 2006
- * Bryan O'Donoghue, deckard@CodeHermit.ie
- *
- * Based on
- * linux/drivers/usbd/ep0.c
- *
- * Copyright (c) 2000, 2001, 2002 Lineo
- * Copyright (c) 2001 Hewlett Packard
- *
- * By:
- *     Stuart Lynne <sl@lineo.com>,
- *     Tom Rushworth <tbr@lineo.com>,
- *     Bruce Balden <balden@lineo.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-/*
- * This is the builtin ep0 control function. It implements all required functionality
- * for responding to control requests (SETUP packets).
- *
- * XXX
- *
- * Currently we do not pass any SETUP packets (or other) to the configured
- * function driver. This may need to change.
- *
- * XXX
- *
- * As alluded to above, a simple callback cdc_recv_setup has been implemented
- * in the usb_device data structure to facilicate passing
- * Common Device Class packets to a function driver.
- *
- * XXX
- */
-
-#include <common.h>
-
-#if defined(CONFIG_USB_DEVICE)
-#include "usbdcore.h"
-
-#if 0
-#define dbg_ep0(lvl,fmt,args...) serial_printf("[%s] %s:%d: "fmt"\n",__FILE__,__FUNCTION__,__LINE__,##args)
-#else
-#define dbg_ep0(lvl,fmt,args...)
-#endif
-
-/* EP0 Configuration Set ********************************************************************* */
-
-
-/**
- * ep0_get_status - fill in URB data with appropriate status
- * @device:
- * @urb:
- * @index:
- * @requesttype:
- *
- */
-static int ep0_get_status (struct usb_device_instance *device,
-                          struct urb *urb, int index, int requesttype)
-{
-       char *cp;
-
-       urb->actual_length = 2;
-       cp = (char*)urb->buffer;
-       cp[0] = cp[1] = 0;
-
-       switch (requesttype) {
-       case USB_REQ_RECIPIENT_DEVICE:
-               cp[0] = USB_STATUS_SELFPOWERED;
-               break;
-       case USB_REQ_RECIPIENT_INTERFACE:
-               break;
-       case USB_REQ_RECIPIENT_ENDPOINT:
-               cp[0] = usbd_endpoint_halted (device, index);
-               break;
-       case USB_REQ_RECIPIENT_OTHER:
-               urb->actual_length = 0;
-       default:
-               break;
-       }
-       dbg_ep0 (2, "%02x %02x", cp[0], cp[1]);
-       return 0;
-}
-
-/**
- * ep0_get_one
- * @device:
- * @urb:
- * @result:
- *
- * Set a single byte value in the urb send buffer. Return non-zero to signal
- * a request error.
- */
-static int ep0_get_one (struct usb_device_instance *device, struct urb *urb,
-                       __u8 result)
-{
-       urb->actual_length = 1; /* XXX 2? */
-       ((char *) urb->buffer)[0] = result;
-       return 0;
-}
-
-/**
- * copy_config
- * @urb: pointer to urb
- * @data: pointer to configuration data
- * @length: length of data
- *
- * Copy configuration data to urb transfer buffer if there is room for it.
- */
-void copy_config (struct urb *urb, void *data, int max_length,
-                        int max_buf)
-{
-       int available;
-       int length;
-
-       /*dbg_ep0(3, "-> actual: %d buf: %d max_buf: %d max_length: %d data: %p", */
-       /*        urb->actual_length, urb->buffer_length, max_buf, max_length, data); */
-
-       if (!data) {
-               dbg_ep0 (1, "data is NULL");
-               return;
-       }
-       length = max_length;
-
-       if (length > max_length) {
-               dbg_ep0 (1, "length: %d >= max_length: %d", length,
-                        max_length);
-               return;
-       }
-       /*dbg_ep0(1, "   actual: %d buf: %d max_buf: %d max_length: %d length: %d", */
-       /*        urb->actual_length, urb->buffer_length, max_buf, max_length, length); */
-
-       if ((available =
-            /*urb->buffer_length */ max_buf - urb->actual_length) <= 0) {
-               return;
-       }
-       /*dbg_ep0(1, "actual: %d buf: %d max_buf: %d length: %d available: %d", */
-       /*        urb->actual_length, urb->buffer_length, max_buf, length, available); */
-
-       if (length > available) {
-               length = available;
-       }
-       /*dbg_ep0(1, "actual: %d buf: %d max_buf: %d length: %d available: %d", */
-       /*        urb->actual_length, urb->buffer_length, max_buf, length, available); */
-
-       memcpy (urb->buffer + urb->actual_length, data, length);
-       urb->actual_length += length;
-
-       dbg_ep0 (3,
-                "copy_config: <- actual: %d buf: %d max_buf: %d max_length: %d available: %d",
-                urb->actual_length, urb->buffer_length, max_buf, max_length,
-                available);
-}
-
-/**
- * ep0_get_descriptor
- * @device:
- * @urb:
- * @max:
- * @descriptor_type:
- * @index:
- *
- * Called by ep0_rx_process for a get descriptor device command. Determine what
- * descriptor is being requested, copy to send buffer. Return zero if ok to send,
- * return non-zero to signal a request error.
- */
-static int ep0_get_descriptor (struct usb_device_instance *device,
-                              struct urb *urb, int max, int descriptor_type,
-                              int index)
-{
-       int port = 0;           /* XXX compound device */
-       char *cp;
-
-       /*dbg_ep0(3, "max: %x type: %x index: %x", max, descriptor_type, index); */
-
-       if (!urb || !urb->buffer || !urb->buffer_length
-           || (urb->buffer_length < 255)) {
-               dbg_ep0 (2, "invalid urb %p", urb);
-               return -1L;
-       }
-
-       /* setup tx urb */
-       urb->actual_length = 0;
-       cp = (char*)urb->buffer;
-
-       dbg_ep0 (2, "%s", USBD_DEVICE_DESCRIPTORS (descriptor_type));
-
-       switch (descriptor_type) {
-       case USB_DESCRIPTOR_TYPE_DEVICE:
-               {
-                       struct usb_device_descriptor *device_descriptor;
-                       if (!
-                           (device_descriptor =
-                            usbd_device_device_descriptor (device, port))) {
-                               return -1;
-                       }
-                       /* copy descriptor for this device */
-                       copy_config (urb, device_descriptor,
-                                    sizeof (struct usb_device_descriptor),
-                                    max);
-
-                       /* correct the correct control endpoint 0 max packet size into the descriptor */
-                       device_descriptor =
-                               (struct usb_device_descriptor *) urb->buffer;
-
-               }
-               dbg_ep0(3, "copied device configuration, actual_length: 0x%x", urb->actual_length);
-               break;
-
-       case USB_DESCRIPTOR_TYPE_CONFIGURATION:
-               {
-                       struct usb_configuration_descriptor
-                               *configuration_descriptor;
-                       struct usb_device_descriptor *device_descriptor;
-                       if (!
-                           (device_descriptor =
-                            usbd_device_device_descriptor (device, port))) {
-                               return -1;
-                       }
-                       /*dbg_ep0(2, "%d %d", index, device_descriptor->bNumConfigurations); */
-                       if (index > device_descriptor->bNumConfigurations) {
-                               dbg_ep0 (0, "index too large: %d > %d", index,
-                                        device_descriptor->
-                                        bNumConfigurations);
-                               return -1;
-                       }
-
-                       if (!
-                           (configuration_descriptor =
-                            usbd_device_configuration_descriptor (device,
-                                                                  port,
-                                                                  index))) {
-                               dbg_ep0 (0,
-                                        "usbd_device_configuration_descriptor failed: %d",
-                                        index);
-                               return -1;
-                       }
-                       dbg_ep0(0, "attempt to copy %d bytes to urb\n",cpu_to_le16(configuration_descriptor->wTotalLength));
-                       copy_config (urb, configuration_descriptor,
-
-                                       cpu_to_le16(configuration_descriptor->wTotalLength),
-                                    max);
-               }
-
-               break;
-
-       case USB_DESCRIPTOR_TYPE_STRING:
-               {
-                       struct usb_string_descriptor *string_descriptor;
-                       if (!(string_descriptor = usbd_get_string (index))) {
-                               serial_printf("Invalid string index %d\n", index);
-                               return -1;
-                       }
-                       dbg_ep0(3, "string_descriptor: %p length %d", string_descriptor, string_descriptor->bLength);
-                       copy_config (urb, string_descriptor, string_descriptor->bLength, max);
-               }
-               break;
-       case USB_DESCRIPTOR_TYPE_INTERFACE:
-       serial_printf("USB_DESCRIPTOR_TYPE_INTERFACE - error not implemented\n");
-               return -1;
-       case USB_DESCRIPTOR_TYPE_ENDPOINT:
-               serial_printf("USB_DESCRIPTOR_TYPE_ENDPOINT - error not implemented\n");
-               return -1;
-       case USB_DESCRIPTOR_TYPE_HID:
-               {
-                       serial_printf("USB_DESCRIPTOR_TYPE_HID - error not implemented\n");
-                       return -1;      /* unsupported at this time */
-#if 0
-                       int bNumInterface =
-                               le16_to_cpu (urb->device_request.wIndex);
-                       int bAlternateSetting = 0;
-                       int class = 0;
-                       struct usb_class_descriptor *class_descriptor;
-
-                       if (!(class_descriptor =
-                             usbd_device_class_descriptor_index (device,
-                                                                 port, 0,
-                                                                 bNumInterface,
-                                                                 bAlternateSetting,
-                                                                 class))
-                           || class_descriptor->descriptor.hid.bDescriptorType != USB_DT_HID) {
-                               dbg_ep0 (3, "[%d] interface is not HID",
-                                        bNumInterface);
-                               return -1;
-                       }
-                       /* copy descriptor for this class */
-                       copy_config (urb, class_descriptor,
-                                    class_descriptor->descriptor.hid.bLength,
-                                    max);
-#endif
-               }
-               break;
-       case USB_DESCRIPTOR_TYPE_REPORT:
-               {
-                       serial_printf("USB_DESCRIPTOR_TYPE_REPORT - error not implemented\n");
-                       return -1;      /* unsupported at this time */
-#if 0
-                       int bNumInterface =
-                               le16_to_cpu (urb->device_request.wIndex);
-                       int bAlternateSetting = 0;
-                       int class = 0;
-                       struct usb_class_report_descriptor *report_descriptor;
-
-                       if (!(report_descriptor =
-                             usbd_device_class_report_descriptor_index
-                             (device, port, 0, bNumInterface,
-                              bAlternateSetting, class))
-                           || report_descriptor->bDescriptorType !=
-                           USB_DT_REPORT) {
-                               dbg_ep0 (3, "[%d] descriptor is not REPORT",
-                                        bNumInterface);
-                               return -1;
-                       }
-                       /* copy report descriptor for this class */
-                       /*copy_config(urb, &report_descriptor->bData[0], report_descriptor->wLength, max); */
-                       if (max - urb->actual_length > 0) {
-                               int length =
-                                       MIN (report_descriptor->wLength,
-                                            max - urb->actual_length);
-                               memcpy (urb->buffer + urb->actual_length,
-                                       &report_descriptor->bData[0], length);
-                               urb->actual_length += length;
-                       }
-#endif
-               }
-               break;
-       case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
-               {
-                       /* If a USB device supports both a full speed and low speed operation
-                        * we must send a Device_Qualifier descriptor here
-                        */
-                       return -1;
-               }
-       default:
-               return -1;
-       }
-
-
-       dbg_ep0 (1, "urb: buffer: %p buffer_length: %2d actual_length: %2d tx_packetSize: %2d",
-                urb->buffer, urb->buffer_length, urb->actual_length,
-                device->bus->endpoint_array[0].tx_packetSize);
-/*
-    if ((urb->actual_length < max) && !(urb->actual_length % device->bus->endpoint_array[0].tx_packetSize)) {
-       dbg_ep0(0, "adding null byte");
-       urb->buffer[urb->actual_length++] = 0;
-       dbg_ep0(0, "urb: buffer_length: %2d actual_length: %2d packet size: %2d",
-               urb->buffer_length, urb->actual_length device->bus->endpoint_array[0].tx_packetSize);
-    }
-*/
-       return 0;
-
-}
-
-/**
- * ep0_recv_setup - called to indicate URB has been received
- * @urb: pointer to struct urb
- *
- * Check if this is a setup packet, process the device request, put results
- * back into the urb and return zero or non-zero to indicate success (DATA)
- * or failure (STALL).
- *
- */
-int ep0_recv_setup (struct urb *urb)
-{
-       /*struct usb_device_request *request = urb->buffer; */
-       /*struct usb_device_instance *device = urb->device; */
-
-       struct usb_device_request *request;
-       struct usb_device_instance *device;
-       int address;
-
-       dbg_ep0 (0, "entering ep0_recv_setup()");
-       if (!urb || !urb->device) {
-               dbg_ep0 (3, "invalid URB %p", urb);
-               return -1;
-       }
-
-       request = &urb->device_request;
-       device = urb->device;
-
-       dbg_ep0 (3, "urb: %p device: %p", urb, urb->device);
-
-
-       /*dbg_ep0(2, "-       -       -       -       -       -       -       -       -       -"); */
-
-       dbg_ep0 (2,
-                "bmRequestType:%02x bRequest:%02x wValue:%04x wIndex:%04x wLength:%04x %s",
-                request->bmRequestType, request->bRequest,
-                le16_to_cpu (request->wValue), le16_to_cpu (request->wIndex),
-                le16_to_cpu (request->wLength),
-                USBD_DEVICE_REQUESTS (request->bRequest));
-
-       /* handle USB Standard Request (c.f. USB Spec table 9-2) */
-       if ((request->bmRequestType & USB_REQ_TYPE_MASK) != 0) {
-               if(device->device_state <= STATE_CONFIGURED){
-                       /*      Attempt to handle a CDC specific request if we are
-                        *      in the configured state.
-                        */
-                       return device->cdc_recv_setup(request,urb);
-               }
-               dbg_ep0 (1, "non standard request: %x",
-                        request->bmRequestType & USB_REQ_TYPE_MASK);
-               return -1;      /* Stall here */
-       }
-
-       switch (device->device_state) {
-       case STATE_CREATED:
-       case STATE_ATTACHED:
-       case STATE_POWERED:
-               /* It actually is important to allow requests in these states,
-                * Windows will request descriptors before assigning an
-                * address to the client.
-                */
-
-               /*dbg_ep0 (1, "request %s not allowed in this state: %s", */
-               /*                USBD_DEVICE_REQUESTS(request->bRequest), */
-               /*                usbd_device_states[device->device_state]); */
-               /*return -1; */
-               break;
-
-       case STATE_INIT:
-       case STATE_DEFAULT:
-               switch (request->bRequest) {
-               case USB_REQ_GET_STATUS:
-               case USB_REQ_GET_INTERFACE:
-               case USB_REQ_SYNCH_FRAME:       /* XXX should never see this (?) */
-               case USB_REQ_CLEAR_FEATURE:
-               case USB_REQ_SET_FEATURE:
-               case USB_REQ_SET_DESCRIPTOR:
-                       /* case USB_REQ_SET_CONFIGURATION: */
-               case USB_REQ_SET_INTERFACE:
-                       dbg_ep0 (1,
-                                "request %s not allowed in DEFAULT state: %s",
-                                USBD_DEVICE_REQUESTS (request->bRequest),
-                                usbd_device_states[device->device_state]);
-                       return -1;
-
-               case USB_REQ_SET_CONFIGURATION:
-               case USB_REQ_SET_ADDRESS:
-               case USB_REQ_GET_DESCRIPTOR:
-               case USB_REQ_GET_CONFIGURATION:
-                       break;
-               }
-       case STATE_ADDRESSED:
-       case STATE_CONFIGURED:
-               break;
-       case STATE_UNKNOWN:
-               dbg_ep0 (1, "request %s not allowed in UNKNOWN state: %s",
-                        USBD_DEVICE_REQUESTS (request->bRequest),
-                        usbd_device_states[device->device_state]);
-               return -1;
-       }
-
-       /* handle all requests that return data (direction bit set on bm RequestType) */
-       if ((request->bmRequestType & USB_REQ_DIRECTION_MASK)) {
-
-               dbg_ep0 (3, "Device-to-Host");
-
-               switch (request->bRequest) {
-
-               case USB_REQ_GET_STATUS:
-                       return ep0_get_status (device, urb, request->wIndex,
-                                              request->bmRequestType &
-                                              USB_REQ_RECIPIENT_MASK);
-
-               case USB_REQ_GET_DESCRIPTOR:
-                       return ep0_get_descriptor (device, urb,
-                                                  le16_to_cpu (request->wLength),
-                                                  le16_to_cpu (request->wValue) >> 8,
-                                                  le16_to_cpu (request->wValue) & 0xff);
-
-               case USB_REQ_GET_CONFIGURATION:
-                       serial_printf("get config %d\n", device->configuration);
-                       return ep0_get_one (device, urb,
-                                           device->configuration);
-
-               case USB_REQ_GET_INTERFACE:
-                       return ep0_get_one (device, urb, device->alternate);
-
-               case USB_REQ_SYNCH_FRAME:       /* XXX should never see this (?) */
-                       return -1;
-
-               case USB_REQ_CLEAR_FEATURE:
-               case USB_REQ_SET_FEATURE:
-               case USB_REQ_SET_ADDRESS:
-               case USB_REQ_SET_DESCRIPTOR:
-               case USB_REQ_SET_CONFIGURATION:
-               case USB_REQ_SET_INTERFACE:
-                       return -1;
-               }
-       }
-       /* handle the requests that do not return data */
-       else {
-
-
-               /*dbg_ep0(3, "Host-to-Device"); */
-               switch (request->bRequest) {
-
-               case USB_REQ_CLEAR_FEATURE:
-               case USB_REQ_SET_FEATURE:
-                       dbg_ep0 (0, "Host-to-Device");
-                       switch (request->
-                               bmRequestType & USB_REQ_RECIPIENT_MASK) {
-                       case USB_REQ_RECIPIENT_DEVICE:
-                               /* XXX DEVICE_REMOTE_WAKEUP or TEST_MODE would be added here */
-                               /* XXX fall through for now as we do not support either */
-                       case USB_REQ_RECIPIENT_INTERFACE:
-                       case USB_REQ_RECIPIENT_OTHER:
-                               dbg_ep0 (0, "request %s not",
-                                        USBD_DEVICE_REQUESTS (request->bRequest));
-                       default:
-                               return -1;
-
-                       case USB_REQ_RECIPIENT_ENDPOINT:
-                               dbg_ep0 (0, "ENDPOINT: %x", le16_to_cpu (request->wValue));
-                               if (le16_to_cpu (request->wValue) == USB_ENDPOINT_HALT) {
-                                       /*return usbd_device_feature (device, le16_to_cpu (request->wIndex), */
-                                       /*                    request->bRequest == USB_REQ_SET_FEATURE); */
-                                       /* NEED TO IMPLEMENT THIS!!! */
-                                       return -1;
-                               } else {
-                                       dbg_ep0 (1, "request %s bad wValue: %04x",
-                                                USBD_DEVICE_REQUESTS
-                                                (request->bRequest),
-                                                le16_to_cpu (request->wValue));
-                                       return -1;
-                               }
-                       }
-
-               case USB_REQ_SET_ADDRESS:
-                       /* check if this is a re-address, reset first if it is (this shouldn't be possible) */
-                       if (device->device_state != STATE_DEFAULT) {
-                               dbg_ep0 (1, "set_address: %02x state: %s",
-                                        le16_to_cpu (request->wValue),
-                                        usbd_device_states[device->device_state]);
-                               return -1;
-                       }
-                       address = le16_to_cpu (request->wValue);
-                       if ((address & 0x7f) != address) {
-                               dbg_ep0 (1, "invalid address %04x %04x",
-                                        address, address & 0x7f);
-                               return -1;
-                       }
-                       device->address = address;
-
-                       /*dbg_ep0(2, "address: %d %d %d", */
-                       /*        request->wValue, le16_to_cpu(request->wValue), device->address); */
-
-                       return 0;
-
-               case USB_REQ_SET_DESCRIPTOR:    /* XXX should we support this? */
-                       dbg_ep0 (0, "set descriptor: NOT SUPPORTED");
-                       return -1;
-
-               case USB_REQ_SET_CONFIGURATION:
-                       /* c.f. 9.4.7 - the top half of wValue is reserved */
-                       /* */
-                       if ((device->configuration =
-                               le16_to_cpu (request->wValue) & 0xFF80) != 0) {
-                               /* c.f. 9.4.7 - zero is the default or addressed state, in our case this */
-                               /* is the same is configuration zero */
-                               serial_printf("error setting dev->config to zero!\n");
-                               device->configuration = 0;      /* TBR - ?????? */
-                       }
-                       /* reset interface and alternate settings */
-                       device->interface = device->alternate = 0;
-
-                       /*dbg_ep0(2, "set configuration: %d", device->configuration); */
-                       /*serial_printf("DEVICE_CONFIGURED.. event?\n"); */
-                       return 0;
-
-               case USB_REQ_SET_INTERFACE:
-                       device->interface = le16_to_cpu (request->wIndex);
-                       device->alternate = le16_to_cpu (request->wValue);
-                       /*dbg_ep0(2, "set interface: %d alternate: %d", device->interface, device->alternate); */
-                       serial_printf ("DEVICE_SET_INTERFACE.. event?\n");
-                       return 0;
-
-               case USB_REQ_GET_STATUS:
-               case USB_REQ_GET_DESCRIPTOR:
-               case USB_REQ_GET_CONFIGURATION:
-               case USB_REQ_GET_INTERFACE:
-               case USB_REQ_SYNCH_FRAME:       /* XXX should never see this (?) */
-                       return -1;
-               }
-       }
-       return -1;
-}
-
-#endif
diff --git a/drivers/usbdcore_mpc8xx.c b/drivers/usbdcore_mpc8xx.c
deleted file mode 100644 (file)
index d4c4096..0000000
+++ /dev/null
@@ -1,1401 +0,0 @@
-/*
- * Copyright (C) 2006 by Bryan O'Donoghue, CodeHermit
- * bodonoghue@CodeHermit.ie
- *
- * References
- * DasUBoot/drivers/usbdcore_omap1510.c, for design and implementation ideas.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- */
-
-/*
- * Notes :
- * 1.  #define __SIMULATE_ERROR__ to inject a CRC error into every 2nd TX
- *             packet to force the USB re-transmit protocol.
- *
- * 2.  #define __DEBUG_UDC__ to switch on debug tracing to serial console
- *     be careful that tracing doesn't create Hiesen-bugs with respect to
- *     response timeouts to control requests.
- *
- * 3.  This driver should be able to support any higher level driver that
- *     that wants to do either of the two standard UDC implementations
- *     Control-Bulk-Interrupt or  Bulk-IN/Bulk-Out standards. Hence
- *     gserial and cdc_acm should work with this code.
- *
- * 4.  NAK events never actually get raised at all, the documentation
- *     is just wrong !
- *
- * 5.  For some reason, cbd_datlen is *always* +2 the value it should be.
- *     this means that having an RX cbd of 16 bytes is not possible, since
- *     the same size is reported for 14 bytes received as 16 bytes received
- *     until we can find out why this happens, RX cbds must be limited to 8
- *     bytes. TODO: check errata for this behaviour.
- *
- * 6.  Right now this code doesn't support properly powering up with the USB
- *     cable attached to the USB host my development board the Adder87x doesn't
- *     have a pull-up fitted to allow this, so it is necessary to power the
- *     board and *then* attached the USB cable to the host. However somebody
- *     with a different design in their board may be able to keep the cable
- *     constantly connected and simply enable/disable a pull-up  re
- *     figure 31.1 in MPC885RM.pdf instead of having to power up the board and
- *     then attach the cable !
- *
- */
-#include <common.h>
-#include <config.h>
-
-#if defined(CONFIG_MPC885_FAMILY) && defined(CONFIG_USB_DEVICE)
-#include <commproc.h>
-#include "usbdcore.h"
-#include "usbdcore_mpc8xx.h"
-#include "usbdcore_ep0.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#define ERR(fmt, args...)\
-       serial_printf("ERROR : [%s] %s:%d: "fmt,\
-                               __FILE__,__FUNCTION__,__LINE__, ##args)
-#ifdef __DEBUG_UDC__
-#define DBG(fmt,args...)\
-               serial_printf("[%s] %s:%d: "fmt,\
-                               __FILE__,__FUNCTION__,__LINE__, ##args)
-#else
-#define DBG(fmt,args...)
-#endif
-
-/* Static Data */
-#ifdef __SIMULATE_ERROR__
-static char err_poison_test = 0;
-#endif
-static struct mpc8xx_ep ep_ref[MAX_ENDPOINTS];
-static u32 address_base = STATE_NOT_READY;
-static mpc8xx_udc_state_t udc_state = 0;
-static struct usb_device_instance *udc_device = 0;
-static volatile usb_epb_t *endpoints[MAX_ENDPOINTS];
-static volatile cbd_t *tx_cbd[TX_RING_SIZE];
-static volatile cbd_t *rx_cbd[RX_RING_SIZE];
-static volatile immap_t *immr = 0;
-static volatile cpm8xx_t *cp = 0;
-static volatile usb_pram_t *usb_paramp = 0;
-static volatile usb_t *usbp = 0;
-static int rx_ct = 0;
-static int tx_ct = 0;
-
-/* Static Function Declarations */
-static void mpc8xx_udc_state_transition_up (usb_device_state_t initial,
-                                           usb_device_state_t final);
-static void mpc8xx_udc_state_transition_down (usb_device_state_t initial,
-                                             usb_device_state_t final);
-static void mpc8xx_udc_stall (unsigned int ep);
-static void mpc8xx_udc_flush_tx_fifo (int epid);
-static void mpc8xx_udc_flush_rx_fifo (void);
-static void mpc8xx_udc_clear_rxbd (volatile cbd_t * rx_cbdp);
-static void mpc8xx_udc_init_tx (struct usb_endpoint_instance *epi,
-                               struct urb *tx_urb);
-static void mpc8xx_udc_dump_request (struct usb_device_request *request);
-static void mpc8xx_udc_clock_init (volatile immap_t * immr,
-                                  volatile cpm8xx_t * cp);
-static int mpc8xx_udc_ep_tx (struct usb_endpoint_instance *epi);
-static int mpc8xx_udc_epn_rx (unsigned int epid, volatile cbd_t * rx_cbdp);
-static void mpc8xx_udc_ep0_rx (volatile cbd_t * rx_cbdp);
-static void mpc8xx_udc_cbd_init (void);
-static void mpc8xx_udc_endpoint_init (void);
-static void mpc8xx_udc_cbd_attach (int ep, uchar tx_size, uchar rx_size);
-static u32 mpc8xx_udc_alloc (u32 data_size, u32 alignment);
-static int mpc8xx_udc_ep0_rx_setup (volatile cbd_t * rx_cbdp);
-static void mpc8xx_udc_set_nak (unsigned int ep);
-static short mpc8xx_udc_handle_txerr (void);
-static void mpc8xx_udc_advance_rx (volatile cbd_t ** rx_cbdp, int epid);
-
-/******************************************************************************
-                              Global Linkage
- *****************************************************************************/
-
-/* udc_init
- *
- * Do initial bus gluing
- */
-int udc_init (void)
-{
-       /* Init various pointers */
-       immr = (immap_t *) CFG_IMMR;
-       cp = (cpm8xx_t *) & (immr->im_cpm);
-       usb_paramp = (usb_pram_t *) & (cp->cp_dparam[PROFF_USB]);
-       usbp = (usb_t *) & (cp->cp_scc[0]);
-
-       memset (ep_ref, 0x00, (sizeof (struct mpc8xx_ep) * MAX_ENDPOINTS));
-
-       udc_device = 0;
-       udc_state = STATE_NOT_READY;
-
-       usbp->usmod = 0x00;
-       usbp->uscom = 0;
-
-       /* Set USB Frame #0, Respond at Address & Get a clock source  */
-       usbp->usaddr = 0x00;
-       mpc8xx_udc_clock_init (immr, cp);
-
-       /* PA15, PA14 as perhiperal USBRXD and USBOE */
-       immr->im_ioport.iop_padir &= ~0x0003;
-       immr->im_ioport.iop_papar |= 0x0003;
-
-       /* PC11/PC10 as peripheral USBRXP USBRXN */
-       immr->im_ioport.iop_pcso |= 0x0030;
-
-       /* PC7/PC6 as perhiperal USBTXP and USBTXN */
-       immr->im_ioport.iop_pcdir |= 0x0300;
-       immr->im_ioport.iop_pcpar |= 0x0300;
-
-       /* Set the base address */
-       address_base = (u32) (cp->cp_dpmem + CPM_USB_BASE);
-
-       /* Initialise endpoints and circular buffers */
-       mpc8xx_udc_endpoint_init ();
-       mpc8xx_udc_cbd_init ();
-
-       /* Assign allocated Dual Port Endpoint descriptors */
-       usb_paramp->ep0ptr = (u32) endpoints[0];
-       usb_paramp->ep1ptr = (u32) endpoints[1];
-       usb_paramp->ep2ptr = (u32) endpoints[2];
-       usb_paramp->ep3ptr = (u32) endpoints[3];
-       usb_paramp->frame_n = 0;
-
-       DBG ("ep0ptr=0x%08x ep1ptr=0x%08x ep2ptr=0x%08x ep3ptr=0x%08x\n",
-            usb_paramp->ep0ptr, usb_paramp->ep1ptr, usb_paramp->ep2ptr,
-            usb_paramp->ep3ptr);
-
-       return 0;
-}
-
-/* udc_irq
- *
- * Poll for whatever events may have occured
- */
-void udc_irq (void)
-{
-       int epid = 0;
-       volatile cbd_t *rx_cbdp = 0;
-       volatile cbd_t *rx_cbdp_base = 0;
-
-       if (udc_state != STATE_READY) {
-               return;
-       }
-
-       if (usbp->usber & USB_E_BSY) {
-               /* This shouldn't happen. If it does then it's a bug ! */
-               usbp->usber |= USB_E_BSY;
-               mpc8xx_udc_flush_rx_fifo ();
-       }
-
-       /* Scan all RX/Bidirectional Endpoints for RX data. */
-       for (epid = 0; epid < MAX_ENDPOINTS; epid++) {
-               if (!ep_ref[epid].prx) {
-                       continue;
-               }
-               rx_cbdp = rx_cbdp_base = ep_ref[epid].prx;
-
-               do {
-                       if (!(rx_cbdp->cbd_sc & RX_BD_E)) {
-
-                               if (rx_cbdp->cbd_sc & 0x1F) {
-                                       /* Corrupt data discard it.
-                                        * Controller has NAK'd this packet.
-                                        */
-                                       mpc8xx_udc_clear_rxbd (rx_cbdp);
-
-                               } else {
-                                       if (!epid) {
-                                               mpc8xx_udc_ep0_rx (rx_cbdp);
-
-                                       } else {
-                                               /* Process data */
-                                               mpc8xx_udc_set_nak (epid);
-                                               mpc8xx_udc_epn_rx (epid, rx_cbdp);
-                                               mpc8xx_udc_clear_rxbd (rx_cbdp);
-                                       }
-                               }
-
-                               /* Advance RX CBD pointer */
-                               mpc8xx_udc_advance_rx (&rx_cbdp, epid);
-                               ep_ref[epid].prx = rx_cbdp;
-                       } else {
-                               /* Advance RX CBD pointer */
-                               mpc8xx_udc_advance_rx (&rx_cbdp, epid);
-                       }
-
-               } while (rx_cbdp != rx_cbdp_base);
-       }
-
-       /* Handle TX events as appropiate, the correct place to do this is
-        * in a tx routine. Perhaps TX on epn was pre-empted by ep0
-        */
-
-       if (usbp->usber & USB_E_TXB) {
-               usbp->usber |= USB_E_TXB;
-       }
-
-       if (usbp->usber & (USB_TX_ERRMASK)) {
-               mpc8xx_udc_handle_txerr ();
-       }
-
-       /* Switch to the default state, respond at the default address */
-       if (usbp->usber & USB_E_RESET) {
-               usbp->usber |= USB_E_RESET;
-               usbp->usaddr = 0x00;
-               udc_device->device_state = STATE_DEFAULT;
-       }
-
-       /* if(usbp->usber&USB_E_IDLE){
-          We could suspend here !
-          usbp->usber|=USB_E_IDLE;
-          DBG("idle state change\n");
-          }
-          if(usbp->usbs){
-          We could resume here when IDLE is deasserted !
-          Not worth doing, so long as we are self powered though.
-          }
-       */
-
-       return;
-}
-
-/* udc_endpoint_write
- *
- * Write some data to an endpoint
- */
-int udc_endpoint_write (struct usb_endpoint_instance *epi)
-{
-       int ep = 0;
-       short epid = 1, unnak = 0, ret = 0;
-
-       if (udc_state != STATE_READY) {
-               ERR ("invalid udc_state != STATE_READY!\n");
-               return -1;
-       }
-
-       if (!udc_device || !epi) {
-               return -1;
-       }
-
-       if (udc_device->device_state != STATE_CONFIGURED) {
-               return -1;
-       }
-
-       ep = epi->endpoint_address & 0x03;
-       if (ep >= MAX_ENDPOINTS) {
-               return -1;
-       }
-
-       /* Set NAK for all RX endpoints during TX */
-       for (epid = 1; epid < MAX_ENDPOINTS; epid++) {
-
-               /* Don't set NAK on DATA IN/CONTROL endpoints */
-               if (ep_ref[epid].sc & USB_DIR_IN) {
-                       continue;
-               }
-
-               if (!(usbp->usep[epid] & (USEP_THS_NAK | USEP_RHS_NAK))) {
-                       unnak |= 1 << epid;
-               }
-
-               mpc8xx_udc_set_nak (epid);
-       }
-
-       mpc8xx_udc_init_tx (&udc_device->bus->endpoint_array[ep],
-                           epi->tx_urb);
-       ret = mpc8xx_udc_ep_tx (&udc_device->bus->endpoint_array[ep]);
-
-       /* Remove temporary NAK */
-       for (epid = 1; epid < MAX_ENDPOINTS; epid++) {
-               if (unnak & (1 << epid)) {
-                       udc_unset_nak (epid);
-               }
-       }
-
-       return ret;
-}
-
-/* mpc8xx_udc_assign_urb
- *
- * Associate a given urb to an endpoint TX or RX transmit/receive buffers
- */
-static int mpc8xx_udc_assign_urb (int ep, char direction)
-{
-       struct usb_endpoint_instance *epi = 0;
-
-       if (ep >= MAX_ENDPOINTS) {
-               goto err;
-       }
-       epi = &udc_device->bus->endpoint_array[ep];
-       if (!epi) {
-               goto err;
-       }
-
-       if (!ep_ref[ep].urb) {
-               ep_ref[ep].urb = usbd_alloc_urb (udc_device, udc_device->bus->endpoint_array);
-               if (!ep_ref[ep].urb) {
-                       goto err;
-               }
-       } else {
-               ep_ref[ep].urb->actual_length = 0;
-       }
-
-       switch (direction) {
-       case USB_DIR_IN:
-               epi->tx_urb = ep_ref[ep].urb;
-               break;
-       case USB_DIR_OUT:
-               epi->rcv_urb = ep_ref[ep].urb;
-               break;
-       default:
-               goto err;
-       }
-       return 0;
-
-      err:
-       udc_state = STATE_ERROR;
-       return -1;
-}
-
-/* udc_setup_ep
- *
- * Associate U-Boot software endpoints to mpc8xx endpoint parameter ram
- * Isochronous endpoints aren't yet supported!
- */
-void udc_setup_ep (struct usb_device_instance *device, unsigned int ep,
-                  struct usb_endpoint_instance *epi)
-{
-       uchar direction = 0;
-       int ep_attrib = 0;
-
-       if (epi && (ep < MAX_ENDPOINTS)) {
-
-               if (ep == 0) {
-                       if (epi->rcv_attributes != USB_ENDPOINT_XFER_CONTROL
-                           || epi->tx_attributes !=
-                           USB_ENDPOINT_XFER_CONTROL) {
-
-                               /* ep0 must be a control endpoint */
-                               udc_state = STATE_ERROR;
-                               return;
-
-                       }
-                       if (!(ep_ref[ep].sc & EP_ATTACHED)) {
-                               mpc8xx_udc_cbd_attach (ep, epi->tx_packetSize,
-                                                      epi->rcv_packetSize);
-                       }
-                       usbp->usep[ep] = 0x0000;
-                       return;
-               }
-
-               if ((epi->endpoint_address & USB_ENDPOINT_DIR_MASK)
-                   == USB_DIR_IN) {
-
-                       direction = 1;
-                       ep_attrib = epi->tx_attributes;
-                       epi->rcv_packetSize = 0;
-                       ep_ref[ep].sc |= USB_DIR_IN;
-               } else {
-
-                       direction = 0;
-                       ep_attrib = epi->rcv_attributes;
-                       epi->tx_packetSize = 0;
-                       ep_ref[ep].sc &= ~USB_DIR_IN;
-               }
-
-               if (mpc8xx_udc_assign_urb (ep, epi->endpoint_address
-                                          & USB_ENDPOINT_DIR_MASK)) {
-                       return;
-               }
-
-               switch (ep_attrib) {
-               case USB_ENDPOINT_XFER_CONTROL:
-                       if (!(ep_ref[ep].sc & EP_ATTACHED)) {
-                               mpc8xx_udc_cbd_attach (ep,
-                                                      epi->tx_packetSize,
-                                                      epi->rcv_packetSize);
-                       }
-                       usbp->usep[ep] = ep << 12;
-                       epi->rcv_urb = epi->tx_urb = ep_ref[ep].urb;
-
-                       break;
-               case USB_ENDPOINT_XFER_BULK:
-               case USB_ENDPOINT_XFER_INT:
-                       if (!(ep_ref[ep].sc & EP_ATTACHED)) {
-                               if (direction) {
-                                       mpc8xx_udc_cbd_attach (ep,
-                                                              epi->tx_packetSize,
-                                                              0);
-                               } else {
-                                       mpc8xx_udc_cbd_attach (ep,
-                                                              0,
-                                                              epi->rcv_packetSize);
-                               }
-                       }
-                       usbp->usep[ep] = (ep << 12) | ((ep_attrib) << 8);
-
-                       break;
-               case USB_ENDPOINT_XFER_ISOC:
-               default:
-                       serial_printf ("Error endpoint attrib %d>3\n", ep_attrib);
-                       udc_state = STATE_ERROR;
-                       break;
-               }
-       }
-
-}
-
-/* udc_connect
- *
- * Move state, switch on the USB
- */
-void udc_connect (void)
-{
-       /* Enable pull-up resistor on D+
-        * TODO: fit a pull-up resistor to drive SE0 for > 2.5us
-        */
-
-       if (udc_state != STATE_ERROR) {
-               udc_state = STATE_READY;
-               usbp->usmod |= USMOD_EN;
-       }
-}
-
-/* udc_disconnect
- *
- * Disconnect is not used but, is included for completeness
- */
-void udc_disconnect (void)
-{
-       /* Disable pull-up resistor on D-
-        * TODO: fix a pullup resistor to control this
-        */
-
-       if (udc_state != STATE_ERROR) {
-               udc_state = STATE_NOT_READY;
-       }
-       usbp->usmod &= ~USMOD_EN;
-}
-
-/* udc_enable
- *
- * Grab an EP0 URB, register interest in a subset of USB events
- */
-void udc_enable (struct usb_device_instance *device)
-{
-       if (udc_state == STATE_ERROR) {
-               return;
-       }
-
-       udc_device = device;
-
-       if (!ep_ref[0].urb) {
-               ep_ref[0].urb = usbd_alloc_urb (device, device->bus->endpoint_array);
-       }
-
-       /* Register interest in all events except SOF, enable transceiver */
-       usbp->usber = 0x03FF;
-       usbp->usbmr = 0x02F7;
-
-       return;
-}
-
-/* udc_disable
- *
- * disable the currently hooked device
- */
-void udc_disable (void)
-{
-       int i = 0;
-
-       if (udc_state == STATE_ERROR) {
-               DBG ("Won't disable UDC. udc_state==STATE_ERROR !\n");
-               return;
-       }
-
-       udc_device = 0;
-
-       for (; i < MAX_ENDPOINTS; i++) {
-               if (ep_ref[i].urb) {
-                       usbd_dealloc_urb (ep_ref[i].urb);
-                       ep_ref[i].urb = 0;
-               }
-       }
-
-       usbp->usbmr = 0x00;
-       usbp->usmod = ~USMOD_EN;
-       udc_state = STATE_NOT_READY;
-}
-
-/* udc_startup_events
- *
- * Enable the specified device
- */
-void udc_startup_events (struct usb_device_instance *device)
-{
-       udc_enable (device);
-       if (udc_state == STATE_READY) {
-               usbd_device_event_irq (device, DEVICE_CREATE, 0);
-       }
-}
-
-/* udc_set_nak
- *
- * Allow upper layers to signal lower layers should not accept more RX data
- *
- */
-void udc_set_nak (int epid)
-{
-       if (epid) {
-               mpc8xx_udc_set_nak (epid);
-       }
-}
-
-/* udc_unset_nak
- *
- * Suspend sending of NAK tokens for DATA OUT tokens on a given endpoint.
- * Switch off NAKing on this endpoint to accept more data output from host.
- *
- */
-void udc_unset_nak (int epid)
-{
-       if (epid > MAX_ENDPOINTS) {
-               return;
-       }
-
-       if (usbp->usep[epid] & (USEP_THS_NAK | USEP_RHS_NAK)) {
-               usbp->usep[epid] &= ~(USEP_THS_NAK | USEP_RHS_NAK);
-               __asm__ ("eieio");
-       }
-}
-
-/******************************************************************************
-                             Static Linkage
-******************************************************************************/
-
-/* udc_state_transition_up
- * udc_state_transition_down
- *
- * Helper functions to implement device state changes. The device states and
- * the events that transition between them are:
- *
- *                             STATE_ATTACHED
- *                             ||      /\
- *                             \/      ||
- *     DEVICE_HUB_CONFIGURED                   DEVICE_HUB_RESET
- *                             ||      /\
- *                             \/      ||
- *                             STATE_POWERED
- *                             ||      /\
- *                             \/      ||
- *     DEVICE_RESET                            DEVICE_POWER_INTERRUPTION
- *                             ||      /\
- *                             \/      ||
- *                             STATE_DEFAULT
- *                             ||      /\
- *                             \/      ||
- *     DEVICE_ADDRESS_ASSIGNED                 DEVICE_RESET
- *                             ||      /\
- *                             \/      ||
- *                             STATE_ADDRESSED
- *                             ||      /\
- *                             \/      ||
- *     DEVICE_CONFIGURED                       DEVICE_DE_CONFIGURED
- *                             ||      /\
- *                             \/      ||
- *                             STATE_CONFIGURED
- *
- * udc_state_transition_up transitions up (in the direction from STATE_ATTACHED
- * to STATE_CONFIGURED) from the specified initial state to the specified final
- * state, passing through each intermediate state on the way.  If the initial
- * state is at or above (i.e. nearer to STATE_CONFIGURED) the final state, then
- * no state transitions will take place.
- *
- * udc_state_transition_down transitions down (in the direction from
- * STATE_CONFIGURED to STATE_ATTACHED) from the specified initial state to the
- * specified final state, passing through each intermediate state on the way.
- * If the initial state is at or below (i.e. nearer to STATE_ATTACHED) the final
- * state, then no state transitions will take place.
- *
- */
-
-static void mpc8xx_udc_state_transition_up (usb_device_state_t initial,
-                                           usb_device_state_t final)
-{
-       if (initial < final) {
-               switch (initial) {
-               case STATE_ATTACHED:
-                       usbd_device_event_irq (udc_device,
-                                              DEVICE_HUB_CONFIGURED, 0);
-                       if (final == STATE_POWERED)
-                               break;
-               case STATE_POWERED:
-                       usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
-                       if (final == STATE_DEFAULT)
-                               break;
-               case STATE_DEFAULT:
-                       usbd_device_event_irq (udc_device,
-                                              DEVICE_ADDRESS_ASSIGNED, 0);
-                       if (final == STATE_ADDRESSED)
-                               break;
-               case STATE_ADDRESSED:
-                       usbd_device_event_irq (udc_device, DEVICE_CONFIGURED,
-                                              0);
-               case STATE_CONFIGURED:
-                       break;
-               default:
-                       break;
-               }
-       }
-}
-
-static void mpc8xx_udc_state_transition_down (usb_device_state_t initial,
-                                             usb_device_state_t final)
-{
-       if (initial > final) {
-               switch (initial) {
-               case STATE_CONFIGURED:
-                       usbd_device_event_irq (udc_device,
-                                              DEVICE_DE_CONFIGURED, 0);
-                       if (final == STATE_ADDRESSED)
-                               break;
-               case STATE_ADDRESSED:
-                       usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
-                       if (final == STATE_DEFAULT)
-                               break;
-               case STATE_DEFAULT:
-                       usbd_device_event_irq (udc_device,
-                                              DEVICE_POWER_INTERRUPTION, 0);
-                       if (final == STATE_POWERED)
-                               break;
-               case STATE_POWERED:
-                       usbd_device_event_irq (udc_device, DEVICE_HUB_RESET,
-                                              0);
-               case STATE_ATTACHED:
-                       break;
-               default:
-                       break;
-               }
-       }
-}
-
-/* mpc8xx_udc_stall
- *
- * Force returning of STALL tokens on the given endpoint. Protocol or function
- * STALL conditions are permissable here
- */
-static void mpc8xx_udc_stall (unsigned int ep)
-{
-       usbp->usep[ep] |= STALL_BITMASK;
-}
-
-/* mpc8xx_udc_set_nak
- *
- * Force returning of NAK responses for the given endpoint as a kind of very
- * simple flow control
- */
-static void mpc8xx_udc_set_nak (unsigned int ep)
-{
-       usbp->usep[ep] |= NAK_BITMASK;
-       __asm__ ("eieio");
-}
-
-/* mpc8xx_udc_handle_txerr
- *
- * Handle errors relevant to TX. Return a status code to allow calling
- * indicative of what if anything happened
- */
-static short mpc8xx_udc_handle_txerr ()
-{
-       short ep = 0, ret = 0;
-
-       for (; ep < TX_RING_SIZE; ep++) {
-               if (usbp->usber & (0x10 << ep)) {
-
-                       /* Timeout or underrun */
-                       if (tx_cbd[ep]->cbd_sc & 0x06) {
-                               ret = 1;
-                               mpc8xx_udc_flush_tx_fifo (ep);
-
-                       } else {
-                               if (usbp->usep[ep] & STALL_BITMASK) {
-                                       if (!ep) {
-                                               usbp->usep[ep] &= ~STALL_BITMASK;
-                                       }
-                               }       /* else NAK */
-                       }
-                       usbp->usber |= (0x10 << ep);
-               }
-       }
-       return ret;
-}
-
-/* mpc8xx_udc_advance_rx
- *
- * Advance cbd rx
- */
-static void mpc8xx_udc_advance_rx (volatile cbd_t ** rx_cbdp, int epid)
-{
-       if ((*rx_cbdp)->cbd_sc & RX_BD_W) {
-               *rx_cbdp = (volatile cbd_t *) (endpoints[epid]->rbase + CFG_IMMR);
-
-       } else {
-               (*rx_cbdp)++;
-       }
-}
-
-
-/* mpc8xx_udc_flush_tx_fifo
- *
- * Flush a given TX fifo. Assumes one tx cbd per endpoint
- */
-static void mpc8xx_udc_flush_tx_fifo (int epid)
-{
-       volatile cbd_t *tx_cbdp = 0;
-
-       if (epid > MAX_ENDPOINTS) {
-               return;
-       }
-
-       /* TX stop */
-       immr->im_cpm.cp_cpcr = ((epid << 2) | 0x1D01);
-       __asm__ ("eieio");
-       while (immr->im_cpm.cp_cpcr & 0x01);
-
-       usbp->uscom = 0x40 | 0;
-
-       /* reset ring */
-       tx_cbdp = (cbd_t *) (endpoints[epid]->tbptr + CFG_IMMR);
-       tx_cbdp->cbd_sc = (TX_BD_I | TX_BD_W);
-
-
-       endpoints[epid]->tptr = endpoints[epid]->tbase;
-       endpoints[epid]->tstate = 0x00;
-       endpoints[epid]->tbcnt = 0x00;
-
-       /* TX start */
-       immr->im_cpm.cp_cpcr = ((epid << 2) | 0x2D01);
-       __asm__ ("eieio");
-       while (immr->im_cpm.cp_cpcr & 0x01);
-
-       return;
-}
-
-/* mpc8xx_udc_flush_rx_fifo
- *
- * For the sake of completeness of the namespace, it seems like
- * a good-design-decision (tm) to include mpc8xx_udc_flush_rx_fifo();
- * If RX_BD_E is true => a driver bug either here or in an upper layer
- * not polling frequently enough. If RX_BD_E is true we have told the host
- * we have accepted data but, the CPM found it had no-where to put that data
- * which needless to say would be a bad thing.
- */
-static void mpc8xx_udc_flush_rx_fifo ()
-{
-       int i = 0;
-
-       for (i = 0; i < RX_RING_SIZE; i++) {
-               if (!(rx_cbd[i]->cbd_sc & RX_BD_E)) {
-                       ERR ("buf %p used rx data len = 0x%x sc=0x%x!\n",
-                            rx_cbd[i], rx_cbd[i]->cbd_datlen,
-                            rx_cbd[i]->cbd_sc);
-
-               }
-       }
-       ERR ("BUG : Input over-run\n");
-}
-
-/* mpc8xx_udc_clear_rxbd
- *
- * Release control of RX CBD to CP.
- */
-static void mpc8xx_udc_clear_rxbd (volatile cbd_t * rx_cbdp)
-{
-       rx_cbdp->cbd_datlen = 0x0000;
-       rx_cbdp->cbd_sc = ((rx_cbdp->cbd_sc & RX_BD_W) | (RX_BD_E | RX_BD_I));
-       __asm__ ("eieio");
-}
-
-/* mpc8xx_udc_tx_irq
- *
- * Parse for tx timeout, control RX or USB reset/busy conditions
- * Return -1 on timeout, -2 on fatal error, else return zero
- */
-static int mpc8xx_udc_tx_irq (int ep)
-{
-       int i = 0;
-
-       if (usbp->usber & (USB_TX_ERRMASK)) {
-               if (mpc8xx_udc_handle_txerr ()) {
-                       /* Timeout, controlling function must retry send */
-                       return -1;
-               }
-       }
-
-       if (usbp->usber & (USB_E_RESET | USB_E_BSY)) {
-               /* Fatal, abandon TX transaction */
-               return -2;
-       }
-
-       if (usbp->usber & USB_E_RXB) {
-               for (i = 0; i < RX_RING_SIZE; i++) {
-                       if (!(rx_cbd[i]->cbd_sc & RX_BD_E)) {
-                               if ((rx_cbd[i] == ep_ref[0].prx) || ep) {
-                                       return -2;
-                               }
-                       }
-               }
-       }
-
-       return 0;
-}
-
-/* mpc8xx_udc_ep_tx
- *
- * Transmit in a re-entrant fashion outbound USB packets.
- * Implement retry/timeout mechanism described in USB specification
- * Toggle DATA0/DATA1 pids as necessary
- * Introduces non-standard tx_retry. The USB standard has no scope for slave
- * devices to give up TX, however tx_retry stops us getting stuck in an endless
- * TX loop.
- */
-static int mpc8xx_udc_ep_tx (struct usb_endpoint_instance *epi)
-{
-       struct urb *urb = epi->tx_urb;
-       volatile cbd_t *tx_cbdp = 0;
-       unsigned int ep = 0, pkt_len = 0, x = 0, tx_retry = 0;
-       int ret = 0;
-
-       if (!epi || (epi->endpoint_address & 0x03) >= MAX_ENDPOINTS || !urb) {
-               return -1;
-       }
-
-       ep = epi->endpoint_address & 0x03;
-       tx_cbdp = (cbd_t *) (endpoints[ep]->tbptr + CFG_IMMR);
-
-       if (tx_cbdp->cbd_sc & TX_BD_R || usbp->usber & USB_E_TXB) {
-               mpc8xx_udc_flush_tx_fifo (ep);
-               usbp->usber |= USB_E_TXB;
-       };
-
-       while (tx_retry++ < 100) {
-               ret = mpc8xx_udc_tx_irq (ep);
-               if (ret == -1) {
-                       /* ignore timeout here */
-               } else if (ret == -2) {
-                       /* Abandon TX */
-                       mpc8xx_udc_flush_tx_fifo (ep);
-                       return -1;
-               }
-
-               tx_cbdp = (cbd_t *) (endpoints[ep]->tbptr + CFG_IMMR);
-               while (tx_cbdp->cbd_sc & TX_BD_R) {
-               };
-               tx_cbdp->cbd_sc = (tx_cbdp->cbd_sc & TX_BD_W);
-
-               pkt_len = urb->actual_length - epi->sent;
-
-               if (pkt_len > epi->tx_packetSize || pkt_len > EP_MAX_PKT) {
-                       pkt_len = MIN (epi->tx_packetSize, EP_MAX_PKT);
-               }
-
-               for (x = 0; x < pkt_len; x++) {
-                       *((unsigned char *) (tx_cbdp->cbd_bufaddr + x)) =
-                               urb->buffer[epi->sent + x];
-               }
-               tx_cbdp->cbd_datlen = pkt_len;
-               tx_cbdp->cbd_sc |= (CBD_TX_BITMASK | ep_ref[ep].pid);
-               __asm__ ("eieio");
-
-#ifdef __SIMULATE_ERROR__
-               if (++err_poison_test == 2) {
-                       err_poison_test = 0;
-                       tx_cbdp->cbd_sc &= ~TX_BD_TC;
-               }
-#endif
-
-               usbp->uscom = (USCOM_STR | ep);
-
-               while (!(usbp->usber & USB_E_TXB)) {
-                       ret = mpc8xx_udc_tx_irq (ep);
-                       if (ret == -1) {
-                               /* TX timeout */
-                               break;
-                       } else if (ret == -2) {
-                               if (usbp->usber & USB_E_TXB) {
-                                       usbp->usber |= USB_E_TXB;
-                               }
-                               mpc8xx_udc_flush_tx_fifo (ep);
-                               return -1;
-                       }
-               };
-
-               if (usbp->usber & USB_E_TXB) {
-                       usbp->usber |= USB_E_TXB;
-               }
-
-               /* ACK must be present <= 18bit times from TX */
-               if (ret == -1) {
-                       continue;
-               }
-
-               /* TX ACK : USB 2.0 8.7.2, Toggle PID, Advance TX */
-               epi->sent += pkt_len;
-               epi->last = MIN (urb->actual_length - epi->sent, epi->tx_packetSize);
-               TOGGLE_TX_PID (ep_ref[ep].pid);
-
-               if (epi->sent >= epi->tx_urb->actual_length) {
-
-                       epi->tx_urb->actual_length = 0;
-                       epi->sent = 0;
-
-                       if (ep_ref[ep].sc & EP_SEND_ZLP) {
-                               ep_ref[ep].sc &= ~EP_SEND_ZLP;
-                       } else {
-                               return 0;
-                       }
-               }
-       }
-
-       ERR ("TX fail, endpoint 0x%x tx bytes 0x%x/0x%x\n", ep, epi->sent,
-            epi->tx_urb->actual_length);
-
-       return -1;
-}
-
-/* mpc8xx_udc_dump_request
- *
- * Dump a control request to console
- */
-static void mpc8xx_udc_dump_request (struct usb_device_request *request)
-{
-       DBG ("bmRequestType:%02x bRequest:%02x wValue:%04x "
-            "wIndex:%04x wLength:%04x ?\n",
-            request->bmRequestType,
-            request->bRequest,
-            request->wValue, request->wIndex, request->wLength);
-
-       return;
-}
-
-/* mpc8xx_udc_ep0_rx_setup
- *
- * Decode received ep0 SETUP packet. return non-zero on error
- */
-static int mpc8xx_udc_ep0_rx_setup (volatile cbd_t * rx_cbdp)
-{
-       unsigned int x = 0;
-       struct urb *purb = ep_ref[0].urb;
-       struct usb_endpoint_instance *epi =
-               &udc_device->bus->endpoint_array[0];
-
-       for (; x < rx_cbdp->cbd_datlen; x++) {
-               *(((unsigned char *) &ep_ref[0].urb->device_request) + x) =
-                       *((unsigned char *) (rx_cbdp->cbd_bufaddr + x));
-       }
-
-       mpc8xx_udc_clear_rxbd (rx_cbdp);
-
-       if (ep0_recv_setup (purb)) {
-               mpc8xx_udc_dump_request (&purb->device_request);
-               return -1;
-       }
-
-       if ((purb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK)
-           == USB_REQ_HOST2DEVICE) {
-
-               switch (purb->device_request.bRequest) {
-               case USB_REQ_SET_ADDRESS:
-                       /* Send the Status OUT ZLP */
-                       ep_ref[0].pid = TX_BD_PID_DATA1;
-                       purb->actual_length = 0;
-                       mpc8xx_udc_init_tx (epi, purb);
-                       mpc8xx_udc_ep_tx (epi);
-
-                       /* Move to the addressed state */
-                       usbp->usaddr = udc_device->address;
-                       mpc8xx_udc_state_transition_up (udc_device->device_state,
-                                                       STATE_ADDRESSED);
-                       return 0;
-
-               case USB_REQ_SET_CONFIGURATION:
-                       if (!purb->device_request.wValue) {
-                               /* Respond at default address */
-                               usbp->usaddr = 0x00;
-                               mpc8xx_udc_state_transition_down (udc_device->device_state,
-                                                                 STATE_ADDRESSED);
-                       } else {
-                               /* TODO: Support multiple configurations */
-                               mpc8xx_udc_state_transition_up (udc_device->device_state,
-                                                               STATE_CONFIGURED);
-                               for (x = 1; x < MAX_ENDPOINTS; x++) {
-                                       if ((udc_device->bus->endpoint_array[x].endpoint_address & USB_ENDPOINT_DIR_MASK)
-                                           == USB_DIR_IN) {
-                                               ep_ref[x].pid = TX_BD_PID_DATA0;
-                                       } else {
-                                               ep_ref[x].pid = RX_BD_PID_DATA0;
-                                       }
-                                       /* Set configuration must unstall endpoints */
-                                       usbp->usep[x] &= ~STALL_BITMASK;
-                               }
-                       }
-                       break;
-               default:
-                       /* CDC/Vendor specific */
-                       break;
-               }
-
-               /* Send ZLP as ACK in Status OUT phase */
-               ep_ref[0].pid = TX_BD_PID_DATA1;
-               purb->actual_length = 0;
-               mpc8xx_udc_init_tx (epi, purb);
-               mpc8xx_udc_ep_tx (epi);
-
-       } else {
-
-               if (purb->actual_length) {
-                       ep_ref[0].pid = TX_BD_PID_DATA1;
-                       mpc8xx_udc_init_tx (epi, purb);
-
-                       if (!(purb->actual_length % EP0_MAX_PACKET_SIZE)) {
-                               ep_ref[0].sc |= EP_SEND_ZLP;
-                       }
-
-                       if (purb->device_request.wValue ==
-                           USB_DESCRIPTOR_TYPE_DEVICE) {
-                               if (le16_to_cpu (purb->device_request.wLength)
-                                   > purb->actual_length) {
-                                       /* Send EP0_MAX_PACKET_SIZE bytes
-                                        * unless correct size requested.
-                                        */
-                                       if (purb->actual_length > epi->tx_packetSize) {
-                                               purb->actual_length = epi->tx_packetSize;
-                                       }
-                               }
-                       }
-                       mpc8xx_udc_ep_tx (epi);
-
-               } else {
-                       /* Corrupt SETUP packet? */
-                       ERR ("Zero length data or SETUP with DATA-IN phase ?\n");
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-/* mpc8xx_udc_init_tx
- *
- * Setup some basic parameters for a TX transaction
- */
-static void mpc8xx_udc_init_tx (struct usb_endpoint_instance *epi,
-                               struct urb *tx_urb)
-{
-       epi->sent = 0;
-       epi->last = 0;
-       epi->tx_urb = tx_urb;
-}
-
-/* mpc8xx_udc_ep0_rx
- *
- * Receive ep0/control USB data. Parse and possibly send a response.
- */
-static void mpc8xx_udc_ep0_rx (volatile cbd_t * rx_cbdp)
-{
-       if (rx_cbdp->cbd_sc & RX_BD_PID_SETUP) {
-
-               /* Unconditionally accept SETUP packets */
-               if (mpc8xx_udc_ep0_rx_setup (rx_cbdp)) {
-                       mpc8xx_udc_stall (0);
-               }
-
-       } else {
-
-               mpc8xx_udc_clear_rxbd (rx_cbdp);
-
-               if ((rx_cbdp->cbd_datlen - 2)) {
-                       /* SETUP with a DATA phase
-                        * outside of SETUP packet.
-                        * Reply with STALL.
-                        */
-                       mpc8xx_udc_stall (0);
-               }
-       }
-}
-
-/* mpc8xx_udc_epn_rx
- *
- * Receive some data from cbd into USB system urb data abstraction
- * Upper layers should NAK if there is insufficient RX data space
- */
-static int mpc8xx_udc_epn_rx (unsigned int epid, volatile cbd_t * rx_cbdp)
-{
-       struct usb_endpoint_instance *epi = 0;
-       struct urb *urb = 0;
-       unsigned int x = 0;
-
-       if (epid >= MAX_ENDPOINTS || !rx_cbdp->cbd_datlen) {
-               return 0;
-       }
-
-       /* USB 2.0 PDF section 8.6.4
-        * Discard data with invalid PID it is a resend.
-        */
-       if (ep_ref[epid].pid != (rx_cbdp->cbd_sc & 0xC0)) {
-               return 1;
-       }
-       TOGGLE_RX_PID (ep_ref[epid].pid);
-
-       epi = &udc_device->bus->endpoint_array[epid];
-       urb = epi->rcv_urb;
-
-       for (; x < (rx_cbdp->cbd_datlen - 2); x++) {
-               *((unsigned char *) (urb->buffer + urb->actual_length + x)) =
-                       *((unsigned char *) (rx_cbdp->cbd_bufaddr + x));
-       }
-
-       if (x) {
-               usbd_rcv_complete (epi, x, 0);
-               if (ep_ref[epid].urb->status == RECV_ERROR) {
-                       DBG ("RX error unset NAK\n");
-                       udc_unset_nak (epid);
-               }
-       }
-       return x;
-}
-
-/* mpc8xx_udc_clock_init
- *
- * Obtain a clock reference for Full Speed Signaling
- */
-static void mpc8xx_udc_clock_init (volatile immap_t * immr,
-                                  volatile cpm8xx_t * cp)
-{
-
-#if defined(CFG_USB_EXTC_CLK)
-
-       /* This has been tested with a 48MHz crystal on CLK6 */
-       switch (CFG_USB_EXTC_CLK) {
-       case 1:
-               immr->im_ioport.iop_papar |= 0x0100;
-               immr->im_ioport.iop_padir &= ~0x0100;
-               cp->cp_sicr |= 0x24;
-               break;
-       case 2:
-               immr->im_ioport.iop_papar |= 0x0200;
-               immr->im_ioport.iop_padir &= ~0x0200;
-               cp->cp_sicr |= 0x2D;
-               break;
-       case 3:
-               immr->im_ioport.iop_papar |= 0x0400;
-               immr->im_ioport.iop_padir &= ~0x0400;
-               cp->cp_sicr |= 0x36;
-               break;
-       case 4:
-               immr->im_ioport.iop_papar |= 0x0800;
-               immr->im_ioport.iop_padir &= ~0x0800;
-               cp->cp_sicr |= 0x3F;
-               break;
-       default:
-               udc_state = STATE_ERROR;
-               break;
-       }
-
-#elif defined(CFG_USB_BRGCLK)
-
-       /* This has been tested with brgclk == 50MHz */
-       int divisor = 0;
-
-       if (gd->cpu_clk < 48000000L) {
-               ERR ("brgclk is too slow for full-speed USB!\n");
-               udc_state = STATE_ERROR;
-               return;
-       }
-
-       /* Assume the brgclk is 'good enough', we want !(gd->cpu_clk%48Mhz)
-        * but, can /probably/ live with close-ish alternative rates.
-        */
-       divisor = (gd->cpu_clk / 48000000L) - 1;
-       cp->cp_sicr &= ~0x0000003F;
-
-       switch (CFG_USB_BRGCLK) {
-       case 1:
-               cp->cp_brgc1 |= (divisor | CPM_BRG_EN);
-               cp->cp_sicr &= ~0x2F;
-               break;
-       case 2:
-               cp->cp_brgc2 |= (divisor | CPM_BRG_EN);
-               cp->cp_sicr |= 0x00000009;
-               break;
-       case 3:
-               cp->cp_brgc3 |= (divisor | CPM_BRG_EN);
-               cp->cp_sicr |= 0x00000012;
-               break;
-       case 4:
-               cp->cp_brgc4 = (divisor | CPM_BRG_EN);
-               cp->cp_sicr |= 0x0000001B;
-               break;
-       default:
-               udc_state = STATE_ERROR;
-               break;
-       }
-
-#else
-#error "CFG_USB_EXTC_CLK or CFG_USB_BRGCLK must be defined"
-#endif
-
-}
-
-/* mpc8xx_udc_cbd_attach
- *
- * attach a cbd to and endpoint
- */
-static void mpc8xx_udc_cbd_attach (int ep, uchar tx_size, uchar rx_size)
-{
-
-       if (!tx_cbd[ep] || !rx_cbd[ep] || ep >= MAX_ENDPOINTS) {
-               udc_state = STATE_ERROR;
-               return;
-       }
-
-       if (tx_size > USB_MAX_PKT || rx_size > USB_MAX_PKT ||
-           (!tx_size && !rx_size)) {
-               udc_state = STATE_ERROR;
-               return;
-       }
-
-       /* Attach CBD to appropiate Parameter RAM Endpoint data structure */
-       if (rx_size) {
-               endpoints[ep]->rbase = (u32) rx_cbd[rx_ct];
-               endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
-               rx_ct++;
-
-               if (!ep) {
-
-                       endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
-                       rx_cbd[rx_ct]->cbd_sc |= RX_BD_W;
-                       rx_ct++;
-
-               } else {
-                       rx_ct += 2;
-                       endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
-                       rx_cbd[rx_ct]->cbd_sc |= RX_BD_W;
-                       rx_ct++;
-               }
-
-               /* Where we expect to RX data on this endpoint */
-               ep_ref[ep].prx = rx_cbd[rx_ct - 1];
-       } else {
-
-               ep_ref[ep].prx = 0;
-               endpoints[ep]->rbase = 0;
-               endpoints[ep]->rbptr = 0;
-       }
-
-       if (tx_size) {
-               endpoints[ep]->tbase = (u32) tx_cbd[tx_ct];
-               endpoints[ep]->tbptr = (u32) tx_cbd[tx_ct];
-               tx_ct++;
-       } else {
-               endpoints[ep]->tbase = 0;
-               endpoints[ep]->tbptr = 0;
-       }
-
-       endpoints[ep]->tstate = 0;
-       endpoints[ep]->tbcnt = 0;
-       endpoints[ep]->mrblr = EP_MAX_PKT;
-       endpoints[ep]->rfcr = 0x18;
-       endpoints[ep]->tfcr = 0x18;
-       ep_ref[ep].sc |= EP_ATTACHED;
-
-       DBG ("ep %d rbase 0x%08x rbptr 0x%08x tbase 0x%08x tbptr 0x%08x prx = %p\n",
-               ep, endpoints[ep]->rbase, endpoints[ep]->rbptr,
-               endpoints[ep]->tbase, endpoints[ep]->tbptr,
-               ep_ref[ep].prx);
-
-       return;
-}
-
-/* mpc8xx_udc_cbd_init
- *
- * Allocate space for a cbd and allocate TX/RX data space
- */
-static void mpc8xx_udc_cbd_init (void)
-{
-       int i = 0;
-
-       for (; i < TX_RING_SIZE; i++) {
-               tx_cbd[i] = (cbd_t *)
-                       mpc8xx_udc_alloc (sizeof (cbd_t), sizeof (int));
-       }
-
-       for (i = 0; i < RX_RING_SIZE; i++) {
-               rx_cbd[i] = (cbd_t *)
-                       mpc8xx_udc_alloc (sizeof (cbd_t), sizeof (int));
-       }
-
-       for (i = 0; i < TX_RING_SIZE; i++) {
-               tx_cbd[i]->cbd_bufaddr =
-                       mpc8xx_udc_alloc (EP_MAX_PKT, sizeof (int));
-
-               tx_cbd[i]->cbd_sc = (TX_BD_I | TX_BD_W);
-               tx_cbd[i]->cbd_datlen = 0x0000;
-       }
-
-
-       for (i = 0; i < RX_RING_SIZE; i++) {
-               rx_cbd[i]->cbd_bufaddr =
-                       mpc8xx_udc_alloc (EP_MAX_PKT, sizeof (int));
-               rx_cbd[i]->cbd_sc = (RX_BD_I | RX_BD_E);
-               rx_cbd[i]->cbd_datlen = 0x0000;
-
-       }
-
-       return;
-}
-
-/* mpc8xx_udc_endpoint_init
- *
- * Attach an endpoint to some dpram
- */
-static void mpc8xx_udc_endpoint_init (void)
-{
-       int i = 0;
-
-       for (; i < MAX_ENDPOINTS; i++) {
-               endpoints[i] = (usb_epb_t *)
-                       mpc8xx_udc_alloc (sizeof (usb_epb_t), 32);
-       }
-}
-
-/* mpc8xx_udc_alloc
- *
- * Grab the address of some dpram
- */
-static u32 mpc8xx_udc_alloc (u32 data_size, u32 alignment)
-{
-       u32 retaddr = address_base;
-
-       while (retaddr % alignment) {
-               retaddr++;
-       }
-       address_base += data_size;
-
-       return retaddr;
-}
-
-#endif /* CONFIG_MPC885_FAMILY && CONFIG_USB_DEVICE) */
diff --git a/drivers/usbdcore_omap1510.c b/drivers/usbdcore_omap1510.c
deleted file mode 100644 (file)
index 84bb936..0000000
+++ /dev/null
@@ -1,1547 +0,0 @@
-/*
- * (C) Copyright 2003
- * Gerry Hamel, geh@ti.com, Texas Instruments
- *
- * Based on
- * linux/drivers/usb/device/bi/omap.c
- * TI OMAP1510 USB bus interface driver
- *
- * Author: MontaVista Software, Inc.
- *        source@mvista.com
- *        (C) Copyright 2002
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307         USA
- *
- */
-
-#include <common.h>
-
-#if defined(CONFIG_OMAP1510) && defined(CONFIG_USB_DEVICE)
-
-#include <asm/io.h>
-#ifdef CONFIG_OMAP_SX1
-#include <i2c.h>
-#endif
-
-#include "usbdcore.h"
-#include "usbdcore_omap1510.h"
-#include "usbdcore_ep0.h"
-
-
-#define UDC_INIT_MDELAY                     80 /* Device settle delay */
-#define UDC_MAX_ENDPOINTS           31 /* Number of endpoints on this UDC */
-
-/* Some kind of debugging output... */
-#if 1
-#define UDCDBG(str)
-#define UDCDBGA(fmt,args...)
-#else  /* The bugs still exists... */
-#define UDCDBG(str) serial_printf("[%s] %s:%d: " str "\n", __FILE__,__FUNCTION__,__LINE__)
-#define UDCDBGA(fmt,args...) serial_printf("[%s] %s:%d: " fmt "\n", __FILE__,__FUNCTION__,__LINE__, ##args)
-#endif
-
-#if 1
-#define UDCREG(name)
-#define UDCREGL(name)
-#else  /* The bugs still exists... */
-#define UDCREG(name)    serial_printf("%s():%d: %s[%08x]=%.4x\n",__FUNCTION__,__LINE__, (#name), name, inw(name))      /* For 16-bit regs */
-#define UDCREGL(name)   serial_printf("%s():%d: %s[%08x]=%.8x\n",__FUNCTION__,__LINE__, (#name), name, inl(name))      /* For 32-bit regs */
-#endif
-
-
-static struct urb *ep0_urb = NULL;
-
-static struct usb_device_instance *udc_device; /* Used in interrupt handler */
-static u16 udc_devstat = 0;    /* UDC status (DEVSTAT) */
-static u32 udc_interrupts = 0;
-
-static void udc_stall_ep (unsigned int ep_addr);
-
-
-static struct usb_endpoint_instance *omap1510_find_ep (int ep)
-{
-       int i;
-
-       for (i = 0; i < udc_device->bus->max_endpoints; i++) {
-               if (udc_device->bus->endpoint_array[i].endpoint_address == ep)
-                       return &udc_device->bus->endpoint_array[i];
-       }
-       return NULL;
-}
-
-/* ************************************************************************** */
-/* IO
- */
-
-/*
- * omap1510_prepare_endpoint_for_rx
- *
- * This function implements TRM Figure 14-11.
- *
- * The endpoint to prepare for transfer is specified as a physical endpoint
- * number.  For OUT (rx) endpoints 1 through 15, the corresponding endpoint
- * configuration register is checked to see if the endpoint is ISO or not.
- * If the OUT endpoint is valid and is non-ISO then its FIFO is enabled.
- * No action is taken for endpoint 0 or for IN (tx) endpoints 16 through 30.
- */
-static void omap1510_prepare_endpoint_for_rx (int ep_addr)
-{
-       int ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;
-
-       UDCDBGA ("omap1510_prepare_endpoint %x", ep_addr);
-       if (((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)) {
-               if ((inw (UDC_EP_RX (ep_num)) &
-                    (UDC_EPn_RX_Valid | UDC_EPn_RX_Iso)) ==
-                   UDC_EPn_RX_Valid) {
-                       /* rx endpoint is valid, non-ISO, so enable its FIFO */
-                       outw (UDC_EP_Sel | ep_num, UDC_EP_NUM);
-                       outw (UDC_Set_FIFO_En, UDC_CTRL);
-                       outw (0, UDC_EP_NUM);
-               }
-       }
-}
-
-/* omap1510_configure_endpoints
- *
- * This function implements TRM Figure 14-10.
- */
-static void omap1510_configure_endpoints (struct usb_device_instance *device)
-{
-       int ep;
-       struct usb_bus_instance *bus;
-       struct usb_endpoint_instance *endpoint;
-       unsigned short ep_ptr;
-       unsigned short ep_size;
-       unsigned short ep_isoc;
-       unsigned short ep_doublebuffer;
-       int ep_addr;
-       int packet_size;
-       int buffer_size;
-       int attributes;
-
-       bus = device->bus;
-
-       /* There is a dedicated 2048 byte buffer for USB packets that may be
-        * arbitrarily partitioned among the endpoints on 8-byte boundaries.
-        * The first 8 bytes are reserved for receiving setup packets on
-        * endpoint 0.
-        */
-       ep_ptr = 8;             /* reserve the first 8 bytes for the setup fifo */
-
-       for (ep = 0; ep < bus->max_endpoints; ep++) {
-               endpoint = bus->endpoint_array + ep;
-               ep_addr = endpoint->endpoint_address;
-               if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
-                       /* IN endpoint */
-                       packet_size = endpoint->tx_packetSize;
-                       attributes = endpoint->tx_attributes;
-               } else {
-                       /* OUT endpoint */
-                       packet_size = endpoint->rcv_packetSize;
-                       attributes = endpoint->rcv_attributes;
-               }
-
-               switch (packet_size) {
-               case 0:
-                       ep_size = 0;
-                       break;
-               case 8:
-                       ep_size = 0;
-                       break;
-               case 16:
-                       ep_size = 1;
-                       break;
-               case 32:
-                       ep_size = 2;
-                       break;
-               case 64:
-                       ep_size = 3;
-                       break;
-               case 128:
-                       ep_size = 4;
-                       break;
-               case 256:
-                       ep_size = 5;
-                       break;
-               case 512:
-                       ep_size = 6;
-                       break;
-               default:
-                       UDCDBGA ("ep 0x%02x has bad packet size %d",
-                                ep_addr, packet_size);
-                       packet_size = 0;
-                       ep_size = 0;
-                       break;
-               }
-
-               switch (attributes & USB_ENDPOINT_XFERTYPE_MASK) {
-               case USB_ENDPOINT_XFER_CONTROL:
-               case USB_ENDPOINT_XFER_BULK:
-               case USB_ENDPOINT_XFER_INT:
-               default:
-                       /* A non-isochronous endpoint may optionally be
-                        * double-buffered. For now we disable
-                        * double-buffering.
-                        */
-                       ep_doublebuffer = 0;
-                       ep_isoc = 0;
-                       if (packet_size > 64)
-                               packet_size = 0;
-                       if (!ep || !ep_doublebuffer)
-                               buffer_size = packet_size;
-                       else
-                               buffer_size = packet_size * 2;
-                       break;
-               case USB_ENDPOINT_XFER_ISOC:
-                       /* Isochronous endpoints are always double-
-                        * buffered, but the double-buffering bit
-                        * in the endpoint configuration register
-                        * becomes the msb of the endpoint size so we
-                        * set the double-buffering flag to zero.
-                        */
-                       ep_doublebuffer = 0;
-                       ep_isoc = 1;
-                       buffer_size = packet_size * 2;
-                       break;
-               }
-
-               /* check to see if our packet buffer RAM is exhausted */
-               if ((ep_ptr + buffer_size) > 2048) {
-                       UDCDBGA ("out of packet RAM for ep 0x%02x buf size %d", ep_addr, buffer_size);
-                       buffer_size = packet_size = 0;
-               }
-
-               /* force a default configuration for endpoint 0 since it is
-                * always enabled
-                */
-               if (!ep && ((packet_size < 8) || (packet_size > 64))) {
-                       buffer_size = packet_size = 64;
-                       ep_size = 3;
-               }
-
-               if (!ep) {
-                       /* configure endpoint 0 */
-                       outw ((ep_size << 12) | (ep_ptr >> 3), UDC_EP0);
-                       /*UDCDBGA("ep 0 buffer offset 0x%03x packet size 0x%03x", */
-                       /*      ep_ptr, packet_size); */
-               } else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
-                       /* IN endpoint */
-                       if (packet_size) {
-                               outw ((1 << 15) | (ep_doublebuffer << 14) |
-                                     (ep_size << 12) | (ep_isoc << 11) |
-                                     (ep_ptr >> 3),
-                                     UDC_EP_TX (ep_addr &
-                                                USB_ENDPOINT_NUMBER_MASK));
-                               UDCDBGA ("IN ep %d buffer offset 0x%03x"
-                                        " packet size 0x%03x",
-                                        ep_addr & USB_ENDPOINT_NUMBER_MASK,
-                                        ep_ptr, packet_size);
-                       } else {
-                               outw (0,
-                                     UDC_EP_TX (ep_addr &
-                                                USB_ENDPOINT_NUMBER_MASK));
-                       }
-               } else {
-                       /* OUT endpoint */
-                       if (packet_size) {
-                               outw ((1 << 15) | (ep_doublebuffer << 14) |
-                                     (ep_size << 12) | (ep_isoc << 11) |
-                                     (ep_ptr >> 3),
-                                     UDC_EP_RX (ep_addr &
-                                                USB_ENDPOINT_NUMBER_MASK));
-                               UDCDBGA ("OUT ep %d buffer offset 0x%03x"
-                                        " packet size 0x%03x",
-                                        ep_addr & USB_ENDPOINT_NUMBER_MASK,
-                                        ep_ptr, packet_size);
-                       } else {
-                               outw (0,
-                                     UDC_EP_RX (ep_addr &
-                                                USB_ENDPOINT_NUMBER_MASK));
-                       }
-               }
-               ep_ptr += buffer_size;
-       }
-}
-
-/* omap1510_deconfigure_device
- *
- * This function balances omap1510_configure_device.
- */
-static void omap1510_deconfigure_device (void)
-{
-       int epnum;
-
-       UDCDBG ("clear Cfg_Lock");
-       outw (inw (UDC_SYSCON1) & ~UDC_Cfg_Lock, UDC_SYSCON1);
-       UDCREG (UDC_SYSCON1);
-
-       /* deconfigure all endpoints */
-       for (epnum = 1; epnum <= 15; epnum++) {
-               outw (0, UDC_EP_RX (epnum));
-               outw (0, UDC_EP_TX (epnum));
-       }
-}
-
-/* omap1510_configure_device
- *
- * This function implements TRM Figure 14-9.
- */
-static void omap1510_configure_device (struct usb_device_instance *device)
-{
-       omap1510_configure_endpoints (device);
-
-
-       /* Figure 14-9 indicates we should enable interrupts here, but we have
-        * other routines (udc_all_interrupts, udc_suspended_interrupts) to
-        * do that.
-        */
-
-       UDCDBG ("set Cfg_Lock");
-       outw (inw (UDC_SYSCON1) | UDC_Cfg_Lock, UDC_SYSCON1);
-       UDCREG (UDC_SYSCON1);
-}
-
-/* omap1510_write_noniso_tx_fifo
- *
- * This function implements TRM Figure 14-30.
- *
- * If the endpoint has an active tx_urb, then the next packet of data from the
- * URB is written to the tx FIFO.  The total amount of data in the urb is given
- * by urb->actual_length.  The maximum amount of data that can be sent in any
- * one packet is given by endpoint->tx_packetSize.  The number of data bytes
- * from this URB that have already been transmitted is given by endpoint->sent.
- * endpoint->last is updated by this routine with the number of data bytes
- * transmitted in this packet.
- *
- * In accordance with Figure 14-30, the EP_NUM register must already have been
- * written with the value to select the appropriate tx FIFO before this routine
- * is called.
- */
-static void omap1510_write_noniso_tx_fifo (struct usb_endpoint_instance
-                                          *endpoint)
-{
-       struct urb *urb = endpoint->tx_urb;
-
-       if (urb) {
-               unsigned int last, i;
-
-               UDCDBGA ("urb->buffer %p, buffer_length %d, actual_length %d",
-                        urb->buffer, urb->buffer_length, urb->actual_length);
-               if ((last =
-                    MIN (urb->actual_length - endpoint->sent,
-                         endpoint->tx_packetSize))) {
-                       u8 *cp = urb->buffer + endpoint->sent;
-
-                       UDCDBGA ("endpoint->sent %d, tx_packetSize %d, last %d", endpoint->sent, endpoint->tx_packetSize, last);
-
-                       if (((u32) cp & 1) == 0) {      /* word aligned? */
-                               outsw (UDC_DATA, cp, last >> 1);
-                       } else {        /* byte aligned. */
-                               for (i = 0; i < (last >> 1); i++) {
-                                       u16 w = ((u16) cp[2 * i + 1] << 8) |
-                                               (u16) cp[2 * i];
-                                       outw (w, UDC_DATA);
-                               }
-                       }
-                       if (last & 1) {
-                               outb (*(cp + last - 1), UDC_DATA);
-                       }
-               }
-               endpoint->last = last;
-       }
-}
-
-/* omap1510_read_noniso_rx_fifo
- *
- * This function implements TRM Figure 14-28.
- *
- * If the endpoint has an active rcv_urb, then the next packet of data is read
- * from the rcv FIFO and written to rcv_urb->buffer at offset
- * rcv_urb->actual_length to append the packet data to the data from any
- * previous packets for this transfer. We assume that there is sufficient room
- * left in the buffer to hold an entire packet of data.
- *
- * The return value is the number of bytes read from the FIFO for this packet.
- *
- * In accordance with Figure 14-28, the EP_NUM register must already have been
- * written with the value to select the appropriate rcv FIFO before this routine
- * is called.
- */
-static int omap1510_read_noniso_rx_fifo (struct usb_endpoint_instance
-                                        *endpoint)
-{
-       struct urb *urb = endpoint->rcv_urb;
-       int len = 0;
-
-       if (urb) {
-               len = inw (UDC_RXFSTAT);
-
-               if (len) {
-                       unsigned char *cp = urb->buffer + urb->actual_length;
-
-                       insw (UDC_DATA, cp, len >> 1);
-                       if (len & 1)
-                               *(cp + len - 1) = inb (UDC_DATA);
-               }
-       }
-       return len;
-}
-
-/* omap1510_prepare_for_control_write_status
- *
- * This function implements TRM Figure 14-17.
- *
- * We have to deal here with non-autodecoded control writes that haven't already
- * been dealt with by ep0_recv_setup.  The non-autodecoded standard control
- * write requests are: set/clear endpoint feature, set configuration, set
- * interface, and set descriptor.  ep0_recv_setup handles set/clear requests for
- * ENDPOINT_HALT by halting the endpoint for a set request and resetting the
- * endpoint for a clear request.  ep0_recv_setup returns an error for
- * SET_DESCRIPTOR requests which causes them to be terminated with a stall by
- * the setup handler.  A SET_INTERFACE request is handled by ep0_recv_setup by
- * generating a DEVICE_SET_INTERFACE event.  This leaves only the
- * SET_CONFIGURATION event for us to deal with here.
- *
- */
-static void omap1510_prepare_for_control_write_status (struct urb *urb)
-{
-       struct usb_device_request *request = &urb->device_request;;
-
-       /* check for a SET_CONFIGURATION request */
-       if (request->bRequest == USB_REQ_SET_CONFIGURATION) {
-               int configuration = le16_to_cpu (request->wValue) & 0xff;
-               unsigned short devstat = inw (UDC_DEVSTAT);
-
-               if ((devstat & (UDC_ADD | UDC_CFG)) == UDC_ADD) {
-                       /* device is currently in ADDRESSED state */
-                       if (configuration) {
-                               /* Assume the specified non-zero configuration
-                                * value is valid and switch to the CONFIGURED
-                                * state.
-                                */
-                               outw (UDC_Dev_Cfg, UDC_SYSCON2);
-                       }
-               } else if ((devstat & UDC_CFG) == UDC_CFG) {
-                       /* device is currently in CONFIGURED state */
-                       if (!configuration) {
-                               /* Switch to ADDRESSED state. */
-                               outw (UDC_Clr_Cfg, UDC_SYSCON2);
-                       }
-               }
-       }
-
-       /* select EP0 tx FIFO */
-       outw (UDC_EP_Dir | UDC_EP_Sel, UDC_EP_NUM);
-       /* clear endpoint (no data bytes in status stage) */
-       outw (UDC_Clr_EP, UDC_CTRL);
-       /* enable the EP0 tx FIFO */
-       outw (UDC_Set_FIFO_En, UDC_CTRL);
-       /* deselect the endpoint */
-       outw (UDC_EP_Dir, UDC_EP_NUM);
-}
-
-/* udc_state_transition_up
- * udc_state_transition_down
- *
- * Helper functions to implement device state changes. The device states and
- * the events that transition between them are:
- *
- *                             STATE_ATTACHED
- *                             ||      /\
- *                             \/      ||
- *     DEVICE_HUB_CONFIGURED                   DEVICE_HUB_RESET
- *                             ||      /\
- *                             \/      ||
- *                             STATE_POWERED
- *                             ||      /\
- *                             \/      ||
- *     DEVICE_RESET                            DEVICE_POWER_INTERRUPTION
- *                             ||      /\
- *                             \/      ||
- *                             STATE_DEFAULT
- *                             ||      /\
- *                             \/      ||
- *     DEVICE_ADDRESS_ASSIGNED                 DEVICE_RESET
- *                             ||      /\
- *                             \/      ||
- *                             STATE_ADDRESSED
- *                             ||      /\
- *                             \/      ||
- *     DEVICE_CONFIGURED                       DEVICE_DE_CONFIGURED
- *                             ||      /\
- *                             \/      ||
- *                             STATE_CONFIGURED
- *
- * udc_state_transition_up transitions up (in the direction from STATE_ATTACHED
- * to STATE_CONFIGURED) from the specified initial state to the specified final
- * state, passing through each intermediate state on the way.  If the initial
- * state is at or above (i.e. nearer to STATE_CONFIGURED) the final state, then
- * no state transitions will take place.
- *
- * udc_state_transition_down transitions down (in the direction from
- * STATE_CONFIGURED to STATE_ATTACHED) from the specified initial state to the
- * specified final state, passing through each intermediate state on the way.
- * If the initial state is at or below (i.e. nearer to STATE_ATTACHED) the final
- * state, then no state transitions will take place.
- *
- * These functions must only be called with interrupts disabled.
- */
-static void udc_state_transition_up (usb_device_state_t initial,
-                                    usb_device_state_t final)
-{
-       if (initial < final) {
-               switch (initial) {
-               case STATE_ATTACHED:
-                       usbd_device_event_irq (udc_device,
-                                              DEVICE_HUB_CONFIGURED, 0);
-                       if (final == STATE_POWERED)
-                               break;
-               case STATE_POWERED:
-                       usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
-                       if (final == STATE_DEFAULT)
-                               break;
-               case STATE_DEFAULT:
-                       usbd_device_event_irq (udc_device,
-                                              DEVICE_ADDRESS_ASSIGNED, 0);
-                       if (final == STATE_ADDRESSED)
-                               break;
-               case STATE_ADDRESSED:
-                       usbd_device_event_irq (udc_device, DEVICE_CONFIGURED,
-                                              0);
-               case STATE_CONFIGURED:
-                       break;
-               default:
-                       break;
-               }
-       }
-}
-
-static void udc_state_transition_down (usb_device_state_t initial,
-                                      usb_device_state_t final)
-{
-       if (initial > final) {
-               switch (initial) {
-               case STATE_CONFIGURED:
-                       usbd_device_event_irq (udc_device, DEVICE_DE_CONFIGURED, 0);
-                       if (final == STATE_ADDRESSED)
-                               break;
-               case STATE_ADDRESSED:
-                       usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
-                       if (final == STATE_DEFAULT)
-                               break;
-               case STATE_DEFAULT:
-                       usbd_device_event_irq (udc_device, DEVICE_POWER_INTERRUPTION, 0);
-                       if (final == STATE_POWERED)
-                               break;
-               case STATE_POWERED:
-                       usbd_device_event_irq (udc_device, DEVICE_HUB_RESET, 0);
-               case STATE_ATTACHED:
-                       break;
-               default:
-                       break;
-               }
-       }
-}
-
-/* Handle all device state changes.
- * This function implements TRM Figure 14-21.
- */
-static void omap1510_udc_state_changed (void)
-{
-       u16 bits;
-       u16 devstat = inw (UDC_DEVSTAT);
-
-       UDCDBGA ("state changed, devstat %x, old %x", devstat, udc_devstat);
-
-       bits = devstat ^ udc_devstat;
-       if (bits) {
-               if (bits & UDC_ATT) {
-                       if (devstat & UDC_ATT) {
-                               UDCDBG ("device attached and powered");
-                               udc_state_transition_up (udc_device->device_state, STATE_POWERED);
-                       } else {
-                               UDCDBG ("device detached or unpowered");
-                               udc_state_transition_down (udc_device->device_state, STATE_ATTACHED);
-                       }
-               }
-               if (bits & UDC_USB_Reset) {
-                       if (devstat & UDC_USB_Reset) {
-                               UDCDBG ("device reset in progess");
-                               udc_state_transition_down (udc_device->device_state, STATE_POWERED);
-                       } else {
-                               UDCDBG ("device reset completed");
-                       }
-               }
-               if (bits & UDC_DEF) {
-                       if (devstat & UDC_DEF) {
-                               UDCDBG ("device entering default state");
-                               udc_state_transition_up (udc_device->device_state, STATE_DEFAULT);
-                       } else {
-                               UDCDBG ("device leaving default state");
-                               udc_state_transition_down (udc_device->device_state, STATE_POWERED);
-                       }
-               }
-               if (bits & UDC_SUS) {
-                       if (devstat & UDC_SUS) {
-                               UDCDBG ("entering suspended state");
-                               usbd_device_event_irq (udc_device, DEVICE_BUS_INACTIVE, 0);
-                       } else {
-                               UDCDBG ("leaving suspended state");
-                               usbd_device_event_irq (udc_device, DEVICE_BUS_ACTIVITY, 0);
-                       }
-               }
-               if (bits & UDC_R_WK_OK) {
-                       UDCDBGA ("remote wakeup %s", (devstat & UDC_R_WK_OK)
-                                ? "enabled" : "disabled");
-               }
-               if (bits & UDC_ADD) {
-                       if (devstat & UDC_ADD) {
-                               UDCDBG ("default -> addressed");
-                               udc_state_transition_up (udc_device->device_state, STATE_ADDRESSED);
-                       } else {
-                               UDCDBG ("addressed -> default");
-                               udc_state_transition_down (udc_device->device_state, STATE_DEFAULT);
-                       }
-               }
-               if (bits & UDC_CFG) {
-                       if (devstat & UDC_CFG) {
-                               UDCDBG ("device configured");
-                               /* The ep0_recv_setup function generates the
-                                * DEVICE_CONFIGURED event when a
-                                * USB_REQ_SET_CONFIGURATION setup packet is
-                                * received, so we should already be in the
-                                * state STATE_CONFIGURED.
-                                */
-                               udc_state_transition_up (udc_device->device_state, STATE_CONFIGURED);
-                       } else {
-                               UDCDBG ("device deconfigured");
-                               udc_state_transition_down (udc_device->device_state, STATE_ADDRESSED);
-                       }
-               }
-       }
-
-       /* Clear interrupt source */
-       outw (UDC_DS_Chg, UDC_IRQ_SRC);
-
-       /* Save current DEVSTAT */
-       udc_devstat = devstat;
-}
-
-/* Handle SETUP USB interrupt.
- * This function implements TRM Figure 14-14.
- */
-static void omap1510_udc_setup (struct usb_endpoint_instance *endpoint)
-{
-       UDCDBG ("-> Entering device setup");
-
-       do {
-               const int setup_pktsize = 8;
-               unsigned char *datap =
-                       (unsigned char *) &ep0_urb->device_request;
-
-               /* Gain access to EP 0 setup FIFO */
-               outw (UDC_Setup_Sel, UDC_EP_NUM);
-
-               /* Read control request data */
-               insb (UDC_DATA, datap, setup_pktsize);
-
-               UDCDBGA ("EP0 setup read [%x %x %x %x %x %x %x %x]",
-                        *(datap + 0), *(datap + 1), *(datap + 2),
-                        *(datap + 3), *(datap + 4), *(datap + 5),
-                        *(datap + 6), *(datap + 7));
-
-               /* Reset EP0 setup FIFO */
-               outw (0, UDC_EP_NUM);
-       } while (inw (UDC_IRQ_SRC) & UDC_Setup);
-
-       /* Try to process setup packet */
-       if (ep0_recv_setup (ep0_urb)) {
-               /* Not a setup packet, stall next EP0 transaction */
-               udc_stall_ep (0);
-               UDCDBG ("can't parse setup packet, still waiting for setup");
-               return;
-       }
-
-       /* Check direction */
-       if ((ep0_urb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK)
-           == USB_REQ_HOST2DEVICE) {
-               UDCDBG ("control write on EP0");
-               if (le16_to_cpu (ep0_urb->device_request.wLength)) {
-                       /* We don't support control write data stages.
-                        * The only standard control write request with a data
-                        * stage is SET_DESCRIPTOR, and ep0_recv_setup doesn't
-                        * support that so we just stall those requests.  A
-                        * function driver might support a non-standard
-                        * write request with a data stage, but it isn't
-                        * obvious what we would do with the data if we read it
-                        * so we'll just stall it.  It seems like the API isn't
-                        * quite right here.
-                        */
-#if 0
-                       /* Here is what we would do if we did support control
-                        * write data stages.
-                        */
-                       ep0_urb->actual_length = 0;
-                       outw (0, UDC_EP_NUM);
-                       /* enable the EP0 rx FIFO */
-                       outw (UDC_Set_FIFO_En, UDC_CTRL);
-#else
-                       /* Stall this request */
-                       UDCDBG ("Stalling unsupported EP0 control write data "
-                               "stage.");
-                       udc_stall_ep (0);
-#endif
-               } else {
-                       omap1510_prepare_for_control_write_status (ep0_urb);
-               }
-       } else {
-               UDCDBG ("control read on EP0");
-               /* The ep0_recv_setup function has already placed our response
-                * packet data in ep0_urb->buffer and the packet length in
-                * ep0_urb->actual_length.
-                */
-               endpoint->tx_urb = ep0_urb;
-               endpoint->sent = 0;
-               /* select the EP0 tx FIFO */
-               outw (UDC_EP_Dir | UDC_EP_Sel, UDC_EP_NUM);
-               /* Write packet data to the FIFO.  omap1510_write_noniso_tx_fifo
-                * will update endpoint->last with the number of bytes written
-                * to the FIFO.
-                */
-               omap1510_write_noniso_tx_fifo (endpoint);
-               /* enable the FIFO to start the packet transmission */
-               outw (UDC_Set_FIFO_En, UDC_CTRL);
-               /* deselect the EP0 tx FIFO */
-               outw (UDC_EP_Dir, UDC_EP_NUM);
-       }
-
-       UDCDBG ("<- Leaving device setup");
-}
-
-/* Handle endpoint 0 RX interrupt
- * This routine implements TRM Figure 14-16.
- */
-static void omap1510_udc_ep0_rx (struct usb_endpoint_instance *endpoint)
-{
-       unsigned short status;
-
-       UDCDBG ("RX on EP0");
-       /* select EP0 rx FIFO */
-       outw (UDC_EP_Sel, UDC_EP_NUM);
-
-       status = inw (UDC_STAT_FLG);
-
-       if (status & UDC_ACK) {
-               /* Check direction */
-               if ((ep0_urb->device_request.bmRequestType
-                    & USB_REQ_DIRECTION_MASK) == USB_REQ_HOST2DEVICE) {
-                       /* This rx interrupt must be for a control write data
-                        * stage packet.
-                        *
-                        * We don't support control write data stages.
-                        * We should never end up here.
-                        */
-
-                       /* clear the EP0 rx FIFO */
-                       outw (UDC_Clr_EP, UDC_CTRL);
-
-                       /* deselect the EP0 rx FIFO */
-                       outw (0, UDC_EP_NUM);
-
-                       UDCDBG ("Stalling unexpected EP0 control write "
-                               "data stage packet");
-                       udc_stall_ep (0);
-               } else {
-                       /* This rx interrupt must be for a control read status
-                        * stage packet.
-                        */
-                       UDCDBG ("ACK on EP0 control read status stage packet");
-                       /* deselect EP0 rx FIFO */
-                       outw (0, UDC_EP_NUM);
-               }
-       } else if (status & UDC_STALL) {
-               UDCDBG ("EP0 stall during RX");
-               /* deselect EP0 rx FIFO */
-               outw (0, UDC_EP_NUM);
-       } else {
-               /* deselect EP0 rx FIFO */
-               outw (0, UDC_EP_NUM);
-       }
-}
-
-/* Handle endpoint 0 TX interrupt
- * This routine implements TRM Figure 14-18.
- */
-static void omap1510_udc_ep0_tx (struct usb_endpoint_instance *endpoint)
-{
-       unsigned short status;
-       struct usb_device_request *request = &ep0_urb->device_request;
-
-       UDCDBG ("TX on EP0");
-       /* select EP0 TX FIFO */
-       outw (UDC_EP_Dir | UDC_EP_Sel, UDC_EP_NUM);
-
-       status = inw (UDC_STAT_FLG);
-       if (status & UDC_ACK) {
-               /* Check direction */
-               if ((request->bmRequestType & USB_REQ_DIRECTION_MASK) ==
-                   USB_REQ_HOST2DEVICE) {
-                       /* This tx interrupt must be for a control write status
-                        * stage packet.
-                        */
-                       UDCDBG ("ACK on EP0 control write status stage packet");
-                       /* deselect EP0 TX FIFO */
-                       outw (UDC_EP_Dir, UDC_EP_NUM);
-               } else {
-                       /* This tx interrupt must be for a control read data
-                        * stage packet.
-                        */
-                       int wLength = le16_to_cpu (request->wLength);
-
-                       /* Update our count of bytes sent so far in this
-                        * transfer.
-                        */
-                       endpoint->sent += endpoint->last;
-
-                       /* We are finished with this transfer if we have sent
-                        * all of the bytes in our tx urb (urb->actual_length)
-                        * unless we need a zero-length terminating packet.  We
-                        * need a zero-length terminating packet if we returned
-                        * fewer bytes than were requested (wLength) by the host,
-                        * and the number of bytes we returned is an exact
-                        * multiple of the packet size endpoint->tx_packetSize.
-                        */
-                       if ((endpoint->sent == ep0_urb->actual_length)
-                           && ((ep0_urb->actual_length == wLength)
-                               || (endpoint->last !=
-                                   endpoint->tx_packetSize))) {
-                               /* Done with control read data stage. */
-                               UDCDBG ("control read data stage complete");
-                               /* deselect EP0 TX FIFO */
-                               outw (UDC_EP_Dir, UDC_EP_NUM);
-                               /* select EP0 RX FIFO to prepare for control
-                                * read status stage.
-                                */
-                               outw (UDC_EP_Sel, UDC_EP_NUM);
-                               /* clear the EP0 RX FIFO */
-                               outw (UDC_Clr_EP, UDC_CTRL);
-                               /* enable the EP0 RX FIFO */
-                               outw (UDC_Set_FIFO_En, UDC_CTRL);
-                               /* deselect the EP0 RX FIFO */
-                               outw (0, UDC_EP_NUM);
-                       } else {
-                               /* We still have another packet of data to send
-                                * in this control read data stage or else we
-                                * need a zero-length terminating packet.
-                                */
-                               UDCDBG ("ACK control read data stage packet");
-                               omap1510_write_noniso_tx_fifo (endpoint);
-                               /* enable the EP0 tx FIFO to start transmission */
-                               outw (UDC_Set_FIFO_En, UDC_CTRL);
-                               /* deselect EP0 TX FIFO */
-                               outw (UDC_EP_Dir, UDC_EP_NUM);
-                       }
-               }
-       } else if (status & UDC_STALL) {
-               UDCDBG ("EP0 stall during TX");
-               /* deselect EP0 TX FIFO */
-               outw (UDC_EP_Dir, UDC_EP_NUM);
-       } else {
-               /* deselect EP0 TX FIFO */
-               outw (UDC_EP_Dir, UDC_EP_NUM);
-       }
-}
-
-/* Handle RX transaction on non-ISO endpoint.
- * This function implements TRM Figure 14-27.
- * The ep argument is a physical endpoint number for a non-ISO OUT endpoint
- * in the range 1 to 15.
- */
-static void omap1510_udc_epn_rx (int ep)
-{
-       unsigned short status;
-
-       /* Check endpoint status */
-       status = inw (UDC_STAT_FLG);
-
-       if (status & UDC_ACK) {
-               int nbytes;
-               struct usb_endpoint_instance *endpoint =
-                       omap1510_find_ep (ep);
-
-               nbytes = omap1510_read_noniso_rx_fifo (endpoint);
-               usbd_rcv_complete (endpoint, nbytes, 0);
-
-               /* enable rx FIFO to prepare for next packet */
-               outw (UDC_Set_FIFO_En, UDC_CTRL);
-       } else if (status & UDC_STALL) {
-               UDCDBGA ("STALL on RX endpoint %d", ep);
-       } else if (status & UDC_NAK) {
-               UDCDBGA ("NAK on RX ep %d", ep);
-       } else {
-               serial_printf ("omap-bi: RX on ep %d with status %x", ep,
-                              status);
-       }
-}
-
-/* Handle TX transaction on non-ISO endpoint.
- * This function implements TRM Figure 14-29.
- * The ep argument is a physical endpoint number for a non-ISO IN endpoint
- * in the range 16 to 30.
- */
-static void omap1510_udc_epn_tx (int ep)
-{
-       unsigned short status;
-
-       /*serial_printf("omap1510_udc_epn_tx( %x )\n",ep); */
-
-       /* Check endpoint status */
-       status = inw (UDC_STAT_FLG);
-
-       if (status & UDC_ACK) {
-               struct usb_endpoint_instance *endpoint =
-                       omap1510_find_ep (ep);
-
-               /* We need to transmit a terminating zero-length packet now if
-                * we have sent all of the data in this URB and the transfer
-                * size was an exact multiple of the packet size.
-                */
-               if (endpoint->tx_urb
-                   && (endpoint->last == endpoint->tx_packetSize)
-                   && (endpoint->tx_urb->actual_length - endpoint->sent -
-                       endpoint->last == 0)) {
-                       /* Prepare to transmit a zero-length packet. */
-                       endpoint->sent += endpoint->last;
-                       /* write 0 bytes of data to FIFO */
-                       omap1510_write_noniso_tx_fifo (endpoint);
-                       /* enable tx FIFO to start transmission */
-                       outw (UDC_Set_FIFO_En, UDC_CTRL);
-               } else if (endpoint->tx_urb
-                          && endpoint->tx_urb->actual_length) {
-                       /* retire the data that was just sent */
-                       usbd_tx_complete (endpoint);
-                       /* Check to see if we have more data ready to transmit
-                        * now.
-                        */
-                       if (endpoint->tx_urb
-                           && endpoint->tx_urb->actual_length) {
-                               /* write data to FIFO */
-                               omap1510_write_noniso_tx_fifo (endpoint);
-                               /* enable tx FIFO to start transmission */
-                               outw (UDC_Set_FIFO_En, UDC_CTRL);
-                       }
-               }
-       } else if (status & UDC_STALL) {
-               UDCDBGA ("STALL on TX endpoint %d", ep);
-       } else if (status & UDC_NAK) {
-               UDCDBGA ("NAK on TX endpoint %d", ep);
-       } else {
-               /*serial_printf("omap-bi: TX on ep %d with status %x\n", ep, status); */
-       }
-}
-
-
-/*
--------------------------------------------------------------------------------
-*/
-
-/* Handle general USB interrupts and dispatch according to type.
- * This function implements TRM Figure 14-13.
- */
-void omap1510_udc_irq (void)
-{
-       u16 irq_src = inw (UDC_IRQ_SRC);
-       int valid_irq = 0;
-
-       if (!(irq_src & ~UDC_SOF_Flg))  /* ignore SOF interrupts ) */
-               return;
-
-       UDCDBGA ("< IRQ #%d start >- %x", udc_interrupts, irq_src);
-       /*serial_printf("< IRQ #%d start >- %x\n", udc_interrupts, irq_src); */
-
-       if (irq_src & UDC_DS_Chg) {
-               /* Device status changed */
-               omap1510_udc_state_changed ();
-               valid_irq++;
-       }
-       if (irq_src & UDC_EP0_RX) {
-               /* Endpoint 0 receive */
-               outw (UDC_EP0_RX, UDC_IRQ_SRC); /* ack interrupt */
-               omap1510_udc_ep0_rx (udc_device->bus->endpoint_array + 0);
-               valid_irq++;
-       }
-       if (irq_src & UDC_EP0_TX) {
-               /* Endpoint 0 transmit */
-               outw (UDC_EP0_TX, UDC_IRQ_SRC); /* ack interrupt */
-               omap1510_udc_ep0_tx (udc_device->bus->endpoint_array + 0);
-               valid_irq++;
-       }
-       if (irq_src & UDC_Setup) {
-               /* Device setup */
-               omap1510_udc_setup (udc_device->bus->endpoint_array + 0);
-               valid_irq++;
-       }
-       /*if (!valid_irq) */
-       /*      serial_printf("unknown interrupt, IRQ_SRC %.4x\n", irq_src); */
-       UDCDBGA ("< IRQ #%d end >", udc_interrupts);
-       udc_interrupts++;
-}
-
-/* This function implements TRM Figure 14-26. */
-void omap1510_udc_noniso_irq (void)
-{
-       unsigned short epnum;
-       unsigned short irq_src = inw (UDC_IRQ_SRC);
-       int valid_irq = 0;
-
-       if (!(irq_src & (UDC_EPn_RX | UDC_EPn_TX)))
-               return;
-
-       UDCDBGA ("non-ISO IRQ, IRQ_SRC %x", inw (UDC_IRQ_SRC));
-
-       if (irq_src & UDC_EPn_RX) {     /* Endpoint N OUT transaction */
-               /* Determine the endpoint number for this interrupt */
-               epnum = (inw (UDC_EPN_STAT) & 0x0f00) >> 8;
-               UDCDBGA ("RX on ep %x", epnum);
-
-               /* acknowledge interrupt */
-               outw (UDC_EPn_RX, UDC_IRQ_SRC);
-
-               if (epnum) {
-                       /* select the endpoint FIFO */
-                       outw (UDC_EP_Sel | epnum, UDC_EP_NUM);
-
-                       omap1510_udc_epn_rx (epnum);
-
-                       /* deselect the endpoint FIFO */
-                       outw (epnum, UDC_EP_NUM);
-               }
-               valid_irq++;
-       }
-       if (irq_src & UDC_EPn_TX) {     /* Endpoint N IN transaction */
-               /* Determine the endpoint number for this interrupt */
-               epnum = (inw (UDC_EPN_STAT) & 0x000f) | USB_DIR_IN;
-               UDCDBGA ("TX on ep %x", epnum);
-
-               /* acknowledge interrupt */
-               outw (UDC_EPn_TX, UDC_IRQ_SRC);
-
-               if (epnum) {
-                       /* select the endpoint FIFO */
-                       outw (UDC_EP_Sel | UDC_EP_Dir | epnum, UDC_EP_NUM);
-
-                       omap1510_udc_epn_tx (epnum);
-
-                       /* deselect the endpoint FIFO */
-                       outw (UDC_EP_Dir | epnum, UDC_EP_NUM);
-               }
-               valid_irq++;
-       }
-       if (!valid_irq)
-               serial_printf (": unknown non-ISO interrupt, IRQ_SRC %.4x\n",
-                              irq_src);
-}
-
-/*
--------------------------------------------------------------------------------
-*/
-
-
-/*
- * Start of public functions.
- */
-
-/* Called to start packet transmission. */
-void udc_endpoint_write (struct usb_endpoint_instance *endpoint)
-{
-       unsigned short epnum =
-               endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
-
-       UDCDBGA ("Starting transmit on ep %x", epnum);
-
-       if (endpoint->tx_urb) {
-               /* select the endpoint FIFO */
-               outw (UDC_EP_Sel | UDC_EP_Dir | epnum, UDC_EP_NUM);
-               /* write data to FIFO */
-               omap1510_write_noniso_tx_fifo (endpoint);
-               /* enable tx FIFO to start transmission */
-               outw (UDC_Set_FIFO_En, UDC_CTRL);
-               /* deselect the endpoint FIFO */
-               outw (UDC_EP_Dir | epnum, UDC_EP_NUM);
-       }
-}
-
-/* Start to initialize h/w stuff */
-int udc_init (void)
-{
-       u16 udc_rev;
-       uchar value;
-       ulong gpio;
-       int i;
-
-       /* Let the device settle down before we start */
-       for (i = 0; i < UDC_INIT_MDELAY; i++) udelay(1000);
-
-       udc_device = NULL;
-
-       UDCDBG ("starting");
-
-       /* Check peripheral reset. Must be 1 to make sure
-          MPU TIPB peripheral reset is inactive */
-       UDCREG (ARM_RSTCT2);
-
-       /* Set and check clock control.
-        * We might ought to be using the clock control API to do
-        * this instead of fiddling with the clock registers directly
-        * here.
-        */
-       outw ((1 << 4) | (1 << 5), CLOCK_CTRL);
-       UDCREG (CLOCK_CTRL);
-       /* Set and check APLL */
-       outw (0x0008, APLL_CTRL);
-       UDCREG (APLL_CTRL);
-       /* Set and check DPLL */
-       outw (0x2210, DPLL_CTRL);
-       UDCREG (DPLL_CTRL);
-       /* Set and check SOFT */
-       outw ((1 << 4) | (1 << 3) | 1, SOFT_REQ);
-       /* Short delay to wait for DPLL */
-       udelay (1000);
-
-       /* Print banner with device revision */
-       udc_rev = inw (UDC_REV) & 0xff;
-       printf ("USB:   TI OMAP1510 USB function module rev %d.%d\n",
-               udc_rev >> 4, udc_rev & 0xf);
-
-#ifdef CONFIG_OMAP_SX1
-       i2c_read (0x32, 0x04, 1, &value, 1);
-       value |= 0x04;
-       i2c_write (0x32, 0x04, 1, &value, 1);
-
-       i2c_read (0x32, 0x03, 1, &value, 1);
-       value |= 0x01;
-       i2c_write (0x32, 0x03, 1, &value, 1);
-
-       gpio = inl(GPIO_PIN_CONTROL_REG);
-       gpio |=  0x0002; /* A_IRDA_OFF */
-       gpio |=  0x0800; /* A_SWITCH   */
-       gpio |=  0x8000; /* A_USB_ON   */
-       outl (gpio, GPIO_PIN_CONTROL_REG);
-
-       gpio = inl(GPIO_DIR_CONTROL_REG);
-       gpio &= ~0x0002; /* A_IRDA_OFF */
-       gpio &= ~0x0800; /* A_SWITCH   */
-       gpio &= ~0x8000; /* A_USB_ON   */
-       outl (gpio, GPIO_DIR_CONTROL_REG);
-
-       gpio = inl(GPIO_DATA_OUTPUT_REG);
-       gpio |=  0x0002; /* A_IRDA_OFF */
-       gpio &= ~0x0800; /* A_SWITCH   */
-       gpio &= ~0x8000; /* A_USB_ON   */
-       outl (gpio, GPIO_DATA_OUTPUT_REG);
-#endif
-
-       /* The VBUS_MODE bit selects whether VBUS detection is done via
-        * software (1) or hardware (0).  When software detection is
-        * selected, VBUS_CTRL selects whether USB is not connected (0)
-        * or connected (1).
-        */
-       outl (inl (FUNC_MUX_CTRL_0) | UDC_VBUS_MODE, FUNC_MUX_CTRL_0);
-       outl (inl (FUNC_MUX_CTRL_0) & ~UDC_VBUS_CTRL, FUNC_MUX_CTRL_0);
-       UDCREGL (FUNC_MUX_CTRL_0);
-
-       /*
-        * At this point, device is ready for configuration...
-        */
-
-       UDCDBG ("disable USB interrupts");
-       outw (0, UDC_IRQ_EN);
-       UDCREG (UDC_IRQ_EN);
-
-       UDCDBG ("disable USB DMA");
-       outw (0, UDC_DMA_IRQ_EN);
-       UDCREG (UDC_DMA_IRQ_EN);
-
-       UDCDBG ("initialize SYSCON1");
-       outw (UDC_Self_Pwr | UDC_Pullup_En, UDC_SYSCON1);
-       UDCREG (UDC_SYSCON1);
-
-       return 0;
-}
-
-/* Stall endpoint */
-static void udc_stall_ep (unsigned int ep_addr)
-{
-       /*int ep_addr = PHYS_EP_TO_EP_ADDR(ep); */
-       int ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;
-
-       UDCDBGA ("stall ep_addr %d", ep_addr);
-
-       /* REVISIT?
-        * The OMAP TRM section 14.2.4.2 says we must check that the FIFO
-        * is empty before halting the endpoint.  The current implementation
-        * doesn't check that the FIFO is empty.
-        */
-
-       if (!ep_num) {
-               outw (UDC_Stall_Cmd, UDC_SYSCON2);
-       } else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
-               if (inw (UDC_EP_RX (ep_num)) & UDC_EPn_RX_Valid) {
-                       /* we have a valid rx endpoint, so halt it */
-                       outw (UDC_EP_Sel | ep_num, UDC_EP_NUM);
-                       outw (UDC_Set_Halt, UDC_CTRL);
-                       outw (ep_num, UDC_EP_NUM);
-               }
-       } else {
-               if (inw (UDC_EP_TX (ep_num)) & UDC_EPn_TX_Valid) {
-                       /* we have a valid tx endpoint, so halt it */
-                       outw (UDC_EP_Sel | UDC_EP_Dir | ep_num, UDC_EP_NUM);
-                       outw (UDC_Set_Halt, UDC_CTRL);
-                       outw (ep_num, UDC_EP_NUM);
-               }
-       }
-}
-
-/* Reset endpoint */
-#if 0
-static void udc_reset_ep (unsigned int ep_addr)
-{
-       /*int ep_addr = PHYS_EP_TO_EP_ADDR(ep); */
-       int ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;
-
-       UDCDBGA ("reset ep_addr %d", ep_addr);
-
-       if (!ep_num) {
-               /* control endpoint 0 can't be reset */
-       } else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
-               UDCDBGA ("UDC_EP_RX(%d) = 0x%04x", ep_num,
-                        inw (UDC_EP_RX (ep_num)));
-               if (inw (UDC_EP_RX (ep_num)) & UDC_EPn_RX_Valid) {
-                       /* we have a valid rx endpoint, so reset it */
-                       outw (ep_num | UDC_EP_Sel, UDC_EP_NUM);
-                       outw (UDC_Reset_EP, UDC_CTRL);
-                       outw (ep_num, UDC_EP_NUM);
-                       UDCDBGA ("OUT endpoint %d reset", ep_num);
-               }
-       } else {
-               UDCDBGA ("UDC_EP_TX(%d) = 0x%04x", ep_num,
-                        inw (UDC_EP_TX (ep_num)));
-               /* Resetting of tx endpoints seems to be causing the USB function
-                * module to fail, which causes problems when the driver is
-                * uninstalled.  We'll skip resetting tx endpoints for now until
-                * we figure out what the problem is.
-                */
-#if 0
-               if (inw (UDC_EP_TX (ep_num)) & UDC_EPn_TX_Valid) {
-                       /* we have a valid tx endpoint, so reset it */
-                       outw (ep_num | UDC_EP_Dir | UDC_EP_Sel, UDC_EP_NUM);
-                       outw (UDC_Reset_EP, UDC_CTRL);
-                       outw (ep_num | UDC_EP_Dir, UDC_EP_NUM);
-                       UDCDBGA ("IN endpoint %d reset", ep_num);
-               }
-#endif
-       }
-}
-#endif
-
-/* ************************************************************************** */
-
-/**
- * udc_check_ep - check logical endpoint
-  *
- * Return physical endpoint number to use for this logical endpoint or zero if not valid.
- */
-#if 0
-int udc_check_ep (int logical_endpoint, int packetsize)
-{
-       if ((logical_endpoint == 0x80) ||
-           ((logical_endpoint & 0x8f) != logical_endpoint)) {
-               return 0;
-       }
-
-       switch (packetsize) {
-       case 8:
-       case 16:
-       case 32:
-       case 64:
-       case 128:
-       case 256:
-       case 512:
-               break;
-       default:
-               return 0;
-       }
-
-       return EP_ADDR_TO_PHYS_EP (logical_endpoint);
-}
-#endif
-
-/*
- * udc_setup_ep - setup endpoint
- *
- * Associate a physical endpoint with endpoint_instance
- */
-void udc_setup_ep (struct usb_device_instance *device,
-                  unsigned int ep, struct usb_endpoint_instance *endpoint)
-{
-       UDCDBGA ("setting up endpoint addr %x", endpoint->endpoint_address);
-
-       /* This routine gets called by bi_modinit for endpoint 0 and from
-        * bi_config for all of the other endpoints.  bi_config gets called
-        * during the DEVICE_CREATE, DEVICE_CONFIGURED, and
-        * DEVICE_SET_INTERFACE events.  We need to reconfigure the OMAP packet
-        * RAM after bi_config scans the selected device configuration and
-        * initializes the endpoint structures, but before this routine enables
-        * the OUT endpoint FIFOs.  Since bi_config calls this routine in a
-        * loop for endpoints 1 through UDC_MAX_ENDPOINTS, we reconfigure our
-        * packet RAM here when ep==1.
-        * I really hate to do this here, but it seems like the API exported
-        * by the USB bus interface controller driver to the usbd-bi module
-        * isn't quite right so there is no good place to do this.
-        */
-       if (ep == 1) {
-               omap1510_deconfigure_device ();
-               omap1510_configure_device (device);
-       }
-
-       if (endpoint && (ep < UDC_MAX_ENDPOINTS)) {
-               int ep_addr = endpoint->endpoint_address;
-
-               if (!ep_addr) {
-                       /* nothing to do for endpoint 0 */
-               } else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
-                       /* nothing to do for IN (tx) endpoints */
-               } else {        /* OUT (rx) endpoint */
-                       if (endpoint->rcv_packetSize) {
-                               /*struct urb* urb = &(urb_out_array[ep&0xFF]); */
-                               /*urb->endpoint = endpoint; */
-                               /*urb->device = device; */
-                               /*urb->buffer_length = sizeof(urb->buffer); */
-
-                               /*endpoint->rcv_urb = urb; */
-                               omap1510_prepare_endpoint_for_rx (ep_addr);
-                       }
-               }
-       }
-}
-
-/**
- * udc_disable_ep - disable endpoint
- * @ep:
- *
- * Disable specified endpoint
- */
-#if 0
-void udc_disable_ep (unsigned int ep_addr)
-{
-       /*int ep_addr = PHYS_EP_TO_EP_ADDR(ep); */
-       int ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;
-       struct usb_endpoint_instance *endpoint = omap1510_find_ep (ep_addr);    /*udc_device->bus->endpoint_array + ep; */
-
-       UDCDBGA ("disable ep_addr %d", ep_addr);
-
-       if (!ep_num) {
-               /* nothing to do for endpoint 0 */ ;
-       } else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
-               if (endpoint->tx_packetSize) {
-                       /* we have a valid tx endpoint */
-                       /*usbd_flush_tx(endpoint); */
-                       endpoint->tx_urb = NULL;
-               }
-       } else {
-               if (endpoint->rcv_packetSize) {
-                       /* we have a valid rx endpoint */
-                       /*usbd_flush_rcv(endpoint); */
-                       endpoint->rcv_urb = NULL;
-               }
-       }
-}
-#endif
-
-/* ************************************************************************** */
-
-/**
- * udc_connected - is the USB cable connected
- *
- * Return non-zero if cable is connected.
- */
-#if 0
-int udc_connected (void)
-{
-       return ((inw (UDC_DEVSTAT) & UDC_ATT) == UDC_ATT);
-}
-#endif
-
-/* Turn on the USB connection by enabling the pullup resistor */
-void udc_connect (void)
-{
-       UDCDBG ("connect, enable Pullup");
-       outl (0x00000018, FUNC_MUX_CTRL_D);
-}
-
-/* Turn off the USB connection by disabling the pullup resistor */
-void udc_disconnect (void)
-{
-       UDCDBG ("disconnect, disable Pullup");
-       outl (0x00000000, FUNC_MUX_CTRL_D);
-}
-
-/* ************************************************************************** */
-
-
-/*
- * udc_disable_interrupts - disable interrupts
- * switch off interrupts
- */
-#if 0
-void udc_disable_interrupts (struct usb_device_instance *device)
-{
-       UDCDBG ("disabling all interrupts");
-       outw (0, UDC_IRQ_EN);
-}
-#endif
-
-/* ************************************************************************** */
-
-/**
- * udc_ep0_packetsize - return ep0 packetsize
- */
-#if 0
-int udc_ep0_packetsize (void)
-{
-       return EP0_PACKETSIZE;
-}
-#endif
-
-/* Switch on the UDC */
-void udc_enable (struct usb_device_instance *device)
-{
-       UDCDBGA ("enable device %p, status %d", device, device->status);
-
-       /* initialize driver state variables */
-       udc_devstat = 0;
-
-       /* Save the device structure pointer */
-       udc_device = device;
-
-       /* Setup ep0 urb */
-       if (!ep0_urb) {
-               ep0_urb =
-                       usbd_alloc_urb (udc_device,
-                                       udc_device->bus->endpoint_array);
-       } else {
-               serial_printf ("udc_enable: ep0_urb already allocated %p\n",
-                              ep0_urb);
-       }
-
-       UDCDBG ("Check clock status");
-       UDCREG (STATUS_REQ);
-
-       /* The VBUS_MODE bit selects whether VBUS detection is done via
-        * software (1) or hardware (0).  When software detection is
-        * selected, VBUS_CTRL selects whether USB is not connected (0)
-        * or connected (1).
-        */
-       outl (inl (FUNC_MUX_CTRL_0) | UDC_VBUS_CTRL | UDC_VBUS_MODE,
-             FUNC_MUX_CTRL_0);
-       UDCREGL (FUNC_MUX_CTRL_0);
-
-       omap1510_configure_device (device);
-}
-
-/* Switch off the UDC */
-void udc_disable (void)
-{
-       UDCDBG ("disable UDC");
-
-       omap1510_deconfigure_device ();
-
-       /* The VBUS_MODE bit selects whether VBUS detection is done via
-        * software (1) or hardware (0).  When software detection is
-        * selected, VBUS_CTRL selects whether USB is not connected (0)
-        * or connected (1).
-        */
-       outl (inl (FUNC_MUX_CTRL_0) | UDC_VBUS_MODE, FUNC_MUX_CTRL_0);
-       outl (inl (FUNC_MUX_CTRL_0) & ~UDC_VBUS_CTRL, FUNC_MUX_CTRL_0);
-       UDCREGL (FUNC_MUX_CTRL_0);
-
-       /* Free ep0 URB */
-       if (ep0_urb) {
-               /*usbd_dealloc_urb(ep0_urb); */
-               ep0_urb = NULL;
-       }
-
-       /* Reset device pointer.
-        * We ought to do this here to balance the initialization of udc_device
-        * in udc_enable, but some of our other exported functions get called
-        * by the bus interface driver after udc_disable, so we have to hang on
-        * to the device pointer to avoid a null pointer dereference. */
-       /* udc_device = NULL; */
-}
-
-/**
- * udc_startup - allow udc code to do any additional startup
- */
-void udc_startup_events (struct usb_device_instance *device)
-{
-       /* The DEVICE_INIT event puts the USB device in the state STATE_INIT. */
-       usbd_device_event_irq (device, DEVICE_INIT, 0);
-
-       /* The DEVICE_CREATE event puts the USB device in the state
-        * STATE_ATTACHED.
-        */
-       usbd_device_event_irq (device, DEVICE_CREATE, 0);
-
-       /* Some USB controller driver implementations signal
-        * DEVICE_HUB_CONFIGURED and DEVICE_RESET events here.
-        * DEVICE_HUB_CONFIGURED causes a transition to the state STATE_POWERED,
-        * and DEVICE_RESET causes a transition to the state STATE_DEFAULT.
-        * The OMAP USB client controller has the capability to detect when the
-        * USB cable is connected to a powered USB bus via the ATT bit in the
-        * DEVSTAT register, so we will defer the DEVICE_HUB_CONFIGURED and
-        * DEVICE_RESET events until later.
-        */
-
-       udc_enable (device);
-}
-
-/**
- * udc_irq - do pseudo interrupts
- */
-void udc_irq(void)
-{
-       /* Loop while we have interrupts.
-        * If we don't do this, the input chain
-        * polling delay is likely to miss
-        * host requests.
-        */
-       while (inw (UDC_IRQ_SRC) & ~UDC_SOF_Flg) {
-               /* Handle any new IRQs */
-               omap1510_udc_irq ();
-               omap1510_udc_noniso_irq ();
-       }
-}
-
-/* Flow control */
-void udc_set_nak(int epid)
-{
-       /* TODO: implement this functionality in omap1510 */
-}
-
-void udc_unset_nak (int epid)
-{
-       /* TODO: implement this functionality in omap1510 */
-}
-#endif
diff --git a/drivers/usbtty.c b/drivers/usbtty.c
deleted file mode 100644 (file)
index a3b5013..0000000
+++ /dev/null
@@ -1,1012 +0,0 @@
-/*
- * (C) Copyright 2003
- * Gerry Hamel, geh@ti.com, Texas Instruments
- *
- * (C) Copyright 2006
- * Bryan O'Donoghue, bodonoghue@codehermit.ie
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307         USA
- *
- */
-
-#include <common.h>
-
-#ifdef CONFIG_USB_TTY
-
-#include <circbuf.h>
-#include <devices.h>
-#include "usbtty.h"
-#include "usb_cdc_acm.h"
-#include "usbdescriptors.h"
-#include <config.h>            /* If defined, override Linux identifiers with
-                                * vendor specific ones */
-
-#if 0
-#define TTYDBG(fmt,args...)\
-       serial_printf("[%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args)
-#else
-#define TTYDBG(fmt,args...) do{}while(0)
-#endif
-
-#if 1
-#define TTYERR(fmt,args...)\
-       serial_printf("ERROR![%s] %s %d: "fmt, __FILE__,__FUNCTION__,\
-       __LINE__,##args)
-#else
-#define TTYERR(fmt,args...) do{}while(0)
-#endif
-
-/*
- * Defines
- */
-#define NUM_CONFIGS    1
-#define MAX_INTERFACES 2
-#define NUM_ENDPOINTS  3
-#define ACM_TX_ENDPOINT 3
-#define ACM_RX_ENDPOINT 2
-#define GSERIAL_TX_ENDPOINT 2
-#define GSERIAL_RX_ENDPOINT 1
-#define NUM_ACM_INTERFACES 2
-#define NUM_GSERIAL_INTERFACES 1
-#define CONFIG_USBD_DATA_INTERFACE_STR "Bulk Data Interface"
-#define CONFIG_USBD_CTRL_INTERFACE_STR "Control Interface"
-
-/*
- * Buffers to hold input and output data
- */
-#define USBTTY_BUFFER_SIZE 256
-static circbuf_t usbtty_input;
-static circbuf_t usbtty_output;
-
-
-/*
- * Instance variables
- */
-static device_t usbttydev;
-static struct usb_device_instance device_instance[1];
-static struct usb_bus_instance bus_instance[1];
-static struct usb_configuration_instance config_instance[NUM_CONFIGS];
-static struct usb_interface_instance interface_instance[MAX_INTERFACES];
-static struct usb_alternate_instance alternate_instance[MAX_INTERFACES];
-/* one extra for control endpoint */
-static struct usb_endpoint_instance endpoint_instance[NUM_ENDPOINTS+1];
-
-/*
- * Global flag
- */
-int usbtty_configured_flag = 0;
-
-/*
- * Serial number
- */
-static char serial_number[16];
-
-
-/*
- * Descriptors, Strings, Local variables.
- */
-
-/* defined and used by usbdcore_ep0.c */
-extern struct usb_string_descriptor **usb_strings;
-
-/* Indicies, References */
-static unsigned short rx_endpoint = 0;
-static unsigned short tx_endpoint = 0;
-static unsigned short interface_count = 0;
-static struct usb_string_descriptor *usbtty_string_table[STR_COUNT];
-
-/* USB Descriptor Strings */
-static u8 wstrLang[4] = {4,USB_DT_STRING,0x9,0x4};
-static u8 wstrManufacturer[2 + 2*(sizeof(CONFIG_USBD_MANUFACTURER)-1)];
-static u8 wstrProduct[2 + 2*(sizeof(CONFIG_USBD_PRODUCT_NAME)-1)];
-static u8 wstrSerial[2 + 2*(sizeof(serial_number) - 1)];
-static u8 wstrConfiguration[2 + 2*(sizeof(CONFIG_USBD_CONFIGURATION_STR)-1)];
-static u8 wstrDataInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)];
-static u8 wstrCtrlInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)];
-
-/* Standard USB Data Structures */
-static struct usb_interface_descriptor interface_descriptors[MAX_INTERFACES];
-static struct usb_endpoint_descriptor *ep_descriptor_ptrs[NUM_ENDPOINTS];
-static struct usb_configuration_descriptor     *configuration_descriptor = 0;
-static struct usb_device_descriptor device_descriptor = {
-       .bLength = sizeof(struct usb_device_descriptor),
-       .bDescriptorType =      USB_DT_DEVICE,
-       .bcdUSB =               cpu_to_le16(USB_BCD_VERSION),
-       .bDeviceSubClass =      0x00,
-       .bDeviceProtocol =      0x00,
-       .bMaxPacketSize0 =      EP0_MAX_PACKET_SIZE,
-       .idVendor =             cpu_to_le16(CONFIG_USBD_VENDORID),
-       .bcdDevice =            cpu_to_le16(USBTTY_BCD_DEVICE),
-       .iManufacturer =        STR_MANUFACTURER,
-       .iProduct =             STR_PRODUCT,
-       .iSerialNumber =        STR_SERIAL,
-       .bNumConfigurations =   NUM_CONFIGS
-};
-
-
-/*
- * Static CDC ACM specific descriptors
- */
-
-struct acm_config_desc {
-       struct usb_configuration_descriptor configuration_desc;
-
-       /* Master Interface */
-       struct usb_interface_descriptor interface_desc;
-
-       struct usb_class_header_function_descriptor usb_class_header;
-       struct usb_class_call_management_descriptor usb_class_call_mgt;
-       struct usb_class_abstract_control_descriptor usb_class_acm;
-       struct usb_class_union_function_descriptor usb_class_union;
-       struct usb_endpoint_descriptor notification_endpoint;
-
-       /* Slave Interface */
-       struct usb_interface_descriptor data_class_interface;
-       struct usb_endpoint_descriptor
-               data_endpoints[NUM_ENDPOINTS-1] __attribute__((packed));
-} __attribute__((packed));
-
-static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = {
-       {
-               .configuration_desc ={
-                       .bLength =
-                               sizeof(struct usb_configuration_descriptor),
-                       .bDescriptorType = USB_DT_CONFIG,
-                       .wTotalLength =
-                               cpu_to_le16(sizeof(struct acm_config_desc)),
-                       .bNumInterfaces = NUM_ACM_INTERFACES,
-                       .bConfigurationValue = 1,
-                       .iConfiguration = STR_CONFIG,
-                       .bmAttributes =
-                               BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
-                       .bMaxPower = USBTTY_MAXPOWER
-               },
-               /* Interface 1 */
-               .interface_desc = {
-                       .bLength  = sizeof(struct usb_interface_descriptor),
-                       .bDescriptorType = USB_DT_INTERFACE,
-                       .bInterfaceNumber = 0,
-                       .bAlternateSetting = 0,
-                       .bNumEndpoints = 0x01,
-                       .bInterfaceClass =
-                               COMMUNICATIONS_INTERFACE_CLASS_CONTROL,
-                       .bInterfaceSubClass = COMMUNICATIONS_ACM_SUBCLASS,
-                       .bInterfaceProtocol = COMMUNICATIONS_V25TER_PROTOCOL,
-                       .iInterface = STR_CTRL_INTERFACE,
-               },
-               .usb_class_header = {
-                       .bFunctionLength        =
-                               sizeof(struct usb_class_header_function_descriptor),
-                       .bDescriptorType        = CS_INTERFACE,
-                       .bDescriptorSubtype     = USB_ST_HEADER,
-                       .bcdCDC = cpu_to_le16(110),
-               },
-               .usb_class_call_mgt = {
-                       .bFunctionLength        =
-                               sizeof(struct usb_class_call_management_descriptor),
-                       .bDescriptorType        = CS_INTERFACE,
-                       .bDescriptorSubtype     = USB_ST_CMF,
-                       .bmCapabilities         = 0x00,
-                       .bDataInterface         = 0x01,
-               },
-               .usb_class_acm = {
-                       .bFunctionLength        =
-                               sizeof(struct usb_class_abstract_control_descriptor),
-                       .bDescriptorType        = CS_INTERFACE,
-                       .bDescriptorSubtype     = USB_ST_ACMF,
-                       .bmCapabilities         = 0x00,
-               },
-               .usb_class_union = {
-                       .bFunctionLength        =
-                               sizeof(struct usb_class_union_function_descriptor),
-                       .bDescriptorType        = CS_INTERFACE,
-                       .bDescriptorSubtype     = USB_ST_UF,
-                       .bMasterInterface       = 0x00,
-                       .bSlaveInterface0       = 0x01,
-               },
-               .notification_endpoint = {
-                       .bLength =
-                               sizeof(struct usb_endpoint_descriptor),
-                       .bDescriptorType        = USB_DT_ENDPOINT,
-                       .bEndpointAddress       = 0x01 | USB_DIR_IN,
-                       .bmAttributes           = USB_ENDPOINT_XFER_INT,
-                       .wMaxPacketSize
-                               = cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
-                       .bInterval              = 0xFF,
-               },
-
-               /* Interface 2 */
-               .data_class_interface = {
-                       .bLength                =
-                               sizeof(struct usb_interface_descriptor),
-                       .bDescriptorType        = USB_DT_INTERFACE,
-                       .bInterfaceNumber       = 0x01,
-                       .bAlternateSetting      = 0x00,
-                       .bNumEndpoints          = 0x02,
-                       .bInterfaceClass        =
-                               COMMUNICATIONS_INTERFACE_CLASS_DATA,
-                       .bInterfaceSubClass     = DATA_INTERFACE_SUBCLASS_NONE,
-                       .bInterfaceProtocol     = DATA_INTERFACE_PROTOCOL_NONE,
-                       .iInterface             = STR_DATA_INTERFACE,
-               },
-               .data_endpoints = {
-                       {
-                               .bLength                =
-                                       sizeof(struct usb_endpoint_descriptor),
-                               .bDescriptorType        = USB_DT_ENDPOINT,
-                               .bEndpointAddress       = 0x02 | USB_DIR_OUT,
-                               .bmAttributes           =
-                                       USB_ENDPOINT_XFER_BULK,
-                               .wMaxPacketSize         =
-                                       cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),
-                               .bInterval              = 0xFF,
-                       },
-                       {
-                               .bLength                =
-                                       sizeof(struct usb_endpoint_descriptor),
-                               .bDescriptorType        = USB_DT_ENDPOINT,
-                               .bEndpointAddress       = 0x03 | USB_DIR_IN,
-                               .bmAttributes           =
-                                       USB_ENDPOINT_XFER_BULK,
-                               .wMaxPacketSize         =
-                                       cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),
-                               .bInterval              = 0xFF,
-                       },
-               },
-       },
-};
-
-static struct rs232_emu rs232_desc={
-               .dter           =       115200,
-               .stop_bits      =       0x00,
-               .parity         =       0x00,
-               .data_bits      =       0x08
-};
-
-
-/*
- * Static Generic Serial specific data
- */
-
-
-struct gserial_config_desc {
-
-       struct usb_configuration_descriptor configuration_desc;
-       struct usb_interface_descriptor
-               interface_desc[NUM_GSERIAL_INTERFACES] __attribute__((packed));
-       struct usb_endpoint_descriptor
-               data_endpoints[NUM_ENDPOINTS] __attribute__((packed));
-
-} __attribute__((packed));
-
-static struct gserial_config_desc
-gserial_configuration_descriptors[NUM_CONFIGS] ={
-       {
-               .configuration_desc ={
-                       .bLength = sizeof(struct usb_configuration_descriptor),
-                       .bDescriptorType = USB_DT_CONFIG,
-                       .wTotalLength =
-                               cpu_to_le16(sizeof(struct gserial_config_desc)),
-                       .bNumInterfaces = NUM_GSERIAL_INTERFACES,
-                       .bConfigurationValue = 1,
-                       .iConfiguration = STR_CONFIG,
-                       .bmAttributes =
-                               BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
-                       .bMaxPower = USBTTY_MAXPOWER
-               },
-               .interface_desc = {
-                       {
-                               .bLength  =
-                                       sizeof(struct usb_interface_descriptor),
-                               .bDescriptorType = USB_DT_INTERFACE,
-                               .bInterfaceNumber = 0,
-                               .bAlternateSetting = 0,
-                               .bNumEndpoints = NUM_ENDPOINTS,
-                               .bInterfaceClass =
-                                       COMMUNICATIONS_INTERFACE_CLASS_VENDOR,
-                               .bInterfaceSubClass =
-                                       COMMUNICATIONS_NO_SUBCLASS,
-                               .bInterfaceProtocol =
-                                       COMMUNICATIONS_NO_PROTOCOL,
-                               .iInterface = STR_DATA_INTERFACE
-                       },
-               },
-               .data_endpoints  = {
-                       {
-                               .bLength =
-                                       sizeof(struct usb_endpoint_descriptor),
-                               .bDescriptorType =      USB_DT_ENDPOINT,
-                               .bEndpointAddress =     0x01 | USB_DIR_OUT,
-                               .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-                               .wMaxPacketSize =
-                                       cpu_to_le16(CONFIG_USBD_SERIAL_OUT_PKTSIZE),
-                               .bInterval=             0xFF,
-                       },
-                       {
-                               .bLength =
-                                       sizeof(struct usb_endpoint_descriptor),
-                               .bDescriptorType =      USB_DT_ENDPOINT,
-                               .bEndpointAddress =     0x02 | USB_DIR_IN,
-                               .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-                               .wMaxPacketSize =
-                                       cpu_to_le16(CONFIG_USBD_SERIAL_IN_PKTSIZE),
-                               .bInterval =            0xFF,
-                       },
-                       {
-                               .bLength =
-                                       sizeof(struct usb_endpoint_descriptor),
-                               .bDescriptorType =      USB_DT_ENDPOINT,
-                               .bEndpointAddress =     0x03 | USB_DIR_IN,
-                               .bmAttributes =         USB_ENDPOINT_XFER_INT,
-                               .wMaxPacketSize =
-                                       cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
-                               .bInterval =            0xFF,
-                       },
-               },
-       },
-};
-
-/*
- * Static Function Prototypes
- */
-
-static void usbtty_init_strings (void);
-static void usbtty_init_instances (void);
-static void usbtty_init_endpoints (void);
-static void usbtty_init_terminal_type(short type);
-static void usbtty_event_handler (struct usb_device_instance *device,
-                               usb_device_event_t event, int data);
-static int usbtty_cdc_setup(struct usb_device_request *request,
-                               struct urb *urb);
-static int usbtty_configured (void);
-static int write_buffer (circbuf_t * buf);
-static int fill_buffer (circbuf_t * buf);
-
-void usbtty_poll (void);
-
-/* utility function for converting char* to wide string used by USB */
-static void str2wide (char *str, u16 * wide)
-{
-       int i;
-       for (i = 0; i < strlen (str) && str[i]; i++){
-               #if defined(__LITTLE_ENDIAN)
-                       wide[i] = (u16) str[i];
-               #elif defined(__BIG_ENDIAN)
-                       wide[i] = ((u16)(str[i])<<8);
-               #else
-                       #error "__LITTLE_ENDIAN or __BIG_ENDIAN undefined"
-               #endif
-       }
-}
-
-/*
- * Test whether a character is in the RX buffer
- */
-
-int usbtty_tstc (void)
-{
-       struct usb_endpoint_instance *endpoint =
-               &endpoint_instance[rx_endpoint];
-
-       /* If no input data exists, allow more RX to be accepted */
-       if(usbtty_input.size <= 0){
-               udc_unset_nak(endpoint->endpoint_address&0x03);
-       }
-
-       usbtty_poll ();
-       return (usbtty_input.size > 0);
-}
-
-/*
- * Read a single byte from the usb client port. Returns 1 on success, 0
- * otherwise. When the function is succesfull, the character read is
- * written into its argument c.
- */
-
-int usbtty_getc (void)
-{
-       char c;
-       struct usb_endpoint_instance *endpoint =
-               &endpoint_instance[rx_endpoint];
-
-       while (usbtty_input.size <= 0) {
-               udc_unset_nak(endpoint->endpoint_address&0x03);
-               usbtty_poll ();
-       }
-
-       buf_pop (&usbtty_input, &c, 1);
-       udc_set_nak(endpoint->endpoint_address&0x03);
-
-       return c;
-}
-
-/*
- * Output a single byte to the usb client port.
- */
-void usbtty_putc (const char c)
-{
-       buf_push (&usbtty_output, &c, 1);
-       /* If \n, also do \r */
-       if (c == '\n')
-               buf_push (&usbtty_output, "\r", 1);
-
-       /* Poll at end to handle new data... */
-       if ((usbtty_output.size + 2) >= usbtty_output.totalsize) {
-               usbtty_poll ();
-       }
-}
-
-/* usbtty_puts() helper function for finding the next '\n' in a string */
-static int next_nl_pos (const char *s)
-{
-       int i;
-
-       for (i = 0; s[i] != '\0'; i++) {
-               if (s[i] == '\n')
-                       return i;
-       }
-       return i;
-}
-
-/*
- * Output a string to the usb client port - implementing flow control
- */
-
-static void __usbtty_puts (const char *str, int len)
-{
-       int maxlen = usbtty_output.totalsize;
-       int space, n;
-
-       /* break str into chunks < buffer size, if needed */
-       while (len > 0) {
-               usbtty_poll ();
-
-               space = maxlen - usbtty_output.size;
-               /* Empty buffer here, if needed, to ensure space... */
-               if (space) {
-                       write_buffer (&usbtty_output);
-
-                       n = MIN (space, MIN (len, maxlen));
-                       buf_push (&usbtty_output, str, n);
-
-                       str += n;
-                       len -= n;
-               }
-       }
-}
-
-void usbtty_puts (const char *str)
-{
-       int n;
-       int len = strlen (str);
-
-       /* add '\r' for each '\n' */
-       while (len > 0) {
-               n = next_nl_pos (str);
-
-               if (str[n] == '\n') {
-                       __usbtty_puts (str, n + 1);
-                       __usbtty_puts ("\r", 1);
-                       str += (n + 1);
-                       len -= (n + 1);
-               } else {
-                       /* No \n found.  All done. */
-                       __usbtty_puts (str, n);
-                       break;
-               }
-       }
-
-       /* Poll at end to handle new data... */
-       usbtty_poll ();
-}
-
-/*
- * Initialize the usb client port.
- *
- */
-int drv_usbtty_init (void)
-{
-       int rc;
-       char * sn;
-       char * tt;
-       int snlen;
-
-       /* Ger seiral number */
-       if (!(sn = getenv("serial#"))) {
-               sn = "000000000000";
-       }
-       snlen = strlen(sn);
-       if (snlen > sizeof(serial_number) - 1) {
-               printf ("Warning: serial number %s is too long (%d > %d)\n",
-                       sn, snlen, sizeof(serial_number) - 1);
-               snlen = sizeof(serial_number) - 1;
-       }
-       memcpy (serial_number, sn, snlen);
-       serial_number[snlen] = '\0';
-
-       /* Decide on which type of UDC device to be.
-        */
-
-       if(!(tt = getenv("usbtty"))) {
-               tt = "generic";
-       }
-       usbtty_init_terminal_type(strcmp(tt,"cdc_acm"));
-
-       /* prepare buffers... */
-       buf_init (&usbtty_input, USBTTY_BUFFER_SIZE);
-       buf_init (&usbtty_output, USBTTY_BUFFER_SIZE);
-
-       /* Now, set up USB controller and infrastructure */
-       udc_init ();            /* Basic USB initialization */
-
-       usbtty_init_strings ();
-       usbtty_init_instances ();
-
-       udc_startup_events (device_instance);/* Enable dev, init udc pointers */
-       udc_connect ();         /* Enable pullup for host detection */
-
-       usbtty_init_endpoints ();
-
-       /* Device initialization */
-       memset (&usbttydev, 0, sizeof (usbttydev));
-
-       strcpy (usbttydev.name, "usbtty");
-       usbttydev.ext = 0;      /* No extensions */
-       usbttydev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_OUTPUT;
-       usbttydev.tstc = usbtty_tstc;   /* 'tstc' function */
-       usbttydev.getc = usbtty_getc;   /* 'getc' function */
-       usbttydev.putc = usbtty_putc;   /* 'putc' function */
-       usbttydev.puts = usbtty_puts;   /* 'puts' function */
-
-       rc = device_register (&usbttydev);
-
-       return (rc == 0) ? 1 : rc;
-}
-
-static void usbtty_init_strings (void)
-{
-       struct usb_string_descriptor *string;
-
-       usbtty_string_table[STR_LANG] =
-               (struct usb_string_descriptor*)wstrLang;
-
-       string = (struct usb_string_descriptor *) wstrManufacturer;
-       string->bLength = sizeof(wstrManufacturer);
-       string->bDescriptorType = USB_DT_STRING;
-       str2wide (CONFIG_USBD_MANUFACTURER, string->wData);
-       usbtty_string_table[STR_MANUFACTURER]=string;
-
-
-       string = (struct usb_string_descriptor *) wstrProduct;
-       string->bLength = sizeof(wstrProduct);
-       string->bDescriptorType = USB_DT_STRING;
-       str2wide (CONFIG_USBD_PRODUCT_NAME, string->wData);
-       usbtty_string_table[STR_PRODUCT]=string;
-
-
-       string = (struct usb_string_descriptor *) wstrSerial;
-       string->bLength = sizeof(serial_number);
-       string->bDescriptorType = USB_DT_STRING;
-       str2wide (serial_number, string->wData);
-       usbtty_string_table[STR_SERIAL]=string;
-
-
-       string = (struct usb_string_descriptor *) wstrConfiguration;
-       string->bLength = sizeof(wstrConfiguration);
-       string->bDescriptorType = USB_DT_STRING;
-       str2wide (CONFIG_USBD_CONFIGURATION_STR, string->wData);
-       usbtty_string_table[STR_CONFIG]=string;
-
-
-       string = (struct usb_string_descriptor *) wstrDataInterface;
-       string->bLength = sizeof(wstrDataInterface);
-       string->bDescriptorType = USB_DT_STRING;
-       str2wide (CONFIG_USBD_DATA_INTERFACE_STR, string->wData);
-       usbtty_string_table[STR_DATA_INTERFACE]=string;
-
-       string = (struct usb_string_descriptor *) wstrCtrlInterface;
-       string->bLength = sizeof(wstrCtrlInterface);
-       string->bDescriptorType = USB_DT_STRING;
-       str2wide (CONFIG_USBD_CTRL_INTERFACE_STR, string->wData);
-       usbtty_string_table[STR_CTRL_INTERFACE]=string;
-
-       /* Now, initialize the string table for ep0 handling */
-       usb_strings = usbtty_string_table;
-}
-
-static void usbtty_init_instances (void)
-{
-       int i;
-
-       /* initialize device instance */
-       memset (device_instance, 0, sizeof (struct usb_device_instance));
-       device_instance->device_state = STATE_INIT;
-       device_instance->device_descriptor = &device_descriptor;
-       device_instance->event = usbtty_event_handler;
-       device_instance->cdc_recv_setup = usbtty_cdc_setup;
-       device_instance->bus = bus_instance;
-       device_instance->configurations = NUM_CONFIGS;
-       device_instance->configuration_instance_array = config_instance;
-
-       /* initialize bus instance */
-       memset (bus_instance, 0, sizeof (struct usb_bus_instance));
-       bus_instance->device = device_instance;
-       bus_instance->endpoint_array = endpoint_instance;
-       bus_instance->max_endpoints = 1;
-       bus_instance->maxpacketsize = 64;
-       bus_instance->serial_number_str = serial_number;
-
-       /* configuration instance */
-       memset (config_instance, 0,
-               sizeof (struct usb_configuration_instance));
-       config_instance->interfaces = interface_count;
-       config_instance->configuration_descriptor = configuration_descriptor;
-       config_instance->interface_instance_array = interface_instance;
-
-       /* interface instance */
-       memset (interface_instance, 0,
-               sizeof (struct usb_interface_instance));
-       interface_instance->alternates = 1;
-       interface_instance->alternates_instance_array = alternate_instance;
-
-       /* alternates instance */
-       memset (alternate_instance, 0,
-               sizeof (struct usb_alternate_instance));
-       alternate_instance->interface_descriptor = interface_descriptors;
-       alternate_instance->endpoints = NUM_ENDPOINTS;
-       alternate_instance->endpoints_descriptor_array = ep_descriptor_ptrs;
-
-       /* endpoint instances */
-       memset (&endpoint_instance[0], 0,
-               sizeof (struct usb_endpoint_instance));
-       endpoint_instance[0].endpoint_address = 0;
-       endpoint_instance[0].rcv_packetSize = EP0_MAX_PACKET_SIZE;
-       endpoint_instance[0].rcv_attributes = USB_ENDPOINT_XFER_CONTROL;
-       endpoint_instance[0].tx_packetSize = EP0_MAX_PACKET_SIZE;
-       endpoint_instance[0].tx_attributes = USB_ENDPOINT_XFER_CONTROL;
-       udc_setup_ep (device_instance, 0, &endpoint_instance[0]);
-
-       for (i = 1; i <= NUM_ENDPOINTS; i++) {
-               memset (&endpoint_instance[i], 0,
-                       sizeof (struct usb_endpoint_instance));
-
-               endpoint_instance[i].endpoint_address =
-                       ep_descriptor_ptrs[i - 1]->bEndpointAddress;
-
-               endpoint_instance[i].rcv_attributes =
-                       ep_descriptor_ptrs[i - 1]->bmAttributes;
-
-               endpoint_instance[i].rcv_packetSize =
-                       le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize);
-
-               endpoint_instance[i].tx_attributes =
-                       ep_descriptor_ptrs[i - 1]->bmAttributes;
-
-               endpoint_instance[i].tx_packetSize =
-                       le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize);
-
-               endpoint_instance[i].tx_attributes =
-                       ep_descriptor_ptrs[i - 1]->bmAttributes;
-
-               urb_link_init (&endpoint_instance[i].rcv);
-               urb_link_init (&endpoint_instance[i].rdy);
-               urb_link_init (&endpoint_instance[i].tx);
-               urb_link_init (&endpoint_instance[i].done);
-
-               if (endpoint_instance[i].endpoint_address & USB_DIR_IN)
-                       endpoint_instance[i].tx_urb =
-                               usbd_alloc_urb (device_instance,
-                                               &endpoint_instance[i]);
-               else
-                       endpoint_instance[i].rcv_urb =
-                               usbd_alloc_urb (device_instance,
-                                               &endpoint_instance[i]);
-       }
-}
-
-static void usbtty_init_endpoints (void)
-{
-       int i;
-
-       bus_instance->max_endpoints = NUM_ENDPOINTS + 1;
-       for (i = 1; i <= NUM_ENDPOINTS; i++) {
-               udc_setup_ep (device_instance, i, &endpoint_instance[i]);
-       }
-}
-
-/* usbtty_init_terminal_type
- *
- * Do some late binding for our device type.
- */
-static void usbtty_init_terminal_type(short type)
-{
-       switch(type){
-               /* CDC ACM */
-               case 0:
-                       /* Assign endpoint descriptors */
-                       ep_descriptor_ptrs[0] =
-                               &acm_configuration_descriptors[0].notification_endpoint;
-                       ep_descriptor_ptrs[1] =
-                               &acm_configuration_descriptors[0].data_endpoints[0];
-                       ep_descriptor_ptrs[2] =
-                               &acm_configuration_descriptors[0].data_endpoints[1];
-
-                       /* Enumerate Device Descriptor */
-                       device_descriptor.bDeviceClass =
-                               COMMUNICATIONS_DEVICE_CLASS;
-                       device_descriptor.idProduct =
-                               cpu_to_le16(CONFIG_USBD_PRODUCTID_CDCACM);
-
-                       /* Assign endpoint indices */
-                       tx_endpoint = ACM_TX_ENDPOINT;
-                       rx_endpoint = ACM_RX_ENDPOINT;
-
-                       /* Configuration Descriptor */
-                       configuration_descriptor =
-                               (struct usb_configuration_descriptor*)
-                               &acm_configuration_descriptors;
-
-                       /* Interface count */
-                       interface_count = NUM_ACM_INTERFACES;
-               break;
-
-               /* BULK IN/OUT & Default */
-               case 1:
-               default:
-                       /* Assign endpoint descriptors */
-                       ep_descriptor_ptrs[0] =
-                               &gserial_configuration_descriptors[0].data_endpoints[0];
-                       ep_descriptor_ptrs[1] =
-                               &gserial_configuration_descriptors[0].data_endpoints[1];
-                       ep_descriptor_ptrs[2] =
-                               &gserial_configuration_descriptors[0].data_endpoints[2];
-
-                       /* Enumerate Device Descriptor */
-                       device_descriptor.bDeviceClass = 0xFF;
-                       device_descriptor.idProduct =
-                               cpu_to_le16(CONFIG_USBD_PRODUCTID_GSERIAL);
-
-                       /* Assign endpoint indices */
-                       tx_endpoint = GSERIAL_TX_ENDPOINT;
-                       rx_endpoint = GSERIAL_RX_ENDPOINT;
-
-                       /* Configuration Descriptor */
-                       configuration_descriptor =
-                               (struct usb_configuration_descriptor*)
-                               &gserial_configuration_descriptors;
-
-                       /* Interface count */
-                       interface_count = NUM_GSERIAL_INTERFACES;
-               break;
-       }
-}
-
-/******************************************************************************/
-
-static struct urb *next_urb (struct usb_device_instance *device,
-                            struct usb_endpoint_instance *endpoint)
-{
-       struct urb *current_urb = NULL;
-       int space;
-
-       /* If there's a queue, then we should add to the last urb */
-       if (!endpoint->tx_queue) {
-               current_urb = endpoint->tx_urb;
-       } else {
-               /* Last urb from tx chain */
-               current_urb =
-                       p2surround (struct urb, link, endpoint->tx.prev);
-       }
-
-       /* Make sure this one has enough room */
-       space = current_urb->buffer_length - current_urb->actual_length;
-       if (space > 0) {
-               return current_urb;
-       } else {                /* No space here */
-               /* First look at done list */
-               current_urb = first_urb_detached (&endpoint->done);
-               if (!current_urb) {
-                       current_urb = usbd_alloc_urb (device, endpoint);
-               }
-
-               urb_append (&endpoint->tx, current_urb);
-               endpoint->tx_queue++;
-       }
-       return current_urb;
-}
-
-static int write_buffer (circbuf_t * buf)
-{
-       if (!usbtty_configured ()) {
-               return 0;
-       }
-
-       struct usb_endpoint_instance *endpoint =
-                       &endpoint_instance[tx_endpoint];
-       struct urb *current_urb = NULL;
-
-       current_urb = next_urb (device_instance, endpoint);
-       /* TX data still exists - send it now
-        */
-       if(endpoint->sent < current_urb->actual_length){
-               if(udc_endpoint_write (endpoint)){
-                       /* Write pre-empted by RX */
-                       return -1;
-               }
-       }
-
-       if (buf->size) {
-               char *dest;
-
-               int space_avail;
-               int popnum, popped;
-               int total = 0;
-
-               /* Break buffer into urb sized pieces,
-                * and link each to the endpoint
-                */
-               while (buf->size > 0) {
-
-                       if (!current_urb) {
-                               TTYERR ("current_urb is NULL, buf->size %d\n",
-                                       buf->size);
-                               return total;
-                       }
-
-                       dest = (char*)current_urb->buffer +
-                               current_urb->actual_length;
-
-                       space_avail =
-                               current_urb->buffer_length -
-                               current_urb->actual_length;
-                       popnum = MIN (space_avail, buf->size);
-                       if (popnum == 0)
-                               break;
-
-                       popped = buf_pop (buf, dest, popnum);
-                       if (popped == 0)
-                               break;
-                       current_urb->actual_length += popped;
-                       total += popped;
-
-                       /* If endpoint->last == 0, then transfers have
-                        * not started on this endpoint
-                        */
-                       if (endpoint->last == 0) {
-                               if(udc_endpoint_write (endpoint)){
-                                       /* Write pre-empted by RX */
-                                       return -1;
-                               }
-                       }
-
-               }/* end while */
-               return total;
-       }
-
-       return 0;
-}
-
-static int fill_buffer (circbuf_t * buf)
-{
-       struct usb_endpoint_instance *endpoint =
-               &endpoint_instance[rx_endpoint];
-
-       if (endpoint->rcv_urb && endpoint->rcv_urb->actual_length) {
-               unsigned int nb = 0;
-               char *src = (char *) endpoint->rcv_urb->buffer;
-               unsigned int rx_avail = buf->totalsize - buf->size;
-
-               if(rx_avail >= endpoint->rcv_urb->actual_length){
-
-                       nb = endpoint->rcv_urb->actual_length;
-                       buf_push (buf, src, nb);
-                       endpoint->rcv_urb->actual_length = 0;
-
-               }
-               return nb;
-       }
-       return 0;
-}
-
-static int usbtty_configured (void)
-{
-       return usbtty_configured_flag;
-}
-
-/******************************************************************************/
-
-static void usbtty_event_handler (struct usb_device_instance *device,
-                                 usb_device_event_t event, int data)
-{
-       switch (event) {
-       case DEVICE_RESET:
-       case DEVICE_BUS_INACTIVE:
-               usbtty_configured_flag = 0;
-               break;
-       case DEVICE_CONFIGURED:
-               usbtty_configured_flag = 1;
-               break;
-
-       case DEVICE_ADDRESS_ASSIGNED:
-               usbtty_init_endpoints ();
-
-       default:
-               break;
-       }
-}
-
-/******************************************************************************/
-
-int usbtty_cdc_setup(struct usb_device_request *request, struct urb *urb)
-{
-       switch (request->bRequest){
-
-               case ACM_SET_CONTROL_LINE_STATE:        /* Implies DTE ready */
-                       break;
-               case ACM_SEND_ENCAPSULATED_COMMAND :    /* Required */
-                       break;
-               case ACM_SET_LINE_ENCODING :            /* DTE stop/parity bits
-                                                        * per character */
-                       break;
-               case ACM_GET_ENCAPSULATED_RESPONSE :    /* request response */
-                       break;
-               case ACM_GET_LINE_ENCODING :            /* request DTE rate,
-                                                        * stop/parity bits */
-                       memcpy (urb->buffer , &rs232_desc, sizeof(rs232_desc));
-                       urb->actual_length = sizeof(rs232_desc);
-
-                       break;
-               default:
-                       return 1;
-       }
-       return 0;
-}
-
-/******************************************************************************/
-
-/*
- * Since interrupt handling has not yet been implemented, we use this function
- * to handle polling.  This is called by the tstc,getc,putc,puts routines to
- * update the USB state.
- */
-void usbtty_poll (void)
-{
-       /* New interrupts? */
-       udc_irq();
-
-       /* Write any output data to host buffer
-        * (do this before checking interrupts to avoid missing one)
-        */
-       if (usbtty_configured ()) {
-               write_buffer (&usbtty_output);
-       }
-
-       /* New interrupts? */
-       udc_irq();
-
-       /* Check for new data from host..
-        * (do this after checking interrupts to get latest data)
-        */
-       if (usbtty_configured ()) {
-               fill_buffer (&usbtty_input);
-       }
-
-       /* New interrupts? */
-       udc_irq();
-
-}
-
-
-#endif
diff --git a/drivers/usbtty.h b/drivers/usbtty.h
deleted file mode 100644 (file)
index 8154e30..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * (C) Copyright 2003
- * Gerry Hamel, geh@ti.com, Texas Instruments
- *
- * (C) Copyright 2006
- * Bryan O'Donoghue, bodonoghue@codehermit.ie, CodeHermit
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307         USA
- *
- */
-
-#ifndef __USB_TTY_H__
-#define __USB_TTY_H__
-
-#include "usbdcore.h"
-#if defined(CONFIG_PPC)
-#include "usbdcore_mpc8xx.h"
-#elif defined(CONFIG_ARM)
-#include "usbdcore_omap1510.h"
-#endif
-
-#include <version_autogenerated.h>
-
-/* If no VendorID/ProductID is defined in config.h, pretend to be Linux
- * DO NOT Reuse this Vendor/Product setup with protocol incompatible devices */
-
-#define CONFIG_USBD_VENDORID 0x0525    /* Linux/NetChip */
-#define CONFIG_USBD_PRODUCTID_GSERIAL 0xa4a6   /* gserial */
-#define CONFIG_USBD_PRODUCTID_CDCACM  0xa4a7   /* CDC ACM */
-#define CONFIG_USBD_MANUFACTURER "Das U-Boot"
-#define CONFIG_USBD_PRODUCT_NAME U_BOOT_VERSION
-
-
-#define CONFIG_USBD_CONFIGURATION_STR "TTY via USB"
-
-#define CONFIG_USBD_SERIAL_OUT_ENDPOINT UDC_OUT_ENDPOINT
-#define CONFIG_USBD_SERIAL_OUT_PKTSIZE UDC_OUT_PACKET_SIZE
-#define CONFIG_USBD_SERIAL_IN_ENDPOINT UDC_IN_ENDPOINT
-#define CONFIG_USBD_SERIAL_IN_PKTSIZE  UDC_IN_PACKET_SIZE
-#define CONFIG_USBD_SERIAL_INT_ENDPOINT UDC_INT_ENDPOINT
-#define CONFIG_USBD_SERIAL_INT_PKTSIZE UDC_INT_PACKET_SIZE
-#define CONFIG_USBD_SERIAL_BULK_PKTSIZE        UDC_BULK_PACKET_SIZE
-
-#define USBTTY_DEVICE_CLASS    COMMUNICATIONS_DEVICE_CLASS
-
-#define USBTTY_BCD_DEVICE      0x00
-#define USBTTY_MAXPOWER                0x00
-
-#define STR_LANG               0x00
-#define STR_MANUFACTURER       0x01
-#define STR_PRODUCT            0x02
-#define STR_SERIAL             0x03
-#define STR_CONFIG             0x04
-#define STR_DATA_INTERFACE     0x05
-#define STR_CTRL_INTERFACE     0x06
-#define STR_COUNT              0x07
-
-#endif
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
new file mode 100644 (file)
index 0000000..36611ec
--- /dev/null
@@ -0,0 +1,53 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libvideo.a
+
+COBJS-y += ati_radeon_fb.o
+COBJS-y += cfb_console.o
+COBJS-y += ct69000.o
+COBJS-y += sed13806.o
+COBJS-y += sed156x.o
+COBJS-y += sm501.o
+COBJS-y += smiLynxEM.o
+COBJS-y += videomodes.o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/video/ati_ids.h b/drivers/video/ati_ids.h
new file mode 100644 (file)
index 0000000..3e72a7d
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * ATI PCI IDs from XFree86, kept here to make sync'ing with
+ * XFree much simpler. Currently, this list is only used by
+ * radeonfb
+ */
+
+#define PCI_CHIP_RV380_3150             0x3150
+#define PCI_CHIP_RV380_3151             0x3151
+#define PCI_CHIP_RV380_3152             0x3152
+#define PCI_CHIP_RV380_3153             0x3153
+#define PCI_CHIP_RV380_3154             0x3154
+#define PCI_CHIP_RV380_3156             0x3156
+#define PCI_CHIP_RV380_3E50             0x3E50
+#define PCI_CHIP_RV380_3E51             0x3E51
+#define PCI_CHIP_RV380_3E52             0x3E52
+#define PCI_CHIP_RV380_3E53             0x3E53
+#define PCI_CHIP_RV380_3E54             0x3E54
+#define PCI_CHIP_RV380_3E56             0x3E56
+#define PCI_CHIP_RS100_4136            0x4136
+#define PCI_CHIP_RS200_4137            0x4137
+#define PCI_CHIP_R300_AD               0x4144
+#define PCI_CHIP_R300_AE               0x4145
+#define PCI_CHIP_R300_AF               0x4146
+#define PCI_CHIP_R300_AG               0x4147
+#define PCI_CHIP_R350_AH                0x4148
+#define PCI_CHIP_R350_AI                0x4149
+#define PCI_CHIP_R350_AJ                0x414A
+#define PCI_CHIP_R350_AK                0x414B
+#define PCI_CHIP_RV350_AP               0x4150
+#define PCI_CHIP_RV350_AQ               0x4151
+#define PCI_CHIP_RV360_AR               0x4152
+#define PCI_CHIP_RV350_AS               0x4153
+#define PCI_CHIP_RV350_AT               0x4154
+#define PCI_CHIP_RV350_AV               0x4156
+#define PCI_CHIP_MACH32                0x4158
+#define PCI_CHIP_RS250_4237            0x4237
+#define PCI_CHIP_R200_BB               0x4242
+#define PCI_CHIP_R200_BC               0x4243
+#define PCI_CHIP_RS100_4336            0x4336
+#define PCI_CHIP_RS200_4337            0x4337
+#define PCI_CHIP_MACH64CT              0x4354
+#define PCI_CHIP_MACH64CX              0x4358
+#define PCI_CHIP_RS250_4437            0x4437
+#define PCI_CHIP_MACH64ET              0x4554
+#define PCI_CHIP_MACH64GB              0x4742
+#define PCI_CHIP_MACH64GD              0x4744
+#define PCI_CHIP_MACH64GI              0x4749
+#define PCI_CHIP_MACH64GL              0x474C
+#define PCI_CHIP_MACH64GM              0x474D
+#define PCI_CHIP_MACH64GN              0x474E
+#define PCI_CHIP_MACH64GO              0x474F
+#define PCI_CHIP_MACH64GP              0x4750
+#define PCI_CHIP_MACH64GQ              0x4751
+#define PCI_CHIP_MACH64GR              0x4752
+#define PCI_CHIP_MACH64GS              0x4753
+#define PCI_CHIP_MACH64GT              0x4754
+#define PCI_CHIP_MACH64GU              0x4755
+#define PCI_CHIP_MACH64GV              0x4756
+#define PCI_CHIP_MACH64GW              0x4757
+#define PCI_CHIP_MACH64GX              0x4758
+#define PCI_CHIP_MACH64GY              0x4759
+#define PCI_CHIP_MACH64GZ              0x475A
+#define PCI_CHIP_RV250_Id              0x4964
+#define PCI_CHIP_RV250_Ie              0x4965
+#define PCI_CHIP_RV250_If              0x4966
+#define PCI_CHIP_RV250_Ig              0x4967
+#define PCI_CHIP_R420_JH                0x4A48
+#define PCI_CHIP_R420_JI                0x4A49
+#define PCI_CHIP_R420_JJ                0x4A4A
+#define PCI_CHIP_R420_JK                0x4A4B
+#define PCI_CHIP_R420_JL                0x4A4C
+#define PCI_CHIP_R420_JM                0x4A4D
+#define PCI_CHIP_R420_JN                0x4A4E
+#define PCI_CHIP_R420_JP                0x4A50
+#define PCI_CHIP_MACH64LB              0x4C42
+#define PCI_CHIP_MACH64LD              0x4C44
+#define PCI_CHIP_RAGE128LE             0x4C45
+#define PCI_CHIP_RAGE128LF             0x4C46
+#define PCI_CHIP_MACH64LG              0x4C47
+#define PCI_CHIP_MACH64LI              0x4C49
+#define PCI_CHIP_MACH64LM              0x4C4D
+#define PCI_CHIP_MACH64LN              0x4C4E
+#define PCI_CHIP_MACH64LP              0x4C50
+#define PCI_CHIP_MACH64LQ              0x4C51
+#define PCI_CHIP_MACH64LR              0x4C52
+#define PCI_CHIP_MACH64LS              0x4C53
+#define PCI_CHIP_MACH64LT              0x4C54
+#define PCI_CHIP_RADEON_LW             0x4C57
+#define PCI_CHIP_RADEON_LX             0x4C58
+#define PCI_CHIP_RADEON_LY             0x4C59
+#define PCI_CHIP_RADEON_LZ             0x4C5A
+#define PCI_CHIP_RV250_Ld              0x4C64
+#define PCI_CHIP_RV250_Le              0x4C65
+#define PCI_CHIP_RV250_Lf              0x4C66
+#define PCI_CHIP_RV250_Lg              0x4C67
+#define PCI_CHIP_RV250_Ln              0x4C6E
+#define PCI_CHIP_RAGE128MF             0x4D46
+#define PCI_CHIP_RAGE128ML             0x4D4C
+#define PCI_CHIP_R300_ND               0x4E44
+#define PCI_CHIP_R300_NE               0x4E45
+#define PCI_CHIP_R300_NF               0x4E46
+#define PCI_CHIP_R300_NG               0x4E47
+#define PCI_CHIP_R350_NH                0x4E48
+#define PCI_CHIP_R350_NI                0x4E49
+#define PCI_CHIP_R360_NJ                0x4E4A
+#define PCI_CHIP_R350_NK                0x4E4B
+#define PCI_CHIP_RV350_NP               0x4E50
+#define PCI_CHIP_RV350_NQ               0x4E51
+#define PCI_CHIP_RV350_NR               0x4E52
+#define PCI_CHIP_RV350_NS               0x4E53
+#define PCI_CHIP_RV350_NT               0x4E54
+#define PCI_CHIP_RV350_NV               0x4E56
+#define PCI_CHIP_RAGE128PA             0x5041
+#define PCI_CHIP_RAGE128PB             0x5042
+#define PCI_CHIP_RAGE128PC             0x5043
+#define PCI_CHIP_RAGE128PD             0x5044
+#define PCI_CHIP_RAGE128PE             0x5045
+#define PCI_CHIP_RAGE128PF             0x5046
+#define PCI_CHIP_RAGE128PG             0x5047
+#define PCI_CHIP_RAGE128PH             0x5048
+#define PCI_CHIP_RAGE128PI             0x5049
+#define PCI_CHIP_RAGE128PJ             0x504A
+#define PCI_CHIP_RAGE128PK             0x504B
+#define PCI_CHIP_RAGE128PL             0x504C
+#define PCI_CHIP_RAGE128PM             0x504D
+#define PCI_CHIP_RAGE128PN             0x504E
+#define PCI_CHIP_RAGE128PO             0x504F
+#define PCI_CHIP_RAGE128PP             0x5050
+#define PCI_CHIP_RAGE128PQ             0x5051
+#define PCI_CHIP_RAGE128PR             0x5052
+#define PCI_CHIP_RAGE128PS             0x5053
+#define PCI_CHIP_RAGE128PT             0x5054
+#define PCI_CHIP_RAGE128PU             0x5055
+#define PCI_CHIP_RAGE128PV             0x5056
+#define PCI_CHIP_RAGE128PW             0x5057
+#define PCI_CHIP_RAGE128PX             0x5058
+#define PCI_CHIP_RADEON_QD             0x5144
+#define PCI_CHIP_RADEON_QE             0x5145
+#define PCI_CHIP_RADEON_QF             0x5146
+#define PCI_CHIP_RADEON_QG             0x5147
+#define PCI_CHIP_R200_QH               0x5148
+#define PCI_CHIP_R200_QI               0x5149
+#define PCI_CHIP_R200_QJ               0x514A
+#define PCI_CHIP_R200_QK               0x514B
+#define PCI_CHIP_R200_QL               0x514C
+#define PCI_CHIP_R200_QM               0x514D
+#define PCI_CHIP_R200_QN               0x514E
+#define PCI_CHIP_R200_QO               0x514F
+#define PCI_CHIP_RV200_QW              0x5157
+#define PCI_CHIP_RV200_QX              0x5158
+#define PCI_CHIP_RV100_QY              0x5159
+#define PCI_CHIP_RV100_QZ              0x515A
+#define PCI_CHIP_RN50                  0x515E
+#define PCI_CHIP_RAGE128RE             0x5245
+#define PCI_CHIP_RAGE128RF             0x5246
+#define PCI_CHIP_RAGE128RG             0x5247
+#define PCI_CHIP_RAGE128RK             0x524B
+#define PCI_CHIP_RAGE128RL             0x524C
+#define PCI_CHIP_RAGE128SE             0x5345
+#define PCI_CHIP_RAGE128SF             0x5346
+#define PCI_CHIP_RAGE128SG             0x5347
+#define PCI_CHIP_RAGE128SH             0x5348
+#define PCI_CHIP_RAGE128SK             0x534B
+#define PCI_CHIP_RAGE128SL             0x534C
+#define PCI_CHIP_RAGE128SM             0x534D
+#define PCI_CHIP_RAGE128SN             0x534E
+#define PCI_CHIP_RAGE128TF             0x5446
+#define PCI_CHIP_RAGE128TL             0x544C
+#define PCI_CHIP_RAGE128TR             0x5452
+#define PCI_CHIP_RAGE128TS             0x5453
+#define PCI_CHIP_RAGE128TT             0x5454
+#define PCI_CHIP_RAGE128TU             0x5455
+#define PCI_CHIP_RV370_5460             0x5460
+#define PCI_CHIP_RV370_5461             0x5461
+#define PCI_CHIP_RV370_5462             0x5462
+#define PCI_CHIP_RV370_5463             0x5463
+#define PCI_CHIP_RV370_5464             0x5464
+#define PCI_CHIP_RV370_5465             0x5465
+#define PCI_CHIP_RV370_5466             0x5466
+#define PCI_CHIP_RV370_5467             0x5467
+#define PCI_CHIP_R423_UH                0x5548
+#define PCI_CHIP_R423_UI                0x5549
+#define PCI_CHIP_R423_UJ                0x554A
+#define PCI_CHIP_R423_UK                0x554B
+#define PCI_CHIP_R423_UQ                0x5551
+#define PCI_CHIP_R423_UR                0x5552
+#define PCI_CHIP_R423_UT                0x5554
+#define PCI_CHIP_MACH64VT              0x5654
+#define PCI_CHIP_MACH64VU              0x5655
+#define PCI_CHIP_MACH64VV              0x5656
+#define PCI_CHIP_RS300_5834            0x5834
+#define PCI_CHIP_RS300_5835            0x5835
+#define PCI_CHIP_RS300_5836            0x5836
+#define PCI_CHIP_RS300_5837            0x5837
+#define PCI_CHIP_RV370_5B60             0x5B60
+#define PCI_CHIP_RV370_5B61             0x5B61
+#define PCI_CHIP_RV370_5B62             0x5B62
+#define PCI_CHIP_RV370_5B63             0x5B63
+#define PCI_CHIP_RV370_5B64             0x5B64
+#define PCI_CHIP_RV370_5B65             0x5B65
+#define PCI_CHIP_RV370_5B66             0x5B66
+#define PCI_CHIP_RV370_5B67             0x5B67
+#define PCI_CHIP_RV280_5960            0x5960
+#define PCI_CHIP_RV280_5961            0x5961
+#define PCI_CHIP_RV280_5962            0x5962
+#define PCI_CHIP_RV280_5964            0x5964
+#define PCI_CHIP_RV280_5C61            0x5C61
+#define PCI_CHIP_RV280_5C63            0x5C63
+#define PCI_CHIP_R423_5D57              0x5D57
+#define PCI_CHIP_RS350_7834             0x7834
+#define PCI_CHIP_RS350_7835             0x7835
diff --git a/drivers/video/ati_radeon_fb.c b/drivers/video/ati_radeon_fb.c
new file mode 100644 (file)
index 0000000..0bdaa1c
--- /dev/null
@@ -0,0 +1,488 @@
+/*
+ * ATI Radeon Video card Framebuffer driver.
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc.
+ * Zhang Wei <wei.zhang@freescale.com>
+ * Jason Jin <jason.jin@freescale.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Some codes of this file is partly ported from Linux kernel
+ * ATI video framebuffer driver.
+ *
+ * Now the driver is tested on below ATI chips:
+ *   9200
+ *   X300
+ *   X700
+ *
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_ATI_RADEON_FB
+
+#include <command.h>
+#include <pci.h>
+#include <asm/processor.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <video_fb.h>
+
+#include <radeon.h>
+#include "ati_ids.h"
+#include "ati_radeon_fb.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DPRINT(x...) printf(x)
+#else
+#define DPRINT(x...) do{}while(0)
+#endif
+
+#ifndef min_t
+#define min_t(type,x,y) \
+       ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
+#endif
+
+#define MAX_MAPPED_VRAM        (2048*2048*4)
+#define MIN_MAPPED_VRAM        (1024*768*1)
+
+/*#define PCI_VENDOR_ID_ATI*/
+#define PCI_CHIP_RV280_5960            0x5960
+#define PCI_CHIP_RV280_5961            0x5961
+#define PCI_CHIP_RV280_5962            0x5962
+#define PCI_CHIP_RV280_5964            0x5964
+#define PCI_CHIP_RV370_5B60            0x5B60
+#define PCI_CHIP_RV380_5657            0x5657
+#define PCI_CHIP_R420_554d             0x554d
+
+static struct pci_device_id ati_radeon_pci_ids[] = {
+       {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5960},
+       {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5961},
+       {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5962},
+       {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5964},
+       {PCI_VENDOR_ID_ATI, PCI_CHIP_RV370_5B60},
+       {PCI_VENDOR_ID_ATI, PCI_CHIP_RV380_5657},
+       {PCI_VENDOR_ID_ATI, PCI_CHIP_R420_554d},
+       {0, 0}
+};
+
+static u16 ati_radeon_id_family_table[][2] = {
+       {PCI_CHIP_RV280_5960, CHIP_FAMILY_RV280},
+       {PCI_CHIP_RV280_5961, CHIP_FAMILY_RV280},
+       {PCI_CHIP_RV280_5962, CHIP_FAMILY_RV280},
+       {PCI_CHIP_RV280_5964, CHIP_FAMILY_RV280},
+       {PCI_CHIP_RV370_5B60, CHIP_FAMILY_RV380},
+       {PCI_CHIP_RV380_5657, CHIP_FAMILY_RV380},
+       {PCI_CHIP_R420_554d,  CHIP_FAMILY_R420},
+       {0, 0}
+};
+
+u16 get_radeon_id_family(u16 device)
+{
+       int i;
+       for (i=0; ati_radeon_id_family_table[0][i]; i+=2)
+               if (ati_radeon_id_family_table[0][i] == device)
+                       return ati_radeon_id_family_table[0][i + 1];
+       return 0;
+}
+
+struct radeonfb_info *rinfo;
+
+static void radeon_identify_vram(struct radeonfb_info *rinfo)
+{
+       u32 tmp;
+
+       /* framebuffer size */
+       if ((rinfo->family == CHIP_FAMILY_RS100) ||
+               (rinfo->family == CHIP_FAMILY_RS200) ||
+               (rinfo->family == CHIP_FAMILY_RS300)) {
+               u32 tom = INREG(NB_TOM);
+               tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
+
+               radeon_fifo_wait(6);
+               OUTREG(MC_FB_LOCATION, tom);
+               OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
+               OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
+               OUTREG(OV0_BASE_ADDR, (tom & 0xffff) << 16);
+
+               /* This is supposed to fix the crtc2 noise problem. */
+               OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000);
+
+               if ((rinfo->family == CHIP_FAMILY_RS100) ||
+                       (rinfo->family == CHIP_FAMILY_RS200)) {
+               /* This is to workaround the asic bug for RMX, some versions
+                  of BIOS dosen't have this register initialized correctly.
+               */
+                       OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN,
+                               ~CRTC_H_CUTOFF_ACTIVE_EN);
+               }
+       } else {
+               tmp = INREG(CONFIG_MEMSIZE);
+       }
+
+       /* mem size is bits [28:0], mask off the rest */
+       rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
+
+       /*
+        * Hack to get around some busted production M6's
+        * reporting no ram
+        */
+       if (rinfo->video_ram == 0) {
+               switch (rinfo->pdev.device) {
+               case PCI_CHIP_RADEON_LY:
+               case PCI_CHIP_RADEON_LZ:
+                       rinfo->video_ram = 8192 * 1024;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       /*
+        * Now try to identify VRAM type
+        */
+       if ((rinfo->family >= CHIP_FAMILY_R300) ||
+           (INREG(MEM_SDRAM_MODE_REG) & (1<<30)))
+               rinfo->vram_ddr = 1;
+       else
+               rinfo->vram_ddr = 0;
+
+       tmp = INREG(MEM_CNTL);
+       if (IS_R300_VARIANT(rinfo)) {
+               tmp &=  R300_MEM_NUM_CHANNELS_MASK;
+               switch (tmp) {
+               case 0:  rinfo->vram_width = 64; break;
+               case 1:  rinfo->vram_width = 128; break;
+               case 2:  rinfo->vram_width = 256; break;
+               default: rinfo->vram_width = 128; break;
+               }
+       } else if ((rinfo->family == CHIP_FAMILY_RV100) ||
+                  (rinfo->family == CHIP_FAMILY_RS100) ||
+                  (rinfo->family == CHIP_FAMILY_RS200)){
+               if (tmp & RV100_MEM_HALF_MODE)
+                       rinfo->vram_width = 32;
+               else
+                       rinfo->vram_width = 64;
+       } else {
+               if (tmp & MEM_NUM_CHANNELS_MASK)
+                       rinfo->vram_width = 128;
+               else
+                       rinfo->vram_width = 64;
+       }
+
+       /* This may not be correct, as some cards can have half of channel disabled
+        * ToDo: identify these cases
+        */
+
+       DPRINT("radeonfb: Found %ldk of %s %d bits wide videoram\n",
+              rinfo->video_ram / 1024,
+              rinfo->vram_ddr ? "DDR" : "SDRAM",
+              rinfo->vram_width);
+
+}
+
+static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode)
+{
+       int i;
+
+       radeon_fifo_wait(20);
+
+#if 0
+       /* Workaround from XFree */
+       if (rinfo->is_mobility) {
+               /* A temporal workaround for the occational blanking on certain laptop
+                * panels. This appears to related to the PLL divider registers
+                * (fail to lock?). It occurs even when all dividers are the same
+                * with their old settings. In this case we really don't need to
+                * fiddle with PLL registers. By doing this we can avoid the blanking
+                * problem with some panels.
+                */
+               if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) &&
+                   (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) &
+                                         (PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK)))) {
+                       /* We still have to force a switch to selected PPLL div thanks to
+                        * an XFree86 driver bug which will switch it away in some cases
+                        * even when using UseFDev */
+                       OUTREGP(CLOCK_CNTL_INDEX,
+                               mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
+                               ~PPLL_DIV_SEL_MASK);
+                       radeon_pll_errata_after_index(rinfo);
+                       radeon_pll_errata_after_data(rinfo);
+                       return;
+               }
+       }
+#endif
+       if(rinfo->pdev.device == PCI_CHIP_RV370_5B60) return;
+
+       /* Swich VCKL clock input to CPUCLK so it stays fed while PPLL updates*/
+       OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_CPUCLK, ~VCLK_SRC_SEL_MASK);
+
+       /* Reset PPLL & enable atomic update */
+       OUTPLLP(PPLL_CNTL,
+               PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN,
+               ~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
+
+       /* Switch to selected PPLL divider */
+       OUTREGP(CLOCK_CNTL_INDEX,
+               mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
+               ~PPLL_DIV_SEL_MASK);
+
+       /* Set PPLL ref. div */
+       if (rinfo->family == CHIP_FAMILY_R300 ||
+           rinfo->family == CHIP_FAMILY_RS300 ||
+           rinfo->family == CHIP_FAMILY_R350 ||
+           rinfo->family == CHIP_FAMILY_RV350) {
+               if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
+                       /* When restoring console mode, use saved PPLL_REF_DIV
+                        * setting.
+                        */
+                       OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, 0);
+               } else {
+                       /* R300 uses ref_div_acc field as real ref divider */
+                       OUTPLLP(PPLL_REF_DIV,
+                               (mode->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT),
+                               ~R300_PPLL_REF_DIV_ACC_MASK);
+               }
+       } else
+               OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
+
+       /* Set PPLL divider 3 & post divider*/
+       OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
+       OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
+
+       /* Write update */
+       while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R)
+               ;
+       OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W);
+
+       /* Wait read update complete */
+       /* FIXME: Certain revisions of R300 can't recover here.  Not sure of
+          the cause yet, but this workaround will mask the problem for now.
+          Other chips usually will pass at the very first test, so the
+          workaround shouldn't have any effect on them. */
+       for (i = 0; (i < 10000 && INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); i++)
+               ;
+
+       OUTPLL(HTOTAL_CNTL, 0);
+
+       /* Clear reset & atomic update */
+       OUTPLLP(PPLL_CNTL, 0,
+               ~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
+
+       /* We may want some locking ... oh well */
+       udelay(5000);
+
+       /* Switch back VCLK source to PPLL */
+       OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK);
+}
+
+typedef struct {
+       u16 reg;
+       u32 val;
+} reg_val;
+
+#if 0  /* unused ? -> scheduled for removal */
+/* these common regs are cleared before mode setting so they do not
+ * interfere with anything
+ */
+static reg_val common_regs[] = {
+       { OVR_CLR, 0 },
+       { OVR_WID_LEFT_RIGHT, 0 },
+       { OVR_WID_TOP_BOTTOM, 0 },
+       { OV0_SCALE_CNTL, 0 },
+       { SUBPIC_CNTL, 0 },
+       { VIPH_CONTROL, 0 },
+       { I2C_CNTL_1, 0 },
+       { GEN_INT_CNTL, 0 },
+       { CAP0_TRIG_CNTL, 0 },
+       { CAP1_TRIG_CNTL, 0 },
+};
+#endif /* 0 */
+
+void radeon_setmode(void)
+{
+       struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));
+
+       mode->crtc_gen_cntl = 0x03000200;
+       mode->crtc_ext_cntl = 0x00008048;
+       mode->dac_cntl = 0xff002100;
+       mode->crtc_h_total_disp = 0x4f0063;
+       mode->crtc_h_sync_strt_wid = 0x8c02a2;
+       mode->crtc_v_total_disp = 0x01df020c;
+       mode->crtc_v_sync_strt_wid = 0x8201ea;
+       mode->crtc_pitch = 0x00500050;
+
+       OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
+       OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
+               ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
+       OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
+       OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
+       OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
+       OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
+       OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
+       OUTREG(CRTC_OFFSET, 0);
+       OUTREG(CRTC_OFFSET_CNTL, 0);
+       OUTREG(CRTC_PITCH, mode->crtc_pitch);
+
+       mode->clk_cntl_index = 0x300;
+       mode->ppll_ref_div = 0xc;
+       mode->ppll_div_3 = 0x00030059;
+
+       radeon_write_pll_regs(rinfo, mode);
+}
+
+#include "../bios_emulator/include/biosemu.h"
+extern int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp);
+
+int radeon_probe(struct radeonfb_info *rinfo)
+{
+       pci_dev_t pdev;
+       u16 did;
+
+       pdev = pci_find_devices(ati_radeon_pci_ids, 0);
+
+       if (pdev != -1) {
+               pci_read_config_word(pdev, PCI_DEVICE_ID, &did);
+               printf("ATI Radeon video card (%04x, %04x) found @(%d:%d:%d)\n",
+                               PCI_VENDOR_ID_ATI, did, (pdev >> 16) & 0xff,
+                               (pdev >> 11) & 0x1f, (pdev >> 8) & 0x7);
+
+               strcpy(rinfo->name, "ATI Radeon");
+               rinfo->pdev.vendor = PCI_VENDOR_ID_ATI;
+               rinfo->pdev.device = did;
+               rinfo->family = get_radeon_id_family(rinfo->pdev.device);
+               pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0,
+                               &rinfo->fb_base_phys);
+               pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2,
+                               &rinfo->mmio_base_phys);
+               rinfo->fb_base_phys &= 0xfffff000;
+               rinfo->mmio_base_phys &= ~0x04;
+
+               rinfo->mmio_base = (void *)rinfo->mmio_base_phys;
+               DPRINT("rinfo->mmio_base = 0x%x\n",rinfo->mmio_base);
+               rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
+               DPRINT("rinfo->fb_local_base = 0x%x\n",rinfo->fb_local_base);
+               /* PostBIOS with x86 emulater */
+               BootVideoCardBIOS(pdev, NULL, 0);
+
+               /*
+                * Check for errata
+                * (These will be added in the future for the chipfamily
+                * R300, RV200, RS200, RV100, RS100.)
+                */
+
+               /* Get VRAM size and type */
+               radeon_identify_vram(rinfo);
+
+               rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM,
+                               rinfo->video_ram);
+               rinfo->fb_base = (void *)rinfo->fb_base_phys;
+
+               DPRINT("Radeon: framebuffer base phy address 0x%08x," \
+                     "MMIO base phy address 0x%08x," \
+                     "framebuffer local base 0x%08x.\n ",
+                     rinfo->fb_base_phys, rinfo->mmio_base_phys,
+                     rinfo->fb_local_base);
+
+               return 0;
+       }
+       return -1;
+}
+
+/*
+ * The Graphic Device
+ */
+GraphicDevice ctfb;
+
+#define CURSOR_SIZE    0x1000  /* in KByte for HW Cursor */
+#define PATTERN_ADR    (pGD->dprBase + CURSOR_SIZE)    /* pattern Memory after Cursor Memory */
+#define PATTERN_SIZE   8*8*4   /* 4 Bytes per Pixel 8 x 8 Pixel */
+#define ACCELMEMORY    (CURSOR_SIZE + PATTERN_SIZE)    /* reserved Memory for BITBlt and hw cursor */
+
+void *video_hw_init(void)
+{
+       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+       int i;
+       u32 *vm;
+
+       rinfo = malloc(sizeof(struct radeonfb_info));
+
+       if(radeon_probe(rinfo)) {
+               printf("No radeon video card found!\n");
+               return NULL;
+       }
+
+       /* fill in Graphic device struct */
+       sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", 640,
+                480, 16, (1000 / 1000),
+                (2000 / 1000));
+       printf ("%s\n", pGD->modeIdent);
+
+       pGD->winSizeX = 640;
+       pGD->winSizeY = 480;
+       pGD->plnSizeX = 640;
+       pGD->plnSizeY = 480;
+
+       pGD->gdfBytesPP = 1;
+       pGD->gdfIndex = GDF__8BIT_INDEX;
+
+       pGD->isaBase = CFG_ISA_IO_BASE_ADDRESS;
+       pGD->pciBase = rinfo->fb_base_phys;
+       pGD->frameAdrs = rinfo->fb_base_phys;
+       pGD->memSize = 64 * 1024 * 1024;
+
+       /* Cursor Start Address */
+       pGD->dprBase =
+           (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + rinfo->fb_base_phys;
+       if ((pGD->dprBase & 0x0fff) != 0) {
+               /* allign it */
+               pGD->dprBase &= 0xfffff000;
+               pGD->dprBase += 0x00001000;
+       }
+       DPRINT ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
+               PATTERN_ADR);
+       pGD->vprBase = rinfo->fb_base_phys;     /* Dummy */
+       pGD->cprBase = rinfo->fb_base_phys;     /* Dummy */
+       /* set up Hardware */
+
+       /* Clear video memory */
+       i = pGD->memSize / 4;
+       vm = (unsigned int *) pGD->pciBase;
+       while (i--)
+               *vm++ = 0;
+       /*SetDrawingEngine (bits_per_pixel);*/
+
+       radeon_setmode();
+
+       return ((void *) pGD);
+}
+
+void video_set_lut (unsigned int index,        /* color number */
+              unsigned char r, /* red */
+              unsigned char g, /* green */
+              unsigned char b  /* blue */
+              )
+{
+       OUTREG(PALETTE_INDEX, index);
+       OUTREG(PALETTE_DATA, (r << 16) | (g << 8) | b);
+}
+#endif
diff --git a/drivers/video/ati_radeon_fb.h b/drivers/video/ati_radeon_fb.h
new file mode 100644 (file)
index 0000000..b5c4b8b
--- /dev/null
@@ -0,0 +1,282 @@
+#ifndef __ATI_RADEON_FB_H
+#define __ATI_RADEON_FB_H
+
+/***************************************************************
+ * Most of the definitions here are adapted right from XFree86 *
+ ***************************************************************/
+
+/*
+ * Chip families. Must fit in the low 16 bits of a long word
+ */
+enum radeon_family {
+       CHIP_FAMILY_UNKNOW,
+       CHIP_FAMILY_LEGACY,
+       CHIP_FAMILY_RADEON,
+       CHIP_FAMILY_RV100,
+       CHIP_FAMILY_RS100,    /* U1 (IGP320M) or A3 (IGP320)*/
+       CHIP_FAMILY_RV200,
+       CHIP_FAMILY_RS200,    /* U2 (IGP330M/340M/350M) or A4 (IGP330/340/345/350),
+                                RS250 (IGP 7000) */
+       CHIP_FAMILY_R200,
+       CHIP_FAMILY_RV250,
+       CHIP_FAMILY_RS300,    /* Radeon 9000 IGP */
+       CHIP_FAMILY_RV280,
+       CHIP_FAMILY_R300,
+       CHIP_FAMILY_R350,
+       CHIP_FAMILY_RV350,
+       CHIP_FAMILY_RV380,    /* RV370/RV380/M22/M24 */
+       CHIP_FAMILY_R420,     /* R420/R423/M18 */
+       CHIP_FAMILY_LAST,
+};
+
+#define IS_RV100_VARIANT(rinfo) (((rinfo)->family == CHIP_FAMILY_RV100)  || \
+                                ((rinfo)->family == CHIP_FAMILY_RV200)  || \
+                                ((rinfo)->family == CHIP_FAMILY_RS100)  || \
+                                ((rinfo)->family == CHIP_FAMILY_RS200)  || \
+                                ((rinfo)->family == CHIP_FAMILY_RV250)  || \
+                                ((rinfo)->family == CHIP_FAMILY_RV280)  || \
+                                ((rinfo)->family == CHIP_FAMILY_RS300))
+
+#define IS_R300_VARIANT(rinfo) (((rinfo)->family == CHIP_FAMILY_R300)  || \
+                               ((rinfo)->family == CHIP_FAMILY_RV350) || \
+                               ((rinfo)->family == CHIP_FAMILY_R350)  || \
+                               ((rinfo)->family == CHIP_FAMILY_RV380) || \
+                               ((rinfo)->family == CHIP_FAMILY_R420))
+
+struct radeonfb_info {
+       char name[20];
+
+       struct pci_device_id    pdev;
+       u16                     family;
+
+       u32                     fb_base_phys;
+       u32                     mmio_base_phys;
+
+       void                    *mmio_base;
+       void                    *fb_base;
+
+       u32                     video_ram;
+       u32                     mapped_vram;
+       int                     vram_width;
+       int                     vram_ddr;
+
+       u32                     fb_local_base;
+};
+
+#define INREG8(addr)           readb((rinfo->mmio_base)+addr)
+#define OUTREG8(addr,val)      writeb(val, (rinfo->mmio_base)+addr)
+#define INREG16(addr)          readw((rinfo->mmio_base)+addr)
+#define OUTREG16(addr,val)     writew(val, (rinfo->mmio_base)+addr)
+#define INREG(addr)            readl((rinfo->mmio_base)+addr)
+#define OUTREG(addr,val)       writel(val, (rinfo->mmio_base)+addr)
+
+static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr,
+                      u32 val, u32 mask)
+{
+       unsigned int tmp;
+
+       tmp = INREG(addr);
+       tmp &= (mask);
+       tmp |= (val);
+       OUTREG(addr, tmp);
+}
+
+#define OUTREGP(addr,val,mask) _OUTREGP(rinfo, addr, val,mask)
+
+/*
+ * 2D Engine helper routines
+ */
+static inline void radeon_engine_flush (struct radeonfb_info *rinfo)
+{
+       int i;
+
+       /* initiate flush */
+       OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
+               ~RB2D_DC_FLUSH_ALL);
+
+       for (i=0; i < 2000000; i++) {
+               if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
+                       return;
+               udelay(1);
+       }
+       printf("radeonfb: Flush Timeout !\n");
+}
+
+static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries)
+{
+       int i;
+
+       for (i=0; i<2000000; i++) {
+               if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
+                       return;
+               udelay(1);
+       }
+       printf("radeonfb: FIFO Timeout !\n");
+}
+
+static inline void _radeon_engine_idle(struct radeonfb_info *rinfo)
+{
+       int i;
+
+       /* ensure FIFO is empty before waiting for idle */
+       _radeon_fifo_wait (rinfo, 64);
+
+       for (i=0; i<2000000; i++) {
+               if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
+                       radeon_engine_flush (rinfo);
+                       return;
+               }
+               udelay(1);
+       }
+       printf("radeonfb: Idle Timeout !\n");
+}
+
+#define radeon_engine_idle()           _radeon_engine_idle(rinfo)
+#define radeon_fifo_wait(entries)      _radeon_fifo_wait(rinfo,entries)
+#define radeon_msleep(ms)              _radeon_msleep(rinfo,ms)
+
+/*
+ * This structure contains the various registers manipulated by this
+ * driver for setting or restoring a mode. It's mostly copied from
+ * XFree's RADEONSaveRec structure. A few chip settings might still be
+ * tweaked without beeing reflected or saved in these registers though
+ */
+struct radeon_regs {
+       /* Common registers */
+       u32             ovr_clr;
+       u32             ovr_wid_left_right;
+       u32             ovr_wid_top_bottom;
+       u32             ov0_scale_cntl;
+       u32             mpp_tb_config;
+       u32             mpp_gp_config;
+       u32             subpic_cntl;
+       u32             viph_control;
+       u32             i2c_cntl_1;
+       u32             gen_int_cntl;
+       u32             cap0_trig_cntl;
+       u32             cap1_trig_cntl;
+       u32             bus_cntl;
+       u32             surface_cntl;
+       u32             bios_5_scratch;
+
+       /* Other registers to save for VT switches or driver load/unload */
+       u32             dp_datatype;
+       u32             rbbm_soft_reset;
+       u32             clock_cntl_index;
+       u32             amcgpio_en_reg;
+       u32             amcgpio_mask;
+
+       /* Surface/tiling registers */
+       u32             surf_lower_bound[8];
+       u32             surf_upper_bound[8];
+       u32             surf_info[8];
+
+       /* CRTC registers */
+       u32             crtc_gen_cntl;
+       u32             crtc_ext_cntl;
+       u32             dac_cntl;
+       u32             crtc_h_total_disp;
+       u32             crtc_h_sync_strt_wid;
+       u32             crtc_v_total_disp;
+       u32             crtc_v_sync_strt_wid;
+       u32             crtc_offset;
+       u32             crtc_offset_cntl;
+       u32             crtc_pitch;
+       u32             disp_merge_cntl;
+       u32             grph_buffer_cntl;
+       u32             crtc_more_cntl;
+
+       /* CRTC2 registers */
+       u32             crtc2_gen_cntl;
+       u32             dac2_cntl;
+       u32             disp_output_cntl;
+       u32             disp_hw_debug;
+       u32             disp2_merge_cntl;
+       u32             grph2_buffer_cntl;
+       u32             crtc2_h_total_disp;
+       u32             crtc2_h_sync_strt_wid;
+       u32             crtc2_v_total_disp;
+       u32             crtc2_v_sync_strt_wid;
+       u32             crtc2_offset;
+       u32             crtc2_offset_cntl;
+       u32             crtc2_pitch;
+
+       /* Flat panel regs */
+       u32             fp_crtc_h_total_disp;
+       u32             fp_crtc_v_total_disp;
+       u32             fp_gen_cntl;
+       u32             fp2_gen_cntl;
+       u32             fp_h_sync_strt_wid;
+       u32             fp2_h_sync_strt_wid;
+       u32             fp_horz_stretch;
+       u32             fp_panel_cntl;
+       u32             fp_v_sync_strt_wid;
+       u32             fp2_v_sync_strt_wid;
+       u32             fp_vert_stretch;
+       u32             lvds_gen_cntl;
+       u32             lvds_pll_cntl;
+       u32             tmds_crc;
+       u32             tmds_transmitter_cntl;
+
+       /* Computed values for PLL */
+       u32             dot_clock_freq;
+       int             feedback_div;
+       int             post_div;
+
+       /* PLL registers */
+       u32             ppll_div_3;
+       u32             ppll_ref_div;
+       u32             vclk_ecp_cntl;
+       u32             clk_cntl_index;
+
+       /* Computed values for PLL2 */
+       u32             dot_clock_freq_2;
+       int             feedback_div_2;
+       int             post_div_2;
+
+       /* PLL2 registers */
+       u32             p2pll_ref_div;
+       u32             p2pll_div_0;
+       u32             htotal_cntl2;
+
+       /* Palette */
+       int             palette_valid;
+};
+
+static inline u32 __INPLL(struct radeonfb_info *rinfo, u32 addr)
+{
+       u32 data;
+
+       OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f);
+       /* radeon_pll_errata_after_index(rinfo); */
+       data = INREG(CLOCK_CNTL_DATA);
+       /* radeon_pll_errata_after_data(rinfo); */
+       return data;
+}
+
+static inline void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index,
+                           u32 val)
+{
+
+       OUTREG8(CLOCK_CNTL_INDEX, (index & 0x0000003f) | 0x00000080);
+       /* radeon_pll_errata_after_index(rinfo); */
+       OUTREG(CLOCK_CNTL_DATA, val);
+       /* radeon_pll_errata_after_data(rinfo); */
+}
+
+static inline void __OUTPLLP(struct radeonfb_info *rinfo, unsigned int index,
+                            u32 val, u32 mask)
+{
+       unsigned int tmp;
+
+       tmp  = __INPLL(rinfo, index);
+       tmp &= (mask);
+       tmp |= (val);
+       __OUTPLL(rinfo, index, tmp);
+}
+
+#define INPLL(addr)                    __INPLL(rinfo, addr)
+#define OUTPLL(index, val)             __OUTPLL(rinfo, index, val)
+#define OUTPLLP(index, val, mask)      __OUTPLLP(rinfo, index, val, mask)
+
+#endif
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
new file mode 100644 (file)
index 0000000..bcf8771
--- /dev/null
@@ -0,0 +1,1274 @@
+/*
+ * (C) Copyright 2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * cfb_console.c
+ *
+ * Color Framebuffer Console driver for 8/15/16/24/32 bits per pixel.
+ *
+ * At the moment only the 8x16 font is tested and the font fore- and
+ * background color is limited to black/white/gray colors. The Linux
+ * logo can be placed in the upper left corner and additional board
+ * information strings (that normaly goes to serial port) can be drawed.
+ *
+ * The console driver can use the standard PC keyboard interface (i8042)
+ * for character input. Character output goes to a memory mapped video
+ * framebuffer with little or big-endian organisation.
+ * With environment setting 'console=serial' the console i/o can be
+ * forced to serial port.
+
+ The driver uses graphic specific defines/parameters/functions:
+
+ (for SMI LynxE graphic chip)
+
+ CONFIG_VIDEO_SMI_LYNXEM - use graphic driver for SMI 710,712,810
+ VIDEO_FB_LITTLE_ENDIAN         - framebuffer organisation default: big endian
+ VIDEO_HW_RECTFILL      - graphic driver supports hardware rectangle fill
+ VIDEO_HW_BITBLT        - graphic driver supports hardware bit blt
+
+ Console Parameters are set by graphic drivers global struct:
+
+ VIDEO_VISIBLE_COLS         - x resolution
+ VIDEO_VISIBLE_ROWS         - y resolution
+ VIDEO_PIXEL_SIZE           - storage size in byte per pixel
+ VIDEO_DATA_FORMAT          - graphical data format GDF
+ VIDEO_FB_ADRS              - start of video memory
+
+ CONFIG_I8042_KBD           - AT Keyboard driver for i8042
+ VIDEO_KBD_INIT_FCT         - init function for keyboard
+ VIDEO_TSTC_FCT                     - keyboard_tstc function
+ VIDEO_GETC_FCT                     - keyboard_getc function
+
+ CONFIG_CONSOLE_CURSOR      - on/off drawing cursor is done with delay
+                              loop in VIDEO_TSTC_FCT (i8042)
+ CFG_CONSOLE_BLINK_COUNT     - value for delay loop - blink rate
+ CONFIG_CONSOLE_TIME        - display time/date in upper right corner,
+                              needs CONFIG_CMD_DATE and CONFIG_CONSOLE_CURSOR
+ CONFIG_VIDEO_LOGO          - display Linux Logo in upper left corner
+ CONFIG_VIDEO_BMP_LOGO      - use bmp_logo instead of linux_logo
+ CONFIG_CONSOLE_EXTRA_INFO   - display additional board information strings
+                              that normaly goes to serial port. This define
+                              requires a board specific function:
+                              video_drawstring (VIDEO_INFO_X,
+                                                VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT,
+                                                info);
+                              that fills a info buffer at i=row.
+                              s.a: board/eltec/bab7xx.
+CONFIG_VGA_AS_SINGLE_DEVICE  - If set the framebuffer device will be initialised
+                              as an output only device. The Keyboard driver
+                              will not be set-up. This may be used, if you
+                              have none or more than one Keyboard devices
+                              (USB Keyboard, AT Keyboard).
+
+CONFIG_VIDEO_SW_CURSOR:             - Draws a cursor after the last character. No
+                              blinking is provided. Uses the macros CURSOR_SET
+                              and CURSOR_OFF.
+CONFIG_VIDEO_HW_CURSOR:             - Uses the hardware cursor capability of the
+                              graphic chip. Uses the macro CURSOR_SET.
+                              ATTENTION: If booting an OS, the display driver
+                              must disable the hardware register of the graphic
+                              chip. Otherwise a blinking field is displayed
+*/
+
+#include <common.h>
+
+#ifdef CONFIG_CFB_CONSOLE
+
+#include <malloc.h>
+
+/*****************************************************************************/
+/* Console device defines with SMI graphic                                  */
+/* Any other graphic must change this section                               */
+/*****************************************************************************/
+
+#ifdef CONFIG_VIDEO_SMI_LYNXEM
+
+#define VIDEO_FB_LITTLE_ENDIAN
+#define VIDEO_HW_RECTFILL
+#define VIDEO_HW_BITBLT
+#endif
+
+/*****************************************************************************/
+/* Defines for the CT69000 driver                                           */
+/*****************************************************************************/
+#ifdef CONFIG_VIDEO_CT69000
+
+#define VIDEO_FB_LITTLE_ENDIAN
+#define VIDEO_HW_RECTFILL
+#define VIDEO_HW_BITBLT
+#endif
+
+/*****************************************************************************/
+/* Defines for the SED13806 driver                                          */
+/*****************************************************************************/
+#ifdef CONFIG_VIDEO_SED13806
+
+#ifndef CONFIG_TOTAL5200
+#define VIDEO_FB_LITTLE_ENDIAN
+#endif
+#define VIDEO_HW_RECTFILL
+#define VIDEO_HW_BITBLT
+#endif
+
+/*****************************************************************************/
+/* Defines for the SED13806 driver                                          */
+/*****************************************************************************/
+#ifdef CONFIG_VIDEO_SM501
+
+#ifdef CONFIG_HH405
+#define VIDEO_FB_LITTLE_ENDIAN
+#endif
+#endif
+
+/*****************************************************************************/
+/* Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc            */
+/*****************************************************************************/
+#include <video_fb.h>
+
+/*****************************************************************************/
+/* some Macros                                                              */
+/*****************************************************************************/
+#define VIDEO_VISIBLE_COLS     (pGD->winSizeX)
+#define VIDEO_VISIBLE_ROWS     (pGD->winSizeY)
+#define VIDEO_PIXEL_SIZE       (pGD->gdfBytesPP)
+#define VIDEO_DATA_FORMAT      (pGD->gdfIndex)
+#define VIDEO_FB_ADRS          (pGD->frameAdrs)
+
+/*****************************************************************************/
+/* Console device defines with i8042 keyboard controller                    */
+/* Any other keyboard controller must change this section                   */
+/*****************************************************************************/
+
+#ifdef CONFIG_I8042_KBD
+#include <i8042.h>
+
+#define VIDEO_KBD_INIT_FCT     i8042_kbd_init()
+#define VIDEO_TSTC_FCT         i8042_tstc
+#define VIDEO_GETC_FCT         i8042_getc
+#endif
+
+/*****************************************************************************/
+/* Console device                                                           */
+/*****************************************************************************/
+
+#include <version.h>
+#include <linux/types.h>
+#include <devices.h>
+#include <video_font.h>
+
+#if defined(CONFIG_CMD_DATE)
+#include <rtc.h>
+#endif
+
+#if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
+#include <watchdog.h>
+#include <bmp_layout.h>
+#endif
+
+/*****************************************************************************/
+/* Cursor definition:                                                       */
+/* CONFIG_CONSOLE_CURSOR:  Uses a timer function (see drivers/i8042.c) to    */
+/*                        let the cursor blink. Uses the macros CURSOR_OFF  */
+/*                        and CURSOR_ON.                                    */
+/* CONFIG_VIDEO_SW_CURSOR: Draws a cursor after the last character. No      */
+/*                        blinking is provided. Uses the macros CURSOR_SET  */
+/*                        and CURSOR_OFF.                                   */
+/* CONFIG_VIDEO_HW_CURSOR: Uses the hardware cursor capability of the       */
+/*                        graphic chip. Uses the macro CURSOR_SET.          */
+/*                        ATTENTION: If booting an OS, the display driver   */
+/*                        must disable the hardware register of the graphic */
+/*                        chip. Otherwise a blinking field is displayed     */
+/*****************************************************************************/
+#if !defined(CONFIG_CONSOLE_CURSOR) && \
+    !defined(CONFIG_VIDEO_SW_CURSOR) && \
+    !defined(CONFIG_VIDEO_HW_CURSOR)
+/* no Cursor defined */
+#define CURSOR_ON
+#define CURSOR_OFF
+#define CURSOR_SET
+#endif
+
+#ifdef CONFIG_CONSOLE_CURSOR
+#ifdef CURSOR_ON
+#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
+#endif
+void   console_cursor (int state);
+#define CURSOR_ON  console_cursor(1);
+#define CURSOR_OFF console_cursor(0);
+#define CURSOR_SET
+#ifndef CONFIG_I8042_KBD
+#warning Cursor drawing on/off needs timer function s.a. drivers/i8042.c
+#endif
+#else
+#ifdef CONFIG_CONSOLE_TIME
+#error CONFIG_CONSOLE_CURSOR must be defined for CONFIG_CONSOLE_TIME
+#endif
+#endif /* CONFIG_CONSOLE_CURSOR */
+
+#ifdef CONFIG_VIDEO_SW_CURSOR
+#ifdef CURSOR_ON
+#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
+#endif
+#define CURSOR_ON
+#define CURSOR_OFF video_putchar(console_col * VIDEO_FONT_WIDTH,\
+                                console_row * VIDEO_FONT_HEIGHT, ' ');
+#define CURSOR_SET video_set_cursor();
+#endif /* CONFIG_VIDEO_SW_CURSOR */
+
+
+#ifdef CONFIG_VIDEO_HW_CURSOR
+#ifdef CURSOR_ON
+#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
+#endif
+#define CURSOR_ON
+#define CURSOR_OFF
+#define CURSOR_SET video_set_hw_cursor(console_col * VIDEO_FONT_WIDTH, \
+                 (console_row * VIDEO_FONT_HEIGHT) + VIDEO_LOGO_HEIGHT);
+#endif /* CONFIG_VIDEO_HW_CURSOR */
+
+#ifdef CONFIG_VIDEO_LOGO
+#ifdef CONFIG_VIDEO_BMP_LOGO
+#include <bmp_logo.h>
+#define VIDEO_LOGO_WIDTH       BMP_LOGO_WIDTH
+#define VIDEO_LOGO_HEIGHT      BMP_LOGO_HEIGHT
+#define VIDEO_LOGO_LUT_OFFSET  BMP_LOGO_OFFSET
+#define VIDEO_LOGO_COLORS      BMP_LOGO_COLORS
+
+#else  /* CONFIG_VIDEO_BMP_LOGO */
+#define LINUX_LOGO_WIDTH       80
+#define LINUX_LOGO_HEIGHT      80
+#define LINUX_LOGO_COLORS      214
+#define LINUX_LOGO_LUT_OFFSET  0x20
+#define __initdata
+#include <linux_logo.h>
+#define VIDEO_LOGO_WIDTH       LINUX_LOGO_WIDTH
+#define VIDEO_LOGO_HEIGHT      LINUX_LOGO_HEIGHT
+#define VIDEO_LOGO_LUT_OFFSET  LINUX_LOGO_LUT_OFFSET
+#define VIDEO_LOGO_COLORS      LINUX_LOGO_COLORS
+#endif /* CONFIG_VIDEO_BMP_LOGO */
+#define VIDEO_INFO_X           (VIDEO_LOGO_WIDTH)
+#define VIDEO_INFO_Y           (VIDEO_FONT_HEIGHT/2)
+#else  /* CONFIG_VIDEO_LOGO */
+#define VIDEO_LOGO_WIDTH       0
+#define VIDEO_LOGO_HEIGHT      0
+#endif /* CONFIG_VIDEO_LOGO */
+
+#define VIDEO_COLS             VIDEO_VISIBLE_COLS
+#define VIDEO_ROWS             VIDEO_VISIBLE_ROWS
+#define VIDEO_SIZE             (VIDEO_ROWS*VIDEO_COLS*VIDEO_PIXEL_SIZE)
+#define VIDEO_PIX_BLOCKS       (VIDEO_SIZE >> 2)
+#define VIDEO_LINE_LEN         (VIDEO_COLS*VIDEO_PIXEL_SIZE)
+#define VIDEO_BURST_LEN                (VIDEO_COLS/8)
+
+#ifdef CONFIG_VIDEO_LOGO
+#define CONSOLE_ROWS           ((VIDEO_ROWS - VIDEO_LOGO_HEIGHT) / VIDEO_FONT_HEIGHT)
+#else
+#define CONSOLE_ROWS           (VIDEO_ROWS / VIDEO_FONT_HEIGHT)
+#endif
+
+#define CONSOLE_COLS           (VIDEO_COLS / VIDEO_FONT_WIDTH)
+#define CONSOLE_ROW_SIZE       (VIDEO_FONT_HEIGHT * VIDEO_LINE_LEN)
+#define CONSOLE_ROW_FIRST      (video_console_address)
+#define CONSOLE_ROW_SECOND     (video_console_address + CONSOLE_ROW_SIZE)
+#define CONSOLE_ROW_LAST       (video_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE)
+#define CONSOLE_SIZE           (CONSOLE_ROW_SIZE * CONSOLE_ROWS)
+#define CONSOLE_SCROLL_SIZE    (CONSOLE_SIZE - CONSOLE_ROW_SIZE)
+
+/* Macros */
+#ifdef VIDEO_FB_LITTLE_ENDIAN
+#define SWAP16(x)       ((((x) & 0x00ff) << 8) | ( (x) >> 8))
+#define SWAP32(x)       ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\
+                         (((x) & 0x00ff0000) >>  8) | (((x) & 0xff000000) >> 24) )
+#define SHORTSWAP32(x)  ((((x) & 0x000000ff) <<  8) | (((x) & 0x0000ff00) >> 8)|\
+                         (((x) & 0x00ff0000) <<  8) | (((x) & 0xff000000) >> 8) )
+#else
+#define SWAP16(x)       (x)
+#define SWAP32(x)       (x)
+#define SHORTSWAP32(x)  (x)
+#endif
+
+#if defined(DEBUG) || defined(DEBUG_CFB_CONSOLE)
+#define PRINTD(x)        printf(x)
+#else
+#define PRINTD(x)
+#endif
+
+
+#ifdef CONFIG_CONSOLE_EXTRA_INFO
+extern void video_get_info_str (    /* setup a board string: type, speed, etc. */
+    int line_number,       /* location to place info string beside logo */
+    char *info             /* buffer for info string */
+    );
+
+#endif
+
+/* Locals */
+static GraphicDevice *pGD;     /* Pointer to Graphic array */
+
+static void *video_fb_address;         /* frame buffer address */
+static void *video_console_address;    /* console buffer start address */
+
+static int console_col = 0; /* cursor col */
+static int console_row = 0; /* cursor row */
+
+static u32 eorx, fgx, bgx;  /* color pats */
+
+static const int video_font_draw_table8[] = {
+           0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
+           0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
+           0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
+           0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff };
+
+static const int video_font_draw_table15[] = {
+           0x00000000, 0x00007fff, 0x7fff0000, 0x7fff7fff };
+
+static const int video_font_draw_table16[] = {
+           0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff };
+
+static const int video_font_draw_table24[16][3] = {
+           { 0x00000000, 0x00000000, 0x00000000 },
+           { 0x00000000, 0x00000000, 0x00ffffff },
+           { 0x00000000, 0x0000ffff, 0xff000000 },
+           { 0x00000000, 0x0000ffff, 0xffffffff },
+           { 0x000000ff, 0xffff0000, 0x00000000 },
+           { 0x000000ff, 0xffff0000, 0x00ffffff },
+           { 0x000000ff, 0xffffffff, 0xff000000 },
+           { 0x000000ff, 0xffffffff, 0xffffffff },
+           { 0xffffff00, 0x00000000, 0x00000000 },
+           { 0xffffff00, 0x00000000, 0x00ffffff },
+           { 0xffffff00, 0x0000ffff, 0xff000000 },
+           { 0xffffff00, 0x0000ffff, 0xffffffff },
+           { 0xffffffff, 0xffff0000, 0x00000000 },
+           { 0xffffffff, 0xffff0000, 0x00ffffff },
+           { 0xffffffff, 0xffffffff, 0xff000000 },
+           { 0xffffffff, 0xffffffff, 0xffffffff } };
+
+static const int video_font_draw_table32[16][4] = {
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+           { 0x00000000, 0x00000000, 0x00000000, 0x00ffffff },
+           { 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 },
+           { 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff },
+           { 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 },
+           { 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff },
+           { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 },
+           { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff },
+           { 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 },
+           { 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff },
+           { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 },
+           { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff },
+           { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 },
+           { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff },
+           { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 },
+           { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff } };
+
+
+int gunzip(void *, int, unsigned char *, unsigned long *);
+
+/******************************************************************************/
+
+static void video_drawchars (int xx, int yy, unsigned char *s, int count)
+{
+       u8 *cdat, *dest, *dest0;
+       int rows, offset, c;
+
+       offset = yy * VIDEO_LINE_LEN + xx * VIDEO_PIXEL_SIZE;
+       dest0 = video_fb_address + offset;
+
+       switch (VIDEO_DATA_FORMAT) {
+       case GDF__8BIT_INDEX:
+       case GDF__8BIT_332RGB:
+               while (count--) {
+                       c = *s;
+                       cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+                       for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
+                            rows--;
+                            dest += VIDEO_LINE_LEN) {
+                               u8 bits = *cdat++;
+
+                               ((u32 *) dest)[0] = (video_font_draw_table8[bits >> 4] & eorx) ^ bgx;
+                               ((u32 *) dest)[1] = (video_font_draw_table8[bits & 15] & eorx) ^ bgx;
+                       }
+                       dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+                       s++;
+               }
+               break;
+
+       case GDF_15BIT_555RGB:
+               while (count--) {
+                       c = *s;
+                       cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+                       for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
+                            rows--;
+                            dest += VIDEO_LINE_LEN) {
+                               u8 bits = *cdat++;
+
+                               ((u32 *) dest)[0] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 6] & eorx) ^ bgx);
+                               ((u32 *) dest)[1] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 4 & 3] & eorx) ^ bgx);
+                               ((u32 *) dest)[2] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 2 & 3] & eorx) ^ bgx);
+                               ((u32 *) dest)[3] = SHORTSWAP32 ((video_font_draw_table15 [bits & 3] & eorx) ^ bgx);
+                       }
+                       dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+                       s++;
+               }
+               break;
+
+       case GDF_16BIT_565RGB:
+               while (count--) {
+                       c = *s;
+                       cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+                       for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
+                            rows--;
+                            dest += VIDEO_LINE_LEN) {
+                               u8 bits = *cdat++;
+
+                               ((u32 *) dest)[0] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 6] & eorx) ^ bgx);
+                               ((u32 *) dest)[1] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 4 & 3] & eorx) ^ bgx);
+                               ((u32 *) dest)[2] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 2 & 3] & eorx) ^ bgx);
+                               ((u32 *) dest)[3] = SHORTSWAP32 ((video_font_draw_table16 [bits & 3] & eorx) ^ bgx);
+                       }
+                       dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+                       s++;
+               }
+               break;
+
+       case GDF_32BIT_X888RGB:
+               while (count--) {
+                       c = *s;
+                       cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+                       for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
+                            rows--;
+                            dest += VIDEO_LINE_LEN) {
+                               u8 bits = *cdat++;
+
+                               ((u32 *) dest)[0] = SWAP32 ((video_font_draw_table32 [bits >> 4][0] & eorx) ^ bgx);
+                               ((u32 *) dest)[1] = SWAP32 ((video_font_draw_table32 [bits >> 4][1] & eorx) ^ bgx);
+                               ((u32 *) dest)[2] = SWAP32 ((video_font_draw_table32 [bits >> 4][2] & eorx) ^ bgx);
+                               ((u32 *) dest)[3] = SWAP32 ((video_font_draw_table32 [bits >> 4][3] & eorx) ^ bgx);
+                               ((u32 *) dest)[4] = SWAP32 ((video_font_draw_table32 [bits & 15][0] & eorx) ^ bgx);
+                               ((u32 *) dest)[5] = SWAP32 ((video_font_draw_table32 [bits & 15][1] & eorx) ^ bgx);
+                               ((u32 *) dest)[6] = SWAP32 ((video_font_draw_table32 [bits & 15][2] & eorx) ^ bgx);
+                               ((u32 *) dest)[7] = SWAP32 ((video_font_draw_table32 [bits & 15][3] & eorx) ^ bgx);
+                       }
+                       dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+                       s++;
+               }
+               break;
+
+       case GDF_24BIT_888RGB:
+               while (count--) {
+                       c = *s;
+                       cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+                       for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
+                            rows--;
+                            dest += VIDEO_LINE_LEN) {
+                               u8 bits = *cdat++;
+
+                               ((u32 *) dest)[0] = (video_font_draw_table24[bits >> 4][0] & eorx) ^ bgx;
+                               ((u32 *) dest)[1] = (video_font_draw_table24[bits >> 4][1] & eorx) ^ bgx;
+                               ((u32 *) dest)[2] = (video_font_draw_table24[bits >> 4][2] & eorx) ^ bgx;
+                               ((u32 *) dest)[3] = (video_font_draw_table24[bits & 15][0] & eorx) ^ bgx;
+                               ((u32 *) dest)[4] = (video_font_draw_table24[bits & 15][1] & eorx) ^ bgx;
+                               ((u32 *) dest)[5] = (video_font_draw_table24[bits & 15][2] & eorx) ^ bgx;
+                       }
+                       dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+                       s++;
+               }
+               break;
+       }
+}
+
+/*****************************************************************************/
+
+static inline void video_drawstring (int xx, int yy, unsigned char *s)
+{
+       video_drawchars (xx, yy, s, strlen ((char *)s));
+}
+
+/*****************************************************************************/
+
+static void video_putchar (int xx, int yy, unsigned char c)
+{
+       video_drawchars (xx, yy + VIDEO_LOGO_HEIGHT, &c, 1);
+}
+
+/*****************************************************************************/
+#if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
+static void video_set_cursor (void)
+{
+       /* swap drawing colors */
+       eorx = fgx;
+       fgx = bgx;
+       bgx = eorx;
+       eorx = fgx ^ bgx;
+       /* draw cursor */
+       video_putchar (console_col * VIDEO_FONT_WIDTH,
+                      console_row * VIDEO_FONT_HEIGHT,
+                      ' ');
+       /* restore drawing colors */
+       eorx = fgx;
+       fgx = bgx;
+       bgx = eorx;
+       eorx = fgx ^ bgx;
+}
+#endif
+/*****************************************************************************/
+#ifdef CONFIG_CONSOLE_CURSOR
+void console_cursor (int state)
+{
+       static int last_state = 0;
+
+#ifdef CONFIG_CONSOLE_TIME
+       struct rtc_time tm;
+       char info[16];
+
+       /* time update only if cursor is on (faster scroll) */
+       if (state) {
+               rtc_get (&tm);
+
+               sprintf (info, " %02d:%02d:%02d ", tm.tm_hour, tm.tm_min,
+                        tm.tm_sec);
+               video_drawstring (VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH,
+                                 VIDEO_INFO_Y, (uchar *)info);
+
+               sprintf (info, "%02d.%02d.%04d", tm.tm_mday, tm.tm_mon,
+                        tm.tm_year);
+               video_drawstring (VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH,
+                                 VIDEO_INFO_Y + 1 * VIDEO_FONT_HEIGHT, (uchar *)info);
+       }
+#endif
+
+       if (state && (last_state != state)) {
+               video_set_cursor ();
+       }
+
+       if (!state && (last_state != state)) {
+               /* clear cursor */
+               video_putchar (console_col * VIDEO_FONT_WIDTH,
+                              console_row * VIDEO_FONT_HEIGHT,
+                              ' ');
+       }
+
+       last_state = state;
+}
+#endif
+
+/*****************************************************************************/
+
+#ifndef VIDEO_HW_RECTFILL
+static void memsetl (int *p, int c, int v)
+{
+       while (c--)
+               *(p++) = v;
+}
+#endif
+
+/*****************************************************************************/
+
+#ifndef VIDEO_HW_BITBLT
+static void memcpyl (int *d, int *s, int c)
+{
+       while (c--)
+               *(d++) = *(s++);
+}
+#endif
+
+/*****************************************************************************/
+
+static void console_scrollup (void)
+{
+       /* copy up rows ignoring the first one */
+
+#ifdef VIDEO_HW_BITBLT
+       video_hw_bitblt (VIDEO_PIXEL_SIZE,      /* bytes per pixel */
+                        0,     /* source pos x */
+                        VIDEO_LOGO_HEIGHT + VIDEO_FONT_HEIGHT, /* source pos y */
+                        0,     /* dest pos x */
+                        VIDEO_LOGO_HEIGHT,     /* dest pos y */
+                        VIDEO_VISIBLE_COLS,    /* frame width */
+                        VIDEO_VISIBLE_ROWS - VIDEO_LOGO_HEIGHT - VIDEO_FONT_HEIGHT     /* frame height */
+               );
+#else
+       memcpyl (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND,
+                CONSOLE_SCROLL_SIZE >> 2);
+#endif
+
+       /* clear the last one */
+#ifdef VIDEO_HW_RECTFILL
+       video_hw_rectfill (VIDEO_PIXEL_SIZE,    /* bytes per pixel */
+                          0,   /* dest pos x */
+                          VIDEO_VISIBLE_ROWS - VIDEO_FONT_HEIGHT,      /* dest pos y */
+                          VIDEO_VISIBLE_COLS,  /* frame width */
+                          VIDEO_FONT_HEIGHT,   /* frame height */
+                          CONSOLE_BG_COL       /* fill color */
+               );
+#else
+       memsetl (CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL);
+#endif
+}
+
+/*****************************************************************************/
+
+static void console_back (void)
+{
+       CURSOR_OFF console_col--;
+
+       if (console_col < 0) {
+               console_col = CONSOLE_COLS - 1;
+               console_row--;
+               if (console_row < 0)
+                       console_row = 0;
+       }
+       video_putchar (console_col * VIDEO_FONT_WIDTH,
+                      console_row * VIDEO_FONT_HEIGHT,
+                      ' ');
+}
+
+/*****************************************************************************/
+
+static void console_newline (void)
+{
+       CURSOR_OFF console_row++;
+       console_col = 0;
+
+       /* Check if we need to scroll the terminal */
+       if (console_row >= CONSOLE_ROWS) {
+               /* Scroll everything up */
+               console_scrollup ();
+
+               /* Decrement row number */
+               console_row--;
+       }
+}
+
+/*****************************************************************************/
+
+void video_putc (const char c)
+{
+       switch (c) {
+       case 13:                /* ignore */
+               break;
+
+       case '\n':              /* next line */
+               console_newline ();
+               break;
+
+       case 9:         /* tab 8 */
+               CURSOR_OFF console_col |= 0x0008;
+               console_col &= ~0x0007;
+
+               if (console_col >= CONSOLE_COLS)
+                       console_newline ();
+               break;
+
+       case 8:         /* backspace */
+               console_back ();
+               break;
+
+       default:                /* draw the char */
+               video_putchar (console_col * VIDEO_FONT_WIDTH,
+                              console_row * VIDEO_FONT_HEIGHT,
+                              c);
+               console_col++;
+
+               /* check for newline */
+               if (console_col >= CONSOLE_COLS)
+                       console_newline ();
+       }
+CURSOR_SET}
+
+
+/*****************************************************************************/
+
+void video_puts (const char *s)
+{
+       int count = strlen (s);
+
+       while (count--)
+               video_putc (*s++);
+}
+
+/*****************************************************************************/
+
+#if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
+
+#define FILL_8BIT_332RGB(r,g,b)        {                       \
+       *fb = ((r>>5)<<5) | ((g>>5)<<2) | (b>>6);       \
+       fb ++;                                          \
+}
+
+#define FILL_15BIT_555RGB(r,g,b) {                     \
+       *(unsigned short *)fb = SWAP16((unsigned short)(((r>>3)<<10) | ((g>>3)<<5) | (b>>3))); \
+       fb += 2;                                        \
+}
+
+#define FILL_16BIT_565RGB(r,g,b) {                     \
+       *(unsigned short *)fb = SWAP16((unsigned short)((((r)>>3)<<11) | (((g)>>2)<<5) | ((b)>>3))); \
+       fb += 2;                                        \
+}
+
+#define FILL_32BIT_X888RGB(r,g,b) {                    \
+       *(unsigned long *)fb = SWAP32((unsigned long)(((r<<16) | (g<<8) | b))); \
+       fb += 4;                                        \
+}
+
+#ifdef VIDEO_FB_LITTLE_ENDIAN
+#define FILL_24BIT_888RGB(r,g,b) {                     \
+       fb[0] = b;                                      \
+       fb[1] = g;                                      \
+       fb[2] = r;                                      \
+       fb += 3;                                        \
+}
+#else
+#define FILL_24BIT_888RGB(r,g,b) {                     \
+       fb[0] = r;                                      \
+       fb[1] = g;                                      \
+       fb[2] = b;                                      \
+       fb += 3;                                        \
+}
+#endif
+
+
+/*
+ * Display the BMP file located at address bmp_image.
+ * Only uncompressed
+ */
+int video_display_bitmap (ulong bmp_image, int x, int y)
+{
+       ushort xcount, ycount;
+       uchar *fb;
+       bmp_image_t *bmp = (bmp_image_t *) bmp_image;
+       uchar *bmap;
+       ushort padded_line;
+       unsigned long width, height, bpp;
+       unsigned colors;
+       unsigned long compression;
+       bmp_color_table_entry_t cte;
+#ifdef CONFIG_VIDEO_BMP_GZIP
+       unsigned char *dst = NULL;
+       ulong len;
+#endif
+
+       WATCHDOG_RESET ();
+
+       if (!((bmp->header.signature[0] == 'B') &&
+             (bmp->header.signature[1] == 'M'))) {
+
+#ifdef CONFIG_VIDEO_BMP_GZIP
+               /*
+                * Could be a gzipped bmp image, try to decrompress...
+                */
+               len = CFG_VIDEO_LOGO_MAX_SIZE;
+               dst = malloc(CFG_VIDEO_LOGO_MAX_SIZE);
+               if (dst == NULL) {
+                       printf("Error: malloc in gunzip failed!\n");
+                       return(1);
+               }
+               if (gunzip(dst, CFG_VIDEO_LOGO_MAX_SIZE, (uchar *)bmp_image, &len) != 0) {
+                       printf ("Error: no valid bmp or bmp.gz image at %lx\n", bmp_image);
+                       free(dst);
+                       return 1;
+               }
+               if (len == CFG_VIDEO_LOGO_MAX_SIZE) {
+                       printf("Image could be truncated (increase CFG_VIDEO_LOGO_MAX_SIZE)!\n");
+               }
+
+               /*
+                * Set addr to decompressed image
+                */
+               bmp = (bmp_image_t *)dst;
+
+               if (!((bmp->header.signature[0] == 'B') &&
+                     (bmp->header.signature[1] == 'M'))) {
+                       printf ("Error: no valid bmp.gz image at %lx\n", bmp_image);
+                       return 1;
+               }
+#else
+               printf ("Error: no valid bmp image at %lx\n", bmp_image);
+               return 1;
+#endif /* CONFIG_VIDEO_BMP_GZIP */
+       }
+
+       width = le32_to_cpu (bmp->header.width);
+       height = le32_to_cpu (bmp->header.height);
+       bpp = le16_to_cpu (bmp->header.bit_count);
+       colors = le32_to_cpu (bmp->header.colors_used);
+       compression = le32_to_cpu (bmp->header.compression);
+
+       debug ("Display-bmp: %d x %d  with %d colors\n",
+              width, height, colors);
+
+       if (compression != BMP_BI_RGB) {
+               printf ("Error: compression type %ld not supported\n",
+                       compression);
+               return 1;
+       }
+
+       padded_line = (((width * bpp + 7) / 8) + 3) & ~0x3;
+
+       if ((x + width) > VIDEO_VISIBLE_COLS)
+               width = VIDEO_VISIBLE_COLS - x;
+       if ((y + height) > VIDEO_VISIBLE_ROWS)
+               height = VIDEO_VISIBLE_ROWS - y;
+
+       bmap = (uchar *) bmp + le32_to_cpu (bmp->header.data_offset);
+       fb = (uchar *) (video_fb_address +
+                       ((y + height - 1) * VIDEO_COLS * VIDEO_PIXEL_SIZE) +
+                       x * VIDEO_PIXEL_SIZE);
+
+       /* We handle only 8bpp or 24 bpp bitmap */
+       switch (le16_to_cpu (bmp->header.bit_count)) {
+       case 8:
+               padded_line -= width;
+               if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) {
+                       /* Copy colormap                                             */
+                       for (xcount = 0; xcount < colors; ++xcount) {
+                               cte = bmp->color_table[xcount];
+                               video_set_lut (xcount, cte.red, cte.green, cte.blue);
+                       }
+               }
+               ycount = height;
+               switch (VIDEO_DATA_FORMAT) {
+               case GDF__8BIT_INDEX:
+                       while (ycount--) {
+                               WATCHDOG_RESET ();
+                               xcount = width;
+                               while (xcount--) {
+                                       *fb++ = *bmap++;
+                               }
+                               bmap += padded_line;
+                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+                       }
+                       break;
+               case GDF__8BIT_332RGB:
+                       while (ycount--) {
+                               WATCHDOG_RESET ();
+                               xcount = width;
+                               while (xcount--) {
+                                       cte = bmp->color_table[*bmap++];
+                                       FILL_8BIT_332RGB (cte.red, cte.green, cte.blue);
+                               }
+                               bmap += padded_line;
+                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+                       }
+                       break;
+               case GDF_15BIT_555RGB:
+                       while (ycount--) {
+                               WATCHDOG_RESET ();
+                               xcount = width;
+                               while (xcount--) {
+                                       cte = bmp->color_table[*bmap++];
+                                       FILL_15BIT_555RGB (cte.red, cte.green, cte.blue);
+                               }
+                               bmap += padded_line;
+                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+                       }
+                       break;
+               case GDF_16BIT_565RGB:
+                       while (ycount--) {
+                               WATCHDOG_RESET ();
+                               xcount = width;
+                               while (xcount--) {
+                                       cte = bmp->color_table[*bmap++];
+                                       FILL_16BIT_565RGB (cte.red, cte.green, cte.blue);
+                               }
+                               bmap += padded_line;
+                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+                       }
+                       break;
+               case GDF_32BIT_X888RGB:
+                       while (ycount--) {
+                               WATCHDOG_RESET ();
+                               xcount = width;
+                               while (xcount--) {
+                                       cte = bmp->color_table[*bmap++];
+                                       FILL_32BIT_X888RGB (cte.red, cte.green, cte.blue);
+                               }
+                               bmap += padded_line;
+                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+                       }
+                       break;
+               case GDF_24BIT_888RGB:
+                       while (ycount--) {
+                               WATCHDOG_RESET ();
+                               xcount = width;
+                               while (xcount--) {
+                                       cte = bmp->color_table[*bmap++];
+                                       FILL_24BIT_888RGB (cte.red, cte.green, cte.blue);
+                               }
+                               bmap += padded_line;
+                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+                       }
+                       break;
+               }
+               break;
+       case 24:
+               padded_line -= 3 * width;
+               ycount = height;
+               switch (VIDEO_DATA_FORMAT) {
+               case GDF__8BIT_332RGB:
+                       while (ycount--) {
+                               WATCHDOG_RESET ();
+                               xcount = width;
+                               while (xcount--) {
+                                       FILL_8BIT_332RGB (bmap[2], bmap[1], bmap[0]);
+                                       bmap += 3;
+                               }
+                               bmap += padded_line;
+                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+                       }
+                       break;
+               case GDF_15BIT_555RGB:
+                       while (ycount--) {
+                               WATCHDOG_RESET ();
+                               xcount = width;
+                               while (xcount--) {
+                                       FILL_15BIT_555RGB (bmap[2], bmap[1], bmap[0]);
+                                       bmap += 3;
+                               }
+                               bmap += padded_line;
+                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+                       }
+                       break;
+               case GDF_16BIT_565RGB:
+                       while (ycount--) {
+                               WATCHDOG_RESET ();
+                               xcount = width;
+                               while (xcount--) {
+                                       FILL_16BIT_565RGB (bmap[2], bmap[1], bmap[0]);
+                                       bmap += 3;
+                               }
+                               bmap += padded_line;
+                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+                       }
+                       break;
+               case GDF_32BIT_X888RGB:
+                       while (ycount--) {
+                               WATCHDOG_RESET ();
+                               xcount = width;
+                               while (xcount--) {
+                                       FILL_32BIT_X888RGB (bmap[2], bmap[1], bmap[0]);
+                                       bmap += 3;
+                               }
+                               bmap += padded_line;
+                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+                       }
+                       break;
+               case GDF_24BIT_888RGB:
+                       while (ycount--) {
+                               WATCHDOG_RESET ();
+                               xcount = width;
+                               while (xcount--) {
+                                       FILL_24BIT_888RGB (bmap[2], bmap[1], bmap[0]);
+                                       bmap += 3;
+                               }
+                               bmap += padded_line;
+                               fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+                       }
+                       break;
+               default:
+                       printf ("Error: 24 bits/pixel bitmap incompatible with current video mode\n");
+                       break;
+               }
+               break;
+       default:
+               printf ("Error: %d bit/pixel bitmaps not supported by U-Boot\n",
+                       le16_to_cpu (bmp->header.bit_count));
+               break;
+       }
+
+#ifdef CONFIG_VIDEO_BMP_GZIP
+       if (dst) {
+               free(dst);
+       }
+#endif
+
+       return (0);
+}
+#endif
+
+/*****************************************************************************/
+
+#ifdef CONFIG_VIDEO_LOGO
+void logo_plot (void *screen, int width, int x, int y)
+{
+
+       int xcount, i;
+       int skip   = (width - VIDEO_LOGO_WIDTH) * VIDEO_PIXEL_SIZE;
+       int ycount = VIDEO_LOGO_HEIGHT;
+       unsigned char r, g, b, *logo_red, *logo_blue, *logo_green;
+       unsigned char *source;
+       unsigned char *dest = (unsigned char *)screen + ((y * width * VIDEO_PIXEL_SIZE) + x);
+
+#ifdef CONFIG_VIDEO_BMP_LOGO
+       source = bmp_logo_bitmap;
+
+       /* Allocate temporary space for computing colormap                       */
+       logo_red = malloc (BMP_LOGO_COLORS);
+       logo_green = malloc (BMP_LOGO_COLORS);
+       logo_blue = malloc (BMP_LOGO_COLORS);
+       /* Compute color map                                                     */
+       for (i = 0; i < VIDEO_LOGO_COLORS; i++) {
+               logo_red[i] = (bmp_logo_palette[i] & 0x0f00) >> 4;
+               logo_green[i] = (bmp_logo_palette[i] & 0x00f0);
+               logo_blue[i] = (bmp_logo_palette[i] & 0x000f) << 4;
+       }
+#else
+       source = linux_logo;
+       logo_red = linux_logo_red;
+       logo_green = linux_logo_green;
+       logo_blue = linux_logo_blue;
+#endif
+
+       if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) {
+               for (i = 0; i < VIDEO_LOGO_COLORS; i++) {
+                       video_set_lut (i + VIDEO_LOGO_LUT_OFFSET,
+                                      logo_red[i], logo_green[i], logo_blue[i]);
+               }
+       }
+
+       while (ycount--) {
+               xcount = VIDEO_LOGO_WIDTH;
+               while (xcount--) {
+                       r = logo_red[*source - VIDEO_LOGO_LUT_OFFSET];
+                       g = logo_green[*source - VIDEO_LOGO_LUT_OFFSET];
+                       b = logo_blue[*source - VIDEO_LOGO_LUT_OFFSET];
+
+                       switch (VIDEO_DATA_FORMAT) {
+                       case GDF__8BIT_INDEX:
+                               *dest = *source;
+                               break;
+                       case GDF__8BIT_332RGB:
+                               *dest = ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
+                               break;
+                       case GDF_15BIT_555RGB:
+                               *(unsigned short *) dest =
+                                       SWAP16 ((unsigned short) (((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3)));
+                               break;
+                       case GDF_16BIT_565RGB:
+                               *(unsigned short *) dest =
+                                       SWAP16 ((unsigned short) (((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)));
+                               break;
+                       case GDF_32BIT_X888RGB:
+                               *(unsigned long *) dest =
+                                       SWAP32 ((unsigned long) ((r << 16) | (g << 8) | b));
+                               break;
+                       case GDF_24BIT_888RGB:
+#ifdef VIDEO_FB_LITTLE_ENDIAN
+                               dest[0] = b;
+                               dest[1] = g;
+                               dest[2] = r;
+#else
+                               dest[0] = r;
+                               dest[1] = g;
+                               dest[2] = b;
+#endif
+                               break;
+                       }
+                       source++;
+                       dest += VIDEO_PIXEL_SIZE;
+               }
+               dest += skip;
+       }
+#ifdef CONFIG_VIDEO_BMP_LOGO
+       free (logo_red);
+       free (logo_green);
+       free (logo_blue);
+#endif
+}
+
+/*****************************************************************************/
+
+static void *video_logo (void)
+{
+       char info[128];
+       extern char version_string;
+
+#ifdef CONFIG_SPLASH_SCREEN
+       char *s;
+       ulong addr;
+
+       if ((s = getenv ("splashimage")) != NULL) {
+               addr = simple_strtoul (s, NULL, 16);
+
+               if (video_display_bitmap (addr, 0, 0) == 0) {
+                       return ((void *) (video_fb_address));
+               }
+       }
+#endif /* CONFIG_SPLASH_SCREEN */
+
+       logo_plot (video_fb_address, VIDEO_COLS, 0, 0);
+
+       sprintf (info, " %s", &version_string);
+       video_drawstring (VIDEO_INFO_X, VIDEO_INFO_Y, (uchar *)info);
+
+#ifdef CONFIG_CONSOLE_EXTRA_INFO
+       {
+               int i, n = ((VIDEO_LOGO_HEIGHT - VIDEO_FONT_HEIGHT) / VIDEO_FONT_HEIGHT);
+
+               for (i = 1; i < n; i++) {
+                       video_get_info_str (i, info);
+                       if (*info)
+                               video_drawstring (VIDEO_INFO_X,
+                                                 VIDEO_INFO_Y + i * VIDEO_FONT_HEIGHT,
+                                                 (uchar *)info);
+               }
+       }
+#endif
+
+       return (video_fb_address + VIDEO_LOGO_HEIGHT * VIDEO_LINE_LEN);
+}
+#endif
+
+
+/*****************************************************************************/
+
+static int video_init (void)
+{
+       unsigned char color8;
+
+       if ((pGD = video_hw_init ()) == NULL)
+               return -1;
+
+       video_fb_address = (void *) VIDEO_FB_ADRS;
+#ifdef CONFIG_VIDEO_HW_CURSOR
+       video_init_hw_cursor (VIDEO_FONT_WIDTH, VIDEO_FONT_HEIGHT);
+#endif
+
+       /* Init drawing pats */
+       switch (VIDEO_DATA_FORMAT) {
+       case GDF__8BIT_INDEX:
+               video_set_lut (0x01, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL);
+               video_set_lut (0x00, CONSOLE_BG_COL, CONSOLE_BG_COL, CONSOLE_BG_COL);
+               fgx = 0x01010101;
+               bgx = 0x00000000;
+               break;
+       case GDF__8BIT_332RGB:
+               color8 = ((CONSOLE_FG_COL & 0xe0) |
+                         ((CONSOLE_FG_COL >> 3) & 0x1c) | CONSOLE_FG_COL >> 6);
+               fgx = (color8 << 24) | (color8 << 16) | (color8 << 8) | color8;
+               color8 = ((CONSOLE_BG_COL & 0xe0) |
+                         ((CONSOLE_BG_COL >> 3) & 0x1c) | CONSOLE_BG_COL >> 6);
+               bgx = (color8 << 24) | (color8 << 16) | (color8 << 8) | color8;
+               break;
+       case GDF_15BIT_555RGB:
+               fgx = (((CONSOLE_FG_COL >> 3) << 26) |
+                      ((CONSOLE_FG_COL >> 3) << 21) | ((CONSOLE_FG_COL >> 3) << 16) |
+                      ((CONSOLE_FG_COL >> 3) << 10) | ((CONSOLE_FG_COL >> 3) << 5) |
+                      (CONSOLE_FG_COL >> 3));
+               bgx = (((CONSOLE_BG_COL >> 3) << 26) |
+                      ((CONSOLE_BG_COL >> 3) << 21) | ((CONSOLE_BG_COL >> 3) << 16) |
+                      ((CONSOLE_BG_COL >> 3) << 10) | ((CONSOLE_BG_COL >> 3) << 5) |
+                      (CONSOLE_BG_COL >> 3));
+               break;
+       case GDF_16BIT_565RGB:
+               fgx = (((CONSOLE_FG_COL >> 3) << 27) |
+                      ((CONSOLE_FG_COL >> 2) << 21) | ((CONSOLE_FG_COL >> 3) << 16) |
+                      ((CONSOLE_FG_COL >> 3) << 11) | ((CONSOLE_FG_COL >> 2) << 5) |
+                      (CONSOLE_FG_COL >> 3));
+               bgx = (((CONSOLE_BG_COL >> 3) << 27) |
+                      ((CONSOLE_BG_COL >> 2) << 21) | ((CONSOLE_BG_COL >> 3) << 16) |
+                      ((CONSOLE_BG_COL >> 3) << 11) | ((CONSOLE_BG_COL >> 2) << 5) |
+                      (CONSOLE_BG_COL >> 3));
+               break;
+       case GDF_32BIT_X888RGB:
+               fgx = (CONSOLE_FG_COL << 16) | (CONSOLE_FG_COL << 8) | CONSOLE_FG_COL;
+               bgx = (CONSOLE_BG_COL << 16) | (CONSOLE_BG_COL << 8) | CONSOLE_BG_COL;
+               break;
+       case GDF_24BIT_888RGB:
+               fgx = (CONSOLE_FG_COL << 24) | (CONSOLE_FG_COL << 16) |
+                       (CONSOLE_FG_COL << 8) | CONSOLE_FG_COL;
+               bgx = (CONSOLE_BG_COL << 24) | (CONSOLE_BG_COL << 16) |
+                       (CONSOLE_BG_COL << 8) | CONSOLE_BG_COL;
+               break;
+       }
+       eorx = fgx ^ bgx;
+
+#ifdef CONFIG_VIDEO_LOGO
+       /* Plot the logo and get start point of console */
+       PRINTD ("Video: Drawing the logo ...\n");
+       video_console_address = video_logo ();
+#else
+       video_console_address = video_fb_address;
+#endif
+
+       /* Initialize the console */
+       console_col = 0;
+       console_row = 0;
+
+       return 0;
+}
+
+
+/*****************************************************************************/
+
+int drv_video_init (void)
+{
+       int skip_dev_init;
+       device_t console_dev;
+
+       skip_dev_init = 0;
+
+       /* Init video chip - returns with framebuffer cleared */
+       if (video_init () == -1)
+               skip_dev_init = 1;
+
+#ifdef CONFIG_VGA_AS_SINGLE_DEVICE
+       /* Devices VGA and Keyboard will be assigned seperately */
+       /* Init vga device */
+       if (!skip_dev_init) {
+               memset (&console_dev, 0, sizeof (console_dev));
+               strcpy (console_dev.name, "vga");
+               console_dev.ext = DEV_EXT_VIDEO;        /* Video extensions */
+               console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM;
+               console_dev.putc = video_putc;  /* 'putc' function */
+               console_dev.puts = video_puts;  /* 'puts' function */
+               console_dev.tstc = NULL;        /* 'tstc' function */
+               console_dev.getc = NULL;        /* 'getc' function */
+
+               if (device_register (&console_dev) == 0)
+                       return 1;
+       }
+#else
+       PRINTD ("KBD: Keyboard init ...\n");
+       if (VIDEO_KBD_INIT_FCT == -1)
+               skip_dev_init = 1;
+
+       /* Init console device */
+       if (!skip_dev_init) {
+               memset (&console_dev, 0, sizeof (console_dev));
+               strcpy (console_dev.name, "vga");
+               console_dev.ext = DEV_EXT_VIDEO;        /* Video extensions */
+               console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+               console_dev.putc = video_putc;  /* 'putc' function */
+               console_dev.puts = video_puts;  /* 'puts' function */
+               console_dev.tstc = VIDEO_TSTC_FCT;      /* 'tstc' function */
+               console_dev.getc = VIDEO_GETC_FCT;      /* 'getc' function */
+
+               if (device_register (&console_dev) == 0)
+                       return 1;
+       }
+#endif /* CONFIG_VGA_AS_SINGLE_DEVICE */
+       /* No console dev available */
+       return 0;
+}
+#endif /* CONFIG_CFB_CONSOLE */
diff --git a/drivers/video/ct69000.c b/drivers/video/ct69000.c
new file mode 100644 (file)
index 0000000..29d82e4
--- /dev/null
@@ -0,0 +1,1286 @@
+/* ported from ctfb.c (linux kernel):
+ * Created in Jan - July 2000 by Thomas Höhenleitner <th@visuelle-maschinen.de>
+ *
+ * Ported to U-Boot:
+ * (C) Copyright 2002 Denis Peter, MPL AG Switzerland
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_VIDEO
+
+#include <pci.h>
+#include <video_fb.h>
+#include "videomodes.h"
+
+#ifdef CONFIG_VIDEO_CT69000
+
+/* debug */
+#undef VGA_DEBUG
+#undef VGA_DUMP_REG
+#ifdef VGA_DEBUG
+#define        PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+/* Macros */
+#ifndef min
+#define min( a, b ) ( ( a ) < ( b ) ) ? ( a ) : ( b )
+#endif
+#ifndef max
+#define max( a, b ) ( ( a ) > ( b ) ) ? ( a ) : ( b )
+#endif
+#ifdef minmax
+#error "term minmax already used."
+#endif
+#define minmax( a, x, b ) max( ( a ), min( ( x ), ( b ) ) )
+#define N_ELTS( x ) ( sizeof( x ) / sizeof( x[ 0 ] ) )
+
+/* CT Register Offsets */
+#define CT_AR_O                        0x3c0   /* Index and Data write port of the attribute Registers */
+#define CT_GR_O                        0x3ce   /* Index port of the Graphic Controller Registers */
+#define CT_SR_O                        0x3c4   /* Index port of the Sequencer Controller */
+#define CT_CR_O                        0x3d4   /* Index port of the CRT Controller */
+#define CT_XR_O                        0x3d6   /* Extended Register index */
+#define CT_MSR_W_O             0x3c2   /* Misc. Output Register (write only) */
+#define CT_LUT_MASK_O          0x3c6   /* Color Palette Mask */
+#define CT_LUT_START_O         0x3c8   /* Color Palette Write Mode Index */
+#define CT_LUT_RGB_O           0x3c9   /* Color Palette Data Port */
+#define CT_STATUS_REG0_O       0x3c2   /* Status Register 0 (read only) */
+#define CT_STATUS_REG1_O       0x3da   /* Input Status Register 1 (read only) */
+
+#define CT_FP_O                        0x3d0   /* Index port of the Flat panel Registers */
+#define CT_MR_O                        0x3d2   /* Index Port of the Multimedia Extension */
+
+/* defines for the memory mapped registers */
+#define BR00_o         0x400000        /* Source and Destination Span Register */
+#define BR01_o         0x400004        /* Pattern/Source Expansion Background Color & Transparency Key Register */
+#define BR02_o         0x400008        /* Pattern/Source Expansion Foreground Color Register */
+#define BR03_o         0x40000C        /* Monochrome Source Control Register */
+#define BR04_o         0x400010        /* BitBLT Control Register */
+#define BR05_o         0x400014        /* Pattern Address Registe */
+#define BR06_o         0x400018        /* Source Address Register */
+#define BR07_o         0x40001C        /* Destination Address Register */
+#define BR08_o         0x400020        /* Destination Width & Height Register */
+#define BR09_o         0x400024        /* Source Expansion Background Color & Transparency Key Register */
+#define BR0A_o         0x400028        /* Source Expansion Foreground Color Register */
+
+#define CURSOR_SIZE    0x1000  /* in KByte for HW Cursor */
+#define PATTERN_ADR    (pGD->dprBase + CURSOR_SIZE)    /* pattern Memory after Cursor Memory */
+#define PATTERN_SIZE   8*8*4   /* 4 Bytes per Pixel 8 x 8 Pixel */
+#define ACCELMEMORY    (CURSOR_SIZE + PATTERN_SIZE)    /* reserved Memory for BITBlt and hw cursor */
+
+/* Some Mode definitions */
+#define FB_SYNC_HOR_HIGH_ACT   1       /* horizontal sync high active  */
+#define FB_SYNC_VERT_HIGH_ACT  2       /* vertical sync high active    */
+#define FB_SYNC_EXT            4       /* external sync                */
+#define FB_SYNC_COMP_HIGH_ACT  8       /* composite sync high active   */
+#define FB_SYNC_BROADCAST      16      /* broadcast video timings      */
+                                       /* vtotal = 144d/288n/576i => PAL  */
+                                       /* vtotal = 121d/242n/484i => NTSC */
+#define FB_SYNC_ON_GREEN       32      /* sync on green */
+
+#define FB_VMODE_NONINTERLACED  0      /* non interlaced */
+#define FB_VMODE_INTERLACED    1       /* interlaced   */
+#define FB_VMODE_DOUBLE                2       /* double scan */
+#define FB_VMODE_MASK          255
+
+#define FB_VMODE_YWRAP         256     /* ywrap instead of panning     */
+#define FB_VMODE_SMOOTH_XPAN   512     /* smooth xpan possible (internally used) */
+#define FB_VMODE_CONUPDATE     512     /* don't update x/yoffset       */
+
+#define text                   0
+#define fntwidth               8
+
+/* table for VGA Initialization  */
+typedef struct {
+       const unsigned char reg;
+       const unsigned char val;
+} CT_CFG_TABLE;
+
+/* this table provides some basic initialisations such as Memory Clock etc */
+static CT_CFG_TABLE xreg[] = {
+       {0x09, 0x01},           /* CRT Controller Extensions Enable */
+       {0x0A, 0x02},           /* Frame Buffer Mapping */
+       {0x0B, 0x01},           /* PCI Write Burst support */
+       {0x20, 0x00},           /* BitBLT Configuration */
+       {0x40, 0x03},           /* Memory Access Control */
+       {0x60, 0x00},           /* Video Pin Control */
+       {0x61, 0x00},           /* DPMS Synch control */
+       {0x62, 0x00},           /* GPIO Pin Control */
+       {0x63, 0xBD},           /* GPIO Pin Data */
+       {0x67, 0x00},           /* Pin Tri-State */
+       {0x80, 0x80},           /* Pixel Pipeline Config 0 register */
+       {0xA0, 0x00},           /* Cursor 1 Control Reg */
+       {0xA1, 0x00},           /* Cursor 1 Vertical Extension Reg */
+       {0xA2, 0x00},           /* Cursor 1 Base Address Low */
+       {0xA3, 0x00},           /* Cursor 1 Base Address High */
+       {0xA4, 0x00},           /* Cursor 1 X-Position Low */
+       {0xA5, 0x00},           /* Cursor 1 X-Position High */
+       {0xA6, 0x00},           /* Cursor 1 Y-Position Low */
+       {0xA7, 0x00},           /* Cursor 1 Y-Position High */
+       {0xA8, 0x00},           /* Cursor 2 Control Reg */
+       {0xA9, 0x00},           /* Cursor 2 Vertical Extension Reg */
+       {0xAA, 0x00},           /* Cursor 2 Base Address Low */
+       {0xAB, 0x00},           /* Cursor 2 Base Address High */
+       {0xAC, 0x00},           /* Cursor 2 X-Position Low */
+       {0xAD, 0x00},           /* Cursor 2 X-Position High */
+       {0xAE, 0x00},           /* Cursor 2 Y-Position Low */
+       {0xAF, 0x00},           /* Cursor 2 Y-Position High */
+       {0xC0, 0x7D},           /* Dot Clock 0 VCO M-Divisor */
+       {0xC1, 0x07},           /* Dot Clock 0 VCO N-Divisor */
+       {0xC3, 0x34},           /* Dot Clock 0 Divisor select */
+       {0xC4, 0x55},           /* Dot Clock 1 VCO M-Divisor */
+       {0xC5, 0x09},           /* Dot Clock 1 VCO N-Divisor */
+       {0xC7, 0x24},           /* Dot Clock 1 Divisor select */
+       {0xC8, 0x7D},           /* Dot Clock 2 VCO M-Divisor */
+       {0xC9, 0x07},           /* Dot Clock 2 VCO N-Divisor */
+       {0xCB, 0x34},           /* Dot Clock 2 Divisor select */
+       {0xCC, 0x38},           /* Memory Clock 0 VCO M-Divisor */
+       {0xCD, 0x03},           /* Memory Clock 0 VCO N-Divisor */
+       {0xCE, 0x90},           /* Memory Clock 0 Divisor select */
+       {0xCF, 0x06},           /* Clock Config */
+       {0xD0, 0x0F},           /* Power Down */
+       {0xD1, 0x01},           /* Power Down BitBLT */
+       {0xFF, 0xFF}            /* end of table */
+};
+/* Clock Config:
+ * =============
+ *
+ * PD Registers:
+ * -------------
+ * Bit2 and Bit4..6 are used for the Loop Divisor and Post Divisor.
+ * They are encoded as follows:
+ *
+ * +---+--------------+
+ * | 2 | Loop Divisor |
+ * +---+--------------+
+ * | 1 | 1            |
+ * +---+--------------+
+ * | 0 | 4            |
+ * +---+--------------+
+ * Note: The Memory Clock does not have a Loop Divisor.
+ * +---+---+---+--------------+
+ * | 6 | 5 | 4 | Post Divisor |
+ * +---+---+---+--------------+
+ * | 0 | 0 | 0 | 1            |
+ * +---+---+---+--------------+
+ * | 0 | 0 | 1 | 2            |
+ * +---+---+---+--------------+
+ * | 0 | 1 | 0 | 4            |
+ * +---+---+---+--------------+
+ * | 0 | 1 | 1 | 8            |
+ * +---+---+---+--------------+
+ * | 1 | 0 | 0 | 16           |
+ * +---+---+---+--------------+
+ * | 1 | 0 | 1 | 32           |
+ * +---+---+---+--------------+
+ * | 1 | 1 | X | reserved     |
+ * +---+---+---+--------------+
+ *
+ * All other bits are reserved in these registers.
+ *
+ * Clock VCO M Registers:
+ * ----------------------
+ * These Registers contain the M Value -2.
+ *
+ * Clock VCO N Registers:
+ * ----------------------
+ * These Registers contain the N Value -2.
+ *
+ * Formulas:
+ * ---------
+ * Fvco = (Fref * Loop Divisor * M/N), whereas 100MHz < Fvco < 220MHz
+ * Fout = Fvco / Post Divisor
+ *
+ * Dot Clk0 (default 25MHz):
+ * -------------------------
+ * Fvco = 14.318 * 127 / 9 = 202.045MHz
+ * Fout = 202.045MHz / 8 = 25.25MHz
+ * Post Divisor = 8
+ * Loop Divisor = 1
+ * XRC0 = (M - 2) = 125 = 0x7D
+ * XRC1 = (N - 2) = 7   = 0x07
+ * XRC3 =                 0x34
+ *
+ * Dot Clk1 (default 28MHz):
+ * -------------------------
+ * Fvco = 14.318 * 87 / 11 = 113.24MHz
+ * Fout = 113.24MHz / 4 = 28.31MHz
+ * Post Divisor = 4
+ * Loop Divisor = 1
+ * XRC4 = (M - 2) = 85 = 0x55
+ * XRC5 = (N - 2) = 9  = 0x09
+ * XRC7 =                0x24
+ *
+ * Dot Clk2 (variable for extended modes set to 25MHz):
+ * ----------------------------------------------------
+ * Fvco = 14.318 * 127 / 9 = 202.045MHz
+ * Fout = 202.045MHz / 8 = 25.25MHz
+ * Post Divisor = 8
+ * Loop Divisor = 1
+ * XRC8 = (M - 2) = 125 = 0x7D
+ * XRC9 = (N - 2) = 7   = 0x07
+ * XRCB =                 0x34
+ *
+ * Memory Clk for most modes >50MHz:
+ * ----------------------------------
+ * Fvco = 14.318 * 58 / 5 = 166MHz
+ * Fout = 166MHz / 2      = 83MHz
+ * Post Divisor = 2
+ * XRCC = (M - 2) = 57  = 0x38
+ * XRCD = (N - 2) = 3   = 0x03
+ * XRCE =                 0x90
+ *
+ * Note Bit7 enables the clock source from the VCO
+ *
+ */
+
+/*******************************************************************
+ * Chips struct
+ *******************************************************************/
+struct ctfb_chips_properties {
+       int device_id;          /* PCI Device ID */
+       unsigned long max_mem;  /* memory for frame buffer */
+       int vld_set;            /* value of VLD if bit2 in clock control is set */
+       int vld_not_set;        /* value of VLD if bit2 in clock control is set */
+       int mn_diff;            /* difference between M/N Value + mn_diff = M/N Register */
+       int mn_min;             /* min value of M/N Value */
+       int mn_max;             /* max value of M/N Value */
+       int vco_min;            /* VCO Min in MHz */
+       int vco_max;            /* VCO Max in MHz */
+};
+
+static const struct ctfb_chips_properties chips[] = {
+       {PCI_DEVICE_ID_CT_69000, 0x200000, 1, 4, -2, 3, 257, 100, 220},
+#ifdef CONFIG_USE_CPCIDVI
+       {PCI_DEVICE_ID_CT_69030, 0x400000, 1, 4, -2, 3, 257, 100, 220},
+#endif
+       {PCI_DEVICE_ID_CT_65555, 0x100000, 16, 4, 0, 1, 255, 48, 220},  /* NOT TESTED */
+       {0, 0, 0, 0, 0, 0, 0, 0, 0}     /* Terminator */
+};
+
+/*
+ * The Graphic Device
+ */
+GraphicDevice ctfb;
+
+/*******************************************************************************
+*
+* Low Level Routines
+*/
+
+/*******************************************************************************
+*
+* Read CT ISA register
+*/
+#ifdef VGA_DEBUG
+static unsigned char
+ctRead (unsigned short index)
+{
+       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+       if (index == CT_AR_O)
+               /* synch the Flip Flop */
+               in8 (pGD->isaBase + CT_STATUS_REG1_O);
+
+       return (in8 (pGD->isaBase + index));
+}
+#endif
+/*******************************************************************************
+*
+* Write CT ISA register
+*/
+static void
+ctWrite (unsigned short index, unsigned char val)
+{
+       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+
+       out8 ((pGD->isaBase + index), val);
+}
+
+/*******************************************************************************
+*
+* Read CT ISA register indexed
+*/
+static unsigned char
+ctRead_i (unsigned short index, char reg)
+{
+       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+       if (index == CT_AR_O)
+               /* synch the Flip Flop */
+               in8 (pGD->isaBase + CT_STATUS_REG1_O);
+       out8 ((pGD->isaBase + index), reg);
+       return (in8 (pGD->isaBase + index + 1));
+}
+
+/*******************************************************************************
+*
+* Write CT ISA register indexed
+*/
+static void
+ctWrite_i (unsigned short index, char reg, char val)
+{
+       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+       if (index == CT_AR_O) {
+               /* synch the Flip Flop */
+               in8 (pGD->isaBase + CT_STATUS_REG1_O);
+               out8 ((pGD->isaBase + index), reg);
+               out8 ((pGD->isaBase + index), val);
+       } else {
+               out8 ((pGD->isaBase + index), reg);
+               out8 ((pGD->isaBase + index + 1), val);
+       }
+}
+
+/*******************************************************************************
+*
+* Write a table of CT ISA register
+*/
+static void
+ctLoadRegs (unsigned short index, CT_CFG_TABLE * regTab)
+{
+       while (regTab->reg != 0xFF) {
+               ctWrite_i (index, regTab->reg, regTab->val);
+               regTab++;
+       }
+}
+
+/*****************************************************************************/
+static void
+SetArRegs (void)
+{
+       int i, tmp;
+
+       for (i = 0; i < 0x10; i++)
+               ctWrite_i (CT_AR_O, i, i);
+       if (text)
+               tmp = 0x04;
+       else
+               tmp = 0x41;
+
+       ctWrite_i (CT_AR_O, 0x10, tmp); /* Mode Control Register */
+       ctWrite_i (CT_AR_O, 0x11, 0x00);        /* Overscan Color Register */
+       ctWrite_i (CT_AR_O, 0x12, 0x0f);        /* Memory Plane Enable Register */
+       if (fntwidth == 9)
+               tmp = 0x08;
+       else
+               tmp = 0x00;
+       ctWrite_i (CT_AR_O, 0x13, tmp); /* Horizontal Pixel Panning */
+       ctWrite_i (CT_AR_O, 0x14, 0x00);        /* Color Select Register    */
+       ctWrite (CT_AR_O, 0x20);        /* enable video             */
+}
+
+/*****************************************************************************/
+static void
+SetGrRegs (void)
+{                              /* Set Graphics Mode */
+       int i;
+
+       for (i = 0; i < 0x05; i++)
+               ctWrite_i (CT_GR_O, i, 0);
+       if (text) {
+               ctWrite_i (CT_GR_O, 0x05, 0x10);
+               ctWrite_i (CT_GR_O, 0x06, 0x02);
+       } else {
+               ctWrite_i (CT_GR_O, 0x05, 0x40);
+               ctWrite_i (CT_GR_O, 0x06, 0x05);
+       }
+       ctWrite_i (CT_GR_O, 0x07, 0x0f);
+       ctWrite_i (CT_GR_O, 0x08, 0xff);
+}
+
+/*****************************************************************************/
+static void
+SetSrRegs (void)
+{
+       int tmp = 0;
+
+       ctWrite_i (CT_SR_O, 0x00, 0x00);        /* reset */
+       /*rr( sr, 0x01, tmp );
+          if( fntwidth == 8 ) tmp |= 0x01; else tmp &= ~0x01;
+          wr( sr, 0x01, tmp );  */
+       if (fntwidth == 8)
+               ctWrite_i (CT_SR_O, 0x01, 0x01);        /* Clocking Mode Register */
+       else
+               ctWrite_i (CT_SR_O, 0x01, 0x00);        /* Clocking Mode Register */
+       ctWrite_i (CT_SR_O, 0x02, 0x0f);        /* Enable CPU wr access to given memory plane */
+       ctWrite_i (CT_SR_O, 0x03, 0x00);        /* Character Map Select Register */
+       if (text)
+               tmp = 0x02;
+       else
+               tmp = 0x0e;
+       ctWrite_i (CT_SR_O, 0x04, tmp); /* Enable CPU accesses to the rest of the 256KB
+                                          total VGA memory beyond the first 64KB and set
+                                          fb mapping mode. */
+       ctWrite_i (CT_SR_O, 0x00, 0x03);        /* enable */
+}
+
+/*****************************************************************************/
+static void
+SetBitsPerPixelIntoXrRegs (int bpp)
+{
+       unsigned int n = (bpp >> 3), tmp;       /* only for 15, 8, 16, 24 bpp */
+       static char md[4] = { 0x04, 0x02, 0x05, 0x06 }; /* DisplayColorMode */
+       static char off[4] = { ~0x20, ~0x30, ~0x20, ~0x10 };    /* mask */
+       static char on[4] = { 0x10, 0x00, 0x10, 0x20 }; /* mask */
+       if (bpp == 15)
+               n = 0;
+       tmp = ctRead_i (CT_XR_O, 0x20);
+       tmp &= off[n];
+       tmp |= on[n];
+       ctWrite_i (CT_XR_O, 0x20, tmp); /* BitBLT Configuration */
+       ctWrite_i (CT_XR_O, 0x81, md[n]);
+}
+
+/*****************************************************************************/
+static void
+SetCrRegs (struct ctfb_res_modes *var, int bits_per_pixel)
+{                              /* he -le-   ht|0    hd -ri- hs     -h-      he */
+       unsigned char cr[0x7a];
+       int i, tmp;
+       unsigned int hd, hs, he, ht, hbe;       /* Horizontal.  */
+       unsigned int vd, vs, ve, vt;    /* vertical */
+       unsigned int bpp, wd, dblscan, interlaced, bcast, CrtHalfLine;
+       unsigned int CompSyncCharClkDelay, CompSyncPixelClkDelay;
+       unsigned int NTSC_PAL_HorizontalPulseWidth, BlDelayCtrl;
+       unsigned int HorizontalEqualizationPulses;
+       unsigned int HorizontalSerration1Start, HorizontalSerration2Start;
+
+       const int LineCompare = 0x3ff;
+       unsigned int TextScanLines = 1; /* this is in fact a vertical zoom factor   */
+       unsigned int RAMDAC_BlankPedestalEnable = 0;    /* 1=en-, 0=disable, see XR82 */
+
+       hd = (var->xres) / 8;   /* HDisp.  */
+       hs = (var->xres + var->right_margin) / 8;       /* HsStrt  */
+       he = (var->xres + var->right_margin + var->hsync_len) / 8;      /* HsEnd   */
+       ht = (var->left_margin + var->xres + var->right_margin + var->hsync_len) / 8;   /* HTotal  */
+       hbe = ht - 1;           /* HBlankEnable todo docu wants ht here, but it does not work */
+       /* ve -up-  vt|0    vd -lo- vs     -v-      ve */
+       vd = var->yres;         /* VDisplay   */
+       vs = var->yres + var->lower_margin;     /* VSyncStart */
+       ve = var->yres + var->lower_margin + var->vsync_len;    /* VSyncEnd */
+       vt = var->upper_margin + var->yres + var->lower_margin + var->vsync_len;        /* VTotal  */
+       bpp = bits_per_pixel;
+       dblscan = (var->vmode & FB_VMODE_DOUBLE) ? 1 : 0;
+       interlaced = var->vmode & FB_VMODE_INTERLACED;
+       bcast = var->sync & FB_SYNC_BROADCAST;
+       CrtHalfLine = bcast ? (hd >> 1) : 0;
+       BlDelayCtrl = bcast ? 1 : 0;
+       CompSyncCharClkDelay = 0;       /* 2 bit */
+       CompSyncPixelClkDelay = 0;      /* 3 bit */
+       if (bcast) {
+               NTSC_PAL_HorizontalPulseWidth = 7;      /*( var->hsync_len >> 1 ) + 1 */
+               HorizontalEqualizationPulses = 0;       /* inverse value */
+               HorizontalSerration1Start = 31; /* ( ht >> 1 ) */
+               HorizontalSerration2Start = 89; /* ( ht >> 1 ) */
+       } else {
+               NTSC_PAL_HorizontalPulseWidth = 0;
+               /* 4 bit: hsync pulse width = ( ( CR74[4:0] - CR74[5] )
+                * / 2 ) + 1 --> CR74[4:0] = 2*(hs-1) + CR74[5] */
+               HorizontalEqualizationPulses = 1;       /* inverse value */
+               HorizontalSerration1Start = 0;  /* ( ht >> 1 ) */
+               HorizontalSerration2Start = 0;  /* ( ht >> 1 ) */
+       }
+
+       if (bpp == 15)
+               bpp = 16;
+       wd = var->xres * bpp / 64;      /* double words per line */
+       if (interlaced) {       /* we divide all vertical timings, exept vd */
+               vs >>= 1;
+               ve >>= 1;
+               vt >>= 1;
+       }
+       memset (cr, 0, sizeof (cr));
+       cr[0x00] = 0xff & (ht - 5);
+       cr[0x01] = hd - 1;      /* soll:4f ist 59 */
+       cr[0x02] = hd;
+       cr[0x03] = (hbe & 0x1F) | 0x80; /* hd + ht - hd  */
+       cr[0x04] = hs;
+       cr[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
+       cr[0x06] = (vt - 2) & 0xFF;
+       cr[0x30] = (vt - 2) >> 8;
+       cr[0x07] = ((vt & 0x100) >> 8)
+           | ((vd & 0x100) >> 7)
+           | ((vs & 0x100) >> 6)
+           | ((vs & 0x100) >> 5)
+           | ((LineCompare & 0x100) >> 4)
+           | ((vt & 0x200) >> 4)
+           | ((vd & 0x200) >> 3)
+           | ((vs & 0x200) >> 2);
+       cr[0x08] = 0x00;
+       cr[0x09] = (dblscan << 7)
+           | ((LineCompare & 0x200) >> 3)
+           | ((vs & 0x200) >> 4)
+           | (TextScanLines - 1);
+       cr[0x10] = vs & 0xff;   /* VSyncPulseStart */
+       cr[0x32] = (vs & 0xf00) >> 8;   /* VSyncPulseStart */
+       cr[0x11] = (ve & 0x0f); /* | 0x20;      */
+       cr[0x12] = (vd - 1) & 0xff;     /* LineCount  */
+       cr[0x31] = ((vd - 1) & 0xf00) >> 8;     /* LineCount */
+       cr[0x13] = wd & 0xff;
+       cr[0x41] = (wd & 0xf00) >> 8;
+       cr[0x15] = vs & 0xff;
+       cr[0x33] = (vs & 0xf00) >> 8;
+       cr[0x38] = (0x100 & (ht - 5)) >> 8;
+       cr[0x3C] = 0xc0 & hbe;
+       cr[0x16] = (vt - 1) & 0xff;     /* vbe - docu wants vt here, */
+       cr[0x17] = 0xe3;        /* but it does not work */
+       cr[0x18] = 0xff & LineCompare;
+       cr[0x22] = 0xff;        /* todo? */
+       cr[0x70] = interlaced ? (0x80 | CrtHalfLine) : 0x00;    /* check:0xa6  */
+       cr[0x71] = 0x80 | (RAMDAC_BlankPedestalEnable << 6)
+           | (BlDelayCtrl << 5)
+           | ((0x03 & CompSyncCharClkDelay) << 3)
+           | (0x07 & CompSyncPixelClkDelay);   /* todo: see XR82 */
+       cr[0x72] = HorizontalSerration1Start;
+       cr[0x73] = HorizontalSerration2Start;
+       cr[0x74] = (HorizontalEqualizationPulses << 5)
+           | NTSC_PAL_HorizontalPulseWidth;
+       /* todo: ct69000 has also 0x75-79 */
+       /* now set the registers */
+       for (i = 0; i <= 0x0d; i++) {   /*CR00 .. CR0D */
+               ctWrite_i (CT_CR_O, i, cr[i]);
+       }
+       for (i = 0x10; i <= 0x18; i++) {        /*CR10 .. CR18 */
+               ctWrite_i (CT_CR_O, i, cr[i]);
+       }
+       i = 0x22;               /*CR22 */
+       ctWrite_i (CT_CR_O, i, cr[i]);
+       for (i = 0x30; i <= 0x33; i++) {        /*CR30 .. CR33 */
+               ctWrite_i (CT_CR_O, i, cr[i]);
+       }
+       i = 0x38;               /*CR38 */
+       ctWrite_i (CT_CR_O, i, cr[i]);
+       i = 0x3C;               /*CR3C */
+       ctWrite_i (CT_CR_O, i, cr[i]);
+       for (i = 0x40; i <= 0x41; i++) {        /*CR40 .. CR41 */
+               ctWrite_i (CT_CR_O, i, cr[i]);
+       }
+       for (i = 0x70; i <= 0x74; i++) {        /*CR70 .. CR74 */
+               ctWrite_i (CT_CR_O, i, cr[i]);
+       }
+       tmp = ctRead_i (CT_CR_O, 0x40);
+       tmp &= 0x0f;
+       tmp |= 0x80;
+       ctWrite_i (CT_CR_O, 0x40, tmp); /* StartAddressEnable */
+}
+
+/* pixelclock control */
+
+/*****************************************************************************
+ We have a rational number p/q and need an m/n which is very close to p/q
+ but has m and n within mnmin and mnmax. We have no floating point in the
+ kernel. We can use long long without divide. And we have time to compute...
+******************************************************************************/
+static unsigned int
+FindBestPQFittingMN (unsigned int p, unsigned int q, unsigned int mnmin,
+                    unsigned int mnmax, unsigned int *pm, unsigned int *pn)
+{
+       /* this code is not for general purpose usable but good for our number ranges */
+       unsigned int n = mnmin, m = 0;
+       long long int L = 0, P = p, Q = q, H = P >> 1;
+       long long int D = 0x7ffffffffffffffLL;
+       for (n = mnmin; n <= mnmax; n++) {
+               m = mnmin;      /* p/q ~ m/n -> p*n ~ m*q -> p*n-x*q ~ 0 */
+               L = P * n - m * Q;      /* n * vco - m * fref should be near 0 */
+               while (L > 0 && m < mnmax) {
+                       L -= q; /* difference is greater as 0 subtract fref */
+                       m++;    /* and increment m */
+               }
+               /* difference is less or equal than 0 or m > maximum */
+               if (m > mnmax)
+                       break;  /* no solution: if we increase n we get the same situation */
+               /* L is <= 0 now */
+               if (-L > H && m > mnmin) {      /* if difference > the half fref */
+                       L += q; /* we take the situation before */
+                       m--;    /* because its closer to 0 */
+               }
+               L = (L < 0) ? -L : +L;  /* absolute value */
+               if (D < L)      /* if last difference was better take next n */
+                       continue;
+               D = L;
+               *pm = m;
+               *pn = n;        /*  keep improved data */
+               if (D == 0)
+                       break;  /* best result we can get */
+       }
+       return (unsigned int) (0xffffffff & D);
+}
+
+/* that is the hardware < 69000 we have to manage
+ +---------+  +-------------------+  +----------------------+  +--+
+ | REFCLK  |__|NTSC Divisor Select|__|FVCO Reference Divisor|__|÷N|__
+ | 14.3MHz |  |(NTSCDS) (÷1, Ã·5)  |  |Select (RDS) (÷1, Ã·4) |  |  |  |
+ +---------+  +-------------------+  +----------------------+  +--+  |
+  ___________________________________________________________________|
+ |
+ |                                    fvco                      fout
+ | +--------+  +------------+  +-----+     +-------------------+   +----+
+ +-| Phase  |__|Charge Pump |__| VCO |_____|Post Divisor (PD)  |___|CLK |--->
+ +-| Detect |  |& Filter VCO|  |     |  |  |÷1, 2, 4, 8, 16, 32|   |    |
+ | +--------+  +------------+  +-----+  |  +-------------------+   +----+
+ |                                      |
+ |    +--+   +---------------+          |
+ |____|÷M|___|VCO Loop Divide|__________|
+      |  |   |(VLD)(÷4, Ã·16) |
+      +--+   +---------------+
+****************************************************************************
+  that is the hardware >= 69000 we have to manage
+ +---------+  +--+
+ | REFCLK  |__|÷N|__
+ | 14.3MHz |  |  |  |
+ +---------+  +--+  |
+  __________________|
+ |
+ |                                    fvco                      fout
+ | +--------+  +------------+  +-----+     +-------------------+   +----+
+ +-| Phase  |__|Charge Pump |__| VCO |_____|Post Divisor (PD)  |___|CLK |--->
+ +-| Detect |  |& Filter VCO|  |     |  |  |÷1, 2, 4, 8, 16, 32|   |    |
+ | +--------+  +------------+  +-----+  |  +-------------------+   +----+
+ |                                      |
+ |    +--+   +---------------+          |
+ |____|÷M|___|VCO Loop Divide|__________|
+      |  |   |(VLD)(÷1, Ã·4)  |
+      +--+   +---------------+
+
+
+*/
+
+#define VIDEO_FREF 14318180;   /* Hz  */
+/*****************************************************************************/
+static int
+ReadPixClckFromXrRegsBack (struct ctfb_chips_properties *param)
+{
+       unsigned int m, n, vld, pd, PD, fref, xr_cb, i, pixclock;
+       i = 0;
+       pixclock = -1;
+       fref = VIDEO_FREF;
+       m = ctRead_i (CT_XR_O, 0xc8);
+       n = ctRead_i (CT_XR_O, 0xc9);
+       m -= param->mn_diff;
+       n -= param->mn_diff;
+       xr_cb = ctRead_i (CT_XR_O, 0xcb);
+       PD = (0x70 & xr_cb) >> 4;
+       pd = 1;
+       for (i = 0; i < PD; i++) {
+               pd *= 2;
+       }
+       vld = (0x04 & xr_cb) ? param->vld_set : param->vld_not_set;
+       if (n * vld * m) {
+               unsigned long long p = 1000000000000LL * pd * n;
+               unsigned long long q = (long long) fref * vld * m;
+               while ((p > 0xffffffffLL) || (q > 0xffffffffLL)) {
+                       p >>= 1;        /* can't divide with long long so we scale down */
+                       q >>= 1;
+               }
+               pixclock = (unsigned) p / (unsigned) q;
+       } else
+               printf ("Invalid data in xr regs.\n");
+       return pixclock;
+}
+
+/*****************************************************************************/
+static void
+FindAndSetPllParamIntoXrRegs (unsigned int pixelclock,
+                             struct ctfb_chips_properties *param)
+{
+       unsigned int m, n, vld, pd, PD, fref, xr_cb;
+       unsigned int fvcomin, fvcomax, pclckmin, pclckmax, pclk;
+       unsigned int pfreq, fvco, new_pixclock;
+       unsigned int D,nback,mback;
+
+       fref = VIDEO_FREF;
+       pd = 1;
+       PD = 0;
+       fvcomin = param->vco_min;
+       fvcomax = param->vco_max;       /* MHz */
+       pclckmin = 1000000 / fvcomax + 1;       /*   4546 */
+       pclckmax = 32000000 / fvcomin - 1;      /* 666665 */
+       pclk = minmax (pclckmin, pixelclock, pclckmax); /* ps pp */
+       pfreq = 250 * (4000000000U / pclk);
+       fvco = pfreq;           /* Hz */
+       new_pixclock = 0;
+       while (fvco < fvcomin * 1000000) {
+               /* double VCO starting with the pixelclock frequency
+                * as long as it is lower than the minimal VCO frequency */
+               fvco *= 2;
+               pd *= 2;
+               PD++;
+       }
+       /* fvco is exactly pd * pixelclock and higher than the ninmal VCO frequency */
+       /* first try */
+       vld = param->vld_set;
+       D=FindBestPQFittingMN (fvco / vld, fref, param->mn_min, param->mn_max, &m, &n); /* rds = 1 */
+       mback=m;
+       nback=n;
+       /* second try */
+       vld = param->vld_not_set;
+       if(D<FindBestPQFittingMN (fvco / vld, fref, param->mn_min, param->mn_max, &m, &n)) {    /* rds = 1 */
+               /* first try was better */
+               m=mback;
+               n=nback;
+               vld = param->vld_set;
+       }
+       m += param->mn_diff;
+       n += param->mn_diff;
+       PRINTF ("VCO %d, pd %d, m %d n %d vld %d \n", fvco, pd, m, n, vld);
+       xr_cb = ((0x7 & PD) << 4) | (vld == param->vld_set ? 0x04 : 0);
+       /* All four of the registers used for dot clock 2 (XRC8 - XRCB) must be
+        * written, and in order from XRC8 to XRCB, before the hardware will
+        * update the synthesizer s settings.
+        */
+       ctWrite_i (CT_XR_O, 0xc8, m);
+       ctWrite_i (CT_XR_O, 0xc9, n);   /* xrca does not exist in CT69000 and CT69030 */
+       ctWrite_i (CT_XR_O, 0xca, 0);   /* because of a hw bug I guess, but we write */
+       ctWrite_i (CT_XR_O, 0xcb, xr_cb);       /* 0 to it for savety */
+       new_pixclock = ReadPixClckFromXrRegsBack (param);
+       PRINTF ("pixelclock.set = %d, pixelclock.real = %d \n",
+               pixelclock, new_pixclock);
+}
+
+/*****************************************************************************/
+static void
+SetMsrRegs (struct ctfb_res_modes *mode)
+{
+       unsigned char h_synch_high, v_synch_high;
+
+       h_synch_high = (mode->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 0x40;  /* horizontal Synch High active */
+       v_synch_high = (mode->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 0x80; /* vertical Synch High active */
+       ctWrite (CT_MSR_W_O, (h_synch_high | v_synch_high | 0x29));
+       /* upper64K==0x20, CLC2select==0x08, RAMenable==0x02!(todo), CGA==0x01
+        * Selects the upper 64KB page.Bit5=1
+        * CLK2 (left reserved in standard VGA) Bit3|2=1|0
+        * Disables CPU access to frame buffer. Bit1=0
+        * Sets the I/O address decode for ST01, FCR, and all CR registers
+        * to the 3Dx I/O address range (CGA emulation). Bit0=1
+        */
+}
+
+/************************************************************************************/
+#ifdef VGA_DUMP_REG
+
+static void
+ctDispRegs (unsigned short index, int from, int to)
+{
+       unsigned char status;
+       int i;
+
+       for (i = from; i < to; i++) {
+               status = ctRead_i (index, i);
+               printf ("%02X: is %02X\n", i, status);
+       }
+}
+
+void
+video_dump_reg (void)
+{
+       int i;
+
+       printf ("Extended Regs:\n");
+       ctDispRegs (CT_XR_O, 0, 0xC);
+       ctDispRegs (CT_XR_O, 0xe, 0xf);
+       ctDispRegs (CT_XR_O, 0x20, 0x21);
+       ctDispRegs (CT_XR_O, 0x40, 0x50);
+       ctDispRegs (CT_XR_O, 0x60, 0x64);
+       ctDispRegs (CT_XR_O, 0x67, 0x68);
+       ctDispRegs (CT_XR_O, 0x70, 0x72);
+       ctDispRegs (CT_XR_O, 0x80, 0x83);
+       ctDispRegs (CT_XR_O, 0xA0, 0xB0);
+       ctDispRegs (CT_XR_O, 0xC0, 0xD3);
+       printf ("Sequencer Regs:\n");
+       ctDispRegs (CT_SR_O, 0, 0x8);
+       printf ("Graphic Regs:\n");
+       ctDispRegs (CT_GR_O, 0, 0x9);
+       printf ("CRT Regs:\n");
+       ctDispRegs (CT_CR_O, 0, 0x19);
+       ctDispRegs (CT_CR_O, 0x22, 0x23);
+       ctDispRegs (CT_CR_O, 0x30, 0x34);
+       ctDispRegs (CT_CR_O, 0x38, 0x39);
+       ctDispRegs (CT_CR_O, 0x3C, 0x3D);
+       ctDispRegs (CT_CR_O, 0x40, 0x42);
+       ctDispRegs (CT_CR_O, 0x70, 0x80);
+       /* don't display the attributes */
+}
+
+#endif
+
+#ifdef CONFIG_VIDEO_HW_CURSOR
+/***************************************************************
+ * Set Hardware Cursor in Pixel
+ */
+void
+video_set_hw_cursor (int x, int y)
+{
+       int sig_x = 0, sig_y = 0;
+       if (x < 0) {
+               x *= -1;
+               sig_x = 1;
+       }
+       if (y < 0) {
+               y *= -1;
+               sig_y = 1;
+       }
+       ctWrite_i (CT_XR_O, 0xa4, x & 0xff);
+       ctWrite_i (CT_XR_O, 0xa5, (x >> 8) & 0x7);
+       ctWrite_i (CT_XR_O, 0xa6, y & 0xff);
+       ctWrite_i (CT_XR_O, 0xa7, (y >> 8) & 0x7);
+}
+
+/***************************************************************
+ * Init Hardware Cursor. To know the size of the Cursor,
+ * we have to know the Font size.
+ */
+void
+video_init_hw_cursor (int font_width, int font_height)
+{
+       unsigned char xr_80;
+       unsigned long *curs, pattern;
+       int i;
+       int cursor_start;
+       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+
+       cursor_start = pGD->dprBase;
+       xr_80 = ctRead_i (CT_XR_O, 0x80);
+       /* set start address */
+       ctWrite_i (CT_XR_O, 0xa2, (cursor_start >> 8) & 0xf0);
+       ctWrite_i (CT_XR_O, 0xa3, (cursor_start >> 16) & 0x3f);
+       /* set cursor shape */
+       curs = (unsigned long *) cursor_start;
+       i = 0;
+       while (i < 0x400) {
+               curs[i++] = 0xffffffff; /* AND mask */
+               curs[i++] = 0xffffffff; /* AND mask */
+               curs[i++] = 0;  /* XOR mask */
+               curs[i++] = 0;  /* XOR mask */
+               /* Transparent */
+       }
+       pattern = 0xffffffff >> font_width;
+       i = 0;
+       while (i < (font_height * 2)) {
+               curs[i++] = pattern;    /* AND mask */
+               curs[i++] = pattern;    /* AND mask */
+               curs[i++] = 0;  /* XOR mask */
+               curs[i++] = 0;  /* XOR mask */
+               /* Cursor Color 0 */
+       }
+       /* set blink rate */
+       ctWrite_i (CT_FP_O, 0x19, 0xf);
+
+       /* set cursors colors */
+       xr_80 = ctRead_i (CT_XR_O, 0x80);
+       xr_80 |= 0x1;           /* alternate palette select */
+       ctWrite_i (CT_XR_O, 0x80, xr_80);
+       video_set_lut (4, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL);
+       /* position 4 is color 0 cursor 0 */
+       xr_80 &= 0xfe;          /* normal palette select */
+       ctWrite_i (CT_XR_O, 0x80, xr_80);
+       /* cursor enable */
+       ctWrite_i (CT_XR_O, 0xa0, 0x91);
+       xr_80 |= 0x10;          /* enable hwcursor */
+       ctWrite_i (CT_XR_O, 0x80, xr_80);
+       video_set_hw_cursor (0, 0);
+}
+#endif                         /* CONFIG_VIDEO_HW_CURSOR */
+
+/***************************************************************
+ * Wait for BitBlt ready
+ */
+static int
+video_wait_bitblt (unsigned long addr)
+{
+       unsigned long br04;
+       int i = 0;
+       br04 = in32r (addr);
+       while (br04 & 0x80000000) {
+               udelay (1);
+               br04 = in32r (addr);
+               if (i++ > 1000000) {
+                       printf ("ERROR Timeout %lx\n", br04);
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+/***************************************************************
+ * Set up BitBlt Registrs
+ */
+static void
+SetDrawingEngine (int bits_per_pixel)
+{
+       unsigned long br04, br00;
+       unsigned char tmp;
+
+       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+
+       tmp = ctRead_i (CT_XR_O, 0x20); /* BitBLT Configuration */
+       tmp |= 0x02;            /* reset BitBLT */
+       ctWrite_i (CT_XR_O, 0x20, tmp); /* BitBLT Configuration */
+       udelay (10);
+       tmp &= 0xfd;            /* release reset BitBLT */
+       ctWrite_i (CT_XR_O, 0x20, tmp); /* BitBLT Configuration */
+       video_wait_bitblt (pGD->pciBase + BR04_o);
+
+       /* set pattern Address */
+       out32r (pGD->pciBase + BR05_o, PATTERN_ADR & 0x003ffff8);
+       br04 = 0;
+       if (bits_per_pixel == 1) {
+               br04 |= 0x00040000;     /* monochome Pattern */
+               br04 |= 0x00001000;     /* monochome source */
+       }
+       br00 = ((pGD->winSizeX * pGD->gdfBytesPP) << 16) + (pGD->winSizeX * pGD->gdfBytesPP);   /* bytes per scanline */
+       out32r (pGD->pciBase + BR00_o, br00);   /* */
+       out32r (pGD->pciBase + BR08_o, (10 << 16) + 10);        /* dummy */
+       out32r (pGD->pciBase + BR04_o, br04);   /* write all 0 */
+       out32r (pGD->pciBase + BR07_o, 0);      /* destination */
+       video_wait_bitblt (pGD->pciBase + BR04_o);
+}
+
+/****************************************************************************
+* supported Video Chips
+*/
+static struct pci_device_id supported[] = {
+       {PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69000},
+#ifdef CONFIG_USE_CPCIDVI
+       {PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69030},
+#endif
+       {}
+};
+
+/*******************************************************************************
+*
+* Init video chip
+*/
+void *
+video_hw_init (void)
+{
+       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+       unsigned short device_id;
+       pci_dev_t devbusfn;
+       int videomode;
+       unsigned long t1, hsynch, vsynch;
+       unsigned int pci_mem_base, *vm;
+       int tmp, i, bits_per_pixel;
+       char *penv;
+       struct ctfb_res_modes *res_mode;
+       struct ctfb_res_modes var_mode;
+       struct ctfb_chips_properties *chips_param;
+       /* Search for video chip */
+
+       if ((devbusfn = pci_find_devices (supported, 0)) < 0) {
+#ifdef CONFIG_VIDEO_ONBOARD
+               printf ("Video: Controller not found !\n");
+#endif
+               return (NULL);
+       }
+
+       /* PCI setup */
+       pci_write_config_dword (devbusfn, PCI_COMMAND,
+                               (PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
+       pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
+       pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
+       pci_mem_base = pci_mem_to_phys (devbusfn, pci_mem_base);
+
+       /* get chips params */
+       for (chips_param = (struct ctfb_chips_properties *) &chips[0];
+            chips_param->device_id != 0; chips_param++) {
+               if (chips_param->device_id == device_id)
+                       break;
+       }
+       if (chips_param->device_id == 0) {
+#ifdef CONFIG_VIDEO_ONBOARD
+               printf ("Video: controller 0x%X not supported\n", device_id);
+#endif
+               return NULL;
+       }
+       /* supported Video controller found */
+       printf ("Video: ");
+
+       tmp = 0;
+       videomode = 0x301;
+       /* get video mode via environment */
+       if ((penv = getenv ("videomode")) != NULL) {
+               /* deceide if it is a string */
+               if (penv[0] <= '9') {
+                       videomode = (int) simple_strtoul (penv, NULL, 16);
+                       tmp = 1;
+               }
+       } else {
+               tmp = 1;
+       }
+       if (tmp) {
+               /* parameter are vesa modes */
+               /* search params */
+               for (i = 0; i < VESA_MODES_COUNT; i++) {
+                       if (vesa_modes[i].vesanr == videomode)
+                               break;
+               }
+               if (i == VESA_MODES_COUNT) {
+                       printf ("no VESA Mode found, switching to mode 0x301 ");
+                       i = 0;
+               }
+               res_mode =
+                   (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].
+                                                            resindex];
+               bits_per_pixel = vesa_modes[i].bits_per_pixel;
+       } else {
+
+               res_mode = (struct ctfb_res_modes *) &var_mode;
+               bits_per_pixel = video_get_params (res_mode, penv);
+       }
+
+       /* calculate available color depth for controller memory */
+       if (bits_per_pixel == 15)
+               tmp = 2;
+       else
+               tmp = bits_per_pixel >> 3;      /* /8 */
+       if (((chips_param->max_mem -
+             ACCELMEMORY) / (res_mode->xres * res_mode->yres)) < tmp) {
+               tmp =
+                   ((chips_param->max_mem -
+                     ACCELMEMORY) / (res_mode->xres * res_mode->yres));
+               if (tmp == 0) {
+                       printf
+                           ("No matching videomode found .-> reduce resolution\n");
+                       return NULL;
+               } else {
+                       printf ("Switching back to %d Bits per Pixel ",
+                               tmp << 3);
+                       bits_per_pixel = tmp << 3;
+               }
+       }
+
+       /* calculate hsynch and vsynch freq (info only) */
+       t1 = (res_mode->left_margin + res_mode->xres +
+             res_mode->right_margin + res_mode->hsync_len) / 8;
+       t1 *= 8;
+       t1 *= res_mode->pixclock;
+       t1 /= 1000;
+       hsynch = 1000000000L / t1;
+       t1 *=
+           (res_mode->upper_margin + res_mode->yres +
+            res_mode->lower_margin + res_mode->vsync_len);
+       t1 /= 1000;
+       vsynch = 1000000000L / t1;
+
+       /* fill in Graphic device struct */
+       sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
+                res_mode->yres, bits_per_pixel, (hsynch / 1000),
+                (vsynch / 1000));
+       printf ("%s\n", pGD->modeIdent);
+       pGD->winSizeX = res_mode->xres;
+       pGD->winSizeY = res_mode->yres;
+       pGD->plnSizeX = res_mode->xres;
+       pGD->plnSizeY = res_mode->yres;
+       switch (bits_per_pixel) {
+       case 8:
+               pGD->gdfBytesPP = 1;
+               pGD->gdfIndex = GDF__8BIT_INDEX;
+               break;
+       case 15:
+               pGD->gdfBytesPP = 2;
+               pGD->gdfIndex = GDF_15BIT_555RGB;
+               break;
+       case 16:
+               pGD->gdfBytesPP = 2;
+               pGD->gdfIndex = GDF_16BIT_565RGB;
+               break;
+       case 24:
+               pGD->gdfBytesPP = 3;
+               pGD->gdfIndex = GDF_24BIT_888RGB;
+               break;
+       }
+       pGD->isaBase = CFG_ISA_IO_BASE_ADDRESS;
+       pGD->pciBase = pci_mem_base;
+       pGD->frameAdrs = pci_mem_base;
+       pGD->memSize = chips_param->max_mem;
+       /* Cursor Start Address */
+       pGD->dprBase =
+           (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + pci_mem_base;
+       if ((pGD->dprBase & 0x0fff) != 0) {
+               /* allign it */
+               pGD->dprBase &= 0xfffff000;
+               pGD->dprBase += 0x00001000;
+       }
+       PRINTF ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
+               PATTERN_ADR);
+       pGD->vprBase = pci_mem_base;    /* Dummy */
+       pGD->cprBase = pci_mem_base;    /* Dummy */
+       /* set up Hardware */
+
+#ifdef CONFIG_USE_CPCIDVI
+       if (device_id == PCI_DEVICE_ID_CT_69030) {
+               ctWrite (CT_MSR_W_O, 0x0b);
+               ctWrite (0x3cd, 0x13);
+               ctWrite_i (CT_FP_O, 0x02, 0x00);
+               ctWrite_i (CT_FP_O, 0x05, 0x00);
+               ctWrite_i (CT_FP_O, 0x06, 0x00);
+               ctWrite (0x3c2, 0x0b);
+               ctWrite_i (CT_FP_O, 0x02, 0x10);
+               ctWrite_i (CT_FP_O, 0x01, 0x09);
+       } else {
+               ctWrite (CT_MSR_W_O, 0x01);
+       }
+#else
+       ctWrite (CT_MSR_W_O, 0x01);
+#endif
+
+       /* set the extended Registers */
+       ctLoadRegs (CT_XR_O, xreg);
+       /* set atribute registers */
+       SetArRegs ();
+       /* set Graphics register */
+       SetGrRegs ();
+       /* set sequencer */
+       SetSrRegs ();
+
+       /* set msr */
+       SetMsrRegs (res_mode);
+
+       /* set CRT Registers */
+       SetCrRegs (res_mode, bits_per_pixel);
+       /* set color mode */
+       SetBitsPerPixelIntoXrRegs (bits_per_pixel);
+
+       /* set PLL */
+       FindAndSetPllParamIntoXrRegs (res_mode->pixclock, chips_param);
+
+       ctWrite_i (CT_SR_O, 0, 0x03);   /* clear synchronous reset */
+       /* Clear video memory */
+       i = pGD->memSize / 4;
+       vm = (unsigned int *) pGD->pciBase;
+       while (i--)
+               *vm++ = 0;
+       SetDrawingEngine (bits_per_pixel);
+#ifdef VGA_DUMP_REG
+       video_dump_reg ();
+#endif
+
+       return ((void *) &ctfb);
+}
+
+ /*******************************************************************************
+*
+* Set a RGB color in the LUT (8 bit index)
+*/
+void
+video_set_lut (unsigned int index,     /* color number */
+              unsigned char r, /* red */
+              unsigned char g, /* green */
+              unsigned char b  /* blue */
+    )
+{
+
+       ctWrite (CT_LUT_MASK_O, 0xff);
+
+       ctWrite (CT_LUT_START_O, (char) index);
+
+       ctWrite (CT_LUT_RGB_O, r);      /* red */
+       ctWrite (CT_LUT_RGB_O, g);      /* green */
+       ctWrite (CT_LUT_RGB_O, b);      /* blue */
+       udelay (1);
+       ctWrite (CT_LUT_MASK_O, 0xff);
+}
+
+/*******************************************************************************
+*
+* Drawing engine fill on screen region
+*/
+void
+video_hw_rectfill (unsigned int bpp,   /* bytes per pixel */
+                  unsigned int dst_x,  /* dest pos x */
+                  unsigned int dst_y,  /* dest pos y */
+                  unsigned int dim_x,  /* frame width */
+                  unsigned int dim_y,  /* frame height */
+                  unsigned int color   /* fill color */
+    )
+{
+       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+       unsigned long *p, br04;
+
+       video_wait_bitblt (pGD->pciBase + BR04_o);
+
+       p = (unsigned long *) PATTERN_ADR;
+       dim_x *= bpp;
+       if (bpp == 3)
+               bpp++;          /* 24Bit needs a 32bit pattern */
+       memset (p, color, (bpp * sizeof (unsigned char) * 8 * 8));      /* 8 x 8 pattern data */
+       out32r (pGD->pciBase + BR07_o, ((pGD->winSizeX * dst_y) + dst_x) * pGD->gdfBytesPP);    /* destination */
+       br04 = in32r (pGD->pciBase + BR04_o) & 0xffffff00;
+       br04 |= 0xF0;           /* write Pattern P -> D */
+       out32r (pGD->pciBase + BR04_o, br04);   /* */
+       out32r (pGD->pciBase + BR08_o, (dim_y << 16) + dim_x);  /* starts the BITBlt */
+       video_wait_bitblt (pGD->pciBase + BR04_o);
+}
+
+/*******************************************************************************
+*
+* Drawing engine bitblt with screen region
+*/
+void
+video_hw_bitblt (unsigned int bpp,     /* bytes per pixel */
+                unsigned int src_x,    /* source pos x */
+                unsigned int src_y,    /* source pos y */
+                unsigned int dst_x,    /* dest pos x */
+                unsigned int dst_y,    /* dest pos y */
+                unsigned int dim_x,    /* frame width */
+                unsigned int dim_y     /* frame height */
+    )
+{
+       GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+       unsigned long br04;
+
+       br04 = in32r (pGD->pciBase + BR04_o);
+
+       /* to prevent data corruption due to overlap, we have to
+        * find out if, and how the frames overlaps */
+       if (src_x < dst_x) {
+               /* src is more left than dest
+                * the frame may overlap -> start from right to left */
+               br04 |= 0x00000100;     /* set bit 8 */
+               src_x += dim_x;
+               dst_x += dim_x;
+       } else {
+               br04 &= 0xfffffeff;     /* clear bit 8 left to right */
+       }
+       if (src_y < dst_y) {
+               /* src is higher than dst
+                * the frame may overlap => start from bottom */
+               br04 |= 0x00000200;     /* set bit 9 */
+               src_y += dim_y;
+               dst_y += dim_y;
+       } else {
+               br04 &= 0xfffffdff;     /* clear bit 9 top to bottom */
+       }
+       dim_x *= bpp;
+       out32r (pGD->pciBase + BR06_o, ((pGD->winSizeX * src_y) + src_x) * pGD->gdfBytesPP);    /* source */
+       out32r (pGD->pciBase + BR07_o, ((pGD->winSizeX * dst_y) + dst_x) * pGD->gdfBytesPP);    /* destination */
+       br04 &= 0xffffff00;
+       br04 |= 0x000000CC;     /* S -> D */
+       out32r (pGD->pciBase + BR04_o, br04);   /* */
+       out32r (pGD->pciBase + BR08_o, (dim_y << 16) + dim_x);  /* start the BITBlt */
+       video_wait_bitblt (pGD->pciBase + BR04_o);
+}
+
+#endif                         /* CONFIG_CT69000 */
+
+#endif                         /* CONFIG_VIDEO */
diff --git a/drivers/video/sed13806.c b/drivers/video/sed13806.c
new file mode 100644 (file)
index 0000000..6996ca8
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ * (C) Copyright 2002
+ * Stäubli Faverges - <www.staubli.com>
+ * Pierre AUBERT  p.aubert@staubli.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+/* Video support for Epson SED13806 chipset                                  */
+
+#include <common.h>
+
+#ifdef CONFIG_VIDEO_SED13806
+
+#include <video_fb.h>
+#include <sed13806.h>
+
+#define readByte(ptrReg)                \
+    *(volatile unsigned char *)(sed13806.isaBase + ptrReg)
+
+#define writeByte(ptrReg,value) \
+    *(volatile unsigned char *)(sed13806.isaBase + ptrReg) = value
+
+#ifdef CONFIG_TOTAL5200
+#define writeWord(ptrReg,value) \
+    (*(volatile unsigned short *)(sed13806.isaBase + ptrReg) = value)
+#else
+#define writeWord(ptrReg,value) \
+    (*(volatile unsigned short *)(sed13806.isaBase + ptrReg) = ((value >> 8 ) & 0xff) | ((value << 8) & 0xff00))
+#endif
+
+GraphicDevice sed13806;
+
+/*-----------------------------------------------------------------------------
+ * EpsonSetRegs --
+ *-----------------------------------------------------------------------------
+ */
+static void EpsonSetRegs (void)
+{
+    /* the content of the chipset register depends on the board (clocks, ...)*/
+    const S1D_REGS *preg = board_get_regs ();
+    while (preg -> Index) {
+       writeByte (preg -> Index, preg -> Value);
+       preg ++;
+    }
+}
+
+/*-----------------------------------------------------------------------------
+ * video_hw_init --
+ *-----------------------------------------------------------------------------
+ */
+void *video_hw_init (void)
+{
+    unsigned int *vm, i;
+
+    memset (&sed13806, 0, sizeof (GraphicDevice));
+
+    /* Initialization of the access to the graphic chipset
+       Retreive base address of the chipset
+       (see board/RPXClassic/eccx.c)                                         */
+    if ((sed13806.isaBase = board_video_init ()) == 0) {
+       return (NULL);
+    }
+
+    sed13806.frameAdrs = sed13806.isaBase + FRAME_BUFFER_OFFSET;
+    sed13806.winSizeX = board_get_width ();
+    sed13806.winSizeY = board_get_height ();
+
+#if defined(CONFIG_VIDEO_SED13806_8BPP)
+    sed13806.gdfIndex = GDF__8BIT_INDEX;
+    sed13806.gdfBytesPP = 1;
+
+#elif defined(CONFIG_VIDEO_SED13806_16BPP)
+    sed13806.gdfIndex = GDF_16BIT_565RGB;
+    sed13806.gdfBytesPP = 2;
+
+#else
+#error Unsupported SED13806 BPP
+#endif
+
+    sed13806.memSize = sed13806.winSizeX * sed13806.winSizeY * sed13806.gdfBytesPP;
+
+    /* Load SED registers                                                    */
+    EpsonSetRegs ();
+
+    /* (see board/RPXClassic/RPXClassic.c)                                   */
+    board_validate_screen (sed13806.isaBase);
+
+    /* Clear video memory */
+    i = sed13806.memSize/4;
+    vm = (unsigned int *)sed13806.frameAdrs;
+    while(i--)
+       *vm++ = 0;
+
+
+    return (&sed13806);
+}
+/*-----------------------------------------------------------------------------
+ * Epson_wait_idle -- Wait for hardware to become idle
+ *-----------------------------------------------------------------------------
+ */
+static void Epson_wait_idle (void)
+{
+    while (readByte (BLT_CTRL0) & 0x80);
+
+    /* Read a word in the BitBLT memory area to shutdown the BitBLT engine   */
+    *(volatile unsigned short *)(sed13806.isaBase + BLT_REG);
+}
+
+/*-----------------------------------------------------------------------------
+ * video_hw_bitblt --
+ *-----------------------------------------------------------------------------
+ */
+void video_hw_bitblt (
+    unsigned int bpp,             /* bytes per pixel */
+    unsigned int src_x,           /* source pos x */
+    unsigned int src_y,           /* source pos y */
+    unsigned int dst_x,           /* dest pos x */
+    unsigned int dst_y,           /* dest pos y */
+    unsigned int dim_x,           /* frame width */
+    unsigned int dim_y            /* frame height */
+    )
+{
+    register GraphicDevice *pGD = (GraphicDevice *)&sed13806;
+    unsigned long      srcAddr, dstAddr;
+    unsigned int stride = bpp * pGD -> winSizeX;
+
+    srcAddr = (src_y * stride) + (src_x * bpp);
+    dstAddr = (dst_y * stride) + (dst_x * bpp);
+
+    Epson_wait_idle ();
+
+    writeByte(BLT_ROP,0x0C);   /* source */
+    writeByte(BLT_OP,0x02);/* move blit in positive direction with ROP */
+    writeWord(BLT_MEM_OFF0, stride / 2);
+    if (pGD -> gdfIndex == GDF__8BIT_INDEX) {
+       writeByte(BLT_CTRL1,0x00);
+    }
+    else {
+       writeByte(BLT_CTRL1,0x01);
+    }
+
+    writeWord(BLT_WIDTH0,(dim_x - 1));
+    writeWord(BLT_HEIGHT0,(dim_y - 1));
+
+    /* set up blit registers                                                 */
+    writeByte(BLT_SRC_ADDR0,srcAddr);
+    writeByte(BLT_SRC_ADDR1,srcAddr>>8);
+    writeByte(BLT_SRC_ADDR2,srcAddr>>16);
+
+    writeByte(BLT_DST_ADDR0,dstAddr);
+    writeByte(BLT_DST_ADDR1,dstAddr>>8);
+    writeByte(BLT_DST_ADDR2,dstAddr>>16);
+
+    /* Engage the blt engine                                                 */
+    /* rectangular region for src and dst                                    */
+    writeByte(BLT_CTRL0,0x80);
+
+    /* wait untill current blits finished                                    */
+    Epson_wait_idle ();
+}
+/*-----------------------------------------------------------------------------
+ * video_hw_rectfill --
+ *-----------------------------------------------------------------------------
+ */
+void video_hw_rectfill (
+    unsigned int bpp,             /* bytes per pixel */
+    unsigned int dst_x,           /* dest pos x */
+    unsigned int dst_y,           /* dest pos y */
+    unsigned int dim_x,           /* frame width */
+    unsigned int dim_y,           /* frame height */
+    unsigned int color            /* fill color */
+     )
+{
+    register GraphicDevice *pGD = (GraphicDevice *)&sed13806;
+    unsigned long      dstAddr;
+    unsigned int stride = bpp * pGD -> winSizeX;
+
+    dstAddr = (dst_y * stride) + (dst_x * bpp);
+
+    Epson_wait_idle ();
+
+    /* set up blit registers                                                 */
+    writeByte(BLT_DST_ADDR0,dstAddr);
+    writeByte(BLT_DST_ADDR1,dstAddr>>8);
+    writeByte(BLT_DST_ADDR2,dstAddr>>16);
+
+    writeWord(BLT_WIDTH0,(dim_x - 1));
+    writeWord(BLT_HEIGHT0,(dim_y - 1));
+    writeWord(BLT_FGCOLOR0,color);
+
+    writeByte(BLT_OP,0x0C);  /* solid fill                                   */
+    writeWord(BLT_MEM_OFF0,stride / 2);
+
+    if (pGD -> gdfIndex == GDF__8BIT_INDEX) {
+       writeByte(BLT_CTRL1,0x00);
+    }
+    else {
+       writeByte(BLT_CTRL1,0x01);
+    }
+
+    /* Engage the blt engine                                                 */
+    /* rectangular region for src and dst                                    */
+    writeByte(BLT_CTRL0,0x80);
+
+    /* wait untill current blits finished                                    */
+    Epson_wait_idle ();
+}
+
+/*-----------------------------------------------------------------------------
+ * video_set_lut --
+ *-----------------------------------------------------------------------------
+ */
+void video_set_lut (
+    unsigned int index,           /* color number */
+    unsigned char r,              /* red */
+    unsigned char g,              /* green */
+    unsigned char b               /* blue */
+    )
+{
+    writeByte(REG_LUT_ADDR, index );
+    writeByte(REG_LUT_DATA, r);
+    writeByte(REG_LUT_DATA, g);
+    writeByte(REG_LUT_DATA, b);
+}
+#ifdef CONFIG_VIDEO_HW_CURSOR
+/*-----------------------------------------------------------------------------
+ * video_set_hw_cursor --
+ *-----------------------------------------------------------------------------
+ */
+void video_set_hw_cursor (int x, int y)
+{
+    writeByte (LCD_CURSOR_XL, (x & 0xff));
+    writeByte (LCD_CURSOR_XM, (x >> 8));
+    writeByte (LCD_CURSOR_YL, (y & 0xff));
+    writeByte (LCD_CURSOR_YM, (y >> 8));
+}
+
+/*-----------------------------------------------------------------------------
+ * video_init_hw_cursor --
+ *-----------------------------------------------------------------------------
+ */
+void video_init_hw_cursor (int font_width, int font_height)
+{
+    volatile unsigned char *ptr;
+    unsigned char pattern;
+    int i;
+
+
+    /* Init cursor content
+       Cursor size is 64x64 pixels
+       Start of the cursor memory depends on panel type (dual panel ...)     */
+    if ((i = readByte (LCD_CURSOR_START)) == 0) {
+       ptr = (unsigned char *)(sed13806.frameAdrs + DEFAULT_VIDEO_MEMORY_SIZE - HWCURSORSIZE);
+    }
+    else {
+       ptr = (unsigned char *)(sed13806.frameAdrs + DEFAULT_VIDEO_MEMORY_SIZE - (i * 8192));
+    }
+
+    /* Fill the first line and the first empty line after cursor             */
+    for (i = 0, pattern = 0; i < 64; i++) {
+       if (i < font_width) {
+           /* Invert background                                             */
+           pattern |= 0x3;
+
+       }
+       else {
+           /* Background                                                    */
+           pattern |= 0x2;
+       }
+       if ((i & 3) == 3) {
+           *ptr = pattern;
+           *(ptr + font_height * 16) = 0xaa;
+           ptr ++;
+           pattern = 0;
+       }
+       pattern <<= 2;
+    }
+
+    /* Duplicate this line                                                   */
+    for (i = 1; i < font_height; i++) {
+       memcpy ((void *)ptr, (void *)(ptr - 16), 16);
+       ptr += 16;
+    }
+
+    for (; i < 64; i++) {
+       memcpy ((void *)(ptr + 16), (void *)ptr, 16);
+       ptr += 16;
+    }
+
+    /* Select cursor mode                                                    */
+    writeByte (LCD_CURSOR_CNTL, 1);
+}
+#endif
+#endif
diff --git a/drivers/video/sed156x.c b/drivers/video/sed156x.c
new file mode 100644 (file)
index 0000000..e9d5ed4
--- /dev/null
@@ -0,0 +1,566 @@
+/*
+ * (C) Copyright 2003
+ *
+ * Pantelis Antoniou <panto@intracom.gr>
+ * Intracom S.A.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <watchdog.h>
+
+#include <sed156x.h>
+
+#ifdef CONFIG_SED156X
+
+/* configure according to the selected display */
+#if defined(CONFIG_SED156X_PG12864Q)
+#define LCD_WIDTH      128
+#define LCD_HEIGHT     64
+#define LCD_LINES      64
+#define LCD_PAGES      9
+#define LCD_COLUMNS    132
+#else
+#error Unsupported SED156x configuration
+#endif
+
+/* include the font data */
+#include <video_font.h>
+
+#if VIDEO_FONT_WIDTH != 8 || VIDEO_FONT_HEIGHT != 16
+#error Expecting VIDEO_FONT_WIDTH == 8 && VIDEO_FONT_HEIGHT == 16
+#endif
+
+#define LCD_BYTE_WIDTH         (LCD_WIDTH / 8)
+#define VIDEO_FONT_BYTE_WIDTH  (VIDEO_FONT_WIDTH / 8)
+
+#define LCD_TEXT_WIDTH (LCD_WIDTH / VIDEO_FONT_WIDTH)
+#define LCD_TEXT_HEIGHT (LCD_HEIGHT / VIDEO_FONT_HEIGHT)
+
+#define LCD_BYTE_LINESZ                (LCD_BYTE_WIDTH * VIDEO_FONT_HEIGHT)
+
+const int sed156x_text_width = LCD_TEXT_WIDTH;
+const int sed156x_text_height = LCD_TEXT_HEIGHT;
+
+/**************************************************************************************/
+
+#define SED156X_SPI_RXD() (SED156X_SPI_RXD_PORT & SED156X_SPI_RXD_MASK)
+
+#define SED156X_SPI_TXD(x) \
+       do { \
+               if (x) \
+                       SED156X_SPI_TXD_PORT |=  SED156X_SPI_TXD_MASK; \
+               else \
+                       SED156X_SPI_TXD_PORT &= ~SED156X_SPI_TXD_MASK; \
+       } while(0)
+
+#define SED156X_SPI_CLK(x) \
+       do { \
+               if (x) \
+                       SED156X_SPI_CLK_PORT |=  SED156X_SPI_CLK_MASK; \
+               else \
+                       SED156X_SPI_CLK_PORT &= ~SED156X_SPI_CLK_MASK; \
+       } while(0)
+
+#define SED156X_SPI_CLK_TOGGLE() (SED156X_SPI_CLK_PORT ^= SED156X_SPI_CLK_MASK)
+
+#define SED156X_SPI_BIT_DELAY() /* no delay */
+
+#define SED156X_CS(x) \
+       do { \
+               if (x) \
+                       SED156X_CS_PORT |=  SED156X_CS_MASK; \
+               else \
+                       SED156X_CS_PORT &= ~SED156X_CS_MASK; \
+       } while(0)
+
+#define SED156X_A0(x) \
+       do { \
+               if (x) \
+                       SED156X_A0_PORT |=  SED156X_A0_MASK; \
+               else \
+                       SED156X_A0_PORT &= ~SED156X_A0_MASK; \
+       } while(0)
+
+/**************************************************************************************/
+
+/*** LCD Commands ***/
+
+#define LCD_ON         0xAF    /* Display ON                                         */
+#define LCD_OFF                0xAE    /* Display OFF                                        */
+#define LCD_LADDR      0x40    /* Display start line set + (6-bit) address           */
+#define LCD_PADDR      0xB0    /* Page address set + (4-bit) page                    */
+#define LCD_CADRH      0x10    /* Column address set upper + (4-bit) column hi       */
+#define LCD_CADRL      0x00    /* Column address set lower + (4-bit) column lo       */
+#define LCD_ADC_NRM    0xA0    /* ADC select Normal                                  */
+#define LCD_ADC_REV    0xA1    /* ADC select Reverse                                 */
+#define LCD_DSP_NRM    0xA6    /* LCD display Normal                                 */
+#define LCD_DSP_REV    0xA7    /* LCD display Reverse                                */
+#define LCD_DPT_NRM    0xA4    /* Display all points Normal                          */
+#define LCD_DPT_ALL    0xA5    /* Display all points ON                              */
+#define LCD_BIAS9      0xA2    /* LCD bias set 1/9                                   */
+#define LCD_BIAS7      0xA3    /* LCD bias set 1/7                                   */
+#define LCD_CAINC      0xE0    /* Read/modify/write                                  */
+#define LCD_CAEND      0xEE    /* End                                                */
+#define LCD_RESET      0xE2    /* Reset                                              */
+#define LCD_C_NRM      0xC0    /* Common output mode select Normal direction         */
+#define LCD_C_RVS      0xC8    /* Common output mode select Reverse direction        */
+#define LCD_PWRMD      0x28    /* Power control set + (3-bit) mode                   */
+#define LCD_RESRT      0x20    /* V5 v. reg. int. resistor ratio set + (3-bit) ratio */
+#define LCD_EVSET      0x81    /* Electronic volume mode set + byte = (6-bit) volume */
+#define LCD_SIOFF      0xAC    /* Static indicator OFF                               */
+#define LCD_SION       0xAD    /* Static indicator ON + byte = (2-bit) mode          */
+#define LCD_NOP                0xE3    /* NOP                                                */
+#define LCD_TEST       0xF0    /* Test/Test mode reset (Note: *DO NOT USE*)          */
+
+/*-------------------------------------------------------------------------------
+  Compound commands
+  -------------------------------------------------------------------------------
+  Command      Description                     Commands
+  ----------   ------------------------        -------------------------------------
+  POWS_ON      POWER SAVER ON command          LCD_OFF, LCD_D_ALL
+  POWS_OFF     POWER SAVER OFF command         LCD_D_NRM
+  SLEEPON      SLEEP mode                      LCD_SIOFF, POWS_ON
+  SLEEPOFF     SLEEP mode cancel               LCD_D_NRM, LCD_SION, LCD_SIS_???
+  STDBYON      STAND BY mode                   LCD_SION, POWS_ON
+  STDBYOFF     STAND BY mode cancel            LCD_D_NRM
+  -------------------------------------------------------------------------------*/
+
+/*** LCD various parameters ***/
+#define LCD_PPB                8       /* Pixels per byte (display is B/W, 1 bit per pixel) */
+
+/*** LCD Status byte masks ***/
+#define LCD_S_BUSY     0x80    /* Status Read - BUSY mask   */
+#define LCD_S_ADC      0x40    /* Status Read - ADC mask    */
+#define LCD_S_ONOFF    0x20    /* Status Read - ON/OFF mask */
+#define LCD_S_RESET    0x10    /* Status Read - RESET mask  */
+
+/*** LCD commands parameter masks ***/
+#define LCD_M_LADDR    0x3F    /* Display start line (6-bit) address mask           */
+#define LCD_M_PADDR    0x0F    /* Page address (4-bit) page mask                    */
+#define LCD_M_CADRH    0x0F    /* Column address upper (4-bit) column hi mask       */
+#define LCD_M_CADRL    0x0F    /* Column address lower (4-bit) column lo mask       */
+#define LCD_M_PWRMD    0x07    /* Power control (3-bit) mode mask                   */
+#define LCD_M_RESRT    0x07    /* V5 v. reg. int. resistor ratio (3-bit) ratio mask */
+#define LCD_M_EVSET    0x3F    /* Electronic volume mode byte (6-bit) volume mask   */
+#define LCD_M_SION     0x03    /* Static indicator ON (2-bit) mode mask             */
+
+/*** LCD Power control cirquits control masks ***/
+#define LCD_PWRBSTR    0x04    /* Power control mode - Booster cirquit ON           */
+#define LCD_PWRVREG    0x02    /* Power control mode - Voltage regulator cirquit ON */
+#define LCD_PWRVFOL    0x01    /* Power control mode - Voltage follower cirquit ON  */
+
+/*** LCD Static indicator states ***/
+#define LCD_SIS_OFF    0x00    /* Static indicator register set - OFF state             */
+#define LCD_SIS_BL     0x01    /* Static indicator register set - 1s blink state        */
+#define LCD_SIS_RBL    0x02    /* Static indicator register set - .5s rapid blink state */
+#define LCD_SIS_ON     0x03    /* Static indicator register set - constantly on state   */
+
+/*** LCD functions special parameters (commands) ***/
+#define LCD_PREVP      0x80    /* Page number for moving to previous */
+#define LCD_NEXTP      0x81    /* or next page */
+#define LCD_ERR_P      0xFF    /* Error in page number */
+
+/*** LCD initialization settings ***/
+#define LCD_BIAS       LCD_BIAS9       /* Bias: 1/9                  */
+#define LCD_ADCMODE    LCD_ADC_NRM     /* ADC mode: normal           */
+#define LCD_COMDIR     LCD_C_NRM       /* Common output mode: normal */
+#define LCD_RRATIO     0               /* Resistor ratio: 0          */
+#define LCD_CNTRST     0x1C            /* electronic volume: 1Ch     */
+#define LCD_POWERM     (LCD_PWRBSTR | LCD_PWRVREG | LCD_PWRVFOL)       /* Power mode: All on */
+
+/**************************************************************************************/
+
+static inline unsigned int sed156x_transfer(unsigned int val)
+{
+       unsigned int rx;
+       int b;
+
+       rx = 0; b = 8;
+       while (--b >= 0) {
+               SED156X_SPI_TXD(val & 0x80);
+               val <<= 1;
+               SED156X_SPI_CLK_TOGGLE();
+               SED156X_SPI_BIT_DELAY();
+               rx <<= 1;
+               if (SED156X_SPI_RXD())
+                       rx |= 1;
+               SED156X_SPI_CLK_TOGGLE();
+               SED156X_SPI_BIT_DELAY();
+       }
+
+       return rx;
+}
+
+unsigned int sed156x_data_transfer(unsigned int val)
+{
+       unsigned int rx;
+
+       SED156X_SPI_CLK(1);
+       SED156X_CS(0);
+       SED156X_A0(1);
+
+       rx = sed156x_transfer(val);
+
+       SED156X_CS(1);
+
+       return rx;
+}
+
+void sed156x_data_block_transfer(const u8 *p, int size)
+{
+       SED156X_SPI_CLK(1);
+       SED156X_CS(0);
+       SED156X_A0(1);
+
+       while (--size >= 0)
+               sed156x_transfer(*p++);
+
+       SED156X_CS(1);
+}
+
+unsigned int sed156x_cmd_transfer(unsigned int val)
+{
+       unsigned int rx;
+
+       SED156X_SPI_CLK(1);
+       SED156X_CS(0);
+       SED156X_A0(0);
+
+       rx = sed156x_transfer(val);
+
+       SED156X_CS(1);
+       SED156X_A0(1);
+
+       return rx;
+}
+
+/******************************************************************************/
+
+static u8 hw_screen[LCD_PAGES][LCD_COLUMNS];
+static u8 last_hw_screen[LCD_PAGES][LCD_COLUMNS];
+static u8 sw_screen[LCD_BYTE_WIDTH * LCD_HEIGHT];
+
+void sed156x_sync(void)
+{
+       int i, j, last_page;
+       u8 *d;
+       const u8 *s, *e, *b, *r;
+       u8 v0, v1, v2, v3, v4, v5, v6, v7;
+
+       /* copy and rotate sw_screen to hw_screen */
+       for (i = 0; i < LCD_HEIGHT / 8; i++) {
+
+               d = &hw_screen[i][0];
+               s = &sw_screen[LCD_BYTE_WIDTH * 8 * i + LCD_BYTE_WIDTH - 1];
+
+               for (j = 0; j < LCD_WIDTH / 8; j++) {
+
+                       v0 = s[0 * LCD_BYTE_WIDTH];
+                       v1 = s[1 * LCD_BYTE_WIDTH];
+                       v2 = s[2 * LCD_BYTE_WIDTH];
+                       v3 = s[3 * LCD_BYTE_WIDTH];
+                       v4 = s[4 * LCD_BYTE_WIDTH];
+                       v5 = s[5 * LCD_BYTE_WIDTH];
+                       v6 = s[6 * LCD_BYTE_WIDTH];
+                       v7 = s[7 * LCD_BYTE_WIDTH];
+
+                       d[0] =  ((v7 & 0x01) << 7) |
+                               ((v6 & 0x01) << 6) |
+                               ((v5 & 0x01) << 5) |
+                               ((v4 & 0x01) << 4) |
+                               ((v3 & 0x01) << 3) |
+                               ((v2 & 0x01) << 2) |
+                               ((v1 & 0x01) << 1) |
+                                (v0 & 0x01)       ;
+
+                       d[1] =  ((v7 & 0x02) << 6) |
+                               ((v6 & 0x02) << 5) |
+                               ((v5 & 0x02) << 4) |
+                               ((v4 & 0x02) << 3) |
+                               ((v3 & 0x02) << 2) |
+                               ((v2 & 0x02) << 1) |
+                               ((v1 & 0x02) << 0) |
+                               ((v0 & 0x02) >> 1) ;
+
+                       d[2] =  ((v7 & 0x04) << 5) |
+                               ((v6 & 0x04) << 4) |
+                               ((v5 & 0x04) << 3) |
+                               ((v4 & 0x04) << 2) |
+                               ((v3 & 0x04) << 1) |
+                                (v2 & 0x04)       |
+                               ((v1 & 0x04) >> 1) |
+                               ((v0 & 0x04) >> 2) ;
+
+                       d[3] =  ((v7 & 0x08) << 4) |
+                               ((v6 & 0x08) << 3) |
+                               ((v5 & 0x08) << 2) |
+                               ((v4 & 0x08) << 1) |
+                                (v3 & 0x08)       |
+                               ((v2 & 0x08) >> 1) |
+                               ((v1 & 0x08) >> 2) |
+                               ((v0 & 0x08) >> 3) ;
+
+                       d[4] =  ((v7 & 0x10) << 3) |
+                               ((v6 & 0x10) << 2) |
+                               ((v5 & 0x10) << 1) |
+                                (v4 & 0x10)       |
+                               ((v3 & 0x10) >> 1) |
+                               ((v2 & 0x10) >> 2) |
+                               ((v1 & 0x10) >> 3) |
+                               ((v0 & 0x10) >> 4) ;
+
+                       d[5] =  ((v7 & 0x20) << 2) |
+                               ((v6 & 0x20) << 1) |
+                                (v5 & 0x20)       |
+                               ((v4 & 0x20) >> 1) |
+                               ((v3 & 0x20) >> 2) |
+                               ((v2 & 0x20) >> 3) |
+                               ((v1 & 0x20) >> 4) |
+                               ((v0 & 0x20) >> 5) ;
+
+                       d[6] =  ((v7 & 0x40) << 1) |
+                                (v6 & 0x40)       |
+                               ((v5 & 0x40) >> 1) |
+                               ((v4 & 0x40) >> 2) |
+                               ((v3 & 0x40) >> 3) |
+                               ((v2 & 0x40) >> 4) |
+                               ((v1 & 0x40) >> 5) |
+                               ((v0 & 0x40) >> 6) ;
+
+                       d[7] =   (v7 & 0x80)       |
+                               ((v6 & 0x80) >> 1) |
+                               ((v5 & 0x80) >> 2) |
+                               ((v4 & 0x80) >> 3) |
+                               ((v3 & 0x80) >> 4) |
+                               ((v2 & 0x80) >> 5) |
+                               ((v1 & 0x80) >> 6) |
+                               ((v0 & 0x80) >> 7) ;
+
+                       d += 8;
+                       s--;
+               }
+       }
+
+       /* and now output only the differences */
+       for (i = 0; i < LCD_PAGES; i++) {
+
+               b = &hw_screen[i][0];
+               e = &hw_screen[i][LCD_COLUMNS];
+
+               d = &last_hw_screen[i][0];
+               s = b;
+
+               last_page = -1;
+
+               /* update only the differences */
+               do {
+                       while (s < e && *s == *d) {
+                               s++;
+                               d++;
+                       }
+                       if (s == e)
+                               break;
+                       r = s;
+                       while (s < e && *s != *d)
+                               *d++ = *s++;
+
+                       j = r - b;
+
+                       if (i != last_page) {
+                               sed156x_cmd_transfer(LCD_PADDR | i);
+                               last_page = i;
+                       }
+
+                       sed156x_cmd_transfer(LCD_CADRH | ((j >> 4) & 0x0F));
+                       sed156x_cmd_transfer(LCD_CADRL | (j & 0x0F));
+                       sed156x_data_block_transfer(r, s - r);
+
+               } while (s < e);
+       }
+
+/********
+       for (i = 0; i < LCD_PAGES; i++) {
+               sed156x_cmd_transfer(LCD_PADDR | i);
+               sed156x_cmd_transfer(LCD_CADRH | 0);
+               sed156x_cmd_transfer(LCD_CADRL | 0);
+               sed156x_data_block_transfer(&hw_screen[i][0], LCD_COLUMNS);
+       }
+       memcpy(last_hw_screen, hw_screen, sizeof(last_hw_screen));
+********/
+}
+
+void sed156x_clear(void)
+{
+       memset(sw_screen, 0, sizeof(sw_screen));
+}
+
+void sed156x_output_at(int x, int y, const char *str, int size)
+{
+       int i, j;
+       u8 *p;
+       const u8 *s;
+
+       if ((unsigned int)y >= LCD_TEXT_HEIGHT || (unsigned int)x >= LCD_TEXT_WIDTH)
+               return;
+
+       p = &sw_screen[y * VIDEO_FONT_HEIGHT * LCD_BYTE_WIDTH + x * VIDEO_FONT_BYTE_WIDTH];
+
+       while (--size >= 0) {
+
+               s = &video_fontdata[((int)*str++ & 0xff) * VIDEO_FONT_BYTE_WIDTH * VIDEO_FONT_HEIGHT];
+               for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
+                       for (j = 0; j < VIDEO_FONT_BYTE_WIDTH; j++)
+                               *p++ = *s++;
+                       p += LCD_BYTE_WIDTH - VIDEO_FONT_BYTE_WIDTH;
+               }
+               p -= (LCD_BYTE_LINESZ - VIDEO_FONT_BYTE_WIDTH);
+
+               if (x >= LCD_TEXT_WIDTH)
+                       break;
+               x++;
+       }
+}
+
+void sed156x_reverse_at(int x, int y, int size)
+{
+       int i, j;
+       u8 *p;
+
+       if ((unsigned int)y >= LCD_TEXT_HEIGHT || (unsigned int)x >= LCD_TEXT_WIDTH)
+               return;
+
+       p = &sw_screen[y * VIDEO_FONT_HEIGHT * LCD_BYTE_WIDTH + x * VIDEO_FONT_BYTE_WIDTH];
+
+       while (--size >= 0) {
+
+               for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
+                       for (j = 0; j < VIDEO_FONT_BYTE_WIDTH; j++, p++)
+                               *p = ~*p;
+                       p += LCD_BYTE_WIDTH - VIDEO_FONT_BYTE_WIDTH;
+               }
+               p -= (LCD_BYTE_LINESZ - VIDEO_FONT_BYTE_WIDTH);
+
+               if (x >= LCD_TEXT_WIDTH)
+                       break;
+               x++;
+       }
+}
+
+void sed156x_scroll_line(void)
+{
+       memmove(&sw_screen[0],
+                       &sw_screen[LCD_BYTE_LINESZ],
+                       LCD_BYTE_WIDTH * (LCD_HEIGHT - VIDEO_FONT_HEIGHT));
+}
+
+void sed156x_scroll(int dx, int dy)
+{
+       u8 *p1 = NULL, *p2 = NULL, *p3 = NULL;  /* pacify gcc */
+       int adx, ady, i, sz;
+
+       adx = dx > 0 ? dx : -dx;
+       ady = dy > 0 ? dy : -dy;
+
+       /* overscroll? erase everything */
+       if (adx >= LCD_TEXT_WIDTH || ady >= LCD_TEXT_HEIGHT) {
+               memset(sw_screen, 0, sizeof(sw_screen));
+               return;
+       }
+
+       sz = LCD_BYTE_LINESZ * ady;
+       if (dy > 0) {
+               p1 = &sw_screen[0];
+               p2 = &sw_screen[sz];
+               p3 = &sw_screen[LCD_BYTE_WIDTH * LCD_HEIGHT - sz];
+       } else if (dy < 0) {
+               p1 = &sw_screen[sz];
+               p2 = &sw_screen[0];
+               p3 = &sw_screen[0];
+       }
+
+       if (ady > 0) {
+               memmove(p1, p2, LCD_BYTE_WIDTH * LCD_HEIGHT - sz);
+               memset(p3, 0, sz);
+       }
+
+       sz = VIDEO_FONT_BYTE_WIDTH * adx;
+       if (dx > 0) {
+               p1 = &sw_screen[0];
+               p2 = &sw_screen[0] + sz;
+               p3 = &sw_screen[0] + LCD_BYTE_WIDTH - sz;
+       } else if (dx < 0) {
+               p1 = &sw_screen[0] + sz;
+               p2 = &sw_screen[0];
+               p3 = &sw_screen[0];
+       }
+
+       /* xscroll */
+       if (adx > 0) {
+               for (i = 0; i < LCD_HEIGHT; i++) {
+                       memmove(p1, p2, LCD_BYTE_WIDTH - sz);
+                       memset(p3, 0, sz);
+                       p1 += LCD_BYTE_WIDTH;
+                       p2 += LCD_BYTE_WIDTH;
+                       p3 += LCD_BYTE_WIDTH;
+               }
+       }
+}
+
+void sed156x_init(void)
+{
+       int i;
+
+       SED156X_CS(1);
+       SED156X_A0(1);
+
+       /* Send initialization commands to the LCD */
+       sed156x_cmd_transfer(LCD_OFF);                  /* Turn display OFF       */
+       sed156x_cmd_transfer(LCD_BIAS);                 /* set the LCD Bias,      */
+       sed156x_cmd_transfer(LCD_ADCMODE);              /* ADC mode,              */
+       sed156x_cmd_transfer(LCD_COMDIR);               /* common output mode,    */
+       sed156x_cmd_transfer(LCD_RESRT | LCD_RRATIO);   /* resistor ratio,        */
+       sed156x_cmd_transfer(LCD_EVSET);                /* electronic volume,     */
+       sed156x_cmd_transfer(LCD_CNTRST);
+       sed156x_cmd_transfer(LCD_PWRMD | LCD_POWERM);   /* and power mode         */
+       sed156x_cmd_transfer(LCD_PADDR | 0);            /* cursor home            */
+       sed156x_cmd_transfer(LCD_CADRH | 0);
+       sed156x_cmd_transfer(LCD_CADRL | 0);
+       sed156x_cmd_transfer(LCD_LADDR | 0);            /* and display start line */
+       sed156x_cmd_transfer(LCD_DSP_NRM);              /* LCD display Normal     */
+
+       /* clear everything */
+       memset(sw_screen, 0, sizeof(sw_screen));
+       memset(hw_screen, 0, sizeof(hw_screen));
+       memset(last_hw_screen, 0, sizeof(last_hw_screen));
+
+       for (i = 0; i < LCD_PAGES; i++) {
+               sed156x_cmd_transfer(LCD_PADDR | i);
+               sed156x_cmd_transfer(LCD_CADRH | 0);
+               sed156x_cmd_transfer(LCD_CADRL | 0);
+               sed156x_data_block_transfer(&hw_screen[i][0], LCD_COLUMNS);
+       }
+
+       sed156x_clear();
+       sed156x_sync();
+       sed156x_cmd_transfer(LCD_ON);                   /* Turn display ON        */
+}
+
+#endif /* CONFIG_SED156X */
diff --git a/drivers/video/sm501.c b/drivers/video/sm501.c
new file mode 100644 (file)
index 0000000..23db02c
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * (C) Copyright 2002
+ * Stäubli Faverges - <www.staubli.com>
+ * Pierre AUBERT  p.aubert@staubli.com
+ *
+ * (C) Copyright 2005
+ * Martin Krause TQ-Systems GmbH martin.krause@tqs.de
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Basic video support for SMI SM501 "Voyager" graphic controller
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_VIDEO_SM501
+
+#include <video_fb.h>
+#include <sm501.h>
+
+#define read8(ptrReg)                \
+    *(volatile unsigned char *)(sm501.isaBase + ptrReg)
+
+#define write8(ptrReg,value) \
+    *(volatile unsigned char *)(sm501.isaBase + ptrReg) = value
+
+#define read16(ptrReg) \
+    (*(volatile unsigned short *)(sm501.isaBase + ptrReg))
+
+#define write16(ptrReg,value) \
+    (*(volatile unsigned short *)(sm501.isaBase + ptrReg) = value)
+
+#define read32(ptrReg) \
+    (*(volatile unsigned int *)(sm501.isaBase + ptrReg))
+
+#define write32(ptrReg, value) \
+    (*(volatile unsigned int *)(sm501.isaBase + ptrReg) = value)
+
+GraphicDevice sm501;
+
+/*-----------------------------------------------------------------------------
+ * SmiSetRegs --
+ *-----------------------------------------------------------------------------
+ */
+static void SmiSetRegs (void)
+{
+       /*
+        * The content of the chipset register depends on the board (clocks,
+        * ...)
+        */
+       const SMI_REGS *preg = board_get_regs ();
+       while (preg->Index) {
+               write32 (preg->Index, preg->Value);
+               /*
+                * Insert a delay between
+                */
+               udelay (1000);
+               preg ++;
+       }
+}
+
+/*-----------------------------------------------------------------------------
+ * video_hw_init --
+ *-----------------------------------------------------------------------------
+ */
+void *video_hw_init (void)
+{
+       unsigned int *vm, i;
+
+       memset (&sm501, 0, sizeof (GraphicDevice));
+
+       /*
+        * Initialization of the access to the graphic chipset Retreive base
+        * address of the chipset (see board/RPXClassic/eccx.c)
+        */
+       if ((sm501.isaBase = board_video_init ()) == 0) {
+               return (NULL);
+       }
+
+       if ((sm501.frameAdrs = board_video_get_fb ()) == 0) {
+               return (NULL);
+       }
+
+       sm501.winSizeX = board_get_width ();
+       sm501.winSizeY = board_get_height ();
+
+#if defined(CONFIG_VIDEO_SM501_8BPP)
+       sm501.gdfIndex = GDF__8BIT_INDEX;
+       sm501.gdfBytesPP = 1;
+
+#elif defined(CONFIG_VIDEO_SM501_16BPP)
+       sm501.gdfIndex = GDF_16BIT_565RGB;
+       sm501.gdfBytesPP = 2;
+
+#elif defined(CONFIG_VIDEO_SM501_32BPP)
+       sm501.gdfIndex = GDF_32BIT_X888RGB;
+       sm501.gdfBytesPP = 4;
+#else
+#error Unsupported SM501 BPP
+#endif
+
+       sm501.memSize = sm501.winSizeX * sm501.winSizeY * sm501.gdfBytesPP;
+
+       /* Load Smi registers */
+       SmiSetRegs ();
+
+       /* (see board/RPXClassic/RPXClassic.c) */
+       board_validate_screen (sm501.isaBase);
+
+       /* Clear video memory */
+       i = sm501.memSize/4;
+       vm = (unsigned int *)sm501.frameAdrs;
+       while(i--)
+               *vm++ = 0;
+
+       return (&sm501);
+}
+
+/*-----------------------------------------------------------------------------
+ * video_set_lut --
+ *-----------------------------------------------------------------------------
+ */
+void video_set_lut (
+       unsigned int index,           /* color number */
+       unsigned char r,              /* red */
+       unsigned char g,              /* green */
+       unsigned char b               /* blue */
+       )
+{
+}
+
+#endif /* CONFIG_VIDEO_SM501 */
diff --git a/drivers/video/smiLynxEM.c b/drivers/video/smiLynxEM.c
new file mode 100644 (file)
index 0000000..20f9beb
--- /dev/null
@@ -0,0 +1,858 @@
+/*
+ * (C) Copyright 1997-2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.        See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * smiLynxEM.c
+ *
+ * Silicon Motion graphic interface for sm810/sm710/sm712 accelerator
+ *
+ * modification history
+ * --------------------
+ * 04-18-2002 Rewritten for U-Boot <fgottschling@eltec.de>.
+ *
+ * 18-03-2004 - Unify videomodes handling with the ct69000
+ *            - The video output can be set via the variable "videoout"
+ *              in the environment.
+ *              videoout=1 output on LCD
+ *              videoout=2 output on CRT (default value)
+ *                     <p.aubert@staubli.com>
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_VIDEO_SMI_LYNXEM)
+
+#include <pci.h>
+#include <video_fb.h>
+#include "videomodes.h"
+/*
+ * Export Graphic Device
+ */
+GraphicDevice smi;
+
+/*
+ * SMI 710/712 have 4MB internal RAM; SMI 810 2MB internal + 2MB external
+ */
+#define VIDEO_MEM_SIZE 0x400000
+
+
+/*
+ * ISA mapped regs
+ */
+#define SMI_INDX_C4            (pGD->isaBase + 0x03c4)    /* index reg */
+#define SMI_DATA_C5            (pGD->isaBase + 0x03c5)    /* data reg */
+#define SMI_INDX_D4            (pGD->isaBase + 0x03d4)    /* index reg */
+#define SMI_DATA_D5            (pGD->isaBase + 0x03d5)    /* data reg */
+#define SMI_ISR1               (pGD->isaBase + 0x03ca)
+#define SMI_INDX_CE            (pGD->isaBase + 0x03ce)    /* index reg */
+#define SMI_DATA_CF            (pGD->isaBase + 0x03cf)    /* data reg */
+#define SMI_LOCK_REG           (pGD->isaBase + 0x03c3)    /* unlock/lock ext crt reg */
+#define SMI_MISC_REG           (pGD->isaBase + 0x03c2)    /* misc reg */
+#define SMI_LUT_MASK           (pGD->isaBase + 0x03c6)    /* lut mask reg */
+#define SMI_LUT_START          (pGD->isaBase + 0x03c8)    /* lut start index */
+#define SMI_LUT_RGB            (pGD->isaBase + 0x03c9)    /* lut colors auto incr.*/
+#define SMI_INDX_ATTR          (pGD->isaBase + 0x03c0)    /* attributes index reg */
+
+/*
+ * Video processor control
+ */
+typedef struct {
+       unsigned int   control;
+       unsigned int   colorKey;
+       unsigned int   colorKeyMask;
+       unsigned int   start;
+       unsigned short offset;
+       unsigned short width;
+       unsigned int   fifoPrio;
+       unsigned int   fifoERL;
+       unsigned int   YUVtoRGB;
+} SmiVideoProc;
+
+/*
+ * Video window control
+ */
+typedef struct {
+       unsigned short top;
+       unsigned short left;
+       unsigned short bottom;
+       unsigned short right;
+       unsigned int   srcStart;
+       unsigned short width;
+       unsigned short offset;
+       unsigned char  hStretch;
+       unsigned char  vStretch;
+} SmiVideoWin;
+
+/*
+ * Capture port control
+ */
+typedef struct {
+       unsigned int   control;
+       unsigned short topClip;
+       unsigned short leftClip;
+       unsigned short srcHeight;
+       unsigned short srcWidth;
+       unsigned int   srcBufStart1;
+       unsigned int   srcBufStart2;
+       unsigned short srcOffset;
+       unsigned short fifoControl;
+} SmiCapturePort;
+
+
+/*
+ * Register values for common video modes
+ */
+static char SMI_SCR[] = {
+       /* all modes */
+       0x10, 0xff, 0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x15, 0x90,
+       0x17, 0x20, 0x18, 0xb1, 0x19, 0x00,
+};
+static char SMI_EXT_CRT[] = {
+       0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
+       0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00,
+};
+static char SMI_ATTR [] = {
+       0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05,
+       0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b,
+       0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x41, 0x11, 0x00,
+       0x12, 0x0f, 0x13, 0x00, 0x14, 0x00,
+};
+static char SMI_GCR[18] = {
+       0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x40,
+       0x06, 0x05, 0x07, 0x0f, 0x08, 0xff,
+};
+static char SMI_SEQR[] = {
+       0x00, 0x00, 0x01, 0x01, 0x02, 0x0f, 0x03, 0x03, 0x04, 0x0e, 0x00, 0x03,
+};
+static char SMI_PCR [] = {
+       0x20, 0x04, 0x21, 0x30, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00,
+};
+static char SMI_MCR[] = {
+       0x60, 0x01, 0x61, 0x00,
+#ifdef CONFIG_HMI1001
+       0x62, 0x74, /* Memory type is not configured by pins on HMI1001 */
+#endif
+};
+
+static char SMI_HCR[] = {
+       0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
+       0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00,
+};
+
+
+/*******************************************************************************
+ *
+ * Write SMI ISA register
+ */
+static void smiWrite (unsigned short index, char reg, char val)
+{
+       register GraphicDevice *pGD = (GraphicDevice *)&smi;
+
+       out8 ((pGD->isaBase + index), reg);
+       out8 ((pGD->isaBase + index + 1), val);
+}
+
+/*******************************************************************************
+ *
+ * Write a table of SMI ISA register
+ */
+static void smiLoadRegs (
+       unsigned int iReg,
+       unsigned int dReg,
+       char         *regTab,
+       unsigned int tabSize
+       )
+{
+       register GraphicDevice *pGD  = (GraphicDevice *)&smi;
+       register int i;
+
+       for (i=0; i<tabSize; i+=2) {
+               if (iReg == SMI_INDX_ATTR) {
+                       /* Reset the Flip Flop */
+                       in8 (SMI_ISR1);
+                       out8 (iReg, regTab[i]);
+                       out8 (iReg, regTab[i+1]);
+               } else {
+                       out8 (iReg, regTab[i]);
+                       out8 (dReg, regTab[i+1]);
+               }
+       }
+}
+
+/*******************************************************************************
+ *
+ * Init capture port registers
+ */
+static void smiInitCapturePort (void)
+{
+       SmiCapturePort smiCP = { 0x01400600, 0x30, 0x40, 480, 640, 0, 0, 2560, 6 };
+       register GraphicDevice *pGD  = (GraphicDevice *)&smi;
+       register SmiCapturePort *pCP = (SmiCapturePort *)&smiCP;
+
+       out32r ((pGD->cprBase + 0x0004), ((pCP->topClip<<16)   | pCP->leftClip));
+       out32r ((pGD->cprBase + 0x0008), ((pCP->srcHeight<<16) | pCP->srcWidth));
+       out32r ((pGD->cprBase + 0x000c), pCP->srcBufStart1/8);
+       out32r ((pGD->cprBase + 0x0010), pCP->srcBufStart2/8);
+       out32r ((pGD->cprBase + 0x0014), pCP->srcOffset/8);
+       out32r ((pGD->cprBase + 0x0018), pCP->fifoControl);
+       out32r ((pGD->cprBase + 0x0000), pCP->control);
+}
+
+
+/*******************************************************************************
+ *
+ * Init video processor registers
+ */
+static void smiInitVideoProcessor (void)
+{
+       SmiVideoProc smiVP = { 0x100000, 0, 0, 0, 0, 1600, 0x1200543, 4, 0xededed };
+       SmiVideoWin  smiVW = { 0, 0, 599, 799, 0, 1600, 0, 0, 0 };
+       register GraphicDevice *pGD = (GraphicDevice *)&smi;
+       register SmiVideoProc  *pVP = (SmiVideoProc *)&smiVP;
+       register SmiVideoWin *pVWin = (SmiVideoWin *)&smiVW;
+
+       pVP->width    = pGD->plnSizeX * pGD->gdfBytesPP;
+       pVP->control |= pGD->gdfIndex << 16;
+       pVWin->bottom = pGD->winSizeY - 1;
+       pVWin->right  = pGD->winSizeX - 1;
+       pVWin->width  = pVP->width;
+
+       /* color key */
+       out32r ((pGD->vprBase + 0x0004), pVP->colorKey);
+
+       /* color key mask */
+       out32r ((pGD->vprBase + 0x0008), pVP->colorKeyMask);
+
+       /* data src start adrs */
+       out32r ((pGD->vprBase + 0x000c), pVP->start / 8);
+
+       /* data width and offset */
+       out32r ((pGD->vprBase + 0x0010),
+               ((pVP->offset   / 8 * pGD->gdfBytesPP) << 16) |
+               (pGD->plnSizeX / 8 * pGD->gdfBytesPP));
+
+       /* video window 1 */
+       out32r ((pGD->vprBase + 0x0014),
+               ((pVWin->top << 16) | pVWin->left));
+
+       out32r ((pGD->vprBase + 0x0018),
+               ((pVWin->bottom << 16) | pVWin->right));
+
+       out32r ((pGD->vprBase + 0x001c), pVWin->srcStart / 8);
+
+       out32r ((pGD->vprBase + 0x0020),
+               (((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
+
+       out32r ((pGD->vprBase + 0x0024),
+               (((pVWin->hStretch) << 8) | pVWin->vStretch));
+
+       /* video window 2 */
+       out32r ((pGD->vprBase + 0x0028),
+               ((pVWin->top << 16) | pVWin->left));
+
+       out32r ((pGD->vprBase + 0x002c),
+               ((pVWin->bottom << 16) | pVWin->right));
+
+       out32r ((pGD->vprBase + 0x0030),
+               pVWin->srcStart / 8);
+
+       out32r ((pGD->vprBase + 0x0034),
+               (((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
+
+       out32r ((pGD->vprBase + 0x0038),
+               (((pVWin->hStretch) << 8) | pVWin->vStretch));
+
+       /* fifo prio control */
+       out32r ((pGD->vprBase + 0x0054), pVP->fifoPrio);
+
+       /* fifo empty request levell */
+       out32r ((pGD->vprBase + 0x0058), pVP->fifoERL);
+
+       /* conversion constant */
+       out32r ((pGD->vprBase + 0x005c), pVP->YUVtoRGB);
+
+       /* vpr control word */
+       out32r ((pGD->vprBase + 0x0000), pVP->control);
+}
+
+/******************************************************************************
+ *
+ * Init drawing engine registers
+ */
+static void smiInitDrawingEngine (void)
+{
+       GraphicDevice *pGD = (GraphicDevice *)&smi;
+       unsigned int val;
+
+       /* don't start now */
+       out32r ((pGD->dprBase + 0x000c), 0x000f0000);
+
+       /* set rop2 to copypen */
+       val = 0xffff3ff0 & in32r ((pGD->dprBase + 0x000c));
+       out32r ((pGD->dprBase + 0x000c), (val | 0x8000 | 0x0c));
+
+       /* set clip rect */
+       out32r ((pGD->dprBase + 0x002c), 0);
+       out32r ((pGD->dprBase + 0x0030),
+               ((pGD->winSizeY<<16) | pGD->winSizeX * pGD->gdfBytesPP ));
+
+       /* src row pitch */
+       val = 0xffff0000 & (in32r ((pGD->dprBase + 0x0010)));
+       out32r ((pGD->dprBase + 0x0010),
+               (val | pGD->plnSizeX * pGD->gdfBytesPP));
+
+       /* dst row pitch */
+       val = 0x0000ffff & (in32r ((pGD->dprBase + 0x0010)));
+       out32r ((pGD->dprBase + 0x0010),
+               (((pGD->plnSizeX * pGD->gdfBytesPP)<<16) | val));
+
+       /* window width src/dst */
+       out32r ((pGD->dprBase + 0x003c),
+               (((pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)<<16) |
+                (pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)));
+       out16r ((pGD->dprBase + 0x001e), 0x0000);
+
+       /* src base adrs */
+       out32r ((pGD->dprBase + 0x0040),
+               (((pGD->frameAdrs/8) & 0x000fffff)));
+
+       /* dst base adrs */
+       out32r ((pGD->dprBase + 0x0044),
+               (((pGD->frameAdrs/8) & 0x000fffff)));
+
+       /* foreground color */
+       out32r ((pGD->dprBase + 0x0014), pGD->fg);
+
+       /* background color */
+       out32r ((pGD->dprBase + 0x0018), pGD->bg);
+
+       /* xcolor */
+       out32r ((pGD->dprBase + 0x0020), 0x00ffffff);
+
+       /* xcolor mask */
+       out32r ((pGD->dprBase + 0x0024), 0x00ffffff);
+
+       /* bit mask */
+       out32r ((pGD->dprBase + 0x0028), 0x00ffffff);
+
+       /* load mono pattern */
+       out32r ((pGD->dprBase + 0x0034), 0);
+       out32r ((pGD->dprBase + 0x0038), 0);
+}
+
+static struct pci_device_id supported[] = {
+       { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_710 },
+       { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_712 },
+       { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_810 },
+       { }
+};
+
+/*****************************************************************************/
+static void smiLoadMsr (struct ctfb_res_modes *mode)
+{
+       unsigned char h_synch_high, v_synch_high;
+       register GraphicDevice *pGD  = (GraphicDevice *)&smi;
+
+       h_synch_high = (mode->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 0x40;  /* horizontal Synch High active */
+       v_synch_high = (mode->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 0x80; /* vertical Synch High active */
+       out8 (SMI_MISC_REG, (h_synch_high | v_synch_high | 0x29));
+       /* upper64K==0x20, CLC2select==0x08, RAMenable==0x02!(todo), CGA==0x01
+        * Selects the upper 64KB page.Bit5=1
+        * CLK2 (left reserved in standard VGA) Bit3|2=1|0
+        * Disables CPU access to frame buffer. Bit1=0
+        * Sets the I/O address decode for ST01, FCR, and all CR registers
+        * to the 3Dx I/O address range (CGA emulation). Bit0=1
+        */
+}
+/*****************************************************************************/
+static void smiLoadCrt (struct ctfb_res_modes *var, int bits_per_pixel)
+{
+       unsigned char cr[0x7a];
+       int i;
+       unsigned int hd, hs, he, ht, hbs, hbe;  /* Horizontal.  */
+       unsigned int vd, vs, ve, vt, vbs, vbe;  /* vertical */
+       unsigned int bpp, wd, dblscan, interlaced;
+
+       const int LineCompare = 0x3ff;
+       unsigned int TextScanLines = 1; /* this is in fact a vertical zoom factor   */
+       register GraphicDevice *pGD  = (GraphicDevice *)&smi;
+
+       /* Horizontal */
+       hd = (var->xres) / 8;   /* HDisp.  */
+       hs = (var->xres + var->right_margin) / 8;       /* HsStrt  */
+       he = (var->xres + var->right_margin + var->hsync_len) / 8;      /* HsEnd   */
+       ht = (var->left_margin + var->xres + var->right_margin + var->hsync_len) / 8;   /* HTotal  */
+       /* Blank */
+       hbs = hd;
+       hbe = 0; /* Blank end at 0 */
+
+       /* Vertical */
+       vd = var->yres;         /* VDisplay   */
+       vs = var->yres + var->lower_margin;     /* VSyncStart */
+       ve = var->yres + var->lower_margin + var->vsync_len;    /* VSyncEnd */
+       vt = var->upper_margin + var->yres + var->lower_margin + var->vsync_len;        /* VTotal  */
+       vbs = vd;
+       vbe = 0;
+
+       bpp = bits_per_pixel;
+       dblscan = (var->vmode & FB_VMODE_DOUBLE) ? 1 : 0;
+       interlaced = var->vmode & FB_VMODE_INTERLACED;
+
+
+       if (bpp == 15)
+               bpp = 16;
+       wd = var->xres * bpp / 64;      /* double words per line */
+       if (interlaced) {       /* we divide all vertical timings, exept vd */
+               vs >>= 1;
+               vbs >>= 1;
+               ve >>= 1;
+               vt >>= 1;
+       }
+
+       memset (cr, 0, sizeof (cr));
+       cr[0x00] = ht - 5;
+       cr[0x01] = hd - 1;
+       cr[0x02] = hbs - 1;
+       cr[0x03] = (hbe & 0x1F);
+       cr[0x04] = hs;
+       cr[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
+
+       cr[0x06] = (vt - 2) & 0xFF;
+       cr[0x07] = (((vt - 2) & 0x100) >> 8)
+               | (((vd - 1) & 0x100) >> 7)
+               | ((vs & 0x100) >> 6)
+               | (((vbs - 1) & 0x100) >> 5)
+               | ((LineCompare & 0x100) >> 4)
+               | (((vt - 2) & 0x200) >> 4)
+               | (((vd - 1) & 0x200) >> 3)
+               | ((vs & 0x200) >> 2);
+
+       cr[0x30] = ((vt - 2) & 0x400) >> 7
+               | (((vd - 1) & 0x400) >> 8)
+               | (((vbs - 1) & 0x400) >> 9)
+               | ((vs & 0x400) >> 10)
+               | (interlaced) ? 0x80 : 0;
+
+
+       cr[0x08] = 0x00;
+       cr[0x09] = (dblscan << 7)
+               | ((LineCompare & 0x200) >> 3)
+               | (((vbs - 1) & 0x200) >> 4)
+               | (TextScanLines - 1);
+
+       cr[0x10] = vs & 0xff;   /* VSyncPulseStart */
+       cr[0x11] = (ve & 0x0f);
+       cr[0x12] = (vd - 1) & 0xff;     /* LineCount  */
+       cr[0x13] = wd & 0xff;
+       cr[0x14] = 0x40;
+       cr[0x15] = (vbs - 1) & 0xff;
+       cr[0x16] = vbe & 0xff;
+       cr[0x17] = 0xe3;        /* but it does not work */
+       cr[0x18] = 0xff & LineCompare;
+       cr[0x22] = 0x00;        /* todo? */
+
+
+       /* now set the registers */
+       for (i = 0; i <= 0x18; i++) {   /*CR00 .. CR18 */
+               smiWrite (SMI_INDX_D4, i, cr[i]);
+       }
+       i = 0x22;               /*CR22 */
+       smiWrite (SMI_INDX_D4, i, cr[i]);
+       i = 0x30;               /*CR30 */
+       smiWrite (SMI_INDX_D4, i, cr[i]);
+}
+
+/*****************************************************************************/
+#define REF_FREQ       14318180
+#define PMIN           1
+#define PMAX           255
+#define QMIN           1
+#define QMAX           63
+
+static unsigned int FindPQ (unsigned int freq, unsigned int *pp, unsigned int *pq)
+{
+       unsigned int n = QMIN, m = 0;
+       long long int L = 0, P = freq, Q = REF_FREQ, H = P >> 1;
+       long long int D = 0x7ffffffffffffffLL;
+
+       for (n = QMIN; n <= QMAX; n++) {
+               m = PMIN;       /* p/q ~ freq/ref -> p*ref-freq*q ~ 0 */
+               L = P * n - m * Q;
+               while (L > 0 && m < PMAX) {
+                       L -= REF_FREQ;  /* difference is greater as 0 subtract fref */
+                       m++;    /* and increment m */
+               }
+               /* difference is less or equal than 0 or m > maximum */
+               if (m > PMAX)
+                       break;  /* no solution: if we increase n we get the same situation */
+               /* L is <= 0 now */
+               if (-L > H && m > PMIN) {       /* if difference > the half fref */
+                       L += REF_FREQ;  /* we take the situation before */
+                       m--;    /* because its closer to 0 */
+               }
+               L = (L < 0) ? -L : +L;  /* absolute value */
+               if (D < L)      /* if last difference was better take next n */
+                       continue;
+               D = L;
+               *pp = m;
+               *pq = n;        /*  keep improved data */
+               if (D == 0)
+                       break;  /* best result we can get */
+       }
+       return (unsigned int) (0xffffffff & D);
+}
+
+/*****************************************************************************/
+static void smiLoadCcr (struct ctfb_res_modes *var, unsigned short device_id)
+{
+       unsigned int p = 0;
+       unsigned int q = 0;
+       long long freq;
+       register GraphicDevice *pGD  = (GraphicDevice *)&smi;
+
+       smiWrite (SMI_INDX_C4, 0x65, 0);
+       smiWrite (SMI_INDX_C4, 0x66, 0);
+       smiWrite (SMI_INDX_C4, 0x68, 0x50);
+       if (device_id == PCI_DEVICE_ID_SMI_810) {
+               smiWrite (SMI_INDX_C4, 0x69, 0x3);
+       } else {
+               smiWrite (SMI_INDX_C4, 0x69, 0x0);
+       }
+
+       /* Memory clock */
+       switch (device_id) {
+       case PCI_DEVICE_ID_SMI_710 :
+               smiWrite (SMI_INDX_C4, 0x6a, 0x75);
+               break;
+       case PCI_DEVICE_ID_SMI_712 :
+               smiWrite (SMI_INDX_C4, 0x6a, 0x80);
+               break;
+       default :
+               smiWrite (SMI_INDX_C4, 0x6a, 0x53);
+               break;
+       }
+       smiWrite (SMI_INDX_C4, 0x6b, 0x15);
+
+       /* VCLK */
+       freq = 1000000000000LL / var -> pixclock;
+
+       FindPQ ((unsigned int)freq, &p, &q);
+
+       smiWrite (SMI_INDX_C4, 0x6c, p);
+       smiWrite (SMI_INDX_C4, 0x6d, q);
+
+}
+
+/*******************************************************************************
+ *
+ * Init video chip with common Linux graphic modes (lilo)
+ */
+void *video_hw_init (void)
+{
+       GraphicDevice *pGD = (GraphicDevice *)&smi;
+       unsigned short device_id;
+       pci_dev_t devbusfn;
+       int videomode;
+       unsigned long t1, hsynch, vsynch;
+       unsigned int pci_mem_base, *vm;
+       char *penv;
+       int tmp, i, bits_per_pixel;
+       struct ctfb_res_modes *res_mode;
+       struct ctfb_res_modes var_mode;
+       unsigned char videoout;
+
+       /* Search for video chip */
+       printf("Video: ");
+
+       if ((devbusfn = pci_find_devices(supported, 0)) < 0)
+       {
+               printf ("Controller not found !\n");
+               return (NULL);
+       }
+
+       /* PCI setup */
+       pci_write_config_dword (devbusfn, PCI_COMMAND, (PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
+       pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
+       pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
+       pci_mem_base = pci_mem_to_phys (devbusfn, pci_mem_base);
+
+       tmp = 0;
+
+       videomode = CFG_DEFAULT_VIDEO_MODE;
+       /* get video mode via environment */
+       if ((penv = getenv ("videomode")) != NULL) {
+               /* deceide if it is a string */
+               if (penv[0] <= '9') {
+                       videomode = (int) simple_strtoul (penv, NULL, 16);
+                       tmp = 1;
+               }
+       } else {
+               tmp = 1;
+       }
+       if (tmp) {
+               /* parameter are vesa modes */
+               /* search params */
+               for (i = 0; i < VESA_MODES_COUNT; i++) {
+                       if (vesa_modes[i].vesanr == videomode)
+                               break;
+               }
+               if (i == VESA_MODES_COUNT) {
+                       printf ("no VESA Mode found, switching to mode 0x%x ", CFG_DEFAULT_VIDEO_MODE);
+                       i = 0;
+               }
+               res_mode =
+                       (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].
+                                                                resindex];
+               bits_per_pixel = vesa_modes[i].bits_per_pixel;
+       } else {
+
+               res_mode = (struct ctfb_res_modes *) &var_mode;
+               bits_per_pixel = video_get_params (res_mode, penv);
+       }
+
+       /* calculate hsynch and vsynch freq (info only) */
+       t1 = (res_mode->left_margin + res_mode->xres +
+             res_mode->right_margin + res_mode->hsync_len) / 8;
+       t1 *= 8;
+       t1 *= res_mode->pixclock;
+       t1 /= 1000;
+       hsynch = 1000000000L / t1;
+       t1 *=
+               (res_mode->upper_margin + res_mode->yres +
+                res_mode->lower_margin + res_mode->vsync_len);
+       t1 /= 1000;
+       vsynch = 1000000000L / t1;
+
+       /* fill in Graphic device struct */
+       sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
+                res_mode->yres, bits_per_pixel, (hsynch / 1000),
+                (vsynch / 1000));
+       printf ("%s\n", pGD->modeIdent);
+       pGD->winSizeX = res_mode->xres;
+       pGD->winSizeY = res_mode->yres;
+       pGD->plnSizeX = res_mode->xres;
+       pGD->plnSizeY = res_mode->yres;
+       switch (bits_per_pixel) {
+       case 8:
+               pGD->gdfBytesPP = 1;
+               pGD->gdfIndex = GDF__8BIT_INDEX;
+               break;
+       case 15:
+               pGD->gdfBytesPP = 2;
+               pGD->gdfIndex = GDF_15BIT_555RGB;
+               break;
+       case 16:
+               pGD->gdfBytesPP = 2;
+               pGD->gdfIndex = GDF_16BIT_565RGB;
+               break;
+       case 24:
+               pGD->gdfBytesPP = 3;
+               pGD->gdfIndex = GDF_24BIT_888RGB;
+               break;
+       }
+
+       pGD->isaBase = CFG_ISA_IO;
+       pGD->pciBase = pci_mem_base;
+       pGD->dprBase = (pci_mem_base + 0x400000 + 0x8000);
+       pGD->vprBase = (pci_mem_base + 0x400000 + 0xc000);
+       pGD->cprBase = (pci_mem_base + 0x400000 + 0xe000);
+       pGD->frameAdrs = pci_mem_base;
+       pGD->memSize = VIDEO_MEM_SIZE;
+
+       /* Set up hardware : select color mode,
+          set Register base to isa 3dx for 3?x regs*/
+       out8 (SMI_MISC_REG, 0x01);
+
+       /* Turn off display */
+       smiWrite (SMI_INDX_C4, 0x01, 0x20);
+
+       /* Unlock ext. crt regs */
+       out8 (SMI_LOCK_REG, 0x40);
+
+       /* Unlock crt regs 0-7 */
+       smiWrite (SMI_INDX_D4, 0x11, 0x0e);
+
+       /* Sytem Control Register */
+       smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_SCR, sizeof(SMI_SCR));
+
+       /* extented CRT Register */
+       smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5, SMI_EXT_CRT, sizeof(SMI_EXT_CRT));
+
+       /* Attributes controller registers */
+       smiLoadRegs (SMI_INDX_ATTR, SMI_INDX_ATTR, SMI_ATTR, sizeof(SMI_ATTR));
+
+       /* Graphics Controller Register */
+       smiLoadRegs (SMI_INDX_CE, SMI_DATA_CF, SMI_GCR, sizeof(SMI_GCR));
+
+       /* Sequencer Register */
+       smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_SEQR, sizeof(SMI_SEQR));
+
+       /* Power Control Register */
+       smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_PCR, sizeof(SMI_PCR));
+
+       /* Memory Control Register */
+       /* Register MSR62 is a power on configurable register. We don't */
+       /* modify it */
+       smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_MCR, sizeof(SMI_MCR));
+
+       /* Set misc output register */
+       smiLoadMsr (res_mode);
+
+       /* Set CRT and Clock control registers */
+       smiLoadCrt (res_mode, bits_per_pixel);
+
+       smiLoadCcr (res_mode, device_id);
+
+       /* Hardware Cusor Register */
+       smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_HCR, sizeof(SMI_HCR));
+
+       /* Enable  Display  */
+       videoout = 2;       /* Default output is CRT */
+       if ((penv = getenv ("videoout")) != NULL) {
+               /* deceide if it is a string */
+               videoout = (int) simple_strtoul (penv, NULL, 16);
+       }
+       smiWrite (SMI_INDX_C4, 0x31, videoout);
+
+       /* Video processor default setup */
+       smiInitVideoProcessor ();
+
+       /* Capture port default setup */
+       smiInitCapturePort ();
+
+       /* Drawing engine default setup */
+       smiInitDrawingEngine ();
+
+       /* Turn on display */
+       smiWrite (0x3c4, 0x01, 0x01);
+
+       /* Clear video memory */
+       i = pGD->memSize/4;
+       vm = (unsigned int *)pGD->pciBase;
+       while(i--)
+               *vm++ = 0;
+       return ((void*)&smi);
+}
+
+/*******************************************************************************
+ *
+ * Drawing engine fill on screen region
+ */
+void video_hw_rectfill (
+       unsigned int bpp,             /* bytes per pixel */
+       unsigned int dst_x,           /* dest pos x */
+       unsigned int dst_y,           /* dest pos y */
+       unsigned int dim_x,           /* frame width */
+       unsigned int dim_y,           /* frame height */
+       unsigned int color            /* fill color */
+       )
+{
+       register GraphicDevice *pGD = (GraphicDevice *)&smi;
+       register unsigned int control;
+
+       dim_x *= bpp;
+
+       out32r ((pGD->dprBase + 0x0014), color);
+       out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
+       out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
+
+       control = 0x0000ffff &  in32r ((pGD->dprBase + 0x000c));
+
+       control |= 0x80010000;
+
+       out32r ((pGD->dprBase + 0x000c),  control);
+
+       /* Wait for drawing processor */
+       do
+       {
+               out8 ((pGD->isaBase + 0x3c4), 0x16);
+       } while (in8 (pGD->isaBase + 0x3c5) & 0x08);
+}
+
+/*******************************************************************************
+ *
+ * Drawing engine bitblt with screen region
+ */
+void video_hw_bitblt (
+       unsigned int bpp,             /* bytes per pixel */
+       unsigned int src_x,           /* source pos x */
+       unsigned int src_y,           /* source pos y */
+       unsigned int dst_x,           /* dest pos x */
+       unsigned int dst_y,           /* dest pos y */
+       unsigned int dim_x,           /* frame width */
+       unsigned int dim_y            /* frame height */
+       )
+{
+       register GraphicDevice *pGD = (GraphicDevice *)&smi;
+       register unsigned int control;
+
+       dim_x *= bpp;
+
+       if ((src_y<dst_y) || ((src_y==dst_y) && (src_x<dst_x)))
+       {
+               out32r ((pGD->dprBase + 0x0000), (((src_x+dim_x-1)<<16) | (src_y+dim_y-1)));
+               out32r ((pGD->dprBase + 0x0004), (((dst_x+dim_x-1)<<16) | (dst_y+dim_y-1)));
+               control = 0x88000000;
+       } else {
+               out32r ((pGD->dprBase + 0x0000), ((src_x<<16) | src_y));
+               out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
+               control = 0x80000000;
+       }
+
+       out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
+       control |= (0x0000ffff &  in32r ((pGD->dprBase + 0x000c)));
+       out32r ((pGD->dprBase + 0x000c), control);
+
+       /* Wait for drawing processor */
+       do
+       {
+               out8 ((pGD->isaBase + 0x3c4), 0x16);
+       } while (in8 (pGD->isaBase + 0x3c5) & 0x08);
+}
+
+/*******************************************************************************
+ *
+ * Set a RGB color in the LUT (8 bit index)
+ */
+void video_set_lut (
+       unsigned int index,           /* color number */
+       unsigned char r,              /* red */
+       unsigned char g,              /* green */
+       unsigned char b               /* blue */
+       )
+{
+       register GraphicDevice *pGD = (GraphicDevice *)&smi;
+
+       out8 (SMI_LUT_MASK,  0xff);
+
+       out8 (SMI_LUT_START, (char)index);
+
+       out8 (SMI_LUT_RGB, r>>2);    /* red */
+       udelay (10);
+       out8 (SMI_LUT_RGB, g>>2);    /* green */
+       udelay (10);
+       out8 (SMI_LUT_RGB, b>>2);    /* blue */
+       udelay (10);
+}
+
+#endif /* CONFIG_VIDEO_SMI_LYNXEM */
diff --git a/drivers/video/videomodes.c b/drivers/video/videomodes.c
new file mode 100644 (file)
index 0000000..c81e5bc
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * (C) Copyright 2004
+ * Pierre Aubert, Staubli Faverges , <p.aubert@staubli.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/************************************************************************
+  Get Parameters for the video mode:
+  The default video mode can be defined in CFG_DEFAULT_VIDEO_MODE.
+  If undefined, default video mode is set to 0x301
+  Parameters can be set via the variable "videomode" in the environment.
+  2 diferent ways are possible:
+  "videomode=301"   - 301 is a hexadecimal number describing the VESA
+                     mode. Following modes are implemented:
+
+                     Colors    640x480 800x600 1024x768 1152x864 1280x1024
+                    --------+---------------------------------------------
+                     8 bits |  0x301   0x303    0x305    0x161     0x307
+                    15 bits |  0x310   0x313    0x316    0x162     0x319
+                    16 bits |  0x311   0x314    0x317    0x163     0x31A
+                    24 bits |  0x312   0x315    0x318      ?       0x31B
+                    --------+---------------------------------------------
+  "videomode=bootargs"
+                  - the parameters are parsed from the bootargs.
+                     The format is "NAME:VALUE,NAME:VALUE" etc.
+                     Ex.:
+                     "bootargs=video=ctfb:x:800,y:600,depth:16,pclk:25000"
+                     Parameters not included in the list will be taken from
+                     the default mode, which is one of the following:
+                     mode:0  640x480x24
+                     mode:1  800x600x16
+                     mode:2  1024x768x8
+                     mode:3  960x720x24
+                     mode:4  1152x864x16
+                     mode:5  1280x1024x8
+
+                     if "mode" is not provided within the parameter list,
+                     mode:0 is assumed.
+                     Following parameters are supported:
+                     x       xres = visible resolution horizontal
+                     y       yres = visible resolution vertical
+                     pclk    pixelclocks in pico sec
+                     le      left_marging time from sync to picture in pixelclocks
+                     ri      right_marging time from picture to sync in pixelclocks
+                     up      upper_margin time from sync to picture
+                     lo      lower_margin
+                     hs      hsync_len length of horizontal sync
+                     vs      vsync_len length of vertical sync
+                     sync    see FB_SYNC_*
+                     vmode   see FB_VMODE_*
+                     depth   Color depth in bits per pixel
+                     All other parameters in the variable bootargs are ignored.
+                     It is also possible to set the parameters direct in the
+                     variable "videomode", or in another variable i.e.
+                     "myvideo" and setting the variable "videomode=myvideo"..
+****************************************************************************/
+
+#include <common.h>
+#include "videomodes.h"
+
+const struct ctfb_vesa_modes vesa_modes[VESA_MODES_COUNT] = {
+       {0x301, RES_MODE_640x480, 8},
+       {0x310, RES_MODE_640x480, 15},
+       {0x311, RES_MODE_640x480, 16},
+       {0x312, RES_MODE_640x480, 24},
+       {0x303, RES_MODE_800x600, 8},
+       {0x313, RES_MODE_800x600, 15},
+       {0x314, RES_MODE_800x600, 16},
+       {0x315, RES_MODE_800x600, 24},
+       {0x305, RES_MODE_1024x768, 8},
+       {0x316, RES_MODE_1024x768, 15},
+       {0x317, RES_MODE_1024x768, 16},
+       {0x318, RES_MODE_1024x768, 24},
+       {0x161, RES_MODE_1152x864, 8},
+       {0x162, RES_MODE_1152x864, 15},
+       {0x163, RES_MODE_1152x864, 16},
+       {0x307, RES_MODE_1280x1024, 8},
+       {0x319, RES_MODE_1280x1024, 15},
+       {0x31A, RES_MODE_1280x1024, 16},
+       {0x31B, RES_MODE_1280x1024, 24},
+};
+const struct ctfb_res_modes res_mode_init[RES_MODES_COUNT] = {
+       /* x     y pixclk   le  ri  up  lo   hs vs  s  vmode */
+       {640, 480, 39721, 40, 24, 32, 11, 96, 2, 0, FB_VMODE_NONINTERLACED},
+       {800, 600, 27778, 64, 24, 22, 1, 72, 2, 0, FB_VMODE_NONINTERLACED},
+       {1024, 768, 15384, 168, 8, 29, 3, 144, 4, 0, FB_VMODE_NONINTERLACED},
+       {960, 720, 13100, 160, 40, 32, 8, 80, 4, 0, FB_VMODE_NONINTERLACED},
+       {1152, 864, 12004, 200, 64, 32, 16, 80, 4, 0, FB_VMODE_NONINTERLACED},
+       {1280, 1024, 9090, 200, 48, 26, 1, 184, 3, 0, FB_VMODE_NONINTERLACED},
+};
+
+/************************************************************************
+ * Get Parameters for the video mode:
+ */
+/*********************************************************************
+ * returns the length to the next seperator
+ */
+static int
+video_get_param_len (char *start, char sep)
+{
+       int i = 0;
+       while ((*start != 0) && (*start != sep)) {
+               start++;
+               i++;
+       }
+       return i;
+}
+
+static int
+video_search_param (char *start, char *param)
+{
+       int len, totallen, i;
+       char *p = start;
+       len = strlen (param);
+       totallen = len + strlen (start);
+       for (i = 0; i < totallen; i++) {
+               if (strncmp (p++, param, len) == 0)
+                       return (i);
+       }
+       return -1;
+}
+
+/***************************************************************
+ * Get parameter via the environment as it is done for the
+ * linux kernel i.e:
+ * video=ctfb:x:800,xv:1280,y:600,yv:1024,depth:16,mode:0,pclk:25000,
+ *      le:56,ri:48,up:26,lo:5,hs:152,vs:2,sync:0,vmode:0,accel:0
+ *
+ * penv is a pointer to the environment, containing the string, or the name of
+ * another environment variable. It could even be the term "bootargs"
+ */
+
+#define GET_OPTION(name,var)                           \
+       if(strncmp(p,name,strlen(name))==0) {           \
+               val_s=p+strlen(name);                   \
+               var=simple_strtoul(val_s, NULL, 10);    \
+       }
+
+int video_get_params (struct ctfb_res_modes *pPar, char *penv)
+{
+       char *p, *s, *val_s;
+       int i = 0, t;
+       int bpp;
+       int mode;
+       /* first search for the environment containing the real param string */
+       s = penv;
+       if ((p = getenv (s)) != NULL) {
+               s = p;
+       }
+       /* in case of the bootargs line, we have to start
+        * after "video=ctfb:"
+        */
+       i = video_search_param (s, "video=ctfb:");
+       if (i >= 0) {
+               s += i;
+               s += strlen ("video=ctfb:");
+       }
+       /* search for mode as a default value */
+       p = s;
+       t = 0;
+       mode = 0;               /* default */
+       while ((i = video_get_param_len (p, ',')) != 0) {
+               GET_OPTION ("mode:", mode)
+                       p += i;
+               if (*p != 0)
+                       p++;    /* skip ',' */
+       }
+       if (mode >= RES_MODES_COUNT)
+               mode = 0;
+       *pPar = res_mode_init[mode];    /* copy default values */
+       bpp = 24 - ((mode % 3) * 8);
+       p = s;                  /* restart */
+       while ((i = video_get_param_len (p, ',')) != 0) {
+               GET_OPTION ("x:", pPar->xres)
+                       GET_OPTION ("y:", pPar->yres)
+                       GET_OPTION ("le:", pPar->left_margin)
+                       GET_OPTION ("ri:", pPar->right_margin)
+                       GET_OPTION ("up:", pPar->upper_margin)
+                       GET_OPTION ("lo:", pPar->lower_margin)
+                       GET_OPTION ("hs:", pPar->hsync_len)
+                       GET_OPTION ("vs:", pPar->vsync_len)
+                       GET_OPTION ("sync:", pPar->sync)
+                       GET_OPTION ("vmode:", pPar->vmode)
+                       GET_OPTION ("pclk:", pPar->pixclock)
+                       GET_OPTION ("depth:", bpp)
+                       p += i;
+               if (*p != 0)
+                       p++;    /* skip ',' */
+       }
+       return bpp;
+}
diff --git a/drivers/video/videomodes.h b/drivers/video/videomodes.h
new file mode 100644 (file)
index 0000000..e2dffe7
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * (C) Copyright 2004
+ * Pierre Aubert, Staubli Faverges , <p.aubert@staubli.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#ifndef CFG_DEFAULT_VIDEO_MODE
+#define CFG_DEFAULT_VIDEO_MODE 0x301
+#endif
+
+/* Some mode definitions */
+#define FB_SYNC_HOR_HIGH_ACT   1       /* horizontal sync high active  */
+#define FB_SYNC_VERT_HIGH_ACT  2       /* vertical sync high active    */
+#define FB_SYNC_EXT            4       /* external sync                */
+#define FB_SYNC_COMP_HIGH_ACT  8       /* composite sync high active   */
+#define FB_SYNC_BROADCAST      16      /* broadcast video timings      */
+                                       /* vtotal = 144d/288n/576i => PAL  */
+                                       /* vtotal = 121d/242n/484i => NTSC */
+#define FB_SYNC_ON_GREEN       32      /* sync on green */
+#define FB_VMODE_NONINTERLACED 0       /* non interlaced */
+#define FB_VMODE_INTERLACED    1       /* interlaced   */
+#define FB_VMODE_DOUBLE                2       /* double scan */
+#define FB_VMODE_MASK          255
+
+#define FB_VMODE_YWRAP         256     /* ywrap instead of panning     */
+#define FB_VMODE_SMOOTH_XPAN   512     /* smooth xpan possible (internally used) */
+#define FB_VMODE_CONUPDATE     512     /* don't update x/yoffset       */
+
+
+/******************************************************************
+ * Resolution Struct
+ ******************************************************************/
+struct ctfb_res_modes {
+       int xres;               /* visible resolution           */
+       int yres;
+       /* Timing: All values in pixclocks, except pixclock (of course) */
+       int pixclock;           /* pixel clock in ps (pico seconds) */
+       int left_margin;        /* time from sync to picture    */
+       int right_margin;       /* time from picture to sync    */
+       int upper_margin;       /* time from sync to picture    */
+       int lower_margin;
+       int hsync_len;          /* length of horizontal sync    */
+       int vsync_len;          /* length of vertical sync      */
+       int sync;               /* see FB_SYNC_*                */
+       int vmode;              /* see FB_VMODE_*               */
+};
+
+/******************************************************************
+ * Vesa Mode Struct
+ ******************************************************************/
+struct ctfb_vesa_modes {
+       int vesanr;             /* Vesa number as in LILO (VESA Nr + 0x200} */
+       int resindex;           /* index to resolution struct */
+       int bits_per_pixel;     /* bpp */
+};
+
+#define RES_MODE_640x480       0
+#define RES_MODE_800x600       1
+#define RES_MODE_1024x768      2
+#define RES_MODE_960_720       3
+#define RES_MODE_1152x864      4
+#define RES_MODE_1280x1024     5
+#define RES_MODES_COUNT                6
+
+#define VESA_MODES_COUNT 19
+
+extern const struct ctfb_vesa_modes vesa_modes[];
+extern const struct ctfb_res_modes res_mode_init[];
+
+int video_get_params (struct ctfb_res_modes *pPar, char *penv);
diff --git a/drivers/videomodes.c b/drivers/videomodes.c
deleted file mode 100644 (file)
index c81e5bc..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * (C) Copyright 2004
- * Pierre Aubert, Staubli Faverges , <p.aubert@staubli.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/************************************************************************
-  Get Parameters for the video mode:
-  The default video mode can be defined in CFG_DEFAULT_VIDEO_MODE.
-  If undefined, default video mode is set to 0x301
-  Parameters can be set via the variable "videomode" in the environment.
-  2 diferent ways are possible:
-  "videomode=301"   - 301 is a hexadecimal number describing the VESA
-                     mode. Following modes are implemented:
-
-                     Colors    640x480 800x600 1024x768 1152x864 1280x1024
-                    --------+---------------------------------------------
-                     8 bits |  0x301   0x303    0x305    0x161     0x307
-                    15 bits |  0x310   0x313    0x316    0x162     0x319
-                    16 bits |  0x311   0x314    0x317    0x163     0x31A
-                    24 bits |  0x312   0x315    0x318      ?       0x31B
-                    --------+---------------------------------------------
-  "videomode=bootargs"
-                  - the parameters are parsed from the bootargs.
-                     The format is "NAME:VALUE,NAME:VALUE" etc.
-                     Ex.:
-                     "bootargs=video=ctfb:x:800,y:600,depth:16,pclk:25000"
-                     Parameters not included in the list will be taken from
-                     the default mode, which is one of the following:
-                     mode:0  640x480x24
-                     mode:1  800x600x16
-                     mode:2  1024x768x8
-                     mode:3  960x720x24
-                     mode:4  1152x864x16
-                     mode:5  1280x1024x8
-
-                     if "mode" is not provided within the parameter list,
-                     mode:0 is assumed.
-                     Following parameters are supported:
-                     x       xres = visible resolution horizontal
-                     y       yres = visible resolution vertical
-                     pclk    pixelclocks in pico sec
-                     le      left_marging time from sync to picture in pixelclocks
-                     ri      right_marging time from picture to sync in pixelclocks
-                     up      upper_margin time from sync to picture
-                     lo      lower_margin
-                     hs      hsync_len length of horizontal sync
-                     vs      vsync_len length of vertical sync
-                     sync    see FB_SYNC_*
-                     vmode   see FB_VMODE_*
-                     depth   Color depth in bits per pixel
-                     All other parameters in the variable bootargs are ignored.
-                     It is also possible to set the parameters direct in the
-                     variable "videomode", or in another variable i.e.
-                     "myvideo" and setting the variable "videomode=myvideo"..
-****************************************************************************/
-
-#include <common.h>
-#include "videomodes.h"
-
-const struct ctfb_vesa_modes vesa_modes[VESA_MODES_COUNT] = {
-       {0x301, RES_MODE_640x480, 8},
-       {0x310, RES_MODE_640x480, 15},
-       {0x311, RES_MODE_640x480, 16},
-       {0x312, RES_MODE_640x480, 24},
-       {0x303, RES_MODE_800x600, 8},
-       {0x313, RES_MODE_800x600, 15},
-       {0x314, RES_MODE_800x600, 16},
-       {0x315, RES_MODE_800x600, 24},
-       {0x305, RES_MODE_1024x768, 8},
-       {0x316, RES_MODE_1024x768, 15},
-       {0x317, RES_MODE_1024x768, 16},
-       {0x318, RES_MODE_1024x768, 24},
-       {0x161, RES_MODE_1152x864, 8},
-       {0x162, RES_MODE_1152x864, 15},
-       {0x163, RES_MODE_1152x864, 16},
-       {0x307, RES_MODE_1280x1024, 8},
-       {0x319, RES_MODE_1280x1024, 15},
-       {0x31A, RES_MODE_1280x1024, 16},
-       {0x31B, RES_MODE_1280x1024, 24},
-};
-const struct ctfb_res_modes res_mode_init[RES_MODES_COUNT] = {
-       /* x     y pixclk   le  ri  up  lo   hs vs  s  vmode */
-       {640, 480, 39721, 40, 24, 32, 11, 96, 2, 0, FB_VMODE_NONINTERLACED},
-       {800, 600, 27778, 64, 24, 22, 1, 72, 2, 0, FB_VMODE_NONINTERLACED},
-       {1024, 768, 15384, 168, 8, 29, 3, 144, 4, 0, FB_VMODE_NONINTERLACED},
-       {960, 720, 13100, 160, 40, 32, 8, 80, 4, 0, FB_VMODE_NONINTERLACED},
-       {1152, 864, 12004, 200, 64, 32, 16, 80, 4, 0, FB_VMODE_NONINTERLACED},
-       {1280, 1024, 9090, 200, 48, 26, 1, 184, 3, 0, FB_VMODE_NONINTERLACED},
-};
-
-/************************************************************************
- * Get Parameters for the video mode:
- */
-/*********************************************************************
- * returns the length to the next seperator
- */
-static int
-video_get_param_len (char *start, char sep)
-{
-       int i = 0;
-       while ((*start != 0) && (*start != sep)) {
-               start++;
-               i++;
-       }
-       return i;
-}
-
-static int
-video_search_param (char *start, char *param)
-{
-       int len, totallen, i;
-       char *p = start;
-       len = strlen (param);
-       totallen = len + strlen (start);
-       for (i = 0; i < totallen; i++) {
-               if (strncmp (p++, param, len) == 0)
-                       return (i);
-       }
-       return -1;
-}
-
-/***************************************************************
- * Get parameter via the environment as it is done for the
- * linux kernel i.e:
- * video=ctfb:x:800,xv:1280,y:600,yv:1024,depth:16,mode:0,pclk:25000,
- *      le:56,ri:48,up:26,lo:5,hs:152,vs:2,sync:0,vmode:0,accel:0
- *
- * penv is a pointer to the environment, containing the string, or the name of
- * another environment variable. It could even be the term "bootargs"
- */
-
-#define GET_OPTION(name,var)                           \
-       if(strncmp(p,name,strlen(name))==0) {           \
-               val_s=p+strlen(name);                   \
-               var=simple_strtoul(val_s, NULL, 10);    \
-       }
-
-int video_get_params (struct ctfb_res_modes *pPar, char *penv)
-{
-       char *p, *s, *val_s;
-       int i = 0, t;
-       int bpp;
-       int mode;
-       /* first search for the environment containing the real param string */
-       s = penv;
-       if ((p = getenv (s)) != NULL) {
-               s = p;
-       }
-       /* in case of the bootargs line, we have to start
-        * after "video=ctfb:"
-        */
-       i = video_search_param (s, "video=ctfb:");
-       if (i >= 0) {
-               s += i;
-               s += strlen ("video=ctfb:");
-       }
-       /* search for mode as a default value */
-       p = s;
-       t = 0;
-       mode = 0;               /* default */
-       while ((i = video_get_param_len (p, ',')) != 0) {
-               GET_OPTION ("mode:", mode)
-                       p += i;
-               if (*p != 0)
-                       p++;    /* skip ',' */
-       }
-       if (mode >= RES_MODES_COUNT)
-               mode = 0;
-       *pPar = res_mode_init[mode];    /* copy default values */
-       bpp = 24 - ((mode % 3) * 8);
-       p = s;                  /* restart */
-       while ((i = video_get_param_len (p, ',')) != 0) {
-               GET_OPTION ("x:", pPar->xres)
-                       GET_OPTION ("y:", pPar->yres)
-                       GET_OPTION ("le:", pPar->left_margin)
-                       GET_OPTION ("ri:", pPar->right_margin)
-                       GET_OPTION ("up:", pPar->upper_margin)
-                       GET_OPTION ("lo:", pPar->lower_margin)
-                       GET_OPTION ("hs:", pPar->hsync_len)
-                       GET_OPTION ("vs:", pPar->vsync_len)
-                       GET_OPTION ("sync:", pPar->sync)
-                       GET_OPTION ("vmode:", pPar->vmode)
-                       GET_OPTION ("pclk:", pPar->pixclock)
-                       GET_OPTION ("depth:", bpp)
-                       p += i;
-               if (*p != 0)
-                       p++;    /* skip ',' */
-       }
-       return bpp;
-}
diff --git a/drivers/videomodes.h b/drivers/videomodes.h
deleted file mode 100644 (file)
index e2dffe7..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * (C) Copyright 2004
- * Pierre Aubert, Staubli Faverges , <p.aubert@staubli.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-
-#ifndef CFG_DEFAULT_VIDEO_MODE
-#define CFG_DEFAULT_VIDEO_MODE 0x301
-#endif
-
-/* Some mode definitions */
-#define FB_SYNC_HOR_HIGH_ACT   1       /* horizontal sync high active  */
-#define FB_SYNC_VERT_HIGH_ACT  2       /* vertical sync high active    */
-#define FB_SYNC_EXT            4       /* external sync                */
-#define FB_SYNC_COMP_HIGH_ACT  8       /* composite sync high active   */
-#define FB_SYNC_BROADCAST      16      /* broadcast video timings      */
-                                       /* vtotal = 144d/288n/576i => PAL  */
-                                       /* vtotal = 121d/242n/484i => NTSC */
-#define FB_SYNC_ON_GREEN       32      /* sync on green */
-#define FB_VMODE_NONINTERLACED 0       /* non interlaced */
-#define FB_VMODE_INTERLACED    1       /* interlaced   */
-#define FB_VMODE_DOUBLE                2       /* double scan */
-#define FB_VMODE_MASK          255
-
-#define FB_VMODE_YWRAP         256     /* ywrap instead of panning     */
-#define FB_VMODE_SMOOTH_XPAN   512     /* smooth xpan possible (internally used) */
-#define FB_VMODE_CONUPDATE     512     /* don't update x/yoffset       */
-
-
-/******************************************************************
- * Resolution Struct
- ******************************************************************/
-struct ctfb_res_modes {
-       int xres;               /* visible resolution           */
-       int yres;
-       /* Timing: All values in pixclocks, except pixclock (of course) */
-       int pixclock;           /* pixel clock in ps (pico seconds) */
-       int left_margin;        /* time from sync to picture    */
-       int right_margin;       /* time from picture to sync    */
-       int upper_margin;       /* time from sync to picture    */
-       int lower_margin;
-       int hsync_len;          /* length of horizontal sync    */
-       int vsync_len;          /* length of vertical sync      */
-       int sync;               /* see FB_SYNC_*                */
-       int vmode;              /* see FB_VMODE_*               */
-};
-
-/******************************************************************
- * Vesa Mode Struct
- ******************************************************************/
-struct ctfb_vesa_modes {
-       int vesanr;             /* Vesa number as in LILO (VESA Nr + 0x200} */
-       int resindex;           /* index to resolution struct */
-       int bits_per_pixel;     /* bpp */
-};
-
-#define RES_MODE_640x480       0
-#define RES_MODE_800x600       1
-#define RES_MODE_1024x768      2
-#define RES_MODE_960_720       3
-#define RES_MODE_1152x864      4
-#define RES_MODE_1280x1024     5
-#define RES_MODES_COUNT                6
-
-#define VESA_MODES_COUNT 19
-
-extern const struct ctfb_vesa_modes vesa_modes[];
-extern const struct ctfb_res_modes res_mode_init[];
-
-int video_get_params (struct ctfb_res_modes *pPar, char *penv);
diff --git a/drivers/w83c553f.c b/drivers/w83c553f.c
deleted file mode 100644 (file)
index 5d82ed4..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Andreas Heppel <aheppel@sysgo.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Initialisation of the PCI-to-ISA bridge and disabling the BIOS
- * write protection (for flash) in function 0 of the chip.
- * Enabling function 1 (IDE controller of the chip.
- */
-
-#include <common.h>
-#include <config.h>
-
-#ifdef CFG_WINBOND_83C553
-
-#include <asm/io.h>
-#include <pci.h>
-
-#include <w83c553f.h>
-
-#define out8(addr,val) do { \
-                       out_8((u8*) (addr),(val)); udelay(1); \
-                       } while (0)
-#define out16(addr,val)        do { \
-                       out_be16((u16*) (addr),(val)); udelay(1); \
-                       } while (0)
-
-extern uint ide_bus_offset[CFG_IDE_MAXBUS];
-
-void initialise_pic(void);
-void initialise_dma(void);
-
-void initialise_w83c553f(void)
-{
-       pci_dev_t devbusfn;
-       unsigned char reg8;
-       unsigned short reg16;
-       unsigned int reg32;
-
-       devbusfn = pci_find_device(W83C553F_VID, W83C553F_DID, 0);
-       if (devbusfn == -1)
-       {
-               printf("Error: Cannot find W83C553F controller on any PCI bus.");
-               return;
-       }
-
-       pci_read_config_word(devbusfn, PCI_COMMAND, &reg16);
-       reg16 |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
-       pci_write_config_word(devbusfn, PCI_COMMAND, reg16);
-
-       pci_read_config_byte(devbusfn, WINBOND_IPADCR, &reg8);
-       /* 16 MB ISA memory space */
-       reg8 |= (IPADCR_IPATOM4 | IPADCR_IPATOM5 | IPADCR_IPATOM6 | IPADCR_IPATOM7);
-       reg8 &= ~IPADCR_MBE512;
-       pci_write_config_byte(devbusfn, WINBOND_IPADCR, reg8);
-
-       pci_read_config_byte(devbusfn, WINBOND_CSCR, &reg8);
-       /* switch off BIOS write protection */
-       reg8 |= CSCR_UBIOSCSE;
-       reg8 &= ~CSCR_BIOSWP;
-       pci_write_config_byte(devbusfn, WINBOND_CSCR, reg8);
-
-       /*
-        * Interrupt routing:
-        *  - IDE  -> IRQ 9/0
-        *  - INTA -> IRQ 10
-        *  - INTB -> IRQ 11
-        *  - INTC -> IRQ 14
-        *  - INTD -> IRQ 15
-        */
-       pci_write_config_byte(devbusfn, WINBOND_IDEIRCR, 0x90);
-       pci_write_config_word(devbusfn, WINBOND_PCIIRCR, 0xABEF);
-
-       /*
-        * Read IDE bus offsets from function 1 device.
-        * We must unmask the LSB indicating that ist is an IO address.
-        */
-       devbusfn |= PCI_BDF(0,0,1);
-
-       /*
-        * Switch off legacy IRQ for IDE and IDE port 1.
-        */
-       pci_write_config_byte(devbusfn, 0x09, 0x8F);
-
-       pci_read_config_dword(devbusfn, WINDOND_IDECSR, &reg32);
-       reg32 &= ~(IDECSR_LEGIRQ | IDECSR_P1EN | IDECSR_P1F16);
-       pci_write_config_dword(devbusfn, WINDOND_IDECSR, reg32);
-
-       pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &ide_bus_offset[0]);
-       ide_bus_offset[0] &= ~1;
-#if CFG_IDE_MAXBUS > 1
-       pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_2, &ide_bus_offset[1]);
-       ide_bus_offset[1] &= ~1;
-#endif
-
-       /*
-        * Enable function 1, IDE -> busmastering and IO space access
-        */
-       pci_read_config_word(devbusfn, PCI_COMMAND, &reg16);
-       reg16 |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
-       pci_write_config_word(devbusfn, PCI_COMMAND, reg16);
-
-       /*
-        * Initialise ISA interrupt controller
-        */
-       initialise_pic();
-
-       /*
-        * Initialise DMA controller
-        */
-       initialise_dma();
-}
-
-void initialise_pic(void)
-{
-       out8(W83C553F_PIC1_ICW1, 0x11);
-       out8(W83C553F_PIC1_ICW2, 0x08);
-       out8(W83C553F_PIC1_ICW3, 0x04);
-       out8(W83C553F_PIC1_ICW4, 0x01);
-       out8(W83C553F_PIC1_OCW1, 0xfb);
-       out8(W83C553F_PIC1_ELC, 0x20);
-
-       out8(W83C553F_PIC2_ICW1, 0x11);
-       out8(W83C553F_PIC2_ICW2, 0x08);
-       out8(W83C553F_PIC2_ICW3, 0x02);
-       out8(W83C553F_PIC2_ICW4, 0x01);
-       out8(W83C553F_PIC2_OCW1, 0xff);
-       out8(W83C553F_PIC2_ELC, 0xce);
-
-       out8(W83C553F_TMR1_CMOD, 0x74);
-
-       out8(W83C553F_PIC2_OCW1, 0x20);
-       out8(W83C553F_PIC1_OCW1, 0x20);
-
-       out8(W83C553F_PIC2_OCW1, 0x2b);
-       out8(W83C553F_PIC1_OCW1, 0x2b);
-}
-
-void initialise_dma(void)
-{
-       unsigned int channel;
-       unsigned int rvalue1, rvalue2;
-
-       /* perform a H/W reset of the devices */
-
-       out8(W83C553F_DMA1 + W83C553F_DMA1_MC, 0x00);
-       out16(W83C553F_DMA2 + W83C553F_DMA2_MC, 0x0000);
-
-       /* initialise all channels to a sane state */
-
-       for (channel = 0; channel < 4; channel++) {
-               /*
-                * dependent upon the channel, setup the specifics:
-                *
-                * demand
-                * address-increment
-                * autoinitialize-disable
-                * verify-transfer
-                */
-
-               switch (channel) {
-               case 0:
-                       rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH0SEL|W83C553F_MODE_TT_VERIFY);
-                       rvalue2 = (W83C553F_MODE_TM_CASCADE|W83C553F_MODE_CH0SEL);
-                       break;
-               case 1:
-                       rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH1SEL|W83C553F_MODE_TT_VERIFY);
-                       rvalue2 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH1SEL|W83C553F_MODE_TT_VERIFY);
-                       break;
-               case 2:
-                       rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH2SEL|W83C553F_MODE_TT_VERIFY);
-                       rvalue2 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH2SEL|W83C553F_MODE_TT_VERIFY);
-                       break;
-               case 3:
-                       rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH3SEL|W83C553F_MODE_TT_VERIFY);
-                       rvalue2 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH3SEL|W83C553F_MODE_TT_VERIFY);
-                       break;
-               default:
-                       rvalue1 = 0x00;
-                       rvalue2 = 0x00;
-                       break;
-               }
-
-               /* write to write mode registers */
-
-               out8(W83C553F_DMA1 + W83C553F_DMA1_WM, rvalue1 & 0xFF);
-               out16(W83C553F_DMA2 + W83C553F_DMA2_WM, rvalue2 & 0x00FF);
-       }
-
-       /* enable all channels */
-
-       out8(W83C553F_DMA1 + W83C553F_DMA1_CM, 0x00);
-       out16(W83C553F_DMA2 + W83C553F_DMA2_CM, 0x0000);
-       /*
-        * initialize the global DMA configuration
-        *
-        * DACK# active low
-        * DREQ active high
-        * fixed priority
-        * channel group enable
-        */
-
-       out8(W83C553F_DMA1 + W83C553F_DMA1_CS, 0x00);
-       out16(W83C553F_DMA2 + W83C553F_DMA2_CS, 0x0000);
-}
-
-#endif /* CFG_WINBOND_83C553 */
diff --git a/dtt/Makefile b/dtt/Makefile
deleted file mode 100644 (file)
index c6a670a..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# (C) Copyright 2006
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-#
-# (C) Copyright 2001
-# Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
-#
-# See file CREDITS for list of people who contributed to this
-# project.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-# MA 02111-1307 USA
-#
-
-include $(TOPDIR)/config.mk
-
-#CFLAGS += -DDEBUG
-
-LIB    = $(obj)libdtt.a
-
-COBJS  = lm75.o ds1621.o adm1021.o lm81.o ds1775.o
-
-SRCS   := $(COBJS:.o=.c)
-OBJS   := $(addprefix $(obj),$(COBJS))
-
-all:   $(LIB)
-
-$(LIB):        $(obj).depend $(OBJS)
-       $(AR) $(ARFLAGS) $@ $(OBJS)
-
-#########################################################################
-
-# defines $(obj).depend target
-include $(SRCTREE)/rules.mk
-
-sinclude $(obj).depend
-
-#########################################################################
diff --git a/dtt/adm1021.c b/dtt/adm1021.c
deleted file mode 100644 (file)
index 9f65cfb..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * (C) Copyright 2003
- * Murray Jensen, CSIRO-MIT, Murray.Jensen@csiro.au
- *
- * based on dtt/lm75.c which is ...
- *
- * (C) Copyright 2001
- * Bill Hunter,  Wave 7 Optics, williamhunter@mediaone.net
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Analog Devices's ADM1021
- * "Low Cost Microprocessor System Temperature Monitor"
- */
-
-#include <common.h>
-
-#ifdef CONFIG_DTT_ADM1021
-
-#include <i2c.h>
-#include <dtt.h>
-
-typedef
-       struct {
-               uint i2c_addr:7;        /* 7bit i2c chip address */
-               uint conv_rate:3;       /* conversion rate */
-               uint enable_alert:1;    /* enable alert output pin */
-               uint enable_local:1;    /* enable internal temp sensor */
-               uint max_local:8;       /* internal temp maximum */
-               uint min_local:8;       /* internal temp minimum */
-               uint enable_remote:1;   /* enable remote temp sensor */
-               uint max_remote:8;      /* remote temp maximum */
-               uint min_remote:8;      /* remote temp minimum */
-       }
-dtt_cfg_t;
-
-dtt_cfg_t dttcfg[] = CFG_DTT_ADM1021;
-
-int
-dtt_read (int sensor, int reg)
-{
-       dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
-       uchar data;
-
-       if (i2c_read(dcp->i2c_addr, reg, 1, &data, 1) != 0)
-               return -1;
-
-       return (int)data;
-} /* dtt_read() */
-
-int
-dtt_write (int sensor, int reg, int val)
-{
-       dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
-       uchar data;
-
-       data = (uchar)(val & 0xff);
-
-       if (i2c_write(dcp->i2c_addr, reg, 1, &data, 1) != 0)
-               return 1;
-
-       return 0;
-} /* dtt_write() */
-
-static int
-_dtt_init (int sensor)
-{
-       dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
-       int reg, val;
-
-       if (((sensor & 1) == 0 ? dcp->enable_local : dcp->enable_remote) == 0)
-               return 1;       /* sensor is disabled (or rather ignored) */
-
-       /*
-        * Setup High Limit register
-        */
-       if ((sensor & 1) == 0) {
-               reg = DTT_WRITE_LOC_HIGHLIM;
-               val = dcp->max_local;
-       }
-       else {
-               reg = DTT_WRITE_REM_HIGHLIM;
-               val = dcp->max_remote;
-       }
-       if (dtt_write (sensor, reg, val) != 0)
-               return 1;
-
-       /*
-        * Setup Low Limit register
-        */
-       if ((sensor & 1) == 0) {
-               reg = DTT_WRITE_LOC_LOWLIM;
-               val = dcp->min_local;
-       }
-       else {
-               reg = DTT_WRITE_REM_LOWLIM;
-               val = dcp->min_remote;
-       }
-       if (dtt_write (sensor, reg, val) != 0)
-               return 1;
-
-       /* shouldn't hurt if the rest gets done twice */
-
-       /*
-        * Setup Conversion Rate register
-        */
-       if (dtt_write (sensor, DTT_WRITE_CONVRATE, dcp->conv_rate) != 0)
-               return 1;
-
-       /*
-        * Setup configuraton register
-        */
-       val = 0;                                /* running */
-       if (dcp->enable_alert == 0)
-               val |= DTT_CONFIG_ALERT_MASKED; /* mask ALERT pin */
-       if (dtt_write (sensor, DTT_WRITE_CONFIG, val) != 0)
-               return 1;
-
-       return 0;
-} /* _dtt_init() */
-
-int
-dtt_init (void)
-{
-       int i;
-       unsigned char sensors[] = CONFIG_DTT_SENSORS;
-       const char *const header = "DTT:   ";
-
-       /* switch to correct I2C bus */
-       I2C_SET_BUS(CFG_DTT_BUS_NUM);
-
-       for (i = 0; i < sizeof(sensors); i++) {
-               if (_dtt_init(sensors[i]) != 0)
-                       printf ("%s%d FAILED INIT\n", header, i+1);
-               else
-                       printf ("%s%d is %i C\n", header, i+1,
-                               dtt_get_temp(sensors[i]));
-       }
-
-       return (0);
-} /* dtt_init() */
-
-int
-dtt_get_temp (int sensor)
-{
-       signed char val;
-
-       if ((sensor & 1) == 0)
-               val = dtt_read(sensor, DTT_READ_LOC_VALUE);
-       else
-               val = dtt_read(sensor, DTT_READ_REM_VALUE);
-
-       return (int) val;
-} /* dtt_get_temp() */
-
-#endif /* CONFIG_DTT_ADM1021 */
diff --git a/dtt/ds1621.c b/dtt/ds1621.c
deleted file mode 100644 (file)
index 4948181..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * (C) Copyright 2001
- * Erik Theisen,  Wave 7 Optics, etheisen@mindspring.com.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Dallas Semiconductor's DS1621 Digital Thermometer and Thermostat.
- */
-
-#include <common.h>
-
-#ifdef CONFIG_DTT_DS1621
-#if !defined(CFG_EEPROM_PAGE_WRITE_ENABLE) || \
-       (CFG_EEPROM_PAGE_WRITE_BITS < 1)
-# error "CFG_EEPROM_PAGE_WRITE_ENABLE must be defined and CFG_EEPROM_PAGE_WRITE_BITS must be greater than 1 to use CONFIG_DTT_DS1621"
-#endif
-#include <i2c.h>
-#include <dtt.h>
-
-/*
- * Device code
- */
-#define DTT_I2C_DEV_CODE 0x48                  /* Dallas Semi's DS1621 */
-
-int dtt_read(int sensor, int reg)
-{
-    int dlen;
-    uchar data[2];
-
-    /*
-     * Calculate sensor address and command.
-     *
-     */
-    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* Calculate addr of ds1621*/
-
-    /*
-     * Prepare to handle 2 byte result.
-     */
-    if ((reg == DTT_READ_TEMP) ||
-       (reg == DTT_TEMP_HIGH) || (reg == DTT_TEMP_LOW))
-       dlen = 2;
-    else
-       dlen = 1;
-
-    /*
-     * Now try to read the register.
-     */
-    if (i2c_read(sensor, reg, 1, data, dlen) != 0)
-       return 1;
-
-    /*
-     * Handle 2 byte result.
-     */
-    if (dlen == 2)
-       return ((int)((short)data[1] + (((short)data[0]) << 8)));
-
-    return (int)data[0];
-} /* dtt_read() */
-
-
-int dtt_write(int sensor, int reg, int val)
-{
-    int dlen;
-    uchar data[2];
-
-    /*
-     * Calculate sensor address and register.
-     *
-     */
-    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07);
-
-    /*
-     * Handle various data sizes.
-     */
-    if ((reg == DTT_READ_TEMP) ||
-       (reg == DTT_TEMP_HIGH) || (reg == DTT_TEMP_LOW)) {
-       dlen = 2;
-       data[0] = (char)((val >> 8) & 0xff);    /* MSB first */
-       data[1] = (char)(val & 0xff);
-    }
-    else if ((reg == DTT_WRITE_START_CONV) || (reg == DTT_WRITE_STOP_CONV)) {
-       dlen = 0;
-       data[0] = (char)0;
-       data[1] = (char)0;
-    }
-    else {
-       dlen = 1;
-       data[0] = (char)(val & 0xff);
-    }
-
-    /*
-     * Write value to device.
-     */
-    if (i2c_write(sensor, reg, 1, data, dlen) != 0)
-       return 1;
-
-    return 0;
-} /* dtt_write() */
-
-
-static int _dtt_init(int sensor)
-{
-    int val;
-
-    /*
-     * Setup High Temp.
-     */
-    val = ((CFG_DTT_MAX_TEMP * 2) << 7) & 0xff80;
-    if (dtt_write(sensor, DTT_TEMP_HIGH, val) != 0)
-       return 1;
-    udelay(50000);                             /* Max 50ms */
-
-    /*
-     * Setup Low Temp - hysteresis.
-     */
-    val = (((CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
-    if (dtt_write(sensor, DTT_TEMP_LOW, val) != 0)
-       return 1;
-    udelay(50000);                             /* Max 50ms */
-
-    /*
-     * Setup configuraton register
-     *
-     * Clear THF & TLF, Reserved = 1, Polarity = Active Low, One Shot = YES
-     *
-     * We run in polled mode, since there isn't any way to know if this
-     * lousy device is ready to provide temperature readings on power up.
-     */
-    val = 0x9;
-    if (dtt_write(sensor, DTT_CONFIG, val) != 0)
-       return 1;
-    udelay(50000);                             /* Max 50ms */
-
-    return 0;
-} /* _dtt_init() */
-
-
-int dtt_init (void)
-{
-    int i;
-    unsigned char sensors[] = CONFIG_DTT_SENSORS;
-
-    for (i = 0; i < sizeof(sensors); i++) {
-       if (_dtt_init(sensors[i]) != 0)
-           printf("DTT%d:  FAILED\n", i+1);
-       else
-           printf("DTT%d:  %i C\n", i+1, dtt_get_temp(sensors[i]));
-    }
-
-    return (0);
-} /* dtt_init() */
-
-
-int dtt_get_temp(int sensor)
-{
-    int i;
-
-    /*
-     * Start a conversion, may take up to 1 second.
-     */
-    dtt_write(sensor, DTT_WRITE_START_CONV, 0);
-    for (i = 0; i <= 10; i++) {
-       udelay(100000);
-       if (dtt_read(sensor, DTT_CONFIG) & 0x80)
-           break;
-    }
-
-    return (dtt_read(sensor, DTT_READ_TEMP) / 256);
-} /* dtt_get_temp() */
-
-
-#endif /* CONFIG_DTT_DS1621 */
diff --git a/dtt/ds1775.c b/dtt/ds1775.c
deleted file mode 100644 (file)
index 0fbb0b4..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Dallas Semiconductor's DS1775 Digital Thermometer and Thermostat
- */
-
-#include <common.h>
-
-#ifdef CONFIG_DTT_DS1775
-#include <i2c.h>
-#include <dtt.h>
-
-#define DTT_I2C_DEV_CODE       CFG_I2C_DTT_ADDR /* Dallas Semi's DS1775 device code */
-
-int dtt_read(int sensor, int reg)
-{
-       int dlen;
-       uchar data[2];
-
-       /*
-        * Calculate sensor address and command
-        */
-       sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* Calculate addr of ds1775 */
-
-       /*
-        * Prepare to handle 2 byte result
-        */
-       if ((reg == DTT_READ_TEMP) ||
-           (reg == DTT_TEMP_OS) || (reg == DTT_TEMP_HYST))
-               dlen = 2;
-       else
-               dlen = 1;
-
-       /*
-        * Now try to read the register
-        */
-       if (i2c_read(sensor, reg, 1, data, dlen) != 0)
-               return 1;
-
-       /*
-        * Handle 2 byte result
-        */
-       if (dlen == 2)
-               return ((int)((short)data[1] + (((short)data[0]) << 8)));
-
-       return (int) data[0];
-}
-
-
-int dtt_write(int sensor, int reg, int val)
-{
-       int dlen;
-       uchar data[2];
-
-       /*
-        * Calculate sensor address and register
-        */
-       sensor = DTT_I2C_DEV_CODE + (sensor & 0x07);
-
-       /*
-        * Handle various data sizes
-        */
-       if ((reg == DTT_READ_TEMP) ||
-           (reg == DTT_TEMP_OS) || (reg == DTT_TEMP_HYST)) {
-               dlen = 2;
-               data[0] = (char)((val >> 8) & 0xff); /* MSB first */
-               data[1] = (char)(val & 0xff);
-       } else {
-               dlen = 1;
-               data[0] = (char)(val & 0xff);
-       }
-
-       /*
-        * Write value to device
-        */
-       if (i2c_write(sensor, reg, 1, data, dlen) != 0)
-               return 1;
-
-       return 0;
-}
-
-
-static int _dtt_init(int sensor)
-{
-       int val;
-
-       /*
-        * Setup High Temp
-        */
-       val = ((CFG_DTT_MAX_TEMP * 2) << 7) & 0xff80;
-       if (dtt_write(sensor, DTT_TEMP_OS, val) != 0)
-               return 1;
-       udelay(50000);                  /* Max 50ms */
-
-       /*
-        * Setup Low Temp - hysteresis
-        */
-       val = (((CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
-       if (dtt_write(sensor, DTT_TEMP_HYST, val) != 0)
-               return 1;
-       udelay(50000);                  /* Max 50ms */
-
-       /*
-        * Setup configuraton register
-        *
-        * Fault Tolerance limits 4, Thermometer resolution bits is 9,
-        * Polarity = Active Low,continuous conversion mode, Thermostat
-        * mode is interrupt mode
-        */
-       val = 0xa;
-       if (dtt_write(sensor, DTT_CONFIG, val) != 0)
-               return 1;
-       udelay(50000);                  /* Max 50ms */
-
-       return 0;
-}
-
-
-int dtt_init (void)
-{
-       int i;
-       unsigned char sensors[] = CONFIG_DTT_SENSORS;
-
-       for (i = 0; i < sizeof(sensors); i++) {
-               if (_dtt_init(sensors[i]) != 0)
-                       printf("DTT%d:  FAILED\n", i+1);
-               else
-                       printf("DTT%d:  %i C\n", i+1, dtt_get_temp(sensors[i]));
-       }
-
-       return (0);
-}
-
-
-int dtt_get_temp(int sensor)
-{
-       return (dtt_read(sensor, DTT_READ_TEMP) / 256);
-}
-
-
-#endif /* CONFIG_DTT_DS1775 */
diff --git a/dtt/lm75.c b/dtt/lm75.c
deleted file mode 100644 (file)
index 63f3b75..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * (C) Copyright 2001
- * Bill Hunter,  Wave 7 Optics, williamhunter@mediaone.net
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * On Semiconductor's LM75 Temperature Sensor
- */
-
-#include <common.h>
-
-#ifdef CONFIG_DTT_LM75
-#if !defined(CFG_EEPROM_PAGE_WRITE_ENABLE) || \
-       (CFG_EEPROM_PAGE_WRITE_BITS < 1)
-# error "CFG_EEPROM_PAGE_WRITE_ENABLE must be defined and CFG_EEPROM_PAGE_WRITE_BITS must be greater than  1 to use CONFIG_DTT_LM75"
-#endif
-
-#include <i2c.h>
-#include <dtt.h>
-
-
-/*
- * Device code
- */
-#define DTT_I2C_DEV_CODE 0x48                  /* ON Semi's LM75 device */
-
-int dtt_read(int sensor, int reg)
-{
-    int dlen;
-    uchar data[2];
-
-    /*
-     * Validate 'reg' param
-     */
-    if((reg < 0) || (reg > 3))
-       return -1;
-
-    /*
-     * Calculate sensor address and register.
-     */
-    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* calculate address of lm75 */
-
-    /*
-     * Prepare to handle 2 byte result.
-     */
-    if ((reg == DTT_READ_TEMP) ||
-       (reg == DTT_TEMP_HYST) ||
-       (reg == DTT_TEMP_SET))
-       dlen = 2;
-    else
-       dlen = 1;
-
-    /*
-     * Now try to read the register.
-     */
-    if (i2c_read(sensor, reg, 1, data, dlen) != 0)
-       return -1;
-
-    /*
-     * Handle 2 byte result.
-     */
-    if (dlen == 2)
-       return ((int)((short)data[1] + (((short)data[0]) << 8)));
-
-
-    return (int)data[0];
-} /* dtt_read() */
-
-
-int dtt_write(int sensor, int reg, int val)
-{
-    int dlen;
-    uchar data[2];
-
-    /*
-     * Validate 'reg' param
-     */
-    if ((reg < 0) || (reg > 3))
-       return 1;
-
-    /*
-     * Calculate sensor address and register.
-     */
-    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* calculate address of lm75 */
-
-    /*
-     * Handle 2 byte values.
-     */
-    if ((reg == DTT_READ_TEMP) ||
-       (reg == DTT_TEMP_HYST) ||
-       (reg == DTT_TEMP_SET)) {
-       dlen = 2;
-       data[0] = (char)((val >> 8) & 0xff);    /* MSB first */
-       data[1] = (char)(val & 0xff);
-    } else {
-       dlen = 1;
-       data[0] = (char)(val & 0xff);
-    }
-
-    /*
-     * Write value to register.
-     */
-    if (i2c_write(sensor, reg, 1, data, dlen) != 0)
-       return 1;
-
-    return 0;
-} /* dtt_write() */
-
-
-static int _dtt_init(int sensor)
-{
-    int val;
-
-    /*
-     * Setup TSET ( trip point ) register
-     */
-    val = ((CFG_DTT_MAX_TEMP * 2) << 7) & 0xff80; /* trip */
-    if (dtt_write(sensor, DTT_TEMP_SET, val) != 0)
-       return 1;
-
-    /*
-     * Setup THYST ( untrip point ) register - Hysteresis
-     */
-    val = (((CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
-    if (dtt_write(sensor, DTT_TEMP_HYST, val) != 0)
-       return 1;
-
-    /*
-     * Setup configuraton register
-     */
-#ifdef CONFIG_DTT_AD7414
-    /* config = alert active low and disabled */
-    val = 0x60;
-#else
-    /* config = 6 sample integration, int mode, active low, and enable */
-    val = 0x18;
-#endif
-    if (dtt_write(sensor, DTT_CONFIG, val) != 0)
-       return 1;
-
-    return 0;
-} /* _dtt_init() */
-
-
-int dtt_init (void)
-{
-    int i;
-    unsigned char sensors[] = CONFIG_DTT_SENSORS;
-    const char *const header = "DTT:   ";
-
-    for (i = 0; i < sizeof(sensors); i++) {
-       if (_dtt_init(sensors[i]) != 0)
-           printf("%s%d FAILED INIT\n", header, i+1);
-       else
-           printf("%s%d is %i C\n", header, i+1,
-                  dtt_get_temp(sensors[i]));
-    }
-
-    return (0);
-} /* dtt_init() */
-
-int dtt_get_temp(int sensor)
-{
-    return (dtt_read(sensor, DTT_READ_TEMP) / 256);
-} /* dtt_get_temp() */
-
-#endif /* CONFIG_DTT_LM75 */
diff --git a/dtt/lm81.c b/dtt/lm81.c
deleted file mode 100644 (file)
index 03bc53d..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * (C) Copyright 2006
- * Heiko Schocher, DENX Software Enginnering <hs@denx.de>
- *
- * based on dtt/lm75.c which is ...
- *
- * (C) Copyright 2001
- * Bill Hunter,  Wave 7 Optics, williamhunter@mediaone.net
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * On Semiconductor's LM81 Temperature Sensor
- */
-
-#include <common.h>
-
-#ifdef CONFIG_DTT_LM81
-#if !defined(CFG_EEPROM_PAGE_WRITE_ENABLE) || \
-       (CFG_EEPROM_PAGE_WRITE_BITS < 1)
-# error "CFG_EEPROM_PAGE_WRITE_ENABLE must be defined and CFG_EEPROM_PAGE_WRITE_BITS must be greater than  1 to use CONFIG_DTT_LM81"
-#endif
-
-#include <i2c.h>
-#include <dtt.h>
-
-/*
- * Device code
- */
-#define DTT_I2C_DEV_CODE 0x2c                  /* ON Semi's LM81 device */
-
-int dtt_read(int sensor, int reg)
-{
-    int dlen = 1;
-    uchar data[2];
-
-    /*
-     * Calculate sensor address and register.
-     */
-    sensor = DTT_I2C_DEV_CODE + (sensor & 0x03); /* calculate address of lm81 */
-
-    /*
-     * Now try to read the register.
-     */
-    if (i2c_read(sensor, reg, 1, data, dlen) != 0)
-       return -1;
-
-    return (int)data[0];
-} /* dtt_read() */
-
-
-int dtt_write(int sensor, int reg, int val)
-{
-    uchar data;
-
-    /*
-     * Calculate sensor address and register.
-     */
-    sensor = DTT_I2C_DEV_CODE + (sensor & 0x03); /* calculate address of lm81 */
-
-    data = (char)(val & 0xff);
-
-    /*
-     * Write value to register.
-     */
-    if (i2c_write(sensor, reg, 1, &data, 1) != 0)
-       return 1;
-
-    return 0;
-} /* dtt_write() */
-
-#define DTT_MANU       0x3e
-#define DTT_REV                0x3f
-#define DTT_CONFIG     0x40
-#define DTT_ADR                0x48
-
-static int _dtt_init(int sensor)
-{
-       int     man;
-       int     adr;
-       int     rev;
-
-       if (dtt_write (sensor, DTT_CONFIG, 0x01) < 0)
-               return 1;
-       /* The LM81 needs 400ms to get the correct values ... */
-       udelay (400000);
-       man = dtt_read (sensor, DTT_MANU);
-       if (man != 0x01)
-               return 1;
-       adr = dtt_read (sensor, DTT_ADR);
-       if (adr < 0)
-               return 1;
-       rev = dtt_read (sensor, DTT_REV);
-       if (adr < 0)
-               return 1;
-
-       printf ("DTT:   Found LM81@%x Rev: %d\n", adr, rev);
-       return 0;
-} /* _dtt_init() */
-
-
-int dtt_init (void)
-{
-    int i;
-    unsigned char sensors[] = CONFIG_DTT_SENSORS;
-    const char *const header = "DTT:   ";
-
-    for (i = 0; i < sizeof(sensors); i++) {
-       if (_dtt_init(sensors[i]) != 0)
-           printf("%s%d FAILED INIT\n", header, i+1);
-       else
-           printf("%s%d is %i C\n", header, i+1,
-                  dtt_get_temp(sensors[i]));
-    }
-
-    return (0);
-} /* dtt_init() */
-
-#define TEMP_FROM_REG(temp) \
-   ((temp)<256?((((temp)&0x1fe) >> 1) * 10)     + ((temp) & 1) * 5:  \
-              ((((temp)&0x1fe) >> 1) -255) * 10 - ((temp) & 1) * 5)  \
-
-int dtt_get_temp(int sensor)
-{
-       int val = dtt_read (sensor, DTT_READ_TEMP);
-       int tmpcnf = dtt_read (sensor, DTT_CONFIG_TEMP);
-
-       return (TEMP_FROM_REG((val << 1) + ((tmpcnf & 0x80) >> 7))) / 10;
-} /* dtt_get_temp() */
-
-#endif /* CONFIG_DTT_LM81 */
diff --git a/examples/.gitignore b/examples/.gitignore
new file mode 100644 (file)
index 0000000..f547024
--- /dev/null
@@ -0,0 +1,5 @@
+/hello_world
+/interrupt
+/sched
+*.bin
+*.srec
index 9d9849bf5c2deede742a3693ee1ca626415e041c..a7707287a2412f130643aae165dab7fc2a07011b 100644 (file)
@@ -39,14 +39,14 @@ SECTIONS
        . = ALIGN(4);
        .data  : { *(.data) }
 
-       . = ALIGN(4);
-       .sdata  : { *(.sdata) }
+       . = .;
+       _gp = ALIGN(16) + 0x7ff0;
 
-       _gp = ALIGN(16);
-
-       __got_start = .;
-       .got  : { *(.got) }
-       __got_end = .;
+       .got : {
+         __got_start = .;
+         *(.got)
+         __got_end = .;
+       }
 
        .sdata  : { *(.sdata) }
 
index 98e3e86ffa555906b0eb34c2cd3fff40fb425767..b8a3594e9e546f901af9449849d239834dcc9cf1 100644 (file)
@@ -29,7 +29,7 @@
 
 #include <common.h>
 #include <exports.h>
-#include "../drivers/smc91111.h"
+#include "../drivers/net/smc91111.h"
 
 #define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE
 #define EEPROM         0x1;
index c1357d0aa5caa40347dbd1d9a653c4c9646412ca..a071af1f6e5d737cc743fdd73f794bf181c4ea32 100644 (file)
@@ -26,9 +26,15 @@ include $(TOPDIR)/config.mk
 LIB    = $(obj)libjffs2.a
 
 AOBJS  =
-COBJS  = jffs2_1pass.o compr_rtime.o compr_rubin.o compr_zlib.o mini_inflate.o
-COBJS  += compr_lzo.o compr_lzari.o
-
+COBJS-y += jffs2_1pass.o
+COBJS-y += compr_rtime.o
+COBJS-y += compr_rubin.o
+COBJS-y += compr_zlib.o
+COBJS-y += mini_inflate.o
+COBJS-y += compr_lzo.o
+COBJS-y += compr_lzari.o
+
+COBJS  := $(COBJS-y)
 SRCS   := $(AOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(AOBJS) $(COBJS))
 
diff --git a/include/.gitignore b/include/.gitignore
new file mode 100644 (file)
index 0000000..d8fda80
--- /dev/null
@@ -0,0 +1,6 @@
+/asm
+/asm-ppc/arch
+/bmp_logo.h
+/config.h
+/config.mk
+/version_autogenerated.h
index 8bb0c47523653d8d2e8745b880a20c001ad49c43..b868e38a3efd4d2e5e100a331942faac60f5a056 100644 (file)
@@ -24,8 +24,6 @@
 
 #ifndef __ASSEMBLY__
 #include "AT91RM9200.h"
-#else
-#include "AT91RM9200_inc.h"
 #endif
 
 /* Virtual and Physical base address for system peripherals */
index 2a3980c13029f06761a44eac0261e35064d5f027..271c27655bd21fb5e644674885c12065ffc88f85 100644 (file)
@@ -57,7 +57,8 @@
 #define MMAP_PWM       0xFC090000
 #define MMAP_EPORT     0xFC094000
 #define MMAP_WDOG      0xFC098000
-#define MMAP_CCM       0xFC0A0000
+#define MMAP_RCM       0xFC0A0000
+#define MMAP_CCM       0xFC0A0004
 #define MMAP_GPIO      0xFC0A4000
 #define MMAP_RTC       0xFC0A8000
 #define MMAP_LCDC      0xFC0AC000
@@ -479,20 +480,22 @@ typedef struct wdog_ctrl {
 
 /*Chip configuration module registers */
 typedef struct ccm_ctrl {
-       u8 rstctrl;             /* 0x00 Reset Controller register */
-       u8 rststat;             /* 0x01 Reset Status register */
-       u16 res1;               /* 0x02 - 0x03 */
-       u16 ccr;                /* 0x04 Chip configuration register */
-       u16 res2;               /* 0x06 */
-       u16 rcon;               /* 0x08 Rreset configuration register */
-       u16 cir;                /* 0x0A Chip identification register */
-       u32 res3;               /* 0x0C */
-       u16 misccr;             /* 0x10 Miscellaneous control register */
-       u16 cdr;                /* 0x12 Clock divider register */
-       u16 uhcsr;              /* 0x14 USB Host controller status register */
-       u16 uocsr;              /* 0x16 USB On-the-Go Controller Status Register */
+       u16 ccr;                /* 0x00 Chip configuration register */
+       u16 res2;               /* 0x02 */
+       u16 rcon;               /* 0x04 Rreset configuration register */
+       u16 cir;                /* 0x06 Chip identification register */
+       u32 res3;               /* 0x08 */
+       u16 misccr;             /* 0x0A Miscellaneous control register */
+       u16 cdr;                /* 0x0C Clock divider register */
+       u16 uhcsr;              /* 0x10 USB Host controller status register */
+       u16 uocsr;              /* 0x12 USB On-the-Go Controller Status Reg */
 } ccm_t;
 
+typedef struct rcm {
+       u8 rcr;
+       u8 rsr;
+} rcm_t;
+
 /* GPIO port registers */
 typedef struct gpio_ctrl {
        /* Port Output Data Registers */
index cd69fb0b5af22eae22e2e5df0bd268816344e86e..3f056511cb60dcf76f4d3c02b59f7f6b7b0c1ca1 100644 (file)
 #define CSCR_BSTR                      (0x00000010)
 #define CSCR_BSTW                      (0x00000008)
 
+/*********************************************************************
+* Reset Controller Module (RCM)
+*********************************************************************/
+
+/* Bit definitions and macros for RCR */
+#define RCM_RCR_FRCRSTOUT              (0x40)
+#define RCM_RCR_SOFTRST                        (0x80)
+
+/* Bit definitions and macros for RSR */
+#define RCM_RSR_LOL                    (0x01)
+#define RCM_RSR_WDR_CORE               (0x02)
+#define RCM_RSR_EXT                    (0x04)
+#define RCM_RSR_POR                    (0x08)
+#define RCM_RSR_SOFT                   (0x20)
+
 /*********************************************************************
 * FlexCAN Module (CAN)
 *********************************************************************/
index 8b886b0b605360bcd44f92eb7ae9516aec101c2c..b2bfb69264cc4819fe62e66090d85c82dcb7d7a6 100644 (file)
 #define GPIO_PAR_FEC_FEC0_MASK         (0xF8)
 #define GPIO_PAR_FEC_FEC0_MII          (0x07)
 #define GPIO_PAR_FEC_FEC0_RMII_GPIO    (0x03)
-#define GPIO_PAR_FEC_FEC0_RMII_ATA     (0x02)
-#define GPIO_PAR_FEC_FEC0_ATA          (0x01)
+#define GPIO_PAR_FEC_FEC0_RMII_ULPI    (0x02)
+#define GPIO_PAR_FEC_FEC0_ULPI         (0x01)
 #define GPIO_PAR_FEC_FEC0_GPIO         (0x00)
 
 /* Bit definitions and macros for PAR_DMA */
index b8214b1c8595cdf82d862d1e5fd8cb60ca1037c3..0e6abd7d0faa914c495dcc50a354c6ca730515db 100644 (file)
@@ -49,7 +49,7 @@
    cannot access physical memory directly from core */
 #define UNCACHED_SDRAM(a) (((unsigned long)(a)) | 0x20000000)
 #else  /* !CONFIG_AU1X00 */
-#define UNCACHED_SDRAM(a) PHYSADDR(a)
+#define UNCACHED_SDRAM(a) KSEG1ADDR(a)
 #endif /* CONFIG_AU1X00 */
 #endif /* __ASSEMBLY__ */
 /*
index cd4d5dc9d9e8e4ff158e18f89ceeb268d6e495e9..1e060f7c31d7bfb01b14d34bfd02324ef7c828c4 100644 (file)
  * instruction, so the lower 16 bits must be zero.  Should be true on
  * on any sane architecture; generic code does not use this assumption.
  */
-extern unsigned long mips_io_port_base;
+extern const unsigned long mips_io_port_base;
+
+/*
+ * Gcc will generate code to load the value of mips_io_port_base after each
+ * function call which may be fairly wasteful in some cases.  So we don't
+ * play quite by the book.  We tell gcc mips_io_port_base is a long variable
+ * which solves the code generation issue.  Now we need to violate the
+ * aliasing rules a little to make initialization possible and finally we
+ * will need the barrier() to fight side effects of the aliasing chat.
+ * This trickery will eventually collapse under gcc's optimizer.  Oh well.
+ */
+static inline void set_io_port_base(unsigned long base)
+{
+       * (unsigned long *) &mips_io_port_base = base;
+}
 
 /*
  * Thanks to James van Artsdalen for a better timing-fix than
index 77aed1a318dd1bf32da983b733049aa89b280cfb..edd00247ebb9dc3f4cd6d1cec67244936a5172ca 100644 (file)
@@ -63,19 +63,13 @@ typedef volatile unsigned char      vu_char;
 #endif
 #elif defined(CONFIG_5xx)
 #include <asm/5xx_immap.h>
-#define CONFIG_RELOC_FIXUP_WORKS
 #elif defined(CONFIG_MPC5xxx)
 #include <mpc5xxx.h>
-#define CONFIG_RELOC_FIXUP_WORKS
 #elif defined(CONFIG_MPC512X)
 #include <mpc512x.h>
 #include <asm/immap_512x.h>
-#define CONFIG_RELOC_FIXUP_WORKS
 #elif defined(CONFIG_MPC8220)
 #include <asm/immap_8220.h>
-#define CONFIG_RELOC_FIXUP_WORKS
-#elif defined(CONFIG_824X)
-#define CONFIG_RELOC_FIXUP_WORKS
 #elif defined(CONFIG_8260)
 #if   defined(CONFIG_MPC8247) \
    || defined(CONFIG_MPC8248) \
@@ -87,7 +81,6 @@ typedef volatile unsigned char        vu_char;
 #define CONFIG_MPC8260 1
 #endif
 #include <asm/immap_8260.h>
-#define CONFIG_RELOC_FIXUP_WORKS
 #endif
 #ifdef CONFIG_MPC86xx
 #include <mpc86xx.h>
@@ -100,7 +93,6 @@ typedef volatile unsigned char       vu_char;
 #ifdef CONFIG_MPC83XX
 #include <mpc83xx.h>
 #include <asm/immap_83xx.h>
-#define CONFIG_RELOC_FIXUP_WORKS
 #endif
 #ifdef CONFIG_4xx
 #include <ppc4xx.h>
index 77938b140da9821607a9192e29789e2819b22f33..c45c39554eb12e75b32e36605664f746164e9d0d 100644 (file)
 /*
  * Command line configuration.
  */
-#include <config_cmd_all.h>
-
-#undef CONFIG_CMD_ASKENV
-#undef CONFIG_CMD_BEDBUG
-#undef CONFIG_CMD_BMP
-#undef CONFIG_CMD_CACHE
-#undef CONFIG_CMD_DOC
-#undef CONFIG_CMD_DTT
-#undef CONFIG_CMD_EEPROM
-#undef CONFIG_CMD_ELF
-#undef CONFIG_CMD_FAT
-#undef CONFIG_CMD_FDC
-#undef CONFIG_CMD_FDOS
-#undef CONFIG_CMD_HWFLOW
-#undef CONFIG_CMD_IDE
-#undef CONFIG_CMD_I2C
-#undef CONFIG_CMD_JFFS2
-#undef CONFIG_CMD_KGDB
-#undef CONFIG_CMD_NAND
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_BSP
+#define CONFIG_CMD_CDP
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_DISPLAY
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_IMMAP
+#define CONFIG_CMD_IRQ
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_PORTIO
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_REISER
+#define CONFIG_CMD_SAVES
+#define CONFIG_CMD_SDRAM
+#define CONFIG_CMD_SNTP
+
 #undef CONFIG_CMD_NFS
-#undef CONFIG_CMD_MMC
-#undef CONFIG_CMD_MII
-#undef CONFIG_CMD_PCI
-#undef CONFIG_CMD_PCMCIA
-#undef CONFIG_CMD_SCSI
-#undef CONFIG_CMD_VFD
-#undef CONFIG_CMD_USB
 #undef CONFIG_CMD_XIMG
 
-#if (CFG_NIOS_CPU_SPI_NUMS != 1)
-#undef CONFIG_CMD_SPI
-#undef CONFIG_CMD_DATE
+#if (CFG_NIOS_CPU_SPI_NUMS == 1)
+#define CONFIG_CMD_DATE
+#define CONFIG_CMD_SPI
 #endif
 
 /*------------------------------------------------------------------------
index 0ddf0e3aeb974c92901f5507b17960932a4cea28..eb7808020804de0a9f77541542bae2668fa1dedc 100644 (file)
 /*
  * Command line configuration.
  */
-#include <config_cmd_all.h>
-
-#undef CONFIG_CMD_ASKENV
-#undef CONFIG_CMD_BEDBUG
-#undef CONFIG_CMD_BMP
-#undef CONFIG_CMD_BSP
-#undef CONFIG_CMD_CACHE
-#undef CONFIG_CMD_DATE
-#undef CONFIG_CMD_DOC
-#undef CONFIG_CMD_DTT
-#undef CONFIG_CMD_EEPROM
-#undef CONFIG_CMD_ELF
-#undef CONFIG_CMD_FDC
-#undef CONFIG_CMD_FDOS
-#undef CONFIG_CMD_HWFLOW
-#undef CONFIG_CMD_I2C
-#undef CONFIG_CMD_JFFS2
-#undef CONFIG_CMD_KGDB
-#undef CONFIG_CMD_NAND
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_CDP
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_DISPLAY
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_IDE
+#define CONFIG_CMD_IMMAP
+#define CONFIG_CMD_IRQ
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_PORTIO
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_SAVES
+#define CONFIG_CMD_SDRAM
+#define CONFIG_CMD_SNTP
+
 #undef CONFIG_CMD_NFS
-#undef CONFIG_CMD_MMC
-#undef CONFIG_CMD_MII
-#undef CONFIG_CMD_PCI
-#undef CONFIG_CMD_PCMCIA
-#undef CONFIG_CMD_REISER
-#undef CONFIG_CMD_SCSI
-#undef CONFIG_CMD_SPI
-#undef CONFIG_CMD_VFD
-#undef CONFIG_CMD_USB
 #undef CONFIG_CMD_XIMG
 
-
 /*------------------------------------------------------------------------
  * COMPACT FLASH
  *----------------------------------------------------------------------*/
index 0032fd3db71f1083fd40f9458da462f49291dedc..bd360717a79a34cc550b3f7eb43213bf2023cc07 100644 (file)
 /*
  * Command line configuration.
  */
-#include <config_cmd_all.h>
-
-#undef CONFIG_CMD_ASKENV
-#undef COND_CMD_BEDBUG
-#undef COND_CMD_BMP
-#undef COND_CMD_BSP
-#undef COND_CMD_CACHE
-#undef COND_CMD_DATE
-#undef COND_CMD_DOC
-#undef COND_CMD_DTT
-#undef COND_CMD_EEPROM
-#undef COND_CMD_ELF
-#undef COND_CMD_FAT
-#undef COND_CMD_FDC
-#undef COND_CMD_FDOS
-#undef COND_CMD_HWFLOW
-#undef COND_CMD_IDE
-#undef COND_CMD_I2C
-#undef COND_CMD_JFFS2
-#undef COND_CMD_KGDB
-#undef COND_CMD_NAND
-#undef COND_CMD_NFS
-#undef COND_CMD_MMC
-#undef COND_CMD_MII
-#undef COND_CMD_PCI
-#undef COND_CMD_PCMCIA
-#undef COND_CMD_SCSI
-#undef COND_CMD_SPI
-#undef COND_CMD_VFD
-#undef COND_CMD_USB
-#undef COND_CMD_XIMG
-
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_CDP
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_DISPLAY
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_IMMAP
+#define CONFIG_CMD_IRQ
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_PORTIO
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_REISER
+#define CONFIG_CMD_SAVES
+#define CONFIG_CMD_SDRAM
+#define CONFIG_CMD_SNTP
+
+#undef CONFIG_CMD_NFS
+#undef CONFIG_CMD_XIMG
 
 /*------------------------------------------------------------------------
  * KGDB
index 85d2bb3f513f5e25d47c358b3e6f2146f7328fdf..bb87fae8c49cc1d31922f726ef195205a74ef3ec 100644 (file)
 
 #define CFG_NS16550_COM1        (CFG_UART_BASE + 0x8000)
 
+
+/* pass open firmware flat tree */
+#define CONFIG_OF_LIBFDT       1
+#define CONFIG_OF_BOARD_SETUP  1
+
+#define OF_CPU "PowerPC,8247@0"
+#define OF_SOC "soc@f0000000"
+#define OF_TBCLK       (bd->bi_busfreq / 4)
+#define OF_STDOUT_PATH "/soc@f0000000/serial8250@e0008000"
+
+
 /*
  * select ethernet configuration
  *
 #undef CONFIG_ETHER_ON_SCC             /* define if ether on SCC       */
 #define        CONFIG_ETHER_ON_FCC             /* define if ether on FCC       */
 #undef CONFIG_ETHER_NONE               /* define if ether on something else */
-#define        CONFIG_ETHER_INDEX    2         /* which SCC/FCC channel for ethernet */
+#define        CONFIG_ETHER_INDEX      1       /* which SCC/FCC channel for ethernet */
+#define CONFIG_ETHER_ON_FCC1
+#define FCC_ENET
 
 /*
- * - Rx-CLK is CLK13
- * - Tx-CLK is CLK14
+ * - Rx-CLK is CLK10
+ * - Tx-CLK is CLK9
  * - RAM for BD/Buffers is on the 60x Bus (see 28-13)
  * - Enable Full Duplex in FSMR
  */
-# define CFG_CMXFCR_MASK       (CMXFCR_FC2|CMXFCR_RF2CS_MSK|CMXFCR_TF2CS_MSK)
-# define CFG_CMXFCR_VALUE      (CMXFCR_RF2CS_CLK13|CMXFCR_TF2CS_CLK14)
+# define CFG_CMXFCR_MASK       (CMXFCR_FC1|CMXFCR_RF1CS_MSK|CMXFCR_TF1CS_MSK)
+# define CFG_CMXFCR_VALUE      (CMXFCR_RF1CS_CLK10|CMXFCR_TF1CS_CLK9)
 # define CFG_CPMFCR_RAMTYPE    0
 # define CFG_FCC_PSMR          (FCC_PSMR_FDE|FCC_PSMR_LPB)
 
 #define CONFIG_BOOTP_BOOTPATH
 #define CONFIG_BOOTP_BOOTFILESIZE
 
+#define CONFIG_RTC_PCF8563
+#define CFG_I2C_RTC_ADDR               0x51
 
 /*
  * Command line configuration.
  */
 #define CFG_BOOTMAPSZ        (8 << 20)       /* Initial Memory map for Linux */
 
-
+#define CFG_FLASH_CFI                          /* The flash is CFI compatible  */
+#define CFG_FLASH_CFI_DRIVER                   /* Use common CFI driver        */
+#define CFG_FLASH_BANKS_LIST   { 0xFF800000 }
+#define CFG_MAX_FLASH_BANKS_DETECT     1
 /* What should the base address of the main FLASH be and how big is
  * it (in MBytes)? This must contain TEXT_BASE from board/ids8247/config.mk
  * The main FLASH is whichever is connected to *CS0.
  * FLASH organization
  */
 #define CFG_MAX_FLASH_BANKS    1       /* max num of memory banks      */
-#define CFG_MAX_FLASH_SECT     64      /* max num of sects on one chip */
+#define CFG_MAX_FLASH_SECT     128     /* max num of sects on one chip */
 
 #define CFG_FLASH_ERASE_TOUT   240000  /* Flash Erase Timeout (in ms)  */
 #define CFG_FLASH_WRITE_TOUT   500     /* Flash Write Timeout (in ms)  */
 */
 #define CFG_OR2    ((~(CFG_GLOBAL_SDRAM_LIMIT-1) & ORxS_SDAM_MSK) |\
                         ORxS_BPD_4                     |\
-                        ORxS_ROWST_PBI0_A10             |\
+                        ORxS_ROWST_PBI0_A9             |\
                         ORxS_NUMR_12)
 
-#define CFG_PSDMR  (PSDMR_SDAM_A13_IS_A5 |\
+#define CFG_PSDMR  (PSDMR_SDAM_A14_IS_A5 |\
                         PSDMR_BSMA_A15_A17           |\
-                        PSDMR_SDA10_PBI0_A11         |\
+                        PSDMR_SDA10_PBI0_A10           |\
                         PSDMR_RFRC_5_CLK               |\
                         PSDMR_PRETOACT_2W              |\
                         PSDMR_ACTTORW_2W               |\
index 46edd08a91f5b34762c8b5621907cd7438bfc7d8..e92069b5a935aebe0cc505522e12dfc9976779fe 100644 (file)
 /*
  * Command line configuration.
  */
-#include <config_cmd_all.h>
-
-#undef CONFIG_CMD_BEDBUG
-#undef CONFIG_CMD_BMP
-#undef CONFIG_CMD_BSP
-#undef CONFIG_CMD_DISPLAY
-#undef CONFIG_CMD_DOC
-#undef CONFIG_CMD_DTT
-#undef CONFIG_CMD_EEPROM
-#undef CONFIG_CMD_ELF
-#undef CONFIG_CMD_EXT2
-#undef CONFIG_CMD_FDC
-#undef CONFIG_CMD_FDOS
-#undef CONFIG_CMD_HWFLOW
-#undef CONFIG_CMD_I2C
-#undef CONFIG_CMD_IDE
-#undef CONFIG_CMD_IRQ
-#undef CONFIG_CMD_JFFS2
-#undef CONFIG_CMD_KGDB
-#undef CONFIG_CMD_MFSL
-#undef CONFIG_CMD_MII
-#undef CONFIG_CMD_MMC
-#undef CONFIG_CMD_NAND
-#undef CONFIG_CMD_PCI
-#undef CONFIG_CMD_PCMCIA
-#undef CONFIG_CMD_REISER
-#undef CONFIG_CMD_SCSI
-#undef CONFIG_CMD_SPI
-#undef CONFIG_CMD_UNIVERSE
-#undef CONFIG_CMD_USB
-#undef CONFIG_CMD_VFD
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_CDP
+#define CONFIG_CMD_DATE
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_IMMAP
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_PORTIO
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_SAVES
+#define CONFIG_CMD_SDRAM
+#define CONFIG_CMD_SNTP
+
 #undef CONFIG_CMD_XIMG
 
 #if !(CONFIG_LANTEC >= 2)
index 48170e7a35a7965c2f8e1c4fa92085e249fe1b81..f5e1b646ca2e52000e1f8dd5b175e92c75869028 100644 (file)
  * Please note that CFG_SDRAM_BASE _must_ start at 0
  */
 #define CFG_SDRAM_BASE         0x00000000
-#define CFG_SDRAM_SIZE         16      /* SDRAM size in MB */
+#define CFG_SDRAM_SIZE               /* SDRAM size in MB */
 
 #ifdef CONFIG_MONITOR_IS_IN_RAM
 #define CFG_MONITOR_BASE       0x20000
index 3c17c1ea1465c32a6ba6db6397de4a0f99a95684..7bb9f60f7650058ff24dc1967da773a036cfc903 100644 (file)
  * Please note that CFG_SDRAM_BASE _must_ start at 0
  */
 #define CFG_SDRAM_BASE         0x00000000
-#define        CFG_SDRAM_SIZE                /* SDRAM size in MB */
+#define        CFG_SDRAM_SIZE          16      /* SDRAM size in MB */
 #define CFG_FLASH_BASE         0xffe00000
 #define        CFG_INT_FLASH_BASE      0xf0000000
 #define CFG_INT_FLASH_ENABLE   0x21
index d3b160505be3c766638b42e5fd5e2b0e8e81674f..47d74a3c37a3179ce75a8505121207f76a39d6e9 100644 (file)
  * Please note that CFG_SDRAM_BASE _must_ start at 0
  */
 #define CFG_SDRAM_BASE         0x40000000
-#define CFG_SDRAM_SIZE         16      /* SDRAM size in MB */
+#define CFG_SDRAM_SIZE         32      /* SDRAM size in MB */
 #define CFG_SDRAM_CFG1         0x53722730
 #define CFG_SDRAM_CFG2         0x56670000
 #define CFG_SDRAM_CTRL         0xE1092000
index 6f4859c238037a1e9d8d713574d92a4b82955cc2..db309584b9a26138cb55926f3bbdd59956ef3c31 100644 (file)
@@ -27,8 +27,8 @@
  * board/config.h - configuration options, board specific
  */
 
-#ifndef _JAMICA54455_H
-#define _JAMICA54455_H
+#ifndef _M54455EVB_H
+#define _M54455EVB_H
 
 /*
  * High Level Configuration Options
@@ -75,7 +75,7 @@
 #define CONFIG_CMD_MISC
 #define CONFIG_CMD_MII
 #define CONFIG_CMD_NET
-#define CONFIG_CMD_PCI
+#undef CONFIG_CMD_PCI
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_REGINFO
 
        "u-boot=u-boot.bin\0"                   \
        "load=tftp ${loadaddr) ${u-boot}\0"     \
        "upd=run load; run prog\0"              \
-       "prog=prot off 2ffff;"                \
-       "era 2ffff;"                          \
+       "prog=prot off 4000000 402ffff;"                \
+       "era 4000000 402ffff;"                          \
        "cp.b ${loadaddr} 0 ${filesize};"       \
        "save\0"                                \
        ""
 #define CFG_IMMR               CFG_MBAR
 
 /* PCI */
+#ifdef CONFIG_CMD_PCI
 #define CONFIG_PCI             1
 
 #define CFG_PCI_MEM_BUS                0xA0000000
 #define CFG_PCI_CFG_BUS                0xB0000000
 #define CFG_PCI_CFG_PHYS       CFG_PCI_CFG_BUS
 #define CFG_PCI_CFG_SIZE       0x01000000
+#endif
 
 /* FPGA - Spartan 2 */
 /* experiment
 /* Configuration for environment
  * Environment is embedded in u-boot in the second sector of the flash
  */
-#define CFG_ENV_OFFSET         0x4000
-#define CFG_ENV_SECT_SIZE      0x2000
 #define CFG_ENV_IS_IN_FLASH    1
 #define CONFIG_ENV_OVERWRITE   1
 #undef CFG_ENV_IS_EMBEDDED
  * FLASH organization
  */
 #ifdef CFG_ATMEL_BOOT
-#      define CFG_FLASH_BASE           0
+#      define CFG_FLASH_BASE           CFG_CS0_BASE
 #      define CFG_FLASH0_BASE          CFG_CS0_BASE
 #      define CFG_FLASH1_BASE          CFG_CS1_BASE
+#      define CFG_ENV_ADDR             (CFG_FLASH_BASE + 0x4000)
+#      define CFG_ENV_SECT_SIZE        0x2000
 #else
 #      define CFG_FLASH_BASE           CFG_FLASH0_BASE
 #      define CFG_FLASH0_BASE          CFG_CS1_BASE
 #      define CFG_FLASH1_BASE          CFG_CS0_BASE
+#      define CFG_ENV_ADDR             (CFG_FLASH_BASE + 0x60000)
+#      define CFG_ENV_SECT_SIZE        0x20000
 #endif
 
 /* M54455EVB has one non CFI flash, defined CFG_FLASH_CFI will cause the system
  * NOTE: Enable CONFIG_CMD_JFFS2 for JFFS2 support.
  */
 #ifdef CFG_ATMEL_BOOT
-#      define CONFIG_JFFS2_DEV         "nor0"
+#      define CONFIG_JFFS2_DEV         "nor1"
 #      define CONFIG_JFFS2_PART_SIZE   0x01000000
-#      define CONFIG_JFFS2_PART_OFFSET CFG_FLASH1_BASE
+#      define CONFIG_JFFS2_PART_OFFSET (CFG_FLASH1_BASE + 0x500000)
 #else
 #      define CONFIG_JFFS2_DEV         "nor0"
 #      define CONFIG_JFFS2_PART_SIZE   (0x01000000 - 0x500000)
 
 #ifdef CFG_ATMEL_BOOT
  /* Atmel Flash */
-#define CFG_CS0_BASE           0
+#define CFG_CS0_BASE           0x04000000
 #define CFG_CS0_MASK           0x00070001
 #define CFG_CS0_CTRL           0x00001140
 /* Intel Flash */
-#define CFG_CS1_BASE           0x04000000
+#define CFG_CS1_BASE           0x00000000
 #define CFG_CS1_MASK           0x01FF0001
-#define CFG_CS1_CTRL           0x003F3D60
+#define CFG_CS1_CTRL           0x00000D60
 
 #define CFG_ATMEL_BASE         CFG_CS0_BASE
 #else
 /* Intel Flash */
-#define CFG_CS0_BASE           0
+#define CFG_CS0_BASE           0x00000000
 #define CFG_CS0_MASK           0x01FF0001
-#define CFG_CS0_CTRL           0x003F3D60
+#define CFG_CS0_CTRL           0x00000D60
  /* Atmel Flash */
 #define CFG_CS1_BASE           0x04000000
 #define CFG_CS1_MASK           0x00070001
 #define CFG_CS3_MASK           0x00070001
 #define CFG_CS3_CTRL           0x00000020
 
-#endif                         /* _JAMICA54455_H */
+#endif                         /* _M54455EVB_H */
index 713518d0da247427351f5283890caa2ba2bedcb8..23508f9f5ae13e6826843bb25423fda5fe5a6b36 100644 (file)
 /*
  * Command line configuration.
  */
-#include <config_cmd_all.h>
-
-#undef CONFIG_CMD_BEDBUG
-#undef CONFIG_CMD_BMP
-#undef CONFIG_CMD_BSP
-#undef CONFIG_CMD_DATE
-#undef CONFIG_CMD_DISPLAY
-#undef CONFIG_CMD_DOC
-#undef CONFIG_CMD_DTT
-#undef CONFIG_CMD_EEPROM
-#undef CONFIG_CMD_ELF
-#undef CONFIG_CMD_EXT2
-#undef CONFIG_CMD_FAT
-#undef CONFIG_CMD_FDC
-#undef CONFIG_CMD_FDOS
-#undef CONFIG_CMD_HWFLOW
-#undef CONFIG_CMD_IDE
-#undef CONFIG_CMD_KGDB
-#undef CONFIG_CMD_MFSL
-#undef CONFIG_CMD_MMC
-#undef CONFIG_CMD_NAND
-#undef CONFIG_CMD_PCMCIA
-#undef CONFIG_CMD_REISER
-#undef CONFIG_CMD_SCSI
-#undef CONFIG_CMD_SPI
-#undef CONFIG_CMD_SNTP
-#undef CONFIG_CMD_UNIVERSE
-#undef CONFIG_CMD_USB
-#undef CONFIG_CMD_VFD
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_CDP
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_IMMAP
+#define CONFIG_CMD_IRQ
+#define CONFIG_CMD_JFFS2
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_PCI
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_PORTIO
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_SAVES
+#define CONFIG_CMD_SDRAM
+
 #undef CONFIG_CMD_XIMG
 
 #if CONFIG_ADSTYPE == CFG_8272ADS
index 4e061bd9ff25147758eee27591ad2b346bf7492b..8dda6651efc2e6c5938eb5c06e49757b10020421 100644 (file)
@@ -316,6 +316,7 @@ extern unsigned long get_clock_freq(void);
 #define OF_SOC                 "soc8541@e0000000"
 #define OF_TBCLK               (bd->bi_busfreq / 8)
 #define OF_STDOUT_PATH         "/soc8541@e0000000/serial@4600"
+#define OF_PCI                 "pci@e0008000"
 
 /*
  * I2C
index f580ccadee5ea515ff5b911c348da1529834eca6..13e2a2c079fca14d44a5347d890e68abd033cb3e 100644 (file)
@@ -198,6 +198,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
 #define PIXIS_VSPEED1          0x18    /* VELA VSpeed 1 */
 #define PIXIS_VCLKH            0x19    /* VELA VCLKH register */
 #define PIXIS_VCLKL            0x1A    /* VELA VCLKL register */
+#define CFG_PIXIS_VBOOT_MASK   0x40    /* Reset altbank mask*/
 
 
 /* define to use L1 as initial stack */
index 608371518939a81876da9e4696183cf51f468604..4edc7fd2b6a5bdcacf395db9b61324c6000f3ed4 100644 (file)
@@ -340,6 +340,7 @@ extern unsigned long get_clock_freq(void);
 #define OF_SOC                 "soc8548@e0000000"
 #define OF_TBCLK               (bd->bi_busfreq / 8)
 #define OF_STDOUT_PATH         "/soc8548@e0000000/serial@4600"
+#define OF_PCI                 "pci@e0008000"
 
 /*
  * I2C
index 1d1b7c907957c153763c92e02732d0499fc9fc99..c414bf033e48aefa27acbbdf42c023783568cbea 100644 (file)
@@ -316,6 +316,7 @@ extern unsigned long get_clock_freq(void);
 #define OF_SOC                 "soc8555@e0000000"
 #define OF_TBCLK               (bd->bi_busfreq / 8)
 #define OF_STDOUT_PATH         "/soc8555@e0000000/serial@4600"
+#define OF_PCI                 "pci@e0008000"
 
 /*
  * I2C
index ba744e99f8d3d0e6437a100570bef7d763c87df9..b9366cc99476dc70d2d1df7f025715c495cc0461 100644 (file)
@@ -297,7 +297,7 @@ extern unsigned long get_clock_freq(void);
 #define OF_SOC                 "soc8568@e0000000"
 #define OF_QE                  "qe@e0080000"
 #define OF_TBCLK               (bd->bi_busfreq / 8)
-#define OF_STDOUT_PATH         "/soc8568@e0000000/serial@4600"
+#define OF_STDOUT_PATH         "/soc8568@e0000000/serial@4500"
 
 /*
  * I2C
@@ -334,11 +334,6 @@ extern unsigned long get_clock_freq(void);
 
 #define CFG_SRIO_MEM_BASE      0xc0000000
 
-#if defined(CONFIG_PCI)
-
-#define CONFIG_NET_MULTI
-#define CONFIG_PCI_PNP                 /* do pci plug-and-play */
-
 #ifdef CONFIG_QE
 /*
  * QE UEC ethernet configuration
@@ -377,6 +372,11 @@ extern unsigned long get_clock_freq(void);
 #endif
 #endif /* CONFIG_QE */
 
+#if defined(CONFIG_PCI)
+
+#define CONFIG_NET_MULTI
+#define CONFIG_PCI_PNP                 /* do pci plug-and-play */
+
 #undef CONFIG_EEPRO100
 #undef CONFIG_TULIP
 
index 7d8a380dc04e3f98362e40042fcfc4e883fbf545..6f8724026333015a119001749448497e729e1a63 100644 (file)
@@ -201,6 +201,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
 #define PIXIS_VSPEED1          0x18    /* VELA VSpeed 1 */
 #define PIXIS_VCLKH            0x19    /* VELA VCLKH register */
 #define PIXIS_VCLKL            0x1A    /* VELA VCLKL register */
+#define CFG_PIXIS_VBOOT_MASK   0x40    /* Reset altbank mask*/
 
 #define CFG_MAX_FLASH_BANKS    2               /* number of banks */
 #define CFG_MAX_FLASH_SECT     128             /* sectors per device */
@@ -346,6 +347,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
 #define CFG_USB_EVENT_POLL     1
 #define CFG_USB_OHCI_SLOT_NAME         "ohci_pci"
 #define CFG_USB_OHCI_MAX_ROOT_PORTS 15
+#define CFG_OHCI_SWAP_REG_ACCESS       1
 
 #if !defined(CONFIG_PCI_PNP)
     #define PCI_ENET0_IOADDR   0xe0000000
@@ -544,6 +546,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
     #define CONFIG_CMD_PCI
     #define CONFIG_CMD_SCSI
     #define CONFIG_CMD_EXT2
+    #define CONFIG_CMD_USB
 #endif
 
 
index 2f6de815514de24f5c89f3553c2b20321e72a45a..fa32e33796a9cb11bea0adb0a77525f52c8e1ea5 100644 (file)
 /*
  * Command line configuration.
  */
-#include <config_cmd_all.h>
-
-#undef CONFIG_CMD_BSP
-#undef CONFIG_CMD_DATE
-#undef CONFIG_CMD_DISPLAY
-#undef CONFIG_CMD_DTT
-#undef CONFIG_CMD_EXT2
-#undef CONFIG_CMD_FDC
-#undef CONFIG_CMD_FDOS
-#undef CONFIG_CMD_HWFLOW
-#undef CONFIG_CMD_IDE
-#undef CONFIG_CMD_IRQ
-#undef CONFIG_CMD_JFFS2
-#undef CONFIG_CMD_MII
-#undef CONFIG_CMD_MFSL
-#undef CONFIG_CMD_MMC
-#undef CONFIG_CMD_NAND
-#undef CONFIG_CMD_PCI
-#undef CONFIG_CMD_PCMCIA
-#undef CONFIG_CMD_REISER
-#undef CONFIG_CMD_SCSI
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_BEDBUG
+#define CONFIG_CMD_BMP
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_CDP
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_DOC
+#define CONFIG_CMD_EEPROM
+#define CONFIG_CMD_ELF
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_IMMAP
+#define CONFIG_CMD_KGDB
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_PORTIO
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_SAVES
+#define CONFIG_CMD_SDRAM
+
 #undef CONFIG_CMD_SETGETDCR
-#undef CONFIG_CMD_SNTP
-#undef CONFIG_CMD_SPI
-#undef CONFIG_CMD_UNIVERSE
-#undef CONFIG_CMD_USB
-#undef CONFIG_CMD_VFD
 #undef CONFIG_CMD_XIMG
 
-
 /*
  * Miscellaneous configurable options
  */
index bb1efdf6deac7cb0991a4e7e344314463f4a7553..58060a8c8a5a5830ebc2cdbf5945b1de3e413127 100644 (file)
 #define CFG_I2C_SPEED          100000  /* I2C speed and slave address */
 #define CFG_I2C_SLAVE          0x7F
 #if 0
-#define CFG_I2C_NOPROBES       {{0,0x69}}      * Don't probe these addrs */
+#define CFG_I2C_NOPROBES       {{0,0x69}}      /* Don't probe these addrs */
 #endif
 
 /*
index 1809fc5d86401c21ee4281df7aa9ea57ae000a55..b33e26fe011727d7fbc9ff38c8d913565223bf8f 100644 (file)
 #define CONFIG_AUTOBOOT_STOP_STR       " "
 
 /*
- * These are "locally administered ethernet addresses" generated by
- * ./tools/gen_eth_addr
- *
- * After booting the board for the first time, new addresses should be
- * generated and assigned to the environment variables "ethaddr" and
- * "eth1addr".
+ * After booting the board for the first time, new ethernet addresses
+ * should be generated and assigned to the environment variables
+ * "ethaddr" and "eth1addr". This is normally done during production.
  */
-#define CONFIG_ETHADDR                 6a:87:71:14:cd:cb
-#define CONFIG_ETH1ADDR                        ca:f8:15:e6:3e:e6
 #define CONFIG_OVERWRITE_ETHADDR_ONCE  1
 #define CONFIG_NET_MULTI               1
 
index 025c24960d2118441b14dc0015d5bd0c29d40e6a..490db5fefd2a17f906b92cad56cac208fefd6ad8 100644 (file)
 /*
  * Command line configuration.
  */
-#include <config_cmd_all.h>
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_BEDBUG
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_CDP
+#define CONFIG_CMD_DATE
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_ELF
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_IMMAP
+#define CONFIG_CMD_IRQ
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_PORTIO
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_SAVES
+#define CONFIG_CMD_SDRAM
+#define CONFIG_CMD_SNTP
 
-#undef CONFIG_CMD_BMP
-#undef CONFIG_CMD_BSP
 #undef CONFIG_CMD_DCR
-#undef CONFIG_CMD_DHCP
-#undef CONFIG_CMD_DISPLAY
-#undef CONFIG_CMD_DOC
-#undef CONFIG_CMD_DTT
-#undef CONFIG_CMD_EEPROM
-#undef CONFIG_CMD_EXT2
-#undef CONFIG_CMD_FDC
-#undef CONFIG_CMD_FDOS
-#undef CONFIG_CMD_HWFLOW
-#undef CONFIG_CMD_IDE
-#undef CONFIG_CMD_JFFS2
-#undef CONFIG_CMD_KGDB
-#undef CONFIG_CMD_MII
-#undef CONFIG_CMD_MFSL
-#undef CONFIG_CMD_MMC
-#undef CONFIG_CMD_NAND
-#undef CONFIG_CMD_PCI
-#undef CONFIG_CMD_PCMCIA
-#undef CONFIG_CMD_REISER
-#undef CONFIG_CMD_SCSI
-#undef CONFIG_CMD_SPI
-#undef CONFIG_CMD_UNIVERSE
-#undef CONFIG_CMD_USB
-#undef CONFIG_CMD_VFD
 #undef CONFIG_CMD_XIMG
 
-
 /* Where do the internal registers live? */
 #define CFG_IMMR               0xF0000000
 #define CFG_DEFAULT_IMMR       0x00010000
index 2547afb3cf0d8a3915936ff01acd3478517258ff..01e79701623a0b28990b60353f3b26b474043ef8 100644 (file)
 /*
  * Command line configuration.
  */
-#include <config_cmd_all.h>
-
-#undef CONFIG_CMD_BEDBUG
-#undef CONFIG_CMD_BMP
-#undef CONFIG_CMD_DISPLAY
-#undef CONFIG_CMD_DOC
-#undef CONFIG_CMD_EXT2
-#undef CONFIG_CMD_FDC
-#undef CONFIG_CMD_FDOS
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_BSP
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_CDP
+#define CONFIG_CMD_DATE
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_DTT
+#define CONFIG_CMD_EEPROM
+#define CONFIG_CMD_ELF
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_IMMAP
+#define CONFIG_CMD_IRQ
+#define CONFIG_CMD_KGDB
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_PORTIO
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_SAVES
+#define CONFIG_CMD_SDRAM
+#define CONFIG_CMD_SNTP
+
 #undef CONFIG_CMD_FPGA
-#undef CONFIG_CMD_HWFLOW
-#undef CONFIG_CMD_IDE
-#undef CONFIG_CMD_JFFS2
-#undef CONFIG_CMD_NAND
-#undef CONFIG_CMD_MFSL
-#undef CONFIG_CMD_MMC
-#undef CONFIG_CMD_PCMCIA
-#undef CONFIG_CMD_PCI
-#undef CONFIG_CMD_USB
-#undef CONFIG_CMD_REISER
-#undef CONFIG_CMD_SCSI
-#undef CONFIG_CMD_SPI
-#undef CONFIG_CMD_UNIVERSE
-#undef CONFIG_CMD_VFD
 #undef CONFIG_CMD_XIMG
 
-
 #ifdef DEBUG
 #define CONFIG_BOOTDELAY       -1      /* autoboot disabled            */
 #else
index 814082ccc633bd20a4deafdf56514baa51cd37ee..40a05fa5e892d0b0350b4be75e195fdb30114429 100644 (file)
@@ -92,8 +92,8 @@
 
 /* enable I2C */
 #define CONFIG_HARD_I2C                1       /* I2C with hardware support */
-#define CFG_I2C_SPEED          400000  /* I2C speed and slave address */
-#define CFG_I2C_SLAVE          0x7F
+#define CFG_I2C_SPEED          50000   /* I2C speed and slave address */
+#define CFG_I2C_SLAVE          0x30
 
 
 /* system clock rate (CLKIN) - equal to the 60x and local bus speed */
index b4a063a1d4c6ad3c199b0b41e917dc4e27265aa6..9b05bd6c8c24cfa92926188af76f8e7ca2438a56 100644 (file)
 #define CONFIG_CMD_DHCP
 #define CONFIG_CMD_ELF
 #define CONFIG_CMD_PING
-#define CONFIG_CMD_REGINFO
 
 
 #define CONFIG_BOOTDELAY       3
index ca404ff452a5ec0b7bb12a5130f59761660a2264..18a036c2b64af1fb15fa81a36cd3e122cf1caf2d 100644 (file)
@@ -88,7 +88,6 @@
 #include <config_cmd_default.h>
 
 #define CONFIG_CMD_CACHE
-#define CONFIG_CMD_REGINFO
 #define CONFIG_CMD_DATE
 #define CONFIG_CMD_ELF
 
index aed80ec1e51beac012edcfa4f3c8007a8d78ec41..81df1419f5165b3c0e7bfe11466f549aa2736648 100644 (file)
 
 /* 8Mbit SRAM @0x80100000 */
 #define CFG_CS1_START          CFG_SRAM_BASE
-#define CFG_CS1_SIZE           0x00100000
+#define CFG_CS1_SIZE           0x00200000
 #define CFG_CS1_CFG            0x21D00
 
 /* Display H1, Status Inputs, EPLD @0x80600000 8 Bit */
index 3dd3aca3b6aaa53803b402be79f451313f18604e..48ccfd9100002deb3aff35ee4f17bc7d232b25b2 100644 (file)
@@ -1,22 +1,3 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
 #ifndef _FDT_H
 #define _FDT_H
 
index 60fa423b334ead6a60eb26fce036617f1a72b7ff..8f781d4405bf59f15f923949ead5d7ab1533887a 100644 (file)
 #include <fdt.h>
 
 int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force);
+void do_fixup_by_path(void *fdt, const char *path, const char *prop,
+                     const void *val, int len, int create);
+void do_fixup_by_path_u32(void *fdt, const char *path, const char *prop,
+                         u32 val, int create);
+void do_fixup_by_prop(void *fdt,
+                     const char *pname, const void *pval, int plen,
+                     const char *prop, const void *val, int len,
+                     int create);
+void do_fixup_by_prop_u32(void *fdt,
+                         const char *pname, const void *pval, int plen,
+                         const char *prop, u32 val, int create);
+void do_fixup_by_compat(void *fdt, const char *compat,
+                       const char *prop, const void *val, int len, int create);
+void do_fixup_by_compat_u32(void *fdt, const char *compat,
+                           const char *prop, u32 val, int create);
+void fdt_fixup_ethernet(void *fdt, bd_t *bd);
 
 #ifdef CONFIG_OF_HAS_UBOOT_ENV
 int fdt_env(void *fdt);
index 38c65a9899e41ff01c63c511f8fc9ecf86d97f2c..6b2fb92ea3578b7a4b6fb5c49ee2c1d8f4ecee5a 100644 (file)
+#ifndef _LIBFDT_H
+#define _LIBFDT_H
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ *  b) Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
  *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
+ *     1. Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *     2. Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef _LIBFDT_H
-#define _LIBFDT_H
-
-#include <fdt.h>
 #include <libfdt_env.h>
+#include <fdt.h>
 
 #define FDT_FIRST_SUPPORTED_VERSION    0x10
 #define FDT_LAST_SUPPORTED_VERSION     0x11
 
 /* Error codes: informative error codes */
 #define FDT_ERR_NOTFOUND       1
+       /* FDT_ERR_NOTFOUND: The requested node or property does not exist */
 #define FDT_ERR_EXISTS         2
+       /* FDT_ERR_EXISTS: Attemped to create a node or property which
+        * already exists */
 #define FDT_ERR_NOSPACE                3
+       /* FDT_ERR_NOSPACE: Operation needed to expand the device
+        * tree, but its buffer did not have sufficient space to
+        * contain the expanded tree. Use fdt_open_into() to move the
+        * device tree to a buffer with more space. */
 
 /* Error codes: codes for bad parameters */
 #define FDT_ERR_BADOFFSET      4
+       /* FDT_ERR_BADOFFSET: Function was passed a structure block
+        * offset which is out-of-bounds, or which points to an
+        * unsuitable part of the structure for the operation. */
 #define FDT_ERR_BADPATH                5
-#define FDT_ERR_BADSTATE       6
+       /* FDT_ERR_BADPATH: Function was passed a badly formatted path
+        * (e.g. missing a leading / for a function which requires an
+        * absolute path) */
+#define FDT_ERR_BADPHANDLE     6
+       /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle
+        * value.  phandle values of 0 and -1 are not permitted. */
+#define FDT_ERR_BADSTATE       7
+       /* FDT_ERR_BADSTATE: Function was passed an incomplete device
+        * tree created by the sequential-write functions, which is
+        * not sufficiently complete for the requested operation. */
 
 /* Error codes: codes for bad device tree blobs */
-#define FDT_ERR_TRUNCATED      7
-#define FDT_ERR_BADMAGIC       8
-#define FDT_ERR_BADVERSION     9
-#define FDT_ERR_BADSTRUCTURE   10
-#define FDT_ERR_BADLAYOUT      11
+#define FDT_ERR_TRUNCATED      8
+       /* FDT_ERR_TRUNCATED: Structure block of the given device tree
+        * ends without an FDT_END tag. */
+#define FDT_ERR_BADMAGIC       9
+       /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
+        * device tree at all - it is missing the flattened device
+        * tree magic number. */
+#define FDT_ERR_BADVERSION     10
+       /* FDT_ERR_BADVERSION: Given device tree has a version which
+        * can't be handled by the requested operation.  For
+        * read-write functions, this may mean that fdt_open_into() is
+        * required to convert the tree to the expected version. */
+#define FDT_ERR_BADSTRUCTURE   11
+       /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt
+        * structure block or other serious error (e.g. misnested
+        * nodes, or subnodes preceding properties). */
+#define FDT_ERR_BADLAYOUT      12
+       /* FDT_ERR_BADLAYOUT: For read-write functions, the given
+        * device tree has it's sub-blocks in an order that the
+        * function can't handle (memory reserve map, then structure,
+        * then strings).  Use fdt_open_into() to reorganize the tree
+        * into a form suitable for the read-write operations. */
+
+/* "Can't happen" error indicating a bug in libfdt */
+#define FDT_ERR_INTERNAL       13
+       /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.
+        * Should never be returned, if it is, it indicates a bug in
+        * libfdt itself. */
 
-#define FDT_ERR_MAX            11
+#define FDT_ERR_MAX            13
+
+/**********************************************************************/
+/* Low-level functions (you probably don't need these)                */
+/**********************************************************************/
+
+const void *fdt_offset_ptr(const void *fdt, int offset, int checklen);
+static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
+{
+       return (void *)fdt_offset_ptr(fdt, offset, checklen);
+}
+
+uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
+
+/**********************************************************************/
+/* General functions                                                  */
+/**********************************************************************/
 
 #define fdt_get_header(fdt, field) \
-       (fdt32_to_cpu(((struct fdt_header *)(fdt))->field))
-#define fdt_magic(fdt)                 (fdt_get_header(fdt, magic))
+       (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
+#define fdt_magic(fdt)                         (fdt_get_header(fdt, magic))
 #define fdt_totalsize(fdt)             (fdt_get_header(fdt, totalsize))
 #define fdt_off_dt_struct(fdt)         (fdt_get_header(fdt, off_dt_struct))
 #define fdt_off_dt_strings(fdt)                (fdt_get_header(fdt, off_dt_strings))
 #define fdt_off_mem_rsvmap(fdt)                (fdt_get_header(fdt, off_mem_rsvmap))
 #define fdt_version(fdt)               (fdt_get_header(fdt, version))
-#define fdt_last_comp_version(fdt)     (fdt_get_header(fdt, last_comp_version))
-#define fdt_boot_cpuid_phys(fdt)       (fdt_get_header(fdt, boot_cpuid_phys))
-#define fdt_size_dt_strings(fdt)       (fdt_get_header(fdt, size_dt_strings))
+#define fdt_last_comp_version(fdt)     (fdt_get_header(fdt, last_comp_version))
+#define fdt_boot_cpuid_phys(fdt)       (fdt_get_header(fdt, boot_cpuid_phys))
+#define fdt_size_dt_strings(fdt)       (fdt_get_header(fdt, size_dt_strings))
 #define fdt_size_dt_struct(fdt)                (fdt_get_header(fdt, size_dt_struct))
 
-#define fdt_set_header(fdt, field, val) \
-       ((struct fdt_header *)(fdt))->field = cpu_to_fdt32(val)
+#define __fdt_set_hdr(name) \
+       static inline void fdt_set_##name(void *fdt, uint32_t val) \
+       { \
+               struct fdt_header *fdth = fdt; \
+               fdth->name = cpu_to_fdt32(val); \
+       }
+__fdt_set_hdr(magic);
+__fdt_set_hdr(totalsize);
+__fdt_set_hdr(off_dt_struct);
+__fdt_set_hdr(off_dt_strings);
+__fdt_set_hdr(off_mem_rsvmap);
+__fdt_set_hdr(version);
+__fdt_set_hdr(last_comp_version);
+__fdt_set_hdr(boot_cpuid_phys);
+__fdt_set_hdr(size_dt_strings);
+__fdt_set_hdr(size_dt_struct);
+#undef __fdt_set_hdr
 
+/**
+ * fdt_check_header - sanity check a device tree or possible device tree
+ * @fdt: pointer to data which might be a flattened device tree
+ *
+ * fdt_check_header() checks that the given buffer contains what
+ * appears to be a flattened device tree with sane information in its
+ * header.
+ *
+ * returns:
+ *     0, if the buffer appears to contain a valid device tree
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE, standard meanings, as above
+ */
 int fdt_check_header(const void *fdt);
 
-void *fdt_offset_ptr(const void *fdt, int offset, int checklen);
+/**
+ * fdt_move - move a device tree around in memory
+ * @fdt: pointer to the device tree to move
+ * @buf: pointer to memory where the device is to be moved
+ * @bufsize: size of the memory space at buf
+ *
+ * fdt_move() relocates, if possible, the device tree blob located at
+ * fdt to the buffer at buf of size bufsize.  The buffer may overlap
+ * with the existing device tree blob at fdt.  Therefore,
+ *     fdt_move(fdt, fdt, fdt_totalsize(fdt))
+ * should always succeed.
+ *
+ * returns:
+ *     0, on success
+ *     -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE, standard meanings
+ */
+int fdt_move(const void *fdt, void *buf, int bufsize);
 
-#define fdt_offset_ptr_typed(fdt, offset, var) \
-       ((typeof(var))(fdt_offset_ptr((fdt), (offset), sizeof(*(var)))))
+/**********************************************************************/
+/* Read-only functions                                                */
+/**********************************************************************/
 
-int fdt_move(const void *fdt, void *buf, int bufsize);
+/**
+ * fdt_string - retreive a string from the strings block of a device tree
+ * @fdt: pointer to the device tree blob
+ * @stroffset: offset of the string within the strings block (native endian)
+ *
+ * fdt_string() retrieves a pointer to a single string from the
+ * strings block of the device tree blob at fdt.
+ *
+ * returns:
+ *     a pointer to the string, on success
+ *     NULL, if stroffset is out of bounds
+ */
+const char *fdt_string(const void *fdt, int stroffset);
 
-/* Read-only functions */
-char *fdt_string(const void *fdt, int stroffset);
+/**
+ * fdt_num_mem_rsv - retreive the number of memory reserve map entries
+ * @fdt: pointer to the device tree blob
+ *
+ * Returns the number of entries in the device tree blob's memory
+ * reservation map.  This does not include the terminating 0,0 entry
+ * or any other (0,0) entries reserved for expansion.
+ *
+ * returns:
+ *     the number of entries
+ */
+int fdt_num_mem_rsv(const void *fdt);
 
+/**
+ * fdt_get_mem_rsv - retreive one memory reserve map entry
+ * @fdt: pointer to the device tree blob
+ * @address, @size: pointers to 64-bit variables
+ *
+ * On success, *address and *size will contain the address and size of
+ * the n-th reserve map entry from the device tree blob, in
+ * native-endian format.
+ *
+ * returns:
+ *     0, on success
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE, standard meanings
+ */
+int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
+
+/**
+ * fdt_subnode_offset_namelen - find a subnode based on substring
+ * @fdt: pointer to the device tree blob
+ * @parentoffset: structure block offset of a node
+ * @name: name of the subnode to locate
+ * @namelen: number of characters of name to consider
+ *
+ * Identical to fdt_subnode_offset(), but only examine the first
+ * namelen characters of name for matching the subnode name.  This is
+ * useful for finding subnodes based on a portion of a larger string,
+ * such as a full path.
+ */
 int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
                               const char *name, int namelen);
+/**
+ * fdt_subnode_offset - find a subnode of a given node
+ * @fdt: pointer to the device tree blob
+ * @parentoffset: structure block offset of a node
+ * @name: name of the subnode to locate
+ *
+ * fdt_subnode_offset() finds a subnode of the node at structure block
+ * offset parentoffset with the given name.  name may include a unit
+ * address, in which case fdt_subnode_offset() will find the subnode
+ * with that unit address, or the unit address may be omitted, in
+ * which case fdt_subnode_offset() will find an arbitrary subnode
+ * whose name excluding unit address matches the given name.
+ *
+ * returns:
+ *     structure block offset of the requested subnode (>=0), on success
+ *     -FDT_ERR_NOTFOUND, if the requested subnode does not exist
+ *     -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
+ *      -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_TRUNCATED, standard meanings.
+ */
 int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
 
-int fdt_find_node_by_path(const void *fdt, const char *path);
-int fdt_find_node_by_type(const void *fdt, int nodeoffset, const char *type);
+/**
+ * fdt_path_offset - find a tree node by its full path
+ * @fdt: pointer to the device tree blob
+ * @path: full path of the node to locate
+ *
+ * fdt_path_offset() finds a node of a given path in the device tree.
+ * Each path component may omit the unit address portion, but the
+ * results of this are undefined if any such path component is
+ * ambiguous (that is if there are multiple nodes at the relevant
+ * level matching the given component, differentiated only by unit
+ * address).
+ *
+ * returns:
+ *     structure block offset of the node with the requested path (>=0), on success
+ *     -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
+ *     -FDT_ERR_NOTFOUND, if the requested node does not exist
+ *      -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_TRUNCATED, standard meanings.
+ */
+int fdt_path_offset(const void *fdt, const char *path);
 
-int fdt_node_is_compatible(const void *fdt, int nodeoffset,
-                          const char *compat);
-int fdt_find_compatible_node(const void *fdt, int nodeoffset,
-                            const char *type, const char *compat);
+/**
+ * fdt_get_name - retreive the name of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: structure block offset of the starting node
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_get_name() retrieves the name (including unit address) of the
+ * device tree node at structure block offset nodeoffset.  If lenp is
+ * non-NULL, the length of this name is also returned, in the integer
+ * pointed to by lenp.
+ *
+ * returns:
+ *     pointer to the node's name, on success
+ *             If lenp is non-NULL, *lenp contains the length of that name (>=0)
+ *     NULL, on error
+ *             if lenp is non-NULL *lenp contains an error code (<0):
+ *             -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *             -FDT_ERR_BADMAGIC,
+ *             -FDT_ERR_BADVERSION,
+ *             -FDT_ERR_BADSTATE, standard meanings
+ */
+const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
 
-struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
-                                     const char *name, int *lenp);
-void *fdt_getprop(const void *fdt, int nodeoffset,
-                 const char *name, int *lenp);
+/**
+ * fdt_get_property - find a given property in a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to find
+ * @name: name of the property to find
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_get_property() retrieves a pointer to the fdt_property
+ * structure within the device tree blob corresponding to the property
+ * named 'name' of the node at offset nodeoffset.  If lenp is
+ * non-NULL, the length of the property value also returned, in the
+ * integer pointed to by lenp.
+ *
+ * returns:
+ *     pointer to the structure representing the property
+ *             if lenp is non-NULL, *lenp contains the length of the property
+ *             value (>=0)
+ *     NULL, on error
+ *             if lenp is non-NULL, *lenp contains an error code (<0):
+ *             -FDT_ERR_NOTFOUND, node does not have named property
+ *             -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *             -FDT_ERR_BADMAGIC,
+ *             -FDT_ERR_BADVERSION,
+ *             -FDT_ERR_BADSTATE,
+ *             -FDT_ERR_BADSTRUCTURE,
+ *             -FDT_ERR_TRUNCATED, standard meanings
+ */
+const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
+                                           const char *name, int *lenp);
+static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
+                                                     const char *name,
+                                                     int *lenp)
+{
+       return (struct fdt_property *)fdt_get_property(fdt, nodeoffset,
+                                                      name, lenp);
+}
 
-uint32_t fdt_next_tag(const void *fdt, int offset,
-                     int *nextoffset, char **namep);
-int fdt_num_reservemap(void *fdt, int *used, int *total);
-int fdt_get_reservemap(void *fdt, int n, struct fdt_reserve_entry *re);
+/**
+ * fdt_getprop - retrieve the value of a given property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to find
+ * @name: name of the property to find
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_getprop() retrieves a pointer to the value of the property
+ * named 'name' of the node at offset nodeoffset (this will be a
+ * pointer to within the device blob itself, not a copy of the value).
+ * If lenp is non-NULL, the length of the property value also
+ * returned, in the integer pointed to by lenp.
+ *
+ * returns:
+ *     pointer to the property's value
+ *             if lenp is non-NULL, *lenp contains the length of the property
+ *             value (>=0)
+ *     NULL, on error
+ *             if lenp is non-NULL, *lenp contains an error code (<0):
+ *             -FDT_ERR_NOTFOUND, node does not have named property
+ *             -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *             -FDT_ERR_BADMAGIC,
+ *             -FDT_ERR_BADVERSION,
+ *             -FDT_ERR_BADSTATE,
+ *             -FDT_ERR_BADSTRUCTURE,
+ *             -FDT_ERR_TRUNCATED, standard meanings
+ */
+const void *fdt_getprop(const void *fdt, int nodeoffset,
+                       const char *name, int *lenp);
+static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
+                                 const char *name, int *lenp)
+{
+       return (void *)fdt_getprop(fdt, nodeoffset, name, lenp);
+}
+
+/**
+ * fdt_get_phandle - retreive the phandle of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: structure block offset of the node
+ *
+ * fdt_get_phandle() retrieves the phandle of the device tree node at
+ * structure block offset nodeoffset.
+ *
+ * returns:
+ *     the phandle of the node at nodeoffset, on succes (!= 0, != -1)
+ *     0, if the node has no phandle, or another error occurs
+ */
+uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_get_path - determine the full path of a node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose path to find
+ * @buf: character buffer to contain the returned path (will be overwritten)
+ * @buflen: size of the character buffer at buf
+ *
+ * fdt_get_path() computes the full path of the node at offset
+ * nodeoffset, and records that path in the buffer at buf.
+ *
+ * NOTE: This function is expensive, as it must scan the device tree
+ * structure from the start to nodeoffset.
+ *
+ * returns:
+ *     0, on success
+ *             buf contains the absolute path of the node at
+ *             nodeoffset, as a NUL-terminated string.
+ *     -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ *     -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
+ *             characters and will not fit in the given buffer.
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
+
+/**
+ * fdt_supernode_atdepth_offset - find a specific ancestor of a node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose parent to find
+ * @supernodedepth: depth of the ancestor to find
+ * @nodedepth: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_supernode_atdepth_offset() finds an ancestor of the given node
+ * at a specific depth from the root (where the root itself has depth
+ * 0, its immediate subnodes depth 1 and so forth).  So
+ *     fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL);
+ * will always return 0, the offset of the root node.  If the node at
+ * nodeoffset has depth D, then:
+ *     fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL);
+ * will return nodeoffset itself.
+ *
+ * NOTE: This function is expensive, as it must scan the device tree
+ * structure from the start to nodeoffset.
+ *
+ * returns:
+
+ *     structure block offset of the node at node offset's ancestor
+ *             of depth supernodedepth (>=0), on success
+ *     -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+*      -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
+                                int supernodedepth, int *nodedepth);
+
+/**
+ * fdt_node_depth - find the depth of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose parent to find
+ *
+ * fdt_node_depth() finds the depth of a given node.  The root node
+ * has depth 0, its immediate subnodes depth 1 and so forth.
+ *
+ * NOTE: This function is expensive, as it must scan the device tree
+ * structure from the start to nodeoffset.
+ *
+ * returns:
+ *     depth of the node at nodeoffset (>=0), on success
+ *     -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_depth(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_parent_offset - find the parent of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose parent to find
+ *
+ * fdt_parent_offset() locates the parent node of a given node (that
+ * is, it finds the offset of the node which contains the node at
+ * nodeoffset as a subnode).
+ *
+ * NOTE: This function is expensive, as it must scan the device tree
+ * structure from the start to nodeoffset, *twice*.
+ *
+ * returns:
+ *     stucture block offset of the parent of the node at nodeoffset
+ *             (>=0), on success
+ *     -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_parent_offset(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_node_offset_by_prop_value - find nodes with a given property value
+ * @fdt: pointer to the device tree blob
+ * @startoffset: only find nodes after this offset
+ * @propname: property name to check
+ * @propval: property value to search for
+ * @proplen: length of the value in propval
+ *
+ * fdt_node_offset_by_prop_value() returns the offset of the first
+ * node after startoffset, which has a property named propname whose
+ * value is of length proplen and has value equal to propval; or if
+ * startoffset is -1, the very first such node in the tree.
+ *
+ * To iterate through all nodes matching the criterion, the following
+ * idiom can be used:
+ *     offset = fdt_node_offset_by_prop_value(fdt, -1, propname,
+ *                                            propval, proplen);
+ *     while (offset != -FDT_ERR_NOTFOUND) {
+ *             // other code here
+ *             offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
+ *                                                    propval, proplen);
+ *     }
+ *
+ * Note the -1 in the first call to the function, if 0 is used here
+ * instead, the function will never locate the root node, even if it
+ * matches the criterion.
+ *
+ * returns:
+ *     structure block offset of the located node (>= 0, >startoffset),
+ *              on success
+ *     -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
+ *             tree after startoffset
+ *     -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
+                                 const char *propname,
+                                 const void *propval, int proplen);
+
+/**
+ * fdt_node_offset_by_phandle - find the node with a given phandle
+ * @fdt: pointer to the device tree blob
+ * @phandle: phandle value
+ *
+ * fdt_node_offset_by_prop_value() returns the offset of the node
+ * which has the given phandle value.  If there is more than one node
+ * in the tree with the given phandle (an invalid tree), results are
+ * undefined.
+ *
+ * returns:
+ *     structure block offset of the located node (>= 0), on success
+ *     -FDT_ERR_NOTFOUND, no node with that phandle exists
+ *     -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1)
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
+
+/**
+ * fdt_node_check_compatible: check a node's compatible property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of a tree node
+ * @compatible: string to match against
+ *
+ *
+ * fdt_node_check_compatible() returns 0 if the given node contains a
+ * 'compatible' property with the given string as one of its elements,
+ * it returns non-zero otherwise, or on error.
+ *
+ * returns:
+ *     0, if the node has a 'compatible' property listing the given string
+ *     1, if the node has a 'compatible' property, but it does not list
+ *             the given string
+ *     -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
+ *     -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_check_compatible(const void *fdt, int nodeoffset,
+                             const char *compatible);
+
+/**
+ * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value
+ * @fdt: pointer to the device tree blob
+ * @startoffset: only find nodes after this offset
+ * @compatible: 'compatible' string to match against
+ *
+ * fdt_node_offset_by_compatible() returns the offset of the first
+ * node after startoffset, which has a 'compatible' property which
+ * lists the given compatible string; or if startoffset is -1, the
+ * very first such node in the tree.
+ *
+ * To iterate through all nodes matching the criterion, the following
+ * idiom can be used:
+ *     offset = fdt_node_offset_by_compatible(fdt, -1, compatible);
+ *     while (offset != -FDT_ERR_NOTFOUND) {
+ *             // other code here
+ *             offset = fdt_node_offset_by_compatible(fdt, offset, compatible);
+ *     }
+ *
+ * Note the -1 in the first call to the function, if 0 is used here
+ * instead, the function will never locate the root node, even if it
+ * matches the criterion.
+ *
+ * returns:
+ *     structure block offset of the located node (>= 0, >startoffset),
+ *              on success
+ *     -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
+ *             tree after startoffset
+ *     -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
+                                 const char *compatible);
+
+/**********************************************************************/
+/* Write-in-place functions                                           */
+/**********************************************************************/
 
-/* Write-in-place functions */
 int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
                        const void *val, int len);
-
-#define fdt_setprop_inplace_typed(fdt, nodeoffset, name, val) \
-       ({ \
-               typeof(val) x = val; \
-               fdt_setprop_inplace(fdt, nodeoffset, name, &x, sizeof(x)); \
-       })
+static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
+                                          const char *name, uint32_t val)
+{
+       val = cpu_to_fdt32(val);
+       return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
+}
 
 int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
 int fdt_nop_node(void *fdt, int nodeoffset);
-int fdt_insert_reservemap_entry(void *fdt, int n, uint64_t addr, uint64_t size);
 
+/**********************************************************************/
+/* Sequential write functions                                         */
+/**********************************************************************/
 
-/* Sequential-write functions */
 int fdt_create(void *buf, int bufsize);
 int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
 int fdt_finish_reservemap(void *fdt);
 int fdt_begin_node(void *fdt, const char *name);
 int fdt_property(void *fdt, const char *name, const void *val, int len);
-#define fdt_property_typed(fdt, name, val) \
-       ({ \
-               typeof(val) x = (val); \
-               fdt_property((fdt), (name), &x, sizeof(x)); \
-       })
+static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
+{
+       val = cpu_to_fdt32(val);
+       return fdt_property(fdt, name, &val, sizeof(val));
+}
 #define fdt_property_string(fdt, name, str) \
        fdt_property(fdt, name, str, strlen(str)+1)
 int fdt_end_node(void *fdt);
 int fdt_finish(void *fdt);
-int fdt_replace_reservemap_entry(void *fdt, int n, uint64_t addr, uint64_t size);
 
-/* Read-write functions */
-int fdt_open_into(void *fdt, void *buf, int bufsize);
+/**********************************************************************/
+/* Read-write functions                                               */
+/**********************************************************************/
+
+int fdt_open_into(const void *fdt, void *buf, int bufsize);
 int fdt_pack(void *fdt);
 
+int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
+int fdt_del_mem_rsv(void *fdt, int n);
+
 int fdt_setprop(void *fdt, int nodeoffset, const char *name,
                const void *val, int len);
-#define fdt_setprop_typed(fdt, nodeoffset, name, val) \
-       ({ \
-               typeof(val) x = (val); \
-               fdt_setprop((fdt), (nodeoffset), (name), &x, sizeof(x)); \
-       })
+static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
+                                  uint32_t val)
+{
+       val = cpu_to_fdt32(val);
+       return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
+}
 #define fdt_setprop_string(fdt, nodeoffset, name, str) \
        fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
-int fdt_find_and_setprop(void *fdt, const char *node, const char *prop,
-                        const void *val, int len, int create);
 int fdt_delprop(void *fdt, int nodeoffset, const char *name);
 int fdt_add_subnode_namelen(void *fdt, int parentoffset,
                            const char *name, int namelen);
 int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
 int fdt_del_node(void *fdt, int nodeoffset);
 
-/* Extra functions */
+/**********************************************************************/
+/* Debugging / informational functions                                */
+/**********************************************************************/
+
 const char *fdt_strerror(int errval);
 
 #endif /* _LIBFDT_H */
index 71716b04d403351884c798517e4b6d948c8e98fc..5518a0a89c217af215a1cc4f192280fb527f57ed 100644 (file)
 |
 |  Author:     Mark Wisner
 |
-|  Change Activity-
-|
-|  Date               Description of Change                                    BY
-|  ---------   ---------------------                                   ---
-|  04-May-99   Created                                                 MKW
-|  07-Jul-99   Added full duplex support                               MKW
-|  08-Sep-01   Tweaks                                                  gvb
-|
 +----------------------------------------------------------------------------*/
 #ifndef _miiphy_h_
 #define _miiphy_h_
 
 #include <net.h>
 
-int  miiphy_read(char *devname, unsigned char addr, unsigned char reg,
-               unsigned short *value);
-int  miiphy_write(char *devname, unsigned char addr, unsigned char reg,
-               unsigned short value);
-int  miiphy_info(char *devname, unsigned char addr, unsigned int  *oui,
-               unsigned char *model, unsigned char *rev);
-int  miiphy_reset(char *devname, unsigned char addr);
-int  miiphy_speed(char *devname, unsigned char addr);
-int  miiphy_duplex(char *devname, unsigned char addr);
+int miiphy_read (char *devname, unsigned char addr, unsigned char reg,
+                unsigned short *value);
+int miiphy_write (char *devname, unsigned char addr, unsigned char reg,
+                 unsigned short value);
+int miiphy_info (char *devname, unsigned char addr, unsigned int *oui,
+                unsigned char *model, unsigned char *rev);
+int miiphy_reset (char *devname, unsigned char addr);
+int miiphy_speed (char *devname, unsigned char addr);
+int miiphy_duplex (char *devname, unsigned char addr);
+int miiphy_is_1000base_x (char *devname, unsigned char addr);
 #ifdef CFG_FAULT_ECHO_LINK_DOWN
-int  miiphy_link(char *devname, unsigned char addr);
+int miiphy_link (char *devname, unsigned char addr);
 #endif
 
-void miiphy_init(void);
+void miiphy_init (void);
 
-void miiphy_register(char *devname,
-       int (* read)(char *devname, unsigned char addr,
-               unsigned char reg, unsigned short *value),
-       int (* write)(char *devname, unsigned char addr,
-               unsigned char reg, unsigned short value));
+void miiphy_register (char *devname,
+                     int (*read) (char *devname, unsigned char addr,
+                                  unsigned char reg, unsigned short *value),
+                     int (*write) (char *devname, unsigned char addr,
+                                   unsigned char reg, unsigned short value));
 
-int miiphy_set_current_dev(char *devname);
-char *miiphy_get_current_dev(void);
+int miiphy_set_current_dev (char *devname);
+char *miiphy_get_current_dev (void);
 
-void miiphy_listdev(void);
+void miiphy_listdev (void);
 
 #define BB_MII_DEVNAME "bbmii"
 
 int bb_miiphy_read (char *devname, unsigned char addr,
-               unsigned char reg, unsigned short *value);
+                   unsigned char reg, unsigned short *value);
 int bb_miiphy_write (char *devname, unsigned char addr,
-               unsigned char reg, unsigned short value);
+                    unsigned char reg, unsigned short value);
 
 /* phy seed setup */
 #define AUTO                   99
-#define _1000BASET              1000
+#define _1000BASET             1000
 #define _100BASET              100
 #define _10BASET               10
 #define HALF                   22
@@ -90,9 +83,10 @@ int bb_miiphy_write (char *devname, unsigned char addr,
 #define PHY_ANLPAR             0x05
 #define PHY_ANER               0x06
 #define PHY_ANNPTR             0x07
-#define PHY_ANLPNP              0x08
-#define PHY_1000BTCR            0x09
-#define PHY_1000BTSR            0x0A
+#define PHY_ANLPNP             0x08
+#define PHY_1000BTCR           0x09
+#define PHY_1000BTSR           0x0A
+#define PHY_EXSR               0x0F
 #define PHY_PHYSTS             0x10
 #define PHY_MIPSCR             0x11
 #define PHY_MIPGSR             0x12
@@ -115,10 +109,10 @@ int bb_miiphy_write (char *devname, unsigned char addr,
 #define PHY_BMCR_DPLX          0x0100
 #define PHY_BMCR_COL_TST       0x0080
 
-#define PHY_BMCR_SPEED_MASK     0x2040
-#define PHY_BMCR_1000_MBPS      0x0040
-#define PHY_BMCR_100_MBPS       0x2000
-#define PHY_BMCR_10_MBPS        0x0000
+#define PHY_BMCR_SPEED_MASK    0x2040
+#define PHY_BMCR_1000_MBPS     0x0040
+#define PHY_BMCR_100_MBPS      0x2000
+#define PHY_BMCR_10_MBPS       0x0000
 
 /* phy BMSR */
 #define PHY_BMSR_100T4         0x8000
@@ -126,6 +120,7 @@ int bb_miiphy_write (char *devname, unsigned char addr,
 #define PHY_BMSR_100TXH                0x2000
 #define PHY_BMSR_10TF          0x1000
 #define PHY_BMSR_10TH          0x0800
+#define PHY_BMSR_EXT_STAT      0x0100
 #define PHY_BMSR_PRE_SUP       0x0040
 #define PHY_BMSR_AUTN_COMP     0x0020
 #define PHY_BMSR_RF            0x0010
@@ -138,23 +133,42 @@ int bb_miiphy_write (char *devname, unsigned char addr,
 #define PHY_ANLPAR_NP          0x8000
 #define PHY_ANLPAR_ACK         0x4000
 #define PHY_ANLPAR_RF          0x2000
+#define PHY_ANLPAR_ASYMP       0x0800
+#define PHY_ANLPAR_PAUSE       0x0400
 #define PHY_ANLPAR_T4          0x0200
 #define PHY_ANLPAR_TXFD                0x0100
 #define PHY_ANLPAR_TX          0x0080
 #define PHY_ANLPAR_10FD                0x0040
 #define PHY_ANLPAR_10          0x0020
-#define PHY_ANLPAR_100         0x0380      /* we can run at 100 */
-
-#define PHY_ANLPAR_PSB_MASK     0x001f
-#define PHY_ANLPAR_PSB_802_3    0x0001
-#define PHY_ANLPAR_PSB_802_9    0x0002
-
-/* PHY_1000BTSR */
-#define PHY_1000BTSR_MSCF       0x8000
-#define PHY_1000BTSR_MSCR       0x4000
-#define PHY_1000BTSR_LRS        0x2000
-#define PHY_1000BTSR_RRS        0x1000
-#define PHY_1000BTSR_1000FD     0x0800
-#define PHY_1000BTSR_1000HD     0x0400
+#define PHY_ANLPAR_100         0x0380  /* we can run at 100 */
+/* phy ANLPAR 1000BASE-X */
+#define PHY_X_ANLPAR_NP                0x8000
+#define PHY_X_ANLPAR_ACK       0x4000
+#define PHY_X_ANLPAR_RF_MASK   0x3000
+#define PHY_X_ANLPAR_PAUSE_MASK        0x0180
+#define PHY_X_ANLPAR_HD                0x0040
+#define PHY_X_ANLPAR_FD                0x0020
+
+#define PHY_ANLPAR_PSB_MASK    0x001f
+#define PHY_ANLPAR_PSB_802_3   0x0001
+#define PHY_ANLPAR_PSB_802_9   0x0002
+
+/* phy 1000BTCR */
+#define PHY_1000BTCR_1000FD    0x0200
+#define PHY_1000BTCR_1000HD    0x0100
+
+/* phy 1000BTSR */
+#define PHY_1000BTSR_MSCF      0x8000
+#define PHY_1000BTSR_MSCR      0x4000
+#define PHY_1000BTSR_LRS       0x2000
+#define PHY_1000BTSR_RRS       0x1000
+#define PHY_1000BTSR_1000FD    0x0800
+#define PHY_1000BTSR_1000HD    0x0400
+
+/* phy EXSR */
+#define PHY_EXSR_1000XF                0x8000
+#define PHY_EXSR_1000XH                0x4000
+#define PHY_EXSR_1000TF                0x2000
+#define PHY_EXSR_1000TH                0x1000
 
 #endif
index 7e97f13476d8c8ec84426a5f7072a7bd5739f579..6f35aa06bf981b0594f9951eaf08b7ec7d1f6dd7 100644 (file)
 #include <net.h>
 
 #ifdef CONFIG_DRIVER_SMC91111
-#include "../drivers/smc91111.h"
+#include "../drivers/net/smc91111.h"
 #endif
 #ifdef CONFIG_DRIVER_LAN91C96
-#include "../drivers/lan91c96.h"
+#include "../drivers/net/lan91c96.h"
 #endif
 
 DECLARE_GLOBAL_DATA_PTR;
index 7c9990f8e0d2b583b1abbadb7bdbeb004645b70c..86a3b67c9899b2cba04c3979435f13e2d30cd5b9 100644 (file)
@@ -35,7 +35,7 @@
 #include <i2c.h>
 #include "blackfin_board.h"
 #include <asm/cplb.h>
-#include "../drivers/smc91111.h"
+#include "../drivers/net/smc91111.h"
 
 #if defined(CONFIG_BF537)&&defined(CONFIG_POST)
 #include <post.h>
index bf377529c20a802b02a0cf9db27e54bf1584d0f1..9713353ddf7008de55c811c2cb2ac30a9b8ca4d6 100644 (file)
@@ -25,11 +25,22 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)libgeneric.a
 
-COBJS  = bzlib.o bzlib_crctable.o bzlib_decompress.o \
-         bzlib_randtable.o bzlib_huffman.o \
-         crc32.o ctype.o display_options.o div64.o ldiv.o sha1.o \
-         string.o vsprintf.o zlib.o
-
+COBJS-y += bzlib.o
+COBJS-y += bzlib_crctable.o
+COBJS-y += bzlib_decompress.o
+COBJS-y += bzlib_randtable.o
+COBJS-y += bzlib_huffman.o
+COBJS-y += crc32.o
+COBJS-y += ctype.o
+COBJS-y += display_options.o
+COBJS-y += div64.o
+COBJS-y += ldiv.o
+COBJS-y += sha1.o
+COBJS-y += string.o
+COBJS-y += vsprintf.o
+COBJS-y += zlib.o
+
+COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS))
 
index bea97441b14570293dcdafbbe6fa0acbc65fa816..cc974c2d60d7dfb4f5f8aa28f47a54b01ff50e9e 100644 (file)
@@ -26,6 +26,7 @@
 #include <image.h>
 #include <zlib.h>
 #include <bzlib.h>
+#include <watchdog.h>
 #include <environment.h>
 #include <asm/byteorder.h>
 
@@ -36,6 +37,8 @@ DECLARE_GLOBAL_DATA_PTR;
 #define LINUX_MAX_ENVS         256
 #define LINUX_MAX_ARGS         256
 
+#define CHUNKSZ                        (64 * 1024)
+
 #ifdef CONFIG_SHOW_BOOT_PROGRESS
 # include <status_led.h>
 # define SHOW_BOOT_PROGRESS(arg)       show_boot_progress(arg)
index 91ccec04df76b04ed20816a212176a2857d8e040..c1a0acf46986e00e229be005c054f46fba497182 100644 (file)
@@ -62,6 +62,11 @@ static ulong mem_malloc_start;
 static ulong mem_malloc_end;
 static ulong mem_malloc_brk;
 
+/*
+ * mips_io_port_base is the begin of the address space to which x86 style
+ * I/O ports are mapped.
+ */
+unsigned long mips_io_port_base = -1;
 
 /*
  * The Malloc area is immediately below the monitor copy in DRAM
index dc411370f5fd550b709b065f71492d179ebcfb66..d166cce7968feb9ba45a01dd166176e4771fbb05 100644 (file)
@@ -27,9 +27,9 @@ LIB   = $(obj)libfdt.a
 
 SOBJS  =
 
-COBJS  = fdt.o  fdt_ro.o  fdt_rw.o  fdt_strerror.o  fdt_sw.o  fdt_wip.o
-
+COBJS-$(CONFIG_OF_LIBFDT) += fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o
 
+COBJS  := $(COBJS-y)
 SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
 
index 1ee67ad19cd8ba118bf5d1c85f4c5f2f1ac75b41..586a36136db215fbffb450cfa475403d6755c311 100644 (file)
@@ -2,23 +2,52 @@
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
  *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ *  b) Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *     1. Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *     2. Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-#include "config.h"
-#if CONFIG_OF_LIBFDT
-
 #include "libfdt_env.h"
 
 #include <fdt.h>
@@ -45,9 +74,9 @@ int fdt_check_header(const void *fdt)
        return 0;
 }
 
-void *fdt_offset_ptr(const void *fdt, int offset, int len)
+const void *fdt_offset_ptr(const void *fdt, int offset, int len)
 {
-       void *p;
+       const void *p;
 
        if (fdt_version(fdt) >= 0x11)
                if (((offset + len) < offset)
@@ -61,6 +90,45 @@ void *fdt_offset_ptr(const void *fdt, int offset, int len)
        return p;
 }
 
+uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset)
+{
+       const uint32_t *tagp, *lenp;
+       uint32_t tag;
+       const char *p;
+
+       if (offset % FDT_TAGSIZE)
+               return -1;
+
+       tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
+       if (! tagp)
+               return FDT_END; /* premature end */
+       tag = fdt32_to_cpu(*tagp);
+       offset += FDT_TAGSIZE;
+
+       switch (tag) {
+       case FDT_BEGIN_NODE:
+               /* skip name */
+               do {
+                       p = fdt_offset_ptr(fdt, offset++, 1);
+               } while (p && (*p != '\0'));
+               if (! p)
+                       return FDT_END;
+               break;
+       case FDT_PROP:
+               lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
+               if (! lenp)
+                       return FDT_END;
+               /* skip name offset, length and value */
+               offset += 2*FDT_TAGSIZE + fdt32_to_cpu(*lenp);
+               break;
+       }
+
+       if (nextoffset)
+               *nextoffset = ALIGN(offset, FDT_TAGSIZE);
+
+       return tag;
+}
+
 const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
 {
        int len = strlen(s) + 1;
@@ -86,5 +154,3 @@ int fdt_move(const void *fdt, void *buf, int bufsize)
        memmove(buf, fdt, fdt_totalsize(fdt));
        return 0;
 }
-
-#endif /* CONFIG_OF_LIBFDT */
index 46d525db1453ad29caad64890039008a373754af..12a37d59f96eba267235cf06962f7ccc7a6c2259 100644 (file)
@@ -2,23 +2,52 @@
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
  *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ *  b) Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *     1. Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *     2. Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-#include "config.h"
-#if CONFIG_OF_LIBFDT
-
 #include "libfdt_env.h"
 
 #include <fdt.h>
 
 #include "libfdt_internal.h"
 
-#define CHECK_HEADER(fdt)      { \
-       int err; \
-       if ((err = fdt_check_header(fdt)) != 0) \
-               return err; \
-}
+#define CHECK_HEADER(fdt) \
+       { \
+               int err; \
+               if ((err = fdt_check_header(fdt)) != 0) \
+                       return err; \
+       }
 
-static int offset_streq(const void *fdt, int offset,
-                       const char *s, int len)
+static int nodename_eq(const void *fdt, int offset,
+                      const char *s, int len)
 {
        const char *p = fdt_offset_ptr(fdt, offset, len+1);
 
@@ -44,169 +74,36 @@ static int offset_streq(const void *fdt, int offset,
        if (memcmp(p, s, len) != 0)
                return 0;
 
-       if (p[len] != '\0')
+       if (p[len] == '\0')
+               return 1;
+       else if (!memchr(s, '@', len) && (p[len] == '@'))
+               return 1;
+       else
                return 0;
-
-       return 1;
 }
 
-/*
- * Checks if the property name matches.
- */
-static int prop_name_eq(const void *fdt, int offset, const char *name,
-                       struct fdt_property **prop, int *lenp)
-{
-       int namestroff, len;
-
-       *prop = fdt_offset_ptr_typed(fdt, offset, *prop);
-       if (! *prop)
-               return -FDT_ERR_BADSTRUCTURE;
-
-       namestroff = fdt32_to_cpu((*prop)->nameoff);
-       if (streq(fdt_string(fdt, namestroff), name)) {
-               len = fdt32_to_cpu((*prop)->len);
-               *prop = fdt_offset_ptr(fdt, offset,
-                                      sizeof(**prop) + len);
-               if (*prop) {
-                       if (lenp)
-                               *lenp = len;
-                       return 1;
-               } else
-                       return -FDT_ERR_BADSTRUCTURE;
-       }
-       return 0;
-}
-
-/*
- * Return a pointer to the string at the given string offset.
- */
-char *fdt_string(const void *fdt, int stroffset)
+const char *fdt_string(const void *fdt, int stroffset)
 {
        return (char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
 }
 
-/*
- * Check if the specified node is compatible by comparing the tokens
- * in its "compatible" property with the specified string:
- *
- *   nodeoffset - starting place of the node
- *   compat     - the string to match to one of the tokens in the
- *                "compatible" list.
- */
-int fdt_node_is_compatible(const void *fdt, int nodeoffset,
-                          const char *compat)
+int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
 {
-       const char* cp;
-       int cplen, len;
-
-       cp = fdt_getprop(fdt, nodeoffset, "compatible", &cplen);
-       if (cp == NULL)
-               return 0;
-       while (cplen > 0) {
-               if (strncmp(cp, compat, strlen(compat)) == 0)
-                       return 1;
-               len = strlen(cp) + 1;
-               cp += len;
-               cplen -= len;
-       }
-
-       return 0;
-}
-
-/*
- * Find a node by its device type property. On success, the offset of that
- * node is returned or an error code otherwise:
- *
- *   nodeoffset - the node to start searching from or 0, the node you pass
- *                will not be searched, only the next one will; typically,
- *                you pass 0 to start the search and then what the previous
- *                call returned.
- *   type       - the device type string to match against.
- */
-int fdt_find_node_by_type(const void *fdt, int nodeoffset, const char *type)
-{
-       int offset, nextoffset;
-       struct fdt_property *prop;
-       uint32_t tag;
-       int len, ret;
-
        CHECK_HEADER(fdt);
-
-       tag = fdt_next_tag(fdt, nodeoffset, &nextoffset, NULL);
-       if (tag != FDT_BEGIN_NODE)
-               return -FDT_ERR_BADOFFSET;
-       if (nodeoffset)
-               nodeoffset = 0; /* start searching with next node */
-
-       while (1) {
-               offset = nextoffset;
-               tag = fdt_next_tag(fdt, offset, &nextoffset, NULL);
-
-               switch (tag) {
-               case FDT_BEGIN_NODE:
-                       nodeoffset = offset;
-                       break;
-
-               case FDT_PROP:
-                       if (nodeoffset == 0)
-                               break;
-                       ret = prop_name_eq(fdt, offset, "device_type",
-                                          &prop, &len);
-                       if (ret < 0)
-                               return ret;
-                       else if (ret > 0 &&
-                                strncmp(prop->data, type, len - 1) == 0)
-                           return nodeoffset;
-                       break;
-
-               case FDT_END_NODE:
-               case FDT_NOP:
-                       break;
-
-               case FDT_END:
-                       return -FDT_ERR_NOTFOUND;
-
-               default:
-                       return -FDT_ERR_BADSTRUCTURE;
-               }
-       }
+       *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
+       *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
+       return 0;
 }
 
-/*
- * Find a node based on its device type and one of the tokens in its its
- * "compatible" property. On success, the offset of that node is returned
- * or an error code otherwise:
- *
- *   nodeoffset - the node to start searching from or 0, the node you pass
- *                will not be searched, only the next one will; typically,
- *                you pass 0 to start the search and then what the previous
- *                call returned.
- *   type       - the device type string to match against.
- *   compat     - the string to match to one of the tokens in the
- *                "compatible" list.
- */
-int fdt_find_compatible_node(const void *fdt, int nodeoffset,
-                            const char *type, const char *compat)
+int fdt_num_mem_rsv(const void *fdt)
 {
-       int offset;
+       int i = 0;
 
-       offset = fdt_find_node_by_type(fdt, nodeoffset, type);
-       if (offset < 0 || fdt_node_is_compatible(fdt, offset, compat))
-               return offset;
-
-       return -FDT_ERR_NOTFOUND;
+       while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
+               i++;
+       return i;
 }
 
-/*
- * Return the node offset of the node specified by:
- *   parentoffset - starting place (0 to start at the root)
- *   name         - name being searched for
- *   namelen      - length of the name: typically strlen(name)
- *
- * Notes:
- *   If the start node has subnodes, the subnodes are _not_ searched for the
- *     requested name.
- */
 int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
                               const char *name, int namelen)
 {
@@ -216,13 +113,13 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
 
        CHECK_HEADER(fdt);
 
-       tag = fdt_next_tag(fdt, parentoffset, &nextoffset, NULL);
+       tag = fdt_next_tag(fdt, parentoffset, &nextoffset);
        if (tag != FDT_BEGIN_NODE)
                return -FDT_ERR_BADOFFSET;
 
        do {
                offset = nextoffset;
-               tag = fdt_next_tag(fdt, offset, &nextoffset, NULL);
+               tag = fdt_next_tag(fdt, offset, &nextoffset);
 
                switch (tag) {
                case FDT_END:
@@ -230,15 +127,10 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
 
                case FDT_BEGIN_NODE:
                        level++;
-                       /*
-                        * If we are nested down levels, ignore the strings
-                        * until we get back to the proper level.
-                        */
                        if (level != 1)
                                continue;
-
-                       /* Return the offset if this is "our" string. */
-                       if (offset_streq(fdt, offset+FDT_TAGSIZE, name, namelen))
+                       if (nodename_eq(fdt, offset+FDT_TAGSIZE, name, namelen))
+                               /* Found it! */
                                return offset;
                        break;
 
@@ -258,20 +150,13 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
        return -FDT_ERR_NOTFOUND;
 }
 
-/*
- * See fdt_subnode_offset_namelen()
- */
 int fdt_subnode_offset(const void *fdt, int parentoffset,
                       const char *name)
 {
        return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));
 }
 
-/*
- * Searches for the node corresponding to the given path and returns the
- * offset of that node.
- */
-int fdt_find_node_by_path(const void *fdt, const char *path)
+int fdt_path_offset(const void *fdt, const char *path)
 {
        const char *end = path + strlen(path);
        const char *p = path;
@@ -279,37 +164,21 @@ int fdt_find_node_by_path(const void *fdt, const char *path)
 
        CHECK_HEADER(fdt);
 
-       /* Paths must be absolute */
        if (*path != '/')
                return -FDT_ERR_BADPATH;
 
-       /* Handle the root path: root offset is 0 */
-       if (strcmp(path, "/") == 0)
-               return 0;
-
        while (*p) {
                const char *q;
 
-               /* Skip path separator(s) */
                while (*p == '/')
                        p++;
                if (! *p)
-                       return -FDT_ERR_BADPATH;
-
-               /*
-                * Find the next path separator.  The characters between
-                * p and q are the next segment of the the path to find.
-                */
+                       return offset;
                q = strchr(p, '/');
                if (! q)
                        q = end;
 
-               /*
-                * Find the offset corresponding to the this path segment.
-                */
                offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);
-
-               /* Oops, error, abort abort abort */
                if (offset < 0)
                        return offset;
 
@@ -319,17 +188,37 @@ int fdt_find_node_by_path(const void *fdt, const char *path)
        return offset;
 }
 
-/*
- * Given the offset of a node and a name of a property in that node, return
- * a pointer to the property struct.
- */
-struct fdt_property *fdt_get_property(const void *fdt,
-                                     int nodeoffset,
-                                     const char *name, int *lenp)
+const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
+{
+       const struct fdt_node_header *nh;
+       int err;
+
+       if ((err = fdt_check_header(fdt)) != 0)
+               goto fail;
+
+       err = -FDT_ERR_BADOFFSET;
+       nh = fdt_offset_ptr(fdt, nodeoffset, sizeof(*nh));
+       if (!nh || (fdt32_to_cpu(nh->tag) != FDT_BEGIN_NODE))
+               goto fail;
+
+       if (len)
+               *len = strlen(nh->name);
+
+       return nh->name;
+
+ fail:
+       if (len)
+               *len = err;
+       return NULL;
+}
+
+const struct fdt_property *fdt_get_property(const void *fdt,
+                                           int nodeoffset,
+                                           const char *name, int *lenp)
 {
-       int level = 0;
        uint32_t tag;
-       struct fdt_property *prop;
+       const struct fdt_property *prop;
+       int namestroff;
        int offset, nextoffset;
        int err;
 
@@ -340,63 +229,59 @@ struct fdt_property *fdt_get_property(const void *fdt,
        if (nodeoffset % FDT_TAGSIZE)
                goto fail;
 
-       tag = fdt_next_tag(fdt, nodeoffset, &nextoffset, NULL);
+       tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
        if (tag != FDT_BEGIN_NODE)
                goto fail;
 
        do {
                offset = nextoffset;
 
-               tag = fdt_next_tag(fdt, offset, &nextoffset, NULL);
+               tag = fdt_next_tag(fdt, offset, &nextoffset);
                switch (tag) {
                case FDT_END:
                        err = -FDT_ERR_TRUNCATED;
                        goto fail;
 
                case FDT_BEGIN_NODE:
-                       level++;
-                       break;
-
                case FDT_END_NODE:
-                       level--;
+               case FDT_NOP:
                        break;
 
                case FDT_PROP:
-                       /*
-                        * If we are nested down levels, ignore the strings
-                        * until we get back to the proper level.
-                        */
-                       if (level != 0)
-                               continue;
-
-                       err = prop_name_eq(fdt, offset, name, &prop, lenp);
-                       if (err > 0)
-                               return prop;
-                       else if (err < 0)
+                       err = -FDT_ERR_BADSTRUCTURE;
+                       prop = fdt_offset_ptr(fdt, offset, sizeof(*prop));
+                       if (! prop)
                                goto fail;
-                       break;
+                       namestroff = fdt32_to_cpu(prop->nameoff);
+                       if (streq(fdt_string(fdt, namestroff), name)) {
+                               /* Found it! */
+                               int len = fdt32_to_cpu(prop->len);
+                               prop = fdt_offset_ptr(fdt, offset,
+                                                     sizeof(*prop)+len);
+                               if (! prop)
+                                       goto fail;
+
+                               if (lenp)
+                                       *lenp = len;
 
-               case FDT_NOP:
+                               return prop;
+                       }
                        break;
 
                default:
                        err = -FDT_ERR_BADSTRUCTURE;
                        goto fail;
                }
-       } while (level >= 0);
+       } while ((tag != FDT_BEGIN_NODE) && (tag != FDT_END_NODE));
 
        err = -FDT_ERR_NOTFOUND;
-fail:
+ fail:
        if (lenp)
                *lenp = err;
        return NULL;
 }
 
-/*
- * Given the offset of a node and a name of a property in that node, return
- * a pointer to the property data (ONLY).
- */
-void *fdt_getprop(const void *fdt, int nodeoffset,
+const void *fdt_getprop(const void *fdt, int nodeoffset,
                  const char *name, int *lenp)
 {
        const struct fdt_property *prop;
@@ -405,132 +290,294 @@ void *fdt_getprop(const void *fdt, int nodeoffset,
        if (! prop)
                return NULL;
 
-       return (void *)prop->data;
+       return prop->data;
 }
 
+uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
+{
+       const uint32_t *php;
+       int len;
+
+       php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
+       if (!php || (len != sizeof(*php)))
+               return 0;
+
+       return fdt32_to_cpu(*php);
+}
 
-uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset, char **namep)
+int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
 {
-       const uint32_t *tagp, *lenp;
        uint32_t tag;
-       const char *p;
-
-       if (offset % FDT_TAGSIZE)
-               return -1;
-
-       tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
-       if (! tagp)
-               return FDT_END; /* premature end */
-       tag = fdt32_to_cpu(*tagp);
-       offset += FDT_TAGSIZE;
-
-       switch (tag) {
-       case FDT_BEGIN_NODE:
-               if(namep)
-                       *namep = fdt_offset_ptr(fdt, offset, 1);
-
-               /* skip name */
-               do {
-                       p = fdt_offset_ptr(fdt, offset++, 1);
-               } while (p && (*p != '\0'));
-               if (! p)
-                       return FDT_END;
-               break;
-       case FDT_PROP:
-               lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
-               if (! lenp)
-                       return FDT_END;
-               /*
-                * Get the property and set the namep to the name.
-                */
-               if(namep) {
-                       struct fdt_property *prop;
-
-                       prop = fdt_offset_ptr_typed(fdt, offset - FDT_TAGSIZE, prop);
-                       if (! prop)
-                               return -FDT_ERR_BADSTRUCTURE;
-                       *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+       int p = 0, overflow = 0;
+       int offset, nextoffset, namelen;
+       const char *name;
+
+       CHECK_HEADER(fdt);
+
+       tag = fdt_next_tag(fdt, 0, &nextoffset);
+       if (tag != FDT_BEGIN_NODE)
+               return -FDT_ERR_BADSTRUCTURE;
+
+       if (buflen < 2)
+               return -FDT_ERR_NOSPACE;
+       buf[0] = '/';
+       p = 1;
+
+       while (nextoffset <= nodeoffset) {
+               offset = nextoffset;
+               tag = fdt_next_tag(fdt, offset, &nextoffset);
+               switch (tag) {
+               case FDT_END:
+                       return -FDT_ERR_BADOFFSET;
+
+               case FDT_BEGIN_NODE:
+                       name = fdt_get_name(fdt, offset, &namelen);
+                       if (!name)
+                               return namelen;
+                       if (overflow || ((p + namelen + 1) > buflen)) {
+                               overflow++;
+                               break;
+                       }
+                       memcpy(buf + p, name, namelen);
+                       p += namelen;
+                       buf[p++] = '/';
+                       break;
+
+               case FDT_END_NODE:
+                       if (overflow) {
+                               overflow--;
+                               break;
+                       }
+                       do {
+                               p--;
+                       } while  (buf[p-1] != '/');
+                       break;
+
+               case FDT_PROP:
+               case FDT_NOP:
+                       break;
+
+               default:
+                       return -FDT_ERR_BADSTRUCTURE;
                }
-               /* skip name offset, length and value */
-               offset += 2*FDT_TAGSIZE + fdt32_to_cpu(*lenp);
-               break;
        }
 
-       if (nextoffset)
-               *nextoffset = ALIGN(offset, FDT_TAGSIZE);
+       if (overflow)
+               return -FDT_ERR_NOSPACE;
 
-       return tag;
+       if (p > 1) /* special case so that root path is "/", not "" */
+               p--;
+       buf[p] = '\0';
+       return p;
 }
 
-/*
- * Return the number of used reserve map entries and total slots available.
- */
-int fdt_num_reservemap(void *fdt, int *used, int *total)
+int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
+                                int supernodedepth, int *nodedepth)
 {
-       struct fdt_reserve_entry *re;
-       int  start;
-       int  end;
-       int  err = fdt_check_header(fdt);
-
-       if (err != 0)
-               return err;
-
-       start = fdt_off_mem_rsvmap(fdt);
-
-       /*
-        * Convention is that the reserve map is before the dt_struct,
-        * but it does not have to be.
-        */
-       end = fdt_totalsize(fdt);
-       if (end > fdt_off_dt_struct(fdt))
-               end = fdt_off_dt_struct(fdt);
-       if (end > fdt_off_dt_strings(fdt))
-               end = fdt_off_dt_strings(fdt);
-
-       /*
-        * Since the reserved area list is zero terminated, you get one fewer.
-        */
-       if (total)
-               *total = ((end - start) / sizeof(struct fdt_reserve_entry)) - 1;
-
-       if (used) {
-               *used = 0;
-               while (start < end) {
-                       re = (struct fdt_reserve_entry *)(fdt + start);
-                       if (re->size == 0)
-                               return 0;       /* zero size terminates the list */
-
-                       *used += 1;
-                       start += sizeof(struct fdt_reserve_entry);
+       int level = -1;
+       uint32_t tag;
+       int offset, nextoffset = 0;
+       int supernodeoffset = -FDT_ERR_INTERNAL;
+
+       CHECK_HEADER(fdt);
+
+       if (supernodedepth < 0)
+               return -FDT_ERR_NOTFOUND;
+
+       do {
+               offset = nextoffset;
+               tag = fdt_next_tag(fdt, offset, &nextoffset);
+               switch (tag) {
+               case FDT_END:
+                       return -FDT_ERR_BADOFFSET;
+
+               case FDT_BEGIN_NODE:
+                       level++;
+                       if (level == supernodedepth)
+                               supernodeoffset = offset;
+                       break;
+
+               case FDT_END_NODE:
+                       level--;
+                       break;
+
+               case FDT_PROP:
+               case FDT_NOP:
+                       break;
+
+               default:
+                       return -FDT_ERR_BADSTRUCTURE;
                }
-               /*
-                * If we get here, there was no zero size termination.
-                */
-               return -FDT_ERR_BADLAYOUT;
+       } while (offset < nodeoffset);
+
+       if (nodedepth)
+               *nodedepth = level;
+
+       if (supernodedepth > level)
+               return -FDT_ERR_NOTFOUND;
+       return supernodeoffset;
+}
+
+int fdt_node_depth(const void *fdt, int nodeoffset)
+{
+       int nodedepth;
+       int err;
+
+       err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
+       if (err)
+               return (err < 0) ? err : -FDT_ERR_INTERNAL;
+       return nodedepth;
+}
+
+int fdt_parent_offset(const void *fdt, int nodeoffset)
+{
+       int nodedepth = fdt_node_depth(fdt, nodeoffset);
+
+       if (nodedepth < 0)
+               return nodedepth;
+       return fdt_supernode_atdepth_offset(fdt, nodeoffset,
+                                           nodedepth - 1, NULL);
+}
+
+int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
+                                 const char *propname,
+                                 const void *propval, int proplen)
+{
+       uint32_t tag;
+       int offset, nextoffset;
+       const void *val;
+       int len;
+
+       CHECK_HEADER(fdt);
+
+       if (startoffset >= 0) {
+               tag = fdt_next_tag(fdt, startoffset, &nextoffset);
+               if (tag != FDT_BEGIN_NODE)
+                       return -FDT_ERR_BADOFFSET;
+       } else {
+               nextoffset = 0;
        }
-       return 0;
+
+       /* FIXME: The algorithm here is pretty horrible: we scan each
+        * property of a node in fdt_getprop(), then if that didn't
+        * find what we want, we scan over them again making our way
+        * to the next node.  Still it's the easiest to implement
+        * approach; performance can come later. */
+       do {
+               offset = nextoffset;
+               tag = fdt_next_tag(fdt, offset, &nextoffset);
+
+               switch (tag) {
+               case FDT_BEGIN_NODE:
+                       val = fdt_getprop(fdt, offset, propname, &len);
+                       if (val
+                           && (len == proplen)
+                           && (memcmp(val, propval, len) == 0))
+                               return offset;
+                       break;
+
+               case FDT_PROP:
+               case FDT_END:
+               case FDT_END_NODE:
+               case FDT_NOP:
+                       break;
+
+               default:
+                       return -FDT_ERR_BADSTRUCTURE;
+               }
+       } while (tag != FDT_END);
+
+       return -FDT_ERR_NOTFOUND;
 }
 
-/*
- * Return the nth reserve map entry.
- */
-int fdt_get_reservemap(void *fdt, int n, struct fdt_reserve_entry *re)
+int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
 {
-       int  used;
-       int  total;
-       int  err;
+       if ((phandle == 0) || (phandle == -1))
+               return -FDT_ERR_BADPHANDLE;
+       phandle = cpu_to_fdt32(phandle);
+       return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle",
+                                            &phandle, sizeof(phandle));
+}
 
-       err = fdt_num_reservemap(fdt, &used, &total);
-       if (err != 0)
-               return err;
+int _stringlist_contains(const void *strlist, int listlen, const char *str)
+{
+       int len = strlen(str);
+       const void *p;
 
-       if (n >= total)
-               return -FDT_ERR_NOSPACE;
-       if (re) {
-               *re = *(struct fdt_reserve_entry *)
-                       _fdt_offset_ptr(fdt, n * sizeof(struct fdt_reserve_entry));
+       while (listlen >= len) {
+               if (memcmp(str, strlist, len+1) == 0)
+                       return 1;
+               p = memchr(strlist, '\0', listlen);
+               if (!p)
+                       return 0; /* malformed strlist.. */
+               listlen -= (p-strlist) + 1;
+               strlist = p + 1;
        }
        return 0;
 }
 
-#endif /* CONFIG_OF_LIBFDT */
+int fdt_node_check_compatible(const void *fdt, int nodeoffset,
+                             const char *compatible)
+{
+       const void *prop;
+       int len;
+
+       prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
+       if (!prop)
+               return len;
+       if (_stringlist_contains(prop, len, compatible))
+               return 0;
+       else
+               return 1;
+}
+
+int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
+                                 const char *compatible)
+{
+       uint32_t tag;
+       int offset, nextoffset;
+       int err;
+
+       CHECK_HEADER(fdt);
+
+       if (startoffset >= 0) {
+               tag = fdt_next_tag(fdt, startoffset, &nextoffset);
+               if (tag != FDT_BEGIN_NODE)
+                       return -FDT_ERR_BADOFFSET;
+       } else {
+               nextoffset = 0;
+       }
+
+       /* FIXME: The algorithm here is pretty horrible: we scan each
+        * property of a node in fdt_node_check_compatible(), then if
+        * that didn't find what we want, we scan over them again
+        * making our way to the next node.  Still it's the easiest to
+        * implement approach; performance can come later. */
+       do {
+               offset = nextoffset;
+               tag = fdt_next_tag(fdt, offset, &nextoffset);
+
+               switch (tag) {
+               case FDT_BEGIN_NODE:
+                       err = fdt_node_check_compatible(fdt, offset,
+                                                       compatible);
+                       if ((err < 0)
+                           && (err != -FDT_ERR_NOTFOUND))
+                               return err;
+                       else if (err == 0)
+                               return offset;
+                       break;
+
+               case FDT_PROP:
+               case FDT_END:
+               case FDT_END_NODE:
+               case FDT_NOP:
+                       break;
+
+               default:
+                       return -FDT_ERR_BADSTRUCTURE;
+               }
+       } while (tag != FDT_END);
+
+       return -FDT_ERR_NOTFOUND;
+}
index 55fcc41d1a2abd2852878b9d9760d17a57998799..dfe5628a33a011b37dd43c3c849c52b0110f01d5 100644 (file)
@@ -2,23 +2,52 @@
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
  *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ *  b) Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *     1. Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *     2. Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-#include "config.h"
-#if CONFIG_OF_LIBFDT
-
 #include "libfdt_env.h"
 
 #include <fdt.h>
 
 #include "libfdt_internal.h"
 
+static int _blocks_misordered(const void *fdt,
+                             int mem_rsv_size, int struct_size)
+{
+       return (fdt_off_mem_rsvmap(fdt) < ALIGN(sizeof(struct fdt_header), 8))
+               || (fdt_off_dt_struct(fdt) <
+                   (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
+               || (fdt_off_dt_strings(fdt) <
+                   (fdt_off_dt_struct(fdt) + struct_size))
+               || (fdt_totalsize(fdt) <
+                   (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
+}
+
 static int rw_check_header(void *fdt)
 {
        int err;
 
        if ((err = fdt_check_header(fdt)))
                return err;
-       if (fdt_version(fdt) < 0x11)
+       if (fdt_version(fdt) < 17)
                return -FDT_ERR_BADVERSION;
-       if (fdt_off_mem_rsvmap(fdt) < ALIGN(sizeof(struct fdt_header), 8))
-               return -FDT_ERR_BADLAYOUT;
-       if (fdt_off_dt_struct(fdt) <
-           (fdt_off_mem_rsvmap(fdt) + sizeof(struct fdt_reserve_entry)))
-               return -FDT_ERR_BADLAYOUT;
-       if (fdt_off_dt_strings(fdt) <
-           (fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt)))
-               return -FDT_ERR_BADLAYOUT;
-       if (fdt_totalsize(fdt) <
-           (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)))
+       if (_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
+                              fdt_size_dt_struct(fdt)))
                return -FDT_ERR_BADLAYOUT;
+       if (fdt_version(fdt) > 17)
+               fdt_set_version(fdt, 17);
+
        return 0;
 }
 
@@ -72,6 +108,19 @@ static int _blob_splice(void *fdt, void *p, int oldlen, int newlen)
        return 0;
 }
 
+static int _blob_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
+                               int oldn, int newn)
+{
+       int delta = (newn - oldn) * sizeof(*p);
+       int err;
+       err = _blob_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
+       if (err)
+               return err;
+       fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
+       fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
+       return 0;
+}
+
 static int _blob_splice_struct(void *fdt, void *p,
                               int oldlen, int newlen)
 {
@@ -81,8 +130,8 @@ static int _blob_splice_struct(void *fdt, void *p,
        if ((err = _blob_splice(fdt, p, oldlen, newlen)))
                return err;
 
-       fdt_set_header(fdt, size_dt_struct, fdt_size_dt_struct(fdt) + delta);
-       fdt_set_header(fdt, off_dt_strings, fdt_off_dt_strings(fdt) + delta);
+       fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
+       fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
        return 0;
 }
 
@@ -94,7 +143,7 @@ static int _blob_splice_string(void *fdt, int newlen)
        if ((err = _blob_splice(fdt, p, 0, newlen)))
                return err;
 
-       fdt_set_header(fdt, size_dt_strings, fdt_size_dt_strings(fdt) + newlen);
+       fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
        return 0;
 }
 
@@ -120,13 +169,47 @@ static int _find_add_string(void *fdt, const char *s)
        return (new - strtab);
 }
 
+int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
+{
+       struct fdt_reserve_entry *re;
+       int err;
+
+       if ((err = rw_check_header(fdt)))
+               return err;
+
+       re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
+       err = _blob_splice_mem_rsv(fdt, re, 0, 1);
+       if (err)
+               return err;
+
+       re->address = cpu_to_fdt64(address);
+       re->size = cpu_to_fdt64(size);
+       return 0;
+}
+
+int fdt_del_mem_rsv(void *fdt, int n)
+{
+       struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
+       int err;
+
+       if ((err = rw_check_header(fdt)))
+               return err;
+       if (n >= fdt_num_mem_rsv(fdt))
+               return -FDT_ERR_NOTFOUND;
+
+       err = _blob_splice_mem_rsv(fdt, re, 1, 0);
+       if (err)
+               return err;
+       return 0;
+}
+
 static int _resize_property(void *fdt, int nodeoffset, const char *name, int len,
                            struct fdt_property **prop)
 {
        int oldlen;
        int err;
 
-       *prop = fdt_get_property(fdt, nodeoffset, name, &oldlen);
+       *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
        if (! (*prop))
                return oldlen;
 
@@ -148,7 +231,7 @@ static int _add_property(void *fdt, int nodeoffset, const char *name, int len,
        int namestroff;
        int err;
 
-       tag = fdt_next_tag(fdt, nodeoffset, &nextoffset, NULL);
+       tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
        if (tag != FDT_BEGIN_NODE)
                return -FDT_ERR_BADOFFSET;
 
@@ -156,7 +239,7 @@ static int _add_property(void *fdt, int nodeoffset, const char *name, int len,
        if (namestroff < 0)
                return namestroff;
 
-       *prop = _fdt_offset_ptr(fdt, nextoffset);
+       *prop = _fdt_offset_ptr_w(fdt, nextoffset);
        proplen = sizeof(**prop) + ALIGN(len, FDT_TAGSIZE);
 
        err = _blob_splice_struct(fdt, *prop, 0, proplen);
@@ -188,32 +271,6 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
        return 0;
 }
 
-/**
- * fdt_find_and_setprop: Find a node and set it's property
- *
- * @fdt: ptr to device tree
- * @node: path of node
- * @prop: property name
- * @val: ptr to new value
- * @len: length of new property value
- * @create: flag to create the property if it doesn't exist
- *
- * Convenience function to directly set a property given the path to the node.
- */
-int fdt_find_and_setprop(void *fdt, const char *node, const char *prop,
-                        const void *val, int len, int create)
-{
-       int nodeoff = fdt_find_node_by_path(fdt, node);
-
-       if (nodeoff < 0)
-               return nodeoff;
-
-       if ((!create) && (fdt_get_property(fdt, nodeoff, prop, 0) == NULL))
-               return 0; /* create flag not set; so exit quietly */
-
-       return fdt_setprop(fdt, nodeoff, prop, val, len);
-}
-
 int fdt_delprop(void *fdt, int nodeoffset, const char *name)
 {
        struct fdt_property *prop;
@@ -221,7 +278,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name)
 
        RW_CHECK_HEADER(fdt);
 
-       prop = fdt_get_property(fdt, nodeoffset, name, &len);
+       prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
        if (! prop)
                return len;
 
@@ -248,13 +305,13 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
                return offset;
 
        /* Try to place the new node after the parent's properties */
-       fdt_next_tag(fdt, parentoffset, &nextoffset, NULL); /* skip the BEGIN_NODE */
+       fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
        do {
                offset = nextoffset;
-               tag = fdt_next_tag(fdt, offset, &nextoffset, NULL);
+               tag = fdt_next_tag(fdt, offset, &nextoffset);
        } while (tag == FDT_PROP);
 
-       nh = _fdt_offset_ptr(fdt, offset);
+       nh = _fdt_offset_ptr_w(fdt, offset);
        nodelen = sizeof(*nh) + ALIGN(namelen+1, FDT_TAGSIZE) + FDT_TAGSIZE;
 
        err = _blob_splice_struct(fdt, nh, 0, nodelen);
@@ -279,46 +336,112 @@ int fdt_del_node(void *fdt, int nodeoffset)
 {
        int endoffset;
 
+       RW_CHECK_HEADER(fdt);
+
        endoffset = _fdt_node_end_offset(fdt, nodeoffset);
        if (endoffset < 0)
                return endoffset;
 
-       return _blob_splice_struct(fdt, _fdt_offset_ptr(fdt, nodeoffset),
+       return _blob_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
                                   endoffset - nodeoffset, 0);
 }
 
-int fdt_open_into(void *fdt, void *buf, int bufsize)
+static void _packblocks(const void *fdt, void *buf,
+                      int mem_rsv_size, int struct_size)
+{
+       int mem_rsv_off, struct_off, strings_off;
+
+       mem_rsv_off = ALIGN(sizeof(struct fdt_header), 8);
+       struct_off = mem_rsv_off + mem_rsv_size;
+       strings_off = struct_off + struct_size;
+
+       memmove(buf + mem_rsv_off, fdt + fdt_off_mem_rsvmap(fdt), mem_rsv_size);
+       fdt_set_off_mem_rsvmap(buf, mem_rsv_off);
+
+       memcpy(buf + struct_off, fdt + fdt_off_dt_struct(fdt), struct_size);
+       fdt_set_off_dt_struct(buf, struct_off);
+       fdt_set_size_dt_struct(buf, struct_size);
+
+       memcpy(buf + strings_off, fdt + fdt_off_dt_strings(fdt),
+              fdt_size_dt_strings(fdt));
+       fdt_set_off_dt_strings(buf, strings_off);
+       fdt_set_size_dt_strings(buf, fdt_size_dt_strings(fdt));
+}
+
+int fdt_open_into(const void *fdt, void *buf, int bufsize)
 {
        int err;
+       int mem_rsv_size, struct_size;
+       int newsize;
+       void *tmp;
 
-       err = fdt_move(fdt, buf, bufsize);
+       err = fdt_check_header(fdt);
        if (err)
                return err;
 
-       fdt = buf;
+       mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
+               * sizeof(struct fdt_reserve_entry);
 
-       fdt_set_header(fdt, totalsize, bufsize);
+       if (fdt_version(fdt) >= 17) {
+               struct_size = fdt_size_dt_struct(fdt);
+       } else {
+               struct_size = 0;
+               while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
+                       ;
+       }
 
-       /* FIXME: re-order if necessary */
+       if (!_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
+               /* no further work necessary */
+               err = fdt_move(fdt, buf, bufsize);
+               if (err)
+                       return err;
+               fdt_set_version(buf, 17);
+               fdt_set_size_dt_struct(buf, struct_size);
+               fdt_set_totalsize(buf, bufsize);
+               return 0;
+       }
 
-       err = rw_check_header(fdt);
-       if (err)
-               return err;
+       /* Need to reorder */
+       newsize = ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
+               + struct_size + fdt_size_dt_strings(fdt);
+
+       if (bufsize < newsize)
+               return -FDT_ERR_NOSPACE;
+
+       if (((buf + newsize) <= fdt)
+           || (buf >= (fdt + fdt_totalsize(fdt)))) {
+               tmp = buf;
+       } else {
+               tmp = (void *)fdt + fdt_totalsize(fdt);
+               if ((tmp + newsize) > (buf + bufsize))
+                       return -FDT_ERR_NOSPACE;
+       }
+
+       _packblocks(fdt, tmp, mem_rsv_size, struct_size);
+       memmove(buf, tmp, newsize);
+
+       fdt_set_magic(buf, FDT_MAGIC);
+       fdt_set_totalsize(buf, bufsize);
+       fdt_set_version(buf, 17);
+       fdt_set_last_comp_version(buf, 16);
+       fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));
 
        return 0;
 }
 
 int fdt_pack(void *fdt)
 {
+       int mem_rsv_size;
        int err;
 
        err = rw_check_header(fdt);
        if (err)
                return err;
 
-       /* FIXME: pack components */
-       fdt_set_header(fdt, totalsize, _blob_data_size(fdt));
+       mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
+               * sizeof(struct fdt_reserve_entry);
+       _packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
+       fdt_set_totalsize(fdt, _blob_data_size(fdt));
+
        return 0;
 }
-
-#endif /* CONFIG_OF_LIBFDT */
index b49c952f346023d4e5441f39c7f2b51ed394f995..f9d32ef5360ab7acc84f23df066621b18f01f646 100644 (file)
@@ -2,23 +2,52 @@
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
  *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ *  b) Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *     1. Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *     2. Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-#include "config.h"
-#if CONFIG_OF_LIBFDT
-
 #include "libfdt_env.h"
 
 #include <fdt.h>
@@ -65,5 +94,3 @@ const char *fdt_strerror(int errval)
 
        return "<unknown error>";
 }
-
-#endif /* CONFIG_OF_LIBFDT */
index c7eea8ff39e524139df44154645509d9de0693a6..dda2de34b2e0a968463cf808b669b37e226620df 100644 (file)
@@ -2,23 +2,52 @@
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
  *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ *  b) Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *     1. Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *     2. Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-#include "config.h"
-#if CONFIG_OF_LIBFDT
-
 #include "libfdt_env.h"
 
 #include <fdt.h>
@@ -44,8 +73,8 @@ static void *grab_space(void *fdt, int len)
        if ((offset + len < offset) || (offset + len > spaceleft))
                return NULL;
 
-       fdt_set_header(fdt, size_dt_struct, offset + len);
-       return fdt_offset_ptr(fdt, offset, len);
+       fdt_set_size_dt_struct(fdt, offset + len);
+       return fdt_offset_ptr_w(fdt, offset, len);
 }
 
 int fdt_create(void *buf, int bufsize)
@@ -57,15 +86,15 @@ int fdt_create(void *buf, int bufsize)
 
        memset(buf, 0, bufsize);
 
-       fdt_set_header(fdt, magic, SW_MAGIC);
-       fdt_set_header(fdt, version, FDT_LAST_SUPPORTED_VERSION);
-       fdt_set_header(fdt, last_comp_version, FDT_FIRST_SUPPORTED_VERSION);
-       fdt_set_header(fdt, totalsize, bufsize);
+       fdt_set_magic(fdt, SW_MAGIC);
+       fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
+       fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
+       fdt_set_totalsize(fdt,  bufsize);
 
-       fdt_set_header(fdt, off_mem_rsvmap, ALIGN(sizeof(struct fdt_header),
-                                             sizeof(struct fdt_reserve_entry)));
-       fdt_set_header(fdt, off_dt_struct, fdt_off_mem_rsvmap(fdt));
-       fdt_set_header(fdt, off_dt_strings, bufsize);
+       fdt_set_off_mem_rsvmap(fdt, ALIGN(sizeof(struct fdt_header),
+                                         sizeof(struct fdt_reserve_entry)));
+       fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
+       fdt_set_off_dt_strings(fdt, bufsize);
 
        return 0;
 }
@@ -85,11 +114,11 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
        if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
                return -FDT_ERR_NOSPACE;
 
-       re = (struct fdt_reserve_entry *)((void *)fdt + offset);
+       re = (struct fdt_reserve_entry *)(fdt + offset);
        re->address = cpu_to_fdt64(addr);
        re->size = cpu_to_fdt64(size);
 
-       fdt_set_header(fdt, off_dt_struct, offset + sizeof(*re));
+       fdt_set_off_dt_struct(fdt, offset + sizeof(*re));
 
        return 0;
 }
@@ -152,7 +181,7 @@ static int find_add_string(void *fdt, const char *s)
                return 0; /* no more room :( */
 
        memcpy(strtab + offset, s, len);
-       fdt_set_header(fdt, size_dt_strings, strtabsize + len);
+       fdt_set_size_dt_strings(fdt, strtabsize + len);
        return offset;
 }
 
@@ -202,14 +231,14 @@ int fdt_finish(void *fdt)
        oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
        newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
        memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
-       fdt_set_header(fdt, off_dt_strings, newstroffset);
+       fdt_set_off_dt_strings(fdt, newstroffset);
 
        /* Walk the structure, correcting string offsets */
        offset = 0;
-       while ((tag = fdt_next_tag(fdt, offset, &nextoffset, NULL)) != FDT_END) {
+       while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
                if (tag == FDT_PROP) {
-                       struct fdt_property *prop = fdt_offset_ptr(fdt, offset,
-                                                                  sizeof(*prop));
+                       struct fdt_property *prop =
+                               fdt_offset_ptr_w(fdt, offset, sizeof(*prop));
                        int nameoff;
 
                        if (! prop)
@@ -223,9 +252,7 @@ int fdt_finish(void *fdt)
        }
 
        /* Finally, adjust the header */
-       fdt_set_header(fdt, totalsize, newstroffset + fdt_size_dt_strings(fdt));
-       fdt_set_header(fdt, magic, FDT_MAGIC);
+       fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
+       fdt_set_magic(fdt, FDT_MAGIC);
        return 0;
 }
-
-#endif /* CONFIG_OF_LIBFDT */
index 2d39aabe1fe9872c2a9e5e441979426244e063fd..88e24b8318f449e4ab7902fc27b4e7345948299d 100644 (file)
@@ -2,23 +2,52 @@
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
  *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
  *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ *  b) Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *     1. Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *     2. Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-#include "config.h"
-#if CONFIG_OF_LIBFDT
-
 #include "libfdt_env.h"
 
 #include <fdt.h>
@@ -32,7 +61,7 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
        void *propval;
        int proplen;
 
-       propval = fdt_getprop(fdt, nodeoffset, name, &proplen);
+       propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen);
        if (! propval)
                return proplen;
 
@@ -56,7 +85,7 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
        struct fdt_property *prop;
        int len;
 
-       prop = fdt_get_property(fdt, nodeoffset, name, &len);
+       prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
        if (! prop)
                return len;
 
@@ -71,12 +100,12 @@ int _fdt_node_end_offset(void *fdt, int nodeoffset)
        uint32_t tag;
        int offset, nextoffset;
 
-       tag = fdt_next_tag(fdt, nodeoffset, &nextoffset, NULL);
+       tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
        if (tag != FDT_BEGIN_NODE)
                return -FDT_ERR_BADOFFSET;
        do {
                offset = nextoffset;
-               tag = fdt_next_tag(fdt, offset, &nextoffset, NULL);
+               tag = fdt_next_tag(fdt, offset, &nextoffset);
 
                switch (tag) {
                case FDT_END:
@@ -110,33 +139,6 @@ int fdt_nop_node(void *fdt, int nodeoffset)
        if (endoffset < 0)
                return endoffset;
 
-       nop_region(fdt_offset_ptr(fdt, nodeoffset, 0), endoffset - nodeoffset);
+       nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0), endoffset - nodeoffset);
        return 0;
 }
-
-/*
- * Replace a reserve map entry in the nth slot.
- */
-int fdt_replace_reservemap_entry(void *fdt, int n, uint64_t addr, uint64_t size)
-{
-       struct fdt_reserve_entry *re;
-       int  used;
-       int  total;
-       int  err;
-
-       err = fdt_num_reservemap(fdt, &used, &total);
-       if (err != 0)
-               return err;
-
-       if (n >= total)
-               return -FDT_ERR_NOSPACE;
-       re = (struct fdt_reserve_entry *)
-               (fdt + fdt_off_mem_rsvmap(fdt) +
-                (n * sizeof(struct fdt_reserve_entry)));
-       re->address = cpu_to_fdt64(addr);
-       re->size    = cpu_to_fdt64(size);
-
-       return 0;
-}
-
-#endif /* CONFIG_OF_LIBFDT */
index cc9633c9e149a206f4f94c3daa72642bf0678a7e..1e60936beb5bbff7d609fc55011430fdadc8bd82 100644 (file)
@@ -4,19 +4,51 @@
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ *  b) Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *     1. Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *     2. Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <fdt.h>
 
 #define memeq(p, q, n) (memcmp((p), (q), (n)) == 0)
 #define streq(p, q)    (strcmp((p), (q)) == 0)
 
-int _fdt_check_header(const void *fdt);
+uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset);
 const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
 int _fdt_node_end_offset(void *fdt, int nodeoffset);
 
-static inline void *_fdt_offset_ptr(const struct fdt_header *fdt, int offset)
+static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
+{
+       return fdt + fdt_off_dt_struct(fdt) + offset;
+}
+
+static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
+{
+       return (void *)_fdt_offset_ptr(fdt, offset);
+}
+
+static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
+{
+       const struct fdt_reserve_entry *rsv_table =
+               fdt + fdt_off_mem_rsvmap(fdt);
+
+       return rsv_table + n;
+}
+static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
 {
-       return (void *)fdt + fdt_off_dt_struct(fdt) + offset;
+       return (void *)_fdt_mem_rsv(fdt, n);
 }
 
 #define SW_MAGIC               (~FDT_MAGIC)
index d8aa5fa777b59ab547f4d24635fbfa5d187b0e54..67fb67d291dd8bbcbc6f82a3e98f9d496223a9c2 100644 (file)
 #
 
 PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__MIPS__
+
+#
+# From Linux arch/mips/Makefile
+#
+# GCC uses -G 0 -mabicalls -fpic as default.  We don't want PIC in the kernel
+# code since it only slows down the whole thing.  At some point we might make
+# use of global pointer optimizations but their use of $28 conflicts with
+# the current pointer optimization.
+#
+# The DECStation requires an ECOFF kernel for remote booting, other MIPS
+# machines may also.  Since BFD is incredibly buggy with respect to
+# crossformat linking we rely on the elf2ecoff tool for format conversion.
+#
+# cflags-y                     += -G 0 -mno-abicalls -fno-pic -pipe
+# cflags-y                     += -msoft-float
+# LDFLAGS_vmlinux              += -G 0 -static -n -nostdlib
+# MODFLAGS                     += -mlong-calls
+#
+
+#
+# Meanwhile, U-Boot rely on PIC. We add proper switches explicitly.
+#
+PLATFORM_CPPFLAGS              += -G 0 -mabicalls -fpic -pipe
+PLATFORM_CPPFLAGS              += -msoft-float
+PLATFORM_LDFLAGS               += -G 0 -static -n -nostdlib
index 2a860140d22de7d0ab78ef09cf6bc189fde024a4..6e53bea0179292efb5d425ac904baed246d1c7e8 100644 (file)
@@ -100,7 +100,7 @@ $(obj)nand_boot.c:
 # from drivers/nand directory
 $(obj)nand_ecc.c:
        @rm -f $(obj)nand_ecc.c
-       ln -s $(SRCTREE)/drivers/nand/nand_ecc.c $(obj)nand_ecc.c
+       ln -s $(SRCTREE)/drivers/mtd/nand/nand_ecc.c $(obj)nand_ecc.c
 
 #########################################################################
 
index 8b5461dcf4cea9bb696fddf48702d4bb491a3005..3a633fb8871c6b00c3840a8bf4cabc71fbdc4132 100644 (file)
@@ -82,7 +82,7 @@ $(obj)nand_boot.c:
 # from drivers/nand directory
 $(obj)nand_ecc.c:
        @rm -f $(obj)nand_ecc.c
-       ln -s $(SRCTREE)/drivers/nand/nand_ecc.c $(obj)nand_ecc.c
+       ln -s $(SRCTREE)/drivers/mtd/nand/nand_ecc.c $(obj)nand_ecc.c
 
 ifneq ($(OBJTREE), $(SRCTREE))
 $(obj)sdram.c:
index ec1be5a768a5a228570aa5488353bba56a23b32a..78bf071f591df479ca9f6a7ce4622edd8f125430 100644 (file)
@@ -88,7 +88,7 @@ $(obj)nand_boot.c:
 # from drivers/nand directory
 $(obj)nand_ecc.c:
        @rm -f $(obj)nand_ecc.c
-       ln -s $(SRCTREE)/drivers/nand/nand_ecc.c $(obj)nand_ecc.c
+       ln -s $(SRCTREE)/drivers/mtd/nand/nand_ecc.c $(obj)nand_ecc.c
 
 #########################################################################
 
index d18460cab35195a525e2d56b876a778b8e8a0046..0eee330cfe3f01cdb89031bdf22f01d646c7cb03 100644 (file)
@@ -27,8 +27,15 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)libnet.a
 
-COBJS  = net.o tftp.o bootp.o rarp.o eth.o nfs.o sntp.o
-
+COBJS-y += net.o
+COBJS-y += tftp.o
+COBJS-y += bootp.o
+COBJS-y += rarp.o
+COBJS-y += eth.o
+COBJS-y += nfs.o
+COBJS-y += sntp.o
+
+COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS))
 
index 749d3e5e0c24ce08fb3ea7f9ccc8726b56445ed8..89e30d2c703e2d8423b84c0e9844bee7041dd343 100644 (file)
@@ -33,7 +33,7 @@
 
 #if defined(CONFIG_CMD_NET)
 
-#define TIMEOUT                5               /* Seconds before trying BOOTP again    */
+#define TIMEOUT                5UL             /* Seconds before trying BOOTP again    */
 #ifndef CONFIG_NET_RETRY_COUNT
 # define TIMEOUT_COUNT 5               /* # of timeouts before giving up  */
 #else
@@ -850,9 +850,9 @@ static void DhcpSendRequestPkt(Bootp_t *bp_offer)
        bp->bp_hlen = HWL_ETHER;
        bp->bp_hops = 0;
        bp->bp_secs = htons(get_timer(0) / CFG_HZ);
-       NetCopyIP(&bp->bp_ciaddr, &bp_offer->bp_ciaddr); /* both in network byte order */
-       NetCopyIP(&bp->bp_yiaddr, &bp_offer->bp_yiaddr);
-       NetCopyIP(&bp->bp_siaddr, &bp_offer->bp_siaddr);
+       /* Do not set the client IP, your IP, or server IP yet, since it hasn't been ACK'ed by
+        * the server yet */
+
        /*
         * RFC3046 requires Relay Agents to discard packets with
         * nonzero and offered giaddr
@@ -870,7 +870,9 @@ static void DhcpSendRequestPkt(Bootp_t *bp_offer)
        /*
         * Copy options from OFFER packet if present
         */
-       NetCopyIP(&OfferedIP, &bp->bp_yiaddr);
+
+       /* Copy offered IP into the parameters request list */
+       NetCopyIP(&OfferedIP, &bp_offer->bp_yiaddr);
        extlen = DhcpExtended((u8 *)bp->bp_vend, DHCP_REQUEST, NetDHCPServerIP, OfferedIP);
 
        pktlen = BOOTP_SIZE - sizeof(bp->bp_vend) + extlen;
@@ -977,6 +979,6 @@ void DhcpRequest(void)
 {
        BootpRequest();
 }
-#endif
+#endif /* CONFIG_CMD_DHCP */
 
-#endif
+#endif /* CONFIG_CMD_NET */
index ba9826e914cb9aaf2bcb2e14103e846ac9b94690..320cc3bd3025f12897b91b3016d57321d2378998 100644 (file)
@@ -88,7 +88,7 @@ typedef enum { INIT,
 #define DHCP_NAK      6
 #define DHCP_RELEASE  7
 
-#define SELECT_TIMEOUT 3       /* Seconds to wait for offers */
+#define SELECT_TIMEOUT 3UL     /* Seconds to wait for offers */
 
 /**********************************************************************/
 
index e7f1220591cfe147fa453f36bb73a7a773375fec..1b56a356c4f4544623b1093b6ef614dd1ff21a38 100644 (file)
--- a/net/eth.c
+++ b/net/eth.c
@@ -54,6 +54,7 @@ extern int rtl8169_initialize(bd_t*);
 extern int scc_initialize(bd_t*);
 extern int skge_initialize(bd_t*);
 extern int tsi108_eth_initialize(bd_t*);
+extern int uli526x_initialize(bd_t *);
 extern int tsec_initialize(bd_t*, int, char *);
 extern int npe_initialize(bd_t *);
 extern int uec_initialize(int);
@@ -238,6 +239,9 @@ int eth_initialize(bd_t *bis)
 #if defined(CONFIG_TSI108_ETH)
        tsi108_eth_initialize(bis);
 #endif
+#if defined(CONFIG_ULI526X)
+       uli526x_initialize(bis);
+#endif
 #if defined(CONFIG_RTL8139)
        rtl8139_initialize(bis);
 #endif
index cde26801b385b8e29a4e44a5e147514d4112c088..c719bc4c0f36d84698e8ae8fc95a3641aa5ff256 100644 (file)
--- a/net/net.c
+++ b/net/net.c
@@ -94,7 +94,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define ARP_TIMEOUT            5               /* Seconds before trying ARP again */
+#define ARP_TIMEOUT            5UL             /* Seconds before trying ARP again */
 #ifndef        CONFIG_NET_RETRY_COUNT
 # define ARP_TIMEOUT_COUNT     5               /* # of timeouts before giving up  */
 #else
@@ -589,7 +589,7 @@ void NetStartAgain (void)
                return;
        }
 #ifndef CONFIG_NET_MULTI
-       NetSetTimeout (10 * CFG_HZ, startAgainTimeout);
+       NetSetTimeout (10UL * CFG_HZ, startAgainTimeout);
        NetSetHandler (startAgainHandler);
 #else  /* !CONFIG_NET_MULTI*/
        eth_halt ();
@@ -598,7 +598,7 @@ void NetStartAgain (void)
        if (NetRestartWrap) {
                NetRestartWrap = 0;
                if (NetDevExists && !once) {
-                       NetSetTimeout (10 * CFG_HZ, startAgainTimeout);
+                       NetSetTimeout (10UL * CFG_HZ, startAgainTimeout);
                        NetSetHandler (startAgainHandler);
                } else {
                        NetState = NETLOOP_FAIL;
@@ -774,7 +774,7 @@ static void PingStart(void)
 #if defined(CONFIG_NET_MULTI)
        printf ("Using %s device\n", eth_get_name());
 #endif /* CONFIG_NET_MULTI */
-       NetSetTimeout (10 * CFG_HZ, PingTimeout);
+       NetSetTimeout (10UL * CFG_HZ, PingTimeout);
        NetSetHandler (PingHandler);
 
        PingSend();
index df2caac48c83ad562767301858387c3b5acc5e3c..aa8d612e5847a8f204f6ab7ef04c6b423fdea4e0 100644 (file)
--- a/net/nfs.c
+++ b/net/nfs.c
@@ -34,7 +34,7 @@
 #if defined(CONFIG_CMD_NET) && defined(CONFIG_CMD_NFS)
 
 #define HASHES_PER_LINE 65     /* Number of "loading" hashes per line  */
-#define NFS_TIMEOUT 60
+#define NFS_TIMEOUT 60UL
 
 static int fs_mounted = 0;
 static unsigned long rpc_id = 0;
@@ -405,7 +405,6 @@ rpc_lookup_reply (int prog, uchar *pkt, unsigned len)
 
        if (rpc_pkt.u.reply.rstatus  ||
            rpc_pkt.u.reply.verifier ||
-           rpc_pkt.u.reply.astatus  ||
            rpc_pkt.u.reply.astatus) {
                return -1;
        }
index 21dfa529c9a381934612e12e62da1e9c0ea438f8..ecf38e4ee5415505564d134dcadd77b9e9f4d981 100644 (file)
@@ -31,7 +31,7 @@
 
 #if defined(CONFIG_CMD_NET)
 
-#define TIMEOUT                5               /* Seconds before trying BOOTP again */
+#define TIMEOUT                5UL             /* Seconds before trying BOOTP again */
 #ifndef        CONFIG_NET_RETRY_COUNT
 # define TIMEOUT_COUNT 5               /* # of timeouts before giving up  */
 #else
index 5ee7676466925cafcdde9a8eee38f7a4b13282f5..8b95bcfec49fbad572ea0b34831b27b926bf7df5 100644 (file)
@@ -15,7 +15,7 @@
 #if defined(CONFIG_CMD_NET)
 
 #define WELL_KNOWN_PORT        69              /* Well known TFTP port #               */
-#define TIMEOUT                5               /* Seconds to timeout for a lost pkt    */
+#define TIMEOUT                5UL             /* Seconds to timeout for a lost pkt    */
 #ifndef        CONFIG_NET_RETRY_COUNT
 # define TIMEOUT_COUNT 10              /* # of timeouts before giving up  */
 #else
diff --git a/rtc/Makefile b/rtc/Makefile
deleted file mode 100644 (file)
index 5a0cf11..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# (C) Copyright 2001-2006
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-#
-# See file CREDITS for list of people who contributed to this
-# project.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-# MA 02111-1307 USA
-#
-
-include $(TOPDIR)/config.mk
-
-#CFLAGS += -DDEBUG
-
-LIB    = $(obj)librtc.a
-
-COBJS  = date.o   \
-         bf5xx_rtc.o ds12887.o ds1302.o ds1306.o ds1307.o \
-         ds1337.o ds1374.o ds1556.o ds164x.o ds174x.o ds3231.o \
-         m41t11.o max6900.o m48t35ax.o mc146818.o mk48t59.o \
-         mpc5xxx.o mpc8xx.o pcf8563.o s3c24x0_rtc.o rs5c372.o \
-         mcfrtc.o x1205.o
-
-SRCS   := $(COBJS:.o=.c)
-OBJS   := $(addprefix $(obj),$(COBJS))
-
-all:   $(LIB)
-
-$(LIB):        $(obj).depend $(OBJS)
-       $(AR) $(ARFLAGS) $@ $(OBJS)
-
-#########################################################################
-
-# defines $(obj).depend target
-include $(SRCTREE)/rules.mk
-
-sinclude $(obj).depend
-
-#########################################################################
diff --git a/rtc/bf5xx_rtc.c b/rtc/bf5xx_rtc.c
deleted file mode 100644 (file)
index 8856bb9..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * (C) Copyright 2001
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- * Real Time Clock interface of ADI21535 (Blackfin) for uCLinux
- *
- * Copyright (C) 2003 Motorola Corporation.  All rights reserved.
- *                             Richard Xiao (A2590C@email.mot.com)
- *
- * Copyright (C) 1996 Paul Gortmaker
- *
- *
- *     Based on other minimal char device drivers, like Alan's
- *     watchdog, Ted's random, etc. etc.
- *
- *     1.07    Paul Gortmaker.
- *     1.08    Miquel van Smoorenburg: disallow certain things on the
- *             DEC Alpha as the CMOS clock is also used for other things.
- *     1.09    Nikita Schmidt: epoch support and some Alpha cleanup.
- *     1.09a   Pete Zaitcev: Sun SPARC
- *     1.09b   Jeff Garzik: Modularize, init cleanup
- *     1.09c   Jeff Garzik: SMP cleanup
- *     1.10    Paul Barton-Davis: add support for async I/O
- *     1.10a   Andrea Arcangeli: Alpha updates
- *     1.10b   Andrew Morton: SMP lock fix
- *     1.10c   Cesar Barros: SMP locking fixes and cleanup
- *     1.10d   Paul Gortmaker: delete paranoia check in rtc_exit
- *     1.10e   LG Soft India: Register access is different in BF533.
- */
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-
-#if defined(CONFIG_RTC_BFIN) && defined(CONFIG_CMD_DATE)
-
-#include <asm/blackfin.h>
-#include <asm/arch/bf5xx_rtc.h>
-
-void rtc_reset(void)
-{
-       return;                 /* nothing to do */
-}
-
-/* Wait for pending writes to complete */
-void wait_for_complete(void)
-{
-       while (!(*(volatile unsigned short *)RTC_ISTAT & 0x8000)) {
-               printf("");
-       }
-       *(volatile unsigned short *)RTC_ISTAT = 0x8000;
-}
-
-/* Enable the RTC prescaler enable register */
-void rtc_init()
-{
-       *(volatile unsigned short *)RTC_PREN = 0x1;
-       wait_for_complete();
-}
-
-/* Set the time. Get the time_in_secs which is the number of seconds since Jan 1970 and set the RTC registers
- * based on this value.
- */
-void rtc_set(struct rtc_time *tmp)
-{
-       unsigned long n_days_1970 = 0;
-       unsigned long n_secs_rem = 0;
-       unsigned long n_hrs = 0;
-       unsigned long n_mins = 0;
-       unsigned long n_secs = 0;
-       unsigned long time_in_secs;
-
-       if (tmp == NULL) {
-               printf("Error setting the date/time \n");
-               return;
-       }
-
-       time_in_secs =
-           mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_hour,
-                  tmp->tm_min, tmp->tm_sec);
-
-       /* Compute no. of days since 1970 */
-       n_days_1970 = (unsigned long)(time_in_secs / (NUM_SECS_IN_DAY));
-
-       /* From the remining secs, compute the hrs(0-23), mins(0-59) and secs(0-59) */
-       n_secs_rem = (unsigned long)(time_in_secs % (NUM_SECS_IN_DAY));
-       n_hrs = n_secs_rem / (NUM_SECS_IN_HOUR);
-       n_secs_rem = n_secs_rem % (NUM_SECS_IN_HOUR);
-       n_mins = n_secs_rem / (NUM_SECS_IN_MIN);
-       n_secs = n_secs_rem % (NUM_SECS_IN_MIN);
-
-       /* Store the new time in the RTC_STAT register */
-       *(volatile unsigned long *)RTC_STAT =
-           ((n_days_1970 << DAY_BITS_OFF) | (n_hrs << HOUR_BITS_OFF) |
-            (n_mins << MIN_BITS_OFF) | (n_secs << SEC_BITS_OFF));
-
-       wait_for_complete();
-}
-
-/* Read the time from the RTC_STAT. time_in_seconds is seconds since Jan 1970 */
-void rtc_get(struct rtc_time *tmp)
-{
-       unsigned long cur_rtc_stat = 0;
-       unsigned long time_in_sec;
-       unsigned long tm_sec = 0, tm_min = 0, tm_hour = 0, tm_day = 0;
-
-       if (tmp == NULL) {
-               printf("Error getting the date/time \n");
-               return;
-       }
-
-       /* Read the RTC_STAT register */
-       cur_rtc_stat = *(volatile unsigned long *)RTC_STAT;
-
-       /* Get the secs (0-59), mins (0-59), hrs (0-23) and the days since Jan 1970 */
-       tm_sec = (cur_rtc_stat >> SEC_BITS_OFF) & 0x3f;
-       tm_min = (cur_rtc_stat >> MIN_BITS_OFF) & 0x3f;
-       tm_hour = (cur_rtc_stat >> HOUR_BITS_OFF) & 0x1f;
-       tm_day = (cur_rtc_stat >> DAY_BITS_OFF) & 0x7fff;
-
-       /* Calculate the total number of seconds since Jan 1970 */
-       time_in_sec = (tm_sec) +
-           MIN_TO_SECS(tm_min) + HRS_TO_SECS(tm_hour) + DAYS_TO_SECS(tm_day);
-       to_tm(time_in_sec, tmp);
-}
-#endif
diff --git a/rtc/date.c b/rtc/date.c
deleted file mode 100644 (file)
index a83a723..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * (C) Copyright 2001
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Date & Time support for Philips PCF8563 RTC
- */
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-
-#if defined(CONFIG_CMD_DATE) || defined(CONFIG_TIMESTAMP)
-
-#define FEBRUARY               2
-#define        STARTOFTIME             1970
-#define SECDAY                 86400L
-#define SECYR                  (SECDAY * 365)
-#define        leapyear(year)          ((year) % 4 == 0)
-#define        days_in_year(a)         (leapyear(a) ? 366 : 365)
-#define        days_in_month(a)        (month_days[(a) - 1])
-
-static int month_days[12] = {
-       31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-};
-
-/*
- * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
- */
-void GregorianDay(struct rtc_time * tm)
-{
-       int leapsToDate;
-       int lastYear;
-       int day;
-       int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };
-
-       lastYear=tm->tm_year-1;
-
-       /*
-        * Number of leap corrections to apply up to end of last year
-        */
-       leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
-
-       /*
-        * This year is a leap year if it is divisible by 4 except when it is
-        * divisible by 100 unless it is divisible by 400
-        *
-        * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
-        */
-       if((tm->tm_year%4==0) &&
-          ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
-          (tm->tm_mon>2)) {
-               /*
-                * We are past Feb. 29 in a leap year
-                */
-               day=1;
-       } else {
-               day=0;
-       }
-
-       day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + tm->tm_mday;
-
-       tm->tm_wday=day%7;
-}
-
-void to_tm(int tim, struct rtc_time * tm)
-{
-       register int    i;
-       register long   hms, day;
-
-       day = tim / SECDAY;
-       hms = tim % SECDAY;
-
-       /* Hours, minutes, seconds are easy */
-       tm->tm_hour = hms / 3600;
-       tm->tm_min = (hms % 3600) / 60;
-       tm->tm_sec = (hms % 3600) % 60;
-
-       /* Number of years in days */
-       for (i = STARTOFTIME; day >= days_in_year(i); i++) {
-               day -= days_in_year(i);
-       }
-       tm->tm_year = i;
-
-       /* Number of months in days left */
-       if (leapyear(tm->tm_year)) {
-               days_in_month(FEBRUARY) = 29;
-       }
-       for (i = 1; day >= days_in_month(i); i++) {
-               day -= days_in_month(i);
-       }
-       days_in_month(FEBRUARY) = 28;
-       tm->tm_mon = i;
-
-       /* Days are what is left over (+1) from all that. */
-       tm->tm_mday = day + 1;
-
-       /*
-        * Determine the day of week
-        */
-       GregorianDay(tm);
-}
-
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-unsigned long
-mktime (unsigned int year, unsigned int mon,
-       unsigned int day, unsigned int hour,
-       unsigned int min, unsigned int sec)
-{
-       if (0 >= (int) (mon -= 2)) {    /* 1..12 -> 11,12,1..10 */
-               mon += 12;              /* Puts Feb last since it has leap day */
-               year -= 1;
-       }
-
-       return (((
-               (unsigned long) (year/4 - year/100 + year/400 + 367*mon/12 + day) +
-                       year*365 - 719499
-           )*24 + hour /* now have hours */
-         )*60 + min /* now have minutes */
-       )*60 + sec; /* finally seconds */
-}
-
-#endif
diff --git a/rtc/ds12887.c b/rtc/ds12887.c
deleted file mode 100644 (file)
index 84fecf0..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * (C) Copyright 2003
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Date & Time support for the DS12887 RTC
- */
-
-#undef RTC_DEBUG
-
-#include <common.h>
-#include <command.h>
-#include <config.h>
-#include <rtc.h>
-
-#if defined(CONFIG_RTC_DS12887) && defined(CONFIG_CMD_DATE)
-
-#define RTC_SECONDS                    0x00
-#define RTC_SECONDS_ALARM              0x01
-#define RTC_MINUTES                    0x02
-#define RTC_MINUTES_ALARM              0x03
-#define RTC_HOURS                      0x04
-#define RTC_HOURS_ALARM                0x05
-#define RTC_DAY_OF_WEEK                0x06
-#define RTC_DATE_OF_MONTH              0x07
-#define RTC_MONTH                      0x08
-#define RTC_YEAR                       0x09
-#define RTC_CONTROL_A                  0x0A
-#define RTC_CONTROL_B                  0x0B
-#define RTC_CONTROL_C                  0x0C
-#define RTC_CONTROL_D                  0x0D
-
-#define RTC_CA_UIP                     0x80
-#define RTC_CB_DM                      0x04
-#define RTC_CB_24_12                   0x02
-#define RTC_CB_SET                     0x80
-
-#if defined(CONFIG_ATC)
-
-static uchar rtc_read (uchar reg)
-{
-       uchar val;
-
-       *(volatile unsigned char*)(RTC_PORT_ADDR) = reg;
-       __asm__ __volatile__ ("sync");
-
-       val = *(volatile unsigned char*)(RTC_PORT_DATA);
-       return (val);
-}
-
-static void rtc_write (uchar reg, uchar val)
-{
-       *(volatile unsigned char*)(RTC_PORT_ADDR) = reg;
-       __asm__ __volatile__ ("sync");
-
-       *(volatile unsigned char*)(RTC_PORT_DATA) = val;
-       __asm__ __volatile__ ("sync");
-}
-
-#else
-# error Board specific rtc access functions should be supplied
-#endif
-
-static unsigned bcd2bin (uchar n)
-{
-       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
-}
-
-static unsigned char bin2bcd (unsigned int n)
-{
-       return (((n / 10) << 4) | (n % 10));
-}
-
-/* ------------------------------------------------------------------------- */
-
-void rtc_get (struct rtc_time *tmp)
-{
-       uchar sec, min, hour, mday, wday, mon, year;
-
-       /* check if rtc is available for access */
-       while( rtc_read(RTC_CONTROL_A) & RTC_CA_UIP)
-               ;
-
-       sec  = rtc_read(RTC_SECONDS);
-       min  = rtc_read(RTC_MINUTES);
-       hour = rtc_read(RTC_HOURS);
-       mday = rtc_read(RTC_DATE_OF_MONTH);
-       wday = rtc_read(RTC_DAY_OF_WEEK);
-       mon  = rtc_read(RTC_MONTH);
-       year = rtc_read(RTC_YEAR);
-
-#ifdef RTC_DEBUG
-       printf( "Get RTC year: %d; mon: %d; mday: %d; wday: %d; "
-               "hr: %d; min: %d; sec: %d\n",
-               year, mon, mday, wday, hour, min, sec );
-
-       printf ( "Alarms: hour: %02x min: %02x sec: %02x\n",
-                rtc_read (RTC_HOURS_ALARM),
-                rtc_read (RTC_MINUTES_ALARM),
-                rtc_read (RTC_SECONDS_ALARM) );
-#endif
-
-       if( !(rtc_read(RTC_CONTROL_B) & RTC_CB_DM))
-       {           /* Information is in BCD format */
-printf(" Get: Convert BSD to BIN\n");
-               tmp->tm_sec  = bcd2bin (sec  & 0x7F);
-               tmp->tm_min  = bcd2bin (min  & 0x7F);
-               tmp->tm_hour = bcd2bin (hour & 0x3F);
-               tmp->tm_mday = bcd2bin (mday & 0x3F);
-               tmp->tm_mon  = bcd2bin (mon & 0x1F);
-               tmp->tm_year = bcd2bin (year);
-               tmp->tm_wday = bcd2bin (wday & 0x07);
-       }
-else
-       {
-               tmp->tm_sec  = sec  & 0x7F;
-               tmp->tm_min  = min  & 0x7F;
-               tmp->tm_hour = hour & 0x3F;
-               tmp->tm_mday = mday & 0x3F;
-               tmp->tm_mon  = mon & 0x1F;
-               tmp->tm_year = year;
-               tmp->tm_wday = wday & 0x07;
-       }
-
-
-       if(tmp->tm_year<70)
-               tmp->tm_year+=2000;
-       else
-               tmp->tm_year+=1900;
-
-       tmp->tm_yday = 0;
-       tmp->tm_isdst= 0;
-#ifdef RTC_DEBUG
-       printf ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-#endif
-}
-
-void rtc_set (struct rtc_time *tmp)
-{
-       uchar save_ctrl_b;
-       uchar sec, min, hour, mday, wday, mon, year;
-
-#ifdef RTC_DEBUG
-       printf ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-#endif
-
-       if( !(rtc_read(RTC_CONTROL_B) & RTC_CB_DM))
-       {           /* Information is in BCD format */
-               year = bin2bcd(tmp->tm_year % 100);
-               mon  = bin2bcd(tmp->tm_mon);
-               wday = bin2bcd(tmp->tm_wday);
-               mday = bin2bcd(tmp->tm_mday);
-               hour = bin2bcd(tmp->tm_hour);
-               min  = bin2bcd(tmp->tm_min);
-               sec  = bin2bcd(tmp->tm_sec);
-       }
-       else
-       {
-               year = tmp->tm_year % 100;
-               mon  = tmp->tm_mon;
-               wday = tmp->tm_wday;
-               mday = tmp->tm_mday;
-               hour = tmp->tm_hour;
-               min  = tmp->tm_min;
-               sec  = tmp->tm_sec;
-       }
-
-       /* disables the RTC to update the regs */
-       save_ctrl_b = rtc_read(RTC_CONTROL_B);
-       save_ctrl_b |= RTC_CB_SET;
-       rtc_write(RTC_CONTROL_B, save_ctrl_b);
-
-       rtc_write (RTC_YEAR, year);
-       rtc_write (RTC_MONTH, mon);
-       rtc_write (RTC_DAY_OF_WEEK, wday);
-       rtc_write (RTC_DATE_OF_MONTH, mday);
-       rtc_write (RTC_HOURS, hour);
-       rtc_write (RTC_MINUTES, min);
-       rtc_write (RTC_SECONDS, sec);
-
-       /* enables the RTC to update the regs */
-       save_ctrl_b &= ~RTC_CB_SET;
-       rtc_write(RTC_CONTROL_B, save_ctrl_b);
-}
-
-void rtc_reset (void)
-{
-       struct rtc_time tmp;
-       uchar ctrl_rg;
-
-       ctrl_rg = RTC_CB_SET;
-       rtc_write(RTC_CONTROL_B,ctrl_rg);
-
-       tmp.tm_year = 1970 % 100;
-       tmp.tm_mon = 1;
-       tmp.tm_mday= 1;
-       tmp.tm_hour = 0;
-       tmp.tm_min = 0;
-       tmp.tm_sec = 0;
-
-#ifdef RTC_DEBUG
-       printf ( "RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC\n",
-                   tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
-                   tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
-#endif
-
-       ctrl_rg = RTC_CB_SET | RTC_CB_24_12 | RTC_CB_DM;
-       rtc_write(RTC_CONTROL_B,ctrl_rg);
-       rtc_set(&tmp);
-
-       rtc_write(RTC_HOURS_ALARM, 0),
-       rtc_write(RTC_MINUTES_ALARM, 0),
-       rtc_write(RTC_SECONDS_ALARM, 0);
-
-       ctrl_rg = RTC_CB_24_12 | RTC_CB_DM;
-       rtc_write(RTC_CONTROL_B,ctrl_rg);
-}
-
-#endif
diff --git a/rtc/ds1302.c b/rtc/ds1302.c
deleted file mode 100644 (file)
index 55af130..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * ds1302.c - Support for the Dallas Semiconductor DS1302 Timekeeping Chip
- *
- * Rex G. Feany <rfeany@zumanetworks.com>
- *
- */
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-
-#if defined(CONFIG_RTC_DS1302) && defined(CONFIG_CMD_DATE)
-
-/* GPP Pins */
-#define DATA           0x200
-#define SCLK           0x400
-#define RST            0x800
-
-/* Happy Fun Defines(tm) */
-#define RESET          rtc_go_low(RST), rtc_go_low(SCLK)
-#define N_RESET                rtc_go_high(RST), rtc_go_low(SCLK)
-
-#define CLOCK_HIGH     rtc_go_high(SCLK)
-#define CLOCK_LOW      rtc_go_low(SCLK)
-
-#define DATA_HIGH      rtc_go_high(DATA)
-#define DATA_LOW       rtc_go_low(DATA)
-#define DATA_READ      (GTREGREAD(GPP_VALUE) & DATA)
-
-#undef RTC_DEBUG
-
-#ifdef RTC_DEBUG
-#  define DPRINTF(x,args...)   printf("ds1302: " x , ##args)
-static inline void DUMP(const char *ptr, int num)
-{
-       while (num--) printf("%x ", *ptr++);
-       printf("]\n");
-}
-#else
-#  define DPRINTF(x,args...)
-#  define DUMP(ptr, num)
-#endif
-
-/* time data format for DS1302 */
-struct ds1302_st
-{
-       unsigned char CH:1;             /* clock halt 1=stop 0=start */
-       unsigned char sec10:3;
-       unsigned char sec:4;
-
-       unsigned char zero0:1;
-       unsigned char min10:3;
-       unsigned char min:4;
-
-       unsigned char fmt:1;            /* 1=12 hour 0=24 hour */
-       unsigned char zero1:1;
-       unsigned char hr10:2;   /* 10 (0-2) or am/pm (am/pm, 0-1) */
-       unsigned char hr:4;
-
-       unsigned char zero2:2;
-       unsigned char date10:2;
-       unsigned char date:4;
-
-       unsigned char zero3:3;
-       unsigned char month10:1;
-       unsigned char month:4;
-
-       unsigned char zero4:5;
-       unsigned char day:3;            /* day of week */
-
-       unsigned char year10:4;
-       unsigned char year:4;
-
-       unsigned char WP:1;             /* write protect 1=protect 0=unprot */
-       unsigned char zero5:7;
-};
-
-static int ds1302_initted=0;
-
-/* Pin control */
-static inline void
-rtc_go_high(unsigned int mask)
-{
-       unsigned int f = GTREGREAD(GPP_VALUE) | mask;
-
-       GT_REG_WRITE(GPP_VALUE, f);
-}
-
-static inline void
-rtc_go_low(unsigned int mask)
-{
-       unsigned int f = GTREGREAD(GPP_VALUE) & ~mask;
-
-       GT_REG_WRITE(GPP_VALUE, f);
-}
-
-static inline void
-rtc_go_input(unsigned int mask)
-{
-       unsigned int f = GTREGREAD(GPP_IO_CONTROL) & ~mask;
-
-       GT_REG_WRITE(GPP_IO_CONTROL, f);
-}
-
-static inline void
-rtc_go_output(unsigned int mask)
-{
-       unsigned int f = GTREGREAD(GPP_IO_CONTROL) | mask;
-
-       GT_REG_WRITE(GPP_IO_CONTROL, f);
-}
-
-/* Access data in RTC */
-
-static void
-write_byte(unsigned char b)
-{
-       int i;
-       unsigned char mask=1;
-
-       for(i=0;i<8;i++) {
-               CLOCK_LOW;                      /* Lower clock */
-               (b&mask)?DATA_HIGH:DATA_LOW;    /* set data */
-               udelay(1);
-               CLOCK_HIGH;             /* latch data with rising clock */
-               udelay(1);
-               mask=mask<<1;
-       }
-}
-
-static unsigned char
-read_byte(void)
-{
-       int i;
-       unsigned char mask=1;
-       unsigned char b=0;
-
-       for(i=0;i<8;i++) {
-               CLOCK_LOW;
-               udelay(1);
-               if (DATA_READ) b|=mask; /* if this bit is high, set in b */
-               CLOCK_HIGH;             /* clock out next bit */
-               udelay(1);
-               mask=mask<<1;
-       }
-       return b;
-}
-
-static void
-read_ser_drv(unsigned char addr, unsigned char *buf, int count)
-{
-       int i;
-#ifdef RTC_DEBUG
-       char *foo = buf;
-#endif
-
-       DPRINTF("READ 0x%x bytes @ 0x%x [ ", count, addr);
-
-       addr|=1;        /* READ */
-       N_RESET;
-       udelay(4);
-       write_byte(addr);
-       rtc_go_input(DATA); /* Put gpp pin into input mode */
-       udelay(1);
-       for(i=0;i<count;i++) *(buf++)=read_byte();
-       RESET;
-       rtc_go_output(DATA);/* Reset gpp for output */
-       udelay(4);
-
-       DUMP(foo, count);
-}
-
-static void
-write_ser_drv(unsigned char addr, unsigned char *buf, int count)
-{
-       int i;
-
-       DPRINTF("WRITE 0x%x bytes @ 0x%x [ ", count, addr);
-       DUMP(buf, count);
-
-       addr&=~1;       /* WRITE */
-       N_RESET;
-       udelay(4);
-       write_byte(addr);
-       for(i=0;i<count;i++) write_byte(*(buf++));
-       RESET;
-       udelay(4);
-
-}
-
-void
-rtc_init(void)
-{
-       struct ds1302_st bbclk;
-       unsigned char b;
-       int mod;
-
-       DPRINTF("init\n");
-
-       rtc_go_output(DATA|SCLK|RST);
-
-       /* disable write protect */
-       b = 0;
-       write_ser_drv(0x8e,&b,1);
-
-       /* enable trickle */
-       b = 0xa5;       /* 1010.0101 */
-       write_ser_drv(0x90,&b,1);
-
-       /* read burst */
-       read_ser_drv(0xbe, (unsigned char *)&bbclk, 8);
-
-       /* Sanity checks */
-       mod = 0;
-       if (bbclk.CH) {
-               printf("ds1302: Clock was halted, starting clock\n");
-               bbclk.CH=0;
-               mod=1;
-       }
-
-       if (bbclk.fmt) {
-               printf("ds1302: Clock was in 12 hour mode, fixing\n");
-               bbclk.fmt=0;
-               mod=1;
-       }
-
-       if (bbclk.year>9) {
-               printf("ds1302: Year was corrupted, fixing\n");
-               bbclk.year10=100/10;    /* 2000 - why not? ;) */
-               bbclk.year=0;
-               mod=1;
-       }
-
-       /* Write out the changes if needed */
-       if (mod) {
-               /* enable write protect */
-               bbclk.WP = 1;
-               write_ser_drv(0xbe,(unsigned char *)&bbclk,8);
-       } else {
-               /* Else just turn write protect on */
-               b = 0x80;
-               write_ser_drv(0x8e,&b,1);
-       }
-       DPRINTF("init done\n");
-
-       ds1302_initted=1;
-}
-
-void
-rtc_reset(void)
-{
-       if(!ds1302_initted) rtc_init();
-       /* TODO */
-}
-
-void
-rtc_get(struct rtc_time *tmp)
-{
-       struct ds1302_st bbclk;
-
-       if(!ds1302_initted) rtc_init();
-
-       read_ser_drv(0xbe,(unsigned char *)&bbclk, 8);      /* read burst */
-
-       if (bbclk.CH) {
-               printf("ds1302: rtc_get: Clock was halted, clock probably "
-                       "corrupt\n");
-       }
-
-       tmp->tm_sec=10*bbclk.sec10+bbclk.sec;
-       tmp->tm_min=10*bbclk.min10+bbclk.min;
-       tmp->tm_hour=10*bbclk.hr10+bbclk.hr;
-       tmp->tm_wday=bbclk.day;
-       tmp->tm_mday=10*bbclk.date10+bbclk.date;
-       tmp->tm_mon=10*bbclk.month10+bbclk.month;
-       tmp->tm_year=10*bbclk.year10+bbclk.year + 1900;
-
-       tmp->tm_yday = 0;
-       tmp->tm_isdst= 0;
-
-       DPRINTF("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
-}
-
-void
-rtc_set(struct rtc_time *tmp)
-{
-       struct ds1302_st bbclk;
-       unsigned char b=0;
-
-       if(!ds1302_initted) rtc_init();
-
-       DPRINTF("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
-       memset(&bbclk,0,sizeof(bbclk));
-       bbclk.CH=0; /* dont halt */
-       bbclk.WP=1; /* write protect when we're done */
-
-       bbclk.sec10=tmp->tm_sec/10;
-       bbclk.sec=tmp->tm_sec%10;
-
-       bbclk.min10=tmp->tm_min/10;
-       bbclk.min=tmp->tm_min%10;
-
-       bbclk.hr10=tmp->tm_hour/10;
-       bbclk.hr=tmp->tm_hour%10;
-
-       bbclk.day=tmp->tm_wday;
-
-       bbclk.date10=tmp->tm_mday/10;
-       bbclk.date=tmp->tm_mday%10;
-
-       bbclk.month10=tmp->tm_mon/10;
-       bbclk.month=tmp->tm_mon%10;
-
-       tmp->tm_year -= 1900;
-       bbclk.year10=tmp->tm_year/10;
-       bbclk.year=tmp->tm_year%10;
-
-       write_ser_drv(0x8e,&b,1);           /* disable write protect */
-       write_ser_drv(0xbe,(unsigned char *)&bbclk, 8);     /* write burst */
-}
-
-#endif
diff --git a/rtc/ds1306.c b/rtc/ds1306.c
deleted file mode 100644 (file)
index 89e433d..0000000
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * (C) Copyright 2002 SIXNET, dge@sixnetio.com.
- *
- * (C) Copyright 2004, Li-Pro.Net <www.li-pro.net>
- * Stephan Linz <linz@li-pro.net>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Date & Time support for DS1306 RTC using SPI:
- *
- *    - SXNI855T:    it uses its own soft SPI here in this file
- *    - all other:   use the external spi_xfer() function
- *                   (see include/spi.h)
- */
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-#include <spi.h>
-
-#if defined(CONFIG_RTC_DS1306) && defined(CONFIG_CMD_DATE)
-
-#define        RTC_SECONDS             0x00
-#define        RTC_MINUTES             0x01
-#define        RTC_HOURS               0x02
-#define        RTC_DAY_OF_WEEK         0x03
-#define        RTC_DATE_OF_MONTH       0x04
-#define        RTC_MONTH               0x05
-#define        RTC_YEAR                0x06
-
-#define        RTC_SECONDS_ALARM0      0x07
-#define        RTC_MINUTES_ALARM0      0x08
-#define        RTC_HOURS_ALARM0        0x09
-#define        RTC_DAY_OF_WEEK_ALARM0  0x0a
-
-#define        RTC_SECONDS_ALARM1      0x0b
-#define        RTC_MINUTES_ALARM1      0x0c
-#define        RTC_HOURS_ALARM1        0x0d
-#define        RTC_DAY_OF_WEEK_ALARM1  0x0e
-
-#define        RTC_CONTROL             0x0f
-#define        RTC_STATUS              0x10
-#define        RTC_TRICKLE_CHARGER     0x11
-
-#define        RTC_USER_RAM_BASE       0x20
-
-/*
- * External table of chip select functions (see the appropriate board
- * support for the actual definition of the table).
- */
-extern spi_chipsel_type spi_chipsel[];
-extern int spi_chipsel_cnt;
-
-static unsigned int bin2bcd (unsigned int n);
-static unsigned char bcd2bin (unsigned char c);
-
-/* ************************************************************************* */
-#ifdef CONFIG_SXNI855T         /* !!! SHOULD BE CHANGED TO NEW CODE !!! */
-
-static void soft_spi_send (unsigned char n);
-static unsigned char soft_spi_read (void);
-static void init_spi (void);
-
-/*-----------------------------------------------------------------------
- * Definitions
- */
-
-#define        PB_SPISCK       0x00000002      /* PB 30 */
-#define PB_SPIMOSI     0x00000004      /* PB 29 */
-#define PB_SPIMISO     0x00000008      /* PB 28 */
-#define PB_SPI_CE      0x00010000      /* PB 15 */
-
-/* ------------------------------------------------------------------------- */
-
-/* read clock time from DS1306 and return it in *tmp */
-void rtc_get (struct rtc_time *tmp)
-{
-       volatile immap_t *immap = (immap_t *) CFG_IMMR;
-       unsigned char spi_byte; /* Data Byte */
-
-       init_spi ();            /* set port B for software SPI */
-
-       /* Now we can enable the DS1306 RTC */
-       immap->im_cpm.cp_pbdat |= PB_SPI_CE;
-       udelay (10);
-
-       /* Shift out the address (0) of the time in the Clock Chip */
-       soft_spi_send (0);
-
-       /* Put the clock readings into the rtc_time structure */
-       tmp->tm_sec = bcd2bin (soft_spi_read ());       /* Read seconds */
-       tmp->tm_min = bcd2bin (soft_spi_read ());       /* Read minutes */
-
-       /* Hours are trickier */
-       spi_byte = soft_spi_read ();    /* Read Hours into temporary value */
-       if (spi_byte & 0x40) {
-               /* 12 hour mode bit is set (time is in 1-12 format) */
-               if (spi_byte & 0x20) {
-                       /* since PM we add 11 to get 0-23 for hours */
-                       tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) + 11;
-               } else {
-                       /* since AM we subtract 1 to get 0-23 for hours */
-                       tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) - 1;
-               }
-       } else {
-               /* Otherwise, 0-23 hour format */
-               tmp->tm_hour = (bcd2bin (spi_byte & 0x3F));
-       }
-
-       soft_spi_read ();       /* Read and discard Day of week */
-       tmp->tm_mday = bcd2bin (soft_spi_read ());      /* Read Day of the Month */
-       tmp->tm_mon = bcd2bin (soft_spi_read ());       /* Read Month */
-
-       /* Read Year and convert to this century */
-       tmp->tm_year = bcd2bin (soft_spi_read ()) + 2000;
-
-       /* Now we can disable the DS1306 RTC */
-       immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;   /* Disable DS1306 Chip */
-       udelay (10);
-
-       GregorianDay (tmp);     /* Determine the day of week */
-
-       debug ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-              tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-              tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* set clock time in DS1306 RTC and in MPC8xx RTC */
-void rtc_set (struct rtc_time *tmp)
-{
-       volatile immap_t *immap = (immap_t *) CFG_IMMR;
-
-       init_spi ();            /* set port B for software SPI */
-
-       /* Now we can enable the DS1306 RTC */
-       immap->im_cpm.cp_pbdat |= PB_SPI_CE;    /* Enable DS1306 Chip */
-       udelay (10);
-
-       /* First disable write protect in the clock chip control register */
-       soft_spi_send (0x8F);   /* send address of the control register */
-       soft_spi_send (0x00);   /* send control register contents */
-
-       /* Now disable the DS1306 to terminate the write */
-       immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;
-       udelay (10);
-
-       /* Now enable the DS1306 to initiate a new write */
-       immap->im_cpm.cp_pbdat |= PB_SPI_CE;
-       udelay (10);
-
-       /* Next, send the address of the clock time write registers */
-       soft_spi_send (0x80);   /* send address of the first time register */
-
-       /* Use Burst Mode to send all of the time data to the clock */
-       bin2bcd (tmp->tm_sec);
-       soft_spi_send (bin2bcd (tmp->tm_sec));  /* Send Seconds */
-       soft_spi_send (bin2bcd (tmp->tm_min));  /* Send Minutes */
-       soft_spi_send (bin2bcd (tmp->tm_hour)); /* Send Hour */
-       soft_spi_send (bin2bcd (tmp->tm_wday)); /* Send Day of the Week */
-       soft_spi_send (bin2bcd (tmp->tm_mday)); /* Send Day of Month */
-       soft_spi_send (bin2bcd (tmp->tm_mon));  /* Send Month */
-       soft_spi_send (bin2bcd (tmp->tm_year - 2000));  /* Send Year */
-
-       /* Now we can disable the Clock chip to terminate the burst write */
-       immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;   /* Disable DS1306 Chip */
-       udelay (10);
-
-       /* Now we can enable the Clock chip to initiate a new write */
-       immap->im_cpm.cp_pbdat |= PB_SPI_CE;    /* Enable DS1306 Chip */
-       udelay (10);
-
-       /* First we Enable write protect in the clock chip control register */
-       soft_spi_send (0x8F);   /* send address of the control register */
-       soft_spi_send (0x40);   /* send out Control Register contents */
-
-       /* Now disable the DS1306 */
-       immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;   /*  Disable DS1306 Chip */
-       udelay (10);
-
-       /* Set standard MPC8xx clock to the same time so Linux will
-        * see the time even if it doesn't have a DS1306 clock driver.
-        * This helps with experimenting with standard kernels.
-        */
-       {
-               ulong tim;
-
-               tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
-                             tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
-               immap->im_sitk.sitk_rtck = KAPWR_KEY;
-               immap->im_sit.sit_rtc = tim;
-       }
-
-       debug ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-              tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-              tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* Initialize Port B for software SPI */
-static void init_spi (void)
-{
-       volatile immap_t *immap = (immap_t *) CFG_IMMR;
-
-       /* Force output pins to begin at logic 0 */
-       immap->im_cpm.cp_pbdat &= ~(PB_SPI_CE | PB_SPIMOSI | PB_SPISCK);
-
-       /* Set these 3 signals as outputs */
-       immap->im_cpm.cp_pbdir |= (PB_SPIMOSI | PB_SPI_CE | PB_SPISCK);
-
-       immap->im_cpm.cp_pbdir &= ~PB_SPIMISO;  /* Make MISO pin an input */
-       udelay (10);
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* NOTE: soft_spi_send() assumes that the I/O lines are configured already */
-static void soft_spi_send (unsigned char n)
-{
-       volatile immap_t *immap = (immap_t *) CFG_IMMR;
-       unsigned char bitpos;   /* bit position to receive */
-       unsigned char i;        /* Loop Control */
-
-       /* bit position to send, start with most significant bit */
-       bitpos = 0x80;
-
-       /* Send 8 bits to software SPI */
-       for (i = 0; i < 8; i++) {       /* Loop for 8 bits */
-               immap->im_cpm.cp_pbdat |= PB_SPISCK;    /* Raise SCK */
-
-               if (n & bitpos)
-                       immap->im_cpm.cp_pbdat |= PB_SPIMOSI;   /* Set MOSI to 1 */
-               else
-                       immap->im_cpm.cp_pbdat &= ~PB_SPIMOSI;  /* Set MOSI to 0 */
-               udelay (10);
-
-               immap->im_cpm.cp_pbdat &= ~PB_SPISCK;   /* Lower SCK */
-               udelay (10);
-
-               bitpos >>= 1;   /* Shift for next bit position */
-       }
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* NOTE: soft_spi_read() assumes that the I/O lines are configured already */
-static unsigned char soft_spi_read (void)
-{
-       volatile immap_t *immap = (immap_t *) CFG_IMMR;
-
-       unsigned char spi_byte = 0;     /* Return value, assume success */
-       unsigned char bitpos;   /* bit position to receive */
-       unsigned char i;        /* Loop Control */
-
-       /* bit position to receive, start with most significant bit */
-       bitpos = 0x80;
-
-       /* Read 8 bits here */
-       for (i = 0; i < 8; i++) {       /* Do 8 bits in loop */
-               immap->im_cpm.cp_pbdat |= PB_SPISCK;    /* Raise SCK */
-               udelay (10);
-               if (immap->im_cpm.cp_pbdat & PB_SPIMISO)        /* Get a bit of data */
-                       spi_byte |= bitpos;     /* Set data accordingly */
-               immap->im_cpm.cp_pbdat &= ~PB_SPISCK;   /* Lower SCK */
-               udelay (10);
-               bitpos >>= 1;   /* Shift for next bit position */
-       }
-
-       return spi_byte;        /* Return the byte read */
-}
-
-/* ------------------------------------------------------------------------- */
-
-void rtc_reset (void)
-{
-       return;                 /* nothing to do */
-}
-
-#else  /* not CONFIG_SXNI855T */
-/* ************************************************************************* */
-
-static unsigned char rtc_read (unsigned char reg);
-static void rtc_write (unsigned char reg, unsigned char val);
-
-/* read clock time from DS1306 and return it in *tmp */
-void rtc_get (struct rtc_time *tmp)
-{
-       unsigned char sec, min, hour, mday, wday, mon, year;
-
-       sec = rtc_read (RTC_SECONDS);
-       min = rtc_read (RTC_MINUTES);
-       hour = rtc_read (RTC_HOURS);
-       mday = rtc_read (RTC_DATE_OF_MONTH);
-       wday = rtc_read (RTC_DAY_OF_WEEK);
-       mon = rtc_read (RTC_MONTH);
-       year = rtc_read (RTC_YEAR);
-
-       debug ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
-              "hr: %02x min: %02x sec: %02x\n",
-              year, mon, mday, wday, hour, min, sec);
-       debug ("Alarms[0]: wday: %02x hour: %02x min: %02x sec: %02x\n",
-              rtc_read (RTC_DAY_OF_WEEK_ALARM0),
-              rtc_read (RTC_HOURS_ALARM0),
-              rtc_read (RTC_MINUTES_ALARM0), rtc_read (RTC_SECONDS_ALARM0));
-       debug ("Alarms[1]: wday: %02x hour: %02x min: %02x sec: %02x\n",
-              rtc_read (RTC_DAY_OF_WEEK_ALARM1),
-              rtc_read (RTC_HOURS_ALARM1),
-              rtc_read (RTC_MINUTES_ALARM1), rtc_read (RTC_SECONDS_ALARM1));
-
-       tmp->tm_sec = bcd2bin (sec & 0x7F);     /* convert Seconds */
-       tmp->tm_min = bcd2bin (min & 0x7F);     /* convert Minutes */
-
-       /* convert Hours */
-       tmp->tm_hour = (hour & 0x40)
-               ? ((hour & 0x20)        /* 12 hour mode */
-                  ? bcd2bin (hour & 0x1F) + 11 /* PM */
-                  : bcd2bin (hour & 0x1F) - 1  /* AM */
-               )
-               : bcd2bin (hour & 0x3F);        /* 24 hour mode */
-
-       tmp->tm_mday = bcd2bin (mday & 0x3F);   /* convert Day of the Month */
-       tmp->tm_mon = bcd2bin (mon & 0x1F);     /* convert Month */
-       tmp->tm_year = bcd2bin (year) + 2000;   /* convert Year */
-       tmp->tm_wday = bcd2bin (wday & 0x07) - 1;       /* convert Day of the Week */
-       tmp->tm_yday = 0;
-       tmp->tm_isdst = 0;
-
-       debug ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-              tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-              tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* set clock time from *tmp in DS1306 RTC */
-void rtc_set (struct rtc_time *tmp)
-{
-       debug ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-              tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-              tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
-       rtc_write (RTC_SECONDS, bin2bcd (tmp->tm_sec));
-       rtc_write (RTC_MINUTES, bin2bcd (tmp->tm_min));
-       rtc_write (RTC_HOURS, bin2bcd (tmp->tm_hour));
-       rtc_write (RTC_DAY_OF_WEEK, bin2bcd (tmp->tm_wday + 1));
-       rtc_write (RTC_DATE_OF_MONTH, bin2bcd (tmp->tm_mday));
-       rtc_write (RTC_MONTH, bin2bcd (tmp->tm_mon));
-       rtc_write (RTC_YEAR, bin2bcd (tmp->tm_year - 2000));
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* reset the DS1306 */
-void rtc_reset (void)
-{
-       /* clear the control register */
-       rtc_write (RTC_CONTROL, 0x00);  /* 1st step: reset WP */
-       rtc_write (RTC_CONTROL, 0x00);  /* 2nd step: reset 1Hz, AIE1, AIE0 */
-
-       /* reset all alarms */
-       rtc_write (RTC_SECONDS_ALARM0, 0x00);
-       rtc_write (RTC_SECONDS_ALARM1, 0x00);
-       rtc_write (RTC_MINUTES_ALARM0, 0x00);
-       rtc_write (RTC_MINUTES_ALARM1, 0x00);
-       rtc_write (RTC_HOURS_ALARM0, 0x00);
-       rtc_write (RTC_HOURS_ALARM1, 0x00);
-       rtc_write (RTC_DAY_OF_WEEK_ALARM0, 0x00);
-       rtc_write (RTC_DAY_OF_WEEK_ALARM1, 0x00);
-}
-
-/* ------------------------------------------------------------------------- */
-
-static unsigned char rtc_read (unsigned char reg)
-{
-       unsigned char dout[2];  /* SPI Output Data Bytes */
-       unsigned char din[2];   /* SPI Input Data Bytes */
-
-       dout[0] = reg;
-
-       if (spi_xfer (spi_chipsel[CFG_SPI_RTC_DEVID], 16, dout, din) != 0) {
-               return 0;
-       } else {
-               return din[1];
-       }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void rtc_write (unsigned char reg, unsigned char val)
-{
-       unsigned char dout[2];  /* SPI Output Data Bytes */
-       unsigned char din[2];   /* SPI Input Data Bytes */
-
-       dout[0] = 0x80 | reg;
-       dout[1] = val;
-
-       spi_xfer (spi_chipsel[CFG_SPI_RTC_DEVID], 16, dout, din);
-}
-
-#endif /* end of code exclusion (see #ifdef CONFIG_SXNI855T above) */
-
-/* ------------------------------------------------------------------------- */
-
-static unsigned char bcd2bin (unsigned char n)
-{
-       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
-}
-
-/* ------------------------------------------------------------------------- */
-
-static unsigned int bin2bcd (unsigned int n)
-{
-       return (((n / 10) << 4) | (n % 10));
-}
-/* ------------------------------------------------------------------------- */
-
-#endif
diff --git a/rtc/ds1307.c b/rtc/ds1307.c
deleted file mode 100644 (file)
index c882d79..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * (C) Copyright 2001, 2002, 2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- * Keith Outwater, keith_outwater@mvis.com`
- * Steven Scholz, steven.scholz@imc-berlin.de
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
- * DS1307 and DS1338 Real Time Clock (RTC).
- *
- * based on ds1337.c
- */
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-#include <i2c.h>
-
-#if (defined(CONFIG_RTC_DS1307) || defined(CONFIG_RTC_DS1338) ) && \
-    defined(CONFIG_CMD_DATE)
-
-/*---------------------------------------------------------------------*/
-#undef DEBUG_RTC
-
-#ifdef DEBUG_RTC
-#define DEBUGR(fmt,args...) printf(fmt ,##args)
-#else
-#define DEBUGR(fmt,args...)
-#endif
-/*---------------------------------------------------------------------*/
-
-#ifndef CFG_I2C_RTC_ADDR
-# define CFG_I2C_RTC_ADDR      0x68
-#endif
-
-#if defined(CONFIG_RTC_DS1307) && (CFG_I2C_SPEED > 100000)
-# error The DS1307 is specified only up to 100kHz!
-#endif
-
-/*
- * RTC register addresses
- */
-#define RTC_SEC_REG_ADDR       0x00
-#define RTC_MIN_REG_ADDR       0x01
-#define RTC_HR_REG_ADDR                0x02
-#define RTC_DAY_REG_ADDR       0x03
-#define RTC_DATE_REG_ADDR      0x04
-#define RTC_MON_REG_ADDR       0x05
-#define RTC_YR_REG_ADDR                0x06
-#define RTC_CTL_REG_ADDR       0x07
-
-#define RTC_SEC_BIT_CH         0x80    /* Clock Halt (in Register 0)   */
-
-#define RTC_CTL_BIT_RS0                0x01    /* Rate select 0                */
-#define RTC_CTL_BIT_RS1                0x02    /* Rate select 1                */
-#define RTC_CTL_BIT_SQWE       0x10    /* Square Wave Enable           */
-#define RTC_CTL_BIT_OUT                0x80    /* Output Control               */
-
-static uchar rtc_read (uchar reg);
-static void rtc_write (uchar reg, uchar val);
-static uchar bin2bcd (unsigned int n);
-static unsigned bcd2bin (uchar c);
-
-/*
- * Get the current time from the RTC
- */
-void rtc_get (struct rtc_time *tmp)
-{
-       uchar sec, min, hour, mday, wday, mon, year;
-
-       sec = rtc_read (RTC_SEC_REG_ADDR);
-       min = rtc_read (RTC_MIN_REG_ADDR);
-       hour = rtc_read (RTC_HR_REG_ADDR);
-       wday = rtc_read (RTC_DAY_REG_ADDR);
-       mday = rtc_read (RTC_DATE_REG_ADDR);
-       mon = rtc_read (RTC_MON_REG_ADDR);
-       year = rtc_read (RTC_YR_REG_ADDR);
-
-       DEBUGR ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
-               "hr: %02x min: %02x sec: %02x\n",
-               year, mon, mday, wday, hour, min, sec);
-
-       if (sec & RTC_SEC_BIT_CH) {
-               printf ("### Warning: RTC oscillator has stopped\n");
-               /* clear the CH flag */
-               rtc_write (RTC_SEC_REG_ADDR,
-                          rtc_read (RTC_SEC_REG_ADDR) & ~RTC_SEC_BIT_CH);
-       }
-
-       tmp->tm_sec  = bcd2bin (sec & 0x7F);
-       tmp->tm_min  = bcd2bin (min & 0x7F);
-       tmp->tm_hour = bcd2bin (hour & 0x3F);
-       tmp->tm_mday = bcd2bin (mday & 0x3F);
-       tmp->tm_mon  = bcd2bin (mon & 0x1F);
-       tmp->tm_year = bcd2bin (year) + ( bcd2bin (year) >= 70 ? 1900 : 2000);
-       tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
-       tmp->tm_yday = 0;
-       tmp->tm_isdst= 0;
-
-       DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-}
-
-
-/*
- * Set the RTC
- */
-void rtc_set (struct rtc_time *tmp)
-{
-       DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
-       if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
-               printf("WARNING: year should be between 1970 and 2069!\n");
-
-       rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
-       rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon));
-       rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
-       rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
-       rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
-       rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
-       rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
-}
-
-
-/*
- * Reset the RTC. We setting the date back to 1970-01-01.
- * We also enable the oscillator output on the SQW/OUT pin and program
- * it for 32,768 Hz output. Note that according to the datasheet, turning
- * on the square wave output increases the current drain on the backup
- * battery to something between 480nA and 800nA.
- */
-void rtc_reset (void)
-{
-       struct rtc_time tmp;
-
-       rtc_write (RTC_SEC_REG_ADDR, 0x00);     /* clearing Clock Halt  */
-       rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_SQWE | RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS0);
-
-       tmp.tm_year = 1970;
-       tmp.tm_mon = 1;
-       tmp.tm_mday= 1;
-       tmp.tm_hour = 0;
-       tmp.tm_min = 0;
-       tmp.tm_sec = 0;
-
-       rtc_set(&tmp);
-
-       printf ( "RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC\n",
-               tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
-               tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
-
-       return;
-}
-
-
-/*
- * Helper functions
- */
-
-static
-uchar rtc_read (uchar reg)
-{
-       return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
-}
-
-
-static void rtc_write (uchar reg, uchar val)
-{
-       i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
-}
-
-static unsigned bcd2bin (uchar n)
-{
-       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
-}
-
-static unsigned char bin2bcd (unsigned int n)
-{
-       return (((n / 10) << 4) | (n % 10));
-}
-
-#endif
diff --git a/rtc/ds1337.c b/rtc/ds1337.c
deleted file mode 100644 (file)
index c636ac5..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * (C) Copyright 2001, 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- * Keith Outwater, keith_outwater@mvis.com`
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
- * DS1337 Real Time Clock (RTC).
- */
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-#include <i2c.h>
-
-#if defined(CONFIG_RTC_DS1337) && defined(CONFIG_CMD_DATE)
-
-/*---------------------------------------------------------------------*/
-#undef DEBUG_RTC
-
-#ifdef DEBUG_RTC
-#define DEBUGR(fmt,args...) printf(fmt ,##args)
-#else
-#define DEBUGR(fmt,args...)
-#endif
-/*---------------------------------------------------------------------*/
-
-/*
- * RTC register addresses
- */
-#define RTC_SEC_REG_ADDR       0x0
-#define RTC_MIN_REG_ADDR       0x1
-#define RTC_HR_REG_ADDR                0x2
-#define RTC_DAY_REG_ADDR       0x3
-#define RTC_DATE_REG_ADDR      0x4
-#define RTC_MON_REG_ADDR       0x5
-#define RTC_YR_REG_ADDR                0x6
-#define RTC_CTL_REG_ADDR       0x0e
-#define RTC_STAT_REG_ADDR      0x0f
-
-/*
- * RTC control register bits
- */
-#define RTC_CTL_BIT_A1IE       0x1     /* Alarm 1 interrupt enable     */
-#define RTC_CTL_BIT_A2IE       0x2     /* Alarm 2 interrupt enable     */
-#define RTC_CTL_BIT_INTCN      0x4     /* Interrupt control            */
-#define RTC_CTL_BIT_RS1                0x8     /* Rate select 1                */
-#define RTC_CTL_BIT_RS2                0x10    /* Rate select 2                */
-#define RTC_CTL_BIT_DOSC       0x80    /* Disable Oscillator           */
-
-/*
- * RTC status register bits
- */
-#define RTC_STAT_BIT_A1F       0x1     /* Alarm 1 flag                 */
-#define RTC_STAT_BIT_A2F       0x2     /* Alarm 2 flag                 */
-#define RTC_STAT_BIT_OSF       0x80    /* Oscillator stop flag         */
-
-
-static uchar rtc_read (uchar reg);
-static void rtc_write (uchar reg, uchar val);
-static uchar bin2bcd (unsigned int n);
-static unsigned bcd2bin (uchar c);
-
-
-/*
- * Get the current time from the RTC
- */
-void rtc_get (struct rtc_time *tmp)
-{
-       uchar sec, min, hour, mday, wday, mon_cent, year, control, status;
-
-       control = rtc_read (RTC_CTL_REG_ADDR);
-       status = rtc_read (RTC_STAT_REG_ADDR);
-       sec = rtc_read (RTC_SEC_REG_ADDR);
-       min = rtc_read (RTC_MIN_REG_ADDR);
-       hour = rtc_read (RTC_HR_REG_ADDR);
-       wday = rtc_read (RTC_DAY_REG_ADDR);
-       mday = rtc_read (RTC_DATE_REG_ADDR);
-       mon_cent = rtc_read (RTC_MON_REG_ADDR);
-       year = rtc_read (RTC_YR_REG_ADDR);
-
-       DEBUGR ("Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
-               "hr: %02x min: %02x sec: %02x control: %02x status: %02x\n",
-               year, mon_cent, mday, wday, hour, min, sec, control, status);
-
-       if (status & RTC_STAT_BIT_OSF) {
-               printf ("### Warning: RTC oscillator has stopped\n");
-               /* clear the OSF flag */
-               rtc_write (RTC_STAT_REG_ADDR,
-                          rtc_read (RTC_STAT_REG_ADDR) & ~RTC_STAT_BIT_OSF);
-       }
-
-       tmp->tm_sec  = bcd2bin (sec & 0x7F);
-       tmp->tm_min  = bcd2bin (min & 0x7F);
-       tmp->tm_hour = bcd2bin (hour & 0x3F);
-       tmp->tm_mday = bcd2bin (mday & 0x3F);
-       tmp->tm_mon  = bcd2bin (mon_cent & 0x1F);
-       tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900);
-       tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
-       tmp->tm_yday = 0;
-       tmp->tm_isdst= 0;
-
-       DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-}
-
-
-/*
- * Set the RTC
- */
-void rtc_set (struct rtc_time *tmp)
-{
-       uchar century;
-
-       DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
-       rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
-
-       century = (tmp->tm_year >= 2000) ? 0x80 : 0;
-       rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon) | century);
-
-       rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
-       rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
-       rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
-       rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
-       rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
-}
-
-
-/*
- * Reset the RTC.  We also enable the oscillator output on the
- * SQW/INTB* pin and program it for 32,768 Hz output. Note that
- * according to the datasheet, turning on the square wave output
- * increases the current drain on the backup battery from about
- * 600 nA to 2uA.
- */
-void rtc_reset (void)
-{
-       rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2);
-}
-
-
-/*
- * Helper functions
- */
-
-static
-uchar rtc_read (uchar reg)
-{
-       return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
-}
-
-
-static void rtc_write (uchar reg, uchar val)
-{
-       i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
-}
-
-static unsigned bcd2bin (uchar n)
-{
-       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
-}
-
-static unsigned char bin2bcd (unsigned int n)
-{
-       return (((n / 10) << 4) | (n % 10));
-}
-
-#endif
diff --git a/rtc/ds1374.c b/rtc/ds1374.c
deleted file mode 100644 (file)
index e773dd9..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * (C) Copyright 2001, 2002, 2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- * Keith Outwater, keith_outwater@mvis.com`
- * Steven Scholz, steven.scholz@imc-berlin.de
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
- * DS1374 Real Time Clock (RTC).
- *
- * based on ds1337.c
- */
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-#include <i2c.h>
-
-#if (defined(CONFIG_RTC_DS1374)) && defined(CONFIG_CMD_DATE)
-
-/*---------------------------------------------------------------------*/
-#undef DEBUG_RTC
-#define DEBUG_RTC
-
-#ifdef DEBUG_RTC
-#define DEBUGR(fmt,args...) printf(fmt ,##args)
-#else
-#define DEBUGR(fmt,args...)
-#endif
-/*---------------------------------------------------------------------*/
-
-#ifndef CFG_I2C_RTC_ADDR
-# define CFG_I2C_RTC_ADDR      0x68
-#endif
-
-#if defined(CONFIG_RTC_DS1374) && (CFG_I2C_SPEED > 400000)
-# error The DS1374 is specified up to 400kHz in fast mode!
-#endif
-
-/*
- * RTC register addresses
- */
-#define RTC_TOD_CNT_BYTE0_ADDR         0x00 /* TimeOfDay */
-#define RTC_TOD_CNT_BYTE1_ADDR         0x01
-#define RTC_TOD_CNT_BYTE2_ADDR         0x02
-#define RTC_TOD_CNT_BYTE3_ADDR         0x03
-
-#define RTC_WD_ALM_CNT_BYTE0_ADDR      0x04
-#define RTC_WD_ALM_CNT_BYTE1_ADDR      0x05
-#define RTC_WD_ALM_CNT_BYTE2_ADDR      0x06
-
-#define RTC_CTL_ADDR                   0x07 /* RTC-CoNTrol-register */
-#define RTC_SR_ADDR                    0x08 /* RTC-StatusRegister */
-#define RTC_TCS_DS_ADDR                        0x09 /* RTC-TrickleChargeSelect DiodeSelect-register */
-
-#define RTC_CTL_BIT_AIE                        (1<<0) /* Bit 0 - Alarm Interrupt enable */
-#define RTC_CTL_BIT_RS1                        (1<<1) /* Bit 1/2 - Rate Select square wave output */
-#define RTC_CTL_BIT_RS2                        (1<<2) /* Bit 2/2 - Rate Select square wave output */
-#define RTC_CTL_BIT_WDSTR              (1<<3) /* Bit 3 - Watchdog Reset Steering */
-#define RTC_CTL_BIT_BBSQW              (1<<4) /* Bit 4 - Battery-Backed Square-Wave */
-#define RTC_CTL_BIT_WD_ALM             (1<<5) /* Bit 5 - Watchdoc/Alarm Counter Select */
-#define RTC_CTL_BIT_WACE               (1<<6) /* Bit 6 - Watchdog/Alarm Counter Enable WACE*/
-#define RTC_CTL_BIT_EN_OSC             (1<<7) /* Bit 7 - Enable Oscilator */
-
-#define RTC_SR_BIT_AF                  0x01 /* Bit 0 = Alarm Flag */
-#define RTC_SR_BIT_OSF                 0x80 /* Bit 7 - Osc Stop Flag */
-
-typedef unsigned char boolean_t;
-
-#ifndef TRUE
-#define TRUE ((boolean_t)(0==0))
-#endif
-#ifndef FALSE
-#define FALSE (!TRUE)
-#endif
-
-const char RtcTodAddr[] = {
-       RTC_TOD_CNT_BYTE0_ADDR,
-       RTC_TOD_CNT_BYTE1_ADDR,
-       RTC_TOD_CNT_BYTE2_ADDR,
-       RTC_TOD_CNT_BYTE3_ADDR
-};
-
-static uchar rtc_read (uchar reg);
-static void rtc_write (uchar reg, uchar val, boolean_t set);
-static void rtc_write_raw (uchar reg, uchar val);
-
-/*
- * Get the current time from the RTC
- */
-void rtc_get (struct rtc_time *tm){
-
-       unsigned long time1, time2;
-       unsigned int limit;
-       unsigned char tmp;
-       unsigned int i;
-
-       /*
-        * Since the reads are being performed one byte at a time,
-        * there is a chance that a carry will occur during the read.
-        * To detect this, 2 reads are performed and compared.
-        */
-       limit = 10;
-       do {
-               i = 4;
-               time1 = 0;
-               while (i--) {
-                       tmp = rtc_read(RtcTodAddr[i]);
-                       time1 = (time1 << 8) | (tmp & 0xff);
-               }
-
-               i = 4;
-               time2 = 0;
-               while (i--) {
-                       tmp = rtc_read(RtcTodAddr[i]);
-                       time2 = (time2 << 8) | (tmp & 0xff);
-               }
-       } while ((time1 != time2) && limit--);
-
-       if (time1 != time2) {
-               printf("can't get consistent time from rtc chip\n");
-       }
-
-       DEBUGR ("Get RTC s since 1.1.1970: %d\n", time1);
-
-       to_tm(time1, tm); /* To Gregorian Date */
-
-       if (rtc_read(RTC_SR_ADDR) & RTC_SR_BIT_OSF)
-               printf ("### Warning: RTC oscillator has stopped\n");
-
-       DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
-               tm->tm_hour, tm->tm_min, tm->tm_sec);
-}
-
-/*
- * Set the RTC
- */
-void rtc_set (struct rtc_time *tmp){
-
-       unsigned long time;
-       unsigned i;
-
-       DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
-       if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
-               printf("WARNING: year should be between 1970 and 2069!\n");
-
-       time = mktime(tmp->tm_year, tmp->tm_mon,
-                       tmp->tm_mday, tmp->tm_hour,
-                       tmp->tm_min, tmp->tm_sec);
-
-       DEBUGR ("Set RTC s since 1.1.1970: %d (0x%02x)\n", time, time);
-
-       /* write to RTC_TOD_CNT_BYTEn_ADDR */
-       for (i = 0; i <= 3; i++) {
-               rtc_write_raw(RtcTodAddr[i], (unsigned char)(time & 0xff));
-               time = time >> 8;
-       }
-
-       /* Start clock */
-       rtc_write(RTC_CTL_ADDR, RTC_CTL_BIT_EN_OSC, FALSE);
-}
-
-/*
- * Reset the RTC. We setting the date back to 1970-01-01.
- * We also enable the oscillator output on the SQW/OUT pin and program
- * it for 32,768 Hz output. Note that according to the datasheet, turning
- * on the square wave output increases the current drain on the backup
- * battery to something between 480nA and 800nA.
- */
-void rtc_reset (void){
-
-       struct rtc_time tmp;
-
-       /* clear status flags */
-       rtc_write (RTC_SR_ADDR, (RTC_SR_BIT_AF|RTC_SR_BIT_OSF), FALSE); /* clearing OSF and AF */
-
-       /* Initialise DS1374 oriented to MPC8349E-ADS */
-       rtc_write (RTC_CTL_ADDR, (RTC_CTL_BIT_EN_OSC
-                                |RTC_CTL_BIT_WACE
-                                |RTC_CTL_BIT_AIE), FALSE);/* start osc, disable WACE, clear AIE
-                                                             - set to 0 */
-       rtc_write (RTC_CTL_ADDR, (RTC_CTL_BIT_WD_ALM
-                               |RTC_CTL_BIT_WDSTR
-                               |RTC_CTL_BIT_RS1
-                               |RTC_CTL_BIT_RS2
-                               |RTC_CTL_BIT_BBSQW), TRUE);/* disable WD/ALM, WDSTR set to INT-pin,
-                                                             set BBSQW and SQW to 32k
-                                                             - set to 1 */
-       tmp.tm_year = 1970;
-       tmp.tm_mon = 1;
-       tmp.tm_mday= 1;
-       tmp.tm_hour = 0;
-       tmp.tm_min = 0;
-       tmp.tm_sec = 0;
-
-       rtc_set(&tmp);
-
-       printf("RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC\n",
-               tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
-               tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
-
-       rtc_write(RTC_WD_ALM_CNT_BYTE2_ADDR,0xAC, TRUE);
-       rtc_write(RTC_WD_ALM_CNT_BYTE1_ADDR,0xDE, TRUE);
-       rtc_write(RTC_WD_ALM_CNT_BYTE2_ADDR,0xAD, TRUE);
-}
-
-/*
- * Helper functions
- */
-static uchar rtc_read (uchar reg)
-{
-       return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
-}
-
-static void rtc_write (uchar reg, uchar val, boolean_t set)
-{
-       if (set == TRUE) {
-               val |= i2c_reg_read (CFG_I2C_RTC_ADDR, reg);
-               i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
-       } else {
-               val = i2c_reg_read (CFG_I2C_RTC_ADDR, reg) & ~val;
-               i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
-       }
-}
-
-static void rtc_write_raw (uchar reg, uchar val)
-{
-               i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
-}
-#endif
diff --git a/rtc/ds1556.c b/rtc/ds1556.c
deleted file mode 100644 (file)
index 4365cfb..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * (C) Copyright 2002
- * ARIO Data Networks, Inc. dchiu@ariodata.com
- *
- * modified for DS1556:
- * Frank Panno <fpanno@delphintech.com>, Delphin Technology AG
- *
- * Based on MontaVista DS1743 code and U-Boot mc146818 code
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Date & Time support for the DS1556 RTC
- */
-
-/*#define      RTC_DEBUG */
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-
-
-#if defined(CONFIG_RTC_DS1556) && defined(CONFIG_CMD_DATE)
-
-static uchar rtc_read( unsigned int addr );
-static void  rtc_write( unsigned int addr, uchar val);
-static uchar bin2bcd   (unsigned int n);
-static unsigned bcd2bin(uchar c);
-
-#define RTC_BASE               ( CFG_NVRAM_SIZE + CFG_NVRAM_BASE_ADDR )
-
-#define RTC_YEAR               ( RTC_BASE + 0xf )
-#define RTC_MONTH              ( RTC_BASE + 0xe )
-#define RTC_DAY_OF_MONTH       ( RTC_BASE + 0xd )
-#define RTC_DAY_OF_WEEK                ( RTC_BASE + 0xc )
-#define RTC_HOURS              ( RTC_BASE + 0xb )
-#define RTC_MINUTES            ( RTC_BASE + 0xa )
-#define RTC_SECONDS            ( RTC_BASE + 0x9 )
-#define RTC_CENTURY            ( RTC_BASE + 0x8 )
-
-#define RTC_CONTROLA           RTC_CENTURY
-#define RTC_CONTROLB           RTC_SECONDS
-#define RTC_CONTROLC           RTC_BASE
-
-#define RTC_CA_WRITE           0x80
-#define RTC_CA_READ            0x40
-
-#define RTC_CB_OSC_DISABLE     0x80
-
-#define RTC_CC_BATTERY_FLAG    0x10
-#define RTC_CC_FREQ_TEST       0x40
-
-/* ------------------------------------------------------------------------- */
-
-void rtc_get( struct rtc_time *tmp )
-{
-       uchar sec, min, hour;
-       uchar mday, wday, mon, year;
-
-       int century;
-
-       uchar reg_a;
-
-       reg_a = rtc_read( RTC_CONTROLA );
-       /* lock clock registers for read */
-       rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
-
-       sec     = rtc_read( RTC_SECONDS );
-       min     = rtc_read( RTC_MINUTES );
-       hour    = rtc_read( RTC_HOURS );
-       mday    = rtc_read( RTC_DAY_OF_MONTH );
-       wday    = rtc_read( RTC_DAY_OF_WEEK );
-       mon     = rtc_read( RTC_MONTH );
-       year    = rtc_read( RTC_YEAR );
-       century = rtc_read( RTC_CENTURY );
-
-       /* unlock clock registers after read */
-       rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
-
-#ifdef RTC_DEBUG
-       printf( "Get RTC year: %02x mon/cent: %02x mon: %02x mday: %02x wday: %02x "
-               "hr: %02x min: %02x sec: %02x\n",
-               year, century, mon, mday, wday,
-               hour, min, sec );
-#endif
-       tmp->tm_sec  = bcd2bin( sec  & 0x7F );
-       tmp->tm_min  = bcd2bin( min  & 0x7F );
-       tmp->tm_hour = bcd2bin( hour & 0x3F );
-       tmp->tm_mday = bcd2bin( mday & 0x3F );
-       tmp->tm_mon  = bcd2bin( mon & 0x1F );
-       tmp->tm_wday = bcd2bin( wday & 0x07 );
-
-       /* glue year from century and year in century */
-       tmp->tm_year = bcd2bin( year ) +
-               ( bcd2bin( century & 0x3F ) * 100 );
-
-       tmp->tm_yday = 0;
-       tmp->tm_isdst= 0;
-#ifdef RTC_DEBUG
-       printf( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
-#endif
-}
-
-void rtc_set( struct rtc_time *tmp )
-{
-       uchar reg_a;
-#ifdef RTC_DEBUG
-       printf( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-#endif
-       /* lock clock registers for write */
-       reg_a = rtc_read( RTC_CONTROLA );
-       rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
-
-       rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
-
-       rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
-       rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
-       rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
-       rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
-       rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
-
-       /* break year up into century and year in century */
-       rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
-       rtc_write( RTC_CENTURY, bin2bcd( tmp->tm_year / 100 ));
-
-       /* unlock clock registers after read */
-       rtc_write( RTC_CONTROLA, ( reg_a  & ~RTC_CA_WRITE ));
-}
-
-void rtc_reset (void)
-{
-       uchar reg_a, reg_b, reg_c;
-
-       reg_a = rtc_read( RTC_CONTROLA );
-       reg_b = rtc_read( RTC_CONTROLB );
-
-       if ( reg_b & RTC_CB_OSC_DISABLE )
-       {
-               printf( "real-time-clock was stopped. Now starting...\n" );
-               reg_a |= RTC_CA_WRITE;
-               reg_b &= ~RTC_CB_OSC_DISABLE;
-
-               rtc_write( RTC_CONTROLA, reg_a );
-               rtc_write( RTC_CONTROLB, reg_b );
-       }
-
-       /* make sure read/write clock register bits are cleared */
-       reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
-       rtc_write( RTC_CONTROLA, reg_a );
-
-       reg_c = rtc_read( RTC_CONTROLC );
-       if (( reg_c & RTC_CC_BATTERY_FLAG ) == 0 )
-               printf( "RTC battery low. Clock setting may not be reliable.\n" );
-}
-
-/* ------------------------------------------------------------------------- */
-
-static uchar rtc_read( unsigned int addr )
-{
-       uchar val = *(volatile unsigned char*)(addr);
-#ifdef RTC_DEBUG
-       printf( "rtc_read: %x:%x\n", addr, val );
-#endif
-       return( val );
-}
-
-static void rtc_write( unsigned int addr, uchar val )
-{
-#ifdef RTC_DEBUG
-       printf( "rtc_write: %x:%x\n", addr, val );
-#endif
-       *(volatile unsigned char*)(addr) = val;
-}
-
-static unsigned bcd2bin (uchar n)
-{
-       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
-}
-
-static unsigned char bin2bcd (unsigned int n)
-{
-       return (((n / 10) << 4) | (n % 10));
-}
-
-#endif
diff --git a/rtc/ds164x.c b/rtc/ds164x.c
deleted file mode 100644 (file)
index bff22b9..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * (C) Copyright 2002
- * ARIO Data Networks, Inc. dchiu@ariodata.com
- *
- * modified for DS164x:
- * The LEOX team <team@leox.org>, http://www.leox.org
- *
- * Based on MontaVista DS1743 code and U-Boot mc146818 code
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Date & Time support for the DS164x RTC
- */
-
-/* #define     RTC_DEBUG */
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-
-
-#if defined(CONFIG_RTC_DS164x) && defined(CONFIG_CMD_DATE)
-
-static uchar    rtc_read(unsigned int addr );
-static void     rtc_write(unsigned int addr, uchar val);
-static uchar    bin2bcd(unsigned int n);
-static unsigned bcd2bin(uchar c);
-
-#define RTC_EPOCH                 2000 /* century */
-
-/*
- * DS164x registers layout
- */
-#define RTC_BASE               ( CFG_NVRAM_BASE_ADDR + CFG_NVRAM_SIZE )
-
-#define RTC_YEAR               ( RTC_BASE + 0x07 )
-#define RTC_MONTH              ( RTC_BASE + 0x06 )
-#define RTC_DAY_OF_MONTH       ( RTC_BASE + 0x05 )
-#define RTC_DAY_OF_WEEK                ( RTC_BASE + 0x04 )
-#define RTC_HOURS              ( RTC_BASE + 0x03 )
-#define RTC_MINUTES            ( RTC_BASE + 0x02 )
-#define RTC_SECONDS            ( RTC_BASE + 0x01 )
-#define RTC_CONTROL            ( RTC_BASE + 0x00 )
-
-#define RTC_CONTROLA           RTC_CONTROL     /* W=bit6, R=bit5 */
-#define   RTC_CA_WRITE           0x80
-#define   RTC_CA_READ            0x40
-#define RTC_CONTROLB           RTC_SECONDS     /* OSC=bit7       */
-#define   RTC_CB_OSC_DISABLE     0x80
-#define RTC_CONTROLC           RTC_DAY_OF_WEEK /* FT=bit6        */
-#define   RTC_CC_FREQ_TEST       0x40
-
-/* ------------------------------------------------------------------------- */
-
-void rtc_get( struct rtc_time *tmp )
-{
-       uchar sec, min, hour;
-       uchar mday, wday, mon, year;
-
-       uchar reg_a;
-
-       reg_a = rtc_read( RTC_CONTROLA );
-       /* lock clock registers for read */
-       rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
-
-       sec     = rtc_read( RTC_SECONDS );
-       min     = rtc_read( RTC_MINUTES );
-       hour    = rtc_read( RTC_HOURS );
-       mday    = rtc_read( RTC_DAY_OF_MONTH );
-       wday    = rtc_read( RTC_DAY_OF_WEEK );
-       mon     = rtc_read( RTC_MONTH );
-       year    = rtc_read( RTC_YEAR );
-
-       /* unlock clock registers after read */
-       rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
-
-#ifdef RTC_DEBUG
-       printf( "Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
-               "hr: %02x min: %02x sec: %02x\n",
-               year, mon, mday, wday,
-               hour, min, sec );
-#endif
-       tmp->tm_sec  = bcd2bin( sec  & 0x7F );
-       tmp->tm_min  = bcd2bin( min  & 0x7F );
-       tmp->tm_hour = bcd2bin( hour & 0x3F );
-       tmp->tm_mday = bcd2bin( mday & 0x3F );
-       tmp->tm_mon  = bcd2bin( mon  & 0x1F );
-       tmp->tm_wday = bcd2bin( wday & 0x07 );
-
-       /* glue year in century (2000) */
-       tmp->tm_year = bcd2bin( year ) + RTC_EPOCH;
-
-       tmp->tm_yday = 0;
-       tmp->tm_isdst= 0;
-#ifdef RTC_DEBUG
-       printf( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
-#endif
-}
-
-void rtc_set( struct rtc_time *tmp )
-{
-       uchar reg_a;
-
-#ifdef RTC_DEBUG
-       printf( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-#endif
-       /* lock clock registers for write */
-       reg_a = rtc_read( RTC_CONTROLA );
-       rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
-
-       rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
-
-       rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
-       rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
-       rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
-       rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
-       rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
-
-       /* break year in century */
-       rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
-
-       /* unlock clock registers after read */
-       rtc_write( RTC_CONTROLA, ( reg_a  & ~RTC_CA_WRITE ));
-}
-
-void rtc_reset (void)
-{
-       uchar reg_a, reg_b;
-
-       reg_a = rtc_read( RTC_CONTROLA );
-       reg_b = rtc_read( RTC_CONTROLB );
-
-       if ( reg_b & RTC_CB_OSC_DISABLE )
-       {
-               printf( "real-time-clock was stopped. Now starting...\n" );
-               reg_a |= RTC_CA_WRITE;
-               reg_b &= ~RTC_CB_OSC_DISABLE;
-
-               rtc_write( RTC_CONTROLA, reg_a );
-               rtc_write( RTC_CONTROLB, reg_b );
-       }
-
-       /* make sure read/write clock register bits are cleared */
-       reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
-       rtc_write( RTC_CONTROLA, reg_a );
-}
-
-/* ------------------------------------------------------------------------- */
-
-static uchar rtc_read( unsigned int addr )
-{
-       uchar val = *(volatile unsigned char*)(addr);
-
-#ifdef RTC_DEBUG
-       printf( "rtc_read: %x:%x\n", addr, val );
-#endif
-       return( val );
-}
-
-static void rtc_write( unsigned int addr, uchar val )
-{
-#ifdef RTC_DEBUG
-       printf( "rtc_write: %x:%x\n", addr, val );
-#endif
-       *(volatile unsigned char*)(addr) = val;
-}
-
-static unsigned bcd2bin (uchar n)
-{
-       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
-}
-
-static unsigned char bin2bcd (unsigned int n)
-{
-       return (((n / 10) << 4) | (n % 10));
-}
-
-#endif
diff --git a/rtc/ds174x.c b/rtc/ds174x.c
deleted file mode 100644 (file)
index 5f85a68..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * (C) Copyright 2001
- * ARIO Data Networks, Inc. dchiu@ariodata.com
- *
- * Based on MontaVista DS1743 code and U-Boot mc146818 code
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Date & Time support for the DS174x RTC
- */
-
-/*#define      DEBUG*/
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-
-#if defined(CONFIG_RTC_DS174x) && defined(CONFIG_CMD_DATE)
-
-static uchar rtc_read( unsigned int addr );
-static void  rtc_write( unsigned int addr, uchar val);
-static uchar bin2bcd   (unsigned int n);
-static unsigned bcd2bin(uchar c);
-
-#define RTC_BASE               ( CFG_NVRAM_SIZE + CFG_NVRAM_BASE_ADDR )
-
-#define RTC_YEAR               ( RTC_BASE + 7 )
-#define RTC_MONTH              ( RTC_BASE + 6 )
-#define RTC_DAY_OF_MONTH       ( RTC_BASE + 5 )
-#define RTC_DAY_OF_WEEK                ( RTC_BASE + 4 )
-#define RTC_HOURS              ( RTC_BASE + 3 )
-#define RTC_MINUTES            ( RTC_BASE + 2 )
-#define RTC_SECONDS            ( RTC_BASE + 1 )
-#define RTC_CENTURY            ( RTC_BASE + 0 )
-
-#define RTC_CONTROLA           RTC_CENTURY
-#define RTC_CONTROLB           RTC_SECONDS
-#define RTC_CONTROLC           RTC_DAY_OF_WEEK
-
-#define RTC_CA_WRITE           0x80
-#define RTC_CA_READ            0x40
-
-#define RTC_CB_OSC_DISABLE     0x80
-
-#define RTC_CC_BATTERY_FLAG    0x80
-#define RTC_CC_FREQ_TEST       0x40
-
-/* ------------------------------------------------------------------------- */
-
-void rtc_get( struct rtc_time *tmp )
-{
-       uchar sec, min, hour;
-       uchar mday, wday, mon, year;
-
-       int century;
-
-       uchar reg_a;
-
-       reg_a = rtc_read( RTC_CONTROLA );
-       /* lock clock registers for read */
-       rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
-
-       sec     = rtc_read( RTC_SECONDS );
-       min     = rtc_read( RTC_MINUTES );
-       hour    = rtc_read( RTC_HOURS );
-       mday    = rtc_read( RTC_DAY_OF_MONTH );
-       wday    = rtc_read( RTC_DAY_OF_WEEK );
-       mon     = rtc_read( RTC_MONTH );
-       year    = rtc_read( RTC_YEAR );
-       century = rtc_read( RTC_CENTURY );
-
-       /* unlock clock registers after read */
-       rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
-
-#ifdef RTC_DEBUG
-       printf( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
-               "hr: %02x min: %02x sec: %02x\n",
-               year, mon_cent, mday, wday,
-               hour, min, sec );
-#endif
-       tmp->tm_sec  = bcd2bin( sec  & 0x7F );
-       tmp->tm_min  = bcd2bin( min  & 0x7F );
-       tmp->tm_hour = bcd2bin( hour & 0x3F );
-       tmp->tm_mday = bcd2bin( mday & 0x3F );
-       tmp->tm_mon  = bcd2bin( mon & 0x1F );
-       tmp->tm_wday = bcd2bin( wday & 0x07 );
-
-       /* glue year from century and year in century */
-       tmp->tm_year = bcd2bin( year ) +
-               ( bcd2bin( century & 0x3F ) * 100 );
-
-       tmp->tm_yday = 0;
-       tmp->tm_isdst= 0;
-#ifdef RTC_DEBUG
-       printf( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
-#endif
-}
-
-void rtc_set( struct rtc_time *tmp )
-{
-       uchar reg_a;
-#ifdef RTC_DEBUG
-       printf( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-#endif
-       /* lock clock registers for write */
-       reg_a = rtc_read( RTC_CONTROLA );
-       rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
-
-       rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
-
-       rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
-       rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
-       rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
-       rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
-       rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
-
-       /* break year up into century and year in century */
-       rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
-       rtc_write( RTC_CENTURY, bin2bcd( tmp->tm_year / 100 ));
-
-       /* unlock clock registers after read */
-       rtc_write( RTC_CONTROLA, ( reg_a  & ~RTC_CA_WRITE ));
-}
-
-void rtc_reset (void)
-{
-       uchar reg_a, reg_b, reg_c;
-
-       reg_a = rtc_read( RTC_CONTROLA );
-       reg_b = rtc_read( RTC_CONTROLB );
-
-       if ( reg_b & RTC_CB_OSC_DISABLE )
-       {
-               printf( "real-time-clock was stopped. Now starting...\n" );
-               reg_a |= RTC_CA_WRITE;
-               reg_b &= ~RTC_CB_OSC_DISABLE;
-
-               rtc_write( RTC_CONTROLA, reg_a );
-               rtc_write( RTC_CONTROLB, reg_b );
-       }
-
-       /* make sure read/write clock register bits are cleared */
-       reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
-       rtc_write( RTC_CONTROLA, reg_a );
-
-       reg_c = rtc_read( RTC_CONTROLC );
-       if (( reg_c & RTC_CC_BATTERY_FLAG ) == 0 )
-               printf( "RTC battery low. Clock setting may not be reliable.\n" );
-}
-
-/* ------------------------------------------------------------------------- */
-
-static uchar rtc_read( unsigned int addr )
-{
-       uchar val = in8( addr );
-#ifdef RTC_DEBUG
-       printf( "rtc_read: %x:%x\n", addr, val );
-#endif
-       return( val );
-}
-
-static void rtc_write( unsigned int addr, uchar val )
-{
-#ifdef RTC_DEBUG
-       printf( "rtc_write: %x:%x\n", addr, val );
-#endif
-       out8( addr, val );
-}
-
-static unsigned bcd2bin (uchar n)
-{
-       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
-}
-
-static unsigned char bin2bcd (unsigned int n)
-{
-       return (((n / 10) << 4) | (n % 10));
-}
-
-#endif
diff --git a/rtc/ds3231.c b/rtc/ds3231.c
deleted file mode 100644 (file)
index fe11b86..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * (C) Copyright 2006
- * Markus Klotzbuecher, mk@denx.de
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
- * Extremly Accurate DS3231 Real Time Clock (RTC).
- *
- * copied from ds1337.c
- */
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-#include <i2c.h>
-
-#if defined(CONFIG_RTC_DS3231) && defined(CONFIG_CMD_DATE)
-
-/*---------------------------------------------------------------------*/
-#undef DEBUG_RTC
-
-#ifdef DEBUG_RTC
-#define DEBUGR(fmt,args...) printf(fmt ,##args)
-#else
-#define DEBUGR(fmt,args...)
-#endif
-/*---------------------------------------------------------------------*/
-
-/*
- * RTC register addresses
- */
-#define RTC_SEC_REG_ADDR       0x0
-#define RTC_MIN_REG_ADDR       0x1
-#define RTC_HR_REG_ADDR                0x2
-#define RTC_DAY_REG_ADDR       0x3
-#define RTC_DATE_REG_ADDR      0x4
-#define RTC_MON_REG_ADDR       0x5
-#define RTC_YR_REG_ADDR                0x6
-#define RTC_CTL_REG_ADDR       0x0e
-#define RTC_STAT_REG_ADDR      0x0f
-
-
-/*
- * RTC control register bits
- */
-#define RTC_CTL_BIT_A1IE       0x1     /* Alarm 1 interrupt enable     */
-#define RTC_CTL_BIT_A2IE       0x2     /* Alarm 2 interrupt enable     */
-#define RTC_CTL_BIT_INTCN      0x4     /* Interrupt control            */
-#define RTC_CTL_BIT_RS1                0x8     /* Rate select 1                */
-#define RTC_CTL_BIT_RS2                0x10    /* Rate select 2                */
-#define RTC_CTL_BIT_DOSC       0x80    /* Disable Oscillator           */
-
-/*
- * RTC status register bits
- */
-#define RTC_STAT_BIT_A1F       0x1     /* Alarm 1 flag                 */
-#define RTC_STAT_BIT_A2F       0x2     /* Alarm 2 flag                 */
-#define RTC_STAT_BIT_OSF       0x80    /* Oscillator stop flag         */
-
-
-static uchar rtc_read (uchar reg);
-static void rtc_write (uchar reg, uchar val);
-static uchar bin2bcd (unsigned int n);
-static unsigned bcd2bin (uchar c);
-
-
-/*
- * Get the current time from the RTC
- */
-void rtc_get (struct rtc_time *tmp)
-{
-       uchar sec, min, hour, mday, wday, mon_cent, year, control, status;
-
-       control = rtc_read (RTC_CTL_REG_ADDR);
-       status = rtc_read (RTC_STAT_REG_ADDR);
-       sec = rtc_read (RTC_SEC_REG_ADDR);
-       min = rtc_read (RTC_MIN_REG_ADDR);
-       hour = rtc_read (RTC_HR_REG_ADDR);
-       wday = rtc_read (RTC_DAY_REG_ADDR);
-       mday = rtc_read (RTC_DATE_REG_ADDR);
-       mon_cent = rtc_read (RTC_MON_REG_ADDR);
-       year = rtc_read (RTC_YR_REG_ADDR);
-
-       DEBUGR ("Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
-               "hr: %02x min: %02x sec: %02x control: %02x status: %02x\n",
-               year, mon_cent, mday, wday, hour, min, sec, control, status);
-
-       if (status & RTC_STAT_BIT_OSF) {
-               printf ("### Warning: RTC oscillator has stopped\n");
-               /* clear the OSF flag */
-               rtc_write (RTC_STAT_REG_ADDR,
-                          rtc_read (RTC_STAT_REG_ADDR) & ~RTC_STAT_BIT_OSF);
-       }
-
-       tmp->tm_sec  = bcd2bin (sec & 0x7F);
-       tmp->tm_min  = bcd2bin (min & 0x7F);
-       tmp->tm_hour = bcd2bin (hour & 0x3F);
-       tmp->tm_mday = bcd2bin (mday & 0x3F);
-       tmp->tm_mon  = bcd2bin (mon_cent & 0x1F);
-       tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900);
-       tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
-       tmp->tm_yday = 0;
-       tmp->tm_isdst= 0;
-
-       DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-}
-
-
-/*
- * Set the RTC
- */
-void rtc_set (struct rtc_time *tmp)
-{
-       uchar century;
-
-       DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
-       rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
-
-       century = (tmp->tm_year >= 2000) ? 0x80 : 0;
-       rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon) | century);
-
-       rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
-       rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
-       rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
-       rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
-       rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
-}
-
-
-/*
- * Reset the RTC.  We also enable the oscillator output on the
- * SQW/INTB* pin and program it for 32,768 Hz output. Note that
- * according to the datasheet, turning on the square wave output
- * increases the current drain on the backup battery from about
- * 600 nA to 2uA.
- */
-void rtc_reset (void)
-{
-       rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2);
-}
-
-
-/*
- * Helper functions
- */
-
-static
-uchar rtc_read (uchar reg)
-{
-       return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
-}
-
-
-static void rtc_write (uchar reg, uchar val)
-{
-       i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
-}
-
-static unsigned bcd2bin (uchar n)
-{
-       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
-}
-
-static unsigned char bin2bcd (unsigned int n)
-{
-       return (((n / 10) << 4) | (n % 10));
-}
-
-#endif
diff --git a/rtc/m41t11.c b/rtc/m41t11.c
deleted file mode 100644 (file)
index 81da33a..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * (C) Copyright 2002
- * Andrew May, Viasat Inc, amay@viasat.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * M41T11 Serial Access Timekeeper(R) SRAM
- * can you believe a trademark on that?
- */
-
-/* #define DEBUG 1 */
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-#include <i2c.h>
-
-/*
-       I Don't have an example config file but this
-       is what should be done.
-
-#define CONFIG_RTC_M41T11 1
-#define CFG_I2C_RTC_ADDR 0x68
-#if 0
-#define CFG_M41T11_EXT_CENTURY_DATA
-#else
-#define CFG_M41T11_BASE_YEAR 2000
-#endif
-*/
-
-#if defined(CONFIG_RTC_M41T11) && defined(CFG_I2C_RTC_ADDR) && defined(CONFIG_CMD_DATE)
-
-static unsigned bcd2bin (uchar n)
-{
-       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
-}
-
-static unsigned char bin2bcd (unsigned int n)
-{
-       return (((n / 10) << 4) | (n % 10));
-}
-
-
-/* ------------------------------------------------------------------------- */
-/*
-  these are simple defines for the chip local to here so they aren't too
-  verbose
-  DAY/DATE aren't nice but that is how they are on the data sheet
-*/
-#define RTC_SEC_ADDR       0x0
-#define RTC_MIN_ADDR       0x1
-#define RTC_HOUR_ADDR      0x2
-#define RTC_DAY_ADDR       0x3
-#define RTC_DATE_ADDR      0x4
-#define RTC_MONTH_ADDR     0x5
-#define RTC_YEARS_ADDR     0x6
-
-#define RTC_REG_CNT        7
-
-#define RTC_CONTROL_ADDR   0x7
-
-
-#ifndef CFG_M41T11_EXT_CENTURY_DATA
-
-#define REG_CNT            (RTC_REG_CNT+1)
-
-/*
-  you only get 00-99 for the year we will asume you
-  want from the year 2000 if you don't set the config
-*/
-#ifndef CFG_M41T11_BASE_YEAR
-#define CFG_M41T11_BASE_YEAR 2000
-#endif
-
-#else
-/* we will store extra year info in byte 9*/
-#define M41T11_YEAR_DATA   0x8
-#define M41T11_YEAR_SIZE   1
-#define REG_CNT            (RTC_REG_CNT+1+M41T11_YEAR_SIZE)
-#endif
-
-#define M41T11_STORAGE_SZ  (64-REG_CNT)
-
-void rtc_get (struct rtc_time *tmp)
-{
-       uchar data[RTC_REG_CNT];
-
-       i2c_read(CFG_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, data, RTC_REG_CNT);
-
-       if( data[RTC_SEC_ADDR] & 0x80 ){
-               printf( "m41t11 RTC Clock stopped!!!\n" );
-       }
-       tmp->tm_sec  = bcd2bin (data[RTC_SEC_ADDR]  & 0x7F);
-       tmp->tm_min  = bcd2bin (data[RTC_MIN_ADDR]  & 0x7F);
-       tmp->tm_hour = bcd2bin (data[RTC_HOUR_ADDR] & 0x3F);
-       tmp->tm_mday = bcd2bin (data[RTC_DATE_ADDR] & 0x3F);
-       tmp->tm_mon  = bcd2bin (data[RTC_MONTH_ADDR]& 0x1F);
-#ifndef CFG_M41T11_EXT_CENTURY_DATA
-       tmp->tm_year = CFG_M41T11_BASE_YEAR
-               + bcd2bin(data[RTC_YEARS_ADDR])
-               + ((data[RTC_HOUR_ADDR]&0x40) ? 100 : 0);
-#else
-       {
-               unsigned char cent;
-               i2c_read(CFG_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, &cent, M41T11_YEAR_SIZE);
-               if( !(data[RTC_HOUR_ADDR] & 0x80) ){
-                       printf( "m41t11 RTC: cann't keep track of years without CEB set\n" );
-               }
-               if( (cent & 0x1) != ((data[RTC_HOUR_ADDR]&0x40)>>7) ){
-                       /*century flip store off new year*/
-                       cent += 1;
-                       i2c_write(CFG_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, &cent, M41T11_YEAR_SIZE);
-               }
-               tmp->tm_year =((int)cent*100)+bcd2bin(data[RTC_YEARS_ADDR]);
-       }
-#endif
-       tmp->tm_wday = bcd2bin (data[RTC_DAY_ADDR]  & 0x07);
-       tmp->tm_yday = 0;
-       tmp->tm_isdst= 0;
-
-       debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-}
-
-void rtc_set (struct rtc_time *tmp)
-{
-       uchar data[RTC_REG_CNT];
-
-       debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
-       data[RTC_SEC_ADDR]    = bin2bcd(tmp->tm_sec) &  0x7F;/*just in case*/
-       data[RTC_MIN_ADDR]    = bin2bcd(tmp->tm_min);
-       data[RTC_HOUR_ADDR]   = bin2bcd(tmp->tm_hour) & 0x3F;/*handle cent stuff later*/
-       data[RTC_DATE_ADDR]   = bin2bcd(tmp->tm_mday) & 0x3F;
-       data[RTC_MONTH_ADDR]  = bin2bcd(tmp->tm_mon);
-       data[RTC_DAY_ADDR]    = bin2bcd(tmp->tm_wday) & 0x07;
-
-       data[RTC_HOUR_ADDR]   |= 0x80;/*we will always use CEB*/
-
-       data[RTC_YEARS_ADDR]  = bin2bcd(tmp->tm_year%100);/*same thing either way*/
-#ifndef CFG_M41T11_EXT_CENTURY_DATA
-       if( ((tmp->tm_year - CFG_M41T11_BASE_YEAR) > 200) ||
-           (tmp->tm_year < CFG_M41T11_BASE_YEAR) ){
-               printf( "m41t11 RTC setting year out of range!!need recompile\n" );
-       }
-       data[RTC_HOUR_ADDR] |= (tmp->tm_year - CFG_M41T11_BASE_YEAR) > 100 ? 0x40 : 0;
-#else
-       {
-               unsigned char cent;
-               cent = tmp->tm_year ? tmp->tm_year / 100 : 0;
-               data[RTC_HOUR_ADDR] |= (cent & 0x1) ? 0x40 : 0;
-               i2c_write(CFG_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, &cent, M41T11_YEAR_SIZE);
-       }
-#endif
-       i2c_write(CFG_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, data, RTC_REG_CNT);
-}
-
-void rtc_reset (void)
-{
-       unsigned char val;
-       /* clear all control & status registers */
-       i2c_read(CFG_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, &val, 1);
-       val = val & 0x7F;/*make sure we are running*/
-       i2c_write(CFG_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, &val, RTC_REG_CNT);
-
-       i2c_read(CFG_I2C_RTC_ADDR, RTC_CONTROL_ADDR, 1, &val, 1);
-       val = val & 0x3F;/*turn off freq test keep calibration*/
-       i2c_write(CFG_I2C_RTC_ADDR, RTC_CONTROL_ADDR, 1, &val, 1);
-}
-
-int rtc_store(int addr, unsigned char* data, int size)
-{
-       /*don't let things wrap onto the time on a write*/
-       if( (addr+size) >= M41T11_STORAGE_SZ )
-               return 1;
-       return i2c_write( CFG_I2C_RTC_ADDR, REG_CNT+addr, 1, data, size );
-}
-
-int rtc_recall(int addr, unsigned char* data, int size)
-{
-       return i2c_read( CFG_I2C_RTC_ADDR, REG_CNT+addr, 1, data, size );
-}
-
-#endif
diff --git a/rtc/m48t35ax.c b/rtc/m48t35ax.c
deleted file mode 100644 (file)
index 0a0ffa8..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * (C) Copyright 2001
- * Erik Theisen,  Wave 7 Optics, etheisen@mindspring.com.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Date & Time support for ST Electronics M48T35Ax RTC
- */
-
-/*#define       DEBUG */
-
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-#include <config.h>
-
-#if defined(CONFIG_RTC_M48T35A) && defined(CONFIG_CMD_DATE)
-
-static uchar rtc_read  (uchar reg);
-static void  rtc_write (uchar reg, uchar val);
-static uchar bin2bcd   (unsigned int n);
-static unsigned bcd2bin(uchar c);
-
-/* ------------------------------------------------------------------------- */
-
-void rtc_get (struct rtc_time *tmp)
-{
-       uchar sec, min, hour, cent_day, date, month, year;
-       uchar ccr;                      /* Clock control register */
-
-       /* Lock RTC for read using clock control register */
-       ccr = rtc_read(0);
-       ccr = ccr | 0x40;
-       rtc_write(0, ccr);
-
-       sec     = rtc_read (0x1);
-       min     = rtc_read (0x2);
-       hour    = rtc_read (0x3);
-       cent_day= rtc_read (0x4);
-       date    = rtc_read (0x5);
-       month   = rtc_read (0x6);
-       year    = rtc_read (0x7);
-
-       /* UNLock RTC */
-       ccr = rtc_read(0);
-       ccr = ccr & 0xBF;
-       rtc_write(0, ccr);
-
-       debug ( "Get RTC year: %02x month: %02x date: %02x cent_day: %02x "
-               "hr: %02x min: %02x sec: %02x\n",
-               year, month, date, cent_day,
-               hour, min, sec );
-
-       tmp->tm_sec  = bcd2bin (sec  & 0x7F);
-       tmp->tm_min  = bcd2bin (min  & 0x7F);
-       tmp->tm_hour = bcd2bin (hour & 0x3F);
-       tmp->tm_mday = bcd2bin (date & 0x3F);
-       tmp->tm_mon  = bcd2bin (month & 0x1F);
-       tmp->tm_year = bcd2bin (year) + ((cent_day & 0x10) ? 2000 : 1900);
-       tmp->tm_wday = bcd2bin (cent_day & 0x07);
-       tmp->tm_yday = 0;
-       tmp->tm_isdst= 0;
-
-       debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-}
-
-void rtc_set (struct rtc_time *tmp)
-{
-       uchar ccr;                      /* Clock control register */
-       uchar century;
-
-       debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
-       /* Lock RTC for write using clock control register */
-       ccr = rtc_read(0);
-       ccr = ccr | 0x80;
-       rtc_write(0, ccr);
-
-       rtc_write (0x07, bin2bcd(tmp->tm_year % 100));
-       rtc_write (0x06, bin2bcd(tmp->tm_mon));
-       rtc_write (0x05, bin2bcd(tmp->tm_mday));
-
-       century = ((tmp->tm_year >= 2000) ? 0x10 : 0) | 0x20;
-       rtc_write (0x04, bin2bcd(tmp->tm_wday) | century);
-
-       rtc_write (0x03, bin2bcd(tmp->tm_hour));
-       rtc_write (0x02, bin2bcd(tmp->tm_min ));
-       rtc_write (0x01, bin2bcd(tmp->tm_sec ));
-
-       /* UNLock RTC */
-       ccr = rtc_read(0);
-       ccr = ccr & 0x7F;
-       rtc_write(0, ccr);
-}
-
-void rtc_reset (void)
-{
-       uchar val;
-
-       /* Clear all clock control registers */
-       rtc_write (0x0, 0x80);          /* No Read Lock or calibration */
-
-       /* Clear stop bit */
-       val = rtc_read (0x1);
-       val &= 0x7f;
-       rtc_write(0x1, val);
-
-       /* Enable century / disable frequency test */
-       val = rtc_read (0x4);
-       val = (val & 0xBF) | 0x20;
-       rtc_write(0x4, val);
-
-       /* Clear write lock */
-       rtc_write(0x0, 0);
-}
-
-/* ------------------------------------------------------------------------- */
-
-static uchar rtc_read (uchar reg)
-{
-       uchar val;
-       val = *(unsigned char *)
-               ((CFG_NVRAM_BASE_ADDR + CFG_NVRAM_SIZE - 8) + reg);
-       return val;
-}
-
-static void rtc_write (uchar reg, uchar val)
-{
-       *(unsigned char *)
-               ((CFG_NVRAM_BASE_ADDR + CFG_NVRAM_SIZE - 8) + reg) = val;
-}
-
-static unsigned bcd2bin (uchar n)
-{
-       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
-}
-
-static unsigned char bin2bcd (unsigned int n)
-{
-       return (((n / 10) << 4) | (n % 10));
-}
-
-#endif
diff --git a/rtc/max6900.c b/rtc/max6900.c
deleted file mode 100644 (file)
index c75a8e0..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * (C) Copyright 2004
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Date & Time support for MAXIM MAX6900 RTC
- */
-
-/* #define     DEBUG   */
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-#include <i2c.h>
-
-#if defined(CONFIG_RTC_MAX6900) && defined(CONFIG_CMD_DATE)
-
-#ifndef        CFG_I2C_RTC_ADDR
-#define        CFG_I2C_RTC_ADDR        0x50
-#endif
-
-/* ------------------------------------------------------------------------- */
-
-static uchar rtc_read (uchar reg)
-{
-       return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
-}
-
-static void rtc_write (uchar reg, uchar val)
-{
-       i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
-       udelay(2500);
-}
-
-static unsigned bcd2bin (uchar n)
-{
-       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
-}
-
-static unsigned char bin2bcd (unsigned int n)
-{
-       return (((n / 10) << 4) | (n % 10));
-}
-
-/* ------------------------------------------------------------------------- */
-
-void rtc_get (struct rtc_time *tmp)
-{
-       uchar sec, min, hour, mday, wday, mon, cent, year;
-       int retry = 1;
-
-       do {
-               sec     = rtc_read (0x80);
-               min     = rtc_read (0x82);
-               hour    = rtc_read (0x84);
-               mday    = rtc_read (0x86);
-               mon     = rtc_read (0x88);
-               wday    = rtc_read (0x8a);
-               year    = rtc_read (0x8c);
-               cent    = rtc_read (0x92);
-               /*
-                * Check for seconds rollover
-                */
-               if ((sec != 59) || (rtc_read(0x80) == sec)){
-                       retry = 0;
-               }
-       } while (retry);
-
-       debug ( "Get RTC year: %02x mon: %02x cent: %02x mday: %02x wday: %02x "
-               "hr: %02x min: %02x sec: %02x\n",
-               year, mon, cent, mday, wday,
-               hour, min, sec );
-
-       tmp->tm_sec  = bcd2bin (sec  & 0x7F);
-       tmp->tm_min  = bcd2bin (min  & 0x7F);
-       tmp->tm_hour = bcd2bin (hour & 0x3F);
-       tmp->tm_mday = bcd2bin (mday & 0x3F);
-       tmp->tm_mon  = bcd2bin (mon & 0x1F);
-       tmp->tm_year = bcd2bin (year) + bcd2bin(cent) * 100;
-       tmp->tm_wday = bcd2bin (wday & 0x07);
-       tmp->tm_yday = 0;
-       tmp->tm_isdst= 0;
-
-       debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-}
-
-void rtc_set (struct rtc_time *tmp)
-{
-
-       debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
-       rtc_write (0x9E, 0x00);
-       rtc_write (0x80, 0);    /* Clear seconds to ensure no rollover */
-       rtc_write (0x92, bin2bcd(tmp->tm_year / 100));
-       rtc_write (0x8c, bin2bcd(tmp->tm_year % 100));
-       rtc_write (0x8a, bin2bcd(tmp->tm_wday));
-       rtc_write (0x88, bin2bcd(tmp->tm_mon));
-       rtc_write (0x86, bin2bcd(tmp->tm_mday));
-       rtc_write (0x84, bin2bcd(tmp->tm_hour));
-       rtc_write (0x82, bin2bcd(tmp->tm_min ));
-       rtc_write (0x80, bin2bcd(tmp->tm_sec ));
-}
-
-void rtc_reset (void)
-{
-}
-
-#endif
diff --git a/rtc/mc146818.c b/rtc/mc146818.c
deleted file mode 100644 (file)
index ab377ed..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * (C) Copyright 2001
- * Denis Peter MPL AG Switzerland. d.peter@mpl.ch
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Date & Time support for the MC146818 (PIXX4) RTC
- */
-
-/*#define      DEBUG*/
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-
-#if defined(CONFIG_RTC_MC146818) && defined(CONFIG_CMD_DATE)
-
-static uchar rtc_read  (uchar reg);
-static void  rtc_write (uchar reg, uchar val);
-static uchar bin2bcd   (unsigned int n);
-static unsigned bcd2bin(uchar c);
-
-#define RTC_PORT_MC146818              CFG_ISA_IO_BASE_ADDRESS +  0x70
-#define RTC_SECONDS            0x00
-#define RTC_SECONDS_ALARM      0x01
-#define RTC_MINUTES                            0x02
-#define RTC_MINUTES_ALARM      0x03
-#define RTC_HOURS                                      0x04
-#define RTC_HOURS_ALARM                0x05
-#define RTC_DAY_OF_WEEK                0x06
-#define RTC_DATE_OF_MONTH      0x07
-#define RTC_MONTH                                      0x08
-#define RTC_YEAR                                               0x09
-#define RTC_CONFIG_A                           0x0A
-#define RTC_CONFIG_B                           0x0B
-#define RTC_CONFIG_C                           0x0C
-#define RTC_CONFIG_D                           0x0D
-
-
-/* ------------------------------------------------------------------------- */
-
-void rtc_get (struct rtc_time *tmp)
-{
-       uchar sec, min, hour, mday, wday, mon, year;
-  /* here check if rtc can be accessed */
-       while((rtc_read(RTC_CONFIG_A)&0x80)==0x80);
-       sec             = rtc_read (RTC_SECONDS);
-       min             = rtc_read (RTC_MINUTES);
-       hour    = rtc_read (RTC_HOURS);
-       mday    = rtc_read (RTC_DATE_OF_MONTH);
-       wday    = rtc_read (RTC_DAY_OF_WEEK);
-       mon             = rtc_read (RTC_MONTH);
-       year    = rtc_read (RTC_YEAR);
-#ifdef CONFIG_AMIGAONEG3SE
-       wday -= 1; /* VIA 686 stores Sunday = 1, Monday = 2, ... */
-#endif
-#ifdef RTC_DEBUG
-       printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
-               "hr: %02x min: %02x sec: %02x\n",
-               year, mon, mday, wday,
-               hour, min, sec );
-       printf ( "Alarms: month: %02x hour: %02x min: %02x sec: %02x\n",
-               rtc_read (RTC_CONFIG_D) & 0x3F,
-               rtc_read (RTC_HOURS_ALARM),
-               rtc_read (RTC_MINUTES_ALARM),
-               rtc_read (RTC_SECONDS_ALARM) );
-#endif
-       tmp->tm_sec  = bcd2bin (sec  & 0x7F);
-       tmp->tm_min  = bcd2bin (min  & 0x7F);
-       tmp->tm_hour = bcd2bin (hour & 0x3F);
-       tmp->tm_mday = bcd2bin (mday & 0x3F);
-       tmp->tm_mon  = bcd2bin (mon & 0x1F);
-       tmp->tm_year = bcd2bin (year);
-       tmp->tm_wday = bcd2bin (wday & 0x07);
-       if(tmp->tm_year<70)
-               tmp->tm_year+=2000;
-       else
-               tmp->tm_year+=1900;
-       tmp->tm_yday = 0;
-       tmp->tm_isdst= 0;
-#ifdef RTC_DEBUG
-       printf ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-#endif
-}
-
-void rtc_set (struct rtc_time *tmp)
-{
-#ifdef RTC_DEBUG
-       printf ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-#endif
-       rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */
-
-       rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100));
-       rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon));
-#ifdef CONFIG_AMIGAONEG3SE
-       rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday)+1);
-#else
-       rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday));
-#endif
-       rtc_write (RTC_DATE_OF_MONTH, bin2bcd(tmp->tm_mday));
-       rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour));
-       rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min ));
-       rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec ));
-       rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */
-
-}
-
-void rtc_reset (void)
-{
-       rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */
-       rtc_write(RTC_CONFIG_A,0x20); /* Normal OP */
-       rtc_write(RTC_CONFIG_B,0x00);
-       rtc_write(RTC_CONFIG_B,0x00);
-       rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */
-}
-
-/* ------------------------------------------------------------------------- */
-
-#ifdef CFG_RTC_REG_BASE_ADDR
-/*
- * use direct memory access
- */
-static uchar rtc_read (uchar reg)
-{
-       return(in8(CFG_RTC_REG_BASE_ADDR+reg));
-}
-
-static void rtc_write (uchar reg, uchar val)
-{
-       out8(CFG_RTC_REG_BASE_ADDR+reg, val);
-}
-#else
-static uchar rtc_read (uchar reg)
-{
-       out8(RTC_PORT_MC146818,reg);
-       return(in8(RTC_PORT_MC146818+1));
-}
-
-static void rtc_write (uchar reg, uchar val)
-{
-       out8(RTC_PORT_MC146818,reg);
-       out8(RTC_PORT_MC146818+1,val);
-}
-#endif
-
-static unsigned bcd2bin (uchar n)
-{
-       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
-}
-
-static unsigned char bin2bcd (unsigned int n)
-{
-       return (((n / 10) << 4) | (n % 10));
-}
-
-#endif
diff --git a/rtc/mcfrtc.c b/rtc/mcfrtc.c
deleted file mode 100644 (file)
index 27386e5..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
- * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-
-#if defined(CONFIG_MCFRTC) && defined(CONFIG_CMD_DATE)
-
-#include <command.h>
-#include <rtc.h>
-#include <asm/immap.h>
-#include <asm/rtc.h>
-
-#undef RTC_DEBUG
-
-#ifndef CFG_MCFRTC_BASE
-#error RTC_BASE is not defined!
-#endif
-
-#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
-#define        STARTOFTIME             1970
-
-void rtc_get(struct rtc_time *tmp)
-{
-       volatile rtc_t *rtc = (rtc_t *) (CFG_MCFRTC_BASE);
-
-       int rtc_days, rtc_hrs, rtc_mins;
-       int tim;
-
-       rtc_days = rtc->days;
-       rtc_hrs = rtc->hourmin >> 8;
-       rtc_mins = RTC_HOURMIN_MINUTES(rtc->hourmin);
-
-       tim = (rtc_days * 24) + rtc_hrs;
-       tim = (tim * 60) + rtc_mins;
-       tim = (tim * 60) + rtc->seconds;
-
-       to_tm(tim, tmp);
-
-       tmp->tm_yday = 0;
-       tmp->tm_isdst = 0;
-
-#ifdef RTC_DEBUG
-       printf("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-              tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-              tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-#endif
-}
-
-void rtc_set(struct rtc_time *tmp)
-{
-       volatile rtc_t *rtc = (rtc_t *) (CFG_MCFRTC_BASE);
-
-       static int month_days[12] = {
-               31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-       };
-       int days, i, months;
-
-       if (tmp->tm_year > 2037) {
-               printf("Unable to handle. Exceeding integer limitation!\n");
-               tmp->tm_year = 2027;
-       }
-#ifdef RTC_DEBUG
-       printf("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-              tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-              tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-#endif
-
-       /* calculate days by years */
-       for (i = STARTOFTIME, days = 0; i < tmp->tm_year; i++) {
-               days += 365 + isleap(i);
-       }
-
-       /* calculate days by months */
-       months = tmp->tm_mon - 1;
-       for (i = 0; i < months; i++) {
-               days += month_days[i];
-
-               if (i == 1)
-                       days += isleap(i);
-       }
-
-       days += tmp->tm_mday - 1;
-
-       rtc->days = days;
-       rtc->hourmin = (tmp->tm_hour << 8) | tmp->tm_min;
-       rtc->seconds = tmp->tm_sec;
-}
-
-void rtc_reset(void)
-{
-       volatile rtc_t *rtc = (rtc_t *) (CFG_MCFRTC_BASE);
-
-       if ((rtc->cr & RTC_CR_EN) == 0) {
-               printf("real-time-clock was stopped. Now starting...\n");
-               rtc->cr |= RTC_CR_EN;
-       }
-
-       rtc->cr |= RTC_CR_SWR;
-}
-
-#endif                         /* CONFIG_MCFRTC && CONFIG_CMD_DATE */
diff --git a/rtc/mk48t59.c b/rtc/mk48t59.c
deleted file mode 100644 (file)
index bacdb5b..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Andreas Heppel <aheppel@sysgo.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Date & Time support for the MK48T59 RTC
- */
-
-#undef RTC_DEBUG
-
-#include <common.h>
-#include <command.h>
-#include <config.h>
-#include <rtc.h>
-#include <mk48t59.h>
-
-#if defined(CONFIG_RTC_MK48T59)
-
-#if defined(CONFIG_BAB7xx)
-
-static uchar rtc_read (short reg)
-{
-       out8(RTC_PORT_ADDR0, reg & 0xFF);
-       out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF);
-       return in8(RTC_PORT_DATA);
-}
-
-static void rtc_write (short reg, uchar val)
-{
-       out8(RTC_PORT_ADDR0, reg & 0xFF);
-       out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF);
-       out8(RTC_PORT_DATA, val);
-}
-
-#elif defined(CONFIG_PCIPPC2)
-
-#include "../board/pcippc2/pcippc2.h"
-
-static uchar rtc_read (short reg)
-{
-       return in8(RTC(reg));
-}
-
-static void rtc_write (short reg, uchar val)
-{
-       out8(RTC(reg),val);
-}
-
-#elif defined(CONFIG_AMIGAONEG3SE)
-
-#include "../board/MAI/AmigaOneG3SE/via686.h"
-#include "../board/MAI/AmigaOneG3SE/memio.h"
-
-
-static uchar rtc_read (short reg)
-{
-    out_byte(CMOS_ADDR, (uint8)reg);
-    return in_byte(CMOS_DATA);
-}
-
-static void rtc_write (short reg, uchar val)
-{
-    out_byte(CMOS_ADDR, (uint8)reg);
-    out_byte(CMOS_DATA, (uint8)val);
-}
-
-#elif defined(CONFIG_EVAL5200)
-
-static uchar rtc_read (short reg)
-{
-       return in8(RTC(reg));
-}
-
-static void rtc_write (short reg, uchar val)
-{
-       out8(RTC(reg),val);
-}
-
-#else
-# error Board specific rtc access functions should be supplied
-#endif
-
-static unsigned bcd2bin (uchar n)
-{
-       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
-}
-
-static unsigned char bin2bcd (unsigned int n)
-{
-       return (((n / 10) << 4) | (n % 10));
-}
-
-/* ------------------------------------------------------------------------- */
-
-void *nvram_read(void *dest, const short src, size_t count)
-{
-       uchar *d = (uchar *) dest;
-       short s = src;
-
-       while (count--)
-               *d++ = rtc_read(s++);
-
-       return dest;
-}
-
-void nvram_write(short dest, const void *src, size_t count)
-{
-       short d = dest;
-       uchar *s = (uchar *) src;
-
-       while (count--)
-               rtc_write(d++, *s++);
-}
-
-#if defined(CONFIG_CMD_DATE)
-
-/* ------------------------------------------------------------------------- */
-
-void rtc_get (struct rtc_time *tmp)
-{
-       uchar save_ctrl_a;
-       uchar sec, min, hour, mday, wday, mon, year;
-
-       /* Simple: freeze the clock, read it and allow updates again */
-       save_ctrl_a = rtc_read(RTC_CONTROLA);
-
-       /* Set the register to read the value. */
-       save_ctrl_a |= RTC_CA_READ;
-       rtc_write(RTC_CONTROLA, save_ctrl_a);
-
-       sec             = rtc_read (RTC_SECONDS);
-       min             = rtc_read (RTC_MINUTES);
-       hour    = rtc_read (RTC_HOURS);
-       mday    = rtc_read (RTC_DAY_OF_MONTH);
-       wday    = rtc_read (RTC_DAY_OF_WEEK);
-       mon             = rtc_read (RTC_MONTH);
-       year    = rtc_read (RTC_YEAR);
-
-       /* re-enable update */
-       save_ctrl_a &= ~RTC_CA_READ;
-       rtc_write(RTC_CONTROLA, save_ctrl_a);
-
-#ifdef RTC_DEBUG
-       printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
-               "hr: %02x min: %02x sec: %02x\n",
-               year, mon, mday, wday,
-               hour, min, sec );
-#endif
-       tmp->tm_sec  = bcd2bin (sec  & 0x7F);
-       tmp->tm_min  = bcd2bin (min  & 0x7F);
-       tmp->tm_hour = bcd2bin (hour & 0x3F);
-       tmp->tm_mday = bcd2bin (mday & 0x3F);
-       tmp->tm_mon  = bcd2bin (mon & 0x1F);
-       tmp->tm_year = bcd2bin (year);
-       tmp->tm_wday = bcd2bin (wday & 0x07);
-       if(tmp->tm_year<70)
-               tmp->tm_year+=2000;
-       else
-               tmp->tm_year+=1900;
-       tmp->tm_yday = 0;
-       tmp->tm_isdst= 0;
-#ifdef RTC_DEBUG
-       printf ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-#endif
-}
-
-void rtc_set (struct rtc_time *tmp)
-{
-       uchar save_ctrl_a;
-
-#ifdef RTC_DEBUG
-       printf ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-#endif
-       save_ctrl_a = rtc_read(RTC_CONTROLA);
-
-       save_ctrl_a |= RTC_CA_WRITE;
-       rtc_write(RTC_CONTROLA, save_ctrl_a); /* disables the RTC to update the regs */
-
-       rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100));
-       rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon));
-
-       rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday));
-       rtc_write (RTC_DAY_OF_MONTH, bin2bcd(tmp->tm_mday));
-       rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour));
-       rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min ));
-       rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec ));
-
-       save_ctrl_a &= ~RTC_CA_WRITE;
-       rtc_write(RTC_CONTROLA, save_ctrl_a); /* enables the RTC to update the regs */
-}
-
-void rtc_reset (void)
-{
-       uchar control_b;
-
-       /*
-        * Start oscillator here.
-        */
-       control_b = rtc_read(RTC_CONTROLB);
-
-       control_b &= ~RTC_CB_STOP;
-       rtc_write(RTC_CONTROLB, control_b);
-}
-
-void rtc_set_watchdog(short multi, short res)
-{
-       uchar wd_value;
-
-       wd_value = RTC_WDS | ((multi & 0x1F) << 2) | (res & 0x3);
-       rtc_write(RTC_WATCHDOG, wd_value);
-}
-
-#endif
-#endif /* CONFIG_RTC_MK48T59 */
diff --git a/rtc/mpc5xxx.c b/rtc/mpc5xxx.c
deleted file mode 100644 (file)
index 216386a..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * (C) Copyright 2004
- * Reinhard Meyer, EMK Elektronik GmbH
- * r.meyer@emk-elektronik.de
- * www.emk-elektronik.de
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*****************************************************************************
- * Date & Time support for internal RTC of MPC52xx
- *****************************************************************************/
-/*#define      DEBUG*/
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-
-#if defined(CONFIG_RTC_MPC5200) && defined(CONFIG_CMD_DATE)
-
-/*****************************************************************************
- * this structure should be defined in mpc5200.h ...
- *****************************************************************************/
-typedef struct rtc5200 {
-       volatile ulong  tsr;    /* MBAR+0x800: time set register */
-       volatile ulong  dsr;    /* MBAR+0x804: data set register */
-       volatile ulong  nysr;   /* MBAR+0x808: new year and stopwatch register */
-       volatile ulong  aier;   /* MBAR+0x80C: alarm and interrupt enable register */
-       volatile ulong  ctr;    /* MBAR+0x810: current time register */
-       volatile ulong  cdr;    /* MBAR+0x814: current data register */
-       volatile ulong  asir;   /* MBAR+0x818: alarm and stopwatch interupt register */
-       volatile ulong  piber;  /* MBAR+0x81C: periodic interrupt and bus error register */
-       volatile ulong  trdr;   /* MBAR+0x820: test register/divides register */
-} RTC5200;
-
-#define        RTC_SET         0x02000000
-#define        RTC_PAUSE       0x01000000
-
-/*****************************************************************************
- * get time
- *****************************************************************************/
-void rtc_get (struct rtc_time *tmp)
-{
-       RTC5200 *rtc = (RTC5200 *) (CFG_MBAR+0x800);
-       ulong time, date, time2;
-
-       /* read twice to avoid getting a funny time when the second is just changing */
-       do {
-               time = rtc->ctr;
-               date = rtc->cdr;
-               time2 = rtc->ctr;
-       } while (time != time2);
-
-       tmp->tm_year    = date & 0xfff;
-       tmp->tm_mon             = (date >> 24) & 0xf;
-       tmp->tm_mday    = (date >> 16) & 0x1f;
-       tmp->tm_wday    = (date >> 21) & 7;
-       /* sunday is 7 in 5200 but 0 in rtc_time */
-       if (tmp->tm_wday == 7)
-               tmp->tm_wday = 0;
-       tmp->tm_hour    = (time >> 16) & 0x1f;
-       tmp->tm_min             = (time >> 8) & 0x3f;
-       tmp->tm_sec             = time & 0x3f;
-
-       debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-}
-
-/*****************************************************************************
- * set time
- *****************************************************************************/
-void rtc_set (struct rtc_time *tmp)
-{
-       RTC5200 *rtc = (RTC5200 *) (CFG_MBAR+0x800);
-       ulong time, date, year;
-
-       debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
-       time = (tmp->tm_hour << 16) | (tmp->tm_min << 8) | tmp->tm_sec;
-       date = (tmp->tm_mon << 16) | tmp->tm_mday;
-       if (tmp->tm_wday == 0)
-               date |= (7 << 8);
-       else
-               date |= (tmp->tm_wday << 8);
-       year = tmp->tm_year;
-
-       /* mask unwanted bits that might show up when rtc_time is corrupt */
-       time &= 0x001f3f3f;
-       date &= 0x001f071f;
-       year &= 0x00000fff;
-
-       /* pause and set the RTC */
-       rtc->nysr = year;
-       rtc->dsr = date | RTC_PAUSE;
-       udelay (1000);
-       rtc->dsr = date | RTC_PAUSE | RTC_SET;
-       udelay (1000);
-       rtc->dsr = date | RTC_PAUSE;
-       udelay (1000);
-       rtc->dsr = date;
-       udelay (1000);
-
-       rtc->tsr = time | RTC_PAUSE;
-       udelay (1000);
-       rtc->tsr = time | RTC_PAUSE | RTC_SET;
-       udelay (1000);
-       rtc->tsr = time | RTC_PAUSE;
-       udelay (1000);
-       rtc->tsr = time;
-       udelay (1000);
-}
-
-/*****************************************************************************
- * reset rtc circuit
- *****************************************************************************/
-void rtc_reset (void)
-{
-       return; /* nothing to do */
-}
-
-#endif
diff --git a/rtc/mpc8xx.c b/rtc/mpc8xx.c
deleted file mode 100644 (file)
index 8d10c0e..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * (C) Copyright 2001
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Date & Time support for internal RTC of MPC8xx
- */
-
-/*#define      DEBUG*/
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-
-#if defined(CONFIG_RTC_MPC8xx) && defined(CONFIG_CMD_DATE)
-
-/* ------------------------------------------------------------------------- */
-
-void rtc_get (struct rtc_time *tmp)
-{
-       volatile immap_t *immr = (immap_t *)CFG_IMMR;
-       ulong tim;
-
-       tim = immr->im_sit.sit_rtc;
-
-       to_tm (tim, tmp);
-
-       debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-}
-
-void rtc_set (struct rtc_time *tmp)
-{
-       volatile immap_t *immr = (immap_t *)CFG_IMMR;
-       ulong tim;
-
-       debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
-       tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
-                     tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
-       immr->im_sitk.sitk_rtck = KAPWR_KEY;
-       immr->im_sit.sit_rtc = tim;
-}
-
-void rtc_reset (void)
-{
-       return; /* nothing to do */
-}
-
-#endif
diff --git a/rtc/pcf8563.c b/rtc/pcf8563.c
deleted file mode 100644 (file)
index 2d73d5d..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * (C) Copyright 2001
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Date & Time support for Philips PCF8563 RTC
- */
-
-/* #define     DEBUG   */
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-#include <i2c.h>
-
-#if defined(CONFIG_RTC_PCF8563) && defined(CONFIG_CMD_DATE)
-
-static uchar rtc_read  (uchar reg);
-static void  rtc_write (uchar reg, uchar val);
-static uchar bin2bcd   (unsigned int n);
-static unsigned bcd2bin(uchar c);
-
-/* ------------------------------------------------------------------------- */
-
-void rtc_get (struct rtc_time *tmp)
-{
-       uchar sec, min, hour, mday, wday, mon_cent, year;
-
-       sec     = rtc_read (0x02);
-       min     = rtc_read (0x03);
-       hour    = rtc_read (0x04);
-       mday    = rtc_read (0x05);
-       wday    = rtc_read (0x06);
-       mon_cent= rtc_read (0x07);
-       year    = rtc_read (0x08);
-
-       debug ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
-               "hr: %02x min: %02x sec: %02x\n",
-               year, mon_cent, mday, wday,
-               hour, min, sec );
-       debug ( "Alarms: wday: %02x day: %02x hour: %02x min: %02x\n",
-               rtc_read (0x0C),
-               rtc_read (0x0B),
-               rtc_read (0x0A),
-               rtc_read (0x09) );
-
-       if (sec & 0x80) {
-               puts ("### Warning: RTC Low Voltage - date/time not reliable\n");
-       }
-
-       tmp->tm_sec  = bcd2bin (sec  & 0x7F);
-       tmp->tm_min  = bcd2bin (min  & 0x7F);
-       tmp->tm_hour = bcd2bin (hour & 0x3F);
-       tmp->tm_mday = bcd2bin (mday & 0x3F);
-       tmp->tm_mon  = bcd2bin (mon_cent & 0x1F);
-       tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900);
-       tmp->tm_wday = bcd2bin (wday & 0x07);
-       tmp->tm_yday = 0;
-       tmp->tm_isdst= 0;
-
-       debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-}
-
-void rtc_set (struct rtc_time *tmp)
-{
-       uchar century;
-
-       debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
-       rtc_write (0x08, bin2bcd(tmp->tm_year % 100));
-
-       century = (tmp->tm_year >= 2000) ? 0x80 : 0;
-       rtc_write (0x07, bin2bcd(tmp->tm_mon) | century);
-
-       rtc_write (0x06, bin2bcd(tmp->tm_wday));
-       rtc_write (0x05, bin2bcd(tmp->tm_mday));
-       rtc_write (0x04, bin2bcd(tmp->tm_hour));
-       rtc_write (0x03, bin2bcd(tmp->tm_min ));
-       rtc_write (0x02, bin2bcd(tmp->tm_sec ));
-}
-
-void rtc_reset (void)
-{
-       /* clear all control & status registers */
-       rtc_write (0x00, 0x00);
-       rtc_write (0x01, 0x00);
-       rtc_write (0x0D, 0x00);
-
-       /* clear Voltage Low bit */
-       rtc_write (0x02, rtc_read (0x02) & 0x7F);
-
-       /* reset all alarms */
-       rtc_write (0x09, 0x00);
-       rtc_write (0x0A, 0x00);
-       rtc_write (0x0B, 0x00);
-       rtc_write (0x0C, 0x00);
-}
-
-/* ------------------------------------------------------------------------- */
-
-static uchar rtc_read (uchar reg)
-{
-       return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
-}
-
-static void rtc_write (uchar reg, uchar val)
-{
-       i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
-}
-
-static unsigned bcd2bin (uchar n)
-{
-       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
-}
-
-static unsigned char bin2bcd (unsigned int n)
-{
-       return (((n / 10) << 4) | (n % 10));
-}
-
-#endif
diff --git a/rtc/rs5c372.c b/rtc/rs5c372.c
deleted file mode 100644 (file)
index 3d1346e..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * rs5c372.c
- *
- * Device driver for Ricoh's Real Time Controller RS5C372A.
- *
- * Copyright (C) 2004 Gary Jennejohn garyj@denx.de
- *
- * Based in part in ds1307.c -
- * (C) Copyright 2001, 2002, 2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- * Keith Outwater, keith_outwater@mvis.com`
- * Steven Scholz, steven.scholz@imc-berlin.de
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-#include <i2c.h>
-
-#if defined(CONFIG_RTC_RS5C372A) && defined(CONFIG_CMD_DATE)
-/*
- * Reads are always done starting with register 15, which requires some
- * jumping-through-hoops to access the data correctly.
- *
- * Writes are always done starting with register 0.
- */
-
-#define DEBUG 0
-
-#if DEBUG
-static unsigned int rtc_debug = DEBUG;
-#else
-#define rtc_debug 0    /* gcc will remove all the debug code for us */
-#endif
-
-#ifndef CFG_I2C_RTC_ADDR
-#define CFG_I2C_RTC_ADDR 0x32
-#endif
-
-#define RS5C372_RAM_SIZE 0x10
-#define RATE_32000HZ   0x80    /* Rate Select 32.000KHz */
-#define RATE_32768HZ   0x00    /* Rate Select 32.768KHz */
-
-#define STATUS_XPT  0x10    /* data invalid because voltage was 0 */
-
-#define USE_24HOUR_MODE 0x20
-#define TWELVE_HOUR_MODE(n) ((((n) >> 5) & 1) == 0)
-#define HOURS_AP(n)    (((n) >> 5) & 1)
-#define HOURS_12(n)    bcd2bin((n) & 0x1F)
-#define HOURS_24(n)    bcd2bin((n) & 0x3F)
-
-
-static uchar bin2bcd (unsigned int n);
-static unsigned bcd2bin (uchar c);
-
-static int setup_done = 0;
-
-static int
-rs5c372_readram(unsigned char *buf, int len)
-{
-       int ret;
-
-       ret = i2c_read(CFG_I2C_RTC_ADDR, 0, 0, buf, len);
-       if (ret != 0) {
-               printf("%s: failed to read\n", __FUNCTION__);
-               return ret;
-       }
-
-       if (buf[0] & STATUS_XPT)
-               printf("### Warning: RTC lost power\n");
-
-       return ret;
-}
-
-static void
-rs5c372_enable(void)
-{
-       unsigned char buf[RS5C372_RAM_SIZE + 1];
-       int ret;
-
-       /* note that this returns reg. 15 in buf[1] */
-       ret = rs5c372_readram(&buf[1], RS5C372_RAM_SIZE);
-       if (ret != 0) {
-               printf("%s: failed\n", __FUNCTION__);
-               return;
-       }
-
-       buf[0] = 0;
-       /* we want to start writing at register 0 so we have to copy the */
-       /* register contents up one slot */
-       for (ret = 2; ret < 9; ret++)
-               buf[ret - 1] = buf[ret];
-       /* registers 0 to 6 (time values) are not touched */
-       buf[8] = RATE_32768HZ; /* reg. 7 */
-       buf[9] = 0; /* reg. 8 */
-       buf[10] = 0; /* reg. 9 */
-       buf[11] = 0; /* reg. 10 */
-       buf[12] = 0; /* reg. 11 */
-       buf[13] = 0; /* reg. 12 */
-       buf[14] = 0; /* reg. 13 */
-       buf[15] = 0; /* reg. 14 */
-       buf[16] = USE_24HOUR_MODE; /* reg. 15 */
-       ret = i2c_write(CFG_I2C_RTC_ADDR, 0, 0, buf, RS5C372_RAM_SIZE+1);
-       if (ret != 0) {
-               printf("%s: failed\n", __FUNCTION__);
-               return;
-       }
-       setup_done = 1;
-
-       return;
-}
-
-static void
-rs5c372_convert_to_time(struct rtc_time *dt, unsigned char *buf)
-{
-       /* buf[0] is register 15 */
-       dt->tm_sec = bcd2bin(buf[1]);
-       dt->tm_min = bcd2bin(buf[2]);
-
-       if (TWELVE_HOUR_MODE(buf[0])) {
-               dt->tm_hour = HOURS_12(buf[3]);
-               if (HOURS_AP(buf[3])) /* PM */
-                       dt->tm_hour += 12;
-       } else /* 24-hour-mode */
-               dt->tm_hour = HOURS_24(buf[3]);
-
-       dt->tm_mday = bcd2bin(buf[5]);
-       dt->tm_mon = bcd2bin(buf[6]);
-       dt->tm_year = bcd2bin(buf[7]);
-       if (dt->tm_year >= 70)
-               dt->tm_year += 1900;
-       else
-               dt->tm_year += 2000;
-       /* 0 is Sunday */
-       dt->tm_wday = bcd2bin(buf[4] & 0x07);
-       dt->tm_yday = 0;
-       dt->tm_isdst= 0;
-
-       if(rtc_debug > 2) {
-               printf("rs5c372_convert_to_time: year = %d\n", dt->tm_year);
-               printf("rs5c372_convert_to_time: mon  = %d\n", dt->tm_mon);
-               printf("rs5c372_convert_to_time: mday = %d\n", dt->tm_mday);
-               printf("rs5c372_convert_to_time: hour = %d\n", dt->tm_hour);
-               printf("rs5c372_convert_to_time: min  = %d\n", dt->tm_min);
-               printf("rs5c372_convert_to_time: sec  = %d\n", dt->tm_sec);
-       }
-}
-
-/*
- * Get the current time from the RTC
- */
-void
-rtc_get (struct rtc_time *tmp)
-{
-       unsigned char buf[RS5C372_RAM_SIZE];
-       int ret;
-
-       if (!setup_done)
-               rs5c372_enable();
-
-       if (!setup_done)
-               return;
-
-       memset(buf, 0, sizeof(buf));
-
-       /* note that this returns reg. 15 in buf[0] */
-       ret = rs5c372_readram(buf, RS5C372_RAM_SIZE);
-       if (ret != 0) {
-               printf("%s: failed\n", __FUNCTION__);
-               return;
-       }
-
-       rs5c372_convert_to_time(tmp, buf);
-
-       return;
-}
-
-/*
- * Set the RTC
- */
-void
-rtc_set (struct rtc_time *tmp)
-{
-       unsigned char buf[8], reg15;
-       int ret;
-
-       if (!setup_done)
-               rs5c372_enable();
-
-       if (!setup_done)
-               return;
-
-       if(rtc_debug > 2) {
-               printf("rtc_set: tm_year = %d\n", tmp->tm_year);
-               printf("rtc_set: tm_mon  = %d\n", tmp->tm_mon);
-               printf("rtc_set: tm_mday = %d\n", tmp->tm_mday);
-               printf("rtc_set: tm_hour = %d\n", tmp->tm_hour);
-               printf("rtc_set: tm_min  = %d\n", tmp->tm_min);
-               printf("rtc_set: tm_sec  = %d\n", tmp->tm_sec);
-       }
-
-       memset(buf, 0, sizeof(buf));
-
-       /* only read register 15 */
-       ret = i2c_read(CFG_I2C_RTC_ADDR, 0, 0, buf, 1);
-
-       if (ret == 0) {
-               /* need to save register 15 */
-               reg15 = buf[0];
-               buf[0] = 0;     /* register address on RS5C372 */
-               buf[1] = bin2bcd(tmp->tm_sec);
-               buf[2] = bin2bcd(tmp->tm_min);
-               /* need to handle 12 hour mode */
-               if (TWELVE_HOUR_MODE(reg15)) {
-                       if (tmp->tm_hour >= 12) { /* PM */
-                               /* 12 PM is a special case */
-                               if (tmp->tm_hour == 12)
-                                       buf[3] = bin2bcd(tmp->tm_hour);
-                               else
-                                       buf[3] = bin2bcd(tmp->tm_hour - 12);
-                               buf[3] |= 0x20;
-                       }
-               } else {
-                       buf[3] = bin2bcd(tmp->tm_hour);
-               }
-
-               buf[4] = bin2bcd(tmp->tm_wday);
-               buf[5] = bin2bcd(tmp->tm_mday);
-               buf[6] = bin2bcd(tmp->tm_mon);
-               if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
-                       printf("WARNING: year should be between 1970 and 2069!\n");
-               buf[7] = bin2bcd(tmp->tm_year % 100);
-
-               ret = i2c_write(CFG_I2C_RTC_ADDR, 0, 0, buf, 8);
-               if (ret != 0)
-                       printf("rs5c372_set_datetime(), i2c_master_send() returned %d\n",ret);
-       }
-
-       return;
-}
-
-/*
- * Reset the RTC. We set the date back to 1970-01-01.
- */
-void
-rtc_reset (void)
-{
-       struct rtc_time tmp;
-
-       if (!setup_done)
-               rs5c372_enable();
-
-       if (!setup_done)
-               return;
-
-       tmp.tm_year = 1970;
-       tmp.tm_mon = 1;
-       /* Jan. 1, 1970 was a Thursday */
-       tmp.tm_wday= 4;
-       tmp.tm_mday= 1;
-       tmp.tm_hour = 0;
-       tmp.tm_min = 0;
-       tmp.tm_sec = 0;
-
-       rtc_set(&tmp);
-
-       printf ("RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC\n",
-               tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
-               tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
-
-       return;
-}
-
-static unsigned int
-bcd2bin (unsigned char n)
-{
-       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
-}
-
-static unsigned char
-bin2bcd (unsigned int n)
-{
-       return (((n / 10) << 4) | (n % 10));
-}
-#endif
diff --git a/rtc/s3c24x0_rtc.c b/rtc/s3c24x0_rtc.c
deleted file mode 100644 (file)
index 7f8b4fa..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * (C) Copyright 2003
- * David Müller ELSOFT AG Switzerland. d.mueller@elsoft.ch
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * Date & Time support for the built-in Samsung S3C24X0 RTC
- */
-
-#include <common.h>
-#include <command.h>
-
-#if defined(CONFIG_RTC_S3C24X0) && (defined(CONFIG_CMD_DATE))
-
-#if defined(CONFIG_S3C2400)
-#include <s3c2400.h>
-#elif defined(CONFIG_S3C2410)
-#include <s3c2410.h>
-#endif
-
-#include <rtc.h>
-
-/*#define      DEBUG*/
-
-typedef enum {
-       RTC_ENABLE,
-       RTC_DISABLE
-} RTC_ACCESS;
-
-
-static inline void SetRTC_Access(RTC_ACCESS a)
-{
-       S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
-       switch (a) {
-               case RTC_ENABLE:
-                       rtc->RTCCON |= 0x01; break;
-
-               case RTC_DISABLE:
-                       rtc->RTCCON &= ~0x01; break;
-       }
-}
-
-static unsigned bcd2bin (uchar n)
-{
-       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
-}
-
-static unsigned char bin2bcd (unsigned int n)
-{
-       return (((n / 10) << 4) | (n % 10));
-}
-
-/* ------------------------------------------------------------------------- */
-
-void rtc_get (struct rtc_time *tmp)
-{
-       S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
-       uchar sec, min, hour, mday, wday, mon, year;
-       uchar a_sec,a_min, a_hour, a_date, a_mon, a_year, a_armed;
-
-       /* enable access to RTC registers */
-       SetRTC_Access(RTC_ENABLE);
-
-       /* read RTC registers */
-       do {
-               sec     = rtc->BCDSEC;
-               min     = rtc->BCDMIN;
-               hour    = rtc->BCDHOUR;
-               mday    = rtc->BCDDATE;
-               wday    = rtc->BCDDAY;
-               mon     = rtc->BCDMON;
-               year    = rtc->BCDYEAR;
-       } while (sec != rtc->BCDSEC);
-
-       /* read ALARM registers */
-       a_sec   = rtc->ALMSEC;
-       a_min   = rtc->ALMMIN;
-       a_hour  = rtc->ALMHOUR;
-       a_date  = rtc->ALMDATE;
-       a_mon   = rtc->ALMMON;
-       a_year  = rtc->ALMYEAR;
-       a_armed = rtc->RTCALM;
-
-       /* disable access to RTC registers */
-       SetRTC_Access(RTC_DISABLE);
-
-#ifdef RTC_DEBUG
-       printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
-               "hr: %02x min: %02x sec: %02x\n",
-               year, mon, mday, wday,
-               hour, min, sec);
-       printf ( "Alarms: %02x: year: %02x month: %02x date: %02x hour: %02x min: %02x sec: %02x\n",
-               a_armed,
-               a_year, a_mon, a_date,
-               a_hour, a_min, a_sec);
-#endif
-
-       tmp->tm_sec  = bcd2bin(sec  & 0x7F);
-       tmp->tm_min  = bcd2bin(min  & 0x7F);
-       tmp->tm_hour = bcd2bin(hour & 0x3F);
-       tmp->tm_mday = bcd2bin(mday & 0x3F);
-       tmp->tm_mon  = bcd2bin(mon & 0x1F);
-       tmp->tm_year = bcd2bin(year);
-       tmp->tm_wday = bcd2bin(wday & 0x07);
-       if(tmp->tm_year<70)
-               tmp->tm_year+=2000;
-       else
-               tmp->tm_year+=1900;
-       tmp->tm_yday = 0;
-       tmp->tm_isdst= 0;
-#ifdef RTC_DEBUG
-       printf ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-#endif
-}
-
-void rtc_set (struct rtc_time *tmp)
-{
-       S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
-       uchar sec, min, hour, mday, wday, mon, year;
-
-#ifdef RTC_DEBUG
-       printf ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
-               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
-               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-#endif
-       year    = bin2bcd(tmp->tm_year % 100);
-       mon     = bin2bcd(tmp->tm_mon);
-       wday    = bin2bcd(tmp->tm_wday);
-       mday    = bin2bcd(tmp->tm_mday);
-       hour    = bin2bcd(tmp->tm_hour);
-       min     = bin2bcd(tmp->tm_min);
-       sec     = bin2bcd(tmp->tm_sec);
-
-       /* enable access to RTC registers */
-       SetRTC_Access(RTC_ENABLE);
-
-       /* write RTC registers */
-       rtc->BCDSEC     = sec;
-       rtc->BCDMIN     = min;
-       rtc->BCDHOUR    = hour;
-       rtc->BCDDATE    = mday;
-       rtc->BCDDAY     = wday;
-       rtc->BCDMON     = mon;
-       rtc->BCDYEAR    = year;
-
-       /* disable access to RTC registers */
-       SetRTC_Access(RTC_DISABLE);
-}
-
-void rtc_reset (void)
-{
-       S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
-
-       rtc->RTCCON = (rtc->RTCCON & ~0x06) | 0x08;
-       rtc->RTCCON &= ~(0x08|0x01);
-}
-
-#endif
diff --git a/tools/.gitignore b/tools/.gitignore
new file mode 100644 (file)
index 0000000..c33679a
--- /dev/null
@@ -0,0 +1,9 @@
+/bmp_logo
+/crc32.c
+/envcrc
+/environment.c
+/gen_eth_addr
+/img2srec
+/mkimage
+/sha1.c
+/ubsha1
diff --git a/tools/scripts/define2mk.sed b/tools/scripts/define2mk.sed
new file mode 100644 (file)
index 0000000..6464627
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# Sed script to parse CPP macros and generate output usable by make
+#
+# It is expected that this script is fed the output of 'gpp -dM'
+# which preprocesses the common.h header files and outputs the final
+# list of CPP macros (and whitespace is sanitized)
+#
+
+# Only process values prefixed with #define CONFIG_
+/^#define CONFIG_[A-Za-z0-9_]\+/ {
+       # Strip the #define prefix
+       s/#define *//;
+       # Change to form CONFIG_*=VALUE
+       s/ \+/=/;
+       # Drop trailing spaces
+       s/ *$//;
+       # drop quotes around string values
+       s/="\(.*\)"$/=\1/;
+       # Concatenate string values
+       s/" *"//g;
+       # Wrap non-numeral values with quotes
+       s/=\(.*\?[^0-9].*\)$/=\"\1\"/;
+       # Change '1' and empty values to "y" (not perfect, but
+       # supports conditional compilation in the makefiles
+       s/=$/=y/;
+       s/=1$/=y/;
+       # print the line
+       p
+}